ContextLab / ContextLab/thunderbird-snooze

build spec

Open
#1 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Description

## Summary

Build a from-scratch, open-source Thunderbird MailExtension that adds **Gmail-style snooze** to email: hide a message from the inbox now, and have it return automatically at a chosen time. It includes a Gmail-style quick-options menu and a slick, themed calendar date/time picker, triggered by a single-key **`b`** shortcut (plus a toolbar button and context menu). It runs **fully locally** — no external service, no Gmail API.

## Why build our own

- Thunderbird has no native snooze.
- Gmail's server-side snooze isn't reachable via IMAP or the Gmail API (we confirmed this), so a Thunderbird key can't trigger real Gmail snooze.
- The polished existing add-on (Snooze Ninja) is paid/closed-source.
- Building our own gives full control over behavior and a UI we can make exactly as slick as we want.

## Goals

- Single-key **`b`** opens a snooze menu, just like Gmail.
- Gmail-style quick presets **plus** a custom date/time picker.
- A **slick, smooth, themed** UI — matches Thunderbird's theme (light/dark) and the OS accent.
- **Reliable local return** of snoozed messages that survives Thunderbird restarts and missed alarms.
- Works with a Gmail (IMAP) account; ideally account-agnostic.

## Non-goals (v1)

- No server-side/cross-device return. The return happens while Thunderbird is running; if TB was closed at the due time, the message returns on next launch. **Document this tradeoff prominently.**
- No mobile, no natural-language time parsing.

## User experience

