Refactor backgrounds uploading

This commit is contained in:
Eduard Kuzmenko 2022-06-19 20:19:41 +04:00
parent e6e898879f
commit 23b688f54c
5 changed files with 147 additions and 165 deletions

View File

@ -7,7 +7,7 @@
import { generateSection } from ".."; import { generateSection } from "..";
import { averageColor, averageColorFromCanvas } from "../../../helpers/averageColor"; import { averageColor, averageColorFromCanvas } from "../../../helpers/averageColor";
import blur from "../../../helpers/blur"; import blur from "../../../helpers/blur";
import deferredPromise from "../../../helpers/cancellablePromise"; import deferredPromise, { CancellablePromise } from "../../../helpers/cancellablePromise";
import { attachClickEvent } from "../../../helpers/dom/clickEvent"; import { attachClickEvent } from "../../../helpers/dom/clickEvent";
import findUpClassName from "../../../helpers/dom/findUpClassName"; import findUpClassName from "../../../helpers/dom/findUpClassName";
import highlightningColor from "../../../helpers/highlightningColor"; import highlightningColor from "../../../helpers/highlightningColor";
@ -30,25 +30,24 @@ import { STATE_INIT, Theme } from "../../../config/state";
import themeController from "../../../helpers/themeController"; import themeController from "../../../helpers/themeController";
import requestFile from "../../../helpers/files/requestFile"; import requestFile from "../../../helpers/files/requestFile";
let uploadTempId = 0;
export default class AppBackgroundTab extends SliderSuperTab { export default class AppBackgroundTab extends SliderSuperTab {
private grid: HTMLElement; private grid: HTMLElement;
private tempId = 0; private tempId = 0;
private theme: Theme;
private clicked: Set<DocId> = new Set(); private clicked: Set<DocId> = new Set();
private blurCheckboxField: CheckboxField; private blurCheckboxField: CheckboxField;
private wallpapersByElement: Map<HTMLElement, WallPaper> = new Map(); private wallPapersByElement: Map<HTMLElement, WallPaper> = new Map();
private elementsByKey: Map<string, HTMLElement> = new Map(); private elementsByKey: Map<string, HTMLElement> = new Map();
private get theme() {
return themeController.getTheme();
}
init() { init() {
this.header.classList.add('with-border'); this.header.classList.add('with-border');
this.container.classList.add('background-container', 'background-image-container'); this.container.classList.add('background-container', 'background-image-container');
this.setTitle('ChatBackground'); this.setTitle('ChatBackground');
this.theme = themeController.getTheme();
{ {
const container = generateSection(this.scrollable); const container = generateSection(this.scrollable);
@ -71,16 +70,16 @@ export default class AppBackgroundTab extends SliderSuperTab {
withRipple: true withRipple: true
}); });
this.listenerSetter.add(blurCheckboxField.input)('change', () => { this.listenerSetter.add(blurCheckboxField.input)('change', async() => {
this.theme.background.blur = blurCheckboxField.input.checked; this.theme.background.blur = blurCheckboxField.input.checked;
this.managers.appStateManager.pushToState('settings', rootScope.settings); await this.managers.appStateManager.pushToState('settings', rootScope.settings);
// * wait for animation end // * wait for animation end
setTimeout(() => { setTimeout(() => {
const active = grid.querySelector('.active') as HTMLElement; const active = grid.querySelector('.active') as HTMLElement;
if(!active) return; if(!active) return;
const wallpaper = this.wallpapersByElement.get(active); const wallpaper = this.wallPapersByElement.get(active);
if((wallpaper as WallPaper.wallPaper).pFlags.pattern || wallpaper._ === 'wallPaperNoFile') { if((wallpaper as WallPaper.wallPaper).pFlags.pattern || wallpaper._ === 'wallPaperNoFile') {
return; return;
} }
@ -109,89 +108,39 @@ export default class AppBackgroundTab extends SliderSuperTab {
private onUploadClick = () => { private onUploadClick = () => {
requestFile('image/x-png,image/png,image/jpeg').then(async(file) => { requestFile('image/x-png,image/png,image/jpeg').then(async(file) => {
// const id = 'wallpaper-upload-' + ++uploadTempId; const wallPaper = await this.managers.appDocsManager.prepareWallPaperUpload(file);
const uploadPromise = this.managers.appDocsManager.uploadWallPaper(wallPaper.id);
const uploadDeferred: CancellablePromise<any> = appDownloadManager.getNewDeferredForUpload(file.name, uploadPromise);
// const thumb = { const deferred = deferredPromise<void>();
// _: 'photoSize', deferred.addNotifyListener = uploadDeferred.addNotifyListener;
// h: 0, deferred.cancel = uploadDeferred.cancel;
// w: 0,
// location: {} as any,
// size: file.size,
// type: 'full',
// } as PhotoSize.photoSize;
// let document: MyDocument = {
// _: 'document',
// access_hash: '',
// attributes: [],
// dc_id: 0,
// file_reference: [],
// id,
// mime_type: file.type,
// size: file.size,
// date: Date.now() / 1000,
// pFlags: {},
// thumbs: [thumb],
// file_name: file.name
// };
// document = await this.managers.appDocsManager.saveDoc(document); uploadDeferred.then((wallPaper) => {
this.clicked.delete(key);
this.elementsByKey.delete(key);
this.wallPapersByElement.set(container, wallPaper);
const newKey = this.getWallPaperKey(wallPaper);
this.elementsByKey.set(newKey, container);
// const cacheContext = appDownloadManager.getCacheContext(document); this.setBackgroundDocument(wallPaper).then(deferred.resolve, deferred.reject);
// cacheContext.downloaded = file.size; }, deferred.reject);
// cacheContext.url = URL.createObjectURL(file);
// let wallpaper: WallPaper.wallPaper = { const key = this.getWallPaperKey(wallPaper);
// _: 'wallPaper', deferred.catch(() => {
// access_hash: '', container.remove();
// document: document, });
// id,
// slug: id,
// pFlags: {}
// };
// const upload = appDownloadManager.upload(file, file.name); const preloader = new ProgressivePreloader({
isUpload: true,
cancelable: true,
tryAgainOnFail: false
});
// const deferred = deferredPromise<void>(); const container = this.addWallPaper(wallPaper, false);
// deferred.addNotifyListener = upload.addNotifyListener; this.clicked.add(key);
// deferred.cancel = upload.cancel;
// upload.then((inputFile) => { preloader.attach(container, false, deferred);
// this.managers.apiManager.invokeApi('account.uploadWallPaper', {
// file: inputFile,
// mime_type: file.type,
// settings: {
// _: 'wallPaperSettings'
// }
// }).then(async(_wallpaper) => {
// const newDoc = (_wallpaper as WallPaper.wallPaper).document as MyDocument;
// const newCacheContext = appDownloadManager.getCacheContext(newDoc);
// Object.assign(newCacheContext, cacheContext);
// wallpaper = _wallpaper as WallPaper.wallPaper;
// wallpaper.document = await this.managers.appDocsManager.saveDoc(wallpaper.document);
// this.setBackgroundDocument(wallpaper).then(deferred.resolve, deferred.reject);
// }, deferred.reject);
// }, deferred.reject);
// const key = this.getWallpaperKey(wallpaper);
// deferred.then(() => {
// this.clicked.delete(key);
// }, (err) => {
// container.remove();
// //console.error('i saw the body drop', err);
// });
// const preloader = new ProgressivePreloader({
// isUpload: true,
// cancelable: true,
// tryAgainOnFail: false
// });
// const container = this.addWallPaper(wallpaper, false);
// this.clicked.add(key);
// preloader.attach(container, false, deferred);
}); });
}; };
@ -206,98 +155,105 @@ export default class AppBackgroundTab extends SliderSuperTab {
} }
}; };
private getColorsFromWallpaper(wallpaper: WallPaper) { private getColorsFromWallPaper(wallPaper: WallPaper) {
return wallpaper.settings ? [ return wallPaper.settings ? [
wallpaper.settings.background_color, wallPaper.settings.background_color,
wallpaper.settings.second_background_color, wallPaper.settings.second_background_color,
wallpaper.settings.third_background_color, wallPaper.settings.third_background_color,
wallpaper.settings.fourth_background_color wallPaper.settings.fourth_background_color
].filter(Boolean).map((color) => '#' + color.toString(16)).join(',') : ''; ].filter(Boolean).map((color) => '#' + color.toString(16)).join(',') : '';
} }
private getWallpaperKey(wallpaper: WallPaper) { private getWallPaperKey(wallPaper: WallPaper) {
return '' + wallpaper.id; return '' + wallPaper.id;
} }
private getWallpaperKeyFromTheme(theme: Theme) { private getWallPaperKeyFromTheme(theme: Theme) {
return '' + theme.background.id; return '' + theme.background.id;
} }
private async addWallPaper(wallpaper: WallPaper, append = true) { private addWallPaper(wallPaper: WallPaper, append = true) {
const colors = this.getColorsFromWallpaper(wallpaper); const colors = this.getColorsFromWallPaper(wallPaper);
const hasFile = wallpaper._ === 'wallPaper'; const hasFile = wallPaper._ === 'wallPaper';
if((hasFile && wallpaper.pFlags.pattern && !colors)/* || if((hasFile && wallPaper.pFlags.pattern && !colors)/* ||
(wallpaper.document as MyDocument).mime_type.indexOf('application/') === 0 */) { (wallpaper.document as MyDocument).mime_type.indexOf('application/') === 0 */) {
return; return;
} }
const isDark = !!wallpaper.pFlags.dark; const isDark = !!wallPaper.pFlags.dark;
const doc = hasFile ? wallpaper.document as Document.document : undefined; const doc = hasFile ? wallPaper.document as Document.document : undefined;
const container = document.createElement('div'); const container = document.createElement('div');
container.classList.add('grid-item'); container.classList.add('grid-item');
container.dataset.id = '' + wallpaper.id; container.dataset.id = '' + wallPaper.id;
const key = this.getWallpaperKey(wallpaper); const key = this.getWallPaperKey(wallPaper);
this.wallpapersByElement.set(container, wallpaper); this.wallPapersByElement.set(container, wallPaper);
this.elementsByKey.set(key, container); this.elementsByKey.set(key, container);
const media = document.createElement('div'); const media = document.createElement('div');
media.classList.add('grid-item-media'); media.classList.add('grid-item-media');
let wrapped: Awaited<ReturnType<typeof wrapPhoto>>, size: PhotoSize; let wrapped: ReturnType<typeof wrapPhoto>, size: PhotoSize;
if(hasFile) { if(hasFile) {
size = choosePhotoSize(doc, 200, 200); size = choosePhotoSize(doc, 200, 200);
wrapped = await wrapPhoto({ wrapped = wrapPhoto({
photo: doc, photo: doc,
message: null, message: null,
container: media, container: media,
withoutPreloader: true, withoutPreloader: true,
size: size, size: size,
noFadeIn: wallpaper.pFlags.pattern noFadeIn: wallPaper.pFlags.pattern
}); });
(wrapped.loadPromises.thumb || wrapped.loadPromises.full).then(() => { if(wallPaper.pFlags.pattern) {
media.classList.add('is-pattern');
}
wrapped.then(async({loadPromises, images}) => {
await loadPromises.thumb || loadPromises.full;
return images;
}).then((images) => {
if(wallPaper.pFlags.pattern) {
if(isDark) {
images.full.style.display = 'none';
if(images.thumb) {
images.thumb.style.display = 'none';
}
} else if(wallPaper.settings?.intensity) {
images.full.style.opacity = '' + Math.abs(wallPaper.settings.intensity) / 100;
}
}
sequentialDom.mutate(() => { sequentialDom.mutate(() => {
container.append(media); container.append(media);
}); });
}); });
if(wallpaper.pFlags.pattern) {
media.classList.add('is-pattern');
if(isDark) {
wrapped.images.full.style.display = 'none';
if(wrapped.images.thumb) {
wrapped.images.thumb.style.display = 'none';
}
} else if(wallpaper.settings?.intensity) {
wrapped.images.full.style.opacity = '' + Math.abs(wallpaper.settings.intensity) / 100;
}
}
} else { } else {
container.append(media); container.append(media);
} }
if(wallpaper.settings && wallpaper.settings.background_color !== undefined) { if(wallPaper.settings && wallPaper.settings.background_color !== undefined) {
const {canvas} = ChatBackgroundGradientRenderer.create(colors); const {canvas} = ChatBackgroundGradientRenderer.create(colors);
canvas.classList.add('background-colors-canvas'); canvas.classList.add('background-colors-canvas');
if(isDark && hasFile) { if(isDark && hasFile) {
wrapped.loadPromises.full.then(async() => { wrapped.then(({loadPromises}) => {
const cacheContext = await this.managers.thumbsStorage.getCacheContext(doc, size.type); loadPromises.full.then(async() => {
canvas.style.webkitMaskImage = `url(${cacheContext.url})`; const cacheContext = await this.managers.thumbsStorage.getCacheContext(doc, size.type);
canvas.style.opacity = '' + Math.abs(wallpaper.settings.intensity) / 100; canvas.style.webkitMaskImage = `url(${cacheContext.url})`;
media.append(canvas); canvas.style.opacity = '' + Math.abs(wallPaper.settings.intensity) / 100;
media.append(canvas);
});
}); });
} else { } else {
media.append(canvas); media.append(canvas);
} }
} }
if(this.getWallpaperKeyFromTheme(this.theme) === key) { if(this.getWallPaperKeyFromTheme(this.theme) === key) {
container.classList.add('active'); container.classList.add('active');
} }
@ -310,13 +266,13 @@ export default class AppBackgroundTab extends SliderSuperTab {
const target = findUpClassName(e.target, 'grid-item') as HTMLElement; const target = findUpClassName(e.target, 'grid-item') as HTMLElement;
if(!target) return; if(!target) return;
const wallpaper = this.wallpapersByElement.get(target); const wallpaper = this.wallPapersByElement.get(target);
if(wallpaper._ === 'wallPaperNoFile') { if(wallpaper._ === 'wallPaperNoFile') {
this.setBackgroundDocument(wallpaper); this.setBackgroundDocument(wallpaper);
return; return;
} }
const key = this.getWallpaperKey(wallpaper); const key = this.getWallPaperKey(wallpaper);
if(this.clicked.has(key)) return; if(this.clicked.has(key)) return;
this.clicked.add(key); this.clicked.add(key);
@ -356,11 +312,11 @@ export default class AppBackgroundTab extends SliderSuperTab {
}); });
}; };
private setBackgroundDocument = (wallpaper: WallPaper) => { private setBackgroundDocument = (wallPaper: WallPaper) => {
let _tempId = ++this.tempId; let _tempId = ++this.tempId;
const middleware = () => _tempId === this.tempId; const middleware = () => _tempId === this.tempId;
const doc = (wallpaper as WallPaper.wallPaper).document as MyDocument; const doc = (wallPaper as WallPaper.wallPaper).document as MyDocument;
const deferred = deferredPromise<void>(); const deferred = deferredPromise<void>();
let download: Promise<void> | ReturnType<AppDownloadManager['downloadMediaURL']>; let download: Promise<void> | ReturnType<AppDownloadManager['downloadMediaURL']>;
if(doc) { if(doc) {
@ -384,7 +340,7 @@ export default class AppBackgroundTab extends SliderSuperTab {
if(url && !this.theme.background.color) { if(url && !this.theme.background.color) {
getPixelPromise = averageColor(url); getPixelPromise = averageColor(url);
} else { } else {
const {canvas} = ChatBackgroundGradientRenderer.create(this.getColorsFromWallpaper(wallpaper)); const {canvas} = ChatBackgroundGradientRenderer.create(this.getColorsFromWallPaper(wallPaper));
getPixelPromise = Promise.resolve(averageColorFromCanvas(canvas)); getPixelPromise = Promise.resolve(averageColorFromCanvas(canvas));
} }
@ -398,10 +354,10 @@ export default class AppBackgroundTab extends SliderSuperTab {
// const hsla = 'rgba(0, 0, 0, 0.3)'; // const hsla = 'rgba(0, 0, 0, 0.3)';
//console.log(doc, hsla, performance.now() - perf); //console.log(doc, hsla, performance.now() - perf);
const slug = (wallpaper as WallPaper.wallPaper).slug ?? ''; const slug = (wallPaper as WallPaper.wallPaper).slug ?? '';
background.id = wallpaper.id; background.id = wallPaper.id;
background.intensity = wallpaper.settings?.intensity ?? 0; background.intensity = wallPaper.settings?.intensity ?? 0;
background.color = this.getColorsFromWallpaper(wallpaper); background.color = this.getColorsFromWallPaper(wallPaper);
background.slug = slug; background.slug = slug;
background.highlightningColor = hsla; background.highlightningColor = hsla;
this.managers.appStateManager.pushToState('settings', rootScope.settings); this.managers.appStateManager.pushToState('settings', rootScope.settings);
@ -442,7 +398,7 @@ export default class AppBackgroundTab extends SliderSuperTab {
private setActive = () => { private setActive = () => {
const active = this.grid.querySelector('.active'); const active = this.grid.querySelector('.active');
const target = this.elementsByKey.get(this.getWallpaperKeyFromTheme(this.theme)); const target = this.elementsByKey.get(this.getWallPaperKeyFromTheme(this.theme));
if(active === target) { if(active === target) {
return; return;
} }

2
src/config/tabId.ts Normal file
View File

@ -0,0 +1,2 @@
const tabId = Date.now() % Math.random() * 100000000 | 0;
export default tabId;

View File

@ -4,13 +4,14 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE * https://github.com/morethanwords/tweb/blob/master/LICENSE
*/ */
import tabId from "../config/tabId";
let uploadId = 0; let uploadId = 0;
export default function getFileNameForUpload(file: File | Blob) { export default function getFileNameForUpload(file: File | Blob) {
let fileName: string; let fileName: string;
const mimeType = file?.type; const mimeType = file?.type;
if(mimeType) { // the same like apiFileName in appMessagesManager for upload! if(mimeType) { // the same like apiFileName in appMessagesManager for upload!
const ext = uploadId++ + '.' + mimeType.split('/')[1]; const ext = `${tabId}_${uploadId++}.mimeType.split('/')[1]`;
if(['image/jpeg', 'image/png', 'image/bmp'].indexOf(mimeType) >= 0) { if(['image/jpeg', 'image/png', 'image/bmp'].indexOf(mimeType) >= 0) {
fileName = 'photo' + ext; fileName = 'photo' + ext;
@ -21,9 +22,8 @@ export default function getFileNameForUpload(file: File | Blob) {
} else { } else {
fileName = 'document' + ext; fileName = 'document' + ext;
} }
} else { } else {
fileName = 'upload-' + uploadId++; fileName = `upload-${tabId}_${uploadId++}`;
} }
return fileName; return fileName;

View File

@ -22,7 +22,7 @@ import { isServiceWorkerOnline } from '../mtproto/mtproto.worker';
import MTProtoMessagePort from '../mtproto/mtprotoMessagePort'; import MTProtoMessagePort from '../mtproto/mtprotoMessagePort';
import getDocumentInput from './utils/docs/getDocumentInput'; import getDocumentInput from './utils/docs/getDocumentInput';
import getDocumentURL from './utils/docs/getDocumentURL'; import getDocumentURL from './utils/docs/getDocumentURL';
import { CancellablePromise } from '../../helpers/cancellablePromise'; import type { ThumbCache } from '../storages/thumbs';
export type MyDocument = Document.document; export type MyDocument = Document.document;
@ -34,6 +34,8 @@ const EXTENSION_MIME_TYPE_MAP = {
pdf: 'application/pdf', pdf: 'application/pdf',
}; };
type WallPaperId = WallPaper.wallPaper['id'];
let uploadWallPaperTempId = 0; let uploadWallPaperTempId = 0;
export class AppDocsManager extends AppManager { export class AppDocsManager extends AppManager {
@ -41,9 +43,12 @@ export class AppDocsManager extends AppManager {
private stickerCachedThumbs: {[docId: DocId]: {[toneIndex: number]: {url: string, w: number, h: number}}}; private stickerCachedThumbs: {[docId: DocId]: {[toneIndex: number]: {url: string, w: number, h: number}}};
private uploadingWallPapers: {[id: WallPaperId]: {cacheContext: ThumbCache, file: File}};
protected after() { protected after() {
this.docs = {}; this.docs = {};
this.stickerCachedThumbs = {}; this.stickerCachedThumbs = {};
this.uploadingWallPapers = {};
MTProtoMessagePort.getInstance<false>().addEventListener('serviceWorkerOnline', (online) => { MTProtoMessagePort.getInstance<false>().addEventListener('serviceWorkerOnline', (online) => {
if(!online) { if(!online) {
@ -64,8 +69,8 @@ export class AppDocsManager extends AppManager {
}; };
public saveDoc(doc: Document, context?: ReferenceContext): MyDocument { public saveDoc(doc: Document, context?: ReferenceContext): MyDocument {
if(doc._ === 'documentEmpty') { if(!doc || doc._ === 'documentEmpty') {
return undefined; return;
} }
const oldDoc = this.docs[doc.id]; const oldDoc = this.docs[doc.id];
@ -313,7 +318,7 @@ export class AppDocsManager extends AppManager {
}); });
} }
public uploadWallPaper(file: File) { public prepareWallPaperUpload(file: File) {
const id = 'wallpaper-upload-' + ++uploadWallPaperTempId; const id = 'wallpaper-upload-' + ++uploadWallPaperTempId;
const thumb = { const thumb = {
@ -343,7 +348,7 @@ export class AppDocsManager extends AppManager {
const cacheContext = this.thumbsStorage.setCacheContextURL(document, undefined, URL.createObjectURL(file), file.size); const cacheContext = this.thumbsStorage.setCacheContextURL(document, undefined, URL.createObjectURL(file), file.size);
let wallpaper: WallPaper.wallPaper = { const wallpaper: WallPaper.wallPaper = {
_: 'wallPaper', _: 'wallPaper',
access_hash: '', access_hash: '',
document: document, document: document,
@ -352,25 +357,35 @@ export class AppDocsManager extends AppManager {
pFlags: {} pFlags: {}
}; };
const upload = this.apiFileManager.upload({file, fileName: file.name}); this.uploadingWallPapers[id] = {
cacheContext,
file,
};
upload.then((inputFile) => { return wallpaper;
this.apiManager.invokeApi('account.uploadWallPaper', { }
public uploadWallPaper(id: WallPaperId) {
const {cacheContext, file} = this.uploadingWallPapers[id];
delete this.uploadingWallPapers[id];
const upload = this.apiFileManager.upload({file, fileName: file.name});
return upload.then((inputFile) => {
return this.apiManager.invokeApi('account.uploadWallPaper', {
file: inputFile, file: inputFile,
mime_type: file.type, mime_type: file.type,
settings: { settings: {
_: 'wallPaperSettings' _: 'wallPaperSettings',
} }
}).then((_wallpaper) => { }).then((wallPaper) => {
const newDoc = (_wallpaper as WallPaper.wallPaper).document as MyDocument; assumeType<WallPaper.wallPaper>(wallPaper);
this.thumbsStorage.setCacheContextURL(newDoc, undefined, cacheContext.url, cacheContext.downloaded); wallPaper.document = this.saveDoc(wallPaper.document);
this.thumbsStorage.setCacheContextURL(wallPaper.document, undefined, cacheContext.url, cacheContext.downloaded);
wallpaper = _wallpaper as WallPaper.wallPaper; return wallPaper;
wallpaper.document = this.saveDoc(wallpaper.document);
}); });
}); });
return wallpaper;
} }
public getGifs() { public getGifs() {

View File

@ -104,6 +104,17 @@ export class AppDownloadManager {
return download[type] = deferred as any; return download[type] = deferred as any;
} }
public getNewDeferredForUpload<T extends Promise<any>>(fileName: string, promise: T) {
const deferred = this.getNewDeferred<InputFile>(fileName);
promise.then(deferred.resolve, deferred.reject);
deferred.finally(() => {
this.clearDownload(fileName);
});
return deferred as CancellablePromise<Awaited<T>>;
}
private clearDownload(fileName: string) { private clearDownload(fileName: string) {
delete this.downloads[fileName]; delete this.downloads[fileName];
} }
@ -162,18 +173,16 @@ export class AppDownloadManager {
return this.downloadMedia(options, 'void'); return this.downloadMedia(options, 'void');
} }
public upload(file: File | Blob, fileName?: string) { public upload(file: File | Blob, fileName?: string, promise?: Promise<any>) {
if(!fileName) { if(!fileName) {
fileName = getFileNameForUpload(file); fileName = getFileNameForUpload(file);
} }
const deferred = this.getNewDeferred<InputFile>(fileName); if(!promise) {
this.managers.apiFileManager.upload({file, fileName}).then(deferred.resolve, deferred.reject); promise = this.managers.apiFileManager.upload({file, fileName});
}
deferred.finally(() => {
this.clearDownload(fileName); const deferred = this.getNewDeferredForUpload(fileName, promise);
});
return deferred as any as CancellablePromise<InputFile>; return deferred as any as CancellablePromise<InputFile>;
} }