Skip to content

Commit

Permalink
feat: keyboard table
Browse files Browse the repository at this point in the history
  • Loading branch information
drl990114 committed Aug 5, 2023
1 parent 03f9da2 commit 13a9597
Show file tree
Hide file tree
Showing 14 changed files with 282 additions and 14 deletions.
1 change: 1 addition & 0 deletions apps/linebyline/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"react-router-dom": "^6.9.0",
"remixicon": "^3.4.0",
"styled-components": "^5.3.11",
"tinykeys": "^2.1.0",
"zustand": "^4.3.9"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions apps/linebyline/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import { Route, Routes } from 'react-router-dom'
import 'remixicon/fonts/remixicon.css'
import { ThemeProvider } from 'styled-components'
import { GlobalStyles } from './globalStyles'
import { useGlobalSettingData, useGlobalTheme } from './hooks'
import useGlobalOSInfo from './hooks/useOSInfo'
import { useGlobalSettingData, useGlobalTheme, useGlobalKeyboard, useGlobalOSInfo } from './hooks'
import { i18nInit } from './i18n'
import { Root, Setting } from '@/router'
import { loadTask, use } from '@/helper/schedule'
Expand All @@ -20,6 +19,7 @@ import { getFileObject, getFileObjectByPath } from './helper/files'

function App() {
useGlobalOSInfo()
useGlobalKeyboard()
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, handler] = useGlobalSettingData()
const { themeColors, muiTheme, setTheme } = useGlobalTheme()
Expand Down
1 change: 1 addition & 0 deletions apps/linebyline/src/helper/cacheManager/settingMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const settingMap = {
},
},
},
keyboard: {}
}

export enum SettingKeys {
Expand Down
2 changes: 2 additions & 0 deletions apps/linebyline/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export { default as useGlobalCacheData } from './useCacheData'
export { default as useGlobalSettingData } from './useSettingData'
export { default as useGlobalTheme } from './useTheme'
export { default as useGlobalKeyboard } from './useKeyboard'
export { default as useGlobalOSInfo } from './useOSInfo'
68 changes: 68 additions & 0 deletions apps/linebyline/src/hooks/useKeyboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { invoke } from '@tauri-apps/api'
import { createGlobalStore } from 'hox'
import { useEffect, useState } from 'react'
import type { KeyBindingMap } from 'tinykeys'
import { createKeybindingsHandler } from 'tinykeys'
import { useCommandStore } from '@/stores'

const getTinyKeyBinding = (keyMap: string[]) => {
let keyBinding = ''
keyMap.forEach((key, index) => {
if (key === 'mod') {
keyBinding += '$mod'
} else {
keyBinding += key
}

if (index < keyMap.length - 1) {
keyBinding += '+'
}
})
return keyBinding
}

function useKeyboard() {
const [keyboardInfos, setKeyboardInfos] = useState<KeyboardInfo[]>([])
const { execute } = useCommandStore()

useEffect(() => {
invoke<{ cmds: KeyboardInfo[] }>('get_keyboard_infos').then((res) => {
setKeyboardInfos(res.cmds)
})
}, [])

useEffect(() => {
const keybindingMap: KeyBindingMap = {}

keyboardInfos.forEach((keyboardInfo) => {
if (keyboardInfo.key_map.length > 0) {
const keybind = getTinyKeyBinding(keyboardInfo.key_map)
keybindingMap[keybind] = () => {
execute(keyboardInfo.id)
}
}
})
console.log('keybindingMap', keybindingMap)
const handler = createKeybindingsHandler(keybindingMap)

window.addEventListener('keydown', handler)

return () => {
window.removeEventListener('keydown', handler)
}
}, [execute, keyboardInfos])

return {
keyboardInfos,
}
}

const [useGlobalKeyboard] = createGlobalStore(useKeyboard)

export default useGlobalKeyboard

interface KeyboardInfo {
id: string
desc: string
key_map: string[]
}
41 changes: 41 additions & 0 deletions apps/linebyline/src/router/Setting/KeyboardTable/KeyboardTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import Table from '@mui/material/Table'
import TableBody from '@mui/material/TableBody'
import TableCell from '@mui/material/TableCell'
import TableContainer from '@mui/material/TableContainer'
import TableHead from '@mui/material/TableHead'
import TableRow from '@mui/material/TableRow'
import Paper from '@mui/material/Paper'
import { useGlobalKeyboard, useGlobalTheme } from '@/hooks'

export function KeyboardTable() {
const { themeColors } = useGlobalTheme()
const { keyboardInfos } = useGlobalKeyboard()

return (
<TableContainer component={Paper}>
<Table size='small' aria-label='caption table'>
<TableHead
sx={{
backgroundColor: themeColors.tipsBgColor,
}}
>
<TableRow>
<TableCell>Command</TableCell>
<TableCell>Descibe</TableCell>
<TableCell>Keybinding</TableCell>
</TableRow>
</TableHead>
<TableBody>
{keyboardInfos.map((row) => (
<TableRow key={row.id}>
<TableCell>{row.id}</TableCell>
<TableCell>{row.desc}</TableCell>
<TableCell>{row.key_map.join('+')}</TableCell>
</TableRow>
))}
</TableBody>
<caption>Currently, custom shortcut keys are not supported.</caption>
</Table>
</TableContainer>
)
}
1 change: 1 addition & 0 deletions apps/linebyline/src/router/Setting/KeyboardTable/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './KeyboardTable'
29 changes: 19 additions & 10 deletions apps/linebyline/src/router/Setting/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import settingMap from '@/helper/cacheManager/settingMap'
import Logo from '@/assets/logo.svg'
import { invoke } from '@tauri-apps/api'
import TitleBar from '@/components/TitleBar'
import { KeyboardTable } from './KeyboardTable'

export interface DialogTitleProps {
children?: ReactNode
Expand Down Expand Up @@ -34,6 +35,23 @@ function Setting() {
})
}, [])

