diff --git a/app/src/main/java/eu/kanade/presentation/library/components/LibraryToolbar.kt b/app/src/main/java/eu/kanade/presentation/library/components/LibraryToolbar.kt index 0ff4d81f9..3eb0300c4 100644 --- a/app/src/main/java/eu/kanade/presentation/library/components/LibraryToolbar.kt +++ b/app/src/main/java/eu/kanade/presentation/library/components/LibraryToolbar.kt @@ -129,7 +129,7 @@ private fun LibraryRegularToolbar( onClick = onClickOpenRandomManga, ), AppBar.OverflowAction( - title = stringResource(MR.strings.sync_library), + title = stringResource(SYMR.strings.sync_library), onClick = onClickSyncNow, ), ).builder().apply { diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsDataScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsDataScreen.kt index 9e51db038..46c8caf6a 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsDataScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsDataScreen.kt @@ -349,15 +349,15 @@ object SettingsDataScreen : SearchableSettings { private fun getSyncPreferences(syncPreferences: SyncPreferences, syncService: Int): List { return listOf( Preference.PreferenceGroup( - title = stringResource(MR.strings.pref_sync_service_category), + title = stringResource(SYMR.strings.pref_sync_service_category), preferenceItems = persistentListOf( Preference.PreferenceItem.ListPreference( pref = syncPreferences.syncService(), - title = stringResource(MR.strings.pref_sync_service), + title = stringResource(SYMR.strings.pref_sync_service), entries = persistentMapOf( SyncManager.SyncService.NONE.value to stringResource(MR.strings.off), - SyncManager.SyncService.SYNCYOMI.value to stringResource(MR.strings.syncyomi), - SyncManager.SyncService.GOOGLE_DRIVE.value to stringResource(MR.strings.google_drive), + SyncManager.SyncService.SYNCYOMI.value to stringResource(SYMR.strings.syncyomi), + SyncManager.SyncService.GOOGLE_DRIVE.value to stringResource(SYMR.strings.google_drive), ), onValueChanged = { true }, ), @@ -402,7 +402,7 @@ object SettingsDataScreen : SearchableSettings { val googleDriveSync = Injekt.get() return listOf( Preference.PreferenceItem.TextPreference( - title = stringResource(MR.strings.pref_google_drive_sign_in), + title = stringResource(SYMR.strings.pref_google_drive_sign_in), onClick = { val intent = googleDriveSync.getSignInIntent() context.startActivity(intent) @@ -427,19 +427,19 @@ object SettingsDataScreen : SearchableSettings { val result = googleDriveSync.deleteSyncDataFromGoogleDrive() when (result) { GoogleDriveSyncService.DeleteSyncDataStatus.NOT_INITIALIZED -> context.toast( - MR.strings.google_drive_not_signed_in, + SYMR.strings.google_drive_not_signed_in, duration = 5000, ) GoogleDriveSyncService.DeleteSyncDataStatus.NO_FILES -> context.toast( - MR.strings.google_drive_sync_data_not_found, + SYMR.strings.google_drive_sync_data_not_found, duration = 5000, ) GoogleDriveSyncService.DeleteSyncDataStatus.SUCCESS -> context.toast( - MR.strings.google_drive_sync_data_purged, + SYMR.strings.google_drive_sync_data_purged, duration = 5000, ) GoogleDriveSyncService.DeleteSyncDataStatus.ERROR -> context.toast( - MR.strings.google_drive_sync_data_purge_error, + SYMR.strings.google_drive_sync_data_purge_error, duration = 10000, ) } @@ -450,7 +450,7 @@ object SettingsDataScreen : SearchableSettings { } return Preference.PreferenceItem.TextPreference( - title = stringResource(MR.strings.pref_google_drive_purge_sync_data), + title = stringResource(SYMR.strings.pref_google_drive_purge_sync_data), onClick = { showPurgeDialog = true }, ) } @@ -462,8 +462,8 @@ object SettingsDataScreen : SearchableSettings { ) { AlertDialog( onDismissRequest = onDismissRequest, - title = { Text(text = stringResource(MR.strings.pref_purge_confirmation_title)) }, - text = { Text(text = stringResource(MR.strings.pref_purge_confirmation_message)) }, + title = { Text(text = stringResource(SYMR.strings.pref_purge_confirmation_title)) }, + text = { Text(text = stringResource(SYMR.strings.pref_purge_confirmation_message)) }, dismissButton = { TextButton(onClick = onDismissRequest) { Text(text = stringResource(MR.strings.action_cancel)) @@ -482,8 +482,8 @@ object SettingsDataScreen : SearchableSettings { val scope = rememberCoroutineScope() return listOf( Preference.PreferenceItem.EditTextPreference( - title = stringResource(MR.strings.pref_sync_host), - subtitle = stringResource(MR.strings.pref_sync_host_summ), + title = stringResource(SYMR.strings.pref_sync_host), + subtitle = stringResource(SYMR.strings.pref_sync_host_summ), pref = syncPreferences.clientHost(), onValueChanged = { newValue -> scope.launch { @@ -496,8 +496,8 @@ object SettingsDataScreen : SearchableSettings { }, ), Preference.PreferenceItem.EditTextPreference( - title = stringResource(MR.strings.pref_sync_api_key), - subtitle = stringResource(MR.strings.pref_sync_api_key_summ), + title = stringResource(SYMR.strings.pref_sync_api_key), + subtitle = stringResource(SYMR.strings.pref_sync_api_key_summ), pref = syncPreferences.clientAPIKey(), ), ) @@ -507,12 +507,12 @@ object SettingsDataScreen : SearchableSettings { private fun getSyncNowPref(): Preference.PreferenceGroup { val navigator = LocalNavigator.currentOrThrow return Preference.PreferenceGroup( - title = stringResource(MR.strings.pref_sync_now_group_title), + title = stringResource(SYMR.strings.pref_sync_now_group_title), preferenceItems = persistentListOf( getSyncOptionsPref(), Preference.PreferenceItem.TextPreference( - title = stringResource(MR.strings.pref_sync_now), - subtitle = stringResource(MR.strings.pref_sync_now_subtitle), + title = stringResource(SYMR.strings.pref_sync_now), + subtitle = stringResource(SYMR.strings.pref_sync_now_subtitle), onClick = { navigator.push(SyncSettingsSelector()) }, @@ -525,8 +525,8 @@ object SettingsDataScreen : SearchableSettings { private fun getSyncOptionsPref(): Preference.PreferenceItem.TextPreference { val navigator = LocalNavigator.currentOrThrow return Preference.PreferenceItem.TextPreference( - title = stringResource(MR.strings.pref_sync_options), - subtitle = stringResource(MR.strings.pref_sync_options_summ), + title = stringResource(SYMR.strings.pref_sync_options), + subtitle = stringResource(SYMR.strings.pref_sync_options_summ), onClick = { navigator.push(SyncTriggerOptionsScreen()) }, ) } @@ -538,16 +538,16 @@ object SettingsDataScreen : SearchableSettings { val lastSync by syncPreferences.lastSyncTimestamp().collectAsState() return Preference.PreferenceGroup( - title = stringResource(MR.strings.pref_sync_automatic_category), + title = stringResource(SYMR.strings.pref_sync_automatic_category), preferenceItems = persistentListOf( Preference.PreferenceItem.ListPreference( pref = syncIntervalPref, - title = stringResource(MR.strings.pref_sync_interval), + title = stringResource(SYMR.strings.pref_sync_interval), entries = persistentMapOf( 0 to stringResource(MR.strings.off), - 30 to stringResource(MR.strings.update_30min), - 60 to stringResource(MR.strings.update_1hour), - 180 to stringResource(MR.strings.update_3hour), + 30 to stringResource(SYMR.strings.update_30min), + 60 to stringResource(SYMR.strings.update_1hour), + 180 to stringResource(SYMR.strings.update_3hour), 360 to stringResource(MR.strings.update_6hour), 720 to stringResource(MR.strings.update_12hour), 1440 to stringResource(MR.strings.update_24hour), @@ -560,7 +560,7 @@ object SettingsDataScreen : SearchableSettings { }, ), Preference.PreferenceItem.InfoPreference( - stringResource(MR.strings.last_synchronization, relativeTimeSpanString(lastSync)), + stringResource(SYMR.strings.last_synchronization, relativeTimeSpanString(lastSync)), ), ), ) diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/SyncSettingsSelector.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/SyncSettingsSelector.kt index 024ebc5f5..93e5405bf 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/SyncSettingsSelector.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/SyncSettingsSelector.kt @@ -20,6 +20,7 @@ import eu.kanade.tachiyomi.util.system.toast import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.flow.update import tachiyomi.i18n.MR +import tachiyomi.i18n.sy.SYMR import tachiyomi.presentation.core.components.LabeledCheckbox import tachiyomi.presentation.core.components.LazyColumnWithAction import tachiyomi.presentation.core.components.SectionCard @@ -39,7 +40,7 @@ class SyncSettingsSelector : Screen() { Scaffold( topBar = { AppBar( - title = stringResource(MR.strings.pref_choose_what_to_sync), + title = stringResource(SYMR.strings.pref_choose_what_to_sync), navigateUp = navigator::pop, scrollBehavior = it, ) @@ -47,14 +48,14 @@ class SyncSettingsSelector : Screen() { ) { contentPadding -> LazyColumnWithAction( contentPadding = contentPadding, - actionLabel = stringResource(MR.strings.label_sync), + actionLabel = stringResource(SYMR.strings.label_sync), actionEnabled = state.options.anyEnabled(), onClickAction = { if (!SyncDataJob.isRunning(context)) { model.syncNow(context) navigator.pop() } else { - context.toast(MR.strings.sync_in_progress) + context.toast(SYMR.strings.sync_in_progress) } }, ) { diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/SyncTriggerOptionsScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/SyncTriggerOptionsScreen.kt index ddcfbebd1..301ebc0d4 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/SyncTriggerOptionsScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/SyncTriggerOptionsScreen.kt @@ -15,6 +15,7 @@ import eu.kanade.tachiyomi.data.sync.models.SyncTriggerOptions import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.flow.update import tachiyomi.i18n.MR +import tachiyomi.i18n.sy.SYMR import tachiyomi.presentation.core.components.LabeledCheckbox import tachiyomi.presentation.core.components.LazyColumnWithAction import tachiyomi.presentation.core.components.SectionCard @@ -34,7 +35,7 @@ class SyncTriggerOptionsScreen : Screen() { Scaffold( topBar = { AppBar( - title = stringResource(MR.strings.pref_sync_options), + title = stringResource(SYMR.strings.pref_sync_options), navigateUp = navigator::pop, scrollBehavior = it, ) @@ -49,7 +50,7 @@ class SyncTriggerOptionsScreen : Screen() { }, ) { item { - SectionCard(MR.strings.label_triggers) { + SectionCard(SYMR.strings.label_triggers) { Options(SyncTriggerOptions.mainOptions, state, model) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/sync/models/SyncTriggerOptions.kt b/app/src/main/java/eu/kanade/tachiyomi/data/sync/models/SyncTriggerOptions.kt index 7d8a9bdb8..690483039 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/sync/models/SyncTriggerOptions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/sync/models/SyncTriggerOptions.kt @@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.data.sync.models import dev.icerock.moko.resources.StringResource import kotlinx.collections.immutable.persistentListOf -import tachiyomi.i18n.MR +import tachiyomi.i18n.sy.SYMR data class SyncTriggerOptions( val syncOnChapterRead: Boolean = false, @@ -25,22 +25,22 @@ data class SyncTriggerOptions( companion object { val mainOptions = persistentListOf( Entry( - label = MR.strings.sync_on_chapter_read, + label = SYMR.strings.sync_on_chapter_read, getter = SyncTriggerOptions::syncOnChapterRead, setter = { options, enabled -> options.copy(syncOnChapterRead = enabled) }, ), Entry( - label = MR.strings.sync_on_chapter_open, + label = SYMR.strings.sync_on_chapter_open, getter = SyncTriggerOptions::syncOnChapterOpen, setter = { options, enabled -> options.copy(syncOnChapterOpen = enabled) }, ), Entry( - label = MR.strings.sync_on_app_start, + label = SYMR.strings.sync_on_app_start, getter = SyncTriggerOptions::syncOnAppStart, setter = { options, enabled -> options.copy(syncOnAppStart = enabled) }, ), Entry( - label = MR.strings.sync_on_app_resume, + label = SYMR.strings.sync_on_app_resume, getter = SyncTriggerOptions::syncOnAppResume, setter = { options, enabled -> options.copy(syncOnAppResume = enabled) }, ), diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/sync/service/GoogleDriveSyncService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/sync/service/GoogleDriveSyncService.kt index 5a3fd5bf8..45ec6b05c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/sync/service/GoogleDriveSyncService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/sync/service/GoogleDriveSyncService.kt @@ -27,6 +27,7 @@ import tachiyomi.core.common.i18n.stringResource import tachiyomi.core.common.util.lang.withIOContext import tachiyomi.core.common.util.system.logcat import tachiyomi.i18n.MR +import tachiyomi.i18n.sy.SYMR import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import java.io.ByteArrayOutputStream @@ -68,7 +69,7 @@ class GoogleDriveSyncService(context: Context, json: Json, syncPreferences: Sync try { googleDriveService.refreshToken() val drive = googleDriveService.driveService - ?: throw Exception(context.stringResource(MR.strings.google_drive_not_signed_in)) + ?: throw Exception(context.stringResource(SYMR.strings.google_drive_not_signed_in)) var backoff = 1000L var retries = 0 // Retry counter @@ -112,11 +113,11 @@ class GoogleDriveSyncService(context: Context, json: Json, syncPreferences: Sync if (retries >= maxRetries) { logcat(LogPriority.ERROR) { "Max retries reached, exiting sync process" } - throw Exception(context.stringResource(MR.strings.error_before_sync_gdrive) + ": Max retries reached.") + throw Exception(context.stringResource(SYMR.strings.error_before_sync_gdrive) + ": Max retries reached.") } } catch (e: Exception) { logcat(LogPriority.ERROR, throwable = e) { "Error in GoogleDrive beforeSync" } - throw Exception(context.stringResource(MR.strings.error_before_sync_gdrive) + ": ${e.message}", e) + throw Exception(context.stringResource(SYMR.strings.error_before_sync_gdrive) + ": ${e.message}", e) } } @@ -125,7 +126,7 @@ class GoogleDriveSyncService(context: Context, json: Json, syncPreferences: Sync if (drive == null) { logcat(LogPriority.DEBUG) { "Google Drive service not initialized" } - throw Exception(context.stringResource(MR.strings.google_drive_not_signed_in)) + throw Exception(context.stringResource(SYMR.strings.google_drive_not_signed_in)) } val fileList = getAppDataFileList(drive) @@ -166,7 +167,7 @@ class GoogleDriveSyncService(context: Context, json: Json, syncPreferences: Sync override suspend fun pushSyncData(syncData: SyncData) { val jsonData = json.encodeToString(syncData) val drive = googleDriveService.driveService - ?: throw Exception(context.stringResource(MR.strings.google_drive_not_signed_in)) + ?: throw Exception(context.stringResource(SYMR.strings.google_drive_not_signed_in)) val fileList = getAppDataFileList(drive) val byteArrayOutputStream = ByteArrayOutputStream() @@ -205,7 +206,7 @@ class GoogleDriveSyncService(context: Context, json: Json, syncPreferences: Sync deleteLockFile(drive) } catch (e: Exception) { logcat(LogPriority.ERROR, throwable = e) { "Failed to push or update sync data" } - throw Exception(context.stringResource(MR.strings.error_uploading_sync_data) + ": ${e.message}", e) + throw Exception(context.stringResource(SYMR.strings.error_uploading_sync_data) + ": ${e.message}", e) } } @@ -282,7 +283,7 @@ class GoogleDriveSyncService(context: Context, json: Json, syncPreferences: Sync } } catch (e: Exception) { logcat(LogPriority.ERROR, throwable = e) { "Error deleting lock file" } - throw Exception(context.stringResource(MR.strings.error_deleting_google_drive_lock_file), e) + throw Exception(context.stringResource(SYMR.strings.error_deleting_google_drive_lock_file), e) } } @@ -407,7 +408,7 @@ class GoogleDriveService(private val context: Context) { .build() if (refreshToken == "") { - throw Exception(context.stringResource(MR.strings.google_drive_not_signed_in)) + throw Exception(context.stringResource(SYMR.strings.google_drive_not_signed_in)) } credential.refreshToken = refreshToken diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryTab.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryTab.kt index 8e12ab072..95a3da3f3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryTab.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryTab.kt @@ -167,7 +167,7 @@ object LibraryTab : Tab { if (!SyncDataJob.isRunning(context)) { SyncDataJob.startNow(context) } else { - context.toast(MR.strings.sync_in_progress) + context.toast(SYMR.strings.sync_in_progress) } }, // SY --> diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/track/GoogleDriveLoginActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/track/GoogleDriveLoginActivity.kt index 65ffa5ae2..7dfcdd824 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/track/GoogleDriveLoginActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/track/GoogleDriveLoginActivity.kt @@ -6,7 +6,7 @@ import androidx.lifecycle.lifecycleScope import eu.kanade.tachiyomi.data.sync.service.GoogleDriveService import tachiyomi.core.common.i18n.stringResource import tachiyomi.core.common.util.lang.launchIO -import tachiyomi.i18n.MR +import tachiyomi.i18n.sy.SYMR import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get @@ -23,7 +23,7 @@ class GoogleDriveLoginActivity : BaseOAuthLoginActivity() { onSuccess = { Toast.makeText( this@GoogleDriveLoginActivity, - stringResource(MR.strings.google_drive_login_success), + stringResource(SYMR.strings.google_drive_login_success), Toast.LENGTH_LONG, ).show() @@ -32,7 +32,7 @@ class GoogleDriveLoginActivity : BaseOAuthLoginActivity() { onFailure = { error -> Toast.makeText( this@GoogleDriveLoginActivity, - stringResource(MR.strings.google_drive_login_failed, error), + stringResource(SYMR.strings.google_drive_login_failed, error), Toast.LENGTH_LONG, ).show() returnToSettings() @@ -42,7 +42,7 @@ class GoogleDriveLoginActivity : BaseOAuthLoginActivity() { } else if (error != null) { Toast.makeText( this@GoogleDriveLoginActivity, - stringResource(MR.strings.google_drive_login_failed, error), + stringResource(SYMR.strings.google_drive_login_failed, error), Toast.LENGTH_LONG, ).show() diff --git a/i18n-sy/src/commonMain/resources/MR/base/strings.xml b/i18n-sy/src/commonMain/resources/MR/base/strings.xml index 634ff32bc..b4fee304c 100644 --- a/i18n-sy/src/commonMain/resources/MR/base/strings.xml +++ b/i18n-sy/src/commonMain/resources/MR/base/strings.xml @@ -187,6 +187,9 @@ Mark duplicate chapters as read after reading Mark new duplicate chapters as read Automatically mark new chapters as read if it has been read before + Every 30 minutes + Every hour + Every 3 hours Hide Feed tab @@ -200,8 +203,60 @@ Allow local source to read hidden folders + Manual & automatic backups and sync Custom entry info All read entries + Backup + Sync + Triggers + + + Syncing library failed + Syncing library complete + Sync is already in progress + Host + Enter the host address for synchronizing your library + API key + Enter the API key to synchronize your library + Sync Actions + Sync now + Sync confirmation + Initiate immediate synchronization of your data + Syncing will overwrite your local library with the remote library. Are you sure you want to continue? + Service + Select the service to sync your library with + Sync + Automatic Synchronization + Synchronization frequency + Choose what to sync + Last sync timestamp reset + SyncYomi + Done in %1$s + Last Synchronization: %1$s + Google Drive + Sign in + Signed in successfully + Sign in failed + Authentication + Clear Sync Data from Google Drive + Sync data purged from Google Drive + No sync data found in Google Drive + Error purging sync data from Google Drive, Try to sign in again. + Logged in to Google Drive + Failed to log in to Google Drive: %s + Not signed in to Google Drive + Error uploading sync data to Google Drive + Error Deleting Google Drive Lock File + Error before sync: %s + Purge confirmation + Purging sync data will delete all your sync data from Google Drive. Are you sure you want to continue? + Create sync triggers + Can be used to set sync triggers + Sync on Chapter Read + Sync on Chapter Open + Sync on App Start + Sync on App Resume + Sync library Biometric lock times diff --git a/i18n/src/commonMain/resources/MR/base/strings.xml b/i18n/src/commonMain/resources/MR/base/strings.xml index a1d23f4e2..7b72cd3b7 100755 --- a/i18n/src/commonMain/resources/MR/base/strings.xml +++ b/i18n/src/commonMain/resources/MR/base/strings.xml @@ -29,10 +29,8 @@ Upcoming History Sources + Backup and restore Data and storage - Backup - Sync - Triggers Statistics Migrate Extensions @@ -213,7 +211,6 @@ One-way progress sync, enhanced sync Sources, extensions, global search Manual & automatic backups, storage space - Manual & automatic backups and sync App lock, secure screen Dump crash logs, battery optimizations @@ -268,9 +265,6 @@ Global update Automatic updates Off - Every 30 minutes - Every hour - Every 3 hours Every 6 hours Every 12 hours Daily @@ -551,52 +545,6 @@ Syncing library Library sync complete - Syncing library failed - Syncing library complete - Sync is already in progress - Host - Enter the host address for synchronizing your library - API key - Enter the API key to synchronize your library - Sync Actions - Sync now - Sync confirmation - Initiate immediate synchronization of your data - Syncing will overwrite your local library with the remote library. Are you sure you want to continue? - Service - Select the service to sync your library with - Sync - Automatic Synchronization - Synchronization frequency - Choose what to sync - Last sync timestamp reset - SyncYomi - Done in %1$s - Last Synchronization: %1$s - Google Drive - Sign in - Signed in successfully - Sign in failed - Authentication - Clear Sync Data from Google Drive - Sync data purged from Google Drive - No sync data found in Google Drive - Error purging sync data from Google Drive, Try to sign in again. - Logged in to Google Drive - Failed to log in to Google Drive: %s - Not signed in to Google Drive - Error uploading sync data to Google Drive - Error Deleting Google Drive Lock File - Error before sync: %s - Purge confirmation - Purging sync data will delete all your sync data from Google Drive. Are you sure you want to continue? - Create sync triggers - Can be used to set sync triggers - Sync on Chapter Read - Sync on Chapter Open - Sync on App Start - Sync on App Resume - Sync library Networking