Consolidate autosave URI persistence management
This commit is contained in:
parent
1522806e62
commit
50d7622172
3 changed files with 50 additions and 61 deletions
|
@ -1,7 +1,6 @@
|
|||
package com.wbrawner.simplemarkdown.view.activity
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
|
@ -9,7 +8,6 @@ import androidx.appcompat.app.AppCompatDelegate
|
|||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.wbrawner.simplemarkdown.R
|
||||
import com.wbrawner.simplemarkdown.viewmodel.PREF_KEY_AUTOSAVE_URI
|
||||
import kotlinx.coroutines.*
|
||||
import timber.log.Timber
|
||||
|
||||
|
@ -40,20 +38,12 @@ class SplashActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
AppCompatDelegate.setDefaultNightMode(darkMode)
|
||||
val uri = withContext(Dispatchers.IO) {
|
||||
intent?.data?.let {
|
||||
Timber.d("Using uri from intent: $it")
|
||||
it
|
||||
} ?: PreferenceManager.getDefaultSharedPreferences(this@SplashActivity)
|
||||
.getString(PREF_KEY_AUTOSAVE_URI, null)
|
||||
?.let {
|
||||
Timber.d("Using uri from shared preferences: $it")
|
||||
Uri.parse(it)
|
||||
}
|
||||
}
|
||||
|
||||
if (uri == null) {
|
||||
val uri = intent?.data?.let {
|
||||
Timber.d("Using uri from intent: $it")
|
||||
it
|
||||
} ?: run {
|
||||
Timber.d("No intent provided to load data from")
|
||||
null
|
||||
}
|
||||
|
||||
val startIntent = Intent(this@SplashActivity, MainActivity::class.java)
|
||||
|
|
|
@ -15,7 +15,6 @@ import androidx.appcompat.app.AlertDialog
|
|||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.edit
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
|
@ -28,7 +27,6 @@ import com.wbrawner.simplemarkdown.utility.ErrorHandler
|
|||
import com.wbrawner.simplemarkdown.utility.errorHandlerImpl
|
||||
import com.wbrawner.simplemarkdown.view.adapter.EditPagerAdapter
|
||||
import com.wbrawner.simplemarkdown.viewmodel.MarkdownViewModel
|
||||
import com.wbrawner.simplemarkdown.viewmodel.PREF_KEY_AUTOSAVE_URI
|
||||
import kotlinx.android.synthetic.main.fragment_main.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -212,21 +210,9 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
|
|||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
val fileLoaded = context?.let {
|
||||
viewModel.load(it, data.data)
|
||||
}
|
||||
if (fileLoaded == false) {
|
||||
context?.let {
|
||||
Toast.makeText(it, R.string.file_load_error, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
} else {
|
||||
Timber.d(
|
||||
"File load succeeded, updating autosave uri in shared prefs: %s",
|
||||
data.data.toString()
|
||||
)
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext()).edit {
|
||||
putString(PREF_KEY_AUTOSAVE_URI, data.data.toString())
|
||||
context?.let {
|
||||
if (!viewModel.load(it, data.data)) {
|
||||
Toast.makeText(it, R.string.file_load_error, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -253,11 +239,10 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
|
|||
|
||||
private fun promptSaveOrDiscardChanges() {
|
||||
if (!viewModel.shouldPromptSave()) {
|
||||
viewModel.reset("Untitled.md")
|
||||
Timber.i("Removing autosave uri from shared prefs")
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext()).edit {
|
||||
remove(PREF_KEY_AUTOSAVE_URI)
|
||||
}
|
||||
viewModel.reset(
|
||||
"Untitled.md",
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
)
|
||||
return
|
||||
}
|
||||
val context = context ?: run {
|
||||
|
@ -268,11 +253,11 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
|
|||
.setTitle(R.string.save_changes)
|
||||
.setMessage(R.string.prompt_save_changes)
|
||||
.setNegativeButton(R.string.action_discard) { _, _ ->
|
||||
Timber.d("Discarding changes and deleting autosave uri from shared preferences")
|
||||
viewModel.reset("Untitled.md")
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext()).edit {
|
||||
remove(PREF_KEY_AUTOSAVE_URI)
|
||||
}
|
||||
Timber.d("Discarding changes")
|
||||
viewModel.reset(
|
||||
"Untitled.md",
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
)
|
||||
}
|
||||
.setPositiveButton(R.string.action_save) { _, _ ->
|
||||
Timber.d("Saving changes")
|
||||
|
|
|
@ -3,8 +3,10 @@ package com.wbrawner.simplemarkdown.viewmodel
|
|||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import androidx.core.content.edit
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.wbrawner.simplemarkdown.utility.getName
|
||||
import com.wbrawner.simplemarkdown.view.fragment.MainFragment
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -32,10 +34,18 @@ class MarkdownViewModel(val timber: Timber.Tree = Timber.asTree()) : ViewModel()
|
|||
isDirty.set(true)
|
||||
}
|
||||
|
||||
suspend fun load(context: Context, uri: Uri?): Boolean {
|
||||
suspend fun load(
|
||||
context: Context,
|
||||
uri: Uri?,
|
||||
sharedPrefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
): Boolean {
|
||||
if (uri == null) {
|
||||
timber.i("Ignoring call to load null uri")
|
||||
return false
|
||||
timber.i("No URI provided to load, attempting to load last autosaved file")
|
||||
sharedPrefs.getString(PREF_KEY_AUTOSAVE_URI, null)
|
||||
?.let {
|
||||
Timber.d("Using uri from shared preferences: $it")
|
||||
return load(context, Uri.parse(it), sharedPrefs)
|
||||
} ?: return false
|
||||
}
|
||||
return withContext(Dispatchers.IO) {
|
||||
try {
|
||||
|
@ -55,6 +65,10 @@ class MarkdownViewModel(val timber: Timber.Tree = Timber.asTree()) : ViewModel()
|
|||
timber.i("Loaded file $fileName from $fileInput")
|
||||
timber.v("File contents:\n$content")
|
||||
isDirty.set(false)
|
||||
timber.i("Persisting autosave uri in shared prefs: $uri")
|
||||
sharedPrefs.edit()
|
||||
.putString(PREF_KEY_AUTOSAVE_URI, uri.toString())
|
||||
.apply()
|
||||
true
|
||||
} ?: run {
|
||||
timber.w("Open file descriptor returned null for uri: $uri")
|
||||
|
@ -67,7 +81,11 @@ class MarkdownViewModel(val timber: Timber.Tree = Timber.asTree()) : ViewModel()
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun save(context: Context, givenUri: Uri? = null): Boolean = saveMutex.withLock {
|
||||
suspend fun save(
|
||||
context: Context,
|
||||
givenUri: Uri? = null,
|
||||
sharedPrefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
): Boolean = saveMutex.withLock {
|
||||
val uri = givenUri?.let {
|
||||
timber.i("Saving file with given uri: $it")
|
||||
it
|
||||
|
@ -94,6 +112,10 @@ class MarkdownViewModel(val timber: Timber.Tree = Timber.asTree()) : ViewModel()
|
|||
this@MarkdownViewModel.uri.postValue(uri)
|
||||
isDirty.set(false)
|
||||
timber.i("Saved file $fileName to uri $uri")
|
||||
timber.i("Persisting autosave uri in shared prefs: $uri")
|
||||
sharedPrefs.edit()
|
||||
.putString(PREF_KEY_AUTOSAVE_URI, uri.toString())
|
||||
.apply()
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
timber.e(e, "Failed to save file at uri: $uri")
|
||||
|
@ -114,37 +136,29 @@ class MarkdownViewModel(val timber: Timber.Tree = Timber.asTree()) : ViewModel()
|
|||
return
|
||||
}
|
||||
|
||||
val uri = if (save(context)) {
|
||||
if (save(context)) {
|
||||
timber.i("Autosave with cached uri succeeded: ${uri.value}")
|
||||
uri.value
|
||||
} else {
|
||||
// The user has left the app, with autosave enabled, and we don't already have a
|
||||
// Uri for them or for some reason we were unable to save to the original Uri. In
|
||||
// this case, we need to just save to internal file storage so that we can recover
|
||||
val fileUri = Uri.fromFile(File(context.filesDir, fileName.value ?: "Untitled.md"))
|
||||
timber.i("No cached uri for autosave, saving to $fileUri instead")
|
||||
if (save(context, fileUri)) {
|
||||
fileUri
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} ?: run {
|
||||
timber.w("Unable to perform autosave, uri was null")
|
||||
return@autosave
|
||||
save(context, fileUri)
|
||||
}
|
||||
timber.i("Persisting autosave uri in shared prefs: $uri")
|
||||
sharedPrefs.edit()
|
||||
.putString(PREF_KEY_AUTOSAVE_URI, uri.toString())
|
||||
.apply()
|
||||
}
|
||||
|
||||
fun reset(untitledFileName: String) {
|
||||
fun reset(untitledFileName: String, sharedPrefs: SharedPreferences) {
|
||||
timber.i("Resetting view model to default state")
|
||||
fileName.postValue(untitledFileName)
|
||||
uri.postValue(null)
|
||||
markdownUpdates.postValue("")
|
||||
editorActions.postValue(EditorAction.Load(""))
|
||||
isDirty.set(false)
|
||||
timber.i("Removing autosave uri from shared prefs")
|
||||
sharedPrefs.edit {
|
||||
remove(PREF_KEY_AUTOSAVE_URI)
|
||||
}
|
||||
}
|
||||
|
||||
fun shouldPromptSave() = isDirty.get()
|
||||
|
|
Loading…
Reference in a new issue