Unblock React Compiler for 18 components with value blocks inside try (#11548)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tomasz Zawadzki
2026-08-31 15:47:42 +02:00
committed by GitHub
parent 80d09a242d
commit 8bf5696d3c
18 changed files with 179 additions and 85 deletions
@@ -450,10 +450,16 @@ function DialogInner({
const feedRkey = useMemo(() => new AtUri(info.uri).rkey, [info.uri])
const onToggleLiked = async () => {
/*
* Hoisted out of the `try`: React Compiler cannot lower a logical
* expression in a test position there, and the `else` below rules out
* splitting this into nested ifs.
*/
const shouldUnlike = isLiked && likeUri
try {
playHaptic()
if (isLiked && likeUri) {
if (shouldUnlike) {
await unlikeFeed({uri: likeUri})
setLikeUri('')
ax.metric('feed:unlike', {feedUrl: info.uri})
@@ -95,11 +95,13 @@ function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) {
const onSave = useCallback(async () => {
setError('')
const embeddingRules = maybeEditedPostgate.embeddingRules ?? []
try {
await setPostInteractionSettings({
threadgateAllowRules:
threadgateAllowUISettingToAllowRecordValue(maybeEditedAllowUI),
postgateEmbeddingRules: maybeEditedPostgate.embeddingRules ?? [],
postgateEmbeddingRules: embeddingRules,
})
Toast.show(_(msg({message: 'Settings saved', context: 'toast'})))
} catch (e: any) {
+16 -10
View File
@@ -78,11 +78,12 @@ export function StepFinished() {
logger.error('Failed to fetch starter pack', {safeMessage: e})
// don't tell the user, just get them through onboarding.
}
const starterPackList = starterPack?.list
try {
if (starterPack?.list) {
if (starterPackList) {
listItems = await getAllListMembers(
appviewClient,
starterPack.list.uri,
starterPackList.uri,
)
}
} catch (e) {
@@ -93,19 +94,24 @@ export function StepFinished() {
}
}
/*
* Hoisted above the `try`: React Compiler cannot lower these inside one, and
* `listItems` is already settled by the earlier try/catch.
*/
const followDids = [
BSKY_APP_ACCOUNT_DID,
...(listItems?.map(i => i.subject.did) ?? []),
]
const starterPackRef = starterPack
? {uri: starterPack.uri, cid: starterPack.cid}
: undefined
try {
const {interestsStepResults, profileStepResults} = state
const {selectedInterests} = interestsStepResults
await Promise.all([
bulkWriteFollows(
pdsClient,
appviewClient,
[BSKY_APP_ACCOUNT_DID, ...(listItems?.map(i => i.subject.did) ?? [])],
starterPack
? {uri: starterPack.uri, cid: starterPack.cid}
: undefined,
),
bulkWriteFollows(pdsClient, appviewClient, followDids, starterPackRef),
(async () => {
// Interests need to get saved first, then we can write the feeds to prefs
await pdsClient.call(setInterestsPref, {tags: selectedInterests})
@@ -259,6 +259,9 @@ export function HeaderLabelerButtons({
requireAuth(async (): Promise<void> => {
playHaptic()
const subscribe = !isSubscribed
const subscribeMetric = subscribe
? 'moderation:subscribedToLabeler'
: 'moderation:unsubscribedFromLabeler'
try {
await toggleSubscription({
@@ -266,12 +269,7 @@ export function HeaderLabelerButtons({
subscribe,
})
ax.metric(
subscribe
? 'moderation:subscribedToLabeler'
: 'moderation:unsubscribedFromLabeler',
{},
)
ax.metric(subscribeMetric, {})
} catch (e: any) {
reset()
if (e.message === 'MAX_LABELERS') {
@@ -238,14 +238,17 @@ export function HeaderStandardButtons({
const onPressFollow = () => {
playHaptic()
const displayNameOrHandle = profile.displayName || profile.handle
requireAuth(async () => {
try {
await queueFollow()
onFollow?.()
if (onFollow) {
onFollow()
}
Toast.show(
_(
msg`Following ${sanitizeDisplayName(
profile.displayName || profile.handle,
displayNameOrHandle,
moderation.ui('displayName'),
)}`,
),
@@ -264,14 +267,17 @@ export function HeaderStandardButtons({
const onPressUnfollow = () => {
playHaptic()
const displayNameOrHandle = profile.displayName || profile.handle
requireAuth(async () => {
try {
await queueUnfollow()
onUnfollow?.()
if (onUnfollow) {
onUnfollow()
}
Toast.show(
_(
msg`No longer following ${sanitizeDisplayName(
profile.displayName || profile.handle,
displayNameOrHandle,
moderation.ui('displayName'),
)}`,
),
@@ -64,6 +64,14 @@ export function Header({
const onTogglePinned = async () => {
playHaptic()
/*
* Hoisted above the `try`: inside it, `pinned` is `!savedFeedConfig.pinned`,
* which is `!isPinned` on the branch that uses this.
*/
const pinnedMessage = !isPinned
? _(msg`Pinned to your feeds`)
: _(msg`Unpinned from your feeds`)
try {
if (savedFeedConfig) {
const pinned = !savedFeedConfig.pinned
@@ -73,11 +81,7 @@ export function Header({
pinned,
},
])
Toast.show(
pinned
? _(msg`Pinned to your feeds`)
: _(msg`Unpinned from your feeds`),
)
Toast.show(pinnedMessage)
} else {
await addSavedFeeds([
{
@@ -5,6 +5,15 @@ import {type CaptchaWebViewProps} from './CaptchaWebView.shared'
const REDIRECT_HOST = new URL(window.location.href).host
/**
* Module scope because React Compiler cannot lower an optional chain inside a
* `try`, and this one has to stay in the `try` - reading `location` on a
* cross-origin frame throws.
*/
function getFrameHref(frame: HTMLIFrameElement | null): string | undefined {
return frame?.contentWindow?.location.href
}
export function CaptchaWebView({
url,
stateParam,
@@ -29,7 +38,7 @@ export function CaptchaWebView({
) as HTMLIFrameElement
try {
const href = frame?.contentWindow?.location.href
const href = getFrameHref(frame)
if (!href) return
const urlp = new URL(href)
@@ -37,7 +46,12 @@ export function CaptchaWebView({
if (urlp.host !== REDIRECT_HOST) return
const code = urlp.searchParams.get('code')
if (urlp.searchParams.get('state') !== stateParam || !code) {
const stateMismatch = urlp.searchParams.get('state') !== stateParam
if (stateMismatch) {
onError({error: 'Invalid state or code'})
return
}
if (!code) {
onError({error: 'Invalid state or code'})
return
}