mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
UI Loading and back
This commit is contained in:
parent
93fe31f014
commit
5938d4824d
14 changed files with 593 additions and 291 deletions
|
@ -156,7 +156,7 @@ class ShiroProvider : MainAPI() {
|
||||||
|
|
||||||
returnValue.add(AnimeSearchResponse(
|
returnValue.add(AnimeSearchResponse(
|
||||||
i.name.replace("Dubbed", ""), // i.english ?: i.canonicalTitle,
|
i.name.replace("Dubbed", ""), // i.english ?: i.canonicalTitle,
|
||||||
"$mainUrl/${i.slug}",
|
"$mainUrl/anime/${i.slug}",
|
||||||
i.slug,
|
i.slug,
|
||||||
this.name,
|
this.name,
|
||||||
type,
|
type,
|
||||||
|
|
|
@ -26,6 +26,7 @@ sealed class Resource<out T> {
|
||||||
val errorResponse: Any?, //ResponseBody
|
val errorResponse: Any?, //ResponseBody
|
||||||
val errorString: String,
|
val errorString: String,
|
||||||
) : Resource<Nothing>()
|
) : Resource<Nothing>()
|
||||||
|
data class Loading(val url : String? = null) : Resource<Nothing>()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun <T> safeApiCall(
|
suspend fun <T> safeApiCall(
|
||||||
|
|
|
@ -3,8 +3,9 @@ package com.lagradost.cloudstream3.ui
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.View.*
|
import android.view.View.*
|
||||||
import android.widget.ImageView
|
import android.widget.*
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.core.content.ContentProviderCompat.requireContext
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||||
|
@ -14,9 +15,13 @@ import com.google.android.gms.cast.framework.CastButtonFactory
|
||||||
import com.google.android.gms.cast.framework.CastSession
|
import com.google.android.gms.cast.framework.CastSession
|
||||||
import com.google.android.gms.cast.framework.media.RemoteMediaClient
|
import com.google.android.gms.cast.framework.media.RemoteMediaClient
|
||||||
import com.google.android.gms.cast.framework.media.uicontroller.UIController
|
import com.google.android.gms.cast.framework.media.uicontroller.UIController
|
||||||
|
import com.google.android.gms.cast.framework.media.widget.CastSeekBar
|
||||||
import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity
|
import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
import com.lagradost.cloudstream3.APIHolder.getApiFromName
|
import com.lagradost.cloudstream3.APIHolder.getApiFromName
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
|
import com.lagradost.cloudstream3.UIHelper
|
||||||
|
import com.lagradost.cloudstream3.UIHelper.colorFromAttribute
|
||||||
import com.lagradost.cloudstream3.mvvm.Resource
|
import com.lagradost.cloudstream3.mvvm.Resource
|
||||||
import com.lagradost.cloudstream3.mvvm.safeApiCall
|
import com.lagradost.cloudstream3.mvvm.safeApiCall
|
||||||
import com.lagradost.cloudstream3.sortUrls
|
import com.lagradost.cloudstream3.sortUrls
|
||||||
|
@ -86,23 +91,35 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi
|
||||||
init {
|
init {
|
||||||
view.setImageResource(R.drawable.ic_baseline_playlist_play_24)
|
view.setImageResource(R.drawable.ic_baseline_playlist_play_24)
|
||||||
view.setOnClickListener {
|
view.setOnClickListener {
|
||||||
lateinit var dialog: AlertDialog
|
// lateinit var dialog: AlertDialog
|
||||||
val holder = getCurrentMetaData()
|
val holder = getCurrentMetaData()
|
||||||
|
|
||||||
if (holder != null) {
|
if (holder != null) {
|
||||||
val items = holder.currentLinks
|
val items = holder.currentLinks
|
||||||
if (items.isNotEmpty() && remoteMediaClient?.currentItem != null) {
|
if (items.isNotEmpty() && remoteMediaClient?.currentItem != null) {
|
||||||
val builder = AlertDialog.Builder(view.context, R.style.AlertDialogCustom)
|
// val builder = AlertDialog.Builder(view.context, R.style.AlertDialogCustom)
|
||||||
builder.setTitle("Pick source")
|
/*val builder = BottomSheetDialog(view.context, R.style.AlertDialogCustom)
|
||||||
|
builder.setTitle("Pick source")*/
|
||||||
|
val bottomSheetDialog = BottomSheetDialog(view.context)
|
||||||
|
bottomSheetDialog.setContentView(R.layout.sort_bottom_sheet)
|
||||||
|
val res = bottomSheetDialog.findViewById<ListView>(R.id.sort_click)!!
|
||||||
|
|
||||||
//https://developers.google.com/cast/docs/reference/web_receiver/cast.framework.messages.MediaInformation
|
//https://developers.google.com/cast/docs/reference/web_receiver/cast.framework.messages.MediaInformation
|
||||||
val contentUrl = (remoteMediaClient?.currentItem?.media?.contentUrl
|
val contentUrl = (remoteMediaClient?.currentItem?.media?.contentUrl
|
||||||
?: remoteMediaClient?.currentItem?.media?.contentId)
|
?: remoteMediaClient?.currentItem?.media?.contentId)
|
||||||
|
|
||||||
builder.setSingleChoiceItems(
|
val sortingMethods = items.map { it.name }.toTypedArray()
|
||||||
items.map { it.name }.toTypedArray(),
|
val sotringIndex = items.indexOfFirst { it.url == contentUrl }
|
||||||
items.indexOfFirst { it.url == contentUrl }
|
|
||||||
) { _, which ->
|
val arrayAdapter = ArrayAdapter<String>(view.context, R.layout.sort_bottom_single_choice)
|
||||||
|
arrayAdapter.addAll(sortingMethods.toMutableList())
|
||||||
|
|
||||||
|
res.choiceMode = AbsListView.CHOICE_MODE_SINGLE
|
||||||
|
res.adapter = arrayAdapter
|
||||||
|
res.setItemChecked(sotringIndex, true)
|
||||||
|
|
||||||
|
|
||||||
|
res.setOnItemClickListener { _, _, which, _ ->
|
||||||
val epData = holder.episodes[holder.currentEpisodeIndex]
|
val epData = holder.episodes[holder.currentEpisodeIndex]
|
||||||
|
|
||||||
fun loadMirror(index: Int) {
|
fun loadMirror(index: Int) {
|
||||||
|
@ -144,10 +161,12 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi
|
||||||
}
|
}
|
||||||
loadMirror(which)
|
loadMirror(which)
|
||||||
|
|
||||||
dialog.dismiss()
|
bottomSheetDialog.dismiss()
|
||||||
}
|
}
|
||||||
|
bottomSheetDialog.show()
|
||||||
|
/*
|
||||||
dialog = builder.create()
|
dialog = builder.create()
|
||||||
dialog.show()
|
dialog.show()*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,5 +295,9 @@ class ControllerActivity : ExpandedControllerActivity() {
|
||||||
uiMediaController.bindViewToUIController(skipBackButton, SkipTimeController(skipBackButton, false))
|
uiMediaController.bindViewToUIController(skipBackButton, SkipTimeController(skipBackButton, false))
|
||||||
uiMediaController.bindViewToUIController(skipForwardButton, SkipTimeController(skipForwardButton, true))
|
uiMediaController.bindViewToUIController(skipForwardButton, SkipTimeController(skipForwardButton, true))
|
||||||
uiMediaController.bindViewToUIController(skipOpButton, SkipNextEpisodeController(skipOpButton))
|
uiMediaController.bindViewToUIController(skipOpButton, SkipNextEpisodeController(skipOpButton))
|
||||||
|
/* val progressBar: CastSeekBar? = findViewById(R.id.cast_seek_bar)
|
||||||
|
|
||||||
|
progressBar?.backgroundTintList = (UIHelper.adjustAlpha(colorFromAttribute(R.attr.colorPrimary), 0.35f))
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,11 +10,14 @@ import android.view.View
|
||||||
import android.view.View.GONE
|
import android.view.View.GONE
|
||||||
import android.view.View.VISIBLE
|
import android.view.View.VISIBLE
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.FrameLayout
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.core.widget.NestedScrollView
|
import androidx.core.widget.NestedScrollView
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
@ -28,7 +31,9 @@ import com.google.android.material.button.MaterialButton
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.UIHelper.colorFromAttribute
|
import com.lagradost.cloudstream3.UIHelper.colorFromAttribute
|
||||||
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
|
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
|
||||||
|
import com.lagradost.cloudstream3.UIHelper.getStatusBarHeight
|
||||||
import com.lagradost.cloudstream3.UIHelper.isCastApiAvailable
|
import com.lagradost.cloudstream3.UIHelper.isCastApiAvailable
|
||||||
|
import com.lagradost.cloudstream3.UIHelper.popCurrentPage
|
||||||
import com.lagradost.cloudstream3.UIHelper.popupMenu
|
import com.lagradost.cloudstream3.UIHelper.popupMenu
|
||||||
import com.lagradost.cloudstream3.UIHelper.popupMenuNoIcons
|
import com.lagradost.cloudstream3.UIHelper.popupMenuNoIcons
|
||||||
import com.lagradost.cloudstream3.mvvm.Resource
|
import com.lagradost.cloudstream3.mvvm.Resource
|
||||||
|
@ -137,14 +142,47 @@ class ResultFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 0 = LOADING, 1 = ERROR LOADING, 2 = LOADED
|
||||||
|
fun updateVisStatus(state: Int) {
|
||||||
|
when (state) {
|
||||||
|
0 -> {
|
||||||
|
result_loading.visibility = VISIBLE
|
||||||
|
result_finish_loading.visibility = GONE
|
||||||
|
result_reload_connectionerror.visibility = GONE
|
||||||
|
result_reload_connection_open_in_browser.visibility = GONE
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
result_loading.visibility = GONE
|
||||||
|
result_finish_loading.visibility = GONE
|
||||||
|
result_reload_connectionerror.visibility = VISIBLE
|
||||||
|
result_reload_connection_open_in_browser.visibility = if (url == null) GONE else VISIBLE
|
||||||
|
}
|
||||||
|
2 -> {
|
||||||
|
result_loading.visibility = GONE
|
||||||
|
result_finish_loading.visibility = VISIBLE
|
||||||
|
result_reload_connectionerror.visibility = GONE
|
||||||
|
result_reload_connection_open_in_browser.visibility = GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private var currentPoster: String? = null
|
private var currentPoster: String? = null
|
||||||
|
|
||||||
|
var url: String? = null
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
activity?.fixPaddingStatusbar(result_scroll)
|
activity?.fixPaddingStatusbar(result_scroll)
|
||||||
activity?.fixPaddingStatusbar(result_barstatus)
|
activity?.fixPaddingStatusbar(result_barstatus)
|
||||||
|
|
||||||
|
val backParameter = result_back.layoutParams as CoordinatorLayout.LayoutParams
|
||||||
|
backParameter.setMargins(backParameter.leftMargin,
|
||||||
|
backParameter.topMargin + requireContext().getStatusBarHeight(),
|
||||||
|
backParameter.rightMargin,
|
||||||
|
backParameter.bottomMargin)
|
||||||
|
result_back.layoutParams = backParameter
|
||||||
|
|
||||||
if (activity?.isCastApiAvailable() == true) {
|
if (activity?.isCastApiAvailable() == true) {
|
||||||
CastButtonFactory.setUpMediaRouteButton(activity, media_route_button)
|
CastButtonFactory.setUpMediaRouteButton(activity, media_route_button)
|
||||||
val castContext = CastContext.getSharedInstance(requireActivity().applicationContext)
|
val castContext = CastContext.getSharedInstance(requireActivity().applicationContext)
|
||||||
|
@ -160,16 +198,20 @@ class ResultFragment : Fragment() {
|
||||||
}
|
}
|
||||||
// activity?.fixPaddingStatusbar(result_toolbar)
|
// activity?.fixPaddingStatusbar(result_toolbar)
|
||||||
|
|
||||||
val url = arguments?.getString("url")
|
url = arguments?.getString("url")
|
||||||
val slug = arguments?.getString("slug")
|
val slug = arguments?.getString("slug")
|
||||||
val apiName = arguments?.getString("apiName")
|
val apiName = arguments?.getString("apiName")
|
||||||
|
|
||||||
result_scroll.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, _, scrollY, _, _ ->
|
result_scroll.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, _, scrollY, _, _ ->
|
||||||
if (result_poster_blur == null) return@OnScrollChangeListener
|
if (result_poster_blur == null) return@OnScrollChangeListener
|
||||||
result_poster_blur.alpha = maxOf(0f, (0.7f - scrollY / 1000f))
|
result_poster_blur.alpha = maxOf(0f, (0.7f - scrollY / 1000f))
|
||||||
|
val setAlpha = 1f - scrollY / 200f
|
||||||
|
result_back.alpha = setAlpha
|
||||||
result_poster_blur_holder.translationY = -scrollY.toFloat()
|
result_poster_blur_holder.translationY = -scrollY.toFloat()
|
||||||
|
// result_back.translationY = -scrollY.toFloat()
|
||||||
//result_barstatus.alpha = scrollY / 200f
|
//result_barstatus.alpha = scrollY / 200f
|
||||||
//result_barstatus.visibility = if (scrollY > 0) View.VISIBLE else View.GONE§
|
//result_barstatus.visibility = if (scrollY > 0) View.VISIBLE else View.GONE§
|
||||||
|
result_back.visibility = if (setAlpha > 0) VISIBLE else GONE
|
||||||
})
|
})
|
||||||
|
|
||||||
result_toolbar.setNavigationIcon(R.drawable.ic_baseline_arrow_back_24)
|
result_toolbar.setNavigationIcon(R.drawable.ic_baseline_arrow_back_24)
|
||||||
|
@ -177,12 +219,11 @@ class ResultFragment : Fragment() {
|
||||||
activity?.onBackPressed()
|
activity?.onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
val adapter: RecyclerView.Adapter<RecyclerView.ViewHolder>? = activity?.let { it ->
|
result_back.setOnClickListener {
|
||||||
EpisodeAdapter(
|
requireActivity().popCurrentPage()
|
||||||
it,
|
}
|
||||||
ArrayList(),
|
|
||||||
result_episodes,
|
fun handleAction(episodeClick: EpisodeClickEvent) {
|
||||||
) { episodeClick ->
|
|
||||||
//val id = episodeClick.data.id
|
//val id = episodeClick.data.id
|
||||||
val index = episodeClick.data.index
|
val index = episodeClick.data.index
|
||||||
val buildInPlayer = true
|
val buildInPlayer = true
|
||||||
|
@ -249,6 +290,15 @@ class ResultFragment : Fragment() {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val adapter: RecyclerView.Adapter<RecyclerView.ViewHolder>? = activity?.let { it ->
|
||||||
|
EpisodeAdapter(
|
||||||
|
it,
|
||||||
|
ArrayList(),
|
||||||
|
result_episodes,
|
||||||
|
) { episodeClick ->
|
||||||
|
handleAction(episodeClick)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result_episodes.adapter = adapter
|
result_episodes.adapter = adapter
|
||||||
|
@ -288,6 +338,8 @@ class ResultFragment : Fragment() {
|
||||||
is Resource.Success -> {
|
is Resource.Success -> {
|
||||||
val d = data.value
|
val d = data.value
|
||||||
if (d is LoadResponse) {
|
if (d is LoadResponse) {
|
||||||
|
updateVisStatus(2)
|
||||||
|
|
||||||
result_bookmark_button.text = "Watching"
|
result_bookmark_button.text = "Watching"
|
||||||
|
|
||||||
currentHeaderName = d.name
|
currentHeaderName = d.name
|
||||||
|
@ -407,6 +459,34 @@ activity?.startActivityForResult(vlcIntent, REQUEST_CODE)
|
||||||
result_tag_holder.visibility = GONE
|
result_tag_holder.visibility = GONE
|
||||||
result_status.visibility = GONE
|
result_status.visibility = GONE
|
||||||
|
|
||||||
|
when (d.type) {
|
||||||
|
TvType.Movie -> {
|
||||||
|
result_play_movie.visibility = VISIBLE
|
||||||
|
result_episodes_text.visibility = GONE
|
||||||
|
result_episodes.visibility = GONE
|
||||||
|
|
||||||
|
result_play_movie.setOnClickListener {
|
||||||
|
val card = currentEpisodes?.first() ?: return@setOnClickListener
|
||||||
|
if (requireContext().isCastApiAvailable()) {
|
||||||
|
val castContext = CastContext.getSharedInstance(requireContext())
|
||||||
|
|
||||||
|
if (castContext.castState == CastState.CONNECTED) {
|
||||||
|
handleAction(EpisodeClickEvent(ACTION_CHROME_CAST_EPISODE, card))
|
||||||
|
} else {
|
||||||
|
handleAction(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, card))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
handleAction(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, card))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
result_play_movie.visibility = GONE
|
||||||
|
result_episodes_text.visibility = VISIBLE
|
||||||
|
result_episodes.visibility = VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
when (d) {
|
when (d) {
|
||||||
is AnimeLoadResponse -> {
|
is AnimeLoadResponse -> {
|
||||||
result_status.visibility = VISIBLE
|
result_status.visibility = VISIBLE
|
||||||
|
@ -438,15 +518,34 @@ activity?.startActivityForResult(vlcIntent, REQUEST_CODE)
|
||||||
}
|
}
|
||||||
else -> result_title.text = d.name
|
else -> result_title.text = d.name
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
updateVisStatus(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Resource.Failure -> {
|
is Resource.Failure -> {
|
||||||
|
updateVisStatus(1)
|
||||||
|
}
|
||||||
|
is Resource.Loading -> {
|
||||||
|
updateVisStatus(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewModel.resultResponse.value == null && apiName != null && slug != null)
|
if (apiName != null && slug != null) {
|
||||||
|
result_reload_connectionerror.setOnClickListener {
|
||||||
|
viewModel.load(requireContext(), slug, apiName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url != null) {
|
||||||
|
result_reload_connection_open_in_browser.setOnClickListener {
|
||||||
|
val i = Intent(Intent.ACTION_VIEW)
|
||||||
|
i.data = Uri.parse(url)
|
||||||
|
startActivity(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viewModel.resultResponse.value == null)
|
||||||
viewModel.load(requireContext(), slug, apiName)
|
viewModel.load(requireContext(), slug, apiName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -56,11 +56,14 @@ class ResultViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun load(context: Context, url: String, apiName: String) = viewModelScope.launch {
|
fun load(context: Context, url: String, apiName: String) = viewModelScope.launch {
|
||||||
|
_resultResponse.postValue(Resource.Loading(url))
|
||||||
|
|
||||||
_apiName.postValue(apiName)
|
_apiName.postValue(apiName)
|
||||||
val api = getApiFromName(apiName)
|
val api = getApiFromName(apiName)
|
||||||
val data = safeApiCall {
|
val data = safeApiCall {
|
||||||
api.load(url)
|
api.load(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
_resultResponse.postValue(data)
|
_resultResponse.postValue(data)
|
||||||
|
|
||||||
when (data) {
|
when (data) {
|
||||||
|
|
|
@ -114,8 +114,6 @@ class SearchFragment : Fragment() {
|
||||||
|
|
||||||
main_search.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
main_search.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||||
override fun onQueryTextSubmit(query: String): Boolean {
|
override fun onQueryTextSubmit(query: String): Boolean {
|
||||||
search_exit_icon.alpha = 0f
|
|
||||||
search_loading_bar.alpha = 1f
|
|
||||||
searchViewModel.search(query)
|
searchViewModel.search(query)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -128,17 +126,26 @@ class SearchFragment : Fragment() {
|
||||||
observe(searchViewModel.searchResponse) {
|
observe(searchViewModel.searchResponse) {
|
||||||
when (it) {
|
when (it) {
|
||||||
is Resource.Success -> {
|
is Resource.Success -> {
|
||||||
(cardSpace.adapter as SearchAdapter).cardList = it.value
|
it?.value?.let { data ->
|
||||||
|
(cardSpace.adapter as SearchAdapter).cardList = data
|
||||||
(cardSpace.adapter as SearchAdapter).notifyDataSetChanged()
|
(cardSpace.adapter as SearchAdapter).notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
is Resource.Failure -> {
|
|
||||||
Toast.makeText(activity, "Server error", Toast.LENGTH_LONG).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
search_exit_icon.alpha = 1f
|
search_exit_icon.alpha = 1f
|
||||||
search_loading_bar.alpha = 0f
|
search_loading_bar.alpha = 0f
|
||||||
}
|
}
|
||||||
(activity as AppCompatActivity).loadResult("https://shiro.is/overlord-dubbed", "overlord-dubbed", "Shiro")
|
is Resource.Failure -> {
|
||||||
|
Toast.makeText(activity, "Server error", Toast.LENGTH_LONG).show()
|
||||||
|
search_exit_icon.alpha = 1f
|
||||||
|
search_loading_bar.alpha = 0f
|
||||||
|
}
|
||||||
|
is Resource.Loading -> {
|
||||||
|
search_exit_icon.alpha = 0f
|
||||||
|
search_loading_bar.alpha = 1f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
searchViewModel.search("overlord")
|
||||||
|
// (activity as AppCompatActivity).loadResult("https://shiro.is/overlord-dubbed", "overlord-dubbed", "Shiro")
|
||||||
/*
|
/*
|
||||||
(requireActivity() as AppCompatActivity).supportFragmentManager.beginTransaction()
|
(requireActivity() as AppCompatActivity).supportFragmentManager.beginTransaction()
|
||||||
.setCustomAnimations(R.anim.enter_anim,
|
.setCustomAnimations(R.anim.enter_anim,
|
||||||
|
|
|
@ -17,6 +17,7 @@ class SearchViewModel : ViewModel() {
|
||||||
val searchResponse: LiveData<Resource<ArrayList<Any>>> get() = _searchResponse
|
val searchResponse: LiveData<Resource<ArrayList<Any>>> get() = _searchResponse
|
||||||
|
|
||||||
fun search(query: String) = viewModelScope.launch {
|
fun search(query: String) = viewModelScope.launch {
|
||||||
|
_searchResponse.postValue(Resource.Loading())
|
||||||
val data = safeApiCall {
|
val data = safeApiCall {
|
||||||
api.search(query)
|
api.search(query)
|
||||||
}
|
}
|
||||||
|
|
5
app/src/main/res/drawable/ic_baseline_autorenew_24.xml
Normal file
5
app/src/main/res/drawable/ic_baseline_autorenew_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="M12,6v3l4,-4 -4,-4v3c-4.42,0 -8,3.58 -8,8 0,1.57 0.46,3.03 1.24,4.26L6.7,14.8c-0.45,-0.83 -0.7,-1.79 -0.7,-2.8 0,-3.31 2.69,-6 6,-6zM18.76,7.74L17.3,9.2c0.44,0.84 0.7,1.79 0.7,2.8 0,3.31 -2.69,6 -6,6v-3l-4,4 4,4v-3c4.42,0 8,-3.58 8,-8 0,-1.57 -0.46,-3.03 -1.24,-4.26z"/>
|
||||||
|
</vector>
|
5
app/src/main/res/drawable/ic_baseline_clear_24.xml
Normal file
5
app/src/main/res/drawable/ic_baseline_clear_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="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
|
||||||
|
</vector>
|
|
@ -9,6 +9,62 @@
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:visibility="visible"
|
||||||
|
tools:visibility="gone"
|
||||||
|
android:id="@+id/result_loading"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_width="50dp" android:layout_height="50dp">
|
||||||
|
</ProgressBar>
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:layout_columnWeight="1"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_marginBottom="50dp"
|
||||||
|
|
||||||
|
app:icon="@drawable/ic_baseline_autorenew_24"
|
||||||
|
app:iconSize="20dp"
|
||||||
|
android:text="@string/reload_error"
|
||||||
|
android:id="@+id/result_reload_connectionerror"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textSize="15sp"
|
||||||
|
app:cornerRadius="5dp"
|
||||||
|
app:strokeWidth="2dp"
|
||||||
|
app:strokeColor="@color/colorAccent"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||||
|
app:rippleColor="@color/colorPrimary"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:minWidth="200dp"
|
||||||
|
>
|
||||||
|
</com.google.android.material.button.MaterialButton>
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:layout_columnWeight="1"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_marginTop="50dp"
|
||||||
|
|
||||||
|
app:icon="@drawable/ic_baseline_public_24"
|
||||||
|
app:iconSize="20dp"
|
||||||
|
android:text="@string/result_open_in_browser"
|
||||||
|
android:id="@+id/result_reload_connection_open_in_browser"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textSize="15sp"
|
||||||
|
app:cornerRadius="5dp"
|
||||||
|
app:strokeWidth="2dp"
|
||||||
|
app:strokeColor="@color/colorAccent"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||||
|
app:rippleColor="@color/colorPrimary"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:minWidth="200dp"
|
||||||
|
>
|
||||||
|
</com.google.android.material.button.MaterialButton>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"
|
||||||
|
android:id="@+id/result_finish_loading" android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:id="@+id/result_barstatus"
|
android:id="@+id/result_barstatus"
|
||||||
|
@ -78,12 +134,14 @@
|
||||||
</androidx.cardview.widget.CardView>
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout android:layout_marginLeft="10dp"
|
<LinearLayout
|
||||||
|
android:layout_marginLeft="10dp"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
<TextView
|
<TextView
|
||||||
|
android:layout_marginRight="50dp"
|
||||||
tools:text="The Perfect Run The Perfect Run The Perfect Run"
|
tools:text="The Perfect Run The Perfect Run The Perfect Run"
|
||||||
android:id="@+id/result_title"
|
android:id="@+id/result_title"
|
||||||
android:textSize="20sp"
|
android:textSize="20sp"
|
||||||
|
@ -171,7 +229,8 @@
|
||||||
android:elevation="10dp"
|
android:elevation="10dp"
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
android:src="@drawable/ic_baseline_public_24"
|
android:src="@drawable/ic_baseline_public_24"
|
||||||
android:layout_gravity="center" android:contentDescription="@string/result_open_in_browser">
|
android:layout_gravity="center"
|
||||||
|
android:contentDescription="@string/result_open_in_browser">
|
||||||
</ImageView>
|
</ImageView>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
|
@ -208,6 +267,28 @@
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
</com.lagradost.cloudstream3.widget.FlowLayout>
|
</com.lagradost.cloudstream3.widget.FlowLayout>
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:visibility="visible"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
app:cornerRadius="4dp"
|
||||||
|
android:id="@+id/result_play_movie"
|
||||||
|
android:text="@string/play_movie_button"
|
||||||
|
|
||||||
|
app:rippleColor="?attr/colorPrimary"
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
app:iconTint="?attr/textColor"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
app:iconGravity="textStart"
|
||||||
|
app:strokeColor="?attr/textColor"
|
||||||
|
app:icon="@drawable/ic_baseline_play_arrow_24"
|
||||||
|
android:backgroundTint="@color/transparent"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="45dp">
|
||||||
|
</com.google.android.material.button.MaterialButton>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -244,6 +325,7 @@
|
||||||
tools:ignore="FragmentTagUsage">
|
tools:ignore="FragmentTagUsage">
|
||||||
</fragment>
|
</fragment>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
@ -264,5 +346,16 @@
|
||||||
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||||
android:contentDescription="@string/search_poster_descript"/>
|
android:contentDescription="@string/search_poster_descript"/>
|
||||||
</androidx.cardview.widget.CardView>-->
|
</androidx.cardview.widget.CardView>-->
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/result_back"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:tint="?attr/white"
|
||||||
|
android:src="@drawable/ic_baseline_clear_24"
|
||||||
|
android:contentDescription="@string/result_go_back">
|
||||||
|
</ImageView>
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
48
app/src/main/res/layout/sort_bottom_sheet.xml
Normal file
48
app/src/main/res/layout/sort_bottom_sheet.xml
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
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:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:background="@null"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<!--<androidx.cardview.widget.CardView
|
||||||
|
app:cardCornerRadius="10dp"
|
||||||
|
android:backgroundTint="?attr/boxItemBackground"
|
||||||
|
android:layout_width="match_parent" android:layout_height="wrap_content">
|
||||||
|
<TextView
|
||||||
|
style="@style/AppTextViewStyle"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
|
||||||
|
android:paddingTop="5dp"
|
||||||
|
android:paddingBottom="5dp"
|
||||||
|
android:paddingLeft="20dp"
|
||||||
|
android:paddingRight="20dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:text="@string/pick_source" android:textColor="?attr/textColor" android:textSize="18sp"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="55dp"
|
||||||
|
>
|
||||||
|
</TextView>
|
||||||
|
</androidx.cardview.widget.CardView>-->
|
||||||
|
<TextView
|
||||||
|
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||||
|
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:text="@string/pick_source"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
</TextView>
|
||||||
|
<ListView
|
||||||
|
android:layout_marginTop="-10dp"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:id="@+id/sort_click"
|
||||||
|
android:background="?attr/bitDarkerGrayBackground"
|
||||||
|
tools:listitem="@layout/sort_bottom_single_choice"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
</ListView>
|
||||||
|
</LinearLayout>
|
13
app/src/main/res/layout/sort_bottom_single_choice.xml
Normal file
13
app/src/main/res/layout/sort_bottom_single_choice.xml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<CheckedTextView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@android:id/text1"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?android:attr/listPreferredItemHeightSmall"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceListItemSmall"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
tools:text="Example Text"
|
||||||
|
android:background="?attr/bitDarkerGrayBackground"
|
||||||
|
android:checkMark="?android:attr/listChoiceIndicatorSingle"
|
||||||
|
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||||
|
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"/>
|
|
@ -30,4 +30,8 @@
|
||||||
<string name="type_dropped">Dropped</string>
|
<string name="type_dropped">Dropped</string>
|
||||||
<string name="type_plan_to_watch">Plan to Watch</string>
|
<string name="type_plan_to_watch">Plan to Watch</string>
|
||||||
<string name="type_none">None</string>
|
<string name="type_none">None</string>
|
||||||
|
<string name="play_movie_button">Play Movie</string>
|
||||||
|
<string name="pick_source">Pick Source</string>
|
||||||
|
<string name="reload_error">Retry connection…</string>
|
||||||
|
<string name="result_go_back">Go Back</string>
|
||||||
</resources>
|
</resources>
|
|
@ -129,8 +129,8 @@
|
||||||
@array/cast_expanded_controller_control_buttons
|
@array/cast_expanded_controller_control_buttons
|
||||||
</item>
|
</item>
|
||||||
<item name="castButtonColor">@null</item>
|
<item name="castButtonColor">@null</item>
|
||||||
<item name="castSeekBarProgressAndThumbColor">@color/white</item>
|
<item name="castSeekBarProgressAndThumbColor">@color/white</item> <!--@color/white ?attr/colorPrimary-->
|
||||||
<item name="castSeekBarSecondaryProgressColor">?attr/darkBackground</item> <!--CHECK-->
|
<item name="castSeekBarSecondaryProgressColor">?attr/darkBackground</item> <!--CHECK ?attr/darkBackground ?attr/colorPrimary-->
|
||||||
<item name="castBackground">?attr/colorPrimary</item>
|
<item name="castBackground">?attr/colorPrimary</item>
|
||||||
<item name="castProgressBarColor">?attr/colorPrimary</item>
|
<item name="castProgressBarColor">?attr/colorPrimary</item>
|
||||||
<item name="castPlayButtonDrawable">@drawable/ic_baseline_play_arrow_24</item>
|
<item name="castPlayButtonDrawable">@drawable/ic_baseline_play_arrow_24</item>
|
||||||
|
|
Loading…
Reference in a new issue