Commit Graph

929 Commits

Author SHA1 Message Date
admin bdc607c6c5 fix(auth): update legal text and center icon+label in auth buttons
- Update auth-legal-text copy to "I agree to the Cozsweet Privacy
  Agreement and Terms of User", keeping the two external links.
- Center the Facebook icon and "Login with Facebook" label as a group
  inside the main Facebook button (change .facebookLabel flex).
- Apply the same centering to the shared AuthSocialButton .label rule
  so the Email and Facebook entries in the "Other Sign-in Options"
  bottom sheet also render icon+text centered.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-11 18:58:12 +08:00
admin d55694a73e refactor(chat): move WebSocket lifecycle into chat machine via fromCallback actor
- chat-screen no longer manages WebSocket directly; it now dispatches three
  auth lifecycle events (ChatGuestLogin, ChatNonGuestLogin, ChatLogout)
  derived from auth.loginStatus
- chat-machine internally owns the WebSocket long-lived actor via
  fromCallback, completing the previously deferred migration scope
- removed ChatWebSocket import, getWsToken helper, and direct WS
  effect from chat-screen; renamed dispatchInitialLoad to
  dispatchAuthLifecycle to reflect the new responsibility
- decouples auth from chat machine via event-driven boundary: machine
  stays unaware of loginStatus, guest semantics live at the dispatch
  layer (guest → skip WS, non-guest → connect with token)
2026-06-11 18:57:11 +08:00
admin 4b356f58f2 refactor(chat): remove unused ChatScreenVisible and ChatScreenInvisible events
The screen-lifecycle events were dead code: the transitions in chat-machine
(idle <-> ready) had no caller behavior tied to them, and the dispatches
in chat-screen.tsx were the only senders. Drop the union members, both
state transitions, and the mount-effect dispatches.

The idle state remains declared as initial but is no longer reachable
at runtime; can be refactored in a follow-up.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-11 18:39:50 +08:00
admin ed4ccddae3 refactor(chat): decouple chat state from auth and gate quota alerts to guests
- Remove ChatAuthStatusChanged dispatch from auth login flow; chat screen now subscribes directly to auth state machine (loginStatus) to derive isGuest and drive WS lifecycle
- Gate quota-exceeded and warning dialogs to guests only (non-guests have no message limit)
- Dispatch ChatLoadMoreHistory for non-guest initial load vs ChatInit for guests
- Fix AppConstants import path from @/core/constants/app_constants to @/core/app_constants
- Add defensive isGuest checks in quota effects to prevent non-guest quota triggers
2026-06-11 18:31:08 +08:00
kanban e3d069e49f fix(chat): remove 75% cap on text bubble and add outer margin
TextBubble now fills the available half-row width instead of being
capped at 75%. Add 16px margin on the avatar-side edge (margin-left
for AI, margin-right for user) so short messages still feel airy
and long messages are no longer artificially clipped.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-11 18:25:47 +08:00
admin 0ffc961e00 refactor(core): consolidate core files under src/core directory
Move breakpoints, fonts, and app_constants into the core directory for better organization:
- Move src/lib/breakpoints.ts to src/core/breakpoints.ts
- Move src/lib/fonts.ts to src/core/fonts.ts
- Move src/core/constants/app_constants.ts to src/core/app_constants.ts and clean up outdated comments
2026-06-11 18:16:08 +08:00
admin e68aa09395 fix(chat): improve text bubble layout to fill width and prevent overflow 2026-06-11 17:25:54 +08:00
admin be6abaacd8 fix(auth): short-circuit guestLoginActor when local guestToken exists
Skip /auth/guest round-trip on splash Skip when localStorage already
holds a valid guestToken. Avoids redundant API call (and the
fingerprintjs deviceId probe) every time the user reopens splash.

Trade-off: a server-revoked token still resolves "guest" until the
first protected API call returns 401, which the HTTP layer handles.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-11 17:12:24 +08:00
Claude d205025a11 fix(splash): left-align bottom text on splash screen 2026-06-11 17:06:47 +08:00
admin 982d9ba790 refactor(data): add I*Repository interfaces and depend on them in stores
为 /src/data/repositories/ 下每个仓库类增加对应的接口契约,
接口文件存放在独立的 interfaces/ 子目录中。

