Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/summary comments #428

Merged
merged 10 commits into from
Feb 12, 2025
5 changes: 5 additions & 0 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { z } from '../z.ts';

export const commentsSortParamsSchema = z.object({
sort: z.enum([
'newest',
'oldest',
'likes',
'replies',
'highest',
'lowest',
'plays',
]),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { z } from '../z.ts';
import { profileResponseSchema } from './userProfileResponseSchema.ts';

export const commentReponseSchema = z.object({
id: z.number(),
parent_id: z.number(),
created_at: z.string(),
updated_at: z.string(),
comment: z.string(),
spoiler: z.boolean(),
review: z.boolean(),
replies: z.number(),
likes: z.number(),
user_rating: z.number().nullable(),
user_stats: z.object({
rating: z.number().nullable(),
play_count: z.number(),
completed_count: z.number(),
}),
user: profileResponseSchema,
});
12 changes: 12 additions & 0 deletions projects/api/src/contracts/movies/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { builder } from '../_internal/builder.ts';
import { commentsSortParamsSchema } from '../_internal/request/commentsSortParamsSchema.ts';
import { extendedQuerySchemaFactory } from '../_internal/request/extendedQuerySchemaFactory.ts';
import { idParamsSchema } from '../_internal/request/idParamsSchema.ts';
import { languageParamsSchema } from '../_internal/request/languageParamsSchema.ts';
import { pageQuerySchema } from '../_internal/request/pageQuerySchema.ts';
import { watchNowParamsSchema } from '../_internal/request/watchNowParamsSchema.ts';
import { commentReponseSchema } from '../_internal/response/commentResponseSchema.ts';
import type { genreResponseSchema } from '../_internal/response/genreResponseSchema.ts';
import type { jobResponseSchema } from '../_internal/response/jobResponseSchema.ts';
import { listResponseSchema } from '../_internal/response/listResponseSchema.ts';
Expand Down Expand Up @@ -119,6 +121,15 @@ const ENTITY_LEVEL = builder.router({
200: listResponseSchema.array(),
},
},
comments: {
path: '/comments/:sort',
method: 'GET',
query: extendedQuerySchemaFactory<['full', 'images']>(),
pathParams: idParamsSchema.merge(commentsSortParamsSchema),
responses: {
200: commentReponseSchema.array(),
},
},
}, {
pathPrefix: '/:id',
});
Expand Down Expand Up @@ -176,6 +187,7 @@ export type PeopleResponse = z.infer<typeof peopleResponseSchema>;
export type CrewResponse = z.infer<typeof crewSchema>;
export type CastResponse = z.infer<typeof castSchema>;
export type ListResponse = z.infer<typeof listResponseSchema>;
export type CommentResponse = z.infer<typeof commentReponseSchema>;

