Commit Graph

2722 Commits (e008b1a23c77945eff87707eb15578d4d6d74e4c)

Author SHA1 Message Date
boojack aafcc21ae6 fix: improve image preview dialog and live photo trigger 3 months ago
boojack 6b0487dcd8 fix: unify live photo previews around LIVE badge playback 3 months ago
boojack 4b4e719470
feat(attachments): add Live Photo and Motion Photo support (#5810) 3 months ago
boojack 894b3eb045 fix(map): refine Leaflet controls and memo map styling 3 months ago
memoclaw f403f8c03c refactor: simplify memo metadata components 3 months ago
memoclaw 0e4d2d25ca refactor: simplify audio attachment playback component 3 months ago
Serhat 9676e72533
i18n: complete Turkish (tr) translations to 100% coverage (#5802)
Signed-off-by: Serhat <49079271+onwp@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
3 months ago
memoclaw c0d5854f67
feat(editor): add voice note recording to the memo composer (#5801)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
3 months ago
memoclaw a0d83e1a9e fix(web): refine attachment media layout 3 months ago
memoclaw 63a17d897d refactor: split audio attachment view into reusable components 3 months ago
memoclaw 1921b57662
fix(tags): allow blur-only tag metadata (#5800)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
3 months ago
memoclaw e520b637fd fix: prevent stale comment drafts from being restored 3 months ago
memoclaw c53677fcba fix(api): improve SSE hub design and fix double-broadcast on comments
- Fix duplicate SSE event on comment creation: CreateMemoComment now
  suppresses the redundant memo.created broadcast from the inner
  CreateMemo call, emitting only memo.comment.created
- Extract reaction event-building IIFEs into buildMemoReactionSSEEvent
  helper, removing duplicated inline DB-fetch logic
- Promote resolveSSEAudienceCreatorID from method to free function
  (resolveSSECreatorID) since it never used the receiver
- Add userID to SSE connect/disconnect log lines for traceability
- Change canReceive default from permissive (return true) to
  deny-with-warning for unknown visibility types
- Add comprehensive tests covering all new helpers, visibility edge
  cases, slow-client drop behavior, and the double-broadcast fix

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3 months ago
memoclaw acddef1f3d
fix(api): switch user resource names to usernames (#5779)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
4 months ago
memoclaw 4f6730a12e chore: show compact attachment count instead of thumbnails in comment previews
When truncate mode is active (comment list), display an inline file icon
with attachment count instead of rendering full image thumbnails.
4 months ago
memoclaw 6a03917f6e chore: upgrade TypeScript to 6.0.2 4 months ago
memoclaw bb7f4978e5
refactor(web): consolidate SharedMemo into MemoDetail (#5773)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
4 months ago
memoclaw 6b30579903
feat: add outline navigation to memo detail sidebar (#5771)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4 months ago
memoclaw 2aaca27bd5
refactor(web): improve MemoDetail and sidebar maintainability (#5769)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
4 months ago
memoclaw e176b28c80
feat(memo-preview): support comment metadata in previews (#5768)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
4 months ago
memoclaw 22519b57a0 fix(web): prevent MemoContent prop leaks 4 months ago
memoclaw 45b21530d9
feat: add blur_content attribute to tag metadata settings (#5767)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4 months ago
memoclaw 9e04049632
feat: treat tag setting keys as anchored regex patterns (#5759)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4 months ago
memoclaw 9ded59a1aa
refactor(web): improve Settings page maintainability and consistency (#5757)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4 months ago
memoclaw d5de325ff4
refactor(web): simplify main layout sidebar structure (#5756)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
4 months ago
memoclaw 4177898054
refactor(web): consolidate memo metadata components into MemoMetadata (#5755)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4 months ago
memoclaw ac077ac3d3
refactor(web): improve MemoView and MemoEditor maintainability (#5754)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4 months ago
memoclaw 7b4f3a9fa5 refactor(memo): simplify MemoDetail error handling, drop memo.failed-to-load i18n key
The failed-to-load key was only used for non-ConnectError exceptions, which
are unreachable in practice since the Connect RPC client always wraps errors
as ConnectError. Use (error as Error).message as a plain fallback instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4 months ago
memoclaw 5f6f624635 i18n: add missing auth.protected-memo-notice and memo.failed-to-load fallbacks to all locales
30 locale files were missing the two keys added in the auth redirect PR.
Added English fallback strings so all locales render properly until
community translations are contributed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4 months ago
xun zhao 7601708ae4
Redirect unauthenticated protected memo access to sign in (#5738) 4 months ago
fiatcode 551ee1d81f
fix(auth): recover session via refresh cookie when localStorage is empty (#5748) 4 months ago
memoclaw be00abe852
fix: sync html lang attribute with active locale (#5753)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4 months ago
google-labs-jules[bot] 23a7e99a21
chore: optimize unreact network requests (#5747)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: boojack <stevenlgtm@gmail.com>
4 months ago
memoclaw a7cabb7ce6
refactor(web): remove masonry memo layout (#5746)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
4 months ago
memoclaw 05810e7882
fix(memo-editor): scope Cmd+Enter save to the active editor (#5745)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
4 months ago
memoclaw e0334cf0a8
refactor: restructure i18n locale keys for better maintainability (#5744)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4 months ago
memoclaw 6f1f3d81c5
chore: remove disallow_public_visibility setting (#5743)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4 months ago
memoclaw 3f3133d6e2
feat(memo): add share links for private memos (#5742)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
4 months ago
memoclaw a249d06e2e
feat(instance): add notification transport setting (#5737)
Co-authored-by: memoclaw <265580040+memoclaw@users.noreply.github.com>
4 months ago
boojack 65d14fbb63
feat(instance): add canonical tag metadata setting (#5736) 4 months ago
boojack 330291d4d9
feat(user): add per-user tag metadata settings (#5735) 4 months ago
boojack 04f239a2fc
fix(api): remove public activity service (#5734) 4 months ago
Nix 89c6902895
feat(i18n): update sse connect label in Chinese (#5732) 4 months ago
memoclaw 6f5f0d94e8
chore(web): update frontend dependencies and Node runtime (#5729) 4 months ago
memoclaw 1e688b2a5d
feat: extract title from first H1 heading into memo property (#5726)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4 months ago
memoclaw 8f43e8075b
fix: correct typos in comments, error messages, and identifiers (#5704)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
4 months ago
memoclaw bdd3554b89
fix: handle chunk load errors after redeployment with auto-reload (#5703)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
4 months ago
memoclaw 2ccb98a6cb
fix: render audio attachments as inline players (#5699)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
4 months ago
memoclaw 4503679155
enhance: improve link memo dialog with rich previews (#5697)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
4 months ago
memoclaw e70149af5f
enhance: polish PWA manifest and meta tags (#5695)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
4 months ago
memoclaw 3d4f793f97
fix: include plain URLs and tags in memo snippet generation (#5688)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
4 months ago
memoclaw 92d937b1aa
feat: replace auto-increment ID with UID for identity provider resource names (#5687)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
4 months ago
Peter Etelej 3010f10eaf
fix: access token refresh on web app (#5681) 4 months ago
longhe.li 0729779e04
fix: toggle focus mode do not reset editor height (#5504)
Signed-off-by: longhe.li <lilonghe@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
4 months ago
thefatcode 2c3f9e3bfb
fix: clear content search filter when selecting shortcut (#5499) 4 months ago
Steven ce441644af fix: ensure comment divs span full width in MemoDetail 4 months ago
Steven 0cf8805184 refactor(sse): move status indicator to avatar badge
Replace the standalone SSE dot above UserMenu with a small badge
overlaid on the bottom-right of the user avatar. Only visible when
status is connecting (yellow) or disconnected (red) — invisible in the
normal connected state, removing constant visual noise.
4 months ago
milvasic ea0892a8b2
feat: add live refresh via Server-Sent Events (SSE) with visual indicator (#5638)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: milvasic <milvasic@users.noreply.github.com>
4 months ago
Steven a69e405c95 refactor: remove dead code and deduplicate comment amount logic 4 months ago
Steven 3a5d3c8ff9 feat: show inline comment preview in list view
Add a comment preview section below memo cards in list view, displaying
up to 3 comment snippets with a "View all" link. Removes the old comment
count icon from the memo header in favor of this richer inline display.
Comment preview is hidden in memo detail view.
4 months ago
Steven 3e4c052f44 chore: unify table style 4 months ago
Steven 4321887a02 chore: fix linter 4 months ago
Lincoln Nogueira d0764fb0be
i18n: update all locale translations (#5679) 4 months ago
Steven 98859eb5e5 fix(routing): redirect unauthenticated users to /explore when public visibility is allowed 4 months ago
Steven 737acbba2f fix(markdown): support height/width attributes on img elements 4 months ago
Steven dfab67f035 chore(seed): polish demo data with realistic multi-user content 4 months ago
Steven 6b37fcc01b fix: improve KaTeX and Mermaid error handling and overflow 4 months ago
Steven 7f753bf6d7 refactor(theme): consolidate theme system and polish dark mode colors
- Reduce themes from 6 to 4: system, light, dark, paper
  - Remove midnight (too similar to dark) and whitewall (too similar to light)
  - Drop all unused tokens: chart-*, sidebar-primary, sidebar-border,
    sidebar-ring, shadow-2xs, tracking-normal, spacing
  - Remove redundant @theme inline blocks from dynamic theme files
    (Tailwind only processes them at compile time, not at runtime)
  - Move shared tokens (fonts, radius) to default.css only

- Polish dark mode color palette
  - Consistent cool-slate hue (h265) across all surfaces
  - Proper surface layering: sidebar(0.07) → bg(0.09) → card(0.13) →
    popover(0.17) → secondary(0.19) → muted(0.21) → accent(0.22)
  - Foreground softened to 0.82 (from 0.9) — comfortable off-white
  - Accent more chromatic than muted (0.012 vs 0.008) — hover feels interactive
  - Popover elevated above card (0.17 vs 0.13) — floating elements visible
  - Destructive more vivid (0.62/c0.20) — clearly red on dark surfaces
  - Input border (0.25) more distinct than layout border (0.21)
  - Sidebar foreground (0.68) dimmer than content foreground (0.82)

- Fix inline code background invisible in dark mode (#5674)
  - Muted was same lightness as card — increased to 0.21 for clear contrast
4 months ago
Johnny 16576be111 chore: polish MemoDetailSidebar for consistent structure and styles 4 months ago
Johnny 53a8a436ba chore: fix frontend linter 4 months ago
Johnny 026ea92f7b fix(editor): show newly linked memos when editing a memo with attachments 4 months ago
mostapko 104d2ec0a6
feat(ui): allow navigating between images with arrows in preview dialog (#5669) 4 months ago
Steven 664b8c5629 fix(ui): unify metadata component styles across MemoView and MemoEditor
Align header padding, text color, background tokens, and item row styles
across CodeBlock, AttachmentList, RelationList, and LocationDisplay so all
metadata panels follow the same visual pattern.
4 months ago
milvasic 6b0736b293
fix(ui): show comment editor above the comment list (#5662) 4 months ago
Steven f7ac6a0191 refactor: auth token refresh flow and simplify user hooks 5 months ago
Steven 333c9df233 fix(web): refresh memo detail cache after editor save 5 months ago
Steven bbdc998646 fix(web): use BroadcastChannel to sync token refreshes across tabs
When multiple tabs are open and a token expires, each tab independently
attempts a refresh. With server-side token rotation this causes all but
the first tab to fail, logging the user out.

Add a BroadcastChannel (memos_token_sync) so that when any tab
successfully refreshes, it broadcasts the new token to all other tabs.
Receiving tabs adopt the token in-memory immediately, skipping their own
refresh request and avoiding conflicts with token rotation.

Falls back gracefully when BroadcastChannel is unavailable (e.g. some
privacy modes).
5 months ago
Steven 9ecd7b876b fix(web): fix spurious logout on page reload with expired access token
Two bugs caused users to be redirected to /auth too frequently:

1. Race condition in Promise.all([initInstance(), initAuth()]):
   initInstance() makes a gRPC request whose auth interceptor calls
   getAccessToken() synchronously. When the access token was expired,
   getAccessToken() eagerly deleted it from localStorage as a "cleanup"
   side-effect. By the time initAuth() ran and checked hasStoredToken(),
   localStorage was already empty, so it skipped the getCurrentUser()
   call and the token refresh cycle entirely — logging the user out even
   when the refresh-token cookie was still valid. Fix: remove the
   localStorage deletion from getAccessToken(); clearAccessToken()
   (called on confirmed auth failure and logout) handles proper cleanup.

2. React Query retry: 1 caused a second refresh+redirect attempt after
   auth failures. The auth interceptor already handles token refresh and
   request retry internally. If it still throws Unauthenticated, the
   redirect is already in flight — a React Query retry only fires another
   failed refresh and a redundant redirectOnAuthFailure() call. Fix: use
   a shouldRetry function that skips retries for Unauthenticated errors
   while keeping the existing once-retry behaviour for other errors.
5 months ago
Steven 03c30b8ccb fix(web): fix explore page showing private tags and improve stats hook
The explore page sidebar was showing tags from the current user's private
memos because the default ListMemos query applies a server-side OR filter
(creator_id == X || visibility in [...]), mixing private content in.

Fix by using a visibility-scoped ListMemos request in the explore context
so private memos are always excluded via the AND'd server auth filter.

Also consolidate two always-firing useMemos calls into one context-aware
query, unify activity stats computation with countBy across all branches,
and extract a toDateString helper to remove duplicated formatting logic.
5 months ago
Steven 1cea9b0a78 fix(web): make MonthNavigator month label reactive to language changes
Use useTranslation() hook instead of the static i18n import so that
the month label re-computes when the language changes.
5 months ago
Steven 17fc8383df fix(web): improve MemoEditor layout and timestamp popover styling 5 months ago
Steven c3061002f3 fix(web): persist auth token in localStorage for cross-tab sessions
Switch from sessionStorage to localStorage so the auth token survives
across tabs and browser restarts, matching standard platform behavior.
Also guard the signup redirect in App.tsx behind profileLoaded to avoid
a false redirect when the instance profile fetch fails.
5 months ago
Steven 4aaebc507e fix(web): skip GetCurrentUser on init when no token is stored
When no token exists in sessionStorage, AuthContext.initialize() was
still calling GetCurrentUser, triggering the auth interceptor to attempt
RefreshToken and retry — producing a burst of 5+ auth API calls in under
a second that reverse proxies with rate limiting (e.g. CrowdSec) flag as
brute force.

Add hasStoredToken() to auth-state and bail out of initialize() early
when there is definitively no session to restore. The refresh flow for
expired tokens is preserved since hasStoredToken() checks for presence
regardless of expiry.

Fixes #5647
5 months ago
Steven b8bca6bacf fix(web): scope task list item index to memo content container
The closest() selector was targeting a CSS class that never existed on
the container, causing fallback to document.body and collecting task
items across all visible memos. This caused index collisions when
multiple memos with todo lists were on the page.

Adds data-memo-content attribute to the container and updates the
selector accordingly.

Fixes #5635
5 months ago
Steven 2ab476ef2e fix(web): memoize useNavigateTo to prevent infinite view transition loop
Wrapping the returned function in useCallback prevents a new reference
on every render, which was causing an infinite startViewTransition loop
on the initial signup page (fresh install with no admin).

Fixes #5626
5 months ago
Steven 6eaab52e48 fix(web): handle delete memo errors and only run post-delete actions on success 5 months ago
milvasic 1d9d4cd797
fix: invalidate comments query on comment reaction and delete (#5641) 5 months ago
Kaki021 122ac94273
fix(web): ensure default memo visibility is correctly applied (#5623) 5 months ago
Steven 861b58cbf3 refactor(web): extract NsfwOverlay into standalone component with flexbox centering 5 months ago
Steven aeb1e5fe40 perf(web): eliminate redundant fetch when opening inline memo editor 5 months ago
Johnny 6402618c26 feat(web): replace EditableTimestamp with inline editor timestamp popover 5 months ago
Johnny 566fdccae6 fix(web): allow calendar year picker to go back to 1970 5 months ago
Johnny 177a74e82b fix: allow ampersand in tags to support compound tags 5 months ago
Steven 47e2ace690 fix(web): redirect to auth page instead of explore on session expiry
Fixes #5617
5 months ago
MuLingQwQ b5108b4f97
fix(web): calendar navigation should use current page path (#5605) 5 months ago
Johnny f827296d6b chore: fix broken links 5 months ago
Johnny c4176b4ef1 fix: videos attachment 5 months ago
Steven 81ef53b398 fix: prevent 401 errors on window focus when token expires
Fixes #5589

When the page returns from background to foreground after the JWT
token expires (~15 min), React Query's automatic refetch-on-focus
triggers multiple API calls simultaneously. These all fail with 401
Unauthorized, leaving the user with empty content.

Solution:
- Add useTokenRefreshOnFocus hook that listens to visibilitychange
- Proactively refresh token BEFORE React Query refetches
- Uses 2-minute buffer to catch expiring tokens early
- Graceful error handling - logs error but doesn't block

Changes:
- Created web/src/hooks/useTokenRefreshOnFocus.ts
- Updated isTokenExpired() to accept optional buffer parameter
- Exported refreshAccessToken() for use by the hook
- Integrated hook into AppInitializer (only when user authenticated)
5 months ago
Steven cf65f0867b refactor: remove hide-scrollbar utility
Removed the hide-scrollbar CSS class and all its usages throughout the
codebase. Hiding scrollbars can hurt UX by making it unclear when
content is scrollable.

Changes:
- Removed hide-scrollbar CSS definition from index.css
- Removed hide-scrollbar class from Navigation component (2 instances)
- Removed hide-scrollbar class from MemoDetailSidebar (2 instances)
- Removed hide-scrollbar class from TagsSection
- Removed hide-scrollbar class from ShortcutsSection

Components now use standard browser scrollbar behavior, which provides
better visual feedback to users about scrollable content. Modern
browsers already handle scrollbar appearance elegantly.
5 months ago
Steven 74b63b278c perf: disable tooltips in year calendar to fix lag
Fixed issue #5579 where the calendar selection dialog was very laggy.

The root cause was rendering ~365 individual Tooltip components when
opening the year calendar view (one per day with activity). This created
a huge number of DOM nodes and event listeners that caused significant
performance issues.

Changes:
- Added disableTooltips prop to MonthCalendar and CalendarCell components
- Disabled tooltips in YearCalendar's small month views
- Removed unnecessary TooltipProvider wrapper in YearCalendar
- Tooltips remain enabled in the default month calendar view

Performance improvements:
- Eliminates ~365 tooltip instances when dialog opens
- Reduces initial render time significantly
- Makes dialog interactions smooth and responsive

Users can still click on dates to drill down for details if needed.
5 months ago