WIP: hide empty collection count pills
This commit is contained in:
@@ -49,15 +49,16 @@ Use this checklist before a release or after changes to panel, pasteboard, setti
|
|||||||
16. Return to Clipboard, select a card, use its Collect button to choose Client Work, and confirm the Client Work chip count increases.
|
16. Return to Clipboard, select a card, use its Collect button to choose Client Work, and confirm the Client Work chip count increases.
|
||||||
17. Select the Client Work chip and confirm the rail filters to assigned items, cards use the Client Work name/color in their headers, and the collection/color/assignment persists after quitting and reopening ClipBored.
|
17. Select the Client Work chip and confirm the rail filters to assigned items, cards use the Client Work name/color in their headers, and the collection/color/assignment persists after quitting and reopening ClipBored.
|
||||||
18. Right-click the Client Work chip, choose Edit Collection..., rename it, change its color, and confirm the chip and assigned card headers update.
|
18. Right-click the Client Work chip, choose Edit Collection..., rename it, change its color, and confirm the chip and assigned card headers update.
|
||||||
19. Right-click a media, file, link, PDF, audio, or text card, choose Rename..., give it a title, and confirm the card title and search results use the custom title while paste/copy still uses the original payload.
|
19. Confirm collection chips with 0 clips do not show a visible count pill, while chips with clips still show their counts.
|
||||||
20. Double-click an item and confirm it attempts to paste or falls back to copy without creating a duplicate history entry.
|
20. Right-click a media, file, link, PDF, audio, or text card, choose Rename..., give it a title, and confirm the card title and search results use the custom title while paste/copy still uses the original payload.
|
||||||
21. Right-click a card, use Capture Rules to ignore its source app, copy from that app again, and confirm the new item is skipped.
|
21. Double-click an item and confirm it attempts to paste or falls back to copy without creating a duplicate history entry.
|
||||||
22. Drag an unassigned card onto the renamed collection chip and confirm the chip count increases and the card appears when that collection is selected.
|
22. Right-click a card, use Capture Rules to ignore its source app, copy from that app again, and confirm the new item is skipped.
|
||||||
23. Resize or test on a narrow display and confirm the bottom shelf switches to compact cards that still show two recent clips cleanly.
|
23. Drag an unassigned card onto the renamed collection chip and confirm the chip count increases and the card appears when that collection is selected.
|
||||||
24. Select a file, rich text, or URL card and confirm the selected-card rail exposes `Paste Plain Text`, the corner source/kind badge remains visible, and on a narrow shelf secondary actions collapse behind `More` instead of overflowing the card.
|
24. Resize or test on a narrow display and confirm the bottom shelf switches to compact cards that still show two recent clips cleanly.
|
||||||
25. Confirm card footers do not show `Unknown` for clips without a source app, and confirm used clips show their usage count beside the source app.
|
25. Select a file, rich text, or URL card and confirm the selected-card rail exposes `Paste Plain Text`, the corner source/kind badge remains visible, and on a narrow shelf secondary actions collapse behind `More` instead of overflowing the card.
|
||||||
26. Confirm card headers use readable relative ages such as `3 minutes ago` or `2 hours ago`, including when viewing a named collection.
|
26. Confirm card footers do not show `Unknown` for clips without a source app, and confirm used clips show their usage count beside the source app.
|
||||||
27. Confirm the selected card shows a green corner Stack control, the action rail does not duplicate Stack, and clips added to Stack keep a visible corner indicator when selection moves away.
|
27. Confirm card headers use readable relative ages such as `3 minutes ago` or `2 hours ago`, including when viewing a named collection.
|
||||||
|
28. Confirm the selected card shows a green corner Stack control, the action rail does not duplicate Stack, and clips added to Stack keep a visible corner indicator when selection moves away.
|
||||||
|
|
||||||
## Copy And Paste
|
## Copy And Paste
|
||||||
|
|
||||||
|
|||||||
@@ -1493,6 +1493,11 @@ final class ClipboardPanelView: NSVisualEffectView, NSSearchFieldDelegate {
|
|||||||
return ClipboardSortMode.allCases.compactMap { collectionButtons[$0]?.count }
|
return ClipboardSortMode.allCases.compactMap { collectionButtons[$0]?.count }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var debugCollectionCountLabelHiddenStates: [Bool] {
|
||||||
|
updateCollectionButtons()
|
||||||
|
return ClipboardSortMode.allCases.compactMap { collectionButtons[$0]?.debugCountLabelIsHidden }
|
||||||
|
}
|
||||||
|
|
||||||
var debugCollectionChipAccessibilityLabels: [String] {
|
var debugCollectionChipAccessibilityLabels: [String] {
|
||||||
updateCollectionButtons()
|
updateCollectionButtons()
|
||||||
return ClipboardSortMode.allCases.compactMap { collectionButtons[$0]?.accessibilityLabel() }
|
return ClipboardSortMode.allCases.compactMap { collectionButtons[$0]?.accessibilityLabel() }
|
||||||
@@ -1565,6 +1570,11 @@ final class ClipboardPanelView: NSVisualEffectView, NSSearchFieldDelegate {
|
|||||||
return viewModel.collectionNames.compactMap { customCollectionButtons[$0]?.count }
|
return viewModel.collectionNames.compactMap { customCollectionButtons[$0]?.count }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var debugCustomCollectionCountLabelHiddenStates: [Bool] {
|
||||||
|
updateCollectionButtons()
|
||||||
|
return viewModel.collectionNames.compactMap { customCollectionButtons[$0]?.debugCountLabelIsHidden }
|
||||||
|
}
|
||||||
|
|
||||||
var debugCustomCollectionColorHexes: [String: String] {
|
var debugCustomCollectionColorHexes: [String: String] {
|
||||||
Dictionary(uniqueKeysWithValues: viewModel.collectionNames.map { name in
|
Dictionary(uniqueKeysWithValues: viewModel.collectionNames.map { name in
|
||||||
(name, ClipboardCollectionVisuals.hexString(for: collectionColor(forCollectionNamed: name)))
|
(name, ClipboardCollectionVisuals.hexString(for: collectionColor(forCollectionNamed: name)))
|
||||||
@@ -2109,6 +2119,7 @@ private final class CollectionChipView: NSView {
|
|||||||
? NSColor.controlAccentColor.withAlphaComponent(0.16)
|
? NSColor.controlAccentColor.withAlphaComponent(0.16)
|
||||||
: NSColor.labelColor.withAlphaComponent(0.07)
|
: NSColor.labelColor.withAlphaComponent(0.07)
|
||||||
).cgColor
|
).cgColor
|
||||||
|
updateCountLabelVisibility()
|
||||||
updateAccessibility()
|
updateAccessibility()
|
||||||
updateChrome()
|
updateChrome()
|
||||||
}
|
}
|
||||||
@@ -2138,9 +2149,14 @@ private final class CollectionChipView: NSView {
|
|||||||
func setCount(_ count: Int) {
|
func setCount(_ count: Int) {
|
||||||
self.count = count
|
self.count = count
|
||||||
countLabel.stringValue = count > 999 ? "999+" : "\(count)"
|
countLabel.stringValue = count > 999 ? "999+" : "\(count)"
|
||||||
|
updateCountLabelVisibility()
|
||||||
updateAccessibility()
|
updateAccessibility()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func updateCountLabelVisibility() {
|
||||||
|
countLabel.isHidden = count == 0
|
||||||
|
}
|
||||||
|
|
||||||
private func updateAccessibility() {
|
private func updateAccessibility() {
|
||||||
let noun = count == 1 ? "clip" : "clips"
|
let noun = count == 1 ? "clip" : "clips"
|
||||||
let selectedText = isSelected ? "selected, " : ""
|
let selectedText = isSelected ? "selected, " : ""
|
||||||
@@ -2291,6 +2307,10 @@ private final class CollectionChipView: NSView {
|
|||||||
isKeyboardFocused
|
isKeyboardFocused
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var debugCountLabelIsHidden: Bool {
|
||||||
|
countLabel.isHidden
|
||||||
|
}
|
||||||
|
|
||||||
func debugDropItem(_ itemID: UUID) {
|
func debugDropItem(_ itemID: UUID) {
|
||||||
onDropItem?(itemID)
|
onDropItem?(itemID)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ final class ClipboardPanelViewTests: XCTestCase {
|
|||||||
fixture.window.contentView?.layoutSubtreeIfNeeded()
|
fixture.window.contentView?.layoutSubtreeIfNeeded()
|
||||||
|
|
||||||
XCTAssertEqual(fixture.view.debugCollectionChipAcceptsFirstResponder, Array(repeating: true, count: ClipboardSortMode.allCases.count))
|
XCTAssertEqual(fixture.view.debugCollectionChipAcceptsFirstResponder, Array(repeating: true, count: ClipboardSortMode.allCases.count))
|
||||||
|
XCTAssertEqual(fixture.view.debugCollectionCountLabelHiddenStates, Array(repeating: true, count: ClipboardSortMode.allCases.count))
|
||||||
XCTAssertEqual(fixture.view.debugCollectionChipAccessibilityLabels.first, "Clipboard, selected, 0 clips")
|
XCTAssertEqual(fixture.view.debugCollectionChipAccessibilityLabels.first, "Clipboard, selected, 0 clips")
|
||||||
|
|
||||||
XCTAssertTrue(fixture.view.debugFocusCollectionChip(.links))
|
XCTAssertTrue(fixture.view.debugFocusCollectionChip(.links))
|
||||||
@@ -326,6 +327,7 @@ final class ClipboardPanelViewTests: XCTestCase {
|
|||||||
XCTAssertEqual(fixture.viewModel.statusMessage, "Created Research Stack")
|
XCTAssertEqual(fixture.viewModel.statusMessage, "Created Research Stack")
|
||||||
XCTAssertEqual(fixture.view.debugCustomCollectionTitles, ["Research Stack"])
|
XCTAssertEqual(fixture.view.debugCustomCollectionTitles, ["Research Stack"])
|
||||||
XCTAssertEqual(fixture.view.debugCustomCollectionCounts, [0])
|
XCTAssertEqual(fixture.view.debugCustomCollectionCounts, [0])
|
||||||
|
XCTAssertEqual(fixture.view.debugCustomCollectionCountLabelHiddenStates, [true])
|
||||||
XCTAssertEqual(fixture.view.debugSelectedCollectionTitle, "Research Stack")
|
XCTAssertEqual(fixture.view.debugSelectedCollectionTitle, "Research Stack")
|
||||||
XCTAssertEqual(fixture.view.debugVisibleCardCount, 0)
|
XCTAssertEqual(fixture.view.debugVisibleCardCount, 0)
|
||||||
XCTAssertEqual(fixture.view.debugEmptyStateText?.title, "No clips in Research Stack")
|
XCTAssertEqual(fixture.view.debugEmptyStateText?.title, "No clips in Research Stack")
|
||||||
@@ -624,6 +626,7 @@ final class ClipboardPanelViewTests: XCTestCase {
|
|||||||
XCTAssertEqual(fixture.viewModel.visibleItems.count, 6)
|
XCTAssertEqual(fixture.viewModel.visibleItems.count, 6)
|
||||||
XCTAssertEqual(ClipboardSortMode.allCases.map { fixture.viewModel.collectionCount(for: $0) }, [6, 6, 2, 1, 1, 1, 1, 1])
|
XCTAssertEqual(ClipboardSortMode.allCases.map { fixture.viewModel.collectionCount(for: $0) }, [6, 6, 2, 1, 1, 1, 1, 1])
|
||||||
XCTAssertEqual(fixture.view.debugCollectionCounts, [6, 6, 2, 1, 1, 1, 1, 1])
|
XCTAssertEqual(fixture.view.debugCollectionCounts, [6, 6, 2, 1, 1, 1, 1, 1])
|
||||||
|
XCTAssertEqual(fixture.view.debugCollectionCountLabelHiddenStates, Array(repeating: false, count: ClipboardSortMode.allCases.count))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCollectionRailShowsAssignedCollections() {
|
func testCollectionRailShowsAssignedCollections() {
|
||||||
@@ -642,6 +645,7 @@ final class ClipboardPanelViewTests: XCTestCase {
|
|||||||
|
|
||||||
XCTAssertEqual(fixture.view.debugCustomCollectionTitles, ["Useful Links", "Important Notes", "Client Work"])
|
XCTAssertEqual(fixture.view.debugCustomCollectionTitles, ["Useful Links", "Important Notes", "Client Work"])
|
||||||
XCTAssertEqual(fixture.view.debugCustomCollectionCounts, [1, 1, 1])
|
XCTAssertEqual(fixture.view.debugCustomCollectionCounts, [1, 1, 1])
|
||||||
|
XCTAssertEqual(fixture.view.debugCustomCollectionCountLabelHiddenStates, [false, false, false])
|
||||||
|
|
||||||
fixture.viewModel.selectCollection(named: "Useful Links")
|
fixture.viewModel.selectCollection(named: "Useful Links")
|
||||||
drainMainQueue()
|
drainMainQueue()
|
||||||
|
|||||||
Reference in New Issue
Block a user