Commit Graph

362 Commits

Author SHA1 Message Date
TerryM
562843e4b2 feat(stream): reset scroll to top on ?post deep-link arrivals
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 28s
Banner / Home-card clicks landing on /browse?post=X now always start the
smooth-scroll positioning from the top of the stream, instead of from
whatever scrollY the user happened to leave the page at. Runs in
useLayoutEffect before paint so the user never briefly sees the previous
position before the jump, giving a clearly visible scroll journey to the
target post every time.

Verified in the browser: before banner click scrollY=2000, immediately
after =0, then smooth-scrolled to ~25k as pagination loaded the target
post deeper in the stream.
2026-06-02 11:42:10 +08:00
TerryM
387b25f1e3 feat(stream): friendlier pagination loading + error retry
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 29s
- Replace the bare '…' loading dots at the bottom of the post stream
  with a skeleton bubble that matches the initial-load placeholders, so
  pagination feels like content arriving instead of a frozen indicator.
- Localize the retry control via new 'retry' / 'loadMoreFailed' keys
  across all 7 locales and surface a user-friendly error string instead
  of the raw exception message.
- Retry button now picks reset() vs loadMore() based on item count so a
  pagination failure only refetches the next page, not the whole stream.
- When a banner deep-link can't find its target post and pagination
  errors, break out of the retry loop and release the scroll lock so the
  user sees the inline retry instead of an endless freeze.

Verified in the browser: zh-CN renders '加载更多资料失败,请检查网络后重试。'
with a '重试' button; banner clicks with empty / '#' / 'javascript:' /
null linkUrls render no anchor and do not navigate.
2026-06-02 11:39:17 +08:00
TerryM
7ed9f8c8bf perf(banner): smoother deep-link from banner to /browse post
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 27s
- MessageStream: drop the mount-time scroll lock and the 80ms-delayed
  custom rAF; engage the lock only while the smooth animation runs and
  use native scrollTo({behavior:'smooth'}) so the page never feels frozen
  during pagination and the easing is buttery.
- PublicLayout: fire the default /browse prefetch immediately on mount
  (banner / Home tile destination) so a fast tap hits a warm cache;
  popular / latest stay deferred to idle.
- FigmaBanner: prefetch the all-scope stream on mount and on pointerdown
  as safety nets, and ignore empty / '#' / javascript: link URLs so a
  contentless banner renders as a non-interactive image.
- usePostStream: dedupe in-flight prefetches by key so concurrent
  callers (layout + banner) collapse into a single network request.
