mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-09-10 22:43:13 +02:00
Searching in recents
This commit is contained in:
parent
fa7b668ac8
commit
3cad9405f9
@ -23,10 +23,10 @@ interface HistoryQueries : DbProvider {
|
|||||||
* @param date recent date range
|
* @param date recent date range
|
||||||
* @offset offset the db by
|
* @offset offset the db by
|
||||||
*/
|
*/
|
||||||
fun getRecentManga(date: Date, offset: Int = 0) = db.get()
|
fun getRecentManga(date: Date, offset: Int = 0, search: String = "") = db.get()
|
||||||
.listOfObjects(MangaChapterHistory::class.java)
|
.listOfObjects(MangaChapterHistory::class.java)
|
||||||
.withQuery(RawQuery.builder()
|
.withQuery(RawQuery.builder()
|
||||||
.query(getRecentMangasQuery(offset))
|
.query(getRecentMangasQuery(offset, search))
|
||||||
.args(date.time)
|
.args(date.time)
|
||||||
.observesTables(HistoryTable.TABLE)
|
.observesTables(HistoryTable.TABLE)
|
||||||
.build())
|
.build())
|
||||||
@ -38,10 +38,10 @@ interface HistoryQueries : DbProvider {
|
|||||||
* @param date recent date range
|
* @param date recent date range
|
||||||
* @offset offset the db by
|
* @offset offset the db by
|
||||||
*/
|
*/
|
||||||
fun getRecentMangaLimit(date: Date, limit: Int = 0) = db.get()
|
fun getRecentMangaLimit(date: Date, limit: Int = 0, search: String = "") = db.get()
|
||||||
.listOfObjects(MangaChapterHistory::class.java)
|
.listOfObjects(MangaChapterHistory::class.java)
|
||||||
.withQuery(RawQuery.builder()
|
.withQuery(RawQuery.builder()
|
||||||
.query(getRecentMangasLimitQuery(limit))
|
.query(getRecentMangasLimitQuery(limit, search))
|
||||||
.args(date.time)
|
.args(date.time)
|
||||||
.observesTables(HistoryTable.TABLE)
|
.observesTables(HistoryTable.TABLE)
|
||||||
.build())
|
.build())
|
||||||
|
@ -47,7 +47,7 @@ fun getRecentsQuery() = """
|
|||||||
* and are read after the given time period
|
* and are read after the given time period
|
||||||
* @return return limit is 25
|
* @return return limit is 25
|
||||||
*/
|
*/
|
||||||
fun getRecentMangasQuery(offset: Int = 0) = """
|
fun getRecentMangasQuery(offset: Int = 0, search: String = "") = """
|
||||||
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
|
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
|
||||||
FROM ${Manga.TABLE}
|
FROM ${Manga.TABLE}
|
||||||
JOIN ${Chapter.TABLE}
|
JOIN ${Chapter.TABLE}
|
||||||
@ -60,7 +60,9 @@ fun getRecentMangasQuery(offset: Int = 0) = """
|
|||||||
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
||||||
GROUP BY ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}) AS max_last_read
|
GROUP BY ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}) AS max_last_read
|
||||||
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = max_last_read.${Chapter.COL_MANGA_ID}
|
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = max_last_read.${Chapter.COL_MANGA_ID}
|
||||||
WHERE ${History.TABLE}.${History.COL_LAST_READ} > ? AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
WHERE ${History.TABLE}.${History.COL_LAST_READ} > ?
|
||||||
|
AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
||||||
|
AND lower(${Manga.TABLE}.${Manga.COL_TITLE}) LIKE '%${search}%'
|
||||||
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
|
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
|
||||||
LIMIT 25 OFFSET $offset
|
LIMIT 25 OFFSET $offset
|
||||||
"""
|
"""
|
||||||
@ -71,7 +73,7 @@ fun getRecentMangasQuery(offset: Int = 0) = """
|
|||||||
* The select statement returns all information of chapters that have the same id as the chapter in max_last_read
|
* The select statement returns all information of chapters that have the same id as the chapter in max_last_read
|
||||||
* and are read after the given time period
|
* and are read after the given time period
|
||||||
*/
|
*/
|
||||||
fun getRecentMangasLimitQuery(limit: Int = 25) = """
|
fun getRecentMangasLimitQuery(limit: Int = 25, search: String = "") = """
|
||||||
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
|
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
|
||||||
FROM ${Manga.TABLE}
|
FROM ${Manga.TABLE}
|
||||||
JOIN ${Chapter.TABLE}
|
JOIN ${Chapter.TABLE}
|
||||||
@ -84,7 +86,9 @@ fun getRecentMangasLimitQuery(limit: Int = 25) = """
|
|||||||
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
||||||
GROUP BY ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}) AS max_last_read
|
GROUP BY ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}) AS max_last_read
|
||||||
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = max_last_read.${Chapter.COL_MANGA_ID}
|
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = max_last_read.${Chapter.COL_MANGA_ID}
|
||||||
WHERE ${History.TABLE}.${History.COL_LAST_READ} > ? AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
WHERE ${History.TABLE}.${History.COL_LAST_READ} > ?
|
||||||
|
AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
||||||
|
AND lower(${Manga.TABLE}.${Manga.COL_TITLE}) LIKE '%${search}%'
|
||||||
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
|
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
|
||||||
LIMIT $limit
|
LIMIT $limit
|
||||||
"""
|
"""
|
||||||
|
@ -4,6 +4,11 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuInflater
|
||||||
|
import android.view.MenuItem
|
||||||
|
import androidx.appcompat.widget.SearchView
|
||||||
|
import com.jakewharton.rxbinding.support.v7.widget.queryTextChanges
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.backup.BackupRestoreService
|
import eu.kanade.tachiyomi.data.backup.BackupRestoreService
|
||||||
@ -31,6 +36,9 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(),
|
|||||||
RecentlyReadAdapter.OnCoverClickListener,
|
RecentlyReadAdapter.OnCoverClickListener,
|
||||||
RemoveHistoryDialog.Listener {
|
RemoveHistoryDialog.Listener {
|
||||||
|
|
||||||
|
init {
|
||||||
|
setHasOptionsMenu(true)
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Adapter containing the recent manga.
|
* Adapter containing the recent manga.
|
||||||
*/
|
*/
|
||||||
@ -41,6 +49,7 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(),
|
|||||||
* Endless loading item.
|
* Endless loading item.
|
||||||
*/
|
*/
|
||||||
private var progressItem: ProgressItem? = null
|
private var progressItem: ProgressItem? = null
|
||||||
|
private var query = ""
|
||||||
|
|
||||||
override fun getTitle(): String? {
|
override fun getTitle(): String? {
|
||||||
return resources?.getString(R.string.label_recent_manga)
|
return resources?.getString(R.string.label_recent_manga)
|
||||||
@ -116,7 +125,7 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(),
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
val adapter = adapter ?: return
|
val adapter = adapter ?: return
|
||||||
presenter.requestNext(adapter.itemCount)
|
presenter.requestNext(adapter.itemCount, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun noMoreLoad(newItemsSize: Int) { }
|
override fun noMoreLoad(newItemsSize: Int) { }
|
||||||
@ -154,5 +163,32 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(),
|
|||||||
presenter.removeFromHistory(history)
|
presenter.removeFromHistory(history)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
|
inflater.inflate(R.menu.recently_read, menu)
|
||||||
|
val searchItem = menu.findItem(R.id.action_search)
|
||||||
|
val searchView = searchItem.actionView as SearchView
|
||||||
|
searchView.maxWidth = Int.MAX_VALUE
|
||||||
|
if (query.isNotEmpty()) {
|
||||||
|
searchItem.expandActionView()
|
||||||
|
searchView.setQuery(query, true)
|
||||||
|
searchView.clearFocus()
|
||||||
|
}
|
||||||
|
searchView.queryTextChanges().filter { router.backstack.lastOrNull()?.controller() == this }
|
||||||
|
.subscribeUntilDestroy {
|
||||||
|
query = it.toString()
|
||||||
|
presenter.updateList(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fixes problem with the overflow icon showing up in lieu of search
|
||||||
|
searchItem.setOnActionExpandListener(object : MenuItem.OnActionExpandListener {
|
||||||
|
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
|
||||||
|
activity?.invalidateOptionsMenu()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ class RecentlyReadPresenter : BasePresenter<RecentlyReadController>() {
|
|||||||
*/
|
*/
|
||||||
val db: DatabaseHelper by injectLazy()
|
val db: DatabaseHelper by injectLazy()
|
||||||
var lastCount = 25
|
var lastCount = 25
|
||||||
|
var lastSearch = ""
|
||||||
|
|
||||||
override fun onCreate(savedState: Bundle?) {
|
override fun onCreate(savedState: Bundle?) {
|
||||||
super.onCreate(savedState)
|
super.onCreate(savedState)
|
||||||
@ -36,9 +37,10 @@ class RecentlyReadPresenter : BasePresenter<RecentlyReadController>() {
|
|||||||
updateList()
|
updateList()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun requestNext(offset: Int) {
|
fun requestNext(offset: Int, search: String = "") {
|
||||||
lastCount = offset
|
lastCount = offset
|
||||||
getRecentMangaObservable((offset))
|
lastSearch = search
|
||||||
|
getRecentMangaObservable((offset), search)
|
||||||
.subscribeLatestCache({ view, mangas ->
|
.subscribeLatestCache({ view, mangas ->
|
||||||
view.onNextManga(mangas)
|
view.onNextManga(mangas)
|
||||||
}, RecentlyReadController::onAddPageError)
|
}, RecentlyReadController::onAddPageError)
|
||||||
@ -48,13 +50,13 @@ class RecentlyReadPresenter : BasePresenter<RecentlyReadController>() {
|
|||||||
* Get recent manga observable
|
* Get recent manga observable
|
||||||
* @return list of history
|
* @return list of history
|
||||||
*/
|
*/
|
||||||
private fun getRecentMangaObservable(offset: Int = 0): Observable<List<RecentlyReadItem>> {
|
private fun getRecentMangaObservable(offset: Int = 0, search: String = ""): Observable<List<RecentlyReadItem>> {
|
||||||
// Set date for recent manga
|
// Set date for recent manga
|
||||||
val cal = Calendar.getInstance()
|
val cal = Calendar.getInstance()
|
||||||
cal.time = Date()
|
cal.time = Date()
|
||||||
cal.add(Calendar.YEAR, -50)
|
cal.add(Calendar.YEAR, -50)
|
||||||
|
|
||||||
return db.getRecentManga(cal.time, offset).asRxObservable()
|
return db.getRecentManga(cal.time, offset, search).asRxObservable()
|
||||||
.map { recents -> recents.map(::RecentlyReadItem) }
|
.map { recents -> recents.map(::RecentlyReadItem) }
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
}
|
||||||
@ -63,13 +65,13 @@ class RecentlyReadPresenter : BasePresenter<RecentlyReadController>() {
|
|||||||
* Get recent manga observable
|
* Get recent manga observable
|
||||||
* @return list of history
|
* @return list of history
|
||||||
*/
|
*/
|
||||||
private fun getRecentMangaLimitObservable(offset: Int = 0): Observable<List<RecentlyReadItem>> {
|
private fun getRecentMangaLimitObservable(offset: Int = 0, search: String = ""): Observable<List<RecentlyReadItem>> {
|
||||||
// Set date for recent manga
|
// Set date for recent manga
|
||||||
val cal = Calendar.getInstance()
|
val cal = Calendar.getInstance()
|
||||||
cal.time = Date()
|
cal.time = Date()
|
||||||
cal.add(Calendar.YEAR, -50)
|
cal.add(Calendar.YEAR, -50)
|
||||||
|
|
||||||
return db.getRecentMangaLimit(cal.time, lastCount).asRxObservable()
|
return db.getRecentMangaLimit(cal.time, lastCount, search).asRxObservable()
|
||||||
.map { recents -> recents.map(::RecentlyReadItem) }
|
.map { recents -> recents.map(::RecentlyReadItem) }
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
}
|
||||||
@ -84,9 +86,9 @@ class RecentlyReadPresenter : BasePresenter<RecentlyReadController>() {
|
|||||||
updateList()
|
updateList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateList(search: String? = null) {
|
||||||
fun updateList() {
|
lastSearch = search?:lastSearch
|
||||||
getRecentMangaLimitObservable(lastCount).take(1)
|
getRecentMangaLimitObservable(lastCount, lastSearch).take(1)
|
||||||
.subscribeLatestCache({ view, mangas ->
|
.subscribeLatestCache({ view, mangas ->
|
||||||
view.onNextManga(mangas, true)
|
view.onNextManga(mangas, true)
|
||||||
}, RecentlyReadController::onAddPageError)
|
}, RecentlyReadController::onAddPageError)
|
||||||
|
10
app/src/main/res/menu/recently_read.xml
Normal file
10
app/src/main/res/menu/recently_read.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?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_search"
|
||||||
|
android:icon="@drawable/ic_search_white_24dp"
|
||||||
|
android:title="@string/action_search"
|
||||||
|
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||||
|
app:showAsAction="ifRoom|collapseActionView" />
|
||||||
|
|
||||||
|
</menu>
|
Loading…
Reference in New Issue
Block a user