Skip to content

Comments

SPA#1538

Merged
MrgSub merged 1 commit intostagingfrom
06-28-spa
Jun 30, 2025
Merged

SPA#1538
MrgSub merged 1 commit intostagingfrom
06-28-spa

Conversation

@MrgSub
Copy link
Collaborator

@MrgSub MrgSub commented Jun 29, 2025

READ CAREFULLY THEN REMOVE

Remove bullet points that are not relevant.

PLEASE REFRAIN FROM USING AI TO WRITE YOUR CODE AND PR DESCRIPTION. IF YOU DO USE AI TO WRITE YOUR CODE PLEASE PROVIDE A DESCRIPTION AND REVIEW IT CAREFULLY. MAKE SURE YOU UNDERSTAND THE CODE YOU ARE SUBMITTING USING AI.

  • Pull requests that do not follow these guidelines will be closed without review or comment.
  • If you use AI to write your PR description your pr will be close without review or comment.
  • If you are unsure about anything, feel free to ask for clarification.

Description

Please provide a clear description of your changes.


Type of Change

Please delete options that are not relevant.

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature with breaking changes)
  • 📝 Documentation update
  • 🎨 UI/UX improvement
  • 🔒 Security enhancement
  • ⚡ Performance improvement

Areas Affected

Please check all that apply:

  • Email Integration (Gmail, IMAP, etc.)
  • User Interface/Experience
  • Authentication/Authorization
  • Data Storage/Management
  • API Endpoints
  • Documentation
  • Testing Infrastructure
  • Development Workflow
  • Deployment/Infrastructure

Testing Done

Describe the tests you've done:

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • Cross-browser testing (if UI changes)
  • Mobile responsiveness verified (if UI changes)

Security Considerations

For changes involving data or authentication:

  • No sensitive data is exposed
  • Authentication checks are in place
  • Input validation is implemented
  • Rate limiting is considered (if applicable)

Checklist

  • I have read the CONTRIBUTING document
  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in complex areas
  • I have updated the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix/feature works
  • All tests pass locally
  • Any dependent changes are merged and published

Additional Notes

Add any other context about the pull request here.

Screenshots/Recordings

Add screenshots or recordings here if applicable.


By submitting this pull request, I confirm that my contribution is made under the terms of the project's license.

Summary by CodeRabbit

  • New Features

    • Introduced a new localization system replacing translation hooks with direct message function calls.
    • Added localization project configuration and Inlang plugins for improved message formatting.
  • Bug Fixes

    • Enhanced pluralization handling across all supported languages for accurate message display.
  • Refactor

    • Unified translation and locale management across components by removing hook-based translations.
    • Removed obsolete navigation and email signature settings pages.
    • Simplified query and server provider logic, removing connection-specific and internationalization context code.
    • Disabled server-side rendering in the mail app.
    • Removed Cloudflare Worker request handler and related environment augmentations.
  • Chores

    • Updated dependencies and scripts, adding Inlang CLI and removing unused packages.
    • Cleaned up configuration files including Vite, Wrangler, and i18n settings.
    • Added .gitignore for localization cache.
    • Updated static asset handling and environment configurations for Cloudflare deployments.

Copy link
Collaborator Author

MrgSub commented Jun 29, 2025

This stack of pull requests is managed by Graphite. Learn more about stacking.

@MrgSub MrgSub marked this pull request as ready for review June 29, 2025 01:42
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 29, 2025

Walkthrough

This update removes the use-intl translation hook from the mail app and replaces all dynamic translation calls with direct imports of a message object m from @/paraglide/messages. Numerous components and hooks are refactored to use this new localization approach. Several files and procedures related to the old i18n system are deleted, and configuration and provider logic is simplified accordingly.

Changes

