mirror of
https://github.com/yuruotong1/autoMate.git
synced 2026-03-22 13:07:17 +08:00
✨ 添加(initShow?): 新增initShow参数到OptionsType接口
🔧 更新(connect.ts): 将数据库文件路径更改为'autoMate.db' 🔧 更新(ipc.ts): 添加selectDatabaseDirectory处理程序 🔧 更新(index.ts): 调用registerAppGlobShortCut()注册全局快捷键 🔧 更新(shortCut.ts): 修改registerAppGlobShortCut()逻辑 🔧 更新(windows.ts): 添加新的code选项和配置项 🔧 更新(index.d.ts): 添加selectDatabaseDirectory全局声明 🔵 更新(index.ts): 导出selectDatabaseDirectory方法 🔧 更新(index.tsx): 更新快捷键注册逻辑 🔧 更新(index.tsx): 添加点击选择数据库目录的处理逻辑 🔧 更新(index.tsx): 添加config和setConfig到store中 🔧 更新(useStore.ts): 新增config和setConfig状态 ⚙️ 更新(types.d.ts): 添加code到WindowNameType类型
This commit is contained in:
@@ -7,6 +7,7 @@ import url from 'node:url'
|
|||||||
export interface OptionsType extends Partial<BrowserWindowConstructorOptions>{
|
export interface OptionsType extends Partial<BrowserWindowConstructorOptions>{
|
||||||
openDevTools?: boolean,
|
openDevTools?: boolean,
|
||||||
hash?: string
|
hash?: string
|
||||||
|
initShow?: boolean
|
||||||
}
|
}
|
||||||
export function createWindow(options: OptionsType): BrowserWindow { // Create the browser window.
|
export function createWindow(options: OptionsType): BrowserWindow { // Create the browser window.
|
||||||
const win = new BrowserWindow(Object.assign({
|
const win = new BrowserWindow(Object.assign({
|
||||||
@@ -27,7 +28,7 @@ export function createWindow(options: OptionsType): BrowserWindow { // Create t
|
|||||||
// 如果是在开发环境下并且选项是打开开发者工具
|
// 如果是在开发环境下并且选项是打开开发者工具
|
||||||
if (is.dev && options.openDevTools) win.webContents.openDevTools()
|
if (is.dev && options.openDevTools) win.webContents.openDevTools()
|
||||||
win.on('ready-to-show', () => {
|
win.on('ready-to-show', () => {
|
||||||
win.show()
|
options.initShow && win.show()
|
||||||
})
|
})
|
||||||
|
|
||||||
win.webContents.setWindowOpenHandler((details) => {
|
win.webContents.setWindowOpenHandler((details) => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import Database, * as BetterSqlite3 from 'better-sqlite3';
|
import Database, * as BetterSqlite3 from 'better-sqlite3';
|
||||||
import { app } from 'electron';
|
import { app } from 'electron';
|
||||||
import {resolve} from 'node:path'
|
import {resolve} from 'node:path'
|
||||||
const file = resolve(app.getPath('home'), "Desktop", 'hd.db')
|
const file = resolve(app.getPath('home'), 'autoMate.db')
|
||||||
const db: BetterSqlite3.Database = new Database(file, {});
|
const db: BetterSqlite3.Database = new Database(file, {});
|
||||||
db.pragma('journal_mode = WAL');
|
db.pragma('journal_mode = WAL');
|
||||||
export {db};
|
export {db};
|
||||||
@@ -1,5 +1,14 @@
|
|||||||
import { IpcMainInvokeEvent, ipcMain } from "electron";
|
import { IpcMainInvokeEvent, dialog, ipcMain } from "electron";
|
||||||
import * as query from './query'
|
import * as query from './query'
|
||||||
ipcMain.handle('sql', (_event: IpcMainInvokeEvent, sql: string, type: SqlActionType, params={}) => {
|
ipcMain.handle('sql', (_event: IpcMainInvokeEvent, sql: string, type: SqlActionType, params={}) => {
|
||||||
return query[type](sql, params)
|
return query[type](sql, params)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
ipcMain.handle('selectDatabaseDirectory', async () => {
|
||||||
|
const ret = await dialog.showOpenDialog({
|
||||||
|
title: "选择目录",
|
||||||
|
properties: ['openDirectory', 'createDirectory']
|
||||||
|
})
|
||||||
|
return ret.canceled?'' : ret.filePaths[0]
|
||||||
})
|
})
|
||||||
@@ -4,12 +4,13 @@ import "./db"
|
|||||||
import "./windows"
|
import "./windows"
|
||||||
import "./ipc"
|
import "./ipc"
|
||||||
import "./shortCut"
|
import "./shortCut"
|
||||||
|
import { registerAppGlobShortCut } from "./shortCut"
|
||||||
|
|
||||||
// This method will be called when Electron has finished
|
// This method will be called when Electron has finished
|
||||||
// initialization and is ready to create browser windows.
|
// initialization and is ready to create browser windows.
|
||||||
// Some APIs can only be used after this event occurs.
|
// Some APIs can only be used after this event occurs.
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
|
registerAppGlobShortCut()
|
||||||
// Set app user model id for windows
|
// Set app user model id for windows
|
||||||
electronApp.setAppUserModelId('com.electron')
|
electronApp.setAppUserModelId('com.electron')
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { IpcMainInvokeEvent } from "electron"
|
import { IpcMainInvokeEvent, dialog } from "electron"
|
||||||
import { ipcMain } from "electron"
|
import { ipcMain } from "electron"
|
||||||
import { getWindowByName } from "./windows"
|
import { getWindowByName } from "./windows"
|
||||||
|
import { config } from "./db/query"
|
||||||
const { app, globalShortcut } = require('electron')
|
const { app, globalShortcut } = require('electron')
|
||||||
|
|
||||||
ipcMain.handle("shortCut", (_event: IpcMainInvokeEvent, shortCut: string) => {
|
ipcMain.handle("shortCut", (_event: IpcMainInvokeEvent, shortCut: string) => {
|
||||||
@@ -11,11 +12,15 @@ ipcMain.handle("shortCut", (_event: IpcMainInvokeEvent, shortCut: string) => {
|
|||||||
|
|
||||||
|
|
||||||
function registerSearchShortCut(shortCut: string){
|
function registerSearchShortCut(shortCut: string){
|
||||||
|
globalShortcut.unregisterAll()
|
||||||
|
|
||||||
// const ret = findOne(`select * from config where id=1`) as {content: string}
|
// const ret = findOne(`select * from config where id=1`) as {content: string}
|
||||||
// const shortCut = JSON.parse(ret.content).shortCut as string
|
// const shortCut = JSON.parse(ret.content).shortCut as string
|
||||||
if (globalShortcut.isRegistered(shortCut)){
|
if (shortCut && globalShortcut.isRegistered(shortCut)){
|
||||||
|
dialog.showErrorBox('提示', '快捷键注册失败,请更换')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
const win = getWindowByName('search')
|
const win = getWindowByName('search')
|
||||||
const res = globalShortcut.register(shortCut, () => {
|
const res = globalShortcut.register(shortCut, () => {
|
||||||
win.isVisible() ? win.hide() : win.show()
|
win.isVisible() ? win.hide() : win.show()
|
||||||
@@ -25,4 +30,9 @@ function registerSearchShortCut(shortCut: string){
|
|||||||
app.on('will-quit', () => {
|
app.on('will-quit', () => {
|
||||||
// Unregister all shortcuts.
|
// Unregister all shortcuts.
|
||||||
globalShortcut.unregisterAll()
|
globalShortcut.unregisterAll()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const registerAppGlobShortCut =()=>{
|
||||||
|
const configData = config() as {shortCut: string}
|
||||||
|
registerSearchShortCut(configData.shortCut)
|
||||||
|
}
|
||||||
@@ -5,15 +5,29 @@ export const config = {
|
|||||||
search: {
|
search: {
|
||||||
id: 0,
|
id: 0,
|
||||||
options: {
|
options: {
|
||||||
|
initShow: true,
|
||||||
hash: '',
|
hash: '',
|
||||||
openDevTools: true,
|
openDevTools: true,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
code: {
|
||||||
|
id: 0,
|
||||||
|
options: {
|
||||||
|
initShow: false,
|
||||||
|
width: 1300,
|
||||||
|
height: 700,
|
||||||
|
openDevTools: true,
|
||||||
|
frame: true,
|
||||||
|
transparent: false,
|
||||||
|
hash: '/#config/category/contentList'
|
||||||
|
}
|
||||||
|
},
|
||||||
config: {
|
config: {
|
||||||
id: 0,
|
id: 0,
|
||||||
options: {
|
options: {
|
||||||
width: 1300,
|
initShow: false,
|
||||||
height: 600,
|
width: 600,
|
||||||
|
height: 400,
|
||||||
openDevTools: true,
|
openDevTools: true,
|
||||||
frame: true,
|
frame: true,
|
||||||
transparent: false,
|
transparent: false,
|
||||||
|
|||||||
1
ui/autoMate/src/preload/index.d.ts
vendored
1
ui/autoMate/src/preload/index.d.ts
vendored
@@ -10,6 +10,7 @@ declare global {
|
|||||||
sql: <T>(sql: string, type: SqlActionType, params?: Record<string, any>) => Promise<T>
|
sql: <T>(sql: string, type: SqlActionType, params?: Record<string, any>) => Promise<T>
|
||||||
openWindow: (name: WindowNameType) => void,
|
openWindow: (name: WindowNameType) => void,
|
||||||
closeWindow: (name: WindowNameType) => void,
|
closeWindow: (name: WindowNameType) => void,
|
||||||
|
selectDatabaseDirectory: () => Promise<string>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ const api = {
|
|||||||
closeWindow: (name: WindowNameType) =>{
|
closeWindow: (name: WindowNameType) =>{
|
||||||
ipcRenderer.send("closeWindow", name)
|
ipcRenderer.send("closeWindow", name)
|
||||||
},
|
},
|
||||||
|
selectDatabaseDirectory: () => {
|
||||||
|
return ipcRenderer.invoke("selectDatabaseDirectory")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export default function Search(): JSX.Element {
|
|||||||
fill="#34495e"
|
fill="#34495e"
|
||||||
strokeWidth={4}
|
strokeWidth={4}
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={()=>window.api.openWindow('config')
|
onClick={()=>window.api.openWindow('code')
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
@@ -31,7 +31,10 @@ export default function Search(): JSX.Element {
|
|||||||
autoFocus
|
autoFocus
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
<section className="text-center text-slate-600 text-xs mt-2">autoMate</section>
|
<section className="text-center text-slate-600 text-xs mt-2 nodrag">
|
||||||
|
autoMate
|
||||||
|
<span className="text-blue-600" onClick={()=>window.api.openWindow('config')}>配置信息</span>
|
||||||
|
</section>
|
||||||
</main>
|
</main>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
import { useStore } from "@renderer/store/useStore"
|
// import { useStore } from "@renderer/store/useStore"
|
||||||
|
|
||||||
export default() => {
|
export default() => {
|
||||||
const setError = useStore(state => state.setError)
|
// const setError = useStore(state => state.setError)
|
||||||
const register = async ()=>{
|
// const register = async ()=>{
|
||||||
const ret = (await window.api.sql('', 'config')) as Record<string, string>
|
// const ret = (await window.api.sql('', 'config')) as Record<string, string>
|
||||||
const isBind = await window.api.shortCut(ret.shortCut)
|
// const isBind = await window.api.shortCut(ret.shortCut)
|
||||||
isBind || setError("注册失败")
|
// isBind || setError("注册失败")
|
||||||
|
|
||||||
}
|
// }
|
||||||
return {
|
// return {
|
||||||
register
|
// register
|
||||||
}
|
// }
|
||||||
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
import Result from "@renderer/components/Result"
|
import Result from "@renderer/components/Result"
|
||||||
import Search from "@renderer/components/Search"
|
import Search from "@renderer/components/Search"
|
||||||
import { CodeProvider } from "@renderer/context/CodeContext"
|
import { CodeProvider } from "@renderer/context/CodeContext"
|
||||||
import useShortCut from "@renderer/hooks/useShortCut"
|
|
||||||
import Error from "@renderer/components/Error"
|
import Error from "@renderer/components/Error"
|
||||||
import { MutableRefObject, useEffect, useRef } from "react"
|
import { MutableRefObject, useEffect, useRef } from "react"
|
||||||
import useIgnoreMouseEvents from "@renderer/hooks/useIgnoreMouseEvents"
|
import useIgnoreMouseEvents from "@renderer/hooks/useIgnoreMouseEvents"
|
||||||
|
import { useStore } from "@renderer/store/useStore"
|
||||||
|
|
||||||
|
|
||||||
function Home(): JSX.Element {
|
function Home(): JSX.Element {
|
||||||
const mainRef = useRef<HTMLDivElement>(null)
|
const mainRef = useRef<HTMLDivElement>(null)
|
||||||
const {setIgnoreMouseEvents} = useIgnoreMouseEvents()
|
const {setIgnoreMouseEvents} = useIgnoreMouseEvents()
|
||||||
|
const config = useStore(state => state.config)
|
||||||
|
window.api.shortCut(config.shortCut)
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
setIgnoreMouseEvents(mainRef as MutableRefObject<HTMLDivElement>)
|
setIgnoreMouseEvents(mainRef as MutableRefObject<HTMLDivElement>)
|
||||||
// //为开发方便,临时代码
|
// //为开发方便,临时代码
|
||||||
// window.api.openConfigWindow()
|
// window.api.openConfigWindow()
|
||||||
}, [])
|
}, [])
|
||||||
// // 注册快捷键
|
|
||||||
const {register} = useShortCut()
|
|
||||||
register()
|
|
||||||
return (
|
return (
|
||||||
<CodeProvider>
|
<CodeProvider>
|
||||||
<main className="relative" ref={mainRef}>
|
<main className="relative" ref={mainRef}>
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import { Form, useLoaderData, useSubmit } from 'react-router-dom'
|
import { Form, useLoaderData } from 'react-router-dom'
|
||||||
import styles from './styles.module.scss'
|
import styles from './styles.module.scss'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
import { useStore } from '@renderer/store/useStore'
|
||||||
|
|
||||||
export const Setting = () => {
|
export const Setting = () => {
|
||||||
const config = useLoaderData() as ConfigDataType
|
// const config = useLoaderData() as ConfigDataType
|
||||||
const submit = useSubmit()
|
|
||||||
const [keys, setKeys] = useState<string[]>([])
|
const [keys, setKeys] = useState<string[]>([])
|
||||||
|
const config = useStore(state => state.config)
|
||||||
|
const setConfig = useStore(state => state.setConfig)
|
||||||
return (
|
return (
|
||||||
<Form method="POST">
|
<Form method="POST">
|
||||||
<main className={styles.settingPage}>
|
<main className={styles.settingPage}>
|
||||||
@@ -19,23 +21,38 @@ export const Setting = () => {
|
|||||||
readOnly
|
readOnly
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.metaKey || e.ctrlKey || e.altKey) {
|
if (e.metaKey || e.ctrlKey || e.altKey) {
|
||||||
keys.push(e.code.replace(/Left|Right|Key|Digit/, ''))
|
const code = e.code.replace(/Left|Right|Key|Digit/, '')
|
||||||
|
if (keys.includes(code)) return
|
||||||
|
keys.push(code)
|
||||||
setKeys(keys)
|
setKeys(keys)
|
||||||
e.currentTarget.value = keys.join('+')
|
// 如果以数字或字母或者空格结尾
|
||||||
|
if (code.match(/^(\w|\s)$/gi)) {
|
||||||
|
e.currentTarget.value = keys.join('+')
|
||||||
|
setKeys([])
|
||||||
|
setConfig({...config, shortCut: e.currentTarget.value})
|
||||||
|
window.api.shortCut(e.currentTarget.value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
onKeyUp={(e) => {
|
|
||||||
setKeys([])
|
|
||||||
console.log("keys", e.currentTarget.value)
|
|
||||||
submit(e.currentTarget.form, {method: 'POST'})
|
|
||||||
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<h5>数据库</h5>
|
<h5>数据库</h5>
|
||||||
<input type="text" name="databaseDirectory" defaultValue={config.databaseDirectory} />
|
<input
|
||||||
|
type="text"
|
||||||
|
name="databaseDirectory"
|
||||||
|
readOnly
|
||||||
|
defaultValue={config.databaseDirectory}
|
||||||
|
onClick={
|
||||||
|
async (e)=>{
|
||||||
|
const path = await window.api.selectDatabaseDirectory()
|
||||||
|
setConfig({...config, databaseDirectory: path})
|
||||||
|
e.currentTarget.value = path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
</Form>
|
</Form>
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ const router = createHashRouter([
|
|||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
index: true,
|
index: true,
|
||||||
loader: SettingLoader,
|
|
||||||
action: SettingAction,
|
|
||||||
element: <Setting/>
|
element: <Setting/>
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { DataType } from "@renderer/data";
|
import { DataType } from "@renderer/data";
|
||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
interface StateProps{
|
interface StateProps{
|
||||||
|
config: ConfigDataType,
|
||||||
|
setConfig: (config: ConfigDataType) => void,
|
||||||
data: DataType[],
|
data: DataType[],
|
||||||
setData: (data: DataType[]) => void,
|
setData: (data: DataType[]) => void,
|
||||||
search: string,
|
search: string,
|
||||||
@@ -13,6 +15,8 @@ interface StateProps{
|
|||||||
setEditCategoryId: (id: number) => void
|
setEditCategoryId: (id: number) => void
|
||||||
}
|
}
|
||||||
export const useStore = create<StateProps>((set) => ({
|
export const useStore = create<StateProps>((set) => ({
|
||||||
|
config: {shortCut: "", databaseDirectory: ""},
|
||||||
|
setConfig: (config) => set({config}),
|
||||||
data: [],
|
data: [],
|
||||||
setData: (data) => set({data}),
|
setData: (data) => set({data}),
|
||||||
search: "",
|
search: "",
|
||||||
|
|||||||
2
ui/autoMate/types.d.ts
vendored
2
ui/autoMate/types.d.ts
vendored
@@ -15,7 +15,7 @@ type ContentType = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type WindowNameType = 'search' | 'config'
|
type WindowNameType = 'search' | 'config' | 'code'
|
||||||
|
|
||||||
type ConfigType = {
|
type ConfigType = {
|
||||||
id: number
|
id: number
|
||||||
|
|||||||
Reference in New Issue
Block a user