Skip to content

feat: add appearance and keyboard shortcut settings - #397

Merged
SudoJacky merged 2 commits into
masterfrom
feat/appearance-theme-settings
Aug 10, 2026
Merged

feat: add appearance and keyboard shortcut settings#397
SudoJacky merged 2 commits into
masterfrom
feat/appearance-theme-settings

Conversation

@SudoJacky

Copy link
Copy Markdown
Owner

Summary

  • add persistent system, light, and dark appearance settings with theme previews and configurable visual tokens
  • add persistent keyboard shortcut settings shared by web key handling and the native desktop menu
  • localize the no-workspace chat group in English and Simplified Chinese

Impact

Users can customize Tinybot's appearance and keyboard shortcuts from Settings. The chat sidebar now follows the active interface language for regular chats that do not belong to a workspace.

Root cause

The no-workspace session label was hardcoded in the session grouping layer, so it could not react to locale changes. The grouping layer now exposes a locale-neutral general group and the React view resolves its translated label.

Validation

  • npm test: 88 files, 560 tests passed
  • npm run build
  • cargo fmt --check
  • cargo check
  • targeted native shortcut Rust tests
  • git diff --check origin/master...HEAD

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 266bf1f808

ℹ️ 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".

Comment on lines +65 to +67
return [
event.ctrlKey || event.metaKey ? "Ctrl" : null,
event.altKey ? "Alt" : null,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the Command modifier for native macOS shortcuts

On macOS, recording Command+N is normalized to Ctrl+N, but the same string is sent unchanged to Tauri, where Ctrl means the physical Control modifier rather than Command. Consequently the renderer handles Command+N while the native menu advertises and handles Control+N, so one configured binding effectively has inconsistent shortcuts depending on which layer receives the event. Serialize a platform-neutral primary modifier such as CmdOrCtrl, or preserve Ctrl and Meta as distinct modifiers.

Useful? React with 👍 / 👎.

Comment on lines +92 to +94
return SHORTCUT_COMMAND_IDS.find((candidateId) => (
candidateId !== commandId && preferences[candidateId] === shortcut
)) ?? null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject collisions with fixed native menu accelerators

When a user assigns one of the configurable commands to a fixed menu accelerator such as Ctrl+F, Ctrl+/, or Ctrl+Shift+P, this conflict check succeeds because it only compares the six configurable preferences. The native menu still contains the fixed command with the same accelerator, leaving two menu items competing for one key combination; the fixed command's emitted ID is not handled by executeShortcutCommand, so the customized command can fail to run. Include the non-configurable menu accelerators in the conflict set or reserve them in the recorder.

Useful? React with 👍 / 👎.

Comment on lines +166 to +172
let result = match item {
MenuItemKind::MenuItem(item) => item
.set_accelerator(binding.accelerator.as_deref())
.map_err(|error| error.to_string()),
MenuItemKind::Check(item) => item
.set_accelerator(binding.accelerator.as_deref())
.map_err(|error| error.to_string()),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Actually clear native accelerators on macOS

When a macOS user clears a binding, this passes None to the locked muda 0.19.2 implementation, whose macOS set_key_accelerator only updates existing NSMenuItems when the new accelerator is Some; the prior key equivalent therefore remains installed. The UI and web handler show the command as unassigned, but its old native shortcut continues firing until restart. Clearing needs a macOS-safe removal path, such as rebuilding the menu or explicitly resetting the native key equivalent.

Useful? React with 👍 / 👎.

@SudoJacky
SudoJacky merged commit 9dfe4a6 into master Aug 10, 2026
1 check passed
@SudoJacky
SudoJacky deleted the feat/appearance-theme-settings branch August 12, 2026 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant