Add watch status changed events

This commit is contained in:
Zoe Roux 2024-03-17 12:23:11 +01:00
parent 0d91001376
commit c15dcb02ec
No known key found for this signature in database
2 changed files with 43 additions and 46 deletions

View File

@ -29,12 +29,7 @@ namespace Kyoo.Abstractions.Controllers;
/// </summary>
public interface IWatchStatusRepository
{
// /// <summary>
// /// The event handler type for all events of this repository.
// /// </summary>
// /// <param name="resource">The resource created/modified/deleted</param>
// /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
// public delegate Task ResourceEventHandler(T resource);
public delegate Task ResourceEventHandler<T>(T resource);
Task<ICollection<IWatchlist>> GetAll(
Filter<IWatchlist>? filter = default,
@ -52,12 +47,22 @@ public interface IWatchStatusRepository
int? percent
);
static event ResourceEventHandler<Movie> OnMovieStatusChangedHandler;
protected static Task OnMovieStatusChanged(Movie obj) =>
OnMovieStatusChangedHandler?.Invoke(obj) ?? Task.CompletedTask;
Task DeleteMovieStatus(Guid movieId, Guid userId);
Task<ShowWatchStatus?> GetShowStatus(Guid showId, Guid userId);
Task<ShowWatchStatus?> SetShowStatus(Guid showId, Guid userId, WatchStatus status);
static event ResourceEventHandler<Show> OnShowStatusChangedHandler;
protected static Task OnShowStatusChanged(Show obj) =>
OnShowStatusChangedHandler?.Invoke(obj) ?? Task.CompletedTask;
Task DeleteShowStatus(Guid showId, Guid userId);
Task<EpisodeWatchStatus?> GetEpisodeStatus(Guid episodeId, Guid userId);
@ -72,5 +77,10 @@ public interface IWatchStatusRepository
int? percent
);
static event ResourceEventHandler<Episode> OnEpisodeStatusChangedHandler;
protected static Task OnEpisodeStatusChanged(Episode obj) =>
OnEpisodeStatusChangedHandler?.Invoke(obj) ?? Task.CompletedTask;
Task DeleteEpisodeStatus(Guid episodeId, Guid userId);
}

View File

@ -33,7 +33,12 @@ using Microsoft.Extensions.DependencyInjection;
namespace Kyoo.Core.Controllers;
public class WatchStatusRepository : IWatchStatusRepository
public class WatchStatusRepository(
DatabaseContext database,
IRepository<Movie> movies,
DbConnection db,
SqlVariableContext context
) : IWatchStatusRepository
{
/// <summary>
/// If the watch percent is below this value, don't consider the item started.
@ -55,11 +60,6 @@ public class WatchStatusRepository : IWatchStatusRepository
private WatchStatus Completed = WatchStatus.Completed;
private WatchStatus Planned = WatchStatus.Planned;
private readonly DatabaseContext _database;
private readonly IRepository<Movie> _movies;
private readonly DbConnection _db;
private readonly SqlVariableContext _context;
static WatchStatusRepository()
{
IRepository<Episode>.OnCreated += async (ep) =>
@ -78,19 +78,6 @@ public class WatchStatusRepository : IWatchStatusRepository
};
}
public WatchStatusRepository(
DatabaseContext database,
IRepository<Movie> movies,
DbConnection db,
SqlVariableContext context
)
{
_database = database;
_movies = movies;
_db = db;
_context = context;
}
// language=PostgreSQL
protected FormattableString Sql =>
$"""
@ -169,11 +156,11 @@ public class WatchStatusRepository : IWatchStatusRepository
/// <inheritdoc />
public Task<IWatchlist?> GetOrDefault(Guid id, Include<IWatchlist>? include = null)
{
return _db.QuerySingle<IWatchlist>(
return db.QuerySingle<IWatchlist>(
Sql,
Config,
Mapper,
_context,
context,
include,
new Filter<IWatchlist>.Eq(nameof(IResource.Id), id)
);
@ -208,12 +195,12 @@ public class WatchStatusRepository : IWatchStatusRepository
limit.AfterID = null;
}
return await _db.Query(
return await db.Query(
Sql,
Config,
Mapper,
(id) => Get(id),
_context,
context,
include,
filter,
null,
@ -224,7 +211,7 @@ public class WatchStatusRepository : IWatchStatusRepository
/// <inheritdoc />
public Task<MovieWatchStatus?> GetMovieStatus(Guid movieId, Guid userId)
{
return _database.MovieWatchStatus.FirstOrDefaultAsync(x =>
return database.MovieWatchStatus.FirstOrDefaultAsync(x =>
x.MovieId == movieId && x.UserId == userId
);
}
@ -238,7 +225,7 @@ public class WatchStatusRepository : IWatchStatusRepository
int? percent
)
{
Movie movie = await _movies.Get(movieId);
Movie movie = await movies.Get(movieId);
if (percent == null && watchedTime != null && movie.Runtime > 0)
percent = (int)Math.Round(watchedTime.Value / (movie.Runtime.Value * 60f) * 100f);
@ -274,7 +261,7 @@ public class WatchStatusRepository : IWatchStatusRepository
AddedDate = DateTime.UtcNow,
PlayedDate = status == WatchStatus.Completed ? DateTime.UtcNow : null,
};
await _database
await database
.MovieWatchStatus.Upsert(ret)
.UpdateIf(x => status != Watching || x.Status != Completed)
.RunAsync();
@ -284,7 +271,7 @@ public class WatchStatusRepository : IWatchStatusRepository
/// <inheritdoc />
public async Task DeleteMovieStatus(Guid movieId, Guid userId)
{
await _database
await database
.MovieWatchStatus.Where(x => x.MovieId == movieId && x.UserId == userId)
.ExecuteDeleteAsync();
}
@ -292,7 +279,7 @@ public class WatchStatusRepository : IWatchStatusRepository
/// <inheritdoc />
public Task<ShowWatchStatus?> GetShowStatus(Guid showId, Guid userId)
{
return _database.ShowWatchStatus.FirstOrDefaultAsync(x =>
return database.ShowWatchStatus.FirstOrDefaultAsync(x =>
x.ShowId == showId && x.UserId == userId
);
}
@ -310,7 +297,7 @@ public class WatchStatusRepository : IWatchStatusRepository
{
int unseenEpisodeCount =
status != WatchStatus.Completed
? await _database
? await database
.Episodes.Where(x => x.ShowId == showId)
.Where(x =>
x.Watched!.First(x => x.UserId == userId)!.Status != WatchStatus.Completed
@ -324,7 +311,7 @@ public class WatchStatusRepository : IWatchStatusRepository
Guid? nextEpisodeId = null;
if (status == WatchStatus.Watching)
{
var cursor = await _database
var cursor = await database
.Episodes.IgnoreQueryFilters()
.Where(x => x.ShowId == showId)
.OrderByDescending(x => x.AbsoluteNumber)
@ -346,7 +333,7 @@ public class WatchStatusRepository : IWatchStatusRepository
nextEpisodeId =
cursor?.Status.Status == WatchStatus.Watching
? cursor.Id
: await _database
: await database
.Episodes.IgnoreQueryFilters()
.Where(x => x.ShowId == showId)
.OrderBy(x => x.AbsoluteNumber)
@ -374,11 +361,11 @@ public class WatchStatusRepository : IWatchStatusRepository
}
else if (status == WatchStatus.Completed)
{
List<Guid> episodes = await _database
List<Guid> episodes = await database
.Episodes.Where(x => x.ShowId == showId)
.Select(x => x.Id)
.ToListAsync();
await _database
await database
.EpisodeWatchStatus.UpsertRange(
episodes.Select(episodeId => new EpisodeWatchStatus
{
@ -412,7 +399,7 @@ public class WatchStatusRepository : IWatchStatusRepository
UnseenEpisodesCount = unseenEpisodeCount,
PlayedDate = status == WatchStatus.Completed ? DateTime.UtcNow : null,
};
await _database
await database
.ShowWatchStatus.Upsert(ret)
.UpdateIf(x => status != Watching || x.Status != Completed || newEpisode)
.RunAsync();
@ -422,11 +409,11 @@ public class WatchStatusRepository : IWatchStatusRepository
/// <inheritdoc />
public async Task DeleteShowStatus(Guid showId, Guid userId)
{
await _database
await database
.ShowWatchStatus.IgnoreAutoIncludes()
.Where(x => x.ShowId == showId && x.UserId == userId)
.ExecuteDeleteAsync();
await _database
await database
.EpisodeWatchStatus.Where(x => x.Episode.ShowId == showId && x.UserId == userId)
.ExecuteDeleteAsync();
}
@ -434,7 +421,7 @@ public class WatchStatusRepository : IWatchStatusRepository
/// <inheritdoc />
public Task<EpisodeWatchStatus?> GetEpisodeStatus(Guid episodeId, Guid userId)
{
return _database.EpisodeWatchStatus.FirstOrDefaultAsync(x =>
return database.EpisodeWatchStatus.FirstOrDefaultAsync(x =>
x.EpisodeId == episodeId && x.UserId == userId
);
}
@ -448,7 +435,7 @@ public class WatchStatusRepository : IWatchStatusRepository
int? percent
)
{
Episode episode = await _database.Episodes.FirstAsync(x => x.Id == episodeId);
Episode episode = await database.Episodes.FirstAsync(x => x.Id == episodeId);
if (percent == null && watchedTime != null && episode.Runtime > 0)
percent = (int)Math.Round(watchedTime.Value / (episode.Runtime.Value * 60f) * 100f);
@ -484,7 +471,7 @@ public class WatchStatusRepository : IWatchStatusRepository
AddedDate = DateTime.UtcNow,
PlayedDate = status == WatchStatus.Completed ? DateTime.UtcNow : null,
};
await _database
await database
.EpisodeWatchStatus.Upsert(ret)
.UpdateIf(x => status != Watching || x.Status != Completed)
.RunAsync();
@ -495,7 +482,7 @@ public class WatchStatusRepository : IWatchStatusRepository
/// <inheritdoc />
public async Task DeleteEpisodeStatus(Guid episodeId, Guid userId)
{
await _database
await database
.EpisodeWatchStatus.Where(x => x.EpisodeId == episodeId && x.UserId == userId)
.ExecuteDeleteAsync();
}