export type MovieTranslationResponse = z.infer<
typeof translationResponseSchema
Expand Down
11 changes: 11 additions & 0 deletions projects/api/src/contracts/shows/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { builder } from '../_internal/builder.ts';
import { commentsSortParamsSchema } from '../_internal/request/commentsSortParamsSchema.ts';
import { extendedQuerySchemaFactory } from '../_internal/request/extendedQuerySchemaFactory.ts';
import { idParamsSchema } from '../_internal/request/idParamsSchema.ts';
import { languageParamsSchema } from '../_internal/request/languageParamsSchema.ts';
import { pageQuerySchema } from '../_internal/request/pageQuerySchema.ts';
import { statsQuerySchema } from '../_internal/request/statsQuerySchema.ts';
import { watchNowParamsSchema } from '../_internal/request/watchNowParamsSchema.ts';
import { commentReponseSchema } from '../_internal/response/commentResponseSchema.ts';
import { episodeResponseSchema } from '../_internal/response/episodeResponseSchema.ts';
import { episodeStatsResponseSchema } from '../_internal/response/episodeStatsResponseSchema.ts';
import { episodeTranslationResponseSchema } from '../_internal/response/episodeTranslationResponseSchema.ts';
Expand Down Expand Up @@ -205,6 +207,15 @@ const ENTITY_LEVEL = builder.router({
200: listResponseSchema.array(),
},
},
comments: {
path: '/comments/:sort',
method: 'GET',
pathParams: idParamsSchema.merge(commentsSortParamsSchema),
query: extendedQuerySchemaFactory<['full', 'images']>(),
responses: {
200: commentReponseSchema.array(),
},
},
}, {
pathPrefix: '/:id',
});
Expand Down
6 changes: 5 additions & 1 deletion projects/client/i18n/messages/de-de.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,5 +278,9 @@
"no_popular_lists": "{title} taucht in keinen beliebten Listen auf.",
"by": "von",
"users_avatar": "{userName}'s Avatar",
"media_poster": "{title} Poster"
"media_poster": "{title} Poster",
"popular_comments": "Beliebte Kommentare",
"no_comments": "Noch keine Kommentare. Sei der/die Erste!",
"review_by": "Review von",
"shout_by": "Shout von"
}
6 changes: 5 additions & 1 deletion projects/client/i18n/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,5 +278,9 @@
"no_popular_lists": "{title} does not appear on any popular lists.",
"by": "by",
"users_avatar": "{userName}'s avatar",
"media_poster": "{title} poster"
"media_poster": "{title} poster",
"popular_comments": "Popular comments",
"no_comments": "No comments yet.",
"review_by": "Review by",
"shout_by": "Shout by"
}
6 changes: 5 additions & 1 deletion projects/client/i18n/messages/es-es.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,5 +278,9 @@
"no_popular_lists": "{title} no aparece en ninguna lista popular.",
"by": "por",
"users_avatar": "Avatar de {userName}",
"media_poster": "Póster de {title}"
"media_poster": "Póster de {title}",
"popular_comments": "Comentarios populares",
"no_comments": "Aún no hay comentarios.",
"review_by": "Reseña de",
"shout_by": "Grito de"
}
6 changes: 5 additions & 1 deletion projects/client/i18n/messages/es-mx.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,5 +278,9 @@
"no_popular_lists": "{title} no aparece en ninguna lista popular.",
"by": "por",
"users_avatar": "Avatar de {userName}",
"media_poster": "Póster de {title}"
"media_poster": "Póster de {title}",
"popular_comments": "Comentarios populares",
"no_comments": "Aún no hay comentarios.",
"review_by": "Reseña de",
"shout_by": "Grito de"
}
6 changes: 5 additions & 1 deletion projects/client/i18n/messages/fr-ca.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,5 +278,9 @@
"no_popular_lists": "{title} ne figure dans aucune liste populaire.",
"by": "par",
"users_avatar": "Avatar de {userName}",
"media_poster": "Affiche de {title}"
"media_poster": "Affiche de {title}",
"popular_comments": "Commentaires populaires",
"no_comments": "Aucun commentaire pour l'instant.",
"review_by": "Critique par",
"shout_by": "Crié par"
}
6 changes: 5 additions & 1 deletion projects/client/i18n/messages/fr-fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,5 +278,9 @@
"no_popular_lists": "{title} n'apparaît dans aucune liste populaire.",
"by": "par",
"users_avatar": "Avatar de {userName}",
"media_poster": "Affiche de {title}"
"media_poster": "Affiche de {title}",
"popular_comments": "Commentaires populaires",
"no_comments": "Pas encore de commentaires.",
"review_by": "Critique par",
"shout_by": "Crié par"
}
6 changes: 5 additions & 1 deletion projects/client/i18n/messages/it-it.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,5 +278,9 @@
"no_popular_lists": "{title} non compare in nessuna lista popolare.",
"by": "di",
"users_avatar": "Avatar di {userName}",
"media_poster": "Locandina di {title}"
"media_poster": "Locandina di {title}",
"popular_comments": "Commenti popolari",
"no_comments": "Nessun commento per ora.",
"review_by": "Recensione di",
"shout_by": "Grido di"
}
6 changes: 5 additions & 1 deletion projects/client/i18n/messages/ja-jp.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,5 +278,9 @@
"no_popular_lists": "{title}は人気のリストには見当たりません。",
"by": "作成者",
"users_avatar": "{userName}のアバター",
"media_poster": "{title}のポスター"
"media_poster": "{title}のポスター",
"popular_comments": "人気のコメント",
"no_comments": "まだコメントはありません。",
"review_by": "レビュー:",
"shout_by": "シャウト:"
}
6 changes: 5 additions & 1 deletion projects/client/i18n/messages/nl-nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,5 +278,9 @@
"no_popular_lists": "{title} staat niet op populaire lijsten.",
"by": "door",
"users_avatar": "Avatar van {userName}",
"media_poster": "{title} poster"
"media_poster": "{title} poster",
"popular_comments": "Populaire reacties",
"no_comments": "Nog geen reacties.",
"review_by": "Review door",
"shout_by": "Geschreeuwd door"
}
6 changes: 5 additions & 1 deletion projects/client/i18n/messages/pl-pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,5 +278,9 @@
"no_popular_lists": "{title} nie pojawia się na żadnych popularnych listach. Wygląda na to, że nikt nie wpadł na to, żeby go umieścić... jeszcze!",
"by": "przez",
"users_avatar": "Awatar użytkownika {userName}",
"media_poster": "Plakat {title}"
"media_poster": "Plakat {title}",
"popular_comments": "Popularne komentarze",
"no_comments": "Jeszcze brak komentarzy.",
"review_by": "Recenzja od",
"shout_by": "Krzyknął"
}
6 changes: 5 additions & 1 deletion projects/client/i18n/messages/pt-br.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,5 +278,9 @@
"no_popular_lists": "{title} não aparece em nenhuma lista popular.",
"by": "de",
"users_avatar": "Avatar de {userName}",
"media_poster": "Pôster de {title}"
"media_poster": "Pôster de {title}",
"popular_comments": "Comentários populares",
"no_comments": "Sem comentários por enquanto. Seja o primeiro!",
"review_by": "Crítica por",
"shout_by": "Grito por"
}
6 changes: 5 additions & 1 deletion projects/client/i18n/messages/ro-ro.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,5 +278,9 @@
"no_popular_lists": "{title} nu apare în nicio listă populară.",
"by": "de",
"users_avatar": "Avatarul lui {userName}",
"media_poster": "Posterul {title}"
"media_poster": "Posterul {title}",
"popular_comments": "Comentarii populare",
"no_comments": "Încă nu sunt comentarii.",
"review_by": "Recenzie de",
"shout_by": "Strigăt de"
}
6 changes: 5 additions & 1 deletion projects/client/i18n/messages/uk-ua.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,5 +278,9 @@
"no_popular_lists": "{title} не з'являється в жодному популярному списку.",
"by": "від",
"users_avatar": "Аватар {userName}",
"media_poster": "Постер {title}"
"media_poster": "Постер {title}",
"popular_comments": "Популярні коментарі",
"no_comments": "Ще немає коментарів.",
"review_by": "Огляд від",
"shout_by": "Вигук від"
}
1 change: 1 addition & 0 deletions projects/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"eslint-plugin-svelte": "^2.46.1",
"globals": "^15.14.0",
"jsdom": "^26.0.0",
"marked": "^15.0.6",
"msw": "^2.7.0",
"playwright": "^1.50.1",
"prettier": "^3.4.2",
Expand Down
14 changes: 1 addition & 13 deletions projects/client/src/lib/components/link/Link.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,7 @@
}

