'Send as...' menu
New profile design Return back to main list by Escape Fix filters menu ripple
This commit is contained in:
parent
697b6bb5bd
commit
cc6084dd72
@ -16,7 +16,7 @@ import isSwipingBackSafari from "../helpers/dom/isSwipingBackSafari";
|
||||
export type NavigationItem = {
|
||||
type: 'left' | 'right' | 'im' | 'chat' | 'popup' | 'media' | 'menu' |
|
||||
'esg' | 'multiselect' | 'input-helper' | 'autocomplete-helper' | 'markup' |
|
||||
'global-search' | 'voice' | 'mobile-search',
|
||||
'global-search' | 'voice' | 'mobile-search' | 'filters',
|
||||
onPop: (canAnimate: boolean) => boolean | void,
|
||||
onEscape?: () => boolean,
|
||||
noHistory?: boolean,
|
||||
@ -169,8 +169,7 @@ export class AppNavigationController {
|
||||
//}
|
||||
}
|
||||
|
||||
public pushItem(item: NavigationItem) {
|
||||
this.navigations.push(item);
|
||||
private onItemAdded(item: NavigationItem) {
|
||||
this.debug && this.log('pushstate', item, this.navigations);
|
||||
|
||||
if(!item.noHistory) {
|
||||
@ -178,6 +177,16 @@ export class AppNavigationController {
|
||||
}
|
||||
}
|
||||
|
||||
public pushItem(item: NavigationItem) {
|
||||
this.navigations.push(item);
|
||||
this.onItemAdded(item);
|
||||
}
|
||||
|
||||
public unshiftItem(item: NavigationItem) {
|
||||
this.navigations.unshift(item);
|
||||
this.onItemAdded(item);
|
||||
}
|
||||
|
||||
private pushState() {
|
||||
this.manual = false;
|
||||
history.pushState(this.id, '');
|
||||
|
@ -47,7 +47,7 @@ const ButtonMenuItem = (options: ButtonMenuItemOptions) => {
|
||||
const keepOpen = !!checkboxField || !!options.keepOpen;
|
||||
|
||||
// * cancel mobile keyboard close
|
||||
attachClickEvent(el, /* CLICK_EVENT_NAME !== 'click' || keepOpen ? */ (e) => {
|
||||
onClick && attachClickEvent(el, /* CLICK_EVENT_NAME !== 'click' || keepOpen ? */ (e) => {
|
||||
cancelEvent(e);
|
||||
const result = onClick(e);
|
||||
|
||||
|
@ -11,13 +11,26 @@ import ButtonIcon from "./buttonIcon";
|
||||
import ButtonMenu, { ButtonMenuItemOptions } from "./buttonMenu";
|
||||
import { closeBtnMenu, openBtnMenu } from "./misc";
|
||||
|
||||
const ButtonMenuToggle = (options: Partial<{noRipple: true, onlyMobile: true, listenerSetter: ListenerSetter, asDiv: boolean}> = {}, direction: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right', buttons: ButtonMenuItemOptions[], onOpen?: (e: Event) => void) => {
|
||||
const ButtonMenuToggle = (
|
||||
options: Partial<{
|
||||
noRipple: true,
|
||||
onlyMobile: true,
|
||||
listenerSetter: ListenerSetter,
|
||||
asDiv: boolean,
|
||||
container: HTMLElement
|
||||
}> = {},
|
||||
direction: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right',
|
||||
buttons: ButtonMenuItemOptions[],
|
||||
onOpen?: (e: Event) => void,
|
||||
onClose?: () => void
|
||||
) => {
|
||||
options.asDiv = true;
|
||||
const button = ButtonIcon('more btn-menu-toggle', options);
|
||||
const button = options.container ?? ButtonIcon('more', options);
|
||||
button.classList.add('btn-menu-toggle');
|
||||
|
||||
const btnMenu = ButtonMenu(buttons, options.listenerSetter);
|
||||
btnMenu.classList.add(direction);
|
||||
ButtonMenuToggleHandler(button, onOpen, options);
|
||||
ButtonMenuToggleHandler(button, onOpen, options, onClose);
|
||||
button.append(btnMenu);
|
||||
return button;
|
||||
};
|
||||
|
@ -190,7 +190,7 @@ export default class Chat extends EventListenerBase<{
|
||||
|
||||
this.topbar = new ChatTopbar(this, appSidebarRight, this.appMessagesManager, this.appPeersManager, this.appChatsManager, this.appNotificationsManager, this.appProfileManager, this.appUsersManager, this.appGroupCallsManager);
|
||||
this.bubbles = new ChatBubbles(this, this.appMessagesManager, this.appStickersManager, this.appUsersManager, this.appInlineBotsManager, this.appPhotosManager, this.appPeersManager, this.appProfileManager, this.appDraftsManager, this.appMessagesIdsManager, this.appChatsManager, this.appReactionsManager);
|
||||
this.input = new ChatInput(this, this.appMessagesManager, this.appMessagesIdsManager, this.appDocsManager, this.appChatsManager, this.appPeersManager, this.appWebPagesManager, this.appImManager, this.appDraftsManager, this.serverTimeManager, this.appNotificationsManager, this.appEmojiManager, this.appUsersManager, this.appInlineBotsManager);
|
||||
this.input = new ChatInput(this, this.appMessagesManager, this.appMessagesIdsManager, this.appDocsManager, this.appChatsManager, this.appPeersManager, this.appWebPagesManager, this.appImManager, this.appDraftsManager, this.serverTimeManager, this.appNotificationsManager, this.appEmojiManager, this.appUsersManager, this.appInlineBotsManager, this.appProfileManager);
|
||||
this.selection = new ChatSelection(this, this.bubbles, this.input, this.appMessagesManager);
|
||||
this.contextMenu = new ChatContextMenu(this.bubbles.bubblesContainer, this, this.appMessagesManager, this.appPeersManager, this.appPollsManager, this.appDocsManager, this.appMessagesIdsManager, this.appReactionsManager);
|
||||
|
||||
@ -425,4 +425,14 @@ export default class Chat extends EventListenerBase<{
|
||||
!this.appMessagesManager.getDialogOnly(this.peerId) &&
|
||||
!this.appMessagesManager.getHistoryStorage(this.peerId).history.length;
|
||||
}
|
||||
|
||||
public getMessageSendingParams() {
|
||||
return {
|
||||
threadId: this.threadId,
|
||||
replyToMsgId: this.input.replyToMsgId,
|
||||
scheduleDate: this.input.scheduleDate,
|
||||
sendSilent: this.input.sendSilent,
|
||||
sendAsPeerId: this.input.sendAsPeerId
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -53,10 +53,8 @@ export default class InlineHelper extends AutocompleteHelper {
|
||||
return this.chat.input.getReadyToSend(() => {
|
||||
const queryAndResultIds = this.appInlineBotsManager.generateQId(queryId, (target as HTMLElement).dataset.resultId);
|
||||
this.appInlineBotsManager.sendInlineResult(peerId.toPeerId(), botId, queryAndResultIds, {
|
||||
...this.chat.getMessageSendingParams(),
|
||||
clearDraft: true,
|
||||
scheduleDate: this.chat.input.scheduleDate,
|
||||
silent: this.chat.input.sendSilent,
|
||||
replyToMsgId: this.chat.input.replyToMsgId
|
||||
});
|
||||
|
||||
this.chat.input.onMessageSent(true, true);
|
||||
|
@ -32,7 +32,7 @@ import PopupNewMedia from '../popups/newMedia';
|
||||
import { toast } from "../toast";
|
||||
import { wrapReply } from "../wrappers";
|
||||
import InputField from '../inputField';
|
||||
import { MessageEntity, DraftMessage, WebPage, Message } from '../../layer';
|
||||
import { MessageEntity, DraftMessage, WebPage, Message, ChatFull } from '../../layer';
|
||||
import StickersHelper from './stickersHelper';
|
||||
import ButtonIcon from '../buttonIcon';
|
||||
import ButtonMenuToggle from '../buttonMenuToggle';
|
||||
@ -87,10 +87,16 @@ import DropdownHover from '../../helpers/dropdownHover';
|
||||
import RadioForm from '../radioForm';
|
||||
import findUpTag from '../../helpers/dom/findUpTag';
|
||||
import toggleDisability from '../../helpers/dom/toggleDisability';
|
||||
import AvatarElement from '../avatar';
|
||||
import type { AppProfileManager } from '../../lib/appManagers/appProfileManager';
|
||||
import { indexOfAndSplice } from '../../helpers/array';
|
||||
import callbackify from '../../helpers/callbackify';
|
||||
|
||||
const RECORD_MIN_TIME = 500;
|
||||
const POSTING_MEDIA_NOT_ALLOWED = 'Posting media content isn\'t allowed in this group.';
|
||||
|
||||
const SEND_AS_ANIMATION_DURATION = 300;
|
||||
|
||||
type ChatInputHelperType = 'edit' | 'webpage' | 'forward' | 'reply';
|
||||
|
||||
export default class ChatInput {
|
||||
@ -115,7 +121,7 @@ export default class ChatInput {
|
||||
|
||||
private replyKeyboard: ReplyKeyboard;
|
||||
|
||||
private attachMenu: HTMLButtonElement;
|
||||
private attachMenu: HTMLElement;
|
||||
private attachMenuButtons: (ButtonMenuItemOptions & {verify: (peerId: PeerId, threadId: number) => boolean})[];
|
||||
|
||||
private sendMenu: SendMenu;
|
||||
@ -208,9 +214,17 @@ export default class ChatInput {
|
||||
private fakeWrapperTo: HTMLElement;
|
||||
private toggleBotStartBtnDisability: () => void;
|
||||
|
||||
private sendAsAvatar: AvatarElement;
|
||||
private sendAsContainer: HTMLElement;
|
||||
private sendAsCloseBtn: HTMLElement;
|
||||
private sendAsBtnMenu: HTMLElement;
|
||||
private sendAsPeerIds: PeerId[];
|
||||
public sendAsPeerId: PeerId;
|
||||
|
||||
// private activeContainer: HTMLElement;
|
||||
|
||||
constructor(private chat: Chat,
|
||||
constructor(
|
||||
private chat: Chat,
|
||||
private appMessagesManager: AppMessagesManager,
|
||||
private appMessagesIdsManager: AppMessagesIdsManager,
|
||||
private appDocsManager: AppDocsManager,
|
||||
@ -223,7 +237,8 @@ export default class ChatInput {
|
||||
private appNotificationsManager: AppNotificationsManager,
|
||||
private appEmojiManager: AppEmojiManager,
|
||||
private appUsersManager: AppUsersManager,
|
||||
private appInlineBotsManager: AppInlineBotsManager
|
||||
private appInlineBotsManager: AppInlineBotsManager,
|
||||
private appProfileManager: AppProfileManager
|
||||
) {
|
||||
this.listenerSetter = new ListenerSetter();
|
||||
}
|
||||
@ -461,6 +476,46 @@ export default class ChatInput {
|
||||
this.newMessageWrapper = document.createElement('div');
|
||||
this.newMessageWrapper.classList.add('new-message-wrapper');
|
||||
|
||||
this.sendAsContainer = document.createElement('div');
|
||||
this.sendAsContainer.classList.add('new-message-send-as-container');
|
||||
|
||||
this.sendAsCloseBtn = document.createElement('div');
|
||||
this.sendAsCloseBtn.classList.add('new-message-send-as-close', 'new-message-send-as-avatar', 'tgico-close');
|
||||
|
||||
const sendAsButtons: ButtonMenuItemOptions[] = [{
|
||||
text: 'SendMessageAsTitle',
|
||||
onClick: undefined
|
||||
}];
|
||||
|
||||
let previousAvatar: HTMLElement;
|
||||
const onSendAsMenuToggle = (visible: boolean) => {
|
||||
if(visible) {
|
||||
previousAvatar = this.sendAsAvatar;
|
||||
}
|
||||
|
||||
const isChanged = this.sendAsAvatar !== previousAvatar;
|
||||
const useRafs = !visible && isChanged ? 2 : 0;
|
||||
|
||||
SetTransition(this.sendAsCloseBtn, 'is-visible', visible, SEND_AS_ANIMATION_DURATION, undefined, useRafs);
|
||||
if(!isChanged) {
|
||||
SetTransition(previousAvatar, 'is-visible', !visible, SEND_AS_ANIMATION_DURATION, undefined, useRafs);
|
||||
}
|
||||
};
|
||||
|
||||
ButtonMenuToggle({
|
||||
noRipple: true,
|
||||
listenerSetter: this.listenerSetter,
|
||||
container: this.sendAsContainer
|
||||
}, 'top-right', sendAsButtons, () => {
|
||||
onSendAsMenuToggle(true);
|
||||
}, () => {
|
||||
onSendAsMenuToggle(false);
|
||||
});
|
||||
|
||||
sendAsButtons[0].element.classList.add('btn-menu-item-header');
|
||||
this.sendAsBtnMenu = this.sendAsContainer.firstElementChild as any;
|
||||
this.sendAsContainer.append(this.sendAsCloseBtn);
|
||||
|
||||
this.btnToggleEmoticons = ButtonIcon('none toggle-emoticons', {noRipple: true});
|
||||
|
||||
this.inputMessageContainer = document.createElement('div');
|
||||
@ -562,7 +617,7 @@ export default class ChatInput {
|
||||
this.fileInput.multiple = true;
|
||||
this.fileInput.style.display = 'none';
|
||||
|
||||
this.newMessageWrapper.append(...[this.btnToggleEmoticons, this.inputMessageContainer, this.btnScheduled, this.btnToggleReplyMarkup, this.attachMenu, this.recordTimeEl, this.fileInput].filter(Boolean));
|
||||
this.newMessageWrapper.append(...[this.sendAsContainer, this.btnToggleEmoticons, this.inputMessageContainer, this.btnScheduled, this.btnToggleReplyMarkup, this.attachMenu, this.recordTimeEl, this.fileInput].filter(Boolean));
|
||||
|
||||
this.rowsWrapper.append(this.replyElements.container);
|
||||
this.autocompleteHelperController = new AutocompleteHelperController();
|
||||
@ -664,6 +719,14 @@ export default class ChatInput {
|
||||
}
|
||||
});
|
||||
|
||||
if(this.sendAsContainer) {
|
||||
this.listenerSetter.add(rootScope)('peer_full_update', (peerId) => {
|
||||
if(peerId.isChannel() && this.chat.peerId === peerId) {
|
||||
this.updateSendAs();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(this.chat.type === 'scheduled') {
|
||||
this.listenerSetter.add(rootScope)('scheduled_delete', ({peerId, mids}) => {
|
||||
if(this.chat.peerId === peerId && mids.includes(this.editMsgId)) {
|
||||
@ -1129,7 +1192,7 @@ export default class ChatInput {
|
||||
public finishPeerChange(startParam?: string) {
|
||||
const peerId = this.chat.peerId;
|
||||
|
||||
const {forwardElements, btnScheduled, replyKeyboard, sendMenu, goDownBtn, chatInput} = this;
|
||||
const {forwardElements, btnScheduled, replyKeyboard, sendMenu, goDownBtn, chatInput, sendAsContainer} = this;
|
||||
chatInput.style.display = '';
|
||||
|
||||
const isBroadcast = this.appPeersManager.isBroadcast(peerId);
|
||||
@ -1160,6 +1223,19 @@ export default class ChatInput {
|
||||
});
|
||||
}
|
||||
|
||||
if(sendAsContainer) {
|
||||
if(this.sendAsAvatar) {
|
||||
this.sendAsAvatar.remove();
|
||||
this.sendAsAvatar = undefined;
|
||||
}
|
||||
|
||||
sendAsContainer.remove();
|
||||
SetTransition(this.newMessageWrapper, 'has-send-as', false, 0);
|
||||
this.sendAsPeerId = undefined;
|
||||
|
||||
this.updateSendAs(true);
|
||||
}
|
||||
|
||||
if(replyKeyboard) {
|
||||
replyKeyboard.setPeer(peerId);
|
||||
}
|
||||
@ -1182,6 +1258,157 @@ export default class ChatInput {
|
||||
this.center(false);
|
||||
}
|
||||
|
||||
private updateSendAsButtons(peerIds: PeerId[]) {
|
||||
const buttons: ButtonMenuItemOptions[] = peerIds.map((sendAsPeerId, idx) => {
|
||||
const textElement = document.createElement('div');
|
||||
|
||||
const subtitle = document.createElement('div');
|
||||
subtitle.classList.add('btn-menu-item-subtitle');
|
||||
if(sendAsPeerId.isUser()) {
|
||||
subtitle.append(i18n('Chat.SendAs.PersonalAccount'));
|
||||
} else {
|
||||
subtitle.append(this.appProfileManager.getChatMembersString(sendAsPeerId.toChatId()));
|
||||
}
|
||||
|
||||
textElement.append(
|
||||
new PeerTitle({peerId: sendAsPeerId}).element,
|
||||
subtitle
|
||||
);
|
||||
|
||||
return {
|
||||
onClick: idx ? () => {
|
||||
const currentPeerId = this.chat.peerId;
|
||||
if(currentPeerId.isChannel()) {
|
||||
const channelFull = this.appProfileManager.getCachedFullChat(currentPeerId.toChatId()) as ChatFull.channelFull;
|
||||
if(channelFull) {
|
||||
channelFull.default_send_as = this.appPeersManager.getOutputPeer(sendAsPeerId);
|
||||
this.sendAsPeerId = sendAsPeerId;
|
||||
this.updateSendAsAvatar(sendAsPeerId);
|
||||
|
||||
const middleware = this.chat.bubbles.getMiddleware();
|
||||
const executeButtonsUpdate = () => {
|
||||
if(this.sendAsPeerId !== sendAsPeerId || !middleware()) return;
|
||||
const peerIds = this.sendAsPeerIds.slice();
|
||||
indexOfAndSplice(peerIds, sendAsPeerId);
|
||||
peerIds.unshift(sendAsPeerId);
|
||||
this.updateSendAsButtons(peerIds);
|
||||
};
|
||||
|
||||
if(rootScope.settings.animationsEnabled) {
|
||||
setTimeout(executeButtonsUpdate, 250);
|
||||
} else {
|
||||
executeButtonsUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return;
|
||||
apiManager.invokeApi('messages.saveDefaultSendAs', {
|
||||
peer: this.appPeersManager.getInputPeerById(currentPeerId),
|
||||
send_as: this.appPeersManager.getInputPeerById(sendAsPeerId)
|
||||
});
|
||||
} : undefined,
|
||||
textElement
|
||||
};
|
||||
});
|
||||
|
||||
const btnMenu = ButtonMenu(buttons/* , this.listenerSetter */);
|
||||
buttons.forEach((button, idx) => {
|
||||
const peerId = peerIds[idx];
|
||||
const avatar = new AvatarElement();
|
||||
avatar.classList.add('avatar-32', 'btn-menu-item-icon');
|
||||
avatar.setAttribute('peer', '' + peerId);
|
||||
|
||||
if(!idx) {
|
||||
avatar.classList.add('active');
|
||||
}
|
||||
|
||||
button.element.prepend(avatar);
|
||||
});
|
||||
|
||||
Array.from(this.sendAsBtnMenu.children).slice(1).forEach(node => node.remove());
|
||||
this.sendAsBtnMenu.append(...Array.from(btnMenu.children));
|
||||
}
|
||||
|
||||
private updateSendAsAvatar(sendAsPeerId: PeerId, skipAnimation?: boolean) {
|
||||
const previousAvatar = this.sendAsAvatar;
|
||||
if(previousAvatar) {
|
||||
if(+previousAvatar.getAttribute('peer') === sendAsPeerId) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(!previousAvatar) {
|
||||
skipAnimation = true;
|
||||
}
|
||||
|
||||
let useRafs = skipAnimation ? 0 : 2;
|
||||
const duration = skipAnimation ? 0 : SEND_AS_ANIMATION_DURATION;
|
||||
const avatar = this.sendAsAvatar = new AvatarElement();
|
||||
avatar.setAttribute('dialog', '0');
|
||||
avatar.setAttribute('peer', '' + sendAsPeerId);
|
||||
avatar.classList.add('new-message-send-as-avatar', 'avatar-30');
|
||||
|
||||
SetTransition(avatar, 'is-visible', true, duration, undefined, useRafs);
|
||||
if(previousAvatar) {
|
||||
SetTransition(previousAvatar, 'is-visible', false, duration, () => {
|
||||
previousAvatar.remove();
|
||||
}, useRafs);
|
||||
}
|
||||
|
||||
this.sendAsContainer.append(avatar);
|
||||
}
|
||||
|
||||
private getDefaultSendAs() {
|
||||
// return rootScope.myId;
|
||||
return callbackify(this.appProfileManager.getChannelFull(this.chat.peerId.toChatId()), (channelFull) => {
|
||||
return channelFull.default_send_as ? this.appPeersManager.getPeerId(channelFull.default_send_as) : undefined;
|
||||
});
|
||||
}
|
||||
|
||||
private updateSendAs(skipAnimation?: boolean) {
|
||||
const peerId = this.chat.peerId;
|
||||
if(!peerId.isChannel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const middleware = this.chat.bubbles.getMiddleware();
|
||||
const {sendAsContainer} = this;
|
||||
const chatId = peerId.toChatId();
|
||||
const result = this.getDefaultSendAs();
|
||||
// const result = Promise.resolve(this.getDefaultSendAs());
|
||||
|
||||
if(result instanceof Promise) {
|
||||
skipAnimation = undefined;
|
||||
}
|
||||
|
||||
callbackify(result, (sendAsPeerId) => {
|
||||
if(!middleware() || sendAsPeerId === undefined) return;
|
||||
|
||||
this.sendAsPeerId = sendAsPeerId;
|
||||
this.updateSendAsAvatar(sendAsPeerId, skipAnimation);
|
||||
|
||||
this.appChatsManager.getSendAs(chatId).then(peers => {
|
||||
if(!middleware()) return;
|
||||
|
||||
const peerIds = peers.map((peer) => this.appPeersManager.getPeerId(peer));
|
||||
this.sendAsPeerIds = peerIds.slice();
|
||||
|
||||
indexOfAndSplice(peerIds, sendAsPeerId);
|
||||
peerIds.unshift(sendAsPeerId);
|
||||
this.updateSendAsButtons(peerIds);
|
||||
});
|
||||
|
||||
let useRafs = 0;
|
||||
if(!sendAsContainer.parentElement) {
|
||||
this.newMessageWrapper.prepend(sendAsContainer);
|
||||
useRafs = 2;
|
||||
}
|
||||
|
||||
SetTransition(this.newMessageWrapper, 'has-send-as', true, skipAnimation ? 0 : SEND_AS_ANIMATION_DURATION, undefined, useRafs);
|
||||
});
|
||||
}
|
||||
|
||||
public updateMessageInput() {
|
||||
const {chatInput, attachMenu, messageInput} = this;
|
||||
const {peerId, threadId} = this.chat;
|
||||
@ -2128,8 +2355,9 @@ export default class ChatInput {
|
||||
return;
|
||||
}
|
||||
|
||||
const {threadId, peerId} = chat;
|
||||
const {replyToMsgId, noWebPage, sendSilent, scheduleDate} = this;
|
||||
const {peerId} = chat;
|
||||
const {noWebPage} = this;
|
||||
const sendingParams = this.chat.getMessageSendingParams();
|
||||
|
||||
const {value, entities} = getRichValue(this.messageInputField.input);
|
||||
|
||||
@ -2151,12 +2379,9 @@ export default class ChatInput {
|
||||
} else if(value.trim()) {
|
||||
this.appMessagesManager.sendText(peerId, value, {
|
||||
entities,
|
||||
replyToMsgId: replyToMsgId,
|
||||
threadId: threadId,
|
||||
...sendingParams,
|
||||
noWebPage: noWebPage,
|
||||
webPage: this.getWebPagePromise ? undefined : this.willSendWebPage,
|
||||
scheduleDate: scheduleDate,
|
||||
silent: sendSilent,
|
||||
clearDraft: true
|
||||
});
|
||||
|
||||
@ -2170,8 +2395,7 @@ export default class ChatInput {
|
||||
setTimeout(() => {
|
||||
for(const fromPeerId in forwarding) {
|
||||
this.appMessagesManager.forwardMessages(peerId, fromPeerId.toPeerId(), forwarding[fromPeerId], {
|
||||
silent: sendSilent,
|
||||
scheduleDate: scheduleDate,
|
||||
...sendingParams,
|
||||
dropAuthor: this.forwardElements && this.forwardElements.hideSender.checkboxField.checked,
|
||||
dropCaptions: this.isDroppingCaptions()
|
||||
});
|
||||
@ -2202,11 +2426,8 @@ export default class ChatInput {
|
||||
|
||||
if(document) {
|
||||
this.appMessagesManager.sendFile(this.chat.peerId, document, {
|
||||
...this.chat.getMessageSendingParams(),
|
||||
isMedia: true,
|
||||
replyToMsgId: this.replyToMsgId,
|
||||
threadId: this.chat.threadId,
|
||||
silent: this.sendSilent,
|
||||
scheduleDate: this.scheduleDate,
|
||||
clearDraft: clearDraft || undefined
|
||||
});
|
||||
this.onMessageSent(clearDraft, true);
|
||||
|
@ -67,7 +67,7 @@ export default class ChatTopbar {
|
||||
private btnGroupCall: HTMLButtonElement;
|
||||
private btnMute: HTMLButtonElement;
|
||||
private btnSearch: HTMLButtonElement;
|
||||
private btnMore: HTMLButtonElement;
|
||||
private btnMore: HTMLElement;
|
||||
|
||||
private chatAudio: ChatAudio;
|
||||
public pinnedMessage: ChatPinnedMessage;
|
||||
|
@ -5,8 +5,10 @@
|
||||
*/
|
||||
|
||||
import IS_PARALLAX_SUPPORTED from "../environment/parallaxSupport";
|
||||
import callbackify from "../helpers/callbackify";
|
||||
import { copyTextToClipboard } from "../helpers/clipboard";
|
||||
import replaceContent from "../helpers/dom/replaceContent";
|
||||
import ListenerSetter from "../helpers/listenerSetter";
|
||||
import { fastRaf } from "../helpers/schedulers";
|
||||
import { ChatFull, User } from "../layer";
|
||||
import { Channel } from "../lib/appManagers/appChatsManager";
|
||||
@ -38,7 +40,7 @@ let setText = (text: string, row: Row) => {
|
||||
|
||||
export default class PeerProfile {
|
||||
public element: HTMLElement;
|
||||
public avatars: PeerProfileAvatars;
|
||||
private avatars: PeerProfileAvatars;
|
||||
private avatar: AvatarElement;
|
||||
private section: SettingSection;
|
||||
private name: HTMLDivElement;
|
||||
@ -48,6 +50,7 @@ export default class PeerProfile {
|
||||
private phone: Row;
|
||||
private notifications: Row;
|
||||
private location: Row;
|
||||
private link: Row;
|
||||
|
||||
private cleaned: boolean;
|
||||
private setMoreDetailsTimeout: number;
|
||||
@ -56,10 +59,18 @@ export default class PeerProfile {
|
||||
private peerId: PeerId;
|
||||
private threadId: number;
|
||||
|
||||
constructor(public scrollable: Scrollable) {
|
||||
constructor(
|
||||
public scrollable: Scrollable,
|
||||
private listenerSetter?: ListenerSetter,
|
||||
private isDialog = true
|
||||
) {
|
||||
if(!IS_PARALLAX_SUPPORTED) {
|
||||
this.scrollable.container.classList.add('no-parallax');
|
||||
}
|
||||
|
||||
if(!listenerSetter) {
|
||||
this.listenerSetter = new ListenerSetter();
|
||||
}
|
||||
}
|
||||
|
||||
public init() {
|
||||
@ -75,7 +86,7 @@ export default class PeerProfile {
|
||||
|
||||
this.avatar = new AvatarElement();
|
||||
this.avatar.classList.add('profile-avatar', 'avatar-120');
|
||||
this.avatar.setAttribute('dialog', '1');
|
||||
this.avatar.setAttribute('dialog', '' + +this.isDialog);
|
||||
this.avatar.setAttribute('clickable', '');
|
||||
|
||||
this.name = document.createElement('div');
|
||||
@ -124,33 +135,41 @@ export default class PeerProfile {
|
||||
}
|
||||
});
|
||||
|
||||
this.link = new Row({
|
||||
title: ' ',
|
||||
subtitleLangKey: 'SetUrlPlaceholder',
|
||||
icon: 'link',
|
||||
clickable: () => {
|
||||
Promise.resolve(appProfileManager.getChatFull(this.peerId.toChatId())).then(chatFull => {
|
||||
copyTextToClipboard(chatFull.exported_invite.link);
|
||||
toast(I18n.format('LinkCopied', true));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.location = new Row({
|
||||
title: ' ',
|
||||
subtitleLangKey: 'ChatLocation',
|
||||
icon: 'location'
|
||||
});
|
||||
|
||||
this.notifications = new Row({
|
||||
checkboxField: new CheckboxField({toggle: true}),
|
||||
titleLangKey: 'Notifications',
|
||||
icon: 'unmute'
|
||||
});
|
||||
|
||||
this.section.content.append(
|
||||
this.phone.container,
|
||||
this.username.container,
|
||||
this.location.container,
|
||||
this.bio.container,
|
||||
this.notifications.container
|
||||
this.link.container
|
||||
);
|
||||
|
||||
this.element.append(this.section.container);
|
||||
const {listenerSetter} = this;
|
||||
if(this.isDialog) {
|
||||
this.notifications = new Row({
|
||||
checkboxField: new CheckboxField({toggle: true}),
|
||||
titleLangKey: 'Notifications',
|
||||
icon: 'unmute'
|
||||
});
|
||||
|
||||
if(IS_PARALLAX_SUPPORTED) {
|
||||
this.element.append(generateDelimiter());
|
||||
}
|
||||
|
||||
this.notifications.checkboxField.input.addEventListener('change', (e) => {
|
||||
listenerSetter.add(this.notifications.checkboxField.input)('change', (e) => {
|
||||
if(!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
@ -159,33 +178,42 @@ export default class PeerProfile {
|
||||
appMessagesManager.togglePeerMute(this.peerId);
|
||||
});
|
||||
|
||||
rootScope.addEventListener('dialog_notify_settings', (dialog) => {
|
||||
listenerSetter.add(rootScope)('dialog_notify_settings', (dialog) => {
|
||||
if(this.peerId === dialog.peerId) {
|
||||
const muted = appNotificationsManager.isPeerLocalMuted(this.peerId, false);
|
||||
this.notifications.checkboxField.checked = !muted;
|
||||
}
|
||||
});
|
||||
|
||||
rootScope.addEventListener('peer_typings', ({peerId}) => {
|
||||
this.section.content.append(this.notifications.container);
|
||||
}
|
||||
|
||||
this.element.append(this.section.container);
|
||||
|
||||
if(IS_PARALLAX_SUPPORTED) {
|
||||
this.element.append(generateDelimiter());
|
||||
}
|
||||
|
||||
listenerSetter.add(rootScope)('peer_typings', ({peerId}) => {
|
||||
if(this.peerId === peerId) {
|
||||
this.setPeerStatus();
|
||||
}
|
||||
});
|
||||
|
||||
rootScope.addEventListener('peer_bio_edit', (peerId) => {
|
||||
listenerSetter.add(rootScope)('peer_bio_edit', (peerId) => {
|
||||
if(peerId === this.peerId) {
|
||||
this.setMoreDetails(true);
|
||||
}
|
||||
});
|
||||
|
||||
rootScope.addEventListener('user_update', (userId) => {
|
||||
if(this.peerId === userId) {
|
||||
listenerSetter.add(rootScope)('user_update', (userId) => {
|
||||
if(this.peerId === userId.toPeerId()) {
|
||||
this.setPeerStatus();
|
||||
}
|
||||
});
|
||||
|
||||
rootScope.addEventListener('contacts_update', (userId) => {
|
||||
if(this.peerId === userId) {
|
||||
listenerSetter.add(rootScope)('contacts_update', (userId) => {
|
||||
if(this.peerId === userId.toPeerId()) {
|
||||
const user = appUsersManager.getUser(userId);
|
||||
if(!user.pFlags.self) {
|
||||
if(user.phone) {
|
||||
@ -204,24 +232,37 @@ export default class PeerProfile {
|
||||
if(!this.peerId) return;
|
||||
|
||||
const peerId = this.peerId;
|
||||
appImManager.setPeerStatus(this.peerId, this.subtitle, needClear, true, () => peerId === this.peerId);
|
||||
appImManager.setPeerStatus(this.peerId, this.subtitle, needClear, true, () => peerId === this.peerId, !this.isDialog);
|
||||
};
|
||||
|
||||
public cleanupHTML() {
|
||||
this.bio.container.style.display = 'none';
|
||||
this.phone.container.style.display = 'none';
|
||||
this.username.container.style.display = 'none';
|
||||
this.location.container.style.display = 'none';
|
||||
[
|
||||
this.bio,
|
||||
this.phone,
|
||||
this.username,
|
||||
this.location,
|
||||
this.link
|
||||
].forEach(row => {
|
||||
row.container.style.display = 'none';
|
||||
});
|
||||
|
||||
if(this.notifications) {
|
||||
this.notifications.container.style.display = '';
|
||||
this.notifications.checkboxField.checked = true;
|
||||
}
|
||||
|
||||
if(this.setMoreDetailsTimeout) {
|
||||
window.clearTimeout(this.setMoreDetailsTimeout);
|
||||
this.setMoreDetailsTimeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private canBeDetailed() {
|
||||
return this.peerId !== rootScope.myId || !this.isDialog;
|
||||
}
|
||||
|
||||
public setAvatar() {
|
||||
if(this.peerId !== rootScope.myId) {
|
||||
if(this.canBeDetailed()) {
|
||||
const photo = appPeersManager.getPeerPhoto(this.peerId);
|
||||
|
||||
if(photo) {
|
||||
@ -268,15 +309,17 @@ export default class PeerProfile {
|
||||
this.setAvatar();
|
||||
|
||||
// username
|
||||
if(peerId !== rootScope.myId) {
|
||||
if(this.canBeDetailed()) {
|
||||
let username = appPeersManager.getPeerUsername(peerId);
|
||||
if(username) {
|
||||
setText(appPeersManager.getPeerUsername(peerId), this.username);
|
||||
}
|
||||
|
||||
if(this.notifications) {
|
||||
const muted = appNotificationsManager.isPeerLocalMuted(peerId, false);
|
||||
this.notifications.checkboxField.checked = !muted;
|
||||
} else {
|
||||
}
|
||||
} else if(this.notifications) {
|
||||
fastRaf(() => {
|
||||
this.notifications.container.style.display = 'none';
|
||||
});
|
||||
@ -287,7 +330,7 @@ export default class PeerProfile {
|
||||
//membersLi.style.display = 'none';
|
||||
|
||||
let user = appUsersManager.getUser(peerId);
|
||||
if(user.phone && peerId !== rootScope.myId) {
|
||||
if(user.phone && this.canBeDetailed()) {
|
||||
setText(appUsersManager.formatUserPhone(user.phone), this.phone);
|
||||
}
|
||||
}/* else {
|
||||
@ -298,7 +341,7 @@ export default class PeerProfile {
|
||||
|
||||
replaceContent(this.name, new PeerTitle({
|
||||
peerId,
|
||||
dialog: true,
|
||||
dialog: this.isDialog,
|
||||
}).element);
|
||||
|
||||
const peer = appPeersManager.getPeer(peerId);
|
||||
@ -318,11 +361,11 @@ export default class PeerProfile {
|
||||
const peerId = this.peerId;
|
||||
const threadId = this.threadId;
|
||||
|
||||
if(!peerId || appPeersManager.isRestricted(peerId) || peerId === rootScope.myId) {
|
||||
if(!peerId || appPeersManager.isRestricted(peerId) || !this.canBeDetailed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Promise.resolve(appProfileManager.getProfileByPeerId(peerId, override)).then((peerFull) => {
|
||||
callbackify(appProfileManager.getProfileByPeerId(peerId, override), (peerFull) => {
|
||||
if(this.peerId !== peerId || this.threadId !== threadId || appPeersManager.isRestricted(peerId)) {
|
||||
//this.log.warn('peer changed');
|
||||
return;
|
||||
@ -334,9 +377,14 @@ export default class PeerProfile {
|
||||
setText(RichTextProcessor.wrapRichText(peerFull.about), this.bio);
|
||||
}
|
||||
|
||||
if((peerFull as ChatFull.channelFull)?.location?._ == 'channelLocation') {
|
||||
// @ts-ignore
|
||||
setText(chatFull.location.address, this.location);
|
||||
const exportedInvite = (peerFull as ChatFull.channelFull).exported_invite;
|
||||
if(exportedInvite) {
|
||||
setText(exportedInvite.link, this.link);
|
||||
}
|
||||
|
||||
const location = (peerFull as ChatFull.channelFull).location;
|
||||
if(location?._ == 'channelLocation') {
|
||||
setText(location.address, this.location);
|
||||
}
|
||||
|
||||
this.setMoreDetailsTimeout = window.setTimeout(() => this.setMoreDetails(true), 60e3);
|
||||
|
@ -286,10 +286,7 @@ export default class PopupCreatePoll extends PopupElement {
|
||||
//console.log('Will try to create poll:', inputMediaPoll);
|
||||
|
||||
this.chat.appMessagesManager.sendOther(this.chat.peerId, inputMediaPoll, {
|
||||
threadId: this.chat.threadId,
|
||||
replyToMsgId: this.chat.input.replyToMsgId,
|
||||
scheduleDate: this.chat.input.scheduleDate,
|
||||
silent: this.chat.input.sendSilent
|
||||
...this.chat.getMessageSendingParams()
|
||||
});
|
||||
|
||||
if(this.chat.input.helperType === 'reply') {
|
||||
|
@ -232,21 +232,17 @@ export default class PopupNewMedia extends PopupElement {
|
||||
//console.log('will send files with options:', willAttach);
|
||||
|
||||
const {peerId, input} = this.chat;
|
||||
const {sendSilent, scheduleDate} = input;
|
||||
|
||||
sendFileDetails.forEach(d => {
|
||||
d.itemDiv = undefined;
|
||||
});
|
||||
|
||||
const {length} = sendFileDetails;
|
||||
const replyToMsgId = input.replyToMsgId;
|
||||
const sendingParams = this.chat.getMessageSendingParams();
|
||||
this.iterate((sendFileDetails) => {
|
||||
if(caption && sendFileDetails.length !== length) {
|
||||
this.chat.appMessagesManager.sendText(peerId, caption, {
|
||||
replyToMsgId,
|
||||
threadId: this.chat.threadId,
|
||||
silent: sendSilent,
|
||||
scheduleDate,
|
||||
...sendingParams,
|
||||
clearDraft: true
|
||||
});
|
||||
|
||||
@ -259,12 +255,9 @@ export default class PopupNewMedia extends PopupElement {
|
||||
};
|
||||
|
||||
this.chat.appMessagesManager.sendAlbum(peerId, w.sendFileDetails.map(d => d.file), Object.assign({
|
||||
...sendingParams,
|
||||
caption,
|
||||
replyToMsgId,
|
||||
threadId: this.chat.threadId,
|
||||
isMedia: isMedia,
|
||||
silent: sendSilent,
|
||||
scheduleDate,
|
||||
clearDraft: true as true
|
||||
}, w));
|
||||
|
||||
|
@ -16,6 +16,7 @@ import setInnerHTML from "../helpers/dom/setInnerHTML";
|
||||
export default class Row {
|
||||
public container: HTMLElement;
|
||||
public title: HTMLDivElement;
|
||||
public titleRight: HTMLElement;
|
||||
public subtitle: HTMLElement;
|
||||
public media: HTMLElement;
|
||||
|
||||
@ -35,6 +36,7 @@ export default class Row {
|
||||
title: string | HTMLElement,
|
||||
titleLangKey: LangPackKey,
|
||||
titleRight: string | HTMLElement,
|
||||
titleRightSecondary: string | HTMLElement,
|
||||
clickable: boolean | ((e: Event) => void),
|
||||
navigationTab: SliderSuperTab,
|
||||
havePadding: boolean,
|
||||
@ -90,7 +92,8 @@ export default class Row {
|
||||
|
||||
if(options.title || options.titleLangKey) {
|
||||
let c: HTMLElement;
|
||||
if(options.titleRight) {
|
||||
const titleRight = options.titleRight || options.titleRightSecondary;
|
||||
if(titleRight) {
|
||||
c = document.createElement('div');
|
||||
c.classList.add('row-title-row');
|
||||
this.container.append(c);
|
||||
@ -112,17 +115,21 @@ export default class Row {
|
||||
}
|
||||
c.append(this.title);
|
||||
|
||||
if(options.titleRight) {
|
||||
const titleRight = document.createElement('div');
|
||||
titleRight.classList.add('row-title', 'row-title-right');
|
||||
if(titleRight) {
|
||||
const titleRightEl = this.titleRight = document.createElement('div');
|
||||
titleRightEl.classList.add('row-title', 'row-title-right');
|
||||
|
||||
if(typeof(options.titleRight) === 'string') {
|
||||
titleRight.innerHTML = options.titleRight;
|
||||
} else {
|
||||
titleRight.append(options.titleRight);
|
||||
if(options.titleRightSecondary) {
|
||||
titleRightEl.classList.add('row-title-right-secondary');
|
||||
}
|
||||
|
||||
c.append(titleRight);
|
||||
if(typeof(titleRight) === 'string') {
|
||||
titleRightEl.innerHTML = titleRight;
|
||||
} else {
|
||||
titleRightEl.append(titleRight);
|
||||
}
|
||||
|
||||
c.append(titleRightEl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ import { ripple } from "../ripple";
|
||||
export const LEFT_COLUMN_ACTIVE_CLASSNAME = 'is-left-column-shown';
|
||||
|
||||
export class AppSidebarLeft extends SidebarSlider {
|
||||
private toolsBtn: HTMLButtonElement;
|
||||
private toolsBtn: HTMLElement;
|
||||
private backBtn: HTMLButtonElement;
|
||||
//private searchInput = document.getElementById('global-search') as HTMLInputElement;
|
||||
private inputSearch: InputSearch;
|
||||
@ -671,7 +671,9 @@ export type SettingSectionOptions = {
|
||||
caption?: LangPackKey | true,
|
||||
noDelimiter?: boolean,
|
||||
fakeGradientDelimiter?: boolean,
|
||||
noShadow?: boolean
|
||||
noShadow?: boolean,
|
||||
// fullWidth?: boolean,
|
||||
// noPaddingTop?: boolean
|
||||
};
|
||||
|
||||
const className = 'sidebar-left-section';
|
||||
@ -682,6 +684,8 @@ export class SettingSection {
|
||||
public title: HTMLElement;
|
||||
public caption: HTMLElement;
|
||||
|
||||
private fullWidth: boolean;
|
||||
|
||||
constructor(options: SettingSectionOptions = {}) {
|
||||
const container = this.container = document.createElement('div');
|
||||
container.classList.add(className + '-container');
|
||||
@ -703,6 +707,14 @@ export class SettingSection {
|
||||
innerContainer.classList.add('no-delimiter');
|
||||
}
|
||||
|
||||
// if(options.fullWidth) {
|
||||
// this.fullWidth = true;
|
||||
// }
|
||||
|
||||
// if(options.noPaddingTop) {
|
||||
// innerContainer.classList.add('no-padding-top');
|
||||
// }
|
||||
|
||||
const content = this.content = this.generateContentElement();
|
||||
|
||||
if(options.name) {
|
||||
@ -728,6 +740,11 @@ export class SettingSection {
|
||||
public generateContentElement() {
|
||||
const content = document.createElement('div');
|
||||
content.classList.add(className + '-content');
|
||||
|
||||
// if(this.fullWidth) {
|
||||
// content.classList.add('full-width');
|
||||
// }
|
||||
|
||||
this.innerContainer.append(content);
|
||||
return content;
|
||||
}
|
||||
|
@ -20,9 +20,9 @@ import PopupPeer from "../../popups/peer";
|
||||
import findUpClassName from "../../../helpers/dom/findUpClassName";
|
||||
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
|
||||
import toggleDisability from "../../../helpers/dom/toggleDisability";
|
||||
import { SliderSuperTabEventable } from "../../sliderTab";
|
||||
|
||||
export default class AppActiveSessionsTab extends SliderSuperTab {
|
||||
public privacyTab: AppPrivacyAndSecurityTab;
|
||||
export default class AppActiveSessionsTab extends SliderSuperTabEventable {
|
||||
public authorizations: Authorization.authorization[];
|
||||
private menuElement: HTMLElement;
|
||||
|
||||
@ -76,7 +76,6 @@ export default class AppActiveSessionsTab extends SliderSuperTab {
|
||||
//toggleDisability([btnTerminate], false);
|
||||
btnTerminate.remove();
|
||||
otherSection.container.remove();
|
||||
this.privacyTab.updateActiveSessions();
|
||||
}, onError).finally(() => {
|
||||
toggle();
|
||||
});
|
||||
@ -127,7 +126,6 @@ export default class AppActiveSessionsTab extends SliderSuperTab {
|
||||
.then(value => {
|
||||
if(value) {
|
||||
target.remove();
|
||||
this.privacyTab.updateActiveSessions();
|
||||
}
|
||||
}, onError);
|
||||
}
|
||||
|
@ -93,8 +93,10 @@ export default class AppPrivacyAndSecurityTab extends SliderSuperTabEventable {
|
||||
subtitleLangKey: SUBTITLE,
|
||||
clickable: () => {
|
||||
const tab = new AppActiveSessionsTab(this.slider);
|
||||
tab.privacyTab = this;
|
||||
tab.authorizations = this.authorizations;
|
||||
tab.eventListener.addEventListener('destroy', () => {
|
||||
this.updateActiveSessions();
|
||||
}, {once: true});
|
||||
tab.open();
|
||||
}
|
||||
});
|
||||
|
@ -5,9 +5,7 @@
|
||||
*/
|
||||
|
||||
import { SliderSuperTab } from "../../slider";
|
||||
import AvatarElement from "../../avatar";
|
||||
import apiManager from "../../../lib/mtproto/mtprotoworker";
|
||||
import appUsersManager from "../../../lib/appManagers/appUsersManager";
|
||||
import ButtonMenuToggle from "../../buttonMenuToggle";
|
||||
import Button from "../../button";
|
||||
import AppPrivacyAndSecurityTab from "./privacyAndSecurity";
|
||||
@ -15,18 +13,24 @@ import AppGeneralSettingsTab from "./generalSettings";
|
||||
import AppEditProfileTab from "./editProfile";
|
||||
import AppChatFoldersTab from "./chatFolders";
|
||||
import AppNotificationsTab from "./notifications";
|
||||
import PeerTitle from "../../peerTitle";
|
||||
import AppLanguageTab from "./language";
|
||||
import lottieLoader from "../../../lib/rlottie/lottieLoader";
|
||||
import PopupPeer from "../../popups/peer";
|
||||
import AppDataAndStorageTab from "./dataAndStorage";
|
||||
import ButtonIcon from "../../buttonIcon";
|
||||
import PeerProfile from "../../peerProfile";
|
||||
import rootScope from "../../../lib/rootScope";
|
||||
import { SettingSection } from "..";
|
||||
import Row from "../../row";
|
||||
import AppActiveSessionsTab from "./activeSessions";
|
||||
import { i18n, LangPackKey } from "../../../lib/langPack";
|
||||
import { AccountAuthorizations, Authorization } from "/Users/kuzmenko/Documents/projects/tweb/src/layer";
|
||||
import { SliderSuperTabConstructable } from "../../sliderTab";
|
||||
import PopupAvatar from "../../popups/avatar";
|
||||
import appProfileManager from "../../../lib/appManagers/appProfileManager";
|
||||
//import AppMediaViewer from "../../appMediaViewerNew";
|
||||
|
||||
export default class AppSettingsTab extends SliderSuperTab {
|
||||
private avatarElem: AvatarElement;
|
||||
private nameDiv: HTMLElement;
|
||||
private phoneDiv: HTMLElement;
|
||||
|
||||
private buttons: {
|
||||
edit: HTMLButtonElement,
|
||||
folders: HTMLButtonElement,
|
||||
@ -34,8 +38,14 @@ export default class AppSettingsTab extends SliderSuperTab {
|
||||
notifications: HTMLButtonElement,
|
||||
storage: HTMLButtonElement,
|
||||
privacy: HTMLButtonElement,
|
||||
language: HTMLButtonElement
|
||||
} = {} as any;
|
||||
private profile: PeerProfile;
|
||||
|
||||
private languageRow: Row;
|
||||
private devicesRow: Row;
|
||||
|
||||
private authorizations: Authorization.authorization[];
|
||||
private getAuthorizationsPromise: Promise<AccountAuthorizations.accountAuthorizations>;
|
||||
|
||||
protected init() {
|
||||
this.container.classList.add('settings-container');
|
||||
@ -59,11 +69,25 @@ export default class AppSettingsTab extends SliderSuperTab {
|
||||
}
|
||||
}]);
|
||||
|
||||
this.header.append(btnMenu);
|
||||
this.buttons.edit = ButtonIcon('edit');
|
||||
|
||||
this.avatarElem = new AvatarElement();
|
||||
this.avatarElem.setAttribute('clickable', '');
|
||||
this.avatarElem.classList.add('profile-avatar', 'avatar-120');
|
||||
this.header.append(this.buttons.edit, btnMenu);
|
||||
|
||||
this.profile = new PeerProfile(this.scrollable, this.listenerSetter, false);
|
||||
this.profile.init();
|
||||
this.profile.setPeer(rootScope.myId);
|
||||
this.profile.fillProfileElements();
|
||||
|
||||
const changeAvatarBtn = Button('btn-circle btn-corner z-depth-1 profile-change-avatar', {icon: 'cameraadd'});
|
||||
changeAvatarBtn.addEventListener('click', () => {
|
||||
const canvas = document.createElement('canvas');
|
||||
new PopupAvatar().open(canvas, (upload) => {
|
||||
upload().then(inputFile => {
|
||||
return appProfileManager.uploadProfilePhoto(inputFile);
|
||||
});
|
||||
});
|
||||
});
|
||||
this.profile.element.lastElementChild.firstElementChild.append(changeAvatarBtn);
|
||||
|
||||
/* const div = document.createElement('div');
|
||||
//div.style.cssText = 'border-radius: 8px; overflow: hidden; width: 396px; height: 264px; flex: 0 0 auto; position: relative; margin: 10rem 0 10rem auto;';
|
||||
@ -107,28 +131,66 @@ export default class AppSettingsTab extends SliderSuperTab {
|
||||
|
||||
this.scrollable.append(div); */
|
||||
|
||||
this.nameDiv = document.createElement('div');
|
||||
this.nameDiv.classList.add('profile-name');
|
||||
|
||||
this.phoneDiv = document.createElement('div');
|
||||
this.phoneDiv.classList.add('profile-subtitle');
|
||||
|
||||
const buttonsDiv = document.createElement('div');
|
||||
buttonsDiv.classList.add('profile-buttons');
|
||||
|
||||
const className = 'profile-button btn-primary btn-transparent';
|
||||
buttonsDiv.append(
|
||||
this.buttons.edit = Button(className, {icon: 'edit', text: 'EditAccount.Title'}),
|
||||
this.buttons.folders = Button(className, {icon: 'folder', text: 'AccountSettings.Filters'}),
|
||||
this.buttons.general = Button(className, {icon: 'settings', text: 'Telegram.GeneralSettingsViewController'}),
|
||||
this.buttons.storage = Button(className, {icon: 'data', text: 'DataSettings'}),
|
||||
this.buttons.notifications = Button(className, {icon: 'unmute', text: 'AccountSettings.Notifications'}),
|
||||
this.buttons.privacy = Button(className, {icon: 'lock', text: 'AccountSettings.PrivacyAndSecurity'}),
|
||||
this.buttons.language = Button(className, {icon: 'language', text: 'AccountSettings.Language'})
|
||||
const b: [string, LangPackKey, SliderSuperTabConstructable][] = [
|
||||
['unmute', 'AccountSettings.Notifications', AppNotificationsTab],
|
||||
['data', 'DataSettings', AppDataAndStorageTab],
|
||||
['lock', 'AccountSettings.PrivacyAndSecurity', AppPrivacyAndSecurityTab],
|
||||
['settings', 'Telegram.GeneralSettingsViewController', AppGeneralSettingsTab],
|
||||
['folder', 'AccountSettings.Filters', AppChatFoldersTab],
|
||||
];
|
||||
|
||||
const rows = b.map(([icon, langPackKey, tabConstructor]) => {
|
||||
return new Row({
|
||||
titleLangKey: langPackKey,
|
||||
icon,
|
||||
clickable: () => {
|
||||
new tabConstructor(this.slider, true).open();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
rows.push(
|
||||
this.devicesRow = new Row({
|
||||
titleLangKey: 'Devices',
|
||||
titleRightSecondary: ' ',
|
||||
icon: 'activesessions',
|
||||
clickable: async() => {
|
||||
if(!this.authorizations) {
|
||||
await this.updateActiveSessions();
|
||||
}
|
||||
|
||||
const tab = new AppActiveSessionsTab(this.slider);
|
||||
tab.authorizations = this.authorizations;
|
||||
tab.eventListener.addEventListener('destroy', () => {
|
||||
this.authorizations = undefined;
|
||||
this.updateActiveSessions(true);
|
||||
}, {once: true});
|
||||
tab.open();
|
||||
}
|
||||
}),
|
||||
|
||||
this.languageRow = new Row({
|
||||
titleLangKey: 'AccountSettings.Language',
|
||||
titleRightSecondary: i18n('LanguageName'),
|
||||
icon: 'language',
|
||||
clickable: () => {
|
||||
new AppLanguageTab(this.slider).open();
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
this.scrollable.append(this.avatarElem, this.nameDiv, this.phoneDiv, buttonsDiv);
|
||||
this.scrollable.container.classList.add('profile-content-wrapper');
|
||||
buttonsDiv.append(...rows.map(row => row.container));
|
||||
|
||||
// const profileSection = new SettingSection({fullWidth: true, noPaddingTop: true});
|
||||
// profileSection.content.append(this.profile.element);
|
||||
|
||||
const buttonsSection = new SettingSection();
|
||||
buttonsSection.content.append(buttonsDiv);
|
||||
|
||||
this.scrollable.append(this.profile.element/* profileSection.container */, buttonsSection.container);
|
||||
|
||||
/* rootScope.$on('user_auth', (e) => {
|
||||
this.fillElements();
|
||||
@ -139,41 +201,28 @@ export default class AppSettingsTab extends SliderSuperTab {
|
||||
tab.open();
|
||||
});
|
||||
|
||||
this.buttons.folders.addEventListener('click', () => {
|
||||
new AppChatFoldersTab(this.slider).open();
|
||||
});
|
||||
|
||||
this.buttons.general.addEventListener('click', () => {
|
||||
new AppGeneralSettingsTab(this.slider).open();
|
||||
});
|
||||
|
||||
this.buttons.storage.addEventListener('click', () => {
|
||||
new AppDataAndStorageTab(this.slider).open();
|
||||
});
|
||||
|
||||
this.buttons.notifications.addEventListener('click', () => {
|
||||
new AppNotificationsTab(this.slider).open();
|
||||
});
|
||||
|
||||
this.buttons.privacy.addEventListener('click', () => {
|
||||
new AppPrivacyAndSecurityTab(this.slider).open();
|
||||
});
|
||||
|
||||
this.buttons.language.addEventListener('click', () => {
|
||||
new AppLanguageTab(this.slider).open();
|
||||
});
|
||||
|
||||
lottieLoader.loadLottieWorkers();
|
||||
|
||||
this.fillElements();
|
||||
this.updateActiveSessions();
|
||||
}
|
||||
|
||||
public fillElements() {
|
||||
const user = appUsersManager.getSelf();
|
||||
const peerId = user.id.toPeerId(false);
|
||||
this.avatarElem.setAttribute('peer', '' + peerId);
|
||||
private getAuthorizations(overwrite?: boolean) {
|
||||
if(this.getAuthorizationsPromise && !overwrite) return this.getAuthorizationsPromise;
|
||||
|
||||
this.nameDiv.append(new PeerTitle({peerId: peerId}).element);
|
||||
this.phoneDiv.innerHTML = user.phone ? appUsersManager.formatUserPhone(user.phone) : '';
|
||||
const promise = this.getAuthorizationsPromise = apiManager.invokeApi('account.getAuthorizations')
|
||||
.finally(() => {
|
||||
if(this.getAuthorizationsPromise === promise) {
|
||||
this.getAuthorizationsPromise = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
public updateActiveSessions(overwrite?: boolean) {
|
||||
return this.getAuthorizations(overwrite).then(auths => {
|
||||
this.authorizations = auths.authorizations;
|
||||
this.devicesRow.titleRight.textContent = '' + this.authorizations.length;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -666,7 +666,7 @@ const lang = {
|
||||
"AutoDownloadPm": "PM",
|
||||
"AutoDownloadGroups": "Groups",
|
||||
"AutoDownloadChannels": "Channels",
|
||||
"AutoDownloadAudioInfo": "Voice messages are tiny, so they\'re always downloaded automatically.",
|
||||
"AutoDownloadAudioInfo": "Voice messages are tiny, so they're always downloaded automatically.",
|
||||
"AutoplayMedia": "Auto-play media",
|
||||
"AutoDownloadPhotosTitle": "Auto-download photos",
|
||||
"AutoDownloadVideosTitle": "Auto-download videos and GIFs",
|
||||
@ -677,6 +677,9 @@ const lang = {
|
||||
"ResetAutomaticMediaDownloadAlertTitle": "Reset settings",
|
||||
"ResetAutomaticMediaDownloadAlert": "Are you sure you want to reset auto-download settings?",
|
||||
"Reset": "Reset",
|
||||
"SendMessageAsTitle": "Send message as...",
|
||||
"Devices": "Devices",
|
||||
"LanguageName": "English",
|
||||
|
||||
// * macos
|
||||
"AccountSettings.Filters": "Chat Folders",
|
||||
@ -811,6 +814,7 @@ const lang = {
|
||||
"Chat.Send.WithoutSound": "Send Without Sound",
|
||||
"Chat.Send.SetReminder": "Set a Reminder",
|
||||
"Chat.Send.ScheduledMessage": "Schedule Message",
|
||||
"Chat.SendAs.PersonalAccount": "personal account",
|
||||
"Chat.UnpinAllMessagesConfirmation": {
|
||||
"one_value": "Do you want to unpin %d message in this chat?",
|
||||
"other_value": "Do you want to unpin all %d messages in this chat?"
|
||||
|
@ -12,7 +12,7 @@
|
||||
import { MOUNT_CLASS_TO } from "../../config/debug";
|
||||
import { isObject, safeReplaceObject, copy, deepEqual } from "../../helpers/object";
|
||||
import { isRestricted } from "../../helpers/restrictions";
|
||||
import { ChannelParticipant, Chat, ChatAdminRights, ChatBannedRights, ChatParticipant, ChatPhoto, InputChannel, InputChatPhoto, InputFile, InputPeer, Update, Updates, ChannelsCreateChannel } from "../../layer";
|
||||
import { ChannelParticipant, Chat, ChatAdminRights, ChatBannedRights, ChatParticipant, ChatPhoto, InputChannel, InputChatPhoto, InputFile, InputPeer, Update, Updates, ChannelsCreateChannel, Peer } from "../../layer";
|
||||
import apiManagerProxy from "../mtproto/mtprotoworker";
|
||||
import apiManager from '../mtproto/mtprotoworker';
|
||||
import { RichTextProcessor } from "../richtextprocessor";
|
||||
@ -787,6 +787,21 @@ export class AppChatsManager {
|
||||
|
||||
return !!(chat.pFlags.restricted && restrictionReasons && isRestricted(restrictionReasons));
|
||||
}
|
||||
|
||||
public getSendAs(channelId: ChatId) {
|
||||
return apiManager.invokeApiSingleProcess({
|
||||
method: 'channels.getSendAs',
|
||||
params: {
|
||||
peer: this.getChannelInputPeer(channelId)
|
||||
},
|
||||
processResult: (sendAsPeers) => {
|
||||
appUsersManager.saveApiUsers(sendAsPeers.users);
|
||||
appChatsManager.saveApiChats(sendAsPeers.chats);
|
||||
|
||||
return sendAsPeers.peers;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const appChatsManager = new AppChatsManager();
|
||||
|
@ -15,7 +15,7 @@ import { ripple } from "../../components/ripple";
|
||||
//import Scrollable from "../../components/scrollable";
|
||||
import Scrollable, { ScrollableX, SliceSides } from "../../components/scrollable";
|
||||
import { formatDateAccordingToTodayNew } from "../../helpers/date";
|
||||
import { IS_SAFARI } from "../../environment/userAgent";
|
||||
import { IS_MOBILE_SAFARI, IS_SAFARI } from "../../environment/userAgent";
|
||||
import { logger, LogTypes } from "../logger";
|
||||
import { RichTextProcessor } from "../richtextprocessor";
|
||||
import rootScope from "../rootScope";
|
||||
@ -59,6 +59,7 @@ import groupCallActiveIcon from "../../components/groupCallActiveIcon";
|
||||
import { Chat } from "../../layer";
|
||||
import IS_GROUP_CALL_SUPPORTED from "../../environment/groupCallSupport";
|
||||
import mediaSizes from "../../helpers/mediaSizes";
|
||||
import appNavigationController, { NavigationItem } from "../../components/appNavigationController";
|
||||
|
||||
export type DialogDom = {
|
||||
avatarEl: AvatarElement,
|
||||
@ -181,6 +182,8 @@ export class AppDialogsManager {
|
||||
private emptyDialogsPlaceholderSubtitle: I18n.IntlElement;
|
||||
private updateContactsLengthPromise: Promise<number>;
|
||||
|
||||
private filtersNavigationItem: NavigationItem;
|
||||
|
||||
constructor() {
|
||||
this.chatsPreloader = putPreloader(null, true);
|
||||
|
||||
@ -298,6 +301,25 @@ export class AppDialogsManager {
|
||||
|
||||
id = +tabContent.dataset.filterId || 0;
|
||||
|
||||
if(!IS_MOBILE_SAFARI) {
|
||||
if(id) {
|
||||
if(!this.filtersNavigationItem) {
|
||||
this.filtersNavigationItem = {
|
||||
type: 'filters',
|
||||
onPop: () => {
|
||||
selectTab(0);
|
||||
this.filtersNavigationItem = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
appNavigationController.unshiftItem(this.filtersNavigationItem);
|
||||
}
|
||||
} else if(this.filtersNavigationItem) {
|
||||
appNavigationController.removeItem(this.filtersNavigationItem);
|
||||
this.filtersNavigationItem = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if(this.filterId === id) return;
|
||||
|
||||
this.sortedLists[id].clear();
|
||||
|
@ -1793,7 +1793,7 @@ export class AppImManager {
|
||||
}
|
||||
}
|
||||
|
||||
public async getPeerStatus(peerId: PeerId) {
|
||||
public async getPeerStatus(peerId: PeerId, ignoreSelf?: boolean) {
|
||||
let subtitle: HTMLElement;
|
||||
if(!peerId) return;
|
||||
|
||||
@ -1828,7 +1828,7 @@ export class AppImManager {
|
||||
} else { // user
|
||||
const user = appUsersManager.getUser(peerId);
|
||||
|
||||
if(rootScope.myId === peerId) {
|
||||
if(rootScope.myId === peerId && !ignoreSelf) {
|
||||
return;
|
||||
} else if(user) {
|
||||
subtitle = appUsersManager.getUserStatusString(user.id);
|
||||
@ -1851,7 +1851,7 @@ export class AppImManager {
|
||||
}
|
||||
}
|
||||
|
||||
public setPeerStatus(peerId: PeerId, element: HTMLElement, needClear: boolean, useWhitespace: boolean, middleware: () => boolean) {
|
||||
public setPeerStatus(peerId: PeerId, element: HTMLElement, needClear: boolean, useWhitespace: boolean, middleware: () => boolean, ignoreSelf?: boolean) {
|
||||
if(needClear) {
|
||||
element.innerHTML = useWhitespace ? '' : ''; // ! HERE U CAN FIND WHITESPACE
|
||||
}
|
||||
@ -1862,7 +1862,7 @@ export class AppImManager {
|
||||
return;
|
||||
}
|
||||
|
||||
this.getPeerStatus(peerId).then((subtitle) => {
|
||||
this.getPeerStatus(peerId, ignoreSelf).then((subtitle) => {
|
||||
if(!middleware()) {
|
||||
return;
|
||||
}
|
||||
|
@ -279,6 +279,7 @@ export class AppInlineBotsManager {
|
||||
clearDraft: true,
|
||||
scheduleDate: number,
|
||||
silent: true,
|
||||
sendAsPeerId: PeerId,
|
||||
geoPoint: GeoPoint
|
||||
}> = {}) {
|
||||
const inlineResult = this.inlineResults[queryAndResultIds];
|
||||
|
@ -449,7 +449,8 @@ export class AppMessagesManager {
|
||||
clearDraft: true,
|
||||
webPage: WebPage,
|
||||
scheduleDate: number,
|
||||
silent: true
|
||||
silent: true,
|
||||
sendAsPeerId: PeerId,
|
||||
}> = {}) {
|
||||
if(!text.trim()) {
|
||||
return Promise.resolve();
|
||||
@ -520,6 +521,7 @@ export class AppMessagesManager {
|
||||
sentRequestOptions.afterMessageId = this.pendingAfterMsgs[peerId].messageId;
|
||||
}
|
||||
|
||||
const sendAs = options.sendAsPeerId ? appPeersManager.getInputPeerById(options.sendAsPeerId) : undefined
|
||||
let apiPromise: any;
|
||||
if(options.viaBotId) {
|
||||
apiPromise = apiManager.invokeApiAfter('messages.sendInlineBotResult', {
|
||||
@ -528,7 +530,8 @@ export class AppMessagesManager {
|
||||
reply_to_msg_id: replyToMsgId || undefined,
|
||||
query_id: options.queryId,
|
||||
id: options.resultId,
|
||||
clear_draft: options.clearDraft
|
||||
clear_draft: options.clearDraft,
|
||||
send_as: sendAs
|
||||
}, sentRequestOptions);
|
||||
} else {
|
||||
apiPromise = apiManager.invokeApiAfter('messages.sendMessage', {
|
||||
@ -540,7 +543,8 @@ export class AppMessagesManager {
|
||||
entities: sendEntites,
|
||||
clear_draft: options.clearDraft,
|
||||
schedule_date: options.scheduleDate || undefined,
|
||||
silent: options.silent
|
||||
silent: options.silent,
|
||||
send_as: sendAs
|
||||
}, sentRequestOptions);
|
||||
}
|
||||
|
||||
@ -633,6 +637,7 @@ export class AppMessagesManager {
|
||||
isMedia: true,
|
||||
|
||||
replyToMsgId: number,
|
||||
sendAsPeerId: PeerId,
|
||||
threadId: number,
|
||||
groupId: string,
|
||||
caption: string,
|
||||
@ -1026,7 +1031,8 @@ export class AppMessagesManager {
|
||||
schedule_date: options.scheduleDate,
|
||||
silent: options.silent,
|
||||
entities,
|
||||
clear_draft: options.clearDraft
|
||||
clear_draft: options.clearDraft,
|
||||
send_as: options.sendAsPeerId ? appPeersManager.getInputPeerById(options.sendAsPeerId) : undefined
|
||||
}).then((updates) => {
|
||||
apiUpdatesManager.processUpdateMessage(updates);
|
||||
}, (error) => {
|
||||
@ -1055,6 +1061,7 @@ export class AppMessagesManager {
|
||||
isMedia: true,
|
||||
entities: MessageEntity[],
|
||||
replyToMsgId: number,
|
||||
sendAsPeerId: PeerId,
|
||||
threadId: number,
|
||||
caption: string,
|
||||
sendFileDetails: Partial<{
|
||||
@ -1101,6 +1108,7 @@ export class AppMessagesManager {
|
||||
silent: options.silent,
|
||||
replyToMsgId,
|
||||
threadId: options.threadId,
|
||||
sendAsPeerId: options.sendAsPeerId,
|
||||
groupId,
|
||||
...details
|
||||
};
|
||||
@ -1146,7 +1154,8 @@ export class AppMessagesManager {
|
||||
reply_to_msg_id: replyToMsgId,
|
||||
schedule_date: options.scheduleDate,
|
||||
silent: options.silent,
|
||||
clear_draft: options.clearDraft
|
||||
clear_draft: options.clearDraft,
|
||||
send_as: options.sendAsPeerId ? appPeersManager.getInputPeerById(options.sendAsPeerId) : undefined
|
||||
}).then((updates) => {
|
||||
apiUpdatesManager.processUpdateMessage(updates);
|
||||
deferred.resolve();
|
||||
@ -1222,7 +1231,8 @@ export class AppMessagesManager {
|
||||
resultId: string,
|
||||
scheduleDate: number,
|
||||
silent: true,
|
||||
geoPoint: GeoPoint
|
||||
geoPoint: GeoPoint,
|
||||
sendAsPeerId: PeerId,
|
||||
}> = {}) {
|
||||
peerId = appPeersManager.getPeerMigratedTo(peerId) || peerId;
|
||||
|
||||
@ -1337,6 +1347,7 @@ export class AppMessagesManager {
|
||||
sentRequestOptions.afterMessageId = this.pendingAfterMsgs[peerId].messageId;
|
||||
}
|
||||
|
||||
const sendAs = options.sendAsPeerId ? appPeersManager.getInputPeerById(options.sendAsPeerId) : undefined;
|
||||
let apiPromise: Promise<any>;
|
||||
if(options.viaBotId) {
|
||||
apiPromise = apiManager.invokeApiAfter('messages.sendInlineBotResult', {
|
||||
@ -1347,7 +1358,8 @@ export class AppMessagesManager {
|
||||
id: options.resultId,
|
||||
clear_draft: options.clearDraft,
|
||||
schedule_date: options.scheduleDate,
|
||||
silent: options.silent
|
||||
silent: options.silent,
|
||||
send_as: sendAs
|
||||
}, sentRequestOptions);
|
||||
} else {
|
||||
apiPromise = apiManager.invokeApiAfter('messages.sendMedia', {
|
||||
@ -1358,7 +1370,8 @@ export class AppMessagesManager {
|
||||
message: '',
|
||||
clear_draft: options.clearDraft,
|
||||
schedule_date: options.scheduleDate,
|
||||
silent: options.silent
|
||||
silent: options.silent,
|
||||
send_as: sendAs
|
||||
}, sentRequestOptions);
|
||||
}
|
||||
|
||||
@ -1463,6 +1476,7 @@ export class AppMessagesManager {
|
||||
private generateOutgoingMessage(peerId: PeerId, options: Partial<{
|
||||
scheduleDate: number,
|
||||
replyToMsgId: number,
|
||||
sendAsPeerId: PeerId,
|
||||
threadId: number,
|
||||
viaBotId: BotId,
|
||||
groupId: string,
|
||||
@ -1486,7 +1500,7 @@ export class AppMessagesManager {
|
||||
const message: Message.message = {
|
||||
_: 'message',
|
||||
id: this.generateTempMessageId(peerId),
|
||||
from_id: this.generateFromId(peerId),
|
||||
from_id: options.sendAsPeerId ? appPeersManager.getOutputPeer(options.sendAsPeerId) : this.generateFromId(peerId),
|
||||
peer_id: appPeersManager.getOutputPeer(peerId),
|
||||
post_author: postAuthor,
|
||||
pFlags: this.generateFlags(peerId),
|
||||
@ -1937,7 +1951,8 @@ export class AppMessagesManager {
|
||||
silent: true,
|
||||
scheduleDate: number,
|
||||
dropAuthor: boolean,
|
||||
dropCaptions: boolean
|
||||
dropCaptions: boolean,
|
||||
sendAsPeerId: PeerId,
|
||||
}> = {}) {
|
||||
peerId = appPeersManager.getPeerMigratedTo(peerId) || peerId;
|
||||
mids = mids.slice().sort((a, b) => a - b);
|
||||
@ -2044,7 +2059,8 @@ export class AppMessagesManager {
|
||||
silent: options.silent,
|
||||
schedule_date: options.scheduleDate,
|
||||
drop_author: options.dropAuthor,
|
||||
drop_media_captions: options.dropCaptions
|
||||
drop_media_captions: options.dropCaptions,
|
||||
send_as: options.sendAsPeerId ? appPeersManager.getInputPeerById(options.sendAsPeerId) : undefined
|
||||
}, sentRequestOptions).then((updates) => {
|
||||
this.log('forwardMessages updates:', updates);
|
||||
apiUpdatesManager.processUpdateMessage(updates);
|
||||
@ -5047,6 +5063,8 @@ export class AppMessagesManager {
|
||||
this.dialogsStorage.dropDialogOnDeletion(peerId);
|
||||
}
|
||||
}
|
||||
|
||||
rootScope.dispatchEvent('channel_update', channelId);
|
||||
};
|
||||
|
||||
private onUpdateChannelReload = (update: Update.updateChannelReload) => {
|
||||
|
@ -121,6 +121,10 @@ export class AppProfileManager {
|
||||
}
|
||||
});
|
||||
|
||||
rootScope.addEventListener('channel_update', (chatId) => {
|
||||
this.refreshFullPeer(chatId.toPeerId(true));
|
||||
});
|
||||
|
||||
// * genius
|
||||
rootScope.addEventListener('chat_full_update', (chatId) => {
|
||||
rootScope.dispatchEvent('peer_full_update', chatId.toPeerId(true));
|
||||
@ -477,10 +481,15 @@ export class AppProfileManager {
|
||||
}
|
||||
|
||||
private refreshFullPeer(peerId: PeerId) {
|
||||
if(peerId.isUser()) delete this.usersFull[peerId.toUserId()];
|
||||
else delete this.chatsFull[peerId.toChatId()];
|
||||
|
||||
rootScope.dispatchEvent('peer_full_update', peerId);
|
||||
if(peerId.isUser()) {
|
||||
const userId = peerId.toUserId();
|
||||
delete this.usersFull[userId];
|
||||
rootScope.dispatchEvent('user_full_update', userId);
|
||||
} else {
|
||||
const chatId = peerId.toChatId();
|
||||
delete this.chatsFull[chatId];
|
||||
rootScope.dispatchEvent('chat_full_update', chatId);
|
||||
}
|
||||
|
||||
// ! эта строчка будет создавать race condition:
|
||||
// ! запрос вернёт chat с установленным флагом call_not_empty, хотя сам апдейт уже будет применён
|
||||
|
@ -29,6 +29,8 @@ export type BroadcastEvents = {
|
||||
'chat_full_update': ChatId,
|
||||
'chat_update': ChatId,
|
||||
|
||||
'channel_update': ChatId,
|
||||
|
||||
'user_update': UserId,
|
||||
'user_auth': UserAuth,
|
||||
'user_full_update': UserId,
|
||||
|
@ -12,8 +12,6 @@
|
||||
"FilterAllNonContacts" = "All Non-Contacts";
|
||||
"FilterAllChannels" = "All Channels";
|
||||
"FilterAllBots" = "All Bots";
|
||||
"WordDelimiter" = ", ";
|
||||
"WordDelimiterLast" = " and ";
|
||||
"EditContact.OriginalName" = "original name";
|
||||
"EditProfile.FirstNameLabel" = "Name";
|
||||
"EditProfile.BioLabel" = "Bio (optional)";
|
||||
@ -55,7 +53,6 @@
|
||||
"General.SendShortcut.CtrlEnter" = "Send by %s + Enter";
|
||||
"General.SendShortcut.NewLine.ShiftEnter" = "New line by Shift + Enter";
|
||||
"General.SendShortcut.NewLine.Enter" = "New line by Enter";
|
||||
"General.AutoplayMedia" = "Auto-Play Media";
|
||||
"General.TimeFormat" = "Time Format";
|
||||
"General.TimeFormat.h12" = "12-hour";
|
||||
"General.TimeFormat.h23" = "24-hour";
|
||||
@ -564,6 +561,44 @@
|
||||
"RequestToJoinSent" = "Join request sent";
|
||||
"RequestToJoinGroupApproved" = "Your request to join the group was approved";
|
||||
"RequestToJoinChannelApproved" = "Your request to join the channel was approved";
|
||||
"Update" = "UPDATE";
|
||||
"Reactions" = "Reactions";
|
||||
"DoubleTapSetting" = "Quick Reaction";
|
||||
"EnableReactions" = "Enable Reactions";
|
||||
"EnableReactionsChannelInfo" = "Allow subscribers to react to channel posts.";
|
||||
"EnableReactionsGroupInfo" = "Allow members to react to group messages.";
|
||||
"AvailableReactions" = "Available reactions";
|
||||
"NobodyViewed" = "Nobody viewed";
|
||||
"MessageSeen_one" = "Seen";
|
||||
"MessageSeen_other" = "%1$d Seen";
|
||||
"DataSettings" = "Data and Storage";
|
||||
"GroupsAndChannelsHelp" = "Change who can add you to groups and channels.";
|
||||
"SessionsInfo" = "Control your sessions on other devices.";
|
||||
"StickersBotInfo" = "Artists are welcome to add their own sticker sets using our @stickers bot.";
|
||||
"AutomaticMediaDownload" = "Automatic media download";
|
||||
"AutoDownloadPhotos" = "Photos";
|
||||
"AutoDownloadVideos" = "Videos";
|
||||
"AutoDownloadFiles" = "Files";
|
||||
"AutoDownloadOnAllChats" = "On in all chats";
|
||||
"AutoDownloadUpToOnAllChats" = "Up to %1$s in all chats";
|
||||
"AutoDownloadOff" = "Off";
|
||||
"AutoDownloadOnUpToFor" = "Up to %1$s for %2$s";
|
||||
"AutoDownloadOnFor" = "On for %1$s";
|
||||
"AutoDownloadContacts" = "Contacts";
|
||||
"AutoDownloadPm" = "PM";
|
||||
"AutoDownloadGroups" = "Groups";
|
||||
"AutoDownloadChannels" = "Channels";
|
||||
"AutoDownloadAudioInfo" = "Voice messages are tiny, so they're always downloaded automatically.";
|
||||
"AutoplayMedia" = "Auto-play media";
|
||||
"AutoDownloadPhotosTitle" = "Auto-download photos";
|
||||
"AutoDownloadVideosTitle" = "Auto-download videos and GIFs";
|
||||
"AutoDownloadFilesTitle" = "Auto-download files and music";
|
||||
"AutoDownloadMaxFileSize" = "Maximum file size";
|
||||
"AutodownloadSizeLimitUpTo" = "up to %1$s";
|
||||
"ResetAutomaticMediaDownload" = "Reset Auto-Download Settings";
|
||||
"ResetAutomaticMediaDownloadAlertTitle" = "Reset settings";
|
||||
"ResetAutomaticMediaDownloadAlert" = "Are you sure you want to reset auto-download settings?";
|
||||
"Reset" = "Reset";
|
||||
"AccountSettings.Filters" = "Chat Folders";
|
||||
"AccountSettings.Notifications" = "Notifications and Sounds";
|
||||
"AccountSettings.PrivacyAndSecurity" = "Privacy and Security";
|
||||
@ -571,6 +606,8 @@
|
||||
"Alert.UserDoesntExists" = "Sorry, this user doesn't seem to exist.";
|
||||
"Alert.Confirm.Discard" = "Discard";
|
||||
"Appearance.Reset" = "Reset to Defaults";
|
||||
"AutoDownloadSettings.Delimeter" = ", ";
|
||||
"AutoDownloadSettings.LastDelimeter" = " and ";
|
||||
"Bio.Description" = "Any details such as age, occupation or city.\nExample: 23 y.o. designer from San Francisco";
|
||||
"Call.Accept" = "Accept";
|
||||
"Call.Decline" = "Decline";
|
||||
@ -614,6 +651,8 @@
|
||||
"Chat.Alert.Forward.Action.HideCaption_other" = "Hide Captions";
|
||||
"Chat.CopySelectedText" = "Copy Selected Text";
|
||||
"Chat.Confirm.Unpin" = "Would you like to unpin this message?";
|
||||
"Chat.Context.Reacted" = "%1$@/%2$@ Reacted";
|
||||
"Chat.Context.ReactedFast_other" = "%d Reacted";
|
||||
"Chat.Date.ScheduledFor" = "Scheduled for %@";
|
||||
"Chat.Date.ScheduledForToday" = "Scheduled for today";
|
||||
"Chat.DropTitle" = "Drop files here to send them";
|
||||
@ -708,6 +747,12 @@
|
||||
"ChatList.Filter.Exclude.LimitReached" = "Sorry, you can only add up to 100 individual chats. Try using chat types.";
|
||||
"ChatList.Filter.Confirm.Remove.Header" = "Remove Folder";
|
||||
"ChatList.Filter.Confirm.Remove.Text" = "Are you sure you want to remove this folder? Your chats will not be deleted.";
|
||||
"ChatList.Mute.1Hour" = "For 1 Hour";
|
||||
"ChatList.Mute.4Hours" = "For 4 Hours";
|
||||
"ChatList.Mute.8Hours" = "For 8 Hours";
|
||||
"ChatList.Mute.1Day" = "For 1 Day";
|
||||
"ChatList.Mute.3Days" = "For 3 Days";
|
||||
"ChatList.Mute.Forever" = "Forever";
|
||||
"Channel.DescriptionHolderDescrpiton" = "You can provide an optional description for your channel.";
|
||||
"CreateGroup.NameHolder" = "Group Name";
|
||||
"Date.Today" = "Today";
|
||||
@ -724,20 +769,26 @@
|
||||
"Emoji.TravelAndPlaces" = "Travel & Places";
|
||||
"Emoji.Objects" = "Objects";
|
||||
"Emoji.Flags" = "Flags";
|
||||
"FileSize.B" = "%@ B";
|
||||
"FileSize.KB" = "%@ KB";
|
||||
"FileSize.MB" = "%@ MB";
|
||||
"FileSize.GB" = "%@ GB";
|
||||
"InstalledStickers.LoopAnimated" = "Loop Animated Stickers";
|
||||
"LastSeen.HoursAgo_one" = "last seen %d hour ago";
|
||||
"LastSeen.HoursAgo_other" = "last seen %d hours ago";
|
||||
"Login.Register.LastName.Placeholder" = "Last Name";
|
||||
"Message.Context.Select" = "Select";
|
||||
"Message.Context.Pin" = "Pin";
|
||||
"Message.Context.Unpin" = "Unpin";
|
||||
"Message.Context.Goto" = "Show Message";
|
||||
"MessageContext.CopyMessageLink1" = "Copy Message Link";
|
||||
"Modal.Send" = "Send";
|
||||
"Telegram.GeneralSettingsViewController" = "General Settings";
|
||||
"Telegram.InstalledStickerPacksController" = "Stickers";
|
||||
"Telegram.NotificationSettingsViewController" = "Notifications";
|
||||
"Telegram.LanguageViewController" = "Language";
|
||||
"Stickers.SearchAdd" = "Add";
|
||||
"Stickers.SearchAdded" = "Added";
|
||||
"Stickers.SuggestStickers" = "Suggest Stickers by Emoji";
|
||||
"ShareModal.Search.Placeholder" = "Share to...";
|
||||
"ShareModal.Search.ForwardPlaceholder" = "Forward to...";
|
||||
"InstalledStickers.LoopAnimated" = "Loop Animated Stickers";
|
||||
"NewPoll.Anonymous" = "Anonymous Voting";
|
||||
"NewPoll.Explanation.Placeholder" = "Add a Comment (Optional)";
|
||||
"NewPoll.OptionsAddOption" = "Add an Option";
|
||||
"NewPoll.MultipleChoice" = "Multiple Answers";
|
||||
"NewPoll.Quiz" = "Quiz Mode";
|
||||
"Notification.Contact.Reacted" = "%1$@ to your \"%2$@\"";
|
||||
"Peer.Activity.User.PlayingGame" = "playing a game";
|
||||
"Peer.Activity.User.TypingText" = "typing";
|
||||
"Peer.Activity.User.SendingPhoto" = "sending a photo";
|
||||
@ -746,6 +797,7 @@
|
||||
"Peer.Activity.User.RecordingAudio" = "recording voice";
|
||||
"Peer.Activity.User.SendingFile" = "sending file";
|
||||
"Peer.Activity.User.ChoosingSticker" = "choosing a sticker";
|
||||
"Peer.Activity.User.EnjoyingAnimations" = "watching %@";
|
||||
"Peer.Activity.Chat.PlayingGame" = "%@ is playing a game";
|
||||
"Peer.Activity.Chat.TypingText" = "%@ is typing";
|
||||
"Peer.Activity.Chat.SendingPhoto" = "%@ is sending a photo";
|
||||
@ -754,6 +806,7 @@
|
||||
"Peer.Activity.Chat.RecordingAudio" = "%@ is recording voice";
|
||||
"Peer.Activity.Chat.SendingFile" = "%@ is sending a file";
|
||||
"Peer.Activity.Chat.ChoosingSticker" = "%@ is choosing a sticker";
|
||||
"Peer.Activity.Chat.EnjoyingAnimations" = "%@ is watching %@";
|
||||
"Peer.Activity.Chat.Multi.PlayingGame1" = "%@ and %d others are playing a game";
|
||||
"Peer.Activity.Chat.Multi.TypingText1" = "%@ and %d others are typing";
|
||||
"Peer.Activity.Chat.Multi.SendingPhoto1" = "%@ and %d others are sending photos";
|
||||
@ -824,16 +877,15 @@
|
||||
"PrivacySettingsController.UserCount_other" = "%d users";
|
||||
"RecentSessions.Error.FreshReset" = "For security reasons, you can't terminate older sessions from a device that you've just connected. Please use an earlier connection or wait for a few hours.";
|
||||
"RequestJoin.Button" = "Request to Join";
|
||||
"Message.Context.Select" = "Select";
|
||||
"Message.Context.Pin" = "Pin";
|
||||
"Message.Context.Unpin" = "Unpin";
|
||||
"Message.Context.Goto" = "Show Message";
|
||||
"MessageContext.CopyMessageLink1" = "Copy Message Link";
|
||||
"NewPoll.Anonymous" = "Anonymous Voting";
|
||||
"NewPoll.Explanation.Placeholder" = "Add a Comment (Optional)";
|
||||
"NewPoll.OptionsAddOption" = "Add an Option";
|
||||
"NewPoll.MultipleChoice" = "Multiple Answers";
|
||||
"NewPoll.Quiz" = "Quiz Mode";
|
||||
"Stickers.SearchAdd" = "Add";
|
||||
"Stickers.SearchAdded" = "Added";
|
||||
"Stickers.SuggestStickers" = "Suggest Stickers by Emoji";
|
||||
"ShareModal.Search.Placeholder" = "Share to...";
|
||||
"ShareModal.Search.ForwardPlaceholder" = "Forward to...";
|
||||
"Telegram.GeneralSettingsViewController" = "General Settings";
|
||||
"Telegram.InstalledStickerPacksController" = "Stickers";
|
||||
"Telegram.NotificationSettingsViewController" = "Notifications";
|
||||
"Telegram.LanguageViewController" = "Language";
|
||||
"GeneralSettings.BigEmoji" = "Large Emoji";
|
||||
"GeneralSettings.EmojiPrediction" = "Suggest Emoji";
|
||||
"GroupPermission.Delete" = "Delete Exception";
|
||||
@ -845,6 +897,24 @@
|
||||
"Schedule.SendDate" = "Send on %@ at %@";
|
||||
"Schedule.SendWhenOnline" = "Send When Online";
|
||||
"Stickers.Recent" = "Recent";
|
||||
"StickerSet.DontExist" = "Sorry, this sticker set doesn't seem to exist.";
|
||||
"Text.Context.Copy.Username" = "Copy Username";
|
||||
"Text.Context.Copy.Hashtag" = "Copy Hashtag";
|
||||
"Time.TomorrowAt" = "tomorrow at %@";
|
||||
"TwoStepAuth.SetPasswordHelp" = "You can set a password that will be required when you log in on a new device in addition to the code you get in the SMS.";
|
||||
"TwoStepAuth.GenericHelp" = "You have enabled Two-Step verification.\nYou'll need the password you set up here to log in to your Telegram account.";
|
||||
"TwoStepAuth.ChangePassword" = "Change Password";
|
||||
"TwoStepAuth.RemovePassword" = "Turn Password Off";
|
||||
"TwoStepAuth.SetupEmail" = "Set Recovery Email";
|
||||
"TwoStepAuth.ChangeEmail" = "Change Recovery Email";
|
||||
"TwoStepAuth.ConfirmEmailCodeDesc" = "Please enter the code we've just emailed to %@.";
|
||||
"TwoStepAuth.RecoveryTitle" = "Email Code";
|
||||
"TwoStepAuth.RecoveryCode" = "Code";
|
||||
"TwoStepAuth.RecoveryCodeInvalid" = "Invalid code. Please try again.";
|
||||
"TwoStepAuth.RecoveryCodeExpired" = "Code Expired";
|
||||
"TwoStepAuth.SetupHintTitle" = "Password Hint";
|
||||
"TwoStepAuth.SetupHintPlaceholder" = "Hint";
|
||||
"UsernameSettings.ChangeDescription" = "You can choose a username on Telegram. If you do, people will be able to find you by this username and contact you without needing your phone number.\n\n\nYou can use a-z, 0-9 and underscores. Minimum length is 5 characters.";
|
||||
"VoiceChat.Chat.StartNew" = "Video chat ended. Start a new one?";
|
||||
"VoiceChat.Chat.StartNew.OK" = "Start";
|
||||
"VoiceChat.Chat.Ended" = "Video chat ended.";
|
||||
@ -875,23 +945,6 @@
|
||||
"VoiceChat.RemovePeer.Confirm.Channel" = "Do you want to remove %1$@ from the channel?";
|
||||
"VoiceChat.RemovePeer.Confirm" = "Are you sure you want to remove %1$@ from the group?";
|
||||
"VoiceChat.RemovePeer.Confirm.OK" = "Remove";
|
||||
"Text.Context.Copy.Username" = "Copy Username";
|
||||
"Text.Context.Copy.Hashtag" = "Copy Hashtag";
|
||||
"Time.TomorrowAt" = "tomorrow at %@";
|
||||
"TwoStepAuth.SetPasswordHelp" = "You can set a password that will be required when you log in on a new device in addition to the code you get in the SMS.";
|
||||
"TwoStepAuth.GenericHelp" = "You have enabled Two-Step verification.\nYou'll need the password you set up here to log in to your Telegram account.";
|
||||
"TwoStepAuth.ChangePassword" = "Change Password";
|
||||
"TwoStepAuth.RemovePassword" = "Turn Password Off";
|
||||
"TwoStepAuth.SetupEmail" = "Set Recovery Email";
|
||||
"TwoStepAuth.ChangeEmail" = "Change Recovery Email";
|
||||
"TwoStepAuth.ConfirmEmailCodeDesc" = "Please enter the code we've just emailed to %@.";
|
||||
"TwoStepAuth.RecoveryTitle" = "Email Code";
|
||||
"TwoStepAuth.RecoveryCode" = "Code";
|
||||
"TwoStepAuth.RecoveryCodeInvalid" = "Invalid code. Please try again.";
|
||||
"TwoStepAuth.RecoveryCodeExpired" = "Code Expired";
|
||||
"TwoStepAuth.SetupHintTitle" = "Password Hint";
|
||||
"TwoStepAuth.SetupHintPlaceholder" = "Hint";
|
||||
"UsernameSettings.ChangeDescription" = "You can choose a username on Telegram. If you do, people will be able to find you by this username and contact you without needing your phone number.\n\n\nYou can use a-z, 0-9 and underscores. Minimum length is 5 characters.";
|
||||
"Login.Title" = "Sign in to Telegram";
|
||||
"Login.CountrySelectorLabel" = "Country";
|
||||
"Login.PhoneLabel" = "Phone Number";
|
||||
|
@ -205,7 +205,8 @@ avatar-element {
|
||||
|
||||
&.avatar-30 {
|
||||
--size: 30px;
|
||||
--multiplier: 1.8;
|
||||
// --multiplier: 1.8; // text won't be centered
|
||||
--multiplier: 1.6875;
|
||||
}
|
||||
|
||||
&.avatar-24 {
|
||||
|
@ -200,6 +200,10 @@
|
||||
&:before {
|
||||
color: var(--secondary-text-color);
|
||||
font-size: var(--icon-size);
|
||||
}
|
||||
|
||||
&-icon,
|
||||
&:before {
|
||||
margin-right: var(--icon-margin);
|
||||
position: relative;
|
||||
}
|
||||
@ -227,6 +231,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-subtitle {
|
||||
font-size: .875rem;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
&-header {
|
||||
color: var(--primary-color);
|
||||
height: 2rem;
|
||||
font-weight: 500;
|
||||
pointer-events: none !important;
|
||||
}
|
||||
|
||||
.stacked-avatars {
|
||||
--margin-right: -.6875rem;
|
||||
flex: 0 0 auto;
|
||||
|
@ -1018,19 +1018,6 @@ $background-transition-total-time: #{$input-transition-time - $background-transi
|
||||
background-color: var(--light-primary-color) !important;
|
||||
}
|
||||
|
||||
.btn-menu {
|
||||
right: calc(var(--padding-horizontal) * -1 - .125rem);
|
||||
bottom: calc(100% + 1.125rem);
|
||||
|
||||
@include respond-to(esg-bottom-new) {
|
||||
bottom: calc(100% + .875rem);
|
||||
}
|
||||
|
||||
&-item {
|
||||
padding: 0 38px 0 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&.btn-disabled {
|
||||
opacity: var(--disabled-opacity);
|
||||
}
|
||||
@ -1175,10 +1162,123 @@ $background-transition-total-time: #{$input-transition-time - $background-transi
|
||||
}
|
||||
|
||||
.new-message-wrapper {
|
||||
--button-size: 2.125rem;
|
||||
--button-horizontal-margin: .125rem;
|
||||
--send-as-size: 1.875rem;
|
||||
--send-as-margin-left: .25rem;
|
||||
--send-as-margin-right: .375rem;
|
||||
--send-as-total-size: calc(var(--send-as-size) + var(--send-as-margin-left) + var(--send-as-margin-right));
|
||||
//padding: 4.5px 0;
|
||||
//padding-bottom: 4.5px;
|
||||
align-items: flex-end;
|
||||
min-height: var(--chat-input-size);
|
||||
|
||||
.new-message-send-as {
|
||||
&-container {
|
||||
width: var(--send-as-size);
|
||||
height: var(--send-as-size);
|
||||
position: absolute;
|
||||
flex: 0 0 auto;
|
||||
// margin: 0 0.375rem .4375rem var(--send-as-margin-left);
|
||||
margin: 0 0 .4375rem var(--send-as-margin-left);
|
||||
cursor: pointer;
|
||||
transform: scale(0);
|
||||
background: none !important;
|
||||
|
||||
.btn-menu-item-icon {
|
||||
margin-right: calc(var(--icon-margin) - .5rem);
|
||||
|
||||
&.active:before {
|
||||
--offset: -.25rem;
|
||||
content: " ";
|
||||
position: absolute;
|
||||
top: var(--offset);
|
||||
right: var(--offset);
|
||||
bottom: var(--offset);
|
||||
left: var(--offset);
|
||||
border: .125rem solid var(--primary-color);
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-avatar {
|
||||
position: absolute;
|
||||
transform: scale(0);
|
||||
opacity: 0;
|
||||
|
||||
&.is-visible {
|
||||
&:not(.backwards) {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&.animating {
|
||||
transition: transform var(--transition-standard-in), opacity var(--transition-standard-in);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-close {
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
background-color: var(--primary-color);
|
||||
font-size: 1.375rem;
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.has-send-as {
|
||||
.toggle-emoticons,
|
||||
.input-message-container {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
&:not(.backwards) {
|
||||
.toggle-emoticons {
|
||||
transform: translateX(var(--send-as-total-size));
|
||||
}
|
||||
|
||||
.input-message-container {
|
||||
--translateX: calc(var(--send-as-total-size));
|
||||
padding-right: var(--translateX);
|
||||
transform: translate(var(--translateX));
|
||||
}
|
||||
|
||||
.new-message-send-as-container {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
&.animating {
|
||||
.toggle-emoticons,
|
||||
.input-message-container,
|
||||
.new-message-send-as-container {
|
||||
transition: transform var(--transition-standard-in);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-menu {
|
||||
bottom: calc(100% + 1.125rem);
|
||||
|
||||
@include respond-to(esg-bottom-new) {
|
||||
bottom: calc(100% + .875rem);
|
||||
}
|
||||
|
||||
&.top-left {
|
||||
right: calc(var(--padding-horizontal) * -1 - .125rem);
|
||||
}
|
||||
|
||||
&.top-right {
|
||||
left: calc(var(--padding-horizontal) * -1 - .125rem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input-message-container {
|
||||
@ -1199,14 +1299,14 @@ $background-transition-total-time: #{$input-transition-time - $background-transi
|
||||
|
||||
.btn-icon {
|
||||
flex: 0 0 auto;
|
||||
font-size: 24px;
|
||||
font-size: 1.5rem;
|
||||
color: var(--secondary-text-color);
|
||||
|
||||
// ! EXPERIMENTAL
|
||||
margin: 0 .125rem 5px;
|
||||
margin: 0 var(--button-horizontal-margin) 5px;
|
||||
padding: 0;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
width: var(--button-size);
|
||||
height: var(--button-size);
|
||||
|
||||
&.active {
|
||||
color: var(--primary-color);
|
||||
|
@ -584,21 +584,9 @@
|
||||
|
||||
.settings-container {
|
||||
.profile {
|
||||
&-button {
|
||||
@include respond-to(handhelds) {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-buttons {
|
||||
margin-top: 1.1875rem;
|
||||
width: 100%;
|
||||
padding: 0 .4375rem;
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
margin-top: .6875rem;
|
||||
padding: 0;
|
||||
}
|
||||
&-avatars-container {
|
||||
padding-bottom: 0;
|
||||
height: 15rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -851,6 +839,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.no-padding-top {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
padding-bottom: .5rem;
|
||||
}
|
||||
@ -876,6 +868,10 @@
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.full-width {
|
||||
margin: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&-name {
|
||||
@ -956,7 +952,6 @@
|
||||
#chats-archived-container,
|
||||
#contacts-container,
|
||||
.add-members-container,
|
||||
.settings-container,
|
||||
#search-private-container,
|
||||
#stickers-container,
|
||||
#poll-results-container,
|
||||
|
@ -214,7 +214,7 @@
|
||||
padding-left: 54px;
|
||||
} */
|
||||
|
||||
&-wrapper {
|
||||
/* &-wrapper {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -223,7 +223,7 @@
|
||||
@include respond-to(not-handhelds) {
|
||||
padding-top: 15px;
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
.sidebar-left-section {
|
||||
position: relative;
|
||||
@ -258,6 +258,21 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-button {
|
||||
@include respond-to(handhelds) {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-change-avatar {
|
||||
--size: 3.375rem;
|
||||
position: absolute !important;
|
||||
top: calc(var(--size) / -2);
|
||||
right: 1.25rem;
|
||||
transform: none;
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
&-container {
|
||||
> .scrollable {
|
||||
display: flex;
|
||||
|
@ -50,6 +50,10 @@
|
||||
&-right {
|
||||
flex: 0 0 auto !important;
|
||||
margin-left: 1rem;
|
||||
|
||||
&-secondary {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,7 @@
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
overflow: visible;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user