Update history fragment
This commit is contained in:
@@ -27,6 +27,9 @@ abstract class HistoryDao {
|
||||
@Query("UPDATE history SET page = :page, chapter_id = :chapterId, updated_at = :updatedAt WHERE manga_id = :mangaId")
|
||||
abstract suspend fun update(mangaId: Long, page: Int, chapterId: Long, updatedAt: Long): Int
|
||||
|
||||
@Query("DELETE FROM history WHERE manga_id = :mangaId")
|
||||
abstract suspend fun delete(mangaId: Long)
|
||||
|
||||
suspend fun update(entity: HistoryEntity) = update(entity.mangaId, entity.page, entity.chapterId, entity.updatedAt)
|
||||
|
||||
@Transaction
|
||||
|
||||
@@ -53,6 +53,11 @@ class HistoryRepository : KoinComponent {
|
||||
notifyHistoryChanged()
|
||||
}
|
||||
|
||||
suspend fun delete(manga: Manga) {
|
||||
db.historyDao().delete(manga.id)
|
||||
notifyHistoryChanged()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val listeners = HashSet<OnHistoryChangeListener>()
|
||||
|
||||
@@ -2,11 +2,9 @@ package org.koitharu.kotatsu.ui.main.list
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.*
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.view.GravityCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
@@ -42,7 +40,7 @@ abstract class MangaListFragment<E> : BaseFragment(R.layout.fragment_list), Mang
|
||||
|
||||
private val settings by inject<AppSettings>()
|
||||
|
||||
private lateinit var adapter: MangaListAdapter
|
||||
private var adapter: MangaListAdapter? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -65,6 +63,7 @@ abstract class MangaListFragment<E> : BaseFragment(R.layout.fragment_list), Mang
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
adapter = null
|
||||
settings.unsubscribe(this)
|
||||
super.onDestroyView()
|
||||
}
|
||||
@@ -103,8 +102,23 @@ abstract class MangaListFragment<E> : BaseFragment(R.layout.fragment_list), Mang
|
||||
startActivity(MangaDetailsActivity.newIntent(context ?: return, item))
|
||||
}
|
||||
|
||||
override fun onItemLongClick(item: Manga, position: Int, view: View): Boolean {
|
||||
val menu = PopupMenu(context ?: return false, view)
|
||||
onCreatePopupMenu(menu.menuInflater, menu.menu, item)
|
||||
return if (menu.menu.hasVisibleItems()) {
|
||||
menu.setOnMenuItemClickListener {
|
||||
onPopupMenuItemSelected(it, item)
|
||||
}
|
||||
menu.gravity = GravityCompat.END or Gravity.TOP
|
||||
menu.show()
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onListChanged(list: List<Manga>) {
|
||||
adapter.replaceData(list)
|
||||
adapter?.replaceData(list)
|
||||
if (list.isEmpty()) {
|
||||
setUpEmptyListHolder()
|
||||
layout_holder.isVisible = true
|
||||
@@ -114,7 +128,20 @@ abstract class MangaListFragment<E> : BaseFragment(R.layout.fragment_list), Mang
|
||||
}
|
||||
|
||||
override fun onListAppended(list: List<Manga>) {
|
||||
adapter.appendData(list)
|
||||
adapter?.appendData(list)
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
override fun onItemRemoved(item: Manga) {
|
||||
adapter?.let {
|
||||
it.removeItem(item)
|
||||
if (it.itemCount == 0) {
|
||||
setUpEmptyListHolder()
|
||||
layout_holder.isVisible = true
|
||||
} else {
|
||||
layout_holder.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(e: Exception) {
|
||||
@@ -181,7 +208,7 @@ abstract class MangaListFragment<E> : BaseFragment(R.layout.fragment_list), Mang
|
||||
recyclerView.adapter = null
|
||||
recyclerView.layoutManager = null
|
||||
recyclerView.clearItemDecorations()
|
||||
adapter.listMode = mode
|
||||
adapter?.listMode = mode
|
||||
recyclerView.layoutManager = when (mode) {
|
||||
ListMode.GRID -> GridLayoutManager(ctx, 3)
|
||||
else -> LinearLayoutManager(ctx)
|
||||
@@ -196,7 +223,7 @@ abstract class MangaListFragment<E> : BaseFragment(R.layout.fragment_list), Mang
|
||||
)
|
||||
}
|
||||
)
|
||||
adapter.notifyDataSetChanged()
|
||||
adapter?.notifyDataSetChanged()
|
||||
recyclerView.firstItem = position
|
||||
}
|
||||
|
||||
@@ -213,4 +240,8 @@ abstract class MangaListFragment<E> : BaseFragment(R.layout.fragment_list), Mang
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun onCreatePopupMenu(inflater: MenuInflater, menu: Menu, data: Manga) = Unit
|
||||
|
||||
protected open fun onPopupMenuItemSelected(item: MenuItem, data: Manga) = false
|
||||
}
|
||||
@@ -23,4 +23,7 @@ interface MangaListView<E> : MvpView {
|
||||
|
||||
@StateStrategyType(AddToEndSingleStrategy::class)
|
||||
fun onInitFilter(sortOrders: List<SortOrder>, tags: List<MangaTag>, currentFilter: MangaFilter?)
|
||||
|
||||
@StateStrategyType(AddToEndStrategy::class)
|
||||
fun onItemRemoved(item: Manga)
|
||||
}
|
||||
@@ -6,6 +6,7 @@ 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
|
||||
|
||||
|
||||
@@ -3,14 +3,18 @@ package org.koitharu.kotatsu.ui.main.list.history
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
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.core.model.MangaHistory
|
||||
import org.koitharu.kotatsu.ui.main.list.MangaListFragment
|
||||
import org.koitharu.kotatsu.ui.main.list.MangaListView
|
||||
import org.koitharu.kotatsu.utils.ext.ellipsize
|
||||
|
||||
class HistoryListFragment : MangaListFragment<MangaHistory>(), MangaListView<MangaHistory>{
|
||||
class HistoryListFragment : MangaListFragment<MangaHistory>(), MangaListView<MangaHistory> {
|
||||
|
||||
private val presenter by moxyPresenter(factory = ::HistoryListPresenter)
|
||||
|
||||
@@ -23,12 +27,20 @@ class HistoryListFragment : MangaListFragment<MangaHistory>(), MangaListView<Man
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem) = when(item.itemId) {
|
||||
R.id.action_clear_history -> {
|
||||
presenter.clearHistory()
|
||||
true
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.action_clear_history -> {
|
||||
AlertDialog.Builder(context ?: return false)
|
||||
.setTitle(R.string.clear_history)
|
||||
.setMessage(R.string.text_clear_history_prompt)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(R.string.clear) { _, _ ->
|
||||
presenter.clearHistory()
|
||||
}.show()
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun getTitle(): CharSequence? {
|
||||
@@ -40,6 +52,31 @@ class HistoryListFragment : MangaListFragment<MangaHistory>(), MangaListView<Man
|
||||
textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0)
|
||||
}
|
||||
|
||||
override fun onCreatePopupMenu(inflater: MenuInflater, menu: Menu, data: Manga) {
|
||||
super.onCreatePopupMenu(inflater, menu, data)
|
||||
inflater.inflate(R.menu.popup_history, menu)
|
||||
}
|
||||
|
||||
override fun onPopupMenuItemSelected(item: MenuItem, data: Manga): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.action_remove -> {
|
||||
presenter.removeFromHistory(data)
|
||||
true
|
||||
}
|
||||
else -> super.onPopupMenuItemSelected(item, data)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemRemoved(item: Manga) {
|
||||
super.onItemRemoved(item)
|
||||
Snackbar.make(
|
||||
recyclerView, getString(
|
||||
R.string._s_removed_from_history,
|
||||
item.title.ellipsize(14)
|
||||
), Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance() = HistoryListFragment()
|
||||
|
||||
@@ -5,6 +5,7 @@ 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.core.model.MangaHistory
|
||||
import org.koitharu.kotatsu.domain.history.HistoryRepository
|
||||
import org.koitharu.kotatsu.ui.common.BasePresenter
|
||||
@@ -61,4 +62,19 @@ class HistoryListPresenter : BasePresenter<MangaListView<MangaHistory>>() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun removeFromHistory(manga: Manga) {
|
||||
launch {
|
||||
try {
|
||||
withContext(Dispatchers.IO) {
|
||||
repository.delete(manga)
|
||||
}
|
||||
viewState.onItemRemoved(manga)
|
||||
} catch (e: Exception) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,4 +57,8 @@ fun String.transliterate(skipMissing: Boolean): String {
|
||||
|
||||
fun String.toFileName() = this.transliterate(false)
|
||||
.replace(Regex("[^a-z0-9_\\-]", setOf(RegexOption.IGNORE_CASE)), " ")
|
||||
.replace(Regex("\\s+"), "_")
|
||||
.replace(Regex("\\s+"), "_")
|
||||
|
||||
fun String.ellipsize(maxLength: Int) = if (this.length > maxLength) {
|
||||
this.take(maxLength - 1) + Typography.ellipsis
|
||||
} else this
|
||||
9
app/src/main/res/menu/popup_history.xml
Normal file
9
app/src/main/res/menu/popup_history.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?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" />
|
||||
|
||||
</menu>
|
||||
@@ -61,4 +61,8 @@
|
||||
<string name="dark">Dark</string>
|
||||
<string name="automatic">Automatic</string>
|
||||
<string name="pages">Pages</string>
|
||||
<string name="clear">Clear</string>
|
||||
<string name="text_clear_history_prompt">Are you rally want to clear all your reading history? This action cannot be undone.</string>
|
||||
<string name="remove">Remove</string>
|
||||
<string name="_s_removed_from_history">\"%s\" removed from history</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user