diff --git a/api/src/controllers/entries.ts b/api/src/controllers/entries.ts index b994b8c2..3919e4ce 100644 --- a/api/src/controllers/entries.ts +++ b/api/src/controllers/entries.ts @@ -1,4 +1,4 @@ -import { type SQL, and, desc, eq, isNotNull, ne, sql } from "drizzle-orm"; +import { and, desc, eq, isNotNull, ne, type SQL, sql } from "drizzle-orm"; import { Elysia, t } from "elysia"; import { auth } from "~/auth"; import { db } from "~/db"; @@ -31,14 +31,14 @@ import { KError } from "~/models/error"; import { madeInAbyss } from "~/models/examples"; import { AcceptLanguage, + createPage, Filter, type FilterDef, - Page, - Sort, - createPage, isUuid, keysetPaginate, + Page, processLanguages, + Sort, sortToSql, } from "~/models/utils"; import { desc as description } from "~/models/utils/descriptions"; diff --git a/api/src/controllers/profiles/history.ts b/api/src/controllers/profiles/history.ts index a2d9c32b..41d997f1 100644 --- a/api/src/controllers/profiles/history.ts +++ b/api/src/controllers/profiles/history.ts @@ -11,10 +11,10 @@ import { KError } from "~/models/error"; import { SeedHistory } from "~/models/history"; import { AcceptLanguage, - Filter, - Page, createPage, + Filter, isUuid, + Page, processLanguages, } from "~/models/utils"; import { desc } from "~/models/utils/descriptions"; diff --git a/api/src/controllers/profiles/nextup.ts b/api/src/controllers/profiles/nextup.ts index 142ae634..78cd6433 100644 --- a/api/src/controllers/profiles/nextup.ts +++ b/api/src/controllers/profiles/nextup.ts @@ -8,13 +8,13 @@ import { getColumns, sqlarr } from "~/db/utils"; import { Entry } from "~/models/entry"; import { AcceptLanguage, + createPage, Filter, type FilterDef, - Page, - Sort, - createPage, keysetPaginate, + Page, processLanguages, + Sort, sortToSql, } from "~/models/utils"; import { desc } from "~/models/utils/descriptions"; diff --git a/api/src/controllers/profiles/watchlist.ts b/api/src/controllers/profiles/watchlist.ts index 5adf5f16..1471213e 100644 --- a/api/src/controllers/profiles/watchlist.ts +++ b/api/src/controllers/profiles/watchlist.ts @@ -18,11 +18,11 @@ import { Movie } from "~/models/movie"; import { Serie } from "~/models/serie"; import { AcceptLanguage, + createPage, DbMetadata, Filter, - Page, - createPage, isUuid, + Page, processLanguages, } from "~/models/utils"; import { desc } from "~/models/utils/descriptions"; diff --git a/api/src/controllers/seasons.ts b/api/src/controllers/seasons.ts index 82b61462..91af3032 100644 --- a/api/src/controllers/seasons.ts +++ b/api/src/controllers/seasons.ts @@ -1,20 +1,20 @@ import { and, eq, sql } from "drizzle-orm"; import { Elysia, t } from "elysia"; import { db } from "~/db"; -import { seasonTranslations, seasons, shows } from "~/db/schema"; +import { seasons, seasonTranslations, shows } from "~/db/schema"; import { getColumns, sqlarr } from "~/db/utils"; import { KError } from "~/models/error"; import { madeInAbyss } from "~/models/examples"; import { AcceptLanguage, + createPage, Filter, type FilterDef, - Page, - Sort, - createPage, isUuid, keysetPaginate, + Page, processLanguages, + Sort, sortToSql, } from "~/models/utils"; import { desc } from "~/models/utils/descriptions"; diff --git a/api/src/controllers/seed/images.ts b/api/src/controllers/seed/images.ts index 0961d44e..fd31f838 100644 --- a/api/src/controllers/seed/images.ts +++ b/api/src/controllers/seed/images.ts @@ -1,11 +1,11 @@ import path from "node:path"; import { encode } from "blurhash"; -import { type SQL, and, eq, is, lt, sql } from "drizzle-orm"; +import { and, eq, is, lt, type SQL, sql } from "drizzle-orm"; import { PgColumn, type PgTable } from "drizzle-orm/pg-core"; import { version } from "package.json"; import type { PoolClient } from "pg"; import sharp from "sharp"; -import { type Transaction, db } from "~/db"; +import { db, type Transaction } from "~/db"; import { mqueue } from "~/db/schema/mqueue"; import type { Image } from "~/models/utils"; import { getFile } from "~/utils"; diff --git a/api/src/controllers/seed/insert/collection.ts b/api/src/controllers/seed/insert/collection.ts index b5a1e65a..024c3307 100644 --- a/api/src/controllers/seed/insert/collection.ts +++ b/api/src/controllers/seed/insert/collection.ts @@ -1,6 +1,6 @@ import { sql } from "drizzle-orm"; import { db } from "~/db"; -import { showTranslations, shows } from "~/db/schema"; +import { shows, showTranslations } from "~/db/schema"; import { conflictUpdateAllExcept } from "~/db/utils"; import type { SeedCollection } from "~/models/collections"; import type { SeedMovie } from "~/models/movie"; diff --git a/api/src/controllers/seed/insert/entries.ts b/api/src/controllers/seed/insert/entries.ts index 592ff4dd..f6c0561c 100644 --- a/api/src/controllers/seed/insert/entries.ts +++ b/api/src/controllers/seed/insert/entries.ts @@ -1,4 +1,4 @@ -import { type Column, type SQL, eq, sql } from "drizzle-orm"; +import { type Column, eq, type SQL, sql } from "drizzle-orm"; import { db } from "~/db"; import { entries, diff --git a/api/src/controllers/seed/insert/seasons.ts b/api/src/controllers/seed/insert/seasons.ts index f3075380..04342c8f 100644 --- a/api/src/controllers/seed/insert/seasons.ts +++ b/api/src/controllers/seed/insert/seasons.ts @@ -1,5 +1,5 @@ import { db } from "~/db"; -import { seasonTranslations, seasons } from "~/db/schema"; +import { seasons, seasonTranslations } from "~/db/schema"; import { conflictUpdateAllExcept } from "~/db/utils"; import type { SeedSeason } from "~/models/season"; import { enqueueOptImage } from "../images"; diff --git a/api/src/controllers/seed/insert/shows.ts b/api/src/controllers/seed/insert/shows.ts index 6841e8fb..e2fa588e 100644 --- a/api/src/controllers/seed/insert/shows.ts +++ b/api/src/controllers/seed/insert/shows.ts @@ -1,15 +1,15 @@ import { - type SQLWrapper, and, count, eq, exists, isNull, ne, + type SQLWrapper, sql, } from "drizzle-orm"; -import { type Transaction, db } from "~/db"; -import { entries, entryVideoJoin, showTranslations, shows } from "~/db/schema"; +import { db, type Transaction } from "~/db"; +import { entries, entryVideoJoin, shows, showTranslations } from "~/db/schema"; import { conflictUpdateAllExcept, sqlarr } from "~/db/utils"; import type { SeedCollection } from "~/models/collections"; import type { SeedMovie } from "~/models/movie"; diff --git a/api/src/controllers/seed/insert/studios.ts b/api/src/controllers/seed/insert/studios.ts index 7eef1bd1..e8a856c9 100644 --- a/api/src/controllers/seed/insert/studios.ts +++ b/api/src/controllers/seed/insert/studios.ts @@ -1,5 +1,5 @@ import { db } from "~/db"; -import { showStudioJoin, studioTranslations, studios } from "~/db/schema"; +import { showStudioJoin, studios, studioTranslations } from "~/db/schema"; import { conflictUpdateAllExcept } from "~/db/utils"; import type { SeedStudio } from "~/models/studio"; import { enqueueOptImage } from "../images"; diff --git a/api/src/controllers/seed/refresh.ts b/api/src/controllers/seed/refresh.ts index 2f142eaa..8dfcb47d 100644 --- a/api/src/controllers/seed/refresh.ts +++ b/api/src/controllers/seed/refresh.ts @@ -1,7 +1,7 @@ // oh i hate js dates so much. export const guessNextRefresh = (airDate: Date | string) => { if (typeof airDate === "string") airDate = new Date(airDate); - const diff = new Date().getTime() - airDate.getTime(); + const diff = Date.now() - airDate.getTime(); const days = diff / (24 * 60 * 60 * 1000); const ret = new Date(); diff --git a/api/src/controllers/shows/collections.ts b/api/src/controllers/shows/collections.ts index 780cd9fb..34ddf4fd 100644 --- a/api/src/controllers/shows/collections.ts +++ b/api/src/controllers/shows/collections.ts @@ -16,10 +16,10 @@ import { Serie } from "~/models/serie"; import { Show } from "~/models/show"; import { AcceptLanguage, - Filter, - Page, createPage, + Filter, isUuid, + Page, processLanguages, } from "~/models/utils"; import { desc } from "~/models/utils/descriptions"; diff --git a/api/src/controllers/shows/logic.ts b/api/src/controllers/shows/logic.ts index 4fb3acf7..e1365d26 100644 --- a/api/src/controllers/shows/logic.ts +++ b/api/src/controllers/shows/logic.ts @@ -1,4 +1,4 @@ -import { and, eq, exists, gt, ne, type SQL, sql } from "drizzle-orm"; +import { and, eq, exists, ne, type SQL, sql } from "drizzle-orm"; import { db } from "~/db"; import { entries, diff --git a/api/src/controllers/shows/movies.ts b/api/src/controllers/shows/movies.ts index 059ffad4..9f619b34 100644 --- a/api/src/controllers/shows/movies.ts +++ b/api/src/controllers/shows/movies.ts @@ -9,10 +9,10 @@ import { bubble } from "~/models/examples"; import { FullMovie, Movie, MovieTranslation } from "~/models/movie"; import { AcceptLanguage, - Filter, - Page, createPage, + Filter, isUuid, + Page, processLanguages, } from "~/models/utils"; import { desc } from "~/models/utils/descriptions"; diff --git a/api/src/controllers/shows/series.ts b/api/src/controllers/shows/series.ts index e1a63c82..52b6de52 100644 --- a/api/src/controllers/shows/series.ts +++ b/api/src/controllers/shows/series.ts @@ -9,10 +9,10 @@ import { madeInAbyss } from "~/models/examples"; import { FullSerie, Serie, SerieTranslation } from "~/models/serie"; import { AcceptLanguage, - Filter, - Page, createPage, + Filter, isUuid, + Page, processLanguages, } from "~/models/utils"; import { desc } from "~/models/utils/descriptions"; diff --git a/api/src/controllers/shows/shows.ts b/api/src/controllers/shows/shows.ts index c100bc6a..b8320bd2 100644 --- a/api/src/controllers/shows/shows.ts +++ b/api/src/controllers/shows/shows.ts @@ -8,9 +8,9 @@ import { KError } from "~/models/error"; import { Show } from "~/models/show"; import { AcceptLanguage, + createPage, Filter, Page, - createPage, processLanguages, } from "~/models/utils"; import { desc } from "~/models/utils/descriptions"; diff --git a/api/src/controllers/staff.ts b/api/src/controllers/staff.ts index ee8266aa..a094249e 100644 --- a/api/src/controllers/staff.ts +++ b/api/src/controllers/staff.ts @@ -1,9 +1,9 @@ -import { type SQL, and, eq, sql } from "drizzle-orm"; +import { and, eq, type SQL, sql } from "drizzle-orm"; import Elysia, { t } from "elysia"; import { auth } from "~/auth"; import { prefix } from "~/base"; import { db } from "~/db"; -import { profiles, showTranslations, shows } from "~/db/schema"; +import { profiles, shows, showTranslations } from "~/db/schema"; import { roles, staff } from "~/db/schema/staff"; import { watchlist } from "~/db/schema/watchlist"; import { getColumns, jsonbBuildObject, sqlarr } from "~/db/utils"; @@ -13,15 +13,15 @@ import { Role, Staff } from "~/models/staff"; import { RoleWShow, RoleWStaff } from "~/models/staff-roles"; import { AcceptLanguage, + createPage, Filter, type FilterDef, type Image, - Page, - Sort, - createPage, isUuid, keysetPaginate, + Page, processLanguages, + Sort, sortToSql, } from "~/models/utils"; import { desc } from "~/models/utils/descriptions"; diff --git a/api/src/controllers/studios.ts b/api/src/controllers/studios.ts index 09fd4f84..65841ede 100644 --- a/api/src/controllers/studios.ts +++ b/api/src/controllers/studios.ts @@ -1,4 +1,4 @@ -import { type SQL, and, eq, exists, sql } from "drizzle-orm"; +import { and, eq, exists, type SQL, sql } from "drizzle-orm"; import Elysia, { t } from "elysia"; import { auth } from "~/auth"; import { prefix } from "~/base"; @@ -6,8 +6,8 @@ import { db } from "~/db"; import { showStudioJoin, shows, - studioTranslations, studios, + studioTranslations, } from "~/db/schema"; import { getColumns, @@ -22,14 +22,14 @@ import { Show } from "~/models/show"; import { Studio, StudioTranslation } from "~/models/studio"; import { AcceptLanguage, - Filter, - Page, - Sort, buildRelations, createPage, + Filter, isUuid, keysetPaginate, + Page, processLanguages, + Sort, sortToSql, } from "~/models/utils"; import { desc } from "~/models/utils/descriptions"; diff --git a/api/src/controllers/videos.ts b/api/src/controllers/videos.ts index 2f9f414d..8a1c9d15 100644 --- a/api/src/controllers/videos.ts +++ b/api/src/controllers/videos.ts @@ -1,6 +1,6 @@ import { and, eq, notExists, or, sql } from "drizzle-orm"; import { Elysia, t } from "elysia"; -import { type Transaction, db } from "~/db"; +import { db, type Transaction } from "~/db"; import { entries, entryVideoJoin, shows, videos } from "~/db/schema"; import { conflictUpdateAllExcept, @@ -13,12 +13,12 @@ import { import { KError } from "~/models/error"; import { bubbleVideo } from "~/models/examples"; import { - Page, - type Resource, - Sort, createPage, isUuid, keysetPaginate, + Page, + type Resource, + Sort, sortToSql, } from "~/models/utils"; import { desc as description } from "~/models/utils/descriptions"; diff --git a/api/src/db/schema/index.ts b/api/src/db/schema/index.ts index f1e91a59..36721cc8 100644 --- a/api/src/db/schema/index.ts +++ b/api/src/db/schema/index.ts @@ -1,9 +1,9 @@ export * from "./entries"; -export * from "./seasons"; -export * from "./shows"; -export * from "./studios"; -export * from "./staff"; -export * from "./videos"; -export * from "./profiles"; export * from "./history"; export * from "./mqueue"; +export * from "./profiles"; +export * from "./seasons"; +export * from "./shows"; +export * from "./staff"; +export * from "./studios"; +export * from "./videos"; diff --git a/api/src/models/entry/extra.ts b/api/src/models/entry/extra.ts index 10a60873..ed951ab1 100644 --- a/api/src/models/entry/extra.ts +++ b/api/src/models/entry/extra.ts @@ -1,5 +1,5 @@ import { t } from "elysia"; -import { type Prettify, comment } from "~/utils"; +import { comment, type Prettify } from "~/utils"; import { madeInAbyss, registerExamples } from "../examples"; import { Progress } from "../history"; import { DbMetadata, SeedImage } from "../utils"; diff --git a/api/src/models/entry/index.ts b/api/src/models/entry/index.ts index d4a338a3..662691e2 100644 --- a/api/src/models/entry/index.ts +++ b/api/src/models/entry/index.ts @@ -13,6 +13,6 @@ export type SeedEntry = SeedEpisode | SeedMovieEntry | SeedSpecial; export type EntryKind = Entry["kind"] | Extra["kind"]; export * from "./episode"; +export * from "./extra"; export * from "./movie-entry"; export * from "./special"; -export * from "./extra"; diff --git a/api/src/models/entry/movie-entry.ts b/api/src/models/entry/movie-entry.ts index 3aa65ee9..befda2d0 100644 --- a/api/src/models/entry/movie-entry.ts +++ b/api/src/models/entry/movie-entry.ts @@ -1,5 +1,5 @@ import { t } from "elysia"; -import { type Prettify, comment } from "~/utils"; +import { comment, type Prettify } from "~/utils"; import { bubbleImages, madeInAbyss, registerExamples } from "../examples"; import { Progress } from "../history"; import { diff --git a/api/src/models/entry/special.ts b/api/src/models/entry/special.ts index 90b8cdd0..97a65cae 100644 --- a/api/src/models/entry/special.ts +++ b/api/src/models/entry/special.ts @@ -1,5 +1,5 @@ import { t } from "elysia"; -import { type Prettify, comment } from "~/utils"; +import { comment, type Prettify } from "~/utils"; import { bubbleImages, madeInAbyss, registerExamples } from "../examples"; import { Progress } from "../history"; import { diff --git a/api/src/models/examples/index.ts b/api/src/models/examples/index.ts index a5601358..823a79db 100644 --- a/api/src/models/examples/index.ts +++ b/api/src/models/examples/index.ts @@ -31,7 +31,7 @@ export const registerExamples = ( }; export * from "./bubble"; -export * from "./made-in-abyss"; export * from "./dune-1984"; export * from "./dune-2021"; export * from "./dune-collection"; +export * from "./made-in-abyss"; diff --git a/api/src/models/utils/filters/index.ts b/api/src/models/utils/filters/index.ts index 1de7a1ce..140c7c37 100644 --- a/api/src/models/utils/filters/index.ts +++ b/api/src/models/utils/filters/index.ts @@ -23,7 +23,10 @@ export type FilterDef = { export const Filter = ({ def, description = "Filters to apply to the query.", -}: { def: FilterDef; description?: string }) => +}: { + def: FilterDef; + description?: string; +}) => t .Transform( t.String({ diff --git a/api/src/models/utils/filters/parser.ts b/api/src/models/utils/filters/parser.ts index ab82ee40..84a0f272 100644 --- a/api/src/models/utils/filters/parser.ts +++ b/api/src/models/utils/filters/parser.ts @@ -1,11 +1,11 @@ import { - type Parjser, anyStringOf, digit, float, int, letter, noCharOf, + type Parjser, string, } from "parjs"; import { diff --git a/api/src/models/utils/filters/to-sql.ts b/api/src/models/utils/filters/to-sql.ts index a35d37c3..62ca044c 100644 --- a/api/src/models/utils/filters/to-sql.ts +++ b/api/src/models/utils/filters/to-sql.ts @@ -1,7 +1,6 @@ import { - type BinaryOperator, - type SQL, and, + type BinaryOperator, eq, gt, gte, @@ -10,6 +9,7 @@ import { ne, not, or, + type SQL, sql, } from "drizzle-orm"; import { KErrorT } from "~/models/error"; diff --git a/api/src/models/utils/index.ts b/api/src/models/utils/index.ts index 53ea1dff..ce15c717 100644 --- a/api/src/models/utils/index.ts +++ b/api/src/models/utils/index.ts @@ -1,12 +1,12 @@ +export * from "./db-metadata"; export * from "./external-id"; +export * from "./filters"; export * from "./genres"; export * from "./image"; -export * from "./language"; -export * from "./resource"; -export * from "./filters"; -export * from "./page"; -export * from "./sort"; export * from "./keyset-paginate"; -export * from "./db-metadata"; +export * from "./language"; export * from "./original"; +export * from "./page"; export * from "./relations"; +export * from "./resource"; +export * from "./sort"; diff --git a/api/src/models/utils/language.ts b/api/src/models/utils/language.ts index ee86cc40..6497bef1 100644 --- a/api/src/models/utils/language.ts +++ b/api/src/models/utils/language.ts @@ -4,9 +4,7 @@ import { type TSchema, type TString, } from "@sinclair/typebox"; -import { type Column, eq, sql, type Table } from "drizzle-orm"; import { t } from "elysia"; -import { sqlarr } from "~/db/utils"; import { comment } from "../../utils"; import { KErrorT } from "../error"; diff --git a/api/src/models/video.ts b/api/src/models/video.ts index c0c1298e..3b2ad90b 100644 --- a/api/src/models/video.ts +++ b/api/src/models/video.ts @@ -1,6 +1,6 @@ import { PatternStringExact, type TSchema } from "@sinclair/typebox"; import { t } from "elysia"; -import { type Prettify, comment } from "~/utils"; +import { comment, type Prettify } from "~/utils"; import { ExtraType } from "./entry/extra"; import { bubble, bubbleVideo, registerExamples } from "./examples"; import { DbMetadata, EpisodeId, ExternalId, Resource } from "./utils"; diff --git a/api/tests/helpers/index.ts b/api/tests/helpers/index.ts index f9111196..d6e8e73d 100644 --- a/api/tests/helpers/index.ts +++ b/api/tests/helpers/index.ts @@ -1,8 +1,7 @@ +export * from "~/base"; export * from "./movies-helper"; export * from "./series-helper"; export * from "./shows-helper"; -export * from "./studio-helper"; export * from "./staff-helper"; +export * from "./studio-helper"; export * from "./videos-helper"; - -export * from "~/base"; diff --git a/api/tests/helpers/series-helper.ts b/api/tests/helpers/series-helper.ts index 090d2a85..36d9f25d 100644 --- a/api/tests/helpers/series-helper.ts +++ b/api/tests/helpers/series-helper.ts @@ -45,7 +45,11 @@ export const getSerie = async ( export const getSeries = async ({ langs, ...query -}: { langs?: string; preferOriginal?: boolean; with?: string[] }) => { +}: { + langs?: string; + preferOriginal?: boolean; + with?: string[]; +}) => { const resp = await handlers.handle( new Request(buildUrl("series", query), { method: "GET", diff --git a/api/tests/movies/seed-movies.test.ts b/api/tests/movies/seed-movies.test.ts index 6da873b8..19014975 100644 --- a/api/tests/movies/seed-movies.test.ts +++ b/api/tests/movies/seed-movies.test.ts @@ -2,7 +2,7 @@ import { beforeAll, describe, expect, it } from "bun:test"; import { eq } from "drizzle-orm"; import { expectStatus } from "tests/utils"; import { db } from "~/db"; -import { showTranslations, shows, videos } from "~/db/schema"; +import { shows, showTranslations, videos } from "~/db/schema"; import { bubble } from "~/models/examples"; import { dune, duneVideo } from "~/models/examples/dune-2021"; import { createMovie, createVideo } from "../helpers"; diff --git a/api/tests/videos/getdel.test.ts b/api/tests/videos/getdel.test.ts index aa346f4f..0cd78443 100644 --- a/api/tests/videos/getdel.test.ts +++ b/api/tests/videos/getdel.test.ts @@ -10,7 +10,7 @@ import { } from "tests/helpers"; import { expectStatus } from "tests/utils"; import { db } from "~/db"; -import { entries, entryVideoJoin, shows, videos } from "~/db/schema"; +import { entries, shows, videos } from "~/db/schema"; import { bubble, madeInAbyss } from "~/models/examples"; beforeAll(async () => { diff --git a/biome.json b/biome.json index 3f6cfd4c..cc2a5da5 100644 --- a/biome.json +++ b/biome.json @@ -21,13 +21,18 @@ }, "suspicious": { "noExplicitAny": "off", - "noArrayIndexKey": "off" + "noArrayIndexKey": "off", + "noTemplateCurlyInString": "off" }, "security": { "noDangerouslySetInnerHtml": "off" }, "complexity": { - "noBannedTypes": "off" + "noBannedTypes": "off", + "noUselessUndefinedInitialization": "off" + }, + "correctness": { + "noUnusedVariables": "off" } } }, diff --git a/front/biome.json b/front/biome.json index 99b4ab8f..8c2c8f47 100644 --- a/front/biome.json +++ b/front/biome.json @@ -1,3 +1,6 @@ { - "extends": "//" + "extends": "//", + "files": { + "includes": ["src/**"] + } } diff --git a/front/src/app/+html.tsx b/front/src/app/+html.tsx index d9b6ddde..4b4a92ed 100644 --- a/front/src/app/+html.tsx +++ b/front/src/app/+html.tsx @@ -8,15 +8,46 @@ export default function Root({ children }: PropsWithChildren) { Kyoo - - + + - - - - - + + + + + diff --git a/front/src/components/items/item-grid.tsx b/front/src/components/items/item-grid.tsx index ad90b60b..e72e6da9 100644 --- a/front/src/components/items/item-grid.tsx +++ b/front/src/components/items/item-grid.tsx @@ -1,12 +1,6 @@ import { useState } from "react"; import { type ImageStyle, Platform, View } from "react-native"; -import { - percent, - px, - type Stylable, - type Theme, - useYoshiki, -} from "yoshiki/native"; +import { percent, type Stylable, type Theme, useYoshiki } from "yoshiki/native"; import type { KImage, WatchStatusV } from "~/models"; import { focusReset, diff --git a/front/src/components/items/item-helpers.tsx b/front/src/components/items/item-helpers.tsx index e0c0d0f0..d3c6d5d5 100644 --- a/front/src/components/items/item-helpers.tsx +++ b/front/src/components/items/item-helpers.tsx @@ -14,7 +14,8 @@ export const ItemWatchStatus = ({ }) => { const { css } = useYoshiki(); - if (watchStatus !== WatchStatusV.Completed && !unseenEpisodesCount) return null; + if (watchStatus !== WatchStatusV.Completed && !unseenEpisodesCount) + return null; return ( ) : ( -

+

{unseenEpisodesCount}

)} diff --git a/front/src/components/items/watchlist-info.tsx b/front/src/components/items/watchlist-info.tsx index 6b3a8781..25fb0224 100644 --- a/front/src/components/items/watchlist-info.tsx +++ b/front/src/components/items/watchlist-info.tsx @@ -1,7 +1,7 @@ -import Bookmark from "@material-symbols/svg-400/rounded/bookmark-fill.svg"; import BookmarkAdd from "@material-symbols/svg-400/rounded/bookmark_add.svg"; import BookmarkAdded from "@material-symbols/svg-400/rounded/bookmark_added-fill.svg"; import BookmarkRemove from "@material-symbols/svg-400/rounded/bookmark_remove.svg"; +import Bookmark from "@material-symbols/svg-400/rounded/bookmark-fill.svg"; import type { ComponentProps } from "react"; import { useTranslation } from "react-i18next"; import type { Serie } from "~/models"; @@ -10,7 +10,13 @@ import { useAccount } from "~/providers/account-context"; import { useMutation } from "~/query"; type WatchStatus = NonNullable["status"]; -const WatchStatus = ["completed", "watching", "rewatching", "dropped", "planned"] as const; +const WatchStatus = [ + "completed", + "watching", + "rewatching", + "dropped", + "planned", +] as const; export const watchListIcon = (status: WatchStatus | null) => { switch (status) { @@ -51,7 +57,12 @@ export const WatchListInfo = ({ if (account == null) { return ( - + ); } @@ -93,7 +104,10 @@ export const WatchListInfo = ({ selected={x === status} /> ))} - mutation.mutate(null)} /> + mutation.mutate(null)} + /> ); default: diff --git a/front/src/models/index.ts b/front/src/models/index.ts index 0847032b..b9ed0e8f 100644 --- a/front/src/models/index.ts +++ b/front/src/models/index.ts @@ -1,15 +1,12 @@ -export * from "./utils/page"; +export * from "./collection"; +export * from "./entry"; export * from "./kyoo-error"; - export * from "./movie"; export * from "./serie"; -export * from "./collection"; export * from "./show"; -export * from "./entry"; export * from "./studio"; -export * from "./video"; - export * from "./user"; - -export * from "./utils/images"; export * from "./utils/genre"; +export * from "./utils/images"; +export * from "./utils/page"; +export * from "./video"; diff --git a/front/src/models/resources/episode.ts b/front/src/models/resources/episode.ts index 0d67f48e..f9570990 100644 --- a/front/src/models/resources/episode.ts +++ b/front/src/models/resources/episode.ts @@ -23,7 +23,8 @@ export const EpisodeP = BaseEpisodeP.and( watchStatus: WatchStatusP.optional().nullable(), }), ).transform((x) => { - if (x.show && !x.thumbnail && x.show.thumbnail) x.thumbnail = x.show.thumbnail; + if (x.show && !x.thumbnail && x.show.thumbnail) + x.thumbnail = x.show.thumbnail; return x; }); diff --git a/front/src/models/resources/watch-info.ts b/front/src/models/resources/watch-info.ts index a4a3ca8b..8c93f813 100644 --- a/front/src/models/resources/watch-info.ts +++ b/front/src/models/resources/watch-info.ts @@ -169,9 +169,11 @@ export const WatchInfoP = z // from https://stackoverflow.com/questions/10420352/converting-file-size-in-bytes-to-human-readable-string const humanFileSize = (size: number): string => { const i = size === 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024)); - // @ts-ignore I'm not gonna fix stackoverflow's working code. - // biome-ignore lint: same as above - return (size / Math.pow(1024, i)).toFixed(2) * 1 + " " + ["B", "kB", "MB", "GB", "TB"][i]; + return ( + // @ts-ignore I'm not gonna fix stackoverflow's working code. + // biome-ignore lint/style/useTemplate: same as above + (size / 1024 ** i).toFixed(2) * 1 + " " + ["B", "kB", "MB", "GB", "TB"][i] + ); }; /** diff --git a/front/src/models/show.ts b/front/src/models/show.ts index 429e0da4..b0b5deea 100644 --- a/front/src/models/show.ts +++ b/front/src/models/show.ts @@ -11,4 +11,10 @@ export const Show = z.union([ export type Show = z.infer; export type WatchStatusV = NonNullable["status"]; -export const WatchStatusV = ["completed", "watching", "rewatching", "dropped", "planned"] as const; +export const WatchStatusV = [ + "completed", + "watching", + "rewatching", + "dropped", + "planned", +] as const; diff --git a/front/src/primitives/alert.tsx b/front/src/primitives/alert.tsx index ed56be15..c61d3daf 100644 --- a/front/src/primitives/alert.tsx +++ b/front/src/primitives/alert.tsx @@ -1,6 +1,10 @@ // Stolen from https://github.com/necolas/react-native-web/issues/1026#issuecomment-1458279681 -import { type AlertButton, type AlertOptions, Alert as RNAlert } from "react-native"; +import { + type AlertButton, + type AlertOptions, + Alert as RNAlert, +} from "react-native"; import type { SweetAlertIcon } from "sweetalert2"; export interface ExtendedAlertStatic { diff --git a/front/src/primitives/alert.web.tsx b/front/src/primitives/alert.web.tsx index 84c32ca0..7bc59fb7 100644 --- a/front/src/primitives/alert.web.tsx +++ b/front/src/primitives/alert.web.tsx @@ -37,7 +37,9 @@ export class Alert { const denyButton = buttons ? buttons.find((button) => button.style === "destructive") : undefined; - const cancelButton = buttons ? buttons.find((button) => button.style === "cancel") : undefined; + const cancelButton = buttons + ? buttons.find((button) => button.style === "cancel") + : undefined; Swal.fire({ title: title, diff --git a/front/src/primitives/avatar.tsx b/front/src/primitives/avatar.tsx index 23b16c7f..c14cb2ed 100644 --- a/front/src/primitives/avatar.tsx +++ b/front/src/primitives/avatar.tsx @@ -1,7 +1,7 @@ import AccountCircle from "@material-symbols/svg-400/rounded/account_circle-fill.svg"; -import { type ComponentType, type RefAttributes, forwardRef } from "react"; +import { type ComponentType, forwardRef, type RefAttributes } from "react"; import { Image, type ImageProps, View, type ViewStyle } from "react-native"; -import { type Stylable, px, useYoshiki } from "yoshiki/native"; +import { px, type Stylable, useYoshiki } from "yoshiki/native"; import { Icon } from "./icons"; import { Skeleton } from "./skeleton"; import { P } from "./text"; @@ -73,7 +73,11 @@ const AvatarC = forwardRef< {placeholder[0]}

) : ( - + )} { return ( - + {alt} void) | undefined>(undefined); +const MenuContext = createContext<((open: boolean) => void) | undefined>( + undefined, +); type Optional = Omit & Partial; @@ -45,7 +47,10 @@ const Menu = ({ const insets = useSafeAreaInsets(); const alreadyRendered = useRef(false); const [isOpen, setOpen] = - outerOpen !== undefined && outerSetOpen ? [outerOpen, outerSetOpen] : useState(false); + outerOpen !== undefined && outerSetOpen + ? [outerOpen, outerSetOpen] + : // biome-ignore lint/correctness/useHookAtTopLevel: const + useState(false); // does the same as a useMemo but for props. const memoRef = useRef({ onMenuOpen, onMenuClose }); @@ -73,7 +78,11 @@ const Menu = ({ setOpen(false)} tabIndex={-1} - {...css({ ...StyleSheet.absoluteFillObject, flexGrow: 1, bg: "transparent" })} + {...css({ + ...StyleSheet.absoluteFillObject, + flexGrow: 1, + bg: "transparent", + })} /> ({ icon={Close} color={theme.colors.black} onPress={() => setOpen(false)} - {...css({ alignSelf: "flex-end", display: { xs: "none", xl: "flex" } })} + {...css({ + alignSelf: "flex-end", + display: { xs: "none", xl: "flex" }, + })} /> {children} @@ -137,7 +149,10 @@ const MenuItem = ({ left?: ReactElement; disabled?: boolean; icon?: ComponentType; -} & ({ onSelect: () => void; href?: undefined } | { href: string; onSelect?: undefined })) => { +} & ( + | { onSelect: () => void; href?: undefined } + | { href: string; onSelect?: undefined } +)) => { const { css, theme } = useYoshiki(); const setOpen = useContext(MenuContext); const router = useRouter(); @@ -174,7 +189,10 @@ const MenuItem = ({ {!left && icn && icn}

diff --git a/front/src/primitives/popup.tsx b/front/src/primitives/popup.tsx index 0f79d171..0be13b89 100644 --- a/front/src/primitives/popup.tsx +++ b/front/src/primitives/popup.tsx @@ -27,7 +27,12 @@ import { Container } from "./container"; import { ContrastArea, SwitchVariant, type YoshikiFunc } from "./themes"; import { ts } from "./utils"; -export const Popup = ({ children, ...props }: { children: ReactNode | YoshikiFunc }) => { +export const Popup = ({ + children, + ...props +}: { + children: ReactNode | YoshikiFunc; +}) => { return ( @@ -67,7 +72,9 @@ export const Popup = ({ children, ...props }: { children: ReactNode | YoshikiFun flexShrink: 1, })} > - {typeof children === "function" ? children({ css, theme }) : children} + {typeof children === "function" + ? children({ css, theme }) + : children} diff --git a/front/src/primitives/progress.tsx b/front/src/primitives/progress.tsx index 9a66b64d..f2325e0d 100644 --- a/front/src/primitives/progress.tsx +++ b/front/src/primitives/progress.tsx @@ -20,7 +20,7 @@ import { ActivityIndicator, Platform, View } from "react-native"; import { Circle, Svg } from "react-native-svg"; -import { type Stylable, px, useYoshiki } from "yoshiki/native"; +import { px, type Stylable, useYoshiki } from "yoshiki/native"; export const CircularProgress = ({ size = 48, @@ -31,7 +31,9 @@ export const CircularProgress = ({ const { css, theme } = useYoshiki(); if (Platform.OS !== "web") - return ; + return ( + + ); return ( @@ -63,7 +65,9 @@ export const CircularProgress = ({ viewBox={`${size / 2} ${size / 2} ${size} ${size}`} {...css( // @ts-ignore Web only - Platform.OS === "web" && { animation: "circularProgress-svg 1.4s ease-in-out infinite" }, + Platform.OS === "web" && { + animation: "circularProgress-svg 1.4s ease-in-out infinite", + }, )} > ({ - label, value, onValueChange, values, @@ -37,7 +36,11 @@ export const Select = ({ getLabel: (key: Value) => string; }) => { return ( -

}> + } + > {values.map((x) => (

{}

- + @@ -98,7 +100,8 @@ export const Select = ({ boxShadow: "0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2)", zIndex: 2, - maxHeight: "calc(var(--radix-dropdown-menu-content-available-height) * 0.8)", + maxHeight: + "calc(var(--radix-dropdown-menu-content-available-height) * 0.8)", })} > @@ -122,55 +125,56 @@ export const Select = ({ ); }; -const Item = forwardRef(function Item( - { label, value, ...props }, - ref, -) { - const { css, theme } = useYoshiki(); - const { css: nCss } = useNativeYoshiki(); - return ( - <> - - theme.paragraph, - borderRadius: "4px", - position: "relative", - userSelect: "none", - ...focusReset, - }, - props as any, - )} - > - theme.paragraph })}>{label} - - - - - - ); -}); + paddingTop: "8px", + paddingBottom: "8px", + paddingLeft: "35px", + paddingRight: "25px", + height: "32px", + color: (theme) => theme.paragraph, + borderRadius: "4px", + position: "relative", + userSelect: "none", + ...focusReset, + }, + props as any, + )} + > + theme.paragraph })}> + {label} + + + + + + + ); + }, +); diff --git a/front/src/primitives/skeleton.tsx b/front/src/primitives/skeleton.tsx index 96a427cd..fd0c8129 100644 --- a/front/src/primitives/skeleton.tsx +++ b/front/src/primitives/skeleton.tsx @@ -32,7 +32,10 @@ export const Skeleton = ({ })); useEffect(() => { - mult.value = withRepeat(withDelay(800, withTiming(1, { duration: 800 })), 0); + mult.value = withRepeat( + withDelay(800, withTiming(1, { duration: 800 })), + 0, + ); }); return ( diff --git a/front/src/primitives/slider.tsx b/front/src/primitives/slider.tsx index c7c727fc..4c71ed2f 100644 --- a/front/src/primitives/slider.tsx +++ b/front/src/primitives/slider.tsx @@ -21,7 +21,7 @@ import { useRef, useState } from "react"; import { type GestureResponderEvent, Platform, View } from "react-native"; import type { ViewProps } from "react-native-svg/lib/typescript/fabric/utils"; -import { Stylable, percent, px, useYoshiki } from "yoshiki/native"; +import { percent, px, useYoshiki } from "yoshiki/native"; import { focusReset } from "./utils"; export const Slider = ({ @@ -80,7 +80,10 @@ export const Slider = ({ }} // @ts-ignore Web only onMouseMove={(e) => - onHover?.(Math.max(0, Math.min((e.clientX - layout.x) / layout.width, 1) * max), layout) + onHover?.( + Math.max(0, Math.min((e.clientX - layout.x) / layout.width, 1) * max), + layout, + ) } tabIndex={0} onFocus={() => setFocus(true)} diff --git a/front/src/primitives/snackbar.tsx b/front/src/primitives/snackbar.tsx index ad3075f1..2adbe0bf 100644 --- a/front/src/primitives/snackbar.tsx +++ b/front/src/primitives/snackbar.tsx @@ -19,7 +19,13 @@ */ import { usePortal } from "@gorhom/portal"; -import { type ReactElement, createContext, useCallback, useContext, useRef } from "react"; +import { + createContext, + type ReactElement, + useCallback, + useContext, + useRef, +} from "react"; import { View } from "react-native"; import { percent, px } from "yoshiki/native"; import { Button } from "./button"; @@ -43,14 +49,21 @@ export type Action = { const SnackbarContext = createContext<(snackbar: Snackbar) => void>(null!); -export const SnackbarProvider = ({ children }: { children: ReactElement | ReactElement[] }) => { +export const SnackbarProvider = ({ + children, +}: { + children: ReactElement | ReactElement[]; +}) => { const { addPortal, removePortal } = usePortal(); const snackbars = useRef([]); const timeout = useRef(null); const createSnackbar = useCallback( (snackbar: Snackbar) => { - if (snackbar.key) snackbars.current = snackbars.current.filter((x) => snackbar.key !== x.key); + if (snackbar.key) + snackbars.current = snackbars.current.filter( + (x) => snackbar.key !== x.key, + ); snackbars.current.unshift(snackbar); if (timeout.current) return; @@ -73,7 +86,11 @@ export const SnackbarProvider = ({ children }: { children: ReactElement | ReactE [addPortal, removePortal], ); - return {children}; + return ( + + {children} + + ); }; export const useSnackbar = () => { diff --git a/front/src/primitives/text.tsx b/front/src/primitives/text.tsx index d3a3c9f4..b1dea453 100644 --- a/front/src/primitives/text.tsx +++ b/front/src/primitives/text.tsx @@ -8,7 +8,13 @@ import { P as EP, } from "@expo/html-elements"; import type { ComponentProps, ComponentType } from "react"; -import { Platform, type StyleProp, Text, type TextProps, type TextStyle } from "react-native"; +import { + Platform, + type StyleProp, + Text, + type TextProps, + type TextStyle, +} from "react-native"; import { percent, rem, useYoshiki } from "yoshiki/native"; import { ts } from "./utils/spacing"; @@ -55,7 +61,10 @@ const styleText = ( return Text; }; -export const H1 = styleText(EH1, "header", { fontSize: rem(3), fontWeight: "900" }); +export const H1 = styleText(EH1, "header", { + fontSize: rem(3), + fontWeight: "900", +}); export const H2 = styleText(EH2, "header", { fontSize: rem(2) }); export const H3 = styleText(EH3, "header"); export const H4 = styleText(EH4, "header"); diff --git a/front/src/primitives/theme/index.ts b/front/src/primitives/theme/index.ts index 3af05249..72c6577c 100644 --- a/front/src/primitives/theme/index.ts +++ b/front/src/primitives/theme/index.ts @@ -1,2 +1,2 @@ -export * from "./theme"; export * from "./catppuccin"; +export * from "./theme"; diff --git a/front/src/primitives/theme/theme.tsx b/front/src/primitives/theme/theme.tsx index 1c43d605..004db878 100644 --- a/front/src/primitives/theme/theme.tsx +++ b/front/src/primitives/theme/theme.tsx @@ -1,7 +1,11 @@ import type { Property } from "csstype"; import type { ReactNode } from "react"; import { Platform, type TextStyle } from "react-native"; -import { type Theme, ThemeProvider as WebThemeProvider, useAutomaticTheme } from "yoshiki"; +import { + type Theme, + useAutomaticTheme, + ThemeProvider as WebThemeProvider, +} from "yoshiki"; import "yoshiki"; import { ThemeProvider, useTheme, useYoshiki } from "yoshiki/native"; import "yoshiki/native"; @@ -52,7 +56,9 @@ declare module "yoshiki" { export type { Theme } from "yoshiki"; export type ThemeBuilder = { - light: Omit & { default: Variant }; + light: Omit & { + default: Variant; + }; dark: Omit & { default: Variant }; }; @@ -88,8 +94,13 @@ const selectMode = ( }; } + // biome-ignore lint/correctness/useHookAtTopLevel: const const auto = useAutomaticTheme("theme", { light, dark }); - const alternate = useAutomaticTheme("alternate", { dark: light, light: dark }); + // biome-ignore lint/correctness/useHookAtTopLevel: const + const alternate = useAutomaticTheme("alternate", { + dark: light, + light: dark, + }); return { ...options, ...auto, @@ -136,12 +147,20 @@ export const ThemeSelector = ({ export type YoshikiFunc = (props: ReturnType) => T; -const YoshikiProvider = ({ children }: { children: YoshikiFunc }) => { +const YoshikiProvider = ({ + children, +}: { + children: YoshikiFunc; +}) => { const yoshiki = useYoshiki(); return <>{children(yoshiki)}; }; -export const SwitchVariant = ({ children }: { children: ReactNode | YoshikiFunc }) => { +export const SwitchVariant = ({ + children, +}: { + children: ReactNode | YoshikiFunc; +}) => { const theme = useTheme(); return ( diff --git a/front/src/primitives/utils/breakpoint.ts b/front/src/primitives/utils/breakpoint.ts index ccfa0c9d..50180402 100644 --- a/front/src/primitives/utils/breakpoint.ts +++ b/front/src/primitives/utils/breakpoint.ts @@ -1,7 +1,12 @@ import { useWindowDimensions } from "react-native"; -import { breakpoints, isBreakpoints, type Breakpoints as YoshikiBreakpoint } from "yoshiki/native"; +import { + breakpoints, + isBreakpoints, + type Breakpoints as YoshikiBreakpoint, +} from "yoshiki/native"; -type AtLeastOne }> = Partial & U[keyof U]; +type AtLeastOne }> = Partial & + U[keyof U]; export type Breakpoint = T | AtLeastOne>; // copied from yoshiki. @@ -36,6 +41,9 @@ export const useBreakpointMap = >( const breakpoint = useBreakpoint(); // @ts-ignore return Object.fromEntries( - Object.entries(value).map(([key, val]) => [key, getBreakpointValue(val, breakpoint)]), + Object.entries(value).map(([key, val]) => [ + key, + getBreakpointValue(val, breakpoint), + ]), ); }; diff --git a/front/src/primitives/utils/index.tsx b/front/src/primitives/utils/index.tsx index 5d553a93..c11b2f9c 100644 --- a/front/src/primitives/utils/index.tsx +++ b/front/src/primitives/utils/index.tsx @@ -1,7 +1,7 @@ -export * from "./nojs"; -export * from "./head"; -export * from "./spacing"; -export * from "./capitalize"; -export * from "./touchonly"; -export * from "./page-style"; export * from "./breakpoint"; +export * from "./capitalize"; +export * from "./head"; +export * from "./nojs"; +export * from "./page-style"; +export * from "./spacing"; +export * from "./touchonly"; diff --git a/front/src/primitives/utils/nojs.tsx b/front/src/primitives/utils/nojs.tsx index 8b361c1f..8fd4796d 100644 --- a/front/src/primitives/utils/nojs.tsx +++ b/front/src/primitives/utils/nojs.tsx @@ -1,6 +1,8 @@ import type { ViewProps } from "react-native"; -export const hiddenIfNoJs: ViewProps = { style: { $$css: true, noJs: "noJsHidden" } as any }; +export const hiddenIfNoJs: ViewProps = { + style: { $$css: true, noJs: "noJsHidden" } as any, +}; export const HiddenIfNoJs = () => (