mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 16:18:55 +01:00 
			
		
		
		
	Add history date section headers
This commit is contained in:
		@@ -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
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
     *
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user