Skip to content

Commit

Permalink
Show dialog for Retry/Select root storage path again in case of load …
Browse files Browse the repository at this point in the history
…crash
  • Loading branch information
tuancoltech committed Dec 13, 2024
1 parent ef2436c commit e09da72
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import dev.arkbuilders.arklib.user.properties.PropertiesStorageRepo
import dev.arkbuilders.arkmemo.models.GraphicNote
import dev.arkbuilders.arkmemo.models.TextNote
import dev.arkbuilders.arkmemo.models.VoiceNote
import dev.arkbuilders.arkmemo.preferences.MemoPreferences
import dev.arkbuilders.arkmemo.repo.NotesRepo
import dev.arkbuilders.arkmemo.repo.NotesRepoHelper
import dev.arkbuilders.arkmemo.repo.graphics.GraphicNotesRepo
Expand Down Expand Up @@ -38,8 +37,7 @@ object RepoHelperModule {
@Singleton
@Provides
fun provideNotesRepoHelper(
memoPreferences: MemoPreferences,
propertiesStorageRepo: PropertiesStorageRepo,
@Named(IO_DISPATCHER) coroutineDispatcher: CoroutineDispatcher,
) = NotesRepoHelper(memoPreferences, propertiesStorageRepo, coroutineDispatcher)
) = NotesRepoHelper(propertiesStorageRepo, coroutineDispatcher)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ interface MemoPreferences {
fun getCrashReportEnabled(): Boolean

fun storageNotAvailable(): Boolean

fun isLastLaunchSuccess(): Boolean

fun setLastLaunchSuccess(success: Boolean)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import kotlin.io.path.exists

private const val NAME = "memo_prefs"
private const val CURRENT_NOTES_PATH = "current_notes_path"
private const val PREF_LAST_LAUNCH_SUCCESS = "pref_last_launch_success"

class MemoPreferencesImpl
@Inject
Expand Down Expand Up @@ -38,4 +39,12 @@ class MemoPreferencesImpl
override fun storageNotAvailable(): Boolean {
return getPath().isEmpty() || !getNotesStorage().exists()
}

override fun isLastLaunchSuccess(): Boolean {
return sharedPreferences.getBoolean(PREF_LAST_LAUNCH_SUCCESS, true)
}

override fun setLastLaunchSuccess(success: Boolean) {
prefEditor.putBoolean(PREF_LAST_LAUNCH_SUCCESS, success).apply()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import dev.arkbuilders.arklib.user.properties.PropertiesStorage
import dev.arkbuilders.arklib.user.properties.PropertiesStorageRepo
import dev.arkbuilders.arkmemo.di.IO_DISPATCHER
import dev.arkbuilders.arkmemo.models.Note
import dev.arkbuilders.arkmemo.preferences.MemoPreferences
import dev.arkbuilders.arkmemo.utils.isEqual
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
Expand All @@ -30,7 +29,6 @@ import kotlin.io.path.name
class NotesRepoHelper
@Inject
constructor(
private val memoPreferences: MemoPreferences,
private val propertiesStorageRepo: PropertiesStorageRepo,
@Named(IO_DISPATCHER) private val iODispatcher: CoroutineDispatcher,
) {
Expand All @@ -40,7 +38,6 @@ class NotesRepoHelper
private val lazyPropertiesStorage by lazy {
CoroutineScope(iODispatcher).async {
val propertyStorage = propertiesStorageRepo.provide(RootIndex.provide(root))
memoPreferences.storePath(root.toString())
propertyStorage
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,42 +67,39 @@ class MainActivity : AppCompatActivity(R.layout.activity_main) {
onBackPressedDispatcher.onBackPressed()
}

supportFragmentManager.onArkPathPicked(this) {
memoPreferences.storePath(it.toString())
showFragment(savedInstanceState)
}

val storageFolderExisting = memoPreferences.getNotesStorage().exists()
if (memoPreferences.storageNotAvailable()) {
if (!storageFolderExisting) {
showNoNoteStorageDialog(RootNotFound(rootPath = memoPreferences.getPath()))
} else {
FilePickerDialog.show(this, supportFragmentManager)
}

supportFragmentManager.onArkPathPicked(this) {
showFragment(savedInstanceState, it.toString())
}
} else {
showFragment(savedInstanceState, memoPreferences.getPath())
if (memoPreferences.isLastLaunchSuccess()) {
showFragment(savedInstanceState)
} else {
showRetrySelectRootDialog(
rootPath = memoPreferences.getPath(),
savedInstanceState = savedInstanceState,
)
}
}
}

private fun showFragment(
savedInstanceState: Bundle?,
storagePath: String,
) {
private fun showFragment(savedInstanceState: Bundle?) {
val textDataFromIntent = intent?.getStringExtra(Intent.EXTRA_TEXT)
if (textDataFromIntent != null) {
fragment = EditTextNotesFragment.newInstance(textDataFromIntent)
fragment.arguments =
Bundle().apply {
putString(BUNDLE_KEY_STORAGE_PATH, storagePath)
}
supportFragmentManager.beginTransaction().apply {
replace(fragContainer, fragment, EditTextNotesFragment.TAG)
commit()
}
} else {
fragment.arguments =
Bundle().apply {
putString(BUNDLE_KEY_STORAGE_PATH, storagePath)
}
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction().apply {
add(fragContainer, fragment, NotesFragment.TAG)
Expand Down Expand Up @@ -143,6 +140,35 @@ class MainActivity : AppCompatActivity(R.layout.activity_main) {
loadFailDialog.show(supportFragmentManager, CommonActionDialog.TAG)
}

private fun showRetrySelectRootDialog(
rootPath: String,
savedInstanceState: Bundle?,
) {
val loadFailDialog =
CommonActionDialog(
title = getString(R.string.error_load_notes_failed_title),
message = getString(R.string.error_load_notes_crash_description, rootPath),
positiveText = R.string.error_load_notes_failed_retry_action,
negativeText = R.string.error_load_notes_failed_negative_action,
neutralText = R.string.error_load_notes_failed_positive_action,
isAlert = false,
enableNeutralOption = true,
onPositiveClick = {
showFragment(savedInstanceState)
},
onNegativeClicked = {
finish()
},
onNeutralClicked = {
FilePickerDialog.show(this, supportFragmentManager)
},
onCloseClicked = {
finish()
},
)
loadFailDialog.show(supportFragmentManager, CommonActionDialog.TAG)
}

override fun onSaveInstanceState(outState: Bundle) {
outState.putString(CURRENT_FRAGMENT_TAG, fragment.tag)
super.onSaveInstanceState(outState)
Expand Down Expand Up @@ -176,7 +202,6 @@ class MainActivity : AppCompatActivity(R.layout.activity_main) {

companion object {
private const val CURRENT_FRAGMENT_TAG = "current fragment tag"
const val BUNDLE_KEY_STORAGE_PATH = "bundle_key_storage_path"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.annotation.StringRes
import androidx.fragment.app.DialogFragment
import dev.arkbuilders.arkmemo.R
import dev.arkbuilders.arkmemo.databinding.DialogCommonActionBinding
import dev.arkbuilders.arkmemo.utils.visible

/**
* This is a common action dialog that can be used inside app.
Expand All @@ -18,9 +19,12 @@ class CommonActionDialog(
private val message: String,
@StringRes private val positiveText: Int,
@StringRes private val negativeText: Int,
@StringRes private val neutralText: Int? = null,
private val isAlert: Boolean = false,
private val enableNeutralOption: Boolean = false,
private val onPositiveClick: (() -> Unit)? = null,
private val onNegativeClicked: (() -> Unit)? = null,
private val onNeutralClicked: (() -> Unit)? = null,
private val onCloseClicked: (() -> Unit)? = null,
) : DialogFragment() {
companion object {
Expand Down Expand Up @@ -48,10 +52,15 @@ class CommonActionDialog(
mBinding.tvPositive.setBackgroundResource(R.drawable.bg_red_button)
}

if (enableNeutralOption) {
mBinding.tvNeutral.visible()
}

mBinding.tvTitle.text = title
mBinding.tvMessage.text = message
mBinding.tvPositive.setText(positiveText)
mBinding.tvNegative.setText(negativeText)
neutralText?.let { mBinding.tvNeutral.setText(neutralText) }
mBinding.ivClose.setOnClickListener {
onCloseClicked?.invoke()
dismiss()
Expand All @@ -66,6 +75,11 @@ class CommonActionDialog(
onNegativeClicked?.invoke()
dismiss()
}

mBinding.tvNeutral.setOnClickListener {
onNeutralClicked?.invoke()
dismiss()
}
}

override fun onResume() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import dagger.hilt.android.AndroidEntryPoint
import dev.arkbuilders.arkmemo.R
import dev.arkbuilders.arkmemo.models.Note
import dev.arkbuilders.arkmemo.models.TextNote
import dev.arkbuilders.arkmemo.ui.activities.MainActivity.Companion.BUNDLE_KEY_STORAGE_PATH
import dev.arkbuilders.arkmemo.utils.getParcelableCompat
import dev.arkbuilders.arkmemo.utils.getTextFromClipBoard
import dev.arkbuilders.arkmemo.utils.gone
Expand Down Expand Up @@ -76,9 +75,7 @@ class EditTextNotesFragment : BaseEditNoteFragment() {
note = it
}
noteStr = requireArguments().getString(NOTE_STRING_KEY)
arguments?.getString(BUNDLE_KEY_STORAGE_PATH)?.let {
notesViewModel.init(it) {}
}
notesViewModel.init {}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,12 @@ class NotesFragment : BaseFragment() {
initEmptyStateViews()

binding.pbLoading.visible()
val root = arguments?.getString(MainActivity.BUNDLE_KEY_STORAGE_PATH) ?: ""
notesViewModel.apply {
storePath("")
init(root) {
setLastLaunchSuccess(false)
init {
readAllNotes {
onNotesLoaded(it)
storePath(root)
setLastLaunchSuccess(true)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,8 @@ class NotesViewModel
@set:Inject
internal lateinit var memoPreferences: MemoPreferences

fun init(
root: String,
extraBlock: () -> Unit,
) {
fun init(extraBlock: () -> Unit) {
val root = memoPreferences.getPath()
val initJob =
viewModelScope.launch(iODispatcher) {
textNotesRepo.init(root)
Expand Down Expand Up @@ -195,7 +193,7 @@ class NotesViewModel
return memoPreferences.getPath()
}

fun storePath(path: String) {
memoPreferences.storePath(path)
fun setLastLaunchSuccess(success: Boolean) {
memoPreferences.setLastLaunchSuccess(success)
}
}
17 changes: 16 additions & 1 deletion app/src/main/res/layout/dialog_common_action.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,21 @@
android:layout_marginTop="24dp"
android:id="@+id/tv_positive"/>

<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
style="@style/PositiveButton"
android:text="@string/error_load_notes_failed_retry_action"
android:clickable="true"
android:foreground="?attr/selectableItemBackground"
app:layout_constraintStart_toStartOf="@+id/tv_title"
app:layout_constraintEnd_toEndOf="@+id/iv_close"
app:layout_constraintTop_toBottomOf="@+id/tv_positive"
android:layout_marginTop="@dimen/common_padding"
android:id="@+id/tv_neutral"
android:visibility="gone"
android:layout_marginBottom="@dimen/common_padding" />

<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
Expand All @@ -64,7 +79,7 @@
android:foreground="?attr/selectableItemBackground"
app:layout_constraintStart_toStartOf="@+id/tv_title"
app:layout_constraintEnd_toEndOf="@+id/iv_close"
app:layout_constraintTop_toBottomOf="@+id/tv_positive"
app:layout_constraintTop_toBottomOf="@+id/tv_neutral"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginTop="@dimen/common_padding"
android:id="@+id/tv_negative"
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,5 +121,7 @@
<string name="error_load_notes_failed_description">The folder %s with notes data cannot be located.\nPlease select a new folder.</string>
<string name="error_load_notes_failed_positive_action">Select</string>
<string name="error_load_notes_failed_negative_action">Leave</string>
<string name="error_load_notes_failed_retry_action">Retry</string>
<string name="error_load_notes_crash_description">There\'s a crash while loading the folder %s.\nPlease retry or select a new folder.</string>

</resources>

0 comments on commit e09da72

Please sign in to comment.