- Rename grpcweb.ts to connect.ts to reflect ConnectRPC usage
- Enable binary protobuf format for improved performance
- Update all imports across 26 files from @/grpcweb to @/connect
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The CodeBlock component was refactored in v0.25.3 to use navigator.clipboard.writeText(),
which requires HTTPS or localhost. This caused the copy button to fail silently for users
accessing Memos over HTTP.
This fix adds a fallback to the copy-to-clipboard library (already used by all other
copy operations in the codebase) when the native clipboard API is unavailable or fails,
ensuring the copy button works reliably in all deployment scenarios.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Extract shared utilities and constants to eliminate code duplication
- Create dedicated Calendar page with year view and month grid
- Add date filter navigation with bidirectional URL sync
- Fix useTodayDate memoization bug causing stale date references
- Standardize naming conventions (get vs generate functions)
- Add comprehensive type exports and proper store encapsulation
- Implement size variants for compact calendar display
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Problem:
The Explore page filter was sending visibility filter as:
visibility in ["3", "2"]
when it should send:
visibility in ["PUBLIC", "PROTECTED"]
The backend CEL filter parser expects string enum names, not numeric values.
This caused the Explore page to return no memos even when public memos existed.
Solution:
- Added getVisibilityName() helper to convert Visibility enum values to string names
- Updated useMemoFilters to use getVisibilityName() when building visibility filter
- Follows same pattern as existing getInstanceSettingKeyName() and getUserSettingKeyName()
- Added validation to warn on invalid enum values
Files changed:
- web/src/store/common.ts: Add getVisibilityName() helper with validation
- web/src/hooks/useMemoFilters.ts: Use getVisibilityName() in visibility filter
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Frontend was incorrectly using numeric enum values (e.g., 1, 2, 3) instead
of string names (e.g., "GENERAL", "STORAGE") when constructing API resource
paths. This caused the backend to fail with "unsupported instance setting
key: INSTANCE_SETTING_KEY_UNSPECIFIED" errors during initialization.
Changes:
- Add helper functions in store/common.ts to convert enum values to names
- getInstanceSettingKeyName() and buildInstanceSettingName()
- getUserSettingKeyName() and buildUserSettingName()
- Update instance store to use string enum names in API calls
- Update user store to use string enum names in API calls
- Update all components to use new helper functions for setting names
Fixes enum string conversion for:
- InstanceSetting_Key (6 locations)
- UserSetting_Key (2 locations)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixes#5319. Checkboxes inside code blocks were incorrectly counted when
toggling tasks, causing the wrong checkbox to be checked. Replaced regex-based
task detection with mdast AST parsing which properly ignores code block content.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extract preference logic into dedicated hooks (useUserLocale, useUserTheme)
- Add applyLocaleEarly() for consistent early application
- Remove applyUserPreferences() from user store (now redundant)
- Simplify App.tsx by moving effects to custom hooks
- Make locale/theme handling consistent and reactive
- Clean up manual preference calls from sign-in flows
Fixes locale not overriding localStorage on user login.
Improves maintainability with better separation of concerns.
Add custom remark plugin to prevent setext headers (headers using === or --- underlines) from being recognized by the markdown parser. The plugin disables the setextUnderline construct at the micromark parser level.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Migrates attachment and avatar binary serving from gRPC endpoints to a new dedicated HTTP fileserver package, fixing Safari video playback issues and improving architectural separation.
Key changes:
- Created server/router/fileserver package for all binary file serving
- Removed GetAttachmentBinary and GetUserAvatar gRPC endpoints from proto
- Implemented native HTTP handlers with full range request support
- Added authentication support (session cookies + JWT) to fileserver
- New avatar endpoint supports lookup by user ID or username
- Eliminated duplicate auth constants (imports from api/v1)
HTTP endpoints:
- Attachments: /file/attachments/:uid/:filename (unchanged URL)
- Avatars: /file/users/:identifier/avatar (new URL format)
This fixes Safari video/audio playback by using http.ServeContent() which properly handles HTTP 206 Partial Content responses and range request headers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Integrates remark-math and rehype-katex plugins to enable LaTeX mathematical expressions in memos. Users can now write inline math ($...$) and display math ($$...$$) using standard LaTeX syntax.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove theme and locale from instance settings to eliminate duplication and
simplify the codebase. These are user-specific preferences and should only
exist in user settings, not instance-wide settings.
Backend changes:
- Remove theme from InstanceGeneralSetting proto
- Remove locale from InstanceCustomProfile proto
- Update instance service converters to remove theme/locale handling
- Simplify RSS feed to use static locale
Frontend changes:
- Remove theme/locale from instanceStore state
- Create unified initialization flow with clear fallback priority:
* Theme: user setting → localStorage → system preference
* Locale: user setting → browser language
- Add applyUserPreferences() to centralize theme/locale application
- Simplify App.tsx by removing redundant state synchronization
- Update all components to use new helper functions:
* getThemeWithFallback() for theme resolution
* getLocaleWithFallback() for locale resolution
- Remove theme/locale selectors from instance profile dialog
Theme utilities refactor:
- Organize code into clear sections with JSDoc comments
- Extract localStorage operations into getStoredTheme/setStoredTheme helpers
- Split DOM manipulation into focused functions
- Improve type safety with Theme and ResolvedTheme types
- Reduce code duplication and improve maintainability
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previously, clicking multiple tags would add them all as active filters. Now clicking a new tag automatically clears any existing tag filters before applying the new one, ensuring only one tag can be filtered at a time. Clicking an already-active tag still deselects it.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Wrap all setter functions in useMemoEditorState with useCallback to ensure stable references
This prevents infinite loops when setters are used in useEffect dependencies (fixes "Maximum update depth exceeded" error)
- Extract MobX observable values in useMemoFilters and useMemoSorting before using them in useMemo dependencies
This prevents React from tracking MobX observables directly, improving reliability
- Add comprehensive documentation explaining the design decisions for future maintainability
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements critical OAuth 2.0 security improvements to protect against authorization code interception attacks and improve provider compatibility:
- Add PKCE (RFC 7636) support with SHA-256 code challenge/verifier
- Fix access token extraction to use standard field instead of Extra()
- Add OAuth error parameter handling (access_denied, invalid_scope, etc.)
- Maintain backward compatibility for non-PKCE flows
This brings the OAuth implementation up to modern security standards as recommended by Auth0, Okta, and the OAuth 2.0 Security Best Current Practice (RFC 8252).
Backend changes:
- Add code_verifier parameter to ExchangeToken with PKCE support
- Use token.AccessToken for better provider compatibility
- Update proto definition with optional code_verifier field
Frontend changes:
- Generate cryptographically secure PKCE parameters
- Include code_challenge in authorization requests
- Handle and display OAuth provider errors gracefully
- Pass code_verifier during token exchange
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove enable_link_preview field from proto definitions
- Remove setting UI from MemoRelatedSettings component
- Remove translations from all 33 locale files
- Regenerate proto files
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove disable_markdown_shortcuts field from proto definitions
- Remove setting UI from MemoRelatedSettings component
- Enable markdown shortcuts permanently in MemoEditor
- Remove translations from all 32 locale files
- Fix TypeScript error in useMemoSave hook by using typed translation function
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added MemoView component to display a single memo card with full functionality including creator info, memo content, attachments, reactions, and comments.
- Created MemoBody and MemoHeader subcomponents to separate concerns and improve maintainability.
- Introduced custom hooks for managing memo actions, keyboard shortcuts, NSFW content visibility, and image preview.
- Implemented reaction handling with new ReactionSelector and ReactionView components.
- Added TypeScript types for better type safety and clarity.
- Established constants for memo card styling and keyboard shortcuts.
- Removed legacy ReactionSelector and ReactionView components from the previous structure.
- Implemented LocationDialog component for selecting and entering location coordinates.
- Created useLocation hook to manage location state and updates.
- Added LocationState type for managing location data.
- Introduced useLinkMemo hook for linking memos with search functionality.
- Added VisibilitySelector component for selecting memo visibility.
- Refactored MemoEditor to integrate new hooks and components for improved functionality.
- Removed obsolete handlers and streamlined memo save logic with useMemoSave hook.
- Enhanced focus mode functionality with dedicated components for overlay and exit button.
Tags were missing CSS styles, appearing as plain text. Added text-primary
styling to Tag component and updated default theme primary color to match
other themes (blue hue 250, chroma 0.08) for consistency.
Fixes#5282🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This fixes multiple issues with the tag sidebar and activity calendar:
1. Tag disappearing bug: When filtering by a tag, the sidebar now shows all tags instead of only the selected tag
2. Activity calendar filtering: Calendar now shows full activity history instead of filtered results
3. Auto-update on memo changes: Sidebar tags and calendar now update automatically when creating/editing memos without requiring manual page refresh
Technical changes:
- Modified useFilteredMemoStats to fetch unfiltered UserStats from backend API for Home/Profile pages
- Fixed key mismatch bug in userStore where stats were stored with inconsistent keys
- Added statsStateId update in fetchUserStats to trigger reactivity
- Updated MainLayout to pass appropriate userName based on page context
- Archived/Explore pages continue to compute from cached memos (correct behavior)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Pass i18n.language to time display components to ensure locale updates
when the user switches languages in UserMenu. Changes:
- MemoView: Pass i18n.language to toLocaleString() and <relative-time> lang attribute
- MonthNavigator: Wrap with observer to make component reactive to i18n.language changes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>