Skip to content

Commit

Permalink
fix: duplication occurs when card view is switched to embed view
Browse files Browse the repository at this point in the history
  • Loading branch information
akumatus committed Sep 20, 2024
1 parent fa30673 commit 3bfc438
Show file tree
Hide file tree
Showing 7 changed files with 399 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import {
} from '@blocksuite/affine-shared/services';
import { getHostName } from '@blocksuite/affine-shared/utils';
import { WidgetComponent } from '@blocksuite/block-std';
import { assertExists } from '@blocksuite/global/utils';
import { type BlockModel, DocCollection } from '@blocksuite/store';
import { autoUpdate, computePosition, flip, offset } from '@floating-ui/dom';
import { html, nothing, type TemplateResult } from 'lit';
Expand Down Expand Up @@ -260,7 +259,8 @@ export class EmbedCardToolbar extends WidgetComponent<
return;
}

const { doc, url, style, caption } = this.focusModel;
const targetModel = this.focusModel;
const { doc, url, style, caption } = targetModel;

let targetFlavour = 'affine:bookmark',
targetStyle = style;
Expand All @@ -277,9 +277,9 @@ export class EmbedCardToolbar extends WidgetComponent<
)[0];
}

const parent = doc.getParent(this.focusModel);
assertExists(parent);
const index = parent.children.indexOf(this.focusModel);
const parent = doc.getParent(targetModel);
if (!parent) return;
const index = parent.children.indexOf(targetModel);

doc.addBlock(
targetFlavour as never,
Expand All @@ -288,7 +288,7 @@ export class EmbedCardToolbar extends WidgetComponent<
index
);
this.std.selection.setGroup('note', []);
doc.deleteBlock(this.focusModel);
doc.deleteBlock(targetModel);
}

private _convertToEmbedView() {
Expand All @@ -309,7 +309,8 @@ export class EmbedCardToolbar extends WidgetComponent<
return;
}

const { doc, url, style, caption } = this.focusModel;
const targetModel = this.focusModel;
const { doc, url, style, caption } = targetModel;

if (!this._embedOptions || this._embedOptions.viewType !== 'embed') {
return;
Expand All @@ -320,9 +321,9 @@ export class EmbedCardToolbar extends WidgetComponent<
? style
: styles.filter(style => style !== 'vertical' && style !== 'cube')[0];

const parent = doc.getParent(this.focusModel);
assertExists(parent);
const index = parent.children.indexOf(this.focusModel);
const parent = doc.getParent(targetModel);
if (!parent) return;
const index = parent.children.indexOf(targetModel);

doc.addBlock(
flavour as never,
Expand All @@ -332,7 +333,7 @@ export class EmbedCardToolbar extends WidgetComponent<
);

this.std.selection.setGroup('note', []);
doc.deleteBlock(this.focusModel);
doc.deleteBlock(targetModel);
}

private _copyUrl() {
Expand Down Expand Up @@ -478,15 +479,15 @@ export class EmbedCardToolbar extends WidgetComponent<
return;
}

const { doc } = this.focusModel;
const parent = doc.getParent(this.focusModel);
const index = parent?.children.indexOf(this.focusModel);
const targetModel = this.focusModel;
const { doc, title, caption, url } = targetModel;
const parent = doc.getParent(targetModel);
const index = parent?.children.indexOf(targetModel);

const yText = new DocCollection.Y.Text();
const insert =
this.focusModel.title || this.focusModel.caption || this.focusModel.url;
const insert = title || caption || url;
yText.insert(0, insert);
yText.format(0, insert.length, { link: this.focusModel.url });
yText.format(0, insert.length, { link: url });
const text = new doc.Text(yText);
doc.addBlock(
'affine:paragraph',
Expand All @@ -497,7 +498,7 @@ export class EmbedCardToolbar extends WidgetComponent<
index
);

doc.deleteBlock(this.focusModel);
doc.deleteBlock(targetModel);
}

