feat: rotate only on specific pages

This commit is contained in:
AkiChase 2025-03-13 20:18:19 +08:00
parent b1f5960306
commit 6eac5c8875
8 changed files with 109 additions and 25 deletions

View File

@ -50,24 +50,29 @@ 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";
import { useRoute } from "vue-router";
import { useHorRotation } from "../tools/hooks";
const { t } = useI18n();
const dialog = useDialog();
const store = useGlobalStore();
const message = useMessage();
const route = useRoute();
const horRotation = useHorRotation();
const port = ref(27183);
const wireless_address = ref("");
const ws_address = ref("");
//#region listener
let unlisten: UnlistenFn | null = null;
let deviceWaitForMetadataTask: ((deviceName: string) => void) | null = null;
let deviceWaitForScreenSizeTask: ((w: number, h: number) => void) | null = null;
let unlisten: UnlistenFn | undefined = undefined;
let lastClipboard = "";
onMounted(async () => {
const appWindow = getCurrentWindow();
unlisten = await listen("device-reply", (event) => {
try {
let payload = JSON.parse(event.payload as string);
@ -90,17 +95,32 @@ onMounted(async () => {
store.screenSizeH = payload.height;
message.info(t("pages.Device.rotation", [payload.rotation * 90]));
}
if (store.rotation.enable) {
let maskW: number;
let maskH: number;
if (payload.width >= payload.height) {
maskW = Math.round(store.rotation.horizontalLength);
maskH = Math.round(maskW * (payload.height / payload.width));
} else {
maskH = Math.round(store.rotation.verticalLength);
maskW = Math.round(maskH * (payload.width / payload.height));
}
getCurrentWindow().setSize(new LogicalSize(maskW + 70, maskH + 30));
let maskW: number;
let maskH: number;
if (payload.width >= payload.height) {
maskW = Math.round(store.rotation.horizontalLength);
maskH = Math.round(maskW * (payload.height / payload.width));
NonReactiveStore.mem.rotationState = {
direction: "horizontal",
maskW,
maskH,
};
} else {
maskH = Math.round(store.rotation.verticalLength);
maskW = Math.round(maskH * (payload.width / payload.height));
NonReactiveStore.mem.rotationState = {
direction: "vertical",
maskW,
maskH,
};
}
if (
store.rotation.enable &&
(route.name === "mask" || route.name === "keyboard")
) {
appWindow.setSize(new LogicalSize(maskW + 70, maskH + 30));
}
break;
default:
@ -114,7 +134,7 @@ onMounted(async () => {
});
onActivated(async () => {
let curClientInfo = await getCurClientInfo();
const curClientInfo = await getCurClientInfo();
if (store.controledDevice) {
// update controledDevice if client not exists
if (!curClientInfo) {
@ -135,7 +155,7 @@ onActivated(async () => {
};
}
}
await horRotation();
await refreshDevices();
});
@ -228,7 +248,7 @@ function onMenuClickoutside() {
}
async function deviceControl() {
let curClientInfo = await getCurClientInfo();
const curClientInfo = await getCurClientInfo();
if (curClientInfo) {
message.error(t("pages.Device.alreadyControled"));
store.controledDevice = {
@ -248,7 +268,7 @@ async function deviceControl() {
const device = devices.value[rowIndex];
let scid = (
const scid = (
"00000000" + Math.floor(Math.random() * 100000).toString(16)
).slice(-8);
@ -257,7 +277,7 @@ async function deviceControl() {
await startScrcpyServer(device.id, scid, `127.0.0.1:${port.value}`);
// connection timeout check
let id = setTimeout(async () => {
const connectionTimeout = setTimeout(async () => {
if (deviceWaitForMetadataTask) {
await shutdown();
store.controledDevice = null;
@ -276,7 +296,7 @@ async function deviceControl() {
deviceWaitForMetadataTask = null;
if (!deviceWaitForScreenSizeTask) {
nextTick(() => {
clearTimeout(id);
clearTimeout(connectionTimeout);
store.hideLoading();
});
}
@ -289,7 +309,7 @@ async function deviceControl() {
deviceWaitForScreenSizeTask = null;
if (!deviceWaitForMetadataTask) {
nextTick(() => {
clearTimeout(id);
clearTimeout(connectionTimeout);
store.hideLoading();
});
}
@ -437,7 +457,7 @@ function closeWS() {
quaternary
circle
type="info"
:tip="`scid: ${store.controledDevice.scid}`"
:tip="`scid: ${store.controledDevice.scid}; w: ${store.screenSizeW}; h: ${store.screenSizeH}`"
:icon="InformationCircle"
/>
<ButtonWithTip

View File

@ -16,12 +16,17 @@ import { useI18n } from "vue-i18n";
import { secondaryClean, secondaryInit } from "../tools/init";
import { cleanAfterimage } from "../tools/tools";
import { NonReactiveStore } from "../store/noneReactiveStore";
import { useRotation } from "../tools/hooks";
import { platform } from "@tauri-apps/plugin-os";
const { t } = useI18n();
const store = useGlobalStore();
const router = useRouter();
const message = useMessage();
const rotation = useRotation();
let initFlag = false;
const platformName = platform();
const curPageActive = ref(false);
@ -37,7 +42,8 @@ onBeforeRouteLeave(() => {
onActivated(async () => {
curPageActive.value = true;
if (initFlag) cleanAfterimage();
if (initFlag && platformName === "macos") await cleanAfterimage();
if (store.controledDevice) {
if (
@ -53,6 +59,7 @@ onActivated(async () => {
message.error(t("pages.Mask.keyconfigException"));
}
}
await rotation();
});
onMounted(() => {

View File

@ -27,12 +27,14 @@ import { DropdownOption, NDropdown, useDialog, useMessage } from "naive-ui";
import { onBeforeRouteLeave } from "vue-router";
import { useKeyboardStore } from "../../store/keyboard";
import { useI18n } from "vue-i18n";
import { useRotation } from "../../tools/hooks";
const { t } = useI18n();
const store = useGlobalStore();
const keyboardStore = useKeyboardStore();
const dialog = useDialog();
const message = useMessage();
const rotation = useRotation();
const curPageActive = ref(false);
const addButtonPos = ref({ x: 0, y: 0 });
@ -300,6 +302,7 @@ onActivated(() => {
document.addEventListener("keydown", handleKeyDown);
document.addEventListener("keyup", handleKeyUp);
document.addEventListener("wheel", handleMouseWheel);
rotation();
});
onBeforeRouteLeave(() => {

View File

@ -6,9 +6,16 @@ import About from "./About.vue";
import { NTabs, NTabPane, NSpin } from "naive-ui";
import { useGlobalStore } from "../../store/global";
import SettingTab from "./SettingTab.vue";
import { useHorRotation } from "../../tools/hooks";
import { onActivated } from "vue";
// TODO Switch back to landscape size when entering Settings and Devices screen
const store = useGlobalStore();
const horRotation = useHorRotation();
onActivated(() => {
horRotation();
});
</script>
<template>

View File

@ -38,7 +38,7 @@
"adbConnectError": "Wireless connection failed",
"rotation": "Device rotation {0}°",
"btnShutdown": "Shutdown control",
"btnRefresh": "Refresh",
"btnRefresh": "Refresh devices list",
"btnReStart": "Restart ADB",
"adbRestartError": "ADB Restart Failed",
"adbUnavailable": "ADB Unavailable"

View File

@ -38,8 +38,8 @@
"adbConnectError": "无线连接失败",
"rotation": "设备旋转 {0}°",
"btnShutdown": "关闭控制",
"btnRefresh": "刷新",
"btnReStart": "重启ABD",
"btnRefresh": "刷新设备列表",
"btnReStart": "重启ADB",
"adbRestartError": "ADB 重启失败",
"adbUnavailable": "ADB 不可用"
},

View File

@ -5,6 +5,11 @@ interface MemType {
screenStreamClientId: string;
keyInputFlag: boolean;
adbUnavailableMsgIns: MessageReactive | null;
rotationState: {
direction: "horizontal" | "vertical";
maskW: number;
maskH: number;
};
}
interface LocalType {
@ -22,6 +27,11 @@ export class NonReactiveStore {
screenStreamClientId: "",
keyInputFlag: false,
adbUnavailableMsgIns: null,
rotationState: {
direction: "horizontal",
maskW: 0,
maskH: 0,
},
};
static local: LocalType = {

View File

@ -6,6 +6,8 @@ import { fetch } from "@tauri-apps/plugin-http";
import { compareVersion } from "./tools";
import { checkAdbAvailable } from "./invoke";
import { NonReactiveStore } from "../store/noneReactiveStore";
import { getCurrentWindow, LogicalSize } from "@tauri-apps/api/window";
import { useGlobalStore } from "../store/global";
// TODO use markdown to render update info
@ -77,3 +79,38 @@ export function useCheckAdb() {
}
};
}
export function useRotation() {
const appWindow = getCurrentWindow();
const store = useGlobalStore();
return async () => {
if (store.controledDevice === null || !store.rotation.enable) return;
const rotationState = NonReactiveStore.mem.rotationState;
if (
store.curMaskSize.w !== rotationState.maskW ||
store.curMaskSize.h !== rotationState.maskH
) {
await appWindow.setSize(
new LogicalSize(rotationState.maskW + 70, rotationState.maskH + 30)
);
}
};
}
export function useHorRotation() {
const appWindow = getCurrentWindow();
const store = useGlobalStore();
return async () => {
if (store.controledDevice === null || !store.rotation.enable) return;
const scale =
store.screenSizeW >= store.screenSizeH
? store.screenSizeH / store.screenSizeW
: store.screenSizeW / store.screenSizeH;
const maskW = Math.round(store.rotation.horizontalLength);
const maskH = Math.round(maskW * scale);
if (store.curMaskSize.w !== maskW || store.curMaskSize.h !== maskH) {
await appWindow.setSize(new LogicalSize(maskW + 70, maskH + 30));
}
};
}