Implement mobile connection resumes
This commit is contained in:
@ -29,6 +29,18 @@ export class App {
|
||||
this.handleUrl(document.URL);
|
||||
}
|
||||
|
||||
close() {
|
||||
if (this.session) this.session.close();
|
||||
}
|
||||
|
||||
sleep() {
|
||||
if (this.session) this.session.sleep();
|
||||
}
|
||||
|
||||
async wakeup() {
|
||||
if (this.session) await this.session.wakeup();
|
||||
}
|
||||
|
||||
setHash(hash: string) {
|
||||
const url = new URL(document.URL);
|
||||
url.hash = hash;
|
||||
@ -244,8 +256,8 @@ export class App {
|
||||
}
|
||||
});
|
||||
|
||||
this.session.subscribe(response => {
|
||||
this.addMessage(response.data.data.message);
|
||||
this.session.subscribe(event => {
|
||||
this.addMessage(event.data.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
29
src/main.ts
29
src/main.ts
@ -7,5 +7,32 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||
for (const noscript of document.getElementsByTagName("noscript")) {
|
||||
noscript.remove();
|
||||
}
|
||||
new Locutus.App();
|
||||
|
||||
const locutus = new Locutus.App();
|
||||
if (isMobilePlatform()) {
|
||||
console.log("MOBILE");
|
||||
document.addEventListener("visibilitychange", () => {
|
||||
if (document.visibilityState === 'hidden') {
|
||||
locutus.sleep();
|
||||
} else if (document.visibilityState === 'visible') {
|
||||
locutus.wakeup().then();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log("DESKTOP");
|
||||
window.addEventListener("beforeunload", (evt) => {
|
||||
locutus.close();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function isMobilePlatform(): boolean {
|
||||
if (window.matchMedia("(any-pointer:coarse)").matches) return true;
|
||||
const ua = navigator.userAgent;
|
||||
if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(ua)) {
|
||||
return true;
|
||||
} else if (/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test(ua)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
53
src/usimp.ts
53
src/usimp.ts
@ -30,6 +30,13 @@ interface OutputEnvelopeJson {
|
||||
} | null,
|
||||
}
|
||||
|
||||
interface EventJson {
|
||||
data: {
|
||||
message: string,
|
||||
}
|
||||
uuid: string,
|
||||
}
|
||||
|
||||
interface WellKnownJson {
|
||||
domain: DomainJson,
|
||||
domain_servers: DomainServerJson[]
|
||||
@ -149,6 +156,7 @@ export class Session {
|
||||
websocket: WebSocket | null;
|
||||
numRequests: number;
|
||||
subscriptions: string[];
|
||||
subscriptionEndpoints: {cb: (a: EventJson) => void}[];
|
||||
|
||||
constructor(domain: Domain) {
|
||||
this.domain = domain;
|
||||
@ -158,6 +166,28 @@ export class Session {
|
||||
this.httpBaseUrl = null;
|
||||
this.websocket = null;
|
||||
this.subscriptions = [];
|
||||
this.subscriptionEndpoints = [];
|
||||
}
|
||||
|
||||
close() {
|
||||
if (this.websocket && (this.websocket.readyState !== WebSocket.CLOSING && this.websocket.readyState !== WebSocket.CLOSED)) {
|
||||
this.websocket.close();
|
||||
this.subscriptions = [];
|
||||
this.websocket = null;
|
||||
this.server = null;
|
||||
}
|
||||
}
|
||||
|
||||
sleep() {
|
||||
this.close();
|
||||
}
|
||||
|
||||
async wakeup() {
|
||||
await this.chooseDomainServer();
|
||||
await this.ping();
|
||||
for (const endpoint of this.subscriptionEndpoints) {
|
||||
await this._subscribe(endpoint.cb);
|
||||
}
|
||||
}
|
||||
|
||||
async chooseDomainServer(): Promise<{ http: number | null, ws: number | null } | undefined> {
|
||||
@ -289,7 +319,7 @@ export class Session {
|
||||
responseData.duration = endTime - startTime;
|
||||
return responseData;
|
||||
} else {
|
||||
return null; // TODO subscription id
|
||||
return await this.waitForWebSocketResponse(req_nr, timeout);
|
||||
}
|
||||
} else if (this.httpBaseUrl) {
|
||||
const controller = new AbortController();
|
||||
@ -369,25 +399,36 @@ export class Session {
|
||||
});
|
||||
}
|
||||
|
||||
async subscribe(cb: (a: OutputEnvelopeJson) => void) {
|
||||
async subscribe(cb: (a: EventJson) => void) {
|
||||
this.subscriptionEndpoints.push({cb: cb});
|
||||
await this._subscribe(cb);
|
||||
}
|
||||
|
||||
private async _subscribe(cb: (a: EventJson) => void) {
|
||||
this.numRequests++;
|
||||
if (this.websocket !== null) {
|
||||
let subscription = await this.send('subscribe', {}, 60_000, false, cb);
|
||||
const subscription = await this.send('subscribe', {}, 60_000, false, (res) => {
|
||||
if (res.data && res.data.events) {
|
||||
for (const event of res.data.events) {
|
||||
cb(event);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.subscriptions.push(subscription);
|
||||
return subscription;
|
||||
} else {
|
||||
this.send('subscribe', {}, 60_000).then((res) => {
|
||||
if (res.status === "success") {
|
||||
this.subscribe(cb);
|
||||
this._subscribe(cb);
|
||||
cb(res);
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
this.subscribe(cb);
|
||||
this._subscribe(cb);
|
||||
}, 1000);
|
||||
}
|
||||
}).catch(() => {
|
||||
setTimeout(() => {
|
||||
this.subscribe(cb);
|
||||
this._subscribe(cb);
|
||||
}, 1000);
|
||||
});
|
||||
return null; // TODO subscription id
|
||||
|
Reference in New Issue
Block a user