forked from recloudstream/cloudstream
		
	chromecast subtitles color + zoro fix
This commit is contained in:
		
							parent
							
								
									70776ea80d
								
							
						
					
					
						commit
						6da2bf900e
					
				
					 11 changed files with 568 additions and 30 deletions
				
			
		|  | @ -36,7 +36,7 @@ android { | ||||||
|         targetSdkVersion 30 |         targetSdkVersion 30 | ||||||
| 
 | 
 | ||||||
|         versionCode 42 |         versionCode 42 | ||||||
|         versionName "2.6.11" |         versionName "2.6.12" | ||||||
| 
 | 
 | ||||||
|         resValue "string", "app_version", |         resValue "string", "app_version", | ||||||
|                 "${defaultConfig.versionName}${versionNameSuffix ?: ""}" |                 "${defaultConfig.versionName}${versionNameSuffix ?: ""}" | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ import com.lagradost.cloudstream3.movieproviders.SflixProvider | ||||||
| import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.toExtractorLink | import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.toExtractorLink | ||||||
| import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.toSubtitleFile | import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.toSubtitleFile | ||||||
| import com.lagradost.cloudstream3.network.WebViewResolver | import com.lagradost.cloudstream3.network.WebViewResolver | ||||||
|  | import com.lagradost.cloudstream3.utils.AppUtils.parseJson | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
| import com.lagradost.cloudstream3.utils.loadExtractor | import com.lagradost.cloudstream3.utils.loadExtractor | ||||||
| import org.jsoup.Jsoup | import org.jsoup.Jsoup | ||||||
|  | @ -283,10 +284,10 @@ class ZoroProvider : MainAPI() { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private suspend fun getM3u8FromRapidCloud(url: String): String { |     private suspend fun getM3u8FromRapidCloud(url: String): String { | ||||||
|         return Regex("""/(embed-\d+)/(.*?)\?z=""").find(url)?.groupValues?.let { |         return /*Regex("""/(embed-\d+)/(.*?)\?z=""").find(url)?.groupValues?.let { | ||||||
|             val jsonLink = "https://rapid-cloud.ru/ajax/${it[1]}/getSources?id=${it[2]}" |             val jsonLink = "https://rapid-cloud.ru/ajax/${it[1]}/getSources?id=${it[2]}" | ||||||
|             app.get(jsonLink).text |             app.get(jsonLink).text | ||||||
|         } ?: app.get( |         } ?:*/ app.get( | ||||||
|             "$url&autoPlay=1&oa=0", |             "$url&autoPlay=1&oa=0", | ||||||
|             headers = mapOf( |             headers = mapOf( | ||||||
|                 "Referer" to "https://zoro.to/", |                 "Referer" to "https://zoro.to/", | ||||||
|  | @ -319,6 +320,7 @@ class ZoroProvider : MainAPI() { | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|         // Prevent duplicates |         // Prevent duplicates | ||||||
|         servers.distinctBy { it.second }.apmap { |         servers.distinctBy { it.second }.apmap { | ||||||
|             val link = |             val link = | ||||||
|  | @ -326,7 +328,7 @@ class ZoroProvider : MainAPI() { | ||||||
|             val extractorLink = app.get( |             val extractorLink = app.get( | ||||||
|                 link, |                 link, | ||||||
|             ).mapped<RapidCloudResponse>().link |             ).mapped<RapidCloudResponse>().link | ||||||
| 
 | //.also { println("AAAAAAAAA: ${it.text}") } | ||||||
|             // Loads the links in the appropriate extractor. |             // Loads the links in the appropriate extractor. | ||||||
|             val hasLoadedExtractorLink = loadExtractor(extractorLink, mainUrl, callback) |             val hasLoadedExtractorLink = loadExtractor(extractorLink, mainUrl, callback) | ||||||
| 
 | 
 | ||||||
|  | @ -342,7 +344,7 @@ class ZoroProvider : MainAPI() { | ||||||
|                     ) |                     ) | ||||||
| 
 | 
 | ||||||
|                 if (response.contains("<html")) return@apmap |                 if (response.contains("<html")) return@apmap | ||||||
|                 val mapped = mapper.readValue<SflixProvider.SourceObject>(response) |                 val mapped = parseJson<SflixProvider.SourceObject>(response) | ||||||
| 
 | 
 | ||||||
|                 mapped.tracks?.forEach { track -> |                 mapped.tracks?.forEach { track -> | ||||||
|                     track?.toSubtitleFile()?.let { subtitleFile -> |                     track?.toSubtitleFile()?.let { subtitleFile -> | ||||||
|  |  | ||||||
|  | @ -1,6 +1,5 @@ | ||||||
| package com.lagradost.cloudstream3.ui | package com.lagradost.cloudstream3.ui | ||||||
| 
 | 
 | ||||||
| import android.graphics.Color |  | ||||||
| import android.os.Bundle | import android.os.Bundle | ||||||
| import android.util.Log | import android.util.Log | ||||||
| import android.view.Menu | import android.view.Menu | ||||||
|  | @ -15,7 +14,6 @@ import com.google.android.gms.cast.MediaSeekOptions | ||||||
| import com.google.android.gms.cast.MediaStatus.REPEAT_MODE_REPEAT_OFF | import com.google.android.gms.cast.MediaStatus.REPEAT_MODE_REPEAT_OFF | ||||||
| import com.google.android.gms.cast.MediaTrack | import com.google.android.gms.cast.MediaTrack | ||||||
| import com.google.android.gms.cast.TextTrackStyle | import com.google.android.gms.cast.TextTrackStyle | ||||||
| import com.google.android.gms.cast.TextTrackStyle.EDGE_TYPE_OUTLINE |  | ||||||
| import com.google.android.gms.cast.framework.CastButtonFactory | import com.google.android.gms.cast.framework.CastButtonFactory | ||||||
| import com.google.android.gms.cast.framework.CastSession | import com.google.android.gms.cast.framework.CastSession | ||||||
| import com.google.android.gms.cast.framework.media.RemoteMediaClient | import com.google.android.gms.cast.framework.media.RemoteMediaClient | ||||||
|  | @ -29,6 +27,7 @@ import com.lagradost.cloudstream3.sortUrls | ||||||
| import com.lagradost.cloudstream3.ui.player.RepoLinkGenerator | import com.lagradost.cloudstream3.ui.player.RepoLinkGenerator | ||||||
| import com.lagradost.cloudstream3.ui.player.SubtitleData | import com.lagradost.cloudstream3.ui.player.SubtitleData | ||||||
| import com.lagradost.cloudstream3.ui.result.ResultEpisode | import com.lagradost.cloudstream3.ui.result.ResultEpisode | ||||||
|  | import com.lagradost.cloudstream3.ui.subtitles.ChromecastSubtitlesFragment | ||||||
| import com.lagradost.cloudstream3.utils.AppUtils.toJson | import com.lagradost.cloudstream3.utils.AppUtils.toJson | ||||||
| import com.lagradost.cloudstream3.utils.CastHelper.awaitLinks | import com.lagradost.cloudstream3.utils.CastHelper.awaitLinks | ||||||
| import com.lagradost.cloudstream3.utils.CastHelper.getMediaInfo | import com.lagradost.cloudstream3.utils.CastHelper.getMediaInfo | ||||||
|  | @ -146,16 +145,22 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi | ||||||
|                             if (which == 0) { |                             if (which == 0) { | ||||||
|                                 remoteMediaClient?.setActiveMediaTracks(longArrayOf()) // NO SUBS |                                 remoteMediaClient?.setActiveMediaTracks(longArrayOf()) // NO SUBS | ||||||
|                             } else { |                             } else { | ||||||
|  |                                 ChromecastSubtitlesFragment.getCurrentSavedStyle().apply { | ||||||
|                                     val font = TextTrackStyle() |                                     val font = TextTrackStyle() | ||||||
|                                 font.fontFamily = "Google Sans" //TODO FONT SETTINGS |                                     font.fontFamily = fontFamily ?: "Google Sans" | ||||||
|                                 font.backgroundColor = 0x00FFFFFF // TRANSPARENT |                                     fontGenericFamily?.let { | ||||||
|  |                                         font.fontGenericFamily = it | ||||||
|  |                                     } | ||||||
|  |                                     font.windowColor = windowColor | ||||||
|  |                                     font.backgroundColor = backgroundColor | ||||||
| 
 | 
 | ||||||
|                                 font.edgeColor = Color.BLACK |                                     font.edgeColor = edgeColor | ||||||
|                                 font.edgeType = EDGE_TYPE_OUTLINE |                                     font.edgeType = edgeType | ||||||
|                                 font.foregroundColor = Color.WHITE |                                     font.foregroundColor = foregroundColor | ||||||
|                                 font.fontScale = 1.05f |                                     font.fontScale = fontScale | ||||||
| 
 | 
 | ||||||
|                                     remoteMediaClient?.setTextTrackStyle(font) |                                     remoteMediaClient?.setTextTrackStyle(font) | ||||||
|  |                                 } | ||||||
| 
 | 
 | ||||||
|                                 remoteMediaClient?.setActiveMediaTracks(longArrayOf(subTracks[which - 1].id)) |                                 remoteMediaClient?.setActiveMediaTracks(longArrayOf(subTracks[which - 1].id)) | ||||||
|                                     ?.setResultCallback { |                                     ?.setResultCallback { | ||||||
|  |  | ||||||
|  | @ -37,6 +37,7 @@ import com.lagradost.cloudstream3.syncproviders.OAuth2API | ||||||
| import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.aniListApi | import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.aniListApi | ||||||
| import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.malApi | import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.malApi | ||||||
| import com.lagradost.cloudstream3.ui.APIRepository | import com.lagradost.cloudstream3.ui.APIRepository | ||||||
|  | import com.lagradost.cloudstream3.ui.subtitles.ChromecastSubtitlesFragment | ||||||
| import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment | import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment | ||||||
| import com.lagradost.cloudstream3.utils.HOMEPAGE_API | import com.lagradost.cloudstream3.utils.HOMEPAGE_API | ||||||
| import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate | import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate | ||||||
|  | @ -199,6 +200,7 @@ class SettingsFragment : PreferenceFragmentCompat() { | ||||||
|         val subPreference = findPreference<Preference>(getString(R.string.subtitle_settings_key))!! |         val subPreference = findPreference<Preference>(getString(R.string.subtitle_settings_key))!! | ||||||
|         val videoCachePreference = findPreference<Preference>(getString(R.string.video_cache_key))!! |         val videoCachePreference = findPreference<Preference>(getString(R.string.video_cache_key))!! | ||||||
|         val settingsManager = PreferenceManager.getDefaultSharedPreferences(requireContext()) |         val settingsManager = PreferenceManager.getDefaultSharedPreferences(requireContext()) | ||||||
|  |         val chromecastSubsPreference = findPreference<Preference>(getString(R.string.subtitle_settings_chomecast_key))!! | ||||||
| 
 | 
 | ||||||
|         videoCachePreference.setOnPreferenceClickListener { |         videoCachePreference.setOnPreferenceClickListener { | ||||||
|             val prefNames = resources.getStringArray(R.array.video_cache_size_names) |             val prefNames = resources.getStringArray(R.array.video_cache_size_names) | ||||||
|  | @ -225,6 +227,11 @@ class SettingsFragment : PreferenceFragmentCompat() { | ||||||
|             return@setOnPreferenceClickListener true |             return@setOnPreferenceClickListener true | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         chromecastSubsPreference.setOnPreferenceClickListener { | ||||||
|  |             ChromecastSubtitlesFragment.push(activity, false) | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         val syncApis = listOf(Pair(R.string.mal_key, malApi), Pair(R.string.anilist_key, aniListApi)) |         val syncApis = listOf(Pair(R.string.mal_key, malApi), Pair(R.string.anilist_key, aniListApi)) | ||||||
|         for (sync in syncApis) { |         for (sync in syncApis) { | ||||||
|             findPreference<Preference>(getString(sync.first))?.apply { |             findPreference<Preference>(getString(sync.first))?.apply { | ||||||
|  |  | ||||||
|  | @ -0,0 +1,344 @@ | ||||||
|  | package com.lagradost.cloudstream3.ui.subtitles | ||||||
|  | 
 | ||||||
|  | import android.app.Activity | ||||||
|  | import android.content.Context | ||||||
|  | import android.content.res.Resources | ||||||
|  | import android.graphics.Color | ||||||
|  | import android.os.Bundle | ||||||
|  | import android.util.DisplayMetrics | ||||||
|  | import android.util.TypedValue | ||||||
|  | import android.view.LayoutInflater | ||||||
|  | import android.view.View | ||||||
|  | import android.view.ViewGroup | ||||||
|  | import android.widget.TextView | ||||||
|  | import android.widget.Toast | ||||||
|  | import androidx.fragment.app.Fragment | ||||||
|  | import com.fasterxml.jackson.annotation.JsonProperty | ||||||
|  | import com.google.android.exoplayer2.text.Cue | ||||||
|  | import com.google.android.gms.cast.TextTrackStyle | ||||||
|  | import com.google.android.gms.cast.TextTrackStyle.* | ||||||
|  | import com.jaredrummler.android.colorpicker.ColorPickerDialog | ||||||
|  | import com.lagradost.cloudstream3.AcraApplication.Companion.getKey | ||||||
|  | import com.lagradost.cloudstream3.CommonActivity.onColorSelectedEvent | ||||||
|  | import com.lagradost.cloudstream3.CommonActivity.onDialogDismissedEvent | ||||||
|  | import com.lagradost.cloudstream3.CommonActivity.showToast | ||||||
|  | import com.lagradost.cloudstream3.R | ||||||
|  | import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings | ||||||
|  | import com.lagradost.cloudstream3.utils.DataStore.setKey | ||||||
|  | import com.lagradost.cloudstream3.utils.Event | ||||||
|  | import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog | ||||||
|  | import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar | ||||||
|  | import com.lagradost.cloudstream3.utils.UIHelper.hideSystemUI | ||||||
|  | import com.lagradost.cloudstream3.utils.UIHelper.navigate | ||||||
|  | import com.lagradost.cloudstream3.utils.UIHelper.popCurrentPage | ||||||
|  | import kotlinx.android.synthetic.main.subtitle_settings.* | ||||||
|  | 
 | ||||||
|  | const val CHROME_SUBTITLE_KEY = "chome_subtitle_settings" | ||||||
|  | 
 | ||||||
|  | data class SaveChromeCaptionStyle( | ||||||
|  |     @JsonProperty("fontFamily") var fontFamily: String? = null, | ||||||
|  |     @JsonProperty("fontGenericFamily") var fontGenericFamily: Int? = null, | ||||||
|  |     @JsonProperty("backgroundColor") var backgroundColor: Int = Color.TRANSPARENT, // transparent, 0x00FFFFFF | ||||||
|  |     @JsonProperty("edgeColor") var edgeColor: Int = Color.BLACK, // BLACK | ||||||
|  |     @JsonProperty("edgeType") var edgeType: Int = TextTrackStyle.EDGE_TYPE_OUTLINE, | ||||||
|  |     @JsonProperty("foregroundColor") var foregroundColor: Int = Color.WHITE, | ||||||
|  |     @JsonProperty("fontScale") var fontScale: Float = 1.05f, | ||||||
|  |     @JsonProperty("windowColor") var windowColor: Int = Color.TRANSPARENT, | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | class ChromecastSubtitlesFragment : Fragment() { | ||||||
|  |     companion object { | ||||||
|  |         val applyStyleEvent = Event<SaveChromeCaptionStyle>() | ||||||
|  | 
 | ||||||
|  |         //fun Context.fromSaveToStyle(data: SaveChromeCaptionStyle): CaptionStyleCompat { | ||||||
|  |         //    return CaptionStyleCompat( | ||||||
|  |         //        data.foregroundColor, | ||||||
|  |         //        data.backgroundColor, | ||||||
|  |         //        data.windowColor, | ||||||
|  |         //        data.edgeType, | ||||||
|  |         //        data.edgeColor, | ||||||
|  |         //        if (typeface == null) Typeface.SANS_SERIF else ResourcesCompat.getFont( | ||||||
|  |         //            this, | ||||||
|  |         //            typeface | ||||||
|  |         //        ) | ||||||
|  |         //    ) | ||||||
|  |         //} | ||||||
|  | 
 | ||||||
|  |         fun push(activity: Activity?, hide: Boolean = true) { | ||||||
|  |             activity.navigate(R.id.global_to_navigation_chrome_subtitles, Bundle().apply { | ||||||
|  |                 putBoolean("hide", hide) | ||||||
|  |             }) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private fun getDefColor(id: Int): Int { | ||||||
|  |             return when (id) { | ||||||
|  |                 0 -> Color.WHITE | ||||||
|  |                 1 -> Color.BLACK | ||||||
|  |                 2 -> Color.TRANSPARENT | ||||||
|  |                 3 -> Color.TRANSPARENT | ||||||
|  |                 else -> Color.TRANSPARENT | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         fun Context.saveStyle(style: SaveChromeCaptionStyle) { | ||||||
|  |             this.setKey(CHROME_SUBTITLE_KEY, style) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private fun getPixels(unit: Int, size: Float): Int { | ||||||
|  |             val metrics: DisplayMetrics = Resources.getSystem().displayMetrics | ||||||
|  |             return TypedValue.applyDimension(unit, size, metrics).toInt() | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         fun getCurrentSavedStyle(): SaveChromeCaptionStyle { | ||||||
|  |             return getKey(CHROME_SUBTITLE_KEY) ?: defaultState | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private val defaultState = SaveChromeCaptionStyle() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun onColorSelected(stuff: Pair<Int, Int>) { | ||||||
|  |         context?.setColor(stuff.first, stuff.second) | ||||||
|  |         if (hide) | ||||||
|  |             activity?.hideSystemUI() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun onDialogDismissed(id: Int) { | ||||||
|  |         if (hide) | ||||||
|  |             activity?.hideSystemUI() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun getColor(id: Int): Int { | ||||||
|  |         val color = when (id) { | ||||||
|  |             0 -> state.foregroundColor | ||||||
|  |             1 -> state.edgeColor | ||||||
|  |             2 -> state.backgroundColor | ||||||
|  |             3 -> state.windowColor | ||||||
|  | 
 | ||||||
|  |             else -> Color.TRANSPARENT | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return if (color == Color.TRANSPARENT) Color.BLACK else color | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun Context.setColor(id: Int, color: Int?) { | ||||||
|  |         val realColor = color ?: getDefColor(id) | ||||||
|  |         when (id) { | ||||||
|  |             0 -> state.foregroundColor = realColor | ||||||
|  |             1 -> state.edgeColor = realColor | ||||||
|  |             2 -> state.backgroundColor = realColor | ||||||
|  |             3 -> state.windowColor = realColor | ||||||
|  | 
 | ||||||
|  |             else -> Unit | ||||||
|  |         } | ||||||
|  |         updateState() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun Context.updateState() { | ||||||
|  |         //subtitle_text?.setStyle(fromSaveToStyle(state)) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun onCreateView( | ||||||
|  |         inflater: LayoutInflater, | ||||||
|  |         container: ViewGroup?, | ||||||
|  |         savedInstanceState: Bundle?, | ||||||
|  |     ): View? { | ||||||
|  |         return inflater.inflate(R.layout.chromecast_subtitle_settings, container, false) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private lateinit var state: SaveChromeCaptionStyle | ||||||
|  |     private var hide: Boolean = true | ||||||
|  | 
 | ||||||
|  |     override fun onDestroy() { | ||||||
|  |         super.onDestroy() | ||||||
|  |         onColorSelectedEvent -= ::onColorSelected | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||||
|  |         super.onViewCreated(view, savedInstanceState) | ||||||
|  |         hide = arguments?.getBoolean("hide") ?: true | ||||||
|  |         onColorSelectedEvent += ::onColorSelected | ||||||
|  |         onDialogDismissedEvent += ::onDialogDismissed | ||||||
|  | 
 | ||||||
|  |         context?.fixPaddingStatusbar(subs_root) | ||||||
|  | 
 | ||||||
|  |         state = getCurrentSavedStyle() | ||||||
|  |         context?.updateState() | ||||||
|  | 
 | ||||||
|  |         val isTvSettings = context?.isTvSettings() == true | ||||||
|  | 
 | ||||||
|  |         fun View.setFocusableInTv() { | ||||||
|  |             this.isFocusableInTouchMode = isTvSettings | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         fun View.setup(id: Int) { | ||||||
|  |             setFocusableInTv() | ||||||
|  | 
 | ||||||
|  |             this.setOnClickListener { | ||||||
|  |                 activity?.let { | ||||||
|  |                     ColorPickerDialog.newBuilder() | ||||||
|  |                         .setDialogId(id) | ||||||
|  |                         .setShowAlphaSlider(true) | ||||||
|  |                         .setColor(getColor(id)) | ||||||
|  |                         .show(it) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             this.setOnLongClickListener { | ||||||
|  |                 it.context.setColor(id, null) | ||||||
|  |                 showToast(activity, R.string.subs_default_reset_toast, Toast.LENGTH_SHORT) | ||||||
|  |                 return@setOnLongClickListener true | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         subs_text_color.setup(0) | ||||||
|  |         subs_outline_color.setup(1) | ||||||
|  |         subs_background_color.setup(2) | ||||||
|  | 
 | ||||||
|  |         val dismissCallback = { | ||||||
|  |             if (hide) | ||||||
|  |                 activity?.hideSystemUI() | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         subs_edge_type.setFocusableInTv() | ||||||
|  |         subs_edge_type.setOnClickListener { textView -> | ||||||
|  |             val edgeTypes = listOf( | ||||||
|  |                 Pair( | ||||||
|  |                     EDGE_TYPE_NONE, | ||||||
|  |                     textView.context.getString(R.string.subtitles_none) | ||||||
|  |                 ), | ||||||
|  |                 Pair( | ||||||
|  |                     EDGE_TYPE_OUTLINE, | ||||||
|  |                     textView.context.getString(R.string.subtitles_outline) | ||||||
|  |                 ), | ||||||
|  |                 Pair( | ||||||
|  |                     EDGE_TYPE_DEPRESSED, | ||||||
|  |                     textView.context.getString(R.string.subtitles_depressed) | ||||||
|  |                 ), | ||||||
|  |                 Pair( | ||||||
|  |                     EDGE_TYPE_DROP_SHADOW, | ||||||
|  |                     textView.context.getString(R.string.subtitles_shadow) | ||||||
|  |                 ), | ||||||
|  |                 Pair( | ||||||
|  |                     EDGE_TYPE_RAISED, | ||||||
|  |                     textView.context.getString(R.string.subtitles_raised) | ||||||
|  |                 ), | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |             //showBottomDialog | ||||||
|  |             activity?.showDialog( | ||||||
|  |                 edgeTypes.map { it.second }, | ||||||
|  |                 edgeTypes.map { it.first }.indexOf(state.edgeType), | ||||||
|  |                 (textView as TextView).text.toString(), | ||||||
|  |                 false, | ||||||
|  |                 dismissCallback | ||||||
|  |             ) { index -> | ||||||
|  |                 state.edgeType = edgeTypes.map { it.first }[index] | ||||||
|  |                 textView.context.updateState() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         subs_edge_type.setOnLongClickListener { | ||||||
|  |             state.edgeType = defaultState.edgeType | ||||||
|  |             it.context.updateState() | ||||||
|  |             showToast(activity, R.string.subs_default_reset_toast, Toast.LENGTH_SHORT) | ||||||
|  |             return@setOnLongClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         subs_font_size.setFocusableInTv() | ||||||
|  |         subs_font_size.setOnClickListener { textView -> | ||||||
|  |             val fontSizes = listOf( | ||||||
|  |                 Pair(0.75f, "75%"), | ||||||
|  |                 Pair(0.80f, "80%"), | ||||||
|  |                 Pair(0.85f, "85%"), | ||||||
|  |                 Pair(0.90f, "90%"), | ||||||
|  |                 Pair(0.95f, "95%"), | ||||||
|  |                 Pair(1.00f, "100%"), | ||||||
|  |                 Pair(1.05f, textView.context.getString(R.string.normal)), | ||||||
|  |                 Pair(1.10f, "110%"), | ||||||
|  |                 Pair(1.15f, "115%"), | ||||||
|  |                 Pair(1.20f, "120%"), | ||||||
|  |                 Pair(1.25f, "125%"), | ||||||
|  |                 Pair(1.30f, "130%"), | ||||||
|  |                 Pair(1.35f, "135%"), | ||||||
|  |                 Pair(1.40f, "140%"), | ||||||
|  |                 Pair(1.45f, "145%"), | ||||||
|  |                 Pair(1.50f, "150%"), | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |             //showBottomDialog | ||||||
|  |             activity?.showDialog( | ||||||
|  |                 fontSizes.map { it.second }, | ||||||
|  |                 fontSizes.map { it.first }.indexOf(state.fontScale), | ||||||
|  |                 (textView as TextView).text.toString(), | ||||||
|  |                 false, | ||||||
|  |                 dismissCallback | ||||||
|  |             ) { index -> | ||||||
|  |                 state.fontScale = fontSizes.map { it.first }[index] | ||||||
|  |                 //textView.context.updateState() // font size not changed | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         subs_font_size.setOnLongClickListener { _ -> | ||||||
|  |             state.fontScale = defaultState.fontScale | ||||||
|  |             //textView.context.updateState() // font size not changed | ||||||
|  |             showToast(activity, R.string.subs_default_reset_toast, Toast.LENGTH_SHORT) | ||||||
|  |             return@setOnLongClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         subs_font.setFocusableInTv() | ||||||
|  |         subs_font.setOnClickListener { textView -> | ||||||
|  |             val fontTypes = listOf( | ||||||
|  |                 Pair(null, textView.context.getString(R.string.normal)), | ||||||
|  |                 Pair("Droid Sans", "Droid Sans"), | ||||||
|  |                 Pair("Droid Sans Mono", "Droid Sans Mono"), | ||||||
|  |                 Pair("Droid Serif Regular", "Droid Serif Regular"), | ||||||
|  |                 Pair("Cutive Mono", "Cutive Mono"), | ||||||
|  |                 Pair("Short Stack", "Short Stack"), | ||||||
|  |                 Pair("Quintessential", "Quintessential"), | ||||||
|  |                 Pair("Alegreya Sans SC", "Alegreya Sans SC"), | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |             //showBottomDialog | ||||||
|  |             activity?.showDialog( | ||||||
|  |                 fontTypes.map { it.second }, | ||||||
|  |                 fontTypes.map { it.first }.indexOf(state.fontFamily), | ||||||
|  |                 (textView as TextView).text.toString(), | ||||||
|  |                 false, | ||||||
|  |                 dismissCallback | ||||||
|  |             ) { index -> | ||||||
|  |                 state.fontFamily = fontTypes.map { it.first }[index] | ||||||
|  |                 textView.context.updateState() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         subs_font.setOnLongClickListener { textView -> | ||||||
|  |             state.fontFamily = defaultState.fontFamily | ||||||
|  |             textView.context.updateState() | ||||||
|  |             showToast(activity, R.string.subs_default_reset_toast, Toast.LENGTH_SHORT) | ||||||
|  |             return@setOnLongClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         cancel_btt.setOnClickListener { | ||||||
|  |             activity?.popCurrentPage() | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         apply_btt.setOnClickListener { | ||||||
|  |             it.context.saveStyle(state) | ||||||
|  |             applyStyleEvent.invoke(state) | ||||||
|  |             //it.context.fromSaveToStyle(state) | ||||||
|  |             activity?.popCurrentPage() | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         subtitle_text.setCues( | ||||||
|  |             listOf( | ||||||
|  |                 Cue.Builder() | ||||||
|  |                     .setTextSize( | ||||||
|  |                         getPixels(TypedValue.COMPLEX_UNIT_SP, 25.0f).toFloat(), | ||||||
|  |                         Cue.TEXT_SIZE_TYPE_ABSOLUTE | ||||||
|  |                     ) | ||||||
|  |                     .setText(subtitle_text.context.getString(R.string.subtitles_example_text)) | ||||||
|  |                     .build() | ||||||
|  |             ) | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -16,6 +16,7 @@ import android.widget.Toast | ||||||
| import androidx.annotation.FontRes | import androidx.annotation.FontRes | ||||||
| import androidx.core.content.res.ResourcesCompat | import androidx.core.content.res.ResourcesCompat | ||||||
| import androidx.fragment.app.Fragment | import androidx.fragment.app.Fragment | ||||||
|  | import com.fasterxml.jackson.annotation.JsonProperty | ||||||
| import com.google.android.exoplayer2.text.Cue | import com.google.android.exoplayer2.text.Cue | ||||||
| import com.google.android.exoplayer2.ui.CaptionStyleCompat | import com.google.android.exoplayer2.ui.CaptionStyleCompat | ||||||
| import com.jaredrummler.android.colorpicker.ColorPickerDialog | import com.jaredrummler.android.colorpicker.ColorPickerDialog | ||||||
|  | @ -42,18 +43,18 @@ const val SUBTITLE_AUTO_SELECT_KEY = "subs_auto_select" | ||||||
| const val SUBTITLE_DOWNLOAD_KEY = "subs_auto_download" | const val SUBTITLE_DOWNLOAD_KEY = "subs_auto_download" | ||||||
| 
 | 
 | ||||||
| data class SaveCaptionStyle( | data class SaveCaptionStyle( | ||||||
|     var foregroundColor: Int, |     @JsonProperty("foregroundColor") var foregroundColor: Int, | ||||||
|     var backgroundColor: Int, |     @JsonProperty("backgroundColor") var backgroundColor: Int, | ||||||
|     var windowColor: Int, |     @JsonProperty("windowColor") var windowColor: Int, | ||||||
|     @CaptionStyleCompat.EdgeType |     @CaptionStyleCompat.EdgeType | ||||||
|     var edgeType: Int, |     @JsonProperty("edgeType") var edgeType: Int, | ||||||
|     var edgeColor: Int, |     @JsonProperty("edgeColor")  var edgeColor: Int, | ||||||
|     @FontRes |     @FontRes | ||||||
|     var typeface: Int?, |     @JsonProperty("typeface") var typeface: Int?, | ||||||
|     /**in dp**/ |     /**in dp**/ | ||||||
|     var elevation: Int, |     @JsonProperty("elevation") var elevation: Int, | ||||||
|     /**in sp**/ |     /**in sp**/ | ||||||
|     var fixedTextSize: Float?, |     @JsonProperty("fixedTextSize") var fixedTextSize: Float?, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const val DEF_SUBS_ELEVATION = 20 | const val DEF_SUBS_ELEVATION = 20 | ||||||
|  |  | ||||||
|  | @ -1,9 +1,6 @@ | ||||||
| package com.lagradost.cloudstream3.utils | package com.lagradost.cloudstream3.utils | ||||||
| 
 | 
 | ||||||
| import android.net.Uri | import android.net.Uri | ||||||
| import com.fasterxml.jackson.databind.DeserializationFeature |  | ||||||
| import com.fasterxml.jackson.databind.json.JsonMapper |  | ||||||
| import com.fasterxml.jackson.module.kotlin.KotlinModule |  | ||||||
| import com.google.android.exoplayer2.util.MimeTypes | import com.google.android.exoplayer2.util.MimeTypes | ||||||
| import com.google.android.gms.cast.* | import com.google.android.gms.cast.* | ||||||
| import com.google.android.gms.cast.framework.CastSession | import com.google.android.gms.cast.framework.CastSession | ||||||
|  | @ -20,9 +17,6 @@ import kotlinx.coroutines.withContext | ||||||
| import org.json.JSONObject | import org.json.JSONObject | ||||||
| 
 | 
 | ||||||
| object CastHelper { | object CastHelper { | ||||||
|     private val mapper: JsonMapper = JsonMapper.builder().addModule(KotlinModule()) |  | ||||||
|         .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build() |  | ||||||
| 
 |  | ||||||
|     fun getMediaInfo( |     fun getMediaInfo( | ||||||
|         epData: ResultEpisode, |         epData: ResultEpisode, | ||||||
|         holder: MetadataHolder, |         holder: MetadataHolder, | ||||||
|  |  | ||||||
							
								
								
									
										157
									
								
								app/src/main/res/layout/chromecast_subtitle_settings.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								app/src/main/res/layout/chromecast_subtitle_settings.xml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,157 @@ | ||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |         android:layout_width="match_parent" | ||||||
|  |         android:layout_height="match_parent" | ||||||
|  |         android:id="@+id/subs_root" | ||||||
|  |         android:background="?attr/primaryBlackBackground"> | ||||||
|  | 
 | ||||||
|  |     <LinearLayout | ||||||
|  |             android:orientation="vertical" | ||||||
|  |             android:layout_width="match_parent" | ||||||
|  |             android:layout_height="wrap_content"> | ||||||
|  | 
 | ||||||
|  |         <TextView | ||||||
|  |                 android:paddingStart="20dp" | ||||||
|  |                 android:paddingEnd="20dp" | ||||||
|  |                 android:layout_marginTop="20dp" | ||||||
|  |                 android:layout_marginBottom="10dp" | ||||||
|  |                 android:textStyle="bold" | ||||||
|  |                 android:text="@string/chomecast_subtitles_settings" | ||||||
|  |                 android:textSize="20sp" | ||||||
|  |                 android:textColor="?attr/textColor" | ||||||
|  |                 android:layout_width="match_parent" | ||||||
|  |                 android:layout_rowWeight="1" | ||||||
|  |                 android:layout_height="wrap_content" /> | ||||||
|  | 
 | ||||||
|  |         <FrameLayout | ||||||
|  |                 android:visibility="gone" | ||||||
|  |                 android:layout_width="match_parent" | ||||||
|  |                 android:layout_height="75sp"> | ||||||
|  | 
 | ||||||
|  |             <ImageView | ||||||
|  |                     android:scaleType="centerCrop" | ||||||
|  |                     android:src="@drawable/subtitles_preview_background" | ||||||
|  |                     android:layout_width="match_parent" | ||||||
|  |                     android:layout_height="match_parent" | ||||||
|  |                     android:contentDescription="@string/preview_background_img_des" /> | ||||||
|  | 
 | ||||||
|  |             <com.google.android.exoplayer2.ui.SubtitleView | ||||||
|  |                     android:id="@+id/subtitle_text" | ||||||
|  | 
 | ||||||
|  |                     android:layout_width="match_parent" | ||||||
|  |                     android:layout_gravity="center" | ||||||
|  |                     android:foregroundGravity="center" | ||||||
|  |                     android:layout_height="match_parent" /> | ||||||
|  |         </FrameLayout> | ||||||
|  | 
 | ||||||
|  |         <TextView | ||||||
|  |                 android:nextFocusDown="@id/subs_font_size" | ||||||
|  |                 android:nextFocusLeft="@id/apply_btt" | ||||||
|  |                 android:nextFocusRight="@id/cancel_btt" | ||||||
|  | 
 | ||||||
|  |                 android:id="@+id/subs_font" | ||||||
|  |                 android:text="@string/subs_font" | ||||||
|  |                 style="@style/SettingsItem" /> | ||||||
|  | 
 | ||||||
|  |         <TextView | ||||||
|  |                 android:nextFocusUp="@id/subs_font" | ||||||
|  |                 android:nextFocusDown="@id/subs_text_color" | ||||||
|  |                 android:nextFocusLeft="@id/apply_btt" | ||||||
|  |                 android:nextFocusRight="@id/cancel_btt" | ||||||
|  | 
 | ||||||
|  |                 android:id="@+id/subs_font_size" | ||||||
|  |                 android:text="@string/subs_font_size" | ||||||
|  |                 style="@style/SettingsItem" /> | ||||||
|  | 
 | ||||||
|  |         <TextView | ||||||
|  |                 android:nextFocusUp="@id/subs_font_size" | ||||||
|  |                 android:nextFocusDown="@id/subs_outline_color" | ||||||
|  |                 android:nextFocusLeft="@id/apply_btt" | ||||||
|  |                 android:nextFocusRight="@id/cancel_btt" | ||||||
|  | 
 | ||||||
|  |                 android:id="@+id/subs_text_color" | ||||||
|  |                 android:text="@string/subs_text_color" | ||||||
|  |                 style="@style/SettingsItem" /> | ||||||
|  | 
 | ||||||
|  |         <TextView | ||||||
|  |                 android:nextFocusUp="@id/subs_text_color" | ||||||
|  |                 android:nextFocusDown="@id/subs_background_color" | ||||||
|  |                 android:nextFocusLeft="@id/apply_btt" | ||||||
|  |                 android:nextFocusRight="@id/cancel_btt" | ||||||
|  | 
 | ||||||
|  |                 android:id="@+id/subs_outline_color" | ||||||
|  |                 android:text="@string/subs_outline_color" | ||||||
|  |                 style="@style/SettingsItem" /> | ||||||
|  | 
 | ||||||
|  |         <TextView | ||||||
|  |                 android:nextFocusUp="@id/subs_outline_color" | ||||||
|  |                 android:nextFocusDown="@id/subs_window_color" | ||||||
|  |                 android:nextFocusLeft="@id/apply_btt" | ||||||
|  |                 android:nextFocusRight="@id/cancel_btt" | ||||||
|  | 
 | ||||||
|  |                 android:id="@+id/subs_background_color" | ||||||
|  |                 android:text="@string/subs_background_color" | ||||||
|  |                 style="@style/SettingsItem" /> | ||||||
|  | 
 | ||||||
|  |         <TextView | ||||||
|  |                 android:visibility="gone" | ||||||
|  |                 android:nextFocusUp="@id/subs_background_color" | ||||||
|  |                 android:nextFocusDown="@id/subs_edge_type" | ||||||
|  |                 android:nextFocusLeft="@id/apply_btt" | ||||||
|  |                 android:nextFocusRight="@id/cancel_btt" | ||||||
|  | 
 | ||||||
|  |                 android:id="@+id/subs_window_color" | ||||||
|  |                 android:text="@string/subs_window_color" | ||||||
|  |                 style="@style/SettingsItem" /> | ||||||
|  | 
 | ||||||
|  |         <TextView | ||||||
|  |                 android:nextFocusUp="@id/subs_window_color" | ||||||
|  |                 android:nextFocusDown="@id/apply_btt" | ||||||
|  |                 android:nextFocusLeft="@id/apply_btt" | ||||||
|  |                 android:nextFocusRight="@id/cancel_btt" | ||||||
|  | 
 | ||||||
|  |                 android:id="@+id/subs_edge_type" | ||||||
|  |                 android:text="@string/subs_edge_type" | ||||||
|  |                 style="@style/SettingsItem" /> | ||||||
|  | 
 | ||||||
|  |         <TextView | ||||||
|  |                 android:gravity="center" | ||||||
|  |                 android:text="@string/subs_hold_to_reset_to_default" | ||||||
|  |                 android:textSize="14sp" | ||||||
|  | 
 | ||||||
|  |                 android:textColor="?attr/textColor" | ||||||
|  |                 android:layout_width="match_parent" | ||||||
|  |                 android:layout_rowWeight="1" | ||||||
|  |                 android:layout_height="wrap_content" /> | ||||||
|  | 
 | ||||||
|  |         <LinearLayout | ||||||
|  |                 android:orientation="horizontal" | ||||||
|  |                 android:layout_gravity="bottom" | ||||||
|  |                 android:gravity="bottom|end" | ||||||
|  |                 android:layout_width="match_parent" | ||||||
|  |                 android:layout_height="60dp"> | ||||||
|  | 
 | ||||||
|  |             <com.google.android.material.button.MaterialButton | ||||||
|  |                     android:nextFocusUp="@id/subs_edge_type" | ||||||
|  |                     android:nextFocusRight="@id/cancel_btt" | ||||||
|  |                     style="@style/WhiteButton" | ||||||
|  |                     android:layout_gravity="center_vertical|end" | ||||||
|  |                     android:visibility="visible" | ||||||
|  |                     android:text="@string/sort_apply" | ||||||
|  |                     android:id="@+id/apply_btt" | ||||||
|  |                     android:layout_width="wrap_content"> | ||||||
|  | 
 | ||||||
|  |                 <requestFocus /> | ||||||
|  |             </com.google.android.material.button.MaterialButton> | ||||||
|  | 
 | ||||||
|  |             <com.google.android.material.button.MaterialButton | ||||||
|  |                     android:nextFocusUp="@id/subs_edge_type" | ||||||
|  |                     android:nextFocusLeft="@id/apply_btt" | ||||||
|  |                     style="@style/BlackButton" | ||||||
|  |                     android:layout_gravity="center_vertical|end" | ||||||
|  |                     android:text="@string/sort_cancel" | ||||||
|  |                     android:id="@+id/cancel_btt" | ||||||
|  |                     android:layout_width="wrap_content" /> | ||||||
|  |         </LinearLayout> | ||||||
|  |     </LinearLayout> | ||||||
|  | </ScrollView> | ||||||
|  | @ -81,6 +81,19 @@ | ||||||
|         /> |         /> | ||||||
|     </action> |     </action> | ||||||
| 
 | 
 | ||||||
|  |     <action android:id="@+id/global_to_navigation_chrome_subtitles" | ||||||
|  |             app:destination="@id/navigation_chrome_subtitles" | ||||||
|  |             app:enterAnim="@anim/enter_anim" | ||||||
|  |             app:exitAnim="@anim/exit_anim" | ||||||
|  |             app:popEnterAnim="@anim/enter_anim" | ||||||
|  |             app:popExitAnim="@anim/exit_anim"> | ||||||
|  |         <argument | ||||||
|  |                 android:name="hide" | ||||||
|  |                 app:argType="boolean" | ||||||
|  |                 android:defaultValue="true" | ||||||
|  |                 /> | ||||||
|  |     </action> | ||||||
|  | 
 | ||||||
|     <action android:id="@+id/global_to_navigation_quick_search" |     <action android:id="@+id/global_to_navigation_quick_search" | ||||||
|             app:destination="@id/navigation_quick_search" |             app:destination="@id/navigation_quick_search" | ||||||
|             app:enterAnim="@anim/enter_anim" |             app:enterAnim="@anim/enter_anim" | ||||||
|  | @ -168,6 +181,12 @@ | ||||||
|             android:name="com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment" |             android:name="com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment" | ||||||
|             android:label="@string/subtitles_settings"/> |             android:label="@string/subtitles_settings"/> | ||||||
| 
 | 
 | ||||||
|  |     <fragment | ||||||
|  |             android:id="@+id/navigation_chrome_subtitles" | ||||||
|  |             android:layout_height="match_parent" | ||||||
|  |             android:name="com.lagradost.cloudstream3.ui.subtitles.ChromecastSubtitlesFragment" | ||||||
|  |             android:label="@string/chomecast_subtitles_settings"/> | ||||||
|  | 
 | ||||||
|     <fragment |     <fragment | ||||||
|             android:id="@+id/navigation_quick_search" |             android:id="@+id/navigation_quick_search" | ||||||
|             android:layout_height="match_parent" |             android:layout_height="match_parent" | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ | ||||||
|     <string name="fast_forward_button_time_key" translatable="false">fast_forward_button_time</string> |     <string name="fast_forward_button_time_key" translatable="false">fast_forward_button_time</string> | ||||||
|     <string name="benene_count" translatable="false">benene_count</string> |     <string name="benene_count" translatable="false">benene_count</string> | ||||||
|     <string name="subtitle_settings_key" translatable="false">subtitle_settings_key</string> |     <string name="subtitle_settings_key" translatable="false">subtitle_settings_key</string> | ||||||
|  |     <string name="subtitle_settings_chomecast_key" translatable="false">subtitle_settings_chomecast_key</string> | ||||||
|     <string name="quality_pref_key" translatable="false">quality_pref_key</string> |     <string name="quality_pref_key" translatable="false">quality_pref_key</string> | ||||||
|     <string name="video_cache_key" translatable="false">video_cache_key</string> |     <string name="video_cache_key" translatable="false">video_cache_key</string> | ||||||
|     <string name="prerelease_commit_hash" translatable="false">unknown_prerelease</string> |     <string name="prerelease_commit_hash" translatable="false">unknown_prerelease</string> | ||||||
|  | @ -175,6 +176,9 @@ | ||||||
|     <string name="player_size_settings_des">Remove the black borders</string> |     <string name="player_size_settings_des">Remove the black borders</string> | ||||||
|     <string name="player_subtitles_settings">Subtitles</string> |     <string name="player_subtitles_settings">Subtitles</string> | ||||||
|     <string name="player_subtitles_settings_des">Player subtitles settings</string> |     <string name="player_subtitles_settings_des">Player subtitles settings</string> | ||||||
|  |     <string name="chomecast_subtitles_settings">Chomecast Subtitles</string> | ||||||
|  |     <string name="chomecast_subtitles_settings_des">Chromecast subtitles settings</string> | ||||||
|  | 
 | ||||||
|     <string name="eigengraumode_settings">Eigengravy Mode</string> |     <string name="eigengraumode_settings">Eigengravy Mode</string> | ||||||
|     <string name="eigengraumode_settings_des">Adds a speed option in the player</string> |     <string name="eigengraumode_settings_des">Adds a speed option in the player</string> | ||||||
|     <string name="swipe_to_seek_settings">Swipe to seek</string> |     <string name="swipe_to_seek_settings">Swipe to seek</string> | ||||||
|  |  | ||||||
|  | @ -11,6 +11,11 @@ | ||||||
|                 android:title="@string/player_subtitles_settings" |                 android:title="@string/player_subtitles_settings" | ||||||
|                 android:icon="@drawable/ic_outline_subtitles_24" |                 android:icon="@drawable/ic_outline_subtitles_24" | ||||||
|                 app:summary="@string/player_subtitles_settings_des" /> |                 app:summary="@string/player_subtitles_settings_des" /> | ||||||
|  |         <Preference | ||||||
|  |                 android:key="@string/subtitle_settings_chomecast_key" | ||||||
|  |                 android:title="@string/chomecast_subtitles_settings" | ||||||
|  |                 android:icon="@drawable/ic_outline_subtitles_24" | ||||||
|  |                 app:summary="@string/chomecast_subtitles_settings_des" /> | ||||||
|         <Preference |         <Preference | ||||||
|                 android:key="@string/quality_pref_key" |                 android:key="@string/quality_pref_key" | ||||||
|                 android:title="@string/watch_quality_pref" |                 android:title="@string/watch_quality_pref" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue