store data stuff

This commit is contained in:
LagradOst 2021-06-16 01:25:58 +02:00
parent 1e01abf929
commit 881ee223c2
17 changed files with 201 additions and 37 deletions

View file

@ -1,6 +1,7 @@
package com.lagradost.cloudstream3 package com.lagradost.cloudstream3
import android.Manifest import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.app.AppOpsManager import android.app.AppOpsManager
import android.content.Context import android.content.Context
@ -11,13 +12,19 @@ import android.media.AudioAttributes
import android.media.AudioFocusRequest import android.media.AudioFocusRequest
import android.media.AudioManager import android.media.AudioManager
import android.os.Build import android.os.Build
import android.view.Gravity
import android.view.MenuItem
import android.view.View import android.view.View
import android.view.WindowManager import android.view.WindowManager
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ContextThemeWrapper
import androidx.appcompat.view.menu.MenuBuilder
import androidx.appcompat.widget.PopupMenu
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.forEach
import androidx.fragment.app.FragmentActivity 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.cast.framework.CastContext
@ -112,12 +119,11 @@ object UIHelper {
) )
} }
} }
private var _AudioFocusRequest: AudioFocusRequest? = null private var _AudioFocusRequest: AudioFocusRequest? = null
private var _OnAudioFocusChangeListener: AudioManager.OnAudioFocusChangeListener? = null private var _OnAudioFocusChangeListener: AudioManager.OnAudioFocusChangeListener? = null
var onAudioFocusEvent = Event<Boolean>() var onAudioFocusEvent = Event<Boolean>()
fun getAudioListener(): AudioManager.OnAudioFocusChangeListener? { private fun getAudioListener(): AudioManager.OnAudioFocusChangeListener? {
if (_OnAudioFocusChangeListener != null) return _OnAudioFocusChangeListener if (_OnAudioFocusChangeListener != null) return _OnAudioFocusChangeListener
_OnAudioFocusChangeListener = AudioManager.OnAudioFocusChangeListener { _OnAudioFocusChangeListener = AudioManager.OnAudioFocusChangeListener {
onAudioFocusEvent.invoke( onAudioFocusEvent.invoke(
@ -302,4 +308,50 @@ object UIHelper {
val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0) inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
} }
@SuppressLint("RestrictedApi")
inline fun View.popupMenu(
items: List<Triple<Int, Int, Int>>,
noinline onMenuItemClick: MenuItem.() -> Unit,
): PopupMenu {
val ctw = ContextThemeWrapper(context, R.style.PopupMenu)
val popup = PopupMenu(ctw, this, Gravity.NO_GRAVITY, R.attr.actionOverflowMenuStyle, 0)
items.forEach { (id, icon, stringRes) ->
popup.menu.add(0, id, 0, stringRes).setIcon(icon)
}
(popup.menu as? MenuBuilder)?.setOptionalIconsVisible(true)
popup.setOnMenuItemClickListener {
it.onMenuItemClick()
true
}
popup.show()
return popup
}
inline fun View.popupMenuNoIcons(
items: List<Pair<Int, Int>>,
noinline onMenuItemClick: MenuItem.() -> Unit,
): PopupMenu {
val ctw = ContextThemeWrapper(context, R.style.PopupMenu)
val popup = PopupMenu(ctw, this, Gravity.NO_GRAVITY, R.attr.actionOverflowMenuStyle, 0)
items.forEach { (id, stringRes) ->
popup.menu.add(0, id, 0, stringRes)
}
(popup.menu as? MenuBuilder)?.setOptionalIconsVisible(true)
popup.setOnMenuItemClickListener {
it.onMenuItemClick()
true
}
popup.show()
return popup
}
} }

View file

@ -0,0 +1,19 @@
package com.lagradost.cloudstream3.ui
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import com.lagradost.cloudstream3.R
enum class WatchType(val internalId: Int, @StringRes val stringRes: Int, @DrawableRes val iconRes: Int) {
// FIX ICONS
WATCHING(0, R.string.type_watching, R.drawable.ic_baseline_remove_red_eye_24),
COMPLETED(1, R.string.type_completed, R.drawable.ic_baseline_check_24),
ONHOLD(2, R.string.type_on_hold, R.drawable.ic_baseline_pause_24),
DROPPED(3, R.string.type_dropped, R.drawable.ic_baseline_close_24),
PLANTOWATCH(4, R.string.type_plan_to_watch, R.drawable.ic_baseline_close_24),
NONE(5, R.string.type_none, R.drawable.ic_baseline_remove_red_eye_24);
companion object {
fun fromInternalId(id: Int?) = values().find { value -> value.internalId == id } ?: NONE
}
}

View file

@ -30,7 +30,6 @@ import android.widget.Toast
import android.widget.Toast.LENGTH_SHORT 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.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
@ -42,7 +41,6 @@ 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.C.TIME_UNSET
import com.google.android.exoplayer2.ext.cast.CastPlayer
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
@ -51,14 +49,9 @@ import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory
import com.google.android.exoplayer2.util.MimeTypes import com.google.android.exoplayer2.util.MimeTypes
import com.google.android.exoplayer2.util.Util import com.google.android.exoplayer2.util.Util
import com.google.android.gms.cast.MediaInfo
import com.google.android.gms.cast.MediaMetadata
import com.google.android.gms.cast.MediaQueueItem
import com.google.android.gms.cast.MediaStatus
import com.google.android.gms.cast.framework.CastButtonFactory import com.google.android.gms.cast.framework.CastButtonFactory
import com.google.android.gms.cast.framework.CastContext import com.google.android.gms.cast.framework.CastContext
import com.google.android.gms.cast.framework.CastState import com.google.android.gms.cast.framework.CastState
import com.google.android.gms.common.images.WebImage
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.MainActivity.Companion.isInPIPMode import com.lagradost.cloudstream3.MainActivity.Companion.isInPIPMode
import com.lagradost.cloudstream3.MainActivity.Companion.isInPlayer import com.lagradost.cloudstream3.MainActivity.Companion.isInPlayer
@ -81,20 +74,16 @@ import com.lagradost.cloudstream3.ui.result.ResultViewModel
import com.lagradost.cloudstream3.utils.CastHelper.startCast import com.lagradost.cloudstream3.utils.CastHelper.startCast
import com.lagradost.cloudstream3.utils.DataStore.getKey import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.setKey import com.lagradost.cloudstream3.utils.DataStore.setKey
import com.lagradost.cloudstream3.utils.DataStoreHelper import com.lagradost.cloudstream3.utils.DataStoreHelper.setViewPos
import com.lagradost.cloudstream3.utils.DataStoreHelper.saveViewPos
import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.getId import com.lagradost.cloudstream3.utils.getId
import kotlinx.android.synthetic.main.fragment_player.* import kotlinx.android.synthetic.main.fragment_player.*
import kotlinx.android.synthetic.main.player_custom_layout.* import kotlinx.android.synthetic.main.player_custom_layout.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import org.json.JSONArray
import org.json.JSONObject
import java.io.File import java.io.File
import javax.net.ssl.HttpsURLConnection import javax.net.ssl.HttpsURLConnection
import javax.net.ssl.SSLContext import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSession import javax.net.ssl.SSLSession
import kotlin.concurrent.thread
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.ceil import kotlin.math.ceil
import kotlin.properties.Delegates import kotlin.properties.Delegates
@ -562,7 +551,7 @@ class PlayerFragment : Fragment() {
private fun savePos() { private fun savePos() {
if (this::exoPlayer.isInitialized) { if (this::exoPlayer.isInitialized) {
if (exoPlayer.duration > 0 && exoPlayer.currentPosition > 0) { if (exoPlayer.duration > 0 && exoPlayer.currentPosition > 0) {
context?.saveViewPos(getEpisode()?.id, exoPlayer.currentPosition, exoPlayer.duration) context?.setViewPos(getEpisode()?.id, exoPlayer.currentPosition, exoPlayer.duration)
} }
} }
} }

View file

@ -28,8 +28,11 @@ import com.google.android.material.button.MaterialButton
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.UIHelper.isCastApiAvailable import com.lagradost.cloudstream3.UIHelper.isCastApiAvailable
import com.lagradost.cloudstream3.UIHelper.popupMenu
import com.lagradost.cloudstream3.UIHelper.popupMenuNoIcons
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.WatchType
import com.lagradost.cloudstream3.ui.player.PlayerData import com.lagradost.cloudstream3.ui.player.PlayerData
import com.lagradost.cloudstream3.ui.player.PlayerFragment import com.lagradost.cloudstream3.ui.player.PlayerFragment
import com.lagradost.cloudstream3.utils.CastHelper.startCast import com.lagradost.cloudstream3.utils.CastHelper.startCast
@ -184,10 +187,10 @@ class ResultFragment : Fragment() {
dialog.setOnDismissListener { dialog.setOnDismissListener {
currentLoadingCount++ currentLoadingCount++
} }
// Toast.makeText(activity, "Loading links", Toast.LENGTH_SHORT).show() // Toast.makeText(activity, "Loading links", Toast.LENGTH_SHORT).show()
viewModel.loadEpisode(episodeClick.data, true) { data -> viewModel.loadEpisode(episodeClick.data, true) { data ->
if(currentLoadingCount != currentLoad) return@loadEpisode if (currentLoadingCount != currentLoad) return@loadEpisode
dialog.dismiss() dialog.dismiss()
when (data) { when (data) {
is Resource.Failure -> { is Resource.Failure -> {
@ -238,6 +241,23 @@ class ResultFragment : Fragment() {
result_episodes.adapter = adapter result_episodes.adapter = adapter
result_episodes.layoutManager = GridLayoutManager(context, 1) result_episodes.layoutManager = GridLayoutManager(context, 1)
result_bookmark_button.setOnClickListener {
it.popupMenuNoIcons(
items = WatchType.values()
.map { watchType -> Pair(watchType.internalId, watchType.stringRes) },
//.map { watchType -> Triple(watchType.internalId, watchType.iconRes, watchType.stringRes) },
) {
context?.let { localContext ->
viewModel.updateWatchStatus(localContext, WatchType.fromInternalId(this.itemId))
}
}
}
observe(viewModel.watchStatus) {
//result_bookmark_button.setIconResource(it.iconRes)
result_bookmark_button.text = getString(it.stringRes)
}
observe(viewModel.allEpisodes) { observe(viewModel.allEpisodes) {
allEpisodes = it allEpisodes = it
} }

View file

@ -9,7 +9,10 @@ import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.APIHolder.getApiFromName import com.lagradost.cloudstream3.APIHolder.getApiFromName
import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.safeApiCall import com.lagradost.cloudstream3.mvvm.safeApiCall
import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.utils.DataStoreHelper.getResultWatchState
import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos import com.lagradost.cloudstream3.utils.DataStoreHelper.getViewPos
import com.lagradost.cloudstream3.utils.DataStoreHelper.setResultWatchState
import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorLink
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -20,6 +23,24 @@ class ResultViewModel : ViewModel() {
val episodes: LiveData<List<ResultEpisode>> get() = _episodes val episodes: LiveData<List<ResultEpisode>> get() = _episodes
private val dubStatus: MutableLiveData<DubStatus> = MutableLiveData() private val dubStatus: MutableLiveData<DubStatus> = MutableLiveData()
private val page: MutableLiveData<LoadResponse> = MutableLiveData()
private val id: MutableLiveData<Int> = MutableLiveData()
private val _watchStatus: MutableLiveData<WatchType> = MutableLiveData()
val watchStatus: LiveData<WatchType> get() = _watchStatus
fun updateWatchStatus(context: Context, status: WatchType) {
val currentId = id.value ?: return
_watchStatus.postValue(status)
context.setResultWatchState(currentId, status.internalId)
}
private fun loadWatchStatus(context: Context, localId: Int? = null) {
val currentId = localId ?: id.value ?: return
val currentWatch = context.getResultWatchState(currentId)
_watchStatus.postValue(currentWatch)
}
fun reloadEpisodes(context: Context) { fun reloadEpisodes(context: Context) {
val current = _episodes.value ?: return val current = _episodes.value ?: return
val copy = current.map { val copy = current.map {
@ -29,10 +50,16 @@ class ResultViewModel : ViewModel() {
_episodes.postValue(copy) _episodes.postValue(copy)
} }
// THIS SHOULD AT LEAST CLEAN IT UP, SO APIS CAN SWITCH DOMAIN
private fun getId(url: String, api: MainAPI): Int {
return url.replace(api.mainUrl, "").hashCode()
}
fun load(context: Context, url: String, apiName: String) = viewModelScope.launch { fun load(context: Context, url: String, apiName: String) = viewModelScope.launch {
_apiName.postValue(apiName) _apiName.postValue(apiName)
val api = getApiFromName(apiName)
val data = safeApiCall { val data = safeApiCall {
getApiFromName(apiName).load(url) api.load(url)
} }
_resultResponse.postValue(data) _resultResponse.postValue(data)
@ -40,6 +67,11 @@ class ResultViewModel : ViewModel() {
is Resource.Success -> { is Resource.Success -> {
val d = data.value val d = data.value
if (d is LoadResponse) { if (d is LoadResponse) {
page.postValue(d)
val mainId = getId(d.url, api)
id.postValue(mainId)
loadWatchStatus(context, mainId)
when (d) { when (d) {
is AnimeLoadResponse -> { is AnimeLoadResponse -> {
val isDub = d.dubEpisodes != null && d.dubEpisodes.size > 0 val isDub = d.dubEpisodes != null && d.dubEpisodes.size > 0
@ -57,14 +89,14 @@ class ResultViewModel : ViewModel() {
null, // TODO FIX SEASON null, // TODO FIX SEASON
i, i,
apiName, apiName,
(d.url + index).hashCode(), (mainId + index + 1),
index, index,
)) ))
} }
_episodes.postValue(episodes) _episodes.postValue(episodes)
} }
} }
is TvSeriesLoadResponse -> { is TvSeriesLoadResponse -> {
val episodes = ArrayList<ResultEpisode>() val episodes = ArrayList<ResultEpisode>()
for ((index, i) in d.episodes.withIndex()) { for ((index, i) in d.episodes.withIndex()) {
@ -75,7 +107,7 @@ class ResultViewModel : ViewModel() {
null, // TODO FIX SEASON null, // TODO FIX SEASON
i, i,
apiName, apiName,
(d.url + index).hashCode(), (mainId + index + 1).hashCode(),
index, index,
)) ))
} }
@ -88,7 +120,7 @@ class ResultViewModel : ViewModel() {
0, null, 0, null,
d.movieUrl, d.movieUrl,
d.apiName, d.apiName,
(d.url).hashCode(), (mainId + 1),
0, 0,
))) )))
} }

View file

@ -1,6 +1,5 @@
package com.lagradost.cloudstream3.utils package com.lagradost.cloudstream3.utils
import android.app.Activity
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.DeserializationFeature
@ -21,10 +20,8 @@ import com.lagradost.cloudstream3.ui.MetadataHolder
import com.lagradost.cloudstream3.ui.result.ResultEpisode import com.lagradost.cloudstream3.ui.result.ResultEpisode
import com.lagradost.cloudstream3.utils.Coroutines.main import com.lagradost.cloudstream3.utils.Coroutines.main
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.json.JSONObject import org.json.JSONObject
import kotlin.concurrent.thread
object CastHelper { object CastHelper {
private val mapper: JsonMapper = JsonMapper.builder().addModule(KotlinModule()) private val mapper: JsonMapper = JsonMapper.builder().addModule(KotlinModule())

View file

@ -1,22 +1,33 @@
package com.lagradost.cloudstream3.utils package com.lagradost.cloudstream3.utils
import android.content.Context import android.content.Context
import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.utils.DataStore.getKey import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.setKey import com.lagradost.cloudstream3.utils.DataStore.setKey
const val VIDEO_POS_DUR = "video_pos_dur" const val VIDEO_POS_DUR = "video_pos_dur"
const val RESULT_WATCH_STATE = "result_watch_state"
data class PosDur(val position: Long, val duration: Long) data class PosDur(val position: Long, val duration: Long)
object DataStoreHelper { object DataStoreHelper {
var currentAccount: String = "0" //TODO ACCOUNT IMPLEMENTATION var currentAccount: String = "0" //TODO ACCOUNT IMPLEMENTATION
fun Context.saveViewPos(id: Int?, pos: Long, dur: Long) { fun Context.setViewPos(id: Int?, pos: Long, dur: Long) {
if(id == null) return if (id == null) return
setKey("$currentAccount/$VIDEO_POS_DUR", id.toString(), PosDur(pos, dur)) setKey("$currentAccount/$VIDEO_POS_DUR", id.toString(), PosDur(pos, dur))
} }
fun Context.getViewPos(id: Int): PosDur? { fun Context.getViewPos(id: Int): PosDur? {
return getKey<PosDur>("$currentAccount/$VIDEO_POS_DUR", id.toString(), null) return getKey("$currentAccount/$VIDEO_POS_DUR", id.toString(), null)
}
fun Context.setResultWatchState(id: Int?, status: Int) {
if (id == null) return
setKey("$currentAccount/$RESULT_WATCH_STATE", id.toString(), status)
}
fun Context.getResultWatchState(id: Int): WatchType {
return WatchType.fromInternalId(getKey<Int>("$currentAccount/$RESULT_WATCH_STATE", id.toString(), null))
} }
} }

View file

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,7c2.76,0 5,2.24 5,5 0,0.65 -0.13,1.26 -0.36,1.83l2.92,2.92c1.51,-1.26 2.7,-2.89 3.43,-4.75 -1.73,-4.39 -6,-7.5 -11,-7.5 -1.4,0 -2.74,0.25 -3.98,0.7l2.16,2.16C10.74,7.13 11.35,7 12,7zM2,4.27l2.28,2.28 0.46,0.46C3.08,8.3 1.78,10.02 1,12c1.73,4.39 6,7.5 11,7.5 1.55,0 3.03,-0.3 4.38,-0.84l0.42,0.42L19.73,22 21,20.73 3.27,3 2,4.27zM7.53,9.8l1.55,1.55c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.66 1.34,3 3,3 0.22,0 0.44,-0.03 0.65,-0.08l1.55,1.55c-0.67,0.33 -1.41,0.53 -2.2,0.53 -2.76,0 -5,-2.24 -5,-5 0,-0.79 0.2,-1.53 0.53,-2.2zM11.84,9.02l3.15,3.15 0.02,-0.16c0,-1.66 -1.34,-3 -3,-3l-0.17,0.01z"/>
</vector>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?attr/bitDarkerGrayBackground"/>
<stroke android:width="@dimen/mtrl_btn_stroke_size" android:color="@color/mtrl_btn_stroke_color_selector"/>
</shape>

View file

@ -61,14 +61,22 @@
</LinearLayout>--> </LinearLayout>-->
<LinearLayout <LinearLayout
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:orientation="horizontal" android:layout_width="match_parent" android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<ImageView
android:id="@+id/result_poster" <androidx.cardview.widget.CardView
android:layout_width="100dp" android:layout_height="150dp" app:cardCornerRadius="@dimen/roundedImageRadius"
tools:src="@drawable/example_poster" android:layout_width="100dp"
android:contentDescription="@string/result_poster"/> android:layout_height="140dp">
<ImageView
android:id="@+id/result_poster"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:src="@drawable/example_poster"
android:contentDescription="@string/result_poster"/>
</androidx.cardview.widget.CardView>
<LinearLayout android:layout_marginLeft="10dp" <LinearLayout android:layout_marginLeft="10dp"
android:gravity="center_vertical" android:gravity="center_vertical"

View file

@ -23,7 +23,7 @@
android:id="@+id/backgroundCard" android:id="@+id/backgroundCard"
app:cardBackgroundColor="@color/darkBackground" app:cardBackgroundColor="@color/darkBackground"
> >
<!-- USING CROP RATIO (182/268), centerCrop for fill -->
<ImageView <ImageView
android:duplicateParentState="true" android:duplicateParentState="true"
android:id="@+id/imageView" android:id="@+id/imageView"

View file

@ -2,7 +2,7 @@
<!-- Default screen margins, per the Android Design guidelines. --> <!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen> <dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen> <dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="roundedImageRadius">4dp</dimen> <dimen name="roundedImageRadius">1dp</dimen>
<dimen name="navbarHeight">0dp</dimen> <dimen name="navbarHeight">0dp</dimen>
<dimen name="card_corner_radius">2dp</dimen> <dimen name="card_corner_radius">2dp</dimen>
</resources> </resources>

View file

@ -22,5 +22,12 @@
<string name="result_share">Share</string> <string name="result_share">Share</string>
<string name="result_open_in_browser">Open In Browser</string> <string name="result_open_in_browser">Open In Browser</string>
<string name="skip_loading">Skip Loading</string> <string name="skip_loading">Skip Loading</string>
<string name="loading_chromecast">Loading...</string> <string name="loading_chromecast">Loading…</string>
<string name="type_watching">Watching</string>
<string name="type_on_hold">On-Hold</string>
<string name="type_completed">Completed</string>
<string name="type_dropped">Dropped</string>
<string name="type_plan_to_watch">Plan to Watch</string>
<string name="type_none">None</string>
</resources> </resources>

View file

@ -32,6 +32,7 @@
@style/CustomCastExpandedController @style/CustomCastExpandedController
</item> </item>
<item name="castMiniControllerStyle">@style/CustomCastMiniController</item> <item name="castMiniControllerStyle">@style/CustomCastMiniController</item>
<!--<item name="mediaRouteButtonTint">?attr/colorPrimary</item>-->
<!-- DEF STYLE --> <!-- DEF STYLE -->
<item name="textColor">@color/textColor</item> <item name="textColor">@color/textColor</item>
@ -118,6 +119,9 @@
<item name="android:windowBackground">@color/transparent</item> <item name="android:windowBackground">@color/transparent</item>
</style> </style>
<style name="PopupMenu" parent="@android:style/Widget.PopupMenu">
<item name="android:backgroundTint">?attr/bitDarkerGrayBackground</item>
</style>
<!-- CHROMECAST --> <!-- CHROMECAST -->
<style name="CustomCastExpandedController" parent="CastExpandedController"> <style name="CustomCastExpandedController" parent="CastExpandedController">