This commit is contained in:
LagradOst 2021-07-15 18:45:25 +02:00
parent 57ce20e95f
commit bcc17171e5
18 changed files with 277 additions and 63 deletions

View file

@ -138,6 +138,11 @@ enum class TvType {
ONA,
}
// IN CASE OF FUTURE ANIME MOVIE OR SMTH
fun TvType.isMovieType() : Boolean {
return this == TvType.Movie
}
data class SubtitleFile(val lang: String, val url: String)
interface SearchResponse {

View file

@ -157,11 +157,12 @@ class MainActivity : AppCompatActivity() {
}
CastButtonFactory.setUpMediaRouteButton(this, media_route_button)
if (!VideoDownloadManager.isMyServiceRunning(this, VideoDownloadKeepAliveService::class.java)) {
val mYourService = VideoDownloadKeepAliveService()
val mServiceIntent = Intent(this, mYourService::class.java).putExtra(START_VALUE_KEY, RESTART_ALL_DOWNLOADS_AND_QUEUE)
this.startService(mServiceIntent)
}
// THIS IS CURRENTLY REMOVED BECAUSE HIGHER VERS OF ANDROID NEEDS A NOTIFICATION
//if (!VideoDownloadManager.isMyServiceRunning(this, VideoDownloadKeepAliveService::class.java)) {
// val mYourService = VideoDownloadKeepAliveService()
// val mServiceIntent = Intent(this, mYourService::class.java).putExtra(START_VALUE_KEY, RESTART_ALL_DOWNLOADS_AND_QUEUE)
// this.startService(mServiceIntent)
//}
/*
val castContext = CastContext.getSharedInstance(applicationContext)

View file

@ -83,16 +83,16 @@ object UIHelper {
return result
}
fun Activity.fixPaddingStatusbar(v: View) {
fun Context.fixPaddingStatusbar(v: View) {
v.setPadding(v.paddingLeft, v.paddingTop + getStatusBarHeight(), v.paddingRight, v.paddingBottom)
}
private fun Activity.getGridFormat(): String {
private fun Context.getGridFormat(): String {
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
return settingsManager.getString(getString(R.string.grid_format_key), "grid")!!
}
fun Activity.getGridFormatId(): Int {
fun Context.getGridFormatId(): Int {
return when (getGridFormat()) {
"list" -> R.layout.search_result_compact
"compact_list" -> R.layout.search_result_super_compact
@ -100,7 +100,7 @@ object UIHelper {
}
}
fun Activity.getGridIsCompact(): Boolean {
fun Context.getGridIsCompact(): Boolean {
return getGridFormat() != "grid"
}

View file

@ -1,4 +1,4 @@
package com.lagradost.cloudstream3.ui.notifications
package com.lagradost.cloudstream3.ui.download
import android.os.Bundle
import android.view.LayoutInflater
@ -10,9 +10,9 @@ import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.lagradost.cloudstream3.R
class NotificationsFragment : Fragment() {
class DownloadFragment : Fragment() {
private lateinit var notificationsViewModel: NotificationsViewModel
private lateinit var notificationsViewModel: DownloadViewModel
override fun onCreateView(
inflater: LayoutInflater,
@ -20,7 +20,7 @@ class NotificationsFragment : Fragment() {
savedInstanceState: Bundle?
): View? {
notificationsViewModel =
ViewModelProvider(this).get(NotificationsViewModel::class.java)
ViewModelProvider(this).get(DownloadViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_notifications, container, false)
val textView: TextView = root.findViewById(R.id.text_notifications)
notificationsViewModel.text.observe(viewLifecycleOwner, Observer {

View file

@ -0,0 +1,91 @@
package com.lagradost.cloudstream3.ui.download
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.isMovieType
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
import kotlinx.android.synthetic.main.download_header_episode.view.*
data class VisualDownloadHeaderCached(
val currentOngoingDownloads: Int,
val totalDownloads: Int,
val totalBytes: Long,
val data: VideoDownloadHelper.DownloadHeaderCached,
)
data class DownloadHeaderClickEvent(val action: Int, val data: VideoDownloadHelper.DownloadHeaderCached)
data class DownloadClickEvent(val action: Int, val data: VideoDownloadHelper.DownloadEpisodeCached)
class DownloadHeaderAdapter(
var cardList: List<VisualDownloadHeaderCached>,
private val clickCallback: (DownloadHeaderClickEvent) -> Unit,
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return DownloadHeaderViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.download_header_episode, parent, false),
clickCallback
)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is DownloadHeaderViewHolder -> {
holder.bind(cardList[position])
}
}
}
override fun getItemCount(): Int {
return cardList.size
}
class DownloadHeaderViewHolder
constructor(
itemView: View,
private val clickCallback: (DownloadHeaderClickEvent) -> Unit,
) : RecyclerView.ViewHolder(itemView) {
private val poster: ImageView = itemView.download_header_poster
private val title: TextView = itemView.download_header_title
private val extraInfo: TextView = itemView.download_header_info
private val holder: CardView = itemView.episode_holder
@SuppressLint("SetTextI18n")
fun bind(card: VisualDownloadHeaderCached) {
val d = card.data
if (d.poster != null) {
val glideUrl =
GlideUrl(d.poster)
poster.context.let {
Glide.with(it)
.load(glideUrl)
.into(poster)
}
}
title.text = d.name
val mbString = "%.1f".format(card.totalBytes / 1000000f)
extraInfo.text =
if (d.type.isMovieType())
"${mbString}MB" else
"${card.totalDownloads} Episode${if (card.totalDownloads == 1) "" else "s"} | ${mbString}MB"
holder.setOnClickListener {
clickCallback.invoke(DownloadHeaderClickEvent(0, d))
}
}
}
}

View file

@ -1,10 +1,10 @@
package com.lagradost.cloudstream3.ui.notifications
package com.lagradost.cloudstream3.ui.download
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class NotificationsViewModel : ViewModel() {
class DownloadViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = "This is notifications Fragment"

View file

@ -17,7 +17,6 @@ import com.google.android.gms.cast.framework.CastContext
import com.google.android.gms.cast.framework.CastState
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.UIHelper.isCastApiAvailable
import kotlinx.android.synthetic.main.result_episode.view.*
import kotlinx.android.synthetic.main.result_episode.view.episode_holder
import kotlinx.android.synthetic.main.result_episode.view.episode_text
import kotlinx.android.synthetic.main.result_episode_large.view.*
@ -30,9 +29,7 @@ const val ACTION_PLAY_EPISODE_IN_PLAYER = 1
data class EpisodeClickEvent(val action: Int, val data: ResultEpisode)
class EpisodeAdapter(
private var activity: Activity,
var cardList: List<ResultEpisode>,
private val resView: RecyclerView,
private val clickCallback: (EpisodeClickEvent) -> Unit,
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
@ -51,8 +48,6 @@ class EpisodeAdapter(
return CardViewHolder(
LayoutInflater.from(parent.context).inflate(layout, parent, false),
activity,
resView,
clickCallback
)
}
@ -72,17 +67,16 @@ class EpisodeAdapter(
class CardViewHolder
constructor(
itemView: View,
val activity: Activity,
resView: RecyclerView,
private val clickCallback: (EpisodeClickEvent) -> Unit,
) : RecyclerView.ViewHolder(itemView) {
private val episodeViewPrecentage: View? = itemView.episode_view_procentage
private val episodeViewPercentageOff: View? = itemView.episode_view_procentage_off
//private val episodeViewPrecentage: View? = itemView.episode_view_procentage
// private val episodeViewPercentageOff: View? = itemView.episode_view_procentage_off
private val episodeText: TextView = itemView.episode_text
private val episodeRating: TextView? = itemView.episode_rating
private val episodeDescript: TextView? = itemView.episode_descript
private val episodeProgress: ContentLoadingProgressBar? = itemView.episode_progress
private val episodePoster: ImageView? = itemView.episode_poster
private val episodeDownload: ImageView? = itemView.episode_download
// val episodeExtra: ImageView = itemView.episode_extra
// private val episodePlay: ImageView = itemView.episode_play
@ -103,10 +97,10 @@ class EpisodeAdapter(
}
val watchProgress = card.getWatchProgress()
if (episodeViewPrecentage != null && episodeViewPercentageOff != null) {
/*if (episodeViewPrecentage != null && episodeViewPercentageOff != null) {
setWidth(episodeViewPrecentage, watchProgress)
setWidth(episodeViewPercentageOff, 1 - watchProgress)
}
}*/
episodeProgress?.progress = (watchProgress * 50).toInt()
episodeProgress?.visibility = if (watchProgress > 0.0f) View.VISIBLE else View.GONE
@ -116,11 +110,9 @@ class EpisodeAdapter(
if (episodePoster != null) {
val glideUrl =
GlideUrl(card.poster)
activity.let {
Glide.with(it)
.load(glideUrl)
.into(episodePoster)
}
Glide.with(episodePoster.context)
.load(glideUrl)
.into(episodePoster)
}
} else {
episodePoster?.visibility = View.GONE
@ -140,19 +132,26 @@ class EpisodeAdapter(
}
episodeHolder.setOnClickListener {
if (activity.isCastApiAvailable()) {
val castContext = CastContext.getSharedInstance(activity)
episodeHolder.context?.let { ctx ->
if (ctx.isCastApiAvailable()) {
val castContext = CastContext.getSharedInstance(ctx)
if (castContext.castState == CastState.CONNECTED) {
clickCallback.invoke(EpisodeClickEvent(ACTION_CHROME_CAST_EPISODE, card))
if (castContext.castState == CastState.CONNECTED) {
clickCallback.invoke(EpisodeClickEvent(ACTION_CHROME_CAST_EPISODE, card))
} else {
// clickCallback.invoke(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, card))
clickCallback.invoke(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, card))
}
} else {
// clickCallback.invoke(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, card))
clickCallback.invoke(EpisodeClickEvent(ACTION_DOWNLOAD_EPISODE, card))
clickCallback.invoke(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, card)) //TODO REDO TO MAIN
}
} else {
// clickCallback.invoke(EpisodeClickEvent(ACTION_PLAY_EPISODE_IN_PLAYER, card))
clickCallback.invoke(EpisodeClickEvent(ACTION_DOWNLOAD_EPISODE, card)) //TODO REDO TO MAIN
}
}
episodeDownload?.setOnClickListener {
clickCallback.invoke(EpisodeClickEvent(ACTION_DOWNLOAD_EPISODE, card))
}
}
}

