From 29327688911741a075c03e2b586d09e38db8388a Mon Sep 17 00:00:00 2001 From: LagradOst Date: Tue, 30 Nov 2021 18:59:52 +0100 Subject: [PATCH] subs fix --- .../com/lagradost/cloudstream3/MainAPI.kt | 1 - .../cloudstream3/ui/player/PlayerFragment.kt | 59 +++++++++---- .../cloudstream3/ui/result/ResultFragment.kt | 26 +++--- .../cloudstream3/ui/result/ResultViewModel.kt | 47 ++++++++--- .../cloudstream3/ui/search/SearchHelper.kt | 5 +- .../ui/subtitles/SubtitlesFragment.kt | 83 ++++++++++--------- .../cloudstream3/utils/SubtitleHelper.kt | 21 +++-- app/src/main/res/values-sv/strings.xml | 22 +++++ app/src/main/res/values/strings.xml | 16 +++- 9 files changed, 190 insertions(+), 90 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index a92a3bbd..1b7c5149 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -7,7 +7,6 @@ import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.json.JsonMapper import com.fasterxml.jackson.module.kotlin.KotlinModule import com.lagradost.cloudstream3.animeproviders.* -import com.lagradost.cloudstream3.metaproviders.TmdbProvider import com.lagradost.cloudstream3.movieproviders.* import com.lagradost.cloudstream3.utils.ExtractorLink import java.util.* diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt index 840455ad..a1636f48 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt @@ -920,9 +920,9 @@ class PlayerFragment : Fragment() { private var resizeMode = 0 private var playbackSpeed = 0f - private var allEpisodes: HashMap> = HashMap() - private var allEpisodesSubs: HashMap> = HashMap() - private var episodes: List = ArrayList() + private var allEpisodes: HashMap> = HashMap() + private var allEpisodesSubs: HashMap> = HashMap() + private var episodes: List = emptyList() var currentPoster: String? = null var currentHeaderName: String? = null var currentIsMovie: Boolean? = null @@ -1138,7 +1138,7 @@ class PlayerFragment : Fragment() { context?.let { ctx -> //val isPlaying = exoPlayer.isPlaying exoPlayer.pause() - val currentSubtitles = activeSubtitles + val currentSubtitles = context?.getSubs()?.map { it.lang } ?: activeSubtitles val sourceBuilder = AlertDialog.Builder(ctx, R.style.AlertDialogCustomBlack) .setView(R.layout.player_select_source_and_subs) @@ -1189,8 +1189,8 @@ class PlayerFragment : Fragment() { } val startIndexFromMap = - currentSubtitles.map { it.removeSuffix(" ") } - .indexOf(preferredSubtitles.removeSuffix(" ")) + 1 + currentSubtitles.map { it.trimEnd() } + .indexOf(preferredSubtitles.trimEnd()) + 1 var subtitleIndex = startIndexFromMap if (currentSubtitles.isEmpty()) { @@ -1218,13 +1218,27 @@ class PlayerFragment : Fragment() { } applyButton.setOnClickListener { + if (this::exoPlayer.isInitialized) playbackPosition = exoPlayer.currentPosition + + var init = false if (sourceIndex != startSource) { - playbackPosition = if (this::exoPlayer.isInitialized) exoPlayer.currentPosition else 0 setMirrorId(sources[sourceIndex].getId()) - initPlayer(getCurrentUrl()) + init = true } if (subtitleIndex != startIndexFromMap) { - setPreferredSubLanguage(if (subtitleIndex <= 0) null else currentSubtitles[subtitleIndex - 1]) + if (subtitleIndex <= 0) { + setPreferredSubLanguage(null) + } else { + val langId = currentSubtitles[subtitleIndex - 1].trimEnd() + setPreferredSubLanguage(langId) + + if (!activeSubtitles.any { it.trimEnd() == langId }) { + init = true + } + } + } + if (init) { + initPlayer(getCurrentUrl()) } sourceDialog.dismiss() } @@ -1253,7 +1267,7 @@ class PlayerFragment : Fragment() { private fun setPreferredSubLanguage(lang: String?) { //val textRendererIndex = getRendererIndex(C.TRACK_TYPE_TEXT) ?: return@setOnClickListener - val realLang = if (lang.isNullOrBlank()) "" else lang + val realLang = if (lang.isNullOrBlank()) "" else lang.trimEnd() preferredSubtitles = if (realLang.length == 2) SubtitleHelper.fromTwoLettersToLanguage(realLang) ?: realLang else realLang @@ -1268,7 +1282,7 @@ class PlayerFragment : Fragment() { } else { trackSelector.setParameters( trackSelector.buildUponParameters() - .setPreferredTextLanguage(realLang) + .setPreferredTextLanguage("_$realLang") //.setRendererDisabled(textRendererIndex, false) ) } @@ -1423,7 +1437,9 @@ class PlayerFragment : Fragment() { player_media_route_button?.isVisible = !isDownloadedFile if (savedInstanceState != null) { currentWindow = savedInstanceState.getInt(STATE_RESUME_WINDOW) - playbackPosition = savedInstanceState.getLong(STATE_RESUME_POSITION) + if (playbackPosition <= 0) { + playbackPosition = savedInstanceState.getLong(STATE_RESUME_POSITION) + } isFullscreen = savedInstanceState.getBoolean(STATE_PLAYER_FULLSCREEN) isPlayerPlaying = savedInstanceState.getBoolean(STATE_PLAYER_PLAYING) resizeMode = savedInstanceState.getInt(RESIZE_MODE_KEY) @@ -1479,6 +1495,13 @@ class PlayerFragment : Fragment() { observeDirectly(viewModel.allEpisodesSubs) { _allEpisodesSubs -> allEpisodesSubs = _allEpisodesSubs + if (preferredSubtitles != "" && !activeSubtitles.contains(preferredSubtitles) && allEpisodesSubs[getEpisode()?.id]?.containsKey( + preferredSubtitles + ) == true + ) { + if (this::exoPlayer.isInitialized) playbackPosition = exoPlayer.currentPosition + initPlayer(getCurrentUrl()) + } } observeDirectly(viewModel.resultResponse) { data -> @@ -1495,6 +1518,8 @@ class PlayerFragment : Fragment() { is Resource.Failure -> { //WTF, HOW DID YOU EVEN GET HERE } + else -> { + } } } } @@ -1685,7 +1710,7 @@ class PlayerFragment : Fragment() { } return list } else { - allEpisodesSubs[getEpisode()?.id] + allEpisodesSubs[getEpisode()?.id]?.values?.toList()?.sortedBy { it.lang } } } catch (e: Exception) { null @@ -1952,13 +1977,13 @@ class PlayerFragment : Fragment() { val subItemsId = ArrayList() for (sub in sortSubs(subs)) { - val langId = sub.lang //SubtitleHelper.fromLanguageToTwoLetters(it.lang) ?: it.lang + val langId = sub.lang.trimEnd() //SubtitleHelper.fromLanguageToTwoLetters(it.lang) ?: it.lang subItemsId.add(langId) subItems.add( MediaItem.Subtitle( Uri.parse(sub.url), sub.url.toSubtitleMimeType(), - langId, + "_$langId", C.SELECTION_FLAG_DEFAULT ) ) @@ -2014,6 +2039,7 @@ class PlayerFragment : Fragment() { databaseProvider ) } + val cacheFactory = CacheDataSource.Factory().apply { simpleCache?.let { setCache(it) } setUpstreamDataSourceFactory(getDataSourceFactory()) @@ -2084,7 +2110,6 @@ class PlayerFragment : Fragment() { player_view?.performClick() - //TODO FIX video_title?.text = hName + if (isEpisodeBased) if (epSeason == null) @@ -2199,7 +2224,7 @@ class PlayerFragment : Fragment() { } override fun onPlayerError(error: PlaybackException) { - println("CURRENT URL: " + currentUrl?.url) + println("CURRENT URL ERROR: " + currentUrl?.url) // Lets pray this doesn't spam Toasts :) val msg = error.message ?: "" val errorName = error.errorCodeName diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt index 9f6d326b..05ea16e7 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt @@ -126,7 +126,7 @@ fun Context.buildResultEpisode( id: Int, index: Int, rating: Int?, - descript: String?, + description: String?, isFiller: Boolean?, ): ResultEpisode { val posDur = getViewPos(id) @@ -142,7 +142,7 @@ fun Context.buildResultEpisode( posDur?.position ?: 0, posDur?.duration ?: 0, rating, - descript, + description, isFiller ) } @@ -167,8 +167,8 @@ class ResultFragment : Fragment() { private var currentLoadingCount = 0 // THIS IS USED TO PREVENT LATE EVENTS, AFTER DISMISS WAS CLICKED private val viewModel: ResultViewModel by activityViewModels() - private var allEpisodes: HashMap> = HashMap() - private var allEpisodesSubs: HashMap> = HashMap() + private var allEpisodes: HashMap> = HashMap() + private var allEpisodesSubs: HashMap> = HashMap() private var currentHeaderName: String? = null private var currentType: TvType? = null private var currentEpisodes: List? = null @@ -352,8 +352,8 @@ class ResultFragment : Fragment() { val index = episodeClick.data.index val buildInPlayer = true currentLoadingCount++ - var currentLinks: ArrayList? = null - var currentSubs: ArrayList? = null + var currentLinks: List? = null + var currentSubs: HashMap? = null val showTitle = episodeClick.data.name ?: getString(R.string.episode_name_format).format( @@ -443,7 +443,7 @@ class ResultFragment : Fragment() { episodeClick.data.index, eps, sortUrls(currentLinks ?: return), - currentSubs ?: ArrayList(), + currentSubs?.values?.toList() ?: emptyList(), startTime = episodeClick.data.getRealPosition(), startIndex = startIndex ) @@ -673,7 +673,7 @@ class ResultFragment : Fragment() { } var text = "#EXTM3U" if (subs != null) { - for (sub in subs) { + for (sub in subs.values) { text += "\n#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"${sub.lang}\",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE=\"${sub.lang}\",URI=\"${sub.url}\"" } } @@ -731,7 +731,7 @@ class ResultFragment : Fragment() { } ACTION_DOWNLOAD_EPISODE -> { - startDownload(currentLinks ?: return@main, currentSubs) + startDownload(currentLinks ?: return@main, currentSubs?.values?.toList() ?: emptyList()) } ACTION_DOWNLOAD_MIRROR -> { @@ -740,7 +740,7 @@ class ResultFragment : Fragment() { links,//(currentLinks ?: return@main).filter { !it.isM3u8 }, getString(R.string.episode_action_download_mirror) ) { link -> - startDownload(listOf(link), currentSubs) + startDownload(listOf(link), currentSubs?.values?.toList() ?: emptyList()) } } } @@ -1064,6 +1064,12 @@ class ResultFragment : Fragment() { return@setOnLongClickListener true } + result_download_movie?.setOnLongClickListener { + val card = currentEpisodes?.firstOrNull() ?: return@setOnLongClickListener true + handleAction(EpisodeClickEvent(ACTION_SHOW_OPTIONS, card)) + return@setOnLongClickListener true + } + // result_options.setOnClickListener { // val card = currentEpisodes?.first() ?: return@setOnClickListener // handleAction(EpisodeClickEvent(ACTION_SHOW_OPTIONS, card)) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt index 02f21e2d..3e5286cf 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt @@ -12,9 +12,8 @@ import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.mvvm.safeApiCall import com.lagradost.cloudstream3.ui.APIRepository import com.lagradost.cloudstream3.ui.WatchType -import com.lagradost.cloudstream3.utils.DOWNLOAD_HEADER_CACHE +import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.DataStore.setKey -import com.lagradost.cloudstream3.utils.DataStoreHelper import com.lagradost.cloudstream3.utils.DataStoreHelper.getBookmarkedData import com.lagradost.cloudstream3.utils.DataStoreHelper.getResultSeason import com.lagradost.cloudstream3.utils.DataStoreHelper.getResultWatchState @@ -25,9 +24,7 @@ import com.lagradost.cloudstream3.utils.DataStoreHelper.setLastWatched import com.lagradost.cloudstream3.utils.DataStoreHelper.setResultSeason import com.lagradost.cloudstream3.utils.DataStoreHelper.setResultWatchState import com.lagradost.cloudstream3.utils.DataStoreHelper.setViewPos -import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.FillerEpisodeCheck.getFillerEpisodes -import com.lagradost.cloudstream3.utils.VideoDownloadHelper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -133,7 +130,7 @@ class ResultViewModel : ViewModel() { val seasons = seasonTypes.toList().map { it.first }.sortedBy { it } seasonSelections.postValue(seasons) if (seasons.isEmpty()) { // WHAT THE FUCK DID YOU DO????? HOW DID YOU DO THIS - _publicEpisodes.postValue(Resource.Success(ArrayList())) + _publicEpisodes.postValue(Resource.Success(emptyList())) return } @@ -415,18 +412,18 @@ class ResultViewModel : ViewModel() { } } - private val _allEpisodes: MutableLiveData>> = + private val _allEpisodes: MutableLiveData>> = MutableLiveData(HashMap()) // LOOKUP BY ID - private val _allEpisodesSubs: MutableLiveData>> = + private val _allEpisodesSubs: MutableLiveData>> = MutableLiveData(HashMap()) // LOOKUP BY ID - val allEpisodes: LiveData>> get() = _allEpisodes - val allEpisodesSubs: LiveData>> get() = _allEpisodesSubs + val allEpisodes: LiveData>> get() = _allEpisodes + val allEpisodesSubs: LiveData>> get() = _allEpisodesSubs private var _apiName: MutableLiveData = MutableLiveData() val apiName: LiveData get() = _apiName - data class EpisodeData(val links: ArrayList, val subs: ArrayList) + data class EpisodeData(val links: List, val subs: HashMap) fun loadEpisode( episode: ResultEpisode, @@ -452,11 +449,35 @@ class ResultViewModel : ViewModel() { _allEpisodes.value?.remove(id) } val links = ArrayList() - val subs = ArrayList() + val subs = HashMap() return safeApiCall { repo?.loadLinks(data, isCasting, { subtitleFile -> - if (!subs.any { it.url == subtitleFile.url }) { - subs.add(subtitleFile) + if (!subs.values.any { it.url == subtitleFile.url }) { + val langTrimmed = subtitleFile.lang.trimEnd() + + val langId = if (langTrimmed.length == 2) { + SubtitleHelper.fromTwoLettersToLanguage(langTrimmed) ?: langTrimmed + } else { + langTrimmed + } + + var title: String + var count = 0 + while (true) { + title = "$langId${if (count == 0) "" else " ${count+1}"}" + count++ + if(!subs.containsKey(title)) { + break + } + } + + val file = + subtitleFile.copy( + lang = title + ) + + subs[title] = file + _allEpisodesSubs.value?.set(id, subs) _allEpisodesSubs.postValue(_allEpisodesSubs.value) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchHelper.kt index f16e2095..e70659be 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchHelper.kt @@ -41,7 +41,10 @@ object SearchHelper { activity.loadSearchResult(card, START_ACTION_LOAD_EP, card.id!!) } } else { - handleSearchClickCallback(activity, SearchClickCallback(SEARCH_ACTION_LOAD,callback.view,callback.card)) + handleSearchClickCallback( + activity, + SearchClickCallback(SEARCH_ACTION_LOAD, callback.view, callback.card) + ) } } SEARCH_ACTION_SHOW_METADATA -> { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/subtitles/SubtitlesFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/subtitles/SubtitlesFragment.kt index e03511ae..cab9427a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/subtitles/SubtitlesFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/subtitles/SubtitlesFragment.kt @@ -216,12 +216,19 @@ class SubtitlesFragment : Fragment() { } subs_subtitle_elevation.setOnClickListener { textView -> + val suffix = "dp" val elevationTypes = listOf( - Pair(0, "None"), - Pair(10, "10"), - Pair(20, "20"), - Pair(30, "30"), - Pair(40, "40"), + Pair(0, textView.context.getString(R.string.none)), + Pair(10, "10$suffix"), + Pair(20, "20$suffix"), + Pair(30, "30$suffix"), + Pair(40, "40$suffix"), + Pair(50, "50$suffix"), + Pair(60, "60$suffix"), + Pair(70, "70$suffix"), + Pair(80, "80$suffix"), + Pair(90, "90$suffix"), + Pair(100, "100$suffix"), ) //showBottomDialog @@ -248,11 +255,11 @@ class SubtitlesFragment : Fragment() { subs_edge_type.setOnClickListener { textView -> val edgeTypes = listOf( - Pair(CaptionStyleCompat.EDGE_TYPE_NONE, "None"), - Pair(CaptionStyleCompat.EDGE_TYPE_OUTLINE, "Outline"), - Pair(CaptionStyleCompat.EDGE_TYPE_DEPRESSED, "Depressed"), - Pair(CaptionStyleCompat.EDGE_TYPE_DROP_SHADOW, "Shadow"), - Pair(CaptionStyleCompat.EDGE_TYPE_RAISED, "Raised"), + Pair(CaptionStyleCompat.EDGE_TYPE_NONE, textView.context.getString(R.string.subtitles_none)), + Pair(CaptionStyleCompat.EDGE_TYPE_OUTLINE, textView.context.getString(R.string.subtitles_outline)), + Pair(CaptionStyleCompat.EDGE_TYPE_DEPRESSED, textView.context.getString(R.string.subtitles_depressed)), + Pair(CaptionStyleCompat.EDGE_TYPE_DROP_SHADOW, textView.context.getString(R.string.subtitles_shadow)), + Pair(CaptionStyleCompat.EDGE_TYPE_RAISED, textView.context.getString(R.string.subtitles_raised)), ) //showBottomDialog @@ -278,32 +285,32 @@ class SubtitlesFragment : Fragment() { subs_font_size.setOnClickListener { textView -> val suffix = "sp" val fontSizes = listOf( - Pair(null, "Normal"), - Pair(6f,"6$suffix"), - Pair(8f,"8$suffix"), - Pair(9f,"9$suffix"), - Pair(10f,"10$suffix"), - Pair(11f,"11$suffix"), - Pair(12f,"12$suffix"), - Pair(14f,"14$suffix"), - Pair(16f,"16$suffix"), - Pair(18f,"18$suffix"), - Pair(19f,"19$suffix"), - Pair(21f,"21$suffix"), - Pair(23f,"23$suffix"), - Pair(24f,"24$suffix"), - Pair(26f,"26$suffix"), - Pair(28f,"28$suffix"), - Pair(30f,"30$suffix"), - Pair(32f,"32$suffix"), - Pair(34f,"34$suffix"), - Pair(36f,"36$suffix"), - Pair(38f,"38$suffix"), - Pair(40f,"40$suffix"), - Pair(42f,"42$suffix"), - Pair(44f,"44$suffix"), - Pair(48f,"48$suffix"), - Pair(60f,"60$suffix"), + Pair(null, textView.context.getString(R.string.normal)), + Pair(6f, "6$suffix"), + Pair(8f, "8$suffix"), + Pair(9f, "9$suffix"), + Pair(10f, "10$suffix"), + Pair(11f, "11$suffix"), + Pair(12f, "12$suffix"), + Pair(14f, "14$suffix"), + Pair(16f, "16$suffix"), + Pair(18f, "18$suffix"), + Pair(19f, "19$suffix"), + Pair(21f, "21$suffix"), + Pair(23f, "23$suffix"), + Pair(24f, "24$suffix"), + Pair(26f, "26$suffix"), + Pair(28f, "28$suffix"), + Pair(30f, "30$suffix"), + Pair(32f, "32$suffix"), + Pair(34f, "34$suffix"), + Pair(36f, "36$suffix"), + Pair(38f, "38$suffix"), + Pair(40f, "40$suffix"), + Pair(42f, "42$suffix"), + Pair(44f, "44$suffix"), + Pair(48f, "48$suffix"), + Pair(60f, "60$suffix"), ) //showBottomDialog @@ -328,7 +335,7 @@ class SubtitlesFragment : Fragment() { subs_font.setOnClickListener { textView -> val fontTypes = listOf( - Pair(null, "Normal"), + Pair(null, textView.context.getString(R.string.normal)), Pair(R.font.trebuchet_ms, "Trebuchet MS"), Pair(R.font.netflix_sans, "Netflix Sans"), Pair(R.font.google_sans, "Google Sans"), @@ -430,7 +437,7 @@ class SubtitlesFragment : Fragment() { getPixels(TypedValue.COMPLEX_UNIT_SP, 25.0f).toFloat(), Cue.TEXT_SIZE_TYPE_ABSOLUTE ) - .setText("The quick brown fox jumps over the lazy dog").build() + .setText(subtitle_text.context.getString(R.string.subtitles_example_text)).build() ) ) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/SubtitleHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/SubtitleHelper.kt index 58044d0e..3eebce76 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/SubtitleHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/SubtitleHelper.kt @@ -1,8 +1,5 @@ package com.lagradost.cloudstream3.utils -import com.lagradost.cloudstream3.network.get -import com.lagradost.cloudstream3.network.text -import org.jsoup.Jsoup import java.util.* object SubtitleHelper { @@ -52,16 +49,22 @@ object SubtitleHelper { return null } + private var ISO_639_1Map : HashMap = hashMapOf() + private fun initISO6391Map() { + for (lang in languages) { + ISO_639_1Map[lang.ISO_639_1] = lang.languageName + } + } + /** ISO_639_1 -> lang*/ fun fromTwoLettersToLanguage(input: String): String? { if (input.length != 2) return null - val comparison = input.toLowerCase(Locale.ROOT) - for (lang in languages) { - if (lang.ISO_639_1 == comparison) { - return lang.languageName - } + if(ISO_639_1Map.isEmpty()) { + initISO6391Map() } - return null + val comparison = input.toLowerCase(Locale.ROOT) + + return ISO_639_1Map[comparison] } /**ISO_639_2_B or ISO_639_2_T or ISO_639_3-> lang*/ diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 87abd50d..5eaf206d 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -213,4 +213,26 @@ Källfel Fjärrfel Renderingsfel + Flygande bäckasiner söka hwila på mjuka tuvor + Skugga + Kontur + Nedsänkt + Upphöjd + Ingen + Normal + Allt + Min + Max + Lägg till konto + Byt konto + Logga in + Logga ut + konto + Nerladdningsplats + Kollar om + Automatisk + DNS över HTTPS + " " + Appens tema + %s A%d diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7143ab55..fd38c149 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -333,5 +333,19 @@ Switch account Add account - + None + Normal + All + Max + Min + @string/none + Outline + Depressed + Shadow + Raised + + The quick brown fox jumps over the lazy dog