mirror of
https://github.com/AkiChase/scrcpy-mask
synced 2025-05-25 18:48:14 +08:00
feat: add help tooltip
This commit is contained in:
parent
2573356b8c
commit
b1f5960306
@ -18,6 +18,7 @@ import {
|
||||
getDeviceScreenSize,
|
||||
adbConnect,
|
||||
getCurClientInfo,
|
||||
adbRestartServer,
|
||||
} from "../tools/invoke";
|
||||
import {
|
||||
NH4,
|
||||
@ -34,6 +35,7 @@ import {
|
||||
useDialog,
|
||||
useMessage,
|
||||
NInputGroup,
|
||||
NSpace,
|
||||
} from "naive-ui";
|
||||
import { CloseCircle, InformationCircle, Refresh } from "@vicons/ionicons5";
|
||||
import { UnlistenFn, listen } from "@tauri-apps/api/event";
|
||||
@ -47,6 +49,7 @@ import {
|
||||
import { LogicalSize, getCurrentWindow } from "@tauri-apps/api/window";
|
||||
import { writeText } from "@tauri-apps/plugin-clipboard-manager";
|
||||
import ButtonWithTip from "./common/ButtonWithTip.vue";
|
||||
import { NonReactiveStore } from "../store/noneReactiveStore";
|
||||
|
||||
const { t } = useI18n();
|
||||
const dialog = useDialog();
|
||||
@ -328,6 +331,21 @@ async function refreshDevices() {
|
||||
store.hideLoading();
|
||||
}
|
||||
|
||||
async function restartAdb() {
|
||||
if (NonReactiveStore.mem.adbUnavailableMsgIns !== null) {
|
||||
message.error(t("pages.Device.adbUnavailable"));
|
||||
return;
|
||||
}
|
||||
store.showLoading();
|
||||
try {
|
||||
await adbRestartServer();
|
||||
} catch (e) {
|
||||
message.error(t("pages.Device.adbRestartError"));
|
||||
console.error(e);
|
||||
}
|
||||
store.hideLoading();
|
||||
}
|
||||
|
||||
async function connectDevice() {
|
||||
if (!wireless_address.value) {
|
||||
message.error(t("pages.Device.inputWirelessAddress"));
|
||||
@ -437,15 +455,24 @@ function closeWS() {
|
||||
<NH4 style="margin: 20px 0" prefix="bar">{{
|
||||
$t("pages.Device.availableDevice")
|
||||
}}</NH4>
|
||||
<NSpace>
|
||||
<ButtonWithTip
|
||||
tertiary
|
||||
circle
|
||||
type="primary"
|
||||
@click="refreshDevices"
|
||||
style="margin-right: 20px"
|
||||
:tip="$t('pages.Device.btnRefresh')"
|
||||
:icon="Refresh"
|
||||
/>
|
||||
<ButtonWithTip
|
||||
tertiary
|
||||
circle
|
||||
type="error"
|
||||
@click="restartAdb"
|
||||
:tip="$t('pages.Device.btnReStart')"
|
||||
:icon="Refresh"
|
||||
/>
|
||||
</NSpace>
|
||||
</NFlex>
|
||||
<NDataTable
|
||||
max-height="120"
|
||||
|
@ -4,9 +4,11 @@ import { useGlobalStore } from "../store/global";
|
||||
import { MessageReactive, useMessage } from "naive-ui";
|
||||
import { ScreenStream } from "../tools/screenStream";
|
||||
import { NonReactiveStore } from "../store/noneReactiveStore";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const store = useGlobalStore();
|
||||
const message = useMessage();
|
||||
const { t } = useI18n();
|
||||
|
||||
const streamImg = ref<HTMLImageElement | null>(null);
|
||||
|
||||
@ -14,16 +16,22 @@ let msgReactive: MessageReactive | null = null;
|
||||
|
||||
function connectScreenStream() {
|
||||
if (streamImg.value) {
|
||||
const ss = new ScreenStream(streamImg.value, NonReactiveStore.mem.screenStreamClientId);
|
||||
const ss = new ScreenStream(
|
||||
streamImg.value,
|
||||
NonReactiveStore.mem.screenStreamClientId
|
||||
);
|
||||
ss.connect(
|
||||
store.screenStream.address,
|
||||
() => {},
|
||||
() => {
|
||||
msgReactive = message.error("投屏连接失败。关闭此信息将尝试重新连接", {
|
||||
msgReactive = message.error(
|
||||
t("pages.Setting.Mask.screenStream.connectError"),
|
||||
{
|
||||
duration: 0,
|
||||
closable: true,
|
||||
onClose: () => connectScreenStream(),
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { NFlex, NH4, NButton, NIcon, NP, NCheckbox } from "naive-ui";
|
||||
import { LogoGithub, Planet } from "@vicons/ionicons5";
|
||||
import { open } from "@tauri-apps/plugin-shell";
|
||||
import { getVersion } from "@tauri-apps/api/app";
|
||||
import { onMounted, ref } from "vue";
|
||||
import { useGlobalStore } from "../../store/global";
|
||||
import { LocalStore } from "../../store/localStore";
|
||||
import { useCheckUpdate } from "../../tools/hooks";
|
||||
import { openWebsite } from "../../tools/tools";
|
||||
|
||||
const store = useGlobalStore();
|
||||
const checkUpdate = useCheckUpdate();
|
||||
@ -16,10 +16,6 @@ onMounted(async () => {
|
||||
appVersion.value = await getVersion();
|
||||
});
|
||||
|
||||
function opendWebsite(url: string) {
|
||||
open(url);
|
||||
}
|
||||
|
||||
async function onClickCheckUpdate() {
|
||||
store.showLoading();
|
||||
await checkUpdate();
|
||||
@ -34,7 +30,7 @@ async function onClickCheckUpdate() {
|
||||
<NFlex :size="30">
|
||||
<NButton
|
||||
text
|
||||
@click="opendWebsite('https://github.com/AkiChase/scrcpy-mask')"
|
||||
@click="openWebsite('https://github.com/AkiChase/scrcpy-mask')"
|
||||
>
|
||||
<template #icon>
|
||||
<NIcon><LogoGithub /> </NIcon>
|
||||
@ -43,7 +39,7 @@ async function onClickCheckUpdate() {
|
||||
</NButton>
|
||||
<NButton
|
||||
text
|
||||
@click="opendWebsite('https://space.bilibili.com/440760180')"
|
||||
@click="openWebsite('https://space.bilibili.com/440760180')"
|
||||
>
|
||||
<template #icon>
|
||||
<NIcon
|
||||
@ -63,7 +59,7 @@ async function onClickCheckUpdate() {
|
||||
</template>
|
||||
BiliBili
|
||||
</NButton>
|
||||
<NButton text @click="opendWebsite('https://www.akichase.top/')">
|
||||
<NButton text @click="openWebsite('https://www.akichase.top/')">
|
||||
<template #icon>
|
||||
<NIcon><Planet /> </NIcon>
|
||||
</template>
|
||||
|
@ -7,9 +7,7 @@ import {
|
||||
NFormItemGi,
|
||||
NInputNumber,
|
||||
FormRules,
|
||||
NButton,
|
||||
NFlex,
|
||||
NIcon,
|
||||
FormInst,
|
||||
useMessage,
|
||||
NSlider,
|
||||
@ -22,11 +20,13 @@ import {
|
||||
LogicalSize,
|
||||
getCurrentWindow,
|
||||
} from "@tauri-apps/api/window";
|
||||
import { SettingsOutline } from "@vicons/ionicons5";
|
||||
import { Help, SettingsOutline } from "@vicons/ionicons5";
|
||||
import { useGlobalStore } from "../../store/global";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { LocalStore } from "../../store/localStore";
|
||||
import { NonReactiveStore } from "../../store/noneReactiveStore";
|
||||
import ButtonWithTip from "../common/ButtonWithTip.vue";
|
||||
import { openWebsite } from "../../tools/tools";
|
||||
|
||||
const { t } = useI18n();
|
||||
const store = useGlobalStore();
|
||||
@ -154,17 +154,14 @@ async function adjustWindowMaskArea() {
|
||||
>
|
||||
<NFlex justify="space-between" align="center">
|
||||
<NH4 prefix="bar">{{ $t("pages.Setting.Mask.areaAdjust") }}</NH4>
|
||||
<NButton
|
||||
<ButtonWithTip
|
||||
tertiary
|
||||
circle
|
||||
type="primary"
|
||||
@click="handleAdjustClick"
|
||||
style="margin-right: 20px"
|
||||
>
|
||||
<template #icon>
|
||||
<NIcon><SettingsOutline /></NIcon>
|
||||
</template>
|
||||
</NButton>
|
||||
:tip="$t('pages.Setting.Mask.btnAreaAdjustTip')"
|
||||
:icon="SettingsOutline"
|
||||
/>
|
||||
</NFlex>
|
||||
<NGrid :cols="2" :x-gap="24">
|
||||
<NFormItemGi label="X" path="posX">
|
||||
@ -226,8 +223,17 @@ async function adjustWindowMaskArea() {
|
||||
/>
|
||||
</NFormItemGi>
|
||||
</NGrid>
|
||||
|
||||
<NFlex justify="space-between" align="center">
|
||||
<NH4 prefix="bar">ScreenStream</NH4>
|
||||
<ButtonWithTip
|
||||
tertiary
|
||||
circle
|
||||
type="primary"
|
||||
@click="openWebsite('https://github.com/dkrivoruchko/ScreenStream')"
|
||||
:tip="$t('pages.Setting.Mask.screenStream.btnHelp')"
|
||||
:icon="Help"
|
||||
/>
|
||||
</NFlex>
|
||||
<NFormItem
|
||||
:label="$t('pages.Setting.Mask.screenStream.enable')"
|
||||
label-placement="left"
|
||||
|
@ -7,6 +7,7 @@ import { NTabs, NTabPane, NSpin } from "naive-ui";
|
||||
import { useGlobalStore } from "../../store/global";
|
||||
import SettingTab from "./SettingTab.vue";
|
||||
|
||||
// TODO Switch back to landscape size when entering Settings and Devices screen
|
||||
const store = useGlobalStore();
|
||||
</script>
|
||||
|
||||
|
@ -30,6 +30,7 @@ div#app {
|
||||
}
|
||||
|
||||
.n-spin-container {
|
||||
background-color: var(--bg-color);
|
||||
@include common.flexFullHeight;
|
||||
.n-spin-content {
|
||||
@include common.flexFullHeight;
|
||||
|
@ -38,7 +38,10 @@
|
||||
"adbConnectError": "Wireless connection failed",
|
||||
"rotation": "Device rotation {0}°",
|
||||
"btnShutdown": "Shutdown control",
|
||||
"btnRefresh": "Refresh"
|
||||
"btnRefresh": "Refresh",
|
||||
"btnReStart": "Restart ADB",
|
||||
"adbRestartError": "ADB Restart Failed",
|
||||
"adbUnavailable": "ADB Unavailable"
|
||||
},
|
||||
"Mask": {
|
||||
"keyconfigException": "The key mapping config is abnormal, please delete this config",
|
||||
@ -97,8 +100,11 @@
|
||||
"screenStream": {
|
||||
"enable": "Enable mirror",
|
||||
"address": "Screen mirror address",
|
||||
"addressPlaceholder": "Please enter the ScreenStream screen mirror address"
|
||||
}
|
||||
"addressPlaceholder": "Please enter the ScreenStream screen mirror address",
|
||||
"connectError": "ScreenStream connection failed. Closing this message will attempt to reconnect",
|
||||
"btnHelp": "ScreenStream is an Android screen mirror app with 0.5-1s screen delay, only as a complementary solution to Scrcpy Mask's screen mirror (click to open its project homepage)"
|
||||
},
|
||||
"btnAreaAdjustTip": "Setting the mask area"
|
||||
},
|
||||
"Basic": {
|
||||
"language": "Language",
|
||||
@ -282,5 +288,6 @@
|
||||
"open": "Connected to external control server",
|
||||
"close": "External control connection disconnected",
|
||||
"error": "Something was wrong, the exter connection is closed"
|
||||
}
|
||||
},
|
||||
"screenStream": {}
|
||||
}
|
||||
|
@ -38,7 +38,10 @@
|
||||
"adbConnectError": "无线连接失败",
|
||||
"rotation": "设备旋转 {0}°",
|
||||
"btnShutdown": "关闭控制",
|
||||
"btnRefresh": "刷新"
|
||||
"btnRefresh": "刷新",
|
||||
"btnReStart": "重启ABD",
|
||||
"adbRestartError": "ADB 重启失败",
|
||||
"adbUnavailable": "ADB 不可用"
|
||||
},
|
||||
"Mask": {
|
||||
"keyconfigException": "按键方案异常,请删除此方案",
|
||||
@ -97,8 +100,11 @@
|
||||
"screenStream": {
|
||||
"enable": "启用投屏",
|
||||
"address": "投屏地址",
|
||||
"addressPlaceholder": "请输入 ScreenStream 投屏地址"
|
||||
}
|
||||
"addressPlaceholder": "请输入 ScreenStream 投屏地址",
|
||||
"connectError": "ScreenStream 投屏连接失败。关闭此信息将尝试重新连接",
|
||||
"btnHelp": "ScreenStream 是一款安卓投屏App,存在0.5-1s的画面延迟,仅作为 Scrcpy Mask 的投屏补充方案(点击打开其项目主页)"
|
||||
},
|
||||
"btnAreaAdjustTip": "设置蒙版区域"
|
||||
},
|
||||
"Basic": {
|
||||
"language": "语言",
|
||||
@ -282,5 +288,6 @@
|
||||
"open": "已连接到外部控制服务端",
|
||||
"close": "外部控制连接断开",
|
||||
"error": "未知错误,外部控制连接断开"
|
||||
}
|
||||
},
|
||||
"screenStream": {}
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { MessageReactive } from "naive-ui";
|
||||
import { LocalStore } from "./localStore";
|
||||
|
||||
interface MemType {
|
||||
screenStreamClientId: string;
|
||||
keyInputFlag: boolean;
|
||||
adbUnavailableMsgIns: MessageReactive | null;
|
||||
}
|
||||
|
||||
interface LocalType {
|
||||
@ -19,6 +21,7 @@ export class NonReactiveStore {
|
||||
static mem: MemType = {
|
||||
screenStreamClientId: "",
|
||||
keyInputFlag: false,
|
||||
adbUnavailableMsgIns: null,
|
||||
};
|
||||
|
||||
static local: LocalType = {
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { getVersion } from "@tauri-apps/api/app";
|
||||
import { MessageReactive, useDialog, useMessage } from "naive-ui";
|
||||
import { useDialog, useMessage } from "naive-ui";
|
||||
import { h } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { fetch } from "@tauri-apps/plugin-http";
|
||||
import { compareVersion } from "./tools";
|
||||
import { checkAdbAvailable } from "./invoke";
|
||||
import { NonReactiveStore } from "../store/noneReactiveStore";
|
||||
|
||||
// TODO use markdown to render update info
|
||||
// TODO check screen stream available
|
||||
|
||||
function renderUpdateInfo(content: string) {
|
||||
const pList = content.split("\r\n").map((line: string) => h("p", line));
|
||||
@ -56,22 +56,24 @@ export function useCheckUpdate() {
|
||||
};
|
||||
}
|
||||
|
||||
let checkAdbMessage: MessageReactive | null = null;
|
||||
export function useCheckAdb() {
|
||||
const message = useMessage();
|
||||
const { t } = useI18n();
|
||||
|
||||
return async function checkAdb() {
|
||||
try {
|
||||
if (checkAdbMessage) {
|
||||
checkAdbMessage.destroy();
|
||||
checkAdbMessage = null;
|
||||
if (NonReactiveStore.mem.adbUnavailableMsgIns) {
|
||||
NonReactiveStore.mem.adbUnavailableMsgIns.destroy();
|
||||
NonReactiveStore.mem.adbUnavailableMsgIns = null;
|
||||
}
|
||||
await checkAdbAvailable();
|
||||
} catch (e) {
|
||||
checkAdbMessage = message.error(t("pages.Mask.checkAdb", [e]), {
|
||||
NonReactiveStore.mem.adbUnavailableMsgIns = message.error(
|
||||
t("pages.Mask.checkAdb", [e]),
|
||||
{
|
||||
duration: 0,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -9,6 +9,10 @@ export async function adbDevices(): Promise<Device[]> {
|
||||
return await invoke("adb_devices");
|
||||
}
|
||||
|
||||
export async function adbRestartServer(): Promise<void> {
|
||||
return await invoke("adb_restart_server");
|
||||
}
|
||||
|
||||
export async function forwardServerPort(
|
||||
id: string,
|
||||
scid: string,
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { getCurrentWindow, LogicalSize } from "@tauri-apps/api/window";
|
||||
import { open as shellOpen } from "@tauri-apps/plugin-shell";
|
||||
|
||||
export function compareVersion(v1: string, v2: string) {
|
||||
const [x1, y1, z1] = v1.split(".");
|
||||
@ -36,3 +37,7 @@ export async function cleanAfterimage() {
|
||||
await appWindow.setSize(newSize);
|
||||
await appWindow.setSize(oldSize);
|
||||
}
|
||||
|
||||
export function openWebsite(url: string) {
|
||||
shellOpen(url);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user