Auth pages css all fixed & album prepare
This commit is contained in:
parent
93fc836f25
commit
c35fb83125
@ -19,7 +19,7 @@ export class SearchGroup {
|
||||
this.nameEl.classList.add('search-group__name');
|
||||
this.nameEl.innerText = name;
|
||||
|
||||
this.container.classList.add('search-group');
|
||||
this.container.classList.add('search-group', 'search-group-' + type);
|
||||
this.container.append(this.nameEl, this.list);
|
||||
this.container.style.display = 'none';
|
||||
|
||||
|
@ -187,10 +187,11 @@ export class ChatInput {
|
||||
});
|
||||
|
||||
let attachFile = (file: File) => {
|
||||
console.log('selected file:', file, typeof(file));
|
||||
|
||||
willAttachFile = file;
|
||||
willAttachObjectURL = '';
|
||||
willAttach.file = file;
|
||||
delete willAttach.objectURL;
|
||||
delete willAttach.duration;
|
||||
delete willAttach.width;
|
||||
delete willAttach.height;
|
||||
|
||||
this.fileInput.value = '';
|
||||
|
||||
@ -200,29 +201,55 @@ export class ChatInput {
|
||||
this.attachMediaPopUp.mediaContainer.style.height = '';
|
||||
this.attachMediaPopUp.mediaContainer.classList.remove('is-document');
|
||||
|
||||
if(file.type.indexOf('video/') === 0) {
|
||||
willAttach = 'document';
|
||||
} else if(file.type.indexOf('image/') === -1 && willAttach == 'media') {
|
||||
willAttach = 'document';
|
||||
if(willAttach.type == 'media' && !['image/', 'video/'].find(s => file.type.indexOf(s) === 0)) {
|
||||
willAttach.type = 'document';
|
||||
}
|
||||
|
||||
switch(willAttach) {
|
||||
console.log('selected file:', file, typeof(file), willAttach);
|
||||
|
||||
switch(willAttach.type) {
|
||||
case 'media': {
|
||||
let img = new Image();
|
||||
img.src = willAttachObjectURL = URL.createObjectURL(file);
|
||||
img.onload = () => {
|
||||
willAttachWidth = img.naturalWidth;
|
||||
willAttachHeight = img.naturalHeight;
|
||||
let isVideo = file.type.indexOf('video/') === 0;
|
||||
|
||||
let {w, h} = calcImageInBox(willAttachWidth, willAttachHeight, 378, 256);
|
||||
this.attachMediaPopUp.mediaContainer.style.width = w + 'px';
|
||||
this.attachMediaPopUp.mediaContainer.style.height = h + 'px';
|
||||
this.attachMediaPopUp.mediaContainer.append(img);
|
||||
};
|
||||
if(isVideo) {
|
||||
let video = document.createElement('video');
|
||||
let source = document.createElement('source');
|
||||
source.src = willAttach.objectURL = URL.createObjectURL(file);
|
||||
video.autoplay = false;
|
||||
video.controls = false;
|
||||
|
||||
this.attachMediaPopUp.titleEl.innerText = 'Send Photo';
|
||||
this.attachMediaPopUp.container.classList.add('active');
|
||||
video.onloadeddata = () => {
|
||||
willAttach.width = video.videoWidth;
|
||||
willAttach.height = video.videoHeight;
|
||||
willAttach.duration = Math.floor(video.duration);
|
||||
|
||||
let {w, h} = calcImageInBox(willAttach.width, willAttach.height, 378, 256);
|
||||
this.attachMediaPopUp.mediaContainer.style.width = w + 'px';
|
||||
this.attachMediaPopUp.mediaContainer.style.height = h + 'px';
|
||||
this.attachMediaPopUp.mediaContainer.append(video);
|
||||
this.attachMediaPopUp.container.classList.add('active');
|
||||
};
|
||||
|
||||
video.append(source);
|
||||
|
||||
this.attachMediaPopUp.titleEl.innerText = 'Send Video';
|
||||
} else {
|
||||
let img = new Image();
|
||||
img.src = willAttach.objectURL = URL.createObjectURL(file);
|
||||
img.onload = () => {
|
||||
willAttach.width = img.naturalWidth;
|
||||
willAttach.height = img.naturalHeight;
|
||||
|
||||
let {w, h} = calcImageInBox(willAttach.width, willAttach.height, 378, 256);
|
||||
this.attachMediaPopUp.mediaContainer.style.width = w + 'px';
|
||||
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;
|
||||
}
|
||||
|
||||
@ -231,11 +258,7 @@ export class ChatInput {
|
||||
file: file,
|
||||
file_name: file.name || '',
|
||||
size: file.size,
|
||||
type: ['image/jpeg',
|
||||
'image/png',
|
||||
'image/gif',
|
||||
'image/webp',
|
||||
'image/bmp'].indexOf(file.type) !== -1 ? 'photo' : 'doc'
|
||||
type: file.type.indexOf('image/') !== -1 ? 'photo' : 'doc'
|
||||
} as any, false, true);
|
||||
|
||||
this.attachMediaPopUp.titleEl.innerText = 'Send File';
|
||||
@ -248,10 +271,17 @@ export class ChatInput {
|
||||
}
|
||||
};
|
||||
|
||||
let willAttach = '';
|
||||
let willAttachFile: File = null;
|
||||
let willAttachObjectURL = '';
|
||||
let willAttachWidth = 0, willAttachHeight = 0;
|
||||
let willAttach: Partial<{
|
||||
type: 'media' | 'document',
|
||||
isMedia: boolean,
|
||||
file: File,
|
||||
caption: string,
|
||||
objectURL: string,
|
||||
width: number,
|
||||
height: number,
|
||||
duration: number
|
||||
}> = {};
|
||||
|
||||
this.fileInput.addEventListener('change', (e) => {
|
||||
var file = (e.target as HTMLInputElement & EventTarget).files[0];
|
||||
if(!file) {
|
||||
@ -262,12 +292,12 @@ export class ChatInput {
|
||||
}, false);
|
||||
|
||||
this.attachMenu.media.addEventListener('click', () => {
|
||||
willAttach = 'media';
|
||||
willAttach.type = 'media';
|
||||
this.fileInput.click();
|
||||
});
|
||||
|
||||
this.attachMenu.document.addEventListener('click', () => {
|
||||
willAttach = 'document';
|
||||
willAttach.type = 'document';
|
||||
this.fileInput.click();
|
||||
});
|
||||
|
||||
@ -291,7 +321,7 @@ export class ChatInput {
|
||||
//console.log(items[i], file);
|
||||
if(!file) continue;
|
||||
|
||||
willAttach = file.type.indexOf('image/') === 0 ? 'media' : "document";
|
||||
willAttach.type = file.type.indexOf('image/') === 0 ? 'media' : "document";
|
||||
attachFile(file);
|
||||
}
|
||||
}
|
||||
@ -299,15 +329,10 @@ export class ChatInput {
|
||||
|
||||
this.attachMediaPopUp.sendBtn.addEventListener('click', () => {
|
||||
this.attachMediaPopUp.container.classList.remove('active');
|
||||
let caption = this.attachMediaPopUp.captionInput.value;
|
||||
willAttach.caption = this.attachMediaPopUp.captionInput.value;
|
||||
willAttach.isMedia = willAttach.type == 'media';
|
||||
|
||||
appMessagesManager.sendFile(appImManager.peerID, willAttachFile, {
|
||||
isMedia: true,
|
||||
caption,
|
||||
width: willAttachWidth,
|
||||
height: willAttachHeight,
|
||||
objectURL: willAttachObjectURL
|
||||
});
|
||||
appMessagesManager.sendFile(appImManager.peerID, willAttach.file, willAttach);
|
||||
|
||||
this.onMessageSent();
|
||||
});
|
||||
|
@ -118,7 +118,7 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement,
|
||||
|
||||
//console.log('emoticons sorted:', sorted);
|
||||
|
||||
Object.keys(sorted).forEach(c => sorted[c].sort());
|
||||
Object.keys(sorted).forEach(c => sorted[c].sort((a, b) => a - b));
|
||||
|
||||
categories.pop();
|
||||
delete sorted["Skin Tones"];
|
||||
|
@ -151,7 +151,7 @@ export function horizontalMenu(tabs: HTMLElement, content: HTMLDivElement, onCli
|
||||
let tabsChildren = tabs ? Array.from(tabs.firstElementChild.children) : [];
|
||||
let activeInSlide: Set<Element> = new Set();
|
||||
|
||||
let selectTab = (id: number) => {
|
||||
let selectTab = async(id: number) => {
|
||||
if(id == prevId) return false;
|
||||
|
||||
let p = prevTabContent;
|
||||
@ -172,10 +172,25 @@ export function horizontalMenu(tabs: HTMLElement, content: HTMLDivElement, onCli
|
||||
//content.style.marginLeft = id > 0 ? (-id * 100) + '%' : '';
|
||||
let toRight = prevId < id;
|
||||
if(prevId != -1) {
|
||||
content.style.cssText = `width: ${activeInSlide.size * 100}%; will-change: width, transform; transform: translateX(-${100 - 100 / activeInSlide.size}%);`;
|
||||
|
||||
//////console.log('mambo rap setting', toRight);
|
||||
|
||||
//content.classList.remove('animated');
|
||||
await new Promise((resolve) => window.requestAnimationFrame(() => {
|
||||
content.style.cssText = `will-change: width, transform; width: ${activeInSlide.size * 100}%; transform: translateX(-${100 - 100 / activeInSlide.size}%);`;
|
||||
|
||||
content.classList.remove('animated');
|
||||
if(toRight) {
|
||||
content.classList.add('animated');
|
||||
} else {
|
||||
window.requestAnimationFrame(() => {
|
||||
content.classList.add('animated');
|
||||
content.style.transform = '';
|
||||
});
|
||||
}
|
||||
|
||||
resolve();
|
||||
}));
|
||||
|
||||
/* content.style.cssText = `will-change: width, transform; width: ${activeInSlide.size * 100}%; transform: translateX(-${100 - 100 / activeInSlide.size}%);`;
|
||||
|
||||
content.classList.remove('animated');
|
||||
if(toRight) {
|
||||
content.classList.add('animated');
|
||||
@ -184,7 +199,7 @@ export function horizontalMenu(tabs: HTMLElement, content: HTMLDivElement, onCli
|
||||
content.classList.add('animated');
|
||||
content.style.transform = '';
|
||||
});
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
if(hideTimeout) clearTimeout(hideTimeout);
|
||||
|
@ -60,13 +60,10 @@ export type MTPhotoSize = {
|
||||
bytes?: Uint8Array // if type == 'i'
|
||||
};
|
||||
|
||||
export function wrapVideo({doc, container, message, justLoader, preloader, round, boxWidth, boxHeight, withTail, isOut, middleware, lazyLoadQueue}: {
|
||||
export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTail, isOut, middleware, lazyLoadQueue}: {
|
||||
doc: MTDocument,
|
||||
container: HTMLDivElement,
|
||||
message: any,
|
||||
justLoader: boolean,
|
||||
preloader?: ProgressivePreloader,
|
||||
round: boolean,
|
||||
boxWidth: number,
|
||||
boxHeight: number,
|
||||
withTail?: boolean,
|
||||
@ -89,10 +86,6 @@ export function wrapVideo({doc, container, message, justLoader, preloader, round
|
||||
container.append(img);
|
||||
}
|
||||
}
|
||||
|
||||
if(!preloader) {
|
||||
preloader = new ProgressivePreloader(container, true);
|
||||
}
|
||||
|
||||
let video = document.createElement('video');
|
||||
if(withTail) {
|
||||
@ -112,11 +105,14 @@ export function wrapVideo({doc, container, message, justLoader, preloader, round
|
||||
|
||||
let loadVideo = () => {
|
||||
let promise = appDocsManager.downloadDoc(doc);
|
||||
|
||||
preloader.attach(container, true, promise);
|
||||
|
||||
if(!doc.downloaded) {
|
||||
let preloader = new ProgressivePreloader(container, true);
|
||||
preloader.attach(container, true, promise);
|
||||
}
|
||||
|
||||
return promise.then(blob => {
|
||||
if(!middleware()) {
|
||||
if(middleware && !middleware()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -136,57 +132,60 @@ export function wrapVideo({doc, container, message, justLoader, preloader, round
|
||||
container.append(video);
|
||||
}
|
||||
|
||||
if(!justLoader || round) {
|
||||
video.dataset.ckin = round ? 'circle' : 'default';
|
||||
video.dataset.overlay = '1';
|
||||
let player = new VideoPlayer(video, !round);
|
||||
} else if(doc.type == 'gif') {
|
||||
if(doc.type == 'gif') {
|
||||
video.autoplay = true;
|
||||
video.loop = true;
|
||||
} else if(doc.type == 'round') {
|
||||
//video.dataset.ckin = doc.type == 'round' ? 'circle' : 'default';
|
||||
video.dataset.ckin = 'circle';
|
||||
video.dataset.overlay = '1';
|
||||
let player = new VideoPlayer(video/* , doc.type != 'round' */);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if(doc.type == 'gif' || true) { // extra fix
|
||||
return doc.downloaded ? loadVideo() : lazyLoadQueue.push({div: container, load: loadVideo, wasSeen: true});
|
||||
} /* else { // if video
|
||||
let load = () => appPhotosManager.preloadPhoto(doc).then((blob) => {
|
||||
if((this.peerID ? this.peerID : this.currentMessageID) != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
return;
|
||||
}
|
||||
|
||||
img.src = URL.createObjectURL(blob);
|
||||
|
||||
if(!justLoader) {
|
||||
return loadVideo();
|
||||
} else {
|
||||
container.style.width = '';
|
||||
container.style.height = '';
|
||||
preloader.detach();
|
||||
}
|
||||
|
||||
if(doc.size >= 20e6 && !doc.downloaded) {
|
||||
let downloadDiv = document.createElement('div');
|
||||
downloadDiv.classList.add('download');
|
||||
|
||||
let span = document.createElement('span');
|
||||
span.classList.add('tgico-download');
|
||||
downloadDiv.append(span);
|
||||
|
||||
downloadDiv.addEventListener('click', () => {
|
||||
downloadDiv.remove();
|
||||
loadVideo();
|
||||
});
|
||||
|
||||
return this.peerID ? this.loadMediaQueuePush(load) : load();
|
||||
} */
|
||||
|
||||
container.append(downloadDiv);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return doc.downloaded ? loadVideo() : lazyLoadQueue.push({div: container, load: loadVideo, wasSeen: true});
|
||||
}
|
||||
|
||||
let formatDate = (timestamp: number) => {
|
||||
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||
const date = new Date(timestamp * 1000);
|
||||
|
||||
return months[date.getMonth()] + ' ' + date.getDate() + ', ' + date.getFullYear()
|
||||
+ ' at ' + date.getHours() + ':' + ('0' + date.getMinutes()).slice(-2);
|
||||
};
|
||||
|
||||
export function wrapDocument(doc: MTDocument, withTime = false, uploading = false): HTMLDivElement {
|
||||
if(doc.type == 'voice') {
|
||||
return wrapVoiceMessage(doc, withTime);
|
||||
} else if(doc.type == 'audio') {
|
||||
return wrapAudio(doc);
|
||||
return wrapAudio(doc, withTime);
|
||||
}
|
||||
|
||||
let docDiv = document.createElement('div');
|
||||
docDiv.classList.add('document');
|
||||
|
||||
let iconDiv = document.createElement('div');
|
||||
iconDiv.classList.add('tgico-document');
|
||||
|
||||
|
||||
let extSplitted = doc.file_name ? doc.file_name.split('.') : '';
|
||||
let ext = '';
|
||||
ext = extSplitted.length > 1 && Array.isArray(extSplitted) ? extSplitted.pop().toLowerCase() : 'file';
|
||||
|
||||
let docDiv = document.createElement('div');
|
||||
docDiv.classList.add('document', `ext-${ext}`);
|
||||
|
||||
let ext2 = ext;
|
||||
if(doc.type == 'photo') {
|
||||
@ -198,15 +197,11 @@ export function wrapDocument(doc: MTDocument, withTime = false, uploading = fals
|
||||
let size = formatBytes(doc.size);
|
||||
|
||||
if(withTime) {
|
||||
let months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||
let date = new Date(doc.date * 1000);
|
||||
|
||||
size += ' · ' + months[date.getMonth()] + ' ' + date.getDate() + ', ' + date.getFullYear()
|
||||
+ ' at ' + date.getHours() + ':' + ('0' + date.getMinutes()).slice(-2);
|
||||
size += ' · ' + formatDate(doc.date);
|
||||
}
|
||||
|
||||
docDiv.innerHTML = `
|
||||
<div class="document-ico ext-${ext}">${ext2}</div>
|
||||
<div class="document-ico">${ext2}</div>
|
||||
${!uploading ? `<div class="document-download"><div class="tgico-download"></div></div>` : ''}
|
||||
<div class="document-name">${fileName}</div>
|
||||
<div class="document-size">${size}</div>
|
||||
@ -255,20 +250,30 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
|
||||
|
||||
console.log('wrapAudio doc:', doc);
|
||||
|
||||
/* let durationStr = String(doc.duration | 0).toHHMMSS(true);
|
||||
let durationStr = String(doc.duration | 0).toHHMMSS(true);
|
||||
let title = doc.audioTitle || doc.file_name;
|
||||
let subtitle = doc.audioPerformer ? RichTextProcessor.wrapPlainText(doc.audioPerformer) : ''; */
|
||||
let durationStr = '3:24';
|
||||
let subtitle = doc.audioPerformer ? RichTextProcessor.wrapPlainText(doc.audioPerformer) : '';
|
||||
/* let durationStr = '3:24';
|
||||
let title = 'Million Telegrams';
|
||||
let subtitle = 'Best Artist';
|
||||
let subtitle = 'Best Artist'; */
|
||||
|
||||
if(withTime) {
|
||||
subtitle += (subtitle ? ' · ' : '') + formatDate(doc.date);
|
||||
}
|
||||
|
||||
div.innerHTML = `
|
||||
<div class="audio-title">${title}</div>
|
||||
<div class="audio-subtitle">${subtitle}</div>
|
||||
<div class="audio-toggle audio-ico tgico-largeplay"></div>
|
||||
<div class="audio-download"><div class="tgico-download"></div></div>
|
||||
<div class="audio-time">${durationStr}</div>
|
||||
<div class="audio-toggle audio-ico tgico-largeplay"></div>
|
||||
<div class="audio-details">
|
||||
<div class="audio-title">${title}</div>
|
||||
<div class="audio-subtitle">${subtitle}</div>
|
||||
<div class="audio-time">${durationStr}</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
/* if(!subtitle) {
|
||||
div.classList.add('audio-no-subtitle');
|
||||
} */
|
||||
|
||||
//////console.log('wrapping audio', doc, doc.attributes[0].waveform);
|
||||
|
||||
@ -281,15 +286,11 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
|
||||
|
||||
let onClick = () => {
|
||||
if(!promise) {
|
||||
if(downloadDiv.classList.contains('downloading')) {
|
||||
return; // means not ready yet
|
||||
}
|
||||
|
||||
if(!preloader) {
|
||||
preloader = new ProgressivePreloader(null, true);
|
||||
}
|
||||
|
||||
let promise = appDocsManager.downloadDoc(doc.id);
|
||||
promise = appDocsManager.downloadDoc(doc.id);
|
||||
preloader.attach(downloadDiv, true, promise);
|
||||
|
||||
promise.then(blob => {
|
||||
@ -298,7 +299,7 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
|
||||
|
||||
let audio = document.createElement('audio');
|
||||
let source = document.createElement('source');
|
||||
source.src = URL.createObjectURL(blob);
|
||||
source.src = doc.url;
|
||||
source.type = doc.mime_type;
|
||||
|
||||
audio.volume = 1;
|
||||
@ -343,18 +344,19 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
|
||||
|
||||
audio.style.display = 'none';
|
||||
audio.append(source);
|
||||
div.classList.add('audio-show-progress');
|
||||
div.append(audio);
|
||||
});
|
||||
|
||||
downloadDiv.classList.add('downloading');
|
||||
} else {
|
||||
downloadDiv.classList.remove('downloading');
|
||||
promise.cancel();
|
||||
promise = null;
|
||||
}
|
||||
};
|
||||
|
||||
div.addEventListener('click', onClick);
|
||||
|
||||
div.click();
|
||||
|
||||
return div;
|
||||
@ -418,15 +420,11 @@ export function wrapVoiceMessage(doc: MTDocument, withTime = false): HTMLDivElem
|
||||
|
||||
let onClick = () => {
|
||||
if(!promise) {
|
||||
if(downloadDiv.classList.contains('downloading')) {
|
||||
return; // means not ready yet
|
||||
}
|
||||
|
||||
if(!preloader) {
|
||||
preloader = new ProgressivePreloader(null, true);
|
||||
}
|
||||
|
||||
let promise = appDocsManager.downloadDoc(doc.id);
|
||||
promise = appDocsManager.downloadDoc(doc.id);
|
||||
preloader.attach(downloadDiv, true, promise);
|
||||
|
||||
promise.then(blob => {
|
||||
@ -435,7 +433,7 @@ export function wrapVoiceMessage(doc: MTDocument, withTime = false): HTMLDivElem
|
||||
|
||||
let audio = document.createElement('audio');
|
||||
let source = document.createElement('source');
|
||||
source.src = URL.createObjectURL(blob);
|
||||
source.src = doc.url;
|
||||
source.type = doc.mime_type;
|
||||
|
||||
audio.volume = 1;
|
||||
@ -544,12 +542,12 @@ export function wrapVoiceMessage(doc: MTDocument, withTime = false): HTMLDivElem
|
||||
downloadDiv.classList.add('downloading');
|
||||
} else {
|
||||
downloadDiv.classList.remove('downloading');
|
||||
promise.cancel();
|
||||
promise = null;
|
||||
}
|
||||
};
|
||||
|
||||
div.addEventListener('click', onClick);
|
||||
|
||||
div.click();
|
||||
|
||||
return div;
|
||||
|
@ -445,7 +445,7 @@ export class AppDialogsManager {
|
||||
if(lastMessage.media) {
|
||||
switch(lastMessage.media._) {
|
||||
case 'messageMediaPhoto':
|
||||
lastMessageText += '<i>Photo' + (lastMessage.message ? ', ' : '') + '</i>';
|
||||
lastMessageText += '<i>' + (lastMessage.grouped_id ? 'Album' : 'Photo') + (lastMessage.message ? ', ' : '') + '</i>';
|
||||
break;
|
||||
case 'messageMediaGeo':
|
||||
lastMessageText += '<i>Geolocation</i>';
|
||||
@ -512,7 +512,7 @@ export class AppDialogsManager {
|
||||
|
||||
d.push(duration % 60 + ' s');
|
||||
if(duration > 60) d.push((duration / 60 | 0) + ' min');
|
||||
if(duration > 3600) d.push((duration / 3600 | 0) + ' h');
|
||||
//if(duration > 3600) d.push((duration / 3600 | 0) + ' h');
|
||||
suffix = ' (' + d.reverse().join(' ') + ')';
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import FileManager from '../filemanager';
|
||||
import {RichTextProcessor} from '../richtextprocessor';
|
||||
import { CancellablePromise } from '../polyfill';
|
||||
import { MTDocument } from '../../components/wrappers';
|
||||
import { isObject } from '../utils';
|
||||
|
||||
class AppDocsManager {
|
||||
private docs: {[docID: string]: MTDocument} = {};
|
||||
@ -140,8 +141,8 @@ class AppDocsManager {
|
||||
return apiDoc;
|
||||
}
|
||||
|
||||
public getDoc(docID: string) {
|
||||
return this.docs[docID] || {_: 'documentEmpty'};
|
||||
public getDoc(docID: any): MTDocument {
|
||||
return isObject(docID) ? docID : this.docs[docID];
|
||||
}
|
||||
|
||||
public getFileName(doc: MTDocument) {
|
||||
@ -199,6 +200,8 @@ class AppDocsManager {
|
||||
}
|
||||
|
||||
if(doc.downloaded && !toFileEntry) {
|
||||
if(doc.url) return Promise.resolve(null);
|
||||
|
||||
var cachedBlob = apiFileManager.getCachedFile(inputFileLocation);
|
||||
if(cachedBlob) {
|
||||
return Promise.resolve(cachedBlob);
|
||||
@ -217,7 +220,7 @@ class AppDocsManager {
|
||||
if(blob) {
|
||||
doc.downloaded = true;
|
||||
|
||||
if(/* !doc.animated || */doc.type != 'sticker') {
|
||||
if(/* !doc.animated || */doc.type && doc.type != 'sticker') {
|
||||
doc.url = FileManager.getFileCorrectUrl(blob, doc.mime_type);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import { ChatInput } from '../../components/chatInput';
|
||||
import Scrollable from '../../components/scrollable';
|
||||
import BubbleGroups from '../../components/bubbleGroups';
|
||||
import LazyLoadQueue from '../../components/lazyLoadQueue';
|
||||
import appDocsManager from './appDocsManager';
|
||||
|
||||
console.log('appImManager included!');
|
||||
|
||||
@ -200,12 +201,21 @@ export class AppImManager {
|
||||
|
||||
// set cached url to media
|
||||
let message = appMessagesManager.getMessage(mid);
|
||||
if(message.media && message.media.photo) {
|
||||
let photo = appPhotosManager.getPhoto(tempID);
|
||||
if(photo) {
|
||||
let newPhoto = message.media.photo;
|
||||
newPhoto.downloaded = photo.downloaded;
|
||||
newPhoto.url = photo.url;
|
||||
if(message.media) {
|
||||
if(message.media.photo) {
|
||||
let photo = appPhotosManager.getPhoto(tempID);
|
||||
if(photo) {
|
||||
let newPhoto = message.media.photo;
|
||||
newPhoto.downloaded = photo.downloaded;
|
||||
newPhoto.url = photo.url;
|
||||
}
|
||||
} else if(message.media.document) {
|
||||
let doc = appDocsManager.getDoc(tempID);
|
||||
if(doc && doc.type && doc.type != 'sticker') {
|
||||
let newDoc = message.media.document;
|
||||
newDoc.downloaded = doc.downloaded;
|
||||
newDoc.url = doc.url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -368,7 +378,7 @@ export class AppImManager {
|
||||
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();
|
||||
}).sort((a, b) => a - b);
|
||||
let idx = ids.findIndex(i => i == messageID);
|
||||
|
||||
let targets = ids.map(id => ({
|
||||
@ -377,7 +387,7 @@ export class AppImManager {
|
||||
mid: id
|
||||
}));
|
||||
|
||||
/////this.log('ids', ids, idx, this.bubbles[prev], this.bubbles[next]);
|
||||
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));
|
||||
@ -649,7 +659,7 @@ export class AppImManager {
|
||||
this.log('loadMoreHistory', top);
|
||||
if(!this.peerID || testScroll || this.setPeerPromise || (top && this.getHistoryTopPromise) || (!top && this.getHistoryBottomPromise)) return;
|
||||
|
||||
let history = Object.keys(this.bubbles).map(id => +id).sort();
|
||||
let history = Object.keys(this.bubbles).map(id => +id).sort((a, b) => a - b);
|
||||
if(!history.length) return;
|
||||
|
||||
/* let history = appMessagesManager.historiesStorage[this.peerID].history;
|
||||
@ -962,6 +972,9 @@ export class AppImManager {
|
||||
this.topbar.style.display = '';
|
||||
if(appPeersManager.isAnyGroup(peerID)) this.chatInner.classList.add('is-chat');
|
||||
else this.chatInner.classList.remove('is-chat');
|
||||
if(appPeersManager.isChannel(peerID)) this.chatInner.classList.add('is-channel');
|
||||
else this.chatInner.classList.remove('is-channel');
|
||||
this.pinnedMessageContainer.style.display = 'none';
|
||||
window.requestAnimationFrame(() => {
|
||||
//this.chatInner.style.visibility = 'hidden';
|
||||
|
||||
@ -970,7 +983,6 @@ export class AppImManager {
|
||||
else title = appPeersManager.getPeerTitle(this.peerID);
|
||||
//this.titleEl.innerHTML = appSidebarRight.profileElements.name.innerHTML = dom.titleSpan.innerHTML;
|
||||
this.titleEl.innerHTML = appSidebarRight.profileElements.name.innerHTML = title;
|
||||
this.pinnedMessageContainer.style.display = 'none';
|
||||
this.goDownBtn.style.display = '';
|
||||
//this.topbar.style.display = this.goDownBtn.style.display = '';
|
||||
//this.chatInput.style.display = appPeersManager.isChannel(peerID) && !appPeersManager.isMegagroup(peerID) ? 'none' : '';
|
||||
@ -1340,15 +1352,37 @@ export class AppImManager {
|
||||
|
||||
switch(pending.type) {
|
||||
case 'photo': {
|
||||
if(pending.size < 5e6) {
|
||||
//if(pending.size < 5e6) {
|
||||
this.log('will wrap pending photo:', pending, message, appPhotosManager.getPhoto(message.id));
|
||||
wrapPhoto(message.id, message, attachmentDiv, undefined, undefined, true, true, this.lazyLoadQueue, null);
|
||||
|
||||
preloader.attach(attachmentDiv, false);
|
||||
bubble.classList.add('hide-name', 'photo');
|
||||
|
||||
break;
|
||||
}
|
||||
//}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'video': {
|
||||
//if(pending.size < 5e6) {
|
||||
let doc = appDocsManager.getDoc(message.id);
|
||||
this.log('will wrap pending video:', pending, message, doc);
|
||||
wrapVideo({
|
||||
doc,
|
||||
container: attachmentDiv,
|
||||
message,
|
||||
boxWidth: 380,
|
||||
boxHeight: 380,
|
||||
withTail: doc.type != 'round',
|
||||
isOut: our,
|
||||
lazyLoadQueue: this.lazyLoadQueue,
|
||||
middleware: null
|
||||
});
|
||||
|
||||
preloader.attach(attachmentDiv, false);
|
||||
bubble.classList.add('hide-name', 'video');
|
||||
//}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'audio':
|
||||
@ -1424,9 +1458,6 @@ export class AppImManager {
|
||||
doc,
|
||||
container: preview,
|
||||
message,
|
||||
justLoader: true,
|
||||
preloader: null,
|
||||
round: false,
|
||||
boxWidth: 380,
|
||||
boxHeight: 300,
|
||||
lazyLoadQueue: this.lazyLoadQueue,
|
||||
@ -1502,7 +1533,7 @@ export class AppImManager {
|
||||
}, this.lazyLoadQueue, 'chat', false, !!message.pending || !multipleRender);
|
||||
|
||||
break;
|
||||
} else if((doc.type == 'video' || doc.type == 'gif' || doc.type == 'round') && doc.size <= 20e6) {
|
||||
} else if(doc.type == 'video' || doc.type == 'gif' || doc.type == 'round'/* && doc.size <= 20e6 */) {
|
||||
this.log('never get free 2', doc);
|
||||
|
||||
if(doc.type == 'round') {
|
||||
@ -1510,14 +1541,10 @@ export class AppImManager {
|
||||
}
|
||||
|
||||
bubble.classList.add('hide-name', 'video');
|
||||
//wrapVideo.call(this, doc, attachmentDiv, message, true, null, false, doc.type == 'round', 380, 380, doc.type != 'round', our);
|
||||
wrapVideo({
|
||||
doc,
|
||||
container: attachmentDiv,
|
||||
message,
|
||||
justLoader: true,
|
||||
preloader: null,
|
||||
round: doc.type == 'round',
|
||||
boxWidth: 380,
|
||||
boxHeight: 380,
|
||||
withTail: doc.type != 'round',
|
||||
@ -1861,11 +1888,11 @@ export class AppImManager {
|
||||
|
||||
let loadCount = Object.keys(this.bubbles).length > 0 ? 20 : this.scrollable.innerHeight / 38/* * 1.25 */ | 0;
|
||||
|
||||
/* if(testScroll) {
|
||||
loadCount = 5;
|
||||
if(testScroll) {
|
||||
loadCount = 1;
|
||||
if(Object.keys(this.bubbles).length > 0)
|
||||
return Promise.resolve(true);
|
||||
} */
|
||||
}
|
||||
|
||||
////console.time('render history total');
|
||||
|
||||
|
@ -39,6 +39,7 @@ export type HistoryResult = {
|
||||
export class AppMessagesManager {
|
||||
public messagesStorage: any = {};
|
||||
public messagesForDialogs: any = {};
|
||||
public groupedMessagesStorage: {[groupID: string]: any} = {}; // will be used for albums
|
||||
public historiesStorage: {
|
||||
[peerID: string]: HistoryStorage
|
||||
} = {};
|
||||
@ -455,13 +456,15 @@ export class AppMessagesManager {
|
||||
entities?: any[],
|
||||
width?: number,
|
||||
height?: number,
|
||||
objectURL?: string
|
||||
objectURL?: string,
|
||||
isRoundMessage?: boolean,
|
||||
duration?: number
|
||||
} = {}) {
|
||||
peerID = AppPeersManager.getPeerMigratedTo(peerID) || peerID;
|
||||
var messageID = this.tempID--;
|
||||
var randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)];
|
||||
var randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString();
|
||||
var historyStorage = this.historiesStorage[peerID];
|
||||
var historyStorage = this.historiesStorage[peerID] ?? (this.historiesStorage[peerID] = {count: null, history: [], pending: []});
|
||||
var flags = 0;
|
||||
var pFlags: any = {};
|
||||
var replyToMsgID = options.replyToMsgID;
|
||||
@ -482,6 +485,8 @@ export class AppMessagesManager {
|
||||
caption = RichTextProcessor.parseMarkdown(caption, entities);
|
||||
}
|
||||
|
||||
let attributes: any[] = [];
|
||||
|
||||
let actionName = '';
|
||||
if(!options.isMedia) {
|
||||
attachType = 'document';
|
||||
@ -512,27 +517,55 @@ export class AppMessagesManager {
|
||||
};
|
||||
|
||||
appPhotosManager.savePhoto(photo);
|
||||
} else if(fileType.substr(0, 6) == 'audio/' || ['video/ogg'].indexOf(fileType) >= 0) {
|
||||
} else if(fileType.indexOf('audio/') === 0 || ['video/ogg'].indexOf(fileType) >= 0) {
|
||||
attachType = 'audio';
|
||||
apiFileName = 'audio.' + (fileType.split('/')[1] == 'ogg' ? 'ogg' : 'mp3');
|
||||
actionName = 'sendMessageUploadAudioAction';
|
||||
} else if(fileType.substr(0, 6) == 'video/') {
|
||||
//attachType = 'video';
|
||||
//apiFileName = 'video.mp4';
|
||||
attachType = 'document'; // last minute fix
|
||||
} else if(fileType.indexOf('video/') === 0) {
|
||||
attachType = 'video';
|
||||
apiFileName = 'video.mp4';
|
||||
actionName = 'sendMessageUploadVideoAction';
|
||||
|
||||
let flags = 1;
|
||||
if(options.isRoundMessage) flags |= 2;
|
||||
let videoAttribute = {
|
||||
_: 'documentAttributeVideo',
|
||||
flags: flags,
|
||||
pFlags: { // that's only for client, not going to telegram
|
||||
supports_streaming: true,
|
||||
round_message: options.isRoundMessage
|
||||
},
|
||||
round_message: options.isRoundMessage,
|
||||
supports_streaming: true,
|
||||
duration: options.duration,
|
||||
w: options.width,
|
||||
h: options.height
|
||||
};
|
||||
|
||||
attributes.push(videoAttribute);
|
||||
|
||||
let doc: any = {
|
||||
_: 'document',
|
||||
id: '' + messageID,
|
||||
duration: options.duration,
|
||||
attributes: attributes,
|
||||
w: options.width,
|
||||
h: options.height,
|
||||
downloaded: file.size,
|
||||
thumbs: [],
|
||||
mime_type: fileType,
|
||||
url: options.objectURL || '',
|
||||
size: file.size
|
||||
};
|
||||
|
||||
appDocsManager.saveDoc(doc);
|
||||
} else {
|
||||
attachType = 'document';
|
||||
apiFileName = 'document.' + fileType.split('/')[1];
|
||||
actionName = 'sendMessageUploadDocumentAction';
|
||||
}
|
||||
|
||||
// console.log(attachType, apiFileName, file.type)
|
||||
|
||||
if(historyStorage === undefined) {
|
||||
historyStorage = this.historiesStorage[peerID] = {count: null, history: [], pending: []};
|
||||
}
|
||||
console.log('AMM: sendFile', attachType, apiFileName, file.type, options);
|
||||
|
||||
var fromID = appUsersManager.getSelf().id;
|
||||
if(peerID != fromID) {
|
||||
@ -576,6 +609,8 @@ export class AppMessagesManager {
|
||||
}
|
||||
};
|
||||
|
||||
attributes.push({_: 'documentAttributeFilename', file_name: media.file_name});
|
||||
|
||||
preloader.preloader.onclick = () => {
|
||||
console.log('cancelling upload', media);
|
||||
appImManager.setTyping('sendMessageCancelAction');
|
||||
@ -690,17 +725,13 @@ export class AppMessagesManager {
|
||||
file: inputFile
|
||||
};
|
||||
break;
|
||||
|
||||
case 'document':
|
||||
|
||||
default:
|
||||
inputMedia = {
|
||||
_: 'inputMediaUploadedDocument',
|
||||
file: inputFile,
|
||||
mime_type: fileType,
|
||||
caption: '',
|
||||
attributes: [
|
||||
{_: 'documentAttributeFilename', file_name: fileName}
|
||||
]
|
||||
attributes: attributes
|
||||
};
|
||||
}
|
||||
|
||||
@ -1079,6 +1110,11 @@ export class AppMessagesManager {
|
||||
var mid = appMessagesIDsManager.getFullMessageID(apiMessage.id, channelID);
|
||||
apiMessage.mid = mid;
|
||||
|
||||
if(apiMessage.grouped_id) {
|
||||
let storage = this.groupedMessagesStorage[apiMessage.grouped_id] ?? (this.groupedMessagesStorage[apiMessage.grouped_id] = {});
|
||||
storage[mid] = apiMessage;
|
||||
}
|
||||
|
||||
var dialog = this.getDialogByPeerID(peerID)[0];
|
||||
if(dialog && mid > 0) {
|
||||
let dialogKey = apiMessage.pFlags.out
|
||||
@ -3106,7 +3142,7 @@ export class AppMessagesManager {
|
||||
//return Promise.resolve(result);
|
||||
}
|
||||
|
||||
public requestHistory(peerID: number, maxID: number, limit: number, offset = 0) {
|
||||
public requestHistory(peerID: number, maxID: number, limit: number, offset = 0): Promise<any> {
|
||||
var isChannel = AppPeersManager.isChannel(peerID);
|
||||
|
||||
//console.trace('requestHistory', peerID, maxID, limit, offset);
|
||||
@ -3126,7 +3162,7 @@ export class AppMessagesManager {
|
||||
timeout: 300,
|
||||
noErrorBox: true
|
||||
}).then((historyResult: any) => {
|
||||
///console.log('requestHistory result:', historyResult);
|
||||
console.log('requestHistory result:', historyResult, maxID, limit, offset);
|
||||
|
||||
appUsersManager.saveApiUsers(historyResult.users);
|
||||
appChatsManager.saveApiChats(historyResult.chats);
|
||||
@ -3143,6 +3179,15 @@ export class AppMessagesManager {
|
||||
historyResult.count--;
|
||||
}
|
||||
|
||||
// will load more history if last message is album grouped (because it can be not last item)
|
||||
let historyStorage = this.historiesStorage[peerID];
|
||||
// historyResult.messages: desc sorted
|
||||
if(historyResult.messages[length - 1].grouped_id && (historyStorage.history.length + historyResult.messages.length) < historyResult.count) {
|
||||
return this.requestHistory(peerID, historyResult.messages[length - 1].mid, 10, 0).then((_historyResult: any) => {
|
||||
return historyResult;
|
||||
});
|
||||
}
|
||||
|
||||
// don't need the intro now
|
||||
/* if(peerID < 0 || !appUsersManager.isBot(peerID) || (length == limit && limit < historyResult.count)) {
|
||||
return historyResult;
|
||||
|
@ -109,14 +109,16 @@ export class AppPhotosManager {
|
||||
|
||||
let bestPhotoSize: MTPhotoSize = {_: 'photoSizeEmpty'};
|
||||
let sizes = (photo.sizes || photo.thumbs) as typeof bestPhotoSize[];
|
||||
for(let photoSize of sizes) {
|
||||
if(!photoSize.w || !photoSize.h) continue;
|
||||
|
||||
bestPhotoSize = photoSize;
|
||||
|
||||
let {w, h} = calcImageInBox(photoSize.w, photoSize.h, width, height);
|
||||
if(w == width || h == height) {
|
||||
break;
|
||||
if(sizes) {
|
||||
for(let photoSize of sizes) {
|
||||
if(!photoSize.w || !photoSize.h) continue;
|
||||
|
||||
bestPhotoSize = photoSize;
|
||||
|
||||
let {w, h} = calcImageInBox(photoSize.w, photoSize.h, width, height);
|
||||
if(w == width || h == height) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ import { logger } from "../polyfill";
|
||||
import appImManager from "./appImManager";
|
||||
import appMediaViewer from "./appMediaViewer";
|
||||
import LazyLoadQueue from "../../components/lazyLoadQueue";
|
||||
import { wrapDocument } from "../../components/wrappers";
|
||||
import { wrapDocument, wrapAudio } from "../../components/wrappers";
|
||||
import AppSearch, { SearchGroup } from "../../components/appSearch";
|
||||
|
||||
const testScroll = false;
|
||||
@ -20,6 +20,7 @@ class AppSidebarRight {
|
||||
public sidebarEl = document.getElementById('column-right') as HTMLDivElement;
|
||||
public profileContainer = this.sidebarEl.querySelector('.profile-container') as HTMLDivElement;
|
||||
public profileContentEl = this.sidebarEl.querySelector('.profile-content') as HTMLDivElement;
|
||||
public contentContainer = this.sidebarEl.querySelector('.content-container') as HTMLDivElement;
|
||||
public profileElements = {
|
||||
avatar: this.profileContentEl.querySelector('.profile-avatar') as HTMLDivElement,
|
||||
name: this.profileContentEl.querySelector('.profile-name') as HTMLDivElement,
|
||||
@ -99,10 +100,11 @@ class AppSidebarRight {
|
||||
});
|
||||
|
||||
constructor() {
|
||||
let container = this.profileContentEl.querySelector('.profile-tabs-content') as HTMLDivElement;
|
||||
let container = this.profileContentEl.querySelector('.content-container .tabs-container') as HTMLDivElement;
|
||||
this.profileTabs = this.profileContentEl.querySelector('.profile-tabs') as HTMLUListElement;
|
||||
|
||||
this.scroll = new Scrollable(this.profileContainer, 'y', 1200, 'SR');
|
||||
this.scroll = new Scrollable(this.profileContainer, 'y', 1200, 'SR', undefined, 400);
|
||||
//this.scroll = new Scrollable(this.profileContentEl, 'y', 1200, 'SR', undefined, 400);
|
||||
this.scroll.container.addEventListener('scroll', this.onSidebarScroll.bind(this));
|
||||
this.scroll.onScrolledBottom = () => {
|
||||
if(this.sharedMediaSelected && !this.scroll.hiddenElements.down.length && this.sharedMediaSelected.childElementCount/* && false */) {
|
||||
@ -116,17 +118,15 @@ class AppSidebarRight {
|
||||
|
||||
this.sharedMediaType = this.sharedMediaTypes[id];
|
||||
this.sharedMediaSelected = tabContent.firstElementChild as HTMLDivElement;
|
||||
|
||||
if(this.prevTabID != -1 && !this.sharedMediaSelected.childElementCount) { // quick brown fix
|
||||
this.loadSidebarMedia(true);
|
||||
|
||||
if(this.profileTabs.offsetTop) {
|
||||
this.scroll.scrollTop -= this.profileTabs.offsetTop;
|
||||
}
|
||||
|
||||
|
||||
if(this.prevTabID != -1) {
|
||||
this.savedVirtualStates[this.prevTabID] = this.scroll.state;
|
||||
}
|
||||
|
||||
this.prevTabID = id;
|
||||
|
||||
this.log('setVirtualContainer', id, this.sharedMediaSelected);
|
||||
this.scroll.setVirtualContainer(this.sharedMediaSelected);
|
||||
|
||||
@ -134,6 +134,15 @@ class AppSidebarRight {
|
||||
this.log(this.savedVirtualStates[id]);
|
||||
this.scroll.state = this.savedVirtualStates[id];
|
||||
}
|
||||
|
||||
if(this.prevTabID != -1 && !this.sharedMediaSelected.childElementCount) { // quick brown fix
|
||||
this.contentContainer.classList.remove('loaded');
|
||||
this.loadSidebarMedia(true);
|
||||
}
|
||||
|
||||
this.prevTabID = id;
|
||||
|
||||
this.scroll.onScroll();
|
||||
}, this.onSidebarScroll.bind(this));
|
||||
|
||||
let sidebarCloseBtn = this.sidebarEl.querySelector('.sidebar-close-button') as HTMLButtonElement;
|
||||
@ -157,7 +166,7 @@ class AppSidebarRight {
|
||||
|
||||
let message = appMessagesManager.getMessage(messageID);
|
||||
|
||||
let ids = Object.keys(this.mediaDivsByIDs).map(k => +k).sort();
|
||||
let ids = Object.keys(this.mediaDivsByIDs).map(k => +k).sort((a, b) => a - b);
|
||||
let idx = ids.findIndex(i => i == messageID);
|
||||
|
||||
let targets = ids.map(id => ({element: this.mediaDivsByIDs[id], mid: id}));
|
||||
@ -397,7 +406,7 @@ class AppSidebarRight {
|
||||
continue;
|
||||
}
|
||||
|
||||
let div = wrapDocument(message.media.document, true);
|
||||
let div = wrapAudio(message.media.document, true);
|
||||
elemsToAppend.push(div);
|
||||
}
|
||||
break;
|
||||
@ -422,6 +431,7 @@ class AppSidebarRight {
|
||||
let parent = sharedMediaDiv.parentElement;
|
||||
if(parent.lastElementChild.classList.contains('preloader')) {
|
||||
parent.lastElementChild.remove();
|
||||
this.contentContainer.classList.add('loaded');
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,7 +443,7 @@ class AppSidebarRight {
|
||||
return;
|
||||
}
|
||||
|
||||
this.log('loadSidebarMedia', single, this.peerID);
|
||||
this.log('loadSidebarMedia', single, this.peerID, this.loadSidebarMediaPromises);
|
||||
|
||||
let peerID = this.peerID;
|
||||
|
||||
@ -455,10 +465,10 @@ class AppSidebarRight {
|
||||
// render from cache
|
||||
if(history.length && this.usedFromHistory[type] < history.length && this.cleared[type]) {
|
||||
let ids = history.slice(this.usedFromHistory[type], this.usedFromHistory[type] + loadCount);
|
||||
this.log('will render from cache', this.usedFromHistory[type], history, ids, loadCount);
|
||||
this.log('loadSidebarMedia: will render from cache', this.usedFromHistory[type], history, ids, loadCount);
|
||||
this.usedFromHistory[type] += ids.length;
|
||||
this.performSearchResult(ids, type);
|
||||
return;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// заливать новую картинку сюда только после полной отправки!
|
||||
@ -469,7 +479,7 @@ class AppSidebarRight {
|
||||
? appMessagesManager.historiesStorage[peerID].history.slice() : [];
|
||||
|
||||
maxID = !maxID && ids.length ? ids[ids.length - 1] : maxID;
|
||||
this.log('search house of glass pre', type, ids, maxID);
|
||||
this.log('loadSidebarMedia: search house of glass pre', type, ids, maxID);
|
||||
|
||||
//let loadCount = history.length ? 50 : 15;
|
||||
return this.loadSidebarMediaPromises[type] = appMessagesManager.getSearch(peerID, '', {_: type}, maxID, loadCount)
|
||||
@ -477,7 +487,7 @@ class AppSidebarRight {
|
||||
ids = ids.concat(value.history);
|
||||
history.push(...ids);
|
||||
|
||||
this.log('search house of glass', type, value, ids, this.cleared);
|
||||
this.log('loadSidebarMedia: search house of glass', type, value, ids, this.cleared);
|
||||
|
||||
if($rootScope.selectedPeerID != peerID) {
|
||||
this.log.warn('peer changed');
|
||||
@ -515,6 +525,8 @@ class AppSidebarRight {
|
||||
this.lastSharedMediaDiv = document.createElement('div');
|
||||
|
||||
//this.log('fillProfileElements');
|
||||
|
||||
this.contentContainer.classList.remove('loaded');
|
||||
|
||||
window.requestAnimationFrame(() => {
|
||||
this.profileContentEl.parentElement.scrollTop = 0;
|
||||
|
@ -12,7 +12,7 @@ import HTTP from './transports/http';
|
||||
import { logger } from '../polyfill';
|
||||
import passwordManager from './passwordManager';
|
||||
|
||||
console.error('apiManager included!');
|
||||
//console.error('apiManager included!');
|
||||
|
||||
export class ApiManager {
|
||||
public cachedNetworkers: {[x: number]: MTPNetworker} = {};
|
||||
|
@ -6,7 +6,7 @@ import networkerFactory from "./networkerFactory";
|
||||
//const ctx: Worker = self as any;
|
||||
const ctx = self;
|
||||
|
||||
console.error('INCLUDE !!!', new Error().stack);
|
||||
//console.error('INCLUDE !!!', new Error().stack);
|
||||
|
||||
networkerFactory.setUpdatesProcessor((obj, bool) => {
|
||||
ctx.postMessage({update: {obj, bool}});
|
||||
@ -28,10 +28,10 @@ ctx.onmessage = function(e) {
|
||||
|
||||
default:
|
||||
return apiManager[e.data.task].apply(apiManager, e.data.args).then(result => {
|
||||
console.log(e.data.task + ' result:', result, taskID);
|
||||
//console.log(e.data.task + ' result:', result, taskID);
|
||||
ctx.postMessage({taskID: taskID, result: result});
|
||||
}).catch(err => {
|
||||
console.error(e.data.task + ' err:', err, taskID);
|
||||
//console.error(e.data.task + ' err:', err, taskID);
|
||||
ctx.postMessage({taskID: taskID, error: err});
|
||||
});
|
||||
//throw new Error('Unknown task: ' + e.data.task);
|
||||
|
@ -19,7 +19,7 @@ class ApiManagerProxy extends CryptoWorkerMethods {
|
||||
}
|
||||
} = {} as any;
|
||||
private pending: Array<Task> = [];
|
||||
private debug = true;
|
||||
private debug = false;
|
||||
|
||||
public updatesProcessor: (obj: any, bool: boolean) => void = null;
|
||||
|
||||
|
@ -15,7 +15,7 @@ import HTTP from './transports/http';
|
||||
import { logger } from '../polyfill';
|
||||
import { Modes, App } from './mtproto_config';
|
||||
|
||||
console.error('networker included!', new Error().stack);
|
||||
//console.error('networker included!', new Error().stack);
|
||||
|
||||
type Message = {
|
||||
msg_id: string,
|
||||
|
@ -5,6 +5,7 @@ import pageIm from './pageIm';
|
||||
import apiManager from '../lib/mtproto/mtprotoworker';
|
||||
import apiFileManager from '../lib/mtproto/apiFileManager';
|
||||
import Page from './page';
|
||||
import { calcImageInBox } from '../lib/utils';
|
||||
|
||||
let authCode: {
|
||||
'phone_number': string,
|
||||
@ -14,9 +15,9 @@ let authCode: {
|
||||
let onFirstMount = () => {
|
||||
const pageElement = page.pageEl;
|
||||
const avatarInput = document.getElementById('avatar-input') as HTMLInputElement;
|
||||
const avatarPopup = pageElement.getElementsByClassName('popup-avatar')[0];
|
||||
const avatarPopup = document.getElementsByClassName('popup-avatar')[0];
|
||||
const avatarPreview = pageElement.querySelector('#canvas-avatar') as HTMLCanvasElement;
|
||||
const cropContainer = avatarPopup.getElementsByClassName('crop')[0];
|
||||
const cropContainer = avatarPopup.getElementsByClassName('crop')[0] as HTMLDivElement;
|
||||
let avatarImage = new Image();
|
||||
cropContainer.append(avatarImage);
|
||||
|
||||
@ -76,11 +77,14 @@ let onFirstMount = () => {
|
||||
avatarImage.src = contents;
|
||||
|
||||
avatarImage.onload = () => {
|
||||
/* let {w, h} = calcImageInBox(avatarImage.naturalWidth, avatarImage.naturalHeight, 460, 554);
|
||||
cropContainer.style.width = w + 'px';
|
||||
cropContainer.style.height = h + 'px'; */
|
||||
avatarPopup.classList.add('active');
|
||||
|
||||
cropper = resizeableImage(avatarImage, avatarPreview);
|
||||
avatarInput.value = '';
|
||||
};
|
||||
|
||||
avatarPopup.classList.add('active');
|
||||
};
|
||||
|
||||
reader.readAsDataURL(file);
|
||||
|
@ -178,6 +178,12 @@ $chat-max-width: 696px;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-channel:not(.is-chat) {
|
||||
.bubble__container {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-scrolling .is-sticky {
|
||||
opacity: 1;
|
||||
}
|
||||
@ -508,6 +514,29 @@ $chat-max-width: 696px;
|
||||
max-width: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.download {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
background-color: rgba(0, 0, 0, .7);
|
||||
border-radius: 50%;
|
||||
font-size: 23px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.sticker) {
|
||||
@ -592,7 +621,7 @@ $chat-max-width: 696px;
|
||||
.title {
|
||||
letter-spacing: -0.2px;
|
||||
line-height: 1.2;
|
||||
font-weight: 500;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
.name {
|
||||
@ -627,7 +656,7 @@ $chat-max-width: 696px;
|
||||
}
|
||||
|
||||
.name, .reply-title {
|
||||
font-weight: 500;
|
||||
font-weight: 500 !important;
|
||||
display: inline!important;
|
||||
}
|
||||
}
|
||||
@ -789,7 +818,7 @@ $chat-max-width: 696px;
|
||||
/* padding: .2675rem .6rem 0 .6rem; */
|
||||
/* padding: .32rem .6rem 0 .6rem; */
|
||||
padding: 5px .6rem 0 .6rem;
|
||||
font-weight: 500;
|
||||
font-weight: 500 !important;
|
||||
/* padding-bottom: 4px; */
|
||||
color: $darkblue;
|
||||
font-size: .9rem;
|
||||
@ -1064,6 +1093,11 @@ $chat-max-width: 696px;
|
||||
right: -2.5rem;
|
||||
}
|
||||
|
||||
.document-ico:after {
|
||||
border-top-color: #eeffde;
|
||||
border-right-color: #eeffde;
|
||||
}
|
||||
|
||||
.audio {
|
||||
&-waveform {
|
||||
rect {
|
||||
@ -1134,8 +1168,6 @@ $chat-max-width: 696px;
|
||||
flex: 0 0 auto;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.5rem;
|
||||
height: 54px;
|
||||
width: 54px;
|
||||
color: #9e9e9e;
|
||||
background-color: #fff;
|
||||
align-self: flex-end;
|
||||
|
@ -152,9 +152,7 @@
|
||||
overflow: hidden;
|
||||
color: $color-gray;
|
||||
flex: 1 1 auto;
|
||||
padding-right: 3.5px;
|
||||
padding-left: 9px;
|
||||
padding-top: 1px;
|
||||
padding: 1px 3.5px 1px 9px;
|
||||
|
||||
p:last-child {
|
||||
margin-top: -3px;
|
||||
@ -164,6 +162,7 @@
|
||||
.user-title {
|
||||
img.emoji {
|
||||
vertical-align: top;
|
||||
margin-top: 4px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
@ -222,7 +221,7 @@
|
||||
line-height: 24px;
|
||||
color: #fff;
|
||||
border-radius: 12px;
|
||||
margin-top: 1.5px;
|
||||
margin-top: 4px;
|
||||
margin-right: -2px;
|
||||
}
|
||||
|
||||
@ -257,8 +256,45 @@
|
||||
|
||||
&__name {
|
||||
color: $color-gray;
|
||||
padding: 0 1.85rem;
|
||||
padding: 0 23px;
|
||||
padding-bottom: 1rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
&:not(.search-group-messages) {
|
||||
.user-avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
&-contacts {
|
||||
padding: 16px 0 7px;
|
||||
|
||||
li > .rp {
|
||||
padding: 9px 11.5px !important;
|
||||
height: 66px;
|
||||
}
|
||||
|
||||
.search-group__name {
|
||||
padding-bottom: 17px;
|
||||
}
|
||||
|
||||
.user-caption {
|
||||
padding: 1px 3.5px 1px 13px;
|
||||
}
|
||||
|
||||
.user-title, b, .user-last-message b {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
p {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
span.user-last-message {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
> .menu-horizontal {
|
||||
padding: 0px 58px 0px 58px;
|
||||
font-weight: 500;
|
||||
//font-weight: 500;
|
||||
margin-top: 2px;
|
||||
|
||||
> li.active:after {
|
||||
|
@ -45,6 +45,8 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
[type="checkbox"] + span {
|
||||
padding-left: 54px;
|
||||
@ -55,6 +57,7 @@
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
@ -64,6 +67,13 @@
|
||||
flex: 1 1 auto;
|
||||
position: relative;
|
||||
//height: 1%; // fix safari
|
||||
|
||||
&.loaded {
|
||||
.profile-tabs-content {
|
||||
position: relative;
|
||||
min-height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,7 +106,7 @@
|
||||
flex-direction: column;
|
||||
padding-left: 80px;
|
||||
padding-right: 12px;
|
||||
font-size: 15px;
|
||||
//font-size: 15px;
|
||||
position: relative;
|
||||
margin-top: 31px;
|
||||
line-height: 1.4;
|
||||
@ -126,6 +136,11 @@
|
||||
color: $placeholder-color !important;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
&-notifications {
|
||||
margin-top: 29px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
}
|
||||
|
||||
&-avatar.user-avatar {
|
||||
@ -140,11 +155,18 @@
|
||||
}
|
||||
|
||||
&-tabs {
|
||||
margin-top: 36px;
|
||||
//margin-top: 36px;
|
||||
position: -webkit-sticky !important;
|
||||
position: sticky !important;
|
||||
top: 0;
|
||||
z-index: 3;
|
||||
background-color: #fff;
|
||||
|
||||
&-content {
|
||||
min-height: 100%;
|
||||
//min-height: 100%;
|
||||
min-height: calc(100% - 49px);
|
||||
position: absolute; // FIX THE SAFARI!
|
||||
//position: relative;
|
||||
/* width: 500%;
|
||||
margin-left: -100%;
|
||||
*/
|
||||
@ -167,7 +189,7 @@
|
||||
|
||||
.preloader {
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
position: absolute !important;
|
||||
height: 100%;
|
||||
|
||||
> svg {
|
||||
@ -300,13 +322,97 @@
|
||||
}
|
||||
|
||||
#content-audio {
|
||||
padding: 0 15px 15px 15px;
|
||||
padding: 20px 15px 15px 20px;
|
||||
|
||||
> div {
|
||||
margin-top: 15px;
|
||||
padding-bottom: 10px;
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
.audio {
|
||||
padding-bottom: 26px;
|
||||
padding-left: 61px;
|
||||
/* min-height: 58px; */
|
||||
max-width: 368px;
|
||||
justify-content: unset;
|
||||
|
||||
&-details {
|
||||
height: 66px;
|
||||
}
|
||||
|
||||
&.audio-show-progress .audio-subtitle {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* &-no-subtitle {
|
||||
padding-bottom: 16px;
|
||||
} */
|
||||
|
||||
&-ico {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
|
||||
&.tgico-largeplay:before {
|
||||
margin-right: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
&-download {
|
||||
border-radius: 50%;
|
||||
background-color: #50a2e9;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&-toggle, &-download {
|
||||
font-size: 1.9rem;
|
||||
}
|
||||
|
||||
&-title {
|
||||
font-size: 1rem;
|
||||
color: #000;
|
||||
line-height: 1.2;
|
||||
padding-top: 5px;
|
||||
margin-top: 0;
|
||||
margin-left: -1px;
|
||||
}
|
||||
|
||||
&-subtitle {
|
||||
font-size: 14px;
|
||||
line-height: 1.25;
|
||||
color: #707579;
|
||||
margin-left: -1px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
&-time {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
&-title, &-subtitle {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
.media-progress {
|
||||
margin: 11px 0 8px;
|
||||
|
||||
&__filled {
|
||||
background-color: #0089ff;
|
||||
transform-origin: left;
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
&__seek {
|
||||
height: 2px;
|
||||
//background-color: #e6ecf0;
|
||||
background: rgba(193, 207, 220, 0.39);
|
||||
|
||||
&::-webkit-slider-thumb {
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
91
src/scss/partials/_scrollable.scss
Normal file
91
src/scss/partials/_scrollable.scss
Normal file
@ -0,0 +1,91 @@
|
||||
div.scrollable::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
div.scrollable::-webkit-scrollbar-thumb {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-button {
|
||||
width: 0;
|
||||
height: 0;
|
||||
display: none;
|
||||
}
|
||||
::-webkit-scrollbar-corner {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
max-height: 100%;
|
||||
//position: relative;
|
||||
|
||||
//will-change: transform;
|
||||
transform: translateZ(0);
|
||||
-webkit-transform: translateZ(0);
|
||||
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&.scrollable-x {
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
&.scrollable-y {
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
&.scrollable-x ~ .scrollbar-thumb {
|
||||
top: auto;
|
||||
right: auto;
|
||||
width: auto;
|
||||
height: 4px;
|
||||
bottom: 0px;
|
||||
}
|
||||
|
||||
.scroll-padding {
|
||||
flex: 0 0 auto;
|
||||
|
||||
&:first-child + * {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scrollbar-thumb {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 2px;
|
||||
width: 4px;
|
||||
//margin-left: 2px;
|
||||
background-color: #000;
|
||||
//cursor: grab;
|
||||
cursor: default;
|
||||
opacity: 0;
|
||||
transition-property: opacity;
|
||||
transition-duration: .2s;
|
||||
transition-timing-function: ease-in-out;
|
||||
|
||||
//display: none;
|
||||
|
||||
border-radius: $border-radius;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
:hover > .scrollbar-thumb {
|
||||
opacity: .4;
|
||||
}
|
@ -41,6 +41,7 @@ $large-screen: 1680px;
|
||||
@import "partials/mediaViewer";
|
||||
@import "partials/ckin";
|
||||
@import "partials/emojiDropdown";
|
||||
@import "partials/scrollable";
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
@ -78,13 +79,20 @@ button, input, optgroup, select, textarea, html {
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
letter-spacing: -.66px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
body.is-mac * {
|
||||
font-weight: normal !important;
|
||||
/* h1, h2, h3, h4, h5, h6, .mac-thin {
|
||||
font-weight: normal;
|
||||
} */
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 2rem;
|
||||
margin: 1.5rem 0 1rem 0;
|
||||
//margin: 1.5rem 0 1rem 0;
|
||||
margin: 22px 0 14px;
|
||||
line-height: 110%;
|
||||
}
|
||||
|
||||
@ -94,8 +102,8 @@ input {
|
||||
|
||||
.subtitle {
|
||||
/* font-weight: 500; */
|
||||
color: $placeholder-color;
|
||||
line-height: 1.25;
|
||||
color: #707579;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.page-authCode {
|
||||
@ -291,11 +299,11 @@ input {
|
||||
display: block;
|
||||
border-radius: 50%;
|
||||
border: 2px solid white;
|
||||
background-color: #4DCD5E;
|
||||
left: 70%;
|
||||
top: 79%;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background-color: #0ac630;
|
||||
left: 74%;
|
||||
top: 73%;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
&.tgico-avatar_deletedaccount {
|
||||
@ -303,13 +311,10 @@ input {
|
||||
}
|
||||
}
|
||||
|
||||
/* .user-title, b {
|
||||
color: #000;
|
||||
} */
|
||||
|
||||
.user-title, b, .user-last-message b {
|
||||
color: #000;
|
||||
font-weight: normal;
|
||||
font-weight: 500;
|
||||
//font-weight: normal;
|
||||
}
|
||||
|
||||
.rp {
|
||||
@ -368,6 +373,27 @@ input {
|
||||
.document {
|
||||
padding-left: 4.5rem;
|
||||
height: 70px;
|
||||
|
||||
&-ico {
|
||||
background-color: $blue;
|
||||
border-radius: 5px;
|
||||
line-height: 10px;
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 1.125rem;
|
||||
height: 1.125rem;
|
||||
border-bottom-left-radius: .25rem;
|
||||
border-left: .5625rem solid rgba(0, 0, 0, .25);
|
||||
border-bottom: .5625rem solid rgba(0, 0, 0, .25);
|
||||
border-top: .5625rem solid #fff;
|
||||
border-right: .5625rem solid #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&-ico, &-download {
|
||||
font-weight: 500;
|
||||
@ -379,20 +405,43 @@ input {
|
||||
}
|
||||
|
||||
&-download {
|
||||
background-color: rgb(101, 161, 227);
|
||||
background-color: $blue;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
&.ext-zip {
|
||||
.document-ico, .document-download {
|
||||
background-color: #FB8C00;
|
||||
}
|
||||
}
|
||||
|
||||
&.ext-pdf {
|
||||
.document-ico, .document-download {
|
||||
background-color: #DF3F40;
|
||||
}
|
||||
}
|
||||
|
||||
&.ext-apk {
|
||||
.document-ico, .document-download {
|
||||
background-color: #43A047;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.photo) {
|
||||
.document-ico {
|
||||
padding-top: 1.5rem;
|
||||
background-image: url('../assets/img/doc-in.svg');
|
||||
//background-image: url('../assets/img/doc-in.svg');
|
||||
}
|
||||
}
|
||||
|
||||
&.photo {
|
||||
.document-ico {
|
||||
background: #000;
|
||||
border-radius: $border-radius;
|
||||
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -512,6 +561,8 @@ input {
|
||||
|
||||
.tabs-container {
|
||||
height: 100%;
|
||||
transform: translateX(0);
|
||||
width: 100%;
|
||||
|
||||
&.animated {
|
||||
transition: .42s transform;
|
||||
@ -564,19 +615,21 @@ input {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 14px;
|
||||
|
||||
canvas {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: $button-primary-background;
|
||||
background-color: $blue;
|
||||
}
|
||||
|
||||
svg {
|
||||
position: absolute;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translateY(-50%) translateX(-50%);
|
||||
@ -904,7 +957,7 @@ input:focus, button:focus {
|
||||
} */
|
||||
|
||||
.btn-primary {
|
||||
background: $button-primary-background;
|
||||
background: $blue;
|
||||
color: #fff;
|
||||
border-radius: $border-radius-medium;
|
||||
width: 100%;
|
||||
@ -918,14 +971,14 @@ input:focus, button:focus {
|
||||
padding: 0; // new
|
||||
|
||||
&:hover {
|
||||
background: darken($button-primary-background, 8%);
|
||||
background: darken($blue, 8%);
|
||||
}
|
||||
|
||||
svg, use {
|
||||
height: calc(100% - 20px);
|
||||
right: 12.5px;
|
||||
left: auto;
|
||||
margin: auto 0;
|
||||
margin: 4px 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
@ -943,39 +996,43 @@ $width: 100px;
|
||||
}
|
||||
} */
|
||||
|
||||
.preloader-circular {
|
||||
animation: rotate 2s linear infinite;
|
||||
height: 100%;
|
||||
transform-origin: center center;
|
||||
/* width: 100%; */
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
}
|
||||
.preloader {
|
||||
&-circular {
|
||||
animation: rotate 2s linear infinite;
|
||||
height: 100%;
|
||||
transform-origin: center center;
|
||||
/* width: 100%; */
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.preloader-path {
|
||||
stroke-dasharray: 1, 200;
|
||||
stroke-dashoffset: 0;
|
||||
animation: dash 1.5s ease-in-out infinite/* , color 6s ease-in-out infinite */;
|
||||
stroke-linecap: round;
|
||||
stroke: white;
|
||||
stroke-width: 3;
|
||||
&-path {
|
||||
stroke-dasharray: 1, 200;
|
||||
stroke-dashoffset: 0;
|
||||
animation: dash 1.5s ease-in-out infinite/* , color 6s ease-in-out infinite */;
|
||||
stroke-linecap: round;
|
||||
stroke: white;
|
||||
stroke-width: 3;
|
||||
}
|
||||
|
||||
&-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
/* cursor: pointer; */
|
||||
}
|
||||
}
|
||||
|
||||
.preloader-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
/* cursor: pointer; */
|
||||
|
||||
.you-spin-me-round {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@ -1165,8 +1222,8 @@ span.popup-close {
|
||||
|
||||
.btn-circle {
|
||||
border-radius: 50%;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
height: 54px;
|
||||
width: 54px;
|
||||
|
||||
path {
|
||||
fill: white;
|
||||
@ -1185,49 +1242,49 @@ span.popup-close {
|
||||
|
||||
.popup-avatar {
|
||||
.popup-container {
|
||||
/* height: 400px; */
|
||||
/* width: 400px; */
|
||||
max-width: 600px;
|
||||
max-height: 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: 15px;
|
||||
right: 15px;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.popup-close {
|
||||
font-size: 1.5rem;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.popup-header {
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1.1rem;
|
||||
font-size: 1.25rem;
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
margin-left: 1.5rem;
|
||||
font-weight: 400;
|
||||
margin-left: 2rem;
|
||||
}
|
||||
|
||||
.crop {
|
||||
/* min-width: calc(100% - 8rem);
|
||||
min-height: calc(100% - 8rem); */
|
||||
|
||||
max-width: 200%;
|
||||
max-height: 200%;
|
||||
|
||||
padding: 0 2.75rem 2.75rem;
|
||||
|
||||
/* position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%); */
|
||||
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
padding: 24px 54px 46px 46px;
|
||||
border-radius: $border-radius;
|
||||
|
||||
> img {
|
||||
display: none;
|
||||
}
|
||||
|
||||
img {
|
||||
/* max-width: 100%; */
|
||||
/* height: 100%; */
|
||||
//height: 100%;
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
}
|
||||
@ -1329,98 +1386,6 @@ span.popup-close {
|
||||
}
|
||||
}
|
||||
|
||||
div.scrollable::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
div.scrollable::-webkit-scrollbar-thumb {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-button {
|
||||
width: 0;
|
||||
height: 0;
|
||||
display: none;
|
||||
}
|
||||
::-webkit-scrollbar-corner {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
max-height: 100%;
|
||||
//position: relative;
|
||||
|
||||
//will-change: transform;
|
||||
transform: translateZ(0);
|
||||
-webkit-transform: translateZ(0);
|
||||
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&.scrollable-x {
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
&.scrollable-y {
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
&.scrollable-x ~ .scrollbar-thumb {
|
||||
top: auto;
|
||||
right: auto;
|
||||
width: auto;
|
||||
height: 4px;
|
||||
bottom: 0px;
|
||||
}
|
||||
|
||||
.scroll-padding {
|
||||
flex: 0 0 auto;
|
||||
|
||||
&:first-child + * {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scrollbar-thumb {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 2px;
|
||||
width: 4px;
|
||||
//margin-left: 2px;
|
||||
background-color: #000;
|
||||
//cursor: grab;
|
||||
cursor: default;
|
||||
opacity: 0;
|
||||
transition-property: opacity;
|
||||
transition-duration: .2s;
|
||||
transition-timing-function: ease-in-out;
|
||||
|
||||
//display: none;
|
||||
|
||||
border-radius: $border-radius;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
:hover > .scrollbar-thumb {
|
||||
opacity: .4;
|
||||
}
|
||||
|
||||
[contenteditable] {
|
||||
-webkit-user-select: text;
|
||||
user-select: text;
|
||||
@ -1450,6 +1415,7 @@ div.scrollable::-webkit-scrollbar-thumb {
|
||||
flex: 1;
|
||||
user-select: none;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
|
||||
&.active {
|
||||
color: $blue;
|
||||
@ -1644,7 +1610,7 @@ div.scrollable::-webkit-scrollbar-thumb {
|
||||
left: 50%;
|
||||
transform: translateY(-50%) translateX(-50%);
|
||||
|
||||
.preloader-path {
|
||||
&-path {
|
||||
stroke: $button-primary-background;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user