Show a notification the sender updated, instead of the version it replaced
A client that updates a notification through replaces_id does not produce a second onNotification: Quickshell writes the new content onto the Notification object the shell is already holding. The card draws a snapshot copied out of that object — deliberately, since a live QObject in a ListModel role becomes a dangling pointer the moment the server destroys it — so the toast kept showing the superseded text, and archived it to history when it left the screen. A Slack thread that updates in place read as stuck. Every property the card draws is now watched on the notification we hold, and a change rewrites both the model row and the file the popup was persisted under. The file name is that popup's identity, so the rewrite lands in place: a shell restart restores the version last shown, and so does the copy that reaches history. The countdown starts over when the content changes. New text arriving a second before the toast was due to expire deserves a full look, not the remainder of the clock the text it replaced had nearly run through. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ab57ad65fd
commit
cd84583b56
@@ -124,6 +124,53 @@ assertDeepEqual(
|
||||
'notifications create stable snapshots'
|
||||
)
|
||||
|
||||
// An in-place update keeps the popup's identity — the file name it was
|
||||
// persisted under — and takes everything the card draws from the new content.
|
||||
const replacement = notifications.replacementSnapshot(
|
||||
{
|
||||
id: 12,
|
||||
appName: 'Slack',
|
||||
summary: 'Thread v2',
|
||||
body: 'message 2',
|
||||
image: 'file:///tmp/new.png',
|
||||
hints: { 'omarchy-glyph': '!' },
|
||||
urgency: 2,
|
||||
expireTimeout: 4000
|
||||
},
|
||||
12,
|
||||
12345
|
||||
)
|
||||
assertDeepEqual(
|
||||
{
|
||||
id: replacement.id,
|
||||
originalId: replacement.originalId,
|
||||
timestamp: replacement.timestamp,
|
||||
summary: replacement.summary,
|
||||
body: replacement.body,
|
||||
image: replacement.image,
|
||||
glyph: replacement.glyph,
|
||||
urgency: replacement.urgency,
|
||||
expireTimeout: replacement.expireTimeout
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
originalId: 12,
|
||||
timestamp: 12345,
|
||||
summary: 'Thread v2',
|
||||
body: 'message 2',
|
||||
image: 'file:///tmp/new.png',
|
||||
glyph: '!',
|
||||
urgency: 2,
|
||||
expireTimeout: 4000
|
||||
},
|
||||
'notifications take updated content without moving the popup it replaces'
|
||||
)
|
||||
assertEqual(
|
||||
notifications.popupFileName(replacement),
|
||||
'12345-12.json',
|
||||
'notifications keep the persisted file name across an in-place update'
|
||||
)
|
||||
|
||||
const settings = notifications.parseSettings(JSON.stringify({ version: 3, dnd: true }))
|
||||
assertEqual(settings.dnd, true, 'notifications parse the persisted DND state')
|
||||
assertEqual(settings.legacy, false, 'notifications do not flag a current settings file as legacy')
|
||||
@@ -315,6 +362,22 @@ assert(
|
||||
/service\.replayCarryOver = liveRowsForReplay\(\)/.test(serviceQml),
|
||||
'notifications service carries the toasts still on screen into the replay'
|
||||
)
|
||||
assert(
|
||||
/watchForUpdates\(notification, snapshot\)/.test(serviceQml),
|
||||
'notifications service watches a shown notification for in-place updates'
|
||||
)
|
||||
assert(
|
||||
/if \(signal && typeof signal\.connect === "function"\) signal\.connect\(refresh\)/.test(serviceQml),
|
||||
'notifications service refreshes the popup from every property the card draws'
|
||||
)
|
||||
assert(
|
||||
/popupModel\.setProperty\(i, "summary", updated\.summary\)[\s\S]{0,600}?persistPopupFile\(updated\)/.test(serviceQml),
|
||||
'notifications service rewrites both the row and its file when a notification is updated in place'
|
||||
)
|
||||
assert(
|
||||
/onSummaryChanged: cardSlot\.remainingLifetime = 1\.0/.test(serviceQml),
|
||||
'notifications service restarts the countdown when a toast is updated under it'
|
||||
)
|
||||
assert(
|
||||
/awk 1 \\"\$1\\"\/\*\.json 2>\/dev\/null \|\| true", "--", historyDir/.test(serviceQml),
|
||||
'notifications service replays history by reading the archived files'
|
||||
|
||||
Reference in New Issue
Block a user