Repository navigation
fix(ui): follow the UI scale and the selected language in canvas chrome, Settings and plugin surfaces - #149
BIackFIame wants to merge 4 commits into
Conversation
…names and titles - Plugin pages, HOME widgets and canvas apps get appearance.uiScale (the root --ui-scale) with the locale and palette, again whenever it changes; separate plugin windows read it from host.getContext. - A manifest may add name.ru/name.en, title.ru/title.en on contributions (canvas apps, the settings page, HOME widgets, windows) and label.ru/label.en on launch fields, each up to 80 characters like the text it translates. The app shows its language's text, else the plain one. - Settings -> Agents: the "may allow" help line uses the normal help text style instead of the monospace metadata line. - Schema, plugin-api.d.ts and docs/plugins (en/ru/zh-CN) document both.
…led outcomes
A started GitHub device sign-in could not be cancelled, retried poll
failures until the code expired, and ended silently when GitHub answered
access_denied or expired_token. A sign-in that could not start showed
the raw IPC error ("Error invoking remote method 'github-auth:start':
...") at the top of the Plugins page, in English in the Russian UI.
- GithubAuthService.cancelDeviceFlow() is public and exposed through the
existing github-auth IPC (main-renderer only) and preload.
- status() reports deviceFlowState: idle, pending, denied, expired,
failed or cancelled.
- access_denied, expired_token, unknown provider errors and non-transient
HTTP errors stop polling with that outcome; OAuth error bodies on HTTP
400 are read as well.
- Network errors, timeouts, HTTP 408/429/5xx and unreadable bodies back
off and retry, but five failures in a row end the flow as failed.
- slow_down keeps adding five seconds to every later poll.
- The host clock ends the flow as expired even if GitHub keeps answering
authorization_pending.
- Settings shows a Cancel button next to the pending code and a localized
status line (en, ru) for the outcome, using existing classes: denied,
expired and failed use the Settings error style, cancelled is a plain
status line. A start or cancel failure shows a localized line ("not
configured" for a build without an OAuth client); the details go to
the log.
…e UI scale
Some UI chrome kept fixed pixel sizes, so Settings -> Appearance -> UI
scale (0.85-1.25) did not reach it:
- The terminal card's options menu (Don't restore this window, plugin
card actions) had a 12px font and pixel paddings while the card header
around it scaled.
- The canvas shortcut-hints panel looked the same at 0.85 and 1.25.
- In Settings -> Plugins the plugin description scaled with the settings
panel, but the permission list, the contribution rows ("App on
canvas"), the plugin title, author, version, buttons, module and
native-hook lists kept fixed 9-17px sizes, so at 1.25 one card mixed
large and small text.
The menu and the hints panel now take their font size from
calc(Npx * var(--ui-scale, 1)) and size their paddings, gaps, radii and
minimum widths in em; the hints icon is sized in em too. The plugin
settings font sizes use the same calc. At scale 1.0 every size is the
same as before. UI_CONTRACT names the menu and the hints panel among the
chrome that follows --ui-scale.
The title bar is left as is: its height is shared with the native
window chrome (macOS traffic-light position, the startup page) and with
every viewport-bound overlay through --titlebar-height.
…like the reference
The Russian canvas hints and Settings still showed English: the
wheel/pinch hint, the hard-coded "Shift + drag" key cap in the hints
panel and the shortcut reference, the canvas navigation override
description ("wheel, pinch и drag ... Drag колёсиком") and the
Settings > Canvas wheel capture strings and Off/On/Key labels.
- Translate them, reusing the existing on/off keys and adding
shortcutShiftDrag and canvasWheelCaptureKey; the hints use one word for
the drag gesture ("перетаскивание"). The group-selection label no
longer repeats its key cap (ru/en). A test checks that these ru strings
hold no Latin words besides key names.
- The wheel/pinch and navigation override rows in Settings > Keyboard
shortcuts wrap instead of cutting their longer Russian labels off.
- The hints panel showed raw bindings ("Alt+ArrowUp") while the shortcut
reference showed "Alt+↑". Both use one formatter now. It maps key by
key, so on macOS "Meta+Comma" reads "Command+," instead of the
reference's ",nd+Comma" (the Comma key was replaced inside "Command").
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b8c543bf9d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| void this.pollDeviceCode(deviceCode, interval, flowLifetimeMs, generation, controller.signal) | ||
| .catch((error) => { | ||
| if (!isAbortError(error)) console.warn("CanvasTTY GitHub OAuth device poll failed.", error); | ||
| if (controller.signal.aborted || isAbortError(error)) return; |
There was a problem hiding this comment.
Treat only the outer abort as cancellation
When GitHub has returned an access token but the subsequent /user request exceeds the 15-second request timeout, request() aborts its private controller and fetchLogin() rethrows an AbortError even though this flow's controller.signal is still active. This guard then mistakes that timeout for a user cancellation, and the finally clears deviceFlow without changing deviceFlowState, leaving status permanently pending and making the new Cancel action a no-op; only suppress the error when the outer signal is actually aborted, and report an internal timeout as failed.
Useful? React with 👍 / 👎.
| if (providerError === null && (!response.ok || !isRecord(payload))) { | ||
| if (isTransientStatus(response.status) || response.ok) { |
There was a problem hiding this comment.
Retry JSON-formatted transient OAuth responses
When the token endpoint returns a transient 429/5xx with an OAuth-shaped JSON body such as {"error":"temporarily_unavailable"}, providerError is non-null, so this condition skips isTransientStatus() and the response falls through to the unknown-provider-error path at lines 343-345, ending sign-in after the first transient response. The previous implementation retried every non-OK response, and the new retry policy also explicitly classifies 429/5xx as transient, so status-based retry handling needs to run even when the body contains an error field.
Useful? React with 👍 / 👎.
| ...(nameRu ? { "name.ru": nameRu } : {}), | ||
| ...(nameEn ? { "name.en": nameEn } : {}), |
There was a problem hiding this comment.
Propagate localized names to card-action UI
For a localized plugin with a trusted cards:decorate service, these fields survive validation but src/main/services/PluginManager.ts:730 still collapses the manifest to name: manifest.name; src/main/services/PluginCards.ts:120 forwards that value and src/renderer/src/features/terminal/TerminalCard.tsx:1321 renders it as the action tooltip (with the same fallback name used in failure toasts at PluginCards.ts:153). As a result, this user-facing plugin surface stays in the manifest's fallback language while the rest of the newly localized UI follows the selected locale; carry the localized variants through the action entry or resolve the name from pluginId in the renderer.
Useful? React with 👍 / 👎.
|
Closing this one: its fixes are now in #159 (the UI scale, Russian text and GitHub sign-in fixes, with their review follow-ups). The plugin-page part ( |
Branch
pr/ui-scale-and-ru(headb8c543bf, 4 commits), based onmainba427487.Why
Your reviews kept coming back to the same three UI points: chrome must follow root
--ui-scale, the text must be in the selected language, and it must be readable on Linux. While taking the Linux screenshots for the other PRs, we found places onmainitself that miss these points. This PR fixes them, along with GitHub device sign-in, which could not be cancelled and showed raw English IPC errors in the Russian UI. It adds no new surfaces and no settings.What changes for users
UI scale: Settings → Appearance → UI scale (0.85–1.25) now also reaches these parts:
At 1.0 nothing changes.
Russian text: the canvas hints, the wheel/pinch settings and the canvas navigation description are fully Russian. Long labels in Settings → Keyboard shortcuts wrap instead of being cut off.
Key caps: the hints panel shows them like the shortcut reference ("Alt+↑", not "Alt+ArrowUp"). This also fixes the reference's ",nd+Comma" on macOS.
GitHub sign-in:
Plugins:
appearance.uiScale, live;name.ru/title.ru/label.ruand.en), shown in the app's language;Commits
0496428cfix(ui): scale the card menu, hints panel and plugin settings with the UI scale894af84bfix(i18n): finish the Russian canvas hints and format their key caps like the reference48d7fb92fix(github): cancel device sign-in and report denied, expired and failed outcomesb8c543bffeat(plugins): send the UI scale to plugin pages and localize plugin names and titlesThe four commits are independent of each other, so you can drop any one of them.
Verification
macOS: this exact tree, with a fake HOME. Results: helpers, catalog (no diff), typecheck, full suite 2189 / 2185 / 0 / 4, build and
audit:secretspass; startup bundle +4,422 bytes overmain(1,693,545).Linux (Ubuntu 24.04 VM, xvfb): checked in ru/en, sage/night, at UI scale 0.85, 1.0 and 1.25: the hints panel (396×248 px at 0.85, 573×348 px at 1.25), wheel settings, the shortcut reference, the GitHub failure line, the card options menu and a plugin card at 1.25.
Not verified: Windows; a real GitHub sign-in (the flow is covered by tests with a stubbed GitHub API); a real third-party plugin page at 1.25; the lilac palette.
Risks
Depends on
Nothing. It conflicts only in text with #136 (
docs/UI_CONTRACT.md: keep #136's bullets and add this PR's clause about the card menu and hints panel).