Cleanup some mapper stuff (#1351)

This commit is contained in:
Zoe Roux 2026-03-11 17:58:19 +01:00 committed by GitHub
parent 732eb2b3c0
commit 75cccdbe33
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 76 additions and 30 deletions

View File

@ -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": {

View File

@ -53,7 +53,7 @@ export const Modal = ({
{scroll ? (
<ScrollView className="p-6">{children}</ScrollView>
) : (
<View>{children}</View>
<View className="flex-1">{children}</View>
)}
</Pressable>
</Pressable>

View File

@ -73,8 +73,6 @@ export const InfiniteFetch = <Data, Type extends string = string>({
return isFetching && !isRefetching ? [...items, ...placeholders] : items;
}, [items, isFetching, isRefetching, placeholderCount, numColumns]);
if (!data.length && Empty) return Empty;
return (
<AnimatedLegendList
data={data}
@ -102,6 +100,7 @@ export const InfiniteFetch = <Data, Type extends string = string>({
onRefresh={layout.layout !== "horizontal" ? refetch : undefined}
refreshing={isRefetching}
ListHeaderComponent={Header}
ListEmptyComponent={Empty}
ListFooterComponent={Footer}
ItemSeparatorComponent={
Divider === true ? HR : (Divider as any) || undefined

View File

@ -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) => (
<View
key={title}
className="m-2 flex-row items-center justify-between rounded bg-card px-6"
>
<P>{t("videos-map.related", { title })}</P>
<IconButton
icon={Close}
onPress={() => removeTitle(title)}
{...tooltip(t("misc.cancel"))}
/>
</View>
))}
<View className="mx-6 mb-6 flex-row items-center">
<SortMenu sort={sort} setSort={setSort} />
</View>
</>
);
};
export const AddVideoFooter = ({
addTitle,
}: {

View File

@ -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 (
<Modal title={data?.name ?? t("misc.loading")} scroll={false}>
{[...titles].map((title) => (
<View
key={title}
className="m-2 flex-row items-center justify-between rounded bg-card px-6"
>
<P>{t("videos-map.related", { title })}</P>
<IconButton
icon={Close}
onPress={() => {
setTitles(titles.filter((x) => x !== title));
}}
{...tooltip(t("misc.cancel"))}
/>
</View>
))}
<View className="mx-6 mb-6 flex-row items-center">
<SortMenu sort={sort} setSort={setSort} />
</View>
<InfiniteFetch
Header={
<VideoListHeader
titles={titles}
removeTitle={(title) =>
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={() => <Skeleton />}
Loader={PathItem.Loader}
Empty={
<View className="flex-1">
<P className="flex-1 self-center">{t("videos-map.no-video")}</P>
</View>
}
Footer={<AddVideoFooter addTitle={addTitle} />}
/>
</Modal>

View File

@ -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 (
<View
className="mx-6 h-12 flex-row items-center justify-between hover:bg-card"
className="mx-6 min-h-12 flex-1 flex-row items-center justify-between hover:bg-card"
style={!saved && { opacity: 0.6 }}
>
<View className="flex-row items-center">
<View className="flex-1 flex-row items-center pr-1">
{saved ? (
<IconButton
icon={Close}
@ -71,7 +71,7 @@ export const PathItem = ({
{...tooltip(t("videos-map.no-guess"))}
/>
)}
<P>{item.path}</P>
<P className="flex-1 flex-wrap">{item.path}</P>
</View>
<ComboBox
multiple
@ -107,3 +107,15 @@ export const PathItem = ({
</View>
);
};
PathItem.Loader = () => {
return (
<View className="mx-6 min-h-12 flex-1 flex-row items-center justify-between hover:bg-card">
<View className="flex-1 flex-row items-center pr-1">
<IconButton icon={Close} />
<Skeleton className="w-4/5" />
</View>
<Skeleton className="w-1/5" />
</View>
);
};