Browse Source

Handle peer title and bio change

master
Eduard Kuzmenko 3 years ago
parent
commit
76a9abc678
  1. 9
      src/components/avatar.ts
  2. 16
      src/components/chat/bubbles.ts
  3. 10
      src/components/chat/topbar.ts
  4. 59
      src/components/peerTitle.ts
  5. 4
      src/components/sidebarLeft/tabs/editProfile.ts
  6. 27
      src/components/sidebarRight/tabs/editGroup.ts
  7. 75
      src/components/sidebarRight/tabs/sharedMedia.ts
  8. 100
      src/lib/appManagers/appChatsManager.ts
  9. 42
      src/lib/appManagers/appDialogsManager.ts
  10. 4
      src/lib/appManagers/appImManager.ts
  11. 31
      src/lib/appManagers/appUsersManager.ts
  12. 8
      src/lib/mtproto/networker.ts
  13. 3
      src/lib/rootScope.ts
  14. 26
      src/scss/partials/_button.scss
  15. 6
      src/scss/partials/_rightSidebar.scss

9
src/components/avatar.ts

@ -7,15 +7,16 @@ import { Photo } from "../layer"; @@ -7,15 +7,16 @@ import { Photo } from "../layer";
import appPeersManager from "../lib/appManagers/appPeersManager";
//import type { LazyLoadQueueIntersector } from "./lazyLoadQueue";
rootScope.on('avatar_update', (e) => {
let peerId = e;
const onAvatarUpdate = (peerId: number) => {
appProfileManager.removeFromAvatarsCache(peerId);
(Array.from(document.querySelectorAll('avatar-element[peer="' + peerId + '"]')) as AvatarElement[]).forEach(elem => {
//console.log('updating avatar:', elem);
elem.update();
});
});
};
rootScope.on('avatar_update', onAvatarUpdate);
rootScope.on('peer_title_edit', onAvatarUpdate);
export default class AvatarElement extends HTMLElement {
private peerId: number;

16
src/components/chat/bubbles.ts

@ -47,6 +47,7 @@ import RepliesElement from "./replies"; @@ -47,6 +47,7 @@ import RepliesElement from "./replies";
import DEBUG from "../../config/debug";
import { SliceEnd } from "../../helpers/slicedArray";
import serverTimeManager from "../../lib/mtproto/serverTimeManager";
import PeerTitle from "../peerTitle";
const USE_MEDIA_TAILS = false;
const IGNORE_ACTIONS = ['messageActionHistoryClear'];
@ -155,7 +156,7 @@ export default class ChatBubbles { @@ -155,7 +156,7 @@ export default class ChatBubbles {
const message = this.chat.getMessage(mid);
if(+bubble.dataset.timestamp >= (message.date - serverTimeManager.serverTimeOffset - 1)) {
if(+bubble.dataset.timestamp >= (message.date + serverTimeManager.serverTimeOffset - 1)) {
return;
}
@ -2353,16 +2354,19 @@ export default class ChatBubbles { @@ -2353,16 +2354,19 @@ export default class ChatBubbles {
const needName = (peerId < 0 && (peerId !== message.fromId || our)) && message.fromId !== rootScope.myId;
if(needName || message.fwd_from || message.reply_to_mid) { // chat
let title = this.appPeersManager.getPeerTitle(message.fwdFromId || message.fromId);
let title: HTMLSpanElement;
const isForwardFromChannel = message.from_id && message.from_id._ === 'peerChannel' && message.fromId === message.fwdFromId;
let isHidden = message.fwd_from && !message.fwd_from.from_id && !message.fwd_from.channel_id;
if(isHidden) {
///////this.log('message to render hidden', message);
title = RichTextProcessor.wrapEmojiText(message.fwd_from.from_name);
title = document.createElement('span');
title.innerHTML = RichTextProcessor.wrapEmojiText(message.fwd_from.from_name);
//title = message.fwd_from.from_name;
bubble.classList.add('hidden-profile');
} else {
title = new PeerTitle({peerId: message.fwdFromId || message.fromId}).element;
}
//this.log(title);
@ -2383,11 +2387,11 @@ export default class ChatBubbles { @@ -2383,11 +2387,11 @@ export default class ChatBubbles {
if(this.peerId === rootScope.myId || this.peerId === REPLIES_PEER_ID || isForwardFromChannel) {
nameDiv.style.color = this.appPeersManager.getPeerColorById(message.fwdFromId, false);
nameDiv.innerHTML = title;
nameDiv.append(title);
} else {
/* const fromTitle = message.fromId === this.myID || appPeersManager.isBroadcast(message.fwdFromId || message.fromId) ? '' : `<div class="name" data-peer-id="${message.fromId}" style="color: ${appPeersManager.getPeerColorByID(message.fromId, false)};">${appPeersManager.getPeerTitle(message.fromId)}</div>`;
nameDiv.innerHTML = fromTitle + 'Forwarded from ' + title; */
nameDiv.innerHTML = 'Forwarded from ' + title;
nameDiv.append('Forwarded from ', title);
if(savedFrom) {
nameDiv.dataset.savedFrom = savedFrom;
@ -2400,7 +2404,7 @@ export default class ChatBubbles { @@ -2400,7 +2404,7 @@ export default class ChatBubbles {
if(!bubble.classList.contains('sticker') && needName) {
let nameDiv = document.createElement('div');
nameDiv.classList.add('name');
nameDiv.innerHTML = title;
nameDiv.append(title);
if(!our) {
nameDiv.style.color = this.appPeersManager.getPeerColorById(message.fromId, false);

10
src/components/chat/topbar.ts

@ -22,7 +22,7 @@ import PopupDeleteDialog from "../popups/deleteDialog"; @@ -22,7 +22,7 @@ import PopupDeleteDialog from "../popups/deleteDialog";
import appNavigationController from "../appNavigationController";
import { LEFT_COLUMN_ACTIVE_CLASSNAME } from "../sidebarLeft";
import AppPrivateSearchTab from "../sidebarRight/tabs/search";
import { SliderSuperTab } from "../slider";
import PeerTitle from "../peerTitle";
export default class ChatTopbar {
container: HTMLDivElement;
@ -482,8 +482,12 @@ export default class ChatTopbar { @@ -482,8 +482,12 @@ export default class ChatTopbar {
});
}
} else if(this.chat.type === 'chat') {
if(this.peerId === rootScope.myId) title = 'Saved Messages';
else title = this.appPeersManager.getPeerTitle(this.peerId);
this.title.innerHTML = '';
this.title.append(new PeerTitle({
peerId: this.peerId,
dialog: true,
}).element);
return;
}
this.title.innerHTML = title;

59
src/components/peerTitle.ts

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
import { MOUNT_CLASS_TO } from "../config/debug";
import appPeersManager from "../lib/appManagers/appPeersManager";
import rootScope from "../lib/rootScope";
export type PeerTitleOptions = {
peerId: number,
plainText?: boolean,
onlyFirstName?: boolean,
dialog?: boolean
};
const weakMap: WeakMap<HTMLElement, PeerTitle> = new WeakMap();
MOUNT_CLASS_TO && (MOUNT_CLASS_TO.peerTitleWeakMap = weakMap);
rootScope.on('peer_title_edit', (peerId) => {
const elements = Array.from(document.querySelectorAll(`.peer-title[data-peer-id="${peerId}"]`)) as HTMLElement[];
elements.forEach(element => {
const peerTitle = weakMap.get(element);
//console.log('in the summer silence i was doing nothing', peerTitle, peerId);
if(peerTitle) {
peerTitle.update();
}
});
});
export default class PeerTitle {
public element: HTMLElement;
public peerId: number;
public plainText = false;
public onlyFirstName = false;
public dialog = false;
constructor(options: PeerTitleOptions) {
this.element = document.createElement('span');
this.element.classList.add('peer-title');
this.update(options);
weakMap.set(this.element, this);
}
public update(options?: PeerTitleOptions) {
if(options) {
for(let i in options) {
// @ts-ignore
this.element.dataset[i] = options[i] ? '' + (typeof(options[i]) === 'boolean' ? +options[i] : options[i]) : '0';
// @ts-ignore
this[i] = options[i];
}
}
if(this.peerId !== rootScope.myId || !this.dialog) {
this.element.innerHTML = appPeersManager.getPeerTitle(this.peerId, this.plainText, this.onlyFirstName);
} else {
this.element.innerHTML = this.onlyFirstName ? 'Saved' : 'Saved Messages';
}
}
}

4
src/components/sidebarLeft/tabs/editProfile.ts

@ -158,14 +158,14 @@ export default class AppEditProfileTab extends SliderSuperTab { @@ -158,14 +158,14 @@ export default class AppEditProfileTab extends SliderSuperTab {
let promises: Promise<any>[] = [];
promises.push(appProfileManager.updateProfile(this.firstNameInputField.value, this.lastNameInputField.value, this.bioInputField.value).then(() => {
this.slider.selectTab(0);
this.close();
}, (err) => {
console.error('updateProfile error:', err);
}));
if(this.editPeer.uploadAvatar) {
promises.push(this.editPeer.uploadAvatar().then(inputFile => {
appProfileManager.uploadProfilePhoto(inputFile);
return appProfileManager.uploadProfilePhoto(inputFile);
}));
}

27
src/components/sidebarRight/tabs/editGroup.ts

@ -7,6 +7,7 @@ import CheckboxField from "../../checkboxField"; @@ -7,6 +7,7 @@ import CheckboxField from "../../checkboxField";
import Button from "../../button";
import appChatsManager from "../../../lib/appManagers/appChatsManager";
import appProfileManager from "../../../lib/appManagers/appProfileManager";
import { attachClickEvent } from "../../../helpers/dom";
export default class AppEditGroupTab extends SliderSuperTab {
private groupNameInputField: InputField;
@ -77,6 +78,32 @@ export default class AppEditGroupTab extends SliderSuperTab { @@ -77,6 +78,32 @@ export default class AppEditGroupTab extends SliderSuperTab {
section.content.append(this.editPeer.avatarEdit.container, inputWrapper, groupTypeRow.container, permissionsRow.container, administratorsRow.container);
this.scrollable.append(section.container);
attachClickEvent(this.editPeer.nextBtn, () => {
this.editPeer.nextBtn.disabled = true;
let promises: Promise<any>[] = [];
const id = -this.peerId;
if(this.groupNameInputField.isValid()) {
promises.push(appChatsManager.editTitle(id, this.groupNameInputField.value));
}
if(this.descriptionInputField.isValid()) {
promises.push(appChatsManager.editAbout(id, this.descriptionInputField.value));
}
if(this.editPeer.uploadAvatar) {
promises.push(this.editPeer.uploadAvatar().then(inputFile => {
return appChatsManager.editPhoto(id, inputFile);
}));
}
Promise.race(promises).finally(() => {
this.editPeer.nextBtn.removeAttribute('disabled');
this.close();
});
}, {listenerSetter: this.listenerSetter});
}
{

75
src/components/sidebarRight/tabs/sharedMedia.ts

@ -11,11 +11,12 @@ import AvatarElement from "../../avatar"; @@ -11,11 +11,12 @@ import AvatarElement from "../../avatar";
import Scrollable from "../../scrollable";
import { SliderTab } from "../../slider";
import CheckboxField from "../../checkboxField";
import { attachClickEvent, cancelEvent } from "../../../helpers/dom";
import { attachClickEvent } from "../../../helpers/dom";
import appSidebarRight from "..";
import { TransitionSlider } from "../../transition";
import appNotificationsManager from "../../../lib/appManagers/appNotificationsManager";
import AppEditGroupTab from "./editGroup";
import PeerTitle from "../../peerTitle";
let setText = (text: string, el: HTMLDivElement) => {
window.requestAnimationFrame(() => {
@ -66,6 +67,8 @@ export default class AppSharedMediaTab implements SliderTab { @@ -66,6 +67,8 @@ export default class AppSharedMediaTab implements SliderTab {
cleaned: boolean;
searchSuper: AppSearchSuper;
private setBioTimeout: number;
public init() {
this.container = document.getElementById('shared-media-container');
this.closeBtn = this.container.querySelector('.sidebar-header .btn-icon');
@ -164,6 +167,12 @@ export default class AppSharedMediaTab implements SliderTab { @@ -164,6 +167,12 @@ export default class AppSharedMediaTab implements SliderTab {
}
});
rootScope.on('peer_bio_edit', (peerId) => {
if(peerId === this.peerId) {
this.setBio(true);
}
});
rootScope.on('user_update', (e) => {
const userId = e;
@ -276,6 +285,10 @@ export default class AppSharedMediaTab implements SliderTab { @@ -276,6 +285,10 @@ export default class AppSharedMediaTab implements SliderTab {
this.profileElements.notificationsCheckbox.checked = true;
this.profileElements.notificationsStatus.innerText = 'Enabled';
this.editBtn.style.display = 'none';
if(this.setBioTimeout) {
window.clearTimeout(this.setBioTimeout);
this.setBioTimeout = 0;
}
this.searchSuper.cleanupHTML();
this.searchSuper.selectTab(0, false);
@ -312,7 +325,6 @@ export default class AppSharedMediaTab implements SliderTab { @@ -312,7 +325,6 @@ export default class AppSharedMediaTab implements SliderTab {
this.cleaned = false;
const peerId = this.peerId;
const threadId = this.threadId;
this.cleanupHTML();
@ -342,11 +354,42 @@ export default class AppSharedMediaTab implements SliderTab { @@ -342,11 +354,42 @@ export default class AppSharedMediaTab implements SliderTab {
if(user.phone && peerId !== rootScope.myId) {
setText(user.rPhone, this.profileElements.phone);
}
appProfileManager.getProfile(peerId).then(userFull => {
}/* else {
//membersLi.style.display = appPeersManager.isBroadcast(peerId) ? 'none' : '';
} */
this.setBio();
this.profileElements.name.innerHTML = '';
this.profileElements.name.append(new PeerTitle({
peerId,
dialog: true
}).element);
this.editBtn.style.display = '';
this.setPeerStatus(true);
}
public setBio(override?: true) {
if(this.setBioTimeout) {
window.clearTimeout(this.setBioTimeout);
this.setBioTimeout = 0;
}
const peerId = this.peerId;
const threadId = this.threadId;
if(!peerId) {
return;
}
let promise: Promise<boolean>;
if(peerId > 0) {
promise = appProfileManager.getProfile(peerId, override).then(userFull => {
if(this.peerId !== peerId || this.threadId !== threadId) {
this.log.warn('peer changed');
return;
return false;
}
if(userFull.rAbout && peerId !== rootScope.myId) {
@ -354,15 +397,13 @@ export default class AppSharedMediaTab implements SliderTab { @@ -354,15 +397,13 @@ export default class AppSharedMediaTab implements SliderTab {
}
//this.log('userFull', userFull);
return true;
});
} else {
//membersLi.style.display = appPeersManager.isBroadcast(peerId) ? 'none' : '';
let chat = appPeersManager.getPeer(peerId);
appProfileManager.getChatFull(chat.id).then((chatFull) => {
promise = appProfileManager.getChatFull(-peerId, override).then((chatFull) => {
if(this.peerId !== peerId || this.threadId !== threadId) {
this.log.warn('peer changed');
return;
return false;
}
//this.log('chatInfo res 2:', chatFull);
@ -370,16 +411,16 @@ export default class AppSharedMediaTab implements SliderTab { @@ -370,16 +411,16 @@ export default class AppSharedMediaTab implements SliderTab {
if(chatFull.about) {
setText(RichTextProcessor.wrapRichText(chatFull.about), this.profileElements.bio);
}
return true;
});
}
let title: string;
if(peerId === rootScope.myId) title = 'Saved Messages';
else title = appPeersManager.getPeerTitle(peerId);
this.profileElements.name.innerHTML = title;
this.editBtn.style.display = '';
this.setPeerStatus(true);
promise.then((canSetNext) => {
if(canSetNext) {
this.setBioTimeout = window.setTimeout(() => this.setBio(true), 60e3);
}
});
}
onOpenAfterTimeout() {

100
src/lib/appManagers/appChatsManager.ts

@ -7,6 +7,7 @@ import { RichTextProcessor } from "../richtextprocessor"; @@ -7,6 +7,7 @@ import { RichTextProcessor } from "../richtextprocessor";
import rootScope from "../rootScope";
import apiUpdatesManager from "./apiUpdatesManager";
import appMessagesManager from "./appMessagesManager";
import appPeersManager from "./appPeersManager";
import appProfileManager from "./appProfileManager";
import appStateManager from "./appStateManager";
import appUsersManager from "./appUsersManager";
@ -137,7 +138,7 @@ export class AppChatsManager { @@ -137,7 +138,7 @@ export class AppChatsManager {
this.usernames[searchUsername] = chat.id;
} */
let changedPhoto = false;
let changedPhoto = false, changedTitle = false;
if(oldChat === undefined) {
this.chats[chat.id] = chat;
} else {
@ -147,6 +148,10 @@ export class AppChatsManager { @@ -147,6 +148,10 @@ export class AppChatsManager {
changedPhoto = true;
}
if(oldChat.title !== chat.title) {
changedTitle = true;
}
safeReplaceObject(oldChat, chat);
rootScope.broadcast('chat_update', chat.id);
}
@ -159,6 +164,10 @@ export class AppChatsManager { @@ -159,6 +164,10 @@ export class AppChatsManager {
if(changedPhoto) {
rootScope.broadcast('avatar_update', -chat.id);
}
if(changedTitle) {
rootScope.broadcast('peer_title_edit', -chat.id);
}
}
public getChat(id: number) {
@ -413,7 +422,10 @@ export class AppChatsManager { @@ -413,7 +422,10 @@ export class AppChatsManager {
}).then((updates: any) => {
apiUpdatesManager.processUpdateMessage(updates);
return updates.chats[0].id;
const channelId = updates.chats[0].id;
rootScope.broadcast('history_focus', -channelId);
return channelId;
});
}
@ -436,33 +448,11 @@ export class AppChatsManager { @@ -436,33 +448,11 @@ export class AppChatsManager {
}).then(updates => {
apiUpdatesManager.processUpdateMessage(updates);
return (updates as any as Updates.updates).chats[0].id;
});
}
public editPhoto(id: number, inputFile: InputFile) {
const isChannel = this.isChannel(id);
const chatId = (updates as any as Updates.updates).chats[0].id;
rootScope.broadcast('history_focus', -chatId);
const inputChatPhoto: InputChatPhoto.inputChatUploadedPhoto = {
_: 'inputChatUploadedPhoto',
file: inputFile
};
if(isChannel) {
return apiManager.invokeApi('channels.editPhoto', {
channel: this.getChannelInput(id),
photo: inputChatPhoto
}).then(updates => {
apiUpdatesManager.processUpdateMessage(updates);
});
} else {
return apiManager.invokeApi('messages.editChatPhoto', {
chat_id: id,
photo: inputChatPhoto
}).then(updates => {
apiUpdatesManager.processUpdateMessage(updates);
});
}
return chatId;
});
}
public async getOnlines(id: number): Promise<number> {
@ -544,6 +534,60 @@ export class AppChatsManager { @@ -544,6 +534,60 @@ export class AppChatsManager {
public leave(id: number) {
return this.isChannel(id) ? this.leaveChannel(id) : this.leaveChat(id);
}
public editPhoto(id: number, inputFile: InputFile) {
const inputChatPhoto: InputChatPhoto = {
_: 'inputChatUploadedPhoto',
file: inputFile
};
let promise: any;
if(this.isChannel(id)) {
promise = apiManager.invokeApi('channels.editPhoto', {
channel: this.getChannelInput(id),
photo: inputChatPhoto
});
} else {
promise = apiManager.invokeApi('messages.editChatPhoto', {
chat_id: id,
photo: inputChatPhoto
});
}
return promise.then((updates: any) => {
apiUpdatesManager.processUpdateMessage(updates);
});
}
public editTitle(id: number, title: string) {
let promise: any;
if(this.isChannel(id)) {
promise = apiManager.invokeApi('channels.editTitle', {
channel: this.getChannelInput(id),
title
});
} else {
promise = apiManager.invokeApi('messages.editChatTitle', {
chat_id: id,
title
});
}
return promise.then((updates: any) => {
apiUpdatesManager.processUpdateMessage(updates);
});
}
public editAbout(id: number, about: string) {
return apiManager.invokeApi('messages.editChatAbout', {
peer: appPeersManager.getInputPeerById(-id),
about
}).then(bool => {
//apiUpdatesManager.processUpdateMessage(updates);
rootScope.broadcast('peer_bio_edit', -id);
});
}
}
const appChatsManager = new AppChatsManager();

42
src/lib/appManagers/appDialogsManager.ts

@ -28,6 +28,7 @@ import App from "../../config/app"; @@ -28,6 +28,7 @@ import App from "../../config/app";
import DEBUG, { MOUNT_CLASS_TO } from "../../config/debug";
import appNotificationsManager from "./appNotificationsManager";
import { InputNotifyPeer } from "../../layer";
import PeerTitle from "../../components/peerTitle";
type DialogDom = {
avatarEl: AvatarElement,
@ -43,8 +44,8 @@ type DialogDom = { @@ -43,8 +44,8 @@ type DialogDom = {
muteAnimationTimeout?: number
};
const testScroll = false;
let testTopSlice = 1;
//const testScroll = false;
//let testTopSlice = 1;
class ConnectionStatusComponent {
public static CHANGE_STATE_DELAY = 1000;
@ -270,7 +271,7 @@ export class AppDialogsManager { @@ -270,7 +271,7 @@ export class AppDialogsManager {
this.setListClickListener(this.chatList, null, true);
if(testScroll) {
/* if(testScroll) {
let i = 0;
let add = () => {
let li = document.createElement('li');
@ -284,7 +285,7 @@ export class AppDialogsManager { @@ -284,7 +285,7 @@ export class AppDialogsManager {
add();
}
(window as any).addElement = add;
}
} */
rootScope.on('user_update', (e) => {
const userId = e;
@ -712,9 +713,9 @@ export class AppDialogsManager { @@ -712,9 +713,9 @@ export class AppDialogsManager {
}
private loadDialogs(side: SliceSides = 'bottom') {
if(testScroll) {
/* if(testScroll) {
return;
}
} */
if(this.loadDialogsPromise/* || 1 === 1 */) return this.loadDialogsPromise;
@ -1081,16 +1082,17 @@ export class AppDialogsManager { @@ -1081,16 +1082,17 @@ export class AppDialogsManager {
if(sender && sender.id) {
const senderBold = document.createElement('b');
let str = '';
if(sender.id === rootScope.myId) {
str = 'You';
senderBold.innerHTML = 'You';
} else {
//str = sender.first_name || sender.last_name || sender.username;
str = appPeersManager.getPeerTitle(lastMessage.fromId, true, true);
senderBold.append(new PeerTitle({
peerId: lastMessage.fromId,
onlyFirstName: true,
}).element);
}
//senderBold.innerText = str + ': ';
senderBold.innerHTML = RichTextProcessor.wrapRichText(str, {noLinebreaks: true, noLinks: true}) + ': ';
senderBold.append(': ');
//console.log(sender, senderBold.innerText);
dom.lastMessageSpan.prepend(senderBold);
} //////// else console.log('no sender', lastMessage, peerId);
@ -1229,8 +1231,6 @@ export class AppDialogsManager { @@ -1229,8 +1231,6 @@ export class AppDialogsManager {
}
}
let title = appPeersManager.getPeerTitle(peerId, false, onlyFirstName);
const avatarEl = new AvatarElement();
avatarEl.setAttribute('dialog', meAsSaved ? '1' : '0');
avatarEl.setAttribute('peer', '' + peerId);
@ -1260,14 +1260,14 @@ export class AppDialogsManager { @@ -1260,14 +1260,14 @@ export class AppDialogsManager {
const titleSpanContainer = document.createElement('span');
titleSpanContainer.classList.add('user-title');
const titleSpan = document.createElement('span');
if(peerId === rootScope.myId && meAsSaved) {
title = onlyFirstName ? 'Saved' : 'Saved Messages';
}
const peerTitle = new PeerTitle({
peerId,
dialog: meAsSaved,
onlyFirstName,
plainText: false
});
titleSpan.innerHTML = title;
titleSpanContainer.append(titleSpan);
titleSpanContainer.append(peerTitle.element);
//p.classList.add('')
// в других случаях иконка верификации не нужна (а первый - это главные чатлисты)
@ -1329,7 +1329,7 @@ export class AppDialogsManager { @@ -1329,7 +1329,7 @@ export class AppDialogsManager {
const dom: DialogDom = {
avatarEl,
captionDiv,
titleSpan,
titleSpan: peerTitle.element,
titleSpanContainer,
statusSpan,
lastTimeSpan,

4
src/lib/appManagers/appImManager.ts

@ -192,6 +192,10 @@ export class AppImManager { @@ -192,6 +192,10 @@ export class AppImManager {
}
});
rootScope.on('history_focus', (peerId) => {
this.setInnerPeer(peerId);
});
/* rootScope.on('peer_changing', (chat) => {
this.saveChatPosition(chat);
});

31
src/lib/appManagers/appUsersManager.ts

@ -40,7 +40,7 @@ export class AppUsersManager { @@ -40,7 +40,7 @@ export class AppUsersManager {
const update = e as Update;
//console.log('on apiUpdate', update);
switch(update._) {
case 'updateUserStatus':
case 'updateUserStatus': {
const userId = update.user_id;
const user = this.users[userId];
if(user) {
@ -58,7 +58,9 @@ export class AppUsersManager { @@ -58,7 +58,9 @@ export class AppUsersManager {
user.sortStatus = this.getUserStatusForSort(user.status);
rootScope.broadcast('user_update', userId);
} //////else console.warn('No user by id:', userId);
break;
}
case 'updateUserPhoto': {
const userId = update.user_id;
@ -84,6 +86,22 @@ export class AppUsersManager { @@ -84,6 +86,22 @@ export class AppUsersManager {
break;
}
case 'updateUserName': {
const userId = update.user_id;
const user = this.users[userId];
if(user) {
this.forceUserOnline(userId);
this.saveApiUser(Object.assign({}, user, {
first_name: update.first_name,
last_name: update.last_name,
username: update.username
}));
}
break;
}
/* case 'updateContactLink':
this.onContactUpdated(update.user_id, update.my_link._ === 'contactLinkContact');
break; */
@ -305,10 +323,17 @@ export class AppUsersManager { @@ -305,10 +323,17 @@ export class AppUsersManager {
user.sortStatus = this.getUserStatusForSort(user.status);
}
let changedTitle = false;
const oldUser = this.users[userId];
if(oldUser === undefined) {
this.users[userId] = user;
} else {
if(user.first_name !== oldUser.first_name
|| user.last_name !== oldUser.last_name
|| user.username !== oldUser.username) {
changedTitle = true;
}
safeReplaceObject(oldUser, user);
}
@ -318,6 +343,10 @@ export class AppUsersManager { @@ -318,6 +343,10 @@ export class AppUsersManager {
safeReplaceObject(this.cachedPhotoLocations[userId], user &&
user.photo ? user.photo : {empty: true});
}
if(changedTitle) {
rootScope.broadcast('peer_title_edit', user.id);
}
}
/* public saveUserAccess(id: number, accessHash: string) {

8
src/lib/mtproto/networker.ts

@ -1249,23 +1249,23 @@ export default class MTPNetworker { @@ -1249,23 +1249,23 @@ export default class MTPNetworker {
const nextReq = Date.now() + (delay || 0);
if(this.nextReq && (delay === undefined || this.nextReq <= nextReq)) {
this.debug && this.log('scheduleRequest: nextReq', this.nextReq, nextReq);
//this.debug && this.log('scheduleRequest: nextReq', this.nextReq, nextReq);
return;
}
this.debug && this.log('scheduleRequest: delay', delay);
//this.debug && this.log('scheduleRequest: delay', delay);
/* if(this.nextReqTimeout) {
return;
} */
const perf = performance.now();
//const perf = performance.now();
if(this.nextReqTimeout) {
clearTimeout(this.nextReqTimeout);
}
const cb = () => {
this.debug && this.log('scheduleRequest: timeout delay was:', performance.now() - perf);
//this.debug && this.log('scheduleRequest: timeout delay was:', performance.now() - perf);
this.nextReqTimeout = 0;
this.nextReq = 0;

3
src/lib/rootScope.ts

@ -21,6 +21,8 @@ export type BroadcastEvents = { @@ -21,6 +21,8 @@ export type BroadcastEvents = {
'peer_pinned_hidden': {peerId: number, maxId: number},
'peer_typings': {peerId: number, typings: UserTyping[]},
'peer_block': {peerId: number, blocked: boolean},
'peer_title_edit': number,
'peer_bio_edit': number,
'filter_delete': MyDialogFilter,
'filter_update': MyDialogFilter,
@ -43,6 +45,7 @@ export type BroadcastEvents = { @@ -43,6 +45,7 @@ export type BroadcastEvents = {
'history_delete': {peerId: number, msgs: {[mid: number]: true}},
'history_forbidden': number,
'history_reload': number,
'history_focus': number,
//'history_request': void,
'message_edit': {storage: MessagesStorage, peerId: number, mid: number},

26
src/scss/partials/_button.scss

@ -1,3 +1,16 @@ @@ -1,3 +1,16 @@
.btn, .btn-icon {
background: none;
outline: none;
border: none;
cursor: pointer;
body.animation-level-0 & {
transition: none;
}
@include btn-hoverable();
}
.btn-icon {
text-align: center;
font-size: 1.5rem;
@ -339,19 +352,6 @@ @@ -339,19 +352,6 @@
}
}
.btn, .btn-icon {
background: none;
outline: none;
border: none;
cursor: pointer;
body.animation-level-0 & {
transition: none;
}
@include btn-hoverable();
}
.btn-color-primary {
background: $color-blue;
color: #fff;

6
src/scss/partials/_rightSidebar.scss

@ -776,11 +776,13 @@ @@ -776,11 +776,13 @@
}
.sidebar-left-section {
padding-bottom: 0;
&:first-child {
padding-top: 0;
}
&:not(:last-child) {
padding-bottom: 0;
}
}
.checkbox-field {

Loading…
Cancel
Save