mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
Merge branch 'recloudstream:master' into master
This commit is contained in:
commit
33e985bfea
6 changed files with 46 additions and 14 deletions
|
@ -14,13 +14,7 @@ import android.os.Bundle
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
import android.view.KeyEvent
|
import android.view.*
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.MotionEvent
|
|
||||||
import android.view.Surface
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.view.WindowManager
|
|
||||||
import android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
import android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
||||||
import android.view.animation.AlphaAnimation
|
import android.view.animation.AlphaAnimation
|
||||||
import android.view.animation.Animation
|
import android.view.animation.Animation
|
||||||
|
@ -50,7 +44,6 @@ import com.lagradost.cloudstream3.ui.settings.Globals
|
||||||
import com.lagradost.cloudstream3.ui.settings.Globals.EMULATOR
|
import com.lagradost.cloudstream3.ui.settings.Globals.EMULATOR
|
||||||
import com.lagradost.cloudstream3.ui.settings.Globals.TV
|
import com.lagradost.cloudstream3.ui.settings.Globals.TV
|
||||||
import com.lagradost.cloudstream3.ui.settings.Globals.isLayout
|
import com.lagradost.cloudstream3.ui.settings.Globals.isLayout
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment
|
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.isUsingMobileData
|
import com.lagradost.cloudstream3.utils.AppUtils.isUsingMobileData
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper
|
import com.lagradost.cloudstream3.utils.DataStoreHelper
|
||||||
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog
|
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog
|
||||||
|
@ -498,6 +491,11 @@ open class FullScreenPlayer : AbstractPlayerFragment() {
|
||||||
dialog.dismissSafe(activity)
|
dialog.dismissSafe(activity)
|
||||||
player.seekTime(1L)
|
player.seekTime(1L)
|
||||||
}
|
}
|
||||||
|
resetBtt.setOnClickListener {
|
||||||
|
subtitleDelay = 0
|
||||||
|
dialog.dismissSafe(activity)
|
||||||
|
player.seekTime(1L)
|
||||||
|
}
|
||||||
cancelBtt.setOnClickListener {
|
cancelBtt.setOnClickListener {
|
||||||
subtitleDelay = beforeOffset
|
subtitleDelay = beforeOffset
|
||||||
dialog.dismissSafe(activity)
|
dialog.dismissSafe(activity)
|
||||||
|
|
|
@ -33,6 +33,7 @@ import com.lagradost.cloudstream3.ui.WatchType
|
||||||
import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup
|
import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup
|
||||||
import com.lagradost.cloudstream3.ui.player.ExtractorLinkGenerator
|
import com.lagradost.cloudstream3.ui.player.ExtractorLinkGenerator
|
||||||
import com.lagradost.cloudstream3.ui.player.GeneratorPlayer
|
import com.lagradost.cloudstream3.ui.player.GeneratorPlayer
|
||||||
|
import com.lagradost.cloudstream3.ui.player.NEXT_WATCH_EPISODE_PERCENTAGE
|
||||||
import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment
|
import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment
|
||||||
import com.lagradost.cloudstream3.ui.result.ResultFragment.getStoredData
|
import com.lagradost.cloudstream3.ui.result.ResultFragment.getStoredData
|
||||||
import com.lagradost.cloudstream3.ui.result.ResultFragment.updateUIEvent
|
import com.lagradost.cloudstream3.ui.result.ResultFragment.updateUIEvent
|
||||||
|
@ -782,7 +783,7 @@ class ResultFragmentTv : Fragment() {
|
||||||
// resultEpisodeLoading.isVisible = episodes is Resource.Loading
|
// resultEpisodeLoading.isVisible = episodes is Resource.Loading
|
||||||
if (episodes is Resource.Success) {
|
if (episodes is Resource.Success) {
|
||||||
|
|
||||||
val lastWatchedIndex = episodes.value.indexOfLast { ep -> ep.videoWatchState == VideoWatchState.Watched }
|
val lastWatchedIndex = episodes.value.indexOfLast { ep -> ep.getWatchProgress() >= NEXT_WATCH_EPISODE_PERCENTAGE.toFloat() / 100.0f }
|
||||||
val firstUnwatched = episodes.value.getOrElse(lastWatchedIndex + 1) { episodes.value.firstOrNull() }
|
val firstUnwatched = episodes.value.getOrElse(lastWatchedIndex + 1) { episodes.value.firstOrNull() }
|
||||||
|
|
||||||
if (firstUnwatched != null) {
|
if (firstUnwatched != null) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.content.*
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.text.format.Formatter.formatFileSize
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.annotation.MainThread
|
import androidx.annotation.MainThread
|
||||||
|
@ -20,7 +21,6 @@ import com.lagradost.cloudstream3.APIHolder.apis
|
||||||
import com.lagradost.cloudstream3.APIHolder.getId
|
import com.lagradost.cloudstream3.APIHolder.getId
|
||||||
import com.lagradost.cloudstream3.APIHolder.unixTime
|
import com.lagradost.cloudstream3.APIHolder.unixTime
|
||||||
import com.lagradost.cloudstream3.APIHolder.unixTimeMS
|
import com.lagradost.cloudstream3.APIHolder.unixTimeMS
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.context
|
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
||||||
import com.lagradost.cloudstream3.CommonActivity.activity
|
import com.lagradost.cloudstream3.CommonActivity.activity
|
||||||
import com.lagradost.cloudstream3.CommonActivity.getCastSession
|
import com.lagradost.cloudstream3.CommonActivity.getCastSession
|
||||||
|
@ -1280,9 +1280,14 @@ class ResultViewModel2 : ViewModel() {
|
||||||
callback: (Pair<LinkLoadingResult, Int>) -> Unit,
|
callback: (Pair<LinkLoadingResult, Int>) -> Unit,
|
||||||
) {
|
) {
|
||||||
loadLinks(result, isVisible = true, type) { links ->
|
loadLinks(result, isVisible = true, type) { links ->
|
||||||
|
// Could not find a better way to do this
|
||||||
|
val context = AcraApplication.context
|
||||||
postPopup(
|
postPopup(
|
||||||
text,
|
text,
|
||||||
links.links.map { txt("${it.name} ${Qualities.getStringByInt(it.quality)}") }) {
|
links.links.apmap {
|
||||||
|
val size = it.getVideoSize()?.let { size -> " " + formatFileSize(context, size) } ?: ""
|
||||||
|
txt("${it.name} ${Qualities.getStringByInt(it.quality)}$size")
|
||||||
|
}) {
|
||||||
callback.invoke(links to (it ?: return@postPopup))
|
callback.invoke(links to (it ?: return@postPopup))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -404,8 +404,28 @@ open class ExtractorLink constructor(
|
||||||
open val extractorData: String? = null,
|
open val extractorData: String? = null,
|
||||||
open val type: ExtractorLinkType,
|
open val type: ExtractorLinkType,
|
||||||
) : VideoDownloadManager.IDownloadableMinimum {
|
) : VideoDownloadManager.IDownloadableMinimum {
|
||||||
val isM3u8 : Boolean get() = type == ExtractorLinkType.M3U8
|
val isM3u8: Boolean get() = type == ExtractorLinkType.M3U8
|
||||||
val isDash : Boolean get() = type == ExtractorLinkType.DASH
|
val isDash: Boolean get() = type == ExtractorLinkType.DASH
|
||||||
|
|
||||||
|
// Cached video size
|
||||||
|
private var videoSize: Long? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get video size in bytes with one head request. Only available for ExtractorLinkType.Video
|
||||||
|
* @param timeoutSeconds timeout of the head request.
|
||||||
|
*/
|
||||||
|
suspend fun getVideoSize(timeoutSeconds: Long = 3L): Long? {
|
||||||
|
// Content-Length is not applicable to other types of formats
|
||||||
|
if (this.type != ExtractorLinkType.VIDEO) return null
|
||||||
|
|
||||||
|
videoSize = videoSize ?: runCatching {
|
||||||
|
val response =
|
||||||
|
app.head(this.url, headers = headers, referer = referer, timeout = timeoutSeconds)
|
||||||
|
response.headers["Content-Length"]?.toLong()
|
||||||
|
}.getOrNull()
|
||||||
|
|
||||||
|
return videoSize
|
||||||
|
}
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
fun getAllHeaders() : Map<String, String> {
|
fun getAllHeaders() : Map<String, String> {
|
||||||
|
|
|
@ -113,6 +113,13 @@
|
||||||
<requestFocus />
|
<requestFocus />
|
||||||
</com.google.android.material.button.MaterialButton>
|
</com.google.android.material.button.MaterialButton>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/reset_btt"
|
||||||
|
style="@style/BlackButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:text="@string/reset_btn" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/cancel_btt"
|
android:id="@+id/cancel_btt"
|
||||||
style="@style/BlackButton"
|
style="@style/BlackButton"
|
||||||
|
|
|
@ -767,4 +767,5 @@
|
||||||
<string name="music_singlar">Music</string>
|
<string name="music_singlar">Music</string>
|
||||||
<string name="audio_book_singular">Audio Book</string>
|
<string name="audio_book_singular">Audio Book</string>
|
||||||
<string name="custom_media_singluar">Media</string>
|
<string name="custom_media_singluar">Media</string>
|
||||||
|
<string name="reset_btn">Reset</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in a new issue