diff --git a/app/build.gradle b/app/build.gradle
index 9ffbc147..cad0a6f1 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -43,8 +43,8 @@ repositories {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
- implementation 'androidx.core:core-ktx:1.3.2'
- implementation 'androidx.appcompat:appcompat:1.2.0'
+ implementation 'androidx.core:core-ktx:1.5.0'
+ implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
@@ -68,11 +68,11 @@ dependencies {
implementation 'com.github.bumptech.glide:glide:4.12.0'
implementation 'jp.wasabeef:glide-transformations:4.0.0'
- implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
+ implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
// Exoplayer
implementation 'com.google.android.exoplayer:exoplayer:2.14.0'
implementation 'com.google.android.exoplayer:extension-cast:2.14.0'
implementation "com.google.android.exoplayer:extension-mediasession:2.14.0"
- implementation "com.google.android.exoplayer:extension-leanback:2.14.0"
+ //implementation "com.google.android.exoplayer:extension-leanback:2.14.0"
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0318a76c..c62789a7 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -14,6 +14,9 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
+
0) {
@@ -56,6 +62,15 @@ object UIHelper {
return result
}
+ fun Context.getNavigationBarHeight(): Int {
+ var result = 0
+ val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
+ if (resourceId > 0) {
+ result = resources.getDimensionPixelSize(resourceId)
+ }
+ return result
+ }
+
fun Activity.fixPaddingStatusbar(v: View) {
v.setPadding(v.paddingLeft, v.paddingTop + getStatusBarHeight(), v.paddingRight, v.paddingBottom)
}
@@ -97,7 +112,7 @@ object UIHelper {
var onAudioFocusEvent = Event()
fun getAudioListener(): AudioManager.OnAudioFocusChangeListener? {
- if(_OnAudioFocusChangeListener != null) return _OnAudioFocusChangeListener
+ if (_OnAudioFocusChangeListener != null) return _OnAudioFocusChangeListener
_OnAudioFocusChangeListener = AudioManager.OnAudioFocusChangeListener {
onAudioFocusEvent.invoke(
when (it) {
@@ -111,6 +126,20 @@ object UIHelper {
return _OnAudioFocusChangeListener
}
+ fun Context.isCastApiAvailable(): Boolean {
+ val isCastApiAvailable =
+ GoogleApiAvailability.getInstance()
+ .isGooglePlayServicesAvailable(applicationContext) == ConnectionResult.SUCCESS
+ try {
+ applicationContext?.let { CastContext.getSharedInstance(it) }
+ } catch (e: Exception) {
+ println(e)
+ // track non-fatal
+ return false
+ }
+ return isCastApiAvailable
+ }
+
fun getFocusRequest(): AudioFocusRequest? {
if (_AudioFocusRequest != null) return _AudioFocusRequest
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@@ -130,4 +159,89 @@ object UIHelper {
null
}
}
+
+ fun Activity.hideSystemUI() {
+ // Enables regular immersive mode.
+ // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
+ // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ // Set the content to appear under the system bars so that the
+ // content doesn't resize when the system bars hide and show.
+ or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ // Hide the nav bar and status bar
+ or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ or View.SYSTEM_UI_FLAG_FULLSCREEN
+ // or View.SYSTEM_UI_FLAG_LOW_PROFILE
+ )
+ // window.addFlags(View.KEEP_SCREEN_ON)
+ }
+
+ fun FragmentActivity.popCurrentPage(isInPlayer: Boolean, isInExpandedView: Boolean, isInResults: Boolean) {
+ val currentFragment = supportFragmentManager.fragments.lastOrNull {
+ it.isVisible
+ }
+ ?: //this.onBackPressed()
+ return
+
+/*
+ if (tvActivity == null) {
+ requestedOrientation = if (settingsManager?.getBoolean("force_landscape", false) == true) {
+ ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
+ } else {
+ ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+ }
+ }*/
+
+ // No fucked animations leaving the player :)
+ when {
+ isInPlayer -> {
+ supportFragmentManager.beginTransaction()
+ //.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit)
+ .remove(currentFragment)
+ .commitAllowingStateLoss()
+ }
+ isInExpandedView && !isInResults -> {
+ supportFragmentManager.beginTransaction()
+ .setCustomAnimations(
+ R.anim.enter_anim,//R.anim.enter_from_right,
+ R.anim.exit_anim,//R.anim.exit_to_right,
+ R.anim.pop_enter,
+ R.anim.pop_exit
+ )
+ .remove(currentFragment)
+ .commitAllowingStateLoss()
+ }
+ else -> {
+ supportFragmentManager.beginTransaction()
+ .setCustomAnimations(R.anim.enter_anim, R.anim.exit_anim, R.anim.pop_enter, R.anim.pop_exit)
+ .remove(currentFragment)
+ .commitAllowingStateLoss()
+ }
+ }
+ }
+
+
+ fun Activity.changeStatusBarState(hide: Boolean): Int {
+ return if (hide) {
+ window?.setFlags(
+ WindowManager.LayoutParams.FLAG_FULLSCREEN,
+ WindowManager.LayoutParams.FLAG_FULLSCREEN
+ )
+ 0
+ } else {
+ window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
+ this.getStatusBarHeight()
+ }
+ }
+
+ // Shows the system bars by removing all the flags
+ // except for the ones that make the content appear under the system bars.
+ fun Activity.showSystemUI() {
+ window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
+ // window.clearFlags(View.KEEP_SCREEN_ON)
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ShiroProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ShiroProvider.kt
index b8a4c662..900b14e0 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ShiroProvider.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ShiroProvider.kt
@@ -24,12 +24,12 @@ class ShiroProvider : MainAPI() {
}
}
- fun autoLoadToken(): Boolean {
+ private fun autoLoadToken(): Boolean {
if (token != null) return true
return loadToken()
}
- fun loadToken(): Boolean {
+ private fun loadToken(): Boolean {
return try {
val response = khttp.get(mainUrl, headers = baseHeader)
@@ -188,7 +188,7 @@ class ShiroProvider : MainAPI() {
return AnimeLoadResponse(
data.english,
data.japanese,
- data.canonicalTitle ?: data.name.replace("Dubbed", ""),
+ data.name.replace("Dubbed", ""),//data.canonicalTitle ?: data.name.replace("Dubbed", ""),
"$mainUrl/${slug}",
this.name,
getType(data.type ?: ""),
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt
new file mode 100644
index 00000000..23f04b0c
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt
@@ -0,0 +1,113 @@
+package com.lagradost.cloudstream3.ui
+
+import android.os.Bundle
+import android.view.Menu
+import android.view.View.INVISIBLE
+import android.view.View.VISIBLE
+import android.widget.ImageView
+import androidx.appcompat.app.AlertDialog
+import com.google.android.gms.cast.MediaStatus.REPEAT_MODE_REPEAT_SINGLE
+import com.google.android.gms.cast.framework.CastButtonFactory
+import com.google.android.gms.cast.framework.CastSession
+import com.google.android.gms.cast.framework.media.uicontroller.UIController
+import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity
+import com.lagradost.cloudstream3.R
+
+import org.json.JSONObject
+
+class SkipOpController(val view: ImageView) : UIController() {
+ init {
+ view.setImageResource(R.drawable.exo_controls_fastforward)
+ view.setOnClickListener {
+ remoteMediaClient.seek(remoteMediaClient.approximateStreamPosition + 85000)
+ }
+ }
+}
+
+class SelectSourceController(val view: ImageView) : UIController() {
+
+ init {
+ view.setImageResource(R.drawable.ic_baseline_playlist_play_24)
+ view.setOnClickListener {
+ //remoteMediaClient.mediaQueue.itemCount
+ //println(remoteMediaClient.mediaInfo.customData)
+ //remoteMediaClient.queueJumpToItem()
+ lateinit var dialog: AlertDialog
+ val items = mutableListOf>()
+ for (i in 0 until remoteMediaClient.mediaQueue.itemCount) {
+ (remoteMediaClient.mediaQueue.getItemAtIndex(i)?.media?.customData?.get("data") as? String)?.let { name ->
+ items.add(
+ remoteMediaClient.mediaQueue.getItemAtIndex(i)!!.itemId to name
+ )
+ }
+ }
+
+ // TODO FIX
+ if (items.isNotEmpty()) {
+ val builder = AlertDialog.Builder(view.context, R.style.AlertDialogCustom)
+ builder.setTitle("Pick source")
+
+ builder.setSingleChoiceItems(
+ items.map { it.second }.toTypedArray(),
+ remoteMediaClient.currentItem.itemId - 1
+ ) { _, which ->
+ println(
+ remoteMediaClient.queueJumpToItem(
+ items[which].first,
+ remoteMediaClient.approximateStreamPosition,
+ null
+ )
+ )
+ dialog.dismiss()
+ }
+ dialog = builder.create()
+ dialog.show()
+ }
+ }
+ }
+
+ override fun onMediaStatusUpdated() {
+ super.onMediaStatusUpdated()
+ // If there's 1 item it won't show
+ val dataString = remoteMediaClient.mediaQueue.getItemAtIndex(1)?.media?.customData?.get("data") as? String
+ view.visibility = if (dataString != null) VISIBLE else INVISIBLE
+ }
+
+ override fun onSessionConnected(castSession: CastSession?) {
+ super.onSessionConnected(castSession)
+ remoteMediaClient.queueSetRepeatMode(REPEAT_MODE_REPEAT_SINGLE, JSONObject())
+ }
+}
+
+class SkipTimeController(val view: ImageView, forwards: Boolean) : UIController() {
+ init {
+ //val settingsManager = PreferenceManager.getDefaultSharedPreferences()
+ //val time = settingsManager?.getInt("chromecast_tap_time", 30) ?: 30
+ val time = 30
+ view.setImageResource(if (forwards) R.drawable.netflix_skip_forward else R.drawable.netflix_skip_back)
+ view.setOnClickListener {
+ remoteMediaClient.seek(remoteMediaClient.approximateStreamPosition + time * 1000 * if (forwards) 1 else -1)
+ }
+ }
+}
+
+class ControllerActivity : ExpandedControllerActivity() {
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
+ super.onCreateOptionsMenu(menu)
+ menuInflater.inflate(R.menu.cast_expanded_controller_menu, menu)
+ CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item)
+ return true
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val sourcesButton: ImageView = getButtonImageViewAt(0)
+ val skipBackButton: ImageView = getButtonImageViewAt(1)
+ val skipForwardButton: ImageView = getButtonImageViewAt(2)
+ val skipOpButton: ImageView = getButtonImageViewAt(3)
+ uiMediaController.bindViewToUIController(sourcesButton, SelectSourceController(sourcesButton))
+ uiMediaController.bindViewToUIController(skipBackButton, SkipTimeController(skipBackButton, false))
+ uiMediaController.bindViewToUIController(skipForwardButton, SkipTimeController(skipForwardButton, true))
+ uiMediaController.bindViewToUIController(skipOpButton, SkipOpController(skipOpButton))
+ }
+}
\ No newline at end of file
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 44ab4832..9804abdc 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
@@ -12,6 +12,7 @@ import android.graphics.Color
import android.media.AudioManager
import android.net.Uri
import android.os.*
+import android.util.DisplayMetrics
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
@@ -20,7 +21,7 @@ import android.view.ViewGroup
import android.view.animation.*
import android.widget.ProgressBar
import android.widget.Toast
-import android.widget.Toast.LENGTH_LONG
+import android.widget.Toast.LENGTH_SHORT
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
@@ -33,6 +34,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.json.JsonMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
import com.google.android.exoplayer2.*
+import com.google.android.exoplayer2.C.TIME_UNSET
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout
@@ -43,7 +45,12 @@ import com.google.android.exoplayer2.util.MimeTypes
import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.UIHelper.getFocusRequest
+import com.lagradost.cloudstream3.UIHelper.getNavigationBarHeight
+import com.lagradost.cloudstream3.UIHelper.getStatusBarHeight
+import com.lagradost.cloudstream3.UIHelper.hideSystemUI
+import com.lagradost.cloudstream3.UIHelper.popCurrentPage
import com.lagradost.cloudstream3.UIHelper.requestLocalAudioFocus
+import com.lagradost.cloudstream3.UIHelper.showSystemUI
import com.lagradost.cloudstream3.UIHelper.toPx
import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.observeDirectly
@@ -64,6 +71,7 @@ import javax.net.ssl.SSLSession
import kotlin.concurrent.thread
import kotlin.math.abs
import kotlin.math.ceil
+import kotlin.properties.Delegates
//http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4
@@ -123,11 +131,13 @@ class PlayerFragment : Fragment() {
//private var currentPercentage = 0
// private var hasNextEpisode = true
- val formatBuilder = StringBuilder()
- val formatter = Formatter(formatBuilder, Locale.getDefault())
+ // val formatBuilder = StringBuilder()
+ // val formatter = Formatter(formatBuilder, Locale.getDefault())
private var width = Resources.getSystem().displayMetrics.heightPixels
private var height = Resources.getSystem().displayMetrics.widthPixels
+ private var statusBarHeight by Delegates.notNull()
+ private var navigationBarHeight by Delegates.notNull()
private var isLocked = false
@@ -271,27 +281,38 @@ class PlayerFragment : Fragment() {
private val swipeVerticalEnabled = true//settingsManager.getBoolean("swipe_vertical_enabled", true)
private val playBackSpeedEnabled = true//settingsManager!!.getBoolean("playback_speed_enabled", false)
private val playerResizeEnabled = true//settingsManager!!.getBoolean("player_resize_enabled", false)
+ private val swipeEdgeSize = 10.toPx
private var isMovingStartTime = 0L
private var currentX = 0F
private var currentY = 0F
private var cachedVolume = 0f
+ private var isValidTouch = false
fun handleMotionEvent(motionEvent: MotionEvent) {
// TIME_UNSET == -9223372036854775807L
// No swiping on unloaded
// https://exoplayer.dev/doc/reference/constant-values.html
- if (isLocked || exoPlayer.duration == -9223372036854775807L || (!swipeEnabled && !swipeVerticalEnabled)) return
+ if (isLocked || exoPlayer.duration == TIME_UNSET || (!swipeEnabled && !swipeVerticalEnabled)) return
+
+
val audioManager = activity?.getSystemService(AUDIO_SERVICE) as? AudioManager
when (motionEvent.action) {
MotionEvent.ACTION_DOWN -> {
- currentX = motionEvent.rawX
- currentY = motionEvent.rawY
- //println("DOWN: " + currentX)
- isMovingStartTime = exoPlayer.currentPosition
+ // SO YOU CAN PULL DOWN STATUSBAR OR NAVBAR
+ if (motionEvent.rawY > statusBarHeight && motionEvent.rawX < width - navigationBarHeight) {
+ currentX = motionEvent.rawX
+ currentY = motionEvent.rawY
+ isValidTouch = true
+ //println("DOWN: " + currentX)
+ isMovingStartTime = exoPlayer.currentPosition
+ } else {
+ isValidTouch = false
+ }
}
MotionEvent.ACTION_MOVE -> {
+ if (!isValidTouch) return
if (swipeVerticalEnabled) {
val distanceMultiplierY = 2F
val distanceY = (motionEvent.rawY - currentY) * distanceMultiplierY
@@ -382,6 +403,7 @@ class PlayerFragment : Fragment() {
}
}
MotionEvent.ACTION_UP -> {
+ if (!isValidTouch) return
val transition: Transition = Fade()
transition.duration = 1000
@@ -417,7 +439,9 @@ class PlayerFragment : Fragment() {
}
fun changeSkip(position: Long? = null) {
- if (exoPlayer.currentPosition >= 0) {
+ val data = localData
+
+ if (this::exoPlayer.isInitialized && exoPlayer.currentPosition >= 0) {
val percentage = ((position ?: exoPlayer.currentPosition) * 100 / exoPlayer.contentDuration).toInt()
val hasNext = hasNextEpisode()
@@ -433,13 +457,17 @@ class PlayerFragment : Fragment() {
}
val nextEp = percentage >= OPENING_PROCENTAGE
- val data = localData
-
skip_op_text.text = if (nextEp) "Next Episode" else "Skip OP"
val isVis =
if (nextEp) hasNext //&& !isCurrentlySkippingEp
else (data is AnimeLoadResponse && (data.type == TvType.Anime || data.type == TvType.ONA))
skip_op.visibility = if (isVis) View.VISIBLE else View.GONE
+ } else {
+ if(data is AnimeLoadResponse) {
+ val isVis = ((data.type == TvType.Anime || data.type == TvType.ONA))
+ skip_op_text.text = "Skip OP"
+ skip_op.visibility = if (isVis) View.VISIBLE else View.GONE
+ }
}
}
@@ -557,6 +585,9 @@ class PlayerFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
+ navigationBarHeight = requireContext().getNavigationBarHeight()
+ statusBarHeight = requireContext().getStatusBarHeight()
+
if (savedInstanceState != null) {
currentWindow = savedInstanceState.getInt(STATE_RESUME_WINDOW)
playbackPosition = savedInstanceState.getLong(STATE_RESUME_POSITION)
@@ -711,7 +742,7 @@ class PlayerFragment : Fragment() {
override fun onSingleClick() {
onClickChange()
- // activity?.hideSystemUI()
+ activity?.hideSystemUI()
}
override fun onMotionEvent(event: MotionEvent) {
@@ -727,6 +758,14 @@ class PlayerFragment : Fragment() {
Listener()
)
+ video_go_back.setOnClickListener {
+ activity?.popCurrentPage(isInPlayer = true, isInExpandedView = false, isInResults = false)
+ }
+ video_go_back_holder.setOnClickListener {
+ println("video_go_back_pressed")
+ activity?.popCurrentPage(isInPlayer = true, isInExpandedView = false, isInResults = false)
+ }
+
playback_speed_btt.visibility = if (playBackSpeedEnabled) VISIBLE else GONE
playback_speed_btt.setOnClickListener {
lateinit var dialog: AlertDialog
@@ -799,6 +838,8 @@ class PlayerFragment : Fragment() {
skipOP()
}
}
+
+ changeSkip()
}
private fun getCurrentUrl(): ExtractorLink? {
@@ -844,6 +885,24 @@ class PlayerFragment : Fragment() {
private var isCurrentlySkippingEp = false
+
+ fun tryNextMirror() {
+ val urls = getUrls()
+ val current = getCurrentUrl()
+ if (urls != null && current != null) {
+ val id = current.getId()
+ val sorted = sortUrls(urls)
+ for ((i, item) in sorted.withIndex()) {
+ if (item.getId() == id) {
+ if (sorted.size > i + 1) {
+ setMirrorId(sorted[i + 1].getId())
+ initPlayer()
+ }
+ }
+ }
+ }
+ }
+
private fun skipToNextEpisode() {
if (isCurrentlySkippingEp) return
isCurrentlySkippingEp = true
@@ -868,6 +927,7 @@ class PlayerFragment : Fragment() {
override fun onResume() {
super.onResume()
+ activity?.hideSystemUI()
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
thread {
initPlayer()
@@ -878,6 +938,8 @@ class PlayerFragment : Fragment() {
override fun onDestroy() {
super.onDestroy()
// releasePlayer()
+
+ activity?.showSystemUI()
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER
}
@@ -1084,11 +1146,12 @@ class PlayerFragment : Fragment() {
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
// updatePIPModeActions()
+ if(activity == null) return
if (playWhenReady) {
when (playbackState) {
Player.STATE_READY -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- requireActivity().requestLocalAudioFocus(getFocusRequest())
+ activity?.requestLocalAudioFocus(getFocusRequest())
}
}
Player.STATE_ENDED -> {
@@ -1113,20 +1176,21 @@ class PlayerFragment : Fragment() {
Toast.makeText(
activity,
"Source error\n" + error.sourceException.message,
- LENGTH_LONG
+ LENGTH_SHORT
)
.show()
+ tryNextMirror()
}
}
ExoPlaybackException.TYPE_REMOTE -> {
- Toast.makeText(activity, "Remote error", LENGTH_LONG)
+ Toast.makeText(activity, "Remote error", LENGTH_SHORT)
.show()
}
ExoPlaybackException.TYPE_RENDERER -> {
Toast.makeText(
activity,
"Renderer error\n" + error.rendererException.message,
- LENGTH_LONG
+ LENGTH_SHORT
)
.show()
}
@@ -1134,7 +1198,7 @@ class PlayerFragment : Fragment() {
Toast.makeText(
activity,
"Unexpected player error\n" + error.unexpectedException.message,
- LENGTH_LONG
+ LENGTH_SHORT
).show()
}
}
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt
index 03dd26d1..7f6a1dde 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt
@@ -9,8 +9,6 @@ import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.*
-import com.lagradost.cloudstream3.APIHolder.getApiFromName
-import com.lagradost.cloudstream3.utils.ExtractorLink
import kotlinx.android.synthetic.main.result_episode.view.*
const val ACTION_PLAY_EPISODE = 1
@@ -50,20 +48,19 @@ class EpisodeAdapter(
class CardViewHolder
constructor(
itemView: View,
- _activity: Activity,
+ val activity: Activity,
resView: RecyclerView,
- clickCallback: (EpisodeClickEvent) -> Unit,
+ private val clickCallback: (EpisodeClickEvent) -> Unit,
) : RecyclerView.ViewHolder(itemView) {
- val activity = _activity
- val episode_view_procentage: View = itemView.episode_view_procentage
- val episode_view_procentage_off: View = itemView.episode_view_procentage_off
- val episode_text: TextView = itemView.episode_text
- val episode_extra: ImageView = itemView.episode_extra
- val episode_play: ImageView = itemView.episode_play
- val clickCallback = clickCallback
+ private val episodeViewPrecentage: View = itemView.episode_view_procentage
+ private val episodeViewPercentageOff: View = itemView.episode_view_procentage_off
+ private val episodeText: TextView = itemView.episode_text
+ val episodeExtra: ImageView = itemView.episode_extra
+ private val episodePlay: ImageView = itemView.episode_play
+ private val episodeHolder = itemView.episode_holder
fun bind(card: ResultEpisode) {
- episode_text.text = card.name ?: "Episode ${card.episode}"
+ episodeText.text = card.name ?: "Episode ${card.episode}"
fun setWidth(v: View, procentage: Float) {
val param = LinearLayout.LayoutParams(
@@ -73,10 +70,10 @@ class EpisodeAdapter(
)
v.layoutParams = param
}
- setWidth(episode_view_procentage, card.watchProgress)
- setWidth(episode_view_procentage_off, 1 - card.watchProgress)
+ setWidth(episodeViewPrecentage, card.watchProgress)
+ setWidth(episodeViewPercentageOff, 1 - card.watchProgress)
- episode_play.setOnClickListener {
+ episodeHolder.setOnClickListener {
clickCallback.invoke(EpisodeClickEvent(ACTION_PLAY_EPISODE, card))
}
}
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt
index cd107b68..b5a5eee2 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt
@@ -1,35 +1,33 @@
package com.lagradost.cloudstream3.ui.result
-import android.Manifest
import android.annotation.SuppressLint
-import android.app.Activity
-import android.content.ComponentName
-import android.content.Intent
-import android.content.Intent.*
-import android.content.pm.PackageManager
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
+import android.view.View.GONE
+import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
-import androidx.core.app.ActivityCompat
-import androidx.core.content.ContextCompat
-import androidx.core.content.FileProvider
-import androidx.core.net.toUri
import androidx.core.widget.NestedScrollView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
+import androidx.mediarouter.app.MediaRouteButton
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.request.RequestOptions.bitmapTransform
-import com.lagradost.cloudstream3.*
-import com.lagradost.cloudstream3.UIHelper.checkWrite
+import com.google.android.gms.cast.framework.CastButtonFactory
+import com.google.android.gms.cast.framework.CastContext
+import com.google.android.gms.cast.framework.CastState
+import com.google.android.material.button.MaterialButton
+import com.lagradost.cloudstream3.AnimeLoadResponse
+import com.lagradost.cloudstream3.LoadResponse
+import com.lagradost.cloudstream3.R
+import com.lagradost.cloudstream3.ShowStatus
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
-import com.lagradost.cloudstream3.UIHelper.loadResult
-import com.lagradost.cloudstream3.UIHelper.requestRW
+import com.lagradost.cloudstream3.UIHelper.isCastApiAvailable
import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.observe
import com.lagradost.cloudstream3.ui.player.PlayerData
@@ -37,10 +35,8 @@ import com.lagradost.cloudstream3.ui.player.PlayerFragment
import com.lagradost.cloudstream3.utils.ExtractorLink
import jp.wasabeef.glide.transformations.BlurTransformation
import kotlinx.android.synthetic.main.fragment_result.*
-import java.io.File
-
-const val MAX_SYNO_LENGH = 600
+const val MAX_SYNO_LENGH = 300
data class ResultEpisode(
val name: String?,
@@ -89,17 +85,34 @@ class ResultFragment : Fragment() {
super.onViewCreated(view, savedInstanceState)
activity?.fixPaddingStatusbar(result_scroll)
activity?.fixPaddingStatusbar(result_barstatus)
+
+ if (activity?.isCastApiAvailable() == true) {
+ val mMediaRouteButton = view.findViewById(R.id.media_route_button)
+
+ CastButtonFactory.setUpMediaRouteButton(activity, media_route_button)
+ val castContext = CastContext.getSharedInstance(requireActivity().applicationContext)
+
+ if (castContext.castState != CastState.NO_DEVICES_AVAILABLE) media_route_button.visibility = VISIBLE
+ castContext.addCastStateListener { state ->
+ if (media_route_button != null) {
+ if (state == CastState.NO_DEVICES_AVAILABLE) media_route_button.visibility = GONE else {
+ if (media_route_button.visibility == GONE) media_route_button.visibility = VISIBLE
+ }
+ }
+ }
+ }
// activity?.fixPaddingStatusbar(result_toolbar)
val url = arguments?.getString("url")
val slug = arguments?.getString("slug")
val apiName = arguments?.getString("apiName")
- result_scroll.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, _, scrollY, _, oldScrollY ->
+ result_scroll.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, _, scrollY, _, _ ->
if (result_poster_blur == null) return@OnScrollChangeListener
- result_poster_blur.alpha = maxOf(0f, (0.3f - scrollY / 1000f))
- result_barstatus.alpha = scrollY / 200f
- result_barstatus.visibility = if (scrollY > 0) View.VISIBLE else View.GONE
+ result_poster_blur.alpha = maxOf(0f, (0.7f - scrollY / 1000f))
+ result_poster_blur_holder.translationY = -scrollY.toFloat()
+ //result_barstatus.alpha = scrollY / 200f
+ //result_barstatus.visibility = if (scrollY > 0) View.VISIBLE else View.GONEĀ§
})
result_toolbar.setNavigationIcon(R.drawable.ic_baseline_arrow_back_24)
@@ -159,6 +172,7 @@ class ResultFragment : Fragment() {
observe(viewModel.episodes) { episodes ->
if (result_episodes == null || result_episodes.adapter == null) return@observe
+ result_episodes_text.text = "${episodes.size} Episode${if (episodes.size == 1) "" else "s"}"
(result_episodes.adapter as EpisodeAdapter).cardList = episodes
(result_episodes.adapter as EpisodeAdapter).notifyDataSetChanged()
}
@@ -180,15 +194,15 @@ class ResultFragment : Fragment() {
if (d.posterUrl != null) {
val glideUrl =
GlideUrl(d.posterUrl)
- context!!.let {
- /*
- Glide.with(it)
- .load(glideUrl)
- .into(result_poster)*/
+ requireContext().let {
Glide.with(it)
.load(glideUrl)
- .apply(bitmapTransform(BlurTransformation(10, 3)))
+ .into(result_poster)
+
+ Glide.with(it)
+ .load(glideUrl)
+ .apply(bitmapTransform(BlurTransformation(80, 3)))
.into(result_poster_blur)
}
}
@@ -265,14 +279,38 @@ activity?.startActivityForResult(vlcIntent, REQUEST_CODE)
result_descript.text = "No Plot found"
}
+ result_tag.removeAllViews()
+ result_tag_holder.visibility = View.GONE
+ result_status.visibility = View.GONE
+
when (d) {
is AnimeLoadResponse -> {
- val preferEnglish = true
- val titleName = (if (preferEnglish) d.engName else d.japName) ?: d.name
+ result_status.visibility = View.VISIBLE
+ result_status.text = when (d.showStatus) {
+ null -> ""
+ ShowStatus.Ongoing -> "Ongoing"
+ ShowStatus.Completed -> "Completed"
+ }
+
+ // val preferEnglish = true
+ //val titleName = (if (preferEnglish) d.engName else d.japName) ?: d.name
+ val titleName = d.name
result_title.text = titleName
result_toolbar.title = titleName
- result_tags.text = (d.tags ?: ArrayList()).joinToString(separator = " | ")
+ if (d.tags == null) {
+ result_tag_holder.visibility = View.GONE
+ } else {
+ result_tag_holder.visibility = View.VISIBLE
+
+ for ((index, tag) in d.tags.withIndex()) {
+ val viewBtt = layoutInflater.inflate(R.layout.result_tag, null)
+ val btt = viewBtt.findViewById(R.id.result_tag_card)
+ btt.text = tag
+
+ result_tag.addView(viewBtt, index)
+ }
+ }
}
else -> result_title.text = d.name
}
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt
index 703ba153..5cd47546 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchAdaptor.kt
@@ -24,21 +24,18 @@ import kotlinx.android.synthetic.main.search_result_grid.view.*
import kotlin.math.roundToInt
class SearchAdapter(
- activity: Activity,
- animeList: ArrayList,
- resView: AutofitRecyclerView,
+ private var activity: Activity,
+ var cardList: ArrayList,
+ private val resView: AutofitRecyclerView,
) :
RecyclerView.Adapter() {
- var cardList = animeList
- private var activity: Activity = activity
- var resView: AutofitRecyclerView? = resView
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layout = activity.getGridFormatId()
return CardViewHolder(
LayoutInflater.from(parent.context).inflate(layout, parent, false),
activity,
- resView!!
+ resView
)
}
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 c7ac7062..701c6c28 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
@@ -20,6 +20,7 @@ import com.lagradost.cloudstream3.APIHolder.getApiSettings
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
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
@@ -41,11 +42,7 @@ class SearchFragment : Fragment() {
return inflater.inflate(R.layout.fragment_search, container, false)
}
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- activity?.fixPaddingStatusbar(searchRoot)
-
+ private fun fixGrid() {
val compactView = activity?.getGridIsCompact() ?: false
val spanCountLandscape = if (compactView) 2 else 6
val spanCountPortrait = if (compactView) 1 else 3
@@ -56,6 +53,18 @@ class SearchFragment : Fragment() {
} else {
cardSpace.spanCount = spanCountPortrait
}
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+ fixGrid()
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ activity?.fixPaddingStatusbar(searchRoot)
+ fixGrid()
val adapter: RecyclerView.Adapter? = activity?.let {
SearchAdapter(
@@ -129,7 +138,7 @@ class SearchFragment : Fragment() {
search_exit_icon.alpha = 1f
search_loading_bar.alpha = 0f
}
-
+ (activity as AppCompatActivity).loadResult("https://shiro.is/overlord-dubbed", "overlord-dubbed", "Shiro")
/*
(requireActivity() as AppCompatActivity).supportFragmentManager.beginTransaction()
.setCustomAnimations(R.anim.enter_anim,
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchViewModel.kt
index d75cbd15..8e9c7a4b 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchViewModel.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchViewModel.kt
@@ -11,7 +11,7 @@ import com.lagradost.cloudstream3.mvvm.safeApiCall
import kotlinx.coroutines.launch
class SearchViewModel : ViewModel() {
- val api: MainAPI = apis[0]
+ val api: MainAPI = apis[0] //TODO MULTI API
private val _searchResponse: MutableLiveData>> = MutableLiveData()
val searchResponse: LiveData>> get() = _searchResponse
diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/CastOptionsProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/CastOptionsProvider.kt
new file mode 100644
index 00000000..908a8668
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/utils/CastOptionsProvider.kt
@@ -0,0 +1,47 @@
+package com.lagradost.cloudstream3.utils
+
+import android.content.Context
+import com.google.android.gms.cast.framework.CastOptions
+import com.google.android.gms.cast.framework.OptionsProvider
+import com.google.android.gms.cast.framework.SessionProvider
+import com.google.android.gms.cast.framework.media.CastMediaOptions
+import com.google.android.gms.cast.framework.media.MediaIntentReceiver
+import com.google.android.gms.cast.framework.media.NotificationOptions
+import com.lagradost.cloudstream3.R
+import com.lagradost.cloudstream3.ui.ControllerActivity
+import java.util.*
+
+class CastOptionsProvider : OptionsProvider {
+ override fun getCastOptions(p0: Context?): CastOptions {
+ val buttonActions = listOf(
+ MediaIntentReceiver.ACTION_REWIND,
+ MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK,
+ MediaIntentReceiver.ACTION_FORWARD,
+ MediaIntentReceiver.ACTION_STOP_CASTING
+ )
+ val compatButtonAction = intArrayOf(1,3)
+ val notificationOptions =
+ NotificationOptions.Builder()
+ .setTargetActivityClassName(ControllerActivity::class.qualifiedName)
+ .setActions(buttonActions, compatButtonAction)
+ .setForward30DrawableResId(R.drawable.go_forward_30)
+ .setRewind30DrawableResId(R.drawable.go_back_30)
+ .setSkipStepMs(30000)
+ .build()
+
+ val mediaOptions = CastMediaOptions.Builder()
+ .setNotificationOptions(notificationOptions)
+ .setExpandedControllerActivityClassName(ControllerActivity::class.qualifiedName)
+ .build()
+
+ return CastOptions.Builder()
+ .setReceiverApplicationId("A12D4273")
+ .setStopReceiverApplicationWhenEndingSession(true)
+ .setCastMediaOptions(mediaOptions)
+ .build()
+ }
+
+ override fun getAdditionalSessionProviders(p0: Context?): MutableList {
+ return Collections.emptyList()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/Vidstream.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/Vidstream.kt
index 1d61c40e..7cc510cc 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/Vidstream.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/utils/extractors/Vidstream.kt
@@ -17,17 +17,18 @@ class Vidstream {
// https://gogo-stream.com/streaming.php?id=MTE3NDg5
fun getUrl(id: String, isCasting: Boolean = false, callback: (ExtractorLink) -> Unit) : Boolean {
try {
+ normalApis.pmap { api ->
+ val url = api.getExtractorUrl(id)
+ val source = api.getUrl(url)
+ source?.forEach { callback.invoke(it) }
+ }
+
val url = getExtractorUrl(id)
with(khttp.get(url)) {
val document = Jsoup.parse(this.text)
val primaryLinks = document.select("ul.list-server-items > li.linkserver")
val extractedLinksList: MutableList = mutableListOf()
- normalApis.pmap { api ->
- val url = api.getExtractorUrl(id)
- val source = api.getUrl(url)
- source?.forEach { callback.invoke(it) }
- }
// All vidstream links passed to extractors
primaryLinks.forEach { element ->
diff --git a/app/src/main/java/com/lagradost/cloudstream3/widget/FlowLayout.kt b/app/src/main/java/com/lagradost/cloudstream3/widget/FlowLayout.kt
new file mode 100644
index 00000000..892701f6
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/widget/FlowLayout.kt
@@ -0,0 +1,98 @@
+package com.lagradost.cloudstream3.widget
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.util.AttributeSet
+import android.view.ViewGroup
+import com.lagradost.cloudstream3.R
+import kotlin.math.max
+
+class FlowLayout : ViewGroup {
+ constructor(context: Context?) : super(context) {}
+
+ @JvmOverloads
+ constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int = 0) : super(context, attrs, defStyleAttr) {
+ }
+
+ override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+ val realWidth = MeasureSpec.getSize(widthMeasureSpec)
+ var currentHeight = 0
+ var currentWidth = 0
+ var currentChildHookPointx = 0
+ var currentChildHookPointy = 0
+ val childCount = this.childCount
+ for (i in 0 until childCount) {
+ val child = getChildAt(i)
+ measureChild(child, widthMeasureSpec, heightMeasureSpec)
+ val childWidth = child.measuredWidth
+ val childHeight = child.measuredHeight
+
+ //check if child can be placed in the current row, else go to next line
+ if (currentChildHookPointx + childWidth > realWidth) {
+ //new line
+ currentWidth = Math.max(currentWidth, currentChildHookPointx)
+
+ //reset for new line
+ currentChildHookPointx = 0
+ currentChildHookPointy += childHeight
+ }
+ val nextChildHookPointx = currentChildHookPointx + childWidth
+ val nextChildHookPointy = currentChildHookPointy
+ currentHeight = max(currentHeight, currentChildHookPointy + childHeight)
+ val lp = child.layoutParams as LayoutParams
+ lp.x = currentChildHookPointx
+ lp.y = currentChildHookPointy
+ currentChildHookPointx = nextChildHookPointx
+ currentChildHookPointy = nextChildHookPointy
+ }
+ currentWidth = Math.max(currentChildHookPointx, currentWidth)
+ setMeasuredDimension(resolveSize(currentWidth, widthMeasureSpec),
+ resolveSize(currentHeight, heightMeasureSpec))
+ }
+
+ override fun onLayout(b: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
+ //call layout on children
+ val childCount = this.childCount
+ for (i in 0 until childCount) {
+ val child = getChildAt(i)
+ val lp = child.layoutParams as LayoutParams
+ child.layout(lp.x, lp.y, lp.x + child.measuredWidth, lp.y + child.measuredHeight)
+ }
+ }
+
+ override fun generateLayoutParams(attrs: AttributeSet): LayoutParams {
+ return LayoutParams(context, attrs)
+ }
+
+ override fun generateDefaultLayoutParams(): LayoutParams {
+ return LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+ }
+
+ override fun generateLayoutParams(p: ViewGroup.LayoutParams): LayoutParams {
+ return LayoutParams(p)
+ }
+
+ override fun checkLayoutParams(p: ViewGroup.LayoutParams): Boolean {
+ return p is LayoutParams
+ }
+
+ class LayoutParams : MarginLayoutParams {
+ var spacing = -1
+ var x = 0
+ var y = 0
+
+ @SuppressLint("CustomViewStyleable")
+ internal constructor(c: Context, attrs: AttributeSet?) : super(c, attrs) {
+ val t = c.obtainStyledAttributes(attrs, R.styleable.FlowLayout_Layout)
+ spacing = 0 //t.getDimensionPixelSize(R.styleable.FlowLayout_Layout_layout_space, 0);
+ t.recycle()
+ }
+
+ internal constructor(width: Int, height: Int) : super(width, height) {
+ spacing = 0
+ }
+
+ constructor(source: MarginLayoutParams?) : super(source) {}
+ internal constructor(source: ViewGroup.LayoutParams?) : super(source) {}
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/.idea/.gitignore b/app/src/main/res/anim/.idea/.gitignore
new file mode 100644
index 00000000..26d33521
--- /dev/null
+++ b/app/src/main/res/anim/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/app/src/main/res/anim/.idea/misc.xml b/app/src/main/res/anim/.idea/misc.xml
new file mode 100644
index 00000000..639900d1
--- /dev/null
+++ b/app/src/main/res/anim/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/.idea/modules.xml b/app/src/main/res/anim/.idea/modules.xml
new file mode 100644
index 00000000..787e58e6
--- /dev/null
+++ b/app/src/main/res/anim/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/.idea/vcs.xml b/app/src/main/res/anim/.idea/vcs.xml
new file mode 100644
index 00000000..bc599707
--- /dev/null
+++ b/app/src/main/res/anim/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
deleted file mode 100644
index 1ee14938..00000000
--- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/drawable/cs3_cloud.xml b/app/src/main/res/drawable/cs3_cloud.xml
new file mode 100644
index 00000000..d8fc1dbd
--- /dev/null
+++ b/app/src/main/res/drawable/cs3_cloud.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/go_back_30.xml b/app/src/main/res/drawable/go_back_30.xml
new file mode 100644
index 00000000..8ab536ee
--- /dev/null
+++ b/app/src/main/res/drawable/go_back_30.xml
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/go_forward_30.xml b/app/src/main/res/drawable/go_forward_30.xml
new file mode 100644
index 00000000..d3ba0af9
--- /dev/null
+++ b/app/src/main/res/drawable/go_forward_30.xml
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_baseline_arrow_back_24.xml b/app/src/main/res/drawable/ic_baseline_arrow_back_24.xml
index 31e7df2e..a6108143 100644
--- a/app/src/main/res/drawable/ic_baseline_arrow_back_24.xml
+++ b/app/src/main/res/drawable/ic_baseline_arrow_back_24.xml
@@ -1,5 +1,5 @@
diff --git a/app/src/main/res/drawable/ic_baseline_aspect_ratio_24.xml b/app/src/main/res/drawable/ic_baseline_aspect_ratio_24.xml
index c7b8b5f5..d93d1b64 100644
--- a/app/src/main/res/drawable/ic_baseline_aspect_ratio_24.xml
+++ b/app/src/main/res/drawable/ic_baseline_aspect_ratio_24.xml
@@ -1,4 +1,4 @@
-
diff --git a/app/src/main/res/drawable/ic_baseline_bookmark_24.xml b/app/src/main/res/drawable/ic_baseline_bookmark_24.xml
index 8f0b1b18..542456d8 100644
--- a/app/src/main/res/drawable/ic_baseline_bookmark_24.xml
+++ b/app/src/main/res/drawable/ic_baseline_bookmark_24.xml
@@ -1,4 +1,4 @@
-
diff --git a/app/src/main/res/drawable/ic_baseline_brightness_7_24.xml b/app/src/main/res/drawable/ic_baseline_brightness_7_24.xml
index dc94884a..191109b7 100644
--- a/app/src/main/res/drawable/ic_baseline_brightness_7_24.xml
+++ b/app/src/main/res/drawable/ic_baseline_brightness_7_24.xml
@@ -1,4 +1,4 @@
-
diff --git a/app/src/main/res/drawable/ic_baseline_more_vert_24.xml b/app/src/main/res/drawable/ic_baseline_more_vert_24.xml
index 6a7f2748..249fe2a2 100644
--- a/app/src/main/res/drawable/ic_baseline_more_vert_24.xml
+++ b/app/src/main/res/drawable/ic_baseline_more_vert_24.xml
@@ -1,4 +1,4 @@
-
diff --git a/app/src/main/res/drawable/ic_baseline_play_arrow_24.xml b/app/src/main/res/drawable/ic_baseline_play_arrow_24.xml
index 0870be8f..f880379f 100644
--- a/app/src/main/res/drawable/ic_baseline_play_arrow_24.xml
+++ b/app/src/main/res/drawable/ic_baseline_play_arrow_24.xml
@@ -1,4 +1,4 @@
-
diff --git a/app/src/main/res/drawable/ic_baseline_playlist_play_24.xml b/app/src/main/res/drawable/ic_baseline_playlist_play_24.xml
index 6ff89010..6295ffae 100644
--- a/app/src/main/res/drawable/ic_baseline_playlist_play_24.xml
+++ b/app/src/main/res/drawable/ic_baseline_playlist_play_24.xml
@@ -1,5 +1,5 @@
diff --git a/app/src/main/res/drawable/ic_baseline_speed_24.xml b/app/src/main/res/drawable/ic_baseline_speed_24.xml
index 1add8a09..046754aa 100644
--- a/app/src/main/res/drawable/ic_baseline_speed_24.xml
+++ b/app/src/main/res/drawable/ic_baseline_speed_24.xml
@@ -1,4 +1,4 @@
-
diff --git a/app/src/main/res/drawable/ic_baseline_star_24.xml b/app/src/main/res/drawable/ic_baseline_star_24.xml
index 954e7723..ab099425 100644
--- a/app/src/main/res/drawable/ic_baseline_star_24.xml
+++ b/app/src/main/res/drawable/ic_baseline_star_24.xml
@@ -1,4 +1,4 @@
-
diff --git a/app/src/main/res/drawable/ic_baseline_subtitles_24.xml b/app/src/main/res/drawable/ic_baseline_subtitles_24.xml
index f1863edf..75f674c9 100644
--- a/app/src/main/res/drawable/ic_baseline_subtitles_24.xml
+++ b/app/src/main/res/drawable/ic_baseline_subtitles_24.xml
@@ -1,4 +1,4 @@
-
diff --git a/app/src/main/res/drawable/ic_baseline_tune_24.xml b/app/src/main/res/drawable/ic_baseline_tune_24.xml
index c7cae9e0..2ce603c5 100644
--- a/app/src/main/res/drawable/ic_baseline_tune_24.xml
+++ b/app/src/main/res/drawable/ic_baseline_tune_24.xml
@@ -1,4 +1,4 @@
-
diff --git a/app/src/main/res/drawable/ic_baseline_volume_up_24.xml b/app/src/main/res/drawable/ic_baseline_volume_up_24.xml
index 45bf404e..e3ae9806 100644
--- a/app/src/main/res/drawable/ic_baseline_volume_up_24.xml
+++ b/app/src/main/res/drawable/ic_baseline_volume_up_24.xml
@@ -1,5 +1,5 @@
diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 00000000..da9562ff
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/netflix_download.xml b/app/src/main/res/drawable/netflix_download.xml
index a939de44..9d9531d8 100644
--- a/app/src/main/res/drawable/netflix_download.xml
+++ b/app/src/main/res/drawable/netflix_download.xml
@@ -8,7 +8,7 @@
diff --git a/app/src/main/res/drawable/netflix_play.xml b/app/src/main/res/drawable/netflix_play.xml
index 00d17877..816d1069 100644
--- a/app/src/main/res/drawable/netflix_play.xml
+++ b/app/src/main/res/drawable/netflix_play.xml
@@ -5,5 +5,5 @@
android:viewportHeight="850.4">
+ android:fillColor="?attr/white"/>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/search_icon.xml b/app/src/main/res/drawable/search_icon.xml
index 4eb4677d..870d0db6 100644
--- a/app/src/main/res/drawable/search_icon.xml
+++ b/app/src/main/res/drawable/search_icon.xml
@@ -8,13 +8,13 @@
diff --git a/app/src/main/res/layout/fragment_player.xml b/app/src/main/res/layout/fragment_player.xml
index 7bf599d7..3a137bb5 100644
--- a/app/src/main/res/layout/fragment_player.xml
+++ b/app/src/main/res/layout/fragment_player.xml
@@ -38,7 +38,6 @@
android:backgroundTint="@android:color/black"
>
-
-
+
+ android:layout_width="match_parent" android:layout_height="30dp">
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
-
+
+
+
-
-
-
-
+
+
+
+
-
+ android:textSize="17sp"
+ android:layout_marginTop="10dp"
+ android:layout_marginBottom="10dp"
+ android:textStyle="normal"
+ android:textColor="?attr/textColor"
+ />
diff --git a/app/src/main/res/layout/player_custom_layout.xml b/app/src/main/res/layout/player_custom_layout.xml
index 7279edb3..638d1b2c 100644
--- a/app/src/main/res/layout/player_custom_layout.xml
+++ b/app/src/main/res/layout/player_custom_layout.xml
@@ -370,7 +370,7 @@
android:textColor="@android:color/white"
android:textSize="14sp"
android:textStyle="normal"/>
-
+
diff --git a/app/src/main/res/layout/result_episode.xml b/app/src/main/res/layout/result_episode.xml
index f3a3c0b9..c26ff182 100644
--- a/app/src/main/res/layout/result_episode.xml
+++ b/app/src/main/res/layout/result_episode.xml
@@ -6,8 +6,11 @@
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:layout_marginBottom="2dp"
+ app:cardBackgroundColor="@color/transparent"
+ app:cardElevation="0dp"
+ android:id="@+id/episode_holder"
+ android:foreground="?android:attr/selectableItemBackgroundBorderless"
+ android:layout_marginBottom="5dp"
>
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/search_result_compact.xml b/app/src/main/res/layout/search_result_compact.xml
index ed73bb01..d756e50c 100644
--- a/app/src/main/res/layout/search_result_compact.xml
+++ b/app/src/main/res/layout/search_result_compact.xml
@@ -20,7 +20,7 @@
android:elevation="0dp"
app:cardCornerRadius="@dimen/roundedImageRadius"
- app:cardBackgroundColor="@color/itemBackground"
+ app:cardBackgroundColor="?attr/boxItemBackground"
android:clickable="true"
android:focusable="true"
>
@@ -50,7 +50,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="17sp"
- android:textColor="@color/textColor"
+ android:textColor="?attr/textColor"
android:id="@+id/imageText"
android:textStyle="bold"
android:maxLines="3"
@@ -59,7 +59,7 @@
tools:text="@string/no_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textColor="@color/lightGrayTextColor"
+ android:textColor="?attr/grayTextColor"
android:id="@+id/imageTextExtra"
android:textSize="13sp"
android:textStyle="bold"
@@ -70,7 +70,7 @@
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textColor="@color/colorPrimary"
+ android:textColor="?attr/colorPrimary"
android:id="@+id/imageTextProvider"
android:maxLines="1"
/>
diff --git a/app/src/main/res/layout/search_result_super_compact.xml b/app/src/main/res/layout/search_result_super_compact.xml
index d5ba157a..2e7fb8f0 100644
--- a/app/src/main/res/layout/search_result_super_compact.xml
+++ b/app/src/main/res/layout/search_result_super_compact.xml
@@ -48,7 +48,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="17sp"
- android:textColor="@color/textColor"
+ android:textColor="?attr/textColor"
android:id="@+id/imageText"
android:textStyle="normal"
android:maxLines="3"
@@ -58,7 +58,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
- android:textColor="@color/lightGrayTextColor"
+ android:textColor="?attr/grayTextColor"
android:id="@+id/imageTextExtra"
android:textSize="13sp"
android:textStyle="bold"
@@ -69,7 +69,7 @@
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textColor="@color/colorPrimary"
+ android:textColor="?attr/colorPrimary"
android:id="@+id/imageTextProvider"
android:maxLines="1"
/>
diff --git a/app/src/main/res/menu/cast_expanded_controller_menu.xml b/app/src/main/res/menu/cast_expanded_controller_menu.xml
new file mode 100644
index 00000000..7fbf6ec9
--- /dev/null
+++ b/app/src/main/res/menu/cast_expanded_controller_menu.xml
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index bbd3e021..7353dbd1 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
index bbd3e021..7353dbd1 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
index a571e600..6df27f85 100644
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
index 61da551c..814f61c0 100644
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
index c41dd285..0fef429f 100644
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
index db5080a7..34d17ffb 100644
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index 6dba46da..29cbab7d 100644
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
index da31a871..af368ed2 100644
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index 15ac6817..93900a2f 100644
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
index b216f2d3..38a51ad2 100644
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index f25a4197..f8c73a40 100644
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
index e96783cc..b30fa322 100644
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
new file mode 100644
index 00000000..fb66e72c
--- /dev/null
+++ b/app/src/main/res/values/attrs.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 1b96a836..45a2e76d 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -12,11 +12,11 @@
#2B2C30
#1C1C20
#1C1C20
- #131217
+ #17171B
#e9eaee
#9ba0a4
- #9f9fa0
+
@color/textColor
#1AFFFFFF
#00000000
@@ -33,6 +33,9 @@
#66000000
#C0121212
#121212
- #66B5B5B5
- #617EFF
+ #66B5B5B5
+
+ @color/colorPrimary
+
+ #9ba0a6
\ No newline at end of file
diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml
new file mode 100644
index 00000000..7bbb50f4
--- /dev/null
+++ b/app/src/main/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+
+
+ #3242D3
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5e4b57b9..bb91e1eb 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -15,4 +15,7 @@
Go back
Next episode
10
+ Poster
+ Plot
+ Genres
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 5ce0aa82..ce927e25 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -27,6 +27,17 @@
- @style/AppBottomSheetDialogTheme
- @style/AppSearchViewStyle
- @style/Theme.Widget.Tabs
+
+
+ - @color/textColor
+ - @color/colorItemSeen
+ - @color/grayTextColor
+ - @color/darkBackground
+ - @color/bitDarkerGrayBackground
+ - @color/grayBackground
+ - @color/itemBackground
+ - @color/iconColor
+ - #FFF