Commit graph

6 commits

Author SHA1 Message Date
Local Dev
5946923547 translate 0.1.4 → 0.1.5: most-used languages pinned above the list
Both selects grow a "Frequently used" optgroup above "All languages",
holding up to ten entries ranked by how often each language has actually
been translated to or from.

Counted on a successful translation, not on a dropdown change: picking
your way down the list looking for something would otherwise rank every
language you skimmed past as highly as the ones you work in. A
detected source counts too — with Auto-detect on you never pick that
language explicitly, but it is one you read.

Ties break on the language's display name so the order is stable rather
than dependent on object key order. Counts live in the existing uiState,
so they persist through the saveUi/loadState path already there, and the
group only appears once there is something to put in it.

Verified in the harness: one translation records exactly one use for the
target and one for the detected source; the cap holds at ten with
fifteen tracked; and a pre-seeded profile comes back with its group,
target and zoom restored, Auto-detect still first in the source select.
2026-09-27 21:02:22 +02:00
Local Dev
83b65498a2 translate 0.1.3 → 0.1.4: bigger letters, plain globe
Drops the meridian ellipse so the globe is just a round field, and
spends the space that frees on the glyphs: tiles grow from 11.6 to 13.4
units and the A from font-size 10 to 12.4, with the 文 strokes
thickened to match. Checked the same way as last time — rasterized at
true 16px and 18px and magnified nearest-neighbour — against three
candidates (plain globe with tiles, letters bare on the globe, and a
single tile). Tiles won: bare glyphs on blue lose too much edge
contrast at 16px, and the two-tile arrangement is what reads as two
scripts rather than one word.

Same mark in the manifest and in the panel header.
2026-09-27 18:54:34 +02:00
Local Dev
13a4dd692d translate 0.1.2 → 0.1.3: real icon, bigger text, zoom, auto-translate on language change
Auto-translate: changing either language only called saveUi(), so the
pane below kept showing the previous language's result with nothing to
say it was stale — you had to notice and press Translate. Both selects
now re-run the translation, guarded on empty input and on
source === target (which would only echo the input back).

Text size: the panes were 13.5px, small for reading a paragraph in a
language you don't know well, which is the entire job. Base is now
15px, driven by a --tsize custom property so both panes stay matched.

Zoom: −/+ either side of a percentage in the header, 70–220% in steps
of 10, clamped with the buttons disabling at each end. Click the
percentage to reset. Ctrl/Cmd with +, - or 0 does the same from either
pane. Persists per-machine alongside the language choice.

Icon: a globe with an A tile and a 文 tile, replacing the 🌐 emoji that
was indistinguishable from every other globe in the dock. Drawn against
the 16px and 18px rasterizations rather than at a comfortable size —
the first pass used a font glyph for 文 and it turned to grey mush at
16px, so the strokes are hand-drawn paths thick enough to survive. Also
drops the hardcoded icon in registerSidebarPanel, which would otherwise
shadow the manifest's mark.

Verified in a harness with a stubbed host API: language change fires
exactly one request, the two guards fire none, zoom clamps and persists,
and the layout holds at sidebar width.
2026-09-27 18:00:46 +02:00
Local Dev
2b8e3a7eb6 translate 0.1.1 → 0.1.2: fetch from the addon's Node side, not the panel
The panel was doing the HTTP call itself, which meant any mirror sitting
behind a Cloudflare-style anti-bot check returned "<!doctype html>…" for
a POST from Origin: file:// and JSON.parse choked on it. Moving the
fetch into index.js gets rid of the whole class of browser-context
interceptors (CORS preflights, captive portals, anti-bot pages) and
lets the addon look at the response body before trying to parse it —
an HTML body is now reported cleanly as "server returned an HTML page
instead of JSON".

While there, chain a small mirror list — translate.disroot.org,
translate.plausibility.cloud, lingva.ml — so a single mirror being down
does not take the feature with it. A user whose saved URL points at a
mirror that stopped resolving (translate.argosopentech.com is the
notable case) now transparently gets a translation from the next mirror
in line instead of a stack trace.

Verified end-to-end from Node against both a working URL and a dead
one; the dead one falls through to disroot as expected.
2026-09-21 03:34:14 +02:00
Local Dev
862e92543c extensions: real PDF/DOC icons + fix translate default URL
- pdf-editor 0.1.1 → 0.1.2: manifest.icon is a data:image/svg+xml red PDF
  document badge (dock renders it as <img>). Same on toolbar-menu.icon.
  Item-level icons dropped — those go through the native OS menu that
  doesn't render data URIs.
- translate 0.1.0 → 0.1.1: default LibreTranslate mirror was
  translate.argosopentech.com, which is now a dead domain — panel just
  said "Failed" on every request. Switched default to
  translate.disroot.org (currently up), added a datalist of known
  mirrors, and a one-shot migration off the dead default so existing
  installs recover on next load.
- docx-editor 0.1.0 → 0.1.1: manifest.icon is a data:image/svg+xml blue
  DOC document badge, index.js no longer overrides it with 📝, and the
  panel header uses the same inline SVG. Same rationale as pdf-editor —
  every extension was rendering as either 📄 or 📝, so PDF and Word
  were visually identical to the Notepad.
2026-09-21 02:41:16 +02:00
Local Dev
501c7cf273 feat(theseus/translate): new sidebar add-on — right-click Translate selection
Adds a bundled add-on `translate` with a sidebar panel + a right-click
"Translate selection" menu item. Two swappable backends:

- LibreTranslate (default) — free MIT engine; the panel's Settings tab
  lets the user point at any instance (public or self-hosted) and drop
  in an API key if one's required.
- Google (unofficial free endpoint at translate.googleapis.com/
  translate_a/single) — no key, wide coverage, but unofficial and
  Google can break it any time. Opt-in fallback.

Flow: user selects text on a page, right-clicks -> "Translate
selection". Add-on's context-menu handler stashes the selection under
storage.__pending and calls api.revealSidebar("main"); the panel
loads, drains __pending on first paint, and translates. Ctrl/Cmd+Enter
in the input textarea also translates. Source + target language
choices, browser-language default target, swap button, copy-to-
clipboard on the output, settings gear.

Depends on a new "context-menu-item" capability + api.revealSidebar
hook in addons-host.js / main.js. Those wiring changes are prepared
but not committed here — a parallel session is refactoring the same
functions concurrently, so the safe path is to land translate/ first
and let the wiring go in alongside the next host-facing commit. Until
the wiring lands, the manifest's "context-menu-item" cap is silently
dropped (per validateManifest's unknown-caps policy) and the sidebar
panel + the panel's translation UI still work standalone — the
right-click entry point is what's gated.
2026-09-20 17:50:06 +02:00