安卓平台下添加APP下载提示

安卓APP添加版本更新提示
修复所有对话框loading状态下还能被关闭的BUG
This commit is contained in:
fangxiang 2022-09-02 11:14:55 +08:00
parent 566110eaea
commit 9d81132329
34 changed files with 315 additions and 19 deletions

View File

@ -1,6 +1,6 @@
{
"name": "media_player_client",
"version": "1.5.2",
"version": "1.5.3",
"description": "A Quasar Framework app",
"productName": "MediaPlayerClient",
"author": "fangxiang <fangxiang@cloudview.work>",
@ -32,6 +32,7 @@
"zrender": "^5.3.1"
},
"devDependencies": {
"@capacitor/core": "^2.5.0",
"@quasar/app": "^3.3.3",
"@types/node": "^10.17.15",
"workbox-webpack-plugin": "^6.4.2"

View File

@ -36,4 +36,5 @@ export namespace EventNamesDefine {
export const RefreshJointActionEquipmentList =
"onRefreshJointActionEquipmentList";
export const CheckDebug = "CheckDebug";
export const NotifyDownloadAndroid = "NotifyDownloadAndroid";
}

View File

@ -23,6 +23,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -20,7 +20,14 @@
</div>
<q-space />
<div>
<q-btn flat round icon="close" color="red" v-close-popup>
<q-btn
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>
<q-tooltip>
{{ $t("close") }}
</q-tooltip>

View File

@ -24,6 +24,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -25,6 +25,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -25,6 +25,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -26,6 +26,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -25,6 +25,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -25,6 +25,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -31,6 +31,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -31,6 +31,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -31,6 +31,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -31,6 +31,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -25,6 +25,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -25,6 +25,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -25,6 +25,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -32,6 +32,7 @@
round
icon="close"
color="red"
:disable="loading"
v-close-popup
>
<q-tooltip>

View File

@ -31,6 +31,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -25,6 +25,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -26,6 +26,7 @@
round
icon="close"
color="red"
:disable="loading"
v-close-popup
>
<q-tooltip>

View File

@ -23,6 +23,7 @@
:loading="loading"
flat
round
:disable="loading"
icon="close"
color="red"
v-close-popup

View File

@ -20,7 +20,14 @@
</div>
<q-space />
<div>
<q-btn flat round icon="close" color="red" v-close-popup>
<q-btn
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>
<q-tooltip>
{{ $t("close") }}
</q-tooltip>

View File

@ -25,6 +25,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -26,6 +26,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -25,6 +25,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -26,6 +26,7 @@
round
icon="close"
color="red"
:disable="loading"
v-close-popup
>
<q-tooltip>

View File

@ -25,6 +25,7 @@
flat
round
icon="close"
:disable="loading"
color="red"
v-close-popup
>

View File

@ -345,4 +345,9 @@ export default {
"type can not be unknow": "Type Can Not Be UnKnow",
"joint action equipment is empty! please add equipment first!":
"Joint Action Equipment Is Empty! Please Add Equipment First!",
download: "Download",
search: "Search",
"device list": "Device List",
"The detected version does not match, please download the new version!":
"The detected version does not match, please download the new version!",
};

View File

@ -622,4 +622,9 @@ export default {
"type can not be unknow": "类型不能为未知",
"joint action equipment is empty! please add equipment first!":
"当前没有联动设备! 请先添加设备!",
download: "下载",
search: "搜索",
"device list": "设备列表",
"The detected version does not match, please download the new version!":
"检测到的版本不匹配,请下载新版本!",
};

View File

@ -170,7 +170,11 @@
:class="'col-' + ($store.state.landspace ? '3' : '4')"
>
<div>
<div class="row q-my-lg" style="width: 1px; height: 1px"></div>
<div
v-if="$q.platform.is.ios"
class="row q-my-lg"
style="width: 1px; height: 1px"
></div>
<div class="row q-my-md" style="width: 1px; height: 1px"></div>
<div class="row">
<q-space />

View File

@ -46,7 +46,12 @@
<q-card-section class="fit">
<q-form ref="login_form" @submit="onSubmit" @reset="onReset">
<q-list class="fit text-h6">
<q-item v-if="$store.state.advanced_debug">
<q-item
v-if="
($q.platform.is.android && $q.platform.is.capacitor) ||
$store.state.advanced_debug
"
>
<q-item-section>
<q-input
:autofocus="!data.ip_address"
@ -89,6 +94,15 @@
</template>
</q-input>
</q-item-section>
<q-item-section avatar v-if="$q.platform.is.capacitor">
<q-btn
flat
round
icon="search"
color="accent"
@click="show_search_dialog = true"
/>
</q-item-section>
</q-item>
<q-item>
@ -200,7 +214,7 @@
:disable="data.loading"
/>
</q-item-section>
<q-item-section>
<q-item-section v-if="!$q.platform.is.capacitor">
<q-checkbox
:label="$t('full screen')"
v-model="full_screen"
@ -233,6 +247,96 @@
</q-page>
</q-page-container>
</q-layout>
<q-dialog
ref="search_dialog"
persistent
v-model="show_search_dialog"
@before-hide="searched_device_list = []"
@show="searchDevice"
@keydown="
(evt) => {
if (!loading && evt.keyCode == 27) {
show_search_dialog = false;
}
}
"
>
<q-card
class="overflow-hidden"
style="overflow-y: scroll; max-height: 60vh; max-width: 40vw"
>
<q-form @submit="onSubmit">
<q-card-section class="q-ma-none q-pa-sm">
<div class="row">
<div class="col-auto text-h6">
{{ $t("device list") }}
</div>
<q-space />
<div>
<q-btn
:loading="data.loading"
flat
round
icon="close"
color="red"
:disable="data.loading"
v-close-popup
>
<q-tooltip>
{{ $t("close") }}
</q-tooltip>
</q-btn>
</div>
</div>
</q-card-section>
<q-separator />
<q-card-section style="max-height: 55vh; width: 40vw" class="scroll">
<q-scroll-area style="height: 36vh">
<q-list>
<q-item
clickable
v-for="(item, index) of searched_device_list"
:key="index"
@click="
() => {
data.ip_address = item;
show_search_dialog = false;
}
"
>
{{ item }}
</q-item>
</q-list>
</q-scroll-area>
</q-card-section>
<q-separator />
<q-card-actions align="right">
<q-btn
:loading="data.loading"
flat
:label="$t('Close')"
no-caps
color="primary"
v-close-popup
/>
<q-btn
flat
:label="$t('search')"
no-caps
:loading="data.loading"
color="primary"
@click="searchDevice"
/>
</q-card-actions>
</q-form>
</q-card>
</q-dialog>
</template>
<script lang="ts">
@ -258,6 +362,7 @@ import { Md5 } from "ts-md5/dist/md5";
import Initializer from "src/common/Initializer";
import { api } from "src/boot/axios";
import { HttpProtocol } from "src/entities/HttpProtocol";
import { Plugins as CapacitorPlugins } from "@capacitor/core";
class _Data {
user_name: string | null = null;
@ -311,6 +416,9 @@ export default defineComponent({
const auto_login = ref(false);
const show_show_password = ref(true);
const show_search_dialog = ref(false);
const searched_device_list: Ref<string[]> = ref([]);
let cache_password: string | null = null;
let web_socket: ClientConnection | null = null;
@ -383,6 +491,9 @@ export default defineComponent({
is_pwa,
show_show_password,
full_screen,
show_search_dialog,
searched_device_list,
async onSubmit() {
data.loading = true;
return new Promise((resolve) => {
@ -560,6 +671,34 @@ export default defineComponent({
});
}
},
searchDevice() {
if ($q.platform.is.capacitor) {
data.loading = true;
searched_device_list.value = [];
try {
const { SearchDevicePlugin } = CapacitorPlugins;
interface SearchDeviceResult {
ip_list: any;
}
SearchDevicePlugin.searchDevice()
.then((result: SearchDeviceResult) => {
if (result && result.ip_list) {
try {
searched_device_list.value = JSON.parse(result.ip_list);
} catch (e) {
console.log(e);
}
}
data.loading = false;
})
.final(() => {
data.loading = false;
});
} catch (e) {
console.log(e);
}
}
},
};
},
});

View File

@ -4,18 +4,18 @@
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<!-- uc强制竖屏 portrait|landscape -->
<meta name="screen-orientation" content="landscape">
<!-- UC强制全屏 -->
<meta name="full-screen" content="yes">
<!-- UC应用模式 -->
<meta name="browsermode" content="application">
<meta name="screen-orientation" content="landscape" />
<!-- UC强制全屏 -->
<meta name="full-screen" content="yes" />
<!-- UC应用模式 -->
<meta name="browsermode" content="application" />
<!-- QQ强制竖屏 portrait|landscape-->
<meta name="x5-orientation" content="landscape">
<meta name="x5-orientation" content="landscape" />
<!-- QQ/华为强制全屏 -->
<meta name="x5-fullscreen" content="true">
<meta name="x5-fullscreen" content="true" />
<!-- QQ应用模式 -->
<meta name="x5-page-mode" content="app">
<meta name="x5-page-mode" content="app" />
<template>
<q-layout view="hHh lpR fFf">
@ -38,7 +38,7 @@
</div>
</div>
</q-page-container>
<q-footer >
<q-footer>
<bottom-bar />
</q-footer>
</div>
@ -72,13 +72,17 @@
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
import TopToolBar from "./TopToolbar.vue";
import BottomBar from "./BottomBar.vue";
import EventBus, { EventNamesDefine } from "src/common/EventBus";
import { useI18n } from "vue-i18n";
import { useQuasar } from "quasar";
import { api } from "src/boot/axios";
import GlobalData from "src/common/GlobalData";
import { HttpProtocol } from "src/entities/HttpProtocol";
export default defineComponent({
name: "PadMainLayout",
@ -86,15 +90,17 @@ export default defineComponent({
components: { TopToolBar, BottomBar },
setup() {
const $q = useQuasar();
const $t = useI18n();
const show_back = ref(true);
(<any>window).isPad = true; // pad flag
(<any>window).touchPriority = true // 使
(<any>window).isPad = true; // pad flag
(<any>window).touchPriority = true; // 使
try {
(window as any).setPadTheme();
} catch {}
EventBus.getInstance().on(EventNamesDefine.CurrentConnectDisconnect, () => {
show_back.value = false;
});
@ -104,6 +110,91 @@ export default defineComponent({
show_back.value = true;
});
if ($q.platform.is.android && !$q.platform.is.capacitor) {
$q.dialog({
title: $t.t("The Anroid platform"),
message: $t.t(
"The Anroid platform recommends using APK for a better experience"
),
persistent: true,
ok: {
label: $t.t("download"),
noCaps: true,
flat: true,
},
cancel: {
label: $t.t("cancel"),
noCaps: true,
flat: true,
},
}).onOk(() => {
window.location.href =
window.location.origin +
window.location.pathname +
"/store/cx_android_client.apk";
});
}
if ($q.platform.is.android && $q.platform.is.capacitor) {
let client = GlobalData.getInstance().getCurrentClient();
if (client) {
let url = new URL(client.url);
url.port =
GlobalData.getInstance().applicationConfig?.httpserver_port ??
HttpProtocol.DefaultHttpPort.toString();
url.pathname = "";
url.protocol = "http:";
// url
var xhr = new XMLHttpRequest();
xhr.open("GET", url.toString(), true);
xhr.onload = function () {
url = new URL(xhr.responseURL);
const back_pathname = url.pathname;
url.pathname += "/store/version.txt";
api
.get(url.toString())
.then((data) => {
if (data && data.data) {
try {
const server_version = parseInt(
(data.data as string).trim().replace(/\./g, "")
);
var package_json = require("../../package.json");
const local_version = parseInt(
package_json.version.trim().replace(/\./g, "")
);
if (server_version > local_version) {
$q.dialog({
title: $t.t("upgrade"),
message: $t.t(
"The detected version does not match, please download the new version!"
),
persistent: true,
ok: {
label: $t.t("download"),
noCaps: true,
flat: true,
},
}).onOk(() => {
url.pathname =
back_pathname + "/store/cx_android_client.apk";
window.location.href = url.toString();
});
}
} catch (e) {
alert($t.t("get version error!"));
}
}
})
.catch(() => {
alert($t.t("get version error!"));
});
};
xhr.send(null);
}
}
return {
show_back,
loga(a: any) {

View File

@ -974,6 +974,13 @@
"@babel/helper-validator-identifier" "^7.16.7"
to-fast-properties "^2.0.0"
"@capacitor/core@^2.5.0":
version "2.5.0"
resolved "https://registry.npmmirror.com/@capacitor/core/-/core-2.5.0.tgz#86b202ed950846427f710fafbdbbd844b1d0cc56"
integrity sha512-WUkUnqqLtlEYn6tly8t6VR0ABlSVbXdlD/gBbYxx0P+gEqMF9b46uYb2YqyH+8HBDANzTweEySpLfhiSUvYS7w==
dependencies:
tslib "^1.9.0"
"@intlify/core-base@9.1.10":
version "9.1.10"
resolved "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.1.10.tgz#cbd3099f375c789a1b974f3ea79b6efb8bb148fa"
@ -10603,6 +10610,11 @@ tslib@2.3.0:
resolved "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
tslib@^1.9.0:
version "1.14.1"
resolved "https://registry.npmmirror.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^2.0.3, tslib@^2.1.0:
version "2.4.0"
resolved "https://registry.npmmirror.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"