diff --git a/src/AppDelegate.swift b/src/AppDelegate.swift index d6310d9..cd76ac0 100644 --- a/src/AppDelegate.swift +++ b/src/AppDelegate.swift @@ -10,6 +10,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { private var monitor: PasteboardMonitor! private var clickMonitor: Any? private var hotkeyRef: EventHotKeyRef? + private var lastHideTime: Date? func applicationDidFinishLaunching(_ notification: Notification) { store = ClipStore() @@ -30,7 +31,6 @@ class AppDelegate: NSObject, NSApplicationDelegate { forName: .dismissShelfPanel, object: nil, queue: .main ) { [weak self] _ in self?.hidePanel() - self?.monitor.syncChangeCount() } } @@ -75,6 +75,9 @@ class AppDelegate: NSObject, NSApplicationDelegate { } private func showPanel() { + if let t = lastHideTime, Date().timeIntervalSince(t) > 10 { + NotificationCenter.default.post(name: .resetShelfScroll, object: nil) + } panel.showAtBottom() clickMonitor = NSEvent.addGlobalMonitorForEvents(matching: [.leftMouseDown, .rightMouseDown]) { @@ -88,6 +91,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { } private func hidePanel() { + lastHideTime = Date() ShelfPreviewController.shared.dismiss() panel.cancelOperation(nil) if let m = clickMonitor { diff --git a/src/ClipStore.swift b/src/ClipStore.swift index afb7a8f..15d6a30 100644 --- a/src/ClipStore.swift +++ b/src/ClipStore.swift @@ -118,4 +118,5 @@ class ClipStore: ObservableObject { extension Notification.Name { static let dismissShelfPanel = Notification.Name("dismissShelfPanel") + static let resetShelfScroll = Notification.Name("resetShelfScroll") } diff --git a/src/ShelfView.swift b/src/ShelfView.swift index 5f30db6..6123e20 100644 --- a/src/ShelfView.swift +++ b/src/ShelfView.swift @@ -112,6 +112,7 @@ struct ShelfView: View { @State private var selectedID: UUID? = nil @State private var expandedItem: UUID? = nil @State private var expandedSelection: Int? = nil + @State private var lastItemCount: Int = 0 private var sortedItems: [ClipItem] { store.items.sorted { a, b in @@ -163,6 +164,15 @@ struct ShelfView: View { } } } + .onChange(of: store.items.count) { + if store.items.count > lastItemCount { + resetToStart(proxy: proxy) + } + lastItemCount = store.items.count + } + .onReceive(NotificationCenter.default.publisher(for: .resetShelfScroll)) { _ in + resetToStart(proxy: proxy) + } } } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom) @@ -224,6 +234,16 @@ struct ShelfView: View { } } + private func resetToStart(proxy: ScrollViewProxy) { + collapseExpansion() + selectedID = nil + if let first = sortedItems.first { + withAnimation(.easeOut(duration: 0.15)) { + proxy.scrollTo(first.id, anchor: .leading) + } + } + } + private func collapseExpansion() { guard expandedItem != nil else { return } withAnimation(.easeOut(duration: 0.15)) {