改动:
- 新建 4 个接口文件 (iauth_repository / ichat_repository /
  imetrics_repository / iuser_repository),纯 type-only,方法签名
  与实现类完全一致
- 4 个实现类加 implements I{Name}Repository 子句,编译器自动校验契约
- 3 个 stores 文件 (auth / chat / user state machines) 改为依赖接口
  类型:通过 `const xxxRepo: I{Name}Repository = xxxRepository` 局部别名,
  actor 内部调用全部走别名
- barrelsby.json 加入 interfaces/ 目录,让自动 barrel 能覆盖
- Auto-regenerated repositories/index.ts 与 interfaces/index.ts

参照 storage 层已有的 IAuthStorage / IChatStorage / IUserStorage 模式。

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-11 17:02:49 +08:00
admin 1151a9a61b fix:splash 界面重定向界面问题 2026-06-11 17:00:04 +08:00
admin e3d549d660 fix:splash 界面重定向界面问题 2026-06-11 16:06:36 +08:00
admin a6bc6941d4 refactor(splash): convert Skip to explicit guest login flow
- Splash Skip button now dispatches `AuthGuestLoginSubmitted` instead of
  direct routing, keeping guest auth under the state machine
- Update PWA install dialog copy ("Add to Home Screen") and drop favicon
  entry from manifest icons
- Add debug logging and routing sequence docs to splash-button
2026-06-11 15:58:48 +08:00
admin e557f084c4 feat: add PWA icons (192x192 and 512x512) to web manifest
Include new splash icons in public/manifest.json to support Progressive Web App installation and display across various device resolutions.
2026-06-11 15:18:25 +08:00
admin 2f4d414412 feat(utils): add structured error logging to Result.wrap
Integrate the Logger into `Result.wrap` so that caught exceptions are
recorded with stack trace, error type, and a `component: "Result"`
tag before being wrapped into a `Result<T>`. Errors are first
normalized via `toError` to preserve `.stack`, `.code`, and `.status`
fields, then logged through the standard pipeline (dev console in
development, JSON pipeline in production). Callers continue to receive
a `Result<T>` — re-throwing remains opt-in via `Result.unwrap`.
2026-06-11 14:58:54 +08:00
admin d189a18f03 chore(deps): add pino logger dependency
Add pino v10.3.1 to project dependencies for structured logging support, along with its transitive dependencies (pino-abstract-transport, pino-std-serializers, quick-format-unescaped, atomic-sleep, etc.).
2026-06-11 14:23:30 +08:00
admin 2b6d3924fd fix(chat): right-align user message row for proper mirror layout
Add align-self: flex-end to .bubbleRowUser so the user message row
sizes to its content and pins to the right edge of the chat area.
Combined with the existing flex-end cross-axis alignment, this places
the user avatar at the right edge with the bubble to its left,
producing a proper left-to-right AI / right-to-left user mirror.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-11 14:03:46 +08:00
admin 674df49e24 style(sidebar): align /sidebar screen with Flutter original
Match the Dart lib/ui/sidebar/sidebar_screen.dart + profile_view.dart
exactly:
- White inner shell with 24px padding
- Back button row (arrow icon + "Back" text, no "Profile" header)
- Single "Other" section with one "Log out" row
- Drop profile card, Account/Data/Session sections, and Sign-in CTA

