migrate player language settings to DialogFragment; update hideBars()
* player language settings is now aDialogFragment * update hideBars() to work with any window & view combination * update hideBars() to use WindowCompat
This commit is contained in:
		| @ -53,9 +53,11 @@ import kotlinx.coroutines.launch | ||||
| import org.mosad.teapod.R | ||||
| import org.mosad.teapod.parser.crunchyroll.NoneEpisode | ||||
| import org.mosad.teapod.preferences.Preferences | ||||
| import org.mosad.teapod.ui.activity.player.fragment.LanguageSettingsDialogFragment | ||||
| import org.mosad.teapod.ui.components.EpisodesListPlayer | ||||
| import org.mosad.teapod.ui.components.LanguageSettingsPlayer | ||||
| import org.mosad.teapod.util.* | ||||
| import org.mosad.teapod.util.hideBars | ||||
| import org.mosad.teapod.util.isInPiPMode | ||||
| import org.mosad.teapod.util.navToLauncherTask | ||||
| import java.util.* | ||||
| import java.util.concurrent.TimeUnit | ||||
| import kotlin.concurrent.scheduleAtFixedRate | ||||
| @ -486,11 +488,8 @@ class PlayerActivity : AppCompatActivity() { | ||||
|     } | ||||
|  | ||||
|     private fun showLanguageSettings() { | ||||
|         val languageSettings = LanguageSettingsPlayer(this, model = model).apply { | ||||
|             onViewRemovedAction = { model.player.play() } | ||||
|         } | ||||
|         player_layout.addView(languageSettings) | ||||
|         pauseAndHideControls() | ||||
|         LanguageSettingsDialogFragment().show(supportFragmentManager, LanguageSettingsDialogFragment.TAG) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|  | ||||
| @ -1,54 +1,75 @@ | ||||
| package org.mosad.teapod.ui.components | ||||
| package org.mosad.teapod.ui.activity.player.fragment | ||||
| 
 | ||||
| import android.content.Context | ||||
| import android.content.DialogInterface | ||||
| import android.graphics.Color | ||||
| import android.graphics.Typeface | ||||
| import android.util.AttributeSet | ||||
| import android.os.Bundle | ||||
| import android.util.TypedValue | ||||
| import android.view.Gravity | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.widget.LinearLayout | ||||
| import android.widget.TextView | ||||
| import androidx.core.view.children | ||||
| import androidx.fragment.app.DialogFragment | ||||
| import androidx.lifecycle.ViewModelProvider | ||||
| import org.mosad.teapod.R | ||||
| import org.mosad.teapod.databinding.PlayerLanguageSettingsBinding | ||||
| import org.mosad.teapod.ui.activity.player.PlayerViewModel | ||||
| import org.mosad.teapod.util.hideBars | ||||
| import java.util.* | ||||
| 
 | ||||
| // TODO port to DialogFragment | ||||
| class LanguageSettingsPlayer @JvmOverloads constructor( | ||||
|     context: Context, | ||||
|     attrs: AttributeSet? = null, | ||||
|     defStyleAttr: Int = 0, | ||||
|     model: PlayerViewModel? = null | ||||
| ) : LinearLayout(context, attrs, defStyleAttr) { | ||||
| class LanguageSettingsDialogFragment : DialogFragment() { | ||||
| 
 | ||||
|     private val binding = PlayerLanguageSettingsBinding.inflate(LayoutInflater.from(context), this, true) | ||||
|     var onViewRemovedAction: (() -> Unit)? = null | ||||
|     private lateinit var model: PlayerViewModel | ||||
|     private lateinit var binding: PlayerLanguageSettingsBinding | ||||
| 
 | ||||
|     private var selectedLocale = model?.currentLanguage ?: Locale.ROOT | ||||
|     private var selectedLocale = Locale.ROOT | ||||
| 
 | ||||
|     init { | ||||
|         model?.let { m -> | ||||
|             m.currentPlayback.streams.adaptive_hls.keys.forEach { languageTag -> | ||||
|                 val locale = Locale.forLanguageTag(languageTag) | ||||
|                 addLanguage(locale, locale == m.currentLanguage) { v -> | ||||
|                     selectedLocale = locale | ||||
|                     updateSelectedLanguage(v as TextView) | ||||
|                 } | ||||
|     companion object { | ||||
|         const val TAG = "LanguageSettingsDialogFragment" | ||||
|     } | ||||
| 
 | ||||
|     override fun onCreate(savedInstanceState: Bundle?) { | ||||
|         super.onCreate(savedInstanceState) | ||||
|         setStyle(STYLE_NO_TITLE, R.style.FullScreenDialogStyle) | ||||
|         model = ViewModelProvider(requireActivity())[PlayerViewModel::class.java] | ||||
|         selectedLocale = model.currentLanguage | ||||
|     } | ||||
| 
 | ||||
|     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { | ||||
|         binding = PlayerLanguageSettingsBinding.inflate(inflater, container, false) | ||||
|         return binding.root | ||||
|     } | ||||
| 
 | ||||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||
|         super.onViewCreated(view, savedInstanceState) | ||||
| 
 | ||||
|         model.currentPlayback.streams.adaptive_hls.keys.forEach { languageTag -> | ||||
|             val locale = Locale.forLanguageTag(languageTag) | ||||
|             addLanguage(locale, locale == model.currentLanguage) { v -> | ||||
|                 selectedLocale = locale | ||||
|                 updateSelectedLanguage(v as TextView) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         binding.buttonCloseLanguageSettings.setOnClickListener { close() } | ||||
|         binding.buttonCancel.setOnClickListener { close() } | ||||
|         binding.buttonCloseLanguageSettings.setOnClickListener { dismiss() } | ||||
|         binding.buttonCancel.setOnClickListener { dismiss() } | ||||
|         binding.buttonSelect.setOnClickListener { | ||||
|             model?.setLanguage(selectedLocale) | ||||
|             close() | ||||
|             model.setLanguage(selectedLocale) | ||||
|             dismiss() | ||||
|         } | ||||
| 
 | ||||
|         // initially hide the status and navigation bar | ||||
|         hideBars(requireDialog().window, binding.root) | ||||
|     } | ||||
| 
 | ||||
|     private fun addLanguage(locale: Locale, isSelected: Boolean, onClick: OnClickListener) { | ||||
|     override fun onDismiss(dialog: DialogInterface) { | ||||
|         super.onDismiss(dialog) | ||||
|         model.player.play() | ||||
|     } | ||||
| 
 | ||||
|     private fun addLanguage(locale: Locale, isSelected: Boolean, onClick: View.OnClickListener) { | ||||
|         val text = TextView(context).apply { | ||||
|             height = 96 | ||||
|             gravity = Gravity.CENTER_VERTICAL | ||||
| @ -83,12 +104,11 @@ class LanguageSettingsPlayer @JvmOverloads constructor( | ||||
|                     setPadding(75, 0, 0, 0) | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         // set selected to selected style | ||||
|         selected.apply { | ||||
|             setTextColor(context.resources.getColor(R.color.exo_white, context.theme)) | ||||
|             setTextColor(context.resources.getColor(R.color.player_white, context.theme)) | ||||
|             setTypeface(null, Typeface.BOLD) | ||||
|             setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.ic_baseline_check_24, 0, 0, 0) | ||||
|             setPadding(0, 0, 0, 0) | ||||
| @ -96,10 +116,4 @@ class LanguageSettingsPlayer @JvmOverloads constructor( | ||||
|             compoundDrawablePadding = 12 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private fun close() { | ||||
|         (this.parent as ViewGroup).removeView(this) | ||||
|         onViewRemovedAction?.invoke() | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -5,9 +5,6 @@ import android.app.ActivityManager | ||||
| import android.content.Context | ||||
| import android.content.Intent | ||||
| import android.os.Build | ||||
| import android.view.View | ||||
| import android.view.WindowInsets | ||||
| import android.view.WindowInsetsController | ||||
| import androidx.fragment.app.Fragment | ||||
| import androidx.fragment.app.FragmentActivity | ||||
| import androidx.fragment.app.commit | ||||
| @ -31,28 +28,7 @@ fun FragmentActivity.showFragment(fragment: Fragment) { | ||||
|  * hide the status and navigation bar | ||||
|  */ | ||||
| fun Activity.hideBars() { | ||||
|     window.apply { | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { | ||||
|             setDecorFitsSystemWindows(false) | ||||
|             insetsController?.apply { | ||||
|                 hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars()) | ||||
|                 systemBarsBehavior = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { | ||||
|                     WindowInsetsController.BEHAVIOR_DEFAULT | ||||
|                 } else { | ||||
|                     @Suppress("deprecation") | ||||
|                     WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             @Suppress("deprecation") | ||||
|             decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE | ||||
|                     or View.SYSTEM_UI_FLAG_LAYOUT_STABLE | ||||
|                     or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | ||||
|                     or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | ||||
|                     or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | ||||
|                     or View.SYSTEM_UI_FLAG_FULLSCREEN) | ||||
|         } | ||||
|     } | ||||
|     hideBars(window, window.decorView.rootView) | ||||
| } | ||||
|  | ||||
| fun Activity.isInPiPMode(): Boolean { | ||||
|  | ||||
| @ -1,6 +1,11 @@ | ||||
| package org.mosad.teapod.util | ||||
|  | ||||
| import android.view.View | ||||
| import android.view.Window | ||||
| import android.widget.TextView | ||||
| import androidx.core.view.WindowCompat | ||||
| import androidx.core.view.WindowInsetsCompat | ||||
| import androidx.core.view.WindowInsetsControllerCompat | ||||
| import org.mosad.teapod.parser.crunchyroll.Collection | ||||
| import org.mosad.teapod.parser.crunchyroll.ContinueWatchingItem | ||||
| import org.mosad.teapod.parser.crunchyroll.Item | ||||
| @ -50,3 +55,13 @@ fun Locale.toDisplayString(fallback: String): String { | ||||
|         fallback | ||||
|     } | ||||
| } | ||||
|  | ||||
| fun hideBars(window: Window?, root: View) { | ||||
|     if (window != null) { | ||||
|         WindowCompat.setDecorFitsSystemWindows(window, false) | ||||
|         WindowInsetsControllerCompat(window, root).let { controller -> | ||||
|             controller.hide(WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.navigationBars()) | ||||
|             controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_SWIPE | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -24,7 +24,7 @@ | ||||
|         android:layout_height="70dp" | ||||
|         android:layout_gravity="center" | ||||
|         android:indeterminate="true" | ||||
|         app:indicatorColor="@color/exo_white" | ||||
|         app:indicatorColor="@color/player_white" | ||||
|         tools:visibility="visible" /> | ||||
|  | ||||
|     <LinearLayout | ||||
| @ -84,7 +84,7 @@ | ||||
|         android:textColor="@android:color/primary_text_light" | ||||
|         android:textSize="16sp" | ||||
|         android:visibility="gone" | ||||
|         app:backgroundTint="@color/exo_white" | ||||
|         app:backgroundTint="@color/player_white" | ||||
|         app:iconGravity="textStart" /> | ||||
|  | ||||
|     <com.google.android.material.button.MaterialButton | ||||
| @ -100,7 +100,7 @@ | ||||
|         android:textColor="@android:color/primary_text_light" | ||||
|         android:textSize="16sp" | ||||
|         android:visibility="gone" | ||||
|         app:backgroundTint="@color/exo_white" | ||||
|         app:backgroundTint="@color/player_white" | ||||
|         app:iconGravity="textStart" /> | ||||
|  | ||||
| </FrameLayout> | ||||
| @ -37,7 +37,7 @@ | ||||
|             android:layout_marginEnd="44dp" | ||||
|             android:text="@string/subtitles" | ||||
|             android:textAlignment="center" | ||||
|             android:textColor="@color/exo_white" | ||||
|             android:textColor="@color/player_white" | ||||
|             android:textSize="16sp" | ||||
|             android:textStyle="bold" /> | ||||
|  | ||||
| @ -75,7 +75,7 @@ | ||||
|             android:layout_marginEnd="7dp" | ||||
|             android:text="@string/cancel" | ||||
|             android:textAllCaps="false" | ||||
|             android:textColor="@color/exo_white" | ||||
|             android:textColor="@color/player_white" | ||||
|             android:textSize="16sp" | ||||
|             app:backgroundTint="@color/buttonBackgroundLight" | ||||
|             app:layout_constraintBottom_toBottomOf="parent" | ||||
|  | ||||
| @ -26,6 +26,9 @@ | ||||
|     <color name="buttonBackgroundDark">#ffffff</color> | ||||
|     <color name="controlHighlightDark">#11ffffff</color> | ||||
|  | ||||
|     <!-- player colors --> | ||||
|     <color name="player_white">#ffffff</color> | ||||
|  | ||||
|     <color name="ic_launcher_background">#ffffff</color> | ||||
|     <color name="ic_splash_background">#ffffff</color> | ||||
| </resources> | ||||
| @ -86,4 +86,13 @@ | ||||
|         <item name="android:popupBackground">?themeSecondary</item> | ||||
|     </style> | ||||
|  | ||||
|     <style name="FullScreenDialogStyle" parent="Theme.MaterialComponents.Light.NoActionBar"> | ||||
|         <item name="android:windowNoTitle">true</item> | ||||
|         <item name="android:windowFullscreen">true</item> | ||||
|         <item name="android:windowActionBar">false</item> | ||||
|         <item name="android:windowIsFloating">false</item> | ||||
|         <item name="android:windowBackground">@android:color/transparent</item> | ||||
|     </style> | ||||
|  | ||||
|  | ||||
| </resources> | ||||
		Reference in New Issue
	
	Block a user