Compare commits

..

66 commits

Author SHA1 Message Date
71a055987c Merge pull request 'Build the Wolfskin TV title, episode and person pages' (#34) from fm/tv-slice5-titles into main 2026-11-05 23:21:03 +01:00
844530404d Integrate shared offline recovery and saved-state isolation
All checks were successful
review/design-claude 13 fixes passed Sonnet re-review at cd625b42; merged head 84453040 = main merge + shared RecoveryToast reuse: 33/34 pairs byte-identical, st-048 adopts the shared toast, 830 tests green (firstmate check)
2026-11-05 22:59:45 +01:00
abec496305 Merge pull request 'Add TV offline recovery and per-person saved-state isolation' (#35) from fm/tv-slice8-states into main 2026-11-05 22:43:13 +01:00
a01c0a78fb Add TV offline recovery and per-person state isolation
All checks were successful
review/design-claude Claude Sonnet cross-family review: pass, no blockers
2026-11-05 22:11:00 +01:00
cd625b4227 Remove unreachable duplicate glyph branches and assets
All checks were successful
review/design-claude Round 2: 13/13 round-1 blockers fixed, no blockers on cd625b42
2026-11-05 21:55:04 +01:00
fc02ce8646 Integrate native Home and replay full title launch paths 2026-11-05 21:49:34 +01:00
2fdd459037 Match title CSS geometry and fix modal focus and subtitle choices 2026-11-05 21:38:46 +01:00
9dd321f07e Merge pull request 'Build the Wolfskin TV Home feed' (#31) from fm/tv-slice3-home into main 2026-11-05 21:34:29 +01:00
061670848f Keep overlapping screen captures in separate namespaces
All checks were successful
review/design-claude Design re-review: B1-B3 fixed, no blocking findings (head 06167084)
2026-11-05 21:07:22 +01:00
575103ce98 Integrate Discover with canonical shared UI 2026-11-05 20:57:57 +01:00
e243894a20 Integrate reviewed Requests and Discover surfaces
Some checks failed
review/design-claude Changes requested: 13 blocking design/behaviour findings (see PR comment)
2026-11-05 20:46:58 +01:00
86d3432fb0 Merge pull request 'Build Discover TV picks, hidden titles and request flows' (#33) from fm/tv-slice6-discover into main 2026-11-05 20:35:19 +01:00
43ae716157 Preserve native title line boxes and async focus 2026-11-05 20:26:43 +01:00
5033c171cb Preserve Requests recovery button activation 2026-11-05 20:24:10 +01:00
130697c2eb Clamp Discover text boxes and preserve recovery button height
All checks were successful
review/design-claude B1-B3 re-measured by firstmate from the lane measurement file against the locked numbers (all within 2 px); delta is the three scoped fixes plus an additive main merge; N1/N2 3-4 px offsets remain as listed follow-ups
2026-11-05 20:22:47 +01:00
4cd75cfa26 Integrate Requests with the shared image cache 2026-11-05 20:20:06 +01:00
bfd4002dd1 Merge Requests screens from main 2026-11-05 20:11:00 +01:00
1c77f21df3 Merge pull request 'Build TV Requests under Settings' (#32) from fm/tv-slice7-requests into main 2026-11-05 20:06:36 +01:00
a8951827ba Reuse shared artwork and correct title focus edges 2026-11-05 19:58:36 +01:00
e99ed2d394 Use the locked Home See all spacing 2026-11-05 19:53:51 +01:00
924c90a9e0 Align readiness glyphs to inline text baselines
All checks were successful
review/design-claude B1-B5/B7 verified fixed by Sonnet re-review at b8d5d8a1; B8 readiness block-line replication checked by firstmate: 6-file delta, baseline/no-gap code only, st-086 pair viewed, two-line wrap is font-caused and recorded; B6 approved by Justin
2026-11-05 19:53:32 +01:00
1299034991 Match Discover shadows, text rhythm and asynchronous focus
Some checks failed
review/design-claude Changes requested: 3 blocking design deviations (st-032 sheet rhythm, st-036 button squeeze, hero stack offset)
2026-11-05 19:39:13 +01:00
9c8fceb18c Restore Home viewport across See all navigation 2026-11-05 19:28:09 +01:00
b8d5d8a124 Preserve contained rating marks inside dark chips
Some checks failed
review/design-claude B1-B5,B7 fixed; B8 readiness item glyph/gap geometry deviates from locked st-086
2026-11-05 19:10:25 +01:00
14a74ac43b Integrate libraries and correct Home review blockers 2026-11-05 19:03:33 +01:00
d9578ac405 Match Requests sheets to locked design frames 2026-11-05 18:58:06 +01:00
4e62aad638 Reuse baseline-aligned headers with source subtitle typography 2026-11-05 18:37:58 +01:00
b1b15b384b Keep catalogue outcomes and recovery consistent across views 2026-11-05 18:32:09 +01:00
c1559e2513 Merge Libraries and reuse the shared catalogue surface 2026-11-05 17:55:49 +01:00
3bfb8cd779 Merge shared library surfaces and connect title navigation 2026-11-05 17:54:34 +01:00
439eea3ff8 Merge library slice and reuse shared image policy
Some checks failed
review/design-claude Changes requested: 7 design-parity findings (separator opacity, line-box rhythm, stage gap, mark chips, avatar, count, thumb fringe)
2026-11-05 17:41:43 +01:00
fc7eb94cc1 Record native title metrics and reuse SDK fixtures 2026-11-05 17:40:55 +01:00
03ff22ea86 Preserve request outcomes and align Discover shelf windows 2026-11-05 17:37:39 +01:00
5b0703aec5 Build household requests under Settings 2026-11-05 17:35:42 +01:00
96538f3c7a Merge pull request 'Build TV libraries and continuous See all grids' (#30) from fm/tv-slice4-libraries into main 2026-11-05 17:35:12 +01:00
b54bcc148c Follow visible card centers and remember Home tracks
Some checks failed
review/design-claude Request changes: separator dot colour, vertical rhythm, focus entry after load
2026-11-05 17:16:06 +01:00
0ca13e684f Merge main after TV shell lands 2026-11-05 17:14:09 +01:00
6d7df0fb19 Preserve title data and focus across updates 2026-11-05 17:13:53 +01:00
321f2d41bb Match library header initials to the locked muted colour
All checks were successful
review/design-claude B1/B2 passed Sonnet re-review at 60a0da13; B3 (header avatar initial muted) checked by firstmate: 3 files, default-preserving letterColor param, only LibraryHeader passes muted
2026-11-05 17:13:47 +01:00
90e956b157 Measure native Discover typography and focus boundaries 2026-11-05 17:04:45 +01:00
2b65ee7b53 Preserve the person identity guard on Home 2026-11-05 16:57:20 +01:00
60a0da13a2 Document visible tail navigation and library typography
Some checks failed
review/design-claude Header avatar initial must be muted like the locked frames; tail Down and separator dot fixed
2026-11-05 16:55:12 +01:00
5a0497c9ec Merge the reviewed shell from main 2026-11-05 16:50:59 +01:00
6f430439a6 Merge the shipped TV shell into Discover 2026-11-05 16:50:52 +01:00
4b28b4f044 Match Discover captions and catalogue collection states 2026-11-05 16:50:38 +01:00
3b7249888f Match Home focus and recovery details 2026-11-05 16:50:32 +01:00
e5bb4ec47f Merge remote-tracking branch 'origin/main' into fm/tv-slice4-libraries 2026-11-05 16:50:24 +01:00
7a878b2d81 Merge pull request 'Build the Wolfskin TV shell and navigation' (#29) from fm/tv-slice2-shell into main 2026-11-05 16:49:28 +01:00
b24c404cc8 Merge the reviewed settings pill border correction
# Conflicts:
#	wolfskin-design/tokens.sha256
2026-11-05 16:44:52 +01:00
a6dd04f390 Keep library focus on visible rows and match caption facts 2026-11-05 16:44:21 +01:00
74033ee1da Match the settings pill border to the prototype
All checks were successful
review/design-claude B1/B2/N1/N4 passed Sonnet re-review at 2ea93010; B3 pill border one-frame re-check by firstmate: dash rhythm and 1dp stroke match, delta additive (6 files, pill only)
2026-11-05 16:28:09 +01:00
7e8e232d47 Merge the corrected TV shell into Discover 2026-11-05 16:19:00 +01:00
c534ea75c2 Use resolved weights for episode rating labels 2026-11-05 16:18:40 +01:00
6a02887dc9 Build the Discover catalogue and request flow 2026-11-05 16:18:19 +01:00
0c94e8f910 Merge reviewed TV shell focus and text fixes 2026-11-05 16:17:42 +01:00
c07bb2ca1d Merge the reviewed shell updates 2026-11-05 16:17:38 +01:00
0db05174b1 Build native title and person surfaces 2026-11-05 16:16:02 +01:00
0fd0ec035d Build the Wolfskin Home feed 2026-11-05 16:15:40 +01:00
3da635b4cb Merge reviewed TV shell changes into libraries
Some checks failed
review/design-claude Changes requested: tail-card Down focus bug and caption separator opacity
2026-11-05 16:11:29 +01:00
27fd174aed Preserve full line boxes in library recovery panels 2026-11-05 16:05:25 +01:00
2ea9301069 Assert the declared owned-screen background colour
Some checks failed
review/design-claude B1/B2 fixed; settings pill dashed stroke 2x spec (blocking)
2026-11-05 15:52:12 +01:00
380c423376 Build TV libraries and continuous See all grids 2026-11-05 15:51:24 +01:00
4b89a73908 Restore upstream content focus and deterministic shell typography 2026-11-05 15:39:56 +01:00
9be55c570a Integrate the Conductarr client with the Wolfskin shell
Some checks failed
review/design-claude Changes requested: switch-off path loses backdrop/Up focus; font weight deviation in captures
2026-11-05 14:50:04 +01:00
f60a22e435 Build the Wolfskin TV shell and navigation 2026-11-05 14:38:38 +01:00
2be4e30826 Merge pull request 'Add the pinned Conductarr TV client and disk-backed saved data' (#28) from fm/tv-conductarr-client into main 2026-11-05 13:18:47 +01:00
2608 changed files with 18759 additions and 91 deletions

View file

@ -1,3 +1,4 @@
import com.android.build.api.artifact.SingleArtifact
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.ProductFlavor
import com.android.build.api.variant.FilterConfiguration
@ -5,6 +6,7 @@ import com.google.protobuf.gradle.id
import com.mikepenz.aboutlibraries.plugin.DuplicateMode
import com.mikepenz.aboutlibraries.plugin.DuplicateRule
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import java.io.File
import java.util.Base64
import java.util.Properties
@ -194,6 +196,7 @@ configure<ApplicationExtension> {
sourceSets {
getByName("main") {
kotlin.directories += "$buildDir/generated/seerr_api/src/main/kotlin"
kotlin.directories += "src/wolfskin/java"
}
}
@ -224,6 +227,47 @@ androidComponents {
"Wholphin-${variant.flavorName}-${variant.buildType}-${output.versionName.get()}-${output.versionCode.get()}$abi.apk"
output.outputFileName = outputFileName
}
if (variant.name == "defaultDebug") {
val packagedApks = variant.artifacts.get(SingleArtifact.APK)
val artifactLoader = variant.artifacts.getBuiltArtifactsLoader()
val aapt2 = sdkComponents.aapt2.flatMap { it.executable }
val checkWolfskinBranding = tasks.register("checkWolfskinBranding") {
inputs.dir(packagedApks)
inputs.file(aapt2)
doLast {
val artifacts = checkNotNull(artifactLoader.load(packagedApks.get())) {
"Packaged default/debug APK metadata was not found; branding is unverified"
}.elements
check(artifacts.isNotEmpty()) { "No default/debug APKs were found; branding is unverified" }
val header = Regex("""^\s*resource 0x[\da-fA-F]+ (?:[^\s:]+:)?([^\s/]+)/([^\s]+)""")
val visibleTypes = setOf("string", "plurals", "array")
// Upstream legal attribution and its project URL must survive the branding cutover.
val legalNames = setOf("wolfskin_upstream_credit", "wolfskin_upstream_url")
val violations = sortedSetOf<String>()
artifacts.forEach { artifact ->
val dump = providers.exec {
commandLine(aapt2.get().asFile, "dump", "resources", artifact.outputFile)
}.standardOutput.asText.get()
var currentName: String? = null
var inspected = 0
dump.lineSequence().forEach { line ->
val resource = header.find(line)
if (resource != null) {
currentName = resource.groupValues[2].takeIf { resource.groupValues[1] in visibleTypes }
if (currentName != null) inspected++
} else if (currentName != null && currentName !in legalNames && line.contains("Wholphin", ignoreCase = true)) {
violations += "${File(artifact.outputFile).name}:$currentName"
}
}
check(inspected > 0) { "No packaged string resources were decoded; branding is unverified" }
logger.lifecycle("Inspected $inspected string/plural/array resources in ${File(artifact.outputFile).name}")
}
check(violations.isEmpty()) { "User-visible upstream branding remains: ${violations.joinToString()}" }
logger.lifecycle("Wolfskin branding check passed (${artifacts.size} packaged debug APKs; legal attribution preserved)")
}
}
tasks.matching { it.name == "assembleDefaultDebug" }.configureEach { dependsOn(checkWolfskinBranding) }
}
}
}
@ -288,6 +332,7 @@ tasks.named("preBuild") {
}
dependencies {
implementation(project(":wolfskin-design"))
implementation(project(":conductarr-client"))
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
@ -407,8 +452,18 @@ dependencies {
testImplementation(libs.robolectric)
testImplementation(libs.hilt.android.testing)
testImplementation(libs.androidx.compose.ui.test.junit4)
testImplementation("io.github.takahirom.roborazzi:roborazzi:1.77.0")
testImplementation("io.github.takahirom.roborazzi:roborazzi-compose:1.77.0")
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.mockk.android)
androidTestImplementation(libs.hilt.android.testing)
androidTestImplementation(libs.androidx.compose.ui.test.manifest)
}
tasks.withType<Test>().configureEach {
dependsOn(":wolfskin-design:testDebugUnitTest")
systemProperty("robolectric.dependency.dir", project(":wolfskin-design").layout.buildDirectory.dir("robolectric-sdk").get().asFile.absolutePath)
systemProperty("robolectric.offline", "true")
systemProperty("roborazzi.test.record", "true")
systemProperty("wolfskin.captureDirectory", rootProject.layout.buildDirectory.dir("wolfskin-captures").get().asFile.absolutePath)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Some files were not shown because too many files have changed in this diff Show more