Stickers and Emoji tab
Stickers sorting Stickers suggestion options Group creation without members Fix voting in polls Fix processing autocomplete on settings change
This commit is contained in:
parent
bb6cda7de5
commit
2408333c47
|
@ -689,7 +689,8 @@ export default class Chat extends EventListenerBase<{
|
||||||
replyToMsgId: this.input.replyToMsgId,
|
replyToMsgId: this.input.replyToMsgId,
|
||||||
scheduleDate: this.input.scheduleDate,
|
scheduleDate: this.input.scheduleDate,
|
||||||
silent: this.input.sendSilent,
|
silent: this.input.sendSilent,
|
||||||
sendAsPeerId: this.input.sendAsPeerId
|
sendAsPeerId: this.input.sendAsPeerId,
|
||||||
|
updateStickersetOrder: rootScope.settings.stickers.dynamicPackOrder
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2277,7 +2277,8 @@ export default class ChatInput {
|
||||||
private async checkAutocomplete(value?: string, caretPos?: number, entities?: MessageEntity[]) {
|
private async checkAutocomplete(value?: string, caretPos?: number, entities?: MessageEntity[]) {
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
if(value === undefined) {
|
const hadValue = value !== undefined;
|
||||||
|
if(!hadValue) {
|
||||||
const r = getRichValueWithCaret(this.messageInputField.input, true, true);
|
const r = getRichValueWithCaret(this.messageInputField.input, true, true);
|
||||||
value = r.value;
|
value = r.value;
|
||||||
caretPos = r.caretPos;
|
caretPos = r.caretPos;
|
||||||
|
@ -2288,7 +2289,7 @@ export default class ChatInput {
|
||||||
caretPos = value.length;
|
caretPos = value.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entities === undefined) {
|
if(entities === undefined || !hadValue) {
|
||||||
const _value = parseMarkdown(value, entities, true);
|
const _value = parseMarkdown(value, entities, true);
|
||||||
entities = mergeEntities(entities, parseEntities(_value));
|
entities = mergeEntities(entities, parseEntities(_value));
|
||||||
}
|
}
|
||||||
|
@ -2310,7 +2311,7 @@ export default class ChatInput {
|
||||||
const firstChar = query[0];
|
const firstChar = query[0];
|
||||||
|
|
||||||
if(this.stickersHelper &&
|
if(this.stickersHelper &&
|
||||||
rootScope.settings.stickers.suggest &&
|
rootScope.settings.stickers.suggest !== 'none' &&
|
||||||
await this.chat.canSend('send_stickers') &&
|
await this.chat.canSend('send_stickers') &&
|
||||||
entity?._ === 'messageEntityEmoji' && entity.length === value.length && !entity.offset) {
|
entity?._ === 'messageEntityEmoji' && entity.length === value.length && !entity.offset) {
|
||||||
foundHelper = this.stickersHelper;
|
foundHelper = this.stickersHelper;
|
||||||
|
@ -2731,7 +2732,7 @@ export default class ChatInput {
|
||||||
}
|
}
|
||||||
|
|
||||||
private getValueAndEntities(input: HTMLElement) {
|
private getValueAndEntities(input: HTMLElement) {
|
||||||
const {entities: apiEntities, value} = getRichValueWithCaret(this.messageInput, true, false);
|
const {entities: apiEntities, value} = getRichValueWithCaret(input, true, false);
|
||||||
const myEntities = parseEntities(value);
|
const myEntities = parseEntities(value);
|
||||||
const totalEntities = mergeEntities(apiEntities, myEntities);
|
const totalEntities = mergeEntities(apiEntities, myEntities);
|
||||||
|
|
||||||
|
|
|
@ -68,12 +68,10 @@ export default class StickersHelper extends AutocompleteHelper {
|
||||||
public checkEmoticon(emoticon: string) {
|
public checkEmoticon(emoticon: string) {
|
||||||
const middleware = this.controller.getMiddleware();
|
const middleware = this.controller.getMiddleware();
|
||||||
|
|
||||||
if(this.lazyLoadQueue) {
|
this.lazyLoadQueue?.clear();
|
||||||
this.lazyLoadQueue.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
preloadAnimatedEmojiSticker(emoticon);
|
preloadAnimatedEmojiSticker(emoticon);
|
||||||
this.managers.appStickersManager.getStickersByEmoticon(emoticon)
|
this.managers.appStickersManager.getStickersByEmoticon(emoticon, true, rootScope.settings.stickers.suggest === 'all')
|
||||||
.then((stickers) => {
|
.then((stickers) => {
|
||||||
if(!middleware()) {
|
if(!middleware()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -789,6 +789,19 @@ export default class StickersTab extends EmoticonsTabC<StickersTabCategory<Stick
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
rootScope.addEventListener('stickers_order', ({type, order}) => {
|
||||||
|
if(type !== 'stickers') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
order.forEach((id) => {
|
||||||
|
const category = this.categories[id];
|
||||||
|
if(category) {
|
||||||
|
this.positionCategory(category, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
rootScope.addEventListener('stickers_updated', ({type, stickers}) => {
|
rootScope.addEventListener('stickers_updated', ({type, stickers}) => {
|
||||||
const category = this.categories[type === 'faved' ? 'faved' : 'recent'];
|
const category = this.categories[type === 'faved' ? 'faved' : 'recent'];
|
||||||
if(category) {
|
if(category) {
|
||||||
|
|
|
@ -479,7 +479,7 @@ export default class PollElement extends HTMLElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clickHandler(e: Event) {
|
clickHandler = (e: Event) => {
|
||||||
const target = findUpClassName(e.target, 'poll-answer') as HTMLElement;
|
const target = findUpClassName(e.target, 'poll-answer') as HTMLElement;
|
||||||
if(!target) {
|
if(!target) {
|
||||||
return;
|
return;
|
||||||
|
@ -505,7 +505,7 @@ export default class PollElement extends HTMLElement {
|
||||||
this.setResults([100, 0], answerIndex);
|
this.setResults([100, 0], answerIndex);
|
||||||
target.classList.remove('is-voting');
|
target.classList.remove('is-voting');
|
||||||
}, 1000); */
|
}, 1000); */
|
||||||
}
|
};
|
||||||
|
|
||||||
sendVotes(indexes: number[]) {
|
sendVotes(indexes: number[]) {
|
||||||
if(this.sendVotePromise) return this.sendVotePromise;
|
if(this.sendVotePromise) return this.sendVotePromise;
|
||||||
|
|
|
@ -97,7 +97,7 @@ export class AppSidebarLeft extends SidebarSlider {
|
||||||
const onNewGroupClick = () => {
|
const onNewGroupClick = () => {
|
||||||
this.createTab(AppAddMembersTab).open({
|
this.createTab(AppAddMembersTab).open({
|
||||||
type: 'chat',
|
type: 'chat',
|
||||||
skippable: false,
|
skippable: true,
|
||||||
takeOut: (peerIds) => this.createTab(AppNewGroupTab).open(peerIds),
|
takeOut: (peerIds) => this.createTab(AppNewGroupTab).open(peerIds),
|
||||||
title: 'GroupAddMembers',
|
title: 'GroupAddMembers',
|
||||||
placeholder: 'SendMessageTo'
|
placeholder: 'SendMessageTo'
|
||||||
|
|
|
@ -34,7 +34,7 @@ export default class AppAddMembersTab extends SliderSuperTab {
|
||||||
const peerIds = this.selector.getSelected().map((sel) => sel.toPeerId());
|
const peerIds = this.selector.getSelected().map((sel) => sel.toPeerId());
|
||||||
const result = this.takeOut(peerIds);
|
const result = this.takeOut(peerIds);
|
||||||
|
|
||||||
if(this.skippable) {
|
if(this.skippable && !(result instanceof Promise)) {
|
||||||
this.close();
|
this.close();
|
||||||
} else if(result instanceof Promise) {
|
} else if(result instanceof Promise) {
|
||||||
this.attachToPromise(result);
|
this.attachToPromise(result);
|
||||||
|
|
|
@ -98,9 +98,7 @@ export class RangeSettingSelector {
|
||||||
export default class AppGeneralSettingsTab extends SliderSuperTabEventable {
|
export default class AppGeneralSettingsTab extends SliderSuperTabEventable {
|
||||||
public static getInitArgs() {
|
public static getInitArgs() {
|
||||||
return {
|
return {
|
||||||
themes: rootScope.managers.appThemesManager.getThemes(),
|
themes: rootScope.managers.appThemesManager.getThemes()
|
||||||
allStickers: rootScope.managers.appStickersManager.getAllStickers(),
|
|
||||||
quickReaction: rootScope.managers.appReactionsManager.getQuickReaction()
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,140 +527,6 @@ export default class AppGeneralSettingsTab extends SliderSuperTabEventable {
|
||||||
container.append(form);
|
container.append(form);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
const container = section('Emoji');
|
|
||||||
|
|
||||||
const suggestCheckboxField = new CheckboxField({
|
|
||||||
text: 'GeneralSettings.EmojiPrediction',
|
|
||||||
name: 'suggest-emoji',
|
|
||||||
stateKey: 'settings.emoji.suggest',
|
|
||||||
listenerSetter: this.listenerSetter
|
|
||||||
});
|
|
||||||
const bigCheckboxField = new CheckboxField({
|
|
||||||
text: 'GeneralSettings.BigEmoji',
|
|
||||||
name: 'emoji-big',
|
|
||||||
stateKey: 'settings.emoji.big',
|
|
||||||
listenerSetter: this.listenerSetter
|
|
||||||
});
|
|
||||||
|
|
||||||
container.append(
|
|
||||||
CreateRowFromCheckboxField(suggestCheckboxField).container,
|
|
||||||
CreateRowFromCheckboxField(bigCheckboxField).container
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const section = new SettingSection({name: 'Telegram.InstalledStickerPacksController', caption: 'StickersBotInfo'});
|
|
||||||
|
|
||||||
const reactionsRow = new Row({
|
|
||||||
titleLangKey: 'DoubleTapSetting',
|
|
||||||
havePadding: true,
|
|
||||||
clickable: () => {
|
|
||||||
this.slider.createTab(AppQuickReactionTab).open();
|
|
||||||
},
|
|
||||||
listenerSetter: this.listenerSetter
|
|
||||||
});
|
|
||||||
|
|
||||||
const renderQuickReaction = () => {
|
|
||||||
p.quickReaction.then((reaction) => {
|
|
||||||
if(reaction._ === 'availableReaction') {
|
|
||||||
return reaction.static_icon;
|
|
||||||
} else {
|
|
||||||
return this.managers.appEmojiManager.getCustomEmojiDocument(reaction.document_id);
|
|
||||||
}
|
|
||||||
}).then((doc) => {
|
|
||||||
wrapStickerToRow({
|
|
||||||
row: reactionsRow,
|
|
||||||
doc,
|
|
||||||
size: 'small'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
renderQuickReaction();
|
|
||||||
|
|
||||||
this.listenerSetter.add(rootScope)('quick_reaction', renderQuickReaction);
|
|
||||||
|
|
||||||
const suggestCheckboxField = new CheckboxField({
|
|
||||||
text: 'Stickers.SuggestStickers',
|
|
||||||
name: 'suggest',
|
|
||||||
stateKey: 'settings.stickers.suggest',
|
|
||||||
listenerSetter: this.listenerSetter
|
|
||||||
});
|
|
||||||
const loopCheckboxField = new CheckboxField({
|
|
||||||
text: 'InstalledStickers.LoopAnimated',
|
|
||||||
name: 'loop',
|
|
||||||
stateKey: 'settings.stickers.loop',
|
|
||||||
listenerSetter: this.listenerSetter
|
|
||||||
});
|
|
||||||
|
|
||||||
const stickerSets: {[id: string]: Row} = {};
|
|
||||||
|
|
||||||
const stickersContent = section.generateContentElement();
|
|
||||||
|
|
||||||
const lazyLoadQueue = new LazyLoadQueue();
|
|
||||||
const renderStickerSet = (stickerSet: StickerSet.stickerSet, method: 'append' | 'prepend' = 'append') => {
|
|
||||||
const row = new Row({
|
|
||||||
title: wrapEmojiText(stickerSet.title),
|
|
||||||
subtitleLangKey: 'Stickers',
|
|
||||||
subtitleLangArgs: [stickerSet.count],
|
|
||||||
havePadding: true,
|
|
||||||
clickable: () => {
|
|
||||||
new PopupStickers({id: stickerSet.id, access_hash: stickerSet.access_hash}).show();
|
|
||||||
},
|
|
||||||
listenerSetter: this.listenerSetter
|
|
||||||
});
|
|
||||||
|
|
||||||
stickerSets[stickerSet.id] = row;
|
|
||||||
|
|
||||||
const div = document.createElement('div');
|
|
||||||
div.classList.add('row-media');
|
|
||||||
|
|
||||||
wrapStickerSetThumb({
|
|
||||||
set: stickerSet,
|
|
||||||
container: div,
|
|
||||||
group: 'GENERAL-SETTINGS',
|
|
||||||
lazyLoadQueue,
|
|
||||||
width: 36,
|
|
||||||
height: 36,
|
|
||||||
autoplay: true,
|
|
||||||
middleware: this.middlewareHelper.get()
|
|
||||||
});
|
|
||||||
|
|
||||||
row.container.append(div);
|
|
||||||
|
|
||||||
stickersContent[method](row.container);
|
|
||||||
};
|
|
||||||
|
|
||||||
const promise = p.allStickers.then((allStickers) => {
|
|
||||||
assumeType<MessagesAllStickers.messagesAllStickers>(allStickers);
|
|
||||||
const promises = allStickers.sets.map((stickerSet) => renderStickerSet(stickerSet));
|
|
||||||
return Promise.all(promises);
|
|
||||||
});
|
|
||||||
|
|
||||||
promises.push(promise);
|
|
||||||
|
|
||||||
this.listenerSetter.add(rootScope)('stickers_installed', (set) => {
|
|
||||||
if(!stickerSets[set.id]) {
|
|
||||||
renderStickerSet(set, 'prepend');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.listenerSetter.add(rootScope)('stickers_deleted', (set) => {
|
|
||||||
if(stickerSets[set.id]) {
|
|
||||||
stickerSets[set.id].container.remove();
|
|
||||||
delete stickerSets[set.id];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
section.content.append(
|
|
||||||
reactionsRow.container,
|
|
||||||
CreateRowFromCheckboxField(suggestCheckboxField).container,
|
|
||||||
CreateRowFromCheckboxField(loopCheckboxField).container
|
|
||||||
);
|
|
||||||
this.scrollable.append(section.container);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.all(promises);
|
return Promise.all(promises);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import appDialogsManager from '../../../lib/appManagers/appDialogsManager';
|
||||||
import InputField from '../../inputField';
|
import InputField from '../../inputField';
|
||||||
import {SliderSuperTab} from '../../slider';
|
import {SliderSuperTab} from '../../slider';
|
||||||
import AvatarEdit from '../../avatarEdit';
|
import AvatarEdit from '../../avatarEdit';
|
||||||
import I18n from '../../../lib/langPack';
|
import I18n, {joinElementsWith} from '../../../lib/langPack';
|
||||||
import ButtonCorner from '../../buttonCorner';
|
import ButtonCorner from '../../buttonCorner';
|
||||||
import getUserStatusString from '../../wrappers/getUserStatusString';
|
import getUserStatusString from '../../wrappers/getUserStatusString';
|
||||||
import appImManager from '../../../lib/appManagers/appImManager';
|
import appImManager from '../../../lib/appManagers/appImManager';
|
||||||
|
@ -141,6 +141,10 @@ export default class AppNewGroupTab extends SliderSuperTab {
|
||||||
nameArgs: [this.peerIds.length]
|
nameArgs: [this.peerIds.length]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(!this.peerIds.length) {
|
||||||
|
chatsSection.container.classList.add('hide');
|
||||||
|
}
|
||||||
|
|
||||||
const list = this.list = appDialogsManager.createChatList({
|
const list = this.list = appDialogsManager.createChatList({
|
||||||
new: true
|
new: true
|
||||||
});
|
});
|
||||||
|
@ -161,16 +165,34 @@ export default class AppNewGroupTab extends SliderSuperTab {
|
||||||
this.groupLocationInputField.container.classList.add('hide');
|
this.groupLocationInputField.container.classList.add('hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(this.peerIds.map(async(userId) => {
|
const usersPromise = Promise.all(this.peerIds.map((peerId) => this.managers.appUsersManager.getUser(peerId.toUserId())));
|
||||||
const {dom} = appDialogsManager.addDialogNew({
|
const myUserPromise = this.managers.appUsersManager.getSelf();
|
||||||
peerId: userId,
|
|
||||||
container: this.list,
|
|
||||||
rippleEnabled: false,
|
|
||||||
avatarSize: 'abitbigger'
|
|
||||||
});
|
|
||||||
|
|
||||||
dom.lastMessageSpan.append(getUserStatusString(await this.managers.appUsersManager.getUser(userId)));
|
const a = usersPromise.then((users) => {
|
||||||
}));
|
return users.map((user) => {
|
||||||
|
const {dom} = appDialogsManager.addDialogNew({
|
||||||
|
peerId: user.id.toPeerId(false),
|
||||||
|
container: this.list,
|
||||||
|
rippleEnabled: false,
|
||||||
|
avatarSize: 'abitbigger'
|
||||||
|
});
|
||||||
|
|
||||||
|
dom.lastMessageSpan.append(getUserStatusString(user));
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const setTitlePromise = this.peerIds.length > 0 && this.peerIds.length < 5 ? Promise.all([usersPromise, myUserPromise]).then(([users, myUser]) => {
|
||||||
|
const names = users.map((user) => [user.first_name, user.last_name].filter(Boolean).join(' '));
|
||||||
|
names.unshift(myUser.first_name);
|
||||||
|
|
||||||
|
const joined = joinElementsWith(names, (isLast) => isLast ? ', ' : ' & ').join('');
|
||||||
|
this.groupNameInputField.setDraftValue(joined);
|
||||||
|
}) : Promise.resolve();
|
||||||
|
|
||||||
|
return Promise.all([
|
||||||
|
a,
|
||||||
|
setTitlePromise
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onCloseAfterTimeout() {
|
public onCloseAfterTimeout() {
|
||||||
|
|
|
@ -28,6 +28,7 @@ import {AccountAuthorizations, Authorization} from '../../../layer';
|
||||||
import PopupElement from '../../popups';
|
import PopupElement from '../../popups';
|
||||||
import {attachClickEvent} from '../../../helpers/dom/clickEvent';
|
import {attachClickEvent} from '../../../helpers/dom/clickEvent';
|
||||||
import SettingSection from '../../settingSection';
|
import SettingSection from '../../settingSection';
|
||||||
|
import AppStickersAndEmojiTab from './stickersAndEmoji';
|
||||||
|
|
||||||
export default class AppSettingsTab extends SliderSuperTab {
|
export default class AppSettingsTab extends SliderSuperTab {
|
||||||
private buttons: {
|
private buttons: {
|
||||||
|
@ -192,7 +193,8 @@ export default class AppSettingsTab extends SliderSuperTab {
|
||||||
m('data', 'DataSettings', AppDataAndStorageTab),
|
m('data', 'DataSettings', AppDataAndStorageTab),
|
||||||
m('lock', 'AccountSettings.PrivacyAndSecurity', AppPrivacyAndSecurityTab),
|
m('lock', 'AccountSettings.PrivacyAndSecurity', AppPrivacyAndSecurityTab),
|
||||||
m('settings', 'Telegram.GeneralSettingsViewController', AppGeneralSettingsTab),
|
m('settings', 'Telegram.GeneralSettingsViewController', AppGeneralSettingsTab),
|
||||||
m('folder', 'AccountSettings.Filters', AppChatFoldersTab)
|
m('folder', 'AccountSettings.Filters', AppChatFoldersTab),
|
||||||
|
m('stickers_face', 'StickersName', AppStickersAndEmojiTab)
|
||||||
];
|
];
|
||||||
|
|
||||||
const rows = b.map((item) => {
|
const rows = b.map((item) => {
|
||||||
|
|
|
@ -0,0 +1,301 @@
|
||||||
|
/*
|
||||||
|
* https://github.com/morethanwords/tweb
|
||||||
|
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
||||||
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
import forEachReverse from '../../../helpers/array/forEachReverse';
|
||||||
|
import assumeType from '../../../helpers/assumeType';
|
||||||
|
import createContextMenu from '../../../helpers/dom/createContextMenu';
|
||||||
|
import positionElementByIndex from '../../../helpers/dom/positionElementByIndex';
|
||||||
|
import Sortable from '../../../helpers/dom/sortable';
|
||||||
|
import {StickerSet, MessagesAllStickers} from '../../../layer';
|
||||||
|
import {i18n, LangPackKey} from '../../../lib/langPack';
|
||||||
|
import wrapEmojiText from '../../../lib/richTextProcessor/wrapEmojiText';
|
||||||
|
import rootScope from '../../../lib/rootScope';
|
||||||
|
import CheckboxField from '../../checkboxField';
|
||||||
|
import LazyLoadQueue from '../../lazyLoadQueue';
|
||||||
|
import PopupStickers from '../../popups/stickers';
|
||||||
|
import Row, {CreateRowFromCheckboxField} from '../../row';
|
||||||
|
import SettingSection from '../../settingSection';
|
||||||
|
import SliderSuperTab from '../../sliderTab';
|
||||||
|
import wrapStickerSetThumb from '../../wrappers/stickerSetThumb';
|
||||||
|
import wrapStickerToRow from '../../wrappers/stickerToRow';
|
||||||
|
import AppQuickReactionTab from './quickReaction';
|
||||||
|
|
||||||
|
export default class AppStickersAndEmojiTab extends SliderSuperTab {
|
||||||
|
public static getInitArgs() {
|
||||||
|
return {
|
||||||
|
allStickers: rootScope.managers.appStickersManager.getAllStickers(),
|
||||||
|
quickReaction: rootScope.managers.appReactionsManager.getQuickReaction()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(p: ReturnType<typeof AppStickersAndEmojiTab['getInitArgs']>) {
|
||||||
|
this.container.classList.add('stickers-emoji-container');
|
||||||
|
this.setTitle('StickersName');
|
||||||
|
|
||||||
|
const promises: Promise<any>[] = [];
|
||||||
|
|
||||||
|
{
|
||||||
|
const section = new SettingSection({caption: 'LoopAnimatedStickersInfo'});
|
||||||
|
|
||||||
|
const suggestStickersRow = new Row({
|
||||||
|
icon: 'lamp',
|
||||||
|
titleLangKey: 'Stickers.SuggestStickers',
|
||||||
|
clickable: true,
|
||||||
|
listenerSetter: this.listenerSetter,
|
||||||
|
titleRightSecondary: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const map: {[k in typeof rootScope.settings.stickers.suggest]: LangPackKey} = {
|
||||||
|
all: 'SuggestStickersAll',
|
||||||
|
installed: 'SuggestStickersInstalled',
|
||||||
|
none: 'SuggestStickersNone'
|
||||||
|
};
|
||||||
|
|
||||||
|
const setStickersSuggestDescription = () => {
|
||||||
|
suggestStickersRow.titleRight.replaceChildren(i18n(map[rootScope.settings.stickers.suggest]));
|
||||||
|
};
|
||||||
|
|
||||||
|
setStickersSuggestDescription();
|
||||||
|
|
||||||
|
const setStickersSuggest = (value: typeof rootScope.settings.stickers.suggest) => {
|
||||||
|
if(rootScope.settings.stickers.suggest === value) return;
|
||||||
|
rootScope.settings.stickers.suggest = value;
|
||||||
|
setStickersSuggestDescription();
|
||||||
|
return this.managers.appStateManager.setByKey('settings.stickers.suggest', value);
|
||||||
|
};
|
||||||
|
|
||||||
|
createContextMenu({
|
||||||
|
buttons: [{
|
||||||
|
icon: 'stickers_face',
|
||||||
|
text: 'SuggestStickersAll',
|
||||||
|
onClick: setStickersSuggest.bind(this, 'all')
|
||||||
|
}, {
|
||||||
|
icon: 'newprivate',
|
||||||
|
text: 'SuggestStickersInstalled',
|
||||||
|
onClick: setStickersSuggest.bind(this, 'installed')
|
||||||
|
}, {
|
||||||
|
icon: 'stop',
|
||||||
|
text: 'SuggestStickersNone',
|
||||||
|
onClick: setStickersSuggest.bind(this, 'none')
|
||||||
|
}],
|
||||||
|
listenTo: suggestStickersRow.container,
|
||||||
|
middleware: this.middlewareHelper.get(),
|
||||||
|
listenForClick: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const reactionsRow = new Row({
|
||||||
|
titleLangKey: 'DoubleTapSetting',
|
||||||
|
havePadding: true,
|
||||||
|
clickable: () => {
|
||||||
|
this.slider.createTab(AppQuickReactionTab).open();
|
||||||
|
},
|
||||||
|
listenerSetter: this.listenerSetter
|
||||||
|
});
|
||||||
|
|
||||||
|
const renderQuickReaction = () => {
|
||||||
|
p.quickReaction.then((reaction) => {
|
||||||
|
if(reaction._ === 'availableReaction') {
|
||||||
|
return reaction.static_icon;
|
||||||
|
} else {
|
||||||
|
return this.managers.appEmojiManager.getCustomEmojiDocument(reaction.document_id);
|
||||||
|
}
|
||||||
|
}).then((doc) => {
|
||||||
|
wrapStickerToRow({
|
||||||
|
row: reactionsRow,
|
||||||
|
doc,
|
||||||
|
size: 'small'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
renderQuickReaction();
|
||||||
|
|
||||||
|
this.listenerSetter.add(rootScope)('quick_reaction', () => {
|
||||||
|
p = AppStickersAndEmojiTab.getInitArgs();
|
||||||
|
renderQuickReaction();
|
||||||
|
});
|
||||||
|
|
||||||
|
const loopStickersRow = new Row({
|
||||||
|
icon: 'flip',
|
||||||
|
titleLangKey: 'InstalledStickers.LoopAnimated',
|
||||||
|
checkboxField: new CheckboxField({
|
||||||
|
name: 'loop',
|
||||||
|
stateKey: 'settings.stickers.loop',
|
||||||
|
listenerSetter: this.listenerSetter,
|
||||||
|
toggle: true
|
||||||
|
}),
|
||||||
|
listenerSetter: this.listenerSetter
|
||||||
|
});
|
||||||
|
|
||||||
|
section.content.append(
|
||||||
|
reactionsRow.container,
|
||||||
|
suggestStickersRow.container,
|
||||||
|
loopStickersRow.container
|
||||||
|
);
|
||||||
|
|
||||||
|
this.scrollable.append(section.container);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const section = new SettingSection({name: 'Emoji'});
|
||||||
|
|
||||||
|
const suggestEmojiRow = new Row({
|
||||||
|
icon: 'lamp',
|
||||||
|
titleLangKey: 'GeneralSettings.EmojiPrediction',
|
||||||
|
checkboxField: new CheckboxField({
|
||||||
|
name: 'suggest-emoji',
|
||||||
|
stateKey: 'settings.emoji.suggest',
|
||||||
|
listenerSetter: this.listenerSetter,
|
||||||
|
toggle: true
|
||||||
|
}),
|
||||||
|
listenerSetter: this.listenerSetter
|
||||||
|
});
|
||||||
|
const bigEmojiRow = new Row({
|
||||||
|
icon: 'smile',
|
||||||
|
titleLangKey: 'GeneralSettings.BigEmoji',
|
||||||
|
checkboxField: new CheckboxField({
|
||||||
|
name: 'emoji-big',
|
||||||
|
stateKey: 'settings.emoji.big',
|
||||||
|
listenerSetter: this.listenerSetter,
|
||||||
|
toggle: true
|
||||||
|
}),
|
||||||
|
listenerSetter: this.listenerSetter
|
||||||
|
});
|
||||||
|
|
||||||
|
section.content.append(
|
||||||
|
suggestEmojiRow.container,
|
||||||
|
bigEmojiRow.container
|
||||||
|
);
|
||||||
|
|
||||||
|
this.scrollable.append(section.container);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const section = new SettingSection({name: 'DynamicPackOrder', caption: 'DynamicPackOrderInfo'});
|
||||||
|
|
||||||
|
const dynamicPackOrderRow = new Row({
|
||||||
|
titleLangKey: 'DynamicPackOrder',
|
||||||
|
checkboxField: new CheckboxField({
|
||||||
|
name: 'dynamic-pack-order',
|
||||||
|
stateKey: 'settings.stickers.dynamicPackOrder',
|
||||||
|
listenerSetter: this.listenerSetter,
|
||||||
|
toggle: true
|
||||||
|
}),
|
||||||
|
listenerSetter: this.listenerSetter
|
||||||
|
});
|
||||||
|
|
||||||
|
section.content.append(
|
||||||
|
dynamicPackOrderRow.container
|
||||||
|
);
|
||||||
|
|
||||||
|
this.scrollable.append(section.container);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const section = new SettingSection({name: 'Telegram.InstalledStickerPacksController', caption: 'StickersBotInfo'});
|
||||||
|
|
||||||
|
const stickerSets: {[id: string]: Row} = {};
|
||||||
|
|
||||||
|
const stickersContent = section.generateContentElement();
|
||||||
|
|
||||||
|
const lazyLoadQueue = new LazyLoadQueue();
|
||||||
|
const renderStickerSet = (stickerSet: StickerSet.stickerSet, method: 'append' | 'prepend' = 'append') => {
|
||||||
|
const row = new Row({
|
||||||
|
title: wrapEmojiText(stickerSet.title),
|
||||||
|
subtitleLangKey: 'Stickers',
|
||||||
|
subtitleLangArgs: [stickerSet.count],
|
||||||
|
havePadding: true,
|
||||||
|
clickable: () => {
|
||||||
|
new PopupStickers({id: stickerSet.id, access_hash: stickerSet.access_hash}).show();
|
||||||
|
},
|
||||||
|
listenerSetter: this.listenerSetter
|
||||||
|
});
|
||||||
|
|
||||||
|
row.container.dataset.id = '' + stickerSet.id;
|
||||||
|
|
||||||
|
row.makeSortable();
|
||||||
|
|
||||||
|
stickerSets[stickerSet.id] = row;
|
||||||
|
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.classList.add('row-media');
|
||||||
|
|
||||||
|
wrapStickerSetThumb({
|
||||||
|
set: stickerSet,
|
||||||
|
container: div,
|
||||||
|
group: 'GENERAL-SETTINGS',
|
||||||
|
lazyLoadQueue,
|
||||||
|
width: 36,
|
||||||
|
height: 36,
|
||||||
|
autoplay: true,
|
||||||
|
middleware: this.middlewareHelper.get()
|
||||||
|
});
|
||||||
|
|
||||||
|
row.container.append(div);
|
||||||
|
|
||||||
|
stickersContent[method](row.container);
|
||||||
|
};
|
||||||
|
|
||||||
|
const promise = p.allStickers.then((allStickers) => {
|
||||||
|
assumeType<MessagesAllStickers.messagesAllStickers>(allStickers);
|
||||||
|
const promises = allStickers.sets.map((stickerSet) => renderStickerSet(stickerSet));
|
||||||
|
return Promise.all(promises);
|
||||||
|
});
|
||||||
|
|
||||||
|
promises.push(promise);
|
||||||
|
|
||||||
|
this.listenerSetter.add(rootScope)('stickers_installed', (set) => {
|
||||||
|
if(!stickerSets[set.id]) {
|
||||||
|
renderStickerSet(set, 'prepend');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.listenerSetter.add(rootScope)('stickers_deleted', (set) => {
|
||||||
|
if(stickerSets[set.id]) {
|
||||||
|
stickerSets[set.id].container.remove();
|
||||||
|
delete stickerSets[set.id];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.listenerSetter.add(rootScope)('stickers_order', ({type, order}) => {
|
||||||
|
if(type !== 'stickers') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
order.forEach((id, idx) => {
|
||||||
|
const row = stickerSets[id];
|
||||||
|
if(!row) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
positionElementByIndex(row.container, stickersContent, idx)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.listenerSetter.add(rootScope)('stickers_top', (id) => {
|
||||||
|
const row = stickerSets[id];
|
||||||
|
if(!row) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
positionElementByIndex(row.container, stickersContent, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
new Sortable({
|
||||||
|
list: stickersContent,
|
||||||
|
middleware: this.middlewareHelper.get(),
|
||||||
|
onSort: (idx, newIdx) => {
|
||||||
|
const order = Array.from(stickersContent.children).map((el) => (el as HTMLElement).dataset.id);
|
||||||
|
this.managers.appStickersManager.reorderStickerSets(order);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.scrollable.append(section.container);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(promises);
|
||||||
|
}
|
||||||
|
}
|
|
@ -132,8 +132,8 @@ export default async function wrapSticker({doc, div, middleware, loadStickerMidd
|
||||||
div.dataset.stickerEmoji = emoji;
|
div.dataset.stickerEmoji = emoji;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.dataset.stickerPlay = '' + +play;
|
div.dataset.stickerPlay = '' + +(play || false);
|
||||||
div.dataset.stickerLoop = '' + +loop;
|
div.dataset.stickerLoop = '' + +(loop || false);
|
||||||
|
|
||||||
div.classList.add('media-sticker-wrapper');
|
div.classList.add('media-sticker-wrapper');
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,7 +21,7 @@ const App = {
|
||||||
version: process.env.VERSION,
|
version: process.env.VERSION,
|
||||||
versionFull: process.env.VERSION_FULL,
|
versionFull: process.env.VERSION_FULL,
|
||||||
build: +process.env.BUILD,
|
build: +process.env.BUILD,
|
||||||
langPackVersion: '0.9.8',
|
langPackVersion: '1.0.1',
|
||||||
langPack: 'webk',
|
langPack: 'webk',
|
||||||
langPackCode: 'en',
|
langPackCode: 'en',
|
||||||
domains: MAIN_DOMAINS,
|
domains: MAIN_DOMAINS,
|
||||||
|
|
|
@ -91,7 +91,8 @@ export type State = {
|
||||||
videos: boolean
|
videos: boolean
|
||||||
},
|
},
|
||||||
stickers: {
|
stickers: {
|
||||||
suggest: boolean,
|
suggest: 'all' | 'installed' | 'none',
|
||||||
|
dynamicPackOrder: boolean,
|
||||||
loop: boolean
|
loop: boolean
|
||||||
},
|
},
|
||||||
emoji: {
|
emoji: {
|
||||||
|
@ -267,7 +268,8 @@ export const STATE_INIT: State = {
|
||||||
video_upload_maxbitrate: 100
|
video_upload_maxbitrate: 100
|
||||||
},
|
},
|
||||||
stickers: {
|
stickers: {
|
||||||
suggest: true,
|
suggest: 'all',
|
||||||
|
dynamicPackOrder: true,
|
||||||
loop: true
|
loop: true
|
||||||
},
|
},
|
||||||
emoji: {
|
emoji: {
|
||||||
|
|
|
@ -6,11 +6,13 @@
|
||||||
|
|
||||||
import ButtonMenu, {ButtonMenuItemOptionsVerifiable} from '../../components/buttonMenu';
|
import ButtonMenu, {ButtonMenuItemOptionsVerifiable} from '../../components/buttonMenu';
|
||||||
import filterAsync from '../array/filterAsync';
|
import filterAsync from '../array/filterAsync';
|
||||||
|
import callbackify from '../callbackify';
|
||||||
import contextMenuController from '../contextMenuController';
|
import contextMenuController from '../contextMenuController';
|
||||||
import ListenerSetter from '../listenerSetter';
|
import ListenerSetter from '../listenerSetter';
|
||||||
import {getMiddleware} from '../middleware';
|
import {getMiddleware, Middleware} from '../middleware';
|
||||||
import positionMenu from '../positionMenu';
|
import positionMenu from '../positionMenu';
|
||||||
import {attachContextMenuListener} from './attachContextMenuListener';
|
import {attachContextMenuListener} from './attachContextMenuListener';
|
||||||
|
import {attachClickEvent} from './clickEvent';
|
||||||
|
|
||||||
export default function createContextMenu<T extends ButtonMenuItemOptionsVerifiable>({
|
export default function createContextMenu<T extends ButtonMenuItemOptionsVerifiable>({
|
||||||
buttons,
|
buttons,
|
||||||
|
@ -21,7 +23,9 @@ export default function createContextMenu<T extends ButtonMenuItemOptionsVerifia
|
||||||
onOpen,
|
onOpen,
|
||||||
onClose,
|
onClose,
|
||||||
onBeforeOpen,
|
onBeforeOpen,
|
||||||
listenerSetter: attachListenerSetter
|
listenerSetter: attachListenerSetter,
|
||||||
|
middleware,
|
||||||
|
listenForClick
|
||||||
}: {
|
}: {
|
||||||
buttons: T[],
|
buttons: T[],
|
||||||
findElement?: (e: MouseEvent | TouchEvent) => HTMLElement,
|
findElement?: (e: MouseEvent | TouchEvent) => HTMLElement,
|
||||||
|
@ -31,60 +35,64 @@ export default function createContextMenu<T extends ButtonMenuItemOptionsVerifia
|
||||||
onOpen?: (target: HTMLElement) => any,
|
onOpen?: (target: HTMLElement) => any,
|
||||||
onClose?: () => any,
|
onClose?: () => any,
|
||||||
onBeforeOpen?: () => any,
|
onBeforeOpen?: () => any,
|
||||||
listenerSetter?: ListenerSetter
|
listenerSetter?: ListenerSetter,
|
||||||
|
middleware?: Middleware,
|
||||||
|
listenForClick?: boolean
|
||||||
}) {
|
}) {
|
||||||
appendTo ??= document.body;
|
appendTo ??= document.body;
|
||||||
|
|
||||||
attachListenerSetter ??= new ListenerSetter();
|
attachListenerSetter ??= new ListenerSetter();
|
||||||
const listenerSetter = new ListenerSetter();
|
const listenerSetter = new ListenerSetter();
|
||||||
const middleware = getMiddleware();
|
const middlewareHelper = middleware ? middleware.create() : getMiddleware();
|
||||||
let element: HTMLElement;
|
let element: HTMLElement;
|
||||||
|
|
||||||
attachContextMenuListener({
|
const open = (e: MouseEvent | TouchEvent) => {
|
||||||
element: listenTo,
|
const target = findElement ? findElement(e as any) : listenTo;
|
||||||
callback: (e) => {
|
if(!target) {
|
||||||
const target = findElement ? findElement(e as any) : listenTo;
|
return;
|
||||||
if(!target) {
|
}
|
||||||
|
|
||||||
|
let _element = element;
|
||||||
|
if(e instanceof MouseEvent || e.hasOwnProperty('preventDefault')) (e as any).preventDefault();
|
||||||
|
if(_element && _element.classList.contains('active')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(e instanceof MouseEvent || e.hasOwnProperty('cancelBubble')) (e as any).cancelBubble = true;
|
||||||
|
|
||||||
|
const r = async() => {
|
||||||
|
await onOpen?.(target);
|
||||||
|
|
||||||
|
const initResult = await init();
|
||||||
|
if(!initResult) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let _element = element;
|
_element = initResult.element;
|
||||||
if(e instanceof MouseEvent || e.hasOwnProperty('preventDefault')) (e as any).preventDefault();
|
const {cleanup, destroy} = initResult;
|
||||||
if(_element && _element.classList.contains('active')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(e instanceof MouseEvent || e.hasOwnProperty('cancelBubble')) (e as any).cancelBubble = true;
|
|
||||||
|
|
||||||
const r = async() => {
|
positionMenu(e, _element);
|
||||||
await onOpen?.(target);
|
contextMenuController.openBtnMenu(_element, () => {
|
||||||
|
onClose?.();
|
||||||
|
cleanup();
|
||||||
|
|
||||||
const initResult = await init();
|
setTimeout(() => {
|
||||||
if(!initResult) {
|
destroy();
|
||||||
return;
|
}, 300);
|
||||||
}
|
});
|
||||||
|
};
|
||||||
|
|
||||||
_element = initResult.element;
|
r();
|
||||||
const {cleanup, destroy} = initResult;
|
};
|
||||||
|
|
||||||
positionMenu(e, _element);
|
attachContextMenuListener({
|
||||||
contextMenuController.openBtnMenu(_element, () => {
|
element: listenTo,
|
||||||
onClose?.();
|
callback: open,
|
||||||
cleanup();
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
destroy();
|
|
||||||
}, 300);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
r();
|
|
||||||
},
|
|
||||||
listenerSetter: attachListenerSetter
|
listenerSetter: attachListenerSetter
|
||||||
});
|
});
|
||||||
|
|
||||||
const cleanup = () => {
|
const cleanup = () => {
|
||||||
listenerSetter.removeAll();
|
listenerSetter.removeAll();
|
||||||
middleware.clean();
|
middlewareHelper.clean();
|
||||||
};
|
};
|
||||||
|
|
||||||
const destroy = () => {
|
const destroy = () => {
|
||||||
|
@ -96,7 +104,9 @@ export default function createContextMenu<T extends ButtonMenuItemOptionsVerifia
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
buttons.forEach((button) => button.element = undefined);
|
buttons.forEach((button) => button.element = undefined);
|
||||||
const f = filterButtons || ((buttons: T[]) => filterAsync(buttons, (button) => button?.verify ? button.verify() : true));
|
const f = filterButtons || ((buttons: T[]) => filterAsync(buttons, (button) => {
|
||||||
|
return button?.verify ? callbackify(button.verify(), (result) => result ?? false) : true;
|
||||||
|
}));
|
||||||
|
|
||||||
const filteredButtons = await f(buttons);
|
const filteredButtons = await f(buttons);
|
||||||
if(!filteredButtons.length) {
|
if(!filteredButtons.length) {
|
||||||
|
@ -122,5 +132,15 @@ export default function createContextMenu<T extends ButtonMenuItemOptionsVerifia
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
return {element, destroy};
|
if(middleware) {
|
||||||
|
middleware.onDestroy(() => {
|
||||||
|
destroy();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(listenForClick) {
|
||||||
|
attachClickEvent(listenTo, open, {listenerSetter: attachListenerSetter});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {element, destroy, open};
|
||||||
}
|
}
|
||||||
|
|
|
@ -933,6 +933,13 @@ const lang = {
|
||||||
'ErrorSendRestrictedPollsAll': 'Sorry, sending polls is not allowed in this group.',
|
'ErrorSendRestrictedPollsAll': 'Sorry, sending polls is not allowed in this group.',
|
||||||
'Remove': 'Remove',
|
'Remove': 'Remove',
|
||||||
'ChannelBlockUser': 'Remove User',
|
'ChannelBlockUser': 'Remove User',
|
||||||
|
'StickersName': 'Stickers and Emoji',
|
||||||
|
'LoopAnimatedStickersInfo': 'Animated stickers will play continuously in chats.',
|
||||||
|
'SuggestStickersAll': 'All Sets',
|
||||||
|
'SuggestStickersInstalled': 'My Sets',
|
||||||
|
'SuggestStickersNone': 'None',
|
||||||
|
'DynamicPackOrder': 'Dynamic Pack Order',
|
||||||
|
'DynamicPackOrderInfo': 'Automatically place recently used sticker packs at the front of the panel.',
|
||||||
|
|
||||||
// * macos
|
// * macos
|
||||||
'AccountSettings.Filters': 'Chat Folders',
|
'AccountSettings.Filters': 'Chat Folders',
|
||||||
|
|
|
@ -166,14 +166,13 @@ const processAfter = (cb: () => void) => {
|
||||||
cb();
|
cb();
|
||||||
};
|
};
|
||||||
|
|
||||||
const UPDATE_STICKERSET_ORDER = true;
|
|
||||||
|
|
||||||
export type MessageSendingParams = Partial<{
|
export type MessageSendingParams = Partial<{
|
||||||
threadId: number,
|
threadId: number,
|
||||||
replyToMsgId: number,
|
replyToMsgId: number,
|
||||||
scheduleDate: number,
|
scheduleDate: number,
|
||||||
silent: boolean,
|
silent: boolean,
|
||||||
sendAsPeerId: number,
|
sendAsPeerId: number,
|
||||||
|
updateStickersetOrder: boolean
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export class AppMessagesManager extends AppManager {
|
export class AppMessagesManager extends AppManager {
|
||||||
|
@ -657,7 +656,7 @@ export class AppMessagesManager extends AppManager {
|
||||||
schedule_date: options.scheduleDate || undefined,
|
schedule_date: options.scheduleDate || undefined,
|
||||||
silent: options.silent,
|
silent: options.silent,
|
||||||
send_as: sendAs,
|
send_as: sendAs,
|
||||||
update_stickersets_order: UPDATE_STICKERSET_ORDER
|
update_stickersets_order: options.updateStickersetOrder
|
||||||
}, sentRequestOptions);
|
}, sentRequestOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1146,7 +1145,8 @@ export class AppMessagesManager extends AppManager {
|
||||||
silent: options.silent,
|
silent: options.silent,
|
||||||
entities,
|
entities,
|
||||||
clear_draft: options.clearDraft,
|
clear_draft: options.clearDraft,
|
||||||
send_as: options.sendAsPeerId ? this.appPeersManager.getInputPeerById(options.sendAsPeerId) : undefined
|
send_as: options.sendAsPeerId ? this.appPeersManager.getInputPeerById(options.sendAsPeerId) : undefined,
|
||||||
|
update_stickersets_order: options.updateStickersetOrder
|
||||||
}).then((updates) => {
|
}).then((updates) => {
|
||||||
this.apiUpdatesManager.processUpdateMessage(updates);
|
this.apiUpdatesManager.processUpdateMessage(updates);
|
||||||
}, (error: ApiError) => {
|
}, (error: ApiError) => {
|
||||||
|
@ -1272,7 +1272,7 @@ export class AppMessagesManager extends AppManager {
|
||||||
silent: options.silent,
|
silent: options.silent,
|
||||||
clear_draft: options.clearDraft,
|
clear_draft: options.clearDraft,
|
||||||
send_as: options.sendAsPeerId ? this.appPeersManager.getInputPeerById(options.sendAsPeerId) : undefined,
|
send_as: options.sendAsPeerId ? this.appPeersManager.getInputPeerById(options.sendAsPeerId) : undefined,
|
||||||
update_stickersets_order: UPDATE_STICKERSET_ORDER
|
update_stickersets_order: options.updateStickersetOrder
|
||||||
}).then((updates) => {
|
}).then((updates) => {
|
||||||
this.apiUpdatesManager.processUpdateMessage(updates);
|
this.apiUpdatesManager.processUpdateMessage(updates);
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
|
@ -1488,7 +1488,7 @@ export class AppMessagesManager extends AppManager {
|
||||||
schedule_date: options.scheduleDate,
|
schedule_date: options.scheduleDate,
|
||||||
silent: options.silent,
|
silent: options.silent,
|
||||||
send_as: sendAs,
|
send_as: sendAs,
|
||||||
update_stickersets_order: UPDATE_STICKERSET_ORDER
|
update_stickersets_order: options.updateStickersetOrder
|
||||||
}, sentRequestOptions);
|
}, sentRequestOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,10 +72,7 @@ export class AppStickersManager extends AppManager {
|
||||||
private names: Record<string, InputStickerSet.inputStickerSetID>;
|
private names: Record<string, InputStickerSet.inputStickerSetID>;
|
||||||
|
|
||||||
protected after() {
|
protected after() {
|
||||||
this.getStickerSetPromises = {};
|
this.clear(true);
|
||||||
this.getStickersByEmoticonsPromises = {};
|
|
||||||
this.sounds = {};
|
|
||||||
this.names = {};
|
|
||||||
|
|
||||||
this.rootScope.addEventListener('user_auth', () => {
|
this.rootScope.addEventListener('user_auth', () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -83,8 +80,8 @@ export class AppStickersManager extends AppManager {
|
||||||
// this.getFavedStickersStickers();
|
// this.getFavedStickersStickers();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
if(!this.getGreetingStickersPromise && this.getGreetingStickersTimeout === undefined) {
|
if(!this.getGreetingStickersPromise) {
|
||||||
this.getGreetingStickersTimeout = ctx.setTimeout(() => {
|
this.getGreetingStickersTimeout ??= ctx.setTimeout(() => {
|
||||||
this.getGreetingStickersTimeout = undefined;
|
this.getGreetingStickersTimeout = undefined;
|
||||||
this.getGreetingSticker(true);
|
this.getGreetingSticker(true);
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
@ -106,10 +103,41 @@ export class AppStickersManager extends AppManager {
|
||||||
|
|
||||||
updateMoveStickerSetToTop: (update) => {
|
updateMoveStickerSetToTop: (update) => {
|
||||||
this.rootScope.dispatchEvent('stickers_top', update.stickerset);
|
this.rootScope.dispatchEvent('stickers_top', update.stickerset);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateStickerSetsOrder: (update) => {
|
||||||
|
this.rootScope.dispatchEvent('stickers_order', {
|
||||||
|
type: update.pFlags.emojis ? 'emojis' : (update.pFlags.masks ? 'masks' : 'stickers'),
|
||||||
|
order: update.order
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// updateStickerSets: (update) => {
|
||||||
|
// if(update.pFlags.masks) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// this.storage.clear(false);
|
||||||
|
|
||||||
|
// if(update.pFlags.emojis) {
|
||||||
|
|
||||||
|
// } else {
|
||||||
|
// this.favedStickers = undefined;
|
||||||
|
// this.recentStickers = undefined;
|
||||||
|
// this.onStickersUpdated('recent', true);
|
||||||
|
// this.onStickersUpdated('faved', true);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public clear = (init?: boolean) => {
|
||||||
|
this.getStickerSetPromises = {};
|
||||||
|
this.getStickersByEmoticonsPromises = {};
|
||||||
|
this.sounds = {};
|
||||||
|
this.names = {};
|
||||||
|
};
|
||||||
|
|
||||||
private async onStickersUpdated(type: 'faved' | 'recent', overwrite: boolean) {
|
private async onStickersUpdated(type: 'faved' | 'recent', overwrite: boolean) {
|
||||||
const stickers = await (type === 'faved' ? this.getFavedStickersStickers(overwrite) : this.getRecentStickersStickers(overwrite));
|
const stickers = await (type === 'faved' ? this.getFavedStickersStickers(overwrite) : this.getRecentStickersStickers(overwrite));
|
||||||
this.rootScope.dispatchEvent('stickers_updated', {
|
this.rootScope.dispatchEvent('stickers_updated', {
|
||||||
|
@ -673,27 +701,29 @@ export class AppStickersManager extends AppManager {
|
||||||
|
|
||||||
public preloadStickerSets() {
|
public preloadStickerSets() {
|
||||||
return this.getAllStickers().then((allStickers) => {
|
return this.getAllStickers().then((allStickers) => {
|
||||||
return Promise.all((allStickers as MessagesAllStickers.messagesAllStickers).sets.map((set) => this.getStickerSet(set, {useCache: true})));
|
const sets = (allStickers as MessagesAllStickers.messagesAllStickers).sets;
|
||||||
|
return Promise.all(sets.map((set) => this.getStickerSet(set, {useCache: true})));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: detect "🤷" by "🤷♂️"
|
// TODO: detect "🤷" by "🤷♂️"
|
||||||
public getStickersByEmoticon(emoticon: string, includeOurStickers = true) {
|
public getStickersByEmoticon(emoticon: string, includeOurStickers = true, includeServerStickers = true) {
|
||||||
emoticon = fixEmoji(emoticon);
|
emoticon = fixEmoji(emoticon);
|
||||||
if(this.getStickersByEmoticonsPromises[emoticon]) return this.getStickersByEmoticonsPromises[emoticon];
|
const cacheKey = emoticon + (includeOurStickers ? '1' : '0') + (includeServerStickers ? '1' : '0');
|
||||||
|
if(this.getStickersByEmoticonsPromises[cacheKey]) return this.getStickersByEmoticonsPromises[cacheKey];
|
||||||
|
|
||||||
return this.getStickersByEmoticonsPromises[emoticon] = Promise.all([
|
return this.getStickersByEmoticonsPromises[cacheKey] = Promise.all([
|
||||||
this.apiManager.invokeApiHashable({
|
includeServerStickers ? this.apiManager.invokeApiHashable({
|
||||||
method: 'messages.getStickers',
|
method: 'messages.getStickers',
|
||||||
params: {
|
params: {
|
||||||
emoticon
|
emoticon
|
||||||
},
|
},
|
||||||
processResult: (stickers) => stickers
|
processResult: (stickers) => stickers
|
||||||
}),
|
}) : undefined,
|
||||||
includeOurStickers ? this.preloadStickerSets() : [],
|
includeOurStickers ? this.preloadStickerSets() : [],
|
||||||
includeOurStickers ? this.getRecentStickers() : undefined
|
includeOurStickers ? this.getRecentStickers() : undefined
|
||||||
]).then(([messagesStickers, installedSets, recentStickers]) => {
|
]).then(([messagesStickers, installedSets, recentStickers]) => {
|
||||||
const foundStickers = (messagesStickers as MessagesStickers.messagesStickers).stickers.map((sticker) => this.appDocsManager.saveDoc(sticker));
|
const foundStickers = messagesStickers ? (messagesStickers as MessagesStickers.messagesStickers).stickers.map((sticker) => this.appDocsManager.saveDoc(sticker)) : [];
|
||||||
const cachedStickersAnimated: Document.document[] = [], cachedStickersStatic: Document.document[] = [];
|
const cachedStickersAnimated: Document.document[] = [], cachedStickersStatic: Document.document[] = [];
|
||||||
|
|
||||||
// console.log('getStickersByEmoticon', messagesStickers, installedSets, recentStickers);
|
// console.log('getStickersByEmoticon', messagesStickers, installedSets, recentStickers);
|
||||||
|
@ -755,4 +785,21 @@ export class AppStickersManager extends AppManager {
|
||||||
|
|
||||||
return this.apiManager.invokeApi('messages.clearRecentStickers');
|
return this.apiManager.invokeApi('messages.clearRecentStickers');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public reorderStickerSets(order: StickerSet.stickerSet['id'][], emojis?: boolean, masks?: boolean) {
|
||||||
|
return this.apiManager.invokeApi('messages.reorderStickerSets', {
|
||||||
|
emojis,
|
||||||
|
masks,
|
||||||
|
order
|
||||||
|
}).then(() => {
|
||||||
|
this.apiUpdatesManager.processLocalUpdate({
|
||||||
|
_: 'updateStickerSetsOrder',
|
||||||
|
order,
|
||||||
|
pFlags: {
|
||||||
|
emojis: emojis || undefined,
|
||||||
|
masks: masks || undefined
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -383,6 +383,10 @@ async function loadStateInner() {
|
||||||
state.settings.liteMode.gif = !state.settings.autoPlay.gifs;
|
state.settings.liteMode.gif = !state.settings.autoPlay.gifs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(state.build < 312 && typeof(state.settings.stickers.suggest) === 'boolean') {
|
||||||
|
state.settings.stickers.suggest = state.settings.stickers.suggest ? 'all' : 'none';
|
||||||
|
}
|
||||||
|
|
||||||
if(compareVersion(state.version, STATE_VERSION) !== 0) {
|
if(compareVersion(state.version, STATE_VERSION) !== 0) {
|
||||||
newVersion = STATE_VERSION;
|
newVersion = STATE_VERSION;
|
||||||
oldVersion = state.version;
|
oldVersion = state.version;
|
||||||
|
|
|
@ -93,6 +93,7 @@ export type BroadcastEvents = {
|
||||||
'stickers_deleted': StickerSet.stickerSet,
|
'stickers_deleted': StickerSet.stickerSet,
|
||||||
'stickers_updated': {type: 'recent' | 'faved', stickers: MyDocument[]},
|
'stickers_updated': {type: 'recent' | 'faved', stickers: MyDocument[]},
|
||||||
'stickers_top': Long,
|
'stickers_top': Long,
|
||||||
|
'stickers_order': {type: 'masks' | 'emojis' | 'stickers', order: Long[]},
|
||||||
'sticker_updated': {type: 'recent' | 'faved', document: MyDocument, faved: boolean},
|
'sticker_updated': {type: 'recent' | 'faved', document: MyDocument, faved: boolean},
|
||||||
|
|
||||||
'state_cleared': void,
|
'state_cleared': void,
|
||||||
|
|
|
@ -10,11 +10,11 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
max-width: calc(#{$large-screen} + 2px) !important;
|
max-width: calc(#{$large-screen} + 2px) !important;
|
||||||
|
|
||||||
.avatar-edit {
|
// .avatar-edit {
|
||||||
.tgico-cameraadd {
|
// .tgico-cameraadd {
|
||||||
top: 52%;
|
// top: 52%;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
#main-columns {
|
#main-columns {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
Loading…
Reference in New Issue