Layout improvements, implement editing, and change UX (mostly done?!)

This commit is contained in:
Luna712 2023-11-03 15:16:51 -06:00
parent 2ad5ac1de1
commit 8d69f9f245
10 changed files with 158 additions and 36 deletions

View file

@ -1,14 +1,18 @@
package com.lagradost.cloudstream3.ui.account package com.lagradost.cloudstream3.ui.account
import android.graphics.RenderEffect
import android.graphics.Shader
import android.os.Build
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.databinding.AccountListItemAddBinding import com.lagradost.cloudstream3.databinding.AccountListItemAddBinding
import com.lagradost.cloudstream3.databinding.AccountListItemBinding import com.lagradost.cloudstream3.databinding.AccountListItemBinding
import com.lagradost.cloudstream3.databinding.AccountListItemEditingBinding import com.lagradost.cloudstream3.databinding.AccountListItemEditBinding
import com.lagradost.cloudstream3.ui.account.AccountHelper.showAccountEditDialog import com.lagradost.cloudstream3.ui.account.AccountHelper.showAccountEditDialog
import com.lagradost.cloudstream3.ui.result.setImage import com.lagradost.cloudstream3.ui.result.setImage
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
@ -22,8 +26,8 @@ class AccountAdapter(
) : RecyclerView.Adapter<AccountAdapter.AccountViewHolder>() { ) : RecyclerView.Adapter<AccountAdapter.AccountViewHolder>() {
companion object { companion object {
private const val VIEW_TYPE_ACCOUNT = 0 const val VIEW_TYPE_SELECT_ACCOUNT = 0
private const val VIEW_TYPE_ADD_ACCOUNT = 1 const val VIEW_TYPE_ADD_ACCOUNT = 1
const val VIEW_TYPE_EDIT_ACCOUNT = 2 const val VIEW_TYPE_EDIT_ACCOUNT = 2
} }
@ -35,18 +39,33 @@ class AccountAdapter(
is AccountListItemBinding -> binding.apply { is AccountListItemBinding -> binding.apply {
if (account == null) return@apply if (account == null) return@apply
val isTv = isTvSettings() || !root.isInTouchMode
val isLastUsedAccount = account.keyIndex == DataStoreHelper.selectedKeyIndex val isLastUsedAccount = account.keyIndex == DataStoreHelper.selectedKeyIndex
accountName.text = account.name accountName.text = account.name
accountImage.setImage(account.image) accountImage.setImage(account.image)
lockIcon.isVisible = account.lockPin != null lockIcon.isVisible = account.lockPin != null
outline.isVisible = isLastUsedAccount outline.isVisible = !isTv && isLastUsedAccount
if (isTvSettings()) { if (isTv) {
// For emulator but this is fine on TV also
root.isFocusableInTouchMode = true root.isFocusableInTouchMode = true
if (isLastUsedAccount) { if (isLastUsedAccount) {
root.requestFocus() root.requestFocus()
} }
root.foreground = ContextCompat.getDrawable(
root.context,
R.drawable.outline_drawable
)
} else {
root.setOnLongClickListener {
showAccountEditDialog(root.context, account, isNewAccount = false) {
accountEditCallback.invoke(it)
}
true
}
} }
root.setOnClickListener { root.setOnClickListener {
@ -54,7 +73,7 @@ class AccountAdapter(
} }
} }
is AccountListItemEditingBinding -> binding.apply { is AccountListItemEditBinding -> binding.apply {
if (account == null) return@apply if (account == null) return@apply
val isLastUsedAccount = account.keyIndex == DataStoreHelper.selectedKeyIndex val isLastUsedAccount = account.keyIndex == DataStoreHelper.selectedKeyIndex
@ -62,13 +81,26 @@ class AccountAdapter(
accountName.text = account.name accountName.text = account.name
accountImage.setImage(account.image) accountImage.setImage(account.image)
lockIcon.isVisible = account.lockPin != null lockIcon.isVisible = account.lockPin != null
outline.isVisible = isLastUsedAccount outline.isVisible = !isTvSettings() && isLastUsedAccount
if (Build.VERSION.SDK_INT >= 33) {
accountImage.setRenderEffect(
RenderEffect.createBlurEffect(
10f, 10f, Shader.TileMode.CLAMP
)
)
}
if (isTvSettings()) { if (isTvSettings()) {
root.isFocusableInTouchMode = true root.isFocusableInTouchMode = true
if (isLastUsedAccount) { if (isLastUsedAccount) {
root.requestFocus() root.requestFocus()
} }
root.foreground = ContextCompat.getDrawable(
root.context,
R.drawable.outline_drawable
)
} }
root.setOnClickListener { root.setOnClickListener {
@ -107,7 +139,7 @@ class AccountAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AccountViewHolder = override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AccountViewHolder =
AccountViewHolder( AccountViewHolder(
binding = when (viewType) { binding = when (viewType) {
VIEW_TYPE_ACCOUNT -> { VIEW_TYPE_SELECT_ACCOUNT -> {
AccountListItemBinding.inflate( AccountListItemBinding.inflate(
LayoutInflater.from(parent.context), LayoutInflater.from(parent.context),
parent, parent,
@ -122,7 +154,7 @@ class AccountAdapter(
) )
} }
VIEW_TYPE_EDIT_ACCOUNT -> { VIEW_TYPE_EDIT_ACCOUNT -> {
AccountListItemEditingBinding.inflate( AccountListItemEditBinding.inflate(
LayoutInflater.from(parent.context), LayoutInflater.from(parent.context),
parent, parent,
false false
@ -145,7 +177,7 @@ class AccountAdapter(
return when (position) { return when (position) {
accounts.count() -> VIEW_TYPE_ADD_ACCOUNT accounts.count() -> VIEW_TYPE_ADD_ACCOUNT
else -> VIEW_TYPE_ACCOUNT else -> VIEW_TYPE_SELECT_ACCOUNT
} }
} }

View file

@ -2,6 +2,7 @@ package com.lagradost.cloudstream3.ui.account
import android.content.Context import android.content.Context
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent
import android.text.Editable import android.text.Editable
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
@ -11,6 +12,7 @@ import androidx.appcompat.app.AlertDialog
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.widget.doOnTextChanged import androidx.core.widget.doOnTextChanged
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKeys import com.lagradost.cloudstream3.AcraApplication.Companion.removeKeys
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
@ -42,6 +44,8 @@ object AccountHelper {
var currentEditAccount = account var currentEditAccount = account
val dialog = builder.show() val dialog = builder.show()
if (!isNewAccount) binding.text1.setText(R.string.edit_account)
// Set up the dialog content // Set up the dialog content
binding.accountName.text = Editable.Factory.getInstance()?.newEditable(account.name) binding.accountName.text = Editable.Factory.getInstance()?.newEditable(account.name)
binding.accountName.doOnTextChanged { text, _, _, _ -> binding.accountName.doOnTextChanged { text, _, _, _ ->
@ -294,8 +298,27 @@ object AccountHelper {
builder.setContentView(binding.root) builder.setContentView(binding.root)
builder.show() builder.show()
binding.profilesRecyclerview.setLinearListLayout(isHorizontal = true) binding.manageAccountsButton.setOnClickListener {
binding.profilesRecyclerview.adapter = AccountAdapter( val accountSelectIntent = Intent(context, AccountSelectActivity::class.java)
accountSelectIntent.putExtra("isEditingFromMainActivity", true)
context.startActivity(accountSelectIntent)
builder.dismissSafe()
}
val recyclerView: RecyclerView = binding.accountRecyclerView
val itemWidth = recyclerView.resources.getDimensionPixelSize(
R.dimen.account_select_linear_item_size
)
val itemHeight = recyclerView.resources.getDimensionPixelSize(
R.dimen.account_select_linear_item_size
)
recyclerView.addItemDecoration(AccountSelectLinearItemDecoration(itemWidth, itemHeight))
recyclerView.setLinearListLayout(isHorizontal = true)
recyclerView.adapter = AccountAdapter(
getAccounts(context), getAccounts(context),
accountSelectCallback = { account -> accountSelectCallback = { account ->
// Check if the selected account has a lock PIN set // Check if the selected account has a lock PIN set
@ -317,10 +340,8 @@ object AccountHelper {
onAccountUpdated(it) onAccountUpdated(it)
builder.dismissSafe() builder.dismissSafe()
}, },
accountEditCallback = { // Editing is done using AccountSelectActivity
onAccountUpdated(it) accountEditCallback = {}
builder.dismissSafe()
}
) )
} }
} }

View file

@ -2,6 +2,7 @@ package com.lagradost.cloudstream3.ui.account
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -11,6 +12,7 @@ import com.lagradost.cloudstream3.MainActivity
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.databinding.ActivityAccountSelectBinding import com.lagradost.cloudstream3.databinding.ActivityAccountSelectBinding
import com.lagradost.cloudstream3.ui.account.AccountAdapter.Companion.VIEW_TYPE_EDIT_ACCOUNT import com.lagradost.cloudstream3.ui.account.AccountAdapter.Companion.VIEW_TYPE_EDIT_ACCOUNT
import com.lagradost.cloudstream3.ui.account.AccountAdapter.Companion.VIEW_TYPE_SELECT_ACCOUNT
import com.lagradost.cloudstream3.ui.account.AccountHelper.showPinInputDialog import com.lagradost.cloudstream3.ui.account.AccountHelper.showPinInputDialog
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
import com.lagradost.cloudstream3.utils.DataStoreHelper import com.lagradost.cloudstream3.utils.DataStoreHelper
@ -40,18 +42,60 @@ class AccountSelectActivity : AppCompatActivity() {
val recyclerView: RecyclerView = binding.accountRecyclerView val recyclerView: RecyclerView = binding.accountRecyclerView
// Are we editing and coming from MainActivity?
val isEditingFromMainActivity = intent.getBooleanExtra(
"isEditingFromMainActivity",
false
)
val adapter = AccountAdapter( val adapter = AccountAdapter(
accounts, accounts,
// Handle the selected account // Handle the selected account
accountSelectCallback = { onAccountSelected(it) }, accountSelectCallback = { onAccountSelected(it) },
accountCreateCallback = { onAccountUpdated(it) }, accountCreateCallback = { onAccountUpdated(it) },
accountEditCallback = { onAccountUpdated(it) } accountEditCallback = {
onAccountUpdated(it)
// We came from MainActivity, return there
// and switch to the edited account
if (isEditingFromMainActivity) {
DataStoreHelper.setAccount(it, it.keyIndex != DataStoreHelper.selectedKeyIndex)
navigateToMainActivity()
}
}
) )
recyclerView.adapter = adapter recyclerView.adapter = adapter
binding.editAccountButton.setOnClickListener { var isEditing = false
if (isEditingFromMainActivity) {
binding.editAccountButton.setImageResource(R.drawable.ic_baseline_close_24)
binding.title.setText(R.string.manage_accounts)
adapter.viewType = VIEW_TYPE_EDIT_ACCOUNT adapter.viewType = VIEW_TYPE_EDIT_ACCOUNT
isEditing = true
adapter.notifyDataSetChanged()
}
binding.editAccountButton.setOnClickListener {
isEditing = !isEditing
if (isEditing) {
(it as ImageView).setImageResource(R.drawable.ic_baseline_close_24)
binding.title.setText(R.string.manage_accounts)
adapter.viewType = VIEW_TYPE_EDIT_ACCOUNT
} else {
// We came from MainActivity, return there
// and resume it's state
if (isEditingFromMainActivity) {
navigateToMainActivity()
}
(it as ImageView).setImageResource(R.drawable.ic_baseline_edit_24)
binding.title.setText(R.string.select_an_account)
adapter.viewType = VIEW_TYPE_SELECT_ACCOUNT
}
adapter.notifyDataSetChanged() adapter.notifyDataSetChanged()
} }

View file

@ -0,0 +1,14 @@
package com.lagradost.cloudstream3.ui.account
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.RecyclerView
class AccountSelectLinearItemDecoration(private val width: Int, private val height: Int) : RecyclerView.ItemDecoration() {
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
val layoutParams = view.layoutParams as RecyclerView.LayoutParams
layoutParams.width = width
layoutParams.height = height
view.layoutParams = layoutParams
}
}

View file

@ -44,14 +44,6 @@
android:src="@drawable/video_locked" android:src="@drawable/video_locked"
android:visibility="gone" /> android:visibility="gone" />
<ImageView
android:id="@+id/pencil_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_add_24"
android:visibility="gone" />
<TextView <TextView
android:id="@+id/account_name" android:id="@+id/account_name"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View file

@ -23,7 +23,7 @@
android:id="@+id/account_image" android:id="@+id/account_image"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:alpha="0.2" android:alpha="0.1"
android:contentDescription="@string/profile_background_des" android:contentDescription="@string/profile_background_des"
android:scaleType="centerCrop" /> android:scaleType="centerCrop" />
@ -39,18 +39,17 @@
android:id="@+id/lock_icon" android:id="@+id/lock_icon"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:layout_gravity="top|end" android:layout_gravity="top|start"
android:layout_margin="4dp" android:layout_margin="4dp"
android:src="@drawable/video_locked" android:src="@drawable/video_locked"
android:visibility="gone" /> android:visibility="gone" />
<ImageView <ImageView
android:id="@+id/pencil_icon" android:id="@+id/pencil_icon"
android:layout_width="48dp" android:layout_width="42dp"
android:layout_height="48dp" android:layout_height="42dp"
android:layout_gravity="center" android:layout_gravity="top|end"
android:src="@drawable/ic_baseline_edit_24" android:src="@drawable/ic_baseline_edit_24" />
android:visibility="visible" />
<TextView <TextView
android:id="@+id/account_name" android:id="@+id/account_name"

View file

@ -41,7 +41,7 @@
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:descendantFocusability="afterDescendants" android:descendantFocusability="afterDescendants"
android:id="@+id/profiles_recyclerview" android:id="@+id/account_recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -52,4 +52,15 @@
<requestFocus /> <requestFocus />
</androidx.recyclerview.widget.RecyclerView> </androidx.recyclerview.widget.RecyclerView>
<com.google.android.material.button.MaterialButton
android:id="@+id/manage_accounts_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_gravity="center"
android:text="@string/manage_accounts"
android:textSize="16sp"
app:icon="@drawable/ic_baseline_edit_24"
style="@style/Widget.MaterialComponents.Button.TextButton" />
</LinearLayout> </LinearLayout>

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="?attr/primaryBlackBackground" android:background="?attr/primaryBlackBackground"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -16,9 +17,14 @@
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:src="@drawable/ic_baseline_edit_24" android:src="@drawable/ic_baseline_edit_24"
android:contentDescription="@string/manage_accounts" /> android:focusable="true"
android:nextFocusDown="@id/account_recycler_view"
android:background="@drawable/player_button_tv_attr_no_bg"
android:contentDescription="@string/manage_accounts"
app:tint="@color/player_on_button_tv_attr" />
<TextView <TextView
android:id="@+id/title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/select_an_account" android:text="@string/select_an_account"

View file

@ -20,4 +20,6 @@
<dimen name="download_size">50dp</dimen> <dimen name="download_size">50dp</dimen>
<dimen name="video_frame_width">1dp</dimen> <dimen name="video_frame_width">1dp</dimen>
<dimen name="account_select_linear_item_size">100dp</dimen>
</resources> </resources>

View file

@ -726,5 +726,6 @@
<string name="pin_error_incorrect">Incorrect PIN. Please try again.</string> <string name="pin_error_incorrect">Incorrect PIN. Please try again.</string>
<string name="pin_error_length">PIN must be 4 characters</string> <string name="pin_error_length">PIN must be 4 characters</string>
<string name="select_an_account">Select an Account</string> <string name="select_an_account">Select an Account</string>
<string name="manage_accounts">Manage accounts</string> <string name="manage_accounts">Manage Accounts</string>
<string name="edit_account">Edit account</string>
</resources> </resources>