mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-29 00:06:09 +08:00
refactor(editor): unify directories naming (#11516)
**Directory Structure Changes** - Renamed multiple block-related directories by removing the "block-" prefix: - `block-attachment` → `attachment` - `block-bookmark` → `bookmark` - `block-callout` → `callout` - `block-code` → `code` - `block-data-view` → `data-view` - `block-database` → `database` - `block-divider` → `divider` - `block-edgeless-text` → `edgeless-text` - `block-embed` → `embed`
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
import type { Color } from '@blocksuite/affine-model';
|
||||
import { ThemeProvider } from '@blocksuite/affine-shared/services';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
import type { EditorHost, SurfaceSelection } from '@blocksuite/std';
|
||||
import { BlockComponent } from '@blocksuite/std';
|
||||
import { GfxControllerIdentifier, type Viewport } from '@blocksuite/std/gfx';
|
||||
import { RANGE_SYNC_EXCLUDE_ATTR } from '@blocksuite/std/inline';
|
||||
import { css, html } from 'lit';
|
||||
import { query } from 'lit/decorators.js';
|
||||
import type { Subject } from 'rxjs';
|
||||
|
||||
import { ConnectorElementModel } from './element-model/index.js';
|
||||
import { CanvasRenderer } from './renderer/canvas-renderer.js';
|
||||
import { OverlayIdentifier } from './renderer/overlay.js';
|
||||
import type { SurfaceBlockModel } from './surface-model.js';
|
||||
|
||||
export interface SurfaceContext {
|
||||
viewport: Viewport;
|
||||
host: EditorHost;
|
||||
selection: {
|
||||
selectedIds: string[];
|
||||
slots: {
|
||||
updated: Subject<SurfaceSelection[]>;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export class SurfaceBlockComponent extends BlockComponent<SurfaceBlockModel> {
|
||||
static isConnector = (element: unknown): element is ConnectorElementModel => {
|
||||
return element instanceof ConnectorElementModel;
|
||||
};
|
||||
|
||||
static override styles = css`
|
||||
.affine-edgeless-surface-block-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.affine-edgeless-surface-block-container canvas {
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
edgeless-block-portal-container {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
height: 100%;
|
||||
font-family: var(--affine-font-family);
|
||||
font-size: var(--affine-font-base);
|
||||
line-height: var(--affine-line-height);
|
||||
color: var(--affine-text-primary-color);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.affine-block-children-container.edgeless {
|
||||
padding-left: 0;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
/**
|
||||
* Fix: pointerEvent stops firing after a short time.
|
||||
* When a gesture is started, the browser intersects the touch-action values of the touched element and its ancestors,
|
||||
* up to the one that implements the gesture (in other words, the first containing scrolling element)
|
||||
* https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action
|
||||
*/
|
||||
touch-action: none;
|
||||
background-color: var(--affine-background-primary-color);
|
||||
background-image: radial-gradient(
|
||||
var(--affine-edgeless-grid-color) 1px,
|
||||
var(--affine-background-primary-color) 1px
|
||||
);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.affine-edgeless-block-child {
|
||||
position: absolute;
|
||||
transform-origin: center;
|
||||
box-sizing: border-box;
|
||||
border: 2px solid var(--affine-white-10);
|
||||
border-radius: 8px;
|
||||
box-shadow: var(--affine-shadow-3);
|
||||
pointer-events: all;
|
||||
}
|
||||
`;
|
||||
|
||||
private _cachedViewport = new Bound();
|
||||
|
||||
private readonly _initThemeObserver = () => {
|
||||
const theme = this.std.get(ThemeProvider);
|
||||
this.disposables.add(theme.theme$.subscribe(() => this.requestUpdate()));
|
||||
};
|
||||
|
||||
private _lastTime = 0;
|
||||
|
||||
private _renderer!: CanvasRenderer;
|
||||
|
||||
fitToViewport = (bound: Bound) => {
|
||||
const { viewport } = this._gfx;
|
||||
bound = bound.expand(30);
|
||||
if (Date.now() - this._lastTime > 200)
|
||||
this._cachedViewport = viewport.viewportBounds;
|
||||
this._lastTime = Date.now();
|
||||
|
||||
if (this._cachedViewport.contains(bound)) return;
|
||||
|
||||
this._cachedViewport = this._cachedViewport.unite(bound);
|
||||
viewport.setViewportByBound(this._cachedViewport, [0, 0, 0, 0], true);
|
||||
};
|
||||
|
||||
refresh = () => {
|
||||
this._renderer?.refresh();
|
||||
};
|
||||
|
||||
private get _gfx() {
|
||||
return this.std.get(GfxControllerIdentifier);
|
||||
}
|
||||
|
||||
get renderer() {
|
||||
return this._renderer;
|
||||
}
|
||||
|
||||
private _initOverlays() {
|
||||
this.std.provider.getAll(OverlayIdentifier).forEach(overlay => {
|
||||
this._renderer.addOverlay(overlay);
|
||||
});
|
||||
|
||||
this._disposables.add(() => {
|
||||
this.std.provider.getAll(OverlayIdentifier).forEach(overlay => {
|
||||
this._renderer.removeOverlay(overlay);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private _initRenderer() {
|
||||
const gfx = this._gfx;
|
||||
const themeService = this.std.get(ThemeProvider);
|
||||
|
||||
this._renderer = new CanvasRenderer({
|
||||
std: this.std,
|
||||
viewport: gfx.viewport,
|
||||
layerManager: gfx.layer,
|
||||
gridManager: gfx.grid,
|
||||
enableStackingCanvas: true,
|
||||
provider: {
|
||||
generateColorProperty: (color: Color, fallback?: Color) =>
|
||||
themeService.generateColorProperty(
|
||||
color,
|
||||
fallback,
|
||||
themeService.edgelessTheme
|
||||
),
|
||||
getColorValue: (color: Color, fallback?: Color, real?: boolean) =>
|
||||
themeService.getColorValue(
|
||||
color,
|
||||
fallback,
|
||||
real,
|
||||
themeService.edgelessTheme
|
||||
),
|
||||
getColorScheme: () => themeService.edgelessTheme,
|
||||
getPropertyValue: (property: string) =>
|
||||
themeService.getCssVariableColor(
|
||||
property,
|
||||
themeService.edgelessTheme
|
||||
),
|
||||
selectedElements: () => gfx.selection.selectedIds,
|
||||
},
|
||||
onStackingCanvasCreated(canvas) {
|
||||
canvas.className = 'indexable-canvas';
|
||||
},
|
||||
surfaceModel: this.model,
|
||||
});
|
||||
|
||||
this._disposables.add(() => {
|
||||
this._renderer.dispose();
|
||||
});
|
||||
this._disposables.add(
|
||||
this._renderer.stackingCanvasUpdated.subscribe(payload => {
|
||||
if (payload.added.length) {
|
||||
this._surfaceContainer.append(...payload.added);
|
||||
}
|
||||
|
||||
if (payload.removed.length) {
|
||||
payload.removed.forEach(canvas => {
|
||||
canvas.remove();
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
this._disposables.add(
|
||||
gfx.selection.slots.updated.subscribe(() => {
|
||||
this._renderer.refresh();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
override connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
this.setAttribute(RANGE_SYNC_EXCLUDE_ATTR, 'true');
|
||||
|
||||
this._initThemeObserver();
|
||||
this._initRenderer();
|
||||
this._initOverlays();
|
||||
}
|
||||
|
||||
override firstUpdated() {
|
||||
this._renderer.attach(this._surfaceContainer);
|
||||
this._renderer['_render']();
|
||||
this._surfaceContainer.append(...this._renderer.stackingCanvas);
|
||||
}
|
||||
|
||||
override render() {
|
||||
return html`
|
||||
<div class="affine-edgeless-surface-block-container">
|
||||
<!-- attach canvas later in renderer -->
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@query('.affine-edgeless-surface-block-container')
|
||||
private accessor _surfaceContainer!: HTMLElement;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'affine-surface': SurfaceBlockComponent;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user