Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 新增数字组合键快速粘贴前九项 #528

Merged
merged 1 commit into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions src-tauri/src/core/setup/mac.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use tauri::{App, Window};
use cocoa::appkit::{NSMainMenuWindowLevel, NSWindow};
use cocoa::base::id;
use tauri::{ActivationPolicy, App, Window};

pub fn platform(app: &mut App, main_window: Window, _preference_window: Window) {
// 隐藏 mac 的程序坞图标:https://github.com/tauri-apps/tauri/issues/4852#issuecomment-1312716378
app.set_activation_policy(tauri::ActivationPolicy::Accessory);
app.set_activation_policy(ActivationPolicy::Accessory);

unsafe {
use cocoa::appkit::{NSMainMenuWindowLevel, NSWindow};
use cocoa::base::id;

let ns_window = main_window.ns_window().unwrap() as id;

// 让窗口在程序坞和菜单栏之上
Expand Down
4 changes: 3 additions & 1 deletion src/components/ProShortcut/keys.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { defaults } from "lodash-es";

export type ModifierKey = "Shift" | "Control" | "Alt" | "Command";

export interface Key {
key: string;
key: ModifierKey | (string & {});
symbol?: string;
shortcut?: string;
macosSymbol?: string;
Expand Down
6 changes: 5 additions & 1 deletion src/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,11 @@
"title": "Shortcuts",
"label": {
"open_clipboard": "Open Clipboard Window",
"open_settings": "Open Preferences Window"
"open_settings": "Open Preferences Window",
"quick_paste": "Quick Paste"
},
"hints": {
"quick_paste": "Use number key combos to quickly paste top 9 items when window is hidden"
}
}
},
Expand Down
6 changes: 5 additions & 1 deletion src/locales/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,11 @@
"title": "ショートカットキー",
"label": {
"open_clipboard": "クリップボードを開く",
"open_settings": "クリップボード設定を開く"
"open_settings": "クリップボード設定を開く",
"quick_paste": "クイックペースト"
},
"hints": {
"quick_paste": "ウィンドウを隠す際、数字キーの組み合わせで最初の9項目を素早く貼り付ける"
}
}
},
Expand Down
6 changes: 5 additions & 1 deletion src/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,11 @@
"title": "快捷键",
"label": {
"open_clipboard": "打开剪贴板窗口",
"open_settings": "打开偏好设置窗口"
"open_settings": "打开偏好设置窗口",
"quick_paste": "快速粘贴"
},
"hints": {
"quick_paste": "在隐藏窗口时,使用数字组合键快速粘贴前九项"
}
}
},
Expand Down
6 changes: 5 additions & 1 deletion src/locales/zh-TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,11 @@
"title": "快捷鍵",
"label": {
"open_clipboard": "打開剪貼簿視窗",
"open_settings": "打開偏好設定視窗"
"open_settings": "打開偏好設定視窗",
"quick_paste": "快速粘貼"
},
"hints": {
"quick_paste": "在隱藏視窗時,使用數位複合鍵快速粘貼前九項"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 +43,11 @@ const Item: FC<ItemProps> = (props) => {
});

const copy = () => {
switch (type) {
case "text":
return writeText(value);
case "rtf":
return writeRTF(search, value);
case "html":
return writeHTML(search, value);
case "image":
return writeImage(value);
case "files":
return writeFiles(JSON.parse(value));
}
return writeClipboard(data);
};