&[data-color="default"] {
text-decoration-color: var(--color-link-active);

&,
&:visited {
color: var(--color-foreground);
}

@include for-mouse {
&:hover,
&:focus-visible {
color: var(--color-link-active);
}
}
@include default-link-style;

&.trakt-link-active {
&,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SPOILER_CLASS_NAME } from '$lib/features/spoilers/constants.ts';
import { clone } from '$lib/utils/object/clone.ts';
import { deepAssign } from '$lib/utils/object/deepAssign.ts';
import { ExtendedUsersResponseMock } from '$mocks/data/users/response/ExtendedUserSettingsResponseMock.ts';
Expand Down Expand Up @@ -46,7 +47,7 @@ describe('action: useSpoilerAction', () => {
spoiler(node);

await waitFor(() =>
expect(node.classList.contains('trakt-spoiler')).toBe(true)
expect(node.classList.contains(SPOILER_CLASS_NAME)).toBe(true)
);
});

Expand All @@ -61,10 +62,10 @@ describe('action: useSpoilerAction', () => {
})
);

node.classList.add('trakt-spoiler');
node.classList.add(SPOILER_CLASS_NAME);
spoiler(node);

expect(node.classList.contains('trakt-spoiler')).toBe(false);
expect(node.classList.contains(SPOILER_CLASS_NAME)).toBe(false);
});

