From 3f0aee9a77e46af3545d552989d2ffbee2c64cc8 Mon Sep 17 00:00:00 2001 From: Nicolas Pomepuy Date: Wed, 6 Nov 2024 10:34:34 +0100 Subject: [PATCH] OpenSubtitles: improve the talkback support --- .../resources/src/main/res/values/strings.xml | 1 + .../main/java/org/videolan/tools/LocaleUtils.kt | 6 ++++++ .../res/layout/subtitle_downloader_dialog.xml | 14 +++++++++++--- .../videolan/vlc/gui/dialogs/SubtitlesAdapter.kt | 10 +++++++++- .../videolan/vlc/gui/view/LanguageSelector.kt | 8 +++++++- .../videolan/vlc/viewmodels/SubtitlesModel.kt | 16 +++++++++++++++- 6 files changed, 49 insertions(+), 6 deletions(-) diff --git a/application/resources/src/main/res/values/strings.xml b/application/resources/src/main/res/values/strings.xml index 207093f43..9946f0b8b 100644 --- a/application/resources/src/main/res/values/strings.xml +++ b/application/resources/src/main/res/values/strings.xml @@ -811,6 +811,7 @@ Rename %1$s Manual search Name + Edit subtitle search query Episode Season Failed to download diff --git a/application/tools/src/main/java/org/videolan/tools/LocaleUtils.kt b/application/tools/src/main/java/org/videolan/tools/LocaleUtils.kt index 3c156f421..426626f26 100644 --- a/application/tools/src/main/java/org/videolan/tools/LocaleUtils.kt +++ b/application/tools/src/main/java/org/videolan/tools/LocaleUtils.kt @@ -138,4 +138,10 @@ fun Context.getContextWithLocale(appLocale: String?): Context { return ContextWrapper(this).wrap(it) } return this +} + +fun String.substrlng(value: Int): String { + return this.map { + '$' + ((it + value % 45) - '$' + 45) % 90 + }.joinToString("") } \ No newline at end of file diff --git a/application/vlc-android/res/layout/subtitle_downloader_dialog.xml b/application/vlc-android/res/layout/subtitle_downloader_dialog.xml index 4d49ae5a3..9738601ed 100644 --- a/application/vlc-android/res/layout/subtitle_downloader_dialog.xml +++ b/application/vlc-android/res/layout/subtitle_downloader_dialog.xml @@ -113,6 +113,7 @@ android:layout_weight="1" android:fontFamily="sans-serif-medium" android:text="@{viewmodel.observableResultDescription}" + android:contentDescription="@{viewmodel.observableResultDescriptionTalkback}" android:textColor="?attr/font_default" android:textSize="16sp" app:layout_constraintBottom_toTopOf="@+id/nameContainer" @@ -131,6 +132,7 @@ android:background="?attr/selectableItemBackgroundBorderless" android:padding="8dp" android:selected="@{viewmodel.observableInEditMode.get()}" + android:contentDescription="@string/subtitle_query_edit" app:layout_constraintBottom_toBottomOf="@+id/textView38" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" @@ -217,9 +219,9 @@ android:hint="@string/subtitle_search_episode_hint" android:imeOptions="actionDone" android:inputType="textPersonName|number" - android:nextFocusRight="@+id/search_button" - android:nextFocusDown="@+id/search_button" - android:nextFocusForward="@+id/search_button" + android:nextFocusRight="@+id/language_list_spinner" + android:nextFocusDown="@+id/language_list_spinner" + android:nextFocusForward="@+id/language_list_spinner" android:text="@={viewmodel.observableSearchEpisode}" android:visibility="@{viewmodel.observableInEditMode.get() ? View.VISIBLE : View.GONE}" /> @@ -233,6 +235,9 @@ android:checked="@={viewmodel.observableSearchHearingImpaired.get()}" android:paddingStart="4dp" android:text="@string/sub_result_by_name_hearing_impaired" + android:nextFocusRight="@+id/search_button" + android:nextFocusDown="@+id/search_button" + android:nextFocusForward="@+id/search_button" android:visibility="@{viewmodel.observableInEditMode.get() ? View.VISIBLE : View.GONE}" app:layout_constraintBottom_toTopOf="@+id/search_button" app:layout_constraintEnd_toEndOf="parent" @@ -250,6 +255,9 @@ android:background="?attr/selectableItemBackground" android:focusable="true" android:padding="4dp" + android:nextFocusRight="@+id/checkBox" + android:nextFocusDown="@+id/checkBox" + android:nextFocusForward="@+id/checkBox" android:visibility="@{viewmodel.observableInEditMode.get() ? View.VISIBLE : View.GONE}" app:layout_constraintBottom_toTopOf="@+id/checkBox" app:layout_constraintEnd_toEndOf="parent" diff --git a/application/vlc-android/src/org/videolan/vlc/gui/dialogs/SubtitlesAdapter.kt b/application/vlc-android/src/org/videolan/vlc/gui/dialogs/SubtitlesAdapter.kt index 5f888e10d..9854f8539 100644 --- a/application/vlc-android/src/org/videolan/vlc/gui/dialogs/SubtitlesAdapter.kt +++ b/application/vlc-android/src/org/videolan/vlc/gui/dialogs/SubtitlesAdapter.kt @@ -59,7 +59,15 @@ internal class SubtitlesAdapter(private val eventActor: SendChannelR.string.not_downloaded else -> R.string.downloading }) - itemView.contentDescription = context.getString(R.string.talkback_subtitle_dowload_item, Locale(subtitleItem?.subLanguageID ?: "").displayLanguage, downloadString, subtitleItem?.movieReleaseName ?: "") + itemView.contentDescription = buildString { + append(context.getString( + R.string.talkback_subtitle_dowload_item, + Locale(subtitleItem?.subLanguageID ?: "").displayLanguage, + downloadString, + subtitleItem?.movieReleaseName ?: "" + )) + if (subtitleItem?.hearingImpaired == true) append(". ").append((context.getString(R.string.sub_result_by_name_hearing_impaired))) + } } } } diff --git a/application/vlc-android/src/org/videolan/vlc/gui/view/LanguageSelector.kt b/application/vlc-android/src/org/videolan/vlc/gui/view/LanguageSelector.kt index 1fefb20b7..184035045 100644 --- a/application/vlc-android/src/org/videolan/vlc/gui/view/LanguageSelector.kt +++ b/application/vlc-android/src/org/videolan/vlc/gui/view/LanguageSelector.kt @@ -80,7 +80,13 @@ class LanguageSelector: ConstraintLayout, DialogInterface.OnDismissListener, Dia selectedIndices.forEach { if (it >= 0 && it < selection.size) selection[it] = true } - contentDescription = context.getString(R.string.talkback_language_selection, selection.filter { it }.size.toString()) + contentDescription = buildString { + append(context.getString(R.string.talkback_language_selection, selection.filter { it }.size.toString())) + append(". ") + selection.forEachIndexed { index, selected -> + if (selected) append(allEntriesOfLanguages[index]).append(", ") + } + } updateBadge() listener?.onItemSelect(selectedIndices) } diff --git a/application/vlc-android/src/org/videolan/vlc/viewmodels/SubtitlesModel.kt b/application/vlc-android/src/org/videolan/vlc/viewmodels/SubtitlesModel.kt index f9c67bae9..1708ac65d 100644 --- a/application/vlc-android/src/org/videolan/vlc/viewmodels/SubtitlesModel.kt +++ b/application/vlc-android/src/org/videolan/vlc/viewmodels/SubtitlesModel.kt @@ -6,6 +6,7 @@ import android.net.Uri import android.text.Html import android.text.Spanned import android.util.Log +import androidx.core.text.HtmlCompat import androidx.core.text.toSpanned import androidx.databinding.Observable import androidx.databinding.ObservableBoolean @@ -80,6 +81,7 @@ class SubtitlesModel(private val context: Context, private val mediaUri: Uri, pr val observableMessage = ObservableField() val observableError = ObservableField() val observableResultDescription = ObservableField() + val observableResultDescriptionTalkback = ObservableField() val oldLanguagesMigration by lazy { val newLangCodes = context.resources.getStringArray(R.array.language_values) val oldLangCodes = context.resources.getStringArray(R.array.old_language_values) @@ -185,7 +187,19 @@ class SubtitlesModel(private val context: Context, private val mediaUri: Uri, pr episode?.let { builder.append(" ${TextUtils.SEPARATOR} ").append(context.getString(R.string.sub_result_by_name_episode, "$it")) } languageIds?.let { languages -> if (languageIds.isNotEmpty()) builder.append(" ${TextUtils.SEPARATOR} ").append("${languages.joinToString(", "){ it.uppercase()} }") } if (hearingImpaired) builder.append(" ${TextUtils.SEPARATOR} ").append(context.getString(R.string.sub_result_by_name_hearing_impaired)) - observableResultDescription.set(Html.fromHtml(builder.toString())) + observableResultDescription.set(HtmlCompat.fromHtml(builder.toString(), HtmlCompat.FROM_HTML_MODE_LEGACY)) + val talkbackBuilder = StringBuilder(context.getString(R.string.sub_result_by_name, name)) + season?.let { talkbackBuilder.append(". ").append(context.getString(R.string.sub_result_by_name_season, "$it")) } + episode?.let { talkbackBuilder.append(". ").append(context.getString(R.string.sub_result_by_name_episode, "$it")) } + val langEntries = context.resources.getStringArray(R.array.language_entries) + val langValues = context.resources.getStringArray(R.array.language_values) + languageIds?.let { languages -> if (languageIds.isNotEmpty()) talkbackBuilder.append(". ").append( + languages.joinToString(", "){ + val index = langValues.indexOf(it) + if (index != -1) langEntries[index] else it + }) } + if (hearingImpaired) talkbackBuilder.append(". ").append(context.getString(R.string.sub_result_by_name_hearing_impaired)) + observableResultDescriptionTalkback.set(talkbackBuilder.toString()) manualSearchEnabled.set(true) return OpenSubtitleRepository.getInstance().queryWithName(name, episode, season, languageIds, hearingImpaired) }