Skip to content

Commit 734be4c

Browse files
committed
⬆️(dependencies) bump blocknote to 0.44.2
We bump the blocknote dependencies to version 0.44.2 to incorporate the latest features and bug fixes. It seems to fix an issue with Titap, when the text was selected and the user clicked on the Go Back button of the browser, the application was crashing. "[tiptap error]: The editor view is not available. Cannot access view['dom']. The editor may not be mounted yet."
1 parent 35be4be commit 734be4c

File tree

21 files changed

+227
-160
lines changed

21 files changed

+227
-160
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ and this project adheres to
1010

1111
- ✨(backend) allow to create a new user in a marketing system
1212

13+
### Fixed
14+
15+
- 🐛(frontend) Select text + Go back one page crash the app #1733
16+
17+
1318
## [4.1.0] - 2025-12-09
1419

1520
### Added

src/frontend/apps/e2e/__tests__/app-impress/doc-comments.spec.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
getOtherBrowserName,
77
verifyDocName,
88
} from './utils-common';
9-
import { writeInEditor } from './utils-editor';
9+
import { getEditor, writeInEditor } from './utils-editor';
1010
import {
1111
addNewMember,
1212
connectOtherUserToDoc,
@@ -48,6 +48,7 @@ test.describe('Doc Comments', () => {
4848
await thread.locator('[data-test="save"]').click();
4949
await expect(thread.getByText('This is a comment').first()).toBeHidden();
5050

51+
await editor.first().click();
5152
await editor.getByText('Hello').click();
5253

5354
await thread.getByText('This is a comment').first().hover();
@@ -135,6 +136,7 @@ test.describe('Doc Comments', () => {
135136
'background-color',
136137
'rgba(237, 180, 0, 0.4)',
137138
);
139+
await editor.first().click();
138140
await editor.getByText('Hello').click();
139141

140142
await thread.getByText('This is a comment').first().hover();
@@ -197,6 +199,7 @@ test.describe('Doc Comments', () => {
197199
'background-color',
198200
'rgba(237, 180, 0, 0.4)',
199201
);
202+
await editor.first().click();
200203
await editor.getByText('Hello').click();
201204

202205
await thread.getByText('This is a new comment').first().hover();
@@ -217,6 +220,8 @@ test.describe('Doc Comments', () => {
217220
// We share the doc with another user
218221
const otherBrowserName = getOtherBrowserName(browserName);
219222

223+
const editor = await getEditor({ page });
224+
220225
// Add a new member with editor role
221226
await page.getByRole('button', { name: 'Share' }).click();
222227
await addNewMember(page, 0, 'Editor', otherBrowserName);
@@ -240,7 +245,7 @@ test.describe('Doc Comments', () => {
240245
text: 'Hello, I can edit the document',
241246
});
242247
await expect(
243-
otherEditor.getByText('Hello, I can edit the document'),
248+
editor.getByText('Hello, I can edit the document'),
244249
).toBeVisible();
245250
await otherEditor.getByText('Hello').selectText();
246251
await otherPage.getByRole('button', { name: 'Comment' }).click();

src/frontend/apps/impress/package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
},
2020
"dependencies": {
2121
"@ag-media/react-pdf-table": "2.0.3",
22-
"@blocknote/code-block": "0.42.3",
23-
"@blocknote/core": "0.42.3",
24-
"@blocknote/mantine": "0.42.3",
25-
"@blocknote/react": "0.42.3",
26-
"@blocknote/xl-docx-exporter": "0.42.3",
27-
"@blocknote/xl-multi-column": "0.42.3",
28-
"@blocknote/xl-odt-exporter": "0.42.3",
29-
"@blocknote/xl-pdf-exporter": "0.42.3",
22+
"@blocknote/code-block": "0.44.2",
23+
"@blocknote/core": "0.44.2",
24+
"@blocknote/mantine": "0.44.2",
25+
"@blocknote/react": "0.44.2",
26+
"@blocknote/xl-docx-exporter": "0.44.2",
27+
"@blocknote/xl-multi-column": "0.44.2",
28+
"@blocknote/xl-odt-exporter": "0.44.2",
29+
"@blocknote/xl-pdf-exporter": "0.44.2",
3030
"@dnd-kit/core": "6.3.1",
3131
"@dnd-kit/modifiers": "9.0.0",
3232
"@emoji-mart/data": "1.2.1",

src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
defaultInlineContentSpecs,
77
withPageBreak,
88
} from '@blocknote/core';
9+
import { CommentsExtension } from '@blocknote/core/comments';
910
import '@blocknote/core/fonts/inter.css';
1011
import * as locales from '@blocknote/core/locales';
1112
import { BlockNoteView } from '@blocknote/mantine';
@@ -101,7 +102,11 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
101102
const cursorName = collabName || t('Anonymous');
102103
const showCursorLabels: 'always' | 'activity' | (string & {}) = 'activity';
103104

104-
const threadStore = useComments(doc.id, canSeeComment, user);
105+
const { resolveUsers, threadStore } = useComments(
106+
doc.id,
107+
canSeeComment,
108+
user,
109+
);
105110

106111
const currentUserAvatarUrl = useMemo(() => {
107112
if (canSeeComment) {
@@ -156,28 +161,12 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
156161
},
157162
showCursorLabels: showCursorLabels as 'always' | 'activity',
158163
},
159-
comments: { threadStore },
160164
dictionary: {
161165
...locales[lang as keyof typeof locales],
162166
multi_column:
163167
multiColumnLocales?.[lang as keyof typeof multiColumnLocales],
164168
},
165-
resolveUsers: async (userIds) => {
166-
return Promise.resolve(
167-
userIds.map((encodedURIUserId) => {
168-
const fullName = decodeURIComponent(encodedURIUserId);
169-
170-
return {
171-
id: encodedURIUserId,
172-
username: fullName || t('Anonymous'),
173-
avatarUrl: avatarUrlFromName(
174-
fullName,
175-
themeTokens?.font?.families?.base,
176-
),
177-
};
178-
}),
179-
);
180-
},
169+
extensions: [CommentsExtension({ threadStore, resolveUsers })],
181170
tables: {
182171
splitCells: true,
183172
cellBackgroundColor: true,
@@ -187,7 +176,7 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
187176
uploadFile,
188177
schema: blockNoteSchema,
189178
},
190-
[cursorName, lang, provider, uploadFile, threadStore],
179+
[cursorName, lang, provider, uploadFile, threadStore, resolveUsers],
191180
);
192181

193182
useHeadings(editor);
@@ -248,7 +237,7 @@ export const BlockNoteReader = ({
248237
}: BlockNoteReaderProps) => {
249238
const { user } = useAuth();
250239
const { setEditor } = useEditorStore();
251-
const threadStore = useComments(docId, false, user);
240+
const { threadStore } = useComments(docId, false, user);
252241
const { t } = useTranslation();
253242
const editor = useCreateBlockNote(
254243
{
@@ -261,12 +250,16 @@ export const BlockNoteReader = ({
261250
provider: undefined,
262251
},
263252
schema: blockNoteSchema,
264-
comments: { threadStore },
265-
resolveUsers: async () => {
266-
return Promise.resolve([]);
267-
},
253+
extensions: [
254+
CommentsExtension({
255+
threadStore,
256+
resolveUsers: async () => {
257+
return Promise.resolve([]);
258+
},
259+
}),
260+
],
268261
},
269-
[initialContent],
262+
[initialContent, threadStore],
270263
);
271264

272265
useEffect(() => {

src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteSuggestionMenu.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { combineByGroup, filterSuggestionItems } from '@blocknote/core';
1+
import { combineByGroup } from '@blocknote/core';
2+
import { filterSuggestionItems } from '@blocknote/core/extensions';
23
import {
34
DefaultReactSuggestionItem,
45
SuggestionMenuController,

src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteToolBar/FileDownloadButton.tsx

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,25 @@
66
* https://github.com/TypeCellOS/BlockNote/blob/main/packages/react/src/components/FormattingToolbar/DefaultButtons/FileDownloadButton.tsx
77
*/
88

9-
import {
10-
BlockSchema,
11-
InlineContentSchema,
12-
StyleSchema,
13-
blockHasType,
14-
} from '@blocknote/core';
9+
import { blockHasType } from '@blocknote/core';
1510
import {
1611
useBlockNoteEditor,
1712
useComponentsContext,
1813
useDictionary,
19-
useSelectedBlocks,
14+
useEditorState,
2015
} from '@blocknote/react';
21-
import { useCallback, useMemo } from 'react';
16+
import { useCallback } from 'react';
2217
import { RiDownload2Fill } from 'react-icons/ri';
2318

2419
import { downloadFile, exportResolveFileUrl } from '@/docs/doc-export';
2520
import { isSafeUrl } from '@/utils/url';
2621

22+
import {
23+
DocsBlockSchema,
24+
DocsInlineContentSchema,
25+
DocsStyleSchema,
26+
} from '../../types';
27+
2728
export const FileDownloadButton = ({
2829
open,
2930
}: {
@@ -33,36 +34,43 @@ export const FileDownloadButton = ({
3334
const Components = useComponentsContext();
3435

3536
const editor = useBlockNoteEditor<
36-
BlockSchema,
37-
InlineContentSchema,
38-
StyleSchema
37+
DocsBlockSchema,
38+
DocsInlineContentSchema,
39+
DocsStyleSchema
3940
>();
4041

41-
const selectedBlocks = useSelectedBlocks(editor);
42+
const fileBlock = useEditorState({
43+
editor,
44+
selector: ({ editor }) => {
45+
const selectedBlocks = editor.getSelection()?.blocks || [
46+
editor.getTextCursorPosition().block,
47+
];
4248

43-
const fileBlock = useMemo(() => {
44-
// Checks if only one block is selected.
45-
if (selectedBlocks.length !== 1) {
46-
return undefined;
47-
}
49+
if (selectedBlocks.length !== 1) {
50+
return undefined;
51+
}
4852

49-
const block = selectedBlocks[0];
53+
const block = selectedBlocks[0];
5054

51-
if (
52-
blockHasType(block, editor, block.type, { url: 'string', name: 'string' })
53-
) {
54-
return block;
55-
}
55+
if (
56+
!blockHasType(block, editor, block.type, {
57+
url: 'string',
58+
name: 'string',
59+
})
60+
) {
61+
return undefined;
62+
}
5663

57-
return undefined;
58-
}, [editor, selectedBlocks]);
64+
return block;
65+
},
66+
});
5967

6068
const onClick = useCallback(async () => {
6169
if (fileBlock && fileBlock.props.url) {
6270
editor.focus();
6371

6472
const url = fileBlock.props.url as string;
65-
const name = fileBlock.props.name as string | undefined;
73+
const name = fileBlock.props.name as string;
6674

6775
/**
6876
* If not hosted on our domain, means not a file uploaded by the user,
@@ -110,19 +118,18 @@ export const FileDownloadButton = ({
110118
return null;
111119
}
112120

121+
const blockType = fileBlock.type as string;
122+
const tooltipText =
123+
dict.formatting_toolbar.file_download.tooltip[blockType] ||
124+
dict.formatting_toolbar.file_download.tooltip['file'];
125+
113126
return (
114127
<>
115128
<Components.FormattingToolbar.Button
116129
className="bn-button --docs--editor-file-download-button"
117130
data-test="downloadfile"
118-
label={
119-
dict.formatting_toolbar.file_download.tooltip[fileBlock.type] ||
120-
dict.formatting_toolbar.file_download.tooltip['file']
121-
}
122-
mainTooltip={
123-
dict.formatting_toolbar.file_download.tooltip[fileBlock.type] ||
124-
dict.formatting_toolbar.file_download.tooltip['file']
125-
}
131+
label={tooltipText}
132+
mainTooltip={tooltipText}
126133
icon={<RiDownload2Fill />}
127134
onClick={() => void onClick()}
128135
/>

src/frontend/apps/impress/src/features/docs/doc-editor/components/comments/CommentToolbarButton.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
* https://github.com/TypeCellOS/BlockNote/blob/main/packages/react/src/components/FormattingToolbar/DefaultButtons/AddCommentButton.tsx
44
*/
55

6+
import { CommentsExtension } from '@blocknote/core/comments';
7+
import { FormattingToolbarExtension } from '@blocknote/core/extensions';
68
import {
79
useBlockNoteEditor,
810
useComponentsContext,
11+
useExtension,
912
useSelectedBlocks,
1013
} from '@blocknote/react';
1114
import { useMemo } from 'react';
@@ -29,6 +32,10 @@ export const CommentToolbarButton = () => {
2932
const { t } = useTranslation();
3033
const { spacingsTokens, colorsTokens } = useCunninghamTheme();
3134
const { isDesktop } = useResponsiveStore();
35+
const comments = useExtension('comments') as unknown as ReturnType<
36+
ReturnType<typeof CommentsExtension>
37+
>;
38+
const { store } = useExtension(FormattingToolbarExtension);
3239

3340
const editor = useBlockNoteEditor<
3441
DocsBlockSchema,
@@ -53,6 +60,7 @@ export const CommentToolbarButton = () => {
5360
};
5461

5562
if (
63+
!comments ||
5664
!isDesktop ||
5765
!show ||
5866
!editor.isEditable ||
@@ -67,8 +75,8 @@ export const CommentToolbarButton = () => {
6775
<Components.Generic.Toolbar.Button
6876
className="bn-button"
6977
onClick={() => {
70-
editor.comments?.startPendingComment();
71-
editor.formattingToolbar.closeMenu();
78+
comments.startPendingComment();
79+
store.setState(false);
7280
focusOnInputThread();
7381
}}
7482
aria-haspopup="dialog"

src/frontend/apps/impress/src/features/docs/doc-editor/components/comments/DocsThreadStore.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ export class DocsThreadStore extends ThreadStore {
200200
const { editor } = useEditorStore.getState();
201201

202202
// Should not happen
203-
if (!editor) {
203+
if (!editor || !editor._tiptapEditor?.view?.dom) {
204204
console.warn('Editor to add thread not ready');
205205
return Promise.resolve();
206206
}

0 commit comments

Comments
 (0)