Skip to content

Commit

Permalink
feat(card-browser): reimplement 'show media filenames'
Browse files Browse the repository at this point in the history
  • Loading branch information
david-allison committed Dec 21, 2024
1 parent f9ded4c commit 3f5254f
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,15 @@ class BrowserMultiColumnAdapter(

try {
val (row, isSelected) = viewModel.transformBrowserRow(id)
holder.firstColumn = row.getCells(0).text
holder.secondColumn = row.getCells(1).text

// PERF: removeSounds only needs to be performed on QUESTION/ANSWER columns
fun renderColumn(columnIndex: Int): String =
removeSounds(
input = row.getCells(columnIndex).text,
showMediaFilenames = viewModel.showMediaFilenames,
)
holder.firstColumn = renderColumn(0)
holder.secondColumn = renderColumn(1)
holder.setIsSelected(isSelected)
holder.setColor(backendColorToColor(row.color))
holder.setIsDeleted(false)
Expand Down Expand Up @@ -246,6 +253,20 @@ class BrowserMultiColumnAdapter(
}

companion object {
private val mediaFilenameRegex = Regex("\uD83D\uDD09(.*?)\uD83D\uDD09") // 🔉(.*?)🔉

/**
* Strips instances of '🔉filename.mp3🔉' if [showMediaFilenames] is not set
*/
@VisibleForTesting
fun removeSounds(
input: String,
showMediaFilenames: Boolean,
): String {
if (showMediaFilenames) return input
return mediaFilenameRegex.replace(input, "")
}

private const val DEFAULT_FONT_SIZE_RATIO = 100

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import com.ichi2.anki.model.CardsOrNotes.NOTES
import com.ichi2.anki.model.SortType
import com.ichi2.anki.pages.CardInfoDestination
import com.ichi2.anki.preferences.SharedPreferencesProvider
import com.ichi2.anki.setUserFlag
import com.ichi2.annotations.NeedsTest
import com.ichi2.libanki.Card
import com.ichi2.libanki.CardId
Expand Down Expand Up @@ -96,6 +97,8 @@ class CardBrowserViewModel(
private val manualInit: Boolean = false,
) : ViewModel(),
SharedPreferencesProvider by preferences {
val showMediaFilenames = sharedPrefs().getBoolean("card_browser_show_media_filenames", false)

/** A job which ensures that parallel searches do not occur */
var searchJob: Job? = null
private set
Expand All @@ -111,9 +114,8 @@ class CardBrowserViewModel(
private set
private var restrictOnDeck: String = ""

// flowOfFilterQuery does not currently bind to the value in the UI and is only used for posting

/** text in the search box (potentially unsubmitted) */
// this does not currently bind to the value in the UI and is only used for posting
val flowOfFilterQuery = MutableSharedFlow<String>()

/**
Expand Down Expand Up @@ -175,6 +177,7 @@ class CardBrowserViewModel(

suspend fun queryAllSelectedNoteIds() = selectedRows.queryNoteIds(this.cardsOrNotes)

@Suppress("RedundantSuspendModifier") // will be necessary
@VisibleForTesting
internal suspend fun queryAllCardIds() = cards.queryCardIds()

Expand Down Expand Up @@ -488,8 +491,6 @@ class CardBrowserViewModel(

fun selectedRowCount(): Int = selectedRows.size

suspend fun selectedNoteCount() = selectedRows.queryNoteIds(cardsOrNotes).distinct().size

suspend fun changeCardOrder(which: SortType): Job? {
val changeType =
when {
Expand Down
3 changes: 2 additions & 1 deletion AnkiDroid/src/test/java/com/ichi2/anki/CardBrowserTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import com.ichi2.anki.browser.CardBrowserColumn.QUESTION
import com.ichi2.anki.browser.CardBrowserColumn.SFLD
import com.ichi2.anki.browser.CardBrowserColumn.TAGS
import com.ichi2.anki.browser.CardBrowserViewModel
import com.ichi2.anki.browser.CardBrowserViewModelTest
import com.ichi2.anki.browser.CardOrNoteId
import com.ichi2.anki.common.utils.isRunningAsUnitTest
import com.ichi2.anki.dialogs.DeckSelectionDialog
Expand Down Expand Up @@ -1122,7 +1123,7 @@ class CardBrowserTest : RobolectricTest() {
}
val question = card.getColumnHeaderText(QUESTION)

assertThat(question, equalTo("\uD83D\uDCACTest\uD83D\uDCAC"))
assertThat(question, equalTo(CardBrowserViewModelTest.EXPECTED_TTS))
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 David Allison <[email protected]>
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.ichi2.anki.browser

import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
import org.junit.Test

/**
* Tests for [BrowserMultiColumnAdapter]
*/
class BrowserMultiColumnAdapterTest {
companion object {
const val EXPECTED_SOUND = "\uD83D\uDD09david.mp3\uD83D\uDD09"
const val TTS = "\uD83D\uDCACTest\uD83D\uDCAC"
}

@Test
fun `sound without filenames`() {
val text = BrowserMultiColumnAdapter.removeSounds(EXPECTED_SOUND, showMediaFilenames = false)
assertThat("sound filename stripped", text, equalTo(""))
}

@Test
fun `tts not affected`() {
val text = BrowserMultiColumnAdapter.removeSounds(TTS, showMediaFilenames = false)
assertThat("unchanged", text, equalTo(TTS))
}

@Test
fun `sound with filenames`() {
val text = BrowserMultiColumnAdapter.removeSounds(EXPECTED_SOUND, showMediaFilenames = true)
assertThat("unchanged", text, equalTo(EXPECTED_SOUND))
}

@Test
fun `meta test`() {
// ensure that Anki's output has not changed
assertThat("sound", EXPECTED_SOUND, equalTo(CardBrowserViewModelTest.EXPECTED_SOUND))
assertThat("tts", TTS, equalTo(CardBrowserViewModelTest.EXPECTED_TTS))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.ichi2.anki.browser

import androidx.core.content.edit
import androidx.test.ext.junit.runners.AndroidJUnit4
import app.cash.turbine.TurbineTestContext
import app.cash.turbine.test
Expand Down Expand Up @@ -773,6 +774,32 @@ class CardBrowserViewModelTest : JvmTest() {
}
}

@Test
fun `sound tags regression test`() {
addNoteUsingBasicModel("[sound:david.mp3]")

showMediaFilenamesPreference = false

BrowserColumnCollection.update(AnkiDroidApp.sharedPreferencesProvider.sharedPrefs(), CardsOrNotes.CARDS) {
it[0] = QUESTION
return@update true
}

runViewModelTest {
waitForSearchResults()
val (row, _) = this.transformBrowserRow(this.cards.single())
val question = row.getCells(0)
assertThat(question.text, equalTo(EXPECTED_SOUND))
}
}

private var showMediaFilenamesPreference: Boolean
get() = AnkiDroidApp.sharedPreferencesProvider.sharedPrefs().getBoolean("card_browser_show_media_filenames", false)
set(value) =
AnkiDroidApp.sharedPreferencesProvider.sharedPrefs().edit {
putBoolean("card_browser_show_media_filenames", value)
}

private fun runViewModelNotesTest(
notes: Int = 0,
manualInit: Boolean = true,
Expand Down Expand Up @@ -823,6 +850,9 @@ class CardBrowserViewModelTest : JvmTest() {
}

companion object {
const val EXPECTED_SOUND = "\uD83D\uDD09david.mp3\uD83D\uDD09"
const val EXPECTED_TTS = "\uD83D\uDCACTest\uD83D\uDCAC"

private suspend fun viewModel(
lastDeckId: DeckId? = null,
intent: CardBrowserLaunchOptions? = null,
Expand Down

0 comments on commit 3f5254f

Please sign in to comment.