Skip to content

Commit

Permalink
feat(presets): copilot panel with self-provided tokens (#5510)
Browse files Browse the repository at this point in the history
Co-authored-by: Mirone <Saul-Mirone@outlook.com>
  • Loading branch information
zzj3720 and Saul-Mirone authored Dec 7, 2023
1 parent 957031b commit fde4ce0
Show file tree
Hide file tree
Showing 49 changed files with 1,750 additions and 466 deletions.
7 changes: 5 additions & 2 deletions packages/blocks/src/_common/utils/filesys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,12 @@ export async function uploadImageFromLocal(storage: BlobManager) {
multiple: true,
});
if (!imageFiles) return [];
return loadImages(imageFiles, storage);
}
export async function loadImages(images: File[], storage: BlobManager) {
const res: { file: File; sourceId: string }[] = [];
for (let i = 0; i < imageFiles.length; i++) {
const file = imageFiles[i];
for (let i = 0; i < images.length; i++) {
const file = images[i];
const sourceId = await storage.set(file);
res.push({ file, sourceId });
}
Expand Down
3 changes: 1 addition & 2 deletions packages/blocks/src/_common/utils/model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { BaseBlockModel } from '@blocksuite/store';
import type { Page } from '@blocksuite/store';
import type { BaseBlockModel, Page } from '@blocksuite/store';

import type {
AttachmentBlockModel,
Expand Down
21 changes: 17 additions & 4 deletions packages/blocks/src/_legacy/clipboard/edgeless-clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ import {
} from '../../page-block/edgeless/utils/query.js';
import { getSelectedContentModels } from '../../page-block/utils/selection.js';
import { EdgelessBlockType } from '../../surface-block/edgeless-types.js';
import { CanvasElementType } from '../../surface-block/index.js';
import {
Bound,
type CanvasElement,
CanvasElementType,
type Connection,
ConnectorElement,
deserializeXYWH,
Expand Down Expand Up @@ -227,7 +227,10 @@ export class EdgelessClipboard implements Clipboard {
if (files.length === 0) {
return;
}
const res: { file: File; sourceId: string }[] = [];
const res: {
file: File;
sourceId: string;
}[] = [];
for (let i = 0; i < files.length; i++) {
const file = files[i];
if (file.type.startsWith('image')) {
Expand Down Expand Up @@ -475,7 +478,9 @@ export class EdgelessClipboard implements Clipboard {
frames: SerializedBlock[];
notes?: SerializedBlock[];
images?: SerializedBlock[];
elements?: { type: CanvasElement['type'] }[];
elements?: {
type: CanvasElement['type'];
}[];
};

// map old id to new id to rebuild connector's source and target
Expand Down Expand Up @@ -555,7 +560,7 @@ export class EdgelessClipboard implements Clipboard {
);
}

async copyAsPng(blocks: TopLevelBlockModel[], shapes: CanvasElement[]) {
async toCanvas(blocks: TopLevelBlockModel[], shapes: CanvasElement[]) {
const blocksLen = blocks.length;
const shapesLen = shapes.length;

Expand Down Expand Up @@ -587,6 +592,14 @@ export class EdgelessClipboard implements Clipboard {

assertExists(canvas);

return canvas;
}

async copyAsPng(blocks: TopLevelBlockModel[], shapes: CanvasElement[]) {
const canvas = await this.toCanvas(blocks, shapes);
if (!canvas) {
return;
}
// @ts-ignore
if (window.apis?.clipboard?.copyAsImageFromString) {
// @ts-ignore
Expand Down
36 changes: 30 additions & 6 deletions packages/blocks/src/_legacy/content-parser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export class ContentParser {
private _notionHtmlParser: NotionHtmlParser;
private urlPattern =
/(?<=\s|^)https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_+.~#?&/=]*)(?=\s|$)/g;

constructor(
page: Page,
options: {
Expand Down Expand Up @@ -183,7 +184,7 @@ export class ContentParser {
gridColor: string;
}
) {
const svgImg = `<svg width="${ctx.canvas.width}px" height="${ctx.canvas.height}px" xmlns="http://www.w3.org/2000/svg" style="background-size:${size}px ${size}px;background-color:${backgroundColor}; background-image: radial-gradient(${gridColor} 1px, ${backgroundColor} 1px)"></svg>`;
const svgImg = `<svg width='${ctx.canvas.width}px' height='${ctx.canvas.height}px' xmlns='http://www.w3.org/2000/svg' style='background-size:${size}px ${size}px;background-color:${backgroundColor}; background-image: radial-gradient(${gridColor} 1px, ${backgroundColor} 1px)'></svg>`;
const img = new Image();
const cleanup = () => {
img.onload = null;
Expand Down Expand Up @@ -274,7 +275,9 @@ export class ContentParser {
nodes?: TopLevelBlockModel[],
surfaces?: SurfaceElement[],
blockElementGetter: (model: BaseBlockModel) => Element | null = () => null,
edgelessBackground?: { zoom: number }
edgelessBackground?: {
zoom: number;
}
): Promise<HTMLCanvasElement | undefined> {
const root = this._page.root;
if (!root) return;
Expand Down Expand Up @@ -314,6 +317,27 @@ export class ContentParser {
// TODO: refactor of this part
const blocks = nodes ?? edgeless?.getSortedElementsByBound(bound) ?? [];
for (const block of blocks) {
if (block.flavour === 'affine:image') {
const blob = await block.page.blob.get(block.sourceId);
if (!blob) {
return;
}
const blobToImage = (blob: Blob) =>
new Promise<HTMLImageElement>((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = reject;
img.src = URL.createObjectURL(blob);
});
const blockBound = xywhArrayToObject(block);
ctx.drawImage(
await blobToImage(blob),
blockBound.x - bound.x,
blockBound.y - bound.y,
blockBound.w,
blockBound.h
);
}
const blockElement = blockElementGetter(block)?.parentElement;

if (blockElement) {
Expand Down Expand Up @@ -918,13 +942,13 @@ export class ContentParser {
return;
},
renderer(token: marked.Tokens.Generic) {
return `<div class="page-meta-data">
<div class="value">
<div class="tags">
return `<div class='page-meta-data'>
<div class='value'>
<div class='tags'>
${(token.text as string)
.split(',')
.map(tag => {
return `<div class="tag">${tag}</div>`;
return `<div class='tag'>${tag}</div>`;
})
.join('')}
</div>
Expand Down
2 changes: 2 additions & 0 deletions packages/blocks/src/_specs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { DatabaseBlockSchema } from '../database-block/database-model.js';
import { DatabaseService } from '../database-block/database-service.js';
import { DividerBlockSchema } from '../divider-block/divider-model.js';
import { EmbedGithubBlockSpec } from '../embed-github-block/index.js';
import { EmbedHtmlBlockSpec } from '../embed-html-block/embed-html-spec.js';
import { FrameBlockSchema } from '../frame-block/index.js';
import { ImageBlockSchema } from '../image-block/image-model.js';
import { ImageService } from '../image-block/index.js';
Expand Down Expand Up @@ -189,6 +190,7 @@ const CommonFirstPartyBlockSpecs: BlockSpec[] = [
},
},
EmbedGithubBlockSpec,
EmbedHtmlBlockSpec,
];

export const DocEditorBlockSpecs: BlockSpec[] = [
Expand Down
57 changes: 57 additions & 0 deletions packages/blocks/src/embed-html-block/embed-html-block.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { css, html, type PropertyValues } from 'lit';
import { customElement, query } from 'lit/decorators.js';

import { EmbedBlockElement } from '../_common/embed-block-helper/index.js';
import type { EmbedHtmlBlockModel } from './embed-html-model.js';

@customElement('affine-embed-html-block')
export class EmbedHtmlBlock extends EmbedBlockElement<EmbedHtmlBlockModel> {
static override styles = css`
//affine-html {
// display: block;
//}
//
.embed-html-block-iframe {
border: none;
width: 100%;
}
`;
@query('.embed-html-block-iframe')
iframe!: HTMLIFrameElement;

updateWH = () => {
const [, , w, h] = JSON.parse(this.model.xywh);
this.iframe.style.width = `${w}px`;
this.iframe.style.height = `${h}px`;
};

public override connectedCallback() {
super.connectedCallback();
this.disposables.add(this.model.propsUpdated.on(this.updateWH));
}

protected override firstUpdated(_changedProperties: PropertyValues) {
super.firstUpdated(_changedProperties);
this.updateWH();
}

override render(): unknown {
return this.renderEmbed(() => {
if (!this.model.html) {
return html` <div class="affine-html-empty">Empty</div>`;
}
return html`<iframe
class="embed-html-block-iframe"
sandbox="allow-scripts"
scrolling="false"
.srcdoc="${this.model.html}"
></iframe>`;
});
}
}

declare global {
interface HTMLElementTagNameMap {
'affine-embed-html-block': EmbedHtmlBlock;
}
}
10 changes: 10 additions & 0 deletions packages/blocks/src/embed-html-block/embed-html-model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { EmbedBlockModel } from '../_common/embed-block-helper/index.js';
import { EdgelessSelectableMixin } from '../surface-block/elements/selectable.js';

export type EmbedHtmlBlockProps = {
html?: string;
design?: string;
};

@EdgelessSelectableMixin
export class EmbedHtmlBlockModel extends EmbedBlockModel<EmbedHtmlBlockProps> {}
5 changes: 5 additions & 0 deletions packages/blocks/src/embed-html-block/embed-html-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { BlockService } from '@blocksuite/block-std';

import type { EmbedHtmlBlockModel } from './embed-html-model.js';

export class EmbedHtmlService extends BlockService<EmbedHtmlBlockModel> {}
16 changes: 16 additions & 0 deletions packages/blocks/src/embed-html-block/embed-html-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { literal } from 'lit/static-html.js';

import { createEmbedBlock } from '../_common/embed-block-helper/index.js';
import { EmbedHtmlBlockModel } from './embed-html-model.js';

export const EmbedHtmlBlockSpec = createEmbedBlock({
schema: {
name: 'html',
version: 1,
toModel: () => new EmbedHtmlBlockModel(),
props: () => ({}),
},
view: {
component: literal`affine-embed-html-block`,
},
});
12 changes: 11 additions & 1 deletion packages/blocks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import './surface-block/index.js';
import './database-block/index.js';
import './surface-ref-block/index.js';

import { matchFlavours } from './_common/utils/index.js';
import { splitElements } from './page-block/edgeless/utils/clipboard-utils.js';

export * from './_common/adapters/index.js';
export * from './_common/components/index.js';
export * from './_common/consts.js';
Expand All @@ -37,6 +40,10 @@ export * from './code-block/index.js';
export * from './data-view-block/index.js';
export * from './database-block/index.js';
export * from './divider-block/index.js';
export * from './embed-html-block/embed-html-block.js';
export * from './embed-html-block/embed-html-model.js';
export * from './embed-html-block/embed-html-service.js';
export * from './embed-html-block/embed-html-spec.js';
export * from './frame-block/index.js';
export * from './image-block/index.js';
export * from './list-block/index.js';
Expand All @@ -49,7 +56,10 @@ export * from './surface-block/surface-block.js';
export * from './surface-block/surface-model.js';
export * from './surface-block/surface-service.js';
export * from './surface-ref-block/index.js';

export const BlocksUtils = {
splitElements,
matchFlavours,
};
const env: Record<string, unknown> =
typeof globalThis !== 'undefined'
? globalThis
Expand Down
2 changes: 2 additions & 0 deletions packages/blocks/src/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { DatabaseBlockSchema } from './database-block/database-model.js';
import type { DividerBlockModel } from './divider-block/divider-model.js';
import { DividerBlockSchema } from './divider-block/divider-model.js';
import { EmbedGithubBlockSpec } from './embed-github-block/index.js';
import { EmbedHtmlBlockSpec } from './embed-html-block/embed-html-spec.js';
import type { FrameBlockModel } from './frame-block/frame-model.js';
import { FrameBlockSchema } from './frame-block/frame-model.js';
import type { ImageBlockModel } from './image-block/image-model.js';
Expand Down Expand Up @@ -74,6 +75,7 @@ export const __unstableSchemas = [
DataViewBlockSchema,
AttachmentBlockSchema,
EmbedGithubBlockSpec.schema,
EmbedHtmlBlockSpec.schema,
] satisfies z.infer<typeof BlockSchema>[];

// TODO support dynamic register
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,11 @@ import {
SendToBackIcon,
} from '../../../../_common/icons/index.js';
import { type ReorderingType } from '../../../../_common/utils/index.js';
import { groupBy } from '../../../../_common/utils/iterable.js';
import type { FrameBlockModel } from '../../../../frame-block/index.js';
import type { ImageBlockModel } from '../../../../models.js';
import type { NoteBlockModel } from '../../../../note-block/index.js';
import { type CanvasElement } from '../../../../surface-block/index.js';
import { getElementsWithoutGroup } from '../../../../surface-block/managers/group-manager.js';
import type { EdgelessPageBlockComponent } from '../../edgeless-page-block.js';
import { removeContainedFrames } from '../../frame-manager.js';
import { duplicate } from '../../utils/clipboard-utils.js';
import { duplicate, splitElements } from '../../utils/clipboard-utils.js';
import { deleteElements } from '../../utils/crud.js';
import { isFrameBlock, isImageBlock, isNoteBlock } from '../../utils/query.js';
import { isFrameBlock } from '../../utils/query.js';
import { createButtonPopper } from '../utils.js';

type Action =
Expand Down Expand Up @@ -191,35 +185,6 @@ export class EdgelessMoreButton extends WithDisposable(LitElement) {
get surface() {
return this.edgeless.surface;
}

private _splitElements() {
const { notes, frames, shapes, images } = groupBy(
getElementsWithoutGroup(this.selection.elements),
element => {
if (isNoteBlock(element)) {
return 'notes';
} else if (isFrameBlock(element)) {
return 'frames';
} else if (isImageBlock(element)) {
return 'images';
}
return 'shapes';
}
) as {
notes: NoteBlockModel[];
shapes: CanvasElement[];
frames: FrameBlockModel[];
images: ImageBlockModel[];
};

return {
notes: notes ?? [],
shapes: shapes ?? [],
frames: frames ?? [],
images: images ?? [],
};
}

private _delete() {
this.page.captureSync();
deleteElements(this.surface, this.selection.elements);
Expand All @@ -246,8 +211,9 @@ export class EdgelessMoreButton extends WithDisposable(LitElement) {
break;
}
case 'copy-as-png': {
const { notes, frames, shapes, images } = this._splitElements();

const { notes, frames, shapes, images } = splitElements(
this.selection.elements
);
this.slots.copyAsPng.emit({
blocks: [...notes, ...removeContainedFrames(frames), ...images],
shapes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,10 @@ export class EdgelessPageBlockComponent extends BlockElement<
private _initElementSlot() {
this._disposables.add(
this.page.slots.blockUpdated.on(event => {
if (![IMAGE, NOTE, FRAME].includes(event.flavour as EdgelessBlockType))
if (
![IMAGE, NOTE, FRAME].includes(event.flavour as EdgelessBlockType) &&
!/affine:embed-*/.test(event.flavour)
)
return;

if (event.flavour === IMAGE) {
Expand Down
Loading

2 comments on commit fde4ce0

@vercel
Copy link

@vercel vercel bot commented on fde4ce0 Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

blocksuite – ./packages/playground

try-blocksuite.vercel.app
blocksuite-git-master-toeverything.vercel.app
blocksuite-toeverything.vercel.app

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Size Report

Bundles

Entry Size Gzip Brotli
examples/basic 13.1 MB (+222 kB) 2.6 MB (+44.2 kB) 1.63 MB (+31.6 kB)

Packages

Name Size Gzip Brotli
blocks 1.74 MB (+2.32 kB) 437 kB (+536 B) 329 kB (+403 B)
editor 84 B 89 B 63 B
store 61.6 kB (+44 B) 17.9 kB (+20 B) 15.9 kB (+11 B)
virgo 31.3 kB 8.81 kB 7.91 kB

Please sign in to comment.