mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-15 05:37:32 +00:00
feat(editor): audio block (#10947)
AudioMedia entity for loading & controlling a single audio media AudioMediaManagerService: Global audio state synchronization across tabs AudioAttachmentService + AudioAttachmentBlock for manipulating AttachmentBlock in affine - e.g., filling transcription (using mock endpoint for now) Added AudioBlock + AudioPlayer for rendering audio block in affine (new transcription block whose renderer is provided in affine) fix AF-2292 fix AF-2337
This commit is contained in:
@@ -29,6 +29,7 @@ import {
|
||||
RootBlockSchemaExtension,
|
||||
SurfaceRefBlockSchemaExtension,
|
||||
TableBlockSchemaExtension,
|
||||
TranscriptionBlockSchemaExtension,
|
||||
} from '@blocksuite/affine-model';
|
||||
import {
|
||||
HighlightSelectionExtension,
|
||||
@@ -84,6 +85,7 @@ export const StoreExtensions: ExtensionType[] = [
|
||||
LatexBlockSchemaExtension,
|
||||
TableBlockSchemaExtension,
|
||||
CalloutBlockSchemaExtension,
|
||||
TranscriptionBlockSchemaExtension,
|
||||
|
||||
BlockSelectionExtension,
|
||||
TextSelectionExtension,
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
RootBlockSchema,
|
||||
SurfaceRefBlockSchema,
|
||||
TableBlockSchema,
|
||||
TranscriptionBlockSchema,
|
||||
} from '@blocksuite/affine-model';
|
||||
import type { BlockSchema } from '@blocksuite/store';
|
||||
import type { z } from 'zod';
|
||||
@@ -56,4 +57,5 @@ export const AffineSchemas: z.infer<typeof BlockSchema>[] = [
|
||||
LatexBlockSchema,
|
||||
TableBlockSchema,
|
||||
CalloutBlockSchema,
|
||||
TranscriptionBlockSchema,
|
||||
];
|
||||
|
||||
@@ -18,7 +18,7 @@ import { humanFileSize } from '@blocksuite/affine-shared/utils';
|
||||
import { BlockSelection } from '@blocksuite/block-std';
|
||||
import { Slice } from '@blocksuite/store';
|
||||
import { html } from 'lit';
|
||||
import { property, state } from 'lit/decorators.js';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
|
||||
@@ -34,10 +34,6 @@ import { checkAttachmentBlob, downloadAttachmentBlob } from './utils';
|
||||
export class AttachmentBlockComponent extends CaptionedBlockComponent<AttachmentBlockModel> {
|
||||
static override styles = styles;
|
||||
|
||||
protected _isDragging = false;
|
||||
|
||||
protected _isResizing = false;
|
||||
|
||||
blockDraggable = true;
|
||||
|
||||
protected containerStyleMap = styleMap({
|
||||
@@ -127,25 +123,6 @@ export class AttachmentBlockComponent extends CaptionedBlockComponent<Attachment
|
||||
this.disposables.add(
|
||||
this.std.get(ThemeProvider).theme$.subscribe(() => this.requestUpdate())
|
||||
);
|
||||
|
||||
// this is required to prevent iframe from capturing pointer events
|
||||
this.disposables.add(
|
||||
this.selected$.subscribe(selected => {
|
||||
this._showOverlay = this._isResizing || this._isDragging || !selected;
|
||||
})
|
||||
);
|
||||
// this is required to prevent iframe from capturing pointer events
|
||||
this.handleEvent('dragStart', () => {
|
||||
this._isDragging = true;
|
||||
this._showOverlay =
|
||||
this._isResizing || this._isDragging || !this.selected$.peek();
|
||||
});
|
||||
|
||||
this.handleEvent('dragEnd', () => {
|
||||
this._isDragging = false;
|
||||
this._showOverlay =
|
||||
this._isResizing || this._isDragging || !this.selected$.peek();
|
||||
});
|
||||
}
|
||||
|
||||
override disconnectedCallback() {
|
||||
@@ -166,7 +143,9 @@ export class AttachmentBlockComponent extends CaptionedBlockComponent<Attachment
|
||||
|
||||
event.stopPropagation();
|
||||
|
||||
this._selectBlock();
|
||||
if (!this.selected$.peek()) {
|
||||
this._selectBlock();
|
||||
}
|
||||
}
|
||||
|
||||
override renderBlock() {
|
||||
@@ -190,13 +169,6 @@ export class AttachmentBlockComponent extends CaptionedBlockComponent<Attachment
|
||||
${embedView
|
||||
? html`<div class="affine-attachment-embed-container">
|
||||
${embedView}
|
||||
|
||||
<div
|
||||
class=${classMap({
|
||||
'affine-attachment-iframe-overlay': true,
|
||||
hide: !this._showOverlay,
|
||||
})}
|
||||
></div>
|
||||
</div>`
|
||||
: html`<div
|
||||
class=${classMap({
|
||||
@@ -227,9 +199,6 @@ export class AttachmentBlockComponent extends CaptionedBlockComponent<Attachment
|
||||
`;
|
||||
}
|
||||
|
||||
@state()
|
||||
protected accessor _showOverlay = true;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor allowEmbed = false;
|
||||
|
||||
|
||||
@@ -18,25 +18,6 @@ export class AttachmentEdgelessBlockComponent extends toGfxBlockComponent(
|
||||
return this.std.get(EdgelessLegacySlotIdentifier);
|
||||
}
|
||||
|
||||
override connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
|
||||
this._disposables.add(
|
||||
this.slots.elementResizeStart.subscribe(() => {
|
||||
this._isResizing = true;
|
||||
this._showOverlay = true;
|
||||
})
|
||||
);
|
||||
|
||||
this._disposables.add(
|
||||
this.slots.elementResizeEnd.subscribe(() => {
|
||||
this._isResizing = false;
|
||||
this._showOverlay =
|
||||
this._isResizing || this._isDragging || !this.selected$.peek();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
override onClick(_: MouseEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ export const attachmentSlashMenuConfig: SlashMenuConfig = {
|
||||
std.host,
|
||||
[file],
|
||||
maxFileSize,
|
||||
model
|
||||
model,
|
||||
'after'
|
||||
);
|
||||
if (model.text?.length === 0) {
|
||||
std.store.deleteBlock(model);
|
||||
@@ -60,8 +61,7 @@ export const attachmentSlashMenuConfig: SlashMenuConfig = {
|
||||
[file],
|
||||
maxFileSize,
|
||||
model,
|
||||
'after',
|
||||
true
|
||||
'after'
|
||||
);
|
||||
if (model.text?.length === 0) {
|
||||
std.store.deleteBlock(model);
|
||||
|
||||
@@ -136,16 +136,4 @@ export const styles = css`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.affine-attachment-iframe-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.affine-attachment-iframe-overlay.hide {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -89,6 +89,7 @@ export const AttachmentBlockSchema = defineBlockSchema({
|
||||
'affine:paragraph',
|
||||
'affine:list',
|
||||
],
|
||||
children: ['@attachment-viewer'],
|
||||
},
|
||||
transformer: transformerConfigs =>
|
||||
new AttachmentBlockTransformer(transformerConfigs),
|
||||
|
||||
@@ -31,6 +31,7 @@ export const CalloutBlockSchema = defineBlockSchema({
|
||||
'affine:paragraph',
|
||||
'affine:list',
|
||||
'affine:edgeless-text',
|
||||
'affine:transcription',
|
||||
],
|
||||
children: ['affine:paragraph'],
|
||||
},
|
||||
|
||||
@@ -15,3 +15,4 @@ export * from './paragraph/index.js';
|
||||
export * from './root/index.js';
|
||||
export * from './surface-ref/index.js';
|
||||
export * from './table';
|
||||
export * from './transcription';
|
||||
|
||||
@@ -44,6 +44,7 @@ export const ParagraphBlockSchema = defineBlockSchema({
|
||||
'affine:list',
|
||||
'affine:edgeless-text',
|
||||
'affine:callout',
|
||||
'affine:transcription',
|
||||
],
|
||||
},
|
||||
toModel: () => new ParagraphBlockModel(),
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './transcription-model.js';
|
||||
@@ -0,0 +1,33 @@
|
||||
import {
|
||||
BlockModel,
|
||||
BlockSchemaExtension,
|
||||
defineBlockSchema,
|
||||
} from '@blocksuite/store';
|
||||
|
||||
export const TranscriptionBlockFlavour = 'affine:transcription';
|
||||
|
||||
export const TranscriptionBlockSchema = defineBlockSchema({
|
||||
flavour: TranscriptionBlockFlavour,
|
||||
props: () => ({
|
||||
transcription: {},
|
||||
jobId: '',
|
||||
}),
|
||||
metadata: {
|
||||
version: 1,
|
||||
role: 'attachment-viewer',
|
||||
parent: ['affine:attachment'],
|
||||
children: ['affine:callout'],
|
||||
},
|
||||
toModel: () => new TranscriptionBlockModel(),
|
||||
});
|
||||
|
||||
export type TranscriptionBlockProps = {
|
||||
transcription: Record<string, any>;
|
||||
jobId: string;
|
||||
};
|
||||
|
||||
export class TranscriptionBlockModel extends BlockModel<TranscriptionBlockProps> {}
|
||||
|
||||
export const TranscriptionBlockSchemaExtension = BlockSchemaExtension(
|
||||
TranscriptionBlockSchema
|
||||
);
|
||||
Reference in New Issue
Block a user