mirror of
https://github.com/rubickCenter/rubick
synced 2025-06-18 01:26:57 +08:00
✨ 支持 template 模板 list 模式
This commit is contained in:
parent
afca4f2b5a
commit
8bcc5d409c
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "rubick",
|
||||
"version": "2.0.1-beta.1",
|
||||
"version": "2.0.1-beta.2",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
|
1
public/tpl/css/app.f5fd5a5f.css
Normal file
1
public/tpl/css/app.f5fd5a5f.css
Normal file
@ -0,0 +1 @@
|
||||
*{margin:0;padding:0}.options{position:absolute;left:0;width:100%;z-index:99;max-height:100vh;overflow:auto}.options::-webkit-scrollbar{width:0}.op-item{padding:0 10px;height:60px;max-height:500px;overflow:auto;background:#fafafa;display:flex;align-items:center;font-size:14px;text-align:left}.icon{width:30px;height:30px;border-radius:100%;margin-right:10px}.desc,.title{width:500px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.desc{color:#999}.op-item.active{background:#dee2e8}
|
BIN
public/tpl/favicon.ico
Normal file
BIN
public/tpl/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
1
public/tpl/index.html
Normal file
1
public/tpl/index.html
Normal file
@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>tpl</title><link href="css/app.f5fd5a5f.css" rel="preload" as="style"><link href="js/app.845a0078.js" rel="preload" as="script"><link href="js/chunk-vendors.d5af439e.js" rel="preload" as="script"><link href="css/app.f5fd5a5f.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but tpl doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.d5af439e.js"></script><script src="js/app.845a0078.js"></script></body></html>
|
2
public/tpl/js/app.845a0078.js
Normal file
2
public/tpl/js/app.845a0078.js
Normal file
@ -0,0 +1,2 @@
|
||||
(function(e){function t(t){for(var r,u,a=t[0],i=t[1],l=t[2],d=0,p=[];d<a.length;d++)u=a[d],Object.prototype.hasOwnProperty.call(c,u)&&c[u]&&p.push(c[u][0]),c[u]=0;for(r in i)Object.prototype.hasOwnProperty.call(i,r)&&(e[r]=i[r]);s&&s(t);while(p.length)p.shift()();return o.push.apply(o,l||[]),n()}function n(){for(var e,t=0;t<o.length;t++){for(var n=o[t],r=!0,a=1;a<n.length;a++){var i=n[a];0!==c[i]&&(r=!1)}r&&(o.splice(t--,1),e=u(u.s=n[0]))}return e}var r={},c={app:0},o=[];function u(t){if(r[t])return r[t].exports;var n=r[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,u),n.l=!0,n.exports}u.m=e,u.c=r,u.d=function(e,t,n){u.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},u.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},u.t=function(e,t){if(1&t&&(e=u(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(u.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)u.d(n,r,function(t){return e[t]}.bind(null,r));return n},u.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return u.d(t,"a",t),t},u.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},u.p="";var a=window["webpackJsonp"]=window["webpackJsonp"]||[],i=a.push.bind(a);a.push=t,a=a.slice();for(var l=0;l<a.length;l++)t(a[l]);var s=i;o.push([0,"chunk-vendors"]),n()})({0:function(e,t,n){e.exports=n("cd49")},2874:function(e,t,n){},"2f93":function(e,t,n){"use strict";n("4016")},4016:function(e,t,n){},5490:function(e,t,n){"use strict";n("2874")},cd49:function(e,t,n){"use strict";n.r(t);n("e260"),n("e6cf"),n("cca6"),n("a79d");var r=n("7a23"),c=n("6c02"),o={setup:function(e){var t=Object(c["d"])();return window.rubick.onPluginEnter((function(e){var n=e.code,r=window.exports[n];t.push({name:r.mode,params:{code:n}})})),function(e,t){var n=Object(r["v"])("router-view");return Object(r["q"])(),Object(r["d"])(n)}}};n("5490");const u=o;var a=u,i=(n("ac1f"),n("841c"),n("a4d3"),n("e01a"),{class:"list-container"}),l={class:"options"},s=["onClick"],d=["src"],p={class:"content"},f={class:"title"},v={class:"desc"},b=Object(r["g"])({setup:function(e){var t=window.require("electron"),n=t.ipcRenderer,o=Object(c["c"])(),u=60,a=10,b=60,O=o.params.code,j=window.exports[O];window.rubick.setExpendHeight(b);var w=Object(r["t"])([]);j.args.enter&&j.args.enter({code:O,type:"",payload:[]},(function(e){e.value=e}));var h=Object(r["t"])(0);n.on("changeCurrent",(function(e,t){h.value+t>w.value.length-1||w.value+t<0||(h.value=h.value+t)})),window.rubick.setSubInput((function(e){var t=e.text;j.args.search&&j.args.search({code:O,type:"",payload:[]},t,(function(e){w.value=e||[];var t=w.value.length>a?a*u:u*w.value.length;window.rubick.setExpendHeight(b+t)}))}),"搜索");var g=function(e){j.args.select&&j.args.select({code:O,type:"",payload:[]},e)},y=function(e){if("Enter"===e.code)return g(w.value[h.value]);var t=0;"ArrowDown"===e.code&&(t=1),"ArrowUp"===e.code&&(t=-1),w.value.length&&(h.value+t>w.value.length-1||h.value+t<0||(h.value=h.value+t))};return window.addEventListener("keydown",y),Object(r["n"])((function(){window.removeEventListener("keydown",y)})),function(e,t){return Object(r["q"])(),Object(r["e"])("div",i,[Object(r["B"])(Object(r["f"])("div",l,[(Object(r["q"])(!0),Object(r["e"])(r["a"],null,Object(r["u"])(w.value,(function(e,t){return Object(r["q"])(),Object(r["e"])("div",{key:t,class:Object(r["l"])(h.value===t?"active op-item":"op-item"),onClick:function(t){return g(e)}},[Object(r["f"])("img",{class:"icon",src:e.icon},null,8,d),Object(r["f"])("div",p,[Object(r["f"])("div",f,Object(r["x"])(e.title),1),Object(r["f"])("div",v,Object(r["x"])(decodeURIComponent(e.description)),1)])],10,s)})),128))],512),[[r["z"],!!(w.value||[]).length]])])}}});n("2f93");const O=b;var j=O,w={class:"home"};function h(e,t){return Object(r["q"])(),Object(r["e"])("div",w)}var g=n("6b0d"),y=n.n(g);const m={},x=y()(m,[["render",h]]);var k=x,P=[{path:"/list",name:"list",component:j},{path:"/doc",name:"doc",component:k}],q=Object(c["a"])({history:Object(c["b"])(),routes:P}),E=q,S=n("5502"),_=Object(S["a"])({state:{},mutations:{},actions:{},modules:{}});Object(r["c"])(a).use(_).use(E).mount("#app")}});
|
||||
//# sourceMappingURL=app.845a0078.js.map
|
1
public/tpl/js/app.845a0078.js.map
Normal file
1
public/tpl/js/app.845a0078.js.map
Normal file
File diff suppressed because one or more lines are too long
8
public/tpl/js/chunk-vendors.d5af439e.js
Normal file
8
public/tpl/js/chunk-vendors.d5af439e.js
Normal file
File diff suppressed because one or more lines are too long
1
public/tpl/js/chunk-vendors.d5af439e.js.map
Normal file
1
public/tpl/js/chunk-vendors.d5af439e.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -5,4 +5,83 @@ const appPath = app.getPath("cache");
|
||||
|
||||
const PLUGIN_INSTALL_DIR = path.join(appPath, "./rubick-plugins");
|
||||
|
||||
export { PLUGIN_INSTALL_DIR };
|
||||
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 };
|
||||
|
@ -3,6 +3,21 @@ import path from "path";
|
||||
import commonConst from "../../common/utils/commonConst";
|
||||
import { PLUGIN_INSTALL_DIR as baseDir } from "@/common/constans/main";
|
||||
|
||||
const getPreloadPath = (plugin, pluginIndexPath) => {
|
||||
const { name, preload, tplPath, indexPath } = plugin;
|
||||
if (commonConst.dev()) {
|
||||
if (name === "rubick-system-feature") {
|
||||
return path.resolve(__static, `../feature/public/preload.js`);
|
||||
}
|
||||
if (tplPath) {
|
||||
return path.resolve(indexPath.replace("file:", ""), `./`, preload);
|
||||
}
|
||||
return path.resolve(pluginIndexPath.replace("file:", ""), `../`, preload);
|
||||
}
|
||||
|
||||
return path.resolve(pluginIndexPath.replace("file:", ""), `../`, preload);
|
||||
};
|
||||
|
||||
export default () => {
|
||||
let view;
|
||||
|
||||
@ -13,19 +28,12 @@ export default () => {
|
||||
};
|
||||
|
||||
const createView = (plugin, window: BrowserWindow) => {
|
||||
let pluginIndexPath = plugin.indexPath;
|
||||
let pluginIndexPath = plugin.tplPath || plugin.indexPath;
|
||||
if (!pluginIndexPath) {
|
||||
const pluginPath = path.resolve(baseDir, "node_modules", plugin.name);
|
||||
pluginIndexPath = `file://${path.join(pluginPath, "./", plugin.main)}`;
|
||||
}
|
||||
const preload =
|
||||
commonConst.dev() && plugin.name === "rubick-system-feature"
|
||||
? path.resolve(__static, `../feature/public/preload.js`)
|
||||
: path.resolve(
|
||||
pluginIndexPath.replace("file:", ""),
|
||||
`../`,
|
||||
plugin.preload
|
||||
);
|
||||
const preload = getPreloadPath(plugin, pluginIndexPath);
|
||||
|
||||
const ses = session.fromPartition("<" + plugin.name + ">");
|
||||
ses.setPreloads([`${__static}/preload.js`]);
|
||||
@ -44,10 +52,10 @@ export default () => {
|
||||
});
|
||||
window.setBrowserView(view);
|
||||
view.webContents.loadURL(pluginIndexPath);
|
||||
window.once("ready-to-show", () => {
|
||||
view.webContents.once("dom-ready", () => {
|
||||
window.setSize(800, 660);
|
||||
view.setBounds({ x: 0, y: 60, width: 800, height: 600 });
|
||||
view.setAutoResize({ width: true });
|
||||
window.setSize(800, 660);
|
||||
commonConst.dev() && view.webContents.openDevTools();
|
||||
executeHooks("PluginEnter", plugin.ext);
|
||||
executeHooks("PluginReady", plugin.ext);
|
||||
|
@ -8,10 +8,10 @@ import {
|
||||
clipboard,
|
||||
} from "electron";
|
||||
import { runner } from "../browsers";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import { LocalDb } from "@/core";
|
||||
import plist from "plist";
|
||||
import { DECODE_KEY } from "@/common/constans/main";
|
||||
|
||||
const runnerInstance = runner();
|
||||
const dbInstance = new LocalDb(app.getPath("userData"));
|
||||
@ -156,6 +156,22 @@ const API: any = {
|
||||
);
|
||||
return true;
|
||||
},
|
||||
sendPluginSomeKeyDownEvent({ data: { modifiers, keyCode } }) {
|
||||
const code = DECODE_KEY[keyCode];
|
||||
if (!code || !runnerInstance.getView()) return;
|
||||
if (modifiers.length > 0) {
|
||||
runnerInstance.getView().webContents.sendInputEvent({
|
||||
type: "keyDown",
|
||||
modifiers,
|
||||
keyCode: code,
|
||||
});
|
||||
} else {
|
||||
runnerInstance.getView().webContents.sendInputEvent({
|
||||
type: "keyDown",
|
||||
keyCode: code,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default (mainWindow: BrowserWindow) => {
|
||||
|
@ -5,17 +5,12 @@
|
||||
id="search"
|
||||
class="main-input"
|
||||
@input="(e) => changeValue(e)"
|
||||
@keydown.down="() => emit('changeCurrent', 1)"
|
||||
@keydown.up="() => emit('changeCurrent', -1)"
|
||||
@keydown.down="(e) => keydownEvent(e, 1)"
|
||||
@keydown.up="(e) => keydownEvent(e, -1)"
|
||||
@keydown="e => checkNeedInit(e)"
|
||||
:value="searchValue"
|
||||
:placeholder="placeholder || 'Hi, Rubick2'"
|
||||
@keypress.enter="
|
||||
(e) => targetSearch({ value: e.target.value, type: 'enter' })
|
||||
"
|
||||
@keypress.space="
|
||||
(e) => targetSearch({ value: e.target.value, type: 'space' })
|
||||
"
|
||||
@keypress.enter="(e) => keydownEvent(e)"
|
||||
>
|
||||
<template #suffix>
|
||||
<div class="suffix-tool" >
|
||||
@ -64,6 +59,7 @@ const props = defineProps({
|
||||
|
||||
const changeValue = (e) => {
|
||||
if (props.currentPlugin.name === "rubick-system-feature") return;
|
||||
targetSearch({ value: e.target.value });
|
||||
emit("onSearch", e);
|
||||
};
|
||||
|
||||
@ -75,6 +71,27 @@ const emit = defineEmits([
|
||||
"choosePlugin",
|
||||
]);
|
||||
|
||||
const keydownEvent = (e, index) => {
|
||||
const { ctrlKey, shiftKey, altKey, metaKey } = e;
|
||||
const modifiers = [];
|
||||
ctrlKey && modifiers.push("control");
|
||||
shiftKey && modifiers.push("shift");
|
||||
altKey && modifiers.push("alt");
|
||||
metaKey && modifiers.push("meta");
|
||||
ipcRenderer.send("msg-trigger", {
|
||||
type: "sendPluginSomeKeyDownEvent",
|
||||
data: {
|
||||
keyCode: e.code,
|
||||
modifiers,
|
||||
},
|
||||
});
|
||||
if(index) {
|
||||
emit("changeCurrent", index);
|
||||
} else {
|
||||
!props.currentPlugin.name && emit("choosePlugin");
|
||||
}
|
||||
};
|
||||
|
||||
const checkNeedInit = (e) => {
|
||||
if (e.target.value === "" && e.keyCode === 8) {
|
||||
closeTag();
|
||||
@ -87,8 +104,6 @@ const targetSearch = ({ value, type }) => {
|
||||
type: "sendSubInputChangeEvent",
|
||||
data: { text: value },
|
||||
});
|
||||
} else {
|
||||
emit("choosePlugin");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -67,7 +67,7 @@ const createPluginManager = (): any => {
|
||||
return {
|
||||
...pluginInfo,
|
||||
indexPath: commonConst.dev()
|
||||
? "http://localhost:8080/#/"
|
||||
? "http://localhost:8081/#/"
|
||||
: `file://${path.join(pluginPath, "../", pluginInfo.main)}`,
|
||||
};
|
||||
};
|
||||
|
@ -3,6 +3,7 @@ import throttle from "lodash.throttle";
|
||||
import { remote } from "electron";
|
||||
import path from "path";
|
||||
import { PLUGIN_INSTALL_DIR as baseDir } from "@/common/constans/renderer";
|
||||
import commonConst from "@/common/utils/commonConst";
|
||||
|
||||
function searchKeyValues(lists, value) {
|
||||
return lists.filter((item) => {
|
||||
@ -44,16 +45,23 @@ const optionsManager = ({ searchValue, appList, openPlugin, currentPlugin }) =>
|
||||
"node_modules",
|
||||
plugin.name
|
||||
);
|
||||
openPlugin({
|
||||
const pluginDist = {
|
||||
...toRaw(plugin),
|
||||
indexPath: `file://${path.join(
|
||||
pluginPath,
|
||||
"./",
|
||||
plugin.main
|
||||
plugin.main || ""
|
||||
)}`,
|
||||
cmd,
|
||||
feature: fe,
|
||||
});
|
||||
};
|
||||
// 模板文件
|
||||
if (!plugin.main) {
|
||||
pluginDist.tplPath = commonConst.dev()
|
||||
? "http://localhost:8082/#/"
|
||||
: `file://${__static}/tpl/index.html`;
|
||||
}
|
||||
openPlugin(pluginDist);
|
||||
},
|
||||
})),
|
||||
];
|
||||
|
23
tpl/.gitignore
vendored
Normal file
23
tpl/.gitignore
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
24
tpl/README.md
Normal file
24
tpl/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
# tpl
|
||||
|
||||
## Project setup
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
3
tpl/babel.config.js
Normal file
3
tpl/babel.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
presets: ["@vue/cli-plugin-babel/preset"],
|
||||
};
|
13227
tpl/package-lock.json
generated
Normal file
13227
tpl/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
56
tpl/package.json
Normal file
56
tpl/package.json
Normal file
@ -0,0 +1,56 @@
|
||||
{
|
||||
"name": "tpl",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "^3.6.5",
|
||||
"vue": "^3.0.0",
|
||||
"vue-router": "^4.0.0-0",
|
||||
"vuex": "^4.0.0-0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^4.18.0",
|
||||
"@typescript-eslint/parser": "^4.18.0",
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||
"@vue/cli-plugin-router": "~4.5.0",
|
||||
"@vue/cli-plugin-typescript": "~4.5.0",
|
||||
"@vue/cli-plugin-vuex": "~4.5.0",
|
||||
"@vue/cli-service": "~4.5.0",
|
||||
"@vue/compiler-sfc": "^3.0.0",
|
||||
"@vue/eslint-config-prettier": "^6.0.0",
|
||||
"@vue/eslint-config-typescript": "^7.0.0",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-prettier": "^3.3.1",
|
||||
"eslint-plugin-vue": "^7.0.0",
|
||||
"prettier": "^2.2.1",
|
||||
"typescript": "~4.1.5"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/vue3-essential",
|
||||
"eslint:recommended",
|
||||
"@vue/typescript/recommended",
|
||||
"@vue/prettier",
|
||||
"@vue/prettier/@typescript-eslint"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020
|
||||
},
|
||||
"rules": {}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not dead"
|
||||
]
|
||||
}
|
BIN
tpl/public/favicon.ico
Normal file
BIN
tpl/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
17
tpl/public/index.html
Normal file
17
tpl/public/index.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
25
tpl/src/App.vue
Normal file
25
tpl/src/App.vue
Normal file
@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<router-view />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const router = useRouter();
|
||||
window.rubick.onPluginEnter(({ code }) => {
|
||||
const current = window.exports[code];
|
||||
router.push({
|
||||
name: current.mode,
|
||||
params: {
|
||||
code,
|
||||
},
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
6
tpl/src/main.ts
Normal file
6
tpl/src/main.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { createApp } from "vue";
|
||||
import App from "./App.vue";
|
||||
import router from "./router";
|
||||
import store from "./store";
|
||||
|
||||
createApp(App).use(store).use(router).mount("#app");
|
23
tpl/src/router/index.ts
Normal file
23
tpl/src/router/index.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
|
||||
import List from "../views/List.vue";
|
||||
import Doc from "../views/Doc.vue";
|
||||
|
||||
const routes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: "/list",
|
||||
name: "list",
|
||||
component: List,
|
||||
},
|
||||
{
|
||||
path: "/doc",
|
||||
name: "doc",
|
||||
component: Doc,
|
||||
},
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes,
|
||||
});
|
||||
|
||||
export default router;
|
10
tpl/src/shims-vue.d.ts
vendored
Normal file
10
tpl/src/shims-vue.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/* eslint-disable */
|
||||
declare module '*.vue' {
|
||||
import type { DefineComponent } from 'vue'
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
||||
|
||||
interface Window {
|
||||
rubick: any;
|
||||
}
|
8
tpl/src/store/index.ts
Normal file
8
tpl/src/store/index.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { createStore } from "vuex";
|
||||
|
||||
export default createStore({
|
||||
state: {},
|
||||
mutations: {},
|
||||
actions: {},
|
||||
modules: {},
|
||||
});
|
7
tpl/src/views/Doc.vue
Normal file
7
tpl/src/views/Doc.vue
Normal file
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div class="home">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
</script>
|
135
tpl/src/views/List.vue
Normal file
135
tpl/src/views/List.vue
Normal file
@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<div class="list-container">
|
||||
<div class="options" v-show="!!(lists || []).length">
|
||||
<div
|
||||
:key="index"
|
||||
:class="currentSelect === index ? 'active op-item' : 'op-item'"
|
||||
v-for="(item, index) in lists"
|
||||
@click="select(item)"
|
||||
>
|
||||
<img class="icon" :src="item.icon" />
|
||||
<div class="content">
|
||||
<div class="title">{{ item.title }}</div>
|
||||
<div class="desc">{{ decodeURIComponent(item.description) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from "vue-router";
|
||||
import { ref, onBeforeUnmount } from "vue";
|
||||
const { ipcRenderer } = window.require("electron");
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const itemHeight = 60;
|
||||
const itemMaxNum = 10;
|
||||
const defaultHeight = 60;
|
||||
|
||||
const code = route.params.code;
|
||||
const current = window.exports[code];
|
||||
window.rubick.setExpendHeight(defaultHeight);
|
||||
|
||||
const lists = ref([]);
|
||||
current.args.enter &&
|
||||
current.args.enter({ code: code, type: "", payload: [] }, (lists) => {
|
||||
lists.value = lists;
|
||||
});
|
||||
|
||||
const currentSelect = ref(0);
|
||||
ipcRenderer.on(`changeCurrent`, (e, result) => {
|
||||
if (
|
||||
currentSelect.value + result > lists.value.length - 1 ||
|
||||
lists.value + result < 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
currentSelect.value = currentSelect.value + result;
|
||||
});
|
||||
window.rubick.setSubInput(({ text }) => {
|
||||
current.args.search &&
|
||||
current.args.search({ code, type: "", payload: [] }, text, (result) => {
|
||||
lists.value = result || [];
|
||||
const height = lists.value.length > itemMaxNum ? itemMaxNum * itemHeight : itemHeight * lists.value.length
|
||||
window.rubick.setExpendHeight(defaultHeight + height);
|
||||
});
|
||||
}, "搜索");
|
||||
|
||||
const select = (item) => {
|
||||
current.args.select && current.args.select({code, type: '', payload: [] }, item);
|
||||
};
|
||||
|
||||
const onKeydownAction = (e) => {
|
||||
if (e.code === "Enter") {
|
||||
return select(lists.value[currentSelect.value]);
|
||||
}
|
||||
let index = 0;
|
||||
if (e.code === "ArrowDown") {
|
||||
index = 1;
|
||||
}
|
||||
if (e.code === "ArrowUp") {
|
||||
index = -1;
|
||||
}
|
||||
if (!lists.value.length) return;
|
||||
if (
|
||||
currentSelect.value + index > lists.value.length - 1 ||
|
||||
currentSelect.value + index < 0
|
||||
)
|
||||
return;
|
||||
currentSelect.value = currentSelect.value + index;
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", onKeydownAction);
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener("keydown", onKeydownAction);
|
||||
});
|
||||
|
||||
</script>
|
||||
<style>
|
||||
.options {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 99;
|
||||
max-height: calc(100vh);
|
||||
overflow: auto;
|
||||
}
|
||||
.options::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
.op-item {
|
||||
padding: 0 10px;
|
||||
height: 60px;
|
||||
max-height: 500px;
|
||||
overflow: auto;
|
||||
background: #fafafa;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
}
|
||||
.icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 100%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.title {
|
||||
width: 500px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.desc {
|
||||
color: #999;
|
||||
width: 500px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.op-item.active {
|
||||
background: #dee2e8;
|
||||
}
|
||||
</style>
|
39
tpl/tsconfig.json
Normal file
39
tpl/tsconfig.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
"importHelpers": true,
|
||||
"moduleResolution": "node",
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"sourceMap": true,
|
||||
"baseUrl": ".",
|
||||
"types": [
|
||||
"webpack-env"
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue",
|
||||
"tests/**/*.ts",
|
||||
"tests/**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
13
tpl/vue.config.js
Normal file
13
tpl/vue.config.js
Normal file
@ -0,0 +1,13 @@
|
||||
const path = require("path");
|
||||
|
||||
module.exports = {
|
||||
css: { // 配置css模块
|
||||
loaderOptions: { // 向预处理器 Loader 传递配置选项
|
||||
less: { // 配置less(其他样式解析用法一致)
|
||||
javascriptEnabled: true // 设置为true
|
||||
}
|
||||
}
|
||||
},
|
||||
outputDir: path.join(__dirname, "../public/tpl"),
|
||||
publicPath: process.env.NODE_ENV === "production" ? "" : "/",
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user