diff --git a/.eslintrc.js b/.eslintrc.js
index 8ae91f34..92834fe6 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,5 +1,3 @@
-const bskyEslint = require('./eslint')
-
module.exports = {
root: true,
extends: [
@@ -27,29 +25,18 @@ module.exports = {
{
impliedTextComponents: [
'Button', // TODO: Not always safe.
- 'ButtonText',
- 'DateField.Label',
- 'Description',
'H1',
'H2',
'H3',
'H4',
'H5',
'H6',
- 'InlineLink',
- 'Label',
'P',
- 'Prompt.Title',
- 'Prompt.Description',
'Prompt.Cancel', // TODO: Not always safe.
'Prompt.Action', // TODO: Not always safe.
- 'TextField.Label',
- 'TextField.Suffix',
- 'Title',
- 'Toggle.Label',
'ToggleButton.Button', // TODO: Not always safe.
],
- impliedTextProps: ['FormContainer title'],
+ impliedTextProps: [],
},
],
'simple-import-sort/imports': [
diff --git a/eslint/__tests__/avoid-unwrapped-text.test.js b/eslint/__tests__/avoid-unwrapped-text.test.js
index 0fbc0112..7c667b4a 100644
--- a/eslint/__tests__/avoid-unwrapped-text.test.js
+++ b/eslint/__tests__/avoid-unwrapped-text.test.js
@@ -246,6 +246,41 @@ describe('avoid-unwrapped-text', () => {
`,
},
+
+ {
+ code: `
+function Stuff() {
+ return foo
+}
+ `,
+ },
+
+ {
+ code: `
+function Stuff({ foo }) {
+ return {foo}
+}
+ `,
+ },
+
+ {
+ code: `
+function MyText() {
+ return foo
+}
+ `,
+ },
+
+ {
+ code: `
+function MyText({ foo }) {
+ if (foo) {
+ return foo
+ }
+ return foo
+}
+ `,
+ },
],
invalid: [
@@ -390,6 +425,36 @@ describe('avoid-unwrapped-text', () => {
`,
errors: 1,
},
+
+ {
+ code: `
+function MyText() {
+ return
+}
+ `,
+ errors: 1,
+ },
+
+ {
+ code: `
+function MyText({ foo }) {
+ return {foo}
+}
+ `,
+ errors: 1,
+ },
+
+ {
+ code: `
+function MyText({ foo }) {
+ if (foo) {
+ return {foo}
+ }
+ return foo
+}
+ `,
+ errors: 1,
+ },
],
}
diff --git a/eslint/avoid-unwrapped-text.js b/eslint/avoid-unwrapped-text.js
index c9e72386..79d099f0 100644
--- a/eslint/avoid-unwrapped-text.js
+++ b/eslint/avoid-unwrapped-text.js
@@ -35,6 +35,11 @@ exports.create = function create(context) {
const impliedTextComponents = options.impliedTextComponents ?? []
const textProps = [...impliedTextProps]
const textComponents = ['Text', ...impliedTextComponents]
+
+ function isTextComponent(tagName) {
+ return textComponents.includes(tagName) || tagName.endsWith('Text')
+ }
+
return {
JSXText(node) {
if (typeof node.value !== 'string' || hasOnlyLineBreak(node.value)) {
@@ -44,7 +49,7 @@ exports.create = function create(context) {
while (parent) {
if (parent.type === 'JSXElement') {
const tagName = getTagName(parent)
- if (textComponents.includes(tagName) || tagName.endsWith('Text')) {
+ if (isTextComponent(tagName)) {
// We're good.
return
}
@@ -107,5 +112,36 @@ exports.create = function create(context) {
continue
}
},
+ ReturnStatement(node) {
+ let fnScope = context.getScope()
+ while (fnScope && fnScope.type !== 'function') {
+ fnScope = fnScope.upper
+ }
+ if (!fnScope) {
+ return
+ }
+ const fn = fnScope.block
+ if (!fn.id || fn.id.type !== 'Identifier' || !fn.id.name) {
+ return
+ }
+ if (!/^[A-Z]\w*Text$/.test(fn.id.name)) {
+ return
+ }
+ if (!node.argument || node.argument.type !== 'JSXElement') {
+ return
+ }
+ const openingEl = node.argument.openingElement
+ if (openingEl.name.type !== 'JSXIdentifier') {
+ return
+ }
+ const returnedComponentName = openingEl.name.name
+ if (!isTextComponent(returnedComponentName)) {
+ context.report({
+ node,
+ message:
+ 'Components ending with *Text must return or .',
+ })
+ }
+ },
}
}
diff --git a/src/components/Link.tsx b/src/components/Link.tsx
index 1a494626..65a015ba 100644
--- a/src/components/Link.tsx
+++ b/src/components/Link.tsx
@@ -250,7 +250,7 @@ export type InlineLinkProps = React.PropsWithChildren<
BaseLinkProps & TextStyleProp & Pick
>
-export function InlineLink({
+export function InlineLinkText({
children,
to,
action = 'push',
diff --git a/src/components/Prompt.tsx b/src/components/Prompt.tsx
index 37d1b700..000d2a3c 100644
--- a/src/components/Prompt.tsx
+++ b/src/components/Prompt.tsx
@@ -51,7 +51,7 @@ export function Outer({
)
}
-export function Title({children}: React.PropsWithChildren<{}>) {
+export function TitleText({children}: React.PropsWithChildren<{}>) {
const {titleId} = React.useContext(Context)
return (
@@ -60,7 +60,7 @@ export function Title({children}: React.PropsWithChildren<{}>) {
)
}
-export function Description({children}: React.PropsWithChildren<{}>) {
+export function DescriptionText({children}: React.PropsWithChildren<{}>) {
const t = useTheme()
const {descriptionId} = React.useContext(Context)
return (
@@ -175,8 +175,8 @@ export function Basic({
}>) {
return (
- {title}
- {description}
+ {title}
+ {description}
{segment.text}
- ,
+ ,
)
} else if (link && AppBskyRichtextFacet.validateLink(link).success) {
if (disableLinks) {
els.push(toShortUrl(segment.text))
} else {
els.push(
-
{toShortUrl(segment.text)}
- ,
+ ,
)
}
} else if (
diff --git a/src/components/dialogs/MutedWords.tsx b/src/components/dialogs/MutedWords.tsx
index 46f319ad..0eced11e 100644
--- a/src/components/dialogs/MutedWords.tsx
+++ b/src/components/dialogs/MutedWords.tsx
@@ -1,37 +1,36 @@
import React from 'react'
import {Keyboard, View} from 'react-native'
+import {AppBskyActorDefs, sanitizeMutedWordValue} from '@atproto/api'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
-import {AppBskyActorDefs, sanitizeMutedWordValue} from '@atproto/api'
-import {
- usePreferencesQuery,
- useUpsertMutedWordsMutation,
- useRemoveMutedWordMutation,
-} from '#/state/queries/preferences'
+import {logger} from '#/logger'
import {isNative} from '#/platform/detection'
+import {
+ usePreferencesQuery,
+ useRemoveMutedWordMutation,
+ useUpsertMutedWordsMutation,
+} from '#/state/queries/preferences'
import {
atoms as a,
- useTheme,
+ native,
useBreakpoints,
+ useTheme,
ViewStyleProp,
web,
- native,
} from '#/alf'
-import {Text} from '#/components/Typography'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
-import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
-import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
+import * as Dialog from '#/components/Dialog'
+import {useGlobalDialogsControlContext} from '#/components/dialogs/Context'
+import {Divider} from '#/components/Divider'
+import * as Toggle from '#/components/forms/Toggle'
import {Hashtag_Stroke2_Corner0_Rounded as Hashtag} from '#/components/icons/Hashtag'
import {PageText_Stroke2_Corner0_Rounded as PageText} from '#/components/icons/PageText'
-import {Divider} from '#/components/Divider'
+import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
+import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
import {Loader} from '#/components/Loader'
-import {logger} from '#/logger'
-import * as Dialog from '#/components/Dialog'
-import * as Toggle from '#/components/forms/Toggle'
import * as Prompt from '#/components/Prompt'
-
-import {useGlobalDialogsControlContext} from '#/components/dialogs/Context'
+import {Text} from '#/components/Typography'
export function MutedWordsDialog() {
const {mutedWordsDialogControl: control} = useGlobalDialogsControlContext()
@@ -130,9 +129,9 @@ function MutedWordsInner({}: {control: Dialog.DialogOuterProps['control']}) {
-
+ Mute in text & tags
-
+
@@ -145,9 +144,9 @@ function MutedWordsInner({}: {control: Dialog.DialogOuterProps['control']}) {
-
+ Mute in tags only
-
+
diff --git a/src/components/forms/DateField/index.android.tsx b/src/components/forms/DateField/index.android.tsx
index 700d15e6..1830ca4b 100644
--- a/src/components/forms/DateField/index.android.tsx
+++ b/src/components/forms/DateField/index.android.tsx
@@ -8,7 +8,7 @@ import * as TextField from '#/components/forms/TextField'
import {DateFieldButton} from './index.shared'
export * as utils from '#/components/forms/DateField/utils'
-export const Label = TextField.Label
+export const LabelText = TextField.LabelText
export function DateField({
value,
diff --git a/src/components/forms/DateField/index.tsx b/src/components/forms/DateField/index.tsx
index 5662bb59..e231ac5b 100644
--- a/src/components/forms/DateField/index.tsx
+++ b/src/components/forms/DateField/index.tsx
@@ -13,7 +13,7 @@ import * as TextField from '#/components/forms/TextField'
import {DateFieldButton} from './index.shared'
export * as utils from '#/components/forms/DateField/utils'
-export const Label = TextField.Label
+export const LabelText = TextField.LabelText
/**
* Date-only input. Accepts a date in the format YYYY-MM-DD, and reports date
diff --git a/src/components/forms/DateField/index.web.tsx b/src/components/forms/DateField/index.web.tsx
index 982d3271..b764620e 100644
--- a/src/components/forms/DateField/index.web.tsx
+++ b/src/components/forms/DateField/index.web.tsx
@@ -9,7 +9,7 @@ import * as TextField from '#/components/forms/TextField'
import {CalendarDays_Stroke2_Corner0_Rounded as CalendarDays} from '#/components/icons/CalendarDays'
export * as utils from '#/components/forms/DateField/utils'
-export const Label = TextField.Label
+export const LabelText = TextField.LabelText
const InputBase = React.forwardRef(
({style, ...props}, ref) => {
diff --git a/src/components/forms/TextField.tsx b/src/components/forms/TextField.tsx
index 0bdeca64..73a660ea 100644
--- a/src/components/forms/TextField.tsx
+++ b/src/components/forms/TextField.tsx
@@ -225,7 +225,7 @@ export function createInput(Component: typeof TextInput) {
export const Input = createInput(TextInput)
-export function Label({
+export function LabelText({
nativeID,
children,
}: React.PropsWithChildren<{nativeID?: string}>) {
@@ -288,7 +288,7 @@ export function Icon({icon: Comp}: {icon: React.ComponentType}) {
)
}
-export function Suffix({
+export function SuffixText({
children,
label,
accessibilityHint,
diff --git a/src/components/forms/Toggle.tsx b/src/components/forms/Toggle.tsx
index 7a4b5ac9..7285e5fa 100644
--- a/src/components/forms/Toggle.tsx
+++ b/src/components/forms/Toggle.tsx
@@ -3,16 +3,16 @@ import {Pressable, View, ViewStyle} from 'react-native'
import {HITSLOP_10} from 'lib/constants'
import {
- useTheme,
atoms as a,
- native,
flatten,
- ViewStyleProp,
+ native,
TextStyleProp,
+ useTheme,
+ ViewStyleProp,
} from '#/alf'
-import {Text} from '#/components/Typography'
import {useInteractionState} from '#/components/hooks/useInteractionState'
import {CheckThick_Stroke2_Corner0_Rounded as Checkmark} from '#/components/icons/Check'
+import {Text} from '#/components/Typography'
export type ItemState = {
name: string
@@ -234,7 +234,7 @@ export function Item({
)
}
-export function Label({
+export function LabelText({
children,
style,
}: React.PropsWithChildren) {
diff --git a/src/components/moderation/LabelPreference.tsx b/src/components/moderation/LabelPreference.tsx
index 028bd1a3..990e7362 100644
--- a/src/components/moderation/LabelPreference.tsx
+++ b/src/components/moderation/LabelPreference.tsx
@@ -13,7 +13,7 @@ import {
} from '#/state/queries/preferences'
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
import * as ToggleButton from '#/components/forms/ToggleButton'
-import {InlineLink} from '#/components/Link'
+import {InlineLinkText} from '#/components/Link'
import {Text} from '#/components/Typography'
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '../icons/CircleInfo'
@@ -243,9 +243,9 @@ export function LabelerLabelPreference({
) : isGlobalLabel ? (
Configured in{' '}
-
+
moderation settings
-
+
.
) : null}
diff --git a/src/components/moderation/LabelsOnMeDialog.tsx b/src/components/moderation/LabelsOnMeDialog.tsx
index 6eddbc7c..95e3d242 100644
--- a/src/components/moderation/LabelsOnMeDialog.tsx
+++ b/src/components/moderation/LabelsOnMeDialog.tsx
@@ -1,20 +1,19 @@
import React from 'react'
import {View} from 'react-native'
+import {ComAtprotoLabelDefs, ComAtprotoModerationDefs} from '@atproto/api'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
-import {ComAtprotoLabelDefs, ComAtprotoModerationDefs} from '@atproto/api'
import {useLabelInfo} from '#/lib/moderation/useLabelInfo'
import {makeProfileLink} from '#/lib/routes/links'
import {sanitizeHandle} from '#/lib/strings/handles'
import {getAgent} from '#/state/session'
-
-import {atoms as a, useBreakpoints, useTheme} from '#/alf'
-import {Text} from '#/components/Typography'
-import * as Dialog from '#/components/Dialog'
-import {Button, ButtonText} from '#/components/Button'
-import {InlineLink} from '#/components/Link'
import * as Toast from '#/view/com/util/Toast'
+import {atoms as a, useBreakpoints, useTheme} from '#/alf'
+import {Button, ButtonText} from '#/components/Button'
+import * as Dialog from '#/components/Dialog'
+import {InlineLinkText} from '#/components/Link'
+import {Text} from '#/components/Typography'
import {Divider} from '../Divider'
export {useDialogControl as useLabelsOnMeDialogControl} from '#/components/Dialog'
@@ -145,13 +144,13 @@ function Label({
Source:{' '}
- control.close()}>
{labeler ? sanitizeHandle(labeler.creator.handle, '@') : label.src}
-
+
@@ -204,14 +203,14 @@ function AppealForm({
This appeal will be sent to{' '}
- control.close()}
style={[a.text_md, a.leading_snug]}>
{labeler ? sanitizeHandle(labeler.creator.handle, '@') : label.src}
-
+
.
diff --git a/src/components/moderation/ModerationDetailsDialog.tsx b/src/components/moderation/ModerationDetailsDialog.tsx
index da490cb4..da57de4d 100644
--- a/src/components/moderation/ModerationDetailsDialog.tsx
+++ b/src/components/moderation/ModerationDetailsDialog.tsx
@@ -1,19 +1,18 @@
import React from 'react'
import {View} from 'react-native'
+import {ModerationCause} from '@atproto/api'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
-import {ModerationCause} from '@atproto/api'
-import {listUriToHref} from '#/lib/strings/url-helpers'
import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
import {makeProfileLink} from '#/lib/routes/links'
-
+import {listUriToHref} from '#/lib/strings/url-helpers'
import {isNative} from '#/platform/detection'
-import {useTheme, atoms as a} from '#/alf'
-import {Text} from '#/components/Typography'
+import {atoms as a, useTheme} from '#/alf'
import * as Dialog from '#/components/Dialog'
-import {InlineLink} from '#/components/Link'
import {Divider} from '#/components/Divider'
+import {InlineLinkText} from '#/components/Link'
+import {Text} from '#/components/Typography'
export {useDialogControl as useModerationDetailsDialogControl} from '#/components/Dialog'
@@ -55,9 +54,9 @@ function ModerationDetailsDialogInner({
description = (
This user is included in the{' '}
-
+
{list.name}
- {' '}
+ {' '}
list which you have blocked.
)
@@ -84,9 +83,9 @@ function ModerationDetailsDialogInner({
description = (
This user is included in the{' '}
-
+
{list.name}
- {' '}
+ {' '}
list which you have muted.
)
@@ -127,12 +126,12 @@ function ModerationDetailsDialogInner({
{modcause.source.type === 'user' ? (
the author
) : (
- control.close()}
style={a.text_md}>
{desc.source}
-
+
)}
.
diff --git a/src/screens/Login/ChooseAccountForm.tsx b/src/screens/Login/ChooseAccountForm.tsx
index 15c06dbe..01eca187 100644
--- a/src/screens/Login/ChooseAccountForm.tsx
+++ b/src/screens/Login/ChooseAccountForm.tsx
@@ -58,11 +58,11 @@ export const ChooseAccountForm = ({
return (
Select account}>
+ titleText={Select account}>
-
+ Sign in as...
-
+
onSelectAccount()}
diff --git a/src/screens/Login/ForgotPasswordForm.tsx b/src/screens/Login/ForgotPasswordForm.tsx
index 580452e7..ec30bab4 100644
--- a/src/screens/Login/ForgotPasswordForm.tsx
+++ b/src/screens/Login/ForgotPasswordForm.tsx
@@ -83,11 +83,11 @@ export const ForgotPasswordForm = ({
return (
Reset password}>
+ titleText={Reset password}>
-
+ Hosting provider
-
+
-
+ Email address
-
+
}) {
@@ -21,9 +21,9 @@ export function FormContainer({
- {title && !gtMobile && (
+ {titleText && !gtMobile && (
- {title}
+ {titleText}
)}
{children}
diff --git a/src/screens/Login/LoginForm.tsx b/src/screens/Login/LoginForm.tsx
index 6bf215ee..6b1340b9 100644
--- a/src/screens/Login/LoginForm.tsx
+++ b/src/screens/Login/LoginForm.tsx
@@ -128,11 +128,11 @@ export const LoginForm = ({
const isReady = !!serviceDescription && !!identifier && !!password
return (
- Sign in}>
+ Sign in}>
-
+ Hosting provider
-
+
-
+ Account
-
+
diff --git a/src/screens/Login/SetNewPasswordForm.tsx b/src/screens/Login/SetNewPasswordForm.tsx
index e7b48865..88f7ec54 100644
--- a/src/screens/Login/SetNewPasswordForm.tsx
+++ b/src/screens/Login/SetNewPasswordForm.tsx
@@ -99,7 +99,7 @@ export const SetNewPasswordForm = ({
return (
Set new password}>
+ titleText={Set new password}>
You will receive an email with a "reset code." Enter that code here,
@@ -108,7 +108,7 @@ export const SetNewPasswordForm = ({
- Reset code
+ Reset code
- New password
+ New password
-
+
Discourage apps from showing my account to logged-out users
-
+
{updateProfile.isPending && }
@@ -545,9 +545,9 @@ function PwiOptOut() {
-
+ Learn more about what is public on Bluesky.
-
+
)
diff --git a/src/screens/Onboarding/Layout.tsx b/src/screens/Onboarding/Layout.tsx
index 6337cee0..cfaf20ff 100644
--- a/src/screens/Onboarding/Layout.tsx
+++ b/src/screens/Onboarding/Layout.tsx
@@ -1,29 +1,27 @@
import React from 'react'
import {View} from 'react-native'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
-import {useLingui} from '@lingui/react'
import {msg} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
-import {IS_DEV} from '#/env'
import {isWeb} from '#/platform/detection'
import {useOnboardingDispatch} from '#/state/shell'
-
-import {
- useTheme,
- atoms as a,
- useBreakpoints,
- web,
- native,
- flatten,
- TextStyleProp,
-} from '#/alf'
-import {P, leading, Text} from '#/components/Typography'
-import {ChevronLeft_Stroke2_Corner0_Rounded as ChevronLeft} from '#/components/icons/Chevron'
-import {Button, ButtonIcon} from '#/components/Button'
import {ScrollView} from '#/view/com/util/Views'
-import {createPortalGroup} from '#/components/Portal'
-
import {Context} from '#/screens/Onboarding/state'
+import {
+ atoms as a,
+ flatten,
+ native,
+ TextStyleProp,
+ useBreakpoints,
+ useTheme,
+ web,
+} from '#/alf'
+import {Button, ButtonIcon} from '#/components/Button'
+import {ChevronLeft_Stroke2_Corner0_Rounded as ChevronLeft} from '#/components/icons/Chevron'
+import {createPortalGroup} from '#/components/Portal'
+import {leading, P, Text} from '#/components/Typography'
+import {IS_DEV} from '#/env'
const COL_WIDTH = 500
@@ -204,7 +202,7 @@ export function Layout({children}: React.PropsWithChildren<{}>) {
)
}
-export function Title({
+export function TitleText({
children,
style,
}: React.PropsWithChildren) {
@@ -224,7 +222,7 @@ export function Title({
)
}
-export function Description({
+export function DescriptionText({
children,
style,
}: React.PropsWithChildren) {
diff --git a/src/screens/Onboarding/StepAlgoFeeds/index.tsx b/src/screens/Onboarding/StepAlgoFeeds/index.tsx
index 35f525ef..4ba61696 100644
--- a/src/screens/Onboarding/StepAlgoFeeds/index.tsx
+++ b/src/screens/Onboarding/StepAlgoFeeds/index.tsx
@@ -6,9 +6,9 @@ import {useLingui} from '@lingui/react'
import {useAnalytics} from '#/lib/analytics/analytics'
import {logEvent} from '#/lib/statsig/statsig'
import {
- Description,
+ DescriptionText,
OnboardingControls,
- Title,
+ TitleText,
} from '#/screens/Onboarding/Layout'
import {Context} from '#/screens/Onboarding/state'
import {FeedCard} from '#/screens/Onboarding/StepAlgoFeeds/FeedCard'
@@ -105,15 +105,15 @@ export function StepAlgoFeeds() {
-
+ Choose your main feeds
-
-
+
+
Custom feeds built by the community bring you new experiences and help
you find the content you love.
-
+
-
+ You're ready to go!
-
-
+
+ We hope you have a wonderful time. Remember, Bluesky is:
-
+
diff --git a/src/screens/Onboarding/StepFollowingFeed.tsx b/src/screens/Onboarding/StepFollowingFeed.tsx
index e886a089..a1c7299f 100644
--- a/src/screens/Onboarding/StepFollowingFeed.tsx
+++ b/src/screens/Onboarding/StepFollowingFeed.tsx
@@ -10,9 +10,9 @@ import {
useSetFeedViewPreferencesMutation,
} from 'state/queries/preferences'
import {
- Description,
+ DescriptionText,
OnboardingControls,
- Title,
+ TitleText,
} from '#/screens/Onboarding/Layout'
import {Context} from '#/screens/Onboarding/state'
import {atoms as a} from '#/alf'
@@ -58,12 +58,12 @@ export function StepFollowingFeed() {
-
+ Your default feed is "Following"
-
-
+
+ It shows posts from the people you follow as they happen.
-
+
-
+ You can change these settings later.
-
+
- {title}
- {description}
+ {title}
+ {description}
{isLoading ? (
diff --git a/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx b/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx
index 9e59c1db..7563bece 100644
--- a/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx
+++ b/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx
@@ -113,15 +113,15 @@ export function AdultContentEnabledPref({
)}
-
+ Adult Content
-
-
+
+
Due to Apple policies, adult content can only be enabled on the web
after completing sign up.
-
+
prompt.close()} cta={_(msg`OK`)} />
diff --git a/src/screens/Onboarding/StepModeration/index.tsx b/src/screens/Onboarding/StepModeration/index.tsx
index c5bdf562..d494f48d 100644
--- a/src/screens/Onboarding/StepModeration/index.tsx
+++ b/src/screens/Onboarding/StepModeration/index.tsx
@@ -9,9 +9,9 @@ import {logEvent} from '#/lib/statsig/statsig'
import {usePreferencesQuery} from '#/state/queries/preferences'
import {usePreferencesSetAdultContentMutation} from 'state/queries/preferences'
import {
- Description,
+ DescriptionText,
OnboardingControls,
- Title,
+ TitleText,
} from '#/screens/Onboarding/Layout'
import {Context} from '#/screens/Onboarding/state'
import {AdultContentEnabledPref} from '#/screens/Onboarding/StepModeration/AdultContentEnabledPref'
@@ -56,14 +56,14 @@ export function StepModeration() {
-
+ You're in control
-
-
+
+
Select what you want to see (or not see), and we’ll handle the rest.
-
+
{!preferences ? (
diff --git a/src/screens/Onboarding/StepSuggestedAccounts/index.tsx b/src/screens/Onboarding/StepSuggestedAccounts/index.tsx
index 2e616136..e9bc3f0f 100644
--- a/src/screens/Onboarding/StepSuggestedAccounts/index.tsx
+++ b/src/screens/Onboarding/StepSuggestedAccounts/index.tsx
@@ -10,9 +10,9 @@ import {capitalize} from '#/lib/strings/capitalize'
import {useModerationOpts} from '#/state/queries/preferences'
import {useProfilesQuery} from '#/state/queries/profile'
import {
- Description,
+ DescriptionText,
OnboardingControls,
- Title,
+ TitleText,
} from '#/screens/Onboarding/Layout'
import {Context} from '#/screens/Onboarding/state'
import {
@@ -136,16 +136,16 @@ export function StepSuggestedAccounts() {
-
+ Here are some accounts for you to follow
-
-
+
+
{state.interestsStepResults.selectedInterests.length ? (
Based on your interest in {interestsText}
) : (
These are popular accounts you might like:
)}
-
+
{isLoading ? (
diff --git a/src/screens/Onboarding/StepTopicalFeeds.tsx b/src/screens/Onboarding/StepTopicalFeeds.tsx
index 26b1c243..bfc9e91d 100644
--- a/src/screens/Onboarding/StepTopicalFeeds.tsx
+++ b/src/screens/Onboarding/StepTopicalFeeds.tsx
@@ -9,9 +9,9 @@ import {capitalize} from '#/lib/strings/capitalize'
import {IS_TEST_USER} from 'lib/constants'
import {useSession} from 'state/session'
import {
- Description,
+ DescriptionText,
OnboardingControls,
- Title,
+ TitleText,
} from '#/screens/Onboarding/Layout'
import {Context} from '#/screens/Onboarding/state'
import {FeedCard} from '#/screens/Onboarding/StepAlgoFeeds/FeedCard'
@@ -76,10 +76,10 @@ export function StepTopicalFeeds() {
-
+ Feeds can be topical as well!
-
-
+
+
{state.interestsStepResults.selectedInterests.length ? (
Here are some topical feeds based on your interests: {interestsText}
@@ -91,7 +91,7 @@ export function StepTopicalFeeds() {
many as you like.
)}
-
+
-
{pluralizedFollowers}
-
-
+
-
+
{formatCount(profile.postsCount || 0)}{' '}
diff --git a/src/screens/Profile/Header/ProfileHeaderLabeler.tsx b/src/screens/Profile/Header/ProfileHeaderLabeler.tsx
index d8720c91..4d8dbad8 100644
--- a/src/screens/Profile/Header/ProfileHeaderLabeler.tsx
+++ b/src/screens/Profile/Header/ProfileHeaderLabeler.tsx
@@ -316,13 +316,13 @@ function CantSubscribePrompt({
const {_} = useLingui()
return (
- Unable to subscribe
-
+ Unable to subscribe
+
We're sorry! You can only subscribe to ten labelers, and you've
reached your limit of ten.
-
+
diff --git a/src/screens/Signup/StepInfo/Policies.tsx b/src/screens/Signup/StepInfo/Policies.tsx
index 4879ae7b..f25bda27 100644
--- a/src/screens/Signup/StepInfo/Policies.tsx
+++ b/src/screens/Signup/StepInfo/Policies.tsx
@@ -6,7 +6,7 @@ import {useLingui} from '@lingui/react'
import {atoms as a, useTheme} from '#/alf'
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
-import {InlineLink} from '#/components/Link'
+import {InlineLinkText} from '#/components/Link'
import {Text} from '#/components/Typography'
export const Policies = ({
@@ -45,16 +45,16 @@ export const Policies = ({
const els = []
if (tos) {
els.push(
-
+
{_(msg`Terms of Service`)}
- ,
+ ,
)
}
if (pp) {
els.push(
-
+
{_(msg`Privacy Policy`)}
- ,
+ ,
)
}
if (els.length === 2) {
diff --git a/src/screens/Signup/StepInfo/index.tsx b/src/screens/Signup/StepInfo/index.tsx
index 136592a0..d22d1323 100644
--- a/src/screens/Signup/StepInfo/index.tsx
+++ b/src/screens/Signup/StepInfo/index.tsx
@@ -36,9 +36,9 @@ export function StepInfo() {
-
+ Hosting provider
-
+
@@ -54,9 +54,9 @@ export function StepInfo() {
<>
{state.serviceDescription.inviteCodeRequired && (
-
+ Invite code
-
+
)}
-
+ Email
-
+
-
+ Password
-
+
-
+ Your birth date
-
+
void}) {
@@ -215,9 +215,9 @@ export function Signup({onPressBack}: {onPressBack: () => void}) {
Having trouble?{' '}
-
+ Contact support
-
+
diff --git a/src/view/com/auth/SplashScreen.web.tsx b/src/view/com/auth/SplashScreen.web.tsx
index cdb72cc0..7a2ee16c 100644
--- a/src/view/com/auth/SplashScreen.web.tsx
+++ b/src/view/com/auth/SplashScreen.web.tsx
@@ -14,7 +14,7 @@ import {ErrorBoundary} from 'view/com/util/ErrorBoundary'
import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonText} from '#/components/Button'
import {ChevronBottom_Stroke2_Corner0_Rounded as ChevronDown} from '#/components/icons/Chevron'
-import {InlineLink} from '#/components/Link'
+import {InlineLinkText} from '#/components/Link'
import {Text} from '#/components/Typography'
import {CenteredView} from '../util/Views'
@@ -162,15 +162,15 @@ function Footer() {
a.flex_1,
t.atoms.border_contrast_medium,
]}>
-
+ Business
-
-
+
+ Blog
-
-
+
+ Jobs
-
+
diff --git a/src/view/com/auth/server-input/index.tsx b/src/view/com/auth/server-input/index.tsx
index b26ac1dc..8aa23c26 100644
--- a/src/view/com/auth/server-input/index.tsx
+++ b/src/view/com/auth/server-input/index.tsx
@@ -1,17 +1,17 @@
import React from 'react'
import {View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
-import {Trans, msg} from '@lingui/macro'
-import {BSKY_SERVICE} from 'lib/constants'
-import * as persisted from '#/state/persisted'
+import * as persisted from '#/state/persisted'
+import {BSKY_SERVICE} from 'lib/constants'
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
-import * as Dialog from '#/components/Dialog'
-import {Text, P} from '#/components/Typography'
import {Button, ButtonText} from '#/components/Button'
-import * as ToggleButton from '#/components/forms/ToggleButton'
+import * as Dialog from '#/components/Dialog'
import * as TextField from '#/components/forms/TextField'
+import * as ToggleButton from '#/components/forms/ToggleButton'
import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe'
+import {P, Text} from '#/components/Typography'
export function ServerInputDialog({
control,
@@ -106,9 +106,9 @@ export function ServerInputDialog({
a.px_md,
a.py_md,
]}>
-
+ Server address
-
+
- {labelValue}
+ {labelValue}
)
})}
@@ -330,7 +330,7 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
disabled={isSelfLabel}
style={isSelfLabel ? {opacity: 0.5} : undefined}>
- Custom label
+ Custom label
@@ -358,23 +358,23 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
- Target is me
+ Target is me
- Following target
+ Following target
- Self label
+ Self label
- Adult disabled
+ Adult disabled
- Logged out
+ Logged out
@@ -400,15 +400,15 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
]}>
- Hide
+ Hide
- Warn
+ Warn
- Ignore
+ Ignore
@@ -446,19 +446,19 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
- Account
+ Account
- Profile
+ Profile
- Post
+ Post
- Embed
+ Embed
@@ -623,15 +623,15 @@ function CustomLabelForm({
- Content
+ Content
- Media
+ Media
- None
+ None
@@ -658,15 +658,15 @@ function CustomLabelForm({
- Alert
+ Alert
- Inform
+ Inform
- None
+ None
diff --git a/src/view/screens/ProfileFeed.tsx b/src/view/screens/ProfileFeed.tsx
index 8eeeb5d9..4560e14e 100644
--- a/src/view/screens/ProfileFeed.tsx
+++ b/src/view/screens/ProfileFeed.tsx
@@ -1,70 +1,71 @@
-import React, {useMemo, useCallback} from 'react'
-import {StyleSheet, View, Pressable} from 'react-native'
-import {NativeStackScreenProps} from '@react-navigation/native-stack'
-import {useIsFocused, useNavigation} from '@react-navigation/native'
-import {useQueryClient} from '@tanstack/react-query'
-import {usePalette} from 'lib/hooks/usePalette'
-import {CommonNavigatorParams} from 'lib/routes/types'
-import {makeRecordUri} from 'lib/strings/url-helpers'
-import {s} from 'lib/styles'
-import {FeedDescriptor} from '#/state/queries/post-feed'
-import {PagerWithHeader} from 'view/com/pager/PagerWithHeader'
-import {ProfileSubpageHeader} from 'view/com/profile/ProfileSubpageHeader'
-import {Feed} from 'view/com/posts/Feed'
-import {InlineLink} from '#/components/Link'
-import {ListRef} from 'view/com/util/List'
-import {Button} from 'view/com/util/forms/Button'
-import {Text} from 'view/com/util/text/Text'
-import {RichText} from '#/components/RichText'
-import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
-import {FAB} from 'view/com/util/fab/FAB'
-import {EmptyState} from 'view/com/util/EmptyState'
-import {LoadingScreen} from 'view/com/util/LoadingScreen'
-import * as Toast from 'view/com/util/Toast'
-import {useSetTitle} from 'lib/hooks/useSetTitle'
-import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
-import {shareUrl} from 'lib/sharing'
-import {toShareUrl} from 'lib/strings/url-helpers'
-import {Haptics} from 'lib/haptics'
-import {useAnalytics} from 'lib/analytics/analytics'
-import {makeCustomFeedLink} from 'lib/routes/links'
-import {pluralize} from 'lib/strings/helpers'
-import {CenteredView} from 'view/com/util/Views'
-import {NavigationProp} from 'lib/routes/types'
-import {ComposeIcon2} from 'lib/icons'
-import {logger} from '#/logger'
-import {Trans, msg} from '@lingui/macro'
+import React, {useCallback, useMemo} from 'react'
+import {Pressable, StyleSheet, View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
-import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog'
-import {useFeedSourceInfoQuery, FeedSourceFeedInfo} from '#/state/queries/feed'
-import {useResolveUriQuery} from '#/state/queries/resolve-uri'
-import {
- UsePreferencesQueryResponse,
- usePreferencesQuery,
- useSaveFeedMutation,
- useRemoveFeedMutation,
- usePinFeedMutation,
- useUnpinFeedMutation,
-} from '#/state/queries/preferences'
-import {useSession} from '#/state/session'
-import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like'
-import {useComposerControls} from '#/state/shell/composer'
-import {truncateAndInvalidate} from '#/state/queries/util'
+import {useIsFocused, useNavigation} from '@react-navigation/native'
+import {NativeStackScreenProps} from '@react-navigation/native-stack'
+import {useQueryClient} from '@tanstack/react-query'
+
+import {HITSLOP_20} from '#/lib/constants'
+import {logger} from '#/logger'
import {isNative} from '#/platform/detection'
import {listenSoftReset} from '#/state/events'
-import {atoms as a, useTheme} from '#/alf'
-import * as Menu from '#/components/Menu'
-import {HITSLOP_20} from '#/lib/constants'
-import {DotGrid_Stroke2_Corner0_Rounded as Ellipsis} from '#/components/icons/DotGrid'
-import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash'
-import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
-import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
-import {ArrowOutOfBox_Stroke2_Corner0_Rounded as Share} from '#/components/icons/ArrowOutOfBox'
+import {FeedSourceFeedInfo, useFeedSourceInfoQuery} from '#/state/queries/feed'
+import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like'
+import {FeedDescriptor} from '#/state/queries/post-feed'
+import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
import {
- Heart2_Stroke2_Corner0_Rounded as HeartOutline,
- Heart2_Filled_Stroke2_Corner0_Rounded as HeartFilled,
-} from '#/components/icons/Heart2'
+ usePinFeedMutation,
+ usePreferencesQuery,
+ UsePreferencesQueryResponse,
+ useRemoveFeedMutation,
+ useSaveFeedMutation,
+ useUnpinFeedMutation,
+} from '#/state/queries/preferences'
+import {useResolveUriQuery} from '#/state/queries/resolve-uri'
+import {truncateAndInvalidate} from '#/state/queries/util'
+import {useSession} from '#/state/session'
+import {useComposerControls} from '#/state/shell/composer'
+import {useAnalytics} from 'lib/analytics/analytics'
+import {Haptics} from 'lib/haptics'
+import {usePalette} from 'lib/hooks/usePalette'
+import {useSetTitle} from 'lib/hooks/useSetTitle'
+import {ComposeIcon2} from 'lib/icons'
+import {makeCustomFeedLink} from 'lib/routes/links'
+import {CommonNavigatorParams} from 'lib/routes/types'
+import {NavigationProp} from 'lib/routes/types'
+import {shareUrl} from 'lib/sharing'
+import {pluralize} from 'lib/strings/helpers'
+import {makeRecordUri} from 'lib/strings/url-helpers'
+import {toShareUrl} from 'lib/strings/url-helpers'
+import {s} from 'lib/styles'
+import {PagerWithHeader} from 'view/com/pager/PagerWithHeader'
+import {Feed} from 'view/com/posts/Feed'
+import {ProfileSubpageHeader} from 'view/com/profile/ProfileSubpageHeader'
+import {EmptyState} from 'view/com/util/EmptyState'
+import {FAB} from 'view/com/util/fab/FAB'
+import {Button} from 'view/com/util/forms/Button'
+import {ListRef} from 'view/com/util/List'
+import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
+import {LoadingScreen} from 'view/com/util/LoadingScreen'
+import {Text} from 'view/com/util/text/Text'
+import * as Toast from 'view/com/util/Toast'
+import {CenteredView} from 'view/com/util/Views'
+import {atoms as a, useTheme} from '#/alf'
import {Button as NewButton, ButtonText} from '#/components/Button'
+import {ArrowOutOfBox_Stroke2_Corner0_Rounded as Share} from '#/components/icons/ArrowOutOfBox'
+import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
+import {DotGrid_Stroke2_Corner0_Rounded as Ellipsis} from '#/components/icons/DotGrid'
+import {
+ Heart2_Filled_Stroke2_Corner0_Rounded as HeartFilled,
+ Heart2_Stroke2_Corner0_Rounded as HeartOutline,
+} from '#/components/icons/Heart2'
+import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
+import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash'
+import {InlineLinkText} from '#/components/Link'
+import * as Menu from '#/components/Menu'
+import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog'
+import {RichText} from '#/components/RichText'
const SECTION_TITLES = ['Posts']
@@ -580,12 +581,12 @@ function AboutSection({
)}
{typeof likeCount === 'number' && (
-
{_(msg`Liked by ${likeCount} ${pluralize(likeCount, 'user')}`)}
-
+
)}
diff --git a/src/view/screens/Settings/ExportCarDialog.tsx b/src/view/screens/Settings/ExportCarDialog.tsx
index ba8fad2d..3ec37e85 100644
--- a/src/view/screens/Settings/ExportCarDialog.tsx
+++ b/src/view/screens/Settings/ExportCarDialog.tsx
@@ -1,14 +1,14 @@
import React from 'react'
import {View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
-import {Trans, msg} from '@lingui/macro'
-import {atoms as a, useBreakpoints, useTheme} from '#/alf'
-import * as Dialog from '#/components/Dialog'
-import {Text, P} from '#/components/Typography'
-import {Button, ButtonText} from '#/components/Button'
-import {InlineLink, Link} from '#/components/Link'
import {getAgent, useSession} from '#/state/session'
+import {atoms as a, useBreakpoints, useTheme} from '#/alf'
+import {Button, ButtonText} from '#/components/Button'
+import * as Dialog from '#/components/Dialog'
+import {InlineLinkText, Link} from '#/components/Link'
+import {P, Text} from '#/components/Typography'
export function ExportCarDialog({
control,
@@ -75,11 +75,11 @@ export function ExportCarDialog({
This feature is in beta. You can read more about repository
exports in{' '}
-
this blogpost
-
+
.
diff --git a/src/view/screens/Storybook/Dialogs.tsx b/src/view/screens/Storybook/Dialogs.tsx
index c2eaf19a..41863bd9 100644
--- a/src/view/screens/Storybook/Dialogs.tsx
+++ b/src/view/screens/Storybook/Dialogs.tsx
@@ -1,12 +1,12 @@
import React from 'react'
import {View} from 'react-native'
+import {useDialogStateControlContext} from '#/state/dialogs'
import {atoms as a} from '#/alf'
import {Button} from '#/components/Button'
-import {H3, P} from '#/components/Typography'
import * as Dialog from '#/components/Dialog'
import * as Prompt from '#/components/Prompt'
-import {useDialogStateControlContext} from '#/state/dialogs'
+import {H3, P} from '#/components/Typography'
export function Dialogs() {
const scrollable = Dialog.useDialogControl()
@@ -61,11 +61,11 @@ export function Dialogs() {
- This is a prompt
-
+ This is a prompt
+
This is a generic prompt component. It accepts a title and a
description, as well as two actions.
-
+
Cancel {}}>Confirm
diff --git a/src/view/screens/Storybook/Forms.tsx b/src/view/screens/Storybook/Forms.tsx
index 2d5495d7..182eacfd 100644
--- a/src/view/screens/Storybook/Forms.tsx
+++ b/src/view/screens/Storybook/Forms.tsx
@@ -2,13 +2,13 @@ import React from 'react'
import {View} from 'react-native'
import {atoms as a} from '#/alf'
-import {H1, H3} from '#/components/Typography'
+import {Button} from '#/components/Button'
+import {DateField, LabelText} from '#/components/forms/DateField'
import * as TextField from '#/components/forms/TextField'
-import {DateField, Label} from '#/components/forms/DateField'
import * as Toggle from '#/components/forms/Toggle'
import * as ToggleButton from '#/components/forms/ToggleButton'
-import {Button} from '#/components/Button'
import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe'
+import {H1, H3} from '#/components/Typography'
export function Forms() {
const [toggleGroupAValues, setToggleGroupAValues] = React.useState(['a'])
@@ -42,7 +42,7 @@ export function Forms() {
- Text field
+ Text field
- @gmail.com
+
+ @gmail.com
+
- Textarea
+ TextareaDateField
-
+ Date
- Uncontrolled toggle
+ Uncontrolled toggle
- Click me
+ Click me
- Click me
+ Click me
- Click me
+ Click me
- Click me
+ Click me
- Click me
+ Click me
@@ -128,23 +130,23 @@ export function Forms() {
- Click me
+ Click me
- Click me
+ Click me
- Click me
+ Click me
- Click me
+ Click me
- Click me
+ Click me
@@ -157,23 +159,23 @@ export function Forms() {
- Click me
+ Click me
- Click me
+ Click me
- Click me
+ Click me
- Click me
+ Click me
- Click me
+ Click me
diff --git a/src/view/screens/Storybook/Links.tsx b/src/view/screens/Storybook/Links.tsx
index f9ecfba5..d35db79b 100644
--- a/src/view/screens/Storybook/Links.tsx
+++ b/src/view/screens/Storybook/Links.tsx
@@ -1,9 +1,9 @@
import React from 'react'
import {View} from 'react-native'
-import {useTheme, atoms as a} from '#/alf'
+import {atoms as a, useTheme} from '#/alf'
import {ButtonText} from '#/components/Button'
-import {InlineLink, Link} from '#/components/Link'
+import {InlineLinkText, Link} from '#/components/Link'
import {H1, Text} from '#/components/Typography'
export function Links() {
@@ -13,20 +13,22 @@ export function Links() {