forked from recloudstream/cloudstream
		
	settings update
This commit is contained in:
		
							parent
							
								
									8d14046c4a
								
							
						
					
					
						commit
						88e1719085
					
				
					 27 changed files with 1655 additions and 1183 deletions
				
			
		|  | @ -36,7 +36,7 @@ android { | ||||||
|         targetSdkVersion 30 |         targetSdkVersion 30 | ||||||
| 
 | 
 | ||||||
|         versionCode 47 |         versionCode 47 | ||||||
|         versionName "2.9.25" |         versionName "2.10.25" | ||||||
| 
 | 
 | ||||||
|         resValue "string", "app_version", |         resValue "string", "app_version", | ||||||
|                 "${defaultConfig.versionName}${versionNameSuffix ?: ""}" |                 "${defaultConfig.versionName}${versionNameSuffix ?: ""}" | ||||||
|  | @ -89,12 +89,13 @@ repositories { | ||||||
| 
 | 
 | ||||||
| dependencies { | dependencies { | ||||||
|     implementation 'com.google.android.mediahome:video:1.0.0' |     implementation 'com.google.android.mediahome:video:1.0.0' | ||||||
|  |     implementation 'androidx.test.ext:junit-ktx:1.1.3' | ||||||
|     testImplementation 'org.json:json:20180813' |     testImplementation 'org.json:json:20180813' | ||||||
| 
 | 
 | ||||||
|     implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" |     implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" | ||||||
|     implementation 'androidx.core:core-ktx:1.7.0' |     implementation 'androidx.core:core-ktx:1.7.0' | ||||||
|     implementation 'androidx.appcompat:appcompat:1.4.1' |     implementation 'androidx.appcompat:appcompat:1.4.1' | ||||||
|     implementation 'com.google.android.material:material:1.5.0' |     implementation 'com.google.android.material:material:1.5.0' // dont change this to 1.6.0 it looks ugly af | ||||||
|     implementation 'androidx.constraintlayout:constraintlayout:2.1.3' |     implementation 'androidx.constraintlayout:constraintlayout:2.1.3' | ||||||
|     implementation 'androidx.navigation:navigation-fragment-ktx:2.5.0-beta01' |     implementation 'androidx.navigation:navigation-fragment-ktx:2.5.0-beta01' | ||||||
|     implementation 'androidx.navigation:navigation-ui-ktx:2.5.0-beta01' |     implementation 'androidx.navigation:navigation-ui-ktx:2.5.0-beta01' | ||||||
|  | @ -108,8 +109,6 @@ dependencies { | ||||||
| //    implementation 'org.jsoup:jsoup:1.13.1' | //    implementation 'org.jsoup:jsoup:1.13.1' | ||||||
| //    implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.12.3" | //    implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.12.3" | ||||||
| 
 | 
 | ||||||
|     implementation "com.google.android.material:material:1.5.0" |  | ||||||
| 
 |  | ||||||
|     implementation "androidx.preference:preference-ktx:1.2.0" |     implementation "androidx.preference:preference-ktx:1.2.0" | ||||||
| 
 | 
 | ||||||
|     implementation 'com.github.bumptech.glide:glide:4.13.1' |     implementation 'com.github.bumptech.glide:glide:4.13.1' | ||||||
|  |  | ||||||
|  | @ -128,7 +128,15 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { | ||||||
|             R.id.navigation_search, |             R.id.navigation_search, | ||||||
|             R.id.navigation_downloads, |             R.id.navigation_downloads, | ||||||
|             R.id.navigation_settings, |             R.id.navigation_settings, | ||||||
|             R.id.navigation_download_child |             R.id.navigation_download_child, | ||||||
|  |             R.id.navigation_subtitles, | ||||||
|  |             R.id.navigation_chrome_subtitles, | ||||||
|  |             R.id.navigation_settings_nginx, | ||||||
|  |             R.id.navigation_settings_player, | ||||||
|  |             R.id.navigation_settings_updates, | ||||||
|  |             R.id.navigation_settings_ui, | ||||||
|  |             R.id.navigation_settings_account, | ||||||
|  |             R.id.navigation_settings_lang, | ||||||
|         ).contains(destination.id) |         ).contains(destination.id) | ||||||
| 
 | 
 | ||||||
|         val landscape = when (resources.configuration.orientation) { |         val landscape = when (resources.configuration.orientation) { | ||||||
|  |  | ||||||
|  | @ -9,7 +9,6 @@ import androidx.appcompat.app.AppCompatActivity | ||||||
| import androidx.core.view.isVisible | import androidx.core.view.isVisible | ||||||
| import androidx.fragment.app.Fragment | import androidx.fragment.app.Fragment | ||||||
| import androidx.lifecycle.ViewModelProvider | import androidx.lifecycle.ViewModelProvider | ||||||
| import androidx.navigation.fragment.NavHostFragment |  | ||||||
| import androidx.recyclerview.widget.GridLayoutManager | import androidx.recyclerview.widget.GridLayoutManager | ||||||
| import androidx.recyclerview.widget.RecyclerView | import androidx.recyclerview.widget.RecyclerView | ||||||
| import com.lagradost.cloudstream3.R | import com.lagradost.cloudstream3.R | ||||||
|  | @ -22,6 +21,7 @@ import com.lagradost.cloudstream3.utils.DOWNLOAD_EPISODE_CACHE | ||||||
| import com.lagradost.cloudstream3.utils.DataStore | import com.lagradost.cloudstream3.utils.DataStore | ||||||
| import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar | import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar | ||||||
| import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard | import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard | ||||||
|  | import com.lagradost.cloudstream3.utils.UIHelper.navigate | ||||||
| import com.lagradost.cloudstream3.utils.VideoDownloadHelper | import com.lagradost.cloudstream3.utils.VideoDownloadHelper | ||||||
| import com.lagradost.cloudstream3.utils.VideoDownloadManager | import com.lagradost.cloudstream3.utils.VideoDownloadManager | ||||||
| import kotlinx.android.synthetic.main.fragment_downloads.* | import kotlinx.android.synthetic.main.fragment_downloads.* | ||||||
|  | @ -80,17 +80,26 @@ class DownloadFragment : Fragment() { | ||||||
|         } |         } | ||||||
|         observe(downloadsViewModel.availableBytes) { |         observe(downloadsViewModel.availableBytes) { | ||||||
|             download_free_txt?.text = |             download_free_txt?.text = | ||||||
|                 getString(R.string.storage_size_format).format(getString(R.string.free_storage), getBytesAsText(it)) |                 getString(R.string.storage_size_format).format( | ||||||
|  |                     getString(R.string.free_storage), | ||||||
|  |                     getBytesAsText(it) | ||||||
|  |                 ) | ||||||
|             download_free?.setLayoutWidth(it) |             download_free?.setLayoutWidth(it) | ||||||
|         } |         } | ||||||
|         observe(downloadsViewModel.usedBytes) { |         observe(downloadsViewModel.usedBytes) { | ||||||
|             download_used_txt?.text = |             download_used_txt?.text = | ||||||
|                 getString(R.string.storage_size_format).format(getString(R.string.used_storage), getBytesAsText(it)) |                 getString(R.string.storage_size_format).format( | ||||||
|  |                     getString(R.string.used_storage), | ||||||
|  |                     getBytesAsText(it) | ||||||
|  |                 ) | ||||||
|             download_used?.setLayoutWidth(it) |             download_used?.setLayoutWidth(it) | ||||||
|         } |         } | ||||||
|         observe(downloadsViewModel.downloadBytes) { |         observe(downloadsViewModel.downloadBytes) { | ||||||
|             download_app_txt?.text = |             download_app_txt?.text = | ||||||
|                 getString(R.string.storage_size_format).format(getString(R.string.app_storage), getBytesAsText(it)) |                 getString(R.string.storage_size_format).format( | ||||||
|  |                     getString(R.string.app_storage), | ||||||
|  |                     getBytesAsText(it) | ||||||
|  |                 ) | ||||||
|             download_app?.setLayoutWidth(it) |             download_app?.setLayoutWidth(it) | ||||||
|             download_storage_appbar?.visibility = View.VISIBLE |             download_storage_appbar?.visibility = View.VISIBLE | ||||||
|         } |         } | ||||||
|  | @ -112,16 +121,21 @@ class DownloadFragment : Fragment() { | ||||||
|                             if (click.data.type.isMovieType()) { |                             if (click.data.type.isMovieType()) { | ||||||
|                                 //wont be called |                                 //wont be called | ||||||
|                             } else { |                             } else { | ||||||
|                                 val folder = DataStore.getFolderName(DOWNLOAD_EPISODE_CACHE, click.data.id.toString()) |                                 val folder = DataStore.getFolderName( | ||||||
|                                 val navHostFragment = activity?.supportFragmentManager?.findFragmentById(R.id.nav_host_fragment) as? NavHostFragment? |                                     DOWNLOAD_EPISODE_CACHE, | ||||||
|                                 navHostFragment?.navController?.navigate( |                                     click.data.id.toString() | ||||||
|                                     R.id.navigation_download_child, |                                 ) | ||||||
|  |                                 activity?.navigate( | ||||||
|  |                                     R.id.action_navigation_downloads_to_navigation_download_child, | ||||||
|                                     DownloadChildFragment.newInstance(click.data.name, folder) |                                     DownloadChildFragment.newInstance(click.data.name, folder) | ||||||
|                                 ) |                                 ) | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                         1 -> { |                         1 -> { | ||||||
|                             (activity as AppCompatActivity?)?.loadResult(click.data.url, click.data.apiName) |                             (activity as AppCompatActivity?)?.loadResult( | ||||||
|  |                                 click.data.url, | ||||||
|  |                                 click.data.apiName | ||||||
|  |                             ) | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1027,7 +1027,6 @@ open class FullScreenPlayer : AbstractPlayerFragment() { | ||||||
| 
 | 
 | ||||||
|         // init variables |         // init variables | ||||||
|         setPlayBackSpeed(getKey(PLAYBACK_SPEED_KEY) ?: 1.0f) |         setPlayBackSpeed(getKey(PLAYBACK_SPEED_KEY) ?: 1.0f) | ||||||
|         fastForwardTime = getKey(PLAYBACK_FASTFORWARD) ?: 10000L |  | ||||||
| 
 | 
 | ||||||
|         // handle tv controls |         // handle tv controls | ||||||
|         playerEventListener = { eventType -> |         playerEventListener = { eventType -> | ||||||
|  | @ -1086,6 +1085,10 @@ open class FullScreenPlayer : AbstractPlayerFragment() { | ||||||
|             context?.let { ctx -> |             context?.let { ctx -> | ||||||
|                 val settingsManager = PreferenceManager.getDefaultSharedPreferences(ctx) |                 val settingsManager = PreferenceManager.getDefaultSharedPreferences(ctx) | ||||||
| 
 | 
 | ||||||
|  |                 fastForwardTime = | ||||||
|  |                     settingsManager.getInt(ctx.getString(R.string.double_tap_seek_time_key), 10) | ||||||
|  |                         .toLong() * 1000L | ||||||
|  | 
 | ||||||
|                 navigationBarHeight = ctx.getNavigationBarHeight() |                 navigationBarHeight = ctx.getNavigationBarHeight() | ||||||
|                 statusBarHeight = ctx.getStatusBarHeight() |                 statusBarHeight = ctx.getStatusBarHeight() | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -52,6 +52,9 @@ class GeneratorPlayer : FullScreenPlayer() { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private var titleRez = 3 | ||||||
|  |     private var limitTitle = 0 | ||||||
|  | 
 | ||||||
|     private lateinit var viewModel: PlayerGeneratorViewModel //by activityViewModels() |     private lateinit var viewModel: PlayerGeneratorViewModel //by activityViewModels() | ||||||
|     private lateinit var sync: SyncViewModel |     private lateinit var sync: SyncViewModel | ||||||
|     private var currentLinks: Set<Pair<ExtractorLink?, ExtractorUri?>> = setOf() |     private var currentLinks: Set<Pair<ExtractorLink?, ExtractorUri?>> = setOf() | ||||||
|  | @ -550,12 +553,7 @@ class GeneratorPlayer : FullScreenPlayer() { | ||||||
|                 tvType = meta.tvType |                 tvType = meta.tvType | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         //Get limit of characters on Video Title | 
 | ||||||
|         var limitTitle = 0 |  | ||||||
|         context?.let { |  | ||||||
|             val settingsManager = PreferenceManager.getDefaultSharedPreferences(it) |  | ||||||
|             limitTitle = settingsManager.getInt(getString(R.string.prefer_limit_title_key), 0) |  | ||||||
|         } |  | ||||||
|         //Generate video title |         //Generate video title | ||||||
|         var playerVideoTitle = if (headerName != null) { |         var playerVideoTitle = if (headerName != null) { | ||||||
|             (headerName + |             (headerName + | ||||||
|  | @ -589,13 +587,21 @@ class GeneratorPlayer : FullScreenPlayer() { | ||||||
|     fun setPlayerDimen(widthHeight: Pair<Int, Int>?) { |     fun setPlayerDimen(widthHeight: Pair<Int, Int>?) { | ||||||
|         val extra = if (widthHeight != null) { |         val extra = if (widthHeight != null) { | ||||||
|             val (width, height) = widthHeight |             val (width, height) = widthHeight | ||||||
|             " - ${width}x${height}" |             "${width}x${height}" | ||||||
|         } else { |         } else { | ||||||
|             "" |             "" | ||||||
|         } |         } | ||||||
|         player_video_title_rez?.text = | 
 | ||||||
|             (currentSelectedLink?.first?.name ?: currentSelectedLink?.second?.name |         val source = currentSelectedLink?.first?.name ?: currentSelectedLink?.second?.name | ||||||
|             ?: "NULL") + extra |         ?: "NULL" | ||||||
|  | 
 | ||||||
|  |         player_video_title_rez?.text = when (titleRez) { | ||||||
|  |             0 -> "" | ||||||
|  |             1 -> extra | ||||||
|  |             2 -> source | ||||||
|  |             3 -> "$source - $extra" | ||||||
|  |             else -> "" | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun playerDimensionsLoaded(widthHeight: Pair<Int, Int>) { |     override fun playerDimensionsLoaded(widthHeight: Pair<Int, Int>) { | ||||||
|  | @ -631,6 +637,12 @@ class GeneratorPlayer : FullScreenPlayer() { | ||||||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||||
|         super.onViewCreated(view, savedInstanceState) |         super.onViewCreated(view, savedInstanceState) | ||||||
| 
 | 
 | ||||||
|  |         context?.let { ctx -> | ||||||
|  |             val settingsManager = PreferenceManager.getDefaultSharedPreferences(ctx) | ||||||
|  |             titleRez = settingsManager.getInt(getString(R.string.prefer_limit_title_rez_key), 3) | ||||||
|  |             limitTitle = settingsManager.getInt(getString(R.string.prefer_limit_title_key), 0) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         unwrapBundle(savedInstanceState) |         unwrapBundle(savedInstanceState) | ||||||
|         unwrapBundle(arguments) |         unwrapBundle(arguments) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -57,7 +57,7 @@ const val PLAYBACK_SPEED = "playback_speed" | ||||||
| const val RESIZE_MODE_KEY = "resize_mode" // Last used resize mode | const val RESIZE_MODE_KEY = "resize_mode" // Last used resize mode | ||||||
| const val PLAYBACK_SPEED_KEY = "playback_speed" // Last used playback speed | const val PLAYBACK_SPEED_KEY = "playback_speed" // Last used playback speed | ||||||
| const val PREFERRED_SUBS_KEY = "preferred_subtitles" // Last used resize mode | const val PREFERRED_SUBS_KEY = "preferred_subtitles" // Last used resize mode | ||||||
| const val PLAYBACK_FASTFORWARD = "playback_fastforward" // Last used resize mode | //const val PLAYBACK_FASTFORWARD = "playback_fastforward" // Last used resize mode | ||||||
| 
 | 
 | ||||||
| /** Abstract Exoplayer logic, can be expanded to other players */ | /** Abstract Exoplayer logic, can be expanded to other players */ | ||||||
| interface IPlayer { | interface IPlayer { | ||||||
|  |  | ||||||
|  | @ -1729,14 +1729,12 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio | ||||||
|                     setRecommendations(d.recommendations, null) |                     setRecommendations(d.recommendations, null) | ||||||
|                     setActors(d.actors) |                     setActors(d.actors) | ||||||
| 
 | 
 | ||||||
|                     if (SettingsFragment.accountEnabled) { |  | ||||||
|                     if (syncModel.addSyncs(d.syncData)) { |                     if (syncModel.addSyncs(d.syncData)) { | ||||||
|                         syncModel.updateMetaAndUser() |                         syncModel.updateMetaAndUser() | ||||||
|                         syncModel.updateSynced() |                         syncModel.updateSynced() | ||||||
|                     } else { |                     } else { | ||||||
|                         syncModel.addFromUrl(d.url) |                         syncModel.addFromUrl(d.url) | ||||||
|                     } |                     } | ||||||
|                     } |  | ||||||
| 
 | 
 | ||||||
|                     result_meta_site?.text = d.apiName |                     result_meta_site?.text = d.apiName | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,149 @@ | ||||||
|  | package com.lagradost.cloudstream3.ui.settings | ||||||
|  | 
 | ||||||
|  | import android.content.Context | ||||||
|  | import android.os.Bundle | ||||||
|  | import android.widget.ImageView | ||||||
|  | import android.widget.TextView | ||||||
|  | import androidx.appcompat.app.AlertDialog | ||||||
|  | import androidx.preference.PreferenceFragmentCompat | ||||||
|  | import androidx.preference.PreferenceManager | ||||||
|  | import androidx.recyclerview.widget.RecyclerView | ||||||
|  | import com.lagradost.cloudstream3.R | ||||||
|  | import com.lagradost.cloudstream3.mvvm.logError | ||||||
|  | import com.lagradost.cloudstream3.syncproviders.AccountManager | ||||||
|  | import com.lagradost.cloudstream3.syncproviders.OAuth2API | ||||||
|  | import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.beneneCount | ||||||
|  | import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.getPref | ||||||
|  | import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe | ||||||
|  | import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard | ||||||
|  | import com.lagradost.cloudstream3.utils.UIHelper.setImage | ||||||
|  | 
 | ||||||
|  | class SettingsAccount : PreferenceFragmentCompat() { | ||||||
|  |     private fun showLoginInfo(api: AccountManager, info: OAuth2API.LoginInfo) { | ||||||
|  |         val builder = | ||||||
|  |             AlertDialog.Builder(context ?: return, R.style.AlertDialogCustom) | ||||||
|  |                 .setView(R.layout.account_managment) | ||||||
|  |         val dialog = builder.show() | ||||||
|  | 
 | ||||||
|  |         dialog.findViewById<ImageView>(R.id.account_profile_picture)?.setImage(info.profilePicture) | ||||||
|  |         dialog.findViewById<TextView>(R.id.account_logout)?.setOnClickListener { | ||||||
|  |             api.logOut() | ||||||
|  |             dialog.dismissSafe(activity) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         (info.name ?: context?.getString(R.string.no_data))?.let { | ||||||
|  |             dialog.findViewById<TextView>(R.id.account_name)?.text = it | ||||||
|  |         } | ||||||
|  |         dialog.findViewById<TextView>(R.id.account_site)?.text = api.name | ||||||
|  |         dialog.findViewById<TextView>(R.id.account_switch_account)?.setOnClickListener { | ||||||
|  |             dialog.dismissSafe(activity) | ||||||
|  |             showAccountSwitch(it.context, api) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun showAccountSwitch(context: Context, api: AccountManager) { | ||||||
|  |         val accounts = api.getAccounts() ?: return | ||||||
|  | 
 | ||||||
|  |         val builder = | ||||||
|  |             AlertDialog.Builder(context, R.style.AlertDialogCustom).setView(R.layout.account_switch) | ||||||
|  |         val dialog = builder.show() | ||||||
|  | 
 | ||||||
|  |         dialog.findViewById<TextView>(R.id.account_add)?.setOnClickListener { | ||||||
|  |             try { | ||||||
|  |                 api.authenticate() | ||||||
|  |             } catch (e: Exception) { | ||||||
|  |                 logError(e) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         val ogIndex = api.accountIndex | ||||||
|  | 
 | ||||||
|  |         val items = ArrayList<OAuth2API.LoginInfo>() | ||||||
|  | 
 | ||||||
|  |         for (index in accounts) { | ||||||
|  |             api.accountIndex = index | ||||||
|  |             val accountInfo = api.loginInfo() | ||||||
|  |             if (accountInfo != null) { | ||||||
|  |                 items.add(accountInfo) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         api.accountIndex = ogIndex | ||||||
|  |         val adapter = AccountAdapter(items, R.layout.account_single) { | ||||||
|  |             dialog?.dismissSafe(activity) | ||||||
|  |             api.changeAccount(it.card.accountIndex) | ||||||
|  |         } | ||||||
|  |         val list = dialog.findViewById<RecyclerView>(R.id.account_list) | ||||||
|  |         list?.adapter = adapter | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { | ||||||
|  |         hideKeyboard() | ||||||
|  |         setPreferencesFromResource(R.xml.settings_credits_account, rootKey) | ||||||
|  |         val settingsManager = PreferenceManager.getDefaultSharedPreferences(requireContext()) | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.legal_notice_key)?.setOnPreferenceClickListener { | ||||||
|  |             val builder: AlertDialog.Builder = AlertDialog.Builder(it.context) | ||||||
|  |             builder.setTitle(R.string.legal_notice) | ||||||
|  |             builder.setMessage(R.string.legal_notice_text) | ||||||
|  |             builder.show() | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         val syncApis = | ||||||
|  |             listOf( | ||||||
|  |                 Pair(R.string.mal_key, OAuth2API.malApi), Pair( | ||||||
|  |                     R.string.anilist_key, | ||||||
|  |                     OAuth2API.aniListApi | ||||||
|  |                 ) | ||||||
|  |             ) | ||||||
|  |         for ((key, api) in syncApis) { | ||||||
|  |             getPref(key)?.apply { | ||||||
|  |                 title = | ||||||
|  |                     getString(R.string.login_format).format(api.name, getString(R.string.account)) | ||||||
|  |                 setOnPreferenceClickListener { _ -> | ||||||
|  |                     val info = api.loginInfo() | ||||||
|  |                     if (info != null) { | ||||||
|  |                         showLoginInfo(api, info) | ||||||
|  |                     } else { | ||||||
|  |                         try { | ||||||
|  |                             api.authenticate() | ||||||
|  |                         } catch (e: Exception) { | ||||||
|  |                             logError(e) | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     return@setOnPreferenceClickListener true | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  |             beneneCount = settingsManager.getInt(getString(R.string.benene_count), 0) | ||||||
|  |             getPref(R.string.benene_count)?.let { pref -> | ||||||
|  |                 pref.summary = | ||||||
|  |                     if (beneneCount <= 0) getString(R.string.benene_count_text_none) else getString( | ||||||
|  |                         R.string.benene_count_text | ||||||
|  |                     ).format( | ||||||
|  |                         beneneCount | ||||||
|  |                     ) | ||||||
|  | 
 | ||||||
|  |                 pref.setOnPreferenceClickListener { | ||||||
|  |                     try { | ||||||
|  |                         beneneCount++ | ||||||
|  |                         settingsManager.edit().putInt(getString(R.string.benene_count), beneneCount) | ||||||
|  |                             .apply() | ||||||
|  |                         it.summary = getString(R.string.benene_count_text).format(beneneCount) | ||||||
|  |                     } catch (e: Exception) { | ||||||
|  |                         logError(e) | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     return@setOnPreferenceClickListener true | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } catch (e: Exception) { | ||||||
|  |             e.printStackTrace() | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -1,75 +1,52 @@ | ||||||
| package com.lagradost.cloudstream3.ui.settings | package com.lagradost.cloudstream3.ui.settings | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| import android.app.UiModeManager | import android.app.UiModeManager | ||||||
| import android.content.ClipData |  | ||||||
| import android.content.ClipboardManager |  | ||||||
| import android.content.Context | import android.content.Context | ||||||
| import android.content.Intent |  | ||||||
| import android.content.res.Configuration | import android.content.res.Configuration | ||||||
| import android.net.Uri |  | ||||||
| import android.os.Build | import android.os.Build | ||||||
| import android.os.Bundle | import android.os.Bundle | ||||||
| import android.os.Environment | import android.view.LayoutInflater | ||||||
| import android.widget.ImageView | import android.view.View | ||||||
| import android.widget.TextView | import android.view.ViewGroup | ||||||
| import android.widget.Toast | import androidx.fragment.app.Fragment | ||||||
| import androidx.activity.result.contract.ActivityResultContracts |  | ||||||
| import androidx.appcompat.app.AlertDialog |  | ||||||
| import androidx.preference.Preference | import androidx.preference.Preference | ||||||
| import androidx.preference.PreferenceFragmentCompat | import androidx.preference.PreferenceFragmentCompat | ||||||
| import androidx.preference.PreferenceManager | import androidx.preference.PreferenceManager | ||||||
| import androidx.recyclerview.widget.RecyclerView |  | ||||||
| import com.hippo.unifile.UniFile |  | ||||||
| import com.lagradost.cloudstream3.APIHolder.apis |  | ||||||
| import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings |  | ||||||
| import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings |  | ||||||
| import com.lagradost.cloudstream3.AcraApplication |  | ||||||
| import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey |  | ||||||
| import com.lagradost.cloudstream3.CommonActivity.setLocale |  | ||||||
| import com.lagradost.cloudstream3.CommonActivity.showToast |  | ||||||
| import com.lagradost.cloudstream3.DubStatus |  | ||||||
| import com.lagradost.cloudstream3.R | import com.lagradost.cloudstream3.R | ||||||
| import com.lagradost.cloudstream3.app |  | ||||||
| import com.lagradost.cloudstream3.mvvm.logError | import com.lagradost.cloudstream3.mvvm.logError | ||||||
| import com.lagradost.cloudstream3.mvvm.normalSafeApiCall | import com.lagradost.cloudstream3.utils.UIHelper.navigate | ||||||
| import com.lagradost.cloudstream3.network.initClient | import kotlinx.android.synthetic.main.main_settings.* | ||||||
| import com.lagradost.cloudstream3.syncproviders.AccountManager |  | ||||||
| import com.lagradost.cloudstream3.syncproviders.OAuth2API |  | ||||||
| import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.aniListApi |  | ||||||
| import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.malApi |  | ||||||
| import com.lagradost.cloudstream3.ui.APIRepository |  | ||||||
| import com.lagradost.cloudstream3.ui.search.SearchResultBuilder |  | ||||||
| import com.lagradost.cloudstream3.ui.subtitles.ChromecastSubtitlesFragment |  | ||||||
| import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment |  | ||||||
| import com.lagradost.cloudstream3.utils.BackupUtils.backup |  | ||||||
| import com.lagradost.cloudstream3.utils.BackupUtils.restorePrompt |  | ||||||
| import com.lagradost.cloudstream3.utils.HOMEPAGE_API |  | ||||||
| import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate |  | ||||||
| import com.lagradost.cloudstream3.utils.Qualities |  | ||||||
| import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog |  | ||||||
| import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog |  | ||||||
| import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showMultiDialog |  | ||||||
| import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showNginxTextInputDialog |  | ||||||
| import com.lagradost.cloudstream3.utils.SubtitleHelper |  | ||||||
| import com.lagradost.cloudstream3.utils.SubtitleHelper.getFlagFromIso |  | ||||||
| import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe |  | ||||||
| import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard |  | ||||||
| import com.lagradost.cloudstream3.utils.UIHelper.setImage |  | ||||||
| import com.lagradost.cloudstream3.utils.VideoDownloadManager |  | ||||||
| import com.lagradost.cloudstream3.utils.VideoDownloadManager.getBasePath |  | ||||||
| import com.lagradost.cloudstream3.utils.VideoDownloadManager.getDownloadDir |  | ||||||
| import kotlinx.android.synthetic.main.logcat.* |  | ||||||
| import okhttp3.internal.closeQuietly |  | ||||||
| import java.io.BufferedReader |  | ||||||
| import java.io.File | import java.io.File | ||||||
| import java.io.InputStreamReader |  | ||||||
| import java.io.OutputStream |  | ||||||
| import kotlin.concurrent.thread |  | ||||||
| 
 | 
 | ||||||
| 
 | class SettingsFragment : Fragment() { | ||||||
| class SettingsFragment : PreferenceFragmentCompat() { |  | ||||||
|     companion object { |     companion object { | ||||||
|  |         var beneneCount = 0 | ||||||
|  | 
 | ||||||
|  |         fun PreferenceFragmentCompat?.getPref(id: Int): Preference? { | ||||||
|  |             if (this == null) return null | ||||||
|  | 
 | ||||||
|  |             return try { | ||||||
|  |                 findPreference(getString(id)) | ||||||
|  |             } catch (e: Exception) { | ||||||
|  |                 logError(e) | ||||||
|  |                 null | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         fun getFolderSize(dir: File): Long { | ||||||
|  |             var size: Long = 0 | ||||||
|  |             dir.listFiles()?.let { | ||||||
|  |                 for (file in it) { | ||||||
|  |                     size += if (file.isFile) { | ||||||
|  |                         // System.out.println(file.getName() + " " + file.length()); | ||||||
|  |                         file.length() | ||||||
|  |                     } else getFolderSize(file) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return size | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         private fun Context.getLayoutInt(): Int { |         private fun Context.getLayoutInt(): Int { | ||||||
|             val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) |             val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) | ||||||
|             return settingsManager.getInt(this.getString(R.string.app_layout_key), -1) |             return settingsManager.getInt(this.getString(R.string.app_layout_key), -1) | ||||||
|  | @ -98,762 +75,47 @@ class SettingsFragment : PreferenceFragmentCompat() { | ||||||
|         private fun Context.isAutoTv(): Boolean { |         private fun Context.isAutoTv(): Boolean { | ||||||
|             val uiModeManager = getSystemService(Context.UI_MODE_SERVICE) as UiModeManager? |             val uiModeManager = getSystemService(Context.UI_MODE_SERVICE) as UiModeManager? | ||||||
|             // AFT = Fire TV |             // AFT = Fire TV | ||||||
|             return uiModeManager?.currentModeType == Configuration.UI_MODE_TYPE_TELEVISION || Build.MODEL.contains("AFT") |             return uiModeManager?.currentModeType == Configuration.UI_MODE_TYPE_TELEVISION || Build.MODEL.contains( | ||||||
|         } |                 "AFT" | ||||||
| 
 |  | ||||||
|         const val accountEnabled = true |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private var beneneCount = 0 |  | ||||||
| 
 |  | ||||||
|     // Open file picker |  | ||||||
|     private val pathPicker = |  | ||||||
|         registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri -> |  | ||||||
|             // It lies, it can be null if file manager quits. |  | ||||||
|             if (uri == null) return@registerForActivityResult |  | ||||||
|             val context = context ?: AcraApplication.context ?: return@registerForActivityResult |  | ||||||
|             // RW perms for the path |  | ||||||
|             val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or |  | ||||||
|                     Intent.FLAG_GRANT_WRITE_URI_PERMISSION |  | ||||||
| 
 |  | ||||||
|             context.contentResolver.takePersistableUriPermission(uri, flags) |  | ||||||
| 
 |  | ||||||
|             val file = UniFile.fromUri(context, uri) |  | ||||||
|             println("Selected URI path: $uri - Full path: ${file.filePath}") |  | ||||||
| 
 |  | ||||||
|             // Stores the real URI using download_path_key |  | ||||||
|             // Important that the URI is stored instead of filepath due to permissions. |  | ||||||
|             PreferenceManager.getDefaultSharedPreferences(context) |  | ||||||
|                 .edit().putString(getString(R.string.download_path_key), uri.toString()).apply() |  | ||||||
| 
 |  | ||||||
|             // From URI -> File path |  | ||||||
|             // File path here is purely for cosmetic purposes in settings |  | ||||||
|             (file.filePath ?: uri.toString()).let { |  | ||||||
|                 PreferenceManager.getDefaultSharedPreferences(context) |  | ||||||
|                     .edit().putString(getString(R.string.download_path_pref), it).apply() |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     // idk, if you find a way of automating this it would be great |  | ||||||
|     // https://www.iemoji.com/view/emoji/1794/flags/antarctica |  | ||||||
|     // Emoji Character Encoding Data --> C/C++/Java Src |  | ||||||
|     // https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes leave blank for auto |  | ||||||
|     private val languages = arrayListOf( |  | ||||||
|         Triple("", "Spanish", "es"), |  | ||||||
|         Triple("", "English", "en"), |  | ||||||
|         Triple("", "Viet Nam", "vi"), |  | ||||||
|         Triple("", "Dutch", "nl"), |  | ||||||
|         Triple("", "French", "fr"), |  | ||||||
|         Triple("", "Greek", "el"), |  | ||||||
|         Triple("", "Swedish", "sv"), |  | ||||||
|         Triple("", "Tagalog", "tl"), |  | ||||||
|         Triple("", "Polish", "pl"), |  | ||||||
|         Triple("", "Hindi", "hi"), |  | ||||||
|         Triple("", "Malayalam", "ml"), |  | ||||||
|         Triple("", "Norsk", "no"), |  | ||||||
|         Triple("", "German", "de"), |  | ||||||
|         Triple("", "Arabic", "ar"), |  | ||||||
|         Triple("", "Turkish", "tr"), |  | ||||||
|         Triple("", "Macedonian", "mk"), |  | ||||||
|         Triple("", "Portuguese (Brazil)", "pt"), |  | ||||||
|         Triple("", "Romanian", "ro"), |  | ||||||
|         Triple("", "Italian", "it"), |  | ||||||
|         Triple("", "Chinese", "zh"), |  | ||||||
|     ).sortedBy { it.second } //ye, we go alphabetical, so ppl don't put their lang on top |  | ||||||
| 
 |  | ||||||
|     private fun showAccountSwitch(context: Context, api: AccountManager) { |  | ||||||
|         val accounts = api.getAccounts() ?: return |  | ||||||
| 
 |  | ||||||
|         val builder = |  | ||||||
|             AlertDialog.Builder(context, R.style.AlertDialogCustom).setView(R.layout.account_switch) |  | ||||||
|         val dialog = builder.show() |  | ||||||
| 
 |  | ||||||
|         dialog.findViewById<TextView>(R.id.account_add)?.setOnClickListener { |  | ||||||
|             try { |  | ||||||
|                 api.authenticate() |  | ||||||
|             } catch (e: Exception) { |  | ||||||
|                 logError(e) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         val ogIndex = api.accountIndex |  | ||||||
| 
 |  | ||||||
|         val items = ArrayList<OAuth2API.LoginInfo>() |  | ||||||
| 
 |  | ||||||
|         for (index in accounts) { |  | ||||||
|             api.accountIndex = index |  | ||||||
|             val accountInfo = api.loginInfo() |  | ||||||
|             if (accountInfo != null) { |  | ||||||
|                 items.add(accountInfo) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         api.accountIndex = ogIndex |  | ||||||
|         val adapter = AccountAdapter(items, R.layout.account_single) { |  | ||||||
|             dialog?.dismissSafe(activity) |  | ||||||
|             api.changeAccount(it.card.accountIndex) |  | ||||||
|         } |  | ||||||
|         val list = dialog.findViewById<RecyclerView>(R.id.account_list) |  | ||||||
|         list?.adapter = adapter |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private fun showLoginInfo(api: AccountManager, info: OAuth2API.LoginInfo) { |  | ||||||
|         val builder = |  | ||||||
|             AlertDialog.Builder(context ?: return, R.style.AlertDialogCustom) |  | ||||||
|                 .setView(R.layout.account_managment) |  | ||||||
|         val dialog = builder.show() |  | ||||||
| 
 |  | ||||||
|         dialog.findViewById<ImageView>(R.id.account_profile_picture)?.setImage(info.profilePicture) |  | ||||||
|         dialog.findViewById<TextView>(R.id.account_logout)?.setOnClickListener { |  | ||||||
|             api.logOut() |  | ||||||
|             dialog.dismissSafe(activity) |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         (info.name ?: context?.getString(R.string.no_data))?.let { |  | ||||||
|             dialog.findViewById<TextView>(R.id.account_name)?.text = it |  | ||||||
|         } |  | ||||||
|         dialog.findViewById<TextView>(R.id.account_site)?.text = api.name |  | ||||||
|         dialog.findViewById<TextView>(R.id.account_switch_account)?.setOnClickListener { |  | ||||||
|             dialog.dismissSafe(activity) |  | ||||||
|             showAccountSwitch(it.context, api) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private fun getPref(id: Int): Preference? { |  | ||||||
|         return try { |  | ||||||
|             findPreference(getString(id)) |  | ||||||
|         } catch (e: Exception) { |  | ||||||
|             logError(e) |  | ||||||
|             null |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private fun getFolderSize(dir: File): Long { |  | ||||||
|         var size: Long = 0 |  | ||||||
|         dir.listFiles()?.let { |  | ||||||
|             for (file in it) { |  | ||||||
|                 size += if (file.isFile) { |  | ||||||
|                     // System.out.println(file.getName() + " " + file.length()); |  | ||||||
|                     file.length() |  | ||||||
|                 } else getFolderSize(file) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return size |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { |  | ||||||
|         hideKeyboard() |  | ||||||
|         setPreferencesFromResource(R.xml.settings, rootKey) |  | ||||||
|         val settingsManager = PreferenceManager.getDefaultSharedPreferences(requireContext()) |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.video_buffer_length_key)?.setOnPreferenceClickListener { |  | ||||||
|             val prefNames = resources.getStringArray(R.array.video_buffer_length_names) |  | ||||||
|             val prefValues = resources.getIntArray(R.array.video_buffer_length_values) |  | ||||||
| 
 |  | ||||||
|             val currentPrefSize = |  | ||||||
|                 settingsManager.getInt(getString(R.string.video_buffer_length_key), 0) |  | ||||||
| 
 |  | ||||||
|             activity?.showDialog( |  | ||||||
|                 prefNames.toList(), |  | ||||||
|                 prefValues.indexOf(currentPrefSize), |  | ||||||
|                 getString(R.string.video_buffer_length_settings), |  | ||||||
|                 true, |  | ||||||
|                 {}) { |  | ||||||
|                 settingsManager.edit() |  | ||||||
|                     .putInt(getString(R.string.video_buffer_length_key), prefValues[it]) |  | ||||||
|                     .apply() |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.video_buffer_size_key)?.setOnPreferenceClickListener { |  | ||||||
|             val prefNames = resources.getStringArray(R.array.video_buffer_size_names) |  | ||||||
|             val prefValues = resources.getIntArray(R.array.video_buffer_size_values) |  | ||||||
| 
 |  | ||||||
|             val currentPrefSize = |  | ||||||
|                 settingsManager.getInt(getString(R.string.video_buffer_size_key), 0) |  | ||||||
| 
 |  | ||||||
|             activity?.showDialog( |  | ||||||
|                 prefNames.toList(), |  | ||||||
|                 prefValues.indexOf(currentPrefSize), |  | ||||||
|                 getString(R.string.video_buffer_size_settings), |  | ||||||
|                 true, |  | ||||||
|                 {}) { |  | ||||||
|                 settingsManager.edit() |  | ||||||
|                     .putInt(getString(R.string.video_buffer_size_key), prefValues[it]) |  | ||||||
|                     .apply() |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.video_buffer_clear_key)?.let { pref -> |  | ||||||
|             val cacheDir = context?.cacheDir ?: return@let |  | ||||||
| 
 |  | ||||||
|             fun updateSummery() { |  | ||||||
|                 try { |  | ||||||
|                     pref.summary = |  | ||||||
|                         getString(R.string.mb_format).format(getFolderSize(cacheDir) / (1024L * 1024L)) |  | ||||||
|                 } catch (e: Exception) { |  | ||||||
|                     logError(e) |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             updateSummery() |  | ||||||
| 
 |  | ||||||
|             pref.setOnPreferenceClickListener { |  | ||||||
|                 try { |  | ||||||
|                     cacheDir.deleteRecursively() |  | ||||||
|                     updateSummery() |  | ||||||
|                 } catch (e: Exception) { |  | ||||||
|                     logError(e) |  | ||||||
|                 } |  | ||||||
|                 return@setOnPreferenceClickListener true |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.video_buffer_disk_key)?.setOnPreferenceClickListener { |  | ||||||
|             val prefNames = resources.getStringArray(R.array.video_buffer_size_names) |  | ||||||
|             val prefValues = resources.getIntArray(R.array.video_buffer_size_values) |  | ||||||
| 
 |  | ||||||
|             val currentPrefSize = |  | ||||||
|                 settingsManager.getInt(getString(R.string.video_buffer_disk_key), 0) |  | ||||||
| 
 |  | ||||||
|             activity?.showDialog( |  | ||||||
|                 prefNames.toList(), |  | ||||||
|                 prefValues.indexOf(currentPrefSize), |  | ||||||
|                 getString(R.string.video_buffer_disk_settings), |  | ||||||
|                 true, |  | ||||||
|                 {}) { |  | ||||||
|                 settingsManager.edit() |  | ||||||
|                     .putInt(getString(R.string.video_buffer_disk_key), prefValues[it]) |  | ||||||
|                     .apply() |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.subtitle_settings_key)?.setOnPreferenceClickListener { |  | ||||||
|             SubtitlesFragment.push(activity, false) |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.subtitle_settings_chromecast_key)?.setOnPreferenceClickListener { |  | ||||||
|             ChromecastSubtitlesFragment.push(activity, false) |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.poster_ui_key)?.setOnPreferenceClickListener { |  | ||||||
|             val prefNames = resources.getStringArray(R.array.poster_ui_options) |  | ||||||
|             val keys = resources.getStringArray(R.array.poster_ui_options_values) |  | ||||||
|             val prefValues = keys.map { |  | ||||||
|                 settingsManager.getBoolean(it, true) |  | ||||||
|             }.mapIndexedNotNull { index, b -> |  | ||||||
|                 if (b) { |  | ||||||
|                     index |  | ||||||
|                 } else null |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             activity?.showMultiDialog( |  | ||||||
|                 prefNames.toList(), |  | ||||||
|                 prefValues, |  | ||||||
|                 getString(R.string.poster_ui_settings), |  | ||||||
|                 {}) { list -> |  | ||||||
|                 val edit = settingsManager.edit() |  | ||||||
|                 for ((i, key) in keys.withIndex()) { |  | ||||||
|                     edit.putBoolean(key, list.contains(i)) |  | ||||||
|                 } |  | ||||||
|                 edit.apply() |  | ||||||
|                 SearchResultBuilder.updateCache(it.context) |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         val syncApis = |  | ||||||
|             listOf(Pair(R.string.mal_key, malApi), Pair(R.string.anilist_key, aniListApi)) |  | ||||||
|         for ((key, api) in syncApis) { |  | ||||||
|             getPref(key)?.apply { |  | ||||||
|                 isVisible = accountEnabled |  | ||||||
|                 title = |  | ||||||
|                     getString(R.string.login_format).format(api.name, getString(R.string.account)) |  | ||||||
|                 setOnPreferenceClickListener { _ -> |  | ||||||
|                     val info = api.loginInfo() |  | ||||||
|                     if (info != null) { |  | ||||||
|                         showLoginInfo(api, info) |  | ||||||
|                     } else { |  | ||||||
|                         try { |  | ||||||
|                             api.authenticate() |  | ||||||
|                         } catch (e: Exception) { |  | ||||||
|                             logError(e) |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                     return@setOnPreferenceClickListener true |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.legal_notice_key)?.setOnPreferenceClickListener { |  | ||||||
|             val builder: AlertDialog.Builder = AlertDialog.Builder(it.context) |  | ||||||
|             builder.setTitle(R.string.legal_notice) |  | ||||||
|             builder.setMessage(R.string.legal_notice_text) |  | ||||||
|             builder.show() |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.display_sub_key)?.setOnPreferenceClickListener { |  | ||||||
|             activity?.getApiDubstatusSettings()?.let { current -> |  | ||||||
|                 val dublist = DubStatus.values() |  | ||||||
|                 val names = dublist.map { it.name } |  | ||||||
| 
 |  | ||||||
|                 val currentList = ArrayList<Int>() |  | ||||||
|                 for (i in current) { |  | ||||||
|                     currentList.add(dublist.indexOf(i)) |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 activity?.showMultiDialog( |  | ||||||
|                     names, |  | ||||||
|                     currentList, |  | ||||||
|                     getString(R.string.display_subbed_dubbed_settings), |  | ||||||
|                     {}) { selectedList -> |  | ||||||
|                     APIRepository.dubStatusActive = selectedList.map { dublist[it] }.toHashSet() |  | ||||||
| 
 |  | ||||||
|                     settingsManager.edit().putStringSet( |  | ||||||
|                         this.getString(R.string.display_sub_key), |  | ||||||
|                         selectedList.map { names[it] }.toMutableSet() |  | ||||||
|                     ).apply() |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.provider_lang_key)?.setOnPreferenceClickListener { |  | ||||||
|             activity?.getApiProviderLangSettings()?.let { current -> |  | ||||||
|                 val allLangs = HashSet<String>() |  | ||||||
|                 for (api in apis) { |  | ||||||
|                     allLangs.add(api.lang) |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 val currentList = ArrayList<Int>() |  | ||||||
|                 for (i in current) { |  | ||||||
|                     currentList.add(allLangs.indexOf(i)) |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 val names = allLangs.map { |  | ||||||
|                     val emoji = getFlagFromIso(it) |  | ||||||
|                     val name = SubtitleHelper.fromTwoLettersToLanguage(it) |  | ||||||
|                     val fullName = "$emoji $name" |  | ||||||
|                     Pair(it, fullName) |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 activity?.showMultiDialog( |  | ||||||
|                     names.map { it.second }, |  | ||||||
|                     currentList, |  | ||||||
|                     getString(R.string.provider_lang_settings), |  | ||||||
|                     {}) { selectedList -> |  | ||||||
|                     settingsManager.edit().putStringSet( |  | ||||||
|                         this.getString(R.string.provider_lang_key), |  | ||||||
|                         selectedList.map { names[it].first }.toMutableSet() |  | ||||||
|                     ).apply() |  | ||||||
|                     //APIRepository.providersActive = it.context.getApiSettings() |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         fun getDownloadDirs(): List<String> { |  | ||||||
|             return normalSafeApiCall { |  | ||||||
|                 val defaultDir = getDownloadDir()?.filePath |  | ||||||
| 
 |  | ||||||
|                 // app_name_download_path = Cloudstream and does not change depending on release. |  | ||||||
|                 // DOES NOT WORK ON SCOPED STORAGE. |  | ||||||
|                 val secondaryDir = |  | ||||||
|                     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) null else Environment.getExternalStorageDirectory().absolutePath + |  | ||||||
|                             File.separator + resources.getString(R.string.app_name_download_path) |  | ||||||
|                 val first = listOf(defaultDir, secondaryDir) |  | ||||||
|                 (try { |  | ||||||
|                     val currentDir = context?.getBasePath()?.let { it.first?.filePath ?: it.second } |  | ||||||
| 
 |  | ||||||
|                     (first + |  | ||||||
|                             requireContext().getExternalFilesDirs("").mapNotNull { it.path } + |  | ||||||
|                             currentDir) |  | ||||||
|                 } catch (e: Exception) { |  | ||||||
|                     first |  | ||||||
|                 }).filterNotNull().distinct() |  | ||||||
|             } ?: emptyList() |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.download_path_key)?.setOnPreferenceClickListener { |  | ||||||
|             val dirs = getDownloadDirs() |  | ||||||
| 
 |  | ||||||
|             val currentDir = |  | ||||||
|                 settingsManager.getString(getString(R.string.download_path_pref), null) |  | ||||||
|                     ?: getDownloadDir().toString() |  | ||||||
| 
 |  | ||||||
|             activity?.showBottomDialog( |  | ||||||
|                 dirs + listOf("Custom"), |  | ||||||
|                 dirs.indexOf(currentDir), |  | ||||||
|                 getString(R.string.download_path_pref), |  | ||||||
|                 true, |  | ||||||
|                 {}) { |  | ||||||
|                 // Last = custom |  | ||||||
|                 if (it == dirs.size) { |  | ||||||
|                     try { |  | ||||||
|                         pathPicker.launch(Uri.EMPTY) |  | ||||||
|                     } catch (e: Exception) { |  | ||||||
|                         logError(e) |  | ||||||
|                     } |  | ||||||
|                 } else { |  | ||||||
|                     // Sets both visual and actual paths. |  | ||||||
|                     // key = used path |  | ||||||
|                     // pref = visual path |  | ||||||
|                     settingsManager.edit() |  | ||||||
|                         .putString(getString(R.string.download_path_key), dirs[it]).apply() |  | ||||||
|                     settingsManager.edit() |  | ||||||
|                         .putString(getString(R.string.download_path_pref), dirs[it]).apply() |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.nginx_url_key)?.setOnPreferenceClickListener { |  | ||||||
|             activity?.showNginxTextInputDialog( |  | ||||||
|                 settingsManager.getString(getString(R.string.nginx_url_pref), "Nginx server url") |  | ||||||
|                     .toString(), |  | ||||||
|                 settingsManager.getString(getString(R.string.nginx_url_key), "") |  | ||||||
|                     .toString(),  // key: the actual you use rn |  | ||||||
|                 android.text.InputType.TYPE_TEXT_VARIATION_URI,  // uri |  | ||||||
|                 {}) { |  | ||||||
|                 settingsManager.edit() |  | ||||||
|                     .putString(getString(R.string.nginx_url_key), it) |  | ||||||
|                     .apply()  // change the stored url in nginx_url_key to it |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.nginx_credentials)?.setOnPreferenceClickListener { |  | ||||||
|             activity?.showNginxTextInputDialog( |  | ||||||
|                 settingsManager.getString( |  | ||||||
|                     getString(R.string.nginx_credentials_title), |  | ||||||
|                     "Nginx Credentials" |  | ||||||
|                 ).toString(), |  | ||||||
|                 settingsManager.getString(getString(R.string.nginx_credentials), "") |  | ||||||
|                     .toString(),  // key: the actual you use rn |  | ||||||
|                 android.text.InputType.TYPE_TEXT_VARIATION_URI, |  | ||||||
|                 {}) { |  | ||||||
|                 settingsManager.edit() |  | ||||||
|                     .putString(getString(R.string.nginx_credentials), it) |  | ||||||
|                     .apply()  // change the stored url in nginx_url_key to it |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.prefer_media_type_key)?.setOnPreferenceClickListener { |  | ||||||
|             val prefNames = resources.getStringArray(R.array.media_type_pref) |  | ||||||
|             val prefValues = resources.getIntArray(R.array.media_type_pref_values) |  | ||||||
| 
 |  | ||||||
|             val currentPrefMedia = |  | ||||||
|                 settingsManager.getInt(getString(R.string.prefer_media_type_key), 0) |  | ||||||
| 
 |  | ||||||
|             activity?.showBottomDialog( |  | ||||||
|                 prefNames.toList(), |  | ||||||
|                 prefValues.indexOf(currentPrefMedia), |  | ||||||
|                 getString(R.string.preferred_media_settings), |  | ||||||
|                 true, |  | ||||||
|                 {}) { |  | ||||||
|                 settingsManager.edit() |  | ||||||
|                     .putInt(getString(R.string.prefer_media_type_key), prefValues[it]) |  | ||||||
|                     .apply() |  | ||||||
| 
 |  | ||||||
|                 removeKey(HOMEPAGE_API) |  | ||||||
|                 (context ?: AcraApplication.context)?.let { ctx -> app.initClient(ctx) } |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.show_logcat_key)?.setOnPreferenceClickListener { pref -> |  | ||||||
|             val builder = |  | ||||||
|                 AlertDialog.Builder(pref.context, R.style.AlertDialogCustom) |  | ||||||
|                     .setView(R.layout.logcat) |  | ||||||
| 
 |  | ||||||
|             val dialog = builder.create() |  | ||||||
|             dialog.show() |  | ||||||
|             val log = StringBuilder() |  | ||||||
|             try { |  | ||||||
|                 //https://developer.android.com/studio/command-line/logcat |  | ||||||
|                 val process = Runtime.getRuntime().exec("logcat -d") |  | ||||||
|                 val bufferedReader = BufferedReader( |  | ||||||
|                     InputStreamReader(process.inputStream) |  | ||||||
|             ) |             ) | ||||||
| 
 |  | ||||||
|                 var line: String? |  | ||||||
|                 while (bufferedReader.readLine().also { line = it } != null) { |  | ||||||
|                     log.append(line) |  | ||||||
|                 } |  | ||||||
|             } catch (e: Exception) { |  | ||||||
|                 logError(e) // kinda ironic |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             val text = log.toString() |  | ||||||
|             dialog.text1?.text = text |  | ||||||
| 
 |  | ||||||
|             dialog.copy_btt?.setOnClickListener { |  | ||||||
|                 val serviceClipboard = |  | ||||||
|                     (activity?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager?) |  | ||||||
|                         ?: return@setOnClickListener |  | ||||||
|                 val clip = ClipData.newPlainText("logcat", text) |  | ||||||
|                 serviceClipboard.setPrimaryClip(clip) |  | ||||||
|                 dialog.dismissSafe(activity) |  | ||||||
|             } |  | ||||||
|             dialog.clear_btt?.setOnClickListener { |  | ||||||
|                 Runtime.getRuntime().exec("logcat -c") |  | ||||||
|                 dialog.dismissSafe(activity) |  | ||||||
|             } |  | ||||||
|             dialog.save_btt?.setOnClickListener { |  | ||||||
|                 var fileStream: OutputStream? = null |  | ||||||
|                 try { |  | ||||||
|                     fileStream = |  | ||||||
|                         VideoDownloadManager.setupStream( |  | ||||||
|                             it.context, |  | ||||||
|                             "logcat", |  | ||||||
|                             null, |  | ||||||
|                             "txt", |  | ||||||
|                             false |  | ||||||
|                         ).fileStream |  | ||||||
|                     fileStream?.writer()?.write(text) |  | ||||||
|                 } catch (e: Exception) { |  | ||||||
|                     logError(e) |  | ||||||
|                 } finally { |  | ||||||
|                     fileStream?.closeQuietly() |  | ||||||
|                     dialog.dismissSafe(activity) |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             dialog.close_btt?.setOnClickListener { |  | ||||||
|                 dialog.dismissSafe(activity) |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.app_layout_key)?.setOnPreferenceClickListener { |  | ||||||
|             val prefNames = resources.getStringArray(R.array.app_layout) |  | ||||||
|             val prefValues = resources.getIntArray(R.array.app_layout_values) |  | ||||||
| 
 |  | ||||||
|             val currentLayout = |  | ||||||
|                 settingsManager.getInt(getString(R.string.app_layout_key), -1) |  | ||||||
| 
 |  | ||||||
|             activity?.showBottomDialog( |  | ||||||
|                 prefNames.toList(), |  | ||||||
|                 prefValues.indexOf(currentLayout), |  | ||||||
|                 getString(R.string.app_layout), |  | ||||||
|                 true, |  | ||||||
|                 {}) { |  | ||||||
|                 try { |  | ||||||
|                     settingsManager.edit() |  | ||||||
|                         .putInt(getString(R.string.app_layout_key), prefValues[it]) |  | ||||||
|                         .apply() |  | ||||||
|                     activity?.recreate() |  | ||||||
|                 } catch (e: Exception) { |  | ||||||
|                     logError(e) |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.backup_key)?.setOnPreferenceClickListener { |  | ||||||
|             activity?.backup() |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.restore_key)?.setOnPreferenceClickListener { |  | ||||||
|             activity?.restorePrompt() |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.primary_color_key)?.setOnPreferenceClickListener { |  | ||||||
|             val prefNames = resources.getStringArray(R.array.themes_overlay_names) |  | ||||||
|             val prefValues = resources.getStringArray(R.array.themes_overlay_names_values) |  | ||||||
| 
 |  | ||||||
|             val currentLayout = |  | ||||||
|                 settingsManager.getString(getString(R.string.primary_color_key), prefValues.first()) |  | ||||||
| 
 |  | ||||||
|             activity?.showDialog( |  | ||||||
|                 prefNames.toList(), |  | ||||||
|                 prefValues.indexOf(currentLayout), |  | ||||||
|                 getString(R.string.primary_color_settings), |  | ||||||
|                 true, |  | ||||||
|                 {}) { |  | ||||||
|                 try { |  | ||||||
|                     settingsManager.edit() |  | ||||||
|                         .putString(getString(R.string.primary_color_key), prefValues[it]) |  | ||||||
|                         .apply() |  | ||||||
|                     activity?.recreate() |  | ||||||
|                 } catch (e: Exception) { |  | ||||||
|                     logError(e) |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.app_theme_key)?.setOnPreferenceClickListener { |  | ||||||
|             val prefNames = resources.getStringArray(R.array.themes_names) |  | ||||||
|             val prefValues = resources.getStringArray(R.array.themes_names_values) |  | ||||||
| 
 |  | ||||||
|             val currentLayout = |  | ||||||
|                 settingsManager.getString(getString(R.string.app_theme_key), prefValues.first()) |  | ||||||
| 
 |  | ||||||
|             activity?.showBottomDialog( |  | ||||||
|                 prefNames.toList(), |  | ||||||
|                 prefValues.indexOf(currentLayout), |  | ||||||
|                 getString(R.string.app_theme_settings), |  | ||||||
|                 true, |  | ||||||
|                 {}) { |  | ||||||
|                 try { |  | ||||||
|                     settingsManager.edit() |  | ||||||
|                         .putString(getString(R.string.app_theme_key), prefValues[it]) |  | ||||||
|                         .apply() |  | ||||||
|                     activity?.recreate() |  | ||||||
|                 } catch (e: Exception) { |  | ||||||
|                     logError(e) |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.quality_pref_key)?.setOnPreferenceClickListener { |  | ||||||
|             val prefValues = Qualities.values().map { it.value }.reversed().toMutableList() |  | ||||||
|             prefValues.remove(Qualities.Unknown.value) |  | ||||||
| 
 |  | ||||||
|             val prefNames = prefValues.map { Qualities.getStringByInt(it) } |  | ||||||
| 
 |  | ||||||
|             val currentQuality = |  | ||||||
|                 settingsManager.getInt( |  | ||||||
|                     getString(R.string.quality_pref_key), |  | ||||||
|                     Qualities.values().last().value |  | ||||||
|                 ) |  | ||||||
| 
 |  | ||||||
|             activity?.showBottomDialog( |  | ||||||
|                 prefNames.toList(), |  | ||||||
|                 prefValues.indexOf(currentQuality), |  | ||||||
|                 getString(R.string.watch_quality_pref), |  | ||||||
|                 true, |  | ||||||
|                 {}) { |  | ||||||
|                 settingsManager.edit().putInt(getString(R.string.quality_pref_key), prefValues[it]) |  | ||||||
|                     .apply() |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.prefer_limit_title_key)?.setOnPreferenceClickListener { |  | ||||||
|             val prefNames = resources.getStringArray(R.array.limit_title_pref_names) |  | ||||||
|             val prefValues = resources.getIntArray(R.array.limit_title_pref_values) |  | ||||||
|             val current = settingsManager.getInt(getString(R.string.prefer_limit_title_key), 0) |  | ||||||
| 
 |  | ||||||
|             activity?.showBottomDialog( |  | ||||||
|                 prefNames.toList(), |  | ||||||
|                 prefValues.indexOf(current), |  | ||||||
|                 getString(R.string.limit_title), |  | ||||||
|                 true, |  | ||||||
|                 {}) { |  | ||||||
|                 settingsManager.edit() |  | ||||||
|                     .putInt(getString(R.string.prefer_limit_title_key), prefValues[it]) |  | ||||||
|                     .apply() |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.dns_key)?.setOnPreferenceClickListener { |  | ||||||
|             val prefNames = resources.getStringArray(R.array.dns_pref) |  | ||||||
|             val prefValues = resources.getIntArray(R.array.dns_pref_values) |  | ||||||
| 
 |  | ||||||
|             val currentDns = |  | ||||||
|                 settingsManager.getInt(getString(R.string.dns_pref), 0) |  | ||||||
| 
 |  | ||||||
|             activity?.showBottomDialog( |  | ||||||
|                 prefNames.toList(), |  | ||||||
|                 prefValues.indexOf(currentDns), |  | ||||||
|                 getString(R.string.dns_pref), |  | ||||||
|                 true, |  | ||||||
|                 {}) { |  | ||||||
|                 settingsManager.edit().putInt(getString(R.string.dns_pref), prefValues[it]).apply() |  | ||||||
|                 (context ?: AcraApplication.context)?.let { ctx -> app.initClient(ctx) } |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         try { |  | ||||||
|             beneneCount = settingsManager.getInt(getString(R.string.benene_count), 0) |  | ||||||
|             getPref(R.string.benene_count)?.let { pref -> |  | ||||||
|                 pref.summary = |  | ||||||
|                     if (beneneCount <= 0) getString(R.string.benene_count_text_none) else getString( |  | ||||||
|                         R.string.benene_count_text |  | ||||||
|                     ).format( |  | ||||||
|                         beneneCount |  | ||||||
|                     ) |  | ||||||
| 
 |  | ||||||
|                 pref.setOnPreferenceClickListener { |  | ||||||
|                     try { |  | ||||||
|                         beneneCount++ |  | ||||||
|                         settingsManager.edit().putInt(getString(R.string.benene_count), beneneCount) |  | ||||||
|                             .apply() |  | ||||||
|                         it.summary = getString(R.string.benene_count_text).format(beneneCount) |  | ||||||
|                     } catch (e: Exception) { |  | ||||||
|                         logError(e) |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     return@setOnPreferenceClickListener true |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } catch (e: Exception) { |  | ||||||
|             e.printStackTrace() |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.manual_check_update_key)?.setOnPreferenceClickListener { |  | ||||||
|             thread { |  | ||||||
|                 if (!requireActivity().runAutoUpdate(false)) { |  | ||||||
|                     activity?.runOnUiThread { |  | ||||||
|                         showToast(activity, R.string.no_update_found, Toast.LENGTH_SHORT) |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         getPref(R.string.locale_key)?.setOnPreferenceClickListener { pref -> |  | ||||||
|             val tempLangs = languages.toMutableList() |  | ||||||
|             if (beneneCount > 100) { |  | ||||||
|                 tempLangs.add(Triple("\uD83E\uDD8D", "mmmm... monke", "mo")) |  | ||||||
|             } |  | ||||||
|             val current = getCurrentLocale() |  | ||||||
|             val languageCodes = tempLangs.map { it.third } |  | ||||||
|             val languageNames = tempLangs.map { (emoji, name, iso) -> |  | ||||||
|                 val flag = emoji.ifBlank { getFlagFromIso(iso) ?: "ERROR" } |  | ||||||
| 
 |  | ||||||
|                 "$flag $name" |  | ||||||
|             } |  | ||||||
|             val index = languageCodes.indexOf(current) |  | ||||||
| 
 |  | ||||||
|             activity?.showDialog( |  | ||||||
|                 languageNames, index, getString(R.string.app_language), true, { } |  | ||||||
|             ) { languageIndex -> |  | ||||||
|                 try { |  | ||||||
|                     val code = languageCodes[languageIndex] |  | ||||||
|                     setLocale(activity, code) |  | ||||||
|                     settingsManager.edit().putString(getString(R.string.locale_key), code).apply() |  | ||||||
|                     activity?.recreate() |  | ||||||
|                 } catch (e: Exception) { |  | ||||||
|                     logError(e) |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             return@setOnPreferenceClickListener true |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun getCurrentLocale(): String { |     override fun onCreateView( | ||||||
|         val res = requireContext().resources |         inflater: LayoutInflater, | ||||||
| // Change locale settings in the app. |         container: ViewGroup?, | ||||||
|         // val dm = res.displayMetrics |         savedInstanceState: Bundle?, | ||||||
|         val conf = res.configuration |     ): View? { | ||||||
|         return conf?.locale?.language ?: "en" |         return inflater.inflate(R.layout.main_settings, container, false) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||||
|  |         fun navigate(id: Int) { | ||||||
|  |             activity?.navigate(id, Bundle()) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         settings_player?.setOnClickListener { | ||||||
|  |             navigate(R.id.action_navigation_settings_to_navigation_settings_player) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         settings_credits?.setOnClickListener { | ||||||
|  |             navigate(R.id.action_navigation_settings_to_navigation_settings_account) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         settings_ui?.setOnClickListener { | ||||||
|  |             navigate(R.id.action_navigation_settings_to_navigation_settings_ui) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         settings_lang?.setOnClickListener { | ||||||
|  |             navigate(R.id.action_navigation_settings_to_navigation_settings_lang) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         settings_nginx?.setOnClickListener { | ||||||
|  |             navigate(R.id.action_navigation_settings_to_navigation_settings_nginx) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         settings_updates?.setOnClickListener { | ||||||
|  |             navigate(R.id.action_navigation_settings_to_navigation_settings_updates) | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -0,0 +1,175 @@ | ||||||
|  | package com.lagradost.cloudstream3.ui.settings | ||||||
|  | 
 | ||||||
|  | import android.os.Bundle | ||||||
|  | import androidx.preference.PreferenceFragmentCompat | ||||||
|  | import androidx.preference.PreferenceManager | ||||||
|  | import com.lagradost.cloudstream3.* | ||||||
|  | import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings | ||||||
|  | import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings | ||||||
|  | import com.lagradost.cloudstream3.mvvm.logError | ||||||
|  | import com.lagradost.cloudstream3.network.initClient | ||||||
|  | import com.lagradost.cloudstream3.ui.APIRepository | ||||||
|  | import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.getPref | ||||||
|  | import com.lagradost.cloudstream3.utils.HOMEPAGE_API | ||||||
|  | import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog | ||||||
|  | import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog | ||||||
|  | import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showMultiDialog | ||||||
|  | import com.lagradost.cloudstream3.utils.SubtitleHelper | ||||||
|  | import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard | ||||||
|  | 
 | ||||||
|  | class SettingsLang : PreferenceFragmentCompat() { | ||||||
|  |     // idk, if you find a way of automating this it would be great | ||||||
|  |     // https://www.iemoji.com/view/emoji/1794/flags/antarctica | ||||||
|  |     // Emoji Character Encoding Data --> C/C++/Java Src | ||||||
|  |     // https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes leave blank for auto | ||||||
|  |     private val languages = arrayListOf( | ||||||
|  |         Triple("", "Spanish", "es"), | ||||||
|  |         Triple("", "English", "en"), | ||||||
|  |         Triple("", "Viet Nam", "vi"), | ||||||
|  |         Triple("", "Dutch", "nl"), | ||||||
|  |         Triple("", "French", "fr"), | ||||||
|  |         Triple("", "Greek", "el"), | ||||||
|  |         Triple("", "Swedish", "sv"), | ||||||
|  |         Triple("", "Tagalog", "tl"), | ||||||
|  |         Triple("", "Polish", "pl"), | ||||||
|  |         Triple("", "Hindi", "hi"), | ||||||
|  |         Triple("", "Malayalam", "ml"), | ||||||
|  |         Triple("", "Norsk", "no"), | ||||||
|  |         Triple("", "German", "de"), | ||||||
|  |         Triple("", "Arabic", "ar"), | ||||||
|  |         Triple("", "Turkish", "tr"), | ||||||
|  |         Triple("", "Macedonian", "mk"), | ||||||
|  |         Triple("\uD83C\uDDE7\uD83C\uDDF7", "Portuguese (Brazil)", "pt"), | ||||||
|  |         Triple("", "Romanian", "ro"), | ||||||
|  |         Triple("", "Italian", "it"), | ||||||
|  |         Triple("", "Chinese", "zh"), | ||||||
|  |     ).sortedBy { it.second } //ye, we go alphabetical, so ppl don't put their lang on top | ||||||
|  | 
 | ||||||
|  |     private fun getCurrentLocale(): String { | ||||||
|  |         val res = requireContext().resources | ||||||
|  | // Change locale settings in the app. | ||||||
|  |         // val dm = res.displayMetrics | ||||||
|  |         val conf = res.configuration | ||||||
|  |         return conf?.locale?.language ?: "en" | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { | ||||||
|  |         hideKeyboard() | ||||||
|  |         setPreferencesFromResource(R.xml.settings_media_lang, rootKey) | ||||||
|  |         val settingsManager = PreferenceManager.getDefaultSharedPreferences(requireContext()) | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.display_sub_key)?.setOnPreferenceClickListener { | ||||||
|  |             activity?.getApiDubstatusSettings()?.let { current -> | ||||||
|  |                 val dublist = DubStatus.values() | ||||||
|  |                 val names = dublist.map { it.name } | ||||||
|  | 
 | ||||||
|  |                 val currentList = ArrayList<Int>() | ||||||
|  |                 for (i in current) { | ||||||
|  |                     currentList.add(dublist.indexOf(i)) | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 activity?.showMultiDialog( | ||||||
|  |                     names, | ||||||
|  |                     currentList, | ||||||
|  |                     getString(R.string.display_subbed_dubbed_settings), | ||||||
|  |                     {}) { selectedList -> | ||||||
|  |                     APIRepository.dubStatusActive = selectedList.map { dublist[it] }.toHashSet() | ||||||
|  | 
 | ||||||
|  |                     settingsManager.edit().putStringSet( | ||||||
|  |                         this.getString(R.string.display_sub_key), | ||||||
|  |                         selectedList.map { names[it] }.toMutableSet() | ||||||
|  |                     ).apply() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.prefer_media_type_key)?.setOnPreferenceClickListener { | ||||||
|  |             val prefNames = resources.getStringArray(R.array.media_type_pref) | ||||||
|  |             val prefValues = resources.getIntArray(R.array.media_type_pref_values) | ||||||
|  | 
 | ||||||
|  |             val currentPrefMedia = | ||||||
|  |                 settingsManager.getInt(getString(R.string.prefer_media_type_key), 0) | ||||||
|  | 
 | ||||||
|  |             activity?.showBottomDialog( | ||||||
|  |                 prefNames.toList(), | ||||||
|  |                 prefValues.indexOf(currentPrefMedia), | ||||||
|  |                 getString(R.string.preferred_media_settings), | ||||||
|  |                 true, | ||||||
|  |                 {}) { | ||||||
|  |                 settingsManager.edit() | ||||||
|  |                     .putInt(getString(R.string.prefer_media_type_key), prefValues[it]) | ||||||
|  |                     .apply() | ||||||
|  | 
 | ||||||
|  |                 AcraApplication.removeKey(HOMEPAGE_API) | ||||||
|  |                 (context ?: AcraApplication.context)?.let { ctx -> app.initClient(ctx) } | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.locale_key)?.setOnPreferenceClickListener { pref -> | ||||||
|  |             val tempLangs = languages.toMutableList() | ||||||
|  |             //if (beneneCount > 100) { | ||||||
|  |             //    tempLangs.add(Triple("\uD83E\uDD8D", "mmmm... monke", "mo")) | ||||||
|  |             //} | ||||||
|  |             val current = getCurrentLocale() | ||||||
|  |             val languageCodes = tempLangs.map { it.third } | ||||||
|  |             val languageNames = tempLangs.map { (emoji, name, iso) -> | ||||||
|  |                 val flag = emoji.ifBlank { SubtitleHelper.getFlagFromIso(iso) ?: "ERROR" } | ||||||
|  | 
 | ||||||
|  |                 "$flag $name" | ||||||
|  |             } | ||||||
|  |             val index = languageCodes.indexOf(current) | ||||||
|  | 
 | ||||||
|  |             activity?.showDialog( | ||||||
|  |                 languageNames, index, getString(R.string.app_language), true, { } | ||||||
|  |             ) { languageIndex -> | ||||||
|  |                 try { | ||||||
|  |                     val code = languageCodes[languageIndex] | ||||||
|  |                     CommonActivity.setLocale(activity, code) | ||||||
|  |                     settingsManager.edit().putString(getString(R.string.locale_key), code).apply() | ||||||
|  |                     activity?.recreate() | ||||||
|  |                 } catch (e: Exception) { | ||||||
|  |                     logError(e) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.provider_lang_key)?.setOnPreferenceClickListener { | ||||||
|  |             activity?.getApiProviderLangSettings()?.let { current -> | ||||||
|  |                 val allLangs = HashSet<String>() | ||||||
|  |                 for (api in APIHolder.apis) { | ||||||
|  |                     allLangs.add(api.lang) | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 val currentList = ArrayList<Int>() | ||||||
|  |                 for (i in current) { | ||||||
|  |                     currentList.add(allLangs.indexOf(i)) | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 val names = allLangs.map { | ||||||
|  |                     val emoji = SubtitleHelper.getFlagFromIso(it) | ||||||
|  |                     val name = SubtitleHelper.fromTwoLettersToLanguage(it) | ||||||
|  |                     val fullName = "$emoji $name" | ||||||
|  |                     Pair(it, fullName) | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 activity?.showMultiDialog( | ||||||
|  |                     names.map { it.second }, | ||||||
|  |                     currentList, | ||||||
|  |                     getString(R.string.provider_lang_settings), | ||||||
|  |                     {}) { selectedList -> | ||||||
|  |                     settingsManager.edit().putStringSet( | ||||||
|  |                         this.getString(R.string.provider_lang_key), | ||||||
|  |                         selectedList.map { names[it].first }.toMutableSet() | ||||||
|  |                     ).apply() | ||||||
|  |                     //APIRepository.providersActive = it.context.getApiSettings() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,54 @@ | ||||||
|  | package com.lagradost.cloudstream3.ui.settings | ||||||
|  | 
 | ||||||
|  | import android.os.Bundle | ||||||
|  | import androidx.preference.PreferenceFragmentCompat | ||||||
|  | import androidx.preference.PreferenceManager | ||||||
|  | import com.lagradost.cloudstream3.AcraApplication | ||||||
|  | import com.lagradost.cloudstream3.R | ||||||
|  | import com.lagradost.cloudstream3.app | ||||||
|  | import com.lagradost.cloudstream3.network.initClient | ||||||
|  | import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.getPref | ||||||
|  | import com.lagradost.cloudstream3.utils.HOMEPAGE_API | ||||||
|  | import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog | ||||||
|  | import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showNginxTextInputDialog | ||||||
|  | import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard | ||||||
|  | 
 | ||||||
|  | class SettingsNginx : PreferenceFragmentCompat() { | ||||||
|  |     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { | ||||||
|  |         hideKeyboard() | ||||||
|  |         setPreferencesFromResource(R.xml.settings_nginx, rootKey) | ||||||
|  |         val settingsManager = PreferenceManager.getDefaultSharedPreferences(requireContext()) | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.nginx_credentials)?.setOnPreferenceClickListener { | ||||||
|  |             activity?.showNginxTextInputDialog( | ||||||
|  |                 settingsManager.getString( | ||||||
|  |                     getString(R.string.nginx_credentials_title), | ||||||
|  |                     "Nginx Credentials" | ||||||
|  |                 ).toString(), | ||||||
|  |                 settingsManager.getString(getString(R.string.nginx_credentials), "") | ||||||
|  |                     .toString(),  // key: the actual you use rn | ||||||
|  |                 android.text.InputType.TYPE_TEXT_VARIATION_URI, | ||||||
|  |                 {}) { | ||||||
|  |                 settingsManager.edit() | ||||||
|  |                     .putString(getString(R.string.nginx_credentials), it) | ||||||
|  |                     .apply()  // change the stored url in nginx_url_key to it | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.nginx_url_key)?.setOnPreferenceClickListener { | ||||||
|  |             activity?.showNginxTextInputDialog( | ||||||
|  |                 settingsManager.getString(getString(R.string.nginx_url_pref), "Nginx server url") | ||||||
|  |                     .toString(), | ||||||
|  |                 settingsManager.getString(getString(R.string.nginx_url_key), "") | ||||||
|  |                     .toString(),  // key: the actual you use rn | ||||||
|  |                 android.text.InputType.TYPE_TEXT_VARIATION_URI,  // uri | ||||||
|  |                 {}) { | ||||||
|  |                 settingsManager.edit() | ||||||
|  |                     .putString(getString(R.string.nginx_url_key), it) | ||||||
|  |                     .apply()  // change the stored url in nginx_url_key to it | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,295 @@ | ||||||
|  | package com.lagradost.cloudstream3.ui.settings | ||||||
|  | 
 | ||||||
|  | import android.content.Intent | ||||||
|  | import android.net.Uri | ||||||
|  | import android.os.Build | ||||||
|  | import android.os.Bundle | ||||||
|  | import android.os.Environment | ||||||
|  | import androidx.activity.result.contract.ActivityResultContracts | ||||||
|  | import androidx.preference.PreferenceFragmentCompat | ||||||
|  | import androidx.preference.PreferenceManager | ||||||
|  | import com.hippo.unifile.UniFile | ||||||
|  | import com.lagradost.cloudstream3.AcraApplication | ||||||
|  | import com.lagradost.cloudstream3.R | ||||||
|  | import com.lagradost.cloudstream3.app | ||||||
|  | import com.lagradost.cloudstream3.mvvm.logError | ||||||
|  | import com.lagradost.cloudstream3.mvvm.normalSafeApiCall | ||||||
|  | import com.lagradost.cloudstream3.network.initClient | ||||||
|  | import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.getFolderSize | ||||||
|  | import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.getPref | ||||||
|  | import com.lagradost.cloudstream3.ui.subtitles.ChromecastSubtitlesFragment | ||||||
|  | import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment | ||||||
|  | import com.lagradost.cloudstream3.utils.Qualities | ||||||
|  | import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog | ||||||
|  | import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog | ||||||
|  | import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard | ||||||
|  | import com.lagradost.cloudstream3.utils.VideoDownloadManager | ||||||
|  | import com.lagradost.cloudstream3.utils.VideoDownloadManager.getBasePath | ||||||
|  | import java.io.File | ||||||
|  | 
 | ||||||
|  | class SettingsPlayer : PreferenceFragmentCompat() { | ||||||
|  |     // Open file picker | ||||||
|  |     private val pathPicker = | ||||||
|  |         registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri -> | ||||||
|  |             // It lies, it can be null if file manager quits. | ||||||
|  |             if (uri == null) return@registerForActivityResult | ||||||
|  |             val context = context ?: AcraApplication.context ?: return@registerForActivityResult | ||||||
|  |             // RW perms for the path | ||||||
|  |             val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or | ||||||
|  |                     Intent.FLAG_GRANT_WRITE_URI_PERMISSION | ||||||
|  | 
 | ||||||
|  |             context.contentResolver.takePersistableUriPermission(uri, flags) | ||||||
|  | 
 | ||||||
|  |             val file = UniFile.fromUri(context, uri) | ||||||
|  |             println("Selected URI path: $uri - Full path: ${file.filePath}") | ||||||
|  | 
 | ||||||
|  |             // Stores the real URI using download_path_key | ||||||
|  |             // Important that the URI is stored instead of filepath due to permissions. | ||||||
|  |             PreferenceManager.getDefaultSharedPreferences(context) | ||||||
|  |                 .edit().putString(getString(R.string.download_path_key), uri.toString()).apply() | ||||||
|  | 
 | ||||||
|  |             // From URI -> File path | ||||||
|  |             // File path here is purely for cosmetic purposes in settings | ||||||
|  |             (file.filePath ?: uri.toString()).let { | ||||||
|  |                 PreferenceManager.getDefaultSharedPreferences(context) | ||||||
|  |                     .edit().putString(getString(R.string.download_path_pref), it).apply() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { | ||||||
|  |         hideKeyboard() | ||||||
|  |         setPreferencesFromResource(R.xml.settings_player, rootKey) | ||||||
|  |         val settingsManager = PreferenceManager.getDefaultSharedPreferences(requireContext()) | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.video_buffer_length_key)?.setOnPreferenceClickListener { | ||||||
|  |             val prefNames = resources.getStringArray(R.array.video_buffer_length_names) | ||||||
|  |             val prefValues = resources.getIntArray(R.array.video_buffer_length_values) | ||||||
|  | 
 | ||||||
|  |             val currentPrefSize = | ||||||
|  |                 settingsManager.getInt(getString(R.string.video_buffer_length_key), 0) | ||||||
|  | 
 | ||||||
|  |             activity?.showDialog( | ||||||
|  |                 prefNames.toList(), | ||||||
|  |                 prefValues.indexOf(currentPrefSize), | ||||||
|  |                 getString(R.string.video_buffer_length_settings), | ||||||
|  |                 true, | ||||||
|  |                 {}) { | ||||||
|  |                 settingsManager.edit() | ||||||
|  |                     .putInt(getString(R.string.video_buffer_length_key), prefValues[it]) | ||||||
|  |                     .apply() | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  |         getPref(R.string.dns_key)?.setOnPreferenceClickListener { | ||||||
|  |             val prefNames = resources.getStringArray(R.array.dns_pref) | ||||||
|  |             val prefValues = resources.getIntArray(R.array.dns_pref_values) | ||||||
|  | 
 | ||||||
|  |             val currentDns = | ||||||
|  |                 settingsManager.getInt(getString(R.string.dns_pref), 0) | ||||||
|  | 
 | ||||||
|  |             activity?.showBottomDialog( | ||||||
|  |                 prefNames.toList(), | ||||||
|  |                 prefValues.indexOf(currentDns), | ||||||
|  |                 getString(R.string.dns_pref), | ||||||
|  |                 true, | ||||||
|  |                 {}) { | ||||||
|  |                 settingsManager.edit().putInt(getString(R.string.dns_pref), prefValues[it]).apply() | ||||||
|  |                 (context ?: AcraApplication.context)?.let { ctx -> app.initClient(ctx) } | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.prefer_limit_title_key)?.setOnPreferenceClickListener { | ||||||
|  |             val prefNames = resources.getStringArray(R.array.limit_title_pref_names) | ||||||
|  |             val prefValues = resources.getIntArray(R.array.limit_title_pref_values) | ||||||
|  |             val current = settingsManager.getInt(getString(R.string.prefer_limit_title_key), 0) | ||||||
|  | 
 | ||||||
|  |             activity?.showBottomDialog( | ||||||
|  |                 prefNames.toList(), | ||||||
|  |                 prefValues.indexOf(current), | ||||||
|  |                 getString(R.string.limit_title), | ||||||
|  |                 true, | ||||||
|  |                 {}) { | ||||||
|  |                 settingsManager.edit() | ||||||
|  |                     .putInt(getString(R.string.prefer_limit_title_key), prefValues[it]) | ||||||
|  |                     .apply() | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /*(getPref(R.string.double_tap_seek_time_key) as? SeekBarPreference?)?.let { | ||||||
|  | 
 | ||||||
|  |         }*/ | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.prefer_limit_title_rez_key)?.setOnPreferenceClickListener { | ||||||
|  |             val prefNames = resources.getStringArray(R.array.limit_title_rez_pref_names) | ||||||
|  |             val prefValues = resources.getIntArray(R.array.limit_title_rez_pref_values) | ||||||
|  |             val current = settingsManager.getInt(getString(R.string.prefer_limit_title_rez_key), 3) | ||||||
|  | 
 | ||||||
|  |             activity?.showBottomDialog( | ||||||
|  |                 prefNames.toList(), | ||||||
|  |                 prefValues.indexOf(current), | ||||||
|  |                 getString(R.string.limit_title_rez), | ||||||
|  |                 true, | ||||||
|  |                 {}) { | ||||||
|  |                 settingsManager.edit() | ||||||
|  |                     .putInt(getString(R.string.prefer_limit_title_rez_key), prefValues[it]) | ||||||
|  |                     .apply() | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.quality_pref_key)?.setOnPreferenceClickListener { | ||||||
|  |             val prefValues = Qualities.values().map { it.value }.reversed().toMutableList() | ||||||
|  |             prefValues.remove(Qualities.Unknown.value) | ||||||
|  | 
 | ||||||
|  |             val prefNames = prefValues.map { Qualities.getStringByInt(it) } | ||||||
|  | 
 | ||||||
|  |             val currentQuality = | ||||||
|  |                 settingsManager.getInt( | ||||||
|  |                     getString(R.string.quality_pref_key), | ||||||
|  |                     Qualities.values().last().value | ||||||
|  |                 ) | ||||||
|  | 
 | ||||||
|  |             activity?.showBottomDialog( | ||||||
|  |                 prefNames.toList(), | ||||||
|  |                 prefValues.indexOf(currentQuality), | ||||||
|  |                 getString(R.string.watch_quality_pref), | ||||||
|  |                 true, | ||||||
|  |                 {}) { | ||||||
|  |                 settingsManager.edit().putInt(getString(R.string.quality_pref_key), prefValues[it]) | ||||||
|  |                     .apply() | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.subtitle_settings_key)?.setOnPreferenceClickListener { | ||||||
|  |             SubtitlesFragment.push(activity, false) | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.subtitle_settings_chromecast_key)?.setOnPreferenceClickListener { | ||||||
|  |             ChromecastSubtitlesFragment.push(activity, false) | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.video_buffer_disk_key)?.setOnPreferenceClickListener { | ||||||
|  |             val prefNames = resources.getStringArray(R.array.video_buffer_size_names) | ||||||
|  |             val prefValues = resources.getIntArray(R.array.video_buffer_size_values) | ||||||
|  | 
 | ||||||
|  |             val currentPrefSize = | ||||||
|  |                 settingsManager.getInt(getString(R.string.video_buffer_disk_key), 0) | ||||||
|  | 
 | ||||||
|  |             activity?.showDialog( | ||||||
|  |                 prefNames.toList(), | ||||||
|  |                 prefValues.indexOf(currentPrefSize), | ||||||
|  |                 getString(R.string.video_buffer_disk_settings), | ||||||
|  |                 true, | ||||||
|  |                 {}) { | ||||||
|  |                 settingsManager.edit() | ||||||
|  |                     .putInt(getString(R.string.video_buffer_disk_key), prefValues[it]) | ||||||
|  |                     .apply() | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  |         getPref(R.string.video_buffer_size_key)?.setOnPreferenceClickListener { | ||||||
|  |             val prefNames = resources.getStringArray(R.array.video_buffer_size_names) | ||||||
|  |             val prefValues = resources.getIntArray(R.array.video_buffer_size_values) | ||||||
|  | 
 | ||||||
|  |             val currentPrefSize = | ||||||
|  |                 settingsManager.getInt(getString(R.string.video_buffer_size_key), 0) | ||||||
|  | 
 | ||||||
|  |             activity?.showDialog( | ||||||
|  |                 prefNames.toList(), | ||||||
|  |                 prefValues.indexOf(currentPrefSize), | ||||||
|  |                 getString(R.string.video_buffer_size_settings), | ||||||
|  |                 true, | ||||||
|  |                 {}) { | ||||||
|  |                 settingsManager.edit() | ||||||
|  |                     .putInt(getString(R.string.video_buffer_size_key), prefValues[it]) | ||||||
|  |                     .apply() | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.video_buffer_clear_key)?.let { pref -> | ||||||
|  |             val cacheDir = context?.cacheDir ?: return@let | ||||||
|  | 
 | ||||||
|  |             fun updateSummery() { | ||||||
|  |                 try { | ||||||
|  |                     pref.summary = | ||||||
|  |                         getString(R.string.mb_format).format(getFolderSize(cacheDir) / (1024L * 1024L)) | ||||||
|  |                 } catch (e: Exception) { | ||||||
|  |                     logError(e) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             updateSummery() | ||||||
|  | 
 | ||||||
|  |             pref.setOnPreferenceClickListener { | ||||||
|  |                 try { | ||||||
|  |                     cacheDir.deleteRecursively() | ||||||
|  |                     updateSummery() | ||||||
|  |                 } catch (e: Exception) { | ||||||
|  |                     logError(e) | ||||||
|  |                 } | ||||||
|  |                 return@setOnPreferenceClickListener true | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         fun getDownloadDirs(): List<String> { | ||||||
|  |             return normalSafeApiCall { | ||||||
|  |                 val defaultDir = VideoDownloadManager.getDownloadDir()?.filePath | ||||||
|  | 
 | ||||||
|  |                 // app_name_download_path = Cloudstream and does not change depending on release. | ||||||
|  |                 // DOES NOT WORK ON SCOPED STORAGE. | ||||||
|  |                 val secondaryDir = | ||||||
|  |                     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) null else Environment.getExternalStorageDirectory().absolutePath + | ||||||
|  |                             File.separator + resources.getString(R.string.app_name_download_path) | ||||||
|  |                 val first = listOf(defaultDir, secondaryDir) | ||||||
|  |                 (try { | ||||||
|  |                     val currentDir = context?.getBasePath()?.let { it.first?.filePath ?: it.second } | ||||||
|  | 
 | ||||||
|  |                     (first + | ||||||
|  |                             requireContext().getExternalFilesDirs("").mapNotNull { it.path } + | ||||||
|  |                             currentDir) | ||||||
|  |                 } catch (e: Exception) { | ||||||
|  |                     first | ||||||
|  |                 }).filterNotNull().distinct() | ||||||
|  |             } ?: emptyList() | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.download_path_key)?.setOnPreferenceClickListener { | ||||||
|  |             val dirs = getDownloadDirs() | ||||||
|  | 
 | ||||||
|  |             val currentDir = | ||||||
|  |                 settingsManager.getString(getString(R.string.download_path_pref), null) | ||||||
|  |                     ?: VideoDownloadManager.getDownloadDir().toString() | ||||||
|  | 
 | ||||||
|  |             activity?.showBottomDialog( | ||||||
|  |                 dirs + listOf("Custom"), | ||||||
|  |                 dirs.indexOf(currentDir), | ||||||
|  |                 getString(R.string.download_path_pref), | ||||||
|  |                 true, | ||||||
|  |                 {}) { | ||||||
|  |                 // Last = custom | ||||||
|  |                 if (it == dirs.size) { | ||||||
|  |                     try { | ||||||
|  |                         pathPicker.launch(Uri.EMPTY) | ||||||
|  |                     } catch (e: Exception) { | ||||||
|  |                         logError(e) | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     // Sets both visual and actual paths. | ||||||
|  |                     // key = used path | ||||||
|  |                     // pref = visual path | ||||||
|  |                     settingsManager.edit() | ||||||
|  |                         .putString(getString(R.string.download_path_key), dirs[it]).apply() | ||||||
|  |                     settingsManager.edit() | ||||||
|  |                         .putString(getString(R.string.download_path_pref), dirs[it]).apply() | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,123 @@ | ||||||
|  | package com.lagradost.cloudstream3.ui.settings | ||||||
|  | 
 | ||||||
|  | import android.os.Bundle | ||||||
|  | import androidx.preference.PreferenceFragmentCompat | ||||||
|  | import androidx.preference.PreferenceManager | ||||||
|  | import com.lagradost.cloudstream3.R | ||||||
|  | import com.lagradost.cloudstream3.mvvm.logError | ||||||
|  | import com.lagradost.cloudstream3.ui.search.SearchResultBuilder | ||||||
|  | import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.getPref | ||||||
|  | import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog | ||||||
|  | import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog | ||||||
|  | import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showMultiDialog | ||||||
|  | import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard | ||||||
|  | 
 | ||||||
|  | class SettingsUI : PreferenceFragmentCompat() { | ||||||
|  |     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { | ||||||
|  |         hideKeyboard() | ||||||
|  |         setPreferencesFromResource(R.xml.settins_ui, rootKey) | ||||||
|  |         val settingsManager = PreferenceManager.getDefaultSharedPreferences(requireContext()) | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.poster_ui_key)?.setOnPreferenceClickListener { | ||||||
|  |             val prefNames = resources.getStringArray(R.array.poster_ui_options) | ||||||
|  |             val keys = resources.getStringArray(R.array.poster_ui_options_values) | ||||||
|  |             val prefValues = keys.map { | ||||||
|  |                 settingsManager.getBoolean(it, true) | ||||||
|  |             }.mapIndexedNotNull { index, b -> | ||||||
|  |                 if (b) { | ||||||
|  |                     index | ||||||
|  |                 } else null | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             activity?.showMultiDialog( | ||||||
|  |                 prefNames.toList(), | ||||||
|  |                 prefValues, | ||||||
|  |                 getString(R.string.poster_ui_settings), | ||||||
|  |                 {}) { list -> | ||||||
|  |                 val edit = settingsManager.edit() | ||||||
|  |                 for ((i, key) in keys.withIndex()) { | ||||||
|  |                     edit.putBoolean(key, list.contains(i)) | ||||||
|  |                 } | ||||||
|  |                 edit.apply() | ||||||
|  |                 SearchResultBuilder.updateCache(it.context) | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.app_layout_key)?.setOnPreferenceClickListener { | ||||||
|  |             val prefNames = resources.getStringArray(R.array.app_layout) | ||||||
|  |             val prefValues = resources.getIntArray(R.array.app_layout_values) | ||||||
|  | 
 | ||||||
|  |             val currentLayout = | ||||||
|  |                 settingsManager.getInt(getString(R.string.app_layout_key), -1) | ||||||
|  | 
 | ||||||
|  |             activity?.showBottomDialog( | ||||||
|  |                 prefNames.toList(), | ||||||
|  |                 prefValues.indexOf(currentLayout), | ||||||
|  |                 getString(R.string.app_layout), | ||||||
|  |                 true, | ||||||
|  |                 {}) { | ||||||
|  |                 try { | ||||||
|  |                     settingsManager.edit() | ||||||
|  |                         .putInt(getString(R.string.app_layout_key), prefValues[it]) | ||||||
|  |                         .apply() | ||||||
|  |                     activity?.recreate() | ||||||
|  |                 } catch (e: Exception) { | ||||||
|  |                     logError(e) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.app_theme_key)?.setOnPreferenceClickListener { | ||||||
|  |             val prefNames = resources.getStringArray(R.array.themes_names) | ||||||
|  |             val prefValues = resources.getStringArray(R.array.themes_names_values) | ||||||
|  | 
 | ||||||
|  |             val currentLayout = | ||||||
|  |                 settingsManager.getString(getString(R.string.app_theme_key), prefValues.first()) | ||||||
|  | 
 | ||||||
|  |             activity?.showBottomDialog( | ||||||
|  |                 prefNames.toList(), | ||||||
|  |                 prefValues.indexOf(currentLayout), | ||||||
|  |                 getString(R.string.app_theme_settings), | ||||||
|  |                 true, | ||||||
|  |                 {}) { | ||||||
|  |                 try { | ||||||
|  |                     settingsManager.edit() | ||||||
|  |                         .putString(getString(R.string.app_theme_key), prefValues[it]) | ||||||
|  |                         .apply() | ||||||
|  |                     activity?.recreate() | ||||||
|  |                 } catch (e: Exception) { | ||||||
|  |                     logError(e) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  |         getPref(R.string.primary_color_key)?.setOnPreferenceClickListener { | ||||||
|  |             val prefNames = resources.getStringArray(R.array.themes_overlay_names) | ||||||
|  |             val prefValues = resources.getStringArray(R.array.themes_overlay_names_values) | ||||||
|  | 
 | ||||||
|  |             val currentLayout = | ||||||
|  |                 settingsManager.getString(getString(R.string.primary_color_key), prefValues.first()) | ||||||
|  | 
 | ||||||
|  |             activity?.showDialog( | ||||||
|  |                 prefNames.toList(), | ||||||
|  |                 prefValues.indexOf(currentLayout), | ||||||
|  |                 getString(R.string.primary_color_settings), | ||||||
|  |                 true, | ||||||
|  |                 {}) { | ||||||
|  |                 try { | ||||||
|  |                     settingsManager.edit() | ||||||
|  |                         .putString(getString(R.string.primary_color_key), prefValues[it]) | ||||||
|  |                         .apply() | ||||||
|  |                     activity?.recreate() | ||||||
|  |                 } catch (e: Exception) { | ||||||
|  |                     logError(e) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,118 @@ | ||||||
|  | package com.lagradost.cloudstream3.ui.settings | ||||||
|  | 
 | ||||||
|  | import android.content.ClipData | ||||||
|  | import android.content.ClipboardManager | ||||||
|  | import android.content.Context | ||||||
|  | import android.os.Bundle | ||||||
|  | import android.widget.Toast | ||||||
|  | import androidx.appcompat.app.AlertDialog | ||||||
|  | import androidx.preference.PreferenceFragmentCompat | ||||||
|  | import androidx.preference.PreferenceManager | ||||||
|  | import com.lagradost.cloudstream3.CommonActivity | ||||||
|  | import com.lagradost.cloudstream3.R | ||||||
|  | import com.lagradost.cloudstream3.mvvm.logError | ||||||
|  | import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.getPref | ||||||
|  | import com.lagradost.cloudstream3.utils.BackupUtils.backup | ||||||
|  | import com.lagradost.cloudstream3.utils.BackupUtils.restorePrompt | ||||||
|  | import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate | ||||||
|  | import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe | ||||||
|  | import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard | ||||||
|  | import com.lagradost.cloudstream3.utils.VideoDownloadManager | ||||||
|  | import kotlinx.android.synthetic.main.logcat.* | ||||||
|  | import okhttp3.internal.closeQuietly | ||||||
|  | import java.io.BufferedReader | ||||||
|  | import java.io.InputStreamReader | ||||||
|  | import java.io.OutputStream | ||||||
|  | import kotlin.concurrent.thread | ||||||
|  | 
 | ||||||
|  | class SettingsUpdates : PreferenceFragmentCompat() { | ||||||
|  |     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { | ||||||
|  |         hideKeyboard() | ||||||
|  |         setPreferencesFromResource(R.xml.settings_updates, rootKey) | ||||||
|  |         val settingsManager = PreferenceManager.getDefaultSharedPreferences(requireContext()) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.backup_key)?.setOnPreferenceClickListener { | ||||||
|  |             activity?.backup() | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.restore_key)?.setOnPreferenceClickListener { | ||||||
|  |             activity?.restorePrompt() | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  |         getPref(R.string.show_logcat_key)?.setOnPreferenceClickListener { pref -> | ||||||
|  |             val builder = | ||||||
|  |                 AlertDialog.Builder(pref.context, R.style.AlertDialogCustom) | ||||||
|  |                     .setView(R.layout.logcat) | ||||||
|  | 
 | ||||||
|  |             val dialog = builder.create() | ||||||
|  |             dialog.show() | ||||||
|  |             val log = StringBuilder() | ||||||
|  |             try { | ||||||
|  |                 //https://developer.android.com/studio/command-line/logcat | ||||||
|  |                 val process = Runtime.getRuntime().exec("logcat -d") | ||||||
|  |                 val bufferedReader = BufferedReader( | ||||||
|  |                     InputStreamReader(process.inputStream) | ||||||
|  |                 ) | ||||||
|  | 
 | ||||||
|  |                 var line: String? | ||||||
|  |                 while (bufferedReader.readLine().also { line = it } != null) { | ||||||
|  |                     log.append(line) | ||||||
|  |                 } | ||||||
|  |             } catch (e: Exception) { | ||||||
|  |                 logError(e) // kinda ironic | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             val text = log.toString() | ||||||
|  |             dialog.text1?.text = text | ||||||
|  | 
 | ||||||
|  |             dialog.copy_btt?.setOnClickListener { | ||||||
|  |                 val serviceClipboard = | ||||||
|  |                     (activity?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager?) | ||||||
|  |                         ?: return@setOnClickListener | ||||||
|  |                 val clip = ClipData.newPlainText("logcat", text) | ||||||
|  |                 serviceClipboard.setPrimaryClip(clip) | ||||||
|  |                 dialog.dismissSafe(activity) | ||||||
|  |             } | ||||||
|  |             dialog.clear_btt?.setOnClickListener { | ||||||
|  |                 Runtime.getRuntime().exec("logcat -c") | ||||||
|  |                 dialog.dismissSafe(activity) | ||||||
|  |             } | ||||||
|  |             dialog.save_btt?.setOnClickListener { | ||||||
|  |                 var fileStream: OutputStream? = null | ||||||
|  |                 try { | ||||||
|  |                     fileStream = | ||||||
|  |                         VideoDownloadManager.setupStream( | ||||||
|  |                             it.context, | ||||||
|  |                             "logcat", | ||||||
|  |                             null, | ||||||
|  |                             "txt", | ||||||
|  |                             false | ||||||
|  |                         ).fileStream | ||||||
|  |                     fileStream?.writer()?.write(text) | ||||||
|  |                 } catch (e: Exception) { | ||||||
|  |                     logError(e) | ||||||
|  |                 } finally { | ||||||
|  |                     fileStream?.closeQuietly() | ||||||
|  |                     dialog.dismissSafe(activity) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             dialog.close_btt?.setOnClickListener { | ||||||
|  |                 dialog.dismissSafe(activity) | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         getPref(R.string.manual_check_update_key)?.setOnPreferenceClickListener { | ||||||
|  |             thread { | ||||||
|  |                 if (!requireActivity().runAutoUpdate(false)) { | ||||||
|  |                     activity?.runOnUiThread { | ||||||
|  |                         CommonActivity.showToast(activity, R.string.no_update_found, Toast.LENGTH_SHORT) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return@setOnPreferenceClickListener true | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -302,7 +302,8 @@ object UIHelper { | ||||||
|         return result |         return result | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fun Context.fixPaddingStatusbar(v: View) { |     fun Context?.fixPaddingStatusbar(v: View?) { | ||||||
|  |         if (v == null || this == null) return | ||||||
|         v.setPadding( |         v.setPadding( | ||||||
|             v.paddingLeft, |             v.paddingLeft, | ||||||
|             v.paddingTop + getStatusBarHeight(), |             v.paddingTop + getStatusBarHeight(), | ||||||
|  |  | ||||||
							
								
								
									
										76
									
								
								app/src/main/res/layout/main_settings.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								app/src/main/res/layout/main_settings.xml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,76 @@ | ||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |         xmlns:app="http://schemas.android.com/apk/res-auto" | ||||||
|  |         android:layout_width="match_parent" | ||||||
|  |         android:background="?attr/primaryBlackBackground" | ||||||
|  |         android:layout_height="match_parent"> | ||||||
|  | 
 | ||||||
|  |     <ScrollView | ||||||
|  |             app:layout_constraintTop_toTopOf="parent" | ||||||
|  |             app:layout_constraintBottom_toBottomOf="parent" | ||||||
|  |             android:layout_width="match_parent" | ||||||
|  |             android:layout_height="wrap_content"> | ||||||
|  | 
 | ||||||
|  |         <LinearLayout | ||||||
|  |                 android:orientation="vertical" | ||||||
|  |                 android:gravity="center_vertical" | ||||||
|  |                 android:layout_width="match_parent" | ||||||
|  |                 android:layout_height="wrap_content"> | ||||||
|  | 
 | ||||||
|  |             <TextView | ||||||
|  |                     android:nextFocusDown="@id/settings_lang" | ||||||
|  | 
 | ||||||
|  |                     android:id="@+id/settings_player" | ||||||
|  |                     style="@style/SettingsItem" | ||||||
|  |                     android:text="@string/category_player" /> | ||||||
|  | 
 | ||||||
|  |             <TextView | ||||||
|  |                     android:nextFocusUp="@id/settings_player" | ||||||
|  |                     android:nextFocusDown="@id/settings_ui" | ||||||
|  | 
 | ||||||
|  |                     android:id="@+id/settings_lang" | ||||||
|  |                     style="@style/SettingsItem" | ||||||
|  |                     android:text="@string/category_preferred_media_and_lang" /> | ||||||
|  | 
 | ||||||
|  |             <TextView | ||||||
|  |                     android:nextFocusUp="@id/settings_lang" | ||||||
|  |                     android:nextFocusDown="@id/settings_nginx" | ||||||
|  | 
 | ||||||
|  |                     android:id="@+id/settings_ui" | ||||||
|  |                     style="@style/SettingsItem" | ||||||
|  |                     android:text="@string/category_ui" /> | ||||||
|  | 
 | ||||||
|  |             <TextView | ||||||
|  |                     android:nextFocusUp="@id/settings_ui" | ||||||
|  |                     android:nextFocusDown="@id/settings_updates" | ||||||
|  | 
 | ||||||
|  |                     android:id="@+id/settings_nginx" | ||||||
|  |                     style="@style/SettingsItem" | ||||||
|  |                     android:text="@string/category_nginx" /> | ||||||
|  | 
 | ||||||
|  |             <TextView | ||||||
|  |                     android:nextFocusUp="@id/settings_nginx" | ||||||
|  |                     android:nextFocusDown="@id/settings_credits" | ||||||
|  | 
 | ||||||
|  |                     android:id="@+id/settings_updates" | ||||||
|  |                     style="@style/SettingsItem" | ||||||
|  |                     android:text="@string/category_updates" /> | ||||||
|  | 
 | ||||||
|  |             <TextView | ||||||
|  |                     android:nextFocusUp="@id/settings_updates" | ||||||
|  | 
 | ||||||
|  |                     android:id="@+id/settings_credits" | ||||||
|  |                     style="@style/SettingsItem" | ||||||
|  |                     android:text="@string/category_credits" /> | ||||||
|  | 
 | ||||||
|  |             <TextView | ||||||
|  |                     android:padding="10dp" | ||||||
|  |                     android:gravity="center" | ||||||
|  |                     android:layout_gravity="center" | ||||||
|  |                     android:textColor="?attr/textColor" | ||||||
|  |                     android:text="@string/app_version" | ||||||
|  |                     android:layout_width="wrap_content" | ||||||
|  |                     android:layout_height="wrap_content" /> | ||||||
|  |         </LinearLayout> | ||||||
|  |     </ScrollView> | ||||||
|  | </androidx.constraintlayout.widget.ConstraintLayout> | ||||||
|  | @ -86,6 +86,69 @@ | ||||||
|                 android:defaultValue="true" /> |                 android:defaultValue="true" /> | ||||||
|     </action> |     </action> | ||||||
| 
 | 
 | ||||||
|  |     <fragment | ||||||
|  |             android:id="@+id/navigation_settings_player" | ||||||
|  |             android:name="com.lagradost.cloudstream3.ui.settings.SettingsPlayer" | ||||||
|  |             app:enterAnim="@anim/enter_anim" | ||||||
|  |             app:exitAnim="@anim/exit_anim" | ||||||
|  |             app:popEnterAnim="@anim/enter_anim" | ||||||
|  |             app:popExitAnim="@anim/exit_anim"> | ||||||
|  |         <action | ||||||
|  |                 android:id="@+id/action_navigation_settings_player_to_navigation_subtitles" | ||||||
|  |                 app:destination="@id/navigation_subtitles" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|  |                 app:popExitAnim="@anim/exit_anim" /> | ||||||
|  |         <action | ||||||
|  |                 android:id="@+id/action_navigation_settings_player_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" /> | ||||||
|  |     </fragment> | ||||||
|  | 
 | ||||||
|  |     <fragment | ||||||
|  |             android:id="@+id/navigation_settings_ui" | ||||||
|  |             android:name="com.lagradost.cloudstream3.ui.settings.SettingsUI" | ||||||
|  |             app:enterAnim="@anim/enter_anim" | ||||||
|  |             app:exitAnim="@anim/exit_anim" | ||||||
|  |             app:popEnterAnim="@anim/enter_anim" | ||||||
|  |             app:popExitAnim="@anim/exit_anim" /> | ||||||
|  | 
 | ||||||
|  |     <fragment | ||||||
|  |             android:id="@+id/navigation_settings_lang" | ||||||
|  |             android:name="com.lagradost.cloudstream3.ui.settings.SettingsLang" | ||||||
|  |             app:enterAnim="@anim/enter_anim" | ||||||
|  |             app:exitAnim="@anim/exit_anim" | ||||||
|  |             app:popEnterAnim="@anim/enter_anim" | ||||||
|  |             app:popExitAnim="@anim/exit_anim" /> | ||||||
|  | 
 | ||||||
|  |     <fragment | ||||||
|  |             android:id="@+id/navigation_settings_nginx" | ||||||
|  |             android:name="com.lagradost.cloudstream3.ui.settings.SettingsNginx" | ||||||
|  |             app:enterAnim="@anim/enter_anim" | ||||||
|  |             app:exitAnim="@anim/exit_anim" | ||||||
|  |             app:popEnterAnim="@anim/enter_anim" | ||||||
|  |             app:popExitAnim="@anim/exit_anim" /> | ||||||
|  | 
 | ||||||
|  |     <fragment | ||||||
|  |             android:id="@+id/navigation_settings_updates" | ||||||
|  |             android:name="com.lagradost.cloudstream3.ui.settings.SettingsUpdates" | ||||||
|  |             app:enterAnim="@anim/enter_anim" | ||||||
|  |             app:exitAnim="@anim/exit_anim" | ||||||
|  |             app:popEnterAnim="@anim/enter_anim" | ||||||
|  |             app:popExitAnim="@anim/exit_anim" /> | ||||||
|  | 
 | ||||||
|  |     <fragment | ||||||
|  |             android:id="@+id/navigation_settings_account" | ||||||
|  |             android:name="com.lagradost.cloudstream3.ui.settings.SettingsAccount" | ||||||
|  |             app:enterAnim="@anim/enter_anim" | ||||||
|  |             app:exitAnim="@anim/exit_anim" | ||||||
|  |             app:popEnterAnim="@anim/enter_anim" | ||||||
|  |             app:popExitAnim="@anim/exit_anim" /> | ||||||
|  | 
 | ||||||
|     <action |     <action | ||||||
|             android:id="@+id/global_to_navigation_quick_search" |             android:id="@+id/global_to_navigation_quick_search" | ||||||
|             app:destination="@id/navigation_quick_search" |             app:destination="@id/navigation_quick_search" | ||||||
|  | @ -103,30 +166,6 @@ | ||||||
|                 android:defaultValue="@null" /> |                 android:defaultValue="@null" /> | ||||||
|     </action> |     </action> | ||||||
| 
 | 
 | ||||||
|     <action |  | ||||||
|             android:id="@+id/global_to_navigation_settings" |  | ||||||
|             app:destination="@id/navigation_settings" |  | ||||||
|             app:enterAnim="@anim/enter_anim" |  | ||||||
|             app:exitAnim="@anim/exit_anim" |  | ||||||
|             app:popEnterAnim="@anim/enter_anim" |  | ||||||
|             app:popExitAnim="@anim/exit_anim" /> |  | ||||||
| 
 |  | ||||||
|     <action |  | ||||||
|             android:id="@+id/global_to_navigation_downloads" |  | ||||||
|             app:destination="@id/navigation_downloads" |  | ||||||
|             app:enterAnim="@anim/enter_anim" |  | ||||||
|             app:exitAnim="@anim/exit_anim" |  | ||||||
|             app:popEnterAnim="@anim/enter_anim" |  | ||||||
|             app:popExitAnim="@anim/exit_anim" /> |  | ||||||
| 
 |  | ||||||
|     <action |  | ||||||
|             android:id="@+id/global_to_navigation_search" |  | ||||||
|             app:destination="@id/navigation_search" |  | ||||||
|             app:enterAnim="@anim/enter_anim" |  | ||||||
|             app:exitAnim="@anim/exit_anim" |  | ||||||
|             app:popEnterAnim="@anim/enter_anim" |  | ||||||
|             app:popExitAnim="@anim/exit_anim" /> |  | ||||||
| 
 |  | ||||||
|     <fragment |     <fragment | ||||||
|             android:id="@+id/navigation_home" |             android:id="@+id/navigation_home" | ||||||
|             android:name="com.lagradost.cloudstream3.ui.home.HomeFragment" |             android:name="com.lagradost.cloudstream3.ui.home.HomeFragment" | ||||||
|  | @ -135,7 +174,22 @@ | ||||||
|             app:enterAnim="@anim/enter_anim" |             app:enterAnim="@anim/enter_anim" | ||||||
|             app:exitAnim="@anim/exit_anim" |             app:exitAnim="@anim/exit_anim" | ||||||
|             app:popEnterAnim="@anim/enter_anim" |             app:popEnterAnim="@anim/enter_anim" | ||||||
|  |             app:popExitAnim="@anim/exit_anim"> | ||||||
|  |         <action | ||||||
|  |                 android:id="@+id/action_navigation_home_to_navigation_results" | ||||||
|  |                 app:destination="@id/navigation_results" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|                 app:popExitAnim="@anim/exit_anim" /> |                 app:popExitAnim="@anim/exit_anim" /> | ||||||
|  |         <action | ||||||
|  |                 android:id="@+id/action_navigation_home_to_navigation_quick_search" | ||||||
|  |                 app:destination="@id/navigation_quick_search" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|  |                 app:popExitAnim="@anim/exit_anim" /> | ||||||
|  |     </fragment> | ||||||
| 
 | 
 | ||||||
|     <fragment |     <fragment | ||||||
|             android:id="@+id/navigation_search" |             android:id="@+id/navigation_search" | ||||||
|  | @ -145,7 +199,15 @@ | ||||||
|             app:enterAnim="@anim/enter_anim" |             app:enterAnim="@anim/enter_anim" | ||||||
|             app:exitAnim="@anim/exit_anim" |             app:exitAnim="@anim/exit_anim" | ||||||
|             app:popEnterAnim="@anim/enter_anim" |             app:popEnterAnim="@anim/enter_anim" | ||||||
|  |             app:popExitAnim="@anim/exit_anim"> | ||||||
|  |         <action | ||||||
|  |                 android:id="@+id/action_navigation_search_to_navigation_results" | ||||||
|  |                 app:destination="@id/navigation_results" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|                 app:popExitAnim="@anim/exit_anim" /> |                 app:popExitAnim="@anim/exit_anim" /> | ||||||
|  |     </fragment> | ||||||
| 
 | 
 | ||||||
|     <fragment |     <fragment | ||||||
|             android:id="@+id/navigation_downloads" |             android:id="@+id/navigation_downloads" | ||||||
|  | @ -159,7 +221,11 @@ | ||||||
| 
 | 
 | ||||||
|         <action |         <action | ||||||
|                 android:id="@+id/action_navigation_downloads_to_navigation_download_child" |                 android:id="@+id/action_navigation_downloads_to_navigation_download_child" | ||||||
|                 app:destination="@id/navigation_download_child"> |                 app:destination="@id/navigation_download_child" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|  |                 app:popExitAnim="@anim/exit_anim"> | ||||||
|             <argument |             <argument | ||||||
|                     android:name="name" |                     android:name="name" | ||||||
|                     app:argType="string" /> |                     app:argType="string" /> | ||||||
|  | @ -167,6 +233,20 @@ | ||||||
|                     android:name="folder" |                     android:name="folder" | ||||||
|                     app:argType="string" /> |                     app:argType="string" /> | ||||||
|         </action> |         </action> | ||||||
|  |         <action | ||||||
|  |                 android:id="@+id/action_navigation_downloads_to_navigation_results" | ||||||
|  |                 app:destination="@id/navigation_results" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|  |                 app:popExitAnim="@anim/exit_anim" /> | ||||||
|  |         <action | ||||||
|  |                 android:id="@+id/action_navigation_downloads_to_navigation_player" | ||||||
|  |                 app:destination="@id/navigation_player" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|  |                 app:popExitAnim="@anim/exit_anim" /> | ||||||
|     </fragment> |     </fragment> | ||||||
|     <fragment |     <fragment | ||||||
|             android:id="@+id/navigation_settings" |             android:id="@+id/navigation_settings" | ||||||
|  | @ -176,7 +256,50 @@ | ||||||
|             app:enterAnim="@anim/enter_anim" |             app:enterAnim="@anim/enter_anim" | ||||||
|             app:exitAnim="@anim/exit_anim" |             app:exitAnim="@anim/exit_anim" | ||||||
|             app:popEnterAnim="@anim/enter_anim" |             app:popEnterAnim="@anim/enter_anim" | ||||||
|  |             app:popExitAnim="@anim/exit_anim"> | ||||||
|  |         <action | ||||||
|  |                 android:id="@+id/action_navigation_settings_to_navigation_settings_nginx" | ||||||
|  |                 app:destination="@id/navigation_settings_nginx" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|                 app:popExitAnim="@anim/exit_anim" /> |                 app:popExitAnim="@anim/exit_anim" /> | ||||||
|  |         <action | ||||||
|  |                 android:id="@+id/action_navigation_settings_to_navigation_settings_ui" | ||||||
|  |                 app:destination="@id/navigation_settings_ui" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|  |                 app:popExitAnim="@anim/exit_anim" /> | ||||||
|  |         <action | ||||||
|  |                 android:id="@+id/action_navigation_settings_to_navigation_settings_lang" | ||||||
|  |                 app:destination="@id/navigation_settings_lang" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|  |                 app:popExitAnim="@anim/exit_anim" /> | ||||||
|  |         <action | ||||||
|  |                 android:id="@+id/action_navigation_settings_to_navigation_settings_player" | ||||||
|  |                 app:destination="@id/navigation_settings_player" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|  |                 app:popExitAnim="@anim/exit_anim" /> | ||||||
|  |         <action | ||||||
|  |                 android:id="@+id/action_navigation_settings_to_navigation_settings_updates" | ||||||
|  |                 app:destination="@id/navigation_settings_updates" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|  |                 app:popExitAnim="@anim/exit_anim" /> | ||||||
|  |         <action | ||||||
|  |                 android:id="@+id/action_navigation_settings_to_navigation_settings_account" | ||||||
|  |                 app:destination="@id/navigation_settings_account" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|  |                 app:popExitAnim="@anim/exit_anim" /> | ||||||
|  |     </fragment> | ||||||
| 
 | 
 | ||||||
|     <fragment |     <fragment | ||||||
|             android:id="@+id/navigation_subtitles" |             android:id="@+id/navigation_subtitles" | ||||||
|  | @ -215,8 +338,15 @@ | ||||||
|             app:enterAnim="@anim/enter_anim" |             app:enterAnim="@anim/enter_anim" | ||||||
|             app:exitAnim="@anim/exit_anim" |             app:exitAnim="@anim/exit_anim" | ||||||
|             app:popEnterAnim="@anim/enter_anim" |             app:popEnterAnim="@anim/enter_anim" | ||||||
|             app:popExitAnim="@anim/exit_anim" |             app:popExitAnim="@anim/exit_anim"> | ||||||
|             android:label="@string/title_settings" /> |         <action | ||||||
|  |                 android:id="@+id/action_navigation_download_child_to_navigation_player" | ||||||
|  |                 app:destination="@id/navigation_player" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|  |                 app:popExitAnim="@anim/exit_anim" /> | ||||||
|  |     </fragment> | ||||||
| 
 | 
 | ||||||
|     <fragment |     <fragment | ||||||
|             android:id="@+id/navigation_results" |             android:id="@+id/navigation_results" | ||||||
|  | @ -225,7 +355,22 @@ | ||||||
|             app:enterAnim="@anim/enter_anim" |             app:enterAnim="@anim/enter_anim" | ||||||
|             app:exitAnim="@anim/exit_anim" |             app:exitAnim="@anim/exit_anim" | ||||||
|             app:popEnterAnim="@anim/enter_anim" |             app:popEnterAnim="@anim/enter_anim" | ||||||
|  |             app:popExitAnim="@anim/exit_anim"> | ||||||
|  |         <action | ||||||
|  |                 android:id="@+id/action_navigation_results_to_navigation_quick_search" | ||||||
|  |                 app:destination="@id/navigation_quick_search" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|                 app:popExitAnim="@anim/exit_anim" /> |                 app:popExitAnim="@anim/exit_anim" /> | ||||||
|  |         <action | ||||||
|  |                 android:id="@+id/action_navigation_results_to_navigation_player" | ||||||
|  |                 app:destination="@id/navigation_player" | ||||||
|  |                 app:enterAnim="@anim/enter_anim" | ||||||
|  |                 app:exitAnim="@anim/exit_anim" | ||||||
|  |                 app:popEnterAnim="@anim/enter_anim" | ||||||
|  |                 app:popExitAnim="@anim/exit_anim" /> | ||||||
|  |     </fragment> | ||||||
| 
 | 
 | ||||||
|     <fragment |     <fragment | ||||||
|             android:id="@+id/navigation_player" |             android:id="@+id/navigation_player" | ||||||
|  |  | ||||||
|  | @ -182,7 +182,7 @@ | ||||||
|     <string name="backup_failed_error_format">Yedekleme hatası %s</string> |     <string name="backup_failed_error_format">Yedekleme hatası %s</string> | ||||||
| 
 | 
 | ||||||
|     <string name="search">Ara</string> |     <string name="search">Ara</string> | ||||||
|     <string name="nginx_category">Nginx Ayarları</string> |     <string name="category_nginx">Nginx Ayarları</string> | ||||||
|     <string name="nginx_credentials_title">Nginx Kimlik Bilgileri</string> |     <string name="nginx_credentials_title">Nginx Kimlik Bilgileri</string> | ||||||
|     <string name="nginx_credentials_summary">Örnekteki formatta yazmalısın havalıkullanıcıadım:güvenlişifrem123</string> |     <string name="nginx_credentials_summary">Örnekteki formatta yazmalısın havalıkullanıcıadım:güvenlişifrem123</string> | ||||||
|     <string name="nginx_info_title">Nginx nedir?</string> |     <string name="nginx_info_title">Nginx nedir?</string> | ||||||
|  |  | ||||||
|  | @ -42,6 +42,20 @@ | ||||||
|         <item>3</item> |         <item>3</item> | ||||||
|     </array> |     </array> | ||||||
| 
 | 
 | ||||||
|  |     <array name="limit_title_rez_pref_names"> | ||||||
|  |         <item>@string/resolution_and_title</item> | ||||||
|  |         <item>@string/title</item> | ||||||
|  |         <item>@string/resolution</item> | ||||||
|  |         <item>@string/none</item> | ||||||
|  |     </array> | ||||||
|  | 
 | ||||||
|  |     <array name="limit_title_rez_pref_values"> | ||||||
|  |         <item>3</item> | ||||||
|  |         <item>2</item> | ||||||
|  |         <item>1</item> | ||||||
|  |         <item>0</item> | ||||||
|  |     </array> | ||||||
|  | 
 | ||||||
|     <array name="limit_title_pref_names"> |     <array name="limit_title_pref_names"> | ||||||
|         <item>@string/none</item> |         <item>@string/none</item> | ||||||
|         <item>16 characters</item> |         <item>16 characters</item> | ||||||
|  | @ -59,6 +73,15 @@ | ||||||
|         <item>-1</item> |         <item>-1</item> | ||||||
|     </array> |     </array> | ||||||
| 
 | 
 | ||||||
|  |     <array name="skip_sec_values"> | ||||||
|  |         <item>5</item> | ||||||
|  |         <item>10</item> | ||||||
|  |         <item>15</item> | ||||||
|  |         <item>20</item> | ||||||
|  |         <item>25</item> | ||||||
|  |         <item>30</item> | ||||||
|  |     </array> | ||||||
|  | 
 | ||||||
|     <array name="video_buffer_length_names"> |     <array name="video_buffer_length_names"> | ||||||
|         <item>@string/automatic</item> |         <item>@string/automatic</item> | ||||||
|         <item>1min</item> |         <item>1min</item> | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ | ||||||
|     <string name="subtitle_settings_chromecast_key" translatable="false">subtitle_settings_chromecast_key</string> |     <string name="subtitle_settings_chromecast_key" translatable="false">subtitle_settings_chromecast_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="prefer_limit_title_key" translatable="false">prefer_limit_title_key</string> |     <string name="prefer_limit_title_key" translatable="false">prefer_limit_title_key</string> | ||||||
|  |     <string name="prefer_limit_title_rez_key" translatable="false">prefer_limit_title_rez_key</string> | ||||||
|     <string name="video_buffer_size_key" translatable="false">video_buffer_size_key</string> |     <string name="video_buffer_size_key" translatable="false">video_buffer_size_key</string> | ||||||
|     <string name="video_buffer_length_key" translatable="false">video_buffer_length_key</string> |     <string name="video_buffer_length_key" translatable="false">video_buffer_length_key</string> | ||||||
|     <string name="video_buffer_clear_key" translatable="false">video_buffer_clear_key</string> |     <string name="video_buffer_clear_key" translatable="false">video_buffer_clear_key</string> | ||||||
|  | @ -26,6 +27,7 @@ | ||||||
|     <string name="pip_enabled_key" translatable="false">pip_enabled_key</string> |     <string name="pip_enabled_key" translatable="false">pip_enabled_key</string> | ||||||
|     <string name="double_tap_enabled_key" translatable="false">double_tap_enabled_key</string> |     <string name="double_tap_enabled_key" translatable="false">double_tap_enabled_key</string> | ||||||
|     <string name="double_tap_pause_enabled_key" translatable="false">double_tap_pause_enabled_key</string> |     <string name="double_tap_pause_enabled_key" translatable="false">double_tap_pause_enabled_key</string> | ||||||
|  |     <string name="double_tap_seek_time_key" translatable="false">double_tap_seek_time_key</string> | ||||||
|     <string name="swipe_vertical_enabled_key" translatable="false">swipe_vertical_enabled_key</string> |     <string name="swipe_vertical_enabled_key" translatable="false">swipe_vertical_enabled_key</string> | ||||||
|     <string name="display_sub_key" translatable="false">display_sub_key</string> |     <string name="display_sub_key" translatable="false">display_sub_key</string> | ||||||
|     <string name="show_fillers_key" translatable="false">show_fillers_key</string> |     <string name="show_fillers_key" translatable="false">show_fillers_key</string> | ||||||
|  | @ -213,6 +215,7 @@ | ||||||
|     <string name="swipe_to_change_settings_des">Swipe on the left or right side to change brightness or volume</string> |     <string name="swipe_to_change_settings_des">Swipe on the left or right side to change brightness or volume</string> | ||||||
|     <string name="double_tap_to_seek_settings">Double tap to seek</string> |     <string name="double_tap_to_seek_settings">Double tap to seek</string> | ||||||
|     <string name="double_tap_to_pause_settings">Double tap to pause</string> |     <string name="double_tap_to_pause_settings">Double tap to pause</string> | ||||||
|  |     <string name="double_tap_to_seek_amount_settings">Player seek amount</string> | ||||||
|     <string name="double_tap_to_seek_settings_des">Tap twice on the right or left side to seek forwards or backwards |     <string name="double_tap_to_seek_settings_des">Tap twice on the right or left side to seek forwards or backwards | ||||||
|     </string> |     </string> | ||||||
|     <string name="double_tap_to_pause_settings_des">Tap in the middle to pause</string> |     <string name="double_tap_to_pause_settings_des">Tap in the middle to pause</string> | ||||||
|  | @ -236,7 +239,9 @@ | ||||||
|     <string name="backup_failed_error_format">Error backing up %s</string> |     <string name="backup_failed_error_format">Error backing up %s</string> | ||||||
| 
 | 
 | ||||||
|     <string name="search">Search</string> |     <string name="search">Search</string> | ||||||
|     <string name="nginx_category">Nginx Settings</string> |     <string name="category_nginx">Nginx</string> | ||||||
|  |     <string name="category_credits">Credits and account</string> | ||||||
|  |     <string name="category_updates">Updates and backup</string> | ||||||
|     <string name="nginx_credentials_title">Nginx Credential</string> |     <string name="nginx_credentials_title">Nginx Credential</string> | ||||||
|     <string name="nginx_credentials_summary">You have to use the following format mycoolusername:mysecurepassword123</string> |     <string name="nginx_credentials_summary">You have to use the following format mycoolusername:mysecurepassword123</string> | ||||||
|     <string name="nginx_info_title">What is Nginx ?</string> |     <string name="nginx_info_title">What is Nginx ?</string> | ||||||
|  | @ -365,7 +370,9 @@ | ||||||
|     <string name="skip_update">Skip this Update</string> |     <string name="skip_update">Skip this Update</string> | ||||||
|     <string name="update">Update</string> |     <string name="update">Update</string> | ||||||
|     <string name="watch_quality_pref">Preferred watch quality</string> |     <string name="watch_quality_pref">Preferred watch quality</string> | ||||||
|     <string name="limit_title">Video player title max chars.</string> |     <string name="limit_title">Video player title max chars</string> | ||||||
|  |     <string name="limit_title_rez">Video player resolution</string> | ||||||
|  | 
 | ||||||
|     <string name="video_buffer_size_settings">Video buffer size</string> |     <string name="video_buffer_size_settings">Video buffer size</string> | ||||||
|     <string name="video_buffer_length_settings">Video buffer length</string> |     <string name="video_buffer_length_settings">Video buffer length</string> | ||||||
|     <string name="video_buffer_disk_settings">Video cache on disk</string> |     <string name="video_buffer_disk_settings">Video cache on disk</string> | ||||||
|  | @ -408,9 +415,11 @@ | ||||||
|     <string name="general">General</string> |     <string name="general">General</string> | ||||||
|     <string name="random_button_settings">Random Button</string> |     <string name="random_button_settings">Random Button</string> | ||||||
|     <string name="random_button_settings_desc">Show random button on Homepage</string> |     <string name="random_button_settings_desc">Show random button on Homepage</string> | ||||||
|     <string name="provider_lang_settings">Provider Languages</string> |     <string name="provider_lang_settings">Provider languages</string> | ||||||
|     <string name="app_layout">App Layout</string> |     <string name="app_layout">App Layout</string> | ||||||
|     <string name="preferred_media_settings">Preferred Media</string> |     <string name="preferred_media_settings">Preferred media</string> | ||||||
|  |     <string name="category_preferred_media_and_lang">Preferred media and language</string> | ||||||
|  |     <string name="category_ui">User interface</string> | ||||||
| 
 | 
 | ||||||
|     <string name="automatic">Auto</string> |     <string name="automatic">Auto</string> | ||||||
|     <string name="tv_layout">TV layout</string> |     <string name="tv_layout">TV layout</string> | ||||||
|  | @ -507,4 +516,8 @@ | ||||||
|     <string name="quality_webrip">Web</string> |     <string name="quality_webrip">Web</string> | ||||||
| 
 | 
 | ||||||
|     <string name="poster_image">Poster Image</string> |     <string name="poster_image">Poster Image</string> | ||||||
|  |     <string name="category_player">Player</string> | ||||||
|  |     <string name="resolution_and_title">Resolution and title</string> | ||||||
|  |     <string name="title">Title</string> | ||||||
|  |     <string name="resolution">Resolution</string> | ||||||
| </resources> | </resources> | ||||||
|  |  | ||||||
|  | @ -1,313 +0,0 @@ | ||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" |  | ||||||
|         xmlns:app="http://schemas.android.com/apk/res-auto"> |  | ||||||
|     <PreferenceCategory /> |  | ||||||
|     <PreferenceCategory |  | ||||||
|             android:key="video" |  | ||||||
|             android:title="Player" |  | ||||||
|             app:isPreferenceVisible="true"> |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/subtitle_settings_key" |  | ||||||
|                 android:title="@string/player_subtitles_settings" |  | ||||||
|                 android:icon="@drawable/ic_outline_subtitles_24" |  | ||||||
|                 app:summary="@string/player_subtitles_settings_des" /> |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/subtitle_settings_chromecast_key" |  | ||||||
|                 android:title="@string/chromecast_subtitles_settings" |  | ||||||
|                 android:icon="@drawable/ic_outline_subtitles_24" |  | ||||||
|                 app:summary="@string/chromecast_subtitles_settings_des" /> |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/quality_pref_key" |  | ||||||
|                 android:title="@string/watch_quality_pref" |  | ||||||
|                 android:icon="@drawable/ic_baseline_hd_24" /> |  | ||||||
|         <Preference |  | ||||||
|             android:key="@string/prefer_limit_title_key" |  | ||||||
|             android:title="@string/limit_title" |  | ||||||
|             android:icon="@drawable/ic_baseline_text_format_24" /> |  | ||||||
| 
 |  | ||||||
|         <SwitchPreference |  | ||||||
|                 android:icon="@drawable/ic_baseline_picture_in_picture_alt_24" |  | ||||||
|                 app:key="@string/pip_enabled_key" |  | ||||||
|                 android:title="@string/picture_in_picture" |  | ||||||
|                 android:summary="@string/picture_in_picture_des" |  | ||||||
|                 app:defaultValue="true" /> |  | ||||||
|         <SwitchPreference |  | ||||||
|                 android:icon="@drawable/ic_baseline_aspect_ratio_24" |  | ||||||
|                 app:key="@string/player_resize_enabled_key" |  | ||||||
|                 android:title="@string/player_size_settings" |  | ||||||
|                 android:summary="@string/player_size_settings_des" |  | ||||||
|                 app:defaultValue="true" /> |  | ||||||
|         <SwitchPreference |  | ||||||
|                 android:icon="@drawable/ic_baseline_speed_24" |  | ||||||
|                 app:key="@string/playback_speed_enabled_key" |  | ||||||
|                 android:title="@string/eigengraumode_settings" |  | ||||||
|                 android:summary="@string/eigengraumode_settings_des" |  | ||||||
|                 app:defaultValue="false" /> |  | ||||||
|         <SwitchPreference |  | ||||||
|                 android:icon="@drawable/ic_baseline_ondemand_video_24" |  | ||||||
|                 app:key="@string/swipe_enabled_key" |  | ||||||
|                 android:title="@string/swipe_to_seek_settings" |  | ||||||
|                 android:summary="@string/swipe_to_seek_settings_des" |  | ||||||
|                 app:defaultValue="true" /> |  | ||||||
|         <SwitchPreference |  | ||||||
|                 android:icon="@drawable/ic_baseline_ondemand_video_24" |  | ||||||
|                 app:key="@string/swipe_vertical_enabled_key" |  | ||||||
|                 android:title="@string/swipe_to_change_settings" |  | ||||||
|                 android:summary="@string/swipe_to_change_settings_des" |  | ||||||
|                 app:defaultValue="true" /> |  | ||||||
|         <SwitchPreference |  | ||||||
|                 android:icon="@drawable/ic_baseline_touch_app_24" |  | ||||||
|                 app:key="@string/double_tap_enabled_key" |  | ||||||
|                 android:title="@string/double_tap_to_seek_settings" |  | ||||||
|                 android:summary="@string/double_tap_to_seek_settings_des" |  | ||||||
|                 app:defaultValue="false" /> |  | ||||||
|         <SwitchPreference |  | ||||||
|                 android:icon="@drawable/netflix_pause" |  | ||||||
|                 app:key="@string/double_tap_pause_enabled_key" |  | ||||||
|                 android:title="@string/double_tap_to_pause_settings" |  | ||||||
|                 android:summary="@string/double_tap_to_pause_settings_des" |  | ||||||
|                 app:defaultValue="false" /> |  | ||||||
| 
 |  | ||||||
|         <SwitchPreference |  | ||||||
|                 android:icon="@drawable/baseline_sync_24" |  | ||||||
|                 app:key="@string/episode_sync_enabled_key" |  | ||||||
|                 android:title="@string/episode_sync_settings" |  | ||||||
|                 android:summary="@string/episode_sync_settings_des" |  | ||||||
|                 app:defaultValue="true" /> |  | ||||||
| 
 |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/video_buffer_disk_key" |  | ||||||
|                 android:title="@string/video_buffer_disk_settings" |  | ||||||
|                 android:summary="@string/video_disk_description" |  | ||||||
|                 android:icon="@drawable/ic_baseline_storage_24" /> |  | ||||||
| 
 |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/video_buffer_size_key" |  | ||||||
|                 android:title="@string/video_buffer_size_settings" |  | ||||||
|                 android:summary="@string/video_ram_description" |  | ||||||
|                 android:icon="@drawable/ic_baseline_storage_24" /> |  | ||||||
| 
 |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/video_buffer_length_key" |  | ||||||
|                 android:title="@string/video_buffer_length_settings" |  | ||||||
|                 android:summary="@string/video_ram_description" |  | ||||||
|                 android:icon="@drawable/ic_baseline_storage_24" /> |  | ||||||
| 
 |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/video_buffer_clear_key" |  | ||||||
|                 android:title="@string/video_buffer_clear_settings" |  | ||||||
|                 android:icon="@drawable/ic_baseline_delete_outline_24" /> |  | ||||||
|         <!-- |  | ||||||
|         <SwitchPreference |  | ||||||
|                 android:icon="@drawable/ic_baseline_brightness_7_24" |  | ||||||
|                 app:key="@string/use_system_brightness_key" |  | ||||||
|                 android:title="@string/use_system_brightness_settings" |  | ||||||
|                 android:summary="@string/use_system_brightness_settings_des" |  | ||||||
|                 app:defaultValue="false" |  | ||||||
|         /> |  | ||||||
|         --> |  | ||||||
|     </PreferenceCategory> |  | ||||||
|     <PreferenceCategory |  | ||||||
|             android:key="general" |  | ||||||
|             android:title="@string/general" |  | ||||||
|             app:isPreferenceVisible="true"> |  | ||||||
|         <SwitchPreference |  | ||||||
|             android:icon="@drawable/ic_baseline_play_arrow_24" |  | ||||||
|             app:key="@string/random_button_key" |  | ||||||
|             android:title="@string/random_button_settings" |  | ||||||
|             android:summary="@string/random_button_settings_desc" |  | ||||||
|             app:defaultValue="false" /> |  | ||||||
|         <Preference |  | ||||||
|                 android:icon="@drawable/ic_baseline_language_24" |  | ||||||
|                 android:key="@string/provider_lang_key" |  | ||||||
|                 android:title="@string/provider_lang_settings" /> |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/locale_key" |  | ||||||
|                 android:title="@string/app_language" |  | ||||||
|                 android:icon="@drawable/ic_baseline_language_24" /> |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/prefer_media_type_key" |  | ||||||
|                 android:title="@string/preferred_media_settings" |  | ||||||
|                 android:icon="@drawable/ic_baseline_play_arrow_24" /> |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/display_sub_key" |  | ||||||
|                 android:title="@string/display_subbed_dubbed_settings" |  | ||||||
|                 android:icon="@drawable/ic_outline_voice_over_off_24" /> |  | ||||||
|         <SwitchPreference |  | ||||||
|                 android:key="@string/show_fillers_key" |  | ||||||
|                 android:icon="@drawable/ic_baseline_skip_next_24" |  | ||||||
|                 android:title="@string/show_fillers_settings" |  | ||||||
|                 android:defaultValue="false" /> |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/dns_key" |  | ||||||
|                 android:title="@string/dns_pref" |  | ||||||
|                 android:summary="@string/dns_pref_summary" |  | ||||||
|                 android:icon="@drawable/ic_baseline_dns_24" /> |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/download_path_key" |  | ||||||
|                 android:title="@string/download_path_pref" |  | ||||||
|                 android:icon="@drawable/netflix_download" /> |  | ||||||
|         <Preference |  | ||||||
|                 android:icon="@drawable/ic_baseline_tv_24" |  | ||||||
|                 android:key="@string/app_layout_key" |  | ||||||
|                 android:title="@string/app_layout" /> |  | ||||||
|         <Preference |  | ||||||
|                 android:icon="@drawable/ic_baseline_color_lens_24" |  | ||||||
|                 android:key="@string/primary_color_key" |  | ||||||
|                 android:title="@string/primary_color_settings" /> |  | ||||||
|         <Preference |  | ||||||
|                 android:icon="@drawable/ic_baseline_color_lens_24" |  | ||||||
|                 android:key="@string/app_theme_key" |  | ||||||
|                 android:title="@string/app_theme_settings" /> |  | ||||||
| 
 |  | ||||||
|         <SwitchPreference |  | ||||||
|                 android:defaultValue="true" |  | ||||||
|                 android:icon="@drawable/baseline_grid_view_24" |  | ||||||
|                 android:key="@string/bottom_title_key" |  | ||||||
|                 android:summary="@string/bottom_title_settings_des" |  | ||||||
|                 android:title="@string/bottom_title_settings" /> |  | ||||||
|         <Preference |  | ||||||
|                 android:icon="@drawable/ic_baseline_tv_24" |  | ||||||
|                 android:key="@string/poster_ui_key" |  | ||||||
|                 android:title="@string/poster_ui_settings" /> |  | ||||||
|     </PreferenceCategory> |  | ||||||
|     <PreferenceCategory |  | ||||||
|             android:key="search" |  | ||||||
|             android:title="@string/search" |  | ||||||
|             app:isPreferenceVisible="true"> |  | ||||||
|         <SwitchPreference |  | ||||||
|                 android:icon="@drawable/search_icon" |  | ||||||
|                 app:key="advanced_search" |  | ||||||
|                 android:title="@string/advanced_search" |  | ||||||
|                 android:summary="@string/advanced_search_des" |  | ||||||
|                 app:defaultValue="true" /> |  | ||||||
|     </PreferenceCategory> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     <PreferenceCategory |  | ||||||
|         android:key="@string/nginx_category" |  | ||||||
|         android:title="@string/nginx_category" |  | ||||||
|         app:isPreferenceVisible="true"> |  | ||||||
|         <Preference |  | ||||||
|             android:key="@string/nginx_url_key" |  | ||||||
|             android:title="@string/nginx_url_pref" |  | ||||||
|             android:icon="@drawable/ic_baseline_play_arrow_24" /> |  | ||||||
|         <Preference |  | ||||||
|             android:key="@string/nginx_credentials" |  | ||||||
|             android:title="@string/nginx_credentials_title" |  | ||||||
|             android:icon="@drawable/video_locked" |  | ||||||
|             android:summary="@string/nginx_credentials_summary"/> |  | ||||||
|         <Preference |  | ||||||
|             android:key="@string/nginx_info" |  | ||||||
|             android:title="@string/nginx_info_title" |  | ||||||
|             android:icon="@drawable/ic_baseline_play_arrow_24" |  | ||||||
| 	        android:summary="@string/nginx_info_summary" > |  | ||||||
|             <intent |  | ||||||
|                 android:action="android.intent.action.VIEW" |  | ||||||
|                 android:data="https://www.sarlays.com/use-nginx-with-cloudstream/" /> |  | ||||||
|         </Preference> |  | ||||||
|     </PreferenceCategory> |  | ||||||
| 
 |  | ||||||
|     <PreferenceCategory |  | ||||||
|             android:key="info" |  | ||||||
|             android:title="@string/settings_info" |  | ||||||
|             app:isPreferenceVisible="true"> |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/legal_notice_key" |  | ||||||
|                 android:title="@string/legal_notice" |  | ||||||
|                 android:icon="@drawable/ic_baseline_warning_24" /> |  | ||||||
| 
 |  | ||||||
|         <SwitchPreference |  | ||||||
|                 android:key="acra.disable" |  | ||||||
|                 android:icon="@drawable/ic_baseline_bug_report_24" |  | ||||||
|                 android:title="@string/pref_disable_acra" |  | ||||||
|                 android:summaryOff="@string/bug_report_settings_off" |  | ||||||
|                 android:summaryOn="@string/bug_report_settings_on" |  | ||||||
|                 android:defaultValue="false" /> |  | ||||||
|         <SwitchPreference |  | ||||||
|                 app:key="@string/auto_update_key" |  | ||||||
|                 android:title="@string/updates_settings" |  | ||||||
|                 android:summary="@string/updates_settings_des" |  | ||||||
|                 app:defaultValue="true" |  | ||||||
|                 android:icon="@drawable/ic_baseline_notifications_active_24" /> |  | ||||||
|         <SwitchPreference |  | ||||||
|                 app:key="@string/prerelease_update_key" |  | ||||||
|                 android:title="@string/uprereleases_settings" |  | ||||||
|                 android:summary="@string/uprereleases_settings_des" |  | ||||||
|                 app:defaultValue="false" |  | ||||||
|                 android:icon="@drawable/ic_baseline_developer_mode_24" /> |  | ||||||
|         <Preference |  | ||||||
|                 android:title="@string/check_for_update" |  | ||||||
|                 app:summary="@string/app_version" |  | ||||||
|                 app:key="@string/manual_check_update_key" |  | ||||||
|                 app:icon="@drawable/ic_baseline_system_update_24" /> |  | ||||||
| 
 |  | ||||||
|         <Preference |  | ||||||
|                 android:icon="@drawable/baseline_save_as_24" |  | ||||||
|                 android:key="@string/backup_key" |  | ||||||
|                 android:title="@string/backup_settings" /> |  | ||||||
| 
 |  | ||||||
|         <Preference |  | ||||||
|                 android:icon="@drawable/baseline_restore_page_24" |  | ||||||
|                 android:key="@string/restore_key" |  | ||||||
|                 android:title="@string/restore_settings" /> |  | ||||||
| 
 |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/show_logcat_key" |  | ||||||
|                 android:title="@string/show_log_cat" |  | ||||||
|                 android:icon="@drawable/baseline_description_24" /> |  | ||||||
| 
 |  | ||||||
|         <!--<SwitchPreference |  | ||||||
|                 android:defaultValue="false" |  | ||||||
|                 android:key="@string/log_enabled_key" |  | ||||||
|                 android:title="@string/toggle_logcat" |  | ||||||
|                 android:summary="@string/toggle_logcat_des" |  | ||||||
|                 android:icon="@drawable/baseline_description_24" />--> |  | ||||||
| 
 |  | ||||||
|         <SwitchPreference |  | ||||||
|                 android:icon="@drawable/netflix_download" |  | ||||||
|                 android:key="@string/killswitch_key" |  | ||||||
|                 android:defaultValue="true" |  | ||||||
|                 android:summary="@string/killswitch_settings_des" |  | ||||||
|                 android:title="@string/killswitch_settings" /> |  | ||||||
| 
 |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/mal_key" |  | ||||||
|                 android:icon="@drawable/mal_logo" /> |  | ||||||
| 
 |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/anilist_key" |  | ||||||
|                 android:icon="@drawable/ic_anilist_icon" /> |  | ||||||
| 
 |  | ||||||
|         <Preference |  | ||||||
|                 android:title="@string/github" |  | ||||||
|                 android:icon="@drawable/ic_github_logo" |  | ||||||
|                 app:summary="https://github.com/LagradOst/CloudStream-3"> |  | ||||||
|             <intent |  | ||||||
|                     android:action="android.intent.action.VIEW" |  | ||||||
|                     android:data="https://github.com/LagradOst/CloudStream-3" /> |  | ||||||
|         </Preference> |  | ||||||
| 
 |  | ||||||
|         <Preference |  | ||||||
|                 android:title="@string/lightnovel" |  | ||||||
|                 android:icon="@drawable/quick_novel_icon" |  | ||||||
|                 app:summary="https://github.com/LagradOst/QuickNovel"> |  | ||||||
|             <intent |  | ||||||
|                     android:action="android.intent.action.VIEW" |  | ||||||
|                     android:data="https://github.com/LagradOst/QuickNovel" /> |  | ||||||
|         </Preference> |  | ||||||
|         <Preference |  | ||||||
|                 android:title="@string/discord" |  | ||||||
|                 android:icon="@drawable/ic_baseline_discord_24" |  | ||||||
|                 app:summary="https://discord.gg/5Hus6fM"> |  | ||||||
|             <intent |  | ||||||
|                     android:action="android.intent.action.VIEW" |  | ||||||
|                     android:data="https://discord.gg/5Hus6fM" /> |  | ||||||
|         </Preference> |  | ||||||
|         <Preference |  | ||||||
|                 android:key="@string/benene_count" |  | ||||||
|                 android:title="@string/benene" |  | ||||||
|                 android:icon="@drawable/benene" |  | ||||||
|                 app:summary="@string/benene_des" /> |  | ||||||
|     </PreferenceCategory> |  | ||||||
| </PreferenceScreen> |  | ||||||
							
								
								
									
										47
									
								
								app/src/main/res/xml/settings_credits_account.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								app/src/main/res/xml/settings_credits_account.xml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,47 @@ | ||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |         xmlns:app="http://schemas.android.com/apk/res-auto"> | ||||||
|  |     <PreferenceCategory app:icon="@color/transparent" /> | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/mal_key" | ||||||
|  |             android:icon="@drawable/mal_logo" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/anilist_key" | ||||||
|  |             android:icon="@drawable/ic_anilist_icon" /> | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/legal_notice_key" | ||||||
|  |             android:title="@string/legal_notice" | ||||||
|  |             android:icon="@drawable/ic_baseline_warning_24" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:title="@string/github" | ||||||
|  |             android:icon="@drawable/ic_github_logo" | ||||||
|  |             app:summary="https://github.com/LagradOst/CloudStream-3"> | ||||||
|  |         <intent | ||||||
|  |                 android:action="android.intent.action.VIEW" | ||||||
|  |                 android:data="https://github.com/LagradOst/CloudStream-3" /> | ||||||
|  |     </Preference> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:title="@string/lightnovel" | ||||||
|  |             android:icon="@drawable/quick_novel_icon" | ||||||
|  |             app:summary="https://github.com/LagradOst/QuickNovel"> | ||||||
|  |         <intent | ||||||
|  |                 android:action="android.intent.action.VIEW" | ||||||
|  |                 android:data="https://github.com/LagradOst/QuickNovel" /> | ||||||
|  |     </Preference> | ||||||
|  |     <Preference | ||||||
|  |             android:title="@string/discord" | ||||||
|  |             android:icon="@drawable/ic_baseline_discord_24" | ||||||
|  |             app:summary="https://discord.gg/5Hus6fM"> | ||||||
|  |         <intent | ||||||
|  |                 android:action="android.intent.action.VIEW" | ||||||
|  |                 android:data="https://discord.gg/5Hus6fM" /> | ||||||
|  |     </Preference> | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/benene_count" | ||||||
|  |             android:title="@string/benene" | ||||||
|  |             android:icon="@drawable/benene" | ||||||
|  |             app:summary="@string/benene_des" /> | ||||||
|  | </PreferenceScreen> | ||||||
							
								
								
									
										23
									
								
								app/src/main/res/xml/settings_media_lang.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								app/src/main/res/xml/settings_media_lang.xml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,23 @@ | ||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |         xmlns:app="http://schemas.android.com/apk/res-auto"> | ||||||
|  |     <PreferenceCategory app:icon="@color/transparent" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/locale_key" | ||||||
|  |             android:title="@string/app_language" | ||||||
|  |             android:icon="@drawable/ic_baseline_language_24" /> | ||||||
|  |     <Preference | ||||||
|  |             android:icon="@drawable/ic_baseline_language_24" | ||||||
|  |             android:key="@string/provider_lang_key" | ||||||
|  |             android:title="@string/provider_lang_settings" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/prefer_media_type_key" | ||||||
|  |             android:title="@string/preferred_media_settings" | ||||||
|  |             android:icon="@drawable/ic_baseline_play_arrow_24" /> | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/display_sub_key" | ||||||
|  |             android:title="@string/display_subbed_dubbed_settings" | ||||||
|  |             android:icon="@drawable/ic_outline_voice_over_off_24" /> | ||||||
|  | </PreferenceScreen> | ||||||
							
								
								
									
										24
									
								
								app/src/main/res/xml/settings_nginx.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								app/src/main/res/xml/settings_nginx.xml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | ||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |         xmlns:app="http://schemas.android.com/apk/res-auto"> | ||||||
|  |     <PreferenceCategory app:icon="@color/transparent" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/nginx_url_key" | ||||||
|  |             android:title="@string/nginx_url_pref" | ||||||
|  |             android:icon="@drawable/ic_baseline_play_arrow_24" /> | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/nginx_credentials" | ||||||
|  |             android:title="@string/nginx_credentials_title" | ||||||
|  |             android:icon="@drawable/video_locked" | ||||||
|  |             android:summary="@string/nginx_credentials_summary" /> | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/nginx_info" | ||||||
|  |             android:title="@string/nginx_info_title" | ||||||
|  |             android:icon="@drawable/ic_baseline_play_arrow_24" | ||||||
|  |             android:summary="@string/nginx_info_summary"> | ||||||
|  |         <intent | ||||||
|  |                 android:action="android.intent.action.VIEW" | ||||||
|  |                 android:data="https://www.sarlays.com/use-nginx-with-cloudstream/" /> | ||||||
|  |     </Preference> | ||||||
|  | </PreferenceScreen> | ||||||
							
								
								
									
										127
									
								
								app/src/main/res/xml/settings_player.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								app/src/main/res/xml/settings_player.xml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,127 @@ | ||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |         xmlns:app="http://schemas.android.com/apk/res-auto"> | ||||||
|  |     <PreferenceCategory app:icon="@color/transparent" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/subtitle_settings_key" | ||||||
|  |             android:title="@string/player_subtitles_settings" | ||||||
|  |             android:icon="@drawable/ic_outline_subtitles_24" | ||||||
|  |             app:summary="@string/player_subtitles_settings_des" /> | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/subtitle_settings_chromecast_key" | ||||||
|  |             android:title="@string/chromecast_subtitles_settings" | ||||||
|  |             android:icon="@drawable/ic_outline_subtitles_24" | ||||||
|  |             app:summary="@string/chromecast_subtitles_settings_des" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/dns_key" | ||||||
|  |             android:title="@string/dns_pref" | ||||||
|  |             android:summary="@string/dns_pref_summary" | ||||||
|  |             android:icon="@drawable/ic_baseline_dns_24" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/download_path_key" | ||||||
|  |             android:title="@string/download_path_pref" | ||||||
|  |             android:icon="@drawable/netflix_download" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/quality_pref_key" | ||||||
|  |             android:title="@string/watch_quality_pref" | ||||||
|  |             android:icon="@drawable/ic_baseline_hd_24" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/prefer_limit_title_key" | ||||||
|  |             android:title="@string/limit_title" | ||||||
|  |             android:icon="@drawable/ic_baseline_text_format_24" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/prefer_limit_title_rez_key" | ||||||
|  |             android:title="@string/limit_title_rez" | ||||||
|  |             android:icon="@drawable/ic_baseline_text_format_24" /> | ||||||
|  | 
 | ||||||
|  |     <SwitchPreference | ||||||
|  |             android:icon="@drawable/ic_baseline_picture_in_picture_alt_24" | ||||||
|  |             app:key="@string/pip_enabled_key" | ||||||
|  |             android:title="@string/picture_in_picture" | ||||||
|  |             android:summary="@string/picture_in_picture_des" | ||||||
|  |             app:defaultValue="true" /> | ||||||
|  |     <SwitchPreference | ||||||
|  |             android:icon="@drawable/ic_baseline_aspect_ratio_24" | ||||||
|  |             app:key="@string/player_resize_enabled_key" | ||||||
|  |             android:title="@string/player_size_settings" | ||||||
|  |             android:summary="@string/player_size_settings_des" | ||||||
|  |             app:defaultValue="true" /> | ||||||
|  |     <SwitchPreference | ||||||
|  |             android:icon="@drawable/ic_baseline_speed_24" | ||||||
|  |             app:key="@string/playback_speed_enabled_key" | ||||||
|  |             android:title="@string/eigengraumode_settings" | ||||||
|  |             android:summary="@string/eigengraumode_settings_des" | ||||||
|  |             app:defaultValue="false" /> | ||||||
|  |     <SwitchPreference | ||||||
|  |             android:icon="@drawable/ic_baseline_ondemand_video_24" | ||||||
|  |             app:key="@string/swipe_enabled_key" | ||||||
|  |             android:title="@string/swipe_to_seek_settings" | ||||||
|  |             android:summary="@string/swipe_to_seek_settings_des" | ||||||
|  |             app:defaultValue="true" /> | ||||||
|  |     <SwitchPreference | ||||||
|  |             android:icon="@drawable/ic_baseline_ondemand_video_24" | ||||||
|  |             app:key="@string/swipe_vertical_enabled_key" | ||||||
|  |             android:title="@string/swipe_to_change_settings" | ||||||
|  |             android:summary="@string/swipe_to_change_settings_des" | ||||||
|  |             app:defaultValue="true" /> | ||||||
|  |     <SwitchPreference | ||||||
|  |             android:icon="@drawable/ic_baseline_touch_app_24" | ||||||
|  |             app:key="@string/double_tap_enabled_key" | ||||||
|  |             android:title="@string/double_tap_to_seek_settings" | ||||||
|  |             android:summary="@string/double_tap_to_seek_settings_des" | ||||||
|  |             app:defaultValue="false" /> | ||||||
|  |     <SwitchPreference | ||||||
|  |             android:icon="@drawable/netflix_pause" | ||||||
|  |             app:key="@string/double_tap_pause_enabled_key" | ||||||
|  |             android:title="@string/double_tap_to_pause_settings" | ||||||
|  |             android:summary="@string/double_tap_to_pause_settings_des" | ||||||
|  |             app:defaultValue="false" /> | ||||||
|  | 
 | ||||||
|  |     <SeekBarPreference | ||||||
|  |             app:icon="@drawable/go_forward_30" | ||||||
|  |             app:adjustable="true" | ||||||
|  |             android:defaultValue="10" | ||||||
|  |             app:min="5" | ||||||
|  |             app:seekBarIncrement="5" | ||||||
|  |             app:showSeekBarValue="true" | ||||||
|  |             android:max="60" | ||||||
|  |             app:key="@string/double_tap_seek_time_key" | ||||||
|  |             android:title="@string/double_tap_to_seek_amount_settings" | ||||||
|  |             app:defaultValue="false" /> | ||||||
|  | 
 | ||||||
|  |     <SwitchPreference | ||||||
|  |             android:icon="@drawable/baseline_sync_24" | ||||||
|  |             app:key="@string/episode_sync_enabled_key" | ||||||
|  |             android:title="@string/episode_sync_settings" | ||||||
|  |             android:summary="@string/episode_sync_settings_des" | ||||||
|  |             app:defaultValue="true" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/video_buffer_disk_key" | ||||||
|  |             android:title="@string/video_buffer_disk_settings" | ||||||
|  |             android:summary="@string/video_disk_description" | ||||||
|  |             android:icon="@drawable/ic_baseline_storage_24" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/video_buffer_size_key" | ||||||
|  |             android:title="@string/video_buffer_size_settings" | ||||||
|  |             android:summary="@string/video_ram_description" | ||||||
|  |             android:icon="@drawable/ic_baseline_storage_24" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/video_buffer_length_key" | ||||||
|  |             android:title="@string/video_buffer_length_settings" | ||||||
|  |             android:summary="@string/video_ram_description" | ||||||
|  |             android:icon="@drawable/ic_baseline_storage_24" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/video_buffer_clear_key" | ||||||
|  |             android:title="@string/video_buffer_clear_settings" | ||||||
|  |             android:icon="@drawable/ic_baseline_delete_outline_24" /> | ||||||
|  | </PreferenceScreen> | ||||||
							
								
								
									
										51
									
								
								app/src/main/res/xml/settings_updates.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								app/src/main/res/xml/settings_updates.xml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | ||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |         xmlns:app="http://schemas.android.com/apk/res-auto"> | ||||||
|  |     <PreferenceCategory app:icon="@color/transparent" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:title="@string/check_for_update" | ||||||
|  |             app:summary="@string/app_version" | ||||||
|  |             app:key="@string/manual_check_update_key" | ||||||
|  |             app:icon="@drawable/ic_baseline_system_update_24" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:icon="@drawable/baseline_save_as_24" | ||||||
|  |             android:key="@string/backup_key" | ||||||
|  |             android:title="@string/backup_settings" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:icon="@drawable/baseline_restore_page_24" | ||||||
|  |             android:key="@string/restore_key" | ||||||
|  |             android:title="@string/restore_settings" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:key="@string/show_logcat_key" | ||||||
|  |             android:title="@string/show_log_cat" | ||||||
|  |             android:icon="@drawable/baseline_description_24" /> | ||||||
|  |     <SwitchPreference | ||||||
|  |             android:key="acra.disable" | ||||||
|  |             android:icon="@drawable/ic_baseline_bug_report_24" | ||||||
|  |             android:title="@string/pref_disable_acra" | ||||||
|  |             android:summaryOff="@string/bug_report_settings_off" | ||||||
|  |             android:summaryOn="@string/bug_report_settings_on" | ||||||
|  |             android:defaultValue="false" /> | ||||||
|  |     <SwitchPreference | ||||||
|  |             app:key="@string/auto_update_key" | ||||||
|  |             android:title="@string/updates_settings" | ||||||
|  |             android:summary="@string/updates_settings_des" | ||||||
|  |             app:defaultValue="true" | ||||||
|  |             android:icon="@drawable/ic_baseline_notifications_active_24" /> | ||||||
|  |     <SwitchPreference | ||||||
|  |             app:key="@string/prerelease_update_key" | ||||||
|  |             android:title="@string/uprereleases_settings" | ||||||
|  |             android:summary="@string/uprereleases_settings_des" | ||||||
|  |             app:defaultValue="false" | ||||||
|  |             android:icon="@drawable/ic_baseline_developer_mode_24" /> | ||||||
|  |     <SwitchPreference | ||||||
|  |             android:icon="@drawable/netflix_download" | ||||||
|  |             android:key="@string/killswitch_key" | ||||||
|  |             android:defaultValue="true" | ||||||
|  |             android:summary="@string/killswitch_settings_des" | ||||||
|  |             android:title="@string/killswitch_settings" /> | ||||||
|  | </PreferenceScreen> | ||||||
							
								
								
									
										45
									
								
								app/src/main/res/xml/settins_ui.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								app/src/main/res/xml/settins_ui.xml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,45 @@ | ||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |         xmlns:app="http://schemas.android.com/apk/res-auto"> | ||||||
|  |     <PreferenceCategory app:icon="@color/transparent" /> | ||||||
|  | 
 | ||||||
|  |     <Preference | ||||||
|  |             android:icon="@drawable/ic_baseline_color_lens_24" | ||||||
|  |             android:key="@string/primary_color_key" | ||||||
|  |             android:title="@string/primary_color_settings" /> | ||||||
|  |     <Preference | ||||||
|  |             android:icon="@drawable/ic_baseline_color_lens_24" | ||||||
|  |             android:key="@string/app_theme_key" | ||||||
|  |             android:title="@string/app_theme_settings" /> | ||||||
|  |     <Preference | ||||||
|  |             android:icon="@drawable/ic_baseline_tv_24" | ||||||
|  |             android:key="@string/app_layout_key" | ||||||
|  |             android:title="@string/app_layout" /> | ||||||
|  |     <Preference | ||||||
|  |             android:icon="@drawable/ic_baseline_tv_24" | ||||||
|  |             android:key="@string/poster_ui_key" | ||||||
|  |             android:title="@string/poster_ui_settings" /> | ||||||
|  |     <SwitchPreference | ||||||
|  |             android:icon="@drawable/search_icon" | ||||||
|  |             app:key="advanced_search" | ||||||
|  |             android:title="@string/advanced_search" | ||||||
|  |             android:summary="@string/advanced_search_des" | ||||||
|  |             app:defaultValue="true" /> | ||||||
|  |     <SwitchPreference | ||||||
|  |             android:defaultValue="true" | ||||||
|  |             android:icon="@drawable/baseline_grid_view_24" | ||||||
|  |             android:key="@string/bottom_title_key" | ||||||
|  |             android:summary="@string/bottom_title_settings_des" | ||||||
|  |             android:title="@string/bottom_title_settings" /> | ||||||
|  |     <SwitchPreference | ||||||
|  |             android:key="@string/show_fillers_key" | ||||||
|  |             android:icon="@drawable/ic_baseline_skip_next_24" | ||||||
|  |             android:title="@string/show_fillers_settings" | ||||||
|  |             android:defaultValue="false" /> | ||||||
|  |     <SwitchPreference | ||||||
|  |             android:icon="@drawable/ic_baseline_play_arrow_24" | ||||||
|  |             app:key="@string/random_button_key" | ||||||
|  |             android:title="@string/random_button_settings" | ||||||
|  |             android:summary="@string/random_button_settings_desc" | ||||||
|  |             app:defaultValue="false" /> | ||||||
|  | </PreferenceScreen> | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue