Ver Fonte

Add ability to sort library by date added (closes #1287)

arkon há 4 anos atrás
pai
commit
1813dbbf59

+ 4 - 0
app/build.gradle

@@ -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 {

+ 9 - 0
app/src/main/java/eu/kanade/tachiyomi/App.kt

@@ -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)

+ 5 - 1
app/src/main/java/eu/kanade/tachiyomi/data/database/DbOpenCallback.kt

@@ -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) {

+ 4 - 1
app/src/main/java/eu/kanade/tachiyomi/data/database/mappers/MangaTypeMapping.kt

@@ -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))
     }
 }
 

+ 2 - 0
app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.kt

@@ -12,6 +12,8 @@ interface Manga : SManga {
 
     var last_update: Long
 
+    var date_added: Long
+
     var viewer: Int
 
     var chapter_flags: Int

+ 2 - 0
app/src/main/java/eu/kanade/tachiyomi/data/database/models/MangaImpl.kt

@@ -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

+ 17 - 1
app/src/main/java/eu/kanade/tachiyomi/data/database/tables/MangaTable.kt

@@ -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)"
 }

+ 9 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SearchPresenter.kt

@@ -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()
         }

+ 7 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt

@@ -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()
     }
 

+ 1 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt

@@ -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")
             }
         }

+ 7 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt

@@ -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")
                     }
                 )

+ 1 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySort.kt

@@ -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

+ 5 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/MangaInfoChaptersPresenter.kt

@@ -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)
         }

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -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>