refactor(carplay): in-place template updates instead of setRootTemplate spam#3
Draft
jeffcrouse wants to merge 1 commit into
Draft
refactor(carplay): in-place template updates instead of setRootTemplate spam#3jeffcrouse wants to merge 1 commit into
jeffcrouse wants to merge 1 commit into
Conversation
…te spam Call setRootTemplate exactly once (on attachInterfaceController), storing the three child CPListTemplates as bridge properties. Subsequent syncs from the JS coordinator (updateFavorites/updateLibrary/updatePlaylists) now call CPListTemplate.updateSections(_:) on the appropriate stored template rather than rebuilding the full CPTabBarTemplate hierarchy and re-setting the root. Adds RootTemplates struct and per-tab section-builder helpers to RootTemplateBuilder so the bridge can rebuild only items/sections without touching the parent templates. Actions are built once and capture [weak self]. Preserves all [CarPlay] NSLog instrumentation from 4f868a5.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
Picks up the deferred refactor from 4f868a5 ("feat(carplay): land CarPlay scene with resilient browse-state sync"), which wired the end-to-end CarPlay scene and fixed the empty-tabs symptom. That commit explicitly deferred the Apple-API-conformance cleanup to give it a soak window.
What this changes
Before this PR,
CarPlayDataBridgecalledRootTemplateBuilder.buildRootTemplate(...)on every sync arrival from the JS coordinator (3 rapidPromise.allSettledcalls: favorites, library, playlists), producing a freshCPTabBarTemplate+ 3 freshCPListTemplates each time, and callingcontroller.setRootTemplate(...)3+ times in rapid succession. This worked in practice but violates Apple's recommended pattern and risks flicker, dropped updates, or losing the user's navigation state when they've drilled into a child template.After this PR:
setRootTemplateis called exactly once — inattachInterfaceController— with aCPTabBarTemplatewhose three childCPListTemplates are stored as bridge properties (favoritesTemplate,libraryTemplate,playlistsTemplate).updateFavorites→updateLibrary→updatePlaylists) rebuilds only the relevant items/sections and callsCPListTemplate.updateSections(_:)on the appropriate stored template. The tab bar and sibling templates are not touched.detachInterfaceControllerthe stored templates and actions are cleared; a fresh hierarchy is built on the next attach.clearStatecallsupdateSectionson all three templates (empty placeholder state) without touching the root.Implementation details
RootTemplatesstruct toRootTemplateBuildersobuildRootTemplatereturns the tab bar and the three child templates in one call.makeFavoritesSections,makeLibrarySections,makePlaylistsSectionsasinternal statichelpers so the bridge can call them per-update without touching parent templates.Actionsstruct is built once inmakeActions()at attach time; all closures capture[weak self]so they resolve to live bridge state at call time.[CarPlay]NSLog lines from 4f868a5 are preserved; the oldsetRoot favs=…log is updated tosetRoot once favs=…to make it obvious in the simulator console that it fires only once per connect.Testing
pnpm --filter @familiar/frontend test src/__tests__/CarPlayCoordinator.test.ts— 8/8 pass (JS coordinator contract is unchanged; no modifications toCarPlayCoordinator.ts).pnpm --filter @familiar/ios exec tsc --noEmit— only the 2 pre-existing errors inTrackListBrowser.tsxandS3BackupSettings.tsx(both pre-date 4f868a5).Simulator verification is the human's responsibility — this agent cannot run the iOS Simulator. @jeffcrouse please launch the CarPlay simulator from Xcode and confirm:
[CarPlay] setRoot oncefiring exactly once per CarPlay connect, followed by[CarPlay] updateSections …lines for each sync.Generated by Claude Code