Add clip player & offline renderer #49
@ -69,6 +69,7 @@ const EN_US = {
|
|||||||
"Popup.Action.Objects.Confirm.Restore": "Restore",
|
"Popup.Action.Objects.Confirm.Restore": "Restore",
|
||||||
"Popup.Delete.Objects.Confirm": "Are you sure you want to delete this object(s)? The object is deleted and cannot be recalled.",
|
"Popup.Delete.Objects.Confirm": "Are you sure you want to delete this object(s)? The object is deleted and cannot be recalled.",
|
||||||
"Popup.Delete.Behavior.Confirm": "Are you sure you want to delete this behavior? The behavior is deleted and cannot be recalled.",
|
"Popup.Delete.Behavior.Confirm": "Are you sure you want to delete this behavior? The behavior is deleted and cannot be recalled.",
|
||||||
|
"Popup.Delete.Clip.Confirm": "Are you sure you want to delete this clip? The clip cannot be restored after deletion.",
|
||||||
"Popup.Restore.Behavior.Confirm": "Are you sure you want to reset all parameters of this behavior? This operation cannot be recalled.",
|
"Popup.Restore.Behavior.Confirm": "Are you sure you want to reset all parameters of this behavior? This operation cannot be recalled.",
|
||||||
"Popup.Setting.Title": "Preferences setting",
|
"Popup.Setting.Title": "Preferences setting",
|
||||||
"Popup.Load.Save.Title": "Load save",
|
"Popup.Load.Save.Title": "Load save",
|
||||||
|
@ -69,6 +69,7 @@ const ZH_CN = {
|
|||||||
"Popup.Action.Objects.Confirm.Restore": "重置",
|
"Popup.Action.Objects.Confirm.Restore": "重置",
|
||||||
"Popup.Delete.Objects.Confirm": "你确定要删除这个(些)对象吗?对象被删除将无法撤回。",
|
"Popup.Delete.Objects.Confirm": "你确定要删除这个(些)对象吗?对象被删除将无法撤回。",
|
||||||
"Popup.Delete.Behavior.Confirm": "你确定要删除这个行为吗?行为被删除将无法撤回。",
|
"Popup.Delete.Behavior.Confirm": "你确定要删除这个行为吗?行为被删除将无法撤回。",
|
||||||
|
"Popup.Delete.Clip.Confirm": "你确定删除这个剪辑片段,剪辑片段删除后将无法恢复。",
|
||||||
"Popup.Restore.Behavior.Confirm": "你确定要重置此行为的全部参数吗?此操作无法撤回。",
|
"Popup.Restore.Behavior.Confirm": "你确定要重置此行为的全部参数吗?此操作无法撤回。",
|
||||||
"Popup.Setting.Title": "首选项设置",
|
"Popup.Setting.Title": "首选项设置",
|
||||||
"Popup.Load.Save.Title": "加载存档",
|
"Popup.Load.Save.Title": "加载存档",
|
||||||
|
@ -371,7 +371,7 @@ class Model extends Emitter<ModelEvent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (deletedClip) {
|
if (deletedClip) {
|
||||||
this.behaviorPool.splice(index, 1);
|
this.clipPool.splice(index, 1);
|
||||||
console.log(`Model: Delete clip ${deletedClip.name ?? deletedClip.id}`);
|
console.log(`Model: Delete clip ${deletedClip.name ?? deletedClip.id}`);
|
||||||
this.emit("clipChange", this.clipPool);
|
this.emit("clipChange", this.clipPool);
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,24 @@
|
|||||||
import { Component, ReactNode } from "react";
|
import { Component, ReactNode } from "react";
|
||||||
import { ClipList } from "@Component/ClipList/ClipList";
|
import { ClipList } from "@Component/ClipList/ClipList";
|
||||||
import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status";
|
import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status";
|
||||||
import { Theme } from "@Component/Theme/Theme";
|
import { BackgroundLevel, FontLevel, Theme } from "@Component/Theme/Theme";
|
||||||
import { Message } from "@Input/Message/Message";
|
import { Message } from "@Input/Message/Message";
|
||||||
import { Clip } from "@Model/Clip";
|
import { Clip } from "@Model/Clip";
|
||||||
import { ActuatorModel } from "@Model/Actuator";
|
import { ActuatorModel } from "@Model/Actuator";
|
||||||
|
import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup";
|
||||||
import "./ClipPlayer.scss";
|
import "./ClipPlayer.scss";
|
||||||
|
|
||||||
@useStatusWithEvent("clipChange", "focusClipChange", "actuatorStartChange")
|
@useStatusWithEvent("clipChange", "focusClipChange", "actuatorStartChange")
|
||||||
class ClipPlayer extends Component<IMixinStatusProps> {
|
class ClipPlayer extends Component<IMixinStatusProps> {
|
||||||
|
|
||||||
|
private isInnerClick: boolean = false;
|
||||||
|
|
||||||
private renderMessage(): ReactNode {
|
private renderMessage(): ReactNode {
|
||||||
return <Message i18nKey="Panel.Info.Clip.List.Error.Nodata"/>;
|
return <Message i18nKey="Panel.Info.Clip.List.Error.Nodata"/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderClipList(clipList: Clip[]): ReactNode {
|
private renderClipList(clipList: Clip[]): ReactNode {
|
||||||
|
|
||||||
const disable =
|
const disable =
|
||||||
!this.props.status?.focusClip &&
|
!this.props.status?.focusClip &&
|
||||||
(
|
(
|
||||||
@ -24,15 +27,51 @@ class ClipPlayer extends Component<IMixinStatusProps> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return <ClipList
|
return <ClipList
|
||||||
|
focus={this.props.status?.focusClip}
|
||||||
clips={clipList}
|
clips={clipList}
|
||||||
disable={disable}
|
disable={disable}
|
||||||
|
delete={(clip) => {
|
||||||
|
this.isInnerClick = true;
|
||||||
|
const status = this.props.status;
|
||||||
|
if (status) {
|
||||||
|
status.popup.showPopup(ConfirmPopup, {
|
||||||
|
infoI18n: "Popup.Delete.Clip.Confirm",
|
||||||
|
titleI18N: "Popup.Action.Objects.Confirm.Title",
|
||||||
|
yesI18n: "Popup.Action.Objects.Confirm.Delete",
|
||||||
|
red: "yes",
|
||||||
|
yes: () => {
|
||||||
|
status.setClipObject()
|
||||||
|
status.model.deleteClip(clip.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
add={() => {
|
||||||
|
this.isInnerClick = true;
|
||||||
|
}}
|
||||||
|
click={(clip) => {
|
||||||
|
this.isInnerClick = true;
|
||||||
|
this.props.status?.setClipObject(clip);
|
||||||
|
}}
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): ReactNode {
|
public render(): ReactNode {
|
||||||
const clipList = this.props.status?.model.clipPool ?? [];
|
const clipList = this.props.status?.model.clipPool ?? [];
|
||||||
|
|
||||||
return <Theme className="Clip-player-clip-list-root">
|
return <Theme
|
||||||
|
className="Clip-player-clip-list-root"
|
||||||
|
fontLevel={FontLevel.normal}
|
||||||
|
backgroundLevel={BackgroundLevel.Level4}
|
||||||
|
onClick={()=>{
|
||||||
|
if (this.isInnerClick) {
|
||||||
|
this.isInnerClick = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.props.status?.setClipObject();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
{ clipList.length > 0 ? null : this.renderMessage() }
|
{ clipList.length > 0 ? null : this.renderMessage() }
|
||||||
{ this.renderClipList(clipList) }
|
{ this.renderClipList(clipList) }
|
||||||
</Theme>;
|
</Theme>;
|
||||||
|
@ -10,6 +10,7 @@ class ClipRecorder extends Component<IMixinStatusProps> {
|
|||||||
let mod: "P" | "R" = this.props.status?.focusClip ? "P" : "R";
|
let mod: "P" | "R" = this.props.status?.focusClip ? "P" : "R";
|
||||||
let runner: boolean = false;
|
let runner: boolean = false;
|
||||||
let currentTime: number = 0;
|
let currentTime: number = 0;
|
||||||
|
let name: string | undefined;
|
||||||
|
|
||||||
// 是否开始录制
|
// 是否开始录制
|
||||||
if (mod === "R") {
|
if (mod === "R") {
|
||||||
@ -19,15 +20,20 @@ class ClipRecorder extends Component<IMixinStatusProps> {
|
|||||||
this.props.status?.actuator.mod === ActuatorModel.Offline;
|
this.props.status?.actuator.mod === ActuatorModel.Offline;
|
||||||
|
|
||||||
currentTime = this.props.status?.actuator.recordClip?.time ?? 0;
|
currentTime = this.props.status?.actuator.recordClip?.time ?? 0;
|
||||||
|
|
||||||
|
name = this.props.status?.actuator.recordClip?.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (mod === "P") {
|
else if (mod === "P") {
|
||||||
|
|
||||||
// 是否正在播放
|
// 是否正在播放
|
||||||
runner = this.props.status?.actuator.mod === ActuatorModel.Play;
|
runner = this.props.status?.actuator.mod === ActuatorModel.Play;
|
||||||
|
|
||||||
|
name = this.props.status?.focusClip?.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Recorder
|
return <Recorder
|
||||||
|
name={name}
|
||||||
currentTime={currentTime}
|
currentTime={currentTime}
|
||||||
mode={mod}
|
mode={mod}
|
||||||
running={runner}
|
running={runner}
|
||||||
|
Loading…
Reference in New Issue
Block a user