Add history date section headers

This commit is contained in:
arkon 2020-03-06 23:13:48 -05:00
parent 29eb87b7ef
commit 52434819c3
11 changed files with 59 additions and 43 deletions

View File

@ -19,7 +19,7 @@ import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.main.ChangelogDialogController
import eu.kanade.tachiyomi.ui.setting.SettingsController
import eu.kanade.tachiyomi.util.lang.launchNow
import eu.kanade.tachiyomi.util.lang.toTimestampString
import eu.kanade.tachiyomi.util.lang.toDateTimestampString
import eu.kanade.tachiyomi.util.preference.defaultValue
import eu.kanade.tachiyomi.util.preference.onChange
import eu.kanade.tachiyomi.util.preference.onClick
@ -180,7 +180,7 @@ class AboutController : SettingsController() {
DateFormat.MEDIUM, DateFormat.SHORT, Locale.getDefault())
outputDf.timeZone = TimeZone.getDefault()
return buildTime.toTimestampString(dateFormat)
return buildTime.toDateTimestampString(dateFormat)
} catch (e: ParseException) {
return BuildConfig.BUILD_TIME
}

View File

@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.ui.recent.updates
package eu.kanade.tachiyomi.ui.recent
import android.text.format.DateUtils
import android.view.View
@ -11,10 +11,10 @@ import eu.davidea.viewholders.FlexibleViewHolder
import eu.kanade.tachiyomi.R
import java.util.Date
class DateItem(val date: Date) : AbstractHeaderItem<DateItem.Holder>() {
class DateSectionItem(val date: Date) : AbstractHeaderItem<DateSectionItem.Holder>() {
override fun getLayoutRes(): Int {
return R.layout.updates_section_item
return R.layout.recent_section_item
}
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): Holder {
@ -27,7 +27,7 @@ class DateItem(val date: Date) : AbstractHeaderItem<DateItem.Holder>() {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other is DateItem) {
if (other is DateSectionItem) {
return date == other.date
}
return false
@ -43,7 +43,7 @@ class DateItem(val date: Date) : AbstractHeaderItem<DateItem.Holder>() {
val section_text: TextView = view.findViewById(R.id.section_text)
fun bind(item: DateItem) {
fun bind(item: DateSectionItem) {
section_text.text = DateUtils.getRelativeTimeSpanString(item.date.time, now, DateUtils.DAY_IN_MILLIS)
}
}

View File

@ -1,10 +1,7 @@
package eu.kanade.tachiyomi.ui.recent.history
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.source.SourceManager
import java.text.DateFormat
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
import uy.kohesive.injekt.injectLazy
@ -34,9 +31,10 @@ class HistoryAdapter(controller: HistoryController) :
val decimalFormat = DecimalFormat("#.###", DecimalFormatSymbols()
.apply { decimalSeparator = '.' })
private val preferences: PreferencesHelper by injectLazy()
val dateFormat: DateFormat = preferences.dateFormat().getOrDefault()
init {
setDisplayHeadersAtStartUp(true)
setStickyHeaders(true)
}
interface OnResumeClickListener {
fun onResumeClick(position: Int)

View File

@ -61,7 +61,7 @@ class HistoryHolder(
.format(adapter.sourceManager.getOrStub(manga.source).toString(), formattedNumber)
// Set last read timestamp title
last_read.text = Date(history.last_read).toTimestampString(adapter.dateFormat)
last_read.text = Date(history.last_read).toTimestampString()
// Set cover
GlideApp.with(itemView.context).clear(cover)

View File

@ -3,12 +3,14 @@ package eu.kanade.tachiyomi.ui.recent.history
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import eu.davidea.flexibleadapter.items.AbstractSectionableItem
import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
import eu.kanade.tachiyomi.ui.recent.DateSectionItem
class HistoryItem(val mch: MangaChapterHistory) : AbstractFlexibleItem<HistoryHolder>() {
class HistoryItem(val mch: MangaChapterHistory, header: DateSectionItem) :
AbstractSectionableItem<HistoryHolder, DateSectionItem>(header) {
override fun getLayoutRes(): Int {
return R.layout.history_item
@ -24,7 +26,6 @@ class HistoryItem(val mch: MangaChapterHistory) : AbstractFlexibleItem<HistoryHo
position: Int,
payloads: List<Any?>?
) {
holder.bind(mch)
}

View File

@ -5,10 +5,14 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.History
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.recent.DateSectionItem
import eu.kanade.tachiyomi.util.lang.toDateKey
import java.util.Calendar
import java.util.Comparator
import java.util.Date
import java.util.TreeMap
import rx.Observable
import rx.android.schedulers.AndroidSchedulers
import uy.kohesive.injekt.injectLazy
@ -38,13 +42,21 @@ class HistoryPresenter : BasePresenter<HistoryController>() {
* @return list of history
*/
fun getRecentMangaObservable(): Observable<List<HistoryItem>> {
// Set date for recent manga
// Set date limit for recent manga
val cal = Calendar.getInstance()
cal.time = Date()
cal.add(Calendar.MONTH, -1)
return db.getRecentManga(cal.time).asRxObservable()
.map { recents -> recents.map(::HistoryItem) }
.map { recents ->
val map = TreeMap<Date, MutableList<MangaChapterHistory>> { d1, d2 -> d2.compareTo(d1) }
val byDay = recents
.groupByTo(map, { it.history.last_read.toDateKey() })
byDay.flatMap {
val dateItem = DateSectionItem(it.key)
it.value.map { HistoryItem(it, dateItem) }
}
}
.observeOn(AndroidSchedulers.mainThread())
}

View File

@ -9,9 +9,10 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.ui.recent.DateSectionItem
class UpdatesItem(val chapter: Chapter, val manga: Manga, header: DateItem) :
AbstractSectionableItem<UpdatesHolder, DateItem>(header) {
class UpdatesItem(val chapter: Chapter, val manga: Manga, header: DateSectionItem) :
AbstractSectionableItem<UpdatesHolder, DateSectionItem>(header) {
private var _status: Int = 0
@ -41,7 +42,6 @@ class UpdatesItem(val chapter: Chapter, val manga: Manga, header: DateItem) :
position: Int,
payloads: List<Any?>?
) {
holder.bind(this)
}

View File

@ -8,6 +8,8 @@ import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.recent.DateSectionItem
import eu.kanade.tachiyomi.util.lang.toDateKey
import java.util.Calendar
import java.util.Date
import java.util.TreeMap
@ -60,9 +62,9 @@ class UpdatesPresenter(
.map { mangaChapters ->
val map = TreeMap<Date, MutableList<MangaChapter>> { d1, d2 -> d2.compareTo(d1) }
val byDay = mangaChapters
.groupByTo(map, { getMapKey(it.chapter.date_fetch) })
.groupByTo(map, { it.chapter.date_fetch.toDateKey() })
byDay.flatMap {
val dateItem = DateItem(it.key)
val dateItem = DateSectionItem(it.key)
it.value
.sortedWith(compareBy({ it.chapter.date_fetch }, { it.chapter.chapter_number })).asReversed()
.map { UpdatesItem(it.chapter, it.manga, dateItem) }
@ -84,22 +86,6 @@ class UpdatesPresenter(
}
}
/**
* Get date as time key
*
* @param date desired date
* @return date as time key
*/
private fun getMapKey(date: Long): Date {
val cal = Calendar.getInstance()
cal.time = Date(date)
cal[Calendar.HOUR_OF_DAY] = 0
cal[Calendar.MINUTE] = 0
cal[Calendar.SECOND] = 0
cal[Calendar.MILLISECOND] = 0
return cal.time
}
/**
* Returns observable containing chapter status.
*

View File

@ -1,10 +1,31 @@
package eu.kanade.tachiyomi.util.lang
import java.text.DateFormat
import java.util.Calendar
import java.util.Date
fun Date.toTimestampString(dateFormatter: DateFormat): String {
fun Date.toDateTimestampString(dateFormatter: DateFormat): String {
val date = dateFormatter.format(this)
val time = DateFormat.getTimeInstance(DateFormat.SHORT).format(this)
return "$date $time"
}
fun Date.toTimestampString(): String {
return DateFormat.getTimeInstance(DateFormat.SHORT).format(this)
}
/**
* Get date as time key
*
* @param date desired date
* @return date as time key
*/
fun Long.toDateKey(): Date {
val cal = Calendar.getInstance()
cal.time = Date(this)
cal[Calendar.HOUR_OF_DAY] = 0
cal[Calendar.MINUTE] = 0
cal[Calendar.SECOND] = 0
cal[Calendar.MILLISECOND] = 0
return cal.time
}

View File

@ -10,8 +10,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingTop="4dp"
android:paddingBottom="4dp"
tools:listitem="@layout/history_item" />
<eu.kanade.tachiyomi.widget.EmptyView