Auto-download settings

This commit is contained in:
Eduard Kuzmenko 2021-03-13 14:12:24 +04:00
parent 166f63b5f8
commit e1de44ebe4
15 changed files with 232 additions and 131 deletions

View File

@ -3,7 +3,6 @@ import appMessagesManager from "../lib/appManagers/appMessagesManager";
import appDocsManager, {MyDocument} from "../lib/appManagers/appDocsManager"; import appDocsManager, {MyDocument} from "../lib/appManagers/appDocsManager";
import { CancellablePromise, deferredPromise } from "../helpers/cancellablePromise"; import { CancellablePromise, deferredPromise } from "../helpers/cancellablePromise";
import { isSafari } from "../helpers/userAgent"; import { isSafari } from "../helpers/userAgent";
import { isInDOM } from "../helpers/dom";
import { MOUNT_CLASS_TO } from "../config/debug"; import { MOUNT_CLASS_TO } from "../config/debug";
// TODO: если удалить сообщение, и при этом аудио будет играть - оно не остановится, и можно будет по нему перейти вникуда // TODO: если удалить сообщение, и при этом аудио будет играть - оно не остановится, и можно будет по нему перейти вникуда
@ -111,17 +110,17 @@ class AppMediaPlaybackController {
waitingStorage[mid] = deferred; waitingStorage[mid] = deferred;
} }
// если что - загрузит voice или round заранее, так правильнее deferred.then(() => {
const downloadPromise: Promise<any> = !doc.supportsStreaming ? appDocsManager.downloadDoc(doc) : Promise.resolve();
Promise.all([deferred, downloadPromise]).then(() => {
//media.autoplay = true; //media.autoplay = true;
//console.log('will set media url:', media, doc, doc.type, doc.url); //console.log('will set media url:', media, doc, doc.type, doc.url);
if(doc.type === 'audio' && doc.supportsStreaming && isSafari) { ((!doc.supportsStreaming ? appDocsManager.downloadDoc(doc) : Promise.resolve()) as Promise<any>).then(() => {
this.handleSafariStreamable(media); if(doc.type === 'audio' && doc.supportsStreaming && isSafari) {
} this.handleSafariStreamable(media);
}
media.src = doc.url;
media.src = doc.url;
});
}, onError); }, onError);
return storage[mid] = media; return storage[mid] = media;

View File

