Add a snackbar when playback error occurs

This commit is contained in:
Zoe Roux 2024-01-31 15:07:30 +01:00
parent b21fc9db25
commit 7c56ec8285
6 changed files with 44 additions and 20 deletions

View File

@ -21,7 +21,7 @@
import "react-native-reanimated"; import "react-native-reanimated";
import { PortalProvider } from "@gorhom/portal"; import { PortalProvider } from "@gorhom/portal";
import { ThemeSelector } from "@kyoo/primitives"; import { SnackbarProvider, ThemeSelector } from "@kyoo/primitives";
import { DownloadProvider } from "@kyoo/ui"; import { DownloadProvider } from "@kyoo/ui";
import { AccountProvider, createQueryClient, storage, useUserTheme } from "@kyoo/models"; import { AccountProvider, createQueryClient, storage, useUserTheme } from "@kyoo/models";
import { PersistQueryClientProvider } from "@tanstack/react-query-persist-client"; import { PersistQueryClientProvider } from "@tanstack/react-query-persist-client";
@ -144,7 +144,9 @@ export default function Root() {
<AccountProvider> <AccountProvider>
<DownloadProvider> <DownloadProvider>
<NavigationThemeProvider> <NavigationThemeProvider>
<Slot /> <SnackbarProvider>
<Slot />
</SnackbarProvider>
</NavigationThemeProvider> </NavigationThemeProvider>
</DownloadProvider> </DownloadProvider>
</AccountProvider> </AccountProvider>

View File

@ -22,7 +22,13 @@ import "../polyfill";
import { HydrationBoundary, QueryClientProvider } from "@tanstack/react-query"; import { HydrationBoundary, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import { HiddenIfNoJs, TouchOnlyCss, SkeletonCss, ThemeSelector } from "@kyoo/primitives"; import {
HiddenIfNoJs,
TouchOnlyCss,
SkeletonCss,
ThemeSelector,
SnackbarProvider,
} from "@kyoo/primitives";
import { WebTooltip } from "@kyoo/primitives/src/tooltip.web"; import { WebTooltip } from "@kyoo/primitives/src/tooltip.web";
import { import {
AccountP, AccountP,
@ -138,21 +144,23 @@ const App = ({ Component, pageProps }: AppProps) => {
<HydrationBoundary state={queryState}> <HydrationBoundary state={queryState}>
<ThemeSelector theme={userTheme} font={{ normal: "inherit" }}> <ThemeSelector theme={userTheme} font={{ normal: "inherit" }}>
<PortalProvider> <PortalProvider>
<GlobalCssTheme /> <SnackbarProvider>
<Layout <GlobalCssTheme />
page={ <Layout
<Component page={
randomItems={ <Component
randomItems[Component.displayName!] ?? randomItems={
arrayShuffle((Component as QueryPage).randomItems ?? []) randomItems[Component.displayName!] ??
} arrayShuffle((Component as QueryPage).randomItems ?? [])
{...props} }
/> {...props}
} />
randomItems={[]} }
{...layoutProps} randomItems={[]}
/> {...layoutProps}
<Tooltip id="tooltip" positionStrategy={"fixed"} /> />
<Tooltip id="tooltip" positionStrategy={"fixed"} />
</SnackbarProvider>
</PortalProvider> </PortalProvider>
</ThemeSelector> </ThemeSelector>
</HydrationBoundary> </HydrationBoundary>

View File

@ -31,6 +31,7 @@ export * from "./container";
export * from "./divider"; export * from "./divider";
export * from "./progress"; export * from "./progress";
export * from "./slider"; export * from "./slider";
export * from "./snackbar";
export * from "./alert"; export * from "./alert";
export * from "./menu"; export * from "./menu";
export * from "./popup"; export * from "./popup";

View File

@ -24,6 +24,8 @@ import { useAtomCallback } from "jotai/utils";
import { ElementRef, memo, useEffect, useLayoutEffect, useRef, useState, useCallback } from "react"; import { ElementRef, memo, useEffect, useLayoutEffect, useRef, useState, useCallback } from "react";
import NativeVideo, { VideoProps } from "./video"; import NativeVideo, { VideoProps } from "./video";
import { Platform } from "react-native"; import { Platform } from "react-native";
import { useSnackbar } from "@kyoo/primitives";
import { useTranslation } from "react-i18next";
export const playAtom = atom(true); export const playAtom = atom(true);
export const loadAtom = atom(false); export const loadAtom = atom(false);
@ -188,6 +190,9 @@ export const Video = memo(function Video({
return () => document.removeEventListener("fullscreenchange", handler); return () => document.removeEventListener("fullscreenchange", handler);
}); });
const createSnackbar = useSnackbar();
const { t } = useTranslation();
if (!source || !links) return null; if (!source || !links) return null;
return ( return (
<NativeVideo <NativeVideo
@ -218,6 +223,11 @@ export const Video = memo(function Video({
fonts={fonts} fonts={fonts}
subtitles={subtitles} subtitles={subtitles}
onMediaUnsupported={() => { onMediaUnsupported={() => {
createSnackbar({
key: "unsuported",
label: t("player.unsupportedError"),
duration: 3,
});
if (mode == PlayMode.Direct) setPlayMode(PlayMode.Hls); if (mode == PlayMode.Direct) setPlayMode(PlayMode.Hls);
}} }}
/> />

View File

@ -151,7 +151,8 @@
"direct": "Pristine", "direct": "Pristine",
"transmux": "Original", "transmux": "Original",
"auto": "Auto", "auto": "Auto",
"notInPristine": "Unavailable in pristine" "notInPristine": "Unavailable in pristine",
"unsupportedError": "Video codec not supported, transcoding in progress..."
}, },
"search": { "search": {
"empty": "No result found. Try a different query." "empty": "No result found. Try a different query."

View File

@ -150,7 +150,9 @@
"fullscreen": "Plein-écran", "fullscreen": "Plein-écran",
"direct": "Pristine", "direct": "Pristine",
"transmux": "Original", "transmux": "Original",
"auto": "Auto" "auto": "Auto",
"notInPristine": "Non disponible en pristine",
"unsupportedError": "Video codec not supported, transcoding in progress..."
}, },
"search": { "search": {
"empty": "Aucun résultat trouvé. Essayer avec une autre recherche." "empty": "Aucun résultat trouvé. Essayer avec une autre recherche."