UI and chromecast stuff
|
@ -43,8 +43,8 @@ repositories {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||||
implementation 'androidx.core:core-ktx:1.3.2'
|
implementation 'androidx.core:core-ktx:1.5.0'
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.3.0'
|
||||||
implementation 'com.google.android.material:material:1.3.0'
|
implementation 'com.google.android.material:material:1.3.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
|
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
|
||||||
|
@ -68,11 +68,11 @@ dependencies {
|
||||||
implementation 'com.github.bumptech.glide:glide:4.12.0'
|
implementation 'com.github.bumptech.glide:glide:4.12.0'
|
||||||
implementation 'jp.wasabeef:glide-transformations:4.0.0'
|
implementation 'jp.wasabeef:glide-transformations:4.0.0'
|
||||||
|
|
||||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||||
|
|
||||||
// Exoplayer
|
// Exoplayer
|
||||||
implementation 'com.google.android.exoplayer:exoplayer:2.14.0'
|
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-cast:2.14.0'
|
||||||
implementation "com.google.android.exoplayer:extension-mediasession: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"
|
||||||
}
|
}
|
|
@ -14,6 +14,9 @@
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
|
||||||
|
android:value="com.lagradost.cloudstream3.utils.CastOptionsProvider"/>
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|keyboard|keyboardHidden|navigation"
|
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|keyboard|keyboardHidden|navigation"
|
||||||
|
|
BIN
app/src/main/ic_launcher-playstore.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
|
@ -10,10 +10,15 @@ import android.media.AudioFocusRequest
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.WindowManager
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
|
import com.google.android.gms.cast.framework.CastContext
|
||||||
|
import com.google.android.gms.common.ConnectionResult
|
||||||
|
import com.google.android.gms.common.GoogleApiAvailability
|
||||||
import com.lagradost.cloudstream3.ui.result.ResultFragment
|
import com.lagradost.cloudstream3.ui.result.ResultFragment
|
||||||
import com.lagradost.cloudstream3.utils.Event
|
import com.lagradost.cloudstream3.utils.Event
|
||||||
|
|
||||||
|
@ -40,6 +45,7 @@ object UIHelper {
|
||||||
|
|
||||||
fun AppCompatActivity.loadResult(url: String, slug: String, apiName: String) {
|
fun AppCompatActivity.loadResult(url: String, slug: String, apiName: String) {
|
||||||
this.runOnUiThread {
|
this.runOnUiThread {
|
||||||
|
viewModelStore.clear()
|
||||||
this.supportFragmentManager.beginTransaction()
|
this.supportFragmentManager.beginTransaction()
|
||||||
.setCustomAnimations(R.anim.enter_anim, R.anim.exit_anim, R.anim.pop_enter, R.anim.pop_exit)
|
.setCustomAnimations(R.anim.enter_anim, R.anim.exit_anim, R.anim.pop_enter, R.anim.pop_exit)
|
||||||
.add(R.id.homeRoot, ResultFragment.newInstance(url, slug, apiName))
|
.add(R.id.homeRoot, ResultFragment.newInstance(url, slug, apiName))
|
||||||
|
@ -47,7 +53,7 @@ object UIHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Activity.getStatusBarHeight(): Int {
|
fun Context.getStatusBarHeight(): Int {
|
||||||
var result = 0
|
var result = 0
|
||||||
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
|
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
|
||||||
if (resourceId > 0) {
|
if (resourceId > 0) {
|
||||||
|
@ -56,6 +62,15 @@ object UIHelper {
|
||||||
return result
|
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) {
|
fun Activity.fixPaddingStatusbar(v: View) {
|
||||||
v.setPadding(v.paddingLeft, v.paddingTop + getStatusBarHeight(), v.paddingRight, v.paddingBottom)
|
v.setPadding(v.paddingLeft, v.paddingTop + getStatusBarHeight(), v.paddingRight, v.paddingBottom)
|
||||||
}
|
}
|
||||||
|
@ -97,7 +112,7 @@ object UIHelper {
|
||||||
var onAudioFocusEvent = Event<Boolean>()
|
var onAudioFocusEvent = Event<Boolean>()
|
||||||
|
|
||||||
fun getAudioListener(): AudioManager.OnAudioFocusChangeListener? {
|
fun getAudioListener(): AudioManager.OnAudioFocusChangeListener? {
|
||||||
if(_OnAudioFocusChangeListener != null) return _OnAudioFocusChangeListener
|
if (_OnAudioFocusChangeListener != null) return _OnAudioFocusChangeListener
|
||||||
_OnAudioFocusChangeListener = AudioManager.OnAudioFocusChangeListener {
|
_OnAudioFocusChangeListener = AudioManager.OnAudioFocusChangeListener {
|
||||||
onAudioFocusEvent.invoke(
|
onAudioFocusEvent.invoke(
|
||||||
when (it) {
|
when (it) {
|
||||||
|
@ -111,6 +126,20 @@ object UIHelper {
|
||||||
return _OnAudioFocusChangeListener
|
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? {
|
fun getFocusRequest(): AudioFocusRequest? {
|
||||||
if (_AudioFocusRequest != null) return _AudioFocusRequest
|
if (_AudioFocusRequest != null) return _AudioFocusRequest
|
||||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
@ -130,4 +159,89 @@ object UIHelper {
|
||||||
null
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -24,12 +24,12 @@ class ShiroProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun autoLoadToken(): Boolean {
|
private fun autoLoadToken(): Boolean {
|
||||||
if (token != null) return true
|
if (token != null) return true
|
||||||
return loadToken()
|
return loadToken()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadToken(): Boolean {
|
private fun loadToken(): Boolean {
|
||||||
return try {
|
return try {
|
||||||
val response = khttp.get(mainUrl, headers = baseHeader)
|
val response = khttp.get(mainUrl, headers = baseHeader)
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ class ShiroProvider : MainAPI() {
|
||||||
return AnimeLoadResponse(
|
return AnimeLoadResponse(
|
||||||
data.english,
|
data.english,
|
||||||
data.japanese,
|
data.japanese,
|
||||||
data.canonicalTitle ?: data.name.replace("Dubbed", ""),
|
data.name.replace("Dubbed", ""),//data.canonicalTitle ?: data.name.replace("Dubbed", ""),
|
||||||
"$mainUrl/${slug}",
|
"$mainUrl/${slug}",
|
||||||
this.name,
|
this.name,
|
||||||
getType(data.type ?: ""),
|
getType(data.type ?: ""),
|
||||||
|
|
|
@ -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<Pair<Int, String>>()
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ import android.graphics.Color
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.*
|
import android.os.*
|
||||||
|
import android.util.DisplayMetrics
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
@ -20,7 +21,7 @@ import android.view.ViewGroup
|
||||||
import android.view.animation.*
|
import android.view.animation.*
|
||||||
import android.widget.ProgressBar
|
import android.widget.ProgressBar
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import android.widget.Toast.LENGTH_LONG
|
import android.widget.Toast.LENGTH_SHORT
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
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.databind.json.JsonMapper
|
||||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||||
import com.google.android.exoplayer2.*
|
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.source.DefaultMediaSourceFactory
|
||||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
|
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
|
||||||
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout
|
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.*
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.UIHelper.getFocusRequest
|
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.requestLocalAudioFocus
|
||||||
|
import com.lagradost.cloudstream3.UIHelper.showSystemUI
|
||||||
import com.lagradost.cloudstream3.UIHelper.toPx
|
import com.lagradost.cloudstream3.UIHelper.toPx
|
||||||
import com.lagradost.cloudstream3.mvvm.Resource
|
import com.lagradost.cloudstream3.mvvm.Resource
|
||||||
import com.lagradost.cloudstream3.mvvm.observeDirectly
|
import com.lagradost.cloudstream3.mvvm.observeDirectly
|
||||||
|
@ -64,6 +71,7 @@ import javax.net.ssl.SSLSession
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
|
|
||||||
//http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4
|
//http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4
|
||||||
|
@ -123,11 +131,13 @@ class PlayerFragment : Fragment() {
|
||||||
//private var currentPercentage = 0
|
//private var currentPercentage = 0
|
||||||
// private var hasNextEpisode = true
|
// private var hasNextEpisode = true
|
||||||
|
|
||||||
val formatBuilder = StringBuilder()
|
// val formatBuilder = StringBuilder()
|
||||||
val formatter = Formatter(formatBuilder, Locale.getDefault())
|
// val formatter = Formatter(formatBuilder, Locale.getDefault())
|
||||||
|
|
||||||
private var width = Resources.getSystem().displayMetrics.heightPixels
|
private var width = Resources.getSystem().displayMetrics.heightPixels
|
||||||
private var height = Resources.getSystem().displayMetrics.widthPixels
|
private var height = Resources.getSystem().displayMetrics.widthPixels
|
||||||
|
private var statusBarHeight by Delegates.notNull<Int>()
|
||||||
|
private var navigationBarHeight by Delegates.notNull<Int>()
|
||||||
|
|
||||||
private var isLocked = false
|
private var isLocked = false
|
||||||
|
|
||||||
|
@ -271,27 +281,38 @@ class PlayerFragment : Fragment() {
|
||||||
private val swipeVerticalEnabled = true//settingsManager.getBoolean("swipe_vertical_enabled", true)
|
private val swipeVerticalEnabled = true//settingsManager.getBoolean("swipe_vertical_enabled", true)
|
||||||
private val playBackSpeedEnabled = true//settingsManager!!.getBoolean("playback_speed_enabled", false)
|
private val playBackSpeedEnabled = true//settingsManager!!.getBoolean("playback_speed_enabled", false)
|
||||||
private val playerResizeEnabled = true//settingsManager!!.getBoolean("player_resize_enabled", false)
|
private val playerResizeEnabled = true//settingsManager!!.getBoolean("player_resize_enabled", false)
|
||||||
|
private val swipeEdgeSize = 10.toPx
|
||||||
|
|
||||||
private var isMovingStartTime = 0L
|
private var isMovingStartTime = 0L
|
||||||
private var currentX = 0F
|
private var currentX = 0F
|
||||||
private var currentY = 0F
|
private var currentY = 0F
|
||||||
private var cachedVolume = 0f
|
private var cachedVolume = 0f
|
||||||
|
private var isValidTouch = false
|
||||||
|
|
||||||
fun handleMotionEvent(motionEvent: MotionEvent) {
|
fun handleMotionEvent(motionEvent: MotionEvent) {
|
||||||
// TIME_UNSET == -9223372036854775807L
|
// TIME_UNSET == -9223372036854775807L
|
||||||
// No swiping on unloaded
|
// No swiping on unloaded
|
||||||
// https://exoplayer.dev/doc/reference/constant-values.html
|
// 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
|
val audioManager = activity?.getSystemService(AUDIO_SERVICE) as? AudioManager
|
||||||
|
|
||||||
when (motionEvent.action) {
|
when (motionEvent.action) {
|
||||||
MotionEvent.ACTION_DOWN -> {
|
MotionEvent.ACTION_DOWN -> {
|
||||||
|
// SO YOU CAN PULL DOWN STATUSBAR OR NAVBAR
|
||||||
|
if (motionEvent.rawY > statusBarHeight && motionEvent.rawX < width - navigationBarHeight) {
|
||||||
currentX = motionEvent.rawX
|
currentX = motionEvent.rawX
|
||||||
currentY = motionEvent.rawY
|
currentY = motionEvent.rawY
|
||||||
|
isValidTouch = true
|
||||||
//println("DOWN: " + currentX)
|
//println("DOWN: " + currentX)
|
||||||
isMovingStartTime = exoPlayer.currentPosition
|
isMovingStartTime = exoPlayer.currentPosition
|
||||||
|
} else {
|
||||||
|
isValidTouch = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MotionEvent.ACTION_MOVE -> {
|
MotionEvent.ACTION_MOVE -> {
|
||||||
|
if (!isValidTouch) return
|
||||||
if (swipeVerticalEnabled) {
|
if (swipeVerticalEnabled) {
|
||||||
val distanceMultiplierY = 2F
|
val distanceMultiplierY = 2F
|
||||||
val distanceY = (motionEvent.rawY - currentY) * distanceMultiplierY
|
val distanceY = (motionEvent.rawY - currentY) * distanceMultiplierY
|
||||||
|
@ -382,6 +403,7 @@ class PlayerFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MotionEvent.ACTION_UP -> {
|
MotionEvent.ACTION_UP -> {
|
||||||
|
if (!isValidTouch) return
|
||||||
val transition: Transition = Fade()
|
val transition: Transition = Fade()
|
||||||
transition.duration = 1000
|
transition.duration = 1000
|
||||||
|
|
||||||
|
@ -417,7 +439,9 @@ class PlayerFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun changeSkip(position: Long? = null) {
|
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 percentage = ((position ?: exoPlayer.currentPosition) * 100 / exoPlayer.contentDuration).toInt()
|
||||||
val hasNext = hasNextEpisode()
|
val hasNext = hasNextEpisode()
|
||||||
|
|
||||||
|
@ -433,13 +457,17 @@ class PlayerFragment : Fragment() {
|
||||||
}
|
}
|
||||||
val nextEp = percentage >= OPENING_PROCENTAGE
|
val nextEp = percentage >= OPENING_PROCENTAGE
|
||||||
|
|
||||||
val data = localData
|
|
||||||
|
|
||||||
skip_op_text.text = if (nextEp) "Next Episode" else "Skip OP"
|
skip_op_text.text = if (nextEp) "Next Episode" else "Skip OP"
|
||||||
val isVis =
|
val isVis =
|
||||||
if (nextEp) hasNext //&& !isCurrentlySkippingEp
|
if (nextEp) hasNext //&& !isCurrentlySkippingEp
|
||||||
else (data is AnimeLoadResponse && (data.type == TvType.Anime || data.type == TvType.ONA))
|
else (data is AnimeLoadResponse && (data.type == TvType.Anime || data.type == TvType.ONA))
|
||||||
skip_op.visibility = if (isVis) View.VISIBLE else View.GONE
|
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?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
navigationBarHeight = requireContext().getNavigationBarHeight()
|
||||||
|
statusBarHeight = requireContext().getStatusBarHeight()
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
currentWindow = savedInstanceState.getInt(STATE_RESUME_WINDOW)
|
currentWindow = savedInstanceState.getInt(STATE_RESUME_WINDOW)
|
||||||
playbackPosition = savedInstanceState.getLong(STATE_RESUME_POSITION)
|
playbackPosition = savedInstanceState.getLong(STATE_RESUME_POSITION)
|
||||||
|
@ -711,7 +742,7 @@ class PlayerFragment : Fragment() {
|
||||||
|
|
||||||
override fun onSingleClick() {
|
override fun onSingleClick() {
|
||||||
onClickChange()
|
onClickChange()
|
||||||
// activity?.hideSystemUI()
|
activity?.hideSystemUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMotionEvent(event: MotionEvent) {
|
override fun onMotionEvent(event: MotionEvent) {
|
||||||
|
@ -727,6 +758,14 @@ class PlayerFragment : Fragment() {
|
||||||
Listener()
|
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.visibility = if (playBackSpeedEnabled) VISIBLE else GONE
|
||||||
playback_speed_btt.setOnClickListener {
|
playback_speed_btt.setOnClickListener {
|
||||||
lateinit var dialog: AlertDialog
|
lateinit var dialog: AlertDialog
|
||||||
|
@ -799,6 +838,8 @@ class PlayerFragment : Fragment() {
|
||||||
skipOP()
|
skipOP()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changeSkip()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCurrentUrl(): ExtractorLink? {
|
private fun getCurrentUrl(): ExtractorLink? {
|
||||||
|
@ -844,6 +885,24 @@ class PlayerFragment : Fragment() {
|
||||||
|
|
||||||
private var isCurrentlySkippingEp = false
|
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() {
|
private fun skipToNextEpisode() {
|
||||||
if (isCurrentlySkippingEp) return
|
if (isCurrentlySkippingEp) return
|
||||||
isCurrentlySkippingEp = true
|
isCurrentlySkippingEp = true
|
||||||
|
@ -868,6 +927,7 @@ class PlayerFragment : Fragment() {
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
activity?.hideSystemUI()
|
||||||
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
|
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
|
||||||
thread {
|
thread {
|
||||||
initPlayer()
|
initPlayer()
|
||||||
|
@ -878,6 +938,8 @@ class PlayerFragment : Fragment() {
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
// releasePlayer()
|
// releasePlayer()
|
||||||
|
|
||||||
|
activity?.showSystemUI()
|
||||||
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER
|
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1084,11 +1146,12 @@ class PlayerFragment : Fragment() {
|
||||||
|
|
||||||
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
|
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
|
||||||
// updatePIPModeActions()
|
// updatePIPModeActions()
|
||||||
|
if(activity == null) return
|
||||||
if (playWhenReady) {
|
if (playWhenReady) {
|
||||||
when (playbackState) {
|
when (playbackState) {
|
||||||
Player.STATE_READY -> {
|
Player.STATE_READY -> {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
requireActivity().requestLocalAudioFocus(getFocusRequest())
|
activity?.requestLocalAudioFocus(getFocusRequest())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Player.STATE_ENDED -> {
|
Player.STATE_ENDED -> {
|
||||||
|
@ -1113,20 +1176,21 @@ class PlayerFragment : Fragment() {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
activity,
|
activity,
|
||||||
"Source error\n" + error.sourceException.message,
|
"Source error\n" + error.sourceException.message,
|
||||||
LENGTH_LONG
|
LENGTH_SHORT
|
||||||
)
|
)
|
||||||
.show()
|
.show()
|
||||||
|
tryNextMirror()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExoPlaybackException.TYPE_REMOTE -> {
|
ExoPlaybackException.TYPE_REMOTE -> {
|
||||||
Toast.makeText(activity, "Remote error", LENGTH_LONG)
|
Toast.makeText(activity, "Remote error", LENGTH_SHORT)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
ExoPlaybackException.TYPE_RENDERER -> {
|
ExoPlaybackException.TYPE_RENDERER -> {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
activity,
|
activity,
|
||||||
"Renderer error\n" + error.rendererException.message,
|
"Renderer error\n" + error.rendererException.message,
|
||||||
LENGTH_LONG
|
LENGTH_SHORT
|
||||||
)
|
)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
@ -1134,7 +1198,7 @@ class PlayerFragment : Fragment() {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
activity,
|
activity,
|
||||||
"Unexpected player error\n" + error.unexpectedException.message,
|
"Unexpected player error\n" + error.unexpectedException.message,
|
||||||
LENGTH_LONG
|
LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,6 @@ import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.APIHolder.getApiFromName
|
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
|
||||||
import kotlinx.android.synthetic.main.result_episode.view.*
|
import kotlinx.android.synthetic.main.result_episode.view.*
|
||||||
|
|
||||||
const val ACTION_PLAY_EPISODE = 1
|
const val ACTION_PLAY_EPISODE = 1
|
||||||
|
@ -50,20 +48,19 @@ class EpisodeAdapter(
|
||||||
class CardViewHolder
|
class CardViewHolder
|
||||||
constructor(
|
constructor(
|
||||||
itemView: View,
|
itemView: View,
|
||||||
_activity: Activity,
|
val activity: Activity,
|
||||||
resView: RecyclerView,
|
resView: RecyclerView,
|
||||||
clickCallback: (EpisodeClickEvent) -> Unit,
|
private val clickCallback: (EpisodeClickEvent) -> Unit,
|
||||||
) : RecyclerView.ViewHolder(itemView) {
|
) : RecyclerView.ViewHolder(itemView) {
|
||||||
val activity = _activity
|
private val episodeViewPrecentage: View = itemView.episode_view_procentage
|
||||||
val episode_view_procentage: View = itemView.episode_view_procentage
|
private val episodeViewPercentageOff: View = itemView.episode_view_procentage_off
|
||||||
val episode_view_procentage_off: View = itemView.episode_view_procentage_off
|
private val episodeText: TextView = itemView.episode_text
|
||||||
val episode_text: TextView = itemView.episode_text
|
val episodeExtra: ImageView = itemView.episode_extra
|
||||||
val episode_extra: ImageView = itemView.episode_extra
|
private val episodePlay: ImageView = itemView.episode_play
|
||||||
val episode_play: ImageView = itemView.episode_play
|
private val episodeHolder = itemView.episode_holder
|
||||||
val clickCallback = clickCallback
|
|
||||||
|
|
||||||
fun bind(card: ResultEpisode) {
|
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) {
|
fun setWidth(v: View, procentage: Float) {
|
||||||
val param = LinearLayout.LayoutParams(
|
val param = LinearLayout.LayoutParams(
|
||||||
|
@ -73,10 +70,10 @@ class EpisodeAdapter(
|
||||||
)
|
)
|
||||||
v.layoutParams = param
|
v.layoutParams = param
|
||||||
}
|
}
|
||||||
setWidth(episode_view_procentage, card.watchProgress)
|
setWidth(episodeViewPrecentage, card.watchProgress)
|
||||||
setWidth(episode_view_procentage_off, 1 - card.watchProgress)
|
setWidth(episodeViewPercentageOff, 1 - card.watchProgress)
|
||||||
|
|
||||||
episode_play.setOnClickListener {
|
episodeHolder.setOnClickListener {
|
||||||
clickCallback.invoke(EpisodeClickEvent(ACTION_PLAY_EPISODE, card))
|
clickCallback.invoke(EpisodeClickEvent(ACTION_PLAY_EPISODE, card))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,33 @@
|
||||||
package com.lagradost.cloudstream3.ui.result
|
package com.lagradost.cloudstream3.ui.result
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.annotation.SuppressLint
|
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.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.View.GONE
|
||||||
|
import android.view.View.VISIBLE
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
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.core.widget.NestedScrollView
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.mediarouter.app.MediaRouteButton
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.load.model.GlideUrl
|
import com.bumptech.glide.load.model.GlideUrl
|
||||||
import com.bumptech.glide.request.RequestOptions.bitmapTransform
|
import com.bumptech.glide.request.RequestOptions.bitmapTransform
|
||||||
import com.lagradost.cloudstream3.*
|
import com.google.android.gms.cast.framework.CastButtonFactory
|
||||||
import com.lagradost.cloudstream3.UIHelper.checkWrite
|
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.fixPaddingStatusbar
|
||||||
import com.lagradost.cloudstream3.UIHelper.loadResult
|
import com.lagradost.cloudstream3.UIHelper.isCastApiAvailable
|
||||||
import com.lagradost.cloudstream3.UIHelper.requestRW
|
|
||||||
import com.lagradost.cloudstream3.mvvm.Resource
|
import com.lagradost.cloudstream3.mvvm.Resource
|
||||||
import com.lagradost.cloudstream3.mvvm.observe
|
import com.lagradost.cloudstream3.mvvm.observe
|
||||||
import com.lagradost.cloudstream3.ui.player.PlayerData
|
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 com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import jp.wasabeef.glide.transformations.BlurTransformation
|
import jp.wasabeef.glide.transformations.BlurTransformation
|
||||||
import kotlinx.android.synthetic.main.fragment_result.*
|
import kotlinx.android.synthetic.main.fragment_result.*
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
|
const val MAX_SYNO_LENGH = 300
|
||||||
const val MAX_SYNO_LENGH = 600
|
|
||||||
|
|
||||||
data class ResultEpisode(
|
data class ResultEpisode(
|
||||||
val name: String?,
|
val name: String?,
|
||||||
|
@ -89,17 +85,34 @@ class ResultFragment : Fragment() {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
activity?.fixPaddingStatusbar(result_scroll)
|
activity?.fixPaddingStatusbar(result_scroll)
|
||||||
activity?.fixPaddingStatusbar(result_barstatus)
|
activity?.fixPaddingStatusbar(result_barstatus)
|
||||||
|
|
||||||
|
if (activity?.isCastApiAvailable() == true) {
|
||||||
|
val mMediaRouteButton = view.findViewById<MediaRouteButton>(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)
|
// activity?.fixPaddingStatusbar(result_toolbar)
|
||||||
|
|
||||||
val url = arguments?.getString("url")
|
val 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, _, oldScrollY ->
|
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.3f - scrollY / 1000f))
|
result_poster_blur.alpha = maxOf(0f, (0.7f - scrollY / 1000f))
|
||||||
result_barstatus.alpha = scrollY / 200f
|
result_poster_blur_holder.translationY = -scrollY.toFloat()
|
||||||
result_barstatus.visibility = if (scrollY > 0) View.VISIBLE else View.GONE
|
//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)
|
result_toolbar.setNavigationIcon(R.drawable.ic_baseline_arrow_back_24)
|
||||||
|
@ -159,6 +172,7 @@ class ResultFragment : Fragment() {
|
||||||
|
|
||||||
observe(viewModel.episodes) { episodes ->
|
observe(viewModel.episodes) { episodes ->
|
||||||
if (result_episodes == null || result_episodes.adapter == null) return@observe
|
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).cardList = episodes
|
||||||
(result_episodes.adapter as EpisodeAdapter).notifyDataSetChanged()
|
(result_episodes.adapter as EpisodeAdapter).notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
@ -180,15 +194,15 @@ class ResultFragment : Fragment() {
|
||||||
if (d.posterUrl != null) {
|
if (d.posterUrl != null) {
|
||||||
val glideUrl =
|
val glideUrl =
|
||||||
GlideUrl(d.posterUrl)
|
GlideUrl(d.posterUrl)
|
||||||
context!!.let {
|
requireContext().let {
|
||||||
/*
|
|
||||||
Glide.with(it)
|
|
||||||
.load(glideUrl)
|
|
||||||
.into(result_poster)*/
|
|
||||||
|
|
||||||
Glide.with(it)
|
Glide.with(it)
|
||||||
.load(glideUrl)
|
.load(glideUrl)
|
||||||
.apply(bitmapTransform(BlurTransformation(10, 3)))
|
.into(result_poster)
|
||||||
|
|
||||||
|
Glide.with(it)
|
||||||
|
.load(glideUrl)
|
||||||
|
.apply(bitmapTransform(BlurTransformation(80, 3)))
|
||||||
.into(result_poster_blur)
|
.into(result_poster_blur)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,14 +279,38 @@ activity?.startActivityForResult(vlcIntent, REQUEST_CODE)
|
||||||
result_descript.text = "No Plot found"
|
result_descript.text = "No Plot found"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result_tag.removeAllViews()
|
||||||
|
result_tag_holder.visibility = View.GONE
|
||||||
|
result_status.visibility = View.GONE
|
||||||
|
|
||||||
when (d) {
|
when (d) {
|
||||||
is AnimeLoadResponse -> {
|
is AnimeLoadResponse -> {
|
||||||
val preferEnglish = true
|
result_status.visibility = View.VISIBLE
|
||||||
val titleName = (if (preferEnglish) d.engName else d.japName) ?: d.name
|
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_title.text = titleName
|
||||||
result_toolbar.title = 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<MaterialButton>(R.id.result_tag_card)
|
||||||
|
btt.text = tag
|
||||||
|
|
||||||
|
result_tag.addView(viewBtt, index)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> result_title.text = d.name
|
else -> result_title.text = d.name
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,21 +24,18 @@ import kotlinx.android.synthetic.main.search_result_grid.view.*
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class SearchAdapter(
|
class SearchAdapter(
|
||||||
activity: Activity,
|
private var activity: Activity,
|
||||||
animeList: ArrayList<Any>,
|
var cardList: ArrayList<Any>,
|
||||||
resView: AutofitRecyclerView,
|
private val resView: AutofitRecyclerView,
|
||||||
) :
|
) :
|
||||||
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
var cardList = animeList
|
|
||||||
private var activity: Activity = activity
|
|
||||||
var resView: AutofitRecyclerView? = resView
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
val layout = activity.getGridFormatId()
|
val layout = activity.getGridFormatId()
|
||||||
return CardViewHolder(
|
return CardViewHolder(
|
||||||
LayoutInflater.from(parent.context).inflate(layout, parent, false),
|
LayoutInflater.from(parent.context).inflate(layout, parent, false),
|
||||||
activity,
|
activity,
|
||||||
resView!!
|
resView
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import com.lagradost.cloudstream3.APIHolder.getApiSettings
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
|
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
|
||||||
import com.lagradost.cloudstream3.UIHelper.getGridIsCompact
|
import com.lagradost.cloudstream3.UIHelper.getGridIsCompact
|
||||||
|
import com.lagradost.cloudstream3.UIHelper.loadResult
|
||||||
import com.lagradost.cloudstream3.mvvm.Resource
|
import com.lagradost.cloudstream3.mvvm.Resource
|
||||||
import com.lagradost.cloudstream3.mvvm.observe
|
import com.lagradost.cloudstream3.mvvm.observe
|
||||||
import com.lagradost.cloudstream3.ui.player.PlayerData
|
import com.lagradost.cloudstream3.ui.player.PlayerData
|
||||||
|
@ -41,11 +42,7 @@ class SearchFragment : Fragment() {
|
||||||
return inflater.inflate(R.layout.fragment_search, container, false)
|
return inflater.inflate(R.layout.fragment_search, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
private fun fixGrid() {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
|
|
||||||
activity?.fixPaddingStatusbar(searchRoot)
|
|
||||||
|
|
||||||
val compactView = activity?.getGridIsCompact() ?: false
|
val compactView = activity?.getGridIsCompact() ?: false
|
||||||
val spanCountLandscape = if (compactView) 2 else 6
|
val spanCountLandscape = if (compactView) 2 else 6
|
||||||
val spanCountPortrait = if (compactView) 1 else 3
|
val spanCountPortrait = if (compactView) 1 else 3
|
||||||
|
@ -56,6 +53,18 @@ class SearchFragment : Fragment() {
|
||||||
} else {
|
} else {
|
||||||
cardSpace.spanCount = spanCountPortrait
|
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<RecyclerView.ViewHolder>? = activity?.let {
|
val adapter: RecyclerView.Adapter<RecyclerView.ViewHolder>? = activity?.let {
|
||||||
SearchAdapter(
|
SearchAdapter(
|
||||||
|
@ -129,7 +138,7 @@ class SearchFragment : Fragment() {
|
||||||
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")
|
||||||
/*
|
/*
|
||||||
(requireActivity() as AppCompatActivity).supportFragmentManager.beginTransaction()
|
(requireActivity() as AppCompatActivity).supportFragmentManager.beginTransaction()
|
||||||
.setCustomAnimations(R.anim.enter_anim,
|
.setCustomAnimations(R.anim.enter_anim,
|
||||||
|
|
|
@ -11,7 +11,7 @@ import com.lagradost.cloudstream3.mvvm.safeApiCall
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class SearchViewModel : ViewModel() {
|
class SearchViewModel : ViewModel() {
|
||||||
val api: MainAPI = apis[0]
|
val api: MainAPI = apis[0] //TODO MULTI API
|
||||||
|
|
||||||
private val _searchResponse: MutableLiveData<Resource<ArrayList<Any>>> = MutableLiveData()
|
private val _searchResponse: MutableLiveData<Resource<ArrayList<Any>>> = MutableLiveData()
|
||||||
val searchResponse: LiveData<Resource<ArrayList<Any>>> get() = _searchResponse
|
val searchResponse: LiveData<Resource<ArrayList<Any>>> get() = _searchResponse
|
||||||
|
|
|
@ -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<SessionProvider> {
|
||||||
|
return Collections.emptyList()
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,17 +17,18 @@ class Vidstream {
|
||||||
// https://gogo-stream.com/streaming.php?id=MTE3NDg5
|
// https://gogo-stream.com/streaming.php?id=MTE3NDg5
|
||||||
fun getUrl(id: String, isCasting: Boolean = false, callback: (ExtractorLink) -> Unit) : Boolean {
|
fun getUrl(id: String, isCasting: Boolean = false, callback: (ExtractorLink) -> Unit) : Boolean {
|
||||||
try {
|
try {
|
||||||
|
normalApis.pmap { api ->
|
||||||
|
val url = api.getExtractorUrl(id)
|
||||||
|
val source = api.getUrl(url)
|
||||||
|
source?.forEach { callback.invoke(it) }
|
||||||
|
}
|
||||||
|
|
||||||
val url = getExtractorUrl(id)
|
val url = getExtractorUrl(id)
|
||||||
with(khttp.get(url)) {
|
with(khttp.get(url)) {
|
||||||
val document = Jsoup.parse(this.text)
|
val document = Jsoup.parse(this.text)
|
||||||
val primaryLinks = document.select("ul.list-server-items > li.linkserver")
|
val primaryLinks = document.select("ul.list-server-items > li.linkserver")
|
||||||
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
|
val extractedLinksList: MutableList<ExtractorLink> = 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
|
// All vidstream links passed to extractors
|
||||||
primaryLinks.forEach { element ->
|
primaryLinks.forEach { element ->
|
||||||
|
|
|
@ -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) {}
|
||||||
|
}
|
||||||
|
}
|
3
app/src/main/res/anim/.idea/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
6
app/src/main/res/anim/.idea/misc.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
8
app/src/main/res/anim/.idea/modules.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/anim.iml" filepath="$PROJECT_DIR$/.idea/anim.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
app/src/main/res/anim/.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/../../../../.." vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -1,31 +0,0 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:aapt="http://schemas.android.com/aapt"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportWidth="108"
|
|
||||||
android:viewportHeight="108">
|
|
||||||
<path
|
|
||||||
android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
|
||||||
<aapt:attr name="android:fillColor">
|
|
||||||
<gradient
|
|
||||||
android:startY="49.59793"
|
|
||||||
android:startX="42.9492"
|
|
||||||
android:endY="92.4963"
|
|
||||||
android:endX="85.84757"
|
|
||||||
android:type="linear">
|
|
||||||
<item
|
|
||||||
android:color="#44000000"
|
|
||||||
android:offset="0.0"/>
|
|
||||||
<item
|
|
||||||
android:color="#00000000"
|
|
||||||
android:offset="1.0"/>
|
|
||||||
</gradient>
|
|
||||||
</aapt:attr>
|
|
||||||
</path>
|
|
||||||
<path
|
|
||||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
|
||||||
android:fillColor="#FFFFFF"
|
|
||||||
android:fillType="nonZero"
|
|
||||||
android:strokeWidth="1"
|
|
||||||
android:strokeColor="#00000000"/>
|
|
||||||
</vector>
|
|
15
app/src/main/res/drawable/cs3_cloud.xml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:name="vector"
|
||||||
|
android:width="850dp"
|
||||||
|
android:height="850dp"
|
||||||
|
android:viewportWidth="850"
|
||||||
|
android:viewportHeight="850">
|
||||||
|
<group android:name="group_6">
|
||||||
|
<path
|
||||||
|
android:name="path_2"
|
||||||
|
android:pathData="M 698.92 450.33 C 697.92 440.99 690.27 432.74 679.92 430.25 L 653.67 430.75 C 655.17 407.75 636.67 386.63 618.79 384 C 611.804 381.871 604.367 381.698 597.29 383.5 C 597.91 379.77 602.74 347.16 578.79 322 C 558.72 300.92 532.54 299.13 517.67 299.31 L 500.37 298.92 C 494.76 293.4 460.65 262.47 412.62 266.67 C 382.23 269.32 354.96 277.67 334.79 302.67 C 333.11 304.74 327.6 311.81 321.17 320.81 C 318.82 323.81 316.91 327.43 314.79 330.5 C 314.63 330.74 288.79 326.44 272.79 331 C 247.52 338.2 224.79 358.54 217.29 385.5 C 215.44 392.18 209.08 415.09 219.79 435 C 222.101 439.202 223.081 444.009 222.6 448.78 C 219.48 450.41 205.02 450.94 182.29 450 C 164.43 449.27 149.83 463.6 149.79 480 C 149.74 497.17 165.23 510.58 184.29 510 C 205.93 510.23 605.96 510.67 637.04 510.56 C 650.12 510.56 656.79 499.17 656.79 499.17 C 661.24 493.35 661.09 486.09 661.04 481.5 L 661.04 477 L 664.79 477 L 675.96 476.33 C 690.35 474.78 700.21 462.36 698.92 450.33 Z M 407.54 456 L 407.54 349.25 L 483.75 402.63 Z"
|
||||||
|
android:fillColor="#ffffff"
|
||||||
|
android:strokeWidth="1"/>
|
||||||
|
</group>
|
||||||
|
</vector>
|
19
app/src/main/res/drawable/go_back_30.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:name="vector"
|
||||||
|
android:width="636dp"
|
||||||
|
android:height="714dp"
|
||||||
|
android:viewportWidth="636"
|
||||||
|
android:viewportHeight="714">
|
||||||
|
<path
|
||||||
|
android:name="path"
|
||||||
|
android:pathData="M 318.05 106.07 C 478.51 106.07 608.6 236.16 608.6 396.62 C 608.6 557.08 478.51 687.17 318.05 687.17 C 157.59 687.17 27.5 557.09 27.5 396.62 C 27.427 349.18 39.026 302.442 61.27 260.54 M 385.11 197.86 L 279.12 91.87 M 385.11 24.61 L 279.12 130.6 M 245.77 192.7 L 139.79 86.71 M 245.77 19.45 L 139.79 125.43"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeWidth="55"
|
||||||
|
android:strokeMiterLimit="10"/>
|
||||||
|
<path
|
||||||
|
android:name="path_1"
|
||||||
|
android:pathData="M 138.13 485.27 L 158.46 457.96 C 172.78 472.21 190.74 483.78 214.41 483.78 C 240.23 483.78 258.03 470.43 258.03 448.17 C 258.03 423.83 242.38 408.11 188.73 408.11 L 188.73 376.94 C 234.88 376.94 250.02 360.94 250.02 339.25 C 250.02 319.52 236.89 307.65 215.15 307.65 C 196.9 307.65 182.21 316.4 167.96 329.9 L 145.85 303.49 C 165.85 285.68 188.59 273.67 216.93 273.67 C 262.04 273.67 293.05 296.22 293.05 336.06 C 293.05 362.4 277.47 380.21 251.95 390.3 L 251.95 391.78 C 279.85 399.05 301.06 419.09 301.06 450.54 C 301.06 493.54 263.52 518.66 218.12 518.66 C 180.05 518.66 154.75 503.96 138.13 485.27 Z M 334.45 395.2 C 334.45 315.44 365.61 273.67 414.58 273.67 C 463.55 273.67 494.71 315.67 494.71 395.2 C 494.71 474.95 463.55 518.66 414.58 518.66 C 365.61 518.66 334.45 474.95 334.45 395.2 Z M 453.9 395.2 C 453.9 328.42 437.43 307.2 414.58 307.2 C 391.73 307.2 375.25 328.42 375.25 395.2 C 375.25 461.98 391.73 485.12 414.58 485.12 C 437.43 485.12 453.9 461.97 453.9 395.2 Z"
|
||||||
|
android:fillColor="#ffffff"
|
||||||
|
android:strokeWidth="1"/>
|
||||||
|
</vector>
|
19
app/src/main/res/drawable/go_forward_30.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:name="vector"
|
||||||
|
android:width="636dp"
|
||||||
|
android:height="714dp"
|
||||||
|
android:viewportWidth="636"
|
||||||
|
android:viewportHeight="714">
|
||||||
|
<path
|
||||||
|
android:name="path"
|
||||||
|
android:pathData="M 318.05 106.07 C 157.58 106.07 27.5 236.16 27.5 396.62 C 27.5 557.08 157.58 687.17 318.05 687.17 C 478.52 687.17 608.6 557.09 608.6 396.62 C 608.675 349.182 597.083 302.445 574.85 260.54 M 250.99 197.86 L 356.98 91.87 M 250.99 24.61 L 356.98 130.6 M 390.33 192.7 L 496.32 86.71 M 390.33 19.45 L 496.32 125.43"
|
||||||
|
android:strokeColor="#ffffff"
|
||||||
|
android:strokeWidth="55"
|
||||||
|
android:strokeMiterLimit="10"/>
|
||||||
|
<path
|
||||||
|
android:name="path_1"
|
||||||
|
android:pathData="M 138.13 485.27 L 158.46 457.96 C 172.78 472.21 190.74 483.78 214.41 483.78 C 240.23 483.78 258.03 470.43 258.03 448.17 C 258.03 423.83 242.38 408.11 188.73 408.11 L 188.73 376.94 C 234.88 376.94 250.02 360.94 250.02 339.25 C 250.02 319.52 236.89 307.65 215.15 307.65 C 196.9 307.65 182.21 316.4 167.96 329.9 L 145.85 303.49 C 165.85 285.68 188.59 273.67 216.93 273.67 C 262.04 273.67 293.05 296.22 293.05 336.06 C 293.05 362.4 277.47 380.21 251.95 390.3 L 251.95 391.78 C 279.85 399.05 301.06 419.09 301.06 450.54 C 301.06 493.54 263.52 518.66 218.12 518.66 C 180.05 518.66 154.75 503.96 138.13 485.27 Z M 334.45 395.2 C 334.45 315.44 365.61 273.67 414.58 273.67 C 463.55 273.67 494.71 315.67 494.71 395.2 C 494.71 474.95 463.55 518.66 414.58 518.66 C 365.61 518.66 334.45 474.95 334.45 395.2 Z M 453.9 395.2 C 453.9 328.42 437.43 307.2 414.58 307.2 C 391.73 307.2 375.25 328.42 375.25 395.2 C 375.25 461.98 391.73 485.12 414.58 485.12 C 437.43 485.12 453.9 461.97 453.9 395.2 Z"
|
||||||
|
android:fillColor="#ffffff"
|
||||||
|
android:strokeWidth="1"/>
|
||||||
|
</vector>
|
|
@ -1,5 +1,5 @@
|
||||||
<vector android:autoMirrored="true" android:height="24dp"
|
<vector android:autoMirrored="true" android:height="24dp"
|
||||||
android:tint="#FFFFFF" android:viewportHeight="24"
|
android:tint="?attr/white" android:viewportHeight="24"
|
||||||
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
|
<path android:fillColor="@android:color/white" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
<vector android:height="24dp" android:tint="?attr/white"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M19,12h-2v3h-3v2h5v-5zM7,9h3L10,7L5,7v5h2L7,9zM21,3L3,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,19.01L3,19.01L3,4.99h18v14.02z"/>
|
<path android:fillColor="@android:color/white" android:pathData="M19,12h-2v3h-3v2h5v-5zM7,9h3L10,7L5,7v5h2L7,9zM21,3L3,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,19.01L3,19.01L3,4.99h18v14.02z"/>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
<vector android:height="24dp" android:tint="?attr/white"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M17,3H7c-1.1,0 -1.99,0.9 -1.99,2L5,21l7,-3 7,3V5c0,-1.1 -0.9,-2 -2,-2z"/>
|
<path android:fillColor="@android:color/white" android:pathData="M17,3H7c-1.1,0 -1.99,0.9 -1.99,2L5,21l7,-3 7,3V5c0,-1.1 -0.9,-2 -2,-2z"/>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
<vector android:height="24dp" android:tint="?attr/white"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M20,8.69L20,4h-4.69L12,0.69 8.69,4L4,4v4.69L0.69,12 4,15.31L4,20h4.69L12,23.31 15.31,20L20,20v-4.69L23.31,12 20,8.69zM12,18c-3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6 6,2.69 6,6 -2.69,6 -6,6zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4z"/>
|
<path android:fillColor="@android:color/white" android:pathData="M20,8.69L20,4h-4.69L12,0.69 8.69,4L4,4v4.69L0.69,12 4,15.31L4,20h4.69L12,23.31 15.31,20L20,20v-4.69L23.31,12 20,8.69zM12,18c-3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6 6,2.69 6,6 -2.69,6 -6,6zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4z"/>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
<vector android:height="24dp" android:tint="?attr/white"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
|
<path android:fillColor="@android:color/white" android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
<vector android:height="24dp" android:tint="?attr/white"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M8,5v14l11,-7z"/>
|
<path android:fillColor="@android:color/white" android:pathData="M8,5v14l11,-7z"/>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<vector android:autoMirrored="true" android:height="24dp"
|
<vector android:autoMirrored="true" android:height="24dp"
|
||||||
android:tint="#FFFFFF" android:viewportHeight="24"
|
android:tint="?attr/white" android:viewportHeight="24"
|
||||||
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M3,10h11v2h-11z"/>
|
<path android:fillColor="@android:color/white" android:pathData="M3,10h11v2h-11z"/>
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M3,6h11v2h-11z"/>
|
<path android:fillColor="@android:color/white" android:pathData="M3,6h11v2h-11z"/>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
<vector android:height="24dp" android:tint="?attr/white"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M20.38,8.57l-1.23,1.85a8,8 0,0 1,-0.22 7.58L5.07,18A8,8 0,0 1,15.58 6.85l1.85,-1.23A10,10 0,0 0,3.35 19a2,2 0,0 0,1.72 1h13.85a2,2 0,0 0,1.74 -1,10 10,0 0,0 -0.27,-10.44zM10.59,15.41a2,2 0,0 0,2.83 0l5.66,-8.49 -8.49,5.66a2,2 0,0 0,0 2.83z"/>
|
<path android:fillColor="@android:color/white" android:pathData="M20.38,8.57l-1.23,1.85a8,8 0,0 1,-0.22 7.58L5.07,18A8,8 0,0 1,15.58 6.85l1.85,-1.23A10,10 0,0 0,3.35 19a2,2 0,0 0,1.72 1h13.85a2,2 0,0 0,1.74 -1,10 10,0 0,0 -0.27,-10.44zM10.59,15.41a2,2 0,0 0,2.83 0l5.66,-8.49 -8.49,5.66a2,2 0,0 0,0 2.83z"/>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
<vector android:height="24dp" android:tint="?attr/white"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/>
|
<path android:fillColor="@android:color/white" android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
<vector android:height="24dp" android:tint="?attr/white"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M20,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM4,12h4v2L4,14v-2zM14,18L4,18v-2h10v2zM20,18h-4v-2h4v2zM20,14L10,14v-2h10v2z"/>
|
<path android:fillColor="@android:color/white" android:pathData="M20,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM4,12h4v2L4,14v-2zM14,18L4,18v-2h10v2zM20,18h-4v-2h4v2zM20,14L10,14v-2h10v2z"/>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
<vector android:height="24dp" android:tint="?attr/white"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M3,17v2h6v-2L3,17zM3,5v2h10L13,5L3,5zM13,21v-2h8v-2h-8v-2h-2v6h2zM7,9v2L3,11v2h4v2h2L9,9L7,9zM21,13v-2L11,11v2h10zM15,9h2L17,7h4L21,5h-4L17,3h-2v6z"/>
|
<path android:fillColor="@android:color/white" android:pathData="M3,17v2h6v-2L3,17zM3,5v2h10L13,5L3,5zM13,21v-2h8v-2h-8v-2h-2v6h2zM7,9v2L3,11v2h4v2h2L9,9L7,9zM21,13v-2L11,11v2h10zM15,9h2L17,7h4L21,5h-4L17,3h-2v6z"/>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<vector android:autoMirrored="true" android:height="24dp"
|
<vector android:autoMirrored="true" android:height="24dp"
|
||||||
android:tint="#FFFFFF" android:viewportHeight="24"
|
android:tint="?attr/white" android:viewportHeight="24"
|
||||||
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M3,9v6h4l5,5L12,4L7,9L3,9zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,3.23v2.06c2.89,0.86 5,3.54 5,6.71s-2.11,5.85 -5,6.71v2.06c4.01,-0.91 7,-4.49 7,-8.77s-2.99,-7.86 -7,-8.77z"/>
|
<path android:fillColor="@android:color/white" android:pathData="M3,9v6h4l5,5L12,4L7,9L3,9zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,3.23v2.06c2.89,0.86 5,3.54 5,6.71s-2.11,5.85 -5,6.71v2.06c4.01,-0.91 7,-4.49 7,-8.77s-2.99,-7.86 -7,-8.77z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|
19
app/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108"
|
||||||
|
android:name="vector">
|
||||||
|
<group android:scaleX="0.08512941"
|
||||||
|
android:scaleY="0.08512941"
|
||||||
|
android:translateX="17.82"
|
||||||
|
android:translateY="17.82">
|
||||||
|
<group android:name="group_6">
|
||||||
|
<path
|
||||||
|
android:name="path_2"
|
||||||
|
android:pathData="M 698.92 450.33 C 697.92 440.99 690.27 432.74 679.92 430.25 L 653.67 430.75 C 655.17 407.75 636.67 386.63 618.79 384 C 611.804 381.871 604.367 381.698 597.29 383.5 C 597.91 379.77 602.74 347.16 578.79 322 C 558.72 300.92 532.54 299.13 517.67 299.31 L 500.37 298.92 C 494.76 293.4 460.65 262.47 412.62 266.67 C 382.23 269.32 354.96 277.67 334.79 302.67 C 333.11 304.74 327.6 311.81 321.17 320.81 C 318.82 323.81 316.91 327.43 314.79 330.5 C 314.63 330.74 288.79 326.44 272.79 331 C 247.52 338.2 224.79 358.54 217.29 385.5 C 215.44 392.18 209.08 415.09 219.79 435 C 222.101 439.202 223.081 444.009 222.6 448.78 C 219.48 450.41 205.02 450.94 182.29 450 C 164.43 449.27 149.83 463.6 149.79 480 C 149.74 497.17 165.23 510.58 184.29 510 C 205.93 510.23 605.96 510.67 637.04 510.56 C 650.12 510.56 656.79 499.17 656.79 499.17 C 661.24 493.35 661.09 486.09 661.04 481.5 L 661.04 477 L 664.79 477 L 675.96 476.33 C 690.35 474.78 700.21 462.36 698.92 450.33 Z M 407.54 456 L 407.54 349.25 L 483.75 402.63 Z"
|
||||||
|
android:fillColor="#ffffff"
|
||||||
|
android:strokeWidth="1"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
</vector>
|
|
@ -8,7 +8,7 @@
|
||||||
<path
|
<path
|
||||||
android:name="path_2"
|
android:name="path_2"
|
||||||
android:pathData="M 233.86 666.14 L 616.54 666.14 M 425.2 539.08 L 425.2 159.6 M 410.14 554.17 L 581.98 454.96 M 268.41 454.96 L 440.25 554.17"
|
android:pathData="M 233.86 666.14 L 616.54 666.14 M 425.2 539.08 L 425.2 159.6 M 410.14 554.17 L 581.98 454.96 M 268.41 454.96 L 440.25 554.17"
|
||||||
android:strokeColor="#ffffff"
|
android:strokeColor="?attr/white"
|
||||||
android:strokeWidth="60"
|
android:strokeWidth="60"
|
||||||
android:strokeMiterLimit="10"/>
|
android:strokeMiterLimit="10"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
@ -5,5 +5,5 @@
|
||||||
android:viewportHeight="850.4">
|
android:viewportHeight="850.4">
|
||||||
<path
|
<path
|
||||||
android:pathData="M674.6,424.6l-417.7,-241.2l0,482.4z"
|
android:pathData="M674.6,424.6l-417.7,-241.2l0,482.4z"
|
||||||
android:fillColor="#FFFFFF"/>
|
android:fillColor="?attr/white"/>
|
||||||
</vector>
|
</vector>
|
|
@ -8,13 +8,13 @@
|
||||||
<path
|
<path
|
||||||
android:name="path"
|
android:name="path"
|
||||||
android:pathData="M 425.2 172.91 C 363.2 172.91 303.676 197.566 259.836 241.406 C 215.996 285.246 191.34 344.77 191.34 406.77 C 191.34 468.77 215.996 528.294 259.836 572.134 C 303.676 615.974 363.2 640.63 425.2 640.63 C 487.2 640.63 546.724 615.974 590.564 572.134 C 634.404 528.294 659.06 468.77 659.06 406.77 C 659.06 344.77 634.404 285.246 590.564 241.406 C 546.724 197.566 487.2 172.91 425.2 172.91 Z"
|
android:pathData="M 425.2 172.91 C 363.2 172.91 303.676 197.566 259.836 241.406 C 215.996 285.246 191.34 344.77 191.34 406.77 C 191.34 468.77 215.996 528.294 259.836 572.134 C 303.676 615.974 363.2 640.63 425.2 640.63 C 487.2 640.63 546.724 615.974 590.564 572.134 C 634.404 528.294 659.06 468.77 659.06 406.77 C 659.06 344.77 634.404 285.246 590.564 241.406 C 546.724 197.566 487.2 172.91 425.2 172.91 Z"
|
||||||
android:strokeColor="#ffffff"
|
android:strokeColor="?attr/white"
|
||||||
android:strokeWidth="60"
|
android:strokeWidth="60"
|
||||||
android:strokeMiterLimit="10"/>
|
android:strokeMiterLimit="10"/>
|
||||||
<path
|
<path
|
||||||
android:name="path_1"
|
android:name="path_1"
|
||||||
android:pathData="M 599.86 562.28 L 719.87 682.29"
|
android:pathData="M 599.86 562.28 L 719.87 682.29"
|
||||||
android:strokeColor="#ffffff"
|
android:strokeColor="?attr/white"
|
||||||
android:strokeWidth="60"
|
android:strokeWidth="60"
|
||||||
android:strokeMiterLimit="10"/>
|
android:strokeMiterLimit="10"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
android:backgroundTint="@android:color/black"
|
android:backgroundTint="@android:color/black"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:layout_width="50dp"
|
android:layout_width="50dp"
|
||||||
android:layout_height="50dp"
|
android:layout_height="50dp"
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
>
|
>
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:visibility="gone"
|
||||||
android:id="@+id/result_barstatus"
|
android:id="@+id/result_barstatus"
|
||||||
android:background="@color/grayBackground"
|
android:background="@color/grayBackground"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -25,49 +26,84 @@
|
||||||
</com.google.android.material.appbar.MaterialToolbar>
|
</com.google.android.material.appbar.MaterialToolbar>
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<FrameLayout android:layout_width="match_parent" android:layout_height="200dp">
|
<FrameLayout android:layout_width="match_parent" android:id="@+id/result_poster_blur_holder"
|
||||||
|
android:layout_height="200dp">
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
android:alpha="0.3"
|
android:alpha="0.7"
|
||||||
tools:src="@drawable/example_poster"
|
tools:src="@drawable/example_poster"
|
||||||
android:background="@color/darkBackground"
|
android:background="@color/darkBackground"
|
||||||
android:id="@+id/result_poster_blur"
|
android:id="@+id/result_poster_blur"
|
||||||
android:contentDescription=""/>
|
android:contentDescription=""/>
|
||||||
<ImageView android:src="@drawable/background_shadow" android:layout_gravity="bottom"
|
<ImageView android:src="@drawable/background_shadow" android:layout_gravity="bottom"
|
||||||
android:layout_width="match_parent" android:layout_height="100dp">
|
android:layout_width="match_parent" android:layout_height="30dp">
|
||||||
|
|
||||||
</ImageView>
|
</ImageView>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
<androidx.core.widget.NestedScrollView android:id="@+id/result_scroll" android:layout_width="match_parent" android:layout_height="wrap_content">
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:id="@+id/result_scroll" android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_marginTop="100dp"
|
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
<GridLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content">
|
<!--
|
||||||
<LinearLayout android:gravity="center_vertical" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content">
|
<LinearLayout android:orientation="horizontal" android:layout_width="match_parent"
|
||||||
|
android:layout_height="30dp">
|
||||||
|
<ImageView android:id="@+id/result_back" android:src="@drawable/ic_baseline_arrow_back_24"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="match_parent">
|
||||||
|
|
||||||
|
</ImageView>
|
||||||
|
</LinearLayout>-->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
|
||||||
|
android:orientation="horizontal" android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/result_poster"
|
||||||
|
android:layout_width="100dp" android:layout_height="150dp"
|
||||||
|
tools:src="@drawable/example_poster"
|
||||||
|
android:contentDescription="@string/result_poster"/>
|
||||||
|
|
||||||
|
<LinearLayout android:layout_marginLeft="10dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
<TextView
|
<TextView
|
||||||
tools:text="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="15sp"
|
android:textSize="20sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:textColor="@color/textColor" android:layout_width="wrap_content"
|
android:textColor="?attr/textColor" android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
</TextView>
|
</TextView>
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/result_year"
|
android:id="@+id/result_year"
|
||||||
tools:text="2021"
|
tools:text="2021"
|
||||||
|
android:textStyle="bold"
|
||||||
android:textSize="15sp"
|
android:textSize="15sp"
|
||||||
android:textColor="@color/textColor" android:layout_width="wrap_content"
|
android:textColor="?attr/textColor" android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
</TextView>
|
</TextView>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/result_status"
|
||||||
|
tools:text="Finished"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:textColor="?attr/textColor" android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
</TextView>
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:visibility="gone"
|
||||||
android:layout_gravity="end"
|
android:layout_gravity="end"
|
||||||
app:cornerRadius="1000dp"
|
app:cornerRadius="1000dp"
|
||||||
android:id="@+id/result_bookmark_button"
|
android:id="@+id/result_bookmark_button"
|
||||||
|
@ -81,33 +117,60 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="45dp">
|
android:layout_height="45dp">
|
||||||
</com.google.android.material.button.MaterialButton>
|
</com.google.android.material.button.MaterialButton>
|
||||||
</GridLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.mediarouter.app.MediaRouteButton
|
||||||
|
android:id="@+id/media_route_button"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:mediaRouteTypes="user"
|
||||||
|
android:visibility="gone"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/result_plot"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:textStyle="normal"
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/result_tags"
|
|
||||||
android:layout_marginTop="10dp"
|
|
||||||
tools:text="Adventure | Fantasy World | Comedy | Ecchi | Action | Science Fiction | Fantasy"
|
|
||||||
android:gravity="center"
|
|
||||||
android:layout_width="match_parent" android:layout_height="wrap_content">
|
|
||||||
</TextView>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_marginTop="10dp"
|
|
||||||
android:id="@+id/result_descript"
|
android:id="@+id/result_descript"
|
||||||
tools:text="Ryan Quicksave Romano is an eccentric adventurer with a strange power: he can create a save-point in time and redo his life whenever he dies. Arriving in New Rome, the glitzy capital of sin of a rebuilding Europe, he finds the city torn between mega-corporations, sponsored heroes, superpowered criminals, and true monsters. It's a time of chaos, where potions can grant the power to rule the world and dangers lurk everywhere. "
|
tools:text="Ryan Quicksave Romano is an eccentric adventurer with a strange power: he can create a save-point in time and redo his life whenever he dies. Arriving in New Rome, the glitzy capital of sin of a rebuilding Europe, he finds the city torn between mega-corporations, sponsored heroes, superpowered criminals, and true monsters. It's a time of chaos, where potions can grant the power to rule the world and dangers lurk everywhere. "
|
||||||
android:layout_width="match_parent" android:layout_height="wrap_content">
|
android:layout_width="match_parent" android:layout_height="wrap_content">
|
||||||
|
|
||||||
</TextView>
|
</TextView>
|
||||||
<TextView
|
<TextView
|
||||||
android:textColor="@color/textColor"
|
android:id="@+id/result_tag_holder"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/result_tags"
|
||||||
|
android:textSize="17sp"
|
||||||
android:layout_marginTop="10dp"
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:textStyle="normal"
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
/>
|
||||||
|
<com.lagradost.cloudstream3.widget.FlowLayout android:id="@+id/result_tag"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
</com.lagradost.cloudstream3.widget.FlowLayout>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/result_episodes_text"
|
android:id="@+id/result_episodes_text"
|
||||||
tools:text="8 Episodes"
|
tools:text="8 Episodes"
|
||||||
android:gravity="start"
|
android:textSize="17sp"
|
||||||
android:layout_width="match_parent" android:layout_height="wrap_content">
|
android:layout_marginTop="10dp"
|
||||||
</TextView>
|
android:layout_marginBottom="10dp"
|
||||||
|
android:textStyle="normal"
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
/>
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
tools:listitem="@layout/result_episode"
|
tools:listitem="@layout/result_episode"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
android:layout_height="25dp"
|
android:layout_height="25dp"
|
||||||
android:layout_margin="10dp"
|
android:layout_margin="10dp"
|
||||||
android:layout_gravity="end|center_vertical"
|
android:layout_gravity="end|center_vertical"
|
||||||
app:tint="@color/textColor"
|
app:tint="?attr/textColor"
|
||||||
android:contentDescription="@string/change_providers_descript">
|
android:contentDescription="@string/change_providers_descript">
|
||||||
</ImageView>
|
</ImageView>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
|
@ -370,7 +370,7 @@
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:textStyle="normal"/>
|
android:textStyle="normal"/>
|
||||||
|
<!--app:buffered_color="@color/videoCache"-->
|
||||||
<com.google.android.exoplayer2.ui.DefaultTimeBar
|
<com.google.android.exoplayer2.ui.DefaultTimeBar
|
||||||
android:id="@id/exo_progress"
|
android:id="@id/exo_progress"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
@ -378,9 +378,10 @@
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
app:scrubber_enabled_size="24dp"
|
app:scrubber_enabled_size="24dp"
|
||||||
app:scrubber_dragged_size="26dp"
|
app:scrubber_dragged_size="26dp"
|
||||||
app:scrubber_color="@color/videoColorPrimary"
|
|
||||||
|
app:scrubber_color="?attr/colorPrimary"
|
||||||
app:bar_height="2dp"
|
app:bar_height="2dp"
|
||||||
app:played_color="@color/videoColorPrimary"
|
app:played_color="?attr/colorPrimary"
|
||||||
app:unplayed_color="@color/videoProgress"/>
|
app:unplayed_color="@color/videoProgress"/>
|
||||||
|
|
||||||
<!-- exo_duration-->
|
<!-- exo_duration-->
|
||||||
|
|
|
@ -6,8 +6,11 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
app:cardCornerRadius="@dimen/roundedImageRadius"
|
app:cardCornerRadius="@dimen/roundedImageRadius"
|
||||||
app:cardBackgroundColor="@color/itemBackground"
|
app:cardBackgroundColor="@color/transparent"
|
||||||
android:layout_marginBottom="2dp"
|
app:cardElevation="0dp"
|
||||||
|
android:id="@+id/episode_holder"
|
||||||
|
android:foreground="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
>
|
>
|
||||||
<!-- IDK BUT THIS DOES NOT SEAM LIKE A GOOD WAY OF DOING IT -->
|
<!-- IDK BUT THIS DOES NOT SEAM LIKE A GOOD WAY OF DOING IT -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -38,7 +41,6 @@
|
||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:id="@+id/episode_play"
|
android:id="@+id/episode_play"
|
||||||
android:background="?selectableItemBackgroundBorderless"
|
|
||||||
android:src="@drawable/ic_baseline_play_arrow_24"
|
android:src="@drawable/ic_baseline_play_arrow_24"
|
||||||
android:contentDescription="@string/episode_play_descript"/>
|
android:contentDescription="@string/episode_play_descript"/>
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -50,6 +52,7 @@
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
</TextView>
|
</TextView>
|
||||||
<ImageView
|
<ImageView
|
||||||
|
android:visibility="gone"
|
||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
android:id="@+id/episode_extra"
|
android:id="@+id/episode_extra"
|
||||||
|
|
28
app/src/main/res/layout/result_tag.xml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:paddingLeft="2dp" android:paddingRight="2dp"
|
||||||
|
android:paddingTop="-10dp"
|
||||||
|
android:layout_marginTop="-4dp"
|
||||||
|
android:layout_marginBottom="-4dp"
|
||||||
|
>
|
||||||
|
<!--app:strokeColor="@color/colorAccent"-->
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:minHeight="0dp"
|
||||||
|
android:minWidth="0dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textSize="13sp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
app:cornerRadius="100dp"
|
||||||
|
tools:text="Test"
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||||
|
android:id="@+id/result_tag_card">
|
||||||
|
|
||||||
|
</com.google.android.material.button.MaterialButton>
|
||||||
|
</FrameLayout>
|
|
@ -20,7 +20,7 @@
|
||||||
android:elevation="0dp"
|
android:elevation="0dp"
|
||||||
|
|
||||||
app:cardCornerRadius="@dimen/roundedImageRadius"
|
app:cardCornerRadius="@dimen/roundedImageRadius"
|
||||||
app:cardBackgroundColor="@color/itemBackground"
|
app:cardBackgroundColor="?attr/boxItemBackground"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
>
|
>
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textSize="17sp"
|
android:textSize="17sp"
|
||||||
android:textColor="@color/textColor"
|
android:textColor="?attr/textColor"
|
||||||
android:id="@+id/imageText"
|
android:id="@+id/imageText"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:maxLines="3"
|
android:maxLines="3"
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
tools:text="@string/no_data"
|
tools:text="@string/no_data"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="@color/lightGrayTextColor"
|
android:textColor="?attr/grayTextColor"
|
||||||
android:id="@+id/imageTextExtra"
|
android:id="@+id/imageTextExtra"
|
||||||
android:textSize="13sp"
|
android:textSize="13sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="@color/colorPrimary"
|
android:textColor="?attr/colorPrimary"
|
||||||
android:id="@+id/imageTextProvider"
|
android:id="@+id/imageTextProvider"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textSize="17sp"
|
android:textSize="17sp"
|
||||||
android:textColor="@color/textColor"
|
android:textColor="?attr/textColor"
|
||||||
android:id="@+id/imageText"
|
android:id="@+id/imageText"
|
||||||
android:textStyle="normal"
|
android:textStyle="normal"
|
||||||
android:maxLines="3"
|
android:maxLines="3"
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:textColor="@color/lightGrayTextColor"
|
android:textColor="?attr/grayTextColor"
|
||||||
android:id="@+id/imageTextExtra"
|
android:id="@+id/imageTextExtra"
|
||||||
android:textSize="13sp"
|
android:textSize="13sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="@color/colorPrimary"
|
android:textColor="?attr/colorPrimary"
|
||||||
android:id="@+id/imageTextProvider"
|
android:id="@+id/imageTextProvider"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
/>
|
/>
|
||||||
|
|
9
app/src/main/res/menu/cast_expanded_controller_menu.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" >
|
||||||
|
<item
|
||||||
|
android:id="@+id/media_route_menu_item"
|
||||||
|
app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
|
||||||
|
app:showAsAction="always"
|
||||||
|
android:title=""/>
|
||||||
|
</menu>
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@drawable/ic_launcher_background"/>
|
<background android:drawable="@color/ic_launcher_background"/>
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@drawable/ic_launcher_background"/>
|
<background android:drawable="@color/ic_launcher_background"/>
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 981 B |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 10 KiB |
22
app/src/main/res/values/attrs.xml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<declare-styleable name="FlowLayout_Layout"/>
|
||||||
|
<declare-styleable name="FlowLayout_Layout_layout_space"/>
|
||||||
|
<declare-styleable name="MainColors">
|
||||||
|
<attr name="colorPrimary" format="color"/>
|
||||||
|
<attr name="colorSearch" format="color"/>
|
||||||
|
<attr name="colorOngoing" format="color"/>
|
||||||
|
<attr name="colorPrimaryDark" format="color"/>
|
||||||
|
<attr name="colorItemSeen" format="color"/>
|
||||||
|
|
||||||
|
<attr name="darkBackground" format="color"/>
|
||||||
|
<attr name="bitDarkerGrayBackground" format="color"/>
|
||||||
|
<attr name="grayBackground" format="color"/>
|
||||||
|
<attr name="boxItemBackground" format="color"/>
|
||||||
|
|
||||||
|
<attr name="textColor" format="color"/>
|
||||||
|
<attr name="grayTextColor" format="color"/>
|
||||||
|
<attr name="iconColor" format="color"/>
|
||||||
|
<attr name="white" format="color"/>
|
||||||
|
</declare-styleable>
|
||||||
|
</resources>
|
|
@ -12,11 +12,11 @@
|
||||||
<color name="darkBackground">#2B2C30</color> <!--0f0f10 0E0E10 303135 2B2C30-->
|
<color name="darkBackground">#2B2C30</color> <!--0f0f10 0E0E10 303135 2B2C30-->
|
||||||
<color name="bitDarkerGrayBackground">#1C1C20</color> <!--191a1f 19181E 202125 1C1C20-->
|
<color name="bitDarkerGrayBackground">#1C1C20</color> <!--191a1f 19181E 202125 1C1C20-->
|
||||||
<color name="grayBackground">#1C1C20</color> <!--141419 202125-->
|
<color name="grayBackground">#1C1C20</color> <!--141419 202125-->
|
||||||
<color name="itemBackground">#131217</color> <!--1B1B20-->
|
<color name="itemBackground">#17171B</color> <!--1B1B20-->
|
||||||
|
|
||||||
<color name="textColor">#e9eaee</color> <!--FFF-->
|
<color name="textColor">#e9eaee</color> <!--FFF-->
|
||||||
<color name="grayTextColor">#9ba0a4</color> <!-- 5e5f62-->
|
<color name="grayTextColor">#9ba0a4</color> <!-- 5e5f62-->
|
||||||
<color name="lightGrayTextColor">#9f9fa0</color>
|
|
||||||
<color name="searchColor">@color/textColor</color> <!--DADADA-->
|
<color name="searchColor">@color/textColor</color> <!--DADADA-->
|
||||||
<color name="searchColorTransparent">#1AFFFFFF</color> <!--DADADA-->
|
<color name="searchColorTransparent">#1AFFFFFF</color> <!--DADADA-->
|
||||||
<color name="transparent">#00000000</color>
|
<color name="transparent">#00000000</color>
|
||||||
|
@ -33,6 +33,9 @@
|
||||||
<color name="black_overlay">#66000000</color>
|
<color name="black_overlay">#66000000</color>
|
||||||
<color name="darkBarTransparent">#C0121212</color>
|
<color name="darkBarTransparent">#C0121212</color>
|
||||||
<color name="darkBar">#121212</color>
|
<color name="darkBar">#121212</color>
|
||||||
<color name="videoProgress">#66B5B5B5</color>
|
<color name="videoProgress">#66B5B5B5</color> <!--66B5B5B5-->
|
||||||
<color name="videoColorPrimary">#617EFF</color>
|
<!--<color name="videoCache">#663D50FA</color>--> <!--66B5B5B5-->
|
||||||
|
<color name="videoColorPrimary">@color/colorPrimary</color> <!--0e09df 617EFF 3d50fa-->
|
||||||
|
|
||||||
|
<color name="iconColor">#9ba0a6</color>
|
||||||
</resources>
|
</resources>
|
4
app/src/main/res/values/ic_launcher_background.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="ic_launcher_background">#3242D3</color>
|
||||||
|
</resources>
|
|
@ -15,4 +15,7 @@
|
||||||
<string name="go_back">Go back</string>
|
<string name="go_back">Go back</string>
|
||||||
<string name="next_episode">Next episode</string>
|
<string name="next_episode">Next episode</string>
|
||||||
<string name="player_skip_button_text">10</string>
|
<string name="player_skip_button_text">10</string>
|
||||||
|
<string name="result_poster">Poster</string>
|
||||||
|
<string name="result_plot">Plot</string>
|
||||||
|
<string name="result_tags">Genres</string>
|
||||||
</resources>
|
</resources>
|
|
@ -27,6 +27,17 @@
|
||||||
<item name="bottomSheetDialogTheme">@style/AppBottomSheetDialogTheme</item>
|
<item name="bottomSheetDialogTheme">@style/AppBottomSheetDialogTheme</item>
|
||||||
<item name="searchViewStyle">@style/AppSearchViewStyle</item>
|
<item name="searchViewStyle">@style/AppSearchViewStyle</item>
|
||||||
<item name="tabStyle">@style/Theme.Widget.Tabs</item>
|
<item name="tabStyle">@style/Theme.Widget.Tabs</item>
|
||||||
|
|
||||||
|
<!-- DEF STYLE -->
|
||||||
|
<item name="textColor">@color/textColor</item>
|
||||||
|
<item name="colorItemSeen">@color/colorItemSeen</item>
|
||||||
|
<item name="grayTextColor">@color/grayTextColor</item>
|
||||||
|
<item name="darkBackground">@color/darkBackground</item>
|
||||||
|
<item name="bitDarkerGrayBackground">@color/bitDarkerGrayBackground</item>
|
||||||
|
<item name="grayBackground">@color/grayBackground</item>
|
||||||
|
<item name="boxItemBackground">@color/itemBackground</item>
|
||||||
|
<item name="iconColor">@color/iconColor</item>
|
||||||
|
<item name="white">#FFF</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="AppSearchViewStyle"
|
<style name="AppSearchViewStyle"
|
||||||
|
|