diff --git a/src/view/shell/bottom-bar/BottomBar.tsx b/src/view/shell/bottom-bar/BottomBar.tsx index c3fc5827a..b404a8f38 100644 --- a/src/view/shell/bottom-bar/BottomBar.tsx +++ b/src/view/shell/bottom-bar/BottomBar.tsx @@ -418,7 +418,7 @@ function Btn({ a.rounded_full, {backgroundColor: t.palette.primary_500}, ]}> - 1 + {notificationCount} ) : hasNew ? ( -- 2.51.2 From da87515d0ae5e22827243e18c3e2adc2d9ccb9fc Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Mon, 15 Dec 2025 13:35:28 -0600 Subject: [PATCH 02/13] [APP-1684] Some contact import tweaks (#9555) * Handle download link * Improve NUX geo gating from #9549 * Fix alignment of phone code select * Show full name * Add gate to nux banner * Add gate to settings screen * Invert gate check in settings, whoops --- .../InternationalPhoneCodeSelect.tsx | 3 +- .../contacts/FindContactsBannerNUX.tsx | 10 +++-- src/components/contacts/country-allowlist.ts | 18 ++++---- .../contacts/screens/ViewMatches.tsx | 6 +-- .../dialogs/nuxs/FindContactsAnnouncement.tsx | 31 ++++++++----- src/components/dialogs/nuxs/index.tsx | 38 +++++++--------- src/components/dialogs/nuxs/utils.ts | 21 +++++++++ src/lib/statsig/gates.ts | 1 + src/routes.ts | 2 +- src/screens/Settings/Settings.tsx | 24 +++++----- src/view/screens/Storybook/Forms.tsx | 44 +++++++++++++++++++ 11 files changed, 138 insertions(+), 60 deletions(-) diff --git a/src/components/InternationalPhoneCodeSelect.tsx b/src/components/InternationalPhoneCodeSelect.tsx index 0cfd4d6b5..57d362ff6 100644 --- a/src/components/InternationalPhoneCodeSelect.tsx +++ b/src/components/InternationalPhoneCodeSelect.tsx @@ -1,4 +1,5 @@ import {Fragment, useMemo} from 'react' +import {Text as RNText} from 'react-native' import {Image} from 'expo-image' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' @@ -113,5 +114,5 @@ function Flag({unicodeFlag, svgFlag}: {unicodeFlag: string; svgFlag: any}) { /> ) } - return unicodeFlag + ' ' + return {unicodeFlag + ' '} } diff --git a/src/components/contacts/FindContactsBannerNUX.tsx b/src/components/contacts/FindContactsBannerNUX.tsx index d2b2d1d3d..e08cf2edd 100644 --- a/src/components/contacts/FindContactsBannerNUX.tsx +++ b/src/components/contacts/FindContactsBannerNUX.tsx @@ -6,6 +6,7 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {HITSLOP_10} from '#/lib/constants' +import {useGate} from '#/lib/statsig/statsig' import {logger} from '#/logger' import {isWeb} from '#/platform/detection' import {Nux, useNux, useSaveNux} from '#/state/queries/nuxs' @@ -20,9 +21,8 @@ export function FindContactsBannerNUX() { const t = useTheme() const {_} = useLingui() const {visible, close} = useInternalState() - const isFeatureEnabled = useIsFindContactsFeatureEnabledBasedOnGeolocation() - if (!visible || !isFeatureEnabled) return null + if (!visible) return null return ( @@ -88,13 +88,17 @@ function useInternalState() { const {nux} = useNux(Nux.FindContactsDismissibleBanner) const {mutate: save, variables} = useSaveNux() const hidden = !!variables + const isFeatureEnabled = useIsFindContactsFeatureEnabledBasedOnGeolocation() + const gate = useGate() const visible = useMemo(() => { if (isWeb) return false if (hidden) return false if (nux && nux.completed) return false + if (!isFeatureEnabled) return false + if (gate('disable_settings_find_contacts')) return false return true - }, [hidden, nux]) + }, [hidden, nux, isFeatureEnabled, gate]) const close = () => { save({ diff --git a/src/components/contacts/country-allowlist.ts b/src/components/contacts/country-allowlist.ts index 97d3d4458..35ba43c8f 100644 --- a/src/components/contacts/country-allowlist.ts +++ b/src/components/contacts/country-allowlist.ts @@ -18,7 +18,16 @@ const FIND_CONTACTS_FEATURE_COUNTRY_ALLOWLIST = [ 'IT', ] satisfies CountryCode[] as string[] -export function isFindContactsFeatureEnabled(countryCode: string): boolean { +export function isFindContactsFeatureEnabled(countryCode?: string): boolean { + if (IS_DEV) return true + + /* + * This should never happen unless geolocation fails entirely. In that + * case, let the user try, since it should work as long as they have a + * phone number from one of the allow-listed countries. + */ + if (!countryCode) return true + return FIND_CONTACTS_FEATURE_COUNTRY_ALLOWLIST.includes( countryCode.toUpperCase(), ) @@ -26,12 +35,5 @@ export function isFindContactsFeatureEnabled(countryCode: string): boolean { export function useIsFindContactsFeatureEnabledBasedOnGeolocation() { const location = useGeolocation() - - if (IS_DEV) return true - - // they can try, by they'll need a phone number - // from one of the allowlisted countries - if (!location.countryCode) return true - return isFindContactsFeatureEnabled(location.countryCode) } diff --git a/src/components/contacts/screens/ViewMatches.tsx b/src/components/contacts/screens/ViewMatches.tsx index 9b4ff9382..d92cb88b1 100644 --- a/src/components/contacts/screens/ViewMatches.tsx +++ b/src/components/contacts/screens/ViewMatches.tsx @@ -104,8 +104,6 @@ export function ViewMatches({ match => !state.dismissedMatches.includes(match.profile.did), ) - console.log(matches) - const followableDids = matches.map(match => match.profile.did) const [didFollowAll, setDidFollowAll] = useState(followableDids.length === 0) @@ -449,7 +447,7 @@ function MatchItem({ const contactName = useMemo(() => { if (!contact) return null - const name = contact.firstName ?? contact.lastName ?? contact.name + const name = contact.name ?? contact.firstName ?? contact.lastName if (name) return _(msg`Your contact ${name}`) const phone = contact.phoneNumbers?.find(p => p.isPrimary) ?? contact.phoneNumbers?.[0] @@ -520,7 +518,7 @@ function ContactItem({ const {_} = useLingui() const {currentAccount} = useSession() - const name = contact.firstName ?? contact.lastName ?? contact.name + const name = contact.name ?? contact.firstName ?? contact.lastName const phone = contact.phoneNumbers?.find(phone => phone.isPrimary) ?? contact.phoneNumbers?.[0] diff --git a/src/components/dialogs/nuxs/FindContactsAnnouncement.tsx b/src/components/dialogs/nuxs/FindContactsAnnouncement.tsx index dd3aed013..b92ece98a 100644 --- a/src/components/dialogs/nuxs/FindContactsAnnouncement.tsx +++ b/src/components/dialogs/nuxs/FindContactsAnnouncement.tsx @@ -6,26 +6,33 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {logger} from '#/logger' -import {isWeb} from '#/platform/detection' +import {isNative, isWeb} from '#/platform/detection' import {atoms as a, useTheme, web} from '#/alf' import {Button, ButtonText} from '#/components/Button' -import {useIsFindContactsFeatureEnabledBasedOnGeolocation} from '#/components/contacts/country-allowlist' +import {isFindContactsFeatureEnabled} from '#/components/contacts/country-allowlist' import * as Dialog from '#/components/Dialog' import {useNuxDialogContext} from '#/components/dialogs/nuxs' +import { + createIsEnabledCheck, + isExistingUserAsOf, +} from '#/components/dialogs/nuxs/utils' import {Text} from '#/components/Typography' +import {IS_E2E} from '#/env' import {navigate} from '#/Navigation' -export function FindContactsAnnouncement() { - const isFeatureEnabled = useIsFindContactsFeatureEnabledBasedOnGeolocation() - - if (!isFeatureEnabled) { - return null - } - - return -} +export const enabled = createIsEnabledCheck(props => { + return ( + !IS_E2E && + isNative && + isExistingUserAsOf( + '2025-12-16T00:00:00.000Z', + props.currentProfile.createdAt, + ) && + isFindContactsFeatureEnabled(props.geolocation.countryCode) + ) +}) -function Inner() { +export function FindContactsAnnouncement() { const t = useTheme() const {_} = useLingui() const nuxDialogs = useNuxDialogContext() diff --git a/src/components/dialogs/nuxs/index.tsx b/src/components/dialogs/nuxs/index.tsx index c0b1410e2..2ab319faf 100644 --- a/src/components/dialogs/nuxs/index.tsx +++ b/src/components/dialogs/nuxs/index.tsx @@ -10,7 +10,6 @@ import {type AppBskyActorDefs} from '@atproto/api' import {useGate} from '#/lib/statsig/statsig' import {logger} from '#/logger' -import {isNative} from '#/platform/detection' import {STALE} from '#/state/queries' import {Nux, useNuxs, useResetNuxs, useSaveNux} from '#/state/queries/nuxs' import { @@ -20,13 +19,13 @@ import { import {useProfileQuery} from '#/state/queries/profile' import {type SessionAccount, useSession} from '#/state/session' import {useOnboardingState} from '#/state/shell' +import { + enabled as isFindContactsAnnouncementEnabled, + FindContactsAnnouncement, +} from '#/components/dialogs/nuxs/FindContactsAnnouncement' import {isSnoozed, snooze, unsnooze} from '#/components/dialogs/nuxs/snoozing' -import {ENV} from '#/env' -/* - * NUXs - */ -import {FindContactsAnnouncement} from './FindContactsAnnouncement' -import {isExistingUserAsOf} from './utils' +import {type EnabledCheckProps} from '#/components/dialogs/nuxs/utils' +import {useGeolocation} from '#/geolocation' type Context = { activeNux: Nux | undefined @@ -35,22 +34,11 @@ type Context = { const queuedNuxs: { id: Nux - enabled?: (props: { - gate: ReturnType - currentAccount: SessionAccount - currentProfile: AppBskyActorDefs.ProfileViewDetailed - preferences: UsePreferencesQueryResponse - }) => boolean + enabled?: (props: EnabledCheckProps) => boolean }[] = [ { id: Nux.FindContactsAnnouncement, - enabled: ({currentProfile}) => { - return ( - isNative && - ENV !== 'e2e' && - isExistingUserAsOf('2025-12-16T00:00:00.000Z', currentProfile.createdAt) - ) - }, + enabled: isFindContactsAnnouncementEnabled, }, ] @@ -101,6 +89,7 @@ function Inner({ preferences: UsePreferencesQueryResponse }) { const gate = useGate() + const geolocation = useGeolocation() const {nuxs} = useNuxs() const [snoozed, setSnoozed] = useState(() => { return isSnoozed() @@ -143,7 +132,13 @@ function Inner({ // then check gate (track exposure) if ( enabled && - !enabled({gate, currentAccount, currentProfile, preferences}) + !enabled({ + gate, + currentAccount, + currentProfile, + preferences, + geolocation, + }) ) { continue } @@ -178,6 +173,7 @@ function Inner({ currentAccount, currentProfile, preferences, + geolocation, ]) const ctx = useMemo(() => { diff --git a/src/components/dialogs/nuxs/utils.ts b/src/components/dialogs/nuxs/utils.ts index ba8f0169d..68ea38ebf 100644 --- a/src/components/dialogs/nuxs/utils.ts +++ b/src/components/dialogs/nuxs/utils.ts @@ -1,3 +1,24 @@ +import {type AppBskyActorDefs} from '@atproto/api' + +import {type useGate} from '#/lib/statsig/statsig' +import {type UsePreferencesQueryResponse} from '#/state/queries/preferences' +import {type SessionAccount} from '#/state/session' +import {type Geolocation} from '#/geolocation' + +export type EnabledCheckProps = { + gate: ReturnType + currentAccount: SessionAccount + currentProfile: AppBskyActorDefs.ProfileViewDetailed + preferences: UsePreferencesQueryResponse + geolocation: Geolocation +} + +export function createIsEnabledCheck( + cb: (props: EnabledCheckProps) => boolean, +) { + return cb +} + const ONE_DAY = 1000 * 60 * 60 * 24 export function isDaysOld(days: number, createdAt?: string) { diff --git a/src/lib/statsig/gates.ts b/src/lib/statsig/gates.ts index 8c757a016..ea67ac01b 100644 --- a/src/lib/statsig/gates.ts +++ b/src/lib/statsig/gates.ts @@ -4,6 +4,7 @@ export type Gate = | 'debug_show_feedcontext' | 'debug_subscriptions' | 'disable_onboarding_find_contacts' + | 'disable_settings_find_contacts' | 'explore_show_suggested_feeds' | 'feed_reply_button_open_thread' | 'old_postonboarding' diff --git a/src/routes.ts b/src/routes.ts index 614b24872..f325539c7 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -7,7 +7,7 @@ type AllNavigatableRoutes = Omit< > export const router = new Router({ - Home: '/', + Home: ['/', '/download'], Search: '/search', Feeds: '/feeds', Notifications: '/notifications', diff --git a/src/screens/Settings/Settings.tsx b/src/screens/Settings/Settings.tsx index 6b0e184c0..2fa5aa7de 100644 --- a/src/screens/Settings/Settings.tsx +++ b/src/screens/Settings/Settings.tsx @@ -16,6 +16,7 @@ import { type CommonNavigatorParams, type NavigationProp, } from '#/lib/routes/types' +import {useGate} from '#/lib/statsig/statsig' import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeHandle} from '#/lib/strings/handles' import {isIOS, isNative} from '#/platform/detection' @@ -93,6 +94,7 @@ export function SettingsScreen({}: Props) { const [showDevOptions, setShowDevOptions] = useState(false) const findContactsEnabled = useIsFindContactsFeatureEnabledBasedOnGeolocation() + const gate = useGate() return ( @@ -211,16 +213,18 @@ export function SettingsScreen({}: Props) { Content and media - {isNative && findContactsEnabled && ( - - - - Find friends from contacts - - - )} + {isNative && + findContactsEnabled && + !gate('disable_settings_find_contacts') && ( + + + + Find friends from contacts + + + )} diff --git a/src/view/screens/Storybook/Forms.tsx b/src/view/screens/Storybook/Forms.tsx index c3dad8dec..ee859a827 100644 --- a/src/view/screens/Storybook/Forms.tsx +++ b/src/view/screens/Storybook/Forms.tsx @@ -1,6 +1,7 @@ import React from 'react' import {type TextInput, View} from 'react-native' +import {APP_LANGUAGES} from '#/lib/../locale/languages' import {atoms as a} from '#/alf' import {Button, ButtonText} from '#/components/Button' import {DateField, LabelText} from '#/components/forms/DateField' @@ -9,6 +10,8 @@ import * as TextField from '#/components/forms/TextField' import * as Toggle from '#/components/forms/Toggle' import * as ToggleButton from '#/components/forms/ToggleButton' import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe' +import {InternationalPhoneCodeSelect} from '#/components/InternationalPhoneCodeSelect' +import * as Select from '#/components/Select' import {H1, H3} from '#/components/Typography' export function Forms() { @@ -22,6 +25,9 @@ export function Forms() { const [value, setValue] = React.useState('') const [date, setDate] = React.useState('2001-01-01') + const [countryCode, setCountryCode] = React.useState('US') + const [phoneNumber, setPhoneNumber] = React.useState('') + const [lang, setLang] = React.useState('en') const inputRef = React.useRef(null) @@ -29,6 +35,44 @@ export function Forms() {

Forms

+ + + + + + ( + + + {label} + + )} + items={APP_LANGUAGES.map(l => ({ + label: l.name, + value: l.code2, + }))} + /> + + + + + setCountryCode(value)} + /> + + + + + + +

