支持 template 模板 list 模式

This commit is contained in:
muwoo
2021-12-17 17:47:51 +08:00
parent afca4f2b5a
commit 8bcc5d409c
30 changed files with 13784 additions and 28 deletions

23
tpl/.gitignore vendored Normal file
View 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
View 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
View File

@@ -0,0 +1,3 @@
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"],
};

13227
tpl/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

56
tpl/package.json Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

17
tpl/public/index.html Normal file
View 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
View 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
View 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
View 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
View 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
View File

@@ -0,0 +1,8 @@
import { createStore } from "vuex";
export default createStore({
state: {},
mutations: {},
actions: {},
modules: {},
});

7
tpl/src/views/Doc.vue Normal file
View File

@@ -0,0 +1,7 @@
<template>
<div class="home">
</div>
</template>
<script lang="ts">
</script>

135
tpl/src/views/List.vue Normal file
View 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
View 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
View 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" ? "" : "/",
};