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)
This commit is contained in:
pszsh 2026-03-13 12:48:32 -07:00
parent dac85bcb57
commit c57df890aa
3 changed files with 26 additions and 1 deletions

View File

@ -10,6 +10,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
private var monitor: PasteboardMonitor! private var monitor: PasteboardMonitor!
private var clickMonitor: Any? private var clickMonitor: Any?
private var hotkeyRef: EventHotKeyRef? private var hotkeyRef: EventHotKeyRef?
private var lastHideTime: Date?
func applicationDidFinishLaunching(_ notification: Notification) { func applicationDidFinishLaunching(_ notification: Notification) {
store = ClipStore() store = ClipStore()
@ -30,7 +31,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
forName: .dismissShelfPanel, object: nil, queue: .main forName: .dismissShelfPanel, object: nil, queue: .main
) { [weak self] _ in ) { [weak self] _ in
self?.hidePanel() self?.hidePanel()
self?.monitor.syncChangeCount()
} }
} }
@ -75,6 +75,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
} }
private func showPanel() { private func showPanel() {
if let t = lastHideTime, Date().timeIntervalSince(t) > 10 {
NotificationCenter.default.post(name: .resetShelfScroll, object: nil)
}
panel.showAtBottom() panel.showAtBottom()
clickMonitor = NSEvent.addGlobalMonitorForEvents(matching: [.leftMouseDown, .rightMouseDown]) { clickMonitor = NSEvent.addGlobalMonitorForEvents(matching: [.leftMouseDown, .rightMouseDown]) {
@ -88,6 +91,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
} }
private func hidePanel() { private func hidePanel() {
lastHideTime = Date()
ShelfPreviewController.shared.dismiss() ShelfPreviewController.shared.dismiss()
panel.cancelOperation(nil) panel.cancelOperation(nil)
if let m = clickMonitor { if let m = clickMonitor {

View File

@ -118,4 +118,5 @@ class ClipStore: ObservableObject {
extension Notification.Name { extension Notification.Name {
static let dismissShelfPanel = Notification.Name("dismissShelfPanel") static let dismissShelfPanel = Notification.Name("dismissShelfPanel")
static let resetShelfScroll = Notification.Name("resetShelfScroll")
} }

View File

@ -112,6 +112,7 @@ struct ShelfView: View {
@State private var selectedID: UUID? = nil @State private var selectedID: UUID? = nil
@State private var expandedItem: UUID? = nil @State private var expandedItem: UUID? = nil
@State private var expandedSelection: Int? = nil @State private var expandedSelection: Int? = nil
@State private var lastItemCount: Int = 0
private var sortedItems: [ClipItem] { private var sortedItems: [ClipItem] {
store.items.sorted { a, b in 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) .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() { private func collapseExpansion() {
guard expandedItem != nil else { return } guard expandedItem != nil else { return }
withAnimation(.easeOut(duration: 0.15)) { withAnimation(.easeOut(duration: 0.15)) {