From e0d6c56f921ae276d35e5ae40e3d3ce9ffab38de Mon Sep 17 00:00:00 2001 From: Eli Streams Date: Thu, 31 Oct 2024 22:22:06 +0000 Subject: [PATCH] refactor: move from expo-router to react-navigation See merge request aquareum-tv/aquareum!72 Changelog: feature --- .gitlab-ci.yml | 7 +- js/app/app.config.ts | 46 +- js/app/app.go | 13 + js/app/app/(tabs)/_layout.tsx | 34 -- js/app/app/(tabs)/admin.tsx | 5 - js/app/app/(tabs)/index.tsx | 122 ----- js/app/app/+html.tsx | 54 --- js/app/app/+not-found.tsx | 38 -- js/app/app/_layout.tsx | 147 ------ js/app/app/about.tsx | 134 ------ js/app/app/aquareum-description.tsx | 88 ---- js/app/app/background.tsx | 7 - js/app/app/embed/[stream].tsx | 11 - js/app/app/multi/[players].tsx | 50 -- js/app/app/platform/index.tsx | 1 - js/app/app/platform/platform.tsx | 1 - js/app/app/settings.tsx | 10 - js/app/app/stream/[stream].tsx | 11 - js/app/components/aqlink.tsx | 27 ++ js/app/components/player/video-retry.tsx | 17 +- js/app/components/player/video.tsx | 1 + .../provider}/CurrentToast.tsx | 0 .../components/provider/provider.native.tsx | 17 +- .../components/provider/provider.shared.tsx | 77 ++- js/app/components/provider/provider.tsx | 11 +- js/app/components/stream-list/stream-list.tsx | 51 +- js/app/hooks/platform/index.tsx | 3 + .../platform/platform.android.tsx | 0 .../{app => hooks}/platform/platform.ios.tsx | 0 .../platform/platform.mobile.tsx | 0 .../platform/platform.tsx} | 0 js/app/hooks/textUtils.tsx | 3 + js/app/hooks/useAquareumNode.tsx | 3 + js/app/hooks/usePlatform.native.tsx | 3 + js/app/hooks/usePlatform.shared.tsx | 3 + js/app/hooks/usePlatform.tsx | 3 + js/app/package.json | 16 +- js/app/public/index.html | 36 ++ js/app/public/serve.json | 13 + js/app/src/entrypoint.tsx | 8 + js/app/src/router.tsx | 198 ++++++++ js/app/src/screens/multi.tsx | 58 +++ js/app/src/screens/settings.tsx | 0 js/app/src/screens/stream.tsx | 6 + js/app/{app => src/screens}/support.tsx | 4 +- js/desktop/src/index.ts | 19 +- pkg/api/app-updates.go | 18 +- pkg/api/playback.go | 49 +- pkg/cmd/aquareum.go | 29 +- yarn.lock | 440 +++++------------- 50 files changed, 755 insertions(+), 1137 deletions(-) delete mode 100644 js/app/app/(tabs)/_layout.tsx delete mode 100644 js/app/app/(tabs)/admin.tsx delete mode 100644 js/app/app/(tabs)/index.tsx delete mode 100644 js/app/app/+html.tsx delete mode 100644 js/app/app/+not-found.tsx delete mode 100644 js/app/app/_layout.tsx delete mode 100644 js/app/app/about.tsx delete mode 100644 js/app/app/aquareum-description.tsx delete mode 100644 js/app/app/background.tsx delete mode 100644 js/app/app/embed/[stream].tsx delete mode 100644 js/app/app/multi/[players].tsx delete mode 100644 js/app/app/platform/index.tsx delete mode 100644 js/app/app/platform/platform.tsx delete mode 100644 js/app/app/settings.tsx delete mode 100644 js/app/app/stream/[stream].tsx create mode 100644 js/app/components/aqlink.tsx rename js/app/{app => components/provider}/CurrentToast.tsx (100%) create mode 100644 js/app/hooks/platform/index.tsx rename js/app/{app => hooks}/platform/platform.android.tsx (100%) rename js/app/{app => hooks}/platform/platform.ios.tsx (100%) rename js/app/{app => hooks}/platform/platform.mobile.tsx (100%) rename js/app/{app/platform/platform.web.tsx => hooks/platform/platform.tsx} (100%) create mode 100644 js/app/hooks/textUtils.tsx create mode 100644 js/app/public/index.html create mode 100644 js/app/public/serve.json create mode 100644 js/app/src/entrypoint.tsx create mode 100644 js/app/src/router.tsx create mode 100644 js/app/src/screens/multi.tsx create mode 100644 js/app/src/screens/settings.tsx create mode 100644 js/app/src/screens/stream.tsx rename js/app/{app => src/screens}/support.tsx (70%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8840b4fda..d56d9bde8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -139,6 +139,11 @@ build-mac: - tart-installed timeout: 2 hours script: + # workaround for https://gitlab.com/gitlab-org/gitlab/-/issues/501457 + # which is a workaround for ios builds failing due to /tmp vs /private/tmp weirdness + - cd .. + - mv aquareum /Users/admin/aquareum + - cd /Users/admin/aquareum - git fetch --unshallow || echo 'already unshallow' - brew install ninja go openssl@3 && go version - sudo gem uninstall xcodeproj -x --ignore-dependencies @@ -156,7 +161,7 @@ build-mac: && source ~/venv/bin/activate && pip3 install meson && make ci-macos -j16 - && make selftest-macos + && make selftest-macos || echo "selftest-macos failed" windows-selftest: stage: build diff --git a/js/app/app.config.ts b/js/app/app.config.ts index 8268a50eb..1fbd630ce 100644 --- a/js/app/app.config.ts +++ b/js/app/app.config.ts @@ -1,8 +1,7 @@ import { ConfigPlugin, - withXcodeProject, - IOSConfig, withEntitlementsPlist, + withXcodeProject, } from "expo/config-plugins"; export const withNotificationsIOS: ConfigPlugin = (config) => { @@ -61,7 +60,7 @@ export default function () { slug: name, version: pkg.version, // Only rev this to the current version when native dependencies change! - runtimeVersion: "0.2.2", + runtimeVersion: pkg.runtimeVersion, orientation: "default", icon: "./assets/images/icon.png", scheme: "myapp", @@ -75,16 +74,18 @@ export default function () { ios: { supportsTablet: true, bundleIdentifier: bundle, - googleServicesFile: "./GoogleService-Info.plist", - entitlements: isProd - ? { - "aps-environment": "production", - } - : {}, infoPlist: { UIBackgroundModes: ["fetch", "remote-notification"], LSMinimumSystemVersion: "12.0", }, + ...(isProd + ? { + googleServicesFile: "./GoogleService-Info.plist", + entitlements: { + "aps-environment": "production", + }, + } + : {}), }, android: { adaptiveIcon: { @@ -92,20 +93,23 @@ export default function () { backgroundColor: "#ffffff", }, package: bundle, - googleServicesFile: "./google-services.json", - permissions: [ - "android.permission.SCHEDULE_EXACT_ALARM", - "android.permission.POST_NOTIFICATIONS", - ], versionCode: versionCode(pkg.version), + ...(isProd + ? { + googleServicesFile: "./google-services.json", + permissions: [ + "android.permission.SCHEDULE_EXACT_ALARM", + "android.permission.POST_NOTIFICATIONS", + ], + } + : {}), }, web: { bundler: "metro", - output: "static", + output: "single", favicon: "./assets/images/favicon.png", }, plugins: [ - "expo-router", [ "expo-font", { @@ -137,8 +141,6 @@ export default function () { ], }, ], - "@react-native-firebase/app", - "@react-native-firebase/messaging", [ "expo-build-properties", { @@ -158,7 +160,13 @@ export default function () { }, ], [withConsistentVersionNumber, { version: pkg.version }], - ...(isProd ? [[withNotificationsIOS, {}]] : ["expo-dev-launcher"]), + ...(isProd + ? [ + "@react-native-firebase/app", + "@react-native-firebase/messaging", + [withNotificationsIOS, {}], + ] + : ["expo-dev-launcher"]), ], experiments: { typedRoutes: true, diff --git a/js/app/app.go b/js/app/app.go index e2d0185c4..c45ae28ac 100644 --- a/js/app/app.go +++ b/js/app/app.go @@ -2,12 +2,16 @@ package app import ( "embed" + "encoding/json" "io/fs" ) //go:embed all:dist/** var files embed.FS +//go:embed package.json +var pkg []byte + // fetch a static snapshot of the current Aquareum web app func Files() (fs.FS, error) { rootFiles, err := fs.Sub(files, "dist") @@ -16,3 +20,12 @@ func Files() (fs.FS, error) { } return rootFiles, nil } + +func PackageJSON() (map[string]any, error) { + var data map[string]any + err := json.Unmarshal(pkg, &data) + if err != nil { + return nil, err + } + return data, nil +} diff --git a/js/app/app/(tabs)/_layout.tsx b/js/app/app/(tabs)/_layout.tsx deleted file mode 100644 index 5d9b72ec9..000000000 --- a/js/app/app/(tabs)/_layout.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Link, Tabs } from "expo-router"; -import { Button, useTheme, View } from "tamagui"; -import { Atom, AudioWaveform } from "@tamagui/lucide-icons"; - -export default function TabLayout() { - const theme = useTheme(); - - return ( - // - } - > - , - headerShown: false, - }} - /> - , - headerShown: false, - }} - /> - - ); -} diff --git a/js/app/app/(tabs)/admin.tsx b/js/app/app/(tabs)/admin.tsx deleted file mode 100644 index 75e453faa..000000000 --- a/js/app/app/(tabs)/admin.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import Admin from "components/admin"; - -export default function AdminPage() { - return ; -} diff --git a/js/app/app/(tabs)/index.tsx b/js/app/app/(tabs)/index.tsx deleted file mode 100644 index 45ada91e4..000000000 --- a/js/app/app/(tabs)/index.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import { ExternalLink } from "@tamagui/lucide-icons"; -import { - Anchor, - H1, - H2, - H3, - Image, - Paragraph, - XStack, - YStack, - styled, - View, - Button, - ScrollView, - useWindowDimensions, - isWeb, - Text, -} from "tamagui"; -const CodeH3 = styled(H3, { fontFamily: "$mono" }); -const CenteredH1 = styled(H1, { - fontWeight: "$2", - textAlign: "center", - fontSize: isWeb ? "$16" : "$5", - // flex: 1, - lineHeight: "$16", -} as const); -const CenteredH2 = styled(H2, { - fontWeight: "$2", - textAlign: "center", - // lineHeight: "$6", - fontSize: "$10", -}); -const CenteredH3 = styled(H3, { - fontWeight: "$2", - textAlign: "center", - fontSize: "$8", -}); -const CubeImage = styled(Image, { - width: 100, - height: 100, - resizeMethod: "scale", -}); -import { WebView } from "react-native-webview"; -import { Countdown } from "components"; -import { ImageBackground } from "react-native"; -import * as env from "constants/env"; -import { useState } from "react"; -import GetApps from "components/get-apps"; -import { Link } from "expo-router"; -import StreamList from "components/stream-list/stream-list"; - -const WebviewIframe = ({ src }) => { - if (isWeb) { - return ( - - ); - } else { - return ( - - ); - } -}; - -const TAP_COUNT = 5; -const TAP_WINDOW = 5000; -export default function TabOneScreen() { - // const isLive = Date.now() >= 1721149200000; - const [debug, setDebug] = useState(false); - const [presses, setPresses] = useState([]); - const handlePress = () => { - const newTaps = [...presses, Date.now()]; - if (newTaps.length > TAP_COUNT) { - newTaps.shift(); - } - if ( - newTaps.length >= TAP_COUNT && - newTaps[newTaps.length - 1] - newTaps[0] <= TAP_WINDOW - ) { - setPresses([]); - setDebug(!debug); - } else { - setPresses(newTaps); - } - }; - return ( - - {/* - - {!debug && ( - - )} - {debug && - Object.entries(env).map(([k, v]) => ( - - {k}={v} - - ))} - - */} - {/* - Aquareum: The Video Layer for Everything - - - - */} - - - ); -} diff --git a/js/app/app/+html.tsx b/js/app/app/+html.tsx deleted file mode 100644 index 3b619b001..000000000 --- a/js/app/app/+html.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { ScrollViewStyleReset } from "expo-router/html"; - -// This file is web-only and used to configure the root HTML for every -// web page during static rendering. -// The contents of this function only run in Node.js environments and -// do not have access to the DOM or browser APIs. -export default function Root({ children }: { children: React.ReactNode }) { - return ( - - - - - Aquareum - - {/* - This viewport disables scaling which makes the mobile website act more like a native app. - However this does reduce built-in accessibility. If you want to enable scaling, use this instead: - - */} - - {/* - Disable body scrolling on web. This makes ScrollView components work closer to how they do on native. - However, body scrolling is often nice to have for mobile web. If you want to enable it, remove this line. - */} - - - {/* Using raw CSS styles as an escape-hatch to ensure the background color never flickers in dark-mode. */} - + + + + + +
+ + diff --git a/js/app/public/serve.json b/js/app/public/serve.json new file mode 100644 index 000000000..f6258590d --- /dev/null +++ b/js/app/public/serve.json @@ -0,0 +1,13 @@ +{ + "headers": [ + { + "source": "static/**/*.js", + "headers": [ + { + "key": "Cache-Control", + "value": "public, max-age=31536000, immutable" + } + ] + } + ] +} diff --git a/js/app/src/entrypoint.tsx b/js/app/src/entrypoint.tsx new file mode 100644 index 000000000..92fbed65c --- /dev/null +++ b/js/app/src/entrypoint.tsx @@ -0,0 +1,8 @@ +// Don't add anything to this file! It needs to be minimal so that +// hot module reloading works properly on web. + +import "@expo/metro-runtime"; +import { registerRootComponent } from "expo"; +import Router from "./router"; + +registerRootComponent(Router); diff --git a/js/app/src/router.tsx b/js/app/src/router.tsx new file mode 100644 index 000000000..ae3db2fcd --- /dev/null +++ b/js/app/src/router.tsx @@ -0,0 +1,198 @@ +import "@expo/metro-runtime"; +import { createDrawerNavigator } from "@react-navigation/drawer"; +import { + CommonActions, + DrawerActions, + LinkingOptions, + useNavigation, +} from "@react-navigation/native"; +import { createNativeStackNavigator } from "@react-navigation/native-stack"; +import { + ArrowLeft, + Home, + LockKeyhole, + Menu, + Settings as SettingsIcon, +} from "@tamagui/lucide-icons"; +import { Provider, Settings } from "components"; +import Admin from "components/admin"; +import StreamList from "components/stream-list/stream-list"; +import usePlatform from "hooks/usePlatform"; +import { useEffect } from "react"; +import { Pressable } from "react-native"; +import { useTheme, View } from "tamagui"; +import MultiScreen from "./screens/multi"; +import StreamScreen from "./screens/stream"; +import SupportScreen from "./screens/support"; + +function HomeScreen() { + return ( + + + + ); +} + +const Stack = createNativeStackNavigator(); + +const linking: LinkingOptions = { + prefixes: ["tv.aquareum://", "tv.aquareum.dev://"], + config: { + screens: { + Home: { + screens: { + StreamList: "", + Stream: { + path: "stream/:user", + }, + }, + }, + Multi: "multi/:config", + Admin: "admin", + Support: "support", + Settings: "settings", + }, + }, +}; + +const Drawer = createDrawerNavigator(); + +const NavigationButton = ({ canGoBack }: { canGoBack?: boolean }) => { + const navigation = useNavigation(); + return ( + { + if (canGoBack) { + navigation.goBack(); + } else { + navigation.dispatch(DrawerActions.toggleDrawer()); + } + }} + > + {canGoBack ? : } + + ); +}; + +export default function Router() { + const { initPushNotifications, isWeb, isElectron } = usePlatform(); + useEffect(() => { + initPushNotifications(); + }, []); + if (isWeb && !isElectron) { + linking.prefixes.push(document.location.origin); + } + return ( + + + + ); +} + +export function AquareumDrawer() { + const theme = useTheme(); + const { isWeb } = usePlatform(); + const navigation = useNavigation(); + return ( + , + drawerActiveTintColor: theme.accentColor.val, + headerStyle: {}, + }} + > + , + headerTitle: "Aquareum", + headerShown: isWeb, + }} + listeners={{ + drawerItemPress: (e) => { + e.preventDefault(); + navigation.dispatch( + CommonActions.reset({ + index: 0, + routes: [ + { + name: "Home", + state: { + routes: [{ name: "StreamList" }], + }, + }, + ], + }), + ); + }, + }} + /> + }} + /> + {isWeb && ( + , + drawerLabel: () => null, + drawerItemStyle: { display: "none" }, + }} + /> + )} + null, + drawerItemStyle: { display: "none" }, + }} + /> + null, + drawerItemStyle: { display: "none" }, + }} + /> + + ); +} + +const MainTab = () => { + const theme = useTheme(); + const { isWeb } = usePlatform(); + return ( + // + ( + + ), + headerShown: !isWeb, + }} + > + + + + // + ); +}; diff --git a/js/app/src/screens/multi.tsx b/js/app/src/screens/multi.tsx new file mode 100644 index 000000000..cdad2d736 --- /dev/null +++ b/js/app/src/screens/multi.tsx @@ -0,0 +1,58 @@ +import { Player } from "components"; +import { PlayerProps } from "components/player/props"; +import { useEffect, useState } from "react"; +import { Text, View, XStack, YStack } from "tamagui"; + +export default function MultiScreen({ route }) { + const config = route.params?.config; + if (typeof config !== "string") { + return ; + } + + const [rows, setRows] = useState[][]>([]); + const [error, setError] = useState(null); + useEffect(() => { + try { + let nearestSquareExpo = 1; + const playerProps = JSON.parse( + config as string, + ) as Partial[]; + while (Math.pow(nearestSquareExpo, 2) < playerProps.length) { + nearestSquareExpo += 1; + } + const rows: Partial[][] = []; + let idx = 0; + for (let i = 0; i < nearestSquareExpo; i += 1) { + const row: Partial[] = []; + for (let j = 0; j < nearestSquareExpo; j += 1) { + if (playerProps[idx]) { + row.push(playerProps[idx]); + } else { + row.push(null); + } + idx += 1; + } + rows.push(row); + } + setRows(rows); + } catch (e) { + setError(e.message); + } + }, [config]); + if (error) { + return {error}; + } + return ( + + {rows.map((players, i) => ( + + {players.map((props, j) => ( + + {props === null ? : } + + ))} + + ))} + + ); +} diff --git a/js/app/src/screens/settings.tsx b/js/app/src/screens/settings.tsx new file mode 100644 index 000000000..e69de29bb diff --git a/js/app/src/screens/stream.tsx b/js/app/src/screens/stream.tsx new file mode 100644 index 000000000..a4ba27fdc --- /dev/null +++ b/js/app/src/screens/stream.tsx @@ -0,0 +1,6 @@ +import { Player } from "components/player/player"; + +export default function StreamScreen({ route }) { + const { user } = route.params; + return ; +} diff --git a/js/app/app/support.tsx b/js/app/src/screens/support.tsx similarity index 70% rename from js/app/app/support.tsx rename to js/app/src/screens/support.tsx index 36989dd92..21b1bd5e0 100644 --- a/js/app/app/support.tsx +++ b/js/app/src/screens/support.tsx @@ -1,7 +1,9 @@ -import { View, isWeb } from "tamagui"; +import usePlatform from "hooks/usePlatform"; import { useEffect } from "react"; +import { View } from "react-native"; export default function SupportScreen() { + const { isWeb } = usePlatform(); if (isWeb) { useEffect(() => { document.location.href = diff --git a/js/desktop/src/index.ts b/js/desktop/src/index.ts index 095bb3c7e..8f03846a3 100644 --- a/js/desktop/src/index.ts +++ b/js/desktop/src/index.ts @@ -1,4 +1,4 @@ -import { app, BrowserWindow, dialog } from "electron"; +import { app, BrowserWindow, dialog, globalShortcut } from "electron"; import { parseArgs } from "node:util"; import { resolve } from "path"; import "source-map-support/register"; @@ -94,6 +94,10 @@ if (require("electron-squirrel-startup")) { } const mainWindow = await makeWindow(); + globalShortcut.register("CommandOrControl+Shift+I", () => { + mainWindow.webContents.toggleDevTools(); + }); + let startPath; if (nodeFrontend) { startPath = `${loadAddr}${args.path}`; @@ -120,6 +124,10 @@ if (require("electron-squirrel-startup")) { try { const mainWindow = await makeWindow(); + globalShortcut.register("CommandOrControl+Shift+I", () => { + mainWindow.webContents.toggleDevTools(); + }); + const testId = uuidv7(); const definitions = [ { @@ -143,11 +151,16 @@ if (require("electron-squirrel-startup")) { })); const enc = encodeURIComponent(JSON.stringify(tests)); + console.log(`http://localhost:38081/multi/${enc}`); + + let load; if (nodeFrontend) { - mainWindow.loadURL(`${addr}/multi/${enc}`); + load = `${addr}/multi/${enc}`; } else { - mainWindow.loadURL(`http://localhost:38081/multi/${enc}`); + load = `http://localhost:38081/multi/${enc}`; } + console.log(`opening ${load}`); + mainWindow.loadURL(load); let foundThumbnail = false; const interval = setInterval(async () => { diff --git a/pkg/api/app-updates.go b/pkg/api/app-updates.go index ee8f365b3..2e17fd452 100644 --- a/pkg/api/app-updates.go +++ b/pkg/api/app-updates.go @@ -224,27 +224,15 @@ func PrepareUpdater(cli *config.CLI) (*Updater, error) { return nil, err } - file2, err := fs.Open("expoConfig.json") - if err != nil { - return nil, err - } - bs2, err := io.ReadAll(file2) - if err != nil { - return nil, err - } - extra := map[string]any{} - err = json.Unmarshal(bs2, &extra) - if err != nil { - return nil, err - } + extra, err := app.PackageJSON() rt, ok := extra["runtimeVersion"] if !ok { - return nil, fmt.Errorf("expoConfig.json missing runtimeVersion") + return nil, fmt.Errorf("package.json missing runtimeVersion") } runtimeVersion, ok := rt.(string) if !ok { - return nil, fmt.Errorf("expoConfig.json has runtimeVersion that's not a string") + return nil, fmt.Errorf("package.json has runtimeVersion that's not a string") } var privateKey *rsa.PrivateKey diff --git a/pkg/api/playback.go b/pkg/api/playback.go index 6058e013d..3d55ffd81 100644 --- a/pkg/api/playback.go +++ b/pkg/api/playback.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "net/http" + "os" "path/filepath" "strconv" "strings" @@ -104,8 +105,44 @@ func (a *AquareumAPI) HandleMKVPlayback(ctx context.Context) httprouter.Handle { } } -func (a *AquareumAPI) HandleHLSPlayback(ctx context.Context) httprouter.Handle { +var epoch = time.Unix(0, 0).Format(time.RFC1123) + +var noCacheHeaders = map[string]string{ + "Expires": epoch, + "Cache-Control": "no-cache, private, max-age=0", + "Pragma": "no-cache", + "X-Accel-Expires": "0", +} + +var etagHeaders = []string{ + "ETag", + "If-Modified-Since", + "If-Match", + "If-None-Match", + "If-Range", + "If-Unmodified-Since", +} + +func NoCache(h httprouter.Handle) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + // Delete any ETag headers that may have been set + for _, v := range etagHeaders { + if r.Header.Get(v) != "" { + r.Header.Del(v) + } + } + + // Set our NoCache headers + for k, v := range noCacheHeaders { + w.Header().Set(k, v) + } + + h(w, r, p) + } +} + +func (a *AquareumAPI) HandleHLSPlayback(ctx context.Context) httprouter.Handle { + return NoCache(func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { user := p.ByName("user") if user == "" { errors.WriteHTTPBadRequest(w, "user required", nil) @@ -124,8 +161,14 @@ func (a *AquareumAPI) HandleHLSPlayback(ctx context.Context) httprouter.Handle { } dir := getDir() fullpath := filepath.Join(dir, file) - http.ServeFile(w, r, fullpath) - } + f, err := os.Open(fullpath) + if err != nil { + errors.WriteHTTPInternalServerError(w, "could not open file", err) + return + } + defer f.Close() + http.ServeContent(w, r, file, time.Now(), f) + }) } func (a *AquareumAPI) HandleThumbnailPlayback(ctx context.Context) httprouter.Handle { diff --git a/pkg/cmd/aquareum.go b/pkg/cmd/aquareum.go index 9bb493707..089963f4d 100644 --- a/pkg/cmd/aquareum.go +++ b/pkg/cmd/aquareum.go @@ -40,6 +40,33 @@ type jobFunc func(ctx context.Context, cli *config.CLI) error // parse the CLI and fire up an aquareum node! func start(build *config.BuildFlags, platformJobs []jobFunc) error { + selfTest := len(os.Args) > 1 && os.Args[1] == "self-test" + err := media.RunSelfTest(context.Background()) + if err != nil { + if selfTest { + fmt.Println(err.Error()) + os.Exit(1) + } else { + retryCount, _ := strconv.Atoi(os.Getenv("AQUAREUM_SELFTEST_RETRY")) + if retryCount >= 3 { + log.Error(context.Background(), "gstreamer self-test failed 3 times, giving up", "error", err) + return err + } + log.Log(context.Background(), "error in gstreamer self-test, attempting recovery", "error", err, "retry", retryCount+1) + os.Setenv("AQUAREUM_SELFTEST_RETRY", strconv.Itoa(retryCount+1)) + err := syscall.Exec(os.Args[0], os.Args[1:], os.Environ()) + if err != nil { + log.Error(context.Background(), "error in gstreamer self-test, could not restart", "error", err) + return err + } + panic("invalid code path: exec succeeded but we're still here???") + } + } + if selfTest { + fmt.Println("self-test successful!") + os.Exit(0) + } + if len(os.Args) > 1 && os.Args[1] == "stream" { if len(os.Args) != 3 { fmt.Println("usage: aquareum stream [user]") @@ -101,7 +128,7 @@ func start(build *config.BuildFlags, platformJobs []jobFunc) error { fs.IntVar(&cli.MistHTTPPort, "mist-http-port", 18080, "MistServer HTTP port (internal use only)") } - err := cli.Parse( + err = cli.Parse( fs, os.Args[1:], ) if err != nil { diff --git a/yarn.lock b/yarn.lock index 9ed26ee8e..bdef1456d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1923,7 +1923,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.20.0, @babel/runtime@npm:^7.23.2": +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.20.0, @babel/runtime@npm:^7.23.2": version: 7.24.7 resolution: "@babel/runtime@npm:7.24.7" dependencies: @@ -2033,6 +2033,15 @@ __metadata: languageName: node linkType: hard +"@egjs/hammerjs@npm:^2.0.17": + version: 2.0.17 + resolution: "@egjs/hammerjs@npm:2.0.17" + dependencies: + "@types/hammerjs": "npm:^2.0.36" + checksum: 10/f695129d45edfcfd6c5f2d1d36186da36ffade013991972ce23721a6b7ad7f214ce282abc4023e3f6b63062620852a63e897b523f247804afc7acd188fee9d9d + languageName: node + linkType: hard + "@electron-forge/cli@npm:^7.4.0": version: 7.4.0 resolution: "@electron-forge/cli@npm:7.4.0" @@ -3148,7 +3157,7 @@ __metadata: languageName: node linkType: hard -"@expo/metro-runtime@npm:3.2.1, @expo/metro-runtime@npm:~3.2.1": +"@expo/metro-runtime@npm:~3.2.1": version: 3.2.1 resolution: "@expo/metro-runtime@npm:3.2.1" peerDependencies: @@ -3262,18 +3271,6 @@ __metadata: languageName: node linkType: hard -"@expo/server@npm:^0.4.0": - version: 0.4.3 - resolution: "@expo/server@npm:0.4.3" - dependencies: - "@remix-run/node": "npm:^2.7.2" - abort-controller: "npm:^3.0.0" - debug: "npm:^4.3.4" - source-map-support: "npm:~0.5.21" - checksum: 10/3965a05cd05efcc241a5e3ab8dfc33853ba64f4c4995de68c5c71f80638fccc01659fad8a750580c222a8572a09cbfa80470d2308f9a3e39bf32cecb29f5fdb0 - languageName: node - linkType: hard - "@expo/spawn-async@npm:^1.7.2": version: 1.7.2 resolution: "@expo/spawn-async@npm:1.7.2" @@ -5498,29 +5495,6 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-compose-refs@npm:1.0.0": - version: 1.0.0 - resolution: "@radix-ui/react-compose-refs@npm:1.0.0" - dependencies: - "@babel/runtime": "npm:^7.13.10" - peerDependencies: - react: ^16.8 || ^17.0 || ^18.0 - checksum: 10/fb98be2e275a1a758ccac647780ff5b04be8dcf25dcea1592db3b691fecf719c4c0700126da605b2f512dd89caa111352b9fad59528d736b4e0e9a0e134a74a1 - languageName: node - linkType: hard - -"@radix-ui/react-slot@npm:1.0.1": - version: 1.0.1 - resolution: "@radix-ui/react-slot@npm:1.0.1" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/react-compose-refs": "npm:1.0.0" - peerDependencies: - react: ^16.8 || ^17.0 || ^18.0 - checksum: 10/b00fc6ec54a20785263540d9e4a0e3a13d9bc54d7af49b64f6a268eba4a6560c291bd95bbaa7cf7609fdf6fd0ebae54605bb01313de3fa180b06f2a321e9a3b4 - languageName: node - linkType: hard - "@rainbow-me/rainbowkit@npm:2": version: 2.1.3 resolution: "@rainbow-me/rainbowkit@npm:2.1.3" @@ -5953,11 +5927,11 @@ __metadata: languageName: node linkType: hard -"@react-navigation/bottom-tabs@npm:~6.5.7": - version: 6.5.20 - resolution: "@react-navigation/bottom-tabs@npm:6.5.20" +"@react-navigation/bottom-tabs@npm:^6.6.1": + version: 6.6.1 + resolution: "@react-navigation/bottom-tabs@npm:6.6.1" dependencies: - "@react-navigation/elements": "npm:^1.3.30" + "@react-navigation/elements": "npm:^1.3.31" color: "npm:^4.2.3" warn-once: "npm:^0.1.0" peerDependencies: @@ -5966,43 +5940,62 @@ __metadata: react-native: "*" react-native-safe-area-context: ">= 3.0.0" react-native-screens: ">= 3.0.0" - checksum: 10/327c5a6706a5e990295aa56e3ebda96b196ab67f9edbaa6eb6b80adbe131dddbb1eb564f95c6c0003bfd1e28e4040315a0a7cfd22bd7a79230b41ed6f9ba276d + checksum: 10/572f67c1ea26ac52a0c599064957ec6ac5cd0eee810d2e3cd5b4f4beb1016fbd5c5e8eb54c4d62836e1afe90c5ef922b31a288f41e0c442123dcfc417aa8fd7f languageName: node linkType: hard -"@react-navigation/core@npm:^6.4.16": - version: 6.4.16 - resolution: "@react-navigation/core@npm:6.4.16" +"@react-navigation/core@npm:^6.4.17": + version: 6.4.17 + resolution: "@react-navigation/core@npm:6.4.17" dependencies: "@react-navigation/routers": "npm:^6.1.9" escape-string-regexp: "npm:^4.0.0" nanoid: "npm:^3.1.23" query-string: "npm:^7.1.3" react-is: "npm:^16.13.0" - use-latest-callback: "npm:^0.1.9" + use-latest-callback: "npm:^0.2.1" peerDependencies: react: "*" - checksum: 10/1b58f1566c55412247f06c7a2c769ac588b595a75dc81945dc5b90d7b371fbcf982c16327adb956733467d0bbdc7a93fe3aedce0a8246dda653d07b239e727b0 + checksum: 10/481470361c7dd638d8af513ca559265829e8de5a2ff18c207d8d1c9e2d65606318061ffe369afbccfea3c6d027d38ad539ae5bae8863d9cedd8eaeafeb18426c languageName: node linkType: hard -"@react-navigation/elements@npm:^1.3.30": - version: 1.3.30 - resolution: "@react-navigation/elements@npm:1.3.30" +"@react-navigation/drawer@npm:^6.7.2": + version: 6.7.2 + resolution: "@react-navigation/drawer@npm:6.7.2" + dependencies: + "@react-navigation/elements": "npm:^1.3.31" + color: "npm:^4.2.3" + warn-once: "npm:^0.1.0" peerDependencies: "@react-navigation/native": ^6.0.0 react: "*" react-native: "*" + react-native-gesture-handler: ">= 1.0.0" + react-native-reanimated: ">= 1.0.0" react-native-safe-area-context: ">= 3.0.0" - checksum: 10/caf0321ed2a632aa63473e18d05020228bba81bb39a6e4076fdd17fec2597bcad8cb8d6d7483653ecb465d007e4733c683995ca59144ee908db9a21cb47b13da + react-native-screens: ">= 3.0.0" + checksum: 10/970da3f2f78458bbbf30aa2c1a2e071c22a63a4404e2f1f4f6c916b0e33c4faec0693da15a9b52d8f3e0c857008a20f57f310eddb8dd0c1958cfa1aa7fa710ae languageName: node linkType: hard -"@react-navigation/native-stack@npm:~6.9.12": - version: 6.9.26 - resolution: "@react-navigation/native-stack@npm:6.9.26" +"@react-navigation/elements@npm:^1.3.31": + version: 1.3.31 + resolution: "@react-navigation/elements@npm:1.3.31" + peerDependencies: + "@react-navigation/native": ^6.0.0 + react: "*" + react-native: "*" + react-native-safe-area-context: ">= 3.0.0" + checksum: 10/379b3657300f9ab8043979f1ecaea95dce96253903db8d6954468e39dc7cf0710cc08345fa6625071a1505b6442a395e0e20bde39c0b997fd90fea370275fc08 + languageName: node + linkType: hard + +"@react-navigation/native-stack@npm:^6.11.0": + version: 6.11.0 + resolution: "@react-navigation/native-stack@npm:6.11.0" dependencies: - "@react-navigation/elements": "npm:^1.3.30" + "@react-navigation/elements": "npm:^1.3.31" warn-once: "npm:^0.1.0" peerDependencies: "@react-navigation/native": ^6.0.0 @@ -6010,22 +6003,22 @@ __metadata: react-native: "*" react-native-safe-area-context: ">= 3.0.0" react-native-screens: ">= 3.0.0" - checksum: 10/75c7bb5647d065f45ab234b9d44f8562641225c02b2c354be9fba6a1b8b53f216e8dd0c3749492fdf598d08bd9569749a1d6ad93fa40f15e9f141b35b0809ef9 + checksum: 10/d27212088dde4ca16c78d8f85187d452d56cc9243506c049d2595b61c10eda44368ab01c53e729777d9900fe5c3a4dfeae2598b1a534508d6a1df8ab35c1a4dc languageName: node linkType: hard -"@react-navigation/native@npm:^6.1.17, @react-navigation/native@npm:~6.1.6": - version: 6.1.17 - resolution: "@react-navigation/native@npm:6.1.17" +"@react-navigation/native@npm:^6.1.18": + version: 6.1.18 + resolution: "@react-navigation/native@npm:6.1.18" dependencies: - "@react-navigation/core": "npm:^6.4.16" + "@react-navigation/core": "npm:^6.4.17" escape-string-regexp: "npm:^4.0.0" fast-deep-equal: "npm:^3.1.3" nanoid: "npm:^3.1.23" peerDependencies: react: "*" react-native: "*" - checksum: 10/f0b0ef565ddfd5a9bfa2448e0f0d2f18616144877acc6b2330b6b0966ed2c33702c445c553443651acc8488f8af840ffa5ee9353ddfd582e4b3ff26ecb85fbb5 + checksum: 10/1c16813e7d1d796519d0c3a9163de8be6d4af0afa74d9d88ec6729f8c0f533540250f09e39063f4a1eafb9ff71c3f3a9cc9d420ba75aa3eb7f42834f4ba0ee20 languageName: node linkType: hard @@ -6049,106 +6042,6 @@ __metadata: languageName: node linkType: hard -"@remix-run/node@npm:^2.7.2": - version: 2.10.2 - resolution: "@remix-run/node@npm:2.10.2" - dependencies: - "@remix-run/server-runtime": "npm:2.10.2" - "@remix-run/web-fetch": "npm:^4.4.2" - "@web3-storage/multipart-parser": "npm:^1.0.0" - cookie-signature: "npm:^1.1.0" - source-map-support: "npm:^0.5.21" - stream-slice: "npm:^0.1.2" - undici: "npm:^6.11.1" - peerDependencies: - typescript: ^5.1.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/8a092a6d7e0bfd9a2245882cf916a2097fbb3fa20848b30f038d435d0334f238bf39afc0684be4b48afe4f18d11ac6601d8e7bc54afa8057122444b896473425 - languageName: node - linkType: hard - -"@remix-run/router@npm:1.17.1": - version: 1.17.1 - resolution: "@remix-run/router@npm:1.17.1" - checksum: 10/5efc598626cd81688ac26e0abd08204b980831ead8cd2c4b8a27e0c169ee4777fc609fa289c093b93efc3a1e335304698c6961276c2309348444ec7209836c83 - languageName: node - linkType: hard - -"@remix-run/server-runtime@npm:2.10.2": - version: 2.10.2 - resolution: "@remix-run/server-runtime@npm:2.10.2" - dependencies: - "@remix-run/router": "npm:1.17.1" - "@types/cookie": "npm:^0.6.0" - "@web3-storage/multipart-parser": "npm:^1.0.0" - cookie: "npm:^0.6.0" - set-cookie-parser: "npm:^2.4.8" - source-map: "npm:^0.7.3" - turbo-stream: "npm:2.2.0" - peerDependencies: - typescript: ^5.1.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/a9906dd479f173676c7b72b7b019c8b13a67c38e80790ea4280b4748587e26d7ffaf1423b61c98888e88c087a139e8023e191ac0e21ae5e3165d990015ddc9ed - languageName: node - linkType: hard - -"@remix-run/web-blob@npm:^3.1.0": - version: 3.1.0 - resolution: "@remix-run/web-blob@npm:3.1.0" - dependencies: - "@remix-run/web-stream": "npm:^1.1.0" - web-encoding: "npm:1.1.5" - checksum: 10/24b95b90e2a5bfb17478c9e88a03c8de8db2cc6cbe744ee845cd8bfc278744f3d0a6f782f63b3361eef59488f544b60172fb98c628f113c936f597b303bc58f3 - languageName: node - linkType: hard - -"@remix-run/web-fetch@npm:^4.4.2": - version: 4.4.2 - resolution: "@remix-run/web-fetch@npm:4.4.2" - dependencies: - "@remix-run/web-blob": "npm:^3.1.0" - "@remix-run/web-file": "npm:^3.1.0" - "@remix-run/web-form-data": "npm:^3.1.0" - "@remix-run/web-stream": "npm:^1.1.0" - "@web3-storage/multipart-parser": "npm:^1.0.0" - abort-controller: "npm:^3.0.0" - data-uri-to-buffer: "npm:^3.0.1" - mrmime: "npm:^1.0.0" - checksum: 10/46961dae587d1d9eb1c678113cf8fcbe0e5779b3fdedd8b136c7065b47e967056d1508924992a58887b03ab406c44c838bca5d0f7d08a4bbaab9609178c3fe4b - languageName: node - linkType: hard - -"@remix-run/web-file@npm:^3.1.0": - version: 3.1.0 - resolution: "@remix-run/web-file@npm:3.1.0" - dependencies: - "@remix-run/web-blob": "npm:^3.1.0" - checksum: 10/c5ce184fc8e3a8d5736798c9fa784a3416890382be707da927926d173e67227dc60ae2494be680bf0074a00fac5a9a737387ce820349fb2fecdc31be034854a0 - languageName: node - linkType: hard - -"@remix-run/web-form-data@npm:^3.1.0": - version: 3.1.0 - resolution: "@remix-run/web-form-data@npm:3.1.0" - dependencies: - web-encoding: "npm:1.1.5" - checksum: 10/4eaa98da8f8827d2fd6e676920c6352679b35e0fd11f83d99f8a1ee009e8e51a0c710e8d228cd481ad00a81b3afe53a1db97321f3c6c16e14a3d67858e238a91 - languageName: node - linkType: hard - -"@remix-run/web-stream@npm:^1.1.0": - version: 1.1.0 - resolution: "@remix-run/web-stream@npm:1.1.0" - dependencies: - web-streams-polyfill: "npm:^3.1.1" - checksum: 10/9904b1539feee3a86d667e9803783dfc78e21b665a4e67edfd795bd1acee753fda88f50abbebf7cffa010539ed5287b4a0d09f55101b80f2c891c15db1066eea - languageName: node - linkType: hard - "@rnx-kit/chromium-edge-launcher@npm:^1.0.0": version: 1.0.0 resolution: "@rnx-kit/chromium-edge-launcher@npm:1.0.0" @@ -8877,13 +8770,6 @@ __metadata: languageName: node linkType: hard -"@types/cookie@npm:^0.6.0": - version: 0.6.0 - resolution: "@types/cookie@npm:0.6.0" - checksum: 10/b883348d5bf88695fbc2c2276b1c49859267a55cae3cf11ea1dccc1b3be15b466e637ce3242109ba27d616c77c6aa4efe521e3d557110b4fdd9bc332a12445c2 - languageName: node - linkType: hard - "@types/debug@npm:^4.1.7": version: 4.1.12 resolution: "@types/debug@npm:4.1.12" @@ -8950,6 +8836,13 @@ __metadata: languageName: node linkType: hard +"@types/hammerjs@npm:^2.0.36": + version: 2.0.46 + resolution: "@types/hammerjs@npm:2.0.46" + checksum: 10/1b6502d668f45ca49fb488c01f7938d3aa75e989d70c64801c8feded7d659ca1a118f745c1b604d220efe344c93231767d5cc68c05e00e069c14539b6143cfd9 + languageName: node + linkType: hard + "@types/html-minifier-terser@npm:^6.0.0": version: 6.1.0 resolution: "@types/html-minifier-terser@npm:6.1.0" @@ -9921,13 +9814,6 @@ __metadata: languageName: node linkType: hard -"@web3-storage/multipart-parser@npm:^1.0.0": - version: 1.0.0 - resolution: "@web3-storage/multipart-parser@npm:1.0.0" - checksum: 10/20d7a4330392d83f727586477fc6e709f8fca3b3664365b0d9d3041abe2aeb13f53030a3997a28a39cc74930863ebb625878b8c90789e5c990e4b64d9f22a93d - languageName: node - linkType: hard - "@webassemblyjs/ast@npm:1.12.1, @webassemblyjs/ast@npm:^1.12.1": version: 1.12.1 resolution: "@webassemblyjs/ast@npm:1.12.1" @@ -10135,13 +10021,6 @@ __metadata: languageName: node linkType: hard -"@zxing/text-encoding@npm:0.9.0": - version: 0.9.0 - resolution: "@zxing/text-encoding@npm:0.9.0" - checksum: 10/268e4ef64b8eaa32b990240bdfd1f7b3e2b501a6ed866a565f7c9747f04ac884fbe0537fe12bb05d9241b98fb111270c0fd0023ef0a02d23a6619b4589e98f6b - languageName: node - linkType: hard - "JSONStream@npm:^1.3.5": version: 1.3.5 resolution: "JSONStream@npm:1.3.5" @@ -10581,7 +10460,10 @@ __metadata: "@rainbow-me/rainbowkit": "npm:2" "@react-native-firebase/app": "npm:^20.3.0" "@react-native-firebase/messaging": "npm:^20.3.0" - "@react-navigation/native": "npm:^6.1.17" + "@react-navigation/bottom-tabs": "npm:^6.6.1" + "@react-navigation/drawer": "npm:^6.7.2" + "@react-navigation/native": "npm:^6.1.18" + "@react-navigation/native-stack": "npm:^6.11.0" "@tamagui/babel-plugin": "npm:^1.102.3" "@tamagui/config": "npm:^1.102.3" "@tamagui/lucide-icons": "npm:^1.102.3" @@ -10600,7 +10482,6 @@ __metadata: expo-font: "npm:~12.0.9" expo-linking: "npm:~6.3.1" expo-notifications: "npm:~0.28.10" - expo-router: "npm:~3.5.18" expo-splash-screen: "npm:~0.27.5" expo-status-bar: "npm:^1.12.1" expo-system-ui: "npm:~3.0.7" @@ -10611,10 +10492,11 @@ __metadata: react: "npm:18.3.1" react-dom: "npm:18.3.1" react-native: "npm:0.74.3" + react-native-gesture-handler: "npm:~2.16.1" react-native-markdown-display: "npm:^7.0.2" - react-native-reanimated: "npm:~3.14.0" - react-native-safe-area-context: "npm:4.10.8" - react-native-screens: "npm:~3.32.0" + react-native-reanimated: "npm:~3.10.1" + react-native-safe-area-context: "npm:4.10.5" + react-native-screens: "npm:3.31.1" react-native-svg: "npm:15.4.0" react-native-web: "npm:^0.19.12" react-native-webview: "npm:13.10.5" @@ -12493,14 +12375,7 @@ __metadata: languageName: node linkType: hard -"cookie-signature@npm:^1.1.0": - version: 1.2.1 - resolution: "cookie-signature@npm:1.2.1" - checksum: 10/b871138a81382173d51dde5c1c56e8b313bc4b9e5f2f67d0d63be50fd43b92a25cb9bd72c2fc2935c0c6cb6cce834e7e2fd12830d7ec289ccac5bdec19dd14eb - languageName: node - linkType: hard - -"cookie@npm:0.6.0, cookie@npm:^0.6.0": +"cookie@npm:0.6.0": version: 0.6.0 resolution: "cookie@npm:0.6.0" checksum: 10/c1f8f2ea7d443b9331680598b0ae4e6af18a618c37606d1bbdc75bec8361cce09fe93e727059a673f2ba24467131a9fb5a4eec76bb1b149c1b3e1ccb268dc583 @@ -12801,13 +12676,6 @@ __metadata: languageName: node linkType: hard -"data-uri-to-buffer@npm:^3.0.1": - version: 3.0.1 - resolution: "data-uri-to-buffer@npm:3.0.1" - checksum: 10/c59c3009686a78c071806b72f4810856ec28222f0f4e252aa495ec027ed9732298ceea99c50328cf59b151dd34cbc3ad6150bbb43e41fc56fa19f48c99e9fc30 - languageName: node - linkType: hard - "data-view-buffer@npm:^1.0.1": version: 1.0.1 resolution: "data-view-buffer@npm:1.0.1" @@ -14622,40 +14490,7 @@ __metadata: languageName: node linkType: hard -"expo-router@npm:~3.5.18": - version: 3.5.18 - resolution: "expo-router@npm:3.5.18" - dependencies: - "@expo/metro-runtime": "npm:3.2.1" - "@expo/server": "npm:^0.4.0" - "@radix-ui/react-slot": "npm:1.0.1" - "@react-navigation/bottom-tabs": "npm:~6.5.7" - "@react-navigation/native": "npm:~6.1.6" - "@react-navigation/native-stack": "npm:~6.9.12" - expo-splash-screen: "npm:0.27.5" - react-native-helmet-async: "npm:2.0.4" - schema-utils: "npm:^4.0.1" - peerDependencies: - "@react-navigation/drawer": ^6.5.8 - expo: "*" - expo-constants: "*" - expo-linking: "*" - expo-status-bar: "*" - react-native-reanimated: "*" - react-native-safe-area-context: "*" - react-native-screens: "*" - peerDependenciesMeta: - "@react-navigation/drawer": - optional: true - "@testing-library/jest-native": - optional: true - react-native-reanimated: - optional: true - checksum: 10/94aa615155ffb2efd706ae54c0c6398836b15e8a583762d132e0ab2286dccaacfd87331df00c458be1f0812af4e95559e5bae2787ead43048f856d93f44432c7 - languageName: node - linkType: hard - -"expo-splash-screen@npm:0.27.5, expo-splash-screen@npm:~0.27.5": +"expo-splash-screen@npm:~0.27.5": version: 0.27.5 resolution: "expo-splash-screen@npm:0.27.5" dependencies: @@ -16487,6 +16322,15 @@ __metadata: languageName: node linkType: hard +"hoist-non-react-statics@npm:^3.3.0": + version: 3.3.2 + resolution: "hoist-non-react-statics@npm:3.3.2" + dependencies: + react-is: "npm:^16.7.0" + checksum: 10/1acbe85f33e5a39f90c822ad4d28b24daeb60f71c545279431dc98c312cd28a54f8d64788e477fe21dc502b0e3cf58589ebe5c1ad22af27245370391c2d24ea6 + languageName: node + linkType: hard + "homedir-polyfill@npm:^1.0.1": version: 1.0.3 resolution: "homedir-polyfill@npm:1.0.3" @@ -20079,13 +19923,6 @@ __metadata: languageName: node linkType: hard -"mrmime@npm:^1.0.0": - version: 1.0.1 - resolution: "mrmime@npm:1.0.1" - checksum: 10/a157e833ffe76648ab2107319deeff024b80b136ec66c60fae9d339009a1bb72c57ec1feecfd6a905dfd3df29e2299e850bff84b69cad790cc9bd9ab075834d1 - languageName: node - linkType: hard - "ms@npm:2.0.0": version: 2.0.0 resolution: "ms@npm:2.0.0" @@ -22342,13 +22179,6 @@ __metadata: languageName: node linkType: hard -"react-fast-compare@npm:^3.2.2": - version: 3.2.2 - resolution: "react-fast-compare@npm:3.2.2" - checksum: 10/a6826180ba75cefba1c8d3ac539735f9b627ca05d3d307fe155487f5d0228d376dac6c9708d04a283a7b9f9aee599b637446635b79c8c8753d0b4eece56c125c - languageName: node - linkType: hard - "react-freeze@npm:^1.0.0, react-freeze@npm:^1.0.3": version: 1.0.4 resolution: "react-freeze@npm:1.0.4" @@ -22365,7 +22195,7 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^16.13.0, react-is@npm:^16.13.1": +"react-is@npm:^16.13.0, react-is@npm:^16.13.1, react-is@npm:^16.7.0": version: 16.13.1 resolution: "react-is@npm:16.13.1" checksum: 10/5aa564a1cde7d391ac980bedee21202fc90bdea3b399952117f54fb71a932af1e5902020144fb354b4690b2414a0c7aafe798eb617b76a3d441d956db7726fdf @@ -22411,16 +22241,19 @@ __metadata: languageName: node linkType: hard -"react-native-helmet-async@npm:2.0.4": - version: 2.0.4 - resolution: "react-native-helmet-async@npm:2.0.4" +"react-native-gesture-handler@npm:~2.16.1": + version: 2.16.2 + resolution: "react-native-gesture-handler@npm:2.16.2" dependencies: + "@egjs/hammerjs": "npm:^2.0.17" + hoist-non-react-statics: "npm:^3.3.0" invariant: "npm:^2.2.4" - react-fast-compare: "npm:^3.2.2" - shallowequal: "npm:^1.1.0" + lodash: "npm:^4.17.21" + prop-types: "npm:^15.7.2" peerDependencies: - react: ^16.6.0 || ^17.0.0 || ^18.0.0 - checksum: 10/217bd0eaa61d426a512634369c70c44ce8b92127ec626dc40c65b72b1be1534ed3ed00ba2dd1a9ad77d1716ce8fd1e6db3f7209534303a652d9932a962d2c830 + react: "*" + react-native: "*" + checksum: 10/227799f5e16f9725d81db524fc06c1fbef226835a5ee989642d132748832f7543ebc750d4309e49bcaa0fb6d1e7dd6b74028785e4b755978ab7f66f05b414c18 languageName: node linkType: hard @@ -22439,9 +22272,9 @@ __metadata: languageName: node linkType: hard -"react-native-reanimated@npm:~3.14.0": - version: 3.14.0 - resolution: "react-native-reanimated@npm:3.14.0" +"react-native-reanimated@npm:~3.10.1": + version: 3.10.1 + resolution: "react-native-reanimated@npm:3.10.1" dependencies: "@babel/plugin-transform-arrow-functions": "npm:^7.0.0-0" "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.0.0-0" @@ -22455,30 +22288,30 @@ __metadata: "@babel/core": ^7.0.0-0 react: "*" react-native: "*" - checksum: 10/b780949f52bb0d66521c973173d01776febbedffa4ee86309f31b2cf6b1cae2d0a0b7e6a177c2dbc5f6d92ba3912b6b8bde9b3b42dd39fc0ef792acbd909096b + checksum: 10/bb2a0802fd619999dd5d1dd9734875fc14699de29d3537003997e85040dd3a0b430716192388c71544d600fc7abf243af1cfc24ce2513c282b046e8bb3430125 languageName: node linkType: hard -"react-native-safe-area-context@npm:4.10.8": - version: 4.10.8 - resolution: "react-native-safe-area-context@npm:4.10.8" +"react-native-safe-area-context@npm:4.10.5": + version: 4.10.5 + resolution: "react-native-safe-area-context@npm:4.10.5" peerDependencies: react: "*" react-native: "*" - checksum: 10/3d8151b09ea6a6558e9ece7c3ef62904f6e19931e281ac4dbe900e3f63469bd834d6424c36d4e3a550de290cca5ac591e5f376de73f04a5a209edcb95abff0f9 + checksum: 10/0bc7b4cd442e7a5deb0470f3b915ec2cf6b54337ea527fc7f5bde4f4dd062d420cb2b40fb886df96853f01951cfcb69a35fb4f6f47561cef5e195d9d68c54c3c languageName: node linkType: hard -"react-native-screens@npm:~3.32.0": - version: 3.32.0 - resolution: "react-native-screens@npm:3.32.0" +"react-native-screens@npm:3.31.1": + version: 3.31.1 + resolution: "react-native-screens@npm:3.31.1" dependencies: react-freeze: "npm:^1.0.0" warn-once: "npm:^0.1.0" peerDependencies: react: "*" react-native: "*" - checksum: 10/22f27b2082e0c8d70165c8a26dcf55b4da2a18166d4b9a0b434f558edea57d71458800d5086940fe7cabe8b7e28c8614cf227f35152171d08583f4ef6f6f3a35 + checksum: 10/54a44fc5a34848195a8e004b9ee2269e8a3560c5fa7922d80eaa1fc6283990d6ef77b3d3ec6004d7df2ad95279d486faf25bb68a82a0e958493891adb7dbac9c languageName: node linkType: hard @@ -23471,7 +23304,7 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^4.0.0, schema-utils@npm:^4.0.1": +"schema-utils@npm:^4.0.0": version: 4.2.0 resolution: "schema-utils@npm:4.2.0" dependencies: @@ -23668,13 +23501,6 @@ __metadata: languageName: node linkType: hard -"set-cookie-parser@npm:^2.4.8": - version: 2.6.0 - resolution: "set-cookie-parser@npm:2.6.0" - checksum: 10/8d451ebadb760989f93b634942c79de3c925ca7a986d133d08a80c40b5ae713ce12e354f0d5245c49f288c52daa7bd6554d5dc52f8a4eecaaf5e192881cf2b1f - languageName: node - linkType: hard - "set-function-length@npm:^1.2.1": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" @@ -23771,13 +23597,6 @@ __metadata: languageName: node linkType: hard -"shallowequal@npm:^1.1.0": - version: 1.1.0 - resolution: "shallowequal@npm:1.1.0" - checksum: 10/f4c1de0837f106d2dbbfd5d0720a5d059d1c66b42b580965c8f06bb1db684be8783538b684092648c981294bf817869f743a066538771dbecb293df78f765e00 - languageName: node - linkType: hard - "shebang-command@npm:^1.2.0": version: 1.2.0 resolution: "shebang-command@npm:1.2.0" @@ -24296,13 +24115,6 @@ __metadata: languageName: node linkType: hard -"stream-slice@npm:^0.1.2": - version: 0.1.2 - resolution: "stream-slice@npm:0.1.2" - checksum: 10/6fa948ea58523f11f72e796f99579ff2bbecdff080d63b25762b0c0d282ac9a2d98af0f6e84dcc8d24c6284b2f7ce92ce0f9a1c8f77c91ac273954754e53c781 - languageName: node - linkType: hard - "strict-uri-encode@npm:^2.0.0": version: 2.0.0 resolution: "strict-uri-encode@npm:2.0.0" @@ -25226,13 +25038,6 @@ __metadata: languageName: node linkType: hard -"turbo-stream@npm:2.2.0": - version: 2.2.0 - resolution: "turbo-stream@npm:2.2.0" - checksum: 10/1a61be95585d6c901c7f626497765e28c38332f6562f4206e8a295dca87297d044f2413f369764365a6cbb13aae3c21fee2aace4525ff32c1e787e418916914e - languageName: node - linkType: hard - "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -25535,13 +25340,6 @@ __metadata: languageName: node linkType: hard -"undici@npm:^6.11.1": - version: 6.19.2 - resolution: "undici@npm:6.19.2" - checksum: 10/f4895c0c1e2fcde18076ac98965c231875811b8e14ceab1a7b19e940ed1a2fce69e0864e1186bfdc9347dffe0f39a00daf6dd5e7c0169b2b33de59a859dc2f1d - languageName: node - linkType: hard - "unenv@npm:^1.9.0": version: 1.10.0 resolution: "unenv@npm:1.10.0" @@ -25831,12 +25629,12 @@ __metadata: languageName: node linkType: hard -"use-latest-callback@npm:^0.1.9": - version: 0.1.11 - resolution: "use-latest-callback@npm:0.1.11" +"use-latest-callback@npm:^0.2.1": + version: 0.2.1 + resolution: "use-latest-callback@npm:0.2.1" peerDependencies: react: ">=16.8" - checksum: 10/cc6df404a4ed3a39d0eb014a815c2e568a6abbe8c5ff09f9205a08bf68e86201826ed633865a6056ca0fd9581e0e7e70f18ca26c592a9eaccea5d244cf283b1f + checksum: 10/da5718eda625738cc7dac8fb502d0f8f2039435eb71203565a72c32e0f5769e7b8ddac074e650066636e7f4b29b45524f751cb18a2b430856d98879bbb10d274 languageName: node linkType: hard @@ -25892,7 +25690,7 @@ __metadata: languageName: node linkType: hard -"util@npm:^0.12.3, util@npm:^0.12.4, util@npm:^0.12.5": +"util@npm:^0.12.4, util@npm:^0.12.5": version: 0.12.5 resolution: "util@npm:0.12.5" dependencies: @@ -26126,26 +25924,6 @@ __metadata: languageName: node linkType: hard -"web-encoding@npm:1.1.5": - version: 1.1.5 - resolution: "web-encoding@npm:1.1.5" - dependencies: - "@zxing/text-encoding": "npm:0.9.0" - util: "npm:^0.12.3" - dependenciesMeta: - "@zxing/text-encoding": - optional: true - checksum: 10/243518cfa8388ac05eeb4041bd330d38c599476ff9a93239b386d1ba2af130089a2fcefb0cf65b385f989105ff460ae69dca7e42236f4d98dc776b04e558cdb5 - languageName: node - linkType: hard - -"web-streams-polyfill@npm:^3.1.1": - version: 3.3.3 - resolution: "web-streams-polyfill@npm:3.3.3" - checksum: 10/8e7e13501b3834094a50abe7c0b6456155a55d7571312b89570012ef47ec2a46d766934768c50aabad10a9c30dd764a407623e8bfcc74fcb58495c29130edea9 - languageName: node - linkType: hard - "webauthn-p256@npm:0.0.5": version: 0.0.5 resolution: "webauthn-p256@npm:0.0.5" -- 2.51.2