about summary refs log tree commit diff
path: root/src/components/StarterPack/ShareDialog.tsx
diff options
context:
space:
mode:
authorHailey <me@haileyok.com>2024-06-21 21:38:04 -0700
committerGitHub <noreply@github.com>2024-06-21 21:38:04 -0700
commitf089f4578131e83cd177b7809ce0f7b75779dfdc (patch)
tree51978aede2040fb8dc319f0749d3de77c7811fbe /src/components/StarterPack/ShareDialog.tsx
parent35f64535cb8dfa0fe46e740a6398f3b991ecfbc7 (diff)
downloadvoidsky-f089f4578131e83cd177b7809ce0f7b75779dfdc.tar.zst
Starter Packs (#4332)
Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
Co-authored-by: Paul Frazee <pfrazee@gmail.com>
Co-authored-by: Eric Bailey <git@esb.lol>
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Diffstat (limited to 'src/components/StarterPack/ShareDialog.tsx')
-rw-r--r--src/components/StarterPack/ShareDialog.tsx180
1 files changed, 180 insertions, 0 deletions
diff --git a/src/components/StarterPack/ShareDialog.tsx b/src/components/StarterPack/ShareDialog.tsx
new file mode 100644
index 000000000..23fa10fb3
--- /dev/null
+++ b/src/components/StarterPack/ShareDialog.tsx
@@ -0,0 +1,180 @@
+import React from 'react'
+import {View} from 'react-native'
+import * as FS from 'expo-file-system'
+import {Image} from 'expo-image'
+import {requestMediaLibraryPermissionsAsync} from 'expo-image-picker'
+import {AppBskyGraphDefs} from '@atproto/api'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+import {nanoid} from 'nanoid/non-secure'
+
+import {logger} from '#/logger'
+import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
+import {saveImageToMediaLibrary} from 'lib/media/manip'
+import {shareUrl} from 'lib/sharing'
+import {logEvent} from 'lib/statsig/statsig'
+import {getStarterPackOgCard} from 'lib/strings/starter-pack'
+import {isNative, isWeb} from 'platform/detection'
+import * as Toast from 'view/com/util/Toast'
+import {atoms as a, useTheme} from '#/alf'
+import {Button, ButtonText} from '#/components/Button'
+import {DialogControlProps} from '#/components/Dialog'
+import * as Dialog from '#/components/Dialog'
+import {Loader} from '#/components/Loader'
+import {Text} from '#/components/Typography'
+
+interface Props {
+  starterPack: AppBskyGraphDefs.StarterPackView
+  link?: string
+  imageLoaded?: boolean
+  qrDialogControl: DialogControlProps
+  control: DialogControlProps
+}
+
+export function ShareDialog(props: Props) {
+  return (
+    <Dialog.Outer control={props.control}>
+      <ShareDialogInner {...props} />
+    </Dialog.Outer>
+  )
+}
+
+function ShareDialogInner({
+  starterPack,
+  link,
+  imageLoaded,
+  qrDialogControl,
+  control,
+}: Props) {
+  const {_} = useLingui()
+  const t = useTheme()
+  const {isTabletOrDesktop} = useWebMediaQueries()
+
+  const imageUrl = getStarterPackOgCard(starterPack)
+
+  const onShareLink = async () => {
+    if (!link) return
+    shareUrl(link)
+    logEvent('starterPack:share', {
+      starterPack: starterPack.uri,
+      shareType: 'link',
+    })
+    control.close()
+  }
+
+  const onSave = async () => {
+    const res = await requestMediaLibraryPermissionsAsync()
+
+    if (!res) {
+      Toast.show(
+        _(msg`You must grant access to your photo library to save the image.`),
+      )
+      return
+    }
+
+    const cachePath = await Image.getCachePathAsync(imageUrl)
+    const filename = `${FS.documentDirectory}/${nanoid(12)}.png`
+
+    if (!cachePath) {
+      Toast.show(_(msg`An error occurred while saving the image.`))
+      return
+    }
+
+    try {
+      await FS.copyAsync({from: cachePath, to: filename})
+      await saveImageToMediaLibrary({uri: filename})
+      await FS.deleteAsync(filename)
+
+      Toast.show(_(msg`Image saved to your camera roll!`))
+      control.close()
+    } catch (e: unknown) {
+      Toast.show(_(msg`An error occurred while saving the QR code!`))
+      logger.error('Failed to save QR code', {error: e})
+      return
+    }
+  }
+
+  return (
+    <>
+      <Dialog.Handle />
+      <Dialog.ScrollableInner label={_(msg`Share link dialog`)}>
+        {!imageLoaded || !link ? (
+          <View style={[a.p_xl, a.align_center]}>
+            <Loader size="xl" />
+          </View>
+        ) : (
+          <View style={[!isTabletOrDesktop && a.gap_lg]}>
+            <View style={[a.gap_sm, isTabletOrDesktop && a.pb_lg]}>
+              <Text style={[a.font_bold, a.text_2xl]}>
+                <Trans>Invite people to this starter pack!</Trans>
+              </Text>
+              <Text style={[a.text_md, t.atoms.text_contrast_medium]}>
+                <Trans>
+                  Share this starter pack and help people join your community on
+                  Bluesky.
+                </Trans>
+              </Text>
+            </View>
+            <Image
+              source={{uri: imageUrl}}
+              style={[
+                a.rounded_sm,
+                {
+                  aspectRatio: 1200 / 630,
+                  transform: [{scale: isTabletOrDesktop ? 0.85 : 1}],
+                  marginTop: isTabletOrDesktop ? -20 : 0,
+                },
+              ]}
+              accessibilityIgnoresInvertColors={true}
+            />
+            <View
+              style={[
+                a.gap_md,
+                isWeb && [a.gap_sm, a.flex_row_reverse, {marginLeft: 'auto'}],
+              ]}>
+              <Button
+                label="Share link"
+                variant="solid"
+                color="secondary"
+                size="small"
+                style={[isWeb && a.self_center]}
+                onPress={onShareLink}>
+                <ButtonText>
+                  {isWeb ? <Trans>Copy Link</Trans> : <Trans>Share Link</Trans>}
+                </ButtonText>
+              </Button>
+              <Button
+                label="Create QR code"
+                variant="solid"
+                color="secondary"
+                size="small"
+                style={[isWeb && a.self_center]}
+                onPress={() => {
+                  control.close(() => {
+                    qrDialogControl.open()
+                  })
+                }}>
+                <ButtonText>
+                  <Trans>Create QR code</Trans>
+                </ButtonText>
+              </Button>
+              {isNative && (
+                <Button
+                  label={_(msg`Save image`)}
+                  variant="ghost"
+                  color="secondary"
+                  size="small"
+                  style={[isWeb && a.self_center]}
+                  onPress={onSave}>
+                  <ButtonText>
+                    <Trans>Save image</Trans>
+                  </ButtonText>
+                </Button>
+              )}
+            </View>
+          </View>
+        )}
+      </Dialog.ScrollableInner>
+    </>
+  )
+}