From a29a42cd44e7ac1cd857186d6dccb64f4e9cd1f7 Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Tue, 22 Feb 2022 14:40:02 +0200 Subject: [PATCH] Added 'Send as...' menu --- src/components/chat/bubbles.ts | 8 +-- src/components/chat/input.ts | 58 ++++++++++++++------- src/components/peerProfile.ts | 4 +- src/components/sidebarLeft/tabs/settings.ts | 20 ++++--- src/config/app.ts | 2 +- src/lang.ts | 2 + 6 files changed, 61 insertions(+), 33 deletions(-) diff --git a/src/components/chat/bubbles.ts b/src/components/chat/bubbles.ts index 809dc880..061e627f 100644 --- a/src/components/chat/bubbles.ts +++ b/src/components/chat/bubbles.ts @@ -3069,6 +3069,8 @@ export default class ChatBubbles { const isOut = our && (!fwdFrom || this.peerId !== rootScope.myId); let nameContainer: HTMLElement = bubbleContainer; + const canHideNameIfMedia = !message.viaBotId && message.fromId === rootScope.myId; + // media if(messageMedia/* && messageMedia._ === 'messageMediaPhoto' */) { let attachmentDiv = document.createElement('div'); @@ -3089,7 +3091,7 @@ export default class ChatBubbles { canHaveTail = false; } - if(!message.viaBotId) { + if(canHideNameIfMedia) { bubble.classList.add('hide-name'); } @@ -3333,7 +3335,7 @@ export default class ChatBubbles { canHaveTail = false; } - if(!message.viaBotId) { + if(canHideNameIfMedia) { bubble.classList.add('hide-name'); } @@ -3540,7 +3542,7 @@ export default class ChatBubbles { let savedFrom = ''; // const needName = ((peerId.isAnyChat() && (peerId !== message.fromId || our)) && message.fromId !== rootScope.myId) || message.viaBotId; - const needName = (message.fromId !== rootScope.myId && this.appPeersManager.isAnyChat(peerId) && !this.appPeersManager.isBroadcast(peerId)) || message.viaBotId || (message as Message.message).pFlags.sponsored; + const needName = (message.fromId !== rootScope.myId && this.appPeersManager.isAnyGroup(peerId)) || message.viaBotId || (message as Message.message).pFlags.sponsored; if(needName || fwdFrom || message.reply_to_mid) { // chat let title: HTMLElement | DocumentFragment; let titleVia: typeof title; diff --git a/src/components/chat/input.ts b/src/components/chat/input.ts index bcbe11bf..14a7c9fa 100644 --- a/src/components/chat/input.ts +++ b/src/components/chat/input.ts @@ -220,6 +220,7 @@ export default class ChatInput { private sendAsBtnMenu: HTMLElement; private sendAsPeerIds: PeerId[]; public sendAsPeerId: PeerId; + private updatingSendAsPromise: Promise; // private activeContainer: HTMLElement; @@ -1232,6 +1233,7 @@ export default class ChatInput { sendAsContainer.remove(); SetTransition(this.newMessageWrapper, 'has-send-as', false, 0); this.sendAsPeerId = undefined; + this.updatingSendAsPromise = undefined; this.updateSendAs(true); } @@ -1266,6 +1268,8 @@ export default class ChatInput { subtitle.classList.add('btn-menu-item-subtitle'); if(sendAsPeerId.isUser()) { subtitle.append(i18n('Chat.SendAs.PersonalAccount')); + } else if(sendAsPeerId === this.chat.peerId) { + subtitle.append(i18n('VoiceChat.DiscussionGroup')); } else { subtitle.append(this.appProfileManager.getChatMembersString(sendAsPeerId.toChatId())); } @@ -1284,6 +1288,7 @@ export default class ChatInput { channelFull.default_send_as = this.appPeersManager.getOutputPeer(sendAsPeerId); this.sendAsPeerId = sendAsPeerId; this.updateSendAsAvatar(sendAsPeerId); + this.updateMessageInputPlaceholder(); const middleware = this.chat.bubbles.getMiddleware(); const executeButtonsUpdate = () => { @@ -1368,11 +1373,14 @@ export default class ChatInput { private updateSendAs(skipAnimation?: boolean) { const peerId = this.chat.peerId; - if(!peerId.isChannel()) { + if(!peerId.isChannel() || this.updatingSendAsPromise) { return; } - - const middleware = this.chat.bubbles.getMiddleware(); + + const middleware = this.chat.bubbles.getMiddleware(() => { + return !this.updatingSendAsPromise || this.updatingSendAsPromise === updatingSendAsPromise; + }); + const {sendAsContainer} = this; const chatId = peerId.toChatId(); const result = this.getDefaultSendAs(); @@ -1382,11 +1390,12 @@ export default class ChatInput { skipAnimation = undefined; } - callbackify(result, (sendAsPeerId) => { + const updateSendAsResult = callbackify(result, (sendAsPeerId) => { if(!middleware() || sendAsPeerId === undefined) return; this.sendAsPeerId = sendAsPeerId; this.updateSendAsAvatar(sendAsPeerId, skipAnimation); + this.updateMessageInputPlaceholder(); this.appChatsManager.getSendAs(chatId).then(peers => { if(!middleware()) return; @@ -1406,30 +1415,25 @@ export default class ChatInput { } SetTransition(this.newMessageWrapper, 'has-send-as', true, skipAnimation ? 0 : SEND_AS_ANIMATION_DURATION, undefined, useRafs); + + this.updatingSendAsPromise = undefined; }); - } - public updateMessageInput() { - const {chatInput, attachMenu, messageInput} = this; - const {peerId, threadId} = this.chat; - const canWrite = this.chat.canSend(); - const isHidden = chatInput.classList.contains('is-hidden'); - const willBeHidden = !canWrite; - if(isHidden !== willBeHidden) { - chatInput.classList.add('no-transition'); - chatInput.classList.toggle('is-hidden', !canWrite); - void chatInput.offsetLeft; // reflow - chatInput.classList.remove('no-transition'); - } + const updatingSendAsPromise = this.updatingSendAsPromise = Promise.resolve(updateSendAsResult); + return updatingSendAsPromise; + } - const i = I18n.weakMap.get(messageInput) as I18n.IntlElement; + private updateMessageInputPlaceholder() { + const i = I18n.weakMap.get(this.messageInput) as I18n.IntlElement; if(i) { + const {peerId, threadId} = this.chat; let key: LangPackKey; if(threadId) { key = 'Comment'; } else if(this.appPeersManager.isBroadcast(peerId)) { key = 'ChannelBroadcast'; - } else if(this.appMessagesManager.isAnonymousSending(peerId)) { + } else if((this.sendAsPeerId !== undefined && this.sendAsPeerId !== rootScope.myId) || + this.appMessagesManager.isAnonymousSending(peerId)) { key = 'SendAnonymously'; } else { key = 'Message'; @@ -1437,6 +1441,22 @@ export default class ChatInput { i.compareAndUpdate({key}); } + } + + public updateMessageInput() { + const {chatInput, attachMenu, messageInput} = this; + const {peerId, threadId} = this.chat; + const canWrite = this.chat.canSend(); + const isHidden = chatInput.classList.contains('is-hidden'); + const willBeHidden = !canWrite; + if(isHidden !== willBeHidden) { + chatInput.classList.add('no-transition'); + chatInput.classList.toggle('is-hidden', !canWrite); + void chatInput.offsetLeft; // reflow + chatInput.classList.remove('no-transition'); + } + + this.updateMessageInputPlaceholder(); const visible = this.attachMenuButtons.filter(button => { const good = button.verify(peerId, threadId); diff --git a/src/components/peerProfile.ts b/src/components/peerProfile.ts index 48a0a50d..58790093 100644 --- a/src/components/peerProfile.ts +++ b/src/components/peerProfile.ts @@ -232,9 +232,9 @@ export default class PeerProfile { } public setPeerStatus = (needClear = false) => { - if(!this.peerId) return; - const peerId = this.peerId; + if(!peerId || rootScope.myId === peerId) return; + appImManager.setPeerStatus(this.peerId, this.subtitle, needClear, true, () => peerId === this.peerId, !this.isDialog); }; diff --git a/src/components/sidebarLeft/tabs/settings.ts b/src/components/sidebarLeft/tabs/settings.ts index 7ce59303..c27579c1 100644 --- a/src/components/sidebarLeft/tabs/settings.ts +++ b/src/components/sidebarLeft/tabs/settings.ts @@ -28,6 +28,7 @@ import { AccountAuthorizations, Authorization } from "/Users/kuzmenko/Documents/ import { SliderSuperTabConstructable } from "../../sliderTab"; import PopupAvatar from "../../popups/avatar"; import appProfileManager from "../../../lib/appManagers/appProfileManager"; +import appUsersManager from "../../../lib/appManagers/appUsersManager"; //import AppMediaViewer from "../../appMediaViewerNew"; export default class AppSettingsTab extends SliderSuperTab { @@ -78,16 +79,19 @@ export default class AppSettingsTab extends SliderSuperTab { 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); + const user = appUsersManager.getSelf(); + if(user.photo?._ === 'userProfilePhoto') { + 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); + 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;'; diff --git a/src/config/app.ts b/src/config/app.ts index ad0b5709..6604add9 100644 --- a/src/config/app.ts +++ b/src/config/app.ts @@ -19,7 +19,7 @@ const App = { version: process.env.VERSION, versionFull: process.env.VERSION_FULL, build: +process.env.BUILD, - langPackVersion: '0.3.9', + langPackVersion: '0.4.0', langPack: 'macos', langPackCode: 'en', domains: [MAIN_DOMAIN] as string[], diff --git a/src/lang.ts b/src/lang.ts index 03a7a204..e7695c6d 100644 --- a/src/lang.ts +++ b/src/lang.ts @@ -133,6 +133,8 @@ const lang = { "PushNotification.Message.NoPreview": "You have a new message", "LogOut.Description": "Are you sure you want to log out?\n\nNote that you can seamlessly use Telegram on all your devices at once.", //"PushNotification.Action.Mute1d.Success": "Notification settings were successfully saved.", + //it is from iOS + "VoiceChat.DiscussionGroup": "discussion group", // * android "AccDescrEditing": "Editing",