diff --git a/main.js b/main.js index a611d85..86d7857 100644 --- a/main.js +++ b/main.js @@ -95,6 +95,7 @@ function createWindow() { } const additionalData = { myKey: 'myValue' } app.on('ready', () => { + // const gotTheLock = true const gotTheLock = app.requestSingleInstanceLock(additionalData) if (gotTheLock) { app.getPath('crashDumps') @@ -159,6 +160,10 @@ app.on('ready', () => { startNumber++ } }); + // 更新 + ipcMain.handle('updateHandle', () => { + updateHandle() + }); // socket ipcMain.handle('startSignalr', (event, user) => { startSignalr(user) @@ -185,6 +190,7 @@ app.on('ready', () => { connection.off('ModifyNickName'); connection.off('JoinChannelCallback'); connection.off('ExitSharedScreen'); + connection.off('SetSpeaker'); } }); ipcMain.handle('onStop', (event) => { @@ -226,6 +232,10 @@ app.on('ready', () => { // 退出房间 await connection.invoke(str, data.roomNum) break; + case 'SetSpeakerCallback': + // 发言人设置成功 + await connection.invoke(str, data) + break; } }); ipcMain.handle('onOtherSignalr', (event) => { @@ -394,6 +404,13 @@ app.on('ready', () => { key: 'ExitSharedScreen' }) }); + // 设置发言人 + connection.on("SetSpeaker", (RoomManagerInputDTO) => { + mainWindow.webContents.send('onSignalr', { + key: 'SetSpeaker', + RoomManagerInputDTO + }) + }); } }); // 放大缩小退出窗口 @@ -717,9 +734,7 @@ function updateHandle() { }) autoUpdater.on('update-available', function (info) { let messageStr = JSON.stringify({ type: '0' }) - setTimeout(() => { - sendUpdateMessage(messageStr) - }, 5000) + sendUpdateMessage(messageStr) }) autoUpdater.on('update-not-available', function (info) { diff --git a/package.json b/package.json index 98dada8..af25b5e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "WGShare.Metting", "private": true, - "version": "0.6.5", + "version": "0.7.1", "main": "main.js", "authors": "yj", "description": "智汇享", diff --git a/preload.js b/preload.js index 4879689..22bc873 100644 --- a/preload.js +++ b/preload.js @@ -91,6 +91,10 @@ window.electron = { setEnv: (str) => { ipcRenderer.invoke('setEnv', str) }, + // 更新 + updateHandle: () => { + ipcRenderer.invoke('updateHandle') + }, // 通知下载最新的包 onDownload: (type) => { ipcRenderer.invoke('updateDownload', type) diff --git a/src/App.tsx b/src/App.tsx index 7e28ca6..3e264ca 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -260,6 +260,12 @@ const App: React.FC = () => { storage.removeItem('user') navigate('/login') } + } else if (e.key === 'reconnect') { + if (e.value == true) { + if (location.hash.indexOf('/meeting') === -1) { + window.electron.updateHandle() + } + } } }; return ( diff --git a/src/api/Meeting/index.ts b/src/api/Meeting/index.ts index 6bf6328..7005eba 100644 --- a/src/api/Meeting/index.ts +++ b/src/api/Meeting/index.ts @@ -71,14 +71,20 @@ export const PostRoomManager = (data: any) => request({ url: `/room/manager`, method: 'post', - data + data: { + ...data, + SettingUserId: '' + } }) export const DeleteRoomManager = (data: any) => request({ url: `/room/manager`, method: 'delete', - data + data: { + ...data, + SettingUserId: '' + } }) export const GetRoomKickout = (roomNum: string, kickUid: string) => diff --git a/src/components/Avatar/index.tsx b/src/components/Avatar/index.tsx index fadc0f6..b561d53 100644 --- a/src/components/Avatar/index.tsx +++ b/src/components/Avatar/index.tsx @@ -1,5 +1,5 @@ import styles from '@/components/Avatar/index.module.scss' -import { useState, useImperativeHandle, forwardRef } from "react"; +import { memo, useImperativeHandle, forwardRef } from "react"; const Avatar = forwardRef((props: any, ref: any) => { useImperativeHandle(ref, () => ({ getData: () => { @@ -15,4 +15,4 @@ const Avatar = forwardRef((props: any, ref: any) => { ) }) -export default Avatar \ No newline at end of file +export default memo(Avatar) \ No newline at end of file diff --git a/src/components/EquipmentManagement/index.tsx b/src/components/EquipmentManagement/index.tsx index 4f740ee..6de9410 100644 --- a/src/components/EquipmentManagement/index.tsx +++ b/src/components/EquipmentManagement/index.tsx @@ -1,7 +1,7 @@ import styles from '@/components/EquipmentManagement/index.module.scss' import { getKeyOpenChildWindow } from '@/utils/package/public'; import { Button, Modal, Select, Slider, message } from 'antd'; -import { useState, useImperativeHandle, forwardRef } from "react"; +import { useState, useImperativeHandle, forwardRef, memo } from "react"; const EquipmentManagement = forwardRef((props: any, ref: any) => { useImperativeHandle(ref, () => ({ changeModal: async (uid: string, userName: string) => { @@ -116,4 +116,4 @@ const EquipmentManagement = forwardRef((props: any, ref: any) => { ) }) -export default EquipmentManagement \ No newline at end of file +export default memo(EquipmentManagement) \ No newline at end of file diff --git a/src/components/FeedBackModel/index.tsx b/src/components/FeedBackModel/index.tsx index f46997a..b38296e 100644 --- a/src/components/FeedBackModel/index.tsx +++ b/src/components/FeedBackModel/index.tsx @@ -2,7 +2,7 @@ import { PostFeedback } from '@/api/Home/Index'; import styles from '@/components/FeedBackModel/index.module.scss' import { Button, message, Modal, Rate } from 'antd'; import TextArea from 'antd/es/input/TextArea'; -import { useState, useImperativeHandle, forwardRef } from "react"; +import { useState, useImperativeHandle, forwardRef, memo } from "react"; const FeedBackModel = forwardRef((_props: any, ref: any) => { useImperativeHandle(ref, () => ({ changeModal: () => { @@ -135,4 +135,4 @@ const FeedBackModel = forwardRef((_props: any, ref: any) => { ) }) -export default FeedBackModel \ No newline at end of file +export default memo(FeedBackModel) \ No newline at end of file diff --git a/src/components/InvitingPersonnelModal/index.tsx b/src/components/InvitingPersonnelModal/index.tsx index ee8b83f..31e3626 100644 --- a/src/components/InvitingPersonnelModal/index.tsx +++ b/src/components/InvitingPersonnelModal/index.tsx @@ -1,6 +1,6 @@ import styles from '@/components/InvitingPersonnelModal/index.module.scss' import { Button, Checkbox, Input, Modal, Pagination, Radio, message } from 'antd'; -import { useState, useImperativeHandle, forwardRef, useEffect } from "react"; +import { useState, useImperativeHandle, forwardRef, useEffect, memo } from "react"; import { SearchOutlined } from '@ant-design/icons'; import { GetUserList } from '@/api/Home/User'; import { useLocation } from 'react-router-dom'; @@ -197,4 +197,4 @@ const InvitingPersonnelModal = forwardRef((props: any, ref: any) => { }) -export default InvitingPersonnelModal \ No newline at end of file +export default memo(InvitingPersonnelModal) \ No newline at end of file diff --git a/src/components/JoinMeetingModal/index.tsx b/src/components/JoinMeetingModal/index.tsx index 048b22b..d5dba68 100644 --- a/src/components/JoinMeetingModal/index.tsx +++ b/src/components/JoinMeetingModal/index.tsx @@ -1,7 +1,7 @@ import styles from '@/components/JoinMeetingModal/index.module.scss' import ImageUrl from '@/utils/package/imageUrl'; import { Modal, message } from 'antd'; -import { useState, useImperativeHandle, forwardRef, useRef } from "react"; +import { useState, useImperativeHandle, forwardRef, useRef, memo } from "react"; import Avatar from '@/components/Avatar'; import JoinSetting from '../JoinSetting'; const JoinMeetingModal = forwardRef((props: any, ref: any) => { @@ -55,4 +55,4 @@ const JoinMeetingModal = forwardRef((props: any, ref: any) => { ) }) -export default JoinMeetingModal \ No newline at end of file +export default memo(JoinMeetingModal) \ No newline at end of file diff --git a/src/components/JoinSetting/index.tsx b/src/components/JoinSetting/index.tsx index a3a6f93..1bf4e7a 100644 --- a/src/components/JoinSetting/index.tsx +++ b/src/components/JoinSetting/index.tsx @@ -3,7 +3,7 @@ import { storage } from '@/utils'; import ImageUrl from '@/utils/package/imageUrl'; import { GetCheckoutRoomNum, GetRoomRtcToken, GetRoomInfo } from '@/api/Home/Index'; import { Button, Modal, message } from 'antd'; -import { useState, useImperativeHandle, forwardRef } from "react"; +import { useState, useImperativeHandle, forwardRef, memo } from "react"; import { PostRefresh } from '@/api/Login'; import Avatar from '@/components/Avatar'; import { useNavigate } from 'react-router-dom'; @@ -236,4 +236,4 @@ const JoinSetting = forwardRef((_props: any, ref: any) => { ) }) -export default JoinSetting \ No newline at end of file +export default memo(JoinSetting) \ No newline at end of file diff --git a/src/components/MeetingDisconnected/index.tsx b/src/components/MeetingDisconnected/index.tsx index 077794a..78a2282 100644 --- a/src/components/MeetingDisconnected/index.tsx +++ b/src/components/MeetingDisconnected/index.tsx @@ -1,6 +1,6 @@ import styles from '@/components/MeetingDisconnected/index.module.scss' import { InfoCircleOutlined } from '@ant-design/icons'; -import { useState, useImperativeHandle, forwardRef } from "react"; +import { useState, useImperativeHandle, forwardRef, memo } from "react"; const MeetingDisconnected = forwardRef((props: any, ref: any) => { useImperativeHandle(ref, () => ({ changeModal: (bool: boolean) => { @@ -17,4 +17,4 @@ const MeetingDisconnected = forwardRef((props: any, ref: any) => { ) }) -export default MeetingDisconnected \ No newline at end of file +export default memo(MeetingDisconnected) \ No newline at end of file diff --git a/src/components/Operation/index.tsx b/src/components/Operation/index.tsx index fa55f90..ec831b8 100644 --- a/src/components/Operation/index.tsx +++ b/src/components/Operation/index.tsx @@ -1,6 +1,6 @@ import styles from '@/components/Operation/index.module.scss' import ImageUrl from '@/utils/package/imageUrl'; -import { useEffect, useState } from "react"; +import { useEffect, useState, memo } from "react"; type OperationKeyType = 'minimize' | 'quit' | 'maximize' | 'unmaximize' | 'hide' | 'show'; type OperationType = { icon: string; @@ -100,4 +100,4 @@ const Operation: React.FC = () => { ) } -export default Operation \ No newline at end of file +export default memo(Operation) \ No newline at end of file diff --git a/src/components/QuitTips/index.tsx b/src/components/QuitTips/index.tsx index 3ace7e8..950a75f 100644 --- a/src/components/QuitTips/index.tsx +++ b/src/components/QuitTips/index.tsx @@ -2,7 +2,7 @@ import styles from '@/components/QuitTips/index.module.scss' import { storage } from '@/utils'; import { InfoCircleOutlined } from '@ant-design/icons'; import { Button, Checkbox, Modal, Radio } from 'antd'; -import { useState, useImperativeHandle, forwardRef } from "react"; +import { useState, useImperativeHandle, forwardRef, memo } from "react"; type OperationKeyType = 'minimize' | 'quit' | 'maximize' | 'unmaximize' | 'hide' | 'show'; const QuitTips = forwardRef((props: any, ref: any) => { useImperativeHandle(ref, () => ({ @@ -66,4 +66,4 @@ const QuitTips = forwardRef((props: any, ref: any) => { ) }) -export default QuitTips \ No newline at end of file +export default memo(QuitTips) \ No newline at end of file diff --git a/src/components/SharedFilesModel/index.tsx b/src/components/SharedFilesModel/index.tsx index 2eb8029..6cbfa9a 100644 --- a/src/components/SharedFilesModel/index.tsx +++ b/src/components/SharedFilesModel/index.tsx @@ -8,7 +8,7 @@ import { VerticalAlignBottomOutlined } from '@ant-design/icons'; import { Button, Input, message, Modal, Pagination, Popconfirm, Progress, Table } from 'antd'; -import { forwardRef, useEffect, useImperativeHandle, useState, useRef } from "react"; +import { forwardRef, useEffect, useImperativeHandle, useState, useRef, memo } from "react"; import { DeleteRoomFile, GetRoomFile, GetRoomFileDwUrl, GetRoomUpFileurl, GetRoomUserItem, PostRoomFile } from '@/api/Meeting'; import axios from 'axios'; import { useLocation } from 'react-router-dom'; @@ -393,4 +393,4 @@ const SharedFilesModel = forwardRef((props: any, ref: any) => { ) }) -export default SharedFilesModel +export default memo(SharedFilesModel) diff --git a/src/components/SingIn/index.tsx b/src/components/SingIn/index.tsx index 5ea64b1..a3d60fa 100644 --- a/src/components/SingIn/index.tsx +++ b/src/components/SingIn/index.tsx @@ -2,7 +2,7 @@ import { GetRoomSingnIn, PostRoomSingnIn } from '@/api/Meeting'; import styles from '@/components/SingIn/index.module.scss' import { storage } from '@/utils'; import { Button, message, Modal } from 'antd'; -import { useState, useImperativeHandle, forwardRef } from "react"; +import { useState, useImperativeHandle, forwardRef, memo } from "react"; const SingIn = forwardRef((props: any, ref: any) => { useImperativeHandle(ref, () => ({ changeModal: () => { @@ -85,4 +85,4 @@ const SingIn = forwardRef((props: any, ref: any) => { ) }) -export default SingIn \ No newline at end of file +export default memo(SingIn) \ No newline at end of file diff --git a/src/components/SpeakerModeModal/index.tsx b/src/components/SpeakerModeModal/index.tsx index c1ef692..73e5351 100644 --- a/src/components/SpeakerModeModal/index.tsx +++ b/src/components/SpeakerModeModal/index.tsx @@ -1,6 +1,6 @@ import styles from '@/components/SpeakerModeModal/index.module.scss' import { Checkbox, Modal } from 'antd'; -import { useState, useImperativeHandle, forwardRef } from "react"; +import { useState, useImperativeHandle, forwardRef, memo } from "react"; import { storage } from '@/utils'; import { useLocation } from 'react-router-dom'; import { GetSyncView } from '@/api/Meeting'; @@ -147,4 +147,4 @@ const FourScreenMode: React.FC = ({ onClick, meetingMode }) => { ) } -export default SpeakerModeModal \ No newline at end of file +export default memo(SpeakerModeModal) \ No newline at end of file diff --git a/src/components/StupWizard/index.tsx b/src/components/StupWizard/index.tsx index 06e17de..1dd1df4 100644 --- a/src/components/StupWizard/index.tsx +++ b/src/components/StupWizard/index.tsx @@ -1,7 +1,7 @@ import styles from '@/components/StupWizard/index.module.scss' import ImageUrl from '@/utils/package/imageUrl'; import { Button, Checkbox, Empty, Input, message, Modal, Popover, Radio, Select, Slider, Space } from 'antd'; -import { forwardRef, useEffect, useImperativeHandle, useState } from "react"; +import { forwardRef, useEffect, useImperativeHandle, useState, memo } from "react"; import { agora } from '@/utils/package/agora' import { CloseOutlined, LoadingOutlined, QuestionCircleOutlined } from '@ant-design/icons'; import { storage } from '@/utils'; @@ -969,4 +969,4 @@ const FileComponents = () => { ) } -export default StupWizard +export default memo(StupWizard) diff --git a/src/components/TldrawView/index.tsx b/src/components/TldrawView/index.tsx index 0ffd680..fc7455d 100644 --- a/src/components/TldrawView/index.tsx +++ b/src/components/TldrawView/index.tsx @@ -1,4 +1,4 @@ -import { useEffect } from "react"; +import { useEffect, memo } from "react"; import '@/components/TldrawView/index.scss' import { Tldraw, @@ -44,4 +44,4 @@ const TldrawView: React.FC = () => { ) } -export default TldrawView \ No newline at end of file +export default memo(TldrawView) \ No newline at end of file diff --git a/src/components/UpdateModal/index.tsx b/src/components/UpdateModal/index.tsx index 261327d..cf5adf4 100644 --- a/src/components/UpdateModal/index.tsx +++ b/src/components/UpdateModal/index.tsx @@ -2,7 +2,7 @@ import styles from '@/components/UpdateModal/index.module.scss' import ImageUrl from '@/utils/package/imageUrl'; import { getUpdateUrl } from '@/utils/package/public'; import { Button, Flex, Modal, Progress } from 'antd'; -import { forwardRef, useImperativeHandle, useState } from "react"; +import { forwardRef, useImperativeHandle, useState, memo } from "react"; const UpdateModal = forwardRef((props: any, ref: any) => { useImperativeHandle(ref, () => ({ @@ -87,4 +87,4 @@ const UpdateModal = forwardRef((props: any, ref: any) => { ) }) -export default UpdateModal +export default memo(UpdateModal) diff --git a/src/components/UserName/index.tsx b/src/components/UserName/index.tsx index 1bc10d7..e60c209 100644 --- a/src/components/UserName/index.tsx +++ b/src/components/UserName/index.tsx @@ -2,7 +2,7 @@ import { PutAlterUname } from '@/api/Meeting'; import styles from '@/components/UserName/index.module.scss' import { storage } from '@/utils'; import { Button, Input, message, Modal } from 'antd'; -import { useState, useImperativeHandle, forwardRef } from "react"; +import { useState, useImperativeHandle, forwardRef, memo } from "react"; const UserName = forwardRef((props: any, ref: any) => { useImperativeHandle(ref, () => ({ changeModal: (data: any) => { @@ -71,4 +71,4 @@ const UserName = forwardRef((props: any, ref: any) => { ) }) -export default UserName \ No newline at end of file +export default memo(UserName) \ No newline at end of file diff --git a/src/components/UserVideo/index.tsx b/src/components/UserVideo/index.tsx index c87e527..0535fb0 100644 --- a/src/components/UserVideo/index.tsx +++ b/src/components/UserVideo/index.tsx @@ -3,7 +3,7 @@ import styles from '@/components/UserVideo/index.module.scss' import { GetPolling } from '@/api/Meeting'; import { agora } from '@/utils/package/agora'; import { Button, Empty, Select, message } from 'antd'; -import { useEffect, useState } from "react"; +import { useEffect, useState, memo } from "react"; import { useLocation } from 'react-router'; import { VideoStreamType } from 'agora-electron-sdk'; const { setInterval, clearInterval } = require('timers'); @@ -154,4 +154,4 @@ const UserVideo: React.FC = () => { ) } -export default UserVideo +export default memo(UserVideo) diff --git a/src/page/Meeting/ShareScreenWindow/index.tsx b/src/page/Meeting/ShareScreenWindow/index.tsx index 25984a4..d67009f 100644 --- a/src/page/Meeting/ShareScreenWindow/index.tsx +++ b/src/page/Meeting/ShareScreenWindow/index.tsx @@ -153,10 +153,10 @@ const ShareScreenWindow: React.FC = () => { <>
- {changeCurrentSeconds(timeStr)} 共享中 + {changeCurrentSeconds(timeStr)} {!isExpand ? '共享中' : ''} {networkIcon(currentEffective)} - 网络质量:{networkQuality.level} + {!isExpand ? 网络质量:{networkQuality.level} : ''} 延迟:{networkOther.lastmileDelay}ms @@ -223,7 +223,7 @@ const ShareScreenWindow: React.FC = () => {
{ setIsExpand(!isExpand) window.electron.setChildWindow({ - width: isExpand ? 440 : 440 / 2, + width: isExpand ? 440 : 440 / 1.6, key: 'shareScreenWindow', }) }}> diff --git a/src/page/Meeting/index.tsx b/src/page/Meeting/index.tsx index 278e590..f5afd9b 100644 --- a/src/page/Meeting/index.tsx +++ b/src/page/Meeting/index.tsx @@ -8,7 +8,7 @@ import { SearchOutlined, EllipsisOutlined, ExclamationCircleFilled, FullscreenEx import { useLocation, useNavigate } from 'react-router-dom'; import { thumbImageBufferToBase64 } from '@/utils/package/base64' import { storage } from '@/utils'; -import { GetRoomUser, PostOpenMicr, PostOpenCamera, GetLeaveAll, PostRoomManager, DeleteRoomManager, GetRoomKickout, GetShowUser, PostShowUser, PostMuteAll, GetRoomUserItem, GetApplySpeak, PostSharedScreen } from '@/api/Meeting'; +import { GetRoomUser, PostOpenMicr, GetSharedScreen, PostOpenCamera, GetLeaveAll, PostRoomManager, DeleteRoomManager, GetRoomKickout, GetShowUser, PostShowUser, PostMuteAll, GetRoomUserItem, GetApplySpeak, PostSharedScreen } from '@/api/Meeting'; import ImageUrl from '@/utils/package/imageUrl' import { agora } from '@/utils/package/agora' import dayjs from 'dayjs'; @@ -162,6 +162,7 @@ const Meeting: React.FC = () => { const [_speackUid, setSpeackUid] = useState([]) const [currentSpeakUser, setCurrentSpeakUser] = useState([]) const [chatList, setChatList] = useState([]) + const [applyUserList, setApplyUserList] = useState([]) const [isExpand, setIsExpand] = useState(false) const [currentVideoId, setCurrentVideoId] = useState('') const [currentVideoUid, setCurrentVideoUid] = useState('') @@ -1022,6 +1023,10 @@ const Meeting: React.FC = () => { return res }) break; + // 共享 + case 'SetSpeaker': + window.electron.onInvoke('SetSpeakerCallback', item.RoomManagerInputDTO) + break; } }) return () => { @@ -1177,6 +1182,49 @@ const Meeting: React.FC = () => { return () => clearTimeout(timer); }, [isClickedMediaSteam]); + useEffect(() => { + let timer: NodeJS.Timeout | undefined; + if (timer) { + clearInterval(timer) + timer = undefined; + } + if (applyUserList.length) { + timer = setInterval(() => { + setRoomUserList((list: any) => { + let newApplyUserList = [...applyUserList] + newApplyUserList.forEach((item: any, index: number) => { + const user = list.find((i: any) => i.uid === item.uid) + if (user) { + if (user.isRoomManager) { + newApplyUserList.splice(index, 1) + } else { + item.status-- + if (item.status <= 0) { + message.error(`设置${user.userName}发言人失败!`) + newApplyUserList.splice(index, 1) + } + } + } else { + newApplyUserList.splice(index, 1) + } + }); + if (newApplyUserList.length === 0) { + clearInterval(timer) + timer = undefined; + } + setApplyUserList(newApplyUserList) + return list + }) + }, 1000); + } else { + if (timer) { + clearInterval(timer) + timer = undefined; + } + } + return () => timer ? clearTimeout(timer) : null; + }, [applyUserList]); + useEffect(() => { const elements = document.querySelectorAll('.intersectionObserver-view'); if (elements.length && currentVideoId) { @@ -1681,8 +1729,15 @@ const Meeting: React.FC = () => { case '共享屏幕': await getUserRoomInfo().then(async (res) => { if (res) { - getDesktopCapturerVideo() - setIsSharedScreenModal(true) + GetSharedScreen(state.channelId).then(req => { + if (req.code === 200) { + if (res.data) { + setIsShare(res.data) + } + getDesktopCapturerVideo() + setIsSharedScreenModal(true) + } + }) } else { message.error(msgTips) } @@ -1977,6 +2032,13 @@ const Meeting: React.FC = () => { roomId: data.roomId, roomNum: data.roomNum, userId: data.userId + }).then(res => { + if (res.code === 200) { + setApplyUserList((newChatList: any) => [...newChatList, { + uid: data.userId, + status: 5 + }]) + } }) } } @@ -2584,7 +2646,7 @@ const Meeting: React.FC = () => { {isAdmin && currentLookUserAccount ? getSettingIcon() : null}
{roomUserList.map((item: any, index: number) => { - return (index <= 19 && item.isRoom && item.isAdmin ?
{
: null) } )} - {roomUserList.length > 6 ?
+ {isAdmin > 6 ?
{meetingMode === "StandardMode" ?
{ const container = document.getElementById('videoView') as HTMLElement; container.scrollLeft -= 100 diff --git a/src/render.d.ts b/src/render.d.ts index ad0eae5..0aeefea 100644 --- a/src/render.d.ts +++ b/src/render.d.ts @@ -25,6 +25,7 @@ export interface IElectronAPI { quitAndInstall: (callBack: Function) => void; isOpenWindows: (callBack: Function) => void; setEnv: (str: string) => any; + updateHandle: () => any; getVersion: () => Promise; isVisible: () => Promise; setRegistry: (uuid: string) => any;