Files/Paths (grouped) Change Summary
apps/mail/app/(auth)/login/error-message.tsx, apps/mail/app/(routes)/settings/[...settings]/page.tsx, apps/mail/app/(routes)/settings/appearance/page.tsx, apps/mail/app/(routes)/settings/connections/page.tsx, apps/mail/app/(routes)/settings/danger-zone/page.tsx, apps/mail/app/(routes)/settings/general/page.tsx, apps/mail/app/(routes)/settings/labels/page.tsx, apps/mail/app/(routes)/settings/privacy/page.tsx, apps/mail/app/(routes)/settings/security/page.tsx, apps/mail/app/(routes)/settings/shortcuts/hotkey-recorder.tsx, apps/mail/app/(routes)/settings/shortcuts/page.tsx, apps/mail/components/connection/add.tsx, apps/mail/components/context/command-palette-context.tsx, apps/mail/components/context/label-sidebar-context.tsx, apps/mail/components/context/thread-context.tsx, apps/mail/components/create/create-email.tsx, apps/mail/components/create/editor.tsx, apps/mail/components/create/image-compression-settings.tsx, apps/mail/components/labels/label-dialog.tsx, apps/mail/components/mail/mail-display.tsx, apps/mail/components/mail/mail-iframe.tsx, apps/mail/components/mail/mail-list.tsx, apps/mail/components/mail/mail.tsx, apps/mail/components/mail/note-panel.tsx, apps/mail/components/mail/reply-composer.tsx, apps/mail/components/mail/thread-display.tsx, apps/mail/components/theme/theme-switcher.tsx, apps/mail/components/ui/app-sidebar.tsx, apps/mail/components/ui/nav-main.tsx, apps/mail/components/ui/nav-user.tsx, apps/mail/config/navigation.ts, apps/mail/hooks/driver/use-delete.ts, apps/mail/hooks/use-notes.tsx, apps/mail/hooks/use-optimistic-actions.ts, apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, apps/mail/lib/notes-utils.ts, apps/mail/lib/utils.ts Replaced useTranslations and dynamic translation calls with direct imports and usage of message object m from @/paraglide/messages for localization; removed related hooks and types.
apps/mail/app/(routes)/mail/[folder]/page.tsx Replaced useQuery with useLabels, removed loading state and spinner, simplified folder validation and navigation logic.
apps/mail/app/(routes)/mail/page.tsx Removed server-side loader and redirect, added client-side redirect logic with new function clientLoader.
apps/mail/app/entry.server.tsx Changed import of renderToReadableStream to use browser build with TypeScript error suppression.
apps/mail/app/root.tsx Removed loader, i18n data fetching, and connection ID logic; simplified layout and error boundary; replaced translation hook in NotFound.
apps/mail/components/mail/nav-main.tsx Deleted entire NavMain component.
apps/mail/i18n/config.ts, apps/mail/i18n/request.ts, apps/mail/worker.ts Deleted old i18n config, request utilities, and Cloudflare Worker entrypoint.
apps/mail/messages/*.json Updated pluralization message keys to use explicit pluralization object format across all locales.
apps/mail/package.json Updated dependencies: removed use-intl, added @inlang/paraglide-js and @inlang/cli, upgraded @tiptap packages, added machine translation script.
apps/mail/project.inlang/.gitignore, apps/mail/project.inlang/project_id, apps/mail/project.inlang/settings.json Added new Inlang localization project config, project ID, and gitignore.
apps/mail/providers/query-provider.tsx Removed connection ID logic from query client creation and provider.
apps/mail/providers/server-providers.tsx Removed i18n provider and connection ID from server providers.
apps/mail/react-router.config.ts Disabled SSR by setting ssr to false.
apps/mail/vite.config.ts Added Paraglide Vite plugin, removed Cloudflare SSR env, updated plugin config.
apps/mail/wrangler.jsonc Updated Cloudflare Worker config: removed node compatibility, main entry, added static assets, updated compatibility date and env names.
apps/server/src/trpc/routes/cookies.ts Removed setLocaleCookie procedure from cookie preferences router.
i18n.json Changed included JSON path from locales to messages.

Sequence Diagram(s)

sequenceDiagram
    participant Component
    participant m (Paraglide Messages)
    Note over Component: (Old) Using useTranslations hook
    Component->>useTranslations: import/use hook
    useTranslations-->>Component: t function
    Component->>t: t('key')
    t-->>Component: localized string

    Note over Component: (New) Using direct message object
    Component->>m: import m from messages
    Component->>m: m['key']()
    m-->>Component: localized string
Loading

Possibly related PRs

  • Mail-0/Zero#1386: Modifies the same loader function in apps/mail/app/(routes)/mail/page.tsx, indicating a direct code-level relation.
  • Mail-0/Zero#1342: Refactors or modifies the now-removed NavMain component, directly relating to its deletion in this PR.
  • Mail-0/Zero#1375: Refactors the now-deleted apps/mail/i18n/request.ts file, which is removed in this PR.

Suggested labels

Low Priority

Poem

A bunny with code on its mind,
Hopped through translations, old and entwined.
Out went the hooks, in came the m’s,
Now messages flow like carrot gems!
With plural forms clear, and configs anew,
This rabbit’s work makes mail feel brand new.
🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4d6443c and 2579d85.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (78)
  • apps/mail/app/(auth)/login/error-message.tsx (3 hunks)
  • apps/mail/app/(routes)/mail/[folder]/page.tsx (2 hunks)
  • apps/mail/app/(routes)/mail/page.tsx (1 hunks)
  • apps/mail/app/(routes)/settings/[...settings]/page.tsx (2 hunks)
  • apps/mail/app/(routes)/settings/appearance/page.tsx (6 hunks)
  • apps/mail/app/(routes)/settings/connections/page.tsx (9 hunks)
  • apps/mail/app/(routes)/settings/danger-zone/page.tsx (8 hunks)
  • apps/mail/app/(routes)/settings/general/page.tsx (13 hunks)
  • apps/mail/app/(routes)/settings/labels/page.tsx (6 hunks)
  • apps/mail/app/(routes)/settings/privacy/page.tsx (6 hunks)
  • apps/mail/app/(routes)/settings/security/page.tsx (4 hunks)
  • apps/mail/app/(routes)/settings/shortcuts/hotkey-recorder.tsx (2 hunks)
  • apps/mail/app/(routes)/settings/shortcuts/page.tsx (3 hunks)
  • apps/mail/app/(routes)/settings/signatures/page.tsx (0 hunks)
  • apps/mail/app/entry.server.tsx (1 hunks)
  • apps/mail/app/root.tsx (5 hunks)
  • apps/mail/components/connection/add.tsx (3 hunks)
  • apps/mail/components/context/command-palette-context.tsx (7 hunks)
  • apps/mail/components/context/label-sidebar-context.tsx (4 hunks)
  • apps/mail/components/context/thread-context.tsx (13 hunks)
  • apps/mail/components/create/create-email.tsx (3 hunks)
  • apps/mail/components/create/editor.tsx (11 hunks)
  • apps/mail/components/create/image-compression-settings.tsx (4 hunks)
  • apps/mail/components/labels/label-dialog.tsx (6 hunks)
  • apps/mail/components/mail/mail-display.tsx (23 hunks)
  • apps/mail/components/mail/mail-iframe.tsx (3 hunks)
  • apps/mail/components/mail/mail-list.tsx (8 hunks)
  • apps/mail/components/mail/mail.tsx (8 hunks)
  • apps/mail/components/mail/nav-main.tsx (0 hunks)
  • apps/mail/components/mail/note-panel.tsx (28 hunks)
  • apps/mail/components/mail/reply-composer.tsx (3 hunks)
  • apps/mail/components/mail/thread-display.tsx (10 hunks)
  • apps/mail/components/theme/theme-switcher.tsx (2 hunks)
  • apps/mail/components/ui/app-sidebar.tsx (2 hunks)
  • apps/mail/components/ui/nav-main.tsx (6 hunks)
  • apps/mail/components/ui/nav-user.tsx (9 hunks)
  • apps/mail/config/navigation.ts (6 hunks)
  • apps/mail/hooks/driver/use-delete.ts (2 hunks)
  • apps/mail/hooks/use-notes.tsx (2 hunks)
  • apps/mail/hooks/use-optimistic-actions.ts (4 hunks)
  • apps/mail/i18n/config.ts (0 hunks)
  • apps/mail/i18n/request.ts (0 hunks)
  • apps/mail/lib/hotkeys/mail-list-hotkeys.tsx (9 hunks)
  • apps/mail/lib/notes-utils.ts (4 hunks)
  • apps/mail/lib/utils.ts (3 hunks)
  • apps/mail/messages/ar.json (4 hunks)
  • apps/mail/messages/ca.json (4 hunks)
  • apps/mail/messages/cs.json (4 hunks)
  • apps/mail/messages/de.json (5 hunks)
  • apps/mail/messages/en.json (6 hunks)
  • apps/mail/messages/es.json (4 hunks)
  • apps/mail/messages/fa.json (4 hunks)
  • apps/mail/messages/fr.json (4 hunks)
  • apps/mail/messages/hi.json (4 hunks)
  • apps/mail/messages/hu.json (4 hunks)
  • apps/mail/messages/ja.json (4 hunks)
  • apps/mail/messages/ko.json (4 hunks)
  • apps/mail/messages/lv.json (4 hunks)
  • apps/mail/messages/nl.json (4 hunks)
  • apps/mail/messages/pl.json (4 hunks)
  • apps/mail/messages/pt.json (4 hunks)
  • apps/mail/messages/ru.json (4 hunks)
  • apps/mail/messages/tr.json (4 hunks)
  • apps/mail/messages/vi.json (4 hunks)
  • apps/mail/messages/zh_CN.json (5 hunks)
  • apps/mail/messages/zh_TW.json (4 hunks)
  • apps/mail/package.json (3 hunks)
  • apps/mail/project.inlang/.gitignore (1 hunks)
  • apps/mail/project.inlang/project_id (1 hunks)
  • apps/mail/project.inlang/settings.json (1 hunks)
  • apps/mail/providers/query-provider.tsx (4 hunks)
  • apps/mail/providers/server-providers.tsx (1 hunks)
  • apps/mail/react-router.config.ts (1 hunks)
  • apps/mail/vite.config.ts (3 hunks)
  • apps/mail/worker.ts (0 hunks)
  • apps/mail/wrangler.jsonc (1 hunks)
  • apps/server/src/trpc/routes/cookies.ts (1 hunks)
  • i18n.json (1 hunks)
💤 Files with no reviewable changes (5)
  • apps/mail/components/mail/nav-main.tsx
  • apps/mail/i18n/request.ts
  • apps/mail/app/(routes)/settings/signatures/page.tsx
  • apps/mail/i18n/config.ts
  • apps/mail/worker.ts
✅ Files skipped from review due to trivial changes (1)
  • apps/mail/components/connection/add.tsx
🚧 Files skipped from review as they are similar to previous changes (72)
  • apps/mail/app/entry.server.tsx
  • apps/mail/project.inlang/.gitignore
  • apps/mail/react-router.config.ts
  • apps/mail/app/(routes)/settings/[...settings]/page.tsx
  • apps/mail/app/(routes)/settings/labels/page.tsx
  • apps/mail/app/(routes)/settings/privacy/page.tsx
  • apps/mail/messages/hu.json
  • i18n.json
  • apps/mail/project.inlang/project_id
  • apps/mail/app/(routes)/mail/page.tsx
  • apps/mail/messages/de.json
  • apps/mail/components/ui/app-sidebar.tsx
  • apps/mail/hooks/driver/use-delete.ts
  • apps/server/src/trpc/routes/cookies.ts
  • apps/mail/messages/hi.json
  • apps/mail/components/labels/label-dialog.tsx
  • apps/mail/app/(routes)/settings/connections/page.tsx
  • apps/mail/app/(routes)/settings/shortcuts/hotkey-recorder.tsx
  • apps/mail/components/ui/nav-main.tsx
  • apps/mail/messages/ar.json
  • apps/mail/components/mail/reply-composer.tsx
  • apps/mail/messages/ru.json
  • apps/mail/app/(routes)/settings/appearance/page.tsx
  • apps/mail/components/context/label-sidebar-context.tsx
  • apps/mail/messages/fr.json
  • apps/mail/app/(routes)/settings/shortcuts/page.tsx
  • apps/mail/messages/en.json
  • apps/mail/components/theme/theme-switcher.tsx
  • apps/mail/app/(routes)/settings/security/page.tsx
  • apps/mail/components/mail/mail-iframe.tsx
  • apps/mail/hooks/use-optimistic-actions.ts
  • apps/mail/messages/zh_CN.json
  • apps/mail/app/(routes)/settings/danger-zone/page.tsx
  • apps/mail/components/create/editor.tsx
  • apps/mail/messages/pl.json
  • apps/mail/messages/zh_TW.json
  • apps/mail/app/(auth)/login/error-message.tsx
  • apps/mail/messages/pt.json
  • apps/mail/wrangler.jsonc
  • apps/mail/messages/ca.json
  • apps/mail/components/context/thread-context.tsx
  • apps/mail/components/create/create-email.tsx
  • apps/mail/lib/notes-utils.ts
  • apps/mail/components/create/image-compression-settings.tsx
  • apps/mail/lib/hotkeys/mail-list-hotkeys.tsx
  • apps/mail/messages/ko.json
  • apps/mail/messages/tr.json
  • apps/mail/hooks/use-notes.tsx
  • apps/mail/messages/nl.json
  • apps/mail/components/mail/thread-display.tsx
  • apps/mail/messages/vi.json
  • apps/mail/app/root.tsx
  • apps/mail/messages/cs.json
  • apps/mail/messages/es.json
  • apps/mail/app/(routes)/mail/[folder]/page.tsx
  • apps/mail/package.json
  • apps/mail/providers/server-providers.tsx
  • apps/mail/components/mail/note-panel.tsx
  • apps/mail/lib/utils.ts
  • apps/mail/project.inlang/settings.json
  • apps/mail/config/navigation.ts
  • apps/mail/messages/ja.json
  • apps/mail/vite.config.ts
  • apps/mail/components/mail/mail-display.tsx
  • apps/mail/components/mail/mail-list.tsx
  • apps/mail/providers/query-provider.tsx
  • apps/mail/app/(routes)/settings/general/page.tsx
  • apps/mail/components/ui/nav-user.tsx
  • apps/mail/messages/lv.json
  • apps/mail/messages/fa.json
  • apps/mail/components/mail/mail.tsx
  • apps/mail/components/context/command-palette-context.tsx
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Cursor BugBot
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

cursor[bot]

This comment was marked as outdated.

Copy link
Collaborator Author

MrgSub commented Jun 29, 2025

bugbot run

cursor[bot]

This comment was marked as outdated.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 17

🔭 Outside diff range comments (5)
apps/mail/components/mail/thread-display.tsx (1)

688-693: Action Required: Correct toast logic in handleToggleImportant

The current implementation in apps/mail/components/mail/thread-display.tsx around lines 688–693 uses the stale isImportant closure and erroneously shows an error toast on a successful “mark as important” operation—and never shows a message when unmarking. Update it to derive the new state from the refetchThread() result and show success messages for both actions:

• Location: apps/mail/components/mail/thread-display.tsx
• Around lines 686–693 (inside handleToggleImportant)

Suggested diff:

-  await toggleImportant({ ids: [id] });
-  await refetchThread();
-  if (isImportant) {
-    toast.success(m['common.mail.markedAsImportant']());
-  } else {
-    toast.error('Failed to mark as important');
-  }
+  await toggleImportant({ ids: [id] });
+  const { data: thread } = await refetchThread();
+  const nowImportant = thread?.important;
+  if (nowImportant) {
+    toast.success(m['common.mail.markedAsImportant']());
+  } else {
+    toast.success(m['common.mail.removedFromImportant']());
+  }

This ensures you read the updated flag and always display the correct success message for both marking and unmarking.

apps/mail/components/connection/add.tsx (1)

74-89: Localize the hardcoded English strings in the upgrade prompt.

The upgrade prompt contains several hardcoded English strings that should be moved to the localization files for consistency with the rest of the application.

Consider adding these strings to your localization files:

-              You can only connect 1 email in the free tier.{' '}
+              {m['pages.settings.connections.freeTrialLimit']()}{' '}
-                Start 7 day free trial
+                {m['pages.settings.connections.startFreeTrial']()}
-              to connect more.
+              {m['pages.settings.connections.toConnectMore']()}
-              $20<span className="text-muted-foreground -ml-2 text-xs">/month</span>
+              {m['pages.settings.connections.proPrice']()}<span className="text-muted-foreground -ml-2 text-xs">/{m['pages.settings.connections.perMonth']()}</span>
apps/mail/components/create/image-compression-settings.tsx (1)

57-75: Fix the hardcoded translation keys for quality options.

All quality options are incorrectly showing the "low" quality label and description. The translation keys should be dynamic based on the option value.

Apply this fix to use the correct translation keys for each quality option:

-                      <Label htmlFor={option.value} className="cursor-pointer text-sm font-medium">
-                        {m['pages.createEmail.imageCompression.low.label']()}
-                      </Label>
-                      <span className="text-muted-foreground text-xs">
-                        {m['pages.createEmail.imageCompression.low.description']()}
-                      </span>
+                      <Label htmlFor={option.value} className="cursor-pointer text-sm font-medium">
+                        {m[`pages.createEmail.imageCompression.${option.value}.label`]()}
+                      </Label>
+                      <span className="text-muted-foreground text-xs">
+                        {m[`pages.createEmail.imageCompression.${option.value}.description`]()}
+                      </span>
apps/mail/components/ui/nav-user.tsx (1)

509-598: Localize the remaining hardcoded UI strings.

Several UI strings remain hardcoded in English and should be moved to localization files for consistency.

Consider localizing these strings:

  • Line 513: "Billing"{m['common.navUser.billing']()}
  • Line 556: "Debug"{m['common.navUser.debug']()}
  • Line 560: "Copy Connection ID"{m['common.navUser.copyConnectionId']()}
  • Line 566: "Clear Local Cache"{m['common.navUser.clearCache']()}
  • Lines 547-548, 551-552: "Privacy" and "Terms"{m['common.navUser.privacy']()} and {m['common.navUser.terms']()}
  • Line 596: "Get verified"{m['common.navUser.getVerified']()}
apps/mail/lib/notes-utils.ts (1)

29-31: Fix missing localization for yellow color.

The yellow color label is still hardcoded as 'Yellow' while all other colors use the localization system. This creates inconsistency in the user interface.

Apply this fix:

  {
    value: 'yellow',
-    label: 'Yellow',
+    label: m['common.notes.colors.yellow'](),
    class: 'border-l-amber-500',
    bgClass: 'hover:bg-amber-50 dark:hover:bg-amber-950/20',
    style: { borderLeftColor: 'rgb(245, 158, 11)' },
  },
♻️ Duplicate comments (3)
apps/mail/messages/ca.json (1)

176-186: Mirror the placeholder change for fileCount

-            "countPlural=0": "fitxers",
-            "countPlural=one": "fitxer",
-            "countPlural=other": "fitxers"
+            "countPlural=0": "0 fitxers",
+            "countPlural=one": "# fitxer",
+            "countPlural=other": "# fitxers"
apps/mail/messages/zh_CN.json (1)

176-186: Same for fileCount

-            "countPlural=0": "文件",
-            "countPlural=one": "个文件",
-            "countPlural=other": "个文件"
+            "countPlural=0": "0 个文件",
+            "countPlural=one": "# 个文件",
+            "countPlural=other": "# 个文件"
apps/mail/messages/fa.json (1)

165-175: LGTM - Consistent pluralization format migration.

The pluralization format changes match the pattern seen in other locale files (like Hindi), maintaining consistency across the localization system. The text content and plural category mappings are preserved correctly.

This follows the same migration pattern verified in the Hindi locale file. The structured format should work correctly with the Paraglide framework.

Also applies to: 176-186, 249-259, 312-322

🧹 Nitpick comments (15)
apps/mail/app/(auth)/login/error-message.tsx (1)

5-5: LGTM with type safety consideration

The localization migration is consistent with the broader refactor. However, the dynamic key construction using template literals (m[\errorMessages.${error}`]()`) may not provide compile-time type safety verification.

Consider using a helper function for better type safety:

+const getErrorMessage = (error: string) => {
+  const key = `errorMessages.${error}` as keyof typeof m;
+  return m[key]?.() || 'Unknown error';
+};

-toast.error(m[`errorMessages.${error}`]());
+toast.error(getErrorMessage(error));

Also applies to: 25-25, 38-38

apps/mail/messages/nl.json (1)

1-1: Consider adding schema declaration for consistency.

The English localization file includes a $schema declaration, but this Dutch file doesn't. For consistency across all locale files and to ensure proper validation, consider adding the same schema declaration.

 {
+  "$schema": "https://inlang.com/schema/inlang-message-format",
   "common": {
apps/mail/messages/tr.json (1)

249-259: Minor wording / placeholder nit-pick.

"# not" (singular) and "# notlar" (other) keep the English stem not instead of notnot lar.
If the intent is Turkish, consider:

-            "countPlural=one": "# not",
-            "countPlural=other": "# notlar"
+            "countPlural=one": "# not",
+            "countPlural=other": "# not"

(Or translate notenot/notlar consistently.)

apps/mail/messages/lv.json (1)

249-259: Tiny style nit – zero form.

"Pievienot piezīmes" (Add notes) is an action phrase while the other forms are counters.
If this key is shown as a count, prefer something like "0 piezīmes".

apps/mail/messages/zh_TW.json (1)

249-259: Zero form wording.

"添加筆記" is an imperative, whereas other forms are counters.
If the UI shows a count, consider "0 則筆記".

apps/mail/messages/pt.json (1)

249-259: Minor localisation polish.

"# nota" vs "# notas" is fine; maybe drop the leading space before the number if not required by rendering engine.

apps/mail/messages/ca.json (1)

165-175: Include # placeholder for attachmentCount

Other counters in this file embed the number (e.g. # nota). Omitting it here breaks UX consistency.

-            "countPlural=0": "adjunts",
-            "countPlural=one": "adjunt",
-            "countPlural=other": "adjunts"
+            "countPlural=0": "0 adjunts",
+            "countPlural=one": "# adjunt",
+            "countPlural=other": "# adjunts"
apps/mail/messages/zh_CN.json (3)

165-175: Add number before “个附件”

Chinese usually shows the numeral: “3 个附件”. Without #, the count is lost.

-            "countPlural=0": "附件",
-            "countPlural=one": "个附件",
-            "countPlural=other": "个附件"
+            "countPlural=0": "0 个附件",
+            "countPlural=one": "# 个附件",
+            "countPlural=other": "# 个附件"

249-259: noteCount: spacing – add ideographic space or normal space

For readability in Chinese, add a space (or \u3000) between number and noun.

-            "countPlural=one": "# 条笔记",
-            "countPlural=other": "# 条笔记"
+            "countPlural=one": "# 条笔记",
+            "countPlural=other": "# 条笔记"

(If using typography guidelines, consider “# 条笔记” with a thin space.)


312-322: replies: mirror numeric placeholder spacing

Same recommendation as above applies to replies: “# 条回复”.

apps/mail/components/mail/mail-list.tsx (1)

702-710: Consider extracting the date formatting logic.

While the translation migration is correct, the conditional rendering with draft.rawMessage?.internalDate could be simplified for better readability.

Consider refactoring for improved readability:

-                {draft.rawMessage?.internalDate && (
-                  <p
-                    className={cn(
-                      'text-muted-foreground text-nowrap text-xs font-normal opacity-70 transition-opacity group-hover:opacity-100 dark:text-[#8C8C8C]',
-                    )}
-                  >
-                    {formatDate(Number(draft.rawMessage?.internalDate))}
-                  </p>
-                )}
+                {draft.rawMessage?.internalDate ? (
+                  <p
+                    className={cn(
+                      'text-muted-foreground text-nowrap text-xs font-normal opacity-70 transition-opacity group-hover:opacity-100 dark:text-[#8C8C8C]',
+                    )}
+                  >
+                    {formatDate(Number(draft.rawMessage.internalDate))}
+                  </p>
+                ) : null}
apps/mail/project.inlang/settings.json (1)

27-28: Consider CDN dependency implications

The plugins are loaded from CDN which could impact build reliability if the CDN is unavailable. Consider hosting these plugins locally or using a package manager dependency for better build stability.

apps/mail/config/navigation.ts (1)

47-47: Update outdated comment.

The comment mentions "message key" but the implementation now uses direct function calls. Please update this comment to reflect the current approach.

-// ! items title has to be a message key (check messages/en.json)
+// ! items title should use message function calls from @/paraglide/messages
apps/mail/app/(routes)/mail/[folder]/page.tsx (1)

25-25: Consider UX impact of removing loading state.

Changing the initial state from null to true and removing loading state management simplifies the code but may impact user experience. Users won't see any loading indication when validating folders.

Consider if a loading state would improve UX, especially for slower network conditions:

-const [isLabelValid, setIsLabelValid] = useState<boolean | null>(true);
+const [isLabelValid, setIsLabelValid] = useState<boolean | null>(null);

And add back loading state handling if appropriate for the user experience.

apps/mail/components/mail/mail-display.tsx (1)

891-896: Simplify the email copying logic.

The function has redundant checks and unnecessary complexity. The second parameter in writeText() is also redundant since personEmail is already validated.

const handleCopySenderEmail = useCallback(async (personEmail: string) => {
-  if (!personEmail) return;
-
-  await navigator.clipboard.writeText(personEmail || '');
+  if (!personEmail) return;
+  
+  await navigator.clipboard.writeText(personEmail);
  toast.success('Email copied to clipboard');
}, []);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 59c18be and f5ed25d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (79)
  • apps/mail/app/(auth)/login/error-message.tsx (3 hunks)
  • apps/mail/app/(routes)/mail/[folder]/page.tsx (2 hunks)
  • apps/mail/app/(routes)/mail/page.tsx (1 hunks)
  • apps/mail/app/(routes)/settings/[...settings]/page.tsx (2 hunks)
  • apps/mail/app/(routes)/settings/appearance/page.tsx (6 hunks)
  • apps/mail/app/(routes)/settings/connections/page.tsx (9 hunks)
  • apps/mail/app/(routes)/settings/danger-zone/page.tsx (5 hunks)
  • apps/mail/app/(routes)/settings/general/page.tsx (13 hunks)
  • apps/mail/app/(routes)/settings/labels/page.tsx (6 hunks)
  • apps/mail/app/(routes)/settings/privacy/page.tsx (6 hunks)
  • apps/mail/app/(routes)/settings/security/page.tsx (4 hunks)
  • apps/mail/app/(routes)/settings/shortcuts/hotkey-recorder.tsx (2 hunks)
  • apps/mail/app/(routes)/settings/shortcuts/page.tsx (3 hunks)
  • apps/mail/app/(routes)/settings/signatures/page.tsx (0 hunks)
  • apps/mail/app/entry.server.tsx (1 hunks)
  • apps/mail/app/root.tsx (5 hunks)
  • apps/mail/components/connection/add.tsx (3 hunks)
  • apps/mail/components/context/command-palette-context.tsx (6 hunks)
  • apps/mail/components/context/label-sidebar-context.tsx (4 hunks)
  • apps/mail/components/context/thread-context.tsx (13 hunks)
  • apps/mail/components/create/create-email.tsx (3 hunks)
  • apps/mail/components/create/editor.tsx (11 hunks)
  • apps/mail/components/create/image-compression-settings.tsx (4 hunks)
  • apps/mail/components/labels/label-dialog.tsx (6 hunks)
  • apps/mail/components/mail/mail-display.tsx (23 hunks)
  • apps/mail/components/mail/mail-iframe.tsx (3 hunks)
  • apps/mail/components/mail/mail-list.tsx (8 hunks)
  • apps/mail/components/mail/mail.tsx (8 hunks)
  • apps/mail/components/mail/nav-main.tsx (1 hunks)
  • apps/mail/components/mail/note-panel.tsx (28 hunks)
  • apps/mail/components/mail/reply-composer.tsx (3 hunks)
  • apps/mail/components/mail/thread-display.tsx (10 hunks)
  • apps/mail/components/theme/theme-switcher.tsx (2 hunks)
  • apps/mail/components/ui/app-sidebar.tsx (2 hunks)
  • apps/mail/components/ui/nav-main.tsx (6 hunks)
  • apps/mail/components/ui/nav-user.tsx (9 hunks)
  • apps/mail/config/navigation.ts (6 hunks)
  • apps/mail/hooks/driver/use-delete.ts (2 hunks)
  • apps/mail/hooks/use-notes.tsx (2 hunks)
  • apps/mail/hooks/use-optimistic-actions.ts (4 hunks)
  • apps/mail/i18n/config.ts (0 hunks)
  • apps/mail/i18n/request.ts (0 hunks)
  • apps/mail/lib/hotkeys/mail-list-hotkeys.tsx (9 hunks)
  • apps/mail/lib/notes-utils.ts (4 hunks)
  • apps/mail/lib/utils.ts (3 hunks)
  • apps/mail/messages/ar.json (4 hunks)
  • apps/mail/messages/ca.json (4 hunks)
  • apps/mail/messages/cs.json (4 hunks)
  • apps/mail/messages/de.json (5 hunks)
  • apps/mail/messages/en.json (6 hunks)
  • apps/mail/messages/es.json (4 hunks)
  • apps/mail/messages/fa.json (4 hunks)
  • apps/mail/messages/fr.json (4 hunks)
  • apps/mail/messages/hi.json (4 hunks)
  • apps/mail/messages/hu.json (4 hunks)
  • apps/mail/messages/ja.json (2 hunks)
  • apps/mail/messages/ko.json (3 hunks)
  • apps/mail/messages/lv.json (4 hunks)
  • apps/mail/messages/nl.json (4 hunks)
  • apps/mail/messages/pl.json (4 hunks)
  • apps/mail/messages/pt.json (4 hunks)
  • apps/mail/messages/ru.json (4 hunks)
  • apps/mail/messages/tr.json (4 hunks)
  • apps/mail/messages/vi.json (4 hunks)
  • apps/mail/messages/zh_CN.json (5 hunks)
  • apps/mail/messages/zh_TW.json (4 hunks)
  • apps/mail/package.json (3 hunks)
  • apps/mail/project.inlang/.gitignore (1 hunks)
  • apps/mail/project.inlang/project_id (1 hunks)
  • apps/mail/project.inlang/settings.json (1 hunks)
  • apps/mail/providers/query-provider.tsx (4 hunks)
  • apps/mail/providers/server-providers.tsx (1 hunks)
  • apps/mail/react-router.config.ts (1 hunks)
  • apps/mail/vite.config.ts (3 hunks)
  • apps/mail/worker.ts (0 hunks)
  • apps/mail/wrangler.jsonc (1 hunks)
  • apps/server/src/trpc/routes/cookies.ts (1 hunks)
  • apps/server/wrangler.jsonc (1 hunks)
  • i18n.json (1 hunks)
💤 Files with no reviewable changes (4)
  • apps/mail/i18n/request.ts
  • apps/mail/worker.ts
  • apps/mail/i18n/config.ts
  • apps/mail/app/(routes)/settings/signatures/page.tsx
🧰 Additional context used
🧠 Learnings (47)
apps/mail/react-router.config.ts (3)
Learnt from: adiologydev
PR: Mail-0/Zero#871
File: docker-compose.yaml:2-21
Timestamp: 2025-05-04T23:21:21.388Z
Learning: To completely disable SSG (Static Site Generation) in Next.js projects for Docker deployments, use 'force-dynamic' for App Router or getServerSideProps for Pages Router in all pages, and set output: 'standalone' in next.config.ts. This allows all environment variables to be passed at runtime instead of build time, improving security for sensitive values.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.709Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
apps/mail/components/mail/nav-main.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/app/entry.server.tsx (3)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.709Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: adiologydev
PR: Mail-0/Zero#871
File: docker-compose.yaml:2-21
Timestamp: 2025-05-04T23:21:21.388Z
Learning: To completely disable SSG (Static Site Generation) in Next.js projects for Docker deployments, use 'force-dynamic' for App Router or getServerSideProps for Pages Router in all pages, and set output: 'standalone' in next.config.ts. This allows all environment variables to be passed at runtime instead of build time, improving security for sensitive values.
apps/mail/app/(routes)/settings/[...settings]/page.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/app/(routes)/settings/shortcuts/hotkey-recorder.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/app/(routes)/settings/labels/page.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: danteissaias
PR: Mail-0/Zero#902
File: apps/mail/components/connection/add.tsx:77-77
Timestamp: 2025-05-07T16:55:46.513Z
Learning: For the "Upgrade" link in AddConnectionDialog, using a proper <button> element instead of a <span> with onClick is recognized as an accessibility improvement but was deferred as out of scope in PR #902 (CSS variables PR).
apps/mail/app/(routes)/settings/appearance/page.tsx (3)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: snehendu098
PR: Mail-0/Zero#1323
File: apps/mail/lib/themes/theme-utils.ts:318-318
Timestamp: 2025-06-24T06:22:58.753Z
Learning: In the Mail-0/Zero theme system (apps/mail/lib/themes/theme-utils.ts), when color themes are being applied, all color values come in HSL format, so there's no need for additional format validation when converting colors with hslToHex().
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/app/(routes)/settings/connections/page.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: danteissaias
PR: Mail-0/Zero#902
File: apps/mail/components/connection/add.tsx:77-77
Timestamp: 2025-05-07T16:55:46.513Z
Learning: For the "Upgrade" link in AddConnectionDialog, using a proper <button> element instead of a <span> with onClick is recognized as an accessibility improvement but was deferred as out of scope in PR #902 (CSS variables PR).
apps/server/wrangler.jsonc (2)
Learnt from: adiologydev
PR: Mail-0/Zero#871
File: docker-compose.yaml:2-21
Timestamp: 2025-05-04T23:13:26.825Z
Learning: Next.js requires certain environment variables during static site generation at build time, particularly those with the NEXT_PUBLIC_ prefix. When using Docker, these should be passed as build args, while sensitive values like API keys and secrets should ideally only be passed at runtime as environment variables.
Learnt from: txj-xyz
PR: Mail-0/Zero#131
File: Dockerfile:31-41
Timestamp: 2025-03-14T22:15:10.146Z
Learning: For Docker configurations in this project, environment variables should be managed using .env files rather than hardcoding them in the Dockerfile, especially for development environments.
apps/mail/components/create/create-email.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/components/mail/reply-composer.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/components/context/label-sidebar-context.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/labels/label-dialog.tsx (3)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1354
File: apps/mail/components/ui/prompts-dialog.tsx:85-88
Timestamp: 2025-06-20T05:03:16.944Z
Learning: In React Hook Form, avoid using useEffect for form state synchronization when the values prop can handle reactive updates automatically. The values prop is specifically designed for this purpose and is more optimal than manual useEffect-based synchronization.
Learnt from: danteissaias
PR: Mail-0/Zero#902
File: apps/mail/components/connection/add.tsx:77-77
Timestamp: 2025-05-07T16:55:46.513Z
Learning: For the "Upgrade" link in AddConnectionDialog, using a proper <button> element instead of a <span> with onClick is recognized as an accessibility improvement but was deferred as out of scope in PR #902 (CSS variables PR).
apps/mail/hooks/driver/use-delete.ts (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.709Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
apps/mail/app/(auth)/login/error-message.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/app/(routes)/settings/security/page.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1354
File: apps/mail/components/ui/prompts-dialog.tsx:85-88
Timestamp: 2025-06-20T05:03:16.944Z
Learning: In React Hook Form, avoid using useEffect for form state synchronization when the values prop can handle reactive updates automatically. The values prop is specifically designed for this purpose and is more optimal than manual useEffect-based synchronization.
apps/mail/app/(routes)/settings/shortcuts/page.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/hooks/use-notes.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/ui/app-sidebar.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/components/mail/mail-iframe.tsx (5)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.709Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: danteissaias
PR: Mail-0/Zero#618
File: apps/mail/components/mail/mail-iframe.tsx:0-0
Timestamp: 2025-04-07T20:46:04.726Z
Learning: In the Zero mail application, the "Trust Sender" button for external images is only shown when a sender is not already in the trusted senders list (`settings?.trustedSenders`). This is controlled by the condition `!imagesEnabled && !settings?.externalImages`, where `imagesEnabled` is based on `isTrustedSender || settings?.externalImages` and `isTrustedSender` is determined by `settings?.trustedSenders?.includes(senderEmail)`. This design pattern prevents duplicate entries in the trusted senders list.
Learnt from: danteissaias
PR: Mail-0/Zero#618
File: apps/mail/components/mail/mail-iframe.tsx:102-102
Timestamp: 2025-04-07T20:48:48.213Z
Learning: In the Zero mail application, when implementing the "Trust Sender" feature, the banner should disappear immediately when a user clicks the "Trust Sender" button without showing a loading state. This is achieved by setting `setImagesEnabled(true)` at the beginning of the `onTrustSender` function, providing immediate visual feedback while the backend operation continues asynchronously.
apps/mail/app/(routes)/settings/privacy/page.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: danteissaias
PR: Mail-0/Zero#618
File: apps/mail/components/mail/mail-iframe.tsx:0-0
Timestamp: 2025-04-07T20:46:04.726Z
Learning: In the Zero mail application, the "Trust Sender" button for external images is only shown when a sender is not already in the trusted senders list (`settings?.trustedSenders`). This is controlled by the condition `!imagesEnabled && !settings?.externalImages`, where `imagesEnabled` is based on `isTrustedSender || settings?.externalImages` and `isTrustedSender` is determined by `settings?.trustedSenders?.includes(senderEmail)`. This design pattern prevents duplicate entries in the trusted senders list.
apps/mail/components/theme/theme-switcher.tsx (3)
Learnt from: snehendu098
PR: Mail-0/Zero#1323
File: apps/mail/lib/themes/theme-utils.ts:318-318
Timestamp: 2025-06-24T06:22:58.753Z
Learning: In the Mail-0/Zero theme system (apps/mail/lib/themes/theme-utils.ts), when color themes are being applied, all color values come in HSL format, so there's no need for additional format validation when converting colors with hslToHex().
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/connection/add.tsx (2)
Learnt from: danteissaias
PR: Mail-0/Zero#902
File: apps/mail/components/connection/add.tsx:77-77
Timestamp: 2025-05-07T16:55:46.513Z
Learning: For the "Upgrade" link in AddConnectionDialog, using a proper <button> element instead of a <span> with onClick is recognized as an accessibility improvement but was deferred as out of scope in PR #902 (CSS variables PR).
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/create/image-compression-settings.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/create/editor.tsx (4)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: yaraslau-klimuk
PR: Mail-0/Zero#604
File: apps/mail/locales/en.json:366-389
Timestamp: 2025-04-06T18:28:21.659Z
Learning: The translation file for the editor's menu bar already includes an "orderedList" key with the value "Ordered List" as part of PR #604.
Learnt from: danteissaias
PR: Mail-0/Zero#902
File: apps/mail/components/connection/add.tsx:77-77
Timestamp: 2025-05-07T16:55:46.513Z
Learning: For the "Upgrade" link in AddConnectionDialog, using a proper <button> element instead of a <span> with onClick is recognized as an accessibility improvement but was deferred as out of scope in PR #902 (CSS variables PR).
apps/mail/components/mail/thread-display.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/lib/hotkeys/mail-list-hotkeys.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/ui/nav-main.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/providers/server-providers.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/config/navigation.ts (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/vite.config.ts (1)
Learnt from: adiologydev
PR: Mail-0/Zero#871
File: docker-compose.yaml:2-21
Timestamp: 2025-05-04T23:21:21.388Z
Learning: To completely disable SSG (Static Site Generation) in Next.js projects for Docker deployments, use 'force-dynamic' for App Router or getServerSideProps for Pages Router in all pages, and set output: 'standalone' in next.config.ts. This allows all environment variables to be passed at runtime instead of build time, improving security for sensitive values.
apps/mail/components/context/thread-context.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/hooks/use-optimistic-actions.ts (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/app/(routes)/settings/danger-zone/page.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1354
File: apps/mail/components/ui/prompts-dialog.tsx:85-88
Timestamp: 2025-06-20T05:03:16.944Z
Learning: In React Hook Form, avoid using useEffect for form state synchronization when the values prop can handle reactive updates automatically. The values prop is specifically designed for this purpose and is more optimal than manual useEffect-based synchronization.
apps/mail/app/(routes)/mail/page.tsx (3)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.709Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/lib/notes-utils.ts (3)
Learnt from: snehendu098
PR: Mail-0/Zero#1323
File: apps/mail/lib/themes/theme-utils.ts:318-318
Timestamp: 2025-06-24T06:22:58.753Z
Learning: In the Mail-0/Zero theme system (apps/mail/lib/themes/theme-utils.ts), when color themes are being applied, all color values come in HSL format, so there's no need for additional format validation when converting colors with hslToHex().
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: danteissaias
PR: Mail-0/Zero#902
File: apps/mail/components/mail/note-panel.tsx:511-513
Timestamp: 2025-05-07T16:45:40.468Z
Learning: The amber color for notes (text-amber-500, fill-amber-200, etc.) is intentionally fixed and should not be converted to theme variables, as it serves as a recognizable visual metaphor for sticky notes.
apps/mail/components/mail/mail-list.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/app/(routes)/mail/[folder]/page.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/components/mail/note-panel.tsx (3)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: danteissaias
PR: Mail-0/Zero#902
File: apps/mail/components/connection/add.tsx:77-77
Timestamp: 2025-05-07T16:55:46.513Z
Learning: For the "Upgrade" link in AddConnectionDialog, using a proper <button> element instead of a <span> with onClick is recognized as an accessibility improvement but was deferred as out of scope in PR #902 (CSS variables PR).
apps/mail/package.json (2)
Learnt from: adiologydev
PR: Mail-0/Zero#871
File: docker-compose.yaml:2-21
Timestamp: 2025-05-04T23:13:26.825Z
Learning: Next.js requires certain environment variables during static site generation at build time, particularly those with the NEXT_PUBLIC_ prefix. When using Docker, these should be passed as build args, while sensitive values like API keys and secrets should ideally only be passed at runtime as environment variables.
Learnt from: adiologydev
PR: Mail-0/Zero#871
File: docker-compose.yaml:2-21
Timestamp: 2025-05-04T23:21:21.388Z
Learning: To completely disable SSG (Static Site Generation) in Next.js projects for Docker deployments, use 'force-dynamic' for App Router or getServerSideProps for Pages Router in all pages, and set output: 'standalone' in next.config.ts. This allows all environment variables to be passed at runtime instead of build time, improving security for sensitive values.
apps/mail/app/root.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.709Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
apps/mail/components/mail/mail.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/lib/utils.ts (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: snehendu098
PR: Mail-0/Zero#1323
File: apps/mail/lib/themes/theme-utils.ts:318-318
Timestamp: 2025-06-24T06:22:58.753Z
Learning: In the Mail-0/Zero theme system (apps/mail/lib/themes/theme-utils.ts), when color themes are being applied, all color values come in HSL format, so there's no need for additional format validation when converting colors with hslToHex().
apps/mail/app/(routes)/settings/general/page.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/mail/mail-display.tsx (4)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: danteissaias
PR: Mail-0/Zero#458
File: apps/mail/lib/email-utils.ts:126-131
Timestamp: 2025-03-16T23:14:09.209Z
Learning: When working with mailto URLs in JavaScript/TypeScript, the `url.pathname` property correctly extracts the email address from a mailto URL (e.g., for "mailto:test@example.com?subject=Test", `url.pathname` will be "test@example.com").
Learnt from: danteissaias
PR: Mail-0/Zero#618
File: apps/mail/components/mail/mail-iframe.tsx:12-12
Timestamp: 2025-04-07T20:46:11.697Z
Learning: In the Mail-0/Zero application, sender emails are guaranteed to be non-empty when passed to components that handle them, making additional empty string validation unnecessary.
apps/mail/components/ui/nav-user.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/context/command-palette-context.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
🧬 Code Graph Analysis (10)
apps/mail/components/context/label-sidebar-context.tsx (3)
apps/mail/hooks/use-labels.ts (1)
  • useLabels (5-13)
apps/mail/components/ui/dialog.tsx (5)
  • DialogTitle (115-115)
  • DialogDescription (116-116)
  • DialogHeader (113-113)
  • DialogFooter (114-114)
  • DialogClose (110-110)
apps/mail/components/ui/button.tsx (1)
  • Button (71-71)
apps/mail/components/connection/add.tsx (2)
apps/mail/components/ui/button.tsx (1)
  • Button (71-71)
apps/mail/components/ui/dialog.tsx (5)
  • DialogTrigger (111-111)
  • DialogContent (112-112)
  • DialogHeader (113-113)
  • DialogTitle (115-115)
  • DialogDescription (116-116)
apps/mail/components/create/image-compression-settings.tsx (1)
apps/mail/lib/image-compression.ts (1)
  • ImageQuality (1-1)
apps/mail/providers/server-providers.tsx (1)
apps/mail/providers/query-provider.tsx (1)
  • QueryProvider (106-142)
apps/mail/components/context/thread-context.tsx (2)
apps/mail/components/icons/icons.tsx (6)
  • Reply (852-867)
  • ReplyAll (869-889)
  • Inbox (292-309)
  • Archive (391-413)
  • ArchiveX (973-989)
  • ExclamationCircle (415-432)
apps/mail/lib/utils.ts (1)
  • LABELS (19-26)
apps/mail/app/(routes)/mail/page.tsx (7)
apps/mail/app/(routes)/mail/[folder]/page.tsx (1)
  • clientLoader (11-20)
apps/mail/app/(routes)/mail/create/page.tsx (1)
  • clientLoader (4-18)
apps/mail/app/(routes)/settings/page.tsx (1)
  • clientLoader (3-5)
apps/mail/app/(routes)/mail/compose/page.tsx (1)
  • clientLoader (13-31)
apps/mail/app/meta-files/not-found.ts (1)
  • clientLoader (1-3)
apps/mail/app/page.tsx (1)
  • clientLoader (6-10)
apps/mail/app/mailto-handler.ts (1)
  • clientLoader (249-284)
apps/mail/lib/notes-utils.ts (1)
apps/mail/lib/utils.ts (1)
  • formatDate (119-170)
apps/mail/app/(routes)/mail/[folder]/page.tsx (1)
apps/mail/hooks/use-labels.ts (1)
  • useLabels (5-13)
apps/mail/app/root.tsx (1)
apps/mail/providers/server-providers.tsx (1)
  • ServerProviders (5-11)
apps/mail/components/ui/nav-user.tsx (1)
apps/mail/lib/utils.ts (1)
  • cn (51-51)
🪛 GitHub Actions: autofix.ci
apps/mail/package.json

[error] 1-1: pnpm install failed due to outdated lockfile. The pnpm-lock.yaml is not up to date with package.json. Dependency 'use-intl@^4.1.0' was removed but lockfile is frozen. Run 'pnpm install --no-frozen-lockfile' to fix.

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Cursor BugBot
🔇 Additional comments (127)
apps/server/wrangler.jsonc (1)

118-121: DROP_AGENT_TABLES = true – double-check safety
Auto-dropping tables on every deploy is convenient for dev, but a single mis-targeted publish can wipe staging/production data.
Consider guarding the flag with an explicit NODE_ENV === "development" check inside your migration script or just default to false and enable via wrangler.dev.toml.

apps/mail/wrangler.jsonc (2)

8-12: Asset directory hard-coded – confirm build output path
"directory": "./build/client/" assumes Vite outputs there. The default is dist.
If vite.config.ts’s build.outDir wasn’t updated, this will 404 every static asset in production.


22-26: Environment name additions LGTM
Explicitly naming each environment (zero-staging, etc.) improves dashboard readability and avoids accidental deployments to the wrong worker.

apps/mail/react-router.config.ts (1)

4-5: SSR disabled – make sure no server-only features remain
Turning off SSR eliminates access to request headers/cookies on first paint and can hurt SEO. Verify that:

  1. Auth still works without reading cookies server-side.
  2. Any dynamic meta tags are generated client-side.
  3. The worker entry (apps/mail/worker.ts) removal doesn’t break Cloudflare routing.

Re-enable (ssr: true) or add fallbacks if needed.

apps/mail/project.inlang/project_id (1)

1-1: Project ID committed – confirm it’s non-secret
Looks like a public Inlang identifier; fine to version-control as long as it can be regenerated if leaked.

apps/mail/project.inlang/.gitignore (1)

1-1: 👍 Cache ignored correctly
Ignoring the cache directory prevents large generated artefacts from polluting the repo.

apps/mail/app/entry.server.tsx (1)

1-2: LGTM: Appropriate migration to browser-compatible rendering.

The change from react-dom/server to react-dom/server.browser aligns with the broader migration away from SSR to client-side rendering. The TypeScript expect-error directive is a reasonable temporary solution for the missing typings in the ESM browser build.

apps/mail/components/mail/reply-composer.tsx (2)

14-14: LGTM: Correct migration to Paraglide message object.

The import change from useTranslations to the Paraglide message object follows the established migration pattern.


214-217: LGTM: Toast messages properly migrated.

The toast message calls have been correctly updated to use the new message object syntax with appropriate namespacing under pages.createEmail.

i18n.json (1)

31-31: Localization files moved successfully

All locale JSON files have been verified under apps/mail/messages/. No further action is required—change is approved.

apps/mail/app/(routes)/settings/[...settings]/page.tsx (2)

6-6: LGTM: Consistent migration to Paraglide imports.

The import change follows the established migration pattern from useTranslations to the Paraglide message object.


29-29: LGTM: Error message properly migrated.

The error message has been correctly updated to use the new message object syntax with appropriate namespacing under pages.error.

apps/mail/hooks/use-notes.tsx (1)

5-5: Clean localization migration from use-intl to Paraglide.

The migration correctly replaces the useTranslations hook with direct message imports. The translation call is properly updated to use the new m['key']() pattern.

Also applies to: 21-21

apps/mail/components/ui/app-sidebar.tsx (1)

45-45: Consistent localization migration maintains component functionality.

The migration properly updates the compose button's text translation while preserving all existing component logic and behavior.

Also applies to: 208-208

apps/mail/components/create/create-email.tsx (1)

15-15: Proper localization migration for success message.

The toast message translation is correctly updated to use the new message object pattern while maintaining the email sending workflow.

Also applies to: 128-128

apps/mail/hooks/driver/use-delete.ts (1)

7-7: Comprehensive toast message migration in delete hook.

All toast promise states (loading, success, error) are correctly updated to use the new localization pattern while preserving the delete functionality.

Also applies to: 29-30, 34-34

apps/mail/app/(routes)/settings/labels/page.tsx (2)

34-34: LGTM: Clean localization migration

The import of the message object m from @/paraglide/messages follows the established pattern for the Paraglide framework migration.


57-59: LGTM: Consistent translation call updates

All translation calls have been properly migrated from t('key') to m['key']() pattern, maintaining the same message keys while adopting the new Paraglide localization system.

Also applies to: 66-68, 83-84, 90-90, 116-116, 150-150, 165-165

apps/mail/components/labels/label-dialog.tsx (2)

25-25: LGTM: Consistent localization import

The message object import follows the established migration pattern.


97-97: LGTM: Proper translation call migration

All translation calls have been correctly updated to use the new message object pattern, including the conditional expression in the dialog title.

Also applies to: 116-116, 125-125, 153-153, 156-156

apps/mail/app/(routes)/settings/appearance/page.tsx (3)

24-24: LGTM: Consistent localization import

The message object import follows the established migration pattern.


82-83: LGTM: Standard translation call updates

All standard translation calls have been properly migrated to the new message object pattern.

Also applies to: 98-99, 102-102, 116-116, 138-138, 144-144, 150-150


130-130: LGTM: Correct dynamic message key usage

The dynamic message key construction using template literals and TypeScript casting (m[\common.themes.${theme}` as MessageKey]()`) follows the proper pattern for variable message keys in the Paraglide system.

apps/mail/app/(routes)/settings/connections/page.tsx (2)

25-25: LGTM: Consistent localization import

The message object import follows the established migration pattern.


46-46: LGTM: Comprehensive translation call migration

All translation calls across toast messages, dialog content, badges, and button labels have been properly migrated to the new message object pattern.

Also applies to: 50-50, 59-60, 144-144, 158-158, 175-175, 178-178, 184-184, 189-189, 211-211, 223-223

apps/mail/components/mail/mail-iframe.tsx (2)

12-12: LGTM: Consistent localization import

The message object import follows the established migration pattern.


146-146: LGTM: Image-related translation call migration

All translation calls for image handling UI elements have been properly migrated to the new message object pattern, completing the localization system migration.

Also applies to: 152-153, 156-156

apps/mail/app/(routes)/settings/privacy/page.tsx (1)

21-21: Verify message keys in @/paraglide/messages

The localization migration is consistent, but please confirm that every key used in apps/mail/app/(routes)/settings/privacy/page.tsx is defined in your messages export to avoid runtime errors.

• Affected lines: 21, 58–59, 72–73, 76, 90, 93, 110, 113, 133
• File: apps/mail/app/(routes)/settings/privacy/page.tsx

Use this script from the repo root to check for missing keys (it performs a literal search and avoids regex-escape issues):

#!/usr/bin/env bash
# Verify that all message keys used in the privacy page exist under paraglide/messages

keys=(
  "common.settings.saved"
  "common.settings.failedToSave"
  "pages.settings.privacy.title"
  "pages.settings.privacy.description"
  "common.actions.saving"
  "common.actions.saveChanges"
  "pages.settings.privacy.externalImages"
  "pages.settings.privacy.externalImagesDescription"
  "pages.settings.privacy.trustedSenders"
  "pages.settings.privacy.trustedSendersDescription"
  "common.actions.remove"
)

echo "Checking message keys in paraglide/…"
for key in "${keys[@]}"; do
  if ! grep -R -F "\"$key\"" paraglide/ >/dev/null; then
    echo "⚠️  Missing key: $key"
  fi
done

Run this and add any missing definitions to your @/paraglide/messages export.

apps/mail/components/theme/theme-switcher.tsx (1)

12-12: Theme localization migration is well-implemented.

The migration from useTranslations to direct message object access is consistent and correctly handles both static keys and dynamic key generation for theme names.

The dynamic key access pattern m[\common.themes.${theme}`]()` on line 61 is particularly well-done, maintaining the flexibility to handle different theme values while using the new localization system.

Also applies to: 61-61, 69-69, 75-75, 81-81

apps/mail/app/(routes)/settings/shortcuts/page.tsx (1)

10-10: Complex shortcut labeling logic correctly preserved during migration.

The localization migration maintains the sophisticated conditional logic for determining whether to display custom category names or localized action labels. The type casting to MessageKey helps maintain some type safety in the new system.

The fallback logic on lines 76-79 elegantly handles cases where category settings are available versus using default localized action names, ensuring a smooth user experience regardless of configuration state.

Also applies to: 26-27, 76-79

apps/mail/components/create/editor.tsx (1)

55-55: LGTM: Clean migration to Paraglide localization

The localization migration is well-executed with consistent patterns throughout the MenuBar component. All translation calls have been properly updated from the useTranslations hook to direct message object calls.

Also applies to: 196-196, 212-212, 229-230, 245-245, 260-260, 280-280, 295-295, 305-306, 323-323, 326-327

apps/mail/vite.config.ts (2)

1-1: LGTM: Proper Paraglide plugin integration

The Vite configuration correctly integrates the Paraglide plugin with appropriate settings for the localization framework migration.

Also applies to: 43-47


60-64: Verify SSR dependency optimization for heavy editor packages

We’ve confirmed extensive use of both novel and @tiptap/extension-placeholder across your editor components, but the SSR optimizeDeps block in apps/mail/vite.config.ts (lines ~60–64) is commented out. Please ensure:

• If you’re running SSR builds (e.g., Cloudflare Workers or similar), re-enable this block to pre-bundle these large dependencies and avoid cold-start or rebuild slowdowns.
• If you’ve switched to a purely client‐side setup and no longer need SSR, remove the commented ssr.optimizeDeps section to clean up the config.

File needing attention:
• apps/mail/vite.config.ts (around lines 60–64)

apps/mail/lib/hotkeys/mail-list-hotkeys.tsx (1)

13-13: LGTM: Consistent localization migration with proper dependency updates

The migration to Paraglide is well-executed throughout the hotkeys implementation. The bracket notation approach (m['common.mail.noEmailsToSelect']()) is appropriate for keys containing dots, and dependency arrays have been properly updated.

Also applies to: 61-61, 73-73, 88-88, 103-103, 118-118, 133-133, 148-148, 163-163

apps/mail/messages/ko.json (1)

229-239: LGTM: Enhanced pluralization format for Paraglide

The pluralization format has been properly updated to use Paraglide's structured approach with explicit declarations and selectors. This provides better type safety and clarity compared to the previous ICU MessageFormat strings while preserving the Korean translations.

Also applies to: 292-302

apps/mail/app/(routes)/settings/security/page.tsx (1)

13-13: LGTM - Clean localization migration to Paraglide framework.

The migration from useTranslations hook to direct message object imports follows the correct pattern. All translation calls have been consistently updated from t('key') to m['key']() while maintaining the same translation keys and logic.

Also applies to: 48-55, 69-73, 88-92

apps/mail/messages/ja.json (1)

229-239: LGTM - Correct pluralization format migration for Paraglide.

The pluralization format has been properly updated from ICU MessageFormat to Paraglide's structured object format. The new format correctly declares the input variable count and plural variable countPlural, with appropriate plural categories mapped to the same Japanese translations.

apps/mail/components/mail/thread-display.tsx (1)

44-44: LGTM - Consistent localization migration with one potential logic issue.

The migration from useTranslations to direct message imports is correctly implemented across all UI elements. All translation calls follow the proper m['key']() pattern.

Also applies to: 821-827, 890-890, 914-916, 931-931, 948-948, 973-1002

apps/mail/components/context/label-sidebar-context.tsx (1)

20-20: LGTM - Correct localization migration for label context menu.

The migration properly converts all translation calls from the useTranslations hook to direct message object usage. The dialog confirmation flow and context menu labels are correctly updated while maintaining the same functionality.

Also applies to: 49-49, 77-77, 86-89, 93-98

apps/mail/providers/server-providers.tsx (1)

5-11: LGTM - Correct simplification aligned with localization migration.

The removal of internationalization props and IntlProvider wrapper correctly reflects the migration to Paraglide framework where locale and messages are handled at runtime rather than being passed down from server loaders. The simplified component signature maintains its core functionality while removing unnecessary complexity.

apps/mail/messages/fr.json (1)

165-322: LGTM! French pluralization rules are correctly implemented.

The migration to the structured pluralization format correctly implements French plural forms:

  • 0 items → plural form
  • 1 item → singular form
  • 2+ items → plural form

This change aligns with the Paraglide framework requirements.

apps/mail/package.json (1)

1-143: Lockfile update failed due to postinstall permission error

The pnpm install --no-frozen-lockfile step is exiting with an EACCES when running postinstall hooks, so the lockfile isn’t actually being updated. To fix this:

  • Run the install while skipping lifecycle scripts, e.g.:
    pnpm install --no-frozen-lockfile --ignore-scripts
    then commit the updated pnpm-lock.yaml.
  • Or adjust your postinstall scripts/CI permissions so they don’t attempt to write outside the repo root.

Please verify that the lockfile now reflects the changes in package.json and the pipeline passes.

apps/mail/messages/cs.json (2)

165-177: Validate Czech pluralization structure for attachmentCount.

The new structured pluralization format looks correct for Czech. The plural categories 0, one, few, many, and other properly cover Czech plural rules. Verify that the Czech translations are accurate:

  • countPlural=0: "příloh" (genitive plural for 0)
  • countPlural=one: "příloha" (nominative singular for 1)
  • countPlural=few: "přílohy" (nominative plural for 2-4)
  • countPlural=many: "příloh" (genitive plural for decimal numbers)
  • countPlural=other: "příloh" (genitive plural for 5+)

178-190: Consistent pluralization structure across all updated keys.

The pluralization structure is consistently applied to fileCount, noteCount, and replies with the same format and proper Czech plural forms. The implementation correctly handles Czech's complex plural rules.

Also applies to: 253-265, 318-330

apps/mail/messages/en.json (2)

2-2: Schema declaration added for Inlang integration.

The addition of the Inlang message format schema is appropriate for the migration to the Paraglide framework. This will provide validation and tooling support for the message format.


166-176: English pluralization simplified correctly.

The English pluralization structure correctly uses only 0, one, and other categories, which is appropriate for English plural rules. The translations are accurate and consistent across all updated keys.

Also applies to: 177-187, 250-260, 313-323

apps/mail/messages/nl.json (1)

165-175: Dutch pluralization structure implemented correctly.

The pluralization structure correctly uses 0, one, and other categories for Dutch, which has similar plural rules to English. The Dutch translations are accurate and consistent.

Also applies to: 176-186, 249-259, 312-322

apps/mail/hooks/use-optimistic-actions.ts (4)

11-11: Import migration from useTranslations to direct message object.

The import change from useTranslations hook to direct m object import from @/paraglide/messages is correct for the Paraglide migration. This eliminates the need for hook-based translation calls.


238-239: Star toggle toast messages migrated correctly.

The translation calls for star toggle actions have been properly migrated from t() to m[]() syntax. The conditional logic remains intact and the message keys are correctly referenced.


268-273: Move operation toast messages updated consistently.

All move operation toast messages (inbox, spam, bin, archive) have been consistently migrated to the new m[]() syntax. The conditional logic for determining the appropriate message based on destination is preserved.


348-348: Delete operation toast message migrated.

The delete operation toast message has been correctly updated to use the new translation syntax.

apps/mail/app/(routes)/settings/danger-zone/page.tsx (2)

19-19: Import migration completed for settings page.

The import has been correctly updated from useTranslations hook to direct m object import from @/paraglide/messages, aligning with the Paraglide migration.


77-77: Comprehensive translation call migration throughout component.

All translation calls in the DangerZone settings page have been systematically migrated from t() to m[]() syntax. The changes cover:

  • Button text
  • Dialog titles and descriptions
  • Warning messages
  • Form descriptions
  • Loading states

The migration is thorough and consistent across all UI elements.

Also applies to: 81-82, 87-87, 97-97, 108-109, 123-124

apps/mail/messages/hu.json (1)

165-175: LGTM! Pluralization format migration is consistent.

The pluralization format has been correctly migrated from simple ICU MessageFormat to the structured array-based format required by the Paraglide framework. All four entries (attachmentCount, fileCount, noteCount, replies) follow the same consistent pattern with proper declarations, selectors, and plural category mappings.

Also applies to: 176-186, 249-259, 312-322

apps/mail/components/ui/nav-main.tsx (2)

13-13: LGTM! Correct import for new localization system.

The import has been properly updated to use the direct message object from Paraglide instead of the useTranslations hook.


190-190: LGTM! Translation calls correctly migrated.

All translation calls have been properly updated from t('key') to m['key']() pattern, maintaining the same functionality while using the new Paraglide message system.

Also applies to: 203-203, 282-282, 286-286, 303-303, 313-313

apps/mail/components/context/thread-context.tsx (2)

35-35: LGTM! Correct import for new localization system.

The import has been properly updated to use the direct message object from Paraglide instead of the useTranslations hook.


169-169: LGTM! All translation calls consistently migrated.

All translation calls throughout the component have been properly updated from t('key') to m['key']() pattern. The migration is comprehensive and maintains all existing functionality while using the new Paraglide message system.

Also applies to: 196-196, 272-272, 279-279, 286-286, 316-316, 323-323, 335-335, 342-342, 354-354, 361-361, 373-373, 380-380, 391-391, 398-398, 405-405, 416-416, 427-429, 435-435, 476-476

apps/mail/messages/de.json (2)

2-2: LGTM! Schema declaration for Inlang framework.

The schema declaration has been correctly added to support the new Inlang/Paraglide localization framework.


166-176: LGTM! Pluralization format migration is consistent.

The pluralization format has been correctly migrated from simple ICU MessageFormat to the structured array-based format required by the Paraglide framework. All entries follow the same consistent pattern with proper German plural forms.

Also applies to: 177-187, 250-260, 313-323

apps/mail/lib/notes-utils.ts (3)

1-2: LGTM! Correct imports for new localization system.

The imports have been properly updated to use the direct message object from Paraglide and the formatDate utility.


9-9: LGTM! Color labels properly localized.

Most color labels have been correctly updated to use the new localization system, maintaining consistency with the broader migration (except for yellow which needs fixing).

Also applies to: 16-16, 23-23, 37-37, 44-44, 51-51, 58-58


90-90: LGTM! Function signature simplified appropriately.

The formatRelativeTime function signature has been simplified by removing the optional formatter parameter, which aligns with the overall codebase cleanup. The function now uses formatDate as the fallback for older dates, maintaining the same functionality with a cleaner API.

Also applies to: 107-107

apps/mail/messages/tr.json (3)

165-175: Pluralisation object looks valid.

The declaration/selector structure and the three plural categories are syntactically correct and the Turkish strings read naturally.


176-186: Good reuse of pattern for fileCount.

Same remarks as above – no issues spotted.


312-322: Plural rules OK, but zero-case may be misleading.

"cevaplar" without the numeric placeholder means Replies instead of 0 replies. Consider including # for clarity (e.g. "# cevap").

apps/mail/messages/lv.json (3)

165-175: Plural object compiles fine.

All three Latvian forms map correctly; no syntax issues.


176-186: Consistent implementation for fileCount.

Looks good.


312-322: Pluralisation is correct.

No further comments.

apps/mail/messages/zh_TW.json (3)

165-175: Valid structure – Chinese has no plural, duplicates are expected.

Nothing to change.


176-186: Same here for fileCount.

OK.


312-322: Plural mapping correct.

No issues.

apps/mail/messages/pt.json (2)

165-175: Plural object good.

Strings and categories match.


176-186: Ditto for fileCount.

All good.

apps/mail/messages/ar.json (1)

255-268: noteCount: mismatched plural word in many/other

Genitive plural form should stay “ملاحظات”. Using “ملاحظة” after a number is ungrammatical.

-            "countPlural=many": "# ملاحظة",
-            "countPlural=other": "# ملاحظة"
+            "countPlural=many": "# ملاحظات",
+            "countPlural=other": "# ملاحظات"

Likely an incorrect or invalid review comment.

apps/mail/messages/zh_CN.json (1)

449-449: Escaped quotes ✅

Escaping the inner “发件人” quotes fixes JSON syntax and avoids breaking the string. Looks good.

apps/mail/messages/vi.json (4)

165-175: LGTM: Pluralization format updated correctly for Vietnamese.

The new structured pluralization format for attachmentCount is correctly implemented. Vietnamese pluralization rules are properly handled with appropriate forms for zero, one, and other cases.


176-186: LGTM: File count pluralization correctly structured.

The fileCount pluralization follows the same consistent pattern as attachmentCount with proper Vietnamese pluralization handling.


249-259: LGTM: Note count pluralization properly implemented.

The noteCount pluralization structure is consistent with other pluralized strings in the file and correctly handles Vietnamese language rules.


312-322: LGTM: Replies pluralization format updated consistently.

The replies pluralization follows the established pattern and maintains consistency with other pluralized strings in the file.

apps/mail/components/mail/mail-list.tsx (7)

54-54: LGTM: Translation system migration implemented correctly.

The import of the message object m from @/paraglide/messages follows the new Paraglide-based localization approach as described in the AI summary.


348-349: LGTM: Star/unstar tooltip correctly migrated.

The translation call has been properly updated from t() function to direct message object access with m['common.threadDisplay.unstar']() and m['common.threadDisplay.star']().


372-372: LGTM: Important toggle tooltip properly updated.

The toggleImportant translation call correctly uses the new direct message object syntax.


393-393: LGTM: Archive tooltip translation updated correctly.

The archive action tooltip properly uses the new message object syntax with m['common.threadDisplay.archive']().


415-415: LGTM: Bin action tooltip correctly migrated.

The bin/trash action tooltip uses the appropriate message key m['common.actions.Bin']() consistent with the new translation system.


527-527: LGTM: Replies count tooltip correctly updated.

The replies count tooltip properly uses the new pluralization syntax with m['common.mail.replies']({ count: getThreadData.totalReplies }), which correctly passes the count parameter for pluralization.


1070-1070: LGTM: Notes label tooltip correctly migrated.

The notes title tooltip properly uses the new message object syntax with m['common.notes.title']().

apps/mail/messages/pl.json (4)

165-177: LGTM: Polish attachment count pluralization correctly implemented.

The attachmentCount pluralization properly handles Polish language rules with all necessary forms: zero, one, few, many, and other. The structure is consistent with the new Paraglide format.


178-190: LGTM: File count pluralization follows Polish grammar rules.

The fileCount pluralization correctly implements Polish plural forms with appropriate translations for each grammatical case.


253-265: LGTM: Note count pluralization properly structured for Polish.

The noteCount pluralization maintains consistency with other pluralized strings and correctly handles Polish language pluralization complexity.


318-330: LGTM: Replies pluralization correctly implements Polish grammar.

The replies pluralization follows the established pattern and properly handles all Polish plural forms with appropriate translations.

apps/mail/messages/es.json (2)

165-175: LGTM: Consistent pluralization format transformation

The pluralization syntax has been correctly transformed from ICU MessageFormat to the new Inlang format. The structure is consistent and the Spanish translations are preserved.


176-186: Consistent pluralization pattern applied

The same pluralization transformation pattern is correctly applied across all affected keys (fileCount, noteCount, replies). The format correctly defines the count input, plural category, and match cases for Spanish.

Also applies to: 249-259, 312-322

apps/mail/project.inlang/settings.json (1)

1-33: Standard Inlang configuration setup

The configuration correctly establishes the Inlang localization framework with appropriate base locale, comprehensive target locales, and proper plugin setup.

apps/mail/components/context/command-palette-context.tsx (4)

59-59: LGTM: Import updated for new localization system

The import has been correctly updated to use the new Paraglide message object instead of the useTranslations hook.


774-774: LGTM: Dependency array correctly updated

The removal of the t dependency from the useMemo dependency array is correct since the useTranslations hook has been removed.


1891-1892: LGTM: Direct message calls implemented correctly

The dialog title and description now use the correct Paraglide message format with explicit key paths and function calls.


719-719: Navigation config uses translated strings
The navigationConfig now initializes each title by calling m['…'](), returning the localized string. Therefore passing navItem.title directly is correct—no further translation lookup is needed.

apps/mail/components/mail/note-panel.tsx (2)

76-76: LGTM - Clean migration to new localization system.

The import change from useTranslations to the direct message object m aligns with the broader localization refactor to Paraglide framework.


167-167: LGTM - Consistent translation method migration.

All UI text strings have been properly migrated from t('key') pattern to m['key']() function calls. The migration maintains the same message keys and functionality.

Also applies to: 174-174, 183-183, 188-188, 195-195, 216-216, 231-231

apps/mail/config/navigation.ts (3)

22-22: LGTM - Clean migration to new localization system.

The import change aligns with the broader migration from use-intl to Paraglide framework.


57-57: LGTM - Consistent navigation title migration.

All navigation titles have been properly migrated to use the new message function calls. The pattern is consistent and maintains the same message keys.

Also applies to: 64-64, 71-71, 83-83, 90-90, 96-96, 140-140, 147-147, 153-153, 158-158, 163-163, 168-168, 173-173, 178-178, 184-184, 207-207, 226-226


26-26: Title property type change is safe

I searched for all MessageKey imports and every use of item.title—all of them treat it as a runtime string (rendering, comparisons, tooltips, keys, etc.). No code relies on NavItem.title being constrained to the MessageKey union. Widening the type to string is fully backward-compatible, so no further changes are required.

apps/mail/app/(routes)/mail/[folder]/page.tsx (2)

4-4: LGTM - Good encapsulation with custom hook.

Using the useLabels hook provides better encapsulation and reusability compared to direct TRPC query usage.


29-29: LGTM - Consistent with useLabels hook adoption.

The destructuring aligns well with the custom hook pattern and maintains the same functionality.

apps/mail/components/mail/mail.tsx (3)

66-66: LGTM: Clean migration to direct message imports.

The import change from useTranslations to the direct message object m is consistent with the localization refactor described in the PR summary.


514-514: LGTM: Tooltip message migrations are correctly implemented.

All tooltip content calls have been properly migrated from the t() function to direct message function calls using the m object. The message keys follow a consistent naming pattern.

Also applies to: 719-719, 736-736, 764-764, 817-817


833-839: No runtime risk in dynamic message key resolution

The existing logic already guards against missing or non-function entries by checking m[key] && typeof m[key] === 'function' before calling it, and falls back to cat.name otherwise. A quick search confirms that all expected keys (important, promotions, personal, updates, work, forums, notes, starred) are defined and invoked elsewhere in mail-display.tsx. Adding a try/catch here isn’t necessary.

Likely an incorrect or invalid review comment.

apps/mail/providers/query-provider.tsx (2)

106-108: LGTM: QueryProvider simplification is consistent.

The removal of connectionId prop and hardcoded persister key aligns with the simplified query client architecture, assuming multi-connection support has been intentionally removed.


31-31: Verify Multi-Account Query Client Isolation

The removal of connectionId from makeQueryClient and getQueryClient means all accounts now share a single default query client and persistence key, yet the codebase still uses useConnections/useActiveConnection for multi-account flows. This can lead to cache collisions, stale data, or cross-account leakage.

Please confirm that either:

  • Multi-account support has been intentionally collapsed into one global cache, or
  • Query keys and persister keys are scoped by connection (e.g. include connection ID in the key)

Key areas to review:
• apps/mail/providers/query-provider.tsx (around line 31) – makeQueryClient signature & persister key
QueryProvider component – fixed persister key "queryClient"
• All parts of the UI that switch or load different connections via useConnections/useActiveConnection

apps/mail/components/mail/mail-display.tsx (4)

51-51: LGTM: Correct migration to new localization system.

The import of the new message object m from @/paraglide/messages is properly added to support the localization migration.


318-354: LGTM: Consistent translation replacements in mail category labels.

All mail category labels have been correctly migrated from the hook-based translation system to direct message object calls. The pattern m['common.mailCategories.{category}']() is consistent and follows the new localization approach.


482-589: LGTM: Mail details popover translations properly migrated.

All labels in the mail details popover (from, to, cc, bcc, date, security, etc.) have been consistently updated to use the new message system. The translation keys maintain their semantic meaning and structure.


812-834: LGTM: Action button text migrations are correct.

The reply, reply all, and forward button texts have been properly migrated to use the new localization system while maintaining their functionality.

apps/mail/app/root.tsx (4)

18-22: LGTM: Proper imports for new localization system.

The addition of getLocale from paraglide runtime and the message object m correctly supports the migration from server-side to runtime localization.


41-41: LGTM: Runtime locale detection for HTML lang attribute.

Using getLocale() at runtime for the HTML lang attribute is appropriate and maintains proper document localization while simplifying the server-side setup.


55-57: LGTM: Simplified ServerProviders usage.

The removal of props to ServerProviders aligns with the migration away from server-side locale and message loading, as confirmed by the relevant code snippet showing the simplified component structure.


149-162: LGTM: NotFound component properly migrated.

The error page translations have been correctly updated to use the new message system, maintaining the same user experience with the new localization approach.

apps/mail/lib/utils.ts (3)

96-113: LGTM: Whitespace cleanup in shouldShowSeparateTime.

The trailing whitespace removal improves code cleanliness while preserving the original logic for determining when to show separate time displays.


119-134: LGTM: Simplified formatDate function signature.

The removal of overload declarations and optional formatter parameters simplifies the function while maintaining its core date formatting logic. This aligns with the localization migration that centralizes formatting logic elsewhere.


172-187: LGTM: Whitespace cleanup in formatTime.

Minor formatting improvement that maintains the existing time formatting logic while improving code readability.

apps/mail/app/(routes)/settings/general/page.tsx (6)

23-36: LGTM: Proper migration to runtime localization.

The import changes correctly replace the old hook-based system with runtime locale detection and direct message imports. The commented-out imports indicate a clean migration path.


42-84: LGTM: TimezoneSelect component properly updated.

The component signature has been correctly simplified to remove the translation function prop, and all internal text uses the new message system consistently.


115-117: LGTM: Runtime locale detection and refetch functionality.

Using getLocale() directly and destructuring the refetch method provides better control over settings updates and aligns with the new localization approach.


159-176: LGTM: Improved error handling and cache management.

The refactored save logic with proper cache updates, error rollback, and success notifications using the new message system is well implemented. The addition of refetchSettings() ensures data consistency.


182-312: LGTM: Comprehensive form text migration.

All form labels, descriptions, placeholders, and button text have been consistently migrated to the new message system. The translation keys maintain semantic meaning and the UI will function identically with the new localization approach.


122-125: Confirm new locale persistence in paraglide/runtime

The setLocaleCookie mutation has been commented out in GeneralPage, so we need to ensure the new getLocale/setLocale from @/paraglide/runtime still persist the user’s language preference across sessions. Please verify:

  • That setLocale writes the locale to a durable storage (cookie, localStorage, etc.).
  • That getLocale reads the persisted locale on initial load (e.g. in root.tsx’s <html lang={getLocale()}…>).

If persistence is missing, please restore or implement equivalent logic to retain user locale across sessions.

try {
const translationKey = `common.commandPalette.groups.${groupKey}` as any;
groupTitle = t(translationKey) || groupKey;
groupTitle = (m as any)[translationKey]() || groupKey;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Type safety issue with dynamic translation lookup

The type assertion to any bypasses TypeScript's type checking, which could lead to runtime errors if the translation key doesn't exist.

Consider using a type-safe approach:

-groupTitle = (m as any)[translationKey]() || groupKey;
+// Create a type-safe helper function or use a mapping approach
+try {
+  const translationFn = (m as Record<string, () => string>)[translationKey];
+  groupTitle = translationFn ? translationFn() : groupKey;
+} catch {
+  groupTitle = groupKey;
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
groupTitle = (m as any)[translationKey]() || groupKey;
// Create a type-safe helper function or use a mapping approach
try {
const translationFn = (m as Record<string, () => string>)[translationKey];
groupTitle = translationFn ? translationFn() : groupKey;
} catch {
groupTitle = groupKey;
}
🤖 Prompt for AI Agents
In apps/mail/components/context/command-palette-context.tsx at line 763, the
code uses a type assertion to any to dynamically call a translation function,
which bypasses TypeScript's type safety and risks runtime errors if the key is
missing. To fix this, define a type-safe interface or type for the translation
object that includes the possible keys as methods, then access the translation
function using a type-safe key check or optional chaining before calling it.
This ensures TypeScript can verify the existence of the method and prevents
unsafe calls.

<div className="mt-2 flex cursor-default items-center text-xs text-[#8C8C8C]">
<Clock className="mr-1 h-3 w-3" />
<span>{formatRelativeTime(note.createdAt, format)}</span>
<span>{formatRelativeTime(note.createdAt)}</span>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify formatRelativeTime function signature change.

The formatRelativeTime call no longer passes the formatter argument. Please ensure this function has been updated to handle localization internally.


🏁 Script executed:

#!/bin/bash
# Description: Verify formatRelativeTime function signature and usage

# Check the function definition in notes-utils
echo "=== formatRelativeTime function definition ==="
ast-grep --pattern 'function formatRelativeTime($_) { $$$ }' || ast-grep --pattern 'export function formatRelativeTime($_) { $$$ }'

# Check all usages of formatRelativeTime to ensure consistency
echo "=== All formatRelativeTime usages ==="
rg "formatRelativeTime\(" -A 2 -B 1

Length of output: 890


🏁 Script executed:

#!/bin/bash
# Display the full implementation of formatRelativeTime for validation
rg -n "export function formatRelativeTime" -A 20 -B 0 apps/mail/lib/notes-utils.ts

Length of output: 968


Implement Localization in formatRelativeTime After Signature Change

The formatRelativeTime function signature was simplified to only accept dateInput, but its implementation still uses hard-coded English strings. To ensure localization isn’t broken:

• apps/mail/lib/notes-utils.ts (lines 90–109):
– Replace static returns ('just now', ${minutes} minute(s) ago, etc.) with a localized formatter (e.g. Intl.RelativeTimeFormat) or internal locale lookup.
– Optionally reintroduce an overload/parameter for locale/options, or derive the user’s locale from context.

• Confirm all callers (e.g. apps/mail/components/mail/note-panel.tsx) reflect this change and no longer pass a formatter argument.

If localization was previously delegated via the removed formatter, you must restore that behavior or build it into formatRelativeTime.

🤖 Prompt for AI Agents
In apps/mail/lib/notes-utils.ts around lines 90 to 109, the formatRelativeTime
function still returns hard-coded English strings despite the signature change;
update it to use Intl.RelativeTimeFormat or an internal localization method to
generate localized relative time strings. Ensure the function either accepts
locale/options parameters or derives the user's locale internally. Then, in
apps/mail/components/mail/note-panel.tsx at line 137, confirm that
formatRelativeTime is called without any formatter argument and that the
displayed output is localized accordingly.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

🔭 Outside diff range comments (4)
apps/mail/app/(routes)/settings/labels/page.tsx (1)

64-72: Unsupported finally prop in toast.promise?

sonner’s toast.promise API (<= v2) accepts only loading / success / error. A stray finally will be silently ignored. If you rely on refetch, move it to .then() of the mutation instead.

-    toast.promise(deleteLabel({ id }), {
+    await toast.promise(deleteLabel({ id }), {-      finally: async () => {
-        await refetch();
-      },
     });
+    await refetch();
apps/mail/components/mail/thread-display.tsx (1)

684-693: Fix incomplete error handling logic.

The current logic only shows success toast when isImportant is true, but shows a generic error in the else case. This doesn't properly handle the actual toggle operation result.

Apply this diff to fix the error handling:

  const handleToggleImportant = useCallback(async () => {
    if (!emailData || !id) return;
-   await toggleImportant({ ids: [id] });
-   await refetchThread();
-   if (isImportant) {
-     toast.success(m['common.mail.markedAsImportant']());
-   } else {
-     toast.error('Failed to mark as important');
-   }
+   try {
+     await toggleImportant({ ids: [id] });
+     await refetchThread();
+     toast.success(isImportant 
+       ? m['common.mail.removedFromImportant']() 
+       : m['common.mail.markedAsImportant']());
+   } catch (error) {
+     toast.error('Failed to toggle important status');
+   }
  }, [emailData, id]);
apps/mail/lib/notes-utils.ts (1)

29-34: Fix missing localization for yellow color

The yellow color label is still hardcoded as "Yellow" while all other colors use localized messages. This breaks the internationalization pattern and will prevent proper translation.

Apply this fix:

  {
    value: 'yellow',
-    label: 'Yellow',
+    label: m['common.notes.colors.yellow'](),
    class: 'border-l-amber-500',
    bgClass: 'hover:bg-amber-50 dark:hover:bg-amber-950/20',
    style: { borderLeftColor: 'rgb(245, 158, 11)' },
  },
apps/mail/components/create/image-compression-settings.tsx (1)

57-76: Critical: All image quality options display the same label

The label and description for all radio options are hardcoded to use the "low" quality message keys, regardless of the actual option value. This makes it impossible for users to distinguish between different compression quality options.

Apply this diff to fix the dynamic message key selection:

-                      <Label htmlFor={option.value} className="cursor-pointer text-sm font-medium">
-                        {m['pages.createEmail.imageCompression.low.label']()}
-                      </Label>
-                      <span className="text-muted-foreground text-xs">
-                        {m['pages.createEmail.imageCompression.low.description']()}
-                      </span>
+                      <Label htmlFor={option.value} className="cursor-pointer text-sm font-medium">
+                        {m[`pages.createEmail.imageCompression.${option.value}.label`]()}
+                      </Label>
+                      <span className="text-muted-foreground text-xs">
+                        {m[`pages.createEmail.imageCompression.${option.value}.description`]()}
+                      </span>
♻️ Duplicate comments (18)
apps/server/wrangler.jsonc (1)

110-120: Align local backend ports between server & SPA

The server’s wrangler.jsonc (apps/server/wrangler.jsonc:112) now points to port 3789, but the mail SPA’s wrangler.jsonc (apps/mail/wrangler.jsonc:17) is still on port 3333. This mismatch will break local API calls.

• apps/server/wrangler.jsonc:112
“VITE_PUBLIC_BACKEND_URL”: “http://localhost:3789”
• apps/mail/wrangler.jsonc:17
“VITE_PUBLIC_BACKEND_URL”: “http://localhost:3333”

Please update the mail SPA config to use port 3789, or document why two different local ports are required:

--- a/apps/mail/wrangler.jsonc
+++ b/apps/mail/wrangler.jsonc
@@ -15,7 +15,7 @@
         "NODE_ENV": "development",
-        "VITE_PUBLIC_BACKEND_URL": "http://localhost:3333",
+        "VITE_PUBLIC_BACKEND_URL": "http://localhost:3789",
         "VITE_PUBLIC_APP_URL": "http://localhost:3000",
         …
apps/mail/messages/cs.json (1)

253-265: Same unreachable plural branches in noteCount

Remove many/0 selectors or switch to count equality checks as above to ensure runtime coverage.

apps/mail/components/mail/nav-main.tsx (1)

1-1: Remove unused import.

The m import from '@/paraglide/messages' is not used anywhere in this component.

apps/mail/app/(routes)/mail/page.tsx (1)

1-2: Client-side redirect migration approved.

The migration from server-side loader to clientLoader with Response.redirect() is consistent with the broader SSR removal across the codebase. The implementation correctly uses the environment variable for the redirect URL.

apps/server/src/trpc/routes/cookies.ts (1)

59-66: Commented code should be removed – duplicate of previous review.

apps/mail/app/(routes)/settings/shortcuts/hotkey-recorder.tsx (1)

4-5: as MessageKey casts hide missing-key bugs – same issue flagged earlier

Previous review already highlighted that the as MessageKey assertions defeat compile-time safety. No action taken here. Please expose these keys in the generated typings instead of casting.

Also applies to: 70-78

apps/mail/messages/pt.json (1)

312-322: Wrong translation set – shows "files" instead of "replies".

The Portuguese strings map to arquivos (files), but the key is replies. This will surface as incorrect UI text.

-            "countPlural=0": "arquivos",
-            "countPlural=one": "arquivo", 
-            "countPlural=other": "arquivos"
+            "countPlural=0": "respostas",
+            "countPlural=one": "# resposta",
+            "countPlural=other": "# respostas"
apps/mail/wrangler.jsonc (1)

15-19: Local backend points to 3333 – mismatch with server config.

With the server listening on 3789, the SPA will attempt to hit an unavailable port.

-        "VITE_PUBLIC_BACKEND_URL": "http://localhost:3333",
+        "VITE_PUBLIC_BACKEND_URL": "http://localhost:3789",

Keep both wrangler configs consistent or add a proxy rule.

apps/mail/messages/ar.json (3)

165-178: Missing number token in Arabic branches (again)
Same remark as the previous review – please prefix # for few/many/other.


179-192: fileCount: identical issue – number not shown
See earlier comment; apply the same fix.


321-334: replies: wrong plural & missing placeholder
The “many” branch still reads “# رداً”. Should be plural “ردود”.

apps/mail/messages/ru.json (4)

165-177: Add numeric placeholder for every plural branch of attachmentCount

All branches except one omit the # placeholder, so the rendered text will lack the actual number (e.g. it will show "вложений" instead of "3 вложений"). This is inconsistent with other counters and with the new Paraglide plural-object guidelines.


178-190: fileCount → incorrect word in other branch

other currently uses "файла", which is singular/genitive and reads oddly for numbers ≥5. Use "файлов" (plural, genitive) to match Russian grammar and the many branch.


253-265: noteCount: "other" should use "заметок"

For counts not covered by one/few/many, "заметок" is grammatically correct. Current value "заметки" is plural nominative and clashes with numeral rules.


318-330: replies: wrong noun and missing number in "other"

"# ответы" mixes number with nominative plural; correct form is genitive plural "# ответов".

apps/mail/components/mail/note-panel.tsx (1)

137-137: Verify localization support in formatRelativeTime function

The formatRelativeTime function call no longer passes a formatter argument. As noted in previous reviews, the function implementation still returns hard-coded English strings, which breaks localization.

#!/bin/bash
# Check the current implementation of formatRelativeTime
rg -A 20 "export function formatRelativeTime" apps/mail/lib/notes-utils.ts
apps/mail/components/context/command-palette-context.tsx (1)

763-763: Type safety issue with dynamic translation lookup

The type assertion to any bypasses TypeScript's type checking, which could lead to runtime errors if the translation key doesn't exist.

apps/mail/providers/query-provider.tsx (1)

31-31: Verify removal of multi-connection support aligns with application architecture

The changes systematically remove dynamic connection ID handling:

  • makeQueryClient() no longer accepts connectionId parameter
  • Query key hashing uses hardcoded 'default' connection ID
  • getQueryClient() simplified to singleton pattern
  • QueryProvider uses fixed cache key suffix

This matches a previous concern about hardcoded connection IDs potentially causing cache conflicts. Please confirm that:

  1. Multi-connection support has been intentionally removed from the application
  2. All related UI and logic for connection switching has been updated accordingly
  3. The 'default' connection ID approach aligns with the new single-connection architecture
#!/bin/bash
# Verify connection switching functionality has been removed or updated
echo "Searching for connection switching related code..."
rg -A 3 "setDefaultConnection|switchConnection|connectionId" --type ts --type tsx
echo -e "\nSearching for connection management hooks..."
rg -A 2 "useActiveConnection|useConnections" --type ts --type tsx

Also applies to: 53-53, 70-79, 106-108

🧹 Nitpick comments (20)
apps/mail/app/(routes)/settings/labels/page.tsx (2)

57-60: Message key spelling looks wrong – likely typo.

failedToSavingLabel reads awkwardly and deviates from the usual failedToSaveLabel naming convention followed elsewhere (saveLabelSuccess). Double-check the key in all locale files and rename it for clarity/consistency.

-        error: m['common.labels.failedToSavingLabel'](),
+        error: m['common.labels.failedToSaveLabel'](),

113-118: Hard-coded empty-state text still in English in non-EN locales.

The empty-label placeholder is now translated (👍) but the surrounding error/loading placeholders (error.message) remain raw. Consider localising those too for complete i18n coverage.

apps/mail/lib/hotkeys/mail-list-hotkeys.tsx (2)

61-62: Repeated toast message – consider DRYing for maintainability.

m['common.mail.noEmailsToSelect']() is duplicated six times. Extracting into a small helper avoids typos and eases future changes.

+  const noSelectionMsg = m['common.mail.noEmailsToSelect']();-      toast.info(m['common.mail.noEmailsToSelect']());
+      toast.info(noSelectionMsg);

202-208: Hard-coded category indices still risky.

The earlier learning notes mention safeguards, but refactors can break assumptions. Consider mapping by shortcut.id instead of index-position to future-proof the hotkeys.

apps/mail/components/labels/label-dialog.tsx (2)

116-120: Placeholder string not localised.

"Enter label name" is hard-coded English. Add a key to the messages bundle for consistency with the rest of the dialog.

-                      <Input placeholder="Enter label name" {...field} autoFocus />
+                      <Input placeholder={m['common.labels.enterLabelName']()} {...field} autoFocus />

151-157: Action text duplication between create & save.

Using common.labels.createLabel for create and common.actions.saveChanges for edit mixes two scopes. Consider a dedicated updateLabel key for clarity and translators’ ease.

apps/mail/components/connection/add.tsx (1)

15-15: Import order keeps changing across files

In several migrated files m is imported before third-party libs, elsewhere after. Pick one convention (project eslint/ts-config may help) to avoid noisy diffs.

apps/mail/package.json (2)

8-12: Environment variable baked into build script

CLOUDFLARE_ENV=staging is hard-coded in both build and deploy.
If someone forgets to override it, production builds may silently target staging resources.

Prefer a cross-platform solution that forwards the caller’s env, e.g.

"build": "react-router build",
"deploy": "wrangler deploy",

and document CLOUDFLARE_ENV in the release pipeline instead.


141-143: Pinning major-zero prerelease libs

@inlang/cli is added as ^3.0.0 while @inlang/paraglide-js is pinned to 2.1.0.
Given their rapid evolution, consider pinning both to an exact version to avoid accidental breaking updates.

apps/mail/messages/zh_TW.json (1)

1-1: Missing schema declaration compared to other locale files.

Consider adding the schema declaration for consistency with other locale files like de.json:

 {
+  "$schema": "https://inlang.com/schema/inlang-message-format",
   "common": {
apps/mail/messages/ca.json (1)

1-1: Missing schema declaration for consistency.

Add the schema declaration to align with other locale files:

 {
+  "$schema": "https://inlang.com/schema/inlang-message-format",
   "common": {
apps/mail/messages/zh_CN.json (1)

165-186: Consider simplifying Chinese pluralization rules.

Chinese typically doesn't distinguish between singular and plural forms. The current format includes "one" and "other" cases, but Chinese might only need "other" for all counts. However, if this format is required by paraglide-js for consistency, it's acceptable.

apps/mail/messages/hi.json (1)

312-322: Expose count for the zero branch

-            "countPlural=0": "जवाब",
+            "countPlural=0": "# जवाब",

This keeps visual alignment with the other branches.

apps/mail/messages/fr.json (1)

312-322: Add # to the zero branch for consistency

-            "countPlural=0": "réponses",
+            "countPlural=0": "# réponses",
apps/mail/messages/hu.json (3)

165-175: Show count for Hungarian attachments

Hungarian keeps the singular noun with numbers, but the number still needs to be
rendered.

-            "countPlural=0": "csatolmány",
-            "countPlural=one": "csatolmány",
-            "countPlural=other": "csatolmány"
+            "countPlural=0": "# csatolmány",
+            "countPlural=one": "# csatolmány",
+            "countPlural=other": "# csatolmány"

176-186: Expose file count

Same rationale as above.

-            "countPlural=0": "fájl",
-            "countPlural=one": "fájl",
-            "countPlural=other": "fájl"
+            "countPlural=0": "# fájl",
+            "countPlural=one": "# fájl",
+            "countPlural=other": "# fájl"

312-322: Add number for the zero branch

-            "countPlural=0": "válasz",
+            "countPlural=0": "# válasz",
apps/mail/components/mail/mail.tsx (1)

833-839: Well-implemented dynamic translation logic with good fallback handling.

The category name translation logic correctly converts category IDs to camelCase keys (e.g., "All Mail" → "allMail") and provides proper fallback to the original name when translations are missing. The type assertion ensures type safety.

Consider memoizing this logic to avoid recomputing the translation keys on every render:

+ const categoryName = useMemo(() => {
    const key = `common.mailCategories.${cat.id
      .split(' ')
      .map((w, i) => (i === 0 ? w.toLowerCase() : w))
      .join('')}` as keyof typeof m;
    return m[key] && typeof m[key] === 'function' ? (m[key] as () => string)() : cat.name;
+ }, [cat.id, cat.name]);
apps/mail/vite.config.ts (1)

60-64: Clarify the reason for commenting out SSR optimization.

The SSR optimizeDeps configuration is commented out. Consider either removing these lines entirely if they're no longer needed, or add a comment explaining why they're temporarily disabled.

-  //   ssr: {
-  //     optimizeDeps: {
-  //       include: ['novel', '@tiptap/extension-placeholder'],
-  //     },
-  //   },
+  // SSR optimization disabled due to SSR being turned off in react-router.config.ts
apps/mail/app/(routes)/settings/general/page.tsx (1)

35-36: Clean up commented code or document temporary state.

There's commented code for useRevalidator and locale cookie mutation. If this is part of the migration process, consider adding a TODO comment explaining the temporary state. If these features are permanently removed, the commented code should be deleted.

-// import { useRevalidator } from 'react-router';
+// TODO: Remove after confirming locale management works without cookies
+// import { useRevalidator } from 'react-router';
-//   const { mutateAsync: setLocaleCookie } = useMutation(
-//     trpc.cookiePreferences.setLocaleCookie.mutationOptions(),
-//   );
-//   const { revalidate } = useRevalidator();
+// TODO: Remove after confirming locale management works without cookies
+// const { mutateAsync: setLocaleCookie } = useMutation(
+//   trpc.cookiePreferences.setLocaleCookie.mutationOptions(),
+// );
+// const { revalidate } = useRevalidator();

Also applies to: 122-125

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 59c18be and f5ed25d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (79)
  • apps/mail/app/(auth)/login/error-message.tsx (3 hunks)
  • apps/mail/app/(routes)/mail/[folder]/page.tsx (2 hunks)
  • apps/mail/app/(routes)/mail/page.tsx (1 hunks)
  • apps/mail/app/(routes)/settings/[...settings]/page.tsx (2 hunks)
  • apps/mail/app/(routes)/settings/appearance/page.tsx (6 hunks)
  • apps/mail/app/(routes)/settings/connections/page.tsx (9 hunks)
  • apps/mail/app/(routes)/settings/danger-zone/page.tsx (5 hunks)
  • apps/mail/app/(routes)/settings/general/page.tsx (13 hunks)
  • apps/mail/app/(routes)/settings/labels/page.tsx (6 hunks)
  • apps/mail/app/(routes)/settings/privacy/page.tsx (6 hunks)
  • apps/mail/app/(routes)/settings/security/page.tsx (4 hunks)
  • apps/mail/app/(routes)/settings/shortcuts/hotkey-recorder.tsx (2 hunks)
  • apps/mail/app/(routes)/settings/shortcuts/page.tsx (3 hunks)
  • apps/mail/app/(routes)/settings/signatures/page.tsx (0 hunks)
  • apps/mail/app/entry.server.tsx (1 hunks)
  • apps/mail/app/root.tsx (5 hunks)
  • apps/mail/components/connection/add.tsx (3 hunks)
  • apps/mail/components/context/command-palette-context.tsx (6 hunks)
  • apps/mail/components/context/label-sidebar-context.tsx (4 hunks)
  • apps/mail/components/context/thread-context.tsx (13 hunks)
  • apps/mail/components/create/create-email.tsx (3 hunks)
  • apps/mail/components/create/editor.tsx (11 hunks)
  • apps/mail/components/create/image-compression-settings.tsx (4 hunks)
  • apps/mail/components/labels/label-dialog.tsx (6 hunks)
  • apps/mail/components/mail/mail-display.tsx (23 hunks)
  • apps/mail/components/mail/mail-iframe.tsx (3 hunks)
  • apps/mail/components/mail/mail-list.tsx (8 hunks)
  • apps/mail/components/mail/mail.tsx (8 hunks)
  • apps/mail/components/mail/nav-main.tsx (1 hunks)
  • apps/mail/components/mail/note-panel.tsx (28 hunks)
  • apps/mail/components/mail/reply-composer.tsx (3 hunks)
  • apps/mail/components/mail/thread-display.tsx (10 hunks)
  • apps/mail/components/theme/theme-switcher.tsx (2 hunks)
  • apps/mail/components/ui/app-sidebar.tsx (2 hunks)
  • apps/mail/components/ui/nav-main.tsx (6 hunks)
  • apps/mail/components/ui/nav-user.tsx (9 hunks)
  • apps/mail/config/navigation.ts (6 hunks)
  • apps/mail/hooks/driver/use-delete.ts (2 hunks)
  • apps/mail/hooks/use-notes.tsx (2 hunks)
  • apps/mail/hooks/use-optimistic-actions.ts (4 hunks)
  • apps/mail/i18n/config.ts (0 hunks)
  • apps/mail/i18n/request.ts (0 hunks)
  • apps/mail/lib/hotkeys/mail-list-hotkeys.tsx (9 hunks)
  • apps/mail/lib/notes-utils.ts (4 hunks)
  • apps/mail/lib/utils.ts (3 hunks)
  • apps/mail/messages/ar.json (4 hunks)
  • apps/mail/messages/ca.json (4 hunks)
  • apps/mail/messages/cs.json (4 hunks)
  • apps/mail/messages/de.json (5 hunks)
  • apps/mail/messages/en.json (6 hunks)
  • apps/mail/messages/es.json (4 hunks)
  • apps/mail/messages/fa.json (4 hunks)
  • apps/mail/messages/fr.json (4 hunks)
  • apps/mail/messages/hi.json (4 hunks)
  • apps/mail/messages/hu.json (4 hunks)
  • apps/mail/messages/ja.json (2 hunks)
  • apps/mail/messages/ko.json (3 hunks)
  • apps/mail/messages/lv.json (4 hunks)
  • apps/mail/messages/nl.json (4 hunks)
  • apps/mail/messages/pl.json (4 hunks)
  • apps/mail/messages/pt.json (4 hunks)
  • apps/mail/messages/ru.json (4 hunks)
  • apps/mail/messages/tr.json (4 hunks)
  • apps/mail/messages/vi.json (4 hunks)
  • apps/mail/messages/zh_CN.json (5 hunks)
  • apps/mail/messages/zh_TW.json (4 hunks)
  • apps/mail/package.json (3 hunks)
  • apps/mail/project.inlang/.gitignore (1 hunks)
  • apps/mail/project.inlang/project_id (1 hunks)
  • apps/mail/project.inlang/settings.json (1 hunks)
  • apps/mail/providers/query-provider.tsx (4 hunks)
  • apps/mail/providers/server-providers.tsx (1 hunks)
  • apps/mail/react-router.config.ts (1 hunks)
  • apps/mail/vite.config.ts (3 hunks)
  • apps/mail/worker.ts (0 hunks)
  • apps/mail/wrangler.jsonc (1 hunks)
  • apps/server/src/trpc/routes/cookies.ts (1 hunks)
  • apps/server/wrangler.jsonc (1 hunks)
  • i18n.json (1 hunks)
💤 Files with no reviewable changes (4)
  • apps/mail/i18n/request.ts
  • apps/mail/i18n/config.ts
  • apps/mail/app/(routes)/settings/signatures/page.tsx
  • apps/mail/worker.ts
🧰 Additional context used
🧠 Learnings (48)
📓 Common learnings
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/mail/nav-main.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/app/entry.server.tsx (4)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.709Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: dakdevs
PR: Mail-0/Zero#764
File: apps/mail/lib/ai.ts:50-51
Timestamp: 2025-04-25T08:33:16.956Z
Learning: In Next.js 15, the `headers()` function from 'next/headers' is asynchronous and requires using `await` when called, which is a breaking change from previous versions where it was synchronous.
Learnt from: dakdevs
PR: Mail-0/Zero#764
File: apps/mail/lib/ai.ts:50-51
Timestamp: 2025-04-25T08:33:16.956Z
Learning: In Next.js 15, the `headers()` function from 'next/headers' is asynchronous and requires using `await` when called, which is a breaking change from previous versions where it was synchronous.
Learnt from: adiologydev
PR: Mail-0/Zero#871
File: docker-compose.yaml:2-21
Timestamp: 2025-05-04T23:21:21.388Z
Learning: To completely disable SSG (Static Site Generation) in Next.js projects for Docker deployments, use 'force-dynamic' for App Router or getServerSideProps for Pages Router in all pages, and set output: 'standalone' in next.config.ts. This allows all environment variables to be passed at runtime instead of build time, improving security for sensitive values.
apps/mail/react-router.config.ts (4)
Learnt from: adiologydev
PR: Mail-0/Zero#871
File: docker-compose.yaml:2-21
Timestamp: 2025-05-04T23:21:21.388Z
Learning: To completely disable SSG (Static Site Generation) in Next.js projects for Docker deployments, use 'force-dynamic' for App Router or getServerSideProps for Pages Router in all pages, and set output: 'standalone' in next.config.ts. This allows all environment variables to be passed at runtime instead of build time, improving security for sensitive values.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.709Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: adiologydev
PR: Mail-0/Zero#871
File: docker-compose.yaml:2-21
Timestamp: 2025-05-04T23:13:26.825Z
Learning: Next.js requires certain environment variables during static site generation at build time, particularly those with the NEXT_PUBLIC_ prefix. When using Docker, these should be passed as build args, while sensitive values like API keys and secrets should ideally only be passed at runtime as environment variables.
apps/mail/app/(routes)/settings/shortcuts/page.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/server/wrangler.jsonc (3)
Learnt from: adiologydev
PR: Mail-0/Zero#871
File: docker-compose.yaml:2-21
Timestamp: 2025-05-04T23:13:26.825Z
Learning: Next.js requires certain environment variables during static site generation at build time, particularly those with the NEXT_PUBLIC_ prefix. When using Docker, these should be passed as build args, while sensitive values like API keys and secrets should ideally only be passed at runtime as environment variables.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: txj-xyz
PR: Mail-0/Zero#131
File: Dockerfile:31-41
Timestamp: 2025-03-14T22:15:10.146Z
Learning: For Docker configurations in this project, environment variables should be managed using .env files rather than hardcoding them in the Dockerfile, especially for development environments.
apps/mail/hooks/driver/use-delete.ts (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.709Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
apps/mail/app/(routes)/settings/appearance/page.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: snehendu098
PR: Mail-0/Zero#1323
File: apps/mail/lib/themes/theme-utils.ts:318-318
Timestamp: 2025-06-24T06:22:58.753Z
Learning: In the Mail-0/Zero theme system (apps/mail/lib/themes/theme-utils.ts), when color themes are being applied, all color values come in HSL format, so there's no need for additional format validation when converting colors with hslToHex().
apps/mail/app/(routes)/settings/shortcuts/hotkey-recorder.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/create/create-email.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/components/theme/theme-switcher.tsx (3)
Learnt from: snehendu098
PR: Mail-0/Zero#1323
File: apps/mail/lib/themes/theme-utils.ts:318-318
Timestamp: 2025-06-24T06:22:58.753Z
Learning: In the Mail-0/Zero theme system (apps/mail/lib/themes/theme-utils.ts), when color themes are being applied, all color values come in HSL format, so there's no need for additional format validation when converting colors with hslToHex().
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/components/ui/app-sidebar.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/app/(routes)/settings/danger-zone/page.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1354
File: apps/mail/components/ui/prompts-dialog.tsx:85-88
Timestamp: 2025-06-20T05:03:16.944Z
Learning: In React Hook Form, avoid using useEffect for form state synchronization when the values prop can handle reactive updates automatically. The values prop is specifically designed for this purpose and is more optimal than manual useEffect-based synchronization.
apps/mail/app/(routes)/mail/page.tsx (4)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.709Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: adiologydev
PR: Mail-0/Zero#871
File: docker-compose.yaml:2-21
Timestamp: 2025-05-04T23:21:21.388Z
Learning: To completely disable SSG (Static Site Generation) in Next.js projects for Docker deployments, use 'force-dynamic' for App Router or getServerSideProps for Pages Router in all pages, and set output: 'standalone' in next.config.ts. This allows all environment variables to be passed at runtime instead of build time, improving security for sensitive values.
apps/mail/components/labels/label-dialog.tsx (4)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1354
File: apps/mail/components/ui/prompts-dialog.tsx:85-88
Timestamp: 2025-06-20T05:03:16.944Z
Learning: In React Hook Form, avoid using useEffect for form state synchronization when the values prop can handle reactive updates automatically. The values prop is specifically designed for this purpose and is more optimal than manual useEffect-based synchronization.
Learnt from: danteissaias
PR: Mail-0/Zero#902
File: apps/mail/components/connection/add.tsx:77-77
Timestamp: 2025-05-07T16:55:46.513Z
Learning: For the "Upgrade" link in AddConnectionDialog, using a proper <button> element instead of a <span> with onClick is recognized as an accessibility improvement but was deferred as out of scope in PR #902 (CSS variables PR).
apps/mail/components/mail/mail-iframe.tsx (5)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.709Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: danteissaias
PR: Mail-0/Zero#618
File: apps/mail/components/mail/mail-iframe.tsx:0-0
Timestamp: 2025-04-07T20:46:04.726Z
Learning: In the Zero mail application, the "Trust Sender" button for external images is only shown when a sender is not already in the trusted senders list (`settings?.trustedSenders`). This is controlled by the condition `!imagesEnabled && !settings?.externalImages`, where `imagesEnabled` is based on `isTrustedSender || settings?.externalImages` and `isTrustedSender` is determined by `settings?.trustedSenders?.includes(senderEmail)`. This design pattern prevents duplicate entries in the trusted senders list.
Learnt from: danteissaias
PR: Mail-0/Zero#618
File: apps/mail/components/mail/mail-iframe.tsx:102-102
Timestamp: 2025-04-07T20:48:48.213Z
Learning: In the Zero mail application, when implementing the "Trust Sender" feature, the banner should disappear immediately when a user clicks the "Trust Sender" button without showing a loading state. This is achieved by setting `setImagesEnabled(true)` at the beginning of the `onTrustSender` function, providing immediate visual feedback while the backend operation continues asynchronously.
apps/mail/app/(routes)/settings/security/page.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1354
File: apps/mail/components/ui/prompts-dialog.tsx:85-88
Timestamp: 2025-06-20T05:03:16.944Z
Learning: In React Hook Form, avoid using useEffect for form state synchronization when the values prop can handle reactive updates automatically. The values prop is specifically designed for this purpose and is more optimal than manual useEffect-based synchronization.
apps/mail/app/(routes)/settings/connections/page.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: danteissaias
PR: Mail-0/Zero#902
File: apps/mail/components/connection/add.tsx:77-77
Timestamp: 2025-05-07T16:55:46.513Z
Learning: For the "Upgrade" link in AddConnectionDialog, using a proper <button> element instead of a <span> with onClick is recognized as an accessibility improvement but was deferred as out of scope in PR #902 (CSS variables PR).
apps/mail/hooks/use-notes.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/connection/add.tsx (2)
Learnt from: danteissaias
PR: Mail-0/Zero#902
File: apps/mail/components/connection/add.tsx:77-77
Timestamp: 2025-05-07T16:55:46.513Z
Learning: For the "Upgrade" link in AddConnectionDialog, using a proper <button> element instead of a <span> with onClick is recognized as an accessibility improvement but was deferred as out of scope in PR #902 (CSS variables PR).
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/mail/reply-composer.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/app/(auth)/login/error-message.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/context/label-sidebar-context.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/app/(routes)/settings/privacy/page.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: danteissaias
PR: Mail-0/Zero#618
File: apps/mail/components/mail/mail-iframe.tsx:0-0
Timestamp: 2025-04-07T20:46:04.726Z
Learning: In the Zero mail application, the "Trust Sender" button for external images is only shown when a sender is not already in the trusted senders list (`settings?.trustedSenders`). This is controlled by the condition `!imagesEnabled && !settings?.externalImages`, where `imagesEnabled` is based on `isTrustedSender || settings?.externalImages` and `isTrustedSender` is determined by `settings?.trustedSenders?.includes(senderEmail)`. This design pattern prevents duplicate entries in the trusted senders list.
apps/mail/app/(routes)/settings/[...settings]/page.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/mail/thread-display.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/app/(routes)/settings/labels/page.tsx (3)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: danteissaias
PR: Mail-0/Zero#902
File: apps/mail/components/connection/add.tsx:77-77
Timestamp: 2025-05-07T16:55:46.513Z
Learning: For the "Upgrade" link in AddConnectionDialog, using a proper <button> element instead of a <span> with onClick is recognized as an accessibility improvement but was deferred as out of scope in PR #902 (CSS variables PR).
apps/mail/providers/server-providers.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/lib/hotkeys/mail-list-hotkeys.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/lib/notes-utils.ts (3)
Learnt from: snehendu098
PR: Mail-0/Zero#1323
File: apps/mail/lib/themes/theme-utils.ts:318-318
Timestamp: 2025-06-24T06:22:58.753Z
Learning: In the Mail-0/Zero theme system (apps/mail/lib/themes/theme-utils.ts), when color themes are being applied, all color values come in HSL format, so there's no need for additional format validation when converting colors with hslToHex().
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: danteissaias
PR: Mail-0/Zero#902
File: apps/mail/components/mail/note-panel.tsx:511-513
Timestamp: 2025-05-07T16:45:40.468Z
Learning: The amber color for notes (text-amber-500, fill-amber-200, etc.) is intentionally fixed and should not be converted to theme variables, as it serves as a recognizable visual metaphor for sticky notes.
apps/mail/components/context/thread-context.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/app/(routes)/mail/[folder]/page.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/package.json (2)
Learnt from: adiologydev
PR: Mail-0/Zero#871
File: docker-compose.yaml:2-21
Timestamp: 2025-05-04T23:13:26.825Z
Learning: Next.js requires certain environment variables during static site generation at build time, particularly those with the NEXT_PUBLIC_ prefix. When using Docker, these should be passed as build args, while sensitive values like API keys and secrets should ideally only be passed at runtime as environment variables.
Learnt from: adiologydev
PR: Mail-0/Zero#871
File: docker-compose.yaml:2-21
Timestamp: 2025-05-04T23:21:21.388Z
Learning: To completely disable SSG (Static Site Generation) in Next.js projects for Docker deployments, use 'force-dynamic' for App Router or getServerSideProps for Pages Router in all pages, and set output: 'standalone' in next.config.ts. This allows all environment variables to be passed at runtime instead of build time, improving security for sensitive values.
apps/mail/components/create/image-compression-settings.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/components/ui/nav-main.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/mail/mail-list.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/create/editor.tsx (2)
Learnt from: yaraslau-klimuk
PR: Mail-0/Zero#604
File: apps/mail/locales/en.json:366-389
Timestamp: 2025-04-06T18:28:21.659Z
Learning: The translation file for the editor's menu bar already includes an "orderedList" key with the value "Ordered List" as part of PR #604.
Learnt from: danteissaias
PR: Mail-0/Zero#902
File: apps/mail/components/connection/add.tsx:77-77
Timestamp: 2025-05-07T16:55:46.513Z
Learning: For the "Upgrade" link in AddConnectionDialog, using a proper <button> element instead of a <span> with onClick is recognized as an accessibility improvement but was deferred as out of scope in PR #902 (CSS variables PR).
apps/mail/components/mail/note-panel.tsx (3)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: danteissaias
PR: Mail-0/Zero#902
File: apps/mail/components/connection/add.tsx:77-77
Timestamp: 2025-05-07T16:55:46.513Z
Learning: For the "Upgrade" link in AddConnectionDialog, using a proper <button> element instead of a <span> with onClick is recognized as an accessibility improvement but was deferred as out of scope in PR #902 (CSS variables PR).
apps/mail/lib/utils.ts (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: snehendu098
PR: Mail-0/Zero#1323
File: apps/mail/lib/themes/theme-utils.ts:318-318
Timestamp: 2025-06-24T06:22:58.753Z
Learning: In the Mail-0/Zero theme system (apps/mail/lib/themes/theme-utils.ts), when color themes are being applied, all color values come in HSL format, so there's no need for additional format validation when converting colors with hslToHex().
apps/mail/hooks/use-optimistic-actions.ts (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/mail/mail.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/app/root.tsx (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.709Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
apps/mail/config/navigation.ts (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/components/ui/nav-user.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/vite.config.ts (2)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: adiologydev
PR: Mail-0/Zero#871
File: docker-compose.yaml:2-21
Timestamp: 2025-05-04T23:21:21.388Z
Learning: To completely disable SSG (Static Site Generation) in Next.js projects for Docker deployments, use 'force-dynamic' for App Router or getServerSideProps for Pages Router in all pages, and set output: 'standalone' in next.config.ts. This allows all environment variables to be passed at runtime instead of build time, improving security for sensitive values.
apps/mail/app/(routes)/settings/general/page.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/mail/components/context/command-palette-context.tsx (1)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/mail/components/mail/mail-display.tsx (4)
Learnt from: retrogtx
PR: Mail-0/Zero#1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: retrogtx
PR: Mail-0/Zero#1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.351Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: danteissaias
PR: Mail-0/Zero#458
File: apps/mail/lib/email-utils.ts:126-131
Timestamp: 2025-03-16T23:14:09.209Z
Learning: When working with mailto URLs in JavaScript/TypeScript, the `url.pathname` property correctly extracts the email address from a mailto URL (e.g., for "mailto:test@example.com?subject=Test", `url.pathname` will be "test@example.com").
Learnt from: danteissaias
PR: Mail-0/Zero#618
File: apps/mail/components/mail/mail-iframe.tsx:12-12
Timestamp: 2025-04-07T20:46:11.697Z
Learning: In the Mail-0/Zero application, sender emails are guaranteed to be non-empty when passed to components that handle them, making additional empty string validation unnecessary.
🧬 Code Graph Analysis (10)
apps/mail/app/(routes)/mail/page.tsx (7)
apps/mail/app/(routes)/mail/[folder]/page.tsx (1)
  • clientLoader (11-20)
apps/mail/app/(routes)/mail/create/page.tsx (1)
  • clientLoader (4-18)
apps/mail/app/(routes)/mail/compose/page.tsx (1)
  • clientLoader (13-31)
apps/mail/app/(routes)/settings/page.tsx (1)
  • clientLoader (3-5)
apps/mail/app/meta-files/not-found.ts (1)
  • clientLoader (1-3)
apps/mail/app/page.tsx (1)
  • clientLoader (6-10)
apps/mail/app/mailto-handler.ts (1)
  • clientLoader (249-284)
apps/mail/app/(routes)/settings/labels/page.tsx (3)
apps/mail/components/labels/label-dialog.tsx (1)
  • LabelDialog (36-168)
apps/mail/components/ui/button.tsx (1)
  • Button (71-71)
apps/mail/components/icons/icons.tsx (1)
  • Plus (1587-1598)
apps/mail/providers/server-providers.tsx (1)
apps/mail/providers/query-provider.tsx (1)
  • QueryProvider (106-142)
apps/mail/lib/notes-utils.ts (1)
apps/mail/lib/utils.ts (1)
  • formatDate (119-170)
apps/mail/components/context/thread-context.tsx (2)
apps/mail/components/icons/icons.tsx (6)
  • Reply (852-867)
  • ReplyAll (869-889)
  • Inbox (292-309)
  • Archive (391-413)
  • ArchiveX (973-989)
  • ExclamationCircle (415-432)
apps/mail/lib/utils.ts (1)
  • LABELS (19-26)
apps/mail/app/(routes)/mail/[folder]/page.tsx (1)
apps/mail/hooks/use-labels.ts (1)
  • useLabels (5-13)
apps/mail/components/create/image-compression-settings.tsx (1)
apps/mail/lib/image-compression.ts (1)
  • ImageQuality (1-1)
apps/mail/components/mail/mail-list.tsx (1)
apps/mail/lib/utils.ts (1)
  • formatDate (119-170)
apps/mail/app/root.tsx (1)
apps/mail/providers/server-providers.tsx (1)
  • ServerProviders (5-11)
apps/mail/components/ui/nav-user.tsx (1)
apps/mail/lib/utils.ts (1)
  • cn (51-51)
🪛 GitHub Actions: autofix.ci
apps/mail/package.json

[error] 1-1: pnpm install failed due to outdated lockfile. The pnpm-lock.yaml is not up to date with package.json. Dependency 'use-intl@^4.1.0' was removed but lockfile is frozen. Run 'pnpm install --no-frozen-lockfile' to fix.

🔇 Additional comments (97)
i18n.json (1)

31-31: 👍 Path update reflects new messages/ layout

The include glob matches the Paraglide setup – no issues spotted.

apps/mail/project.inlang/.gitignore (1)

1-1: Good call ignoring build cache

Keeps VCS clean, no objections.

apps/mail/project.inlang/project_id (1)

1-1: Project ID committed – confirm not secret

Assuming this identifier is intended to be public; if not, relocate to env vars.

apps/mail/react-router.config.ts (1)

4-4: SSR disabled as part of SPA migration.

This change correctly disables server-side rendering, which aligns with the broader refactor to move from SSR to client-side rendering mentioned in the AI summary.

apps/mail/app/entry.server.tsx (1)

1-2: Valid browser-specific server rendering API usage.

The switch to react-dom/server.browser with the TypeScript error suppression is appropriate for browser-specific rendering in SPA mode. The comment clearly explains the typing limitation.

apps/mail/components/mail/reply-composer.tsx (2)

14-14: Translation system migration looks correct.

The import of the new message object is properly added.


214-217: Toast message translations migrated correctly.

The success and error toast messages have been properly migrated from t() calls to m['key']() format with appropriate message keys.

apps/mail/app/(routes)/settings/appearance/page.tsx (2)

24-24: Message object import added correctly.

The import statement for the new translation system is properly positioned.


82-83: Comprehensive translation migration completed.

All translation calls have been successfully migrated from t('key') to m['key']() format across the component, including:

  • Toast messages for save operations
  • Page title and description
  • Form labels and button text
  • Theme selection options

The message keys follow consistent naming patterns and the implementation is complete.

Also applies to: 98-99, 102-102, 116-116, 130-130, 138-138, 144-144, 150-150

apps/mail/components/create/create-email.tsx (1)

15-15: Clean i18n migration to paraglide messages.

The migration from useTranslations hook to direct message object access is implemented correctly. The import and usage are consistent with the new internationalization approach.

Also applies to: 128-128

apps/mail/hooks/use-notes.tsx (1)

5-5: Proper i18n migration in useQuery error handling.

The migration from useTranslations to direct message access is correctly implemented. The error message retrieval follows the new pattern consistently.

Also applies to: 21-21

apps/mail/components/ui/app-sidebar.tsx (1)

45-45: Consistent i18n migration in sidebar component.

The replacement of useTranslations with direct message object access is properly implemented. The JSX usage follows the new pattern correctly.

Also applies to: 208-208

apps/mail/app/(routes)/settings/connections/page.tsx (1)

25-25: Comprehensive i18n migration in settings page.

The migration from useTranslations hook to direct message object access is thoroughly implemented across all localized strings in the component. All translation calls (toast messages, UI labels, dialog content, and button text) follow the new pattern consistently.

Also applies to: 46-46, 50-50, 59-60, 144-144, 158-158, 175-175, 178-178, 184-184, 189-189, 211-211, 223-223

apps/mail/components/mail/mail-iframe.tsx (1)

12-12: Clean i18n migration to paraglide messages.

The migration from useTranslations hook to direct m object imports is implemented correctly. All translation keys are preserved and the component logic remains unchanged.

Also applies to: 146-146, 152-153, 156-156

apps/mail/components/theme/theme-switcher.tsx (1)

12-12: Consistent i18n migration with proper dynamic key handling.

The translation migration is implemented correctly, including the dynamic theme key construction using template literals. All theme switching functionality is preserved.

Also applies to: 61-61, 69-69, 75-75, 81-81

apps/mail/hooks/driver/use-delete.ts (1)

7-7: Proper i18n migration in deletion hook.

The translation updates are correctly applied to toast notifications while preserving all deletion logic, error handling, and state management functionality.

Also applies to: 29-30, 34-34

apps/mail/app/(routes)/settings/shortcuts/page.tsx (1)

10-10: Well-handled i18n migration with dynamic message keys.

The translation migration properly handles both static page metadata and dynamic shortcut action labels. The complex logic for category-based vs. default action labels is preserved, with correct type assertions for dynamic message keys.

Also applies to: 26-27, 76-78

apps/mail/app/(routes)/settings/privacy/page.tsx (1)

21-21: Comprehensive i18n migration preserving all privacy settings functionality.

The translation migration covers all user-facing text including form labels, descriptions, toast messages, and button text. All privacy settings logic, form validation, and data persistence functionality remains unchanged.

Also applies to: 58-59, 72-73, 76-76, 90-90, 93-93, 110-110, 113-113, 133-133

apps/mail/app/(routes)/settings/[...settings]/page.tsx (1)

6-6: LGTM! Clean i18n migration implementation.

The import and usage of the new message object m is correctly implemented and consistent with the broader internationalization refactor described in the PR.

Also applies to: 29-29

apps/mail/messages/ko.json (1)

229-239: LGTM! Correct pluralization format migration.

The structured pluralization format properly declares input variables, selectors, and mapping for Korean plural forms. The actual Korean translations remain unchanged, ensuring consistency while adapting to the new localization framework.

Also applies to: 292-302

apps/mail/components/mail/thread-display.tsx (2)

44-44: LGTM! Correct import for new i18n approach.

The import of the message object m is properly added to support the migration from useTranslations hook to direct message function calls.


821-821: LGTM! Systematic i18n migration implementation.

All translation calls have been correctly migrated from the useTranslations hook pattern to direct message object function calls. The UI text for tooltips, buttons, and dropdown items maintains the same functionality while using the new localization approach.

Also applies to: 827-827, 890-890, 914-915, 931-931, 948-948, 973-973, 984-984, 988-988, 994-994, 1002-1002

apps/mail/messages/en.json (2)

166-187: LGTM! Correct structured pluralization format.

The migration to the new pluralization format is properly implemented with correct declarations, selectors, and plural category mappings. This maintains the same functionality while adapting to the new localization framework requirements.

Also applies to: 250-260, 313-323


2-2: Schema URL Verified
The schema URL (https://inlang.com/schema/inlang-message-format) returns an HTTP 200 response and valid JSON schema content as expected. No further action required.

apps/mail/messages/de.json (2)

2-2: Schema addition aligns with Inlang integration.

The addition of the Inlang message format schema supports the new internationalization framework migration.


166-176: Pluralization format standardization looks good.

The migration from simple ICU MessageFormat strings to structured pluralization objects is consistent across all entries. The German plural categories (0, one, other) are correctly applied, and the format aligns with the new Inlang-based message system.

Also applies to: 177-187, 250-260, 313-323

apps/mail/messages/zh_TW.json (1)

165-175: Pluralization format applied consistently.

The structured pluralization format is correctly applied. Note that Traditional Chinese doesn't have grammatical plural distinctions, so all plural categories use the same text, which is appropriate for framework consistency.

Also applies to: 176-186, 249-259, 312-322

apps/mail/messages/ca.json (1)

165-175: Catalan pluralization correctly implemented.

The structured pluralization format properly handles Catalan's grammatical plural forms (e.g., "adjunt" vs "adjunts"). The implementation is consistent with the new message framework.

Also applies to: 176-186, 249-259, 312-322

apps/mail/hooks/use-optimistic-actions.ts (2)

11-11: Import migration to new i18n system.

The import change from useTranslations to the static message object m aligns with the broader internationalization refactor to the Inlang-based system.


238-239: Translation function calls correctly migrated.

All toast message calls have been properly migrated from the t() function to the new m[]() syntax. The message keys remain consistent and the function call pattern is correct for the new static message object approach.

Also applies to: 268-268, 270-270, 272-272, 273-273, 348-348

apps/mail/messages/nl.json (4)

176-186: LGTM! Consistent pluralization format.

The fileCount pluralization follows the same structured format as attachmentCount, maintaining consistency.


249-259: LGTM! Proper noteCount pluralization.

The noteCount pluralization is correctly structured and maintains the Dutch translations appropriately.


312-322: LGTM! Consistent replies pluralization.

The replies pluralization follows the established pattern correctly.


165-175: Verify paraglide-js pluralization format and Dutch rules

All four entries (attachmentCount, fileCount, noteCount, replies) consistently use:

  • declarations: ["input count", "local countPlural = count: plural"]
  • selectors: ["countPlural"]
  • match cases: "countPlural=0", "countPlural=one", "countPlural=other"

Next steps:

  • Confirm paraglide-js supports this structured array format with explicit zero-case matches.
  • Dutch pluralization only distinguishes “one” (count = 1) and “other” (all other counts); decide whether the explicit “countPlural=0” branch is required or can be removed.
  • Verify at runtime that zero, one, and other produce the intended strings.
apps/mail/app/(routes)/settings/security/page.tsx (2)

13-13: LGTM! Proper i18n migration.

The import change from useTranslations to the direct message object m aligns with the paraglide-js migration.


48-91: LGTM! Consistent message function calls.

All translation calls have been properly migrated from t('key') to m['key']() format. The message keys appear to be correctly mapped and the syntax is consistent throughout.

apps/mail/components/context/thread-context.tsx (3)

35-35: LGTM! Proper import migration.

The import change is consistent with the paraglide-js migration pattern.


169-196: LGTM! Proper toast message migration.

The error and info toast messages have been correctly migrated to use the new message system.


272-476: LGTM! Comprehensive action label migration.

All action labels in the context menu have been properly migrated. The conditional logic for different message types (read/unread, starred/unstarred, important/unimportant) is preserved correctly with the new message system.

apps/mail/messages/zh_CN.json (2)

249-322: LGTM! Consistent pluralization format.

The noteCount and replies pluralization follow the same structured format, maintaining consistency across the file.


449-449: LGTM! Proper quote escaping.

The quote escaping in the defaultEmailDescription string is correctly implemented.

apps/mail/components/create/editor.tsx (3)

55-55: LGTM! Proper import migration.

The import change follows the established migration pattern.


196-295: LGTM! Comprehensive tooltip migration.

All editor toolbar tooltips (bold, italic, strikethrough, underline, link, bulletList, orderedList) have been properly migrated to use the new message system. The functionality remains unchanged.


305-327: LGTM! Dialog content properly migrated.

The link dialog title, description, and button labels have been correctly updated to use the new message system.

apps/mail/providers/server-providers.tsx (1)

5-8: LGTM! Simplification aligns with i18n refactor.

The removal of internationalization props and IntlProvider wrapper is consistent with the architectural shift to static message imports via @/paraglide/messages. This simplification correctly reflects the removal of server-side locale handling.

apps/mail/app/(auth)/login/error-message.tsx (2)

5-5: LGTM! Correct implementation of new message system.

The import change from useTranslations to the static m object aligns with the broader i18n refactor across the application.


25-25: LGTM! Proper migration to function-based messages.

The replacement of t(\errorMessages.${error}`)withm`errorMessages.${error}`` correctly implements the new message system while preserving the dynamic error key functionality.

Also applies to: 38-38

apps/mail/messages/es.json (1)

165-175: LGTM! Correct pluralization format migration.

The transformation from ICU MessageFormat to structured pluralization objects is implemented correctly. Spanish translations are accurate with proper plural forms: "anexo/anexos", "archivo/archivos", "nota/notas", and "respuesta/respuestas".

Also applies to: 176-186, 249-259, 312-322

apps/mail/messages/pt.json (1)

165-175: LGTM! Correct pluralization format for attachments, files, and notes.

The structured pluralization format is implemented correctly with accurate Portuguese translations for "anexo/anexos", "arquivo/arquivos", and "nota/notas".

Also applies to: 176-186, 249-259

apps/mail/wrangler.jsonc (2)

4-4: LGTM! Updated for static asset deployment.

The compatibility date update and new assets configuration correctly support SPA routing and static file serving, aligning with the removal of the previous worker.ts implementation.

Also applies to: 8-12


15-15: LGTM! Environment-specific naming added.

The addition of environment-specific names ("zero-local", "zero-staging", "zero-production") provides better identification for each deployment environment.

Also applies to: 22-22, 29-29

apps/mail/messages/hi.json (1)

249-259: ✅ Plural rules look good

Zero-state text intentionally uses a verb phrase; other branches expose the
count correctly. No change needed.

apps/mail/messages/fr.json (1)

249-259: 👍 noteCount zero-state is fine

Zero branch conveys an action (‘Ajoutez des notes’) and the others already show
the number. No change required.

apps/mail/messages/hu.json (1)

249-259: Looks OK

Zero branch is an action sentence; other branches show the number.
Nothing to change here.

apps/mail/components/ui/nav-main.tsx (1)

13-13: LGTM! Clean translation refactor implementation.

The migration from useTranslations to direct m object imports is well-executed. The tooltip content properly uses the function call syntax m[key](), and the direct usage of item.title aligns with the updated navigation configuration that now provides pre-translated strings.

Also applies to: 190-190, 203-203, 282-282, 286-286, 303-303, 313-313

apps/mail/components/mail/mail.tsx (1)

43-43: LGTM! Consistent translation refactor across UI elements.

All tooltip and UI text migrations to the m object pattern are correctly implemented with proper function call syntax.

Also applies to: 66-66, 514-514, 719-719, 736-736, 764-764, 817-817

apps/mail/messages/vi.json (1)

165-175: LGTM! Modernized pluralization format aligns with new message system.

The migration from ICU MessageFormat to the structured array-based pluralization format is correctly implemented. The new format explicitly declares the input variable and maps plural categories ("0", "one", "other") to Vietnamese strings while preserving all original translation content.

This structured approach provides better compatibility with the paraglide message system and maintains consistency across the internationalization framework.

Also applies to: 176-186, 249-259, 312-322

apps/mail/components/mail/mail-list.tsx (3)

54-54: LGTM: Clean internationalization migration

The migration from useTranslations hook to direct m object imports is implemented consistently throughout the component. All translation calls have been properly updated from t('key') to m['key']() format.


348-349: LGTM: Tooltip and label localization updated correctly

All tooltip content and labels have been successfully migrated to use the new message object pattern. The translation keys remain consistent and the function call syntax is correct.

Also applies to: 372-372, 393-393, 415-415, 527-527, 1070-1070


702-710: Minor JSX formatting improvement

The conditional rendering of draft internal date has been reformatted for better readability, with proper line breaks and consistent indentation.

apps/mail/messages/pl.json (1)

165-177: LGTM: Pluralization format migration completed successfully

The migration from ICU MessageFormat to structured JSON pluralization objects is implemented correctly. The new format with explicit declarations, selectors, and match cases provides better clarity while maintaining the correct Polish plural forms for all categories (0, one, few, many, other).

Also applies to: 178-190, 253-265, 318-330

apps/mail/lib/notes-utils.ts (2)

7-16: LGTM: Color labels properly localized

The migration to use localized message functions for color labels is implemented correctly. All colors properly use the m['common.notes.colors.*']() pattern for consistent internationalization.

Also applies to: 22-27, 36-41, 43-48, 50-55, 57-62


90-109: LGTM: Function signature simplified appropriately

The removal of the optional formatter parameter from formatRelativeTime aligns with the broader simplification of date formatting utilities and maintains consistent behavior.

apps/mail/messages/tr.json (1)

165-175: LGTM! Pluralization format changes are consistent

The pluralization format updates from ICU MessageFormat to the structured object format are correctly applied across all four keys (attachmentCount, fileCount, noteCount, and replies). The Turkish plural forms and text content remain unchanged, which is appropriate.

Also applies to: 176-186, 249-259, 312-322

apps/mail/project.inlang/settings.json (1)

1-33: LGTM! Inlang configuration is properly set up

The configuration correctly defines:

  • English as the base locale
  • 20 target locales matching the existing message files
  • Standard Inlang plugins for message formatting and function matching
  • Correct path pattern for localization files
apps/mail/messages/fa.json (1)

165-175: LGTM! Consistent pluralization format updates

The Persian localization file has been updated with the same structured pluralization format as other locale files. The plural forms are appropriately maintained for the Persian language.

Also applies to: 176-186, 249-259, 312-322

apps/mail/app/(routes)/mail/[folder]/page.tsx (3)

1-1: LGTM: Import simplification aligns with loading state removal.

The removal of Navigate and Loader2 imports is consistent with the simplification of loading states throughout this refactor.


25-25: Verify the UX impact of removing initial loading state.

Changing the initial state from null to true means the component will immediately render the MailLayout instead of showing a loading state, then potentially switch to "Folder not found" if validation fails. This could cause a brief flash of the mail layout before error state.

Consider if this provides the desired user experience, especially for slow network conditions where label validation might take time.


29-29: LGTM: Consistent hook usage pattern.

The switch from useQuery to the useLabels hook follows the established pattern for this refactor and maintains the same destructuring approach for data and isLoading.

apps/mail/config/navigation.ts (3)

22-22: LGTM: Consistent with i18n refactor.

The import of the message object m aligns with the broader migration from useTranslations hook to direct message object usage throughout the codebase.


26-26: LGTM: Type simplification reflects new i18n approach.

Changing the title property type from MessageKey | string to plain string correctly reflects that titles are now resolved at definition time via m['key']() calls rather than being message keys resolved at render time.


57-227: LGTM: Systematic migration to new message object pattern.

All navigation item titles have been consistently updated to use the m['key']() pattern, which aligns with the broader i18n refactor across the codebase. The changes maintain the same translation keys while switching to the new message resolution approach.

apps/mail/components/context/command-palette-context.tsx (4)

59-59: LGTM: Consistent with i18n migration.

The import of the message object m aligns with the systematic replacement of useTranslations hook throughout the codebase.


719-719: LGTM: Direct title usage after i18n refactor.

Using navItem.title directly is correct since navigation titles are now resolved at definition time via the m['key']() calls in the navigation configuration.


774-774: LGTM: Memo dependency updated correctly.

Removing t from the dependency array is appropriate since the translation function is no longer used in this component after the i18n refactor.


1891-1892: LGTM: Dialog accessibility labels using new i18n system.

The dialog title and description correctly use the new message object pattern while maintaining proper accessibility with VisuallyHidden wrapper.

apps/mail/vite.config.ts (3)

1-1: LGTM: Paraglide plugin import for new i18n system.

The import of paraglideVitePlugin is necessary for integrating the new Inlang-based localization framework that replaces the previous use-intl system.


16-16: LGTM: Cloudflare plugin configuration simplified.

Removing the viteEnvironment option simplifies the plugin configuration, which is appropriate if this option is no longer needed for the current setup.


43-47: LGTM: Proper Paraglide plugin configuration.

The plugin configuration with project, outdir, and strategy options follows the standard Paraglide setup pattern for cookie-based locale detection with base locale fallback.

apps/mail/lib/utils.ts (3)

119-119: LGTM: Function signature simplified.

Removing the function overloads and optional formatter parameter simplifies the API while maintaining the core functionality for both string and Date inputs.


124-135: LGTM: Unified date formatting logic.

The simplified logic handles both Date objects and string inputs in a single code path, which is easier to maintain than the previous overloaded approach.


98-180: LGTM: Minor whitespace cleanup.

The whitespace adjustments improve code readability without affecting functionality.

apps/mail/components/ui/nav-user.tsx (3)

39-39: LGTM: Clean migration to new i18n system

The import of the message object m from @/paraglide/messages is correctly added and aligns with the broader internationalization refactor across the codebase.


92-92: LGTM: Consistent translation key migration

All translation calls have been properly migrated from the useTranslations hook pattern t('key') to the new message object pattern m['key'](). The translation keys maintain semantic consistency and the function call syntax is correct.

Also applies to: 141-141, 249-249, 298-298, 305-305, 314-314, 322-322


575-575: Minor formatting improvements noted

The JSX formatting changes improve code consistency by:

  • Adding proper line spacing
  • Adjusting className formatting for better readability
  • Organizing button attributes more clearly

These are beneficial style improvements that don't affect functionality.

Also applies to: 577-577, 580-580, 591-598

apps/mail/components/mail/mail-display.tsx (4)

34-34: LGTM: Clean import organization and i18n migration

The imports have been properly reorganized:

  • Utility functions consolidated in a single import statement
  • New i18n message object imported correctly
  • Toast import added appropriately

All changes support the new internationalization system.

Also applies to: 51-51, 58-58


318-318: LGTM: Consistent mail category translation migration

All mail category labels have been properly migrated to the new translation system. The message keys follow a logical naming convention (common.mailCategories.*) and maintain semantic consistency with the original translations.

Also applies to: 323-323, 328-328, 333-333, 338-338, 343-343, 348-348, 353-353


892-896: Simplify callback logic for better readability

The handleCopySenderEmail callback has been simplified appropriately. The early return guard and direct clipboard API usage are clean and efficient.

Apply this additional simplification:

-  const handleCopySenderEmail = useCallback(async (personEmail: string) => {
-    if (!personEmail) return;
-
-    await navigator.clipboard.writeText(personEmail || '');
-    toast.success('Email copied to clipboard');
-  }, []);
+  const handleCopySenderEmail = useCallback(async (personEmail: string) => {
+    if (!personEmail) return;
+
+    await navigator.clipboard.writeText(personEmail);
+    toast.success('Email copied to clipboard');
+  }, []);

1297-1323: LGTM: Improved JSX formatting and dependency array

The JSX formatting improvements enhance readability with:

  • Better indentation and spacing
  • Cleaner className organization
  • Proper dependency array simplification in the renderPerson callback

These changes improve code maintainability without affecting functionality.

apps/mail/app/root.tsx (3)

18-18: LGTM: Clean transition to runtime-based internationalization

The import changes properly support the new i18n system:

  • getLocale from runtime for dynamic locale detection
  • Message object m for direct translation access

This aligns with removing server-side locale resolution.

Also applies to: 22-22


41-41: LGTM: Simplified client-side locale handling

The changes correctly implement runtime locale detection:

  • getLocale() provides dynamic language attribute for HTML element
  • ServerProviders simplified by removing i18n-related props

This approach eliminates server-side complexity while maintaining proper locale support.

Also applies to: 55-55


149-149: LGTM: Consistent migration of NotFound component translations

The translation calls in the NotFound component have been properly migrated to the new message object pattern:

  • m['pages.error.notFound.title']()
  • m['pages.error.notFound.description']()
  • m['pages.error.notFound.goBack']()

The message key structure follows logical naming conventions and maintains semantic clarity.

Also applies to: 151-151, 162-162

apps/mail/messages/lv.json (1)

165-175: LGTM! Pluralization format migration looks good.

The changes consistently migrate from compact ICU MessageFormat to the new explicit pluralization object format. The Latvian pluralization rules are correctly implemented with proper zero, one, and other cases, and the localized strings are appropriate.

Also applies to: 176-186, 249-259, 312-322

apps/mail/app/(routes)/settings/general/page.tsx (4)

42-42: LGTM! TimezoneSelect component migration is clean.

The removal of the translation function parameter and direct usage of m message functions is correctly implemented. The component now properly uses the new i18n system.

Also applies to: 74-74, 83-83


159-177: Form submission logic improvements look good.

The refactored submission logic properly updates the query cache optimistically, saves settings, and refetches data. The error handling correctly reverts the optimistic update on failure. The new toast messages using m functions are correctly implemented.


23-23: Old locale hooks removed – manual runtime verification needed

No occurrences of useLocale or useTranslations remain in any .ts/.tsx files.

Please manually test that:

  • Locale selection persists across sessions (e.g., via cookies or localStorage).
  • There are no hydration mismatches when switching locales on the client.

182-183: Verify external i18n message keys in @/paraglide/messages

I attempted to locate all keys used in apps/mail/app/(routes)/settings/general/page.tsx in the local apps/mail/messages folder and none were found—this is expected since the new system sources messages from the external @/paraglide/messages package. Please confirm that the package exports and types the following keys to avoid runtime errors:

  • common.actions.saveChanges
  • common.actions.saving
  • common.settings.failedToSave
  • common.settings.saved
  • pages.settings.general.autoRead
  • pages.settings.general.autoReadDescription
  • pages.settings.general.defaultEmailAlias
  • pages.settings.general.defaultEmailDescription
  • pages.settings.general.description
  • pages.settings.general.language
  • pages.settings.general.noResultsFound
  • pages.settings.general.selectDefaultEmail
  • pages.settings.general.selectLanguage
  • pages.settings.general.selectTimezone
  • pages.settings.general.timezone
  • pages.settings.general.title
  • pages.settings.general.zeroSignature
  • pages.settings.general.zeroSignatureDescription

@MrgSub
Copy link
Collaborator Author

MrgSub commented Jun 30, 2025

bugbot run

cursor[bot]

This comment was marked as outdated.

Copy link
Collaborator Author

MrgSub commented Jun 30, 2025

Merge activity

  • Jun 30, 6:37 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 30, 6:37 PM UTC: @MrgSub merged this pull request with Graphite.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Dynamic Keys Break Paraglide's Static Requirements

Dynamic key access using template literals for Paraglide messages (m[...]) is used. This is incompatible with Paraglide's design, which requires static keys for tree-shaking and type safety, and will cause runtime or TypeScript compilation errors.

apps/mail/app/(routes)/settings/shortcuts/page.tsx#L71-L76

const cat = categorySettings[idx];
label = cat
? `Show ${cat.name}`
: m[`pages.settings.shortcuts.actions.${shortcut.action}`]();
} else {
label = m[`pages.settings.shortcuts.actions.${shortcut.action}`]();

Fix in Cursor


Bug: Dynamic Keys Unsupported in Paraglide

The m[common.themes.${theme as 'dark' | 'light' | 'system'}]() expression attempts dynamic key access using a template literal with Paraglide's message system. This is unsupported, as Paraglide requires static string literal keys for proper resolution, type safety, and tree-shaking. This will cause runtime errors, particularly because the theme variable can be undefined (e.g., during initial render from useTheme()) or an unexpected value, leading to invalid message keys despite the unsafe type cast.

apps/mail/components/theme/theme-switcher.tsx#L58-L59

{theme === 'system' && <Laptop className="h-4 w-4" />}
{m[`common.themes.${theme as 'dark' | 'light' | 'system'}`]()}

Fix in Cursor


Was this report helpful? Give feedback by reacting with 👍 or 👎

@MrgSub MrgSub merged commit 2fbaf7b into staging Jun 30, 2025
8 checks passed
@MrgSub MrgSub deleted the 06-28-spa branch June 30, 2025 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant