Send multiple files
Refactor sendAlbum
This commit is contained in:
parent
2580c4e720
commit
eda9f5a306
@ -30,7 +30,7 @@ import AudioElement from "../audio";
|
||||
import AvatarElement from "../avatar";
|
||||
import { formatPhoneNumber } from "../misc";
|
||||
import { ripple } from "../ripple";
|
||||
import { wrapAlbum, wrapPhoto, wrapVideo, wrapDocument, wrapSticker, wrapPoll, wrapReply } from "../wrappers";
|
||||
import { wrapAlbum, wrapPhoto, wrapVideo, wrapDocument, wrapSticker, wrapPoll, wrapReply, wrapGroupedDocuments } from "../wrappers";
|
||||
import { MessageRender } from "./messageRender";
|
||||
import LazyLoadQueue from "../lazyLoadQueue";
|
||||
import { AppChatsManager } from "../../lib/appManagers/appChatsManager";
|
||||
@ -196,20 +196,18 @@ export default class ChatBubbles {
|
||||
const message = this.appMessagesManager.getMessage(mid);
|
||||
|
||||
appSidebarRight.sharedMediaTab.renderNewMessages(message.peerID, [mid]);
|
||||
|
||||
const bubble = this.bubbles[tempID];
|
||||
if(bubble) {
|
||||
this.bubbles[mid] = bubble;
|
||||
|
||||
const mounted = this.getMountedBubble(tempID) || this.getMountedBubble(mid);
|
||||
if(mounted) {
|
||||
const bubble = mounted.bubble;
|
||||
//this.bubbles[mid] = bubble;
|
||||
|
||||
/////this.log('message_sent', bubble);
|
||||
|
||||
// set new mids to album items for mediaViewer
|
||||
if(message.grouped_id) {
|
||||
const items = bubble.querySelectorAll('.grouped-item');
|
||||
const groupIDs = getObjectKeysAndSort(appMessagesManager.groupedMessagesStorage[message.grouped_id]);
|
||||
(Array.from(items) as HTMLElement[]).forEach((item, idx) => {
|
||||
item.dataset.mid = '' + groupIDs[idx];
|
||||
});
|
||||
const item = bubble.querySelector(`.grouped-item[data-mid="${tempID}"]`) as HTMLElement;
|
||||
item.dataset.mid = '' + mid;
|
||||
}
|
||||
|
||||
if(message.media?.poll) {
|
||||
@ -222,16 +220,16 @@ export default class ChatBubbles {
|
||||
}
|
||||
|
||||
if(['audio', 'voice'].includes(message.media?.document?.type)) {
|
||||
const audio = bubble.querySelector('audio-element');
|
||||
const audio = bubble.querySelector(`audio-element[message-id="${tempID}"]`);
|
||||
audio.setAttribute('doc-id', message.media.document.id);
|
||||
audio.setAttribute('message-id', '' + mid);
|
||||
}
|
||||
|
||||
bubble.classList.remove('is-sending');
|
||||
/* bubble.classList.remove('is-sending');
|
||||
bubble.classList.add('is-sent');
|
||||
bubble.dataset.mid = '' + mid;
|
||||
|
||||
this.bubbleGroups.removeBubble(bubble, tempID);
|
||||
this.bubbleGroups.removeBubble(bubble, tempID); */
|
||||
|
||||
if(message.media?.webpage && !bubble.querySelector('.web')) {
|
||||
const mounted = this.getMountedBubble(mid);
|
||||
@ -239,11 +237,23 @@ export default class ChatBubbles {
|
||||
this.renderMessage(mounted.message, true, false, mounted.bubble, false);
|
||||
}
|
||||
|
||||
delete this.bubbles[tempID];
|
||||
//delete this.bubbles[tempID];
|
||||
} else {
|
||||
this.log.warn('message_sent there is no bubble', e.detail);
|
||||
}
|
||||
|
||||
if(this.bubbles[tempID]) {
|
||||
const bubble = this.bubbles[tempID];
|
||||
this.bubbles[mid] = bubble;
|
||||
delete this.bubbles[tempID];
|
||||
|
||||
bubble.classList.remove('is-sending');
|
||||
bubble.classList.add('is-sent');
|
||||
bubble.dataset.mid = '' + mid;
|
||||
|
||||
this.bubbleGroups.removeBubble(bubble, tempID);
|
||||
}
|
||||
|
||||
if(this.unreadOut.has(tempID)) {
|
||||
this.unreadOut.delete(tempID);
|
||||
this.unreadOut.add(mid);
|
||||
@ -1360,7 +1370,7 @@ export default class ChatBubbles {
|
||||
let messageMedia = message.media;
|
||||
|
||||
let messageMessage: string, totalEntities: any[];
|
||||
if(messageMedia?.document && !messageMedia.document.type) {
|
||||
if(messageMedia?.document && messageMedia.document.type !== 'video') {
|
||||
// * just filter this case
|
||||
} else if(message.grouped_id && albumMustBeRenderedFull) {
|
||||
const t = this.appMessagesManager.getAlbumText(message.grouped_id);
|
||||
@ -1575,25 +1585,23 @@ export default class ChatBubbles {
|
||||
case 'audio':
|
||||
case 'voice':
|
||||
case 'document': {
|
||||
const doc = this.appDocsManager.getDoc(message.id);
|
||||
//if(doc._ == 'documentEmpty') break;
|
||||
this.log('will wrap pending doc:', doc);
|
||||
const docDiv = wrapDocument(doc, false, true, message.id);
|
||||
|
||||
if(doc.type == 'audio' || doc.type == 'voice') {
|
||||
(docDiv as AudioElement).preloader = preloader;
|
||||
} else {
|
||||
const icoDiv = docDiv.querySelector('.audio-download, .document-ico');
|
||||
preloader.attach(icoDiv, false);
|
||||
const newNameContainer = wrapGroupedDocuments({
|
||||
albumMustBeRenderedFull,
|
||||
message,
|
||||
bubble,
|
||||
messageDiv
|
||||
});
|
||||
|
||||
if(newNameContainer) {
|
||||
nameContainer = newNameContainer;
|
||||
}
|
||||
|
||||
|
||||
if(pending.type == 'voice') {
|
||||
bubble.classList.add('bubble-audio');
|
||||
}
|
||||
|
||||
bubble.classList.remove('is-message-empty');
|
||||
messageDiv.classList.add((pending.type || 'document') + '-message');
|
||||
messageDiv.append(docDiv);
|
||||
processingWebPage = true;
|
||||
break;
|
||||
}
|
||||
@ -1805,52 +1813,15 @@ export default class ChatBubbles {
|
||||
|
||||
break;
|
||||
} else {
|
||||
//const storage = this.appMessagesManager.groupedMessagesStorage[message.grouped_id];
|
||||
//const isFullAlbum = storage && Object.keys(storage).length != 1;
|
||||
const mids = albumMustBeRenderedFull ? this.appMessagesManager.getMidsByMid(message.mid) : [message.mid];
|
||||
mids.forEach((mid, idx) => {
|
||||
const message = this.appMessagesManager.getMessage(mid);
|
||||
const doc = message.media.document;
|
||||
const div = wrapDocument(doc, false, false, mid);
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.classList.add('document-container');
|
||||
container.dataset.mid = '' + mid;
|
||||
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.classList.add('document-wrapper');
|
||||
|
||||
if(message.message) {
|
||||
const messageDiv = document.createElement('div');
|
||||
messageDiv.classList.add('document-message');
|
||||
|
||||
const richText = RichTextProcessor.wrapRichText(message.message, {
|
||||
entities: message.totalEntities
|
||||
});
|
||||
|
||||
messageDiv.innerHTML = richText;
|
||||
wrapper.append(messageDiv);
|
||||
}
|
||||
|
||||
if(mids.length > 1) {
|
||||
const selection = document.createElement('div');
|
||||
selection.classList.add('document-selection');
|
||||
container.append(selection);
|
||||
|
||||
container.classList.add('grouped-item');
|
||||
|
||||
if(idx === 0) {
|
||||
nameContainer = wrapper;
|
||||
}
|
||||
}
|
||||
|
||||
wrapper.append(div);
|
||||
container.append(wrapper);
|
||||
messageDiv.append(container);
|
||||
const newNameContainer = wrapGroupedDocuments({
|
||||
albumMustBeRenderedFull,
|
||||
message,
|
||||
bubble,
|
||||
messageDiv
|
||||
});
|
||||
|
||||
if(mids.length > 1) {
|
||||
bubble.classList.add('is-multiple-documents', 'is-grouped');
|
||||
if(newNameContainer) {
|
||||
nameContainer = newNameContainer;
|
||||
}
|
||||
|
||||
bubble.classList.remove('is-message-empty');
|
||||
|
@ -8,6 +8,7 @@ import { ripple } from "./ripple";
|
||||
import Scrollable from "./scrollable";
|
||||
import { toast } from "./toast";
|
||||
import { prepareAlbum, wrapDocument } from "./wrappers";
|
||||
import CheckboxField from "./checkbox";
|
||||
|
||||
type SendFileParams = Partial<{
|
||||
file: File,
|
||||
@ -25,13 +26,16 @@ export default class PopupNewMedia extends PopupElement {
|
||||
private btnSend: HTMLElement;
|
||||
private input: HTMLInputElement;
|
||||
private mediaContainer: HTMLElement;
|
||||
private groupCheckboxField: { label: HTMLLabelElement; input: HTMLInputElement; span: HTMLSpanElement; };
|
||||
|
||||
private willAttach: Partial<{
|
||||
type: 'media' | 'document',
|
||||
isMedia: boolean,
|
||||
isMedia: true,
|
||||
group: boolean,
|
||||
sendFileDetails: SendFileParams[]
|
||||
}> = {
|
||||
sendFileDetails: []
|
||||
sendFileDetails: [],
|
||||
group: false
|
||||
};
|
||||
|
||||
constructor(files: File[], willAttachType: PopupNewMedia['willAttach']['type']) {
|
||||
@ -60,7 +64,29 @@ export default class PopupNewMedia extends PopupElement {
|
||||
showLengthOn: 80
|
||||
});
|
||||
this.input = inputField.input;
|
||||
this.container.append(scrollable.container, inputField.container);
|
||||
|
||||
this.container.append(scrollable.container);
|
||||
|
||||
if(files.length > 1) {
|
||||
this.groupCheckboxField = CheckboxField('Group items', 'group-items');
|
||||
this.container.append(this.groupCheckboxField.label, inputField.container);
|
||||
|
||||
this.groupCheckboxField.input.checked = true;
|
||||
this.willAttach.group = true;
|
||||
|
||||
this.groupCheckboxField.input.addEventListener('change', () => {
|
||||
const checked = this.groupCheckboxField.input.checked;
|
||||
|
||||
this.willAttach.group = checked;
|
||||
this.willAttach.sendFileDetails.length = 0;
|
||||
|
||||
//this.mediaContainer.innerHTML = '';
|
||||
//this.container.classList.remove('is-media', 'is-document', 'is-album');
|
||||
this.attachFiles(files);
|
||||
});
|
||||
}
|
||||
|
||||
this.container.append(inputField.container);
|
||||
|
||||
this.attachFiles(files);
|
||||
}
|
||||
@ -85,18 +111,35 @@ export default class PopupNewMedia extends PopupElement {
|
||||
|
||||
this.destroy();
|
||||
const willAttach = this.willAttach;
|
||||
willAttach.isMedia = willAttach.type == 'media';
|
||||
willAttach.isMedia = willAttach.type == 'media' ? true : undefined;
|
||||
|
||||
//console.log('will send files with options:', willAttach);
|
||||
|
||||
const peerID = appImManager.chat.peerID;
|
||||
const chatInputC = appImManager.chat.input;
|
||||
|
||||
if(willAttach.sendFileDetails.length > 1 && willAttach.isMedia) {
|
||||
appMessagesManager.sendAlbum(peerID, willAttach.sendFileDetails.map(d => d.file), Object.assign({
|
||||
caption,
|
||||
replyToMsgID: chatInputC.replyToMsgID
|
||||
}, willAttach));
|
||||
if(willAttach.sendFileDetails.length > 1 && willAttach.group) {
|
||||
for(let i = 0; i < willAttach.sendFileDetails.length;) {
|
||||
let firstType = willAttach.sendFileDetails[i].file.type.split('/')[0];
|
||||
for(var k = 0; k < 10 && i < willAttach.sendFileDetails.length; ++i, ++k) {
|
||||
const type = willAttach.sendFileDetails[i].file.type.split('/')[0];
|
||||
if(firstType != type) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const w = {...willAttach};
|
||||
w.sendFileDetails = willAttach.sendFileDetails.slice(i - k, i);
|
||||
|
||||
appMessagesManager.sendAlbum(peerID, w.sendFileDetails.map(d => d.file), Object.assign({
|
||||
caption,
|
||||
replyToMsgID: chatInputC.replyToMsgID,
|
||||
isMedia: willAttach.isMedia
|
||||
}, w));
|
||||
|
||||
caption = undefined;
|
||||
chatInputC.replyToMsgID = 0;
|
||||
}
|
||||
} else {
|
||||
if(caption) {
|
||||
if(willAttach.sendFileDetails.length > 1) {
|
||||
@ -109,7 +152,7 @@ export default class PopupNewMedia extends PopupElement {
|
||||
const promises = willAttach.sendFileDetails.map(params => {
|
||||
const promise = appMessagesManager.sendFile(peerID, params.file, Object.assign({
|
||||
//isMedia: willAttach.isMedia,
|
||||
isMedia: params.file.type.includes('audio/') || willAttach.isMedia,
|
||||
isMedia: willAttach.isMedia,
|
||||
caption,
|
||||
replyToMsgID: chatInputC.replyToMsgID
|
||||
}, params));
|
||||
@ -176,7 +219,8 @@ export default class PopupNewMedia extends PopupElement {
|
||||
|
||||
case 'document': {
|
||||
const isPhoto = file.type.indexOf('image/') !== -1;
|
||||
if(isPhoto) {
|
||||
const isAudio = file.type.indexOf('audio/') !== -1;
|
||||
if(isPhoto || isAudio) {
|
||||
params.objectURL = URL.createObjectURL(file);
|
||||
}
|
||||
|
||||
@ -220,9 +264,9 @@ export default class PopupNewMedia extends PopupElement {
|
||||
const container = this.container;
|
||||
const willAttach = this.willAttach;
|
||||
|
||||
if(files.length > 10 && willAttach.type == 'media') {
|
||||
/* if(files.length > 10 && willAttach.type == 'media') {
|
||||
willAttach.type = 'document';
|
||||
}
|
||||
} */
|
||||
|
||||
files = files.filter(file => {
|
||||
if(willAttach.type == 'media') {
|
||||
@ -232,64 +276,77 @@ export default class PopupNewMedia extends PopupElement {
|
||||
}
|
||||
});
|
||||
|
||||
if(files.length) {
|
||||
if(willAttach.type == 'document') {
|
||||
this.title.innerText = 'Send ' + (files.length > 1 ? files.length + ' Files' : 'File');
|
||||
container.classList.add('is-document');
|
||||
} else {
|
||||
container.classList.add('is-media');
|
||||
Promise.all(files.map(this.attachFile)).then(results => {
|
||||
this.container.classList.remove('is-media', 'is-document', 'is-album');
|
||||
this.mediaContainer.innerHTML = '';
|
||||
|
||||
let foundPhotos = 0;
|
||||
let foundVideos = 0;
|
||||
files.forEach(file => {
|
||||
if(file.type.indexOf('image/') === 0) ++foundPhotos;
|
||||
else if(file.type.indexOf('video/') === 0) ++foundVideos;
|
||||
});
|
||||
|
||||
if(foundPhotos && foundVideos) {
|
||||
this.title.innerText = 'Send Album';
|
||||
} else if(foundPhotos) {
|
||||
this.title.innerText = 'Send ' + (foundPhotos > 1 ? foundPhotos + ' Photos' : 'Photo');
|
||||
} else if(foundVideos) {
|
||||
this.title.innerText = 'Send ' + (foundVideos > 1 ? foundVideos + ' Videos' : 'Video');
|
||||
if(files.length) {
|
||||
if(willAttach.type == 'document') {
|
||||
this.title.innerText = 'Send ' + (files.length > 1 ? files.length + ' Files' : 'File');
|
||||
container.classList.add('is-document');
|
||||
} else {
|
||||
container.classList.add('is-media');
|
||||
|
||||
let foundPhotos = 0;
|
||||
let foundVideos = 0;
|
||||
files.forEach(file => {
|
||||
if(file.type.indexOf('image/') === 0) ++foundPhotos;
|
||||
else if(file.type.indexOf('video/') === 0) ++foundVideos;
|
||||
});
|
||||
|
||||
if(foundPhotos && foundVideos && willAttach.group) {
|
||||
this.title.innerText = 'Send Album';
|
||||
} else if(foundPhotos) {
|
||||
this.title.innerText = 'Send ' + (foundPhotos > 1 ? foundPhotos + ' Photos' : 'Photo');
|
||||
} else if(foundVideos) {
|
||||
this.title.innerText = 'Send ' + (foundVideos > 1 ? foundVideos + ' Videos' : 'Video');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Promise.all(files.map(this.attachFile)).then(results => {
|
||||
if(willAttach.type == 'media') {
|
||||
if(willAttach.sendFileDetails.length > 1) {
|
||||
if(willAttach.sendFileDetails.length > 1 && willAttach.group) {
|
||||
container.classList.add('is-album');
|
||||
|
||||
this.mediaContainer.append(...results);
|
||||
for(let i = 0; i < results.length; i += 10) {
|
||||
const albumContainer = document.createElement('div');
|
||||
albumContainer.classList.add('popup-album');
|
||||
|
||||
prepareAlbum({
|
||||
container: this.mediaContainer,
|
||||
items: willAttach.sendFileDetails.map(o => ({w: o.width, h: o.height})),
|
||||
maxWidth: 380,
|
||||
minWidth: 100,
|
||||
spacing: 4
|
||||
});
|
||||
albumContainer.append(...results.slice(i, i + 10));
|
||||
prepareAlbum({
|
||||
container: albumContainer,
|
||||
items: willAttach.sendFileDetails.slice(i, i + 10).map(o => ({w: o.width, h: o.height})),
|
||||
maxWidth: 380,
|
||||
minWidth: 100,
|
||||
spacing: 4
|
||||
});
|
||||
|
||||
this.mediaContainer.append(albumContainer);
|
||||
}
|
||||
|
||||
//console.log('chatInput album layout:', layout);
|
||||
} else {
|
||||
const params = willAttach.sendFileDetails[0];
|
||||
const div = results[0];
|
||||
const {w, h} = calcImageInBox(params.width, params.height, 380, 320);
|
||||
div.style.width = w + 'px';
|
||||
div.style.height = h + 'px';
|
||||
this.mediaContainer.append(div);
|
||||
for(let i = 0; i < results.length; ++i) {
|
||||
const params = willAttach.sendFileDetails[i];
|
||||
const div = results[i];
|
||||
const {w, h} = calcImageInBox(params.width, params.height, 380, 320);
|
||||
div.style.width = w + 'px';
|
||||
div.style.height = h + 'px';
|
||||
this.mediaContainer.append(div);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.mediaContainer.append(...results);
|
||||
}
|
||||
|
||||
// show now
|
||||
document.body.addEventListener('keydown', this.onKeyDown);
|
||||
this.onClose = () => {
|
||||
document.body.removeEventListener('keydown', this.onKeyDown);
|
||||
};
|
||||
this.show();
|
||||
if(!this.element.classList.contains('active')) {
|
||||
document.body.addEventListener('keydown', this.onKeyDown);
|
||||
this.onClose = () => {
|
||||
document.body.removeEventListener('keydown', this.onKeyDown);
|
||||
};
|
||||
this.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import PollElement from './poll';
|
||||
import ProgressivePreloader from './preloader';
|
||||
import './middleEllipsis';
|
||||
import { nextRandomInt } from '../helpers/random';
|
||||
import RichTextProcessor from '../lib/richtextprocessor';
|
||||
|
||||
const MAX_VIDEO_AUTOPLAY_SIZE = 50 * 1024 * 1024; // 50 MB
|
||||
|
||||
@ -337,7 +338,7 @@ export function wrapDocument(doc: MyDocument, withTime = false, uploading = fals
|
||||
const icoDiv = document.createElement('div');
|
||||
icoDiv.classList.add('document-ico');
|
||||
|
||||
if(doc.thumbs?.length || (uploading && doc.url)) {
|
||||
if(doc.thumbs?.length || (uploading && doc.url && doc.type == 'photo')) {
|
||||
docDiv.classList.add('document-with-thumb');
|
||||
|
||||
if(uploading) {
|
||||
@ -858,7 +859,7 @@ export function wrapAlbum({groupID, attachmentDiv, middleware, uploading, lazyLo
|
||||
}) {
|
||||
const items: {size: PhotoSize.photoSize, media: any, message: any}[] = [];
|
||||
|
||||
// !higher msgID will be the FIRST in album
|
||||
// !lowest msgID will be the FIRST in album
|
||||
const storage = appMessagesManager.getMidsByAlbum(groupID);
|
||||
for(const mid of storage) {
|
||||
const m = appMessagesManager.getMessage(mid);
|
||||
@ -868,6 +869,11 @@ export function wrapAlbum({groupID, attachmentDiv, middleware, uploading, lazyLo
|
||||
items.push({size, media, message: m});
|
||||
}
|
||||
|
||||
// * pending
|
||||
if(storage[0] < 0) {
|
||||
items.reverse();
|
||||
}
|
||||
|
||||
prepareAlbum({
|
||||
container: attachmentDiv,
|
||||
items: items.map(i => ({w: i.size.w, h: i.size.h})),
|
||||
@ -912,6 +918,77 @@ export function wrapAlbum({groupID, attachmentDiv, middleware, uploading, lazyLo
|
||||
});
|
||||
}
|
||||
|
||||
export function wrapGroupedDocuments({albumMustBeRenderedFull, message, bubble, messageDiv}: {
|
||||
albumMustBeRenderedFull: boolean,
|
||||
message: any,
|
||||
messageDiv: HTMLElement,
|
||||
bubble: HTMLElement,
|
||||
uploading?: boolean
|
||||
}) {
|
||||
let nameContainer: HTMLDivElement;
|
||||
const mids = albumMustBeRenderedFull ? appMessagesManager.getMidsByMid(message.mid) : [message.mid];
|
||||
const isPending = message.mid < 0;
|
||||
if(isPending) {
|
||||
mids.reverse();
|
||||
}
|
||||
|
||||
mids.forEach((mid, idx) => {
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
const doc = message.media.document;
|
||||
const div = wrapDocument(doc, false, isPending, mid);
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.classList.add('document-container');
|
||||
container.dataset.mid = '' + mid;
|
||||
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.classList.add('document-wrapper');
|
||||
|
||||
if(message.message) {
|
||||
const messageDiv = document.createElement('div');
|
||||
messageDiv.classList.add('document-message');
|
||||
|
||||
const richText = RichTextProcessor.wrapRichText(message.message, {
|
||||
entities: message.totalEntities
|
||||
});
|
||||
|
||||
messageDiv.innerHTML = richText;
|
||||
wrapper.append(messageDiv);
|
||||
}
|
||||
|
||||
if(mids.length > 1) {
|
||||
const selection = document.createElement('div');
|
||||
selection.classList.add('document-selection');
|
||||
container.append(selection);
|
||||
|
||||
container.classList.add('grouped-item');
|
||||
|
||||
if(idx === 0) {
|
||||
nameContainer = wrapper;
|
||||
}
|
||||
}
|
||||
|
||||
if(isPending) {
|
||||
if(doc.type == 'audio' || doc.type == 'voice') {
|
||||
(div as AudioElement).preloader = message.media.preloader;
|
||||
} else {
|
||||
const icoDiv = div.querySelector('.audio-download, .document-ico');
|
||||
message.media.preloader.attach(icoDiv, false);
|
||||
}
|
||||
}
|
||||
|
||||
wrapper.append(div);
|
||||
container.append(wrapper);
|
||||
messageDiv.append(container);
|
||||
});
|
||||
|
||||
if(mids.length > 1) {
|
||||
bubble.classList.add('is-multiple-documents', 'is-grouped');
|
||||
}
|
||||
|
||||
return nameContainer;
|
||||
}
|
||||
|
||||
export function wrapPoll(pollID: string, mid: number) {
|
||||
const elem = new PollElement();
|
||||
elem.setAttribute('poll-id', pollID);
|
||||
|
@ -4,7 +4,7 @@ import { tsNow } from "../../helpers/date";
|
||||
import { copy, defineNotNumerableProperties, safeReplaceObject, getObjectKeysAndSort } from "../../helpers/object";
|
||||
import { randomLong } from "../../helpers/random";
|
||||
import { splitStringByLength, limitSymbols } from "../../helpers/string";
|
||||
import { Dialog as MTDialog, DialogPeer, DocumentAttribute, InputMessage, InputNotifyPeer, InputPeerNotifySettings, Message, MessageAction, MessageEntity, MessagesDialogs, MessagesFilter, MessagesMessages, MessagesPeerDialogs, MethodDeclMap, NotifyPeer, PhotoSize, SendMessageAction, Update } from "../../layer";
|
||||
import { Dialog as MTDialog, DialogPeer, DocumentAttribute, InputMedia, InputMessage, InputNotifyPeer, InputPeerNotifySettings, InputSingleMedia, Message, MessageAction, MessageEntity, MessagesDialogs, MessagesFilter, MessagesMessages, MessagesPeerDialogs, MethodDeclMap, NotifyPeer, PhotoSize, SendMessageAction, Update } from "../../layer";
|
||||
import { InvokeApiOptions } from "../../types";
|
||||
import { langPack } from "../langPack";
|
||||
import { logger, LogLevels } from "../logger";
|
||||
@ -569,31 +569,32 @@ export class AppMessagesManager {
|
||||
}
|
||||
|
||||
public sendFile(peerID: number, file: File | Blob | MyDocument, options: Partial<{
|
||||
isMedia: boolean,
|
||||
isRoundMessage: true,
|
||||
isVoiceMessage: true,
|
||||
isGroupedItem: true,
|
||||
isMedia: true,
|
||||
|
||||
replyToMsgID: number,
|
||||
caption: string,
|
||||
entities: any[],
|
||||
entities: MessageEntity[],
|
||||
width: number,
|
||||
height: number,
|
||||
objectURL: string,
|
||||
isRoundMessage: boolean,
|
||||
duration: number,
|
||||
background: boolean,
|
||||
background: true,
|
||||
|
||||
isVoiceMessage: boolean,
|
||||
waveform: Uint8Array
|
||||
}> = {}) {
|
||||
peerID = appPeersManager.getPeerMigratedTo(peerID) || peerID;
|
||||
var messageID = this.tempID--;
|
||||
var randomIDS = randomLong();
|
||||
var historyStorage = this.historiesStorage[peerID] ?? (this.historiesStorage[peerID] = {count: null, history: [], pending: []});
|
||||
var flags = 0;
|
||||
var pFlags: any = {};
|
||||
var replyToMsgID = options.replyToMsgID;
|
||||
var isChannel = appPeersManager.isChannel(peerID);
|
||||
var isMegagroup = isChannel && appPeersManager.isMegagroup(peerID);
|
||||
var asChannel = isChannel && !isMegagroup ? true : false;
|
||||
var attachType: string, apiFileName: string;
|
||||
const messageID = this.tempID--;
|
||||
const randomIDS = randomLong();
|
||||
const historyStorage = this.historiesStorage[peerID] ?? (this.historiesStorage[peerID] = {count: null, history: [], pending: []});
|
||||
const pFlags: any = {};
|
||||
const replyToMsgID = options.replyToMsgID;
|
||||
const isChannel = appPeersManager.isChannel(peerID);
|
||||
const isMegagroup = isChannel && appPeersManager.isMegagroup(peerID);
|
||||
const asChannel = !!(isChannel && !isMegagroup);
|
||||
let attachType: string, apiFileName: string;
|
||||
|
||||
const fileType = 'mime_type' in file ? file.mime_type : file.type;
|
||||
const fileName = file instanceof File ? file.name : '';
|
||||
@ -613,20 +614,42 @@ export class AppMessagesManager {
|
||||
|
||||
const isPhoto = ['image/jpeg', 'image/png', 'image/bmp'].indexOf(fileType) >= 0;
|
||||
|
||||
let photo: MyPhoto, document: MyDocument;
|
||||
|
||||
let actionName = '';
|
||||
if(!options.isMedia) {
|
||||
if(isDocument) { // maybe it's a sticker or gif
|
||||
attachType = 'document';
|
||||
apiFileName = '';
|
||||
} else if(fileType.indexOf('audio/') === 0 || ['video/ogg'].indexOf(fileType) >= 0) {
|
||||
attachType = 'audio';
|
||||
apiFileName = 'audio.' + (fileType.split('/')[1] == 'ogg' ? 'ogg' : 'mp3');
|
||||
actionName = 'sendMessageUploadAudioAction';
|
||||
|
||||
if(options.isVoiceMessage) {
|
||||
attachType = 'voice';
|
||||
pFlags.media_unread = true;
|
||||
}
|
||||
|
||||
let attribute: DocumentAttribute.documentAttributeAudio = {
|
||||
_: 'documentAttributeAudio',
|
||||
pFlags: {
|
||||
voice: options.isVoiceMessage
|
||||
},
|
||||
waveform: options.waveform,
|
||||
duration: options.duration || 0
|
||||
};
|
||||
|
||||
attributes.push(attribute);
|
||||
} else if(!options.isMedia) {
|
||||
attachType = 'document';
|
||||
apiFileName = 'document.' + fileType.split('/')[1];
|
||||
actionName = 'sendMessageUploadDocumentAction';
|
||||
} else if(isDocument) { // maybe it's a sticker or gif
|
||||
attachType = 'document';
|
||||
apiFileName = '';
|
||||
} else if(isPhoto) {
|
||||
attachType = 'photo';
|
||||
apiFileName = 'photo.' + fileType.split('/')[1];
|
||||
actionName = 'sendMessageUploadPhotoAction';
|
||||
|
||||
let photo: MyPhoto = {
|
||||
photo = {
|
||||
_: 'photo',
|
||||
id: '' + messageID,
|
||||
sizes: [{
|
||||
@ -646,30 +669,6 @@ export class AppMessagesManager {
|
||||
photo.url = options.objectURL || '';
|
||||
|
||||
appPhotosManager.savePhoto(photo);
|
||||
} else if(fileType.indexOf('audio/') === 0 || ['video/ogg'].indexOf(fileType) >= 0) {
|
||||
attachType = 'audio';
|
||||
apiFileName = 'audio.' + (fileType.split('/')[1] == 'ogg' ? 'ogg' : 'mp3');
|
||||
actionName = 'sendMessageUploadAudioAction';
|
||||
|
||||
let flags = 0;
|
||||
if(options.isVoiceMessage) {
|
||||
flags |= 1 << 10;
|
||||
flags |= 1 << 2;
|
||||
attachType = 'voice';
|
||||
pFlags.media_unread = true;
|
||||
}
|
||||
|
||||
let attribute: DocumentAttribute.documentAttributeAudio = {
|
||||
_: 'documentAttributeAudio',
|
||||
flags: flags,
|
||||
pFlags: { // that's only for client, not going to telegram
|
||||
voice: options.isVoiceMessage || undefined
|
||||
},
|
||||
waveform: options.waveform,
|
||||
duration: options.duration || 0
|
||||
};
|
||||
|
||||
attributes.push(attribute);
|
||||
} else if(fileType.indexOf('video/') === 0) {
|
||||
attachType = 'video';
|
||||
apiFileName = 'video.mp4';
|
||||
@ -677,9 +676,8 @@ export class AppMessagesManager {
|
||||
|
||||
let videoAttribute: DocumentAttribute.documentAttributeVideo = {
|
||||
_: 'documentAttributeVideo',
|
||||
pFlags: { // that's only for client, not going to telegram
|
||||
supports_streaming: true,
|
||||
round_message: options.isRoundMessage || undefined
|
||||
pFlags: {
|
||||
round_message: options.isRoundMessage
|
||||
},
|
||||
duration: options.duration,
|
||||
w: options.width,
|
||||
@ -697,7 +695,7 @@ export class AppMessagesManager {
|
||||
|
||||
if(['document', 'video', 'audio', 'voice'].indexOf(attachType) !== -1 && !isDocument) {
|
||||
const thumbs: PhotoSize[] = [];
|
||||
const doc: MyDocument = {
|
||||
document = {
|
||||
_: 'document',
|
||||
id: '' + messageID,
|
||||
duration: options.duration,
|
||||
@ -709,10 +707,10 @@ export class AppMessagesManager {
|
||||
size: file.size
|
||||
} as any;
|
||||
|
||||
defineNotNumerableProperties(doc, ['downloaded', 'url']);
|
||||
defineNotNumerableProperties(document, ['downloaded', 'url']);
|
||||
// @ts-ignore
|
||||
doc.downloaded = file.size;
|
||||
doc.url = options.objectURL || '';
|
||||
document.downloaded = file.size;
|
||||
document.url = options.objectURL || '';
|
||||
|
||||
if(isPhoto) {
|
||||
attributes.push({
|
||||
@ -732,42 +730,36 @@ export class AppMessagesManager {
|
||||
});
|
||||
}
|
||||
|
||||
appDocsManager.saveDoc(doc);
|
||||
appDocsManager.saveDoc(document);
|
||||
}
|
||||
|
||||
this.log('AMM: sendFile', attachType, apiFileName, file.type, options);
|
||||
|
||||
var fromID = appUsersManager.getSelf().id;
|
||||
let fromID = appUsersManager.getSelf().id;
|
||||
if(peerID != fromID) {
|
||||
flags |= 2;
|
||||
pFlags.out = true;
|
||||
|
||||
if(!isChannel && !appUsersManager.isBot(peerID)) {
|
||||
flags |= 1;
|
||||
pFlags.unread = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(replyToMsgID) {
|
||||
flags |= 8;
|
||||
}
|
||||
|
||||
if(asChannel) {
|
||||
fromID = 0;
|
||||
pFlags.post = true;
|
||||
} else {
|
||||
flags |= 256;
|
||||
}
|
||||
|
||||
const preloader = new ProgressivePreloader(null, true, false, 'prepend');
|
||||
|
||||
const media = {
|
||||
_: 'messageMediaPending',
|
||||
type: attachType,
|
||||
type: options.isGroupedItem && options.isMedia ? 'album' : attachType,
|
||||
file_name: fileName || apiFileName,
|
||||
size: file.size,
|
||||
file: file,
|
||||
preloader: preloader,
|
||||
file,
|
||||
preloader,
|
||||
photo,
|
||||
document,
|
||||
w: options.width,
|
||||
h: options.height,
|
||||
url: options.objectURL
|
||||
@ -778,8 +770,8 @@ export class AppMessagesManager {
|
||||
id: messageID,
|
||||
from_id: appPeersManager.getOutputPeer(fromID),
|
||||
peer_id: appPeersManager.getOutputPeer(peerID),
|
||||
pFlags: pFlags,
|
||||
date: date,
|
||||
pFlags,
|
||||
date,
|
||||
message: caption,
|
||||
media: isDocument ? {
|
||||
_: 'messageMediaDocument',
|
||||
@ -805,59 +797,22 @@ export class AppMessagesManager {
|
||||
let uploaded = false,
|
||||
uploadPromise: ReturnType<ApiFileManager['uploadFile']> = null;
|
||||
|
||||
const invoke = (flags: number, inputMedia: any) => {
|
||||
this.setTyping(peerID, 'sendMessageCancelAction');
|
||||
|
||||
return apiManager.invokeApi('messages.sendMedia', {
|
||||
flags: flags,
|
||||
background: options.background || undefined,
|
||||
clear_draft: true,
|
||||
peer: appPeersManager.getInputPeerByID(peerID),
|
||||
media: inputMedia,
|
||||
message: caption,
|
||||
random_id: randomIDS,
|
||||
reply_to_msg_id: appMessagesIDsManager.getMessageLocalID(replyToMsgID)
|
||||
}).then((updates) => {
|
||||
apiUpdatesManager.processUpdateMessage(updates);
|
||||
}, (error) => {
|
||||
if(attachType == 'photo' &&
|
||||
error.code == 400 &&
|
||||
(error.type == 'PHOTO_INVALID_DIMENSIONS' ||
|
||||
error.type == 'PHOTO_SAVE_FILE_INVALID')) {
|
||||
error.handled = true
|
||||
attachType = 'document'
|
||||
message.send();
|
||||
return;
|
||||
}
|
||||
|
||||
toggleError(true);
|
||||
});
|
||||
};
|
||||
|
||||
const sentDeferred = deferredPromise<InputMedia>();
|
||||
message.send = () => {
|
||||
let flags = 0;
|
||||
if(replyToMsgID) {
|
||||
flags |= 1;
|
||||
}
|
||||
if(options.background) {
|
||||
flags |= 64;
|
||||
}
|
||||
flags |= 128; // clear_draft
|
||||
|
||||
if(isDocument) {
|
||||
const {id, access_hash, file_reference} = file as MyDocument;
|
||||
|
||||
const inputMedia = {
|
||||
const inputMedia: InputMedia = {
|
||||
_: 'inputMediaDocument',
|
||||
id: {
|
||||
_: 'inputDocument',
|
||||
id: id,
|
||||
access_hash: access_hash,
|
||||
file_reference: file_reference
|
||||
id,
|
||||
access_hash,
|
||||
file_reference
|
||||
}
|
||||
};
|
||||
|
||||
invoke(flags, inputMedia);
|
||||
sentDeferred.resolve(inputMedia);
|
||||
} else if(file instanceof File || file instanceof Blob) {
|
||||
const deferred = deferredPromise<void>();
|
||||
|
||||
@ -873,7 +828,7 @@ export class AppMessagesManager {
|
||||
|
||||
inputFile.name = apiFileName;
|
||||
uploaded = true;
|
||||
var inputMedia;
|
||||
let inputMedia: InputMedia;
|
||||
switch(attachType) {
|
||||
case 'photo':
|
||||
inputMedia = {
|
||||
@ -887,11 +842,11 @@ export class AppMessagesManager {
|
||||
_: 'inputMediaUploadedDocument',
|
||||
file: inputFile,
|
||||
mime_type: fileType,
|
||||
attributes: attributes
|
||||
attributes
|
||||
};
|
||||
}
|
||||
|
||||
invoke(flags, inputMedia);
|
||||
sentDeferred.resolve(inputMedia);
|
||||
}, (/* error */) => {
|
||||
toggleError(true);
|
||||
});
|
||||
@ -907,6 +862,7 @@ export class AppMessagesManager {
|
||||
this.log('cancelling upload', media);
|
||||
|
||||
deferred.resolve();
|
||||
sentDeferred.reject(err);
|
||||
this.cancelPendingMessage(randomIDS);
|
||||
this.setTyping(peerID, 'sendMessageCancelAction');
|
||||
}
|
||||
@ -917,19 +873,52 @@ export class AppMessagesManager {
|
||||
|
||||
this.sendFilePromise = deferred;
|
||||
}
|
||||
|
||||
return sentDeferred;
|
||||
};
|
||||
|
||||
this.saveMessages([message]);
|
||||
historyStorage.pending.unshift(messageID);
|
||||
rootScope.broadcast('history_append', {peerID, messageID, my: true});
|
||||
|
||||
setTimeout(message.send.bind(this), 0);
|
||||
|
||||
this.pendingByRandomID[randomIDS] = [peerID, messageID];
|
||||
|
||||
if(!options.isGroupedItem) {
|
||||
this.saveMessages([message]);
|
||||
rootScope.broadcast('history_append', {peerID, messageID, my: true});
|
||||
setTimeout(message.send, 0);
|
||||
sentDeferred.then(inputMedia => {
|
||||
this.setTyping(peerID, 'sendMessageCancelAction');
|
||||
|
||||
return apiManager.invokeApi('messages.sendMedia', {
|
||||
background: options.background,
|
||||
clear_draft: true,
|
||||
peer: appPeersManager.getInputPeerByID(peerID),
|
||||
media: inputMedia,
|
||||
message: caption,
|
||||
random_id: randomIDS,
|
||||
reply_to_msg_id: appMessagesIDsManager.getMessageLocalID(replyToMsgID)
|
||||
}).then((updates) => {
|
||||
apiUpdatesManager.processUpdateMessage(updates);
|
||||
}, (error) => {
|
||||
if(attachType == 'photo' &&
|
||||
error.code == 400 &&
|
||||
(error.type == 'PHOTO_INVALID_DIMENSIONS' ||
|
||||
error.type == 'PHOTO_SAVE_FILE_INVALID')) {
|
||||
error.handled = true;
|
||||
attachType = 'document';
|
||||
message.send();
|
||||
return;
|
||||
}
|
||||
|
||||
toggleError(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {message, promise: sentDeferred};
|
||||
}
|
||||
|
||||
public async sendAlbum(peerID: number, files: File[], options: Partial<{
|
||||
entities: any[],
|
||||
isMedia: true,
|
||||
entities: MessageEntity[],
|
||||
replyToMsgID: number,
|
||||
caption: string,
|
||||
sendFileDetails: Partial<{
|
||||
@ -939,146 +928,50 @@ export class AppMessagesManager {
|
||||
objectURL: string,
|
||||
}>[]
|
||||
}> = {}) {
|
||||
if(files.length === 1) {
|
||||
return this.sendFile(peerID, files[0], {...options, ...options.sendFileDetails[0]});
|
||||
}
|
||||
|
||||
peerID = appPeersManager.getPeerMigratedTo(peerID) || peerID;
|
||||
let groupID: number;
|
||||
let historyStorage = this.historiesStorage[peerID] ?? (this.historiesStorage[peerID] = {count: null, history: [], pending: []});
|
||||
let flags = 0;
|
||||
let pFlags: any = {};
|
||||
let replyToMsgID = options.replyToMsgID;
|
||||
let isChannel = appPeersManager.isChannel(peerID);
|
||||
let isMegagroup = isChannel && appPeersManager.isMegagroup(peerID);
|
||||
let asChannel = isChannel && !isMegagroup ? true : false;
|
||||
const replyToMsgID = options.replyToMsgID;
|
||||
|
||||
let caption = options.caption || '';
|
||||
|
||||
let date = tsNow(true) + serverTimeManager.serverTimeOffset;
|
||||
|
||||
let entities: MessageEntity[];
|
||||
if(caption) {
|
||||
let entities = options.entities || [];
|
||||
entities = options.entities || [];
|
||||
caption = RichTextProcessor.parseMarkdown(caption, entities);
|
||||
}
|
||||
|
||||
this.log('AMM: sendAlbum', files, options);
|
||||
|
||||
let fromID = appUsersManager.getSelf().id;
|
||||
if(peerID != fromID) {
|
||||
pFlags.out = true;
|
||||
|
||||
if(!isChannel && !appUsersManager.isBot(peerID)) {
|
||||
pFlags.unread = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(replyToMsgID) {
|
||||
flags |= 1;
|
||||
}
|
||||
|
||||
if(asChannel) {
|
||||
fromID = 0;
|
||||
pFlags.post = true;
|
||||
} else {
|
||||
flags |= 128; // clear_draft
|
||||
}
|
||||
|
||||
let ids = files.map(() => this.tempID--).reverse();
|
||||
groupID = ids[ids.length - 1];
|
||||
let messages = files.map((file, idx) => {
|
||||
//let messageID = this.tempID--;
|
||||
//if(!groupID) groupID = messageID;
|
||||
let messageID = ids[idx];
|
||||
let randomIDS = randomLong();
|
||||
let preloader = new ProgressivePreloader(null, true, false, 'prepend');
|
||||
|
||||
let details = options.sendFileDetails[idx];
|
||||
|
||||
let media = {
|
||||
_: 'messageMediaPending',
|
||||
type: 'album',
|
||||
preloader: preloader,
|
||||
document: undefined as any,
|
||||
photo: undefined as any
|
||||
const messages = files.map((file, idx) => {
|
||||
const details = options.sendFileDetails[idx];
|
||||
const o: any = {
|
||||
isGroupedItem: true,
|
||||
isMedia: options.isMedia,
|
||||
...details
|
||||
};
|
||||
|
||||
if(file.type.indexOf('video/') === 0) {
|
||||
let videoAttribute: DocumentAttribute.documentAttributeVideo = {
|
||||
_: 'documentAttributeVideo',
|
||||
pFlags: { // that's only for client, not going to telegram
|
||||
supports_streaming: true
|
||||
},
|
||||
duration: details.duration,
|
||||
w: details.width,
|
||||
h: details.height
|
||||
};
|
||||
|
||||
let doc: MyDocument = {
|
||||
_: 'document',
|
||||
id: '' + messageID,
|
||||
attributes: [videoAttribute],
|
||||
thumbs: [],
|
||||
mime_type: file.type,
|
||||
size: file.size
|
||||
} as any;
|
||||
|
||||
defineNotNumerableProperties(doc, ['downloaded', 'url']);
|
||||
// @ts-ignore
|
||||
doc.downloaded = file.size;
|
||||
doc.url = details.objectURL || '';
|
||||
|
||||
appDocsManager.saveDoc(doc);
|
||||
media.document = doc;
|
||||
} else {
|
||||
let photo: any = {
|
||||
_: 'photo',
|
||||
id: '' + messageID,
|
||||
sizes: [{
|
||||
_: 'photoSize',
|
||||
w: details.width,
|
||||
h: details.height,
|
||||
type: 'm',
|
||||
size: file.size
|
||||
} as PhotoSize],
|
||||
w: details.width,
|
||||
h: details.height
|
||||
};
|
||||
|
||||
defineNotNumerableProperties(photo, ['downloaded', 'url']);
|
||||
// @ts-ignore
|
||||
photo.downloaded = file.size;
|
||||
photo.url = details.objectURL || '';
|
||||
|
||||
appPhotosManager.savePhoto(photo);
|
||||
media.photo = photo;
|
||||
if(idx === 0) {
|
||||
o.caption = caption;
|
||||
o.entities = entities;
|
||||
o.replyToMsgID = replyToMsgID;
|
||||
}
|
||||
|
||||
let message = {
|
||||
_: 'message',
|
||||
id: messageID,
|
||||
from_id: appPeersManager.getOutputPeer(fromID),
|
||||
grouped_id: groupID,
|
||||
peer_id: appPeersManager.getOutputPeer(peerID),
|
||||
pFlags: pFlags,
|
||||
date: date,
|
||||
message: caption,
|
||||
media: media,
|
||||
random_id: randomIDS,
|
||||
reply_to: {reply_to_msg_id: replyToMsgID},
|
||||
views: asChannel && 1,
|
||||
pending: true,
|
||||
error: false
|
||||
};
|
||||
|
||||
this.saveMessages([message]);
|
||||
historyStorage.pending.unshift(messageID);
|
||||
//rootScope.$broadcast('history_append', {peerID: peerID, messageID: messageID, my: true});
|
||||
|
||||
this.pendingByRandomID[randomIDS] = [peerID, messageID];
|
||||
|
||||
return message;
|
||||
return this.sendFile(peerID, file, o).message;
|
||||
});
|
||||
|
||||
rootScope.broadcast('history_append', {peerID, messageID: messages[messages.length - 1].id, my: true});
|
||||
const groupID = messages[0].id;
|
||||
messages.forEach(message => {
|
||||
message.grouped_id = groupID;
|
||||
});
|
||||
this.saveMessages(messages);
|
||||
|
||||
let toggleError = (message: any, on: boolean) => {
|
||||
rootScope.broadcast('history_append', {peerID, messageID: groupID, my: true});
|
||||
|
||||
//return;
|
||||
|
||||
const toggleError = (message: any, on: boolean) => {
|
||||
if(on) {
|
||||
message.error = true;
|
||||
} else {
|
||||
@ -1088,15 +981,11 @@ export class AppMessagesManager {
|
||||
rootScope.broadcast('messages_pending');
|
||||
};
|
||||
|
||||
let uploaded = false,
|
||||
uploadPromise: ReturnType<ApiFileManager['uploadFile']> = null;
|
||||
|
||||
let inputPeer = appPeersManager.getInputPeerByID(peerID);
|
||||
let invoke = (multiMedia: any[]) => {
|
||||
const inputPeer = appPeersManager.getInputPeerByID(peerID);
|
||||
const invoke = (multiMedia: any[]) => {
|
||||
this.setTyping(peerID, 'sendMessageCancelAction');
|
||||
|
||||
return apiManager.invokeApi('messages.sendMultiMedia', {
|
||||
flags: flags,
|
||||
peer: inputPeer,
|
||||
multi_media: multiMedia,
|
||||
reply_to_msg_id: appMessagesIDsManager.getMessageLocalID(replyToMsgID)
|
||||
@ -1107,114 +996,42 @@ export class AppMessagesManager {
|
||||
});
|
||||
};
|
||||
|
||||
let inputs: any[] = [];
|
||||
for(let i = 0, length = files.length; i < length; ++i) {
|
||||
const file = files[i];
|
||||
const message = messages[i];
|
||||
const media = message.media;
|
||||
const preloader = media.preloader;
|
||||
const actionName = file.type.indexOf('video/') === 0 ? 'sendMessageUploadVideoAction' : 'sendMessageUploadPhotoAction';
|
||||
const deferred = deferredPromise<void>();
|
||||
let canceled = false;
|
||||
|
||||
let apiFileName: string;
|
||||
if(file.type.indexOf('video/') === 0) {
|
||||
apiFileName = 'video.mp4';
|
||||
} else {
|
||||
apiFileName = 'photo.' + file.type.split('/')[1];
|
||||
}
|
||||
|
||||
await this.sendFilePromise;
|
||||
this.sendFilePromise = deferred;
|
||||
|
||||
if(!uploaded || message.error) {
|
||||
uploaded = false;
|
||||
uploadPromise = appDownloadManager.upload(file);
|
||||
preloader.attachPromise(uploadPromise);
|
||||
}
|
||||
|
||||
uploadPromise.addNotifyListener((progress: {done: number, total: number}) => {
|
||||
this.log('upload progress', progress);
|
||||
const percents = Math.max(1, Math.floor(100 * progress.done / progress.total));
|
||||
this.setTyping(peerID, {_: actionName, progress: percents | 0});
|
||||
});
|
||||
|
||||
uploadPromise.catch(err => {
|
||||
if(err.name === 'AbortError' && !uploaded) {
|
||||
this.log('cancelling upload item', media);
|
||||
canceled = true;
|
||||
}
|
||||
});
|
||||
|
||||
await uploadPromise.then((inputFile) => {
|
||||
this.log('appMessagesManager: sendAlbum file uploaded:', inputFile);
|
||||
|
||||
if(canceled) {
|
||||
return;
|
||||
}
|
||||
|
||||
inputFile.name = apiFileName;
|
||||
const inputs: InputSingleMedia[] = [];
|
||||
for(const message of messages) {
|
||||
const inputMedia: InputMedia = await message.send();
|
||||
this.log('sendAlbum uploaded item:', inputMedia);
|
||||
|
||||
await apiManager.invokeApi('messages.uploadMedia', {
|
||||
peer: inputPeer,
|
||||
media: inputMedia
|
||||
}).then(messageMedia => {
|
||||
let inputMedia: any;
|
||||
let details = options.sendFileDetails[i];
|
||||
if(details.duration) {
|
||||
inputMedia = {
|
||||
_: 'inputMediaUploadedDocument',
|
||||
file: inputFile,
|
||||
mime_type: file.type,
|
||||
attributes: [{
|
||||
_: 'documentAttributeVideo',
|
||||
supports_streaming: true,
|
||||
duration: details.duration,
|
||||
w: details.width,
|
||||
h: details.height
|
||||
}]
|
||||
};
|
||||
} else {
|
||||
inputMedia = {
|
||||
_: 'inputMediaUploadedPhoto',
|
||||
file: inputFile
|
||||
};
|
||||
if(messageMedia._ == 'messageMediaPhoto') {
|
||||
const photo = appPhotosManager.savePhoto(messageMedia.photo);
|
||||
inputMedia = appPhotosManager.getInput(photo);
|
||||
} else if(messageMedia._ == 'messageMediaDocument') {
|
||||
const doc = appDocsManager.saveDoc(messageMedia.document);
|
||||
inputMedia = appDocsManager.getMediaInput(doc);
|
||||
}
|
||||
|
||||
return apiManager.invokeApi('messages.uploadMedia', {
|
||||
peer: inputPeer,
|
||||
media: inputMedia
|
||||
}).then(messageMedia => {
|
||||
if(canceled) {
|
||||
return;
|
||||
}
|
||||
|
||||
let inputMedia: any;
|
||||
if(messageMedia._ == 'messageMediaPhoto') {
|
||||
const photo = appPhotosManager.savePhoto(messageMedia.photo);
|
||||
inputMedia = appPhotosManager.getInput(photo);
|
||||
} else if(messageMedia._ == 'messageMediaDocument') {
|
||||
const doc = appDocsManager.saveDoc(messageMedia.document);
|
||||
inputMedia = appDocsManager.getMediaInput(doc);
|
||||
}
|
||||
|
||||
inputs.push({
|
||||
_: 'inputSingleMedia',
|
||||
media: inputMedia,
|
||||
random_id: message.random_id,
|
||||
message: caption,
|
||||
entities: []
|
||||
});
|
||||
|
||||
caption = ''; // only 1 caption for all inputs
|
||||
}, () => {
|
||||
toggleError(message, true);
|
||||
inputs.push({
|
||||
_: 'inputSingleMedia',
|
||||
media: inputMedia,
|
||||
random_id: message.random_id,
|
||||
message: caption,
|
||||
entities
|
||||
});
|
||||
|
||||
// * only 1 caption for all inputs
|
||||
if(caption) {
|
||||
caption = '';
|
||||
entities = [];
|
||||
}
|
||||
}, () => {
|
||||
toggleError(message, true);
|
||||
});
|
||||
|
||||
this.log('appMessagesManager: sendAlbum uploadPromise.finally!');
|
||||
deferred.resolve();
|
||||
}
|
||||
|
||||
uploaded = true;
|
||||
invoke(inputs);
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
/* max-height: 425px; */
|
||||
|
||||
#{$parent}-photo {
|
||||
max-height: 320px;
|
||||
//max-height: 320px;
|
||||
margin: 0 auto;
|
||||
|
||||
img {
|
||||
@ -24,6 +24,7 @@
|
||||
> div {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -33,7 +34,7 @@
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
|
||||
> div {
|
||||
.album-item {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@ -87,6 +88,7 @@
|
||||
//justify-content: center;
|
||||
width: fit-content;
|
||||
border-radius: $border-radius-medium;
|
||||
user-select: none;
|
||||
/* align-items: center; */
|
||||
|
||||
.document {
|
||||
@ -152,4 +154,19 @@
|
||||
.popup-header {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.checkbox-field {
|
||||
margin-bottom: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.popup-album, .popup-container:not(.is-album) .popup-item-media {
|
||||
position: relative;
|
||||
border-radius: inherit;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.popup-album + .popup-album, .popup-container:not(.is-album) .popup-item-media + .popup-item-media {
|
||||
margin-top: .5rem;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user