diff --git a/apps/macos/Sources/MunkelApp/CommandPaletteState.swift b/apps/macos/Sources/MunkelApp/CommandPaletteState.swift index 557b59dc..1677dca5 100644 --- a/apps/macos/Sources/MunkelApp/CommandPaletteState.swift +++ b/apps/macos/Sources/MunkelApp/CommandPaletteState.swift @@ -88,11 +88,33 @@ final class CommandPaletteState: ObservableObject { } func reset() { - selectedIndex = 0 + selectedIndex = rememberedIndex message = "" attachedImages = [] } + // MARK: - Remembered target + + private static let lastChannelKey = "lastPaletteChannel" + private static let lastMemberKey = "lastPaletteMember" + + func select(_ index: Int) { + guard let recipient = recipients[safe: index] else { return } + selectedIndex = index + UserDefaults.standard.set(recipient.channel, forKey: Self.lastChannelKey) + UserDefaults.standard.set(recipient.memberId, forKey: Self.lastMemberKey) + } + + private var rememberedIndex: Int { + let defaults = UserDefaults.standard + guard let channel = defaults.string(forKey: Self.lastChannelKey) else { return 0 } + let member = defaults.string(forKey: Self.lastMemberKey) + let all = recipients + let sameTarget = all.firstIndex { $0.channel == channel && $0.memberId == member } + let sameChannel = all.firstIndex { $0.channel == channel } + return sameTarget ?? sameChannel ?? 0 + } + // MARK: - Recipient navigation enum Direction { case up, down } @@ -126,17 +148,17 @@ final class CommandPaletteState: ObservableObject { switch dir { case .up: if single { - selectedIndex = max(here.lowerBound, selectedIndex - 1) + select(max(here.lowerBound, selectedIndex - 1)) } else { let target = ranges[max(0, row - 1)] - selectedIndex = target.lowerBound + min(col, target.count - 1) + select(target.lowerBound + min(col, target.count - 1)) } case .down: if single { - selectedIndex = min(here.upperBound - 1, selectedIndex + 1) + select(min(here.upperBound - 1, selectedIndex + 1)) } else { let target = ranges[min(ranges.count - 1, row + 1)] - selectedIndex = target.lowerBound + min(col, target.count - 1) + select(target.lowerBound + min(col, target.count - 1)) } } } @@ -148,9 +170,9 @@ final class CommandPaletteState: ObservableObject { guard !r.isEmpty else { return } if backward { - selectedIndex = selectedIndex == 0 ? r.count - 1 : selectedIndex - 1 + select(selectedIndex == 0 ? r.count - 1 : selectedIndex - 1) } else { - selectedIndex = selectedIndex == r.count - 1 ? 0 : selectedIndex + 1 + select(selectedIndex == r.count - 1 ? 0 : selectedIndex + 1) } } } diff --git a/apps/macos/Sources/MunkelApp/CommandPaletteView.swift b/apps/macos/Sources/MunkelApp/CommandPaletteView.swift index 43f60768..7e982597 100644 --- a/apps/macos/Sources/MunkelApp/CommandPaletteView.swift +++ b/apps/macos/Sources/MunkelApp/CommandPaletteView.swift @@ -90,6 +90,12 @@ struct CommandPaletteView: View { proxy.scrollTo(state.selectedIndex, anchor: .center) } } + .onAppear { + Task { + try? await Task.sleep(for: .milliseconds(80)) + proxy.scrollTo(state.selectedIndex, anchor: .center) + } + } } } } @@ -119,7 +125,7 @@ struct CommandPaletteView: View { private func chip(_ recipient: Recipient, index: Int) -> some View { let selected = index == state.selectedIndex return Button { - state.selectedIndex = index + state.select(index) focused = true } label: { HStack(spacing: 5) {