Change reply width
Fix some layout issues on handhelds Improve loading avatar speeds (state)
This commit is contained in:
parent
7d94cc7369
commit
ef7e4141eb
@ -3,10 +3,11 @@ import apiManager from '../mtproto/mtprotoworker';
|
|||||||
import { RichTextProcessor } from "../richtextprocessor";
|
import { RichTextProcessor } from "../richtextprocessor";
|
||||||
import $rootScope from "../rootScope";
|
import $rootScope from "../rootScope";
|
||||||
import searchIndexManager from "../searchIndexManager";
|
import searchIndexManager from "../searchIndexManager";
|
||||||
import { copy, defineNotNumerableProperties, getAbbreviation, isObject, numberWithCommas, safeReplaceObject } from "../utils";
|
import { copy, getAbbreviation, isObject, numberWithCommas, safeReplaceObject } from "../utils";
|
||||||
import apiUpdatesManager from "./apiUpdatesManager";
|
import apiUpdatesManager from "./apiUpdatesManager";
|
||||||
import appMessagesManager from "./appMessagesManager";
|
import appMessagesManager from "./appMessagesManager";
|
||||||
import appProfileManager from "./appProfileManager";
|
import appProfileManager from "./appProfileManager";
|
||||||
|
import appStateManager from "./appStateManager";
|
||||||
import appUsersManager from "./appUsersManager";
|
import appUsersManager from "./appUsersManager";
|
||||||
|
|
||||||
export type Channel = {
|
export type Channel = {
|
||||||
@ -64,10 +65,10 @@ export type ChatRights = 'send' | 'edit_title' | 'edit_photo' | 'invite' | 'pin'
|
|||||||
|
|
||||||
export class AppChatsManager {
|
export class AppChatsManager {
|
||||||
public chats: {[id: number]: Channel | Chat | any} = {};
|
public chats: {[id: number]: Channel | Chat | any} = {};
|
||||||
public usernames: any = {};
|
//public usernames: any = {};
|
||||||
public channelAccess: any = {};
|
//public channelAccess: any = {};
|
||||||
public megagroups: any = {};
|
public megagroups: {[id: number]: true} = {};
|
||||||
public cachedPhotoLocations: any = {};
|
public cachedPhotoLocations: {[id: number]: any} = {};
|
||||||
|
|
||||||
public megagroupOnlines: {[id: number]: {timestamp: number, onlines: number}} = {};
|
public megagroupOnlines: {[id: number]: {timestamp: number, onlines: number}} = {};
|
||||||
|
|
||||||
@ -83,6 +84,10 @@ export class AppChatsManager {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
appStateManager.getState().then((state) => {
|
||||||
|
this.chats = state.chats;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public saveApiChats(apiChats: any[]) {
|
public saveApiChats(apiChats: any[]) {
|
||||||
@ -95,7 +100,7 @@ export class AppChatsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// * exclude from state
|
// * exclude from state
|
||||||
defineNotNumerableProperties(chat, ['rTitle', 'initials']);
|
// defineNotNumerableProperties(chat, ['rTitle', 'initials']);
|
||||||
|
|
||||||
//chat.rTitle = chat.title || 'chat_title_deleted';
|
//chat.rTitle = chat.title || 'chat_title_deleted';
|
||||||
chat.rTitle = RichTextProcessor.wrapRichText(chat.title, {noLinks: true, noLinebreaks: true}) || 'chat_title_deleted';
|
chat.rTitle = RichTextProcessor.wrapRichText(chat.title, {noLinks: true, noLinebreaks: true}) || 'chat_title_deleted';
|
||||||
@ -121,10 +126,10 @@ export class AppChatsManager {
|
|||||||
chat.participants_count = oldChat.participants_count;
|
chat.participants_count = oldChat.participants_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(chat.username) {
|
/* if(chat.username) {
|
||||||
let searchUsername = searchIndexManager.cleanUsername(chat.username);
|
let searchUsername = searchIndexManager.cleanUsername(chat.username);
|
||||||
this.usernames[searchUsername] = chat.id;
|
this.usernames[searchUsername] = chat.id;
|
||||||
}
|
} */
|
||||||
|
|
||||||
let changedPhoto = false;
|
let changedPhoto = false;
|
||||||
if(oldChat === undefined) {
|
if(oldChat === undefined) {
|
||||||
@ -152,7 +157,7 @@ export class AppChatsManager {
|
|||||||
|
|
||||||
public getChat(id: number) {
|
public getChat(id: number) {
|
||||||
if(id < 0) id = -id;
|
if(id < 0) id = -id;
|
||||||
return this.chats[id] || {_: 'chatEmpty', id: id, deleted: true, access_hash: this.channelAccess[id]};
|
return this.chats[id] || {_: 'chatEmpty', id: id, deleted: true, access_hash: ''/* this.channelAccess[id] */};
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasRights(id: number, action: ChatRights, flag?: keyof ChatBannedRights['pFlags']) {
|
public hasRights(id: number, action: ChatRights, flag?: keyof ChatBannedRights['pFlags']) {
|
||||||
@ -239,13 +244,13 @@ export class AppChatsManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public resolveUsername(username: string) {
|
/* public resolveUsername(username: string) {
|
||||||
return this.usernames[username] || 0;
|
return this.usernames[username] || 0;
|
||||||
}
|
} */
|
||||||
|
|
||||||
public saveChannelAccess(id: number, accessHash: string) {
|
/* public saveChannelAccess(id: number, accessHash: string) {
|
||||||
this.channelAccess[id] = accessHash;
|
this.channelAccess[id] = accessHash;
|
||||||
}
|
} */
|
||||||
|
|
||||||
public saveIsMegagroup(id: number) {
|
public saveIsMegagroup(id: number) {
|
||||||
this.megagroups[id] = true;
|
this.megagroups[id] = true;
|
||||||
@ -254,7 +259,7 @@ export class AppChatsManager {
|
|||||||
public isChannel(id: number) {
|
public isChannel(id: number) {
|
||||||
if(id < 0) id = -id;
|
if(id < 0) id = -id;
|
||||||
let chat = this.chats[id];
|
let chat = this.chats[id];
|
||||||
if(chat && (chat._ == 'channel' || chat._ == 'channelForbidden') || this.channelAccess[id]) {
|
if(chat && (chat._ == 'channel' || chat._ == 'channelForbidden')/* || this.channelAccess[id] */) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -281,7 +286,7 @@ export class AppChatsManager {
|
|||||||
return {
|
return {
|
||||||
_: 'inputChannel',
|
_: 'inputChannel',
|
||||||
channel_id: id,
|
channel_id: id,
|
||||||
access_hash: this.getChat(id).access_hash || this.channelAccess[id] || 0
|
access_hash: this.getChat(id).access_hash/* || this.channelAccess[id] */ || 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,7 +301,7 @@ export class AppChatsManager {
|
|||||||
return {
|
return {
|
||||||
_: 'inputPeerChannel',
|
_: 'inputPeerChannel',
|
||||||
channel_id: id,
|
channel_id: id,
|
||||||
access_hash: this.getChat(id).access_hash || this.channelAccess[id] || 0
|
access_hash: this.getChat(id).access_hash/* || this.channelAccess[id] */ || 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,7 +703,7 @@ export class AppDialogsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* if(lastMessage.from_id == auth.id) { // You: */
|
/* if(lastMessage.from_id == auth.id) { // You: */
|
||||||
if(peer._ != 'peerUser' && peerID != lastMessage.fromID) {
|
if(peer._ != 'peerUser' && peerID != lastMessage.fromID && !lastMessage.action) {
|
||||||
const sender = appPeersManager.getPeer(lastMessage.fromID);
|
const sender = appPeersManager.getPeer(lastMessage.fromID);
|
||||||
if(sender && sender.id) {
|
if(sender && sender.id) {
|
||||||
const senderBold = document.createElement('b');
|
const senderBold = document.createElement('b');
|
||||||
|
@ -50,10 +50,11 @@ class AppDocsManager {
|
|||||||
this.docs[doc.id] = doc;
|
this.docs[doc.id] = doc;
|
||||||
|
|
||||||
// * exclude from state
|
// * exclude from state
|
||||||
defineNotNumerableProperties(doc, [/* 'thumbs', */'type', 'h', 'w', 'file_name',
|
// defineNotNumerableProperties(doc, [/* 'thumbs', */'type', 'h', 'w', 'file_name',
|
||||||
'file', 'duration', 'downloaded', 'url', 'audioTitle',
|
// 'file', 'duration', 'downloaded', 'url', 'audioTitle',
|
||||||
'audioPerformer', 'sticker', 'stickerEmoji', 'stickerEmojiRaw',
|
// 'audioPerformer', 'sticker', 'stickerEmoji', 'stickerEmojiRaw',
|
||||||
'stickerSetInput', 'stickerThumbConverted', 'animated', 'supportsStreaming']);
|
// 'stickerSetInput', 'stickerThumbConverted', 'animated', 'supportsStreaming']);
|
||||||
|
defineNotNumerableProperties(doc, ['downloaded', 'url']);
|
||||||
|
|
||||||
doc.attributes.forEach(attribute => {
|
doc.attributes.forEach(attribute => {
|
||||||
switch(attribute._) {
|
switch(attribute._) {
|
||||||
|
@ -36,7 +36,7 @@ import apiManager from '../mtproto/mtprotoworker';
|
|||||||
import { MOUNT_CLASS_TO } from '../mtproto/mtproto_config';
|
import { MOUNT_CLASS_TO } from '../mtproto/mtproto_config';
|
||||||
import { RichTextProcessor } from "../richtextprocessor";
|
import { RichTextProcessor } from "../richtextprocessor";
|
||||||
import $rootScope from '../rootScope';
|
import $rootScope from '../rootScope';
|
||||||
import { cancelEvent, findUpClassName, findUpTag, getObjectKeysAndSort, langPack, numberWithCommas, placeCaretAtEnd, whichChild } from "../utils";
|
import { cancelEvent, defineNotNumerableProperties, findUpClassName, findUpTag, getObjectKeysAndSort, langPack, numberWithCommas, placeCaretAtEnd, whichChild } from "../utils";
|
||||||
import apiUpdatesManager from './apiUpdatesManager';
|
import apiUpdatesManager from './apiUpdatesManager';
|
||||||
import appChatsManager, { Channel, Chat } from "./appChatsManager";
|
import appChatsManager, { Channel, Chat } from "./appChatsManager";
|
||||||
import appDialogsManager from "./appDialogsManager";
|
import appDialogsManager from "./appDialogsManager";
|
||||||
@ -258,6 +258,8 @@ export class AppImManager {
|
|||||||
const photo = appPhotosManager.getPhoto('' + tempID);
|
const photo = appPhotosManager.getPhoto('' + tempID);
|
||||||
if(/* photo._ != 'photoEmpty' */photo) {
|
if(/* photo._ != 'photoEmpty' */photo) {
|
||||||
const newPhoto = message.media.photo;
|
const newPhoto = message.media.photo;
|
||||||
|
// костыль
|
||||||
|
defineNotNumerableProperties(newPhoto, ['downloaded', 'url']);
|
||||||
newPhoto.downloaded = photo.downloaded;
|
newPhoto.downloaded = photo.downloaded;
|
||||||
newPhoto.url = photo.url;
|
newPhoto.url = photo.url;
|
||||||
}
|
}
|
||||||
@ -1651,30 +1653,7 @@ export class AppImManager {
|
|||||||
|
|
||||||
bubble.className = 'bubble service';
|
bubble.className = 'bubble service';
|
||||||
|
|
||||||
let title = appPeersManager.getPeerTitle(message.fromID);
|
bubbleContainer.innerHTML = `<div class="service-msg">${message.rReply}</div>`;
|
||||||
let name = document.createElement('div');
|
|
||||||
name.classList.add('name');
|
|
||||||
name.dataset.peerID = message.fromID;
|
|
||||||
name.innerHTML = title;
|
|
||||||
|
|
||||||
let str = '';
|
|
||||||
if(action.message) {
|
|
||||||
str = RichTextProcessor.wrapRichText(action.message, {noLinebreaks: true});
|
|
||||||
} else {
|
|
||||||
if(_ == "messageActionPhoneCall") {
|
|
||||||
_ += '.' + action.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
let l = langPack[_];
|
|
||||||
if(!l) {
|
|
||||||
l = '[' + _ + ']';
|
|
||||||
}
|
|
||||||
|
|
||||||
str = l[0].toUpperCase() == l[0] ? l : (name.innerText ? name.outerHTML + ' ' : '') + l;
|
|
||||||
}
|
|
||||||
|
|
||||||
bubbleContainer.innerHTML = `<div class="service-msg">${str}</div>`;
|
|
||||||
|
|
||||||
if(updatePosition) {
|
if(updatePosition) {
|
||||||
this.renderMessagesQueue(message, bubble, reverse);
|
this.renderMessagesQueue(message, bubble, reverse);
|
||||||
|
@ -996,10 +996,12 @@ export class AppMessagesManager {
|
|||||||
size: file.size
|
size: file.size
|
||||||
}],
|
}],
|
||||||
w: options.width,
|
w: options.width,
|
||||||
h: options.height,
|
h: options.height
|
||||||
downloaded: file.size,
|
|
||||||
url: options.objectURL || ''
|
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
|
defineNotNumerableProperties(photo, ['downloaded', 'url']);
|
||||||
|
photo.downloaded = file.size;
|
||||||
|
photo.url = options.objectURL || '';
|
||||||
|
|
||||||
appPhotosManager.savePhoto(photo);
|
appPhotosManager.savePhoto(photo);
|
||||||
} else if(fileType.indexOf('audio/') === 0 || ['video/ogg'].indexOf(fileType) >= 0) {
|
} else if(fileType.indexOf('audio/') === 0 || ['video/ogg'].indexOf(fileType) >= 0) {
|
||||||
@ -1063,13 +1065,16 @@ export class AppMessagesManager {
|
|||||||
attributes,
|
attributes,
|
||||||
w: options.width,
|
w: options.width,
|
||||||
h: options.height,
|
h: options.height,
|
||||||
downloaded: file.size,
|
|
||||||
thumbs,
|
thumbs,
|
||||||
mime_type: fileType,
|
mime_type: fileType,
|
||||||
url: options.objectURL || '',
|
|
||||||
size: file.size
|
size: file.size
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
|
defineNotNumerableProperties(doc, ['downloaded', 'url']);
|
||||||
|
// @ts-ignore
|
||||||
|
doc.downloaded = file.size;
|
||||||
|
doc.url = options.objectURL || '';
|
||||||
|
|
||||||
if(isPhoto) {
|
if(isPhoto) {
|
||||||
attributes.push({
|
attributes.push({
|
||||||
_: 'documentAttributeImageSize',
|
_: 'documentAttributeImageSize',
|
||||||
@ -1375,12 +1380,15 @@ export class AppMessagesManager {
|
|||||||
_: 'document',
|
_: 'document',
|
||||||
id: '' + messageID,
|
id: '' + messageID,
|
||||||
attributes: [videoAttribute],
|
attributes: [videoAttribute],
|
||||||
downloaded: file.size,
|
|
||||||
thumbs: [],
|
thumbs: [],
|
||||||
mime_type: file.type,
|
mime_type: file.type,
|
||||||
url: details.objectURL || '',
|
|
||||||
size: file.size
|
size: file.size
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
|
defineNotNumerableProperties(doc, ['downloaded', 'url']);
|
||||||
|
// @ts-ignore
|
||||||
|
doc.downloaded = file.size;
|
||||||
|
doc.url = details.objectURL || '';
|
||||||
|
|
||||||
appDocsManager.saveDoc(doc);
|
appDocsManager.saveDoc(doc);
|
||||||
media.document = doc;
|
media.document = doc;
|
||||||
@ -1396,10 +1404,13 @@ export class AppMessagesManager {
|
|||||||
size: file.size
|
size: file.size
|
||||||
} as PhotoSize],
|
} as PhotoSize],
|
||||||
w: details.width,
|
w: details.width,
|
||||||
h: details.height,
|
h: details.height
|
||||||
downloaded: file.size,
|
|
||||||
url: details.objectURL || ''
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
defineNotNumerableProperties(photo, ['downloaded', 'url']);
|
||||||
|
// @ts-ignore
|
||||||
|
photo.downloaded = file.size;
|
||||||
|
photo.url = details.objectURL || '';
|
||||||
|
|
||||||
appPhotosManager.savePhoto(photo);
|
appPhotosManager.savePhoto(photo);
|
||||||
media.photo = photo;
|
media.photo = photo;
|
||||||
@ -2218,7 +2229,7 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// * exclude from state
|
// * exclude from state
|
||||||
defineNotNumerableProperties(message, ['rReply', 'mid', 'savedFrom', 'fwdFromID', 'fromID', 'peerID', 'reply_to_mid', 'viaBotID']);
|
// defineNotNumerableProperties(message, ['rReply', 'mid', 'savedFrom', 'fwdFromID', 'fromID', 'peerID', 'reply_to_mid', 'viaBotID']);
|
||||||
|
|
||||||
const peerID = this.getMessagePeer(message);
|
const peerID = this.getMessagePeer(message);
|
||||||
const isChannel = message.peer_id._ == 'peerChannel';
|
const isChannel = message.peer_id._ == 'peerChannel';
|
||||||
@ -2481,33 +2492,7 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(message.action) {
|
if(message.action) {
|
||||||
let action = message.action;
|
const str = this.wrapMessageActionText(message);
|
||||||
|
|
||||||
let str = '';
|
|
||||||
if(action.message) {
|
|
||||||
str = RichTextProcessor.wrapRichText(action.message, {noLinebreaks: true});
|
|
||||||
} else {
|
|
||||||
let suffix = '';
|
|
||||||
let _ = action._;
|
|
||||||
if(_ == "messageActionPhoneCall") {
|
|
||||||
_ += '.' + action.type;
|
|
||||||
|
|
||||||
let duration = action.duration;
|
|
||||||
if(duration) {
|
|
||||||
let d = [];
|
|
||||||
|
|
||||||
d.push(duration % 60 + ' s');
|
|
||||||
if(duration >= 60) d.push((duration / 60 | 0) + ' min');
|
|
||||||
//if(duration >= 3600) d.push((duration / 3600 | 0) + ' h');
|
|
||||||
suffix = ' (' + d.reverse().join(' ') + ')';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
str = (langPack[_] || action._) + suffix;
|
|
||||||
}
|
|
||||||
|
|
||||||
//this.log('message action:', action);
|
|
||||||
|
|
||||||
messageText = str ? '<i>' + str + '</i>' : '';
|
messageText = str ? '<i>' + str + '</i>' : '';
|
||||||
}
|
}
|
||||||
@ -2529,6 +2514,68 @@ export class AppMessagesManager {
|
|||||||
return messageText + messageWrapped;
|
return messageText + messageWrapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public wrapMessageActionText(message: any) {
|
||||||
|
const action = message.action;
|
||||||
|
|
||||||
|
let str = '';
|
||||||
|
if(action.message) {
|
||||||
|
str = RichTextProcessor.wrapRichText(action.message, {noLinebreaks: true});
|
||||||
|
} else {
|
||||||
|
let _ = action._;
|
||||||
|
let suffix = '';
|
||||||
|
let l = '';
|
||||||
|
|
||||||
|
const getNameDivHTML = (peerID: number) => {
|
||||||
|
const title = appPeersManager.getPeerTitle(peerID);
|
||||||
|
return title ? `<div class="name inline" data-peer-i-d="${peerID}">${title}</div> ` : '';
|
||||||
|
};
|
||||||
|
|
||||||
|
switch(_) {
|
||||||
|
case "messageActionPhoneCall": {
|
||||||
|
_ += '.' + action.type;
|
||||||
|
|
||||||
|
const duration = action.duration;
|
||||||
|
if(duration) {
|
||||||
|
const d: string[] = [];
|
||||||
|
|
||||||
|
d.push(duration % 60 + ' s');
|
||||||
|
if(duration >= 60) d.push((duration / 60 | 0) + ' min');
|
||||||
|
//if(duration >= 3600) d.push((duration / 3600 | 0) + ' h');
|
||||||
|
suffix = ' (' + d.reverse().join(' ') + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
return langPack[_] + suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'messageActionChatDeleteUser':
|
||||||
|
case 'messageActionChatAddUsers':
|
||||||
|
case 'messageActionChatAddUser': {
|
||||||
|
let users: number[] = action.users || [action.user_id];
|
||||||
|
|
||||||
|
l = langPack[_].replace('{}', users.map((userID: number) => getNameDivHTML(userID)).join(', '));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
str = langPack[_] || `[${action._}]`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!l) {
|
||||||
|
l = langPack[_];
|
||||||
|
if(!l) {
|
||||||
|
l = '[' + _ + ']';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
str = l[0].toUpperCase() == l[0] ? l : getNameDivHTML(message.fromID) + l + (suffix ? ' ' : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
//this.log('message action:', action);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
public editPeerFolders(peerIDs: number[], folderID: number) {
|
public editPeerFolders(peerIDs: number[], folderID: number) {
|
||||||
apiManager.invokeApi('folders.editPeerFolders', {
|
apiManager.invokeApi('folders.editPeerFolders', {
|
||||||
folder_peers: peerIDs.map(peerID => {
|
folder_peers: peerIDs.map(peerID => {
|
||||||
|
@ -2,7 +2,6 @@ import { DialogPeer, InputDialogPeer, InputPeer, Peer } from "../../layer";
|
|||||||
import { RichTextProcessor } from "../richtextprocessor";
|
import { RichTextProcessor } from "../richtextprocessor";
|
||||||
import { isObject } from "../utils";
|
import { isObject } from "../utils";
|
||||||
import appChatsManager from "./appChatsManager";
|
import appChatsManager from "./appChatsManager";
|
||||||
import appStateManager from "./appStateManager";
|
|
||||||
import appUsersManager from "./appUsersManager";
|
import appUsersManager from "./appUsersManager";
|
||||||
|
|
||||||
// https://github.com/eelcohn/Telegram-API/wiki/Calculating-color-for-a-Telegram-user-on-IRC
|
// https://github.com/eelcohn/Telegram-API/wiki/Calculating-color-for-a-Telegram-user-on-IRC
|
||||||
@ -22,19 +21,10 @@ const DialogColors = ['#e17076', '#7bc862', '#e5ca77', '#65AADD', '#a695e7', '#e
|
|||||||
const DialogColorsMap = [0, 7, 4, 1, 6, 3, 5];
|
const DialogColorsMap = [0, 7, 4, 1, 6, 3, 5];
|
||||||
|
|
||||||
export class AppPeersManager {
|
export class AppPeersManager {
|
||||||
constructor() {
|
/* public savePeerInstance(peerID: number, instance: any) {
|
||||||
appStateManager.getState().then((state) => {
|
if(peerID < 0) appChatsManager.saveApiChat(instance);
|
||||||
for(let peerID in state.peers) {
|
|
||||||
let peer = state.peers[peerID];
|
|
||||||
this.savePeerInstance(+peerID, peer);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public savePeerInstance(peerID: number, instance: any) {
|
|
||||||
if(+peerID < 0) appChatsManager.saveApiChat(instance);
|
|
||||||
else appUsersManager.saveApiUser(instance);
|
else appUsersManager.saveApiUser(instance);
|
||||||
}
|
} */
|
||||||
|
|
||||||
public getPeerPhoto(peerID: number) {
|
public getPeerPhoto(peerID: number) {
|
||||||
return peerID > 0
|
return peerID > 0
|
||||||
@ -150,13 +140,13 @@ export class AppPeersManager {
|
|||||||
return (peerID > 0) && appUsersManager.isBot(peerID);
|
return (peerID > 0) && appUsersManager.isBot(peerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getInputPeer(peerString: string): InputPeer {
|
/* public getInputPeer(peerString: string): InputPeer {
|
||||||
var firstChar = peerString.charAt(0);
|
var firstChar = peerString.charAt(0);
|
||||||
var peerParams = peerString.substr(1).split('_');
|
var peerParams = peerString.substr(1).split('_');
|
||||||
let id = +peerParams[0];
|
let id = +peerParams[0];
|
||||||
|
|
||||||
if(firstChar == 'u') {
|
if(firstChar == 'u') {
|
||||||
appUsersManager.saveUserAccess(id, peerParams[1]);
|
//appUsersManager.saveUserAccess(id, peerParams[1]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_: 'inputPeerUser',
|
_: 'inputPeerUser',
|
||||||
@ -164,7 +154,7 @@ export class AppPeersManager {
|
|||||||
access_hash: peerParams[1]
|
access_hash: peerParams[1]
|
||||||
};
|
};
|
||||||
} else if(firstChar == 'c' || firstChar == 's') {
|
} else if(firstChar == 'c' || firstChar == 's') {
|
||||||
appChatsManager.saveChannelAccess(id, peerParams[1]);
|
//appChatsManager.saveChannelAccess(id, peerParams[1]);
|
||||||
if(firstChar == 's') {
|
if(firstChar == 's') {
|
||||||
appChatsManager.saveIsMegagroup(id);
|
appChatsManager.saveIsMegagroup(id);
|
||||||
}
|
}
|
||||||
@ -180,7 +170,7 @@ export class AppPeersManager {
|
|||||||
chat_id: id
|
chat_id: id
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
|
|
||||||
public getInputPeerByID(peerID: number): InputPeer {
|
public getInputPeerByID(peerID: number): InputPeer {
|
||||||
if(!peerID) {
|
if(!peerID) {
|
||||||
|
@ -6,6 +6,8 @@ import EventListenerBase from '../../helpers/eventListenerBase';
|
|||||||
import $rootScope from '../rootScope';
|
import $rootScope from '../rootScope';
|
||||||
import AppStorage from '../storage';
|
import AppStorage from '../storage';
|
||||||
import { logger } from '../logger';
|
import { logger } from '../logger';
|
||||||
|
import type { AppUsersManager } from './appUsersManager';
|
||||||
|
import type { AppChatsManager } from './appChatsManager';
|
||||||
|
|
||||||
const REFRESH_EVERY = 24 * 60 * 60 * 1000; // 1 day
|
const REFRESH_EVERY = 24 * 60 * 60 * 1000; // 1 day
|
||||||
const STATE_VERSION = App.version;
|
const STATE_VERSION = App.version;
|
||||||
@ -13,7 +15,9 @@ const STATE_VERSION = App.version;
|
|||||||
type State = Partial<{
|
type State = Partial<{
|
||||||
dialogs: Dialog[],
|
dialogs: Dialog[],
|
||||||
allDialogsLoaded: DialogsStorage['allDialogsLoaded'],
|
allDialogsLoaded: DialogsStorage['allDialogsLoaded'],
|
||||||
peers: {[peerID: string]: ReturnType<AppPeersManager['getPeer']>},
|
//peers: {[peerID: string]: ReturnType<AppPeersManager['getPeer']>},
|
||||||
|
chats: {[peerID: string]: ReturnType<AppChatsManager['getChat']>},
|
||||||
|
users: {[peerID: string]: ReturnType<AppUsersManager['getUser']>},
|
||||||
messages: any[],
|
messages: any[],
|
||||||
contactsList: number[],
|
contactsList: number[],
|
||||||
updates: any,
|
updates: any,
|
||||||
@ -60,12 +64,10 @@ export class AppStateManager extends EventListenerBase<{
|
|||||||
//state = {};
|
//state = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// will not throw error because state can be `FALSE`
|
|
||||||
const {peers} = state;
|
|
||||||
|
|
||||||
this.state = state || {};
|
this.state = state || {};
|
||||||
this.state.peers = peers || {};
|
this.state.chats = state.chats || {};
|
||||||
|
this.state.users = state.users || {};
|
||||||
this.state.version = STATE_VERSION;
|
this.state.version = STATE_VERSION;
|
||||||
|
|
||||||
// ??= doesn't compiles
|
// ??= doesn't compiles
|
||||||
@ -114,8 +116,9 @@ export class AppStateManager extends EventListenerBase<{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setPeer(peerID: number, peer: any) {
|
public setPeer(peerID: number, peer: any) {
|
||||||
if(this.state.peers.hasOwnProperty(peerID)) return;
|
const container = peerID > 0 ? this.state.users : this.state.chats;
|
||||||
this.state.peers[peerID] = peer;
|
if(container.hasOwnProperty(peerID)) return;
|
||||||
|
container[peerID] = peer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,57 +6,30 @@ import serverTimeManager from "../mtproto/serverTimeManager";
|
|||||||
import { RichTextProcessor } from "../richtextprocessor";
|
import { RichTextProcessor } from "../richtextprocessor";
|
||||||
import $rootScope from "../rootScope";
|
import $rootScope from "../rootScope";
|
||||||
import searchIndexManager from "../searchIndexManager";
|
import searchIndexManager from "../searchIndexManager";
|
||||||
import { defineNotNumerableProperties, getAbbreviation, isObject, safeReplaceObject, tsNow } from "../utils";
|
import { getAbbreviation, isObject, safeReplaceObject, tsNow } from "../utils";
|
||||||
import appChatsManager from "./appChatsManager";
|
import appChatsManager from "./appChatsManager";
|
||||||
import appPeersManager from "./appPeersManager";
|
import appPeersManager from "./appPeersManager";
|
||||||
import appStateManager from "./appStateManager";
|
import appStateManager from "./appStateManager";
|
||||||
|
|
||||||
// TODO: updateUserBlocked
|
// TODO: updateUserBlocked
|
||||||
|
|
||||||
/* export type User = {
|
|
||||||
_: 'user',
|
|
||||||
access_hash: string,
|
|
||||||
first_name: string,
|
|
||||||
last_name: string,
|
|
||||||
username: string,
|
|
||||||
flags: number,
|
|
||||||
id: number,
|
|
||||||
phone: string,
|
|
||||||
photo: any,
|
|
||||||
|
|
||||||
status?: Partial<{
|
|
||||||
_: 'userStatusOffline' | 'userStatusOnline' | 'userStatusRecently' | 'userStatusLastWeek' | 'userStatusLastMonth' | 'userStatusEmpty',
|
|
||||||
wasStatus: any,
|
|
||||||
was_online: number,
|
|
||||||
expires: number
|
|
||||||
}>,
|
|
||||||
|
|
||||||
initials?: string,
|
|
||||||
num?: number,
|
|
||||||
pFlags: Partial<{verified: boolean, support: boolean, self: boolean, bot: boolean, min: number, deleted: boolean}>,
|
|
||||||
rFirstName?: string,
|
|
||||||
rFullName?: string,
|
|
||||||
rPhone?: string,
|
|
||||||
sortName?: string,
|
|
||||||
sortStatus?: number,
|
|
||||||
}; */
|
|
||||||
export type User = MTUser.user;
|
export type User = MTUser.user;
|
||||||
|
|
||||||
export class AppUsersManager {
|
export class AppUsersManager {
|
||||||
public users: {[userID: number]: User} = {};
|
public users: {[userID: number]: User} = {};
|
||||||
public usernames: {[username: string]: number} = {};
|
public usernames: {[username: string]: number} = {};
|
||||||
public userAccess: {[userID: number]: string} = {};
|
//public userAccess: {[userID: number]: string} = {};
|
||||||
public cachedPhotoLocations: any = {};
|
public cachedPhotoLocations: any = {};
|
||||||
public contactsIndex = searchIndexManager.createIndex();
|
public contactsIndex = searchIndexManager.createIndex();
|
||||||
public contactsFillPromise: Promise<Set<number>>;
|
public contactsFillPromise: Promise<Set<number>>;
|
||||||
public contactsList: Set<number> = new Set();
|
public contactsList: Set<number> = new Set();
|
||||||
|
|
||||||
public getPeersPromise: Promise<number[]>;
|
public getTopPeersPromise: Promise<number[]>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
setInterval(this.updateUsersStatuses.bind(this), 60000);
|
setInterval(this.updateUsersStatuses, 60000);
|
||||||
|
|
||||||
$rootScope.$on('stateSynchronized', this.updateUsersStatuses.bind(this));
|
$rootScope.$on('stateSynchronized', this.updateUsersStatuses);
|
||||||
|
|
||||||
$rootScope.$on('apiUpdate', (e) => {
|
$rootScope.$on('apiUpdate', (e) => {
|
||||||
const update = e.detail as Update;
|
const update = e.detail as Update;
|
||||||
@ -137,6 +110,8 @@ export class AppUsersManager {
|
|||||||
});
|
});
|
||||||
this.contactsFillPromise = Promise.resolve(this.contactsList);
|
this.contactsFillPromise = Promise.resolve(this.contactsList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.users = state.users;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,12 +122,14 @@ export class AppUsersManager {
|
|||||||
|
|
||||||
return this.contactsFillPromise = apiManager.invokeApi('contacts.getContacts', {
|
return this.contactsFillPromise = apiManager.invokeApi('contacts.getContacts', {
|
||||||
hash: 0
|
hash: 0
|
||||||
}).then((result: any) => {
|
}).then((result) => {
|
||||||
this.saveApiUsers(result.users);
|
if(result._ == 'contacts.contacts') {
|
||||||
|
this.saveApiUsers(result.users);
|
||||||
|
|
||||||
result.contacts.forEach((contact: any) => {
|
result.contacts.forEach((contact) => {
|
||||||
this.pushContact(contact.user_id);
|
this.pushContact(contact.user_id);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return this.contactsList;
|
return this.contactsList;
|
||||||
});
|
});
|
||||||
@ -221,10 +198,6 @@ export class AppUsersManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* public resolveUsername(username: string) {
|
|
||||||
return this.usernames[username] || 0;
|
|
||||||
} */
|
|
||||||
|
|
||||||
public saveApiUsers(apiUsers: any[]) {
|
public saveApiUsers(apiUsers: any[]) {
|
||||||
apiUsers.forEach((user) => this.saveApiUser(user));
|
apiUsers.forEach((user) => this.saveApiUser(user));
|
||||||
}
|
}
|
||||||
@ -251,7 +224,7 @@ export class AppUsersManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// * exclude from state
|
// * exclude from state
|
||||||
defineNotNumerableProperties(user, ['initials', 'num', 'rFirstName', 'rFullName', 'rPhone', 'sortName', 'sortStatus']);
|
// defineNotNumerableProperties(user, ['initials', 'num', 'rFirstName', 'rFullName', 'rPhone', 'sortName', 'sortStatus']);
|
||||||
|
|
||||||
if(user.phone) {
|
if(user.phone) {
|
||||||
user.rPhone = '+' + formatPhoneNumber(user.phone).formatted;
|
user.rPhone = '+' + formatPhoneNumber(user.phone).formatted;
|
||||||
@ -306,9 +279,9 @@ export class AppUsersManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public saveUserAccess(id: number, accessHash: string) {
|
/* public saveUserAccess(id: number, accessHash: string) {
|
||||||
this.userAccess[id] = accessHash;
|
this.userAccess[id] = accessHash;
|
||||||
}
|
} */
|
||||||
|
|
||||||
public getUserStatusForSort(status: User['status']) {
|
public getUserStatusForSort(status: User['status']) {
|
||||||
if(status) {
|
if(status) {
|
||||||
@ -336,7 +309,7 @@ export class AppUsersManager {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.users[id] || {id: id, pFlags: {deleted: true}, access_hash: this.userAccess[id]} as User;
|
return this.users[id] || {id: id, pFlags: {deleted: true}, access_hash: ''/* this.userAccess[id] */} as User;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getSelf() {
|
public getSelf() {
|
||||||
@ -462,7 +435,7 @@ export class AppUsersManager {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateUsersStatuses() {
|
public updateUsersStatuses = () => {
|
||||||
const timestampNow = tsNow(true);
|
const timestampNow = tsNow(true);
|
||||||
for(const i in this.users) {
|
for(const i in this.users) {
|
||||||
const user = this.users[i];
|
const user = this.users[i];
|
||||||
@ -475,7 +448,7 @@ export class AppUsersManager {
|
|||||||
$rootScope.$broadcast('user_update', user.id);
|
$rootScope.$broadcast('user_update', user.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
public forceUserOnline(id: number) {
|
public forceUserOnline(id: number) {
|
||||||
if(this.isBot(id)) {
|
if(this.isBot(id)) {
|
||||||
@ -571,15 +544,14 @@ export class AppUsersManager {
|
|||||||
} */
|
} */
|
||||||
|
|
||||||
public getTopPeers(): Promise<number[]> {
|
public getTopPeers(): Promise<number[]> {
|
||||||
if(this.getPeersPromise) return this.getPeersPromise;
|
if(this.getTopPeersPromise) return this.getTopPeersPromise;
|
||||||
|
|
||||||
return this.getPeersPromise = appStateManager.getState().then((state) => {
|
return this.getTopPeersPromise = appStateManager.getState().then((state) => {
|
||||||
if(state?.topPeers?.length) {
|
if(state?.topPeers?.length) {
|
||||||
return state.topPeers;
|
return state.topPeers;
|
||||||
}
|
}
|
||||||
|
|
||||||
return apiManager.invokeApi('contacts.getTopPeers', {
|
return apiManager.invokeApi('contacts.getTopPeers', {
|
||||||
flags: 1,
|
|
||||||
correspondents: true,
|
correspondents: true,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
limit: 30,
|
limit: 30,
|
||||||
@ -643,9 +615,9 @@ export class AppUsersManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = this.users[userID];
|
const user = this.users[userID];
|
||||||
if(user) {
|
if(user) {
|
||||||
var status: any = offline ? {
|
const status: any = offline ? {
|
||||||
_: 'userStatusOffline',
|
_: 'userStatusOffline',
|
||||||
was_online: tsNow(true)
|
was_online: tsNow(true)
|
||||||
} : {
|
} : {
|
||||||
|
@ -16,7 +16,7 @@ export type UserAuth = {
|
|||||||
export const App = {
|
export const App = {
|
||||||
id: 1025907,
|
id: 1025907,
|
||||||
hash: '452b0359b988148995f22ff0f4229750',
|
hash: '452b0359b988148995f22ff0f4229750',
|
||||||
version: '0.3.0',
|
version: '0.3.1',
|
||||||
domains: [] as string[],
|
domains: [] as string[],
|
||||||
baseDcID: 2
|
baseDcID: 2
|
||||||
};
|
};
|
||||||
|
@ -204,10 +204,10 @@ export const langPack: {[actionType: string]: string} = {
|
|||||||
"messageActionChatDeletePhoto": "removed group photo",
|
"messageActionChatDeletePhoto": "removed group photo",
|
||||||
"messageActionChatReturn": "returned to group",
|
"messageActionChatReturn": "returned to group",
|
||||||
"messageActionChatJoined": "joined the group",
|
"messageActionChatJoined": "joined the group",
|
||||||
"messageActionChatAddUser": "invited {user}",
|
"messageActionChatAddUser": "invited {}",
|
||||||
"messageActionChatAddUsers": "invited {} users",
|
"messageActionChatAddUsers": "invited {} users",
|
||||||
"messageActionChatLeave": "left the group",
|
"messageActionChatLeave": "left the group",
|
||||||
"messageActionChatDeleteUser": "removed user",
|
"messageActionChatDeleteUser": "removed user {}",
|
||||||
"messageActionChatJoinedByLink": "joined the group",
|
"messageActionChatJoinedByLink": "joined the group",
|
||||||
"messageActionPinMessage": "pinned message",
|
"messageActionPinMessage": "pinned message",
|
||||||
"messageActionContactSignUp": "joined Telegram",
|
"messageActionContactSignUp": "joined Telegram",
|
||||||
|
@ -96,6 +96,10 @@ Utility Classes
|
|||||||
}
|
}
|
||||||
} */
|
} */
|
||||||
|
|
||||||
|
.inline {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
.center-align, .text-center {
|
.center-align, .text-center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
@ -305,7 +305,7 @@ $chat-helper-size: 39px;
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 9px;
|
padding: 9px;
|
||||||
/* height: 100%; */
|
/* height: 100%; */
|
||||||
max-height: 30rem;
|
max-height: calc(30rem - var(--padding-vertical) * 2);
|
||||||
overflow-y: none;
|
overflow-y: none;
|
||||||
resize: none;
|
resize: none;
|
||||||
border: none;
|
border: none;
|
||||||
@ -733,6 +733,10 @@ $chat-helper-size: 39px;
|
|||||||
.pinned-message-content, .reply-content {
|
.pinned-message-content, .reply-content {
|
||||||
padding-left: 40px;
|
padding-left: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.emoji:first-child {
|
||||||
|
margin-right: .25rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html.no-touch &:hover {
|
html.no-touch &:hover {
|
||||||
@ -935,7 +939,9 @@ $chat-helper-size: 39px;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.input-message {
|
.input-message {
|
||||||
--padding: .3125rem .5rem;
|
--padding-vertical: .3125rem;
|
||||||
|
--padding-horizontal: .5rem;
|
||||||
|
--padding: var(--padding-vertical) var(--padding-horizontal);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -974,7 +980,8 @@ $chat-helper-size: 39px;
|
|||||||
} */
|
} */
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
@include respond-to(handhelds) {
|
||||||
--padding: .5px .5rem;
|
--padding-vertical: .5px;
|
||||||
|
--padding-horizontal: .5rem;
|
||||||
width: calc(100% - #{$chat-input-handhelds-size + $btn-send-margin});
|
width: calc(100% - #{$chat-input-handhelds-size + $btn-send-margin});
|
||||||
max-width: calc(100% - #{$chat-input-handhelds-size + $btn-send-margin});
|
max-width: calc(100% - #{$chat-input-handhelds-size + $btn-send-margin});
|
||||||
min-height: $chat-input-handhelds-size;
|
min-height: $chat-input-handhelds-size;
|
||||||
@ -985,14 +992,16 @@ $chat-helper-size: 39px;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@include respond-to(esg-bottom) {
|
@include respond-to(esg-bottom) {
|
||||||
--padding: .5px .5rem;
|
--padding-vertical: .5px;
|
||||||
|
--padding-horizontal: .5rem;
|
||||||
min-height: $chat-input-handhelds-size;
|
min-height: $chat-input-handhelds-size;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -.1875rem;
|
//bottom: -.1875rem;
|
||||||
|
bottom: -.1925rem;
|
||||||
right: -8.4px;
|
right: -8.4px;
|
||||||
width: .5625rem;
|
width: .5625rem;
|
||||||
height: 1.25rem;
|
height: 1.25rem;
|
||||||
@ -1044,6 +1053,10 @@ $chat-helper-size: 39px;
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
|
@include respond-to(handhelds) {
|
||||||
|
padding-top: .25rem;
|
||||||
|
}
|
||||||
|
|
||||||
.chat-container.is-helper-active & {
|
.chat-container.is-helper-active & {
|
||||||
border-bottom-left-radius: 0;
|
border-bottom-left-radius: 0;
|
||||||
border-bottom-right-radius: 0;
|
border-bottom-right-radius: 0;
|
||||||
@ -1069,7 +1082,6 @@ $chat-helper-size: 39px;
|
|||||||
//padding: 4.5px 0;
|
//padding: 4.5px 0;
|
||||||
//padding-bottom: 4.5px;
|
//padding-bottom: 4.5px;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.btn-icon:before {
|
.btn-icon:before {
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
@ -1207,6 +1219,10 @@ $chat-helper-size: 39px;
|
|||||||
&.is-chat-input-hidden.is-selecting:not(.backwards) {
|
&.is-chat-input-hidden.is-selecting:not(.backwards) {
|
||||||
--translateY: -79px;
|
--translateY: -79px;
|
||||||
|
|
||||||
|
@include respond-to(handhelds) {
|
||||||
|
--translateY: -58px;
|
||||||
|
}
|
||||||
|
|
||||||
#bubbles-inner {
|
#bubbles-inner {
|
||||||
transform: translateY(calc(var(--translateY) * -1));
|
transform: translateY(calc(var(--translateY) * -1));
|
||||||
//margin-top: $chat-helper-size;
|
//margin-top: $chat-helper-size;
|
||||||
|
@ -707,10 +707,13 @@ $bubble-margin: .25rem;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.reply {
|
.reply {
|
||||||
max-width: 300px;
|
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
&-content {
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-reply {
|
&.is-reply {
|
||||||
@ -1160,9 +1163,13 @@ $bubble-margin: .25rem;
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-right: 5px;
|
//margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
img.emoji {
|
img.emoji {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user