The model picker was a plain div that could not take focus, and Tab in
the composer indented text instead of leaving it, so keyboard users could
not change the model. The picker is now a button named "Model: <name>",
Tab moves on from the composer, and the title that opens the chat history
is named "Chat history: <title>" instead of repeating "New Chat".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Coming back to the AI tab showed the saved prompt with "0/500", because
the counter only moved after an edit. The editor's length plugin never
called its callback; it now reports the opening length and each change,
which also brings back the AI task prompt counter.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Choosing SN Pro as the global or content font did nothing on the web:
the production Tailwind pass rewrites the whole stylesheet and drops the
font CSS's relative url()s, so no font file was emitted and each request
got index.html. The font CSS is now imported from JS on its own, in the
renderer and the SSR client.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The subscription column focuses its sidebar in a mount effect, which
writes the focus scope in the same commit that mounts the timeline
header. jotai 3 subscribes after that commit, so the header kept the
empty scope and never bound Shift+Cmd+A until focus moved elsewhere.
Read focus scopes with useAtomValueRawSync.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The segment control's group could take focus, but its segments couldn't
be reached and nothing handled keys, so keyboard users couldn't change
a selection in the settings, Discover, action rules or view toggles,
and screen readers weren't told which segment was selected. Move the
selection with the arrow, Home and End keys, and expose the selected
segment.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Below 1024px the responsive select renders a button over a native
select, and neither received disabled, so a phone or a narrow window
could still change the fields of a disabled action rule or the language
while it was loading. Disable both.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since jotai 3, useAtomValue subscribes in a passive effect without
re-reading the atom. StableRouterProvider writes the route atom in a
layout effect, so components that mount in the same commit (a full page
load in dev, or opening a timeline from Discover, AI and other layouts)
kept the previous params: feedId and entryId stayed undefined, the view
fell back to Articles, the header and title were empty and scroll
mark-read never fired.
Read the route atom with useAtomValueRawSync, which re-checks the
snapshot after subscribing, and cover both cases with a regression test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Move the hard-coded English left in the desktop renderer, the Electron
main process, the mobile app and the shared packages to i18next, with
en, zh-CN, zh-TW, ja and fr-FR translations. SSR share pages are
unchanged.
- Fill every namespace in every language, delete keys no code reads
(server error codes stay) and update translations left behind by
later English changes.
- Stop HTML-escaping interpolated values in the desktop renderer.
React already escapes text, so names with & or quotes showed entities.
- Render error boundary fallbacks as components so they can use hooks.
- Localize zod validation messages with the app language.
- Throw ClipboardError from the clipboard helpers and show translated
toasts. formatEstimatedMins takes a formatter so callers localize the
units.
- Use one glossary term per concept in ja, fr-FR and zh-TW.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shared pages built with Vite 8 received the whole react-fast-marquee module object for its default import and crashed with React error #130 when a title marquee rendered.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Thumb's `before:` pseudo-element was meant to enlarge its hit target,
but its negative offsets plus `-translate-x-full -translate-y-full` place
the box 44px to the left of the scrollbar and half a thumb height above
it. Tailwind 3 dropped the unitless `min-w-[44]`, so the box was inert;
Tailwind 4 compiles it to `min-width: 44px`, turning it into an invisible
strip in the scrollbar layer that steals hover and swallows clicks on the
right edge of timeline entries (and the right edge of wide views).
Radix already handles pointer down on the whole track, so drop the
pseudo-element instead of repositioning it.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Show a preferences button next to the login button when logged out, so
guests can open the settings modal without signing in. The modal already
supports guest mode and gates account-bound tabs behind login.
Also fix KbdCombined splitting the comma key in shortcuts like "$mod+,"
as if it were a separator between multiple shortcuts.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* feat: add cross-platform e2e coverage
* fix: stabilize desktop e2e navigation
* fix: harden desktop e2e read flow
* fix: harden desktop e2e auth and follow flows
* fix: stabilize desktop e2e discover entry flows
* fix: run android e2e in a single shell
* fix: speed up mobile e2e builds in ci
* fix: build android e2e app from mobile workspace
* fix: invoke android gradle build from repo root
* fix: use absolute path for android ci build
* fix: restore android eas build in ci
* fix: target iOS simulator by udid in ci
* fix: align desktop e2e with discover card flow
* fix: reorder web e2e after relogin
* fix: navigate web e2e via real hash url
* fix: close stale settings modal before reopening
* fix: track android maestro flows
* fix: wait for settings router in web e2e
* fix: wait for web settings sync propagation
* fix: stabilize desktop e2e settings flows
* fix: harden desktop e2e regressions
* fix: stabilize desktop e2e selectors
* fix: read desktop entry state from locators
* fix: relax desktop e2e entry assertions
* fix: avoid waiting on missing desktop feed ids
* chore: update workspace dependencies
- bump dependencies across desktop, mobile, ssr, and internal packages
- refresh pnpm lockfile
- apply type compatibility fixes required by upgraded packages
* fix(ssr): prevent tsdown CI warning from failing build
- set inlineOnly to false in tsdown config
* style: format files for CI prettier check
- apply prettier formatting to files reported by format:check
* fix(mobile): downgrade reanimated for rn 0.79 ios build
- Added MobileTimelineLayout component to handle mobile-specific rendering.
- Integrated useMobile hook for responsive behavior in AIEnhancedTimelineLayout.
- Updated layout logic to conditionally render components based on mobile view.
- Enhanced dropdown and context menu styles for better visual feedback.
Signed-off-by: Innei <tukon479@gmail.com>
- Added a renderValue function to the LanguageSelector for improved display of selected language names.
- Updated layout component to support responsive behavior based on viewport width.
- Refactored setting sync to utilize useMobile hook for better mobile detection.
- Enhanced withResponsiveComponent to accept a breakpoint function for more flexible responsive layouts.
Signed-off-by: Innei <tukon479@gmail.com>
- Introduced gradient backgrounds and box shadows for dropdown menus and context menus for a more modern appearance.
- Updated modal styles to include backdrop blur and inner glow effects for better visual depth.
- Adjusted component layouts for consistency and improved user experience across modals and context menus.
- Refined keyboard component styles for better interaction feedback.
Signed-off-by: Innei <tukon479@gmail.com>
* feat: implement BYOK (Bring Your Own Key) feature for AI providers
- Added BYOK section in AI settings to manage custom API keys.
- Introduced components for adding, editing, and deleting BYOK providers.
- Updated translations for BYOK-related UI elements.
- Modified existing components to support new BYOK functionality.
Signed-off-by: Innei <tukon479@gmail.com>
* feat: enhance BYOK provider support and update UI elements
- Added support for the "OpenRouter" BYOK provider in relevant components.
- Updated translations for security-related UI elements to reflect new descriptions.
- Adjusted styling in settings components for improved visual consistency.
Signed-off-by: Innei <tukon479@gmail.com>
* feat: refine BYOK provider management and enhance UI
- Introduced a new constants file for BYOK provider options.
- Updated the ByokProviderModalContent to filter available providers based on configured ones.
- Enhanced the ByokSection to manage provider addition and editing more effectively.
- Adjusted table styling in the PlanComparisonTable for improved readability.
- Added new translation keys for "AI Bring Your Own Key" in multiple languages.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
- Updated CSS for the code highlighter to improve layout and add custom scrollbar styles.
- Refined the Shiki component with a subtle glow effect and improved header layout.
- Adjusted the LoginButton icon size and color for better visibility.
Signed-off-by: Innei <tukon479@gmail.com>
- Introduced `requiresLogin` property for menu items and actions across multiple components to enforce user authentication.
- Added `useRequireLogin` hook to manage login checks and modal presentation.
- Updated context menus, action buttons, and settings to utilize the new login guard functionality.
- Enhanced user experience by prompting login where necessary, ensuring actions are only accessible to authenticated users.
Signed-off-by: Innei <tukon479@gmail.com>
Updated the global shortcuts registration to ensure proper detection of editable elements by checking if the target is an instance of HTMLElement. This change enhances the accuracy of shortcut handling in editable contexts.
style(toast): remove unused toast styles
Deleted redundant CSS styles related to sonner toast notifications to streamline the stylesheet and improve maintainability.
style(toast): enhance toast styles with z-index and pointer events
Added z-index and pointer-events styles to the toast component for better layering and interaction handling.
Signed-off-by: Innei <tukon479@gmail.com>
- Introduced a comprehensive glassmorphic design system to enhance visual hierarchy in UI elements such as modals, toasts, and floating panels.
- Added detailed design principles, color usage guidelines, and component structure examples to AGENTS.md.
- Updated AISmartSidebar component to utilize layered glass effects and smooth animations.
- Enhanced CSS styles for glassmorphic elements, ensuring performance optimizations and accessibility considerations.
These changes aim to elevate the user experience through refined aesthetics and improved interaction dynamics.
Signed-off-by: Innei <tukon479@gmail.com>
- Modified the isEmpty method in both ChatInput and LexicalRichEditor components to check if the editor's content is empty by verifying if the trimmed text content is an empty string.
- Added an accessories prop to LexicalRichEditor for improved flexibility in rendering additional UI elements.
Signed-off-by: Innei <tukon479@gmail.com>
- Updated Shortcut components to include icon rendering and a command prefix for better user experience.
- Modified shortcut trigger patterns to use '/' instead of '#' for consistency across the application.
- Added new icon selection feature in ShortcutModalContent for improved customization.
- Updated localization files to include new icon-related strings.
Signed-off-by: Innei <tukon479@gmail.com>
Added AutoLinkPlugin and TabIndentationPlugin to the LexicalRichEditor for improved user experience. Introduced ExitCodeBoundaryPlugin to manage caret behavior when exiting code contexts and TripleBacktickTogglePlugin for toggling code blocks. Updated node imports and types to support these new features, enhancing the editor's capabilities.
Signed-off-by: Innei <tukon479@gmail.com>
Updated the ChatInput and LexicalRichEditor components to streamline the logic for determining if the editor is empty. The isEmpty state now directly utilizes the $getRoot().isEmpty() method, enhancing code clarity and maintainability. Removed unnecessary text content checks in favor of a more efficient approach.
Signed-off-by: Innei <tukon479@gmail.com>
Updated the ChatInput and EditableMessage components to set a fixed height for the LexicalRichEditor, improving the layout consistency. Additionally, refactored the AITaskModal to manage prompt state outside of react-hook-form, allowing for better control over the prompt length and submission handling.
Signed-off-by: Innei <tukon479@gmail.com>
- Replaced `[text-autospace:auto]` with `autospace-normal` class in ListItem, EntryTitle, and ArticleLayout components to standardize text spacing.
- Added a new utility class `autospace-normal` in tailwind.css to ensure consistent text rendering across the application.
Signed-off-by: Innei <tukon479@gmail.com>
- Updated the import path for the AIShortcutButton component to the new location.
- Introduced a more flexible gradient handling function that adapts based on the dark/light mode.
- Removed the old AIShortcutButton component file as it is no longer needed.
Signed-off-by: Innei <tukon479@gmail.com>
- Updated the prompt input field with additional padding for better usability.
- Added size prop to the Switch component, allowing for small and medium sizes.
- Adjusted styles for the Switch component to accommodate the new size options, ensuring consistent appearance across different sizes.
Signed-off-by: Innei <tukon479@gmail.com>