Skip to content

Conversation

@myieye
Copy link
Collaborator

@myieye myieye commented Dec 5, 2025

Wraps hardcoded English strings in translation functions so they can be properly translated.

@github-actions github-actions bot added the 💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related label Dec 5, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 5, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

This PR introduces comprehensive application update functionality spanning backend event publishing, caching, permission checking, and frontend UI orchestration. It adds progress tracking, auto-update support detection, permission validation, and localized user-facing messages for the complete update workflow.

Changes

Cohort / File(s) Summary
Backend Core Update Logic
backend/FwLite/FwLiteMaui/Platforms/Windows/AppUpdateService.cs, backend/FwLite/FwLiteShared/AppUpdate/IPlatformUpdateService.cs, backend/FwLite/FwLiteShared/AppUpdate/UpdateChecker.cs
AppUpdateService constructor now accepts GlobalEventBus for event publishing; UpdateResult enum gains Disallowed member; UpdateChecker refactored with IMemoryCache caching, new AvailableUpdate record, improved flow separation (CheckForUpdate, TryUpdate, ApplyUpdate), and permission-based result handling.
Backend Event System
backend/FwLite/FwLiteShared/Events/AppUpdateEvent.cs, backend/FwLite/FwLiteShared/Events/AppUpdateProgressEvent.cs, backend/FwLite/FwLiteShared/Events/IFwEvent.cs
AppUpdateEvent extended with FwLiteRelease parameter; new AppUpdateProgressEvent class added for progress tracking; IFwEvent updated with AppUpdateProgress type mapping and enum member.
Backend DI & Service Registration
backend/FwLite/FwLiteShared/FwLiteSharedKernel.cs, backend/FwLite/FwLiteShared/Services/FwLiteProvider.cs, backend/FwLite/FwLiteShared/Services/UpdateService.cs
Memory cache registration added; UpdateService singleton registered; FwLiteProvider extended with DotnetService.UpdateService enum member and corresponding type mapping; new UpdateService class created with JS-invokable methods (CheckForUpdates, ApplyUpdate).
Backend Type Generation
backend/FwLite/FwLiteShared/TypeGen/ReinforcedFwLiteTypingConfig.cs
FwLiteRelease and AvailableUpdate types added to exported interfaces list.
Frontend Generated Types
frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/*, frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/*, frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/*, frontend/viewer/src/lib/dotnet-types/generated-types/LexCore/Entities/IFwLiteRelease.ts
New TypeScript interfaces generated: IAvailableUpdate, IAppUpdateProgressEvent, IUpdateService, IFwLiteRelease; UpdateResult enum extended with Disallowed member; FwEventType and DotnetService enums updated; index.ts files created for barrel exports.
Frontend UI Components
frontend/viewer/src/lib/updates/UpdateDialog.svelte, frontend/viewer/src/lib/updates/UpdateDialogContent.svelte
New UpdateDialog component wiring update service, event bus, and lifecycle management; UpdateDialogContent component rendering various update states (checking, available, installing, success/error outcomes) with version display and action buttons.
Frontend Integration Points
frontend/viewer/src/home/HomeView.svelte, frontend/viewer/src/project/ProjectSidebar.svelte, frontend/viewer/src/lib/notifications/NotificationOutlet.svelte
UpdateDialog integration added to HomeView and ProjectSidebar with state binding; NotificationOutlet refactored to use release URLs from events instead of platform-specific mapping.
Frontend Utilities & Services
frontend/viewer/src/lib/updates/utils.ts, frontend/viewer/src/lib/services/service-provider.ts, frontend/viewer/src/project/demo/in-memory-demo-api.ts
New utils module with openReleaseUrl, getReleaseUrl, and URL constants; service-provider extended with useUpdateService hook and registry mapping; demo API extended with mockUpdateService.
UI & Localization Updates
frontend/viewer/src/lib/components/ThemePicker.svelte, frontend/viewer/src/lib/troubleshoot/TroubleshootDialog.svelte, frontend/viewer/src/project/browse/filter/OpFilter.svelte
ThemePicker and OpFilter updated with i18n translation keys; TroubleshootDialog restructured with Platform display and improved layout.
Localization Files
frontend/viewer/src/locales/*.po
Extensive updates across en.po, es.po, fr.po, id.po, ko.po, ms.po, sw.po with new update-related translation keys (UpdateDialog, UpdateDialogContent entries) and reorganized source file references for existing translations.
Testing & Storybook
frontend/viewer/.storybook/vitest.setup.ts, frontend/viewer/src/stories/demo-story-error.ts, frontend/viewer/src/stories/updates/update-dialog-content.stories.svelte
Vitest setup extended to ignore DemoStoryError instances; new DemoStoryError class added; comprehensive Storybook stories created for UpdateDialogContent covering all update states and scenarios.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • UpdateChecker.cs: Multiple method signature changes, new caching logic with GetOrCreateAsync, refactored flow with CheckForUpdate/TryUpdate/ApplyUpdate separation, and permission-based result handling require careful verification of control flow and cache behavior.
  • AppUpdateEvent and AppUpdateProgressEvent: Changes to event signatures and new event types need validation for backward compatibility and proper integration with the event bus.
  • UpdateDialog.svelte and UpdateDialogContent.svelte: Complex promise state management, multiple async operations, conditional rendering logic, and icon/link wiring need thorough testing of all update outcome paths.
  • Localization files (.po): High-volume changes with source reference relocations and numerous new translation keys require verification that all strings are properly anchored to correct component files.
  • Service registration and DI wiring: Verify FwLiteProvider mappings, DotnetService enum additions, and JS interop integration are correctly aligned across backend and frontend.

Possibly related PRs

Suggested labels

💻 FW Lite, 📦 Lexbox, ✨ feature, 🌐 i18n

Suggested reviewers

  • hahn-kev
  • imnasnainaec

Poem

🐰 Hops through the updates with glee,
Progress bars blooming from cache to decree,
Dialogs dancing on frontend and back,
Events and promises guide the whole track,
From checkForUpdates to release so fine—
The system now gleams with update divine!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 2 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The pull request title is vague and generic. While it mentions wrapping strings in translation functions, it lacks specificity about which strings or components are affected, making it unclear what the primary changes encompass. Consider providing a more specific title that identifies the main area of changes, such as 'Add update dialog UI and wrap hardcoded strings in translations' or 'Implement update feature with i18n support'.
Description check ❓ Inconclusive The description is vague and incompletely addresses the changeset. While it mentions wrapping hardcoded strings in translation functions, the actual pull request introduces substantial new functionality including an UpdateDialog component, update checking/application logic, and numerous TypeScript type definitions—changes far beyond just translation wrapping. Update the description to comprehensively cover all major changes: new UpdateDialog components, UpdateService integration, update checking/application flow, event handling, and localization updates across multiple languages.

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Dec 5, 2025

UI unit Tests

  1 files  ±0   45 suites  ±0   18s ⏱️ ±0s
111 tests ±0  111 ✅ ±0  0 💤 ±0  0 ❌ ±0 
160 runs  ±0  160 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 01eadce. ± Comparison against base commit 055fe51.

♻️ This comment has been updated with latest results.

@argos-ci
Copy link

argos-ci bot commented Dec 5, 2025

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Dec 5, 2025, 11:26 AM

@github-actions
Copy link

github-actions bot commented Dec 5, 2025

C# Unit Tests

137 tests  ±0   137 ✅ ±0   19s ⏱️ ±0s
 21 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 01eadce. ± Comparison against base commit 055fe51.

♻️ This comment has been updated with latest results.

Copy link

@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: 0

🧹 Nitpick comments (4)
frontend/viewer/src/lib/troubleshoot/TroubleshootDialog.svelte (1)

42-58: Troubleshoot header localization and layout look good

Wrapping Application version, Platform, and Copy version in $t aligns this section with the rest of the localized UI, and the new layout makes version/platform clearer.

If you also care about fully localizing the clipboard contents, you might consider moving the "on" in ${config.appVersion} on ${config.os} into a translation with placeholders so languages can reorder or change that connector—but it’s fine as-is since it’s only in copied text.

frontend/viewer/src/project/ProjectSidebar.svelte (1)

57-59: Updates dialog wiring looks good; consider minor markup consistency

The new updateDialogOpen state, “Updates” menu item, and <UpdateDialog bind:open={updateDialogOpen}/> integration all look correct, and using $t\Updates`` fits the Lingui + Svelte i18n pattern. As per coding guidelines, this keeps the UI translatable and consistent.

For visual/semantic consistency with neighboring menu entries (which wrap labels in <span>), you might optionally wrap the Updates label the same way:

-        <Sidebar.MenuItem>
-          <Sidebar.MenuButton onclick={() => updateDialogOpen = true}>
-            <Icon icon="i-mdi-update" />
-            {$t`Updates`}
-          </Sidebar.MenuButton>
-        </Sidebar.MenuItem>
+        <Sidebar.MenuItem>
+          <Sidebar.MenuButton onclick={() => updateDialogOpen = true}>
+            <Icon icon="i-mdi-update" />
+            <span>{$t`Updates`}</span>
+          </Sidebar.MenuButton>
+        </Sidebar.MenuItem>

Also applies to: 188-193, 225-225

frontend/viewer/src/project/demo/in-memory-demo-api.ts (1)

68-82: LGTM - Mock update service appropriate for demo purposes.

The mock implementation correctly follows the IUpdateService interface and provides sensible demo behavior with a simulated delay.

Minor: Line 80 can be simplified since the function is already async:

  async applyUpdate(_update: IAvailableUpdate): Promise<UpdateResult> {
    await delay(2000);
-   return Promise.resolve(UpdateResult.Success);
+   return UpdateResult.Success;
  }
frontend/viewer/src/lib/updates/UpdateDialogContent.svelte (1)

47-79: Missing error handling for install promise rejection.

The installPromise await block has no {:catch} handler. If the installation fails with an exception (not just returning UpdateResult.Failed), the UI will not show any feedback to the user.

Consider adding an error catch block:

   {:then updateResult}
     <div class="flex items-center gap-4 p-4 rounded-lg bg-muted">
       <!-- existing result handling -->
     </div>
+  {:catch error}
+    <div class="flex items-center gap-4 p-4 rounded-lg bg-muted">
+      <Icon icon="i-mdi-alert-circle" />
+      <p>{$t`Update failed: ${error instanceof Error ? error.message : String(error)}`}</p>
+    </div>
   {/await}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 055fe51 and f08a365.

📒 Files selected for processing (41)
  • backend/FwLite/FwLiteMaui/Platforms/Windows/AppUpdateService.cs (3 hunks)
  • backend/FwLite/FwLiteShared/AppUpdate/IPlatformUpdateService.cs (1 hunks)
  • backend/FwLite/FwLiteShared/AppUpdate/UpdateChecker.cs (1 hunks)
  • backend/FwLite/FwLiteShared/Events/AppUpdateEvent.cs (1 hunks)
  • backend/FwLite/FwLiteShared/Events/AppUpdateProgressEvent.cs (1 hunks)
  • backend/FwLite/FwLiteShared/Events/IFwEvent.cs (2 hunks)
  • backend/FwLite/FwLiteShared/FwLiteSharedKernel.cs (2 hunks)
  • backend/FwLite/FwLiteShared/Services/FwLiteProvider.cs (3 hunks)
  • backend/FwLite/FwLiteShared/Services/UpdateService.cs (1 hunks)
  • backend/FwLite/FwLiteShared/TypeGen/ReinforcedFwLiteTypingConfig.cs (1 hunks)
  • frontend/viewer/.storybook/vitest.setup.ts (4 hunks)
  • frontend/viewer/src/home/HomeView.svelte (4 hunks)
  • frontend/viewer/src/lib/components/ThemePicker.svelte (1 hunks)
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/IAvailableUpdate.ts (1 hunks)
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/UpdateResult.ts (1 hunks)
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/index.ts (1 hunks)
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/FwEventType.ts (1 hunks)
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/IAppUpdateEvent.ts (1 hunks)
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/IAppUpdateProgressEvent.ts (1 hunks)
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/index.ts (1 hunks)
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/DotnetService.ts (1 hunks)
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/IUpdateService.ts (1 hunks)
  • frontend/viewer/src/lib/dotnet-types/generated-types/LexCore/Entities/IFwLiteRelease.ts (1 hunks)
  • frontend/viewer/src/lib/notifications/NotificationOutlet.svelte (1 hunks)
  • frontend/viewer/src/lib/services/service-provider.ts (3 hunks)
  • frontend/viewer/src/lib/troubleshoot/TroubleshootDialog.svelte (1 hunks)
  • frontend/viewer/src/lib/updates/UpdateDialog.svelte (1 hunks)
  • frontend/viewer/src/lib/updates/UpdateDialogContent.svelte (1 hunks)
  • frontend/viewer/src/lib/updates/utils.ts (1 hunks)
  • frontend/viewer/src/locales/en.po (41 hunks)
  • frontend/viewer/src/locales/es.po (41 hunks)
  • frontend/viewer/src/locales/fr.po (41 hunks)
  • frontend/viewer/src/locales/id.po (41 hunks)
  • frontend/viewer/src/locales/ko.po (41 hunks)
  • frontend/viewer/src/locales/ms.po (41 hunks)
  • frontend/viewer/src/locales/sw.po (41 hunks)
  • frontend/viewer/src/project/ProjectSidebar.svelte (5 hunks)
  • frontend/viewer/src/project/browse/filter/OpFilter.svelte (1 hunks)
  • frontend/viewer/src/project/demo/in-memory-demo-api.ts (3 hunks)
  • frontend/viewer/src/stories/demo-story-error.ts (1 hunks)
  • frontend/viewer/src/stories/updates/update-dialog-content.stories.svelte (1 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
frontend/**/*.{ts,tsx,svelte}

