native macOS codings agent orchestrator
6
fork

Configure Feed

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

Reorder worktrees on notifications

khoi 1f0caf57 430bde08

+52 -4
+11 -4
supacode/Features/App/Reducer/AppFeature.swift
··· 438 438 case .updates: 439 439 return .none 440 440 441 - case .terminalEvent(.notificationReceived): 442 - guard state.settings.notificationSoundEnabled else { return .none } 443 - return .run { _ in 444 - await MainActor.run { _ = notificationSound?.play() } 441 + case .terminalEvent(.notificationReceived(let worktreeID, _, _)): 442 + var effects: [Effect<Action>] = [ 443 + .send(.repositories(.worktreeNotificationReceived(worktreeID))) 444 + ] 445 + if state.settings.notificationSoundEnabled { 446 + effects.append( 447 + .run { _ in 448 + await MainActor.run { _ = notificationSound?.play() } 449 + } 450 + ) 445 451 } 452 + return .merge(effects) 446 453 447 454 case .terminalEvent(.notificationIndicatorChanged(let count)): 448 455 state.notificationIndicatorCount = count
+41
supacode/Features/Repositories/Reducer/RepositoriesFeature.swift
··· 88 88 case unpinWorktree(Worktree.ID) 89 89 case presentAlert(title: String, message: String) 90 90 case worktreeInfoEvent(WorktreeInfoWatcherClient.Event) 91 + case worktreeNotificationReceived(Worktree.ID) 91 92 case worktreeBranchNameLoaded(worktreeID: Worktree.ID, name: String) 92 93 case worktreeLineChangesLoaded(worktreeID: Worktree.ID, added: Int, removed: Int) 93 94 case worktreePullRequestLoaded(worktreeID: Worktree.ID, pullRequest: GithubPullRequest?) ··· 876 877 state.alert = errorAlert(title: title, message: message) 877 878 return .none 878 879 880 + case .worktreeNotificationReceived(let worktreeID): 881 + guard let repositoryID = state.repositoryID(containing: worktreeID), 882 + let repository = state.repositories[id: repositoryID], 883 + let worktree = repository.worktrees[id: worktreeID] 884 + else { 885 + return .none 886 + } 887 + if state.isMainWorktree(worktree) || state.isWorktreePinned(worktree) { 888 + return .none 889 + } 890 + let reordered = reorderedUnpinnedWorktreeIDs( 891 + for: worktreeID, 892 + in: repository, 893 + state: state 894 + ) 895 + if state.worktreeOrderByRepository[repositoryID] == reordered { 896 + return .none 897 + } 898 + withAnimation(.snappy(duration: 0.2)) { 899 + state.worktreeOrderByRepository[repositoryID] = reordered 900 + } 901 + let worktreeOrderByRepository = state.worktreeOrderByRepository 902 + return .run { _ in 903 + await repositoryPersistence.saveWorktreeOrderByRepository(worktreeOrderByRepository) 904 + } 905 + 879 906 case .worktreeInfoEvent(let event): 880 907 switch event { 881 908 case .branchChanged(let worktreeID): ··· 1617 1644 } else { 1618 1645 state.worktreeInfoByID[worktreeID] = entry 1619 1646 } 1647 + } 1648 + 1649 + private func reorderedUnpinnedWorktreeIDs( 1650 + for worktreeID: Worktree.ID, 1651 + in repository: Repository, 1652 + state: RepositoriesFeature.State 1653 + ) -> [Worktree.ID] { 1654 + var ordered = state.orderedUnpinnedWorktreeIDs(in: repository) 1655 + guard let index = ordered.firstIndex(of: worktreeID) else { 1656 + return ordered 1657 + } 1658 + ordered.remove(at: index) 1659 + ordered.insert(worktreeID, at: 0) 1660 + return ordered 1620 1661 } 1621 1662 1622 1663 private func restoreSelection(