Browse Source

增加最小化,最大化,关闭,程序图标

Caner 2 years ago
parent
commit
ccf808bb10

BIN
electron/icon/playGame.png


+ 64 - 14
electron/main.js

@@ -1,9 +1,6 @@
-const { app, BrowserWindow, Menu, ipcMain, globalShortcut } = require('electron');
-const path = require('path');
+const { app, BrowserWindow, Menu, ipcMain, globalShortcut, dialog, screen, Tray } = require('electron');
+const { join } = require('path');
 const HID = require('node-hid');
-const devices = HID.devices();
-const logitech = devices.filter(el => el.manufacturer == 'Logitech');
-const data = new HID.HID(logitech[0].vendorId, logitech[0].productId);
 
 class MainSerivce {
   constructor() {
@@ -11,9 +8,10 @@ class MainSerivce {
     app.commandLine.appendSwitch('wm-window-animations-disabled') // 拖动闪屏
     this.loadingWin = null
     this.mainWin = null
+    this.icon = join(__dirname, './icon/playGame.png')
     app.on('ready', this.onRead.bind(this))
     app.on('activate', this.createWindow.bind(this))
-    app.on('window-all-closed',app.quit)
+    app.on('window-all-closed', app.quit)
   }
 
   createLoading() {
@@ -41,12 +39,13 @@ class MainSerivce {
         height: 760,
         frame: false,
         transparent: true,
+        icon: this.icon,
         webPreferences: {
           contextIsolation: true,
           nodeIntegration: true,
           webSecurity: false, // 去掉跨越
           nodeIntegrationInWorker: true,
-          preload: path.join(__dirname, './preload.js')
+          preload: join(__dirname, './preload.js')
         },
         show: false
       })// 创建一个窗口
@@ -59,7 +58,7 @@ class MainSerivce {
       }
 
       // 事件监听
-      this.mainWin.on('close', () => {this.mainWin = null})
+      this.mainWin.on('close', () => { this.mainWin = null })
     }
   }
 
