Migrate autosave logic to viewmodel and fix failing UI tests
This commit is contained in:
parent
f2ed687b02
commit
ed57785d0a
5 changed files with 49 additions and 36 deletions
|
@ -66,7 +66,7 @@ class MarkdownTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun newMarkdownTest() {
|
fun newMarkdownTest() {
|
||||||
onView(withId(R.id.markdown_edit))
|
onView(withId(R.id.markdown_edit))
|
||||||
.perform(typeText("# UI Testing\n\nThe quick brown fox jumped over the lazy dog."))
|
.perform(typeText("# UI Testing\n\nThe quick brown fox jumped over the lazy dog."))
|
||||||
openActionBarOverflowOrOptionsMenu(getApplicationContext())
|
openActionBarOverflowOrOptionsMenu(getApplicationContext())
|
||||||
|
|
|
@ -8,6 +8,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.wbrawner.simplemarkdown.R
|
import com.wbrawner.simplemarkdown.R
|
||||||
|
import com.wbrawner.simplemarkdown.viewmodel.PREF_KEY_AUTOSAVE_URI
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
@ -43,10 +44,8 @@ class SplashActivity : AppCompatActivity(), CoroutineScope {
|
||||||
val uri = withContext(Dispatchers.IO) {
|
val uri = withContext(Dispatchers.IO) {
|
||||||
intent?.data
|
intent?.data
|
||||||
?: PreferenceManager.getDefaultSharedPreferences(this@SplashActivity)
|
?: PreferenceManager.getDefaultSharedPreferences(this@SplashActivity)
|
||||||
.getString(
|
.getString(PREF_KEY_AUTOSAVE_URI, null)
|
||||||
getString(R.string.pref_key_autosave_uri),
|
?.let {
|
||||||
null
|
|
||||||
)?.let {
|
|
||||||
Uri.parse(it)
|
Uri.parse(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import android.content.res.Configuration
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.webkit.MimeTypeMap
|
import android.webkit.MimeTypeMap
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
@ -29,6 +30,7 @@ import com.wbrawner.simplemarkdown.utility.ErrorHandler
|
||||||
import com.wbrawner.simplemarkdown.utility.errorHandlerImpl
|
import com.wbrawner.simplemarkdown.utility.errorHandlerImpl
|
||||||
import com.wbrawner.simplemarkdown.view.adapter.EditPagerAdapter
|
import com.wbrawner.simplemarkdown.view.adapter.EditPagerAdapter
|
||||||
import com.wbrawner.simplemarkdown.viewmodel.MarkdownViewModel
|
import com.wbrawner.simplemarkdown.viewmodel.MarkdownViewModel
|
||||||
|
import com.wbrawner.simplemarkdown.viewmodel.PREF_KEY_AUTOSAVE_URI
|
||||||
import kotlinx.android.synthetic.main.fragment_main.*
|
import kotlinx.android.synthetic.main.fragment_main.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
@ -98,6 +100,7 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||||
}
|
}
|
||||||
R.id.action_save -> {
|
R.id.action_save -> {
|
||||||
launch {
|
launch {
|
||||||
|
Log.d("SimpleMarkdown", "Saving file from onOptionsItemSelected")
|
||||||
if (!viewModel.save(requireContext())) {
|
if (!viewModel.save(requireContext())) {
|
||||||
requestFileOp(REQUEST_SAVE_FILE)
|
requestFileOp(REQUEST_SAVE_FILE)
|
||||||
} else {
|
} else {
|
||||||
|
@ -154,32 +157,9 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
|
val context = context?.applicationContext ?: return
|
||||||
launch {
|
launch {
|
||||||
val context = context?.applicationContext ?: return@launch
|
viewModel.autosave(context, PreferenceManager.getDefaultSharedPreferences(context))
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +211,7 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PreferenceManager.getDefaultSharedPreferences(requireContext()).edit {
|
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 {
|
launch {
|
||||||
context?.let {
|
context?.let {
|
||||||
|
Log.d("SimpleMarkdown", "Saving file from onActivityResult")
|
||||||
viewModel.save(it, data.data)
|
viewModel.save(it, data.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,10 +233,10 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun promptSaveOrDiscardChanges() {
|
private fun promptSaveOrDiscardChanges() {
|
||||||
if (viewModel.shouldPromptSave()) {
|
if (!viewModel.shouldPromptSave()) {
|
||||||
viewModel.reset("Untitled.md")
|
viewModel.reset("Untitled.md")
|
||||||
PreferenceManager.getDefaultSharedPreferences(requireContext()).edit {
|
PreferenceManager.getDefaultSharedPreferences(requireContext()).edit {
|
||||||
remove(getString(R.string.pref_key_autosave_uri))
|
remove(PREF_KEY_AUTOSAVE_URI)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -266,7 +247,7 @@ class MainFragment : Fragment(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||||
.setNegativeButton(R.string.action_discard) { _, _ ->
|
.setNegativeButton(R.string.action_discard) { _, _ ->
|
||||||
viewModel.reset("Untitled.md")
|
viewModel.reset("Untitled.md")
|
||||||
PreferenceManager.getDefaultSharedPreferences(requireContext()).edit {
|
PreferenceManager.getDefaultSharedPreferences(requireContext()).edit {
|
||||||
remove(getString(R.string.pref_key_autosave_uri))
|
remove(PREF_KEY_AUTOSAVE_URI)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.setPositiveButton(R.string.action_save) { _, _ ->
|
.setPositiveButton(R.string.action_save) { _, _ ->
|
||||||
|
|
|
@ -1,18 +1,26 @@
|
||||||
package com.wbrawner.simplemarkdown.viewmodel
|
package com.wbrawner.simplemarkdown.viewmodel
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.util.Log
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
|
import com.wbrawner.simplemarkdown.R
|
||||||
import com.wbrawner.simplemarkdown.utility.getName
|
import com.wbrawner.simplemarkdown.utility.getName
|
||||||
|
import com.wbrawner.simplemarkdown.view.fragment.MainFragment
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.Reader
|
import java.io.Reader
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
|
const val PREF_KEY_AUTOSAVE_URI = "autosave.uri"
|
||||||
|
|
||||||
class MarkdownViewModel : ViewModel() {
|
class MarkdownViewModel : ViewModel() {
|
||||||
val fileName = MutableLiveData<String>("Untitled.md")
|
val fileName = MutableLiveData<String?>("Untitled.md")
|
||||||
val markdownUpdates = MutableLiveData<String>()
|
val markdownUpdates = MutableLiveData<String>()
|
||||||
val editorActions = MutableLiveData<EditorAction>()
|
val editorActions = MutableLiveData<EditorAction>()
|
||||||
val uri = MutableLiveData<Uri?>()
|
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) {
|
fun reset(untitledFileName: String) {
|
||||||
fileName.postValue(untitledFileName)
|
fileName.postValue(untitledFileName)
|
||||||
uri.postValue(null)
|
uri.postValue(null)
|
||||||
|
|
|
@ -58,7 +58,6 @@
|
||||||
<string name="pref_key_dark_mode_light" translatable="false">light</string>
|
<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_dark" translatable="false">dark</string>
|
||||||
<string name="pref_key_dark_mode_auto" translatable="false">auto</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="save_changes">Save Changes</string>
|
||||||
<string name="prompt_save_changes">Would you like to save your changes?</string>
|
<string name="prompt_save_changes">Would you like to save your changes?</string>
|
||||||
<string name="action_discard">Discard</string>
|
<string name="action_discard">Discard</string>
|
||||||
|
|
Loading…
Reference in a new issue