Fix showing autocomplete helper when it's unneeded
This commit is contained in:
parent
d203337cb7
commit
b8c3310d78
@ -86,12 +86,14 @@ export default class AutocompleteHelper extends EventListenerBase<{
|
|||||||
this.addEventListener('visible', this.onVisible);
|
this.addEventListener('visible', this.onVisible);
|
||||||
}
|
}
|
||||||
|
|
||||||
public toggle(hide?: boolean) {
|
public toggle(hide?: boolean, fromController = false) {
|
||||||
if(this.init) {
|
if(this.init) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hide = hide === undefined ? this.container.classList.contains('is-visible') && !this.container.classList.contains('backwards') : hide;
|
if(hide === undefined) {
|
||||||
|
hide = this.container.classList.contains('is-visible') && !this.container.classList.contains('backwards');
|
||||||
|
}
|
||||||
|
|
||||||
if(this.hidden === hide) {
|
if(this.hidden === hide) {
|
||||||
if(!hide && this.resetTarget) {
|
if(!hide && this.resetTarget) {
|
||||||
@ -103,10 +105,10 @@ export default class AutocompleteHelper extends EventListenerBase<{
|
|||||||
|
|
||||||
this.hidden = hide;
|
this.hidden = hide;
|
||||||
|
|
||||||
if(!this.hidden) {
|
if(!hide) {
|
||||||
this.controller.hideOtherHelpers(this);
|
this.controller.hideOtherHelpers(this);
|
||||||
this.dispatchEvent('visible'); // fire it before so target will be set
|
this.dispatchEvent('visible'); // fire it before so target will be set
|
||||||
} else {
|
} else if(!fromController) {
|
||||||
this.controller.hideOtherHelpers();
|
this.controller.hideOtherHelpers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,11 +29,15 @@ export default class AutocompleteHelperController {
|
|||||||
this.helpers.add(helper);
|
this.helpers.add(helper);
|
||||||
}
|
}
|
||||||
|
|
||||||
public hideOtherHelpers(helper?: AutocompleteHelper) {
|
public hideOtherHelpers(preserveHelper?: AutocompleteHelper) {
|
||||||
this.helpers.forEach(h => {
|
this.helpers.forEach(helper => {
|
||||||
if(h !== helper) {
|
if(helper !== preserveHelper) {
|
||||||
h.toggle(true);
|
helper.toggle(true, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(!preserveHelper) {
|
||||||
|
this.middleware.clean();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type ChatInput from "./input";
|
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 AutocompleteHelperController from "./autocompleteHelperController";
|
import AutocompleteHelperController from "./autocompleteHelperController";
|
||||||
import AutocompletePeerHelper from "./autocompletePeerHelper";
|
import AutocompletePeerHelper from "./autocompletePeerHelper";
|
||||||
|
import SearchIndex from "../../lib/searchIndex";
|
||||||
|
|
||||||
export default class CommandsHelper extends AutocompletePeerHelper {
|
export default class CommandsHelper extends AutocompletePeerHelper {
|
||||||
constructor(appendTo: HTMLElement, controller: AutocompleteHelperController, private chatInput: ChatInput) {
|
constructor(appendTo: HTMLElement,
|
||||||
|
controller: AutocompleteHelperController,
|
||||||
|
chatInput: ChatInput,
|
||||||
|
private appProfileManager: AppProfileManager,
|
||||||
|
private appUsersManager: AppUsersManager) {
|
||||||
super(appendTo,
|
super(appendTo,
|
||||||
controller,
|
controller,
|
||||||
'commands-helper',
|
'commands-helper',
|
||||||
@ -20,4 +28,41 @@ export default class CommandsHelper extends AutocompletePeerHelper {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public checkQuery(query: string, peerId: number) {
|
||||||
|
if(!this.appUsersManager.isBot(peerId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const middleware = this.controller.getMiddleware();
|
||||||
|
this.appProfileManager.getProfileByPeerId(peerId).then(full => {
|
||||||
|
if(!middleware()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const botInfos: BotInfo.botInfo[] = [].concat(full.bot_info);
|
||||||
|
const index = new SearchIndex<string>(false, false);
|
||||||
|
|
||||||
|
const commands: Map<string, {peerId: number, 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,
|
||||||
|
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));
|
||||||
|
this.render(filtered);
|
||||||
|
// console.log('found commands', found, filtered);
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type ChatInput from "./input";
|
import type ChatInput from "./input";
|
||||||
|
import type { AppEmojiManager } from "../../lib/appManagers/appEmojiManager";
|
||||||
import { appendEmoji, getEmojiFromElement } from "../emoticonsDropdown/tabs/emoji";
|
import { appendEmoji, getEmojiFromElement } from "../emoticonsDropdown/tabs/emoji";
|
||||||
import { ScrollableX } from "../scrollable";
|
import { ScrollableX } from "../scrollable";
|
||||||
import AutocompleteHelper from "./autocompleteHelper";
|
import AutocompleteHelper from "./autocompleteHelper";
|
||||||
@ -13,13 +14,16 @@ import AutocompleteHelperController from "./autocompleteHelperController";
|
|||||||
export default class EmojiHelper extends AutocompleteHelper {
|
export default class EmojiHelper extends AutocompleteHelper {
|
||||||
private scrollable: ScrollableX;
|
private scrollable: ScrollableX;
|
||||||
|
|
||||||
constructor(appendTo: HTMLElement, controller: AutocompleteHelperController, private chatInput: ChatInput) {
|
constructor(appendTo: HTMLElement,
|
||||||
|
controller: AutocompleteHelperController,
|
||||||
|
chatInput: ChatInput,
|
||||||
|
private appEmojiManager: AppEmojiManager) {
|
||||||
super({
|
super({
|
||||||
appendTo,
|
appendTo,
|
||||||
controller,
|
controller,
|
||||||
listType: 'x',
|
listType: 'x',
|
||||||
onSelect: (target) => {
|
onSelect: (target) => {
|
||||||
this.chatInput.onEmojiSelected(getEmojiFromElement(target as any), true);
|
chatInput.onEmojiSelected(getEmojiFromElement(target as any), true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -51,6 +55,8 @@ export default class EmojiHelper extends AutocompleteHelper {
|
|||||||
this.init = null;
|
this.init = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emojis = emojis.slice(0, 80);
|
||||||
|
|
||||||
if(emojis.length) {
|
if(emojis.length) {
|
||||||
this.list.innerHTML = '';
|
this.list.innerHTML = '';
|
||||||
emojis.forEach(emoji => {
|
emojis.forEach(emoji => {
|
||||||
@ -65,4 +71,18 @@ export default class EmojiHelper extends AutocompleteHelper {
|
|||||||
this.container.style.width = (3 * 2) + (emojis.length * 44) + 'px';
|
this.container.style.width = (3 * 2) + (emojis.length * 44) + 'px';
|
||||||
}); */
|
}); */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public checkQuery(query: string, firstChar: string) {
|
||||||
|
const middleware = this.controller.getMiddleware();
|
||||||
|
this.appEmojiManager.getBothEmojiKeywords().then(() => {
|
||||||
|
if(!middleware()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const q = query.replace(/^:/, '');
|
||||||
|
const emojis = this.appEmojiManager.searchEmojis(q);
|
||||||
|
this.render(emojis, firstChar !== ':');
|
||||||
|
//console.log(emojis);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,11 +60,9 @@ import { MarkdownType, markdownTags } from '../../helpers/dom/getRichElementValu
|
|||||||
import getRichValueWithCaret from '../../helpers/dom/getRichValueWithCaret';
|
import getRichValueWithCaret from '../../helpers/dom/getRichValueWithCaret';
|
||||||
import EmojiHelper from './emojiHelper';
|
import EmojiHelper from './emojiHelper';
|
||||||
import setRichFocus from '../../helpers/dom/setRichFocus';
|
import setRichFocus from '../../helpers/dom/setRichFocus';
|
||||||
import SearchIndex from '../../lib/searchIndex';
|
|
||||||
import CommandsHelper from './commandsHelper';
|
import CommandsHelper from './commandsHelper';
|
||||||
import AutocompleteHelperController from './autocompleteHelperController';
|
import AutocompleteHelperController from './autocompleteHelperController';
|
||||||
import AutocompleteHelper from './autocompleteHelper';
|
import AutocompleteHelper from './autocompleteHelper';
|
||||||
import appUsersManager from '../../lib/appManagers/appUsersManager';
|
|
||||||
import MentionsHelper from './mentionsHelper';
|
import MentionsHelper from './mentionsHelper';
|
||||||
|
|
||||||
const RECORD_MIN_TIME = 500;
|
const RECORD_MIN_TIME = 500;
|
||||||
@ -372,9 +370,9 @@ export default class ChatInput {
|
|||||||
this.rowsWrapper.append(this.replyElements.container);
|
this.rowsWrapper.append(this.replyElements.container);
|
||||||
this.autocompleteHelperController = new AutocompleteHelperController();
|
this.autocompleteHelperController = new AutocompleteHelperController();
|
||||||
this.stickersHelper = new StickersHelper(this.rowsWrapper, this.autocompleteHelperController);
|
this.stickersHelper = new StickersHelper(this.rowsWrapper, this.autocompleteHelperController);
|
||||||
this.emojiHelper = new EmojiHelper(this.rowsWrapper, this.autocompleteHelperController, this);
|
this.emojiHelper = new EmojiHelper(this.rowsWrapper, this.autocompleteHelperController, this, this.appEmojiManager);
|
||||||
this.commandsHelper = new CommandsHelper(this.rowsWrapper, this.autocompleteHelperController, this);
|
this.commandsHelper = new CommandsHelper(this.rowsWrapper, this.autocompleteHelperController, this, this.chat.appProfileManager, this.chat.appUsersManager);
|
||||||
this.mentionsHelper = new MentionsHelper(this.rowsWrapper, this.autocompleteHelperController, this);
|
this.mentionsHelper = new MentionsHelper(this.rowsWrapper, this.autocompleteHelperController, this, this.chat.appProfileManager, this.chat.appUsersManager);
|
||||||
this.rowsWrapper.append(this.newMessageWrapper);
|
this.rowsWrapper.append(this.newMessageWrapper);
|
||||||
|
|
||||||
this.btnCancelRecord = ButtonIcon('delete danger btn-circle z-depth-1 btn-record-cancel');
|
this.btnCancelRecord = ButtonIcon('delete danger btn-circle z-depth-1 btn-record-cancel');
|
||||||
@ -1258,61 +1256,18 @@ export default class ChatInput {
|
|||||||
//console.log('autocomplete matches', matches);
|
//console.log('autocomplete matches', matches);
|
||||||
|
|
||||||
if(firstChar === '@') { // mentions
|
if(firstChar === '@') { // mentions
|
||||||
const trimmed = query.trim(); // check that there is no whitespace
|
|
||||||
if(this.chat.peerId < 0 && query.length === trimmed.length) {
|
|
||||||
foundHelper = this.mentionsHelper;
|
|
||||||
const topMsgId = this.chat.threadId ? this.appMessagesManager.getServerMessageId(this.chat.threadId) : undefined;
|
const topMsgId = this.chat.threadId ? this.appMessagesManager.getServerMessageId(this.chat.threadId) : undefined;
|
||||||
this.chat.appProfileManager.getMentions(-this.chat.peerId, trimmed, topMsgId).then(peerIds => {
|
if(this.mentionsHelper.checkQuery(query, this.chat.peerId, topMsgId)) {
|
||||||
const username = trimmed.slice(1).toLowerCase();
|
foundHelper = this.mentionsHelper;
|
||||||
this.mentionsHelper.render(peerIds.map(peerId => {
|
|
||||||
const user = this.chat.appUsersManager.getUser(peerId);
|
|
||||||
if(user.username && user.username.toLowerCase() === username) { // hide full matched suggestion
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
peerId,
|
|
||||||
description: user.username ? '@' + user.username : undefined
|
|
||||||
};
|
|
||||||
}).filter(Boolean));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else if(!matches[1] && firstChar === '/') { // commands
|
} else if(!matches[1] && firstChar === '/') { // commands
|
||||||
if(appUsersManager.isBot(this.chat.peerId)) {
|
if(this.commandsHelper.checkQuery(query, this.chat.peerId)) {
|
||||||
foundHelper = this.commandsHelper;
|
foundHelper = this.commandsHelper;
|
||||||
this.chat.appProfileManager.getProfileByPeerId(this.chat.peerId).then(full => {
|
|
||||||
const botInfos: BotInfo.botInfo[] = [].concat(full.bot_info);
|
|
||||||
const index = new SearchIndex<string>(true, false);
|
|
||||||
|
|
||||||
const commands: Map<string, {peerId: number, 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,
|
|
||||||
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));
|
|
||||||
this.commandsHelper.render(filtered);
|
|
||||||
// console.log('found commands', found, filtered);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else if(rootScope.settings.emoji.suggest) { // emoji
|
} else if(rootScope.settings.emoji.suggest) { // emoji
|
||||||
if(!value.match(/^\s*:(.+):\s*$/)) {
|
if(!value.match(/^\s*:(.+):\s*$/)) {
|
||||||
foundHelper = this.emojiHelper;
|
foundHelper = this.emojiHelper;
|
||||||
this.appEmojiManager.getBothEmojiKeywords().then(() => {
|
this.emojiHelper.checkQuery(query, firstChar);
|
||||||
const q = query.replace(/^:/, '');
|
|
||||||
const emojis = this.appEmojiManager.searchEmojis(q);
|
|
||||||
this.emojiHelper.render(emojis, firstChar !== ':');
|
|
||||||
//console.log(emojis);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,12 +6,17 @@
|
|||||||
|
|
||||||
import type ChatInput from "./input";
|
import type ChatInput from "./input";
|
||||||
import type { MessageEntity } from "../../layer";
|
import type { MessageEntity } from "../../layer";
|
||||||
|
import type { AppProfileManager } from "../../lib/appManagers/appProfileManager";
|
||||||
|
import type { AppUsersManager } from "../../lib/appManagers/appUsersManager";
|
||||||
import AutocompleteHelperController from "./autocompleteHelperController";
|
import AutocompleteHelperController from "./autocompleteHelperController";
|
||||||
import AutocompletePeerHelper from "./autocompletePeerHelper";
|
import AutocompletePeerHelper from "./autocompletePeerHelper";
|
||||||
import appUsersManager from "../../lib/appManagers/appUsersManager";
|
|
||||||
|
|
||||||
export default class MentionsHelper extends AutocompletePeerHelper {
|
export default class MentionsHelper extends AutocompletePeerHelper {
|
||||||
constructor(appendTo: HTMLElement, controller: AutocompleteHelperController, private chatInput: ChatInput) {
|
constructor(appendTo: HTMLElement,
|
||||||
|
controller: AutocompleteHelperController,
|
||||||
|
chatInput: ChatInput,
|
||||||
|
private appProfileManager: AppProfileManager,
|
||||||
|
private appUsersManager: AppUsersManager) {
|
||||||
super(appendTo,
|
super(appendTo,
|
||||||
controller,
|
controller,
|
||||||
'mentions-helper',
|
'mentions-helper',
|
||||||
@ -35,4 +40,26 @@ export default class MentionsHelper extends AutocompletePeerHelper {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public checkQuery(query: string, peerId: number, topMsgId: number) {
|
||||||
|
const trimmed = query.trim(); // check that there is no whitespace
|
||||||
|
if(peerId > 0 || query.length !== trimmed.length) return false;
|
||||||
|
|
||||||
|
this.appProfileManager.getMentions(-peerId, trimmed, topMsgId).then(peerIds => {
|
||||||
|
const username = trimmed.slice(1).toLowerCase();
|
||||||
|
this.render(peerIds.map(peerId => {
|
||||||
|
const user = this.appUsersManager.getUser(peerId);
|
||||||
|
if(user.username && user.username.toLowerCase() === username) { // hide full matched suggestion
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
peerId,
|
||||||
|
description: user.username ? '@' + user.username : undefined
|
||||||
|
};
|
||||||
|
}).filter(Boolean));
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user