Use title case for Starter Pack (#11653)

This commit is contained in:
DS Boyce
2026-09-03 12:26:51 -07:00
committed by GitHub
parent 23d8fcf5ea
commit edcd363fcb
39 changed files with 295 additions and 393 deletions
-52
View File
@@ -296,19 +296,6 @@
"count": 1
}
},
"src/components/StarterPack/Main/ProfilesList.tsx": {
"typescript/no-misused-promises": {
"count": 1
}
},
"src/components/StarterPack/ProfileStarterPacks.tsx": {
"typescript/no-explicit-any": {
"count": 1
},
"typescript/no-misused-promises": {
"count": 2
}
},
"src/components/StarterPack/QrCodeDialog.tsx": {
"typescript/no-floating-promises": {
"count": 5
@@ -398,21 +385,11 @@
"count": 1
}
},
"src/components/dialogs/StarterPackDialog.tsx": {
"typescript/no-misused-promises": {
"count": 1
}
},
"src/components/dialogs/SwitchAccount.tsx": {
"typescript/no-floating-promises": {
"count": 1
}
},
"src/components/dialogs/lists/CreateListFromStarterPackDialog.tsx": {
"typescript/no-floating-promises": {
"count": 2
}
},
"src/components/dialogs/lists/CreateOrEditListDialog.tsx": {
"typescript/no-explicit-any": {
"count": 2
@@ -857,14 +834,6 @@
"count": 1
}
},
"src/screens/ProfileList/components/MoreOptionsMenu.tsx": {
"typescript/no-floating-promises": {
"count": 1
},
"typescript/no-misused-promises": {
"count": 5
}
},
"src/screens/ProfileList/components/SubscribeMenu.tsx": {
"typescript/no-misused-promises": {
"count": 2
@@ -996,22 +965,6 @@
"count": 1
}
},
"src/screens/StarterPack/StarterPackScreen.tsx": {
"typescript/no-floating-promises": {
"count": 1
},
"typescript/require-await": {
"count": 1
}
},
"src/screens/StarterPack/Wizard/index.tsx": {
"typescript/no-floating-promises": {
"count": 2
},
"typescript/require-await": {
"count": 1
}
},
"src/state/a11y.tsx": {
"typescript/no-floating-promises": {
"count": 1
@@ -1233,11 +1186,6 @@
"count": 2
}
},
"src/state/queries/starter-packs.ts": {
"typescript/require-await": {
"count": 1
}
},
"src/state/queries/suggested-follows.ts": {
"no-unused-vars": {
"count": 1
+2 -2
View File
@@ -575,12 +575,12 @@ function commonScreens(Stack: typeof Flat, unreadCountLabel?: string) {
<Stack.Screen
name="StarterPackWizard"
getComponent={() => Wizard}
options={{title: title(msg`Create a starter pack`), requireAuth: true}}
options={{title: title(msg`Create a Starter Pack`), requireAuth: true}}
/>
<Stack.Screen
name="StarterPackEdit"
getComponent={() => Wizard}
options={{title: title(msg`Edit your starter pack`), requireAuth: true}}
options={{title: title(msg`Edit your Starter Pack`), requireAuth: true}}
/>
<Stack.Screen
name="VideoFeed"
+2 -2
View File
@@ -102,7 +102,7 @@ function DialogInner({
if (isMe) {
if (profile.joinedViaStarterPack) {
return _(
msg`You joined Bluesky using a starter pack ${timeAgoString} ago`,
msg`You joined Bluesky using a Starter Pack ${timeAgoString} ago`,
)
} else {
return _(msg`You joined Bluesky ${timeAgoString} ago`)
@@ -110,7 +110,7 @@ function DialogInner({
} else {
if (profile.joinedViaStarterPack) {
return _(
msg`${profileName} joined Bluesky using a starter pack ${timeAgoString} ago`,
msg`${profileName} joined Bluesky using a Starter Pack ${timeAgoString} ago`,
)
} else {
return _(msg`${profileName} joined Bluesky ${timeAgoString} ago`)
@@ -2,8 +2,7 @@ import {forwardRef, useCallback, useImperativeHandle, useState} from 'react'
import {type ListRenderItemInfo, View} from 'react-native'
import {AtUri} from '@atproto/syntax'
import {type ModerationOpts} from '@bsky/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {useLingui} from '@lingui/react/macro'
import {Trans} from '@lingui/react/macro'
import {useBottomBarOffset} from '#/lib/hooks/useBottomBarOffset'
@@ -107,6 +106,12 @@ export const ProfilesList = forwardRef<SectionRef, ProfilesListProps>(
)
}
const onRefresh = async () => {
setIsPTRing(true)
await refetch()
setIsPTRing(false)
}
if (!data) {
return (
<View
@@ -140,11 +145,7 @@ export const ProfilesList = forwardRef<SectionRef, ProfilesListProps>(
desktopFixedHeight
initialNumToRender={initialNumToRender}
refreshing={isPTRing}
onRefresh={async () => {
setIsPTRing(true)
await refetch()
setIsPTRing(false)
}}
onRefresh={() => void onRefresh()}
/>
)
},
@@ -159,14 +160,14 @@ function OptedOutControls({
listUri: string
canRemove: boolean
}) {
const {_} = useLingui()
const {t: l} = useLingui()
const ax = useAnalytics()
const [isRemoved, setIsRemoved] = useState(false)
const {mutate: removeMembership, isPending} = useListMembershipRemoveMutation(
{
onSuccess: () => {
setIsRemoved(true)
Toast.show(_(msg`Removed from starter pack`))
Toast.show(l`Removed from Starter Pack`)
},
onError: error =>
Toast.show(cleanError(error), {
@@ -183,12 +184,12 @@ function OptedOutControls({
<Admonition.Icon />
<Admonition.Content>
<Admonition.Text>
<Trans>Opted out of this starter pack</Trans>
<Trans>Opted out of this Starter Pack</Trans>
</Admonition.Text>
</Admonition.Content>
{canRemove ? (
<Admonition.Button
label={_(msg`Remove user from starter pack`)}
label={l`Remove user from Starter Pack`}
color="secondary"
disabled={isPending}
onPress={() => {
@@ -6,9 +6,7 @@ import {
View,
type ViewStyle,
} from 'react-native'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
import {Trans, useLingui} from '@lingui/react/macro'
import {useNavigation} from '@react-navigation/native'
import {useGenerateStarterPackMutation} from '#/lib/generate-starterpack'
@@ -54,7 +52,7 @@ interface ProfileFeedgensProps {
isMe: boolean
emptyStateMessage?: string
emptyStateButton?: EmptyStateButtonProps
emptyStateIcon?: React.ComponentType<any> | React.ReactElement
emptyStateIcon?: React.ComponentType | React.ReactElement
}
function keyExtractor(item: app.bsky.graph.defs.StarterPackViewBasic) {
@@ -90,7 +88,7 @@ export function ProfileStarterPacks({
const {isTabletOrDesktop} = useWebMediaQueries()
const items = data?.pages.flatMap(page => page.starterPacks)
const {_} = useLingui()
const {t: l} = useLingui()
const EmptyComponent = useCallback(() => {
if (emptyStateMessage || emptyStateButton || emptyStateIcon) {
@@ -101,9 +99,7 @@ export function ProfileStarterPacks({
iconSize="3xl"
message={
emptyStateMessage ??
_(
msg`Starter packs let you share your favorite feeds and people with your friends.`,
)
l`Starter Packs let you share your favorite feeds and people with your friends.`
}
button={emptyStateButton}
/>
@@ -111,7 +107,7 @@ export function ProfileStarterPacks({
)
}
return <Empty />
}, [_, emptyStateMessage, emptyStateButton, emptyStateIcon])
}, [l, emptyStateMessage, emptyStateButton, emptyStateIcon])
useImperativeHandle(ref, () => ({
scrollToTop: () => {},
@@ -122,7 +118,7 @@ export function ProfileStarterPacks({
try {
await refetch()
} catch (err) {
logger.error('Failed to refresh starter packs', {message: err})
logger.error('Failed to refresh Starter Packs', {message: err})
}
setIsPTRing(false)
}, [refetch, setIsPTRing])
@@ -132,7 +128,7 @@ export function ProfileStarterPacks({
try {
await fetchNextPage()
} catch (err) {
logger.error('Failed to load more starter packs', {message: err})
logger.error('Failed to load more Starter Packs', {message: err})
}
}, [isFetchingNextPage, hasNextPage, isError, fetchNextPage])
@@ -179,8 +175,8 @@ export function ProfileStarterPacks({
}}
removeClippedSubviews={true}
desktopFixedHeight
onEndReached={onEndReached}
onRefresh={onRefresh}
onEndReached={() => void onEndReached()}
onRefresh={() => void onRefresh()}
ListEmptyComponent={
data ? (isMe ? EmptyComponent : undefined) : FeedLoadingPlaceholder
}
@@ -193,7 +189,7 @@ export function ProfileStarterPacks({
}
function CreateAnother() {
const {_} = useLingui()
const {t: l} = useLingui()
const t = useTheme()
const navigation = useNavigation<NavigationProp>()
@@ -207,7 +203,7 @@ function CreateAnother() {
t.atoms.border_contrast_low,
]}>
<Button
label={_(msg`Create a starter pack`)}
label={l`Create a Starter Pack`}
variant="solid"
color="secondary"
size="small"
@@ -223,7 +219,7 @@ function CreateAnother() {
}
function Empty() {
const {_} = useLingui()
const {t: l} = useLingui()
const navigation = useNavigation<NavigationProp>()
const confirmDialogControl = useDialogControl()
const followersDialogControl = useDialogControl()
@@ -244,7 +240,7 @@ function Empty() {
setIsGenerating(false)
},
onError: e => {
logger.error('Failed to generate starter pack', {safeMessage: e})
logger.error('Failed to generate Starter Pack', {safeMessage: e})
setIsGenerating(false)
if (e.message.includes('NOT_ENOUGH_FOLLOWERS')) {
followersDialogControl.open()
@@ -265,7 +261,7 @@ function Empty() {
const wrappedOpenConfirmDialog = requireEmailVerification(openConfirmDialog, {
instructions: [
<Trans key="confirm">
Before creating a starter pack, you must first verify your email.
Before creating a Starter Pack, you must first verify your email.
</Trans>,
],
})
@@ -275,7 +271,7 @@ function Empty() {
const wrappedNavToWizard = requireEmailVerification(navToWizard, {
instructions: [
<Trans key="nav">
Before creating a starter pack, you must first verify your email.
Before creating a Starter Pack, you must first verify your email.
</Trans>,
],
})
@@ -292,18 +288,18 @@ function Empty() {
]}>
<View style={[a.gap_xs]}>
<Text style={[a.font_semi_bold, a.text_lg, {color: 'white'}]}>
<Trans>You haven't created a starter pack yet!</Trans>
<Trans>You haven't created a Starter Pack yet!</Trans>
</Text>
<Text style={[a.text_md, {color: 'white'}]}>
<Trans>
Starter packs let you easily share your favorite feeds and people
Starter Packs let you easily share your favorite feeds and people
with your friends.
</Trans>
</Text>
</View>
<View style={[a.flex_row, a.gap_md, {marginLeft: 'auto'}]}>
<Button
label={_(msg`Create a starter pack for me`)}
label={l`Create a Starter Pack for me`}
variant="ghost"
color="primary"
size="small"
@@ -316,7 +312,7 @@ function Empty() {
{isGenerating && <Loader size="md" />}
</Button>
<Button
label={_(msg`Create a starter pack`)}
label={l`Create a Starter Pack`}
variant="ghost"
color="primary"
size="small"
@@ -333,11 +329,10 @@ function Empty() {
</ButtonText>
</Button>
</View>
<Prompt.Outer control={confirmDialogControl}>
<Prompt.Content>
<Prompt.TitleText>
<Trans>Generate a starter pack</Trans>
<Trans>Generate a Starter Pack</Trans>
</Prompt.TitleText>
<Prompt.DescriptionText>
<Trans>
@@ -349,12 +344,12 @@ function Empty() {
<Prompt.Actions>
<Prompt.Action
color="primary"
cta={_(msg`Choose for me`)}
cta={l`Choose for me`}
onPress={generate}
/>
<Prompt.Action
color="secondary"
cta={_(msg`Let me choose`)}
cta={l`Let me choose`}
onPress={() => {
navigation.navigate('StarterPackWizard', {})
}}
@@ -363,21 +358,17 @@ function Empty() {
</Prompt.Outer>
<Prompt.Basic
control={followersDialogControl}
title={_(msg`Oops!`)}
description={_(
msg`You must be following at least seven other people to generate a starter pack.`,
)}
title={l`Oops!`}
description={l`You must be following at least seven other people to generate a Starter Pack.`}
onConfirm={() => {}}
showCancel={false}
/>
<Prompt.Basic
control={errorDialogControl}
title={_(msg`Oops!`)}
description={_(
msg`An error occurred while generating your starter pack. Want to try again?`,
)}
title={l`Oops!`}
description={l`An error occurred while generating your Starter Pack. Want to try again?`}
onConfirm={generate}
confirmButtonCta={_(msg`Retry`)}
confirmButtonCta={l`Retry`}
/>
</LinearGradientBackground>
)
+1 -1
View File
@@ -164,7 +164,7 @@ export function QrCodeDialog({
<Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
<Dialog.Handle />
<Dialog.ScrollableInner
label={_(msg`Create a QR code for a starter pack`)}>
label={_(msg`Create a QR code for a Starter Pack`)}>
<View style={[a.flex_1, a.align_center, a.gap_5xl]}>
<Suspense fallback={<Loading />}>
{!link ? (
+2 -2
View File
@@ -81,11 +81,11 @@ function ShareDialogInner({
<View style={[!gtMobile && a.gap_lg]}>
<View style={[a.gap_sm, gtMobile && a.pb_lg]}>
<Text style={[a.font_semi_bold, a.text_2xl]}>
<Trans>Invite people to this starter pack!</Trans>
<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
Share this Starter Pack and help people join your community on
Bluesky.
</Trans>
</Text>
+10 -12
View File
@@ -2,9 +2,7 @@ import {useMemo} from 'react'
import {View} from 'react-native'
import {Image} from 'expo-image'
import {AtUri} from '@atproto/syntax'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Plural, Trans} from '@lingui/react/macro'
import {Plural, Trans, useLingui} from '@lingui/react/macro'
import {useQueryClient} from '@tanstack/react-query'
import {sanitizeHandle} from '#/lib/strings/handles'
@@ -59,7 +57,7 @@ export function Card({
}) {
const {record, creator, joinedAllTimeCount} = starterPack
const {_} = useLingui()
const {t: l} = useLingui()
const t = useTheme()
const {currentAccount} = useSession()
const isOwnStarterPack = creator?.did === currentAccount?.did
@@ -84,8 +82,8 @@ export function Card({
style={[a.leading_snug, t.atoms.text_contrast_medium]}
numberOfLines={1}>
{isOwnStarterPack
? _(msg`Starter pack by you`)
: _(msg`Starter pack by ${sanitizeHandle(creator.handle, '@')}`)}
? l`Starter Pack by you`
: l`Starter Pack by ${sanitizeHandle(creator.handle, '@')}`}
</Text>
</View>
</View>
@@ -96,7 +94,7 @@ export function Card({
) : null}
{!!joinedAllTimeCount && joinedAllTimeCount >= 50 && (
<Text style={[a.font_semi_bold, t.atoms.text_contrast_medium]}>
<Trans comment="Number of users (always at least 50) who have joined Bluesky using a specific starter pack">
<Trans comment="Number of users (always at least 50) who have joined Bluesky using a specific Starter Pack">
<Plural value={joinedAllTimeCount} other="# users have" /> joined!
</Trans>
</Text>
@@ -110,7 +108,7 @@ export function useStarterPackLink({
}: {
view: bsky.starterPack.AnyStarterPackView
}) {
const {_} = useLingui()
const {t: l} = useLingui()
const qc = useQueryClient()
const {rkey, handleOrDid} = useMemo(() => {
const rkey = new AtUri(view.uri).rkey
@@ -125,8 +123,8 @@ export function useStarterPackLink({
return {
to: `/starter-pack/${handleOrDid}/${rkey}`,
label: bsky.isType(app.bsky.graph.starterpack, view.record)
? _(msg`Navigate to ${view.record.name}`)
: _(msg`Navigate to starter pack`),
? l`Navigate to ${view.record.name}`
: l`Navigate to Starter Pack`,
precache,
}
}
@@ -139,7 +137,7 @@ export function Link({
onPress?: () => void
children: BaseLinkProps['children']
}) {
const {_} = useLingui()
const {t: l} = useLingui()
const queryClient = useQueryClient()
const {record} = starterPack
const {rkey, handleOrDid} = useMemo(() => {
@@ -155,7 +153,7 @@ export function Link({
return (
<BaseLink
to={`/starter-pack/${handleOrDid}/${rkey}`}
label={_(msg`Navigate to ${record.name}`)}
label={l`Navigate to ${record.name}`}
onPress={() => {
precacheResolvedUri(
queryClient,
@@ -5,9 +5,7 @@ import {
type ModerationOpts,
type ModerationUI,
} from '@bsky/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
import {Trans, useLingui} from '@lingui/react/macro'
import {DISCOVER_FEED_URI, STARTER_PACK_MAX_SIZE} from '#/lib/constants'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
@@ -53,15 +51,15 @@ function WizardListCard({
moderationUi: ModerationUI
}) {
const t = useTheme()
const {_} = useLingui()
const {t: l} = useLingui()
return (
<Toggle.Item
name={type === 'user' ? _(msg`Person toggle`) : _(msg`Feed toggle`)}
name={type === 'user' ? l`Person toggle` : l`Feed toggle`}
label={
included
? _(msg`Remove ${displayName} from starter pack`)
: _(msg`Add ${displayName} to starter pack`)
? l`Remove ${displayName} from Starter Pack`
: l`Add ${displayName} to Starter Pack`
}
value={included}
disabled={btnType === 'remove' || disabled}
@@ -109,7 +107,7 @@ function WizardListCard({
<Checkbox />
) : !disabled ? (
<Button
label={_(msg`Remove`)}
label={l`Remove`}
variant="solid"
color="secondary"
size="small"
@@ -142,7 +140,7 @@ export function WizardProfileCard({
const ax = useAnalytics()
const {currentAccount} = useSession()
// Determine the "main" profile for this starter pack - either targetDid or current account
// Determine the "main" profile for this Starter Pack - either targetDid or current account
const targetProfileDid = state.targetDid || currentAccount?.did
const isTarget = profile.did === targetProfileDid
const included = isTarget || state.profiles.some(p => p.did === profile.did)
+1 -1
View File
@@ -149,7 +149,7 @@ export function useTopic(
} else if (link.startsWith('/starter-pack')) {
return {
type: 'starter-pack',
label: l`Browse starter pack ${displayName}`,
label: l`Browse Starter Pack ${displayName}`,
displayName,
uri: undefined,
url: link,
+21 -25
View File
@@ -1,8 +1,6 @@
import {useCallback} from 'react'
import {View} from 'react-native'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Plural, Trans} from '@lingui/react/macro'
import {Plural, Trans, useLingui} from '@lingui/react/macro'
import {useNavigation} from '@react-navigation/native'
import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification'
@@ -67,7 +65,7 @@ export function StarterPackDialog({
const wrappedNavToWizard = requireEmailVerification(navToWizard, {
instructions: [
<Trans key="nav">
Before creating a starter pack, you must first verify your email.
Before creating a Starter Pack, you must first verify your email.
</Trans>,
],
})
@@ -85,7 +83,7 @@ export function StarterPackDialog({
}
function Empty({onStartWizard}: {onStartWizard: () => void}) {
const {_} = useLingui()
const {t: l} = useLingui()
const t = useTheme()
return (
@@ -96,18 +94,17 @@ function Empty({onStartWizard}: {onStartWizard: () => void}) {
fill={t.atoms.border_contrast_medium.borderColor}
/>
<Text style={[a.text_center]}>
<Trans>You have no starter packs.</Trans>
<Trans>You have no Starter Packs.</Trans>
</Text>
</View>
<View style={[a.align_center]}>
<Button
label={_(msg`Create starter pack`)}
label={l`Create Starter Pack`}
color="secondary_inverted"
size="small"
onPress={onStartWizard}>
<ButtonText>
<Trans comment="Text on button to create a new starter pack">
<Trans comment="Text on button to create a new Starter Pack">
Create
</Trans>
</ButtonText>
@@ -128,7 +125,7 @@ function StarterPackList({
enabled?: boolean
}) {
const control = Dialog.useDialogContext()
const {_} = useLingui()
const {t: l} = useLingui()
const {data: subject} = useProfileQuery({did: targetDid})
const {
@@ -178,10 +175,10 @@ function StarterPackList({
native(a.pt_lg),
]}>
<Text style={[a.text_lg, a.font_semi_bold]}>
<Trans>Add to starter packs</Trans>
<Trans>Add to Starter Packs</Trans>
</Text>
<Button
label={_(msg`Close`)}
label={l`Close`}
onPress={onClose}
variant="ghost"
color="secondary"
@@ -196,15 +193,15 @@ function StarterPackList({
<View
style={[a.flex_row, a.justify_between, a.align_center, a.py_md]}>
<Text style={[a.text_md, a.font_semi_bold]}>
<Trans>New starter pack</Trans>
<Trans>New Starter Pack</Trans>
</Text>
<Button
label={_(msg`Create starter pack`)}
label={l`Create Starter Pack`}
color="secondary_inverted"
size="small"
onPress={onStartWizard}>
<ButtonText>
<Trans comment="Text on button to create a new starter pack">
<Trans comment="Text on button to create a new Starter Pack">
Create
</Trans>
</ButtonText>
@@ -234,7 +231,7 @@ function StarterPackList({
? () => 'starter_pack_dialog_loader'
: (item: StarterPackWithMembership) => item.starterPack.uri
}
onEndReached={onEndReached}
onEndReached={() => void onEndReached()}
onEndReachedThreshold={0.1}
ListHeaderComponent={listHeader}
ListEmptyComponent={<Empty onStartWizard={onStartWizard} />}
@@ -257,7 +254,7 @@ function StarterPackItem({
}) {
const t = useTheme()
const ax = useAnalytics()
const {_} = useLingui()
const {t: l} = useLingui()
const {currentAccount} = useSession()
const isSelf = subject?.did === currentAccount?.did
@@ -268,26 +265,26 @@ function StarterPackItem({
useListMembershipAddMutation({
subject,
onSuccess: () => {
Toast.show(_(msg`Added to starter pack`))
Toast.show(l`Added to Starter Pack`)
},
onError: err => {
if (!isNetworkError(err)) {
logger.error('Failed to add to starter pack', {safeMessage: err})
logger.error('Failed to add to Starter Pack', {safeMessage: err})
}
Toast.show(_(msg`Failed to add to starter pack`), {type: 'error'})
Toast.show(l`Failed to add to Starter Pack`, {type: 'error'})
},
})
const {mutate: removeMembership, isPending: isPendingRemove} =
useListMembershipRemoveMutation({
onSuccess: () => {
Toast.show(_(msg`Removed from starter pack`))
Toast.show(l`Removed from Starter Pack`)
},
onError: err => {
if (!isNetworkError(err)) {
logger.error('Failed to remove from starter pack', {safeMessage: err})
logger.error('Failed to remove from Starter Pack', {safeMessage: err})
}
Toast.show(_(msg`Failed to remove from starter pack`), {type: 'error'})
Toast.show(l`Failed to remove from Starter Pack`, {type: 'error'})
},
})
@@ -363,9 +360,8 @@ function StarterPackItem({
)}
</View>
</View>
<Button
label={isInPack ? _(msg`Remove`) : _(msg`Add`)}
label={isInPack ? l`Remove` : l`Add`}
color={isInPack ? 'secondary' : 'primary_subtle'}
size="tiny"
disabled={isPending || isSelf}
@@ -2,8 +2,7 @@ import {View} from 'react-native'
import {TID} from '@atproto/common-web'
import {type $Typed} from '@atproto/lex'
import {AtUri, type AtUriString, toDatetimeString} from '@atproto/syntax'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {useLingui} from '@lingui/react/macro'
import {Trans} from '@lingui/react/macro'
import {useNavigation} from '@react-navigation/native'
import {useQueryClient} from '@tanstack/react-query'
@@ -33,7 +32,7 @@ export function CreateListFromStarterPackDialog({
control: Dialog.DialogControlProps
starterPack: app.bsky.graph.defs.StarterPackView
}) {
const {_} = useLingui()
const {t: l} = useLingui()
const t = useTheme()
const appviewClient = useAppviewClient()
const pdsClient = usePdsClient()
@@ -115,7 +114,7 @@ export function CreateListFromStarterPackDialog({
})(),
)
queryClient.invalidateQueries({queryKey: ['list-members', listUri]})
void queryClient.invalidateQueries({queryKey: ['list-members', listUri]})
ax.metric('starterPack:convertToList', {
starterPack: starterPack.uri,
@@ -123,7 +122,7 @@ export function CreateListFromStarterPackDialog({
})
} catch (e) {
logger.error('Failed to add members to list', {safeMessage: e})
Toast.show(_(msg`List created, but failed to add some members`), {
Toast.show(l`List created, but failed to add some members`, {
type: 'error',
})
}
@@ -133,7 +132,7 @@ export function CreateListFromStarterPackDialog({
const onListCreated = (listUri: string) => {
loadingDialogControl.open()
addMembersAndNavigate(listUri)
void addMembersAndNavigate(listUri)
}
return (
@@ -144,24 +143,24 @@ export function CreateListFromStarterPackDialog({
nativeOptions={{preventExpansion: true}}>
<Dialog.Handle />
<Dialog.ScrollableInner
label={_(msg`Create list from starter pack`)}
label={l`Create list from Starter Pack`}
style={web({maxWidth: 400})}>
<View style={[a.gap_lg]}>
<Text style={[a.text_xl, a.font_bold]}>
<Trans>Create list from starter pack</Trans>
<Trans>Create list from Starter Pack</Trans>
</Text>
<Text
style={[a.text_md, a.leading_snug, t.atoms.text_contrast_high]}>
<Trans>
This will create a new list with the same name, description, and
members as this starter pack.
members as this Starter Pack.
</Trans>
</Text>
<Admonition type="tip">
<Trans>
Changes to the starter pack will not be reflected in the list
Changes to the Starter Pack will not be reflected in the list
after creation. The list will be an independent copy.
</Trans>
</Admonition>
@@ -176,7 +175,7 @@ export function CreateListFromStarterPackDialog({
a.pt_sm,
]}>
<Button
label={_(msg`Create list`)}
label={l`Create list`}
onPress={onPressCreate}
size={platform({
web: 'small',
@@ -188,7 +187,7 @@ export function CreateListFromStarterPackDialog({
</ButtonText>
</Button>
<Button
label={_(msg`Cancel`)}
label={l`Cancel`}
onPress={() => control.close()}
size={platform({
web: 'small',
@@ -204,7 +203,6 @@ export function CreateListFromStarterPackDialog({
<Dialog.Close />
</Dialog.ScrollableInner>
</Dialog.Outer>
<CreateOrEditListDialog
control={createDialogControl}
purpose="app.bsky.graph.defs#curatelist"
@@ -215,13 +213,12 @@ export function CreateListFromStarterPackDialog({
avatar: starterPack.list?.avatar,
}}
/>
<Dialog.Outer
control={loadingDialogControl}
nativeOptions={{preventDismiss: true}}>
<Dialog.Handle />
<Dialog.ScrollableInner
label={_(msg`Adding members to list...`)}
label={l`Adding members to list...`}
style={web({maxWidth: 400})}>
<View style={[a.align_center, a.gap_lg, a.py_5xl]}>
<Loader size="xl" />
@@ -187,7 +187,7 @@ function DialogInner({
ImageMeta | undefined | null
>()
// When creating with pre-filled values (from starter pack), consider dirty
// When creating with pre-filled values (from Starter Pack), consider dirty
// immediately so the Save button is enabled
const hasInitialValuesForCreate = !list && initialValues != null
const dirty =
@@ -53,7 +53,7 @@ export function useLandingEntry() {
}, 500)
void (async () => {
// Check for starter pack
// Check for Starter Pack
let uri: string | null | undefined
if (IS_ANDROID) {
+1 -1
View File
@@ -11,7 +11,7 @@ export function useLandingEntry() {
const href = window.location.href
const url = new URL(href)
// Check for starter pack
// Check for Starter Pack
const atUri = httpStarterPackUriToAtUri(href)
if (atUri) {
// Determines if an App Clip is loading this landing page
+21 -22
View File
@@ -1,71 +1,70 @@
import {useMemo} from 'react'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {useLingui} from '@lingui/react/macro'
import {type ParsedReportSubject} from './types'
export function useCopyForSubject(subject: ParsedReportSubject) {
const {_} = useLingui()
const {t: l} = useLingui()
return useMemo(() => {
switch (subject.type) {
case 'account': {
return {
title: _(msg`Report this user`),
subtitle: _(msg`Why should this user be reviewed?`),
title: l`Report this user`,
subtitle: l`Why should this user be reviewed?`,
}
}
case 'status': {
return {
title: _(msg`Report this livestream`),
subtitle: _(msg`Why should this livestream be reviewed?`),
title: l`Report this livestream`,
subtitle: l`Why should this livestream be reviewed?`,
}
}
case 'post': {
return {
title: _(msg`Report this post`),
subtitle: _(msg`Why should this post be reviewed?`),
title: l`Report this post`,
subtitle: l`Why should this post be reviewed?`,
}
}
case 'list': {
return {
title: _(msg`Report this list`),
subtitle: _(msg`Why should this list be reviewed?`),
title: l`Report this list`,
subtitle: l`Why should this list be reviewed?`,
}
}
case 'feed': {
return {
title: _(msg`Report this feed`),
subtitle: _(msg`Why should this feed be reviewed?`),
title: l`Report this feed`,
subtitle: l`Why should this feed be reviewed?`,
}
}
case 'starterPack': {
return {
title: _(msg`Report this starter pack`),
subtitle: _(msg`Why should this starter pack be reviewed?`),
title: l`Report this Starter Pack`,
subtitle: l`Why should this Starter Pack be reviewed?`,
}
}
case 'convoMessage': {
switch (subject.view) {
case 'convo': {
return {
title: _(msg`Report this conversation`),
subtitle: _(msg`Why should this conversation be reviewed?`),
title: l`Report this conversation`,
subtitle: l`Why should this conversation be reviewed?`,
}
}
case 'message': {
return {
title: _(msg`Report this message`),
subtitle: _(msg`Why should this message be reviewed?`),
title: l`Report this message`,
subtitle: l`Why should this message be reviewed?`,
}
}
}
}
case 'convo': {
return {
title: _(msg`Report this conversation`),
subtitle: _(msg`Why should this conversation be reviewed?`),
title: l`Report this conversation`,
subtitle: l`Why should this conversation be reviewed?`,
}
}
}
}, [_, subject])
}, [l, subject])
}
+1 -1
View File
@@ -406,7 +406,7 @@ export function shortLinkToHref(url: string): string {
try {
const urlp = new URL(url)
// For now we only support starter packs, but in the future we should add additional paths to this check
// For now we only support Starter Packs, but in the future we should add additional paths to this check
const parts = urlp.pathname.split('/').filter(Boolean)
if (parts.length === 1) {
return `/starter-pack-short/${parts[0]}`
+1 -1
View File
@@ -82,7 +82,7 @@ export const router = new Router<AllNavigatableRoutes>({
MessagesConversation: '/messages/:conversation',
MessagesConversationSettings: '/messages/:conversation/settings',
MessagesJoinRequests: '/messages/:conversation/requests',
// starter packs
// Starter Packs
Start: '/start/:name/:rkey',
StarterPackEdit: '/starter-pack/edit/:rkey',
StarterPack: '/starter-pack/:name/:rkey',
@@ -75,7 +75,7 @@ export function StepFinished() {
})
starterPack = spRes.starterPack
} catch (e) {
logger.error('Failed to fetch starter pack', {safeMessage: e})
logger.error('Failed to fetch Starter Pack', {safeMessage: e})
// don't tell the user, just get them through onboarding.
}
const starterPackList = starterPack?.list
@@ -87,7 +87,7 @@ export function StepFinished() {
)
}
} catch (e) {
logger.error('Failed to fetch starter pack list items', {
logger.error('Failed to fetch Starter Pack list items', {
safeMessage: e,
})
// don't tell the user, just get them through onboarding.
@@ -132,7 +132,7 @@ export function StepFinished() {
},
]
// Any starter pack feeds will be pinned _after_ the defaults
// Any Starter Pack feeds will be pinned _after_ the defaults
if (starterPack && starterPack.feeds?.length) {
feedsToSave.push(
...starterPack.feeds.map(f => ({
@@ -55,7 +55,7 @@ export function StarterPackCard({
Toast.show(_(msg`An error occurred while trying to follow all`), {
type: 'error',
})
logger.error('Failed to get list members for starter pack', {
logger.error('Failed to get list members for Starter Pack', {
safeMessage: e,
})
return
@@ -40,7 +40,7 @@ export function StepSuggestedStarterpacks() {
<View style={[a.align_start, a.gap_sm]} testID="onboardingInterests">
<OnboardingPosition />
<OnboardingTitleText>
<Trans comment="Starter packs suggested to the user for them to follow">
<Trans comment="Starter Packs suggested to the user for them to follow">
Find people to follow
</Trans>
</OnboardingTitleText>
+1 -1
View File
@@ -38,7 +38,7 @@ export function Onboarding() {
return bcp47Match.basicFilter('en', contentLanguages).length > 0
}, [contentLanguages])
// starter packs screen is currently geared towards english-speaking accounts
// Starter Packs screen is currently geared towards english-speaking accounts
const showSuggestedStarterpacks = ENV !== 'e2e' && probablySpeaksEnglish
const findContactsEnabled =
@@ -1,6 +1,5 @@
import {AtUri} from '@atproto/syntax'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {useLingui} from '@lingui/react/macro'
import {Trans} from '@lingui/react/macro'
import {useNavigation} from '@react-navigation/native'
@@ -46,7 +45,7 @@ export function MoreOptionsMenu({
list: app.bsky.graph.defs.ListView
savedFeedConfig?: app.bsky.actor.defs.SavedFeed
}) {
const {_} = useLingui()
const {t: l} = useLingui()
const ax = useAnalytics()
const {currentAccount} = useSession()
const editListDialogControl = useDialogControl()
@@ -79,15 +78,15 @@ export function MoreOptionsMenu({
})
Toast.show(
action === 'optOut'
? _(msg`Opted out of starter pack`)
: _(msg`Opt-out undone`),
? l`Opted out of Starter Pack`
: l`Opt-out undone`,
)
},
onError: error => {
logger.error('Failed to update starter pack opt-out', {
logger.error('Failed to update Starter Pack opt-out', {
safeMessage: error,
})
Toast.show(_(msg`Failed to update starter pack opt-out`), {
Toast.show(l`Failed to update Starter Pack opt-out`, {
type: 'error',
})
},
@@ -96,16 +95,16 @@ export function MoreOptionsMenu({
const onPressShare = () => {
const {rkey} = new AtUri(list.uri)
const url = toShareUrl(`/profile/${list.creator.did}/lists/${rkey}`)
shareUrl(url)
void shareUrl(url)
}
const onRemoveFromSavedFeeds = async () => {
if (!savedFeedConfig) return
try {
await removeSavedFeed(savedFeedConfig)
Toast.show(_(msg`Removed from your feeds`))
Toast.show(l`Removed from your feeds`)
} catch (e) {
Toast.show(_(msg`There was an issue contacting the server`), {
Toast.show(l`There was an issue contacting the server`, {
type: 'error',
})
logger.error('Failed to remove pinned list', {message: e})
@@ -119,7 +118,7 @@ export function MoreOptionsMenu({
await removeSavedFeed(savedFeedConfig)
}
Toast.show(_(msg({message: 'List deleted', context: 'toast'})))
Toast.show(l({message: 'List deleted', context: 'toast'}))
if (navigation.canGoBack()) {
navigation.goBack()
} else {
@@ -131,9 +130,9 @@ export function MoreOptionsMenu({
try {
if (!savedFeedConfig) return
await removeSavedFeed(savedFeedConfig)
Toast.show(_(msg`Unpinned list`))
Toast.show(l`Unpinned list`)
} catch {
Toast.show(_(msg`Failed to unpin list`), {
Toast.show(l`Failed to unpin list`, {
type: 'error',
})
}
@@ -142,13 +141,11 @@ export function MoreOptionsMenu({
const onUnsubscribeMute = async () => {
try {
await muteList({uri: list.uri, mute: false})
Toast.show(_(msg({message: 'List unmuted', context: 'toast'})))
Toast.show(l({message: 'List unmuted', context: 'toast'}))
ax.metric('moderation:unsubscribedFromList', {listType: 'mute'})
} catch {
Toast.show(
_(
msg`There was an issue. Please check your internet connection and try again.`,
),
l`There was an issue. Please check your internet connection and try again.`,
)
}
}
@@ -156,13 +153,11 @@ export function MoreOptionsMenu({
const onUnsubscribeBlock = async () => {
try {
await blockList({uri: list.uri, block: false})
Toast.show(_(msg({message: 'List unblocked', context: 'toast'})))
Toast.show(l({message: 'List unblocked', context: 'toast'}))
ax.metric('moderation:unsubscribedFromList', {listType: 'block'})
} catch {
Toast.show(
_(
msg`There was an issue. Please check your internet connection and try again.`,
),
l`There was an issue. Please check your internet connection and try again.`,
)
}
}
@@ -170,7 +165,7 @@ export function MoreOptionsMenu({
return (
<>
<Menu.Root>
<Menu.Trigger label={_(msg`More options`)}>
<Menu.Trigger label={l`More options`}>
{({props}) => (
<Button
label={props.accessibilityLabel}
@@ -186,7 +181,7 @@ export function MoreOptionsMenu({
<Menu.Outer showCancel>
<Menu.Group>
<Menu.Item
label={IS_WEB ? _(msg`Copy link to list`) : _(msg`Share via...`)}
label={IS_WEB ? l`Copy link to list` : l`Share via...`}
onPress={onPressShare}>
<Menu.ItemText>
{IS_WEB ? (
@@ -202,8 +197,8 @@ export function MoreOptionsMenu({
</Menu.Item>
{savedFeedConfig && (
<Menu.Item
label={_(msg`Remove from my feeds`)}
onPress={onRemoveFromSavedFeeds}>
label={l`Remove from my feeds`}
onPress={() => void onRemoveFromSavedFeeds()}>
<Menu.ItemText>
<Trans>Remove from my feeds</Trans>
</Menu.ItemText>
@@ -217,7 +212,7 @@ export function MoreOptionsMenu({
{isOwner ? (
<Menu.Group>
<Menu.Item
label={_(msg`Edit list details`)}
label={l`Edit list details`}
onPress={editListDialogControl.open}>
<Menu.ItemText>
<Trans>Edit list details</Trans>
@@ -225,7 +220,7 @@ export function MoreOptionsMenu({
<Menu.ItemIcon position="right" icon={PencilLineIcon} />
</Menu.Item>
<Menu.Item
label={_(msg`Delete list`)}
label={l`Delete list`}
onPress={deleteListPromptControl.open}>
<Menu.ItemText>
<Trans>Delete list</Trans>
@@ -237,7 +232,7 @@ export function MoreOptionsMenu({
<>
<Menu.Group>
<Menu.Item
label={_(msg`Report list`)}
label={l`Report list`}
onPress={reportDialogControl.open}>
<Menu.ItemText>
<Trans>Report list</Trans>
@@ -252,8 +247,8 @@ export function MoreOptionsMenu({
<Menu.Item
label={
referenceListOptOut
? _(msg`Undo opt-out from starter pack`)
: _(msg`Opt out of starter pack`)
? l`Undo opt-out from Starter Pack`
: l`Opt out of Starter Pack`
}
disabled={isOptOutPending}
onPress={optOutDialogControl.open}>
@@ -261,7 +256,7 @@ export function MoreOptionsMenu({
{referenceListOptOut ? (
<Trans>Undo opt-out</Trans>
) : (
<Trans>Opt out of starter pack</Trans>
<Trans>Opt out of Starter Pack</Trans>
)}
</Menu.ItemText>
</Menu.Item>
@@ -276,8 +271,8 @@ export function MoreOptionsMenu({
<Menu.Divider />
<Menu.Group>
<Menu.Item
label={_(msg`Unpin moderation list`)}
onPress={onUnpinModList}>
label={l`Unpin moderation list`}
onPress={() => void onUnpinModList()}>
<Menu.ItemText>
<Trans>Unpin moderation list</Trans>
</Menu.ItemText>
@@ -293,8 +288,8 @@ export function MoreOptionsMenu({
<Menu.Group>
{isBlocking && (
<Menu.Item
label={_(msg`Unblock list`)}
onPress={onUnsubscribeBlock}>
label={l`Unblock list`}
onPress={() => void onUnsubscribeBlock()}>
<Menu.ItemText>
<Trans>Unblock list</Trans>
</Menu.ItemText>
@@ -303,8 +298,8 @@ export function MoreOptionsMenu({
)}
{isMuting && (
<Menu.Item
label={_(msg`Unmute list`)}
onPress={onUnsubscribeMute}>
label={l`Unmute list`}
onPress={() => void onUnsubscribeMute()}>
<Menu.ItemText>
<Trans>Unmute list</Trans>
</Menu.ItemText>
@@ -316,37 +311,32 @@ export function MoreOptionsMenu({
)}
</Menu.Outer>
</Menu.Root>
<CreateOrEditListDialog control={editListDialogControl} list={list} />
<Prompt.Basic
control={deleteListPromptControl}
title={_(msg`Delete this list?`)}
description={_(
msg`If you delete this list, you won't be able to recover it.`,
)}
onConfirm={onPressDelete}
confirmButtonCta={_(msg`Delete`)}
title={l`Delete this list?`}
description={l`If you delete this list, you won't be able to recover it.`}
onConfirm={() => void onPressDelete()}
confirmButtonCta={l`Delete`}
confirmButtonColor="negative"
/>
{isReferenceList ? (
<Prompt.Outer control={optOutDialogControl}>
<Prompt.TitleText>
{referenceListOptOut ? (
<Trans>Undo opt-out?</Trans>
) : (
<Trans>Opt out of this starter pack?</Trans>
<Trans>Opt out of this Starter Pack?</Trans>
)}
</Prompt.TitleText>
<Prompt.DescriptionText>
{referenceListOptOut ? (
<Trans>
You will be eligible to appear in this starter pack again.
You will be eligible to appear in this Starter Pack again.
</Trans>
) : (
<Trans>
You will no longer appear in this starter pack. The creator will
You will no longer appear in this Starter Pack. The creator will
be able to see that you've opted out and remove you if they
wish.
</Trans>
@@ -356,8 +346,8 @@ export function MoreOptionsMenu({
<Prompt.Action
cta={
referenceListOptOut
? _(msg`Undo opt-out`)
: _(msg`Opt out of starter pack`)
? l`Undo opt-out`
: l`Opt out of Starter Pack`
}
color={referenceListOptOut ? 'primary' : 'negative'}
disabled={isOptOutPending}
@@ -369,7 +359,6 @@ export function MoreOptionsMenu({
</Prompt.Actions>
</Prompt.Outer>
) : null}
<ReportDialog
control={reportDialogControl}
subject={{
+1 -1
View File
@@ -117,7 +117,7 @@ let SearchResults = ({
},
noFilters &&
isStarterPacksEnabled && {
title: l`Starter packs`,
title: l`Starter Packs`,
component: (
<SearchScreenStarterPackResults
query={query}
@@ -387,7 +387,7 @@ export function NotificationSettingsScreen({}: Props) {
titleText={<Trans>Everything else</Trans>}
subtitleText={
<Trans>
Get notifications for starter pack joins, verification, and other
Get notifications for Starter Pack joins, verification, and other
activity.
</Trans>
}
@@ -190,7 +190,7 @@ function LandingScreenLoaded({
a.text_md,
{color: 'white'},
]}>
Starter pack by {`@${creator.handle}`}
<Trans>Starter Pack by {`@${creator.handle}`}</Trans>
</Text>
</LinearGradientBackground>
<View style={[a.gap_2xl, a.mx_lg, a.my_2xl]}>
@@ -299,14 +299,14 @@ function LandingScreenLoaded({
) : null}
</View>
<Button
label={_(msg`Create an account without using this starter pack`)}
label={_(msg`Create an account without using this Starter Pack`)}
variant="solid"
color="secondary"
size="large"
style={[a.py_lg]}
onPress={onJoinWithoutPress}>
<ButtonText>
<Trans>Create an account without using this starter pack</Trans>
<Trans>Create an account without using this Starter Pack</Trans>
</ButtonText>
</Button>
</View>
@@ -396,7 +396,7 @@ export function AppClipOverlay({
Download Bluesky to get started!
</Text>
<Text style={[a.text_lg, {color: 'white'}]}>
We'll remember the starter pack you chose and use it when you create
Well remember the Starter Pack you chose and use it when you create
an account in the app.
</Text>
</View>
+56 -64
View File
@@ -4,9 +4,7 @@ import {Image} from 'expo-image'
import {AtUri} from '@atproto/syntax'
import {type ModerationOpts} from '@bsky/sdk/moderation'
import {RichText as RichTextAPI} from '@bsky/sdk/richtext'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Plural, Trans} from '@lingui/react/macro'
import {Plural, Trans, useLingui} from '@lingui/react/macro'
import {useNavigation} from '@react-navigation/native'
import {type NativeStackScreenProps} from '@react-navigation/native-stack'
import {useQueryClient} from '@tanstack/react-query'
@@ -96,7 +94,7 @@ export function StarterPackScreen({route}: StarterPackScreeProps) {
}
export function StarterPackScreenShort({route}: StarterPackScreenShortProps) {
const {_} = useLingui()
const {t: l} = useLingui()
const {
data: resolvedStarterPack,
isLoading,
@@ -111,8 +109,8 @@ export function StarterPackScreenShort({route}: StarterPackScreenShortProps) {
<ListMaybePlaceholder
isLoading={isLoading}
isError={isError}
errorMessage={_(msg`That starter pack could not be found.`)}
emptyMessage={_(msg`That starter pack could not be found.`)}
errorMessage={l`That Starter Pack could not be found.`}
emptyMessage={l`That Starter Pack could not be found.`}
/>
</Layout.Screen>
)
@@ -130,7 +128,7 @@ export function StarterPackScreenInner({
routeParams: StarterPackScreeProps['route']['params']
}) {
const {name, rkey} = routeParams
const {_} = useLingui()
const {t: l} = useLingui()
const {currentAccount} = useSession()
const moderationOpts = useModerationOpts()
@@ -156,8 +154,8 @@ export function StarterPackScreenInner({
<ListMaybePlaceholder
isLoading={isLoadingDid || isLoadingStarterPack || !moderationOpts}
isError={isErrorDid || isErrorStarterPack || !isValid}
errorMessage={_(msg`That starter pack could not be found.`)}
emptyMessage={_(msg`That starter pack could not be found.`)}
errorMessage={l`That Starter Pack could not be found.`}
emptyMessage={l`That Starter Pack could not be found.`}
/>
)
}
@@ -187,13 +185,13 @@ function StarterPackScreenLoaded({
const showPeopleTab = Boolean(starterPack.list)
const showFeedsTab = Boolean(starterPack.feeds?.length)
const showPostsTab = Boolean(starterPack.list)
const {_} = useLingui()
const {t: l} = useLingui()
const ax = useAnalytics()
const tabs = [
...(showPeopleTab ? [_(msg`People`)] : []),
...(showFeedsTab ? [_(msg`Feeds`)] : []),
...(showPostsTab ? [_(msg`Posts`)] : []),
...(showPeopleTab ? [l`People`] : []),
...(showFeedsTab ? [l`Feeds`] : []),
...(showPostsTab ? [l`Posts`] : []),
]
const qrCodeDialogControl = useDialogControl()
@@ -211,7 +209,7 @@ function StarterPackScreenLoaded({
const onOpenShareDialog = useCallback(() => {
const rkey = new AtUri(starterPack.uri).rkey
shortenLink(makeStarterPackLink(starterPack.creator.did, rkey)).then(
void shortenLink(makeStarterPackLink(starterPack.creator.did, rkey)).then(
res => {
setLink(res.url)
},
@@ -301,7 +299,7 @@ function Header({
routeParams: StarterPackScreeProps['route']['params']
onOpenShareDialog: () => void
}) {
const {_} = useLingui()
const {t: l} = useLingui()
const t = useTheme()
const {currentAccount, hasSession} = useSession()
const appviewClient = useAppviewClient()
@@ -351,10 +349,10 @@ function Header({
listItems = await getAllListMembers(appviewClient, starterPack.list.uri)
} catch (e) {
setIsProcessing(false)
Toast.show(_(msg`An error occurred while trying to follow all`), {
Toast.show(l`An error occurred while trying to follow all`, {
type: 'error',
})
logger.error('Failed to get list members for starter pack', {
logger.error('Failed to get list members for Starter Pack', {
safeMessage: e,
})
return
@@ -378,7 +376,7 @@ function Header({
})
} catch (e) {
setIsProcessing(false)
Toast.show(_(msg`An error occurred while trying to follow all`), {
Toast.show(l`An error occurred while trying to follow all`, {
type: 'error',
})
logger.error('Failed to follow all accounts', {safeMessage: e})
@@ -392,7 +390,7 @@ function Header({
})
}
})
Toast.show(_(msg`All accounts have been followed!`))
Toast.show(l`All accounts have been followed!`)
captureAction(ProgressGuideAction.Follow, dids.length)
ax.metric('starterPack:followAll', {
logContext: 'StarterPackProfilesList',
@@ -427,7 +425,7 @@ function Header({
<View style={[a.flex_row, a.gap_sm, a.align_center]}>
{isOwn ? (
<Button
label={_(msg`Share this starter pack`)}
label={l`Share this Starter Pack`}
hitSlop={HITSLOP_20}
variant="solid"
color="primary"
@@ -439,7 +437,7 @@ function Header({
</Button>
) : (
<Button
label={_(msg`Follow all`)}
label={l`Follow all`}
variant="solid"
color="primary"
size="small"
@@ -465,7 +463,7 @@ function Header({
{richText ? <RichText value={richText} style={[a.text_md]} /> : null}
{!hasSession ? (
<Button
label={_(msg`Join Bluesky`)}
label={l`Join Bluesky`}
onPress={() => {
setActiveStarterPack({
uri: starterPack.uri,
@@ -491,12 +489,12 @@ function Header({
a.text_sm,
t.atoms.text_contrast_medium,
]}>
<Trans comment="Number of users (always at least 25) who have joined Bluesky using a specific starter pack">
<Trans comment="Number of users (always at least 25) who have joined Bluesky using a specific Starter Pack">
<Plural
value={starterPack.joinedAllTimeCount || 0}
other="# people have"
/>{' '}
joined Bluesky via this starter pack!
joined Bluesky via this Starter Pack!
</Trans>
</Text>
</View>
@@ -517,7 +515,7 @@ function OverflowMenu({
onOpenShareDialog: () => void
}) {
const t = useTheme()
const {_} = useLingui()
const {t: l} = useLingui()
const ax = useAnalytics()
const {gtMobile} = useBreakpoints()
const {currentAccount} = useSession()
@@ -543,7 +541,7 @@ function OverflowMenu({
})
},
onError: e => {
logger.error('Failed to delete starter pack', {safeMessage: e})
logger.error('Failed to delete Starter Pack', {safeMessage: e})
},
})
@@ -559,21 +557,21 @@ function OverflowMenu({
})
Toast.show(
action === 'optOut'
? _(msg`Opted out of starter pack`)
: _(msg`Opt-out undone`),
? l`Opted out of Starter Pack`
: l`Opt-out undone`,
)
},
onError: error => {
logger.error('Failed to update starter pack opt-out', {
logger.error('Failed to update Starter Pack opt-out', {
safeMessage: error,
})
Toast.show(_(msg`Failed to update starter pack opt-out`), {
Toast.show(l`Failed to update Starter Pack opt-out`, {
type: 'error',
})
},
})
const onDeleteStarterPack = async () => {
const onDeleteStarterPack = () => {
if (!starterPack.list) {
logger.error(`Unable to delete starterpack because list is missing`)
return
@@ -589,12 +587,12 @@ function OverflowMenu({
return (
<>
<Menu.Root>
<Menu.Trigger label={_(msg`Repost or quote post`)}>
<Menu.Trigger label={l`Repost or quote post`}>
{({props}) => (
<Button
{...props}
testID="headerDropdownBtn"
label={_(msg`Open starter pack menu`)}
label={l`Open Starter Pack menu`}
hitSlop={HITSLOP_20}
variant="solid"
color="secondary"
@@ -608,7 +606,7 @@ function OverflowMenu({
{isOwn ? (
<>
<Menu.Item
label={_(msg`Edit starter pack`)}
label={l`Edit Starter Pack`}
testID="editStarterPackLinkBtn"
onPress={() => {
navigation.navigate('StarterPackEdit', {
@@ -621,7 +619,7 @@ function OverflowMenu({
<Menu.ItemIcon icon={Pencil} position="right" />
</Menu.Item>
<Menu.Item
label={_(msg`Delete starter pack`)}
label={l`Delete Starter Pack`}
testID="deleteStarterPackBtn"
onPress={() => {
deleteDialogControl.open()
@@ -632,7 +630,7 @@ function OverflowMenu({
<Menu.ItemIcon icon={Trash} position="right" />
</Menu.Item>
<Menu.Item
label={_(msg`Create a list from this starter pack`)}
label={l`Create a list from this Starter Pack`}
testID="convertToListBtn"
onPress={() => {
convertToListDialogControl.open()
@@ -648,9 +646,7 @@ function OverflowMenu({
<Menu.Group>
<Menu.Item
label={
IS_WEB
? _(msg`Copy link to starter pack`)
: _(msg`Share via...`)
IS_WEB ? l`Copy link to Starter Pack` : l`Share via...`
}
testID="shareStarterPackLinkBtn"
onPress={onOpenShareDialog}>
@@ -669,10 +665,10 @@ function OverflowMenu({
</Menu.Group>
<Menu.Item
label={_(msg`Report starter pack`)}
label={l`Report Starter Pack`}
onPress={() => reportDialogControl.open()}>
<Menu.ItemText>
<Trans>Report starter pack</Trans>
<Trans>Report Starter Pack</Trans>
</Menu.ItemText>
<Menu.ItemIcon icon={CircleInfo} position="right" />
</Menu.Item>
@@ -680,8 +676,8 @@ function OverflowMenu({
<Menu.Item
label={
referenceListOptOut
? _(msg`Undo opt-out from starter pack`)
: _(msg`Opt out of starter pack`)
? l`Undo opt-out from Starter Pack`
: l`Opt out of Starter Pack`
}
disabled={isOptOutPending}
onPress={() => optOutDialogControl.open()}>
@@ -689,7 +685,7 @@ function OverflowMenu({
{referenceListOptOut ? (
<Trans>Undo opt-out</Trans>
) : (
<Trans>Opt out of starter pack</Trans>
<Trans>Opt out of Starter Pack</Trans>
)}
</Menu.ItemText>
</Menu.Item>
@@ -698,7 +694,6 @@ function OverflowMenu({
)}
</Menu.Outer>
</Menu.Root>
{starterPack.list && (
<ReportDialog
control={reportDialogControl}
@@ -708,13 +703,12 @@ function OverflowMenu({
}}
/>
)}
<Prompt.Outer control={deleteDialogControl}>
<Prompt.TitleText>
<Trans>Delete starter pack?</Trans>
<Trans>Delete Starter Pack?</Trans>
</Prompt.TitleText>
<Prompt.DescriptionText>
<Trans>Are you sure you want to delete this starter pack?</Trans>
<Trans>Are you sure you want to delete this Starter Pack?</Trans>
</Prompt.DescriptionText>
{deleteError && (
<View
@@ -742,7 +736,7 @@ function OverflowMenu({
variant="solid"
color="negative"
size={gtMobile ? 'small' : 'large'}
label={_(msg`Yes, delete this starter pack`)}
label={l`Yes, delete this Starter Pack`}
onPress={onDeleteStarterPack}>
<ButtonText>
<Trans>Delete</Trans>
@@ -752,24 +746,23 @@ function OverflowMenu({
<Prompt.Cancel />
</Prompt.Actions>
</Prompt.Outer>
{starterPack.list ? (
<Prompt.Outer control={optOutDialogControl}>
<Prompt.TitleText>
{referenceListOptOut ? (
<Trans>Undo opt-out?</Trans>
) : (
<Trans>Opt out of this starter pack?</Trans>
<Trans>Opt out of this Starter Pack?</Trans>
)}
</Prompt.TitleText>
<Prompt.DescriptionText>
{referenceListOptOut ? (
<Trans>
You will be eligible to appear in this starter pack again.
You will be eligible to appear in this Starter Pack again.
</Trans>
) : (
<Trans>
You will no longer appear in this starter pack. The creator will
You will no longer appear in this Starter Pack. The creator will
be able to see that you've opted out and remove you if they
wish.
</Trans>
@@ -782,8 +775,8 @@ function OverflowMenu({
size="large"
label={
referenceListOptOut
? _(msg`Undo opt-out`)
: _(msg`Opt out of starter pack`)
? l`Undo opt-out`
: l`Opt out of Starter Pack`
}
disabled={isOptOutPending}
onPress={() => {
@@ -804,7 +797,6 @@ function OverflowMenu({
</Prompt.Actions>
</Prompt.Outer>
) : null}
<CreateListFromStarterPackDialog
control={convertToListDialogControl}
starterPack={starterPack}
@@ -814,7 +806,7 @@ function OverflowMenu({
}
function InvalidStarterPack({rkey}: {rkey: string}) {
const {_} = useLingui()
const {t: l} = useLingui()
const t = useTheme()
const navigation = useNavigation<NavigationProp>()
const {gtMobile} = useBreakpoints()
@@ -835,8 +827,8 @@ function InvalidStarterPack({rkey}: {rkey: string}) {
},
onError: e => {
setIsProcessing(false)
logger.error('Failed to delete invalid starter pack', {safeMessage: e})
Toast.show(_(msg`Failed to delete starter pack`), {
logger.error('Failed to delete invalid Starter Pack', {safeMessage: e})
Toast.show(l`Failed to delete Starter Pack`, {
type: 'error',
})
},
@@ -847,7 +839,7 @@ function InvalidStarterPack({rkey}: {rkey: string}) {
<View style={[a.py_4xl, a.px_xl, a.align_center, a.gap_5xl]}>
<View style={[a.w_full, a.align_center, a.gap_lg]}>
<Text style={[a.font_semi_bold, a.text_3xl]}>
<Trans>Starter pack is invalid</Trans>
<Trans>Starter Pack is invalid</Trans>
</Text>
<Text
style={[
@@ -858,8 +850,8 @@ function InvalidStarterPack({rkey}: {rkey: string}) {
gtMobile ? {width: 450} : [a.w_full, a.px_lg],
]}>
<Trans>
The starter pack that you are trying to view is invalid. You may
delete this starter pack instead.
The Starter Pack that you are trying to view is invalid. You may
delete this Starter Pack instead.
</Trans>
</Text>
</View>
@@ -867,7 +859,7 @@ function InvalidStarterPack({rkey}: {rkey: string}) {
<Button
variant="solid"
color="primary"
label={_(msg`Delete starter pack`)}
label={l`Delete Starter Pack`}
size="large"
style={[a.rounded_sm, a.overflow_hidden, {paddingVertical: 10}]}
disabled={isProcessing}
@@ -883,7 +875,7 @@ function InvalidStarterPack({rkey}: {rkey: string}) {
<Button
variant="solid"
color="secondary"
label={_(msg`Return to previous page`)}
label={l`Return to previous page`}
size="large"
style={[a.rounded_sm, a.overflow_hidden, {paddingVertical: 10}]}
disabled={isProcessing}
@@ -41,12 +41,12 @@ export function StepDetails() {
</View>
<View>
<TextField.LabelText>
<Trans>What do you want to call your starter pack?</Trans>
<Trans>What do you want to call your Starter Pack?</Trans>
</TextField.LabelText>
<TextField.Root>
<TextField.Input
label={
name ? _(msg`${name}'s starter pack`) : _(msg`My starter pack`)
name ? _(msg`${name}s Starter Pack`) : _(msg`My Starter Pack`)
}
value={state.name}
onChangeText={text => dispatch({type: 'SetName', name: text})}
+31 -35
View File
@@ -5,9 +5,7 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {Image} from 'expo-image'
import {AtUri} from '@atproto/syntax'
import {type ModerationOpts} from '@bsky/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Plural, Trans} from '@lingui/react/macro'
import {Plural, Trans, useLingui} from '@lingui/react/macro'
import {useNavigation} from '@react-navigation/native'
import {type NativeStackScreenProps} from '@react-navigation/native-stack'
@@ -71,7 +69,7 @@ export function Wizard({
const {currentAccount} = useSession()
const moderationOpts = useModerationOpts()
const {_} = useLingui()
const {t: l} = useLingui()
// Use targetDid if provided (from dialog), otherwise use current account
const profileDid = targetDid || currentAccount!.did
@@ -109,7 +107,7 @@ export function Wizard({
isLoadingStarterPack || isLoadingProfiles || isLoadingProfile
}
isError={isErrorStarterPack || isErrorProfiles || isErrorProfile}
errorMessage={_(msg`That starter pack could not be found.`)}
errorMessage={l`That Starter Pack could not be found.`}
/>
</Layout.Screen>
)
@@ -119,7 +117,7 @@ export function Wizard({
<ListMaybePlaceholder
isLoading={false}
isError={true}
errorMessage={_(msg`That starter pack could not be found.`)}
errorMessage={l`That Starter Pack could not be found.`}
/>
</Layout.Screen>
)
@@ -164,7 +162,7 @@ function WizardInner({
}) {
const navigation = useNavigation<NavigationProp>()
const ax = useAnalytics()
const {_} = useLingui()
const {t: l} = useLingui()
const [state, dispatch] = useWizardState()
const {currentAccount} = useSession()
@@ -182,7 +180,7 @@ function WizardInner({
const getDefaultName = () => {
const displayName = createSanitizedDisplayName(currentProfile!, true)
return _(msg`${displayName}'s Starter Pack`).slice(0, 50)
return l`${displayName}s Starter Pack`.slice(0, 50)
}
const wizardUiStrings: Record<
@@ -190,16 +188,16 @@ function WizardInner({
{header: string; nextBtn: string; subtitle?: string}
> = {
Details: {
header: _(msg`Starter Pack`),
nextBtn: _(msg`Next`),
header: l`Starter Pack`,
nextBtn: l`Next`,
},
Profiles: {
header: _(msg`Choose People`),
nextBtn: _(msg`Next`),
header: l`Choose People`,
nextBtn: l`Next`,
},
Feeds: {
header: _(msg`Choose Feeds`),
nextBtn: state.feeds.length === 0 ? _(msg`Skip`) : _(msg`Finish`),
header: l`Choose Feeds`,
nextBtn: state.feeds.length === 0 ? l`Skip` : l`Finish`,
},
}
const currUiStrings = wizardUiStrings[state.currentStep]
@@ -212,7 +210,7 @@ function WizardInner({
profilesCount: state.profiles.length,
feedsCount: state.feeds.length,
})
Image.prefetch([getStarterPackOgCard(currentProfile!.did, rkey)])
void Image.prefetch([getStarterPackOgCard(currentProfile!.did, rkey)])
dispatch({type: 'SetProcessing', processing: false})
if (fromDialog) {
@@ -241,9 +239,9 @@ function WizardInner({
const {mutate: createStarterPack} = useCreateStarterPackMutation({
onSuccess: onSuccessCreate,
onError: e => {
logger.error('Failed to create starter pack', {safeMessage: e})
logger.error('Failed to create Starter Pack', {safeMessage: e})
dispatch({type: 'SetProcessing', processing: false})
Toast.show(_(msg`Failed to create starter pack`), {
Toast.show(l`Failed to create Starter Pack`, {
type: 'error',
})
},
@@ -251,15 +249,15 @@ function WizardInner({
const {mutate: editStarterPack} = useEditStarterPackMutation({
onSuccess: onSuccessEdit,
onError: e => {
logger.error('Failed to edit starter pack', {safeMessage: e})
logger.error('Failed to edit Starter Pack', {safeMessage: e})
dispatch({type: 'SetProcessing', processing: false})
Toast.show(_(msg`Failed to create starter pack`), {
Toast.show(l`Failed to create Starter Pack`, {
type: 'error',
})
},
})
const submit = async () => {
const submit = () => {
dispatch({type: 'SetProcessing', processing: true})
if (currentStarterPack && currentListItems) {
editStarterPack({
@@ -308,8 +306,8 @@ function WizardInner({
<Layout.Center style={[a.flex_1]}>
<Layout.Header.Outer>
<Layout.Header.BackButton
label={_(msg`Back`)}
accessibilityHint={_(msg`Returns to the previous step`)}
label={l`Back`}
accessibilityHint={l`Returns to the previous step`}
onPress={evt => {
if (state.currentStep !== 'Details') {
evt.preventDefault()
@@ -324,7 +322,7 @@ function WizardInner({
</Layout.Header.Content>
{isEditEnabled ? (
<Button
label={_(msg`Edit`)}
label={l`Edit`}
color="secondary"
size="small"
onPress={editDialogControl.open}>
@@ -336,7 +334,6 @@ function WizardInner({
<Layout.Header.Slot />
)}
</Layout.Header.Outer>
<Container>
{state.currentStep === 'Details' ? (
<StepDetails />
@@ -355,7 +352,6 @@ function WizardInner({
<StepFeeds moderationOpts={moderationOpts} />
) : null}
</Container>
{state.currentStep !== 'Details' && (
<Footer onNext={onNext} nextBtnText={currUiStrings.nextBtn} />
)}
@@ -371,7 +367,7 @@ function WizardInner({
}
function Container({children}: {children: React.ReactNode}) {
const {_} = useLingui()
const {t: l} = useLingui()
const [state, dispatch] = useWizardState()
if (state.currentStep === 'Profiles' || state.currentStep === 'Feeds') {
@@ -386,7 +382,7 @@ function Container({children}: {children: React.ReactNode}) {
{state.currentStep === 'Details' && (
<>
<Button
label={_(msg`Next`)}
label={l`Next`}
variant="solid"
color="primary"
size="large"
@@ -490,7 +486,7 @@ function Footer({
<Text style={[a.font_semi_bold, textStyles]} emoji>
{getName(items[0])}{' '}
</Text>
right now! Add more people to your starter pack by searching
right now! Add more people to your Starter Pack by searching
above.
</Trans>
)
@@ -502,7 +498,7 @@ function Footer({
<Text style={[a.font_semi_bold, textStyles]} emoji>
{getName(items[1] /* [0] is self, skip it */)}{' '}
</Text>
are included in your starter pack
are included in your Starter Pack
</Trans>
) : (
<Trans>
@@ -514,7 +510,7 @@ function Footer({
<Text style={[a.font_semi_bold, textStyles]} emoji>
{getName(items[1] /* [0] is self, skip it */)}{' '}
</Text>
are included in your starter pack
are included in your Starter Pack
</Trans>
)
) : items.length > 2 ? (
@@ -531,7 +527,7 @@ function Footer({
one="# other"
other="# others"
/>{' '}
are included in your starter pack
are included in your Starter Pack
</Trans>
) : null /* Should not happen. */
}
@@ -540,7 +536,7 @@ function Footer({
items.length === 0 ? (
<View style={[a.gap_sm]}>
<Text style={[a.font_semi_bold, a.text_center, textStyles]}>
<Trans>Add some feeds to your starter pack!</Trans>
<Trans>Add some feeds to your Starter Pack!</Trans>
</Text>
<Text style={[a.text_center, textStyles]}>
<Trans>
@@ -556,7 +552,7 @@ function Footer({
<Text style={[a.font_semi_bold, textStyles]} emoji>
{getName(items[0])}
</Text>{' '}
is included in your starter pack
is included in your Starter Pack
</Trans>
) : items.length === 2 ? (
<Trans>
@@ -568,7 +564,7 @@ function Footer({
<Text style={[a.font_semi_bold, textStyles]} emoji>
{getName(items[1])}{' '}
</Text>
are included in your starter pack
are included in your Starter Pack
</Trans>
) : items.length > 2 ? (
<Trans context="feeds">
@@ -584,7 +580,7 @@ function Footer({
one="# other"
other="# others"
/>{' '}
are included in your starter pack
are included in your Starter Pack
</Trans>
) : null /* Should not happen. */
}
+3 -3
View File
@@ -25,7 +25,7 @@ export function useListMembershipAddMutation({
onError,
}: {
/**
* Needed for optimistic update of starter pack query
* Needed for optimistic update of Starter Pack query
*/
subject?: bsky.profile.AnyProfileView
onSuccess?: (data: {uri: AtUriString; cid: string}) => void
@@ -66,7 +66,7 @@ export function useListMembershipAddMutation({
})
}, 1e3)
// update WITH_MEMBERSHIPS query for starter packs
// update WITH_MEMBERSHIPS query for Starter Packs
if (subject) {
queryClient.setQueryData<
InfiniteData<app.bsky.graph.getStarterPacksWithMembership.$OutputBody>
@@ -161,7 +161,7 @@ export function useListMembershipRemoveMutation({
})
}, 1e3)
// update WITH_MEMBERSHIPS query for starter packs
// update WITH_MEMBERSHIPS query for Starter Packs
queryClient.setQueryData<
InfiniteData<app.bsky.graph.getStarterPacksWithMembership.$OutputBody>
>(STARTER_PACKS_WITH_MEMBERSHIPS_RKEY(variables.actorDid), old => {
@@ -39,7 +39,7 @@ function makeFollowNotification(
}
describe('groupNotifications', () => {
it('does not group a starter pack follow with an organic follow', () => {
it('does not group a Starter Pack follow with an organic follow', () => {
const pack = 'at://did:plc:alice/app.bsky.graph.starterpack/a'
const grouped = groupNotifications([
@@ -56,7 +56,7 @@ describe('groupNotifications', () => {
expect(grouped[1].additional).toBeUndefined()
})
it('groups follows by starter pack', () => {
it('groups follows by Starter Pack', () => {
const packA = 'at://did:plc:alice/app.bsky.graph.starterpack/a'
const packB = 'at://did:plc:bob/app.bsky.graph.starterpack/b'
+3 -3
View File
@@ -98,7 +98,7 @@ export function useReferenceListOptOutMutation({
>({
mutationFn: async ({referenceListOptOut}) => {
if (!starterPack.list) {
throw new Error('Starter pack does not have a reference list')
throw new Error('Starter Pack does not have a reference list')
}
let nextOptOut: AtUriString | undefined
@@ -292,7 +292,7 @@ export function useCreateStarterPackMutation({
})
onSuccess(data)
},
onError: async error => {
onError: error => {
onError(error)
},
})
@@ -333,7 +333,7 @@ export function useEditStarterPackMutation({
}
if (!bsky.isType(app.bsky.graph.starterpack, currentStarterPack.record)) {
throw new Error('Invalid starter pack')
throw new Error('Invalid Starter Pack')
}
const removedItems = currentListItems.filter(
+2 -2
View File
@@ -44,14 +44,14 @@ const syntheticFullView = {
list: {
uri: 'at://did:plc:abc/app.bsky.graph.list/123',
cid: '',
name: 'Starter pack',
name: 'Starter Pack',
purpose: 'app.bsky.graph.defs#referencelist',
},
}
/*
* Type-level assertions for the view alias: it must accept both the basic and
* the full starter pack view. Compile-time only - a failure surfaces as a
* the full Starter Pack view. Compile-time only - a failure surfaces as a
* typecheck error.
*/
type Assignable<From, To> = From extends To ? true : false
+2 -2
View File
@@ -26,7 +26,7 @@ export function isView(v: unknown): v is app.bsky.graph.defs.StarterPackView {
}
/**
* Accepts both forms of a full starter pack view used by the app:
* Accepts both forms of a full Starter Pack view used by the app:
*
* - direct lexicon refs returned by the app view, where `$type` may be omitted
* - trusted synthetic cache entries, which carry `$type` but may contain
@@ -39,7 +39,7 @@ export function isTrustedView(
}
/**
* Matches any starter pack view exported by our SDK.
* Matches any Starter Pack view exported by our SDK.
*/
export type AnyStarterPackView =
app.bsky.graph.defs.StarterPackViewBasic | app.bsky.graph.defs.StarterPackView
+1 -1
View File
@@ -91,7 +91,7 @@ export function LoggedOut({onDismiss}: {onDismiss?: () => void}) {
/*
* Back from the login or create-account step. Where it returns depends on how
* the view was entered:
* - Entered on the splash or a landing screen (starter pack, group chat
* - Entered on the splash or a landing screen (Starter Pack, group chat
* invite): return there, i.e. the screen the user actually saw first.
* - Dropped directly onto login/create-account (e.g. tapping "Create
* account" elsewhere in the app): there is no preceding screen in this
@@ -338,7 +338,7 @@ let NotificationFeedItem = ({
* see `src/state/queries/notifications/util.ts`
*/
a11yLabel = starterPackName
? l`${firstAuthorName} followed you back via starter pack ${starterPackName}`
? l`${firstAuthorName} followed you back via Starter Pack ${starterPackName}`
: l`${firstAuthorName} followed you back`
notificationContent = <Trans>{firstAuthorLink} followed you back</Trans>
} else {
@@ -347,8 +347,8 @@ let NotificationFeedItem = ({
? l`${firstAuthorName} and ${plural(additionalAuthorsCount, {
one: `${formattedAuthorsCount} other`,
other: `${formattedAuthorsCount} others`,
})} followed you via starter pack ${starterPackName}`
: l`${firstAuthorName} followed you via starter pack ${starterPackName}`
})} followed you via Starter Pack ${starterPackName}`
: l`${firstAuthorName} followed you via Starter Pack ${starterPackName}`
: hasMultipleAuthors
? l`${firstAuthorName} and ${plural(additionalAuthorsCount, {
one: `${formattedAuthorsCount} other`,
@@ -407,8 +407,8 @@ let NotificationFeedItem = ({
? l`${firstAuthorName} and ${plural(additionalAuthorsCount, {
one: `${formattedAuthorsCount} other`,
other: `${formattedAuthorsCount} others`,
})} signed up with your starter pack`
: l`${firstAuthorName} signed up with your starter pack`
})} signed up with your Starter Pack`
: l`${firstAuthorName} signed up with your Starter Pack`
notificationContent = hasMultipleAuthors ? (
<Trans>
{firstAuthorLink} and{' '}
@@ -419,10 +419,10 @@ let NotificationFeedItem = ({
other={`${formattedAuthorsCount} others`}
/>
</Text>{' '}
signed up with your starter pack
signed up with your Starter Pack
</Trans>
) : (
<Trans>{firstAuthorLink} signed up with your starter pack</Trans>
<Trans>{firstAuthorLink} signed up with your Starter Pack</Trans>
)
icon = (
<View style={{height: 30, width: 30}}>
@@ -735,8 +735,8 @@ function FollowedViaStarterPack({
return (
<Text style={[native(a.pt_xs), t.atoms.text_contrast_medium]}>
<Trans comment="When the source of a follow is a starter pack, i.e., 'via starter pack {starterPackName}'.">
via starter pack{' '}
<Trans comment="When the source of a follow is a Starter Pack, i.e., 'via Starter Pack {starterPackName}'.">
via Starter Pack{' '}
<StarterPackIcon
size="sm"
gradient="sky"
+2 -2
View File
@@ -365,10 +365,10 @@ let ProfileMenu = ({
)}
<Menu.Item
testID="profileHeaderDropdownStarterPackAddRemoveBtn"
label={l`Add to starter packs`}
label={l`Add to Starter Packs`}
onPress={onPressAddToStarterPacks}>
<Menu.ItemText>
<Trans>Add to starter packs</Trans>
<Trans>Add to Starter Packs</Trans>
</Menu.ItemText>
<Menu.ItemIcon icon={StarterPackIcon} />
</Menu.Item>
@@ -1,9 +1,7 @@
import {useCallback} from 'react'
import {Pressable, View} from 'react-native'
import Animated, {useAnimatedRef} from 'react-native-reanimated'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
import {Trans, useLingui} from '@lingui/react/macro'
import {useNavigation} from '@react-navigation/native'
import {usePalette} from '#/lib/hooks/usePalette'
@@ -47,7 +45,7 @@ export function ProfileSubpageHeader({
avatarType: UserAvatarType | 'starter-pack'
}>) {
const navigation = useNavigation<NavigationProp>()
const {_} = useLingui()
const {t: l} = useLingui()
const {isMobile} = useWebMediaQueries()
const {openLightbox} = useLightboxControls()
const pal = usePalette('default')
@@ -90,7 +88,6 @@ export function ProfileSubpageHeader({
<Layout.Header.Content />
{children}
</Layout.Header.Outer>
<View
style={{
flexDirection: 'row',
@@ -105,7 +102,7 @@ export function ProfileSubpageHeader({
testID="headerAviButton"
onPress={onPressAvi}
accessibilityRole="image"
accessibilityLabel={_(msg`View the avatar`)}
accessibilityLabel={l`View the avatar`}
accessibilityHint=""
style={{width: 58}}>
{avatarType === 'starter-pack' ? (
@@ -166,10 +163,10 @@ export function ProfileSubpageHeader({
)
) : purpose === 'app.bsky.graph.defs#referencelist' ? (
isOwner ? (
<Trans>Starter pack by you</Trans>
<Trans>Starter Pack by you</Trans>
) : (
<Trans>
Starter pack by{' '}
Starter Pack by{' '}
<TextLink
text={sanitizeHandle(creator.handle || '', '@')}
href={makeProfileLink(creator)}
+1 -1
View File
@@ -349,7 +349,7 @@ function ProfileScreenLoaded({
const wrappedNavToWizard = requireEmailVerification(navToWizard, {
instructions: [
<Trans key="nav">
Before creating a starter pack, you must first verify your email.
Before creating a Starter Pack, you must first verify your email.
</Trans>,
],
})