Unblock React Compiler for 5 components with early exits inside try
Where a `return` sits in the try or the catch, the `finally` body has to be duplicated on that exit path before it can be hoisted below the try/catch. Where a `throw` is used to jump to the catch, an explicit test replaces it. Each of these then revealed a second cause in the same try, so the fixes go together: an optional chain hoisted above the try where it does not depend on anything the try produces, moved into a module-scope helper where it does, and one `&&` in an if-test split into nested ifs. Skipped components: 125 -> 120. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,12 +21,12 @@ export function useGoogleTranslate() {
|
|||||||
if (IS_ANDROID) {
|
if (IS_ANDROID) {
|
||||||
try {
|
try {
|
||||||
// use `getApplicationIconAsync` to determine if the translate app is installed
|
// use `getApplicationIconAsync` to determine if the translate app is installed
|
||||||
if (
|
const installed = await IntentLauncher.getApplicationIconAsync(
|
||||||
!(await IntentLauncher.getApplicationIconAsync(
|
'com.google.android.apps.translate',
|
||||||
'com.google.android.apps.translate',
|
)
|
||||||
))
|
if (!installed) {
|
||||||
) {
|
openLink(translateUrl)
|
||||||
throw new Error('Translate app not installed')
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this should only be called one at a time, use something like
|
// TODO: this should only be called one at a time, use something like
|
||||||
|
|||||||
@@ -83,10 +83,10 @@ export function BetaFeaturesSettingsScreen({}: Props) {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error('Failed to toggle beta features', {safeMessage: e})
|
logger.error('Failed to toggle beta features', {safeMessage: e})
|
||||||
Toast.show(l`Something went wrong, please try again.`, {type: 'error'})
|
Toast.show(l`Something went wrong, please try again.`, {type: 'error'})
|
||||||
return
|
|
||||||
} finally {
|
|
||||||
setIsPending(false)
|
setIsPending(false)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
setIsPending(false)
|
||||||
/*
|
/*
|
||||||
* The toggle already succeeded; re-evaluate feature gates against the new
|
* The toggle already succeeded; re-evaluate feature gates against the new
|
||||||
* attribute in-session as a best-effort follow-up. A failure here should
|
* attribute in-session as a best-effort follow-up. A failure here should
|
||||||
|
|||||||
@@ -76,10 +76,11 @@ export function StepHandle() {
|
|||||||
|
|
||||||
dispatch({type: 'setIsLoading', value: true})
|
dispatch({type: 'setIsLoading', value: true})
|
||||||
|
|
||||||
|
const serviceDid = state.serviceDescription?.did ?? 'UNKNOWN'
|
||||||
try {
|
try {
|
||||||
const {available: handleAvailable} = await checkHandleAvailability(
|
const {available: handleAvailable} = await checkHandleAvailability(
|
||||||
createFullHandle(handle, state.userDomain),
|
createFullHandle(handle, state.userDomain),
|
||||||
state.serviceDescription?.did ?? 'UNKNOWN',
|
serviceDid,
|
||||||
{},
|
{},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -90,6 +91,7 @@ export function StepHandle() {
|
|||||||
value: _(msg`That username is already taken`),
|
value: _(msg`That username is already taken`),
|
||||||
field: 'handle',
|
field: 'handle',
|
||||||
})
|
})
|
||||||
|
dispatch({type: 'setIsLoading', value: false})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
ax.metric('signup:handleAvailable', {typeahead: false})
|
ax.metric('signup:handleAvailable', {typeahead: false})
|
||||||
@@ -99,9 +101,8 @@ export function StepHandle() {
|
|||||||
safeMessage: error,
|
safeMessage: error,
|
||||||
})
|
})
|
||||||
// do nothing on error, let them pass
|
// do nothing on error, let them pass
|
||||||
} finally {
|
|
||||||
dispatch({type: 'setIsLoading', value: false})
|
|
||||||
}
|
}
|
||||||
|
dispatch({type: 'setIsLoading', value: false})
|
||||||
|
|
||||||
ax.metric('signup:nextPressed', {
|
ax.metric('signup:nextPressed', {
|
||||||
activeStep: state.activeStep,
|
activeStep: state.activeStep,
|
||||||
|
|||||||
@@ -322,6 +322,7 @@ export function useSubmitSignup() {
|
|||||||
dispatch({type: 'setError', value: ''})
|
dispatch({type: 'setError', value: ''})
|
||||||
dispatch({type: 'setIsLoading', value: true})
|
dispatch({type: 'setIsLoading', value: true})
|
||||||
|
|
||||||
|
const verificationCode = state.pendingSubmit?.verificationCode
|
||||||
try {
|
try {
|
||||||
await createAccount(
|
await createAccount(
|
||||||
{
|
{
|
||||||
@@ -331,7 +332,7 @@ export function useSubmitSignup() {
|
|||||||
password: state.password,
|
password: state.password,
|
||||||
birthDate: state.dateOfBirth,
|
birthDate: state.dateOfBirth,
|
||||||
inviteCode: state.inviteCode.trim(),
|
inviteCode: state.inviteCode.trim(),
|
||||||
verificationCode: state.pendingSubmit?.verificationCode,
|
verificationCode,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
signupDuration: Date.now() - state.signupStartTime,
|
signupDuration: Date.now() - state.signupStartTime,
|
||||||
@@ -360,6 +361,7 @@ export function useSubmitSignup() {
|
|||||||
field: 'invite-code',
|
field: 'invite-code',
|
||||||
})
|
})
|
||||||
dispatch({type: 'setStep', value: SignupStep.INFO})
|
dispatch({type: 'setStep', value: SignupStep.INFO})
|
||||||
|
dispatch({type: 'setIsLoading', value: false})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,9 +386,8 @@ export function useSubmitSignup() {
|
|||||||
safeMessage: e,
|
safeMessage: e,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
dispatch({type: 'setIsLoading', value: false})
|
|
||||||
}
|
}
|
||||||
|
dispatch({type: 'setIsLoading', value: false})
|
||||||
},
|
},
|
||||||
[l, ax, createAccount, onboardingDispatch],
|
[l, ax, createAccount, onboardingDispatch],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,6 +10,16 @@ import {updatePostShadow} from '../cache/post-shadow'
|
|||||||
import {useAppviewClient, useSession} from '../session'
|
import {useAppviewClient, useSession} from '../session'
|
||||||
import {useProfileUpdateMutation} from './profile'
|
import {useProfileUpdateMutation} from './profile'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Out of the hook because React Compiler cannot lower an optional chain inside a
|
||||||
|
* `try` block, and `profile` only exists once the request inside it resolves.
|
||||||
|
*/
|
||||||
|
function getPinnedPostUri(profile: {
|
||||||
|
pinnedPost?: {uri: string}
|
||||||
|
}): string | undefined {
|
||||||
|
return profile.pinnedPost?.uri
|
||||||
|
}
|
||||||
|
|
||||||
export function usePinnedPostMutation() {
|
export function usePinnedPostMutation() {
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
@@ -27,19 +37,24 @@ export function usePinnedPostMutation() {
|
|||||||
postCid: string
|
postCid: string
|
||||||
action: 'pin' | 'unpin'
|
action: 'pin' | 'unpin'
|
||||||
}) => {
|
}) => {
|
||||||
|
if (!currentAccount) throw new Error('Not signed in')
|
||||||
|
|
||||||
const pinCurrentPost = action === 'pin'
|
const pinCurrentPost = action === 'pin'
|
||||||
let prevPinnedPost: string | undefined
|
let prevPinnedPost: string | undefined
|
||||||
try {
|
try {
|
||||||
updatePostShadow(queryClient, postUri, {pinned: pinCurrentPost})
|
updatePostShadow(queryClient, postUri, {pinned: pinCurrentPost})
|
||||||
|
|
||||||
// get the currently pinned post so we can optimistically remove the pin from it
|
// get the currently pinned post so we can optimistically remove the pin from it
|
||||||
if (!currentAccount) throw new Error('Not signed in')
|
|
||||||
const profile = await client.call(app.bsky.actor.getProfile, {
|
const profile = await client.call(app.bsky.actor.getProfile, {
|
||||||
actor: currentAccount.did,
|
actor: currentAccount.did,
|
||||||
})
|
})
|
||||||
prevPinnedPost = profile.pinnedPost?.uri
|
prevPinnedPost = getPinnedPostUri(profile)
|
||||||
if (prevPinnedPost && prevPinnedPost !== postUri) {
|
if (prevPinnedPost) {
|
||||||
updatePostShadow(queryClient, prevPinnedPost, {pinned: false})
|
// Nested rather than `&&`: React Compiler cannot lower a logical
|
||||||
|
// expression in a test position inside a `try`.
|
||||||
|
if (prevPinnedPost !== postUri) {
|
||||||
|
updatePostShadow(queryClient, prevPinnedPost, {pinned: false})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await profileUpdateMutate({
|
await profileUpdateMutate({
|
||||||
|
|||||||
Reference in New Issue
Block a user