Telegram Web K with changes to work inside I2P https://web.telegram.i2p/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

294 lines
11 KiB

3 years ago
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import type Chat from "./chat";
import debounce from "../../helpers/schedulers/debounce";
import { WebDocument } from "../../layer";
import { MyDocument } from "../../lib/appManagers/appDocsManager";
import LazyLoadQueue from "../lazyLoadQueue";
import Scrollable from "../scrollable";
3 years ago
import { wrapPhoto } from "../wrappers";
3 years ago
import AutocompleteHelper from "./autocompleteHelper";
import AutocompleteHelperController from "./autocompleteHelperController";
import Button from "../button";
import { attachClickEvent } from "../../helpers/dom/clickEvent";
import { MyPhoto } from "../../lib/appManagers/appPhotosManager";
import assumeType from "../../helpers/assumeType";
import GifsMasonry from "../gifsMasonry";
import { SuperStickerRenderer } from "../emoticonsDropdown/tabs/stickers";
import mediaSizes from "../../helpers/mediaSizes";
3 years ago
import readBlobAsDataURL from "../../helpers/blob/readBlobAsDataURL";
import setInnerHTML from "../../helpers/dom/setInnerHTML";
3 years ago
import renderImageWithFadeIn from "../../helpers/dom/renderImageWithFadeIn";
import { AppManagers } from "../../lib/appManagers/managers";
import wrapEmojiText from "../../lib/richTextProcessor/wrapEmojiText";
import wrapRichText from "../../lib/richTextProcessor/wrapRichText";
import generateQId from "../../lib/appManagers/utils/inlineBots/generateQId";
import appDownloadManager from "../../lib/appManagers/appDownloadManager";
3 years ago
const ANIMATION_GROUP = 'INLINE-HELPER';
// const GRID_ITEMS = 5;
export default class InlineHelper extends AutocompleteHelper {
private scrollable: Scrollable;
private lazyLoadQueue: LazyLoadQueue;
private gifsMasonry: GifsMasonry;
private superStickerRenderer: SuperStickerRenderer;
private onChangeScreen: () => void;
3 years ago
public checkQuery: (peerId: PeerId, username: string, query: string) => ReturnType<InlineHelper['_checkQuery']>;
3 years ago
3 years ago
constructor(
appendTo: HTMLElement,
3 years ago
controller: AutocompleteHelperController,
private chat: Chat,
3 years ago
private managers: AppManagers
) {
3 years ago
super({
appendTo,
controller,
listType: 'xy',
waitForKey: ['ArrowUp', 'ArrowDown'],
3 years ago
onSelect: (target) => {
if(!target) return false; // can happen when there is only button
3 years ago
const {peerId, botId, queryId} = this.list.dataset;
return this.chat.input.getReadyToSend(() => {
const queryAndResultIds = generateQId(queryId, (target as HTMLElement).dataset.resultId);
3 years ago
this.managers.appInlineBotsManager.sendInlineResult(peerId.toPeerId(), botId, queryAndResultIds, {
...this.chat.getMessageSendingParams(),
3 years ago
clearDraft: true,
});
this.chat.input.onMessageSent(true, true);
});
}
});
this.container.classList.add('inline-helper');
this.addEventListener('visible', () => {
setTimeout(() => { // it is not rendered yet
this.scrollable.container.scrollTop = 0;
}, 0);
});
this.checkQuery = debounce(this._checkQuery, 200, true, true);
this.addEventListener('hidden', () => {
if(this.onChangeScreen) {
mediaSizes.removeEventListener('changeScreen', this.onChangeScreen);
this.onChangeScreen = undefined;
}
});
}
3 years ago
public _checkQuery = async(peerId: PeerId, username: string, query: string) => {
3 years ago
const middleware = this.controller.getMiddleware();
3 years ago
const peer = await this.managers.appUsersManager.resolveUsername(username);
3 years ago
if(!middleware()) {
throw 'PEER_CHANGED';
}
if(peer._ !== 'user') {
throw 'NOT_A_BOT';
}
const renderPromise = this.managers.appInlineBotsManager.getInlineResults(peerId, peer.id, query).then((botResults) => {
3 years ago
if(!middleware()) {
throw 'PEER_CHANGED';
}
if(this.init) {
this.init();
this.init = null;
}
const list = this.list.cloneNode() as HTMLElement;
list.dataset.peerId = '' + peerId;
list.dataset.botId = '' + peer.id;
3 years ago
list.dataset.queryId = '' + botResults.query_id;
3 years ago
const gifsMasonry = new GifsMasonry(null, ANIMATION_GROUP, this.scrollable, false);
this.lazyLoadQueue.clear();
this.superStickerRenderer.clear();
const loadPromises: Promise<any>[] = [];
const isGallery = !!botResults.pFlags.gallery;
// botResults.results.length = 3;
for(const item of botResults.results) {
const container = document.createElement('div');
container.classList.add('inline-helper-result');
container.dataset.resultId = item.id;
const preview = isGallery ? undefined : document.createElement('div');
if(preview) {
preview.classList.add('inline-helper-result-preview');
container.append(preview);
}
list.append(container);
if(!isGallery) {
preview.classList.add('empty');
3 years ago
setInnerHTML(preview, wrapEmojiText([...item.title.trim()][0]));
3 years ago
const title = document.createElement('div');
title.classList.add('inline-helper-result-title');
3 years ago
setInnerHTML(title, wrapEmojiText(item.title));
3 years ago
const description = document.createElement('div');
description.classList.add('inline-helper-result-description');
3 years ago
setInnerHTML(description, wrapRichText(item.description, {
3 years ago
noCommands: true,
noLinks: true
}));
3 years ago
container.append(title, description);
const separator = document.createElement('div');
separator.classList.add('inline-helper-separator');
list.append(separator);
} else {
container.classList.add('grid-item');
}
if(item._ === 'botInlineResult') {
if(item.thumb && item.thumb.mime_type.indexOf('image/') === 0) {
let mediaContainer: HTMLElement;
if(preview) {
mediaContainer = document.createElement('div');
preview.append(mediaContainer);
} else {
mediaContainer = container;
}
mediaContainer.classList.add('media-container');
isGallery && mediaContainer.classList.add('no-border-radius');
3 years ago
this.lazyLoadQueue.push({
div: container,
3 years ago
load: () => {
return appDownloadManager.download({
dcId: 4,
location: {
_: 'inputWebFileLocation',
access_hash: (item.thumb as WebDocument.webDocument).access_hash,
url: item.thumb.url
},
size: item.thumb.size,
mimeType: item.thumb.mime_type
}).then((blob) => {
3 years ago
const image = new Image();
image.classList.add('media-photo');
readBlobAsDataURL(blob).then((dataURL) => {
3 years ago
renderImageWithFadeIn(mediaContainer, image, dataURL, true);
});
});
}
});
}
} else {
const media = item.document as MyDocument || item.photo as MyPhoto;
if((['sticker', 'gif'] as MyDocument['type'][]).includes((media as MyDocument)?.type) && isGallery) {
assumeType<MyDocument>(media);
if(media.type === 'gif') {
gifsMasonry.add(media, container);
} else if(media.type === 'sticker') {
container.classList.add('super-sticker');
this.superStickerRenderer.renderSticker(media, container, loadPromises);
if(media.sticker === 2) {
this.superStickerRenderer.observeAnimatedDiv(container);
}
}
} else if(media) {
const size = isGallery ? 48 : undefined;
isGallery && container.classList.add('no-border-radius');
3 years ago
wrapPhoto({
photo: media,
container: isGallery ? container : preview,
boxWidth: size,
boxHeight: size,
middleware,
lazyLoadQueue: this.lazyLoadQueue,
loadPromises
});
}
}
}
return Promise.all(loadPromises).then(() => {
if(!middleware()) {
gifsMasonry.clear();
return;
}
list.classList.toggle('is-gallery', isGallery);
list.classList.toggle('super-stickers', isGallery);
this.container.classList.toggle('is-gallery', isGallery);
/* if(isGallery) {
list.style.gridTemplateColumns = `repeat(${Math.min(botResults.results.length, 4)}, 1fr)`;
}
this.container.style.setProperty('width', isGallery ? `${Math.min(botResults.results.length, 4) * 25}%` : '', 'important'); */
const parent = this.list.parentElement;
parent.textContent = '';
if(botResults.switch_pm) {
const btnSwitchToPM = Button('btn-primary btn-secondary btn-primary-transparent primary');
3 years ago
setInnerHTML(btnSwitchToPM, wrapEmojiText(botResults.switch_pm.text));
3 years ago
attachClickEvent(btnSwitchToPM, (e) => {
this.chat.appImManager.setInnerPeer({peerId});
3 years ago
this.managers.appInlineBotsManager.switchToPM(peerId, peer.id, botResults.switch_pm.start_param);
3 years ago
});
parent.append(btnSwitchToPM);
}
parent.append(this.list = list);
if(this.gifsMasonry) {
this.gifsMasonry.detach();
}
this.gifsMasonry = gifsMasonry;
gifsMasonry.attach();
if(!this.onChangeScreen) {
this.onChangeScreen = () => {
if(this.list.classList.contains('is-gallery')) {
const width = (this.list.childElementCount * mediaSizes.active.esgSticker.width) + (this.list.childElementCount - 1 * 1);
this.list.style.width = width + 'px';
} else {
this.list.style.width = '';
}
};
mediaSizes.addEventListener('changeScreen', this.onChangeScreen);
}
this.onChangeScreen();
this.toggle(!botResults.results.length && !botResults.switch_pm);
this.scrollable.scrollTop = 0;
});
});
return {user: peer, renderPromise};
};
protected init() {
this.list = document.createElement('div');
this.list.classList.add('inline-helper-results');
this.container.append(this.list);
this.scrollable = new Scrollable(this.container);
this.lazyLoadQueue = new LazyLoadQueue();
3 years ago
this.superStickerRenderer = new SuperStickerRenderer(this.lazyLoadQueue, ANIMATION_GROUP, this.managers);
3 years ago
}
}