forked from github/wulkanowy-mirror
Add force sync feature in settings (#643)
This commit is contained in:
parent
3612326628
commit
6a0ce3a58d
@ -154,6 +154,8 @@ dependencies {
|
|||||||
implementation "androidx.work:work-rxjava2:$work_manager"
|
implementation "androidx.work:work-rxjava2:$work_manager"
|
||||||
implementation "androidx.work:work-gcm:$work_manager"
|
implementation "androidx.work:work-gcm:$work_manager"
|
||||||
|
|
||||||
|
implementation 'com.github.PaulinaSadowska:RxWorkManagerObservers:1.0.0'
|
||||||
|
|
||||||
implementation "androidx.room:room-runtime:$room"
|
implementation "androidx.room:room-runtime:$room"
|
||||||
implementation "androidx.room:room-rxjava2:$room"
|
implementation "androidx.room:room-rxjava2:$room"
|
||||||
implementation "androidx.room:room-ktx:$room"
|
implementation "androidx.room:room-ktx:$room"
|
||||||
|
@ -5,18 +5,24 @@ import android.os.Build.VERSION_CODES.O
|
|||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import androidx.work.BackoffPolicy.EXPONENTIAL
|
import androidx.work.BackoffPolicy.EXPONENTIAL
|
||||||
import androidx.work.Constraints
|
import androidx.work.Constraints
|
||||||
|
import androidx.work.Data
|
||||||
import androidx.work.ExistingPeriodicWorkPolicy.KEEP
|
import androidx.work.ExistingPeriodicWorkPolicy.KEEP
|
||||||
import androidx.work.ExistingPeriodicWorkPolicy.REPLACE
|
import androidx.work.ExistingPeriodicWorkPolicy.REPLACE
|
||||||
|
import androidx.work.ExistingWorkPolicy
|
||||||
import androidx.work.NetworkType.CONNECTED
|
import androidx.work.NetworkType.CONNECTED
|
||||||
import androidx.work.NetworkType.UNMETERED
|
import androidx.work.NetworkType.UNMETERED
|
||||||
|
import androidx.work.OneTimeWorkRequestBuilder
|
||||||
import androidx.work.PeriodicWorkRequestBuilder
|
import androidx.work.PeriodicWorkRequestBuilder
|
||||||
|
import androidx.work.WorkInfo
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
|
import com.paulinasadowska.rxworkmanagerobservers.extensions.getWorkInfoByIdObservable
|
||||||
import io.github.wulkanowy.data.db.SharedPrefProvider
|
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||||
import io.github.wulkanowy.data.db.SharedPrefProvider.Companion.APP_VERSION_CODE_KEY
|
import io.github.wulkanowy.data.db.SharedPrefProvider.Companion.APP_VERSION_CODE_KEY
|
||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.services.sync.channels.Channel
|
import io.github.wulkanowy.services.sync.channels.Channel
|
||||||
import io.github.wulkanowy.utils.AppInfo
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.isHolidays
|
import io.github.wulkanowy.utils.isHolidays
|
||||||
|
import io.reactivex.Observable
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.concurrent.TimeUnit.MINUTES
|
import java.util.concurrent.TimeUnit.MINUTES
|
||||||
@ -42,13 +48,13 @@ class SyncManager @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sharedPrefProvider.getLong(APP_VERSION_CODE_KEY, -1L) != appInfo.versionCode.toLong()) {
|
if (sharedPrefProvider.getLong(APP_VERSION_CODE_KEY, -1L) != appInfo.versionCode.toLong()) {
|
||||||
startSyncWorker(true)
|
startPeriodicSyncWorker(true)
|
||||||
sharedPrefProvider.putLong(APP_VERSION_CODE_KEY, appInfo.versionCode.toLong(), true)
|
sharedPrefProvider.putLong(APP_VERSION_CODE_KEY, appInfo.versionCode.toLong(), true)
|
||||||
}
|
}
|
||||||
Timber.i("SyncManager was initialized")
|
Timber.i("SyncManager was initialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startSyncWorker(restart: Boolean = false) {
|
fun startPeriodicSyncWorker(restart: Boolean = false) {
|
||||||
if (preferencesRepository.isServiceEnabled && !now().isHolidays) {
|
if (preferencesRepository.isServiceEnabled && !now().isHolidays) {
|
||||||
workManager.enqueueUniquePeriodicWork(SyncWorker::class.java.simpleName, if (restart) REPLACE else KEEP,
|
workManager.enqueueUniquePeriodicWork(SyncWorker::class.java.simpleName, if (restart) REPLACE else KEEP,
|
||||||
PeriodicWorkRequestBuilder<SyncWorker>(preferencesRepository.servicesInterval, MINUTES)
|
PeriodicWorkRequestBuilder<SyncWorker>(preferencesRepository.servicesInterval, MINUTES)
|
||||||
@ -61,6 +67,19 @@ class SyncManager @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun startOneTimeSyncWorker(): Observable<WorkInfo> {
|
||||||
|
val work = OneTimeWorkRequestBuilder<SyncWorker>()
|
||||||
|
.setInputData(
|
||||||
|
Data.Builder()
|
||||||
|
.putBoolean("one_time", true)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
workManager.enqueueUniqueWork("${SyncWorker::class.java.simpleName}_one_time", ExistingWorkPolicy.REPLACE, work)
|
||||||
|
return workManager.getWorkInfoByIdObservable(work.id)
|
||||||
|
}
|
||||||
|
|
||||||
fun stopSyncWorker() {
|
fun stopSyncWorker() {
|
||||||
workManager.cancelUniqueWork(SyncWorker::class.java.simpleName)
|
workManager.cancelUniqueWork(SyncWorker::class.java.simpleName)
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package io.github.wulkanowy.services.sync
|
package io.github.wulkanowy.services.sync
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.os.Build.VERSION_CODES.LOLLIPOP
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationCompat.BigTextStyle
|
import androidx.core.app.NotificationCompat.BigTextStyle
|
||||||
import androidx.core.app.NotificationCompat.PRIORITY_DEFAULT
|
import androidx.core.app.NotificationCompat.PRIORITY_DEFAULT
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import androidx.work.Data
|
||||||
import androidx.work.ListenableWorker
|
import androidx.work.ListenableWorker
|
||||||
import androidx.work.RxWorker
|
import androidx.work.RxWorker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
@ -17,6 +19,7 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
|
|||||||
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
|
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
|
||||||
import io.github.wulkanowy.services.sync.channels.DebugChannel
|
import io.github.wulkanowy.services.sync.channels.DebugChannel
|
||||||
import io.github.wulkanowy.services.sync.works.Work
|
import io.github.wulkanowy.services.sync.works.Work
|
||||||
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.getCompatColor
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@ -30,7 +33,8 @@ class SyncWorker @AssistedInject constructor(
|
|||||||
private val semesterRepository: SemesterRepository,
|
private val semesterRepository: SemesterRepository,
|
||||||
private val works: Set<@JvmSuppressWildcards Work>,
|
private val works: Set<@JvmSuppressWildcards Work>,
|
||||||
private val preferencesRepository: PreferencesRepository,
|
private val preferencesRepository: PreferencesRepository,
|
||||||
private val notificationManager: NotificationManagerCompat
|
private val notificationManager: NotificationManagerCompat,
|
||||||
|
private val appInfo: AppInfo
|
||||||
) : RxWorker(appContext, workerParameters) {
|
) : RxWorker(appContext, workerParameters) {
|
||||||
|
|
||||||
override fun createWork(): Single<Result> {
|
override fun createWork(): Single<Result> {
|
||||||
@ -52,8 +56,15 @@ class SyncWorker @AssistedInject constructor(
|
|||||||
.toSingleDefault(Result.success())
|
.toSingleDefault(Result.success())
|
||||||
.onErrorReturn {
|
.onErrorReturn {
|
||||||
Timber.e(it, "There was an error during synchronization")
|
Timber.e(it, "There was an error during synchronization")
|
||||||
if (it is FeatureDisabledException) Result.success()
|
when {
|
||||||
else Result.retry()
|
it is FeatureDisabledException -> Result.success()
|
||||||
|
inputData.getBoolean("one_time", false) -> {
|
||||||
|
Result.failure(Data.Builder()
|
||||||
|
.putString("error", it.toString())
|
||||||
|
.build())
|
||||||
|
}
|
||||||
|
else -> Result.retry()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.doOnSuccess {
|
.doOnSuccess {
|
||||||
if (preferencesRepository.isDebugNotificationEnable) notify(it)
|
if (preferencesRepository.isDebugNotificationEnable) notify(it)
|
||||||
@ -64,7 +75,7 @@ class SyncWorker @AssistedInject constructor(
|
|||||||
private fun notify(result: Result) {
|
private fun notify(result: Result) {
|
||||||
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(applicationContext, DebugChannel.CHANNEL_ID)
|
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(applicationContext, DebugChannel.CHANNEL_ID)
|
||||||
.setContentTitle("Debug notification")
|
.setContentTitle("Debug notification")
|
||||||
.setSmallIcon(R.drawable.ic_more_settings)
|
.setSmallIcon(R.drawable.ic_stat_push)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setColor(applicationContext.getCompatColor(R.color.colorPrimary))
|
.setColor(applicationContext.getCompatColor(R.color.colorPrimary))
|
||||||
.setStyle(BigTextStyle().bigText("${SyncWorker::class.java.simpleName} result: $result"))
|
.setStyle(BigTextStyle().bigText("${SyncWorker::class.java.simpleName} result: $result"))
|
||||||
|
@ -33,7 +33,7 @@ class MainPresenter @Inject constructor(
|
|||||||
Timber.i("Main view was initialized with $startMenuIndex menu index and $startMenuMoreIndex more index")
|
Timber.i("Main view was initialized with $startMenuIndex menu index and $startMenuMoreIndex more index")
|
||||||
}
|
}
|
||||||
|
|
||||||
syncManager.startSyncWorker()
|
syncManager.startPeriodicSyncWorker()
|
||||||
analytics.logEvent("app_open", "destination" to initMenu?.name)
|
analytics.logEvent("app_open", "destination" to initMenu?.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.ui.modules.settings
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import com.yariksoffice.lingver.Lingver
|
import com.yariksoffice.lingver.Lingver
|
||||||
@ -33,11 +34,24 @@ class SettingsFragment : PreferenceFragmentCompat(),
|
|||||||
|
|
||||||
override val titleStringId get() = R.string.settings_title
|
override val titleStringId get() = R.string.settings_title
|
||||||
|
|
||||||
|
override val syncSuccessString get() = getString(R.string.pref_services_message_sync_success)
|
||||||
|
|
||||||
|
override val syncFailedString get() = getString(R.string.pref_services_message_sync_failed)
|
||||||
|
|
||||||
override fun onAttach(context: Context) {
|
override fun onAttach(context: Context) {
|
||||||
AndroidSupportInjection.inject(this)
|
AndroidSupportInjection.inject(this)
|
||||||
super.onAttach(context)
|
super.onAttach(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun initView() {
|
||||||
|
findPreference<Preference>(getString(R.string.pref_key_services_force_sync))?.run {
|
||||||
|
onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||||
|
presenter.onSyncNowClicked()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
presenter.onAttachView(this)
|
presenter.onAttachView(this)
|
||||||
@ -61,12 +75,19 @@ class SettingsFragment : PreferenceFragmentCompat(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun setServicesSuspended(serviceEnablesKey: String, isHolidays: Boolean) {
|
override fun setServicesSuspended(serviceEnablesKey: String, isHolidays: Boolean) {
|
||||||
findPreference<Preference>(serviceEnablesKey)?.apply {
|
findPreference<Preference>(serviceEnablesKey)?.run {
|
||||||
summary = if (isHolidays) getString(R.string.pref_services_suspended) else ""
|
summary = if (isHolidays) getString(R.string.pref_services_suspended) else ""
|
||||||
isEnabled = !isHolidays
|
isEnabled = !isHolidays
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun setSyncInProgress(inProgress: Boolean) {
|
||||||
|
findPreference<Preference>(getString(R.string.pref_key_services_force_sync))?.run {
|
||||||
|
isEnabled = !inProgress
|
||||||
|
summary = if (inProgress) getString(R.string.pref_services_sync_in_progress) else ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun showError(text: String, error: Throwable) {
|
override fun showError(text: String, error: Throwable) {
|
||||||
(activity as? BaseActivity<*>)?.showError(text, error)
|
(activity as? BaseActivity<*>)?.showError(text, error)
|
||||||
}
|
}
|
||||||
@ -87,6 +108,15 @@ class SettingsFragment : PreferenceFragmentCompat(),
|
|||||||
ErrorDialog.newInstance(error).show(childFragmentManager, error.toString())
|
ErrorDialog.newInstance(error).show(childFragmentManager, error.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun showForceSyncDialog() {
|
||||||
|
AlertDialog.Builder(requireContext())
|
||||||
|
.setTitle(R.string.pref_services_dialog_force_sync_title)
|
||||||
|
.setMessage(R.string.pref_services_dialog_force_sync_summary)
|
||||||
|
.setPositiveButton(android.R.string.ok) { _, _ -> presenter.onForceSyncDialogSubmit() }
|
||||||
|
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
|
preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.settings
|
package io.github.wulkanowy.ui.modules.settings
|
||||||
|
|
||||||
|
import androidx.work.WorkInfo
|
||||||
import com.chuckerteam.chucker.api.ChuckerCollector
|
import com.chuckerteam.chucker.api.ChuckerCollector
|
||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
@ -29,6 +30,7 @@ class SettingsPresenter @Inject constructor(
|
|||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
Timber.i("Settings view was initialized")
|
Timber.i("Settings view was initialized")
|
||||||
view.setServicesSuspended(preferencesRepository.serviceEnableKey, now().isHolidays)
|
view.setServicesSuspended(preferencesRepository.serviceEnableKey, now().isHolidays)
|
||||||
|
view.initView()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onSharedPreferenceChanged(key: String) {
|
fun onSharedPreferenceChanged(key: String) {
|
||||||
@ -36,8 +38,8 @@ class SettingsPresenter @Inject constructor(
|
|||||||
|
|
||||||
with(preferencesRepository) {
|
with(preferencesRepository) {
|
||||||
when (key) {
|
when (key) {
|
||||||
serviceEnableKey -> with(syncManager) { if (isServiceEnabled) startSyncWorker() else stopSyncWorker() }
|
serviceEnableKey -> with(syncManager) { if (isServiceEnabled) startPeriodicSyncWorker() else stopSyncWorker() }
|
||||||
servicesIntervalKey, servicesOnlyWifiKey -> syncManager.startSyncWorker(true)
|
servicesIntervalKey, servicesOnlyWifiKey -> syncManager.startPeriodicSyncWorker(true)
|
||||||
isDebugNotificationEnableKey -> chuckerCollector.showNotification = isDebugNotificationEnable
|
isDebugNotificationEnableKey -> chuckerCollector.showNotification = isDebugNotificationEnable
|
||||||
appThemeKey -> view?.recreateView()
|
appThemeKey -> view?.recreateView()
|
||||||
appLanguageKey -> view?.run {
|
appLanguageKey -> view?.run {
|
||||||
@ -49,4 +51,25 @@ class SettingsPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
analytics.logEvent("setting_changed", "name" to key)
|
analytics.logEvent("setting_changed", "name" to key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onSyncNowClicked() {
|
||||||
|
view?.showForceSyncDialog()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onForceSyncDialogSubmit() {
|
||||||
|
view?.run {
|
||||||
|
Timber.i("Setting sync now started")
|
||||||
|
analytics.logEvent("sync_now_started")
|
||||||
|
disposable.add(syncManager.startOneTimeSyncWorker()
|
||||||
|
.doOnSubscribe { setSyncInProgress(true) }
|
||||||
|
.doFinally { setSyncInProgress(false) }
|
||||||
|
.subscribe({ workInfo ->
|
||||||
|
if (workInfo.state == WorkInfo.State.SUCCEEDED) showMessage(syncSuccessString)
|
||||||
|
else if (workInfo.state == WorkInfo.State.FAILED) showError(syncFailedString, Throwable(workInfo.outputData.getString("error")))
|
||||||
|
}, {
|
||||||
|
Timber.e("Sync now failed")
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,19 @@ import io.github.wulkanowy.ui.base.BaseView
|
|||||||
|
|
||||||
interface SettingsView : BaseView {
|
interface SettingsView : BaseView {
|
||||||
|
|
||||||
|
val syncSuccessString: String
|
||||||
|
|
||||||
|
val syncFailedString: String
|
||||||
|
|
||||||
|
fun initView()
|
||||||
|
|
||||||
fun recreateView()
|
fun recreateView()
|
||||||
|
|
||||||
fun updateLanguage(langCode: String)
|
fun updateLanguage(langCode: String)
|
||||||
|
|
||||||
fun setServicesSuspended(serviceEnablesKey: String, isHolidays: Boolean)
|
fun setServicesSuspended(serviceEnablesKey: String, isHolidays: Boolean)
|
||||||
|
|
||||||
|
fun setSyncInProgress(inProgress: Boolean)
|
||||||
|
|
||||||
|
fun showForceSyncDialog()
|
||||||
}
|
}
|
||||||
|
@ -375,6 +375,15 @@
|
|||||||
<string name="pref_services_suspended">Zawieszona na wakacjach</string>
|
<string name="pref_services_suspended">Zawieszona na wakacjach</string>
|
||||||
<string name="pref_services_interval">Interwał aktualizacji</string>
|
<string name="pref_services_interval">Interwał aktualizacji</string>
|
||||||
<string name="pref_services_wifi">Tylko WiFi</string>
|
<string name="pref_services_wifi">Tylko WiFi</string>
|
||||||
|
<string name="pref_services_force_sync">Synchronizuj teraz</string>
|
||||||
|
<string name="pref_services_message_sync_success">Zsynchronizowano!</string>
|
||||||
|
<string name="pref_services_message_sync_failed">Synchronizacja nie powiodła się</string>
|
||||||
|
<string name="pref_services_sync_in_progress">Synchronizacja w trakcie</string>
|
||||||
|
<string name="pref_services_dialog_force_sync_title">Synchronizacja</string>
|
||||||
|
<string name="pref_services_dialog_force_sync_summary">
|
||||||
|
Ręczna synchronizacja nie odświeża widoków w aplikacji.
|
||||||
|
\nAby zobaczyć zsynchronizowane informacje uruchom ponownie aplikację po zsynchronizowaniu.
|
||||||
|
</string>
|
||||||
|
|
||||||
<string name="pref_other_header">Inne</string>
|
<string name="pref_other_header">Inne</string>
|
||||||
<string name="pref_other_grade_modifier_plus">Wartość plusa</string>
|
<string name="pref_other_grade_modifier_plus">Wartość plusa</string>
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
<string name="pref_key_services_enable">services_enable</string>
|
<string name="pref_key_services_enable">services_enable</string>
|
||||||
<string name="pref_key_services_interval">services_interval</string>
|
<string name="pref_key_services_interval">services_interval</string>
|
||||||
<string name="pref_key_services_wifi_only">services_disable_wifi_only</string>
|
<string name="pref_key_services_wifi_only">services_disable_wifi_only</string>
|
||||||
|
<string name="pref_key_services_force_sync">services_force_sync</string>
|
||||||
<string name="pref_key_notifications_enable">notifications_enable</string>
|
<string name="pref_key_notifications_enable">notifications_enable</string>
|
||||||
<string name="pref_key_notification_debug">notification_debug</string>
|
<string name="pref_key_notification_debug">notification_debug</string>
|
||||||
<string name="pref_key_grade_modifier_plus">grade_modifier_plus</string>
|
<string name="pref_key_grade_modifier_plus">grade_modifier_plus</string>
|
||||||
|
@ -360,6 +360,15 @@
|
|||||||
<string name="pref_services_suspended">Suspended on holidays</string>
|
<string name="pref_services_suspended">Suspended on holidays</string>
|
||||||
<string name="pref_services_interval">Updates interval</string>
|
<string name="pref_services_interval">Updates interval</string>
|
||||||
<string name="pref_services_wifi">Wi-Fi only</string>
|
<string name="pref_services_wifi">Wi-Fi only</string>
|
||||||
|
<string name="pref_services_force_sync">Sync now</string>
|
||||||
|
<string name="pref_services_message_sync_success">Synced!</string>
|
||||||
|
<string name="pref_services_message_sync_failed">Sync failed</string>
|
||||||
|
<string name="pref_services_sync_in_progress">Sync in progress</string>
|
||||||
|
<string name="pref_services_dialog_force_sync_title">Synchronization</string>
|
||||||
|
<string name="pref_services_dialog_force_sync_summary">
|
||||||
|
Manual sync doesn\'t refresh app views.
|
||||||
|
\nTo see the synced data relaunch the app after syncing.
|
||||||
|
</string>
|
||||||
|
|
||||||
<string name="pref_other_header">Other</string>
|
<string name="pref_other_header">Other</string>
|
||||||
<string name="pref_other_grade_modifier_plus">Value of the plus</string>
|
<string name="pref_other_grade_modifier_plus">Value of the plus</string>
|
||||||
|
@ -77,6 +77,10 @@
|
|||||||
app:iconSpaceReserved="false"
|
app:iconSpaceReserved="false"
|
||||||
app:key="@string/pref_key_services_wifi_only"
|
app:key="@string/pref_key_services_wifi_only"
|
||||||
app:title="@string/pref_services_wifi" />
|
app:title="@string/pref_services_wifi" />
|
||||||
|
<Preference
|
||||||
|
app:iconSpaceReserved="false"
|
||||||
|
app:title="@string/pref_services_force_sync"
|
||||||
|
app:key="@string/pref_key_services_force_sync" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
app:iconSpaceReserved="false"
|
app:iconSpaceReserved="false"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user