feat: 分发包改为字节码,并补上 MuMu 探测和下载列表滚动
This commit is contained in:
+40
-6
@@ -470,6 +470,15 @@ function deviceLabel(item: Device) {
|
||||
return `${item.model} · ${item.serial} · ${mark}`;
|
||||
}
|
||||
|
||||
function applyDeviceList(list: Device[]) {
|
||||
devices.value = list;
|
||||
const stillThere = devices.value.some((item) => item.serial === serial.value && item.state === "device");
|
||||
if (!stillThere) {
|
||||
const ready = devices.value.filter((item) => item.state === "device");
|
||||
serial.value = ready.length === 1 ? ready[0].serial : null;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadDevices() {
|
||||
error.value = "";
|
||||
devicesBusy.value = true;
|
||||
@@ -479,12 +488,7 @@ async function loadDevices() {
|
||||
if (!response.ok) {
|
||||
throw new Error(payload.detail || "读取设备失败");
|
||||
}
|
||||
devices.value = payload.devices || [];
|
||||
const stillThere = devices.value.some((item) => item.serial === serial.value && item.state === "device");
|
||||
if (!stillThere) {
|
||||
const ready = devices.value.filter((item) => item.state === "device");
|
||||
serial.value = ready.length === 1 ? ready[0].serial : null;
|
||||
}
|
||||
applyDeviceList(payload.devices || []);
|
||||
} catch (exc) {
|
||||
devices.value = [];
|
||||
serial.value = null;
|
||||
@@ -494,6 +498,29 @@ async function loadDevices() {
|
||||
}
|
||||
}
|
||||
|
||||
async function probeMumu() {
|
||||
error.value = "";
|
||||
devicesBusy.value = true;
|
||||
try {
|
||||
const response = await fetch("/api/adb/probe-mumu", { method: "POST" });
|
||||
const payload = await response.json();
|
||||
if (!response.ok) {
|
||||
throw new Error(payload.detail || "没有连上 MuMu");
|
||||
}
|
||||
applyDeviceList(payload.devices || []);
|
||||
const ready = devices.value.filter((item) => item.state === "device");
|
||||
if (!ready.length) {
|
||||
const ports = Array.isArray(payload.ports) ? payload.ports.join("、") : "";
|
||||
throw new Error(ports ? `已尝试连接 MuMu 端口 ${ports},但设备还不可用。请在模拟器里允许调试后再探测。` : "没有连上 MuMu");
|
||||
}
|
||||
} catch (exc) {
|
||||
if (!devices.value.length) serial.value = null;
|
||||
error.value = exc instanceof Error ? exc.message : "没有连上 MuMu";
|
||||
} finally {
|
||||
devicesBusy.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
watch(method, (value) => {
|
||||
error.value = "";
|
||||
if (value === "adb") loadDevices();
|
||||
@@ -854,6 +881,7 @@ onUnmounted(stopLive);
|
||||
placeholder="请选择设备"
|
||||
/>
|
||||
<n-button :loading="devicesBusy" @click="loadDevices">刷新</n-button>
|
||||
<n-button :loading="devicesBusy" @click="probeMumu">探测 MuMu</n-button>
|
||||
</div>
|
||||
</n-form-item>
|
||||
<n-text v-if="method === 'guest'" class="hint" depth="3">将注册一个新的游客账号,并读取它的个人信息。</n-text>
|
||||
@@ -943,6 +971,12 @@ html { color-scheme: dark; }
|
||||
.shell .main-pane .n-layout-content > .n-layout-scroll-container {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.shell .main-pane .n-layout-content > .n-layout-scroll-container > * {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
}
|
||||
.sider { height: 100%; min-height: 100%; display: flex; flex-direction: column; box-sizing: border-box; padding: 12px 8px; }
|
||||
.user-nav {
|
||||
|
||||
@@ -70,9 +70,10 @@ async function remove(id: string) {
|
||||
{{ resumeAll ? "继续" : "暂停" }}
|
||||
</n-button>
|
||||
</template>
|
||||
<n-tab-pane name="active" :tab="`正在下载${props.active.length ? ` ${props.active.length}` : ''}`">
|
||||
<div v-if="!props.active.length" class="progress-empty">没有正在下载的剧</div>
|
||||
<article v-for="job in props.active" :key="job.id" class="job">
|
||||
<n-tab-pane name="active" :tab="`正在下载${props.active.length ? ` ${props.active.length}` : ''}`" display-directive="show">
|
||||
<div class="job-scroll">
|
||||
<div v-if="!props.active.length" class="progress-empty">没有正在下载的剧</div>
|
||||
<article v-for="job in props.active" :key="job.id" class="job">
|
||||
<img v-if="coverOf(job.image)" class="job-cover" :src="coverOf(job.image)" alt="" />
|
||||
<div v-else class="job-cover"></div>
|
||||
<div class="job-main">
|
||||
@@ -115,10 +116,12 @@ async function remove(id: string) {
|
||||
</n-tooltip>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="done" tab="已完成">
|
||||
<div v-if="!props.done.length" class="progress-empty">还没有完成的下载</div>
|
||||
<article v-for="job in props.done" :key="job.id" class="job">
|
||||
<n-tab-pane name="done" tab="已完成" display-directive="show">
|
||||
<div class="job-scroll">
|
||||
<div v-if="!props.done.length" class="progress-empty">还没有完成的下载</div>
|
||||
<article v-for="job in props.done" :key="job.id" class="job">
|
||||
<img v-if="coverOf(job.image)" class="job-cover" :src="coverOf(job.image)" alt="" />
|
||||
<div v-else class="job-cover"></div>
|
||||
<div class="job-main">
|
||||
@@ -147,15 +150,34 @@ async function remove(id: string) {
|
||||
</n-tooltip>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</n-tab-pane>
|
||||
</n-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.progress-page { height: 100%; min-height: 0; display: flex; flex-direction: column; overflow: hidden; box-sizing: border-box; padding: 8px 20px 20px; }
|
||||
.progress-page > .n-tabs { flex: 1; min-height: 0; display: flex; flex-direction: column; }
|
||||
.progress-page .n-tabs-pane-wrapper { flex: 1; min-height: 0; overflow: auto; }
|
||||
.progress-page { height: 100%; min-height: 0; display: flex; flex-direction: column; overflow: hidden; box-sizing: border-box; padding: 8px 20px 16px; }
|
||||
.progress-page > .n-tabs { flex: 1; min-height: 0; height: 100%; display: flex; flex-direction: column; overflow: hidden; }
|
||||
.progress-page .n-tabs-nav { flex: none; }
|
||||
.progress-page .n-tabs-pane-wrapper {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.progress-page .n-tab-pane {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.job-scroll { flex: 1; min-height: 0; overflow: auto; }
|
||||
.bulk-hold { margin-left: 12px; }
|
||||
.progress-empty { padding: 28px 0; color: rgba(255, 255, 255, 0.45); }
|
||||
.job {
|
||||
|
||||
Reference in New Issue
Block a user