mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Rework router
This commit is contained in:
parent
cb65325c56
commit
d2a6ffc1c7
@ -21,12 +21,9 @@
|
|||||||
import { SearchPage } from "@kyoo/ui";
|
import { SearchPage } from "@kyoo/ui";
|
||||||
import { Stack, useLocalSearchParams } from "expo-router";
|
import { Stack, useLocalSearchParams } from "expo-router";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { createParam } from "solito";
|
import { useRouter, useParam } from "@kyoo/primitives";
|
||||||
import { useRouter } from "@kyoo/primitives";
|
|
||||||
import { useTheme } from "yoshiki/native";
|
import { useTheme } from "yoshiki/native";
|
||||||
|
|
||||||
const { useParam } = createParam<{ q?: string }>();
|
|
||||||
|
|
||||||
const Search = () => {
|
const Search = () => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { back } = useRouter();
|
const { back } = useRouter();
|
||||||
@ -52,7 +49,7 @@ const Search = () => {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<SearchPage {...routeParams} />
|
<SearchPage q={query} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -22,6 +22,7 @@ import "~/polyfill";
|
|||||||
// typeof layoutInfo === "function" ? { Layout: layoutInfo, props: {} } : layoutInfo;
|
// typeof layoutInfo === "function" ? { Layout: layoutInfo, props: {} } : layoutInfo;
|
||||||
// return <Layout page={<Component {...props} />} randomItems={[]} {...layoutProps} />;
|
// return <Layout page={<Component {...props} />} randomItems={[]} {...layoutProps} />;
|
||||||
// };
|
// };
|
||||||
|
|
||||||
const GlobalCssTheme = () => {
|
const GlobalCssTheme = () => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
return (
|
return (
|
||||||
@ -76,35 +77,36 @@ const GlobalCssTheme = () => {
|
|||||||
};
|
};
|
||||||
export default function Layout({ children }: { children: ReactNode }) {
|
export default function Layout({ children }: { children: ReactNode }) {
|
||||||
// TODO: theme ssr
|
// TODO: theme ssr
|
||||||
const userTheme = useUserTheme(undefined);
|
// const userTheme = useUserTheme(undefined);
|
||||||
|
|
||||||
useMobileHover();
|
useMobileHover();
|
||||||
|
|
||||||
// TODO: ssr account/error
|
// TODO: ssr account/error
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AccountProvider ssrAccount={undefined} ssrError={undefined}>
|
{/* <AccountProvider ssrAccount={undefined} ssrError={undefined}> */}
|
||||||
<ThemeSelector theme={userTheme} font={{ normal: "inherit" }}>
|
{/* <ThemeSelector theme={userTheme} font={{ normal: "inherit" }}> */}
|
||||||
<PortalProvider>
|
{/* <PortalProvider> */}
|
||||||
<SnackbarProvider>
|
{/* <SnackbarProvider> */}
|
||||||
<GlobalCssTheme />
|
<GlobalCssTheme />
|
||||||
{children}
|
{children}
|
||||||
{/* <ConnectionErrorVerifier skipErrors={(Component as QueryPage).isPublic}>
|
{/* {/* <ConnectionErrorVerifier skipErrors={(Component as QueryPage).isPublic}> */}
|
||||||
<WithLayout
|
{/* <WithLayout */}
|
||||||
Component={children}
|
{/* Component={children} */}
|
||||||
randomItems={
|
{/* randomItems={ */}
|
||||||
randomItems[Component.displayName!] ??
|
{/* randomItems[Component.displayName!] ?? */}
|
||||||
arrayShuffle((Component as QueryPage).randomItems ?? [])
|
{/* arrayShuffle((Component as QueryPage).randomItems ?? []) */}
|
||||||
}
|
{/* } */}
|
||||||
{...props}
|
{/* {...props} */}
|
||||||
/>
|
{/* /> */}
|
||||||
</ConnectionErrorVerifier> */}
|
{/* </ConnectionErrorVerifier> */}
|
||||||
<Tooltip id="tooltip" positionStrategy={"fixed"} />
|
{/* <Tooltip id="tooltip" positionStrategy={"fixed"} /> */}
|
||||||
</SnackbarProvider>
|
{/* </SnackbarProvider> */}
|
||||||
</PortalProvider>
|
{/* </PortalProvider> */}
|
||||||
</ThemeSelector>
|
{/* </ThemeSelector> */}
|
||||||
</AccountProvider>
|
{/* </AccountProvider> */}
|
||||||
<ReactQueryDevtools initialIsOpen={false} />
|
{/* <ReactQueryDevtools initialIsOpen={false} /> */}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import type { Config } from "vike/types";
|
import type { Config } from "vike/types";
|
||||||
import logoUrl from "../../public/icon.svg";
|
|
||||||
import vikeReact from "vike-react/config";
|
import vikeReact from "vike-react/config";
|
||||||
import vikeReactQuery from "vike-react-query/config";
|
import vikeReactQuery from "vike-react-query/config";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
ssr: true,
|
ssr: true,
|
||||||
title: "Kyoo",
|
title: "Kyoo",
|
||||||
favicon: logoUrl,
|
|
||||||
extends: [vikeReact, vikeReactQuery],
|
extends: [vikeReact, vikeReactQuery],
|
||||||
} satisfies Config;
|
} satisfies Config;
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
import { HomePage } from "@kyoo/ui";
|
// import { HomePage } from "@kyoo/ui";
|
||||||
|
|
||||||
export default HomePage;
|
// export default HomePage;
|
||||||
|
|
||||||
|
export default function Test() {
|
||||||
|
return <div>
|
||||||
|
<p>tosej</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@ -13,5 +13,15 @@ export default {
|
|||||||
"~": path.resolve(__dirname, "./src"),
|
"~": path.resolve(__dirname, "./src"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
build: {
|
||||||
|
commonjsOptions: {
|
||||||
|
transformMixedEsModules: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
optimizeDeps: {
|
||||||
|
esbuildOptions: {
|
||||||
|
mainFields: ["module", "main"],
|
||||||
|
},
|
||||||
|
},
|
||||||
plugins: [react(), vike(), reactNativeWeb()],
|
plugins: [react(), vike(), reactNativeWeb()],
|
||||||
} satisfies UserConfig;
|
} satisfies UserConfig;
|
||||||
|
@ -43,3 +43,4 @@ export * from "./chip";
|
|||||||
export * from "./utils";
|
export * from "./utils";
|
||||||
export * from "./constants";
|
export * from "./constants";
|
||||||
export * from "./navigation/router";
|
export * from "./navigation/router";
|
||||||
|
export * from "./navigation/params";
|
||||||
|
@ -23,6 +23,8 @@ import { Platform, Pressable, type TextProps, type View, type PressableProps } f
|
|||||||
import { useTheme, useYoshiki } from "yoshiki/native";
|
import { useTheme, useYoshiki } from "yoshiki/native";
|
||||||
import type { UrlObject } from "node:url";
|
import type { UrlObject } from "node:url";
|
||||||
import { alpha } from "./themes";
|
import { alpha } from "./themes";
|
||||||
|
import { P } from "./text";
|
||||||
|
import { useLink } from "./navigation/link";
|
||||||
|
|
||||||
export const A = ({
|
export const A = ({
|
||||||
href,
|
href,
|
||||||
@ -32,43 +34,16 @@ export const A = ({
|
|||||||
...props
|
...props
|
||||||
}: TextProps & {
|
}: TextProps & {
|
||||||
href?: string | UrlObject | null;
|
href?: string | UrlObject | null;
|
||||||
target?: string;
|
target?: "_blank";
|
||||||
replace?: boolean;
|
replace?: boolean;
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
const { css, theme } = useYoshiki();
|
const link = useLink(href ?? "#", { target, replace });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TextLink
|
<P {...link} {...props}>
|
||||||
href={href ?? ""}
|
|
||||||
target={target}
|
|
||||||
replace={replace as any}
|
|
||||||
experimental={
|
|
||||||
replace
|
|
||||||
? {
|
|
||||||
nativeBehavior: "stack-replace",
|
|
||||||
isNestedNavigator: true,
|
|
||||||
}
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
textProps={css(
|
|
||||||
[
|
|
||||||
{
|
|
||||||
fontFamily: theme.font.normal,
|
|
||||||
color: theme.link,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
userSelect: "text",
|
|
||||||
} as any,
|
|
||||||
],
|
|
||||||
{
|
|
||||||
hrefAttrs: { target },
|
|
||||||
...props,
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{children}
|
{children}
|
||||||
</TextLink>
|
</P>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,20 +68,17 @@ export const PressableFeedback = forwardRef<View, PressableProps>(function Feedb
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const Link = ({
|
export const Link = ({
|
||||||
href: link,
|
href,
|
||||||
replace,
|
replace,
|
||||||
target,
|
target,
|
||||||
children,
|
children,
|
||||||
...props
|
...props
|
||||||
}: { href?: string | UrlObject | null; target?: string; replace?: boolean } & PressableProps) => {
|
}: { href?: string | UrlObject | null; target?: "_blank"; replace?: boolean } & PressableProps) => {
|
||||||
const href = link && typeof link === "object" ? parseNextPath(link) : link;
|
const linkProps = useLink(href ?? "#", {
|
||||||
const linkProps = useLink({
|
target,
|
||||||
href: href ?? "#",
|
|
||||||
replace,
|
replace,
|
||||||
experimental: { nativeBehavior: "stack-replace", isNestedNavigator: true },
|
isNested: true,
|
||||||
});
|
});
|
||||||
// @ts-ignore Missing hrefAttrs type definition.
|
|
||||||
linkProps.hrefAttrs = { ...linkProps.hrefAttrs, target };
|
|
||||||
return (
|
return (
|
||||||
<PressableFeedback
|
<PressableFeedback
|
||||||
{...linkProps}
|
{...linkProps}
|
||||||
|
@ -15,8 +15,9 @@ export const useLink = (
|
|||||||
href,
|
href,
|
||||||
onPress: (e) => {
|
onPress: (e) => {
|
||||||
if (e?.defaultPrevented) return;
|
if (e?.defaultPrevented) return;
|
||||||
if (Platform.OS !== "web" && href.includes("://")) {
|
const abs = href.includes("://");
|
||||||
Linking.openURL(href);
|
if (Platform.OS !== "web" && (abs || opts.target)) {
|
||||||
|
Linking.openURL(abs ? href : `https://${href}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +32,9 @@ export const useLink = (
|
|||||||
we.shiftKey ||
|
we.shiftKey ||
|
||||||
// ignore everything but left clicks
|
// ignore everything but left clicks
|
||||||
we.button !== null ||
|
we.button !== null ||
|
||||||
we.button !== 0
|
we.button !== 0 ||
|
||||||
|
// let the browser handle target blank
|
||||||
|
opts.target
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
23
front/packages/primitives/src/navigation/params.ts
Normal file
23
front/packages/primitives/src/navigation/params.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { useCallback } from "react";
|
||||||
|
import { usePageContext } from "vike-react/usePageContext";
|
||||||
|
import { useRouter } from "./router";
|
||||||
|
|
||||||
|
export const useParam = (name: string) => {
|
||||||
|
const { urlParsed } = usePageContext();
|
||||||
|
const router = useRouter();
|
||||||
|
const val = urlParsed.search[name];
|
||||||
|
|
||||||
|
const setState = useCallback(
|
||||||
|
(newVal: string | null) => {
|
||||||
|
if (newVal) urlParsed.search[name] = newVal;
|
||||||
|
else delete urlParsed.search[name];
|
||||||
|
router.replace({
|
||||||
|
...urlParsed,
|
||||||
|
search: Object.entries(urlParsed.search).join("&"),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[router],
|
||||||
|
);
|
||||||
|
|
||||||
|
return [val, setState] as const;
|
||||||
|
};
|
@ -1,18 +1,23 @@
|
|||||||
import { navigate } from "vike/client/router";
|
import { navigate } from "vike/client/router";
|
||||||
import { type UrlObject, format } from "node:url";
|
import { type UrlObject, format } from "node:url";
|
||||||
|
import { useMemo } from "react";
|
||||||
|
|
||||||
export const useRouter = () => {
|
export const useRouter = () => {
|
||||||
return {
|
const ret = useMemo(
|
||||||
|
() => ({
|
||||||
push: (route: string | UrlObject) => {
|
push: (route: string | UrlObject) => {
|
||||||
if (typeof route === "object") route = format(route);
|
if (typeof route === "object") route = format(route);
|
||||||
navigate(route);
|
navigate(route);
|
||||||
},
|
},
|
||||||
replace: (route: string | UrlObject, opts: {isNested?: boolean} = {}) => {
|
replace: (route: string | UrlObject, opts?: { isNested?: boolean }) => {
|
||||||
if (typeof route === "object") route = format(route);
|
if (typeof route === "object") route = format(route);
|
||||||
navigate(route, { overwriteLastHistoryEntry: opts.isNested });
|
navigate(route, { overwriteLastHistoryEntry: true });
|
||||||
},
|
},
|
||||||
back: () => {
|
back: () => {
|
||||||
window.history.back();
|
window.history.back();
|
||||||
},
|
},
|
||||||
};
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
return ret;
|
||||||
};
|
};
|
||||||
|
@ -1,18 +1,23 @@
|
|||||||
import { navigate } from "vike/client/router";
|
import { navigate } from "vike/client/router";
|
||||||
import { type UrlObject, format } from "node:url";
|
import { type UrlObject, format } from "node:url";
|
||||||
|
import { useMemo } from "react";
|
||||||
|
|
||||||
export const useRouter = () => {
|
export const useRouter = () => {
|
||||||
return {
|
const ret = useMemo(
|
||||||
|
() => ({
|
||||||
push: (route: string | UrlObject) => {
|
push: (route: string | UrlObject) => {
|
||||||
if (typeof route === "object") route = format(route);
|
if (typeof route === "object") route = format(route);
|
||||||
navigate(route);
|
navigate(route);
|
||||||
},
|
},
|
||||||
replace: (route: string | UrlObject, isNested = true) => {
|
replace: (route: string | UrlObject, opts?: { isNested?: boolean }) => {
|
||||||
if (typeof route === "object") route = format(route);
|
if (typeof route === "object") route = format(route);
|
||||||
navigate(route, { overwriteLastHistoryEntry: true });
|
navigate(route, { overwriteLastHistoryEntry: true });
|
||||||
},
|
},
|
||||||
back: () => {
|
back: () => {
|
||||||
window.history.back();
|
window.history.back();
|
||||||
},
|
},
|
||||||
};
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
return ret;
|
||||||
};
|
};
|
||||||
|
@ -25,18 +25,16 @@ import {
|
|||||||
type QueryPage,
|
type QueryPage,
|
||||||
getDisplayDate,
|
getDisplayDate,
|
||||||
} from "@kyoo/models";
|
} from "@kyoo/models";
|
||||||
|
import { useParam } from "@kyoo/primitives";
|
||||||
import { type ComponentProps, useState } from "react";
|
import { type ComponentProps, useState } from "react";
|
||||||
import { createParam } from "solito";
|
import { DefaultLayout } from "../layout";
|
||||||
import type { WithLoading } from "../fetch";
|
import type { WithLoading } from "../fetch";
|
||||||
import { InfiniteFetch } from "../fetch-infinite";
|
import { InfiniteFetch } from "../fetch-infinite";
|
||||||
import { DefaultLayout } from "../layout";
|
|
||||||
import { ItemGrid } from "./grid";
|
import { ItemGrid } from "./grid";
|
||||||
import { BrowseSettings } from "./header";
|
import { BrowseSettings } from "./header";
|
||||||
import { ItemList } from "./list";
|
import { ItemList } from "./list";
|
||||||
import { Layout, SortBy, SortOrd } from "./types";
|
import { Layout, SortBy, SortOrd } from "./types";
|
||||||
|
|
||||||
const { useParam } = createParam<{ sortBy?: string }>();
|
|
||||||
|
|
||||||
export const itemMap = (
|
export const itemMap = (
|
||||||
item: WithLoading<LibraryItem>,
|
item: WithLoading<LibraryItem>,
|
||||||
): WithLoading<ComponentProps<typeof ItemGrid> & ComponentProps<typeof ItemList>> => {
|
): WithLoading<ComponentProps<typeof ItemGrid> & ComponentProps<typeof ItemList>> => {
|
||||||
|
@ -44,7 +44,7 @@ export const LoginPage: QueryPage<{ apiUrl?: string; error?: string }> = ({
|
|||||||
const { css } = useYoshiki();
|
const { css } = useYoshiki();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!apiUrl && Platform.OS !== "web") router.replace("/server-url", false);
|
if (!apiUrl && Platform.OS !== "web") router.replace("/server-url", { isNested: false });
|
||||||
}, [apiUrl, router]);
|
}, [apiUrl, router]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -70,7 +70,7 @@ export const LoginPage: QueryPage<{ apiUrl?: string; error?: string }> = ({
|
|||||||
});
|
});
|
||||||
setError(error);
|
setError(error);
|
||||||
if (error) return;
|
if (error) return;
|
||||||
router.replace("/", false);
|
router.replace("/", { isNested: false });
|
||||||
}}
|
}}
|
||||||
{...css({
|
{...css({
|
||||||
m: ts(1),
|
m: ts(1),
|
||||||
|
@ -104,12 +104,12 @@ export const OidcCallbackPage: QueryPage<{
|
|||||||
hasRun.current = true;
|
hasRun.current = true;
|
||||||
|
|
||||||
function onError(error: string) {
|
function onError(error: string) {
|
||||||
router.replace({ pathname: "/login", query: { error, apiUrl } }, false);
|
router.replace({ pathname: "/login", query: { error, apiUrl } }, { isNested: false });
|
||||||
}
|
}
|
||||||
async function run() {
|
async function run() {
|
||||||
const { error: loginError } = await oidcLogin(provider, code, apiUrl);
|
const { error: loginError } = await oidcLogin(provider, code, apiUrl);
|
||||||
if (loginError) onError(loginError);
|
if (loginError) onError(loginError);
|
||||||
else router.replace("/", false);
|
else router.replace("/", { isNested: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) onError(error);
|
if (error) onError(error);
|
||||||
|
@ -41,7 +41,7 @@ export const RegisterPage: QueryPage<{ apiUrl?: string }> = ({ apiUrl }) => {
|
|||||||
const { css } = useYoshiki();
|
const { css } = useYoshiki();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!apiUrl && Platform.OS !== "web") router.replace("/server-url", false);
|
if (!apiUrl && Platform.OS !== "web") router.replace("/server-url", { isNested: false });
|
||||||
}, [apiUrl, router]);
|
}, [apiUrl, router]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -79,7 +79,7 @@ export const RegisterPage: QueryPage<{ apiUrl?: string }> = ({ apiUrl }) => {
|
|||||||
const { error } = await login("register", { email, username, password, apiUrl });
|
const { error } = await login("register", { email, username, password, apiUrl });
|
||||||
setError(error);
|
setError(error);
|
||||||
if (error) return;
|
if (error) return;
|
||||||
router.replace("/", false);
|
router.replace("/", { isNested: false });
|
||||||
}}
|
}}
|
||||||
{...css({
|
{...css({
|
||||||
m: ts(1),
|
m: ts(1),
|
||||||
|
@ -29,6 +29,7 @@ import {
|
|||||||
Link,
|
Link,
|
||||||
Menu,
|
Menu,
|
||||||
PressableFeedback,
|
PressableFeedback,
|
||||||
|
useRouter,
|
||||||
tooltip,
|
tooltip,
|
||||||
ts,
|
ts,
|
||||||
} from "@kyoo/primitives";
|
} from "@kyoo/primitives";
|
||||||
@ -40,11 +41,10 @@ import Search from "@material-symbols/svg-400/rounded/search-fill.svg";
|
|||||||
import Settings from "@material-symbols/svg-400/rounded/settings.svg";
|
import Settings from "@material-symbols/svg-400/rounded/settings.svg";
|
||||||
import { forwardRef, useEffect, useRef, useState } from "react";
|
import { forwardRef, useEffect, useRef, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Platform, type TextInput, View, type ViewProps } from "react-native";
|
|
||||||
import { useRouter } from "solito/router";
|
|
||||||
import { type Stylable, useYoshiki } from "yoshiki/native";
|
import { type Stylable, useYoshiki } from "yoshiki/native";
|
||||||
import { AdminPage } from "../admin";
|
import { AdminPage } from "../admin";
|
||||||
import { KyooLongLogo } from "./icon";
|
import { KyooLongLogo } from "./icon";
|
||||||
|
import { Platform, TextInput, View, ViewProps } from "react-native";
|
||||||
|
|
||||||
export const NavbarTitle = (props: Stylable & { onLayout?: ViewProps["onLayout"] }) => {
|
export const NavbarTitle = (props: Stylable & { onLayout?: ViewProps["onLayout"] }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -66,7 +66,7 @@ const SearchBar = forwardRef<TextInput, Stylable>(function SearchBar(props, ref)
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Platform.OS !== "web" || !hasChanged.current) return;
|
if (Platform.OS !== "web" || !hasChanged.current) return;
|
||||||
const action = window.location.pathname.startsWith("/search") ? replace : push;
|
const action = window.location.pathname.startsWith("/search") ? replace : push;
|
||||||
if (query) action(`/search?q=${encodeURI(query)}`, undefined, { shallow: true });
|
if (query) action(`/search?q=${encodeURI(query)}`);
|
||||||
else back();
|
else back();
|
||||||
}, [query, push, replace, back]);
|
}, [query, push, replace, back]);
|
||||||
|
|
||||||
|
@ -158,8 +158,8 @@ export const Player = ({
|
|||||||
startTime={startTime}
|
startTime={startTime}
|
||||||
onEnd={() => {
|
onEnd={() => {
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
if (data.type === "movie") router.replace(`/movie/${data.slug}`, true);
|
if (data.type === "movie") router.replace(`/movie/${data.slug}`, { isNested: true });
|
||||||
else router.replace(next ?? `/show/${data.show!.slug}`, true);
|
else router.replace(next ?? `/show/${data.show!.slug}`, { isNested: true });
|
||||||
}}
|
}}
|
||||||
{...css(StyleSheet.absoluteFillObject)}
|
{...css(StyleSheet.absoluteFillObject)}
|
||||||
/>
|
/>
|
||||||
|
@ -19,19 +19,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { type LibraryItem, LibraryItemP, type QueryIdentifier, type QueryPage } from "@kyoo/models";
|
import { type LibraryItem, LibraryItemP, type QueryIdentifier, type QueryPage } from "@kyoo/models";
|
||||||
import { usePageStyle } from "@kyoo/primitives";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { createParam } from "solito";
|
import { DefaultLayout } from "../layout";
|
||||||
|
import { InfiniteFetch } from "../fetch-infinite";
|
||||||
import { itemMap } from "../browse";
|
import { itemMap } from "../browse";
|
||||||
import { ItemGrid } from "../browse/grid";
|
import { ItemGrid } from "../browse/grid";
|
||||||
import { BrowseSettings } from "../browse/header";
|
import { BrowseSettings } from "../browse/header";
|
||||||
import { ItemList } from "../browse/list";
|
import { ItemList } from "../browse/list";
|
||||||
|
import { useParam, usePageStyle } from "@kyoo/primitives";
|
||||||
import { Layout, SearchSort, SortOrd } from "../browse/types";
|
import { Layout, SearchSort, SortOrd } from "../browse/types";
|
||||||
import { InfiniteFetch } from "../fetch-infinite";
|
|
||||||
import { DefaultLayout } from "../layout";
|
|
||||||
|
|
||||||
const { useParam } = createParam<{ sortBy?: string }>();
|
|
||||||
|
|
||||||
const query = (
|
const query = (
|
||||||
query?: string,
|
query?: string,
|
||||||
|
@ -3144,7 +3144,6 @@ __metadata:
|
|||||||
react-native-blurhash: ^1.1.11
|
react-native-blurhash: ^1.1.11
|
||||||
react-native-fast-image: ^8.6.3
|
react-native-fast-image: ^8.6.3
|
||||||
react-native-safe-area-context: 4.8.2
|
react-native-safe-area-context: 4.8.2
|
||||||
solito: ^4.2.0
|
|
||||||
typescript: ^5.3.3
|
typescript: ^5.3.3
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
"@gorhom/portal": "*"
|
"@gorhom/portal": "*"
|
||||||
@ -12079,15 +12078,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"solito@npm:^4.2.0":
|
|
||||||
version: 4.2.0
|
|
||||||
resolution: "solito@npm:4.2.0"
|
|
||||||
dependencies:
|
|
||||||
typescript: ^5.0.4
|
|
||||||
checksum: 58ea67fce743cc864e7cb9065d06fa287fd99bab1b0a96c5d9bd1e974740bb4a308620622c9b46975d58ba084127a8388dc7696cc6e171ed6b501843093ab64f
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"source-map-js@npm:^1.0.1, source-map-js@npm:^1.0.2":
|
"source-map-js@npm:^1.0.1, source-map-js@npm:^1.0.2":
|
||||||
version: 1.0.2
|
version: 1.0.2
|
||||||
resolution: "source-map-js@npm:1.0.2"
|
resolution: "source-map-js@npm:1.0.2"
|
||||||
@ -12740,7 +12730,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"typescript@npm:5.3.3, typescript@npm:^5.0.4, typescript@npm:^5.3.3":
|
"typescript@npm:5.3.3, typescript@npm:^5.3.3":
|
||||||
version: 5.3.3
|
version: 5.3.3
|
||||||
resolution: "typescript@npm:5.3.3"
|
resolution: "typescript@npm:5.3.3"
|
||||||
bin:
|
bin:
|
||||||
@ -12750,7 +12740,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"typescript@patch:typescript@5.3.3#~builtin<compat/typescript>, typescript@patch:typescript@^5.0.4#~builtin<compat/typescript>, typescript@patch:typescript@^5.3.3#~builtin<compat/typescript>":
|
"typescript@patch:typescript@5.3.3#~builtin<compat/typescript>, typescript@patch:typescript@^5.3.3#~builtin<compat/typescript>":
|
||||||
version: 5.3.3
|
version: 5.3.3
|
||||||
resolution: "typescript@patch:typescript@npm%3A5.3.3#~builtin<compat/typescript>::version=5.3.3&hash=701156"
|
resolution: "typescript@patch:typescript@npm%3A5.3.3#~builtin<compat/typescript>::version=5.3.3&hash=701156"
|
||||||
bin:
|
bin:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user