InputText

-- 2.51.2 From f45e58e057284830527a258d3d47ef4fa2d04e7e Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Mon, 15 Dec 2025 14:38:05 -0600 Subject: [PATCH 03/13] [AAv2] Add blurb for orgs (#9556) * Add blurb for orgs * Update --- src/ageAssurance/components/NoAccessScreen.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/ageAssurance/components/NoAccessScreen.tsx b/src/ageAssurance/components/NoAccessScreen.tsx index a8667bf0c..8b2a44c26 100644 --- a/src/ageAssurance/components/NoAccessScreen.tsx +++ b/src/ageAssurance/components/NoAccessScreen.tsx @@ -120,6 +120,15 @@ export function NoAccessScreen() { ) + const orgAdmonition = ( + + + For organizational accounts, use the birthdate of the person who is + responsible for the account. + + + ) + return ( <> @@ -166,6 +175,8 @@ export function NoAccessScreen() { {!isBlocked && birthdateUpdateText} + + {orgAdmonition} @@ -180,6 +191,8 @@ export function NoAccessScreen() { {birthdateUpdateText} + + {orgAdmonition}
)} @@ -211,7 +224,7 @@ export function NoAccessScreen() { - {isUsingAppPassword && ( + {isUsingAppPassword ? ( Hmm, it looks like you're logged in with an{' '} @@ -220,6 +233,8 @@ export function NoAccessScreen() { password, or ask whomever controls this account to do so. + ) : ( + orgAdmonition )}
)} -- 2.51.2 From 2200cc95d841c4de3adf30cebb7508745fdfafec Mon Sep 17 00:00:00 2001 From: estrattonbailey <4732330+estrattonbailey@users.noreply.github.com> Date: Mon, 15 Dec 2025 20:49:31 +0000 Subject: [PATCH 04/13] Nightly source-language update --- src/locale/locales/en/messages.po | 248 +++++++++++++++--------------- 1 file changed, 126 insertions(+), 122 deletions(-) diff --git a/src/locale/locales/en/messages.po b/src/locale/locales/en/messages.po index 0f1eab65d..e232dbf37 100644 --- a/src/locale/locales/en/messages.po +++ b/src/locale/locales/en/messages.po @@ -38,7 +38,7 @@ msgstr "" msgid "{0, plural, one {# following} other {# following}}" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:267 +#: src/components/contacts/screens/ViewMatches.tsx:265 msgid "{0, plural, one {# friend found!} other {# friends found!}}" msgstr "" @@ -576,8 +576,8 @@ msgstr "" #: src/Navigation.tsx:534 #: src/screens/Settings/AboutSettings.tsx:75 -#: src/screens/Settings/Settings.tsx:258 -#: src/screens/Settings/Settings.tsx:261 +#: src/screens/Settings/Settings.tsx:262 +#: src/screens/Settings/Settings.tsx:265 msgid "About" msgstr "" @@ -604,8 +604,8 @@ msgid "Accept this language suggestion" msgstr "" #: src/screens/Settings/AccessibilitySettings.tsx:44 -#: src/screens/Settings/Settings.tsx:234 -#: src/screens/Settings/Settings.tsx:237 +#: src/screens/Settings/Settings.tsx:238 +#: src/screens/Settings/Settings.tsx:241 msgid "Accessibility" msgstr "" @@ -616,8 +616,8 @@ msgstr "" #: src/Navigation.tsx:401 #: src/screens/Login/LoginForm.tsx:194 #: src/screens/Settings/AccountSettings.tsx:51 -#: src/screens/Settings/Settings.tsx:178 -#: src/screens/Settings/Settings.tsx:181 +#: src/screens/Settings/Settings.tsx:180 +#: src/screens/Settings/Settings.tsx:183 msgid "Account" msgstr "" @@ -648,7 +648,7 @@ msgstr "" msgid "Account Muted by List" msgstr "" -#: src/screens/Settings/Settings.tsx:640 +#: src/screens/Settings/Settings.tsx:644 msgid "Account options" msgstr "" @@ -656,7 +656,7 @@ msgstr "" msgid "Account provider" msgstr "" -#: src/screens/Settings/Settings.tsx:676 +#: src/screens/Settings/Settings.tsx:680 msgid "Account removed from quick access" msgstr "" @@ -741,8 +741,8 @@ msgstr "" msgid "Add alt text (optional)" msgstr "" -#: src/screens/Settings/Settings.tsx:580 -#: src/screens/Settings/Settings.tsx:583 +#: src/screens/Settings/Settings.tsx:584 +#: src/screens/Settings/Settings.tsx:587 #: src/view/shell/desktop/LeftNav.tsx:262 #: src/view/shell/desktop/LeftNav.tsx:266 msgid "Add another account" @@ -844,7 +844,7 @@ msgstr "" msgid "Add user to list" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:210 +#: src/ageAssurance/components/NoAccessScreen.tsx:223 msgid "Add your birthdate" msgstr "" @@ -914,7 +914,7 @@ msgctxt "toast" msgid "Age assurance inquiry was submitted" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:342 +#: src/ageAssurance/components/NoAccessScreen.tsx:357 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:191 msgid "Age assurance only takes a few minutes" msgstr "" @@ -934,7 +934,7 @@ msgstr "" msgid "All accounts have been followed!" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:143 +#: src/components/contacts/screens/ViewMatches.tsx:141 msgid "All friends followed!" msgstr "" @@ -1070,7 +1070,7 @@ msgstr "" msgid "An error occurred while generating your starter pack. Want to try again?" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:242 +#: src/components/contacts/screens/ViewMatches.tsx:240 msgid "An error occurred while hiding suggestion. {0}" msgstr "" @@ -1108,7 +1108,7 @@ msgid "An error occurred. {0}" msgstr "" #: src/components/contacts/components/HeroImage.tsx:28 -#: src/components/dialogs/nuxs/FindContactsAnnouncement.tsx:71 +#: src/components/dialogs/nuxs/FindContactsAnnouncement.tsx:78 msgid "An illustration depicting user avatars flowing from a contact book into the Bluesky app" msgstr "" @@ -1272,8 +1272,8 @@ msgstr "" #: src/Navigation.tsx:393 #: src/screens/Settings/AppearanceSettings.tsx:73 -#: src/screens/Settings/Settings.tsx:226 -#: src/screens/Settings/Settings.tsx:229 +#: src/screens/Settings/Settings.tsx:230 +#: src/screens/Settings/Settings.tsx:233 msgid "Appearance" msgstr "" @@ -1282,8 +1282,8 @@ msgstr "" msgid "Apply default recommended feeds" msgstr "" -#: src/screens/Settings/Settings.tsx:512 -#: src/screens/Settings/Settings.tsx:514 +#: src/screens/Settings/Settings.tsx:516 +#: src/screens/Settings/Settings.tsx:518 msgid "Apply Pull Request" msgstr "" @@ -1585,11 +1585,11 @@ msgstr "" msgid "Bluesky is more fun with friends" msgstr "" -#: src/components/dialogs/nuxs/FindContactsAnnouncement.tsx:99 +#: src/components/dialogs/nuxs/FindContactsAnnouncement.tsx:106 msgid "Bluesky is more fun with friends! Import your contacts to see who’s already here." msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:314 +#: src/components/contacts/screens/ViewMatches.tsx:312 msgid "Bluesky is more fun with friends. Do you want to invite some of yours? <0/>" msgstr "" @@ -1761,7 +1761,7 @@ msgstr "" #: src/screens/Settings/components/ChangeHandleDialog.tsx:85 #: src/screens/Settings/components/ChangePasswordDialog.tsx:247 #: src/screens/Settings/components/ChangePasswordDialog.tsx:253 -#: src/screens/Settings/Settings.tsx:303 +#: src/screens/Settings/Settings.tsx:307 #: src/screens/Takendown.tsx:107 #: src/screens/Takendown.tsx:110 #: src/view/com/composer/Composer.tsx:1050 @@ -1997,11 +1997,11 @@ msgstr "" msgid "Choose your username" msgstr "" -#: src/screens/Settings/Settings.tsx:504 +#: src/screens/Settings/Settings.tsx:508 msgid "Clear all storage data" msgstr "" -#: src/screens/Settings/Settings.tsx:506 +#: src/screens/Settings/Settings.tsx:510 msgid "Clear all storage data (restart after this)" msgstr "" @@ -2026,7 +2026,7 @@ msgstr "" msgid "Click here to contact our support team" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:233 +#: src/ageAssurance/components/NoAccessScreen.tsx:248 msgid "Click here to log out" msgstr "" @@ -2035,7 +2035,7 @@ msgid "Click here to restart the verification process." msgstr "" #: src/ageAssurance/components/NoAccessScreen.tsx:97 -#: src/ageAssurance/components/NoAccessScreen.tsx:207 +#: src/ageAssurance/components/NoAccessScreen.tsx:220 msgid "Click here to update your birthdate" msgstr "" @@ -2252,7 +2252,7 @@ msgstr "" msgid "Confirm delete account" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:356 +#: src/ageAssurance/components/NoAccessScreen.tsx:371 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:87 #: src/components/dialogs/DeviceLocationRequestDialog.tsx:40 #: src/components/dialogs/DeviceLocationRequestDialog.tsx:105 @@ -2279,7 +2279,7 @@ msgstr "" msgid "Connection issue" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:293 +#: src/ageAssurance/components/NoAccessScreen.tsx:308 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:130 #: src/components/ageAssurance/AgeAssuranceAppealDialog.tsx:29 msgid "Contact our moderation team" @@ -2312,8 +2312,8 @@ msgstr "" msgid "Content & Media" msgstr "" -#: src/screens/Settings/Settings.tsx:208 -#: src/screens/Settings/Settings.tsx:211 +#: src/screens/Settings/Settings.tsx:210 +#: src/screens/Settings/Settings.tsx:213 msgid "Content and media" msgstr "" @@ -2581,7 +2581,7 @@ msgstr "" msgid "Could not upload contacts. You need to re-verify your phone number to proceed" msgstr "" -#: src/components/InternationalPhoneCodeSelect.tsx:79 +#: src/components/InternationalPhoneCodeSelect.tsx:80 msgid "Country code" msgstr "" @@ -2741,7 +2741,7 @@ msgstr "" msgid "Deactivate account" msgstr "" -#: src/screens/Settings/Settings.tsx:469 +#: src/screens/Settings/Settings.tsx:473 msgid "Debug Moderation" msgstr "" @@ -2794,7 +2794,7 @@ msgstr "" msgid "Delete chat" msgstr "" -#: src/screens/Settings/Settings.tsx:476 +#: src/screens/Settings/Settings.tsx:480 msgid "Delete chat declaration record" msgstr "" @@ -2907,8 +2907,8 @@ msgctxt "toast" msgid "Developer mode enabled" msgstr "" -#: src/screens/Settings/Settings.tsx:285 -#: src/screens/Settings/Settings.tsx:288 +#: src/screens/Settings/Settings.tsx:289 +#: src/screens/Settings/Settings.tsx:292 msgid "Developer options" msgstr "" @@ -3068,8 +3068,8 @@ msgstr "" #: src/components/contacts/components/InviteInfo.tsx:72 #: src/components/contacts/components/InviteInfo.tsx:78 -#: src/components/contacts/screens/ViewMatches.tsx:394 -#: src/components/contacts/screens/ViewMatches.tsx:411 +#: src/components/contacts/screens/ViewMatches.tsx:392 +#: src/components/contacts/screens/ViewMatches.tsx:409 #: src/components/dialogs/BirthDateSettings.tsx:183 #: src/components/dialogs/BirthDateSettings.tsx:190 #: src/components/dialogs/ServerInput.tsx:240 @@ -3695,15 +3695,15 @@ msgstr "" msgid "Failed to follow all suggested accounts, please try again" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:147 +#: src/components/contacts/screens/ViewMatches.tsx:145 msgid "Failed to follow all your friends, please try again" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:235 +#: src/components/contacts/screens/ViewMatches.tsx:233 msgid "Failed to hide suggestion, please check your internet connection" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:580 +#: src/components/contacts/screens/ViewMatches.tsx:578 msgid "Failed to launch SMS app" msgstr "" @@ -3991,8 +3991,8 @@ msgstr "" msgid "Find Friends" msgstr "" -#: src/screens/Settings/Settings.tsx:217 -#: src/screens/Settings/Settings.tsx:220 +#: src/screens/Settings/Settings.tsx:221 +#: src/screens/Settings/Settings.tsx:224 msgid "Find friends from contacts" msgstr "" @@ -4013,7 +4013,7 @@ msgstr "" msgid "Find posts, users, and feeds on Bluesky" msgstr "" -#: src/components/dialogs/nuxs/FindContactsAnnouncement.tsx:89 +#: src/components/dialogs/nuxs/FindContactsAnnouncement.tsx:96 msgid "Find your friends" msgstr "" @@ -4088,8 +4088,8 @@ msgstr "" msgid "Follow account" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:275 -#: src/components/contacts/screens/ViewMatches.tsx:290 +#: src/components/contacts/screens/ViewMatches.tsx:273 +#: src/components/contacts/screens/ViewMatches.tsx:288 #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:265 #: src/screens/Onboarding/StepSuggestedStarterpacks/StarterPackCard.tsx:156 #: src/screens/Onboarding/StepSuggestedStarterpacks/StarterPackCard.tsx:163 @@ -4205,6 +4205,10 @@ msgstr "" msgid "Food" msgstr "" +#: src/ageAssurance/components/NoAccessScreen.tsx:125 +msgid "For organizational accounts, use the birthdate of the person who is responsible for the account." +msgstr "" + #: src/view/com/modals/DeleteAccount.tsx:125 msgid "For security reasons, we'll need to send a confirmation code to your email address." msgstr "" @@ -4527,8 +4531,8 @@ msgstr "" msgid "Held by Bluesky for 7 days to prevent abuse, then deleted" msgstr "" -#: src/screens/Settings/Settings.tsx:250 #: src/screens/Settings/Settings.tsx:254 +#: src/screens/Settings/Settings.tsx:258 #: src/view/shell/desktop/RightNav.tsx:123 #: src/view/shell/desktop/RightNav.tsx:124 #: src/view/shell/Drawer.tsx:381 @@ -4548,11 +4552,11 @@ msgstr "" msgid "Hey there 👋" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:158 +#: src/ageAssurance/components/NoAccessScreen.tsx:167 msgid "Hey there!" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:189 +#: src/ageAssurance/components/NoAccessScreen.tsx:202 msgid "Hi there!" msgstr "" @@ -4652,7 +4656,7 @@ msgstr "" msgid "Hides the content" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:216 +#: src/ageAssurance/components/NoAccessScreen.tsx:229 msgid "Hmm, it looks like you're logged in with an <0>App Password. To set your birthdate, you'll need to log in with your main account password, or ask whomever controls this account to do so." msgstr "" @@ -4745,7 +4749,7 @@ msgstr "" msgid "I understand" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:576 +#: src/components/contacts/screens/ViewMatches.tsx:574 msgid "I'm on Bluesky as {0} - come find me! https://bsky.app/download" msgstr "" @@ -4835,8 +4839,8 @@ msgstr "" msgid "Import contacts" msgstr "" -#: src/components/dialogs/nuxs/FindContactsAnnouncement.tsx:107 -#: src/components/dialogs/nuxs/FindContactsAnnouncement.tsx:118 +#: src/components/dialogs/nuxs/FindContactsAnnouncement.tsx:114 +#: src/components/dialogs/nuxs/FindContactsAnnouncement.tsx:125 msgid "Import Contacts" msgstr "" @@ -4845,7 +4849,7 @@ msgstr "" msgid "Import contacts to find your friends" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:192 +#: src/ageAssurance/components/NoAccessScreen.tsx:205 msgid "In order to provide an age-appropriate experience, we need to know your birthdate. This is a one-time thing, and your data will be kept private." msgstr "" @@ -4918,7 +4922,7 @@ msgstr "" msgid "Introducing activity notifications" msgstr "" -#: src/components/dialogs/nuxs/FindContactsAnnouncement.tsx:48 +#: src/components/dialogs/nuxs/FindContactsAnnouncement.tsx:55 msgid "Introducing finding friends via contacts" msgstr "" @@ -4953,11 +4957,11 @@ msgstr "" msgid "Invalid Verification Code" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:585 +#: src/components/contacts/screens/ViewMatches.tsx:583 msgid "Invite" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:565 +#: src/components/contacts/screens/ViewMatches.tsx:563 msgid "Invite {name} to join Bluesky" msgstr "" @@ -4974,7 +4978,7 @@ msgstr "" msgid "Invite Friends" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:300 +#: src/components/contacts/screens/ViewMatches.tsx:298 msgid "Invite friends <0/>" msgstr "" @@ -4990,7 +4994,7 @@ msgstr "" msgid "Invites, but personal" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:353 +#: src/ageAssurance/components/NoAccessScreen.tsx:368 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:84 msgid "Is your location not accurate? <0>Tap here to confirm your location." msgstr "" @@ -5078,8 +5082,8 @@ msgid "Language Settings" msgstr "" #: src/screens/Settings/LanguageSettings.tsx:78 -#: src/screens/Settings/Settings.tsx:242 -#: src/screens/Settings/Settings.tsx:245 +#: src/screens/Settings/Settings.tsx:246 +#: src/screens/Settings/Settings.tsx:249 msgid "Languages" msgstr "" @@ -5087,12 +5091,12 @@ msgstr "" msgid "Larger" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:336 +#: src/ageAssurance/components/NoAccessScreen.tsx:351 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:185 msgid "Last initiated {timeAgo} ago" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:334 +#: src/ageAssurance/components/NoAccessScreen.tsx:349 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:183 msgid "Last initiated just now" msgstr "" @@ -5628,8 +5632,8 @@ msgstr "" #: src/Navigation.tsx:179 #: src/screens/Moderation/index.tsx:99 -#: src/screens/Settings/Settings.tsx:192 -#: src/screens/Settings/Settings.tsx:195 +#: src/screens/Settings/Settings.tsx:194 +#: src/screens/Settings/Settings.tsx:197 msgid "Moderation" msgstr "" @@ -5974,8 +5978,8 @@ msgstr "" msgid "News" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:394 -#: src/components/contacts/screens/ViewMatches.tsx:409 +#: src/components/contacts/screens/ViewMatches.tsx:392 +#: src/components/contacts/screens/ViewMatches.tsx:407 #: src/screens/Login/ForgotPasswordForm.tsx:137 #: src/screens/Login/ForgotPasswordForm.tsx:143 #: src/screens/Login/LoginForm.tsx:346 @@ -6006,11 +6010,11 @@ msgstr "" msgid "No app passwords yet" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:679 +#: src/components/contacts/screens/ViewMatches.tsx:677 msgid "No contacts found" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:657 +#: src/components/contacts/screens/ViewMatches.tsx:655 msgid "No contacts with the name “{query}” found" msgstr "" @@ -6063,7 +6067,7 @@ msgstr "" msgid "No more doomscrolling junk-filled algorithms. Find feeds that work for you, not against you." msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:561 +#: src/components/contacts/screens/ViewMatches.tsx:559 msgid "No name" msgstr "" @@ -6244,8 +6248,8 @@ msgstr "" #: src/screens/Settings/NotificationSettings/ReplyNotificationSettings.tsx:30 #: src/screens/Settings/NotificationSettings/RepostNotificationSettings.tsx:30 #: src/screens/Settings/NotificationSettings/RepostsOnRepostsNotificationSettings.tsx:30 -#: src/screens/Settings/Settings.tsx:200 -#: src/screens/Settings/Settings.tsx:203 +#: src/screens/Settings/Settings.tsx:202 +#: src/screens/Settings/Settings.tsx:205 #: src/view/screens/Notifications.tsx:130 #: src/view/shell/bottom-bar/BottomBar.tsx:252 #: src/view/shell/desktop/LeftNav.tsx:709 @@ -6310,7 +6314,7 @@ msgstr "" msgid "on<0><1/><2><3/>" msgstr "" -#: src/screens/Settings/Settings.tsx:402 +#: src/screens/Settings/Settings.tsx:406 msgid "Onboarding reset" msgstr "" @@ -6412,7 +6416,7 @@ msgstr "" msgid "Open message options" msgstr "" -#: src/screens/Settings/Settings.tsx:467 +#: src/screens/Settings/Settings.tsx:471 msgid "Open moderation debug page" msgstr "" @@ -6441,12 +6445,12 @@ msgstr "" msgid "Open starter pack menu" msgstr "" -#: src/screens/Settings/Settings.tsx:460 -#: src/screens/Settings/Settings.tsx:474 +#: src/screens/Settings/Settings.tsx:464 +#: src/screens/Settings/Settings.tsx:478 msgid "Open storybook page" msgstr "" -#: src/screens/Settings/Settings.tsx:453 +#: src/screens/Settings/Settings.tsx:457 msgid "Open system log" msgstr "" @@ -6509,7 +6513,7 @@ msgstr "" msgid "Opens GIF select dialog" msgstr "" -#: src/screens/Settings/Settings.tsx:251 +#: src/screens/Settings/Settings.tsx:255 msgid "Opens helpdesk in browser" msgstr "" @@ -7116,8 +7120,8 @@ msgstr "" msgid "Privacy" msgstr "" -#: src/screens/Settings/Settings.tsx:186 -#: src/screens/Settings/Settings.tsx:189 +#: src/screens/Settings/Settings.tsx:188 +#: src/screens/Settings/Settings.tsx:191 msgid "Privacy and security" msgstr "" @@ -7395,7 +7399,7 @@ msgstr "" #: src/components/StarterPack/Wizard/WizardListCard.tsx:105 #: src/components/StarterPack/Wizard/WizardListCard.tsx:112 #: src/screens/Bookmarks/index.tsx:266 -#: src/screens/Settings/Settings.tsx:678 +#: src/screens/Settings/Settings.tsx:682 #: src/view/com/modals/UserAddRemoveLists.tsx:235 #: src/view/com/posts/PostFeedErrorMessage.tsx:220 msgid "Remove" @@ -7409,8 +7413,8 @@ msgstr "" msgid "Remove {historyItem}" msgstr "" -#: src/screens/Settings/Settings.tsx:657 -#: src/screens/Settings/Settings.tsx:660 +#: src/screens/Settings/Settings.tsx:661 +#: src/screens/Settings/Settings.tsx:664 msgid "Remove account" msgstr "" @@ -7455,7 +7459,7 @@ msgstr "" msgid "Remove from my feeds" msgstr "" -#: src/screens/Settings/Settings.tsx:670 +#: src/screens/Settings/Settings.tsx:674 msgid "Remove from quick access?" msgstr "" @@ -7499,7 +7503,7 @@ msgstr "" msgid "Remove subtitle file" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:499 +#: src/components/contacts/screens/ViewMatches.tsx:497 #: src/screens/Settings/FindContactsSettings.tsx:323 msgid "Remove suggestion" msgstr "" @@ -7830,8 +7834,8 @@ msgstr "" msgid "Resend Verification Email" msgstr "" -#: src/screens/Settings/Settings.tsx:496 -#: src/screens/Settings/Settings.tsx:498 +#: src/screens/Settings/Settings.tsx:500 +#: src/screens/Settings/Settings.tsx:502 msgid "Reset activity subscription nudge" msgstr "" @@ -7839,8 +7843,8 @@ msgstr "" msgid "Reset code" msgstr "" -#: src/screens/Settings/Settings.tsx:481 -#: src/screens/Settings/Settings.tsx:483 +#: src/screens/Settings/Settings.tsx:485 +#: src/screens/Settings/Settings.tsx:487 msgid "Reset onboarding state" msgstr "" @@ -8042,7 +8046,7 @@ msgstr "" msgid "Search by name or interest" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:355 +#: src/components/contacts/screens/ViewMatches.tsx:353 msgid "Search contacts" msgstr "" @@ -8281,7 +8285,7 @@ msgstr "" msgid "Select subtitle file (.vtt)" msgstr "" -#: src/components/InternationalPhoneCodeSelect.tsx:67 +#: src/components/InternationalPhoneCodeSelect.tsx:68 msgid "Select telephone code" msgstr "" @@ -8421,7 +8425,7 @@ msgstr "" msgid "Set who can reply to your post" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:199 +#: src/ageAssurance/components/NoAccessScreen.tsx:212 msgid "Set your birthdate below and we'll get you back to posting and exploring in no time!" msgstr "" @@ -8430,7 +8434,7 @@ msgid "Sets email for password reset" msgstr "" #: src/Navigation.tsx:215 -#: src/screens/Settings/Settings.tsx:103 +#: src/screens/Settings/Settings.tsx:105 #: src/view/shell/desktop/LeftNav.tsx:805 #: src/view/shell/Drawer.tsx:609 msgid "Settings" @@ -8680,7 +8684,7 @@ msgstr "" msgid "Shows information about when this post was created" msgstr "" -#: src/screens/Settings/Settings.tsx:129 +#: src/screens/Settings/Settings.tsx:131 msgid "Shows other accounts you can switch to" msgstr "" @@ -8741,9 +8745,9 @@ msgstr "" msgid "Sign in to view post" msgstr "" -#: src/screens/Settings/Settings.tsx:268 -#: src/screens/Settings/Settings.tsx:270 -#: src/screens/Settings/Settings.tsx:302 +#: src/screens/Settings/Settings.tsx:272 +#: src/screens/Settings/Settings.tsx:274 +#: src/screens/Settings/Settings.tsx:306 #: src/screens/SignupQueued.tsx:93 #: src/screens/SignupQueued.tsx:96 #: src/screens/Takendown.tsx:93 @@ -8757,7 +8761,7 @@ msgstr "" msgid "Sign Out" msgstr "" -#: src/screens/Settings/Settings.tsx:299 +#: src/screens/Settings/Settings.tsx:303 #: src/view/shell/desktop/LeftNav.tsx:209 msgid "Sign out?" msgstr "" @@ -8983,7 +8987,7 @@ msgstr "" msgid "Step {0} of {1}" msgstr "" -#: src/screens/Settings/Settings.tsx:407 +#: src/screens/Settings/Settings.tsx:411 msgid "Storage cleared, you need to restart the app now." msgstr "" @@ -8992,7 +8996,7 @@ msgid "Stored as part of a secure code for matching with others" msgstr "" #: src/Navigation.tsx:308 -#: src/screens/Settings/Settings.tsx:462 +#: src/screens/Settings/Settings.tsx:466 msgid "Storybook" msgstr "" @@ -9092,9 +9096,9 @@ msgstr "" msgid "Support for this feature in your country has not been enabled yet! Please check back later." msgstr "" -#: src/screens/Settings/Settings.tsx:127 -#: src/screens/Settings/Settings.tsx:141 -#: src/screens/Settings/Settings.tsx:620 +#: src/screens/Settings/Settings.tsx:129 +#: src/screens/Settings/Settings.tsx:143 +#: src/screens/Settings/Settings.tsx:624 #: src/view/shell/desktop/LeftNav.tsx:247 msgid "Switch account" msgstr "" @@ -9122,7 +9126,7 @@ msgstr "" #: src/screens/Log.tsx:58 #: src/screens/Settings/AboutSettings.tsx:107 #: src/screens/Settings/AboutSettings.tsx:110 -#: src/screens/Settings/Settings.tsx:455 +#: src/screens/Settings/Settings.tsx:459 msgid "System log" msgstr "" @@ -9222,7 +9226,7 @@ msgstr "" msgid "Thanks, you have successfully verified your email address. You can close this dialog." msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:382 +#: src/ageAssurance/components/NoAccessScreen.tsx:397 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:113 msgid "Thanks! You're all set." msgstr "" @@ -9718,7 +9722,7 @@ msgstr "" msgid "This will delete \"{0}\" from your muted words. You can always add it back later." msgstr "" -#: src/screens/Settings/Settings.tsx:672 +#: src/screens/Settings/Settings.tsx:676 msgid "This will remove @{0} from the quick access list." msgstr "" @@ -9766,7 +9770,7 @@ msgstr "" msgid "To disable your email 2FA method, please verify your access to <0>{0}" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:230 +#: src/ageAssurance/components/NoAccessScreen.tsx:245 msgid "To log out, <0>click here." msgstr "" @@ -9897,11 +9901,11 @@ msgstr "" msgid "Unable to delete" msgstr "" -#: src/screens/Settings/Settings.tsx:521 +#: src/screens/Settings/Settings.tsx:525 msgid "Unapply Pull Request" msgstr "" -#: src/screens/Settings/Settings.tsx:523 +#: src/screens/Settings/Settings.tsx:527 msgid "Unapply Pull Request {currentChannel}" msgstr "" @@ -9981,7 +9985,7 @@ msgstr "" msgid "Unfortunately, none of your subscribed labelers supports this report type." msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:176 +#: src/ageAssurance/components/NoAccessScreen.tsx:187 msgid "Unfortunately, the birthdate you have saved to your profile makes you too young to access Bluesky." msgstr "" @@ -10089,8 +10093,8 @@ msgstr "" msgid "Unpinned list" msgstr "" -#: src/screens/Settings/Settings.tsx:488 -#: src/screens/Settings/Settings.tsx:490 +#: src/screens/Settings/Settings.tsx:492 +#: src/screens/Settings/Settings.tsx:494 msgid "Unsnooze email reminder" msgstr "" @@ -10342,7 +10346,7 @@ msgstr "" msgid "Verify account" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:319 +#: src/ageAssurance/components/NoAccessScreen.tsx:334 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:168 msgid "Verify again" msgstr "" @@ -10369,8 +10373,8 @@ msgstr "" msgid "Verify email dialog" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:307 -#: src/ageAssurance/components/NoAccessScreen.tsx:321 +#: src/ageAssurance/components/NoAccessScreen.tsx:322 +#: src/ageAssurance/components/NoAccessScreen.tsx:336 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:156 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:170 msgid "Verify now" @@ -10768,7 +10772,7 @@ msgstr "" msgid "We're so excited to have you join us!" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:375 +#: src/ageAssurance/components/NoAccessScreen.tsx:390 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:106 msgid "We're sorry, but based on your device's location, you are currently located in a region that requires age assurance." msgstr "" @@ -10976,7 +10980,7 @@ msgstr "" msgid "You are a trusted verifier" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:161 +#: src/ageAssurance/components/NoAccessScreen.tsx:170 msgid "You are accessing Bluesky from a region that legally requires us to verify your age before allowing you to access the app." msgstr "" @@ -10984,7 +10988,7 @@ msgstr "" msgid "You are creating an account on" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:289 +#: src/ageAssurance/components/NoAccessScreen.tsx:304 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:126 msgid "You are currently unable to access Bluesky's Age Assurance flow. Please <0>contact our moderation team if you believe this is an error." msgstr "" @@ -11117,7 +11121,7 @@ msgstr "" msgid "You don't have any saved feeds." msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:311 +#: src/components/contacts/screens/ViewMatches.tsx:309 msgid "You got here first" msgstr "" @@ -11272,7 +11276,7 @@ msgstr "" msgid "You previously deactivated @{0}." msgstr "" -#: src/screens/Settings/Settings.tsx:418 +#: src/screens/Settings/Settings.tsx:422 msgid "You probably want to restart the app now." msgstr "" @@ -11289,7 +11293,7 @@ msgstr "" msgid "You recently changed your birthdate" msgstr "" -#: src/screens/Settings/Settings.tsx:300 +#: src/screens/Settings/Settings.tsx:304 #: src/view/shell/desktop/LeftNav.tsx:210 msgid "You will be signed out of all your accounts." msgstr "" @@ -11456,7 +11460,7 @@ msgstr "" msgid "Your contact {firstAuthorName} is on Bluesky" msgstr "" -#: src/components/contacts/screens/ViewMatches.tsx:453 +#: src/components/contacts/screens/ViewMatches.tsx:451 msgid "Your contact {name}" msgstr "" -- 2.51.2 From f02b9c323f54bbd328ababb1562b20b177b73fc0 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Wed, 17 Dec 2025 22:10:39 +0200 Subject: [PATCH 05/13] Change empty states if not own profile (#9518) * change empty states if not own profile * Update ProfileFeedgens.tsx * capitalise starter packs --- src/view/com/feeds/ProfileFeedgens.tsx | 38 +++++++++--- src/view/com/lists/ProfileLists.tsx | 40 +++++++++---- src/view/screens/Profile.tsx | 82 ++++++++++++++++---------- 3 files changed, 109 insertions(+), 51 deletions(-) diff --git a/src/view/com/feeds/ProfileFeedgens.tsx b/src/view/com/feeds/ProfileFeedgens.tsx index 34762dc15..5b09545f6 100644 --- a/src/view/com/feeds/ProfileFeedgens.tsx +++ b/src/view/com/feeds/ProfileFeedgens.tsx @@ -23,6 +23,7 @@ import {logger} from '#/logger' import {isIOS, isNative, isWeb} from '#/platform/detection' import {usePreferencesQuery} from '#/state/queries/preferences' import {RQKEY, useProfileFeedgensQuery} from '#/state/queries/profile-feedgens' +import {useSession} from '#/state/session' import {EmptyState} from '#/view/com/util/EmptyState' import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' import {List, type ListRef} from '#/view/com/util/List' @@ -81,6 +82,8 @@ export function ProfileFeedgens({ const isEmpty = !isPending && !data?.pages[0]?.feeds.length const {data: preferences} = usePreferencesQuery() const navigation = useNavigation() + const {currentAccount} = useSession() + const isSelf = currentAccount?.did === did const items = useMemo(() => { let items: any[] = [] @@ -152,15 +155,23 @@ export function ProfileFeedgens({ navigation.navigate('Feeds' as never), - size: 'small', - color: 'secondary', - }} + button={ + isSelf + ? { + label: _(msg`Browse custom feeds`), + text: _(msg`Browse custom feeds`), + onPress: () => navigation.navigate('Feeds' as never), + size: 'small', + color: 'secondary', + } + : undefined + } /> ) } else if (item === ERROR_ITEM) { @@ -194,7 +205,16 @@ export function ProfileFeedgens({ } return null }, - [_, t, error, refetch, onPressRetryLoadMore, preferences, navigation], + [ + _, + t, + error, + refetch, + onPressRetryLoadMore, + preferences, + navigation, + isSelf, + ], ) useEffect(() => { diff --git a/src/view/com/lists/ProfileLists.tsx b/src/view/com/lists/ProfileLists.tsx index c60fc42ee..35ab7b8a8 100644 --- a/src/view/com/lists/ProfileLists.tsx +++ b/src/view/com/lists/ProfileLists.tsx @@ -23,6 +23,7 @@ import {logger} from '#/logger' import {isIOS, isNative, isWeb} from '#/platform/detection' import {usePreferencesQuery} from '#/state/queries/preferences' import {RQKEY, useProfileListsQuery} from '#/state/queries/profile-lists' +import {useSession} from '#/state/session' import {EmptyState} from '#/view/com/util/EmptyState' import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' import {List, type ListRef} from '#/view/com/util/List' @@ -81,6 +82,8 @@ export function ProfileLists({ const isEmpty = !isPending && !data?.pages[0]?.lists.length const {data: preferences} = usePreferencesQuery() const navigation = useNavigation() + const {currentAccount} = useSession() + const isSelf = currentAccount?.did === did const items = useMemo(() => { let items: any[] = [] @@ -151,17 +154,23 @@ export function ProfileLists({ return ( navigation.navigate('Lists' as never), - size: 'small', - color: 'primary', - }} + button={ + isSelf + ? { + label: _(msg`Create a list`), + text: _(msg`Create a list`), + onPress: () => navigation.navigate('Lists' as never), + size: 'small', + color: 'primary', + } + : undefined + } /> ) } else if (item === ERROR_ITEM) { @@ -195,7 +204,16 @@ export function ProfileLists({ } return null }, - [_, t, error, refetch, onPressRetryLoadMore, preferences, navigation], + [ + _, + t, + error, + refetch, + onPressRetryLoadMore, + preferences, + navigation, + isSelf, + ], ) useEffect(() => { diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx index fddde55e1..5bb46f0d2 100644 --- a/src/view/screens/Profile.tsx +++ b/src/view/screens/Profile.tsx @@ -429,13 +429,17 @@ function ProfileScreenLoaded({ ignoreFilterFor={profile.did} setScrollViewTag={setScrollViewTag} emptyStateMessage={_(msg`No posts yet`)} - emptyStateButton={{ - label: _(msg`Write a post`), - text: _(msg`Write a post`), - onPress: () => openComposer({}), - size: 'small', - color: 'primary', - }} + emptyStateButton={ + isMe + ? { + label: _(msg`Write a post`), + text: _(msg`Write a post`), + onPress: () => openComposer({}), + size: 'small', + color: 'primary', + } + : undefined + } /> ) : null} @@ -465,13 +469,17 @@ function ProfileScreenLoaded({ ignoreFilterFor={profile.did} setScrollViewTag={setScrollViewTag} emptyStateMessage={_(msg`No media yet`)} - emptyStateButton={{ - label: _(msg`Post a photo`), - text: _(msg`Post a photo`), - onPress: () => openComposer({}), - size: 'small', - color: 'primary', - }} + emptyStateButton={ + isMe + ? { + label: _(msg`Post a photo`), + text: _(msg`Post a photo`), + onPress: () => openComposer({}), + size: 'small', + color: 'primary', + } + : undefined + } emptyStateIcon={ImageIcon} /> ) @@ -487,13 +495,17 @@ function ProfileScreenLoaded({ ignoreFilterFor={profile.did} setScrollViewTag={setScrollViewTag} emptyStateMessage={_(msg`No video posts yet`)} - emptyStateButton={{ - label: _(msg`Post a video`), - text: _(msg`Post a video`), - onPress: () => openComposer({}), - size: 'small', - color: 'primary', - }} + emptyStateButton={ + isMe + ? { + label: _(msg`Post a video`), + text: _(msg`Post a video`), + onPress: () => openComposer({}), + size: 'small', + color: 'primary', + } + : undefined + } emptyStateIcon={VideoIcon} /> ) @@ -535,16 +547,24 @@ function ProfileScreenLoaded({ headerOffset={headerHeight} enabled={isFocused} setScrollViewTag={setScrollViewTag} - emptyStateMessage={_( - msg`Starter packs let you share your favorite feeds and people with your friends.`, - )} - emptyStateButton={{ - label: _(msg`Create a Starter Pack`), - text: _(msg`Create a Starter Pack`), - onPress: wrappedNavToWizard, - color: 'primary', - size: 'small', - }} + emptyStateMessage={ + isMe + ? _( + msg`Starter Packs let you share your favorite feeds and people with your friends.`, + ) + : _(msg`No Starter Packs yet`) + } + emptyStateButton={ + isMe + ? { + label: _(msg`Create a Starter Pack`), + text: _(msg`Create a Starter Pack`), + onPress: wrappedNavToWizard, + color: 'primary', + size: 'small', + } + : undefined + } emptyStateIcon={CircleAndSquareIcon} /> ) -- 2.51.2 From e80e2f66c3d7c2542b73defd0a411c3e87e5d49f Mon Sep 17 00:00:00 2001 From: Alex Benzer Date: Wed, 17 Dec 2025 13:45:21 -0800 Subject: [PATCH 06/13] Adds a dismiss button to user suggestions (#9484) * Add dismiss button to user suggestions * Adds dismiss button to suggested user cards, behind a feature gate * Reverse gate check, best practice * Sync DISMISS_ANIMATION_DURATION --------- Co-authored-by: Eric Bailey --- src/components/FeedInterstitials.tsx | 379 ++++++++++++++---- src/lib/statsig/gates.ts | 1 + src/logger/metrics.ts | 6 + .../Profile/Header/SuggestedFollows.tsx | 186 ++++++++- 4 files changed, 493 insertions(+), 79 deletions(-) diff --git a/src/components/FeedInterstitials.tsx b/src/components/FeedInterstitials.tsx index 7418c8d76..267d303be 100644 --- a/src/components/FeedInterstitials.tsx +++ b/src/components/FeedInterstitials.tsx @@ -1,12 +1,13 @@ import React, {useCallback, useEffect, useRef} from 'react' import {ScrollView, View} from 'react-native' +import Animated, {LinearTransition} from 'react-native-reanimated' import {type AppBskyFeedDefs, AtUri} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' import {type NavigationProp} from '#/lib/routes/types' -import {logEvent} from '#/lib/statsig/statsig' +import {logEvent, useGate} from '#/lib/statsig/statsig' import {logger} from '#/logger' import {type MetricEvents} from '#/logger/metrics' import {isIOS} from '#/platform/detection' @@ -14,7 +15,10 @@ import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useGetPopularFeedsQuery} from '#/state/queries/feed' import {type FeedDescriptor} from '#/state/queries/post-feed' import {useProfilesQuery} from '#/state/queries/profile' -import {useSuggestedFollowsByActorQuery} from '#/state/queries/suggested-follows' +import { + useSuggestedFollowsByActorQuery, + useSuggestedFollowsQuery, +} from '#/state/queries/suggested-follows' import {useSession} from '#/state/session' import * as userActionHistory from '#/state/userActionHistory' import {type SeenPost} from '#/state/userActionHistory' @@ -31,6 +35,7 @@ import {useDialogControl} from '#/components/Dialog' import * as FeedCard from '#/components/FeedCard' import {ArrowRight_Stroke2_Corner0_Rounded as ArrowRight} from '#/components/icons/Arrow' import {Hashtag_Stroke2_Corner0_Rounded as Hashtag} from '#/components/icons/Hashtag' +import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times' import {InlineLinkText} from '#/components/Link' import * as ProfileCard from '#/components/ProfileCard' import {Text} from '#/components/Typography' @@ -38,6 +43,8 @@ import type * as bsky from '#/types/bsky' import {FollowDialogWithoutGuide} from './ProgressGuide/FollowDialog' import {ProgressGuideList} from './ProgressGuide/List' +const DISMISS_ANIMATION_DURATION = 200 + const MOBILE_CARD_WIDTH = 165 const FINAL_CARD_WIDTH = 120 @@ -202,6 +209,9 @@ export function SuggestedFollows({feed}: {feed: FeedDescriptor}) { } export function SuggestedFollowsProfile({did}: {did: string}) { + const {gtMobile} = useBreakpoints() + const moderationOpts = useModerationOpts() + const maxLength = gtMobile ? 4 : 6 const { isLoading: isSuggestionsLoading, data, @@ -209,29 +219,194 @@ export function SuggestedFollowsProfile({did}: {did: string}) { } = useSuggestedFollowsByActorQuery({ did, }) + const { + data: moreSuggestions, + fetchNextPage, + hasNextPage, + isFetchingNextPage, + } = useSuggestedFollowsQuery({limit: 25}) + + const [dismissedDids, setDismissedDids] = React.useState>( + new Set(), + ) + const [dismissingDids, setDismissingDids] = React.useState>( + new Set(), + ) + + const onDismiss = React.useCallback((dismissedDid: string) => { + // Start the fade animation + setDismissingDids(prev => new Set(prev).add(dismissedDid)) + // After animation completes, actually remove from list + setTimeout(() => { + setDismissedDids(prev => new Set(prev).add(dismissedDid)) + setDismissingDids(prev => { + const next = new Set(prev) + next.delete(dismissedDid) + return next + }) + }, DISMISS_ANIMATION_DURATION) + }, []) + + // Combine profiles from the actor-specific query with fallback suggestions + const allProfiles = React.useMemo(() => { + const actorProfiles = data?.suggestions ?? [] + const fallbackProfiles = + moreSuggestions?.pages.flatMap(page => page.actors) ?? [] + + // Dedupe by did, preferring actor-specific profiles + const seen = new Set() + const combined: bsky.profile.AnyProfileView[] = [] + + for (const profile of actorProfiles) { + if (!seen.has(profile.did)) { + seen.add(profile.did) + combined.push(profile) + } + } + + for (const profile of fallbackProfiles) { + if (!seen.has(profile.did) && profile.did !== did) { + seen.add(profile.did) + combined.push(profile) + } + } + + return combined + }, [data?.suggestions, moreSuggestions?.pages, did]) + + const filteredProfiles = React.useMemo(() => { + return allProfiles.filter(p => !dismissedDids.has(p.did)) + }, [allProfiles, dismissedDids]) + + // Fetch more when running low + React.useEffect(() => { + if ( + moderationOpts && + filteredProfiles.length < maxLength && + hasNextPage && + !isFetchingNextPage + ) { + fetchNextPage() + } + }, [ + filteredProfiles.length, + maxLength, + hasNextPage, + isFetchingNextPage, + fetchNextPage, + moderationOpts, + ]) + return ( ) } export function SuggestedFollowsHome() { + const {gtMobile} = useBreakpoints() + const moderationOpts = useModerationOpts() + const maxLength = gtMobile ? 4 : 6 const { isLoading: isSuggestionsLoading, - profiles, - error, + profiles: experimentalProfiles, + error: experimentalError, } = useExperimentalSuggestedUsersQuery() + const { + data: moreSuggestions, + fetchNextPage, + hasNextPage, + isFetchingNextPage, + error: suggestionsError, + } = useSuggestedFollowsQuery({limit: 25}) + + const [dismissedDids, setDismissedDids] = React.useState>( + new Set(), + ) + const [dismissingDids, setDismissingDids] = React.useState>( + new Set(), + ) + + const onDismiss = React.useCallback((did: string) => { + // Start the fade animation + setDismissingDids(prev => new Set(prev).add(did)) + // After animation completes, actually remove from list + setTimeout(() => { + setDismissedDids(prev => new Set(prev).add(did)) + setDismissingDids(prev => { + const next = new Set(prev) + next.delete(did) + return next + }) + }, DISMISS_ANIMATION_DURATION) + }, []) + + // Combine profiles from experimental query with paginated suggestions + const allProfiles = React.useMemo(() => { + const fallbackProfiles = + moreSuggestions?.pages.flatMap(page => page.actors) ?? [] + + // Dedupe by did, preferring experimental profiles + const seen = new Set() + const combined: bsky.profile.AnyProfileView[] = [] + + for (const profile of experimentalProfiles) { + if (!seen.has(profile.did)) { + seen.add(profile.did) + combined.push(profile) + } + } + + for (const profile of fallbackProfiles) { + if (!seen.has(profile.did)) { + seen.add(profile.did) + combined.push(profile) + } + } + + return combined + }, [experimentalProfiles, moreSuggestions?.pages]) + + const filteredProfiles = React.useMemo(() => { + return allProfiles.filter(p => !dismissedDids.has(p.did)) + }, [allProfiles, dismissedDids]) + + // Fetch more when running low + React.useEffect(() => { + if ( + moderationOpts && + filteredProfiles.length < maxLength && + hasNextPage && + !isFetchingNextPage + ) { + fetchNextPage() + } + }, [ + filteredProfiles.length, + maxLength, + hasNextPage, + isFetchingNextPage, + fetchNextPage, + moderationOpts, + ]) + return ( ) } @@ -240,19 +415,26 @@ export function ProfileGrid({ isSuggestionsLoading, error, profiles, + totalProfileCount, recId, viewContext = 'feed', + onDismiss, + dismissingDids, isVisible = true, }: { isSuggestionsLoading: boolean profiles: bsky.profile.AnyProfileView[] + totalProfileCount?: number recId?: number error: Error | null + dismissingDids?: Set viewContext: 'profile' | 'profileHeader' | 'feed' + onDismiss?: (did: string) => void isVisible?: boolean }) { const t = useTheme() const {_} = useLingui() + const gate = useGate() const moderationOpts = useModerationOpts() const {gtMobile} = useBreakpoints() const followDialogControl = useDialogControl() @@ -260,6 +442,7 @@ export function ProfileGrid({ const isLoading = isSuggestionsLoading || !moderationOpts const isProfileHeaderContext = viewContext === 'profileHeader' const isFeedContext = viewContext === 'feed' + const showDismissButton = onDismiss && gate('suggested_users_dismiss') const maxLength = gtMobile ? 3 : isProfileHeaderContext ? 12 : 6 const minLength = gtMobile ? 3 : 4 @@ -363,20 +546,9 @@ export function ProfileGrid({ : error || !profiles.length ? null : profiles.slice(0, maxLength).map((profile, index) => ( - { - logEvent('suggestedUser:press', { - logContext: isFeedContext - ? 'InterstitialDiscover' - : 'InterstitialProfile', - recId, - position: index, - suggestedDid: profile.did, - category: null, - }) - }} + layout={LinearTransition.duration(DISMISS_ANIMATION_DURATION)} style={[ a.flex_1, gtMobile && @@ -385,68 +557,127 @@ export function ProfileGrid({ a.flex_grow, {width: `calc(30% - ${a.gap_md.gap / 2}px)`}, ]), + { + opacity: dismissingDids?.has(profile.did) ? 0 : 1, + transitionProperty: 'opacity', + transitionDuration: `${DISMISS_ANIMATION_DURATION}ms`, + }, ]}> - {({hovered, pressed}) => ( - - - - - - { + logEvent('suggestedUser:press', { + logContext: isFeedContext + ? 'InterstitialDiscover' + : 'InterstitialProfile', + recId, + position: index, + suggestedDid: profile.did, + category: null, + }) + }}> + {({hovered, pressed}) => ( + + + {showDismissButton && ( + + )} + + - + + + + - - { - logEvent('suggestedUser:follow', { - logContext: isFeedContext - ? 'InterstitialDiscover' - : 'InterstitialProfile', - location: 'Card', - recId, - position: index, - suggestedDid: profile.did, - category: null, - }) - }} - /> - - - )} - + { + logEvent('suggestedUser:follow', { + logContext: isFeedContext + ? 'InterstitialDiscover' + : 'InterstitialProfile', + location: 'Card', + recId, + position: index, + suggestedDid: profile.did, + category: null, + }) + }} + /> + + + )} + + )) - if (error || (!isLoading && profiles.length < minLength)) { + // Use totalProfileCount (before dismissals) for minLength check on initial render. + const profileCountForMinCheck = totalProfileCount ?? profiles.length + if (error || (!isLoading && profileCountForMinCheck < minLength)) { logger.debug(`Not enough profiles to show suggested follows`) return null } diff --git a/src/lib/statsig/gates.ts b/src/lib/statsig/gates.ts index ea67ac01b..357548d3b 100644 --- a/src/lib/statsig/gates.ts +++ b/src/lib/statsig/gates.ts @@ -12,5 +12,6 @@ export type Gate = | 'onboarding_suggested_starterpacks' | 'remove_show_latest_button' | 'show_composer_prompt' + | 'suggested_users_dismiss' | 'test_gate_1' | 'test_gate_2' diff --git a/src/logger/metrics.ts b/src/logger/metrics.ts index 6908f3a05..949c883b7 100644 --- a/src/logger/metrics.ts +++ b/src/logger/metrics.ts @@ -379,6 +379,12 @@ export type MetricEvents = { | 'Profile' | 'Onboarding' } + 'suggestedUser:dismiss': { + logContext: 'InterstitialDiscover' | 'InterstitialProfile' + recId?: number + position: number + suggestedDid: string + } 'profile:unfollow': { logContext: | 'RecommendedFollowsItem' diff --git a/src/screens/Profile/Header/SuggestedFollows.tsx b/src/screens/Profile/Header/SuggestedFollows.tsx index 48856cef7..239ad7d9f 100644 --- a/src/screens/Profile/Header/SuggestedFollows.tsx +++ b/src/screens/Profile/Header/SuggestedFollows.tsx @@ -1,20 +1,113 @@ +import React from 'react' +import {type AppBskyActorDefs} from '@atproto/api' + import {AccordionAnimation} from '#/lib/custom-animations/AccordionAnimation' import {isAndroid} from '#/platform/detection' -import {useSuggestedFollowsByActorQuery} from '#/state/queries/suggested-follows' +import {useModerationOpts} from '#/state/preferences/moderation-opts' +import { + useSuggestedFollowsByActorQuery, + useSuggestedFollowsQuery, +} from '#/state/queries/suggested-follows' +import {useBreakpoints} from '#/alf' import {ProfileGrid} from '#/components/FeedInterstitials' +const DISMISS_ANIMATION_DURATION = 200 + export function ProfileHeaderSuggestedFollows({actorDid}: {actorDid: string}) { + const {gtMobile} = useBreakpoints() + const moderationOpts = useModerationOpts() + const maxLength = gtMobile ? 4 : 12 const {isLoading, data, error} = useSuggestedFollowsByActorQuery({ did: actorDid, }) + const { + data: moreSuggestions, + fetchNextPage, + hasNextPage, + isFetchingNextPage, + } = useSuggestedFollowsQuery({limit: 25}) + + const [dismissedDids, setDismissedDids] = React.useState>( + new Set(), + ) + const [dismissingDids, setDismissingDids] = React.useState>( + new Set(), + ) + + const onDismiss = React.useCallback((did: string) => { + // Start the fade animation + setDismissingDids(prev => new Set(prev).add(did)) + // After animation completes, actually remove from list + setTimeout(() => { + setDismissedDids(prev => new Set(prev).add(did)) + setDismissingDids(prev => { + const next = new Set(prev) + next.delete(did) + return next + }) + }, DISMISS_ANIMATION_DURATION) + }, []) + + // Combine profiles from the actor-specific query with fallback suggestions + const allProfiles = React.useMemo(() => { + const actorProfiles = data?.suggestions ?? [] + const fallbackProfiles = + moreSuggestions?.pages.flatMap(page => page.actors) ?? [] + + // Dedupe by did, preferring actor-specific profiles + const seen = new Set() + const combined: AppBskyActorDefs.ProfileView[] = [] + + for (const profile of actorProfiles) { + if (!seen.has(profile.did)) { + seen.add(profile.did) + combined.push(profile) + } + } + + for (const profile of fallbackProfiles) { + if (!seen.has(profile.did) && profile.did !== actorDid) { + seen.add(profile.did) + combined.push(profile) + } + } + + return combined + }, [data?.suggestions, moreSuggestions?.pages, actorDid]) + + const filteredProfiles = React.useMemo(() => { + return allProfiles.filter(p => !dismissedDids.has(p.did)) + }, [allProfiles, dismissedDids]) + + // Fetch more when running low + React.useEffect(() => { + if ( + moderationOpts && + filteredProfiles.length < maxLength && + hasNextPage && + !isFetchingNextPage + ) { + fetchNextPage() + } + }, [ + filteredProfiles.length, + maxLength, + hasNextPage, + isFetchingNextPage, + fetchNextPage, + moderationOpts, + ]) return ( ) } @@ -26,11 +119,91 @@ export function AnimatedProfileHeaderSuggestedFollows({ isExpanded: boolean actorDid: string }) { + const {gtMobile} = useBreakpoints() + const moderationOpts = useModerationOpts() + const maxLength = gtMobile ? 4 : 12 const {isLoading, data, error} = useSuggestedFollowsByActorQuery({ did: actorDid, }) + const { + data: moreSuggestions, + fetchNextPage, + hasNextPage, + isFetchingNextPage, + } = useSuggestedFollowsQuery({limit: 25}) + + const [dismissedDids, setDismissedDids] = React.useState>( + new Set(), + ) + const [dismissingDids, setDismissingDids] = React.useState>( + new Set(), + ) + + const onDismiss = React.useCallback((did: string) => { + // Start the fade animation + setDismissingDids(prev => new Set(prev).add(did)) + // After animation completes, actually remove from list + setTimeout(() => { + setDismissedDids(prev => new Set(prev).add(did)) + setDismissingDids(prev => { + const next = new Set(prev) + next.delete(did) + return next + }) + }, DISMISS_ANIMATION_DURATION) + }, []) + + // Combine profiles from the actor-specific query with fallback suggestions + const allProfiles = React.useMemo(() => { + const actorProfiles = data?.suggestions ?? [] + const fallbackProfiles = + moreSuggestions?.pages.flatMap(page => page.actors) ?? [] + + // Dedupe by did, preferring actor-specific profiles + const seen = new Set() + const combined: AppBskyActorDefs.ProfileView[] = [] + + for (const profile of actorProfiles) { + if (!seen.has(profile.did)) { + seen.add(profile.did) + combined.push(profile) + } + } + + for (const profile of fallbackProfiles) { + if (!seen.has(profile.did) && profile.did !== actorDid) { + seen.add(profile.did) + combined.push(profile) + } + } + + return combined + }, [data?.suggestions, moreSuggestions?.pages, actorDid]) + + const filteredProfiles = React.useMemo(() => { + return allProfiles.filter(p => !dismissedDids.has(p.did)) + }, [allProfiles, dismissedDids]) + + // Fetch more when running low + React.useEffect(() => { + if ( + moderationOpts && + filteredProfiles.length < maxLength && + hasNextPage && + !isFetchingNextPage + ) { + fetchNextPage() + } + }, [ + filteredProfiles.length, + maxLength, + hasNextPage, + isFetchingNextPage, + fetchNextPage, + moderationOpts, + ]) - if (!data?.suggestions?.length) return null + if (!allProfiles.length && !isLoading) return null /* NOTE (caidanw): * Android does not work well with this feature yet. @@ -43,10 +216,13 @@ export function AnimatedProfileHeaderSuggestedFollows({ -- 2.51.2 From f50b70e2b4db2a12fdfd13b662231a1b372d73ce Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 17 Dec 2025 17:03:16 -0600 Subject: [PATCH 07/13] Bump to v1.113.0 (#9569) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d8f3dee7f..c1a3bb47b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bsky.app", - "version": "1.112.0", + "version": "1.113.0", "private": true, "engines": { "node": ">=20" -- 2.51.2 From e9524d8a83ee241da9761a1ceb98c9bf40c7d4dc Mon Sep 17 00:00:00 2001 From: pfrazee <1270099+pfrazee@users.noreply.github.com> Date: Thu, 18 Dec 2025 02:42:38 +0000 Subject: [PATCH 08/13] Nightly source-language update --- src/locale/locales/en/messages.po | 87 +++++++++++++++++++------------ 1 file changed, 53 insertions(+), 34 deletions(-) diff --git a/src/locale/locales/en/messages.po b/src/locale/locales/en/messages.po index e232dbf37..6ea91d4a7 100644 --- a/src/locale/locales/en/messages.po +++ b/src/locale/locales/en/messages.po @@ -1637,25 +1637,25 @@ msgstr "" msgid "Breaking site rules" msgstr "" -#: src/view/com/feeds/ProfileFeedgens.tsx:158 -#: src/view/com/feeds/ProfileFeedgens.tsx:159 +#: src/view/com/feeds/ProfileFeedgens.tsx:167 +#: src/view/com/feeds/ProfileFeedgens.tsx:168 msgid "Browse custom feeds" msgstr "" -#: src/components/FeedInterstitials.tsx:547 +#: src/components/FeedInterstitials.tsx:778 msgid "Browse more accounts" msgstr "" -#: src/components/FeedInterstitials.tsx:676 +#: src/components/FeedInterstitials.tsx:907 msgid "Browse more feeds on the Explore page" msgstr "" -#: src/components/FeedInterstitials.tsx:657 -#: src/components/FeedInterstitials.tsx:660 +#: src/components/FeedInterstitials.tsx:888 +#: src/components/FeedInterstitials.tsx:891 msgid "Browse more suggestions" msgstr "" -#: src/components/FeedInterstitials.tsx:685 +#: src/components/FeedInterstitials.tsx:916 msgid "Browse more suggestions on the Explore page" msgstr "" @@ -2593,8 +2593,8 @@ msgstr "" msgid "Create" msgstr "" -#: src/view/com/lists/ProfileLists.tsx:159 -#: src/view/com/lists/ProfileLists.tsx:160 +#: src/view/com/lists/ProfileLists.tsx:166 +#: src/view/com/lists/ProfileLists.tsx:167 msgid "Create a list" msgstr "" @@ -2608,8 +2608,8 @@ msgstr "" msgid "Create a starter pack" msgstr "" -#: src/view/screens/Profile.tsx:542 -#: src/view/screens/Profile.tsx:543 +#: src/view/screens/Profile.tsx:560 +#: src/view/screens/Profile.tsx:561 msgid "Create a Starter Pack" msgstr "" @@ -3018,6 +3018,10 @@ msgstr "" msgid "Dismiss this section" msgstr "" +#: src/components/FeedInterstitials.tsx:587 +msgid "Dismiss this suggestion" +msgstr "" + #: src/screens/Settings/AccessibilitySettings.tsx:69 #: src/screens/Settings/AccessibilitySettings.tsx:74 msgid "Display larger alt text badges" @@ -5405,7 +5409,6 @@ msgid "Lists" msgstr "" #: src/view/com/lists/MyLists.tsx:72 -#: src/view/com/lists/ProfileLists.tsx:155 msgid "Lists allow you to see content from your favorite people." msgstr "" @@ -5936,7 +5939,7 @@ msgstr "" #: src/screens/ProfileList/index.tsx:284 #: src/view/screens/Feeds.tsx:552 #: src/view/screens/Notifications.tsx:167 -#: src/view/screens/Profile.tsx:571 +#: src/view/screens/Profile.tsx:591 msgid "New post" msgstr "" @@ -6018,6 +6021,10 @@ msgstr "" msgid "No contacts with the name “{query}” found" msgstr "" +#: src/view/com/feeds/ProfileFeedgens.tsx:161 +msgid "No custom feeds yet" +msgstr "" + #: src/screens/Settings/components/ChangeHandleDialog.tsx:408 #: src/screens/Settings/components/ChangeHandleDialog.tsx:410 msgid "No DNS Panel" @@ -6045,17 +6052,21 @@ msgstr "" #: src/components/LikedByList.tsx:84 #: src/view/com/post-thread/PostLikedBy.tsx:84 -#: src/view/screens/Profile.tsx:511 +#: src/view/screens/Profile.tsx:523 msgid "No likes yet" msgstr "" +#: src/view/com/lists/ProfileLists.tsx:160 +msgid "No lists" +msgstr "" + #: src/components/ProfileCard.tsx:531 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:269 #: src/view/com/notifications/NotificationFeedItem.tsx:792 msgid "No longer following {0}" msgstr "" -#: src/view/screens/Profile.tsx:467 +#: src/view/screens/Profile.tsx:471 msgid "No media yet" msgstr "" @@ -6100,7 +6111,7 @@ msgstr "" msgid "No quotes yet" msgstr "" -#: src/view/screens/Profile.tsx:452 +#: src/view/screens/Profile.tsx:456 msgid "No replies yet" msgstr "" @@ -6143,12 +6154,16 @@ msgstr "" msgid "No search results found for \"{search}\"." msgstr "" +#: src/view/screens/Profile.tsx:555 +msgid "No Starter Packs yet" +msgstr "" + #: src/components/dialogs/EmbedConsent.tsx:104 #: src/components/dialogs/EmbedConsent.tsx:111 msgid "No thanks" msgstr "" -#: src/view/screens/Profile.tsx:489 +#: src/view/screens/Profile.tsx:497 msgid "No video posts yet" msgstr "" @@ -6970,13 +6985,13 @@ msgctxt "action" msgid "Post" msgstr "" -#: src/view/screens/Profile.tsx:469 -#: src/view/screens/Profile.tsx:470 +#: src/view/screens/Profile.tsx:475 +#: src/view/screens/Profile.tsx:476 msgid "Post a photo" msgstr "" -#: src/view/screens/Profile.tsx:491 -#: src/view/screens/Profile.tsx:492 +#: src/view/screens/Profile.tsx:501 +#: src/view/screens/Profile.tsx:502 msgid "Post a video" msgstr "" @@ -8153,12 +8168,12 @@ msgstr "" msgid "See jobs at Bluesky" msgstr "" -#: src/components/FeedInterstitials.tsx:499 -#: src/components/FeedInterstitials.tsx:562 +#: src/components/FeedInterstitials.tsx:730 +#: src/components/FeedInterstitials.tsx:793 msgid "See more" msgstr "" -#: src/components/FeedInterstitials.tsx:481 +#: src/components/FeedInterstitials.tsx:712 msgid "See more suggested profiles" msgstr "" @@ -8776,7 +8791,7 @@ msgstr "" msgid "Signed in as @{0}" msgstr "" -#: src/components/FeedInterstitials.tsx:476 +#: src/components/FeedInterstitials.tsx:707 msgid "Similar accounts" msgstr "" @@ -8827,7 +8842,7 @@ msgstr "" msgid "Some of your verifications are invalid." msgstr "" -#: src/components/FeedInterstitials.tsx:639 +#: src/components/FeedInterstitials.tsx:870 msgid "Some other feeds you might like" msgstr "" @@ -8973,8 +8988,8 @@ msgstr "" msgid "Starter packs let you easily share your favorite feeds and people with your friends." msgstr "" -#: src/view/screens/Profile.tsx:539 -msgid "Starter packs let you share your favorite feeds and people with your friends." +#: src/view/screens/Profile.tsx:553 +msgid "Starter Packs let you share your favorite feeds and people with your friends." msgstr "" #: src/screens/Settings/AboutSettings.tsx:100 @@ -9066,7 +9081,7 @@ msgid "Suggested Accounts" msgstr "" #. Accounts suggested to the user for them to follow -#: src/components/FeedInterstitials.tsx:474 +#: src/components/FeedInterstitials.tsx:705 #: src/screens/Onboarding/StepSuggestedAccounts/index.tsx:155 msgid "Suggested for you" msgstr "" @@ -9413,8 +9428,8 @@ msgstr "" msgid "There was an issue fetching your app passwords" msgstr "" -#: src/view/com/feeds/ProfileFeedgens.tsx:174 -#: src/view/com/lists/ProfileLists.tsx:175 +#: src/view/com/feeds/ProfileFeedgens.tsx:185 +#: src/view/com/lists/ProfileLists.tsx:184 msgid "There was an issue fetching your lists. Tap here to try again." msgstr "" @@ -10920,8 +10935,8 @@ msgstr "" msgid "Write a message" msgstr "" -#: src/view/screens/Profile.tsx:433 -#: src/view/screens/Profile.tsx:434 +#: src/view/screens/Profile.tsx:435 +#: src/view/screens/Profile.tsx:436 msgid "Write a post" msgstr "" @@ -11198,7 +11213,11 @@ msgstr "" msgid "You haven't created a starter pack yet!" msgstr "" -#: src/view/com/feeds/ProfileFeedgens.tsx:155 +#: src/view/com/lists/ProfileLists.tsx:159 +msgid "You haven't created any lists yet." +msgstr "" + +#: src/view/com/feeds/ProfileFeedgens.tsx:160 msgid "You haven't made any custom feeds yet." msgstr "" -- 2.51.2 From 89cffdf5d00be39422da8787020984c4f2808bdf Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Thu, 18 Dec 2025 09:45:51 -0600 Subject: [PATCH 09/13] Ignore new flag SVGs in build output (#9567) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f15f673dc..38a12f24c 100644 --- a/.gitignore +++ b/.gitignore @@ -124,3 +124,4 @@ bskyogcard/src/assets/fonts/noto-* bskyweb/static/media/*.webp bskyweb/static/media/*.jpg bskyweb/static/media/*.png +bskyweb/static/media/*.svg -- 2.51.2 From a355eedf85b557f49eeb8722aac4fbddf40a0afc Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Thu, 18 Dec 2025 11:05:39 -0600 Subject: [PATCH 10/13] Improve instructions on NoAccessScreen and bday dialog (#9571) --- .../components/NoAccessScreen.tsx | 78 ++++++++----------- src/components/dialogs/BirthDateSettings.tsx | 15 +++- 2 files changed, 47 insertions(+), 46 deletions(-) diff --git a/src/ageAssurance/components/NoAccessScreen.tsx b/src/ageAssurance/components/NoAccessScreen.tsx index 8b2a44c26..3aa69dc78 100644 --- a/src/ageAssurance/components/NoAccessScreen.tsx +++ b/src/ageAssurance/components/NoAccessScreen.tsx @@ -9,12 +9,11 @@ import { useCreateSupportLink, } from '#/lib/hooks/useCreateSupportLink' import {dateDiff, useGetTimeAgo} from '#/lib/hooks/useTimeAgo' -import {isAppPassword} from '#/lib/jwt' import {logger} from '#/logger' import {isWeb} from '#/platform/detection' import {isNative} from '#/platform/detection' import {useIsBirthdateUpdateAllowed} from '#/state/birthdate' -import {useSession, useSessionApi} from '#/state/session' +import {useSessionApi} from '#/state/session' import {atoms as a, useBreakpoints, useTheme, web} from '#/alf' import {Admonition} from '#/components/Admonition' import {AgeAssuranceAppealDialog} from '#/components/ageAssurance/AgeAssuranceAppealDialog' @@ -30,7 +29,7 @@ import {ShieldCheck_Stroke2_Corner0_Rounded as ShieldIcon} from '#/components/ic import {createStaticClick, SimpleInlineLinkText} from '#/components/Link' import {Outlet as PortalOutlet} from '#/components/Portal' import * as Toast from '#/components/Toast' -import {Span, Text} from '#/components/Typography' +import {Text} from '#/components/Typography' import {BottomSheetOutlet} from '#/../modules/bottom-sheet' import {useAgeAssurance} from '#/ageAssurance' import {useAgeAssuranceDataContext} from '#/ageAssurance/data' @@ -55,9 +54,6 @@ export function NoAccessScreen() { const {logoutCurrentAccount} = useSessionApi() const createSupportLink = useCreateSupportLink() - const {currentAccount} = useSession() - const isUsingAppPassword = isAppPassword(currentAccount?.accessJwt || '') - const aa = useAgeAssurance() const isBlocked = aa.state.status === aa.Status.Blocked const isAARegion = !!region @@ -89,22 +85,38 @@ export function NoAccessScreen() { logoutCurrentAccount('AgeAssuranceNoAccessScreen') }, [logoutCurrentAccount]) - const birthdateUpdateText = canUpdateBirthday ? ( - + const orgAdmonition = ( + - If you believe your birthdate is incorrect, you can update it by{' '} - { - logger.metric('ageAssurance:noAccessScreen:openBirthdateDialog', {}) - birthdateControl.open() - })}> - clicking here - - . + For organizational accounts, use the birthdate of the person who is + responsible for the account. - + + ) + + const birthdateUpdateText = canUpdateBirthday ? ( + <> + + + If you believe your birthdate is incorrect, you can update it by{' '} + { + logger.metric( + 'ageAssurance:noAccessScreen:openBirthdateDialog', + {}, + ) + birthdateControl.open() + })}> + clicking here + + . + + + + {orgAdmonition} + ) : ( @@ -120,15 +132,6 @@ export function NoAccessScreen() { ) - const orgAdmonition = ( - - - For organizational accounts, use the birthdate of the person who is - responsible for the account. - - - ) - return ( <> @@ -175,8 +178,6 @@ export function NoAccessScreen() { {!isBlocked && birthdateUpdateText} - - {orgAdmonition} @@ -191,8 +192,6 @@ export function NoAccessScreen() { {birthdateUpdateText} - - {orgAdmonition}
)} @@ -224,18 +223,7 @@ export function NoAccessScreen() { - {isUsingAppPassword ? ( - - - Hmm, it looks like you're logged in with an{' '} - App Password. To set your - birthdate, you'll need to log in with your main account - password, or ask whomever controls this account to do so. - - - ) : ( - orgAdmonition - )} + {orgAdmonition}
)} diff --git a/src/components/dialogs/BirthDateSettings.tsx b/src/components/dialogs/BirthDateSettings.tsx index c5205bf71..f258824a9 100644 --- a/src/components/dialogs/BirthDateSettings.tsx +++ b/src/components/dialogs/BirthDateSettings.tsx @@ -4,6 +4,7 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useCleanError} from '#/lib/hooks/useCleanError' +import {isAppPassword} from '#/lib/jwt' import {getAge, getDateAgo} from '#/lib/strings/time' import {logger} from '#/logger' import {isIOS, isWeb} from '#/platform/detection' @@ -15,6 +16,7 @@ import { usePreferencesQuery, type UsePreferencesQueryResponse, } from '#/state/queries/preferences' +import {useSession} from '#/state/session' import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' import {atoms as a, useTheme, web} from '#/alf' import {Admonition} from '#/components/Admonition' @@ -23,7 +25,7 @@ import * as Dialog from '#/components/Dialog' import {DateField} from '#/components/forms/DateField' import {SimpleInlineLinkText} from '#/components/Link' import {Loader} from '#/components/Loader' -import {Text} from '#/components/Typography' +import {Span, Text} from '#/components/Typography' export function BirthDateSettingsDialog({ control, @@ -34,6 +36,8 @@ export function BirthDateSettingsDialog({ const {_} = useLingui() const {isLoading, error, data: preferences} = usePreferencesQuery() const isBirthdateUpdateAllowed = useIsBirthdateUpdateAllowed() + const {currentAccount} = useSession() + const isUsingAppPassword = isAppPassword(currentAccount?.accessJwt || '') return ( @@ -65,6 +69,15 @@ export function BirthDateSettingsDialog({ } style={[a.rounded_sm]} /> + ) : isUsingAppPassword ? ( + + + Hmm, it looks like you're logged in with an{' '} + App Password. To set your + birthdate, you'll need to log in with your main account + password, or ask whomever controls this account to do so. + + ) : ( )} -- 2.51.2 From 998ee78e3dab561778174b9370c904536f79982f Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Thu, 18 Dec 2025 12:08:17 -0600 Subject: [PATCH 11/13] Move NUXDialogs into shell (#9573) --- src/App.native.tsx | 2 -- src/App.web.tsx | 2 -- src/view/shell/index.tsx | 2 ++ src/view/shell/index.web.tsx | 2 ++ 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/App.native.tsx b/src/App.native.tsx index fb3008627..34c3cc204 100644 --- a/src/App.native.tsx +++ b/src/App.native.tsx @@ -61,7 +61,6 @@ import {Shell} from '#/view/shell' import {ThemeProvider as Alf} from '#/alf' import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Provider as ContextMenuProvider} from '#/components/ContextMenu' -import {NuxDialogs} from '#/components/dialogs/nuxs' import {useStarterPackEntry} from '#/components/hooks/useStarterPackEntry' import {Provider as IntentDialogProvider} from '#/components/intents/IntentDialogs' import {Provider as PolicyUpdateOverlayProvider} from '#/components/PolicyUpdateOverlay' @@ -165,7 +164,6 @@ function InnerApp() { - diff --git a/src/App.web.tsx b/src/App.web.tsx index f4b514dfc..956c52005 100644 --- a/src/App.web.tsx +++ b/src/App.web.tsx @@ -48,7 +48,6 @@ import {Shell} from '#/view/shell/index' import {ThemeProvider as Alf} from '#/alf' import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Provider as ContextMenuProvider} from '#/components/ContextMenu' -import {NuxDialogs} from '#/components/dialogs/nuxs' import {useStarterPackEntry} from '#/components/hooks/useStarterPackEntry' import {Provider as IntentDialogProvider} from '#/components/intents/IntentDialogs' import {Provider as PolicyUpdateOverlayProvider} from '#/components/PolicyUpdateOverlay' @@ -138,7 +137,6 @@ function InnerApp() { - diff --git a/src/view/shell/index.tsx b/src/view/shell/index.tsx index f27c982cb..7f53755fc 100644 --- a/src/view/shell/index.tsx +++ b/src/view/shell/index.tsx @@ -32,6 +32,7 @@ import {EmailDialog} from '#/components/dialogs/EmailDialog' import {InAppBrowserConsentDialog} from '#/components/dialogs/InAppBrowserConsent' import {LinkWarningDialog} from '#/components/dialogs/LinkWarning' import {MutedWordsDialog} from '#/components/dialogs/MutedWords' +import {NuxDialogs} from '#/components/dialogs/nuxs' import {SigninDialog} from '#/components/dialogs/Signin' import { Outlet as PolicyUpdateOverlayPortalOutlet, @@ -110,6 +111,7 @@ function ShellInner() { + {/* Until policy update has been completed by the user, don't render anything that is portaled */} {policyUpdateState.completed && ( diff --git a/src/view/shell/index.web.tsx b/src/view/shell/index.web.tsx index a37b68032..dc5c7d7bd 100644 --- a/src/view/shell/index.web.tsx +++ b/src/view/shell/index.web.tsx @@ -22,6 +22,7 @@ import {AgeAssuranceRedirectDialog} from '#/components/ageAssurance/AgeAssurance import {EmailDialog} from '#/components/dialogs/EmailDialog' import {LinkWarningDialog} from '#/components/dialogs/LinkWarning' import {MutedWordsDialog} from '#/components/dialogs/MutedWords' +import {NuxDialogs} from '#/components/dialogs/nuxs' import {SigninDialog} from '#/components/dialogs/Signin' import {useWelcomeModal} from '#/components/hooks/useWelcomeModal' import { @@ -86,6 +87,7 @@ function ShellInner() { + {welcomeModalControl.isOpen && ( -- 2.51.2 From a14a9be1274006b881653f3f1dd979f18de3d762 Mon Sep 17 00:00:00 2001 From: pfrazee <1270099+pfrazee@users.noreply.github.com> Date: Fri, 19 Dec 2025 02:44:03 +0000 Subject: [PATCH 12/13] Nightly source-language update --- src/locale/locales/en/messages.po | 92 +++++++++++++++---------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/locale/locales/en/messages.po b/src/locale/locales/en/messages.po index 6ea91d4a7..a30f62432 100644 --- a/src/locale/locales/en/messages.po +++ b/src/locale/locales/en/messages.po @@ -844,7 +844,7 @@ msgstr "" msgid "Add user to list" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:223 +#: src/ageAssurance/components/NoAccessScreen.tsx:222 msgid "Add your birthdate" msgstr "" @@ -914,7 +914,7 @@ msgctxt "toast" msgid "Age assurance inquiry was submitted" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:357 +#: src/ageAssurance/components/NoAccessScreen.tsx:345 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:191 msgid "Age assurance only takes a few minutes" msgstr "" @@ -1448,7 +1448,7 @@ msgstr "" msgid "Begin the age assurance process by completing the fields below." msgstr "" -#: src/components/dialogs/BirthDateSettings.tsx:149 +#: src/components/dialogs/BirthDateSettings.tsx:162 msgid "Birthdate" msgstr "" @@ -2022,11 +2022,11 @@ msgstr "" msgid "click here" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:114 +#: src/ageAssurance/components/NoAccessScreen.tsx:126 msgid "Click here to contact our support team" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:248 +#: src/ageAssurance/components/NoAccessScreen.tsx:236 msgid "Click here to log out" msgstr "" @@ -2034,8 +2034,8 @@ msgstr "" msgid "Click here to restart the verification process." msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:97 -#: src/ageAssurance/components/NoAccessScreen.tsx:220 +#: src/ageAssurance/components/NoAccessScreen.tsx:103 +#: src/ageAssurance/components/NoAccessScreen.tsx:219 msgid "Click here to update your birthdate" msgstr "" @@ -2121,7 +2121,7 @@ msgstr "" msgid "Close dialog" msgstr "" -#: src/view/shell/index.web.tsx:111 +#: src/view/shell/index.web.tsx:113 msgid "Close drawer menu" msgstr "" @@ -2252,7 +2252,7 @@ msgstr "" msgid "Confirm delete account" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:371 +#: src/ageAssurance/components/NoAccessScreen.tsx:359 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:87 #: src/components/dialogs/DeviceLocationRequestDialog.tsx:40 #: src/components/dialogs/DeviceLocationRequestDialog.tsx:105 @@ -2279,7 +2279,7 @@ msgstr "" msgid "Connection issue" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:308 +#: src/ageAssurance/components/NoAccessScreen.tsx:296 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:130 #: src/components/ageAssurance/AgeAssuranceAppealDialog.tsx:29 msgid "Contact our moderation team" @@ -3074,8 +3074,8 @@ msgstr "" #: src/components/contacts/components/InviteInfo.tsx:78 #: src/components/contacts/screens/ViewMatches.tsx:392 #: src/components/contacts/screens/ViewMatches.tsx:409 -#: src/components/dialogs/BirthDateSettings.tsx:183 -#: src/components/dialogs/BirthDateSettings.tsx:190 +#: src/components/dialogs/BirthDateSettings.tsx:196 +#: src/components/dialogs/BirthDateSettings.tsx:203 #: src/components/dialogs/ServerInput.tsx:240 #: src/components/dialogs/ServerInput.tsx:242 #: src/components/dms/AfterReportDialog.tsx:142 @@ -3449,7 +3449,7 @@ msgstr "" msgid "Enter the username or email address you used when you created your account" msgstr "" -#: src/components/dialogs/BirthDateSettings.tsx:150 +#: src/components/dialogs/BirthDateSettings.tsx:163 msgid "Enter your birthdate" msgstr "" @@ -4209,7 +4209,7 @@ msgstr "" msgid "Food" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:125 +#: src/ageAssurance/components/NoAccessScreen.tsx:90 msgid "For organizational accounts, use the birthdate of the person who is responsible for the account." msgstr "" @@ -4556,11 +4556,11 @@ msgstr "" msgid "Hey there 👋" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:167 +#: src/ageAssurance/components/NoAccessScreen.tsx:170 msgid "Hey there!" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:202 +#: src/ageAssurance/components/NoAccessScreen.tsx:201 msgid "Hi there!" msgstr "" @@ -4660,7 +4660,7 @@ msgstr "" msgid "Hides the content" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:229 +#: src/components/dialogs/BirthDateSettings.tsx:74 msgid "Hmm, it looks like you're logged in with an <0>App Password. To set your birthdate, you'll need to log in with your main account password, or ask whomever controls this account to do so." msgstr "" @@ -4765,11 +4765,11 @@ msgstr "" msgid "If you are not yet an adult according to the laws of your country, your parent or legal guardian must read these Terms on your behalf." msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:110 +#: src/ageAssurance/components/NoAccessScreen.tsx:122 msgid "If you believe your birthdate is incorrect, please <0>contact our support team." msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:94 +#: src/ageAssurance/components/NoAccessScreen.tsx:100 msgid "If you believe your birthdate is incorrect, you can update it by <0>clicking here." msgstr "" @@ -4853,7 +4853,7 @@ msgstr "" msgid "Import contacts to find your friends" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:205 +#: src/ageAssurance/components/NoAccessScreen.tsx:204 msgid "In order to provide an age-appropriate experience, we need to know your birthdate. This is a one-time thing, and your data will be kept private." msgstr "" @@ -4998,7 +4998,7 @@ msgstr "" msgid "Invites, but personal" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:368 +#: src/ageAssurance/components/NoAccessScreen.tsx:356 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:84 msgid "Is your location not accurate? <0>Tap here to confirm your location." msgstr "" @@ -5095,12 +5095,12 @@ msgstr "" msgid "Larger" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:351 +#: src/ageAssurance/components/NoAccessScreen.tsx:339 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:185 msgid "Last initiated {timeAgo} ago" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:349 +#: src/ageAssurance/components/NoAccessScreen.tsx:337 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:183 msgid "Last initiated just now" msgstr "" @@ -5825,8 +5825,8 @@ msgstr "" msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them." msgstr "" -#: src/components/dialogs/BirthDateSettings.tsx:43 #: src/components/dialogs/BirthDateSettings.tsx:47 +#: src/components/dialogs/BirthDateSettings.tsx:51 msgid "My Birthdate" msgstr "" @@ -7935,7 +7935,7 @@ msgstr "" msgid "Returns to the previous step" msgstr "" -#: src/components/dialogs/BirthDateSettings.tsx:190 +#: src/components/dialogs/BirthDateSettings.tsx:203 #: src/components/dialogs/lists/CreateOrEditListDialog.tsx:292 #: src/components/dialogs/lists/CreateOrEditListDialog.tsx:307 #: src/components/dialogs/PostInteractionSettingsDialog.tsx:662 @@ -7961,7 +7961,7 @@ msgctxt "action" msgid "Save" msgstr "" -#: src/components/dialogs/BirthDateSettings.tsx:183 +#: src/components/dialogs/BirthDateSettings.tsx:196 msgid "Save birthdate" msgstr "" @@ -8440,7 +8440,7 @@ msgstr "" msgid "Set who can reply to your post" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:212 +#: src/ageAssurance/components/NoAccessScreen.tsx:211 msgid "Set your birthdate below and we'll get you back to posting and exploring in no time!" msgstr "" @@ -8899,8 +8899,8 @@ msgstr "" msgid "Sorry, we're unable to load account suggestions at this time." msgstr "" -#: src/App.native.tsx:127 -#: src/App.web.tsx:100 +#: src/App.native.tsx:126 +#: src/App.web.tsx:99 msgid "Sorry! Your session expired. Please sign in again." msgstr "" @@ -9212,7 +9212,7 @@ msgstr "" msgid "Terms" msgstr "" -#: src/components/dialogs/BirthDateSettings.tsx:169 +#: src/components/dialogs/BirthDateSettings.tsx:182 #: src/components/PolicyUpdateOverlay/updates/202508/index.tsx:30 #: src/components/PolicyUpdateOverlay/updates/202508/index.tsx:97 #: src/Navigation.tsx:338 @@ -9241,7 +9241,7 @@ msgstr "" msgid "Thanks, you have successfully verified your email address. You can close this dialog." msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:397 +#: src/ageAssurance/components/NoAccessScreen.tsx:385 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:113 msgid "Thanks! You're all set." msgstr "" @@ -9287,7 +9287,7 @@ msgstr "" msgid "The author of this thread has hidden this reply." msgstr "" -#: src/components/dialogs/BirthDateSettings.tsx:156 +#: src/components/dialogs/BirthDateSettings.tsx:169 msgid "The birthdate you've entered means you are under 18 years old. Certain content and features may be unavailable to you." msgstr "" @@ -9383,7 +9383,7 @@ msgstr "" msgid "Theme" msgstr "" -#: src/components/dialogs/BirthDateSettings.tsx:91 +#: src/components/dialogs/BirthDateSettings.tsx:104 msgid "There is a limit to how often you can change your birthdate. You may need to wait a day or two before updating it again." msgstr "" @@ -9607,7 +9607,7 @@ msgstr "" msgid "This handle is reserved. Please try a different one." msgstr "" -#: src/components/dialogs/BirthDateSettings.tsx:51 +#: src/components/dialogs/BirthDateSettings.tsx:55 msgid "This information is private and not shared with other users." msgstr "" @@ -9785,7 +9785,7 @@ msgstr "" msgid "To disable your email 2FA method, please verify your access to <0>{0}" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:245 +#: src/ageAssurance/components/NoAccessScreen.tsx:233 msgid "To log out, <0>click here." msgstr "" @@ -10000,7 +10000,7 @@ msgstr "" msgid "Unfortunately, none of your subscribed labelers supports this report type." msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:187 +#: src/ageAssurance/components/NoAccessScreen.tsx:188 msgid "Unfortunately, the birthdate you have saved to your profile makes you too young to access Bluesky." msgstr "" @@ -10361,7 +10361,7 @@ msgstr "" msgid "Verify account" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:334 +#: src/ageAssurance/components/NoAccessScreen.tsx:322 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:168 msgid "Verify again" msgstr "" @@ -10388,8 +10388,8 @@ msgstr "" msgid "Verify email dialog" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:322 -#: src/ageAssurance/components/NoAccessScreen.tsx:336 +#: src/ageAssurance/components/NoAccessScreen.tsx:310 +#: src/ageAssurance/components/NoAccessScreen.tsx:324 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:156 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:170 msgid "Verify now" @@ -10728,7 +10728,7 @@ msgstr "" msgid "We were unable to determine if you are allowed to upload videos. Please try again." msgstr "" -#: src/components/dialogs/BirthDateSettings.tsx:63 +#: src/components/dialogs/BirthDateSettings.tsx:67 msgid "We were unable to load your birthdate preferences. Please try again." msgstr "" @@ -10787,7 +10787,7 @@ msgstr "" msgid "We're so excited to have you join us!" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:390 +#: src/ageAssurance/components/NoAccessScreen.tsx:378 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:106 msgid "We're sorry, but based on your device's location, you are currently located in a region that requires age assurance." msgstr "" @@ -10995,7 +10995,7 @@ msgstr "" msgid "You are a trusted verifier" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:170 +#: src/ageAssurance/components/NoAccessScreen.tsx:173 msgid "You are accessing Bluesky from a region that legally requires us to verify your age before allowing you to access the app." msgstr "" @@ -11003,7 +11003,7 @@ msgstr "" msgid "You are creating an account on" msgstr "" -#: src/ageAssurance/components/NoAccessScreen.tsx:304 +#: src/ageAssurance/components/NoAccessScreen.tsx:292 #: src/components/ageAssurance/AgeAssuranceAccountCard.tsx:126 msgid "You are currently unable to access Bluesky's Age Assurance flow. Please <0>contact our moderation team if you believe this is an error." msgstr "" @@ -11262,7 +11262,7 @@ msgstr "" msgid "You must be 13 years of age or older to create an account." msgstr "" -#: src/components/dialogs/BirthDateSettings.tsx:165 +#: src/components/dialogs/BirthDateSettings.tsx:178 msgid "You must be at least 13 years old to use Bluesky. Read our <0>Terms of Service for more information." msgstr "" @@ -11307,8 +11307,8 @@ msgstr "" msgid "You reacted {0} to {1}" msgstr "" -#: src/components/dialogs/BirthDateSettings.tsx:77 -#: src/components/dialogs/BirthDateSettings.tsx:87 +#: src/components/dialogs/BirthDateSettings.tsx:90 +#: src/components/dialogs/BirthDateSettings.tsx:100 msgid "You recently changed your birthdate" msgstr "" -- 2.51.2 From 699fdbac018c134a7eae974f03f200555d69f321 Mon Sep 17 00:00:00 2001 From: hailey Date: Mon, 22 Dec 2025 19:21:17 -0800 Subject: [PATCH 13/13] update actions (#9586) * update actions * update actions * $ * procenv --- .github/workflows/build-submit-android.yml | 8 +++++-- .github/workflows/build-submit-ios.yml | 8 +++++-- .../workflows/bundle-deploy-eas-update.yml | 21 +++++++++++++------ .github/workflows/pull-request-comment.yml | 10 ++++++--- .github/workflows/pull-request-commit.yml | 15 +++++++++---- .github/workflows/verify-yarn-lock.yml | 8 +++++-- 6 files changed, 51 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build-submit-android.yml b/.github/workflows/build-submit-android.yml index 595cfa74d..e76eacbc2 100644 --- a/.github/workflows/build-submit-android.yml +++ b/.github/workflows/build-submit-android.yml @@ -79,13 +79,15 @@ jobs: echo "$json" > google-services.json - name: 🏗️ EAS Build + env: + PROFILE: ${{ inputs.profile || 'testflight-android' }} run: > SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }} SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }} yarn use-build-number-with-bump eas build -p android - --profile ${{ inputs.profile || 'testflight-android' }} + --profile $PROFILE --local --output build.aab --non-interactive - name: ✍️ Rename Testflight bundle @@ -194,4 +196,6 @@ jobs: - name: ✏️ Write commit hash to cache if: ${{ inputs.profile == 'testflight-android' }} - run: echo ${{ github.sha }} > most-recent-testflight-commit.txt + env: + GITHUB_SHA: ${{ github.sha }} + run: echo $GITHUB_SHA > most-recent-testflight-commit.txt diff --git a/.github/workflows/build-submit-ios.yml b/.github/workflows/build-submit-ios.yml index 24eba2489..391f95131 100644 --- a/.github/workflows/build-submit-ios.yml +++ b/.github/workflows/build-submit-ios.yml @@ -91,13 +91,15 @@ jobs: echo "${{ secrets.GOOGLE_SERVICES_TOKEN }}" > google-services.json - name: 🏗️ EAS Build + env: + PROFILE: ${{ inputs.profile || 'testflight' }} run: > SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }} SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }} yarn use-build-number-with-bump eas build -p ios - --profile ${{ inputs.profile || 'testflight' }} + --profile $PROFILE --local --output build.tar.gz --non-interactive - name: 📂 Extract build artifact @@ -147,5 +149,7 @@ jobs: key: most-recent-testflight-commit - name: ✏️ Write commit hash to cache + env: + GITHUB_SHA: ${{ github.sha }} if: ${{ inputs.profile == 'testflight' }} - run: echo ${{ github.sha }} > most-recent-testflight-commit.txt + run: echo $GITHUB_SHA > most-recent-testflight-commit.txt diff --git a/.github/workflows/bundle-deploy-eas-update.yml b/.github/workflows/bundle-deploy-eas-update.yml index 3204c7bb8..af629dd55 100644 --- a/.github/workflows/bundle-deploy-eas-update.yml +++ b/.github/workflows/bundle-deploy-eas-update.yml @@ -39,10 +39,12 @@ jobs: # Validate the version if one is supplied. This should generally happen if the update is for a production client - name: 🧐 Validate version + env: + RUNTIME_VERSION: ${{ inputs.runtimeVersion }} if: ${{ inputs.runtimeVersion }} run: | - if [ -z "${{ inputs.runtimeVersion }}" ]; then - [[ "${{ inputs.runtimeVersion }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && echo "Version is valid" || exit 1 + if [ -z "$RUNTIME_VERSION" ]; then + [[ "$RUNTIME_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && echo "Version is valid" || exit 1 fi - name: ⬇️ Checkout @@ -103,12 +105,15 @@ jobs: # eas.json not used here, set EXPO_PUBLIC_ENV - name: Env + env: + CHANNEL: ${{ inputs.channel || 'testflight' }} + GITHUB_SHA: ${{ github.sha }} id: env if: ${{ !steps.fingerprint.outputs.includes-changes }} run: | export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}' echo "${{ secrets.ENV_TOKEN }}" > .env - echo "EXPO_PUBLIC_ENV=${{ inputs.channel || 'testflight' }}" >> .env + echo "EXPO_PUBLIC_ENV=$CHANNEL" >> .env echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env @@ -145,7 +150,7 @@ jobs: - name: ✏️ Write commit hash to cache if: ${{ !steps.fingerprint.outputs.includes-changes }} - run: echo ${{ github.sha }} > most-recent-testflight-commit.txt + run: echo $GITHUB_SHA > most-recent-testflight-commit.txt # GitHub actions are horrible so let's just copy paste this in buildIfNecessaryIOS: @@ -249,7 +254,9 @@ jobs: - name: ✏️ Write commit hash to cache if: ${{ inputs.channel == 'testflight' }} - run: echo ${{ github.sha }} > most-recent-testflight-commit.txt + env: + GITHUB_SHA: ${{ github.sha }} + run: echo $GITHUB_SHA > most-recent-testflight-commit.txt buildIfNecessaryAndroid: name: Build and Submit Android @@ -363,5 +370,7 @@ jobs: key: most-recent-testflight-commit - name: ✏️ Write commit hash to cache + env: + GITHUB_SHA: ${{ github.sha }} if: ${{ inputs.channel != 'testflight' && inputs.channel != 'production' }} - run: echo ${{ github.sha }} > most-recent-testflight-commit.txt + run: echo $GITHUB_SHA > most-recent-testflight-commit.txt diff --git a/.github/workflows/pull-request-comment.yml b/.github/workflows/pull-request-comment.yml index 9fde88ad3..5668854f0 100644 --- a/.github/workflows/pull-request-comment.yml +++ b/.github/workflows/pull-request-comment.yml @@ -32,7 +32,7 @@ jobs: fi - if [[ "${{ github.event.comment.body }}" == *"ota"* ]]; then + if [[ "$COMMENT" == *"ota"* ]]; then has_ota=true else has_ota=false @@ -75,6 +75,8 @@ jobs: steps: - name: Get PR HEAD SHA + env: + ISSUE_NUMBER: ${{ github.event.issue.number }} id: pr-info uses: actions/github-script@v7 with: @@ -82,7 +84,7 @@ jobs: const pr = await github.rest.pulls.get({ owner: context.repo.owner, repo: context.repo.repo, - pull_number: ${{ github.event.issue.number }} + pull_number: process.env.ISSUE_NUMBER, }); console.log(`PR HEAD SHA: ${pr.data.head.sha}`); @@ -184,13 +186,15 @@ jobs: - name: 💬 Drop a comment uses: marocchino/sticky-pull-request-comment@v2 + env: + ISSUE_NUMBER: ${{ github.event.issue.number }} with: header: pull-request-eas-build-${{ steps.pr-info.outputs.head-sha }} number: ${{ github.event.issue.number }} message: | Your requested OTA deployment was successful! You may now apply it by either scanning the QR code or opening the deep link below in your browser: - + `bluesky://intent/apply-ota?channel=pull-request-${{ github.event.issue.number }}` --- diff --git a/.github/workflows/pull-request-commit.yml b/.github/workflows/pull-request-commit.yml index bca92d470..6e575148e 100644 --- a/.github/workflows/pull-request-commit.yml +++ b/.github/workflows/pull-request-commit.yml @@ -35,20 +35,27 @@ jobs: cache: yarn - name: Ensure tracking relevant branches and checkout base + env: + HEAD_REF: ${{ github.head_ref }} + BASE_REF: ${{ github.base_ref }} run: | - git checkout ${{ github.head_ref }} - git checkout ${{ github.base_ref }} + git checkout $HEAD_REF + git checkout $BASE_REF - name: Get the base commit id: base-commit - run: echo base-commit=$(git log -n 1 ${{ github.base_ref }} --pretty=format:'%H') >> "$GITHUB_OUTPUT" + env: + BASE_REF: ${{ github.base_ref }} + run: echo base-commit=$(git log -n 1 $BASE_REF --pretty=format:'%H') >> "$GITHUB_OUTPUT" - name: Merge PR commit + env: + HEAD_REF: ${{ github.head_ref }} run: | # Have to set a git config for the merge to work git config --global user.email "github-actions[bot]@users.noreply.github.com" git config --global user.name "github-actions[bot]" - git merge --no-edit ${{ github.head_ref }} + git merge --no-edit $HEAD_REF yarn install yarn intl:build diff --git a/.github/workflows/verify-yarn-lock.yml b/.github/workflows/verify-yarn-lock.yml index afa554c59..6eadf7be7 100644 --- a/.github/workflows/verify-yarn-lock.yml +++ b/.github/workflows/verify-yarn-lock.yml @@ -17,7 +17,9 @@ jobs: fetch-depth: 0 - name: Fetch base branch - run: git fetch origin ${{ github.base_ref }} --depth=1 + env: + BASE_REF: ${{ github.base_ref }} + run: git fetch origin $BASE_REF --depth=1 - name: Install node uses: actions/setup-node@v6 @@ -25,7 +27,9 @@ jobs: node-version-file: .nvmrc - name: Reset yarn.lock to base - run: git show "origin/${{ github.base_ref }}:yarn.lock" > yarn.lock + env: + BASE_REF: ${{ github.base_ref }} + run: git show "origin/$BASE_REF:yarn.lock" > yarn.lock - name: Yarn install uses: Wandalen/wretry.action@master