mirror of
https://github.com/yuruotong1/autoMate.git
synced 2025-12-26 05:16:21 +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:
parent
13d6e00a88
commit
ec1bdbd39d
@ -7,6 +7,7 @@ import url from 'node:url'
|
||||
export interface OptionsType extends Partial<BrowserWindowConstructorOptions>{
|
||||
openDevTools?: boolean,
|
||||
hash?: string
|
||||
initShow?: boolean
|
||||
}
|
||||
export function createWindow(options: OptionsType): BrowserWindow { // Create the browser window.
|
||||
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()
|
||||
win.on('ready-to-show', () => {
|
||||
win.show()
|
||||
options.initShow && win.show()
|
||||
})
|
||||
|
||||
win.webContents.setWindowOpenHandler((details) => {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import Database, * as BetterSqlite3 from 'better-sqlite3';
|
||||
import { app } from 'electron';
|
||||
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, {});
|
||||
db.pragma('journal_mode = WAL');
|
||||
export {db};
|
||||
@ -1,5 +1,14 @@
|
||||
import { IpcMainInvokeEvent, ipcMain } from "electron";
|
||||
import { IpcMainInvokeEvent, dialog, ipcMain } from "electron";
|
||||
import * as query from './query'
|
||||
ipcMain.handle('sql', (_event: IpcMainInvokeEvent, sql: string, type: SqlActionType, 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 "./ipc"
|
||||
import "./shortCut"
|
||||
import { registerAppGlobShortCut } from "./shortCut"
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(() => {
|
||||
|
||||
registerAppGlobShortCut()
|
||||
// Set app user model id for windows
|
||||
electronApp.setAppUserModelId('com.electron')
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { IpcMainInvokeEvent } from "electron"
|
||||
import { IpcMainInvokeEvent, dialog } from "electron"
|
||||
import { ipcMain } from "electron"
|
||||
import { getWindowByName } from "./windows"
|
||||
import { config } from "./db/query"
|
||||
const { app, globalShortcut } = require('electron')
|
||||
|
||||
ipcMain.handle("shortCut", (_event: IpcMainInvokeEvent, shortCut: string) => {
|
||||
@ -11,11 +12,15 @@ ipcMain.handle("shortCut", (_event: IpcMainInvokeEvent, shortCut: string) => {
|
||||
|
||||
|
||||
function registerSearchShortCut(shortCut: string){
|
||||
globalShortcut.unregisterAll()
|
||||
|
||||
// const ret = findOne(`select * from config where id=1`) as {content: string}
|
||||
// const shortCut = JSON.parse(ret.content).shortCut as string
|
||||
if (globalShortcut.isRegistered(shortCut)){
|
||||
if (shortCut && globalShortcut.isRegistered(shortCut)){
|
||||
dialog.showErrorBox('提示', '快捷键注册失败,请更换')
|
||||
return false
|
||||
}
|
||||
|
||||
const win = getWindowByName('search')
|
||||
const res = globalShortcut.register(shortCut, () => {
|
||||
win.isVisible() ? win.hide() : win.show()
|
||||
@ -25,4 +30,9 @@ function registerSearchShortCut(shortCut: string){
|
||||
app.on('will-quit', () => {
|
||||
// Unregister all shortcuts.
|
||||
globalShortcut.unregisterAll()
|
||||
})
|
||||
})
|
||||
|
||||
export const registerAppGlobShortCut =()=>{
|
||||
const configData = config() as {shortCut: string}
|
||||
registerSearchShortCut(configData.shortCut)
|
||||
}
|
||||
@ -5,15 +5,29 @@ export const config = {
|
||||
search: {
|
||||
id: 0,
|
||||
options: {
|
||||
initShow: true,
|
||||
hash: '',
|
||||
openDevTools: true,
|
||||
}
|
||||
},
|
||||
code: {
|
||||
id: 0,
|
||||
options: {
|
||||
initShow: false,
|
||||
width: 1300,
|
||||
height: 700,
|
||||
openDevTools: true,
|
||||
frame: true,
|
||||
transparent: false,
|
||||
hash: '/#config/category/contentList'
|
||||
}
|
||||
},
|
||||
config: {
|
||||
id: 0,
|
||||
options: {
|
||||
width: 1300,
|
||||
height: 600,
|
||||
initShow: false,
|
||||
width: 600,
|
||||
height: 400,
|
||||
openDevTools: true,
|
||||
frame: true,
|
||||
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>
|
||||
openWindow: (name: WindowNameType) => void,
|
||||
closeWindow: (name: WindowNameType) => void,
|
||||
selectDatabaseDirectory: () => Promise<string>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,9 @@ const api = {
|
||||
closeWindow: (name: WindowNameType) =>{
|
||||
ipcRenderer.send("closeWindow", name)
|
||||
},
|
||||
selectDatabaseDirectory: () => {
|
||||
return ipcRenderer.invoke("selectDatabaseDirectory")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ export default function Search(): JSX.Element {
|
||||
fill="#34495e"
|
||||
strokeWidth={4}
|
||||
className="cursor-pointer"
|
||||
onClick={()=>window.api.openWindow('config')
|
||||
onClick={()=>window.api.openWindow('code')
|
||||
}
|
||||
/>
|
||||
<Input
|
||||
@ -31,7 +31,10 @@ export default function Search(): JSX.Element {
|
||||
autoFocus
|
||||
/>
|
||||
</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>
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,15 +1,16 @@
|
||||
import { useStore } from "@renderer/store/useStore"
|
||||
// import { useStore } from "@renderer/store/useStore"
|
||||
|
||||
export default() => {
|
||||
const setError = useStore(state => state.setError)
|
||||
const register = async ()=>{
|
||||
const ret = (await window.api.sql('', 'config')) as Record<string, string>
|
||||
const isBind = await window.api.shortCut(ret.shortCut)
|
||||
isBind || setError("注册失败")
|
||||
// const setError = useStore(state => state.setError)
|
||||
// const register = async ()=>{
|
||||
// const ret = (await window.api.sql('', 'config')) as Record<string, string>
|
||||
// const isBind = await window.api.shortCut(ret.shortCut)
|
||||
// isBind || setError("注册失败")
|
||||
|
||||
}
|
||||
return {
|
||||
register
|
||||
}
|
||||
// }
|
||||
// return {
|
||||
// register
|
||||
// }
|
||||
return {}
|
||||
}
|
||||
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
import Result from "@renderer/components/Result"
|
||||
import Search from "@renderer/components/Search"
|
||||
import { CodeProvider } from "@renderer/context/CodeContext"
|
||||
import useShortCut from "@renderer/hooks/useShortCut"
|
||||
import Error from "@renderer/components/Error"
|
||||
import { MutableRefObject, useEffect, useRef } from "react"
|
||||
import useIgnoreMouseEvents from "@renderer/hooks/useIgnoreMouseEvents"
|
||||
import { useStore } from "@renderer/store/useStore"
|
||||
|
||||
|
||||
function Home(): JSX.Element {
|
||||
const mainRef = useRef<HTMLDivElement>(null)
|
||||
const {setIgnoreMouseEvents} = useIgnoreMouseEvents()
|
||||
const config = useStore(state => state.config)
|
||||
window.api.shortCut(config.shortCut)
|
||||
useEffect(()=>{
|
||||
setIgnoreMouseEvents(mainRef as MutableRefObject<HTMLDivElement>)
|
||||
// //为开发方便,临时代码
|
||||
// window.api.openConfigWindow()
|
||||
}, [])
|
||||
// // 注册快捷键
|
||||
const {register} = useShortCut()
|
||||
register()
|
||||
|
||||
return (
|
||||
<CodeProvider>
|
||||
<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 { useState } from 'react'
|
||||
import { useStore } from '@renderer/store/useStore'
|
||||
|
||||
export const Setting = () => {
|
||||
const config = useLoaderData() as ConfigDataType
|
||||
const submit = useSubmit()
|
||||
// const config = useLoaderData() as ConfigDataType
|
||||
const [keys, setKeys] = useState<string[]>([])
|
||||
const config = useStore(state => state.config)
|
||||
const setConfig = useStore(state => state.setConfig)
|
||||
return (
|
||||
<Form method="POST">
|
||||
<main className={styles.settingPage}>
|
||||
@ -19,23 +21,38 @@ export const Setting = () => {
|
||||
readOnly
|
||||
onKeyDown={(e) => {
|
||||
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)
|
||||
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>
|
||||
<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>
|
||||
</main>
|
||||
</Form>
|
||||
|
||||
@ -26,8 +26,6 @@ const router = createHashRouter([
|
||||
children: [
|
||||
{
|
||||
index: true,
|
||||
loader: SettingLoader,
|
||||
action: SettingAction,
|
||||
element: <Setting/>
|
||||
},
|
||||
{
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import { DataType } from "@renderer/data";
|
||||
import { create } from "zustand";
|
||||
interface StateProps{
|
||||
config: ConfigDataType,
|
||||
setConfig: (config: ConfigDataType) => void,
|
||||
data: DataType[],
|
||||
setData: (data: DataType[]) => void,
|
||||
search: string,
|
||||
@ -13,6 +15,8 @@ interface StateProps{
|
||||
setEditCategoryId: (id: number) => void
|
||||
}
|
||||
export const useStore = create<StateProps>((set) => ({
|
||||
config: {shortCut: "", databaseDirectory: ""},
|
||||
setConfig: (config) => set({config}),
|
||||
data: [],
|
||||
setData: (data) => set({data}),
|
||||
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 = {
|
||||
id: number
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user