about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2024-04-22 22:07:48 +0100
committerGitHub <noreply@github.com>2024-04-22 22:07:48 +0100
commitf4e72cc83c431285dee454b6201377871dbed09a (patch)
tree33a0aba2bab717c1380c96e4b7295c6e005a1c6e /src
parent27c4054fcb885d8e00a466b4bd416edfe6eca32c (diff)
downloadvoidsky-f4e72cc83c431285dee454b6201377871dbed09a.tar.zst
[GIFs] Add error boundary to GIF picker (#3643)
* error boundary on gif picker

* add dialog.close for web users

* fix size of dialog on web

* Safer coercion

---------

Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/components/dialogs/GifSelect.tsx37
-rw-r--r--src/view/com/util/ErrorBoundary.tsx12
2 files changed, 45 insertions, 4 deletions
diff --git a/src/components/dialogs/GifSelect.tsx b/src/components/dialogs/GifSelect.tsx
index baff31168..ad4fbeade 100644
--- a/src/components/dialogs/GifSelect.tsx
+++ b/src/components/dialogs/GifSelect.tsx
@@ -13,6 +13,8 @@ import {
   useSetExternalEmbedPref,
 } from '#/state/preferences'
 import {Gif, useGifphySearch, useGiphyTrending} from '#/state/queries/giphy'
+import {ErrorScreen} from '#/view/com/util/error/ErrorScreen'
+import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
 import {atoms as a, useBreakpoints, useTheme} from '#/alf'
 import * as Dialog from '#/components/Dialog'
 import * as TextField from '#/components/forms/TextField'
@@ -54,13 +56,18 @@ export function GifSelectDialog({
       break
   }
 
+  const renderErrorBoundary = useCallback(
+    (error: any) => <DialogError details={String(error)} />,
+    [],
+  )
+
   return (
     <Dialog.Outer
       control={control}
       nativeOptions={{sheet: {snapPoints}}}
       onClose={onClose}>
       <Dialog.Handle />
-      {content}
+      <ErrorBoundary renderError={renderErrorBoundary}>{content}</ErrorBoundary>
     </Dialog.Outer>
   )
 }
@@ -357,3 +364,31 @@ function GiphyConsentPrompt({control}: {control: Dialog.DialogControlProps}) {
     </Dialog.ScrollableInner>
   )
 }
+
+function DialogError({details}: {details?: string}) {
+  const {_} = useLingui()
+  const control = Dialog.useDialogContext()
+
+  return (
+    <Dialog.ScrollableInner style={a.gap_md} label={_(msg`An error occured`)}>
+      <Dialog.Close />
+      <ErrorScreen
+        title={_(msg`Oh no!`)}
+        message={_(
+          msg`There was an unexpected issue in the application. Please let us know if this happened to you!`,
+        )}
+        details={details}
+      />
+      <Button
+        label={_(msg`Close dialog`)}
+        onPress={() => control.close()}
+        color="primary"
+        size="medium"
+        variant="solid">
+        <ButtonText>
+          <Trans>Close</Trans>
+        </ButtonText>
+      </Button>
+    </Dialog.ScrollableInner>
+  )
+}
diff --git a/src/view/com/util/ErrorBoundary.tsx b/src/view/com/util/ErrorBoundary.tsx
index 22fdd606e..dccd2bbc9 100644
--- a/src/view/com/util/ErrorBoundary.tsx
+++ b/src/view/com/util/ErrorBoundary.tsx
@@ -1,12 +1,14 @@
 import React, {Component, ErrorInfo, ReactNode} from 'react'
-import {ErrorScreen} from './error/ErrorScreen'
-import {CenteredView} from './Views'
 import {msg} from '@lingui/macro'
-import {logger} from '#/logger'
 import {useLingui} from '@lingui/react'
 
+import {logger} from '#/logger'
+import {ErrorScreen} from './error/ErrorScreen'
+import {CenteredView} from './Views'
+
 interface Props {
   children?: ReactNode
+  renderError?: (error: any) => ReactNode
 }
 
 interface State {
@@ -30,6 +32,10 @@ export class ErrorBoundary extends Component<Props, State> {
 
   public render() {
     if (this.state.hasError) {
+      if (this.props.renderError) {
+        return this.props.renderError(this.state.error)
+      }
+
       return (
         <CenteredView style={{height: '100%', flex: 1}}>
           <TranslatedErrorScreen details={this.state.error.toString()} />