mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 12:55:00 +00:00
feat(core): add reload button to audio block (#12451)
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** - Added a reload button with an icon for audio blocks, allowing users to retry loading audio files if an error occurs. - Error messages are now displayed with actionable options when audio loading fails. - **Enhancements** - Audio file sizes are now shown in a human-readable format within the audio player. - Improved display of audio file information, including error messages and formatted descriptions. - **Style** - Updated styling for audio player and audio block components, including new styles for error states and reload button. - Renamed and refined audio player description styling for better layout and spacing. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -60,8 +60,9 @@ export const spacer = style({
|
||||
flex: 1,
|
||||
});
|
||||
|
||||
export const sizeInfo = style({
|
||||
export const description = style({
|
||||
display: 'flex',
|
||||
gap: '8px',
|
||||
alignItems: 'center',
|
||||
fontSize: cssVar('fontXs'),
|
||||
color: cssVarV2('text/secondary'),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import bytes from 'bytes';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import { AudioPlayer, MiniAudioPlayer } from './audio-player';
|
||||
|
||||
@@ -159,6 +160,10 @@ const AudioWrapper = () => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const description = useMemo(() => {
|
||||
return audioFile ? <>{bytes(audioFile.size)}</> : null;
|
||||
}, [audioFile]);
|
||||
|
||||
useEffect(() => {
|
||||
const audio = audioRef.current;
|
||||
if (!audio || !audioFile) return;
|
||||
@@ -296,7 +301,7 @@ const AudioWrapper = () => {
|
||||
/>
|
||||
<MiniAudioPlayer
|
||||
name={audioFile.name}
|
||||
size={audioFile.size}
|
||||
description={description}
|
||||
waveform={waveform}
|
||||
playbackState={playbackState}
|
||||
seekTime={seekTime}
|
||||
@@ -311,7 +316,7 @@ const AudioWrapper = () => {
|
||||
/>
|
||||
<AudioPlayer
|
||||
name={audioFile.name}
|
||||
size={audioFile.size}
|
||||
description={description}
|
||||
waveform={waveform}
|
||||
playbackState={playbackState}
|
||||
seekTime={seekTime}
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
RewindFifteenSecondsIcon,
|
||||
VoiceIcon,
|
||||
} from '@blocksuite/icons/rc';
|
||||
import bytes from 'bytes';
|
||||
import { clamp } from 'lodash-es';
|
||||
import { type MouseEventHandler, type ReactNode, useCallback } from 'react';
|
||||
|
||||
@@ -24,7 +23,7 @@ const formatTime = (seconds: number): string => {
|
||||
export interface AudioPlayerProps {
|
||||
// Audio metadata
|
||||
name: string;
|
||||
size: number | ReactNode; // the size entry may be used for drawing error message
|
||||
description?: ReactNode; // Display file size or error message
|
||||
waveform: number[] | null;
|
||||
// Playback state
|
||||
playbackState: 'idle' | 'playing' | 'paused' | 'stopped';
|
||||
@@ -52,7 +51,7 @@ const playbackRates = [0.5, 0.75, 1, 1.5, 1.75, 2, 3];
|
||||
|
||||
export const AudioPlayer = ({
|
||||
name,
|
||||
size,
|
||||
description,
|
||||
playbackState,
|
||||
seekTime,
|
||||
duration,
|
||||
@@ -108,9 +107,7 @@ export const AudioPlayer = ({
|
||||
<div className={styles.nameLabel}>{name}</div>
|
||||
</div>
|
||||
<div className={styles.upperRow}>
|
||||
<div className={styles.sizeInfo}>
|
||||
{typeof size === 'number' ? bytes(size) : size}
|
||||
</div>
|
||||
<div className={styles.description}>{description}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.upperRight}>
|
||||
|
||||
Reference in New Issue
Block a user