native macOS codings agent orchestrator
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

Revert "perf(shelf): isolate book switch animation"

This reverts commit eca655a31c0f48da17a15b516253e128c3dc7675.

+11 -57
+11 -57
supacode/Features/Shelf/Views/ShelfView.swift
··· 44 44 45 45 HStack(spacing: 0) { 46 46 if let openIndex { 47 - spineStack( 48 - books: Array(books[0...openIndex]), 49 - openIndex: openIndex, 50 - baseOffset: 0, 51 - animationValue: openBookID 52 - ) 47 + spineStack(books: Array(books[0...openIndex]), openIndex: openIndex, baseOffset: 0) 53 48 openBookArea(for: books[openIndex], state: state) 54 49 .transition(.opacity) 55 - .transaction { transaction in 56 - transaction.animation = nil 57 - } 58 50 let rightStart = openIndex + 1 59 51 if rightStart < books.count { 60 52 spineStack( 61 53 books: Array(books[rightStart..<books.count]), 62 54 openIndex: openIndex, 63 - baseOffset: rightStart, 64 - animationValue: openBookID 55 + baseOffset: rightStart 65 56 ) 66 57 } 67 58 } else { 68 - spineStack(books: books, openIndex: nil, baseOffset: 0, animationValue: openBookID) 59 + spineStack(books: books, openIndex: nil, baseOffset: 0) 69 60 emptyOpenArea() 70 61 } 71 62 } 72 63 .frame(maxWidth: .infinity, maxHeight: .infinity) 73 64 .background(Color(nsColor: .windowBackgroundColor).opacity(surfaceBackgroundOpacity)) 65 + // Animate on every openBookID change — covers both Shelf-originated 66 + // book switches (which also set their own TCA animation) and 67 + // left-nav-originated switches, so the spine flow is consistent 68 + // regardless of entry point. 69 + .animation(.easeInOut(duration: 0.2), value: openBookID) 74 70 } 75 71 76 72 /// `baseOffset` is the index of `books.first` within the full ordered 77 73 /// list, so we can reconstruct each spine's global index and compute 78 74 /// its distance to `openIndex` without re-scanning the full list. 79 75 @ViewBuilder 80 - private func spineStack( 81 - books: [ShelfBook], 82 - openIndex: Int?, 83 - baseOffset: Int, 84 - animationValue: Worktree.ID? 85 - ) -> some View { 76 + private func spineStack(books: [ShelfBook], openIndex: Int?, baseOffset: Int) -> some View { 86 77 HStack(spacing: 0) { 87 78 ForEach(Array(books.enumerated()), id: \.element.id) { localIndex, book in 88 79 let globalIndex = baseOffset + localIndex 89 80 let distance = openIndex.map { abs(globalIndex - $0) } 90 81 let open = globalIndex == openIndex 91 - ShelfSpineContainer( 82 + ShelfSpineView( 92 83 book: book, 93 84 isOpen: open, 94 85 distanceFromOpen: distance, 95 - terminalManager: terminalManager, 86 + terminalState: terminalManager.stateIfExists(for: book.id), 96 87 onOpenBook: { openBook(book, selectingTab: nil) }, 97 88 onSelectTab: { tabID in openBook(book, selectingTab: tabID) }, 98 89 onNewTab: { ··· 114 105 .matchedGeometryEffect(id: book.id, in: spineNamespace) 115 106 } 116 107 } 117 - // Keep the visual spine-flow animation scoped to the lightweight 118 - // spine layer. The terminal content area is intentionally outside 119 - // this transaction so Ghostty/AppKit representables do not inherit a 120 - // book-switch animation. 121 - .animation(.easeInOut(duration: 0.2), value: animationValue) 122 108 } 123 109 124 110 /// Dispatch the open-book action only when `book` isn't already the open ··· 243 229 } 244 230 } 245 231 } 246 - 247 - private struct ShelfSpineContainer: View { 248 - let book: ShelfBook 249 - let isOpen: Bool 250 - let distanceFromOpen: Int? 251 - let terminalManager: WorktreeTerminalManager 252 - let onOpenBook: () -> Void 253 - let onSelectTab: (TerminalTabID) -> Void 254 - let onNewTab: () -> Void 255 - let onSplitVertical: (() -> Void)? 256 - let onSplitHorizontal: (() -> Void)? 257 - let closeMenuTitle: String 258 - let onCloseBook: () -> Void 259 - let onOpenRepositorySettings: () -> Void 260 - 261 - var body: some View { 262 - ShelfSpineView( 263 - book: book, 264 - isOpen: isOpen, 265 - distanceFromOpen: distanceFromOpen, 266 - terminalState: terminalManager.stateIfExists(for: book.id), 267 - onOpenBook: onOpenBook, 268 - onSelectTab: onSelectTab, 269 - onNewTab: onNewTab, 270 - onSplitVertical: onSplitVertical, 271 - onSplitHorizontal: onSplitHorizontal, 272 - closeMenuTitle: closeMenuTitle, 273 - onCloseBook: onCloseBook, 274 - onOpenRepositorySettings: onOpenRepositorySettings 275 - ) 276 - } 277 - }