2026-06-02 11:30:47 +08:00
TerryM
fbb9d21f24 fix: cap banners shown to 10 with a single-row dot indicator
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 28s
The banners API can return hundreds of records; show at most 10 so the carousel
and its dot indicator stay on one row within the phone width, regardless of how
many exist on the backend.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 11:16:49 +08:00
TerryM
e752de67e1 fix(banner): preserve active language when navigating to post links
Banner linkUrls come back from the API as unprefixed paths
(e.g. /browse?post=123). Navigating to them directly dropped non-English
viewers into the English version of the post. Localize both the rendered
href and the SPA navigate target via stripLangPrefix + localizePath.
2026-06-02 11:12:26 +08:00
TerryM
8b0ee18cd8 fix: seed home categories from cache to stop icon flicker
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 29s
Initialize the categories state from the cached response on first render so the
category icons stay visible when navigating back to the home page, instead of
flashing empty for a frame.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 11:05:59 +08:00
TerryM
d3e562663d fix: cap banner dot indicator at 10 to avoid mobile overflow
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 40s
With many banners the pagination dots overflowed the phone width. Show at most
10 dots in a window that follows the active slide; each dot still maps to its
real slide index.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 11:01:15 +08:00
TerryM
92210cf0a2 fix(lightbox): extend save hint display to 2.5s 2026-06-02 10:52:08 +08:00
TerryM
6c0c3b89a9 fix(lightbox): anchor save hint below rendered image
Measure the image's rendered bottom edge with refs + ResizeObserver and
position the long-press save hint relative to it instead of pinning to
screen center or stage bottom. Enlarges the toast for mobile legibility
and clamps the offset so tall portrait images don't push it offscreen.
2026-06-02 10:51:17 +08:00
TerryM
8acb3a281b fix: opt out of browser auto-translation
The app ships its own 7-language i18n and serves localized content, but mobile
browsers (Google Translate) were auto-translating the Chinese UI into broken
English (brand, nav, language dropdown). Add translate="no" + the Google
notranslate meta, and keep the attribute set on language changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 10:47:36 +08:00
TerryM
4e33c7deef docs: add wallet/favorites UI redesign requirements brief
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 10:42:57 +08:00
TerryM
e1b24aa0f9 fix: keep desktop browser-wallet on direct injected; add login diagnostics
Revert desktop primary back to the direct injected sign (no WalletConnect relay,
which could spin forever) — reliable for a BNB-chain extension. Add console
diagnostics ([wallet-login] ...) and provider enumeration so a stuck/no-popup
flow can be pinpointed. WalletConnect stays as the explicit mobile MetaMask/
imToken option.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 10:38:29 +08:00
TerryM
11599e54ea fix: use RainbowKit picker for desktop browser-wallet login
Raw window.ethereum is unreliable when several extensions contend for it, so
desktop now opens the RainbowKit connect modal (EIP-6963 wallet discovery +
WalletConnect QR) when a project id is configured, falling back to the injected
flow otherwise. In-wallet mobile browsers keep the direct injected sign.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 10:33:59 +08:00
TerryM
8821058c0a fix: reset TokenPocket request state on expired/failed poll
Clear tpRequest when a TokenPocket login expires or fails so the mobile UI
returns to the initial state instead of showing a stuck waiting spinner
alongside the error.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 04:30:27 +08:00
TerryM
ed04e1fb7e fix: TokenPocket mobile deep-link login, desktop empty-state, toast above modal
- Mobile TokenPocket now opens the tpoutside:// sign deep link and returns to
  the original browser to finish login (no wallet in-app browser); desktop
  keeps the QR. Fixes mobile login + logout being trapped in TP's browser.
- Desktop without an injected wallet shows a clear message instead of a dead
  button; TokenPocket login card is always available as a working path.
- Raise toast z-index above the login modal so feedback is visible.
- Add native TokenPocket-login strings across 7 locales.
- Document that the live backend lacks favorites + TokenPocket routes (404),
  the real blocker for those features in production.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 04:00:30 +08:00
TerryM
7abe4a868c feat: redesign wallet login and favorites, fix desktop/mobile bugs
- Remove forced BNB chain switch on injected login (signature is chain-agnostic)
- Refine isMobileDevice so touch Macs stay on desktop flow
- Wire RainbowKit/WalletConnect as a real MetaMask/imToken QR fallback,
  gated on a valid VITE_WALLETCONNECT_PROJECT_ID
- Rebuild login modal: single desktop primary action, collapsible other
  methods, mobile open-app fallback feedback, brand icons
