mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
android tv popup (#390)
This commit is contained in:
parent
1804484860
commit
a8f5dcc943
5 changed files with 238 additions and 42 deletions
|
@ -48,11 +48,11 @@ import com.lagradost.cloudstream3.utils.DataStoreHelper.removeLastWatched
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.setResultWatchState
|
import com.lagradost.cloudstream3.utils.DataStoreHelper.setResultWatchState
|
||||||
import com.lagradost.cloudstream3.utils.Event
|
import com.lagradost.cloudstream3.utils.Event
|
||||||
import com.lagradost.cloudstream3.utils.HOMEPAGE_API
|
import com.lagradost.cloudstream3.utils.HOMEPAGE_API
|
||||||
|
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showOptionSelectStringRes
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
|
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbarView
|
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbarView
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.getSpanCount
|
import com.lagradost.cloudstream3.utils.UIHelper.getSpanCount
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIcons
|
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes
|
import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.setImage
|
import com.lagradost.cloudstream3.utils.UIHelper.setImage
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.setImageBlur
|
import com.lagradost.cloudstream3.utils.UIHelper.setImageBlur
|
||||||
|
@ -597,20 +597,63 @@ class HomeFragment : Fragment() {
|
||||||
nextFocusDown = home_bookmarked_child_recyclerview?.nextFocusDownId
|
nextFocusDown = home_bookmarked_child_recyclerview?.nextFocusDownId
|
||||||
) { callback ->
|
) { callback ->
|
||||||
if (callback.action == SEARCH_ACTION_SHOW_METADATA) {
|
if (callback.action == SEARCH_ACTION_SHOW_METADATA) {
|
||||||
val id = callback.card.id
|
activity?.showOptionSelectStringRes(
|
||||||
if (id != null) {
|
callback.view,
|
||||||
callback.view.popupMenuNoIcons(
|
callback.card.posterUrl,
|
||||||
listOf(
|
listOf(
|
||||||
Pair(
|
R.string.action_open_watching,
|
||||||
0,
|
R.string.action_remove_from_bookmarks,
|
||||||
|
),
|
||||||
|
listOf(
|
||||||
|
R.string.action_open_play,
|
||||||
|
R.string.action_open_watching,
|
||||||
R.string.action_remove_from_bookmarks
|
R.string.action_remove_from_bookmarks
|
||||||
)
|
)
|
||||||
)
|
) { (isTv, actionId) ->
|
||||||
) {
|
fun play() {
|
||||||
if (itemId == 0) {
|
activity.loadSearchResult(callback.card, START_ACTION_RESUME_LATEST)
|
||||||
setResultWatchState(id, WatchType.NONE.internalId)
|
|
||||||
reloadStored()
|
reloadStored()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun remove() {
|
||||||
|
setResultWatchState(callback.card.id, WatchType.NONE.internalId)
|
||||||
|
reloadStored()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun info() {
|
||||||
|
handleSearchClickCallback(
|
||||||
|
activity,
|
||||||
|
SearchClickCallback(
|
||||||
|
SEARCH_ACTION_LOAD,
|
||||||
|
callback.view,
|
||||||
|
-1,
|
||||||
|
callback.card
|
||||||
|
)
|
||||||
|
)
|
||||||
|
reloadStored()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTv) {
|
||||||
|
when (actionId) {
|
||||||
|
0 -> {
|
||||||
|
play()
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
info()
|
||||||
|
}
|
||||||
|
2 -> {
|
||||||
|
remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
when (actionId) {
|
||||||
|
0 -> {
|
||||||
|
info()
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -624,15 +667,33 @@ class HomeFragment : Fragment() {
|
||||||
nextFocusDown = home_watch_child_recyclerview?.nextFocusDownId
|
nextFocusDown = home_watch_child_recyclerview?.nextFocusDownId
|
||||||
) { callback ->
|
) { callback ->
|
||||||
if (callback.action == SEARCH_ACTION_SHOW_METADATA) {
|
if (callback.action == SEARCH_ACTION_SHOW_METADATA) {
|
||||||
val id = callback.card.id
|
activity?.showOptionSelectStringRes(
|
||||||
if (id != null) {
|
callback.view,
|
||||||
callback.view.popupMenuNoIcons(
|
callback.card.posterUrl,
|
||||||
listOf(
|
listOf(
|
||||||
Pair(1, R.string.action_open_watching),
|
R.string.action_open_watching,
|
||||||
Pair(0, R.string.action_remove_watching)
|
R.string.action_remove_watching
|
||||||
|
),
|
||||||
|
listOf(
|
||||||
|
R.string.action_open_play,
|
||||||
|
R.string.action_open_watching,
|
||||||
|
R.string.action_remove_watching
|
||||||
)
|
)
|
||||||
) {
|
) { (isTv, actionId) ->
|
||||||
if (itemId == 1) {
|
fun play() {
|
||||||
|
activity.loadSearchResult(callback.card, START_ACTION_RESUME_LATEST)
|
||||||
|
reloadStored()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun remove() {
|
||||||
|
val card = callback.card
|
||||||
|
if (card is DataStoreHelper.ResumeWatchingResult) {
|
||||||
|
removeLastWatched(card.parentId)
|
||||||
|
reloadStored()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun info() {
|
||||||
handleSearchClickCallback(
|
handleSearchClickCallback(
|
||||||
activity,
|
activity,
|
||||||
SearchClickCallback(
|
SearchClickCallback(
|
||||||
|
@ -644,14 +705,30 @@ class HomeFragment : Fragment() {
|
||||||
)
|
)
|
||||||
reloadStored()
|
reloadStored()
|
||||||
}
|
}
|
||||||
if (itemId == 0) {
|
|
||||||
val card = callback.card
|
if (isTv) {
|
||||||
if (card is DataStoreHelper.ResumeWatchingResult) {
|
when (actionId) {
|
||||||
removeLastWatched(card.parentId)
|
0 -> {
|
||||||
reloadStored()
|
play()
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
info()
|
||||||
|
}
|
||||||
|
2 -> {
|
||||||
|
remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
when (actionId) {
|
||||||
|
0 -> {
|
||||||
|
info()
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
remove()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
homeHandleSearch(callback)
|
homeHandleSearch(callback)
|
||||||
|
|
|
@ -2,17 +2,71 @@ package com.lagradost.cloudstream3.utils
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
|
import android.view.View
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.*
|
||||||
import androidx.core.view.marginLeft
|
|
||||||
import androidx.core.view.marginRight
|
|
||||||
import androidx.core.view.marginTop
|
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
||||||
|
import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes
|
||||||
|
import com.lagradost.cloudstream3.utils.UIHelper.setImage
|
||||||
|
|
||||||
object SingleSelectionHelper {
|
object SingleSelectionHelper {
|
||||||
|
fun Activity.showOptionSelectStringRes(
|
||||||
|
view: View?,
|
||||||
|
poster: String?,
|
||||||
|
options: List<Int>,
|
||||||
|
tvOptions: List<Int> = listOf(),
|
||||||
|
callback: (Pair<Boolean, Int>) -> Unit
|
||||||
|
) {
|
||||||
|
this.showOptionSelect(view, poster, options.map { this.getString(it) },tvOptions.map { this.getString(it) }, callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Activity.showOptionSelect(
|
||||||
|
view: View?,
|
||||||
|
poster: String?,
|
||||||
|
options: List<String>,
|
||||||
|
tvOptions: List<String>,
|
||||||
|
callback: (Pair<Boolean, Int>) -> Unit
|
||||||
|
) {
|
||||||
|
if (this.isTvSettings()) {
|
||||||
|
val builder =
|
||||||
|
AlertDialog.Builder(this, R.style.AlertDialogCustom)
|
||||||
|
.setView(R.layout.options_popup_tv)
|
||||||
|
|
||||||
|
val dialog = builder.create()
|
||||||
|
dialog.show()
|
||||||
|
|
||||||
|
dialog.findViewById<ListView>(R.id.listview1)?.let { listView ->
|
||||||
|
listView.choiceMode = AbsListView.CHOICE_MODE_SINGLE
|
||||||
|
listView.adapter = ArrayAdapter<String>(this, R.layout.sort_bottom_single_choice_color).apply {
|
||||||
|
addAll(tvOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
listView.setOnItemClickListener { _, _, i, _ ->
|
||||||
|
callback.invoke(Pair(true,i))
|
||||||
|
dialog.dismissSafe(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.findViewById<ImageView>(R.id.imageView)?.apply {
|
||||||
|
isGone = poster.isNullOrEmpty()
|
||||||
|
setImage(poster)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
view?.popupMenuNoIconsAndNoStringRes(options.mapIndexed { index, s ->
|
||||||
|
Pair(
|
||||||
|
index,
|
||||||
|
s
|
||||||
|
)
|
||||||
|
}) {
|
||||||
|
callback(Pair(false,this.itemId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun Activity.showDialog(
|
fun Activity.showDialog(
|
||||||
dialog: Dialog,
|
dialog: Dialog,
|
||||||
items: List<String>,
|
items: List<String>,
|
||||||
|
@ -98,7 +152,8 @@ object SingleSelectionHelper {
|
||||||
callback: (List<Int>) -> Unit,
|
callback: (List<Int>) -> Unit,
|
||||||
) {
|
) {
|
||||||
val builder =
|
val builder =
|
||||||
AlertDialog.Builder(this, R.style.AlertDialogCustom).setView(R.layout.bottom_selection_dialog)
|
AlertDialog.Builder(this, R.style.AlertDialogCustom)
|
||||||
|
.setView(R.layout.bottom_selection_dialog)
|
||||||
|
|
||||||
val dialog = builder.create()
|
val dialog = builder.create()
|
||||||
dialog.show()
|
dialog.show()
|
||||||
|
@ -114,7 +169,8 @@ object SingleSelectionHelper {
|
||||||
callback: (Int) -> Unit,
|
callback: (Int) -> Unit,
|
||||||
) {
|
) {
|
||||||
val builder =
|
val builder =
|
||||||
AlertDialog.Builder(this, R.style.AlertDialogCustom).setView(R.layout.bottom_selection_dialog)
|
AlertDialog.Builder(this, R.style.AlertDialogCustom)
|
||||||
|
.setView(R.layout.bottom_selection_dialog)
|
||||||
|
|
||||||
val dialog = builder.create()
|
val dialog = builder.create()
|
||||||
dialog.show()
|
dialog.show()
|
||||||
|
|
44
app/src/main/res/layout/options_popup_tv.xml
Normal file
44
app/src/main/res/layout/options_popup_tv.xml
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:foreground="@drawable/outline_drawable"
|
||||||
|
android:layout_margin="2dp"
|
||||||
|
android:layout_width="114dp"
|
||||||
|
android:layout_height="180dp"
|
||||||
|
android:layout_marginBottom="2dp"
|
||||||
|
android:elevation="10dp"
|
||||||
|
app:cardCornerRadius="@dimen/rounded_image_radius"
|
||||||
|
android:id="@+id/backgroundCard"
|
||||||
|
app:cardBackgroundColor="?attr/primaryGrayBackground">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:duplicateParentState="true"
|
||||||
|
android:id="@+id/imageView"
|
||||||
|
tools:src="@drawable/example_poster"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/search_poster_img_des" />
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:nextFocusRight="@id/cancel_btt"
|
||||||
|
android:nextFocusLeft="@id/apply_btt"
|
||||||
|
|
||||||
|
android:nextFocusUp="@id/toggle1"
|
||||||
|
android:nextFocusDown="@id/apply_btt"
|
||||||
|
|
||||||
|
android:id="@+id/listview1"
|
||||||
|
android:requiresFadingEdge="vertical"
|
||||||
|
tools:listitem="@layout/sort_bottom_single_choice_color"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_rowWeight="1" />
|
||||||
|
</LinearLayout>
|
18
app/src/main/res/layout/sort_bottom_single_choice_color.xml
Normal file
18
app/src/main/res/layout/sort_bottom_single_choice_color.xml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
style="@style/AppTextViewStyle"
|
||||||
|
android:id="@android:id/text1"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="?android:attr/listPreferredItemHeightSmall"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:textColor="@color/text_selection_color"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingStart="12dp"
|
||||||
|
android:paddingEnd="7dip"
|
||||||
|
tools:text="TEST"
|
||||||
|
android:checkMark="?android:attr/listChoiceIndicatorSingle"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:foreground="?attr/selectableItemBackgroundBorderless" />
|
|
@ -157,6 +157,7 @@
|
||||||
|
|
||||||
<string name="action_remove_watching">Remove</string>
|
<string name="action_remove_watching">Remove</string>
|
||||||
<string name="action_open_watching">More Info</string>
|
<string name="action_open_watching">More Info</string>
|
||||||
|
<string name="action_open_play">@string/home_play </string>
|
||||||
|
|
||||||
<string name="vpn_might_be_needed">A VPN might be needed for this provider to work correctly</string>
|
<string name="vpn_might_be_needed">A VPN might be needed for this provider to work correctly</string>
|
||||||
<string name="vpn_torrent">This provider is a torrent, a VPN is recommended</string>
|
<string name="vpn_torrent">This provider is a torrent, a VPN is recommended</string>
|
||||||
|
|
Loading…
Reference in a new issue