Skip to content

Commit

Permalink
NF: improve SyncErrorDialog
Browse files Browse the repository at this point in the history
Use an enum and constants
  • Loading branch information
Arthur-Milchior committed Dec 28, 2024
1 parent 6c2e4ab commit 5d41c2a
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 192 deletions.
9 changes: 3 additions & 6 deletions AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1804,7 +1804,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 @@ -1813,10 +1813,7 @@ open class DeckPicker :
* @param dialogType id of dialog to show
* @param message text to show
*/
override fun showSyncErrorDialog(
dialogType: Int,
message: String?,
) {
override fun showSyncErrorDialog(dialogType: SyncErrorDialog.Type, message: String?) {
val newFragment: AsyncDialogFragment = newInstance(dialogType, message)
showAsyncDialogFragment(newFragment, Channel.SYNC)
}
Expand Down Expand Up @@ -1939,7 +1936,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
60 changes: 28 additions & 32 deletions AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ImportDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,54 +19,47 @@ 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 -> {
dialog
.setTitle(R.string.import_title)
return when (dialogType) {
DIALOG_IMPORT_ADD_CONFIRM -> {
dialog.setTitle(R.string.import_title)
.setMessage(res().getString(R.string.import_dialog_message_add, displayFileName))
.positiveButton(R.string.import_message_add) {
(activity as ImportDialogListener).importAdd(packagePath)
activity?.dismissAllDialogFragments()
}.negativeButton(R.string.dialog_cancel)
.create()
}
Type.DIALOG_IMPORT_REPLACE_CONFIRM -> {
dialog
.setTitle(R.string.import_title)
DIALOG_IMPORT_REPLACE_CONFIRM -> {
dialog.setTitle(R.string.import_title)
.setMessage(res().getString(R.string.import_message_replace_confirm, displayFileName))
.positiveButton(R.string.dialog_positive_replace) {
(activity as ImportDialogListener).importReplace(packagePath)
Expand Down Expand Up @@ -98,6 +91,13 @@ 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 @@ -109,17 +109,13 @@ class ImportDialog : AsyncDialogFragment() {
* @param packagePath the path of the package to import
*/
@CheckResult
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
}
fun newInstance(dialogType: Type, packagePath: String): 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
102 changes: 48 additions & 54 deletions AnkiDroid/src/main/java/com/ichi2/anki/dialogs/MediaCheckDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +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 @@ -32,12 +30,24 @@ 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) { _, _ ->
(activity as MediaCheckDialogListener?)?.mediaCheck()
Expand All @@ -46,22 +56,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 @@ -111,31 +121,19 @@ 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)
get() = 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)
}
get() = 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 @@ -165,40 +163,36 @@ 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
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
// make MediaCheckResult parcelable with @Parcelize and put it instead
fun newInstance(dialogType: Type, checkList: MediaCheckResult) = 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 @@ -212,7 +206,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 5d41c2a

Please sign in to comment.