mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-21 16:26:58 +08:00
@@ -1,3 +1,4 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import { toggleEmbedCardCreateModal } from '@blocksuite/affine-components/embed-card-modal';
|
||||
import { BookmarkBlockSchema } from '@blocksuite/affine-model';
|
||||
import {
|
||||
@@ -5,6 +6,7 @@ import {
|
||||
SlashMenuConfigIdentifier,
|
||||
} from '@blocksuite/affine-widget-slash-menu';
|
||||
import { LinkIcon } from '@blocksuite/icons/lit';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/std/gfx';
|
||||
import type { ExtensionType } from '@blocksuite/store';
|
||||
|
||||
import { LinkTooltip } from './tooltips';
|
||||
@@ -33,7 +35,13 @@ const bookmarkSlashMenuConfig: SlashMenuConfig = {
|
||||
host,
|
||||
'Links',
|
||||
'The added link will be displayed as a card view.',
|
||||
{ mode: 'page', parentModel, index }
|
||||
{ mode: 'page', parentModel, index },
|
||||
({ mode }) => {
|
||||
if (mode === 'edgeless') {
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
if (model.text?.length === 0) {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"@blocksuite/affine-block-surface": "workspace:*",
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-ext-loader": "workspace:*",
|
||||
"@blocksuite/affine-gfx-pointer": "workspace:*",
|
||||
"@blocksuite/affine-inline-reference": "workspace:*",
|
||||
"@blocksuite/affine-model": "workspace:*",
|
||||
"@blocksuite/affine-rich-text": "workspace:*",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
DefaultTool,
|
||||
EdgelessCRUDIdentifier,
|
||||
SurfaceBlockComponent,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
@@ -82,10 +83,7 @@ export function insertEmbedCard(
|
||||
surfaceBlock.model
|
||||
);
|
||||
|
||||
gfx.tool.setTool(
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
'default'
|
||||
);
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
gfx.selection.set({
|
||||
elements: [cardId],
|
||||
editing: false,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import { toggleEmbedCardCreateModal } from '@blocksuite/affine-components/embed-card-modal';
|
||||
import type { SlashMenuConfig } from '@blocksuite/affine-widget-slash-menu';
|
||||
import { FigmaDuotoneIcon } from '@blocksuite/icons/lit';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/std/gfx';
|
||||
|
||||
import { FigmaTooltip } from './tooltips';
|
||||
|
||||
@@ -29,7 +31,13 @@ export const embedFigmaSlashMenuConfig: SlashMenuConfig = {
|
||||
host,
|
||||
'Figma',
|
||||
'The added Figma link will be displayed as an embed view.',
|
||||
{ mode: 'page', parentModel, index }
|
||||
{ mode: 'page', parentModel, index },
|
||||
({ mode }) => {
|
||||
if (mode === 'edgeless') {
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (model.text?.length === 0) std.store.deleteBlock(model);
|
||||
})().catch(console.error);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import { toggleEmbedCardCreateModal } from '@blocksuite/affine-components/embed-card-modal';
|
||||
import type { SlashMenuConfig } from '@blocksuite/affine-widget-slash-menu';
|
||||
import { GithubDuotoneIcon } from '@blocksuite/icons/lit';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/std/gfx';
|
||||
|
||||
import { GithubRepoTooltip } from './tooltips';
|
||||
|
||||
@@ -29,7 +31,13 @@ export const embedGithubSlashMenuConfig: SlashMenuConfig = {
|
||||
host,
|
||||
'GitHub',
|
||||
'The added GitHub issue or pull request link will be displayed as a card view.',
|
||||
{ mode: 'page', parentModel, index }
|
||||
{ mode: 'page', parentModel, index },
|
||||
({ mode }) => {
|
||||
if (mode === 'edgeless') {
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (model.text?.length === 0) std.store.deleteBlock(model);
|
||||
})().catch(console.error);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
DefaultTool,
|
||||
EdgelessCRUDIdentifier,
|
||||
SurfaceBlockComponent,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
@@ -90,10 +91,7 @@ export const insertEmbedIframeWithUrlCommand: Command<
|
||||
surfaceBlock.model
|
||||
);
|
||||
|
||||
gfx.tool.setTool(
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
'default'
|
||||
);
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
|
||||
gfx.selection.set({
|
||||
elements: [newBlockId],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import { toggleEmbedCardCreateModal } from '@blocksuite/affine-components/embed-card-modal';
|
||||
import type { SlashMenuConfig } from '@blocksuite/affine-widget-slash-menu';
|
||||
import { LoomLogoDuotoneIcon } from '@blocksuite/icons/lit';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/std/gfx';
|
||||
|
||||
import { LoomTooltip } from './tooltips';
|
||||
|
||||
@@ -29,7 +31,13 @@ export const embedLoomSlashMenuConfig: SlashMenuConfig = {
|
||||
host,
|
||||
'Loom',
|
||||
'The added Loom video link will be displayed as an embed view.',
|
||||
{ mode: 'page', parentModel, index }
|
||||
{ mode: 'page', parentModel, index },
|
||||
({ mode }) => {
|
||||
if (mode === 'edgeless') {
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (model.text?.length === 0) std.store.deleteBlock(model);
|
||||
})().catch(console.error);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import { toggleEmbedCardCreateModal } from '@blocksuite/affine-components/embed-card-modal';
|
||||
import type { SlashMenuConfig } from '@blocksuite/affine-widget-slash-menu';
|
||||
import { YoutubeDuotoneIcon } from '@blocksuite/icons/lit';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/std/gfx';
|
||||
|
||||
import { YoutubeVideoTooltip } from './tooltips';
|
||||
|
||||
@@ -29,7 +31,13 @@ export const embedYoutubeSlashMenuConfig: SlashMenuConfig = {
|
||||
host,
|
||||
'YouTube',
|
||||
'The added YouTube video link will be displayed as an embed view.',
|
||||
{ mode: 'page', parentModel, index }
|
||||
{ mode: 'page', parentModel, index },
|
||||
({ mode }) => {
|
||||
if (mode === 'edgeless') {
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (model.text?.length === 0) std.store.deleteBlock(model);
|
||||
})().catch(console.error);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
{ "path": "../surface" },
|
||||
{ "path": "../../components" },
|
||||
{ "path": "../../ext-loader" },
|
||||
{ "path": "../../gfx/pointer" },
|
||||
{ "path": "../../inlines/reference" },
|
||||
{ "path": "../../model" },
|
||||
{ "path": "../../rich-text" },
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"@blocksuite/affine-block-surface": "workspace:*",
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-ext-loader": "workspace:*",
|
||||
"@blocksuite/affine-gfx-pointer": "workspace:*",
|
||||
"@blocksuite/affine-model": "workspace:*",
|
||||
"@blocksuite/affine-shared": "workspace:*",
|
||||
"@blocksuite/affine-widget-edgeless-toolbar": "workspace:*",
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import { menu } from '@blocksuite/affine-components/context-menu';
|
||||
import type { DenseMenuBuilder } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { FrameIcon } from '@blocksuite/icons/lit';
|
||||
|
||||
import { EdgelessFrameManagerIdentifier } from '../frame-manager.js';
|
||||
import { FrameTool } from '../frame-tool';
|
||||
import { FrameConfig } from './config.js';
|
||||
|
||||
export const buildFrameDenseMenu: DenseMenuBuilder = (edgeless, gfx) =>
|
||||
menu.subMenu({
|
||||
name: 'Frame',
|
||||
prefix: FrameIcon({ width: '20px', height: '20px' }),
|
||||
select: () => gfx.tool.setTool({ type: 'frame' }),
|
||||
select: () => gfx.tool.setTool(FrameTool),
|
||||
isSelected: gfx.tool.currentToolName$.peek() === 'frame',
|
||||
options: {
|
||||
items: [
|
||||
menu.action({
|
||||
name: 'Custom',
|
||||
select: () => gfx.tool.setTool({ type: 'frame' }),
|
||||
select: () => gfx.tool.setTool(FrameTool),
|
||||
}),
|
||||
...FrameConfig.map(config =>
|
||||
menu.action({
|
||||
name: `Slide ${config.name}`,
|
||||
select: () => {
|
||||
const frame = edgeless.std.get(EdgelessFrameManagerIdentifier);
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
gfx.tool.setTool('default');
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
frame.createFrameOnViewportCenter(config.wh);
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import { EdgelessToolbarToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/std/gfx';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
|
||||
import { EdgelessFrameManagerIdentifier } from '../frame-manager.js';
|
||||
import { FrameTool } from '../frame-tool';
|
||||
import { FrameConfig } from './config.js';
|
||||
|
||||
export class EdgelessFrameMenu extends EdgelessToolbarToolMixin(LitElement) {
|
||||
@@ -65,7 +66,7 @@ export class EdgelessFrameMenu extends EdgelessToolbarToolMixin(LitElement) {
|
||||
}
|
||||
`;
|
||||
|
||||
override type: GfxToolsFullOptionValue['type'] = 'frame';
|
||||
override type = FrameTool;
|
||||
|
||||
get frameManager() {
|
||||
return this.edgeless.std.get(EdgelessFrameManagerIdentifier);
|
||||
@@ -84,8 +85,7 @@ export class EdgelessFrameMenu extends EdgelessToolbarToolMixin(LitElement) {
|
||||
(item, index) => html`
|
||||
<div
|
||||
@click=${() => {
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
gfx.tool.setTool('default');
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
frameManager.createFrameOnViewportCenter(item.wh);
|
||||
}}
|
||||
class="frame-add-button ${index}"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { QuickToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { FrameIcon } from '@blocksuite/icons/lit';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/std/gfx';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
|
||||
import { FrameTool } from '../frame-tool';
|
||||
|
||||
export class EdgelessFrameToolButton extends QuickToolMixin(LitElement) {
|
||||
static override styles = css`
|
||||
:host {
|
||||
@@ -10,7 +11,7 @@ export class EdgelessFrameToolButton extends QuickToolMixin(LitElement) {
|
||||
}
|
||||
`;
|
||||
|
||||
override type: GfxToolsFullOptionValue['type'] = 'frame';
|
||||
override type = FrameTool;
|
||||
|
||||
private _toggleFrameMenu() {
|
||||
if (this.tryDisposePopper()) return;
|
||||
@@ -20,7 +21,7 @@ export class EdgelessFrameToolButton extends QuickToolMixin(LitElement) {
|
||||
}
|
||||
|
||||
override render() {
|
||||
const type = this.edgelessTool?.type;
|
||||
const type = this.edgelessTool?.toolType?.toolName;
|
||||
return html`
|
||||
<edgeless-tool-icon-button
|
||||
class="edgeless-frame-button"
|
||||
@@ -37,7 +38,7 @@ export class EdgelessFrameToolButton extends QuickToolMixin(LitElement) {
|
||||
@click=${() => {
|
||||
// don't update tool before toggling menu
|
||||
this._toggleFrameMenu();
|
||||
this.setEdgelessTool({ type: 'frame' });
|
||||
this.setEdgelessTool(FrameTool);
|
||||
}}
|
||||
>
|
||||
${FrameIcon()}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { EdgelessLegacySlotIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
DefaultTool,
|
||||
EdgelessLegacySlotIdentifier,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { toast } from '@blocksuite/affine-components/toast';
|
||||
import { PanTool } from '@blocksuite/affine-gfx-pointer';
|
||||
import type { FrameBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
EditPropsStore,
|
||||
@@ -16,7 +20,7 @@ import {
|
||||
StopAiIcon,
|
||||
} from '@blocksuite/icons/lit';
|
||||
import type { BlockComponent } from '@blocksuite/std';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/std/gfx';
|
||||
import type { ToolOptions } from '@blocksuite/std/gfx';
|
||||
import { effect } from '@preact/signals-core';
|
||||
import { cssVar } from '@toeverything/theme';
|
||||
import { css, html, LitElement, nothing, type PropertyValues } from 'lit';
|
||||
@@ -27,6 +31,7 @@ import {
|
||||
isFrameBlock,
|
||||
type NavigatorMode,
|
||||
} from '../frame-manager';
|
||||
import { PresentTool } from '../present-tool';
|
||||
|
||||
export class PresentationToolbar extends EdgelessToolbarToolMixin(
|
||||
SignalWatcher(LitElement)
|
||||
@@ -114,7 +119,7 @@ export class PresentationToolbar extends EdgelessToolbarToolMixin(
|
||||
|
||||
private _timer?: ReturnType<typeof setTimeout>;
|
||||
|
||||
override type: GfxToolsFullOptionValue['type'] = 'frameNavigator';
|
||||
override type = PresentTool;
|
||||
|
||||
private get _cachedPresentHideToolbar() {
|
||||
return !!this.edgeless.std
|
||||
@@ -151,7 +156,7 @@ export class PresentationToolbar extends EdgelessToolbarToolMixin(
|
||||
|
||||
private _bindHotKey() {
|
||||
const handleKeyIfFrameNavigator = (action: () => void) => () => {
|
||||
if (this.edgelessTool.type === 'frameNavigator') {
|
||||
if (this.edgelessTool.toolType === PresentTool) {
|
||||
action();
|
||||
}
|
||||
};
|
||||
@@ -171,11 +176,11 @@ export class PresentationToolbar extends EdgelessToolbarToolMixin(
|
||||
private _exitPresentation() {
|
||||
// When exit presentation mode, we need to set the tool to default or pan
|
||||
// And exit fullscreen
|
||||
const tool = this.edgeless.doc.readonly
|
||||
? { type: 'pan', panning: false }
|
||||
: { type: 'default' };
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool(tool);
|
||||
if (this.edgeless.doc.readonly) {
|
||||
this.setEdgelessTool(PanTool, { panning: false });
|
||||
} else {
|
||||
this.setEdgelessTool(DefaultTool);
|
||||
}
|
||||
|
||||
if (document.fullscreenElement) {
|
||||
document.exitFullscreen().catch(console.error);
|
||||
@@ -261,9 +266,11 @@ export class PresentationToolbar extends EdgelessToolbarToolMixin(
|
||||
const currentTool = this.gfx.tool.currentToolOption$.value;
|
||||
const selection = this.gfx.selection;
|
||||
|
||||
if (currentTool?.type === 'frameNavigator') {
|
||||
if (currentTool?.toolType === PresentTool) {
|
||||
this._cachedIndex = this._currentFrameIndex;
|
||||
this._navigatorMode = currentTool.mode ?? this._navigatorMode;
|
||||
this._navigatorMode =
|
||||
(currentTool.options as ToolOptions<PresentTool>)?.mode ??
|
||||
this._navigatorMode;
|
||||
if (isFrameBlock(selection.selectedElements[0])) {
|
||||
this._cachedIndex = this._frames.findIndex(
|
||||
frame => frame.id === selection.selectedElements[0].id
|
||||
@@ -306,14 +313,14 @@ export class PresentationToolbar extends EdgelessToolbarToolMixin(
|
||||
// When exit fullscreen, we need to clear the timer
|
||||
clearTimeout(this._timer);
|
||||
if (
|
||||
this.edgelessTool.type === 'frameNavigator' &&
|
||||
this.edgelessTool.toolType === PresentTool &&
|
||||
this._fullScreenMode
|
||||
) {
|
||||
const tool = this.edgeless.doc.readonly
|
||||
? { type: 'pan', panning: false }
|
||||
: { type: 'default' };
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool(tool);
|
||||
if (this.edgeless.doc.readonly) {
|
||||
this.setEdgelessTool(PanTool, { panning: false });
|
||||
} else {
|
||||
this.setEdgelessTool(DefaultTool);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,7 +432,7 @@ export class PresentationToolbar extends EdgelessToolbarToolMixin(
|
||||
protected override updated(changedProperties: PropertyValues) {
|
||||
if (
|
||||
changedProperties.has('_currentFrameIndex') &&
|
||||
this.edgelessTool.type === 'frameNavigator'
|
||||
this.edgelessTool.toolType === PresentTool
|
||||
) {
|
||||
this._moveToCurrentFrame();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { OverlayIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
DefaultTool,
|
||||
OverlayIdentifier,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import type { FrameBlockModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
EditPropsStore,
|
||||
@@ -39,8 +42,7 @@ export class FrameTool extends BaseTool {
|
||||
if (this._frame) {
|
||||
const frame = this._frame;
|
||||
frame.pop('xywh');
|
||||
// @ts-expect-error TODO: refactor gfx tool
|
||||
this.gfx.tool.setTool('default');
|
||||
this.gfx.tool.setTool(DefaultTool);
|
||||
this.gfx.selection.set({
|
||||
elements: [frame.id],
|
||||
editing: false,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { FrameTool } from './frame-tool';
|
||||
import type { PresentTool, PresentToolOption } from './preset-tool';
|
||||
import type { PresentTool, PresentToolOption } from './present-tool';
|
||||
|
||||
export * from './edgeless-clipboard-config';
|
||||
export * from './edgeless-toolbar';
|
||||
@@ -9,7 +9,7 @@ export * from './frame-manager';
|
||||
export * from './frame-spec';
|
||||
export * from './frame-tool';
|
||||
export * from './frame-toolbar';
|
||||
export * from './preset-tool';
|
||||
export * from './present-tool';
|
||||
|
||||
declare module '@blocksuite/std/gfx' {
|
||||
interface GfxToolsMap {
|
||||
|
||||
@@ -9,6 +9,8 @@ import { css, html, nothing } from 'lit';
|
||||
import { state } from 'lit/decorators.js';
|
||||
import { literal, unsafeStatic } from 'lit/static-html.js';
|
||||
|
||||
import { PresentTool } from '../present-tool';
|
||||
|
||||
export const EDGELESS_NAVIGATOR_BLACK_BACKGROUND_WIDGET =
|
||||
'edgeless-navigator-black-background';
|
||||
export class EdgelessNavigatorBlackBackgroundWidget extends WidgetComponent<RootBlockModel> {
|
||||
@@ -59,7 +61,7 @@ export class EdgelessNavigatorBlackBackgroundWidget extends WidgetComponent<Root
|
||||
|
||||
this.show =
|
||||
blackBackground &&
|
||||
this.gfx.tool.currentToolOption$.peek().type === 'frameNavigator';
|
||||
this.gfx.tool.currentToolOption$.peek().toolType === PresentTool;
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
@@ -3,9 +3,10 @@ import {
|
||||
QuickToolMixin,
|
||||
} from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { PresentationIcon } from '@blocksuite/icons/lit';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/std/gfx';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
|
||||
import { PresentTool } from '../present-tool';
|
||||
|
||||
export class EdgelessPresentButton extends QuickToolMixin(
|
||||
EdgelessToolbarToolMixin(LitElement)
|
||||
) {
|
||||
@@ -19,7 +20,7 @@ export class EdgelessPresentButton extends QuickToolMixin(
|
||||
}
|
||||
`;
|
||||
|
||||
override type: GfxToolsFullOptionValue['type'] = 'frameNavigator';
|
||||
override type = PresentTool;
|
||||
|
||||
override render() {
|
||||
return html`<edgeless-tool-icon-button
|
||||
@@ -29,9 +30,7 @@ export class EdgelessPresentButton extends QuickToolMixin(
|
||||
.iconContainerPadding=${6}
|
||||
.iconSize=${'24px'}
|
||||
@click=${() => {
|
||||
this.setEdgelessTool({
|
||||
type: 'frameNavigator',
|
||||
});
|
||||
this.setEdgelessTool(PresentTool);
|
||||
}}
|
||||
>
|
||||
${PresentationIcon()}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { FrameBlockSpec } from './frame-spec';
|
||||
import { FrameTool } from './frame-tool';
|
||||
import { frameToolbarExtension } from './frame-toolbar';
|
||||
import { edgelessNavigatorBgWidget } from './present/navigator-bg-widget';
|
||||
import { PresentTool } from './preset-tool';
|
||||
import { PresentTool } from './present-tool';
|
||||
|
||||
export class FrameViewExtension extends ViewExtensionProvider {
|
||||
override name = 'affine-frame-block';
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
{ "path": "../surface" },
|
||||
{ "path": "../../components" },
|
||||
{ "path": "../../ext-loader" },
|
||||
{ "path": "../../gfx/pointer" },
|
||||
{ "path": "../../model" },
|
||||
{ "path": "../../shared" },
|
||||
{ "path": "../../widgets/edgeless-toolbar" },
|
||||
|
||||
@@ -2,6 +2,7 @@ import { addAttachments } from '@blocksuite/affine-block-attachment';
|
||||
import { EdgelessFrameManagerIdentifier } from '@blocksuite/affine-block-frame';
|
||||
import { addImages } from '@blocksuite/affine-block-image';
|
||||
import {
|
||||
DefaultTool,
|
||||
EdgelessCRUDIdentifier,
|
||||
ExportManager,
|
||||
getSurfaceComponent,
|
||||
@@ -608,7 +609,7 @@ export class EdgelessClipboardController extends PageClipboard {
|
||||
elements: [noteId],
|
||||
editing: false,
|
||||
});
|
||||
this.gfx.tool.setTool('default');
|
||||
this.gfx.tool.setTool(DefaultTool);
|
||||
}
|
||||
|
||||
copy() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
DefaultModeDragType,
|
||||
DefaultTool,
|
||||
} from '@blocksuite/affine-gfx-pointer';
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import type { RootBlockModel } from '@blocksuite/affine-model';
|
||||
import { WidgetComponent } from '@blocksuite/std';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/std/gfx';
|
||||
@@ -41,6 +41,7 @@ export class EdgelessDraggingAreaRectWidget extends WidgetComponent<RootBlockMod
|
||||
if (
|
||||
rect.w === 0 ||
|
||||
rect.h === 0 ||
|
||||
!tool ||
|
||||
!(tool instanceof DefaultTool) ||
|
||||
tool.dragType !== DefaultModeDragType.Selecting
|
||||
)
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
EdgelessCRUDIdentifier,
|
||||
getSurfaceComponent,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { ConnectorTool } from '@blocksuite/affine-gfx-connector';
|
||||
import {
|
||||
createGroupCommand,
|
||||
createGroupFromSelectedCommand,
|
||||
@@ -196,9 +197,9 @@ export const builtinMiscToolbarConfig = {
|
||||
const point = ctx.gfx.viewport.toViewCoordFromClientCoord([x, y]);
|
||||
|
||||
ctx.store.captureSync();
|
||||
ctx.gfx.tool.setTool('connector', { mode: DEFAULT_CONNECTOR_MODE });
|
||||
ctx.gfx.tool.setTool(ConnectorTool, { mode: DEFAULT_CONNECTOR_MODE });
|
||||
|
||||
const ctc = ctx.gfx.tool.get('connector');
|
||||
const ctc = ctx.gfx.tool.get(ConnectorTool);
|
||||
ctc.quickConnect(point, models[0]);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
import { insertLinkByQuickSearchCommand } from '@blocksuite/affine-block-bookmark';
|
||||
import { EdgelessTextBlockComponent } from '@blocksuite/affine-block-edgeless-text';
|
||||
import { isNoteBlock } from '@blocksuite/affine-block-surface';
|
||||
import { FrameTool } from '@blocksuite/affine-block-frame';
|
||||
import { DefaultTool, isNoteBlock } from '@blocksuite/affine-block-surface';
|
||||
import { toast } from '@blocksuite/affine-components/toast';
|
||||
import { mountConnectorLabelEditor } from '@blocksuite/affine-gfx-connector';
|
||||
import {
|
||||
BrushTool,
|
||||
EraserTool,
|
||||
HighlighterTool,
|
||||
} from '@blocksuite/affine-gfx-brush';
|
||||
import {
|
||||
ConnectorTool,
|
||||
mountConnectorLabelEditor,
|
||||
} from '@blocksuite/affine-gfx-connector';
|
||||
import {
|
||||
createGroupFromSelectedCommand,
|
||||
ungroupCommand,
|
||||
@@ -12,7 +21,10 @@ import {
|
||||
isElementOutsideViewport,
|
||||
isSingleMindMapNode,
|
||||
} from '@blocksuite/affine-gfx-mindmap';
|
||||
import { NoteTool } from '@blocksuite/affine-gfx-note';
|
||||
import { PanTool } from '@blocksuite/affine-gfx-pointer';
|
||||
import { mountShapeTextEditor, ShapeTool } from '@blocksuite/affine-gfx-shape';
|
||||
import { TextTool } from '@blocksuite/affine-gfx-text';
|
||||
import {
|
||||
ConnectorElementModel,
|
||||
ConnectorMode,
|
||||
@@ -33,11 +45,12 @@ import { IS_MAC } from '@blocksuite/global/env';
|
||||
import { Bound, getCommonBound } from '@blocksuite/global/gfx';
|
||||
import { SurfaceSelection, TextSelection } from '@blocksuite/std';
|
||||
import {
|
||||
type BaseTool,
|
||||
GfxBlockElementModel,
|
||||
type GfxPrimitiveElementModel,
|
||||
type GfxToolsMap,
|
||||
type GfxToolsOption,
|
||||
isGfxGroupCompatibleModel,
|
||||
type ToolOptions,
|
||||
type ToolType,
|
||||
} from '@blocksuite/std/gfx';
|
||||
|
||||
import { PageKeyboardManager } from '../keyboard/keyboard-manager.js';
|
||||
@@ -61,38 +74,38 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager {
|
||||
this.rootComponent.bindHotKey(
|
||||
{
|
||||
v: () => {
|
||||
this._setEdgelessTool('default');
|
||||
this._setEdgelessTool(DefaultTool);
|
||||
},
|
||||
t: () => {
|
||||
this._setEdgelessTool('text');
|
||||
this._setEdgelessTool(TextTool);
|
||||
},
|
||||
c: () => {
|
||||
const mode = ConnectorMode.Curve;
|
||||
rootComponent.std.get(EditPropsStore).recordLastProps('connector', {
|
||||
mode,
|
||||
});
|
||||
this._setEdgelessTool('connector', { mode });
|
||||
this._setEdgelessTool(ConnectorTool, { mode });
|
||||
},
|
||||
h: () => {
|
||||
this._setEdgelessTool('pan', {
|
||||
this._setEdgelessTool(PanTool, {
|
||||
panning: false,
|
||||
});
|
||||
},
|
||||
n: () => {
|
||||
this._setEdgelessTool('affine:note', {
|
||||
this._setEdgelessTool(NoteTool, {
|
||||
childFlavour: DEFAULT_NOTE_CHILD_FLAVOUR,
|
||||
childType: DEFAULT_NOTE_CHILD_TYPE,
|
||||
tip: DEFAULT_NOTE_TIP,
|
||||
});
|
||||
},
|
||||
p: () => {
|
||||
this._setEdgelessTool('brush');
|
||||
this._setEdgelessTool(BrushTool);
|
||||
},
|
||||
'Shift-p': () => {
|
||||
this._setEdgelessTool('highlighter');
|
||||
this._setEdgelessTool(HighlighterTool);
|
||||
},
|
||||
e: () => {
|
||||
this._setEdgelessTool('eraser');
|
||||
this._setEdgelessTool(EraserTool);
|
||||
},
|
||||
k: () => {
|
||||
if (this.rootComponent.service.locked) return;
|
||||
@@ -128,7 +141,7 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager {
|
||||
});
|
||||
rootComponent.surface.fitToViewport(Bound.deserialize(frame.xywh));
|
||||
} else if (!this.rootComponent.service.selection.editing) {
|
||||
this._setEdgelessTool('frame');
|
||||
this._setEdgelessTool(FrameTool);
|
||||
}
|
||||
},
|
||||
'-': () => {
|
||||
@@ -184,7 +197,7 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager {
|
||||
}
|
||||
const { shapeName } = controller.activatedOption;
|
||||
const nextShapeName = getNextShapeType(shapeName);
|
||||
this._setEdgelessTool('shape', {
|
||||
this._setEdgelessTool(ShapeTool, {
|
||||
shapeName: nextShapeName,
|
||||
});
|
||||
|
||||
@@ -633,11 +646,9 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager {
|
||||
});
|
||||
}
|
||||
|
||||
private _setEdgelessTool<K extends keyof GfxToolsMap>(
|
||||
toolName: K,
|
||||
...options: K extends keyof GfxToolsOption
|
||||
? [option: GfxToolsOption[K], ignoreActiveState?: boolean]
|
||||
: [option: void, ignoreActiveState?: boolean]
|
||||
private _setEdgelessTool<T extends BaseTool>(
|
||||
toolType: ToolType<T>,
|
||||
...options: [options?: ToolOptions<T>, ignoreActiveState?: boolean]
|
||||
) {
|
||||
const ignoreActiveState =
|
||||
typeof options === 'boolean'
|
||||
@@ -651,9 +662,8 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager {
|
||||
return;
|
||||
}
|
||||
|
||||
this.rootComponent.gfx.tool.setTool<K>(
|
||||
toolName,
|
||||
// @ts-expect-error FIXME: ts error
|
||||
this.rootComponent.gfx.tool.setTool(
|
||||
toolType,
|
||||
options[0] !== undefined && typeof options[0] !== 'boolean'
|
||||
? options[0]
|
||||
: undefined
|
||||
@@ -678,8 +688,7 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager {
|
||||
const revertToPrevTool = (ev: KeyboardEvent) => {
|
||||
if (ev.code === 'Space') {
|
||||
this._setEdgelessTool(
|
||||
// @ts-expect-error FIXME: ts error
|
||||
currentTool.toolName,
|
||||
(currentTool as DefaultTool).constructor as typeof DefaultTool,
|
||||
currentTool?.activatedOption
|
||||
);
|
||||
selection.set(currentSel);
|
||||
@@ -694,7 +703,7 @@ export class EdgelessPageKeyboardManager extends PageKeyboardManager {
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this._setEdgelessTool('pan', { panning: false });
|
||||
this._setEdgelessTool(PanTool, { panning: false });
|
||||
|
||||
edgeless.dispatcher.disposables.addFromEvent(
|
||||
document,
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { NoteConfigExtension } from '@blocksuite/affine-block-note';
|
||||
import type {
|
||||
SurfaceBlockComponent,
|
||||
SurfaceBlockModel,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
DefaultTool,
|
||||
EdgelessLegacySlotIdentifier,
|
||||
getBgGridGap,
|
||||
normalizeWheelDeltaY,
|
||||
type SurfaceBlockComponent,
|
||||
type SurfaceBlockModel,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { isSingleMindMapNode } from '@blocksuite/affine-gfx-mindmap';
|
||||
import { PanTool } from '@blocksuite/affine-gfx-pointer';
|
||||
import { mountShapeTextEditor } from '@blocksuite/affine-gfx-shape';
|
||||
import {
|
||||
NoteBlockModel,
|
||||
@@ -468,9 +468,9 @@ export class EdgelessRootBlockComponent extends BlockComponent<
|
||||
this._initPinchEvent();
|
||||
|
||||
if (this.doc.readonly) {
|
||||
this.gfx.tool.setTool('pan', { panning: true });
|
||||
this.gfx.tool.setTool(PanTool, { panning: true });
|
||||
} else {
|
||||
this.gfx.tool.setTool('default');
|
||||
this.gfx.tool.setTool(DefaultTool);
|
||||
}
|
||||
|
||||
this.gfx.viewport.elementReady.next(this.gfxViewportElm);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { CanvasElementWithText } from '@blocksuite/affine-block-surface';
|
||||
import type { PanTool } from '@blocksuite/affine-gfx-pointer';
|
||||
import {
|
||||
type AttachmentBlockModel,
|
||||
type BookmarkBlockModel,
|
||||
@@ -26,7 +27,7 @@ import { Bound } from '@blocksuite/global/gfx';
|
||||
import type {
|
||||
GfxModel,
|
||||
GfxPrimitiveElementModel,
|
||||
GfxToolsFullOptionValue,
|
||||
ToolOptionWithType,
|
||||
} from '@blocksuite/std/gfx';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
|
||||
@@ -191,15 +192,17 @@ export function isConnectable(
|
||||
}
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/CSS/cursor
|
||||
export function getCursorMode(edgelessTool: GfxToolsFullOptionValue | null) {
|
||||
export function getCursorMode(edgelessTool: ToolOptionWithType) {
|
||||
if (!edgelessTool) {
|
||||
return 'default';
|
||||
}
|
||||
switch (edgelessTool.type) {
|
||||
switch (edgelessTool.toolType?.toolName) {
|
||||
case 'default':
|
||||
return 'default';
|
||||
case 'pan':
|
||||
return edgelessTool.panning ? 'grabbing' : 'grab';
|
||||
return (edgelessTool as ToolOptionWithType<PanTool>).options?.panning
|
||||
? 'grabbing'
|
||||
: 'grab';
|
||||
case 'brush':
|
||||
case 'highlighter':
|
||||
return drawingCursor;
|
||||
|
||||
@@ -32,9 +32,8 @@ export {
|
||||
PageSurfaceBlockSpec,
|
||||
} from './surface-spec.js';
|
||||
export { SurfaceBlockTransformer } from './surface-transformer.js';
|
||||
export * from './tool/default-tool.js';
|
||||
export {
|
||||
addNote,
|
||||
addNoteAtPoint,
|
||||
generateElementId,
|
||||
getBgGridGap,
|
||||
getLastPropsKey,
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
} from '@blocksuite/std/gfx';
|
||||
import { effect } from '@preact/signals-core';
|
||||
|
||||
import { calPanDelta } from '../utils/panning-utils.js';
|
||||
import { calPanDelta } from './panning-utils.js';
|
||||
|
||||
export enum DefaultModeDragType {
|
||||
/** Moving selected contents */
|
||||
@@ -1,137 +0,0 @@
|
||||
import {
|
||||
DEFAULT_NOTE_HEIGHT,
|
||||
DEFAULT_NOTE_WIDTH,
|
||||
NOTE_MIN_HEIGHT,
|
||||
type NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { focusTextModel } from '@blocksuite/affine-rich-text';
|
||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
||||
import type { NoteChildrenFlavour } from '@blocksuite/affine-shared/types';
|
||||
import { handleNativeRangeAtPoint } from '@blocksuite/affine-shared/utils';
|
||||
import { type IPoint, type Point, serializeXYWH } from '@blocksuite/global/gfx';
|
||||
import type { BlockStdScope } from '@blocksuite/std';
|
||||
import {
|
||||
type GfxBlockElementModel,
|
||||
GfxControllerIdentifier,
|
||||
} from '@blocksuite/std/gfx';
|
||||
|
||||
import { DEFAULT_NOTE_OFFSET_X, DEFAULT_NOTE_OFFSET_Y } from '../consts';
|
||||
import { EdgelessCRUDIdentifier } from '../extensions/crud-extension';
|
||||
|
||||
export function addNoteAtPoint(
|
||||
std: BlockStdScope,
|
||||
/**
|
||||
* The point is in browser coordinate
|
||||
*/
|
||||
point: IPoint,
|
||||
options: {
|
||||
width?: number;
|
||||
height?: number;
|
||||
parentId?: string;
|
||||
noteIndex?: number;
|
||||
offsetX?: number;
|
||||
offsetY?: number;
|
||||
scale?: number;
|
||||
} = {}
|
||||
) {
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
const crud = std.get(EdgelessCRUDIdentifier);
|
||||
const {
|
||||
width = DEFAULT_NOTE_WIDTH,
|
||||
height = DEFAULT_NOTE_HEIGHT,
|
||||
offsetX = DEFAULT_NOTE_OFFSET_X,
|
||||
offsetY = DEFAULT_NOTE_OFFSET_Y,
|
||||
parentId = gfx.doc.root?.id,
|
||||
noteIndex,
|
||||
scale = 1,
|
||||
} = options;
|
||||
const [x, y] = gfx.viewport.toModelCoord(point.x, point.y);
|
||||
const blockId = crud.addBlock(
|
||||
'affine:note',
|
||||
{
|
||||
xywh: serializeXYWH(
|
||||
x - offsetX * scale,
|
||||
y - offsetY * scale,
|
||||
width,
|
||||
height
|
||||
),
|
||||
displayMode: NoteDisplayMode.EdgelessOnly,
|
||||
},
|
||||
parentId,
|
||||
noteIndex
|
||||
);
|
||||
|
||||
std.getOptional(TelemetryProvider)?.track('CanvasElementAdded', {
|
||||
control: 'canvas:draw',
|
||||
page: 'whiteboard editor',
|
||||
module: 'toolbar',
|
||||
segment: 'toolbar',
|
||||
type: 'note',
|
||||
});
|
||||
|
||||
return blockId;
|
||||
}
|
||||
|
||||
type NoteOptions = {
|
||||
childFlavour: NoteChildrenFlavour;
|
||||
childType: string | null;
|
||||
collapse: boolean;
|
||||
};
|
||||
|
||||
export function addNote(
|
||||
std: BlockStdScope,
|
||||
point: Point,
|
||||
options: NoteOptions,
|
||||
width = DEFAULT_NOTE_WIDTH,
|
||||
height = DEFAULT_NOTE_HEIGHT
|
||||
) {
|
||||
const noteId = addNoteAtPoint(std, point, {
|
||||
width,
|
||||
height,
|
||||
});
|
||||
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
const doc = std.store;
|
||||
|
||||
const blockId = doc.addBlock(
|
||||
options.childFlavour,
|
||||
{ type: options.childType },
|
||||
noteId
|
||||
);
|
||||
if (options.collapse && height > NOTE_MIN_HEIGHT) {
|
||||
const note = doc.getModelById(noteId) as NoteBlockModel;
|
||||
doc.updateBlock(note, () => {
|
||||
note.props.edgeless.collapse = true;
|
||||
note.props.edgeless.collapsedHeight = height;
|
||||
});
|
||||
}
|
||||
gfx.tool.setTool(
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
'default'
|
||||
);
|
||||
|
||||
// Wait for edgelessTool updated
|
||||
requestAnimationFrame(() => {
|
||||
const blocks =
|
||||
(doc.root?.children.filter(
|
||||
child => child.flavour === 'affine:note'
|
||||
) as GfxBlockElementModel[]) ?? [];
|
||||
const element = blocks.find(b => b.id === noteId);
|
||||
if (element) {
|
||||
gfx.selection.set({
|
||||
elements: [element.id],
|
||||
editing: true,
|
||||
});
|
||||
|
||||
// Waiting dom updated, `note mask` is removed
|
||||
if (blockId) {
|
||||
focusTextModel(gfx.std, blockId);
|
||||
} else {
|
||||
// Cannot reuse `handleNativeRangeClick` directly here,
|
||||
// since `retargetClick` will re-target to pervious editor
|
||||
handleNativeRangeAtPoint(point.x, point.y);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -33,7 +33,6 @@ export function normalizeWheelDeltaY(delta: number, zoom = 1) {
|
||||
return newZoom;
|
||||
}
|
||||
|
||||
export { addNote, addNoteAtPoint } from './add-note';
|
||||
export { getBgGridGap } from './get-bg-grip-gap';
|
||||
export { getLastPropsKey } from './get-last-props-key';
|
||||
export * from './get-surface-block';
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
EditPropsMiddlewareBuilder,
|
||||
} from './extensions';
|
||||
import { ExportManagerExtension } from './extensions/export-manager/export-manager';
|
||||
import { DefaultTool } from './tool/default-tool';
|
||||
|
||||
export class SurfaceViewExtension extends ViewExtensionProvider {
|
||||
override name = 'affine-surface-block';
|
||||
@@ -30,6 +31,7 @@ export class SurfaceViewExtension extends ViewExtensionProvider {
|
||||
ExportManagerExtension,
|
||||
]);
|
||||
if (this.isEdgeless(context.scope)) {
|
||||
context.register(DefaultTool);
|
||||
context.register(
|
||||
BlockViewExtension('affine:surface', literal`affine-surface`)
|
||||
);
|
||||
|
||||
@@ -62,13 +62,8 @@ export class EmbedCardCreateModal extends SignalWatcher(
|
||||
}
|
||||
|
||||
this.createOptions.onSave(url);
|
||||
|
||||
gfx.tool.setTool(
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
'default'
|
||||
);
|
||||
}
|
||||
this.onConfirm();
|
||||
this.onConfirm({ mode });
|
||||
this.remove();
|
||||
};
|
||||
|
||||
@@ -176,7 +171,7 @@ export class EmbedCardCreateModal extends SignalWatcher(
|
||||
accessor input!: HTMLInputElement;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor onConfirm!: () => void;
|
||||
accessor onConfirm!: (options: { mode: 'edgeless' | 'page' }) => void;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor titleText!: string;
|
||||
@@ -195,7 +190,8 @@ export async function toggleEmbedCardCreateModal(
|
||||
| {
|
||||
mode: 'edgeless';
|
||||
onSave: (url: string) => void;
|
||||
}
|
||||
},
|
||||
onConfirm: (options: { mode: 'page' | 'edgeless' }) => void
|
||||
): Promise<void> {
|
||||
host.selection.clear();
|
||||
|
||||
@@ -208,7 +204,10 @@ export async function toggleEmbedCardCreateModal(
|
||||
document.body.append(embedCardCreateModal);
|
||||
|
||||
return new Promise(resolve => {
|
||||
embedCardCreateModal.onConfirm = () => resolve();
|
||||
embedCardCreateModal.onConfirm = options => {
|
||||
onConfirm(options);
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import type { NavigatorMode } from '@blocksuite/affine-block-frame';
|
||||
import {
|
||||
type NavigatorMode,
|
||||
PresentTool,
|
||||
} from '@blocksuite/affine-block-frame';
|
||||
import { EdgelessLegacySlotIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
DocModeProvider,
|
||||
@@ -124,8 +127,7 @@ export class FramePanelHeader extends WithDisposable(LitElement) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this._gfx.tool.setTool({
|
||||
type: 'frameNavigator',
|
||||
this._gfx.tool.setTool(PresentTool, {
|
||||
mode: this._navigatorMode,
|
||||
});
|
||||
}, 100);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import { ThemeProvider } from '@blocksuite/affine-shared/services';
|
||||
import { EdgelessToolbarToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/std/gfx';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
|
||||
import { EraserTool } from '../../../eraser-tool';
|
||||
import { EdgelessEraserDarkIcon, EdgelessEraserLightIcon } from './icons.js';
|
||||
|
||||
export class EdgelessEraserToolButton extends EdgelessToolbarToolMixin(
|
||||
@@ -33,16 +34,15 @@ export class EdgelessEraserToolButton extends EdgelessToolbarToolMixin(
|
||||
|
||||
override enableActiveBackground = true;
|
||||
|
||||
override type: GfxToolsFullOptionValue['type'] = 'eraser';
|
||||
override type = EraserTool;
|
||||
|
||||
override firstUpdated() {
|
||||
this.disposables.add(
|
||||
this.edgeless.bindHotKey(
|
||||
{
|
||||
Escape: () => {
|
||||
if (this.edgelessTool.type === 'eraser') {
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'default' });
|
||||
if (this.edgelessTool.toolType === EraserTool) {
|
||||
this.setEdgelessTool(DefaultTool);
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -52,7 +52,7 @@ export class EdgelessEraserToolButton extends EdgelessToolbarToolMixin(
|
||||
}
|
||||
|
||||
override render() {
|
||||
const type = this.edgelessTool?.type;
|
||||
const type = this.edgelessTool?.toolType;
|
||||
const appTheme = this.edgeless.std.get(ThemeProvider).app$.value;
|
||||
const icon =
|
||||
appTheme === 'dark' ? EdgelessEraserDarkIcon : EdgelessEraserLightIcon;
|
||||
@@ -65,8 +65,8 @@ export class EdgelessEraserToolButton extends EdgelessToolbarToolMixin(
|
||||
data-shortcut="${'E'}"
|
||||
></affine-tooltip-content-with-shortcut>`}
|
||||
.tooltipOffset=${4}
|
||||
.active=${type === 'eraser'}
|
||||
@click=${() => this.setEdgelessTool({ type: 'eraser' })}
|
||||
.active=${type === EraserTool}
|
||||
@click=${() => this.setEdgelessTool(EraserTool)}
|
||||
>
|
||||
<div class="eraser-button">${icon}</div>
|
||||
</edgeless-toolbar-button>
|
||||
|
||||
@@ -16,6 +16,8 @@ import { css, html, LitElement, type TemplateResult } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
|
||||
import { BrushTool } from '../../../brush-tool';
|
||||
import { HighlighterTool } from '../../../highlighter-tool';
|
||||
import { penInfoMap } from './consts';
|
||||
import type { Pen, PenMap } from './types';
|
||||
|
||||
@@ -80,7 +82,11 @@ export class EdgelessPenMenu extends EdgelessToolbarToolMixin(
|
||||
|
||||
private readonly _onPickPen = (tool: Pen) => {
|
||||
this.pen$.value = tool;
|
||||
this.setEdgelessTool(tool);
|
||||
if (tool === 'brush') {
|
||||
this.setEdgelessTool(BrushTool);
|
||||
} else {
|
||||
this.setEdgelessTool(HighlighterTool);
|
||||
}
|
||||
};
|
||||
|
||||
private readonly _onPickColor = (e: ColorEvent) => {
|
||||
@@ -91,7 +97,7 @@ export class EdgelessPenMenu extends EdgelessToolbarToolMixin(
|
||||
this.onChange({ color });
|
||||
};
|
||||
|
||||
override type: Pen[] = ['brush', 'highlighter'];
|
||||
override type = [BrushTool, HighlighterTool];
|
||||
|
||||
override render() {
|
||||
const {
|
||||
|
||||
@@ -10,6 +10,8 @@ import { css, html, LitElement, nothing } from 'lit';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
import { when } from 'lit/directives/when.js';
|
||||
|
||||
import { BrushTool } from '../../../brush-tool';
|
||||
import { HighlighterTool } from '../../../highlighter-tool';
|
||||
import { penIconMap, penInfoMap } from './consts';
|
||||
import type { Pen } from './types';
|
||||
|
||||
@@ -97,19 +99,19 @@ export class EdgelessPenToolButton extends EdgelessToolbarToolMixin(
|
||||
|
||||
override enableActiveBackground = true;
|
||||
|
||||
override type: Pen[] = ['brush', 'highlighter'];
|
||||
override type = [BrushTool, HighlighterTool];
|
||||
|
||||
override firstUpdated() {
|
||||
this.disposables.add(
|
||||
this.gfx.tool.currentToolName$.subscribe(name => {
|
||||
const tool = this.type.find(t => t === name);
|
||||
const tool = this.type.find(t => t.toolName === name);
|
||||
if (!tool) {
|
||||
this.tryDisposePopper();
|
||||
return;
|
||||
}
|
||||
|
||||
if (tool !== this.pen$.peek()) {
|
||||
this.pen$.value = tool;
|
||||
if (tool.toolName !== this.pen$.peek()) {
|
||||
this.pen$.value = tool.toolName as Pen;
|
||||
}
|
||||
|
||||
if (this.active) return;
|
||||
@@ -121,7 +123,17 @@ export class EdgelessPenToolButton extends EdgelessToolbarToolMixin(
|
||||
|
||||
private _togglePenMenu() {
|
||||
if (this.tryDisposePopper()) return;
|
||||
!this.active && this.setEdgelessTool(this.pen$.peek());
|
||||
const setPenByType = (pen: Pen) => {
|
||||
if (pen === 'brush') {
|
||||
this.setEdgelessTool(BrushTool);
|
||||
} else {
|
||||
this.setEdgelessTool(HighlighterTool);
|
||||
}
|
||||
};
|
||||
if (!this.active) {
|
||||
const pen = this.pen$.peek();
|
||||
setPenByType(pen);
|
||||
}
|
||||
const menu = this.createPopper('edgeless-pen-menu', this);
|
||||
Object.assign(menu.element, {
|
||||
colors$: this.colors$,
|
||||
@@ -132,7 +144,7 @@ export class EdgelessPenToolButton extends EdgelessToolbarToolMixin(
|
||||
onChange: (props: Record<string, unknown>) => {
|
||||
const pen = this.pen$.peek();
|
||||
this.edgeless.std.get(EditPropsStore).recordLastProps(pen, props);
|
||||
this.setEdgelessTool(pen);
|
||||
setPenByType(pen);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/std/gfx';
|
||||
|
||||
export type Pen = Extract<
|
||||
GfxToolsFullOptionValue['type'],
|
||||
'brush' | 'highlighter'
|
||||
>;
|
||||
export type Pen = 'brush' | 'highlighter';
|
||||
|
||||
export type PenMap<T> = Record<Pen, T>;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
CanvasElementType,
|
||||
DefaultTool,
|
||||
OverlayIdentifier,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import type {
|
||||
@@ -104,8 +105,7 @@ export class ConnectorTool extends BaseTool<ConnectorToolOptions> {
|
||||
this._allowCancel = true;
|
||||
}
|
||||
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.gfx.tool.setTool('default');
|
||||
this.gfx.tool.setTool(DefaultTool);
|
||||
this.gfx.selection.set({ elements: [focusedId] });
|
||||
}
|
||||
|
||||
@@ -132,8 +132,8 @@ export class ConnectorTool extends BaseTool<ConnectorToolOptions> {
|
||||
const connector = this._connector;
|
||||
|
||||
this.doc.captureSync();
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.gfx.tool.setTool('default');
|
||||
|
||||
this.gfx.tool.setTool(DefaultTool);
|
||||
this.gfx.selection.set({ elements: [connector.id] });
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
DefaultTool,
|
||||
EdgelessCRUDIdentifier,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { getLineHeight } from '@blocksuite/affine-gfx-text';
|
||||
import type { ConnectorElementModel } from '@blocksuite/affine-model';
|
||||
import type { RichText } from '@blocksuite/affine-rich-text';
|
||||
@@ -40,8 +43,7 @@ export function mountConnectorLabelEditor(
|
||||
|
||||
const gfx = edgeless.std.get(GfxControllerIdentifier);
|
||||
|
||||
// @ts-expect-error default tool should be migrated to std
|
||||
gfx.tool.setTool('default');
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
gfx.selection.set({
|
||||
elements: [connector.id],
|
||||
editing: true,
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
DefaultTool,
|
||||
EdgelessCRUDIdentifier,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import type { ConnectorElementModel } from '@blocksuite/affine-model';
|
||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||
import type { IVec } from '@blocksuite/global/gfx';
|
||||
@@ -24,8 +27,7 @@ export function mountConnectorLabelEditor(
|
||||
|
||||
const gfx = edgeless.std.get(GfxControllerIdentifier);
|
||||
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
gfx.tool.setTool('default');
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
gfx.selection.set({
|
||||
elements: [connector.id],
|
||||
editing: true,
|
||||
|
||||
@@ -8,6 +8,8 @@ import {
|
||||
ConnectorLIcon,
|
||||
} from '@blocksuite/icons/lit';
|
||||
|
||||
import { ConnectorTool } from '../connector-tool';
|
||||
|
||||
export const buildConnectorDenseMenu: DenseMenuBuilder = (edgeless, gfx) => {
|
||||
const prevMode =
|
||||
edgeless.std.get(EditPropsStore).lastProps$.value.connector.mode;
|
||||
@@ -17,7 +19,7 @@ export const buildConnectorDenseMenu: DenseMenuBuilder = (edgeless, gfx) => {
|
||||
const createSelect =
|
||||
(mode: ConnectorMode, record = true) =>
|
||||
() => {
|
||||
gfx.tool.setTool('connector', {
|
||||
gfx.tool.setTool(ConnectorTool, {
|
||||
mode,
|
||||
});
|
||||
record &&
|
||||
|
||||
@@ -16,11 +16,12 @@ import {
|
||||
ConnectorEIcon,
|
||||
ConnectorLIcon,
|
||||
} from '@blocksuite/icons/lit';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/std/gfx';
|
||||
import { computed } from '@preact/signals-core';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
|
||||
import { ConnectorTool } from '../connector-tool';
|
||||
|
||||
function ConnectorModeButtonGroup(
|
||||
mode: ConnectorMode,
|
||||
setConnectorMode: (props: Record<string, unknown>) => void
|
||||
@@ -110,7 +111,7 @@ export class EdgelessConnectorMenu extends EdgelessToolbarToolMixin(
|
||||
return this.edgeless.std.get(ThemeProvider).theme$.value;
|
||||
});
|
||||
|
||||
override type: GfxToolsFullOptionValue['type'] = 'connector';
|
||||
override type = ConnectorTool;
|
||||
|
||||
override render() {
|
||||
const { stroke, strokeWidth, mode } = this._props$.value;
|
||||
|
||||
@@ -10,6 +10,8 @@ import {
|
||||
import { computed } from '@preact/signals-core';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
|
||||
import { ConnectorTool } from '../connector-tool';
|
||||
|
||||
const IcomMap = {
|
||||
[ConnectorMode.Straight]: ConnectorLIcon(),
|
||||
[ConnectorMode.Orthogonal]: ConnectorEIcon(),
|
||||
@@ -30,7 +32,7 @@ export class EdgelessConnectorToolButton extends QuickToolMixin(
|
||||
.mode;
|
||||
});
|
||||
|
||||
override type = 'connector' as const;
|
||||
override type = ConnectorTool;
|
||||
|
||||
private _toggleMenu() {
|
||||
if (this.tryDisposePopper()) return;
|
||||
@@ -64,7 +66,7 @@ export class EdgelessConnectorToolButton extends QuickToolMixin(
|
||||
@click=${() => {
|
||||
// don't update tool before toggling menu
|
||||
this._toggleMenu();
|
||||
this.gfx.tool.setTool('connector', {
|
||||
this.gfx.tool.setTool(ConnectorTool, {
|
||||
mode,
|
||||
});
|
||||
}}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import type { GroupElementModel } from '@blocksuite/affine-model';
|
||||
import type { RichText } from '@blocksuite/affine-rich-text';
|
||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||
@@ -36,8 +37,7 @@ export function mountGroupTitleEditor(
|
||||
|
||||
const gfx = edgeless.std.get(GfxControllerIdentifier);
|
||||
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
gfx.tool.setTool('default');
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
gfx.selection.set({
|
||||
elements: [group.id],
|
||||
editing: true,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import type { GroupElementModel } from '@blocksuite/affine-model';
|
||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||
import type { BlockComponent } from '@blocksuite/std';
|
||||
@@ -19,8 +20,7 @@ export function mountGroupTitleEditor(
|
||||
|
||||
const gfx = edgeless.std.get(GfxControllerIdentifier);
|
||||
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
gfx.tool.setTool('default');
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
gfx.selection.set({
|
||||
elements: [group.id],
|
||||
editing: true,
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import { insertLinkByQuickSearchCommand } from '@blocksuite/affine-block-bookmark';
|
||||
import { insertEmbedCard } from '@blocksuite/affine-block-embed';
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import { toggleEmbedCardCreateModal } from '@blocksuite/affine-components/embed-card-modal';
|
||||
import { LinkIcon } from '@blocksuite/affine-components/icons';
|
||||
import type * as PointerEffect from '@blocksuite/affine-gfx-pointer';
|
||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
||||
import { QuickToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/std/gfx';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
|
||||
declare type _GLOBAL_ = typeof PointerEffect;
|
||||
|
||||
export class EdgelessLinkToolButton extends QuickToolMixin(LitElement) {
|
||||
static override styles = css`
|
||||
.link-icon,
|
||||
@@ -18,7 +17,7 @@ export class EdgelessLinkToolButton extends QuickToolMixin(LitElement) {
|
||||
}
|
||||
`;
|
||||
|
||||
override type = 'default' as const;
|
||||
override type = DefaultTool;
|
||||
|
||||
private _onClick() {
|
||||
const [success, { insertedLinkType }] = this.edgeless.std.command.exec(
|
||||
@@ -40,6 +39,12 @@ export class EdgelessLinkToolButton extends QuickToolMixin(LitElement) {
|
||||
props: { url },
|
||||
});
|
||||
},
|
||||
},
|
||||
({ mode }) => {
|
||||
if (mode === 'edgeless') {
|
||||
const gfx = this.edgeless.std.get(GfxControllerIdentifier);
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
}
|
||||
}
|
||||
).catch(console.error);
|
||||
return;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-ext-loader": "workspace:*",
|
||||
"@blocksuite/affine-gfx-connector": "workspace:*",
|
||||
"@blocksuite/affine-gfx-pointer": "workspace:*",
|
||||
"@blocksuite/affine-gfx-shape": "workspace:*",
|
||||
"@blocksuite/affine-gfx-text": "workspace:*",
|
||||
"@blocksuite/affine-model": "workspace:*",
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import { toast } from '@blocksuite/affine-components/toast';
|
||||
import { EmptyTool } from '@blocksuite/affine-gfx-pointer';
|
||||
import type { MindmapStyle } from '@blocksuite/affine-model';
|
||||
import {
|
||||
EditPropsStore,
|
||||
@@ -123,8 +125,7 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
||||
ToolbarMindmapItem | TextItem | ImportItem | MediaItem
|
||||
>;
|
||||
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
override type = 'empty' as const;
|
||||
override type = EmptyTool;
|
||||
|
||||
get mindMaps() {
|
||||
return getMindMaps(this.theme);
|
||||
@@ -223,8 +224,7 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
||||
this.onActiveStyleChange?.(element.data.style);
|
||||
}
|
||||
// a workaround to active mindmap, so that menu cannot be closed by `Escape`
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'empty' });
|
||||
this.setEdgelessTool(EmptyTool);
|
||||
},
|
||||
onDrop: (element, bound) => {
|
||||
if ('render' in element.data) {
|
||||
@@ -234,8 +234,7 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
||||
if (!id) return;
|
||||
if (element.data.type === 'mindmap') {
|
||||
this.onActiveStyleChange?.(element.data.style);
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'default' });
|
||||
this.setEdgelessTool(DefaultTool);
|
||||
this.gfx.selection.set({
|
||||
elements: [id],
|
||||
editing: false,
|
||||
@@ -244,8 +243,7 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
||||
element.data.type === 'text' ||
|
||||
element.data.type === 'media'
|
||||
) {
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'default' });
|
||||
this.setEdgelessTool(DefaultTool);
|
||||
}
|
||||
})
|
||||
.catch(console.error);
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import { EdgelessCRUDIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
DefaultTool,
|
||||
EdgelessCRUDIdentifier,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { EmptyTool } from '@blocksuite/affine-gfx-pointer';
|
||||
import { TextTool } from '@blocksuite/affine-gfx-text';
|
||||
import type {
|
||||
MindmapElementModel,
|
||||
MindmapStyle,
|
||||
@@ -14,7 +19,6 @@ import {
|
||||
} from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import type { Bound } from '@blocksuite/global/gfx';
|
||||
import { SignalWatcher } from '@blocksuite/global/lit';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/std/gfx';
|
||||
import { computed } from '@preact/signals-core';
|
||||
import { css, html, LitElement, nothing } from 'lit';
|
||||
import { property, query, state } from 'lit/decorators.js';
|
||||
@@ -150,8 +154,7 @@ export class EdgelessMindmapToolButton extends EdgelessToolbarToolMixin(
|
||||
|
||||
override enableActiveBackground = true;
|
||||
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
override type: GfxToolsFullOptionValue['type'][] = ['empty', 'text'];
|
||||
override type = [EmptyTool, TextTool];
|
||||
|
||||
get draggableTools(): DraggableTool[] {
|
||||
const style = this._style$.value;
|
||||
@@ -192,8 +195,7 @@ export class EdgelessMindmapToolButton extends EdgelessToolbarToolMixin(
|
||||
|
||||
private _toggleMenu() {
|
||||
if (this.tryDisposePopper()) return;
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'default' });
|
||||
this.setEdgelessTool(DefaultTool);
|
||||
|
||||
const menu = this.createPopper('edgeless-mindmap-menu', this);
|
||||
Object.assign(menu.element, {
|
||||
@@ -213,8 +215,7 @@ export class EdgelessMindmapToolButton extends EdgelessToolbarToolMixin(
|
||||
const element = this.crud.getElementById(id) as MindmapElementModel;
|
||||
|
||||
this.tryDisposePopper();
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'default' });
|
||||
this.setEdgelessTool(DefaultTool);
|
||||
this.gfx.selection.set({
|
||||
elements: [element.tree.id],
|
||||
editing: false,
|
||||
@@ -274,15 +275,13 @@ export class EdgelessMindmapToolButton extends EdgelessToolbarToolMixin(
|
||||
if (!id) return;
|
||||
this.readyToDrop = false;
|
||||
if (el.data.name === 'mindmap') {
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'default' });
|
||||
this.setEdgelessTool(DefaultTool);
|
||||
this.gfx.selection.set({
|
||||
elements: [id],
|
||||
editing: false,
|
||||
});
|
||||
} else if (el.data.name === 'text') {
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'default' });
|
||||
this.setEdgelessTool(DefaultTool);
|
||||
}
|
||||
})
|
||||
.catch(console.error);
|
||||
@@ -314,8 +313,7 @@ export class EdgelessMindmapToolButton extends EdgelessToolbarToolMixin(
|
||||
});
|
||||
return;
|
||||
}
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'empty' });
|
||||
this.setEdgelessTool(EmptyTool);
|
||||
const icon = this.mindmapElement;
|
||||
const { x, y } = gfx.tool.lastMousePos$.peek();
|
||||
const { viewport } = this.edgeless.std.get(ViewportElementProvider);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
{ "path": "../../components" },
|
||||
{ "path": "../../ext-loader" },
|
||||
{ "path": "../connector" },
|
||||
{ "path": "../pointer" },
|
||||
{ "path": "../shape" },
|
||||
{ "path": "../text" },
|
||||
{ "path": "../../model" },
|
||||
|
||||
@@ -1,18 +1,35 @@
|
||||
import type { SurfaceBlockComponent } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
addNote,
|
||||
DEFAULT_NOTE_OFFSET_X,
|
||||
DEFAULT_NOTE_OFFSET_Y,
|
||||
DefaultTool,
|
||||
EdgelessCRUDIdentifier,
|
||||
EXCLUDING_MOUSE_OUT_CLASS_LIST,
|
||||
type SurfaceBlockComponent,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
DEFAULT_NOTE_HEIGHT,
|
||||
DEFAULT_NOTE_WIDTH,
|
||||
NOTE_MIN_HEIGHT,
|
||||
type NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { EditPropsStore } from '@blocksuite/affine-shared/services';
|
||||
import { focusTextModel } from '@blocksuite/affine-rich-text';
|
||||
import {
|
||||
EditPropsStore,
|
||||
TelemetryProvider,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import type { NoteChildrenFlavour } from '@blocksuite/affine-shared/types';
|
||||
import { hasClassNameInList } from '@blocksuite/affine-shared/utils';
|
||||
import { Point } from '@blocksuite/global/gfx';
|
||||
import type { PointerEventState } from '@blocksuite/std';
|
||||
import { BaseTool } from '@blocksuite/std/gfx';
|
||||
import {
|
||||
handleNativeRangeAtPoint,
|
||||
hasClassNameInList,
|
||||
} from '@blocksuite/affine-shared/utils';
|
||||
import { type IPoint, Point, serializeXYWH } from '@blocksuite/global/gfx';
|
||||
import type { BlockStdScope, PointerEventState } from '@blocksuite/std';
|
||||
import {
|
||||
BaseTool,
|
||||
type GfxBlockElementModel,
|
||||
GfxControllerIdentifier,
|
||||
} from '@blocksuite/std/gfx';
|
||||
import { effect } from '@preact/signals-core';
|
||||
|
||||
import { DraggingNoteOverlay, NoteOverlay } from './overlay';
|
||||
@@ -210,3 +227,116 @@ declare module '@blocksuite/std/gfx' {
|
||||
'affine:note': NoteToolOption;
|
||||
}
|
||||
}
|
||||
|
||||
type NoteOptions = {
|
||||
childFlavour: NoteChildrenFlavour;
|
||||
childType: string | null;
|
||||
collapse: boolean;
|
||||
};
|
||||
function addNote(
|
||||
std: BlockStdScope,
|
||||
point: Point,
|
||||
options: NoteOptions,
|
||||
width = DEFAULT_NOTE_WIDTH,
|
||||
height = DEFAULT_NOTE_HEIGHT
|
||||
) {
|
||||
const noteId = addNoteAtPoint(std, point, {
|
||||
width,
|
||||
height,
|
||||
});
|
||||
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
const doc = std.store;
|
||||
|
||||
const blockId = doc.addBlock(
|
||||
options.childFlavour,
|
||||
{ type: options.childType },
|
||||
noteId
|
||||
);
|
||||
if (options.collapse && height > NOTE_MIN_HEIGHT) {
|
||||
const note = doc.getModelById(noteId) as NoteBlockModel;
|
||||
doc.updateBlock(note, () => {
|
||||
note.props.edgeless.collapse = true;
|
||||
note.props.edgeless.collapsedHeight = height;
|
||||
});
|
||||
}
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
|
||||
// Wait for edgelessTool updated
|
||||
requestAnimationFrame(() => {
|
||||
const blocks =
|
||||
(doc.root?.children.filter(
|
||||
child => child.flavour === 'affine:note'
|
||||
) as GfxBlockElementModel[]) ?? [];
|
||||
const element = blocks.find(b => b.id === noteId);
|
||||
if (element) {
|
||||
gfx.selection.set({
|
||||
elements: [element.id],
|
||||
editing: true,
|
||||
});
|
||||
|
||||
// Waiting dom updated, `note mask` is removed
|
||||
if (blockId) {
|
||||
focusTextModel(gfx.std, blockId);
|
||||
} else {
|
||||
// Cannot reuse `handleNativeRangeClick` directly here,
|
||||
// since `retargetClick` will re-target to pervious editor
|
||||
handleNativeRangeAtPoint(point.x, point.y);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addNoteAtPoint(
|
||||
std: BlockStdScope,
|
||||
/**
|
||||
* The point is in browser coordinate
|
||||
*/
|
||||
point: IPoint,
|
||||
options: {
|
||||
width?: number;
|
||||
height?: number;
|
||||
parentId?: string;
|
||||
noteIndex?: number;
|
||||
offsetX?: number;
|
||||
offsetY?: number;
|
||||
scale?: number;
|
||||
} = {}
|
||||
) {
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
const crud = std.get(EdgelessCRUDIdentifier);
|
||||
const {
|
||||
width = DEFAULT_NOTE_WIDTH,
|
||||
height = DEFAULT_NOTE_HEIGHT,
|
||||
offsetX = DEFAULT_NOTE_OFFSET_X,
|
||||
offsetY = DEFAULT_NOTE_OFFSET_Y,
|
||||
parentId = gfx.doc.root?.id,
|
||||
noteIndex,
|
||||
scale = 1,
|
||||
} = options;
|
||||
const [x, y] = gfx.viewport.toModelCoord(point.x, point.y);
|
||||
const blockId = crud.addBlock(
|
||||
'affine:note',
|
||||
{
|
||||
xywh: serializeXYWH(
|
||||
x - offsetX * scale,
|
||||
y - offsetY * scale,
|
||||
width,
|
||||
height
|
||||
),
|
||||
displayMode: NoteDisplayMode.EdgelessOnly,
|
||||
},
|
||||
parentId,
|
||||
noteIndex
|
||||
);
|
||||
|
||||
std.getOptional(TelemetryProvider)?.track('CanvasElementAdded', {
|
||||
control: 'canvas:draw',
|
||||
page: 'whiteboard editor',
|
||||
module: 'toolbar',
|
||||
segment: 'toolbar',
|
||||
type: 'note',
|
||||
});
|
||||
|
||||
return blockId;
|
||||
}
|
||||
|
||||
@@ -5,10 +5,11 @@ import {
|
||||
import { type Color, DefaultTheme } from '@blocksuite/affine-model';
|
||||
import { ThemeProvider } from '@blocksuite/affine-shared/services';
|
||||
import type { XYWH } from '@blocksuite/global/gfx';
|
||||
import type { GfxController, GfxToolsMap } from '@blocksuite/std/gfx';
|
||||
import type { GfxController } from '@blocksuite/std/gfx';
|
||||
import { effect } from '@preact/signals-core';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
import type { NoteTool } from '../note-tool';
|
||||
import {
|
||||
NOTE_OVERLAY_CORNER_RADIUS,
|
||||
NOTE_OVERLAY_HEIGHT,
|
||||
@@ -33,8 +34,7 @@ export class NoteOverlay extends ToolOverlay {
|
||||
effect(() => {
|
||||
// when change note child type, update overlay text
|
||||
if (this.gfx.tool.currentToolName$.value !== 'affine:note') return;
|
||||
const tool =
|
||||
this.gfx.tool.currentTool$.peek() as GfxToolsMap['affine:note'];
|
||||
const tool = this.gfx.tool.currentTool$.peek() as NoteTool;
|
||||
this.text = this._getOverlayText(tool.activatedOption.tip);
|
||||
(this.gfx.surfaceComponent as SurfaceBlockComponent).refresh();
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { addAttachments } from '@blocksuite/affine-block-attachment';
|
||||
import { insertLinkByQuickSearchCommand } from '@blocksuite/affine-block-bookmark';
|
||||
import { addImages } from '@blocksuite/affine-block-image';
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import { MAX_IMAGE_WIDTH } from '@blocksuite/affine-model';
|
||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
||||
import type { NoteChildrenFlavour } from '@blocksuite/affine-shared/types';
|
||||
@@ -10,13 +11,13 @@ import {
|
||||
} from '@blocksuite/affine-shared/utils';
|
||||
import { EdgelessToolbarToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { AttachmentIcon, ImageIcon, LinkIcon } from '@blocksuite/icons/lit';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/std/gfx';
|
||||
import type { ToolOptions } from '@blocksuite/std/gfx';
|
||||
import { effect } from '@preact/signals-core';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { property, state } from 'lit/decorators.js';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
|
||||
import type { NoteToolOption } from '../note-tool.js';
|
||||
import { NoteTool, type NoteToolOption } from '../note-tool.js';
|
||||
import { NOTE_MENU_ITEMS } from './note-menu-config.js';
|
||||
|
||||
export class EdgelessNoteMenu extends EdgelessToolbarToolMixin(LitElement) {
|
||||
@@ -51,7 +52,7 @@ export class EdgelessNoteMenu extends EdgelessToolbarToolMixin(LitElement) {
|
||||
}
|
||||
`;
|
||||
|
||||
override type: GfxToolsFullOptionValue['type'] = 'affine:note';
|
||||
override type = NoteTool;
|
||||
|
||||
private async _addImages() {
|
||||
this._imageLoading = true;
|
||||
@@ -60,8 +61,7 @@ export class EdgelessNoteMenu extends EdgelessToolbarToolMixin(LitElement) {
|
||||
maxWidth: MAX_IMAGE_WIDTH,
|
||||
});
|
||||
this._imageLoading = false;
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.gfx.tool.setTool('default');
|
||||
this.gfx.tool.setTool(DefaultTool);
|
||||
this.gfx.selection.set({ elements: ids });
|
||||
}
|
||||
|
||||
@@ -96,10 +96,11 @@ export class EdgelessNoteMenu extends EdgelessToolbarToolMixin(LitElement) {
|
||||
effect(() => {
|
||||
const tool = this.gfx.tool.currentToolOption$.value;
|
||||
|
||||
if (tool?.type !== 'affine:note') return;
|
||||
this.childFlavour = tool.childFlavour;
|
||||
this.childType = tool.childType;
|
||||
this.tip = tool.tip;
|
||||
if (tool?.toolType !== NoteTool) return;
|
||||
const options = tool.options as ToolOptions<NoteTool>;
|
||||
this.childFlavour = options.childFlavour;
|
||||
this.childType = options.childType;
|
||||
this.tip = options.tip;
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -141,8 +142,7 @@ export class EdgelessNoteMenu extends EdgelessToolbarToolMixin(LitElement) {
|
||||
const file = await openFileOrFiles();
|
||||
if (!file) return;
|
||||
await addAttachments(this.edgeless.std, [file]);
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.gfx.tool.setTool('default');
|
||||
this.gfx.tool.setTool(DefaultTool);
|
||||
this.edgeless.std
|
||||
.getOptional(TelemetryProvider)
|
||||
?.track('CanvasElementAdded', {
|
||||
|
||||
@@ -13,7 +13,7 @@ import { computed } from '@preact/signals-core';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { state } from 'lit/decorators.js';
|
||||
|
||||
import type { NoteToolOption } from '../note-tool.js';
|
||||
import { NoteTool, type NoteToolOption } from '../note-tool.js';
|
||||
import { toShapeNotToAdapt } from './icon.js';
|
||||
|
||||
export class EdgelessNoteSeniorButton extends EdgelessToolbarToolMixin(
|
||||
@@ -138,15 +138,14 @@ export class EdgelessNoteSeniorButton extends EdgelessToolbarToolMixin(
|
||||
|
||||
override enableActiveBackground = true;
|
||||
|
||||
override type = 'affine:note' as const;
|
||||
override type = NoteTool;
|
||||
|
||||
private _toggleNoteMenu() {
|
||||
if (this.tryDisposePopper()) return;
|
||||
|
||||
const { edgeless, childFlavour, childType, tip } = this;
|
||||
|
||||
this.setEdgelessTool({
|
||||
type: 'affine:note',
|
||||
this.setEdgelessTool(NoteTool, {
|
||||
childFlavour,
|
||||
childType,
|
||||
tip,
|
||||
@@ -171,8 +170,7 @@ export class EdgelessNoteSeniorButton extends EdgelessToolbarToolMixin(
|
||||
Object.assign(this, { [key]: props[key] });
|
||||
}
|
||||
});
|
||||
this.setEdgelessTool({
|
||||
type: 'affine:note',
|
||||
this.setEdgelessTool(NoteTool, {
|
||||
childFlavour: this.childFlavour,
|
||||
childType: this.childType,
|
||||
tip: this.tip,
|
||||
|
||||
@@ -4,12 +4,11 @@ import {
|
||||
QuickToolMixin,
|
||||
} from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { PageIcon } from '@blocksuite/icons/lit';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/std/gfx';
|
||||
import { effect } from '@preact/signals-core';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { state } from 'lit/decorators.js';
|
||||
|
||||
import type { NoteToolOption } from '../note-tool.js';
|
||||
import { NoteTool, type NoteToolOption } from '../note-tool.js';
|
||||
import type { EdgelessNoteMenu } from './note-menu.js';
|
||||
|
||||
export class EdgelessNoteToolButton extends QuickToolMixin(LitElement) {
|
||||
@@ -23,7 +22,7 @@ export class EdgelessNoteToolButton extends QuickToolMixin(LitElement) {
|
||||
|
||||
private readonly _states = ['childFlavour', 'childType', 'tip'] as const;
|
||||
|
||||
override type: GfxToolsFullOptionValue['type'] = 'affine:note';
|
||||
override type = NoteTool;
|
||||
|
||||
private _disposeMenu() {
|
||||
this._noteMenu?.dispose();
|
||||
@@ -35,7 +34,7 @@ export class EdgelessNoteToolButton extends QuickToolMixin(LitElement) {
|
||||
this._disposeMenu();
|
||||
this.requestUpdate();
|
||||
} else {
|
||||
this.gfx.tool.setTool('affine:note', {
|
||||
this.gfx.tool.setTool(NoteTool, {
|
||||
childFlavour: this.childFlavour,
|
||||
childType: this.childType,
|
||||
tip: this.tip,
|
||||
@@ -59,7 +58,7 @@ export class EdgelessNoteToolButton extends QuickToolMixin(LitElement) {
|
||||
Object.assign(this, { [key]: props[key] });
|
||||
}
|
||||
});
|
||||
this.gfx.tool.setTool('affine:note', {
|
||||
this.gfx.tool.setTool(NoteTool, {
|
||||
childFlavour: this.childFlavour,
|
||||
childType: this.childType,
|
||||
tip: this.tip,
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import { QuickToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { HandIcon, SelectIcon } from '@blocksuite/icons/lit';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/std/gfx';
|
||||
import { effect } from '@preact/signals-core';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { query } from 'lit/decorators.js';
|
||||
|
||||
import { PanTool } from '../tools';
|
||||
|
||||
export class EdgelessDefaultToolButton extends QuickToolMixin(LitElement) {
|
||||
static override styles = css`
|
||||
.current-icon {
|
||||
@@ -17,19 +19,19 @@ export class EdgelessDefaultToolButton extends QuickToolMixin(LitElement) {
|
||||
}
|
||||
`;
|
||||
|
||||
override type: GfxToolsFullOptionValue['type'][] = ['default', 'pan'];
|
||||
override type = [DefaultTool, PanTool];
|
||||
|
||||
private _changeTool() {
|
||||
if (this.toolbar.activePopper) {
|
||||
// click manually always closes the popper
|
||||
this.toolbar.activePopper.dispose();
|
||||
}
|
||||
const type = this.edgelessTool?.type;
|
||||
const type = this.edgelessTool?.toolType?.toolName;
|
||||
if (type !== 'default' && type !== 'pan') {
|
||||
if (localStorage.defaultTool === 'default') {
|
||||
this.setEdgelessTool('default');
|
||||
this.setEdgelessTool(DefaultTool);
|
||||
} else if (localStorage.defaultTool === 'pan') {
|
||||
this.setEdgelessTool('pan', { panning: false });
|
||||
this.setEdgelessTool(PanTool, { panning: false });
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -37,9 +39,9 @@ export class EdgelessDefaultToolButton extends QuickToolMixin(LitElement) {
|
||||
// wait for animation to finish
|
||||
setTimeout(() => {
|
||||
if (type === 'default') {
|
||||
this.setEdgelessTool('pan', { panning: false });
|
||||
this.setEdgelessTool(PanTool, { panning: false });
|
||||
} else if (type === 'pan') {
|
||||
this.setEdgelessTool('default');
|
||||
this.setEdgelessTool(DefaultTool);
|
||||
}
|
||||
this._fadeIn();
|
||||
}, 100);
|
||||
@@ -71,7 +73,7 @@ export class EdgelessDefaultToolButton extends QuickToolMixin(LitElement) {
|
||||
}
|
||||
|
||||
override render() {
|
||||
const type = this.edgelessTool?.type;
|
||||
const type = this.edgelessTool?.toolType?.toolName;
|
||||
const { active } = this;
|
||||
const tipInfo =
|
||||
type === 'pan'
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
export * from './default-tool.js';
|
||||
export * from './empty-tool.js';
|
||||
export * from './pan-tool.js';
|
||||
|
||||
@@ -56,11 +56,14 @@ export class PanTool extends BaseTool<PanToolOption> {
|
||||
const selection = this.gfx.selection.surfaceSelections;
|
||||
const currentTool = this.controller.currentToolOption$.peek();
|
||||
const restoreToPrevious = () => {
|
||||
this.controller.setTool(currentTool);
|
||||
this.gfx.selection.set(selection);
|
||||
const { toolType, options } = currentTool;
|
||||
if (toolType && options) {
|
||||
this.controller.setTool(toolType, options);
|
||||
this.gfx.selection.set(selection);
|
||||
}
|
||||
};
|
||||
|
||||
this.controller.setTool('pan', {
|
||||
this.controller.setTool(PanTool, {
|
||||
panning: true,
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { effects } from './effects';
|
||||
import { defaultQuickTool } from './quick-tool/quick-tool';
|
||||
import { SnapExtension } from './snap/snap-manager';
|
||||
import { SnapOverlay } from './snap/snap-overlay';
|
||||
import { DefaultTool, EmptyTool, PanTool } from './tools';
|
||||
import { EmptyTool, PanTool } from './tools';
|
||||
|
||||
export class PointerViewExtension extends ViewExtensionProvider {
|
||||
override name = 'affine-pointer-gfx';
|
||||
@@ -20,7 +20,6 @@ export class PointerViewExtension extends ViewExtensionProvider {
|
||||
override setup(context: ViewExtensionContext) {
|
||||
super.setup(context);
|
||||
context.register(EmptyTool);
|
||||
context.register(DefaultTool);
|
||||
context.register(PanTool);
|
||||
if (this.isEdgeless(context.scope)) {
|
||||
context.register(defaultQuickTool);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
CanvasElementType,
|
||||
DefaultTool,
|
||||
EdgelessCRUDIdentifier,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
@@ -137,7 +138,7 @@ export class EdgelessToolbarShapeDraggable extends EdgelessToolbarToolMixin(
|
||||
|
||||
draggingShape: DraggableShape['name'] = 'roundedRect';
|
||||
|
||||
override type = 'shape' as const;
|
||||
override type = ShapeTool;
|
||||
|
||||
get crud() {
|
||||
return this.edgeless.std.get(EdgelessCRUDIdentifier);
|
||||
@@ -169,8 +170,7 @@ export class EdgelessToolbarShapeDraggable extends EdgelessToolbarToolMixin(
|
||||
this.draggableController.states.draggingElement?.data.name;
|
||||
if (!shapeName) return;
|
||||
|
||||
this.setEdgelessTool({
|
||||
type: 'shape',
|
||||
this.setEdgelessTool(ShapeTool, {
|
||||
shapeName,
|
||||
});
|
||||
const controller = this.gfx.tool.currentTool$.peek();
|
||||
@@ -206,8 +206,7 @@ export class EdgelessToolbarShapeDraggable extends EdgelessToolbarToolMixin(
|
||||
this._setShapeOverlayLock(false);
|
||||
this.readyToDrop = false;
|
||||
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.gfx.tool.setTool('default');
|
||||
this.gfx.tool.setTool(DefaultTool);
|
||||
this.gfx.selection.set({
|
||||
elements: [id],
|
||||
editing: false,
|
||||
@@ -265,7 +264,7 @@ export class EdgelessToolbarShapeDraggable extends EdgelessToolbarToolMixin(
|
||||
const clientPos = { x: x + left, y: y + top };
|
||||
this.draggableController.dragAndMoveTo(el, clientPos);
|
||||
} else {
|
||||
this.setEdgelessTool('shape', {
|
||||
this.setEdgelessTool(ShapeTool, {
|
||||
shapeName: this.draggingShape,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,12 +15,16 @@ import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit';
|
||||
import { StyleGeneralIcon, StyleScribbleIcon } from '@blocksuite/icons/lit';
|
||||
import type { BlockComponent } from '@blocksuite/std';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/std/gfx';
|
||||
import {
|
||||
GfxControllerIdentifier,
|
||||
type ToolOptionWithType,
|
||||
} from '@blocksuite/std/gfx';
|
||||
import { computed, effect, type Signal, signal } from '@preact/signals-core';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import { when } from 'lit/directives/when.js';
|
||||
|
||||
import { ShapeTool } from '../shape-tool';
|
||||
import { ShapeComponentConfig } from '../toolbar';
|
||||
|
||||
export class EdgelessShapeMenu extends SignalWatcher(
|
||||
@@ -115,8 +119,12 @@ export class EdgelessShapeMenu extends SignalWatcher(
|
||||
effect(() => {
|
||||
const value = gfx.tool.currentToolOption$.value;
|
||||
|
||||
if (value && value.type === 'shape') {
|
||||
this._shapeName$.value = value.shapeName;
|
||||
if (value && value.toolType === ShapeTool) {
|
||||
const shapeName = (value as ToolOptionWithType<ShapeTool>).options
|
||||
?.shapeName;
|
||||
if (shapeName) {
|
||||
this._shapeName$.value = shapeName;
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
@@ -38,7 +38,7 @@ export class EdgelessShapeToolButton extends EdgelessToolbarToolMixin(
|
||||
if (!this.popper) this._toggleMenu();
|
||||
};
|
||||
|
||||
override type = 'shape' as const;
|
||||
override type = ShapeTool;
|
||||
|
||||
private _toggleMenu() {
|
||||
this.createPopper('edgeless-shape-menu', this, {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
CanvasElementType,
|
||||
DefaultTool,
|
||||
EdgelessCRUDIdentifier,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
@@ -109,8 +110,7 @@ export class EdgelessShapeToolElement extends WithDisposable(LitElement) {
|
||||
return;
|
||||
}
|
||||
this._dragging = false;
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.gfx.tool.setTool('default');
|
||||
this.gfx.tool.setTool(DefaultTool);
|
||||
if (this._isOutside) {
|
||||
const rect = this._shapeElement.getBoundingClientRect();
|
||||
this._backupShapeElement.style.setProperty('transition', 'none');
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
CanvasElementType,
|
||||
DefaultTool,
|
||||
EXCLUDING_MOUSE_OUT_CLASS_LIST,
|
||||
type SurfaceBlockComponent,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
@@ -180,8 +181,7 @@ export class ShapeTool extends BaseTool<ShapeToolOption> {
|
||||
const element = this.gfx.getElementById(id);
|
||||
if (!element) return;
|
||||
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.gfx.tool.setTool('default');
|
||||
this.gfx.tool.setTool(DefaultTool);
|
||||
this.gfx.selection.set({
|
||||
elements: [element.id],
|
||||
editing: false,
|
||||
@@ -257,8 +257,7 @@ export class ShapeTool extends BaseTool<ShapeToolOption> {
|
||||
const element = this.gfx.getElementById(id);
|
||||
if (!element) return;
|
||||
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.controller.setTool('default');
|
||||
this.controller.setTool(DefaultTool);
|
||||
this.gfx.selection.set({
|
||||
elements: [element.id],
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
DefaultTool,
|
||||
EdgelessCRUDIdentifier,
|
||||
TextUtils,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
@@ -49,8 +50,7 @@ export function mountShapeTextEditor(
|
||||
return;
|
||||
}
|
||||
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
gfx.tool.setTool('default');
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
gfx.selection.set({
|
||||
elements: [shapeElement.id],
|
||||
editing: true,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
darkToolbarStyles,
|
||||
lightToolbarStyles,
|
||||
@@ -314,8 +315,7 @@ export class EdgelessTemplatePanel extends WithDisposable(LitElement) {
|
||||
}
|
||||
} finally {
|
||||
this._loadingTemplate = null;
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.gfx.tool.setTool('default');
|
||||
this.gfx.tool.setTool(DefaultTool);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import { ArrowDownSmallIcon } from '@blocksuite/affine-components/icons';
|
||||
import { once } from '@blocksuite/affine-shared/utils';
|
||||
import { EdgelessToolbarToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/std/gfx';
|
||||
import type { ToolOptionWithType } from '@blocksuite/std/gfx';
|
||||
import {
|
||||
arrow,
|
||||
autoUpdate,
|
||||
@@ -14,6 +15,7 @@ import { state } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
|
||||
import { TemplateTool } from '../template-tool';
|
||||
import { TemplateCard1, TemplateCard2, TemplateCard3 } from './cards.js';
|
||||
import type { EdgelessTemplatePanel } from './template-panel.js';
|
||||
|
||||
@@ -115,11 +117,11 @@ export class EdgelessTemplateButton extends EdgelessToolbarToolMixin(
|
||||
|
||||
private _cleanup: (() => void) | null = null;
|
||||
|
||||
private _prevTool: GfxToolsFullOptionValue | null = null;
|
||||
private _prevTool: ToolOptionWithType | null = null;
|
||||
|
||||
override enableActiveBackground = true;
|
||||
|
||||
override type: GfxToolsFullOptionValue['type'] = 'template';
|
||||
override type = TemplateTool;
|
||||
|
||||
get cards() {
|
||||
const { theme } = this;
|
||||
@@ -134,12 +136,15 @@ export class EdgelessTemplateButton extends EdgelessToolbarToolMixin(
|
||||
this._cleanup = null;
|
||||
this.requestUpdate();
|
||||
|
||||
if (this._prevTool && this._prevTool.type !== 'template') {
|
||||
this.setEdgelessTool(this._prevTool);
|
||||
if (
|
||||
this._prevTool &&
|
||||
this._prevTool.toolType &&
|
||||
this._prevTool.toolType !== TemplateTool
|
||||
) {
|
||||
this.setEdgelessTool(this._prevTool.toolType, this._prevTool.options);
|
||||
this._prevTool = null;
|
||||
} else {
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool('default');
|
||||
this.setEdgelessTool(DefaultTool);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,8 +152,8 @@ export class EdgelessTemplateButton extends EdgelessToolbarToolMixin(
|
||||
private _togglePanel() {
|
||||
if (this._openedPanel) {
|
||||
this._closePanel();
|
||||
if (this._prevTool) {
|
||||
this.setEdgelessTool(this._prevTool);
|
||||
if (this._prevTool && this._prevTool.toolType) {
|
||||
this.setEdgelessTool(this._prevTool.toolType, this._prevTool.options);
|
||||
this._prevTool = null;
|
||||
}
|
||||
return;
|
||||
@@ -156,7 +161,7 @@ export class EdgelessTemplateButton extends EdgelessToolbarToolMixin(
|
||||
|
||||
this._prevTool = this.edgelessTool ? { ...this.edgelessTool } : null;
|
||||
|
||||
this.setEdgelessTool('template');
|
||||
this.setEdgelessTool(TemplateTool);
|
||||
|
||||
const panel = document.createElement('edgeless-templates-panel');
|
||||
panel.edgeless = this.edgeless;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
CanvasElementType,
|
||||
DefaultTool,
|
||||
EdgelessCRUDIdentifier,
|
||||
getSurfaceBlock,
|
||||
type IModelCoord,
|
||||
@@ -53,8 +54,7 @@ export function mountTextElementEditor(
|
||||
|
||||
const gfx = edgeless.std.get(GfxControllerIdentifier);
|
||||
|
||||
// @ts-expect-error TODO: refactor gfx tool
|
||||
gfx.tool.setTool('default');
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
gfx.selection.set({
|
||||
elements: [textElement.id],
|
||||
editing: true,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
CanvasElementType,
|
||||
DefaultTool,
|
||||
EdgelessCRUDIdentifier,
|
||||
type IModelCoord,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
@@ -37,8 +38,7 @@ export function mountTextElementEditor(
|
||||
|
||||
const gfx = edgeless.std.get(GfxControllerIdentifier);
|
||||
|
||||
// @ts-expect-error TODO: refactor gfx tool
|
||||
gfx.tool.setTool('default');
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
gfx.selection.set({
|
||||
elements: [textElement.id],
|
||||
editing: true,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import type { TextElementModel } from '@blocksuite/affine-model';
|
||||
import {
|
||||
FeatureFlagService,
|
||||
@@ -49,8 +50,7 @@ export class TextTool extends BaseTool {
|
||||
if (textFlag) {
|
||||
const [x, y] = this.gfx.viewport.toModelCoord(e.x, e.y);
|
||||
this.gfx.std.command.exec(insertEdgelessTextCommand, { x, y });
|
||||
// @ts-expect-error TODO: refactor gfx tool
|
||||
this.gfx.tool.setTool('default');
|
||||
this.gfx.tool.setTool(DefaultTool);
|
||||
} else {
|
||||
addText(this.gfx, e);
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@ import { DefaultTheme } from '@blocksuite/affine-model';
|
||||
import { ThemeProvider } from '@blocksuite/affine-shared/services';
|
||||
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
|
||||
import { EdgelessToolbarToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/std/gfx';
|
||||
import { computed } from '@preact/signals-core';
|
||||
import { css, html, LitElement, nothing } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
|
||||
import { TextTool } from '../tool';
|
||||
|
||||
export class EdgelessTextMenu extends EdgelessToolbarToolMixin(LitElement) {
|
||||
static override styles = css`
|
||||
:host {
|
||||
@@ -20,10 +21,10 @@ export class EdgelessTextMenu extends EdgelessToolbarToolMixin(LitElement) {
|
||||
return this.edgeless.std.get(ThemeProvider).theme$.value;
|
||||
});
|
||||
|
||||
override type: GfxToolsFullOptionValue['type'] = 'text';
|
||||
override type = TextTool;
|
||||
|
||||
override render() {
|
||||
if (this.edgelessTool.type !== 'text') return nothing;
|
||||
if (this.edgelessTool.toolType !== TextTool) return nothing;
|
||||
|
||||
return html`
|
||||
<edgeless-slide-menu>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { getSelectedRect } from '@blocksuite/affine-shared/utils';
|
||||
import { type IVec, Rect } from '@blocksuite/global/gfx';
|
||||
import {
|
||||
GfxControllerIdentifier,
|
||||
type GfxToolsFullOptionValue,
|
||||
type ToolOptionWithType,
|
||||
} from '@blocksuite/std/gfx';
|
||||
import { effect } from '@preact/signals-core';
|
||||
|
||||
@@ -22,10 +22,9 @@ import type { AffineDragHandleWidget } from '../drag-handle.js';
|
||||
*/
|
||||
export class EdgelessWatcher {
|
||||
private readonly _handleEdgelessToolUpdated = (
|
||||
newTool: GfxToolsFullOptionValue
|
||||
newTool: ToolOptionWithType
|
||||
) => {
|
||||
// @ts-expect-error GfxToolsFullOptionValue is extended in other packages
|
||||
if (newTool.type === 'default') {
|
||||
if (newTool.toolType?.toolName === 'default') {
|
||||
this.updateAnchorElement();
|
||||
} else {
|
||||
this.widget.hide();
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
/* oxlint-disable @typescript-eslint/no-non-null-assertion */
|
||||
import { EdgelessLegacySlotIdentifier } from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
DefaultTool,
|
||||
EdgelessLegacySlotIdentifier,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import {
|
||||
type MenuHandler,
|
||||
popMenu,
|
||||
@@ -430,8 +433,7 @@ export class EdgelessToolbarWidget extends WidgetComponent<RootBlockModel> {
|
||||
}
|
||||
|
||||
get edgelessTool() {
|
||||
// FIXME: maybe we need to fix this type
|
||||
return this.gfx.tool.currentToolOption$.value as { type: string };
|
||||
return this.gfx.tool.currentToolName$.value;
|
||||
}
|
||||
|
||||
get gfx() {
|
||||
@@ -439,7 +441,7 @@ export class EdgelessToolbarWidget extends WidgetComponent<RootBlockModel> {
|
||||
}
|
||||
|
||||
get isPresentMode() {
|
||||
return this.edgelessTool.type === 'frameNavigator';
|
||||
return this.edgelessTool === 'frameNavigator';
|
||||
}
|
||||
|
||||
get scrollSeniorToolSize() {
|
||||
@@ -523,7 +525,7 @@ export class EdgelessToolbarWidget extends WidgetComponent<RootBlockModel> {
|
||||
@click=${this._openMoreQuickToolsMenu}
|
||||
?active=${this._quickTools
|
||||
.slice(this._visibleQuickToolSize)
|
||||
.some(tool => tool.type === this.edgelessTool?.type)}
|
||||
.some(tool => tool.type === this.edgelessTool)}
|
||||
>
|
||||
${MoreHorizontalIcon({ width: '20px', height: '20px' })}
|
||||
<affine-tooltip tip-position="top" .offset=${25}>
|
||||
@@ -602,16 +604,15 @@ export class EdgelessToolbarWidget extends WidgetComponent<RootBlockModel> {
|
||||
{
|
||||
Escape: () => {
|
||||
if (this.gfx.selection.editing) return;
|
||||
if (this.edgelessTool.type === 'frameNavigator') return;
|
||||
if (this.edgelessTool.type === 'default') {
|
||||
if (this.edgelessTool === 'frameNavigator') return;
|
||||
if (this.edgelessTool === 'default') {
|
||||
if (this.activePopper) {
|
||||
this.activePopper.dispose();
|
||||
this.activePopper = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.gfx.tool.setTool('default');
|
||||
this.gfx.tool.setTool(DefaultTool);
|
||||
},
|
||||
},
|
||||
{ global: true }
|
||||
@@ -658,7 +659,7 @@ export class EdgelessToolbarWidget extends WidgetComponent<RootBlockModel> {
|
||||
}
|
||||
|
||||
override render() {
|
||||
const { type } = this.edgelessTool || {};
|
||||
const type = this.edgelessTool;
|
||||
if (this.doc.readonly && type !== 'frameNavigator') {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import type { MenuConfig } from '@blocksuite/affine-components/context-menu';
|
||||
import { createIdentifier } from '@blocksuite/global/di';
|
||||
import type { BlockComponent } from '@blocksuite/std';
|
||||
import type { GfxController, GfxToolsMap } from '@blocksuite/std/gfx';
|
||||
import type { GfxController } from '@blocksuite/std/gfx';
|
||||
import type { ExtensionType } from '@blocksuite/store';
|
||||
import { type TemplateResult } from 'lit';
|
||||
|
||||
export interface QuickTool {
|
||||
type?: keyof GfxToolsMap;
|
||||
type?: string;
|
||||
enable?: boolean;
|
||||
content: TemplateResult;
|
||||
/**
|
||||
|
||||
@@ -9,9 +9,9 @@ import type { BlockComponent } from '@blocksuite/std';
|
||||
import {
|
||||
type GfxController,
|
||||
GfxControllerIdentifier,
|
||||
type GfxToolsFullOption,
|
||||
type GfxToolsFullOptionValue,
|
||||
type ToolController,
|
||||
type ToolOptionWithType,
|
||||
type ToolType,
|
||||
} from '@blocksuite/std/gfx';
|
||||
import { consume } from '@lit/context';
|
||||
import { effect } from '@preact/signals-core';
|
||||
@@ -28,8 +28,6 @@ import {
|
||||
import { createPopper, type MenuPopper } from '../create-popper';
|
||||
import type { EdgelessToolbarWidget } from '../edgeless-toolbar';
|
||||
|
||||
type ValueOf<T> = T[keyof T];
|
||||
|
||||
export declare abstract class EdgelessToolbarToolClass extends DisposableClass {
|
||||
active: boolean;
|
||||
|
||||
@@ -37,7 +35,7 @@ export declare abstract class EdgelessToolbarToolClass extends DisposableClass {
|
||||
|
||||
edgeless: BlockComponent;
|
||||
|
||||
edgelessTool: GfxToolsFullOptionValue;
|
||||
edgelessTool: ToolOptionWithType;
|
||||
|
||||
enableActiveBackground?: boolean;
|
||||
|
||||
@@ -58,9 +56,7 @@ export declare abstract class EdgelessToolbarToolClass extends DisposableClass {
|
||||
*/
|
||||
tryDisposePopper: () => boolean;
|
||||
|
||||
abstract type:
|
||||
| GfxToolsFullOptionValue['type']
|
||||
| GfxToolsFullOptionValue['type'][];
|
||||
abstract type: ToolType | ToolType[];
|
||||
|
||||
accessor toolbar: EdgelessToolbarWidget;
|
||||
}
|
||||
@@ -71,19 +67,15 @@ export const EdgelessToolbarToolMixin = <T extends Constructor<LitElement>>(
|
||||
abstract class DerivedClass extends WithDisposable(SuperClass) {
|
||||
enableActiveBackground = false;
|
||||
|
||||
abstract type:
|
||||
| GfxToolsFullOptionValue['type']
|
||||
| GfxToolsFullOptionValue['type'][];
|
||||
abstract type: ToolType | ToolType[];
|
||||
|
||||
get active() {
|
||||
const { type } = this;
|
||||
// @ts-expect-error FIXME: we need to fix the type of edgelessTool
|
||||
const activeType = this.edgelessTool?.type;
|
||||
const activeType = this.edgelessTool?.toolType;
|
||||
|
||||
return activeType
|
||||
? Array.isArray(type)
|
||||
? // @ts-expect-error FIXME: we need to fix the type of edgelessTool
|
||||
type.includes(activeType)
|
||||
? type.includes(activeType)
|
||||
: activeType === type
|
||||
: false;
|
||||
}
|
||||
@@ -93,12 +85,7 @@ export const EdgelessToolbarToolMixin = <T extends Constructor<LitElement>>(
|
||||
}
|
||||
|
||||
get setEdgelessTool() {
|
||||
return (...args: Parameters<ToolController['setTool']>) => {
|
||||
this.gfx.tool.setTool(
|
||||
// @ts-expect-error FIXME: ts error
|
||||
...args
|
||||
);
|
||||
};
|
||||
return this.gfx.tool.setTool;
|
||||
}
|
||||
|
||||
private _applyActiveStyle() {
|
||||
@@ -162,7 +149,7 @@ export const EdgelessToolbarToolMixin = <T extends Constructor<LitElement>>(
|
||||
accessor edgeless!: BlockComponent;
|
||||
|
||||
@state()
|
||||
accessor edgelessTool!: ValueOf<GfxToolsFullOption> | null;
|
||||
accessor edgelessTool!: ToolOptionWithType | null;
|
||||
|
||||
@state()
|
||||
public accessor popper: MenuPopper<HTMLElement> | null = null;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"author": "toeverything",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@blocksuite/affine-block-surface": "workspace:*",
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-ext-loader": "workspace:*",
|
||||
"@blocksuite/affine-model": "workspace:*",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
||||
import type { FrameBlockModel } from '@blocksuite/affine-model';
|
||||
import { BlockSuiteError } from '@blocksuite/global/exceptions';
|
||||
import type { BlockComponent } from '@blocksuite/std';
|
||||
@@ -19,8 +20,7 @@ export function mountFrameTitleEditor(
|
||||
|
||||
const gfx = edgeless.std.get(GfxControllerIdentifier);
|
||||
|
||||
// @ts-expect-error TODO: refactor gfx tool
|
||||
gfx.tool.setTool('default');
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
gfx.selection.set({
|
||||
elements: [frame.id],
|
||||
editing: true,
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
},
|
||||
"include": ["./src"],
|
||||
"references": [
|
||||
{ "path": "../../blocks/surface" },
|
||||
{ "path": "../../components" },
|
||||
{ "path": "../../ext-loader" },
|
||||
{ "path": "../../model" },
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
dedentParagraphCommand,
|
||||
indentParagraphCommand,
|
||||
} from '@blocksuite/affine-block-paragraph';
|
||||
import { getSurfaceBlock } from '@blocksuite/affine-block-surface';
|
||||
import { DefaultTool, getSurfaceBlock } from '@blocksuite/affine-block-surface';
|
||||
import { insertSurfaceRefBlockCommand } from '@blocksuite/affine-block-surface-ref';
|
||||
import { toggleEmbedCardCreateModal } from '@blocksuite/affine-components/embed-card-modal';
|
||||
import { toast } from '@blocksuite/affine-components/toast';
|
||||
@@ -101,6 +101,7 @@ import {
|
||||
type BlockStdScope,
|
||||
ConfigExtensionFactory,
|
||||
} from '@blocksuite/std';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/std/gfx';
|
||||
import { computed } from '@preact/signals-core';
|
||||
import { cssVarV2 } from '@toeverything/theme/v2';
|
||||
import type { TemplateResult } from 'lit';
|
||||
@@ -393,7 +394,13 @@ const contentMediaToolGroup: KeyboardToolPanelGroup = {
|
||||
std.host,
|
||||
'Links',
|
||||
'The added link will be displayed as a card view.',
|
||||
{ mode: 'page', parentModel, index }
|
||||
{ mode: 'page', parentModel, index },
|
||||
({ mode }) => {
|
||||
if (mode === 'edgeless') {
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (model.text?.length === 0) {
|
||||
std.store.deleteBlock(model);
|
||||
@@ -486,7 +493,13 @@ const embedToolGroup: KeyboardToolPanelGroup = {
|
||||
std.host,
|
||||
'YouTube',
|
||||
'The added YouTube video link will be displayed as an embed view.',
|
||||
{ mode: 'page', parentModel, index }
|
||||
{ mode: 'page', parentModel, index },
|
||||
({ mode }) => {
|
||||
if (mode === 'edgeless') {
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (model.text?.length === 0) {
|
||||
std.store.deleteBlock(model);
|
||||
@@ -513,7 +526,13 @@ const embedToolGroup: KeyboardToolPanelGroup = {
|
||||
std.host,
|
||||
'GitHub',
|
||||
'The added GitHub issue or pull request link will be displayed as a card view.',
|
||||
{ mode: 'page', parentModel, index }
|
||||
{ mode: 'page', parentModel, index },
|
||||
({ mode }) => {
|
||||
if (mode === 'edgeless') {
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (model.text?.length === 0) {
|
||||
std.store.deleteBlock(model);
|
||||
@@ -541,7 +560,13 @@ const embedToolGroup: KeyboardToolPanelGroup = {
|
||||
std.host,
|
||||
'Figma',
|
||||
'The added Figma link will be displayed as an embed view.',
|
||||
{ mode: 'page', parentModel, index }
|
||||
{ mode: 'page', parentModel, index },
|
||||
({ mode }) => {
|
||||
if (mode === 'edgeless') {
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (model.text?.length === 0) {
|
||||
std.store.deleteBlock(model);
|
||||
@@ -568,7 +593,13 @@ const embedToolGroup: KeyboardToolPanelGroup = {
|
||||
std.host,
|
||||
'Loom',
|
||||
'The added Loom video link will be displayed as an embed view.',
|
||||
{ mode: 'page', parentModel, index }
|
||||
{ mode: 'page', parentModel, index },
|
||||
({ mode }) => {
|
||||
if (mode === 'edgeless') {
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
gfx.tool.setTool(DefaultTool);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (model.text?.length === 0) {
|
||||
std.store.deleteBlock(model);
|
||||
|
||||
Reference in New Issue
Block a user