mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
added local accounts
This commit is contained in:
parent
b06f098447
commit
180987e2d0
17 changed files with 693 additions and 29 deletions
|
@ -148,6 +148,14 @@ class AcraApplication : Application() {
|
||||||
_context = WeakReference(value)
|
_context = WeakReference(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T : Any> getKeyClass(path: String, valueType: Class<T>): T? {
|
||||||
|
return context?.getKey(path, valueType)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : Any> setKeyClass(path: String, value: T) {
|
||||||
|
context?.setKey(path, value)
|
||||||
|
}
|
||||||
|
|
||||||
fun removeKeys(folder: String): Int? {
|
fun removeKeys(folder: String): Int? {
|
||||||
return context?.removeKeys(folder)
|
return context?.removeKeys(folder)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
package com.lagradost.cloudstream3.ui
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.viewbinding.ViewBinding
|
||||||
|
import com.lagradost.cloudstream3.databinding.WhoIsWatchingAccountAddBinding
|
||||||
|
import com.lagradost.cloudstream3.databinding.WhoIsWatchingAccountBinding
|
||||||
|
import com.lagradost.cloudstream3.ui.result.setImage
|
||||||
|
import com.lagradost.cloudstream3.utils.DataStoreHelper
|
||||||
|
|
||||||
|
class WhoIsWatchingAdapter(
|
||||||
|
private val selectCallBack: (DataStoreHelper.Account) -> Unit = { },
|
||||||
|
private val editCallBack: (DataStoreHelper.Account) -> Unit = { },
|
||||||
|
private val addAccountCallback: () -> Unit = {}
|
||||||
|
) :
|
||||||
|
ListAdapter<DataStoreHelper.Account, WhoIsWatchingAdapter.WhoIsWatchingHolder>(DiffCallback()) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val FOOTER = 1
|
||||||
|
const val NORMAL = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return currentList.size + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemViewType(position: Int): Int = when (position) {
|
||||||
|
currentList.size -> FOOTER
|
||||||
|
else -> NORMAL
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WhoIsWatchingHolder =
|
||||||
|
WhoIsWatchingHolder(
|
||||||
|
binding = when (viewType) {
|
||||||
|
NORMAL -> WhoIsWatchingAccountBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
FOOTER -> WhoIsWatchingAccountAddBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
else -> throw NotImplementedError()
|
||||||
|
},
|
||||||
|
selectCallBack = selectCallBack,
|
||||||
|
addAccountCallback = addAccountCallback,
|
||||||
|
editCallBack = editCallBack,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: WhoIsWatchingHolder, position: Int) =
|
||||||
|
holder.bind(currentList.getOrNull(position))
|
||||||
|
|
||||||
|
class WhoIsWatchingHolder(
|
||||||
|
val binding: ViewBinding,
|
||||||
|
val selectCallBack: (DataStoreHelper.Account) -> Unit,
|
||||||
|
val addAccountCallback: () -> Unit,
|
||||||
|
val editCallBack: (DataStoreHelper.Account) -> Unit
|
||||||
|
) :
|
||||||
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
|
fun bind(card: DataStoreHelper.Account?) {
|
||||||
|
when (binding) {
|
||||||
|
is WhoIsWatchingAccountBinding -> binding.apply {
|
||||||
|
if(card == null) return@apply
|
||||||
|
outline.isVisible = card.keyIndex == DataStoreHelper.selectedKeyIndex
|
||||||
|
profileText.text = card.name
|
||||||
|
profileImageBackground.setImage(card.image)
|
||||||
|
root.setOnClickListener {
|
||||||
|
selectCallBack(card)
|
||||||
|
}
|
||||||
|
root.setOnLongClickListener {
|
||||||
|
editCallBack(card)
|
||||||
|
return@setOnLongClickListener true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is WhoIsWatchingAccountAddBinding -> binding.apply {
|
||||||
|
root.setOnClickListener {
|
||||||
|
addAccountCallback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DiffCallback : DiffUtil.ItemCallback<DataStoreHelper.Account>() {
|
||||||
|
override fun areItemsTheSame(
|
||||||
|
oldItem: DataStoreHelper.Account,
|
||||||
|
newItem: DataStoreHelper.Account
|
||||||
|
): Boolean = oldItem.keyIndex == newItem.keyIndex
|
||||||
|
|
||||||
|
override fun areContentsTheSame(
|
||||||
|
oldItem: DataStoreHelper.Account,
|
||||||
|
newItem: DataStoreHelper.Account
|
||||||
|
): Boolean = oldItem == newItem
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,6 +40,7 @@ import com.lagradost.cloudstream3.utils.DataStoreHelper
|
||||||
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
|
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
|
||||||
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showOptionSelectStringRes
|
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showOptionSelectStringRes
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
|
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
|
||||||
|
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbarMargin
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbarView
|
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbarView
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.setImage
|
import com.lagradost.cloudstream3.utils.UIHelper.setImage
|
||||||
|
|
||||||
|
@ -250,6 +251,11 @@ class HomeParentItemAdapterPreview(
|
||||||
private var bookmarkRecyclerView: RecyclerView =
|
private var bookmarkRecyclerView: RecyclerView =
|
||||||
itemView.findViewById(R.id.home_bookmarked_child_recyclerview)
|
itemView.findViewById(R.id.home_bookmarked_child_recyclerview)
|
||||||
|
|
||||||
|
private var homeAccount: View? =
|
||||||
|
itemView.findViewById(R.id.home_switch_account)
|
||||||
|
|
||||||
|
private var topPadding : View? = itemView.findViewById(R.id.home_padding)
|
||||||
|
|
||||||
private val homeNonePadding: View = itemView.findViewById(R.id.home_none_padding)
|
private val homeNonePadding: View = itemView.findViewById(R.id.home_none_padding)
|
||||||
|
|
||||||
private val previewCallback: ViewPager2.OnPageChangeCallback =
|
private val previewCallback: ViewPager2.OnPageChangeCallback =
|
||||||
|
@ -432,6 +438,8 @@ class HomeParentItemAdapterPreview(
|
||||||
resumeRecyclerView.setLinearListLayout()
|
resumeRecyclerView.setLinearListLayout()
|
||||||
bookmarkRecyclerView.setLinearListLayout()
|
bookmarkRecyclerView.setLinearListLayout()
|
||||||
|
|
||||||
|
fixPaddingStatusbarMargin(topPadding)
|
||||||
|
|
||||||
for ((chip, watch) in toggleList) {
|
for ((chip, watch) in toggleList) {
|
||||||
chip.isChecked = false
|
chip.isChecked = false
|
||||||
chip.setOnCheckedChangeListener { _, isChecked ->
|
chip.setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
@ -445,6 +453,10 @@ class HomeParentItemAdapterPreview(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
homeAccount?.setOnClickListener { v ->
|
||||||
|
DataStoreHelper.showWhoIsWatching(v?.context ?: return@setOnClickListener)
|
||||||
|
}
|
||||||
|
|
||||||
(binding as? FragmentHomeHeadTvBinding)?.apply {
|
(binding as? FragmentHomeHeadTvBinding)?.apply {
|
||||||
homePreviewChangeApi.setOnClickListener { view ->
|
homePreviewChangeApi.setOnClickListener { view ->
|
||||||
view.context.selectHomepage(viewModel.repo?.name) { api ->
|
view.context.selectHomepage(viewModel.repo?.name) { api ->
|
||||||
|
@ -485,8 +497,6 @@ class HomeParentItemAdapterPreview(
|
||||||
}
|
}
|
||||||
|
|
||||||
(binding as? FragmentHomeHeadBinding)?.apply {
|
(binding as? FragmentHomeHeadBinding)?.apply {
|
||||||
fixPaddingStatusbar(binding.homeSearch)
|
|
||||||
|
|
||||||
homeSearch.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
homeSearch.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||||
override fun onQueryTextSubmit(query: String): Boolean {
|
override fun onQueryTextSubmit(query: String): Boolean {
|
||||||
viewModel.queryTextSubmit(query)
|
viewModel.queryTextSubmit(query)
|
||||||
|
|
|
@ -96,8 +96,8 @@ open class FullScreenPlayer : AbstractPlayerFragment() {
|
||||||
// protected var currentPrefQuality =
|
// protected var currentPrefQuality =
|
||||||
// Qualities.P2160.value // preferred maximum quality, used for ppl w bad internet or on cell
|
// Qualities.P2160.value // preferred maximum quality, used for ppl w bad internet or on cell
|
||||||
protected var fastForwardTime = 10000L
|
protected var fastForwardTime = 10000L
|
||||||
protected var androidTVInterfaceOffSeekTime = 10000L;
|
protected var androidTVInterfaceOffSeekTime = 10000L
|
||||||
protected var androidTVInterfaceOnSeekTime = 30000L;
|
protected var androidTVInterfaceOnSeekTime = 30000L
|
||||||
protected var swipeHorizontalEnabled = false
|
protected var swipeHorizontalEnabled = false
|
||||||
protected var swipeVerticalEnabled = false
|
protected var swipeVerticalEnabled = false
|
||||||
protected var playBackSpeedEnabled = false
|
protected var playBackSpeedEnabled = false
|
||||||
|
|
|
@ -1252,7 +1252,6 @@ class GeneratorPlayer : FullScreenPlayer() {
|
||||||
private fun displayTimeStamp(show: Boolean) {
|
private fun displayTimeStamp(show: Boolean) {
|
||||||
if (timestampShowState == show) return
|
if (timestampShowState == show) return
|
||||||
skipIndex++
|
skipIndex++
|
||||||
println("displayTimeStamp = $show")
|
|
||||||
timestampShowState = show
|
timestampShowState = show
|
||||||
playerBinding?.skipChapterButton?.apply {
|
playerBinding?.skipChapterButton?.apply {
|
||||||
val showWidth = 170.toPx
|
val showWidth = 170.toPx
|
||||||
|
@ -1294,7 +1293,6 @@ class GeneratorPlayer : FullScreenPlayer() {
|
||||||
|
|
||||||
override fun onTimestamp(timestamp: EpisodeSkip.SkipStamp?) {
|
override fun onTimestamp(timestamp: EpisodeSkip.SkipStamp?) {
|
||||||
if (timestamp != null) {
|
if (timestamp != null) {
|
||||||
println("timestamp: $timestamp")
|
|
||||||
playerBinding?.skipChapterButton?.setText(timestamp.uiText)
|
playerBinding?.skipChapterButton?.setText(timestamp.uiText)
|
||||||
displayTimeStamp(true)
|
displayTimeStamp(true)
|
||||||
val currentIndex = skipIndex
|
val currentIndex = skipIndex
|
||||||
|
|
|
@ -6,7 +6,12 @@ import androidx.preference.PreferenceManager
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
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.lagradost.cloudstream3.AcraApplication.Companion.getKeyClass
|
||||||
|
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
|
||||||
|
import com.lagradost.cloudstream3.AcraApplication.Companion.setKeyClass
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
const val DOWNLOAD_HEADER_CACHE = "download_header_cache"
|
const val DOWNLOAD_HEADER_CACHE = "download_header_cache"
|
||||||
|
|
||||||
|
@ -20,6 +25,31 @@ const val PREFERENCES_NAME = "rebuild_preference"
|
||||||
|
|
||||||
// TODO degelgate by value for get & set
|
// TODO degelgate by value for get & set
|
||||||
|
|
||||||
|
class PreferenceDelegate<T : Any>(
|
||||||
|
val key: String, val default: T //, private val klass: KClass<T>
|
||||||
|
) {
|
||||||
|
private val klass: KClass<out T> = default::class
|
||||||
|
// simple cache to make it not get the key every time it is accessed, however this requires
|
||||||
|
// that ONLY this changes the key
|
||||||
|
private var cache: T? = null
|
||||||
|
|
||||||
|
operator fun getValue(self: Any?, property: KProperty<*>) =
|
||||||
|
cache ?: getKeyClass(key, klass.java).also { newCache -> cache = newCache } ?: default
|
||||||
|
|
||||||
|
operator fun setValue(
|
||||||
|
self: Any?,
|
||||||
|
property: KProperty<*>,
|
||||||
|
t: T?
|
||||||
|
) {
|
||||||
|
cache = t
|
||||||
|
if (t == null) {
|
||||||
|
removeKey(key)
|
||||||
|
} else {
|
||||||
|
setKeyClass(key, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object DataStore {
|
object DataStore {
|
||||||
val mapper: JsonMapper = JsonMapper.builder().addModule(KotlinModule())
|
val mapper: JsonMapper = JsonMapper.builder().addModule(KotlinModule())
|
||||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build()
|
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build()
|
||||||
|
@ -89,7 +119,7 @@ object DataStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.removeKeys(folder: String): Int {
|
fun Context.removeKeys(folder: String): Int {
|
||||||
val keys = getKeys(folder)
|
val keys = getKeys("$folder/")
|
||||||
keys.forEach { value ->
|
keys.forEach { value ->
|
||||||
removeKey(value)
|
removeKey(value)
|
||||||
}
|
}
|
||||||
|
@ -106,6 +136,15 @@ object DataStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T> Context.getKey(path: String, valueType: Class<T>): T? {
|
||||||
|
try {
|
||||||
|
val json: String = getSharedPrefs().getString(path, null) ?: return null
|
||||||
|
return json.toKotlinObject(valueType)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun <T> Context.setKey(folder: String, path: String, value: T) {
|
fun <T> Context.setKey(folder: String, path: String, value: T) {
|
||||||
setKey(getFolderName(folder, path), value)
|
setKey(getFolderName(folder, path), value)
|
||||||
}
|
}
|
||||||
|
@ -114,6 +153,10 @@ object DataStore {
|
||||||
return mapper.readValue(this, T::class.java)
|
return mapper.readValue(this, T::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T> String.toKotlinObject(valueType: Class<T>): T {
|
||||||
|
return mapper.readValue(this, valueType)
|
||||||
|
}
|
||||||
|
|
||||||
// GET KEY GIVEN PATH AND DEFAULT VALUE, NULL IF ERROR
|
// GET KEY GIVEN PATH AND DEFAULT VALUE, NULL IF ERROR
|
||||||
inline fun <reified T : Any> Context.getKey(path: String, defVal: T?): T? {
|
inline fun <reified T : Any> Context.getKey(path: String, defVal: T?): T? {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
package com.lagradost.cloudstream3.utils
|
package com.lagradost.cloudstream3.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.text.Editable
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.core.view.isGone
|
||||||
|
import androidx.core.widget.doOnTextChanged
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.APIHolder.unixTimeMS
|
import com.lagradost.cloudstream3.APIHolder.unixTimeMS
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||||
|
@ -8,10 +16,20 @@ import com.lagradost.cloudstream3.AcraApplication.Companion.getKeys
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKeys
|
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKeys
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
||||||
|
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||||
|
import com.lagradost.cloudstream3.databinding.WhoIsWatchingAccountEditBinding
|
||||||
|
import com.lagradost.cloudstream3.databinding.WhoIsWatchingBinding
|
||||||
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
import com.lagradost.cloudstream3.syncproviders.AccountManager
|
import com.lagradost.cloudstream3.syncproviders.AccountManager
|
||||||
import com.lagradost.cloudstream3.syncproviders.SyncAPI
|
import com.lagradost.cloudstream3.syncproviders.SyncAPI
|
||||||
import com.lagradost.cloudstream3.ui.WatchType
|
import com.lagradost.cloudstream3.ui.WatchType
|
||||||
|
import com.lagradost.cloudstream3.ui.WhoIsWatchingAdapter
|
||||||
|
import com.lagradost.cloudstream3.ui.result.UiImage
|
||||||
import com.lagradost.cloudstream3.ui.result.VideoWatchState
|
import com.lagradost.cloudstream3.ui.result.VideoWatchState
|
||||||
|
import com.lagradost.cloudstream3.ui.result.setImage
|
||||||
|
import com.lagradost.cloudstream3.ui.result.setLinearListLayout
|
||||||
|
import com.lagradost.cloudstream3.utils.AppUtils.setDefaultFocus
|
||||||
|
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
||||||
|
|
||||||
const val VIDEO_POS_DUR = "video_pos_dur"
|
const val VIDEO_POS_DUR = "video_pos_dur"
|
||||||
const val VIDEO_WATCH_STATE = "video_watch_state"
|
const val VIDEO_WATCH_STATE = "video_watch_state"
|
||||||
|
@ -26,6 +44,197 @@ const val RESULT_SEASON = "result_season"
|
||||||
const val RESULT_DUB = "result_dub"
|
const val RESULT_DUB = "result_dub"
|
||||||
|
|
||||||
object DataStoreHelper {
|
object DataStoreHelper {
|
||||||
|
// be aware, don't change the index of these as Account uses the index for the art
|
||||||
|
private val profileImages = arrayOf(
|
||||||
|
R.drawable.profile_bg_dark_blue,
|
||||||
|
R.drawable.profile_bg_blue,
|
||||||
|
R.drawable.profile_bg_orange,
|
||||||
|
R.drawable.profile_bg_pink,
|
||||||
|
R.drawable.profile_bg_purple,
|
||||||
|
R.drawable.profile_bg_red,
|
||||||
|
R.drawable.profile_bg_teal
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Account(
|
||||||
|
@JsonProperty("keyIndex")
|
||||||
|
val keyIndex: Int,
|
||||||
|
@JsonProperty("name")
|
||||||
|
val name: String,
|
||||||
|
@JsonProperty("customImage")
|
||||||
|
val customImage: String? = null,
|
||||||
|
@JsonProperty("defaultImageIndex")
|
||||||
|
val defaultImageIndex: Int,
|
||||||
|
) {
|
||||||
|
val image: UiImage
|
||||||
|
get() = customImage?.let { UiImage.Image(it) } ?: UiImage.Drawable(
|
||||||
|
profileImages.getOrNull(defaultImageIndex) ?: profileImages.first()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const val TAG = "data_store_helper"
|
||||||
|
private var accounts by PreferenceDelegate("$TAG/account", arrayOf<Account>())
|
||||||
|
var selectedKeyIndex by PreferenceDelegate("$TAG/account_key_index", 0)
|
||||||
|
val currentAccount: String get() = selectedKeyIndex.toString()
|
||||||
|
|
||||||
|
private fun setAccount(account: Account) {
|
||||||
|
selectedKeyIndex = account.keyIndex
|
||||||
|
showToast(account.name)
|
||||||
|
MainActivity.bookmarksUpdatedEvent(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun editAccount(context: Context, account: Account, isNewAccount: Boolean) {
|
||||||
|
val binding =
|
||||||
|
WhoIsWatchingAccountEditBinding.inflate(LayoutInflater.from(context), null, false)
|
||||||
|
val builder =
|
||||||
|
AlertDialog.Builder(context, R.style.AlertDialogCustom)
|
||||||
|
.setView(binding.root)
|
||||||
|
|
||||||
|
var currentEditAccount = account
|
||||||
|
val dialog = builder.show()
|
||||||
|
binding.accountName.text = Editable.Factory.getInstance()?.newEditable(account.name)
|
||||||
|
binding.accountName.doOnTextChanged { text, _, _, _ ->
|
||||||
|
currentEditAccount = currentEditAccount.copy(name = text?.toString() ?: "")
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.deleteBtt.isGone = isNewAccount
|
||||||
|
binding.deleteBtt.setOnClickListener {
|
||||||
|
val dialogClickListener =
|
||||||
|
DialogInterface.OnClickListener { _, which ->
|
||||||
|
when (which) {
|
||||||
|
DialogInterface.BUTTON_POSITIVE -> {
|
||||||
|
// remove all keys as well as the account, note that default wont get
|
||||||
|
// deleted from currentAccounts, as it is not part of "accounts",
|
||||||
|
// but the watch keys will
|
||||||
|
removeKeys(account.keyIndex.toString())
|
||||||
|
val currentAccounts = accounts.toMutableList()
|
||||||
|
currentAccounts.removeIf { it.keyIndex == account.keyIndex }
|
||||||
|
accounts = currentAccounts.toTypedArray()
|
||||||
|
|
||||||
|
// update UI
|
||||||
|
setAccount(getDefaultAccount(context))
|
||||||
|
MainActivity.bookmarksUpdatedEvent(true)
|
||||||
|
dialog?.dismissSafe()
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogInterface.BUTTON_NEGATIVE -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
AlertDialog.Builder(context).setTitle(R.string.delete).setMessage(
|
||||||
|
context.getString(R.string.delete_message).format(
|
||||||
|
currentEditAccount.name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.setPositiveButton(R.string.delete, dialogClickListener)
|
||||||
|
.setNegativeButton(R.string.cancel, dialogClickListener)
|
||||||
|
.show().setDefaultFocus()
|
||||||
|
} catch (t: Throwable) {
|
||||||
|
logError(t)
|
||||||
|
// ye you somehow fucked up formatting did you?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.cancelBtt.setOnClickListener {
|
||||||
|
dialog?.dismissSafe()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.profilePic.setImage(account.image)
|
||||||
|
binding.profilePic.setOnClickListener {
|
||||||
|
// rolls the image forwards once
|
||||||
|
currentEditAccount =
|
||||||
|
currentEditAccount.copy(defaultImageIndex = (currentEditAccount.defaultImageIndex + 1) % profileImages.size)
|
||||||
|
binding.profilePic.setImage(currentEditAccount.image)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.applyBtt.setOnClickListener {
|
||||||
|
val currentAccounts = accounts.toMutableList()
|
||||||
|
|
||||||
|
val overrideIndex =
|
||||||
|
currentAccounts.indexOfFirst { it.keyIndex == currentEditAccount.keyIndex }
|
||||||
|
|
||||||
|
// if an account is found that has the same keyIndex then override that one, if not then append it
|
||||||
|
if (overrideIndex != -1) {
|
||||||
|
currentAccounts[overrideIndex] = currentEditAccount
|
||||||
|
} else {
|
||||||
|
currentAccounts.add(currentEditAccount)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the new default account as well as add the key for the new account
|
||||||
|
setAccount(currentEditAccount)
|
||||||
|
accounts = currentAccounts.toTypedArray()
|
||||||
|
|
||||||
|
dialog.dismissSafe()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDefaultAccount(context: Context): Account {
|
||||||
|
return accounts.let { currentAccounts ->
|
||||||
|
currentAccounts.getOrNull(currentAccounts.indexOfFirst { it.keyIndex == 0 }) ?: Account(
|
||||||
|
keyIndex = 0,
|
||||||
|
name = context.getString(R.string.default_account),
|
||||||
|
defaultImageIndex = 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showWhoIsWatching(context: Context) {
|
||||||
|
val binding: WhoIsWatchingBinding = WhoIsWatchingBinding.inflate(
|
||||||
|
LayoutInflater.from(context)
|
||||||
|
)
|
||||||
|
|
||||||
|
val showAccount = accounts.toMutableList().apply {
|
||||||
|
val item = getDefaultAccount(context)
|
||||||
|
remove(item)
|
||||||
|
add(0, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
val builder =
|
||||||
|
BottomSheetDialog(context)
|
||||||
|
builder.setContentView(binding.root)
|
||||||
|
val accountName = context.getString(R.string.account)
|
||||||
|
|
||||||
|
binding.profilesRecyclerview.setLinearListLayout(isHorizontal = true)
|
||||||
|
binding.profilesRecyclerview.adapter = WhoIsWatchingAdapter(
|
||||||
|
selectCallBack = { account ->
|
||||||
|
setAccount(account)
|
||||||
|
builder.dismissSafe()
|
||||||
|
},
|
||||||
|
addAccountCallback = {
|
||||||
|
val currentAccounts = accounts
|
||||||
|
val remainingImages =
|
||||||
|
profileImages.toSet() - currentAccounts.filter { it.customImage == null }
|
||||||
|
.mapNotNull { profileImages.getOrNull(it.defaultImageIndex) }.toSet()
|
||||||
|
val image =
|
||||||
|
profileImages.indexOf(remainingImages.randomOrNull() ?: profileImages.random())
|
||||||
|
val keyIndex = (currentAccounts.maxOfOrNull { it.keyIndex } ?: 0) + 1
|
||||||
|
|
||||||
|
// create a new dummy account
|
||||||
|
editAccount(
|
||||||
|
context,
|
||||||
|
Account(
|
||||||
|
keyIndex = keyIndex,
|
||||||
|
name = "$accountName $keyIndex",
|
||||||
|
customImage = null,
|
||||||
|
defaultImageIndex = image
|
||||||
|
), isNewAccount = true
|
||||||
|
)
|
||||||
|
builder.dismissSafe()
|
||||||
|
},
|
||||||
|
editCallBack = { account ->
|
||||||
|
editAccount(
|
||||||
|
context, account, isNewAccount = false
|
||||||
|
)
|
||||||
|
builder.dismissSafe()
|
||||||
|
}
|
||||||
|
).apply {
|
||||||
|
submitList(showAccount)
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
data class PosDur(
|
data class PosDur(
|
||||||
@JsonProperty("position") val position: Long,
|
@JsonProperty("position") val position: Long,
|
||||||
@JsonProperty("duration") val duration: Long
|
@JsonProperty("duration") val duration: Long
|
||||||
|
@ -117,7 +326,6 @@ object DataStoreHelper {
|
||||||
/**
|
/**
|
||||||
* A datastore wide account for future implementations of a multiple account system
|
* A datastore wide account for future implementations of a multiple account system
|
||||||
**/
|
**/
|
||||||
var currentAccount: String = "0" //TODO ACCOUNT IMPLEMENTATION
|
|
||||||
|
|
||||||
fun getAllWatchStateIds(): List<Int>? {
|
fun getAllWatchStateIds(): List<Int>? {
|
||||||
val folder = "$currentAccount/$RESULT_WATCH_STATE"
|
val folder = "$currentAccount/$RESULT_WATCH_STATE"
|
||||||
|
|
|
@ -15,6 +15,7 @@ import android.graphics.drawable.Drawable
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.*
|
import android.view.*
|
||||||
|
import android.view.ViewGroup.MarginLayoutParams
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.ListAdapter
|
import android.widget.ListAdapter
|
||||||
|
@ -33,6 +34,10 @@ import androidx.core.graphics.blue
|
||||||
import androidx.core.graphics.drawable.toBitmapOrNull
|
import androidx.core.graphics.drawable.toBitmapOrNull
|
||||||
import androidx.core.graphics.green
|
import androidx.core.graphics.green
|
||||||
import androidx.core.graphics.red
|
import androidx.core.graphics.red
|
||||||
|
import androidx.core.view.marginBottom
|
||||||
|
import androidx.core.view.marginLeft
|
||||||
|
import androidx.core.view.marginRight
|
||||||
|
import androidx.core.view.marginTop
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
|
@ -55,7 +60,6 @@ import com.lagradost.cloudstream3.mvvm.logError
|
||||||
import com.lagradost.cloudstream3.ui.result.UiImage
|
import com.lagradost.cloudstream3.ui.result.UiImage
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
|
|
||||||
import jp.wasabeef.glide.transformations.BlurTransformation
|
import jp.wasabeef.glide.transformations.BlurTransformation
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
@ -77,8 +81,8 @@ object UIHelper {
|
||||||
|| Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
|
|| Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun populateChips(view: ChipGroup?, tags : List<String>) {
|
fun populateChips(view: ChipGroup?, tags: List<String>) {
|
||||||
if(view == null) return
|
if (view == null) return
|
||||||
view.removeAllViews()
|
view.removeAllViews()
|
||||||
val context = view.context ?: return
|
val context = view.context ?: return
|
||||||
|
|
||||||
|
@ -304,7 +308,7 @@ object UIHelper {
|
||||||
else req
|
else req
|
||||||
}
|
}
|
||||||
|
|
||||||
if(radius > 0) {
|
if (radius > 0) {
|
||||||
builder = builder.apply(bitmapTransform(BlurTransformation(radius, sample)))
|
builder = builder.apply(bitmapTransform(BlurTransformation(radius, sample)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,6 +500,22 @@ object UIHelper {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun fixPaddingStatusbarMargin(v: View?) {
|
||||||
|
if (v == null) return
|
||||||
|
val ctx = v.context ?: return
|
||||||
|
|
||||||
|
v.layoutParams = v.layoutParams.apply {
|
||||||
|
if (this is MarginLayoutParams) {
|
||||||
|
setMargins(
|
||||||
|
v.marginLeft,
|
||||||
|
v.marginTop + ctx.getStatusBarHeight(),
|
||||||
|
v.marginRight,
|
||||||
|
v.marginBottom
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun fixPaddingStatusbarView(v: View?) {
|
fun fixPaddingStatusbarView(v: View?) {
|
||||||
if (v == null) return
|
if (v == null) return
|
||||||
val ctx = v.context ?: return
|
val ctx = v.context ?: return
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
<vector android:height="24dp" android:tint="#000000"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:width="24dp"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:height="24dp"
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM7.35,18.5C8.66,17.56 10.26,17 12,17s3.34,0.56 4.65,1.5C15.34,19.44 13.74,20 12,20S8.66,19.44 7.35,18.5zM18.14,17.12L18.14,17.12C16.45,15.8 14.32,15 12,15s-4.45,0.8 -6.14,2.12l0,0C4.7,15.73 4,13.95 4,12c0,-4.42 3.58,-8 8,-8s8,3.58 8,8C20,13.95 19.3,15.73 18.14,17.12z"/>
|
android:tint="?attr/white"
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M12,6c-1.93,0 -3.5,1.57 -3.5,3.5S10.07,13 12,13s3.5,-1.57 3.5,-3.5S13.93,6 12,6zM12,11c-0.83,0 -1.5,-0.67 -1.5,-1.5S11.17,8 12,8s1.5,0.67 1.5,1.5S12.83,11 12,11z"/>
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM7.35,18.5C8.66,17.56 10.26,17 12,17s3.34,0.56 4.65,1.5C15.34,19.44 13.74,20 12,20S8.66,19.44 7.35,18.5zM18.14,17.12L18.14,17.12C16.45,15.8 14.32,15 12,15s-4.45,0.8 -6.14,2.12l0,0C4.7,15.73 4,13.95 4,12c0,-4.42 3.58,-8 8,-8s8,3.58 8,8C20,13.95 19.3,15.73 18.14,17.12z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,6c-1.93,0 -3.5,1.57 -3.5,3.5S10.07,13 12,13s3.5,-1.57 3.5,-3.5S13.93,6 12,6zM12,11c-0.83,0 -1.5,-0.67 -1.5,-1.5S11.17,8 12,8s1.5,0.67 1.5,1.5S12.83,11 12,11z" />
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:color="@android:color/white">
|
android:color="@android:color/white">
|
||||||
|
|
||||||
<item>
|
<item>
|
||||||
<shape android:shape="rectangle">
|
<shape android:shape="rectangle">
|
||||||
<stroke
|
<stroke
|
||||||
android:width="2dp"
|
android:width="2dp"
|
||||||
android:color="@android:color/white" />
|
android:color="@android:color/white" />
|
||||||
<corners android:radius="2dp" />
|
<corners android:radius="@dimen/rounded_image_radius" />
|
||||||
</shape>
|
</shape>
|
||||||
</item>
|
</item>
|
||||||
|
|
||||||
<item android:id="@android:id/mask">
|
<item android:id="@android:id/mask">
|
||||||
<shape android:shape="rectangle">
|
<shape android:shape="rectangle">
|
||||||
<corners android:radius="2dp" />
|
<corners android:radius="@dimen/rounded_image_radius" />
|
||||||
<solid android:color="?attr/iconGrayBackground" />
|
<solid android:color="?attr/iconGrayBackground" />
|
||||||
</shape>
|
</shape>
|
||||||
</item>
|
</item>
|
||||||
|
|
||||||
</ripple>
|
</ripple>
|
|
@ -38,16 +38,21 @@
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/home_padding"
|
android:id="@+id/home_padding"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="50dp"
|
||||||
android:orientation="vertical">
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<androidx.appcompat.widget.SearchView
|
<androidx.appcompat.widget.SearchView
|
||||||
android:id="@+id/home_search"
|
android:id="@+id/home_search"
|
||||||
|
android:nextFocusRight="@id/home_switch_account"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="60dp"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="center_vertical"
|
||||||
|
android:padding="0dp"
|
||||||
|
android:layout_marginEnd="50dp"
|
||||||
android:editTextColor="@color/white"
|
android:editTextColor="@color/white"
|
||||||
android:gravity="start"
|
android:gravity="center_vertical"
|
||||||
|
|
||||||
android:iconifiedByDefault="true"
|
android:iconifiedByDefault="true"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textColorHint="@color/white"
|
android:textColorHint="@color/white"
|
||||||
|
@ -57,6 +62,19 @@
|
||||||
app:queryHint="@string/search_hint"
|
app:queryHint="@string/search_hint"
|
||||||
app:searchIcon="@drawable/search_icon"
|
app:searchIcon="@drawable/search_icon"
|
||||||
tools:ignore="RtlSymmetry" />
|
tools:ignore="RtlSymmetry" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
|
||||||
|
android:nextFocusLeft="@id/home_search"
|
||||||
|
android:id="@+id/home_switch_account"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginStart="-50dp"
|
||||||
|
android:contentDescription="@string/account"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:src="@drawable/ic_outline_account_circle_24" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
android:id="@+id/outline"
|
android:id="@+id/outline"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/outline"
|
android:background="@drawable/outline_card"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
|
35
app/src/main/res/layout/who_is_watching.xml
Normal file
35
app/src/main/res/layout/who_is_watching.xml
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||||
|
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:text="@string/switch_account"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_rowWeight="1"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:descendantFocusability="afterDescendants"
|
||||||
|
android:id="@+id/profiles_recyclerview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
tools:itemCount="4"
|
||||||
|
tools:listitem="@layout/who_is_watching_account">
|
||||||
|
|
||||||
|
<requestFocus />
|
||||||
|
</androidx.recyclerview.widget.RecyclerView>
|
||||||
|
</LinearLayout>
|
47
app/src/main/res/layout/who_is_watching_account.xml
Normal file
47
app/src/main/res/layout/who_is_watching_account.xml
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/card_view"
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:animateLayoutChanges="true"
|
||||||
|
android:backgroundTint="?attr/primaryGrayBackground"
|
||||||
|
android:foreground="?attr/selectableItemBackgroundBorderless"
|
||||||
|
app:cardCornerRadius="@dimen/rounded_image_radius"
|
||||||
|
android:layout_margin="5dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintDimensionRatio="1"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHeight_percent="0.4"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/profile_image_background"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:alpha="0.4"
|
||||||
|
android:contentDescription="@string/profile_background_des"
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/outline"
|
||||||
|
tools:visibility="visible"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/outline_card"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/profile_text"
|
||||||
|
tools:text="@string/mobile_data"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
29
app/src/main/res/layout/who_is_watching_account_add.xml
Normal file
29
app/src/main/res/layout/who_is_watching_account_add.xml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/card_view"
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:animateLayoutChanges="true"
|
||||||
|
android:backgroundTint="?attr/primaryGrayBackground"
|
||||||
|
android:foreground="?attr/selectableItemBackgroundBorderless"
|
||||||
|
app:cardCornerRadius="@dimen/rounded_image_radius"
|
||||||
|
android:layout_margin="5dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintDimensionRatio="1"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHeight_percent="0.4"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/ic_baseline_add_24"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:contentDescription="@string/add_account" />
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
135
app/src/main/res/layout/who_is_watching_account_edit.xml
Normal file
135
app/src/main/res/layout/who_is_watching_account_edit.xml
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text1"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_rowWeight="1"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_weight="1"
|
||||||
|
|
||||||
|
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||||
|
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||||
|
android:text="@string/create_account"
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<!-- <com.google.android.material.button.MaterialButton-->
|
||||||
|
<!-- android:nextFocusDown="@id/repo_name_input"-->
|
||||||
|
<!-- android:id="@+id/list_repositories"-->
|
||||||
|
<!-- android:nextFocusLeft="@id/apply_btt"-->
|
||||||
|
<!-- android:nextFocusRight="@id/cancel_btt"-->
|
||||||
|
<!-- style="@style/WhiteButton"-->
|
||||||
|
<!-- android:layout_width="wrap_content"-->
|
||||||
|
<!-- android:layout_gravity="center_vertical"-->
|
||||||
|
<!-- android:text="@string/view_public_repositories_button_short" />-->
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_rowWeight="1"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||||
|
|
||||||
|
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||||
|
android:textColor="?attr/grayTextColor"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:text="Gogoanime" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="10dp"
|
||||||
|
android:layout_marginBottom="60dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/account_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:autofillHints="username"
|
||||||
|
android:hint="@string/default_account"
|
||||||
|
android:inputType="text"
|
||||||
|
android:nextFocusLeft="@id/apply_btt"
|
||||||
|
android:nextFocusRight="@id/cancel_btt"
|
||||||
|
android:nextFocusDown="@id/site_url_input"
|
||||||
|
android:requiresFadingEdge="vertical"
|
||||||
|
android:textColorHint="?attr/grayTextColor"
|
||||||
|
tools:ignore="LabelFor" />
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:cardCornerRadius="@dimen/rounded_image_radius">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/profile_pic"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:contentDescription="@string/preview_background_img_des"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@drawable/profile_bg_blue" />
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/apply_btt_holder"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginTop="-60dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="10dp">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/delete_btt"
|
||||||
|
style="@style/BlackButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:nextFocusRight="@id/apply_btt"
|
||||||
|
android:text="@string/delete" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/apply_btt"
|
||||||
|
style="@style/WhiteButton"
|
||||||
|
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:layout_toStartOf="@+id/cancel_btt"
|
||||||
|
android:nextFocusLeft="@id/delete_btt"
|
||||||
|
android:nextFocusRight="@id/cancel_btt"
|
||||||
|
android:text="@string/sort_apply" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/cancel_btt"
|
||||||
|
style="@style/BlackButton"
|
||||||
|
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:nextFocusLeft="@id/apply_btt"
|
||||||
|
android:text="@string/sort_cancel" />
|
||||||
|
</RelativeLayout>
|
||||||
|
</LinearLayout>
|
|
@ -307,6 +307,7 @@
|
||||||
<string name="queued">queued</string>
|
<string name="queued">queued</string>
|
||||||
<string name="no_subtitles">No Subtitles</string>
|
<string name="no_subtitles">No Subtitles</string>
|
||||||
<string name="default_subtitles">Default</string>
|
<string name="default_subtitles">Default</string>
|
||||||
|
<string name="default_account">@string/default_subtitles</string>
|
||||||
<string name="free_storage">Free</string>
|
<string name="free_storage">Free</string>
|
||||||
<string name="used_storage">Used</string>
|
<string name="used_storage">Used</string>
|
||||||
<string name="app_storage">App</string>
|
<string name="app_storage">App</string>
|
||||||
|
|
Loading…
Reference in a new issue