private _viewMenuButton() {
Expand Down
137 changes: 127 additions & 10 deletions tests/bookmark.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import type { Page } from '@playwright/test';
import type { BlockSnapshot } from '@store/index.js';

import { expect } from '@playwright/test';
import { ignoreSnapshotId } from 'utils/ignore.js';
import { getEmbedCardToolbar } from 'utils/query.js';

import {
activeNoteInEdgeless,
copyByKeyboard,
dragBlockToPoint,
enterPlaygroundRoom,
expectConsoleMessage,
focusRichText,
getPageSnapshot,
initEmptyEdgelessState,
Expand Down Expand Up @@ -41,7 +44,11 @@ import {
import './utils/declare-test-window.js';
import { scoped, test } from './utils/playwright.js';

const inputUrl = 'http://localhost';
const LOCAL_HOST_URL = 'http://localhost';

const YOUTUBE_URL = 'https://www.youtube.com/watch?v=fakeid';

const FIGMA_URL = 'https://www.figma.com/design/JuXs6uOAICwf4I4tps0xKZ123';

test.beforeEach(async ({ page }) => {
await page.route(
Expand All @@ -54,15 +61,18 @@ test.beforeEach(async ({ page }) => {
);
});

const createBookmarkBlockBySlashMenu = async (page: Page) => {
const createBookmarkBlockBySlashMenu = async (
page: Page,
url = LOCAL_HOST_URL
) => {
await enterPlaygroundRoom(page);
await initEmptyParagraphState(page);
await focusRichText(page);
await page.waitForTimeout(100);
await type(page, '/link', 100);
await pressEnter(page);
await page.waitForTimeout(100);
await type(page, inputUrl);
await type(page, url);
await pressEnter(page);
};

Expand Down Expand Up @@ -92,8 +102,8 @@ test(
await initEmptyParagraphState(page);
await focusRichText(page);

await type(page, inputUrl);
await setInlineRangeInSelectedRichText(page, 0, inputUrl.length);
await type(page, LOCAL_HOST_URL);
await setInlineRangeInSelectedRichText(page, 0, LOCAL_HOST_URL.length);
await copyByKeyboard(page);
await focusRichText(page);
await type(page, '/link');
Expand All @@ -112,7 +122,7 @@ test(
await enterPlaygroundRoom(page);
const ids = await initEmptyEdgelessState(page);
await focusRichText(page);
await type(page, inputUrl);
await type(page, LOCAL_HOST_URL);

await switchEditorMode(page);

Expand Down Expand Up @@ -203,7 +213,7 @@ test('press backspace after bookmark block can select bookmark block', async ({
await type(page, '/link');
await pressEnter(page);
await page.waitForTimeout(100);
await type(page, inputUrl);
await type(page, LOCAL_HOST_URL);
await pressEnter(page);

await focusRichText(page);
Expand Down Expand Up @@ -273,7 +283,7 @@ test('indent bookmark block to paragraph', async ({ page }) => {
await pressEnter(page);
await type(page, '/link', 100);
await pressEnter(page);
await type(page, inputUrl);
await type(page, LOCAL_HOST_URL);
await pressEnter(page);

await assertBlockChildrenIds(page, '1', ['2', '4']);
Expand Down Expand Up @@ -301,7 +311,7 @@ test('indent bookmark block to list', async ({ page }) => {
await pressEnter(page);
await type(page, '/link', 100);
await pressEnter(page);
await type(page, inputUrl);
await type(page, LOCAL_HOST_URL);
await pressEnter(page);

await assertBlockChildrenIds(page, '1', ['3', '5']);
Expand Down Expand Up @@ -330,7 +340,7 @@ test('bookmark can be dragged from note to surface top level block', async ({
await type(page, '/link', 100);
await pressEnter(page);
await page.waitForTimeout(100);
await type(page, inputUrl);
await type(page, LOCAL_HOST_URL);
await pressEnter(page);

await switchEditorMode(page);
Expand All @@ -341,3 +351,110 @@ test('bookmark can be dragged from note to surface top level block', async ({
await waitNextFrame(page);
await assertParentBlockFlavour(page, '5', 'affine:surface');
});

test.describe('embed youtube card', () => {
test(scoped`create youtube card by slash menu`, async ({ page }) => {
expectConsoleMessage(page, /Unrecognized feature/, 'warning');
expectConsoleMessage(page, /Failed to load resource/);
await createBookmarkBlockBySlashMenu(page, YOUTUBE_URL);
const snapshot = (await getPageSnapshot(page)) as BlockSnapshot;
expect(ignoreSnapshotId(snapshot)).toMatchSnapshot('embed-youtube.json');
});

test(scoped`change youtube card style`, async ({ page }) => {
expectConsoleMessage(page, /Unrecognized feature/, 'warning');
expectConsoleMessage(page, /Failed to load resource/);

await createBookmarkBlockBySlashMenu(page, YOUTUBE_URL);
const youtube = page.locator('affine-embed-youtube-block');
await youtube.click();
await page.waitForTimeout(100);

// change to card view
const embedToolbar = page.locator('affine-embed-card-toolbar');
await expect(embedToolbar).toBeVisible();
const embedView = page.locator('editor-menu-button', {
hasText: 'embed view',
});
await expect(embedView).toBeVisible();
await embedView.click();
const cardView = page.locator('editor-menu-action', {
hasText: 'card view',
});
await expect(cardView).toBeVisible();
await cardView.click();
const snapshot = (await getPageSnapshot(page)) as BlockSnapshot;
expect(ignoreSnapshotId(snapshot)).toMatchSnapshot(
'horizontal-youtube.json'
);

// change to embed view
const bookmark = page.locator('affine-bookmark');
await bookmark.click();
await page.waitForTimeout(100);
const cardView2 = page.locator('editor-icon-button', {
hasText: 'card view',
});
await expect(cardView2).toBeVisible();
await cardView2.click();
const embedView2 = page.locator('editor-menu-action', {
hasText: 'embed view',
});
await expect(embedView2).toBeVisible();
await embedView2.click();
const snapshot2 = (await getPageSnapshot(page)) as BlockSnapshot;
expect(ignoreSnapshotId(snapshot2)).toMatchSnapshot('embed-youtube.json');
});
});

test.describe('embed figma card', () => {
test(scoped`create figma card by slash menu`, async ({ page }) => {
expectConsoleMessage(page, /Failed to load resource/);
expectConsoleMessage(page, /Refused to frame/);
await createBookmarkBlockBySlashMenu(page, FIGMA_URL);
const snapshot = (await getPageSnapshot(page)) as BlockSnapshot;
expect(ignoreSnapshotId(snapshot)).toMatchSnapshot('embed-figma.json');
});

test(scoped`change figma card style`, async ({ page }) => {
expectConsoleMessage(page, /Failed to load resource/);
expectConsoleMessage(page, /Refused to frame/);
await createBookmarkBlockBySlashMenu(page, FIGMA_URL);
const youtube = page.locator('affine-embed-figma-block');
await youtube.click();
await page.waitForTimeout(100);

// change to card view
const embedToolbar = page.locator('affine-embed-card-toolbar');
await expect(embedToolbar).toBeVisible();
const embedView = page.locator('editor-menu-button', {
hasText: 'embed view',
});
await expect(embedView).toBeVisible();
await embedView.click();
const cardView = page.locator('editor-menu-action', {
hasText: 'card view',
});
await expect(cardView).toBeVisible();
await cardView.click();
const snapshot = (await getPageSnapshot(page)) as BlockSnapshot;
expect(ignoreSnapshotId(snapshot)).toMatchSnapshot('horizontal-figma.json');

// change to embed view
const bookmark = page.locator('affine-bookmark');
await bookmark.click();
await page.waitForTimeout(100);
const cardView2 = page.locator('editor-icon-button', {
hasText: 'card view',
});
await expect(cardView2).toBeVisible();
await cardView2.click();
const embedView2 = page.locator('editor-menu-action', {
hasText: 'embed view',
});
await expect(embedView2).toBeVisible();
await embedView2.click();
const snapshot2 = (await getPageSnapshot(page)) as BlockSnapshot;
expect(ignoreSnapshotId(snapshot2)).toMatchSnapshot('embed-figma.json');
});
});
54 changes: 54 additions & 0 deletions tests/snapshots/bookmark.spec.ts/embed-figma.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"type": "block",
"id": "*",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "*",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,800,95]",
"background": "--affine-note-background-white",
"index": "a0",
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "*",
"flavour": "affine:embed-figma",
"version": 1,
"props": {
"index": "a0",
"xywh": "[0,0,0,0]",
"rotate": 0,
"style": "figma",
"url": "https://www.figma.com/design/JuXs6uOAICwf4I4tps0xKZ123",
"caption": null,
"title": "Figma",
"description": "https://www.figma.com/design/JuXs6uOAICwf4I4tps0xKZ123"
},
"children": []
}
]
}
]
}
Loading

0 comments on commit 3bfc438

Please sign in to comment.