ReferenceAPI

Notifications and dialogs

Reference for dd.notify and the dd.dialogs pickers for desktop and folder items.

dd.notify

Needs the notifications permission.

dd.notify.sync()

dd.notify.sync(entries: {
  id: string;      // 1..64 chars, unique within the list
  at: number;      // epoch ms, between now and 366 days ahead
  title: string;   // non-empty, up to 80 chars
  body?: string;   // up to 200 chars
}[]): Promise<{ scheduled: number }>

Replaces this instance's entire schedule of future notifications. Cancelling one means omitting it; an empty array clears them all. There is no per-entry add or remove.

The host keeps the schedule and raises each toast itself, which is the whole point: a hidden or disabled widget stops running, and the app may restart, but the reminder still arrives. Re-send the list whenever it changes, and once on boot.

Behavior and limits:

  • Caps are rejected, never silently clamped: 64 entries, at within a year, title up to 80 characters, body up to 200. Control characters are stripped host-side.
  • An entry more than 15 minutes past its time is dropped unfired rather than stacking, so a machine that slept for a week does not wake to a week of toasts.
  • The toast is a host-drawn window in the corner of the primary work area. The widget supplies text, never markup, and does not control placement, appearance, or timing beyond at. At most 3 toasts are on screen at once.
  • Removing or disabling the instance drops its schedule. Hiding deliberately does not: surviving an unmount is the point.

dd.dialogs

Host-drawn picker windows. Both pickers share the same consent gates and lifecycle:

  • Requires the real cursor inside the widget (call from a click handler), and never opens in edit mode.
  • The picker is a normal OS window (taskbar, Alt-Tab, minimizable) that the host renders and owns; the widget never draws into it, and only ever receives ids back.
  • No client timeout: the promise resolves whenever the user answers. The host force-settles it after 1 hour unanswered, and force-cancels on edit mode, widget reload, hide, disable, remove, or a crash.
  • One picker per kind and instance. Calling again while your picker is open surfaces the existing window, and the new call resolves cancelled immediately.
  • checked pre-checks ids (up to 1024, each up to 64 chars): pass your current selection.
  • The result is a replacement set: cancelled: true means change nothing; otherwise ids is the user's full new checked set, and unchecking is meaningful. Checked ids that no longer exist are carried through untouched.
  • 5 opens per rolling 10 seconds, shared between both pickers.

dd.dialogs.pickDesktopItems()

dd.dialogs.pickDesktopItems(opts?: { checked?: string[] }): Promise<{
  cancelled: boolean;
  ids: string[];
}>

Needs the desktop permission. Picks from the items on the user's desktop (the same set dd.desktop.list returns).

dd.dialogs.pickFolderItems()

dd.dialogs.pickFolderItems(settingKey: string, opts?: { checked?: string[] }): Promise<{
  cancelled: boolean;
  ids: string[];
}>

Needs the folders permission. The same picker aimed at the folder the named filePath setting resolves to. A blank setting value falls through to the desktop picker behind its own desktop grant, so a drawer widget keeps one code path.