📄 CodeRabbit inference engine (AGENTS.md)

Use SvelteKit and TypeScript for frontend development

Files:

  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/index.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/UpdateResult.ts
  • frontend/viewer/src/stories/demo-story-error.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/IAvailableUpdate.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/LexCore/Entities/IFwLiteRelease.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/IUpdateService.ts
  • frontend/viewer/src/lib/updates/UpdateDialog.svelte
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/FwEventType.ts
  • frontend/viewer/src/lib/components/ThemePicker.svelte
  • frontend/viewer/src/project/browse/filter/OpFilter.svelte
  • frontend/viewer/src/lib/updates/utils.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/IAppUpdateProgressEvent.ts
  • frontend/viewer/src/lib/troubleshoot/TroubleshootDialog.svelte
  • frontend/viewer/src/project/demo/in-memory-demo-api.ts
  • frontend/viewer/src/lib/notifications/NotificationOutlet.svelte
  • frontend/viewer/src/lib/services/service-provider.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/index.ts
  • frontend/viewer/src/home/HomeView.svelte
  • frontend/viewer/src/lib/updates/UpdateDialogContent.svelte
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/IAppUpdateEvent.ts
  • frontend/viewer/src/stories/updates/update-dialog-content.stories.svelte
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/DotnetService.ts
  • frontend/viewer/src/project/ProjectSidebar.svelte
