From 77a512ae32eb1aae6be2b67779ffd9d8a1e28cb6 Mon Sep 17 00:00:00 2001 From: Hailey Date: Mon, 24 Jun 2024 10:24:39 -0700 Subject: [PATCH] Couple of starter packs tweaks (#4604) --- app.config.js | 4 +- src/components/StarterPack/QrCodeDialog.tsx | 10 +---- src/components/StarterPack/ShareDialog.tsx | 23 +++-------- .../Wizard/WizardEditListDialog.tsx | 2 + .../StarterPack/Wizard/WizardListCard.tsx | 29 ++++++++++++-- src/screens/StarterPack/Wizard/StepFeeds.tsx | 13 ++++--- .../StarterPack/Wizard/StepProfiles.tsx | 1 + src/screens/StarterPack/Wizard/index.tsx | 38 ++++++------------- 8 files changed, 57 insertions(+), 63 deletions(-) diff --git a/app.config.js b/app.config.js index 57d43058..4a449122 100644 --- a/app.config.js +++ b/app.config.js @@ -45,9 +45,7 @@ module.exports = function (config) { 'appclips:bsky.app', 'appclips:go.bsky.app', // Allows App Clip to work when scanning QR codes // When testing local services, enter an ngrok (et al) domain here. It must use a standard HTTP/HTTPS port. - ...(IS_DEV || IS_TESTFLIGHT - ? ['appclips:sptesting.haileyok.com', 'applinks:sptesting.haileyok.com'] - : []), + ...(IS_DEV || IS_TESTFLIGHT ? [] : []), ] const UPDATES_CHANNEL = IS_TESTFLIGHT diff --git a/src/components/StarterPack/QrCodeDialog.tsx b/src/components/StarterPack/QrCodeDialog.tsx index 580c6cc7..39eb3076 100644 --- a/src/components/StarterPack/QrCodeDialog.tsx +++ b/src/components/StarterPack/QrCodeDialog.tsx @@ -1,16 +1,14 @@ import React from 'react' import {View} from 'react-native' import ViewShot from 'react-native-view-shot' -import * as FS from 'expo-file-system' import {requestMediaLibraryPermissionsAsync} from 'expo-image-picker' +import {createAssetAsync} from 'expo-media-library' import * as Sharing from 'expo-sharing' import {AppBskyGraphDefs, AppBskyGraphStarterpack} 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 {saveImageToMediaLibrary} from 'lib/media/manip' import {logEvent} from 'lib/statsig/statsig' import {isNative, isWeb} from 'platform/detection' import * as Toast from '#/view/com/util/Toast' @@ -65,13 +63,9 @@ export function QrCodeDialog({ return } - const filename = `${FS.documentDirectory}/${nanoid(12)}.png` - // Incase of a FS failure, don't crash the app try { - await FS.copyAsync({from: uri, to: filename}) - await saveImageToMediaLibrary({uri: filename}) - await FS.deleteAsync(filename) + await createAssetAsync(`file://${uri}`) } catch (e: unknown) { Toast.show(_(msg`An error occurred while saving the QR code!`)) logger.error('Failed to save QR code', {error: e}) diff --git a/src/components/StarterPack/ShareDialog.tsx b/src/components/StarterPack/ShareDialog.tsx index 23fa10fb..61e23808 100644 --- a/src/components/StarterPack/ShareDialog.tsx +++ b/src/components/StarterPack/ShareDialog.tsx @@ -1,12 +1,10 @@ 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' @@ -72,19 +70,8 @@ function ShareDialogInner({ 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) - + await saveImageToMediaLibrary({uri: imageUrl}) Toast.show(_(msg`Image saved to your camera roll!`)) control.close() } catch (e: unknown) { @@ -133,18 +120,18 @@ function ShareDialogInner({ isWeb && [a.gap_sm, a.flex_row_reverse, {marginLeft: 'auto'}], ]}> {isNative && ( diff --git a/src/components/StarterPack/Wizard/WizardEditListDialog.tsx b/src/components/StarterPack/Wizard/WizardEditListDialog.tsx index bf250ac3..cf755e1b 100644 --- a/src/components/StarterPack/Wizard/WizardEditListDialog.tsx +++ b/src/components/StarterPack/Wizard/WizardEditListDialog.tsx @@ -58,6 +58,7 @@ export function WizardEditListDialog({ state.currentStep === 'Profiles' ? ( - + {btnType === 'checkbox' ? ( + + ) : !disabled ? ( + + ) : null} ) } export function WizardProfileCard({ + btnType, state, dispatch, profile, moderationOpts, }: { + btnType: 'checkbox' | 'remove' state: WizardState dispatch: (action: WizardAction) => void profile: AppBskyActorDefs.ProfileViewBasic @@ -127,6 +146,7 @@ export function WizardProfileCard({ return ( void @@ -170,6 +192,7 @@ export function WizardFeedCard({ return ( page.feeds) - .filter(f => !savedFeeds?.some(sf => sf?.uri === f.uri)) ?? [] + const popularFeeds = popularFeedsPages?.pages.flatMap(p => p.feeds) ?? [] - const suggestedFeeds = savedFeeds?.concat(popularFeeds) + const suggestedFeeds = + savedFeeds.length === 0 + ? popularFeeds + : savedFeeds.concat( + popularFeeds.filter(f => !savedFeeds.some(sf => sf.uri === f.uri)), + ) const {data: searchedFeeds, isLoading: isLoadingSearch} = useSearchPopularFeedsQuery({q: throttledQuery}) @@ -56,6 +58,7 @@ export function StepFeeds({moderationOpts}: {moderationOpts: ModerationOpts}) { return ( { - let displayName - if ( - currentProfile?.displayName != null && - currentProfile?.displayName !== '' - ) { - displayName = sanitizeDisplayName(currentProfile.displayName) - } else { - displayName = sanitizeHandle(currentProfile!.handle) - } + const displayName = createSanitizedDisplayName(currentProfile!, true) return _(msg`${displayName}'s Starter Pack`).slice(0, 50) } @@ -191,16 +184,12 @@ function WizardInner({ nextBtn: _(msg`Next`), }, Profiles: { - header: _(msg`People`), + header: _(msg`Choose People`), nextBtn: _(msg`Next`), - subtitle: _( - msg`Add people to your starter pack that you think others will enjoy following`, - ), }, Feeds: { - header: _(msg`Feeds`), + header: _(msg`Choose Feeds`), nextBtn: state.feeds.length === 0 ? _(msg`Skip`) : _(msg`Finish`), - subtitle: _(msg`Some subtitle`), }, } const currUiStrings = wizardUiStrings[state.currentStep] @@ -254,8 +243,8 @@ function WizardInner({ dispatch({type: 'SetProcessing', processing: true}) if (currentStarterPack && currentListItems) { editStarterPack({ - name: state.name ?? getDefaultName(), - description: state.description, + name: state.name?.trim() || getDefaultName(), + description: state.description?.trim(), descriptionFacets: [], profiles: state.profiles, feeds: state.feeds, @@ -264,8 +253,8 @@ function WizardInner({ }) } else { createStarterPack({ - name: state.name ?? getDefaultName(), - description: state.description, + name: state.name?.trim() || getDefaultName(), + description: state.description?.trim(), descriptionFacets: [], profiles: state.profiles, feeds: state.feeds, @@ -483,13 +472,10 @@ function Footer({ ) : items.length === 2 ? ( - - {getName(items[initialNamesIndex])}{' '} - - and + You and - {getName(items[state.currentStep === 'Profiles' ? 0 : 1])}{' '} + {getName(items[initialNamesIndex])}{' '} are included in your starter pack @@ -579,9 +565,9 @@ function Footer({ function getName(item: AppBskyActorDefs.ProfileViewBasic | GeneratorView) { if (typeof item.displayName === 'string') { - return enforceLen(sanitizeDisplayName(item.displayName), 16, true) + return enforceLen(sanitizeDisplayName(item.displayName), 28, true) } else if (typeof item.handle === 'string') { - return enforceLen(sanitizeHandle(item.handle), 16, true) + return enforceLen(sanitizeHandle(item.handle), 28, true) } return '' }