const renderCurrentSettingData = () => {
if (curGroupKey === 'keyboard') {
return <KeyboardTable />
}

return curGroupKeys.map((key) => {
return (
<SettingGroup
key={key}
group={curGroup[key]}
groupKey={key}
categoryKey={curGroupKey}
/>
)
})
}

return (
<>
<TitleBar transparent />
Expand Down Expand Up @@ -71,16 +89,7 @@ function Setting() {
<div className="conf-path">
<small>Path: {confPath}</small>
</div>
{curGroupKeys.map((key) => {
return (
<SettingGroup
key={key}
group={curGroup[key]}
groupKey={key}
categoryKey={curGroupKey}
/>
)
})}
{renderCurrentSettingData()}
</div>
</Container>
</>
Expand Down
1 change: 1 addition & 0 deletions apps/linebyline/src/stores/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default as useEditorStore } from './useEditorStore'
export { default as useCommandStore } from './useCommandStore'
43 changes: 43 additions & 0 deletions apps/linebyline/src/stores/useCommandStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { create } from 'zustand'

const useCommandStore = create<CommandStore>((set, get) => {
return {
commands: {},
addCommand: ({ id, handler }) => {
set((state) => {
return {
...state,
commands: {
...state.commands,
[id]: {
exec: handler,
},
},
}
})
},
execute: (id: string) => {
const { commands } = get()
const command = commands[id]
if (command) {
command.exec()
} else {
console.error(`command ${id} not found`)
}
},
}
})

interface CommandStore {
commands: Commands
addCommand: (command: { id: string; handler: () => any }) => void
execute: (id: string) => void
}

export default useCommandStore

type Commands = Record<string, Command>

interface Command {
exec: () => void
}
94 changes: 94 additions & 0 deletions src-tauri/src/app/keyboard.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
use super::conf;
use crate::fc::{create_file, exists};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;

#[derive(Serialize, Deserialize)]
struct KeyboardInfo {
id: String,
desc: String,
key_map: Vec<String>,
}

impl KeyboardInfo {
pub fn new(id: String, desc: String, key_map: Vec<String>) -> Self {
Self { id, desc, key_map }
}
}

#[derive(Serialize, Deserialize)]
pub struct KeyboardInfos {
cmds: Vec<KeyboardInfo>,
}

impl KeyboardInfos {
pub fn new() -> Self {
let key_map: Vec<String> = Vec::new();
Self {
cmds: vec![
KeyboardInfo::new(
"app:dialog_about".to_string(),
"获取应用信息".to_string(),
Vec::new(),
),
KeyboardInfo::new(
"app:window_setting".to_string(),
"打开设置窗口".to_string(),
Vec::new(),
),
KeyboardInfo::new(
"app:open_folder".to_string(),
"打开文件夹".to_string(),
vec!["mod".to_string(), "Shift".to_string(), "o".to_string()],
)
],
}
}

pub fn get_path() -> PathBuf {
conf::app_root().join("keybord_map.json")
}

pub fn read() -> Self {
match std::fs::read_to_string(Self::get_path()) {
Ok(v) => {
if let Ok(v2) = serde_json::from_str::<KeyboardInfos>(&v) {
v2
} else {
Self::default()
}
}
Err(err) => Self::default(),
}
}

pub fn write(self) -> Self {
let path = &Self::get_path();
if !exists(path) {
create_file(path).unwrap();
}
if let Ok(v) = serde_json::to_string_pretty(&self) {
std::fs::write(path, v).unwrap_or_else(|err| {
Self::default().write();
});
} else {
}
self
}
}

impl Default for KeyboardInfos {
fn default() -> Self {
Self::new()
}
}

pub mod cmd {
use super::KeyboardInfos;
use tauri::{command, AppHandle};

#[command]
pub fn get_keyboard_infos() -> KeyboardInfos {
KeyboardInfos::read()
}
}
1 change: 1 addition & 0 deletions src-tauri/src/app/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod conf;
pub mod keyboard;
5 changes: 3 additions & 2 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod fc;
mod menu;
mod setup;

use app::conf;
use app::{conf, keyboard};

fn main() {
let context = tauri::generate_context!();
Expand All @@ -21,7 +21,8 @@ fn main() {
conf::cmd::get_app_conf,
conf::cmd::reset_app_conf,
conf::cmd::save_app_conf,
conf::cmd::open_conf_window
conf::cmd::open_conf_window,
keyboard::cmd::get_keyboard_infos,
])
.setup(setup::init)
.menu(menu::generate_menu())
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10153,6 +10153,11 @@ tinycolor2@^1.4.1:
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.6.0.tgz#f98007460169b0263b97072c5ae92484ce02d09e"
integrity sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==

tinykeys@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tinykeys/-/tinykeys-2.1.0.tgz#1341563e92a7fac9ca90053fddaf2b7553500298"
integrity sha512-/MESnqBD1xItZJn5oGQ4OsNORQgJfPP96XSGoyu4eLpwpL0ifO0SYR5OD76u0YMhMXsqkb0UqvI9+yXTh4xv8Q==

tinypool@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-0.6.0.tgz#c3640b851940abe2168497bb6e43b49fafb3ba7b"
Expand Down

0 comments on commit 13a9597

Please sign in to comment.