Added recently read tab (#316)

This commit is contained in:
Bram van de Kerkhof
2016-06-06 15:26:56 +02:00
parent 11262f86f9
commit 7ba898f701
38 changed files with 932 additions and 38 deletions
@@ -1,128 +0,0 @@
package eu.kanade.tachiyomi.ui.recent
import android.support.v7.widget.RecyclerView
import android.view.View
import android.view.ViewGroup
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.MangaChapter
import eu.kanade.tachiyomi.util.inflate
import java.util.*
/**
* Adapter of RecentChaptersHolder.
* Connection between Fragment and Holder
* Holder updates should be called from here.
*
* @param fragment a RecentChaptersFragment object
* @constructor creates an instance of the adapter.
*/
class RecentChaptersAdapter(val fragment: RecentChaptersFragment) : FlexibleAdapter<RecyclerView.ViewHolder, Any>() {
/**
* The id of the view type
*/
private val VIEW_TYPE_CHAPTER = 0
/**
* The id of the view type
*/
private val VIEW_TYPE_SECTION = 1
init {
// Let each each item in the data set be represented with a unique identifier.
setHasStableIds(true)
}
/**
* Called when ViewHolder is bind
*
* @param holder bind holder
* @param position position of holder
*/
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
// Check which view type and set correct values.
val item = getItem(position)
when (holder.itemViewType) {
VIEW_TYPE_CHAPTER -> {
if (item is MangaChapter) {
(holder as RecentChaptersHolder).onSetValues(item)
}
}
VIEW_TYPE_SECTION -> {
if (item is Date) {
(holder as SectionViewHolder).onSetValues(item)
}
}
}
//When user scrolls this bind the correct selection status
holder.itemView.isActivated = isSelected(position)
}
/**
* Called when ViewHolder is created
*
* @param parent parent View
* @param viewType int containing viewType
*/
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder? {
val view: View
// Check which view type and set correct values.
when (viewType) {
VIEW_TYPE_CHAPTER -> {
view = parent.inflate(R.layout.item_recent_chapter)
return RecentChaptersHolder(view, this, fragment)
}
VIEW_TYPE_SECTION -> {
view = parent.inflate(R.layout.item_recent_chapter_section)
return SectionViewHolder(view)
}
}
return null
}
/**
* Returns the correct ViewType
*
* @param position position of item
*/
override fun getItemViewType(position: Int): Int {
return if (getItem(position) is MangaChapter) VIEW_TYPE_CHAPTER else VIEW_TYPE_SECTION
}
/**
* Update items
* @param items items
*/
fun setItems(items: List<Any>) {
mItems = items
notifyDataSetChanged()
}
/**
* Needed to determine holder id
*
* @param position position of holder item
*/
override fun getItemId(position: Int): Long {
val item = getItem(position)
if (item is MangaChapter)
return item.chapter.id
else
return item.hashCode().toLong()
}
/**
* Abstract function (not needed).
*
* @param p0 a string.
*/
override fun updateDataSet(p0: String) {
// Empty function.
}
}
@@ -1,316 +0,0 @@
package eu.kanade.tachiyomi.ui.recent
import android.os.Bundle
import android.support.v4.app.DialogFragment
import android.support.v7.view.ActionMode
import android.view.*
import com.afollestad.materialdialogs.MaterialDialog
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.MangaChapter
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder
import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.getResourceDrawable
import eu.kanade.tachiyomi.util.toast
import eu.kanade.tachiyomi.widget.DeletingChaptersDialog
import eu.kanade.tachiyomi.widget.DividerItemDecoration
import eu.kanade.tachiyomi.widget.NpaLinearLayoutManager
import kotlinx.android.synthetic.main.fragment_recent_chapters.*
import nucleus.factory.RequiresPresenter
import timber.log.Timber
/**
* Fragment that shows recent chapters.
* Uses [R.layout.fragment_recent_chapters].
* UI related actions should be called from here.
*/
@RequiresPresenter(RecentChaptersPresenter::class)
class RecentChaptersFragment : BaseRxFragment<RecentChaptersPresenter>(), ActionMode.Callback, FlexibleViewHolder.OnListItemClickListener {
companion object {
/**
* Create new RecentChaptersFragment.
* @return a new instance of [RecentChaptersFragment].
*/
@JvmStatic
fun newInstance(): RecentChaptersFragment {
return RecentChaptersFragment()
}
}
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
return false
}
/**
* Called when ActionMode item clicked
* @param mode the ActionMode object
* @param item item from ActionMode.
*/
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_mark_as_read -> markAsRead(getSelectedChapters())
R.id.action_mark_as_unread -> markAsUnread(getSelectedChapters())
R.id.action_download -> downloadChapters(getSelectedChapters())
R.id.action_delete -> {
MaterialDialog.Builder(activity)
.content(R.string.confirm_delete_chapters)
.positiveText(android.R.string.yes)
.negativeText(android.R.string.no)
.onPositive { dialog, action -> deleteChapters(getSelectedChapters()) }
.show()
}
else -> return false
}
return true
}
/**
* Called when ActionMode created.
* @param mode the ActionMode object
* @param menu menu object of ActionMode
*/
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.chapter_recent_selection, menu)
adapter.mode = FlexibleAdapter.MODE_MULTI
return true
}
/**
* Called when ActionMode destroyed
* @param mode the ActionMode object
*/
override fun onDestroyActionMode(mode: ActionMode?) {
adapter.mode = FlexibleAdapter.MODE_SINGLE
adapter.clearSelection()
actionMode = null
}
/**
* Action mode for multiple selection.
*/
private var actionMode: ActionMode? = null
/**
* Adapter containing the recent chapters.
*/
lateinit var adapter: RecentChaptersAdapter
private set
/**
* Called when view gets created
* @param inflater layout inflater
* @param container view group
* @param savedState status of saved state
*/
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedState: Bundle?): View? {
// Inflate view
return inflater.inflate(R.layout.fragment_recent_chapters, container, false)
}
/**
* Called when view is created
* @param view created view
* @param savedInstanceState status of saved sate
*/
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
// Init RecyclerView and adapter
recycler.layoutManager = NpaLinearLayoutManager(activity)
recycler.addItemDecoration(DividerItemDecoration(context.theme.getResourceDrawable(R.attr.divider_drawable)))
recycler.setHasFixedSize(true)
adapter = RecentChaptersAdapter(this)
recycler.adapter = adapter
// Update toolbar text
setToolbarTitle(R.string.label_recent_updates)
}
/**
* Returns selected chapters
* @return list of [MangaChapter]s
*/
fun getSelectedChapters(): List<MangaChapter> {
return adapter.selectedItems.map { adapter.getItem(it) as? MangaChapter }.filterNotNull()
}
/**
* Called when item in list is clicked
* @param position position of clicked item
*/
override fun onListItemClick(position: Int): Boolean {
// Get item from position
val item = adapter.getItem(position)
if (item is MangaChapter) {
if (actionMode != null && adapter.mode == FlexibleAdapter.MODE_MULTI) {
toggleSelection(position)
return true
} else {
openChapter(item)
return false
}
}
return false
}
/**
* Called when item in list is long clicked
* @param position position of clicked item
*/
override fun onListItemLongClick(position: Int) {
if (actionMode == null)
actionMode = activity.startSupportActionMode(this)
toggleSelection(position)
}
/**
* Called to toggle selection
* @param position position of selected item
*/
private fun toggleSelection(position: Int) {
adapter.toggleSelection(position, false)
val count = adapter.selectedItemCount
if (count == 0) {
actionMode?.finish()
} else {
setContextTitle(count)
actionMode?.invalidate()
}
}
/**
* Set the context title
* @param count count of selected items
*/
private fun setContextTitle(count: Int) {
actionMode?.title = getString(R.string.label_selected, count)
}
/**
* Open chapter in reader
* @param mangaChapter selected [MangaChapter]
*/
private fun openChapter(mangaChapter: MangaChapter) {
val intent = ReaderActivity.newIntent(activity, mangaChapter.manga, mangaChapter.chapter)
startActivity(intent)
}
/**
* Download selected items
* @param mangaChapters list of selected [MangaChapter]s
*/
fun downloadChapters(mangaChapters: List<MangaChapter>) {
destroyActionModeIfNeeded()
presenter.downloadChapters(mangaChapters)
}
/**
* Populate adapter with chapters
* @param chapters list of [Any]
*/
fun onNextMangaChapters(chapters: List<Any>) {
(activity as MainActivity).updateEmptyView(chapters.isEmpty(),
R.string.information_no_recent, R.drawable.ic_history_black_128dp)
destroyActionModeIfNeeded()
adapter.setItems(chapters)
}
/**
* Update download status of chapter
* @param download [Download] object containing download progress.
*/
fun onChapterStatusChange(download: Download) {
getHolder(download)?.onStatusChange(download.status)
}
/**
* Returns holder belonging to chapter
* @param download [Download] object containing download progress.
*/
private fun getHolder(download: Download): RecentChaptersHolder? {
return recycler.findViewHolderForItemId(download.chapter.id) as? RecentChaptersHolder
}
/**
* Mark chapter as read
* @param mangaChapters list of [MangaChapter] objects
*/
fun markAsRead(mangaChapters: List<MangaChapter>) {
presenter.markChapterRead(mangaChapters, true)
if (presenter.preferences.removeAfterMarkedAsRead()) {
deleteChapters(mangaChapters)
}
}
/**
* Delete selected chapters
* @param mangaChapters list of [MangaChapter] objects
*/
fun deleteChapters(mangaChapters: List<MangaChapter>) {
destroyActionModeIfNeeded()
DeletingChaptersDialog().show(childFragmentManager, DeletingChaptersDialog.TAG)
presenter.deleteChapters(mangaChapters)
}
/**
* Destory [ActionMode] if it's shown
*/
fun destroyActionModeIfNeeded() {
actionMode?.finish()
}
/**
* Mark chapter as unread
* @param mangaChapters list of selected [MangaChapter]
*/
fun markAsUnread(mangaChapters: List<MangaChapter>) {
presenter.markChapterRead(mangaChapters, false)
}
/**
* Start downloading chapter
* @param item selected chapter with manga
*/
fun downloadChapter(item: MangaChapter) {
presenter.downloadChapter(item)
}
/**
* Start deleting chapter
* @param item selected chapter with manga
*/
fun deleteChapter(item: MangaChapter) {
DeletingChaptersDialog().show(childFragmentManager, DeletingChaptersDialog.TAG)
presenter.deleteChapter(item)
}
/**
* Called when chapters are deleted
*/
fun onChaptersDeleted() {
dismissDeletingDialog()
adapter.notifyDataSetChanged()
}
/**
* Called when error while deleting
* @param error error message
*/
fun onChaptersDeletedError(error: Throwable) {
dismissDeletingDialog()
Timber.e(error, error.message)
}
/**
* Called to dismiss deleting dialog
*/
fun dismissDeletingDialog() {
(childFragmentManager.findFragmentByTag(DeletingChaptersDialog.TAG) as? DialogFragment)?.dismiss()
}
}
@@ -1,136 +0,0 @@
package eu.kanade.tachiyomi.ui.recent
import android.view.View
import android.widget.PopupMenu
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.MangaChapter
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder
import eu.kanade.tachiyomi.util.getResourceColor
import kotlinx.android.synthetic.main.item_recent_chapter.view.*
/**
* Holder that contains chapter item
* Uses R.layout.item_recent_chapter.
* UI related actions should be called from here.
*
* @param view the inflated view for this holder.
* @param adapter the adapter handling this holder.
* @param listener a listener to react to single tap and long tap events.
* @constructor creates a new recent chapter holder.
*/
class RecentChaptersHolder(view: View, private val adapter: RecentChaptersAdapter, listener: FlexibleViewHolder.OnListItemClickListener) :
FlexibleViewHolder(view, adapter, listener) {
/**
* Color of read chapter
*/
private var readColor = view.context.theme.getResourceColor(android.R.attr.textColorHint)
/**
* Color of unread chapter
*/
private var unreadColor = view.context.theme.getResourceColor(android.R.attr.textColorPrimary)
/**
* Object containing chapter information
*/
private var mangaChapter: MangaChapter? = null
init {
// We need to post a Runnable to show the popup to make sure that the PopupMenu is
// correctly positioned. The reason being that the view may change position before the
// PopupMenu is shown.
itemView.chapter_menu.setOnClickListener { it.post({ showPopupMenu(it) }) }
}
/**
* Set values of view
*
* @param item item containing chapter information
*/
fun onSetValues(item: MangaChapter) {
this.mangaChapter = item
// Set chapter title
itemView.chapter_title.text = item.chapter.name
// Set manga title
itemView.manga_title.text = item.manga.title
// Check if chapter is read and set correct color
if (item.chapter.read) {
itemView.chapter_title.setTextColor(readColor)
itemView.manga_title.setTextColor(readColor)
} else {
itemView.chapter_title.setTextColor(unreadColor)
itemView.manga_title.setTextColor(unreadColor)
}
// Set chapter status
onStatusChange(item.chapter.status)
}
/**
* Updates chapter status in view.
* @param status download status
*/
fun onStatusChange(status: Int) {
when (status) {
Download.QUEUE -> itemView.download_text.setText(R.string.chapter_queued)
Download.DOWNLOADING -> itemView.download_text.setText(R.string.chapter_downloading)
Download.DOWNLOADED -> itemView.download_text.setText(R.string.chapter_downloaded)
Download.ERROR -> itemView.download_text.setText(R.string.chapter_error)
else -> itemView.download_text.text = ""
}
}
/**
* Show pop up menu
* @param view view containing popup menu.
*/
private fun showPopupMenu(view: View) {
// Create a PopupMenu, giving it the clicked view for an anchor
val popup = PopupMenu(adapter.fragment.activity, view)
// Inflate our menu resource into the PopupMenu's Menu
popup.menuInflater.inflate(R.menu.chapter_recent, popup.menu)
mangaChapter?.let {
// Hide download and show delete if the chapter is downloaded and
if (it.chapter.isDownloaded) {
val menu = popup.menu
menu.findItem(R.id.action_download).isVisible = false
menu.findItem(R.id.action_delete).isVisible = true
}
// Hide mark as unread when the chapter is unread
if (!it.chapter.read /*&& mangaChapter.chapter.last_page_read == 0*/) {
popup.menu.findItem(R.id.action_mark_as_unread).isVisible = false
}
// Hide mark as read when the chapter is read
if (it.chapter.read) {
popup.menu.findItem(R.id.action_mark_as_read).isVisible = false
}
// Set a listener so we are notified if a menu item is clicked
popup.setOnMenuItemClickListener { menuItem ->
when (menuItem.itemId) {
R.id.action_download -> adapter.fragment.downloadChapter(it)
R.id.action_delete -> adapter.fragment.deleteChapter(it)
R.id.action_mark_as_read -> adapter.fragment.markAsRead(listOf(it))
R.id.action_mark_as_unread -> adapter.fragment.markAsUnread(listOf(it))
}
true
}
}
// Finally show the PopupMenu
popup.show()
}
}
@@ -1,346 +0,0 @@
package eu.kanade.tachiyomi.ui.recent
import android.os.Bundle
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaChapter
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.source.SourceManager
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import rx.Observable
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import timber.log.Timber
import java.util.*
import javax.inject.Inject
class RecentChaptersPresenter : BasePresenter<RecentChaptersFragment>() {
/**
* Used to connect to database
*/
@Inject lateinit var db: DatabaseHelper
/**
* Used to get settings
*/
@Inject lateinit var preferences: PreferencesHelper
/**
* Used to get information from download manager
*/
@Inject lateinit var downloadManager: DownloadManager
/**
* Used to get source from source id
*/
@Inject lateinit var sourceManager: SourceManager
/**
* List containing chapter and manga information
*/
private var mangaChapters: List<MangaChapter>? = null
/**
* The id of the restartable.
*/
val GET_RECENT_CHAPTERS = 1
/**
* The id of the restartable.
*/
val CHAPTER_STATUS_CHANGES = 2
override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState)
// Used to get recent chapters
restartableLatestCache(GET_RECENT_CHAPTERS,
{ getRecentChaptersObservable() },
{ fragment, chapters ->
// Update adapter to show recent manga's
fragment.onNextMangaChapters(chapters)
// Update download status
updateChapterStatus(convertToMangaChaptersList(chapters))
}
)
// Used to update download status
startableLatestCache(CHAPTER_STATUS_CHANGES,
{ getChapterStatusObs() },
{ recentChaptersFragment, download ->
// Set chapter status
recentChaptersFragment.onChapterStatusChange(download)
},
{ view, error -> Timber.e(error.cause, error.message) }
)
if (savedState == null) {
// Start fetching recent chapters
start(GET_RECENT_CHAPTERS)
}
}
/**
* Returns observable containing chapter status.
* @return download object containing download progress.
*/
private fun getChapterStatusObs(): Observable<Download> {
return downloadManager.queue.getStatusObservable()
.observeOn(AndroidSchedulers.mainThread())
.filter { download: Download ->
if (chapterIdEquals(download.chapter.id))
true
else
false
}
.doOnNext { download1: Download -> updateChapterStatus(download1) }
}
/**
* Function to check if chapter is in recent list
* @param chaptersId id of chapter
* @return exist in recent list
*/
private fun chapterIdEquals(chaptersId: Long): Boolean {
mangaChapters!!.forEach { mangaChapter ->
if (chaptersId == mangaChapter.chapter.id) {
return true
}
}
return false
}
/**
* Returns a list only containing MangaChapter objects.
* @param input the list that will be converted.
* @return list containing MangaChapters objects.
*/
private fun convertToMangaChaptersList(input: List<Any>): List<MangaChapter> {
// Create temp list
val tempMangaChapterList = ArrayList<MangaChapter>()
// Only add MangaChapter objects
//noinspection Convert2streamapi
input.forEach { `object` ->
if (`object` is MangaChapter) {
tempMangaChapterList.add(`object`)
}
}
// Return temp list
return tempMangaChapterList
}
/**
* Update status of chapters.
* @param download download object containing progress.
*/
private fun updateChapterStatus(download: Download) {
// Loop through list
mangaChapters?.let {
for (item in it) {
if (download.chapter.id == item.chapter.id) {
// Update status.
item.chapter.status = download.status
break
}
}
}
}
/**
* Update status of chapters
* @param mangaChapters list containing recent chapters
*/
private fun updateChapterStatus(mangaChapters: List<MangaChapter>) {
// Set global list of chapters.
this.mangaChapters = mangaChapters
// Update status.
//noinspection Convert2streamapi
for (mangaChapter in mangaChapters)
setChapterStatus(mangaChapter)
// Start onChapterStatusChange restartable.
start(CHAPTER_STATUS_CHANGES)
}
/**
* Set the chapter status
* @param mangaChapter MangaChapter which status gets updated
*/
private fun setChapterStatus(mangaChapter: MangaChapter) {
// Check if chapter in queue
for (download in downloadManager.queue) {
if (mangaChapter.chapter.id == download.chapter.id) {
mangaChapter.chapter.status = download.status
return
}
}
// Get source of chapter
val source = sourceManager.get(mangaChapter.manga.source)!!
// Check if chapter is downloaded
if (downloadManager.isChapterDownloaded(source, mangaChapter.manga, mangaChapter.chapter)) {
mangaChapter.chapter.status = Download.DOWNLOADED
} else {
mangaChapter.chapter.status = Download.NOT_DOWNLOADED
}
}
/**
* Get observable containing recent chapters and date
* @return observable containing recent chapters and date
*/
fun getRecentChaptersObservable(): Observable<ArrayList<Any>>? {
// Set date for recent chapters
val cal = Calendar.getInstance()
cal.time = Date()
cal.add(Calendar.MONTH, -1)
return db.getRecentChapters(cal.time).asRxObservable()
// Group chapters by the date they were fetched on a ordered map.
.flatMap { recentItems ->
Observable.from(recentItems)
.toMultimap(
{ getMapKey(it.chapter.date_fetch) },
{ it },
{ TreeMap { d1, d2 -> d2.compareTo(d1) } })
}
// Add every day and all its chapters to a single list.
.map { recentItems ->
val items = ArrayList<Any>()
recentItems.entries.forEach { recent ->
items.add(recent.key)
items.addAll(recent.value)
}
items
}
.observeOn(AndroidSchedulers.mainThread())
}
/**
* 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
}
/**
* Mark selected chapter as read
* @param mangaChapters list of selected MangaChapters
* @param read read status
*/
fun markChapterRead(mangaChapters: List<MangaChapter>, read: Boolean) {
Observable.from(mangaChapters)
.doOnNext { mangaChapter ->
mangaChapter.chapter.read = read
if (!read) {
mangaChapter.chapter.last_page_read = 0
}
}
.map { mangaChapter -> mangaChapter.chapter }
.toList()
.flatMap { db.updateChaptersProgress(it).asRxObservable() }
.subscribeOn(Schedulers.io())
.subscribe()
}
/**
* Delete selected chapters
* @param chapters list of MangaChapters
*/
fun deleteChapters(chapters: List<MangaChapter>) {
val wasRunning = downloadManager.isRunning
if (wasRunning) {
DownloadService.stop(context)
}
Observable.from(chapters)
.doOnNext { deleteChapter(it) }
.toList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeFirst({ view, result ->
view.onChaptersDeleted()
if (wasRunning) {
DownloadService.start(context)
}
}, { view, error ->
view.onChaptersDeletedError(error)
})
}
/**
* Download selected chapters
* @param mangaChapters [MangaChapter] that is selected
*/
fun downloadChapters(mangaChapters: List<MangaChapter>) {
DownloadService.start(context)
Observable.from(mangaChapters)
.doOnNext { downloadChapter(it) }
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe()
}
/**
* Download selected chapter
* @param item chapter that is selected
*/
fun downloadChapter(item: MangaChapter) {
DownloadService.start(context)
downloadManager.downloadChapters(item.manga, listOf(item.chapter))
}
/**
* Delete selected chapter
* @param item chapter that are selected
*/
fun deleteChapter(item: MangaChapter) {
val wasRunning = downloadManager.isRunning
if (wasRunning) {
DownloadService.stop(context)
}
Observable.just(item)
.doOnNext { deleteChapter(it.chapter, it.manga) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeFirst({ view, result ->
view.onChaptersDeleted()
if (wasRunning) {
DownloadService.start(context)
}
}, { view, error ->
view.onChaptersDeletedError(error)
})
}
/**
* Delete selected chapter
* @param chapter chapter that is selected
* @param manga manga that belongs to chapter
*/
private fun deleteChapter(chapter: Chapter, manga: Manga) {
val source = sourceManager.get(manga.source) ?: return
downloadManager.queue.del(chapter)
downloadManager.deleteChapter(source, manga, chapter)
chapter.status = Download.NOT_DOWNLOADED
}
}
@@ -1,26 +0,0 @@
package eu.kanade.tachiyomi.ui.recent
import android.support.v7.widget.RecyclerView
import android.text.format.DateUtils
import android.view.View
import kotlinx.android.synthetic.main.item_recent_chapter_section.view.*
import java.util.*
class SectionViewHolder(view: View) : RecyclerView.ViewHolder(view) {
/**
* Current date
*/
private val now = Date().time
/**
* Set value of section header
*
* @param date of section header
*/
fun onSetValues(date: Date) {
val s = DateUtils.getRelativeTimeSpanString(
date.time, now, DateUtils.DAY_IN_MILLIS)
itemView.section_text.text = s
}
}