snapshot of https://github.com/toeverything/AFFiNE.git (canary, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Build & Test / Analyze (javascript, affine) (push) Failing after 4s
Build & Test / Analyze (typescript, affine) (push) Failing after 3s
Build & Test / Rust test filter (push) Failing after 4s
Build & Test / Check yarn binary (push) Failing after 3s
Build & Test / E2E BlockSuite Test (3) (push) Failing after 3s
Build & Test / Analyze (javascript, blocksuite) (push) Failing after 3s
Build & Test / Analyze (typescript, blocksuite) (push) Failing after 3s
Build & Test / Mobile native build filter (push) Failing after 3s
Build & Test / E2E BlockSuite Test (1) (push) Failing after 4s
Build & Test / E2E BlockSuite Test (2) (push) Failing after 4s
Build & Test / E2E Mobile Test (1) (push) Failing after 3s
Build & Test / Unit Test (1) (push) Has been skipped
Build & Test / Unit Test (2) (push) Has been skipped
Build & Test / Unit Test (3) (push) Has been skipped
Build & Test / Unit Test (4) (push) Has been skipped
Build & Test / Unit Test (5) (push) Has been skipped
Build & Test / Native Unit Test (push) Has been skipped
Build & Test / E2E BlockSuite Test (4) (push) Failing after 3s
Build & Test / E2E BlockSuite Test (5) (push) Failing after 3s
Build & Test / E2E BlockSuite Cross Browser Test (push) Failing after 3s
Build & Test / E2E Mobile Test (2) (push) Failing after 3s
Build & Test / Build AFFiNE native (x86_64-unknown-linux-gnu) (push) Failing after 3s
Build & Test / Build Server native (push) Failing after 3s
Build & Test / Check Git Status (push) Has been skipped
Build & Test / Server Test (0, 4) (push) Has been skipped
Build & Test / Server Test (1, 4) (push) Has been skipped
Build & Test / Server Test (2, 4) (push) Has been skipped
Build & Test / Server Test (3, 4) (push) Has been skipped
Build & Test / Server Test with Elasticsearch (push) Has been skipped
Build & Test / Build @affine/electron renderer (push) Failing after 3s
Build & Test / Copilot test filter (push) Failing after 4s
Build & Test / Lint Rust (push) Has been skipped
Build & Test / Server Test with Embedded Search (push) Has been skipped
Build & Test / Server Test with Manticore Search (push) Has been skipped
Build & Test / Server E2E Test (push) Has been skipped
Build & Test / Cloud Desktop E2E Test (push) Has been skipped
Build & Test / Cloud E2E Test 1/2 (push) Has been skipped
Build & Test / Cloud E2E Test 2/2 (push) Has been skipped
Build & Test / Build Android app (push) Has been skipped
Build & Test / Test Android app (push) Has been skipped
Build & Test / Run native tests (push) Has been skipped
Build & Test / Server Copilot Api Test (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (1, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (2, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (3, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (4, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (5, 5) (push) Has been skipped
Release / Canary Gate (push) Has been skipped
Build & Test / Build AFFiNE native (aarch64-apple-darwin) (push) Has been cancelled
Build & Test / Lint (push) Has been cancelled
Build & Test / Typecheck (push) Has been cancelled
Build & Test / Build AFFiNE native (x86_64-apple-darwin) (push) Has been cancelled
Build & Test / Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true) (push) Has been cancelled
Build & Test / Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true) (push) Has been cancelled
Build & Test / E2E Test (1) (push) Has been cancelled
Build & Test / E2E Test (2) (push) Has been cancelled
Build & Test / E2E Test (3) (push) Has been cancelled
Build & Test / E2E Test (4) (push) Has been cancelled
Build & Test / E2E Test (5) (push) Has been cancelled
Build & Test / Build AFFiNE native (aarch64-pc-windows-msvc) (push) Has been cancelled
Build & Test / Build AFFiNE native (x86_64-pc-windows-msvc) (push) Has been cancelled
Build & Test / Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true) (push) Has been cancelled
Build & Test / Desktop Test (macos-latest, macos, x64, x86_64-apple-darwin, false) (push) Has been cancelled
Build & Test / 3, 2, 1 Launch (push) Has been cancelled
Build & Test / Build iOS app (push) Has been cancelled
Copilot Test Automatically / Setup Test (push) Failing after 1s
Release / Prepare (push) Failing after 1s
Release / Release Cloud (push) Has been skipped
Release / Release Desktop (push) Has been skipped
Release / Release Mobile (push) Has been skipped
Release / Release Docker Image (push) Has been skipped
Some checks failed
Build & Test / Analyze (javascript, affine) (push) Failing after 4s
Build & Test / Analyze (typescript, affine) (push) Failing after 3s
Build & Test / Rust test filter (push) Failing after 4s
Build & Test / Check yarn binary (push) Failing after 3s
Build & Test / E2E BlockSuite Test (3) (push) Failing after 3s
Build & Test / Analyze (javascript, blocksuite) (push) Failing after 3s
Build & Test / Analyze (typescript, blocksuite) (push) Failing after 3s
Build & Test / Mobile native build filter (push) Failing after 3s
Build & Test / E2E BlockSuite Test (1) (push) Failing after 4s
Build & Test / E2E BlockSuite Test (2) (push) Failing after 4s
Build & Test / E2E Mobile Test (1) (push) Failing after 3s
Build & Test / Unit Test (1) (push) Has been skipped
Build & Test / Unit Test (2) (push) Has been skipped
Build & Test / Unit Test (3) (push) Has been skipped
Build & Test / Unit Test (4) (push) Has been skipped
Build & Test / Unit Test (5) (push) Has been skipped
Build & Test / Native Unit Test (push) Has been skipped
Build & Test / E2E BlockSuite Test (4) (push) Failing after 3s
Build & Test / E2E BlockSuite Test (5) (push) Failing after 3s
Build & Test / E2E BlockSuite Cross Browser Test (push) Failing after 3s
Build & Test / E2E Mobile Test (2) (push) Failing after 3s
Build & Test / Build AFFiNE native (x86_64-unknown-linux-gnu) (push) Failing after 3s
Build & Test / Build Server native (push) Failing after 3s
Build & Test / Check Git Status (push) Has been skipped
Build & Test / Server Test (0, 4) (push) Has been skipped
Build & Test / Server Test (1, 4) (push) Has been skipped
Build & Test / Server Test (2, 4) (push) Has been skipped
Build & Test / Server Test (3, 4) (push) Has been skipped
Build & Test / Server Test with Elasticsearch (push) Has been skipped
Build & Test / Build @affine/electron renderer (push) Failing after 3s
Build & Test / Copilot test filter (push) Failing after 4s
Build & Test / Lint Rust (push) Has been skipped
Build & Test / Server Test with Embedded Search (push) Has been skipped
Build & Test / Server Test with Manticore Search (push) Has been skipped
Build & Test / Server E2E Test (push) Has been skipped
Build & Test / Cloud Desktop E2E Test (push) Has been skipped
Build & Test / Cloud E2E Test 1/2 (push) Has been skipped
Build & Test / Cloud E2E Test 2/2 (push) Has been skipped
Build & Test / Build Android app (push) Has been skipped
Build & Test / Test Android app (push) Has been skipped
Build & Test / Run native tests (push) Has been skipped
Build & Test / Server Copilot Api Test (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (1, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (2, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (3, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (4, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (5, 5) (push) Has been skipped
Release / Canary Gate (push) Has been skipped
Build & Test / Build AFFiNE native (aarch64-apple-darwin) (push) Has been cancelled
Build & Test / Lint (push) Has been cancelled
Build & Test / Typecheck (push) Has been cancelled
Build & Test / Build AFFiNE native (x86_64-apple-darwin) (push) Has been cancelled
Build & Test / Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true) (push) Has been cancelled
Build & Test / Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true) (push) Has been cancelled
Build & Test / E2E Test (1) (push) Has been cancelled
Build & Test / E2E Test (2) (push) Has been cancelled
Build & Test / E2E Test (3) (push) Has been cancelled
Build & Test / E2E Test (4) (push) Has been cancelled
Build & Test / E2E Test (5) (push) Has been cancelled
Build & Test / Build AFFiNE native (aarch64-pc-windows-msvc) (push) Has been cancelled
Build & Test / Build AFFiNE native (x86_64-pc-windows-msvc) (push) Has been cancelled
Build & Test / Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true) (push) Has been cancelled
Build & Test / Desktop Test (macos-latest, macos, x64, x86_64-apple-darwin, false) (push) Has been cancelled
Build & Test / 3, 2, 1 Launch (push) Has been cancelled
Build & Test / Build iOS app (push) Has been cancelled
Copilot Test Automatically / Setup Test (push) Failing after 1s
Release / Prepare (push) Failing after 1s
Release / Release Cloud (push) Has been skipped
Release / Release Desktop (push) Has been skipped
Release / Release Mobile (push) Has been skipped
Release / Release Docker Image (push) Has been skipped
This commit is contained in:
246
blocksuite/affine/fragments/outline/src/card/outline-preview.ts
Normal file
246
blocksuite/affine/fragments/outline/src/card/outline-preview.ts
Normal file
@@ -0,0 +1,246 @@
|
||||
import type {
|
||||
AttachmentBlockModel,
|
||||
BookmarkBlockModel,
|
||||
CodeBlockModel,
|
||||
DatabaseBlockModel,
|
||||
ImageBlockModel,
|
||||
ListBlockModel,
|
||||
ParagraphBlockModel,
|
||||
RootBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { DocDisplayMetaProvider } from '@blocksuite/affine-shared/services';
|
||||
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit';
|
||||
import { noop } from '@blocksuite/global/utils';
|
||||
import { LinkedPageIcon } from '@blocksuite/icons/lit';
|
||||
import { ShadowlessElement } from '@blocksuite/std';
|
||||
import type { BlockModel, DeltaInsert } from '@blocksuite/store';
|
||||
import { consume } from '@lit/context';
|
||||
import { html, nothing } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
|
||||
import {
|
||||
placeholderMap,
|
||||
previewIconMap,
|
||||
type TocContext,
|
||||
tocContext,
|
||||
} from '../config.js';
|
||||
import { isHeadingBlock, isRootBlock } from '../utils/query.js';
|
||||
import * as styles from './outline-preview.css';
|
||||
|
||||
function assertType<T>(value: unknown): asserts value is T {
|
||||
noop(value);
|
||||
}
|
||||
|
||||
export const AFFINE_OUTLINE_BLOCK_PREVIEW = 'affine-outline-block-preview';
|
||||
|
||||
export class OutlineBlockPreview extends SignalWatcher(
|
||||
WithDisposable(ShadowlessElement)
|
||||
) {
|
||||
private get _docDisplayMetaService() {
|
||||
return this._context.editor$.value.std.get(DocDisplayMetaProvider);
|
||||
}
|
||||
|
||||
private _TextBlockPreview(block: ParagraphBlockModel | ListBlockModel) {
|
||||
const deltas: DeltaInsert<AffineTextAttributes>[] =
|
||||
block.props.text.yText.toDelta();
|
||||
if (!block.props.text.length) return nothing;
|
||||
const iconClass = this.disabledIcon ? styles.iconDisabled : styles.icon;
|
||||
|
||||
const previewText = deltas.map(delta => {
|
||||
if (delta.attributes?.reference) {
|
||||
// If linked doc, render linked doc icon and the doc title.
|
||||
const refAttribute = delta.attributes.reference;
|
||||
const refMeta = block.store.workspace.meta.docMetas.find(
|
||||
doc => doc.id === refAttribute.pageId
|
||||
);
|
||||
const unavailable = !refMeta;
|
||||
|
||||
const icon = unavailable
|
||||
? LinkedPageIcon({ width: '1.1em', height: '1.1em' })
|
||||
: this._docDisplayMetaService.icon(refMeta.id).value;
|
||||
const title = unavailable
|
||||
? 'Deleted doc'
|
||||
: this._docDisplayMetaService.title(refMeta.id).value;
|
||||
|
||||
return html`<span
|
||||
class=${classMap({
|
||||
[styles.linkedDocPreviewUnavailable]: unavailable,
|
||||
[styles.linkedDocPreviewAvailable]: !unavailable,
|
||||
})}
|
||||
>
|
||||
${icon}
|
||||
<span
|
||||
class=${classMap({
|
||||
[styles.linkedDocText]: true,
|
||||
[styles.linkedDocTextUnavailable]: unavailable,
|
||||
})}
|
||||
>${title.length ? title : 'Untitled'}</span
|
||||
></span
|
||||
>`;
|
||||
} else {
|
||||
// If not linked doc, render the text.
|
||||
return delta.insert.toString().trim().length > 0
|
||||
? html`<span class=${styles.textSpan}
|
||||
>${delta.insert.toString()}</span
|
||||
>`
|
||||
: nothing;
|
||||
}
|
||||
});
|
||||
|
||||
const headingClass =
|
||||
block.props.type in styles.subtypeStyles
|
||||
? styles.subtypeStyles[
|
||||
block.props.type as keyof typeof styles.subtypeStyles
|
||||
]
|
||||
: '';
|
||||
|
||||
return html`<span
|
||||
data-testid="outline-block-preview-${block.props.type}"
|
||||
class="${styles.text} ${styles.textGeneral} ${headingClass}"
|
||||
>${previewText}</span
|
||||
>
|
||||
${
|
||||
this._context.showIcons$.value
|
||||
? html`<span class=${iconClass}
|
||||
>${previewIconMap[block.props.type]}</span
|
||||
>`
|
||||
: nothing
|
||||
}`;
|
||||
}
|
||||
|
||||
override render() {
|
||||
return html`<div class=${styles.outlineBlockPreview}>
|
||||
${this.renderBlockByFlavour()}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
renderBlockByFlavour() {
|
||||
const { block } = this;
|
||||
const iconClass = this.disabledIcon ? styles.iconDisabled : styles.icon;
|
||||
|
||||
if (
|
||||
!this._context.enableSorting$.value &&
|
||||
!isHeadingBlock(block) &&
|
||||
!isRootBlock(block)
|
||||
)
|
||||
return nothing;
|
||||
|
||||
const showPreviewIcon = this._context.showIcons$.value;
|
||||
|
||||
switch (block.flavour) {
|
||||
case 'affine:page':
|
||||
assertType<RootBlockModel>(block);
|
||||
return block.props.title.length > 0
|
||||
? html`<span
|
||||
data-testid="outline-block-preview-title"
|
||||
class="${styles.text} ${styles.subtypeStyles.title}"
|
||||
>
|
||||
${block.props.title$.value}
|
||||
</span>`
|
||||
: nothing;
|
||||
case 'affine:paragraph':
|
||||
assertType<ParagraphBlockModel>(block);
|
||||
return this._TextBlockPreview(block);
|
||||
case 'affine:list':
|
||||
assertType<ListBlockModel>(block);
|
||||
return this._TextBlockPreview(block);
|
||||
case 'affine:bookmark':
|
||||
assertType<BookmarkBlockModel>(block);
|
||||
return html`
|
||||
<span class="${styles.text} ${styles.textGeneral}"
|
||||
>${
|
||||
block.props.title || block.props.url || placeholderMap['bookmark']
|
||||
}</span
|
||||
>
|
||||
${
|
||||
showPreviewIcon
|
||||
? html`<span class=${iconClass}
|
||||
>${previewIconMap['bookmark']}</span
|
||||
>`
|
||||
: nothing
|
||||
}
|
||||
`;
|
||||
case 'affine:code':
|
||||
assertType<CodeBlockModel>(block);
|
||||
return html`
|
||||
<span class="${styles.text} ${styles.textGeneral}"
|
||||
>${block.props.language ?? placeholderMap['code']}</span
|
||||
>
|
||||
${
|
||||
showPreviewIcon
|
||||
? html`<span class=${iconClass}>${previewIconMap['code']}</span>`
|
||||
: nothing
|
||||
}
|
||||
`;
|
||||
case 'affine:database':
|
||||
assertType<DatabaseBlockModel>(block);
|
||||
return html`
|
||||
<span class="${styles.text} ${styles.textGeneral}"
|
||||
>${
|
||||
block.props.title.toString().length
|
||||
? block.props.title.toString()
|
||||
: placeholderMap['database']
|
||||
}</span
|
||||
>
|
||||
${
|
||||
showPreviewIcon
|
||||
? html`<span class=${iconClass}>${previewIconMap['table']}</span>`
|
||||
: nothing
|
||||
}
|
||||
`;
|
||||
case 'affine:image':
|
||||
assertType<ImageBlockModel>(block);
|
||||
return html`
|
||||
<span class="${styles.text} ${styles.textGeneral}"
|
||||
>${
|
||||
block.props.caption?.length
|
||||
? block.props.caption
|
||||
: placeholderMap['image']
|
||||
}</span
|
||||
>
|
||||
${
|
||||
showPreviewIcon
|
||||
? html`<span class=${iconClass}>${previewIconMap['image']}</span>`
|
||||
: nothing
|
||||
}
|
||||
`;
|
||||
case 'affine:attachment':
|
||||
assertType<AttachmentBlockModel>(block);
|
||||
return html`
|
||||
<span class="${styles.text} ${styles.textGeneral}"
|
||||
>${
|
||||
block.props.name?.length
|
||||
? block.props.name
|
||||
: placeholderMap['attachment']
|
||||
}</span
|
||||
>
|
||||
${
|
||||
showPreviewIcon
|
||||
? html`<span class=${iconClass}
|
||||
>${previewIconMap['attachment']}</span
|
||||
>`
|
||||
: nothing
|
||||
}
|
||||
`;
|
||||
default:
|
||||
return nothing;
|
||||
}
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor block!: BlockModel;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor disabledIcon = false;
|
||||
|
||||
@consume({ context: tocContext })
|
||||
private accessor _context!: TocContext;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[AFFINE_OUTLINE_BLOCK_PREVIEW]: OutlineBlockPreview;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user