/* eslint-disable react/destructuring-assignment */ /* eslint-disable camelcase */ import { ipcRenderer } from "electron"; import React, { useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { Button, Tooltip } from "antd"; import { useTranslation } from "react-i18next"; import { setProgramNotExist } from "../programsSlice"; import ImageButton from "../../../app/components/image_button/ImageButton"; import { IconTag } from "../../../apis/cache"; import useLongPressRestart from "./useLongPressRestart"; import "./ProgramButton.less"; // dont use import from main due bundle isolation const kUrl = "openUrl"; const kFile = "openProgram"; const kCloseFile = "closeProgram"; const kForegroundError = "exec-foreground-error"; const kError = "exec-error"; const kNotExist = "not-exist"; export default (props) => { const dispatch = useDispatch(); const [tooltipTitle, useTooltipTitle] = useState({ visible: false, title: "", }); const notExistedPrograms = useSelector( (state) => state.programs.programsNotExist ); const isCompact = useSelector((state) => state.taskbar.compact); const { type, program, active } = props; const { name, label, description, order } = program; useEffect( () => useTooltipTitle({ visible: false, title: description }), [description] ); const { t } = useTranslation(); const iconUrl = useSelector( (state) => state.cache.attachments[`workplace_${name}_${IconTag}`] ); let runProgram; let closeProgram; let notExist = false; const handleResult = (result) => { switch (result) { case kForegroundError: break; case kError: break; case kNotExist: dispatch(setProgramNotExist(program)); break; default: break; } }; if (type === "program") { const { executable_path, fallback_path, window_process, parameters } = props.program; runProgram = async () => { const result = await ipcRenderer.invoke(kFile, { file: executable_path, fallback_path, params: parameters, windowProcess: window_process, }); handleResult(result); }; closeProgram = async () => { await ipcRenderer.invoke(kCloseFile, { file: executable_path, fallback_path, windowProcess: window_process, }); }; } else if (type === "exclusive") { const { executable_path, fallback_path } = props.program; runProgram = async () => { const result = await ipcRenderer.invoke(kFile, { file: executable_path, fallback_path, params: null, }); handleResult(result); }; closeProgram = async () => { await ipcRenderer.invoke(kCloseFile, { file: executable_path, fallback_path, }); }; } else if (type === "web") { const { url, open_with_default_browser, is_frameless } = props.program; runProgram = async () => { const result = await ipcRenderer.invoke(kUrl, { title: name, url, fullscreen: true, frameless: is_frameless, openDefaultBrowser: open_with_default_browser, }); handleResult(result); }; } if (notExistedPrograms.find((e) => e === name)) { notExist = true; } const { events } = useLongPressRestart( () => { if (type === "program" || type === "exclusive") useTooltipTitle({ visible: true, title: t("programRestarting") }); }, async () => { if (type === "program" || type === "exclusive") { setTimeout( () => useTooltipTitle({ visible: false, title: description }), 100 ); await closeProgram(); runProgram(); } }, 2000 ); return ( <Tooltip open={tooltipTitle.visible} placement="right" title={tooltipTitle.title} className={isCompact ? "program-button--compact" : "program-button"} > {iconUrl ? ( <ImageButton key={name} text={label || name} iconUrl={iconUrl} order={order} callback={() => { if (!tooltipTitle.visible) runProgram(); }} active={active} events={events} /> ) : ( <Button danger={notExist} style={{ order }} onClick={() => { if (!tooltipTitle.visible) runProgram(); }} // eslint-disable-next-line react/jsx-props-no-spreading {...events} > {label || name} </Button> )} </Tooltip> ); };