about summary refs log tree commit diff
path: root/src/view/com/util/post-embeds/VideoEmbed.tsx
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2024-08-10 00:49:11 +0100
committerGitHub <noreply@github.com>2024-08-10 00:49:11 +0100
commitc2131bb0392487f11b0c31fe68fdd3e847d62142 (patch)
tree65e926fb03c4921338343e6205a5270c3e674d13 /src/view/com/util/post-embeds/VideoEmbed.tsx
parentab0da7c892ce7532840417b89a42302ab9db7018 (diff)
downloadvoidsky-c2131bb0392487f11b0c31fe68fdd3e847d62142.tar.zst
[Videos] Add error boundary to native (#4914)
* move error fallback to own component

* use error boundary on native

---------

Co-authored-by: Samuel Newman <10959775+mozzius@users.noreply.github.com>
Diffstat (limited to 'src/view/com/util/post-embeds/VideoEmbed.tsx')
-rw-r--r--src/view/com/util/post-embeds/VideoEmbed.tsx71
1 files changed, 48 insertions, 23 deletions
diff --git a/src/view/com/util/post-embeds/VideoEmbed.tsx b/src/view/com/util/post-embeds/VideoEmbed.tsx
index 887efac1a..4e2909f40 100644
--- a/src/view/com/util/post-embeds/VideoEmbed.tsx
+++ b/src/view/com/util/post-embeds/VideoEmbed.tsx
@@ -1,6 +1,6 @@
-import React from 'react'
+import React, {useCallback, useState} from 'react'
 import {View} from 'react-native'
-import {msg} from '@lingui/macro'
+import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 
 import {VideoEmbedInnerNative} from 'view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerNative'
@@ -8,13 +8,23 @@ import {atoms as a, useTheme} from '#/alf'
 import {Button, ButtonIcon} from '#/components/Button'
 import {Play_Filled_Corner2_Rounded as PlayIcon} from '#/components/icons/Play'
 import {VisibilityView} from '../../../../../modules/expo-bluesky-swiss-army'
+import {ErrorBoundary} from '../ErrorBoundary'
 import {useActiveVideoView} from './ActiveVideoContext'
+import * as VideoFallback from './VideoEmbedInner/VideoFallback'
 
 export function VideoEmbed({source}: {source: string}) {
   const t = useTheme()
   const {active, setActive} = useActiveVideoView({source})
   const {_} = useLingui()
 
+  const [key, setKey] = useState(0)
+  const renderError = useCallback(
+    (error: unknown) => (
+      <VideoError error={error} retry={() => setKey(key + 1)} />
+    ),
+    [key],
+  )
+
   return (
     <View
       style={[
@@ -25,27 +35,42 @@ export function VideoEmbed({source}: {source: string}) {
         t.atoms.bg_contrast_25,
         a.my_xs,
       ]}>
-      <VisibilityView
-        enabled={true}
-        onChangeStatus={isActive => {
-          if (isActive) {
-            setActive()
-          }
-        }}>
-        {active ? (
-          <VideoEmbedInnerNative />
-        ) : (
-          <Button
-            style={[a.flex_1, t.atoms.bg_contrast_25]}
-            onPress={setActive}
-            label={_(msg`Play video`)}
-            variant="ghost"
-            color="secondary"
-            size="large">
-            <ButtonIcon icon={PlayIcon} />
-          </Button>
-        )}
-      </VisibilityView>
+      <ErrorBoundary renderError={renderError} key={key}>
+        <VisibilityView
+          enabled={true}
+          onChangeStatus={isActive => {
+            if (isActive) {
+              setActive()
+            }
+          }}>
+          {active ? (
+            <VideoEmbedInnerNative />
+          ) : (
+            <Button
+              style={[a.flex_1, t.atoms.bg_contrast_25]}
+              onPress={setActive}
+              label={_(msg`Play video`)}
+              variant="ghost"
+              color="secondary"
+              size="large">
+              <ButtonIcon icon={PlayIcon} />
+            </Button>
+          )}
+        </VisibilityView>
+      </ErrorBoundary>
     </View>
   )
 }
+
+function VideoError({retry}: {error: unknown; retry: () => void}) {
+  return (
+    <VideoFallback.Container>
+      <VideoFallback.Text>
+        <Trans>
+          An error occurred while loading the video. Please try again later.
+        </Trans>
+      </VideoFallback.Text>
+      <VideoFallback.RetryButton onPress={retry} />
+    </VideoFallback.Container>
+  )
+}