diff options
Diffstat (limited to 'src/view/com')
-rw-r--r-- | src/view/com/composer/Composer.tsx | 21 | ||||
-rw-r--r-- | src/view/com/composer/videos/SelectVideoBtn.tsx | 112 | ||||
-rw-r--r-- | src/view/com/feeds/FeedPage.tsx | 16 | ||||
-rw-r--r-- | src/view/com/post-thread/PostThread.tsx | 18 | ||||
-rw-r--r-- | src/view/com/post-thread/PostThreadItem.tsx | 4 | ||||
-rw-r--r-- | src/view/com/post/Post.tsx | 16 | ||||
-rw-r--r-- | src/view/com/posts/PostFeedItem.tsx | 4 | ||||
-rw-r--r-- | src/view/com/util/post-ctrls/PostCtrls.tsx | 4 |
8 files changed, 63 insertions, 132 deletions
diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index b6d269d28..e690e7256 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -62,7 +62,6 @@ import { type SupportedMimeTypes, } from '#/lib/constants' import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED' -import {useEmail} from '#/lib/hooks/useEmail' import {useIsKeyboardVisible} from '#/lib/hooks/useIsKeyboardVisible' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' import {usePalette} from '#/lib/hooks/usePalette' @@ -120,8 +119,6 @@ import * as Toast from '#/view/com/util/Toast' import {UserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, native, useTheme, web} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' -import {useDialogControl} from '#/components/Dialog' -import {VerifyEmailDialog} from '#/components/dialogs/VerifyEmailDialog' import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' import {EmojiArc_Stroke2_Corner0_Rounded as EmojiSmile} from '#/components/icons/Emoji' import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times' @@ -331,15 +328,6 @@ export const ComposePost = ({ } }, [onPressCancel, closeAllDialogs, closeAllModals]) - const {needsEmailVerification} = useEmail() - const emailVerificationControl = useDialogControl() - - useEffect(() => { - if (needsEmailVerification) { - emailVerificationControl.open() - } - }, [needsEmailVerification, emailVerificationControl]) - const missingAltError = useMemo(() => { if (!requireAltTextEnabled) { return @@ -620,15 +608,6 @@ export const ComposePost = ({ const isWebFooterSticky = !isNative && thread.posts.length > 1 return ( <BottomSheetPortalProvider> - <VerifyEmailDialog - control={emailVerificationControl} - onCloseWithoutVerifying={() => { - onClose() - }} - reasonText={_( - msg`Before creating a post, you must first verify your email.`, - )} - /> <KeyboardAvoidingView testID="composePostView" behavior={isIOS ? 'padding' : 'height'} diff --git a/src/view/com/composer/videos/SelectVideoBtn.tsx b/src/view/com/composer/videos/SelectVideoBtn.tsx index 8d9371f0d..96715955f 100644 --- a/src/view/com/composer/videos/SelectVideoBtn.tsx +++ b/src/view/com/composer/videos/SelectVideoBtn.tsx @@ -1,26 +1,19 @@ import {useCallback} from 'react' -import {Keyboard} from 'react-native' -import {ImagePickerAsset} from 'expo-image-picker' +import {type ImagePickerAsset} from 'expo-image-picker' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import { SUPPORTED_MIME_TYPES, - SupportedMimeTypes, + type SupportedMimeTypes, VIDEO_MAX_DURATION_MS, } from '#/lib/constants' -import {BSKY_SERVICE} from '#/lib/constants' import {useVideoLibraryPermission} from '#/lib/hooks/usePermissions' -import {getHostnameFromUrl} from '#/lib/strings/url-helpers' import {isWeb} from '#/platform/detection' import {isNative} from '#/platform/detection' -import {useSession} from '#/state/session' import {atoms as a, useTheme} from '#/alf' import {Button} from '#/components/Button' -import {useDialogControl} from '#/components/Dialog' -import {VerifyEmailDialog} from '#/components/dialogs/VerifyEmailDialog' import {VideoClip_Stroke2_Corner0_Rounded as VideoClipIcon} from '#/components/icons/VideoClip' -import * as Prompt from '#/components/Prompt' import {pickVideo} from './pickVideo' type Props = { @@ -33,66 +26,45 @@ export function SelectVideoBtn({onSelectVideo, disabled, setError}: Props) { const {_} = useLingui() const t = useTheme() const {requestVideoAccessIfNeeded} = useVideoLibraryPermission() - const control = Prompt.usePromptControl() - const {currentAccount} = useSession() const onPressSelectVideo = useCallback(async () => { if (isNative && !(await requestVideoAccessIfNeeded())) { return } - if ( - currentAccount && - !currentAccount.emailConfirmed && - getHostnameFromUrl(currentAccount.service) === - getHostnameFromUrl(BSKY_SERVICE) - ) { - Keyboard.dismiss() - control.open() - } else { - const response = await pickVideo() - if (response.assets && response.assets.length > 0) { - const asset = response.assets[0] - try { - if (isWeb) { - // asset.duration is null for gifs (see the TODO in pickVideo.web.ts) - if (asset.duration && asset.duration > VIDEO_MAX_DURATION_MS) { - throw Error(_(msg`Videos must be less than 3 minutes long`)) - } - // compression step on native converts to mp4, so no need to check there - if ( - !SUPPORTED_MIME_TYPES.includes( - asset.mimeType as SupportedMimeTypes, - ) - ) { - throw Error(_(msg`Unsupported video type: ${asset.mimeType}`)) - } - } else { - if (typeof asset.duration !== 'number') { - throw Error('Asset is not a video') - } - if (asset.duration > VIDEO_MAX_DURATION_MS) { - throw Error(_(msg`Videos must be less than 3 minutes long`)) - } + const response = await pickVideo() + if (response.assets && response.assets.length > 0) { + const asset = response.assets[0] + try { + if (isWeb) { + // asset.duration is null for gifs (see the TODO in pickVideo.web.ts) + if (asset.duration && asset.duration > VIDEO_MAX_DURATION_MS) { + throw Error(_(msg`Videos must be less than 3 minutes long`)) } - onSelectVideo(asset) - } catch (err) { - if (err instanceof Error) { - setError(err.message) - } else { - setError(_(msg`An error occurred while selecting the video`)) + // compression step on native converts to mp4, so no need to check there + if ( + !SUPPORTED_MIME_TYPES.includes(asset.mimeType as SupportedMimeTypes) + ) { + throw Error(_(msg`Unsupported video type: ${asset.mimeType}`)) } + } else { + if (typeof asset.duration !== 'number') { + throw Error('Asset is not a video') + } + if (asset.duration > VIDEO_MAX_DURATION_MS) { + throw Error(_(msg`Videos must be less than 3 minutes long`)) + } + } + onSelectVideo(asset) + } catch (err) { + if (err instanceof Error) { + setError(err.message) + } else { + setError(_(msg`An error occurred while selecting the video`)) } } } - }, [ - requestVideoAccessIfNeeded, - currentAccount, - control, - setError, - _, - onSelectVideo, - ]) + }, [requestVideoAccessIfNeeded, setError, _, onSelectVideo]) return ( <> @@ -111,30 +83,6 @@ export function SelectVideoBtn({onSelectVideo, disabled, setError}: Props) { style={disabled && t.atoms.text_contrast_low} /> </Button> - <VerifyEmailPrompt control={control} /> - </> - ) -} - -function VerifyEmailPrompt({control}: {control: Prompt.PromptControlProps}) { - const {_} = useLingui() - const verifyEmailDialogControl = useDialogControl() - - return ( - <> - <Prompt.Basic - control={control} - title={_(msg`Verified email required`)} - description={_( - msg`To upload videos to Bluesky, you must first verify your email.`, - )} - confirmButtonCta={_(msg`Verify now`)} - confirmButtonColor="primary" - onConfirm={() => { - verifyEmailDialogControl.open() - }} - /> - <VerifyEmailDialog control={verifyEmailDialogControl} /> </> ) } diff --git a/src/view/com/feeds/FeedPage.tsx b/src/view/com/feeds/FeedPage.tsx index f643adaf9..604533b0f 100644 --- a/src/view/com/feeds/FeedPage.tsx +++ b/src/view/com/feeds/FeedPage.tsx @@ -1,32 +1,32 @@ import React from 'react' import {View} from 'react-native' -import {AppBskyActorDefs, AppBskyFeedDefs} from '@atproto/api' +import {type AppBskyActorDefs, AppBskyFeedDefs} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {NavigationProp, useNavigation} from '@react-navigation/native' +import {type NavigationProp, useNavigation} from '@react-navigation/native' import {useQueryClient} from '@tanstack/react-query' import {VIDEO_FEED_URIS} from '#/lib/constants' +import {useOpenComposer} from '#/lib/hooks/useOpenComposer' import {ComposeIcon2} from '#/lib/icons' import {getRootNavigation, getTabState, TabState} from '#/lib/routes/helpers' -import {AllNavigatorParams} from '#/lib/routes/types' +import {type AllNavigatorParams} from '#/lib/routes/types' import {logEvent} from '#/lib/statsig/statsig' import {s} from '#/lib/styles' import {isNative} from '#/platform/detection' import {listenSoftReset} from '#/state/events' import {FeedFeedbackProvider, useFeedFeedback} from '#/state/feed-feedback' import {useSetHomeBadge} from '#/state/home-badge' -import {SavedFeedSourceInfo} from '#/state/queries/feed' +import {type SavedFeedSourceInfo} from '#/state/queries/feed' import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed' -import {FeedDescriptor, FeedParams} from '#/state/queries/post-feed' +import {type FeedDescriptor, type FeedParams} from '#/state/queries/post-feed' import {truncateAndInvalidate} from '#/state/queries/util' import {useSession} from '#/state/session' import {useSetMinimalShellMode} from '#/state/shell' -import {useComposerControls} from '#/state/shell/composer' import {useHeaderOffset} from '#/components/hooks/useHeaderOffset' import {PostFeed} from '../posts/PostFeed' import {FAB} from '../util/fab/FAB' -import {ListMethods} from '../util/List' +import {type ListMethods} from '../util/List' import {LoadLatestBtn} from '../util/load-latest/LoadLatestBtn' import {MainScrollProvider} from '../util/MainScrollProvider' @@ -57,7 +57,7 @@ export function FeedPage({ const {_} = useLingui() const navigation = useNavigation<NavigationProp<AllNavigatorParams>>() const queryClient = useQueryClient() - const {openComposer} = useComposerControls() + const {openComposer} = useOpenComposer() const [isScrolledDown, setIsScrolledDown] = React.useState(false) const setMinimalShellMode = useSetMinimalShellMode() const headerOffset = useHeaderOffset() diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx index 83dbdb553..d974ce6b5 100644 --- a/src/view/com/post-thread/PostThread.tsx +++ b/src/view/com/post-thread/PostThread.tsx @@ -5,7 +5,7 @@ import Animated from 'react-native-reanimated' import {useSafeAreaInsets} from 'react-native-safe-area-context' import { AppBskyFeedDefs, - AppBskyFeedThreadgate, + type AppBskyFeedThreadgate, moderatePost, } from '@atproto/api' import {msg, Trans} from '@lingui/macro' @@ -14,6 +14,7 @@ import {useLingui} from '@lingui/react' import {HITSLOP_10} from '#/lib/constants' import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender' import {useMinimalShellFabTransform} from '#/lib/hooks/useMinimalShellTransform' +import {useOpenComposer} from '#/lib/hooks/useOpenComposer' import {useSetTitle} from '#/lib/hooks/useSetTitle' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {clamp} from '#/lib/numbers' @@ -25,19 +26,18 @@ import {useModerationOpts} from '#/state/preferences/moderation-opts' import { fillThreadModerationCache, sortThread, - ThreadBlocked, - ThreadModerationCache, - ThreadNode, - ThreadNotFound, - ThreadPost, + type ThreadBlocked, + type ThreadModerationCache, + type ThreadNode, + type ThreadNotFound, + type ThreadPost, usePostThreadQuery, } from '#/state/queries/post-thread' import {useSetThreadViewPreferencesMutation} from '#/state/queries/preferences' import {usePreferencesQuery} from '#/state/queries/preferences' import {useSession} from '#/state/session' -import {useComposerControls} from '#/state/shell' import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies' -import {List, ListMethods} from '#/view/com/util/List' +import {List, type ListMethods} from '#/view/com/util/List' import {atoms as a, useTheme} from '#/alf' import {Button, ButtonIcon} from '#/components/Button' import {SettingsSliderVertical_Stroke2_Corner0_Rounded as SettingsSlider} from '#/components/icons/SettingsSlider' @@ -394,7 +394,7 @@ export function PostThread({uri}: {uri: string | undefined}) { [refetch], ) - const {openComposer} = useComposerControls() + const {openComposer} = useOpenComposer() const onPressReply = React.useCallback(() => { if (thread?.type !== 'post') { return diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index dfd641f66..10c3e6b4d 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -17,6 +17,7 @@ import {msg, Plural, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {MAX_POST_LINES} from '#/lib/constants' +import {useOpenComposer} from '#/lib/hooks/useOpenComposer' import {useOpenLink} from '#/lib/hooks/useOpenLink' import {usePalette} from '#/lib/hooks/usePalette' import {makeProfileLink} from '#/lib/routes/links' @@ -36,7 +37,6 @@ import {useProfileShadow} from '#/state/cache/profile-shadow' import {useLanguagePrefs} from '#/state/preferences' import {type ThreadPost} from '#/state/queries/post-thread' import {useSession} from '#/state/session' -import {useComposerControls} from '#/state/shell/composer' import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies' import {PostThreadFollowBtn} from '#/view/com/post-thread/PostThreadFollowBtn' import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' @@ -204,7 +204,7 @@ let PostThreadItemLoaded = ({ const pal = usePalette('default') const {_, i18n} = useLingui() const langPrefs = useLanguagePrefs() - const {openComposer} = useComposerControls() + const {openComposer} = useOpenComposer() const [limitLines, setLimitLines] = React.useState( () => countLines(richText?.text) >= MAX_POST_LINES, ) diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx index 600cee428..c6cf254f3 100644 --- a/src/view/com/post/Post.tsx +++ b/src/view/com/post/Post.tsx @@ -1,11 +1,11 @@ import React, {useMemo, useState} from 'react' -import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native' +import {type StyleProp, StyleSheet, View, type ViewStyle} from 'react-native' import { - AppBskyFeedDefs, + type AppBskyFeedDefs, AppBskyFeedPost, AtUri, moderatePost, - ModerationDecision, + type ModerationDecision, RichText as RichTextAPI, } from '@atproto/api' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' @@ -14,15 +14,19 @@ import {useLingui} from '@lingui/react' import {useQueryClient} from '@tanstack/react-query' import {MAX_POST_LINES} from '#/lib/constants' +import {useOpenComposer} from '#/lib/hooks/useOpenComposer' import {usePalette} from '#/lib/hooks/usePalette' import {makeProfileLink} from '#/lib/routes/links' import {countLines} from '#/lib/strings/helpers' import {colors, s} from '#/lib/styles' -import {POST_TOMBSTONE, Shadow, usePostShadow} from '#/state/cache/post-shadow' +import { + POST_TOMBSTONE, + type Shadow, + usePostShadow, +} from '#/state/cache/post-shadow' import {useModerationOpts} from '#/state/preferences/moderation-opts' import {precacheProfile} from '#/state/queries/profile' import {useSession} from '#/state/session' -import {useComposerControls} from '#/state/shell/composer' import {AviFollowButton} from '#/view/com/posts/AviFollowButton' import {atoms as a} from '#/alf' import {ProfileHoverCard} from '#/components/ProfileHoverCard' @@ -113,7 +117,7 @@ function PostInner({ const queryClient = useQueryClient() const pal = usePalette('default') const {_} = useLingui() - const {openComposer} = useComposerControls() + const {openComposer} = useOpenComposer() const [limitLines, setLimitLines] = useState( () => countLines(richText?.text) >= MAX_POST_LINES, ) diff --git a/src/view/com/posts/PostFeedItem.tsx b/src/view/com/posts/PostFeedItem.tsx index facd31e5f..123a8b0c2 100644 --- a/src/view/com/posts/PostFeedItem.tsx +++ b/src/view/com/posts/PostFeedItem.tsx @@ -19,6 +19,7 @@ import {useQueryClient} from '@tanstack/react-query' import {isReasonFeedSource, type ReasonFeedSource} from '#/lib/api/feed/types' import {MAX_POST_LINES} from '#/lib/constants' +import {useOpenComposer} from '#/lib/hooks/useOpenComposer' import {usePalette} from '#/lib/hooks/usePalette' import {makeProfileLink} from '#/lib/routes/links' import {sanitizeDisplayName} from '#/lib/strings/display-names' @@ -33,7 +34,6 @@ import { import {useFeedFeedbackContext} from '#/state/feed-feedback' import {precacheProfile} from '#/state/queries/profile' import {useSession} from '#/state/session' -import {useComposerControls} from '#/state/shell/composer' import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies' import {FeedNameText} from '#/view/com/util/FeedInfoText' import {PostCtrls} from '#/view/com/util/post-ctrls/PostCtrls' @@ -159,7 +159,7 @@ let FeedItemInner = ({ onShowLess?: (interaction: AppBskyFeedDefs.Interaction) => void }): React.ReactNode => { const queryClient = useQueryClient() - const {openComposer} = useComposerControls() + const {openComposer} = useOpenComposer() const pal = usePalette('default') const {_} = useLingui() diff --git a/src/view/com/util/post-ctrls/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx index d97654a63..a9cae8886 100644 --- a/src/view/com/util/post-ctrls/PostCtrls.tsx +++ b/src/view/com/util/post-ctrls/PostCtrls.tsx @@ -22,6 +22,7 @@ import {DISCOVER_DEBUG_DIDS, POST_CTRL_HITSLOP} from '#/lib/constants' import {CountWheel} from '#/lib/custom-animations/CountWheel' import {AnimatedLikeIcon} from '#/lib/custom-animations/LikeIcon' import {useHaptics} from '#/lib/haptics' +import {useOpenComposer} from '#/lib/hooks/useOpenComposer' import {makeProfileLink} from '#/lib/routes/links' import {shareUrl} from '#/lib/sharing' import {useGate} from '#/lib/statsig/statsig' @@ -33,7 +34,6 @@ import { usePostRepostMutationQueue, } from '#/state/queries/post' import {useRequireAuth, useSession} from '#/state/session' -import {useComposerControls} from '#/state/shell/composer' import { ProgressGuideAction, useProgressGuideControls, @@ -76,7 +76,7 @@ let PostCtrls = ({ }): React.ReactNode => { const t = useTheme() const {_, i18n} = useLingui() - const {openComposer} = useComposerControls() + const {openComposer} = useOpenComposer() const {currentAccount} = useSession() const [queueLike, queueUnlike] = usePostLikeMutationQueue(post, logContext) const [queueRepost, queueUnrepost] = usePostRepostMutationQueue( |