frontend/viewer/**/*.{svelte,ts,js}

📄 CodeRabbit inference engine (frontend/viewer/AGENTS.md)

Use SvelteKit with Vite as the framework for this web UI application

Files:

  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/index.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/UpdateResult.ts
  • frontend/viewer/src/stories/demo-story-error.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/IAvailableUpdate.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/LexCore/Entities/IFwLiteRelease.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/IUpdateService.ts
  • frontend/viewer/src/lib/updates/UpdateDialog.svelte
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/FwEventType.ts
  • frontend/viewer/src/lib/components/ThemePicker.svelte
  • frontend/viewer/src/project/browse/filter/OpFilter.svelte
  • frontend/viewer/src/lib/updates/utils.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/IAppUpdateProgressEvent.ts
  • frontend/viewer/src/lib/troubleshoot/TroubleshootDialog.svelte
  • frontend/viewer/src/project/demo/in-memory-demo-api.ts
  • frontend/viewer/src/lib/notifications/NotificationOutlet.svelte
  • frontend/viewer/src/lib/services/service-provider.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/index.ts
  • frontend/viewer/src/home/HomeView.svelte
  • frontend/viewer/src/lib/updates/UpdateDialogContent.svelte
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/IAppUpdateEvent.ts
  • frontend/viewer/src/stories/updates/update-dialog-content.stories.svelte
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/DotnetService.ts
  • frontend/viewer/src/project/ProjectSidebar.svelte
frontend/viewer/**/*.{svelte,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (frontend/viewer/AGENTS.md)

Use Lingui with svelte-i18n-lingui for internationalization (i18n)

Files:

  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/index.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/UpdateResult.ts
  • frontend/viewer/src/stories/demo-story-error.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/IAvailableUpdate.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/LexCore/Entities/IFwLiteRelease.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/IUpdateService.ts
  • frontend/viewer/src/lib/updates/UpdateDialog.svelte
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/FwEventType.ts
  • frontend/viewer/src/lib/components/ThemePicker.svelte
  • frontend/viewer/src/project/browse/filter/OpFilter.svelte
  • frontend/viewer/src/lib/updates/utils.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/IAppUpdateProgressEvent.ts
  • frontend/viewer/src/lib/troubleshoot/TroubleshootDialog.svelte
  • frontend/viewer/src/project/demo/in-memory-demo-api.ts
  • frontend/viewer/src/lib/notifications/NotificationOutlet.svelte
  • frontend/viewer/src/lib/services/service-provider.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/index.ts
  • frontend/viewer/src/home/HomeView.svelte
  • frontend/viewer/src/lib/updates/UpdateDialogContent.svelte
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/IAppUpdateEvent.ts
  • frontend/viewer/src/stories/updates/update-dialog-content.stories.svelte
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/DotnetService.ts
  • frontend/viewer/src/project/ProjectSidebar.svelte
frontend/**/*.svelte

📄 CodeRabbit inference engine (frontend/AGENTS.md)

frontend/**/*.svelte: Use DaisyUI classes for consistent styling in Svelte components
Import icons from $lib/icons/ for icon components

Files:

  • frontend/viewer/src/lib/updates/UpdateDialog.svelte
  • frontend/viewer/src/lib/components/ThemePicker.svelte
  • frontend/viewer/src/project/browse/filter/OpFilter.svelte
  • frontend/viewer/src/lib/troubleshoot/TroubleshootDialog.svelte
  • frontend/viewer/src/lib/notifications/NotificationOutlet.svelte
  • frontend/viewer/src/home/HomeView.svelte
  • frontend/viewer/src/lib/updates/UpdateDialogContent.svelte
  • frontend/viewer/src/stories/updates/update-dialog-content.stories.svelte
  • frontend/viewer/src/project/ProjectSidebar.svelte
frontend/viewer/**/*.svelte

📄 CodeRabbit inference engine (frontend/viewer/AGENTS.md)

Use ShadCN-Svelte (Tailwind-based) for UI components

Files:

  • frontend/viewer/src/lib/updates/UpdateDialog.svelte
  • frontend/viewer/src/lib/components/ThemePicker.svelte
  • frontend/viewer/src/project/browse/filter/OpFilter.svelte
  • frontend/viewer/src/lib/troubleshoot/TroubleshootDialog.svelte
  • frontend/viewer/src/lib/notifications/NotificationOutlet.svelte
  • frontend/viewer/src/home/HomeView.svelte
  • frontend/viewer/src/lib/updates/UpdateDialogContent.svelte
  • frontend/viewer/src/stories/updates/update-dialog-content.stories.svelte
  • frontend/viewer/src/project/ProjectSidebar.svelte
frontend/viewer/src/lib/**/*.svelte

📄 CodeRabbit inference engine (frontend/viewer/AGENTS.md)

Place shared components and the entry editor in src/lib/ directory

Files:

  • frontend/viewer/src/lib/updates/UpdateDialog.svelte
  • frontend/viewer/src/lib/components/ThemePicker.svelte
  • frontend/viewer/src/lib/troubleshoot/TroubleshootDialog.svelte
  • frontend/viewer/src/lib/notifications/NotificationOutlet.svelte
  • frontend/viewer/src/lib/updates/UpdateDialogContent.svelte
backend/**/*.cs

📄 CodeRabbit inference engine (AGENTS.md)

Use .NET 9, C# for backend development with Entity Framework Core and GraphQL (Hot Chocolate)

backend/**/*.cs: Use async/await for asynchronous operations in C# code; avoid using .Result or .Wait()
Prefer Records for DTOs and immutable data structures in C#

Files:

  • backend/FwLite/FwLiteShared/AppUpdate/IPlatformUpdateService.cs
  • backend/FwLite/FwLiteShared/Events/IFwEvent.cs
  • backend/FwLite/FwLiteShared/Events/AppUpdateEvent.cs
  • backend/FwLite/FwLiteShared/Events/AppUpdateProgressEvent.cs
  • backend/FwLite/FwLiteShared/TypeGen/ReinforcedFwLiteTypingConfig.cs
  • backend/FwLite/FwLiteShared/FwLiteSharedKernel.cs
  • backend/FwLite/FwLiteShared/Services/FwLiteProvider.cs
  • backend/FwLite/FwLiteShared/Services/UpdateService.cs
  • backend/FwLite/FwLiteShared/AppUpdate/UpdateChecker.cs
  • backend/FwLite/FwLiteMaui/Platforms/Windows/AppUpdateService.cs
backend/**/*Kernel.cs

📄 CodeRabbit inference engine (backend/AGENTS.md)

Register services in *Kernel.cs files (e.g., LexBoxKernel.cs) for dependency injection configuration

Files:

  • backend/FwLite/FwLiteShared/FwLiteSharedKernel.cs
backend/**/{*Kernel.cs,Program.cs}

📄 CodeRabbit inference engine (backend/AGENTS.md)

Use AddScoped for request-scoped services and AddSingleton for app-wide services in dependency injection registration

Files:

  • backend/FwLite/FwLiteShared/FwLiteSharedKernel.cs
🧠 Learnings (34)
📓 Common learnings
Learnt from: imnasnainaec
Repo: sillsdev/languageforge-lexbox PR: 1867
File: platform.bible-extension/src/main.ts:239-246
Timestamp: 2025-07-31T19:10:41.178Z
Learning: In the sillsdev/languageforge-lexbox repository, user imnasnainaec prefers to defer code improvements when there are related TODO comments indicating planned refactoring work, choosing to bundle related changes together rather than making incremental improvements that would need to be modified again during the larger refactoring.
📚 Learning: 2025-07-02T13:55:24.775Z
Learnt from: myieye
Repo: sillsdev/languageforge-lexbox PR: 1800
File: frontend/viewer/src/stories/notifications/notification.stories.svelte:82-82
Timestamp: 2025-07-02T13:55:24.775Z
Learning: In Storybook stories and test/demo files, intentional error throwing (including unhandled promise rejections) is acceptable and expected behavior when testing error handling systems. Buttons labeled "Throw Exception" or similar are designed to trigger errors to verify that global error handlers work correctly.

Applied to files:

  • frontend/viewer/src/stories/demo-story-error.ts
  • frontend/viewer/.storybook/vitest.setup.ts
📚 Learning: 2025-07-22T09:19:37.386Z
Learnt from: rmunn
Repo: sillsdev/languageforge-lexbox PR: 1836
File: frontend/viewer/src/lib/components/audio/AudioDialog.svelte:25-25
Timestamp: 2025-07-22T09:19:37.386Z
Learning: In the sillsdev/languageforge-lexbox project, when file size limits or other constants need to be shared between C# backend and TypeScript frontend code, prefer exposing them through Reinforced.Typings type generation rather than hardcoding the values separately. This ensures consistency and prevents discrepancies when values change.

Applied to files:

  • frontend/viewer/src/lib/dotnet-types/generated-types/LexCore/Entities/IFwLiteRelease.ts
  • backend/FwLite/FwLiteShared/TypeGen/ReinforcedFwLiteTypingConfig.cs
📚 Learning: 2025-12-05T10:28:57.540Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: frontend/viewer/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:57.540Z
Learning: Applies to frontend/viewer/**/components.json : Maintain ShadCN-Svelte configuration in `components.json`

Applied to files:

  • frontend/viewer/src/lib/updates/UpdateDialog.svelte
  • frontend/viewer/src/lib/components/ThemePicker.svelte
  • frontend/viewer/src/home/HomeView.svelte
  • frontend/viewer/src/lib/updates/UpdateDialogContent.svelte
  • frontend/viewer/src/project/ProjectSidebar.svelte
📚 Learning: 2025-12-05T10:28:57.540Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: frontend/viewer/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:57.540Z
Learning: Applies to frontend/viewer/src/lib/**/*.svelte : Place shared components and the entry editor in `src/lib/` directory

Applied to files:

  • frontend/viewer/src/lib/updates/UpdateDialog.svelte
  • frontend/viewer/src/lib/components/ThemePicker.svelte
  • frontend/viewer/src/home/HomeView.svelte
  • frontend/viewer/src/lib/updates/UpdateDialogContent.svelte
  • frontend/viewer/src/project/ProjectSidebar.svelte
📚 Learning: 2025-08-14T12:50:25.135Z
Learnt from: myieye
Repo: sillsdev/languageforge-lexbox PR: 1906
File: frontend/viewer/src/lib/components/ui/dialog-shared/dialog-shared-root.svelte:3-3
Timestamp: 2025-08-14T12:50:25.135Z
Learning: In the dialog-shared-root.svelte component, the module-level `openDialogs` state is intentionally shared across all component instances to coordinate dialog stacking and overlay behavior across the entire application. This enables proper z-index management where newer dialogs appear on top and only the bottom dialog shows its overlay.

Applied to files:

  • frontend/viewer/src/lib/updates/UpdateDialog.svelte
  • frontend/viewer/src/lib/troubleshoot/TroubleshootDialog.svelte
  • frontend/viewer/src/home/HomeView.svelte
  • frontend/viewer/src/project/ProjectSidebar.svelte
📚 Learning: 2025-12-05T10:28:57.540Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: frontend/viewer/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:57.540Z
Learning: Applies to frontend/viewer/**/*.{svelte,ts,tsx,js,jsx} : Use Lingui with svelte-i18n-lingui for internationalization (i18n)

Applied to files:

  • frontend/viewer/src/lib/updates/UpdateDialog.svelte
  • frontend/viewer/src/lib/components/ThemePicker.svelte
  • frontend/viewer/src/project/browse/filter/OpFilter.svelte
  • frontend/viewer/src/locales/fr.po
  • frontend/viewer/src/locales/en.po
  • frontend/viewer/src/lib/updates/UpdateDialogContent.svelte
  • frontend/viewer/src/project/ProjectSidebar.svelte
  • frontend/viewer/src/locales/sw.po
📚 Learning: 2025-12-05T10:28:57.540Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: frontend/viewer/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:57.540Z
Learning: Applies to frontend/viewer/**/*.svelte : Use ShadCN-Svelte (Tailwind-based) for UI components

Applied to files:

  • frontend/viewer/src/lib/updates/UpdateDialog.svelte
  • frontend/viewer/src/lib/components/ThemePicker.svelte
  • frontend/viewer/src/home/HomeView.svelte
  • frontend/viewer/src/lib/updates/UpdateDialogContent.svelte
  • frontend/viewer/src/project/ProjectSidebar.svelte
📚 Learning: 2025-12-05T10:28:57.540Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: frontend/viewer/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:57.540Z
Learning: Applies to frontend/viewer/**/*.{test,spec}.{ts,js} : Use Vitest for unit and component testing

Applied to files:

  • frontend/viewer/.storybook/vitest.setup.ts
📚 Learning: 2025-12-05T10:28:57.540Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: frontend/viewer/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:57.540Z
Learning: Applies to frontend/viewer/tests/**/*.ts : Use Playwright for E2E testing

Applied to files:

  • frontend/viewer/.storybook/vitest.setup.ts
📚 Learning: 2025-12-05T10:28:57.540Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: frontend/viewer/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:57.540Z
Learning: Use Storybook for component documentation and development (stored in `.storybook/`)

Applied to files:

  • frontend/viewer/.storybook/vitest.setup.ts
  • frontend/viewer/src/stories/updates/update-dialog-content.stories.svelte
📚 Learning: 2025-12-05T10:28:57.540Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: frontend/viewer/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:57.540Z
Learning: Applies to frontend/viewer/**/lingui.config.ts : Maintain i18n configuration in `lingui.config.ts`

Applied to files:

  • frontend/viewer/src/lib/components/ThemePicker.svelte
  • frontend/viewer/src/locales/fr.po
  • frontend/viewer/src/locales/en.po
  • frontend/viewer/src/locales/ms.po
📚 Learning: 2025-06-18T05:13:00.591Z
Learnt from: hahn-kev
Repo: sillsdev/languageforge-lexbox PR: 1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

Applied to files:

  • frontend/viewer/src/project/browse/filter/OpFilter.svelte
  • frontend/viewer/src/locales/fr.po
  • frontend/viewer/src/locales/ko.po
  • frontend/viewer/src/locales/en.po
  • frontend/viewer/src/locales/id.po
  • frontend/viewer/src/locales/es.po
  • frontend/viewer/src/locales/ms.po
  • frontend/viewer/src/locales/sw.po
📚 Learning: 2025-12-05T10:28:57.540Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: frontend/viewer/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:57.540Z
Learning: Applies to frontend/viewer/src/locales/**/*.json : Store i18n translation files as JSON in `src/locales/`

Applied to files:

  • frontend/viewer/src/locales/fr.po
📚 Learning: 2025-10-06T12:48:36.601Z
Learnt from: myieye
Repo: sillsdev/languageforge-lexbox PR: 2025
File: frontend/viewer/src/locales/sw.po:146-149
Timestamp: 2025-10-06T12:48:36.601Z
Learning: Do not review or comment on `.po` translation files (e.g., files in `frontend/viewer/src/locales/`) in the languageforge-lexbox repository, as translations are managed by Crowdin.

Applied to files:

  • frontend/viewer/src/locales/fr.po
  • frontend/viewer/src/locales/ko.po
  • frontend/viewer/src/locales/en.po
📚 Learning: 2025-08-15T07:32:23.641Z
Learnt from: hahn-kev
Repo: sillsdev/languageforge-lexbox PR: 1923
File: frontend/viewer/src/locales/en.po:845-848
Timestamp: 2025-08-15T07:32:23.641Z
Learning: Do not suggest specific translations for missing msgstr entries in locale files. Only identify that translations are missing without proposing the actual translated text.

Applied to files:

  • frontend/viewer/src/locales/fr.po
  • frontend/viewer/src/locales/ko.po
  • frontend/viewer/src/locales/en.po
  • frontend/viewer/src/locales/id.po
  • frontend/viewer/src/locales/es.po
  • frontend/viewer/src/locales/ms.po
  • frontend/viewer/src/locales/sw.po
📚 Learning: 2025-03-06T03:30:17.687Z
Learnt from: hahn-kev
Repo: sillsdev/languageforge-lexbox PR: 1522
File: frontend/viewer/src/lib/services/service-provider.ts:41-48
Timestamp: 2025-03-06T03:30:17.687Z
Learning: In the LexboxServiceProvider class, the default implementation of `nextEventAsync()` for the JsEventListener service intentionally returns an unresolved Promise (`new Promise<IFwEvent>(() => {})`) rather than a resolved one. This is a deliberate design choice related to event handling.

Applied to files:

  • frontend/viewer/src/project/demo/in-memory-demo-api.ts
📚 Learning: 2025-12-05T10:27:49.254Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: backend/AGENTS.md:0-0
Timestamp: 2025-12-05T10:27:49.254Z
Learning: Applies to backend/LexData/**/*.cs : Store DbContext in the LexData project and use IQueryable projections to avoid loading full entities

Applied to files:

  • frontend/viewer/src/project/demo/in-memory-demo-api.ts
📚 Learning: 2025-12-05T10:28:27.128Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: backend/FwLite/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:27.128Z
Learning: Applies to backend/FwLite/LcmCrdt/Changes/*.cs : For new CRDT fields, use JsonPatchChange<T> for simple field changes (simplest), or create dedicated change class for complex operations. MUST register in LcmCrdtKernel.cs → ConfigureCrdt()

Applied to files:

  • backend/FwLite/FwLiteShared/Events/IFwEvent.cs
📚 Learning: 2025-12-05T10:28:27.128Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: backend/FwLite/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:27.128Z
Learning: Applies to backend/FwLite/MiniLcm/SyncHelpers/*.cs : Add diff logic for new fields in MiniLcm/SyncHelpers/ files, particularly checking EntrySync.cs to add to EntryDiffToUpdate()

Applied to files:

  • backend/FwLite/FwLiteShared/Events/AppUpdateEvent.cs
  • backend/FwLite/FwLiteShared/TypeGen/ReinforcedFwLiteTypingConfig.cs
  • backend/FwLite/FwLiteShared/Services/UpdateService.cs
  • backend/FwLite/FwLiteShared/AppUpdate/UpdateChecker.cs
📚 Learning: 2025-07-07T06:02:41.194Z
Learnt from: hahn-kev
Repo: sillsdev/languageforge-lexbox PR: 1804
File: backend/FwLite/LcmCrdt/CurrentProjectService.cs:18-19
Timestamp: 2025-07-07T06:02:41.194Z
Learning: In the CurrentProjectService class, the service locator pattern is intentionally used to retrieve IDbContextFactory<LcmCrdtDbContext> and EntrySearchServiceFactory because these services indirectly depend on CurrentProjectService to have the current project set, creating a circular dependency. This is an acceptable use of service locator to break the circular dependency while keeping project context responsibility consolidated.

Applied to files:

  • frontend/viewer/src/lib/services/service-provider.ts
📚 Learning: 2025-12-05T10:28:27.128Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: backend/FwLite/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:27.128Z
Learning: Applies to backend/FwLite/MiniLcm/Models/*.cs : When adding a new field/property to the model (Entry, Sense, etc.), add the property with appropriate type, add to Copy() method, add to GetReferences() if it references another entity, and add to RemoveReference() if it can be orphaned in MiniLcm/Models/

Applied to files:

  • backend/FwLite/FwLiteShared/TypeGen/ReinforcedFwLiteTypingConfig.cs
📚 Learning: 2025-12-05T10:28:27.128Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: backend/FwLite/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:27.128Z
Learning: Applies to backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs : When adding a new field to the model, update FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs to map to/from LCM (FieldWorks) data structures

Applied to files:

  • backend/FwLite/FwLiteShared/TypeGen/ReinforcedFwLiteTypingConfig.cs
📚 Learning: 2025-12-05T10:28:05.025Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: backend/FwHeadless/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:05.025Z
Learning: Register all services via dependency injection in `Program.cs` and `FwHeadlessKernel.cs`; ensure no services are instantiated outside of the DI container

Applied to files:

  • backend/FwLite/FwLiteShared/FwLiteSharedKernel.cs
📚 Learning: 2025-12-05T10:27:49.254Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: backend/AGENTS.md:0-0
Timestamp: 2025-12-05T10:27:49.254Z
Learning: Applies to backend/**/{*Kernel.cs,Program.cs} : Use AddScoped for request-scoped services and AddSingleton for app-wide services in dependency injection registration

Applied to files:

  • backend/FwLite/FwLiteShared/FwLiteSharedKernel.cs
📚 Learning: 2025-12-05T10:28:36.655Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: backend/LexBoxApi/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:36.655Z
Learning: Applies to backend/LexBoxApi/**/LexBoxKernel.cs : Register services and dependencies in `LexBoxKernel.cs` for dependency injection

Applied to files:

  • backend/FwLite/FwLiteShared/FwLiteSharedKernel.cs
📚 Learning: 2025-12-05T10:27:49.254Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: backend/AGENTS.md:0-0
Timestamp: 2025-12-05T10:27:49.254Z
Learning: Applies to backend/**/*Kernel.cs : Register services in *Kernel.cs files (e.g., LexBoxKernel.cs) for dependency injection configuration

Applied to files:

  • backend/FwLite/FwLiteShared/FwLiteSharedKernel.cs
📚 Learning: 2025-06-02T14:27:02.745Z
Learnt from: myieye
Repo: sillsdev/languageforge-lexbox PR: 1720
File: frontend/viewer/src/locales/es.json:1786-1790
Timestamp: 2025-06-02T14:27:02.745Z
Learning: Spanish locale file (frontend/viewer/src/locales/es.json) contains generated code that may have null line numbers in origin entries due to limitations in the code generation process.

Applied to files:

  • frontend/viewer/src/locales/es.po
📚 Learning: 2025-06-24T03:13:09.152Z
Learnt from: hahn-kev
Repo: sillsdev/languageforge-lexbox PR: 1770
File: backend/FwLite/FwLiteShared/AppUpdate/UpdateChecker.cs:27-47
Timestamp: 2025-06-24T03:13:09.152Z
Learning: In UpdateChecker.cs, the LastUpdateCheck timestamp is intentionally set after every HTTP call attempt (successful or failed) to enforce the 8-hour update check interval regardless of network issues. This design choice prevents retry attempts and reduces server load.

Applied to files:

  • backend/FwLite/FwLiteShared/AppUpdate/UpdateChecker.cs
📚 Learning: 2025-06-24T03:15:09.437Z
Learnt from: hahn-kev
Repo: sillsdev/languageforge-lexbox PR: 1770
File: backend/FwLite/FwLiteMaui/Platforms/Windows/AppUpdateService.cs:21-21
Timestamp: 2025-06-24T03:15:09.437Z
Learning: In the FwLite Windows app update system, update checks only occur once on application startup, so there's typically only one notification at a time in the NotificationCompletionSources dictionary.

Applied to files:

  • backend/FwLite/FwLiteMaui/Platforms/Windows/AppUpdateService.cs
📚 Learning: 2025-12-05T10:28:45.578Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:45.578Z
Learning: Applies to frontend/**/*.svelte : Import icons from `$lib/icons/` for icon components

Applied to files:

  • frontend/viewer/src/project/ProjectSidebar.svelte
📚 Learning: 2025-12-05T10:27:39.967Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T10:27:39.967Z
Learning: Applies to frontend/**/*.{ts,tsx,svelte} : Use SvelteKit and TypeScript for frontend development

Applied to files:

  • frontend/viewer/src/project/ProjectSidebar.svelte
📚 Learning: 2025-12-05T10:28:45.578Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:45.578Z
Learning: Applies to frontend/**/*.svelte : Use DaisyUI classes for consistent styling in Svelte components

Applied to files:

  • frontend/viewer/src/project/ProjectSidebar.svelte
📚 Learning: 2025-12-05T10:28:57.540Z
Learnt from: CR
Repo: sillsdev/languageforge-lexbox PR: 0
File: frontend/viewer/AGENTS.md:0-0
Timestamp: 2025-12-05T10:28:57.540Z
Learning: Applies to frontend/viewer/**/*.{svelte,ts,js} : Use SvelteKit with Vite as the framework for this web UI application

Applied to files:

  • frontend/viewer/src/project/ProjectSidebar.svelte
🧬 Code graph analysis (12)
frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/IAvailableUpdate.ts (1)
frontend/viewer/src/lib/dotnet-types/generated-types/LexCore/Entities/IFwLiteRelease.ts (1)
  • IFwLiteRelease (6-10)
frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/IUpdateService.ts (1)
frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/IAvailableUpdate.ts (1)
  • IAvailableUpdate (8-12)
frontend/viewer/.storybook/vitest.setup.ts (1)
frontend/viewer/src/stories/demo-story-error.ts (1)
  • DemoStoryError (2-2)
frontend/viewer/src/lib/updates/utils.ts (3)
frontend/viewer/src/lib/dotnet-types/generated-types/LexCore/Entities/IFwLiteRelease.ts (1)
  • IFwLiteRelease (6-10)
frontend/viewer/src/lib/services/url-opener.ts (1)
  • openUrl (5-19)
frontend/viewer/src/lib/services/service-provider.ts (1)
  • useFwLiteConfig (116-118)
frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/IAppUpdateProgressEvent.ts (1)
frontend/viewer/src/lib/dotnet-types/generated-types/LexCore/Entities/IFwLiteRelease.ts (1)
  • IFwLiteRelease (6-10)
frontend/viewer/src/project/demo/in-memory-demo-api.ts (2)
frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/IUpdateService.ts (1)
  • IUpdateService (9-13)
frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/IAvailableUpdate.ts (1)
  • IAvailableUpdate (8-12)
backend/FwLite/FwLiteShared/Events/IFwEvent.cs (1)
backend/FwLite/FwLiteShared/Events/AppUpdateProgressEvent.cs (1)
  • AppUpdateProgressEvent (5-11)
backend/FwLite/FwLiteShared/Events/AppUpdateEvent.cs (1)
backend/FwLite/FwLiteShared/Events/GlobalEventBus.cs (1)
  • IFwEvent (24-27)
frontend/viewer/src/lib/services/service-provider.ts (1)
frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/IUpdateService.ts (1)
  • IUpdateService (9-13)
backend/FwLite/FwLiteShared/FwLiteSharedKernel.cs (1)
backend/FwLite/FwLiteShared/Services/UpdateService.cs (1)
  • UpdateService (7-21)
backend/FwLite/FwLiteShared/Services/FwLiteProvider.cs (1)
backend/FwLite/FwLiteShared/Services/UpdateService.cs (1)
  • UpdateService (7-21)
backend/FwLite/FwLiteShared/AppUpdate/UpdateChecker.cs (4)
backend/FwLite/FwLiteShared/Events/GlobalEventBus.cs (2)
  • GlobalEventBus (8-34)
  • PublishEvent (16-22)
backend/FwLite/FwLiteShared/AppUpdate/IPlatformUpdateService.cs (2)
  • Task (11-11)
  • Task (12-12)
backend/FwLite/FwLiteShared/AppUpdate/CorePlatformUpdateService.cs (2)
  • Task (26-29)
  • Task (31-34)
backend/FwLite/FwLiteShared/Events/AppUpdateEvent.cs (1)
  • AppUpdateEvent (6-12)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Build API / publish-api
  • GitHub Check: Build UI / publish-ui
  • GitHub Check: check-and-lint
  • GitHub Check: Analyze (csharp)
  • GitHub Check: frontend-component-unit-tests
  • GitHub Check: frontend
  • GitHub Check: Build FW Lite and run tests
🔇 Additional comments (47)
frontend/viewer/src/stories/demo-story-error.ts (1)

1-2: LGTM!

The DemoStoryError class is simple and well-suited for its purpose. The comment clearly explains that this error type is designed to be thrown in story tests without causing test failures. Based on learnings, intentional error throwing in Storybook stories is acceptable for testing error handling systems.

frontend/viewer/.storybook/vitest.setup.ts (5)

5-5: LGTM!

The import path is correct and the DemoStoryError class is properly imported for use in the error handling logic below.


43-49: LGTM!

The console.error handler correctly identifies and ignores DemoStoryError instances. The instanceof check on line 45 will properly match instances of DemoStoryError, allowing story tests to log these errors without failing the test.


53-58: LGTM!

The window error event handler correctly checks if e.error is an instance of DemoStoryError on line 55. This properly handles uncaught errors thrown in the browser environment.


59-66: LGTM!

The unhandled rejection handler correctly checks if e.reason is an instance of DemoStoryError on line 62. This properly handles rejected promises that throw DemoStoryError without failing the test.


69-76: LGTM! Improved error message clarity.

The addition of "(potentially in previous story)" on line 74 improves the debugging experience by clarifying that errors collected in afterEach might originate from a previous story due to async timing issues. While this is a hardcoded English string, it's acceptable in test infrastructure code since it's developer-facing rather than user-facing.

frontend/viewer/src/project/browse/filter/OpFilter.svelte (1)

26-26: LGTM! Proper i18n implementation.

The string is correctly wrapped in the translation function, consistent with the other translatable strings in this file and the PR's objective.

backend/FwLite/FwLiteShared/Services/FwLiteProvider.cs (1)

38-38: LGTM! Complete service registration.

The UpdateService is properly integrated across all three required locations: ExportedServices array, GetServiceType switch, and DotnetService enum. The implementation follows the established pattern for service registration.

Also applies to: 57-57, 116-116

backend/FwLite/FwLiteMaui/Platforms/Windows/AppUpdateService.cs (1)

12-12: LGTM! Clean event bus integration.

The GlobalEventBus parameter is properly added to the constructor for DI injection, and the progress notification is correctly published through the new NotifyInstallProgress method during the update installation flow.

Also applies to: 119-119, 148-151

frontend/viewer/src/home/HomeView.svelte (1)

31-31: LGTM! Consistent dialog integration.

The UpdateDialog is properly integrated following the same pattern as the existing FeedbackDialog and TroubleshootDialog. The menu item text is correctly wrapped in the translation function, and the component state management is consistent with the established approach.

Also applies to: 136-136, 165-167, 178-178

backend/FwLite/FwLiteShared/Events/IFwEvent.cs (1)

12-12: LGTM! Proper polymorphic event type registration.

The AppUpdateProgressEvent is correctly registered with both the JsonDerivedType attribute for serialization and the FwEventType enum member. This follows the established pattern for other event types in the system.

Also applies to: 29-29

frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/FwEventType.ts (1)

12-13: LGTM! Generated types correctly mirror backend.

The generated TypeScript enum properly reflects the backend C# enum changes, adding the AppUpdateProgress member.

backend/FwLite/FwLiteShared/TypeGen/ReinforcedFwLiteTypingConfig.cs (1)

177-179: LGTM! Update-related types properly exported.

FwLiteRelease and AvailableUpdate are correctly added to the TypeScript export configuration, ensuring the frontend has proper type definitions for the update functionality. This follows the established pattern for exporting backend types to TypeScript.

backend/FwLite/FwLiteShared/AppUpdate/IPlatformUpdateService.cs (1)

22-23: LGTM! Update result enum extended appropriately.

The Disallowed enum member is properly added to UpdateResult, providing a clear semantic distinction for cases where updates cannot be applied. The trailing comma on the previous member follows best practices.

frontend/viewer/src/lib/components/ThemePicker.svelte (1)

67-68: Theme and mode labels now correctly localized

Using {$t(themeName)} for theme labels and $t\Mode`` for the section label cleanly localizes the remaining hardcoded strings without changing behavior.

Also applies to: 74-74

frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/index.ts (1)

1-2: Barrel exports for AppUpdate look good

Re-exporting IAvailableUpdate and UpdateResult from an index barrel simplifies imports and is consistent with typical generated-types layout.

frontend/viewer/src/lib/notifications/NotificationOutlet.svelte (1)

9-9: Update notification callback correctly delegates to openReleaseUrl

Importing openReleaseUrl and calling void openReleaseUrl(event.release) from the manual-update action aligns the UI with the new release-aware update flow without changing notification semantics.

Also applies to: 17-18

frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/IAppUpdateEvent.ts (1)

8-8: Release metadata addition to IAppUpdateEvent looks consistent

Importing IFwLiteRelease and adding a release field gives consumers typed access to release data and matches how the update notification now uses event.release.

Also applies to: 14-14

frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/DotnetService.ts (1)

20-22: DotnetService.UpdateService addition is safe and coherent

Extending DotnetService with UpdateService = "UpdateService" follows the existing pattern and provides a clear key for wiring the new update service.

frontend/viewer/src/lib/dotnet-types/generated-types/LexCore/Entities/IFwLiteRelease.ts (1)

1-11: IFwLiteRelease shape is minimal and sufficient

Defining version and url as strings provides exactly what the frontend needs for display and for openReleaseUrl without overcomplicating the generated type.

frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/UpdateResult.ts (1)

11-12: UpdateResult enum extension is straightforward

Adding Disallowed = "Disallowed" cleanly extends the result space; as long as consumers branch on UpdateResult symbolically, this is a non-breaking change.

frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/AppUpdate/IAvailableUpdate.ts (1)

6-12: Generated IAvailableUpdate shape looks correct and consistent

release: IFwLiteRelease and supportsAutoUpdate: boolean align with the backend types and IUpdateService usage; no issues from the TS side. Since this is Reinforced.Typings output, it should be kept in sync via regeneration rather than manual edits.

backend/FwLite/FwLiteShared/Events/AppUpdateEvent.cs (1)

2-9: Adding Release to AppUpdateEvent cleanly enriches the event payload

The new FwLiteRelease release parameter and Release property integrate well with the existing Result and IFwEvent surface, and the added using LexCore.Entities; keeps the type reference clear. This should make consumers’ lives easier without breaking existing event handling.

backend/FwLite/FwLiteShared/Events/AppUpdateProgressEvent.cs (1)

1-11: AppUpdateProgressEvent matches the existing event patterns

The new AppUpdateProgressEvent follows the same structure as other IFwEvent implementations, carrying both Percentage and Release plus the correct Type and IsGlobal flag. This is a straightforward, well-scoped addition.

frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/IAppUpdateProgressEvent.ts (1)

6-16: IAppUpdateProgressEvent correctly mirrors the backend event contract

The interface matches the C# AppUpdateProgressEvent surface (percentage, release, type, isGlobal) and extends IFwEvent as expected. Looks good for frontend consumers; changes should continue to be driven via the Reinforced.Typings generator.

backend/FwLite/FwLiteShared/FwLiteSharedKernel.cs (1)

25-51: DI additions for caching and UpdateService look appropriate

Registering services.AddMemoryCache(); and services.AddSingleton<UpdateService>(); fits the existing pattern here: both are app-wide concerns, so singleton lifetime in this *Kernel file matches the backend DI guidelines. The placement alongside UpdateChecker keeps related update functionality grouped coherently.

frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/IUpdateService.ts (1)

6-13: IUpdateService interface aligns with the JS-invokable backend UpdateService

The signatures for checkForUpdates() and applyUpdate(update: IAvailableUpdate) correspond cleanly to the C# UpdateService methods and the IAvailableUpdate/UpdateResult types. This should give the frontend a straightforward, type-safe contract for driving the update flow.

frontend/viewer/src/lib/services/service-provider.ts (1)

22-23: UpdateService registration and accessor follow existing service-provider patterns

Adding [DotnetService.UpdateService]: IUpdateService to LexboxServiceRegistry and the useUpdateService() helper is consistent with how other .NET services are exposed (e.g., useFwLiteConfig, useTroubleshootingService). The type import and key wiring look correct.

Just ensure that the .NET side registers the UpdateService under the same DotnetService.UpdateService key via the existing service-declaration/interop mechanism so this accessor always resolves at runtime.

Also applies to: 40-41, 128-130

frontend/viewer/src/stories/updates/update-dialog-content.stories.svelte (1)

1-179: Well-structured Storybook coverage for the update dialog.

The story file provides comprehensive coverage of all update states including checking, available updates (auto/manual), errors, installation progress, and various result states. The helper functions for simulating promise behaviors are cleanly designed and the sample data objects are appropriately typed.

frontend/viewer/src/lib/updates/UpdateDialog.svelte (1)

50-92: LGTM - Clean dialog implementation with proper i18n and accessibility.

The dialog correctly uses Lingui's $t template literals for internationalization, external links have proper security attributes (rel="noopener noreferrer"), and the component composition with UpdateDialogContent is well-structured.

backend/FwLite/FwLiteShared/Services/UpdateService.cs (1)

1-21: Clean service implementation following best practices.

The service is a thin wrapper delegating to UpdateChecker, uses async/await properly (as per coding guidelines), and has correct JS interop attributes. The TsFunction type annotation ensures correct TypeScript type generation.

frontend/viewer/src/lib/updates/utils.ts (1)

1-29: LGTM - Clean utility module for update URL handling.

The implementation properly handles platform-specific store URLs with a sensible fallback to the release URL. The constants for static URLs are appropriately exported, and the async openReleaseUrl function correctly delegates to the openUrl service.

frontend/viewer/src/lib/updates/UpdateDialogContent.svelte (1)

1-22: LGTM - Clean component setup with proper i18n and typing.

The component correctly uses svelte-i18n-lingui for internationalization as per coding guidelines. Props are well-typed, and the component follows Svelte 5 conventions with $props().

frontend/viewer/src/locales/fr.po (1)

1-1478: Skipping review of translation file.

Based on learnings, translations in .po files are managed by Crowdin and should not be reviewed here.

frontend/viewer/src/locales/en.po (1)

1-1474: Skipping review of translation file.

Based on learnings, translations in .po files are managed by Crowdin and should not be reviewed here.

frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Events/index.ts (1)

1-10: LGTM - Standard barrel export pattern.

The index file correctly re-exports all event-related types from the generated types directory, providing a clean single entry point for consumers. The alphabetical ordering aids maintainability.

frontend/viewer/src/locales/ms.po (1)

1-1479: Skipping review of translation file.

Based on learnings, translations in .po files are managed by Crowdin and should not be reviewed here.

backend/FwLite/FwLiteShared/AppUpdate/UpdateChecker.cs (3)

11-11: LGTM: Good use of records for DTOs.

The AvailableUpdate record is a clean, immutable data structure that aligns with best practices for DTOs. As per coding guidelines, records are preferred for such purposes.


37-48: LGTM: Caching logic is sound.

The 2-minute cache prevents redundant network calls during rapid UI interactions while the ShouldCheckForUpdate() guard in TryUpdate() preserves the 8-hour interval logic. Setting LastUpdateCheck inside the cache factory ensures the timestamp is only updated after actual HTTP calls, which aligns with the existing design intent. Based on learnings, this approach correctly enforces the update check interval regardless of network issues.


50-66: LGTM: Permission handling and update flow are correct.

The method properly:

  • Requests permission before proceeding when on a metered connection
  • Returns UpdateResult.Disallowed early if permission is denied
  • Falls back to ManualUpdateRequired when auto-update isn't supported
  • Publishes the event with both result and release information
frontend/viewer/src/locales/sw.po (7)

157-160: Update workflow strings are consistently extracted and ready for translation

New msgids for checking/installing updates and related metadata (Application version, Platform, Download page, Release notes, various Update… status messages, Updates, and You are running the latest version.) are all added with consistent {0} placeholder usage and empty msgstr for later localization. This wiring looks correct and matches the PR goal of making the update UX translatable. Based on learnings, I’m intentionally not proposing specific Swahili translations here.

Also applies to: 219-221, 417-420, 430-433, 479-482, 686-693, 786-789, 1002-1006, 1046-1049, 1362-1365, 1386-1405, 1406-1411, 1464-1467


25-30: Shared navigation and action labels reused across additional contexts

Common UI strings like {0}, Cancel, Close, Download, Feedback & Support, Local, Login, Refresh Projects, and Troubleshoot now reference more components (e.g. HomeView.svelte, ProjectSidebar.svelte, Server.svelte). Reusing the same msgids here is appropriate and will keep navigation and action labeling consistent across the app.

Also applies to: 201-210, 246-251, 407-412, 525-529, 748-751, 757-760, 1042-1045, 1314-1317


223-226: ThemePicker-related keys are coherently grouped

The theming-related strings (Choose theme, Color, Dark, Light, Mode, System) are all correctly associated with ThemePicker.svelte. Centralizing these under the theme picker should simplify translation and keep theme terminology consistent across the UI.

Also applies to: 256-259, 331-334, 727-729, 817-820, 1232-1235


239-244: Filter/select control strings correctly shared between select components

Strings like clear, Filter By, Filter..., No items found, None, and Refine your filter to see more... are now shared between multi-select.svelte and select.svelte (and related filter UIs). This reuse is appropriate and will keep filter controls consistently labeled.

Also applies to: 584-587, 600-603, 878-882, 903-907, 1036-1040


97-101: Entry/editor and browse-related msgids wired to new components

New or expanded contexts for entry-editing and browsing strings (Add audio, Complex Form, Component, Current Entry/Word, Display as, Entry, Gloss, Go to {0}, Grammatical info., History, New Entry/New Word, No entries found, Open in new Window, Part, Part of, Part of speech, Sense, Untitled, Word) correctly reference the various EntryEditor/ComplexForms/browse components. Sharing these msgids across the different views is sensible and should keep terminology aligned.

Also applies to: 260-265, 281-284, 317-321, 327-330, 391-393, 458-465, 630-633, 635-638, 641-644, 653-657, 839-843, 845-847, 865-867, 963-967, 972-976, 979-983, 985-989, 1008-1011, 1121-1123, 1366-1375, 1433-1443


547-553: FieldWorks open/reopen flow strings are consistently localized

Labels and messages around FieldWorks integration (FieldWorks logo, Open in FieldWorks, Reopen, the long “This project is now open in FieldWorks…” notice, and Unable to open in FieldWorks) are now all tied to OpenInFieldWorksButton.svelte and related components. Using shared msgids here should keep the FieldWorks-related UX consistent wherever it appears.

Also applies to: 958-961, 1058-1061, 1284-1287, 1335-1338


520-523: Status and error strings reused across sync/activity views

Status/error messages (Failed to synchronize, Never, Unknown, Unknown error) now have additional references in sync and activity components. Centralizing these under shared msgids is appropriate and will help keep status wording uniform throughout the app.

Also applies to: 827-829, 1340-1343, 1346-1349

@myieye myieye force-pushed the fix/wrap-hardcoded-strings-in-translation branch from f08a365 to afd5004 Compare December 5, 2025 11:21
@myieye myieye force-pushed the fix/wrap-hardcoded-strings-in-translation branch from afd5004 to b94fe3f Compare December 5, 2025 11:22
variant="outline"
size="sm"
onclick={() => {
setTheme(themeName);
Copy link
Collaborator

Choose a reason for hiding this comment

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

❓ Won't the translated strings in themes prevent both setTheme(themeName) and data-theme={themeName} from working?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants