mirror of
https://git.mihon.tech/mihonapp/mihon
synced 2024-11-26 23:28:58 +03:00
Add ability to sort library by date added (closes #1287)
This commit is contained in:
parent
339169b624
commit
1813dbbf59
14 changed files with 74 additions and 5 deletions
|
@ -284,6 +284,10 @@ dependencies {
|
|||
|
||||
// For detecting memory leaks; see https://square.github.io/leakcanary/
|
||||
// debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.2'
|
||||
|
||||
// Debug tool; see https://fbflipper.com/
|
||||
// debugImplementation 'com.facebook.flipper:flipper:0.49.0'
|
||||
// debugImplementation 'com.facebook.soloader:soloader:0.9.0'
|
||||
}
|
||||
|
||||
buildscript {
|
||||
|
|
|
@ -43,6 +43,15 @@ open class App : Application(), LifecycleObserver {
|
|||
super.onCreate()
|
||||
if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
|
||||
|
||||
// Debug tool; see https://fbflipper.com/
|
||||
// SoLoader.init(this, false)
|
||||
// if (BuildConfig.DEBUG && FlipperUtils.shouldEnableFlipper(this)) {
|
||||
// val client = AndroidFlipperClient.getInstance(this)
|
||||
// client.addPlugin(InspectorFlipperPlugin(this, DescriptorMapping.withDefaults()))
|
||||
// client.addPlugin(DatabasesFlipperPlugin(this))
|
||||
// client.start()
|
||||
// }
|
||||
|
||||
// Enforce WebView availability
|
||||
if (!WebViewUtil.supportsWebView(this)) {
|
||||
toast(R.string.information_webview_required, Toast.LENGTH_LONG)
|
||||
|
|
|
@ -20,7 +20,7 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
|
|||
/**
|
||||
* Version of the database.
|
||||
*/
|
||||
const val DATABASE_VERSION = 10
|
||||
const val DATABASE_VERSION = 11
|
||||
}
|
||||
|
||||
override fun onCreate(db: SupportSQLiteDatabase) = with(db) {
|
||||
|
@ -78,6 +78,10 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
|
|||
if (oldVersion < 10) {
|
||||
db.execSQL(MangaTable.addCoverLastModified)
|
||||
}
|
||||
if (oldVersion < 11) {
|
||||
db.execSQL(MangaTable.addDateAdded)
|
||||
db.execSQL(MangaTable.backfillDateAdded)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onConfigure(db: SupportSQLiteDatabase) {
|
||||
|
|
|
@ -15,6 +15,7 @@ import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_ARTIST
|
|||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_AUTHOR
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_CHAPTER_FLAGS
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_COVER_LAST_MODIFIED
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_DATE_ADDED
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_DESCRIPTION
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_FAVORITE
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_GENRE
|
||||
|
@ -47,7 +48,7 @@ class MangaPutResolver : DefaultPutResolver<Manga>() {
|
|||
.whereArgs(obj.id)
|
||||
.build()
|
||||
|
||||
override fun mapToContentValues(obj: Manga) = ContentValues(15).apply {
|
||||
override fun mapToContentValues(obj: Manga) = ContentValues(17).apply {
|
||||
put(COL_ID, obj.id)
|
||||
put(COL_SOURCE, obj.source)
|
||||
put(COL_URL, obj.url)
|
||||
|
@ -64,6 +65,7 @@ class MangaPutResolver : DefaultPutResolver<Manga>() {
|
|||
put(COL_VIEWER, obj.viewer)
|
||||
put(COL_CHAPTER_FLAGS, obj.chapter_flags)
|
||||
put(COL_COVER_LAST_MODIFIED, obj.cover_last_modified)
|
||||
put(COL_DATE_ADDED, obj.date_added)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,6 +87,7 @@ interface BaseMangaGetResolver {
|
|||
viewer = cursor.getInt(cursor.getColumnIndex(COL_VIEWER))
|
||||
chapter_flags = cursor.getInt(cursor.getColumnIndex(COL_CHAPTER_FLAGS))
|
||||
cover_last_modified = cursor.getLong(cursor.getColumnIndex(COL_COVER_LAST_MODIFIED))
|
||||
date_added = cursor.getLong(cursor.getColumnIndex(COL_DATE_ADDED))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@ interface Manga : SManga {
|
|||
|
||||
var last_update: Long
|
||||
|
||||
var date_added: Long
|
||||
|
||||
var viewer: Int
|
||||
|
||||
var chapter_flags: Int
|
||||
|
|
|
@ -26,6 +26,8 @@ open class MangaImpl : Manga {
|
|||
|
||||
override var last_update: Long = 0
|
||||
|
||||
override var date_added: Long = 0
|
||||
|
||||
override var initialized: Boolean = false
|
||||
|
||||
override var viewer: Int = 0
|
||||
|
|
|
@ -28,6 +28,8 @@ object MangaTable {
|
|||
|
||||
const val COL_LAST_UPDATE = "last_update"
|
||||
|
||||
const val COL_DATE_ADDED = "date_added"
|
||||
|
||||
const val COL_INITIALIZED = "initialized"
|
||||
|
||||
const val COL_VIEWER = "viewer"
|
||||
|
@ -58,7 +60,8 @@ object MangaTable {
|
|||
$COL_INITIALIZED BOOLEAN NOT NULL,
|
||||
$COL_VIEWER INTEGER NOT NULL,
|
||||
$COL_CHAPTER_FLAGS INTEGER NOT NULL,
|
||||
$COL_COVER_LAST_MODIFIED LONG NOT NULL
|
||||
$COL_COVER_LAST_MODIFIED LONG NOT NULL,
|
||||
$COL_DATE_ADDED LONG NOT NULL
|
||||
)"""
|
||||
|
||||
val createUrlIndexQuery: String
|
||||
|
@ -70,4 +73,17 @@ object MangaTable {
|
|||
|
||||
val addCoverLastModified: String
|
||||
get() = "ALTER TABLE $TABLE ADD COLUMN $COL_COVER_LAST_MODIFIED LONG NOT NULL DEFAULT 0"
|
||||
|
||||
val addDateAdded: String
|
||||
get() = "ALTER TABLE $TABLE ADD COLUMN $COL_DATE_ADDED LONG NOT NULL DEFAULT 0"
|
||||
|
||||
/**
|
||||
* Used with addDateAdded to populate it with the oldest chapter fetch date.
|
||||
*/
|
||||
val backfillDateAdded: String
|
||||
get() = "UPDATE $TABLE SET $COL_DATE_ADDED = " +
|
||||
"(SELECT MIN(${ChapterTable.COL_DATE_FETCH}) " +
|
||||
"FROM $TABLE INNER JOIN ${ChapterTable.TABLE} " +
|
||||
"ON $TABLE.$COL_ID = ${ChapterTable.TABLE}.${ChapterTable.COL_MANGA_ID} " +
|
||||
"GROUP BY $TABLE.$COL_ID)"
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchCardItem
|
|||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchItem
|
||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchPresenter
|
||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||
import java.util.Date
|
||||
import rx.Observable
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import rx.schedulers.Schedulers
|
||||
|
@ -147,6 +148,14 @@ class SearchPresenter(
|
|||
manga.viewer = prevManga.viewer
|
||||
db.updateMangaViewer(manga).executeAsBlocking()
|
||||
|
||||
// Update date added
|
||||
if (replace) {
|
||||
manga.date_added = prevManga.date_added
|
||||
prevManga.date_added = 0
|
||||
} else {
|
||||
manga.date_added = Date().time
|
||||
}
|
||||
|
||||
// SearchPresenter#networkToLocalManga may have updated the manga title, so ensure db gets updated title
|
||||
db.updateMangaTitle(manga).executeAsBlocking()
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import eu.kanade.tachiyomi.ui.browse.source.filter.TextSectionItem
|
|||
import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateItem
|
||||
import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateSectionItem
|
||||
import eu.kanade.tachiyomi.util.removeCovers
|
||||
import java.util.Date
|
||||
import kotlinx.coroutines.flow.subscribe
|
||||
import rx.Observable
|
||||
import rx.Subscription
|
||||
|
@ -260,9 +261,15 @@ open class BrowseSourcePresenter(
|
|||
*/
|
||||
fun changeMangaFavorite(manga: Manga) {
|
||||
manga.favorite = !manga.favorite
|
||||
manga.date_added = when (manga.favorite) {
|
||||
true -> Date().time
|
||||
false -> 0
|
||||
}
|
||||
|
||||
if (!manga.favorite) {
|
||||
manga.removeCovers(coverCache)
|
||||
}
|
||||
|
||||
db.insertManga(manga).executeAsBlocking()
|
||||
}
|
||||
|
||||
|
|
|
@ -218,6 +218,7 @@ class LibraryPresenter(
|
|||
?: latestChapterManga.size
|
||||
manga1latestChapter.compareTo(manga2latestChapter)
|
||||
}
|
||||
LibrarySort.DATE_ADDED -> i2.manga.date_added.compareTo(i1.manga.date_added)
|
||||
else -> throw Exception("Unknown sorting mode")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,10 +111,11 @@ class LibrarySettingsSheet(
|
|||
private val lastChecked = Item.MultiSort(R.string.action_sort_last_checked, this)
|
||||
private val unread = Item.MultiSort(R.string.action_filter_unread, this)
|
||||
private val latestChapter = Item.MultiSort(R.string.action_sort_latest_chapter, this)
|
||||
private val dateAdded = Item.MultiSort(R.string.action_sort_date_added, this)
|
||||
|
||||
override val header = null
|
||||
override val items =
|
||||
listOf(alphabetically, lastRead, lastChecked, unread, total, latestChapter)
|
||||
listOf(alphabetically, lastRead, lastChecked, unread, total, latestChapter, dateAdded)
|
||||
override val footer = null
|
||||
|
||||
override fun initModels() {
|
||||
|
@ -133,9 +134,12 @@ class LibrarySettingsSheet(
|
|||
if (sorting == LibrarySort.LAST_CHECKED) order else Item.MultiSort.SORT_NONE
|
||||
unread.state =
|
||||
if (sorting == LibrarySort.UNREAD) order else Item.MultiSort.SORT_NONE
|
||||
total.state = if (sorting == LibrarySort.TOTAL) order else Item.MultiSort.SORT_NONE
|
||||
total.state =
|
||||
if (sorting == LibrarySort.TOTAL) order else Item.MultiSort.SORT_NONE
|
||||
latestChapter.state =
|
||||
if (sorting == LibrarySort.LATEST_CHAPTER) order else Item.MultiSort.SORT_NONE
|
||||
dateAdded.state =
|
||||
if (sorting == LibrarySort.DATE_ADDED) order else Item.MultiSort.SORT_NONE
|
||||
}
|
||||
|
||||
override fun onItemClicked(item: Item) {
|
||||
|
@ -161,6 +165,7 @@ class LibrarySettingsSheet(
|
|||
unread -> LibrarySort.UNREAD
|
||||
total -> LibrarySort.TOTAL
|
||||
latestChapter -> LibrarySort.LATEST_CHAPTER
|
||||
dateAdded -> LibrarySort.DATE_ADDED
|
||||
else -> throw Exception("Unknown sorting")
|
||||
}
|
||||
)
|
||||
|
|
|
@ -8,6 +8,7 @@ object LibrarySort {
|
|||
const val UNREAD = 3
|
||||
const val TOTAL = 4
|
||||
const val LATEST_CHAPTER = 6
|
||||
const val DATE_ADDED = 7
|
||||
|
||||
@Deprecated("Removed in favor of searching by source")
|
||||
const val SOURCE = 5
|
||||
|
|
|
@ -20,6 +20,7 @@ import eu.kanade.tachiyomi.util.lang.launchIO
|
|||
import eu.kanade.tachiyomi.util.prepUpdateCover
|
||||
import eu.kanade.tachiyomi.util.removeCovers
|
||||
import eu.kanade.tachiyomi.util.shouldDownloadNewChapters
|
||||
import java.util.Date
|
||||
import rx.Observable
|
||||
import rx.Subscription
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
|
@ -149,6 +150,10 @@ class MangaInfoChaptersPresenter(
|
|||
*/
|
||||
fun toggleFavorite(): Boolean {
|
||||
manga.favorite = !manga.favorite
|
||||
manga.date_added = when (manga.favorite) {
|
||||
true -> Date().time
|
||||
false -> 0
|
||||
}
|
||||
if (!manga.favorite) {
|
||||
manga.removeCovers(coverCache)
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
<string name="action_sort_last_read">Last read</string>
|
||||
<string name="action_sort_last_checked">Last checked</string>
|
||||
<string name="action_sort_latest_chapter">Latest chapter</string>
|
||||
<string name="action_sort_date_added">Date added</string>
|
||||
<string name="action_search">Search</string>
|
||||
<string name="action_global_search">Global search</string>
|
||||
<string name="action_select_all">Select all</string>
|
||||
|
|
Loading…
Reference in a new issue