mirror of
https://github.com/zoriya/Kyoo.git
synced 2026-08-15 18:45:24 +00:00
Cleanup context menues for shows
This commit is contained in:
@@ -1,17 +1,21 @@
|
||||
// import Download from "@material-symbols/svg-400/rounded/download.svg";
|
||||
import Refresh from "@material-symbols/svg-400/rounded/autorenew.svg";
|
||||
import Delete from "@material-symbols/svg-400/rounded/delete.svg";
|
||||
import Download from "@material-symbols/svg-400/rounded/download.svg";
|
||||
import Info from "@material-symbols/svg-400/rounded/info.svg";
|
||||
import MoreVert from "@material-symbols/svg-400/rounded/more_vert.svg";
|
||||
import MovieInfo from "@material-symbols/svg-400/rounded/movie_info.svg";
|
||||
import Search from "@material-symbols/svg-400/rounded/search-fill.svg";
|
||||
import VideoLibrary from "@material-symbols/svg-400/rounded/video_library-fill.svg";
|
||||
import { useRouter } from "expo-router";
|
||||
import type { ComponentProps } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Alert } from "react-native";
|
||||
import { WatchStatusV } from "~/models";
|
||||
import { HR, IconButton, Menu, tooltip } from "~/primitives";
|
||||
import { HRP, IconButton, Menu, tooltip } from "~/primitives";
|
||||
import { useAccount } from "~/providers/account-context";
|
||||
import { useMutation } from "~/query";
|
||||
import { cn } from "~/utils";
|
||||
import { watchListIcon } from "./watchlist-info";
|
||||
// import { useDownloader } from "../../packages/ui/src/downloads/ui/src/downloads";
|
||||
|
||||
export const EntryContext = ({
|
||||
kind,
|
||||
@@ -28,7 +32,6 @@ export const EntryContext = ({
|
||||
className?: string;
|
||||
} & Partial<ComponentProps<typeof Menu>> &
|
||||
Partial<ComponentProps<typeof IconButton>>) => {
|
||||
// const downloader = useDownloader();
|
||||
const account = useAccount();
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -70,39 +73,46 @@ export const EntryContext = ({
|
||||
onSelect={() => markAsSeenMutation.mutate()}
|
||||
/>
|
||||
)}
|
||||
{/* <Menu.Item */}
|
||||
{/* label={t("home.episodeMore.download")} */}
|
||||
{/* icon={Download} */}
|
||||
{/* onSelect={() => downloader(type, slug)} */}
|
||||
{/* /> */}
|
||||
{videoSlug && (
|
||||
<Menu.Item
|
||||
label={t("home.episodeMore.mediainfo")}
|
||||
icon={MovieInfo}
|
||||
href={`/info/${videoSlug}`}
|
||||
/>
|
||||
<>
|
||||
<Menu.Item
|
||||
label={t("home.episodeMore.download")}
|
||||
icon={Download}
|
||||
href={`/api/videos/${videoSlug}/direct`}
|
||||
download
|
||||
/>
|
||||
<Menu.Item
|
||||
label={t("home.episodeMore.mediainfo")}
|
||||
icon={MovieInfo}
|
||||
href={`/info/${videoSlug}`}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
||||
export const ItemContext = ({
|
||||
export const ShowContext = ({
|
||||
kind,
|
||||
slug,
|
||||
name,
|
||||
videoSlug,
|
||||
status,
|
||||
showWatchlist = true,
|
||||
className,
|
||||
...props
|
||||
}: {
|
||||
kind: "movie" | "serie";
|
||||
kind: "movie" | "serie" | "collection";
|
||||
slug: string;
|
||||
name: string;
|
||||
videoSlug: string | null;
|
||||
status: WatchStatusV | null;
|
||||
showWatchlist?: boolean;
|
||||
className?: string;
|
||||
} & Partial<ComponentProps<typeof Menu>> &
|
||||
Partial<ComponentProps<typeof IconButton>>) => {
|
||||
const account = useAccount();
|
||||
// const downloader = useDownloader();
|
||||
const router = useRouter();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const mutation = useMutation({
|
||||
@@ -120,6 +130,12 @@ export const ItemContext = ({
|
||||
invalidate: null,
|
||||
});
|
||||
|
||||
const deleteMutation = useMutation({
|
||||
method: "DELETE",
|
||||
path: ["api", `${kind}s`, slug],
|
||||
invalidate: ["api", "shows"],
|
||||
});
|
||||
|
||||
return (
|
||||
<Menu
|
||||
Trigger={IconButton}
|
||||
@@ -128,35 +144,38 @@ export const ItemContext = ({
|
||||
{...tooltip(t("misc.more"))}
|
||||
{...(props as any)}
|
||||
>
|
||||
<Menu.Sub
|
||||
label={account ? t("show.watchlistEdit") : t("show.watchlistLogin")}
|
||||
disabled={!account}
|
||||
icon={watchListIcon(status)}
|
||||
>
|
||||
{Object.values(WatchStatusV).map((x) => (
|
||||
<Menu.Item
|
||||
key={x}
|
||||
label={t(
|
||||
`show.watchlistMark.${x.toLowerCase() as Lowercase<WatchStatusV>}`,
|
||||
)}
|
||||
onSelect={() => mutation.mutate(x)}
|
||||
selected={x === status}
|
||||
/>
|
||||
))}
|
||||
{status !== null && (
|
||||
<Menu.Item
|
||||
label={t("show.watchlistMark.null")}
|
||||
onSelect={() => mutation.mutate(null)}
|
||||
/>
|
||||
)}
|
||||
</Menu.Sub>
|
||||
{showWatchlist && kind !== "collection" && (
|
||||
<Menu.Sub
|
||||
label={account ? t("show.watchlistEdit") : t("show.watchlistLogin")}
|
||||
disabled={!account}
|
||||
icon={watchListIcon(status)}
|
||||
>
|
||||
{Object.values(WatchStatusV).map((x) => (
|
||||
<Menu.Item
|
||||
key={x}
|
||||
label={t(
|
||||
`show.watchlistMark.${x.toLowerCase() as Lowercase<WatchStatusV>}`,
|
||||
)}
|
||||
onSelect={() => mutation.mutate(x)}
|
||||
selected={x === status}
|
||||
/>
|
||||
))}
|
||||
{status !== null && (
|
||||
<Menu.Item
|
||||
label={t("show.watchlistMark.null")}
|
||||
onSelect={() => mutation.mutate(null)}
|
||||
/>
|
||||
)}
|
||||
</Menu.Sub>
|
||||
)}
|
||||
{videoSlug && (
|
||||
<>
|
||||
{/* <Menu.Item */}
|
||||
{/* label={t("home.episodeMore.download")} */}
|
||||
{/* icon={Download} */}
|
||||
{/* onSelect={() => downloader(type, slug)} */}
|
||||
{/* /> */}
|
||||
<Menu.Item
|
||||
label={t("home.episodeMore.download")}
|
||||
icon={Download}
|
||||
href={`/api/videos/${videoSlug}/direct`}
|
||||
download
|
||||
/>
|
||||
<Menu.Item
|
||||
label={t("home.episodeMore.mediainfo")}
|
||||
icon={MovieInfo}
|
||||
@@ -166,11 +185,47 @@ export const ItemContext = ({
|
||||
)}
|
||||
{account?.isAdmin === true && (
|
||||
<>
|
||||
<HR />
|
||||
<HRP text={t("navbar.admin")} />
|
||||
<Menu.Item
|
||||
label={t("home.refreshMetadata")}
|
||||
icon={Refresh}
|
||||
onSelect={() => metadataRefreshMutation.mutate()}
|
||||
label={t("show.videos-map")}
|
||||
icon={VideoLibrary}
|
||||
href={`/${kind === "movie" ? "movies" : "series"}/${slug}/videos`}
|
||||
/>
|
||||
{kind !== "collection" && (
|
||||
<Menu.Item
|
||||
label={t("show.remap")}
|
||||
icon={Search}
|
||||
href={`/${kind}s/${slug}/remap?q=${name}`}
|
||||
/>
|
||||
)}
|
||||
{kind !== "collection" && (
|
||||
<Menu.Item
|
||||
label={t("home.refreshMetadata")}
|
||||
icon={Refresh}
|
||||
onSelect={() => metadataRefreshMutation.mutate()}
|
||||
/>
|
||||
)}
|
||||
<Menu.Item
|
||||
label={t("misc.delete")}
|
||||
icon={Delete}
|
||||
onSelect={() => {
|
||||
Alert.alert(
|
||||
t("misc.delete-name", { name }),
|
||||
t("login.delete-confirmation"),
|
||||
[
|
||||
{ text: t("misc.cancel"), style: "cancel" },
|
||||
{
|
||||
text: t("misc.delete"),
|
||||
style: "destructive",
|
||||
onPress: async () => {
|
||||
await deleteMutation.mutateAsync();
|
||||
router.back();
|
||||
},
|
||||
},
|
||||
],
|
||||
{ cancelable: true },
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -2,7 +2,7 @@ import PlayArrow from "@material-symbols/svg-400/rounded/play_arrow-fill.svg";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ScrollView, View, type ViewProps } from "react-native";
|
||||
import { ItemContext } from "~/components/items/context-menus";
|
||||
import { ShowContext } from "~/components/items/context-menus";
|
||||
import { ItemWatchStatus } from "~/components/items/item-helpers";
|
||||
import type { Genre, KImage, WatchStatusV } from "~/models";
|
||||
import {
|
||||
@@ -85,16 +85,15 @@ export const ItemDetails = ({
|
||||
</PosterBackground>
|
||||
<View className="mb-14 flex-1 justify-end">
|
||||
<View className="my-2 flex-row-reverse justify-between p-2">
|
||||
{kind !== "collection" && (
|
||||
<ItemContext
|
||||
kind={kind}
|
||||
slug={slug}
|
||||
status={watchStatus}
|
||||
isOpen={moreOpened}
|
||||
setOpen={(v) => setMoreOpened(v)}
|
||||
videoSlug={videoSlug}
|
||||
/>
|
||||
)}
|
||||
<ShowContext
|
||||
kind={kind}
|
||||
slug={slug}
|
||||
name={name}
|
||||
status={watchStatus}
|
||||
isOpen={moreOpened}
|
||||
setOpen={(v) => setMoreOpened(v)}
|
||||
videoSlug={videoSlug}
|
||||
/>
|
||||
{tagline && <P className="p-1">{tagline}</P>}
|
||||
</View>
|
||||
<ScrollView className="p-3">
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
} from "~/primitives";
|
||||
import type { Layout } from "~/query";
|
||||
import { cn } from "~/utils";
|
||||
import { ItemContext } from "./context-menus";
|
||||
import { ShowContext } from "./context-menus";
|
||||
import { ItemWatchStatus } from "./item-helpers";
|
||||
|
||||
export const ItemProgress = ({ watchPercent }: { watchPercent: number }) => {
|
||||
@@ -87,22 +87,21 @@ export const ItemGrid = ({
|
||||
{kind === "movie" && !!watchPercent && (
|
||||
<ItemProgress watchPercent={watchPercent} />
|
||||
)}
|
||||
{kind !== "collection" && (
|
||||
<ItemContext
|
||||
kind={kind}
|
||||
slug={slug}
|
||||
videoSlug={videoSlug}
|
||||
status={watchStatus}
|
||||
isOpen={moreOpened}
|
||||
setOpen={(v) => setMoreOpened(v)}
|
||||
className={cn(
|
||||
"absolute top-0 right-0 bg-gray-800/70 hover:bg-gray-800 focus-visible:bg-gray-800",
|
||||
"native:hidden opacity-0 focus-visible:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100",
|
||||
moreOpened && "opacity-100",
|
||||
)}
|
||||
iconClassName="fill-slate-200 dark:fill-slate-200"
|
||||
/>
|
||||
)}
|
||||
<ShowContext
|
||||
kind={kind}
|
||||
slug={slug}
|
||||
name={name}
|
||||
videoSlug={videoSlug}
|
||||
status={watchStatus}
|
||||
isOpen={moreOpened}
|
||||
setOpen={(v) => setMoreOpened(v)}
|
||||
className={cn(
|
||||
"absolute top-0 right-0 bg-gray-800/70 hover:bg-gray-800 focus-visible:bg-gray-800",
|
||||
"native:hidden opacity-0 focus-visible:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100",
|
||||
moreOpened && "opacity-100",
|
||||
)}
|
||||
iconClassName="fill-slate-200 dark:fill-slate-200"
|
||||
/>
|
||||
</PosterBackground>
|
||||
<P
|
||||
numberOfLines={subtitle ? 1 : 2}
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
} from "~/primitives";
|
||||
import type { Layout } from "~/query";
|
||||
import { cn } from "~/utils";
|
||||
import { ItemContext } from "./context-menus";
|
||||
import { ShowContext } from "./context-menus";
|
||||
import { ItemWatchStatus } from "./item-helpers";
|
||||
|
||||
export const ItemList = ({
|
||||
@@ -73,23 +73,22 @@ export const ItemList = ({
|
||||
>
|
||||
{name}
|
||||
</Heading>
|
||||
{kind !== "collection" && (
|
||||
<ItemContext
|
||||
kind={kind}
|
||||
slug={slug}
|
||||
videoSlug={videoSlug}
|
||||
status={watchStatus}
|
||||
isOpen={moreOpened}
|
||||
setOpen={(v) => setMoreOpened(v)}
|
||||
className={cn(
|
||||
"ml-4",
|
||||
"bg-gray-800/70 hover:bg-gray-800 focus-visible:bg-gray-800",
|
||||
"native:hidden opacity-0 focus-visible:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100",
|
||||
moreOpened && "opacity-100",
|
||||
)}
|
||||
iconClassName="fill-slate-200 dark:fill-slate-200"
|
||||
/>
|
||||
)}
|
||||
<ShowContext
|
||||
kind={kind}
|
||||
slug={slug}
|
||||
name={name}
|
||||
videoSlug={videoSlug}
|
||||
status={watchStatus}
|
||||
isOpen={moreOpened}
|
||||
setOpen={(v) => setMoreOpened(v)}
|
||||
className={cn(
|
||||
"ml-4",
|
||||
"bg-gray-800/70 hover:bg-gray-800 focus-visible:bg-gray-800",
|
||||
"native:hidden opacity-0 focus-visible:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100",
|
||||
moreOpened && "opacity-100",
|
||||
)}
|
||||
iconClassName="fill-slate-200 dark:fill-slate-200"
|
||||
/>
|
||||
</View>
|
||||
{subtitle && (
|
||||
<P className="mr-8 text-center text-slate-400">{subtitle}</P>
|
||||
|
||||
@@ -15,9 +15,11 @@ import { P } from "./text";
|
||||
export function useLinkTo({
|
||||
href,
|
||||
replace = false,
|
||||
download,
|
||||
}: {
|
||||
href?: string | null;
|
||||
replace?: boolean;
|
||||
download?: boolean;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
|
||||
@@ -28,8 +30,9 @@ export function useLinkTo({
|
||||
return {
|
||||
// @ts-expect-error href is not known
|
||||
href: href,
|
||||
download,
|
||||
onPress: (e) => {
|
||||
if (e?.defaultPrevented) return;
|
||||
if (e?.defaultPrevented || download) return;
|
||||
// prevent native navigation via href.
|
||||
e?.preventDefault();
|
||||
if (href.startsWith("http")) {
|
||||
@@ -46,15 +49,17 @@ export function useLinkTo({
|
||||
export const A = ({
|
||||
href,
|
||||
replace,
|
||||
download,
|
||||
children,
|
||||
className,
|
||||
...props
|
||||
}: TextProps & {
|
||||
href?: string | null;
|
||||
replace?: boolean;
|
||||
download?: boolean;
|
||||
children: ReactNode;
|
||||
}) => {
|
||||
const linkProps = useLinkTo({ href, replace });
|
||||
const linkProps = useLinkTo({ href, replace, download });
|
||||
|
||||
return (
|
||||
<P
|
||||
@@ -94,6 +99,7 @@ export const PressableFeedback = ({
|
||||
export const Link = ({
|
||||
href,
|
||||
replace,
|
||||
download,
|
||||
children,
|
||||
disabled,
|
||||
...props
|
||||
@@ -102,7 +108,7 @@ export const Link = ({
|
||||
replace?: boolean;
|
||||
download?: boolean;
|
||||
} & PressableProps) => {
|
||||
const linkProps = useLinkTo({ href, replace });
|
||||
const linkProps = useLinkTo({ href, replace, download });
|
||||
|
||||
return (
|
||||
<PressableFeedback
|
||||
|
||||
@@ -117,8 +117,8 @@ const MenuItem = ({
|
||||
closeOnSelect?: boolean;
|
||||
icon?: ComponentType<SvgProps>;
|
||||
} & (
|
||||
| { onSelect: () => void; href?: undefined }
|
||||
| { href: string; onSelect?: undefined }
|
||||
| { onSelect: () => void; href?: undefined; download?: undefined }
|
||||
| { href: string; download?: boolean; onSelect?: undefined }
|
||||
)) => {
|
||||
const setOpen = useContext(MenuContext);
|
||||
const router = useRouter();
|
||||
|
||||
@@ -85,8 +85,8 @@ const MenuItem = forwardRef<
|
||||
closeOnSelect?: boolean;
|
||||
className?: string;
|
||||
} & (
|
||||
| { onSelect: () => void; href?: undefined }
|
||||
| { href: string; onSelect?: undefined }
|
||||
| { onSelect: () => void; href?: undefined; download?: undefined }
|
||||
| { href: string; download?: boolean; onSelect?: undefined }
|
||||
)
|
||||
>(function MenuItem(
|
||||
{
|
||||
@@ -96,6 +96,7 @@ const MenuItem = forwardRef<
|
||||
selected,
|
||||
onSelect,
|
||||
href,
|
||||
download,
|
||||
disabled,
|
||||
closeOnSelect = true,
|
||||
className,
|
||||
@@ -114,7 +115,36 @@ const MenuItem = forwardRef<
|
||||
/>
|
||||
);
|
||||
|
||||
const { onPress, ...linkProps } = useLinkTo({ href });
|
||||
let content = (
|
||||
<>
|
||||
{left && left}
|
||||
{!left && icn}
|
||||
<P
|
||||
className={cn(
|
||||
"flex-1 group-data-highlighted:text-slate-200",
|
||||
disabled && "text-slate-600",
|
||||
)}
|
||||
style={{
|
||||
paddingLeft: 8 * 2 + +!(icon || selected || left) * 24,
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</P>
|
||||
{left && icn}
|
||||
</>
|
||||
);
|
||||
|
||||
let { onPress, ...linkProps } = useLinkTo({ href });
|
||||
|
||||
if (href && download) {
|
||||
content = (
|
||||
<a href={href} download className="flew-row flex items-center">
|
||||
{content}
|
||||
</a>
|
||||
);
|
||||
onPress = undefined;
|
||||
linkProps = {};
|
||||
}
|
||||
|
||||
return (
|
||||
<DropdownMenu.Item
|
||||
@@ -132,21 +162,7 @@ const MenuItem = forwardRef<
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{left && left}
|
||||
{!left && icn}
|
||||
<P
|
||||
className={cn(
|
||||
"flex-1 group-data-highlighted:text-slate-200",
|
||||
disabled && "text-slate-600",
|
||||
)}
|
||||
style={{
|
||||
paddingLeft: 8 * 2 + +!(icon || selected || left) * 24,
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</P>
|
||||
|
||||
{left && icn}
|
||||
{content}
|
||||
</DropdownMenu.Item>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
import Refresh from "@material-symbols/svg-400/rounded/autorenew.svg";
|
||||
import BookmarkAdd from "@material-symbols/svg-400/rounded/bookmark_add.svg";
|
||||
import Delete from "@material-symbols/svg-400/rounded/delete.svg";
|
||||
import MoreHoriz from "@material-symbols/svg-400/rounded/more_horiz.svg";
|
||||
import MovieInfo from "@material-symbols/svg-400/rounded/movie_info.svg";
|
||||
import PlayArrow from "@material-symbols/svg-400/rounded/play_arrow-fill.svg";
|
||||
import Search from "@material-symbols/svg-400/rounded/search-fill.svg";
|
||||
import Theaters from "@material-symbols/svg-400/rounded/theaters-fill.svg";
|
||||
import VideoLibrary from "@material-symbols/svg-400/rounded/video_library-fill.svg";
|
||||
import { useRouter } from "expo-router";
|
||||
import { Fragment } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { View, type ViewProps } from "react-native";
|
||||
import { entryDisplayNumber } from "~/components/entries";
|
||||
import { EntrySelect } from "~/components/entries/select";
|
||||
import { ShowContext } from "~/components/items/context-menus";
|
||||
import { WatchListInfo } from "~/components/items/watchlist-info";
|
||||
import { Rating } from "~/components/rating";
|
||||
import {
|
||||
@@ -26,7 +20,6 @@ import {
|
||||
import type { Metadata } from "~/models/utils/metadata";
|
||||
import {
|
||||
A,
|
||||
Alert,
|
||||
Chip,
|
||||
Container,
|
||||
capitalize,
|
||||
@@ -40,7 +33,6 @@ import {
|
||||
ImageBackground,
|
||||
LI,
|
||||
Link,
|
||||
Menu,
|
||||
P,
|
||||
Popup,
|
||||
Poster,
|
||||
@@ -49,8 +41,7 @@ import {
|
||||
UL,
|
||||
usePopup,
|
||||
} from "~/primitives";
|
||||
import { useAccount } from "~/providers/account-context";
|
||||
import { Fetch, type QueryIdentifier, useMutation } from "~/query";
|
||||
import { Fetch, type QueryIdentifier } from "~/query";
|
||||
import { cn, displayRuntime, getDisplayDate } from "~/utils";
|
||||
import { PartOf } from "./part-of";
|
||||
|
||||
@@ -64,6 +55,7 @@ const ButtonList = ({
|
||||
trailerUrl,
|
||||
watchStatus,
|
||||
iconsClassName,
|
||||
videoSlug,
|
||||
}: {
|
||||
kind: "movie" | "serie" | "collection";
|
||||
slug: string;
|
||||
@@ -74,22 +66,10 @@ const ButtonList = ({
|
||||
trailerUrl: string | null;
|
||||
watchStatus: WatchStatusV | null;
|
||||
iconsClassName?: string;
|
||||
videoSlug: string | null;
|
||||
}) => {
|
||||
const account = useAccount();
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const [setPopup, closePopup] = usePopup();
|
||||
const deleteMutation = useMutation({
|
||||
method: "DELETE",
|
||||
path: ["api", `${kind}s`, slug],
|
||||
invalidate: ["api", "shows"],
|
||||
});
|
||||
|
||||
const metadataRefreshMutation = useMutation({
|
||||
method: "POST",
|
||||
path: ["scanner", `${kind}s`, slug, "refresh"],
|
||||
invalidate: null,
|
||||
});
|
||||
|
||||
return (
|
||||
<View className="flex-row items-center justify-center">
|
||||
@@ -135,76 +115,15 @@ const ButtonList = ({
|
||||
iconClassName={iconsClassName}
|
||||
/>
|
||||
)}
|
||||
{(kind === "movie" || account?.isAdmin === true) && (
|
||||
<Menu
|
||||
Trigger={IconButton}
|
||||
icon={MoreHoriz}
|
||||
iconClassName={iconsClassName}
|
||||
{...tooltip(t("misc.more"))}
|
||||
>
|
||||
{kind === "movie" && videos?.length === 1 && (
|
||||
<>
|
||||
{/* <Menu.Item */}
|
||||
{/* icon={Download} */}
|
||||
{/* onSelect={() => downloader(kind, slug)} */}
|
||||
{/* label={t("home.episodeMore.download")} */}
|
||||
{/* /> */}
|
||||
<Menu.Item
|
||||
label={t("home.episodeMore.mediainfo")}
|
||||
icon={MovieInfo}
|
||||
href={`/info/${slug}`}
|
||||
/>
|
||||
{account?.isAdmin && <HR />}
|
||||
</>
|
||||
)}
|
||||
{account?.isAdmin === true && (
|
||||
<>
|
||||
<Menu.Item
|
||||
label={t("show.videos-map")}
|
||||
icon={VideoLibrary}
|
||||
href={`/${kind === "movie" ? "movies" : "series"}/${slug}/videos`}
|
||||
/>
|
||||
{kind !== "collection" && (
|
||||
<Menu.Item
|
||||
label={t("show.remap")}
|
||||
icon={Search}
|
||||
href={`/${kind}s/${slug}/remap?q=${name}`}
|
||||
/>
|
||||
)}
|
||||
{kind !== "collection" && <HR />}
|
||||
{kind !== "collection" && (
|
||||
<Menu.Item
|
||||
label={t("home.refreshMetadata")}
|
||||
icon={Refresh}
|
||||
onSelect={() => metadataRefreshMutation.mutate()}
|
||||
/>
|
||||
)}
|
||||
<Menu.Item
|
||||
label={t("misc.delete")}
|
||||
icon={Delete}
|
||||
onSelect={() => {
|
||||
Alert.alert(
|
||||
t("misc.delete-name", { name }),
|
||||
t("login.delete-confirmation"),
|
||||
[
|
||||
{ text: t("misc.cancel"), style: "cancel" },
|
||||
{
|
||||
text: t("misc.delete"),
|
||||
style: "destructive",
|
||||
onPress: async () => {
|
||||
await deleteMutation.mutateAsync();
|
||||
router.back();
|
||||
},
|
||||
},
|
||||
],
|
||||
{ cancelable: true },
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Menu>
|
||||
)}
|
||||
<ShowContext
|
||||
kind={kind}
|
||||
slug={slug}
|
||||
name={name}
|
||||
videoSlug={videoSlug}
|
||||
status={watchStatus}
|
||||
showWatchlist={false}
|
||||
iconClassName={iconsClassName}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
@@ -272,6 +191,7 @@ export const TitleLine = ({
|
||||
trailerUrl={trailerUrl}
|
||||
watchStatus={watchStatus}
|
||||
iconsClassName="lg:fill-slate-200 dark:fill-slate-200"
|
||||
videoSlug={videos?.length === 1 ? videos[0].slug : null}
|
||||
/>
|
||||
{Object.keys(rating).length > 0 && (
|
||||
<>
|
||||
@@ -317,10 +237,7 @@ TitleLine.Loader = ({
|
||||
<View className="flex-warp flex-row items-center max-sm:justify-center sm:mt-8">
|
||||
<IconFab icon={PlayArrow} iconClassName="lg:fill-slate-200" />
|
||||
<IconButton icon={Theaters} iconClassName="lg:fill-slate-200" />
|
||||
{kind !== "collection" && (
|
||||
<IconButton icon={BookmarkAdd} iconClassName="lg:fill-slate-200" />
|
||||
)}
|
||||
{kind === "movie" && <IconButton icon={MoreHoriz} />}
|
||||
<IconButton icon={MoreHoriz} iconClassName="lg:fill-slate-200" />
|
||||
<DottedSeparator className="lg:text-slate-200" />
|
||||
<Rating.Loader
|
||||
textClassName="lg:text-slate-200"
|
||||
|
||||
Reference in New Issue
Block a user