Skip to content

fix: delete a sticky note on close instead of only hiding it - #345

Open
itzmekhokan wants to merge 3 commits into
WordPress:trunkfrom
itzmekhokan:fix/344-sticky-note-delete
Open

fix: delete a sticky note on close instead of only hiding it#345
itzmekhokan wants to merge 3 commits into
WordPress:trunkfrom
itzmekhokan:fix/344-sticky-note-delete

Conversation

@itzmekhokan

Copy link
Copy Markdown
Contributor

Summary

Fixes #344.

The sticky-note title-bar × was labelled "Hide sticky note" and only called layer.forget() — an in-memory eviction. The backing wp_guideline post was never touched, so the note reappeared on the next heartbeat tick, page reload, or any desktop re-render. Since the × was the only removal affordance, a note could never actually be deleted.

Fix

Make the × delete the note, following the same soft-trash + Undo pattern the desktop-files layer (trashPlacementWithUndo) already uses:

  • rest.ts — add deleteStickyNote() (REST trash, not force, so it stays recoverable) and restoreStickyNote() (untrash by flipping status back to private). fetchStickyNotes only queries status: 'private', so a trashed note never re-hydrates onto the desktop.
  • layer.ts — the × now trashes the note with optimistic eviction and an Undo toast, and is relabelled "Delete sticky note". A dismissedIds guard drops any in-flight heartbeat/reload echo for a just-deleted id so it can't resurrect the note before the trash propagates.
  • A note created and closed inside the save debounce is persisted first (save() now hands callers its in-flight promise) so there's always a server row to trash — closing the create-then-delete race behind the intermittent resurrection.

No behaviour change for the "empty, never-saved note" case (still dropped locally with no round-trip).

Testing

  • npm run typecheck, npm run lint — clean
  • npm run test:js1610 pass (adds 2 tests: the × trashes + evicts the note, and a stale heartbeat echo can't re-add a deleted note)
  • Manual, in wp-env:

itzmekhokan and others added 2 commits July 14, 2026 10:24
The note's title-bar × was labelled "Hide sticky note" and only called
layer.forget() — an in-memory eviction. The backing wp_guideline post
survived, so the note reappeared on the next heartbeat tick, reload, or
any desktop re-render. With no other removal affordance, notes could
never actually be deleted (GH#344).

Make the × delete the note, following the same soft-trash + Undo pattern
the desktop-files layer already uses:

- rest.ts: add deleteStickyNote() (REST trash, not force, so it stays
  recoverable) and restoreStickyNote() (untrash by flipping status back
  to private). fetchStickyNotes only queries status=private, so a
  trashed note never re-hydrates.
- layer.ts: the × now trashes the note with optimistic eviction and an
  Undo toast; relabel it "Delete sticky note". A `dismissedIds` guard
  drops any in-flight heartbeat/reload echo for a just-deleted id so it
  can't resurrect the note before the trash propagates.
- A note created and closed inside the save debounce is persisted first
  (save() now hands callers the in-flight promise) so there's always a
  server row to trash — closing the create-then-delete race that caused
  the intermittent resurrection.

Adds vitest coverage for the trash path and the heartbeat-echo guard.
Verified in wp-env: deleting a note trashes the post and it no longer
returns after a reload; Undo restores it.
@AllTerrainDeveloper

Copy link
Copy Markdown
Collaborator

Hey Thanks for your contribution! I'll ask the person who made the Sticky Notes, not sure if he really intended to hide for the session or close them forever. @artpi?

renderToast() flipped the enter state ("in") inside a
requestAnimationFrame so the CSS fade runs after first paint. rAF is
paused while the tab is hidden/backgrounded, so a toast raised then
stayed at opacity:0 — and could hit its dismiss timer before ever
showing. Pair the rAF with a setTimeout fallback (which still fires in
a hidden tab); the enter callback is idempotent, so whichever runs
first wins and the other is a no-op.
@AllTerrainDeveloper

Copy link
Copy Markdown
Collaborator

I'll reach Artur internally 😆

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Closing a sticky note doesn't delete it — the note reappears on the next desktop render

2 participants