Skip to content

Commit

Permalink
feat: linked doc supports aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
fundon committed Dec 5, 2024
1 parent 2fa9d81 commit 22bf05c
Show file tree
Hide file tree
Showing 35 changed files with 1,544 additions and 281 deletions.
2 changes: 1 addition & 1 deletion packages/affine/block-embed/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@blocksuite/affine-shared": "workspace:*",
"@blocksuite/block-std": "workspace:*",
"@blocksuite/global": "workspace:*",
"@blocksuite/icons": "^2.1.70",
"@blocksuite/icons": "^2.1.75",
"@blocksuite/inline": "workspace:*",
"@blocksuite/store": "workspace:*",
"@floating-ui/dom": "^1.6.10",
Expand Down
52 changes: 46 additions & 6 deletions packages/affine/block-embed/src/common/render-linked-doc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ async function renderNoteContent(
card.isNoteContentEmpty = false;

const noteContainer = await card.noteContainer;

if (!noteContainer) {
return;
}

while (noteContainer.firstChild) {
noteContainer.firstChild.remove();
}
Expand Down Expand Up @@ -199,13 +204,10 @@ async function renderNoteContent(
}

function filterTextModel(model: BlockModel) {
if (matchFlavours(model, ['affine:divider'])) {
return true;
}
if (!matchFlavours(model, ['affine:paragraph', 'affine:list'])) {
return false;
if (matchFlavours(model, ['affine:paragraph', 'affine:list'])) {
return !!model.text?.toString().length;
}
return !!model.text?.toString().length;
return false;
}

export function getNotesFromDoc(doc: Doc) {
Expand Down Expand Up @@ -255,3 +257,41 @@ function getSurfaceBlock(doc: Doc) {
const blocks = doc.getBlocksByFlavour('affine:surface');
return blocks.length !== 0 ? (blocks[0].model as SurfaceBlockModel) : null;
}

/**
* Gets the document content with a max length.
*/
export function getDocContentWithMaxLength(doc: Doc, maxlength = 500) {
const notes = getNotesFromDoc(doc);
if (!notes) return;

const noteChildren = notes.flatMap(note =>
note.children.filter(model => filterTextModel(model))
);
if (!noteChildren.length) return;

let count = 0;
let reached = false;
const texts = [];

for (const model of noteChildren) {
let t = model.text?.toString();
if (t?.length) {
const c: number = count + Math.max(0, texts.length - 1);

if (t.length + c > maxlength) {
t = t.substring(0, maxlength - c);
reached = true;
}

texts.push(t);
count += t.length;

if (reached) {
break;
}
}
}

return texts.join('\n');
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ import {
} from '@blocksuite/affine-shared/services';
import { matchFlavours } from '@blocksuite/affine-shared/utils';
import { Bound } from '@blocksuite/global/utils';
import { AliasIcon } from '@blocksuite/icons/lit';
import { DocCollection } from '@blocksuite/store';
import { html, nothing } from 'lit';
import { property, queryAsync, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { styleMap } from 'lit/directives/style-map.js';
import { when } from 'lit/directives/when.js';

import { EmbedBlockComponent } from '../common/embed-block-element.js';
import { renderLinkedDocInCard } from '../common/render-linked-doc.js';
Expand Down Expand Up @@ -198,9 +200,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
}

get docTitle() {
return this.linkedDoc?.meta?.title.length
? this.linkedDoc.meta.title
: 'Untitled';
return this.model.title || this.linkedDoc?.meta?.title || 'Untitled';
}

get editorMode() {
Expand Down Expand Up @@ -322,10 +322,6 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
);
}

override disconnectedCallback() {
super.disconnectedCallback();
}

getInitialState(): {
loading?: boolean;
isError?: boolean;
Expand Down Expand Up @@ -371,17 +367,22 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
? LoadingIcon
: isDeleted
? LinkedDocDeletedIcon
: this._isLinkToNode
? BlockLinkIcon
: LinkedDocIcon;
: this.model.title
? AliasIcon({ width: '16px', height: '16pc' })
: this._isLinkToNode
? BlockLinkIcon
: LinkedDocIcon;

const title = this.docTitle;
const description = this.model.description;

const titleText = isError
? linkedDoc?.meta?.title || 'Untitled'
? title
: isLoading
? 'Loading...'
: isDeleted
? `Deleted doc`
: linkedDoc?.meta?.title || 'Untitled';
: title;

const showDefaultNoteContent = isError || isLoading || isDeleted || isEmpty;
const defaultNoteContent = isError
Expand Down Expand Up @@ -409,6 +410,8 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
? LinkedDocDeletedBanner
: LinkedDocEmptyBanner;

const hasDescription = Boolean(description && description.length > 0);

return this.renderEmbed(
() => html`
<div
Expand All @@ -431,12 +434,27 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
</div>
</div>
<div class="affine-embed-linked-doc-content-note render"></div>
${showDefaultNoteContent
? html`<div class="affine-embed-linked-doc-content-note default">
${defaultNoteContent}
</div>`
: nothing}
${when(
hasDescription,
() =>
html`<div class="affine-embed-linked-doc-content-note alias">
${description}
</div>`,
() =>
when(
showDefaultNoteContent,
() => html`
<div class="affine-embed-linked-doc-content-note default">
${defaultNoteContent}
</div>
`,
() => html`
<div
class="affine-embed-linked-doc-content-note render"
></div>
`
)
)}
${isError
? html`
<div class="affine-embed-linked-doc-card-content-reload">
Expand Down Expand Up @@ -518,5 +536,5 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
accessor isNoteContentEmpty = false;

@queryAsync('.affine-embed-linked-doc-content-note.render')
accessor noteContainer!: Promise<HTMLDivElement>;
accessor noteContainer!: Promise<HTMLDivElement | null>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export const styles = css`
${embedNoteContentStyles}
.affine-embed-linked-doc-content-note.alias,
.affine-embed-linked-doc-content-note.default {
flex: 1;
display: -webkit-box;
Expand All @@ -105,6 +106,10 @@ export const styles = css`
line-height: 20px;
}
.affine-embed-linked-doc-content-note.alias {
color: var(--affine-text-primary-color);
}
.affine-embed-linked-doc-card-content-reload,
.affine-embed-linked-doc-content-date {
display: flex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ import {
} from '@blocksuite/block-std';
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
import { assertExists, Bound, getCommonBound } from '@blocksuite/global/utils';
import { BlockViewType, DocCollection, type Query } from '@blocksuite/store';
import {
BlockViewType,
DocCollection,
type GetDocOptions,
type Query,
} from '@blocksuite/store';
import { html, type PropertyValues } from 'lit';
import { query, state } from 'lit/decorators.js';
import { choose } from 'lit/directives/choose.js';
Expand Down Expand Up @@ -327,9 +332,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
}

get docTitle() {
return this.syncedDoc?.meta?.title.length
? this.syncedDoc.meta.title
: 'Untitled';
return this.syncedDoc?.meta?.title || 'Untitled';
}

get docUpdatedAt() {
Expand All @@ -353,14 +356,9 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
}

get syncedDoc() {
return this.isPageMode
? this.std.collection.getDoc(this.model.pageId, {
readonly: true,
query: this._pageFilter,
})
: this.std.collection.getDoc(this.model.pageId, {
readonly: true,
});
const options: GetDocOptions = { readonly: true };
if (this.isPageMode) options.query = this._pageFilter;
return this.std.collection.getDoc(this.model.pageId, options);
}

private _checkCycle() {
Expand Down
1 change: 1 addition & 0 deletions packages/affine/block-embed/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export {
LinkPreviewer,
type LinkPreviewResponseData,
} from './common/link-previewer.js';
export { getDocContentWithMaxLength } from './common/render-linked-doc.js';
export { toEdgelessEmbedBlock } from './common/to-edgeless-embed-block.js';

export * from './embed-figma-block/index.js';
Expand Down
9 changes: 7 additions & 2 deletions packages/affine/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@blocksuite/affine-shared": "workspace:*",
"@blocksuite/block-std": "workspace:*",
"@blocksuite/global": "workspace:*",
"@blocksuite/icons": "^2.1.70",
"@blocksuite/icons": "^2.1.75",
"@blocksuite/inline": "workspace:*",
"@blocksuite/store": "workspace:*",
"@floating-ui/dom": "^1.6.10",
Expand Down Expand Up @@ -53,7 +53,8 @@
"./date-picker": "./src/date-picker/index.ts",
"./drag-indicator": "./src/drag-indicator/index.ts",
"./virtual-keyboard": "./src/virtual-keyboard/index.ts",
"./toggle-button": "./src/toggle-button/index.ts"
"./toggle-button": "./src/toggle-button/index.ts",
"./notification": "./src/notification/index.ts"
},
"publishConfig": {
"access": "public",
Expand Down Expand Up @@ -115,6 +116,10 @@
"./toggle-button": {
"types": "./dist/toggle-button/index.d.ts",
"import": "./dist/toggle-button/index.js"
},
"./notification": {
"types": "./dist/notification/index.d.ts",
"import": "./dist/notification/index.js"
}
}
},
Expand Down
1 change: 1 addition & 0 deletions packages/affine/components/src/notification/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './linked-doc.js';
71 changes: 71 additions & 0 deletions packages/affine/components/src/notification/linked-doc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import type { BlockStdScope } from '@blocksuite/block-std';

import { NotificationProvider } from '@blocksuite/affine-shared/services';

import { toast } from '../toast/toast.js';

function notify(std: BlockStdScope, title: string, message: string) {
const notification = std.getOptional(NotificationProvider);
const { doc, host } = std;

if (!notification) {
toast(host, title);
return;
}

const abortController = new AbortController();
const clear = () => {
doc.history.off('stack-item-added', addHandler);
doc.history.off('stack-item-popped', popHandler);
disposable.dispose();
};
const closeNotify = () => {
abortController.abort();
clear();
};

// edit or undo or switch doc, close notify toast
const addHandler = doc.history.on('stack-item-added', closeNotify);
const popHandler = doc.history.on('stack-item-popped', closeNotify);
const disposable = host.slots.unmounted.on(closeNotify);

notification.notify({
title,
message,
accent: 'info',
duration: 10 * 1000,
action: {
label: 'Undo',
onClick: () => {
doc.undo();
clear();
},
},
abort: abortController.signal,
onClose: clear,
});
}

export function notifyLinkedDocSwitchedToCard(std: BlockStdScope) {
notify(
std,
'View Updated',
'The alias modification has disabled sync. The embed has been updated to a card view.'
);
}

export function notifyLinkedDocSwitchedToEmbed(std: BlockStdScope) {
notify(
std,
'Embed View Restored',
'Custom alias removed. The linked doc now displays the original title and description.'
);
}

export function notifyLinkedDocClearedAliases(std: BlockStdScope) {
notify(
std,
'Reset successful',
`Card view has been restored to original doc title and description. All custom aliases have been removed.`
);
}
3 changes: 3 additions & 0 deletions packages/affine/components/src/rich-text/effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { LatexEditorMenu } from './inline/presets/nodes/latex-node/latex-editor-
import { LatexEditorUnit } from './inline/presets/nodes/latex-node/latex-editor-unit.js';
import { AffineLatexNode } from './inline/presets/nodes/latex-node/latex-node.js';
import { LinkPopup } from './inline/presets/nodes/link-node/link-popup/link-popup.js';
import { ReferenceAliasPopup } from './inline/presets/nodes/reference-node/reference-alias-popup.js';
import { ReferencePopup } from './inline/presets/nodes/reference-node/reference-popup.js';
import { RichText } from './rich-text.js';

Expand All @@ -35,6 +36,7 @@ export function effects() {
customElements.define('link-popup', LinkPopup);
customElements.define('affine-link', AffineLink);
customElements.define('reference-popup', ReferencePopup);
customElements.define('reference-alias-popup', ReferenceAliasPopup);
customElements.define('affine-reference', AffineReference);
}

Expand All @@ -46,6 +48,7 @@ declare global {
'affine-text': AffineText;
'rich-text': RichText;
'reference-popup': ReferencePopup;
'reference-alias-popup': ReferenceAliasPopup;
'latex-editor-unit': LatexEditorUnit;
'latex-editor-menu': LatexEditorMenu;
'link-popup': LinkPopup;
Expand Down
Loading

0 comments on commit 22bf05c

Please sign in to comment.