Browse Source

Auth pages css all fixed & album prepare

master
morethanwords 5 years ago
parent
commit
c35fb83125
  1. 2
      src/components/appSearch.ts
  2. 115
      src/components/chatInput.ts
  3. 2
      src/components/emoticonsDropdown.ts
  4. 27
      src/components/misc.ts
  5. 146
      src/components/wrappers.ts
  6. 4
      src/lib/appManagers/appDialogsManager.ts
  7. 9
      src/lib/appManagers/appDocsManager.ts
  8. 77
      src/lib/appManagers/appImManager.ts
  9. 85
      src/lib/appManagers/appMessagesManager.ts
  10. 18
      src/lib/appManagers/appPhotosManager.ts
  11. 44
      src/lib/appManagers/appSidebarRight.ts
  12. 2
      src/lib/mtproto/apiManager.ts
  13. 6
      src/lib/mtproto/mtproto.worker.js
  14. 2
      src/lib/mtproto/mtprotoworker.ts
  15. 2
      src/lib/mtproto/networker.ts
  16. 12
      src/pages/pageSignUp.ts
  17. 42
      src/scss/partials/_chat.scss
  18. 46
      src/scss/partials/_chatlist.scss
  19. 2
      src/scss/partials/_emojiDropdown.scss
  20. 120
      src/scss/partials/_rightSIdebar.scss
  21. 91
      src/scss/partials/_scrollable.scss
  22. 304
      src/scss/style.scss

2
src/components/appSearch.ts

@ -19,7 +19,7 @@ export class SearchGroup { @@ -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';

115
src/components/chatInput.ts

@ -187,10 +187,11 @@ export class ChatInput { @@ -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 { @@ -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) {
case 'media': {
let img = new Image();
img.src = willAttachObjectURL = URL.createObjectURL(file);
img.onload = () => {
willAttachWidth = img.naturalWidth;
willAttachHeight = img.naturalHeight;
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);
};
this.attachMediaPopUp.titleEl.innerText = 'Send Photo';
this.attachMediaPopUp.container.classList.add('active');
console.log('selected file:', file, typeof(file), willAttach);
switch(willAttach.type) {
case 'media': {
let isVideo = file.type.indexOf('video/') === 0;
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;
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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -299,15 +329,10 @@ export class ChatInput {
this.attachMediaPopUp.sendBtn.addEventListener('click', () => {
this.attachMediaPopUp.container.classList.remove('active');
let caption = this.attachMediaPopUp.captionInput.value;
appMessagesManager.sendFile(appImManager.peerID, willAttachFile, {
isMedia: true,
caption,
width: willAttachWidth,
height: willAttachHeight,
objectURL: willAttachObjectURL
});
willAttach.caption = this.attachMediaPopUp.captionInput.value;
willAttach.isMedia = willAttach.type == 'media';
appMessagesManager.sendFile(appImManager.peerID, willAttach.file, willAttach);
this.onMessageSent();
});

2
src/components/emoticonsDropdown.ts

@ -118,7 +118,7 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement, @@ -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"];

27
src/components/misc.ts

@ -151,7 +151,7 @@ export function horizontalMenu(tabs: HTMLElement, content: HTMLDivElement, onCli @@ -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 @@ -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 @@ -184,7 +199,7 @@ export function horizontalMenu(tabs: HTMLElement, content: HTMLDivElement, onCli
content.classList.add('animated');
content.style.transform = '';
});
}
} */
}
if(hideTimeout) clearTimeout(hideTimeout);

146
src/components/wrappers.ts

@ -60,13 +60,10 @@ export type MTPhotoSize = { @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 @@ -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 @@ -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 @@ -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;

4
src/lib/appManagers/appDialogsManager.ts

@ -445,7 +445,7 @@ export class AppDialogsManager { @@ -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 { @@ -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(' ') + ')';
}
}

9
src/lib/appManagers/appDocsManager.ts

@ -3,6 +3,7 @@ import FileManager from '../filemanager'; @@ -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 { @@ -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 { @@ -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 { @@ -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);
}
}

77
src/lib/appManagers/appImManager.ts

@ -24,6 +24,7 @@ import { ChatInput } from '../../components/chatInput'; @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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');

85
src/lib/appManagers/appMessagesManager.ts

@ -39,6 +39,7 @@ export type HistoryResult = { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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;

18
src/lib/appManagers/appPhotosManager.ts

@ -109,14 +109,16 @@ export class AppPhotosManager { @@ -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;
}
}
}

44
src/lib/appManagers/appSidebarRight.ts

@ -11,7 +11,7 @@ import { logger } from "../polyfill"; @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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;

2
src/lib/mtproto/apiManager.ts

@ -12,7 +12,7 @@ import HTTP from './transports/http'; @@ -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
src/lib/mtproto/mtproto.worker.js

@ -6,7 +6,7 @@ import networkerFactory from "./networkerFactory"; @@ -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) { @@ -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);

2
src/lib/mtproto/mtprotoworker.ts

@ -19,7 +19,7 @@ class ApiManagerProxy extends CryptoWorkerMethods { @@ -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;

2
src/lib/mtproto/networker.ts

@ -15,7 +15,7 @@ import HTTP from './transports/http'; @@ -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,

12
src/pages/pageSignUp.ts

@ -5,6 +5,7 @@ import pageIm from './pageIm'; @@ -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: { @@ -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 = () => { @@ -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);

42
src/scss/partials/_chat.scss

@ -178,6 +178,12 @@ $chat-max-width: 696px; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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;

46
src/scss/partials/_chatlist.scss

@ -152,9 +152,7 @@ @@ -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 @@ @@ -164,6 +162,7 @@
.user-title {
img.emoji {
vertical-align: top;
margin-top: 4px;
width: 18px;
height: 18px;
}
@ -222,7 +221,7 @@ @@ -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 @@ @@ -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;
}
}
}
}

2
src/scss/partials/_emojiDropdown.scss

@ -26,7 +26,7 @@ @@ -26,7 +26,7 @@
> .menu-horizontal {
padding: 0px 58px 0px 58px;
font-weight: 500;
//font-weight: 500;
margin-top: 2px;
> li.active:after {

120
src/scss/partials/_rightSIdebar.scss

@ -45,6 +45,8 @@ @@ -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 @@ @@ -55,6 +57,7 @@
flex: 0 0 auto;
display: flex;
flex-direction: column;
margin-bottom: 36px;
}
.content-container {
@ -64,6 +67,13 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -167,7 +189,7 @@
.preloader {
padding: 0;
position: absolute;
position: absolute !important;
height: 100%;
> svg {
@ -300,13 +322,97 @@ @@ -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

@ -0,0 +1,91 @@ @@ -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;
}

304
src/scss/style.scss

@ -41,6 +41,7 @@ $large-screen: 1680px; @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -512,6 +561,8 @@ input {
.tabs-container {
height: 100%;
transform: translateX(0);
width: 100%;
&.animated {
transition: .42s transform;
@ -564,19 +615,21 @@ input { @@ -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 { @@ -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 { @@ -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; @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -1644,7 +1610,7 @@ div.scrollable::-webkit-scrollbar-thumb {
left: 50%;
transform: translateY(-50%) translateX(-50%);
.preloader-path {
&-path {
stroke: $button-primary-background;
}
}

Loading…
Cancel
Save