@ -4,7 +4,9 @@
package org.mozilla.fenix.settings
package org.mozilla.fenix.settings
import android.content.Context
import android.os.Bundle
import android.os.Bundle
import android.text.format.DateUtils
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.Navigation
import androidx.navigation.Navigation
import androidx.preference.Preference
import androidx.preference.Preference
@ -13,9 +15,12 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.launch
import mozilla.components.concept.sync.SyncStatusObserver
import mozilla.components.feature.sync.getLastSynced
import org.mozilla.fenix.R
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.requireComponents
import java.lang.Exception
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.CoroutineContext
class AccountSettingsFragment : PreferenceFragmentCompat ( ) , CoroutineScope {
class AccountSettingsFragment : PreferenceFragmentCompat ( ) , CoroutineScope {
@ -38,9 +43,28 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), CoroutineScope {
override fun onCreatePreferences ( savedInstanceState : Bundle ? , rootKey : String ? ) {
override fun onCreatePreferences ( savedInstanceState : Bundle ? , rootKey : String ? ) {
setPreferencesFromResource ( R . xml . account _settings _preferences , rootKey )
setPreferencesFromResource ( R . xml . account _settings _preferences , rootKey )
val signIn = context ?. getPreferenceKey ( R . string . pref _key _sign _out )
// Sign out
val preferenceSignOut = findPreference < Preference > ( signIn )
val signOut = context ?. getPreferenceKey ( R . string . pref _key _sign _out )
val preferenceSignOut = findPreference < Preference > ( signOut )
preferenceSignOut . onPreferenceClickListener = getClickListenerForSignOut ( )
preferenceSignOut . onPreferenceClickListener = getClickListenerForSignOut ( )
// Sync now
val syncNow = context ?. getPreferenceKey ( R . string . pref _key _sync _now )
val preferenceSyncNow = findPreference < Preference > ( syncNow )
preferenceSyncNow . onPreferenceClickListener = getClickListenerForSyncNow ( )
// Current sync state
updateLastSyncedTimePref ( context !! , preferenceSyncNow )
if ( requireComponents . backgroundServices . syncManager . isSyncRunning ( ) ) {
preferenceSyncNow . title = getString ( R . string . sync _syncing )
preferenceSyncNow . isEnabled = false
} else {
preferenceSyncNow . isEnabled = true
}
// NB: ObserverRegistry will take care of cleaning up internal references to 'observer' and
// 'owner' when appropriate.
requireComponents . backgroundServices . syncManager . register ( syncStatusObserver , owner = this , autoPause = true )
}
}
private fun getClickListenerForSignOut ( ) : Preference . OnPreferenceClickListener {
private fun getClickListenerForSignOut ( ) : Preference . OnPreferenceClickListener {
@ -52,4 +76,66 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), CoroutineScope {
true
true
}
}
}
}
private fun getClickListenerForSyncNow ( ) : Preference . OnPreferenceClickListener {
return Preference . OnPreferenceClickListener {
requireComponents . backgroundServices . syncManager . syncNow ( )
true
}
}
private val syncStatusObserver = object : SyncStatusObserver {
override fun onStarted ( ) {
CoroutineScope ( Dispatchers . Main ) . launch {
val pref = findPreference < Preference > ( context ?. getPreferenceKey ( R . string . pref _key _sync _now ) )
pref . title = getString ( R . string . sync _syncing )
pref . isEnabled = false
}
}
// Sync stopped successfully.
override fun onIdle ( ) {
CoroutineScope ( Dispatchers . Main ) . launch {
val pref = findPreference < Preference > ( context ?. getPreferenceKey ( R . string . pref _key _sync _now ) )
pref . title = getString ( R . string . preferences _sync _now )
pref . isEnabled = true
updateLastSyncedTimePref ( context !! , pref , failed = false )
}
}
// Sync stopped after encountering a problem.
override fun onError ( error : Exception ? ) {
CoroutineScope ( Dispatchers . Main ) . launch {
val pref = findPreference < Preference > ( context ?. getPreferenceKey ( R . string . pref _key _sync _now ) )
pref . title = getString ( R . string . preferences _sync _now )
pref . isEnabled = true
updateLastSyncedTimePref ( context !! , pref , failed = true )
}
}
}
fun updateLastSyncedTimePref ( context : Context , pref : Preference , failed : Boolean = false ) {
val lastSyncTime = getLastSynced ( context )
pref . summary = if ( ! failed && lastSyncTime == 0L ) {
// Never tried to sync.
getString ( R . string . sync _never _synced _summary )
} else if ( failed && lastSyncTime == 0L ) {
// Failed to sync, never succeeded before.
getString ( R . string . sync _failed _never _synced _summary )
} else if ( ! failed && lastSyncTime != 0L ) {
// Successfully synced.
getString (
R . string . sync _last _synced _summary ,
DateUtils . getRelativeTimeSpanString ( lastSyncTime )
)
} else {
// Failed to sync, succeeded before.
getString (
R . string . sync _failed _summary ,
DateUtils . getRelativeTimeSpanString ( lastSyncTime )
)
}
}
}
}