Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Stop passing `_` around in composer functions (#10256)

authored by

Samuel Newman and committed by
GitHub
ecc78efb bcbc1141

+129 -137
+2 -2
src/lib/media/video/upload.shared.ts
··· 30 30 return serviceAuth.token 31 31 } 32 32 33 - export async function getVideoUploadLimits(agent: BskyAgent, _: I18n['_']) { 33 + export async function getVideoUploadLimits(agent: BskyAgent, i18n: I18n) { 34 34 const token = await getServiceAuthToken({ 35 35 agent, 36 36 lxm: 'app.bsky.video.getUploadLimits', ··· 52 52 throw new UploadLimitError(limits.message) 53 53 } else { 54 54 throw new UploadLimitError( 55 - _( 55 + i18n._( 56 56 msg`You have temporarily reached the limit for video uploads. Please try again later.`, 57 57 ), 58 58 )
+6 -4
src/lib/media/video/upload.ts
··· 16 16 did, 17 17 setProgress, 18 18 signal, 19 - _, 19 + i18n, 20 20 }: { 21 21 video: CompressedVideo 22 22 agent: BskyAgent 23 23 did: string 24 24 setProgress: (progress: number) => void 25 25 signal: AbortSignal 26 - _: I18n['_'] 26 + i18n: I18n 27 27 }) { 28 28 if (signal.aborted) { 29 29 throw new AbortError() 30 30 } 31 - await getVideoUploadLimits(agent, _) 31 + await getVideoUploadLimits(agent, i18n) 32 32 33 33 const uri = createVideoEndpointUrl('/xrpc/app.bsky.video.uploadVideo', { 34 34 did, ··· 69 69 const responseBody = JSON.parse(res.body) as AppBskyVideoDefs.JobStatus 70 70 71 71 if (!responseBody.jobId) { 72 - throw new ServerError(responseBody.error || _(msg`Failed to upload video`)) 72 + throw new ServerError( 73 + responseBody.error || i18n._(msg`Failed to upload video`), 74 + ) 73 75 } 74 76 75 77 if (signal.aborted) {
+6 -6
src/lib/media/video/upload.web.ts
··· 15 15 did, 16 16 setProgress, 17 17 signal, 18 - _, 18 + i18n, 19 19 }: { 20 20 video: CompressedVideo 21 21 agent: BskyAgent 22 22 did: string 23 23 setProgress: (progress: number) => void 24 24 signal: AbortSignal 25 - _: I18n['_'] 25 + i18n: I18n 26 26 }) { 27 27 if (signal.aborted) { 28 28 throw new AbortError() 29 29 } 30 - await getVideoUploadLimits(agent, _) 30 + await getVideoUploadLimits(agent, i18n) 31 31 32 32 const uri = createVideoEndpointUrl('/xrpc/app.bsky.video.uploadVideo', { 33 33 did, ··· 70 70 ) as AppBskyVideoDefs.JobStatus 71 71 resolve(uploadRes) 72 72 } else { 73 - reject(new ServerError(_(msg`Failed to upload video`))) 73 + reject(new ServerError(i18n._(msg`Failed to upload video`))) 74 74 } 75 75 } 76 76 xhr.onerror = () => { 77 - reject(new ServerError(_(msg`Failed to upload video`))) 77 + reject(new ServerError(i18n._(msg`Failed to upload video`))) 78 78 } 79 79 xhr.open('POST', uri) 80 80 xhr.setRequestHeader('Content-Type', video.mimeType) ··· 84 84 ) 85 85 86 86 if (!res.jobId) { 87 - throw new ServerError(res.error || _(msg`Failed to upload video`)) 87 + throw new ServerError(res.error || i18n._(msg`Failed to upload video`)) 88 88 } 89 89 90 90 if (signal.aborted) {
+96 -106
src/view/com/composer/Composer.tsx
··· 54 54 type BskyAgent, 55 55 type RichText, 56 56 } from '@atproto/api' 57 - import {msg, plural} from '@lingui/core/macro' 58 - import {useLingui} from '@lingui/react' 59 - import {Trans} from '@lingui/react/macro' 57 + import {plural} from '@lingui/core/macro' 58 + import {Trans, useLingui} from '@lingui/react/macro' 60 59 import {useNavigation} from '@react-navigation/native' 61 60 import {useQueryClient} from '@tanstack/react-query' 62 61 ··· 197 196 cancelRef?: React.RefObject<CancelRef | null> 198 197 }) => { 199 198 const {currentAccount} = useSession() 199 + const t = useTheme() 200 200 const ax = useAnalytics() 201 201 const agent = useAgent() 202 202 const queryClient = useQueryClient() 203 203 const currentDid = currentAccount!.did 204 204 const {closeComposer} = useComposerControls() 205 - const {_} = useLingui() 205 + const {t: l, i18n} = useLingui() 206 206 const requireAltTextEnabled = useRequireAltTextEnabled() 207 207 const langPrefs = useLanguagePrefs() 208 208 const setLangPrefs = useLanguagePrefsApi() ··· 313 313 abortController, 314 314 }, 315 315 }) 316 - processVideo( 316 + void processVideo( 317 317 asset, 318 318 videoAction => { 319 319 composerDispatch({ ··· 328 328 agent, 329 329 currentDid, 330 330 abortController.signal, 331 - _, 331 + i18n, 332 332 ) 333 333 }, 334 - [_, agent, currentDid, composerDispatch], 334 + [i18n, agent, currentDid, composerDispatch], 335 335 ) 336 336 337 337 const onInitVideo = useNonReactiveCallback(() => { ··· 460 460 } 461 461 462 462 // Start video compression and upload 463 - processVideo( 463 + void processVideo( 464 464 asset, 465 465 videoAction => { 466 466 composerDispatch({ ··· 475 475 agent, 476 476 currentDid, 477 477 abortController.signal, 478 - _, 478 + i18n, 479 479 ) 480 480 } catch (e) { 481 481 logger.error('Failed to restore video from draft', { ··· 484 484 }) 485 485 } 486 486 }, 487 - [_, agent, currentDid, composerDispatch], 487 + [i18n, agent, currentDid, composerDispatch], 488 488 ) 489 489 490 490 const handleSelectDraft = useCallback( ··· 558 558 const getDraftSaveError = useCallback( 559 559 (e: unknown): string => { 560 560 if (e instanceof AppBskyDraftCreateDraft.DraftLimitReachedError) { 561 - return _(msg`You've reached the maximum number of drafts`) 561 + return l`You've reached the maximum number of drafts` 562 562 } 563 - return _(msg`Failed to save draft`) 563 + return l`Failed to save draft` 564 564 }, 565 - [_], 565 + [l], 566 566 ) 567 567 568 568 const validateDraftTextOrError = useCallback((): boolean => { ··· 571 571 ) 572 572 if (tooLong) { 573 573 setError( 574 - _( 575 - msg`One or more posts are too long to save as a draft. ${plural(MAX_DRAFT_GRAPHEME_LENGTH, {one: 'The maximum number of characters is # character.', other: 'The maximum number of characters is # characters.'})}`, 576 - ), 574 + l`One or more posts are too long to save as a draft. ${plural(MAX_DRAFT_GRAPHEME_LENGTH, {one: 'The maximum number of characters is # character.', other: 'The maximum number of characters is # characters.'})}`, 577 575 ) 578 576 return false 579 577 } 580 578 return true 581 - }, [composerState.thread.posts, _]) 579 + }, [composerState.thread.posts, l]) 582 580 583 581 const handleSaveDraft = useCallback(async () => { 584 582 setError('') ··· 768 766 const media = thread.posts[i].embed.media 769 767 if (media) { 770 768 if (media.type === 'images' && media.images.some(img => !img.alt)) { 771 - return _(msg`One or more images is missing alt text.`) 769 + return l`One or more images is missing alt text.` 772 770 } 773 771 if (media.type === 'gif' && !media.alt) { 774 - return _(msg`One or more GIFs is missing alt text.`) 772 + return l`One or more GIFs is missing alt text.` 775 773 } 776 774 if ( 777 775 media.type === 'video' && 778 776 media.video.status !== 'error' && 779 777 !media.video.altText 780 778 ) { 781 - return _(msg`One or more videos is missing alt text.`) 779 + return l`One or more videos is missing alt text.` 782 780 } 783 781 } 784 782 } 785 - }, [thread, requireAltTextEnabled, _]) 783 + }, [thread, requireAltTextEnabled, l]) 786 784 787 785 const canPost = 788 786 !missingAltError && ··· 895 893 896 894 let err = cleanError(e.message) 897 895 if (err.includes('not locate record')) { 898 - err = _( 899 - msg`We're sorry! The post you are replying to has been deleted.`, 900 - ) 896 + err = l`We're sorry! The post you are replying to has been deleted.` 901 897 } else if (e instanceof EmbeddingDisabledError) { 902 - err = _(msg`This post's author has disabled quote posts.`) 898 + err = l`This post's author has disabled quote posts.` 903 899 } 904 900 setError(err) 905 901 setIsPublishing(false) ··· 979 975 <Toast.Icon /> 980 976 <Toast.Text> 981 977 {thread.posts.length > 1 982 - ? _(msg`Your posts were sent`) 978 + ? l`Your posts were sent` 983 979 : replyTo 984 - ? _(msg`Your reply was sent`) 985 - : _(msg`Your post was sent`)} 980 + ? l`Your reply was sent` 981 + : l`Your post was sent`} 986 982 </Toast.Text> 987 983 {postUri && ( 988 984 <Toast.Action 989 - label={_(msg`View post`)} 985 + label={l`View post`} 990 986 onPress={() => { 991 987 const {host: name, rkey} = new AtUri(postUri) 992 988 navigation.navigate('PostThread', {name, rkey}) ··· 1001 997 ) 1002 998 }, 500) 1003 999 }, [ 1004 - _, 1000 + l, 1005 1001 ax, 1006 1002 agent, 1007 1003 thread, ··· 1026 1022 // Preserves the referential identity passed to each post item. 1027 1023 // Avoids re-rendering all posts on each keystroke. 1028 1024 const onComposerPostPublish = useNonReactiveCallback(() => { 1029 - onPressPublish() 1025 + void onPressPublish() 1030 1026 }) 1031 1027 1032 1028 useEffect(() => { ··· 1047 1043 setPublishOnUpload(false) 1048 1044 } else if (uploadingVideos === 0) { 1049 1045 setPublishOnUpload(false) 1050 - onPressPublish() 1046 + void onPressPublish() 1051 1047 } 1052 1048 } 1053 1049 }, [thread.posts, onPressPublish, publishOnUpload]) ··· 1189 1185 layout={native(LinearTransition)} 1190 1186 onScroll={scrollHandler} 1191 1187 contentContainerStyle={a.flex_grow} 1192 - style={a.flex_1} 1188 + style={[ 1189 + a.flex_1, 1190 + web({ 1191 + scrollbarGutter: 'stable', 1192 + scrollbarColor: `${t.palette.contrast_200} transparent`, 1193 + }), 1194 + ]} 1193 1195 keyboardShouldPersistTaps="always" 1194 1196 onContentSizeChange={onScrollViewContentSizeChange} 1195 1197 onLayout={onScrollViewLayout}> ··· 1224 1226 {replyTo ? ( 1225 1227 <Prompt.Basic 1226 1228 control={discardPromptControl} 1227 - title={_(msg`Discard draft?`)} 1229 + title={l`Discard draft?`} 1228 1230 description="" 1229 - confirmButtonCta={_(msg`Discard`)} 1231 + confirmButtonCta={l`Discard`} 1230 1232 confirmButtonColor="negative" 1231 1233 onConfirm={handleDiscard} 1232 1234 /> ··· 1264 1266 <Prompt.Actions> 1265 1267 {allPostsWithinLimit && ( 1266 1268 <Prompt.Action 1267 - cta={ 1268 - composerState.draftId 1269 - ? _(msg`Save changes`) 1270 - : _(msg`Save draft`) 1271 - } 1269 + cta={composerState.draftId ? l`Save changes` : l`Save draft`} 1272 1270 onPress={handleSaveDraft} 1273 1271 color="primary" 1274 1272 /> 1275 1273 )} 1276 1274 <Prompt.Action 1277 - cta={_(msg`Discard`)} 1275 + cta={l`Discard`} 1278 1276 onPress={handleDiscard} 1279 1277 color="negative_subtle" 1280 1278 /> 1281 - <Prompt.Cancel cta={_(msg`Keep editing`)} /> 1279 + <Prompt.Cancel cta={l`Keep editing`} /> 1282 1280 </Prompt.Actions> 1283 1281 </Prompt.Outer> 1284 1282 )} ··· 1320 1318 }) { 1321 1319 const {currentAccount} = useSession() 1322 1320 const currentDid = currentAccount!.did 1323 - const {_} = useLingui() 1321 + const {t: l} = useLingui() 1324 1322 const {data: currentProfile} = useProfileQuery({did: currentDid}) 1325 1323 const richtext = post.richtext 1326 1324 const isTextOnly = !post.embed.link && !post.embed.quote && !post.embed.media 1327 1325 const forceMinHeight = IS_WEB && isTextOnly && isActive 1328 1326 const selectTextInputPlaceholder = isReply 1329 1327 ? isFirstPost 1330 - ? _(msg`Write your reply`) 1331 - : _(msg`Add another post`) 1332 - : _(msg`What's up?`) 1328 + ? l`Write your reply` 1329 + : l`Add another post` 1330 + : l`What's up?` 1333 1331 const discardPromptControl = Prompt.usePromptControl() 1334 1332 1335 1333 const dispatchPost = useCallback( ··· 1369 1367 if (IS_NATIVE) return // web only 1370 1368 const [mimeType] = uri.slice('data:'.length).split(';') 1371 1369 if (!SUPPORTED_MIME_TYPES.includes(mimeType as SupportedMimeTypes)) { 1372 - Toast.show(_(msg`Unsupported video type: ${mimeType}`), { 1370 + Toast.show(l`Unsupported video type: ${mimeType}`, { 1373 1371 type: 'error', 1374 1372 }) 1375 1373 return ··· 1384 1382 onImageAdd([res]) 1385 1383 } 1386 1384 }, 1387 - [post.id, onSelectVideo, onImageAdd, _], 1385 + [post.id, onSelectVideo, onImageAdd, l], 1388 1386 ) 1389 1387 1390 1388 useHideKeyboardOnBackground() ··· 1429 1427 onError={onError} 1430 1428 onPressPublish={onPublish} 1431 1429 accessible={true} 1432 - accessibilityLabel={_(msg`Write post`)} 1433 - accessibilityHint={_( 1434 - msg`Compose posts up to ${plural(MAX_GRAPHEME_LENGTH || 0, { 1430 + accessibilityLabel={l`Write post`} 1431 + accessibilityHint={l`Compose posts up to ${plural( 1432 + MAX_GRAPHEME_LENGTH || 0, 1433 + { 1435 1434 other: '# characters', 1436 - })} in length`, 1437 - )} 1435 + }, 1436 + )} in length`} 1438 1437 /> 1439 1438 </View> 1440 1439 1441 1440 {canRemovePost && isActive && ( 1442 1441 <> 1443 1442 <Button 1444 - label={_(msg`Delete post`)} 1443 + label={l`Delete post`} 1445 1444 size="small" 1446 1445 color="secondary" 1447 1446 variant="ghost" ··· 1466 1465 </Button> 1467 1466 <Prompt.Basic 1468 1467 control={discardPromptControl} 1469 - title={_(msg`Discard post?`)} 1470 - description={_(msg`Are you sure you'd like to discard this post?`)} 1468 + title={l`Discard post?`} 1469 + description={l`Are you sure you'd like to discard this post?`} 1471 1470 onConfirm={() => { 1472 1471 dispatch({ 1473 1472 type: 'remove_post', 1474 1473 postId: post.id, 1475 1474 }) 1476 1475 }} 1477 - confirmButtonCta={_(msg`Discard`)} 1476 + confirmButtonCta={l`Discard`} 1478 1477 confirmButtonColor="negative" 1479 1478 /> 1480 1479 </> ··· 1531 1530 children?: React.ReactNode 1532 1531 }) { 1533 1532 const t = useTheme() 1534 - const {_} = useLingui() 1533 + const {t: l} = useLingui() 1534 + 1535 1535 return ( 1536 1536 <Animated.View 1537 1537 style={topBarAnimatedStyle} ··· 1544 1544 IS_LIQUID_GLASS ? [a.px_lg, a.pt_lg, a.pb_md] : [a.p_sm], 1545 1545 ]}> 1546 1546 <Button 1547 - label={_(msg`Cancel`)} 1547 + label={l`Cancel`} 1548 1548 variant="ghost" 1549 1549 color="primary" 1550 1550 shape="default" ··· 1552 1552 style={[{paddingLeft: 7, paddingRight: 7}]} 1553 1553 hoverStyle={[a.bg_transparent, {opacity: 0.5}]} 1554 1554 onPress={onCancel} 1555 - accessibilityHint={_( 1556 - msg`Closes post composer and discards post draft`, 1557 - )}> 1555 + accessibilityHint={l`Closes post composer and discards post draft`}> 1558 1556 <ButtonText style={[a.text_md]} maxFontSizeMultiplier={2}> 1559 1557 <Trans>Cancel</Trans> 1560 1558 </ButtonText> ··· 1588 1586 label={ 1589 1587 isReply 1590 1588 ? isThread 1591 - ? _( 1592 - msg({ 1593 - message: 'Publish replies', 1594 - comment: 1595 - 'Accessibility label for button to publish multiple replies in a thread', 1596 - }), 1597 - ) 1598 - : _( 1599 - msg({ 1600 - message: 'Publish reply', 1601 - comment: 1602 - 'Accessibility label for button to publish a single reply', 1603 - }), 1604 - ) 1589 + ? l({ 1590 + message: 'Publish replies', 1591 + comment: 1592 + 'Accessibility label for button to publish multiple replies in a thread', 1593 + }) 1594 + : l({ 1595 + message: 'Publish reply', 1596 + comment: 1597 + 'Accessibility label for button to publish a single reply', 1598 + }) 1605 1599 : isThread 1606 - ? _( 1607 - msg({ 1608 - message: 'Publish posts', 1609 - comment: 1610 - 'Accessibility label for button to publish multiple posts in a thread', 1611 - }), 1612 - ) 1613 - : _( 1614 - msg({ 1615 - message: 'Publish post', 1616 - comment: 1617 - 'Accessibility label for button to publish a single post', 1618 - }), 1619 - ) 1600 + ? l({ 1601 + message: 'Publish posts', 1602 + comment: 1603 + 'Accessibility label for button to publish multiple posts in a thread', 1604 + }) 1605 + : l({ 1606 + message: 'Publish post', 1607 + comment: 1608 + 'Accessibility label for button to publish a single post', 1609 + }) 1620 1610 } 1621 1611 color="primary" 1622 1612 size="small" ··· 1851 1841 openGallery?: boolean 1852 1842 }) { 1853 1843 const t = useTheme() 1854 - const {_} = useLingui() 1844 + const {t: l} = useLingui() 1855 1845 const {isMobile} = useWebMediaQueries() 1856 1846 /* 1857 1847 * Once we've allowed a certain type of asset to be selected, we don't allow ··· 1979 1969 <Button 1980 1970 onPress={onEmojiButtonPress} 1981 1971 style={a.p_sm} 1982 - label={_(msg`Open emoji picker`)} 1983 - accessibilityHint={_(msg`Opens emoji picker`)} 1972 + label={l`Open emoji picker`} 1973 + accessibilityHint={l`Opens emoji picker`} 1984 1974 variant="ghost" 1985 1975 shape="round" 1986 1976 color="primary"> ··· 1994 1984 <View style={[a.flex_row, a.align_center, a.justify_between]}> 1995 1985 {showAddButton && ( 1996 1986 <Button 1997 - label={_(msg`Add another post to thread`)} 1987 + label={l`Add another post to thread`} 1998 1988 onPress={onAddPost} 1999 1989 style={[a.p_sm]} 2000 1990 variant="ghost" ··· 2276 2266 clearVideo: () => void 2277 2267 }) { 2278 2268 const t = useTheme() 2279 - const {_} = useLingui() 2269 + const {t: l} = useLingui() 2280 2270 2281 2271 const videoError = 2282 2272 videoState.status === 'error' ? videoState.error : undefined ··· 2311 2301 {error} 2312 2302 </Text> 2313 2303 <Button 2314 - label={_(msg`Dismiss error`)} 2304 + label={l`Dismiss error`} 2315 2305 size="tiny" 2316 2306 color="secondary" 2317 2307 variant="ghost" ··· 2358 2348 2359 2349 function VideoUploadToolbar({state}: {state: VideoState}) { 2360 2350 const t = useTheme() 2361 - const {_} = useLingui() 2351 + const {t: l} = useLingui() 2362 2352 const progress = state.progress 2363 2353 const shouldRotate = 2364 2354 state.status === 'processing' && (progress === 0 || progress === 1) ··· 2390 2380 switch (state.status) { 2391 2381 case 'compressing': 2392 2382 if (isGif) { 2393 - text = _(msg`Compressing GIF...`) 2383 + text = l`Compressing GIF...` 2394 2384 } else { 2395 - text = _(msg`Compressing video...`) 2385 + text = l`Compressing video...` 2396 2386 } 2397 2387 break 2398 2388 case 'uploading': 2399 2389 if (isGif) { 2400 - text = _(msg`Uploading GIF...`) 2390 + text = l`Uploading GIF...` 2401 2391 } else { 2402 - text = _(msg`Uploading video...`) 2392 + text = l`Uploading video...` 2403 2393 } 2404 2394 break 2405 2395 case 'processing': 2406 2396 if (isGif) { 2407 - text = _(msg`Processing GIF...`) 2397 + text = l`Processing GIF...` 2408 2398 } else { 2409 - text = _(msg`Processing video...`) 2399 + text = l`Processing video...` 2410 2400 } 2411 2401 break 2412 2402 case 'error': 2413 - text = _(msg`Error`) 2403 + text = l`Error` 2414 2404 wheelProgress = 100 2415 2405 break 2416 2406 case 'done': 2417 2407 if (isGif) { 2418 - text = _(msg`GIF uploaded`) 2408 + text = l`GIF uploaded` 2419 2409 } else { 2420 - text = _(msg`Video uploaded`) 2410 + text = l`Video uploaded` 2421 2411 } 2422 2412 break 2423 2413 }
+19 -19
src/view/com/composer/state/video.ts
··· 263 263 agent: BskyAgent, 264 264 did: string, 265 265 signal: AbortSignal, 266 - _: I18n['_'], 266 + i18n: I18n, 267 267 ) { 268 268 let video: CompressedVideo | undefined 269 269 try { ··· 274 274 signal, 275 275 }) 276 276 } catch (e) { 277 - const message = getCompressErrorMessage(e, _) 277 + const message = getCompressErrorMessage(e, i18n) 278 278 if (message !== null) { 279 279 dispatch({ 280 280 type: 'to_error', ··· 297 297 agent, 298 298 did, 299 299 signal, 300 - _, 300 + i18n, 301 301 setProgress: p => { 302 302 dispatch({type: 'update_progress', progress: p, signal}) 303 303 }, 304 304 }) 305 305 } catch (e) { 306 - const message = getUploadErrorMessage(e, _) 306 + const message = getUploadErrorMessage(e, i18n) 307 307 if (message !== null) { 308 308 dispatch({ 309 309 type: 'to_error', ··· 355 355 logger.error('Error processing video', {safeMessage: e}) 356 356 dispatch({ 357 357 type: 'to_error', 358 - error: _(msg`Video failed to process`), 358 + error: i18n._(msg`Video failed to process`), 359 359 signal, 360 360 }) 361 361 return // Exit async loop ··· 387 387 } 388 388 } 389 389 390 - function getCompressErrorMessage(e: unknown, _: I18n['_']): string | null { 390 + function getCompressErrorMessage(e: unknown, i18n: I18n): string | null { 391 391 if (e instanceof AbortError) { 392 392 return null 393 393 } 394 394 if (e instanceof VideoTooLargeError) { 395 - return _( 395 + return i18n._( 396 396 msg`The selected video is larger than 100 MB. Please try again with a smaller file.`, 397 397 ) 398 398 } 399 399 logger.error('Error compressing video', {safeMessage: e}) 400 - return _(msg`An error occurred while compressing the video.`) 400 + return i18n._(msg`An error occurred while compressing the video.`) 401 401 } 402 402 403 - function getUploadErrorMessage(e: unknown, _: I18n['_']): string | null { 403 + function getUploadErrorMessage(e: unknown, i18n: I18n): string | null { 404 404 if (e instanceof AbortError) { 405 405 return null 406 406 } ··· 408 408 // https://github.com/bluesky-social/tango/blob/lumi/lumi/worker/permissions.go#L77 409 409 switch (e.message) { 410 410 case 'User is not allowed to upload videos': 411 - return _(msg`You are not allowed to upload videos.`) 411 + return i18n._(msg`You are not allowed to upload videos.`) 412 412 case 'Uploading is disabled at the moment': 413 - return _( 413 + return i18n._( 414 414 msg`Hold up! We’re gradually giving access to video, and you’re still waiting in line. Check back soon!`, 415 415 ) 416 416 case "Failed to get user's upload stats": 417 - return _( 417 + return i18n._( 418 418 msg`We were unable to determine if you are allowed to upload videos. Please try again.`, 419 419 ) 420 420 case 'User has exceeded daily upload bytes limit': 421 - return _( 421 + return i18n._( 422 422 msg`You've reached your daily limit for video uploads (too many bytes)`, 423 423 ) 424 424 case 'User has exceeded daily upload videos limit': 425 - return _( 425 + return i18n._( 426 426 msg`You've reached your daily limit for video uploads (too many videos)`, 427 427 ) 428 428 case 'Account is not old enough to upload videos': 429 - return _( 429 + return i18n._( 430 430 msg`Your account is not yet old enough to upload videos. Please try again later.`, 431 431 ) 432 432 case 'file size (100000001 bytes) is larger than the maximum allowed size (100000000 bytes)': 433 - return _( 433 + return i18n._( 434 434 msg`The selected video is larger than 100 MB. Please try again with a smaller file.`, 435 435 ) 436 436 case 'Confirm your email address to upload videos': 437 - return _(msg`Please confirm your email address to upload videos.`) 437 + return i18n._(msg`Please confirm your email address to upload videos.`) 438 438 } 439 439 } 440 440 441 441 if (isNetworkError(e)) { 442 - return _( 442 + return i18n._( 443 443 msg`An error occurred while uploading the video. Please check your internet connection and try again.`, 444 444 ) 445 445 } else { ··· 448 448 } 449 449 450 450 const message = e instanceof Error ? e.message : '' 451 - return _(msg`An error occurred while uploading the video. ${message}`) 451 + return i18n._(msg`An error occurred while uploading the video. ${message}`) 452 452 }