From abeebe03176c1cf858a27e7399a0ca328441212f Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Mon, 4 Apr 2022 23:39:39 +0300 Subject: [PATCH] Fix setting background patterns --- src/components/chat/bubbles.ts | 4 ++-- src/helpers/blob/blobConstruct.ts | 6 +++++- src/lib/cacheStorage.ts | 6 +++--- src/lib/fileManager.ts | 30 +++++++++++++----------------- src/lib/idb.ts | 2 +- src/lib/mtproto/apiFileManager.ts | 28 +++++++++++++++++++--------- src/lib/rlottie/lottieLoader.ts | 2 +- 7 files changed, 44 insertions(+), 34 deletions(-) diff --git a/src/components/chat/bubbles.ts b/src/components/chat/bubbles.ts index ac34b344..778485bb 100644 --- a/src/components/chat/bubbles.ts +++ b/src/components/chat/bubbles.ts @@ -847,7 +847,7 @@ export default class ChatBubbles { this.onUnreadedInViewport(target, mid); } }); - }); + }, {root: this.scrollable.container}); this.viewsObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { @@ -870,7 +870,7 @@ export default class ChatBubbles { } } }); - }); + }, {root: this.scrollable.container}); this.sendViewCountersDebounced = debounce(() => { const mids = [...this.viewsMids]; diff --git a/src/helpers/blob/blobConstruct.ts b/src/helpers/blob/blobConstruct.ts index dbc1df76..64d5defd 100644 --- a/src/helpers/blob/blobConstruct.ts +++ b/src/helpers/blob/blobConstruct.ts @@ -11,7 +11,11 @@ import blobSafeMimeType from "./blobSafeMimeType"; -export default function blobConstruct(blobParts: any, mimeType: string = ''): Blob { +export default function blobConstruct(blobParts: Array | T, mimeType: string = ''): Blob { + if(!Array.isArray(blobParts)) { + blobParts = [blobParts]; + } + let blob; const safeMimeType = blobSafeMimeType(mimeType); try { diff --git a/src/lib/cacheStorage.ts b/src/lib/cacheStorage.ts index 022f72ee..073423b6 100644 --- a/src/lib/cacheStorage.ts +++ b/src/lib/cacheStorage.ts @@ -78,7 +78,7 @@ export default class CacheStorageController { public saveFile(fileName: string, blob: Blob | Uint8Array) { //return Promise.resolve(blobConstruct([blob])); if(!(blob instanceof Blob)) { - blob = blobConstruct(blob) as Blob; + blob = blobConstruct(blob); } const response = new Response(blob, { @@ -123,8 +123,8 @@ export default class CacheStorageController { }); } - public getFileWriter(fileName: string, mimeType: string) { - const fakeWriter = FileManager.getFakeFileWriter(mimeType, (blob) => { + public getFileWriter(fileName: string, fileSize: number, mimeType: string) { + const fakeWriter = FileManager.getFakeFileWriter(mimeType, fileSize, (blob) => { return this.saveFile(fileName, blob).catch(() => blob); }); diff --git a/src/lib/fileManager.ts b/src/lib/fileManager.ts index 61e4d2c5..811d1521 100644 --- a/src/lib/fileManager.ts +++ b/src/lib/fileManager.ts @@ -10,7 +10,6 @@ */ import blobConstruct from "../helpers/blob/blobConstruct"; -import readBlobAsUint8Array from "../helpers/blob/readBlobAsUint8Array"; export class FileManager { private blobSupported = true; @@ -27,37 +26,34 @@ export class FileManager { return this.blobSupported; } - public write(fileWriter: ReturnType, bytes: Uint8Array | Blob | string): Promise { - if(bytes instanceof Blob) { // is file bytes - return readBlobAsUint8Array(bytes).then(arr => { - return fileWriter.write(arr); - }); - } else { - return fileWriter.write(bytes); - } - } - - public getFakeFileWriter(mimeType: string, saveFileCallback?: (blob: Blob) => Promise) { - const blobParts: Array = []; + public getFakeFileWriter(mimeType: string, size: number, saveFileCallback?: (blob: Blob) => Promise) { + let bytes: Uint8Array = new Uint8Array(size); const fakeFileWriter = { - write: async(part: Uint8Array | string) => { + write: async(part: Uint8Array, offset: number) => { if(!this.blobSupported) { throw false; } - blobParts.push(part); + bytes.set(part, offset); }, truncate: () => { - blobParts.length = 0; + bytes = new Uint8Array(); + }, + trim: (size: number) => { + bytes = bytes.slice(0, size); }, finalize: (saveToStorage = true) => { - const blob = blobConstruct(blobParts, mimeType); + const blob = blobConstruct(bytes, mimeType); if(saveToStorage && saveFileCallback) { saveFileCallback(blob); } return blob; + }, + getParts: () => bytes, + replaceParts: (parts: typeof bytes) => { + bytes = parts; } }; diff --git a/src/lib/idb.ts b/src/lib/idb.ts index d7b21383..ee848be3 100644 --- a/src/lib/idb.ts +++ b/src/lib/idb.ts @@ -260,7 +260,7 @@ export default class IDBStorage> { public saveFile(fileName: string, blob: Blob | Uint8Array) { //return Promise.resolve(blobConstruct([blob])); if(!(blob instanceof Blob)) { - blob = blobConstruct([blob]) as Blob; + blob = blobConstruct(blob); } return this.save(fileName, blob); diff --git a/src/lib/mtproto/apiFileManager.ts b/src/lib/mtproto/apiFileManager.ts index 063620f1..c1b3fc67 100644 --- a/src/lib/mtproto/apiFileManager.ts +++ b/src/lib/mtproto/apiFileManager.ts @@ -272,13 +272,13 @@ export class ApiFileManager { private uncompressTGS = (bytes: Uint8Array, fileName: string) => { //this.log('uncompressTGS', bytes, bytes.slice().buffer); // slice нужен потому что в uint8array - 5053 length, в arraybuffer - 5084 - return cryptoWorker.invokeCrypto('gzipUncompress', bytes.slice().buffer, true) as Promise; + return cryptoWorker.invokeCrypto('gzipUncompress', bytes.slice().buffer, false) as Promise; }; private uncompressTGV = (bytes: Uint8Array, fileName: string) => { //this.log('uncompressTGS', bytes, bytes.slice().buffer); // slice нужен потому что в uint8array - 5053 length, в arraybuffer - 5084 - return cryptoWorker.invokeCrypto('gzipUncompress', bytes.slice().buffer, true) as Promise; + return cryptoWorker.invokeCrypto('gzipUncompress', bytes.slice().buffer, false) as Promise; }; private convertWebp = (bytes: Uint8Array, fileName: string) => { @@ -408,11 +408,11 @@ export class ApiFileManager { deferred.resolve(blob); }).catch(() => { //this.log('not cached', fileName); - const fileWriterPromise = fileStorage.getFileWriter(fileName, mimeType); + const limit = options.limitPart || this.getLimitPart(size); + const fileWriterPromise = fileStorage.getFileWriter(fileName, size || limit, mimeType); fileWriterPromise.then((fileWriter) => { cacheFileWriter = fileWriter; - const limit = options.limitPart || this.getLimitPart(size); let offset: number; let startOffset = 0; let writeFilePromise: CancellablePromise = Promise.resolve(), @@ -422,7 +422,7 @@ export class ApiFileManager { //console.error('maxRequests', maxRequests); - const processDownloaded = async(bytes: Uint8Array, offset: number) => { + const processDownloaded = async(bytes: Uint8Array) => { if(process) { //const perf = performance.now(); const processed = await process(bytes, fileName); @@ -473,13 +473,18 @@ export class ApiFileManager { deferred.notify({done, offset, total: size}); //} - const processedResult = await processDownloaded(bytes, offset); + await writeFilePromise; checkCancel(); - await writeFilePromise; + await fileWriter.write(bytes, offset); + } + + if(isFinal && process) { + const bytes = fileWriter.getParts(); + const processedResult = await processDownloaded(bytes); checkCancel(); - await fileManager.write(fileWriter, processedResult); + fileWriter.replaceParts(processedResult); } writeFileDeferred.resolve(); @@ -487,7 +492,12 @@ export class ApiFileManager { if(isFinal) { resolved = true; - deferred.resolve(fileWriter.finalize(size < MAX_FILE_SAVE_SIZE)); + const realSize = size || bytes.byteLength; + if(!size) { + fileWriter.trim(realSize); + } + + deferred.resolve(fileWriter.finalize(realSize < MAX_FILE_SAVE_SIZE)); } } catch(err) { errorHandler(err as Error); diff --git a/src/lib/rlottie/lottieLoader.ts b/src/lib/rlottie/lottieLoader.ts index 842c4d67..6ec10536 100644 --- a/src/lib/rlottie/lottieLoader.ts +++ b/src/lib/rlottie/lottieLoader.ts @@ -101,7 +101,7 @@ export class LottieLoader { return fetch(url) .then(res => { if(!res.headers || res.headers.get('content-type') === 'application/octet-stream') { - return res.arrayBuffer().then(data => apiManager.invokeCrypto('gzipUncompress', data)).then(arr => blobConstruct([arr], '')) + return res.arrayBuffer().then(data => apiManager.invokeCrypto('gzipUncompress', data)).then(arr => blobConstruct(arr as Uint8Array, '')) } else { return res.blob(); }