mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
fix(editor): improve image block upload and download states (#12017)
Related to: [BS-3143](https://linear.app/affine-design/issue/BS-3143/更新-loading-和错误样式) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a unified resource controller for managing image and attachment resources, providing improved loading, error, and state handling. - Added a visual loading indicator overlay to image blocks for better feedback during image loading. - **Improvements** - Simplified and centralized image and attachment state management, reducing redundant properties and manual state tracking. - Updated fallback UI for image blocks with clearer titles, descriptions, and improved layout. - Enhanced batch image block creation and download handling for improved efficiency. - Refined image block accessibility with improved alt text and streamlined rendering logic. - Centralized target model selection for image insertion in AI actions. - Reordered CSS declarations without affecting styling. - Improved reactive state tracking for blob upload/download operations in mock server. - **Bug Fixes** - Improved cleanup of object URLs to prevent resource leaks. - Adjusted toolbar logic to more accurately reflect available actions based on image state. - **Tests** - Updated end-to-end tests to match new UI text and behaviors for image loading and error states. - **Chores** - Refactored internal logic and updated comments for clarity and maintainability. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import type { Disposable } from '@blocksuite/global/disposable';
|
||||
import type { BlobEngine, BlobState } from '@blocksuite/sync';
|
||||
import { effect, type ReadonlySignal, signal } from '@preact/signals-core';
|
||||
import type { TemplateResult } from 'lit-html';
|
||||
@@ -23,7 +24,9 @@ export type ResolvedStateInfo = StateInfo & {
|
||||
state: StateKind;
|
||||
};
|
||||
|
||||
export class ResourceController {
|
||||
export class ResourceController implements Disposable {
|
||||
readonly blobUrl$ = signal<string | null>(null);
|
||||
|
||||
readonly state$ = signal<Partial<BlobState>>({});
|
||||
|
||||
private engine?: BlobEngine;
|
||||
@@ -33,6 +36,7 @@ export class ResourceController {
|
||||
readonly kind: ResourceKind = 'File'
|
||||
) {}
|
||||
|
||||
// This is a tradeoff, initializing `Blob Sync Engine`.
|
||||
setEngine(engine: BlobEngine) {
|
||||
this.engine = engine;
|
||||
return this;
|
||||
@@ -142,7 +146,7 @@ export class ResourceController {
|
||||
return blob;
|
||||
}
|
||||
|
||||
async createBlobUrlWith(type?: string) {
|
||||
async createUrlWith(type?: string) {
|
||||
let blob = await this.blob();
|
||||
if (!blob) return null;
|
||||
|
||||
@@ -150,4 +154,26 @@ export class ResourceController {
|
||||
|
||||
return URL.createObjectURL(blob);
|
||||
}
|
||||
|
||||
async refreshUrlWith(type?: string) {
|
||||
const url = await this.createUrlWith(type);
|
||||
if (!url) return;
|
||||
|
||||
const prevUrl = this.blobUrl$.peek();
|
||||
|
||||
this.blobUrl$.value = url;
|
||||
|
||||
if (!prevUrl) return;
|
||||
|
||||
// Releases the previous url.
|
||||
URL.revokeObjectURL(prevUrl);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
const url = this.blobUrl$.peek();
|
||||
if (!url) return;
|
||||
|
||||
// Releases the current url.
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user