Show alert when pinning dialog over the limit
This commit is contained in:
parent
fdd4232fcc
commit
9d93fe65a5
@ -26,8 +26,8 @@ import blurActiveElement from "../../helpers/dom/blurActiveElement";
|
|||||||
import { cancelEvent } from "../../helpers/dom/cancelEvent";
|
import { cancelEvent } from "../../helpers/dom/cancelEvent";
|
||||||
import cancelSelection from "../../helpers/dom/cancelSelection";
|
import cancelSelection from "../../helpers/dom/cancelSelection";
|
||||||
import getSelectedText from "../../helpers/dom/getSelectedText";
|
import getSelectedText from "../../helpers/dom/getSelectedText";
|
||||||
|
import rootScope from "../../lib/rootScope";
|
||||||
|
|
||||||
const MAX_SELECTION_LENGTH = 100;
|
|
||||||
//const MIN_CLICK_MOVE = 32; // minimum bubble height
|
//const MIN_CLICK_MOVE = 32; // minimum bubble height
|
||||||
|
|
||||||
export default class ChatSelection {
|
export default class ChatSelection {
|
||||||
@ -473,7 +473,7 @@ export default class ChatSelection {
|
|||||||
if(found) {
|
if(found) {
|
||||||
this.selectedMids.delete(mid);
|
this.selectedMids.delete(mid);
|
||||||
} else {
|
} else {
|
||||||
const diff = MAX_SELECTION_LENGTH - this.selectedMids.size - 1;
|
const diff = rootScope.config.forwarded_count_max - this.selectedMids.size - 1;
|
||||||
if(diff < 0) {
|
if(diff < 0) {
|
||||||
toast(I18n.format('Chat.Selection.LimitToast', true));
|
toast(I18n.format('Chat.Selection.LimitToast', true));
|
||||||
return;
|
return;
|
||||||
|
@ -14,6 +14,10 @@ import PopupDeleteDialog from "./popups/deleteDialog";
|
|||||||
import { i18n } from "../lib/langPack";
|
import { i18n } from "../lib/langPack";
|
||||||
import findUpTag from "../helpers/dom/findUpTag";
|
import findUpTag from "../helpers/dom/findUpTag";
|
||||||
import appNotificationsManager from "../lib/appManagers/appNotificationsManager";
|
import appNotificationsManager from "../lib/appManagers/appNotificationsManager";
|
||||||
|
import PopupPeer from "./popups/peer";
|
||||||
|
import AppChatFoldersTab from "./sidebarLeft/tabs/chatFolders";
|
||||||
|
import appSidebarLeft from "./sidebarLeft";
|
||||||
|
import { toastNew } from "./toast";
|
||||||
|
|
||||||
export default class DialogsContextMenu {
|
export default class DialogsContextMenu {
|
||||||
private element: HTMLElement;
|
private element: HTMLElement;
|
||||||
@ -101,7 +105,27 @@ export default class DialogsContextMenu {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private onPinClick = () => {
|
private onPinClick = () => {
|
||||||
appMessagesManager.toggleDialogPin(this.selectedId, this.filterId);
|
appMessagesManager.toggleDialogPin(this.selectedId, this.filterId).catch(err => {
|
||||||
|
if(err.type === 'PINNED_DIALOGS_TOO_MUCH') {
|
||||||
|
if(this.filterId >= 1) {
|
||||||
|
toastNew({langPackKey: 'PinFolderLimitReached'});
|
||||||
|
} else {
|
||||||
|
new PopupPeer('pinned-dialogs-too-much', {
|
||||||
|
buttons: [{
|
||||||
|
langKey: 'OK',
|
||||||
|
isCancel: true
|
||||||
|
}, {
|
||||||
|
langKey: 'FiltersSetupPinAlert',
|
||||||
|
callback: () => {
|
||||||
|
new AppChatFoldersTab(appSidebarLeft).open();
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
descriptionLangKey: 'PinToTopLimitReached2',
|
||||||
|
descriptionLangArgs: [i18n('Chats', [rootScope.config.pinned_dialogs_count_max])]
|
||||||
|
}).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
private onUnmuteClick = () => {
|
private onUnmuteClick = () => {
|
||||||
|
@ -26,7 +26,7 @@ rootScope.addEventListener('language_change', () => {
|
|||||||
|
|
||||||
function getLang(): Promise<[Config.config, LangPackString[], LangPackDifference.langPackDifference]> {
|
function getLang(): Promise<[Config.config, LangPackString[], LangPackDifference.langPackDifference]> {
|
||||||
if(cachedPromise) return cachedPromise;
|
if(cachedPromise) return cachedPromise;
|
||||||
return cachedPromise = apiManager.invokeApiCacheable('help.getConfig').then(config => {
|
return cachedPromise = apiManager.getConfig().then(config => {
|
||||||
if(config.suggested_lang_code !== I18n.lastRequestedLangCode) {
|
if(config.suggested_lang_code !== I18n.lastRequestedLangCode) {
|
||||||
//I18n.loadLangPack(config.suggested_lang_code);
|
//I18n.loadLangPack(config.suggested_lang_code);
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ import appDownloadManager from "../../lib/appManagers/appDownloadManager";
|
|||||||
import calcImageInBox from "../../helpers/calcImageInBox";
|
import calcImageInBox from "../../helpers/calcImageInBox";
|
||||||
import isSendShortcutPressed from "../../helpers/dom/isSendShortcutPressed";
|
import isSendShortcutPressed from "../../helpers/dom/isSendShortcutPressed";
|
||||||
import placeCaretAtEnd from "../../helpers/dom/placeCaretAtEnd";
|
import placeCaretAtEnd from "../../helpers/dom/placeCaretAtEnd";
|
||||||
|
import rootScope from "../../lib/rootScope";
|
||||||
|
|
||||||
type SendFileParams = Partial<{
|
type SendFileParams = Partial<{
|
||||||
file: File,
|
file: File,
|
||||||
@ -30,8 +31,6 @@ type SendFileParams = Partial<{
|
|||||||
duration: number
|
duration: number
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
const MAX_LENGTH_CAPTION = 1024;
|
|
||||||
|
|
||||||
// TODO: .gif upload as video
|
// TODO: .gif upload as video
|
||||||
|
|
||||||
export default class PopupNewMedia extends PopupElement {
|
export default class PopupNewMedia extends PopupElement {
|
||||||
@ -87,7 +86,7 @@ export default class PopupNewMedia extends PopupElement {
|
|||||||
placeholder: 'PreviewSender.CaptionPlaceholder',
|
placeholder: 'PreviewSender.CaptionPlaceholder',
|
||||||
label: 'Caption',
|
label: 'Caption',
|
||||||
name: 'photo-caption',
|
name: 'photo-caption',
|
||||||
maxLength: MAX_LENGTH_CAPTION,
|
maxLength: rootScope.config.caption_length_max,
|
||||||
showLengthOn: 80
|
showLengthOn: 80
|
||||||
});
|
});
|
||||||
this.input = this.inputField.input;
|
this.input = this.inputField.input;
|
||||||
@ -150,7 +149,7 @@ export default class PopupNewMedia extends PopupElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let caption = this.inputField.value;
|
let caption = this.inputField.value;
|
||||||
if(caption.length > MAX_LENGTH_CAPTION) {
|
if(caption.length > rootScope.config.caption_length_max) {
|
||||||
toast(I18n.format('Error.PreviewSender.CaptionTooLong', true));
|
toast(I18n.format('Error.PreviewSender.CaptionTooLong', true));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ export default class PopupPeer extends PopupElement {
|
|||||||
this.header.prepend(avatarEl);
|
this.header.prepend(avatarEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(options.descriptionLangKey) this.title.append(i18n(options.titleLangKey, options.titleLangArgs));
|
if(options.titleLangKey || !options.title) this.title.append(i18n(options.titleLangKey || 'AppName', options.titleLangArgs));
|
||||||
else this.title.innerText = options.title || '';
|
else this.title.innerText = options.title || '';
|
||||||
|
|
||||||
let p = document.createElement('p');
|
let p = document.createElement('p');
|
||||||
|
@ -518,6 +518,11 @@ const lang = {
|
|||||||
"AddMembersAlertCountText": "Are you sure you want to add %1$s to **%2$s**?",
|
"AddMembersAlertCountText": "Are you sure you want to add %1$s to **%2$s**?",
|
||||||
"AddMembersForwardMessages": "Show the last 100 messages to the new members",
|
"AddMembersForwardMessages": "Show the last 100 messages to the new members",
|
||||||
"AddOneMemberForwardMessages": "Show the last 100 messages to **%1$s**",
|
"AddOneMemberForwardMessages": "Show the last 100 messages to **%1$s**",
|
||||||
|
"PinToTopLimitReached2": "Sorry, you can only pin %1$s to the top in the main list. More chats can be pinned in Chat Folders and your Archive.",
|
||||||
|
"FiltersSetupPinAlert": "Set Up Folders",
|
||||||
|
"AppName": "Telegram",
|
||||||
|
"OK": "OK",
|
||||||
|
"PinFolderLimitReached": "Sorry, you can\'t pin any more chats to the top.",
|
||||||
|
|
||||||
// * macos
|
// * macos
|
||||||
"AccountSettings.Filters": "Chat Folders",
|
"AccountSettings.Filters": "Chat Folders",
|
||||||
|
@ -438,7 +438,7 @@ export class AppMessagesManager {
|
|||||||
options.replyToMsgId = options.threadId;
|
options.replyToMsgId = options.threadId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_LENGTH = 4096;
|
const MAX_LENGTH = rootScope.config.message_length_max;
|
||||||
if(text.length > MAX_LENGTH) {
|
if(text.length > MAX_LENGTH) {
|
||||||
const splitted = splitStringByLength(text, MAX_LENGTH);
|
const splitted = splitStringByLength(text, MAX_LENGTH);
|
||||||
text = splitted[0];
|
text = splitted[0];
|
||||||
@ -2913,6 +2913,11 @@ export class AppMessagesManager {
|
|||||||
public toggleDialogPin(peerId: number, filterId?: number) {
|
public toggleDialogPin(peerId: number, filterId?: number) {
|
||||||
if(filterId > 1) {
|
if(filterId > 1) {
|
||||||
return this.filtersStorage.toggleDialogPin(peerId, filterId);
|
return this.filtersStorage.toggleDialogPin(peerId, filterId);
|
||||||
|
} else {
|
||||||
|
const max = filterId === 1 ? rootScope.config.pinned_infolder_count_max : rootScope.config.pinned_dialogs_count_max;
|
||||||
|
if(this.dialogsStorage.getPinnedOrders(filterId).length >= max) {
|
||||||
|
return Promise.reject({type: 'PINNED_DIALOGS_TOO_MUCH'});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const dialog = this.getDialogOnly(peerId);
|
const dialog = this.getDialogOnly(peerId);
|
||||||
@ -3017,11 +3022,12 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// * second rule for saved messages, because there is no 'out' flag
|
// * second rule for saved messages, because there is no 'out' flag
|
||||||
if(message.pFlags.out || this.getMessagePeer(message) === appUsersManager.getSelf().id) {
|
if(/* message.pFlags.out || */this.getMessagePeer(message) === appUsersManager.getSelf().id) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((message.date < (tsNow(true) - (2 * 86400)) && message.media?._ !== 'messageMediaPoll') || !message.pFlags.out) {
|
if((message.date < (tsNow(true) - rootScope.config.edit_time_limit) &&
|
||||||
|
message.media?._ !== 'messageMediaPoll') || !message.pFlags.out) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
import type { LocalStorageProxyTask, LocalStorageProxyTaskResponse } from '../localStorage';
|
import type { LocalStorageProxyTask, LocalStorageProxyTaskResponse } from '../localStorage';
|
||||||
//import type { LocalStorageProxyDeleteTask, LocalStorageProxySetTask } from '../storage';
|
//import type { LocalStorageProxyDeleteTask, LocalStorageProxySetTask } from '../storage';
|
||||||
import type { Awaited, InvokeApiOptions, WorkerTaskVoidTemplate } from '../../types';
|
import type { Awaited, InvokeApiOptions, WorkerTaskVoidTemplate } from '../../types';
|
||||||
import type { InputFile, MethodDeclMap } from '../../layer';
|
import type { Config, InputFile, MethodDeclMap } from '../../layer';
|
||||||
import MTProtoWorker from 'worker-loader!./mtproto.worker';
|
import MTProtoWorker from 'worker-loader!./mtproto.worker';
|
||||||
//import './mtproto.worker';
|
//import './mtproto.worker';
|
||||||
import { isObject } from '../../helpers/object';
|
import { isObject } from '../../helpers/object';
|
||||||
@ -99,6 +99,8 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
|
|||||||
|
|
||||||
private postMessagesWaiting: any[][] = [];
|
private postMessagesWaiting: any[][] = [];
|
||||||
|
|
||||||
|
private getConfigPromise: Promise<Config.config>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.log('constructor');
|
this.log('constructor');
|
||||||
@ -210,6 +212,10 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
|
|||||||
/// #if !MTPROTO_SW
|
/// #if !MTPROTO_SW
|
||||||
this.registerWorker();
|
this.registerWorker();
|
||||||
/// #endif
|
/// #endif
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.getConfig();
|
||||||
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public isServiceWorkerOnline() {
|
public isServiceWorkerOnline() {
|
||||||
@ -597,6 +603,14 @@ export class ApiManagerProxy extends CryptoWorkerMethods {
|
|||||||
public forceReconnect() {
|
public forceReconnect() {
|
||||||
this.postMessage({type: 'forceReconnect'});
|
this.postMessage({type: 'forceReconnect'});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getConfig() {
|
||||||
|
if(this.getConfigPromise) return this.getConfigPromise;
|
||||||
|
return this.getConfigPromise = this.invokeApi('help.getConfig').then(config => {
|
||||||
|
rootScope.config = config;
|
||||||
|
return config;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiManagerProxy = new ApiManagerProxy();
|
const apiManagerProxy = new ApiManagerProxy();
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Message, StickerSet, Update, NotifyPeer, PeerNotifySettings, ConstructorDeclMap } from "../layer";
|
import type { Message, StickerSet, Update, NotifyPeer, PeerNotifySettings, ConstructorDeclMap, Config } from "../layer";
|
||||||
import type { MyDocument } from "./appManagers/appDocsManager";
|
import type { MyDocument } from "./appManagers/appDocsManager";
|
||||||
import type { AppMessagesManager, Dialog, MessagesStorage } from "./appManagers/appMessagesManager";
|
import type { AppMessagesManager, Dialog, MessagesStorage } from "./appManagers/appMessagesManager";
|
||||||
import type { Poll, PollResults } from "./appManagers/appPollsManager";
|
import type { Poll, PollResults } from "./appManagers/appPollsManager";
|
||||||
@ -144,6 +144,14 @@ export class RootScope extends EventListenerBase<{
|
|||||||
public settings: State['settings'];
|
public settings: State['settings'];
|
||||||
public peerId = 0;
|
public peerId = 0;
|
||||||
public systemTheme: Theme['name'];
|
public systemTheme: Theme['name'];
|
||||||
|
public config: Partial<Config.config> = {
|
||||||
|
forwarded_count_max: 100,
|
||||||
|
edit_time_limit: 86400 * 2,
|
||||||
|
pinned_dialogs_count_max: 5,
|
||||||
|
pinned_infolder_count_max: 100,
|
||||||
|
message_length_max: 4096,
|
||||||
|
caption_length_max: 1024,
|
||||||
|
};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
@ -146,6 +146,10 @@ export default class DialogsStorage {
|
|||||||
this.pinnedOrders[folderId] = [];
|
this.pinnedOrders[folderId] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getPinnedOrders(folderId: number) {
|
||||||
|
return this.pinnedOrders[folderId];
|
||||||
|
}
|
||||||
|
|
||||||
public getOffsetDate(folderId: number) {
|
public getOffsetDate(folderId: number) {
|
||||||
return this.dialogsOffsetDate[folderId] || 0;
|
return this.dialogsOffsetDate[folderId] || 0;
|
||||||
}
|
}
|
||||||
|
@ -182,6 +182,10 @@ export default class FiltersStorage {
|
|||||||
public toggleDialogPin(peerId: number, filterId: number) {
|
public toggleDialogPin(peerId: number, filterId: number) {
|
||||||
const filter = this.filters[filterId];
|
const filter = this.filters[filterId];
|
||||||
|
|
||||||
|
if(filter.pinned_peers.length >= this.rootScope.config.pinned_infolder_count_max) {
|
||||||
|
return Promise.reject({type: 'PINNED_DIALOGS_TOO_MUCH'});
|
||||||
|
}
|
||||||
|
|
||||||
const wasPinned = filter.pinned_peers.findAndSplice(p => p === peerId);
|
const wasPinned = filter.pinned_peers.findAndSplice(p => p === peerId);
|
||||||
if(!wasPinned) {
|
if(!wasPinned) {
|
||||||
filter.pinned_peers.unshift(peerId);
|
filter.pinned_peers.unshift(peerId);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user