[Streaming] Fix hanged chunk load promise
Hide 'Sensitive content' section if it's unavailable
This commit is contained in:
parent
1b88742d3e
commit
eff96de924
@ -31,6 +31,7 @@ import CheckboxField from "../../checkboxField";
|
||||
import PopupPeer from "../../popups/peer";
|
||||
import appDraftsManager from "../../../lib/appManagers/appDraftsManager";
|
||||
import Button from "../../button";
|
||||
import toggleDisability from "../../../helpers/dom/toggleDisability";
|
||||
|
||||
export default class AppPrivacyAndSecurityTab extends SliderSuperTabEventable {
|
||||
private activeSessionsRow: Row;
|
||||
@ -232,6 +233,7 @@ export default class AppPrivacyAndSecurityTab extends SliderSuperTabEventable {
|
||||
const promises: Promise<any>[] = [];
|
||||
{
|
||||
const section = new SettingSection({name: 'Privacy.SensitiveContent'});
|
||||
section.container.classList.add('hide');
|
||||
|
||||
promises.push(apiManager.invokeApi('account.getContentSettings').then(settings => {
|
||||
if(!settings.pFlags.sensitive_can_change) {
|
||||
@ -247,7 +249,7 @@ export default class AppPrivacyAndSecurityTab extends SliderSuperTabEventable {
|
||||
});
|
||||
|
||||
section.content.append(sensitiveRow.container);
|
||||
|
||||
section.container.classList.remove('hide');
|
||||
|
||||
this.eventListener.addEventListener('destroy', () => {
|
||||
const _enabled = sensitiveRow.checkboxField.checked;
|
||||
@ -273,7 +275,10 @@ export default class AppPrivacyAndSecurityTab extends SliderSuperTabEventable {
|
||||
buttons: [{
|
||||
langKey: 'Delete',
|
||||
callback: () => {
|
||||
appDraftsManager.clearAllDrafts();
|
||||
const toggle = toggleDisability([deleteButton], true);
|
||||
appDraftsManager.clearAllDrafts().then(() => {
|
||||
toggle();
|
||||
});
|
||||
},
|
||||
isDanger: true,
|
||||
}],
|
||||
|
@ -10,6 +10,12 @@ export const isWorker = isWebWorker || isServiceWorker;
|
||||
|
||||
// в SW может быть сразу две переменных TRUE, поэтому проверяю по последней
|
||||
|
||||
export const getWindowClients = () => {
|
||||
return (self as any as ServiceWorkerGlobalScope)
|
||||
.clients
|
||||
.matchAll({ includeUncontrolled: false, type: 'window' });
|
||||
};
|
||||
|
||||
const notifyServiceWorker = (all: boolean, ...args: any[]) => {
|
||||
(self as any as ServiceWorkerGlobalScope)
|
||||
.clients
|
||||
|
@ -54,7 +54,7 @@ export interface ToggleStorageTask extends WorkerTaskVoidTemplate {
|
||||
export class ApiManagerProxy extends CryptoWorkerMethods {
|
||||
public worker: /* Window */Worker;
|
||||
public postMessage: (...args: any[]) => void;
|
||||
public postSWMessage: (...args: any[]) => void = () => {};
|
||||
//public postSWMessage: (...args: any[]) => void = () => {};
|
||||
private afterMessageIdTemp = 0;
|
||||
|
||||
private taskId = 0;
|
||||
@ -229,7 +229,7 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
|
||||
this.log('SW statechange', e);
|
||||
});
|
||||
|
||||
this.postSWMessage = worker.controller.postMessage.bind(worker.controller);
|
||||
//this.postSWMessage = worker.controller.postMessage.bind(worker.controller);
|
||||
|
||||
/// #if MTPROTO_SW
|
||||
const controller = worker.controller || registration.installing || registration.waiting || registration.active;
|
||||
@ -292,6 +292,12 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
|
||||
});
|
||||
}
|
||||
|
||||
public postSWMessage(message: any) {
|
||||
if(navigator.serviceWorker.controller) {
|
||||
navigator.serviceWorker.controller.postMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
private onWorkerFirstMessage(worker: any) {
|
||||
if(!this.worker) {
|
||||
this.worker = worker;
|
||||
|
@ -181,9 +181,7 @@ export class WebPushApiManager {
|
||||
}
|
||||
};
|
||||
|
||||
if(navigator.serviceWorker.controller) {
|
||||
navigator.serviceWorker.controller.postMessage(task);
|
||||
}
|
||||
apiManager.postSWMessage(task);
|
||||
|
||||
this.isAliveTO = setTimeout(this.isAliveNotify, 10000);
|
||||
}
|
||||
@ -199,10 +197,8 @@ export class WebPushApiManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if(navigator.serviceWorker.controller) {
|
||||
const task: ServiceWorkerNotificationsClearTask = {type: 'notifications_clear'};
|
||||
navigator.serviceWorker.controller.postMessage(task);
|
||||
}
|
||||
const task: ServiceWorkerNotificationsClearTask = {type: 'notifications_clear'};
|
||||
apiManager.postSWMessage(task);
|
||||
}
|
||||
|
||||
public setUpServiceWorkerChannel() {
|
||||
|
@ -22,7 +22,7 @@ import CacheStorageController from '../cacheStorage';
|
||||
|
||||
export const log = logger('SW', LogTypes.Error | LogTypes.Debug | LogTypes.Log | LogTypes.Warn);
|
||||
const ctx = self as any as ServiceWorkerGlobalScope;
|
||||
export const deferredPromises: {[taskId: string]: CancellablePromise<any>} = {};
|
||||
export const deferredPromises: Map<WindowClient['id'], {[taskId: string]: CancellablePromise<any>}> = new Map();
|
||||
|
||||
export interface RequestFilePartTask extends Modify<WorkerTaskTemplate, {id: string}> {
|
||||
type: 'requestFilePart',
|
||||
@ -69,16 +69,23 @@ const taskListeners: {
|
||||
ping: (task: ServiceWorkerPingTask, event) => {
|
||||
onPing(task, event);
|
||||
},
|
||||
requestFilePart: (task: RequestFilePartTaskResponse) => {
|
||||
const promise = deferredPromises[task.id];
|
||||
|
||||
if(task.error) {
|
||||
promise.reject(task.error);
|
||||
} else {
|
||||
promise.resolve(task.payload);
|
||||
requestFilePart: (task: RequestFilePartTaskResponse, e: ExtendableMessageEvent) => {
|
||||
const windowClient = e.source as WindowClient;
|
||||
const promises = deferredPromises.get(windowClient.id);
|
||||
if(!promises) {
|
||||
return;
|
||||
}
|
||||
|
||||
delete deferredPromises[task.id];
|
||||
const promise = promises[task.id];
|
||||
if(promise) {
|
||||
if(task.error) {
|
||||
promise.reject(task.error);
|
||||
} else {
|
||||
promise.resolve(task.payload);
|
||||
}
|
||||
|
||||
delete promises[task.id];
|
||||
}
|
||||
},
|
||||
toggleStorage: (task: ToggleStorageTask) => {
|
||||
CacheStorageController.toggleStorage(task.payload);
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
import { readBlobAsUint8Array } from "../../helpers/blob";
|
||||
import { CancellablePromise, deferredPromise } from "../../helpers/cancellablePromise";
|
||||
import { notifySomeone } from "../../helpers/context";
|
||||
import { getWindowClients, notifySomeone } from "../../helpers/context";
|
||||
import debounce from "../../helpers/schedulers/debounce";
|
||||
import { isSafari } from "../../helpers/userAgent";
|
||||
import { InputFileLocation, UploadFile } from "../../layer";
|
||||
@ -49,6 +49,20 @@ const clearOldChunks = () => {
|
||||
};
|
||||
|
||||
setInterval(clearOldChunks, 1800e3);
|
||||
setInterval(() => {
|
||||
getWindowClients().then((clients) => {
|
||||
for(const [clientId, promises] of deferredPromises) {
|
||||
if(!clients.find(client => client.id === clientId)) {
|
||||
for(const taskId in promises) {
|
||||
const promise = promises[taskId];
|
||||
promise.reject();
|
||||
}
|
||||
|
||||
deferredPromises.delete(clientId);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 120e3);
|
||||
|
||||
type StreamRange = [number, number];
|
||||
type StreamId = string;
|
||||
@ -72,7 +86,7 @@ class Stream {
|
||||
streams.delete(this.id);
|
||||
};
|
||||
|
||||
private requestFilePartFromWorker(alignedOffset: number, limit: number, fromPreload = false) {
|
||||
private async requestFilePartFromWorker(alignedOffset: number, limit: number, fromPreload = false) {
|
||||
const task: Omit<RequestFilePartTask, 'id'> = {
|
||||
type: 'requestFilePart',
|
||||
payload: [this.info.dcId, this.info.location, alignedOffset, limit]
|
||||
@ -81,16 +95,32 @@ class Stream {
|
||||
const taskId = JSON.stringify(task);
|
||||
(task as RequestFilePartTask).id = taskId;
|
||||
|
||||
let deferred = deferredPromises[taskId] as CancellablePromise<UploadFile.uploadFile>;
|
||||
const windowClient = await getWindowClients().then((clients) => {
|
||||
if(!clients.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
return clients.find(client => deferredPromises.has(client.id)) || clients[0];
|
||||
});
|
||||
|
||||
if(!windowClient) {
|
||||
throw new Error('no window');
|
||||
}
|
||||
|
||||
let promises = deferredPromises.get(windowClient.id);
|
||||
if(!promises) {
|
||||
deferredPromises.set(windowClient.id, promises = {});
|
||||
}
|
||||
|
||||
let deferred = promises[taskId] as CancellablePromise<UploadFile.uploadFile>;
|
||||
if(deferred) {
|
||||
return deferred.then(uploadFile => uploadFile.bytes);
|
||||
}
|
||||
|
||||
notifySomeone(task);
|
||||
|
||||
|
||||
windowClient.postMessage(task);
|
||||
this.loadedOffsets.add(alignedOffset);
|
||||
|
||||
deferred = deferredPromises[taskId] = deferredPromise<UploadFile.uploadFile>();
|
||||
deferred = promises[taskId] = deferredPromise<UploadFile.uploadFile>();
|
||||
const bytesPromise = deferred.then(uploadFile => uploadFile.bytes);
|
||||
|
||||
this.saveChunkToCache(bytesPromise, alignedOffset, limit);
|
||||
|
Loading…
x
Reference in New Issue
Block a user