Manage favourites categories
This commit is contained in:
@@ -53,6 +53,10 @@
|
||||
android:label="@string/error_occurred"
|
||||
android:theme="@android:style/Theme.DeviceDefault.Dialog"
|
||||
android:windowSoftInputMode="stateAlwaysHidden" />
|
||||
<activity
|
||||
android:name=".ui.main.list.favourites.categories.CategoriesActivity"
|
||||
android:windowSoftInputMode="stateAlwaysHidden"
|
||||
android:label="@string/favourites_categories" />
|
||||
|
||||
<service
|
||||
android:name=".ui.download.DownloadService"
|
||||
|
||||
@@ -17,4 +17,7 @@ abstract class FavouriteCategoriesDao {
|
||||
|
||||
@Query("DELETE FROM favourite_categories WHERE category_id = :id")
|
||||
abstract suspend fun delete(id: Long)
|
||||
|
||||
@Query("UPDATE favourite_categories SET title = :title WHERE category_id = :id")
|
||||
abstract suspend fun update(id: Long, title: String)
|
||||
}
|
||||
@@ -42,6 +42,9 @@ class FavouritesRepository : KoinComponent {
|
||||
val id = db.favouriteCategoriesDao.insert(entity)
|
||||
return entity.toFavouriteCategory(id)
|
||||
}
|
||||
suspend fun renameCategory(id: Long, title: String) {
|
||||
db.favouriteCategoriesDao.update(id, title)
|
||||
}
|
||||
|
||||
suspend fun removeCategory(id: Long) {
|
||||
db.favouriteCategoriesDao.delete(id)
|
||||
|
||||
@@ -59,6 +59,12 @@ class TextInputDialog private constructor(private val delegate: AlertDialog) :
|
||||
return this
|
||||
}
|
||||
|
||||
fun setText(text: String): Builder {
|
||||
view.inputEdit.setText(text)
|
||||
view.inputEdit.setSelection(text.length)
|
||||
return this
|
||||
}
|
||||
|
||||
fun setPositiveButton(@StringRes textId: Int, listener: (DialogInterface, String) -> Unit): Builder {
|
||||
delegate.setPositiveButton(textId) { dialog, _ ->
|
||||
listener(dialog, view.inputEdit.text?.toString().orEmpty())
|
||||
|
||||
@@ -13,7 +13,7 @@ import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
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.main.list.favourites.categories.select.FavouriteCategoriesDialog
|
||||
import org.koitharu.kotatsu.ui.reader.ReaderActivity
|
||||
import org.koitharu.kotatsu.ui.search.MangaSearchSheet
|
||||
import org.koitharu.kotatsu.utils.ext.addChips
|
||||
|
||||
@@ -6,11 +6,11 @@ import android.view.MenuItem
|
||||
import kotlinx.android.synthetic.main.fragment_list.*
|
||||
import moxy.ktx.moxyPresenter
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.Manga
|
||||
import org.koitharu.kotatsu.ui.main.list.MangaListFragment
|
||||
import org.koitharu.kotatsu.ui.main.list.MangaListView
|
||||
import org.koitharu.kotatsu.ui.main.list.favourites.categories.CategoriesActivity
|
||||
|
||||
class FavouritesListFragment : MangaListFragment<Unit>(), MangaListView<Unit>{
|
||||
class FavouritesListFragment : MangaListFragment<Unit>(), MangaListView<Unit> {
|
||||
|
||||
private val presenter by moxyPresenter(factory = ::FavouritesListPresenter)
|
||||
|
||||
@@ -19,12 +19,17 @@ class FavouritesListFragment : MangaListFragment<Unit>(), MangaListView<Unit>{
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
// inflater.inflate(R.menu.opt_history, menu)
|
||||
inflater.inflate(R.menu.opt_favourites, menu)
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem) = when(item.itemId) {
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
|
||||
R.id.action_categories -> {
|
||||
context?.let {
|
||||
startActivity(CategoriesActivity.newIntent(it))
|
||||
}
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites.categories
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.text.InputType
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.android.synthetic.main.activity_categories.*
|
||||
import moxy.ktx.moxyPresenter
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.ui.common.BaseActivity
|
||||
import org.koitharu.kotatsu.ui.common.dialog.TextInputDialog
|
||||
import org.koitharu.kotatsu.ui.common.list.OnRecyclerItemClickListener
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.utils.ext.showPopupMenu
|
||||
|
||||
class CategoriesActivity : BaseActivity(), OnRecyclerItemClickListener<FavouriteCategory>,
|
||||
FavouriteCategoriesView, View.OnClickListener {
|
||||
|
||||
private val presenter by moxyPresenter(factory = ::FavouriteCategoriesPresenter)
|
||||
|
||||
private lateinit var adapter: CategoriesAdapter
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_categories)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
fab_add.imageTintList = ColorStateList.valueOf(Color.WHITE)
|
||||
adapter = CategoriesAdapter(this)
|
||||
recyclerView.addItemDecoration(DividerItemDecoration(this, RecyclerView.VERTICAL))
|
||||
recyclerView.adapter = adapter
|
||||
fab_add.setOnClickListener(this)
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.fab_add -> createCategory()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemClick(item: FavouriteCategory, position: Int, view: View) {
|
||||
view.showPopupMenu(R.menu.popup_category) {
|
||||
when (it.itemId) {
|
||||
R.id.action_remove -> deleteCategory(item)
|
||||
R.id.action_rename -> renameCategory(item)
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCategoriesChanged(categories: List<FavouriteCategory>) {
|
||||
adapter.replaceData(categories)
|
||||
textView_holder.isVisible = categories.isEmpty()
|
||||
}
|
||||
|
||||
override fun onCheckedCategoriesChanged(checkedIds: Set<Int>) = Unit
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
Snackbar.make(recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG)
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun deleteCategory(category: FavouriteCategory) {
|
||||
AlertDialog.Builder(this)
|
||||
.setMessage(getString(R.string.category_delete_confirm, category.title))
|
||||
.setTitle(R.string.remove_category)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(R.string.remove) { _, _ ->
|
||||
presenter.deleteCategory(category.id)
|
||||
}.create()
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun renameCategory(category: FavouriteCategory) {
|
||||
TextInputDialog.Builder(this)
|
||||
.setTitle(R.string.rename)
|
||||
.setText(category.title)
|
||||
.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.rename) { _, name ->
|
||||
presenter.renameCategory(category.id, name)
|
||||
}.create()
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun createCategory() {
|
||||
TextInputDialog.Builder(this)
|
||||
.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 {
|
||||
|
||||
fun newIntent(context: Context) = Intent(context, CategoriesActivity::class.java)
|
||||
}
|
||||
}
|
||||
@@ -1,46 +1,17 @@
|
||||
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.ui.common.list.OnRecyclerItemClickListener
|
||||
import org.koitharu.kotatsu.ui.main.list.favourites.categories.select.CategoryCheckableHolder
|
||||
|
||||
class CategoriesAdapter(private val listener: OnCategoryCheckListener) :
|
||||
BaseRecyclerAdapter<FavouriteCategory, Boolean>() {
|
||||
class CategoriesAdapter(onItemClickListener: OnRecyclerItemClickListener<FavouriteCategory>? = null) :
|
||||
BaseRecyclerAdapter<FavouriteCategory, Unit>(onItemClickListener) {
|
||||
|
||||
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
|
||||
|
||||
override fun onViewHolderCreated(holder: BaseViewHolder<FavouriteCategory, Boolean>) {
|
||||
super.onViewHolderCreated(holder)
|
||||
holder.itemView.setOnClickListener {
|
||||
if (it !is Checkable) return@setOnClickListener
|
||||
it.toggle()
|
||||
if (it.isChecked) {
|
||||
listener.onCategoryChecked(holder.requireData())
|
||||
} else {
|
||||
listener.onCategoryUnchecked(holder.requireData())
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun getExtra(item: FavouriteCategory, position: Int) = Unit
|
||||
}
|
||||
@@ -1,16 +1,15 @@
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites.categories
|
||||
|
||||
import android.view.ViewGroup
|
||||
import kotlinx.android.synthetic.main.item_category_checkable.*
|
||||
import kotlinx.android.synthetic.main.item_category.*
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.ui.common.list.BaseViewHolder
|
||||
|
||||
class CategoryHolder(parent: ViewGroup) :
|
||||
BaseViewHolder<FavouriteCategory, Boolean>(parent, R.layout.item_category_checkable) {
|
||||
BaseViewHolder<FavouriteCategory, Unit>(parent, R.layout.item_category) {
|
||||
|
||||
override fun onBind(data: FavouriteCategory, extra: Boolean) {
|
||||
checkedTextView.text = data.title
|
||||
checkedTextView.isChecked = extra
|
||||
override fun onBind(data: FavouriteCategory, extra: Unit) {
|
||||
textView.text = data.title
|
||||
}
|
||||
}
|
||||
@@ -70,6 +70,40 @@ class FavouriteCategoriesPresenter : BasePresenter<FavouriteCategoriesView>() {
|
||||
}
|
||||
}
|
||||
|
||||
fun renameCategory(id: Long, name: String) {
|
||||
presenterScope.launch {
|
||||
try {
|
||||
val categories = withContext(Dispatchers.IO) {
|
||||
repository.renameCategory(id, name)
|
||||
repository.getAllCategories()
|
||||
}
|
||||
viewState.onCategoriesChanged(categories)
|
||||
} catch (e: Exception) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
viewState.onError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteCategory(id: Long) {
|
||||
presenterScope.launch {
|
||||
try {
|
||||
val categories = withContext(Dispatchers.IO) {
|
||||
repository.removeCategory(id)
|
||||
repository.getAllCategories()
|
||||
}
|
||||
viewState.onCategoriesChanged(categories)
|
||||
} catch (e: Exception) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
viewState.onError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun addToCategory(manga: Manga, categoryId: Long) {
|
||||
presenterScope.launch {
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites.categories.select
|
||||
|
||||
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
|
||||
|
||||
class CategoriesSelectAdapter(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) =
|
||||
CategoryCheckableHolder(
|
||||
parent
|
||||
)
|
||||
|
||||
override fun onGetItemId(item: FavouriteCategory) = item.id
|
||||
|
||||
override fun onViewHolderCreated(holder: BaseViewHolder<FavouriteCategory, Boolean>) {
|
||||
super.onViewHolderCreated(holder)
|
||||
holder.itemView.setOnClickListener {
|
||||
if (it !is Checkable) return@setOnClickListener
|
||||
it.toggle()
|
||||
if (it.isChecked) {
|
||||
listener.onCategoryChecked(holder.requireData())
|
||||
} else {
|
||||
listener.onCategoryUnchecked(holder.requireData())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites.categories.select
|
||||
|
||||
import android.view.ViewGroup
|
||||
import kotlinx.android.synthetic.main.item_category_checkable.*
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.ui.common.list.BaseViewHolder
|
||||
|
||||
class CategoryCheckableHolder(parent: ViewGroup) :
|
||||
BaseViewHolder<FavouriteCategory, Boolean>(parent, R.layout.item_category_checkable) {
|
||||
|
||||
override fun onBind(data: FavouriteCategory, extra: Boolean) {
|
||||
checkedTextView.text = data.title
|
||||
checkedTextView.isChecked = extra
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites.categories
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites.categories.select
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.InputType
|
||||
@@ -12,6 +12,8 @@ import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.core.model.Manga
|
||||
import org.koitharu.kotatsu.ui.common.BaseBottomSheet
|
||||
import org.koitharu.kotatsu.ui.common.dialog.TextInputDialog
|
||||
import org.koitharu.kotatsu.ui.main.list.favourites.categories.FavouriteCategoriesPresenter
|
||||
import org.koitharu.kotatsu.ui.main.list.favourites.categories.FavouriteCategoriesView
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||
|
||||
@@ -23,11 +25,13 @@ class FavouriteCategoriesDialog : BaseBottomSheet(R.layout.dialog_favorite_categ
|
||||
|
||||
private val manga get() = arguments?.getParcelable<Manga>(ARG_MANGA)
|
||||
|
||||
private var adapter: CategoriesAdapter? = null
|
||||
private var adapter: CategoriesSelectAdapter? = null
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
adapter = CategoriesAdapter(this)
|
||||
adapter =
|
||||
CategoriesSelectAdapter(
|
||||
this)
|
||||
recyclerView_categories.adapter = adapter
|
||||
textView_add.setOnClickListener {
|
||||
createCategory()
|
||||
@@ -79,8 +83,10 @@ class FavouriteCategoriesDialog : BaseBottomSheet(R.layout.dialog_favorite_categ
|
||||
private const val ARG_MANGA = "manga"
|
||||
private const val TAG = "FavouriteCategoriesDialog"
|
||||
|
||||
fun show(fm: FragmentManager, manga: Manga) = FavouriteCategoriesDialog().withArgs(1) {
|
||||
fun show(fm: FragmentManager, manga: Manga) = FavouriteCategoriesDialog()
|
||||
.withArgs(1) {
|
||||
putParcelable(ARG_MANGA, manga)
|
||||
}.show(fm, TAG)
|
||||
}.show(fm,
|
||||
TAG)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites.categories
|
||||
package org.koitharu.kotatsu.ui.main.list.favourites.categories.select
|
||||
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
|
||||
@@ -48,7 +48,7 @@ class HistoryListFragment : MangaListFragment<MangaHistory>(), MangaListView<Man
|
||||
}
|
||||
|
||||
override fun setUpEmptyListHolder() {
|
||||
textView_holder.setText(R.string.history_is_empty)
|
||||
textView_holder.setText(R.string.text_history_holder)
|
||||
textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0)
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ class LocalListFragment : MangaListFragment<File>() {
|
||||
}
|
||||
|
||||
override fun setUpEmptyListHolder() {
|
||||
textView_holder.setText(R.string.no_saved_manga)
|
||||
textView_holder.setText(R.string.text_local_holder)
|
||||
textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0)
|
||||
}
|
||||
|
||||
|
||||
60
app/src/main/res/layout/activity_categories.xml
Normal file
60
app/src/main/res/layout/activity_categories.xml
Normal file
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?colorPrimary"
|
||||
android:fitsSystemWindows="true"
|
||||
android:theme="@style/AppToolbarTheme">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:popupTheme="@style/AppPopupTheme" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="vertical"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_holder"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
android:layout_margin="20dp"
|
||||
android:textAppearance="?android:textAppearanceMedium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:text="@string/text_categories_holder"/>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab_add"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:contentDescription="@string/add_new_category"
|
||||
android:src="@drawable/ic_add"
|
||||
app:backgroundTint="?colorAccent"
|
||||
app:fabSize="normal"
|
||||
app:layout_anchor="@id/recyclerView"
|
||||
app:layout_anchorGravity="bottom|end"
|
||||
app:layout_dodgeInsetEdges="bottom" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
14
app/src/main/res/layout/item_category.xml
Normal file
14
app/src/main/res/layout/item_category.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:listPreferredItemHeight"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:gravity="start|center_vertical"
|
||||
android:paddingStart="?android:listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:listPreferredItemPaddingEnd"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
tools:text="@tools:sample/lorem[4]" />
|
||||
12
app/src/main/res/menu/opt_favourites.xml
Normal file
12
app/src/main/res/menu/opt_favourites.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_categories"
|
||||
android:orderInCategory="50"
|
||||
android:title="@string/categories_"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
||||
13
app/src/main/res/menu/popup_category.xml
Normal file
13
app/src/main/res/menu/popup_category.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_remove"
|
||||
android:title="@string/remove" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_rename"
|
||||
android:title="@string/rename" />
|
||||
|
||||
</menu>
|
||||
@@ -23,7 +23,7 @@
|
||||
<string name="history_is_empty">История пуста</string>
|
||||
<string name="read">Читать</string>
|
||||
<string name="add_bookmark">Добавить закладку</string>
|
||||
<string name="you_have_not_favourites_yet">У Вас пока нет избранной манги</string>
|
||||
<string name="you_have_not_favourites_yet">Добавьте интересующую Вас мангу в избренное, чтобы не потерять её</string>
|
||||
<string name="add_to_favourites">Добавить в избранное</string>
|
||||
<string name="add_new_category">Создать категорию</string>
|
||||
<string name="add">Добавить</string>
|
||||
@@ -122,4 +122,12 @@
|
||||
<string name="notification_sound">Звук уведомления</string>
|
||||
<string name="light_indicator">Световая индикация</string>
|
||||
<string name="vibration">Вибросигнал</string>
|
||||
<string name="favourites_categories">Категории избранного</string>
|
||||
<string name="categories_">Категории…</string>
|
||||
<string name="rename">Переименовать</string>
|
||||
<string name="category_delete_confirm">Вы уверены, что хотите удалить категорию \"%s\"? \nВся манга из данной категории будет утеряна.</string>
|
||||
<string name="remove_category">Удалить категорию</string>
|
||||
<string name="text_categories_holder">Категории помогают упорядочивать избранную мангу. Нажмите «+», чтобы создать категорию</string>
|
||||
<string name="text_history_holder">Здесь будет оборажаться манга, которую Вы читаете. Вы можете найти, что почитать, в боковом меню</string>
|
||||
<string name="text_local_holder">У Вас пока нет сохранённой манги. Вы можете сохранить мангу из онлайн каталога или импортировать из файла</string>
|
||||
</resources>
|
||||
@@ -123,4 +123,12 @@
|
||||
<string name="notification_sound">Notification sound</string>
|
||||
<string name="light_indicator">Light indicator</string>
|
||||
<string name="vibration">Vibration</string>
|
||||
<string name="favourites_categories">Favourites categories</string>
|
||||
<string name="categories_">Categories…</string>
|
||||
<string name="rename">Rename</string>
|
||||
<string name="category_delete_confirm">Do you really want to remove category \"%s\" from your favourites? \nAll containing manga will be lost.</string>
|
||||
<string name="remove_category">Remove category</string>
|
||||
<string name="text_categories_holder">You can use categories to organize your favourite manga. Press «+» to create a category</string>
|
||||
<string name="text_history_holder">Manga you are reading will be displayed here. You can find what to read in side menu</string>
|
||||
<string name="text_local_holder">You have not any saved manga yet. You can save it from online sources or import from file</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user