Skip to content

Commit

Permalink
feat: Preference - Show audio play buttons
Browse files Browse the repository at this point in the history
Functionality added in Anki Desktop

Fixes 14649
  • Loading branch information
david-allison authored and BrayanDSO committed Nov 3, 2023
1 parent 555c07c commit df10031
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ abstract class AbstractFlashcardViewer :
registerExternalStorageListener()
restoreCollectionPreferences(col)
initLayout()
mHtmlGenerator = createInstance(this, typeAnswer!!)
mHtmlGenerator = createInstance(this, col, typeAnswer!!)

// Initialize text-to-speech. This is an asynchronous operation.
mTTS.initialize(this, ReadTextListener())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ object UsageAnalytics {
"showTopbar", // Show top bar
"showProgress", // Show remaining
"showETA", // Show ETA
"showAudioPlayButtons", // Show play buttons on cards with audio (reversed in collection: HIDE_AUDIO_PLAY_BUTTONS)
"card_browser_show_media_filenames", // Display filenames in card browser
// Controls
"gestures", // Enable gestures
Expand Down
14 changes: 12 additions & 2 deletions AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/HtmlGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ package com.ichi2.anki.cardviewer
import android.content.Context
import android.content.res.Resources
import androidx.annotation.CheckResult
import anki.config.ConfigKey
import com.ichi2.anki.preferences.sharedPrefs
import com.ichi2.anki.reviewer.ReviewerCustomFonts
import com.ichi2.libanki.Card
import com.ichi2.libanki.Collection
import com.ichi2.libanki.Sound
import com.ichi2.libanki.stripAvRefs
import timber.log.Timber
import java.io.BufferedReader
import java.io.IOException
Expand All @@ -33,6 +36,7 @@ class HtmlGenerator(
private val typeAnswer: TypeAnswer,
val cardAppearance: CardAppearance,
val cardTemplate: CardTemplate,
private val showAudioPlayButtons: Boolean,
val resources: Resources
) {

Expand All @@ -49,22 +53,28 @@ class HtmlGenerator(
}

fun expandSounds(content: String): String {
return Sound.expandSounds(content)
return if (showAudioPlayButtons) {
Sound.expandSounds(content)
} else {
stripAvRefs(content)
}
}

companion object {
fun createInstance(
context: Context,
col: Collection,
typeAnswer: TypeAnswer
): HtmlGenerator {
val preferences = context.sharedPrefs()
val cardAppearance = CardAppearance.create(ReviewerCustomFonts(), preferences)
val cardHtmlTemplate = loadCardTemplate(context)

val showAudioPlayButtons = !col.config.getBool(ConfigKey.Bool.HIDE_AUDIO_PLAY_BUTTONS)
return HtmlGenerator(
typeAnswer,
cardAppearance,
cardHtmlTemplate,
showAudioPlayButtons,
context.resources
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import androidx.core.app.ActivityCompat
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.SwitchPreferenceCompat
import anki.config.ConfigKey
import com.ichi2.anki.*
import com.ichi2.anki.CollectionManager.withCol
import com.ichi2.anki.snackbar.showSnackbar
Expand Down Expand Up @@ -141,6 +142,16 @@ class AppearanceSettingsFragment : SettingsFragment() {
true
}
}

// Show play buttons on cards with audio
// Note: Stored inverted in the collection as HIDE_AUDIO_PLAY_BUTTONS
requirePreference<SwitchPreferenceCompat>(R.string.show_audio_play_buttons_key).apply {
title = CollectionManager.TR.preferencesShowPlayButtonsOnCardsWith()
launchCatchingTask { isChecked = withCol { !config.getBool(ConfigKey.Bool.HIDE_AUDIO_PLAY_BUTTONS) } }
setOnPreferenceChangeListener { newValue ->
launchCatchingTask { withCol { config.setBool(ConfigKey.Bool.HIDE_AUDIO_PLAY_BUTTONS, !(newValue as Boolean)) } }
}
}
}

private val mBackgroundImageResultLauncher = registerForActivityResult(ActivityResultContracts.GetContent()) { selectedImage ->
Expand Down
1 change: 1 addition & 0 deletions AnkiDroid/src/main/res/values/preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<string name="show_topbar_preference">showTopbar</string>
<string name="show_progress_preference">showProgress</string>
<string name="show_eta_preference">showETA</string>
<string name="show_audio_play_buttons_key">showAudioPlayButtons</string>
<string name="pref_card_browser_font_scale_key">relativeCardBrowserFontSize</string>
<!-- App bar buttons -->
<string name="pref_app_bar_buttons_screen_key">appBarButtonsScreen</string>
Expand Down
6 changes: 6 additions & 0 deletions AnkiDroid/src/main/res/xml/preferences_appearance.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:search="http://schemas.android.com/apk/com.bytehamster.lib.preferencesearch"
xmlns:tools="http://schemas.android.com/tools"
android:title="@string/pref_cat_appearance"
android:key="@string/pref_appearance_screen_key">
<PreferenceCategory android:title="@string/pref_cat_themes" >
Expand Down Expand Up @@ -109,6 +110,11 @@
android:defaultValue="true"
android:summary="@string/show_eta_summ"
android:title="@string/show_eta" />
<SwitchPreferenceCompat
android:key="@string/show_audio_play_buttons_key"
android:defaultValue="true"
tools:title="Show play buttons on cards with audio"
/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/card_browser">
<SwitchPreferenceCompat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import androidx.annotation.RequiresApi
import androidx.core.content.IntentCompat
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import anki.config.ConfigKey
import com.ichi2.anim.ActivityTransitionAnimation
import com.ichi2.anki.AbstractFlashcardViewer.WebViewSignalParserUtils.ANSWER_ORDINAL_1
import com.ichi2.anki.AbstractFlashcardViewer.WebViewSignalParserUtils.ANSWER_ORDINAL_2
Expand Down Expand Up @@ -259,6 +260,51 @@ class AbstractFlashcardViewerTest : RobolectricTest() {
assertEquals(getResourceString(R.string.studyoptions_congrats_finished), ShadowToast.getTextOfLatestToast())
}

@Test
fun `Show audio play buttons preference handling - sound`() = runTest {
addNoteUsingBasicTypedModel("SOUND [sound:android_audiorec.3gp]", "back")
getViewerContent().let { content ->
assertThat("show audio preference default value: enabled", content, containsString("playsound:q:0"))
assertThat("show audio preference default value: enabled", content, containsString("SOUND"))
}
setHidePlayAudioButtons(true)
getViewerContent().let { content ->
assertThat("show audio preference disabled", content, not(containsString("playsound:q:0")))
assertThat("show audio preference disabled", content, containsString("SOUND"))
}
setHidePlayAudioButtons(false)
getViewerContent().let { content ->
assertThat("show audio preference enabled explicitly", content, containsString("playsound:q:0"))
assertThat("show audio preference enabled explicitly", content, containsString("SOUND"))
}
}

@Test
fun `Show audio play buttons preference handling - tts`() = runTest {
addNoteUsingTextToSpeechNoteType("TTS", "BACK")
getViewerContent().let { content ->
assertThat("show audio preference default value: enabled", content, containsString("playsound:q:0"))
assertThat("show audio preference default value: enabled", content, containsString("TTS"))
}
setHidePlayAudioButtons(true)
getViewerContent().let { content ->
assertThat("show audio preference disabled", content, not(containsString("playsound:q:0")))
assertThat("show audio preference disabled", content, containsString("TTS"))
}
setHidePlayAudioButtons(false)
getViewerContent().let { content ->
assertThat("show audio preference enabled explicitly", content, containsString("playsound:q:0"))
assertThat("show audio preference enabled explicitly", content, containsString("TTS"))
}
}

private fun setHidePlayAudioButtons(value: Boolean) = col.config.setBool(ConfigKey.Bool.HIDE_AUDIO_PLAY_BUTTONS, value)

private fun getViewerContent(): String? {
// PERF: Optimise this to not create a new viewer each time
return getViewer(addCard = false).cardContent
}

private fun showNextCard(viewer: NonAbstractFlashcardViewer) {
viewer.executeCommand(ViewerCommand.FLIP_OR_ANSWER_EASE4)
viewer.executeCommand(ViewerCommand.FLIP_OR_ANSWER_EASE4)
Expand Down
7 changes: 7 additions & 0 deletions AnkiDroid/src/test/java/com/ichi2/anki/RobolectricTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,13 @@ open class RobolectricTest : AndroidTest {
return name
}

/** Adds a note with Text to Speech functionality */
@Suppress("SameParameterValue")
protected fun addNoteUsingTextToSpeechNoteType(front: String, back: String) {
addNonClozeModel("TTS", arrayOf("Front", "Back"), "{{Front}}{{tts en_GB:Front}}", "{{tts en_GB:Front}}<br>{{Back}}")
addNoteUsingModelName("TTS", front, back)
}

private fun addField(notetype: NotetypeJson, name: String) {
val models = col.notetypes
try {
Expand Down

0 comments on commit df10031

Please sign in to comment.