Skip to content

Commit

Permalink
Local history: add/remove entries when marking multiple episodes
Browse files Browse the repository at this point in the history
  • Loading branch information
UweTrottmann committed Mar 7, 2024
1 parent e5d9aa2 commit 77282d6
Show file tree
Hide file tree
Showing 12 changed files with 177 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.battlelancer.seriesguide.provider.SeriesGuideContract
import com.battlelancer.seriesguide.provider.SgRoomDatabase
import com.battlelancer.seriesguide.shows.database.SgEpisode2Numbers
import com.battlelancer.seriesguide.shows.episodes.EpisodeTools
import com.battlelancer.seriesguide.shows.history.SgActivityHelper
import com.battlelancer.seriesguide.shows.tools.LatestEpisodeUpdateTask
import com.google.flatbuffers.FlatBufferBuilder

Expand All @@ -37,17 +38,19 @@ abstract class BaseEpisodesJob(
*/
@CallSuper
override fun applyLocalChanges(context: Context, requiresNetworkJob: Boolean): Boolean {
val episodes: List<SgEpisode2Numbers> = getAffectedEpisodes(context)

// prepare network job
var networkJobInfo: ByteArray? = null
if (requiresNetworkJob) {
networkJobInfo = prepareNetworkJob(context)
networkJobInfo = prepareNetworkJob(episodes)
if (networkJobInfo == null) {
return false
}
}

// apply local updates
val updated = applyDatabaseChanges(context)
val updated = applyDatabaseChanges(context, episodes)
if (!updated) {
return false
}
Expand All @@ -66,24 +69,27 @@ abstract class BaseEpisodesJob(
return true
}

protected abstract fun applyDatabaseChanges(context: Context): Boolean
protected abstract fun applyDatabaseChanges(
context: Context,
episodes: List<SgEpisode2Numbers>
): Boolean

/**
* Note: Ensure episodes are ordered by season number (lowest first),
* then episode number (lowest first).
*/
protected abstract fun getEpisodesForNetworkJob(context: Context): List<SgEpisode2Numbers>
protected abstract fun getAffectedEpisodes(context: Context): List<SgEpisode2Numbers>

/**
* Returns the number of plays to upload to Cloud (Trakt currently not supported)
* based on the current number of plays (before [.applyLocalChanges].
*/
protected abstract fun getPlaysForNetworkJob(plays: Int): Int

private fun prepareNetworkJob(context: Context): ByteArray? {
// store affected episodes for network part
val episodes = getEpisodesForNetworkJob(context)

/**
* Store affected episodes for network job.
*/
private fun prepareNetworkJob(episodes: List<SgEpisode2Numbers>): ByteArray? {
val builder = FlatBufferBuilder(0)

val episodeInfos = IntArray(episodes.size)
Expand Down Expand Up @@ -122,4 +128,20 @@ abstract class BaseEpisodesJob(
}
LatestEpisodeUpdateTask.updateLatestEpisodeFor(context, showId)
}

/**
* Add or remove watch activity entries for episodes. Only used for watch jobs.
*/
protected fun updateActivity(context: Context, episodes: List<SgEpisode2Numbers>) {
val showTmdbIdOrZero =
SgRoomDatabase.getInstance(context).sgShow2Helper().getShowTmdbId(showId)
val episodeTmdbIds = episodes.mapNotNull { it.tmdbId }
if (showTmdbIdOrZero != 0 && episodeTmdbIds.isNotEmpty()) return

if (EpisodeTools.isWatched(flagValue)) {
SgActivityHelper.addActivitiesForEpisodes(context, showTmdbIdOrZero, episodeTmdbIds)
} else if (EpisodeTools.isUnwatched(flagValue)) {
SgActivityHelper.removeActivitiesForEpisodes(context, episodeTmdbIds)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ protected long getShowId() {

@NonNull
@Override
protected List<SgEpisode2Numbers> getEpisodesForNetworkJob(@NonNull Context context) {
protected List<SgEpisode2Numbers> getAffectedEpisodes(@NonNull Context context) {
List<SgEpisode2Numbers> list = new ArrayList<>();
list.add(episode);
return list;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ package com.battlelancer.seriesguide.jobs.episodes

import android.content.Context
import com.battlelancer.seriesguide.provider.SgRoomDatabase
import com.battlelancer.seriesguide.shows.database.SgEpisode2Numbers

class EpisodeCollectedJob(
episodeId: Long, private val isCollected: Boolean
) : EpisodeBaseJob(episodeId, if (isCollected) 1 else 0, JobAction.EPISODE_COLLECTION) {
override fun applyDatabaseChanges(context: Context): Boolean {
override fun applyDatabaseChanges(
context: Context,
episodes: List<SgEpisode2Numbers>
): Boolean {
val updated = SgRoomDatabase.getInstance(context).sgEpisode2Helper()
.updateCollected(episodeId, isCollected)
return updated == 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ package com.battlelancer.seriesguide.jobs.episodes
import android.content.Context
import com.battlelancer.seriesguide.appwidget.ListWidgetProvider
import com.battlelancer.seriesguide.provider.SgRoomDatabase
import com.battlelancer.seriesguide.shows.database.SgEpisode2Numbers
import com.battlelancer.seriesguide.shows.episodes.EpisodeFlags
import com.battlelancer.seriesguide.shows.episodes.EpisodeTools
import com.battlelancer.seriesguide.shows.history.SgActivityHelper

class EpisodeWatchedJob(
episodeId: Long,
Expand Down Expand Up @@ -49,31 +49,10 @@ class EpisodeWatchedJob(
}
}

override fun applyLocalChanges(context: Context, requiresNetworkJob: Boolean): Boolean {
if (!super.applyLocalChanges(context, requiresNetworkJob)) {
return false
}

// set a new last watched episode
// set last watched time to now if marking as watched or skipped
val unwatched = EpisodeTools.isUnwatched(flagValue)
updateLastWatched(context, getLastWatchedEpisodeId(context), !unwatched)

if (EpisodeTools.isWatched(flagValue)) {
// create activity entry for watched episode
SgActivityHelper.addActivity(context, episodeId, showId)
} else if (unwatched) {
// remove any previous activity entries for this episode
// use case: user accidentally toggled watched flag
SgActivityHelper.removeActivity(context, episodeId)
}

ListWidgetProvider.notifyDataChanged(context)

return true
}

override fun applyDatabaseChanges(context: Context): Boolean {
override fun applyDatabaseChanges(
context: Context,
episodes: List<SgEpisode2Numbers>
): Boolean {
val episodeHelper = SgRoomDatabase.getInstance(context).sgEpisode2Helper()
val flagValue = flagValue
val rowsUpdated: Int = when (flagValue) {
Expand All @@ -82,7 +61,20 @@ class EpisodeWatchedJob(
EpisodeFlags.UNWATCHED -> episodeHelper.setNotWatchedAndRemovePlays(episodeId)
else -> throw IllegalArgumentException("Flag value not supported")
}
return rowsUpdated == 1
val isSuccessful = rowsUpdated == 1

if (isSuccessful) {
// set a new last watched episode
// set last watched time to now if marking as watched or skipped
val unwatched = EpisodeTools.isUnwatched(flagValue)
updateLastWatched(context, getLastWatchedEpisodeId(context), !unwatched)

// Add or remove activity entry
updateActivity(context, episodes)

ListWidgetProvider.notifyDataChanged(context)
}
return isSuccessful
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,28 @@ class EpisodeWatchedUpToJob(
private val episodeNumber: Int
) : BaseEpisodesJob(EpisodeFlags.WATCHED, JobAction.EPISODE_WATCHED_FLAG) {

override fun applyLocalChanges(context: Context, requiresNetworkJob: Boolean): Boolean {
if (!super.applyLocalChanges(context, requiresNetworkJob)) {
return false
}

// we don't care about the last watched episode value
// always update last watched time, this type only marks as watched
updateLastWatched(context, -1, true)
override fun applyDatabaseChanges(
context: Context,
episodes: List<SgEpisode2Numbers>
): Boolean {
val rowsUpdated = SgRoomDatabase.getInstance(context).sgEpisode2Helper()
.setWatchedUpToAndAddPlay(showId, episodeFirstAired, episodeNumber)
val isSuccessful = rowsUpdated >= 0 // -1 means error

ListWidgetProvider.notifyDataChanged(context)
if (isSuccessful) {
// we don't care about the last watched episode value
// always update last watched time, this type only marks as watched
updateLastWatched(context, -1, true)

return true
}
// Add or remove activity entries
updateActivity(context, episodes)

override fun applyDatabaseChanges(context: Context): Boolean {
val rowsUpdated = SgRoomDatabase.getInstance(context).sgEpisode2Helper()
.setWatchedUpToAndAddPlay(showId, episodeFirstAired, episodeNumber)
return rowsUpdated >= 0 // -1 means error
ListWidgetProvider.notifyDataChanged(context)
}
return isSuccessful
}

override fun getEpisodesForNetworkJob(context: Context): List<SgEpisode2Numbers> {
override fun getAffectedEpisodes(context: Context): List<SgEpisode2Numbers> {
return SgRoomDatabase.getInstance(context).sgEpisode2Helper()
.getEpisodeNumbersForWatchedUpTo(showId, episodeFirstAired, episodeNumber)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ class SeasonCollectedJob(
seasonId: Long,
private val isCollected: Boolean
) : SeasonBaseJob(seasonId, if (isCollected) 1 else 0, JobAction.EPISODE_COLLECTION) {
override fun applyDatabaseChanges(context: Context): Boolean {
override fun applyDatabaseChanges(context: Context, episodes: List<SgEpisode2Numbers>): Boolean {
val rowsUpdated = SgRoomDatabase.getInstance(context).sgEpisode2Helper()
.updateCollectedOfSeason(seasonId, isCollected)
return rowsUpdated >= 0 // -1 means error.
}

override fun getEpisodesForNetworkJob(context: Context): List<SgEpisode2Numbers> {
override fun getAffectedEpisodes(context: Context): List<SgEpisode2Numbers> {
return SgRoomDatabase.getInstance(context).sgEpisode2Helper()
.getEpisodeNumbersOfSeason(seasonId)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ class SeasonWatchedJob(seasonId: Long, episodeFlags: Int) :
}
}

override fun applyDatabaseChanges(context: Context): Boolean {
override fun applyDatabaseChanges(
context: Context,
episodes: List<SgEpisode2Numbers>
): Boolean {
val database = SgRoomDatabase.getInstance(context)
val helper = database.sgEpisode2Helper()
val rowsUpdated = when (flagValue) {
Expand All @@ -45,18 +48,23 @@ class SeasonWatchedJob(seasonId: Long, episodeFlags: Int) :
EpisodeFlags.UNWATCHED -> helper.setSeasonNotWatchedAndRemovePlays(seasonId)
else -> throw IllegalArgumentException("Flag value not supported")
}
val isSuccessful = rowsUpdated >= 0 // -1 means error.

// set a new last watched episode
// set last watched time to now if marking as watched or skipped
val unwatched = EpisodeTools.isUnwatched(flagValue)
updateLastWatched(context, getLastWatchedEpisodeId(context), !unwatched)
if (isSuccessful) {
// set a new last watched episode
// set last watched time to now if marking as watched or skipped
val unwatched = EpisodeTools.isUnwatched(flagValue)
updateLastWatched(context, getLastWatchedEpisodeId(context), !unwatched)

ListWidgetProvider.notifyDataChanged(context)
// Add or remove activity entries
updateActivity(context, episodes)

return rowsUpdated >= 0 // -1 means error.
ListWidgetProvider.notifyDataChanged(context)
}
return isSuccessful
}

override fun getEpisodesForNetworkJob(context: Context): List<SgEpisode2Numbers> {
override fun getAffectedEpisodes(context: Context): List<SgEpisode2Numbers> {
val helper = SgRoomDatabase.getInstance(context).sgEpisode2Helper()
return if (EpisodeTools.isUnwatched(flagValue)) {
// set unwatched
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ class ShowCollectedJob(
private val isCollected: Boolean
) : ShowBaseJob(showId, if (isCollected) 1 else 0, JobAction.EPISODE_COLLECTION) {

override fun applyDatabaseChanges(context: Context): Boolean {
override fun applyDatabaseChanges(
context: Context,
episodes: List<SgEpisode2Numbers>
): Boolean {
val rowsUpdated = SgRoomDatabase.getInstance(context).sgEpisode2Helper()
.updateCollectedOfShowExcludeSpecials(showId, isCollected)
return rowsUpdated >= 0 // -1 means error.
}

override fun getEpisodesForNetworkJob(context: Context): List<SgEpisode2Numbers> {
override fun getAffectedEpisodes(context: Context): List<SgEpisode2Numbers> {
return SgRoomDatabase.getInstance(context).sgEpisode2Helper()
.getEpisodeNumbersOfShow(showId)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,16 @@ class ShowWatchedJob(
if (!super.applyLocalChanges(context, requiresNetworkJob)) {
return false
}
val lastWatchedEpisodeId =
if (EpisodeTools.isUnwatched(flagValue)) {
0L /* just reset */
} else {
-1L /* we don't care */
}

// set a new last watched episode
// set last watched time to now if marking as watched or skipped
updateLastWatched(context, lastWatchedEpisodeId, !EpisodeTools.isUnwatched(flagValue))

ListWidgetProvider.notifyDataChanged(context)

return true
}

override fun applyDatabaseChanges(context: Context): Boolean {
override fun applyDatabaseChanges(
context: Context,
episodes: List<SgEpisode2Numbers>
): Boolean {
val helper = SgRoomDatabase.getInstance(context).sgEpisode2Helper()
val rowsUpdated: Int = when (flagValue) {
EpisodeFlags.UNWATCHED -> helper.setShowNotWatchedAndRemovePlays(showId)
Expand All @@ -51,10 +44,29 @@ class ShowWatchedJob(
throw IllegalArgumentException("Flag value not supported")
}
}
return rowsUpdated >= 0 // -1 means error.
val isSuccessful = rowsUpdated >= 0 // -1 means error

if (isSuccessful) {
val lastWatchedEpisodeId =
if (EpisodeTools.isUnwatched(flagValue)) {
0L /* just reset */
} else {
-1L /* we don't care */
}

// set a new last watched episode
// set last watched time to now if marking as watched or skipped
updateLastWatched(context, lastWatchedEpisodeId, !EpisodeTools.isUnwatched(flagValue))

// Add or remove activity entries
updateActivity(context, episodes)

ListWidgetProvider.notifyDataChanged(context)
}
return isSuccessful
}

override fun getEpisodesForNetworkJob(context: Context): List<SgEpisode2Numbers> {
override fun getAffectedEpisodes(context: Context): List<SgEpisode2Numbers> {
val helper = SgRoomDatabase.getInstance(context).sgEpisode2Helper()
return if (EpisodeTools.isUnwatched(flagValue)) {
// set unwatched
Expand Down
Loading

0 comments on commit 77282d6

Please sign in to comment.