From e5d9aa26dad1986aa0d73a4a062807b1f3d5559d Mon Sep 17 00:00:00 2001 From: Uwe Trottmann Date: Thu, 7 Mar 2024 11:05:50 +0100 Subject: [PATCH] Kotlin: convert some job classes --- .../jobs/episodes/BaseEpisodesJob.kt | 140 ++++++++---------- .../jobs/episodes/EpisodeCollectedJob.kt | 36 ++--- .../jobs/episodes/EpisodeWatchedJob.kt | 134 +++++++---------- .../jobs/episodes/EpisodeWatchedUpToJob.kt | 11 +- .../jobs/episodes/SeasonBaseJob.kt | 59 +++----- .../jobs/episodes/SeasonCollectedJob.kt | 50 +++---- .../jobs/episodes/SeasonWatchedJob.kt | 118 ++++++--------- .../seriesguide/jobs/episodes/ShowBaseJob.kt | 26 +--- .../jobs/episodes/ShowCollectedJob.kt | 52 +++---- .../jobs/episodes/ShowWatchedJob.kt | 114 +++++++------- 10 files changed, 299 insertions(+), 441 deletions(-) diff --git a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/BaseEpisodesJob.kt b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/BaseEpisodesJob.kt index fefa91e430..81ce726508 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/BaseEpisodesJob.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/BaseEpisodesJob.kt @@ -1,122 +1,104 @@ -// Copyright 2023 Uwe Trottmann // SPDX-License-Identifier: Apache-2.0 - -package com.battlelancer.seriesguide.jobs.episodes; - -import android.content.Context; -import androidx.annotation.CallSuper; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import com.battlelancer.seriesguide.jobs.BaseFlagJob; -import com.battlelancer.seriesguide.jobs.EpisodeInfo; -import com.battlelancer.seriesguide.jobs.SgJobInfo; -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.tools.LatestEpisodeUpdateTask; -import com.google.flatbuffers.FlatBufferBuilder; -import java.util.List; - -public abstract class BaseEpisodesJob extends BaseFlagJob { - - private final int flagValue; - - public BaseEpisodesJob(int flagValue, JobAction action) { - super(action); - this.flagValue = flagValue; - } - - @Override - public boolean supportsHexagon() { - return true; +// Copyright 2017, 2018, 2020-2024 Uwe Trottmann +package com.battlelancer.seriesguide.jobs.episodes + +import android.content.Context +import androidx.annotation.CallSuper +import com.battlelancer.seriesguide.jobs.BaseFlagJob +import com.battlelancer.seriesguide.jobs.EpisodeInfo +import com.battlelancer.seriesguide.jobs.SgJobInfo +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.tools.LatestEpisodeUpdateTask +import com.google.flatbuffers.FlatBufferBuilder + +abstract class BaseEpisodesJob( + protected val flagValue: Int, + action: JobAction +) : BaseFlagJob(action) { + + protected abstract val showId: Long + + override fun supportsHexagon(): Boolean { + return true } - @Override - public boolean supportsTrakt() { + override fun supportsTrakt(): Boolean { /* No need to create network job for skipped episodes, not supported by trakt. Note that a network job might still be created if hexagon is connected. */ - return !EpisodeTools.isSkipped(flagValue); + return !EpisodeTools.isSkipped(flagValue) } - protected int getFlagValue() { - return flagValue; - } - - protected abstract long getShowId(); - /** * Builds and executes the database op required to flag episodes in the local database, * notifies affected URIs, may update the list widget. */ - @Override @CallSuper - public boolean applyLocalChanges(Context context, boolean requiresNetworkJob) { + override fun applyLocalChanges(context: Context, requiresNetworkJob: Boolean): Boolean { // prepare network job - byte[] networkJobInfo = null; + var networkJobInfo: ByteArray? = null if (requiresNetworkJob) { - networkJobInfo = prepareNetworkJob(context); + networkJobInfo = prepareNetworkJob(context) if (networkJobInfo == null) { - return false; + return false } } // apply local updates - boolean updated = applyDatabaseChanges(context); + val updated = applyDatabaseChanges(context) if (!updated) { - return false; + return false } // persist network job after successful local updates if (requiresNetworkJob) { - if (!persistNetworkJob(context, networkJobInfo)) { - return false; + if (!persistNetworkJob(context, networkJobInfo!!)) { + return false } } // notify some other URIs about updates - context.getContentResolver() - .notifyChange(SeriesGuideContract.ListItems.CONTENT_WITH_DETAILS_URI, null); + context.contentResolver + .notifyChange(SeriesGuideContract.ListItems.CONTENT_WITH_DETAILS_URI, null) - return true; + return true } - protected abstract boolean applyDatabaseChanges(@NonNull Context context); + protected abstract fun applyDatabaseChanges(context: Context): Boolean /** * Note: Ensure episodes are ordered by season number (lowest first), * then episode number (lowest first). */ - @NonNull - protected abstract List getEpisodesForNetworkJob(@NonNull Context context); + protected abstract fun getEpisodesForNetworkJob(context: Context): List /** * Returns the number of plays to upload to Cloud (Trakt currently not supported) - * based on the current number of plays (before {@link #applyLocalChanges(Context, boolean)}. + * based on the current number of plays (before [.applyLocalChanges]. */ - protected abstract int getPlaysForNetworkJob(int plays); + protected abstract fun getPlaysForNetworkJob(plays: Int): Int - @Nullable - private byte[] prepareNetworkJob(Context context) { + private fun prepareNetworkJob(context: Context): ByteArray? { // store affected episodes for network part - List episodes = getEpisodesForNetworkJob(context); + val episodes = getEpisodesForNetworkJob(context) - FlatBufferBuilder builder = new FlatBufferBuilder(0); + val builder = FlatBufferBuilder(0) - int[] episodeInfos = new int[episodes.size()]; - for (int i = 0; i < episodes.size(); i++) { - SgEpisode2Numbers episode = episodes.get(i); - int plays = getPlaysForNetworkJob(episode.getPlays()); + val episodeInfos = IntArray(episodes.size) + for (i in episodes.indices) { + val episode = episodes[i] + val newPlays = getPlaysForNetworkJob(episode.plays) episodeInfos[i] = EpisodeInfo - .createEpisodeInfo(builder, episode.getSeason(), episode.getEpisodenumber(), - plays); + .createEpisodeInfo(builder, episode.season, episode.episodenumber, newPlays) } - int episodesVector = SgJobInfo.createEpisodesVector(builder, episodeInfos); - int jobInfo = SgJobInfo.createSgJobInfo(builder, flagValue, episodesVector, 0, 0, getShowId()); + val episodesVector = SgJobInfo.createEpisodesVector(builder, episodeInfos) + val jobInfo = SgJobInfo.createSgJobInfo(builder, flagValue, episodesVector, 0, 0, showId) - builder.finish(jobInfo); - return builder.sizedByteArray(); + builder.finish(jobInfo) + return builder.sizedByteArray() } /** @@ -127,13 +109,17 @@ public abstract class BaseEpisodesJob extends BaseFlagJob { * for no-op. * @param setLastWatchedToNow Whether to set the last watched time of a show to now. */ - protected final void updateLastWatched(Context context, - long lastWatchedEpisodeId, boolean setLastWatchedToNow) { - if (lastWatchedEpisodeId != -1 || setLastWatchedToNow) { + protected fun updateLastWatched( + context: Context, + lastWatchedEpisodeId: Long, setLastWatchedToNow: Boolean + ) { + if (lastWatchedEpisodeId != -1L || setLastWatchedToNow) { SgRoomDatabase.getInstance(context).sgShow2Helper() - .updateLastWatchedEpisodeIdAndTime(getShowId(), lastWatchedEpisodeId, - setLastWatchedToNow); + .updateLastWatchedEpisodeIdAndTime( + showId, lastWatchedEpisodeId, + setLastWatchedToNow + ) } - LatestEpisodeUpdateTask.updateLatestEpisodeFor(context, getShowId()); + LatestEpisodeUpdateTask.updateLatestEpisodeFor(context, showId) } } diff --git a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/EpisodeCollectedJob.kt b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/EpisodeCollectedJob.kt index 579fddfa4c..63a25031b2 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/EpisodeCollectedJob.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/EpisodeCollectedJob.kt @@ -1,30 +1,20 @@ // SPDX-License-Identifier: Apache-2.0 -// Copyright 2017, 2018, 2020-2023 Uwe Trottmann +// Copyright 2017, 2018, 2020-2024 Uwe Trottmann +package com.battlelancer.seriesguide.jobs.episodes -package com.battlelancer.seriesguide.jobs.episodes; +import android.content.Context +import com.battlelancer.seriesguide.provider.SgRoomDatabase -import android.content.Context; -import androidx.annotation.NonNull; -import com.battlelancer.seriesguide.provider.SgRoomDatabase; - -public class EpisodeCollectedJob extends EpisodeBaseJob { - - private final boolean isCollected; - - public EpisodeCollectedJob(long episodeId, boolean isCollected) { - super(episodeId, isCollected ? 1 : 0, JobAction.EPISODE_COLLECTION); - this.isCollected = isCollected; - } - - @Override - protected boolean applyDatabaseChanges(@NonNull Context context) { - int updated = SgRoomDatabase.getInstance(context).sgEpisode2Helper() - .updateCollected(episodeId, isCollected); - return updated == 1; +class EpisodeCollectedJob( + episodeId: Long, private val isCollected: Boolean +) : EpisodeBaseJob(episodeId, if (isCollected) 1 else 0, JobAction.EPISODE_COLLECTION) { + override fun applyDatabaseChanges(context: Context): Boolean { + val updated = SgRoomDatabase.getInstance(context).sgEpisode2Helper() + .updateCollected(episodeId, isCollected) + return updated == 1 } - @Override - protected int getPlaysForNetworkJob(int plays) { - return plays; // Collected change does not change plays. + override fun getPlaysForNetworkJob(plays: Int): Int { + return plays // Collected change does not change plays. } } diff --git a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/EpisodeWatchedJob.kt b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/EpisodeWatchedJob.kt index c238e43182..5ddd33b9c8 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/EpisodeWatchedJob.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/EpisodeWatchedJob.kt @@ -1,119 +1,99 @@ -// Copyright 2023 Uwe Trottmann // SPDX-License-Identifier: Apache-2.0 - -package com.battlelancer.seriesguide.jobs.episodes; - -import android.content.Context; -import androidx.annotation.NonNull; -import com.battlelancer.seriesguide.appwidget.ListWidgetProvider; -import com.battlelancer.seriesguide.provider.SgRoomDatabase; -import com.battlelancer.seriesguide.shows.database.SgEpisode2Helper; -import com.battlelancer.seriesguide.shows.episodes.EpisodeFlags; -import com.battlelancer.seriesguide.shows.episodes.EpisodeTools; -import com.battlelancer.seriesguide.shows.history.SgActivityHelper; - -public class EpisodeWatchedJob extends EpisodeBaseJob { - - public EpisodeWatchedJob(long episodeId, int episodeFlags) { - super(episodeId, episodeFlags, JobAction.EPISODE_WATCHED_FLAG); - } - - private long getLastWatchedEpisodeId(Context context) { - if (!EpisodeTools.isUnwatched(getFlagValue())) { +// Copyright 2017, 2018, 2020, 2021, 2023, 2024 Uwe Trottmann +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.episodes.EpisodeFlags +import com.battlelancer.seriesguide.shows.episodes.EpisodeTools +import com.battlelancer.seriesguide.shows.history.SgActivityHelper + +class EpisodeWatchedJob( + episodeId: Long, + episodeFlags: Int +) : EpisodeBaseJob(episodeId, episodeFlags, JobAction.EPISODE_WATCHED_FLAG) { + + private fun getLastWatchedEpisodeId(context: Context): Long { + return if (!EpisodeTools.isUnwatched(flagValue)) { // watched or skipped episode - return episodeId; + episodeId } else { // changed episode to not watched - long lastWatchedId = -1; // don't change last watched episode by default + var lastWatchedId: Long = -1 // don't change last watched episode by default // if modified episode is identical to last watched one (e.g. was just watched), // find an appropriate last watched episode - SgRoomDatabase database = SgRoomDatabase.getInstance(context); - long lastWatchedEpisodeId = database.sgShow2Helper() - .getShowLastWatchedEpisodeId(getShowId()); + val database = SgRoomDatabase.getInstance(context) + val lastWatchedEpisodeId = database.sgShow2Helper() + .getShowLastWatchedEpisodeId(showId) // identical to last watched episode? if (episodeId == lastWatchedEpisodeId) { - if (getEpisode().getSeason() == 0) { + if (episode.season == 0) { // keep last watched (= this episode) if we got a special - return -1; + return -1 } - lastWatchedId = 0; // re-set if we don't find one + lastWatchedId = 0 // re-set if we don't find one // get newest watched before this one - long previousWatchedEpisodeId = database.sgEpisode2Helper() - .getPreviousWatchedEpisodeOfShow(getShowId(), getEpisode().getSeason(), - getEpisode().getEpisodenumber()); + val previousWatchedEpisodeId = database.sgEpisode2Helper() + .getPreviousWatchedEpisodeOfShow( + showId, episode.season, + episode.episodenumber + ) if (previousWatchedEpisodeId > 0) { - lastWatchedId = previousWatchedEpisodeId; + lastWatchedId = previousWatchedEpisodeId } } - - return lastWatchedId; + lastWatchedId } } - @Override - public boolean applyLocalChanges(Context context, boolean requiresNetworkJob) { + override fun applyLocalChanges(context: Context, requiresNetworkJob: Boolean): Boolean { if (!super.applyLocalChanges(context, requiresNetworkJob)) { - return false; + return false } // set a new last watched episode // set last watched time to now if marking as watched or skipped - boolean unwatched = EpisodeTools.isUnwatched(getFlagValue()); - updateLastWatched(context, getLastWatchedEpisodeId(context), !unwatched); + val unwatched = EpisodeTools.isUnwatched(flagValue) + updateLastWatched(context, getLastWatchedEpisodeId(context), !unwatched) - if (EpisodeTools.isWatched(getFlagValue())) { + if (EpisodeTools.isWatched(flagValue)) { // create activity entry for watched episode - SgActivityHelper.addActivity(context, episodeId, getShowId()); + 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); + SgActivityHelper.removeActivity(context, episodeId) } - ListWidgetProvider.notifyDataChanged(context); + ListWidgetProvider.notifyDataChanged(context) - return true; + return true } - @Override - protected boolean applyDatabaseChanges(@NonNull Context context) { - SgEpisode2Helper episodeHelper = SgRoomDatabase.getInstance(context).sgEpisode2Helper(); - int flagValue = getFlagValue(); - - int rowsUpdated; - switch (flagValue) { - case EpisodeFlags.SKIPPED: - rowsUpdated = episodeHelper.setSkipped(episodeId); - break; - case EpisodeFlags.WATCHED: - rowsUpdated = episodeHelper.setWatchedAndAddPlay(episodeId); - break; - case EpisodeFlags.UNWATCHED: - rowsUpdated = episodeHelper.setNotWatchedAndRemovePlays(episodeId); - break; - default: - throw new IllegalArgumentException("Flag value not supported"); + override fun applyDatabaseChanges(context: Context): Boolean { + val episodeHelper = SgRoomDatabase.getInstance(context).sgEpisode2Helper() + val flagValue = flagValue + val rowsUpdated: Int = when (flagValue) { + EpisodeFlags.SKIPPED -> episodeHelper.setSkipped(episodeId) + EpisodeFlags.WATCHED -> episodeHelper.setWatchedAndAddPlay(episodeId) + EpisodeFlags.UNWATCHED -> episodeHelper.setNotWatchedAndRemovePlays(episodeId) + else -> throw IllegalArgumentException("Flag value not supported") } - - return rowsUpdated == 1; + return rowsUpdated == 1 } /** - * Note: this should mirror the planned database changes in {@link #applyDatabaseChanges(Context)}. + * Note: this should mirror the planned database changes in [applyDatabaseChanges]. */ - @Override - protected int getPlaysForNetworkJob(int plays) { - switch (getFlagValue()) { - case EpisodeFlags.SKIPPED: - return plays; - case EpisodeFlags.WATCHED: - return plays + 1; - case EpisodeFlags.UNWATCHED: - return 0; - default: - throw new IllegalArgumentException("Flag value not supported"); + override fun getPlaysForNetworkJob(plays: Int): Int { + return when (flagValue) { + EpisodeFlags.SKIPPED -> plays + EpisodeFlags.WATCHED -> plays + 1 + EpisodeFlags.UNWATCHED -> 0 + else -> throw IllegalArgumentException("Flag value not supported") } } } diff --git a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/EpisodeWatchedUpToJob.kt b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/EpisodeWatchedUpToJob.kt index 910b833fc9..d36e0e3afe 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/EpisodeWatchedUpToJob.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/EpisodeWatchedUpToJob.kt @@ -1,28 +1,23 @@ -// Copyright 2023 Uwe Trottmann // SPDX-License-Identifier: Apache-2.0 +// Copyright 2019-2024 Uwe Trottmann package com.battlelancer.seriesguide.jobs.episodes import android.content.Context -import com.battlelancer.seriesguide.R import com.battlelancer.seriesguide.appwidget.ListWidgetProvider -import com.battlelancer.seriesguide.shows.database.SgEpisode2Numbers import com.battlelancer.seriesguide.provider.SgRoomDatabase +import com.battlelancer.seriesguide.shows.database.SgEpisode2Numbers import com.battlelancer.seriesguide.shows.episodes.EpisodeFlags /** * Set episodes watched up to (== including) a specific one excluding those with no release date. */ class EpisodeWatchedUpToJob( - private val showId: Long, + override val showId: Long, private val episodeFirstAired: Long, private val episodeNumber: Int ) : BaseEpisodesJob(EpisodeFlags.WATCHED, JobAction.EPISODE_WATCHED_FLAG) { - override fun getShowId(): Long { - return showId - } - override fun applyLocalChanges(context: Context, requiresNetworkJob: Boolean): Boolean { if (!super.applyLocalChanges(context, requiresNetworkJob)) { return false diff --git a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/SeasonBaseJob.kt b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/SeasonBaseJob.kt index 7f4570b7c9..22533f6ec8 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/SeasonBaseJob.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/SeasonBaseJob.kt @@ -1,49 +1,32 @@ -// Copyright 2023 Uwe Trottmann // SPDX-License-Identifier: Apache-2.0 +// Copyright 2017, 2018, 2021-2024 Uwe Trottmann +package com.battlelancer.seriesguide.jobs.episodes -package com.battlelancer.seriesguide.jobs.episodes; - -import android.content.Context; -import androidx.annotation.NonNull; -import com.battlelancer.seriesguide.provider.SgRoomDatabase; -import com.battlelancer.seriesguide.shows.database.SgSeason2Numbers; +import android.content.Context +import com.battlelancer.seriesguide.provider.SgRoomDatabase +import com.battlelancer.seriesguide.shows.database.SgSeason2Numbers /** * Flagging whole seasons watched or collected. */ -public abstract class SeasonBaseJob extends BaseEpisodesJob { - - protected final long seasonId; - private SgSeason2Numbers season; - - public SeasonBaseJob(long seasonId, int flagValue, JobAction action) { - super(flagValue, action); - this.seasonId = seasonId; +abstract class SeasonBaseJob( + val seasonId: Long, + flagValue: Int, + action: JobAction +) : BaseEpisodesJob(flagValue, action) { + + private lateinit var season: SgSeason2Numbers + override fun applyLocalChanges(context: Context, requiresNetworkJob: Boolean): Boolean { + val season = SgRoomDatabase.getInstance(context).sgSeason2Helper() + .getSeasonNumbers(seasonId) ?: return false + this.season = season + return super.applyLocalChanges(context, requiresNetworkJob) } - @Override - public boolean applyLocalChanges(Context context, boolean requiresNetworkJob) { - SgSeason2Numbers season = SgRoomDatabase.getInstance(context).sgSeason2Helper() - .getSeasonNumbers(seasonId); - if (season == null) { - return false; - } - this.season = season; - - return super.applyLocalChanges(context, requiresNetworkJob); + fun getSeason(): SgSeason2Numbers { + return season } - @NonNull - public SgSeason2Numbers getSeason() { - return season; - } - - @Override - protected long getShowId() { - return getSeason().getShowId(); - } - - public long getSeasonId() { - return seasonId; - } + override val showId: Long + get() = getSeason().showId } diff --git a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/SeasonCollectedJob.kt b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/SeasonCollectedJob.kt index 7645638868..9494c88647 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/SeasonCollectedJob.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/SeasonCollectedJob.kt @@ -1,39 +1,27 @@ // SPDX-License-Identifier: Apache-2.0 -// Copyright 2017, 2018, 2020-2023 Uwe Trottmann - -package com.battlelancer.seriesguide.jobs.episodes; - -import android.content.Context; -import androidx.annotation.NonNull; -import com.battlelancer.seriesguide.provider.SgRoomDatabase; -import com.battlelancer.seriesguide.shows.database.SgEpisode2Numbers; -import java.util.List; - -public class SeasonCollectedJob extends SeasonBaseJob { - - private final boolean isCollected; - - public SeasonCollectedJob(long seasonId, boolean isCollected) { - super(seasonId, isCollected ? 1 : 0, JobAction.EPISODE_COLLECTION); - this.isCollected = isCollected; - } - - @Override - protected boolean applyDatabaseChanges(@NonNull Context context) { - int rowsUpdated = SgRoomDatabase.getInstance(context).sgEpisode2Helper() - .updateCollectedOfSeason(seasonId, isCollected); - return rowsUpdated >= 0; // -1 means error. +// Copyright 2017, 2018, 2020-2024 Uwe Trottmann +package com.battlelancer.seriesguide.jobs.episodes + +import android.content.Context +import com.battlelancer.seriesguide.provider.SgRoomDatabase +import com.battlelancer.seriesguide.shows.database.SgEpisode2Numbers + +class SeasonCollectedJob( + seasonId: Long, + private val isCollected: Boolean +) : SeasonBaseJob(seasonId, if (isCollected) 1 else 0, JobAction.EPISODE_COLLECTION) { + override fun applyDatabaseChanges(context: Context): Boolean { + val rowsUpdated = SgRoomDatabase.getInstance(context).sgEpisode2Helper() + .updateCollectedOfSeason(seasonId, isCollected) + return rowsUpdated >= 0 // -1 means error. } - @NonNull - @Override - protected List getEpisodesForNetworkJob(@NonNull Context context) { + override fun getEpisodesForNetworkJob(context: Context): List { return SgRoomDatabase.getInstance(context).sgEpisode2Helper() - .getEpisodeNumbersOfSeason(seasonId); + .getEpisodeNumbersOfSeason(seasonId) } - @Override - protected int getPlaysForNetworkJob(int plays) { - return plays; // Collected change does not change plays. + override fun getPlaysForNetworkJob(plays: Int): Int { + return plays // Collected change does not change plays. } } diff --git a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/SeasonWatchedJob.kt b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/SeasonWatchedJob.kt index 5abb79be6b..bc81476693 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/SeasonWatchedJob.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/SeasonWatchedJob.kt @@ -1,115 +1,83 @@ // SPDX-License-Identifier: Apache-2.0 -// Copyright 2017, 2018, 2020-2023 Uwe Trottmann +// Copyright 2017, 2018, 2020-2024 Uwe Trottmann +package com.battlelancer.seriesguide.jobs.episodes -package com.battlelancer.seriesguide.jobs.episodes; - -import android.content.Context; -import androidx.annotation.NonNull; -import com.battlelancer.seriesguide.appwidget.ListWidgetProvider; -import com.battlelancer.seriesguide.provider.SgRoomDatabase; -import com.battlelancer.seriesguide.shows.database.SgEpisode2Helper; -import com.battlelancer.seriesguide.shows.database.SgEpisode2Numbers; -import com.battlelancer.seriesguide.shows.episodes.EpisodeFlags; -import com.battlelancer.seriesguide.shows.episodes.EpisodeTools; -import java.util.List; +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 /** * Sets *all* episodes of a season watched, skipped or not watched. Includes also episodes that do * not have a release date, which is common for special episodes. Also it is unexpected if all does * not mean all (previously this only marked episodes with release date up to current time + 1 hour). */ -public class SeasonWatchedJob extends SeasonBaseJob { - - public SeasonWatchedJob(long seasonId, int episodeFlags) { - super(seasonId, episodeFlags, JobAction.EPISODE_WATCHED_FLAG); - } - - private long getLastWatchedEpisodeId(Context context) { - if (EpisodeTools.isUnwatched(getFlagValue())) { +class SeasonWatchedJob(seasonId: Long, episodeFlags: Int) : + SeasonBaseJob(seasonId, episodeFlags, JobAction.EPISODE_WATCHED_FLAG) { + private fun getLastWatchedEpisodeId(context: Context): Long { + return if (EpisodeTools.isUnwatched(flagValue)) { // unwatched season // just reset - return 0; + 0 } else { // watched or skipped season // Get the highest episode of the season. - long highestWatchedId = SgRoomDatabase.getInstance(context) - .sgEpisode2Helper() - .getHighestEpisodeOfSeason(seasonId); - if (highestWatchedId != 0) { - return highestWatchedId; + val highestWatchedId = SgRoomDatabase.getInstance(context) + .sgEpisode2Helper() + .getHighestEpisodeOfSeason(seasonId) + if (highestWatchedId != 0L) { + highestWatchedId } else { - return -1; // do not change + -1 // do not change } } } - @Override - public boolean applyLocalChanges(Context context, boolean requiresNetworkJob) { - if (!super.applyLocalChanges(context, requiresNetworkJob)) { - return false; + override fun applyDatabaseChanges(context: Context): Boolean { + val database = SgRoomDatabase.getInstance(context) + val helper = database.sgEpisode2Helper() + val rowsUpdated = when (flagValue) { + EpisodeFlags.SKIPPED -> helper.setSeasonSkipped(seasonId) + EpisodeFlags.WATCHED -> helper.setSeasonWatchedAndAddPlay(seasonId) + EpisodeFlags.UNWATCHED -> helper.setSeasonNotWatchedAndRemovePlays(seasonId) + else -> throw IllegalArgumentException("Flag value not supported") } // set a new last watched episode // set last watched time to now if marking as watched or skipped - updateLastWatched(context, getLastWatchedEpisodeId(context), - !EpisodeTools.isUnwatched(getFlagValue())); + val unwatched = EpisodeTools.isUnwatched(flagValue) + updateLastWatched(context, getLastWatchedEpisodeId(context), !unwatched) - ListWidgetProvider.notifyDataChanged(context); + ListWidgetProvider.notifyDataChanged(context) - return true; - } - - @Override - protected boolean applyDatabaseChanges(@NonNull Context context) { - SgEpisode2Helper helper = SgRoomDatabase.getInstance(context).sgEpisode2Helper(); - - int rowsUpdated; - switch (getFlagValue()) { - case EpisodeFlags.SKIPPED: - rowsUpdated = helper.setSeasonSkipped(seasonId); - break; - case EpisodeFlags.WATCHED: - rowsUpdated = helper.setSeasonWatchedAndAddPlay(seasonId); - break; - case EpisodeFlags.UNWATCHED: - rowsUpdated = helper.setSeasonNotWatchedAndRemovePlays(seasonId); - break; - default: - throw new IllegalArgumentException("Flag value not supported"); - } - return rowsUpdated >= 0; // -1 means error. + return rowsUpdated >= 0 // -1 means error. } - @NonNull - @Override - protected List getEpisodesForNetworkJob(@NonNull Context context) { - SgEpisode2Helper helper = SgRoomDatabase.getInstance(context).sgEpisode2Helper(); - if (EpisodeTools.isUnwatched(getFlagValue())) { + override fun getEpisodesForNetworkJob(context: Context): List { + val helper = SgRoomDatabase.getInstance(context).sgEpisode2Helper() + return if (EpisodeTools.isUnwatched(flagValue)) { // set unwatched // include watched or skipped episodes - return helper.getWatchedOrSkippedEpisodeNumbersOfSeason(seasonId); + helper.getWatchedOrSkippedEpisodeNumbersOfSeason(seasonId) } else { // set watched or skipped // do NOT mark watched episodes again to avoid Trakt adding a new watch - return helper.getNotWatchedOrSkippedEpisodeNumbersOfSeason(seasonId); + helper.getNotWatchedOrSkippedEpisodeNumbersOfSeason(seasonId) } } /** - * Note: this should mirror the planned database changes in {@link #applyDatabaseChanges(Context)}. + * Note: this should mirror the planned database changes in [BaseEpisodesJob.applyDatabaseChanges]. */ - @Override - protected int getPlaysForNetworkJob(int plays) { - switch (getFlagValue()) { - case EpisodeFlags.SKIPPED: - return plays; - case EpisodeFlags.WATCHED: - return plays + 1; - case EpisodeFlags.UNWATCHED: - return 0; - default: - throw new IllegalArgumentException("Flag value not supported"); + override fun getPlaysForNetworkJob(plays: Int): Int { + return when (flagValue) { + EpisodeFlags.SKIPPED -> plays + EpisodeFlags.WATCHED -> plays + 1 + EpisodeFlags.UNWATCHED -> 0 + else -> throw IllegalArgumentException("Flag value not supported") } } } diff --git a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/ShowBaseJob.kt b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/ShowBaseJob.kt index ed49cde848..1b0370fc0e 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/ShowBaseJob.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/ShowBaseJob.kt @@ -1,19 +1,9 @@ -// Copyright 2023 Uwe Trottmann // SPDX-License-Identifier: Apache-2.0 - -package com.battlelancer.seriesguide.jobs.episodes; - -public abstract class ShowBaseJob extends BaseEpisodesJob { - - private final long showId; - - public ShowBaseJob(long showId, int flagValue, JobAction action) { - super(flagValue, action); - this.showId = showId; - } - - @Override - public long getShowId() { - return showId; - } -} +// Copyright 2017, 2018, 2021, 2023, 2024 Uwe Trottmann +package com.battlelancer.seriesguide.jobs.episodes + +abstract class ShowBaseJob( + override val showId: Long, + flagValue: Int, + action: JobAction +) : BaseEpisodesJob(flagValue, action) diff --git a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/ShowCollectedJob.kt b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/ShowCollectedJob.kt index 84a0e21fc7..a8bf630601 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/ShowCollectedJob.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/ShowCollectedJob.kt @@ -1,40 +1,28 @@ // SPDX-License-Identifier: Apache-2.0 -// Copyright 2017, 2018, 2020-2023 Uwe Trottmann - -package com.battlelancer.seriesguide.jobs.episodes; - -import android.content.Context; -import androidx.annotation.NonNull; -import com.battlelancer.seriesguide.provider.SgRoomDatabase; -import com.battlelancer.seriesguide.shows.database.SgEpisode2Numbers; -import java.util.List; - -public class ShowCollectedJob extends ShowBaseJob { - - private final boolean isCollected; - - public ShowCollectedJob(long showId, boolean isCollected) { - super(showId, isCollected ? 1 : 0, JobAction.EPISODE_COLLECTION); - this.isCollected = isCollected; - } - - @Override - protected boolean applyDatabaseChanges(@NonNull Context context) { - int rowsUpdated = SgRoomDatabase.getInstance(context).sgEpisode2Helper() - .updateCollectedOfShowExcludeSpecials(getShowId(), isCollected); - return rowsUpdated >= 0; // -1 means error. +// Copyright 2017, 2018, 2020-2024 Uwe Trottmann +package com.battlelancer.seriesguide.jobs.episodes + +import android.content.Context +import com.battlelancer.seriesguide.provider.SgRoomDatabase +import com.battlelancer.seriesguide.shows.database.SgEpisode2Numbers + +class ShowCollectedJob( + showId: Long, + private val isCollected: Boolean +) : ShowBaseJob(showId, if (isCollected) 1 else 0, JobAction.EPISODE_COLLECTION) { + + override fun applyDatabaseChanges(context: Context): Boolean { + val rowsUpdated = SgRoomDatabase.getInstance(context).sgEpisode2Helper() + .updateCollectedOfShowExcludeSpecials(showId, isCollected) + return rowsUpdated >= 0 // -1 means error. } - @NonNull - @Override - protected List getEpisodesForNetworkJob(@NonNull Context context) { + override fun getEpisodesForNetworkJob(context: Context): List { return SgRoomDatabase.getInstance(context).sgEpisode2Helper() - .getEpisodeNumbersOfShow(getShowId()); + .getEpisodeNumbersOfShow(showId) } - @Override - protected int getPlaysForNetworkJob(int plays) { - return plays; // Collected change does not change plays. + override fun getPlaysForNetworkJob(plays: Int): Int { + return plays // Collected change does not change plays. } - } diff --git a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/ShowWatchedJob.kt b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/ShowWatchedJob.kt index b14cf7f3b7..76374bb825 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/ShowWatchedJob.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/jobs/episodes/ShowWatchedJob.kt @@ -1,97 +1,87 @@ // SPDX-License-Identifier: Apache-2.0 -// Copyright 2017, 2018, 2020-2023 Uwe Trottmann +// Copyright 2017, 2018, 2020-2024 Uwe Trottmann +package com.battlelancer.seriesguide.jobs.episodes -package com.battlelancer.seriesguide.jobs.episodes; +import android.content.Context +import android.text.format.DateUtils +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 android.content.Context; -import android.text.format.DateUtils; -import androidx.annotation.NonNull; -import com.battlelancer.seriesguide.appwidget.ListWidgetProvider; -import com.battlelancer.seriesguide.provider.SgRoomDatabase; -import com.battlelancer.seriesguide.shows.database.SgEpisode2Helper; -import com.battlelancer.seriesguide.shows.database.SgEpisode2Numbers; -import com.battlelancer.seriesguide.shows.episodes.EpisodeFlags; -import com.battlelancer.seriesguide.shows.episodes.EpisodeTools; -import java.util.List; +class ShowWatchedJob( + showId: Long, + flagValue: Int, currentTime: Long +) : ShowBaseJob(showId, flagValue, JobAction.EPISODE_WATCHED_FLAG) { -public class ShowWatchedJob extends ShowBaseJob { + private val currentTimePlusOneHour: Long - private final long currentTimePlusOneHour; - - public ShowWatchedJob(long showId, int flagValue, long currentTime) { - super(showId, flagValue, JobAction.EPISODE_WATCHED_FLAG); - this.currentTimePlusOneHour = currentTime + DateUtils.HOUR_IN_MILLIS; + init { + currentTimePlusOneHour = currentTime + DateUtils.HOUR_IN_MILLIS } - @Override - public boolean applyLocalChanges(Context context, boolean requiresNetworkJob) { + override fun applyLocalChanges(context: Context, requiresNetworkJob: Boolean): Boolean { if (!super.applyLocalChanges(context, requiresNetworkJob)) { - return false; + return false } - - int lastWatchedEpisodeTvdbId = EpisodeTools.isUnwatched(getFlagValue()) - ? 0 /* just reset */ - : -1 /* we don't care */; + 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, lastWatchedEpisodeTvdbId, - !EpisodeTools.isUnwatched(getFlagValue())); + updateLastWatched(context, lastWatchedEpisodeId, !EpisodeTools.isUnwatched(flagValue)) - ListWidgetProvider.notifyDataChanged(context); + ListWidgetProvider.notifyDataChanged(context) - return true; + return true } - @Override - protected boolean applyDatabaseChanges(@NonNull Context context) { - SgEpisode2Helper helper = SgRoomDatabase.getInstance(context).sgEpisode2Helper(); - - int rowsUpdated; - switch (getFlagValue()) { - case EpisodeFlags.UNWATCHED: - rowsUpdated = helper.setShowNotWatchedAndRemovePlays(getShowId()); - break; - case EpisodeFlags.WATCHED: - rowsUpdated = helper.setShowWatchedAndAddPlay(getShowId(), currentTimePlusOneHour); - break; - default: + override fun applyDatabaseChanges(context: Context): Boolean { + val helper = SgRoomDatabase.getInstance(context).sgEpisode2Helper() + val rowsUpdated: Int = when (flagValue) { + EpisodeFlags.UNWATCHED -> helper.setShowNotWatchedAndRemovePlays(showId) + EpisodeFlags.WATCHED -> helper.setShowWatchedAndAddPlay(showId, currentTimePlusOneHour) + else -> { // Note: Skip not supported for whole show. - throw new IllegalArgumentException("Flag value not supported"); + throw IllegalArgumentException("Flag value not supported") + } } - return rowsUpdated >= 0; // -1 means error. + return rowsUpdated >= 0 // -1 means error. } - @NonNull - @Override - protected List getEpisodesForNetworkJob(@NonNull Context context) { - SgEpisode2Helper helper = SgRoomDatabase.getInstance(context).sgEpisode2Helper(); - if (EpisodeTools.isUnwatched(getFlagValue())) { + override fun getEpisodesForNetworkJob(context: Context): List { + val helper = SgRoomDatabase.getInstance(context).sgEpisode2Helper() + return if (EpisodeTools.isUnwatched(flagValue)) { // set unwatched // include watched or skipped episodes - return helper.getWatchedOrSkippedEpisodeNumbersOfShow(getShowId()); + helper.getWatchedOrSkippedEpisodeNumbersOfShow(showId) } else { // set watched or skipped // do NOT mark watched episodes again to avoid trakt adding a new watch // only mark episodes that have been released until within the hour - return helper.getNotWatchedOrSkippedEpisodeNumbersOfShow(getShowId(), - currentTimePlusOneHour); + helper.getNotWatchedOrSkippedEpisodeNumbersOfShow( + showId, + currentTimePlusOneHour + ) } } /** - * Note: this should mirror the planned database changes in {@link #applyDatabaseChanges(Context)}. + * Note: this should mirror the planned database changes in [applyDatabaseChanges]. */ - @Override - protected int getPlaysForNetworkJob(int plays) { - switch (getFlagValue()) { - case EpisodeFlags.WATCHED: - return plays + 1; - case EpisodeFlags.UNWATCHED: - return 0; - default: + override fun getPlaysForNetworkJob(plays: Int): Int { + return when (flagValue) { + EpisodeFlags.WATCHED -> plays + 1 + EpisodeFlags.UNWATCHED -> 0 + else -> { // Note: Skip not supported for whole show. - throw new IllegalArgumentException("Flag value not supported"); + throw IllegalArgumentException("Flag value not supported") + } } } }