Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 7 additions & 21 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
## vNEXT (not yet released)

## v3.18.5

### `@liveblocks/react-tiptap`

- Support overlapping comment marks, they now all appear in the
`AnchoredThreads` and `FloatingThreads` components.

## v3.18.4

### `@liveblocks/emails`
Expand Down Expand Up @@ -3546,13 +3553,11 @@ In **@liveblocks/react**:
https://liveblocks.io/docs/guides/troubleshooting#stale-props-zombie-child

- In **@liveblocks/zustand**:

- Fix a confusing error message

## v0.18.2

- In **@liveblocks/react**:

- Make sure that `useOther` will not rerender if tracked users already left
the room, so that child components won't get rerendered before the parent
got the chance to unmount them.
Expand All @@ -3561,7 +3566,6 @@ In **@liveblocks/react**:
## v0.18.1

- In **@liveblocks/react**:

- Fix a bug that could cause an error when patching presence during local
development. Not an issue in production builds. (#505)

Expand All @@ -3573,7 +3577,6 @@ For information, please read our
### New React hooks ✨

- In **@liveblocks/react**:

- [`useStorage`](https://liveblocks.io/docs/api-reference/liveblocks-react#useStorage)
- [`useMutation`](https://liveblocks.io/docs/api-reference/liveblocks-react#useMutation)
- [`useSelf`](https://liveblocks.io/docs/api-reference/liveblocks-react#useSelf)
Expand All @@ -3584,7 +3587,6 @@ For information, please read our
(singular)

- In **@liveblocks/client**:

- New
[`.toImmutable()`](https://liveblocks.io/docs/api-reference/liveblocks-client#LiveObject.toImmutable)
method on `LiveObject`, `LiveList`, and `LiveMap` lets you work with an
Expand Down Expand Up @@ -3630,19 +3632,16 @@ In **@liveblocks/react**:
### New history APIs ↩️ ↪️

- In **@liveblocks/client**:

- Add `canUndo()` and `canRedo()` utilities to `room.history`
- Add `"history"` event type to `room.subscribe()` to subscribe to the current
user's history changes

- In **@liveblocks/react**:

- Add `useCanUndo()` and `useCanRedo()` hooks

## v0.17.7

- In **@liveblocks/zustand**:

- Simplify zustand middleware integration with Typescript. `TPresence`,
`TStorage`, `TUserMeta`, and `TRoomEvent` are now optional.

Expand Down Expand Up @@ -3724,13 +3723,11 @@ useStore(state => state.liveblocks.others[0].presence?.isTyping)
## v0.17.6

- In **@liveblocks/react**:

- Expose `RoomContext` in the return value of `createRoomContext()`

## v0.17.5

- In **@liveblocks/react**:

- Fix bug where changing the `key` argument of `useMap()`, `useList()`,
`useObject()` did not resubscribe to updates correctly
- Ignore changes to the `RoomProvider`'s initial presence/storage props on
Expand Down Expand Up @@ -3782,12 +3779,10 @@ It's surprisingly simple!
### New APIs ✨

- In **@liveblocks/react**:

- [`createRoomContext()`](https://liveblocks.io/docs/api-reference/liveblocks-react#createRoomContext)
is now the preferred way to initialize hooks.

- In the API:

- New endpoint to
[Get Users in a Room](https://liveblocks.io/docs/api-reference/rest-api-endpoints#GetRoomUsers)
- New endpoint to
Expand All @@ -3801,13 +3796,11 @@ It's surprisingly simple!
### Breaking changes

- In **@liveblocks/client**:

- Removed old `Room.unsubscribe()` API

### New deprecations

- In **@liveblocks/client**:

- The `defaultPresence` option to `client.enter()` will get renamed to
`initialPresence`
- The `defaultStorageRoot` option to `client.enter()` will get renamed to
Expand All @@ -3816,7 +3809,6 @@ It's surprisingly simple!
or `new LiveMap([])`

- In **@liveblocks/react**:

- Importing the React hooks directly is deprecated, instead use the new
`createRoomContext()` helper. For help, read the
[Recommended Upgrade Steps section](https://liveblocks.io/docs/platform/upgrading/0.17#recommended-upgrade-steps)
Expand Down Expand Up @@ -3887,7 +3879,6 @@ Fix bug in example code suggested in deprecation warning.
### Bug fixes

- In **@liveblocks/client**:

- If you're using `@liveblocks/client` in a ES2015 context, you no longer have
to polyfill `Object.fromEntries()`.

Expand All @@ -3905,15 +3896,12 @@ Fix bug in example code suggested in deprecation warning.
### Bug fixes

- In **@liveblocks/client**:

- Fix bug where internal presence state could not get restored correctly after
undo/redo in certain circumstances.

- In **@liveblocks/zustand** and **@liveblocks/redux**:

- Fixes an issue when initializing an array with items would result in having
duplicated items in other clients. Example:

- Client A updates state : `{ list: [0] }`
- Client B states is updated to : `{ list: [0, 0] }`

Expand All @@ -3922,7 +3910,6 @@ Fix bug in example code suggested in deprecation warning.
### Bug fixes

- In **@liveblocks/client**:

- Fix small bug related to new `JsonObject` type, which would reject some
values that were legal JSON objects.

Expand All @@ -3931,7 +3918,6 @@ Fix bug in example code suggested in deprecation warning.
### Bug fixes

- In **@liveblocks/react**:

- Fix issue with React 18 and StrictMode.

## v0.16.0
Expand Down
2 changes: 1 addition & 1 deletion packages/liveblocks-chat-sdk-adapter/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@liveblocks/chat-sdk-adapter",
"version": "3.18.4",
"version": "3.18.5",
"description": "Liveblocks adapter for the Chat SDK.",
"license": "Apache-2.0",
"author": "Liveblocks Inc.",
Expand Down
2 changes: 1 addition & 1 deletion packages/liveblocks-client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@liveblocks/client",
"version": "3.18.4",
"version": "3.18.5",
"description": "A client that lets you interact with Liveblocks servers. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.",
"license": "Apache-2.0",
"author": "Liveblocks Inc.",
Expand Down
2 changes: 1 addition & 1 deletion packages/liveblocks-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@liveblocks/core",
"version": "3.18.4",
"version": "3.18.5",
"description": "Private internals for Liveblocks. DO NOT import directly from this package!",
"type": "module",
"main": "./dist/index.cjs",
Expand Down
2 changes: 1 addition & 1 deletion packages/liveblocks-emails/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@liveblocks/emails",
"version": "3.18.4",
"version": "3.18.5",
"description": "A set of functions and utilities to make sending emails based on Liveblocks notification events easy. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.",
"license": "Apache-2.0",
"author": "Liveblocks Inc.",
Expand Down
2 changes: 1 addition & 1 deletion packages/liveblocks-node-lexical/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@liveblocks/node-lexical",
"version": "3.18.4",
"version": "3.18.5",
"description": "A server-side utility that lets you modify lexical documents hosted in Liveblocks.",
"license": "Apache-2.0",
"author": "Liveblocks Inc.",
Expand Down
2 changes: 1 addition & 1 deletion packages/liveblocks-node-prosemirror/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@liveblocks/node-prosemirror",
"version": "3.18.4",
"version": "3.18.5",
"description": "A server-side utility that lets you modify prosemirror and tiptap documents hosted in Liveblocks.",
"license": "Apache-2.0",
"author": "Liveblocks Inc.",
Expand Down
2 changes: 1 addition & 1 deletion packages/liveblocks-node/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@liveblocks/node",
"version": "3.18.4",
"version": "3.18.5",
"description": "A server-side utility that lets you set up a Liveblocks authentication endpoint. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.",
"license": "Apache-2.0",
"author": "Liveblocks Inc.",
Expand Down
2 changes: 1 addition & 1 deletion packages/liveblocks-react-blocknote/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@liveblocks/react-blocknote",
"version": "3.18.4",
"version": "3.18.5",
"description": "An integration of BlockNote + React to enable collaboration, comments, live cursors, and more with Liveblocks.",
"license": "Apache-2.0",
"author": "Liveblocks Inc.",
Expand Down
2 changes: 1 addition & 1 deletion packages/liveblocks-react-flow/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@liveblocks/react-flow",
"version": "3.18.4",
"version": "3.18.5",
"description": "An integration of React Flow to enable collaboration and realtime cursors with Liveblocks.",
"license": "Apache-2.0",
"author": "Liveblocks Inc.",
Expand Down
2 changes: 1 addition & 1 deletion packages/liveblocks-react-lexical/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@liveblocks/react-lexical",
"version": "3.18.4",
"version": "3.18.5",
"description": "An integration of Lexical + React to enable collaboration, comments, live cursors, and more with Liveblocks.",
"license": "Apache-2.0",
"author": "Liveblocks Inc.",
Expand Down
2 changes: 1 addition & 1 deletion packages/liveblocks-react-tiptap/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@liveblocks/react-tiptap",
"version": "3.18.4",
"version": "3.18.5",
"description": "An integration of TipTap + React to enable collaboration, comments, live cursors, and more with Liveblocks.",
"license": "Apache-2.0",
"author": "Liveblocks Inc.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import {
type CollaborationCaretOptions,
} from "./collaboration-caret/collaboration-caret";
import {
areSetsEqual,
CommentsExtension,
FILTERED_THREADS_PLUGIN_KEY,
} from "./comments/CommentsExtension";
Expand All @@ -40,6 +39,7 @@ import type {
ResolveContextualPromptResponse,
} from "./types";
import { LIVEBLOCKS_COMMENT_MARK_TYPE } from "./types";
import { areSetsEqual } from "./utils";

type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };

Expand Down
3 changes: 2 additions & 1 deletion packages/liveblocks-react-tiptap/src/ai/AiExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ export const AiExtension = Extension.create<
pud: undefined,

// The actual default resolver is set in LiveblocksExtension via AiExtension.configure()
resolveContextualPrompt: () => Promise.reject(new Error("resolveContextualPrompt not configured")),
resolveContextualPrompt: () =>
Promise.reject(new Error("resolveContextualPrompt not configured")),
name: DEFAULT_AI_NAME,
};
},
Expand Down
42 changes: 29 additions & 13 deletions packages/liveblocks-react-tiptap/src/comments/AnchoredThreads.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import type { BaseMetadata, DCM, DTM, ThreadData } from "@liveblocks/core";
import {
type BaseMetadata,
type DCM,
type DTM,
shallow,
type ThreadData,
} from "@liveblocks/core";
import { useLayoutEffect } from "@liveblocks/react/_private";
import {
Thread as DefaultThread,
Expand Down Expand Up @@ -71,14 +77,16 @@ export function AnchoredThreads({
equalityFn: (prev, next) => {
if (!prev || !next) return false;
return (
prev.pluginState?.selectedThreadId ===
next.pluginState?.selectedThreadId &&
prev.pluginState?.threadPositions === next.pluginState?.threadPositions
); // new map is made each time threadPos updates so shallow equality is fine
prev.pluginState?.threadPositions ===
next.pluginState?.threadPositions &&
shallow(
prev.pluginState?.activeThreadIds,
next.pluginState?.activeThreadIds
)
);
},
}) ?? { pluginState: undefined };

// TODO: lexical supoprts multiple threads being active, should probably do that here as well
const handlePositionThreads = useCallback(() => {
const container = containerRef.current;
if (
Expand All @@ -90,13 +98,20 @@ export function AnchoredThreads({
return;
}

const activeIndex = orderedThreads.findIndex(
({ thread }) => thread.id === pluginState?.selectedThreadId
);
const activeIds = pluginState?.activeThreadIds ?? [];

const firstActiveIndex =
activeIds.length === 0
? -1
: orderedThreads.findIndex(({ thread }) =>
activeIds.includes(thread.id)
);
const ascending =
activeIndex !== -1 ? orderedThreads.slice(activeIndex) : orderedThreads;
firstActiveIndex !== -1
? orderedThreads.slice(firstActiveIndex)
: orderedThreads;
const descending =
activeIndex !== -1 ? orderedThreads.slice(0, activeIndex) : [];
firstActiveIndex !== -1 ? orderedThreads.slice(0, firstActiveIndex) : [];

const newPositions = new Map<string, number>();

Expand Down Expand Up @@ -142,7 +157,7 @@ export function AnchoredThreads({
}

setPositions(newPositions);
}, [editor, orderedThreads, pluginState?.selectedThreadId, elements]);
}, [editor, orderedThreads, pluginState?.activeThreadIds, elements]);

useEffect(() => {
if (!pluginState) return;
Expand Down Expand Up @@ -232,7 +247,8 @@ export function AnchoredThreads({
top = positions.get(thread.id)!;
}

const isActive = thread.id === pluginState?.selectedThreadId;
const isActive =
pluginState?.activeThreadIds.includes(thread.id) ?? false;

return (
<ThreadWrapper
Expand Down
Loading
Loading