mirror of
https://github.com/yume-chan/ya-webadb.git
synced 2025-10-06 03:50:18 +02:00
feat: add back install apk page
This commit is contained in:
parent
ab32a8ee87
commit
20b914fe6f
10 changed files with 192 additions and 69 deletions
|
@ -4,7 +4,7 @@ import AdbWebUsbBackend, { AdbWebCredentialStore, AdbWebUsbBackendWatcher } from
|
|||
import AdbWsBackend from '@yume-chan/adb-backend-ws';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
||||
import { device, logger } from '../state';
|
||||
import { global, logger } from '../state';
|
||||
import { CommonStackTokens } from '../utils';
|
||||
import { ErrorDialogContext } from './error-dialog';
|
||||
|
||||
|
@ -58,7 +58,7 @@ function _Connect(): JSX.Element | null {
|
|||
const [wsBackendList, setWsBackendList] = useState<AdbBackend[]>([]);
|
||||
useEffect(() => {
|
||||
const intervalId = setInterval(async () => {
|
||||
if (connecting || device.current) {
|
||||
if (connecting || global.device) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ function _Connect(): JSX.Element | null {
|
|||
try {
|
||||
setConnecting(true);
|
||||
await adb.connect(CredentialStore);
|
||||
device.setCurrent(adb);
|
||||
global.setCurrent(adb);
|
||||
} catch (e) {
|
||||
adb.dispose();
|
||||
throw e;
|
||||
|
@ -113,8 +113,8 @@ function _Connect(): JSX.Element | null {
|
|||
}, [showErrorDialog, selectedBackend]);
|
||||
const disconnect = useCallback(async () => {
|
||||
try {
|
||||
await device.current!.dispose();
|
||||
device.setCurrent(undefined);
|
||||
await global.device!.dispose();
|
||||
global.setCurrent(undefined);
|
||||
} catch (e: any) {
|
||||
showErrorDialog(e.message);
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ function _Connect(): JSX.Element | null {
|
|||
tokens={{ childrenGap: 8, padding: '0 0 8px 8px' }}
|
||||
>
|
||||
<Dropdown
|
||||
disabled={!!device.current || backendOptions.length === 0}
|
||||
disabled={!!global.device || backendOptions.length === 0}
|
||||
label="Available devices"
|
||||
placeholder="No available devices"
|
||||
options={backendOptions}
|
||||
|
@ -161,7 +161,7 @@ function _Connect(): JSX.Element | null {
|
|||
onChange={handleSelectedBackendChange}
|
||||
/>
|
||||
|
||||
{!device.current ? (
|
||||
{!global.device ? (
|
||||
<Stack horizontal tokens={CommonStackTokens}>
|
||||
<StackItem grow shrink>
|
||||
<PrimaryButton
|
||||
|
|
|
@ -3,7 +3,7 @@ import { AdbDemoModeMobileDataType, AdbDemoModeMobileDataTypes, AdbDemoModeSigna
|
|||
import { autorun, makeAutoObservable, reaction, runInAction } from "mobx";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { CSSProperties, useCallback } from 'react';
|
||||
import { device } from "../state";
|
||||
import { global } from "../state";
|
||||
|
||||
const SignalStrengthOptions =
|
||||
Object.values(AdbDemoModeSignalStrength)
|
||||
|
@ -65,7 +65,7 @@ class DemoModeState {
|
|||
makeAutoObservable(this);
|
||||
|
||||
reaction(
|
||||
() => device.current,
|
||||
() => global.device,
|
||||
async (device) => {
|
||||
if (device) {
|
||||
const allowed = await device.demoMode.getAllowed();
|
||||
|
@ -120,21 +120,21 @@ const FEATURES: FeatureDefinition[][] = [
|
|||
max: 100,
|
||||
step: 1,
|
||||
initial: 100,
|
||||
onChange: (value) => device.current!.demoMode.setBatteryLevel(value as number),
|
||||
onChange: (value) => global.device!.demoMode.setBatteryLevel(value as number),
|
||||
},
|
||||
{
|
||||
key: 'batteryCharging',
|
||||
label: 'Battery Charging',
|
||||
type: 'boolean',
|
||||
initial: false,
|
||||
onChange: (value) => device.current!.demoMode.setBatteryCharging(value as boolean),
|
||||
onChange: (value) => global.device!.demoMode.setBatteryCharging(value as boolean),
|
||||
},
|
||||
{
|
||||
key: 'powerSaveMode',
|
||||
label: 'Power Save Mode',
|
||||
type: 'boolean',
|
||||
initial: false,
|
||||
onChange: (value) => device.current!.demoMode.setPowerSaveMode(value as boolean),
|
||||
onChange: (value) => global.device!.demoMode.setPowerSaveMode(value as boolean),
|
||||
},
|
||||
],
|
||||
[
|
||||
|
@ -144,14 +144,14 @@ const FEATURES: FeatureDefinition[][] = [
|
|||
type: 'select',
|
||||
options: SignalStrengthOptions,
|
||||
initial: AdbDemoModeSignalStrength.Level4,
|
||||
onChange: (value) => device.current!.demoMode.setWifiSignalStrength(value as AdbDemoModeSignalStrength),
|
||||
onChange: (value) => global.device!.demoMode.setWifiSignalStrength(value as AdbDemoModeSignalStrength),
|
||||
},
|
||||
{
|
||||
key: 'airplaneMode',
|
||||
label: 'Airplane Mode',
|
||||
type: 'boolean',
|
||||
initial: false,
|
||||
onChange: (value) => device.current!.demoMode.setAirplaneMode(value as boolean),
|
||||
onChange: (value) => global.device!.demoMode.setAirplaneMode(value as boolean),
|
||||
},
|
||||
{
|
||||
key: 'mobileDataType',
|
||||
|
@ -159,7 +159,7 @@ const FEATURES: FeatureDefinition[][] = [
|
|||
type: 'select',
|
||||
options: MobileDataTypeOptions,
|
||||
initial: 'lte',
|
||||
onChange: (value) => device.current!.demoMode.setMobileDataType(value as AdbDemoModeMobileDataType),
|
||||
onChange: (value) => global.device!.demoMode.setMobileDataType(value as AdbDemoModeMobileDataType),
|
||||
},
|
||||
{
|
||||
key: 'mobileSignalStrength',
|
||||
|
@ -167,7 +167,7 @@ const FEATURES: FeatureDefinition[][] = [
|
|||
type: 'select',
|
||||
options: SignalStrengthOptions,
|
||||
initial: AdbDemoModeSignalStrength.Level4,
|
||||
onChange: (value) => device.current!.demoMode.setMobileSignalStrength(value as AdbDemoModeSignalStrength),
|
||||
onChange: (value) => global.device!.demoMode.setMobileSignalStrength(value as AdbDemoModeSignalStrength),
|
||||
},
|
||||
],
|
||||
[
|
||||
|
@ -177,42 +177,42 @@ const FEATURES: FeatureDefinition[][] = [
|
|||
type: 'select',
|
||||
options: StatusBarModeOptions,
|
||||
initial: 'transparent',
|
||||
onChange: (value) => device.current!.demoMode.setStatusBarMode(value as AdbDemoModeStatusBarMode),
|
||||
onChange: (value) => global.device!.demoMode.setStatusBarMode(value as AdbDemoModeStatusBarMode),
|
||||
},
|
||||
{
|
||||
key: 'vibrateMode',
|
||||
label: 'Vibrate Mode Indicator',
|
||||
type: 'boolean',
|
||||
initial: false,
|
||||
onChange: (value) => device.current!.demoMode.setVibrateModeEnabled(value as boolean),
|
||||
onChange: (value) => global.device!.demoMode.setVibrateModeEnabled(value as boolean),
|
||||
},
|
||||
{
|
||||
key: 'bluetoothConnected',
|
||||
label: 'Bluetooth Indicator',
|
||||
type: 'boolean',
|
||||
initial: false,
|
||||
onChange: (value) => device.current!.demoMode.setBluetoothConnected(value as boolean),
|
||||
onChange: (value) => global.device!.demoMode.setBluetoothConnected(value as boolean),
|
||||
},
|
||||
{
|
||||
key: 'locatingIcon',
|
||||
label: 'Locating Icon',
|
||||
type: 'boolean',
|
||||
initial: false,
|
||||
onChange: (value) => device.current!.demoMode.setLocatingIcon(value as boolean),
|
||||
onChange: (value) => global.device!.demoMode.setLocatingIcon(value as boolean),
|
||||
},
|
||||
{
|
||||
key: 'alarmIcon',
|
||||
label: 'Alarm Icon',
|
||||
type: 'boolean',
|
||||
initial: false,
|
||||
onChange: (value) => device.current!.demoMode.setAlarmIcon(value as boolean),
|
||||
onChange: (value) => global.device!.demoMode.setAlarmIcon(value as boolean),
|
||||
},
|
||||
{
|
||||
key: 'notificationsVisibility',
|
||||
label: 'Notifications Visibility',
|
||||
type: 'boolean',
|
||||
initial: true,
|
||||
onChange: (value) => device.current!.demoMode.setNotificationsVisibility(value as boolean),
|
||||
onChange: (value) => global.device!.demoMode.setNotificationsVisibility(value as boolean),
|
||||
},
|
||||
{
|
||||
key: 'hour',
|
||||
|
@ -222,7 +222,7 @@ const FEATURES: FeatureDefinition[][] = [
|
|||
max: 23,
|
||||
step: 1,
|
||||
initial: 12,
|
||||
onChange: (value) => device.current!.demoMode.setTime(value as number, state.features.get('minute') as number | undefined ?? 34)
|
||||
onChange: (value) => global.device!.demoMode.setTime(value as number, state.features.get('minute') as number | undefined ?? 34)
|
||||
},
|
||||
{
|
||||
key: 'minute',
|
||||
|
@ -232,7 +232,7 @@ const FEATURES: FeatureDefinition[][] = [
|
|||
max: 59,
|
||||
step: 1,
|
||||
initial: 34,
|
||||
onChange: (value) => device.current!.demoMode.setTime(state.features.get('hour') as number | undefined ?? 34, value as number)
|
||||
onChange: (value) => global.device!.demoMode.setTime(state.features.get('hour') as number | undefined ?? 34, value as number)
|
||||
},
|
||||
],
|
||||
];
|
||||
|
@ -306,7 +306,7 @@ const DemoModeBase = ({
|
|||
style,
|
||||
}: DemoModeProps) => {
|
||||
const handleAllowedChange = useCallback(async (e, value?: boolean) => {
|
||||
await device.current!.demoMode.setAllowed(value!);
|
||||
await global.device!.demoMode.setAllowed(value!);
|
||||
runInAction(() => {
|
||||
state.allowed = value!;
|
||||
state.enabled = false;
|
||||
|
@ -314,7 +314,7 @@ const DemoModeBase = ({
|
|||
}, []);
|
||||
|
||||
const handleEnabledChange = useCallback(async (e, value?: boolean) => {
|
||||
await device.current!.demoMode.setEnabled(value!);
|
||||
await global.device!.demoMode.setEnabled(value!);
|
||||
runInAction(() => state.enabled = value!);
|
||||
}, []);
|
||||
|
||||
|
@ -322,7 +322,7 @@ const DemoModeBase = ({
|
|||
<div style={{ padding: 12, overflow: 'hidden auto', ...style }}>
|
||||
<Toggle
|
||||
label="Allowed"
|
||||
disabled={!device.current}
|
||||
disabled={!global.device}
|
||||
checked={state.allowed}
|
||||
onChange={handleAllowedChange}
|
||||
/>
|
||||
|
|
|
@ -5,7 +5,7 @@ import type { NextPage } from 'next';
|
|||
import Head from 'next/head';
|
||||
import React from "react";
|
||||
import { ExternalLink } from "../components";
|
||||
import { device } from '../state';
|
||||
import { global } from '../state';
|
||||
import { RouteStackProps } from "../utils";
|
||||
|
||||
const KNOWN_FEATURES: Record<string, string> = {
|
||||
|
@ -52,7 +52,7 @@ const DeviceInfo: NextPage = () => {
|
|||
</MessageBar>
|
||||
<span>
|
||||
<span>Protocol Version: </span>
|
||||
<code>{device.current?.protocolVersion?.toString(16).padStart(8, '0')}</code>
|
||||
<code>{global.device?.protocolVersion?.toString(16).padStart(8, '0')}</code>
|
||||
</span>
|
||||
<Separator />
|
||||
|
||||
|
@ -60,21 +60,21 @@ const DeviceInfo: NextPage = () => {
|
|||
<code>ro.product.name</code>
|
||||
<span> field in Android Build Props</span>
|
||||
</MessageBar>
|
||||
<span>Product Name: {device.current?.product}</span>
|
||||
<span>Product Name: {global.device?.product}</span>
|
||||
<Separator />
|
||||
|
||||
<MessageBar>
|
||||
<code>ro.product.model</code>
|
||||
<span> field in Android Build Props</span>
|
||||
</MessageBar>
|
||||
<span>Model Name: {device.current?.model}</span>
|
||||
<span>Model Name: {global.device?.model}</span>
|
||||
<Separator />
|
||||
|
||||
<MessageBar>
|
||||
<code>ro.product.device</code>
|
||||
<span> field in Android Build Props</span>
|
||||
</MessageBar>
|
||||
<span>Device Name: {device.current?.device}</span>
|
||||
<span>Device Name: {global.device?.device}</span>
|
||||
<Separator />
|
||||
|
||||
<MessageBar>
|
||||
|
@ -87,7 +87,7 @@ const DeviceInfo: NextPage = () => {
|
|||
</MessageBar>
|
||||
<span>
|
||||
<span>Features: </span>
|
||||
{device.current?.features?.map((feature, index) => (
|
||||
{global.device?.features?.map((feature, index) => (
|
||||
<span key={feature}>
|
||||
{index !== 0 && (<span>, </span>)}
|
||||
<span>{feature}</span>
|
||||
|
|
|
@ -10,7 +10,7 @@ import Router, { useRouter } from "next/router";
|
|||
import path from 'path';
|
||||
import React, { useCallback, useContext, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import { CommandBar, ErrorDialogContext } from '../components';
|
||||
import { device } from '../state';
|
||||
import { global } from '../state';
|
||||
import { asyncEffect, chunkFile, formatSize, formatSpeed, pickFile, RouteStackProps, useSpeed } from '../utils';
|
||||
|
||||
let StreamSaver: typeof import('streamsaver');
|
||||
|
@ -96,7 +96,7 @@ class FileManagerState {
|
|||
items: observable.shallow,
|
||||
});
|
||||
reaction(
|
||||
() => device.current,
|
||||
() => global.device,
|
||||
() => this.loadFiles(),
|
||||
{ fireImmediately: true },
|
||||
);
|
||||
|
@ -264,13 +264,13 @@ class FileManagerState {
|
|||
|
||||
runInAction(() => this.items = []);
|
||||
|
||||
if (!device.current) {
|
||||
if (!global.device) {
|
||||
return;
|
||||
}
|
||||
|
||||
runInAction(() => this.loading = true);
|
||||
|
||||
const sync = await device.current.sync();
|
||||
const sync = await global.device.sync();
|
||||
|
||||
const items: ListItem[] = [];
|
||||
const linkItems: AdbSyncEntryResponse[] = [];
|
||||
|
@ -365,7 +365,7 @@ const FileManager: NextPage = (): JSX.Element | null => {
|
|||
|
||||
const [previewUrl, setPreviewUrl] = useState<string | undefined>();
|
||||
const previewImage = useCallback(async (path: string) => {
|
||||
const sync = await device.current!.sync();
|
||||
const sync = await global.device!.sync();
|
||||
try {
|
||||
const readableStream = createReadableStreamFromBufferIterator(sync.read(path));
|
||||
const response = new Response(readableStream);
|
||||
|
@ -413,7 +413,7 @@ const FileManager: NextPage = (): JSX.Element | null => {
|
|||
const [uploadTotalSize, setUploadTotalSize] = useState(0);
|
||||
const [debouncedUploadedSize, uploadSpeed] = useSpeed(uploadedSize, uploadTotalSize);
|
||||
const upload = useCallback(async (file: File) => {
|
||||
const sync = await device.current!.sync();
|
||||
const sync = await global.device!.sync();
|
||||
try {
|
||||
const itemPath = path.resolve(state.path!, file.name);
|
||||
setUploading(true);
|
||||
|
@ -445,7 +445,7 @@ const FileManager: NextPage = (): JSX.Element | null => {
|
|||
key: 'upload',
|
||||
text: 'Upload',
|
||||
iconProps: { iconName: 'Upload' },
|
||||
disabled: !device.current,
|
||||
disabled: !global.device,
|
||||
onClick() {
|
||||
(async () => {
|
||||
const files = await pickFile({ multiple: true });
|
||||
|
@ -467,7 +467,7 @@ const FileManager: NextPage = (): JSX.Element | null => {
|
|||
iconProps: { iconName: 'Download' },
|
||||
onClick() {
|
||||
(async () => {
|
||||
const sync = await device.current!.sync();
|
||||
const sync = await global.device!.sync();
|
||||
try {
|
||||
const itemPath = path.resolve(state.path, selectedItems[0].name!);
|
||||
const readableStream = createReadableStreamFromBufferIterator(sync.read(itemPath));
|
||||
|
@ -495,7 +495,7 @@ const FileManager: NextPage = (): JSX.Element | null => {
|
|||
(async () => {
|
||||
try {
|
||||
for (const item of selectedItems) {
|
||||
const output = await device.current!.rm(path.resolve(state.path, item.name!));
|
||||
const output = await global.device!.rm(path.resolve(state.path, item.name!));
|
||||
if (output) {
|
||||
showErrorDialog(output);
|
||||
return;
|
||||
|
|
|
@ -6,7 +6,7 @@ import { NextPage } from "next";
|
|||
import Head from "next/head";
|
||||
import React, { useCallback, useContext, useEffect, useRef } from 'react';
|
||||
import { CommandBar, DemoMode, DeviceView, ErrorDialogContext } from '../components';
|
||||
import { device } from "../state";
|
||||
import { global } from "../state";
|
||||
import { RouteStackProps } from "../utils";
|
||||
|
||||
class FrameBufferState {
|
||||
|
@ -38,13 +38,13 @@ const FrameBuffer: NextPage = (): JSX.Element | null => {
|
|||
const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
||||
|
||||
const capture = useCallback(async () => {
|
||||
if (!device.current) {
|
||||
if (!global.device) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const start = window.performance.now();
|
||||
const framebuffer = await device.current.framebuffer();
|
||||
const framebuffer = await global.device.framebuffer();
|
||||
const end = window.performance.now();
|
||||
console.log('time', end - start);
|
||||
state.setImage(framebuffer);
|
||||
|
@ -68,7 +68,7 @@ const FrameBuffer: NextPage = (): JSX.Element | null => {
|
|||
const commandBarItems = computed(() => [
|
||||
{
|
||||
key: 'start',
|
||||
disabled: !device.current,
|
||||
disabled: !global.device,
|
||||
iconProps: { iconName: 'Camera' },
|
||||
text: 'Capture',
|
||||
onClick: capture,
|
||||
|
@ -87,7 +87,7 @@ const FrameBuffer: NextPage = (): JSX.Element | null => {
|
|||
const url = canvas.toDataURL();
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `Screenshot of ${device.current!.name}.png`;
|
||||
a.download = `Screenshot of ${global.device!.name}.png`;
|
||||
a.click();
|
||||
},
|
||||
},
|
||||
|
|
123
apps/demo/pages/install.tsx
Normal file
123
apps/demo/pages/install.tsx
Normal file
|
@ -0,0 +1,123 @@
|
|||
import { DefaultButton, ProgressIndicator, Stack } from "@fluentui/react";
|
||||
import { AdbSyncMaxPacketSize } from "@yume-chan/adb";
|
||||
import { makeAutoObservable, observable, runInAction } from "mobx";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import React from "react";
|
||||
import { global } from "../state";
|
||||
import { chunkFile, pickFile, RouteStackProps } from "../utils";
|
||||
|
||||
enum Stage {
|
||||
Uploading,
|
||||
|
||||
Installing,
|
||||
|
||||
Completed,
|
||||
}
|
||||
|
||||
interface Progress {
|
||||
filename: string;
|
||||
|
||||
stage: Stage;
|
||||
|
||||
uploadedSize: number;
|
||||
|
||||
totalSize: number;
|
||||
|
||||
value: number | undefined;
|
||||
}
|
||||
|
||||
class InstallPageState {
|
||||
installing = false;
|
||||
|
||||
progress: Progress | undefined;
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this, {
|
||||
progress: observable.ref,
|
||||
});
|
||||
}
|
||||
|
||||
async install() {
|
||||
const file = await pickFile({ accept: '.apk' });
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
runInAction(() => {
|
||||
this.installing = true;
|
||||
this.progress = {
|
||||
filename: file.name,
|
||||
stage: Stage.Uploading,
|
||||
uploadedSize: 0,
|
||||
totalSize: file.size,
|
||||
value: 0,
|
||||
};
|
||||
});
|
||||
|
||||
await global.device!.install(chunkFile(file, AdbSyncMaxPacketSize), uploaded => {
|
||||
runInAction(() => {
|
||||
if (uploaded !== file.size) {
|
||||
this.progress = {
|
||||
filename: file.name,
|
||||
stage: Stage.Uploading,
|
||||
uploadedSize: uploaded,
|
||||
totalSize: file.size,
|
||||
value: uploaded / file.size * 0.8,
|
||||
};
|
||||
} else {
|
||||
this.progress = {
|
||||
filename: file.name,
|
||||
stage: Stage.Installing,
|
||||
uploadedSize: uploaded,
|
||||
totalSize: file.size,
|
||||
value: 0.8,
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
this.progress = {
|
||||
filename: file.name,
|
||||
stage: Stage.Completed,
|
||||
uploadedSize: file.size,
|
||||
totalSize: file.size,
|
||||
value: 1,
|
||||
};
|
||||
this.installing = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const state = new InstallPageState();
|
||||
|
||||
const Install: NextPage = () => {
|
||||
return (
|
||||
<Stack {...RouteStackProps}>
|
||||
<Head>
|
||||
<title>Install APK - WebADB</title>
|
||||
</Head>
|
||||
|
||||
<Stack horizontal>
|
||||
<DefaultButton
|
||||
disabled={!global.device || state.installing}
|
||||
text="Open"
|
||||
onClick={() => state.install()}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
{state.progress && (
|
||||
<ProgressIndicator
|
||||
styles={{ root: { width: 300 } }}
|
||||
label={state.progress.filename}
|
||||
percentComplete={state.progress.value}
|
||||
description={Stage[state.progress.stage]}
|
||||
/>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
export default observer(Install);
|
|
@ -6,7 +6,7 @@ import Head from "next/head";
|
|||
import React, { CSSProperties, useCallback, useContext, useEffect, useRef, useState } from 'react';
|
||||
import 'xterm/css/xterm.css';
|
||||
import { ErrorDialogContext } from '../components/error-dialog';
|
||||
import { device } from "../state";
|
||||
import { global } from "../state";
|
||||
import { ResizeObserver, RouteStackProps } from '../utils';
|
||||
|
||||
let terminal: import('../components/terminal').AdbTerminal;
|
||||
|
@ -43,9 +43,9 @@ const Shell: NextPage = (): JSX.Element | null => {
|
|||
const connectingRef = useRef(false);
|
||||
useEffect(() => {
|
||||
return reaction(
|
||||
() => device.current,
|
||||
() => global.device,
|
||||
async () => {
|
||||
if (!device.current) {
|
||||
if (!global.device) {
|
||||
terminal.socket = undefined;
|
||||
return;
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ const Shell: NextPage = (): JSX.Element | null => {
|
|||
|
||||
try {
|
||||
connectingRef.current = true;
|
||||
const socket = await device.current.childProcess.shell();
|
||||
const socket = await global.device.childProcess.shell();
|
||||
terminal.socket = socket;
|
||||
} catch (e) {
|
||||
showErrorDialog(e instanceof Error ? e.message : `${e}`);
|
||||
|
|
|
@ -5,7 +5,7 @@ import { NextPage } from "next";
|
|||
import Head from "next/head";
|
||||
import React, { useCallback } from "react";
|
||||
import { ExternalLink } from "../components";
|
||||
import { device } from "../state";
|
||||
import { global } from "../state";
|
||||
import { asyncEffect, RouteStackProps } from "../utils";
|
||||
|
||||
class TcpIpState {
|
||||
|
@ -18,7 +18,7 @@ class TcpIpState {
|
|||
constructor() {
|
||||
makeAutoObservable(this);
|
||||
reaction(
|
||||
() => device.current,
|
||||
() => global.device,
|
||||
() => this.queryInfo(),
|
||||
{ fireImmediately: true }
|
||||
);
|
||||
|
@ -28,14 +28,14 @@ class TcpIpState {
|
|||
return [
|
||||
{
|
||||
key: 'refresh',
|
||||
disabled: !device.current,
|
||||
disabled: !global.device,
|
||||
iconProps: { iconName: 'Refresh' },
|
||||
text: 'Refresh',
|
||||
onClick: () => { this.queryInfo(); },
|
||||
},
|
||||
{
|
||||
key: 'apply',
|
||||
disabled: !device.current,
|
||||
disabled: !global.device,
|
||||
iconProps: { iconName: 'Save' },
|
||||
text: 'Apply',
|
||||
onClick: () => { this.applyServicePort(); },
|
||||
|
@ -44,7 +44,7 @@ class TcpIpState {
|
|||
}
|
||||
|
||||
queryInfo = asyncEffect(async (signal) => {
|
||||
if (!device.current) {
|
||||
if (!global.device) {
|
||||
runInAction(() => {
|
||||
this.serviceListenAddresses = undefined;
|
||||
this.servicePortEnabled = false;
|
||||
|
@ -55,9 +55,9 @@ class TcpIpState {
|
|||
return;
|
||||
}
|
||||
|
||||
const serviceListenAddresses = await device.current.getProp('service.adb.listen_addrs');
|
||||
const servicePort = await device.current.getProp('service.adb.tcp.port');
|
||||
const persistPort = await device.current.getProp('persist.adb.tcp.port');
|
||||
const serviceListenAddresses = await global.device.getProp('service.adb.listen_addrs');
|
||||
const servicePort = await global.device.getProp('service.adb.tcp.port');
|
||||
const persistPort = await global.device.getProp('persist.adb.tcp.port');
|
||||
|
||||
if (signal.aborted) {
|
||||
return;
|
||||
|
@ -85,14 +85,14 @@ class TcpIpState {
|
|||
});
|
||||
|
||||
async applyServicePort() {
|
||||
if (!device.current) {
|
||||
if (!global.device) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.servicePortEnabled) {
|
||||
await device.current.tcpip.setPort(Number.parseInt(state.servicePort, 10));
|
||||
await global.device.tcpip.setPort(Number.parseInt(state.servicePort, 10));
|
||||
} else {
|
||||
await device.current.tcpip.disable();
|
||||
await global.device.tcpip.disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -158,12 +158,12 @@ const TcpIp: NextPage = () => {
|
|||
inlineLabel
|
||||
label="service.adb.tcp.port"
|
||||
checked={state.servicePortEnabled}
|
||||
disabled={!device.current || !!state.serviceListenAddresses}
|
||||
disabled={!global.device || !!state.serviceListenAddresses}
|
||||
onText="Enabled"
|
||||
offText="Disabled"
|
||||
onChange={handleServicePortEnabledChange}
|
||||
/>
|
||||
{device && (
|
||||
{global && (
|
||||
<TextField
|
||||
disabled={!!state.serviceListenAddresses}
|
||||
value={state.servicePort}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import { Adb } from "@yume-chan/adb";
|
||||
import { makeAutoObservable } from 'mobx';
|
||||
|
||||
export class Device {
|
||||
current: Adb | undefined;
|
||||
export class GlobalState {
|
||||
device: Adb | undefined;
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
setCurrent(device: Adb | undefined) {
|
||||
this.current = device;
|
||||
this.device = device;
|
||||
device?.onDisconnected(() => {
|
||||
this.setCurrent(undefined);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const device = new Device();
|
||||
export const global = new GlobalState();
|
|
@ -1,2 +1,2 @@
|
|||
export * from './device';
|
||||
export * from './global';
|
||||
export * from './logger';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue