diff --git a/apps/mobile/app/file-viewer.tsx b/apps/mobile/app/[site_id]/chat/[id]/file-viewer.tsx
similarity index 58%
rename from apps/mobile/app/file-viewer.tsx
rename to apps/mobile/app/[site_id]/chat/[id]/file-viewer.tsx
index 9f055f6d..44fde45d 100644
--- a/apps/mobile/app/file-viewer.tsx
+++ b/apps/mobile/app/[site_id]/chat/[id]/file-viewer.tsx
@@ -1,32 +1,48 @@
import ShareButton from "@components/common/ShareButton"
import VideoPlayer from "@components/features/video/VideoPlayer"
import useFileURL from "@hooks/useFileURL"
-import { getFileExtension, isVideoFile } from "@raven/lib/utils/operations"
+import { getFileExtension, isImageFile, isVideoFile } from "@raven/lib/utils/operations"
import { Stack, useLocalSearchParams } from "expo-router"
+import { useState } from "react"
import WebView from "react-native-webview"
import { WebViewSourceUri } from "react-native-webview/lib/WebViewTypes"
+import ImageViewer from "@components/features/image/ImageViewer"
const FileViewer = () => {
const { uri } = useLocalSearchParams() as { uri: string }
+ const [showHeader, setShowHeader] = useState(true)
+
const fileExtension = getFileExtension(uri)
const isVideo = isVideoFile(fileExtension)
+ const isImage = isImageFile(fileExtension)
+
+ const handleShowHeader = () => {
+ setShowHeader((prev) => !prev)
+ }
+
+ const renderFile = () => {
+ if (isVideo) {
+ return
+ }
+ else if (isImage) {
+ return
+ }
+ return
+ }
return (
<>
}} />
- {isVideo ?
-
- :
-
- }
+ {renderFile()}
>
)
}
@@ -42,4 +58,5 @@ const FileView = ({ uri }: { uri: string }) => {
)
}
+
export default FileViewer
\ No newline at end of file
diff --git a/apps/mobile/components/common/ErrorBanner.tsx b/apps/mobile/components/common/ErrorBanner.tsx
new file mode 100644
index 00000000..b928a89c
--- /dev/null
+++ b/apps/mobile/components/common/ErrorBanner.tsx
@@ -0,0 +1,38 @@
+import { View, Text } from 'react-native';
+
+interface BaseProps {
+ heading?: string
+}
+
+type ErrorBannerProps =
+ | (BaseProps & { message: string; error?: never })
+ | (BaseProps & { error: Error; message?: never })
+
+const ErrorBanner = ({ heading, message, error }: ErrorBannerProps) => {
+ return (
+
+
+
+ {(heading || error) && (heading ?
+
+ {heading}
+ :
+
+ {error?.name}
+
+ )}
+ {(message || error) && (message ?
+
+ {message}
+ :
+
+ {error?.message}
+
+ )}
+
+
+
+ )
+}
+
+export default ErrorBanner
diff --git a/apps/mobile/components/features/image/ImageViewer.tsx b/apps/mobile/components/features/image/ImageViewer.tsx
new file mode 100644
index 00000000..256a8611
--- /dev/null
+++ b/apps/mobile/components/features/image/ImageViewer.tsx
@@ -0,0 +1,48 @@
+import ErrorBanner from "@components/common/ErrorBanner";
+import useFileURL from "@hooks/useFileURL";
+import { useWindowDimensions, Image, View } from "react-native";
+import { fitContainer, ResumableZoom, Source, useImageResolution } from "react-native-zoom-toolkit";
+
+interface ImageViewerProps {
+ uri: string
+ handleShowHeader: VoidFunction
+}
+
+const ImageViewer = ({ uri, handleShowHeader }: ImageViewerProps) => {
+ console.log('ImageViewer', uri)
+ const source = useFileURL(uri)
+ if (!source) {
+ return
+
+
+ }
+ return (
+
+ )
+}
+
+export default ImageViewer
+
+const ImageComponent = ({ source, handleShowHeader }: { source: Source, handleShowHeader: VoidFunction }) => {
+
+ const { width, height } = useWindowDimensions()
+ const { isFetching, resolution, error } = useImageResolution(source)
+ if (isFetching || resolution === undefined || error) {
+ console.log('isFetching', isFetching)
+ console.log('resolution', resolution)
+ return
+ {error && }
+
+ }
+
+ const size = fitContainer(resolution.width / resolution.height, {
+ width,
+ height,
+ })
+
+ return (
+
+
+
+ )
+}
diff --git a/apps/mobile/global.css b/apps/mobile/global.css
index c5deaa2e..c120c7fe 100644
--- a/apps/mobile/global.css
+++ b/apps/mobile/global.css
@@ -20,6 +20,10 @@
--accent-foreground: 255 255 255;
--destructive: 255 56 43;
--destructive-foreground: 255 255 255;
+ --error: 206 32 33;
+ --error-background: 251 234 233;
+ --error-heading: 176 20 20;
+ --error-border: 182 22 22;
--border: 230 230 235;
--input: 210 210 215;
--ring: 230 230 235;
@@ -40,6 +44,10 @@
--android-accent-foreground: 255 255 255;
--android-destructive: 186 26 26;
--android-destructive-foreground: 255 255 255;
+ --android-error: 206 32 33;
+ --android-error-background: 251 234 233;
+ --android-error-heading: 176 20 20;
+ --android-error-border: 182 22 22;
--android-border: 215 217 228;
--android-input: 210 210 215;
--android-ring: 215 217 228;
@@ -63,6 +71,10 @@
--accent-foreground: 255 255 255;
--destructive: 254 67 54;
--destructive-foreground: 255 255 255;
+ --error: 176 20 20;
+ --error-background: 39 19 20;
+ --error-heading: 220 50 50;
+ --error-border: 145 22 22;
--border: 40 40 42;
--input: 55 55 57;
--ring: 40 40 42;
@@ -83,6 +95,10 @@
--android-accent-foreground: 238 177 255;
--android-destructive: 147 0 10;
--android-destructive-foreground: 255 255 255;
+ --android-error: 176 20 20;
+ --android-error-background: 39 19 20;
+ --android-error-heading: 220 50 50;
+ --android-error-border: 145 22 22;
--android-border: 39 42 50;
--android-input: 55 55 57;
--android-ring: 39 42 50;
diff --git a/apps/mobile/hooks/useFileURL.ts b/apps/mobile/hooks/useFileURL.ts
index 178521fe..2efb54d0 100644
--- a/apps/mobile/hooks/useFileURL.ts
+++ b/apps/mobile/hooks/useFileURL.ts
@@ -8,7 +8,7 @@ type UseFileURLReturnType = {
* resource (which should be wrapped in the `require('./path/to/image.png')`
* function).
*/
- uri: string | undefined;
+ uri: string;
/**
* `headers` is an object representing the HTTP headers to send along with the
* request for a remote image.
diff --git a/apps/mobile/package.json b/apps/mobile/package.json
index 64b097bb..70962d18 100644
--- a/apps/mobile/package.json
+++ b/apps/mobile/package.json
@@ -47,11 +47,12 @@
"react": "18.3.1",
"react-dom": "18.3.1",
"react-native": "0.76.5",
- "react-native-gesture-handler": "~2.20.2",
+ "react-native-gesture-handler": "^2.21.2",
+ "react-native-image-viewing": "^0.2.2",
"react-native-ios-context-menu": "^2.5.3",
"react-native-ios-utilities": "^4.5.1",
"react-native-keyboard-controller": "^1.15.0",
- "react-native-reanimated": "~3.16.1",
+ "react-native-reanimated": "^3.16.6",
"react-native-safe-area-context": "^4.14.1",
"react-native-screens": "~4.1.0",
"react-native-svg": "^15.10.1",
@@ -59,6 +60,7 @@
"react-native-uitextview": "^1.4.0",
"react-native-web": "~0.19.13",
"react-native-webview": "^13.12.5",
+ "react-native-zoom-toolkit": "^4.0.0",
"sonner-native": "^0.16.2",
"tailwind-merge": "^2.5.5"
},
diff --git a/apps/mobile/tailwind.config.js b/apps/mobile/tailwind.config.js
index b7607236..7622441e 100644
--- a/apps/mobile/tailwind.config.js
+++ b/apps/mobile/tailwind.config.js
@@ -24,6 +24,12 @@ module.exports = {
DEFAULT: withOpacity('destructive'),
foreground: withOpacity('destructive-foreground'),
},
+ error: {
+ DEFAULT: withOpacity('error'),
+ background: withOpacity('error-background'),
+ heading: withOpacity('error-heading'),
+ border: withOpacity('error-border'),
+ },
muted: {
DEFAULT: withOpacity('muted'),
foreground: withOpacity('muted-foreground'),
diff --git a/yarn.lock b/yarn.lock
index 741bc5f0..94918c90 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1100,20 +1100,7 @@
"@babel/parser" "^7.25.9"
"@babel/types" "^7.25.9"
-"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3":
- version "7.26.4"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.26.4.tgz#ac3a2a84b908dde6d463c3bfa2c5fdc1653574bd"
- integrity sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==
- dependencies:
- "@babel/code-frame" "^7.26.2"
- "@babel/generator" "^7.26.3"
- "@babel/parser" "^7.26.3"
- "@babel/template" "^7.25.9"
- "@babel/types" "^7.26.3"
- debug "^4.3.1"
- globals "^11.1.0"
-
-"@babel/traverse@^7.23.0", "@babel/traverse@^7.25.3", "@babel/traverse@^7.25.9":
+"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3", "@babel/traverse@^7.23.0", "@babel/traverse@^7.25.3", "@babel/traverse@^7.25.9":
version "7.26.4"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.26.4.tgz#ac3a2a84b908dde6d463c3bfa2c5fdc1653574bd"
integrity sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==
@@ -4839,7 +4826,7 @@ ci-info@^3.2.0, ci-info@^3.3.0:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4"
integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==
-class-variance-authority@^0.7.1:
+class-variance-authority@^0.7.1, "cva@npm:class-variance-authority":
version "0.7.1"
resolved "https://registry.yarnpkg.com/class-variance-authority/-/class-variance-authority-0.7.1.tgz#4008a798a0e4553a781a57ac5177c9fb5d043787"
integrity sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==
@@ -5202,13 +5189,6 @@ csstype@^3.0.2:
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
-"cva@npm:class-variance-authority":
- version "0.7.1"
- resolved "https://registry.yarnpkg.com/class-variance-authority/-/class-variance-authority-0.7.1.tgz#4008a798a0e4553a781a57ac5177c9fb5d043787"
- integrity sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==
- dependencies:
- clsx "^2.1.1"
-
data-uri-to-buffer@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636"
@@ -5896,6 +5876,11 @@ expo-secure-store@~14.0.0:
resolved "https://registry.yarnpkg.com/expo-secure-store/-/expo-secure-store-14.0.0.tgz#cf6eb7f73e619f8907d5a073e2f438927b5fc2ab"
integrity sha512-VyhtRFXP+7hQmHhKlHIOWid1Q/IRpM7Uif32tZHLZHvQ6FNz2cUkr26XWGvCa7btYbrR6OL++FBFZYjbIcRZTw==
+expo-sharing@^13.0.0:
+ version "13.0.0"
+ resolved "https://registry.yarnpkg.com/expo-sharing/-/expo-sharing-13.0.0.tgz#fbc46f4afdaa265a2811fe88c2a589aae2d2de0f"
+ integrity sha512-b23ymicRmYn/Pjj05sl9tFZHN5cH9I1f0yiqY1Yk8Q3oCx0Aznri82DnTYA4T/J6D9vrkraX0wQ4jWVMOffmlg==
+
expo-status-bar@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/expo-status-bar/-/expo-status-bar-2.0.0.tgz#dd99adc2ace12a24c92718cd0f97b93347103393"
@@ -5909,6 +5894,11 @@ expo-system-ui@~4.0.6:
"@react-native/normalize-colors" "0.76.5"
debug "^4.3.2"
+expo-video@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/expo-video/-/expo-video-2.0.3.tgz#22ef37f6323b20fb2d2f7e7a4684977bbe98baab"
+ integrity sha512-cBY6fBVj+jUXrKw7Xfn4/QwpXKMKPdv/4LCnFHy/SjR+suG4jIHMsCM2eZgqxXF1cbA8CII5LmK6LwmKB7DjMw==
+
expo-web-browser@^14.0.1, expo-web-browser@~14.0.0:
version "14.0.1"
resolved "https://registry.yarnpkg.com/expo-web-browser/-/expo-web-browser-14.0.1.tgz#97f3f141b0897364bc8364d90d6e29df0beec8aa"
@@ -6697,7 +6687,7 @@ internal-slot@^1.1.0:
hasown "^2.0.2"
side-channel "^1.1.0"
-invariant@^2.2.4:
+invariant@2.2.4, invariant@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
@@ -8932,10 +8922,10 @@ react-native-drawer-layout@^4.1.1:
dependencies:
use-latest-callback "^0.2.1"
-react-native-gesture-handler@~2.20.2:
- version "2.20.2"
- resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.20.2.tgz#73844c8e9c417459c2f2981bc4d8f66ba8a5ee66"
- integrity sha512-HqzFpFczV4qCnwKlvSAvpzEXisL+Z9fsR08YV5LfJDkzuArMhBu2sOoSPUF/K62PCoAb+ObGlTC83TKHfUd0vg==
+react-native-gesture-handler@^2.21.2:
+ version "2.21.2"
+ resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.21.2.tgz#824a098d7397212fbe51aa3a9df84833a4ea1c3f"
+ integrity sha512-HcwB225K9aeZ8e/B8nFzEh+2T4EPWTeamO1l/y3PcQ9cyCDYO2zja/G31ITpYRIqkip7XzGs6wI/gnHOQn1LDQ==
dependencies:
"@egjs/hammerjs" "^2.0.17"
hoist-non-react-statics "^3.3.0"
@@ -8951,6 +8941,11 @@ react-native-helmet-async@2.0.4:
react-fast-compare "^3.2.2"
shallowequal "^1.1.0"
+react-native-image-viewing@^0.2.2:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/react-native-image-viewing/-/react-native-image-viewing-0.2.2.tgz#fb26e57d7d3d9ce4559a3af3d244387c0367242b"
+ integrity sha512-osWieG+p/d2NPbAyonOMubttajtYEYiRGQaJA54slFxZ69j1V4/dCmcrVQry47ktVKy8/qpFwCpW1eT6MH5T2Q==
+
react-native-ios-context-menu@^2.5.3:
version "2.5.3"
resolved "https://registry.yarnpkg.com/react-native-ios-context-menu/-/react-native-ios-context-menu-2.5.3.tgz#3e65a6cee50e95a71766ad3ebc3920015eb02318"
@@ -8975,10 +8970,10 @@ react-native-keyboard-controller@^1.15.0:
dependencies:
react-native-is-edge-to-edge "^1.1.6"
-react-native-reanimated@~3.16.1:
- version "3.16.5"
- resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-3.16.5.tgz#2a411b9030a8659722a9398d2e0ea19bc076c846"
- integrity sha512-mq/5k14pimkhCeP9XwFJkEr8XufaHqIekum8fqpsn0fcBzbLvyiqfM2LEuBvi0+DTv5Bd2dHmUHkYqGYfkj3Jw==
+react-native-reanimated@^3.16.6:
+ version "3.16.6"
+ resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-3.16.6.tgz#fa1eda23b740c893e81a024712346c79f1bbdf36"
+ integrity sha512-jPbAfLF5t8+UCKFTO+LeOY+OmAcDP5SsAfqINvNQz5GFGvoO7UebxujjtY58CmpZNH6c3SQ514FF9//mZDpo/g==
dependencies:
"@babel/plugin-transform-arrow-functions" "^7.0.0-0"
"@babel/plugin-transform-class-properties" "^7.0.0-0"
@@ -9043,6 +9038,19 @@ react-native-web@~0.19.13:
postcss-value-parser "^4.2.0"
styleq "^0.1.3"
+react-native-webview@^13.12.5:
+ version "13.12.5"
+ resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-13.12.5.tgz#ed9eec1eda234d7cf18d329859b9bdebf7e258b6"
+ integrity sha512-INOKPom4dFyzkbxbkuQNfeRG9/iYnyRDzrDkJeyvSWgJAW2IDdJkWFJBS2v0RxIL4gqLgHkiIZDOfiLaNnw83Q==
+ dependencies:
+ escape-string-regexp "^4.0.0"
+ invariant "2.2.4"
+
+react-native-zoom-toolkit@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/react-native-zoom-toolkit/-/react-native-zoom-toolkit-4.0.0.tgz#f609b282123bb88f08c5d7a37ba139e568f9fd97"
+ integrity sha512-xn1p4CCiAqae8ZV8AjxfQa9fxct/GYq3iLSq6SkvamiBSxXX/ZcP8EvwPX5ROOhgcoe6R9Pt+7TGMIdK1H1YjA==
+
react-native@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.76.5.tgz#3ce43d3c31f46cfd98e56ef2dfc70866c04ad185"
@@ -9763,6 +9771,11 @@ socket.io-parser@~4.2.4:
"@socket.io/component-emitter" "~3.1.0"
debug "~4.3.1"
+sonner-native@^0.16.2:
+ version "0.16.2"
+ resolved "https://registry.yarnpkg.com/sonner-native/-/sonner-native-0.16.2.tgz#046fd9c750c08f51546bb2b9b53fc940f8c7bc7d"
+ integrity sha512-IxiqcwZ2ZqmbtMWWhFq/um31hQndEUOa9ERnhS7+Z7lc0v9b9boa9pjHtNRoDktJ/OzEOMb1ERyr2bCNYNdUog==
+
sonner@^1.7.0:
version "1.7.1"
resolved "https://registry.yarnpkg.com/sonner/-/sonner-1.7.1.tgz#737110a3e6211d8d766442076f852ddde1725205"
@@ -9876,16 +9889,7 @@ strict-uri-encode@^2.0.0:
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546"
integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==
-"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==
@@ -9970,7 +9974,7 @@ stringify-object@^3.3.0:
is-obj "^1.0.1"
is-regexp "^1.0.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==
@@ -9984,13 +9988,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"
@@ -11020,16 +11017,7 @@ workbox-window@7.3.0, workbox-window@^7.1.0:
"@types/trusted-types" "^2.0.2"
workbox-core "7.3.0"
-"wrap-ansi-cjs@npm: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@^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==