View file

@ -31,7 +31,7 @@ class SearchAdapter(
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layout = activity.getGridFormatId()
val layout = parent.context.getGridFormatId()
return CardViewHolder(
LayoutInflater.from(parent.context).inflate(layout, parent, false),
activity,
@ -66,7 +66,7 @@ class SearchAdapter(
//val cardTextExtra: TextView? = itemView.imageTextExtra
//val imageTextProvider: TextView? = itemView.imageTextProvider
val bg = itemView.backgroundCard
val compactView = activity.getGridIsCompact()
val compactView = itemView.context.getGridIsCompact()
private val coverHeight: Int = if (compactView) 80.toPx else (resView.itemWidth / 0.68).roundToInt()
fun bind(card: Any) {
@ -98,11 +98,11 @@ class SearchAdapter(
val glideUrl =
GlideUrl(card.posterUrl)
activity.let {
Glide.with(it)
Glide.with(cardView.context)
.load(glideUrl)
.into(cardView)
}
}
bg.setOnClickListener {

View file

@ -23,8 +23,6 @@ import com.lagradost.cloudstream3.UIHelper.getGridIsCompact
import com.lagradost.cloudstream3.UIHelper.loadResult
import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.observe
import com.lagradost.cloudstream3.ui.player.PlayerData
import com.lagradost.cloudstream3.ui.player.PlayerFragment
import kotlinx.android.synthetic.main.fragment_search.*
class SearchFragment : Fragment() {
@ -77,10 +75,10 @@ class SearchFragment : Fragment() {
cardSpace.adapter = adapter
search_loading_bar.alpha = 0f
val search_exit_icon = main_search.findViewById<ImageView>(androidx.appcompat.R.id.search_close_btn)
val search_mag_icon = main_search.findViewById<ImageView>(androidx.appcompat.R.id.search_mag_icon)
search_mag_icon.scaleX = 0.65f
search_mag_icon.scaleY = 0.65f
val searchExitIcon = main_search.findViewById<ImageView>(androidx.appcompat.R.id.search_close_btn)
val searchMagIcon = main_search.findViewById<ImageView>(androidx.appcompat.R.id.search_mag_icon)
searchMagIcon.scaleX = 0.65f
searchMagIcon.scaleY = 0.65f
search_filter.setOnClickListener {
val apiNamesSetting = activity?.getApiSettings()
if (apiNamesSetting != null) {
@ -131,16 +129,16 @@ class SearchFragment : Fragment() {
(cardSpace.adapter as SearchAdapter).cardList = data
(cardSpace.adapter as SearchAdapter).notifyDataSetChanged()
}
search_exit_icon.alpha = 1f
searchExitIcon.alpha = 1f
search_loading_bar.alpha = 0f
}
is Resource.Failure -> {
Toast.makeText(activity, "Server error", Toast.LENGTH_LONG).show()
search_exit_icon.alpha = 1f
searchExitIcon.alpha = 1f
search_loading_bar.alpha = 0f
}
is Resource.Loading -> {
search_exit_icon.alpha = 0f
searchExitIcon.alpha = 0f
search_loading_bar.alpha = 1f
}
}

View file

@ -0,0 +1,25 @@
package com.lagradost.cloudstream3.utils
import com.lagradost.cloudstream3.TvType
object VideoDownloadHelper {
data class DownloadEpisodeCached(
val name: String?,
val poster: String?,
val episode: Int,
val season: Int?,
val id: Int,
val parentId: Int,
val rating: Int?,
val descript: String?,
)
data class DownloadHeaderCached(
val apiName: String,
val source: String,
val type : TvType,
val name: String,
val poster: String?,
val id: Int,
)
}

View file

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" 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="M8.59,16.59L13.17,12 8.59,7.41 10,6l6,6 -6,6 -1.41,-1.41z"/>
</vector>

View file

@ -1,8 +1,8 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="vector"
android:width="850dp"
android:height="850dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="850"
android:viewportHeight="850">
<path

View file

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
app:cardCornerRadius="@dimen/roundedImageRadius"
app:cardBackgroundColor="@color/itemBackground"
android:id="@+id/episode_holder"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:layout_marginBottom="10dp"
>
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<!--app:cardCornerRadius="@dimen/roundedImageRadius"-->
<androidx.cardview.widget.CardView
android:layout_width="70dp"
android:layout_height="104dp"
>
<ImageView
android:id="@+id/download_header_poster"
tools:src="@drawable/example_poster"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/episode_poster">
</ImageView>
</androidx.cardview.widget.CardView>
<LinearLayout
android:layout_marginStart="15dp"
android:orientation="vertical"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_marginEnd="50dp"
android:layout_height="wrap_content">
<TextView
android:id="@+id/download_header_title"
tools:text="Perfect Run"
android:textStyle="bold"
android:textColor="@color/textColor"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<TextView
android:id="@+id/download_header_info"
tools:text="1 episode | 285MB"
android:textColor="@color/grayTextColor"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
<ImageView
android:layout_marginStart="-40dp"
android:layout_height="match_parent"
android:layout_width="30dp"
android:background="?selectableItemBackgroundBorderless"
android:layout_gravity="center_vertical|end"
android:src="@drawable/ic_baseline_keyboard_arrow_right_24"
android:contentDescription="@string/download_descript"/>
</LinearLayout>
</androidx.cardview.widget.CardView>

View file

@ -5,7 +5,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.notifications.NotificationsFragment">
tools:context=".ui.download.DownloadFragment">
<TextView
android:id="@+id/text_notifications"

View file

@ -13,7 +13,7 @@
android:layout_marginBottom="5dp"
>
<!-- IDK BUT THIS DOES NOT SEAM LIKE A GOOD WAY OF DOING IT -->
<LinearLayout
<!--<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
@ -33,7 +33,18 @@
android:layout_width="0dp"
android:layout_height="match_parent">
</View>
</LinearLayout>
</LinearLayout>-->
<androidx.core.widget.ContentLoadingProgressBar
android:layout_marginBottom="-1.5dp"
android:id="@+id/episode_progress"
android:progressTint="@color/colorPrimary"
android:progressBackgroundTint="@color/colorPrimary"
style="@android:style/Widget.Material.ProgressBar.Horizontal"
android:layout_width="match_parent"
tools:progress="50"
android:layout_gravity="bottom"
android:layout_height="5dp">
</androidx.core.widget.ContentLoadingProgressBar>
<GridLayout android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
android:layout_marginStart="10dp"
@ -51,13 +62,15 @@
android:layout_height="match_parent">
</TextView>
<ImageView
android:visibility="gone"
android:visibility="visible"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:id="@+id/episode_extra"
android:layout_height="match_parent"
android:layout_width="30dp"
android:id="@+id/episode_download"
android:background="?selectableItemBackgroundBorderless"
android:layout_gravity="center_vertical|end"
android:src="@drawable/ic_baseline_more_vert_24"
android:contentDescription="@string/episode_more_options_descript"/>
android:src="@drawable/netflix_download"
android:contentDescription="@string/download_descript"/>
</GridLayout>
</androidx.cardview.widget.CardView>

View file

@ -58,6 +58,7 @@
android:orientation="vertical"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_marginEnd="50dp"
android:layout_height="wrap_content">
<TextView
android:id="@+id/episode_text"
@ -75,6 +76,16 @@
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
<ImageView
android:visibility="visible"
android:layout_marginStart="-40dp"
android:layout_height="match_parent"
android:layout_width="30dp"
android:id="@+id/episode_download"
android:background="?selectableItemBackgroundBorderless"
android:layout_gravity="center_vertical|end"
android:src="@drawable/netflix_download"
android:contentDescription="@string/download_descript"/>
</LinearLayout>
<TextView
android:paddingTop="10dp"

View file

@ -19,7 +19,7 @@
<fragment
android:id="@+id/navigation_notifications"
android:name="com.lagradost.cloudstream3.ui.notifications.NotificationsFragment"
android:name="com.lagradost.cloudstream3.ui.download.DownloadFragment"
android:label="@string/title_downloads"
tools:layout="@layout/fragment_notifications"/>
<fragment

View file

@ -38,4 +38,5 @@
<string name="episode_poster">Episode Poster</string>
<string name="play_episode">Play Episode</string>
<string name="need_storage">Allow to download episodes</string>
<string name="download_descript">Download</string>
</resources>