diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index 126366d2..ddc36dda 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -254,11 +254,8 @@ fun sortSubs(urls: List): List { } /** 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? { diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index 0c9a956d..8b1927d4 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -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 diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt index 9e016807..72d3bfcb 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt @@ -996,7 +996,7 @@ class PlayerFragment : Fragment() { activity?.unregisterReceiver(it) } activity?.hideSystemUI() - this.view?.let { activity?.hideKeyboard(it) } + this.view?.let { hideKeyboard(it) } } } 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 17a9fd79..4669a73e 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 @@ -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.filterSearchResponse(): List { @@ -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 = ParentItemAdapter(listOf(), { callback -> SearchHelper.handleSearchClickCallback(activity, callback) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt index 328090d3..f4fe9923 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt @@ -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(getString(R.string.legal_notice_key))!! val subdubPreference = findPreference(getString(R.string.display_sub_key))!! val providerLangPreference = findPreference(getString(R.string.provider_lang_key))!! + val allLayoutPreference = findPreference(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 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 ea6b1bec..a5d946de 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/UIHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/UIHelper.kt @@ -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 */ diff --git a/app/src/main/res/drawable/ic_baseline_tv_24.xml b/app/src/main/res/drawable/ic_baseline_tv_24.xml new file mode 100644 index 00000000..d578ed0d --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_tv_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 7f949ab5..17903e53 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -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"> + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 1aa84a8d..307122fd 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -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"> - + + diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml index c2a1504f..1184d36b 100644 --- a/app/src/main/res/values/array.xml +++ b/app/src/main/res/values/array.xml @@ -68,4 +68,16 @@ 7 8 + + + @string/automatic + @string/phone_layout + @string/tv_layout + + + + -1 + 0 + 1 + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e057a0f3..f0da348f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -24,7 +24,7 @@ show_fillers_key provider_lang_key dns_key - + app_layout_key %d %s | %sMB @@ -294,4 +294,9 @@ General Provider Languages + App Layout + + Auto + Tv Layout + Phone Layout diff --git a/app/src/main/res/xml/settings.xml b/app/src/main/res/xml/settings.xml index c866a536..c1af7fba 100644 --- a/app/src/main/res/xml/settings.xml +++ b/app/src/main/res/xml/settings.xml @@ -99,6 +99,16 @@ android:summary="@string/dns_pref_summary" android:icon="@drawable/ic_baseline_dns_24"> + + + +