mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 20:24:27 -04:00
Add watch status changed events
This commit is contained in:
parent
0d91001376
commit
c15dcb02ec
@ -29,12 +29,7 @@ namespace Kyoo.Abstractions.Controllers;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IWatchStatusRepository
|
public interface IWatchStatusRepository
|
||||||
{
|
{
|
||||||
// /// <summary>
|
public delegate Task ResourceEventHandler<T>(T resource);
|
||||||
// /// 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);
|
|
||||||
|
|
||||||
Task<ICollection<IWatchlist>> GetAll(
|
Task<ICollection<IWatchlist>> GetAll(
|
||||||
Filter<IWatchlist>? filter = default,
|
Filter<IWatchlist>? filter = default,
|
||||||
@ -52,12 +47,22 @@ public interface IWatchStatusRepository
|
|||||||
int? percent
|
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 DeleteMovieStatus(Guid movieId, Guid userId);
|
||||||
|
|
||||||
Task<ShowWatchStatus?> GetShowStatus(Guid showId, Guid userId);
|
Task<ShowWatchStatus?> GetShowStatus(Guid showId, Guid userId);
|
||||||
|
|
||||||
Task<ShowWatchStatus?> SetShowStatus(Guid showId, Guid userId, WatchStatus status);
|
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 DeleteShowStatus(Guid showId, Guid userId);
|
||||||
|
|
||||||
Task<EpisodeWatchStatus?> GetEpisodeStatus(Guid episodeId, Guid userId);
|
Task<EpisodeWatchStatus?> GetEpisodeStatus(Guid episodeId, Guid userId);
|
||||||
@ -72,5 +77,10 @@ public interface IWatchStatusRepository
|
|||||||
int? percent
|
int? percent
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static event ResourceEventHandler<Episode> OnEpisodeStatusChangedHandler;
|
||||||
|
|
||||||
|
protected static Task OnEpisodeStatusChanged(Episode obj) =>
|
||||||
|
OnEpisodeStatusChangedHandler?.Invoke(obj) ?? Task.CompletedTask;
|
||||||
|
|
||||||
Task DeleteEpisodeStatus(Guid episodeId, Guid userId);
|
Task DeleteEpisodeStatus(Guid episodeId, Guid userId);
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,12 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
|
|
||||||
namespace Kyoo.Core.Controllers;
|
namespace Kyoo.Core.Controllers;
|
||||||
|
|
||||||
public class WatchStatusRepository : IWatchStatusRepository
|
public class WatchStatusRepository(
|
||||||
|
DatabaseContext database,
|
||||||
|
IRepository<Movie> movies,
|
||||||
|
DbConnection db,
|
||||||
|
SqlVariableContext context
|
||||||
|
) : IWatchStatusRepository
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If the watch percent is below this value, don't consider the item started.
|
/// 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 Completed = WatchStatus.Completed;
|
||||||
private WatchStatus Planned = WatchStatus.Planned;
|
private WatchStatus Planned = WatchStatus.Planned;
|
||||||
|
|
||||||
private readonly DatabaseContext _database;
|
|
||||||
private readonly IRepository<Movie> _movies;
|
|
||||||
private readonly DbConnection _db;
|
|
||||||
private readonly SqlVariableContext _context;
|
|
||||||
|
|
||||||
static WatchStatusRepository()
|
static WatchStatusRepository()
|
||||||
{
|
{
|
||||||
IRepository<Episode>.OnCreated += async (ep) =>
|
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
|
// language=PostgreSQL
|
||||||
protected FormattableString Sql =>
|
protected FormattableString Sql =>
|
||||||
$"""
|
$"""
|
||||||
@ -169,11 +156,11 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task<IWatchlist?> GetOrDefault(Guid id, Include<IWatchlist>? include = null)
|
public Task<IWatchlist?> GetOrDefault(Guid id, Include<IWatchlist>? include = null)
|
||||||
{
|
{
|
||||||
return _db.QuerySingle<IWatchlist>(
|
return db.QuerySingle<IWatchlist>(
|
||||||
Sql,
|
Sql,
|
||||||
Config,
|
Config,
|
||||||
Mapper,
|
Mapper,
|
||||||
_context,
|
context,
|
||||||
include,
|
include,
|
||||||
new Filter<IWatchlist>.Eq(nameof(IResource.Id), id)
|
new Filter<IWatchlist>.Eq(nameof(IResource.Id), id)
|
||||||
);
|
);
|
||||||
@ -208,12 +195,12 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
limit.AfterID = null;
|
limit.AfterID = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await _db.Query(
|
return await db.Query(
|
||||||
Sql,
|
Sql,
|
||||||
Config,
|
Config,
|
||||||
Mapper,
|
Mapper,
|
||||||
(id) => Get(id),
|
(id) => Get(id),
|
||||||
_context,
|
context,
|
||||||
include,
|
include,
|
||||||
filter,
|
filter,
|
||||||
null,
|
null,
|
||||||
@ -224,7 +211,7 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task<MovieWatchStatus?> GetMovieStatus(Guid movieId, Guid userId)
|
public Task<MovieWatchStatus?> GetMovieStatus(Guid movieId, Guid userId)
|
||||||
{
|
{
|
||||||
return _database.MovieWatchStatus.FirstOrDefaultAsync(x =>
|
return database.MovieWatchStatus.FirstOrDefaultAsync(x =>
|
||||||
x.MovieId == movieId && x.UserId == userId
|
x.MovieId == movieId && x.UserId == userId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -238,7 +225,7 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
int? percent
|
int? percent
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Movie movie = await _movies.Get(movieId);
|
Movie movie = await movies.Get(movieId);
|
||||||
|
|
||||||
if (percent == null && watchedTime != null && movie.Runtime > 0)
|
if (percent == null && watchedTime != null && movie.Runtime > 0)
|
||||||
percent = (int)Math.Round(watchedTime.Value / (movie.Runtime.Value * 60f) * 100f);
|
percent = (int)Math.Round(watchedTime.Value / (movie.Runtime.Value * 60f) * 100f);
|
||||||
@ -274,7 +261,7 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
AddedDate = DateTime.UtcNow,
|
AddedDate = DateTime.UtcNow,
|
||||||
PlayedDate = status == WatchStatus.Completed ? DateTime.UtcNow : null,
|
PlayedDate = status == WatchStatus.Completed ? DateTime.UtcNow : null,
|
||||||
};
|
};
|
||||||
await _database
|
await database
|
||||||
.MovieWatchStatus.Upsert(ret)
|
.MovieWatchStatus.Upsert(ret)
|
||||||
.UpdateIf(x => status != Watching || x.Status != Completed)
|
.UpdateIf(x => status != Watching || x.Status != Completed)
|
||||||
.RunAsync();
|
.RunAsync();
|
||||||
@ -284,7 +271,7 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task DeleteMovieStatus(Guid movieId, Guid userId)
|
public async Task DeleteMovieStatus(Guid movieId, Guid userId)
|
||||||
{
|
{
|
||||||
await _database
|
await database
|
||||||
.MovieWatchStatus.Where(x => x.MovieId == movieId && x.UserId == userId)
|
.MovieWatchStatus.Where(x => x.MovieId == movieId && x.UserId == userId)
|
||||||
.ExecuteDeleteAsync();
|
.ExecuteDeleteAsync();
|
||||||
}
|
}
|
||||||
@ -292,7 +279,7 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task<ShowWatchStatus?> GetShowStatus(Guid showId, Guid userId)
|
public Task<ShowWatchStatus?> GetShowStatus(Guid showId, Guid userId)
|
||||||
{
|
{
|
||||||
return _database.ShowWatchStatus.FirstOrDefaultAsync(x =>
|
return database.ShowWatchStatus.FirstOrDefaultAsync(x =>
|
||||||
x.ShowId == showId && x.UserId == userId
|
x.ShowId == showId && x.UserId == userId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -310,7 +297,7 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
{
|
{
|
||||||
int unseenEpisodeCount =
|
int unseenEpisodeCount =
|
||||||
status != WatchStatus.Completed
|
status != WatchStatus.Completed
|
||||||
? await _database
|
? await database
|
||||||
.Episodes.Where(x => x.ShowId == showId)
|
.Episodes.Where(x => x.ShowId == showId)
|
||||||
.Where(x =>
|
.Where(x =>
|
||||||
x.Watched!.First(x => x.UserId == userId)!.Status != WatchStatus.Completed
|
x.Watched!.First(x => x.UserId == userId)!.Status != WatchStatus.Completed
|
||||||
@ -324,7 +311,7 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
Guid? nextEpisodeId = null;
|
Guid? nextEpisodeId = null;
|
||||||
if (status == WatchStatus.Watching)
|
if (status == WatchStatus.Watching)
|
||||||
{
|
{
|
||||||
var cursor = await _database
|
var cursor = await database
|
||||||
.Episodes.IgnoreQueryFilters()
|
.Episodes.IgnoreQueryFilters()
|
||||||
.Where(x => x.ShowId == showId)
|
.Where(x => x.ShowId == showId)
|
||||||
.OrderByDescending(x => x.AbsoluteNumber)
|
.OrderByDescending(x => x.AbsoluteNumber)
|
||||||
@ -346,7 +333,7 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
nextEpisodeId =
|
nextEpisodeId =
|
||||||
cursor?.Status.Status == WatchStatus.Watching
|
cursor?.Status.Status == WatchStatus.Watching
|
||||||
? cursor.Id
|
? cursor.Id
|
||||||
: await _database
|
: await database
|
||||||
.Episodes.IgnoreQueryFilters()
|
.Episodes.IgnoreQueryFilters()
|
||||||
.Where(x => x.ShowId == showId)
|
.Where(x => x.ShowId == showId)
|
||||||
.OrderBy(x => x.AbsoluteNumber)
|
.OrderBy(x => x.AbsoluteNumber)
|
||||||
@ -374,11 +361,11 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
}
|
}
|
||||||
else if (status == WatchStatus.Completed)
|
else if (status == WatchStatus.Completed)
|
||||||
{
|
{
|
||||||
List<Guid> episodes = await _database
|
List<Guid> episodes = await database
|
||||||
.Episodes.Where(x => x.ShowId == showId)
|
.Episodes.Where(x => x.ShowId == showId)
|
||||||
.Select(x => x.Id)
|
.Select(x => x.Id)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
await _database
|
await database
|
||||||
.EpisodeWatchStatus.UpsertRange(
|
.EpisodeWatchStatus.UpsertRange(
|
||||||
episodes.Select(episodeId => new EpisodeWatchStatus
|
episodes.Select(episodeId => new EpisodeWatchStatus
|
||||||
{
|
{
|
||||||
@ -412,7 +399,7 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
UnseenEpisodesCount = unseenEpisodeCount,
|
UnseenEpisodesCount = unseenEpisodeCount,
|
||||||
PlayedDate = status == WatchStatus.Completed ? DateTime.UtcNow : null,
|
PlayedDate = status == WatchStatus.Completed ? DateTime.UtcNow : null,
|
||||||
};
|
};
|
||||||
await _database
|
await database
|
||||||
.ShowWatchStatus.Upsert(ret)
|
.ShowWatchStatus.Upsert(ret)
|
||||||
.UpdateIf(x => status != Watching || x.Status != Completed || newEpisode)
|
.UpdateIf(x => status != Watching || x.Status != Completed || newEpisode)
|
||||||
.RunAsync();
|
.RunAsync();
|
||||||
@ -422,11 +409,11 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task DeleteShowStatus(Guid showId, Guid userId)
|
public async Task DeleteShowStatus(Guid showId, Guid userId)
|
||||||
{
|
{
|
||||||
await _database
|
await database
|
||||||
.ShowWatchStatus.IgnoreAutoIncludes()
|
.ShowWatchStatus.IgnoreAutoIncludes()
|
||||||
.Where(x => x.ShowId == showId && x.UserId == userId)
|
.Where(x => x.ShowId == showId && x.UserId == userId)
|
||||||
.ExecuteDeleteAsync();
|
.ExecuteDeleteAsync();
|
||||||
await _database
|
await database
|
||||||
.EpisodeWatchStatus.Where(x => x.Episode.ShowId == showId && x.UserId == userId)
|
.EpisodeWatchStatus.Where(x => x.Episode.ShowId == showId && x.UserId == userId)
|
||||||
.ExecuteDeleteAsync();
|
.ExecuteDeleteAsync();
|
||||||
}
|
}
|
||||||
@ -434,7 +421,7 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task<EpisodeWatchStatus?> GetEpisodeStatus(Guid episodeId, Guid userId)
|
public Task<EpisodeWatchStatus?> GetEpisodeStatus(Guid episodeId, Guid userId)
|
||||||
{
|
{
|
||||||
return _database.EpisodeWatchStatus.FirstOrDefaultAsync(x =>
|
return database.EpisodeWatchStatus.FirstOrDefaultAsync(x =>
|
||||||
x.EpisodeId == episodeId && x.UserId == userId
|
x.EpisodeId == episodeId && x.UserId == userId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -448,7 +435,7 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
int? percent
|
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)
|
if (percent == null && watchedTime != null && episode.Runtime > 0)
|
||||||
percent = (int)Math.Round(watchedTime.Value / (episode.Runtime.Value * 60f) * 100f);
|
percent = (int)Math.Round(watchedTime.Value / (episode.Runtime.Value * 60f) * 100f);
|
||||||
@ -484,7 +471,7 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
AddedDate = DateTime.UtcNow,
|
AddedDate = DateTime.UtcNow,
|
||||||
PlayedDate = status == WatchStatus.Completed ? DateTime.UtcNow : null,
|
PlayedDate = status == WatchStatus.Completed ? DateTime.UtcNow : null,
|
||||||
};
|
};
|
||||||
await _database
|
await database
|
||||||
.EpisodeWatchStatus.Upsert(ret)
|
.EpisodeWatchStatus.Upsert(ret)
|
||||||
.UpdateIf(x => status != Watching || x.Status != Completed)
|
.UpdateIf(x => status != Watching || x.Status != Completed)
|
||||||
.RunAsync();
|
.RunAsync();
|
||||||
@ -495,7 +482,7 @@ public class WatchStatusRepository : IWatchStatusRepository
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task DeleteEpisodeStatus(Guid episodeId, Guid userId)
|
public async Task DeleteEpisodeStatus(Guid episodeId, Guid userId)
|
||||||
{
|
{
|
||||||
await _database
|
await database
|
||||||
.EpisodeWatchStatus.Where(x => x.EpisodeId == episodeId && x.UserId == userId)
|
.EpisodeWatchStatus.Where(x => x.EpisodeId == episodeId && x.UserId == userId)
|
||||||
.ExecuteDeleteAsync();
|
.ExecuteDeleteAsync();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user