Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle error when the folder is removed externally #83

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/src/main/java/dev/arkbuilders/arkmemo/models/LoadError.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package dev.arkbuilders.arkmemo.models

sealed interface LoadError

data class RootNotFound(val rootPath: String) : LoadError
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ interface MemoPreferences {
fun storeCrashReportEnabled(enabled: Boolean)

fun getCrashReportEnabled(): Boolean

fun storageNotAvailable(): Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import dev.arkbuilders.arkmemo.utils.CRASH_REPORT_ENABLE
import java.nio.file.Path
import javax.inject.Inject
import kotlin.io.path.Path
import kotlin.io.path.exists

private const val NAME = "memo_prefs"
private const val CURRENT_NOTES_PATH = "current_notes_path"
Expand All @@ -33,4 +34,8 @@ class MemoPreferencesImpl
}

override fun getCrashReportEnabled(): Boolean = sharedPreferences.getBoolean(CRASH_REPORT_ENABLE, true)

override fun storageNotAvailable(): Boolean {
return getPath().isEmpty() || !getNotesStorage().exists()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ import dagger.hilt.android.AndroidEntryPoint
import dev.arkbuilders.arkmemo.R
import dev.arkbuilders.arkmemo.contracts.PermissionContract
import dev.arkbuilders.arkmemo.databinding.ActivityMainBinding
import dev.arkbuilders.arkmemo.models.RootNotFound
import dev.arkbuilders.arkmemo.preferences.MemoPreferences
import dev.arkbuilders.arkmemo.ui.dialogs.CommonActionDialog
import dev.arkbuilders.arkmemo.ui.dialogs.FilePickerDialog
import dev.arkbuilders.arkmemo.ui.fragments.BaseFragment
import dev.arkbuilders.arkmemo.ui.fragments.EditTextNotesFragment
import dev.arkbuilders.arkmemo.ui.fragments.NotesFragment
import dev.arkbuilders.components.filepicker.onArkPathPicked
import javax.inject.Inject
import kotlin.io.path.exists

@AndroidEntryPoint
class MainActivity : AppCompatActivity(R.layout.activity_main) {
Expand Down Expand Up @@ -92,8 +95,13 @@ class MainActivity : AppCompatActivity(R.layout.activity_main) {
}
}

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

supportFragmentManager.onArkPathPicked(this) {
memoPreferences.storePath(it.toString())
Expand All @@ -104,6 +112,27 @@ class MainActivity : AppCompatActivity(R.layout.activity_main) {
}
}

private fun showNoNoteStorageDialog(error: RootNotFound) {
val loadFailDialog =
CommonActionDialog(
title = getString(R.string.error_load_notes_failed_title),
message = getString(R.string.error_load_notes_failed_description, error.rootPath),
positiveText = R.string.error_load_notes_failed_positive_action,
negativeText = R.string.error_load_notes_failed_negative_action,
isAlert = false,
onPositiveClick = {
FilePickerDialog.show(this, supportFragmentManager)
},
onNegativeClicked = {
finish()
},
onCloseClicked = {
finish()
},
)
loadFailDialog.show(supportFragmentManager, CommonActionDialog.TAG)
}

override fun onSaveInstanceState(outState: Bundle) {
outState.putString(CURRENT_FRAGMENT_TAG, fragment.tag)
super.onSaveInstanceState(outState)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import dev.arkbuilders.arkmemo.ui.activities.MainActivity
import dev.arkbuilders.arkmemo.ui.fragments.ArkRecorderFragment
import dev.arkbuilders.arkmemo.ui.fragments.EditGraphicNotesFragment
import dev.arkbuilders.arkmemo.ui.fragments.EditTextNotesFragment
import dev.arkbuilders.arkmemo.ui.fragments.NotesFragment
import dev.arkbuilders.arkmemo.ui.viewmodels.ArkMediaPlayerSideEffect
import dev.arkbuilders.arkmemo.ui.viewmodels.ArkMediaPlayerState
import dev.arkbuilders.arkmemo.utils.getAutoTitle
Expand Down Expand Up @@ -295,6 +296,11 @@ class NotesListAdapter(

private val clickNoteToEditListener =
View.OnClickListener {
val storageFolderExist = (activity.fragment as? NotesFragment)?.checkForStorageExistence() ?: true
if (!storageFolderExist) {
return@OnClickListener
}

if (mActionMode) {
checkedByItemClick = true
binding.cbDelete.toggle()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,18 @@ class FilePickerDialog : ArkFilePickerFragment() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (storageNotAvailable()) {
if (memoPreferences.storageNotAvailable()) {
isCancelable = false
}
}

override fun dismiss() {
super.dismiss()
if (storageNotAvailable()) {
if (memoPreferences.storageNotAvailable()) {
activity?.finish()
}
}

private fun storageNotAvailable(): Boolean = memoPreferences.getPath().isEmpty()

companion object {
private const val TAG = "file_picker"
private lateinit var fragmentManager: FragmentManager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ import dagger.hilt.android.AndroidEntryPoint
import dev.arkbuilders.arkmemo.R
import dev.arkbuilders.arkmemo.databinding.FragmentHomeBinding
import dev.arkbuilders.arkmemo.models.Note
import dev.arkbuilders.arkmemo.models.RootNotFound
import dev.arkbuilders.arkmemo.models.VoiceNote
import dev.arkbuilders.arkmemo.ui.activities.MainActivity
import dev.arkbuilders.arkmemo.ui.adapters.NotesListAdapter
import dev.arkbuilders.arkmemo.ui.dialogs.CommonActionDialog
import dev.arkbuilders.arkmemo.ui.dialogs.FilePickerDialog
import dev.arkbuilders.arkmemo.ui.viewmodels.ArkMediaPlayerSideEffect
import dev.arkbuilders.arkmemo.ui.viewmodels.ArkMediaPlayerViewModel
import dev.arkbuilders.arkmemo.ui.viewmodels.NotesViewModel
Expand Down Expand Up @@ -62,6 +64,10 @@ class NotesFragment : BaseFragment() {

private val pasteNoteClickListener =
View.OnClickListener {
if (!checkForStorageExistence()) {
return@OnClickListener
}

requireContext().getTextFromClipBoard(view) { clipBoardText ->
if (clipBoardText != null) {
activity.fragment = EditTextNotesFragment.newInstance(clipBoardText)
Expand Down Expand Up @@ -151,6 +157,9 @@ class NotesFragment : BaseFragment() {
activity.title = getString(R.string.app_name)
activity.supportActionBar?.setDisplayHomeAsUpEnabled(false)
binding.ivSettings.setOnClickListener {
if (!checkForStorageExistence()) {
return@setOnClickListener
}
activity.fragment = SettingsFragment()
activity.replaceFragment(activity.fragment, SettingsFragment::class.java.name)
}
Expand Down Expand Up @@ -419,6 +428,10 @@ class NotesFragment : BaseFragment() {
binding.groupFabActions.gone()
showingFloatingButtons = false
} else {
if (!checkForStorageExistence()) {
return
}

binding.fabNewAction.extend()
binding.fabNewAction.icon = ContextCompat.getDrawable(activity, R.drawable.ic_close)
binding.fabNewAction.backgroundTintList =
Expand Down Expand Up @@ -539,6 +552,35 @@ class NotesFragment : BaseFragment() {
}
}

private fun showNoNoteStorageDialog(error: RootNotFound) {
val loadFailDialog =
CommonActionDialog(
title = getString(R.string.error_load_notes_failed_title),
message = getString(R.string.error_load_notes_failed_description, error.rootPath),
positiveText = R.string.error_load_notes_failed_positive_action,
negativeText = R.string.error_load_notes_failed_negative_action,
isAlert = false,
onPositiveClick = {
FilePickerDialog.show(activity, fragmentManager = parentFragmentManager)
},
onNegativeClicked = {
activity.finish()
},
onCloseClicked = {
activity.finish()
},
)
loadFailDialog.show(parentFragmentManager, CommonActionDialog.TAG)
}

fun checkForStorageExistence(): Boolean {
if (notesViewModel.storageFolderNotAvailable()) {
showNoNoteStorageDialog(RootNotFound(rootPath = notesViewModel.getStorageFolderPath()))
return false
}
return true
}

companion object {
const val TAG = "NotesFragment"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import dev.arkbuilders.arkmemo.models.Note
import dev.arkbuilders.arkmemo.models.SaveNoteResult
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.utils.extractDuration
import kotlinx.coroutines.CoroutineDispatcher
Expand Down Expand Up @@ -39,6 +40,9 @@ class NotesViewModel
private val mSaveNoteResultLiveData = MutableLiveData<SaveNoteResult>()
private var searchJob: Job? = null

@Inject
lateinit var memoPreferences: MemoPreferences

fun init(extraBlock: () -> Unit) {
val initJob =
viewModelScope.launch(iODispatcher) {
Expand Down Expand Up @@ -179,4 +183,12 @@ class NotesViewModel
fun getSaveNoteResultLiveData(): LiveData<SaveNoteResult> {
return mSaveNoteResultLiveData
}

fun storageFolderNotAvailable(): Boolean {
return memoPreferences.storageNotAvailable()
}

fun getStorageFolderPath(): String {
return memoPreferences.getPath()
}
}
4 changes: 4 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -117,5 +117,9 @@
</plurals>
<string name="select_all">Select All</string>
<string name="deselect_all">Deselect All</string>
<string name="error_load_notes_failed_title">Cannot find notes</string>
<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>

</resources>