Albums send & render after send
This commit is contained in:
parent
ae8e8f0008
commit
d15abda503
@ -5,11 +5,12 @@ import { RichTextProcessor } from "../lib/richtextprocessor";
|
|||||||
import apiManager from "../lib/mtproto/mtprotoworker";
|
import apiManager from "../lib/mtproto/mtprotoworker";
|
||||||
import appWebPagesManager from "../lib/appManagers/appWebPagesManager";
|
import appWebPagesManager from "../lib/appManagers/appWebPagesManager";
|
||||||
import appImManager from "../lib/appManagers/appImManager";
|
import appImManager from "../lib/appManagers/appImManager";
|
||||||
import { calcImageInBox, getRichValue } from "../lib/utils";
|
import { getRichValue, calcImageInBox } from "../lib/utils";
|
||||||
import { wrapDocument, wrapReply } from "./wrappers";
|
import { wrapDocument, wrapReply } from "./wrappers";
|
||||||
import appMessagesManager from "../lib/appManagers/appMessagesManager";
|
import appMessagesManager from "../lib/appManagers/appMessagesManager";
|
||||||
import initEmoticonsDropdown, { EMOTICONSSTICKERGROUP } from "./emoticonsDropdown";
|
import initEmoticonsDropdown, { EMOTICONSSTICKERGROUP } from "./emoticonsDropdown";
|
||||||
import lottieLoader from "../lib/lottieLoader";
|
import lottieLoader from "../lib/lottieLoader";
|
||||||
|
import { Layouter, RectPart } from "./groupedLayout";
|
||||||
|
|
||||||
export class ChatInput {
|
export class ChatInput {
|
||||||
public pageEl = document.querySelector('.page-chats') as HTMLDivElement;
|
public pageEl = document.querySelector('.page-chats') as HTMLDivElement;
|
||||||
@ -187,67 +188,44 @@ export class ChatInput {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let attachFile = (file: File) => {
|
let attachFile = (file: File) => {
|
||||||
willAttach.file = file;
|
return new Promise<HTMLDivElement>((resolve, reject) => {
|
||||||
delete willAttach.objectURL;
|
let params: SendFileParams = {};
|
||||||
delete willAttach.duration;
|
params.file = file;
|
||||||
delete willAttach.width;
|
|
||||||
delete willAttach.height;
|
|
||||||
|
|
||||||
this.fileInput.value = '';
|
|
||||||
|
|
||||||
this.attachMediaPopUp.captionInput.value = '';
|
|
||||||
this.attachMediaPopUp.mediaContainer.innerHTML = '';
|
|
||||||
this.attachMediaPopUp.mediaContainer.style.width = '';
|
|
||||||
this.attachMediaPopUp.mediaContainer.style.height = '';
|
|
||||||
this.attachMediaPopUp.mediaContainer.classList.remove('is-document');
|
|
||||||
|
|
||||||
if(willAttach.type == 'media' && !['image/', 'video/'].find(s => file.type.indexOf(s) === 0)) {
|
|
||||||
willAttach.type = 'document';
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('selected file:', file, typeof(file), willAttach);
|
console.log('selected file:', file, typeof(file), willAttach);
|
||||||
|
let itemDiv = document.createElement('div');
|
||||||
switch(willAttach.type) {
|
switch(willAttach.type) {
|
||||||
case 'media': {
|
case 'media': {
|
||||||
let isVideo = file.type.indexOf('video/') === 0;
|
let isVideo = file.type.indexOf('video/') === 0;
|
||||||
|
|
||||||
|
itemDiv.classList.add('popup-item-media');
|
||||||
|
|
||||||
if(isVideo) {
|
if(isVideo) {
|
||||||
let video = document.createElement('video');
|
let video = document.createElement('video');
|
||||||
let source = document.createElement('source');
|
let source = document.createElement('source');
|
||||||
source.src = willAttach.objectURL = URL.createObjectURL(file);
|
source.src = params.objectURL = URL.createObjectURL(file);
|
||||||
video.autoplay = false;
|
video.autoplay = false;
|
||||||
video.controls = false;
|
video.controls = false;
|
||||||
|
|
||||||
video.onloadeddata = () => {
|
video.onloadeddata = () => {
|
||||||
willAttach.width = video.videoWidth;
|
params.width = video.videoWidth;
|
||||||
willAttach.height = video.videoHeight;
|
params.height = video.videoHeight;
|
||||||
willAttach.duration = Math.floor(video.duration);
|
params.duration = Math.floor(video.duration);
|
||||||
|
|
||||||
let {w, h} = calcImageInBox(willAttach.width, willAttach.height, 378, 256);
|
itemDiv.append(video);
|
||||||
this.attachMediaPopUp.mediaContainer.style.width = w + 'px';
|
resolve(itemDiv);
|
||||||
this.attachMediaPopUp.mediaContainer.style.height = h + 'px';
|
|
||||||
this.attachMediaPopUp.mediaContainer.append(video);
|
|
||||||
this.attachMediaPopUp.container.classList.add('active');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
video.append(source);
|
video.append(source);
|
||||||
|
|
||||||
this.attachMediaPopUp.titleEl.innerText = 'Send Video';
|
|
||||||
} else {
|
} else {
|
||||||
let img = new Image();
|
let img = new Image();
|
||||||
img.src = willAttach.objectURL = URL.createObjectURL(file);
|
img.src = params.objectURL = URL.createObjectURL(file);
|
||||||
img.onload = () => {
|
img.onload = () => {
|
||||||
willAttach.width = img.naturalWidth;
|
params.width = img.naturalWidth;
|
||||||
willAttach.height = img.naturalHeight;
|
params.height = img.naturalHeight;
|
||||||
|
|
||||||
let {w, h} = calcImageInBox(willAttach.width, willAttach.height, 378, 256);
|
itemDiv.append(img);
|
||||||
this.attachMediaPopUp.mediaContainer.style.width = w + 'px';
|
resolve(itemDiv);
|
||||||
this.attachMediaPopUp.mediaContainer.style.height = h + 'px';
|
|
||||||
this.attachMediaPopUp.mediaContainer.append(img);
|
|
||||||
this.attachMediaPopUp.container.classList.add('active');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.attachMediaPopUp.titleEl.innerText = 'Send Photo';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -261,34 +239,127 @@ export class ChatInput {
|
|||||||
type: file.type.indexOf('image/') !== -1 ? 'photo' : 'doc'
|
type: file.type.indexOf('image/') !== -1 ? 'photo' : 'doc'
|
||||||
} as any, false, true);
|
} as any, false, true);
|
||||||
|
|
||||||
this.attachMediaPopUp.titleEl.innerText = 'Send File';
|
itemDiv.append(docDiv);
|
||||||
|
resolve(itemDiv);
|
||||||
this.attachMediaPopUp.mediaContainer.append(docDiv);
|
|
||||||
this.attachMediaPopUp.mediaContainer.classList.add('is-document');
|
|
||||||
this.attachMediaPopUp.container.classList.add('active');
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
willAttach.sendFileDetails.push(params);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let willAttach: Partial<{
|
let attachFiles = (files: File[]) => {
|
||||||
type: 'media' | 'document',
|
this.fileInput.value = '';
|
||||||
isMedia: boolean,
|
|
||||||
|
let container = this.attachMediaPopUp.container.firstElementChild as HTMLElement;
|
||||||
|
container.classList.remove('is-media', 'is-document', 'is-album');
|
||||||
|
|
||||||
|
this.attachMediaPopUp.captionInput.value = '';
|
||||||
|
this.attachMediaPopUp.mediaContainer.innerHTML = '';
|
||||||
|
this.attachMediaPopUp.mediaContainer.style.width = this.attachMediaPopUp.mediaContainer.style.height = '';
|
||||||
|
//willAttach.sendFileDetails.length = 0;
|
||||||
|
willAttach.sendFileDetails = []; // need new array
|
||||||
|
|
||||||
|
files = files.filter(file => {
|
||||||
|
if(willAttach.type == 'media') {
|
||||||
|
return ['image/', 'video/'].find(s => file.type.indexOf(s) === 0);
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(files.length) {
|
||||||
|
if(willAttach.type == 'document') {
|
||||||
|
this.attachMediaPopUp.titleEl.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) {
|
||||||
|
this.attachMediaPopUp.titleEl.innerText = 'Send Album';
|
||||||
|
} else if(foundPhotos) {
|
||||||
|
this.attachMediaPopUp.titleEl.innerText = 'Send ' + (foundPhotos > 1 ? foundPhotos + ' Photos' : 'Photo');
|
||||||
|
} else if(foundVideos) {
|
||||||
|
this.attachMediaPopUp.titleEl.innerText = 'Send ' + (foundVideos > 1 ? foundVideos + ' Videos' : 'Video');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise.all(files.map(attachFile)).then(results => {
|
||||||
|
if(willAttach.type == 'media') {
|
||||||
|
if(willAttach.sendFileDetails.length > 1) {
|
||||||
|
container.classList.add('is-album');
|
||||||
|
|
||||||
|
let layouter = new Layouter(willAttach.sendFileDetails.map(o => ({w: o.width, h: o.height})), 380, 100, 4);
|
||||||
|
let layout = layouter.layout();
|
||||||
|
|
||||||
|
for(let {geometry, sides} of layout) {
|
||||||
|
let div = results.shift();
|
||||||
|
|
||||||
|
div.style.width = geometry.width + 'px';
|
||||||
|
div.style.height = geometry.height + 'px';
|
||||||
|
div.style.top = geometry.y + 'px';
|
||||||
|
div.style.left = geometry.x + 'px';
|
||||||
|
|
||||||
|
if(sides & RectPart.Right) {
|
||||||
|
this.attachMediaPopUp.mediaContainer.style.width = geometry.width + geometry.x + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sides & RectPart.Bottom) {
|
||||||
|
this.attachMediaPopUp.mediaContainer.style.height = geometry.height + geometry.y + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.attachMediaPopUp.mediaContainer.append(div);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('chatInput album layout:', layout);
|
||||||
|
} else {
|
||||||
|
let params = willAttach.sendFileDetails[0];
|
||||||
|
let div = results[0];
|
||||||
|
let {w, h} = calcImageInBox(params.width, params.height, 380, 320);
|
||||||
|
div.style.width = w + 'px';
|
||||||
|
div.style.height = h + 'px';
|
||||||
|
this.attachMediaPopUp.mediaContainer.append(div);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.attachMediaPopUp.mediaContainer.append(...results);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.attachMediaPopUp.container.classList.add('active');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
type SendFileParams = Partial<{
|
||||||
file: File,
|
file: File,
|
||||||
caption: string,
|
|
||||||
objectURL: string,
|
objectURL: string,
|
||||||
width: number,
|
width: number,
|
||||||
height: number,
|
height: number,
|
||||||
duration: number
|
duration: number
|
||||||
}> = {};
|
}>;
|
||||||
|
|
||||||
|
let willAttach: Partial<{
|
||||||
|
type: 'media' | 'document',
|
||||||
|
isMedia: boolean,
|
||||||
|
sendFileDetails: SendFileParams[]
|
||||||
|
}> = {
|
||||||
|
sendFileDetails: []
|
||||||
|
};
|
||||||
|
|
||||||
this.fileInput.addEventListener('change', (e) => {
|
this.fileInput.addEventListener('change', (e) => {
|
||||||
var file = (e.target as HTMLInputElement & EventTarget).files[0];
|
let files = (e.target as HTMLInputElement & EventTarget).files;
|
||||||
if(!file) {
|
if(!files.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
attachFile(file);
|
attachFiles(Array.from(files));
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.attachMenu.media.addEventListener('click', () => {
|
this.attachMenu.media.addEventListener('click', () => {
|
||||||
@ -329,10 +400,43 @@ export class ChatInput {
|
|||||||
|
|
||||||
this.attachMediaPopUp.sendBtn.addEventListener('click', () => {
|
this.attachMediaPopUp.sendBtn.addEventListener('click', () => {
|
||||||
this.attachMediaPopUp.container.classList.remove('active');
|
this.attachMediaPopUp.container.classList.remove('active');
|
||||||
willAttach.caption = this.attachMediaPopUp.captionInput.value;
|
let caption = this.attachMediaPopUp.captionInput.value;
|
||||||
willAttach.isMedia = willAttach.type == 'media';
|
willAttach.isMedia = willAttach.type == 'media';
|
||||||
|
|
||||||
appMessagesManager.sendFile(appImManager.peerID, willAttach.file, willAttach);
|
console.log('will send files with options:', willAttach);
|
||||||
|
|
||||||
|
let peerID = appImManager.peerID;
|
||||||
|
|
||||||
|
if(willAttach.sendFileDetails.length > 1 && willAttach.isMedia) {
|
||||||
|
appMessagesManager.sendAlbum(peerID, willAttach.sendFileDetails.map(d => d.file), Object.assign({
|
||||||
|
caption,
|
||||||
|
replyToMsgID: this.replyToMsgID
|
||||||
|
}, willAttach));
|
||||||
|
} else {
|
||||||
|
if(caption) {
|
||||||
|
if(willAttach.sendFileDetails.length > 1) {
|
||||||
|
appMessagesManager.sendText(peerID, caption, {replyToMsgID: this.replyToMsgID});
|
||||||
|
caption = '';
|
||||||
|
this.replyToMsgID = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let promises = willAttach.sendFileDetails.map(params => {
|
||||||
|
let promise = appMessagesManager.sendFile(peerID, params.file, Object.assign({
|
||||||
|
isMedia: willAttach.isMedia,
|
||||||
|
caption,
|
||||||
|
replyToMsgID: this.replyToMsgID
|
||||||
|
}, params));
|
||||||
|
|
||||||
|
caption = '';
|
||||||
|
this.replyToMsgID = 0;
|
||||||
|
return promise;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Promise.all(promises);
|
||||||
|
|
||||||
|
//appMessagesManager.sendFile(appImManager.peerID, willAttach.file, willAttach);
|
||||||
|
|
||||||
this.onMessageSent();
|
this.onMessageSent();
|
||||||
});
|
});
|
||||||
|
@ -4,7 +4,6 @@ import { CancellablePromise } from "../lib/polyfill";
|
|||||||
export default class ProgressivePreloader {
|
export default class ProgressivePreloader {
|
||||||
public preloader: HTMLDivElement = null;
|
public preloader: HTMLDivElement = null;
|
||||||
private circle: SVGCircleElement = null;
|
private circle: SVGCircleElement = null;
|
||||||
private progress = 0;
|
|
||||||
private promise: CancellablePromise<any> = null;
|
private promise: CancellablePromise<any> = null;
|
||||||
private tempID = 0;
|
private tempID = 0;
|
||||||
private detached = true;
|
private detached = true;
|
||||||
@ -103,8 +102,6 @@ export default class ProgressivePreloader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setProgress(percents: number) {
|
public setProgress(percents: number) {
|
||||||
this.progress = percents;
|
|
||||||
|
|
||||||
if(!isInDOM(this.circle)) {
|
if(!isInDOM(this.circle)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import appPhotosManager from '../lib/appManagers/appPhotosManager';
|
import appPhotosManager, { MTPhoto } from '../lib/appManagers/appPhotosManager';
|
||||||
//import CryptoWorker from '../lib/crypto/cryptoworker';
|
//import CryptoWorker from '../lib/crypto/cryptoworker';
|
||||||
import apiManager from '../lib/mtproto/mtprotoworker';
|
import apiManager from '../lib/mtproto/mtprotoworker';
|
||||||
import LottieLoader from '../lib/lottieLoader';
|
import LottieLoader from '../lib/lottieLoader';
|
||||||
@ -13,6 +13,8 @@ import VideoPlayer, { MediaProgressLine } from '../lib/mediaPlayer';
|
|||||||
import { RichTextProcessor } from '../lib/richtextprocessor';
|
import { RichTextProcessor } from '../lib/richtextprocessor';
|
||||||
import { CancellablePromise } from '../lib/polyfill';
|
import { CancellablePromise } from '../lib/polyfill';
|
||||||
import { renderImageFromUrl } from './misc';
|
import { renderImageFromUrl } from './misc';
|
||||||
|
import appMessagesManager from '../lib/appManagers/appMessagesManager';
|
||||||
|
import { Layouter, RectPart } from './groupedLayout';
|
||||||
|
|
||||||
export type MTDocument = {
|
export type MTDocument = {
|
||||||
_: 'document' | 'documentEmpty',
|
_: 'document' | 'documentEmpty',
|
||||||
@ -75,6 +77,17 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
|
|||||||
|
|
||||||
if(withTail) {
|
if(withTail) {
|
||||||
img = wrapMediaWithTail(doc, message, container, boxWidth, boxHeight, isOut);
|
img = wrapMediaWithTail(doc, message, container, boxWidth, boxHeight, isOut);
|
||||||
|
} else if(!boxWidth && !boxHeight) { // album
|
||||||
|
let sizes = doc.thumbs;
|
||||||
|
if(!doc.downloaded && sizes && sizes[0].bytes) {
|
||||||
|
appPhotosManager.setAttachmentPreview(sizes[0].bytes, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
img = container.firstElementChild as HTMLImageElement || new Image();
|
||||||
|
|
||||||
|
if(!container.contains(img)) {
|
||||||
|
container.append(img);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if(!container.firstElementChild || (container.firstElementChild.tagName != 'IMG' && container.firstElementChild.tagName != 'VIDEO')) {
|
if(!container.firstElementChild || (container.firstElementChild.tagName != 'IMG' && container.firstElementChild.tagName != 'VIDEO')) {
|
||||||
let size = appPhotosManager.setAttachmentSize(doc, container, boxWidth, boxHeight);
|
let size = appPhotosManager.setAttachmentSize(doc, container, boxWidth, boxHeight);
|
||||||
@ -106,7 +119,9 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
|
|||||||
let loadVideo = () => {
|
let loadVideo = () => {
|
||||||
let promise = appDocsManager.downloadDoc(doc);
|
let promise = appDocsManager.downloadDoc(doc);
|
||||||
|
|
||||||
if(!doc.downloaded) {
|
if(message.media.preloader) { // means upload
|
||||||
|
message.media.preloader.attach(container);
|
||||||
|
} else if(!doc.downloaded) {
|
||||||
let preloader = new ProgressivePreloader(container, true);
|
let preloader = new ProgressivePreloader(container, true);
|
||||||
preloader.attach(container, true, promise);
|
preloader.attach(container, true, promise);
|
||||||
}
|
}
|
||||||
@ -600,14 +615,24 @@ function wrapMediaWithTail(photo: any, message: {mid: number, message: string},
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function wrapPhoto(photoID: string, message: any, container: HTMLDivElement, boxWidth = 380, boxHeight = 380, withTail = true, isOut = false, lazyLoadQueue: LazyLoadQueue, middleware: () => boolean) {
|
export function wrapPhoto(photoID: string, message: any, container: HTMLDivElement, boxWidth = 380, boxHeight = 380, withTail = true, isOut = false, lazyLoadQueue: LazyLoadQueue, middleware: () => boolean, size: MTPhotoSize = null) {
|
||||||
let photo = appPhotosManager.getPhoto(photoID);
|
let photo = appPhotosManager.getPhoto(photoID);
|
||||||
|
|
||||||
let size: MTPhotoSize;
|
|
||||||
let image: SVGImageElement | HTMLImageElement;
|
let image: SVGImageElement | HTMLImageElement;
|
||||||
if(withTail) {
|
if(withTail) {
|
||||||
image = wrapMediaWithTail(photo, message, container, boxWidth, boxHeight, isOut);
|
image = wrapMediaWithTail(photo, message, container, boxWidth, boxHeight, isOut);
|
||||||
} else { // means webpage's preview
|
} else if(size) { // album
|
||||||
|
let sizes = photo.sizes;
|
||||||
|
if(!photo.downloaded && sizes && sizes[0].bytes) {
|
||||||
|
appPhotosManager.setAttachmentPreview(sizes[0].bytes, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
image = container.firstElementChild as HTMLImageElement || new Image();
|
||||||
|
|
||||||
|
if(!container.contains(image)) {
|
||||||
|
container.appendChild(image);
|
||||||
|
}
|
||||||
|
} else if(boxWidth && boxHeight) { // means webpage's preview
|
||||||
size = appPhotosManager.setAttachmentSize(photoID, container, boxWidth, boxHeight, false);
|
size = appPhotosManager.setAttachmentSize(photoID, container, boxWidth, boxHeight, false);
|
||||||
|
|
||||||
image = container.firstElementChild as HTMLImageElement || new Image();
|
image = container.firstElementChild as HTMLImageElement || new Image();
|
||||||
@ -626,7 +651,12 @@ export function wrapPhoto(photoID: string, message: any, container: HTMLDivEleme
|
|||||||
} */
|
} */
|
||||||
|
|
||||||
let preloader: ProgressivePreloader;
|
let preloader: ProgressivePreloader;
|
||||||
if(!photo.downloaded) preloader = new ProgressivePreloader(container, false);
|
if(message.media.preloader) { // means upload
|
||||||
|
message.media.preloader.attach(container);
|
||||||
|
} else if(!photo.downloaded) {
|
||||||
|
preloader = new ProgressivePreloader(container, false);
|
||||||
|
}
|
||||||
|
|
||||||
let load = () => {
|
let load = () => {
|
||||||
let promise = appPhotosManager.preloadPhoto(photoID, size);
|
let promise = appPhotosManager.preloadPhoto(photoID, size);
|
||||||
|
|
||||||
@ -637,7 +667,7 @@ export function wrapPhoto(photoID: string, message: any, container: HTMLDivEleme
|
|||||||
return promise.then(() => {
|
return promise.then(() => {
|
||||||
if(middleware && !middleware()) return;
|
if(middleware && !middleware()) return;
|
||||||
|
|
||||||
renderImageFromUrl(image, photo.url);
|
renderImageFromUrl(image || container, photo.url);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -854,3 +884,128 @@ export function wrapReply(title: string, subtitle: string, media?: any) {
|
|||||||
|
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function wrapAlbum({groupID, attachmentDiv, middleware, uploading, lazyLoadQueue, isOut}: {
|
||||||
|
groupID: string,
|
||||||
|
attachmentDiv: HTMLElement,
|
||||||
|
middleware?: () => boolean,
|
||||||
|
lazyLoadQueue?: LazyLoadQueue,
|
||||||
|
uploading?: boolean,
|
||||||
|
isOut: boolean
|
||||||
|
}) {
|
||||||
|
let items: {size: MTPhotoSize, media: any, message: any}[] = [];
|
||||||
|
|
||||||
|
// higher msgID will be the last in album
|
||||||
|
let storage = appMessagesManager.groupedMessagesStorage[groupID];
|
||||||
|
for(let mid in storage) {
|
||||||
|
let m = appMessagesManager.getMessage(+mid);
|
||||||
|
let media = m.media.photo || m.media.document;
|
||||||
|
|
||||||
|
let size: any = media._ == 'photo' ? appPhotosManager.choosePhotoSize(media, 380, 380) : {w: media.w, h: media.h};
|
||||||
|
items.push({size, media, message: m});
|
||||||
|
}
|
||||||
|
|
||||||
|
let spacing = 2;
|
||||||
|
let layouter = new Layouter(items.map(i => ({w: i.size.w, h: i.size.h})), 451, 100, spacing);
|
||||||
|
let layout = layouter.layout();
|
||||||
|
console.log('layout:', layout, items.map(i => ({w: i.size.w, h: i.size.h})));
|
||||||
|
|
||||||
|
/* let borderRadius = window.getComputedStyle(realParent).getPropertyValue('border-radius');
|
||||||
|
let brSplitted = fillPropertyValue(borderRadius); */
|
||||||
|
|
||||||
|
for(let {geometry, sides} of layout) {
|
||||||
|
let {size, media, message} = items.shift();
|
||||||
|
let div = document.createElement('div');
|
||||||
|
div.classList.add('album-item');
|
||||||
|
div.dataset.mid = message.mid;
|
||||||
|
|
||||||
|
div.style.width = geometry.width + 'px';
|
||||||
|
div.style.height = geometry.height + 'px';
|
||||||
|
div.style.top = geometry.y + 'px';
|
||||||
|
div.style.left = geometry.x + 'px';
|
||||||
|
|
||||||
|
if(sides & RectPart.Right) {
|
||||||
|
attachmentDiv.style.width = geometry.width + geometry.x + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sides & RectPart.Bottom) {
|
||||||
|
attachmentDiv.style.height = geometry.height + geometry.y + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sides & RectPart.Left && sides & RectPart.Top) {
|
||||||
|
div.style.borderTopLeftRadius = 'inherit';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sides & RectPart.Left && sides & RectPart.Bottom) {
|
||||||
|
div.style.borderBottomLeftRadius = 'inherit';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sides & RectPart.Right && sides & RectPart.Top) {
|
||||||
|
div.style.borderTopRightRadius = 'inherit';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sides & RectPart.Right && sides & RectPart.Bottom) {
|
||||||
|
div.style.borderBottomRightRadius = 'inherit';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(media._ == 'photo') {
|
||||||
|
wrapPhoto(
|
||||||
|
media.id,
|
||||||
|
message,
|
||||||
|
div,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
isOut,
|
||||||
|
lazyLoadQueue,
|
||||||
|
middleware,
|
||||||
|
size
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
wrapVideo({
|
||||||
|
doc: message.media.document,
|
||||||
|
container: div,
|
||||||
|
message,
|
||||||
|
boxWidth: 0,
|
||||||
|
boxHeight: 0,
|
||||||
|
withTail: false,
|
||||||
|
isOut,
|
||||||
|
lazyLoadQueue,
|
||||||
|
middleware
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* let load = () => appPhotosManager.preloadPhoto(media._ == 'photo' ? media.id : media, size)
|
||||||
|
.then((blob) => {
|
||||||
|
if(middleware && !middleware()) {
|
||||||
|
console.warn('peer changed');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!uploading) {
|
||||||
|
preloader.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(media && media.url) {
|
||||||
|
renderImageFromUrl(div, media.url);
|
||||||
|
} else {
|
||||||
|
let url = URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
let img = new Image();
|
||||||
|
img.src = url;
|
||||||
|
img.onload = () => {
|
||||||
|
div.style.backgroundImage = 'url(' + url + ')';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//div.style.backgroundImage = 'url(' + url + ')';
|
||||||
|
});
|
||||||
|
|
||||||
|
load(); */
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
//div.style.backgroundColor = '#' + Math.floor(Math.random() * (2 ** 24 - 1)).toString(16).padStart(6, '0');
|
||||||
|
|
||||||
|
attachmentDiv.append(div);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -145,6 +145,21 @@ class AppDocsManager {
|
|||||||
return isObject(docID) ? docID : this.docs[docID];
|
return isObject(docID) ? docID : this.docs[docID];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getInputByID(docID: any) {
|
||||||
|
let doc = this.getDoc(docID);
|
||||||
|
return {
|
||||||
|
_: 'inputMediaDocument',
|
||||||
|
flags: 0,
|
||||||
|
id: {
|
||||||
|
_: 'inputDocument',
|
||||||
|
id: doc.id,
|
||||||
|
access_hash: doc.access_hash,
|
||||||
|
file_reference: doc.file_reference
|
||||||
|
},
|
||||||
|
ttl_seconds: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public getFileName(doc: MTDocument) {
|
public getFileName(doc: MTDocument) {
|
||||||
if(doc.file_name) {
|
if(doc.file_name) {
|
||||||
return doc.file_name;
|
return doc.file_name;
|
||||||
|
@ -17,15 +17,14 @@ import appSidebarLeft from "./appSidebarLeft";
|
|||||||
import appChatsManager from "./appChatsManager";
|
import appChatsManager from "./appChatsManager";
|
||||||
import appMessagesIDsManager from "./appMessagesIDsManager";
|
import appMessagesIDsManager from "./appMessagesIDsManager";
|
||||||
import apiUpdatesManager from './apiUpdatesManager';
|
import apiUpdatesManager from './apiUpdatesManager';
|
||||||
import { wrapDocument, wrapPhoto, wrapVideo, wrapSticker, wrapReply, MTPhotoSize } from '../../components/wrappers';
|
import { wrapDocument, wrapPhoto, wrapVideo, wrapSticker, wrapReply, wrapAlbum } from '../../components/wrappers';
|
||||||
import ProgressivePreloader from '../../components/preloader';
|
import ProgressivePreloader from '../../components/preloader';
|
||||||
import { openBtnMenu, renderImageFromUrl, formatPhoneNumber } from '../../components/misc';
|
import { openBtnMenu, formatPhoneNumber } from '../../components/misc';
|
||||||
import { ChatInput } from '../../components/chatInput';
|
import { ChatInput } from '../../components/chatInput';
|
||||||
import Scrollable from '../../components/scrollable';
|
import Scrollable from '../../components/scrollable';
|
||||||
import BubbleGroups from '../../components/bubbleGroups';
|
import BubbleGroups from '../../components/bubbleGroups';
|
||||||
import LazyLoadQueue from '../../components/lazyLoadQueue';
|
import LazyLoadQueue from '../../components/lazyLoadQueue';
|
||||||
import appDocsManager from './appDocsManager';
|
import appDocsManager from './appDocsManager';
|
||||||
import { Layouter, RectPart } from '../../components/groupedLayout';
|
|
||||||
|
|
||||||
console.log('appImManager included!');
|
console.log('appImManager included!');
|
||||||
|
|
||||||
@ -192,13 +191,7 @@ export class AppImManager {
|
|||||||
$rootScope.$on('message_sent', (e: CustomEvent) => {
|
$rootScope.$on('message_sent', (e: CustomEvent) => {
|
||||||
let {tempID, mid} = e.detail;
|
let {tempID, mid} = e.detail;
|
||||||
|
|
||||||
////this.log('message_sent', e.detail);
|
this.log('message_sent', e.detail);
|
||||||
|
|
||||||
let bubble = this.bubbles[tempID];
|
|
||||||
if(bubble) {
|
|
||||||
this.bubbles[mid] = bubble;
|
|
||||||
|
|
||||||
/////this.log('message_sent', bubble);
|
|
||||||
|
|
||||||
// set cached url to media
|
// set cached url to media
|
||||||
let message = appMessagesManager.getMessage(mid);
|
let message = appMessagesManager.getMessage(mid);
|
||||||
@ -220,6 +213,21 @@ export class AppImManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let bubble = this.bubbles[tempID];
|
||||||
|
if(bubble) {
|
||||||
|
this.bubbles[mid] = bubble;
|
||||||
|
|
||||||
|
/////this.log('message_sent', bubble);
|
||||||
|
|
||||||
|
// set new mids to album items for mediaViewer
|
||||||
|
if(message.grouped_id) {
|
||||||
|
let items = bubble.querySelectorAll('.album-item');
|
||||||
|
let groupIDs = Object.keys(appMessagesManager.groupedMessagesStorage[message.grouped_id]).map(i => +i).sort((a, b) => a - b);
|
||||||
|
(Array.from(items) as HTMLElement[]).forEach((item, idx) => {
|
||||||
|
item.dataset.mid = '' + groupIDs[idx];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
bubble.classList.remove('is-sending');
|
bubble.classList.remove('is-sending');
|
||||||
bubble.classList.add('is-sent');
|
bubble.classList.add('is-sent');
|
||||||
bubble.dataset.mid = mid;
|
bubble.dataset.mid = mid;
|
||||||
@ -243,11 +251,16 @@ export class AppImManager {
|
|||||||
let {peerID, mid, id, justMedia} = e.detail;
|
let {peerID, mid, id, justMedia} = e.detail;
|
||||||
|
|
||||||
if(peerID != this.peerID) return;
|
if(peerID != this.peerID) return;
|
||||||
|
let message = appMessagesManager.getMessage(mid);
|
||||||
|
|
||||||
let bubble = this.bubbles[mid];
|
let bubble = this.bubbles[mid];
|
||||||
|
if(!bubble && message.grouped_id) {
|
||||||
|
let a = this.getAlbumBubble(message.grouped_id);
|
||||||
|
bubble = a.bubble;
|
||||||
|
message = a.message;
|
||||||
|
}
|
||||||
if(!bubble) return;
|
if(!bubble) return;
|
||||||
|
|
||||||
let message = appMessagesManager.getMessage(mid);
|
|
||||||
this.renderMessage(message, true, false, bubble, false);
|
this.renderMessage(message, true, false, bubble, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -320,7 +333,50 @@ export class AppImManager {
|
|||||||
|
|
||||||
if(!bubble) return;
|
if(!bubble) return;
|
||||||
|
|
||||||
if(['IMG', 'VIDEO', 'SVG', 'DIV', 'image'].indexOf(target.tagName) === -1) target = findUpTag(target, 'DIV');
|
if((target.tagName == 'IMG' && !target.classList.contains('emoji') && !target.parentElement.classList.contains('user-avatar'))
|
||||||
|
|| target.tagName == 'image'
|
||||||
|
|| target.classList.contains('album-item')
|
||||||
|
|| (target.tagName == 'VIDEO' && !bubble.classList.contains('round'))) {
|
||||||
|
let messageID = +findUpClassName(target, 'album-item')?.dataset.mid || +bubble.dataset.mid;
|
||||||
|
let message = appMessagesManager.getMessage(messageID);
|
||||||
|
if(!message) {
|
||||||
|
this.log.warn('no message by messageID:', messageID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let targets: {element: HTMLElement, mid: number}[] = [];
|
||||||
|
let ids = Object.keys(this.bubbles).map(k => +k).filter(id => {
|
||||||
|
//if(!this.scrollable.visibleElements.find(e => e.element == this.bubbles[id])) return false;
|
||||||
|
|
||||||
|
let message = appMessagesManager.getMessage(id);
|
||||||
|
|
||||||
|
return message.media && (message.media.photo || (message.media.document && (message.media.document.type == 'video' || message.media.document.type == 'gif')) || (message.media.webpage && (message.media.webpage.document || message.media.webpage.photo)));
|
||||||
|
}).sort((a, b) => a - b);
|
||||||
|
|
||||||
|
ids.forEach(id => {
|
||||||
|
let bubble = this.bubbles[id];
|
||||||
|
|
||||||
|
let elements = this.bubbles[id].querySelectorAll('.attachment img, .preview img, video, .bubble__media-container') as NodeListOf<HTMLElement>;
|
||||||
|
Array.from(elements).forEach((element: HTMLElement) => {
|
||||||
|
let albumItem = findUpClassName(element, 'album-item');
|
||||||
|
targets.push({
|
||||||
|
element,
|
||||||
|
mid: +albumItem?.dataset.mid || id
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let idx = targets.findIndex(t => t.mid == messageID);
|
||||||
|
|
||||||
|
this.log('open mediaViewer single with ids:', ids, idx, targets);
|
||||||
|
|
||||||
|
appMediaViewer.openMedia(message, targets[idx].element, true,
|
||||||
|
this.scroll.parentElement, targets.slice(0, idx), targets.slice(idx + 1)/* , !message.grouped_id */);
|
||||||
|
|
||||||
|
//appMediaViewer.openMedia(message, target as HTMLImageElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(['IMG', 'DIV'].indexOf(target.tagName) === -1) target = findUpTag(target, 'DIV');
|
||||||
|
|
||||||
if(target.tagName == 'DIV') {
|
if(target.tagName == 'DIV') {
|
||||||
if(target.classList.contains('forward')) {
|
if(target.classList.contains('forward')) {
|
||||||
@ -351,49 +407,12 @@ export class AppImManager {
|
|||||||
let originalMessageID = +bubble.getAttribute('data-original-mid');
|
let originalMessageID = +bubble.getAttribute('data-original-mid');
|
||||||
this.setPeer(this.peerID, originalMessageID);
|
this.setPeer(this.peerID, originalMessageID);
|
||||||
}
|
}
|
||||||
} else if(bubble.classList.contains('round')) {
|
|
||||||
|
|
||||||
} else if(target.tagName == 'IMG' && target.parentElement.classList.contains('user-avatar')) {
|
} else if(target.tagName == 'IMG' && target.parentElement.classList.contains('user-avatar')) {
|
||||||
let peerID = +target.parentElement.dataset.peerID;
|
let peerID = +target.parentElement.dataset.peerID;
|
||||||
|
|
||||||
if(!isNaN(peerID)) {
|
if(!isNaN(peerID)) {
|
||||||
this.setPeer(peerID);
|
this.setPeer(peerID);
|
||||||
}
|
}
|
||||||
} else if((target.tagName == 'IMG' && !target.classList.contains('emoji')) || target.tagName == 'image' || target.tagName == 'VIDEO') {
|
|
||||||
let messageID = 0;
|
|
||||||
for(let mid in this.bubbles) {
|
|
||||||
if(this.bubbles[mid] == bubble) {
|
|
||||||
messageID = +mid;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let message = appMessagesManager.getMessage(messageID);
|
|
||||||
if(!message) {
|
|
||||||
this.log.warn('no message by messageID:', messageID);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let ids = Object.keys(this.bubbles).map(k => +k).filter(id => {
|
|
||||||
//if(!this.scrollable.visibleElements.find(e => e.element == this.bubbles[id])) return false;
|
|
||||||
|
|
||||||
let message = appMessagesManager.getMessage(id);
|
|
||||||
|
|
||||||
return message.media && (message.media.photo || (message.media.document && (message.media.document.type == 'video' || message.media.document.type == 'gif')) || (message.media.webpage && (message.media.webpage.document || message.media.webpage.photo)));
|
|
||||||
}).sort((a, b) => a - b);
|
|
||||||
let idx = ids.findIndex(i => i == messageID);
|
|
||||||
|
|
||||||
let targets = ids.map(id => ({
|
|
||||||
//element: (this.bubbles[id].querySelector('img, video') || this.bubbles[id].querySelector('image')) as HTMLElement,
|
|
||||||
element: this.bubbles[id].querySelector('.attachment img, .preview img, video, .bubble__media-container, .album-item') as HTMLElement,
|
|
||||||
mid: id
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.log('open mediaViewer with ids:', ids, idx, targets);
|
|
||||||
|
|
||||||
appMediaViewer.openMedia(message, targets[idx].element, true,
|
|
||||||
this.scroll.parentElement, targets.slice(0, idx), targets.slice(idx + 1));
|
|
||||||
|
|
||||||
//appMediaViewer.openMedia(message, target as HTMLImageElement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.log('chatInner click', e);
|
//console.log('chatInner click', e);
|
||||||
@ -656,6 +675,19 @@ export class AppImManager {
|
|||||||
return apiManager.invokeApi('account.updateStatus', {offline: this.offline});
|
return apiManager.invokeApi('account.updateStatus', {offline: this.offline});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getAlbumBubble(groupID: string) {
|
||||||
|
let group = appMessagesManager.groupedMessagesStorage[groupID];
|
||||||
|
for(let i in group) {
|
||||||
|
let mid = +i;
|
||||||
|
if(this.bubbles[mid]) return {
|
||||||
|
bubble: this.bubbles[mid],
|
||||||
|
message: appMessagesManager.getMessage(mid)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public loadMoreHistory(top: boolean) {
|
public loadMoreHistory(top: boolean) {
|
||||||
this.log('loadMoreHistory', top);
|
this.log('loadMoreHistory', top);
|
||||||
if(!this.peerID || testScroll || this.setPeerPromise || (top && this.getHistoryTopPromise) || (!top && this.getHistoryBottomPromise)) return;
|
if(!this.peerID || testScroll || this.setPeerPromise || (top && this.getHistoryTopPromise) || (!top && this.getHistoryBottomPromise)) return;
|
||||||
@ -1295,13 +1327,37 @@ export class AppImManager {
|
|||||||
timeInner.classList.add('inner', 'tgico');
|
timeInner.classList.add('inner', 'tgico');
|
||||||
timeInner.innerHTML = time;
|
timeInner.innerHTML = time;
|
||||||
|
|
||||||
let richText = RichTextProcessor.wrapRichText(message.message, {
|
let messageMessage: string, totalEntities: any[];
|
||||||
entities: message.totalEntities
|
if(message.grouped_id) {
|
||||||
|
let group = appMessagesManager.groupedMessagesStorage[message.grouped_id];
|
||||||
|
let foundMessages = 0;
|
||||||
|
for(let i in group) {
|
||||||
|
let m = group[i];
|
||||||
|
if(m.message) {
|
||||||
|
if(++foundMessages > 1) break;
|
||||||
|
messageMessage = m.message;
|
||||||
|
totalEntities = m.totalEntities;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(foundMessages > 1) {
|
||||||
|
messageMessage = undefined;
|
||||||
|
totalEntities = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!messageMessage && !totalEntities) {
|
||||||
|
messageMessage = message.message;
|
||||||
|
totalEntities = message.totalEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
let richText = RichTextProcessor.wrapRichText(messageMessage, {
|
||||||
|
entities: totalEntities
|
||||||
});
|
});
|
||||||
|
|
||||||
if(message.totalEntities) {
|
if(totalEntities) {
|
||||||
let emojiEntities = message.totalEntities.filter((e: any) => e._ == 'messageEntityEmoji');
|
let emojiEntities = totalEntities.filter((e: any) => e._ == 'messageEntityEmoji');
|
||||||
let strLength = message.message.length;
|
let strLength = messageMessage.length;
|
||||||
let emojiStrLength = emojiEntities.reduce((acc: number, curr: any) => acc + curr.length, 0);
|
let emojiStrLength = emojiEntities.reduce((acc: number, curr: any) => acc + curr.length, 0);
|
||||||
|
|
||||||
if(emojiStrLength == strLength && emojiEntities.length <= 3) {
|
if(emojiStrLength == strLength && emojiEntities.length <= 3) {
|
||||||
@ -1348,23 +1404,37 @@ export class AppImManager {
|
|||||||
let attachmentDiv = document.createElement('div');
|
let attachmentDiv = document.createElement('div');
|
||||||
attachmentDiv.classList.add('attachment');
|
attachmentDiv.classList.add('attachment');
|
||||||
|
|
||||||
if(!message.message) {
|
if(!messageMessage) {
|
||||||
bubble.classList.add('is-message-empty');
|
bubble.classList.add('is-message-empty');
|
||||||
}
|
}
|
||||||
|
|
||||||
let processingWebPage = false;
|
let processingWebPage = false;
|
||||||
|
|
||||||
switch(message.media._) {
|
switch(message.media._) {
|
||||||
case 'messageMediaPending': {
|
case 'messageMediaPending': {
|
||||||
let pending = message.media;
|
let pending = message.media;
|
||||||
let preloader = pending.preloader as ProgressivePreloader;
|
let preloader = pending.preloader as ProgressivePreloader;
|
||||||
|
|
||||||
switch(pending.type) {
|
switch(pending.type) {
|
||||||
|
case 'album': {
|
||||||
|
this.log('will wrap pending album');
|
||||||
|
|
||||||
|
bubble.classList.add('hide-name', 'photo', 'is-album');
|
||||||
|
wrapAlbum({
|
||||||
|
groupID: '' + message.id,
|
||||||
|
attachmentDiv,
|
||||||
|
uploading: true,
|
||||||
|
isOut: true
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'photo': {
|
case 'photo': {
|
||||||
//if(pending.size < 5e6) {
|
//if(pending.size < 5e6) {
|
||||||
this.log('will wrap pending photo:', pending, message, appPhotosManager.getPhoto(message.id));
|
this.log('will wrap pending photo:', pending, message, appPhotosManager.getPhoto(message.id));
|
||||||
wrapPhoto(message.id, message, attachmentDiv, undefined, undefined, true, true, this.lazyLoadQueue, null);
|
wrapPhoto(message.id, message, attachmentDiv, undefined, undefined, true, true, this.lazyLoadQueue, null);
|
||||||
|
|
||||||
preloader.attach(attachmentDiv, false);
|
|
||||||
bubble.classList.add('hide-name', 'photo');
|
bubble.classList.add('hide-name', 'photo');
|
||||||
//}
|
//}
|
||||||
|
|
||||||
@ -1401,6 +1471,7 @@ export class AppImManager {
|
|||||||
preloader.attach(icoDiv, false);
|
preloader.attach(icoDiv, false);
|
||||||
|
|
||||||
bubble.classList.remove('is-message-empty');
|
bubble.classList.remove('is-message-empty');
|
||||||
|
messageDiv.classList.add((pending.type || 'document') + '-message');
|
||||||
messageDiv.append(docDiv);
|
messageDiv.append(docDiv);
|
||||||
processingWebPage = true;
|
processingWebPage = true;
|
||||||
break;
|
break;
|
||||||
@ -1416,105 +1487,18 @@ export class AppImManager {
|
|||||||
////////this.log('messageMediaPhoto', photo);
|
////////this.log('messageMediaPhoto', photo);
|
||||||
|
|
||||||
bubble.classList.add('hide-name', 'photo');
|
bubble.classList.add('hide-name', 'photo');
|
||||||
|
|
||||||
if(message.grouped_id) {
|
if(message.grouped_id) {
|
||||||
bubble.classList.add('is-album');
|
bubble.classList.add('is-album');
|
||||||
|
|
||||||
let items: {size: MTPhotoSize, media: any}[] = [];
|
wrapAlbum({
|
||||||
|
groupID: message.grouped_id,
|
||||||
// higher msgID will be the last in album
|
attachmentDiv,
|
||||||
let storage = appMessagesManager.groupedMessagesStorage[message.grouped_id];
|
middleware: () => {
|
||||||
for(let mid in storage) {
|
return this.peerID == peerID;
|
||||||
let m = appMessagesManager.getMessage(+mid);
|
},
|
||||||
let media = m.media.photo || m.media.document;
|
isOut: our,
|
||||||
|
lazyLoadQueue: this.lazyLoadQueue
|
||||||
let size = appPhotosManager.choosePhotoSize(media, 380, 380);
|
|
||||||
items.push({size, media});
|
|
||||||
}
|
|
||||||
|
|
||||||
let spacing = 2;
|
|
||||||
let layouter = new Layouter(items.map(i => ({w: i.size.w, h: i.size.h})), 451, 100, spacing);
|
|
||||||
let layout = layouter.layout();
|
|
||||||
this.log('layout:', layout);
|
|
||||||
|
|
||||||
/* let borderRadius = window.getComputedStyle(realParent).getPropertyValue('border-radius');
|
|
||||||
let brSplitted = fillPropertyValue(borderRadius); */
|
|
||||||
|
|
||||||
for(let {geometry, sides} of layout) {
|
|
||||||
let {size, media} = items.shift();
|
|
||||||
let div = document.createElement('div');
|
|
||||||
div.classList.add('album-item');
|
|
||||||
|
|
||||||
div.style.width = geometry.width + 'px';
|
|
||||||
div.style.height = geometry.height + 'px';
|
|
||||||
div.style.top = geometry.y + 'px';
|
|
||||||
div.style.left = geometry.x + 'px';
|
|
||||||
|
|
||||||
if(sides & RectPart.Right) {
|
|
||||||
attachmentDiv.style.width = geometry.width + geometry.x + 'px';
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sides & RectPart.Bottom) {
|
|
||||||
attachmentDiv.style.height = geometry.height + geometry.y + 'px';
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sides & RectPart.Left && sides & RectPart.Top) {
|
|
||||||
div.style.borderTopLeftRadius = 'inherit';
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sides & RectPart.Left && sides & RectPart.Bottom) {
|
|
||||||
div.style.borderBottomLeftRadius = 'inherit';
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sides & RectPart.Right && sides & RectPart.Top) {
|
|
||||||
div.style.borderTopRightRadius = 'inherit';
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sides & RectPart.Right && sides & RectPart.Bottom) {
|
|
||||||
div.style.borderBottomRightRadius = 'inherit';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if(geometry.y != 0) {
|
|
||||||
div.style.marginTop = spacing + 'px';
|
|
||||||
}
|
|
||||||
|
|
||||||
if(geometry.x != 0) {
|
|
||||||
div.style.marginLeft = spacing + 'px';
|
|
||||||
} */
|
|
||||||
|
|
||||||
let preloader = new ProgressivePreloader(div);
|
|
||||||
|
|
||||||
let load = () => appPhotosManager.preloadPhoto(media._ == 'photo' ? media.id : media, size)
|
|
||||||
.then((blob) => {
|
|
||||||
if(this.peerID != peerID) {
|
|
||||||
this.log.warn('peer changed');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
preloader.detach();
|
|
||||||
if(media && media.url) {
|
|
||||||
renderImageFromUrl(div, media.url);
|
|
||||||
}/* else {
|
|
||||||
let url = URL.createObjectURL(blob);
|
|
||||||
this.urlsToRevoke.push(url);
|
|
||||||
|
|
||||||
let img = new Image();
|
|
||||||
img.src = url;
|
|
||||||
img.onload = () => {
|
|
||||||
div.style.backgroundImage = 'url(' + url + ')';
|
|
||||||
};
|
|
||||||
} */
|
|
||||||
|
|
||||||
//div.style.backgroundImage = 'url(' + url + ')';
|
|
||||||
});
|
});
|
||||||
|
|
||||||
load();
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
//div.style.backgroundColor = '#' + Math.floor(Math.random() * (2 ** 24 - 1)).toString(16).padStart(6, '0');
|
|
||||||
|
|
||||||
attachmentDiv.append(div);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
wrapPhoto(photo.id, message, attachmentDiv, undefined, undefined, true, our, this.lazyLoadQueue, () => {
|
wrapPhoto(photo.id, message, attachmentDiv, undefined, undefined, true, our, this.lazyLoadQueue, () => {
|
||||||
return this.peerID == peerID;
|
return this.peerID == peerID;
|
||||||
@ -1650,6 +1634,19 @@ export class AppImManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bubble.classList.add('hide-name', 'video');
|
bubble.classList.add('hide-name', 'video');
|
||||||
|
if(message.grouped_id) {
|
||||||
|
bubble.classList.add('is-album');
|
||||||
|
|
||||||
|
wrapAlbum({
|
||||||
|
groupID: message.grouped_id,
|
||||||
|
attachmentDiv,
|
||||||
|
middleware: () => {
|
||||||
|
return this.peerID == peerID;
|
||||||
|
},
|
||||||
|
isOut: our,
|
||||||
|
lazyLoadQueue: this.lazyLoadQueue
|
||||||
|
});
|
||||||
|
} else {
|
||||||
wrapVideo({
|
wrapVideo({
|
||||||
doc,
|
doc,
|
||||||
container: attachmentDiv,
|
container: attachmentDiv,
|
||||||
@ -1663,6 +1660,7 @@ export class AppImManager {
|
|||||||
return this.peerID == peerID;
|
return this.peerID == peerID;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} else if(doc.mime_type == 'audio/ogg') {
|
} else if(doc.mime_type == 'audio/ogg') {
|
||||||
|
@ -56,6 +56,7 @@ export class AppMediaViewer {
|
|||||||
private loadedAllMediaDown = false;
|
private loadedAllMediaDown = false;
|
||||||
|
|
||||||
private reverse = false; // reverse means next = higher msgid
|
private reverse = false; // reverse means next = higher msgid
|
||||||
|
private needLoadMore = true;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.log = logger('AMV');
|
this.log = logger('AMV');
|
||||||
@ -517,7 +518,7 @@ export class AppMediaViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public openMedia(message: any, target?: HTMLElement, reverse = false, targetContainer?: HTMLElement,
|
public openMedia(message: any, target?: HTMLElement, reverse = false, targetContainer?: HTMLElement,
|
||||||
prevTargets: AppMediaViewer['prevTargets'] = [], nextTargets: AppMediaViewer['prevTargets'] = [], loadMore: () => void = null) {
|
prevTargets: AppMediaViewer['prevTargets'] = [], nextTargets: AppMediaViewer['prevTargets'] = [], needLoadMore = true) {
|
||||||
////////this.log('openMedia doc:', message, prevTarget, nextTarget);
|
////////this.log('openMedia doc:', message, prevTarget, nextTarget);
|
||||||
let media = message.media.photo || message.media.document || message.media.webpage.document || message.media.webpage.photo;
|
let media = message.media.photo || message.media.document || message.media.webpage.document || message.media.webpage.photo;
|
||||||
|
|
||||||
@ -530,6 +531,7 @@ export class AppMediaViewer {
|
|||||||
this.prevTargets = prevTargets;
|
this.prevTargets = prevTargets;
|
||||||
this.nextTargets = nextTargets;
|
this.nextTargets = nextTargets;
|
||||||
this.reverse = reverse;
|
this.reverse = reverse;
|
||||||
|
this.needLoadMore = needLoadMore;
|
||||||
//this.loadMore = loadMore;
|
//this.loadMore = loadMore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,6 +559,7 @@ export class AppMediaViewer {
|
|||||||
this.currentMessageID = message.mid;
|
this.currentMessageID = message.mid;
|
||||||
this.lastTarget = target;
|
this.lastTarget = target;
|
||||||
|
|
||||||
|
if(this.needLoadMore) {
|
||||||
if(this.nextTargets.length < 20) {
|
if(this.nextTargets.length < 20) {
|
||||||
this.loadMoreMedia(!this.reverse);
|
this.loadMoreMedia(!this.reverse);
|
||||||
}
|
}
|
||||||
@ -564,6 +567,7 @@ export class AppMediaViewer {
|
|||||||
if(this.prevTargets.length < 20) {
|
if(this.prevTargets.length < 20) {
|
||||||
this.loadMoreMedia(this.reverse);
|
this.loadMoreMedia(this.reverse);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(container.firstElementChild) {
|
if(container.firstElementChild) {
|
||||||
container.innerHTML = '';
|
container.innerHTML = '';
|
||||||
|
@ -47,7 +47,7 @@ export class AppMessagesManager {
|
|||||||
count: any,
|
count: any,
|
||||||
dialogs: any[]
|
dialogs: any[]
|
||||||
} = {count: null, dialogs: []};
|
} = {count: null, dialogs: []};
|
||||||
public pendingByRandomID: any = {};
|
public pendingByRandomID: {[randomID: string]: [number, number]} = {};
|
||||||
public pendingByMessageID: any = {};
|
public pendingByMessageID: any = {};
|
||||||
public pendingAfterMsgs: any = {};
|
public pendingAfterMsgs: any = {};
|
||||||
public pendingTopMsgs: any = {};
|
public pendingTopMsgs: any = {};
|
||||||
@ -449,17 +449,18 @@ export class AppMessagesManager {
|
|||||||
this.pendingByRandomID[randomIDS] = [peerID, messageID];
|
this.pendingByRandomID[randomIDS] = [peerID, messageID];
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendFile(peerID: number, file: File | Blob | MTDocument, options: {
|
public sendFile(peerID: number, file: File | Blob | MTDocument, options: Partial<{
|
||||||
isMedia?: boolean,
|
isMedia: boolean,
|
||||||
replyToMsgID?: number,
|
replyToMsgID: number,
|
||||||
caption?: string,
|
caption: string,
|
||||||
entities?: any[],
|
entities: any[],
|
||||||
width?: number,
|
width: number,
|
||||||
height?: number,
|
height: number,
|
||||||
objectURL?: string,
|
objectURL: string,
|
||||||
isRoundMessage?: boolean,
|
isRoundMessage: boolean,
|
||||||
duration?: number
|
duration: number,
|
||||||
} = {}) {
|
background: boolean
|
||||||
|
}> = {}) {
|
||||||
peerID = AppPeersManager.getPeerMigratedTo(peerID) || peerID;
|
peerID = AppPeersManager.getPeerMigratedTo(peerID) || peerID;
|
||||||
var messageID = this.tempID--;
|
var messageID = this.tempID--;
|
||||||
var randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)];
|
var randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)];
|
||||||
@ -656,6 +657,8 @@ export class AppMessagesManager {
|
|||||||
|
|
||||||
return apiManager.invokeApi('messages.sendMedia', {
|
return apiManager.invokeApi('messages.sendMedia', {
|
||||||
flags: flags,
|
flags: flags,
|
||||||
|
background: options.background,
|
||||||
|
clear_draft: true,
|
||||||
peer: AppPeersManager.getInputPeerByID(peerID),
|
peer: AppPeersManager.getInputPeerByID(peerID),
|
||||||
media: inputMedia,
|
media: inputMedia,
|
||||||
message: caption,
|
message: caption,
|
||||||
@ -683,9 +686,10 @@ export class AppMessagesManager {
|
|||||||
if(replyToMsgID) {
|
if(replyToMsgID) {
|
||||||
flags |= 1;
|
flags |= 1;
|
||||||
}
|
}
|
||||||
if(asChannel) {
|
if(options.background) {
|
||||||
flags |= 16;
|
flags |= 64;
|
||||||
}
|
}
|
||||||
|
flags |= 128; // clear_draft
|
||||||
|
|
||||||
if(isDocument) {
|
if(isDocument) {
|
||||||
let {id, access_hash, file_reference} = file as MTDocument;
|
let {id, access_hash, file_reference} = file as MTDocument;
|
||||||
@ -777,6 +781,293 @@ export class AppMessagesManager {
|
|||||||
this.pendingByRandomID[randomIDS] = [peerID, messageID];
|
this.pendingByRandomID[randomIDS] = [peerID, messageID];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async sendAlbum(peerID: number, files: File[], options: Partial<{
|
||||||
|
entities: any[],
|
||||||
|
replyToMsgID: number,
|
||||||
|
caption: string,
|
||||||
|
sendFileDetails: Partial<{
|
||||||
|
duration: number,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
objectURL: string,
|
||||||
|
}>[]
|
||||||
|
}> = {}) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
let caption = options.caption || '';
|
||||||
|
|
||||||
|
let date = tsNow(true) + ServerTimeManager.serverTimeOffset;
|
||||||
|
|
||||||
|
if(caption) {
|
||||||
|
let entities = options.entities || [];
|
||||||
|
caption = RichTextProcessor.parseMarkdown(caption, entities);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.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 randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)];
|
||||||
|
let randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString();
|
||||||
|
let preloader = new ProgressivePreloader(null, true);
|
||||||
|
|
||||||
|
let details = options.sendFileDetails[idx];
|
||||||
|
|
||||||
|
let media = {
|
||||||
|
_: 'messageMediaPending',
|
||||||
|
type: 'album',
|
||||||
|
preloader: preloader,
|
||||||
|
progress: {
|
||||||
|
percent: 1,
|
||||||
|
total: file.size,
|
||||||
|
done: 0,
|
||||||
|
cancel: () => {}
|
||||||
|
},
|
||||||
|
document: undefined as any,
|
||||||
|
photo: undefined as any
|
||||||
|
};
|
||||||
|
|
||||||
|
if(file.type.indexOf('video/') === 0) {
|
||||||
|
let flags = 1;
|
||||||
|
let videoAttribute = {
|
||||||
|
_: 'documentAttributeVideo',
|
||||||
|
flags: flags,
|
||||||
|
pFlags: { // that's only for client, not going to telegram
|
||||||
|
supports_streaming: true,
|
||||||
|
round_message: false
|
||||||
|
},
|
||||||
|
round_message: false,
|
||||||
|
supports_streaming: true,
|
||||||
|
duration: details.duration,
|
||||||
|
w: details.width,
|
||||||
|
h: details.height
|
||||||
|
};
|
||||||
|
|
||||||
|
let doc: any = {
|
||||||
|
_: 'document',
|
||||||
|
id: '' + messageID,
|
||||||
|
attributes: [videoAttribute],
|
||||||
|
downloaded: file.size,
|
||||||
|
thumbs: [],
|
||||||
|
mime_type: file.type,
|
||||||
|
url: details.objectURL || '',
|
||||||
|
size: file.size
|
||||||
|
};
|
||||||
|
|
||||||
|
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 MTPhotoSize],
|
||||||
|
w: details.width,
|
||||||
|
h: details.height,
|
||||||
|
downloaded: file.size,
|
||||||
|
url: details.objectURL || ''
|
||||||
|
};
|
||||||
|
|
||||||
|
appPhotosManager.savePhoto(photo);
|
||||||
|
media.photo = photo;
|
||||||
|
}
|
||||||
|
|
||||||
|
preloader.preloader.onclick = () => {
|
||||||
|
console.log('cancelling upload', media);
|
||||||
|
appImManager.setTyping('sendMessageCancelAction');
|
||||||
|
media.progress.cancel();
|
||||||
|
};
|
||||||
|
|
||||||
|
let message = {
|
||||||
|
_: 'message',
|
||||||
|
id: messageID,
|
||||||
|
from_id: fromID,
|
||||||
|
grouped_id: groupID,
|
||||||
|
to_id: AppPeersManager.getOutputPeer(peerID),
|
||||||
|
flags: flags,
|
||||||
|
pFlags: pFlags,
|
||||||
|
date: date,
|
||||||
|
message: caption,
|
||||||
|
media: media,
|
||||||
|
random_id: randomIDS,
|
||||||
|
randomID: randomID,
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
|
||||||
|
$rootScope.$broadcast('history_append', {peerID: peerID, messageID: messages[messages.length - 1].id, my: true});
|
||||||
|
|
||||||
|
let toggleError = (message: any, on: boolean) => {
|
||||||
|
if(on) {
|
||||||
|
message.error = true;
|
||||||
|
} else {
|
||||||
|
delete message.error;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rootScope.$broadcast('messages_pending');
|
||||||
|
};
|
||||||
|
|
||||||
|
let uploaded = false,
|
||||||
|
uploadPromise: ReturnType<typeof apiFileManager.uploadFile> = null;
|
||||||
|
|
||||||
|
let inputPeer = AppPeersManager.getInputPeerByID(peerID);
|
||||||
|
let invoke = (multiMedia: any[]) => {
|
||||||
|
appImManager.setTyping('sendMessageCancelAction');
|
||||||
|
|
||||||
|
return apiManager.invokeApi('messages.sendMultiMedia', {
|
||||||
|
flags: flags,
|
||||||
|
peer: inputPeer,
|
||||||
|
multi_media: multiMedia,
|
||||||
|
reply_to_msg_id: appMessagesIDsManager.getMessageLocalID(replyToMsgID)
|
||||||
|
}).then((updates) => {
|
||||||
|
apiUpdatesManager.processUpdateMessage(updates);
|
||||||
|
}, (error) => {
|
||||||
|
messages.forEach(message => toggleError(message, true));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let inputs: any[] = [];
|
||||||
|
for(let i = 0, length = files.length; i < length; ++i) {
|
||||||
|
let file = files[i];
|
||||||
|
let message = messages[i];
|
||||||
|
let media = message.media;
|
||||||
|
let preloader = media.preloader;
|
||||||
|
let actionName = file.type.indexOf('video/') === 0 ? 'sendMessageUploadVideoAction' : 'sendMessageUploadPhotoAction';
|
||||||
|
let deferred = deferredPromise<void>();
|
||||||
|
|
||||||
|
await this.sendFilePromise;
|
||||||
|
this.sendFilePromise = deferred;
|
||||||
|
|
||||||
|
if(!uploaded || message.error) {
|
||||||
|
uploaded = false;
|
||||||
|
uploadPromise = apiFileManager.uploadFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadPromise.notify = (progress: {done: number, total: number}) => {
|
||||||
|
console.log('upload progress', progress);
|
||||||
|
media.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total));
|
||||||
|
appImManager.setTyping({_: actionName, progress: media.progress.percent | 0});
|
||||||
|
preloader.setProgress(media.progress.percent); // lol, nice
|
||||||
|
$rootScope.$broadcast('history_update', {peerID: peerID});
|
||||||
|
};
|
||||||
|
|
||||||
|
await uploadPromise.then((inputFile) => {
|
||||||
|
console.log('appMessagesManager: sendAlbum file uploaded:', inputFile);
|
||||||
|
|
||||||
|
let inputMedia: any;
|
||||||
|
let details = options.sendFileDetails[i];
|
||||||
|
if(details.duration) {
|
||||||
|
inputMedia = {
|
||||||
|
_: 'inputMediaUploadedDocument',
|
||||||
|
flags: 0,
|
||||||
|
file: inputFile,
|
||||||
|
mime_type: file.type,
|
||||||
|
attributes: [{
|
||||||
|
_: 'documentAttributeVideo',
|
||||||
|
flags: 2,
|
||||||
|
supports_streaming: true,
|
||||||
|
duration: details.duration,
|
||||||
|
w: details.width,
|
||||||
|
h: details.height
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
inputMedia = {
|
||||||
|
_: 'inputMediaUploadedPhoto',
|
||||||
|
flags: 0,
|
||||||
|
file: inputFile
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return apiManager.invokeApi('messages.uploadMedia', {
|
||||||
|
peer: inputPeer,
|
||||||
|
media: inputMedia
|
||||||
|
}).then(messageMedia => {
|
||||||
|
let inputMedia: any;
|
||||||
|
if(messageMedia.photo) {
|
||||||
|
let photo = messageMedia.photo;
|
||||||
|
appPhotosManager.savePhoto(photo);
|
||||||
|
inputMedia = appPhotosManager.getInputByID(photo.id);
|
||||||
|
} else {
|
||||||
|
let doc = messageMedia.document;
|
||||||
|
appDocsManager.saveDoc(doc);
|
||||||
|
inputMedia = appDocsManager.getInputByID(doc.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
inputs.push({
|
||||||
|
_: 'inputSingleMedia',
|
||||||
|
flags: 0,
|
||||||
|
media: inputMedia,
|
||||||
|
random_id: message.randomID,
|
||||||
|
message: caption,
|
||||||
|
entities: []
|
||||||
|
});
|
||||||
|
|
||||||
|
caption = ''; // only 1 caption for all inputs
|
||||||
|
}, () => {
|
||||||
|
toggleError(message, true);
|
||||||
|
});
|
||||||
|
}, () => {
|
||||||
|
toggleError(message, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('appMessagesManager: sendAlbum uploadPromise.finally!');
|
||||||
|
deferred.resolve();
|
||||||
|
preloader.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
uploaded = true;
|
||||||
|
invoke(inputs);
|
||||||
|
}
|
||||||
|
|
||||||
public cancelPendingMessage(randomID: string) {
|
public cancelPendingMessage(randomID: string) {
|
||||||
var pendingData = this.pendingByRandomID[randomID];
|
var pendingData = this.pendingByRandomID[randomID];
|
||||||
|
|
||||||
@ -2273,6 +2564,7 @@ export class AppMessagesManager {
|
|||||||
case 'updateMessageID': {
|
case 'updateMessageID': {
|
||||||
var randomID = update.random_id;
|
var randomID = update.random_id;
|
||||||
var pendingData = this.pendingByRandomID[randomID];
|
var pendingData = this.pendingByRandomID[randomID];
|
||||||
|
console.log('AMM updateMessageID:', update, pendingData);
|
||||||
if(pendingData) {
|
if(pendingData) {
|
||||||
var peerID: number = pendingData[0];
|
var peerID: number = pendingData[0];
|
||||||
var tempID = pendingData[1];
|
var tempID = pendingData[1];
|
||||||
|
@ -315,6 +315,21 @@ export class AppPhotosManager {
|
|||||||
return isObject(photoID) ? photoID : this.photos[photoID];
|
return isObject(photoID) ? photoID : this.photos[photoID];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getInputByID(photoID: any) {
|
||||||
|
let photo = this.getPhoto(photoID);
|
||||||
|
return {
|
||||||
|
_: 'inputMediaPhoto',
|
||||||
|
flags: 0,
|
||||||
|
id: {
|
||||||
|
_: 'inputPhoto',
|
||||||
|
id: photo.id,
|
||||||
|
access_hash: photo.access_hash,
|
||||||
|
file_reference: photo.file_reference
|
||||||
|
},
|
||||||
|
ttl_seconds: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public downloadPhoto(photoID: string) {
|
public downloadPhoto(photoID: string) {
|
||||||
var photo = this.photos[photoID];
|
var photo = this.photos[photoID];
|
||||||
var ext = 'jpg';
|
var ext = 'jpg';
|
||||||
|
@ -171,7 +171,7 @@ class AppSidebarRight {
|
|||||||
|
|
||||||
let targets = ids.map(id => ({element: this.mediaDivsByIDs[id], mid: id}));
|
let targets = ids.map(id => ({element: this.mediaDivsByIDs[id], mid: id}));
|
||||||
|
|
||||||
appMediaViewer.openMedia(message, target, false, this.sidebarEl, targets.slice(idx + 1).reverse(), targets.slice(0, idx).reverse(), () => this.loadSidebarMedia(true));
|
appMediaViewer.openMedia(message, target, false, this.sidebarEl, targets.slice(idx + 1).reverse(), targets.slice(0, idx).reverse(), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.profileElements.notificationsCheckbox.addEventListener('change', () => {
|
this.profileElements.notificationsCheckbox.addEventListener('change', () => {
|
||||||
|
@ -121,6 +121,7 @@ class ApiManagerProxy extends CryptoWorkerMethods {
|
|||||||
stopTime?: number,
|
stopTime?: number,
|
||||||
rawError?: any
|
rawError?: any
|
||||||
} = {}): Promise<any> {
|
} = {}): Promise<any> {
|
||||||
|
console.log('will invokeApi:', method, params, options);
|
||||||
return this.performTaskWorker('invokeApi', method, params, options);
|
return this.performTaskWorker('invokeApi', method, params, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,6 +589,10 @@ $chat-max-width: 696px;
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
|
img, video {
|
||||||
|
border-radius: inherit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1132,8 +1136,8 @@ $chat-max-width: 696px;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.audio-subtitle, .contact-number {
|
.audio-subtitle, .contact-number, .audio-time {
|
||||||
color: #707579;
|
color: #707579 !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1376,6 +1380,16 @@ $chat-max-width: 696px;
|
|||||||
&.menu-open {
|
&.menu-open {
|
||||||
color: $blue;
|
color: $blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-menu {
|
||||||
|
padding: 8px 0;
|
||||||
|
right: -8px;
|
||||||
|
bottom: calc(100% + 16px);
|
||||||
|
|
||||||
|
> div {
|
||||||
|
padding: 0 38px 0 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
.emoji-dropdown {
|
.emoji-dropdown {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: calc(-420px + -0.75rem);
|
top: calc(-420px + -4px);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 420px;
|
width: 420px;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background: rgba(0, 0, 0, .9);
|
background: rgba(0, 0, 0, .88);
|
||||||
/* color: $darkgrey; */
|
/* color: $darkgrey; */
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
52
src/scss/partials/popups/_editAvatar.scss
Normal file
52
src/scss/partials/popups/_editAvatar.scss
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
.popup-avatar {
|
||||||
|
$parent: ".popup";
|
||||||
|
|
||||||
|
#{$parent} {
|
||||||
|
&-container {
|
||||||
|
max-width: 600px;
|
||||||
|
//max-height: 600px;
|
||||||
|
padding: 15px 16px 16px 24px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
> button {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 20px;
|
||||||
|
right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-close {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-header {
|
||||||
|
margin-bottom: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
text-align: left;
|
||||||
|
margin: 0;
|
||||||
|
margin-left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.crop {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
padding: 24px 54px 46px 46px;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
|
||||||
|
> img {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
//height: 100%;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
150
src/scss/partials/popups/_mediaAttacher.scss
Normal file
150
src/scss/partials/popups/_mediaAttacher.scss
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
.popup-send-photo {
|
||||||
|
$parent: ".popup";
|
||||||
|
|
||||||
|
#{$parent} {
|
||||||
|
&-container {
|
||||||
|
width: 420px;
|
||||||
|
max-width: 420px;
|
||||||
|
overflow: hidden;
|
||||||
|
/* padding: 12px 20px 50px; */
|
||||||
|
padding: 12px 20px 32.5px;
|
||||||
|
|
||||||
|
&.is-media:not(.is-album) {
|
||||||
|
/* max-height: 425px; */
|
||||||
|
|
||||||
|
#{$parent}-photo {
|
||||||
|
max-height: 320px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
> div {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-album {
|
||||||
|
#{$parent}-photo {
|
||||||
|
margin: 0 auto;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-document, &.is-album {
|
||||||
|
#{$parent}-photo {
|
||||||
|
img, video {
|
||||||
|
object-fit: cover;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-header {
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 9px;
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
width: 79px;
|
||||||
|
height: 36px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
padding: 0;
|
||||||
|
padding-top: 2px;
|
||||||
|
margin-top: -3px;
|
||||||
|
border-radius: $border-radius-medium;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-close {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin: -1px 0 0 -4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-title {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0 2rem 0 1.5rem;
|
||||||
|
margin: 0;
|
||||||
|
margin-top: -3px;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-photo {
|
||||||
|
max-width: 380px;
|
||||||
|
//display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
//justify-content: center;
|
||||||
|
width: fit-content;
|
||||||
|
border-radius: $border-radius-medium;
|
||||||
|
/* align-items: center; */
|
||||||
|
|
||||||
|
.document {
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: default;
|
||||||
|
padding-left: 3.75rem;
|
||||||
|
height: 4.5rem;
|
||||||
|
|
||||||
|
&-name {
|
||||||
|
font-weight: normal;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-ico {
|
||||||
|
height: 48px;
|
||||||
|
width: 48px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 11px;
|
||||||
|
letter-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* &.photo {
|
||||||
|
.document-ico {
|
||||||
|
border-radius: $border-radius;
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-field {
|
||||||
|
margin-top: 1rem;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: #a2acb4;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
height: 54px;
|
||||||
|
font-size: 1rem;
|
||||||
|
padding: 0 15px;
|
||||||
|
border-radius: $border-radius-medium;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
padding: 0 14.5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-size: inherit;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
80
src/scss/partials/popups/_popup.scss
Normal file
80
src/scss/partials/popups/_popup.scss
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
.popup {
|
||||||
|
position: fixed!important;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
max-width: none;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 3;
|
||||||
|
background-color: rgba(0, 0, 0, .3);
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
-webkit-transition: opacity 0.3s 0s, visibility 0s 0.3s;
|
||||||
|
-moz-transition: opacity 0.3s 0s, visibility 0s 0.3s;
|
||||||
|
transition: opacity 0.3s 0s, visibility 0s 0.3s;
|
||||||
|
overflow: auto;
|
||||||
|
/* text-align: center; */
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
-webkit-transition: opacity 0.3s 0s, visibility 0s 0s;
|
||||||
|
-moz-transition: opacity 0.3s 0s, visibility 0s 0s;
|
||||||
|
transition: opacity 0.3s 0s, visibility 0s 0s;
|
||||||
|
|
||||||
|
.popup-container {
|
||||||
|
-webkit-transform: translateY(0);
|
||||||
|
-moz-transform: translateY(0);
|
||||||
|
-ms-transform: translateY(0);
|
||||||
|
-o-transform: translateY(0);
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-container {
|
||||||
|
position: relative;
|
||||||
|
/* max-width: 400px; */
|
||||||
|
border-radius: $border-radius-medium;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 1rem;
|
||||||
|
-webkit-transform: translateY(-40px);
|
||||||
|
-moz-transform: translateY(-40px);
|
||||||
|
-ms-transform: translateY(-40px);
|
||||||
|
-o-transform: translateY(-40px);
|
||||||
|
transform: translateY(-40px);
|
||||||
|
backface-visibility: hidden;
|
||||||
|
-webkit-backface-visibility: hidden;
|
||||||
|
-webkit-transition-property: -webkit-transform;
|
||||||
|
-moz-transition-property: -moz-transform;
|
||||||
|
transition-property: transform;
|
||||||
|
-webkit-transition-duration: 0.3s;
|
||||||
|
-moz-transition-duration: 0.3s;
|
||||||
|
transition-duration: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-close {
|
||||||
|
cursor: pointer;
|
||||||
|
color: $color-gray;
|
||||||
|
z-index: 3;
|
||||||
|
text-align: center;
|
||||||
|
justify-self: center;
|
||||||
|
line-height: 1;
|
||||||
|
transition: .2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-header {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
@ -43,6 +43,10 @@ $large-screen: 1680px;
|
|||||||
@import "partials/emojiDropdown";
|
@import "partials/emojiDropdown";
|
||||||
@import "partials/scrollable";
|
@import "partials/scrollable";
|
||||||
|
|
||||||
|
@import "partials/popups/popup";
|
||||||
|
@import "partials/popups/editAvatar";
|
||||||
|
@import "partials/popups/mediaAttacher";
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -1156,81 +1160,6 @@ img.emoji {
|
|||||||
height: 18px;
|
height: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup {
|
|
||||||
position: fixed!important;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
height: 100%;
|
|
||||||
max-width: none;
|
|
||||||
width: 100%;
|
|
||||||
z-index: 3;
|
|
||||||
background-color: rgba(0, 0, 0, .35);
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-shadow: none;
|
|
||||||
opacity: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
-webkit-transition: opacity 0.3s 0s, visibility 0s 0.3s;
|
|
||||||
-moz-transition: opacity 0.3s 0s, visibility 0s 0.3s;
|
|
||||||
transition: opacity 0.3s 0s, visibility 0s 0.3s;
|
|
||||||
overflow: auto;
|
|
||||||
/* text-align: center; */
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup.active {
|
|
||||||
opacity: 1;
|
|
||||||
visibility: visible;
|
|
||||||
-webkit-transition: opacity 0.3s 0s, visibility 0s 0s;
|
|
||||||
-moz-transition: opacity 0.3s 0s, visibility 0s 0s;
|
|
||||||
transition: opacity 0.3s 0s, visibility 0s 0s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-container {
|
|
||||||
position: relative;
|
|
||||||
/* max-width: 400px; */
|
|
||||||
border-radius: $border-radius;
|
|
||||||
background-color: #fff;
|
|
||||||
padding: 1rem;
|
|
||||||
-webkit-transform: translateY(-40px);
|
|
||||||
-moz-transform: translateY(-40px);
|
|
||||||
-ms-transform: translateY(-40px);
|
|
||||||
-o-transform: translateY(-40px);
|
|
||||||
transform: translateY(-40px);
|
|
||||||
backface-visibility: hidden;
|
|
||||||
-webkit-backface-visibility: hidden;
|
|
||||||
-webkit-transition-property: -webkit-transform;
|
|
||||||
-moz-transition-property: -moz-transform;
|
|
||||||
transition-property: transform;
|
|
||||||
-webkit-transition-duration: 0.3s;
|
|
||||||
-moz-transition-duration: 0.3s;
|
|
||||||
transition-duration: 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.popup-close {
|
|
||||||
cursor: pointer;
|
|
||||||
color: $color-gray;
|
|
||||||
z-index: 3;
|
|
||||||
text-align: center;
|
|
||||||
justify-self: center;
|
|
||||||
line-height: 1;
|
|
||||||
transition: .2s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup.active .popup-container {
|
|
||||||
-webkit-transform: translateY(0);
|
|
||||||
-moz-transform: translateY(0);
|
|
||||||
-ms-transform: translateY(0);
|
|
||||||
-o-transform: translateY(0);
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-circle {
|
.btn-circle {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
height: 54px;
|
height: 54px;
|
||||||
@ -1241,66 +1170,6 @@ span.popup-close {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-header {
|
|
||||||
/* display: grid;
|
|
||||||
align-items: center;
|
|
||||||
grid-template-columns: 9.5% 86.5%;
|
|
||||||
justify-content: space-between; */
|
|
||||||
display: flex;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-avatar {
|
|
||||||
.popup-container {
|
|
||||||
max-width: 600px;
|
|
||||||
//max-height: 600px;
|
|
||||||
border-radius: $border-radius-medium;
|
|
||||||
padding: 15px 16px 16px 24px;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
> button {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 20px;
|
|
||||||
right: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-close {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-header {
|
|
||||||
margin-bottom: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h6 {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
text-align: left;
|
|
||||||
margin: 0;
|
|
||||||
margin-left: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.crop {
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
padding: 24px 54px 46px 46px;
|
|
||||||
border-radius: $border-radius;
|
|
||||||
|
|
||||||
> img {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
//height: 100%;
|
|
||||||
border-radius: $border-radius;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.overlay::selection {
|
.overlay::selection {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
@ -1487,105 +1356,6 @@ span.popup-close {
|
|||||||
justify-content: flex-start!important;
|
justify-content: flex-start!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-send-photo {
|
|
||||||
.popup-container {
|
|
||||||
width: 420px;
|
|
||||||
max-width: 420px;
|
|
||||||
max-height: 425px;
|
|
||||||
overflow: hidden;
|
|
||||||
/* padding: 12px 20px 50px; */
|
|
||||||
padding: 12px 20px 32.5px;
|
|
||||||
border-radius: $border-radius-medium;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-header {
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 12.5px;
|
|
||||||
|
|
||||||
.popup-close {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
margin-left: .5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-title {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0 2rem;
|
|
||||||
margin: 0;
|
|
||||||
font-size: 1.35rem;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
width: 80px;
|
|
||||||
height: 35px;
|
|
||||||
font-size: 1rem;
|
|
||||||
padding: 0;
|
|
||||||
border-radius: $border-radius-medium;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-photo {
|
|
||||||
max-width: 378px;
|
|
||||||
max-height: 256px;
|
|
||||||
display: flex;
|
|
||||||
overflow: hidden;
|
|
||||||
justify-content: center;
|
|
||||||
width: fit-content;
|
|
||||||
border-radius: $border-radius-medium;
|
|
||||||
margin: 0 auto;
|
|
||||||
/* align-items: center; */
|
|
||||||
|
|
||||||
&.is-document {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.document {
|
|
||||||
max-width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
cursor: default;
|
|
||||||
|
|
||||||
.document-name {
|
|
||||||
font-weight: normal;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* &.photo {
|
|
||||||
.document-ico {
|
|
||||||
border-radius: $border-radius;
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
object-fit: contain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-field {
|
|
||||||
margin-top: 25px;
|
|
||||||
|
|
||||||
input {
|
|
||||||
height: 55px;
|
|
||||||
font-size: 1.15rem;
|
|
||||||
padding: 0 15px;
|
|
||||||
border-radius: $border-radius-medium;
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
padding: 0 14.5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: inherit;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-chats {
|
.page-chats {
|
||||||
/* display: grid; */
|
/* display: grid; */
|
||||||
/* grid-template-columns: 25% 50%; */
|
/* grid-template-columns: 25% 50%; */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user