- Add My Favorites entry points (header, mobile menu, wallet dropdown)
- Favorites page: error retry, mobile filter drawer
- Auto sign-out and re-login prompt on favorites 401
- Full native translations for all wallet strings across 7 locales

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 03:43:13 +08:00
TerryM
f935f122f9 docs: design wallet login + favorites redesign and backend checklist
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 03:20:06 +08:00
TerryM
0edcc80513 fix: simplify wallet choices and use bnb chain 2026-06-02 02:58:01 +08:00
TerryM
b9fe7ff168 fix: batch favorite status checks 2026-06-02 01:11:00 +08:00
TerryM
fb6cb5bc11 fix: encode metamask dapp deep link 2026-06-02 01:06:55 +08:00
TerryM
184193e655 docs: note wallet session tradeoffs 2026-06-02 01:00:13 +08:00
TerryM
fc2ca62957 fix: clean up wallet favorites state 2026-06-02 00:57:37 +08:00
TerryM
05c2252b49 fix: close mobile menu before wallet login 2026-06-02 00:45:58 +08:00
TerryM
4900256423 feat: add favorites to latest rows 2026-06-02 00:41:06 +08:00
TerryM
de93e883c9 feat: build favorites page 2026-06-02 00:39:36 +08:00
TerryM
337e8f7e67 feat: add favorites state and buttons 2026-06-02 00:36:11 +08:00
TerryM
43700d9fdc feat: add wallet login modal 2026-06-02 00:32:46 +08:00
TerryM
71dac8373e feat: add wallet provider foundation 2026-06-02 00:28:22 +08:00
TerryM
df20005357 docs: design user favorites 2026-06-02 00:14:10 +08:00
TerryM
b265a57541 docs: design china-friendly wallet login 2026-06-02 00:05:37 +08:00
TerryM
5a5acfcbc2 fix: show save guide on mobile only
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 27s
2026-06-01 23:13:25 +08:00
TerryM
097c12bab5 copy: polish save album guide
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 36s
2026-06-01 23:09:25 +08:00
TerryM
e096d59fa6 feat: add media save guide 2026-06-01 23:00:28 +08:00
TerryM
7b48f9780c fix: use backend video preview urls
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 37s
2026-06-01 17:52:33 +08:00
TerryM
b4eb44f824 Merge terry-staging into main
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 37s
2026-06-01 16:56:51 +08:00
TerryM
56d6bd033d fix: sync language prefixes 2026-06-01 16:36:55 +08:00
TerryM
da4c13f304 fix: preserve localized redirects 2026-06-01 16:36:36 +08:00
TerryM
a968f47640 feat: support mobile video previews 2026-06-01 16:35:40 +08:00
TerryM
c53032155b feat(i18n): add full ja/vi/id/ms translations and drop languageNames fallback
- Add complete dicts: src/locales/{ja,vi,id,ms}.ts (115 keys each)
- Remove languageNames override map; dict object now points directly to each locale
- i18n.tsx shrinks from ~414 lines to ~81 lines
2026-06-01 15:54:29 +08:00
TerryM
337d19e626 feat(i18n): split locale dicts into src/locales/ and add full Korean translation
- Extract zhDict/enDict from i18n.tsx into src/locales/{zh-CN,en}.ts
- Add full Korean dictionary (src/locales/ko.ts) covering all 115 UI keys
- Update formatBytes test/impl boundary for 1000-based units
2026-06-01 15:49:15 +08:00
TerryM
c490524575 fix: widen desktop header brand max-width to fit longer translations 2026-06-01 15:42:00 +08:00
TerryM
c32ae539f6 fix: use decimal (1000-based) units in formatBytes to match S3/curl display 2026-06-01 15:24:41 +08:00
TerryM
4dcf68bc71 Merge terry-staging into main
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 36s
2026-06-01 15:11:53 +08:00
TerryM
fa78568c94 feat: add localized home routes 2026-06-01 15:09:58 +08:00
TerryM
6c4936fea3 Merge terry-staging into main
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 26s
2026-05-31 19:24:26 +08:00
TerryM
9b08379d50 fix: 2-column masonry at md with side padding, 3 at lg
- md (768-1023px): 2 columns with px-4 so cards don't kiss the screen edge.
- lg+ (>=1024px): 3 columns, parent wrapper provides spacing.
- <768px stays on the original single-column mobile branch.
2026-05-31 19:24:18 +08:00
TerryM
04badc26d1 Merge terry-staging into main
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 26s
2026-05-31 18:41:02 +08:00
TerryM
186ba362f3 fix: align banner width with 3-column latest section 2026-05-31 18:40:27 +08:00
d0302218b2 Merge pull request 'terry-staging' (#14) from terry-staging into main
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 35s
Reviewed-on: #14
2026-05-31 10:36:12 +00:00
TerryM
06fe117ebc feat: render desktop latest section as 3-column masonry
- Matches Figma design (file uHDZkVHjAp7BXDKQKB0PM4, node 4367-11405).
- Mobile keeps the existing 5-post single column unchanged.
- Desktop (md+) renders all 12 latest posts in a CSS-columns masonry
  with break-inside-avoid so each card's height stays content-driven.
- Adds an optional 'fluid' prop to MessageBubble that drops the
  standalone-feed max-widths so bubbles fill the masonry column. The
  /browse stream keeps the default non-fluid widths.
2026-05-31 18:35:57 +08:00