### Triggering the snooze menu
- Press **`b`** with a message selected/focused in the message list (true single key, like Gmail).
- Also available via a **toolbar button** (message list + reader) and a right-click **"Snooze…"** context menu item.
- Acts on the focused message, or on all selected messages if several are selected.
- `b` must **not** fire while typing in a search box, the quick-filter, a compose window, or any text input (respect focus — mirror tbkeys' `stopCallback`).

### The snooze menu (Gmail-style)
A small popup anchored near the message/toolbar, with rows showing icon + label + the computed return time (right-aligned), hover highlight, and full keyboard nav (↑/↓, Enter, Esc):
- **Later today** — default +3 hours; if that lands too late, fall back to "This evening" 6:00 PM (configurable).
- **Tomorrow** — next day at the morning time (default **8:00 AM**). e.g. "Tomorrow, 8:00 AM".
- **This weekend** — upcoming Saturday at morning time (if already the weekend, next Saturday).
- **Next week** — upcoming Monday at morning time.
- **Pick date & time…** — opens the calendar picker.

### The calendar date/time picker (the slick part)
- Themed month calendar: current month, prev/next navigation, **today** highlighted, past dates disabled.
- Pick a date → choose a time: preset chips (**Morning** 8:00 / **Afternoon** 1:00 / **Evening** 6:00) plus a custom time input.
- Smooth transitions (month slide, selection pop), rounded corners, soft shadow, clear focus rings, a live preview of the resulting return datetime, and Confirm / Cancel.
- Fully keyboard-drivable and accessible.

### Theming & feel
- Match Thunderbird's active theme (light/dark) and OS accent color. Use Thunderbird's in-content theme CSS variables and `prefers-color-scheme`; **no hard-coded colors**.
- Lightweight and instant — vanilla JS + CSS (no heavy framework) for control, load speed, and no layout jank.

## Technical design

### Add-on type & manifest
- Thunderbird **MailExtension**. Recommend **Manifest V2** for the broadest, most stable API coverage on current Thunderbird (revisit MV3 later).
- Permissions (approx.): `messagesRead`, `messagesMove`, `messagesUpdate`/`messagesModify`, `accountsRead`, `folders`, `storage`, `alarms`, `menus`.
- Components: background script; message-display action + browser action (toolbar button + popup); menus; options page; and an **Experiment API** for the single-key `b` handler (below).

### Message & folder operations (MailExtension APIs)
- Target messages via `mailTabs.getSelectedMessages()` / message-display APIs.
- Ensure a **"Snoozed"** folder exists per account (`folders.query` / `folders.create`); on Gmail this becomes a label.
- **Snooze** = `messages.move(ids, snoozedFolder)` + persist a schedule entry.
- **Return** = `messages.move(ids, originalFolder)` + `messages.update(id, {read:false})` (and optionally `{flagged:true}` / a tag) for visibility.

### Scheduling & return
- Persist each snooze in `storage.local`: `{ key, headerMessageId, accountId, originalFolderId, snoozedFolderId, returnAtEpochMs }`. Track by **`headerMessageId`** (stable across moves), since numeric message ids can change.
- Use `browser.alarms` for the next due time; on `onAlarm`, process everything now due.
- On **startup** (and periodically), scan for overdue entries and process them → handles the "TB was closed" case.
- Robustness: local-time math with DST awareness; message-not-found (moved/deleted) → graceful skip; guard against double-returns.

### Keyboard shortcut (single-key `b`)
- The WebExtension `commands` API generally can't bind a bare letter (needs a modifier). For a true single-key `b`, use a small **Experiment API** that installs a `keydown` listener on the `mail:3pane` window — exactly the technique **tbkeys** uses (Mousetrap + a focus-aware `stopCallback`). Reference: `github.com/wshanks/tbkeys` (`addon/implementation.js`, `addon/modules/mousetrap.js`).
- Make the key configurable (default `b`). Ensure it doesn't double-bind if tbkeys is also installed (we intentionally left `b` unbound in tbkeys).
- Note: shipping an Experiment API means the add-on is fully privileged (not a "lite"/store-listable build) — fine for a self-hosted / sideloaded add-on.

### Options / settings
Configurable: morning time, "later today" offset / evening time, weekend day, Snoozed folder name, return behavior (mark unread, flag/tag), the shortcut key, and per-account enable.

## Suggested file layout
```
manifest.json
background.js // scheduler, alarms, orchestration
lib/schedule.js // compute preset datetimes + persistence
lib/messages.js // move / return / ensure-folder / mark helpers
popup/menu.{html,js,css} // Gmail-style quick menu
popup/calendar.{html,js,css} // slick date/time picker
options/options.{html,js,css}
experiment/keys.js + schema.json // single-key `b` handler (tbkeys-style)
icons/
```

## Implementation plan (parallelizable — for batches of agents)
Each task gets its own branch + PR referencing this issue, with frequent commits. After the scaffold, most run in parallel:
- [ ] **T0 Scaffold** — manifest, background stub, build/package to `.xpi`, load in TB. *(blocking)*
- [ ] **T1 Message ops** — ensure Snoozed folder; move to/from; mark unread/flag.
- [ ] **T2 Scheduler** — storage schema, alarms, startup catch-up, edge cases *(interfaces with T1)*.
- [ ] **T3 Snooze menu UI** — Gmail-style quick options + computed times + keyboard nav.
- [ ] **T4 Calendar picker UI** — slick themed date/time selector + animations.
- [ ] **T5 Theming** — light/dark + system accent via TB theme vars; polish *(follows T3/T4)*.
- [ ] **T6 Keyboard `b`** — Experiment API keydown handler (tbkeys-style), configurable.
- [ ] **T7 Toolbar button + context menus.**
- [ ] **T8 Options page.**
- [ ] **T9 Integration + testing** on a real Gmail account *(final)*.

## Testing plan (real messages, no mocks)
- Manual end-to-end on a real Gmail/IMAP account in Thunderbird:
- Snooze via `b` → menu → each preset and a custom date; verify the message leaves the inbox into "Snoozed" and **returns at the chosen time, unread**.
- Return while TB is running (alarm) **and** return after restarting TB across the due time (startup catch-up).
- Multiple selected messages; a threaded conversation.
- Timezone/DST sanity; message deleted/moved before return → graceful no-op.
- UI: screenshots of the menu and calendar in **light and dark** themes; check alignment, contrast, overlap, spacing, and animation smoothness.
- Don't sign off until verified with real examples.

## References / code to borrow
- **tbkeys** (`github.com/wshanks/tbkeys`, MIT-style) — single-key handling via Experiment API + Mousetrap + focus-aware `stopCallback`. Reuse the keyboard technique.
- Open-source Thunderbird snooze add-ons on addons.thunderbird.net (check each listing for a source link — e.g. "Snooze – Remind Me Later", "SnoozeFlow"): reference move/alarm/return mechanics. **Do not** copy non-open code (Snooze Ninja is paid/closed).
- Thunderbird MailExtension API docs: `messages`, `folders`, `alarms`, `menus`, `messageDisplayAction`, `storage`.

## Open questions / decisions to confirm
1. Preset set & default times — confirm: Later today (+3h), Tomorrow 8:00, This weekend Sat 8:00, Next week Mon 8:00. Add "Someday"/"Next month"?
2. Return surfacing — unread only, or also flag/star/tag? (True "bump to top" isn't possible for date-sorted IMAP; unread + flag is the realistic signal. Stretch: investigate re-dating/re-injection to bump — risky.)
3. Scope — account-agnostic, or Gmail-only for v1?
4. Snoozed storage — dedicated "Snoozed" folder/label (recommended). Confirm the name.
5. Manifest V2 vs V3.

## Constraints
- **Repo is public** — never commit private info (email addresses, account data, message contents, tokens). Keep all code generic.
- Local-only; document the "Thunderbird must be running for the timed return" tradeoff prominently in the README.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the proposed manifest.json and T0 scaffold plan, then review the Thunderbird MailExtension APIs and the tbkeys references for the Experiment API approach. The full feature is done only after the listed menu, scheduling, message-operation, shortcut, options, and testing tasks work with real Gmail/IMAP messages, including restart recovery and light/dark UI checks.

Written by the indexing model from the issue text.

Assessment

Tech stack
css, html, javascript
Domain
desktop, frontend, testing
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.