fix(editor): using click event instead of pointerDown event for page block (#10351)
Close [BS-2647](https://linear.app/affine-design/issue/BS-2647/ios返回手势会误触发focus导致弹起键盘) ### What Changes: - Using `click` event instead of `pointerDown` event to handle selection logic in page block, because gestures on mobile devices can trigger the `pointerDown` event, causing the cursor to update and unexpectedly bring up the virtual keyboard.
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import { appendParagraphCommand } from '@blocksuite/affine-block-paragraph';
|
||||||
import { focusTextModel } from '@blocksuite/affine-components/rich-text';
|
import { focusTextModel } from '@blocksuite/affine-components/rich-text';
|
||||||
import {
|
import {
|
||||||
CodeBlockModel,
|
CodeBlockModel,
|
||||||
@@ -49,11 +50,7 @@ function testClickOnBlankArea(
|
|||||||
const blankRight =
|
const blankRight =
|
||||||
viewportLeft + (viewportWidth - pageWidth) / 2 + pageWidth - paddingRight;
|
viewportLeft + (viewportWidth - pageWidth) / 2 + pageWidth - paddingRight;
|
||||||
|
|
||||||
if (state.raw.clientX < blankLeft || state.raw.clientX > blankRight) {
|
return state.raw.clientX < blankLeft || state.raw.clientX > blankRight;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PageRootBlockComponent extends BlockComponent<
|
export class PageRootBlockComponent extends BlockComponent<
|
||||||
@@ -321,6 +318,32 @@ export class PageRootBlockComponent extends BlockComponent<
|
|||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// prevent cursor jump
|
||||||
|
event.raw.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.handleEvent('click', ctx => {
|
||||||
|
const event = ctx.get('pointerState');
|
||||||
|
if (
|
||||||
|
event.raw.target !== this &&
|
||||||
|
event.raw.target !== this.viewportElement &&
|
||||||
|
event.raw.target !== this.rootElementContainer
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const notes = this.model.children.filter(
|
||||||
|
(child): child is NoteBlockModel =>
|
||||||
|
child instanceof NoteBlockModel &&
|
||||||
|
child.displayMode !== NoteDisplayMode.EdgelessOnly
|
||||||
|
);
|
||||||
|
|
||||||
|
// make sure there is a block can be focused
|
||||||
|
if (notes.length === 0 || notes[notes.length - 1].children.length === 0) {
|
||||||
|
this.std.command.exec(appendParagraphCommand);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const { paddingLeft, paddingRight } = window.getComputedStyle(
|
const { paddingLeft, paddingRight } = window.getComputedStyle(
|
||||||
this.rootElementContainer
|
this.rootElementContainer
|
||||||
);
|
);
|
||||||
@@ -334,6 +357,14 @@ export class PageRootBlockComponent extends BlockComponent<
|
|||||||
parseFloat(paddingRight)
|
parseFloat(paddingRight)
|
||||||
);
|
);
|
||||||
if (!isClickOnBlankArea) {
|
if (!isClickOnBlankArea) {
|
||||||
|
const lastBlock = notes[notes.length - 1].lastChild();
|
||||||
|
if (
|
||||||
|
!lastBlock ||
|
||||||
|
!matchModels(lastBlock, [ParagraphBlockModel]) ||
|
||||||
|
lastBlock.text.length !== 0
|
||||||
|
) {
|
||||||
|
this.std.command.exec(appendParagraphCommand);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,67 +403,6 @@ export class PageRootBlockComponent extends BlockComponent<
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.handleEvent('click', ctx => {
|
|
||||||
const event = ctx.get('pointerState');
|
|
||||||
if (
|
|
||||||
event.raw.target !== this &&
|
|
||||||
event.raw.target !== this.viewportElement &&
|
|
||||||
event.raw.target !== this.rootElementContainer
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let newTextSelectionId: string | null = null;
|
|
||||||
const readonly = this.doc.readonly;
|
|
||||||
const lastNote = this.model.children
|
|
||||||
.slice()
|
|
||||||
.reverse()
|
|
||||||
.find(child => {
|
|
||||||
const isNote = matchModels(child, [NoteBlockModel]);
|
|
||||||
if (!isNote) return false;
|
|
||||||
const displayOnDoc =
|
|
||||||
!!child.displayMode &&
|
|
||||||
child.displayMode !== NoteDisplayMode.EdgelessOnly;
|
|
||||||
return displayOnDoc;
|
|
||||||
});
|
|
||||||
if (!lastNote) {
|
|
||||||
if (readonly) return;
|
|
||||||
const noteId = this.doc.addBlock('affine:note', {}, this.model.id);
|
|
||||||
const paragraphId = this.doc.addBlock('affine:paragraph', {}, noteId);
|
|
||||||
newTextSelectionId = paragraphId;
|
|
||||||
} else {
|
|
||||||
const last = lastNote.children.at(-1);
|
|
||||||
if (
|
|
||||||
!last ||
|
|
||||||
!(matchModels(last, [ParagraphBlockModel]) && last.text.length === 0)
|
|
||||||
) {
|
|
||||||
if (readonly) return;
|
|
||||||
const paragraphId = this.doc.addBlock(
|
|
||||||
'affine:paragraph',
|
|
||||||
{},
|
|
||||||
lastNote.id
|
|
||||||
);
|
|
||||||
newTextSelectionId = paragraphId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.updateComplete
|
|
||||||
.then(() => {
|
|
||||||
if (!newTextSelectionId) return;
|
|
||||||
this.host.selection.setGroup('note', [
|
|
||||||
this.host.selection.create(TextSelection, {
|
|
||||||
from: {
|
|
||||||
blockId: newTextSelectionId,
|
|
||||||
index: 0,
|
|
||||||
length: 0,
|
|
||||||
},
|
|
||||||
to: null,
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
})
|
|
||||||
.catch(console.error);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override disconnectedCallback() {
|
override disconnectedCallback() {
|
||||||
|
|||||||
Reference in New Issue
Block a user