Typing statuses
Handle AUTH_KEY_DUPLICATED
This commit is contained in:
parent
882977a459
commit
73b47ad5c7
@ -7,7 +7,6 @@
|
|||||||
import appChatsManager, { ChatRights } from "../lib/appManagers/appChatsManager";
|
import appChatsManager, { ChatRights } from "../lib/appManagers/appChatsManager";
|
||||||
import appDialogsManager from "../lib/appManagers/appDialogsManager";
|
import appDialogsManager from "../lib/appManagers/appDialogsManager";
|
||||||
import appMessagesManager, { Dialog } from "../lib/appManagers/appMessagesManager";
|
import appMessagesManager, { Dialog } from "../lib/appManagers/appMessagesManager";
|
||||||
import appPeersManager from "../lib/appManagers/appPeersManager";
|
|
||||||
import appPhotosManager from "../lib/appManagers/appPhotosManager";
|
import appPhotosManager from "../lib/appManagers/appPhotosManager";
|
||||||
import appUsersManager from "../lib/appManagers/appUsersManager";
|
import appUsersManager from "../lib/appManagers/appUsersManager";
|
||||||
import rootScope from "../lib/rootScope";
|
import rootScope from "../lib/rootScope";
|
||||||
@ -167,7 +166,7 @@ export default class AppSelectPeers {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
target.classList.toggle('active');
|
//target.classList.toggle('active');
|
||||||
if(this.selected.has(key)) {
|
if(this.selected.has(key)) {
|
||||||
this.remove(key);
|
this.remove(key);
|
||||||
} else {
|
} else {
|
||||||
@ -436,7 +435,7 @@ export default class AppSelectPeers {
|
|||||||
const checkboxField = new CheckboxField();
|
const checkboxField = new CheckboxField();
|
||||||
|
|
||||||
if(selected) {
|
if(selected) {
|
||||||
dom.listEl.classList.add('active');
|
//dom.listEl.classList.add('active');
|
||||||
checkboxField.input.checked = true;
|
checkboxField.input.checked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,6 +394,14 @@ export default class ChatBubbles {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.listenerSetter.add(this.bubblesContainer, 'dblclick', (e) => {
|
||||||
|
const bubble = (e.target as HTMLElement).classList.contains('bubble') ? e.target as HTMLElement : null;
|
||||||
|
if(bubble) {
|
||||||
|
const mid = +bubble.dataset.mid
|
||||||
|
this.chat.input.initMessageReply(mid);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/* if(false) */this.stickyIntersector = new StickyIntersector(this.scrollable.container, (stuck, target) => {
|
/* if(false) */this.stickyIntersector = new StickyIntersector(this.scrollable.container, (stuck, target) => {
|
||||||
for(const timestamp in this.dateMessages) {
|
for(const timestamp in this.dateMessages) {
|
||||||
const dateMessage = this.dateMessages[timestamp];
|
const dateMessage = this.dateMessages[timestamp];
|
||||||
|
@ -36,7 +36,7 @@ export default class ChatContextMenu {
|
|||||||
public message: any;
|
public message: any;
|
||||||
|
|
||||||
constructor(private attachTo: HTMLElement, private chat: Chat, private appMessagesManager: AppMessagesManager, private appChatsManager: AppChatsManager, private appPeersManager: AppPeersManager, private appPollsManager: AppPollsManager) {
|
constructor(private attachTo: HTMLElement, private chat: Chat, private appMessagesManager: AppMessagesManager, private appChatsManager: AppChatsManager, private appPeersManager: AppPeersManager, private appPollsManager: AppPollsManager) {
|
||||||
const onContextMenu = (e: MouseEvent | Touch) => {
|
const onContextMenu = (e: MouseEvent | Touch | TouchEvent) => {
|
||||||
if(this.init) {
|
if(this.init) {
|
||||||
this.init();
|
this.init();
|
||||||
this.init = null;
|
this.init = null;
|
||||||
@ -52,11 +52,11 @@ export default class ChatContextMenu {
|
|||||||
// ! context menu click by date bubble (there is no pointer-events)
|
// ! context menu click by date bubble (there is no pointer-events)
|
||||||
if(!bubble) return;
|
if(!bubble) return;
|
||||||
|
|
||||||
if(e instanceof MouseEvent) e.preventDefault();
|
if(e instanceof MouseEvent || e.hasOwnProperty('preventDefault')) (e as any).preventDefault();
|
||||||
if(this.element.classList.contains('active')) {
|
if(this.element.classList.contains('active')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(e instanceof MouseEvent) e.cancelBubble = true;
|
if(e instanceof MouseEvent || e.hasOwnProperty('cancelBubble')) (e as any).cancelBubble = true;
|
||||||
|
|
||||||
let mid = +bubble.dataset.mid;
|
let mid = +bubble.dataset.mid;
|
||||||
if(!mid) return;
|
if(!mid) return;
|
||||||
@ -107,14 +107,14 @@ export default class ChatContextMenu {
|
|||||||
const side: 'left' | 'right' = bubble.classList.contains('is-in') ? 'left' : 'right';
|
const side: 'left' | 'right' = bubble.classList.contains('is-in') ? 'left' : 'right';
|
||||||
//bubble.parentElement.append(this.element);
|
//bubble.parentElement.append(this.element);
|
||||||
//appImManager.log('contextmenu', e, bubble, side);
|
//appImManager.log('contextmenu', e, bubble, side);
|
||||||
positionMenu(e, this.element, side);
|
positionMenu((e as TouchEvent).touches ? (e as TouchEvent).touches[0] : e as MouseEvent, this.element, side);
|
||||||
openBtnMenu(this.element, () => {
|
openBtnMenu(this.element, () => {
|
||||||
this.peerId = this.mid = 0;
|
this.peerId = this.mid = 0;
|
||||||
this.target = null;
|
this.target = null;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if(isTouchSupported) {
|
if(isTouchSupported/* && false */) {
|
||||||
attachClickEvent(attachTo, (e) => {
|
attachClickEvent(attachTo, (e) => {
|
||||||
if(chat.selection.isSelecting) {
|
if(chat.selection.isSelecting) {
|
||||||
return;
|
return;
|
||||||
|
@ -10,7 +10,7 @@ import type { AppMessagesManager } from "../../lib/appManagers/appMessagesManage
|
|||||||
import type { AppPeersManager } from "../../lib/appManagers/appPeersManager";
|
import type { AppPeersManager } from "../../lib/appManagers/appPeersManager";
|
||||||
import type { AppSidebarRight } from "../sidebarRight";
|
import type { AppSidebarRight } from "../sidebarRight";
|
||||||
import type Chat from "./chat";
|
import type Chat from "./chat";
|
||||||
import { cancelEvent, attachClickEvent, blurActiveElement } from "../../helpers/dom";
|
import { cancelEvent, attachClickEvent, blurActiveElement, replaceContent } from "../../helpers/dom";
|
||||||
import mediaSizes, { ScreenSize } from "../../helpers/mediaSizes";
|
import mediaSizes, { ScreenSize } from "../../helpers/mediaSizes";
|
||||||
import { isSafari } from "../../helpers/userAgent";
|
import { isSafari } from "../../helpers/userAgent";
|
||||||
import rootScope from "../../lib/rootScope";
|
import rootScope from "../../lib/rootScope";
|
||||||
@ -562,17 +562,6 @@ export default class ChatTopbar {
|
|||||||
if(!this.subtitle) return;
|
if(!this.subtitle) return;
|
||||||
|
|
||||||
const peerId = this.peerId;
|
const peerId = this.peerId;
|
||||||
if(needClear) {
|
this.chat.appImManager.setPeerStatus(this.peerId, this.subtitle, needClear, false, () => peerId === this.peerId);
|
||||||
this.subtitle.innerHTML = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.chat.appImManager.getPeerStatus(this.peerId).then((subtitle) => {
|
|
||||||
if(peerId !== this.peerId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.subtitle.textContent = '';
|
|
||||||
this.subtitle.append(subtitle);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import { cancelEvent, CLICK_EVENT_NAME } from "../helpers/dom";
|
|||||||
import ListenerSetter from "../helpers/listenerSetter";
|
import ListenerSetter from "../helpers/listenerSetter";
|
||||||
import mediaSizes from "../helpers/mediaSizes";
|
import mediaSizes from "../helpers/mediaSizes";
|
||||||
import { isTouchSupported } from "../helpers/touchSupport";
|
import { isTouchSupported } from "../helpers/touchSupport";
|
||||||
import { isApple, isMobileSafari } from "../helpers/userAgent";
|
import { isApple, isMobileSafari, isSafari } from "../helpers/userAgent";
|
||||||
import appNavigationController from "./appNavigationController";
|
import appNavigationController from "./appNavigationController";
|
||||||
|
|
||||||
export function putPreloader(elem: Element, returnDiv = false): HTMLElement {
|
export function putPreloader(elem: Element, returnDiv = false): HTMLElement {
|
||||||
@ -341,6 +341,12 @@ export function attachContextMenuListener(element: HTMLElement, callback: (e: To
|
|||||||
}
|
}
|
||||||
}, .4e3);
|
}, .4e3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* if(!isSafari) {
|
||||||
|
add('contextmenu', (e: any) => {
|
||||||
|
cancelEvent(e);
|
||||||
|
}, {passive: false, capture: true});
|
||||||
|
} */
|
||||||
} else {
|
} else {
|
||||||
add('contextmenu', isTouchSupported ? (e: any) => {
|
add('contextmenu', isTouchSupported ? (e: any) => {
|
||||||
callback(e);
|
callback(e);
|
||||||
|
@ -138,7 +138,7 @@ export default class AppIncludedChatsTab extends SliderSuperTab {
|
|||||||
|
|
||||||
const selected = this.selector.selected.has(peerId);
|
const selected = this.selector.selected.has(peerId);
|
||||||
dom.containerEl.append(this.checkbox(selected));
|
dom.containerEl.append(this.checkbox(selected));
|
||||||
if(selected) dom.listEl.classList.add('active');
|
//if(selected) dom.listEl.classList.add('active');
|
||||||
|
|
||||||
const foundInFilters: HTMLElement[] = [];
|
const foundInFilters: HTMLElement[] = [];
|
||||||
this.dialogsByFilters.forEach((dialogs, filter) => {
|
this.dialogsByFilters.forEach((dialogs, filter) => {
|
||||||
|
@ -579,18 +579,7 @@ class PeerProfile {
|
|||||||
if(!this.peerId) return;
|
if(!this.peerId) return;
|
||||||
|
|
||||||
const peerId = this.peerId;
|
const peerId = this.peerId;
|
||||||
if(needClear) {
|
appImManager.setPeerStatus(this.peerId, this.subtitle, needClear, true, () => peerId === this.peerId);
|
||||||
this.subtitle.innerHTML = ''; // ! HERE U CAN FIND WHITESPACE
|
|
||||||
}
|
|
||||||
|
|
||||||
appImManager.getPeerStatus(this.peerId).then((subtitle) => {
|
|
||||||
if(peerId !== this.peerId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.subtitle.textContent = '';
|
|
||||||
this.subtitle.append(subtitle || '');
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public cleanupHTML() {
|
public cleanupHTML() {
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
const App = {
|
const App = {
|
||||||
id: 1025907,
|
id: 1025907,
|
||||||
hash: '452b0359b988148995f22ff0f4229750',
|
hash: '452b0359b988148995f22ff0f4229750',
|
||||||
version: '0.4.2',
|
version: '0.4.3',
|
||||||
langPackVersion: '0.1.4',
|
langPackVersion: '0.1.5',
|
||||||
langPack: 'macos',
|
langPack: 'macos',
|
||||||
langPackCode: 'en',
|
langPackCode: 'en',
|
||||||
domains: [] as string[],
|
domains: [] as string[],
|
||||||
|
@ -139,10 +139,10 @@ console.timeEnd('get storage1'); */
|
|||||||
});
|
});
|
||||||
|
|
||||||
if(userAgent.isApple) {
|
if(userAgent.isApple) {
|
||||||
if(userAgent.isSafari && userAgent.isMobile) {
|
if(userAgent.isSafari) {
|
||||||
document.documentElement.classList.add('is-safari');
|
document.documentElement.classList.add('is-safari');
|
||||||
|
|
||||||
if(touchSupport.isTouchSupported) {
|
if(userAgent.isMobile && touchSupport.isTouchSupported) {
|
||||||
let key: 'clientY' | 'pageY' = 'clientY';
|
let key: 'clientY' | 'pageY' = 'clientY';
|
||||||
let startY = 0;
|
let startY = 0;
|
||||||
const o = {capture: true, passive: false};
|
const o = {capture: true, passive: false};
|
||||||
|
27
src/lang.ts
27
src/lang.ts
@ -524,13 +524,28 @@ const lang = {
|
|||||||
"Stickers.SuggestStickers": "Suggest Stickers by Emoji",
|
"Stickers.SuggestStickers": "Suggest Stickers by Emoji",
|
||||||
"ShareModal.Search.ForwardPlaceholder": "Forward to...",
|
"ShareModal.Search.ForwardPlaceholder": "Forward to...",
|
||||||
"InstalledStickers.LoopAnimated": "Loop Animated Stickers",
|
"InstalledStickers.LoopAnimated": "Loop Animated Stickers",
|
||||||
// "Peer.Activity.User.PlayingGame": "playing a game",
|
"Peer.Activity.User.PlayingGame": "playing a game",
|
||||||
"Peer.Activity.User.TypingText": "typing",
|
"Peer.Activity.User.TypingText": "typing",
|
||||||
// "Peer.Activity.User.SendingPhoto": "sending a photo",
|
"Peer.Activity.User.SendingPhoto": "sending a photo",
|
||||||
// "Peer.Activity.User.RecordingVideo": "recording video",
|
"Peer.Activity.User.RecordingVideo": "recording video",
|
||||||
// "Peer.Activity.User.SendingVideo": "sending a video",
|
"Peer.Activity.User.SendingVideo": "sending a video",
|
||||||
// "Peer.Activity.User.RecordingAudio": "recording voice",
|
"Peer.Activity.User.RecordingAudio": "recording voice",
|
||||||
// "Peer.Activity.User.SendingFile": "sending file",
|
"Peer.Activity.User.SendingFile": "sending file",
|
||||||
|
"Peer.Activity.Chat.PlayingGame": "%@ is playing a game",
|
||||||
|
"Peer.Activity.Chat.TypingText": "%@ is typing",
|
||||||
|
"Peer.Activity.Chat.SendingPhoto": "%@ is sending a photo",
|
||||||
|
"Peer.Activity.Chat.RecordingVideo": "%@ is recording video",
|
||||||
|
"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.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",
|
||||||
|
"Peer.Activity.Chat.Multi.RecordingVideo1": "%@ and %d others are recording video",
|
||||||
|
"Peer.Activity.Chat.Multi.SendingVideo1": "%@ and %d others are sending videos",
|
||||||
|
"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.ServiceNotifications": "service notifications",
|
"Peer.ServiceNotifications": "service notifications",
|
||||||
"Peer.RepliesNotifications": "Reply Notifications",
|
"Peer.RepliesNotifications": "Reply Notifications",
|
||||||
"Peer.Status.online": "online",
|
"Peer.Status.online": "online",
|
||||||
|
@ -71,53 +71,74 @@ export class AppChatsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 'updateUserTyping':
|
case 'updateUserTyping':
|
||||||
case 'updateChatUserTyping': {
|
case 'updateChatUserTyping':
|
||||||
|
case 'updateChannelUserTyping': {
|
||||||
const fromId = (update as Update.updateUserTyping).user_id || appPeersManager.getPeerId((update as Update.updateChatUserTyping).from_id);
|
const fromId = (update as Update.updateUserTyping).user_id || appPeersManager.getPeerId((update as Update.updateChatUserTyping).from_id);
|
||||||
if(rootScope.myId === fromId) {
|
if(rootScope.myId === fromId) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const peerId = update._ === 'updateUserTyping' ? fromId : -update.chat_id;
|
const peerId = update._ === 'updateUserTyping' ?
|
||||||
|
fromId :
|
||||||
|
-((update as Update.updateChatUserTyping).chat_id || (update as Update.updateChannelUserTyping).channel_id);
|
||||||
const typings = this.typingsInPeer[peerId] ?? (this.typingsInPeer[peerId] = []);
|
const typings = this.typingsInPeer[peerId] ?? (this.typingsInPeer[peerId] = []);
|
||||||
let typing = typings.find(t => t.userId === fromId);
|
let typing = typings.find(t => t.userId === fromId);
|
||||||
if(!typing) {
|
|
||||||
typing = {
|
|
||||||
userId: fromId
|
|
||||||
};
|
|
||||||
|
|
||||||
typings.push(typing);
|
const cancelAction = () => {
|
||||||
}
|
|
||||||
|
|
||||||
//console.log('updateChatUserTyping', update, typings);
|
|
||||||
|
|
||||||
typing.action = update.action;
|
|
||||||
|
|
||||||
if(!appUsersManager.hasUser(fromId)) {
|
|
||||||
if(update._ === 'updateChatUserTyping') {
|
|
||||||
if(update.chat_id && appChatsManager.hasChat(update.chat_id) && !appChatsManager.isChannel(update.chat_id)) {
|
|
||||||
appProfileManager.getChatFull(update.chat_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//return;
|
|
||||||
}
|
|
||||||
|
|
||||||
appUsersManager.forceUserOnline(fromId);
|
|
||||||
|
|
||||||
if(typing.timeout !== undefined) clearTimeout(typing.timeout);
|
|
||||||
|
|
||||||
typing.timeout = window.setTimeout(() => {
|
|
||||||
delete typing.timeout;
|
delete typing.timeout;
|
||||||
typings.findAndSplice(t => t.userId === fromId);
|
//typings.findAndSplice(t => t === typing);
|
||||||
|
const idx = typings.indexOf(typing);
|
||||||
|
if(idx !== -1) {
|
||||||
|
typings.splice(idx, 1);
|
||||||
|
}
|
||||||
|
|
||||||
rootScope.broadcast('peer_typings', {peerId, typings});
|
rootScope.broadcast('peer_typings', {peerId, typings});
|
||||||
|
|
||||||
if(!typings.length) {
|
if(!typings.length) {
|
||||||
delete this.typingsInPeer[peerId];
|
delete this.typingsInPeer[peerId];
|
||||||
}
|
}
|
||||||
}, 6000);
|
};
|
||||||
|
|
||||||
|
if(typing && typing.timeout !== undefined) {
|
||||||
|
clearTimeout(typing.timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(update.action._ === 'sendMessageCancelAction') {
|
||||||
|
if(!typing) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelAction();
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if(!typing) {
|
||||||
|
typing = {
|
||||||
|
userId: fromId
|
||||||
|
};
|
||||||
|
|
||||||
|
typings.push(typing);
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log('updateChatUserTyping', update, typings);
|
||||||
|
|
||||||
|
typing.action = update.action;
|
||||||
|
|
||||||
|
if(!appUsersManager.hasUser(fromId)) {
|
||||||
|
if(update._ === 'updateChatUserTyping') {
|
||||||
|
if(update.chat_id && appChatsManager.hasChat(update.chat_id) && !appChatsManager.isChannel(update.chat_id)) {
|
||||||
|
appProfileManager.getChatFull(update.chat_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
|
||||||
|
appUsersManager.forceUserOnline(fromId);
|
||||||
|
|
||||||
|
typing.timeout = window.setTimeout(cancelAction, 6000);
|
||||||
|
rootScope.broadcast('peer_typings', {peerId, typings});
|
||||||
|
}
|
||||||
|
|
||||||
rootScope.broadcast('peer_typings', {peerId, typings});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ import { isSafari } from "../../helpers/userAgent";
|
|||||||
import { logger, LogLevels } from "../logger";
|
import { logger, LogLevels } from "../logger";
|
||||||
import { RichTextProcessor } from "../richtextprocessor";
|
import { RichTextProcessor } from "../richtextprocessor";
|
||||||
import rootScope from "../rootScope";
|
import rootScope from "../rootScope";
|
||||||
import { positionElementByIndex } from "../../helpers/dom";
|
import { positionElementByIndex, replaceContent } from "../../helpers/dom";
|
||||||
import appImManager from "./appImManager";
|
import appImManager from "./appImManager";
|
||||||
import appMessagesManager, { Dialog } from "./appMessagesManager";
|
import appMessagesManager, { Dialog } from "./appMessagesManager";
|
||||||
import {MyDialogFilter as DialogFilter} from "../storages/filters";
|
import {MyDialogFilter as DialogFilter} from "../storages/filters";
|
||||||
@ -36,6 +36,7 @@ import { InputNotifyPeer } from "../../layer";
|
|||||||
import PeerTitle from "../../components/peerTitle";
|
import PeerTitle from "../../components/peerTitle";
|
||||||
import { i18n } from "../langPack";
|
import { i18n } from "../langPack";
|
||||||
import findUpTag from "../../helpers/dom/findUpTag";
|
import findUpTag from "../../helpers/dom/findUpTag";
|
||||||
|
import appChatsManager from "./appChatsManager";
|
||||||
|
|
||||||
export type DialogDom = {
|
export type DialogDom = {
|
||||||
avatarEl: AvatarElement,
|
avatarEl: AvatarElement,
|
||||||
@ -465,7 +466,7 @@ export class AppDialogsManager {
|
|||||||
if(!dialog) return;
|
if(!dialog) return;
|
||||||
|
|
||||||
if(typings.length) {
|
if(typings.length) {
|
||||||
this.setTyping(dialog, appUsersManager.getUser(typings[0]));
|
this.setTyping(dialog);
|
||||||
} else {
|
} else {
|
||||||
this.unsetTyping(dialog);
|
this.unsetTyping(dialog);
|
||||||
}
|
}
|
||||||
@ -1379,26 +1380,20 @@ export class AppDialogsManager {
|
|||||||
return {dom, dialog};
|
return {dom, dialog};
|
||||||
}
|
}
|
||||||
|
|
||||||
public setTyping(dialog: Dialog, user: User) {
|
public setTyping(dialog: Dialog) {
|
||||||
const dom = this.getDialogDom(dialog.peerId);
|
const dom = this.getDialogDom(dialog.peerId);
|
||||||
if(!dom) {
|
if(!dom) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let str = '';
|
let typingElement = dom.lastMessageSpan.querySelector('.peer-typing-container') as HTMLElement;
|
||||||
if(dialog.peerId < 0) {
|
if(typingElement) {
|
||||||
let s = user.rFirstName || user.username;
|
appImManager.getPeerTyping(dialog.peerId, typingElement);
|
||||||
if(!s) return;
|
} else {
|
||||||
str = s + ' ';
|
typingElement = appImManager.getPeerTyping(dialog.peerId);
|
||||||
}
|
replaceContent(dom.lastMessageSpan, typingElement);
|
||||||
|
dom.lastMessageSpan.classList.add('user-typing');
|
||||||
const senderBold = document.createElement('i');
|
}
|
||||||
str += 'typing...';
|
|
||||||
senderBold.innerHTML = str;
|
|
||||||
|
|
||||||
dom.lastMessageSpan.innerHTML = '';
|
|
||||||
dom.lastMessageSpan.append(senderBold);
|
|
||||||
dom.lastMessageSpan.classList.add('user-typing');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsetTyping(dialog: Dialog) {
|
public unsetTyping(dialog: Dialog) {
|
||||||
|
@ -24,7 +24,7 @@ import appPhotosManager from './appPhotosManager';
|
|||||||
import appProfileManager from './appProfileManager';
|
import appProfileManager from './appProfileManager';
|
||||||
import appStickersManager from './appStickersManager';
|
import appStickersManager from './appStickersManager';
|
||||||
import appWebPagesManager from './appWebPagesManager';
|
import appWebPagesManager from './appWebPagesManager';
|
||||||
import { blurActiveElement, cancelEvent, disableTransition, placeCaretAtEnd, whichChild } from '../../helpers/dom';
|
import { blurActiveElement, cancelEvent, disableTransition, placeCaretAtEnd, replaceContent, whichChild } from '../../helpers/dom';
|
||||||
import PopupNewMedia from '../../components/popups/newMedia';
|
import PopupNewMedia from '../../components/popups/newMedia';
|
||||||
import MarkupTooltip from '../../components/chat/markupTooltip';
|
import MarkupTooltip from '../../components/chat/markupTooltip';
|
||||||
import { isTouchSupported } from '../../helpers/touchSupport';
|
import { isTouchSupported } from '../../helpers/touchSupport';
|
||||||
@ -43,11 +43,12 @@ import { MOUNT_CLASS_TO } from '../../config/debug';
|
|||||||
import appNavigationController from '../../components/appNavigationController';
|
import appNavigationController from '../../components/appNavigationController';
|
||||||
import appNotificationsManager from './appNotificationsManager';
|
import appNotificationsManager from './appNotificationsManager';
|
||||||
import AppPrivateSearchTab from '../../components/sidebarRight/tabs/search';
|
import AppPrivateSearchTab from '../../components/sidebarRight/tabs/search';
|
||||||
import { i18n } from '../langPack';
|
import { i18n, LangPackKey } from '../langPack';
|
||||||
import { SendMessageAction } from '../../layer';
|
import { SendMessageAction } from '../../layer';
|
||||||
import { hslaStringToRgbString } from '../../helpers/color';
|
import { hslaStringToRgbString } from '../../helpers/color';
|
||||||
import { copy, getObjectKeysAndSort } from '../../helpers/object';
|
import { copy, getObjectKeysAndSort } from '../../helpers/object';
|
||||||
import { getFilesFromEvent } from '../../helpers/files';
|
import { getFilesFromEvent } from '../../helpers/files';
|
||||||
|
import PeerTitle from '../../components/peerTitle';
|
||||||
|
|
||||||
//console.log('appImManager included33!');
|
//console.log('appImManager included33!');
|
||||||
|
|
||||||
@ -295,7 +296,8 @@ export class AppImManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const key = chat.peerId + (chat.threadId ? '_' + chat.threadId : '');
|
const key = chat.peerId + (chat.threadId ? '_' + chat.threadId : '');
|
||||||
return sessionStorage.getFromCache('chatPositions')[key];
|
const cache = sessionStorage.getFromCache('chatPositions');
|
||||||
|
return cache && cache[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
public applyHighlightningColor() {
|
public applyHighlightningColor() {
|
||||||
@ -840,9 +842,10 @@ export class AppImManager {
|
|||||||
private getTypingElement(action: SendMessageAction) {
|
private getTypingElement(action: SendMessageAction) {
|
||||||
const el = document.createElement('span');
|
const el = document.createElement('span');
|
||||||
el.classList.add('peer-typing');
|
el.classList.add('peer-typing');
|
||||||
|
el.dataset.action = action._;
|
||||||
switch(action._) {
|
switch(action._) {
|
||||||
//case 'sendMessageTypingAction': {
|
case 'sendMessageTypingAction': {
|
||||||
default: {
|
//default: {
|
||||||
const c = 'peer-typing-text';
|
const c = 'peer-typing-text';
|
||||||
el.classList.add(c);
|
el.classList.add(c);
|
||||||
for(let i = 0; i < 3; ++i) {
|
for(let i = 0; i < 3; ++i) {
|
||||||
@ -852,16 +855,146 @@ export class AppImManager {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'sendMessageUploadAudioAction':
|
||||||
|
case 'sendMessageUploadDocumentAction':
|
||||||
|
case 'sendMessageUploadRoundAction':
|
||||||
|
case 'sendMessageUploadVideoAction':
|
||||||
|
case 'sendMessageUploadPhotoAction': {
|
||||||
|
const c = 'peer-typing-upload';
|
||||||
|
el.classList.add(c);
|
||||||
|
/* const trail = document.createElement('span');
|
||||||
|
trail.className = c + '-trail';
|
||||||
|
el.append(trail); */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'sendMessageRecordAudioAction':
|
||||||
|
case 'sendMessageRecordRoundAction':
|
||||||
|
case 'sendMessageRecordVideoAction': {
|
||||||
|
const c = 'peer-typing-record';
|
||||||
|
el.classList.add(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getPeerTyping(peerId: number, container?: HTMLElement) {
|
||||||
|
if(!appUsersManager.isBot(peerId)) {
|
||||||
|
const typings = appChatsManager.typingsInPeer[peerId];
|
||||||
|
if(!typings || !typings.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const typing = typings[0];
|
||||||
|
|
||||||
|
const langPackKeys: {
|
||||||
|
[peerType in 'private' | 'chat' | 'multi']?: Partial<{[action in SendMessageAction['_']]: LangPackKey}>
|
||||||
|
} = {
|
||||||
|
private: {
|
||||||
|
'sendMessageTypingAction': 'Peer.Activity.User.TypingText',
|
||||||
|
'sendMessageUploadAudioAction': 'Peer.Activity.User.SendingFile',
|
||||||
|
'sendMessageUploadDocumentAction': 'Peer.Activity.User.SendingFile',
|
||||||
|
'sendMessageUploadPhotoAction': 'Peer.Activity.User.SendingPhoto',
|
||||||
|
'sendMessageUploadVideoAction': 'Peer.Activity.User.SendingVideo',
|
||||||
|
'sendMessageUploadRoundAction': 'Peer.Activity.User.SendingVideo',
|
||||||
|
'sendMessageRecordVideoAction': 'Peer.Activity.User.RecordingVideo',
|
||||||
|
'sendMessageRecordAudioAction': 'Peer.Activity.User.RecordingAudio',
|
||||||
|
'sendMessageRecordRoundAction': 'Peer.Activity.User.RecordingVideo',
|
||||||
|
'sendMessageGamePlayAction': 'Peer.Activity.User.PlayingGame'
|
||||||
|
},
|
||||||
|
chat: {
|
||||||
|
'sendMessageTypingAction': 'Peer.Activity.Chat.TypingText',
|
||||||
|
'sendMessageUploadAudioAction': 'Peer.Activity.Chat.SendingFile',
|
||||||
|
'sendMessageUploadDocumentAction': 'Peer.Activity.Chat.SendingFile',
|
||||||
|
'sendMessageUploadPhotoAction': 'Peer.Activity.Chat.SendingPhoto',
|
||||||
|
'sendMessageUploadVideoAction': 'Peer.Activity.Chat.SendingVideo',
|
||||||
|
'sendMessageUploadRoundAction': 'Peer.Activity.Chat.SendingVideo',
|
||||||
|
'sendMessageRecordVideoAction': 'Peer.Activity.Chat.RecordingVideo',
|
||||||
|
'sendMessageRecordAudioAction': 'Peer.Activity.Chat.RecordingAudio',
|
||||||
|
'sendMessageRecordRoundAction': 'Peer.Activity.Chat.RecordingVideo',
|
||||||
|
'sendMessageGamePlayAction': 'Peer.Activity.Chat.PlayingGame'
|
||||||
|
},
|
||||||
|
multi: {
|
||||||
|
'sendMessageTypingAction': 'Peer.Activity.Chat.Multi.TypingText1',
|
||||||
|
'sendMessageUploadAudioAction': 'Peer.Activity.Chat.Multi.SendingFile1',
|
||||||
|
'sendMessageUploadDocumentAction': 'Peer.Activity.Chat.Multi.SendingFile1',
|
||||||
|
'sendMessageUploadPhotoAction': 'Peer.Activity.Chat.Multi.SendingPhoto1',
|
||||||
|
'sendMessageUploadVideoAction': 'Peer.Activity.Chat.Multi.SendingVideo1',
|
||||||
|
'sendMessageUploadRoundAction': 'Peer.Activity.Chat.Multi.SendingVideo1',
|
||||||
|
'sendMessageRecordVideoAction': 'Peer.Activity.Chat.Multi.RecordingVideo1',
|
||||||
|
'sendMessageRecordAudioAction': 'Peer.Activity.Chat.Multi.RecordingAudio1',
|
||||||
|
'sendMessageRecordRoundAction': 'Peer.Activity.Chat.Multi.RecordingVideo1',
|
||||||
|
'sendMessageGamePlayAction': 'Peer.Activity.Chat.Multi.PlayingGame1'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapa = peerId > 0 ? langPackKeys.private : (typings.length > 1 ? langPackKeys.multi : langPackKeys.chat);
|
||||||
|
let action = typing.action;
|
||||||
|
|
||||||
|
if(typings.length > 1) {
|
||||||
|
const s: any = {};
|
||||||
|
typings.forEach(typing => {
|
||||||
|
const type = typing.action._;
|
||||||
|
if(s[type] === undefined) s[type] = 0;
|
||||||
|
++s[type];
|
||||||
|
});
|
||||||
|
|
||||||
|
if(Object.keys(s).length > 1) {
|
||||||
|
action = {
|
||||||
|
_: 'sendMessageTypingAction'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const langPackKey = mapa[action._];
|
||||||
|
if(!langPackKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!container) {
|
||||||
|
container = document.createElement('span');
|
||||||
|
container.classList.add('online', 'peer-typing-container');
|
||||||
|
}
|
||||||
|
|
||||||
|
let typingElement = container.firstElementChild as HTMLElement;
|
||||||
|
if(!typingElement) {
|
||||||
|
typingElement = this.getTypingElement(action);
|
||||||
|
container.prepend(typingElement);
|
||||||
|
} else {
|
||||||
|
if(typingElement.dataset.action !== action._) {
|
||||||
|
typingElement.replaceWith(this.getTypingElement(action));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let args: any[];
|
||||||
|
if(peerId < 0) {
|
||||||
|
args = [
|
||||||
|
new PeerTitle({peerId: typing.userId, onlyFirstName: true}).element,
|
||||||
|
typings.length - 1
|
||||||
|
];
|
||||||
|
}
|
||||||
|
const descriptionElement = i18n(langPackKey, args);
|
||||||
|
descriptionElement.classList.add('peer-typing-description');
|
||||||
|
|
||||||
|
if(container.childElementCount > 1) container.lastElementChild.replaceWith(descriptionElement);
|
||||||
|
else container.append(descriptionElement);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async getPeerStatus(peerId: number) {
|
public async getPeerStatus(peerId: number) {
|
||||||
let subtitle: HTMLElement;
|
let subtitle: HTMLElement;
|
||||||
if(!peerId) return '';
|
if(!peerId) return '';
|
||||||
|
|
||||||
if(peerId < 0) { // not human
|
if(peerId < 0) { // not human
|
||||||
|
let span = this.getPeerTyping(peerId);
|
||||||
|
if(span) {
|
||||||
|
return span;
|
||||||
|
}
|
||||||
|
|
||||||
const chatInfo = await appProfileManager.getChatFull(-peerId) as any;
|
const chatInfo = await appProfileManager.getChatFull(-peerId) as any;
|
||||||
this.chat.log('chatInfo res:', chatInfo);
|
this.chat.log('chatInfo res:', chatInfo);
|
||||||
|
|
||||||
@ -886,16 +1019,14 @@ export class AppImManager {
|
|||||||
subtitle = appUsersManager.getUserStatusString(user.id);
|
subtitle = appUsersManager.getUserStatusString(user.id);
|
||||||
|
|
||||||
if(!appUsersManager.isBot(peerId)) {
|
if(!appUsersManager.isBot(peerId)) {
|
||||||
const typings = appChatsManager.typingsInPeer[peerId];
|
let span = this.getPeerTyping(peerId);
|
||||||
if(typings && typings.length) {
|
if(!span && user.status?._ === 'userStatusOnline') {
|
||||||
const span = document.createElement('span');
|
span = document.createElement('span');
|
||||||
span.classList.add('online');
|
|
||||||
span.append(this.getTypingElement(typings[0].action), i18n('Peer.Activity.User.TypingText'));
|
|
||||||
return span;
|
|
||||||
} else if(user.status?._ === 'userStatusOnline') {
|
|
||||||
const span = document.createElement('span');
|
|
||||||
span.classList.add('online');
|
span.classList.add('online');
|
||||||
span.append(subtitle);
|
span.append(subtitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(span) {
|
||||||
return span;
|
return span;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -904,6 +1035,26 @@ export class AppImManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setPeerStatus(peerId: number, element: HTMLElement, needClear: boolean, useWhitespace: boolean, middleware: () => boolean) {
|
||||||
|
if(needClear) {
|
||||||
|
element.innerHTML = useWhitespace ? '' : ''; // ! HERE U CAN FIND WHITESPACE
|
||||||
|
}
|
||||||
|
|
||||||
|
// * good good good
|
||||||
|
const typingContainer = element.querySelector('.peer-typing-container') as HTMLElement;
|
||||||
|
if(typingContainer && this.getPeerTyping(peerId, typingContainer)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getPeerStatus(peerId).then((subtitle) => {
|
||||||
|
if(!middleware()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
replaceContent(element, subtitle || (useWhitespace ? '' : ''));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const appImManager = new AppImManager();
|
const appImManager = new AppImManager();
|
||||||
|
@ -301,7 +301,8 @@ export class ApiManager {
|
|||||||
|
|
||||||
deferred.reject(error);
|
deferred.reject(error);
|
||||||
|
|
||||||
if(error.code === 401 && error.type === 'SESSION_REVOKED') {
|
if((error.code === 401 && error.type === 'SESSION_REVOKED') ||
|
||||||
|
(error.code === 406 && error.type === 'AUTH_KEY_DUPLICATED')) {
|
||||||
this.logOut();
|
this.logOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ $chat-helper-size: 39px;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.chat-input-container {
|
.chat-input-container {
|
||||||
--padding-horizontal: #{$chat-padding-handhelds};
|
--padding-horizontal: var(--chat-input-padding);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -82,10 +82,6 @@ $chat-helper-size: 39px;
|
|||||||
position: relative;
|
position: relative;
|
||||||
padding-bottom: var(--bottom);
|
padding-bottom: var(--bottom);
|
||||||
|
|
||||||
@include respond-to(not-handhelds) {
|
|
||||||
--padding-horizontal: #{$chat-padding};
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-circle {
|
.btn-circle {
|
||||||
width: var(--chat-input-size);
|
width: var(--chat-input-size);
|
||||||
height: var(--chat-input-size);
|
height: var(--chat-input-size);
|
||||||
@ -611,7 +607,7 @@ $chat-helper-size: 39px;
|
|||||||
|
|
||||||
.chat-input-wrapper {
|
.chat-input-wrapper {
|
||||||
--padding-vertical: .3125rem;
|
--padding-vertical: .3125rem;
|
||||||
--padding-horizontal: .5rem;
|
--padding-horizontal: var(--chat-input-inner-padding);
|
||||||
--padding: var(--padding-vertical) var(--padding-horizontal);
|
--padding: var(--padding-vertical) var(--padding-horizontal);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -781,7 +777,6 @@ $chat-helper-size: 39px;
|
|||||||
|
|
||||||
@include respond-to(handhelds) {
|
@include respond-to(handhelds) {
|
||||||
--padding-vertical: 1px;
|
--padding-vertical: 1px;
|
||||||
--padding-horizontal: #{$chat-padding-handhelds};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 420px) {
|
@media only screen and (max-width: 420px) {
|
||||||
@ -790,7 +785,6 @@ $chat-helper-size: 39px;
|
|||||||
|
|
||||||
@include respond-to(esg-bottom) {
|
@include respond-to(esg-bottom) {
|
||||||
--padding-vertical: 1px;
|
--padding-vertical: 1px;
|
||||||
--padding-horizontal: #{$chat-padding-handhelds};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bubble-tail {
|
.bubble-tail {
|
||||||
|
@ -156,15 +156,6 @@ ul.chatlist {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
|
||||||
//display: inline-block;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
//margin: .1rem 0;
|
|
||||||
line-height: 27px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -204,11 +195,14 @@ ul.chatlist {
|
|||||||
.tgico-chatspinned:before,
|
.tgico-chatspinned:before,
|
||||||
//.user-title:after,
|
//.user-title:after,
|
||||||
.user-title,
|
.user-title,
|
||||||
b,
|
|
||||||
.message-status {
|
.message-status {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
.user-title:after {
|
.user-title:after {
|
||||||
color: rgba(255, 255, 255, .7);
|
color: rgba(255, 255, 255, .7);
|
||||||
}
|
}
|
||||||
@ -230,10 +224,34 @@ ul.chatlist {
|
|||||||
background-color: #fff !important;
|
background-color: #fff !important;
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.peer-typing-container {
|
||||||
|
--color: #fff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* .user-title,
|
||||||
|
.dialog-title-details,
|
||||||
|
.user-last-message */li span {
|
||||||
|
//display: inline-block;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
//margin: .1rem 0;
|
||||||
|
line-height: 27px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.peer-typing-container {
|
||||||
|
--color: var(--secondary-text-color);
|
||||||
|
|
||||||
|
.peer-typing-text {
|
||||||
|
display: inline-flex;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.dialog {
|
.dialog {
|
||||||
&-title {
|
&-title {
|
||||||
&-details {
|
&-details {
|
||||||
|
@ -5,16 +5,34 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
.peer-typing {
|
.peer-typing {
|
||||||
display: inline-block;
|
//display: flex;
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
|
|
||||||
|
&-container {
|
||||||
|
--color: var(--primary-color);
|
||||||
|
color: var(--color);
|
||||||
|
//display: inline-block;
|
||||||
|
//display: flex;
|
||||||
|
//align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* &-description {
|
||||||
|
@include text-overflow();
|
||||||
|
} */
|
||||||
|
|
||||||
|
&:not(.peer-typing-text) {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
&-text {
|
&-text {
|
||||||
&-dot {
|
&-dot {
|
||||||
width: 6px;
|
width: 6px;
|
||||||
height: 6px;
|
height: 6px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: var(--primary-color);
|
background-color: var(--color);
|
||||||
margin: 0 1px;
|
margin: 0 .5px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
animation-duration: .6s;
|
animation-duration: .6s;
|
||||||
@ -31,6 +49,49 @@
|
|||||||
animation-name: dotLast;
|
animation-name: dotLast;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-upload {
|
||||||
|
width: 13px;
|
||||||
|
height: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
border-radius: 2px;
|
||||||
|
margin-right: .375rem;
|
||||||
|
|
||||||
|
&:before, &:after {
|
||||||
|
display: block;
|
||||||
|
content: " ";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
background-color: var(--color);
|
||||||
|
border-radius: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
opacity: .3;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
animation: upload 1s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-record {
|
||||||
|
margin-right: .375rem;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: var(--color);
|
||||||
|
animation: recordBlink 1.25s infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$scale-max: 1;
|
$scale-max: 1;
|
||||||
@ -111,3 +172,13 @@ $opacity-min: $opacity-max - ($opacity-step * 2);
|
|||||||
opacity: $opacity-max;
|
opacity: $opacity-max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes upload {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-13px);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translate(13px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -82,8 +82,8 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.peer-typing-text-dot {
|
.peer-typing-container {
|
||||||
background-color: #fff;
|
--color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-name {
|
.profile-name {
|
||||||
@ -162,6 +162,12 @@
|
|||||||
padding-bottom: .5rem;
|
padding-bottom: .5rem;
|
||||||
//margin-bottom: .75rem;
|
//margin-bottom: .75rem;
|
||||||
//box-shadow: 0px 1px 5px -1px rgba(0, 0, 0, .16);
|
//box-shadow: 0px 1px 5px -1px rgba(0, 0, 0, .16);
|
||||||
|
|
||||||
|
.profile-subtitle {
|
||||||
|
.peer-typing-container {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .search-super {
|
/* .search-super {
|
||||||
|
@ -24,12 +24,21 @@ $messages-container-width: 728px;
|
|||||||
$chat-input-size: 3.375rem;
|
$chat-input-size: 3.375rem;
|
||||||
$chat-input-handhelds-size: 2.875rem;
|
$chat-input-handhelds-size: 2.875rem;
|
||||||
$chat-padding: .8125rem;
|
$chat-padding: .8125rem;
|
||||||
$chat-padding-handhelds: .25rem;
|
$chat-padding-handhelds: .5rem;
|
||||||
|
$chat-input-inner-padding: .5rem;
|
||||||
|
$chat-input-inner-padding-handhelds: .25rem;
|
||||||
|
|
||||||
@function hover-color($color) {
|
@function hover-color($color) {
|
||||||
@return rgba($color, $hover-alpha);
|
@return rgba($color, $hover-alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* @mixin safari-overflow() {
|
||||||
|
html.is-safari & {
|
||||||
|
-webkit-mask-image: -webkit-radial-gradient(circle, white 100%, black 100%);
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
@import "mixins/hover";
|
@import "mixins/hover";
|
||||||
@import "mixins/respondTo";
|
@import "mixins/respondTo";
|
||||||
@import "mixins/textOverflow";
|
@import "mixins/textOverflow";
|
||||||
@ -90,6 +99,7 @@ $chat-padding-handhelds: .25rem;
|
|||||||
|
|
||||||
--chat-input-size: #{$chat-input-handhelds-size};
|
--chat-input-size: #{$chat-input-handhelds-size};
|
||||||
--chat-input-padding: #{$chat-padding-handhelds};
|
--chat-input-padding: #{$chat-padding-handhelds};
|
||||||
|
--chat-input-inner-padding: #{$chat-input-inner-padding-handhelds};
|
||||||
}
|
}
|
||||||
|
|
||||||
@include respond-to(not-handhelds) {
|
@include respond-to(not-handhelds) {
|
||||||
@ -97,10 +107,12 @@ $chat-padding-handhelds: .25rem;
|
|||||||
|
|
||||||
--chat-input-size: #{$chat-input-size};
|
--chat-input-size: #{$chat-input-size};
|
||||||
--chat-input-padding: #{$chat-padding};
|
--chat-input-padding: #{$chat-padding};
|
||||||
|
--chat-input-inner-padding: #{$chat-input-inner-padding};
|
||||||
}
|
}
|
||||||
|
|
||||||
@include respond-to(esg-bottom) {
|
@include respond-to(esg-bottom) {
|
||||||
--chat-input-size: #{$chat-input-handhelds-size};
|
--chat-input-size: #{$chat-input-handhelds-size};
|
||||||
|
--chat-input-inner-padding: #{$chat-input-inner-padding-handhelds};
|
||||||
}
|
}
|
||||||
|
|
||||||
@include respond-to(only-medium-screens) {
|
@include respond-to(only-medium-screens) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user