mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-07 01:09:54 +08:00
fix(editor): switch view is not allowed during upload (#12018)
Closes: [BS-3352](https://linear.app/affine-design/issue/BS-3352/[improvement]-附件上传时禁止切-view)  <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved the logic for enabling or disabling the embed and card actions in the attachment toolbar, ensuring actions are only available when the file is ready and conditions are met. - **Refactor** - Enhanced reliability by centralizing block state checks and refining conditions for action availability in the attachment dropdown menu. - Centralized resource state management with a new computed signal, improving consistency in loading and error state handling. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
import type { Disposable } from '@blocksuite/global/disposable';
|
||||
import type { BlobEngine, BlobState } from '@blocksuite/sync';
|
||||
import { effect, type ReadonlySignal, signal } from '@preact/signals-core';
|
||||
import {
|
||||
computed,
|
||||
effect,
|
||||
type ReadonlySignal,
|
||||
signal,
|
||||
} from '@preact/signals-core';
|
||||
import type { TemplateResult } from 'lit-html';
|
||||
|
||||
export type ResourceKind = 'Blob' | 'File' | 'Image';
|
||||
@@ -18,17 +23,40 @@ export type StateInfo = {
|
||||
description?: string;
|
||||
};
|
||||
|
||||
export type ResolvedStateInfo = StateInfo & {
|
||||
export type ResolvedStateInfoPart = {
|
||||
loading: boolean;
|
||||
error: boolean;
|
||||
state: StateKind;
|
||||
};
|
||||
|
||||
export type ResolvedStateInfo = StateInfo & ResolvedStateInfoPart;
|
||||
|
||||
export class ResourceController implements Disposable {
|
||||
readonly blobUrl$ = signal<string | null>(null);
|
||||
|
||||
readonly state$ = signal<Partial<BlobState>>({});
|
||||
|
||||
readonly resolvedState$ = computed<ResolvedStateInfoPart>(() => {
|
||||
const {
|
||||
uploading = false,
|
||||
downloading = false,
|
||||
overSize = false,
|
||||
errorMessage,
|
||||
} = this.state$.value;
|
||||
const hasExceeded = overSize;
|
||||
const hasError = hasExceeded || Boolean(errorMessage);
|
||||
const state = this.determineState(
|
||||
hasExceeded,
|
||||
hasError,
|
||||
uploading,
|
||||
downloading
|
||||
);
|
||||
|
||||
const loading = state === 'uploading' || state === 'loading';
|
||||
|
||||
return { error: hasError, loading, state };
|
||||
});
|
||||
|
||||
private engine?: BlobEngine;
|
||||
|
||||
constructor(
|
||||
@@ -61,26 +89,12 @@ export class ResourceController implements Disposable {
|
||||
errorIcon?: TemplateResult;
|
||||
} & StateInfo
|
||||
): ResolvedStateInfo {
|
||||
const {
|
||||
uploading = false,
|
||||
downloading = false,
|
||||
overSize = false,
|
||||
errorMessage,
|
||||
} = this.state$.value;
|
||||
const hasExceeded = overSize;
|
||||
const hasError = hasExceeded || Boolean(errorMessage);
|
||||
const state = this.determineState(
|
||||
hasExceeded,
|
||||
hasError,
|
||||
uploading,
|
||||
downloading
|
||||
);
|
||||
const loading = state === 'uploading' || state === 'loading';
|
||||
const { error, loading, state } = this.resolvedState$.value;
|
||||
|
||||
const { icon, title, description, loadingIcon, errorIcon } = info;
|
||||
|
||||
const result = {
|
||||
error: hasError,
|
||||
error,
|
||||
loading,
|
||||
state,
|
||||
icon,
|
||||
@@ -91,9 +105,9 @@ export class ResourceController implements Disposable {
|
||||
if (loading) {
|
||||
result.icon = loadingIcon ?? icon;
|
||||
result.title = state === 'uploading' ? 'Uploading...' : 'Loading...';
|
||||
} else if (hasError) {
|
||||
} else if (error) {
|
||||
result.icon = errorIcon ?? icon;
|
||||
result.description = errorMessage ?? description;
|
||||
result.description = this.state$.value.errorMessage ?? description;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user