Migrate autosave logic to viewmodel and fix failing UI tests

This commit is contained in:
William Brawner 2021-02-20 20:35:28 -07:00
parent f2ed687b02
commit ed57785d0a
5 changed files with 49 additions and 36 deletions

View file

@ -66,7 +66,7 @@ class MarkdownTests {
}
@Test
fun newMarkdownTest() {
fun newMarkdownTest() {
onView(withId(R.id.markdown_edit))
.perform(typeText("# UI Testing\n\nThe quick brown fox jumped over the lazy dog."))
openActionBarOverflowOrOptionsMenu(getApplicationContext())

View file

@ -8,6 +8,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.PreferenceManager
import com.wbrawner.simplemarkdown.R
import com.wbrawner.simplemarkdown.viewmodel.PREF_KEY_AUTOSAVE_URI
import kotlinx.coroutines.*
import kotlin.coroutines.CoroutineContext
@ -43,10 +44,8 @@ class SplashActivity : AppCompatActivity(), CoroutineScope {
val uri = withContext(Dispatchers.IO) {
intent?.data
?: PreferenceManager.getDefaultSharedPreferences(this@SplashActivity)
.getString(
getString(R.string.pref_key_autosave_uri),
null
)?.let {
.getString(PREF_KEY_AUTOSAVE_URI, null)
?.let {
Uri.parse(it)
}
}

View file

@ -9,6 +9,7 @@ import android.content.res.Configuration
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.*
import android.webkit.MimeTypeMap
import android.widget.Toast
@ -29,6 +30,7 @@ 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.*
import java.io.File
@ -98,6 +100,7 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
}
R.id.action_save -> {
launch {
Log.d("SimpleMarkdown", "Saving file from onOptionsItemSelected")
if (!viewModel.save(requireContext())) {
requestFileOp(REQUEST_SAVE_FILE)
} else {
@ -154,32 +157,9 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
override fun onPause() {
super.onPause()
val context = context?.applicationContext ?: return
launch {
val context = context?.applicationContext ?: return@launch
withContext(Dispatchers.IO) {
val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context)
val isAutoSaveEnabled = sharedPrefs.getBoolean(KEY_AUTOSAVE, true)
if (!shouldAutoSave || !isAutoSaveEnabled) {
return@withContext
}
val uri = if (viewModel.save(context)) {
viewModel.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, viewModel.fileName.value!!))
if (viewModel.save(context, fileUri)) {
fileUri
} else {
null
}
} ?: return@withContext
sharedPrefs.edit()
.putString(getString(R.string.pref_key_autosave_uri), uri.toString())
.apply()
}
viewModel.autosave(context, PreferenceManager.getDefaultSharedPreferences(context))
}
}
@ -231,7 +211,7 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
}
} else {
PreferenceManager.getDefaultSharedPreferences(requireContext()).edit {
putString(getString(R.string.pref_key_autosave_uri), data.data.toString())
putString(PREF_KEY_AUTOSAVE_URI, data.data.toString())
}
}
}
@ -243,6 +223,7 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
launch {
context?.let {
Log.d("SimpleMarkdown", "Saving file from onActivityResult")
viewModel.save(it, data.data)
}
}
@ -252,10 +233,10 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
}
private fun promptSaveOrDiscardChanges() {
if (viewModel.shouldPromptSave()) {
if (!viewModel.shouldPromptSave()) {
viewModel.reset("Untitled.md")
PreferenceManager.getDefaultSharedPreferences(requireContext()).edit {
remove(getString(R.string.pref_key_autosave_uri))
remove(PREF_KEY_AUTOSAVE_URI)
}
return
}
@ -266,7 +247,7 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
.setNegativeButton(R.string.action_discard) { _, _ ->
viewModel.reset("Untitled.md")
PreferenceManager.getDefaultSharedPreferences(requireContext()).edit {
remove(getString(R.string.pref_key_autosave_uri))
remove(PREF_KEY_AUTOSAVE_URI)
}
}
.setPositiveButton(R.string.action_save) { _, _ ->

View file

@ -1,18 +1,26 @@
package com.wbrawner.simplemarkdown.viewmodel
import android.content.Context
import android.content.SharedPreferences
import android.net.Uri
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.preference.PreferenceManager
import com.wbrawner.simplemarkdown.R
import com.wbrawner.simplemarkdown.utility.getName
import com.wbrawner.simplemarkdown.view.fragment.MainFragment
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileInputStream
import java.io.Reader
import java.util.concurrent.atomic.AtomicBoolean
const val PREF_KEY_AUTOSAVE_URI = "autosave.uri"
class MarkdownViewModel : ViewModel() {
val fileName = MutableLiveData<String>("Untitled.md")
val fileName = MutableLiveData<String?>("Untitled.md")
val markdownUpdates = MutableLiveData<String>()
val editorActions = MutableLiveData<EditorAction>()
val uri = MutableLiveData<Uri?>()
@ -68,6 +76,32 @@ class MarkdownViewModel : ViewModel() {
}
}
suspend fun autosave(context: Context, sharedPrefs: SharedPreferences) {
val isAutoSaveEnabled = sharedPrefs.getBoolean(MainFragment.KEY_AUTOSAVE, true)
if (!isDirty.get() || !isAutoSaveEnabled) {
return
}
val uri = if (save(context)) {
Log.d("SimpleMarkdown", "Saving file from onPause")
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"))
Log.d("SimpleMarkdown", "Saving file from onPause failed, trying again")
if (save(context, fileUri)) {
fileUri
} else {
null
}
} ?: return
sharedPrefs.edit()
.putString(PREF_KEY_AUTOSAVE_URI, uri.toString())
.apply()
}
fun reset(untitledFileName: String) {
fileName.postValue(untitledFileName)
uri.postValue(null)

View file

@ -58,7 +58,6 @@
<string name="pref_key_dark_mode_light" translatable="false">light</string>
<string name="pref_key_dark_mode_dark" translatable="false">dark</string>
<string name="pref_key_dark_mode_auto" translatable="false">auto</string>
<string name="pref_key_autosave_uri" translatable="false">autosave.uri</string>
<string name="save_changes">Save Changes</string>
<string name="prompt_save_changes">Would you like to save your changes?</string>
<string name="action_discard">Discard</string>