Feature: Sync Mutations (Bookmarks, Collections, Collection Bookmarks, Notes)#105
Merged
AhmedNMahran merged 31 commits intomainfrom Feb 21, 2026
Merged
Feature: Sync Mutations (Bookmarks, Collections, Collection Bookmarks, Notes)#105AhmedNMahran merged 31 commits intomainfrom
AhmedNMahran merged 31 commits intomainfrom
Conversation
- rename classes - update models to fix serialization errors
- uncomment sync adapters in SynchronizationClient.kt
…e triggering sync - add `triggerSyncImmediately` and `cancelSyncing` to `SynchronizationClient` and `Scheduler` - observe authentication state in `SyncService` to trigger or cancel sync based on login status - add `isLoggedIn` to `AuthenticationDataFetcher` interface and implementations
- rename `MainSyncViewModel` to `SyncViewModel` in iOS and Kotlin - integrate authentication actions (`login`, `logout`, `clearError`) directly into `SyncViewModel` - remove `AuthViewModel` dependency from `SyncViewModel` and replace it with `AuthService` - update Android and iOS demo apps to use the updated `SyncViewModel` and `SyncService` classes
- delete bookmark (WIP)
- add ayah bookmark - delete bookmark - fix updating local bookmarks when receiving deleted mutation
- note - update ui
Contributor
|
ran this through a code-review from Codex, and it said: |
Contributor
|
side note - just merged #107 to fix tests on main so might want to rebase on that one |
ahmedre
reviewed
Feb 8, 2026
sync-pipelines/src/commonMain/kotlin/com/quran/shared/pipeline/SyncPipelineFactory.kt
Show resolved
Hide resolved
ahmedre
reviewed
Feb 8, 2026
demo/android/src/main/kotlin/com/quran/shared/demo/android/ui/SyncViewModel.kt
Show resolved
Hide resolved
mohamede1945
requested changes
Feb 9, 2026
Collections and note
…d their bookmarks for UI - update `SyncService` and `SyncViewModel` to provide a flow of `CollectionWithBookmarks` - improve `CollectionBookmarksSyncAdapter` to map unknown bookmark types using local data - implement `dirty` flag in `notes` table to better track unsynced changes - refactor `SyncViewModel` in both Android and iOS demo apps to handle async/await operations and improve data observation - add functionality to add random bookmarks directly to a specific collection in demo apps - update `NotesRepositoryImpl` to fetch unsynced notes based on the new `dirty` flag instead of just timestamps - refine `fetchLocalModel` in `CollectionBookmarksRepositoryDataFetcher` to return existing bookmarks by remote ID
the added `service.clear()` when cleared on both platforms - improve note creation in Android and iOS demo apps to use random suras and ayahs instead of hardcoded dummy values
collections and notes logic
- configure `oidcRedirectScheme` manifest placeholder in `sync-pipelines` and `auth` modules
Fix build errors - add jvm target and ktor-client-okhttp dependency to auth module - configure oidcRedirectScheme manifest placeholder in sync-pipelines and auth modules
…ions - use suspend functions in `SyncViewModel.kt` instead of internal `viewmodelScope`
Sync Feature PR comments refactor iOS architecture and remove unnecessary classes and functions use suspend functions in SyncViewModel.kt instead of internal viewmodelScope
- Move `SyncViewModel` from the `sync-pipelines` module to the respective demo app modules (`demo/android` and `demo/apple`). - Remove `SyncViewModel` creation logic from `SyncPipelineFactory` to decouple the factory from the UI layer. - Update Android and iOS demo apps to instantiate `SyncViewModel` directly. - Rename the `service` property to `syncService` in the Swift `SyncViewModel` for clarity.
Replaced dedicated observer methods with inlined loops in observeData. used @mainactor [weak self] for task group additions. Added guard let self = self else { break } inside for await loops to ensure background tasks terminate when the ViewModel is deallocated.
mohamede1945
approved these changes
Feb 20, 2026
Collaborator
mohamede1945
left a comment
There was a problem hiding this comment.
Approving swift changes. Jazak Allah khyrn Ahmed
ahmedre
reviewed
Feb 20, 2026
demo/common/src/commonMain/kotlin/com/quran/shared/demo/common/util/QuranActionsUtils.kt
Show resolved
Hide resolved
persistence/src/commonMain/sqldelight/com/quran/shared/persistence/notes.sq
Outdated
Show resolved
Hide resolved
syncengine/src/commonMain/kotlin/com/quran/shared/syncengine/network/GetMutationsRequest.kt
Outdated
Show resolved
Hide resolved
demo/android/src/main/kotlin/com/quran/shared/demo/android/MainActivity.kt
Outdated
Show resolved
Hide resolved
sync-pipelines/src/commonMain/kotlin/com/quran/shared/pipeline/SyncEnginePipeline.kt
Outdated
Show resolved
Hide resolved
ahmedre
approved these changes
Feb 20, 2026
…` to avoid activity leakage
Collaborator
Author
|
@ahmedre @mohamede1945 Jazakum Allah Khayran for the valuable comments. all nits are now resolved alhamdulillah, for the DI, will create an issue to track insha'Allah |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related to Issue #87
Summary
This PR improves the synchronization engine by making it fully authentication-aware and refactoring the pipeline architecture for better maintainability. The core synchronization lifecycle is now tightly coupled with the user's authentication state via a reactive observer. Additionally, a new factory-based initialization system has been introduced to simplify the integration of synchronization features across Android and iOS platforms, eliminating manual object wiring in the UI layer.
Key Changes
1. Auth-Aware Synchronization Engine
SynchronizationClientnow verifies authentication status viaAuthenticationDataFetcher.isLoggedIn()before any sync operation begins. Triggers received while logged out are safely ignored.triggerSyncImmediately()andcancelSyncing()to the sync client. These are automatically invoked by the service layer when authentication states change (SuccessvsIdle/Error).2. Enhanced Scheduler Logic
Scheduler.cancel()which halts pending jobs and resets the state toIdle. This allows the scheduler to be cleanly resumed when a user re-authenticates without stopping the underlying CoroutineScope.3. Factory-Based Initialization
sync-pipelinesmodule to encapsulate the complex setup of databases, repositories, and synchronization engines.4. Bookmark, Collection, Collection Bookmark, and Notes Actions Integration
Technical Details
syncengineSynchronizationClientandScheduler.sync-pipelinesSyncPipelineFactory.Testing
SynchronizationClientIntegrationTest.ktto verify that sync operations are blocked when logged out.