From bbe28f769dc4936cf2e59740b4d389a9a6db651e Mon Sep 17 00:00:00 2001 From: Koitharu Date: Tue, 4 Feb 2020 21:53:41 +0200 Subject: [PATCH] Favourites --- app/build.gradle | 5 +- .../koitharu/kotatsu/core/db/FavouritesDao.kt | 4 +- .../domain/favourites/FavouritesRepository.kt | 14 +++ .../kotatsu/ui/common/AlertDialogFragment.kt | 3 +- .../kotatsu/ui/common/TextInputDialog.kt | 69 ++++++++++++ .../ui/details/MangaDetailsFragment.kt | 4 + .../favourites/FavouriteCategoriesDialog.kt | 7 -- .../{ => categories}/CategoriesAdapter.kt | 18 +++- .../{ => categories}/CategoryHolder.kt | 2 +- .../categories/FavouriteCategoriesDialog.kt | 91 ++++++++++++++++ .../FavouriteCategoriesPresenter.kt | 101 ++++++++++++++++++ .../categories/FavouriteCategoriesView.kt | 19 ++++ .../OnCategoryCheckListener.kt | 2 +- .../org/koitharu/kotatsu/utils/ext/ViewExt.kt | 10 +- app/src/main/res/layout/activity_main.xml | 2 +- .../res/layout/dialog_favorite_categories.xml | 16 ++- app/src/main/res/layout/dialog_input.xml | 28 +++++ app/src/main/res/layout/fragment_details.xml | 25 ++++- .../res/layout/item_caegory_checkable.xml | 8 +- .../res/layout/item_manga_list_details.xml | 5 + app/src/main/res/values/strings.xml | 4 + 21 files changed, 405 insertions(+), 32 deletions(-) create mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/common/TextInputDialog.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/FavouriteCategoriesDialog.kt rename app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/{ => categories}/CategoriesAdapter.kt (72%) rename app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/{ => categories}/CategoryHolder.kt (88%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesDialog.kt create mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesPresenter.kt create mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesView.kt rename app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/{ => categories}/OnCategoryCheckListener.kt (75%) create mode 100644 app/src/main/res/layout/dialog_input.xml diff --git a/app/build.gradle b/app/build.gradle index d830532cc..2c4f64f27 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -56,8 +56,9 @@ dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3' - implementation 'androidx.core:core-ktx:1.1.0' - implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.core:core-ktx:1.3.0-alpha01' + implementation "androidx.fragment:fragment-ktx:1.2.0" + implementation 'androidx.appcompat:appcompat:1.2.0-alpha02' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha03' implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha01' diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/FavouritesDao.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/FavouritesDao.kt index c3e1252bc..af246b399 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/FavouritesDao.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/db/FavouritesDao.kt @@ -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) } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/favourites/FavouritesRepository.kt b/app/src/main/java/org/koitharu/kotatsu/domain/favourites/FavouritesRepository.kt index 2115f6699..85bc0c7a7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/favourites/FavouritesRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/domain/favourites/FavouritesRepository.kt @@ -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) + } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/common/AlertDialogFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/common/AlertDialogFragment.kt index 43e482aba..6d3e52ce8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/common/AlertDialogFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/common/AlertDialogFragment.kt @@ -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 diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/common/TextInputDialog.kt b/app/src/main/java/org/koitharu/kotatsu/ui/common/TextInputDialog.kt new file mode 100644 index 000000000..efbda40bd --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/ui/common/TextInputDialog.kt @@ -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()) + + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsFragment.kt index d072e9d10..d1a209084 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsFragment.kt @@ -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() } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/FavouriteCategoriesDialog.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/FavouriteCategoriesDialog.kt deleted file mode 100644 index d4ed778cf..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/FavouriteCategoriesDialog.kt +++ /dev/null @@ -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) { -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/CategoriesAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/CategoriesAdapter.kt similarity index 72% rename from app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/CategoriesAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/CategoriesAdapter.kt index 0545b280c..bc1307d9f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/CategoriesAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/CategoriesAdapter.kt @@ -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() { private val checkedIds = SparseBooleanArray() + fun setCheckedIds(ids: Iterable) { + 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 { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/CategoryHolder.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/CategoryHolder.kt similarity index 88% rename from app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/CategoryHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/CategoryHolder.kt index aa31981a6..a9ab85a8b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/CategoryHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/CategoryHolder.kt @@ -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.* diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesDialog.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesDialog.kt new file mode 100644 index 000000000..d3f741957 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesDialog.kt @@ -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(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) { + adapter?.replaceData(categories) + } + + override fun onCheckedCategoriesChanged(checkedIds: Set) { + 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesPresenter.kt new file mode 100644 index 000000000..fa4a13eed --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesPresenter.kt @@ -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() { + + 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) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesView.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesView.kt new file mode 100644 index 000000000..2a434ee41 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/FavouriteCategoriesView.kt @@ -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) + + @StateStrategyType(AddToEndSingleStrategy::class) + fun onCheckedCategoriesChanged(checkedIds: Set) + + @StateStrategyType(OneExecutionStateStrategy::class) + fun onError(e: Exception) +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/OnCategoryCheckListener.kt b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/OnCategoryCheckListener.kt similarity index 75% rename from app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/OnCategoryCheckListener.kt rename to app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/OnCategoryCheckListener.kt index cc58880eb..a3403c323 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/OnCategoryCheckListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/main/list/favourites/categories/OnCategoryCheckListener.kt @@ -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 diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt index 8b8cd08f3..5a06f1c32 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt @@ -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) } - } \ No newline at end of file + } + +fun View.disableFor(timeInMillis: Long) { + isEnabled = false + postDelayed(timeInMillis) { + isEnabled = true + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index c00400d98..88a35d9b9 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -28,7 +28,7 @@ - @@ -16,16 +17,21 @@ android:scrollbars="vertical" tools:listitem="@layout/item_caegory_checkable" /> + + + android:text="@string/add_new_category" /> \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_input.xml b/app/src/main/res/layout/dialog_input.xml new file mode 100644 index 000000000..7bfc4edc1 --- /dev/null +++ b/app/src/main/res/layout/dialog_input.xml @@ -0,0 +1,28 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_details.xml b/app/src/main/res/layout/fragment_details.xml index 57f6f96af..442ccb26f 100644 --- a/app/src/main/res/layout/fragment_details.xml +++ b/app/src/main/res/layout/fragment_details.xml @@ -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 @@ + + Continue Add bookmark You have not favourites yet + Add to favourites + Add new category + Add + Enter category name \ No newline at end of file