New bot commands menu
This commit is contained in:
parent
7f9c298a05
commit
d6b987eba4
@ -16,6 +16,7 @@ import AutocompleteHelperController from "./autocompleteHelperController";
|
||||
export default class AutocompleteHelper extends EventListenerBase<{
|
||||
hidden: () => void,
|
||||
visible: () => void,
|
||||
hiding: () => void
|
||||
}> {
|
||||
protected hidden = true;
|
||||
protected container: HTMLElement;
|
||||
@ -34,7 +35,7 @@ export default class AutocompleteHelper extends EventListenerBase<{
|
||||
|
||||
constructor(options: {
|
||||
appendTo: HTMLElement,
|
||||
controller: AutocompleteHelper['controller'],
|
||||
controller?: AutocompleteHelper['controller'],
|
||||
listType: AutocompleteHelper['listType'],
|
||||
onSelect: AutocompleteHelper['onSelect'],
|
||||
waitForKey?: AutocompleteHelper['waitForKey']
|
||||
@ -50,7 +51,7 @@ export default class AutocompleteHelper extends EventListenerBase<{
|
||||
|
||||
this.attachNavigation();
|
||||
|
||||
this.controller.addHelper(this);
|
||||
this.controller && this.controller.addHelper(this);
|
||||
}
|
||||
|
||||
public toggleListNavigation(enabled: boolean) {
|
||||
@ -110,7 +111,7 @@ export default class AutocompleteHelper extends EventListenerBase<{
|
||||
this.addEventListener('visible', this.onVisible);
|
||||
}
|
||||
|
||||
public toggle(hide?: boolean, fromController = false) {
|
||||
public toggle(hide?: boolean, fromController = false, skipAnimation?: boolean) {
|
||||
if(this.init) {
|
||||
return;
|
||||
}
|
||||
@ -130,7 +131,7 @@ export default class AutocompleteHelper extends EventListenerBase<{
|
||||
this.hidden = hide;
|
||||
|
||||
if(!hide) {
|
||||
this.controller.hideOtherHelpers(this);
|
||||
this.controller && this.controller.hideOtherHelpers(this);
|
||||
this.dispatchEvent('visible'); // fire it before so target will be set
|
||||
} else {
|
||||
if(this.navigationItem) {
|
||||
@ -138,7 +139,7 @@ export default class AutocompleteHelper extends EventListenerBase<{
|
||||
this.navigationItem = undefined;
|
||||
}
|
||||
|
||||
if(!fromController) {
|
||||
if(!fromController && this.controller) {
|
||||
this.controller.hideOtherHelpers();
|
||||
}
|
||||
|
||||
@ -147,8 +148,21 @@ export default class AutocompleteHelper extends EventListenerBase<{
|
||||
}
|
||||
}
|
||||
|
||||
SetTransition(this.container, 'is-visible', !hide, rootScope.settings.animationsEnabled ? 200 : 0, () => {
|
||||
this.hidden && this.dispatchEvent('hidden');
|
||||
});
|
||||
const useRafs = this.controller || hide ? 0 : 2;
|
||||
|
||||
if(hide) {
|
||||
this.dispatchEvent('hiding');
|
||||
}
|
||||
|
||||
SetTransition(
|
||||
this.container,
|
||||
'is-visible',
|
||||
!hide,
|
||||
rootScope.settings.animationsEnabled && !skipAnimation ? 300 : 0,
|
||||
() => {
|
||||
this.hidden && this.dispatchEvent('hidden');
|
||||
},
|
||||
useRafs
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,12 @@ export default class AutocompletePeerHelper extends AutocompleteHelper {
|
||||
protected static BASE_CLASS_LIST_ELEMENT = AutocompletePeerHelper.BASE_CLASS + '-list-element';
|
||||
private scrollable: Scrollable;
|
||||
|
||||
constructor(appendTo: HTMLElement, controller: AutocompleteHelperController, protected className: string, onSelect: (target: Element) => boolean | void) {
|
||||
constructor(
|
||||
appendTo: HTMLElement,
|
||||
controller: AutocompleteHelperController,
|
||||
protected className: string,
|
||||
onSelect: (target: Element) => boolean | void
|
||||
) {
|
||||
super({
|
||||
appendTo,
|
||||
controller,
|
||||
@ -29,7 +34,7 @@ export default class AutocompletePeerHelper extends AutocompleteHelper {
|
||||
|
||||
protected init() {
|
||||
this.list = document.createElement('div');
|
||||
this.list.classList.add(AutocompletePeerHelper.BASE_CLASS + '-list');
|
||||
this.list.classList.add(AutocompletePeerHelper.BASE_CLASS + '-list', this.className + '-list');
|
||||
|
||||
this.container.append(this.list);
|
||||
|
||||
@ -42,7 +47,7 @@ export default class AutocompletePeerHelper extends AutocompleteHelper {
|
||||
});
|
||||
}
|
||||
|
||||
public render(data: {peerId: PeerId, name?: string, description?: string}[]) {
|
||||
public render(data: {peerId: PeerId, name?: string, description?: string}[], doNotShow?: boolean) {
|
||||
if(this.init) {
|
||||
if(!data.length) {
|
||||
return;
|
||||
@ -66,7 +71,9 @@ export default class AutocompletePeerHelper extends AutocompleteHelper {
|
||||
});
|
||||
}
|
||||
|
||||
this.toggle(!data.length);
|
||||
if(!doNotShow) {
|
||||
this.toggle(!data.length);
|
||||
}
|
||||
}
|
||||
|
||||
public static listElement(options: {
|
||||
|
54
src/components/chat/botCommands.ts
Normal file
54
src/components/chat/botCommands.ts
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* https://github.com/morethanwords/tweb
|
||||
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
||||
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
import type { AppProfileManager } from "../../lib/appManagers/appProfileManager";
|
||||
import type ChatInput from "./input";
|
||||
import callbackify from "../../helpers/callbackify";
|
||||
import AutocompletePeerHelper from "./autocompletePeerHelper";
|
||||
import { processPeerFullForCommands } from "./commandsHelper";
|
||||
|
||||
const CLASS_NAME = 'bot-commands';
|
||||
export default class ChatBotCommands extends AutocompletePeerHelper {
|
||||
private userId: UserId;
|
||||
|
||||
constructor(
|
||||
appendTo: HTMLElement,
|
||||
private chatInput: ChatInput,
|
||||
private appProfileManager: AppProfileManager
|
||||
) {
|
||||
super(appendTo, undefined, CLASS_NAME, (target) => {
|
||||
const innerHTML = target.querySelector(`.${AutocompletePeerHelper.BASE_CLASS_LIST_ELEMENT}-name`).innerHTML;
|
||||
return chatInput.getReadyToSend(() => {
|
||||
chatInput.messageInput.innerHTML = innerHTML;
|
||||
chatInput.sendMessage(true);
|
||||
this.toggle(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public setUserId(userId: UserId, middleware: () => boolean) {
|
||||
if(this.userId === userId && this.list?.childElementCount) {
|
||||
this.toggle(false);
|
||||
return;
|
||||
}
|
||||
|
||||
this.userId = userId;
|
||||
return callbackify(this.appProfileManager.getProfile(userId), (full) => {
|
||||
if(!middleware()) return;
|
||||
const filtered = processPeerFullForCommands(full);
|
||||
|
||||
const PADDING_TOP = 8;
|
||||
// const PADDING_BOTTOM = 8;
|
||||
const PADDING_BOTTOM = 24;
|
||||
const height = filtered.length * 50 + PADDING_TOP + PADDING_BOTTOM;
|
||||
this.container.style.setProperty('--height', height + 'px');
|
||||
|
||||
this.render(filtered);
|
||||
|
||||
// this.container.style.top =
|
||||
});
|
||||
}
|
||||
}
|
@ -7,11 +7,46 @@
|
||||
import type ChatInput from "./input";
|
||||
import type { AppProfileManager } from "../../lib/appManagers/appProfileManager";
|
||||
import type { AppUsersManager } from "../../lib/appManagers/appUsersManager";
|
||||
import type { BotInfo } from "../../layer";
|
||||
import type { BotInfo, ChatFull, UserFull } from "../../layer";
|
||||
import AutocompleteHelperController from "./autocompleteHelperController";
|
||||
import AutocompletePeerHelper from "./autocompletePeerHelper";
|
||||
import SearchIndex from "../../lib/searchIndex";
|
||||
|
||||
export function processPeerFullForCommands(full: ChatFull.chatFull | ChatFull.channelFull | UserFull.userFull, query?: string) {
|
||||
const botInfos: BotInfo.botInfo[] = [].concat(full.bot_info);
|
||||
let index: SearchIndex<string>;
|
||||
|
||||
if(query !== undefined) {
|
||||
index = new SearchIndex<string>({
|
||||
ignoreCase: true
|
||||
});
|
||||
}
|
||||
|
||||
const commands: Map<string, {peerId: PeerId, name: string, description: string}> = new Map();
|
||||
botInfos.forEach(botInfo => {
|
||||
botInfo.commands.forEach(botCommand => {
|
||||
const c = '/' + botCommand.command;
|
||||
commands.set(botCommand.command, {
|
||||
peerId: botInfo.user_id.toPeerId(false),
|
||||
name: c,
|
||||
description: botCommand.description
|
||||
});
|
||||
|
||||
if(index) {
|
||||
index.indexObject(botCommand.command, c);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if(!index) {
|
||||
return [...commands.values()];
|
||||
}
|
||||
|
||||
const found = index.search(query);
|
||||
const filtered = Array.from(found).map(command => commands.get(command));
|
||||
return filtered;
|
||||
}
|
||||
|
||||
export default class CommandsHelper extends AutocompletePeerHelper {
|
||||
constructor(appendTo: HTMLElement,
|
||||
controller: AutocompleteHelperController,
|
||||
@ -42,27 +77,7 @@ export default class CommandsHelper extends AutocompletePeerHelper {
|
||||
return;
|
||||
}
|
||||
|
||||
const botInfos: BotInfo.botInfo[] = [].concat(full.bot_info);
|
||||
const index = new SearchIndex<string>({
|
||||
ignoreCase: true
|
||||
});
|
||||
|
||||
const commands: Map<string, {peerId: PeerId, name: string, description: string}> = new Map();
|
||||
botInfos.forEach(botInfo => {
|
||||
botInfo.commands.forEach(botCommand => {
|
||||
const c = '/' + botCommand.command;
|
||||
commands.set(botCommand.command, {
|
||||
peerId: botInfo.user_id.toPeerId(false),
|
||||
name: c,
|
||||
description: botCommand.description
|
||||
});
|
||||
|
||||
index.indexObject(botCommand.command, c);
|
||||
});
|
||||
});
|
||||
|
||||
const found = index.search(query);
|
||||
const filtered = Array.from(found).map(command => commands.get(command));
|
||||
const filtered = processPeerFullForCommands(full, query);
|
||||
this.render(filtered);
|
||||
// console.log('found commands', found, filtered);
|
||||
});
|
||||
|
@ -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, ChatFull } from '../../layer';
|
||||
import { MessageEntity, DraftMessage, WebPage, Message, ChatFull, UserFull } from '../../layer';
|
||||
import StickersHelper from './stickersHelper';
|
||||
import ButtonIcon from '../buttonIcon';
|
||||
import ButtonMenuToggle from '../buttonMenuToggle';
|
||||
@ -91,6 +91,7 @@ import AvatarElement from '../avatar';
|
||||
import type { AppProfileManager } from '../../lib/appManagers/appProfileManager';
|
||||
import { indexOfAndSplice } from '../../helpers/array';
|
||||
import callbackify from '../../helpers/callbackify';
|
||||
import ChatBotCommands from './botCommands';
|
||||
|
||||
const RECORD_MIN_TIME = 500;
|
||||
const POSTING_MEDIA_NOT_ALLOWED = 'Posting media content isn\'t allowed in this group.';
|
||||
@ -222,6 +223,11 @@ export default class ChatInput {
|
||||
public sendAsPeerId: PeerId;
|
||||
private updatingSendAsPromise: Promise<void>;
|
||||
|
||||
private botCommandsToggle: HTMLElement;
|
||||
private botCommands: ChatBotCommands;
|
||||
private botCommandsIcon: HTMLDivElement;
|
||||
hasBotCommands: number;
|
||||
|
||||
// private activeContainer: HTMLElement;
|
||||
|
||||
constructor(
|
||||
@ -573,6 +579,38 @@ export default class ChatInput {
|
||||
});
|
||||
this.listenerSetter.add(this.replyKeyboard)('open', () => this.btnToggleReplyMarkup.classList.add('active'));
|
||||
this.listenerSetter.add(this.replyKeyboard)('close', () => this.btnToggleReplyMarkup.classList.remove('active'));
|
||||
|
||||
this.botCommands = new ChatBotCommands(this.rowsWrapper, this, this.appProfileManager);
|
||||
this.botCommandsToggle = document.createElement('div');
|
||||
this.botCommandsToggle.classList.add('new-message-bot-commands');
|
||||
|
||||
const scaler = document.createElement('div');
|
||||
scaler.classList.add('new-message-bot-commands-icon-scale');
|
||||
|
||||
const icon = this.botCommandsIcon = document.createElement('div');
|
||||
icon.classList.add('animated-menu-icon', 'animated-menu-close-icon');
|
||||
scaler.append(icon);
|
||||
this.botCommandsToggle.append(scaler);
|
||||
|
||||
attachClickEvent(this.botCommandsToggle, (e) => {
|
||||
cancelEvent(e);
|
||||
const isShown = icon.classList.contains('state-back');
|
||||
if(isShown) {
|
||||
this.botCommands.toggle(true);
|
||||
icon.classList.remove('state-back');
|
||||
} else {
|
||||
this.botCommands.setUserId(this.chat.peerId.toUserId(), this.chat.bubbles.getMiddleware());
|
||||
icon.classList.add('state-back');
|
||||
}
|
||||
}, {listenerSetter: this.listenerSetter});
|
||||
|
||||
this.botCommands.addEventListener('visible', () => {
|
||||
icon.classList.add('state-back');
|
||||
});
|
||||
|
||||
this.botCommands.addEventListener('hiding', () => {
|
||||
icon.classList.remove('state-back');
|
||||
});
|
||||
}
|
||||
|
||||
this.attachMenuButtons = [{
|
||||
@ -619,7 +657,7 @@ export default class ChatInput {
|
||||
this.fileInput.multiple = true;
|
||||
this.fileInput.style.display = 'none';
|
||||
|
||||
this.newMessageWrapper.append(...[this.sendAsContainer, this.btnToggleEmoticons, this.inputMessageContainer, this.btnScheduled, this.btnToggleReplyMarkup, this.attachMenu, this.recordTimeEl, this.fileInput].filter(Boolean));
|
||||
this.newMessageWrapper.append(...[this.sendAsContainer, this.botCommandsToggle, 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();
|
||||
@ -1194,7 +1232,7 @@ export default class ChatInput {
|
||||
public finishPeerChange(startParam?: string) {
|
||||
const peerId = this.chat.peerId;
|
||||
|
||||
const {forwardElements, btnScheduled, replyKeyboard, sendMenu, goDownBtn, chatInput, sendAsContainer} = this;
|
||||
const {forwardElements, btnScheduled, replyKeyboard, sendMenu, goDownBtn, chatInput, sendAsContainer, botCommandsToggle} = this;
|
||||
chatInput.style.display = '';
|
||||
|
||||
const isBroadcast = this.appPeersManager.isBroadcast(peerId);
|
||||
@ -1225,6 +1263,24 @@ export default class ChatInput {
|
||||
});
|
||||
}
|
||||
|
||||
this.updateOffset(null, false, true);
|
||||
|
||||
if(botCommandsToggle) {
|
||||
this.hasBotCommands = undefined;
|
||||
this.botCommands.toggle(true, undefined, true);
|
||||
this.updateBotCommandsToggle(true);
|
||||
botCommandsToggle.remove();
|
||||
if(this.appPeersManager.isBot(peerId)) {
|
||||
const userId = peerId.toUserId();
|
||||
const middleware = this.chat.bubbles.getMiddleware();
|
||||
const getUserFullResult = this.appProfileManager.getProfile(userId);
|
||||
callbackify(getUserFullResult, (userFull) => {
|
||||
if(!middleware()) return;
|
||||
this.updateBotCommands(userFull, !(getUserFullResult instanceof Promise));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(sendAsContainer) {
|
||||
if(this.sendAsAvatar) {
|
||||
this.sendAsAvatar.remove();
|
||||
@ -1232,7 +1288,6 @@ export default class ChatInput {
|
||||
}
|
||||
|
||||
sendAsContainer.remove();
|
||||
SetTransition(this.newMessageWrapper, 'has-send-as', false, 0);
|
||||
this.sendAsPeerId = undefined;
|
||||
this.updatingSendAsPromise = undefined;
|
||||
|
||||
@ -1261,6 +1316,39 @@ export default class ChatInput {
|
||||
this.center(false);
|
||||
}
|
||||
|
||||
private updateOffset(type: 'commands' | 'as', forwards: boolean, skipAnimation?: boolean, useRafs?: number) {
|
||||
if(type) {
|
||||
this.newMessageWrapper.dataset.offset = type;
|
||||
} else {
|
||||
delete this.newMessageWrapper.dataset.offset;
|
||||
}
|
||||
|
||||
SetTransition(this.newMessageWrapper, 'has-offset', forwards, skipAnimation ? 0 : 300, undefined, useRafs);
|
||||
}
|
||||
|
||||
private updateBotCommands(userFull: UserFull.userFull, skipAnimation?: boolean) {
|
||||
this.hasBotCommands = userFull.bot_info && userFull.bot_info.commands.length;
|
||||
this.updateBotCommandsToggle(skipAnimation);
|
||||
}
|
||||
|
||||
private updateBotCommandsToggle(skipAnimation?: boolean) {
|
||||
const {botCommandsToggle, hasBotCommands} = this;
|
||||
|
||||
const show = hasBotCommands && this.isInputEmpty();
|
||||
if(!hasBotCommands) {
|
||||
botCommandsToggle.remove();
|
||||
}
|
||||
|
||||
const forwards = show;
|
||||
const useRafs = botCommandsToggle.parentElement ? 0 : 2;
|
||||
|
||||
if(!botCommandsToggle.parentElement) {
|
||||
this.newMessageWrapper.prepend(botCommandsToggle);
|
||||
}
|
||||
|
||||
this.updateOffset('commands', forwards, skipAnimation, useRafs);
|
||||
}
|
||||
|
||||
private updateSendAsButtons(peerIds: PeerId[]) {
|
||||
const buttons: ButtonMenuItemOptions[] = peerIds.map((sendAsPeerId, idx) => {
|
||||
const textElement = document.createElement('div');
|
||||
@ -1415,7 +1503,7 @@ export default class ChatInput {
|
||||
useRafs = 2;
|
||||
}
|
||||
|
||||
SetTransition(this.newMessageWrapper, 'has-send-as', true, skipAnimation ? 0 : SEND_AS_ANIMATION_DURATION, undefined, useRafs);
|
||||
this.updateOffset('as', true, skipAnimation, useRafs);
|
||||
|
||||
this.updatingSendAsPromise = undefined;
|
||||
});
|
||||
@ -1850,7 +1938,8 @@ export default class ChatInput {
|
||||
}
|
||||
}
|
||||
|
||||
if(!richValue.trim()) {
|
||||
const isEmpty = !richValue.trim();
|
||||
if(isEmpty) {
|
||||
if(this.lastTimeType) {
|
||||
this.appMessagesManager.setTyping(this.chat.peerId, {_: 'sendMessageCancelAction'});
|
||||
}
|
||||
@ -1864,6 +1953,14 @@ export default class ChatInput {
|
||||
this.lastTimeType = time;
|
||||
this.appMessagesManager.setTyping(this.chat.peerId, {_: 'sendMessageTypingAction'});
|
||||
}
|
||||
|
||||
if(this.botCommands) {
|
||||
this.botCommands.toggle(true);
|
||||
}
|
||||
}
|
||||
|
||||
if(this.botCommands) {
|
||||
this.updateBotCommandsToggle();
|
||||
}
|
||||
|
||||
if(!this.editMsgId) {
|
||||
|
@ -96,7 +96,11 @@ Utility Classes
|
||||
}
|
||||
|
||||
.no-transition {
|
||||
transition: none !important;
|
||||
&,
|
||||
&:before,
|
||||
&:after {
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
/* &-all, &-all * {
|
||||
transition: none !important;
|
||||
|
@ -31,12 +31,6 @@
|
||||
&, &:before, &:after {
|
||||
transition: transform var(--slide-header-transition);
|
||||
}
|
||||
|
||||
&.no-transition {
|
||||
&, &:before, &:after {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.state-back {
|
||||
@ -53,13 +47,14 @@
|
||||
}
|
||||
|
||||
.animated-menu-icon {
|
||||
--color: var(--secondary-text-color);
|
||||
position: absolute;
|
||||
|
||||
&, &:before, &:after {
|
||||
width: 1.125rem;
|
||||
height: .125rem;
|
||||
border-radius: .125rem;
|
||||
background-color: var(--secondary-text-color);
|
||||
background-color: var(--color);
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
@ -96,6 +91,48 @@
|
||||
}
|
||||
}
|
||||
|
||||
.animated-menu-close-icon {
|
||||
margin-top: -.625rem;
|
||||
|
||||
&:before {
|
||||
top: .3125rem;
|
||||
opacity: 1;
|
||||
|
||||
@include animation-level(2) {
|
||||
transition: transform .25s, opacity .125s 0s;
|
||||
}
|
||||
}
|
||||
|
||||
&:after {
|
||||
top: .625rem;
|
||||
}
|
||||
|
||||
&.state-back {
|
||||
transform: translate(0, .3125rem) rotate(135deg);
|
||||
|
||||
&:before {
|
||||
transform: rotate(45deg);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&:after {
|
||||
transform: translate(-.0rem, -.625rem) rotate(90deg);
|
||||
}
|
||||
}
|
||||
/* &.state-back {
|
||||
transform: rotate(135deg) translate(.25rem, -.1875rem);
|
||||
|
||||
&:before {
|
||||
transform: rotate(45deg);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&:after {
|
||||
transform: rotate(90deg) translate(-.625rem, 0rem);
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
.animated-button-icon {
|
||||
> .tgico {
|
||||
position: absolute;
|
||||
|
@ -5,7 +5,8 @@
|
||||
*/
|
||||
|
||||
$btn-send-margin: .5rem;
|
||||
$chat-helper-size: 36px;
|
||||
$chat-helper-size: 45px;
|
||||
$chat-input-box-shadow: 0px 1px 8px 1px rgb(0 0 0 / 18%);
|
||||
|
||||
$input-transition-time: .2s;
|
||||
$input-half-transition-time: #{$input-transition-time / 2};
|
||||
@ -765,7 +766,7 @@ $background-transition-total-time: #{$input-transition-time - $background-transi
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
border-radius: inherit;
|
||||
box-shadow: 0px 1px 8px 1px rgb(0 0 0 / 18%);
|
||||
box-shadow: $chat-input-box-shadow;
|
||||
background-color: #fff;
|
||||
background-color: var(--surface-color);
|
||||
opacity: 1;
|
||||
@ -1047,9 +1048,9 @@ $background-transition-total-time: #{$input-transition-time - $background-transi
|
||||
height: 100%;
|
||||
z-index: 1; */
|
||||
height: 0;
|
||||
width: calc(100% - var(--padding-horizontal) * 2);
|
||||
padding: 0;
|
||||
margin-top: .5625rem;//var(--padding-vertical);
|
||||
width: 100%;
|
||||
padding: .5625rem var(--padding-horizontal) 0;
|
||||
// margin-top: .5625rem;//var(--padding-vertical);
|
||||
margin-bottom: -.5625rem;
|
||||
//height: calc(#{$chat-helper-size} + .3125rem);
|
||||
align-items: center;
|
||||
@ -1064,7 +1065,7 @@ $background-transition-total-time: #{$input-transition-time - $background-transi
|
||||
}
|
||||
|
||||
@include respond-to(esg-bottom-new) {
|
||||
margin-top: .3125rem;
|
||||
padding-top: .3125rem;
|
||||
margin-bottom: -.3125rem;
|
||||
}
|
||||
|
||||
@ -1163,29 +1164,78 @@ $background-transition-total-time: #{$input-transition-time - $background-transi
|
||||
} */
|
||||
}
|
||||
|
||||
/* &:after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: .0625rem;
|
||||
background-color: var(--border-color);
|
||||
opacity: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&.have-commands {
|
||||
&:after {
|
||||
opacity: 1;
|
||||
}
|
||||
} */
|
||||
|
||||
.new-message-wrapper {
|
||||
--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));
|
||||
--commands-size: 2.375rem;
|
||||
--commands-margin-left: .25rem;
|
||||
--commands-margin-right: .375rem;
|
||||
--commands-total-size: calc(var(--commands-size) + var(--commands-margin-left) + var(--commands-margin-right));
|
||||
--offset-translateX: 0px;
|
||||
//padding: 4.5px 0;
|
||||
//padding-bottom: 4.5px;
|
||||
align-items: flex-end;
|
||||
min-height: var(--chat-input-size);
|
||||
|
||||
.new-message-bot-commands,
|
||||
.new-message-send-as-container {
|
||||
position: absolute;
|
||||
flex: 0 0 auto;
|
||||
bottom: calc(var(--padding-vertical) + .4375rem);
|
||||
cursor: pointer;
|
||||
transform: scale(0);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.new-message-bot-commands {
|
||||
width: var(--commands-size);
|
||||
height: 1.875rem;
|
||||
border-radius: 1.875rem;
|
||||
background-color: var(--primary-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: var(--commands-margin-left);
|
||||
cursor: pointer;
|
||||
|
||||
&-icon-scale {
|
||||
transform: scale(.875);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.animated-menu-close-icon {
|
||||
--color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.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-left: var(--send-as-margin-left);
|
||||
bottom: calc(var(--padding-vertical) + .4375rem);
|
||||
cursor: pointer;
|
||||
transform: scale(0);
|
||||
background: none !important;
|
||||
z-index: 2;
|
||||
|
||||
.btn-menu {
|
||||
max-height: 20rem;
|
||||
@ -1253,7 +1303,15 @@ $background-transition-total-time: #{$input-transition-time - $background-transi
|
||||
}
|
||||
}
|
||||
|
||||
&.has-send-as {
|
||||
&.has-offset {
|
||||
&[data-offset="as"] {
|
||||
--offset-translateX: var(--send-as-total-size);
|
||||
}
|
||||
|
||||
&[data-offset="commands"] {
|
||||
--offset-translateX: 48px;
|
||||
}
|
||||
|
||||
.toggle-emoticons,
|
||||
.input-message-container {
|
||||
transform: translateX(0);
|
||||
@ -1261,16 +1319,17 @@ $background-transition-total-time: #{$input-transition-time - $background-transi
|
||||
|
||||
&:not(.backwards) {
|
||||
.toggle-emoticons {
|
||||
transform: translateX(var(--send-as-total-size));
|
||||
transform: translateX(var(--offset-translateX));
|
||||
}
|
||||
|
||||
.input-message-container {
|
||||
--translateX: calc(var(--send-as-total-size));
|
||||
--translateX: calc(var(--offset-translateX));
|
||||
padding-right: var(--translateX);
|
||||
transform: translate(var(--translateX));
|
||||
}
|
||||
|
||||
.new-message-send-as-container {
|
||||
.new-message-send-as-container,
|
||||
.new-message-bot-commands {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
@ -1278,7 +1337,8 @@ $background-transition-total-time: #{$input-transition-time - $background-transi
|
||||
&.animating {
|
||||
.toggle-emoticons,
|
||||
.input-message-container,
|
||||
.new-message-send-as-container {
|
||||
.new-message-send-as-container,
|
||||
.new-message-bot-commands {
|
||||
transition: transform var(--transition-standard-in);
|
||||
}
|
||||
}
|
||||
|
85
src/scss/partials/_chatBotCommands.scss
Normal file
85
src/scss/partials/_chatBotCommands.scss
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* https://github.com/morethanwords/tweb
|
||||
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
||||
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
.bot-commands {
|
||||
--border-radius-padding: #{$border-radius-big * 2};
|
||||
--offset: .5rem;
|
||||
position: absolute !important;
|
||||
// bottom: 100%;
|
||||
bottom: calc(100% - var(--border-radius-padding));
|
||||
right: calc(var(--offset) * -1);
|
||||
left: calc(var(--offset) * -1);
|
||||
width: auto !important;
|
||||
max-height: 20rem;
|
||||
max-width: none;
|
||||
border-radius: $border-radius-big $border-radius-big 0 0 !important;
|
||||
background-color: transparent !important;
|
||||
pointer-events: none;
|
||||
overflow: hidden;
|
||||
padding: var(--offset) var(--offset) 0 !important;
|
||||
box-shadow: none;
|
||||
animation: none !important;
|
||||
visibility: visible !important;
|
||||
transition: none !important;
|
||||
display: flex !important;
|
||||
|
||||
.scrollable {
|
||||
background-color: var(--surface-color);
|
||||
box-shadow: $chat-input-box-shadow;
|
||||
border-radius: inherit;
|
||||
height: auto;
|
||||
pointer-events: all;
|
||||
// max-height: 20rem;
|
||||
|
||||
@include animation-level(2) {
|
||||
opacity: 0;
|
||||
transform: translateY(var(--height));
|
||||
}
|
||||
}
|
||||
|
||||
&.is-visible {
|
||||
&.animating {
|
||||
.scrollable {
|
||||
transition: transform var(--transition-standard-in), opacity var(--transition-standard-in);
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.backwards) {
|
||||
.scrollable {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-list {
|
||||
border-radius: inherit;
|
||||
width: 100%;
|
||||
height: var(--height);
|
||||
// padding-bottom: var(--border-radius-padding);
|
||||
padding-bottom: 0;
|
||||
|
||||
&-element {
|
||||
border-radius: 0 !important;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
padding-left: 3.375rem;
|
||||
|
||||
&-avatar {
|
||||
position: absolute;
|
||||
left: .75rem;
|
||||
}
|
||||
|
||||
&-name,
|
||||
&-description {
|
||||
margin-left: 0;
|
||||
font-size: .875rem;
|
||||
line-height: var(--line-height-14);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -307,6 +307,7 @@ $chat-input-inner-padding-handhelds: .25rem;
|
||||
@import "partials/chatInlineHelper";
|
||||
@import "partials/chatSearch";
|
||||
@import "partials/chatDrop";
|
||||
@import "partials/chatBotCommands";
|
||||
@import "partials/crop";
|
||||
@import "partials/sidebar";
|
||||
@import "partials/profile";
|
||||
|
Loading…
x
Reference in New Issue
Block a user