diff --git a/electron/main/index.ts b/electron/main/index.ts index 9b7634b..6cb3f08 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -1,4 +1,4 @@ -import {app, BrowserWindow, shell, ipcMain} from 'electron' +import {app, BrowserWindow, shell, ipcMain, ipcRenderer, contextBridge} from 'electron' import Store from "electron-store"; import {release} from 'node:os' import {join} from 'node:path' @@ -45,12 +45,29 @@ const indexHtml = join(process.env.DIST, 'index.html') // electron-store 存储 let store = new Store(); + +let defaultSizeData = { + height: 800, + width: 1100, +} + +interface WindowSize { + height: number, + width: number +} + +let windowSizeData = store.get("windowSizeData") as WindowSize; +if (windowSizeData) { + defaultSizeData.height = windowSizeData.height; + defaultSizeData.width = windowSizeData.width; +} + async function createWindow() { win = new BrowserWindow({ title: 'KafkaDesktop', icon: join(process.env.VITE_PUBLIC, 'favicon.ico'), - height: 800, - width: 1100, + height: defaultSizeData.height, + width: defaultSizeData.width, webPreferences: { preload, // Warning: Enable nodeIntegration and disable contextIsolation is not secure in production @@ -84,6 +101,14 @@ async function createWindow() { return {action: 'deny'} }) + win.on("resize", (e: any) => { + let sizeData = win?.getContentBounds(); + if (sizeData) { + defaultSizeData.width = sizeData.width; + defaultSizeData.height = sizeData.height; + } + }) + // Apply electron-updater update(win) } @@ -91,6 +116,8 @@ async function createWindow() { app.whenReady().then(createWindow) app.on('window-all-closed', () => { + // 程序关闭存储程序窗口大小 + store.set("windowSizeData", defaultSizeData); win = null if (process.platform !== 'darwin') app.quit() }) @@ -146,4 +173,4 @@ ipcMain.on("getData", (event,k ) => { ipcMain.on("delData", (event,k ) => { store.delete(k); console.log('delete k successfully: ', k); -}) \ No newline at end of file +}) diff --git a/src/App.tsx b/src/App.tsx index f2bb258..c9c807e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,5 @@ -import React, {useState} from "react"; -import {Button, Container, Content, CustomProvider, Footer, Header, Sidebar} from "rsuite"; +import React, {useEffect, useState} from "react"; +import {Container, Content, CustomProvider, Sidebar} from "rsuite"; import "./index.scss" import Side from "@/components/side/side"; import PageContext from "@/PageContext"; @@ -10,28 +10,77 @@ interface State { theme: 'light' | 'dark' | 'high-contrast', } -const getTheme = () => { - const storeTheme = ipcRenderer.sendSync("getData", "theme"); - if (storeTheme) { - return storeTheme; - } - return "light"; -} - const App = () => { - const [state, setState] = useState({theme: getTheme()}); + const [state, setState] = useState(); + + const [sideWidth, setSideWidth] = useState(280); + + let sideWidthBack = 280; const changeTheme = (theme: 'light' | 'dark' | 'high-contrast') => { ipcRenderer.send("saveData", "theme", theme); setState({theme: theme}); } + const getTheme = () => { + if (state) { + return state.theme; + } + const storeTheme = ipcRenderer.sendSync("getData", "theme"); + if (storeTheme) { + setState({theme: storeTheme}); + return storeTheme; + } + return "light"; + } + const contextVal = { - theme: state.theme, + theme: getTheme(), changeTheme: changeTheme, } + const mousemove = (e: MouseEvent) => { + const mouseX = e.x; + const dragSideWidth = mouseX - 17; + + if ((dragSideWidth > 280) && (dragSideWidth < 1200)) { + setSideWidth(dragSideWidth); + sideWidthBack = dragSideWidth; + } + } + + const mouseup = () => { + document.documentElement.removeEventListener('mousemove', mousemove); + document.documentElement.removeEventListener('mouseup', mouseup); + ipcRenderer.send("saveData", "sideWidth", sideWidthBack); + } + + const bindSideBarDrag = () => { + const dragPointer = document.getElementById('drag-resize-pointer'); + + if (dragPointer) { + dragPointer.addEventListener('mousedown', (e) => { + e.preventDefault(); + + document.documentElement.addEventListener('mousemove', mousemove); + document.documentElement.addEventListener('mouseup', mouseup); + }); + } + } + + const initSideWidth = () => { + const storeValue = ipcRenderer.sendSync("getData", "sideWidth"); + if (storeValue) { + setSideWidth(storeValue); + } + } + + useEffect(() => { + initSideWidth(); + bindSideBarDrag(); + }, []); + return ( @@ -39,12 +88,12 @@ const App = () => {
- +
-
+
diff --git a/src/components/rightContent/RightContent.tsx b/src/components/rightContent/RightContent.tsx index 6efad70..a1fa1fc 100644 --- a/src/components/rightContent/RightContent.tsx +++ b/src/components/rightContent/RightContent.tsx @@ -58,10 +58,20 @@ const RightContent = () => { }); // 初始化 kafka 连接对象 开始连接 setKafkaClient(tmpClient); + let resultObj = { + success: true, + data: data + } + PubSub.publish("connectResultTopic", resultObj); }).catch(() => { toaster.push(集群连接异常,请检查配置信息是否正确, { duration: 2000 }); + let resultObj = { + success: false, + data: data + } + PubSub.publish("connectResultTopic", resultObj); }).finally(() => { if (testAdmin) { testAdmin.disconnect(); diff --git a/src/components/side/side.scss b/src/components/side/side.scss index 423aa35..27040ed 100644 --- a/src/components/side/side.scss +++ b/src/components/side/side.scss @@ -11,12 +11,18 @@ width: 100%; } +.icon-btn { + float: right; + margin: 0 0 0 10px; +} + .conn-btn { width: 100%; } .row-container { - margin: 0 0 0 -10px + margin: 0 0 0 -10px; + display: flex; } .light-conn-row { @@ -27,4 +33,4 @@ .dark-conn-row { //background-color: #11ea40 !important; color: #34c3ff; -} \ No newline at end of file +} diff --git a/src/components/side/side.tsx b/src/components/side/side.tsx index 09c53b7..92ac190 100644 --- a/src/components/side/side.tsx +++ b/src/components/side/side.tsx @@ -70,8 +70,15 @@ const Side = () => { console.log("side mount"); const storeValue = ipcRenderer.sendSync("getData", "clusterInfo"); setClusterList(storeValue == undefined ? [] : storeValue); + // 订阅连接响应信息 + PubSub.subscribe("connectResultTopic", connectResultConsumer); }, []) + const connectResultConsumer = (msg: any, data: any) => { + if (data.success) { + setConnRowData(data.data); + } + } const changeTheme = () => { const targetTheme = context.theme == "light" ? "dark" : "light"; @@ -80,7 +87,7 @@ const Side = () => { const connect = (rowData: RowDataType) => { console.log('connect rowData:', rowData); - setConnRowData(rowData); + // setConnRowData(rowData); // publish a topic asynchronously PubSub.publish('clusterInfoTopic', rowData); } @@ -147,25 +154,22 @@ const Side = () => {
- - - - - - - - } - onClick={changeTheme} - /> - - - - +
+
+ +
+
+ + } + onClick={changeTheme} + /> +
+
{ }} > - + clusterName diff --git a/src/index.scss b/src/index.scss index e496a07..3f23859 100644 --- a/src/index.scss +++ b/src/index.scss @@ -5,6 +5,8 @@ body, html { font-family: 'LXGWWenKaiMono-Bold', sans-serif; font-size: 0.99em; + // 拖拽大小修改可能会出现滚动条,超出部分hidden处理 + overflow: hidden; } @font-face {