Skip to content

Commit

Permalink
NF: improve SyncErrorDialog
Browse files Browse the repository at this point in the history
Use an enum and constants

Co-authored-by: David Allison <62114487+david-allison@users.noreply.github.com>
  • Loading branch information
Arthur-Milchior and david-allison committed Dec 28, 2024
1 parent 2914cc0 commit afe220c
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 138 deletions.
6 changes: 3 additions & 3 deletions AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1808,7 +1808,7 @@ open class DeckPicker :
* Show a specific sync error dialog
* @param dialogType id of dialog to show
*/
override fun showSyncErrorDialog(dialogType: Int) {
override fun showSyncErrorDialog(dialogType: SyncErrorDialog.Type) {
showSyncErrorDialog(dialogType, "")
}

Expand All @@ -1818,7 +1818,7 @@ open class DeckPicker :
* @param message text to show
*/
override fun showSyncErrorDialog(
dialogType: Int,
dialogType: SyncErrorDialog.Type,
message: String?,
) {
val newFragment: AsyncDialogFragment = newInstance(dialogType, message)
Expand Down Expand Up @@ -1943,7 +1943,7 @@ open class DeckPicker :
if (hkey!!.isEmpty()) {
Timber.w("User not logged in")
pullToSyncWrapper.isRefreshing = false
showSyncErrorDialog(SyncErrorDialog.DIALOG_USER_NOT_LOGGED_IN_SYNC)
showSyncErrorDialog(SyncErrorDialog.Type.DIALOG_USER_NOT_LOGGED_IN_SYNC)
return
}

Expand Down
2 changes: 1 addition & 1 deletion AnkiDroid/src/main/java/com/ichi2/anki/Sync.kt
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ private suspend fun handleNormalSync(

SyncCollectionResponse.ChangesRequired.FULL_SYNC -> {
deckPicker.mediaUsnOnConflict = mediaUsn
deckPicker.showSyncErrorDialog(SyncErrorDialog.DIALOG_SYNC_CONFLICT_RESOLUTION)
deckPicker.showSyncErrorDialog(SyncErrorDialog.Type.DIALOG_SYNC_CONFLICT_RESOLUTION)
}

SyncCollectionResponse.ChangesRequired.NORMAL_SYNC,
Expand Down
57 changes: 32 additions & 25 deletions AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ImportDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,42 +19,37 @@ package com.ichi2.anki.dialogs
import android.os.Bundle
import androidx.annotation.CheckResult
import androidx.appcompat.app.AlertDialog
import androidx.core.os.bundleOf
import com.ichi2.anki.R
import com.ichi2.anki.dialogs.ImportDialog.Type.DIALOG_IMPORT_ADD_CONFIRM
import com.ichi2.anki.dialogs.ImportDialog.Type.DIALOG_IMPORT_REPLACE_CONFIRM
import com.ichi2.anki.utils.ext.dismissAllDialogFragments
import com.ichi2.utils.negativeButton
import com.ichi2.utils.positiveButton
import timber.log.Timber
import java.net.URLDecoder

class ImportDialog : AsyncDialogFragment() {
enum class Type(
val code: Int,
) {
DIALOG_IMPORT_ADD_CONFIRM(0),
DIALOG_IMPORT_REPLACE_CONFIRM(1),
;

companion object {
fun fromCode(code: Int) = Type.entries.first { code == it.code }
}
}

interface ImportDialogListener {
fun importAdd(importPath: String)

fun importReplace(importPath: String)
}

private val dialogType: Type
get() = Type.fromCode(requireArguments().getInt(IMPORT_DIALOG_TYPE_KEY))

private val packagePath: String
get() = requireArguments().getString(IMPORT_DIALOG_PACKAGE_PATH_KEY)!!

override fun onCreateDialog(savedInstanceState: Bundle?): AlertDialog {
super.onCreate(savedInstanceState)
val type = Type.fromCode(requireArguments().getInt(IMPORT_DIALOG_TYPE_KEY))
val dialog = AlertDialog.Builder(requireActivity())
dialog.setCancelable(true)
val packagePath = requireArguments().getString(IMPORT_DIALOG_PACKAGE_PATH_KEY)!!
val displayFileName = filenameFromPath(convertToDisplayName(packagePath))

return when (type) {
Type.DIALOG_IMPORT_ADD_CONFIRM -> {
return when (dialogType) {
DIALOG_IMPORT_ADD_CONFIRM -> {
dialog
.setTitle(R.string.import_title)
.setMessage(res().getString(R.string.import_dialog_message_add, displayFileName))
Expand All @@ -64,7 +59,7 @@ class ImportDialog : AsyncDialogFragment() {
}.negativeButton(R.string.dialog_cancel)
.create()
}
Type.DIALOG_IMPORT_REPLACE_CONFIRM -> {
DIALOG_IMPORT_REPLACE_CONFIRM -> {
dialog
.setTitle(R.string.import_title)
.setMessage(res().getString(R.string.import_message_replace_confirm, displayFileName))
Expand Down Expand Up @@ -98,6 +93,18 @@ class ImportDialog : AsyncDialogFragment() {
return res().getString(R.string.import_title)
}

enum class Type(
val code: Int,
) {
DIALOG_IMPORT_ADD_CONFIRM(0),
DIALOG_IMPORT_REPLACE_CONFIRM(1),
;

companion object {
fun fromCode(code: Int) = Type.entries.first { code == it.code }
}
}

companion object {
const val IMPORT_DIALOG_TYPE_KEY = "dialogType"
const val IMPORT_DIALOG_PACKAGE_PATH_KEY = "packagePath"
Expand All @@ -112,14 +119,14 @@ class ImportDialog : AsyncDialogFragment() {
fun newInstance(
dialogType: Type,
packagePath: String,
): ImportDialog {
val f = ImportDialog()
val args = Bundle()
args.putInt(IMPORT_DIALOG_TYPE_KEY, dialogType.code)
args.putString(IMPORT_DIALOG_PACKAGE_PATH_KEY, packagePath)
f.arguments = args
return f
}
): ImportDialog =
ImportDialog().apply {
arguments =
bundleOf(
IMPORT_DIALOG_TYPE_KEY to dialogType.code,
IMPORT_DIALOG_PACKAGE_PATH_KEY to packagePath,
)
}

private fun filenameFromPath(path: String): String = path.split("/").toTypedArray()[path.split("/").toTypedArray().size - 1]
}
Expand Down
105 changes: 50 additions & 55 deletions AnkiDroid/src/main/java/com/ichi2/anki/dialogs/MediaCheckDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,12 @@ import androidx.core.os.bundleOf
import com.ichi2.anki.AnkiActivity
import com.ichi2.anki.DeckPicker
import com.ichi2.anki.R
import com.ichi2.anki.dialogs.MediaCheckDialog.Type.DIALOG_CONFIRM_MEDIA_CHECK
import com.ichi2.anki.dialogs.MediaCheckDialog.Type.DIALOG_MEDIA_CHECK_RESULTS
import com.ichi2.anki.showError
import com.ichi2.anki.utils.ext.dismissAllDialogFragments
import com.ichi2.libanki.MediaCheckResult

/**
* Key for an array of strings of name of invalid media
*/
const val INVALID = "invalid"

class MediaCheckDialog : AsyncDialogFragment() {
interface MediaCheckDialogListener {
fun showMediaCheckDialog(dialogType: Type)
Expand All @@ -38,14 +35,26 @@ class MediaCheckDialog : AsyncDialogFragment() {
fun deleteUnused(unused: List<String>)
}

private val dialogType: Type
get() = Type.fromCode(requireArguments().getInt(MEDIA_CHECK_DIALOG_TYPE_KEY))

private val noHave: List<String>?
get() = requireArguments().getStringArrayList(NO_HAVE)

private val unused: List<String>?
get() = requireArguments().getStringArrayList(UNUSED)

private val invalid: List<String>?
get() = requireArguments().getStringArrayList(INVALID)

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
super.onCreate(savedInstanceState)
val dialog =
AlertDialog
.Builder(requireContext())
.setTitle(notificationTitle)
return when (typeFromArguments()) {
Type.DIALOG_CONFIRM_MEDIA_CHECK -> {
return when (dialogType) {
DIALOG_CONFIRM_MEDIA_CHECK -> {
dialog
.setMessage(notificationMessage)
.setPositiveButton(R.string.dialog_ok) { _, _ ->
Expand All @@ -55,22 +64,22 @@ class MediaCheckDialog : AsyncDialogFragment() {
activity?.dismissAllDialogFragments()
}.create()
}
Type.DIALOG_MEDIA_CHECK_RESULTS -> {
val noHave = requireArguments().getStringArrayList(NO_HAVE)
val unused = requireArguments().getStringArrayList(UNUSED)
val invalid = requireArguments().getStringArrayList(INVALID)
DIALOG_MEDIA_CHECK_RESULTS -> {
val noHave = noHave!!
val unused = unused!!
val invalid = invalid!!
// Generate report
val report = StringBuilder()
if (invalid!!.isNotEmpty()) {
if (invalid.isNotEmpty()) {
report.append(String.format(res().getString(R.string.check_media_invalid), invalid.size))
}
if (unused!!.isNotEmpty()) {
if (unused.isNotEmpty()) {
if (report.isNotEmpty()) {
report.append("\n")
}
report.append(String.format(res().getString(R.string.check_media_unused), unused.size))
}
if (noHave!!.isNotEmpty()) {
if (noHave.isNotEmpty()) {
if (report.isNotEmpty()) {
report.append("\n")
}
Expand Down Expand Up @@ -121,32 +130,20 @@ class MediaCheckDialog : AsyncDialogFragment() {

override val notificationMessage: String
get() =
when (typeFromArguments()) {
Type.DIALOG_CONFIRM_MEDIA_CHECK -> res().getString(R.string.check_media_warning)
Type.DIALOG_MEDIA_CHECK_RESULTS -> res().getString(R.string.check_media_acknowledge)
when (dialogType) {
DIALOG_CONFIRM_MEDIA_CHECK -> res().getString(R.string.check_media_warning)
DIALOG_MEDIA_CHECK_RESULTS -> res().getString(R.string.check_media_acknowledge)
}

override val notificationTitle: String
get() =
when (typeFromArguments()) {
Type.DIALOG_CONFIRM_MEDIA_CHECK -> {
res().getString(R.string.check_media_title)
}

Type.DIALOG_MEDIA_CHECK_RESULTS -> {
res().getString(R.string.app_name)
}
when (dialogType) {
DIALOG_CONFIRM_MEDIA_CHECK -> res().getString(R.string.check_media_title)
DIALOG_MEDIA_CHECK_RESULTS -> res().getString(R.string.app_name)
}

private fun typeFromArguments() = Type.fromCode(requireArguments().getInt(MEDIA_CHECK_DIALOG_TYPE_KEY))

override val dialogHandlerMessage: MediaCheckCompleteDialog
get() {
val dialogType = typeFromArguments()
val noHave = requireArguments().getStringArrayList(NO_HAVE)
val unused = requireArguments().getStringArrayList(UNUSED)
val invalid = requireArguments().getStringArrayList(INVALID)

return MediaCheckCompleteDialog(dialogType, noHave, unused, invalid)
}

Expand Down Expand Up @@ -178,43 +175,41 @@ class MediaCheckDialog : AsyncDialogFragment() {
*/
const val UNUSED = "unused"

/**
* Key for an array of strings of name of invalid media
*/
const val INVALID = "invalid"

@CheckResult
fun newInstance(dialogType: Type): MediaCheckDialog {
val f = MediaCheckDialog()
val args = Bundle()
args.putInt(MEDIA_CHECK_DIALOG_TYPE_KEY, dialogType.code)
f.arguments = args
return f
}
fun newInstance(dialogType: Type) =
MediaCheckDialog().apply { arguments = bundleOf(MEDIA_CHECK_DIALOG_TYPE_KEY to dialogType.code) }

// TODO Instead of putting string arrays into the bundle,
// make MediaCheckResult parcelable with @Parcelize and put it instead.
// TODO Extract keys to constants
// make MediaCheckResult parcelable with @Parcelize and put it instead
fun newInstance(
dialogType: Type,
checkList: MediaCheckResult,
): MediaCheckDialog {
val f = MediaCheckDialog()
val args = Bundle()
args.putStringArrayList(NO_HAVE, ArrayList(checkList.missingFileNames))
args.putStringArrayList(UNUSED, ArrayList(checkList.unusedFileNames))
args.putStringArrayList(INVALID, ArrayList(checkList.invalidFileNames))
args.putInt(MEDIA_CHECK_DIALOG_TYPE_KEY, dialogType.code)
f.arguments = args
return f
) = MediaCheckDialog().apply {
arguments =
bundleOf(
NO_HAVE to ArrayList(checkList.missingFileNames),
UNUSED to ArrayList(checkList.unusedFileNames),
INVALID to ArrayList(checkList.invalidFileNames),
MEDIA_CHECK_DIALOG_TYPE_KEY to dialogType.code,
)
}
}

class MediaCheckCompleteDialog(
private val dialogType: Type,
private val noHave: ArrayList<String>?,
private val unused: ArrayList<String>?,
private val invalid: ArrayList<String>?,
private val noHave: List<String>?,
private val unused: List<String>?,
private val invalid: List<String>?,
) : DialogHandlerMessage(WhichDialogHandler.MSG_SHOW_MEDIA_CHECK_COMPLETE_DIALOG, "MediaCheckCompleteDialog") {
override fun handleAsyncMessage(activity: AnkiActivity) {
// Media check results
when (dialogType) {
Type.DIALOG_MEDIA_CHECK_RESULTS -> {
DIALOG_MEDIA_CHECK_RESULTS -> {
// we may be called via any AnkiActivity but media check is a DeckPicker thing
if (activity !is DeckPicker) {
showError(
Expand All @@ -228,7 +223,7 @@ class MediaCheckDialog : AsyncDialogFragment() {
val checkList = MediaCheckResult(noHave ?: arrayListOf(), unused ?: arrayListOf(), invalid ?: arrayListOf())
activity.showMediaCheckDialog(dialogType, checkList)
}
Type.DIALOG_CONFIRM_MEDIA_CHECK -> { }
DIALOG_CONFIRM_MEDIA_CHECK -> { }
}
}

Expand Down
Loading

0 comments on commit afe220c

Please sign in to comment.