mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
android tv layout stuff
This commit is contained in:
parent
0766f04ded
commit
3734871608
14 changed files with 207 additions and 30 deletions
|
@ -254,11 +254,8 @@ fun sortSubs(urls: List<SubtitleFile>): List<SubtitleFile> {
|
|||
}
|
||||
|
||||
/** https://www.imdb.com/title/tt2861424/ -> tt2861424 */
|
||||
fun imdbUrlToId(url: String): String {
|
||||
return url
|
||||
.removePrefix("https://www.imdb.com/title/")
|
||||
.removePrefix("https://imdb.com/title/tt2861424/")
|
||||
.replace("/", "")
|
||||
fun imdbUrlToId(url: String): String? {
|
||||
return Regex("/title/(tt[0-9]*)").find(url)?.groupValues?.get(1) ?: Regex("tt[0-9]{5,}").find(url)?.groupValues?.get(0)
|
||||
}
|
||||
|
||||
fun imdbUrlToIdNullable(url: String?): String? {
|
||||
|
|
|
@ -9,8 +9,10 @@ import android.content.pm.PackageManager
|
|||
import android.content.res.ColorStateList
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import android.view.*
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
|
@ -31,6 +33,7 @@ import com.lagradost.cloudstream3.receivers.VideoDownloadRestartReceiver
|
|||
import com.lagradost.cloudstream3.ui.APIRepository
|
||||
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO
|
||||
import com.lagradost.cloudstream3.ui.player.PlayerEventType
|
||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.loadResult
|
||||
import com.lagradost.cloudstream3.utils.DataStore.getKey
|
||||
|
@ -49,6 +52,7 @@ import kotlinx.android.synthetic.main.activity_main.*
|
|||
import kotlinx.android.synthetic.main.fragment_result.*
|
||||
import java.util.*
|
||||
import kotlin.concurrent.thread
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
|
||||
const val VLC_PACKAGE = "org.videolan.vlc"
|
||||
|
@ -136,8 +140,28 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
}
|
||||
}
|
||||
|
||||
private fun Activity.getRootView(): View {
|
||||
return findViewById(android.R.id.content)
|
||||
}
|
||||
|
||||
private fun Context.convertDpToPx(dp: Float): Float {
|
||||
return TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
dp,
|
||||
this.resources.displayMetrics
|
||||
)
|
||||
}
|
||||
|
||||
private fun Activity.isKeyboardOpen(): Boolean {
|
||||
val visibleBounds = Rect()
|
||||
this.getRootView().getWindowVisibleDisplayFrame(visibleBounds)
|
||||
val heightDiff = getRootView().height - visibleBounds.height()
|
||||
val marginOfError = this.convertDpToPx(50F).roundToInt()
|
||||
return heightDiff > marginOfError
|
||||
}
|
||||
|
||||
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
|
||||
//println("Keycode: $keyCode")
|
||||
println("Keycode: $keyCode")
|
||||
//showToast(
|
||||
// this,
|
||||
// "Got Keycode $keyCode | ${KeyEvent.keyCodeToString(keyCode)} \n ${event?.action}",
|
||||
|
@ -160,16 +184,16 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
KeyEvent.KEYCODE_BACK, KeyEvent.KEYCODE_A, KeyEvent.KEYCODE_MEDIA_SKIP_BACKWARD, KeyEvent.KEYCODE_MEDIA_REWIND -> {
|
||||
PlayerEventType.SeekBack
|
||||
}
|
||||
KeyEvent.KEYCODE_MEDIA_NEXT -> {
|
||||
KeyEvent.KEYCODE_MEDIA_NEXT, KeyEvent.KEYCODE_BUTTON_R1 -> {
|
||||
PlayerEventType.NextEpisode
|
||||
}
|
||||
KeyEvent.KEYCODE_MEDIA_PREVIOUS -> {
|
||||
KeyEvent.KEYCODE_MEDIA_PREVIOUS, KeyEvent.KEYCODE_BUTTON_L1 -> {
|
||||
PlayerEventType.PrevEpisode
|
||||
}
|
||||
KeyEvent.KEYCODE_MEDIA_PAUSE -> {
|
||||
PlayerEventType.Pause
|
||||
}
|
||||
KeyEvent.KEYCODE_MEDIA_PLAY -> {
|
||||
KeyEvent.KEYCODE_MEDIA_PLAY, KeyEvent.KEYCODE_BUTTON_START -> {
|
||||
PlayerEventType.Play
|
||||
}
|
||||
KeyEvent.KEYCODE_L, KeyEvent.KEYCODE_NUMPAD_7 -> {
|
||||
|
@ -184,13 +208,13 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
KeyEvent.KEYCODE_S, KeyEvent.KEYCODE_NUMPAD_9 -> {
|
||||
PlayerEventType.ShowMirrors
|
||||
}
|
||||
KeyEvent.KEYCODE_E, KeyEvent.KEYCODE_NUMPAD_3 -> {
|
||||
KeyEvent.KEYCODE_E, KeyEvent.KEYCODE_NUMPAD_3 -> {
|
||||
PlayerEventType.ShowSpeed
|
||||
}
|
||||
KeyEvent.KEYCODE_R, KeyEvent.KEYCODE_NUMPAD_0 -> {
|
||||
PlayerEventType.Resize
|
||||
}
|
||||
KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, KeyEvent.KEYCODE_P, KeyEvent.KEYCODE_SPACE -> { // space is not captured due to navigation
|
||||
KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, KeyEvent.KEYCODE_P, KeyEvent.KEYCODE_SPACE, KeyEvent.KEYCODE_NUMPAD_ENTER, KeyEvent.KEYCODE_ENTER -> { // space is not captured due to navigation
|
||||
PlayerEventType.PlayPauseToggle
|
||||
}
|
||||
else -> null
|
||||
|
@ -198,6 +222,12 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
playerEventListener?.invoke(playerEvent)
|
||||
}
|
||||
|
||||
when (keyCode) {
|
||||
KeyEvent.KEYCODE_DPAD_CENTER -> {
|
||||
println("DPAD PRESSED ${this.isKeyboardOpen()}")
|
||||
}
|
||||
}
|
||||
|
||||
return super.onKeyDown(keyCode, event)
|
||||
}
|
||||
|
||||
|
@ -371,7 +401,12 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
|
||||
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
|
||||
|
||||
setContentView(R.layout.activity_main)
|
||||
if (isTvSettings()) {
|
||||
setContentView(R.layout.activity_main_tv)
|
||||
} else {
|
||||
setContentView(R.layout.activity_main)
|
||||
}
|
||||
|
||||
// val navView: BottomNavigationView = findViewById(R.id.nav_view)
|
||||
|
||||
//https://stackoverflow.com/questions/52594181/how-to-know-if-user-has-disabled-picture-in-picture-feature-permission
|
||||
|
|
|
@ -996,7 +996,7 @@ class PlayerFragment : Fragment() {
|
|||
activity?.unregisterReceiver(it)
|
||||
}
|
||||
activity?.hideSystemUI()
|
||||
this.view?.let { activity?.hideKeyboard(it) }
|
||||
this.view?.let { hideKeyboard(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,9 +35,11 @@ import com.lagradost.cloudstream3.utils.SEARCH_PROVIDER_TOGGLE
|
|||
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.getGridIsCompact
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.showInputMethod
|
||||
import kotlinx.android.synthetic.main.fragment_search.*
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
|
||||
|
||||
class SearchFragment : Fragment() {
|
||||
companion object {
|
||||
fun List<SearchResponse>.filterSearchResponse(): List<SearchResponse> {
|
||||
|
@ -360,18 +362,13 @@ class SearchFragment : Fragment() {
|
|||
typesActive = it.getApiTypeSettings()
|
||||
}
|
||||
|
||||
/*main_search.setOnQueryTextFocusChangeListener { searchView, b ->
|
||||
main_search.setOnQueryTextFocusChangeListener { searchView, b ->
|
||||
if (b) {
|
||||
// https://stackoverflow.com/questions/12022715/unable-to-show-keyboard-automatically-in-the-searchview
|
||||
searchView?.postDelayed({
|
||||
(activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager?)?.showSoftInput(
|
||||
view.findFocus(),
|
||||
0
|
||||
)
|
||||
}, 200)
|
||||
showInputMethod(view.findFocus())
|
||||
}
|
||||
}
|
||||
main_search.onActionViewExpanded()*/
|
||||
//main_search.onActionViewExpanded()*/
|
||||
|
||||
val masterAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder> = ParentItemAdapter(listOf(), { callback ->
|
||||
SearchHelper.handleSearchClickCallback(activity, callback)
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package com.lagradost.cloudstream3.ui.settings
|
||||
|
||||
import android.app.UiModeManager
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
|
@ -30,6 +33,22 @@ import kotlin.concurrent.thread
|
|||
|
||||
|
||||
class SettingsFragment : PreferenceFragmentCompat() {
|
||||
companion object {
|
||||
fun Context.isTvSettings(): Boolean {
|
||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
var value = settingsManager.getInt(this.getString(R.string.app_layout_key), -1)
|
||||
if (value == -1) {
|
||||
value = if (isAutoTv()) 1 else 0
|
||||
}
|
||||
return value == 1
|
||||
}
|
||||
|
||||
private fun Context.isAutoTv(): Boolean {
|
||||
val uiModeManager = getSystemService(Context.UI_MODE_SERVICE) as UiModeManager?
|
||||
return uiModeManager?.currentModeType == Configuration.UI_MODE_TYPE_TELEVISION
|
||||
}
|
||||
}
|
||||
|
||||
private var beneneCount = 0
|
||||
|
||||
// idk, if you find a way of automating this it would be great
|
||||
|
@ -61,6 +80,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
val legalPreference = findPreference<Preference>(getString(R.string.legal_notice_key))!!
|
||||
val subdubPreference = findPreference<Preference>(getString(R.string.display_sub_key))!!
|
||||
val providerLangPreference = findPreference<Preference>(getString(R.string.provider_lang_key))!!
|
||||
val allLayoutPreference = findPreference<Preference>(getString(R.string.app_layout_key))!!
|
||||
|
||||
legalPreference.setOnPreferenceClickListener {
|
||||
val builder: AlertDialog.Builder = AlertDialog.Builder(it.context)
|
||||
|
@ -141,6 +161,29 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
return@setOnPreferenceClickListener true
|
||||
}
|
||||
|
||||
allLayoutPreference.setOnPreferenceClickListener {
|
||||
val prefNames = resources.getStringArray(R.array.app_layout)
|
||||
val prefValues = resources.getIntArray(R.array.app_layout_values)
|
||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
|
||||
val currentLayout =
|
||||
settingsManager.getInt(getString(R.string.app_layout_key), -1)
|
||||
context?.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
|
||||
}
|
||||
|
||||
watchQualityPreference.setOnPreferenceClickListener {
|
||||
val prefNames = resources.getStringArray(R.array.quality_pref)
|
||||
val prefValues = resources.getIntArray(R.array.quality_pref_values)
|
||||
|
@ -193,7 +236,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
settingsManager.edit().putInt(getString(R.string.benene_count), beneneCount).apply()
|
||||
it.summary = getString(R.string.benene_count_text).format(beneneCount)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
logError(e)
|
||||
}
|
||||
|
||||
return@setOnPreferenceClickListener true
|
||||
|
|
|
@ -36,6 +36,7 @@ import androidx.preference.PreferenceManager
|
|||
import com.bumptech.glide.load.model.GlideUrl
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
|
||||
|
@ -68,7 +69,7 @@ object UIHelper {
|
|||
activity?.window?.decorView?.clearFocus()
|
||||
view.let {
|
||||
if (it != null) {
|
||||
activity?.hideKeyboard(it)
|
||||
hideKeyboard(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -202,6 +203,10 @@ object UIHelper {
|
|||
}*/
|
||||
|
||||
fun Context.getStatusBarHeight(): Int {
|
||||
if(isTvSettings()) {
|
||||
return 0
|
||||
}
|
||||
|
||||
var result = 0
|
||||
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
|
||||
if (resourceId > 0) {
|
||||
|
@ -285,9 +290,14 @@ object UIHelper {
|
|||
) == AppOpsManager.MODE_ALLOWED
|
||||
}
|
||||
|
||||
fun Context.hideKeyboard(view: View) {
|
||||
val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
|
||||
fun hideKeyboard(view: View) {
|
||||
val inputMethodManager = view.context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager?
|
||||
inputMethodManager?.hideSoftInputFromWindow(view.windowToken, 0)
|
||||
}
|
||||
|
||||
fun showInputMethod(view: View) {
|
||||
val inputMethodManager = view.context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager?
|
||||
inputMethodManager?.showSoftInput(view, 0)
|
||||
}
|
||||
|
||||
/**id, stringRes */
|
||||
|
|
5
app/src/main/res/drawable/ic_baseline_tv_24.xml
Normal file
5
app/src/main/res/drawable/ic_baseline_tv_24.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M21,3L3,3c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h5v2h8v-2h5c1.1,0 1.99,-0.9 1.99,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,17L3,17L3,5h18v12z"/>
|
||||
</vector>
|
|
@ -6,7 +6,7 @@
|
|||
android:id="@+id/homeRoot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
|
||||
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|keyboard|navigation"
|
||||
android:paddingTop="0dp">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_height="match_parent"
|
||||
|
|
59
app/src/main/res/layout/activity_main_tv.xml
Normal file
59
app/src/main/res/layout/activity_main_tv.xml
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/homeRoot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|keyboard|navigation"
|
||||
android:paddingTop="0dp">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent">
|
||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
android:id="@+id/nav_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/darkBackground"
|
||||
|
||||
android:outlineSpotShadowColor="@color/transparent"
|
||||
android:outlineAmbientShadowColor="@color/transparent"
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:labelVisibilityMode="labeled"
|
||||
app:layout_constraintBottom_toTopOf="@+id/nav_host_fragment"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:menu="@menu/bottom_nav_menu"
|
||||
/>
|
||||
<fragment
|
||||
android:id="@+id/nav_host_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:defaultNavHost="true"
|
||||
app:layout_constraintTop_toBottomOf="@+id/nav_view"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:navGraph="@navigation/mobile_navigation"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toTopOf="@+id/nav_view"
|
||||
android:id="@+id/cast_mini_controller_holder"
|
||||
>
|
||||
<!--com.google.android.gms.cast.framework.media.widget.MiniControllerFragment-->
|
||||
<fragment
|
||||
app:customCastBackgroundColor="?attr/darkBackground"
|
||||
app:castControlButtons="@array/cast_mini_controller_control_buttons"
|
||||
android:id="@+id/cast_mini_controller"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
class="com.lagradost.cloudstream3.ui.MyMiniControllerFragment"
|
||||
tools:ignore="FragmentTagUsage">
|
||||
</fragment>
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</FrameLayout>
|
|
@ -103,7 +103,7 @@
|
|||
android:id="@+id/home_settings_bar"
|
||||
android:background="?attr/darkBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp">
|
||||
android:layout_height="70dp">
|
||||
<LinearLayout
|
||||
android:gravity="center"
|
||||
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
android:nextFocusLeft="@id/search_filter"
|
||||
android:nextFocusDown="@id/cardSpace"
|
||||
|
||||
android:imeOptions="actionSearch"
|
||||
android:inputType="text"
|
||||
|
||||
android:id="@+id/main_search"
|
||||
app:queryBackground="@color/transparent"
|
||||
app:searchIcon="@drawable/search_icon"
|
||||
|
@ -38,7 +41,7 @@
|
|||
android:layout_gravity="center_vertical"
|
||||
app:iconifiedByDefault="false"
|
||||
tools:ignore="RtlSymmetry">
|
||||
<requestFocus/>
|
||||
|
||||
|
||||
<androidx.core.widget.ContentLoadingProgressBar
|
||||
android:id="@+id/search_loading_bar"
|
||||
|
@ -70,6 +73,7 @@
|
|||
android:layout_gravity="end|center_vertical"
|
||||
app:tint="?attr/textColor"
|
||||
android:contentDescription="@string/change_providers_img_des">
|
||||
<requestFocus/>
|
||||
</ImageView>
|
||||
</FrameLayout>
|
||||
|
||||
|
|
|
@ -68,4 +68,16 @@
|
|||
<item>7</item>
|
||||
<item>8</item>
|
||||
</array>
|
||||
|
||||
<array name="app_layout">
|
||||
<item>@string/automatic</item>
|
||||
<item>@string/phone_layout</item>
|
||||
<item>@string/tv_layout</item>
|
||||
</array>
|
||||
|
||||
<array name="app_layout_values">
|
||||
<item>-1</item>
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
</array>
|
||||
</resources>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<string name="show_fillers_key" translatable="false">show_fillers_key</string>
|
||||
<string name="provider_lang_key" translatable="false">provider_lang_key</string>
|
||||
<string name="dns_key" translatable="false">dns_key</string>
|
||||
|
||||
<string name="app_layout_key" translatable="false">app_layout_key</string>
|
||||
|
||||
<!-- FORMAT MIGHT TRANSLATE, WILL CAUSE CRASH IF APPLIED WRONG -->
|
||||
<string name="extra_info_format" translatable="false" formatted="true">%d %s | %sMB</string>
|
||||
|
@ -294,4 +294,9 @@
|
|||
</string>
|
||||
<string name="general">General</string>
|
||||
<string name="provider_lang_settings">Provider Languages</string>
|
||||
<string name="app_layout">App Layout</string>
|
||||
|
||||
<string name="automatic">Auto</string>
|
||||
<string name="tv_layout">Tv Layout</string>
|
||||
<string name="phone_layout">Phone Layout</string>
|
||||
</resources>
|
||||
|
|
|
@ -99,6 +99,16 @@
|
|||
android:summary="@string/dns_pref_summary"
|
||||
android:icon="@drawable/ic_baseline_dns_24">
|
||||
</Preference>
|
||||
<Preference
|
||||
android:icon="@drawable/ic_baseline_language_24"
|
||||
android:key="@string/provider_lang_key"
|
||||
android:title="@string/provider_lang_settings">
|
||||
</Preference>
|
||||
<Preference
|
||||
android:icon="@drawable/ic_baseline_tv_24"
|
||||
android:key="@string/app_layout_key"
|
||||
android:title="@string/app_layout">
|
||||
</Preference>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory
|
||||
android:key="search"
|
||||
|
|
Loading…
Reference in a new issue