Skip to content

Conversation

@myieye
Copy link
Collaborator

@myieye myieye commented Feb 6, 2026

Summary

This PR introduces a new IPreferencesService that provides a unified interface for storing user preferences across platforms. When running in MAUI, it uses native MAUI Preferences; otherwise, it falls back to localStorage.

Key Changes

Backend (.NET)

  • Added IPreferencesService interface with Get(), Set(), and Remove() methods
  • Implemented PreferencesServiceJsInvokable wrapper around MAUI's IPreferences with JSInvokable attributes for JavaScript interop
  • Registered the service in the MAUI dependency injection container
  • Updated FwLiteProvider to expose the service to JavaScript

Frontend (TypeScript/Svelte)

  • Generated TypeScript types for IPreferencesService interface
  • Added tryUsePreferencesService() hook to safely access the preferences service
  • Updated LexboxServiceRegistry to include the new service

Project Storage

  • Refactored ProjectStorage to use the preferences service backend
  • Created LocalStorageBackend class implementing IPreferencesService as a fallback
  • Changed StorageProp.set() from synchronous to async to support both MAUI and localStorage backends
  • Updated TasksView.svelte to properly await async storage operations

Implementation Details

  • The preferences service is optional on the frontend (tryUsePreferencesService() returns undefined if unavailable)
  • LocalStorageBackend wraps localStorage in an async interface for consistency
  • Storage operations are now async-first, allowing callers to await or fire-and-forget
  • Initial storage values load asynchronously; reactive state updates when ready
  • Project-scoped keys use the format project:{projectCode}:{key} for isolation

https://claude.ai/code/session_01XdJtubGvpeSyetSuA3zfFA

@coderabbitai
Copy link

coderabbitai bot commented Feb 6, 2026

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.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR introduces a new IPreferencesService interface and its MAUI implementation to expose device preferences to JavaScript code via JSInterop. The service is registered in the DI container, exposed through TypeScript type definitions, integrated into the frontend service provider, and utilized in the project storage layer with localStorage fallback support.

Changes

Cohort / File(s) Summary
Backend Service Definition
backend/FwLite/FwLiteShared/Services/IPreferencesService.cs
New interface defining Get, Set, and Remove methods for key-value preferences accessible to JavaScript.
MAUI Service Implementation & DI
backend/FwLite/FwLiteMaui/Services/PreferencesServiceJsInvokable.cs, backend/FwLite/FwLiteMaui/FwLiteMauiKernel.cs
JSInvokable wrapper class implementing IPreferencesService delegating to MAUI IPreferences, registered as singleton in DI.
Shared Service Provider
backend/FwLite/FwLiteShared/Services/FwLiteProvider.cs
Added PreferencesService enum value and service resolution mapping to IPreferencesService interface.
Frontend Type Generation
frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/DotnetService.ts, frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/IPreferencesService.ts, frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/index.ts
Generated TypeScript definitions for DotnetService enum and IPreferencesService interface with Promise-based methods.
Frontend Service Provider Integration
frontend/viewer/src/lib/services/service-provider.ts
Added PreferencesService type mapping and tryUsePreferencesService() helper function for safe service access.
Storage Refactoring
frontend/viewer/src/lib/utils/project-storage.svelte.ts
Implemented LocalStorageBackend fallback, refactored StorageProp and ProjectStorage to accept backend parameter, converted storage operations to async, and integrated preferences service selection.
UI Component Update
frontend/viewer/src/project/tasks/TasksView.svelte
Changed Select.Root binding from two-way bind:value to one-way value with explicit onValueChange handler.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • #2142: Directly modifies the same project-storage.svelte.ts file, adding MAUI-aware preferences and async storage APIs.

Suggested labels

🟨Medium

Suggested reviewers

  • hahn-kev
  • imnasnainaec

Poem

🐰 A preferences service hops into view,
MAUI meets JavaScript, both old and new,
LocalStorage stands as a faithful friend,
While async pathways gracefully bend,
From storage pens come cleaner designs,
A rabbit celebrates—the code shines!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: introducing a preferences service for cross-platform user settings storage, which is the central feature of this PR.
Description check ✅ Passed The description comprehensively explains the PR's purpose, key changes across backend and frontend, implementation details, and architectural decisions—all directly related to the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/maui-preferences-storage-HWSj7

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 github-actions bot added the 💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related label Feb 6, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

UI unit Tests

  1 files  ±0   50 suites  ±0   24s ⏱️ ±0s
138 tests ±0  138 ✅ ±0  0 💤 ±0  0 ❌ ±0 
203 runs  ±0  203 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 16ae6c9. ± Comparison against base commit 7995859.

♻️ This comment has been updated with latest results.

@argos-ci
Copy link

argos-ci bot commented Feb 6, 2026

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

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Feb 11, 2026, 2:37 PM

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

C# Unit Tests

160 tests  ±0   160 ✅ ±0   19s ⏱️ -1s
 23 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 16ae6c9. ± Comparison against base commit 7995859.

♻️ This comment has been updated with latest results.

@myieye myieye force-pushed the claude/maui-preferences-storage-HWSj7 branch from 8fb8c26 to 878d684 Compare February 6, 2026 15:40
@myieye myieye marked this pull request as ready for review February 6, 2026 15:55
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: 1

🤖 Fix all issues with AI agents
In `@frontend/viewer/src/lib/utils/project-storage.svelte.ts`:
- Around line 56-84: Constructor calls load() fire-and-forget which can race
with set() and allow load() to overwrite `#value` with stale backend data; fix by
adding a simple sequencing guard: introduce a private sequence counter (e.g.
`#writeSeq` or `#initSeq`) on the class, increment it at the start of set(), and in
load() capture the current sequence before awaiting the backend and only assign
this.#value if the captured sequence still equals the current sequence; update
references to constructor, load(), set(), and `#value` accordingly so late load()
results no longer overwrite newer writes.

claude and others added 8 commits February 11, 2026 15:33
Add PreferencesService to expose MAUI IPreferences to the TypeScript
frontend via JSInterop. When running in MAUI, project storage now uses
native preferences instead of localStorage.

- Add IPreferencesService interface and PreferencesServiceJsInvokable
- Register service in FwLiteProvider and FwLiteMauiKernel
- Refactor project-storage.svelte.ts with StorageBackend abstraction
- Fall back to localStorage when not running in MAUI

https://claude.ai/code/session_01XdJtubGvpeSyetSuA3zfFA
Change API from setter to explicit async method:
- `current` getter is reactive and read-only
- `set()` is async - callers can await or fire-and-forget
- Add error logging for load failures

Update TasksView to use onValueChange instead of bind:value.

https://claude.ai/code/session_01XdJtubGvpeSyetSuA3zfFA
- Remove redundant StorageBackend interface (identical to IPreferencesService)
- Remove PreferencesBackend wrapper class (just a passthrough)
- LocalStorageBackend now implements IPreferencesService directly
- Make load() async without catch - errors hit global handler
- Add IPreferencesService to Services barrel export

https://claude.ai/code/session_01XdJtubGvpeSyetSuA3zfFA
IPreferences is a MAUI type, so the implementation must live in
FwLiteMaui, not FwLiteShared. The interface (IPreferencesService)
remains in FwLiteShared.

https://claude.ai/code/session_01XdJtubGvpeSyetSuA3zfFA
If set() is called before load() completes, the #hasBeenSet flag
prevents load() from overwriting the user's value with stale data.

https://claude.ai/code/session_01XdJtubGvpeSyetSuA3zfFA
@myieye myieye force-pushed the claude/maui-preferences-storage-HWSj7 branch from 4903c7f to 16ae6c9 Compare February 11, 2026 14:34
@myieye myieye merged commit b04aee5 into develop Feb 11, 2026
33 of 34 checks passed
@myieye myieye deleted the claude/maui-preferences-storage-HWSj7 branch February 11, 2026 15:03
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.

2 participants