From c57df890aaddb45cd27d4842dd4727c63aa6821e Mon Sep 17 00:00:00 2001 From: pszsh Date: Fri, 13 Mar 2026 12:48:32 -0700 Subject: [PATCH] Couple bugs fixed: - Copying an old item brings it to the top as intended - UI touch ups It's pretty much solid now, though, time may tell things unknown to me right now. But, if so, I'll fix em'. It's ready for use, install this sh*t if you don't want to buy any of those other ones that have nothing that this one does not (or at least, this does exactly what Paste does and looks very similar) --- src/AppDelegate.swift | 6 +++++- src/ClipStore.swift | 1 + src/ShelfView.swift | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) 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)) {