Accept movie progress from all clients and return resume position on movie detail.
This commit is contained in:
parent
e6607654a2
commit
b783ba137f
2 changed files with 23 additions and 5 deletions
|
|
@ -642,9 +642,9 @@ export function registerViewerRoutes(
|
||||||
|
|
||||||
app.get("/api/v1/client/movies/:id", async (request) => {
|
app.get("/api/v1/client/movies/:id", async (request) => {
|
||||||
const auth = await viewers.authFromBearer(request.headers.authorization);
|
const auth = await viewers.authFromBearer(request.headers.authorization);
|
||||||
requireProfile(auth);
|
const profileId = requireProfile(auth);
|
||||||
const { id } = request.params as { id: string };
|
const { id } = request.params as { id: string };
|
||||||
return viewers.movieDetail(id, auth.profile?.isKids === true);
|
return viewers.movieDetail(id, auth.profile?.isKids === true, profileId);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/api/v1/client/series/:id", async (request) => {
|
app.get("/api/v1/client/series/:id", async (request) => {
|
||||||
|
|
@ -684,8 +684,12 @@ export function registerViewerRoutes(
|
||||||
hiddenFromContinue?: boolean;
|
hiddenFromContinue?: boolean;
|
||||||
};
|
};
|
||||||
if (!body.mediaType) throw new AppError("INVALID_REQUEST", "mediaType verplicht", 400);
|
if (!body.mediaType) throw new AppError("INVALID_REQUEST", "mediaType verplicht", 400);
|
||||||
|
const mediaType = String(body.mediaType).trim().toUpperCase();
|
||||||
|
if (mediaType !== "MOVIE" && mediaType !== "EPISODE") {
|
||||||
|
throw new AppError("INVALID_REQUEST", "mediaType moet MOVIE of EPISODE zijn", 400);
|
||||||
|
}
|
||||||
const row = await viewers.upsertProgress(profileId, {
|
const row = await viewers.upsertProgress(profileId, {
|
||||||
mediaType: body.mediaType,
|
mediaType: mediaType as "MOVIE" | "EPISODE",
|
||||||
movieId: body.movieId,
|
movieId: body.movieId,
|
||||||
episodeId: body.episodeId,
|
episodeId: body.episodeId,
|
||||||
seriesId: body.seriesId,
|
seriesId: body.seriesId,
|
||||||
|
|
|
||||||
|
|
@ -2026,13 +2026,17 @@ export class ViewerService {
|
||||||
hiddenFromContinue?: boolean;
|
hiddenFromContinue?: boolean;
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
const mediaType = String(body.mediaType || "").trim().toUpperCase();
|
||||||
|
if (mediaType !== "MOVIE" && mediaType !== "EPISODE") {
|
||||||
|
throw new AppError("INVALID_REQUEST", "mediaType moet MOVIE of EPISODE zijn", 400);
|
||||||
|
}
|
||||||
const positionMs = Math.max(0, Math.floor(body.positionMs || 0));
|
const positionMs = Math.max(0, Math.floor(body.positionMs || 0));
|
||||||
const durationMs = Math.max(0, Math.floor(body.durationMs || 0));
|
const durationMs = Math.max(0, Math.floor(body.durationMs || 0));
|
||||||
const autoComplete =
|
const autoComplete =
|
||||||
body.completed === true ||
|
body.completed === true ||
|
||||||
(durationMs > 0 && positionMs / durationMs >= 0.9);
|
(durationMs > 0 && positionMs / durationMs >= 0.9);
|
||||||
|
|
||||||
if (body.mediaType === "MOVIE") {
|
if (mediaType === "MOVIE") {
|
||||||
if (!body.movieId) throw new AppError("INVALID_REQUEST", "movieId verplicht", 400);
|
if (!body.movieId) throw new AppError("INVALID_REQUEST", "movieId verplicht", 400);
|
||||||
const existingMovie = await prisma.watchProgress.findUnique({
|
const existingMovie = await prisma.watchProgress.findUnique({
|
||||||
where: { profileId_movieId: { profileId, movieId: body.movieId } },
|
where: { profileId_movieId: { profileId, movieId: body.movieId } },
|
||||||
|
|
@ -2523,7 +2527,7 @@ export class ViewerService {
|
||||||
return this.getShelfPrefs(profileId);
|
return this.getShelfPrefs(profileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async movieDetail(movieId: string, kidsMode = false) {
|
async movieDetail(movieId: string, kidsMode = false, profileId?: string | null) {
|
||||||
const movie = await prisma.movie.findUnique({
|
const movie = await prisma.movie.findUnique({
|
||||||
where: { id: movieId },
|
where: { id: movieId },
|
||||||
include: {
|
include: {
|
||||||
|
|
@ -2552,6 +2556,12 @@ export class ViewerService {
|
||||||
.catch(() => undefined);
|
.catch(() => undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const progress = profileId
|
||||||
|
? await prisma.watchProgress.findUnique({
|
||||||
|
where: { profileId_movieId: { profileId, movieId: movie.id } },
|
||||||
|
})
|
||||||
|
: null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "movie" as const,
|
type: "movie" as const,
|
||||||
id: movie.id,
|
id: movie.id,
|
||||||
|
|
@ -2567,6 +2577,10 @@ export class ViewerService {
|
||||||
cast: extras.cast ?? [],
|
cast: extras.cast ?? [],
|
||||||
director: extras.director ?? [],
|
director: extras.director ?? [],
|
||||||
trailerYoutubeKey: extras.trailers?.[0]?.source ?? null,
|
trailerYoutubeKey: extras.trailers?.[0]?.source ?? null,
|
||||||
|
positionMs: progress && !progress.completed ? progress.positionMs : 0,
|
||||||
|
durationMs: progress?.durationMs ?? 0,
|
||||||
|
completed: progress?.completed === true,
|
||||||
|
progressId: progress?.id ?? null,
|
||||||
mediaFiles: movie.mediaFiles.map((f, index) => ({
|
mediaFiles: movie.mediaFiles.map((f, index) => ({
|
||||||
id: f.id,
|
id: f.id,
|
||||||
resolution: cleanMeta(f.resolution),
|
resolution: cleanMeta(f.resolution),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue