diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index 71a24ced..63183d73 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -1374,6 +1374,35 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { } } + observeNullable(viewModel.favoriteStatus) observeFavoriteStatus@{ isFavorite -> + resultviewPreviewFavorite.isVisible = isFavorite != null + if (isFavorite == null) return@observeFavoriteStatus + + val drawable = if (isFavorite) { + R.drawable.ic_baseline_favorite_24 + } else { + R.drawable.ic_baseline_favorite_border_24 + } + + resultviewPreviewFavorite.setImageResource(drawable) + } + + resultviewPreviewFavorite.setOnClickListener{ + viewModel.toggleFavoriteStatus(this@MainActivity) { newStatus: Boolean? -> + if (newStatus == null) return@toggleFavoriteStatus + + val message = if (newStatus) { + R.string.favorite_added + } else { + R.string.favorite_removed + } + + val name = (viewModel.page.value as? Resource.Success)?.value?.title + ?: txt(R.string.no_data).asStringNull(this@MainActivity) ?: "" + showToast(txt(message, name), Toast.LENGTH_SHORT) + } + } + if (!isTvSettings()) // dont want this clickable on tv layout resultviewPreviewDescription.setOnClickListener { view -> view.context?.let { ctx -> diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/ContentXExtractor.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/ContentXExtractor.kt index 61943b70..b7f84af1 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/ContentXExtractor.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/ContentXExtractor.kt @@ -18,7 +18,22 @@ open class ContentX : ExtractorApi() { val i_source = app.get(url, referer=ext_ref).text val i_extract = Regex("""window\.openPlayer\('([^']+)'""").find(i_source)!!.groups[1]?.value ?: throw ErrorLoadingException("i_extract is null") - val vid_source = app.get("https://contentx.me/source2.php?v=${i_extract}", referer=ext_ref).text + val sub_urls = mutableSetOf() + Regex("""\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"""").findAll(i_source).forEach { + val (sub_url, sub_lang) = it.destructured + + if (sub_url in sub_urls) { return@forEach } + sub_urls.add(sub_url) + + subtitleCallback.invoke( + SubtitleFile( + lang = sub_lang.replace("\\u0131", "ı").replace("\\u0130", "İ").replace("\\u00fc", "ü").replace("\\u00e7", "ç"), + url = fixUrl(sub_url.replace("\\", "")) + ) + ) + } + + val vid_source = app.get("${mainUrl}/source2.php?v=${i_extract}", referer=ext_ref).text val vid_extract = Regex("""file\":\"([^\"]+)""").find(vid_source)!!.groups[1]?.value ?: throw ErrorLoadingException("vid_extract is null") val m3u_link = vid_extract.replace("\\", "") @@ -35,7 +50,7 @@ open class ContentX : ExtractorApi() { val i_dublaj = Regex(""",\"([^']+)\",\"Türkçe""").find(i_source)!!.groups[1]?.value if (i_dublaj != null) { - val dublaj_source = app.get("https://contentx.me/source2.php?v=${i_dublaj}", referer=ext_ref).text + val dublaj_source = app.get("${mainUrl}/source2.php?v=${i_dublaj}", referer=ext_ref).text val dublaj_extract = Regex("""file\":\"([^\"]+)""").find(dublaj_source)!!.groups[1]?.value ?: throw ErrorLoadingException("dublaj_extract is null") val dublaj_link = dublaj_extract.replace("\\", "") diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/HotlingerExtractor.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/HotlingerExtractor.kt index 4a77cbf3..7389db68 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/HotlingerExtractor.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/HotlingerExtractor.kt @@ -5,4 +5,9 @@ package com.lagradost.cloudstream3.extractors class Hotlinger : ContentX() { override var name = "Hotlinger" override var mainUrl = "https://hotlinger.com" +} + +class FourCX : ContentX() { + override var name = "FourCX" + override var mainUrl = "https://four.contentx.me" } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamTape.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamTape.kt index ece8dc4b..2ee98c65 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamTape.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamTape.kt @@ -9,6 +9,10 @@ class StreamTapeNet : StreamTape() { override var mainUrl = "https://streamtape.net" } +class StreamTapeXyz : StreamTape() { + override var mainUrl = "https://streamtape.xyz" +} + class ShaveTape : StreamTape(){ override var mainUrl = "https://shavetape.cash" } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapterPreview.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapterPreview.kt index cc4ab895..b7f601ff 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapterPreview.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeParentItemAdapterPreview.kt @@ -216,6 +216,9 @@ class HomeParentItemAdapterPreview( viewModel.click(callback) return@HomeChildItemAdapter } + + (callback.view.context?.getActivity() as? MainActivity)?.loadPopup(callback.card, load = false) + /* callback.view.context?.getActivity()?.showOptionSelectStringRes( callback.view, callback.card.posterUrl, @@ -261,6 +264,7 @@ class HomeParentItemAdapterPreview( } } } + */ } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/library/LibraryFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/library/LibraryFragment.kt index a37fbcb3..8e9c8521 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/library/LibraryFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/library/LibraryFragment.kt @@ -20,11 +20,12 @@ import android.widget.Toast import androidx.annotation.StringRes import androidx.appcompat.widget.SearchView import androidx.core.view.allViews +import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import androidx.preference.PreferenceManager import androidx.recyclerview.widget.RecyclerView -import androidx.viewpager2.widget.ViewPager2 import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator import com.lagradost.cloudstream3.APIHolder @@ -35,6 +36,7 @@ import com.lagradost.cloudstream3.AcraApplication.Companion.setKey import com.lagradost.cloudstream3.CommonActivity import com.lagradost.cloudstream3.MainActivity import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.databinding.FragmentLibraryBinding import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.mvvm.debugAssert @@ -80,6 +82,8 @@ data class ProviderLibraryData( class LibraryFragment : Fragment() { companion object { + + val listLibraryItems = mutableListOf() fun newInstance() = LibraryFragment() /** @@ -91,6 +95,7 @@ class LibraryFragment : Fragment() { private val libraryViewModel: LibraryViewModel by activityViewModels() var binding: FragmentLibraryBinding? = null + private var toggleRandomButton = false override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -196,6 +201,25 @@ class LibraryFragment : Fragment() { } } + //Load value for toggling Random button. Hide at startup + context?.let { + val settingsManager = PreferenceManager.getDefaultSharedPreferences(it) + toggleRandomButton = + settingsManager.getBoolean( + getString(R.string.random_button_key), + false + ) && !SettingsFragment.isTvSettings() + binding?.libraryRandom?.visibility = View.GONE + } + + binding?.libraryRandom?.setOnClickListener { + if (listLibraryItems.isNotEmpty()) { + val listLibraryItem = listLibraryItems.random() + libraryViewModel.currentSyncApi?.syncIdName?.let { + loadLibraryItem(it, listLibraryItem.syncId,listLibraryItem) + } + } + } /** * Shows a plugin selection dialogue and saves the response @@ -277,8 +301,10 @@ class LibraryFragment : Fragment() { { isScrollingDown: Boolean -> if (isScrollingDown) { binding?.sortFab?.shrink() + binding?.libraryRandom?.shrink() } else { binding?.sortFab?.extend() + binding?.libraryRandom?.extend() } }) callback@{ searchClickCallback -> // To prevent future accidents @@ -303,52 +329,7 @@ class LibraryFragment : Fragment() { } SEARCH_ACTION_LOAD -> { - // This basically first selects the individual opener and if that is default then - // selects the whole list opener - val savedListSelection = - getKey("$currentAccount/$LIBRARY_FOLDER", syncName.name) - val savedSelection = getKey( - "$currentAccount/$LIBRARY_FOLDER", - syncId - ).takeIf { - it?.openType != LibraryOpenerType.Default - } ?: savedListSelection - - when (savedSelection?.openType) { - null, LibraryOpenerType.Default -> { - // Prevents opening MAL/AniList as a provider - if (APIHolder.getApiFromNameNull(searchClickCallback.card.apiName) != null) { - activity?.loadSearchResult( - searchClickCallback.card - ) - } else { - // Search when no provider can open - QuickSearchFragment.pushSearch( - activity, - searchClickCallback.card.name - ) - } - } - - LibraryOpenerType.None -> {} - LibraryOpenerType.Provider -> - savedSelection.providerData?.apiName?.let { apiName -> - activity?.loadResult( - searchClickCallback.card.url, - apiName, - ) - } - - LibraryOpenerType.Browser -> - openBrowser(searchClickCallback.card.url) - - LibraryOpenerType.Search -> { - QuickSearchFragment.pushSearch( - activity, - searchClickCallback.card.name - ) - } - } + loadLibraryItem(syncName, syncId, searchClickCallback.card) } } } @@ -414,6 +395,16 @@ class LibraryFragment : Fragment() { binding?.viewpager?.setCurrentItem(page, false) } + observe(libraryViewModel.currentPage){ + if (toggleRandomButton) { + listLibraryItems.clear() + listLibraryItems.addAll(pages[it].items) + libraryRandom.isVisible = listLibraryItems.isNotEmpty() + } else { + libraryRandom.isGone = true + } + } + // Only stop loading after 300ms to hide the fade effect the viewpager produces when updating // Without this there would be a flashing effect: // loading -> show old viewpager -> black screen -> show new viewpager @@ -512,6 +503,62 @@ class LibraryFragment : Fragment() { } })*/ } + + private fun loadLibraryItem( + syncName: SyncIdName, + syncId: String, + card: SearchResponse + ) { + // This basically first selects the individual opener and if that is default then + // selects the whole list opener + val savedListSelection = + getKey("$currentAccount/$LIBRARY_FOLDER", syncName.name) + + val savedSelection = getKey( + "$currentAccount/$LIBRARY_FOLDER", + syncId + ).takeIf { + it?.openType != LibraryOpenerType.Default + } ?: savedListSelection + + when (savedSelection?.openType) { + null, LibraryOpenerType.Default -> { + // Prevents opening MAL/AniList as a provider + if (APIHolder.getApiFromNameNull(card.apiName) != null) { + activity?.loadSearchResult( + card + ) + } else { + // Search when no provider can open + QuickSearchFragment.pushSearch( + activity, + card.name + ) + } + } + + LibraryOpenerType.None -> {} + LibraryOpenerType.Provider -> + savedSelection.providerData?.apiName?.let { apiName -> + activity?.loadResult( + card.url, + apiName, + ) + } + + LibraryOpenerType.Browser -> + openBrowser(card.url) + + LibraryOpenerType.Search -> { + QuickSearchFragment.pushSearch( + activity, + card.name + ) + } + } + + } + override fun onConfigurationChanged(newConfig: Configuration) { (binding?.viewpager?.adapter as? ViewpagerAdapter)?.rebind() super.onConfigurationChanged(newConfig) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt index f0622934..9dd97842 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt @@ -377,7 +377,6 @@ open class FullScreenPlayer : AbstractPlayerFragment() { } protected fun exitFullscreen() { - activity?.showSystemUI() //if (lockRotation) activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER @@ -389,6 +388,7 @@ open class FullScreenPlayer : AbstractPlayerFragment() { WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT } activity?.window?.attributes = lp + activity?.showSystemUI() } override fun onResume() { @@ -1481,6 +1481,7 @@ open class FullScreenPlayer : AbstractPlayerFragment() { playerGoBack.setOnClickListener { activity?.popCurrentPage() + activity?.showSystemUI() } playerSourcesBtt.setOnClickListener { @@ -1575,4 +1576,4 @@ open class FullScreenPlayer : AbstractPlayerFragment() { ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE // default orientation } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt index 0a626471..386e8df0 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt @@ -1383,6 +1383,7 @@ class GeneratorPlayer : FullScreenPlayer() { } binding?.playerLoadingGoBack?.setOnClickListener { + exitFullscreen() player.release() activity?.popCurrentPage() } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt index ad34309c..e7e50b9d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt @@ -2,6 +2,9 @@ package com.lagradost.cloudstream3.ui.result import android.annotation.SuppressLint import android.app.Dialog +import android.content.ClipData +import android.content.ClipboardManager +import android.content.Context import android.content.Intent import android.content.res.ColorStateList import android.graphics.Rect @@ -31,6 +34,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialog import com.lagradost.cloudstream3.APIHolder import com.lagradost.cloudstream3.APIHolder.updateHasTrailers import com.lagradost.cloudstream3.CommonActivity +import com.lagradost.cloudstream3.CommonActivity.showToast import com.lagradost.cloudstream3.DubStatus import com.lagradost.cloudstream3.LoadResponse import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent @@ -77,7 +81,6 @@ import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes import com.lagradost.cloudstream3.utils.UIHelper.setImage import com.lagradost.cloudstream3.utils.VideoDownloadHelper - open class ResultFragmentPhone : FullScreenPlayer() { private val gestureRegionsListener = object : PanelsChildGestureRegionObserver.GestureRegionsListener { override fun onGestureRegionsUpdate(gestureRegions: List) { @@ -247,6 +250,7 @@ open class ResultFragmentPhone : FullScreenPlayer() { } var selectSeason: String? = null + var selectEpisodeRange: String? = null private fun setUrl(url: String?) { if (url == null) { @@ -751,6 +755,17 @@ open class ResultFragmentPhone : FullScreenPlayer() { resultLoadingError.isVisible = data is Resource.Failure resultErrorText.isVisible = data is Resource.Failure resultReloadConnectionOpenInBrowser.isVisible = data is Resource.Failure + + resultTitle.setOnLongClickListener { + val titleToCopy = resultTitle.text + val clipboardManager = + activity?.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager? + clipboardManager?.setPrimaryClip(ClipData.newPlainText("Title", titleToCopy)) + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) { + showToast(R.string.copyTitle, Toast.LENGTH_SHORT) + } + return@setOnLongClickListener true + } } } @@ -1027,6 +1042,8 @@ open class ResultFragmentPhone : FullScreenPlayer() { observeNullable(viewModel.selectedRange) { range -> resultBinding?.apply { resultEpisodeSelect.setText(range) + + selectEpisodeRange = range?.asStringNull(resultEpisodeSelect.context) // If Season button is invisible then the bookmark button next focus is episode select if (resultEpisodeSelect.isVisible && !resultSeasonButton.isVisible && resultResumeParent.isVisible) { setFocusUpAndDown(resultResumeSeriesButton, resultEpisodeSelect) @@ -1060,9 +1077,12 @@ open class ResultFragmentPhone : FullScreenPlayer() { r to (text?.asStringNull(ctx) ?: return@mapNotNull null) } - view.popupMenuNoIconsAndNoStringRes(names.mapIndexed { index, (_, name) -> - index to name - }) { + activity?.showDialog( + names.map { it.second }, + names.indexOfFirst { it.second == selectEpisodeRange }, + "", + false, + {}) { itemId -> viewModel.changeRange(names[itemId].first) } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt index e60c388b..c24efe56 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt @@ -1006,6 +1006,7 @@ class ResultViewModel2 : ViewModel() { removeFavoritesData(currentId) statusChangedCallback?.invoke(false) _favoriteStatus.postValue(false) + MainActivity.reloadLibraryEvent(true) } else { checkAndWarnDuplicates( context, @@ -1050,8 +1051,8 @@ class ResultViewModel2 : ViewModel() { ) _favoriteStatus.postValue(true) - statusChangedCallback?.invoke(true) + MainActivity.reloadLibraryEvent(true) } } } @@ -2604,6 +2605,11 @@ class ResultViewModel2 : ViewModel() { this.rating = searchResponse.personalRating?.times(100) ?: searchResponse.rating this.tags = searchResponse.tags } + if (searchResponse is DataStoreHelper.BookmarkedData) { + this.plot = searchResponse.plot + this.rating = searchResponse.rating + this.tags = searchResponse.tags + } } val mainId = searchResponse.id ?: response.getId() diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt index 7f33c08d..243d9f4e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt @@ -264,6 +264,9 @@ class SearchFragment : Fragment() { builder.setContentView(selectMainpageBinding.root) builder.show() builder.let { dialog -> + val previousSelectedApis = selectedApis.toSet() + val previousSelectedSearchTypes = selectedSearchTypes.toSet() + val isMultiLang = ctx.getApiProviderLangSettings().let { set -> set.size > 1 || set.contains(AllLanguagesName) } @@ -352,7 +355,9 @@ class SearchFragment : Fragment() { selectedApis = currentSelectedApis // run search when dialog is close - search(binding?.mainSearch?.query?.toString()) + if(previousSelectedApis != selectedApis.toSet() || previousSelectedSearchTypes != selectedSearchTypes.toSet()) { + search(binding?.mainSearch?.query?.toString()) + } } updateList(selectedSearchTypes.toList()) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt index deb0eb3c..1ae1b9b5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -104,6 +104,7 @@ import com.lagradost.cloudstream3.extractors.TauVideo import com.lagradost.cloudstream3.extractors.SibNet import com.lagradost.cloudstream3.extractors.ContentX import com.lagradost.cloudstream3.extractors.Hotlinger +import com.lagradost.cloudstream3.extractors.FourCX import com.lagradost.cloudstream3.extractors.HDMomPlayer import com.lagradost.cloudstream3.extractors.HDPlayerSystem import com.lagradost.cloudstream3.extractors.VideoSeyred @@ -151,6 +152,7 @@ import com.lagradost.cloudstream3.extractors.StreamSB8 import com.lagradost.cloudstream3.extractors.StreamSB9 import com.lagradost.cloudstream3.extractors.StreamTape import com.lagradost.cloudstream3.extractors.StreamTapeNet +import com.lagradost.cloudstream3.extractors.StreamTapeXyz import com.lagradost.cloudstream3.extractors.StreamhideCom import com.lagradost.cloudstream3.extractors.StreamhideTo import com.lagradost.cloudstream3.extractors.Streamhub2 @@ -619,6 +621,7 @@ val extractorApis: MutableList = arrayListOf( StreamTape(), StreamTapeNet(), ShaveTape(), + StreamTapeXyz(), //mixdrop extractors MixDropBz(), @@ -683,6 +686,7 @@ val extractorApis: MutableList = arrayListOf( SibNet(), ContentX(), Hotlinger(), + FourCX(), HDMomPlayer(), HDPlayerSystem(), VideoSeyred(), diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/UIHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/UIHelper.kt index 09ea151d..d0a2e500 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/UIHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/UIHelper.kt @@ -35,6 +35,7 @@ import androidx.core.graphics.blue import androidx.core.graphics.drawable.toBitmapOrNull import androidx.core.graphics.green import androidx.core.graphics.red +import androidx.core.view.WindowInsetsCompat import androidx.core.view.marginBottom import androidx.core.view.marginLeft import androidx.core.view.marginRight @@ -401,81 +402,35 @@ object UIHelper { // Enables regular immersive mode. // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE. // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY - window.decorView.systemUiVisibility = ( - View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY - // Set the content to appear under the system bars so that the - // content doesn't resize when the system bars hide and show. - or View.SYSTEM_UI_FLAG_LAYOUT_STABLE - or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - // Hide the nav bar and status bar - or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - or View.SYSTEM_UI_FLAG_FULLSCREEN - // or View.SYSTEM_UI_FLAG_LOW_PROFILE - ) - // window.addFlags(View.KEEP_SCREEN_ON) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + + if (window.insetsController != null) { + + window!!.insetsController?.hide(WindowInsetsCompat.Type.systemBars()) + window!!.insetsController?.systemBarsBehavior = + WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + } + } + + else { + @Suppress("DEPRECATION") + window.decorView.systemUiVisibility = ( + View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY + // Set the content to appear under the system bars so that the + // content doesn't resize when the system bars hide and show. + or View.SYSTEM_UI_FLAG_LAYOUT_STABLE + or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + // Hide the nav bar and status bar + or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + or View.SYSTEM_UI_FLAG_FULLSCREEN + ) + } } fun FragmentActivity.popCurrentPage() { this.onBackPressedDispatcher.onBackPressed() - /*val currentFragment = supportFragmentManager.fragments.lastOrNull { - it.isVisible - } ?: return - - supportFragmentManager.beginTransaction() - .setCustomAnimations( - R.anim.enter_anim, - R.anim.exit_anim, - R.anim.pop_enter, - R.anim.pop_exit - ) - .remove(currentFragment) - .commitAllowingStateLoss()*/ } - /* - fun FragmentActivity.popCurrentPage(isInPlayer: Boolean, isInExpandedView: Boolean, isInResults: Boolean) { - val currentFragment = supportFragmentManager.fragments.lastOrNull { - it.isVisible - } - ?: //this.onBackPressedDispatcher.onBackPressed() - return - -/* - if (tvActivity == null) { - requestedOrientation = if (settingsManager?.getBoolean("force_landscape", false) == true) { - ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE - } else { - ActivityInfo.SCREEN_ORIENTATION_PORTRAIT - } - }*/ - - // No fucked animations leaving the player :) - when { - isInPlayer -> { - supportFragmentManager.beginTransaction() - //.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit) - .remove(currentFragment) - .commitAllowingStateLoss() - } - isInExpandedView && !isInResults -> { - supportFragmentManager.beginTransaction() - .setCustomAnimations( - R.anim.enter_anim,//R.anim.enter_from_right, - R.anim.exit_anim,//R.anim.exit_to_right, - R.anim.pop_enter, - R.anim.pop_exit - ) - .remove(currentFragment) - .commitAllowingStateLoss() - } - else -> { - supportFragmentManager.beginTransaction() - .setCustomAnimations(R.anim.enter_anim, R.anim.exit_anim, R.anim.pop_enter, R.anim.pop_exit) - .remove(currentFragment) - .commitAllowingStateLoss() - } - } - }*/ fun Context.getStatusBarHeight(): Int { if (isTvSettings()) { @@ -541,14 +496,27 @@ object UIHelper { } fun Activity.changeStatusBarState(hide: Boolean): Int { + @Suppress("DEPRECATION") return if (hide) { - window?.setFlags( - WindowManager.LayoutParams.FLAG_FULLSCREEN, - WindowManager.LayoutParams.FLAG_FULLSCREEN - ) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + window.insetsController?.hide(WindowInsets.Type.statusBars()) + + } else { + window.setFlags( + WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN + ) + } 0 } else { - window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + window.insetsController?.show(WindowInsets.Type.statusBars()) + + } else { + window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN) + } + this.getStatusBarHeight() } } @@ -556,13 +524,20 @@ object UIHelper { // Shows the system bars by removing all the flags // except for the ones that make the content appear under the system bars. fun Activity.showSystemUI() { - window.decorView.systemUiVisibility = - (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + + if (window.insetsController != null) { + window!!.insetsController?.show(WindowInsetsCompat.Type.systemBars()) + } + + } else { + @Suppress("DEPRECATION") + window.decorView.systemUiVisibility = + (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) + } changeStatusBarState(isEmulatorSettings()) - - // window.clearFlags(View.KEEP_SCREEN_ON) } fun Context.shouldShowPIPMode(isInPlayer: Boolean): Boolean { diff --git a/app/src/main/res/layout/bottom_resultview_preview.xml b/app/src/main/res/layout/bottom_resultview_preview.xml index fe3f9b8d..4a64114e 100644 --- a/app/src/main/res/layout/bottom_resultview_preview.xml +++ b/app/src/main/res/layout/bottom_resultview_preview.xml @@ -41,17 +41,36 @@ android:layout_marginStart="10dp" android:orientation="vertical"> - - android:textStyle="bold" - tools:text="The Perfect Run"> + - + + + + + + Close Clear Save + Title copied! Player Speed Subtitle Settings Text Color @@ -435,7 +436,7 @@ Features General Random Button - Show random button on Homepage + Show random button on Homepage and Library Provider languages App Layout Preferred media