diff --git a/front/public/translations/en.json b/front/public/translations/en.json index e8dac9c8..fa0313c6 100644 --- a/front/public/translations/en.json +++ b/front/public/translations/en.json @@ -55,7 +55,8 @@ "no-guess": "This video was guessed to be part of this serie but we don't know which episode", "related": "Added videos related to the title {{title}}", "sort-path": "Path", - "sort-entry": "Episode order" + "sort-entry": "Episode order", + "no-video": "No video file linked to this serie." }, "browse": { "mediatypekey": { diff --git a/front/src/primitives/modal.tsx b/front/src/primitives/modal.tsx index e614a961..393ad10d 100644 --- a/front/src/primitives/modal.tsx +++ b/front/src/primitives/modal.tsx @@ -53,7 +53,7 @@ export const Modal = ({ {scroll ? ( {children} ) : ( - {children} + {children} )} diff --git a/front/src/query/fetch-infinite.tsx b/front/src/query/fetch-infinite.tsx index 9a38594b..205909d7 100644 --- a/front/src/query/fetch-infinite.tsx +++ b/front/src/query/fetch-infinite.tsx @@ -73,8 +73,6 @@ export const InfiniteFetch = ({ return isFetching && !isRefetching ? [...items, ...placeholders] : items; }, [items, isFetching, isRefetching, placeholderCount, numColumns]); - if (!data.length && Empty) return Empty; - return ( ({ onRefresh={layout.layout !== "horizontal" ? refetch : undefined} refreshing={isRefetching} ListHeaderComponent={Header} + ListEmptyComponent={Empty} ListFooterComponent={Footer} ItemSeparatorComponent={ Divider === true ? HR : (Divider as any) || undefined diff --git a/front/src/ui/admin/videos-modal/headers.tsx b/front/src/ui/admin/videos-modal/headers.tsx index 18a57a22..87a25147 100644 --- a/front/src/ui/admin/videos-modal/headers.tsx +++ b/front/src/ui/admin/videos-modal/headers.tsx @@ -1,13 +1,16 @@ +import Close from "@material-symbols/svg-400/rounded/close-fill.svg"; import Path from "@material-symbols/svg-400/rounded/conversion_path-fill.svg"; import LibraryAdd from "@material-symbols/svg-400/rounded/library_add-fill.svg"; import Sort from "@material-symbols/svg-400/rounded/sort.svg"; import Entry from "@material-symbols/svg-400/rounded/tv_next-fill.svg"; import { useTranslation } from "react-i18next"; +import { View } from "react-native"; import { FullVideo } from "~/models"; import { Button, ComboBox, Icon, + IconButton, Menu, P, PressableFeedback, @@ -53,6 +56,41 @@ export const SortMenu = ({ ); }; +export const VideoListHeader = ({ + titles, + removeTitle, + sort, + setSort, +}: { + titles: string[]; + removeTitle: (title: string) => void; + sort: "path" | "entry"; + setSort: (sort: "path" | "entry") => void; +}) => { + const { t } = useTranslation(); + + return ( + <> + {[...titles].map((title) => ( + + {t("videos-map.related", { title })} + removeTitle(title)} + {...tooltip(t("misc.cancel"))} + /> + + ))} + + + + > + ); +}; + export const AddVideoFooter = ({ addTitle, }: { diff --git a/front/src/ui/admin/videos-modal/index.tsx b/front/src/ui/admin/videos-modal/index.tsx index 13250018..a70b4305 100644 --- a/front/src/ui/admin/videos-modal/index.tsx +++ b/front/src/ui/admin/videos-modal/index.tsx @@ -1,9 +1,8 @@ -import Close from "@material-symbols/svg-400/rounded/close-fill.svg"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { View } from "react-native"; import { type Entry, FullVideo, type Page } from "~/models"; -import { IconButton, Modal, P, Skeleton, tooltip } from "~/primitives"; +import { Modal, P } from "~/primitives"; import { InfiniteFetch, type QueryIdentifier, @@ -12,7 +11,7 @@ import { } from "~/query"; import { useQueryState } from "~/utils"; import { Header } from "../../details/header"; -import { AddVideoFooter, SortMenu } from "./headers"; +import { AddVideoFooter, VideoListHeader } from "./headers"; import { PathItem } from "./path-item"; export const useEditLinks = ( @@ -79,25 +78,17 @@ export const VideosModal = () => { return ( - {[...titles].map((title) => ( - - {t("videos-map.related", { title })} - { - setTitles(titles.filter((x) => x !== title)); - }} - {...tooltip(t("misc.cancel"))} - /> - - ))} - - - + setTitles(titles.filter((x) => x !== title)) + } + sort={sort} + setSort={setSort} + /> + } query={VideosModal.query(slug, titles, sort)} layout={{ layout: "vertical", gap: 8, numColumns: 1, size: 48 }} Render={({ item }) => ( @@ -108,7 +99,12 @@ export const VideosModal = () => { editLinks={editLinks} /> )} - Loader={() => } + Loader={PathItem.Loader} + Empty={ + + {t("videos-map.no-video")} + + } Footer={} /> diff --git a/front/src/ui/admin/videos-modal/path-item.tsx b/front/src/ui/admin/videos-modal/path-item.tsx index ce3bcf24..4cf267c4 100644 --- a/front/src/ui/admin/videos-modal/path-item.tsx +++ b/front/src/ui/admin/videos-modal/path-item.tsx @@ -5,7 +5,7 @@ import { useTranslation } from "react-i18next"; import { View } from "react-native"; import { entryDisplayNumber } from "~/components/entries"; import { Entry, type FullVideo } from "~/models"; -import { ComboBox, IconButton, P, tooltip } from "~/primitives"; +import { ComboBox, IconButton, P, Skeleton, tooltip } from "~/primitives"; import { uniqBy } from "~/utils"; import type { useEditLinks } from "."; @@ -39,10 +39,10 @@ export const PathItem = ({ : []; return ( - + {saved ? ( )} - {item.path} + {item.path} ); }; + +PathItem.Loader = () => { + return ( + + + + + + + + ); +};
{t("videos-map.related", { title })}
{t("videos-map.no-video")}
{item.path}