Add clip list component

This commit is contained in:
MrKBear 2022-04-30 20:40:02 +08:00
parent 53e6c9db9c
commit c067088157
5 changed files with 116 additions and 11 deletions

View File

@ -57,15 +57,32 @@ div.clip-list-root {
}
div.clip-item-content {
width: calc( 100% - 65px );
padding-right: 10px;
max-width: 125px;
height: $clip-item-height;
display: flex;
flex-direction: column;
justify-content: center;
div {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
width: 100%;
}
div.info {
opacity: .75;
}
}
}
div.clip-item:hover {
div.clip-item.disable {
cursor: not-allowed;
}
div.clip-item.able:hover {
div.clip-icon-view {
@ -98,7 +115,7 @@ div.dark.clip-list-root {
}
}
div.clip-item:hover {
div.clip-item.able:hover {
color: $lt-font-color-lvl2-dark;
background-color: $lt-bg-color-lvl2-dark;
}
@ -119,7 +136,7 @@ div.light.clip-list-root {
}
}
div.clip-item:hover {
div.clip-item.able:hover {
color: $lt-font-color-lvl2-light;
background-color: $lt-bg-color-lvl2-light;
}

View File

@ -1,3 +1,4 @@
import { Localization } from "@Component/Localization/Localization";
import { Theme } from "@Component/Theme/Theme";
import { Icon } from "@fluentui/react";
import { Clip } from "@Model/Clip";
@ -6,20 +7,73 @@ import "./ClipList.scss";
interface IClipListProps {
clips: Clip[];
focus?: Clip;
disable?: boolean;
add?: () => any;
click?: (clip: Clip) => any;
delete?: (clip: Clip) => any;
}
class ClipList extends Component<IClipListProps> {
private isInnerClick: boolean = false;
private resolveCallback(fn?: (p: any) => any, p?: any): any {
if (this.props.disable) {
return false;
}
if (fn) {
return fn(p);
}
}
private parseTime(time?: number): string {
if (time === undefined) {
return "0:0:0:0";
}
const h = Math.floor(time / 3600);
const m = Math.floor((time % 3600) / 60);
const s = Math.floor((time % 3600) % 60);
const ms = Math.floor((time % 1) * 1000);
return `${h}:${m}:${s}:${ms}`;
}
private getClipInfo(clip: Clip): string {
let fps = Math.floor(clip.frames.length / clip.time);
if (isNaN(fps)) fps = 0;
return `${this.parseTime(clip.time)} ${fps}fps`;
}
private renderClip(clip: Clip) {
const focus = clip.equal(this.props.focus);
const disable = this.props.disable;
const classList = ["clip-item"];
if (focus) {
classList.push("focus");
}
if (disable) {
classList.push("disable");
} else {
classList.push("able");
}
return <div
key={clip.id}
className="clip-item"
className={classList.join(" ")}
onClick={() => {
if (this.isInnerClick) {
this.isInnerClick = false;
} else {
this.resolveCallback(this.props.click, clip);
}
}}
>
<div className="clip-item-hole-view">
{new Array(4).fill(0).map(() => {
return <div className="clip-item-hole"/>
{new Array(4).fill(0).map((_, index) => {
return <div className="clip-item-hole" key={index}/>
})}
</div>
<div className="clip-icon-view">
@ -28,21 +82,36 @@ class ClipList extends Component<IClipListProps> {
iconName="Delete"
className="delete"
onClick={() => {
this.props.delete && this.props.delete(clip);
this.isInnerClick = true;
this.resolveCallback(this.props.delete, clip);
}}
/>
</div>
<div className="clip-item-content">
<div className="title">{clip.name}</div>
<div className="info">{clip.frames.length}</div>
<div className="info">{
clip.isRecording ?
<Localization i18nKey="Panel.Info.Behavior.Clip.Uname.Clip"/> :
this.getClipInfo(clip)
}</div>
</div>
</div>;
}
private renderAddButton(): ReactNode {
const classList = ["clip-item", "add-button"];
if (this.props.disable) {
classList.push("disable");
} else {
classList.push("able");
}
return <div
className="clip-item add-button"
onClick={this.props.add}
key="ADD_BUTTON"
className={classList.join(" ")}
onClick={() => this.resolveCallback(this.props.add)}
>
<Icon iconName="Add"/>
</div>

View File

@ -52,6 +52,7 @@ class Actuator extends Emitter<IActuatorEvent> {
// 记录录制片段
this.recordClip = clip;
clip.isRecording = true;
// 如果仿真未开启,开启仿真
if (!this.start()) this.start(true);
@ -65,6 +66,9 @@ class Actuator extends Emitter<IActuatorEvent> {
*/
public endRecord() {
this.recordClip && (this.recordClip.isRecording = false);
this.recordClip = undefined;
// 如果仿真未停止,停止仿真
if (this.start()) this.start(false);

View File

@ -44,6 +44,11 @@ class Clip {
*/
public frames: IFrame[] = [];
/**
*
*/
public isRecording: boolean = false;
/**
*
*/

View File

@ -4,6 +4,7 @@ import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status";
import { Theme } from "@Component/Theme/Theme";
import { Message } from "@Input/Message/Message";
import { Clip } from "@Model/Clip";
import { ActuatorModel } from "@Model/Actuator";
import "./ClipPlayer.scss";
@useStatusWithEvent("clipChange", "focusClipChange", "actuatorStartChange")
@ -14,8 +15,17 @@ class ClipPlayer extends Component<IMixinStatusProps> {
}
private renderClipList(clipList: Clip[]): ReactNode {
const disable =
!this.props.status?.focusClip &&
(
this.props.status?.actuator.mod === ActuatorModel.Record ||
this.props.status?.actuator.mod === ActuatorModel.Offline
);
return <ClipList
clips={clipList}
disable={disable}
/>;
}