Grey the toolbar icon while the testing switch is on or Postulo cannot be reached #4

Closed
opened 2026-09-30 15:19:44 +00:00 by tiagoagueda · 0 comments
Owner

The toolbar icon never changes: the only action calls in src set the badge (showUnsentCount(), src/lib/local.js:30-35). Nor does the extension know whether Postulo answers unless it is sending: with nothing waiting, deliver() returns nothing before reading the settings or contacting anything (src/lib/outbox.js:32-37), and lastDelivery (src/lib/local.js:24-26) is written and never read. This issue greys the icon while the testing switch is on or Postulo cannot be reached, and owns the connection state that #5 and #9 also read.

“Working offline” is read as the testing switch, the code's offline; a real failure is the outcome unreachable. Read as the device having no network, that fails like an unreachable Postulo: grey either way.

What the extension should do

  1. One connection state in storage.local, with when and how it was learnt: not set up, testing, no permission, token refused, unreachable or reachable.
  2. Written by the background on the five-minute alarm, at onStartup and onInstalled, when instance, token or offline change, and when the host permission is granted or withdrawn (permissions.onAdded, onRemoved); and from the outcome of POST /captures, POST /captures/known, and Test's GET /me when it tested the saved address and token (it takes what is typed: src/options.js:94-106). No check is made in testing (nothing may be sent), when not set up, or without the permission.
  3. Read by the icon, the popup footer (#9) and the badge (#5); the background repaints the icon whenever it changes.
  4. The icon is grey in every state but reachable, global (no tabId) and set again at onStartup and onInstalled, as the badge is: browsers forget action changes on restart. Grey, not disabled: a disabled action opens no popup, and capturing must work with Postulo away.
  5. Why, in words, never colour alone (the extension's rule, src/style.css:450): action.setTitle gives the reason, then the button's title (actionTitle). notConnected, offlineOn, noPermission and tokenRefused exist; waiting is about one capture just sent, so unreachable needs a new sentence, for example “Postulo cannot be reached: what you send waits in this browser until it answers.”

Decisions for this repository

  • Which states are grey. The suggestion names the testing switch and Postulo unreachable (nothing within the 20 s timeout, a network error, a 5xx, /healthz answering 503). Proposed too: not set up, since nothing reaches Postulo; token refused (401 or 403) and host permission missing, since nothing is sent or accepted until the settings are fixed. The alternative: these three in colour, said only in the popup. A 429 means Postulo answered, so reachable; deliver() reports it as unreachable today (kindOfFailure()), so the record goes by the status code. Recommended: grey for all five; not for a 429.
  • The check. GET /healthz is public, needs no token, is neither throttled nor cached, costs about one query and answers 503 when the database is down (the core's src/postulo/core/views.py), but proves nothing about the token. GET /api/v1/me proves it but spends one of the token's 600 calls an hour (the default), shared with captures. Recommended: /healthz, with no token and no cookies; the token's state from the last real call that carried it (a token revoked since shows at the next send), and GET /me, checking for captures as Test does, only when that is unknown, after saving. A 4xx from /healthz (a proxy blocking it) means the host answered: fall back to GET /me.
  • The grey image. A grey 16 and 32 pair from scripts/icons.py, which would desaturate what the core's rendered() draws, committed and switched with setIcon({path}); or drawn at run time with OffscreenCanvas and a grayscale(1) filter, available in both backgrounds. Recommended: icons.py: no drawing code, the same pixels in both browsers. Check it on a dark toolbar too.
  • lastDelivery: kept, or replaced by the record. Recommended: replaced.

The browser behaviour here is documented (Chrome, MDN), not tried in a real browser. Chrome keeps the icon in its extensions menu until pinned. Where Firefox puts the button, and the title doubling as the menu label on Firefox for Android: postulo/postulo-firefox#3.

Needs from the server

Nothing: /healthz and GET /me exist. Not filed on postulo/postulo.

Documents and translations

  • PRIVACY.md says “exactly three” requests. A periodic GET /healthz is a fourth: no token and nothing of the person's, though it tells their server the browser is running, and from where; “Nothing is ever sent that you did not press Send on” must name it as the exception. GET /me after saving extends the Test row. The list of what is kept, and the date, change too.
  • README.md: the layout table's src/background.js row, and src/icons/ if grey icons are committed.
  • test/i18n.test.mjs requires every new key in all 40 _locales at once, with identical placeholders: each new sentence costs 40 translations in the same commit.

Done when

  • The testing switch greys the icon at once, the tooltip naming it, and nothing reaches Postulo; off, colour returns after one check.
  • With Postulo stopped, grey after a failed send or at the next alarm, the tooltip saying so; colour at the first check it answers.
  • Not set up, token refused and permission missing show as decided, with their reasons.
  • After a browser restart, icon and tooltip are right before the popup opens.
  • A pure function from settings and record to image and tooltip is tested with node --test, like test/outbox.test.mjs.
  • PRIVACY.md and README.md describe the new behaviour.

From the list of extension improvements of 2026-09-30.

The toolbar icon never changes: the only action calls in `src` set the badge (`showUnsentCount()`, `src/lib/local.js:30-35`). Nor does the extension know whether Postulo answers unless it is sending: with nothing waiting, `deliver()` returns `nothing` before reading the settings or contacting anything (`src/lib/outbox.js:32-37`), and `lastDelivery` (`src/lib/local.js:24-26`) is written and never read. This issue greys the icon while the testing switch is on or Postulo cannot be reached, and owns the connection state that #5 and #9 also read. “Working offline” is read as the testing switch, the code's `offline`; a real failure is the outcome `unreachable`. Read as the device having no network, that fails like an unreachable Postulo: grey either way. ## What the extension should do 1. **One connection state** in storage.local, with when and how it was learnt: not set up, testing, no permission, token refused, unreachable or reachable. 2. **Written** by the background on the five-minute alarm, at `onStartup` and `onInstalled`, when `instance`, `token` or `offline` change, and when the host permission is granted or withdrawn (`permissions.onAdded`, `onRemoved`); and from the outcome of `POST /captures`, `POST /captures/known`, and *Test*'s `GET /me` when it tested the saved address and token (it takes what is typed: `src/options.js:94-106`). No check is made in testing (nothing may be sent), when not set up, or without the permission. 3. **Read** by the icon, the popup footer (#9) and the badge (#5); the background repaints the icon whenever it changes. 4. **The icon** is grey in every state but reachable, global (no `tabId`) and set again at `onStartup` and `onInstalled`, as the badge is: browsers forget action changes on restart. Grey, not disabled: a disabled action opens no popup, and capturing must work with Postulo away. 5. **Why, in words**, never colour alone (the extension's rule, `src/style.css:450`): `action.setTitle` gives the reason, then the button's title (`actionTitle`). `notConnected`, `offlineOn`, `noPermission` and `tokenRefused` exist; `waiting` is about one capture just sent, so unreachable needs a new sentence, for example “Postulo cannot be reached: what you send waits in this browser until it answers.” ## Decisions for this repository - **Which states are grey.** The suggestion names the testing switch and Postulo unreachable (nothing within the 20 s timeout, a network error, a 5xx, `/healthz` answering 503). Proposed too: not set up, since nothing reaches Postulo; token refused (401 or 403) and host permission missing, since nothing is sent or accepted until the settings are fixed. The alternative: these three in colour, said only in the popup. A 429 means Postulo answered, so reachable; `deliver()` reports it as `unreachable` today (`kindOfFailure()`), so the record goes by the status code. **Recommended:** grey for all five; not for a 429. - **The check.** `GET /healthz` is public, needs no token, is neither throttled nor cached, costs about one query and answers 503 when the database is down (the core's `src/postulo/core/views.py`), but proves nothing about the token. `GET /api/v1/me` proves it but spends one of the token's 600 calls an hour (the default), shared with captures. **Recommended:** `/healthz`, with no token and no cookies; the token's state from the last real call that carried it (a token revoked since shows at the next send), and `GET /me`, checking for `captures` as *Test* does, only when that is unknown, after saving. A 4xx from `/healthz` (a proxy blocking it) means the host answered: fall back to `GET /me`. - **The grey image.** A grey 16 and 32 pair from `scripts/icons.py`, which would desaturate what the core's `rendered()` draws, committed and switched with `setIcon({path})`; or drawn at run time with `OffscreenCanvas` and a `grayscale(1)` filter, available in both backgrounds. **Recommended:** `icons.py`: no drawing code, the same pixels in both browsers. Check it on a dark toolbar too. - **`lastDelivery`**: kept, or replaced by the record. **Recommended:** replaced. The browser behaviour here is documented (Chrome, MDN), not tried in a real browser. Chrome keeps the icon in its extensions menu until pinned. Where Firefox puts the button, and the title doubling as the menu label on Firefox for Android: postulo/postulo-firefox#3. ## Needs from the server Nothing: `/healthz` and `GET /me` exist. Not filed on postulo/postulo. ## Documents and translations - `PRIVACY.md` says “exactly three” requests. A periodic `GET /healthz` is a fourth: no token and nothing of the person's, though it tells their server the browser is running, and from where; “Nothing is ever sent that you did not press Send on” must name it as the exception. `GET /me` after saving extends the *Test* row. The list of what is kept, and the date, change too. - `README.md`: the layout table's `src/background.js` row, and `src/icons/` if grey icons are committed. - `test/i18n.test.mjs` requires every new key in all 40 `_locales` at once, with identical placeholders: each new sentence costs 40 translations in the same commit. ## Done when - The testing switch greys the icon at once, the tooltip naming it, and nothing reaches Postulo; off, colour returns after one check. - With Postulo stopped, grey after a failed send or at the next alarm, the tooltip saying so; colour at the first check it answers. - Not set up, token refused and permission missing show as decided, with their reasons. - After a browser restart, icon and tooltip are right before the popup opens. - A pure function from settings and record to image and tooltip is tested with `node --test`, like `test/outbox.test.mjs`. - `PRIVACY.md` and `README.md` describe the new behaviour. From the list of extension improvements of 2026-09-30.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo-chromium#4
No description provided.