it('should NOT remove the spoiler class when a show is unwatched', async () => {
Expand Down Expand Up @@ -104,11 +105,11 @@ describe('action: useSpoilerAction', () => {
spoiler(node);

// Remove the class to the node
node.classList.remove('trakt-spoiler');
node.classList.remove(SPOILER_CLASS_NAME);

// Then verify it is removed
await waitFor(
() => expect(node.classList.contains('trakt-spoiler')).toBe(true),
() => expect(node.classList.contains(SPOILER_CLASS_NAME)).toBe(true),
);
});

Expand Down Expand Up @@ -149,11 +150,11 @@ describe('action: useSpoilerAction', () => {
spoiler(node);

// Add the class to the node
node.classList.add('trakt-spoiler');
node.classList.add(SPOILER_CLASS_NAME);

// Then verify it is removed
await waitFor(
() => expect(node.classList.contains('trakt-spoiler')).toBe(false),
() => expect(node.classList.contains(SPOILER_CLASS_NAME)).toBe(false),
);
});
});
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SPOILER_CLASS_NAME } from '$lib/features/spoilers/constants.ts';
import type { MediaStoreProps } from '$lib/models/MediaStoreProps.ts';
import { useMediaSpoiler } from '../useMediaSpoiler.ts';

Expand All @@ -8,11 +9,11 @@ export function useSpoilerAction(rest: SpoilerActionProps) {

function spoiler(node: HTMLElement) {
const add = () => {
node.classList.add('trakt-spoiler');
node.classList.add(SPOILER_CLASS_NAME);
};

const remove = () => {
node.classList.remove('trakt-spoiler');
node.classList.remove(SPOILER_CLASS_NAME);
};

function applySpoilerStyle(isHidden: boolean) {
Expand All @@ -29,7 +30,7 @@ export function useSpoilerAction(rest: SpoilerActionProps) {
return {
destroy() {
unsubscribe();
node.classList.remove('trakt-spoiler');
node.classList.remove(SPOILER_CLASS_NAME);
},
};
}
Expand Down
1 change: 1 addition & 0 deletions projects/client/src/lib/features/spoilers/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const SPOILER_CLASS_NAME = 'trakt-spoiler';
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { MediaStoreProps } from '$lib/models/MediaStoreProps.ts';
import {
useIsWatched,
} from '$lib/sections/media-actions/mark-as-watched/useIsWatched';
} from '$lib/sections/media-actions/mark-as-watched/useIsWatched.ts';
import { derived } from 'svelte/store';
import { useSpoiler } from './_internal/useSpoiler.ts';

Expand Down
Loading
Loading