[APP-1013] Configure and apply default post interaction settings from user preferences (#7664)
* Add interaction settings screen * Move header out of interaction settings form * WIP hook it up * Thread through default settings into composer * Update copy pasta * Handle edited state * Copy feedback * Sentence case Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update copy * Bump SDK * Fix new type error * Less in your face * Remove new dep * Add slot * Copy edit --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
This commit is contained in:
+1
-1
@@ -54,7 +54,7 @@
|
|||||||
"icons:optimize": "svgo -f ./assets/icons"
|
"icons:optimize": "svgo -f ./assets/icons"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@atproto/api": "^0.13.31",
|
"@atproto/api": "^0.13.33",
|
||||||
"@bitdrift/react-native": "^0.6.2",
|
"@bitdrift/react-native": "^0.6.2",
|
||||||
"@braintree/sanitize-url": "^6.0.2",
|
"@braintree/sanitize-url": "^6.0.2",
|
||||||
"@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet",
|
"@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet",
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ import {MessagesScreen} from '#/screens/Messages/ChatList'
|
|||||||
import {MessagesConversationScreen} from '#/screens/Messages/Conversation'
|
import {MessagesConversationScreen} from '#/screens/Messages/Conversation'
|
||||||
import {MessagesSettingsScreen} from '#/screens/Messages/Settings'
|
import {MessagesSettingsScreen} from '#/screens/Messages/Settings'
|
||||||
import {ModerationScreen} from '#/screens/Moderation'
|
import {ModerationScreen} from '#/screens/Moderation'
|
||||||
|
import {Screen as ModerationInteractionSettings} from '#/screens/ModerationInteractionSettings'
|
||||||
import {PostLikedByScreen} from '#/screens/Post/PostLikedBy'
|
import {PostLikedByScreen} from '#/screens/Post/PostLikedBy'
|
||||||
import {PostQuotesScreen} from '#/screens/Post/PostQuotes'
|
import {PostQuotesScreen} from '#/screens/Post/PostQuotes'
|
||||||
import {PostRepostedByScreen} from '#/screens/Post/PostRepostedBy'
|
import {PostRepostedByScreen} from '#/screens/Post/PostRepostedBy'
|
||||||
@@ -155,6 +156,14 @@ function commonScreens(Stack: typeof HomeTab, unreadCountLabel?: string) {
|
|||||||
getComponent={() => ModerationBlockedAccounts}
|
getComponent={() => ModerationBlockedAccounts}
|
||||||
options={{title: title(msg`Blocked Accounts`), requireAuth: true}}
|
options={{title: title(msg`Blocked Accounts`), requireAuth: true}}
|
||||||
/>
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="ModerationInteractionSettings"
|
||||||
|
getComponent={() => ModerationInteractionSettings}
|
||||||
|
options={{
|
||||||
|
title: title(msg`Post Interaction Settings`),
|
||||||
|
requireAuth: true,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
name="Settings"
|
name="Settings"
|
||||||
getComponent={() => SettingsScreen}
|
getComponent={() => SettingsScreen}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import {Loader} from '#/components/Loader'
|
|||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
export type PostInteractionSettingsFormProps = {
|
export type PostInteractionSettingsFormProps = {
|
||||||
|
canSave?: boolean
|
||||||
onSave: () => void
|
onSave: () => void
|
||||||
isSaving?: boolean
|
isSaving?: boolean
|
||||||
|
|
||||||
@@ -58,20 +59,53 @@ export function PostInteractionSettingsControlledDialog({
|
|||||||
}: PostInteractionSettingsFormProps & {
|
}: PostInteractionSettingsFormProps & {
|
||||||
control: Dialog.DialogControlProps
|
control: Dialog.DialogControlProps
|
||||||
}) {
|
}) {
|
||||||
|
const t = useTheme()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog.Outer control={control}>
|
<Dialog.Outer control={control}>
|
||||||
<Dialog.Handle />
|
<Dialog.Handle />
|
||||||
<Dialog.ScrollableInner
|
<Dialog.ScrollableInner
|
||||||
label={_(msg`Edit post interaction settings`)}
|
label={_(msg`Edit post interaction settings`)}
|
||||||
style={[{maxWidth: 500}, a.w_full]}>
|
style={[{maxWidth: 500}, a.w_full]}>
|
||||||
<PostInteractionSettingsForm {...rest} />
|
<View style={[a.gap_md]}>
|
||||||
|
<Header />
|
||||||
|
<PostInteractionSettingsForm {...rest} />
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
a.pt_sm,
|
||||||
|
a.text_sm,
|
||||||
|
a.leading_snug,
|
||||||
|
t.atoms.text_contrast_medium,
|
||||||
|
]}>
|
||||||
|
<Trans>
|
||||||
|
You can set default interaction settings in{' '}
|
||||||
|
<Text style={[a.font_bold, t.atoms.text_contrast_medium]}>
|
||||||
|
Settings → Moderation → Interaction settings.
|
||||||
|
</Text>
|
||||||
|
</Trans>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
<Dialog.Close />
|
<Dialog.Close />
|
||||||
</Dialog.ScrollableInner>
|
</Dialog.ScrollableInner>
|
||||||
</Dialog.Outer>
|
</Dialog.Outer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function Header() {
|
||||||
|
return (
|
||||||
|
<View style={[a.gap_md, a.pb_sm]}>
|
||||||
|
<Text style={[a.text_2xl, a.font_bold]}>
|
||||||
|
<Trans>Post interaction settings</Trans>
|
||||||
|
</Text>
|
||||||
|
<Text style={[a.text_md, a.pb_xs]}>
|
||||||
|
<Trans>Customize who can interact with this post.</Trans>
|
||||||
|
</Text>
|
||||||
|
<Divider />
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export type PostInteractionSettingsDialogProps = {
|
export type PostInteractionSettingsDialogProps = {
|
||||||
control: Dialog.DialogControlProps
|
control: Dialog.DialogControlProps
|
||||||
/**
|
/**
|
||||||
@@ -203,26 +237,31 @@ export function PostInteractionSettingsDialogControlledInner(
|
|||||||
<Dialog.ScrollableInner
|
<Dialog.ScrollableInner
|
||||||
label={_(msg`Edit post interaction settings`)}
|
label={_(msg`Edit post interaction settings`)}
|
||||||
style={[{maxWidth: 500}, a.w_full]}>
|
style={[{maxWidth: 500}, a.w_full]}>
|
||||||
{isLoading ? (
|
<View style={[a.gap_md]}>
|
||||||
<View style={[a.flex_1, a.py_4xl, a.align_center, a.justify_center]}>
|
<Header />
|
||||||
<Loader size="xl" />
|
|
||||||
</View>
|
{isLoading ? (
|
||||||
) : (
|
<View style={[a.flex_1, a.py_4xl, a.align_center, a.justify_center]}>
|
||||||
<PostInteractionSettingsForm
|
<Loader size="xl" />
|
||||||
replySettingsDisabled={!isThreadgateOwnedByViewer}
|
</View>
|
||||||
isSaving={isSaving}
|
) : (
|
||||||
onSave={onSave}
|
<PostInteractionSettingsForm
|
||||||
postgate={postgateValue}
|
replySettingsDisabled={!isThreadgateOwnedByViewer}
|
||||||
onChangePostgate={setEditedPostgate}
|
isSaving={isSaving}
|
||||||
threadgateAllowUISettings={allowUIValue}
|
onSave={onSave}
|
||||||
onChangeThreadgateAllowUISettings={setEditedAllowUISettings}
|
postgate={postgateValue}
|
||||||
/>
|
onChangePostgate={setEditedPostgate}
|
||||||
)}
|
threadgateAllowUISettings={allowUIValue}
|
||||||
|
onChangeThreadgateAllowUISettings={setEditedAllowUISettings}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
</Dialog.ScrollableInner>
|
</Dialog.ScrollableInner>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PostInteractionSettingsForm({
|
export function PostInteractionSettingsForm({
|
||||||
|
canSave = true,
|
||||||
onSave,
|
onSave,
|
||||||
isSaving,
|
isSaving,
|
||||||
postgate,
|
postgate,
|
||||||
@@ -283,17 +322,7 @@ export function PostInteractionSettingsForm({
|
|||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<View style={[a.flex_1, a.gap_md]}>
|
<View style={[a.flex_1, a.gap_md]}>
|
||||||
<Text style={[a.text_2xl, a.font_bold]}>
|
|
||||||
<Trans>Post interaction settings</Trans>
|
|
||||||
</Text>
|
|
||||||
|
|
||||||
<View style={[a.gap_lg]}>
|
<View style={[a.gap_lg]}>
|
||||||
<Text style={[a.text_md]}>
|
|
||||||
<Trans>Customize who can interact with this post.</Trans>
|
|
||||||
</Text>
|
|
||||||
|
|
||||||
<Divider />
|
|
||||||
|
|
||||||
<View style={[a.gap_sm]}>
|
<View style={[a.gap_sm]}>
|
||||||
<Text style={[a.font_bold, a.text_lg]}>
|
<Text style={[a.font_bold, a.text_lg]}>
|
||||||
<Trans>Quote settings</Trans>
|
<Trans>Quote settings</Trans>
|
||||||
@@ -435,6 +464,7 @@ export function PostInteractionSettingsForm({
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
disabled={!canSave || isSaving}
|
||||||
label={_(msg`Save`)}
|
label={_(msg`Save`)}
|
||||||
onPress={onSave}
|
onPress={onSave}
|
||||||
color="primary"
|
color="primary"
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export type CommonNavigatorParams = {
|
|||||||
ModerationModlists: undefined
|
ModerationModlists: undefined
|
||||||
ModerationMutedAccounts: undefined
|
ModerationMutedAccounts: undefined
|
||||||
ModerationBlockedAccounts: undefined
|
ModerationBlockedAccounts: undefined
|
||||||
|
ModerationInteractionSettings: undefined
|
||||||
Settings: undefined
|
Settings: undefined
|
||||||
Profile: {name: string; hideBackButton?: boolean}
|
Profile: {name: string; hideBackButton?: boolean}
|
||||||
ProfileFollowers: {name: string}
|
ProfileFollowers: {name: string}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export const router = new Router({
|
|||||||
ModerationModlists: '/moderation/modlists',
|
ModerationModlists: '/moderation/modlists',
|
||||||
ModerationMutedAccounts: '/moderation/muted-accounts',
|
ModerationMutedAccounts: '/moderation/muted-accounts',
|
||||||
ModerationBlockedAccounts: '/moderation/blocked-accounts',
|
ModerationBlockedAccounts: '/moderation/blocked-accounts',
|
||||||
|
ModerationInteractionSettings: '/moderation/interaction-settings',
|
||||||
// profiles, threads, lists
|
// profiles, threads, lists
|
||||||
Profile: ['/profile/:name', '/profile/:name/rss'],
|
Profile: ['/profile/:name', '/profile/:name/rss'],
|
||||||
ProfileFollowers: '/profile/:name/followers',
|
ProfileFollowers: '/profile/:name/followers',
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import * as Toggle from '#/components/forms/Toggle'
|
|||||||
import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron'
|
import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron'
|
||||||
import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign'
|
import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign'
|
||||||
import {Props as SVGIconProps} from '#/components/icons/common'
|
import {Props as SVGIconProps} from '#/components/icons/common'
|
||||||
|
import {EditBig_Stroke2_Corner0_Rounded as EditBig} from '#/components/icons/EditBig'
|
||||||
import {Filter_Stroke2_Corner0_Rounded as Filter} from '#/components/icons/Filter'
|
import {Filter_Stroke2_Corner0_Rounded as Filter} from '#/components/icons/Filter'
|
||||||
import {Group3_Stroke2_Corner0_Rounded as Group} from '#/components/icons/Group'
|
import {Group3_Stroke2_Corner0_Rounded as Group} from '#/components/icons/Group'
|
||||||
import {Person_Stroke2_Corner0_Rounded as Person} from '#/components/icons/Person'
|
import {Person_Stroke2_Corner0_Rounded as Person} from '#/components/icons/Person'
|
||||||
@@ -199,6 +200,21 @@ export function ModerationScreenInner({
|
|||||||
a.overflow_hidden,
|
a.overflow_hidden,
|
||||||
t.atoms.bg_contrast_25,
|
t.atoms.bg_contrast_25,
|
||||||
]}>
|
]}>
|
||||||
|
<Link
|
||||||
|
label={_(msg`View your default post interaction settings`)}
|
||||||
|
testID="interactionSettingsBtn"
|
||||||
|
to="/moderation/interaction-settings">
|
||||||
|
{state => (
|
||||||
|
<SubItem
|
||||||
|
title={_(msg`Interaction settings`)}
|
||||||
|
icon={EditBig}
|
||||||
|
style={[
|
||||||
|
(state.hovered || state.pressed) && [t.atoms.bg_contrast_50],
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Link>
|
||||||
|
<Divider />
|
||||||
<Button
|
<Button
|
||||||
testID="mutedWordsBtn"
|
testID="mutedWordsBtn"
|
||||||
label={_(msg`Open muted words and tags settings`)}
|
label={_(msg`Open muted words and tags settings`)}
|
||||||
|
|||||||
@@ -0,0 +1,127 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import {View} from 'react-native'
|
||||||
|
import {msg, Trans} from '@lingui/macro'
|
||||||
|
import {useLingui} from '@lingui/react'
|
||||||
|
import deepEqual from 'lodash.isequal'
|
||||||
|
|
||||||
|
import {logger} from '#/logger'
|
||||||
|
import {usePostInteractionSettingsMutation} from '#/state/queries/post-interaction-settings'
|
||||||
|
import {createPostgateRecord} from '#/state/queries/postgate/util'
|
||||||
|
import {
|
||||||
|
usePreferencesQuery,
|
||||||
|
UsePreferencesQueryResponse,
|
||||||
|
} from '#/state/queries/preferences'
|
||||||
|
import {
|
||||||
|
threadgateAllowUISettingToAllowRecordValue,
|
||||||
|
threadgateRecordToAllowUISetting,
|
||||||
|
} from '#/state/queries/threadgate'
|
||||||
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
|
import {atoms as a, useGutters} from '#/alf'
|
||||||
|
import {Admonition} from '#/components/Admonition'
|
||||||
|
import {PostInteractionSettingsForm} from '#/components/dialogs/PostInteractionSettingsDialog'
|
||||||
|
import * as Layout from '#/components/Layout'
|
||||||
|
import {Loader} from '#/components/Loader'
|
||||||
|
|
||||||
|
export function Screen() {
|
||||||
|
const gutters = useGutters(['base'])
|
||||||
|
const {data: preferences} = usePreferencesQuery()
|
||||||
|
return (
|
||||||
|
<Layout.Screen testID="ModerationInteractionSettingsScreen">
|
||||||
|
<Layout.Header.Outer>
|
||||||
|
<Layout.Header.BackButton />
|
||||||
|
<Layout.Header.Content>
|
||||||
|
<Layout.Header.TitleText>
|
||||||
|
<Trans>Post Interaction Settings</Trans>
|
||||||
|
</Layout.Header.TitleText>
|
||||||
|
</Layout.Header.Content>
|
||||||
|
<Layout.Header.Slot />
|
||||||
|
</Layout.Header.Outer>
|
||||||
|
<Layout.Content>
|
||||||
|
<View style={[gutters, a.gap_xl]}>
|
||||||
|
<Admonition type="tip">
|
||||||
|
<Trans>
|
||||||
|
The following settings will be used as your defaults when creating
|
||||||
|
new posts. You can edit these for a specific post from the
|
||||||
|
composer.
|
||||||
|
</Trans>
|
||||||
|
</Admonition>
|
||||||
|
{preferences ? (
|
||||||
|
<Inner preferences={preferences} />
|
||||||
|
) : (
|
||||||
|
<View style={[gutters, a.justify_center, a.align_center]}>
|
||||||
|
<Loader size="xl" />
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</Layout.Content>
|
||||||
|
</Layout.Screen>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) {
|
||||||
|
const {_} = useLingui()
|
||||||
|
const {mutateAsync: setPostInteractionSettings, isPending} =
|
||||||
|
usePostInteractionSettingsMutation()
|
||||||
|
const [error, setError] = React.useState<string | undefined>(undefined)
|
||||||
|
|
||||||
|
const allowUI = React.useMemo(() => {
|
||||||
|
return threadgateRecordToAllowUISetting({
|
||||||
|
$type: 'app.bsky.feed.threadgate',
|
||||||
|
post: '',
|
||||||
|
createdAt: new Date().toString(),
|
||||||
|
allow: preferences.postInteractionSettings.threadgateAllowRules,
|
||||||
|
})
|
||||||
|
}, [preferences.postInteractionSettings.threadgateAllowRules])
|
||||||
|
const postgate = React.useMemo(() => {
|
||||||
|
return createPostgateRecord({
|
||||||
|
post: '',
|
||||||
|
embeddingRules:
|
||||||
|
preferences.postInteractionSettings.postgateEmbeddingRules,
|
||||||
|
})
|
||||||
|
}, [preferences.postInteractionSettings.postgateEmbeddingRules])
|
||||||
|
|
||||||
|
const [maybeEditedAllowUI, setAllowUI] = React.useState(allowUI)
|
||||||
|
const [maybeEditedPostgate, setEditedPostgate] = React.useState(postgate)
|
||||||
|
|
||||||
|
const wasEdited = React.useMemo(() => {
|
||||||
|
return (
|
||||||
|
!deepEqual(allowUI, maybeEditedAllowUI) ||
|
||||||
|
!deepEqual(postgate.embeddingRules, maybeEditedPostgate.embeddingRules)
|
||||||
|
)
|
||||||
|
}, [postgate, allowUI, maybeEditedAllowUI, maybeEditedPostgate])
|
||||||
|
|
||||||
|
const onSave = React.useCallback(async () => {
|
||||||
|
setError('')
|
||||||
|
|
||||||
|
try {
|
||||||
|
await setPostInteractionSettings({
|
||||||
|
threadgateAllowRules:
|
||||||
|
threadgateAllowUISettingToAllowRecordValue(maybeEditedAllowUI),
|
||||||
|
postgateEmbeddingRules: maybeEditedPostgate.embeddingRules ?? [],
|
||||||
|
})
|
||||||
|
Toast.show(_(msg`Settings saved`))
|
||||||
|
} catch (e: any) {
|
||||||
|
logger.error(`Failed to save post interaction settings`, {
|
||||||
|
context: 'ModerationInteractionSettingsScreen',
|
||||||
|
safeMessage: e.message,
|
||||||
|
})
|
||||||
|
setError(_(msg`Failed to save settings. Please try again.`))
|
||||||
|
}
|
||||||
|
}, [_, maybeEditedPostgate, maybeEditedAllowUI, setPostInteractionSettings])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PostInteractionSettingsForm
|
||||||
|
canSave={wasEdited}
|
||||||
|
isSaving={isPending}
|
||||||
|
onSave={onSave}
|
||||||
|
postgate={maybeEditedPostgate}
|
||||||
|
onChangePostgate={setEditedPostgate}
|
||||||
|
threadgateAllowUISettings={maybeEditedAllowUI}
|
||||||
|
onChangeThreadgateAllowUISettings={setAllowUI}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{error && <Admonition type="error">{error}</Admonition>}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -36,7 +36,7 @@ export function ExportCarDialog({
|
|||||||
const saveRes = await saveBytesToDisk(
|
const saveRes = await saveBytesToDisk(
|
||||||
'repo.car',
|
'repo.car',
|
||||||
downloadRes.data,
|
downloadRes.data,
|
||||||
downloadRes.headers['content-type'],
|
downloadRes.headers['content-type'] || 'application/vnd.ipld.car',
|
||||||
)
|
)
|
||||||
|
|
||||||
if (saveRes) {
|
if (saveRes) {
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import {AppBskyActorDefs} from '@atproto/api'
|
||||||
|
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {preferencesQueryKey} from '#/state/queries/preferences'
|
||||||
|
import {useAgent} from '#/state/session'
|
||||||
|
|
||||||
|
export function usePostInteractionSettingsMutation() {
|
||||||
|
const qc = useQueryClient()
|
||||||
|
const agent = useAgent()
|
||||||
|
return useMutation({
|
||||||
|
async mutationFn(props: AppBskyActorDefs.PostInteractionSettingsPref) {
|
||||||
|
await agent.setPostInteractionSettings(props)
|
||||||
|
},
|
||||||
|
async onSuccess() {
|
||||||
|
await qc.invalidateQueries({
|
||||||
|
queryKey: preferencesQueryKey,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -39,4 +39,8 @@ export const DEFAULT_LOGGED_OUT_PREFERENCES: UsePreferencesQueryResponse = {
|
|||||||
activeProgressGuide: undefined,
|
activeProgressGuide: undefined,
|
||||||
nuxs: [],
|
nuxs: [],
|
||||||
},
|
},
|
||||||
|
postInteractionSettings: {
|
||||||
|
threadgateAllowRules: undefined,
|
||||||
|
postgateEmbeddingRules: [],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ import {
|
|||||||
useLanguagePrefs,
|
useLanguagePrefs,
|
||||||
useLanguagePrefsApi,
|
useLanguagePrefsApi,
|
||||||
} from '#/state/preferences/languages'
|
} from '#/state/preferences/languages'
|
||||||
|
import {usePreferencesQuery} from '#/state/queries/preferences'
|
||||||
import {useProfileQuery} from '#/state/queries/profile'
|
import {useProfileQuery} from '#/state/queries/profile'
|
||||||
import {Gif} from '#/state/queries/tenor'
|
import {Gif} from '#/state/queries/tenor'
|
||||||
import {useAgent, useSession} from '#/state/session'
|
import {useAgent, useSession} from '#/state/session'
|
||||||
@@ -169,6 +170,7 @@ export const ComposePost = ({
|
|||||||
const discardPromptControl = Prompt.usePromptControl()
|
const discardPromptControl = Prompt.usePromptControl()
|
||||||
const {closeAllDialogs} = useDialogStateControlContext()
|
const {closeAllDialogs} = useDialogStateControlContext()
|
||||||
const {closeAllModals} = useModalControls()
|
const {closeAllModals} = useModalControls()
|
||||||
|
const {data: preferences} = usePreferencesQuery()
|
||||||
|
|
||||||
const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true})
|
const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true})
|
||||||
const [isPublishing, setIsPublishing] = useState(false)
|
const [isPublishing, setIsPublishing] = useState(false)
|
||||||
@@ -177,7 +179,13 @@ export const ComposePost = ({
|
|||||||
|
|
||||||
const [composerState, composerDispatch] = useReducer(
|
const [composerState, composerDispatch] = useReducer(
|
||||||
composerReducer,
|
composerReducer,
|
||||||
{initImageUris, initQuoteUri: initQuote?.uri, initText, initMention},
|
{
|
||||||
|
initImageUris,
|
||||||
|
initQuoteUri: initQuote?.uri,
|
||||||
|
initText,
|
||||||
|
initMention,
|
||||||
|
initInteractionSettings: preferences?.postInteractionSettings,
|
||||||
|
},
|
||||||
createComposerState,
|
createComposerState,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import {ImagePickerAsset} from 'expo-image-picker'
|
import {ImagePickerAsset} from 'expo-image-picker'
|
||||||
import {AppBskyFeedPostgate, AppBskyRichtextFacet, RichText} from '@atproto/api'
|
import {
|
||||||
|
AppBskyFeedPostgate,
|
||||||
|
AppBskyRichtextFacet,
|
||||||
|
BskyPreferences,
|
||||||
|
RichText,
|
||||||
|
} from '@atproto/api'
|
||||||
import {nanoid} from 'nanoid/non-secure'
|
import {nanoid} from 'nanoid/non-secure'
|
||||||
|
|
||||||
import {SelfLabel} from '#/lib/moderation'
|
import {SelfLabel} from '#/lib/moderation'
|
||||||
@@ -13,7 +18,7 @@ import {
|
|||||||
import {ComposerImage, createInitialImages} from '#/state/gallery'
|
import {ComposerImage, createInitialImages} from '#/state/gallery'
|
||||||
import {createPostgateRecord} from '#/state/queries/postgate/util'
|
import {createPostgateRecord} from '#/state/queries/postgate/util'
|
||||||
import {Gif} from '#/state/queries/tenor'
|
import {Gif} from '#/state/queries/tenor'
|
||||||
import {threadgateViewToAllowUISetting} from '#/state/queries/threadgate'
|
import {threadgateRecordToAllowUISetting} from '#/state/queries/threadgate'
|
||||||
import {ThreadgateAllowUISetting} from '#/state/queries/threadgate'
|
import {ThreadgateAllowUISetting} from '#/state/queries/threadgate'
|
||||||
import {ComposerOpts} from '#/state/shell/composer'
|
import {ComposerOpts} from '#/state/shell/composer'
|
||||||
import {
|
import {
|
||||||
@@ -477,11 +482,15 @@ export function createComposerState({
|
|||||||
initMention,
|
initMention,
|
||||||
initImageUris,
|
initImageUris,
|
||||||
initQuoteUri,
|
initQuoteUri,
|
||||||
|
initInteractionSettings,
|
||||||
}: {
|
}: {
|
||||||
initText: string | undefined
|
initText: string | undefined
|
||||||
initMention: string | undefined
|
initMention: string | undefined
|
||||||
initImageUris: ComposerOpts['imageUris']
|
initImageUris: ComposerOpts['imageUris']
|
||||||
initQuoteUri: string | undefined
|
initQuoteUri: string | undefined
|
||||||
|
initInteractionSettings:
|
||||||
|
| BskyPreferences['postInteractionSettings']
|
||||||
|
| undefined
|
||||||
}): ComposerState {
|
}): ComposerState {
|
||||||
let media: ImagesMedia | undefined
|
let media: ImagesMedia | undefined
|
||||||
if (initImageUris?.length) {
|
if (initImageUris?.length) {
|
||||||
@@ -591,8 +600,16 @@ export function createComposerState({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
postgate: createPostgateRecord({post: ''}),
|
postgate: createPostgateRecord({
|
||||||
threadgate: threadgateViewToAllowUISetting(undefined),
|
post: '',
|
||||||
|
embeddingRules: initInteractionSettings?.postgateEmbeddingRules || [],
|
||||||
|
}),
|
||||||
|
threadgate: threadgateRecordToAllowUISetting({
|
||||||
|
$type: 'app.bsky.feed.threadgate',
|
||||||
|
post: '',
|
||||||
|
createdAt: new Date().toString(),
|
||||||
|
allow: initInteractionSettings?.threadgateAllowRules,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,15 +72,15 @@
|
|||||||
tlds "^1.234.0"
|
tlds "^1.234.0"
|
||||||
zod "^3.23.8"
|
zod "^3.23.8"
|
||||||
|
|
||||||
"@atproto/api@^0.13.31":
|
"@atproto/api@^0.13.33":
|
||||||
version "0.13.31"
|
version "0.13.33"
|
||||||
resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.13.31.tgz#23ca2c9118eefddf6e0206f759e56b6726b68483"
|
resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.13.33.tgz#01d31a1cfd1be311e11324b810b8a83fe4cbf9b0"
|
||||||
integrity sha512-i2cUQuwe+3j8rgPJj4YWRjSQeJunGqJ3IzesnvbODjjZh3IS9jB80BZ/pTe/AvNg6JCBbqeWJjWDVKeFHaiZAw==
|
integrity sha512-d8AOvtxo2J2zrmcakJTUtLdz2ns+pAqywNXhPxPzHrHcw79D6MKBLHR0vr8oxkGwhDBQTsHiQWTk4gSo8PF7YA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@atproto/common-web" "^0.3.2"
|
"@atproto/common-web" "^0.4.0"
|
||||||
"@atproto/lexicon" "^0.4.5"
|
"@atproto/lexicon" "^0.4.6"
|
||||||
"@atproto/syntax" "^0.3.1"
|
"@atproto/syntax" "^0.3.2"
|
||||||
"@atproto/xrpc" "^0.6.6"
|
"@atproto/xrpc" "^0.6.8"
|
||||||
await-lock "^2.2.2"
|
await-lock "^2.2.2"
|
||||||
multiformats "^9.9.0"
|
multiformats "^9.9.0"
|
||||||
tlds "^1.234.0"
|
tlds "^1.234.0"
|
||||||
@@ -169,10 +169,10 @@
|
|||||||
uint8arrays "3.0.0"
|
uint8arrays "3.0.0"
|
||||||
zod "^3.23.8"
|
zod "^3.23.8"
|
||||||
|
|
||||||
"@atproto/common-web@^0.3.2":
|
"@atproto/common-web@^0.4.0":
|
||||||
version "0.3.2"
|
version "0.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/@atproto/common-web/-/common-web-0.3.2.tgz#4cf78ad4d24fed801882f3d35afc39bceccdff51"
|
resolved "https://registry.yarnpkg.com/@atproto/common-web/-/common-web-0.4.0.tgz#b1407ae3f964f0ee23c2c3184f38041bac99d1f4"
|
||||||
integrity sha512-Vx0JtL1/CssJbFAb0UOdvTrkbUautsDfHNOXNTcX2vyPIxH9xOameSqLLunM1hZnOQbJwyjmQCt6TV+bhnanDg==
|
integrity sha512-ZYL0P9myHybNgwh/hBY0HaBzqiLR1B5/ie5bJpLQAg0whRzNA28t8/nU2vh99tbsWcAF0LOD29M8++LyENJLNQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
graphemer "^1.4.0"
|
graphemer "^1.4.0"
|
||||||
multiformats "^9.9.0"
|
multiformats "^9.9.0"
|
||||||
@@ -293,13 +293,13 @@
|
|||||||
multiformats "^9.9.0"
|
multiformats "^9.9.0"
|
||||||
zod "^3.23.8"
|
zod "^3.23.8"
|
||||||
|
|
||||||
"@atproto/lexicon@^0.4.5":
|
"@atproto/lexicon@^0.4.6":
|
||||||
version "0.4.5"
|
version "0.4.6"
|
||||||
resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.4.5.tgz#4fcf3731193c674286e9e8d677bbab5dd530b817"
|
resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.4.6.tgz#74b2a0f3e4c867b33f75430d4ccec70c47e41576"
|
||||||
integrity sha512-fljWqMGKn+XWtTprBcS3F1hGBREnQYh6qYHv2sjENucc7REms1gtmZXSerB9N6pVeHVNOnXiILdukeAcic5OEw==
|
integrity sha512-RbiwXcnTuLp9vQrNoQ7xly8HyifKkovqCYtbfXVwqdylWYKPhmRsYkRfcPNv/lILhT9Lm0GVnxNwGGwvvgIsfA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@atproto/common-web" "^0.3.2"
|
"@atproto/common-web" "^0.4.0"
|
||||||
"@atproto/syntax" "^0.3.1"
|
"@atproto/syntax" "^0.3.2"
|
||||||
iso-datestring-validator "^2.2.2"
|
iso-datestring-validator "^2.2.2"
|
||||||
multiformats "^9.9.0"
|
multiformats "^9.9.0"
|
||||||
zod "^3.23.8"
|
zod "^3.23.8"
|
||||||
@@ -447,6 +447,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.3.1.tgz#4346418728f9643d783d2ffcf7c77e132e1f53d4"
|
resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.3.1.tgz#4346418728f9643d783d2ffcf7c77e132e1f53d4"
|
||||||
integrity sha512-fzW0Mg1QUOVCWUD3RgEsDt6d1OZ6DdFmbKcDdbzUfh0t4rhtRAC05KbZYmxuMPWDAiJ4BbbQ5dkAc/mNypMXkw==
|
integrity sha512-fzW0Mg1QUOVCWUD3RgEsDt6d1OZ6DdFmbKcDdbzUfh0t4rhtRAC05KbZYmxuMPWDAiJ4BbbQ5dkAc/mNypMXkw==
|
||||||
|
|
||||||
|
"@atproto/syntax@^0.3.2":
|
||||||
|
version "0.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.3.2.tgz#188f8dccba11e5ace1bf83cbff8ed9e1a3d2d66c"
|
||||||
|
integrity sha512-JLMhTbXER1Im98RrozfsLAZARGIAzKCZEm+Inh1IF00XU6tHcoGKS+HOw0Uy4R2r04yvxoFs8fswmwAhmMpMdw==
|
||||||
|
|
||||||
"@atproto/xrpc-server@^0.7.4":
|
"@atproto/xrpc-server@^0.7.4":
|
||||||
version "0.7.4"
|
version "0.7.4"
|
||||||
resolved "https://registry.yarnpkg.com/@atproto/xrpc-server/-/xrpc-server-0.7.4.tgz#dfac8f7276c1c971a35eaba627eb6372088441c3"
|
resolved "https://registry.yarnpkg.com/@atproto/xrpc-server/-/xrpc-server-0.7.4.tgz#dfac8f7276c1c971a35eaba627eb6372088441c3"
|
||||||
@@ -473,12 +478,12 @@
|
|||||||
"@atproto/lexicon" "^0.4.4"
|
"@atproto/lexicon" "^0.4.4"
|
||||||
zod "^3.23.8"
|
zod "^3.23.8"
|
||||||
|
|
||||||
"@atproto/xrpc@^0.6.6":
|
"@atproto/xrpc@^0.6.8":
|
||||||
version "0.6.6"
|
version "0.6.8"
|
||||||
resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.6.6.tgz#28f58270ef4a8056f7f718bd52512e74bcd3702f"
|
resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.6.8.tgz#cede54e17b6f8863f78e16f27f87c1966446eea6"
|
||||||
integrity sha512-umXEYVMo9/pyIBoKmIAIi64RXDW9tSXY+wqztlQ6I2GZtjLfNZqmAWU+wADk3SxUe54mvjxxGyA4TtyGtDMfhA==
|
integrity sha512-+KW0NcwdFyLziccYimX6tPkORiwwxlJPqlkVL9bJyj8nJ0aB8cyqo9HXkziMI+R6ansB1BuWQ0tfdPlLLwrUcA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@atproto/lexicon" "^0.4.5"
|
"@atproto/lexicon" "^0.4.6"
|
||||||
zod "^3.23.8"
|
zod "^3.23.8"
|
||||||
|
|
||||||
"@aws-crypto/crc32@3.0.0":
|
"@aws-crypto/crc32@3.0.0":
|
||||||
@@ -3290,7 +3295,7 @@
|
|||||||
"@babel/parser" "^7.25.9"
|
"@babel/parser" "^7.25.9"
|
||||||
"@babel/types" "^7.25.9"
|
"@babel/types" "^7.25.9"
|
||||||
|
|
||||||
"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3":
|
"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3", "@babel/traverse@^7.25.3", "@babel/traverse@^7.25.9":
|
||||||
version "7.25.9"
|
version "7.25.9"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84"
|
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84"
|
||||||
integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==
|
integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==
|
||||||
@@ -3351,19 +3356,6 @@
|
|||||||
debug "^4.3.1"
|
debug "^4.3.1"
|
||||||
globals "^11.1.0"
|
globals "^11.1.0"
|
||||||
|
|
||||||
"@babel/traverse@^7.25.3", "@babel/traverse@^7.25.9":
|
|
||||||
version "7.25.9"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84"
|
|
||||||
integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==
|
|
||||||
dependencies:
|
|
||||||
"@babel/code-frame" "^7.25.9"
|
|
||||||
"@babel/generator" "^7.25.9"
|
|
||||||
"@babel/parser" "^7.25.9"
|
|
||||||
"@babel/template" "^7.25.9"
|
|
||||||
"@babel/types" "^7.25.9"
|
|
||||||
debug "^4.3.1"
|
|
||||||
globals "^11.1.0"
|
|
||||||
|
|
||||||
"@babel/types@^7.0.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.10", "@babel/types@^7.22.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
|
"@babel/types@^7.0.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.10", "@babel/types@^7.22.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
|
||||||
version "7.22.10"
|
version "7.22.10"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.10.tgz#4a9e76446048f2c66982d1a989dd12b8a2d2dc03"
|
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.10.tgz#4a9e76446048f2c66982d1a989dd12b8a2d2dc03"
|
||||||
@@ -17652,16 +17644,7 @@ string-natural-compare@^3.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
|
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
|
||||||
integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==
|
integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==
|
||||||
|
|
||||||
"string-width-cjs@npm:string-width@^4.2.0":
|
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||||
version "4.2.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
|
||||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
|
||||||
dependencies:
|
|
||||||
emoji-regex "^8.0.0"
|
|
||||||
is-fullwidth-code-point "^3.0.0"
|
|
||||||
strip-ansi "^6.0.1"
|
|
||||||
|
|
||||||
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
|
||||||
version "4.2.3"
|
version "4.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||||
@@ -17761,7 +17744,7 @@ string_decoder@~1.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "~5.1.0"
|
safe-buffer "~5.1.0"
|
||||||
|
|
||||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||||
@@ -17775,13 +17758,6 @@ strip-ansi@^5.2.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ansi-regex "^4.1.0"
|
ansi-regex "^4.1.0"
|
||||||
|
|
||||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
|
||||||
version "6.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
|
||||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
|
||||||
dependencies:
|
|
||||||
ansi-regex "^5.0.1"
|
|
||||||
|
|
||||||
strip-ansi@^7.0.1:
|
strip-ansi@^7.0.1:
|
||||||
version "7.1.0"
|
version "7.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
|
||||||
@@ -19056,7 +19032,7 @@ wordwrap@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
|
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
|
||||||
integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
|
integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
|
||||||
|
|
||||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
|
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||||
@@ -19074,15 +19050,6 @@ wrap-ansi@^6.2.0:
|
|||||||
string-width "^4.1.0"
|
string-width "^4.1.0"
|
||||||
strip-ansi "^6.0.0"
|
strip-ansi "^6.0.0"
|
||||||
|
|
||||||
wrap-ansi@^7.0.0:
|
|
||||||
version "7.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
|
||||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
|
||||||
dependencies:
|
|
||||||
ansi-styles "^4.0.0"
|
|
||||||
string-width "^4.1.0"
|
|
||||||
strip-ansi "^6.0.0"
|
|
||||||
|
|
||||||
wrap-ansi@^8.0.1, wrap-ansi@^8.1.0:
|
wrap-ansi@^8.0.1, wrap-ansi@^8.1.0:
|
||||||
version "8.1.0"
|
version "8.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
|
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
|
||||||
|
|||||||
Reference in New Issue
Block a user