@@ -67,20 +66,71 @@ class MainSerivce {
     this.createLoading()
     this.createWindow()
 
+    // 图标
+    const tray = new Tray(this.icon)
+    const contextMenu = Menu.buildFromTemplate([
+      {
+        label: '退出',
+        click: () => {
+          this.mainWin.close()
+          app.quit()
+        }
+      }
+    ])
+    tray.setContextMenu(contextMenu)
+    tray.setToolTip('控制端')
+    tray.on('click', () => { this.mainWin.show() })
+
     // 注册调试模式
     globalShortcut.register('Control+F12', () => {
-      // win.flashFrame(true)
       this.mainWin.webContents.toggleDevTools()
     })
 
-    ipcMain.once('close-loading', () => {
-      this.loadingWin.close()
-      this.mainWin.show()
+    // 禁用右键
+    this.mainWin.hookWindowMessage(278, () => {
+      this.mainWin.setEnabled(false);//窗口禁用
+      setTimeout(() => {
+        this.mainWin.setEnabled(true);
+      }, 100) //延时太快会立刻启动,太慢会妨碍窗口其他操作,可自行测试最佳时间
+      return true
     })
 
-    data.on('data', (db) => {
-      if(this.mainWin.isEnabled()) this.mainWin?.webContents.send('contrlData',db)
+    // 通信
+    ipcMain.on('signal', (_, evt, data) => {
+      if (evt === 'close-loading') {
+        if (this.loadingWin) this.loadingWin.close()
+        this.mainWin.show()
+        // this.connectLogi()
+      } else if (evt === 'minWin') {
+        this.mainWin.minimize()
+      } else if (evt === 'closeWin') {
+        this.mainWin.close()
+      } else if (evt === 'maxWin') {
+        const { width, height } = screen.getPrimaryDisplay().size
+        if (data) { this.mainWin.setBounds({ x: 0, y: 0, width, height }) } else {
+          this.mainWin.setBounds({ width: 1300, height: 760 })
+          this.mainWin.center()
+        }
+      }
     })
   }
+
+  connectLogi() {
+    try {
+      const devices = HID.devices();
+      const logitech = devices.filter(el => el.manufacturer == 'Logitech');
+      const data = new HID.HID(logitech[0].vendorId, logitech[0].productId);
+      data.on('data', (db) => {
+        if (this.mainWin) this.mainWin?.webContents.send('contrlData', db)
+      })
+    } catch (error) {
+      dialog.showMessageBox(this.mainWin, { message: '连接方向盘失败', type: 'error', title: '连接错误', detail: '请检查方向盘是否连接' }).then(({ response }) => {
+        if (!response) {
+          this.mainWin.close()
+          app.quit()
+        }
+      })
+    }
+  }
 };
 new MainSerivce()

+ 3 - 3
electron/preload.js

@@ -1,7 +1,7 @@
 const { contextBridge, ipcRenderer } = require('electron');
 
 contextBridge.exposeInMainWorld('$electron', {
-  send: (channel, args) => ipcRenderer.send(channel, args),
-  once: (channel, listener) => ipcRenderer.once(channel, listener),
-  on: (channel, args) => ipcRenderer.on(channel, args)
+  send: (event, args) => ipcRenderer.send('signal', event, args),
+  once: (event, callBack) => ipcRenderer.once(event, (_, args) => callBack(args)),
+  on: (event, callBack) => ipcRenderer.on(event, (_, args) => callBack(args))
 })

+ 1 - 9
src/App.vue

@@ -2,13 +2,5 @@
   <router-view />
 </template>
 <script setup lang='ts'>
-import { onMounted } from 'vue'
-
-onMounted(() => {
-  // 通知主进程是否完成渲染
-  const electron = window.$electron || null
-  if (electron) {
-    electron.send('close-loading')
-  }
-})
+window.$electron.send('close-loading')
 </script>

+ 1 - 0
src/assets/icons/max.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1686466364777" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3580" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M959.72 0H294.216a63.96 63.96 0 0 0-63.96 63.96v127.92H64.28A63.96 63.96 0 0 0 0.32 255.84V959.4a63.96 63.96 0 0 0 63.96 63.96h703.56a63.96 63.96 0 0 0 63.96-63.96V792.465h127.92a63.96 63.96 0 0 0 63.96-63.96V63.96A63.96 63.96 0 0 0 959.72 0zM767.84 728.505V959.4H64.28V255.84h703.56z m189.322 0H831.8V255.84a63.96 63.96 0 0 0-63.96-63.96H294.216V63.96H959.72z" p-id="3581"></path></svg>

+ 1 - 0
src/assets/icons/maxMin.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1686466360385" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3440" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M812.3 959.4H213.7c-81.6 0-148-66.4-148-148V212.9c0-81.6 66.4-148 148-148h598.5c81.6 0 148 66.4 148 148v598.5C960.3 893 893.9 959.4 812.3 959.4zM213.7 120.9c-50.7 0-92 41.3-92 92v598.5c0 50.7 41.3 92 92 92h598.5c50.7 0 92-41.3 92-92V212.9c0-50.7-41.3-92-92-92H213.7z" fill="" p-id="3441"></path></svg>

+ 28 - 1
src/components/login.vue

@@ -5,15 +5,31 @@ const name = ref('')
 const roomID = ref('')
 defineProps<{ err: string }>()
 const emit = defineEmits<{(evt: 'loginBack', value: { name: string, roomID: string }): void }>()
+
 function login() {
   if (name.value && roomID.value) emit('loginBack', { name: name.value, roomID: roomID.value })
 }
+
+function titleEvent(type: string) {
+  window.$electron?.send(type)
+}
 </script>
 <template>
   <div class="login">
+    <div class="login-title">
+      <Icon
+        name="close"
+        :size="21"
+        color="#fff"
+        @click="titleEvent('closeWin')"
+      />
+    </div>
     <div class="login-content">
       <div class="login-content-left" />
-      <div class="login-content-right">
+      <div
+        class="login-content-right"
+        @keydown.enter="login"
+      >
         <p>Hello, 欢迎登录</p>
         <div>
           <Icon
@@ -63,6 +79,16 @@ function login() {
   background: url(../assets/img/bg.png) center center no-repeat;
   background-size: 100% 100%;
   -webkit-app-region: drag;
+  position: relative;
+
+  &-title {
+    position: absolute;
+    right: 0.15rem;
+    top: 0.12rem;
+    cursor: pointer;
+    -webkit-app-region:no-drag;
+  }
+
   &-content {
     width: 8rem;
     height: 4rem;
@@ -82,6 +108,7 @@ function login() {
       flex: 1;
       padding: 0 0.3rem;
       -webkit-app-region: no-drag;
+
       &>p {
         font-size: 0.3rem;
         color: #5970C6;

+ 3 - 2
src/components/record.vue

@@ -1,7 +1,7 @@
 <template>
   <Icon
     name="mic"
-    :size="30"
+    :size="size"
     :color="show ? '#00CED1' : 'rgba(0, 0, 0, 0.3)'"
   />
 </template>
@@ -13,7 +13,8 @@ const mediaRecorder = ref(null as null | MediaRecorder)
 const show = ref(false)
 
 const props = defineProps<{
-  audioState: boolean
+  audioState: boolean,
+  size:number
 }>()
 // const emit = defineEmits<{(evt: 'callBack', value: Blob): void;
 // }>()

+ 36 - 20
src/views/index/index.vue

@@ -35,7 +35,7 @@ const iceServers = ref([
   }
 ])
 const num = ref(0)
-
+const winMaxOrMin = ref(false)
 // 发送语音
 function sendAudio(blob: Blob) {
   if (!socket.value && !socket.value!.connected) return
@@ -251,8 +251,10 @@ window.$electron?.on('contrlData', (db: Uint8Array) => {
 })
 
 function titleEvent(type: string) {
-  window.$electron?.send(type)
+  if (type === 'maxWin') winMaxOrMin.value = !winMaxOrMin.value
+  window.$electron?.send(type, winMaxOrMin.value)
 }
+
 onMounted(() => {
   intSoketRtc(HOST.value)
 })
@@ -273,23 +275,24 @@ onUnmounted(() => {
         <!-- 手柄状态 -->
         <Icon
           name="gemePad"
-          :size="30"
+          :size="40"
           :color="contrlState ? '#00CED1' : 'rgba(0, 0, 0, 0.3)'"
         />
         <!-- 音频状态 -->
         <Record
           class="marke-audio"
+          :size="33"
           :audio-state="audioState"
           @callBack="sendAudio"
         />
         <!-- 喇叭状态 -->
         <Icon
           name="audio"
-          :size="25"
+          :size="30"
           :color="contrlState ? '#00CED1' : 'rgba(0, 0, 0, 0.3)'"
         />
         <!-- 电量状态 -->
-        <Battery :quantity="30" />
+        <Battery :quantity="33" />
       </div>
       <div class="marke-right">
         <Icon
@@ -298,6 +301,12 @@ onUnmounted(() => {
           color="#fff"
           @click="titleEvent('minWin')"
         />
+        <Icon
+          :name="winMaxOrMin ? 'max' : 'maxMin'"
+          :size="23"
+          color="#fff"
+          @click="titleEvent('maxWin')"
+        />
         <Icon
           name="close"
           :size="23"
@@ -330,18 +339,20 @@ video {
 
 .marke {
   position: fixed;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 50px;
-  z-index: 1;
-  background: #666666;
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  overflow: hidden;
-  border-top-left-radius: 20px;
-  border-top-right-radius: 20px;
+    top: 0;
+    left: 0;
+    width: available;
+    width: -webkit-fill-available;
+    height: 0.5rem;
+    z-index: 1;
+    background: #666666;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    overflow: hidden;
+    border-top-left-radius: 20px;
+    border-top-right-radius: 20px;
+    padding-left: 1.5rem;
 
   &>div {
     display: flex;
@@ -361,10 +372,15 @@ video {
   &-right {
     display: flex;
     align-items: center;
-    margin-right: 15px;
+    margin-right: 0.15rem;
 
-    &>*:last-child {
-      margin-left: 10px;
+    &>* {
+      cursor: pointer;
+
+      &:not(:first-child) {
+        margin-left: 0.15rem;
+
+      }
     }
   }
 }

+ 3 - 3
vite.config.ts

@@ -31,9 +31,9 @@ export default () => defineConfig({
     strictPort: false,
     https: false,
   },
-  esbuild: {
-    drop: ['console', 'debugger'] // build 移除打印
-  },
+  // esbuild: {
+  //   drop: ['console', 'debugger'] // build 移除打印
+  // },
   build: {
     rollupOptions: {
       input: {