* add dep * add some basic styling to QR codes, save to camera roll * use correct text component * rm unnecessary wrapper
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 9.9 KiB |
@@ -177,6 +177,7 @@
|
|||||||
"react-native-pager-view": "6.2.3",
|
"react-native-pager-view": "6.2.3",
|
||||||
"react-native-picker-select": "^9.1.3",
|
"react-native-picker-select": "^9.1.3",
|
||||||
"react-native-progress": "bluesky-social/react-native-progress",
|
"react-native-progress": "bluesky-social/react-native-progress",
|
||||||
|
"react-native-qrcode-styled": "^0.3.1",
|
||||||
"react-native-reanimated": "^3.11.0",
|
"react-native-reanimated": "^3.11.0",
|
||||||
"react-native-root-siblings": "^4.1.1",
|
"react-native-root-siblings": "^4.1.1",
|
||||||
"react-native-safe-area-context": "4.10.1",
|
"react-native-safe-area-context": "4.10.1",
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import {View} from 'react-native'
|
||||||
|
import QRCode from 'react-native-qrcode-styled'
|
||||||
|
import * as FS from 'expo-file-system'
|
||||||
|
import {msg, Trans} from '@lingui/macro'
|
||||||
|
import {useLingui} from '@lingui/react'
|
||||||
|
import {nanoid} from 'nanoid/non-secure'
|
||||||
|
|
||||||
|
import {saveImageToMediaLibrary} from 'lib/media/manip'
|
||||||
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
|
import {useTheme} from '#/alf'
|
||||||
|
import {atoms as a} from '#/alf'
|
||||||
|
import {Button, ButtonText} from '#/components/Button'
|
||||||
|
import * as Dialog from '#/components/Dialog'
|
||||||
|
import {DialogControlProps} from '#/components/Dialog'
|
||||||
|
import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
|
export function QrCodeDialog({
|
||||||
|
control,
|
||||||
|
url,
|
||||||
|
}: {
|
||||||
|
control: DialogControlProps
|
||||||
|
url: string
|
||||||
|
}) {
|
||||||
|
const {_} = useLingui()
|
||||||
|
const t = useTheme()
|
||||||
|
|
||||||
|
// No types for this
|
||||||
|
// See https://github.com/tokkozhin/react-native-qrcode-styled/blob/main/example/src/examples/DownloadQR.tsx for usage
|
||||||
|
const qrCodeRef = React.useRef<any>()
|
||||||
|
|
||||||
|
const onSavePress = () => {
|
||||||
|
qrCodeRef.current?.toDataURL(async (base64Code: string) => {
|
||||||
|
const filename = `${FS.cacheDirectory}/${nanoid(12)}.png`
|
||||||
|
await FS.writeAsStringAsync(filename, base64Code, {
|
||||||
|
encoding: FS.EncodingType.Base64,
|
||||||
|
})
|
||||||
|
|
||||||
|
await saveImageToMediaLibrary({uri: filename})
|
||||||
|
Toast.show(_(msg`QR code saved to your camera roll!`))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog.Outer control={control}>
|
||||||
|
<Dialog.Handle />
|
||||||
|
<Dialog.ScrollableInner
|
||||||
|
label={_(msg`Create a QR code for a starter pack`)}>
|
||||||
|
<View style={[a.flex_1, a.align_center, a.gap_3xl]}>
|
||||||
|
<Text style={[a.font_bold, a.text_xl, a.text_center]}>
|
||||||
|
Share this starter pack with friends!
|
||||||
|
</Text>
|
||||||
|
<View style={[t.atoms.bg_contrast_25, a.rounded_md]}>
|
||||||
|
<QRCode
|
||||||
|
data={url}
|
||||||
|
style={[{height: 200, width: 200}]}
|
||||||
|
pieceSize={8}
|
||||||
|
padding={20}
|
||||||
|
// pieceLiquidRadius={2}
|
||||||
|
pieceBorderRadius={4.5}
|
||||||
|
outerEyesOptions={{
|
||||||
|
topLeft: {
|
||||||
|
borderRadius: [12, 12, 0, 12],
|
||||||
|
color: t.palette.primary_500,
|
||||||
|
},
|
||||||
|
topRight: {
|
||||||
|
borderRadius: [12, 12, 12, 0],
|
||||||
|
color: t.palette.primary_500,
|
||||||
|
},
|
||||||
|
bottomLeft: {
|
||||||
|
borderRadius: [12, 0, 12, 12],
|
||||||
|
color: t.palette.primary_500,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
innerEyesOptions={{borderRadius: 3}}
|
||||||
|
logo={{
|
||||||
|
href: require('../../../assets/logo.png'),
|
||||||
|
scale: 1.2,
|
||||||
|
padding: 2,
|
||||||
|
hidePieces: true,
|
||||||
|
}}
|
||||||
|
ref={qrCodeRef}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Button
|
||||||
|
label={_(msg`Save QR code`)}
|
||||||
|
variant="solid"
|
||||||
|
color="primary"
|
||||||
|
size="medium"
|
||||||
|
onPress={onSavePress}>
|
||||||
|
<ButtonText>
|
||||||
|
<Trans>Save QR code</Trans>
|
||||||
|
</ButtonText>
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
</Dialog.ScrollableInner>
|
||||||
|
</Dialog.Outer>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,22 +1,25 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {Text, View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||||
|
|
||||||
import {CommonNavigatorParams} from 'lib/routes/types'
|
import {CommonNavigatorParams} from 'lib/routes/types'
|
||||||
|
import {shareUrl} from 'lib/sharing'
|
||||||
import {isWeb} from 'platform/detection'
|
import {isWeb} from 'platform/detection'
|
||||||
import {PagerWithHeader} from 'view/com/pager/PagerWithHeader'
|
import {PagerWithHeader} from 'view/com/pager/PagerWithHeader'
|
||||||
import {ProfileSubpageHeader} from 'view/com/profile/ProfileSubpageHeader'
|
import {ProfileSubpageHeader} from 'view/com/profile/ProfileSubpageHeader'
|
||||||
import {EventStopper} from 'view/com/util/EventStopper'
|
|
||||||
import {CenteredView} from 'view/com/util/Views'
|
import {CenteredView} from 'view/com/util/Views'
|
||||||
import {FeedsList} from '#/screens/StarterPack/Main/FeedsList'
|
import {FeedsList} from '#/screens/StarterPack/Main/FeedsList'
|
||||||
import {ProfilesList} from '#/screens/StarterPack/Main/ProfilesList'
|
import {ProfilesList} from '#/screens/StarterPack/Main/ProfilesList'
|
||||||
import {atoms as a} from '#/alf'
|
import {atoms as a} from '#/alf'
|
||||||
import {Button, ButtonText} from '#/components/Button'
|
import {Button, ButtonText} from '#/components/Button'
|
||||||
|
import {useDialogControl} from '#/components/Dialog'
|
||||||
import {ArrowOutOfBox_Stroke2_Corner0_Rounded as ArrowOutOfBox} from '#/components/icons/ArrowOutOfBox'
|
import {ArrowOutOfBox_Stroke2_Corner0_Rounded as ArrowOutOfBox} from '#/components/icons/ArrowOutOfBox'
|
||||||
import {QrCode_Stroke2_Corner0_Rounded as QrCode} from '#/components/icons/QrCode'
|
import {QrCode_Stroke2_Corner0_Rounded as QrCode} from '#/components/icons/QrCode'
|
||||||
import * as Menu from '#/components/Menu'
|
import * as Menu from '#/components/Menu'
|
||||||
|
import {QrCodeDialog} from '#/components/StarterPack/QrCodeDialog'
|
||||||
|
import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TEMPORARY CONTENT, DO NOT TRANSLATE
|
* TEMPORARY CONTENT, DO NOT TRANSLATE
|
||||||
@@ -140,6 +143,7 @@ function StarterPackScreenInner() {
|
|||||||
|
|
||||||
function Header({isOwn}: {isOwn: boolean}) {
|
function Header({isOwn}: {isOwn: boolean}) {
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
|
const qrCodeDialogControl = useDialogControl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -152,7 +156,6 @@ function Header({isOwn}: {isOwn: boolean}) {
|
|||||||
creator={undefined}
|
creator={undefined}
|
||||||
avatarType="starter-pack">
|
avatarType="starter-pack">
|
||||||
<View style={[a.flex_row, a.gap_sm]}>
|
<View style={[a.flex_row, a.gap_sm]}>
|
||||||
<EventStopper onKeyDown={false}>
|
|
||||||
<Menu.Root>
|
<Menu.Root>
|
||||||
<Menu.Trigger label={_(msg`Repost or quote post`)}>
|
<Menu.Trigger label={_(msg`Repost or quote post`)}>
|
||||||
{({props}) => {
|
{({props}) => {
|
||||||
@@ -175,7 +178,9 @@ function Header({isOwn}: {isOwn: boolean}) {
|
|||||||
<Menu.Item
|
<Menu.Item
|
||||||
label={_(msg`Share link`)}
|
label={_(msg`Share link`)}
|
||||||
testID="shareStarterPackLinkBtn"
|
testID="shareStarterPackLinkBtn"
|
||||||
onPress={() => {}}>
|
onPress={() => {
|
||||||
|
shareUrl('https://bsky.app')
|
||||||
|
}}>
|
||||||
<Menu.ItemText>
|
<Menu.ItemText>
|
||||||
<Trans>Share link</Trans>
|
<Trans>Share link</Trans>
|
||||||
</Menu.ItemText>
|
</Menu.ItemText>
|
||||||
@@ -184,7 +189,7 @@ function Header({isOwn}: {isOwn: boolean}) {
|
|||||||
<Menu.Item
|
<Menu.Item
|
||||||
label={_(msg`Create QR code`)}
|
label={_(msg`Create QR code`)}
|
||||||
testID="createQRCodeBtn"
|
testID="createQRCodeBtn"
|
||||||
onPress={() => {}}>
|
onPress={qrCodeDialogControl.open}>
|
||||||
<Menu.ItemText>
|
<Menu.ItemText>
|
||||||
<Trans>Create QR code</Trans>
|
<Trans>Create QR code</Trans>
|
||||||
</Menu.ItemText>
|
</Menu.ItemText>
|
||||||
@@ -193,7 +198,6 @@ function Header({isOwn}: {isOwn: boolean}) {
|
|||||||
</Menu.Group>
|
</Menu.Group>
|
||||||
</Menu.Outer>
|
</Menu.Outer>
|
||||||
</Menu.Root>
|
</Menu.Root>
|
||||||
</EventStopper>
|
|
||||||
{isOwn && (
|
{isOwn && (
|
||||||
<Button
|
<Button
|
||||||
label={_(msg`Edit`)}
|
label={_(msg`Edit`)}
|
||||||
@@ -214,6 +218,8 @@ function Header({isOwn}: {isOwn: boolean}) {
|
|||||||
started with the science community on Bluesky!
|
started with the science community on Bluesky!
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
<QrCodeDialog control={qrCodeDialogControl} url="https://bsky.app" />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11021,6 +11021,11 @@ diff@^4.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
||||||
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
||||||
|
|
||||||
|
dijkstrajs@^1.0.1:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz#4c8dbdea1f0f6478bff94d9c49c784d623e4fc23"
|
||||||
|
integrity sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==
|
||||||
|
|
||||||
dir-glob@^3.0.1:
|
dir-glob@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
|
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
|
||||||
@@ -11286,6 +11291,11 @@ emojis-list@^3.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
|
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
|
||||||
integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
|
integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
|
||||||
|
|
||||||
|
encode-utf8@^1.0.3:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda"
|
||||||
|
integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==
|
||||||
|
|
||||||
encodeurl@~1.0.2:
|
encodeurl@~1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||||
@@ -17676,6 +17686,11 @@ pngjs@^3.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
|
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
|
||||||
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
|
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
|
||||||
|
|
||||||
|
pngjs@^5.0.0:
|
||||||
|
version "5.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb"
|
||||||
|
integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==
|
||||||
|
|
||||||
pofile@^1.1.4:
|
pofile@^1.1.4:
|
||||||
version "1.1.4"
|
version "1.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.1.4.tgz#eab7e29f5017589b2a61b2259dff608c0cad76a2"
|
resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.1.4.tgz#eab7e29f5017589b2a61b2259dff608c0cad76a2"
|
||||||
@@ -18632,6 +18647,16 @@ qrcode-terminal@0.11.0:
|
|||||||
resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz#ffc6c28a2fc0bfb47052b47e23f4f446a5fbdb9e"
|
resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz#ffc6c28a2fc0bfb47052b47e23f4f446a5fbdb9e"
|
||||||
integrity sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==
|
integrity sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==
|
||||||
|
|
||||||
|
qrcode@^1.5.1:
|
||||||
|
version "1.5.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.5.3.tgz#03afa80912c0dccf12bc93f615a535aad1066170"
|
||||||
|
integrity sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==
|
||||||
|
dependencies:
|
||||||
|
dijkstrajs "^1.0.1"
|
||||||
|
encode-utf8 "^1.0.3"
|
||||||
|
pngjs "^5.0.0"
|
||||||
|
yargs "^15.3.1"
|
||||||
|
|
||||||
qs@6.11.0:
|
qs@6.11.0:
|
||||||
version "6.11.0"
|
version "6.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
|
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
|
||||||
@@ -18927,6 +18952,13 @@ react-native-progress@bluesky-social/react-native-progress:
|
|||||||
dependencies:
|
dependencies:
|
||||||
prop-types "^15.7.2"
|
prop-types "^15.7.2"
|
||||||
|
|
||||||
|
react-native-qrcode-styled@^0.3.1:
|
||||||
|
version "0.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-native-qrcode-styled/-/react-native-qrcode-styled-0.3.1.tgz#be6a0fab173511b0d3d8d71588771c2230982dbf"
|
||||||
|
integrity sha512-Q4EqbIFV0rpCYcdmWY51+H8Vrc0fvP01hPkiSqPEmjjxhm6mqyAuTMdNHNEddLXZzCVQCJujvj6IrHjdAhKjnA==
|
||||||
|
dependencies:
|
||||||
|
qrcode "^1.5.1"
|
||||||
|
|
||||||
react-native-reanimated@^3.11.0:
|
react-native-reanimated@^3.11.0:
|
||||||
version "3.11.0"
|
version "3.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-3.11.0.tgz#d4265d4e0232623f5958ed60e1686ca884fc3452"
|
resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-3.11.0.tgz#d4265d4e0232623f5958ed60e1686ca884fc3452"
|
||||||
@@ -22480,7 +22512,7 @@ yargs-parser@^21.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
|
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
|
||||||
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
|
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
|
||||||
|
|
||||||
yargs@^15.1.0:
|
yargs@^15.1.0, yargs@^15.3.1:
|
||||||
version "15.4.1"
|
version "15.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8"
|
resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8"
|
||||||
integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==
|
integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==
|
||||||
|
|||||||
Reference in New Issue
Block a user