Match Flutter row visuals in the shared SettingsSection:
- Gray (#f5f5f5) rounded row pill on a white card
- 20px chevron, 1px rgba(61,49,74,0.5) divider
- Destructive color #ff6b6b, 14px/600 black section title

Add tokens: --color-settings-card-background, --color-settings-row-background,
--color-settings-divider, --color-chevron-icon, --color-destructive.

Wire the BlocConsumer listener equivalent: on currentUser transitioning to
null, dispatch ChatAuthStatusChanged + AuthReset and router.replace("/chat").

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-11 14:02:52 +08:00
admin 2475cb3e45 feat(auth): add startup auth status check with device id fallback
Add AuthStatusChecker mounted in RootProviders to dispatch AuthStatusCheckSubmitted on mount. The new checkAuthStatusActor retrieves the device id, checks for an existing login or guest token, and falls back to a guest login API call when neither is present. Wires the new event/actor through the auth machine to enable automatic session restoration and guest-mode bootstrap.
2026-06-11 13:23:29 +08:00
admin 7c89f1b39d fix(chat): align message bubble and avatar in the same row
Change flex-direction from column to row on .bubbleRowAi and
.bubbleRowUser so the avatar and message content render side-by-side
as the JSX and JSDoc already intend.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-11 13:00:32 +08:00
admin 0c63b7dee4 feat(auth): sync OAuth provider tokens to backend via NextAuth session
Wire the Google/Facebook OAuth callback flow end-to-end so the provider's id_token (Google) and access_token (Facebook) captured by NextAuth are forwarded to the backend in exchange for business tokens:

- Extend the NextAuth config with jwt/session callbacks that surface `account.id_token` / `account.access_token` to the client during first sign-in
- Add an `OAuthSessionSync` bridge mounted inside `RootProviders` that listens to `useSession()` and dispatches new `AuthGoogleSyncSubmitted` / `AuthFacebookSyncSubmitted` events
- Add corresponding actors in the auth XState machine that call `authRepository.googleLogin` / `facebookLogin`, persisting the backend's `LoginResponse` through the existing repository path

This keeps all authentication orchestrated by the auth state machine while preserving NextAuth's OAuth redirect UX.
2026-06-11 12:59:23 +08:00
admin b50191ed50 refactor(auth): rename loginType to loginStatus and update related logic 2026-06-11 12:04:48 +08:00
admin 72941d9c9f style(pwa-install-dialog): redesign dialog to match Dart spec
Update the PWA install dialog styling and content to align with the
original Dart design, including a white background with large 40px
radius, 86x86 PNG icon, gradient primary button, and dynamic app title
sourced from AppConstants.
2026-06-11 11:29:52 +08:00
admin 39ef78e9ea refactor(sidebar): move SidebarPage/BottomNavItem enums to sidebar-state
Move the `SidebarPage` and `BottomNavItem` enum definitions from
`sidebar-machine.ts` to `sidebar-state.ts` to avoid a circular
dependency between the two modules. Since both enums are tightly
coupled to the state shape (they define the value sets of
`currentPage` and `selectedBottomNavItem`), they now live alongside
the state itself.

- Move enum declarations and types from `sidebar-machine.ts` to
  `sidebar-state.ts`
- Update `sidebar-events.ts` import path to reference `sidebar-state`
- Keep `sidebar-machine.ts` re-exporting `SidebarState` and
  `initialState` to preserve its public API
2026-06-11 10:35:57 +08:00
admin d0df7296cc chore: add build:start script to package.json for streamlined deployment 2026-06-11 10:29:17 +08:00
kanban e2a57386e7 refactor(auth): funnel OAuth signIn into auth state machine
Move new AuthPlatform(provider).signIn() out of UI components and into
the auth state machine. UI now dispatches AuthGoogle/FacebookLoginSubmitted
events; a new oauthSignIn actor inside the machine calls next-auth/react's
signIn(provider). Errors and the OAuth redirect window are exposed via
the existing state.isLoading / state.errorMessage surface, removing the
local busy / error state in auth-facebook-panel.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-11 10:05:48 +08:00
admin d4cb40a74b chore: migrate contexts to stores and refresh barrel exports
- Move state management from `src/contexts` to `src/stores` (zustand-based)
- Update barrelsby config to include new stores directory
- Add bottom-sheet and auth-background components
- Auto-open browser on dev server ready in VS Code launch config
- Refresh generated barrel index files
2026-06-11 09:35:26 +08:00
admin 2bc2e1b691 refactor: migrate img tags to next/image and fix hook usage 2026-06-10 19:16:41 +08:00
admin 47591be41c refactor(auth): unify Facebook and Google login into AuthPlatform class
Replace the separate FacebookLogin and GoogleLogin classes with a single
AuthPlatform class that takes a provider name ("facebook" | "google") as a
constructor argument. This consolidates duplicate OAuth sign-in logic behind
one entry point while preserving the existing NextAuth flow.

- Add new src/lib/auth/auth_platform.ts exporting AuthPlatform and
  AuthProvider type
- Update auth-facebook-panel.tsx and splash-button.tsx to use the new API
- Rename initialContext → initialState in the auth machine for consistency
- Update inline docs and comments to reference AuthPlatform

No behavioral change for end users; both providers still route through
NextAuth's signIn() with the same callbacks and cookies.
2026-06-10 18:58:15 +08:00
kanban 744e23fc29 refactor(stores): split state and event unions into separate files
Extract `<Name>Context` interface + `initialContext` const into
`<name>-context.ts` and the event union into `<name>-events.ts` for
all four state machines (auth, chat, sidebar, user) under src/stores/.

- `*-machine.ts` keeps helpers, actors, actions, and the
  `setup().createMachine()` body; re-exports the types/initial value
  to preserve its public API.
- `*-types.ts` re-exports from the new files for backward compatibility
  (sidebar keeps enum re-exports, chat keeps GuestChatQuota).
- `index.ts` barrels updated to re-export the new files.
- Removed unused model imports (AuthMode, AuthPanelMode) from
  auth-machine.ts; kept LoginType, UiMessage, UserView where still
  used by actors/helpers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-10 18:24:04 +08:00
admin 0593920318 chore: cleanup unused exports and fix mobile shell background
- Remove unused CharacterIntro export from chat components index
- Drop stale JSDoc block from splash-screen server component
- Set mobile shell background to explicit black so the desktop area outside the 500px viewport is black instead of inheriting from parent
2026-06-10 18:18:03 +08:00
admin b95c3b8f02 refactor(auth): align auth screen with splash screen layout pattern
Extract background image into a reusable AuthBackground component and restructure AuthScreen to use MobileShell as the top-level wrapper, mirroring the SplashScreen implementation.
2026-06-10 18:00:58 +08:00
admin aa1688140a refactor: move websocket and message queue to core/net
Reorganize project structure by relocating chat-websocket and message-queue modules from `src/integrations/` to `src/core/net/` to better reflect their networking purpose and improve code organization.
2026-06-10 17:44:35 +08:00
admin a511beaa34 style(chat): align header and input styles with Dart implementation
Update chat-header and chat-input-text-field CSS to match the
Dart counterparts (chat_header.dart, chat_input_text_field.dart):
- Header: remove outer padding/background, use transparent base
- Guest banner: switch to --spacing-sm/md tokens
- Header row: add margin-left and symmetric padding
- Menu button: use 32px radius and #0d0b14 @ 0.7 background
- Input field: add white background, 32px radius, accent caret
  color, and flex centering for vertical text alignment
2026-06-10 17:44:23 +08:00
admin 5f3a343bb1 chore: allow pnpm builds for sharp and unrs-resolver
Add allowBuilds configuration for sharp and unrs-resolver packages
to permit their postinstall scripts to run, and ignore the local
.pnpm-store directory.
2026-06-10 17:28:47 +08:00
admin b02262fd4a chore: update pnpm configuration to allow all built dependencies 2026-06-10 17:23:19 +08:00
admin 956dd11ccc chore: configure pnpm to allow build scripts for next and tailwindcss
Allow pnpm to run build scripts for next, @tailwindcss/postcss, and tailwindcss by adding the onlyBuiltDependencies configuration. This is required to prevent pnpm from blocking post-install build scripts for these packages.
2026-06-10 16:52:55 +08:00
admin 6b5ec1d290 refactor(deploy): simplify script to git push-based deployment
Replace the previous Next.js build + rsync + archive workflow with a
minimal `push_to_server` helper that only does `git push` to the
`server` remote. Build, install, and start are now expected to be
handled by the server's post-receive hook, removing duplicate logic
and shrinking the script from 164 lines to 46. The old `build`,
`deploy`, `archive`, `setup_env`, and `check_local_build_dir`
functions (along with pnpm/rsync/sshpass usage) have been removed.
2026-06-10 16:48:50 +08:00
admin e0d0e353c0 refactor(auth): remove AuthGate abstraction in favor of useSession
- Drop AuthGate/AuthGateState re-exports from @/lib/auth/nextauth
- Simplify SplashButton by removing skipHref prop and hardcoding ROUTES.chat
- Update comments to reference useSession() (next-auth/react) directly instead of the AuthGate wrapper, since the auth UI gate no longer needs the extra abstraction layer.
2026-06-10 15:48:49 +08:00
admin d70e61f92e refactor(auth): switch to class-based social login and v4 route handler
Migrate from function-based social login helpers (`facebookLogin`, `googleLogin`)
to class-based services (`new FacebookLogin().signIn()`, `new GoogleLogin().signIn()`),
updating call sites in `AuthFacebookPanel` and `SplashButton` with try/catch error
handling. The NextAuth route handler is also refactored to the v4 pattern, importing
pre-built `GET` / `POST` exports from `@/lib/auth/nextauth` instead of constructing
the handler inline with `NextAuth(authOptions)`.
2026-06-10 15:34:52 +08:00
admin 90bb711a45 feat(auth): redesign auth UI to match Dart original
- Full-bleed bg_login.png background outside 500px MobileShell
- Facebook landing: logo + Facebook pill button + "Other Sign In Options" link
- Replace centered Dialog with true bottom sheet (drag handle, top radius 28px)
- Email panel: internal login/register toggle, no separate route
- Pink gradient primary button (#f96ADE → #f657A0)
- Pill input fields (46px, white, radius 24, pink 10% shadow)
- Pink circular checkbox + bold Privacy/Terms rich text (visual only, non-blocking)
- Floating 40x40 white back button (top:20/left:20)
- Wire AuthPanelModeChanged dispatch for panel switching
- New design tokens (--color-auth-*, --auth-*, --radius-bottom-sheet)
- New generic BottomSheet component
- Copy ic-logo-login.png (+@2x, +@3x) from Dart assets

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-10 14:29:30 +08:00
admin 4e27b4c512 build: drop next-pwa and switch to default Next 16 build 2026-06-10 14:24:51 +08:00
admin d768bf1f9e refactor(svg): remove unused SVG files from the public directory 2026-06-10 13:19:18 +08:00
admin cd693b75ae feat: integrate PWA support with @ducanh2912/next-pwa
Configure Progressive Web App capabilities for production builds, enabling offline support and installability. PWA is disabled in dev to avoid HMR conflicts, and switches the build to webpack since PWA tooling requires it.
2026-06-10 13:18:26 +08:00
admin 2066934094 refactor(auth): centralize auth routing via proxy and marker cookie 2026-06-10 12:47:47 +08:00
admin 1db3e3ae31 refactor(chat): align chat header and input bar with Dart source 2026-06-10 11:59:53 +08:00
admin 1e5b7420d3 feat(core): add centralized app constants module
Introduce AppConstants class to consolidate application-wide
constant values previously scattered across the Dart codebase.
Includes env-aware getters for appTitle and appUrl using
getAppEnv(), with NEXT_PUBLIC_* env overrides for OAuth client IDs
and sensible fallbacks for local development.
2026-06-10 11:18:58 +08:00
admin dc66b35e0e refactor(fonts): move font definitions to a dedicated fonts module 2026-06-10 11:06:08 +08:00
admin 2cba315214 refactor: move ROUTES from @/lib/routes to @/router/routes 2026-06-10 10:53:43 +08:00
admin a4b902893e refactor(auth): migrate social login to next-auth 2026-06-10 10:26:45 +08:00