Skip to content

Commit

Permalink
feat: 粘贴
Browse files Browse the repository at this point in the history
  • Loading branch information
nopdan committed Mar 12, 2024
1 parent 5ef3c9b commit cb2d04b
Show file tree
Hide file tree
Showing 11 changed files with 220 additions and 111 deletions.
5 changes: 2 additions & 3 deletions frontend/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ import Main from "./components/Main.vue";
<style>
.content {
margin: auto;
max-width: 800px;
max-width: 700px;
min-height: 90vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-family: -apple-system, "Noto Sans", "Helvetica Neue", Helvetica, "Nimbus Sans L", Arial, "Liberation Sans",
"PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Source Han Sans SC", "Source Han Sans CN", "Microsoft YaHei",
Expand All @@ -32,7 +31,7 @@ import Main from "./components/Main.vue";
color: transparent;
font-size: xx-large;
font-weight: bold;
padding: 1em;
padding: 12px;
font-family: Baskerville, Georgia, "Liberation Serif", "Kaiti SC", STKaiti, "AR PL UKai CN", "AR PL UKai HK",
"AR PL UKai TW", "AR PL UKai TW MBE", "AR PL KaitiM GB", KaiTi, KaiTi_GB2312, DFKai-SB, "TW\-Kai", serif;
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/Data.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Generated by https://quicktype.io

import { OldData } from "./OldData";
import { DataOld } from "./DataOld";

export interface Data {
Info: Info;
Expand Down Expand Up @@ -105,9 +105,9 @@ export class DataUtils {
}
}

export function New2Old(_new: Data): OldData {
export function New2Old(_new: Data): DataOld {
const util = new DataUtils(_new);
const _old: OldData = {
const _old: DataOld = {
TextName: _new.Info.TextName,
TextLen: _new.Info.TextLen,
DictName: _new.Info.DictName,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Generated by https://quicktype.io

export interface OldData {
export interface DataOld {
TextName: string;
TextLen: number;
DictName: string;
Expand Down
225 changes: 144 additions & 81 deletions frontend/src/components/Main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,39 @@
import { ClipboardOutline as ClipboardIcon } from "@vicons/ionicons5";
import { Data } from "./Data";
interface Config {
// 文本
// 文本
interface TextConfig {
source: string;
path: string;
text: string;
/** 计算所有文本并合并结果 */
merge: boolean;
/** 忽略缺字和符号*/
clean: boolean;
name: string | null;
string: string | null;
}
/** 计算所有文本并合并结果 */
const merge = ref(false);
/** 忽略缺字和符号*/
const clean = ref(false);
/** 文本来源 */
const srcOptions = [
{ label: "本地文件", value: "local" },
{ label: "剪贴板", value: "clipboard" },
];
const conf = reactive({
const text = reactive({
source: "local",
} as Config);
} as TextConfig);
const textOpts = ref([]);
function paste() {
function paste(type: string) {
navigator.clipboard
.readText()
.then((text) => {
conf.text = text;
.then((str) => {
if (type === "text") {
text.string = str;
} else if (type === "dict") {
dict.string = str;
}
})
.catch((err) => console.error("读取剪贴板内容失败:", err));
}
Expand Down Expand Up @@ -74,8 +79,7 @@ enum SpacePreference {
Right = "right",
}
interface Dict {
path: string;
interface Dict extends TextConfig {
/** 码表格式 */
format: DictFormat;
/** 起顶码长 */
Expand Down Expand Up @@ -145,6 +149,7 @@ const spaceOptions = [
];
const dict = reactive({
source: "local",
format: DictFormat.Default,
push: 4,
keys: "_;'",
Expand All @@ -155,8 +160,51 @@ const dict = reactive({
const dictList = reactive(new Array<Dict>());
const dictOpts = ref([]);
watch(
() => text.source,
() => {
text.name = null;
text.string = null;
},
);
watch(
() => text.string,
() => {
if (text.string) {
text.name = clipText(text.string, 10);
}
},
);
const disableFormat = ref(true);
watch(
() => dict.source,
() => {
dict.name = null;
dict.string = null;
if (dict.source === "local") {
dict.format = DictFormat.Default;
disableFormat.value = true;
} else {
disableFormat.value = false;
}
},
);
watch(
() => dict.string,
() => {
if (dict.string) {
dict.name = clipText(dict.string, 10);
}
},
);
function addDict(dict: Dict): void {
if (dict.source === "local") {
dict.name = tidyPath(dict.path, "dict");
}
const d = Object.assign({}, dict);
dictList.push(d);
console.log("添加码表", d);
Expand All @@ -168,8 +216,8 @@ function removeDict(index: number): void {
dictList.splice(index, 1);
}
function tidyPath(path: string, suffix: string) {
const index = path.lastIndexOf(suffix);
function tidyPath(path: string, type: string) {
const index = path.lastIndexOf(type);
let name = path;
if (index != -1) {
name = path.substring(index + 5);
Expand All @@ -190,8 +238,8 @@ function fetchList() {
value: e,
};
});
if (conf.path == null) {
conf.path = data.text[0];
if (text.path == null) {
text.path = data.text[0];
}
dictOpts.value = data.dict.map((e: string) => {
return {
Expand All @@ -218,7 +266,12 @@ async function race() {
racing.value = true;
// 生成 formData
const formData = new FormData();
const data = JSON.stringify(Object.assign({}, conf, { dict: dictList }));
const data = JSON.stringify({
clean: clean.value,
merge: merge.value,
text: text,
dict: dictList,
});
formData.append("data", data);
console.log("data:", data);
Expand All @@ -243,39 +296,40 @@ async function race() {
</script>

<template>
<div class="line">
<span class="name">文本来源</span>
<n-radio-group v-model:value="conf.source" size="large">
<n-flex>
<n-radio v-for="src in srcOptions" :key="src.value" :value="src.value">
{{ src.label }}
</n-radio>
</n-flex>
</n-radio-group>
</div>
<div v-if="conf.source === 'local'">
<div class="line">
<span class="name">选择文本</span>
<n-select v-model:value="conf.path" :options="textOpts" placeholder="请选择文件" :disabled="conf.merge" />
</div>
<div>
<div class="line">
<span class="name">全部文本</span>
<n-switch v-model:value="conf.merge"></n-switch>
<span class="name">文本来源</span>
<n-radio-group v-model:value="text.source" size="large">
<n-flex>
<n-radio v-for="src in srcOptions" :key="src.value" :value="src.value">
{{ src.label }}
</n-radio>
</n-flex>
</n-radio-group>
</div>
</div>
<div class="line" v-if="conf.source === 'clipboard'" style="min-height: 150px">
<span class="name"></span>
<div v-if="conf.text" class="text-preview">
{{ clipText(conf.text || "", 100) }}
<div v-if="text.source === 'local'">
<div class="line">
<span class="name">选择文本</span>
<n-select v-model:value="text.path" :options="textOpts" placeholder="请选择文本" :disabled="merge" />
</div>
<div class="line">
<span class="name">全部文本</span>
<n-switch v-model:value="merge"></n-switch>
</div>
</div>
<div class="clipboard" @click="paste">
<div class="empty">
<div style="margin-bottom: 12px">
<n-icon size="48" :depth="3">
<clipboard-icon />
</n-icon>
<div v-if="text.source === 'clipboard'">
<div class="line">
<span class="name">文本名</span>
<n-input v-model:value="text.name"></n-input>
</div>
<div class="line">
<span class="name"></span>
<div style="display: flex">
<n-button @click="paste('text')" style="margin-right: 10px">读取剪贴板</n-button>
</div>
<div v-if="text.string" class="text-preview">
{{ clipText(text.string || "", 100) }}
</div>
<n-text style="font-size: 16px"> 点击读取系统剪贴板 </n-text>
</div>
</div>
</div>
Expand All @@ -285,18 +339,45 @@ async function race() {
<div>
<n-flex justify="center">
<n-tag type="success" closable v-for="(conf, idx) in dictList" @close="removeDict(idx)">
{{ tidyPath(conf.path, "dict") }}
{{ conf.name }}
</n-tag>
</n-flex>
<div class="line">
<span class="name">选择码表</span>
<n-select v-model:value="dict.path" :options="dictOpts" placeholder="请选择文件" />
<span class="name">码表来源</span>
<n-radio-group v-model:value="dict.source" size="large">
<n-flex>
<n-radio v-for="src in srcOptions" :key="src.value" :value="src.value">
{{ src.label }}
</n-radio>
</n-flex>
</n-radio-group>
</div>
<div v-if="dict.source === 'local'">
<div class="line">
<span class="name">选择码表</span>
<n-select v-model:value="dict.path" :options="dictOpts" placeholder="请选择文件" />
</div>
</div>
<div v-if="dict.source === 'clipboard'">
<div class="line">
<span class="name">码表名</span>
<n-input v-model:value="dict.name"></n-input>
</div>
<div class="line">
<span class="name"></span>
<div style="display: flex">
<n-button @click="paste('dict')" style="margin-right: 10px">读取剪贴板</n-button>
</div>
<div v-if="dict.string" class="text-preview">
{{ clipText(dict.string || "", 100) }}
</div>
</div>
</div>
<div class="line">
<span class="name">码表格式</span>
<n-radio-group v-model:value="dict.format" size="large">
<n-flex>
<n-radio v-for="format in formatOptions" :key="format.value" :value="format.value">
<n-radio v-for="format in formatOptions" :key="format.value" :value="format.value" :disabled="disableFormat">
{{ format.label }}
</n-radio>
</n-flex>
Expand Down Expand Up @@ -346,15 +427,23 @@ async function race() {
</n-radio-group>
</div>
<n-flex justify="center">
<n-button type="info" @click="addDict(dict)" style="width: 100px" ghost> 添加</n-button>
<n-button
type="info"
@click="addDict(dict)"
:disabled="dict.source === 'clipboard' && !dict.string"
style="width: 100px"
ghost
>
添加</n-button
>
</n-flex>
</div>

<n-divider />
<div class="line" style="justify-content: right">
<span style="margin-right: 20px; display: flex; align-items: center">
<span style="margin-right: 10px">忽略缺字和符号</span>
<n-switch v-model:value="conf.clean" />
<n-switch v-model:value="clean" />
</span>
<n-button type="primary" @click="race" :disabled="dictList.length === 0" :loading="racing">开始比赛</n-button>
</div>
Expand All @@ -380,34 +469,8 @@ async function race() {
}
}
.clipboard {
display: flex;
justify-content: center;
width: 100%;
min-height: 120px;
border: 1px dashed #e0e0e6;
border-radius: 3px;
padding: 14px;
background-color: #fafafc;
cursor: pointer;
align-items: center;
& .empty {
text-align: center;
}
&:hover {
border-color: #18a058;
}
&:active {
background-color: #f0f0f0;
}
}
.text-preview {
color: #999;
width: 600px;
margin-right: 14px;
padding: 0 15px;
}
</style>
Loading

0 comments on commit cb2d04b

Please sign in to comment.