diff --git a/assets/icons/flame_stroke2_corner1_rounded.svg b/assets/icons/flame_stroke2_corner1_rounded.svg new file mode 100644 index 0000000000..78a2acc616 --- /dev/null +++ b/assets/icons/flame_stroke2_corner1_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/trending3_stroke2_corner1_rounded.svg b/assets/icons/trending3_stroke2_corner1_rounded.svg new file mode 100644 index 0000000000..0d447d52db --- /dev/null +++ b/assets/icons/trending3_stroke2_corner1_rounded.svg @@ -0,0 +1 @@ + diff --git a/package.json b/package.json index db68a18c84..162b27cb6c 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "icons:optimize": "svgo -f ./assets/icons" }, "dependencies": { - "@atproto/api": "^0.14.16", + "@atproto/api": "^0.14.18", "@bitdrift/react-native": "^0.6.8", "@braintree/sanitize-url": "^6.0.2", "@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet", diff --git a/src/components/icons/Flame.tsx b/src/components/icons/Flame.tsx new file mode 100644 index 0000000000..42569b0dee --- /dev/null +++ b/src/components/icons/Flame.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Flame_Stroke2_Corner1_Rounded = createSinglePathSVG({ + path: 'M11.158 2.879c.584-.835 1.757-1.137 2.673-.507.951.654 2.597 1.92 4.013 3.694S20.5 10.194 20.5 13c0 4.997-3.752 9-8.5 9s-8.5-4.003-8.5-9c0-2.035.874-4.636 2.578-6.712.746-.91 2.034-.855 2.786-.133l2.294-3.276Zm-3.04 15.758C6.538 17.386 5.5 15.37 5.5 13c0-1.511.666-3.616 2.042-5.342.87.797 2.254.653 2.939-.325l2.286-3.265c.871.606 2.299 1.723 3.514 3.246C17.53 8.879 18.5 10.804 18.5 13c0 2.369-1.038 4.386-2.618 5.637q.117-.518.118-1.061c0-2.601-2.038-4.382-2.911-5.04a1.8 1.8 0 0 0-2.177 0C10.038 13.195 8 14.976 8 17.577q0 .543.118 1.061ZM12 14.222c-.825.648-2 1.859-2 3.354C10 19.043 11.016 20 12 20s2-.957 2-2.424c0-1.495-1.175-2.706-2-3.354Z', +}) diff --git a/src/components/icons/Trending2.tsx b/src/components/icons/Trending.tsx similarity index 61% rename from src/components/icons/Trending2.tsx rename to src/components/icons/Trending.tsx index 5fba4167b5..bdc8539e0e 100644 --- a/src/components/icons/Trending2.tsx +++ b/src/components/icons/Trending.tsx @@ -3,3 +3,7 @@ import {createSinglePathSVG} from './TEMPLATE' export const Trending2_Stroke2_Corner2_Rounded = createSinglePathSVG({ path: 'm18.192 5.004 1.864 5.31a1 1 0 0 0 1.887-.662L20.08 4.34c-.665-1.893-3.378-1.741-3.834.207l-3.381 14.449-2.985-9.605C9.3 7.531 6.684 7.506 6.07 9.355l-1.18 3.56-.969-2.312a1 1 0 0 0-1.844.772l.97 2.315c.715 1.71 3.159 1.613 3.741-.144l1.18-3.56 2.985 9.605c.607 1.952 3.392 1.848 3.857-.138l3.381-14.449Z', }) + +export const Trending3_Stroke2_Corner1_Rounded = createSinglePathSVG({ + path: 'M15 7a1 1 0 0 1 1-1h5a1 1 0 0 1 1 1v5a1 1 0 1 1-2 0V9.414L14.414 15a2 2 0 0 1-2.828 0L9 12.414l-5.293 5.293a1 1 0 0 1-1.414-1.414L7.586 11a2 2 0 0 1 2.828 0L13 13.586 18.586 8H16a1 1 0 0 1-1-1Z', +}) diff --git a/src/components/interstitials/Trending.tsx b/src/components/interstitials/Trending.tsx index 7412c6f0ac..56c756c50b 100644 --- a/src/components/interstitials/Trending.tsx +++ b/src/components/interstitials/Trending.tsx @@ -15,7 +15,7 @@ import {BlockDrawerGesture} from '#/view/shell/BlockDrawerGesture' import {atoms as a, useGutters, useTheme} from '#/alf' import {Button, ButtonIcon} from '#/components/Button' import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times' -import {Trending2_Stroke2_Corner2_Rounded as Graph} from '#/components/icons/Trending2' +import {Trending2_Stroke2_Corner2_Rounded as Graph} from '#/components/icons/Trending' import * as Prompt from '#/components/Prompt' import {TrendingTopicLink} from '#/components/TrendingTopics' import {Text} from '#/components/Typography' diff --git a/src/components/interstitials/TrendingVideos.tsx b/src/components/interstitials/TrendingVideos.tsx index 126d6f4174..fab738b9cb 100644 --- a/src/components/interstitials/TrendingVideos.tsx +++ b/src/components/interstitials/TrendingVideos.tsx @@ -16,7 +16,7 @@ import {atoms as a, useGutters, useTheme} from '#/alf' import {Button, ButtonIcon} from '#/components/Button' import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times' -import {Trending2_Stroke2_Corner2_Rounded as Graph} from '#/components/icons/Trending2' +import {Trending2_Stroke2_Corner2_Rounded as Graph} from '#/components/icons/Trending' import {Link} from '#/components/Link' import * as Prompt from '#/components/Prompt' import {Text} from '#/components/Typography' diff --git a/src/screens/Onboarding/StepFinished.tsx b/src/screens/Onboarding/StepFinished.tsx index d0b0caccaa..e725b7b80a 100644 --- a/src/screens/Onboarding/StepFinished.tsx +++ b/src/screens/Onboarding/StepFinished.tsx @@ -1,12 +1,12 @@ import React from 'react' import {View} from 'react-native' import { - AppBskyActorProfile, - AppBskyGraphDefs, + type AppBskyActorProfile, + type AppBskyGraphDefs, AppBskyGraphStarterpack, - Un$Typed, + type Un$Typed, } from '@atproto/api' -import {SavedFeed} from '@atproto/api/dist/client/types/app/bsky/actor/defs' +import {type SavedFeed} from '@atproto/api/dist/client/types/app/bsky/actor/defs' import {TID} from '@atproto/common-web' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' @@ -46,7 +46,7 @@ import {IconCircle} from '#/components/IconCircle' import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check' import {Growth_Stroke2_Corner0_Rounded as Growth} from '#/components/icons/Growth' import {News2_Stroke2_Corner0_Rounded as News} from '#/components/icons/News2' -import {Trending2_Stroke2_Corner2_Rounded as Trending} from '#/components/icons/Trending2' +import {Trending2_Stroke2_Corner2_Rounded as Trending} from '#/components/icons/Trending' import {Loader} from '#/components/Loader' import {Text} from '#/components/Typography' import * as bsky from '#/types/bsky' diff --git a/src/screens/Search/modules/ExploreTrendingTopics.tsx b/src/screens/Search/modules/ExploreTrendingTopics.tsx index 5e268adbbf..a085ff88a9 100644 --- a/src/screens/Search/modules/ExploreTrendingTopics.tsx +++ b/src/screens/Search/modules/ExploreTrendingTopics.tsx @@ -1,32 +1,24 @@ -import React from 'react' -import {View} from 'react-native' +import {Pressable, View} from 'react-native' +import {type AppBskyUnspeccedDefs} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {logger} from '#/logger' -import {isWeb} from '#/platform/detection' -import { - useTrendingSettings, - useTrendingSettingsApi, -} from '#/state/preferences/trending' -import { - DEFAULT_LIMIT as TRENDING_TOPICS_COUNT, - useTrendingTopics, -} from '#/state/queries/trending/useTrendingTopics' +import {useTrendingSettings} from '#/state/preferences/trending' +import {useGetTrendsQuery} from '#/state/queries/trending/useGetTrendsQuery' import {useTrendingConfig} from '#/state/trending-config' -import {atoms as a, tokens, useGutters, useTheme} from '#/alf' -import {Button, ButtonIcon} from '#/components/Button' -import {GradientFill} from '#/components/GradientFill' -import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times' -import {Trending2_Stroke2_Corner2_Rounded as Trending} from '#/components/icons/Trending2' -import * as Prompt from '#/components/Prompt' -import { - TrendingTopic, - TrendingTopicLink, - TrendingTopicSkeleton, -} from '#/components/TrendingTopics' +import {LoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder' +import {formatCount} from '#/view/com/util/numeric/format' +import {atoms as a, useGutters, useTheme, type ViewStyleProp, web} from '#/alf' +import {AvatarStack} from '#/components/AvatarStack' +import {type Props as SVGIconProps} from '#/components/icons/common' +import {Flame_Stroke2_Corner1_Rounded as FlameIcon} from '#/components/icons/Flame' +import {Trending3_Stroke2_Corner1_Rounded as TrendingIcon} from '#/components/icons/Trending' +import {Link} from '#/components/Link' import {Text} from '#/components/Typography' +const TOPIC_COUNT = 5 + export function ExploreTrendingTopics() { const {enabled} = useTrendingConfig() const {trendingDisabled} = useTrendingSettings() @@ -34,117 +26,247 @@ export function ExploreTrendingTopics() { } function Inner() { - const t = useTheme() - const {_} = useLingui() - const gutters = useGutters([0, 'compact']) - const {data: trending, error, isLoading} = useTrendingTopics() - const noTopics = !isLoading && !error && !trending?.topics?.length - const {setTrendingDisabled} = useTrendingSettingsApi() - const trendingPrompt = Prompt.usePromptControl() + const {data: trending, error, isLoading} = useGetTrendsQuery() + const noTopics = !isLoading && !error && !trending?.trends?.length - const onConfirmHide = React.useCallback(() => { - logger.metric( - 'trendingTopics:hide', - {context: 'explore:trending'}, - {statsig: true}, - ) - setTrendingDisabled(true) - }, [setTrendingDisabled]) - - return error || noTopics ? null : ( + return isLoading ? ( + Array.from({length: TOPIC_COUNT}).map((__, i) => ( + + )) + ) : error || !trending?.trends || noTopics ? null : ( <> - - - - - - Trending - - - - - BETA - - - - - What people are posting about. - - - - - - - - {isLoading ? ( - Array(TRENDING_TOPICS_COUNT) - .fill(0) - .map((__, i) => ) - ) : !trending?.topics ? null : ( - <> - {trending.topics.map(topic => ( - { - logger.metric( - 'trendingTopic:click', - {context: 'explore'}, - {statsig: true}, - ) - }}> - {({hovered}) => ( - - )} - - ))} - - )} - - - - + {trending.trends.map((trend, index) => ( + { + logger.metric('trendingTopic:click', {context: 'explore'}) + }} + /> + ))} ) } + +export function TrendRow({ + trend, + rank, + children, + onPress, +}: ViewStyleProp & { + trend: AppBskyUnspeccedDefs.TrendView + rank: number + children?: React.ReactNode + onPress?: () => void +}) { + const t = useTheme() + const {_, i18n} = useLingui() + const gutters = useGutters([0, 'base']) + + const category = useCategoryDisplayName(trend?.category || 'other') + const age = Math.floor( + (Date.now() - new Date(trend.startedAt || Date.now()).getTime()) / + (1000 * 60 * 60), + ) + const badgeType = trend.status === 'hot' ? 'hot' : age < 2 ? 'new' : age + const postCount = trend.postCount + ? _(msg`${formatCount(i18n, trend.postCount)} posts`) + : null + + return ( + + {({hovered, pressed}) => ( + <> + + + + + + {rank}. + + + + {trend.displayName} + + + + {trend.actors.length > 0 && ( + + )} + + {postCount} + {postCount && category && <> · } + {category} + + + + + + + + + {children} + + )} + + ) +} + +type TrendingIndicatorType = 'hot' | 'new' | number + +function TrendingIndicator({type}: {type: TrendingIndicatorType | 'skeleton'}) { + const t = useTheme() + const {_} = useLingui() + const pillStyles = [ + a.flex_row, + a.align_center, + a.gap_xs, + a.rounded_full, + a.px_sm, + { + height: 28, + }, + ] + + let Icon: React.ComponentType | null = null + let text: string | null = null + let color: string | null = null + let backgroundColor: string | null = null + + switch (type) { + case 'skeleton': { + return ( + + ) + } + case 'hot': { + Icon = FlameIcon + color = + t.scheme === 'light' ? t.palette.negative_500 : t.palette.negative_950 + backgroundColor = + t.scheme === 'light' ? t.palette.negative_50 : t.palette.negative_200 + text = _(msg`Hot`) + break + } + case 'new': { + Icon = TrendingIcon + text = _(msg`New`) + color = t.palette.positive_700 + backgroundColor = t.palette.positive_50 + break + } + default: { + text = _( + msg({ + message: `${type}h ago`, + comment: + 'trending topic time spent trending. should be as short as possible to fit in a pill', + }), + ) + color = t.atoms.text_contrast_medium.color + backgroundColor = t.atoms.bg_contrast_25.backgroundColor + break + } + } + + return ( + + {Icon && } + {text} + + ) +} + +function useCategoryDisplayName( + category: AppBskyUnspeccedDefs.TrendView['category'], +) { + const {_} = useLingui() + + switch (category) { + case 'sports': + return _(msg`Sports`) + case 'politics': + return _(msg`Politics`) + case 'video-games': + return _(msg`Video Games`) + case 'pop-culture': + return _(msg`Entertainment`) + case 'other': + default: + return null + } +} + +export function TrendingTopicRowSkeleton({}: {withPosts: boolean}) { + const t = useTheme() + const gutters = useGutters([0, 'base']) + + return ( + + + + + + + + + + + + + + + + + + + ) +} diff --git a/src/screens/Settings/ContentAndMediaSettings.tsx b/src/screens/Settings/ContentAndMediaSettings.tsx index e28c98803c..57b86fb2bf 100644 --- a/src/screens/Settings/ContentAndMediaSettings.tsx +++ b/src/screens/Settings/ContentAndMediaSettings.tsx @@ -1,8 +1,8 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {NativeStackScreenProps} from '@react-navigation/native-stack' +import {type NativeStackScreenProps} from '@react-navigation/native-stack' -import {CommonNavigatorParams} from '#/lib/routes/types' +import {type CommonNavigatorParams} from '#/lib/routes/types' import {logEvent} from '#/lib/statsig/statsig' import {isNative} from '#/platform/detection' import {useAutoplayDisabled, useSetAutoplayDisabled} from '#/state/preferences' @@ -22,7 +22,7 @@ import {Hashtag_Stroke2_Corner0_Rounded as HashtagIcon} from '#/components/icons import {Home_Stroke2_Corner2_Rounded as HomeIcon} from '#/components/icons/Home' import {Macintosh_Stroke2_Corner2_Rounded as MacintoshIcon} from '#/components/icons/Macintosh' import {Play_Stroke2_Corner2_Rounded as PlayIcon} from '#/components/icons/Play' -import {Trending2_Stroke2_Corner2_Rounded as Graph} from '#/components/icons/Trending2' +import {Trending2_Stroke2_Corner2_Rounded as Graph} from '#/components/icons/Trending' import {Window_Stroke2_Corner2_Rounded as WindowIcon} from '#/components/icons/Window' import * as Layout from '#/components/Layout' diff --git a/src/state/queries/trending/useGetTrendsQuery.ts b/src/state/queries/trending/useGetTrendsQuery.ts new file mode 100644 index 0000000000..d34b026f92 --- /dev/null +++ b/src/state/queries/trending/useGetTrendsQuery.ts @@ -0,0 +1,59 @@ +import React from 'react' +import {type AppBskyUnspeccedGetTrends} from '@atproto/api' +import {hasMutedWord} from '@atproto/api/dist/moderation/mutewords' +import {useQuery} from '@tanstack/react-query' + +import { + aggregateUserInterests, + createBskyTopicsHeader, +} from '#/lib/api/feed/utils' +import {getContentLanguages} from '#/state/preferences/languages' +import {STALE} from '#/state/queries' +import {usePreferencesQuery} from '#/state/queries/preferences' +import {useAgent} from '#/state/session' + +export const DEFAULT_LIMIT = 5 + +export const createGetTrendsQueryKey = () => ['trending-topics'] + +export function useGetTrendsQuery() { + const agent = useAgent() + const {data: preferences} = usePreferencesQuery() + const mutedWords = React.useMemo(() => { + return preferences?.moderationPrefs?.mutedWords || [] + }, [preferences?.moderationPrefs]) + + return useQuery({ + refetchOnWindowFocus: true, + staleTime: STALE.MINUTES.THREE, + queryKey: createGetTrendsQueryKey(), + queryFn: async () => { + const contentLangs = getContentLanguages().join(',') + const {data} = await agent.app.bsky.unspecced.getTrends( + { + limit: DEFAULT_LIMIT, + }, + { + headers: { + ...createBskyTopicsHeader(aggregateUserInterests(preferences)), + 'Accept-Language': contentLangs, + }, + }, + ) + return data + }, + select: React.useCallback( + (data: AppBskyUnspeccedGetTrends.OutputSchema) => { + return { + trends: (data.trends ?? []).filter(t => { + return !hasMutedWord({ + mutedWords, + text: t.topic + ' ' + t.displayName + ' ' + t.category, + }) + }), + } + }, + [mutedWords], + ), + }) +} diff --git a/src/view/com/util/numeric/format.ts b/src/view/com/util/numeric/format.ts index 8f3ebd0e71..f05f285401 100644 --- a/src/view/com/util/numeric/format.ts +++ b/src/view/com/util/numeric/format.ts @@ -1,4 +1,4 @@ -import {I18n} from '@lingui/core' +import {type I18n} from '@lingui/core' export const formatCount = (i18n: I18n, num: number) => { return i18n.number(num, { diff --git a/src/view/shell/desktop/SidebarTrendingTopics.tsx b/src/view/shell/desktop/SidebarTrendingTopics.tsx index a7b9a8391e..db94923495 100644 --- a/src/view/shell/desktop/SidebarTrendingTopics.tsx +++ b/src/view/shell/desktop/SidebarTrendingTopics.tsx @@ -14,7 +14,7 @@ import {atoms as a, useTheme} from '#/alf' import {Button, ButtonIcon} from '#/components/Button' import {Divider} from '#/components/Divider' import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times' -import {Trending2_Stroke2_Corner2_Rounded as Graph} from '#/components/icons/Trending2' +import {Trending2_Stroke2_Corner2_Rounded as Graph} from '#/components/icons/Trending' import * as Prompt from '#/components/Prompt' import { TrendingTopic, diff --git a/yarn.lock b/yarn.lock index 7572c2fd26..406a91180b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -80,10 +80,10 @@ tlds "^1.234.0" zod "^3.23.8" -"@atproto/api@^0.14.16": - version "0.14.16" - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.14.16.tgz#7b59eb83a27e906e0dc442d3de0f0d3869092b4a" - integrity sha512-xzUK3KVdp1TDJJ09Di2rvS/fisVctvMHO7Er0XhYviL3V4lxGQPNT3pHwbTbbb22QP7xH/d5ghCgfdIoS5Z8/A== +"@atproto/api@^0.14.18": + version "0.14.18" + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.14.18.tgz#21cb1c33e3467154a81d2dff51135500785e6ec1" + integrity sha512-BEkM7p51oYslDN9lUNeMtVAQqYWUhinJnFsCdTuSLLCb28LNDErbmt6wiA3mCw68E5E/Sh8DC1+L9UPfCi0Awg== dependencies: "@atproto/common-web" "^0.4.0" "@atproto/lexicon" "^0.4.9" @@ -3370,7 +3370,7 @@ "@babel/parser" "^7.26.9" "@babel/types" "^7.26.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" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84" integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw== @@ -3431,19 +3431,6 @@ debug "^4.3.1" 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/traverse@^7.26.10": version "7.26.10" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.26.10.tgz#43cca33d76005dbaa93024fae536cc1946a4c380" @@ -18460,16 +18447,7 @@ string-natural-compare@^3.0.1: resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== -"string-width-cjs@npm:string-width@^4.2.0": - 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: +"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== @@ -18601,7 +18579,7 @@ string_decoder@~1.1.1: dependencies: 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" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -18615,13 +18593,6 @@ strip-ansi@^5.2.0: dependencies: 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: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -20054,7 +20025,7 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" 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" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -20072,15 +20043,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.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: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"