From e3e8c42a8206a689a247ff7631ee5fb185c93248 Mon Sep 17 00:00:00 2001 From: Jack Zhuang <50353452+hotlong@users.noreply.github.com> Date: Mon, 23 Dec 2024 14:26:11 +0800 Subject: [PATCH] @steedos-widgets/liveblocks --- .../@steedos-widgets/liveblocks/package.json | 8 +- .../liveblocks/src/components/Comments.tsx | 103 +------------- .../src/components/InboxPopover.css | 107 ++++++++++++++ .../src/components/InboxPopover.tsx | 131 ++++++++++++++++++ .../liveblocks/src/components/Loading.tsx | 9 ++ .../liveblocks/src/components/Provider.tsx | 92 ++++++++++++ .../liveblocks/src/components/index.tsx | 2 + .../@steedos-widgets/liveblocks/src/meta.ts | 9 +- .../liveblocks/src/metas/Comments.ts | 28 ---- .../liveblocks/src/metas/InboxPopover.ts | 77 ++++++++++ .../liveblocks/src/metas/Provider.ts | 74 ++++++++++ yarn.lock | 54 ++++---- 12 files changed, 530 insertions(+), 164 deletions(-) create mode 100644 packages/@steedos-widgets/liveblocks/src/components/InboxPopover.css create mode 100644 packages/@steedos-widgets/liveblocks/src/components/InboxPopover.tsx create mode 100644 packages/@steedos-widgets/liveblocks/src/components/Loading.tsx create mode 100644 packages/@steedos-widgets/liveblocks/src/components/Provider.tsx create mode 100644 packages/@steedos-widgets/liveblocks/src/metas/InboxPopover.ts create mode 100644 packages/@steedos-widgets/liveblocks/src/metas/Provider.ts diff --git a/packages/@steedos-widgets/liveblocks/package.json b/packages/@steedos-widgets/liveblocks/package.json index b9fe278f9..f73daba29 100644 --- a/packages/@steedos-widgets/liveblocks/package.json +++ b/packages/@steedos-widgets/liveblocks/package.json @@ -48,10 +48,10 @@ "rollup-plugin-visualizer": "^5.8.0" }, "dependencies": { - "@liveblocks/client": "^2.11.0", - "@liveblocks/node": "^2.11.0", - "@liveblocks/react": "^2.11.0", - "@liveblocks/react-ui": "^2.11.0", + "@liveblocks/client": "2.12.0", + "@liveblocks/node": "2.12.0", + "@liveblocks/react": "2.12.0", + "@liveblocks/react-ui": "2.12.0", "@rollup/plugin-replace": "^5.0.2", "@steedos-widgets/amis-lib": "6.3.11", "react-error-boundary": "^4.1.2" diff --git a/packages/@steedos-widgets/liveblocks/src/components/Comments.tsx b/packages/@steedos-widgets/liveblocks/src/components/Comments.tsx index bdf341da1..984a2d7c1 100644 --- a/packages/@steedos-widgets/liveblocks/src/components/Comments.tsx +++ b/packages/@steedos-widgets/liveblocks/src/components/Comments.tsx @@ -6,13 +6,10 @@ import { RoomProvider, useThreads } from "@liveblocks/react/suspense"; import { ErrorBoundary } from "react-error-boundary"; import "@liveblocks/react-ui/styles.css"; // import "@liveblocks/react-ui/styles/dark/media-query.css"; +import { Loading } from "./Loading"; import './Comments.css'; -export const Loading = () => { - return
Loading...
; -} - export const Threads = (props:any) => { const { threads } = useThreads(); @@ -28,109 +25,12 @@ export const Threads = (props:any) => { export const AmisComments = (props: any) => { const { - config: configJSON = {}, - data: amisData, className = "m-2 flex flex-col gap-y-2", roomId, - baseUrl, - dataFilter } = props; - const [config, setConfig] = useState(configJSON); - const [token, setToken] = useState(null); - - const fixedBaseUrl = baseUrl || amisData.context?.rootUrl || `${window.location.protocol}//${window.location.host}` - console.log('liveblocks baseUrl:', fixedBaseUrl); - - let onDataFilter = null; - - if (typeof dataFilter === 'string') { - onDataFilter = new Function('config', 'data', 'return (async () => { ' + dataFilter + ' })()') - } - - useEffect(() => { - let isCancelled = false; - (async () => { - try { - if (onDataFilter) { - const newConfig = await onDataFilter(config, amisData); - if (!isCancelled) { - setConfig(newConfig || config); - } - } - } catch (e) { - console.warn(e); - } - })(); - - return () => { - isCancelled = true; - }; - }, []); return ( - { - const authEndpoint = `${fixedBaseUrl}/v2/c/auth`; - const headers = { - "Content-Type": "application/json", - }; - - const body = JSON.stringify({ - room, - }); - - const response = await fetch(authEndpoint, { - method: "POST", - headers, - body, - credentials: 'include' - }); - const result = await response.json(); - setToken(result.token); - - return result; - }} - // Get users' info from their ID - resolveUsers={async ({ userIds }) => { - const searchParams = new URLSearchParams( - userIds.map((userId) => ["userIds", userId]) - ); - const response = await fetch(`${fixedBaseUrl}/v2/c/users?${searchParams}`, { - headers: { - "Authorization": `Bearer ${token}` - } - }); - - if (!response.ok) { - throw new Error("Problem resolving users"); - } - - const users = await response.json(); - return users; - }} - // publicApiKey={import.meta.env.VITE_LIVEBLOCKS_PUBLIC_KEY} - - // Find a list of users that match the current search term - resolveMentionSuggestions={async ({ text = "" }) => { - const response = await fetch( - `${fixedBaseUrl}/v2/c/users/search?keyword=${encodeURIComponent(text)}`, { - headers: { - "Authorization": `Bearer ${token}` - } - } - ); - - if (!response.ok) { - throw new Error("Problem resolving mention suggestions"); - } - - const userIds = await response.json(); - return userIds; - }} - > { - ); }; diff --git a/packages/@steedos-widgets/liveblocks/src/components/InboxPopover.css b/packages/@steedos-widgets/liveblocks/src/components/InboxPopover.css new file mode 100644 index 000000000..0b3226d7c --- /dev/null +++ b/packages/@steedos-widgets/liveblocks/src/components/InboxPopover.css @@ -0,0 +1,107 @@ + +.inbox { + background: #fff; + width: 460px; + height: 560px; + max-height: calc(100vh - var(--header-height) - 10px); + display: flex; + flex-direction: column; + outline: none; + overflow-y: auto; + border-radius: 0.75rem; + box-shadow: + 0 0 0 1px rgb(0 0 0 / 4%), + 0 2px 6px rgb(0 0 0 / 8%), + 0 8px 26px rgb(0 0 0 / 12%); +} + +.inbox-header { + position: sticky; + top: 0; + z-index: 1; + display: flex; + place-items: center; + justify-content: space-between; + background: #fff; + width: 100%; + padding: 0.5rem 0.5rem 0.5rem 1rem; + box-shadow: + 0 0 0 1px rgb(0 0 0 / 4%), + 0 2px 6px rgb(0 0 0 / 4%), + 0 8px 26px rgb(0 0 0 / 6%); +} + +.inbox-title { + font-weight: 500; +} + +.inbox-buttons { + display: flex; + gap: 6px; +} + +.inbox-list { + box-shadow: 0 0 0 1px rgb(0 0 0 / 8%); +} + +.inbox-unread-count { + position: absolute; + top: 0; + right: 0; + transform: translate(50%, -50%); + display: flex; + place-content: center; + place-items: center; + background: var(--accent); + color: #fff; + font-size: 0.65rem; + font-weight: 500; + height: 1rem; + min-width: 1rem; + padding: 0 0.25rem; + border-radius: 9999px; +} + + +.inbox-content { + display: flex; + min-height: 100vh; + padding: calc(var(--header-height) + 1rem) 1rem 1rem + calc(var(--sidebar-width) + 1rem); + overflow-y: auto; +} + +.inbox-button { + all: unset; + position: relative; + display: flex; + place-items: center; + place-content: center; + padding: 0.5rem 0.75rem; + font-size: 0.875rem; + border-radius: 0.5rem; + background: #f3f3f3; + color: #555; +} + +.inbox-button.square { + padding: 0; + width: 2rem; + height: 2rem; +} + +.inbox-button.destructive { + background: #fde5e5; + color: #953939; +} + +.inbox-button:hover, +.inbox-button:focus-visible { + background: #e8e8e8; + cursor: pointer; +} + +.inbox-button.destructive:hover, +.inbox-button.destructive:focus-visible{ + background: #ffd6d6; +} \ No newline at end of file diff --git a/packages/@steedos-widgets/liveblocks/src/components/InboxPopover.tsx b/packages/@steedos-widgets/liveblocks/src/components/InboxPopover.tsx new file mode 100644 index 000000000..77e3c8bfe --- /dev/null +++ b/packages/@steedos-widgets/liveblocks/src/components/InboxPopover.tsx @@ -0,0 +1,131 @@ +"use client"; +import React from 'react'; +import { InboxNotification, InboxNotificationList } from "@liveblocks/react-ui"; +import * as Popover from "@radix-ui/react-popover"; +import { + useDeleteAllInboxNotifications, + useInboxNotifications, + useMarkAllInboxNotificationsAsRead, + useUnreadInboxNotificationsCount, +} from "@liveblocks/react/suspense"; +import { ClientSideSuspense } from "@liveblocks/react"; +import { Loading } from "./Loading"; +import { ComponentPropsWithoutRef, useEffect, useState } from "react"; +import { ErrorBoundary } from "react-error-boundary"; +import clsx from "clsx"; +// import { Link } from "./Link"; +// import { usePathname } from "next/navigation"; +import './InboxPopover.css'; + + +function Inbox({ className, ...props }: ComponentPropsWithoutRef<"div">) { + const { inboxNotifications } = useInboxNotifications(); + + return inboxNotifications.length === 0 ? ( +
+ There aren’t any notifications yet. +
+ ) : ( +
+ + {inboxNotifications.map((inboxNotification) => { + return ( + + ); + })} + +
+ ); +} + +function InboxPopoverUnreadCount() { + const { count } = useUnreadInboxNotificationsCount(); + + return count ?
{count}
: null; +} + +export function AmisInboxPopover({ + className, + ...props +}: Popover.PopoverContentProps) { + const [isOpen, setOpen] = useState(false); + const markAllInboxNotificationsAsRead = useMarkAllInboxNotificationsAsRead(); + const deleteAllInboxNotifications = useDeleteAllInboxNotifications(); + // const pathname = usePathname(); + + // useEffect(() => { + // setOpen(false); + // }, [pathname]); + + return ( + + + + + + + + + + + + + + +
+ Notifications +
+ + +
+
+ + There was an error while getting notifications. + + } + > + }> + + + +
+
+
+ ); +} diff --git a/packages/@steedos-widgets/liveblocks/src/components/Loading.tsx b/packages/@steedos-widgets/liveblocks/src/components/Loading.tsx new file mode 100644 index 000000000..6136d3f15 --- /dev/null +++ b/packages/@steedos-widgets/liveblocks/src/components/Loading.tsx @@ -0,0 +1,9 @@ +import React from 'react'; + + +export function Loading() { + return ( + + + ); +} diff --git a/packages/@steedos-widgets/liveblocks/src/components/Provider.tsx b/packages/@steedos-widgets/liveblocks/src/components/Provider.tsx new file mode 100644 index 000000000..0eda61d8d --- /dev/null +++ b/packages/@steedos-widgets/liveblocks/src/components/Provider.tsx @@ -0,0 +1,92 @@ +import React, { Suspense, useEffect, useState } from 'react'; + +import { LiveblocksProvider } from "@liveblocks/react"; +import { Composer, Thread } from "@liveblocks/react-ui"; +import { RoomProvider, useThreads } from "@liveblocks/react/suspense"; +import { ErrorBoundary } from "react-error-boundary"; +import "@liveblocks/react-ui/styles.css"; + + +export const AmisRoomsProvider = (props: any) => { + const { + data: amisData, + baseUrl, + children, + body, + render, + } = props; + + const [token, setToken] = useState(null); + + const fixedBaseUrl = baseUrl || amisData.context?.rootUrl || `${window.location.protocol}//${window.location.host}` + console.log('liveblocks baseUrl:', fixedBaseUrl); + + return ( + { + const authEndpoint = `${fixedBaseUrl}/v2/c/auth`; + const headers = { + "Content-Type": "application/json", + }; + + const body = JSON.stringify({ + room, + }); + + const response = await fetch(authEndpoint, { + method: "POST", + headers, + body, + credentials: 'include' + }); + const result = await response.json(); + setToken(result.token); + + return result; + }} + // Get users' info from their ID + resolveUsers={async ({ userIds }) => { + const searchParams = new URLSearchParams( + userIds.map((userId) => ["userIds", userId]) + ); + const response = await fetch(`${fixedBaseUrl}/v2/c/users?${searchParams}`, { + headers: { + "Authorization": `Bearer ${token}` + } + }); + + if (!response.ok) { + throw new Error("Problem resolving users"); + } + + const users = await response.json(); + return users; + }} + // publicApiKey={import.meta.env.VITE_LIVEBLOCKS_PUBLIC_KEY} + + // Find a list of users that match the current search term + resolveMentionSuggestions={async ({ text = "" }) => { + const response = await fetch( + `${fixedBaseUrl}/v2/c/users/search?keyword=${encodeURIComponent(text)}`, { + headers: { + "Authorization": `Bearer ${token}` + } + } + ); + + if (!response.ok) { + throw new Error("Problem resolving mention suggestions"); + } + + const userIds = await response.json(); + return userIds; + }} + > + {body && render('body', body, {})} + + {children} + + ); +}; diff --git a/packages/@steedos-widgets/liveblocks/src/components/index.tsx b/packages/@steedos-widgets/liveblocks/src/components/index.tsx index ff3845b7a..8c354ad67 100644 --- a/packages/@steedos-widgets/liveblocks/src/components/index.tsx +++ b/packages/@steedos-widgets/liveblocks/src/components/index.tsx @@ -1 +1,3 @@ export * from './Comments'; +export * from './InboxPopover'; +export * from './Provider'; \ No newline at end of file diff --git a/packages/@steedos-widgets/liveblocks/src/meta.ts b/packages/@steedos-widgets/liveblocks/src/meta.ts index 6512a45a1..96009746a 100644 --- a/packages/@steedos-widgets/liveblocks/src/meta.ts +++ b/packages/@steedos-widgets/liveblocks/src/meta.ts @@ -6,12 +6,15 @@ * @Description: */ import Comments from "./metas/Comments"; -const components = [Comments]; +import InboxPopover from "./metas/InboxPopover"; +import Provider from "./metas/Provider"; + +const components = [Comments, InboxPopover, Provider]; const componentList = [ { - title: "华炎魔方", + title: "Builder6", icon: "", - children: [Comments] + children: [Comments, InboxPopover, Provider] } ]; export default { diff --git a/packages/@steedos-widgets/liveblocks/src/metas/Comments.ts b/packages/@steedos-widgets/liveblocks/src/metas/Comments.ts index 9c5ebf107..1f6469794 100644 --- a/packages/@steedos-widgets/liveblocks/src/metas/Comments.ts +++ b/packages/@steedos-widgets/liveblocks/src/metas/Comments.ts @@ -62,12 +62,6 @@ export default { }, panelTitle: "设置", panelControls: [ - { - type: "text", - name: "baseUrl", - label: "Base URL", - value: "m-2 flex flex-col gap-y-2" - }, { type: "text", name: "roomId", @@ -80,28 +74,6 @@ export default { label: "CSS类名", value: "m-2 flex flex-col gap-y-2" }, - { - type: "editor", - "language": "json", - name: "config", - label: "配置", - pipeOut: (value) => { - try { - return value ? JSON.parse(value) : null; - } catch (e) { - } - return value; - } - }, - { - type: "editor", - "language": "javascript", - name: "dataFilter", - label: "数据加工", - description: "如果后端没有直接返回配置,可以自己写一段函数来包装。\ - 签名:(config, env, data) => config \ - " - }, ], events: [{ diff --git a/packages/@steedos-widgets/liveblocks/src/metas/InboxPopover.ts b/packages/@steedos-widgets/liveblocks/src/metas/InboxPopover.ts new file mode 100644 index 000000000..8105928b3 --- /dev/null +++ b/packages/@steedos-widgets/liveblocks/src/metas/InboxPopover.ts @@ -0,0 +1,77 @@ + +const config: any = { + group: "华炎魔方-原子组件", + componentName: "AmisInboxPopover", + title: "Inbox Popover", + docUrl: "", + screenshot: "", + npm: { + package: "@steedos-widgets/liveblocks", + version: "{{version}}", + exportName: "AmisInboxPopover", + main: "", + destructuring: true, + subName: "" + }, + props: [ + ], + preview: { + }, + targets: ["steedos__RecordPage", "steedos__AppPage", "steedos__HomePage"], + engines: ["amis"], + // settings for amis. + amis: { + name: 'rooms-inbox-popover', + icon: "fa-fw fa fa-list-alt" + } +}; + +export default { + ...config, + snippets: [ + { + title: config.title, + screenshot: "", + schema: { + componentName: config.componentName, + props: config.preview + } + } + ], + amis: { + render: { + type: config.amis.name, + usage: "renderer",//使用 renderer 会无法监听到onEvent中配置的事件 + weight: 1, + framework: "react" + }, + plugin: { + rendererName: config.amis.name, + $schema: '/schemas/UnkownSchema.json', + name: config.title, + description: config.title, + tags: [config.group], + order: -9999, + icon: config.amis.icon, + scaffold: { + type: config.amis.name, + className: "m-2 flex flex-col gap-y-2", + }, + previewSchema: { + type: config.amis.name, + }, + panelTitle: "设置", + panelControls: [ + { + type: "text", + name: "className", + label: "CSS类名", + value: "m-2 flex flex-col gap-y-2" + }, + ], + events: [{ + + }], + }, + } +}; diff --git a/packages/@steedos-widgets/liveblocks/src/metas/Provider.ts b/packages/@steedos-widgets/liveblocks/src/metas/Provider.ts new file mode 100644 index 000000000..0e95110e3 --- /dev/null +++ b/packages/@steedos-widgets/liveblocks/src/metas/Provider.ts @@ -0,0 +1,74 @@ + +const config: any = { + group: "Builder6", + componentName: "AmisRoomsProvider", + title: "Rooms Provider", + docUrl: "", + screenshot: "", + npm: { + package: "@steedos-widgets/liveblocks", + version: "{{version}}", + exportName: "AmisRoomsProvider", + main: "", + destructuring: true, + subName: "" + }, + props: [ + ], + preview: { + }, + targets: ["steedos__RecordPage", "steedos__AppPage", "steedos__HomePage"], + engines: ["amis"], + // settings for amis. + amis: { + name: 'rooms-provider', + icon: "fa-fw fa fa-list-alt" + } +}; + +export default { + ...config, + snippets: [ + { + title: config.title, + screenshot: "", + schema: { + componentName: config.componentName, + props: config.preview + } + } + ], + amis: { + render: { + type: config.amis.name, + usage: "renderer",//使用 renderer 会无法监听到onEvent中配置的事件 + weight: 1, + framework: "react" + }, + plugin: { + rendererName: config.amis.name, + $schema: '/schemas/UnkownSchema.json', + name: config.title, + description: config.title, + tags: [config.group], + order: -9999, + icon: config.amis.icon, + scaffold: { + type: config.amis.name, + className: "m-2 flex flex-col gap-y-2", + }, + previewSchema: { + type: config.amis.name, + }, + panelTitle: "设置", + panelControls: [ + { + type: "text", + name: "baseUrl", + label: "Base URL", + value: "m-2 flex flex-col gap-y-2" + }, + ], + }, + } +}; diff --git a/yarn.lock b/yarn.lock index 2125ba768..79a0a097e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3298,37 +3298,37 @@ write-pkg "4.0.0" yargs "16.2.0" -"@liveblocks/client@2.13.1", "@liveblocks/client@^2.11.0": - version "2.13.1" - resolved "https://registry.npmjs.org/@liveblocks/client/-/client-2.13.1.tgz#8d61fb2c7e7867d952cfa706279967a13f56da57" - integrity sha512-lID7zLeqHWJxmrFaUGWE23ItG78ox6xAz9lSVQV7vqjJFyDisivE+toJ7OKTViRftqvO4s7HgqMNh7PMmUrFKw== +"@liveblocks/client@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@liveblocks/client/-/client-2.12.0.tgz#d1580b35194430b0dc331f005031682798259875" + integrity sha512-Y2pb9t5hS1kplvS1sTD0q391AM00b3vbRHfFDZhZzElT8u3nGpe+KRB1I1FWGKDoIsSnGk1SSbak01cFSwt2bA== dependencies: - "@liveblocks/core" "2.13.1" + "@liveblocks/core" "2.12.0" -"@liveblocks/core@2.13.1": - version "2.13.1" - resolved "https://registry.npmjs.org/@liveblocks/core/-/core-2.13.1.tgz#2c5e43fd60fa495aa69527fca79ef9c8f66da36a" - integrity sha512-pSb46I/Uvo5NkIR5G4Gc74mPh1xjyok5uyaIO7eFX4E/zBZWWK/XEIgufTlDS9yqlLWW78XdJL2OSI5pK5+7iw== +"@liveblocks/core@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@liveblocks/core/-/core-2.12.0.tgz#2e216cc158f9da6c7860bbac910abe12e33c680a" + integrity sha512-Bsd3dvsj97OruvuYyEWuZmLFihWzv/ghLGgBIBJFCY1AWrbQwkd0tRbkmRXpTtWJd8+902asoHajPYHhpeGWOA== -"@liveblocks/node@^2.11.0": - version "2.13.1" - resolved "https://registry.npmjs.org/@liveblocks/node/-/node-2.13.1.tgz#c056167c8b2446980754e58e65ce7528c5feccb2" - integrity sha512-eEHrJe4mB4qF1Sv0GAQv7+Ec5de1W4SxfF0StpKxLC4T+8ZTJLoEatTrwQVP7cBXiDGAbdcJL7NPRaWPI6Xzzg== +"@liveblocks/node@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@liveblocks/node/-/node-2.12.0.tgz#5dc0624a1a2dd144df50f4a914d90cfae6aa8cc3" + integrity sha512-m2mguyLjyWzCrwLbUd+s1Dox3W/IkG9k5OB7M9SdpWPaeTa53TLj/m5Il/dWNmLBMiPE3RyQ6f+QX66xYDQLTg== dependencies: - "@liveblocks/core" "2.13.1" + "@liveblocks/core" "2.12.0" "@stablelib/base64" "^1.0.1" fast-sha256 "^1.3.0" node-fetch "^2.6.1" -"@liveblocks/react-ui@^2.11.0": - version "2.13.1" - resolved "https://registry.npmjs.org/@liveblocks/react-ui/-/react-ui-2.13.1.tgz#56748939c5975265fd99984294cadea253778b04" - integrity sha512-nOYe8oPhn1srCIxVxccH9RzRjS0EeJQHBY7K6SWK+IaBwbZFdp/GlRmUB3kwy8/HBYHP9c1OqeyLji/+cyRX/g== +"@liveblocks/react-ui@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@liveblocks/react-ui/-/react-ui-2.12.0.tgz#05b7e70b9dba478638ef50bad5e45d661631f72f" + integrity sha512-hljja9ZwF0s/bmdPAbH+MW0xQDPRxR6XkDqXgGw8RwLPrHYYjOXjc5lRL9Q4JyWMy3+OBmhtcZmXxiV1xs0Gow== dependencies: "@floating-ui/react-dom" "^2.1.2" - "@liveblocks/client" "2.13.1" - "@liveblocks/core" "2.13.1" - "@liveblocks/react" "2.13.1" + "@liveblocks/client" "2.12.0" + "@liveblocks/core" "2.12.0" + "@liveblocks/react" "2.12.0" "@radix-ui/react-dropdown-menu" "^2.1.2" "@radix-ui/react-popover" "^1.1.2" "@radix-ui/react-slot" "^1.1.0" @@ -3341,13 +3341,13 @@ slate-react "^0.110.3" use-sync-external-store "^1.2.2" -"@liveblocks/react@2.13.1", "@liveblocks/react@^2.11.0": - version "2.13.1" - resolved "https://registry.npmjs.org/@liveblocks/react/-/react-2.13.1.tgz#ae1c698819ab6445b704873e6e9e85cf239b283a" - integrity sha512-UeJO6Vu5pbxOUiWKx7+OmfmDnXfqV9VJ5hmDiCHryojibM67xOnIwRpY7lvediEUtTU/U2230kXr5QfpaWmX7A== +"@liveblocks/react@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@liveblocks/react/-/react-2.12.0.tgz#04f088d09ab9b0b35aa7453303ea7053a95ba5de" + integrity sha512-ivevtDYbda695WSa2TSwBjDILzY3Ys2cfc3BcfishELb/udb01ujDT6ZUUGzEKFdF5iNxFmfeis7OmmJSjKYCQ== dependencies: - "@liveblocks/client" "2.13.1" - "@liveblocks/core" "2.13.1" + "@liveblocks/client" "2.12.0" + "@liveblocks/core" "2.12.0" use-sync-external-store "^1.2.2" "@mdx-js/mdx@^1.6.22":