Skip to content

Commit 478ae51

Browse files
committed
refactor: define 'TR.sentenceCase' properties
Simplified accessors for SentenceCase strings: `TR.sentenceCase.checkDatabase` This avoids bugs caused by passing in the wrong resId to `toSentenceCase`
1 parent f652a4e commit 478ae51

6 files changed

Lines changed: 55 additions & 15 deletions

File tree

AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ import com.ichi2.anki.sync.launchCatchingRequiringOneWaySyncDiscardUndo
164164
import com.ichi2.anki.ui.ResizablePaneManager
165165
import com.ichi2.anki.ui.animations.fadeIn
166166
import com.ichi2.anki.ui.animations.fadeOut
167-
import com.ichi2.anki.ui.internationalization.toSentenceCase
167+
import com.ichi2.anki.ui.internationalization.sentenceCase
168168
import com.ichi2.anki.ui.windows.permissions.PermissionsActivity
169169
import com.ichi2.anki.utils.Destination
170170
import com.ichi2.anki.utils.ShortcutUtils
@@ -1144,8 +1144,8 @@ open class DeckPicker :
11441144
toolbarSearchView?.maxWidth = Integer.MAX_VALUE
11451145

11461146
menu.findItem(R.id.action_export_collection)?.title = TR.actionsExport()
1147-
menu.findItem(R.id.action_check_database)?.title = TR.databaseCheckTitle().toSentenceCase(R.string.sentence_check_db)
1148-
menu.findItem(R.id.action_check_media)?.title = TR.mediaCheckCheckMediaAction().toSentenceCase(R.string.sentence_check_media)
1147+
menu.findItem(R.id.action_check_database)?.title = TR.sentenceCase.checkDatabase
1148+
menu.findItem(R.id.action_check_media)?.title = TR.sentenceCase.checkMediaAction
11491149
setupMediaSyncMenuItem(menu)
11501150
// redraw menu synchronously to avoid flicker
11511151
updateMenuFromState(menu)
@@ -1416,7 +1416,7 @@ open class DeckPicker :
14161416
private fun showMediaCheckDialog() {
14171417
Timber.i("showing media check dialog")
14181418
AlertDialog.Builder(this).show {
1419-
title(text = TR.mediaCheckWindowTitle().toSentenceCase(R.string.sentence_check_media))
1419+
title(text = TR.sentenceCase.checkMediaTitle)
14201420
message(text = getString(R.string.check_media_warning))
14211421
positiveButton(R.string.dialog_ok) {
14221422
Timber.i("Starting media check")
@@ -1897,7 +1897,7 @@ open class DeckPicker :
18971897
if (status.shouldWarnOnIntegrityCheck()) {
18981898
Timber.d("Displaying File Size confirmation")
18991899
AlertDialog.Builder(this).show {
1900-
title(text = TR.databaseCheckTitle().toSentenceCase(R.string.sentence_check_db))
1900+
title(text = TR.sentenceCase.checkDatabase)
19011901
message(text = status.getWarningDetails(this@DeckPicker))
19021902
positiveButton(R.string.integrity_check_continue_anyway) {
19031903
performIntegrityCheck()
@@ -2270,14 +2270,14 @@ open class DeckPicker :
22702270
shortcut("/", R.string.deck_conf_cram_search),
22712271
shortcut("S", Translations::decksStudyDeck),
22722272
shortcut("T", R.string.open_statistics),
2273-
shortcut("C", { databaseCheckTitle().toSentenceCase(R.string.sentence_check_db) }),
2273+
shortcut("C") { this.sentenceCase.checkDatabase },
22742274
shortcut("D", R.string.new_deck),
22752275
shortcut("F", R.string.new_dynamic_deck),
22762276
if (fragmented) shortcut("DEL", R.string.contextmenu_deckpicker_delete_deck) else null,
22772277
if (fragmented) shortcut("Shift+DEL", R.string.delete_deck_without_confirmation) else null,
22782278
if (fragmented) shortcut("R", R.string.rename_deck) else null,
22792279
shortcut("P", R.string.open_settings),
2280-
shortcut("M", { mediaCheckCheckMediaAction().toSentenceCase(R.string.sentence_check_media) }),
2280+
shortcut("M") { this.sentenceCase.checkMediaAction },
22812281
shortcut("Ctrl+E", R.string.export_collection),
22822282
shortcut("Ctrl+Shift+I", R.string.menu_import),
22832283
shortcut("Ctrl+Shift+N", R.string.model_browser_label),

AnkiDroid/src/main/java/com/ichi2/anki/dialogs/DatabaseErrorDialog.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ import com.ichi2.anki.libanki.Consts
6565
import com.ichi2.anki.requireAnkiActivity
6666
import com.ichi2.anki.servicelayer.DebugInfoService
6767
import com.ichi2.anki.showImportDialog
68+
import com.ichi2.anki.ui.internationalization.sentenceCase
6869
import com.ichi2.anki.ui.internationalization.toSentenceCase
6970
import com.ichi2.anki.utils.ext.dismissAllDialogFragments
7071
import com.ichi2.utils.UiUtil.makeBold
@@ -300,7 +301,7 @@ class DatabaseErrorDialog : AsyncDialogFragment() {
300301
DIALOG_CONFIRM_DATABASE_CHECK -> {
301302
// Confirmation dialog for database check
302303
alertDialog.show {
303-
title(text = TR.databaseCheckTitle().toSentenceCase(R.string.sentence_check_db))
304+
title(text = TR.sentenceCase.checkDatabase)
304305
message(text = message)
305306
positiveButton(R.string.dialog_ok) {
306307
requireDeckPicker().integrityCheck()

AnkiDroid/src/main/java/com/ichi2/anki/dialogs/SyncErrorDialog.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import com.ichi2.anki.dialogs.SyncErrorDialog.Type.DIALOG_SYNC_SANITY_ERROR
3737
import com.ichi2.anki.dialogs.SyncErrorDialog.Type.DIALOG_SYNC_SANITY_ERROR_CONFIRM_KEEP_LOCAL
3838
import com.ichi2.anki.dialogs.SyncErrorDialog.Type.DIALOG_SYNC_SANITY_ERROR_CONFIRM_KEEP_REMOTE
3939
import com.ichi2.anki.dialogs.SyncErrorDialog.Type.DIALOG_USER_NOT_LOGGED_IN_SYNC
40-
import com.ichi2.anki.ui.internationalization.toSentenceCase
40+
import com.ichi2.anki.ui.internationalization.sentenceCase
4141
import com.ichi2.anki.utils.ext.dismissAllDialogFragments
4242
import com.ichi2.anki.utils.openUrl
4343
import com.ichi2.utils.titleWithHelpIcon
@@ -155,7 +155,7 @@ class SyncErrorDialog : AsyncDialogFragment() {
155155
}
156156
DIALOG_MEDIA_SYNC_ERROR -> {
157157
dialog
158-
.setPositiveButton(TR.mediaCheckCheckMediaAction().toSentenceCase(R.string.sentence_check_media)) { _, _ ->
158+
.setPositiveButton(TR.sentenceCase.checkMediaAction) { _, _ ->
159159
requireSyncErrorDialogListener().mediaCheck()
160160
activity?.dismissAllDialogFragments()
161161
}.setNegativeButton(R.string.dialog_cancel) { _, _ -> }
@@ -171,7 +171,7 @@ class SyncErrorDialog : AsyncDialogFragment() {
171171
}
172172
DIALOG_SYNC_BASIC_CHECK_ERROR -> {
173173
dialog
174-
.setPositiveButton(TR.databaseCheckTitle().toSentenceCase(R.string.sentence_check_db)) { _, _ ->
174+
.setPositiveButton(TR.sentenceCase.checkDatabase) { _, _ ->
175175
requireSyncErrorDialogListener().integrityCheck()
176176
activity?.dismissAllDialogFragments()
177177
}.setNegativeButton(R.string.dialog_cancel) { _, _ -> }

AnkiDroid/src/main/java/com/ichi2/anki/mediacheck/MediaCheckFragment.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import com.ichi2.anki.R
3838
import com.ichi2.anki.SingleFragmentActivity
3939
import com.ichi2.anki.databinding.FragmentMediaCheckBinding
4040
import com.ichi2.anki.launchCatchingTask
41+
import com.ichi2.anki.ui.internationalization.sentenceCase
4142
import com.ichi2.anki.ui.internationalization.toSentenceCase
4243
import com.ichi2.anki.withProgress
4344
import com.ichi2.utils.cancelable
@@ -66,7 +67,7 @@ class MediaCheckFragment : Fragment(R.layout.fragment_media_check) {
6667
super.onViewCreated(view, savedInstanceState)
6768

6869
binding.toolbar.apply {
69-
setTitle(TR.mediaCheckWindowTitle().toSentenceCase(R.string.sentence_check_media))
70+
setTitle(TR.sentenceCase.checkMediaTitle)
7071
setNavigationOnClickListener {
7172
requireActivity().onBackPressedDispatcher.onBackPressed()
7273
}

AnkiDroid/src/main/java/com/ichi2/anki/ui/internationalization/SentenceCase.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ import android.content.Context
2020
import android.content.res.Resources
2121
import androidx.annotation.StringRes
2222
import androidx.fragment.app.Fragment
23+
import anki.i18n.GeneratedTranslations
24+
import com.ichi2.anki.CollectionManager.TR
25+
import com.ichi2.anki.R
2326

2427
// Functions for handling a move from 'Title Case' in Anki Desktop to 'Sentence case' in AnkiDroid
2528

@@ -59,3 +62,38 @@ fun String.toSentenceCase(
5962
if (this.equals(resString, ignoreCase = true)) return resString
6063
return this
6164
}
65+
66+
/**
67+
* Provides properties converting from Anki Desktop's 'Title Case' strings to AnkiDroid's
68+
* 'Sentence case' strings.
69+
*
70+
* Sentence case is a material design guideline
71+
*/
72+
// TODO: Expand for all past properties
73+
object SentenceCase {
74+
context(_: Context)
75+
val checkDatabase get() = TR.databaseCheckTitle().toSentenceCase(R.string.sentence_check_db)
76+
77+
context(_: Fragment)
78+
val checkDatabase get() = TR.databaseCheckTitle().toSentenceCase(R.string.sentence_check_db)
79+
80+
context(_: Context)
81+
val checkMediaTitle get() = TR.mediaCheckWindowTitle().toSentenceCase(R.string.sentence_check_media)
82+
83+
context(_: Fragment)
84+
val checkMediaTitle get() = TR.mediaCheckWindowTitle().toSentenceCase(R.string.sentence_check_media)
85+
86+
context(_: Context)
87+
val checkMediaAction get() = TR.mediaCheckCheckMediaAction().toSentenceCase(R.string.sentence_check_media)
88+
context(_: Fragment)
89+
val checkMediaAction get() = TR.mediaCheckCheckMediaAction().toSentenceCase(R.string.sentence_check_media)
90+
}
91+
92+
/**
93+
* Provides properties converting from Anki Desktop's 'Title Case' strings to AnkiDroid's
94+
* 'Sentence case' strings.
95+
*
96+
* Sentence case is a material design guideline
97+
*/
98+
@Suppress("UnusedReceiverParameter")
99+
val GeneratedTranslations.sentenceCase get() = SentenceCase

AnkiDroid/src/test/java/com/ichi2/anki/ui/internationalization/SentenceCaseTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ class SentenceCaseTest : RobolectricTest() {
4949
TR.cardTemplatesRestoreToDefault().toSentenceCase(this, R.string.sentence_restore_to_default),
5050
equalTo("Restore to default"),
5151
)
52-
assertThat(TR.databaseCheckTitle().toSentenceCase(this, R.string.sentence_check_db), equalTo("Check database"))
53-
assertThat(TR.mediaCheckWindowTitle().toSentenceCase(this, R.string.sentence_check_media), equalTo("Check media"))
54-
assertThat(TR.mediaCheckCheckMediaAction().toSentenceCase(this, R.string.sentence_check_media), equalTo("Check media"))
52+
assertThat(TR.sentenceCase.checkDatabase, equalTo("Check database"))
53+
assertThat(TR.sentenceCase.checkMediaTitle, equalTo("Check media"))
54+
assertThat(TR.sentenceCase.checkMediaAction, equalTo("Check media"))
5555

5656
assertThat("syncMediaLogTitle", TR.syncMediaLogTitle(), equalTo("Media Sync Log"))
5757
assertThat(

0 commit comments

Comments
 (0)