living-together/source/Context/Archive.tsx

133 lines
3.3 KiB
TypeScript

import { FunctionComponent, useEffect } from "react";
import { useSetting, IMixinSettingProps, Platform } from "@Context/Setting";
import { useStatus, IMixinStatusProps } from "@Context/Status";
import { useElectron, IMixinElectronProps } from "@Context/Electron";
import { I18N } from "@Component/Localization/Localization";
import * as download from "downloadjs";
interface IFileInfo {
fileName: string;
isNewFile: boolean;
isSaved: boolean;
fileUrl?: string;
fileData: () => Promise<string>;
}
interface IRunnerProps {
running?: boolean;
afterRunning?: () => any;
}
interface ICallBackProps {
then: () => any;
}
const ArchiveSaveDownloadView: FunctionComponent<IFileInfo & ICallBackProps> = function ArchiveSaveDownloadView(props) {
const runner = async () => {
const file = await props.fileData();
setTimeout(() => {
download(file, props.fileName, "text/json");
props.then();
}, 100);
}
useEffect(() => { runner() }, []);
return <></>;
}
const ArchiveSaveDownload = ArchiveSaveDownloadView;
const ArchiveSaveFsView: FunctionComponent<IFileInfo & ICallBackProps & IMixinElectronProps & IMixinSettingProps & IMixinStatusProps> =
function ArchiveSaveFsView(props) {
const runner = async () => {
const file = await props.fileData();
setTimeout(() => {
if (props.electron) {
props.electron.fileSave(
file,
I18N(props, "Popup.Load.Save.Select.File.Name"),
I18N(props, "Popup.Load.Save.Select.Path.Title"),
I18N(props, "Popup.Load.Save.Select.Path.Button"),
props.fileUrl
);
}
}, 100);
}
const saveEvent = ({name, url, success} : {name: string, url: string, success: boolean}) => {
if (success && props.status) {
props.status.archive.fileUrl = url;
props.status.archive.fileName = name;
props.status.archive.isNewFile = false;
props.status.archive.emit("fileSave", props.status.archive);
}
props.then();
}
useEffect(() => {
runner();
props.electron?.on("fileSave", saveEvent);
return () => {
props.electron?.off("fileSave", saveEvent);
};
}, []);
return <></>;
}
const ArchiveSaveFs = useSetting(useElectron(useStatus(ArchiveSaveFsView)));
/**
* 保存存档文件
*/
const ArchiveSaveView: FunctionComponent<IMixinSettingProps & IMixinStatusProps & IRunnerProps> = function ArchiveSave(props) {
if (!props.running) {
return <></>;
}
const fileData: IFileInfo = {
fileName: "",
isNewFile: true,
isSaved: false,
fileUrl: undefined,
fileData: async () => `{"nextIndividualId":0,"objectPool":[],"labelPool":[],"behaviorPool":[]}`
}
if (props.status) {
fileData.isNewFile = props.status.archive.isNewFile;
fileData.fileName = props.status.archive.fileName ?? "";
fileData.isSaved = props.status.archive.isSaved;
fileData.fileUrl = props.status.archive.fileUrl;
}
if (fileData.isNewFile) {
fileData.fileName = I18N(props, "Header.Bar.New.File.Name");
}
// 生成存档文件
fileData.fileData = async () => {
return props.status?.archive.save(props.status.model) ?? "";
};
const callBack = () => {
if (props.afterRunning) {
props.afterRunning();
}
}
return <>
{
props.setting?.platform === Platform.web ?
<ArchiveSaveDownload {...fileData} then={callBack}/> :
<ArchiveSaveFs {...fileData} then={callBack}/>
}
</>
}
const ArchiveSave = useSetting(useStatus(ArchiveSaveView));
export { ArchiveSave };