Favourites
This commit is contained in:
@@ -18,6 +18,6 @@ abstract class FavouritesDao {
|
||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||
abstract suspend fun add(favourite: FavouriteEntity)
|
||||
|
||||
@Delete
|
||||
abstract suspend fun delete(favourite: FavouriteEntity)
|
||||
@Query("DELETE FROM favourites WHERE manga_id = :mangaId AND category_id = :categoryId")
|
||||
abstract suspend fun delete(categoryId: Long, mangaId: Long)
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.core.db.entity.FavouriteCategoryEntity
|
||||
import org.koitharu.kotatsu.core.db.entity.FavouriteEntity
|
||||
import org.koitharu.kotatsu.core.db.entity.MangaEntity
|
||||
import org.koitharu.kotatsu.core.db.entity.TagEntity
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.core.model.Manga
|
||||
@@ -40,4 +42,16 @@ class FavouritesRepository : KoinComponent {
|
||||
suspend fun removeCategory(id: Long) {
|
||||
db.favouriteCategoriesDao().delete(id)
|
||||
}
|
||||
|
||||
suspend fun addToCategory(manga: Manga, categoryId: Long) {
|
||||
val tags = manga.tags.map(TagEntity.Companion::fromMangaTag)
|
||||
db.tagsDao().upsert(tags)
|
||||
db.mangaDao().upsert(MangaEntity.from(manga), tags)
|
||||
val entity = FavouriteEntity(manga.id, categoryId, System.currentTimeMillis())
|
||||
db.favouritesDao().add(entity)
|
||||
}
|
||||
|
||||
suspend fun removeFromCategory(manga: Manga, categoryId: Long) {
|
||||
db.favouritesDao().delete(categoryId, manga.id)
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,9 @@ import android.view.View
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import moxy.MvpAppCompatDialogFragment
|
||||
|
||||
abstract class AlertDialogFragment(@LayoutRes private val layoutResId: Int) : DialogFragment() {
|
||||
abstract class AlertDialogFragment(@LayoutRes private val layoutResId: Int) : MvpAppCompatDialogFragment() {
|
||||
|
||||
private var rootView: View? = null
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package org.koitharu.kotatsu.ui.common
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.view.LayoutInflater
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import kotlinx.android.synthetic.main.dialog_input.view.*
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.utils.ext.hideKeyboard
|
||||
import org.koitharu.kotatsu.utils.ext.showKeyboard
|
||||
|
||||
class TextInputDialog private constructor(private val delegate: AlertDialog) :
|
||||
DialogInterface by delegate {
|
||||
|
||||
init {
|
||||
delegate.setOnShowListener {
|
||||
delegate.currentFocus?.showKeyboard()
|
||||
}
|
||||
}
|
||||
|
||||
fun show() = delegate.show()
|
||||
|
||||
class Builder(context: Context) {
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
private val view = LayoutInflater.from(context).inflate(R.layout.dialog_input, null, false)
|
||||
|
||||
private val delegate = AlertDialog.Builder(context)
|
||||
.setView(view)
|
||||
|
||||
fun setTitle(@StringRes titleResId: Int): Builder {
|
||||
delegate.setTitle(titleResId)
|
||||
return this
|
||||
}
|
||||
|
||||
fun setTitle(title: CharSequence): Builder {
|
||||
delegate.setTitle(title)
|
||||
return this
|
||||
}
|
||||
|
||||
fun setHint(@StringRes hintResId: Int): Builder {
|
||||
view.inputLayout.hint = view.context.getString(hintResId)
|
||||
return this
|
||||
}
|
||||
|
||||
fun setInputType(inputType: Int): Builder {
|
||||
view.inputEdit.inputType = inputType
|
||||
return this
|
||||
}
|
||||
|
||||
fun setPositiveButton(@StringRes textId: Int, listener: (DialogInterface, String) -> Unit): Builder {
|
||||
delegate.setPositiveButton(textId) { dialog, _ ->
|
||||
view.hideKeyboard()
|
||||
listener(dialog, view.inputEdit.text?.toString().orEmpty())
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun setNegativeButton(@StringRes textId: Int, listener: DialogInterface.OnClickListener? = null): Builder {
|
||||
delegate.setNegativeButton(textId, listener)
|
||||
return this
|
||||
}
|
||||
|
||||
fun create() = TextInputDialog(delegate.create())
|
||||
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.Manga
|
||||
import org.koitharu.kotatsu.core.model.MangaHistory
|
||||
import org.koitharu.kotatsu.ui.common.BaseFragment
|
||||
import org.koitharu.kotatsu.ui.main.list.favourites.categories.FavouriteCategoriesDialog
|
||||
import org.koitharu.kotatsu.ui.reader.ReaderActivity
|
||||
import org.koitharu.kotatsu.utils.ext.setChips
|
||||
import kotlin.math.roundToInt
|
||||
@@ -40,6 +41,9 @@ class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetai
|
||||
tag = it
|
||||
)
|
||||
}
|
||||
imageView_favourite.setOnClickListener {
|
||||
FavouriteCategoriesDialog.show(childFragmentManager, manga)
|
||||
}
|
||||
updateReadButton()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites
|
||||
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.ui.common.AlertDialogFragment
|
||||
|
||||
class FavouriteCategoriesDialog() : AlertDialogFragment(R.layout.dialog_favorite_categories) {
|
||||
}
|
||||
@@ -1,21 +1,34 @@
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites.categories
|
||||
|
||||
import android.util.SparseBooleanArray
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Checkable
|
||||
import androidx.core.util.set
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.ui.common.list.BaseRecyclerAdapter
|
||||
import org.koitharu.kotatsu.ui.common.list.BaseViewHolder
|
||||
import org.koitharu.kotatsu.utils.ext.disableFor
|
||||
|
||||
class CategoriesAdapter(private val listener: OnCategoryCheckListener) :
|
||||
BaseRecyclerAdapter<FavouriteCategory, Boolean>() {
|
||||
|
||||
private val checkedIds = SparseBooleanArray()
|
||||
|
||||
fun setCheckedIds(ids: Iterable<Int>) {
|
||||
checkedIds.clear()
|
||||
ids.forEach {
|
||||
checkedIds[it] = true
|
||||
}
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun getExtra(item: FavouriteCategory, position: Int) =
|
||||
checkedIds.get(item.id.toInt(), false)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup) = CategoryHolder(parent)
|
||||
override fun onCreateViewHolder(parent: ViewGroup) =
|
||||
CategoryHolder(
|
||||
parent
|
||||
)
|
||||
|
||||
override fun onGetItemId(item: FavouriteCategory) = item.id
|
||||
|
||||
@@ -24,6 +37,7 @@ class CategoriesAdapter(private val listener: OnCategoryCheckListener) :
|
||||
holder.itemView.setOnClickListener {
|
||||
if (it !is Checkable) return@setOnClickListener
|
||||
it.toggle()
|
||||
it.disableFor(200)
|
||||
if (it.isChecked) {
|
||||
listener.onCategoryChecked(holder.requireData())
|
||||
} else {
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites.categories
|
||||
|
||||
import android.view.ViewGroup
|
||||
import kotlinx.android.synthetic.main.item_caegory_checkable.*
|
||||
@@ -0,0 +1,91 @@
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites.categories
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.InputType
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import kotlinx.android.synthetic.main.dialog_favorite_categories.*
|
||||
import moxy.ktx.moxyPresenter
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.core.model.Manga
|
||||
import org.koitharu.kotatsu.ui.common.AlertDialogFragment
|
||||
import org.koitharu.kotatsu.ui.common.TextInputDialog
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||
|
||||
class FavouriteCategoriesDialog() : AlertDialogFragment(R.layout.dialog_favorite_categories),
|
||||
FavouriteCategoriesView,
|
||||
OnCategoryCheckListener {
|
||||
|
||||
private val presenter by moxyPresenter(factory = ::FavouriteCategoriesPresenter)
|
||||
|
||||
private val manga get() = arguments?.getParcelable<Manga>(ARG_MANGA)
|
||||
|
||||
private var adapter: CategoriesAdapter? = null
|
||||
|
||||
override fun onBuildDialog(builder: AlertDialog.Builder) {
|
||||
builder.setTitle(R.string.add_to_favourites)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
adapter = CategoriesAdapter(this)
|
||||
recyclerView_categories.adapter = adapter
|
||||
textView_add.setOnClickListener {
|
||||
createCategory()
|
||||
}
|
||||
manga?.let {
|
||||
presenter.loadMangaCategories(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
adapter = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onCategoriesChanged(categories: List<FavouriteCategory>) {
|
||||
adapter?.replaceData(categories)
|
||||
}
|
||||
|
||||
override fun onCheckedCategoriesChanged(checkedIds: Set<Int>) {
|
||||
adapter?.setCheckedIds(checkedIds)
|
||||
}
|
||||
|
||||
override fun onCategoryChecked(category: FavouriteCategory) {
|
||||
presenter.addToCategory(manga ?: return, category.id)
|
||||
}
|
||||
|
||||
override fun onCategoryUnchecked(category: FavouriteCategory) {
|
||||
presenter.removeFromCategory(manga ?: return, category.id)
|
||||
}
|
||||
|
||||
override fun onError(e: Exception) {
|
||||
Toast.makeText(context ?: return, e.getDisplayMessage(resources), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
private fun createCategory() {
|
||||
TextInputDialog.Builder(context ?: return)
|
||||
.setTitle(R.string.add_new_category)
|
||||
.setHint(R.string.enter_category_name)
|
||||
.setInputType(InputType.TYPE_TEXT_VARIATION_PERSON_NAME or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES)
|
||||
.setNegativeButton(android.R.string.cancel)
|
||||
.setPositiveButton(R.string.add) { _, name ->
|
||||
presenter.createCategory(name)
|
||||
}.create()
|
||||
.show()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val ARG_MANGA = "manga"
|
||||
private const val TAG = "FavouriteCategoriesDialog"
|
||||
|
||||
fun show(fm: FragmentManager, manga: Manga) = FavouriteCategoriesDialog().withArgs(1) {
|
||||
putParcelable(ARG_MANGA, manga)
|
||||
}.show(fm, TAG)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites.categories
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import moxy.InjectViewState
|
||||
import org.koitharu.kotatsu.BuildConfig
|
||||
import org.koitharu.kotatsu.core.model.Manga
|
||||
import org.koitharu.kotatsu.domain.favourites.FavouritesRepository
|
||||
import org.koitharu.kotatsu.ui.common.BasePresenter
|
||||
|
||||
@InjectViewState
|
||||
class FavouriteCategoriesPresenter : BasePresenter<FavouriteCategoriesView>() {
|
||||
|
||||
private lateinit var repository: FavouritesRepository
|
||||
|
||||
override fun onFirstViewAttach() {
|
||||
repository = FavouritesRepository()
|
||||
super.onFirstViewAttach()
|
||||
loadAllCategories()
|
||||
}
|
||||
|
||||
fun loadAllCategories() {
|
||||
launch {
|
||||
try {
|
||||
val categories = withContext(Dispatchers.IO) {
|
||||
repository.getAllCategories()
|
||||
}
|
||||
viewState.onCategoriesChanged(categories)
|
||||
} catch (e: Exception) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
viewState.onError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun loadMangaCategories(manga: Manga) {
|
||||
launch {
|
||||
try {
|
||||
val categories = withContext(Dispatchers.IO) {
|
||||
repository.getCategories(manga.id)
|
||||
}
|
||||
viewState.onCheckedCategoriesChanged(categories.map { it.id.toInt() }.toSet())
|
||||
} catch (e: Exception) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
viewState.onError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createCategory(name: String) {
|
||||
launch {
|
||||
try {
|
||||
val categories = withContext(Dispatchers.IO) {
|
||||
repository.addCategory(name)
|
||||
repository.getAllCategories()
|
||||
}
|
||||
viewState.onCategoriesChanged(categories)
|
||||
} catch (e: Exception) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
viewState.onError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun addToCategory(manga: Manga, categoryId: Long) {
|
||||
launch {
|
||||
try {
|
||||
val categories = withContext(Dispatchers.IO) {
|
||||
repository.addToCategory(manga,categoryId)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
viewState.onError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun removeFromCategory(manga: Manga, categoryId: Long) {
|
||||
launch {
|
||||
try {
|
||||
val categories = withContext(Dispatchers.IO) {
|
||||
repository.removeFromCategory(manga, categoryId)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
viewState.onError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites.categories
|
||||
|
||||
import moxy.MvpView
|
||||
import moxy.viewstate.strategy.AddToEndSingleStrategy
|
||||
import moxy.viewstate.strategy.OneExecutionStateStrategy
|
||||
import moxy.viewstate.strategy.StateStrategyType
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
|
||||
interface FavouriteCategoriesView : MvpView {
|
||||
|
||||
@StateStrategyType(AddToEndSingleStrategy::class)
|
||||
fun onCategoriesChanged(categories: List<FavouriteCategory>)
|
||||
|
||||
@StateStrategyType(AddToEndSingleStrategy::class)
|
||||
fun onCheckedCategoriesChanged(checkedIds: Set<Int>)
|
||||
|
||||
@StateStrategyType(OneExecutionStateStrategy::class)
|
||||
fun onError(e: Exception)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites.categories
|
||||
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
|
||||
@@ -10,6 +10,7 @@ import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.postDelayed
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@@ -88,4 +89,11 @@ var RecyclerView.firstItem: Int
|
||||
if (value != RecyclerView.NO_POSITION) {
|
||||
(layoutManager as? LinearLayoutManager)?.scrollToPositionWithOffset(value, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun View.disableFor(timeInMillis: Long) {
|
||||
isEnabled = false
|
||||
postDelayed(timeInMillis) {
|
||||
isEnabled = true
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<FrameLayout
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="12dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
@@ -16,16 +17,21 @@
|
||||
android:scrollbars="vertical"
|
||||
tools:listitem="@layout/item_caegory_checkable" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?android:listDivider" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_add"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?listPreferredItemHeightSmall"
|
||||
android:background="?selectableItemBackground"
|
||||
android:layout_height="?android:listPreferredItemHeightSmall"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:gravity="start|center_vertical"
|
||||
android:paddingStart="?listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?listPreferredItemPaddingEnd"
|
||||
android:paddingStart="?android:listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:listPreferredItemPaddingEnd"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:text="" />
|
||||
android:text="@string/add_new_category" />
|
||||
|
||||
</LinearLayout>
|
||||
28
app/src/main/res/layout/dialog_input.xml
Normal file
28
app/src/main/res/layout/dialog_input.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="14dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingEnd="14dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/inputLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:boxBackgroundMode="filled">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/inputEdit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:imeOptions="actionDone"
|
||||
android:maxLines="1"
|
||||
tools:text="@tools:sample/lorem[2]" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -27,8 +27,8 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:maxLines="3"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:maxLines="3"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
@@ -41,9 +41,9 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:maxLines="2"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:maxLines="2"
|
||||
app:layout_constraintEnd_toEndOf="@id/textView_title"
|
||||
app:layout_constraintStart_toStartOf="@id/textView_title"
|
||||
app:layout_constraintTop_toBottomOf="@id/textView_title"
|
||||
@@ -63,19 +63,34 @@
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button_read"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:enabled="false"
|
||||
android:text="@string/read"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
app:icon="@drawable/ic_read"
|
||||
app:iconPadding="12dp"
|
||||
android:enabled="false"
|
||||
android:layout_marginEnd="4dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
|
||||
app:layout_constraintEnd_toEndOf="@id/textView_title"
|
||||
app:layout_constraintTop_toBottomOf="@id/ratingBar"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView_favourite"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/add_to_favourites"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_favourites"
|
||||
android:tint="?colorAccent"
|
||||
app:layout_constraintBottom_toBottomOf="@id/button_read"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintEnd_toStartOf="@id/button_read"
|
||||
app:layout_constraintTop_toTopOf="@id/button_read" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/barrier_title"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/checkedTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?listPreferredItemHeightSmall"
|
||||
android:background="?selectableItemBackground"
|
||||
android:layout_height="?android:listPreferredItemHeightSmall"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
|
||||
android:gravity="start|center_vertical"
|
||||
android:paddingStart="?listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?listPreferredItemPaddingEnd"
|
||||
android:paddingStart="?android:listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:listPreferredItemPaddingEnd"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
tools:checked="true"
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
app:cardElevation="0dp"
|
||||
app:strokeColor="?android:textColorPrimary"
|
||||
app:strokeWidth="1px"
|
||||
app:cardBackgroundColor="?android:windowBackground"
|
||||
android:layout_height="@dimen/manga_list_details_item_height">
|
||||
|
||||
<RelativeLayout
|
||||
|
||||
@@ -26,4 +26,8 @@
|
||||
<string name="continue_">Continue</string>
|
||||
<string name="add_bookmark">Add bookmark</string>
|
||||
<string name="you_have_not_favourites_yet">You have not favourites yet</string>
|
||||
<string name="add_to_favourites">Add to favourites</string>
|
||||
<string name="add_new_category">Add new category</string>
|
||||
<string name="add">Add</string>
|
||||
<string name="enter_category_name">Enter category name</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user