chore: stt player ui

This commit is contained in:
jialin
2025-02-17 13:49:55 +08:00
parent d2a3388058
commit c60015bd09
11 changed files with 142 additions and 111 deletions
+8 -6
View File
@@ -1,7 +1,7 @@
.player-wrap {
width: 100%;
display: flex;
background-color: var(--ant-color-fill-quaternary);
// background-color: var(--ant-color-fill-quaternary);
border-radius: 6px;
.player-ui {
@@ -13,10 +13,10 @@
}
.controls {
width: 100%;
display: flex;
justify-content: center;
justify-content: space-between;
align-items: center;
margin-inline: 10px;
}
.play-btn {
@@ -43,7 +43,6 @@
.slider-inner {
flex: 1;
margin-inline: 10px;
}
}
@@ -55,8 +54,11 @@
}
.time {
width: 52px;
text-align: right;
&.current {
margin-left: 6px;
text-align: left;
}
}
@@ -65,7 +67,7 @@
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
align-items: flex-start;
justify-content: center;
.slider {
+69 -55
View File
@@ -25,6 +25,7 @@ interface AudioPlayerProps {
height?: number;
width?: number;
duration?: number;
extra?: React.ReactNode;
}
const speedOptions = [
@@ -42,7 +43,7 @@ const speedConfig = {
const AudioPlayer: React.FC<AudioPlayerProps> = forwardRef((props, ref) => {
const intl = useIntl();
const { autoplay = false, speed: defaultSpeed = 1 } = props;
const { autoplay = false, speed: defaultSpeed = 1, extra } = props;
const audioRef = React.useRef<HTMLAudioElement>(null);
const [audioState, setAudioState] = React.useState<{
currentTime: number;
@@ -206,76 +207,89 @@ const AudioPlayer: React.FC<AudioPlayerProps> = forwardRef((props, ref) => {
<div className="progress-bar">
<span className="file-name">{props.name}</span>
<div className="slider">
<span className="time current">
{/* <span className="time current">
{' '}
{formatTime(audioState.currentTime)}
</span>
</span> */}
<div className="slider-inner">
<Slider
tooltip={{ open: false }}
min={0}
step={1}
styles={{
rail: {
// height: 6
}
}}
max={audioState.duration}
value={audioState.currentTime}
onChange={handleCurrentChange}
/>
</div>
<span className="time">{formatTime(audioState.duration)}</span>
{/* <span className="time">{formatTime(audioState.duration)}</span> */}
</div>
<div className="controls">
<Tooltip
title={intl.formatMessage({
id: 'playground.audio.button.slow'
})}
>
<Button
type="text"
size="small"
className="backward"
disabled={
speed === speedConfig.min || speed < speedConfig.min
}
onClick={handleReduceSpeed}
<div className="audio-control flex-center">
<span className="time current">
{' '}
{formatTime(audioState.currentTime)}
</span>
<Tooltip
title={intl.formatMessage({
id: 'playground.audio.button.slow'
})}
>
<FastBackwardOutlined className="font-size-20" />
</Button>
</Tooltip>
<span className="play-btn">
<Button
size="middle"
type="text"
onClick={handlePlay}
disabled={!audioState?.duration}
icon={
!playOn ? (
<PlayCircleFilled
style={{ fontSize: '22px' }}
></PlayCircleFilled>
) : (
<PauseCircleFilled
style={{ fontSize: '22px' }}
></PauseCircleFilled>
)
}
></Button>
</span>
<Tooltip
title={intl.formatMessage({
id: 'playground.audio.button.fast'
})}
>
<Button
type="text"
size="small"
className="forward"
disabled={
speed === speedConfig.max || speed > speedConfig.max
}
onClick={handleAddSpeed}
<Button
type="text"
size="small"
className="backward"
disabled={
speed === speedConfig.min || speed < speedConfig.min
}
onClick={handleReduceSpeed}
>
<FastBackwardOutlined className="font-size-20" />
</Button>
</Tooltip>
<span className="play-btn">
<Button
size="middle"
type="text"
onClick={handlePlay}
disabled={!audioState?.duration}
icon={
!playOn ? (
<PlayCircleFilled
style={{ fontSize: '22px' }}
></PlayCircleFilled>
) : (
<PauseCircleFilled
style={{ fontSize: '22px' }}
></PauseCircleFilled>
)
}
></Button>
</span>
<Tooltip
title={intl.formatMessage({
id: 'playground.audio.button.fast'
})}
>
<FastForwardOutlined className="font-size-20" />
</Button>
</Tooltip>
<Button
type="text"
size="small"
className="forward"
disabled={
speed === speedConfig.max || speed > speedConfig.max
}
onClick={handleAddSpeed}
>
<FastForwardOutlined className="font-size-20" />
</Button>
</Tooltip>
<span className="time">{formatTime(audioState.duration)}</span>
</div>
{extra}
</div>
</div>
</div>
+5 -1
View File
@@ -139,7 +139,11 @@ const LogsList: React.FC<LogsListProps> = forwardRef((props, ref) => {
<div className={classNames('content')}>
{_.map(dataList, (item: any, index: number) => {
return (
<div key={item.uid} className={classNames('text')}>
<div
key={item.uid}
className={classNames('text')}
data-uid={item.uid}
>
{item.content}
</div>
);
+16 -4
View File
@@ -4,6 +4,10 @@ const removeBrackets = (str: string) => {
return str?.replace?.(/^\(…\)/, '');
};
const removeBracketsFromLine = (row: string) => {
return row.startsWith('(…)') ? row.slice(3) : row;
};
class AnsiParser {
private cursorRow: number = 0;
private cursorCol: number = 0;
@@ -12,6 +16,8 @@ class AnsiParser {
private uid: number = 0;
private isProcessing: boolean = false;
private taskQueue: string[] = [];
private page: number = 1;
private pageSize: number = 500;
private colorMap = {
'30': 'black',
'31': 'red',
@@ -33,6 +39,11 @@ class AnsiParser {
this.screen = [['']];
this.rawDataRows = 0;
this.uid = this.uid + 1;
this.page = 1;
}
public setPage(page: number) {
this.page = page;
}
private setId() {
@@ -125,9 +136,9 @@ class AnsiParser {
const remainingText = input.slice(lastIndex);
this.handleText(remainingText);
const result = this.screen.map((row) => ({
content: removeBrackets(row.join('')),
uid: this.setId()
const result = this.screen.map((row, index) => ({
content: removeBracketsFromLine(row.join('')),
uid: `${this.page}-${index}`
}));
return {
@@ -176,7 +187,8 @@ class AnsiParser {
const parser = new AnsiParser();
self.onmessage = function (event) {
const { inputStr, reset } = event.data;
const { inputStr, reset, page } = event.data;
parser.setPage(page);
if (reset) {
parser.reset();
}
@@ -133,6 +133,7 @@ const LogsViewer: React.FC<LogsViewerProps> = forwardRef((props, ref) => {
}
logParseWorker.current.postMessage({
inputStr: data,
page: pageRef.current,
reset: clearScreen.current
});
clearScreen.current = false;
@@ -1,6 +1,5 @@
import useSetChunkRequest from '@/hooks/use-chunk-request';
import { FitAddon } from '@xterm/addon-fit';
import { WebglAddon } from '@xterm/addon-webgl';
import { Terminal } from '@xterm/xterm';
import '@xterm/xterm/css/xterm.css';
import classNames from 'classnames';
@@ -126,7 +125,6 @@ const LogsViewer: React.FC<LogsViewerProps> = forwardRef((props, ref) => {
});
fitAddonRef.current = new FitAddon();
termRef.current.loadAddon(fitAddonRef.current);
termRef.current.loadAddon(new WebglAddon());
termRef.current.open(termwrapRef.current);
// add event
@@ -11,6 +11,10 @@
margin-bottom: 0;
}
b {
font-weight: var(--font-weight-bold);
}
h1,
h2,
h3,
@@ -80,6 +84,10 @@
max-width: 100%;
height: auto;
}
img[src^="https://img.shields.io/"], img[src*="badge.svg"]
{
margin-bottom: 6px;
}
video {
max-width: 100%;
-4
View File
@@ -45,10 +45,6 @@ const MarkdownViewer: React.FC<MarkdownViewerProps> = ({
// 'bibtex'
];
// renderer.link = ({ href, title, text }) => {
// return `<a href="${href}" title="${title || ''}" target="_blank" rel="noopener noreferrer">${text}</a>`;
// };
const isValidURL = useCallback((url: string) => {
const pattern = /^(https?:\/\/|\/\/)([^\s/$.?#].[^\s]*)$/;
@@ -1 +0,0 @@
export default {};