mirror of
https://github.com/mihonapp/mihon.git
synced 2025-11-15 21:47:28 +01:00
Add Start/Finish date support for MAL (#2672)
* Started working on MAL support * Added date picker UI * Replaced Date with Calendar * Added MAL remote update functionality * Join url methods listEntryUrl and editUrl * Removed unused methods * Renamed mangaEditPayload to mangaEditPostBody * Moved code to separate method * Uniformed code to project conventions * Removed wildcard import * Moved MyAnimeListTrack to private class * Improved MyAnimeListTrack name * Removed redundant code * Add start/finish date in local database * Fixed format and improved codestyle * Fixed typo and fixed TrackHolder's format * Improved code style * Ran linter * Add database updating methods * Change date format to fit new layout * Review Commits * Improve SetTrackReadingDatesDialog readability * Move private methods after public ones * Fixed SQL error * Fixed remove date button * Updated MaterialDesign methods to latest version * Replaced dismissDialog() with dialog.Dismiss() * Fixed wrong string resource usage.
This commit is contained in:
committed by
GitHub
parent
c967308859
commit
f7c139030f
@@ -0,0 +1,127 @@
|
||||
package eu.kanade.tachiyomi.ui.manga.track
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.widget.NumberPicker
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.customview.customView
|
||||
import com.afollestad.materialdialogs.customview.getCustomView
|
||||
import com.bluelinelabs.conductor.Controller
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Track
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import java.text.DateFormatSymbols
|
||||
import java.util.Calendar
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class SetTrackReadingDatesDialog<T> : DialogController
|
||||
where T : Controller, T : SetTrackReadingDatesDialog.Listener {
|
||||
|
||||
private val item: TrackItem
|
||||
|
||||
private val dateToUpdate: ReadingDate
|
||||
|
||||
constructor(target: T, dateToUpdate: ReadingDate, item: TrackItem) : super(Bundle().apply {
|
||||
putSerializable(SetTrackReadingDatesDialog.KEY_ITEM_TRACK, item.track)
|
||||
}) {
|
||||
targetController = target
|
||||
this.item = item
|
||||
this.dateToUpdate = dateToUpdate
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
constructor(bundle: Bundle) : super(bundle) {
|
||||
val track = bundle.getSerializable(SetTrackReadingDatesDialog.KEY_ITEM_TRACK) as Track
|
||||
val service = Injekt.get<TrackManager>().getService(track.sync_id)!!
|
||||
item = TrackItem(track, service)
|
||||
dateToUpdate = ReadingDate.Start
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
||||
val item = item
|
||||
|
||||
val dialog = MaterialDialog(activity!!)
|
||||
.title(when (dateToUpdate) {
|
||||
ReadingDate.Start -> R.string.track_started_reading_date
|
||||
ReadingDate.Finish -> R.string.track_finished_reading_date
|
||||
})
|
||||
.customView(R.layout.track_date_dialog, dialogWrapContent = false)
|
||||
.positiveButton(android.R.string.ok) { dialog ->
|
||||
onDialogConfirm(dialog)
|
||||
}
|
||||
.negativeButton(android.R.string.cancel) { dialog ->
|
||||
dialog.dismiss()
|
||||
}
|
||||
.neutralButton(R.string.action_remove) { dialog ->
|
||||
val listener = (targetController as? Listener)
|
||||
listener?.setReadingDate(item, dateToUpdate, 0L)
|
||||
dialog.dismiss()
|
||||
}
|
||||
.noAutoDismiss()
|
||||
|
||||
onDialogCreated(dialog)
|
||||
|
||||
return dialog
|
||||
}
|
||||
|
||||
private fun onDialogCreated(dialog: MaterialDialog) {
|
||||
val view = dialog.getCustomView()
|
||||
|
||||
val dayPicker: NumberPicker = view.findViewById(R.id.day_picker)
|
||||
val monthPicker: NumberPicker = view.findViewById(R.id.month_picker)
|
||||
val yearPicker: NumberPicker = view.findViewById(R.id.year_picker)
|
||||
|
||||
val monthNames: Array<String> = DateFormatSymbols().months
|
||||
monthPicker.displayedValues = monthNames
|
||||
|
||||
val calendar = Calendar.getInstance()
|
||||
item.track?.let {
|
||||
val date = when (dateToUpdate) {
|
||||
ReadingDate.Start -> it.started_reading_date
|
||||
ReadingDate.Finish -> it.finished_reading_date
|
||||
}
|
||||
if (date != 0L)
|
||||
calendar.timeInMillis = date
|
||||
}
|
||||
dayPicker.value = calendar[Calendar.DAY_OF_MONTH]
|
||||
monthPicker.value = calendar[Calendar.MONTH]
|
||||
yearPicker.maxValue = calendar[Calendar.YEAR]
|
||||
yearPicker.value = calendar[Calendar.YEAR]
|
||||
}
|
||||
|
||||
private fun onDialogConfirm(dialog: MaterialDialog) {
|
||||
val view = dialog.getCustomView()
|
||||
|
||||
val dayPicker: NumberPicker = view.findViewById(R.id.day_picker)
|
||||
val monthPicker: NumberPicker = view.findViewById(R.id.month_picker)
|
||||
val yearPicker: NumberPicker = view.findViewById(R.id.year_picker)
|
||||
|
||||
try {
|
||||
val calendar = Calendar.getInstance().apply { isLenient = false }
|
||||
calendar.set(yearPicker.value, monthPicker.value, dayPicker.value)
|
||||
calendar.time = calendar.time // Throws if invalid
|
||||
|
||||
val listener = (targetController as? Listener)
|
||||
listener?.setReadingDate(item, dateToUpdate, calendar.timeInMillis)
|
||||
dialog.dismiss()
|
||||
} catch (e: Exception) {
|
||||
activity?.toast(R.string.error_invalid_date_supplied)
|
||||
}
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
fun setReadingDate(item: TrackItem, type: ReadingDate, date: Long)
|
||||
}
|
||||
|
||||
enum class ReadingDate {
|
||||
Start,
|
||||
Finish
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val KEY_ITEM_TRACK = "SetTrackReadingDatesDialog.item.track"
|
||||
}
|
||||
}
|
||||
@@ -40,5 +40,7 @@ class TrackAdapter(controller: TrackController) : RecyclerView.Adapter<TrackHold
|
||||
fun onStatusClick(position: Int)
|
||||
fun onChaptersClick(position: Int)
|
||||
fun onScoreClick(position: Int)
|
||||
fun onStartDateClick(position: Int)
|
||||
fun onFinishDateClick(position: Int)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@ class TrackController : NucleusController<TrackControllerBinding, TrackPresenter
|
||||
TrackAdapter.OnClickListener,
|
||||
SetTrackStatusDialog.Listener,
|
||||
SetTrackChaptersDialog.Listener,
|
||||
SetTrackScoreDialog.Listener {
|
||||
SetTrackScoreDialog.Listener,
|
||||
SetTrackReadingDatesDialog.Listener {
|
||||
|
||||
private var adapter: TrackAdapter? = null
|
||||
|
||||
@@ -123,6 +124,20 @@ class TrackController : NucleusController<TrackControllerBinding, TrackPresenter
|
||||
SetTrackScoreDialog(this, item).showDialog(router)
|
||||
}
|
||||
|
||||
override fun onStartDateClick(position: Int) {
|
||||
val item = adapter?.getItem(position) ?: return
|
||||
if (item.track == null) return
|
||||
|
||||
SetTrackReadingDatesDialog(this, SetTrackReadingDatesDialog.ReadingDate.Start, item).showDialog(router)
|
||||
}
|
||||
|
||||
override fun onFinishDateClick(position: Int) {
|
||||
val item = adapter?.getItem(position) ?: return
|
||||
if (item.track == null) return
|
||||
|
||||
SetTrackReadingDatesDialog(this, SetTrackReadingDatesDialog.ReadingDate.Finish, item).showDialog(router)
|
||||
}
|
||||
|
||||
override fun setStatus(item: TrackItem, selection: Int) {
|
||||
presenter.setStatus(item, selection)
|
||||
binding.swipeRefresh.isRefreshing = true
|
||||
@@ -138,6 +153,14 @@ class TrackController : NucleusController<TrackControllerBinding, TrackPresenter
|
||||
binding.swipeRefresh.isRefreshing = true
|
||||
}
|
||||
|
||||
override fun setReadingDate(item: TrackItem, type: SetTrackReadingDatesDialog.ReadingDate, date: Long) {
|
||||
when (type) {
|
||||
SetTrackReadingDatesDialog.ReadingDate.Start -> presenter.setStartDate(item, date)
|
||||
SetTrackReadingDatesDialog.ReadingDate.Finish -> presenter.setFinishDate(item, date)
|
||||
}
|
||||
binding.swipeRefresh.isRefreshing = true
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val TAG_SEARCH_CONTROLLER = "track_search_controller"
|
||||
}
|
||||
|
||||
@@ -2,19 +2,34 @@ package eu.kanade.tachiyomi.ui.manga.track
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.View
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.ui.base.holder.BaseViewHolder
|
||||
import eu.kanade.tachiyomi.util.view.gone
|
||||
import eu.kanade.tachiyomi.util.view.visibleIf
|
||||
import java.text.DateFormat
|
||||
import kotlinx.android.synthetic.main.track_item.bottom_divider
|
||||
import kotlinx.android.synthetic.main.track_item.logo_container
|
||||
import kotlinx.android.synthetic.main.track_item.track_chapters
|
||||
import kotlinx.android.synthetic.main.track_item.track_details
|
||||
import kotlinx.android.synthetic.main.track_item.track_finish_date
|
||||
import kotlinx.android.synthetic.main.track_item.track_logo
|
||||
import kotlinx.android.synthetic.main.track_item.track_score
|
||||
import kotlinx.android.synthetic.main.track_item.track_set
|
||||
import kotlinx.android.synthetic.main.track_item.track_start_date
|
||||
import kotlinx.android.synthetic.main.track_item.track_status
|
||||
import kotlinx.android.synthetic.main.track_item.track_title
|
||||
import kotlinx.android.synthetic.main.track_item.vert_divider_3
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class TrackHolder(view: View, adapter: TrackAdapter) : BaseViewHolder(view) {
|
||||
|
||||
private val preferences: PreferencesHelper by injectLazy()
|
||||
|
||||
private val dateFormat: DateFormat by lazy {
|
||||
preferences.dateFormat().getOrDefault()
|
||||
}
|
||||
|
||||
init {
|
||||
val listener = adapter.rowClickListener
|
||||
|
||||
@@ -24,6 +39,8 @@ class TrackHolder(view: View, adapter: TrackAdapter) : BaseViewHolder(view) {
|
||||
track_status.setOnClickListener { listener.onStatusClick(bindingAdapterPosition) }
|
||||
track_chapters.setOnClickListener { listener.onChaptersClick(bindingAdapterPosition) }
|
||||
track_score.setOnClickListener { listener.onScoreClick(bindingAdapterPosition) }
|
||||
track_start_date.setOnClickListener { listener.onStartDateClick(bindingAdapterPosition) }
|
||||
track_finish_date.setOnClickListener { listener.onFinishDateClick(bindingAdapterPosition) }
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@@ -42,6 +59,18 @@ class TrackHolder(view: View, adapter: TrackAdapter) : BaseViewHolder(view) {
|
||||
if (track.total_chapters > 0) track.total_chapters else "-"
|
||||
track_status.text = item.service.getStatus(track.status)
|
||||
track_score.text = if (track.score == 0f) "-" else item.service.displayScore(track)
|
||||
|
||||
if (item.service.supportsReadingDates) {
|
||||
track_start_date.text =
|
||||
if (track.started_reading_date != 0L) dateFormat.format(track.started_reading_date) else "-"
|
||||
track_finish_date.text =
|
||||
if (track.finished_reading_date != 0L) dateFormat.format(track.finished_reading_date) else "-"
|
||||
} else {
|
||||
bottom_divider.gone()
|
||||
vert_divider_3.gone()
|
||||
track_start_date.gone()
|
||||
track_finish_date.gone()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,4 +135,16 @@ class TrackPresenter(
|
||||
}
|
||||
updateRemote(track, item.service)
|
||||
}
|
||||
|
||||
fun setStartDate(item: TrackItem, date: Long) {
|
||||
val track = item.track!!
|
||||
track.started_reading_date = date
|
||||
updateRemote(track, item.service)
|
||||
}
|
||||
|
||||
fun setFinishDate(item: TrackItem, date: Long) {
|
||||
val track = item.track!!
|
||||
track.finished_reading_date = date
|
||||
updateRemote(track, item.service)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user