Some fixes
This commit is contained in:
parent
274f611bdd
commit
6a3a923310
|
@ -282,7 +282,7 @@ export default class BubbleGroups {
|
||||||
}
|
}
|
||||||
|
|
||||||
removeItem(item: GroupItem) {
|
removeItem(item: GroupItem) {
|
||||||
item.group.removeItem(item);
|
item.group?.removeItem(item);
|
||||||
this.removeItemFromCache(item);
|
this.removeItemFromCache(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,10 +298,12 @@ export default class BubbleGroups {
|
||||||
|
|
||||||
const group = item.group;
|
const group = item.group;
|
||||||
this.removeItem(item);
|
this.removeItem(item);
|
||||||
group.unmountItem(item);
|
|
||||||
|
|
||||||
const modifiedGroups: Set<BubbleGroup> = new Set();
|
const modifiedGroups: Set<BubbleGroup> = new Set();
|
||||||
modifiedGroups.add(group);
|
if(group) {
|
||||||
|
group.unmountItem(item);
|
||||||
|
modifiedGroups.add(group);
|
||||||
|
}
|
||||||
|
|
||||||
const [previousSibling, nextSibling] = siblings;
|
const [previousSibling, nextSibling] = siblings;
|
||||||
if(
|
if(
|
||||||
|
|
|
@ -1214,7 +1214,7 @@ export default class ChatBubbles {
|
||||||
|
|
||||||
private onBubblesMouseMove = async(e: MouseEvent) => {
|
private onBubblesMouseMove = async(e: MouseEvent) => {
|
||||||
const content = findUpClassName(e.target, 'bubble-content');
|
const content = findUpClassName(e.target, 'bubble-content');
|
||||||
if(content && !this.chat.selection.isSelecting) {
|
if(content && !this.chat.selection.isSelecting && !findUpClassName(e.target, 'service')) {
|
||||||
const bubble = findUpClassName(content, 'bubble');
|
const bubble = findUpClassName(content, 'bubble');
|
||||||
if(!this.chat.selection.canSelectBubble(bubble)) {
|
if(!this.chat.selection.canSelectBubble(bubble)) {
|
||||||
this.unhoverPrevious();
|
this.unhoverPrevious();
|
||||||
|
@ -1241,7 +1241,12 @@ export default class ChatBubbles {
|
||||||
|
|
||||||
content.append(hoverReaction);
|
content.append(hoverReaction);
|
||||||
|
|
||||||
let message = (await this.chat.getMessage(+bubble.dataset.mid)) as Message.message;
|
let message = await this.chat.getMessage(+bubble.dataset.mid);
|
||||||
|
if(message?._ !== 'message') {
|
||||||
|
this.unhoverPrevious();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
message = await this.managers.appMessagesManager.getGroupsFirstMessage(message);
|
message = await this.managers.appMessagesManager.getGroupsFirstMessage(message);
|
||||||
|
|
||||||
const middleware = this.getMiddleware(() => this.hoverReaction === hoverReaction);
|
const middleware = this.getMiddleware(() => this.hoverReaction === hoverReaction);
|
||||||
|
@ -1281,7 +1286,7 @@ export default class ChatBubbles {
|
||||||
attachClickEvent(hoverReaction, (e) => {
|
attachClickEvent(hoverReaction, (e) => {
|
||||||
cancelEvent(e); // cancel triggering selection
|
cancelEvent(e); // cancel triggering selection
|
||||||
|
|
||||||
this.managers.appReactionsManager.sendReaction(message, availableReaction);
|
this.managers.appReactionsManager.sendReaction(message as Message.message, availableReaction);
|
||||||
this.unhoverPrevious();
|
this.unhoverPrevious();
|
||||||
}, {listenerSetter: this.listenerSetter});
|
}, {listenerSetter: this.listenerSetter});
|
||||||
}, noop);
|
}, noop);
|
||||||
|
@ -4407,6 +4412,7 @@ export default class ChatBubbles {
|
||||||
bubble.classList.add('must-have-name');
|
bubble.classList.add('must-have-name');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isForward = fwdFromId || fwdFrom;
|
||||||
if(isHidden) {
|
if(isHidden) {
|
||||||
// /////this.log('message to render hidden', message);
|
// /////this.log('message to render hidden', message);
|
||||||
title = document.createElement('span');
|
title = document.createElement('span');
|
||||||
|
@ -4415,7 +4421,7 @@ export default class ChatBubbles {
|
||||||
// title = fwdFrom.from_name;
|
// title = fwdFrom.from_name;
|
||||||
bubble.classList.add('hidden-profile');
|
bubble.classList.add('hidden-profile');
|
||||||
} else {
|
} else {
|
||||||
title = new PeerTitle({peerId: fwdFromId || message.fromId, withPremiumIcon: true}).element;
|
title = new PeerTitle({peerId: fwdFromId || message.fromId, withPremiumIcon: !isForward}).element;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(message.reply_to_mid && message.reply_to_mid !== this.chat.threadId && isMessage) {
|
if(message.reply_to_mid && message.reply_to_mid !== this.chat.threadId && isMessage) {
|
||||||
|
@ -4430,7 +4436,7 @@ export default class ChatBubbles {
|
||||||
// this.log(title);
|
// this.log(title);
|
||||||
|
|
||||||
let nameDiv: HTMLElement;
|
let nameDiv: HTMLElement;
|
||||||
if((fwdFromId || fwdFrom)) {
|
if(isForward) {
|
||||||
if(this.peerId !== rootScope.myId && !isForwardFromChannel) {
|
if(this.peerId !== rootScope.myId && !isForwardFromChannel) {
|
||||||
bubble.classList.add('forwarded');
|
bubble.classList.add('forwarded');
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@ import type {Dialog} from '../lib/appManagers/appMessagesManager';
|
||||||
import rootScope from '../lib/rootScope';
|
import rootScope from '../lib/rootScope';
|
||||||
import ButtonMenu, {ButtonMenuItemOptions} from './buttonMenu';
|
import ButtonMenu, {ButtonMenuItemOptions} from './buttonMenu';
|
||||||
import PopupDeleteDialog from './popups/deleteDialog';
|
import PopupDeleteDialog from './popups/deleteDialog';
|
||||||
import {i18n} from '../lib/langPack';
|
import {i18n, LangPackKey, _i18n} from '../lib/langPack';
|
||||||
import findUpTag from '../helpers/dom/findUpTag';
|
import findUpTag from '../helpers/dom/findUpTag';
|
||||||
import PopupPeer from './popups/peer';
|
import PopupPeer, {PopupPeerButton} from './popups/peer';
|
||||||
import AppChatFoldersTab from './sidebarLeft/tabs/chatFolders';
|
import AppChatFoldersTab from './sidebarLeft/tabs/chatFolders';
|
||||||
import appSidebarLeft from './sidebarLeft';
|
import appSidebarLeft from './sidebarLeft';
|
||||||
import {toastNew} from './toast';
|
import {toastNew} from './toast';
|
||||||
|
@ -19,6 +19,7 @@ import PopupMute from './popups/mute';
|
||||||
import {AppManagers} from '../lib/appManagers/managers';
|
import {AppManagers} from '../lib/appManagers/managers';
|
||||||
import positionMenu from '../helpers/positionMenu';
|
import positionMenu from '../helpers/positionMenu';
|
||||||
import contextMenuController from '../helpers/contextMenuController';
|
import contextMenuController from '../helpers/contextMenuController';
|
||||||
|
import type {ApiLimitType} from '../lib/mtproto/api_methods';
|
||||||
|
|
||||||
export default class DialogsContextMenu {
|
export default class DialogsContextMenu {
|
||||||
private element: HTMLElement;
|
private element: HTMLElement;
|
||||||
|
@ -113,6 +114,107 @@ export default class DialogsContextMenu {
|
||||||
if(this.filterId >= 1) {
|
if(this.filterId >= 1) {
|
||||||
toastNew({langPackKey: 'PinFolderLimitReached'});
|
toastNew({langPackKey: 'PinFolderLimitReached'});
|
||||||
} else {
|
} else {
|
||||||
|
// const a: {[type in ApiLimitType]?: {
|
||||||
|
// title: LangPackKey,
|
||||||
|
// description: LangPackKey,
|
||||||
|
// descriptionPremium: LangPackKey,
|
||||||
|
// descriptionLocked: LangPackKey,
|
||||||
|
// icon: string
|
||||||
|
// }} = {
|
||||||
|
// pin: {
|
||||||
|
// title: 'LimitReached',
|
||||||
|
// description: 'LimitReachedPinDialogs',
|
||||||
|
// descriptionPremium: 'LimitReachedPinDialogsPremium',
|
||||||
|
// descriptionLocked: 'LimitReachedPinDialogsLocked',
|
||||||
|
// icon: 'limit_pin'
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class P extends PopupPeer {
|
||||||
|
// constructor(options: {
|
||||||
|
// isPremium: boolean,
|
||||||
|
// limit: number,
|
||||||
|
// limitPremium: number
|
||||||
|
// }, _a: typeof a[keyof typeof a]) {
|
||||||
|
// super('popup-limit', {
|
||||||
|
// buttons: options.isPremium === undefined ? [{
|
||||||
|
// langKey: 'LimitReached.Ok',
|
||||||
|
// isCancel: true
|
||||||
|
// }] : (options.isPremium ? [{
|
||||||
|
// langKey: 'OK',
|
||||||
|
// isCancel: true
|
||||||
|
// }] : [{
|
||||||
|
// langKey: 'IncreaseLimit',
|
||||||
|
// callback: () => {
|
||||||
|
|
||||||
|
// }
|
||||||
|
// }, {
|
||||||
|
// langKey: 'Cancel',
|
||||||
|
// isCancel: true
|
||||||
|
// }]),
|
||||||
|
// descriptionLangKey: options.isPremium === undefined ? _a.descriptionLocked : (options.isPremium ? _a.descriptionPremium : _a.description),
|
||||||
|
// descriptionLangArgs: options.isPremium ? [options.limitPremium] : [options.limit, options.limitPremium],
|
||||||
|
// titleLangKey: _a.title
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const isLocked = options.isPremium === undefined;
|
||||||
|
// if(isLocked) {
|
||||||
|
// this.element.classList.add('is-locked');
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const limitContainer = document.createElement('div');
|
||||||
|
// limitContainer.classList.add('popup-limit-line');
|
||||||
|
|
||||||
|
// const hint = document.createElement('div');
|
||||||
|
// hint.classList.add('popup-limit-hint');
|
||||||
|
// const i = document.createElement('span');
|
||||||
|
// i.classList.add('popup-limit-hint-icon', 'tgico-' + _a.icon);
|
||||||
|
// hint.append(i, '' + (options.isPremium ? options.limitPremium : options.limit));
|
||||||
|
|
||||||
|
// limitContainer.append(hint);
|
||||||
|
|
||||||
|
// if(!isLocked) {
|
||||||
|
// const limit = document.createElement('div');
|
||||||
|
// limit.classList.add('limit-line');
|
||||||
|
|
||||||
|
// const free = document.createElement('div');
|
||||||
|
// free.classList.add('limit-line-free');
|
||||||
|
|
||||||
|
// const premium = document.createElement('div');
|
||||||
|
// premium.classList.add('limit-line-premium');
|
||||||
|
|
||||||
|
// limit.append(free, premium);
|
||||||
|
|
||||||
|
// _i18n(free, 'LimitFree');
|
||||||
|
// premium.append(i18n('LimitPremium'), '' + options.limitPremium);
|
||||||
|
|
||||||
|
// limitContainer.append(limit);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// this.container.insertBefore(limitContainer, this.description);
|
||||||
|
|
||||||
|
// if(options.isPremium === false) {
|
||||||
|
// this.buttons.pop().element.remove();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// async function showLimitPopup(type: keyof typeof a) {
|
||||||
|
// const _a = a[type];
|
||||||
|
// const [appConfig, limit, limitPremium] = await Promise.all([
|
||||||
|
// rootScope.managers.apiManager.getAppConfig(),
|
||||||
|
// ...[false, true].map((v) => rootScope.managers.apiManager.getLimit(type, v))
|
||||||
|
// ]);
|
||||||
|
// const isLocked = appConfig.premium_purchase_blocked;
|
||||||
|
// new P({
|
||||||
|
// isPremium: isLocked ? undefined : rootScope.premium,
|
||||||
|
// limit,
|
||||||
|
// limitPremium
|
||||||
|
// }, _a).show();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// showLimitPopup('pin');
|
||||||
|
|
||||||
const config = await this.managers.apiManager.getConfig();
|
const config = await this.managers.apiManager.getConfig();
|
||||||
new PopupPeer('pinned-dialogs-too-much', {
|
new PopupPeer('pinned-dialogs-too-much', {
|
||||||
buttons: [{
|
buttons: [{
|
||||||
|
|
|
@ -298,8 +298,7 @@ class EmoticonsTabC {
|
||||||
export default class StickersTab extends EmoticonsTabC implements EmoticonsTab {
|
export default class StickersTab extends EmoticonsTabC implements EmoticonsTab {
|
||||||
private superStickerRenderer: SuperStickerRenderer;
|
private superStickerRenderer: SuperStickerRenderer;
|
||||||
|
|
||||||
private setFavedLimit(appConfig: MTAppConfig) {
|
private setFavedLimit(limit: number) {
|
||||||
const limit = rootScope.premium ? appConfig.stickers_faved_limit_premium : appConfig.stickers_faved_limit_default;
|
|
||||||
const category = this.categories['faved'];
|
const category = this.categories['faved'];
|
||||||
category.limit = limit;
|
category.limit = limit;
|
||||||
}
|
}
|
||||||
|
@ -494,10 +493,10 @@ export default class StickersTab extends EmoticonsTabC implements EmoticonsTab {
|
||||||
|
|
||||||
const promises = [
|
const promises = [
|
||||||
Promise.all([
|
Promise.all([
|
||||||
this.managers.apiManager.getAppConfig(),
|
this.managers.apiManager.getLimit('favedStickers'),
|
||||||
this.managers.appStickersManager.getFavedStickersStickers()
|
this.managers.appStickersManager.getFavedStickersStickers()
|
||||||
]).then(([appConfig, stickers]) => {
|
]).then(([limit, stickers]) => {
|
||||||
this.setFavedLimit(appConfig);
|
this.setFavedLimit(limit);
|
||||||
onCategoryStickers(favedCategory, stickers);
|
onCategoryStickers(favedCategory, stickers);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -604,7 +603,9 @@ export default class StickersTab extends EmoticonsTabC implements EmoticonsTab {
|
||||||
});
|
});
|
||||||
|
|
||||||
rootScope.addEventListener('app_config', (appConfig) => {
|
rootScope.addEventListener('app_config', (appConfig) => {
|
||||||
this.setFavedLimit(appConfig);
|
this.managers.apiManager.getLimit('favedStickers').then((limit) => {
|
||||||
|
this.setFavedLimit(limit);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const resizeCategories = () => {
|
const resizeCategories = () => {
|
||||||
|
|
|
@ -209,6 +209,7 @@ export const RadioFormFromRows = (rows: Row[], onChange: (value: string) => void
|
||||||
|
|
||||||
export const RadioFormFromValues = (values: {langPackKey: LangPackKey, value: number | string, checked?: boolean}[], onChange: Parameters<typeof RadioFormFromRows>[1]) => {
|
export const RadioFormFromValues = (values: {langPackKey: LangPackKey, value: number | string, checked?: boolean}[], onChange: Parameters<typeof RadioFormFromRows>[1]) => {
|
||||||
const name = 'name-' + (Math.random() * 0x7FFFFF | 0);
|
const name = 'name-' + (Math.random() * 0x7FFFFF | 0);
|
||||||
|
let checkedRadioField: RadioField;
|
||||||
const rows = values.map(({langPackKey, value, checked}) => {
|
const rows = values.map(({langPackKey, value, checked}) => {
|
||||||
const row = new Row({
|
const row = new Row({
|
||||||
radioField: new RadioField({
|
radioField: new RadioField({
|
||||||
|
@ -219,11 +220,15 @@ export const RadioFormFromValues = (values: {langPackKey: LangPackKey, value: nu
|
||||||
});
|
});
|
||||||
|
|
||||||
if(checked) {
|
if(checked) {
|
||||||
row.radioField.checked = checked;
|
checkedRadioField = row.radioField;
|
||||||
}
|
}
|
||||||
|
|
||||||
return row;
|
return row;
|
||||||
});
|
});
|
||||||
|
|
||||||
return RadioFormFromRows(rows, onChange);
|
const form = RadioFormFromRows(rows, onChange);
|
||||||
|
if(checkedRadioField) {
|
||||||
|
checkedRadioField.checked = true;
|
||||||
|
}
|
||||||
|
return form;
|
||||||
};
|
};
|
||||||
|
|
|
@ -260,13 +260,13 @@ export default class AppChatFoldersTab extends SliderSuperTab {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async canCreateFolder() {
|
private async canCreateFolder() {
|
||||||
const [appConfig, filters] = await Promise.all([
|
const [limit, filters] = await Promise.all([
|
||||||
this.managers.apiManager.getAppConfig(),
|
this.managers.apiManager.getLimit('folders'),
|
||||||
this.managers.filtersStorage.getDialogFilters()
|
this.managers.filtersStorage.getDialogFilters()
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const filtersLength = filters.filter((filter) => !REAL_FOLDERS.has(filter.id)).length;
|
const filtersLength = filters.filter((filter) => !REAL_FOLDERS.has(filter.id)).length;
|
||||||
return filtersLength < (rootScope.premium ? appConfig.dialog_filters_limit_premium : appConfig.dialog_filters_limit_default);
|
return filtersLength < limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSuggestedFilters() {
|
private getSuggestedFilters() {
|
||||||
|
|
|
@ -37,7 +37,7 @@ export default class AppEditProfileTab extends SliderSuperTab {
|
||||||
const inputWrapper = document.createElement('div');
|
const inputWrapper = document.createElement('div');
|
||||||
inputWrapper.classList.add('input-wrapper');
|
inputWrapper.classList.add('input-wrapper');
|
||||||
|
|
||||||
const appConfig = await this.managers.apiManager.getAppConfig();
|
const bioMaxLength = await this.managers.apiManager.getLimit('bio');
|
||||||
this.firstNameInputField = new InputField({
|
this.firstNameInputField = new InputField({
|
||||||
label: 'EditProfile.FirstNameLabel',
|
label: 'EditProfile.FirstNameLabel',
|
||||||
name: 'first-name',
|
name: 'first-name',
|
||||||
|
@ -51,7 +51,7 @@ export default class AppEditProfileTab extends SliderSuperTab {
|
||||||
this.bioInputField = new InputField({
|
this.bioInputField = new InputField({
|
||||||
label: 'EditProfile.BioLabel',
|
label: 'EditProfile.BioLabel',
|
||||||
name: 'bio',
|
name: 'bio',
|
||||||
maxLength: rootScope.premium ? appConfig.about_length_limit_premium : appConfig.about_length_limit_default
|
maxLength: bioMaxLength
|
||||||
});
|
});
|
||||||
|
|
||||||
inputWrapper.append(this.firstNameInputField.container, this.lastNameInputField.container, this.bioInputField.container);
|
inputWrapper.append(this.firstNameInputField.container, this.lastNameInputField.container, this.bioInputField.container);
|
||||||
|
|
|
@ -19,7 +19,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.4.8',
|
langPackVersion: '0.4.9',
|
||||||
langPack: 'macos',
|
langPack: 'macos',
|
||||||
langPackCode: 'en',
|
langPackCode: 'en',
|
||||||
domains: [MAIN_DOMAIN] as string[],
|
domains: [MAIN_DOMAIN] as string[],
|
||||||
|
|
|
@ -142,6 +142,7 @@ const lang = {
|
||||||
'PaymentInfo.Done': 'PROCEED TO CHECKOUT',
|
'PaymentInfo.Done': 'PROCEED TO CHECKOUT',
|
||||||
'PaymentCard.Error.Invalid': 'Invalid card number',
|
'PaymentCard.Error.Invalid': 'Invalid card number',
|
||||||
'PaymentCard.Error.Incomplete': 'Incomplete card number',
|
'PaymentCard.Error.Incomplete': 'Incomplete card number',
|
||||||
|
'LimitReached.Ok': 'OK, GOT IT',
|
||||||
|
|
||||||
// * android
|
// * android
|
||||||
'AccDescrEditing': 'Editing',
|
'AccDescrEditing': 'Editing',
|
||||||
|
@ -783,6 +784,13 @@ const lang = {
|
||||||
'AllReactions': 'All reactions',
|
'AllReactions': 'All reactions',
|
||||||
'SomeReactions': 'Some reactions',
|
'SomeReactions': 'Some reactions',
|
||||||
'NoReactions': 'No reactions',
|
'NoReactions': 'No reactions',
|
||||||
|
'LimitReached': 'Limit Reached',
|
||||||
|
'LimitReachedPinDialogs': 'You can\'t pin more than %1$d chats to the top. Unpin some that are currently pinned – or subscribe to **Telegram Premium** to double the limit to **%2$d** chats.',
|
||||||
|
'LimitReachedPinDialogsPremium': 'Sorry, you can\'t pin more than %1$d chats to the top. Unpin some that are currently pinned.',
|
||||||
|
'LimitReachedPinDialogsLocked': 'Sorry, you can\'t pin more than %1$d chats to the top. Unpin some that are currently pinned. We are working to let you increase this limit in the future.',
|
||||||
|
'IncreaseLimit': 'Increase Limit',
|
||||||
|
'LimitFree': 'Free',
|
||||||
|
'LimitPremium': 'Premium',
|
||||||
|
|
||||||
// * macos
|
// * macos
|
||||||
'AccountSettings.Filters': 'Chat Folders',
|
'AccountSettings.Filters': 'Chat Folders',
|
||||||
|
|
|
@ -3085,10 +3085,7 @@ export class AppMessagesManager extends AppManager {
|
||||||
const pinned = dialog.pFlags?.pinned ? undefined : true;
|
const pinned = dialog.pFlags?.pinned ? undefined : true;
|
||||||
|
|
||||||
if(pinned) {
|
if(pinned) {
|
||||||
const appConfig = await this.apiManager.getAppConfig();
|
const max = await this.apiManager.getLimit(filterId === 1 ? 'folderPin' : 'pin');
|
||||||
const max = filterId === 1 ?
|
|
||||||
(this.rootScope.premium ? appConfig.dialogs_folder_pinned_limit_premium : appConfig.dialogs_folder_pinned_limit_default) :
|
|
||||||
(this.rootScope.premium ? appConfig.dialogs_pinned_limit_premium : appConfig.dialogs_pinned_limit_default);
|
|
||||||
if(this.dialogsStorage.getPinnedOrders(filterId).length >= max) {
|
if(this.dialogsStorage.getPinnedOrders(filterId).length >= max) {
|
||||||
return Promise.reject(makeError('PINNED_DIALOGS_TOO_MUCH'));
|
return Promise.reject(makeError('PINNED_DIALOGS_TOO_MUCH'));
|
||||||
}
|
}
|
||||||
|
@ -4329,8 +4326,11 @@ export class AppMessagesManager extends AppManager {
|
||||||
message
|
message
|
||||||
});
|
});
|
||||||
|
|
||||||
if(isTopMessage || (message as Message.message).grouped_id) {
|
if(isTopMessage) {
|
||||||
this.dialogsStorage.setDialogToState(dialog);
|
this.dialogsStorage.setDialogToState(dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((isTopMessage || (message as Message.message).grouped_id) && dialog) {
|
||||||
this.rootScope.dispatchEvent('dialogs_multiupdate', new Map([[peerId, dialog]]));
|
this.rootScope.dispatchEvent('dialogs_multiupdate', new Map([[peerId, dialog]]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,13 @@ import {ReferenceContext} from '../mtproto/referenceDatabase';
|
||||||
|
|
||||||
export type UserTyping = Partial<{userId: UserId, action: SendMessageAction, timeout: number}>;
|
export type UserTyping = Partial<{userId: UserId, action: SendMessageAction, timeout: number}>;
|
||||||
|
|
||||||
|
const PEER_FULL_TTL = 3 * 60e3;
|
||||||
|
|
||||||
export class AppProfileManager extends AppManager {
|
export class AppProfileManager extends AppManager {
|
||||||
// private botInfos: any = {};
|
// private botInfos: any = {};
|
||||||
private usersFull: {[id: UserId]: UserFull.userFull} = {};
|
private usersFull: {[id: UserId]: UserFull.userFull} = {};
|
||||||
private chatsFull: {[id: ChatId]: ChatFull} = {};
|
private chatsFull: {[id: ChatId]: ChatFull} = {};
|
||||||
|
private fullExpiration: {[peerId: PeerId]: number} = {};
|
||||||
private typingsInPeer: {[peerId: PeerId]: UserTyping[]};
|
private typingsInPeer: {[peerId: PeerId]: UserTyping[]};
|
||||||
|
|
||||||
protected after() {
|
protected after() {
|
||||||
|
@ -161,7 +164,7 @@ export class AppProfileManager extends AppManager {
|
||||||
} */
|
} */
|
||||||
|
|
||||||
public getProfile(id: UserId, override?: true) {
|
public getProfile(id: UserId, override?: true) {
|
||||||
if(this.usersFull[id] && !override) {
|
if(this.usersFull[id] && !override && Date.now() < this.fullExpiration[id.toPeerId()]) {
|
||||||
return this.usersFull[id];
|
return this.usersFull[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,6 +196,7 @@ export class AppProfileManager extends AppManager {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.usersFull[id] = userFull;
|
this.usersFull[id] = userFull;
|
||||||
|
this.fullExpiration[peerId] = Date.now() + PEER_FULL_TTL;
|
||||||
|
|
||||||
/* if(userFull.bot_info) {
|
/* if(userFull.bot_info) {
|
||||||
userFull.bot_info = this.saveBotInfo(userFull.bot_info) as any;
|
userFull.bot_info = this.saveBotInfo(userFull.bot_info) as any;
|
||||||
|
@ -263,9 +267,10 @@ export class AppProfileManager extends AppManager {
|
||||||
return this.getChannelFull(id, override);
|
return this.getChannelFull(id, override);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const peerId = id.toPeerId(true);
|
||||||
const fullChat = this.chatsFull[id] as ChatFull.chatFull;
|
const fullChat = this.chatsFull[id] as ChatFull.chatFull;
|
||||||
if(fullChat && !override) {
|
if(fullChat && !override && Date.now() < this.fullExpiration[peerId]) {
|
||||||
const chat = this.appChatsManager.getChat(id);
|
const chat: Chat.chat = this.appChatsManager.getChat(id);
|
||||||
if(chat.version === (fullChat.participants as ChatParticipants.chatParticipants).version ||
|
if(chat.version === (fullChat.participants as ChatParticipants.chatParticipants).version ||
|
||||||
chat.pFlags.left) {
|
chat.pFlags.left) {
|
||||||
return fullChat as ChatFull;
|
return fullChat as ChatFull;
|
||||||
|
@ -281,7 +286,6 @@ export class AppProfileManager extends AppManager {
|
||||||
this.appChatsManager.saveApiChats(result.chats, true);
|
this.appChatsManager.saveApiChats(result.chats, true);
|
||||||
this.appUsersManager.saveApiUsers(result.users);
|
this.appUsersManager.saveApiUsers(result.users);
|
||||||
const chatFull = result.full_chat as ChatFull.chatFull;
|
const chatFull = result.full_chat as ChatFull.chatFull;
|
||||||
const peerId = id.toPeerId(true);
|
|
||||||
if(chatFull && chatFull.chat_photo && chatFull.chat_photo.id) {
|
if(chatFull && chatFull.chat_photo && chatFull.chat_photo.id) {
|
||||||
chatFull.chat_photo = this.appPhotosManager.savePhoto(chatFull.chat_photo, {type: 'profilePhoto', peerId});
|
chatFull.chat_photo = this.appPhotosManager.savePhoto(chatFull.chat_photo, {type: 'profilePhoto', peerId});
|
||||||
}
|
}
|
||||||
|
@ -297,6 +301,7 @@ export class AppProfileManager extends AppManager {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.chatsFull[id] = chatFull;
|
this.chatsFull[id] = chatFull;
|
||||||
|
this.fullExpiration[peerId] = Date.now() + PEER_FULL_TTL;
|
||||||
this.rootScope.dispatchEvent('chat_full_update', id);
|
this.rootScope.dispatchEvent('chat_full_update', id);
|
||||||
|
|
||||||
return chatFull;
|
return chatFull;
|
||||||
|
@ -383,7 +388,8 @@ export class AppProfileManager extends AppManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public getChannelFull(id: ChatId, override?: true) {
|
public getChannelFull(id: ChatId, override?: true) {
|
||||||
if(this.chatsFull[id] !== undefined && !override) {
|
const peerId = id.toPeerId(true);
|
||||||
|
if(this.chatsFull[id] !== undefined && !override && Date.now() < this.fullExpiration[peerId]) {
|
||||||
return this.chatsFull[id] as ChatFull.channelFull;
|
return this.chatsFull[id] as ChatFull.channelFull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,7 +399,6 @@ export class AppProfileManager extends AppManager {
|
||||||
channel: this.appChatsManager.getChannelInput(id)
|
channel: this.appChatsManager.getChannelInput(id)
|
||||||
},
|
},
|
||||||
processResult: (result) => {
|
processResult: (result) => {
|
||||||
const peerId = id.toPeerId(true);
|
|
||||||
this.appChatsManager.saveApiChats(result.chats, true);
|
this.appChatsManager.saveApiChats(result.chats, true);
|
||||||
this.appUsersManager.saveApiUsers(result.users);
|
this.appUsersManager.saveApiUsers(result.users);
|
||||||
const fullChannel = result.full_chat as ChatFull.channelFull;
|
const fullChannel = result.full_chat as ChatFull.channelFull;
|
||||||
|
@ -412,6 +417,7 @@ export class AppProfileManager extends AppManager {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.chatsFull[id] = fullChannel;
|
this.chatsFull[id] = fullChannel;
|
||||||
|
this.fullExpiration[peerId] = Date.now() + PEER_FULL_TTL;
|
||||||
this.rootScope.dispatchEvent('chat_full_update', id);
|
this.rootScope.dispatchEvent('chat_full_update', id);
|
||||||
|
|
||||||
return fullChannel;
|
return fullChannel;
|
||||||
|
@ -533,7 +539,7 @@ export class AppProfileManager extends AppManager {
|
||||||
this.rootScope.dispatchEvent('peer_bio_edit', peerId);
|
this.rootScope.dispatchEvent('peer_bio_edit', peerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.getProfile(this.appPeersManager.peerId, true);
|
return this.getProfile(user.id, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -231,8 +231,7 @@ export class AppReactionsManager extends AppManager {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const appConfig = await this.apiManager.getAppConfig();
|
const limit = await this.apiManager.getLimit('reactions');
|
||||||
const limit = this.rootScope.premium ? appConfig.reactions_user_max_premium : appConfig.reactions_user_max_default;
|
|
||||||
|
|
||||||
const lastSendingTimeKey = message.peerId + '_' + message.mid;
|
const lastSendingTimeKey = message.peerId + '_' + message.mid;
|
||||||
const lastSendingTime = this.lastSendingTimes.get(lastSendingTimeKey);
|
const lastSendingTime = this.lastSendingTimes.get(lastSendingTimeKey);
|
||||||
|
|
|
@ -521,9 +521,8 @@ export class AppStickersManager extends AppManager {
|
||||||
return this.getFavedStickers().then(() => this.favedStickers);
|
return this.getFavedStickers().then(() => this.favedStickers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getFavedStickersLimit() {
|
public getFavedStickersLimit() {
|
||||||
const appConfig = await this.apiManager.getAppConfig();
|
return this.apiManager.getLimit('favedStickers');
|
||||||
return this.rootScope.premium ? appConfig.stickers_faved_limit_premium : appConfig.stickers_faved_limit_default;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async faveSticker(docId: DocId, unfave?: boolean) {
|
public async faveSticker(docId: DocId, unfave?: boolean) {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ctx from '../../environment/ctx';
|
import ctx from '../../environment/ctx';
|
||||||
|
import callbackify from '../../helpers/callbackify';
|
||||||
import {ignoreRestrictionReasons} from '../../helpers/restrictions';
|
import {ignoreRestrictionReasons} from '../../helpers/restrictions';
|
||||||
import {Config, MethodDeclMap, User} from '../../layer';
|
import {Config, MethodDeclMap, User} from '../../layer';
|
||||||
import {InvokeApiOptions} from '../../types';
|
import {InvokeApiOptions} from '../../types';
|
||||||
|
@ -22,6 +23,8 @@ type HashOptions = {
|
||||||
[queryJSON: string]: HashResult
|
[queryJSON: string]: HashResult
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ApiLimitType = 'pin' | 'folderPin' | 'folders' | 'favedStickers' | 'reactions' | 'bio';
|
||||||
|
|
||||||
export default abstract class ApiManagerMethods extends AppManager {
|
export default abstract class ApiManagerMethods extends AppManager {
|
||||||
private afterMessageIdTemp: number;
|
private afterMessageIdTemp: number;
|
||||||
private hashes: {[method: string]: HashOptions} = {};
|
private hashes: {[method: string]: HashOptions} = {};
|
||||||
|
@ -282,4 +285,22 @@ export default abstract class ApiManagerMethods extends AppManager {
|
||||||
options: {overwrite}
|
options: {overwrite}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getLimit(type: ApiLimitType, isPremium?: boolean) {
|
||||||
|
return callbackify(this.getAppConfig(), (appConfig) => {
|
||||||
|
const map: {[type in ApiLimitType]: [keyof MTAppConfig, keyof MTAppConfig]} = {
|
||||||
|
pin: ['dialogs_pinned_limit_default', 'dialogs_pinned_limit_premium'],
|
||||||
|
folderPin: ['dialogs_folder_pinned_limit_default', 'dialogs_folder_pinned_limit_premium'],
|
||||||
|
folders: ['dialog_filters_limit_default', 'dialog_filters_limit_premium'],
|
||||||
|
favedStickers: ['stickers_faved_limit_default', 'stickers_faved_limit_premium'],
|
||||||
|
reactions: ['reactions_user_max_default', 'reactions_user_max_premium'],
|
||||||
|
bio: ['about_length_limit_default', 'about_length_limit_premium']
|
||||||
|
};
|
||||||
|
|
||||||
|
isPremium ??= this.rootScope.premium;
|
||||||
|
|
||||||
|
const key = map[type][isPremium ? 1 : 0];
|
||||||
|
return appConfig[key] as number;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
1
src/lib/mtproto/appConfig.d.ts
vendored
1
src/lib/mtproto/appConfig.d.ts
vendored
|
@ -57,6 +57,7 @@ export interface MTAppConfig {
|
||||||
message_animated_emoji_max?: number;
|
message_animated_emoji_max?: number;
|
||||||
premium_promo_order?: string[];
|
premium_promo_order?: string[];
|
||||||
premium_bot_username?: string;
|
premium_bot_username?: string;
|
||||||
|
premium_purchase_blocked?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EmojiesSendDiceSuccess {
|
export interface EmojiesSendDiceSuccess {
|
||||||
|
|
|
@ -34,10 +34,10 @@ export class RLottieItem {
|
||||||
constructor(
|
constructor(
|
||||||
private reqId: number,
|
private reqId: number,
|
||||||
private width: number,
|
private width: number,
|
||||||
private height: number/* ,
|
private height: number,
|
||||||
|
private raw?: boolean/* ,
|
||||||
private canvas: OffscreenCanvas */
|
private canvas: OffscreenCanvas */
|
||||||
) {
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(json: string, fps: number) {
|
public init(json: string, fps: number) {
|
||||||
|
@ -67,7 +67,7 @@ export class RLottieItem {
|
||||||
|
|
||||||
reply(['loaded', this.reqId, this.frameCount, this.fps]);
|
reply(['loaded', this.reqId, this.frameCount, this.fps]);
|
||||||
|
|
||||||
if(IS_IMAGE_BITMAP_SUPPORTED) {
|
if(!this.raw && IS_IMAGE_BITMAP_SUPPORTED) {
|
||||||
this.imageData = new ImageData(this.width, this.height);
|
this.imageData = new ImageData(this.width, this.height);
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
@ -105,7 +105,7 @@ export class RLottieItem {
|
||||||
|
|
||||||
// this.context.putImageData(new ImageData(clamped, this.width, this.height), 0, 0);
|
// this.context.putImageData(new ImageData(clamped, this.width, this.height), 0, 0);
|
||||||
|
|
||||||
reply(['frame', this.reqId, frameNo, clamped], [clamped]);
|
reply(['frame', this.reqId, frameNo, clamped], [clamped.buffer]);
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.error('Render error:', e);
|
console.error('Render error:', e);
|
||||||
|
@ -158,8 +158,8 @@ _Module.onRuntimeInitialized = function() {
|
||||||
|
|
||||||
const items: {[reqId: string]: RLottieItem} = {};
|
const items: {[reqId: string]: RLottieItem} = {};
|
||||||
const queryableFunctions = {
|
const queryableFunctions = {
|
||||||
loadFromData: function(reqId: number, blob: Blob, width: number, height: number, toneIndex: number/* , canvas: OffscreenCanvas */) {
|
loadFromData: function(reqId: number, blob: Blob, width: number, height: number, toneIndex: number, raw: boolean/* , canvas: OffscreenCanvas */) {
|
||||||
const item = items[reqId] = new RLottieItem(reqId, width, height/* , canvas */);
|
const item = items[reqId] = new RLottieItem(reqId, width, height, raw/* , canvas */);
|
||||||
readBlobAsText(blob).then((json) => {
|
readBlobAsText(blob).then((json) => {
|
||||||
try {
|
try {
|
||||||
if(typeof(toneIndex) === 'number' && toneIndex >= 1 && toneIndex <= 5) {
|
if(typeof(toneIndex) === 'number' && toneIndex >= 1 && toneIndex <= 5) {
|
||||||
|
|
|
@ -120,6 +120,8 @@ export default class RLottiePlayer extends EventListenerBase<{
|
||||||
public overrideRender: (frame: ImageData | HTMLCanvasElement | ImageBitmap) => void;
|
public overrideRender: (frame: ImageData | HTMLCanvasElement | ImageBitmap) => void;
|
||||||
private renderedFirstFrame: boolean;
|
private renderedFirstFrame: boolean;
|
||||||
|
|
||||||
|
private raw: boolean;
|
||||||
|
|
||||||
constructor({el, worker, options}: {
|
constructor({el, worker, options}: {
|
||||||
el: RLottiePlayer['el'],
|
el: RLottiePlayer['el'],
|
||||||
worker: QueryableWorker,
|
worker: QueryableWorker,
|
||||||
|
@ -148,6 +150,7 @@ export default class RLottiePlayer extends EventListenerBase<{
|
||||||
this.name = options.name;
|
this.name = options.name;
|
||||||
this.skipFirstFrameRendering = options.skipFirstFrameRendering;
|
this.skipFirstFrameRendering = options.skipFirstFrameRendering;
|
||||||
this.toneIndex = options.toneIndex;
|
this.toneIndex = options.toneIndex;
|
||||||
|
this.raw = this.color !== undefined;
|
||||||
|
|
||||||
if(this.name) {
|
if(this.name) {
|
||||||
this.cacheName = RLottiePlayer.CACHE.generateName(this.name, this.width, this.height, this.color, this.toneIndex);
|
this.cacheName = RLottiePlayer.CACHE.generateName(this.name, this.width, this.height, this.color, this.toneIndex);
|
||||||
|
@ -203,7 +206,7 @@ export default class RLottiePlayer extends EventListenerBase<{
|
||||||
|
|
||||||
this.contexts = this.canvas.map((canvas) => canvas.getContext('2d'));
|
this.contexts = this.canvas.map((canvas) => canvas.getContext('2d'));
|
||||||
|
|
||||||
if(!IS_IMAGE_BITMAP_SUPPORTED) {
|
if(!IS_IMAGE_BITMAP_SUPPORTED || this.raw) {
|
||||||
this.imageData = new ImageData(this.width, this.height);
|
this.imageData = new ImageData(this.width, this.height);
|
||||||
|
|
||||||
if(CAN_USE_TRANSFERABLES) {
|
if(CAN_USE_TRANSFERABLES) {
|
||||||
|
@ -230,12 +233,12 @@ export default class RLottiePlayer extends EventListenerBase<{
|
||||||
this.cache.clearCache();
|
this.cache.clearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendQuery(args: any[]) {
|
public sendQuery(args: any[], transfer?: Transferable[]) {
|
||||||
this.worker.sendQuery([args.shift(), this.reqId, ...args]);
|
this.worker.sendQuery([args.shift(), this.reqId, ...args], transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public loadFromData(data: RLottieOptions['animationData']) {
|
public loadFromData(data: RLottieOptions['animationData']) {
|
||||||
this.sendQuery(['loadFromData', data, this.width, this.height, this.toneIndex/* , this.canvas.transferControlToOffscreen() */]);
|
this.sendQuery(['loadFromData', data, this.width, this.height, this.toneIndex, this.color !== undefined/* , this.canvas.transferControlToOffscreen() */]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public play() {
|
public play() {
|
||||||
|
@ -442,7 +445,7 @@ export default class RLottiePlayer extends EventListenerBase<{
|
||||||
this.clamped = new Uint8ClampedArray(this.width * this.height * 4);
|
this.clamped = new Uint8ClampedArray(this.width * this.height * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sendQuery(['renderFrame', frameNo, this.clamped]);
|
this.sendQuery(['renderFrame', frameNo], this.clamped ? [this.clamped.buffer] : undefined);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -545,13 +545,8 @@ export default class FiltersStorage extends AppManager {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isPremium = this.rootScope.premium;
|
const limit = await this.apiManager.getLimit('folders');
|
||||||
let isFolderAvailable = isPremium;
|
const isFolderAvailable = this.filtersArr.filter((filter) => !REAL_FOLDERS.has(filter.id)).slice(0, limit).some((filter) => filter.id === filterId);
|
||||||
if(!isPremium) {
|
|
||||||
const config = await this.apiManager.getAppConfig();
|
|
||||||
const limit = config.dialog_filters_limit_default;
|
|
||||||
isFolderAvailable = this.filtersArr.filter((filter) => !REAL_FOLDERS.has(filter.id)).slice(0, limit).some((filter) => filter.id === filterId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return isFolderAvailable;
|
return isFolderAvailable;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,10 @@
|
||||||
|
|
||||||
@use "sass:math";
|
@use "sass:math";
|
||||||
|
|
||||||
$bubble-margin: .25rem;
|
$bubble-margin: .125rem;
|
||||||
|
$bubble-margin-big: .5rem;
|
||||||
|
$bubble-overflow: math.div($bubble-margin-big, 8);
|
||||||
|
$bubble-overflow-big: math.div($bubble-margin-big, 2);
|
||||||
$bubble-beside-button-width: 38px;
|
$bubble-beside-button-width: 38px;
|
||||||
|
|
||||||
@keyframes bubbleSelected {
|
@keyframes bubbleSelected {
|
||||||
|
@ -36,7 +39,7 @@ $bubble-beside-button-width: 38px;
|
||||||
e.g. make the height bigger and adjust the top so observeHeaders()'s
|
e.g. make the height bigger and adjust the top so observeHeaders()'s
|
||||||
IntersectionObserver fires as soon as the bottom of the sentinel crosses the
|
IntersectionObserver fires as soon as the bottom of the sentinel crosses the
|
||||||
top of the intersection container. */
|
top of the intersection container. */
|
||||||
height: $bubble-margin;
|
height: $bubble-overflow-big;
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,8 +139,8 @@ $bubble-beside-button-width: 38px;
|
||||||
left: -50%;
|
left: -50%;
|
||||||
/* top: 0;
|
/* top: 0;
|
||||||
bottom: 0; */
|
bottom: 0; */
|
||||||
top: -#{math.div($bubble-margin, 2)};
|
top: -#{$bubble-overflow};
|
||||||
bottom: -#{math.div($bubble-margin, 2)};
|
bottom: -#{$bubble-overflow};
|
||||||
content: " ";
|
content: " ";
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
}
|
}
|
||||||
|
@ -145,13 +148,13 @@ $bubble-beside-button-width: 38px;
|
||||||
|
|
||||||
/* &.is-highlighted, &.is-selected {
|
/* &.is-highlighted, &.is-selected {
|
||||||
&:not(.is-group-last):after {
|
&:not(.is-group-last):after {
|
||||||
height: calc(100% + #{math.div($bubble-margin, 2)}) !important;
|
height: calc(100% + #{$bubble-overflow}) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
& + &:not(.is-group-last) {
|
& + &:not(.is-group-last) {
|
||||||
&:after {
|
&:after {
|
||||||
top: .125rem !important;
|
top: .125rem !important;
|
||||||
height: calc(100% - #{math.div($bubble-margin, 2)}) !important;
|
height: calc(100% - #{$bubble-overflow}) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} */
|
} */
|
||||||
|
@ -159,7 +162,7 @@ $bubble-beside-button-width: 38px;
|
||||||
// ! if turn this on, there will be an empty space
|
// ! if turn this on, there will be an empty space
|
||||||
/* &.is-highlighted, &.is-selected {
|
/* &.is-highlighted, &.is-selected {
|
||||||
&.is-group-last:after {
|
&.is-group-last:after {
|
||||||
bottom: #{math.div($bubble-margin, 2)} !important;
|
bottom: #{$bubble-overflow} !important;
|
||||||
}
|
}
|
||||||
} */
|
} */
|
||||||
|
|
||||||
|
@ -180,7 +183,7 @@ $bubble-beside-button-width: 38px;
|
||||||
&:before {
|
&:before {
|
||||||
content: "Unread messages";
|
content: "Unread messages";
|
||||||
height: 30px;
|
height: 30px;
|
||||||
margin-bottom: $bubble-margin;
|
margin-bottom: $bubble-overflow-big;
|
||||||
margin-left: -50%;
|
margin-left: -50%;
|
||||||
margin-right: -50%;
|
margin-right: -50%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -193,9 +196,10 @@ $bubble-beside-button-width: 38px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-highlighted, &.is-selected {
|
&.is-highlighted,
|
||||||
|
&.is-selected {
|
||||||
&:after {
|
&:after {
|
||||||
top: calc(#{math.div($bubble-margin, 2)} + 30px);
|
top: calc(#{$bubble-overflow} + 30px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -391,8 +395,8 @@ $bubble-beside-button-width: 38px;
|
||||||
|
|
||||||
&.is-date {
|
&.is-date {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: $bubble-margin;
|
top: $bubble-overflow-big;
|
||||||
padding-bottom: $bubble-margin;
|
padding-bottom: #{$bubble-overflow-big + $bubble-margin};
|
||||||
//z-index: 3;
|
//z-index: 3;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
transition: opacity .3s ease;
|
transition: opacity .3s ease;
|
||||||
|
@ -500,10 +504,10 @@ $bubble-beside-button-width: 38px;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
&.is-group-last {
|
&.is-group-last {
|
||||||
margin-bottom: #{$bubble-margin * 2};
|
margin-bottom: #{$bubble-margin-big};
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
bottom: -#{$bubble-margin};
|
bottom: -#{$bubble-overflow-big};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* > .bubble-select-checkbox {
|
/* > .bubble-select-checkbox {
|
||||||
|
@ -519,7 +523,7 @@ $bubble-beside-button-width: 38px;
|
||||||
|
|
||||||
&.is-group-first {
|
&.is-group-first {
|
||||||
&:after {
|
&:after {
|
||||||
top: -#{$bubble-margin};
|
top: -#{$bubble-overflow-big};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1618,7 +1622,7 @@ $bubble-beside-button-width: 38px;
|
||||||
|
|
||||||
&:first-of-type {
|
&:first-of-type {
|
||||||
.document-selection {
|
.document-selection {
|
||||||
top: -#{math.div($bubble-margin, 2)}; // * padding inner + half padding outer
|
top: -#{$bubble-overflow}; // * padding inner + half padding outer
|
||||||
}
|
}
|
||||||
|
|
||||||
.document-wrapper {
|
.document-wrapper {
|
||||||
|
@ -1630,7 +1634,7 @@ $bubble-beside-button-width: 38px;
|
||||||
|
|
||||||
&:last-of-type {
|
&:last-of-type {
|
||||||
.document-selection {
|
.document-selection {
|
||||||
bottom: -#{math.div($bubble-margin, 2)};
|
bottom: -#{$bubble-overflow};
|
||||||
}
|
}
|
||||||
|
|
||||||
.document-wrapper {
|
.document-wrapper {
|
||||||
|
@ -1644,7 +1648,7 @@ $bubble-beside-button-width: 38px;
|
||||||
&.is-group-first .document-container {
|
&.is-group-first .document-container {
|
||||||
&:first-of-type {
|
&:first-of-type {
|
||||||
.document-selection {
|
.document-selection {
|
||||||
top: -$bubble-margin;
|
top: -$bubble-overflow-big;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1652,7 +1656,7 @@ $bubble-beside-button-width: 38px;
|
||||||
&.is-group-last .document-container {
|
&.is-group-last .document-container {
|
||||||
&:last-of-type {
|
&:last-of-type {
|
||||||
.document-selection {
|
.document-selection {
|
||||||
bottom: -$bubble-margin;
|
bottom: -$bubble-overflow-big;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
70
src/scss/partials/popups/_limit.scss
Normal file
70
src/scss/partials/popups/_limit.scss
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* https://github.com/morethanwords/tweb
|
||||||
|
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
||||||
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
.popup-limit {
|
||||||
|
.popup-container {
|
||||||
|
min-width: 22.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-line {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin: .75rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-hint {
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: var(--font-weight-bold);
|
||||||
|
|
||||||
|
&-icon {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
margin-right: .25rem;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.limit-line {
|
||||||
|
align-self: stretch;
|
||||||
|
margin: 1rem .5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.is-locked) &-hint {
|
||||||
|
height: 2rem;
|
||||||
|
border-radius: 1rem;
|
||||||
|
padding: 0 .75rem;
|
||||||
|
position: relative;
|
||||||
|
background: linear-gradient(73.4deg, #6C93FF -7.21%, #976FFF 114.57%, #DF69D1 241.52%);
|
||||||
|
background-size: 200px 2rem;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
display: block;
|
||||||
|
content: " ";
|
||||||
|
width: 100%; // 26
|
||||||
|
height: 9px;
|
||||||
|
position: absolute;
|
||||||
|
bottom: -9px;
|
||||||
|
clip-path: path("M0 0H26H24.4853C22.894 0 21.3679 0.632141 20.2426 1.75736L14.4142 7.58579C13.6332 8.36684 12.3668 8.36683 11.5858 7.58579L5.75736 1.75736C4.63214 0.632139 3.10602 0 1.51472 0H0Z");
|
||||||
|
background: inherit;
|
||||||
|
background-size: inherit;
|
||||||
|
background-position-x: calc(-50% + -86px);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-locked &-hint {
|
||||||
|
height: 2.75rem;
|
||||||
|
border-radius: 1.375rem;
|
||||||
|
padding: 0 1.25rem 0 1rem;
|
||||||
|
margin-right: -.25rem;
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
|
@ -390,6 +390,7 @@ $chat-input-inner-padding-handhelds: .25rem;
|
||||||
@import "partials/popups/paymentShippingMethods";
|
@import "partials/popups/paymentShippingMethods";
|
||||||
@import "partials/popups/paymentVerification";
|
@import "partials/popups/paymentVerification";
|
||||||
@import "partials/popups/paymentCardConfirmation";
|
@import "partials/popups/paymentCardConfirmation";
|
||||||
|
@import "partials/popups/limit";
|
||||||
|
|
||||||
@import "partials/pages/pages";
|
@import "partials/pages/pages";
|
||||||
@import "partials/pages/authCode";
|
@import "partials/pages/authCode";
|
||||||
|
@ -1717,6 +1718,43 @@ hr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.limit-line {
|
||||||
|
height: 2rem;
|
||||||
|
// border-radius: $border-radius-medium;
|
||||||
|
font-weight: var(--font-weight-bold);
|
||||||
|
display: flex;
|
||||||
|
// background: linear-gradient(84.4deg, #6C93FF -4.85%, #976FFF 51.72%, #DF69D1 110.7%), #F1F3F5;
|
||||||
|
|
||||||
|
&-free {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-premium {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-free {
|
||||||
|
border-top-left-radius: $border-radius-medium;
|
||||||
|
border-bottom-left-radius: $border-radius-medium;
|
||||||
|
background-color: #F1F3F5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-premium {
|
||||||
|
border-top-right-radius: $border-radius-medium;
|
||||||
|
border-bottom-right-radius: $border-radius-medium;
|
||||||
|
background: linear-gradient(84.4deg, #6C93FF -4.85%, #976FFF 51.72%, #DF69D1 110.7%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-free,
|
||||||
|
&-premium {
|
||||||
|
flex: 1 1 0;
|
||||||
|
padding: 0 .75rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.movable-element {
|
.movable-element {
|
||||||
--size: .5rem;
|
--size: .5rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user