@ -341,6 +341,7 @@ export default class AudioElement extends HTMLElement {
public voiceAsMusic = false; public voiceAsMusic = false;
public searchContext: SearchSuperContext; public searchContext: SearchSuperContext;
public showSender = false; public showSender = false;
public noAutoDownload: boolean;
private attachedHandlers: {[name: string]: any[]} = {}; private attachedHandlers: {[name: string]: any[]} = {};
private onTypeDisconnect: () => void; private onTypeDisconnect: () => void;
@ -464,7 +465,10 @@ export default class AudioElement extends HTMLElement {
}; };
attachClickEvent(this, onClick); attachClickEvent(this, onClick);
onClick();
if(!this.noAutoDownload) {
onClick();
}
} else { } else {
if(doc.supportsStreaming) { if(doc.supportsStreaming) {
onLoad(false); onLoad(false);

View File

@ -30,7 +30,7 @@ import { langPack } from "../../lib/langPack";
import AvatarElement from "../avatar"; import AvatarElement from "../avatar";
import { formatPhoneNumber } from "../misc"; import { formatPhoneNumber } from "../misc";
import { ripple } from "../ripple"; import { ripple } from "../ripple";
import { wrapAlbum, wrapPhoto, wrapVideo, wrapDocument, wrapSticker, wrapPoll, wrapReply, wrapGroupedDocuments } from "../wrappers"; import { wrapAlbum, wrapPhoto, wrapVideo, wrapDocument, wrapSticker, wrapPoll, wrapGroupedDocuments } from "../wrappers";
import { MessageRender } from "./messageRender"; import { MessageRender } from "./messageRender";
import LazyLoadQueue from "../lazyLoadQueue"; import LazyLoadQueue from "../lazyLoadQueue";
import { AppChatsManager } from "../../lib/appManagers/appChatsManager"; import { AppChatsManager } from "../../lib/appManagers/appChatsManager";
@ -1669,6 +1669,8 @@ export default class ChatBubbles {
}).catch(reject); }).catch(reject);
}, 0); }, 0);
}); });
//this.messagesQueuePromise.catch(() => {});
} }
public setBubblePosition(bubble: HTMLElement, message: any, reverse: boolean) { public setBubblePosition(bubble: HTMLElement, message: any, reverse: boolean) {
@ -2033,7 +2035,8 @@ export default class ChatBubbles {
isOut: our, isOut: our,
lazyLoadQueue: this.lazyLoadQueue, lazyLoadQueue: this.lazyLoadQueue,
chat: this.chat, chat: this.chat,
loadPromises loadPromises,
noAutoDownload: this.chat.noAutoDownloadMedia,
}); });
break; break;
@ -2049,7 +2052,8 @@ export default class ChatBubbles {
isOut, isOut,
lazyLoadQueue: this.lazyLoadQueue, lazyLoadQueue: this.lazyLoadQueue,
middleware: this.getMiddleware(), middleware: this.getMiddleware(),
loadPromises loadPromises,
noAutoDownload: this.chat.noAutoDownloadMedia,
}); });
break; break;
@ -2098,12 +2102,14 @@ export default class ChatBubbles {
middleware: this.getMiddleware(), middleware: this.getMiddleware(),
isOut, isOut,
group: CHAT_ANIMATION_GROUP, group: CHAT_ANIMATION_GROUP,
loadPromises loadPromises,
noAutoDownload: this.chat.noAutoDownloadMedia,
}); });
//} //}
} else { } else {
const docDiv = wrapDocument({ const docDiv = wrapDocument({
message message,
noAutoDownload: this.chat.noAutoDownloadMedia,
}); });
preview.append(docDiv); preview.append(docDiv);
preview.classList.add('preview-with-document'); preview.classList.add('preview-with-document');
@ -2166,7 +2172,8 @@ export default class ChatBubbles {
lazyLoadQueue: this.lazyLoadQueue, lazyLoadQueue: this.lazyLoadQueue,
middleware: this.getMiddleware(), middleware: this.getMiddleware(),
loadPromises, loadPromises,
withoutPreloader: isSquare withoutPreloader: isSquare,
noAutoDownload: this.chat.noAutoDownloadMedia,
}); });
} }
@ -2233,7 +2240,8 @@ export default class ChatBubbles {
isOut: our, isOut: our,
lazyLoadQueue: this.lazyLoadQueue, lazyLoadQueue: this.lazyLoadQueue,
chat: this.chat, chat: this.chat,
loadPromises loadPromises,
noAutoDownload: this.chat.noAutoDownloadMedia,
}); });
} else { } else {
const withTail = !isAndroid && !isApple && doc.type !== 'round' && canHaveTail && !withReplies && USE_MEDIA_TAILS; const withTail = !isAndroid && !isApple && doc.type !== 'round' && canHaveTail && !withReplies && USE_MEDIA_TAILS;
@ -2249,7 +2257,8 @@ export default class ChatBubbles {
lazyLoadQueue: this.lazyLoadQueue, lazyLoadQueue: this.lazyLoadQueue,
middleware: this.getMiddleware(), middleware: this.getMiddleware(),
group: CHAT_ANIMATION_GROUP, group: CHAT_ANIMATION_GROUP,
loadPromises loadPromises,
noAutoDownload: this.chat.noAutoDownloadMedia,
}); });
} }
@ -2261,7 +2270,8 @@ export default class ChatBubbles {
bubble, bubble,
messageDiv, messageDiv,
chat: this.chat, chat: this.chat,
loadPromises loadPromises,
noAutoDownload: this.chat.noAutoDownloadMedia
}); });
if(newNameContainer) { if(newNameContainer) {

View File

@ -29,6 +29,7 @@ import { renderImageFromUrl } from "../misc";
import SetTransition from "../singleTransition"; import SetTransition from "../singleTransition";
import { fastRaf } from "../../helpers/schedulers"; import { fastRaf } from "../../helpers/schedulers";
import AppPrivateSearchTab from "../sidebarRight/tabs/search"; import AppPrivateSearchTab from "../sidebarRight/tabs/search";
import type { State } from "../../lib/appManagers/appStateManager";
export type ChatType = 'chat' | 'pinned' | 'replies' | 'discussion' | 'scheduled'; export type ChatType = 'chat' | 'pinned' | 'replies' | 'discussion' | 'scheduled';
@ -54,6 +55,8 @@ export default class Chat extends EventListenerBase<{
public log: ReturnType<typeof logger>; public log: ReturnType<typeof logger>;
public type: ChatType = 'chat'; public type: ChatType = 'chat';
public noAutoDownloadMedia: boolean;
constructor(public appImManager: AppImManager, public appChatsManager: AppChatsManager, public appDocsManager: AppDocsManager, public appInlineBotsManager: AppInlineBotsManager, public appMessagesManager: AppMessagesManager, public appPeersManager: AppPeersManager, public appPhotosManager: AppPhotosManager, public appProfileManager: AppProfileManager, public appStickersManager: AppStickersManager, public appUsersManager: AppUsersManager, public appWebPagesManager: AppWebPagesManager, public appPollsManager: AppPollsManager, public apiManager: ApiManagerProxy, public appDraftsManager: AppDraftsManager, public serverTimeManager: ServerTimeManager, public storage: typeof sessionStorage, public appNotificationsManager: AppNotificationsManager) { constructor(public appImManager: AppImManager, public appChatsManager: AppChatsManager, public appDocsManager: AppDocsManager, public appInlineBotsManager: AppInlineBotsManager, public appMessagesManager: AppMessagesManager, public appPeersManager: AppPeersManager, public appPhotosManager: AppPhotosManager, public appProfileManager: AppProfileManager, public appStickersManager: AppStickersManager, public appUsersManager: AppUsersManager, public appWebPagesManager: AppWebPagesManager, public appPollsManager: AppPollsManager, public apiManager: ApiManagerProxy, public appDraftsManager: AppDraftsManager, public serverTimeManager: ServerTimeManager, public storage: typeof sessionStorage, public appNotificationsManager: AppNotificationsManager) {
super(); super();
@ -210,6 +213,7 @@ export default class Chat extends EventListenerBase<{
appSidebarRight.sharedMediaTab.setPeer(peerId, this.threadId); appSidebarRight.sharedMediaTab.setPeer(peerId, this.threadId);
this.input.clearHelper(); // костыль this.input.clearHelper(); // костыль
this.selection.cleanup(); // TODO: REFACTOR !!!!!! this.selection.cleanup(); // TODO: REFACTOR !!!!!!
this.setAutoDownloadMedia();
} }
this.peerChanged = samePeer; this.peerChanged = samePeer;
@ -238,6 +242,25 @@ export default class Chat extends EventListenerBase<{
return result; return result;
} }
public setAutoDownloadMedia() {
let type: keyof State['settings']['autoDownload'];
if(this.peerId < 0) {
if(this.appPeersManager.isBroadcast(this.peerId)) {
type = 'channels';
} else {
type = 'groups';
}
} else {
if(this.appUsersManager.isContact(this.peerId)) {
type = 'contacts';
} else {
type = 'private';
}
}
this.noAutoDownloadMedia = !rootScope.settings.autoDownload[type];
}
public setMessageId(messageId?: number) { public setMessageId(messageId?: number) {
return this.setPeer(this.peerId, messageId); return this.setPeer(this.peerId, messageId);
} }

View File

@ -81,7 +81,9 @@ export class LazyLoadQueueBase {
//await item.load(item.div); //await item.load(item.div);
await this.loadItem(item); await this.loadItem(item);
} catch(err) { } catch(err) {
this.log.error('loadMediaQueue error:', err/* , item */); if(err !== 'NO_ENTRY_FOUND') {
this.log.error('loadMediaQueue error:', err/* , item */);
}
} }
this.inProcess.delete(item); this.inProcess.delete(item);

View File

@ -22,7 +22,7 @@ export default class ProgressivePreloader {
private tryAgainOnFail = true; private tryAgainOnFail = true;
private attachMethod: 'append' | 'prepend' = 'append'; private attachMethod: 'append' | 'prepend' = 'append';
private loadFunc: () => {download: CancellablePromise<any>}; public loadFunc: () => {download: CancellablePromise<any>};
private totalLength: number; private totalLength: number;

View File

@ -103,7 +103,7 @@ export default class AppGeneralSettingsTab extends SliderSuperTab {
{ {
const container = section('Auto-Download Media'); const container = section('Auto-Download Media');
container.classList.add('sidebar-left-section-disabled'); //container.classList.add('sidebar-left-section-disabled');
const contactsCheckboxField = new CheckboxField({ const contactsCheckboxField = new CheckboxField({
text: 'Contacts', text: 'Contacts',

View File

@ -9,6 +9,7 @@ import AppGeneralSettingsTab from "./generalSettings";
import AppEditProfileTab from "./editProfile"; import AppEditProfileTab from "./editProfile";
import AppChatFoldersTab from "./chatFolders"; import AppChatFoldersTab from "./chatFolders";
import AppNotificationsTab from "./notifications"; import AppNotificationsTab from "./notifications";
import PeerTitle from "../../peerTitle";
//import AppMediaViewer from "../../appMediaViewerNew"; //import AppMediaViewer from "../../appMediaViewerNew";
export default class AppSettingsTab extends SliderSuperTab { export default class AppSettingsTab extends SliderSuperTab {
@ -120,7 +121,7 @@ export default class AppSettingsTab extends SliderSuperTab {
}); });
this.buttons.general.addEventListener('click', () => { this.buttons.general.addEventListener('click', () => {
new AppGeneralSettingsTab(this.slider as any).open(); new AppGeneralSettingsTab(this.slider).open();
}); });
this.buttons.notifications.addEventListener('click', () => { this.buttons.notifications.addEventListener('click', () => {
@ -136,7 +137,7 @@ export default class AppSettingsTab extends SliderSuperTab {
let user = appUsersManager.getSelf(); let user = appUsersManager.getSelf();
this.avatarElem.setAttribute('peer', '' + user.id); this.avatarElem.setAttribute('peer', '' + user.id);
this.nameDiv.innerHTML = user.rFullName || ''; this.nameDiv.append(new PeerTitle({peerId: user.id}).element);
this.phoneDiv.innerHTML = user.rPhone || ''; this.phoneDiv.innerHTML = user.rPhone || '';
} }

View File

@ -5,13 +5,12 @@ import { deferredPromise } from '../helpers/cancellablePromise';
import { formatDateAccordingToToday, months } from '../helpers/date'; import { formatDateAccordingToToday, months } from '../helpers/date';
import mediaSizes from '../helpers/mediaSizes'; import mediaSizes from '../helpers/mediaSizes';
import { formatBytes } from '../helpers/number'; import { formatBytes } from '../helpers/number';
import { isAppleMobile, isSafari } from '../helpers/userAgent'; import { isSafari } from '../helpers/userAgent';
import { PhotoSize } from '../layer'; import { PhotoSize } from '../layer';
import appDocsManager, { MyDocument } from "../lib/appManagers/appDocsManager"; import appDocsManager, { MyDocument } from "../lib/appManagers/appDocsManager";
import appMessagesManager from '../lib/appManagers/appMessagesManager'; import appMessagesManager from '../lib/appManagers/appMessagesManager';
import appPhotosManager, { MyPhoto } from '../lib/appManagers/appPhotosManager'; import appPhotosManager, { MyPhoto } from '../lib/appManagers/appPhotosManager';
import LottieLoader from '../lib/lottieLoader'; import LottieLoader from '../lib/lottieLoader';
import VideoPlayer from '../lib/mediaPlayer';
import { attachClickEvent, cancelEvent, isInDOM } from "../helpers/dom"; import { attachClickEvent, cancelEvent, isInDOM } from "../helpers/dom";
import webpWorkerController from '../lib/webp/webpWorkerController'; import webpWorkerController from '../lib/webp/webpWorkerController';
import animationIntersector from './animationIntersector'; import animationIntersector from './animationIntersector';
@ -34,7 +33,7 @@ import { animateSingle } from '../helpers/animation';
const MAX_VIDEO_AUTOPLAY_SIZE = 50 * 1024 * 1024; // 50 MB const MAX_VIDEO_AUTOPLAY_SIZE = 50 * 1024 * 1024; // 50 MB
export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTail, isOut, middleware, lazyLoadQueue, noInfo, group, onlyPreview, withoutPreloader, loadPromises, noPlayButton}: { export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTail, isOut, middleware, lazyLoadQueue, noInfo, group, onlyPreview, withoutPreloader, loadPromises, noPlayButton, noAutoDownload}: {
doc: MyDocument, doc: MyDocument,
container?: HTMLElement, container?: HTMLElement,
message?: any, message?: any,
@ -49,7 +48,8 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
group?: string, group?: string,
onlyPreview?: boolean, onlyPreview?: boolean,
withoutPreloader?: boolean, withoutPreloader?: boolean,
loadPromises?: Promise<any>[] loadPromises?: Promise<any>[],
noAutoDownload?: boolean,
}) { }) {
const isAlbumItem = !(boxWidth && boxHeight); const isAlbumItem = !(boxWidth && boxHeight);
const canAutoplay = doc.type !== 'video' || (doc.size <= MAX_VIDEO_AUTOPLAY_SIZE && !isAlbumItem); const canAutoplay = doc.type !== 'video' || (doc.size <= MAX_VIDEO_AUTOPLAY_SIZE && !isAlbumItem);
@ -94,7 +94,8 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
lazyLoadQueue, lazyLoadQueue,
middleware, middleware,
withoutPreloader, withoutPreloader,
loadPromises loadPromises,
noAutoDownload
}); });
res.thumb = photoRes; res.thumb = photoRes;
@ -112,7 +113,7 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
video.setAttribute('playsinline', 'true'); video.setAttribute('playsinline', 'true');
video.muted = true; video.muted = true;
if(doc.type === 'round') { if(doc.type === 'round') {
const globalVideo = appMediaPlaybackController.addMedia(message.peerId, doc, message.mid) as HTMLVideoElement; const globalVideo = appMediaPlaybackController.addMedia(message.peerId, doc, message.mid, !noAutoDownload) as HTMLVideoElement;
const divRound = document.createElement('div'); const divRound = document.createElement('div');
divRound.classList.add('media-round', 'z-depth-1'); divRound.classList.add('media-round', 'z-depth-1');
@ -230,7 +231,8 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
lazyLoadQueue, lazyLoadQueue,
middleware, middleware,
withoutPreloader: true, withoutPreloader: true,
loadPromises loadPromises,
noAutoDownload
}); });
res.thumb = photoRes; res.thumb = photoRes;
@ -259,85 +261,97 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
container.append(video); container.append(video);
} }
const loadVideo = async() => { let preloader: ProgressivePreloader;
if(middleware && !middleware()) { if(message?.media?.preloader) { // means upload
return; preloader = message.media.preloader as ProgressivePreloader;
preloader.attach(container, false);
noAutoDownload = undefined;
} else if(!doc.downloaded && !doc.supportsStreaming) {
preloader = new ProgressivePreloader({
attachMethod: 'prepend'
});
} else if(doc.supportsStreaming) {
preloader = new ProgressivePreloader({
cancelable: false,
attachMethod: 'prepend'
});
}
let f = noAutoDownload && photoRes?.preloader?.loadFunc;
const load = () => {
if(preloader && noAutoDownload && !withoutPreloader) {
preloader.construct();
preloader.setManual();
} }
let loadPromise: Promise<any> = Promise.resolve(); let loadPromise: Promise<any> = Promise.resolve();
let preloader: ProgressivePreloader; if(preloader) {
if(message?.media?.preloader) { // means upload if(!doc.downloaded && !doc.supportsStreaming) {
preloader = message.media.preloader as ProgressivePreloader; const promise = loadPromise = appDocsManager.downloadDoc(doc, lazyLoadQueue?.queueId, noAutoDownload);
preloader.attach(container, false); preloader.attach(container, false, promise);
} else if(!doc.downloaded && !doc.supportsStreaming) { } else if(doc.supportsStreaming) {
const promise = loadPromise = appDocsManager.downloadDoc(doc, lazyLoadQueue?.queueId); if(noAutoDownload) {
preloader = new ProgressivePreloader({ loadPromise = Promise.reject();
attachMethod: 'prepend' } else {
}); preloader.attach(container, false, null);
preloader.attach(container, true, promise); video.addEventListener(isSafari ? 'timeupdate' : 'canplay', () => {
preloader.detach();
//if(doc.type !== 'round') { }, {once: true});
await promise;
if(middleware && !middleware()) {
return;
} }
//} }
} else if(doc.supportsStreaming) {
preloader = new ProgressivePreloader({
cancelable: false,
attachMethod: 'prepend'
});
preloader.attach(container, false, null);
video.addEventListener(isSafari ? 'timeupdate' : 'canplay', () => {
preloader.detach();
}, {once: true});
} }
/* if(doc.type === 'round') { if(!noAutoDownload && f) {
return; f();
} */ f = null;
}
//console.log('loaded doc:', doc, doc.url, container);
noAutoDownload = undefined;
const deferred = deferredPromise<void>(); const deferred = deferredPromise<void>();
loadPromise.then(() => {
if(middleware && !middleware()) {
deferred.resolve();
return;
}
if(doc.type === 'round') {
appMediaPlaybackController.resolveWaitingForLoadMedia(message.peerId, message.mid);
}
//if(doc.type === 'gif'/* || true */) {
onVideoLoad(video).then(() => { onVideoLoad(video).then(() => {
/* if(!video.paused) {
video.pause();
} */
if(group) { if(group) {
animationIntersector.addAnimation(video, group); animationIntersector.addAnimation(video, group);
} }
// test lazyLoadQueue deferred.resolve();
//setTimeout(() => {
deferred.resolve();
//}, 5000);
}); });
//}
if(doc.type === 'video') {
if(doc.type === 'video') { video.addEventListener('timeupdate', () => {
video.addEventListener('timeupdate', () => { spanTime.innerText = (video.duration - video.currentTime + '').toHHMMSS(false);
spanTime.innerText = (video.duration - video.currentTime + '').toHHMMSS(false); });
}
video.addEventListener('error', (e) => {
deferred.resolve();
}); });
}
video.muted = true;
video.loop = true;
//video.play();
video.autoplay = true;
video.addEventListener('error', (e) => { renderImageFromUrl(video, doc.url);
deferred.resolve(); }, () => {});
});
video.muted = true; return {download: loadPromise, render: deferred};
video.loop = true;
//video.play();
video.autoplay = true;
renderImageFromUrl(video, doc.url);
return Promise.all([loadPromise, deferred]);
}; };
if(preloader) {
preloader.setDownloadFunction(load);
}
/* if(doc.size >= 20e6 && !doc.downloaded) { /* if(doc.size >= 20e6 && !doc.downloaded) {
let downloadDiv = document.createElement('div'); let downloadDiv = document.createElement('div');
downloadDiv.classList.add('download'); downloadDiv.classList.add('download');
@ -356,7 +370,7 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
return; return;
} */ } */
res.loadPromise = !lazyLoadQueue ? loadVideo() : (lazyLoadQueue.push({div: container, load: loadVideo}), Promise.resolve()); res.loadPromise = !lazyLoadQueue ? load().render : (lazyLoadQueue.push({div: container, load: () => load().render}), Promise.resolve());
return res; return res;
} }
@ -375,14 +389,15 @@ export const formatDate = (timestamp: number, monthShort = false, withYear = tru
return str + ' at ' + date.getHours() + ':' + ('0' + date.getMinutes()).slice(-2); return str + ' at ' + date.getHours() + ':' + ('0' + date.getMinutes()).slice(-2);
}; };
export function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showSender, searchContext, loadPromises}: { export function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showSender, searchContext, loadPromises, noAutoDownload}: {
message: any, message: any,
withTime?: boolean, withTime?: boolean,
fontWeight?: number, fontWeight?: number,
voiceAsMusic?: boolean, voiceAsMusic?: boolean,
showSender?: boolean, showSender?: boolean,
searchContext?: SearchSuperContext, searchContext?: SearchSuperContext,
loadPromises?: Promise<any>[] loadPromises?: Promise<any>[],
noAutoDownload?: boolean,
}): HTMLElement { }): HTMLElement {
if(!fontWeight) fontWeight = 500; if(!fontWeight) fontWeight = 500;
@ -394,6 +409,7 @@ export function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showS
audioElement.setAttribute('peer-id', '' + message.peerId); audioElement.setAttribute('peer-id', '' + message.peerId);
audioElement.withTime = withTime; audioElement.withTime = withTime;
audioElement.message = message; audioElement.message = message;
audioElement.noAutoDownload = noAutoDownload;
if(voiceAsMusic) audioElement.voiceAsMusic = voiceAsMusic; if(voiceAsMusic) audioElement.voiceAsMusic = voiceAsMusic;
if(searchContext) audioElement.searchContext = searchContext; if(searchContext) audioElement.searchContext = searchContext;
@ -590,7 +606,7 @@ function wrapMediaWithTail(photo: MyPhoto | MyDocument, message: {mid: number, m
return img; return img;
} }
export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withTail, isOut, lazyLoadQueue, middleware, size, withoutPreloader, loadPromises}: { export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withTail, isOut, lazyLoadQueue, middleware, size, withoutPreloader, loadPromises, noAutoDownload}: {
photo: MyPhoto | MyDocument, photo: MyPhoto | MyDocument,
message: any, message: any,
container: HTMLElement, container: HTMLElement,
@ -602,7 +618,8 @@ export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withT
middleware?: () => boolean, middleware?: () => boolean,
size?: PhotoSize, size?: PhotoSize,
withoutPreloader?: boolean, withoutPreloader?: boolean,
loadPromises?: Promise<any>[] loadPromises?: Promise<any>[],
noAutoDownload?: boolean,
}) { }) {
if(!((photo as MyPhoto).sizes || (photo as MyDocument).thumbs)) { if(!((photo as MyPhoto).sizes || (photo as MyDocument).thumbs)) {
if(boxWidth && boxHeight && photo._ === 'document') { if(boxWidth && boxHeight && photo._ === 'document') {
@ -617,7 +634,8 @@ export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withT
images: { images: {
thumb: null, thumb: null,
full: null full: null
} },
preloader: null
}; };
} }
@ -660,6 +678,7 @@ export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withT
if(message?.media?.preloader) { // means upload if(message?.media?.preloader) { // means upload
preloader = message.media.preloader; preloader = message.media.preloader;
preloader.attach(container); preloader.attach(container);
noAutoDownload = undefined;
} else { } else {
preloader = new ProgressivePreloader({ preloader = new ProgressivePreloader({
attachMethod: 'prepend' attachMethod: 'prepend'
@ -669,7 +688,9 @@ export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withT
const getDownloadPromise = () => { const getDownloadPromise = () => {
const promise = photo._ === 'document' && photo.mime_type === 'image/gif' ? const promise = photo._ === 'document' && photo.mime_type === 'image/gif' ?
appDocsManager.downloadDoc(photo, /* undefined, */lazyLoadQueue?.queueId) : appDocsManager.downloadDoc(photo, /* undefined, */lazyLoadQueue?.queueId) :
appPhotosManager.preloadPhoto(photo, size, lazyLoadQueue?.queueId); appPhotosManager.preloadPhoto(photo, size, lazyLoadQueue?.queueId, noAutoDownload);
noAutoDownload = undefined;
return promise; return promise;
}; };
@ -701,13 +722,20 @@ export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withT
let loadPromise: Promise<any>; let loadPromise: Promise<any>;
const load = () => { const load = () => {
if(noAutoDownload && !withoutPreloader) {
preloader.construct();
preloader.setManual();
}
const promise = getDownloadPromise(); const promise = getDownloadPromise();
if(!cacheContext.downloaded && !withoutPreloader && (size as PhotoSize.photoSize).w >= 150 && (size as PhotoSize.photoSize).h >= 150) { if(!cacheContext.downloaded && !withoutPreloader && (size as PhotoSize.photoSize).w >= 150 && (size as PhotoSize.photoSize).h >= 150) {
preloader.attach(container, false, promise); preloader.attach(container, false, promise);
} }
return {download: promise, render: promise.then(onLoad)}; const renderPromise = promise.then(onLoad);
renderPromise.catch(() => {});
return {download: promise, render: renderPromise};
}; };
preloader.setDownloadFunction(load); preloader.setDownloadFunction(load);
@ -716,7 +744,11 @@ export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withT
loadThumbPromise = loadPromise = load().render; loadThumbPromise = loadPromise = load().render;
} else { } else {
if(!lazyLoadQueue) loadPromise = load().render; if(!lazyLoadQueue) loadPromise = load().render;
else lazyLoadQueue.push({div: container, load: () => load().download}); /* else if(noAutoDownload) {
preloader.construct();
preloader.setManual();
preloader.attach(container);
} */ else lazyLoadQueue.push({div: container, load: () => load().download});
} }
if(loadPromises && loadThumbPromise) { if(loadPromises && loadThumbPromise) {
@ -731,7 +763,8 @@ export function wrapPhoto({photo, message, container, boxWidth, boxHeight, withT
images: { images: {
thumb: thumbImage, thumb: thumbImage,
full: image full: image
} },
preloader
}; };
} }
@ -1089,7 +1122,7 @@ export function prepareAlbum(options: {
} */ } */
} }
export function wrapAlbum({groupId, attachmentDiv, middleware, uploading, lazyLoadQueue, isOut, chat, loadPromises}: { export function wrapAlbum({groupId, attachmentDiv, middleware, uploading, lazyLoadQueue, isOut, chat, loadPromises, noAutoDownload}: {
groupId: string, groupId: string,
attachmentDiv: HTMLElement, attachmentDiv: HTMLElement,
middleware?: () => boolean, middleware?: () => boolean,
@ -1097,7 +1130,8 @@ export function wrapAlbum({groupId, attachmentDiv, middleware, uploading, lazyLo
uploading?: boolean, uploading?: boolean,
isOut: boolean, isOut: boolean,
chat: Chat, chat: Chat,
loadPromises?: Promise<any>[] loadPromises?: Promise<any>[],
noAutoDownload?: boolean,
}) { }) {
const items: {size: PhotoSize.photoSize, media: any, message: any}[] = []; const items: {size: PhotoSize.photoSize, media: any, message: any}[] = [];
@ -1142,7 +1176,8 @@ export function wrapAlbum({groupId, attachmentDiv, middleware, uploading, lazyLo
lazyLoadQueue, lazyLoadQueue,
middleware, middleware,
size, size,
loadPromises loadPromises,
noAutoDownload
}); });
} else { } else {
wrapVideo({ wrapVideo({
@ -1155,20 +1190,22 @@ export function wrapAlbum({groupId, attachmentDiv, middleware, uploading, lazyLo
isOut, isOut,
lazyLoadQueue, lazyLoadQueue,
middleware, middleware,
loadPromises loadPromises,
noAutoDownload
}); });
} }
}); });
} }
export function wrapGroupedDocuments({albumMustBeRenderedFull, message, bubble, messageDiv, chat, loadPromises}: { export function wrapGroupedDocuments({albumMustBeRenderedFull, message, bubble, messageDiv, chat, loadPromises, noAutoDownload}: {
albumMustBeRenderedFull: boolean, albumMustBeRenderedFull: boolean,
message: any, message: any,
messageDiv: HTMLElement, messageDiv: HTMLElement,
bubble: HTMLElement, bubble: HTMLElement,
uploading?: boolean, uploading?: boolean,
chat: Chat, chat: Chat,
loadPromises?: Promise<any>[] loadPromises?: Promise<any>[],
noAutoDownload?: boolean,
}) { }) {
let nameContainer: HTMLElement; let nameContainer: HTMLElement;
const mids = albumMustBeRenderedFull ? chat.getMidsByMid(message.mid) : [message.mid]; const mids = albumMustBeRenderedFull ? chat.getMidsByMid(message.mid) : [message.mid];
@ -1180,7 +1217,8 @@ export function wrapGroupedDocuments({albumMustBeRenderedFull, message, bubble,
const message = chat.getMessage(mid); const message = chat.getMessage(mid);
const div = wrapDocument({ const div = wrapDocument({
message, message,
loadPromises loadPromises,
noAutoDownload
}); });
const container = document.createElement('div'); const container = document.createElement('div');

View File

@ -214,7 +214,7 @@ export class AppDocsManager {
}; };
} }
public getFileDownloadOptions(doc: MyDocument, thumb?: PhotoSize.photoSize, queueId?: number) { public getFileDownloadOptions(doc: MyDocument, thumb?: PhotoSize.photoSize, queueId?: number, onlyCache?: boolean) {
const inputFileLocation = this.getInput(doc, thumb?.type); const inputFileLocation = this.getInput(doc, thumb?.type);
let mimeType: string; let mimeType: string;
@ -230,7 +230,8 @@ export class AppDocsManager {
size: thumb ? thumb.size : doc.size, size: thumb ? thumb.size : doc.size,
mimeType: mimeType, mimeType: mimeType,
fileName: doc.file_name, fileName: doc.file_name,
queueId queueId,
onlyCache
}; };
} }
@ -278,7 +279,7 @@ export class AppDocsManager {
return getFileNameByLocation(this.getInput(doc, thumbSize), {fileName: doc.file_name}); return getFileNameByLocation(this.getInput(doc, thumbSize), {fileName: doc.file_name});
} }
public downloadDoc(doc: MyDocument, queueId?: number): DownloadBlob { public downloadDoc(doc: MyDocument, queueId?: number, onlyCache?: boolean): DownloadBlob {
const fileName = this.getInputFileName(doc); const fileName = this.getInputFileName(doc);
let download: DownloadBlob = appDownloadManager.getDownload(fileName); let download: DownloadBlob = appDownloadManager.getDownload(fileName);
@ -286,15 +287,15 @@ export class AppDocsManager {
return download; return download;
} }
const downloadOptions = this.getFileDownloadOptions(doc, undefined, queueId); const downloadOptions = this.getFileDownloadOptions(doc, undefined, queueId, onlyCache);
download = appDownloadManager.download(downloadOptions); download = appDownloadManager.download(downloadOptions);
const originalPromise = download; const originalPromise = download;
originalPromise.then((blob) => { originalPromise.then((blob) => {
doc.url = URL.createObjectURL(blob); doc.url = URL.createObjectURL(blob);
doc.downloaded = true; doc.downloaded = true;
}); }, () => {});
if(doc.type === 'voice' && !opusDecodeController.isPlaySupported()) { if(doc.type === 'voice' && !opusDecodeController.isPlaySupported()) {
download = originalPromise.then(async(blob) => { download = originalPromise.then(async(blob) => {
const reader = new FileReader(); const reader = new FileReader();

View File

@ -56,8 +56,7 @@ export class AppDownloadManager {
error.name = 'AbortError'; error.name = 'AbortError';
apiManager.cancelDownload(fileName); apiManager.cancelDownload(fileName);
this.clearDownload(fileName);
deferred.reject(error); deferred.reject(error);
deferred.cancel = () => {}; deferred.cancel = () => {};
/* } catch(err) { /* } catch(err) {
@ -70,6 +69,10 @@ export class AppDownloadManager {
delete this.progressCallbacks[fileName]; delete this.progressCallbacks[fileName];
}); });
deferred.catch(() => {
this.clearDownload(fileName);
});
return this.downloads[fileName] = deferred; return this.downloads[fileName] = deferred;
} }
@ -121,11 +124,14 @@ export class AppDownloadManager {
const tryDownload = (): Promise<unknown> => { const tryDownload = (): Promise<unknown> => {
//return Promise.resolve(); //return Promise.resolve();
if(!apiManager.worker) { if(!apiManager.worker || options.onlyCache) {
return this.cacheStorage.getFile(fileName).then((blob) => { const promise = this.cacheStorage.getFile(fileName).then((blob) => {
if(blob.size < options.size) throw 'wrong size'; if(blob.size < options.size) throw 'wrong size';
else deferred.resolve(blob); else deferred.resolve(blob);
}).catch(() => { });
if(options.onlyCache) return promise.catch(onError);
return promise.catch(() => {
return apiManager.downloadFile(options).then(deferred.resolve, onError); return apiManager.downloadFile(options).then(deferred.resolve, onError);
}); });
} else { } else {
@ -237,4 +243,4 @@ export class AppDownloadManager {
} }
} }
export default new AppDownloadManager(); export default new AppDownloadManager();

View File

@ -161,7 +161,7 @@ export class AppImManager {
}); });
this.setSettings(); this.setSettings();
rootScope.on('settings_updated', () => this.setSettings()); rootScope.on('settings_updated', this.setSettings);
useHeavyAnimationCheck(() => { useHeavyAnimationCheck(() => {
animationIntersector.setOnlyOnePlayableGroup('lock'); animationIntersector.setOnlyOnePlayableGroup('lock');
@ -237,7 +237,7 @@ export class AppImManager {
return sessionStorage.getFromCache('chatPositions')[key]; return sessionStorage.getFromCache('chatPositions')[key];
} */ } */
private setSettings() { private setSettings = () => {
document.documentElement.style.setProperty('--messages-text-size', rootScope.settings.messagesTextSize + 'px'); document.documentElement.style.setProperty('--messages-text-size', rootScope.settings.messagesTextSize + 'px');
if(rootScope.settings.background.highlightningColor) { if(rootScope.settings.background.highlightningColor) {
@ -261,7 +261,11 @@ export class AppImManager {
lottieLoader.setLoop(rootScope.settings.stickers.loop); lottieLoader.setLoop(rootScope.settings.stickers.loop);
animationIntersector.checkAnimations(false); animationIntersector.checkAnimations(false);
}
for(const chat of this.chats) {
chat.setAutoDownloadMedia();
}
};
// * не могу использовать тут TransitionSlider, так как мне нужен отрисованный блок рядом // * не могу использовать тут TransitionSlider, так как мне нужен отрисованный блок рядом
// * (или под текущим чатом) чтобы правильно отрендерить чат (напр. scrollTop) // * (или под текущим чатом) чтобы правильно отрендерить чат (напр. scrollTop)

View File

@ -6,7 +6,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 } from "../../helpers/string"; import { splitStringByLength, limitSymbols } from "../../helpers/string";
import { ChatFull, Dialog as MTDialog, DialogPeer, DocumentAttribute, InputMedia, InputMessage, InputPeerNotifySettings, InputSingleMedia, Message, MessageAction, MessageEntity, MessageFwdHeader, MessageReplies, MessageReplyHeader, MessagesDialogs, MessagesFilter, MessagesMessages, MessagesPeerDialogs, MethodDeclMap, NotifyPeer, PeerNotifySettings, PhotoSize, SendMessageAction, Update } from "../../layer"; import { Chat, ChatFull, Dialog as MTDialog, DialogPeer, DocumentAttribute, InputMedia, InputMessage, InputPeerNotifySettings, InputSingleMedia, Message, MessageAction, MessageEntity, MessageFwdHeader, MessageReplies, MessageReplyHeader, MessagesDialogs, MessagesFilter, MessagesMessages, MessagesPeerDialogs, MethodDeclMap, NotifyPeer, PeerNotifySettings, PhotoSize, SendMessageAction, Update } from "../../layer";
import { InvokeApiOptions } from "../../types"; import { InvokeApiOptions } from "../../types";
import { langPack } from "../langPack"; import { langPack } from "../langPack";
import { logger, LogLevels } from "../logger"; import { logger, LogLevels } from "../logger";
@ -1759,6 +1759,10 @@ export class AppMessagesManager {
// ! нужно передавать folderId, так как по папке !== 0 нет свойства folder_id // ! нужно передавать folderId, так как по папке !== 0 нет свойства folder_id
this.saveConversation(dialog, dialog.folder_id ?? folderId); this.saveConversation(dialog, dialog.folder_id ?? folderId);
if(dialog.peerId === undefined) {
return;
}
/* if(dialog.peerId === -1213511294) { /* if(dialog.peerId === -1213511294) {
this.log.error('lun bot', folderId, d); this.log.error('lun bot', folderId, d);
} */ } */
@ -2894,7 +2898,7 @@ export class AppMessagesManager {
} }
/** /**
* Won't save migrated from peer * Won't save migrated from peer, forbidden peers, left and kicked
*/ */
public saveConversation(dialog: Dialog, folderId = 0) { public saveConversation(dialog: Dialog, folderId = 0) {
const peerId = appPeersManager.getPeerId(dialog.peer); const peerId = appPeersManager.getPeerId(dialog.peer);
@ -2908,6 +2912,14 @@ export class AppMessagesManager {
} }
const channelId = appPeersManager.isChannel(peerId) ? -peerId : 0; const channelId = appPeersManager.isChannel(peerId) ? -peerId : 0;
if(peerId < 0) {
const chat: Chat = appChatsManager.getChat(-peerId);
if(chat._ === 'channelForbidden' || chat._ === 'chatForbidden' || (chat as Chat.chat).pFlags.left || (chat as Chat.chat).pFlags.kicked) {
return false;
}
}
const peerText = appPeersManager.getPeerSearchText(peerId); const peerText = appPeersManager.getPeerSearchText(peerId);
searchIndexManager.indexObject(peerId, peerText, this.dialogsIndex); searchIndexManager.indexObject(peerId, peerText, this.dialogsIndex);

View File

@ -256,7 +256,7 @@ export class AppPhotosManager {
return null; return null;
} }
public getPhotoDownloadOptions(photo: MyPhoto | MyDocument, photoSize: PhotoSize, queueId?: number) { public getPhotoDownloadOptions(photo: MyPhoto | MyDocument, photoSize: PhotoSize, queueId?: number, onlyCache?: boolean) {
const isMyDocument = photo._ === 'document'; const isMyDocument = photo._ === 'document';
if(!photoSize || photoSize._ === 'photoSizeEmpty') { if(!photoSize || photoSize._ === 'photoSizeEmpty') {
@ -274,7 +274,7 @@ export class AppPhotosManager {
thumb_size: photoSize.type thumb_size: photoSize.type
} : (photoSize as PhotoSize.photoSize).location; } : (photoSize as PhotoSize.photoSize).location;
return {dcId: photo.dc_id, location, size: isPhoto ? (photoSize as PhotoSize.photoSize).size : undefined, queueId}; return {dcId: photo.dc_id, location, size: isPhoto ? (photoSize as PhotoSize.photoSize).size : undefined, queueId, onlyCache};
} }
/* public getPhotoURL(photo: MTPhoto | MTMyDocument, photoSize: MTPhotoSize) { /* public getPhotoURL(photo: MTPhoto | MTMyDocument, photoSize: MTPhotoSize) {
@ -297,7 +297,7 @@ export class AppPhotosManager {
return isDownloaded; return isDownloaded;
} }
public preloadPhoto(photoId: any, photoSize?: PhotoSize, queueId?: number): CancellablePromise<Blob> { public preloadPhoto(photoId: any, photoSize?: PhotoSize, queueId?: number, onlyCache?: boolean): CancellablePromise<Blob> {
const photo = this.getPhoto(photoId); const photo = this.getPhoto(photoId);
// @ts-ignore // @ts-ignore
@ -317,7 +317,7 @@ export class AppPhotosManager {
return Promise.resolve() as any; return Promise.resolve() as any;
} }
const downloadOptions = this.getPhotoDownloadOptions(photo, photoSize, queueId); const downloadOptions = this.getPhotoDownloadOptions(photo, photoSize, queueId, onlyCache);
const fileName = getFileNameByLocation(downloadOptions.location); const fileName = getFileNameByLocation(downloadOptions.location);
@ -342,7 +342,7 @@ export class AppPhotosManager {
(photoSize as any).url = url; (photoSize as any).url = url;
return blob; return blob;
}); }).catch(() => {});
return download; return download;
} }

View File

@ -25,7 +25,8 @@ export type DownloadOptions = {
fileName?: string, fileName?: string,
mimeType?: string, mimeType?: string,
limitPart?: number, limitPart?: number,
queueId?: number queueId?: number,
onlyCache?: boolean,
}; };
type MyUploadFile = UploadFile.uploadFile; type MyUploadFile = UploadFile.uploadFile;