add systray

This commit is contained in:
2026-02-07 17:57:48 +08:00
parent eb23ef9d5d
commit e76ada9b4b
17 changed files with 335 additions and 617 deletions

View File

@@ -17,7 +17,8 @@ import {
GetVersion,
GetLanguage,
SetLanguage,
GetLanguageByString,
SetCloseToSystray,
GetCloseToSystray,
} from "../../bindings/mesh-drop/internal/config/config";
import { Language } from "bindings/mesh-drop/internal/config";
@@ -27,6 +28,7 @@ const hostName = ref("");
const autoAccept = ref(false);
const saveHistory = ref(false);
const version = ref("");
const closeToSystray = ref(false);
const { t, locale } = useI18n();
@@ -46,6 +48,7 @@ onMounted(async () => {
if (l != "") {
locale.value = l;
}
closeToSystray.value = await GetCloseToSystray();
});
// --- 方法 ---
@@ -71,6 +74,7 @@ watch(locale, async (newVal) => {
<template>
<v-list lines="one" bg-color="transparent">
<!-- 保存路径 -->
<v-list-item :title="t('settings.savePath')" :subtitle="savePath">
<template #prepend>
<v-icon icon="mdi-folder-download"></v-icon>
@@ -86,6 +90,8 @@ watch(locale, async (newVal) => {
</v-btn>
</template>
</v-list-item>
<!-- 主机名 -->
<v-list-item :title="t('settings.hostName')">
<template #prepend>
<v-icon icon="mdi-laptop"></v-icon>
@@ -100,6 +106,8 @@ watch(locale, async (newVal) => {
></v-text-field>
</template>
</v-list-item>
<!-- 保存历史 -->
<v-list-item :title="t('settings.saveHistory')">
<template #prepend>
<v-icon icon="mdi-history"></v-icon>
@@ -114,6 +122,8 @@ watch(locale, async (newVal) => {
></v-switch>
</template>
</v-list-item>
<!-- 自动接受 -->
<v-list-item :title="t('settings.autoAccept')">
<template #prepend>
<v-icon icon="mdi-content-save"></v-icon>
@@ -128,15 +138,24 @@ watch(locale, async (newVal) => {
></v-switch>
</template>
</v-list-item>
<v-list-item :title="t('settings.version')">
<!-- 关闭窗口时最小化到托盘 -->
<v-list-item :title="t('settings.closeToSystray')">
<template #prepend>
<v-icon icon="mdi-information"></v-icon>
<v-icon icon="mdi-tray"></v-icon>
</template>
<template #append>
<div class="text-grey">{{ version }}</div>
<v-switch
v-model="closeToSystray"
color="primary"
inset
hide-details
@update:modelValue="SetCloseToSystray(closeToSystray)"
></v-switch>
</template>
</v-list-item>
<!-- 语言 -->
<v-list-item :title="t('settings.language')">
<template #prepend>
<v-icon icon="mdi-translate"></v-icon>
@@ -152,5 +171,15 @@ watch(locale, async (newVal) => {
></v-select>
</template>
</v-list-item>
<!-- 版本 -->
<v-list-item :title="t('settings.version')">
<template #prepend>
<v-icon icon="mdi-information"></v-icon>
</template>
<template #append>
<div class="text-grey">{{ version }}</div>
</template>
</v-list-item>
</v-list>
</template>

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
// --- Vue 核心 ---
import { computed, ref, watch } from "vue";
import { useI18n } from "vue-i18n";
// --- Wails & 后端绑定 ---
import { Events, Dialogs } from "@wailsio/runtime";
@@ -20,6 +21,7 @@ const emit = defineEmits<{
}>();
// --- 状态 ---
const { t } = useI18n();
const fileList = ref<{ name: string; path: string }[]>([]);
// --- 计算属性 ---
@@ -51,7 +53,7 @@ watch(show, (newVal) => {
// --- 方法 ---
const openFileDialog = async () => {
const files = await Dialogs.OpenFile({
Title: "Select files to send",
Title: t("modal.fileSend.selectTitle"),
AllowsMultipleSelection: true,
});
@@ -91,14 +93,14 @@ const handleSendFiles = async () => {
show.value = false;
} catch (e) {
console.error(e);
alert("Failed to send files: " + e);
alert(t("modal.fileSend.failed", { error: e }));
}
};
</script>
<template>
<v-dialog v-model="show" width="600" persistent eager>
<v-card title="Send Files">
<v-card :title="$t('modal.fileSend.title')">
<v-card-text>
<div
v-if="fileList.length === 0"
@@ -113,7 +115,7 @@ const handleSendFiles = async () => {
class="mb-2"
></v-icon>
<div class="text-body-1 text-medium-emphasis">
Click to select files
{{ $t("modal.fileSend.dragDrop") }}
</div>
</div>
@@ -153,20 +155,23 @@ const handleSendFiles = async () => {
@click="openFileDialog"
class="mt-2"
>
Add more files
{{ $t("modal.fileSend.addMore") }}
</v-btn>
</div>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn variant="text" @click="show = false">Cancel</v-btn>
<v-btn variant="text" @click="show = false">{{
$t("common.cancel")
}}</v-btn>
<v-btn
color="primary"
@click="handleSendFiles"
:disabled="fileList.length === 0"
>
Send {{ fileList.length > 0 ? `(${fileList.length})` : "" }}
{{ $t("modal.fileSend.sendSrc") }}
{{ fileList.length > 0 ? `(${fileList.length})` : "" }}
</v-btn>
</v-card-actions>
</v-card>

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
// --- Vue 核心 ---
import { computed, ref, watch, nextTick } from "vue";
import { useI18n } from "vue-i18n";
// --- Wails & 后端绑定 ---
import { SendText } from "../../../bindings/mesh-drop/internal/transfer/service";
@@ -19,6 +20,7 @@ const emit = defineEmits<{
}>();
// --- 状态 ---
const { t } = useI18n();
const textContent = ref("");
const textareaRef = ref();
@@ -47,33 +49,35 @@ const executeSendText = async () => {
textContent.value = "";
} catch (e) {
console.error(e);
alert("Failed to send text: " + e);
alert(t("modal.textSend.failed", { error: e }));
}
};
</script>
<template>
<v-dialog v-model="show" width="500" persistent eager>
<v-card title="Send Text">
<v-card :title="$t('modal.textSend.title')">
<v-card-text>
<v-textarea
ref="textareaRef"
v-model="textContent"
label="Content"
placeholder="Type something to send..."
:label="$t('modal.textSend.contentLabel')"
:placeholder="$t('modal.textSend.placeholder')"
rows="4"
auto-grow
></v-textarea>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn variant="text" @click="show = false">Cancel</v-btn>
<v-btn variant="text" @click="show = false">{{
$t("common.cancel")
}}</v-btn>
<v-btn
color="primary"
@click="executeSendText"
:disabled="!textContent"
>
Send
{{ $t("modal.textSend.send") }}
</v-btn>
</v-card-actions>
</v-card>