Language change button for QR page
Refactor apiManagerProxy
This commit is contained in:
parent
d5ceab476a
commit
1a4dc37f22
76
src/components/languageChangeButton.ts
Normal file
76
src/components/languageChangeButton.ts
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import { attachClickEvent, cancelEvent } from "../helpers/dom";
|
||||||
|
import { Config, LangPackDifference, LangPackString } from "../layer";
|
||||||
|
import I18n, { LangPackKey } from "../lib/langPack";
|
||||||
|
import apiManager from "../lib/mtproto/mtprotoworker";
|
||||||
|
import rootScope from "../lib/rootScope";
|
||||||
|
import Button from "./button";
|
||||||
|
import { putPreloader } from "./misc";
|
||||||
|
|
||||||
|
let set = false, times = 0;
|
||||||
|
rootScope.addEventListener('language_change', () => {
|
||||||
|
if(++times < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('language_change');
|
||||||
|
set = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
function getLang(): Promise<[Config.config, LangPackString[], LangPackDifference.langPackDifference]> {
|
||||||
|
if(cachedPromise) return cachedPromise;
|
||||||
|
return cachedPromise = apiManager.invokeApiCacheable('help.getConfig').then(config => {
|
||||||
|
if(config.suggested_lang_code !== I18n.lastRequestedLangCode) {
|
||||||
|
//I18n.loadLangPack(config.suggested_lang_code);
|
||||||
|
|
||||||
|
return Promise.all([
|
||||||
|
config,
|
||||||
|
I18n.getStrings(config.suggested_lang_code, ['Login.ContinueOnLanguage']),
|
||||||
|
I18n.getCacheLangPack()
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
return [] as any;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let cachedPromise: ReturnType<typeof getLang>;
|
||||||
|
|
||||||
|
export default function getLanguageChangeButton(appendTo: HTMLElement) {
|
||||||
|
if(set) return;
|
||||||
|
getLang().then(([config, strings]) => {
|
||||||
|
if(!config) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const backup: LangPackString[] = [];
|
||||||
|
strings.forEach(string => {
|
||||||
|
const backupString = I18n.strings.get(string.key as LangPackKey);
|
||||||
|
if(!backupString) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
backup.push(backupString);
|
||||||
|
I18n.strings.set(string.key as LangPackKey, string);
|
||||||
|
});
|
||||||
|
|
||||||
|
const btnChangeLanguage = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.ContinueOnLanguage'});
|
||||||
|
appendTo.append(btnChangeLanguage);
|
||||||
|
|
||||||
|
rootScope.addEventListener('language_change', () => {
|
||||||
|
btnChangeLanguage.remove();
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
backup.forEach(string => {
|
||||||
|
I18n.strings.set(string.key as LangPackKey, string);
|
||||||
|
});
|
||||||
|
|
||||||
|
attachClickEvent(btnChangeLanguage, (e) => {
|
||||||
|
cancelEvent(e);
|
||||||
|
|
||||||
|
btnChangeLanguage.disabled = true;
|
||||||
|
putPreloader(btnChangeLanguage);
|
||||||
|
|
||||||
|
I18n.getLangPack(config.suggested_lang_code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -17,16 +17,16 @@ import { logger, LogTypes } from "../logger";
|
|||||||
import { RichTextProcessor } from "../richtextprocessor";
|
import { RichTextProcessor } from "../richtextprocessor";
|
||||||
import rootScope from "../rootScope";
|
import rootScope from "../rootScope";
|
||||||
import { positionElementByIndex, replaceContent } from "../../helpers/dom";
|
import { positionElementByIndex, replaceContent } from "../../helpers/dom";
|
||||||
|
import apiUpdatesManager from "./apiUpdatesManager";
|
||||||
|
import appPeersManager from './appPeersManager';
|
||||||
import appImManager from "./appImManager";
|
import appImManager from "./appImManager";
|
||||||
import appMessagesManager, { Dialog } from "./appMessagesManager";
|
import appMessagesManager, { Dialog } from "./appMessagesManager";
|
||||||
import {MyDialogFilter as DialogFilter} from "../storages/filters";
|
import {MyDialogFilter as DialogFilter} from "../storages/filters";
|
||||||
import appPeersManager from './appPeersManager';
|
|
||||||
import appStateManager from "./appStateManager";
|
import appStateManager from "./appStateManager";
|
||||||
import appUsersManager from "./appUsersManager";
|
import appUsersManager from "./appUsersManager";
|
||||||
import Button from "../../components/button";
|
import Button from "../../components/button";
|
||||||
import SetTransition from "../../components/singleTransition";
|
import SetTransition from "../../components/singleTransition";
|
||||||
import sessionStorage from '../sessionStorage';
|
import sessionStorage from '../sessionStorage';
|
||||||
import apiUpdatesManager from "./apiUpdatesManager";
|
|
||||||
import appDraftsManager, { MyDraftMessage } from "./appDraftsManager";
|
import appDraftsManager, { MyDraftMessage } from "./appDraftsManager";
|
||||||
import ProgressivePreloader from "../../components/preloader";
|
import ProgressivePreloader from "../../components/preloader";
|
||||||
import App from "../../config/app";
|
import App from "../../config/app";
|
||||||
@ -490,6 +490,7 @@ export class AppDialogsManager {
|
|||||||
|
|
||||||
//selectTab(0);
|
//selectTab(0);
|
||||||
(this.folders.menu.firstElementChild as HTMLElement).click();
|
(this.folders.menu.firstElementChild as HTMLElement).click();
|
||||||
|
appMessagesManager.construct();
|
||||||
appStateManager.getState().then((state) => {
|
appStateManager.getState().then((state) => {
|
||||||
appNotificationsManager.getNotifyPeerTypeSettings();
|
appNotificationsManager.getNotifyPeerTypeSettings();
|
||||||
|
|
||||||
|
@ -30,13 +30,17 @@ export class AppDocsManager {
|
|||||||
private docs: {[docId: string]: MyDocument} = {};
|
private docs: {[docId: string]: MyDocument} = {};
|
||||||
private savingLottiePreview: {[docId: string]: true} = {};
|
private savingLottiePreview: {[docId: string]: true} = {};
|
||||||
|
|
||||||
public onServiceWorkerFail() {
|
constructor() {
|
||||||
|
apiManager.onServiceWorkerFail = this.onServiceWorkerFail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public onServiceWorkerFail = () => {
|
||||||
for(const id in this.docs) {
|
for(const id in this.docs) {
|
||||||
const doc = this.docs[id];
|
const doc = this.docs[id];
|
||||||
delete doc.supportsStreaming;
|
delete doc.supportsStreaming;
|
||||||
delete doc.url;
|
delete doc.url;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
public saveDoc(doc: Document, context?: ReferenceContext): MyDocument {
|
public saveDoc(doc: Document, context?: ReferenceContext): MyDocument {
|
||||||
if(doc._ === 'documentEmpty') {
|
if(doc._ === 'documentEmpty') {
|
||||||
|
@ -17,7 +17,7 @@ import { createPosterForVideo } from "../../helpers/files";
|
|||||||
import { copy, defineNotNumerableProperties, getObjectKeysAndSort } from "../../helpers/object";
|
import { copy, defineNotNumerableProperties, getObjectKeysAndSort } from "../../helpers/object";
|
||||||
import { randomLong } from "../../helpers/random";
|
import { randomLong } from "../../helpers/random";
|
||||||
import { splitStringByLength, limitSymbols, escapeRegExp } from "../../helpers/string";
|
import { splitStringByLength, limitSymbols, escapeRegExp } from "../../helpers/string";
|
||||||
import { Chat, ChatFull, Dialog as MTDialog, DialogPeer, DocumentAttribute, InputMedia, InputMessage, InputPeerNotifySettings, InputSingleMedia, Message, MessageAction, MessageEntity, MessageFwdHeader, MessageMedia, MessageReplies, MessageReplyHeader, MessagesDialogs, MessagesFilter, MessagesMessages, MessagesPeerDialogs, MethodDeclMap, NotifyPeer, PeerNotifySettings, PhotoSize, SendMessageAction, Update, Photo } from "../../layer";
|
import { Chat, ChatFull, Dialog as MTDialog, DialogPeer, DocumentAttribute, InputMedia, InputMessage, InputPeerNotifySettings, InputSingleMedia, Message, MessageAction, MessageEntity, MessageFwdHeader, MessageMedia, MessageReplies, MessageReplyHeader, MessagesDialogs, MessagesFilter, MessagesMessages, MethodDeclMap, NotifyPeer, PeerNotifySettings, PhotoSize, SendMessageAction, Update, Photo } from "../../layer";
|
||||||
import { InvokeApiOptions } from "../../types";
|
import { InvokeApiOptions } from "../../types";
|
||||||
import I18n, { i18n, join, langPack, LangPackKey, _i18n } from "../langPack";
|
import I18n, { i18n, join, langPack, LangPackKey, _i18n } from "../langPack";
|
||||||
import { logger, LogTypes } from "../logger";
|
import { logger, LogTypes } from "../logger";
|
||||||
@ -42,7 +42,6 @@ import appStateManager from "./appStateManager";
|
|||||||
import appUsersManager from "./appUsersManager";
|
import appUsersManager from "./appUsersManager";
|
||||||
import appWebPagesManager from "./appWebPagesManager";
|
import appWebPagesManager from "./appWebPagesManager";
|
||||||
import appDraftsManager from "./appDraftsManager";
|
import appDraftsManager from "./appDraftsManager";
|
||||||
import pushHeavyTask from "../../helpers/heavyQueue";
|
|
||||||
import { getFileNameByLocation } from "../../helpers/fileName";
|
import { getFileNameByLocation } from "../../helpers/fileName";
|
||||||
import appProfileManager from "./appProfileManager";
|
import appProfileManager from "./appProfileManager";
|
||||||
import DEBUG, { MOUNT_CLASS_TO } from "../../config/debug";
|
import DEBUG, { MOUNT_CLASS_TO } from "../../config/debug";
|
||||||
@ -193,9 +192,6 @@ export class AppMessagesManager {
|
|||||||
private groupedTempId = 0;
|
private groupedTempId = 0;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.dialogsStorage = new DialogsStorage(this, appChatsManager, appPeersManager, appUsersManager, appDraftsManager, appNotificationsManager, appStateManager, apiUpdatesManager, serverTimeManager);
|
|
||||||
this.filtersStorage = new FiltersStorage(this, appPeersManager, appUsersManager, appNotificationsManager, appStateManager, apiUpdatesManager, /* apiManager, */ rootScope);
|
|
||||||
|
|
||||||
rootScope.addMultipleEventsListeners({
|
rootScope.addMultipleEventsListeners({
|
||||||
updateMessageID: this.onUpdateMessageId,
|
updateMessageID: this.onUpdateMessageId,
|
||||||
|
|
||||||
@ -298,7 +294,7 @@ export class AppMessagesManager {
|
|||||||
this.reloadConversation(peerId);
|
this.reloadConversation(peerId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
appStateManager.getState().then(state => {
|
appStateManager.getState().then(state => {
|
||||||
if(state.maxSeenMsgId) {
|
if(state.maxSeenMsgId) {
|
||||||
this.maxSeenId = state.maxSeenMsgId;
|
this.maxSeenId = state.maxSeenMsgId;
|
||||||
@ -308,6 +304,11 @@ export class AppMessagesManager {
|
|||||||
appNotificationsManager.start();
|
appNotificationsManager.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public construct() {
|
||||||
|
this.dialogsStorage = new DialogsStorage(this, appChatsManager, appPeersManager, appUsersManager, appDraftsManager, appNotificationsManager, appStateManager, apiUpdatesManager, serverTimeManager);
|
||||||
|
this.filtersStorage = new FiltersStorage(this, appPeersManager, appUsersManager, appNotificationsManager, appStateManager, apiUpdatesManager, /* apiManager, */ rootScope);
|
||||||
|
}
|
||||||
|
|
||||||
public getInputEntities(entities: MessageEntity[]) {
|
public getInputEntities(entities: MessageEntity[]) {
|
||||||
var sendEntites = copy(entities);
|
var sendEntites = copy(entities);
|
||||||
sendEntites.forEach((entity: any) => {
|
sendEntites.forEach((entity: any) => {
|
||||||
|
@ -14,12 +14,9 @@ import { logger } from '../logger';
|
|||||||
import rootScope from '../rootScope';
|
import rootScope from '../rootScope';
|
||||||
import webpWorkerController from '../webp/webpWorkerController';
|
import webpWorkerController from '../webp/webpWorkerController';
|
||||||
import type { DownloadOptions } from './apiFileManager';
|
import type { DownloadOptions } from './apiFileManager';
|
||||||
import { ApiError } from './apiManager';
|
import type { ServiceWorkerTask } from './mtproto.service';
|
||||||
import type { ServiceWorkerTask, ServiceWorkerTaskResponse } from './mtproto.service';
|
|
||||||
import { UserAuth } from './mtproto_config';
|
import { UserAuth } from './mtproto_config';
|
||||||
import type { MTMessage } from './networker';
|
import type { MTMessage } from './networker';
|
||||||
import referenceDatabase from './referenceDatabase';
|
|
||||||
import appDocsManager from '../appManagers/appDocsManager';
|
|
||||||
import DEBUG, { MOUNT_CLASS_TO } from '../../config/debug';
|
import DEBUG, { MOUNT_CLASS_TO } from '../../config/debug';
|
||||||
import Socket from './transports/websocket';
|
import Socket from './transports/websocket';
|
||||||
|
|
||||||
@ -80,136 +77,29 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
|
|||||||
|
|
||||||
private sockets: Map<number, Socket> = new Map();
|
private sockets: Map<number, Socket> = new Map();
|
||||||
|
|
||||||
|
private taskListeners: {[taskType: string]: (task: any) => void} = {};
|
||||||
|
|
||||||
|
public onServiceWorkerFail: () => void;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.log('constructor');
|
this.log('constructor');
|
||||||
|
|
||||||
this.registerServiceWorker();
|
this.registerServiceWorker();
|
||||||
|
|
||||||
/// #if !MTPROTO_SW
|
this.addTaskListener('reload', () => {
|
||||||
this.registerWorker();
|
|
||||||
/// #endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public isServiceWorkerOnline() {
|
|
||||||
return this.isSWRegistered;
|
|
||||||
}
|
|
||||||
|
|
||||||
private registerServiceWorker() {
|
|
||||||
if(!('serviceWorker' in navigator)) return;
|
|
||||||
|
|
||||||
const worker = navigator.serviceWorker;
|
|
||||||
worker.register('./sw.js', {scope: './'}).then(registration => {
|
|
||||||
this.log('SW registered', registration);
|
|
||||||
this.isSWRegistered = true;
|
|
||||||
|
|
||||||
const sw = registration.installing || registration.waiting || registration.active;
|
|
||||||
sw.addEventListener('statechange', (e) => {
|
|
||||||
this.log('SW statechange', e);
|
|
||||||
});
|
|
||||||
|
|
||||||
/// #if MTPROTO_SW
|
|
||||||
const controller = worker.controller || registration.installing || registration.waiting || registration.active;
|
|
||||||
this.onWorkerFirstMessage(controller);
|
|
||||||
/// #endif
|
|
||||||
}, (err) => {
|
|
||||||
this.isSWRegistered = false;
|
|
||||||
this.log.error('SW registration failed!', err);
|
|
||||||
appDocsManager.onServiceWorkerFail();
|
|
||||||
});
|
|
||||||
|
|
||||||
worker.addEventListener('controllerchange', () => {
|
|
||||||
this.log.warn('controllerchange');
|
|
||||||
this.releasePending();
|
|
||||||
|
|
||||||
worker.controller.addEventListener('error', (e) => {
|
|
||||||
this.log.error('controller error:', e);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
/// #if MTPROTO_SW
|
|
||||||
worker.addEventListener('message', this.onWorkerMessage);
|
|
||||||
/// #else
|
|
||||||
worker.addEventListener('message', (e) => {
|
|
||||||
const task: ServiceWorkerTask = e.data;
|
|
||||||
if(!isObject(task)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.postMessage(task);
|
|
||||||
});
|
|
||||||
/// #endif
|
|
||||||
|
|
||||||
worker.addEventListener('messageerror', (e) => {
|
|
||||||
this.log.error('SW messageerror:', e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private onWorkerFirstMessage(worker: any) {
|
|
||||||
if(!this.worker) {
|
|
||||||
this.worker = worker;
|
|
||||||
this.log('set webWorker');
|
|
||||||
|
|
||||||
this.postMessage = this.worker.postMessage.bind(this.worker);
|
|
||||||
|
|
||||||
const isWebpSupported = webpWorkerController.isWebpSupported();
|
|
||||||
this.log('WebP supported:', isWebpSupported);
|
|
||||||
this.postMessage({type: 'webpSupport', payload: isWebpSupported});
|
|
||||||
|
|
||||||
this.releasePending();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private onWorkerMessage = (e: MessageEvent) => {
|
|
||||||
//this.log('got message from worker:', e.data);
|
|
||||||
|
|
||||||
const task = e.data;
|
|
||||||
|
|
||||||
if(!isObject(task)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(task.update) {
|
|
||||||
if(this.updatesProcessor) {
|
|
||||||
this.updatesProcessor(task.update);
|
|
||||||
}
|
|
||||||
} else if(task.progress) {
|
|
||||||
rootScope.broadcast('download_progress', task.progress);
|
|
||||||
} else if(task.type === 'reload') {
|
|
||||||
location.reload();
|
location.reload();
|
||||||
} else if(task.type === 'connectionStatusChange') {
|
});
|
||||||
|
|
||||||
|
this.addTaskListener('connectionStatusChange', (task: any) => {
|
||||||
rootScope.broadcast('connection_status_change', task.payload);
|
rootScope.broadcast('connection_status_change', task.payload);
|
||||||
} else if(task.type === 'convertWebp') {
|
});
|
||||||
|
|
||||||
|
this.addTaskListener('convertWebp', (task) => {
|
||||||
webpWorkerController.postMessage(task);
|
webpWorkerController.postMessage(task);
|
||||||
} else if((task as ServiceWorkerTaskResponse).type === 'requestFilePart') {
|
});
|
||||||
const _task = task as ServiceWorkerTaskResponse;
|
|
||||||
|
|
||||||
if(_task.error) {
|
|
||||||
const onError = (error: ApiError) => {
|
|
||||||
if(error?.type === 'FILE_REFERENCE_EXPIRED') {
|
|
||||||
// @ts-ignore
|
|
||||||
const bytes = _task.originalPayload[1].file_reference;
|
|
||||||
referenceDatabase.refreshReference(bytes).then(() => {
|
|
||||||
// @ts-ignore
|
|
||||||
_task.originalPayload[1].file_reference = referenceDatabase.getReferenceByLink(bytes);
|
|
||||||
const newTask: ServiceWorkerTask = {
|
|
||||||
type: _task.type,
|
|
||||||
id: _task.id,
|
|
||||||
payload: _task.originalPayload
|
|
||||||
};
|
|
||||||
|
|
||||||
this.postMessage(newTask);
|
this.addTaskListener('socketProxy', (task) => {
|
||||||
}).catch(onError);
|
|
||||||
} else {
|
|
||||||
navigator.serviceWorker.controller.postMessage(task);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onError(_task.error);
|
|
||||||
} else {
|
|
||||||
navigator.serviceWorker.controller.postMessage(task);
|
|
||||||
}
|
|
||||||
} else if(task.type === 'socketProxy') {
|
|
||||||
const socketTask = task.payload;
|
const socketTask = task.payload;
|
||||||
const id = socketTask.id;
|
const id = socketTask.id;
|
||||||
//console.log('socketProxy', socketTask, id);
|
//console.log('socketProxy', socketTask, id);
|
||||||
@ -263,6 +153,110 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
|
|||||||
socket.addEventListener('message', onMessage);
|
socket.addEventListener('message', onMessage);
|
||||||
this.sockets.set(id, socket);
|
this.sockets.set(id, socket);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/// #if !MTPROTO_SW
|
||||||
|
this.registerWorker();
|
||||||
|
/// #endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public isServiceWorkerOnline() {
|
||||||
|
return this.isSWRegistered;
|
||||||
|
}
|
||||||
|
|
||||||
|
private registerServiceWorker() {
|
||||||
|
if(!('serviceWorker' in navigator)) return;
|
||||||
|
|
||||||
|
const worker = navigator.serviceWorker;
|
||||||
|
worker.register('./sw.js', {scope: './'}).then(registration => {
|
||||||
|
this.log('SW registered', registration);
|
||||||
|
this.isSWRegistered = true;
|
||||||
|
|
||||||
|
const sw = registration.installing || registration.waiting || registration.active;
|
||||||
|
sw.addEventListener('statechange', (e) => {
|
||||||
|
this.log('SW statechange', e);
|
||||||
|
});
|
||||||
|
|
||||||
|
/// #if MTPROTO_SW
|
||||||
|
const controller = worker.controller || registration.installing || registration.waiting || registration.active;
|
||||||
|
this.onWorkerFirstMessage(controller);
|
||||||
|
/// #endif
|
||||||
|
}, (err) => {
|
||||||
|
this.isSWRegistered = false;
|
||||||
|
this.log.error('SW registration failed!', err);
|
||||||
|
|
||||||
|
if(this.onServiceWorkerFail) {
|
||||||
|
this.onServiceWorkerFail();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
worker.addEventListener('controllerchange', () => {
|
||||||
|
this.log.warn('controllerchange');
|
||||||
|
this.releasePending();
|
||||||
|
|
||||||
|
worker.controller.addEventListener('error', (e) => {
|
||||||
|
this.log.error('controller error:', e);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/// #if MTPROTO_SW
|
||||||
|
worker.addEventListener('message', this.onWorkerMessage);
|
||||||
|
/// #else
|
||||||
|
worker.addEventListener('message', (e) => {
|
||||||
|
const task: ServiceWorkerTask = e.data;
|
||||||
|
if(!isObject(task)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.postMessage(task);
|
||||||
|
});
|
||||||
|
/// #endif
|
||||||
|
|
||||||
|
worker.addEventListener('messageerror', (e) => {
|
||||||
|
this.log.error('SW messageerror:', e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private onWorkerFirstMessage(worker: any) {
|
||||||
|
if(!this.worker) {
|
||||||
|
this.worker = worker;
|
||||||
|
this.log('set webWorker');
|
||||||
|
|
||||||
|
this.postMessage = this.worker.postMessage.bind(this.worker);
|
||||||
|
|
||||||
|
const isWebpSupported = webpWorkerController.isWebpSupported();
|
||||||
|
this.log('WebP supported:', isWebpSupported);
|
||||||
|
this.postMessage({type: 'webpSupport', payload: isWebpSupported});
|
||||||
|
|
||||||
|
this.releasePending();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public addTaskListener(name: keyof ApiManagerProxy['taskListeners'], callback: ApiManagerProxy['taskListeners'][typeof name]) {
|
||||||
|
this.taskListeners[name] = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
private onWorkerMessage = (e: MessageEvent) => {
|
||||||
|
//this.log('got message from worker:', e.data);
|
||||||
|
|
||||||
|
const task = e.data;
|
||||||
|
|
||||||
|
if(!isObject(task)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const callback = this.taskListeners[task.type];
|
||||||
|
if(callback) {
|
||||||
|
callback(task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(task.update) {
|
||||||
|
if(this.updatesProcessor) {
|
||||||
|
this.updatesProcessor(task.update);
|
||||||
|
}
|
||||||
|
} else if(task.progress) {
|
||||||
|
rootScope.broadcast('download_progress', task.progress);
|
||||||
} else if(task.hasOwnProperty('result') || task.hasOwnProperty('error')) {
|
} else if(task.hasOwnProperty('result') || task.hasOwnProperty('error')) {
|
||||||
this.finalizeTask(task.taskId, task.result, task.error);
|
this.finalizeTask(task.taskId, task.result, task.error);
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,14 @@
|
|||||||
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type { ServiceWorkerTask, ServiceWorkerTaskResponse } from "./mtproto.service";
|
||||||
|
import type { ApiError } from "./apiManager";
|
||||||
import appMessagesManager from "../appManagers/appMessagesManager";
|
import appMessagesManager from "../appManagers/appMessagesManager";
|
||||||
import { Photo } from "../../layer";
|
import { Photo } from "../../layer";
|
||||||
import { bytesToHex } from "../../helpers/bytes";
|
import { bytesToHex } from "../../helpers/bytes";
|
||||||
import { deepEqual } from "../../helpers/object";
|
import { deepEqual } from "../../helpers/object";
|
||||||
import { MOUNT_CLASS_TO } from "../../config/debug";
|
import { MOUNT_CLASS_TO } from "../../config/debug";
|
||||||
|
import apiManager from "./mtprotoworker";
|
||||||
|
|
||||||
export type ReferenceContext = ReferenceContext.referenceContextProfilePhoto | ReferenceContext.referenceContextMessage;
|
export type ReferenceContext = ReferenceContext.referenceContextProfilePhoto | ReferenceContext.referenceContextMessage;
|
||||||
export namespace ReferenceContext {
|
export namespace ReferenceContext {
|
||||||
@ -34,6 +37,36 @@ class ReferenceDatabase {
|
|||||||
//private references: Map<ReferenceBytes, number[]> = new Map();
|
//private references: Map<ReferenceBytes, number[]> = new Map();
|
||||||
private links: {[hex: string]: ReferenceBytes} = {};
|
private links: {[hex: string]: ReferenceBytes} = {};
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
apiManager.addTaskListener('requestFilePart', (task: ServiceWorkerTaskResponse) => {
|
||||||
|
if(task.error) {
|
||||||
|
const onError = (error: ApiError) => {
|
||||||
|
if(error?.type === 'FILE_REFERENCE_EXPIRED') {
|
||||||
|
// @ts-ignore
|
||||||
|
const bytes = task.originalPayload[1].file_reference;
|
||||||
|
referenceDatabase.refreshReference(bytes).then(() => {
|
||||||
|
// @ts-ignore
|
||||||
|
task.originalPayload[1].file_reference = referenceDatabase.getReferenceByLink(bytes);
|
||||||
|
const newTask: ServiceWorkerTask = {
|
||||||
|
type: task.type,
|
||||||
|
id: task.id,
|
||||||
|
payload: task.originalPayload
|
||||||
|
};
|
||||||
|
|
||||||
|
apiManager.postMessage(newTask);
|
||||||
|
}).catch(onError);
|
||||||
|
} else {
|
||||||
|
navigator.serviceWorker.controller.postMessage(task);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onError(task.error);
|
||||||
|
} else {
|
||||||
|
navigator.serviceWorker.controller.postMessage(task);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public saveContext(reference: ReferenceBytes, context: ReferenceContext, contexts?: ReferenceContexts) {
|
public saveContext(reference: ReferenceBytes, context: ReferenceContext, contexts?: ReferenceContexts) {
|
||||||
[contexts, reference] = this.getContexts(reference);
|
[contexts, reference] = this.getContexts(reference);
|
||||||
if(!contexts) {
|
if(!contexts) {
|
||||||
|
@ -20,8 +20,7 @@ import fastSmoothScroll from "../helpers/fastSmoothScroll";
|
|||||||
import { isTouchSupported } from "../helpers/touchSupport";
|
import { isTouchSupported } from "../helpers/touchSupport";
|
||||||
import App from "../config/app";
|
import App from "../config/app";
|
||||||
import Modes from "../config/modes";
|
import Modes from "../config/modes";
|
||||||
import I18n, { _i18n, i18n, LangPackKey } from "../lib/langPack";
|
import { _i18n, i18n } from "../lib/langPack";
|
||||||
import { LangPackString } from "../layer";
|
|
||||||
import lottieLoader from "../lib/lottieLoader";
|
import lottieLoader from "../lib/lottieLoader";
|
||||||
import { ripple } from "../components/ripple";
|
import { ripple } from "../components/ripple";
|
||||||
import findUpTag from "../helpers/dom/findUpTag";
|
import findUpTag from "../helpers/dom/findUpTag";
|
||||||
@ -29,6 +28,8 @@ import findUpClassName from "../helpers/dom/findUpClassName";
|
|||||||
import { randomLong } from "../helpers/random";
|
import { randomLong } from "../helpers/random";
|
||||||
import AppStorage from "../lib/storage";
|
import AppStorage from "../lib/storage";
|
||||||
import CacheStorageController from "../lib/cacheStorage";
|
import CacheStorageController from "../lib/cacheStorage";
|
||||||
|
import pageSignQR from "./pageSignQR";
|
||||||
|
import getLanguageChangeButton from "../components/languageChangeButton";
|
||||||
|
|
||||||
type Country = _Country & {
|
type Country = _Country & {
|
||||||
li?: HTMLLIElement[]
|
li?: HTMLLIElement[]
|
||||||
@ -383,7 +384,8 @@ let onFirstMount = () => {
|
|||||||
|
|
||||||
let qrMounted = false;
|
let qrMounted = false;
|
||||||
btnQr.addEventListener('click', () => {
|
btnQr.addEventListener('click', () => {
|
||||||
const promise = import('./pageSignQR');
|
pageSignQR.mount();
|
||||||
|
/* const promise = import('./pageSignQR');
|
||||||
btnQr.disabled = true;
|
btnQr.disabled = true;
|
||||||
|
|
||||||
let preloaderDiv: HTMLElement;
|
let preloaderDiv: HTMLElement;
|
||||||
@ -401,7 +403,7 @@ let onFirstMount = () => {
|
|||||||
preloaderDiv.remove();
|
preloaderDiv.remove();
|
||||||
}
|
}
|
||||||
}, 200);
|
}, 200);
|
||||||
});
|
}); */
|
||||||
});
|
});
|
||||||
|
|
||||||
inputWrapper.append(countryInputField.container, telInputField.container, signedCheckboxField.label, btnNext, btnQr);
|
inputWrapper.append(countryInputField.container, telInputField.container, signedCheckboxField.label, btnNext, btnQr);
|
||||||
@ -461,45 +463,7 @@ let onFirstMount = () => {
|
|||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
apiManager.invokeApi('help.getConfig').then(config => {
|
getLanguageChangeButton(inputWrapper);
|
||||||
if(config.suggested_lang_code !== I18n.lastRequestedLangCode) {
|
|
||||||
//I18n.loadLangPack(config.suggested_lang_code);
|
|
||||||
|
|
||||||
Promise.all([
|
|
||||||
I18n.getStrings(config.suggested_lang_code, ['Login.ContinueOnLanguage']),
|
|
||||||
I18n.getCacheLangPack()
|
|
||||||
]).then(res => {
|
|
||||||
const backup: LangPackString[] = [];
|
|
||||||
res[0].forEach(string => {
|
|
||||||
const backupString = I18n.strings.get(string.key as LangPackKey);
|
|
||||||
if(!backupString) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
backup.push(backupString);
|
|
||||||
I18n.strings.set(string.key as LangPackKey, string);
|
|
||||||
});
|
|
||||||
|
|
||||||
const btnChangeLanguage = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.ContinueOnLanguage'});
|
|
||||||
inputWrapper.append(btnChangeLanguage);
|
|
||||||
|
|
||||||
backup.forEach(string => {
|
|
||||||
I18n.strings.set(string.key as LangPackKey, string);
|
|
||||||
});
|
|
||||||
|
|
||||||
attachClickEvent(btnChangeLanguage, (e) => {
|
|
||||||
cancelEvent(e);
|
|
||||||
|
|
||||||
btnChangeLanguage.disabled = true;
|
|
||||||
putPreloader(btnChangeLanguage);
|
|
||||||
|
|
||||||
I18n.getLangPack(config.suggested_lang_code).then(() => {
|
|
||||||
btnChangeLanguage.remove();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
tryAgain();
|
tryAgain();
|
||||||
};
|
};
|
||||||
|
@ -16,6 +16,7 @@ import { _i18n, i18n, LangPackKey } from '../lib/langPack';
|
|||||||
import appStateManager from '../lib/appManagers/appStateManager';
|
import appStateManager from '../lib/appManagers/appStateManager';
|
||||||
import rootScope from '../lib/rootScope';
|
import rootScope from '../lib/rootScope';
|
||||||
import { putPreloader } from '../components/misc';
|
import { putPreloader } from '../components/misc';
|
||||||
|
import getLanguageChangeButton from '../components/languageChangeButton';
|
||||||
|
|
||||||
let onFirstMount = async() => {
|
let onFirstMount = async() => {
|
||||||
const pageElement = page.pageEl;
|
const pageElement = page.pageEl;
|
||||||
@ -29,6 +30,8 @@ let onFirstMount = async() => {
|
|||||||
const btnBack = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.QR.Cancel'});
|
const btnBack = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.QR.Cancel'});
|
||||||
inputWrapper.append(btnBack);
|
inputWrapper.append(btnBack);
|
||||||
|
|
||||||
|
getLanguageChangeButton(inputWrapper);
|
||||||
|
|
||||||
const container = imageDiv.parentElement;
|
const container = imageDiv.parentElement;
|
||||||
|
|
||||||
const h4 = document.createElement('h4');
|
const h4 = document.createElement('h4');
|
||||||
|
Loading…
Reference in New Issue
Block a user