chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
export const WINDOW_WIDTH = 800;
|
||||
export const WINDOW_HEIGHT = 60;
|
||||
export const WINDOW_PLUGIN_HEIGHT = 600;
|
||||
|
||||
export const GUIDE_WIDTH = 800;
|
||||
export const GUIDE_HEIGHT = 600;
|
||||
|
||||
export const WINDOW_MIN_HEIGHT = 60;
|
||||
@@ -0,0 +1,36 @@
|
||||
export default {
|
||||
version: 7,
|
||||
perf: {
|
||||
custom: {
|
||||
theme: 'SPRING',
|
||||
primaryColor: '#ff4ea4',
|
||||
errorColor: '#ed6d46',
|
||||
warningColor: '#e5a84b',
|
||||
successColor: '#c0d695',
|
||||
infoColor: '#aa8eeB',
|
||||
logo: `file://${__static}/logo.png`,
|
||||
placeholder: '你好,Rubick!请输入插件关键词',
|
||||
username: 'Rubick',
|
||||
},
|
||||
shortCut: {
|
||||
showAndHidden: 'Option+R',
|
||||
separate: 'Ctrl+D',
|
||||
quit: 'Shift+Escape',
|
||||
capture: 'Ctrl+Shift+A',
|
||||
},
|
||||
common: {
|
||||
start: true,
|
||||
space: true,
|
||||
hideOnBlur: true,
|
||||
autoPast: false,
|
||||
darkMode: false,
|
||||
guide: false,
|
||||
history: true,
|
||||
lang: 'zh-CN',
|
||||
},
|
||||
local: {
|
||||
search: true,
|
||||
},
|
||||
},
|
||||
global: [],
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
import { app } from 'electron';
|
||||
import path from 'path';
|
||||
|
||||
const appPath = app.getPath('userData');
|
||||
|
||||
const PLUGIN_INSTALL_DIR = path.join(appPath, './rubick-plugins-new');
|
||||
|
||||
const DECODE_KEY = {
|
||||
Backspace: 'Backspace',
|
||||
Tab: 'Tab',
|
||||
Enter: 'Enter',
|
||||
MediaPlayPause: 'MediaPlayPause',
|
||||
Escape: 'Escape',
|
||||
Space: 'Space',
|
||||
PageUp: 'PageUp',
|
||||
PageDown: 'PageDown',
|
||||
End: 'End',
|
||||
Home: 'Home',
|
||||
ArrowLeft: 'Left',
|
||||
ArrowUp: 'Up',
|
||||
ArrowRight: 'Right',
|
||||
ArrowDown: 'Down',
|
||||
PrintScreen: 'PrintScreen',
|
||||
Insert: 'Insert',
|
||||
Delete: 'Delete',
|
||||
Digit0: '0',
|
||||
Digit1: '1',
|
||||
Digit2: '2',
|
||||
Digit3: '3',
|
||||
Digit4: '4',
|
||||
Digit5: '5',
|
||||
Digit6: '6',
|
||||
Digit7: '7',
|
||||
Digit8: '8',
|
||||
Digit9: '9',
|
||||
KeyA: 'A',
|
||||
KeyB: 'B',
|
||||
KeyC: 'C',
|
||||
KeyD: 'D',
|
||||
KeyE: 'E',
|
||||
KeyF: 'F',
|
||||
KeyG: 'G',
|
||||
KeyH: 'H',
|
||||
KeyI: 'I',
|
||||
KeyJ: 'J',
|
||||
KeyK: 'K',
|
||||
KeyL: 'L',
|
||||
KeyM: 'M',
|
||||
KeyN: 'N',
|
||||
KeyO: 'O',
|
||||
KeyP: 'P',
|
||||
KeyQ: 'Q',
|
||||
KeyR: 'R',
|
||||
KeyS: 'S',
|
||||
KeyT: 'T',
|
||||
KeyU: 'U',
|
||||
KeyV: 'V',
|
||||
KeyW: 'W',
|
||||
KeyX: 'X',
|
||||
KeyY: 'Y',
|
||||
KeyZ: 'Z',
|
||||
F1: 'F1',
|
||||
F2: 'F2',
|
||||
F3: 'F3',
|
||||
F4: 'F4',
|
||||
F5: 'F5',
|
||||
F6: 'F6',
|
||||
F7: 'F7',
|
||||
F8: 'F8',
|
||||
F9: 'F9',
|
||||
F10: 'F10',
|
||||
F11: 'F11',
|
||||
F12: 'F12',
|
||||
Semicolon: ';',
|
||||
Equal: '=',
|
||||
Comma: ',',
|
||||
Minus: '-',
|
||||
Period: '.',
|
||||
Slash: '/',
|
||||
Backquote: '`',
|
||||
BracketLeft: '[',
|
||||
Backslash: '\\',
|
||||
BracketRight: ']',
|
||||
Quote: "'",
|
||||
};
|
||||
|
||||
export { PLUGIN_INSTALL_DIR, DECODE_KEY };
|
||||
@@ -0,0 +1,9 @@
|
||||
import { app } from '@electron/remote';
|
||||
import path from 'path';
|
||||
|
||||
const appPath = app.getPath('userData');
|
||||
|
||||
const PLUGIN_INSTALL_DIR = path.join(appPath, './rubick-plugins-new');
|
||||
const PLUGIN_HISTORY = 'rubick-plugin-history';
|
||||
|
||||
export { PLUGIN_INSTALL_DIR, PLUGIN_HISTORY };
|
||||
@@ -0,0 +1,17 @@
|
||||
export default {
|
||||
linux(): boolean {
|
||||
return process.platform === 'linux';
|
||||
},
|
||||
macOS(): boolean {
|
||||
return process.platform === 'darwin';
|
||||
},
|
||||
windows(): boolean {
|
||||
return process.platform === 'win32';
|
||||
},
|
||||
production(): boolean {
|
||||
return process.env.NODE_ENV !== 'development';
|
||||
},
|
||||
dev(): boolean {
|
||||
return process.env.NODE_ENV === 'development';
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
import { ipcRenderer } from 'electron';
|
||||
|
||||
const useDrag = () => {
|
||||
let animationId: number;
|
||||
let mouseX: number;
|
||||
let mouseY: number;
|
||||
let clientWidth = 0;
|
||||
let clientHeight = 0;
|
||||
let draggable = true;
|
||||
|
||||
const onMouseDown = (e) => {
|
||||
// 右击不移动
|
||||
if (e.button === 2) return;
|
||||
draggable = true;
|
||||
mouseX = e.clientX;
|
||||
mouseY = e.clientY;
|
||||
if (Math.abs(document.body.clientWidth - clientWidth) > 5) {
|
||||
clientWidth = document.body.clientWidth;
|
||||
}
|
||||
if (Math.abs(document.body.clientHeight - clientHeight) > 5) {
|
||||
clientHeight = document.body.clientHeight;
|
||||
}
|
||||
document.addEventListener('mouseup', onMouseUp);
|
||||
animationId = requestAnimationFrame(moveWindow);
|
||||
};
|
||||
|
||||
const onMouseUp = () => {
|
||||
draggable = false;
|
||||
document.removeEventListener('mouseup', onMouseUp);
|
||||
cancelAnimationFrame(animationId);
|
||||
};
|
||||
|
||||
const moveWindow = () => {
|
||||
ipcRenderer.send('msg-trigger', {
|
||||
type: 'windowMoving',
|
||||
data: { mouseX, mouseY, width: clientWidth, height: clientHeight },
|
||||
});
|
||||
if (draggable) animationId = requestAnimationFrame(moveWindow);
|
||||
};
|
||||
|
||||
return {
|
||||
onMouseDown,
|
||||
};
|
||||
};
|
||||
|
||||
export default useDrag;
|
||||
@@ -0,0 +1,55 @@
|
||||
import commonConst from './commonConst';
|
||||
import { clipboard } from 'electron';
|
||||
import plist from 'plist';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import ofs from 'original-fs';
|
||||
|
||||
export default function getCopyFiles(): Array<any> | null {
|
||||
let fileInfo;
|
||||
if (commonConst.macOS()) {
|
||||
if (!clipboard.has('NSFilenamesPboardType')) return null;
|
||||
const result = clipboard.read('NSFilenamesPboardType');
|
||||
if (!result) return null;
|
||||
try {
|
||||
fileInfo = plist.parse(result);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
} else if (process.platform === 'win32') {
|
||||
try {
|
||||
/* eslint-disable */
|
||||
const clipboardEx = require('electron-clipboard-ex');
|
||||
fileInfo = clipboardEx.readFilePaths();
|
||||
} catch (e) {
|
||||
// todo
|
||||
}
|
||||
} else {
|
||||
if (!commonConst.linux()) return null;
|
||||
if (!clipboard.has('text/uri-list')) return null;
|
||||
const result = clipboard.read('text/uri-list').match(/^file:\/\/\/.*/gm);
|
||||
if (!result || !result.length) return null;
|
||||
fileInfo = result.map((e) =>
|
||||
decodeURIComponent(e).replace(/^file:\/\//, '')
|
||||
);
|
||||
}
|
||||
if (!Array.isArray(fileInfo)) return null;
|
||||
const target: any = fileInfo
|
||||
.map((p) => {
|
||||
if (!fs.existsSync(p)) return false;
|
||||
let info;
|
||||
try {
|
||||
info = ofs.lstatSync(p);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return {
|
||||
isFile: info.isFile(),
|
||||
isDirectory: info.isDirectory(),
|
||||
name: path.basename(p) || p,
|
||||
path: p,
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
return target.length ? target : null;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
export default (): string => {
|
||||
let localDataFile: any = process.env.HOME;
|
||||
if (!localDataFile) {
|
||||
localDataFile = process.env.LOCALAPPDATA;
|
||||
}
|
||||
const rubickPath = path.join(localDataFile, 'rubick');
|
||||
if (!fs.existsSync(rubickPath)) {
|
||||
fs.mkdirSync(rubickPath);
|
||||
}
|
||||
return rubickPath;
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
const WINDOW_MAX_HEIGHT = 620;
|
||||
const WINDOW_MIN_HEIGHT = 60;
|
||||
const PRE_ITEM_HEIGHT = 70;
|
||||
const HISTORY_HEIGHT = 70;
|
||||
|
||||
export default (searchList: Array<any>, historyList): number => {
|
||||
const defaultHeight = historyList.length ? HISTORY_HEIGHT : 0;
|
||||
if (!searchList) return WINDOW_MAX_HEIGHT + defaultHeight;
|
||||
if (!searchList.length) return WINDOW_MIN_HEIGHT + defaultHeight;
|
||||
return searchList.length * PRE_ITEM_HEIGHT + WINDOW_MIN_HEIGHT >
|
||||
WINDOW_MAX_HEIGHT
|
||||
? WINDOW_MAX_HEIGHT
|
||||
: searchList.length * PRE_ITEM_HEIGHT + WINDOW_MIN_HEIGHT;
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import getLocalDataFile from './getLocalDataFile';
|
||||
import defaultConfigForAnyPlatform from '../constans/defaultConfig';
|
||||
|
||||
const configPath = path.join(getLocalDataFile(), './rubick-config.json');
|
||||
|
||||
global.OP_CONFIG = {
|
||||
config: null,
|
||||
getDefaultConfig() {
|
||||
return defaultConfigForAnyPlatform;
|
||||
},
|
||||
get() {
|
||||
try {
|
||||
if (!global.OP_CONFIG.config) {
|
||||
global.OP_CONFIG.config = JSON.parse(
|
||||
fs.readFileSync(configPath, 'utf8') ||
|
||||
JSON.stringify(defaultConfigForAnyPlatform)
|
||||
);
|
||||
}
|
||||
// 重置
|
||||
if (
|
||||
!global.OP_CONFIG.config.version ||
|
||||
global.OP_CONFIG.config.version < defaultConfigForAnyPlatform.version
|
||||
) {
|
||||
global.OP_CONFIG.config = defaultConfigForAnyPlatform;
|
||||
fs.writeFileSync(
|
||||
configPath,
|
||||
JSON.stringify(defaultConfigForAnyPlatform)
|
||||
);
|
||||
}
|
||||
return global.OP_CONFIG.config;
|
||||
} catch (e) {
|
||||
global.OP_CONFIG.config = defaultConfigForAnyPlatform;
|
||||
return global.OP_CONFIG.config;
|
||||
}
|
||||
},
|
||||
set(value) {
|
||||
global.OP_CONFIG.config = {
|
||||
...global.OP_CONFIG.config,
|
||||
...value,
|
||||
};
|
||||
fs.writeFileSync(configPath, JSON.stringify(global.OP_CONFIG.config));
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,120 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { PluginHandler } from '@/core';
|
||||
import { PLUGIN_INSTALL_DIR as baseDir } from '@/common/constans/main';
|
||||
import API from '@/main/common/api';
|
||||
|
||||
const configPath = path.join(baseDir, './rubick-local-plugin.json');
|
||||
|
||||
let registry;
|
||||
let pluginInstance;
|
||||
(async () => {
|
||||
try {
|
||||
const res = await API.dbGet({
|
||||
data: {
|
||||
id: 'rubick-localhost-config',
|
||||
},
|
||||
});
|
||||
|
||||
registry = res && res.data.register;
|
||||
pluginInstance = new PluginHandler({
|
||||
baseDir,
|
||||
registry,
|
||||
});
|
||||
} catch (e) {
|
||||
pluginInstance = new PluginHandler({
|
||||
baseDir,
|
||||
registry,
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
global.LOCAL_PLUGINS = {
|
||||
PLUGINS: [],
|
||||
async downloadPlugin(plugin) {
|
||||
await pluginInstance.install([plugin.name], { isDev: plugin.isDev });
|
||||
if (plugin.isDev) {
|
||||
// 获取 dev 插件信息
|
||||
const pluginPath = path.resolve(baseDir, 'node_modules', plugin.name);
|
||||
const pluginInfo = JSON.parse(
|
||||
fs.readFileSync(path.join(pluginPath, './package.json'), 'utf8')
|
||||
);
|
||||
plugin = {
|
||||
...plugin,
|
||||
...pluginInfo,
|
||||
};
|
||||
}
|
||||
global.LOCAL_PLUGINS.addPlugin(plugin);
|
||||
return global.LOCAL_PLUGINS.PLUGINS;
|
||||
},
|
||||
refreshPlugin(plugin) {
|
||||
// 获取 dev 插件信息
|
||||
const pluginPath = path.resolve(baseDir, 'node_modules', plugin.name);
|
||||
const pluginInfo = JSON.parse(
|
||||
fs.readFileSync(path.join(pluginPath, './package.json'), 'utf8')
|
||||
);
|
||||
plugin = {
|
||||
...plugin,
|
||||
...pluginInfo,
|
||||
};
|
||||
// 刷新
|
||||
let currentPlugins = global.LOCAL_PLUGINS.getLocalPlugins();
|
||||
|
||||
currentPlugins = currentPlugins.map((p) => {
|
||||
if (p.name === plugin.name) {
|
||||
return plugin;
|
||||
}
|
||||
return p;
|
||||
});
|
||||
|
||||
// 存入
|
||||
global.LOCAL_PLUGINS.PLUGINS = currentPlugins;
|
||||
fs.writeFileSync(configPath, JSON.stringify(currentPlugins));
|
||||
return global.LOCAL_PLUGINS.PLUGINS;
|
||||
},
|
||||
getLocalPlugins() {
|
||||
try {
|
||||
if (!global.LOCAL_PLUGINS.PLUGINS.length) {
|
||||
global.LOCAL_PLUGINS.PLUGINS = JSON.parse(
|
||||
fs.readFileSync(configPath, 'utf-8')
|
||||
);
|
||||
}
|
||||
return global.LOCAL_PLUGINS.PLUGINS;
|
||||
} catch (e) {
|
||||
global.LOCAL_PLUGINS.PLUGINS = [];
|
||||
return global.LOCAL_PLUGINS.PLUGINS;
|
||||
}
|
||||
},
|
||||
addPlugin(plugin) {
|
||||
let has = false;
|
||||
const currentPlugins = global.LOCAL_PLUGINS.getLocalPlugins();
|
||||
currentPlugins.some((p) => {
|
||||
has = p.name === plugin.name;
|
||||
return has;
|
||||
});
|
||||
if (!has) {
|
||||
currentPlugins.unshift(plugin);
|
||||
global.LOCAL_PLUGINS.PLUGINS = currentPlugins;
|
||||
fs.writeFileSync(configPath, JSON.stringify(currentPlugins));
|
||||
}
|
||||
},
|
||||
updatePlugin(plugin) {
|
||||
global.LOCAL_PLUGINS.PLUGINS = global.LOCAL_PLUGINS.PLUGINS.map(
|
||||
(origin) => {
|
||||
if (origin.name === plugin.name) {
|
||||
return plugin;
|
||||
}
|
||||
return origin;
|
||||
}
|
||||
);
|
||||
fs.writeFileSync(configPath, JSON.stringify(global.LOCAL_PLUGINS.PLUGINS));
|
||||
},
|
||||
async deletePlugin(plugin) {
|
||||
await pluginInstance.uninstall([plugin.name], { isDev: plugin.isDev });
|
||||
global.LOCAL_PLUGINS.PLUGINS = global.LOCAL_PLUGINS.PLUGINS.filter(
|
||||
(p) => plugin.name !== p.name
|
||||
);
|
||||
fs.writeFileSync(configPath, JSON.stringify(global.LOCAL_PLUGINS.PLUGINS));
|
||||
return global.LOCAL_PLUGINS.PLUGINS;
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export default function throttle(func, wait, options?: any): () => void {
|
||||
let context, args, result;
|
||||
let timeout = null;
|
||||
let previous = 0;
|
||||
if (!options) options = {};
|
||||
const later = function () {
|
||||
previous = options.leading === false ? 0 : Date.now();
|
||||
timeout = null;
|
||||
result = func.apply(context, args);
|
||||
if (!timeout) context = args = null;
|
||||
};
|
||||
return () => {
|
||||
const now = Date.now();
|
||||
if (!previous && options.leading === false) previous = now;
|
||||
// 计算剩余时间
|
||||
const remaining = wait - (now - previous);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
context = this;
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
args = arguments;
|
||||
if (remaining <= 0 || remaining > wait) {
|
||||
if (timeout) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
}
|
||||
previous = now;
|
||||
result = func.apply(context, args);
|
||||
if (!timeout) context = args = null;
|
||||
} else if (!timeout && options.trailing !== false) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
timeout = setTimeout(later, remaining);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user