From 0371b5976853d17dd66ec066898488da4aa26646 Mon Sep 17 00:00:00 2001 From: morethanwords Date: Mon, 29 Nov 2021 19:24:29 +0400 Subject: [PATCH] Added 'choosing a sticker' typing --- src/components/chat/stickersHelper.ts | 5 + .../emoticonsDropdown/tabs/stickers.ts | 16 ++++ src/lang.ts | 3 + src/lib/appManagers/appImManager.ts | 45 +++++++-- src/lib/rootScope.ts | 3 +- src/scss/partials/_peerTyping.scss | 94 ++++++++++++++++++- 6 files changed, 154 insertions(+), 12 deletions(-) diff --git a/src/components/chat/stickersHelper.ts b/src/components/chat/stickersHelper.ts index 2040aca7..7f5cb268 100644 --- a/src/components/chat/stickersHelper.ts +++ b/src/components/chat/stickersHelper.ts @@ -8,6 +8,7 @@ import mediaSizes from "../../helpers/mediaSizes"; import { MyDocument } from "../../lib/appManagers/appDocsManager"; import { CHAT_ANIMATION_GROUP } from "../../lib/appManagers/appImManager"; import appStickersManager from "../../lib/appManagers/appStickersManager"; +import rootScope from "../../lib/rootScope"; import { EmoticonsDropdown } from "../emoticonsDropdown"; import { SuperStickerRenderer } from "../emoticonsDropdown/tabs/stickers"; import LazyLoadQueue from "../lazyLoadQueue"; @@ -38,6 +39,8 @@ export default class StickersHelper extends AutocompleteHelper { setTimeout(() => { // it is not rendered yet this.scrollable.container.scrollTop = 0; }, 0); + + rootScope.dispatchEvent('choosing_sticker', true); }); this.addEventListener('hidden', () => { @@ -45,6 +48,8 @@ export default class StickersHelper extends AutocompleteHelper { mediaSizes.removeEventListener('changeScreen', this.onChangeScreen); this.onChangeScreen = undefined; } + + rootScope.dispatchEvent('choosing_sticker', false); }); } diff --git a/src/components/emoticonsDropdown/tabs/stickers.ts b/src/components/emoticonsDropdown/tabs/stickers.ts index 582fc543..20ad4163 100644 --- a/src/components/emoticonsDropdown/tabs/stickers.ts +++ b/src/components/emoticonsDropdown/tabs/stickers.ts @@ -297,8 +297,23 @@ export default class StickersTab implements EmoticonsTab { EmoticonsDropdown.onMediaClick(e); }); + const setTyping = (cancel = false) => { + rootScope.dispatchEvent('choosing_sticker', !cancel); + }; + this.scroll = new Scrollable(this.content, 'STICKERS'); this.scroll.setVirtualContainer(this.stickersDiv); + this.scroll.onAdditionalScroll = () => { + setTyping(); + }; + + emoticonsDropdown.addEventListener('closed', () => { + setTyping(true); + }); + + emoticonsDropdown.addEventListener('opened', () => { + setTyping(); + }); this.stickyIntersector = EmoticonsDropdown.menuOnClick(this.menu, this.scroll, menuScroll).stickyIntersector; @@ -329,6 +344,7 @@ export default class StickersTab implements EmoticonsTab { }) ]).finally(() => { this.mounted = true; + setTyping(); }); this.superStickerRenderer = new SuperStickerRenderer(EmoticonsDropdown.lazyLoadQueue, EMOTICONSSTICKERGROUP); diff --git a/src/lang.ts b/src/lang.ts index 5621e68e..88858769 100644 --- a/src/lang.ts +++ b/src/lang.ts @@ -769,6 +769,7 @@ const lang = { "Peer.Activity.User.SendingVideo": "sending a video", "Peer.Activity.User.RecordingAudio": "recording voice", "Peer.Activity.User.SendingFile": "sending file", + "Peer.Activity.User.ChoosingSticker": "choosing a sticker", "Peer.Activity.Chat.PlayingGame": "%@ is playing a game", "Peer.Activity.Chat.TypingText": "%@ is typing", "Peer.Activity.Chat.SendingPhoto": "%@ is sending a photo", @@ -776,6 +777,7 @@ const lang = { "Peer.Activity.Chat.SendingVideo": "%@ is sending a video", "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.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", @@ -784,6 +786,7 @@ const lang = { "Peer.Activity.Chat.Multi.RecordingAudio1": "%@ and %d others are recording voice", //"Peer.Activity.Chat.Multi.SendingAudio1": "%@ and %d others are sending audio", "Peer.Activity.Chat.Multi.SendingFile1": "%@ and %d others are sending files", + "Peer.Activity.Chat.Multi.ChoosingSticker1": "%@ and %d others are choosing stickers", "Peer.ServiceNotifications": "service notifications", "Peer.RepliesNotifications": "Reply Notifications", "Peer.Status.justNow": "last seen just now", diff --git a/src/lib/appManagers/appImManager.ts b/src/lib/appManagers/appImManager.ts index 10ad83bd..4c70d296 100644 --- a/src/lib/appManagers/appImManager.ts +++ b/src/lib/appManagers/appImManager.ts @@ -200,6 +200,10 @@ export class AppImManager { this.applyCurrentTheme(); }); + rootScope.addEventListener('choosing_sticker', (choosing) => { + this.setChoosingStickerTyping(!choosing); + }); + rootScope.addEventListener('instance_deactivated', () => { const popup = new PopupElement('popup-instance-deactivated', undefined, {overlayClosable: true}); const c = document.createElement('div'); @@ -1312,13 +1316,13 @@ export class AppImManager { private getTypingElement(action: SendMessageAction) { const el = document.createElement('span'); - el.classList.add('peer-typing'); + let c = 'peer-typing'; + el.classList.add(c); el.dataset.action = action._; switch(action._) { case 'sendMessageTypingAction': { //default: { - const c = 'peer-typing-text'; - el.classList.add(c); + c += '-text'; for(let i = 0; i < 3; ++i) { const dot = document.createElement('span'); dot.className = c + '-dot'; @@ -1332,8 +1336,7 @@ export class AppImManager { case 'sendMessageUploadRoundAction': case 'sendMessageUploadVideoAction': case 'sendMessageUploadPhotoAction': { - const c = 'peer-typing-upload'; - el.classList.add(c); + c += '-upload'; /* const trail = document.createElement('span'); trail.className = c + '-trail'; el.append(trail); */ @@ -1343,12 +1346,23 @@ export class AppImManager { case 'sendMessageRecordAudioAction': case 'sendMessageRecordRoundAction': case 'sendMessageRecordVideoAction': { - const c = 'peer-typing-record'; - el.classList.add(c); + c += '-record'; + break; + } + + case 'sendMessageChooseStickerAction': { + c += '-choosing-sticker'; + for(let i = 0; i < 2; ++i) { + const eye = document.createElement('div'); + eye.className = c + '-eye'; + el.append(eye); + } break; } } + el.classList.add(c); + return el; } @@ -1374,7 +1388,8 @@ export class AppImManager { 'sendMessageRecordVideoAction': 'Peer.Activity.User.RecordingVideo', 'sendMessageRecordAudioAction': 'Peer.Activity.User.RecordingAudio', 'sendMessageRecordRoundAction': 'Peer.Activity.User.RecordingVideo', - 'sendMessageGamePlayAction': 'Peer.Activity.User.PlayingGame' + 'sendMessageGamePlayAction': 'Peer.Activity.User.PlayingGame', + 'sendMessageChooseStickerAction': 'Peer.Activity.User.ChoosingSticker' }, chat: { 'sendMessageTypingAction': 'Peer.Activity.Chat.TypingText', @@ -1386,7 +1401,8 @@ export class AppImManager { 'sendMessageRecordVideoAction': 'Peer.Activity.Chat.RecordingVideo', 'sendMessageRecordAudioAction': 'Peer.Activity.Chat.RecordingAudio', 'sendMessageRecordRoundAction': 'Peer.Activity.Chat.RecordingVideo', - 'sendMessageGamePlayAction': 'Peer.Activity.Chat.PlayingGame' + 'sendMessageGamePlayAction': 'Peer.Activity.Chat.PlayingGame', + 'sendMessageChooseStickerAction': 'Peer.Activity.Chat.ChoosingSticker' }, multi: { 'sendMessageTypingAction': 'Peer.Activity.Chat.Multi.TypingText1', @@ -1398,7 +1414,8 @@ export class AppImManager { 'sendMessageRecordVideoAction': 'Peer.Activity.Chat.Multi.RecordingVideo1', 'sendMessageRecordAudioAction': 'Peer.Activity.Chat.Multi.RecordingAudio1', 'sendMessageRecordRoundAction': 'Peer.Activity.Chat.Multi.RecordingVideo1', - 'sendMessageGamePlayAction': 'Peer.Activity.Chat.Multi.PlayingGame1' + 'sendMessageGamePlayAction': 'Peer.Activity.Chat.Multi.PlayingGame1', + 'sendMessageChooseStickerAction': 'Peer.Activity.Chat.Multi.ChoosingSticker1' } }; @@ -1430,6 +1447,10 @@ export class AppImManager { container.classList.add('online', 'peer-typing-container'); } + if(action._ === 'sendMessageChooseStickerAction') { + container.classList.add('peer-typing-flex'); + } + let typingElement = container.firstElementChild as HTMLElement; if(!typingElement) { typingElement = this.getTypingElement(action); @@ -1533,6 +1554,10 @@ export class AppImManager { replaceContent(element, subtitle || (useWhitespace ? '‎' : '')); }); } + + public setChoosingStickerTyping(cancel: boolean) { + appMessagesManager.setTyping(this.chat.peerId, {_: cancel ? 'sendMessageCancelAction' : 'sendMessageChooseStickerAction'}); + } } const appImManager = new AppImManager(); diff --git a/src/lib/rootScope.ts b/src/lib/rootScope.ts index f0362a8a..22842a3f 100644 --- a/src/lib/rootScope.ts +++ b/src/lib/rootScope.ts @@ -135,7 +135,8 @@ export type BroadcastEvents = { 'download_progress': any, 'document_downloaded': MyDocument, - 'context_menu_toggle': boolean + 'context_menu_toggle': boolean, + 'choosing_sticker': boolean }; export class RootScope extends EventListenerBase<{ diff --git a/src/scss/partials/_peerTyping.scss b/src/scss/partials/_peerTyping.scss index a3b87177..6f3eb0da 100644 --- a/src/scss/partials/_peerTyping.scss +++ b/src/scss/partials/_peerTyping.scss @@ -20,7 +20,12 @@ @include text-overflow(); } */ - &:not(.peer-typing-text) { + &-flex { + display: flex; + align-items: center; + } + + &:not(.peer-typing-text):not(.peer-typing-choosing-sticker) { display: inline-block; vertical-align: middle; transform: translateY(-1px); @@ -92,6 +97,41 @@ animation: recordBlink 1.25s infinite; } } + + &-choosing-sticker { + margin-right: .375rem; + flex: 0 0 auto; + display: flex; + align-items: center; + height: 16px; + + &-eye { + width: 8px; + height: 14px; + border-radius: 50%; + display: inline-block; + vertical-align: middle; + border: 1px solid var(--color); + margin: 0 .0625rem; + position: relative; + animation: eye 1.8s ease-in-out infinite; + + &:before { + content: " "; + display: block; + width: .25rem; + height: .25rem; + background-color: var(--color); + border-radius: 50%; + position: absolute; + // left: 50%; + top: 50%; + // transform: translate(-50%, -50%); + animation: eye-move 1.8s ease-in-out infinite; + transform: translate(-1px, -50%); + } + } + } } $scale-max: 1; @@ -182,3 +222,55 @@ $opacity-min: $opacity-max - ($opacity-step * 2); transform: translate(13px); } } + +@keyframes eye { + 0% { + transform: scale(1.1) translateX(-.75px); + } + + 12.5% { + transform: scale(1) translateX(0px); + } + + 25% { + transform: scale(1.1) translateX(.375px); + } + + 50% { + transform: scale(1.1) translateX(.75px); + } + + 62.5% { + transform: scale(1) translateX(0px); + } + + 75% { + transform: scale(1.1) translateX(-.375px); + } + + 100% { + transform: scale(1.1) translateX(-.75px); + } +} + +@keyframes eye-move { + 0% { + transform: translate(-1px, -50%); + } + + 25% { + transform: translate(3px, -50%); + } + + 50% { + transform: translate(3px, -50%); + } + + 75% { + transform: translate(-1px, -50%); + } + + 100% { + transform: translate(-1px, -50%); + } +}