const pastePlainText = async () => {
await writeText(search);

paste();
const pastePlainText = () => {
pasteClipboard(data, true);
};

const toggleFavorite = async () => {
Expand Down Expand Up @@ -121,9 +108,7 @@ const Item: FC<ItemProps> = (props) => {
const pasteValue = async () => {
if (state.activeId !== id) return;

await copy();

paste();
pasteClipboard(data);
};

const handleContextMenu = async (event: MouseEvent) => {
Expand Down
6 changes: 4 additions & 2 deletions src/pages/Clipboard/Panel/components/List/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ const List = () => {

const isFocusWithin = useFocusWithin(document.body);

useEffect(() => {
useAsyncEffect(async () => {
rowVirtualizer.scrollToIndex(0);

getClipboardList?.();
await getClipboardList?.();

state.activeId = state.data.list[0].id;
}, [state.search, state.group, state.favorite]);

useOSKeyPress(
Expand Down
39 changes: 34 additions & 5 deletions src/pages/Clipboard/Panel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import type { AudioRef } from "@/components/Audio";
import Audio from "@/components/Audio";
import type { ClipboardItem, TablePayload } from "@/types/database";
import { listen } from "@tauri-apps/api/event";
import { registerAll, unregister } from "@tauri-apps/api/globalShortcut";
import type { EventEmitter } from "ahooks/lib/useEventEmitter";
import { isEqual, merge } from "lodash-es";
import { isEqual, last, merge, range } from "lodash-es";
import { createContext } from "react";
import { useSnapshot } from "valtio";
import { subscribeKey } from "valtio/utils";
import Dock from "./components/Dock";
import Float from "./components/Float";

Expand All @@ -20,6 +22,7 @@ interface State extends TablePayload {
loading: boolean;
};
$eventBus?: EventEmitter<string>;
quickPasteShortcuts: string[];
}

const INITIAL_STATE: State = {
Expand All @@ -31,6 +34,7 @@ const INITIAL_STATE: State = {
size: 20,
loading: false,
},
quickPasteShortcuts: [],
};

interface ClipboardPanelContextValue {
Expand Down Expand Up @@ -113,6 +117,12 @@ const ClipboardPanel = () => {

// 监听主窗口显示/隐藏
listen(LISTEN_KEY.TOGGLE_MAIN_WINDOW_VISIBLE, toggleWindowVisible);

// 监听快速粘贴的启用状态变更
watchKey(globalStore.shortcut.quickPaste, "enable", registerQuickPaste);

// 监听快速粘贴的快捷键变更
subscribeKey(globalStore.shortcut.quickPaste, "value", registerQuickPaste);
});

// 监听窗口焦点
Expand All @@ -131,17 +141,36 @@ const ClipboardPanel = () => {
const getClipboardList = async () => {
const { search, group, favorite } = state;

const list = await selectSQL<ClipboardItem[]>("history", {
state.data.list = await selectSQL<ClipboardItem[]>("history", {
search,
group,
favorite,
});
};

state.data.list = list;
// 注册数字组合键快速粘贴的快捷键
const registerQuickPaste = async () => {
const { enable, value } = globalStore.shortcut.quickPaste;

if (state.data.page === 1) {
state.activeId ||= list[0]?.id;
for await (const shortcut of state.quickPasteShortcuts) {
await unregister(shortcut);
}

if (!enable) return;

const shortcuts = range(1, 10).map((item) => `${value}+${item}`);

await registerAll(shortcuts, async (shortcut) => {
if (!globalStore.shortcut.quickPaste.enable) return;

const index = Number(last(shortcut));

const data = state.data.list[index - 1];

pasteClipboard(data);
});

state.quickPasteShortcuts = shortcuts;
};

return (
Expand Down
49 changes: 49 additions & 0 deletions src/pages/Shortcut/components/QuickPaste/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import EcoSelect from "@/components/EcoSelect";
import ProListItem from "@/components/ProListItem";
import { modifierKeys } from "@/components/ProShortcut/keys";
import { Space, Switch } from "antd";
import type { DefaultOptionType } from "antd/es/select";
import { useSnapshot } from "valtio";

const QuickPaste = () => {
const { shortcut } = useSnapshot(globalStore);
const { t } = useTranslation();

const options: DefaultOptionType[] = modifierKeys.map((item) => {
const { key, symbol, macosSymbol } = item;

return {
label: isMac() ? macosSymbol : symbol,
value: key,
};
});

return (
<ProListItem
title={t("preference.shortcut.shortcut.label.quick_paste")}
description={t("preference.shortcut.shortcut.hints.quick_paste")}
>
<Switch
value={shortcut.quickPaste.enable}
onChange={(value) => {
globalStore.shortcut.quickPaste.enable = value;
}}
/>

<Space>
<EcoSelect
options={options}
value={shortcut.quickPaste.value}
disabled={!shortcut.quickPaste.enable}
onChange={(value) => {
globalStore.shortcut.quickPaste.value = value;
}}
/>

<span>1~9</span>
</Space>
</ProListItem>
);
};

export default QuickPaste;
3 changes: 3 additions & 0 deletions src/pages/Shortcut/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ProList from "@/components/ProList";
import ProShortcut from "@/components/ProShortcut";
import { useSnapshot } from "valtio";
import QuickPaste from "./components/QuickPaste";

const Shortcut = () => {
const { shortcut } = useSnapshot(globalStore);
Expand All @@ -23,6 +24,8 @@ const Shortcut = () => {
globalStore.shortcut.preference = value;
}}
/>

<QuickPaste />
</ProList>
);
};
Expand Down
37 changes: 37 additions & 0 deletions src/plugins/clipboard.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { ClipboardItem } from "@/types/database";
import type { ClipboardPayload, ReadImage, WinOCR } from "@/types/plugin";
import { invoke } from "@tauri-apps/api";
import { listen } from "@tauri-apps/api/event";
Expand Down Expand Up @@ -289,3 +290,39 @@ export const onClipboardUpdate = (
oldPayload = payload;
});
};

/**
* 将数据写入剪切板
* @param data 数据
*/
export const writeClipboard = async (data: ClipboardItem) => {
const { type, value, search } = data;

switch (type) {
case "text":
return writeText(value);
case "rtf":
return writeRTF(search, value);
case "html":
return writeHTML(search, value);
case "image":
return writeImage(getSaveImagePath(value));
case "files":
return writeFiles(JSON.parse(value));
}
};

/**
* 粘贴剪切板数据
* @param data 数据
* @param plain 是否纯文本粘贴
*/
export const pasteClipboard = async (data: ClipboardItem, plain = false) => {
if (plain) {
await writeText(data.search);
} else {
await writeClipboard(data);
}

paste();
};
4 changes: 4 additions & 0 deletions src/stores/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export const GLOBAL_STORE_INITIAL_STATE: GlobalStore = {
shortcut: {
clipboard: "Alt+C",
preference: "Alt+X",
quickPaste: {
enable: false,
value: "Alt",
},
},

env: {},
Expand Down
6 changes: 6 additions & 0 deletions src/types/store.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { ModifierKey } from "@/components/ProShortcut/keys";

export type Theme = "auto" | "light" | "dark";

export type Language = (typeof LANGUAGE)[keyof typeof LANGUAGE];
Expand Down Expand Up @@ -30,6 +32,10 @@ export interface GlobalStore {
shortcut: {
clipboard: string;
preference?: string;
quickPaste: {
enable: boolean;
value: ModifierKey;
};
};

// 只在当前系统环境使用
Expand Down
6 changes: 4 additions & 2 deletions src/utils/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ export const getSaveImageDir = () => {
* 获取图片内容的存储路径
* @param file 文件名
*/
export const getSaveImagePath = (fileName: string) => {
return joinPath(getSaveImageDir(), fileName);
export const getSaveImagePath = (file: string) => {
if (file.startsWith(getSaveImageDir())) return file;

return joinPath(getSaveImageDir(), file);
};

/**
Expand Down