temp profile commit
improved ESG animation
This commit is contained in:
parent
22b3858864
commit
2a5467e074
@ -1,8 +1,11 @@
|
|||||||
import { EmoticonsDropdown, EmoticonsTab } from "..";
|
import { EmoticonsDropdown, EmoticonsTab } from "..";
|
||||||
|
import findUpClassName from "../../../helpers/dom/findUpClassName";
|
||||||
|
import { fastRaf } from "../../../helpers/schedulers";
|
||||||
import appImManager from "../../../lib/appManagers/appImManager";
|
import appImManager from "../../../lib/appManagers/appImManager";
|
||||||
import appStateManager from "../../../lib/appManagers/appStateManager";
|
import appStateManager from "../../../lib/appManagers/appStateManager";
|
||||||
import Config from "../../../lib/config";
|
import Config from "../../../lib/config";
|
||||||
import { RichTextProcessor } from "../../../lib/richtextprocessor";
|
import { RichTextProcessor } from "../../../lib/richtextprocessor";
|
||||||
|
import rootScope from "../../../lib/rootScope";
|
||||||
import { putPreloader } from "../../misc";
|
import { putPreloader } from "../../misc";
|
||||||
import Scrollable from "../../scrollable";
|
import Scrollable from "../../scrollable";
|
||||||
import StickyIntersector from "../../stickyIntersector";
|
import StickyIntersector from "../../stickyIntersector";
|
||||||
@ -162,7 +165,29 @@ export default class EmojiTab implements EmoticonsTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(spanEmoji.firstElementChild && !RichTextProcessor.emojiSupported) {
|
if(spanEmoji.firstElementChild && !RichTextProcessor.emojiSupported) {
|
||||||
(spanEmoji.firstElementChild as HTMLImageElement).setAttribute('loading', 'lazy');
|
const image = spanEmoji.firstElementChild as HTMLImageElement;
|
||||||
|
image.setAttribute('loading', 'lazy');
|
||||||
|
|
||||||
|
const placeholder = document.createElement('span');
|
||||||
|
placeholder.classList.add('emoji-placeholder');
|
||||||
|
|
||||||
|
if(rootScope.settings.animationsEnabled) {
|
||||||
|
image.style.opacity = '0';
|
||||||
|
placeholder.style.opacity = '1';
|
||||||
|
}
|
||||||
|
|
||||||
|
image.addEventListener('load', () => {
|
||||||
|
fastRaf(() => {
|
||||||
|
if(rootScope.settings.animationsEnabled) {
|
||||||
|
image.style.opacity = '';
|
||||||
|
placeholder.style.opacity = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
spanEmoji.classList.remove('empty');
|
||||||
|
});
|
||||||
|
}, {once: true});
|
||||||
|
|
||||||
|
spanEmoji.append(placeholder);
|
||||||
}
|
}
|
||||||
|
|
||||||
//spanEmoji = spanEmoji.firstElementChild as HTMLSpanElement;
|
//spanEmoji = spanEmoji.firstElementChild as HTMLSpanElement;
|
||||||
@ -185,7 +210,7 @@ export default class EmojiTab implements EmoticonsTab {
|
|||||||
//if(target.tagName !== 'SPAN') return;
|
//if(target.tagName !== 'SPAN') return;
|
||||||
|
|
||||||
if(target.tagName === 'SPAN' && !target.classList.contains('emoji')) {
|
if(target.tagName === 'SPAN' && !target.classList.contains('emoji')) {
|
||||||
target = target.firstChild as HTMLElement;
|
target = findUpClassName(target, 'category-item').firstChild as HTMLElement;
|
||||||
} else if(target.tagName === 'DIV') return;
|
} else if(target.tagName === 'DIV') return;
|
||||||
|
|
||||||
//console.log('contentEmoji div', target);
|
//console.log('contentEmoji div', target);
|
||||||
|
@ -8,10 +8,9 @@ import { RichTextProcessor } from "../../../lib/richtextprocessor";
|
|||||||
import rootScope from "../../../lib/rootScope";
|
import rootScope from "../../../lib/rootScope";
|
||||||
import AppSearchSuper, { SearchSuperType } from "../../appSearchSuper.";
|
import AppSearchSuper, { SearchSuperType } from "../../appSearchSuper.";
|
||||||
import AvatarElement from "../../avatar";
|
import AvatarElement from "../../avatar";
|
||||||
import Scrollable from "../../scrollable";
|
import SidebarSlider, { SliderSuperTab } from "../../slider";
|
||||||
import SidebarSlider, { SliderSuperTab, SliderTab } from "../../slider";
|
|
||||||
import CheckboxField from "../../checkboxField";
|
import CheckboxField from "../../checkboxField";
|
||||||
import { attachClickEvent } from "../../../helpers/dom";
|
import { attachClickEvent, replaceContent } from "../../../helpers/dom";
|
||||||
import appSidebarRight from "..";
|
import appSidebarRight from "..";
|
||||||
import { TransitionSlider } from "../../transition";
|
import { TransitionSlider } from "../../transition";
|
||||||
import appNotificationsManager from "../../../lib/appManagers/appNotificationsManager";
|
import appNotificationsManager from "../../../lib/appManagers/appNotificationsManager";
|
||||||
@ -20,7 +19,7 @@ import PeerTitle from "../../peerTitle";
|
|||||||
import AppEditChannelTab from "./editChannel";
|
import AppEditChannelTab from "./editChannel";
|
||||||
import AppEditContactTab from "./editContact";
|
import AppEditContactTab from "./editContact";
|
||||||
import appChatsManager, { Channel } from "../../../lib/appManagers/appChatsManager";
|
import appChatsManager, { Channel } from "../../../lib/appManagers/appChatsManager";
|
||||||
import { Chat } from "../../../layer";
|
import { Chat, UserProfilePhoto } from "../../../layer";
|
||||||
import Button from "../../button";
|
import Button from "../../button";
|
||||||
import ButtonIcon from "../../buttonIcon";
|
import ButtonIcon from "../../buttonIcon";
|
||||||
import I18n, { i18n } from "../../../lib/langPack";
|
import I18n, { i18n } from "../../../lib/langPack";
|
||||||
@ -28,14 +27,471 @@ import { SettingSection } from "../../sidebarLeft";
|
|||||||
import Row from "../../row";
|
import Row from "../../row";
|
||||||
import { copyTextToClipboard } from "../../../helpers/clipboard";
|
import { copyTextToClipboard } from "../../../helpers/clipboard";
|
||||||
import { toast } from "../../toast";
|
import { toast } from "../../toast";
|
||||||
|
import { fastRaf } from "../../../helpers/schedulers";
|
||||||
|
import { safeAssign } from "../../../helpers/object";
|
||||||
|
import { forEachReverse } from "../../../helpers/array";
|
||||||
|
import appPhotosManager from "../../../lib/appManagers/appPhotosManager";
|
||||||
|
import renderImageFromUrl from "../../../helpers/dom/renderImageFromUrl";
|
||||||
|
|
||||||
let setText = (text: string, row: Row) => {
|
let setText = (text: string, row: Row) => {
|
||||||
window.requestAnimationFrame(() => {
|
fastRaf(() => {
|
||||||
row.title.innerHTML = text;
|
row.title.innerHTML = text;
|
||||||
row.container.style.display = '';
|
row.container.style.display = '';
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type ListLoaderResult<T> = {count: number, items: any[]};
|
||||||
|
class ListLoader<T> {
|
||||||
|
public current: T;
|
||||||
|
public previous: T[] = [];
|
||||||
|
public next: T[] = [];
|
||||||
|
|
||||||
|
public tempId = 0;
|
||||||
|
public loadMore: (anchor: T, older: boolean) => Promise<ListLoaderResult<T>>;
|
||||||
|
public processItem: (item: any) => false | T;
|
||||||
|
public loadCount = 50;
|
||||||
|
public reverse = false; // reverse means next = higher msgid
|
||||||
|
|
||||||
|
public loadedAllUp = false;
|
||||||
|
public loadedAllDown = false;
|
||||||
|
public loadPromiseUp: Promise<void>;
|
||||||
|
public loadPromiseDown: Promise<void>;
|
||||||
|
|
||||||
|
constructor(options: {
|
||||||
|
loadMore: ListLoader<T>['loadMore'],
|
||||||
|
loadCount: ListLoader<T>['loadCount'],
|
||||||
|
processItem?: ListLoader<T>['processItem'],
|
||||||
|
}) {
|
||||||
|
safeAssign(this, options);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public go(length: number) {
|
||||||
|
let items: T[], item: T;
|
||||||
|
if(length > 0) {
|
||||||
|
items = this.next.splice(0, length);
|
||||||
|
item = items.pop();
|
||||||
|
this.previous.push(...items);
|
||||||
|
} else {
|
||||||
|
items = this.previous.splice(this.previous.length - length, length);
|
||||||
|
item = items.shift();
|
||||||
|
this.next.unshift(...items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public load(older: boolean) {
|
||||||
|
if(older && this.loadedAllDown) return Promise.resolve();
|
||||||
|
else if(!older && this.loadedAllUp) return Promise.resolve();
|
||||||
|
|
||||||
|
if(older && this.loadPromiseDown) return this.loadPromiseDown;
|
||||||
|
else if(!older && this.loadPromiseUp) return this.loadPromiseUp;
|
||||||
|
|
||||||
|
/* const loadCount = 50;
|
||||||
|
const backLimit = older ? 0 : loadCount; */
|
||||||
|
|
||||||
|
let anchor: T;
|
||||||
|
if(older) {
|
||||||
|
anchor = this.reverse ? this.previous[0] : this.next[this.next.length - 1];
|
||||||
|
} else {
|
||||||
|
anchor = this.reverse ? this.next[this.next.length - 1] : this.previous[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const promise = this.loadMore(anchor, older).then(result => {
|
||||||
|
if(result.items.length < this.loadCount) {
|
||||||
|
if(older) this.loadedAllDown = true;
|
||||||
|
else this.loadedAllUp = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const method = older ? result.items.forEach.bind(result.items) : forEachReverse.bind(null, result.items);
|
||||||
|
method((item: any) => {
|
||||||
|
const processed = this.processItem ? this.processItem(item) : item;
|
||||||
|
|
||||||
|
if(!processed) return;
|
||||||
|
|
||||||
|
if(older) {
|
||||||
|
if(this.reverse) this.previous.unshift(processed);
|
||||||
|
else this.next.push(processed);
|
||||||
|
} else {
|
||||||
|
if(this.reverse) this.next.push(processed);
|
||||||
|
else this.previous.unshift(processed);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, () => {}).then(() => {
|
||||||
|
if(older) this.loadPromiseDown = null;
|
||||||
|
else this.loadPromiseUp = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if(older) this.loadPromiseDown = promise;
|
||||||
|
else this.loadPromiseUp = promise;
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PeerProfileAvatars {
|
||||||
|
public static BASE_CLASS = 'profile-avatars';
|
||||||
|
public container: HTMLElement;
|
||||||
|
public avatars: HTMLElement;
|
||||||
|
public info: HTMLElement;
|
||||||
|
public listLoader: ListLoader<string>;
|
||||||
|
public peerId: number;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.container = document.createElement('div');
|
||||||
|
this.container.classList.add(PeerProfileAvatars.BASE_CLASS + '-container');
|
||||||
|
|
||||||
|
this.avatars = document.createElement('div');
|
||||||
|
this.avatars.classList.add(PeerProfileAvatars.BASE_CLASS + '-avatars');
|
||||||
|
|
||||||
|
this.info = document.createElement('div');
|
||||||
|
this.info.classList.add(PeerProfileAvatars.BASE_CLASS + '-info');
|
||||||
|
|
||||||
|
this.container.append(this.avatars, this.info);
|
||||||
|
|
||||||
|
attachClickEvent(this.container, (_e) => {
|
||||||
|
const rect = this.container.getBoundingClientRect();
|
||||||
|
|
||||||
|
const e = (_e as TouchEvent).touches ? (_e as TouchEvent).touches[0] : _e as MouseEvent;
|
||||||
|
const x = e.pageX;
|
||||||
|
|
||||||
|
const centerX = rect.right - (rect.width / 2);
|
||||||
|
const toRight = x > centerX;
|
||||||
|
|
||||||
|
const id = this.listLoader.previous.length;
|
||||||
|
const nextId = Math.max(0, id + (toRight ? 1 : -1));
|
||||||
|
this.avatars.style.transform = `translateX(-${100 * nextId}%)`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public setPeer(peerId: number) {
|
||||||
|
this.peerId = peerId;
|
||||||
|
|
||||||
|
const photo = appPeersManager.getPeerPhoto(peerId);
|
||||||
|
if(!photo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadCount = 50;
|
||||||
|
const listLoader: PeerProfileAvatars['listLoader'] = this.listLoader = new ListLoader<string>({
|
||||||
|
loadCount,
|
||||||
|
loadMore: (anchor, older) => {
|
||||||
|
return appPhotosManager.getUserPhotos(peerId, anchor || listLoader.current, loadCount).then(result => {
|
||||||
|
return {
|
||||||
|
count: result.count,
|
||||||
|
items: result.photos
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
processItem: this.processItem
|
||||||
|
});
|
||||||
|
|
||||||
|
listLoader.current = (photo as UserProfilePhoto.userProfilePhoto).photo_id;
|
||||||
|
this.processItem(listLoader.current);
|
||||||
|
|
||||||
|
listLoader.load(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public processItem = (photoId: string) => {
|
||||||
|
const avatar = document.createElement('div');
|
||||||
|
avatar.classList.add(PeerProfileAvatars.BASE_CLASS + '-avatar');
|
||||||
|
|
||||||
|
const photo = appPhotosManager.getPhoto(photoId);
|
||||||
|
if(photo) {
|
||||||
|
appPhotosManager.preloadPhoto(photo, appPhotosManager.choosePhotoSize(photo, 420, 420, false)).then(() => {
|
||||||
|
const img = new Image();
|
||||||
|
renderImageFromUrl(img, photo.url, () => {
|
||||||
|
avatar.append(img);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const photo = appPeersManager.getPeerPhoto(this.peerId);
|
||||||
|
appProfileManager.putAvatar(avatar, this.peerId, photo, 'photo_big');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.avatars.append(avatar);
|
||||||
|
|
||||||
|
return photoId;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class PeerProfile {
|
||||||
|
public element: HTMLElement;
|
||||||
|
private avatars: PeerProfileAvatars;
|
||||||
|
private avatar: AvatarElement;
|
||||||
|
private section: SettingSection;
|
||||||
|
private name: HTMLDivElement;
|
||||||
|
private subtitle: HTMLDivElement;
|
||||||
|
private bio: Row;
|
||||||
|
private username: Row;
|
||||||
|
private phone: Row;
|
||||||
|
private notifications: Row;
|
||||||
|
|
||||||
|
private cleaned: boolean;
|
||||||
|
private setBioTimeout: number;
|
||||||
|
private setPeerStatusInterval: number;
|
||||||
|
|
||||||
|
private peerId = 0;
|
||||||
|
private threadId: number;
|
||||||
|
|
||||||
|
public init() {
|
||||||
|
this.init = null;
|
||||||
|
|
||||||
|
this.element = document.createElement('div');
|
||||||
|
this.element.classList.add('profile-content');
|
||||||
|
|
||||||
|
this.section = new SettingSection({
|
||||||
|
noDelimiter: true
|
||||||
|
});
|
||||||
|
|
||||||
|
this.avatars = new PeerProfileAvatars();
|
||||||
|
|
||||||
|
this.avatar = new AvatarElement();
|
||||||
|
this.avatar.classList.add('profile-avatar', 'avatar-120');
|
||||||
|
this.avatar.setAttribute('dialog', '1');
|
||||||
|
this.avatar.setAttribute('clickable', '');
|
||||||
|
|
||||||
|
this.name = document.createElement('div');
|
||||||
|
this.name.classList.add('profile-name');
|
||||||
|
|
||||||
|
this.subtitle = document.createElement('div');
|
||||||
|
this.subtitle.classList.add('profile-subtitle');
|
||||||
|
|
||||||
|
this.bio = new Row({
|
||||||
|
title: ' ',
|
||||||
|
subtitleLangKey: 'UserBio',
|
||||||
|
icon: 'info',
|
||||||
|
clickable: (e) => {
|
||||||
|
if((e.target as HTMLElement).tagName === 'A') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
appProfileManager.getProfileByPeerId(this.peerId).then(full => {
|
||||||
|
copyTextToClipboard(full.about);
|
||||||
|
toast(I18n.format('BioCopied', true));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.bio.title.classList.add('pre-wrap');
|
||||||
|
|
||||||
|
this.username = new Row({
|
||||||
|
title: ' ',
|
||||||
|
subtitleLangKey: 'Username',
|
||||||
|
icon: 'username',
|
||||||
|
clickable: () => {
|
||||||
|
const peer: Channel | User = appPeersManager.getPeer(this.peerId);
|
||||||
|
copyTextToClipboard('@' + peer.username);
|
||||||
|
toast(I18n.format('UsernameCopied', true));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.phone = new Row({
|
||||||
|
title: ' ',
|
||||||
|
subtitleLangKey: 'Phone',
|
||||||
|
icon: 'phone',
|
||||||
|
clickable: () => {
|
||||||
|
const peer: User = appUsersManager.getUser(this.peerId);
|
||||||
|
copyTextToClipboard('+' + peer.phone);
|
||||||
|
toast(I18n.format('PhoneCopied', true));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.notifications = new Row({
|
||||||
|
checkboxField: new CheckboxField({text: 'Notifications'})
|
||||||
|
});
|
||||||
|
|
||||||
|
this.section.content.append(/* this.name, this.subtitle, */
|
||||||
|
this.phone.container, this.username.container, this.bio.container, this.notifications.container);
|
||||||
|
this.element.append(this.avatars.container, this.section.container);
|
||||||
|
|
||||||
|
this.notifications.checkboxField.input.addEventListener('change', (e) => {
|
||||||
|
if(!e.isTrusted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//let checked = this.notificationsCheckbox.checked;
|
||||||
|
appMessagesManager.mutePeer(this.peerId);
|
||||||
|
});
|
||||||
|
|
||||||
|
rootScope.on('dialog_notify_settings', (dialog) => {
|
||||||
|
if(this.peerId === dialog.peerId) {
|
||||||
|
const muted = appNotificationsManager.isPeerLocalMuted(this.peerId, false);
|
||||||
|
this.notifications.checkboxField.checked = !muted;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
rootScope.on('peer_typings', (e) => {
|
||||||
|
const {peerId} = e;
|
||||||
|
|
||||||
|
if(this.peerId === peerId) {
|
||||||
|
this.setPeerStatus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
rootScope.on('peer_bio_edit', (peerId) => {
|
||||||
|
if(peerId === this.peerId) {
|
||||||
|
this.setBio(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
rootScope.on('user_update', (e) => {
|
||||||
|
const userId = e;
|
||||||
|
|
||||||
|
if(this.peerId === userId) {
|
||||||
|
this.setPeerStatus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setPeerStatusInterval = window.setInterval(this.setPeerStatus, 60e3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setPeerStatus = (needClear = false) => {
|
||||||
|
if(!this.peerId) return;
|
||||||
|
|
||||||
|
const peerId = this.peerId;
|
||||||
|
if(needClear) {
|
||||||
|
this.subtitle.innerHTML = ''; // ! HERE U CAN FIND WHITESPACE
|
||||||
|
}
|
||||||
|
|
||||||
|
appImManager.getPeerStatus(this.peerId).then((subtitle) => {
|
||||||
|
if(peerId !== this.peerId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.subtitle.textContent = '';
|
||||||
|
this.subtitle.append(subtitle || '');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
public cleanupHTML() {
|
||||||
|
this.bio.container.style.display = 'none';
|
||||||
|
this.phone.container.style.display = 'none';
|
||||||
|
this.username.container.style.display = 'none';
|
||||||
|
this.notifications.container.style.display = '';
|
||||||
|
this.notifications.checkboxField.checked = true;
|
||||||
|
if(this.setBioTimeout) {
|
||||||
|
window.clearTimeout(this.setBioTimeout);
|
||||||
|
this.setBioTimeout = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fillProfileElements() {
|
||||||
|
if(!this.cleaned) return;
|
||||||
|
this.cleaned = false;
|
||||||
|
|
||||||
|
const peerId = this.peerId;
|
||||||
|
|
||||||
|
this.cleanupHTML();
|
||||||
|
|
||||||
|
this.avatar.setAttribute('peer', '' + peerId);
|
||||||
|
|
||||||
|
this.avatars.setPeer(peerId);
|
||||||
|
this.avatars.info.append(this.name, this.subtitle);
|
||||||
|
|
||||||
|
// username
|
||||||
|
if(peerId !== rootScope.myId) {
|
||||||
|
let username = appPeersManager.getPeerUsername(peerId);
|
||||||
|
if(username) {
|
||||||
|
setText(appPeersManager.getPeerUsername(peerId), this.username);
|
||||||
|
}
|
||||||
|
|
||||||
|
const muted = appNotificationsManager.isPeerLocalMuted(peerId, false);
|
||||||
|
this.notifications.checkboxField.checked = !muted;
|
||||||
|
} else {
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
this.notifications.container.style.display = 'none';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//let membersLi = this.profileTabs.firstElementChild.children[0] as HTMLLIElement;
|
||||||
|
if(peerId > 0) {
|
||||||
|
//membersLi.style.display = 'none';
|
||||||
|
|
||||||
|
let user = appUsersManager.getUser(peerId);
|
||||||
|
if(user.phone && peerId !== rootScope.myId) {
|
||||||
|
setText(user.rPhone, this.phone);
|
||||||
|
}
|
||||||
|
}/* else {
|
||||||
|
//membersLi.style.display = appPeersManager.isBroadcast(peerId) ? 'none' : '';
|
||||||
|
} */
|
||||||
|
|
||||||
|
this.setBio();
|
||||||
|
|
||||||
|
replaceContent(this.name, new PeerTitle({
|
||||||
|
peerId,
|
||||||
|
dialog: true
|
||||||
|
}).element);
|
||||||
|
|
||||||
|
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 false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(userFull.rAbout && peerId !== rootScope.myId) {
|
||||||
|
setText(userFull.rAbout, this.bio);
|
||||||
|
}
|
||||||
|
|
||||||
|
//this.log('userFull', userFull);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
promise = appProfileManager.getChatFull(-peerId, override).then((chatFull) => {
|
||||||
|
if(this.peerId !== peerId || this.threadId !== threadId) {
|
||||||
|
//this.log.warn('peer changed');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this.log('chatInfo res 2:', chatFull);
|
||||||
|
|
||||||
|
if(chatFull.about) {
|
||||||
|
setText(RichTextProcessor.wrapRichText(chatFull.about), this.bio);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
promise.then((canSetNext) => {
|
||||||
|
if(canSetNext) {
|
||||||
|
this.setBioTimeout = window.setTimeout(() => this.setBio(true), 60e3);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public setPeer(peerId: number, threadId = 0) {
|
||||||
|
if(this.peerId === peerId && this.threadId === peerId) return;
|
||||||
|
|
||||||
|
if(this.init) {
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.peerId = peerId;
|
||||||
|
this.threadId = threadId;
|
||||||
|
|
||||||
|
this.cleaned = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: отредактированное сообщение не изменится
|
// TODO: отредактированное сообщение не изменится
|
||||||
export default class AppSharedMediaTab extends SliderSuperTab {
|
export default class AppSharedMediaTab extends SliderSuperTab {
|
||||||
public editBtn: HTMLElement;
|
public editBtn: HTMLElement;
|
||||||
@ -43,17 +499,6 @@ export default class AppSharedMediaTab extends SliderSuperTab {
|
|||||||
private peerId = 0;
|
private peerId = 0;
|
||||||
private threadId = 0;
|
private threadId = 0;
|
||||||
|
|
||||||
public profileContentEl: HTMLDivElement;
|
|
||||||
public profileElements: {
|
|
||||||
avatar: AvatarElement,
|
|
||||||
name: HTMLDivElement,
|
|
||||||
subtitle: HTMLDivElement,
|
|
||||||
bio: Row,
|
|
||||||
username: Row,
|
|
||||||
phone: Row,
|
|
||||||
notifications: Row
|
|
||||||
} = {} as any;
|
|
||||||
|
|
||||||
public historiesStorage: {
|
public historiesStorage: {
|
||||||
[peerId: number]: Partial<{
|
[peerId: number]: Partial<{
|
||||||
[type in SearchSuperType]: {mid: number, peerId: number}[]
|
[type in SearchSuperType]: {mid: number, peerId: number}[]
|
||||||
@ -61,11 +506,10 @@ export default class AppSharedMediaTab extends SliderSuperTab {
|
|||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
private log = logger('SM'/* , LogLevels.error */);
|
private log = logger('SM'/* , LogLevels.error */);
|
||||||
setPeerStatusInterval: number;
|
private cleaned: boolean;
|
||||||
cleaned: boolean;
|
private searchSuper: AppSearchSuper;
|
||||||
searchSuper: AppSearchSuper;
|
|
||||||
|
|
||||||
private setBioTimeout: number;
|
public profile: PeerProfile;
|
||||||
|
|
||||||
constructor(slider: SidebarSlider) {
|
constructor(slider: SidebarSlider) {
|
||||||
super(slider, false);
|
super(slider, false);
|
||||||
@ -90,7 +534,7 @@ export default class AppSharedMediaTab extends SliderSuperTab {
|
|||||||
const transitionFirstItem = document.createElement('div');
|
const transitionFirstItem = document.createElement('div');
|
||||||
transitionFirstItem.classList.add('transition-item');
|
transitionFirstItem.classList.add('transition-item');
|
||||||
|
|
||||||
this.title.append(i18n('Telegram.PeerInfoController'));
|
this.title.append(i18n('Profile'));
|
||||||
this.editBtn = ButtonIcon('edit');
|
this.editBtn = ButtonIcon('edit');
|
||||||
//const moreBtn = ButtonIcon('more');
|
//const moreBtn = ButtonIcon('more');
|
||||||
|
|
||||||
@ -110,72 +554,10 @@ export default class AppSharedMediaTab extends SliderSuperTab {
|
|||||||
|
|
||||||
// * body
|
// * body
|
||||||
|
|
||||||
this.profileContentEl = document.createElement('div');
|
this.profile = new PeerProfile();
|
||||||
this.profileContentEl.classList.add('profile-content');
|
this.profile.init();
|
||||||
|
|
||||||
const section = new SettingSection({
|
this.scrollable.append(this.profile.element);
|
||||||
noDelimiter: true
|
|
||||||
});
|
|
||||||
|
|
||||||
this.profileElements.avatar = new AvatarElement();
|
|
||||||
this.profileElements.avatar.classList.add('profile-avatar', 'avatar-120');
|
|
||||||
this.profileElements.avatar.setAttribute('dialog', '1');
|
|
||||||
this.profileElements.avatar.setAttribute('clickable', '');
|
|
||||||
|
|
||||||
this.profileElements.name = document.createElement('div');
|
|
||||||
this.profileElements.name.classList.add('profile-name');
|
|
||||||
|
|
||||||
this.profileElements.subtitle = document.createElement('div');
|
|
||||||
this.profileElements.subtitle.classList.add('profile-subtitle');
|
|
||||||
|
|
||||||
this.profileElements.bio = new Row({
|
|
||||||
title: ' ',
|
|
||||||
subtitleLangKey: 'UserBio',
|
|
||||||
icon: 'info',
|
|
||||||
clickable: (e) => {
|
|
||||||
if((e.target as HTMLElement).tagName === 'A') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
appProfileManager.getProfileByPeerId(this.peerId).then(full => {
|
|
||||||
copyTextToClipboard(full.about);
|
|
||||||
toast(I18n.format('BioCopied', true));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.profileElements.bio.title.classList.add('pre-wrap');
|
|
||||||
|
|
||||||
this.profileElements.username = new Row({
|
|
||||||
title: ' ',
|
|
||||||
subtitleLangKey: 'Username',
|
|
||||||
icon: 'username',
|
|
||||||
clickable: () => {
|
|
||||||
const peer: Channel | User = appPeersManager.getPeer(this.peerId);
|
|
||||||
copyTextToClipboard('@' + peer.username);
|
|
||||||
toast(I18n.format('UsernameCopied', true));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.profileElements.phone = new Row({
|
|
||||||
title: ' ',
|
|
||||||
subtitleLangKey: 'Phone',
|
|
||||||
icon: 'phone',
|
|
||||||
clickable: () => {
|
|
||||||
const peer: User = appUsersManager.getUser(this.peerId);
|
|
||||||
copyTextToClipboard('+' + peer.phone);
|
|
||||||
toast(I18n.format('PhoneCopied', true));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.profileElements.notifications = new Row({
|
|
||||||
checkboxField: new CheckboxField({text: 'Notifications'})
|
|
||||||
});
|
|
||||||
|
|
||||||
section.content.append(this.profileElements.avatar, this.profileElements.name, this.profileElements.subtitle,
|
|
||||||
this.profileElements.bio.container, this.profileElements.username.container, this.profileElements.phone.container, this.profileElements.notifications.container);
|
|
||||||
this.profileContentEl.append(section.container);
|
|
||||||
this.scrollable.append(this.profileContentEl);
|
|
||||||
|
|
||||||
const HEADER_HEIGHT = 56;
|
const HEADER_HEIGHT = 56;
|
||||||
this.scrollable.onAdditionalScroll = () => {
|
this.scrollable.onAdditionalScroll = () => {
|
||||||
@ -229,46 +611,6 @@ export default class AppSharedMediaTab extends SliderSuperTab {
|
|||||||
|
|
||||||
//this.container.prepend(this.closeBtn.parentElement);
|
//this.container.prepend(this.closeBtn.parentElement);
|
||||||
|
|
||||||
this.profileElements.notifications.checkboxField.input.addEventListener('change', (e) => {
|
|
||||||
if(!e.isTrusted) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//let checked = this.profileElements.notificationsCheckbox.checked;
|
|
||||||
appMessagesManager.mutePeer(this.peerId);
|
|
||||||
});
|
|
||||||
|
|
||||||
rootScope.on('dialog_notify_settings', (dialog) => {
|
|
||||||
if(this.peerId === dialog.peerId) {
|
|
||||||
const muted = appNotificationsManager.isPeerLocalMuted(this.peerId, false);
|
|
||||||
this.profileElements.notifications.checkboxField.checked = !muted;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
rootScope.on('peer_typings', (e) => {
|
|
||||||
const {peerId} = e;
|
|
||||||
|
|
||||||
if(this.peerId === peerId) {
|
|
||||||
this.setPeerStatus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
rootScope.on('peer_bio_edit', (peerId) => {
|
|
||||||
if(peerId === this.peerId) {
|
|
||||||
this.setBio(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
rootScope.on('user_update', (e) => {
|
|
||||||
const userId = e;
|
|
||||||
|
|
||||||
if(this.peerId === userId) {
|
|
||||||
this.setPeerStatus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.setPeerStatusInterval = window.setInterval(this.setPeerStatus, 60e3);
|
|
||||||
|
|
||||||
this.searchSuper = new AppSearchSuper([{
|
this.searchSuper = new AppSearchSuper([{
|
||||||
inputFilter: 'inputMessagesFilterPhotoVideo',
|
inputFilter: 'inputMessagesFilterPhotoVideo',
|
||||||
name: 'SharedMediaTab2',
|
name: 'SharedMediaTab2',
|
||||||
@ -287,27 +629,9 @@ export default class AppSharedMediaTab extends SliderSuperTab {
|
|||||||
type: 'music'
|
type: 'music'
|
||||||
}], this.scrollable/* , undefined, undefined, false */);
|
}], this.scrollable/* , undefined, undefined, false */);
|
||||||
|
|
||||||
this.profileContentEl.append(this.searchSuper.container);
|
this.profile.element.append(this.searchSuper.container);
|
||||||
}
|
}
|
||||||
|
|
||||||
public setPeerStatus = (needClear = false) => {
|
|
||||||
if(!this.peerId) return;
|
|
||||||
|
|
||||||
const peerId = this.peerId;
|
|
||||||
if(needClear) {
|
|
||||||
this.profileElements.subtitle.innerHTML = ''; // ! HERE U CAN FIND WHITESPACE
|
|
||||||
}
|
|
||||||
|
|
||||||
appImManager.getPeerStatus(this.peerId).then((subtitle) => {
|
|
||||||
if(peerId !== this.peerId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.profileElements.subtitle.textContent = '';
|
|
||||||
this.profileElements.subtitle.append(subtitle || '');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
public renderNewMessages(peerId: number, mids: number[]) {
|
public renderNewMessages(peerId: number, mids: number[]) {
|
||||||
if(this.init) return; // * not inited yet
|
if(this.init) return; // * not inited yet
|
||||||
|
|
||||||
@ -369,17 +693,9 @@ export default class AppSharedMediaTab extends SliderSuperTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public cleanupHTML() {
|
public cleanupHTML() {
|
||||||
this.profileElements.bio.container.style.display = 'none';
|
this.profile.cleanupHTML();
|
||||||
this.profileElements.phone.container.style.display = 'none';
|
|
||||||
this.profileElements.username.container.style.display = 'none';
|
|
||||||
this.profileElements.notifications.container.style.display = '';
|
|
||||||
this.profileElements.notifications.checkboxField.checked = true;
|
|
||||||
this.editBtn.style.display = 'none';
|
|
||||||
if(this.setBioTimeout) {
|
|
||||||
window.clearTimeout(this.setBioTimeout);
|
|
||||||
this.setBioTimeout = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
this.editBtn.style.display = 'none';
|
||||||
this.searchSuper.cleanupHTML();
|
this.searchSuper.cleanupHTML();
|
||||||
this.searchSuper.selectTab(0, false);
|
this.searchSuper.selectTab(0, false);
|
||||||
}
|
}
|
||||||
@ -403,124 +719,30 @@ export default class AppSharedMediaTab extends SliderSuperTab {
|
|||||||
//threadId,
|
//threadId,
|
||||||
historyStorage: this.historiesStorage[peerId] ?? (this.historiesStorage[peerId] = {})
|
historyStorage: this.historiesStorage[peerId] ?? (this.historiesStorage[peerId] = {})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.profile.setPeer(peerId, threadId);
|
||||||
this.cleaned = true;
|
this.cleaned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fillProfileElements() {
|
||||||
|
this.profile.fillProfileElements();
|
||||||
|
|
||||||
|
if(this.peerId > 0) {
|
||||||
|
if(this.peerId !== rootScope.myId && appUsersManager.isContact(this.peerId)) {
|
||||||
|
this.editBtn.style.display = '';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const chat: Chat = appChatsManager.getChat(-this.peerId);
|
||||||
|
if(chat._ === 'chat' || (chat as Chat.channel).admin_rights) {
|
||||||
|
this.editBtn.style.display = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public loadSidebarMedia(single: boolean) {
|
public loadSidebarMedia(single: boolean) {
|
||||||
this.searchSuper.load(single);
|
this.searchSuper.load(single);
|
||||||
}
|
}
|
||||||
|
|
||||||
public fillProfileElements() {
|
|
||||||
if(!this.cleaned) return;
|
|
||||||
this.cleaned = false;
|
|
||||||
|
|
||||||
const peerId = this.peerId;
|
|
||||||
|
|
||||||
this.cleanupHTML();
|
|
||||||
|
|
||||||
this.profileElements.avatar.setAttribute('peer', '' + peerId);
|
|
||||||
|
|
||||||
// username
|
|
||||||
if(peerId !== rootScope.myId) {
|
|
||||||
let username = appPeersManager.getPeerUsername(peerId);
|
|
||||||
if(username) {
|
|
||||||
setText(appPeersManager.getPeerUsername(peerId), this.profileElements.username);
|
|
||||||
}
|
|
||||||
|
|
||||||
const muted = appNotificationsManager.isPeerLocalMuted(peerId, false);
|
|
||||||
this.profileElements.notifications.checkboxField.checked = !muted;
|
|
||||||
} else {
|
|
||||||
window.requestAnimationFrame(() => {
|
|
||||||
this.profileElements.notifications.container.style.display = 'none';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//let membersLi = this.profileTabs.firstElementChild.children[0] as HTMLLIElement;
|
|
||||||
if(peerId > 0) {
|
|
||||||
//membersLi.style.display = 'none';
|
|
||||||
|
|
||||||
let user = appUsersManager.getUser(peerId);
|
|
||||||
if(user.phone && peerId !== rootScope.myId) {
|
|
||||||
setText(user.rPhone, this.profileElements.phone);
|
|
||||||
}
|
|
||||||
}/* else {
|
|
||||||
//membersLi.style.display = appPeersManager.isBroadcast(peerId) ? 'none' : '';
|
|
||||||
} */
|
|
||||||
|
|
||||||
this.setBio();
|
|
||||||
|
|
||||||
this.profileElements.name.innerHTML = '';
|
|
||||||
this.profileElements.name.append(new PeerTitle({
|
|
||||||
peerId,
|
|
||||||
dialog: true
|
|
||||||
}).element);
|
|
||||||
|
|
||||||
if(peerId > 0) {
|
|
||||||
if(peerId !== rootScope.myId && appUsersManager.isContact(peerId)) {
|
|
||||||
this.editBtn.style.display = '';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const chat: Chat = appChatsManager.getChat(-peerId);
|
|
||||||
if(chat._ === 'chat' || (chat as Chat.channel).admin_rights) {
|
|
||||||
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 false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(userFull.rAbout && peerId !== rootScope.myId) {
|
|
||||||
setText(userFull.rAbout, this.profileElements.bio);
|
|
||||||
}
|
|
||||||
|
|
||||||
//this.log('userFull', userFull);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
promise = appProfileManager.getChatFull(-peerId, override).then((chatFull) => {
|
|
||||||
if(this.peerId !== peerId || this.threadId !== threadId) {
|
|
||||||
this.log.warn('peer changed');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//this.log('chatInfo res 2:', chatFull);
|
|
||||||
|
|
||||||
if(chatFull.about) {
|
|
||||||
setText(RichTextProcessor.wrapRichText(chatFull.about), this.profileElements.bio);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
promise.then((canSetNext) => {
|
|
||||||
if(canSetNext) {
|
|
||||||
this.setBioTimeout = window.setTimeout(() => this.setBio(true), 60e3);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onOpenAfterTimeout() {
|
onOpenAfterTimeout() {
|
||||||
this.scrollable.onScroll();
|
this.scrollable.onScroll();
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,7 @@ const lang = {
|
|||||||
"TwoStepAuth.EmailCodeChangeEmail": "Change Email",
|
"TwoStepAuth.EmailCodeChangeEmail": "Change Email",
|
||||||
"MarkupTooltip.LinkPlaceholder": "Enter URL...",
|
"MarkupTooltip.LinkPlaceholder": "Enter URL...",
|
||||||
"MediaViewer.Context.Download": "Download",
|
"MediaViewer.Context.Download": "Download",
|
||||||
|
"Profile": "Profile",
|
||||||
|
|
||||||
// * android
|
// * android
|
||||||
"ActionCreateChannel": "Channel created",
|
"ActionCreateChannel": "Channel created",
|
||||||
@ -484,7 +485,6 @@ const lang = {
|
|||||||
"Telegram.GeneralSettingsViewController": "General Settings",
|
"Telegram.GeneralSettingsViewController": "General Settings",
|
||||||
"Telegram.InstalledStickerPacksController": "Stickers",
|
"Telegram.InstalledStickerPacksController": "Stickers",
|
||||||
"Telegram.NotificationSettingsViewController": "Notifications",
|
"Telegram.NotificationSettingsViewController": "Notifications",
|
||||||
"Telegram.PeerInfoController": "Info",
|
|
||||||
"Telegram.LanguageViewController": "Language",
|
"Telegram.LanguageViewController": "Language",
|
||||||
"Stickers.SearchAdd": "Add",
|
"Stickers.SearchAdd": "Add",
|
||||||
"Stickers.SearchAdded": "Added",
|
"Stickers.SearchAdded": "Added",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { MOUNT_CLASS_TO } from "../../config/debug";
|
import { MOUNT_CLASS_TO } from "../../config/debug";
|
||||||
import { numberThousandSplitter } from "../../helpers/number";
|
import { numberThousandSplitter } from "../../helpers/number";
|
||||||
import { isObject, safeReplaceObject, copy, deepEqual } from "../../helpers/object";
|
import { isObject, safeReplaceObject, copy, deepEqual } from "../../helpers/object";
|
||||||
import { ChannelParticipant, Chat, ChatAdminRights, ChatBannedRights, ChatFull, ChatParticipant, ChatParticipants, InputChannel, InputChatPhoto, InputFile, InputPeer, SendMessageAction, Update, Updates } from "../../layer";
|
import { ChannelParticipant, Chat, ChatAdminRights, ChatBannedRights, ChatFull, ChatParticipant, ChatParticipants, ChatPhoto, InputChannel, InputChatPhoto, InputFile, InputPeer, SendMessageAction, Update, Updates } from "../../layer";
|
||||||
import { i18n, LangPackKey } from "../langPack";
|
import { i18n, LangPackKey } from "../langPack";
|
||||||
import apiManagerProxy from "../mtproto/mtprotoworker";
|
import apiManagerProxy from "../mtproto/mtprotoworker";
|
||||||
import apiManager from '../mtproto/mtprotoworker';
|
import apiManager from '../mtproto/mtprotoworker';
|
||||||
@ -25,7 +25,7 @@ export class AppChatsManager {
|
|||||||
//public usernames: any = {};
|
//public usernames: any = {};
|
||||||
//public channelAccess: any = {};
|
//public channelAccess: any = {};
|
||||||
//public megagroups: {[id: number]: true} = {};
|
//public megagroups: {[id: number]: true} = {};
|
||||||
public cachedPhotoLocations: {[id: number]: any} = {};
|
public cachedPhotoLocations: {[id: number]: ChatPhoto} = {};
|
||||||
|
|
||||||
public megagroupOnlines: {[id: number]: {timestamp: number, onlines: number}} = {};
|
public megagroupOnlines: {[id: number]: {timestamp: number, onlines: number}} = {};
|
||||||
|
|
||||||
@ -371,10 +371,12 @@ export class AppChatsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getChatPhoto(id: number) {
|
public getChatPhoto(id: number) {
|
||||||
const chat = this.getChat(id);
|
const chat: Chat.chat = this.getChat(id);
|
||||||
|
|
||||||
if(this.cachedPhotoLocations[id] === undefined) {
|
if(this.cachedPhotoLocations[id] === undefined) {
|
||||||
this.cachedPhotoLocations[id] = chat && chat.photo ? chat.photo : {empty: true};
|
this.cachedPhotoLocations[id] = chat && chat.photo || {
|
||||||
|
_: 'chatPhotoEmpty'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.cachedPhotoLocations[id];
|
return this.cachedPhotoLocations[id];
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { MOUNT_CLASS_TO } from "../../config/debug";
|
import { MOUNT_CLASS_TO } from "../../config/debug";
|
||||||
import { isObject } from "../../helpers/object";
|
import { isObject } from "../../helpers/object";
|
||||||
import { DialogPeer, InputDialogPeer, InputNotifyPeer, InputPeer, Peer, Update } from "../../layer";
|
import { ChatPhoto, DialogPeer, InputDialogPeer, InputNotifyPeer, InputPeer, Peer, Update, UserProfilePhoto } from "../../layer";
|
||||||
import { LangPackKey } from "../langPack";
|
import { LangPackKey } from "../langPack";
|
||||||
import { RichTextProcessor } from "../richtextprocessor";
|
import { RichTextProcessor } from "../richtextprocessor";
|
||||||
import rootScope from "../rootScope";
|
import rootScope from "../rootScope";
|
||||||
@ -46,10 +46,12 @@ export class AppPeersManager {
|
|||||||
return peerId > 0 || appChatsManager.hasRights(-peerId, 'pin_messages');
|
return peerId > 0 || appChatsManager.hasRights(-peerId, 'pin_messages');
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPeerPhoto(peerId: number) {
|
public getPeerPhoto(peerId: number): UserProfilePhoto.userProfilePhoto | ChatPhoto.chatPhoto {
|
||||||
return peerId > 0
|
const photo = peerId > 0
|
||||||
? appUsersManager.getUserPhoto(peerId)
|
? appUsersManager.getUserPhoto(peerId)
|
||||||
: appChatsManager.getChatPhoto(-peerId);
|
: appChatsManager.getChatPhoto(-peerId);
|
||||||
|
|
||||||
|
return photo._ !== 'chatPhotoEmpty' && photo._ !== 'userProfilePhotoEmpty' ? photo : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPeerMigratedTo(peerId: number) {
|
public getPeerMigratedTo(peerId: number) {
|
||||||
|
@ -129,10 +129,9 @@ export class AppPhotosManager {
|
|||||||
max_id: maxId
|
max_id: maxId
|
||||||
}).then((photosResult) => {
|
}).then((photosResult) => {
|
||||||
appUsersManager.saveApiUsers(photosResult.users);
|
appUsersManager.saveApiUsers(photosResult.users);
|
||||||
const photoIds: string[] = [];
|
const photoIds: string[] = photosResult.photos.map((photo, idx) => {
|
||||||
photosResult.photos.forEach((photo, idx) => {
|
|
||||||
photosResult.photos[idx] = this.savePhoto(photo, {type: 'profilePhoto', peerId: userId});
|
photosResult.photos[idx] = this.savePhoto(photo, {type: 'profilePhoto', peerId: userId});
|
||||||
photoIds.push(photo.id);
|
return photo.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -2,7 +2,7 @@ import { formatPhoneNumber } from "../../components/misc";
|
|||||||
import { MOUNT_CLASS_TO } from "../../config/debug";
|
import { MOUNT_CLASS_TO } from "../../config/debug";
|
||||||
import { tsNow } from "../../helpers/date";
|
import { tsNow } from "../../helpers/date";
|
||||||
import { safeReplaceObject, isObject } from "../../helpers/object";
|
import { safeReplaceObject, isObject } from "../../helpers/object";
|
||||||
import { InputUser, Update, User as MTUser, UserStatus } from "../../layer";
|
import { InputUser, Update, User as MTUser, UserProfilePhoto, UserStatus } from "../../layer";
|
||||||
import I18n, { i18n, LangPackKey } from "../langPack";
|
import I18n, { i18n, LangPackKey } from "../langPack";
|
||||||
//import apiManager from '../mtproto/apiManager';
|
//import apiManager from '../mtproto/apiManager';
|
||||||
import apiManager from '../mtproto/mtprotoworker';
|
import apiManager from '../mtproto/mtprotoworker';
|
||||||
@ -24,7 +24,7 @@ export class AppUsersManager {
|
|||||||
private users: {[userId: number]: User} = {};
|
private users: {[userId: number]: User} = {};
|
||||||
private usernames: {[username: string]: number} = {};
|
private usernames: {[username: string]: number} = {};
|
||||||
//public userAccess: {[userId: number]: string} = {};
|
//public userAccess: {[userId: number]: string} = {};
|
||||||
private cachedPhotoLocations: any = {};
|
private cachedPhotoLocations: {[userId: number]: UserProfilePhoto} = {};
|
||||||
private contactsIndex = searchIndexManager.createIndex();
|
private contactsIndex = searchIndexManager.createIndex();
|
||||||
private contactsFillPromise: Promise<Set<number>>;
|
private contactsFillPromise: Promise<Set<number>>;
|
||||||
public contactsList: Set<number> = new Set();
|
public contactsList: Set<number> = new Set();
|
||||||
@ -501,10 +501,12 @@ export class AppUsersManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getUserPhoto(id: number) {
|
public getUserPhoto(id: number) {
|
||||||
var user = this.getUser(id);
|
const user = this.getUser(id);
|
||||||
|
|
||||||
if(this.cachedPhotoLocations[id] === undefined) {
|
if(this.cachedPhotoLocations[id] === undefined) {
|
||||||
this.cachedPhotoLocations[id] = user && user.photo ? user.photo : {empty: true};
|
this.cachedPhotoLocations[id] = user && user.photo || {
|
||||||
|
_: 'userProfilePhotoEmpty'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.cachedPhotoLocations[id];
|
return this.cachedPhotoLocations[id];
|
||||||
|
@ -1041,7 +1041,7 @@ $chat-helper-size: 39px;
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
//--translateY: 0;
|
//--translateY: 0;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
//transition: opacity var(--layer-transition), visibility 0s 0s !important;
|
transition: opacity var(--layer-transition), visibility 0s 0s !important;
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
|
|
||||||
/* &.is-broadcast {
|
/* &.is-broadcast {
|
||||||
@ -1164,8 +1164,8 @@ $chat-helper-size: 39px;
|
|||||||
overflow: visible;
|
overflow: visible;
|
||||||
//--translateY: calc(var(--chat-input-size) + 10px);
|
//--translateY: calc(var(--chat-input-size) + 10px);
|
||||||
//--translateY: calc(100% + 10px);
|
//--translateY: calc(100% + 10px);
|
||||||
//transition: opacity var(--layer-transition), visibility 0s .2s !important;
|
transition: opacity var(--layer-transition), visibility 0s .2s !important;
|
||||||
transition: opacity var(--layer-transition);
|
//transition: opacity var(--layer-transition);
|
||||||
transform: none !important;
|
transform: none !important;
|
||||||
|
|
||||||
body.animation-level-0 & {
|
body.animation-level-0 & {
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.drop {
|
.drop {
|
||||||
background-color: #fff;
|
background-color: var(--surface-color);
|
||||||
position: relative;
|
position: relative;
|
||||||
//height: 100%;
|
//height: 100%;
|
||||||
border-radius: $border-radius-big;
|
border-radius: $border-radius-big;
|
||||||
|
@ -19,12 +19,14 @@
|
|||||||
box-shadow: 0px 5px 10px 5px rgba(16, 35, 47, .14);
|
box-shadow: 0px 5px 10px 5px rgba(16, 35, 47, .14);
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
transition: transform .2s ease-out;
|
transition: transform .2s, opacity .2s;
|
||||||
|
transition-timing-function: cubic-bezier(.4, 0, .2, 1);
|
||||||
transform: scale(0);
|
transform: scale(0);
|
||||||
|
opacity: 0;
|
||||||
transform-origin: 0 100%;
|
transform-origin: 0 100%;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
transition: transform .2s ease-in;
|
opacity: 1;
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,6 +185,32 @@
|
|||||||
width: 42px;
|
width: 42px;
|
||||||
height: 42px;
|
height: 42px;
|
||||||
|
|
||||||
|
html:not(.emoji-supported) & {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-placeholder {
|
||||||
|
position: absolute;
|
||||||
|
left: 7px;
|
||||||
|
top: 7px;
|
||||||
|
width: 1.75rem;
|
||||||
|
height: 1.75rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: var(--light-secondary-text-color);
|
||||||
|
|
||||||
|
@include animation-level(2) {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity .2s ease-in-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include animation-level(2) {
|
||||||
|
img {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity .2s ease-in-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.emoji {
|
.emoji {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
155
src/scss/partials/_profile.scss
Normal file
155
src/scss/partials/_profile.scss
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
.profile {
|
||||||
|
&-avatars {
|
||||||
|
&-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 26.25rem;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
/* &:before, &:after {
|
||||||
|
position: absolute;
|
||||||
|
content: " ";
|
||||||
|
height: 100%;
|
||||||
|
width:
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
|
||||||
|
&-avatars {
|
||||||
|
width: inherit;
|
||||||
|
height: inherit;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&-avatar {
|
||||||
|
width: inherit;
|
||||||
|
height: inherit;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
/* img, video {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
|
||||||
|
&-info {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
left: 1.5rem;
|
||||||
|
bottom: .5625rem;
|
||||||
|
|
||||||
|
.profile-name, .profile-subtitle {
|
||||||
|
color: #fff;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-name {
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-subtitle {
|
||||||
|
opacity: .7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-content {
|
||||||
|
/* flex: 1 1 auto; */
|
||||||
|
flex: 0 0 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
/* height: 100%; */
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.checkbox-field {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin-left: -54px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-caption {
|
||||||
|
padding-left: 54px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-wrapper {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding-bottom: 13px;
|
||||||
|
|
||||||
|
@include respond-to(not-handhelds) {
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-left-section {
|
||||||
|
//padding-top: .5625rem;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-container {
|
||||||
|
> .scrollable {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
//transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-name {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 1.3125;
|
||||||
|
font-weight: 500;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
word-break: break-word;
|
||||||
|
max-width: 340px;
|
||||||
|
margin: 0 auto;
|
||||||
|
color: var(--primary-text-color);
|
||||||
|
|
||||||
|
span.emoji {
|
||||||
|
vertical-align: inherit;
|
||||||
|
min-width: min-content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-subtitle {
|
||||||
|
text-align: center;
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: .875rem;
|
||||||
|
margin-top: 1px;
|
||||||
|
|
||||||
|
@include respond-to(handhelds) {
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.online {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-avatar {
|
||||||
|
margin: .5rem auto 10px;
|
||||||
|
display: block;
|
||||||
|
//flex: 0 0 auto;
|
||||||
|
|
||||||
|
@include respond-to(handhelds) {
|
||||||
|
margin: 0 auto 10px;
|
||||||
|
--size: 100px;
|
||||||
|
--multiplier: .54;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-name, &-subtitle, &-avatar {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
}
|
@ -93,105 +93,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile {
|
|
||||||
&-content {
|
|
||||||
/* flex: 1 1 auto; */
|
|
||||||
flex: 0 0 auto;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
/* height: 100%; */
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.checkbox-field {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
margin-left: -54px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox-caption {
|
|
||||||
padding-left: 54px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-wrapper {
|
|
||||||
flex: 1 1 auto;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding-bottom: 13px;
|
|
||||||
|
|
||||||
@include respond-to(not-handhelds) {
|
|
||||||
padding-top: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-left-section {
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-container {
|
|
||||||
> .scrollable {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
//transform: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row-title {
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-name {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 20px;
|
|
||||||
line-height: 1.4;
|
|
||||||
font-weight: 500;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
word-break: break-word;
|
|
||||||
max-width: 340px;
|
|
||||||
margin: 0 auto;
|
|
||||||
color: var(--primary-text-color);
|
|
||||||
|
|
||||||
span.emoji {
|
|
||||||
vertical-align: inherit;
|
|
||||||
min-width: min-content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-subtitle {
|
|
||||||
text-align: center;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
font-size: 14px;
|
|
||||||
margin-bottom: .875rem;
|
|
||||||
margin-top: 1px;
|
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
|
||||||
margin-top: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.online {
|
|
||||||
color: var(--primary-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-avatar {
|
|
||||||
margin: .5rem auto 10px;
|
|
||||||
display: block;
|
|
||||||
//flex: 0 0 auto;
|
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
|
||||||
margin: 0 auto 10px;
|
|
||||||
--size: 100px;
|
|
||||||
--multiplier: .54;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-name, &-subtitle, &-avatar {
|
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#shared-media-container {
|
#shared-media-container {
|
||||||
/* .search-super {
|
/* .search-super {
|
||||||
top: 100%;
|
top: 100%;
|
||||||
|
@ -201,6 +201,7 @@ html.night {
|
|||||||
@import "partials/chatDrop";
|
@import "partials/chatDrop";
|
||||||
@import "partials/crop";
|
@import "partials/crop";
|
||||||
@import "partials/sidebar";
|
@import "partials/sidebar";
|
||||||
|
@import "partials/profile";
|
||||||
@import "partials/leftSidebar";
|
@import "partials/leftSidebar";
|
||||||
@import "partials/rightSidebar";
|
@import "partials/rightSidebar";
|
||||||
@import "partials/mediaViewer";
|
@import "partials/mediaViewer";
|
||||||
@ -998,9 +999,9 @@ middle-ellipsis-element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
min-height: 3.5rem;
|
min-height: 3rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: .9375rem 1rem;
|
padding: .6875rem 1rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -1027,7 +1028,7 @@ middle-ellipsis-element {
|
|||||||
color: var(--primary-text-color);
|
color: var(--primary-text-color);
|
||||||
line-height: var(--line-height);
|
line-height: var(--line-height);
|
||||||
|
|
||||||
@include text-overflow();
|
@include text-overflow(false);
|
||||||
|
|
||||||
&-right {
|
&-right {
|
||||||
flex: 0 0 auto !important;
|
flex: 0 0 auto !important;
|
||||||
@ -1046,6 +1047,7 @@ middle-ellipsis-element {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 1rem;
|
left: 1rem;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
|
margin-top: .25rem;
|
||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user