diff --git a/src/api/gramjs/apiBuilders/appConfig.ts b/src/api/gramjs/apiBuilders/appConfig.ts index 850d20c4c..4f6933a0b 100644 --- a/src/api/gramjs/apiBuilders/appConfig.ts +++ b/src/api/gramjs/apiBuilders/appConfig.ts @@ -3,20 +3,11 @@ import { Api as GramJs } from '../../../lib/gramjs'; import type { ApiAppConfig, ApiLimitType, ApiPremiumSection } from '../../types'; +import { omitUndefined } from '../../../util/iteratees'; import { + DEFAULT_APP_CONFIG, DEFAULT_LIMITS, - MAX_UNIQUE_REACTIONS, - SERVICE_NOTIFICATIONS_USER_ID, - STORY_EXPIRE_PERIOD, - STORY_VIEWERS_EXPIRE_PERIOD, - TODO_ITEM_LENGTH_LIMIT, - TODO_ITEMS_LIMIT, - TODO_TITLE_LENGTH_LIMIT, - TON_SUGGESTED_POST_AMOUNT_MAX, - TON_SUGGESTED_POST_AMOUNT_MIN, - TON_TOPUP_URL_DEFAULT, - TON_USD_RATE_DEFAULT, -} from '../../../config'; +} from '../../../limits'; import localDb from '../localDb'; import { buildJson } from './misc'; @@ -36,7 +27,8 @@ type Limit = | 'chatlist_invites_limit' | 'chatlist_joined_limit' | 'recommended_channels_limit' - | 'saved_dialogs_pinned_limit'; + | 'saved_dialogs_pinned_limit' + | 'reactions_user_max'; type LimitKey = `${Limit}_${LimitType}`; type LimitsConfig = Record; @@ -57,6 +49,7 @@ export interface GramJsAppConfig extends LimitsConfig { autologin_domains: string[]; autologin_token: string; url_auth_domains: string[]; + whitelisted_domains: string[]; premium_purchase_blocked: boolean; giveaway_gifts_purchase_available: boolean; giveaway_add_peers_max: number; @@ -74,11 +67,9 @@ export interface GramJsAppConfig extends LimitsConfig { // Forums topics_pinned_limit: number; // Stories - stories_all_hidden?: boolean; - story_expire_period: number; story_viewers_expire_period: number; - stories_changelog_user_id?: number; - stories_pinned_to_top_count_max?: number; + stories_changelog_user_id: number; + stories_pinned_to_top_count_max: number; // Boosts group_transcribe_level_min?: number; new_noncontact_peers_require_premium_without_ownpremium?: boolean; @@ -157,14 +148,15 @@ function getLimit(appConfig: GramJsAppConfig, key: Limit, fallbackKey: ApiLimitT export function buildAppConfig(json: GramJs.TypeJSONValue, hash: number): ApiAppConfig { const appConfig = buildJson(json) as GramJsAppConfig; - return { + const config: Partial = { emojiSounds: buildEmojiSounds(appConfig), seenByMaxChatMembers: appConfig.chat_read_mark_size_threshold, seenByExpiresAt: appConfig.chat_read_mark_expire_period, readDateExpiresAt: appConfig.pm_read_date_expire_period, autologinDomains: appConfig.autologin_domains || [], urlAuthDomains: appConfig.url_auth_domains || [], - maxUniqueReactions: appConfig.reactions_uniq_max ?? MAX_UNIQUE_REACTIONS, + whitelistedDomains: appConfig.whitelisted_domains || [], + maxUniqueReactions: appConfig.reactions_uniq_max, premiumBotUsername: appConfig.premium_bot_username, premiumInvoiceSlug: appConfig.premium_invoice_slug, premiumPromoOrder: appConfig.premium_promo_order as ApiPremiumSection[], @@ -172,8 +164,6 @@ export function buildAppConfig(json: GramJs.TypeJSONValue, hash: number): ApiApp isGiveawayGiftsPurchaseAvailable: appConfig.giveaway_gifts_purchase_available, defaultEmojiStatusesStickerSetId: appConfig.default_emoji_statuses_stickerset_id, topicsPinnedLimit: appConfig.topics_pinned_limit, - maxUserReactionsDefault: appConfig.reactions_user_max_default, - maxUserReactionsPremium: appConfig.reactions_user_max_premium, hiddenMembersMinCount: appConfig.hidden_members_group_size_min, giveawayAddPeersMax: appConfig.giveaway_add_peers_max, giveawayBoostsPerPremium: appConfig.giveaway_boosts_per_premium, @@ -195,13 +185,12 @@ export function buildAppConfig(json: GramJs.TypeJSONValue, hash: number): ApiApp chatlistJoined: getLimit(appConfig, 'chatlist_joined_limit', 'chatlistJoined'), recommendedChannels: getLimit(appConfig, 'recommended_channels_limit', 'recommendedChannels'), savedDialogsPinned: getLimit(appConfig, 'saved_dialogs_pinned_limit', 'savedDialogsPinned'), + maxReactions: getLimit(appConfig, 'reactions_user_max', 'maxReactions'), moreAccounts: DEFAULT_LIMITS.moreAccounts, }, hash, - areStoriesHidden: appConfig.stories_all_hidden, - storyExpirePeriod: appConfig.story_expire_period ?? STORY_EXPIRE_PERIOD, - storyViewersExpirePeriod: appConfig.story_viewers_expire_period ?? STORY_VIEWERS_EXPIRE_PERIOD, - storyChangelogUserId: appConfig.stories_changelog_user_id?.toString() ?? SERVICE_NOTIFICATIONS_USER_ID, + storyViewersExpirePeriod: appConfig.story_viewers_expire_period, + storyChangelogUserId: appConfig.stories_changelog_user_id?.toString(), maxPinnedStoriesCount: appConfig.stories_pinned_to_top_count_max, groupTranscribeLevelMin: appConfig.group_transcribe_level_min, canLimitNewMessagesWithoutPremium: appConfig.new_noncontact_peers_require_premium_without_ownpremium, @@ -238,18 +227,23 @@ export function buildAppConfig(json: GramJs.TypeJSONValue, hash: number): ApiApp starsSuggestedPostFutureMax: appConfig.stars_suggested_post_future_max, starsSuggestedPostFutureMin: appConfig.stars_suggested_post_future_min, tonSuggestedPostCommissionPermille: appConfig.ton_suggested_post_commission_permille, - tonSuggestedPostAmountMax: appConfig.ton_suggested_post_amount_max ?? TON_SUGGESTED_POST_AMOUNT_MAX, - tonSuggestedPostAmountMin: appConfig.ton_suggested_post_amount_min ?? TON_SUGGESTED_POST_AMOUNT_MIN, - tonUsdRate: appConfig.ton_usd_rate ?? TON_USD_RATE_DEFAULT, - tonTopupUrl: appConfig.ton_topup_url ?? TON_TOPUP_URL_DEFAULT, + tonSuggestedPostAmountMax: appConfig.ton_suggested_post_amount_max, + tonSuggestedPostAmountMin: appConfig.ton_suggested_post_amount_min, + tonUsdRate: appConfig.ton_usd_rate, + tonTopupUrl: appConfig.ton_topup_url, pollMaxAnswers: appConfig.poll_answers_max, - todoItemsMax: appConfig.todo_items_max ?? TODO_ITEMS_LIMIT, - todoTitleLengthMax: appConfig.todo_title_length_max ?? TODO_TITLE_LENGTH_LIMIT, - todoItemLengthMax: appConfig.todo_item_length_max ?? TODO_ITEM_LENGTH_LIMIT, + todoItemsMax: appConfig.todo_items_max, + todoTitleLengthMax: appConfig.todo_title_length_max, + todoItemLengthMax: appConfig.todo_item_length_max, ignoreRestrictionReasons: appConfig.ignore_restriction_reasons, needAgeVideoVerification: appConfig.need_age_video_verification, verifyAgeBotUsername: appConfig.verify_age_bot_username, verifyAgeCountry: appConfig.verify_age_country, verifyAgeMin: appConfig.verify_age_min, }; + + return { + ...DEFAULT_APP_CONFIG, + ...omitUndefined(config), + }; } diff --git a/src/api/gramjs/methods/calls.ts b/src/api/gramjs/methods/calls.ts index dd6874773..59ad4382a 100644 --- a/src/api/gramjs/methods/calls.ts +++ b/src/api/gramjs/methods/calls.ts @@ -6,7 +6,7 @@ import type { ApiChat, ApiGroupCall, ApiPhoneCall, ApiUser, } from '../../types'; -import { GROUP_CALL_PARTICIPANTS_LIMIT } from '../../../config'; +import { GROUP_CALL_PARTICIPANTS_LIMIT } from '../../../limits'; import { buildApiGroupCall, buildApiGroupCallParticipant, buildCallProtocol, diff --git a/src/api/gramjs/methods/chats.ts b/src/api/gramjs/methods/chats.ts index 1b98753d7..8489c19e9 100644 --- a/src/api/gramjs/methods/chats.ts +++ b/src/api/gramjs/methods/chats.ts @@ -27,13 +27,13 @@ import { ARCHIVED_FOLDER_ID, DEBUG, GENERAL_TOPIC_ID, - GLOBAL_SEARCH_CONTACTS_LIMIT, MAX_INT_32, MEMBERS_LOAD_SLICE, SERVICE_NOTIFICATIONS_USER_ID, TOPICS_SLICE, } from '../../../config'; import { buildCollectionByKey, omitUndefined } from '../../../util/iteratees'; +import { GLOBAL_SEARCH_CONTACTS_LIMIT } from '../../../limits'; import { buildApiChatBotCommands, buildApiChatFolder, diff --git a/src/api/gramjs/methods/messages.ts b/src/api/gramjs/methods/messages.ts index 8974d3d1d..5b2cb43a3 100644 --- a/src/api/gramjs/methods/messages.ts +++ b/src/api/gramjs/methods/messages.ts @@ -38,13 +38,11 @@ import { } from '../../types'; import { - API_GENERAL_ID_LIMIT, DEBUG, GIF_MIME_TYPE, MAX_INT_32, MENTION_UNREAD_SLICE, MESSAGE_ID_REQUIRED_ERROR, - PINNED_MESSAGES_LIMIT, REACTION_UNREAD_SLICE, SUPPORTED_PHOTO_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES, @@ -54,6 +52,7 @@ import { compact, split } from '../../../util/iteratees'; import { getMessageKey } from '../../../util/keys/messageKey'; import { getServerTime } from '../../../util/serverTime'; import { interpolateArray } from '../../../util/waveform'; +import { API_GENERAL_ID_LIMIT, PINNED_MESSAGES_LIMIT } from '../../../limits'; import { buildApiChatFromPreview, buildApiSendAsPeerId, diff --git a/src/api/gramjs/methods/reactions.ts b/src/api/gramjs/methods/reactions.ts index 119a04e3d..e5ae60f41 100644 --- a/src/api/gramjs/methods/reactions.ts +++ b/src/api/gramjs/methods/reactions.ts @@ -5,13 +5,13 @@ import type { ApiChat, ApiReaction, ApiSticker, } from '../../types'; +import { split } from '../../../util/iteratees'; import { API_GENERAL_ID_LIMIT, REACTION_LIST_LIMIT, RECENT_REACTIONS_LIMIT, TOP_REACTIONS_LIMIT, -} from '../../../config'; -import { split } from '../../../util/iteratees'; +} from '../../../limits'; import { buildApiAvailableEffect, buildApiAvailableReaction, diff --git a/src/api/gramjs/methods/settings.ts b/src/api/gramjs/methods/settings.ts index 2d4f9ffe1..ea4c16aca 100644 --- a/src/api/gramjs/methods/settings.ts +++ b/src/api/gramjs/methods/settings.ts @@ -18,11 +18,11 @@ import type { import { ACCEPTABLE_USERNAME_ERRORS, - BLOCKED_LIST_LIMIT, LANG_PACK, MAX_INT_32, } from '../../../config'; import { buildCollectionByKey } from '../../../util/iteratees'; +import { BLOCKED_LIST_LIMIT } from '../../../limits'; import { buildAppConfig } from '../apiBuilders/appConfig'; import { buildApiPhoto, buildPrivacyRules } from '../apiBuilders/common'; import { buildApiDisallowedGiftsSettings } from '../apiBuilders/gifts'; diff --git a/src/api/gramjs/methods/stories.ts b/src/api/gramjs/methods/stories.ts index 775638f3d..b75d649fe 100644 --- a/src/api/gramjs/methods/stories.ts +++ b/src/api/gramjs/methods/stories.ts @@ -10,8 +10,9 @@ import type { ApiTypeStory, } from '../../types'; -import { MESSAGE_ID_REQUIRED_ERROR, STORY_LIST_LIMIT } from '../../../config'; +import { MESSAGE_ID_REQUIRED_ERROR } from '../../../config'; import { buildCollectionByCallback } from '../../../util/iteratees'; +import { STORY_LIST_LIMIT } from '../../../limits'; import { buildApiReportResult } from '../apiBuilders/messages'; import { getApiChatIdFromMtpPeer } from '../apiBuilders/peers'; import { diff --git a/src/api/types/misc.ts b/src/api/types/misc.ts index e8df0dfd7..31221cd60 100644 --- a/src/api/types/misc.ts +++ b/src/api/types/misc.ts @@ -205,6 +205,7 @@ export interface ApiAppConfig { readDateExpiresAt: number; autologinDomains: string[]; urlAuthDomains: string[]; + whitelistedDomains: string[]; premiumInvoiceSlug: string; premiumBotUsername: string; isPremiumPurchaseBlocked: boolean; @@ -217,27 +218,24 @@ export interface ApiAppConfig { defaultEmojiStatusesStickerSetId: string; maxUniqueReactions: number; topicsPinnedLimit: number; - maxUserReactionsDefault: number; - maxUserReactionsPremium: number; hiddenMembersMinCount: number; limits: Record; canDisplayAutoarchiveSetting: boolean; - areStoriesHidden?: boolean; - storyExpirePeriod: number; storyViewersExpirePeriod: number; storyChangelogUserId: string; - maxPinnedStoriesCount?: number; - groupTranscribeLevelMin?: number; - canLimitNewMessagesWithoutPremium?: boolean; + maxPinnedStoriesCount: number; + groupTranscribeLevelMin: number; + canLimitNewMessagesWithoutPremium: boolean; starsPaidMessagesAvailable?: boolean; starsPaidMessageCommissionPermille?: number; starsPaidMessageAmountMax?: number; - starsUsdWithdrawRateX1000?: number; + starsUsdWithdrawRateX1000: number; bandwidthPremiumNotifyPeriod?: number; bandwidthPremiumUploadSpeedup?: number; bandwidthPremiumDownloadSpeedup?: number; channelRestrictAdsLevelMin?: number; channelAutoTranslationLevelMin?: number; + channelLevelMax: number; paidReactionMaxAmount?: number; isChannelRevenueWithdrawalEnabled?: boolean; isStarsGiftEnabled?: boolean; @@ -252,24 +250,24 @@ export interface ApiAppConfig { starsStargiftResaleAmountMin?: number; starsStargiftResaleAmountMax?: number; starsStargiftResaleCommissionPermille?: number; - starsSuggestedPostAmountMax?: number; - starsSuggestedPostAmountMin?: number; - starsSuggestedPostCommissionPermille?: number; - starsSuggestedPostAgeMin?: number; - starsSuggestedPostFutureMax?: number; - starsSuggestedPostFutureMin?: number; - tonSuggestedPostCommissionPermille?: number; - tonSuggestedPostAmountMax?: number; - tonSuggestedPostAmountMin?: number; + starsSuggestedPostAmountMax: number; + starsSuggestedPostAmountMin: number; + starsSuggestedPostCommissionPermille: number; + starsSuggestedPostAgeMin: number; + starsSuggestedPostFutureMax: number; + starsSuggestedPostFutureMin: number; + tonSuggestedPostCommissionPermille: number; + tonSuggestedPostAmountMax: number; + tonSuggestedPostAmountMin: number; tonStargiftResaleAmountMax?: number; tonStargiftResaleAmountMin?: number; tonStargiftResaleCommissionPermille?: number; tonUsdRate?: number; - tonTopupUrl?: string; + tonTopupUrl: string; pollMaxAnswers?: number; - todoItemsMax?: number; - todoTitleLengthMax?: number; - todoItemLengthMax?: number; + todoItemsMax: number; + todoTitleLengthMax: number; + todoItemLengthMax: number; ignoreRestrictionReasons?: string[]; needAgeVideoVerification?: boolean; verifyAgeBotUsername?: string; @@ -375,14 +373,16 @@ export type ApiLimitType = | 'chatlistJoined' | 'recommendedChannels' | 'savedDialogsPinned' + | 'maxReactions' | 'moreAccounts'; export type ApiLimitTypeWithModal = Exclude; export type ApiLimitTypeForPromo = Exclude; export type ApiPeerNotifySettings = { diff --git a/src/components/common/Composer.tsx b/src/components/common/Composer.tsx index fca274611..c28804a41 100644 --- a/src/components/common/Composer.tsx +++ b/src/components/common/Composer.tsx @@ -47,7 +47,6 @@ import { MAIN_THREAD_ID } from '../../api/types'; import { BASE_EMOJI_KEYWORD_LANG, - DEFAULT_MAX_MESSAGE_LENGTH, EDITABLE_INPUT_MODAL_ID, HEART_REACTION, MAX_UPLOAD_FILEPART_SIZE, @@ -126,6 +125,7 @@ import parseHtmlAsFormattedText from '../../util/parseHtmlAsFormattedText'; import { insertHtmlInSelection } from '../../util/selection'; import { getServerTime } from '../../util/serverTime'; import windowSize from '../../util/windowSize'; +import { DEFAULT_MAX_MESSAGE_LENGTH } from '../../limits'; import applyIosAutoCapitalizationFix from '../middle/composer/helpers/applyIosAutoCapitalizationFix'; import buildAttachment, { prepareAttachmentsToSend } from '../middle/composer/helpers/buildAttachment'; import { buildCustomEmojiHtml } from '../middle/composer/helpers/customEmoji'; @@ -2622,7 +2622,7 @@ export default memo(withGlobal( isAccountFrozen, isAppConfigLoaded, insertingPeerIdMention, - pollMaxAnswers: appConfig?.pollMaxAnswers, + pollMaxAnswers: appConfig.pollMaxAnswers, }; }, )(Composer)); diff --git a/src/components/common/SensitiveContentConfirmModal.tsx b/src/components/common/SensitiveContentConfirmModal.tsx index becca1541..de663e02f 100644 --- a/src/components/common/SensitiveContentConfirmModal.tsx +++ b/src/components/common/SensitiveContentConfirmModal.tsx @@ -53,7 +53,7 @@ const SensitiveContentConfirmModal = ({ export default memo(withGlobal((global): StateProps => { const appConfig = global.appConfig; - const verifyAgeMin = appConfig?.verifyAgeMin; + const verifyAgeMin = appConfig.verifyAgeMin; return { verifyAgeMin: verifyAgeMin || VERIFY_AGE_MIN_DEFAULT, diff --git a/src/components/common/paidMessage/PaidMessagePrice.tsx b/src/components/common/paidMessage/PaidMessagePrice.tsx index ebdeeb707..2ee32157e 100644 --- a/src/components/common/paidMessage/PaidMessagePrice.tsx +++ b/src/components/common/paidMessage/PaidMessagePrice.tsx @@ -100,16 +100,16 @@ function PaidMessagePrice({ export default memo(withGlobal( (global): StateProps => { - const starsUsdWithdrawRateX1000 = global.appConfig?.starsUsdWithdrawRateX1000; + const starsUsdWithdrawRateX1000 = global.appConfig.starsUsdWithdrawRateX1000; const starsUsdWithdrawRate = starsUsdWithdrawRateX1000 ? starsUsdWithdrawRateX1000 / 1000 : 1; - const configStarsPaidMessageCommissionPermille = global.appConfig?.starsPaidMessageCommissionPermille; + const configStarsPaidMessageCommissionPermille = global.appConfig.starsPaidMessageCommissionPermille; const starsPaidMessageCommissionPermille = configStarsPaidMessageCommissionPermille ? configStarsPaidMessageCommissionPermille / 1000 : 100; return { starsPaidMessageCommissionPermille, starsUsdWithdrawRate, - starsPaidMessageAmountMax: global.appConfig?.starsPaidMessageAmountMax || DEFAULT_MAXIMUM_CHARGE_FOR_MESSAGES, + starsPaidMessageAmountMax: global.appConfig.starsPaidMessageAmountMax || DEFAULT_MAXIMUM_CHARGE_FOR_MESSAGES, }; }, )(PaidMessagePrice)); diff --git a/src/components/left/main/Chat.scss b/src/components/left/main/Chat.scss index cf70f91e0..d612a249f 100644 --- a/src/components/left/main/Chat.scss +++ b/src/components/left/main/Chat.scss @@ -252,10 +252,12 @@ overflow: hidden; display: flex; &-summary { - text-overflow: ellipsis; overflow: hidden; flex: unset; + max-width: none; + + text-overflow: ellipsis; white-space: nowrap; } .draft { @@ -280,6 +282,8 @@ } .media-preview--image { + flex-shrink: 0; + width: 1.25rem; height: 1.25rem; margin-inline-start: 0.125rem; @@ -289,7 +293,6 @@ vertical-align: -0.25rem; object-fit: cover; - flex-shrink: 0; body.is-ios & { width: 1.125rem; diff --git a/src/components/left/settings/PrivacyMessages.tsx b/src/components/left/settings/PrivacyMessages.tsx index de26eb398..37de4a3f7 100644 --- a/src/components/left/settings/PrivacyMessages.tsx +++ b/src/components/left/settings/PrivacyMessages.tsx @@ -241,8 +241,8 @@ export default memo(withGlobal((global): StateProps => { shouldChargeForMessages: Boolean(nonContactPeersPaidStars), nonContactPeersPaidStars: nonContactPeersPaidStars || DEFAULT_CHARGE_FOR_MESSAGES, isCurrentUserPremium: selectIsCurrentUserPremium(global), - canLimitNewMessagesWithoutPremium: global.appConfig?.canLimitNewMessagesWithoutPremium, - canChargeForMessages: global.appConfig?.starsPaidMessagesAvailable, + canLimitNewMessagesWithoutPremium: global.appConfig.canLimitNewMessagesWithoutPremium, + canChargeForMessages: global.appConfig.starsPaidMessagesAvailable, noPaidReactionsForUsersCount, privacy, }; diff --git a/src/components/left/settings/SettingsPrivacy.tsx b/src/components/left/settings/SettingsPrivacy.tsx index dbb876d12..baef9f467 100644 --- a/src/components/left/settings/SettingsPrivacy.tsx +++ b/src/components/left/settings/SettingsPrivacy.tsx @@ -490,12 +490,12 @@ export default memo(withGlobal( blockedCount: blocked.totalCount, webAuthCount: global.activeWebSessions.orderedHashes.length, isSensitiveEnabled, - canDisplayAutoarchiveSetting: Boolean(appConfig?.canDisplayAutoarchiveSetting), + canDisplayAutoarchiveSetting: Boolean(appConfig.canDisplayAutoarchiveSetting), shouldArchiveAndMuteNewNonContact, canChangeSensitive, shouldNewNonContactPeersRequirePremium, shouldChargeForMessages, - needAgeVideoVerification: Boolean(appConfig?.needAgeVideoVerification), + needAgeVideoVerification: Boolean(appConfig.needAgeVideoVerification), privacy, canDisplayChatInTitle, canSetPasscode: selectCanSetPasscode(global), diff --git a/src/components/main/premium/GiveawayModal.tsx b/src/components/main/premium/GiveawayModal.tsx index 86c80d177..7ca023769 100644 --- a/src/components/main/premium/GiveawayModal.tsx +++ b/src/components/main/premium/GiveawayModal.tsx @@ -919,10 +919,10 @@ export default memo(withGlobal((global): StateProps => { gifts: giveawayModal?.gifts, selectedMemberList: giveawayModal?.selectedMemberIds, selectedChannelList: giveawayModal?.selectedChannelIds, - giveawayBoostPerPremiumLimit: global.appConfig?.giveawayBoostsPerPremium, - isStarsGiftEnabled: global.appConfig?.isStarsGiftEnabled, - userSelectionLimit: global.appConfig?.giveawayAddPeersMax, - countrySelectionLimit: global.appConfig?.giveawayCountriesMax, + giveawayBoostPerPremiumLimit: global.appConfig.giveawayBoostsPerPremium, + isStarsGiftEnabled: global.appConfig.isStarsGiftEnabled, + userSelectionLimit: global.appConfig.giveawayAddPeersMax, + countrySelectionLimit: global.appConfig.giveawayCountriesMax, countryList: global.countryList.general, prepaidGiveaway: giveawayModal?.prepaidGiveaway, isChannel, diff --git a/src/components/main/premium/PremiumMainModal.tsx b/src/components/main/premium/PremiumMainModal.tsx index 081a8af06..771a2af08 100644 --- a/src/components/main/premium/PremiumMainModal.tsx +++ b/src/components/main/premium/PremiumMainModal.tsx @@ -530,9 +530,9 @@ export default memo(withGlobal((global): StateProps => { limitFolders: selectPremiumLimit(global, 'dialogFilters'), limitPins: selectPremiumLimit(global, 'dialogFolderPinned'), limitLinks: selectPremiumLimit(global, 'channelsPublic'), - limits: global.appConfig?.limits, - premiumSlug: global.appConfig?.premiumInvoiceSlug, - premiumBotUsername: global.appConfig?.premiumBotUsername, - premiumPromoOrder: global.appConfig?.premiumPromoOrder, + limits: global.appConfig.limits, + premiumSlug: global.appConfig.premiumInvoiceSlug, + premiumBotUsername: global.appConfig.premiumBotUsername, + premiumPromoOrder: global.appConfig.premiumPromoOrder, }; })(PremiumMainModal)); diff --git a/src/components/main/premium/common/PremiumLimitReachedModal.tsx b/src/components/main/premium/common/PremiumLimitReachedModal.tsx index 5ba289f13..0b8e19b2b 100644 --- a/src/components/main/premium/common/PremiumLimitReachedModal.tsx +++ b/src/components/main/premium/common/PremiumLimitReachedModal.tsx @@ -219,7 +219,7 @@ const PremiumLimitReachedModal: FC = ({ export default memo(withGlobal( (global, { limit }): StateProps => { - const { limits } = global.appConfig || {}; + const { limits } = global.appConfig; const isPremium = selectIsCurrentUserPremium(global); return { diff --git a/src/components/middle/composer/ToDoListModal.tsx b/src/components/middle/composer/ToDoListModal.tsx index 5c6513271..0455575c9 100644 --- a/src/components/middle/composer/ToDoListModal.tsx +++ b/src/components/middle/composer/ToDoListModal.tsx @@ -9,11 +9,6 @@ import type { ApiNewMediaTodo } from '../../../api/types'; import type { ApiMessage } from '../../../api/types'; import type { TabState } from '../../../global/types/tabState'; -import { - TODO_ITEM_LENGTH_LIMIT, - TODO_ITEMS_LIMIT, - TODO_TITLE_LENGTH_LIMIT, -} from '../../../config'; import { requestMeasure, requestNextMutation } from '../../../lib/fasterdom/fasterdom'; import { selectChatMessage } from '../../../global/selectors'; import captureEscKeyListener from '../../../util/captureEscKeyListener'; @@ -40,9 +35,9 @@ export type OwnProps = { export type StateProps = { editingMessage?: ApiMessage; - maxItemsCount?: number; - maxTitleLength?: number; - maxItemLength?: number; + maxItemsCount: number; + maxTitleLength: number; + maxItemLength: number; }; type Item = { @@ -56,9 +51,9 @@ const MAX_OPTION_LENGTH = 100; const ToDoListModal = ({ modal, - maxItemsCount = TODO_ITEMS_LIMIT, - maxTitleLength = TODO_TITLE_LENGTH_LIMIT, - maxItemLength = TODO_ITEM_LENGTH_LIMIT, + maxItemsCount, + maxTitleLength, + maxItemLength, editingMessage, onSend, onClear, @@ -407,9 +402,9 @@ export default memo(withGlobal( const editingMessage = modal?.messageId ? selectChatMessage(global, modal.chatId, modal.messageId) : undefined; return { editingMessage, - maxItemsCount: appConfig?.todoItemsMax, - maxTitleLength: appConfig?.todoTitleLengthMax, - maxItemLength: appConfig?.todoItemLengthMax, + maxItemsCount: appConfig.todoItemsMax, + maxTitleLength: appConfig.todoTitleLengthMax, + maxItemLength: appConfig.todoItemLengthMax, }; }, )(ToDoListModal)); diff --git a/src/components/middle/message/ContextMenuContainer.tsx b/src/components/middle/message/ContextMenuContainer.tsx index ded21ea60..e86c4b3f3 100644 --- a/src/components/middle/message/ContextMenuContainer.tsx +++ b/src/components/middle/message/ContextMenuContainer.tsx @@ -26,9 +26,6 @@ import type { } from '../../../types'; import { MAIN_THREAD_ID } from '../../../api/types'; -import { - TODO_ITEMS_LIMIT, -} from '../../../config'; import { PREVIEW_AVATAR_COUNT, SERVICE_NOTIFICATIONS_USER_ID } from '../../../config'; import { areReactionsEmpty, @@ -802,7 +799,7 @@ export default memo(withGlobal( const { seenByExpiresAt, seenByMaxChatMembers, maxUniqueReactions, readDateExpiresAt, - } = global.appConfig || {}; + } = global.appConfig; const reactionsLimit = chatFullInfo?.reactionsLimit || maxUniqueReactions; @@ -899,7 +896,7 @@ export default memo(withGlobal( const canGift = selectCanGift(global, message.chatId); const savedDialogId = selectSavedDialogIdFromMessage(global, message); - const todoItemsMax = global.appConfig?.todoItemsMax || TODO_ITEMS_LIMIT; + const todoItemsMax = global.appConfig.todoItemsMax; const canAppendTodoList = message.content.todo?.todo.othersCanAppend && message.content.todo?.todo.items?.length < todoItemsMax; diff --git a/src/components/middle/message/Message.tsx b/src/components/middle/message/Message.tsx index 1861ec5f4..cd4411291 100644 --- a/src/components/middle/message/Message.tsx +++ b/src/components/middle/message/Message.tsx @@ -46,7 +46,7 @@ import type { OnIntersectPinnedMessage } from '../hooks/usePinnedMessage'; import { MAIN_THREAD_ID } from '../../../api/types'; import { AudioOrigin } from '../../../types'; -import { EMOJI_STATUS_LOOP_LIMIT, MESSAGE_APPEARANCE_DELAY, STARS_SUGGESTED_POST_FUTURE_MIN } from '../../../config'; +import { EMOJI_STATUS_LOOP_LIMIT, MESSAGE_APPEARANCE_DELAY } from '../../../config'; import { areReactionsEmpty, getIsDownloading, @@ -1995,7 +1995,7 @@ export default memo(withGlobal( ? (chatFullInfo?.boostsApplied ?? message.senderBoosts) : message.senderBoosts; const chatLevel = chat?.boostLevel || 0; - const transcribeMinLevel = global.appConfig?.groupTranscribeLevelMin; + const transcribeMinLevel = global.appConfig.groupTranscribeLevelMin; const canTranscribeVoice = isPremium || Boolean(transcribeMinLevel && chatLevel >= transcribeMinLevel); const viaBusinessBot = viaBusinessBotId ? selectUser(global, viaBusinessBotId) : undefined; @@ -2009,7 +2009,7 @@ export default memo(withGlobal( const lastPlaybackTimestamp = selectMessageLastPlaybackTimestamp(global, chatId, message.id); const isAccountFrozen = selectIsCurrentUserFrozen(global); - const minFutureTime = global.appConfig?.starsSuggestedPostFutureMin || STARS_SUGGESTED_POST_FUTURE_MIN; + const minFutureTime = global.appConfig.starsSuggestedPostFutureMin; const isMediaNsfw = selectIsMediaNsfw(global, message); const isReplyMediaNsfw = replyMessage && selectIsMediaNsfw(global, replyMessage); diff --git a/src/components/middle/message/Photo.tsx b/src/components/middle/message/Photo.tsx index d297380b4..53cde6ed9 100644 --- a/src/components/middle/message/Photo.tsx +++ b/src/components/middle/message/Photo.tsx @@ -310,7 +310,7 @@ const Photo = ({ export default memo(withGlobal((global): StateProps => { const appConfig = global.appConfig; - const needsAgeVerification = appConfig?.needAgeVideoVerification; + const needsAgeVerification = appConfig.needAgeVideoVerification; return { needsAgeVerification, diff --git a/src/components/middle/message/Sticker.tsx b/src/components/middle/message/Sticker.tsx index b35f500f7..3ff32b658 100644 --- a/src/components/middle/message/Sticker.tsx +++ b/src/components/middle/message/Sticker.tsx @@ -232,7 +232,7 @@ const Sticker: FC = ({ export default memo(withGlobal((global): StateProps => { const appConfig = global.appConfig; - const needsAgeVerification = appConfig?.needAgeVideoVerification; + const needsAgeVerification = appConfig.needAgeVideoVerification; return { needsAgeVerification, diff --git a/src/components/middle/message/Video.tsx b/src/components/middle/message/Video.tsx index 4b10ac7d4..e4f6f52d5 100644 --- a/src/components/middle/message/Video.tsx +++ b/src/components/middle/message/Video.tsx @@ -353,7 +353,7 @@ const Video = ({ export default memo(withGlobal((global): StateProps => { const appConfig = global.appConfig; - const needsAgeVerification = appConfig?.needAgeVideoVerification; + const needsAgeVerification = appConfig.needAgeVideoVerification; return { needsAgeVerification, diff --git a/src/components/middle/message/actions/StarGift.tsx b/src/components/middle/message/actions/StarGift.tsx index d2e881e02..ad9faac69 100644 --- a/src/components/middle/message/actions/StarGift.tsx +++ b/src/components/middle/message/actions/StarGift.tsx @@ -194,7 +194,7 @@ export default memo(withGlobal( canPlayAnimatedEmojis, sender: giftSender || messageSender, recipient: giftRecipient || messageRecipient, - starGiftMaxConvertPeriod: global.appConfig?.starGiftMaxConvertPeriod, + starGiftMaxConvertPeriod: global.appConfig.starGiftMaxConvertPeriod, }; }, )(StarGiftAction)); diff --git a/src/components/middle/message/actions/SuggestedPostApproval.tsx b/src/components/middle/message/actions/SuggestedPostApproval.tsx index 65d9a8806..9d3ffbbea 100644 --- a/src/components/middle/message/actions/SuggestedPostApproval.tsx +++ b/src/components/middle/message/actions/SuggestedPostApproval.tsx @@ -4,7 +4,7 @@ import { withGlobal } from '../../../../global'; import type { ApiMessage, ApiPeer } from '../../../../api/types'; import type { ApiMessageActionSuggestedPostApproval } from '../../../../api/types/messageActions'; -import { STARS_SUGGESTED_POST_AGE_MIN, TON_CURRENCY_CODE } from '../../../../config'; +import { TON_CURRENCY_CODE } from '../../../../config'; import { getPeerFullTitle } from '../../../../global/helpers/peers'; import { getMessageReplyInfo } from '../../../../global/helpers/replies'; import { selectIsMonoforumAdmin, selectMonoforumChannel, @@ -146,7 +146,7 @@ export default memo(withGlobal( } const { appConfig } = global; - const ageMinSeconds = appConfig?.starsSuggestedPostAgeMin || STARS_SUGGESTED_POST_AGE_MIN; + const ageMinSeconds = appConfig.starsSuggestedPostAgeMin; const isAdmin = chat ? Boolean(selectIsMonoforumAdmin(global, message.chatId)) : false; return { diff --git a/src/components/middle/message/reactions/ReactionPicker.tsx b/src/components/middle/message/reactions/ReactionPicker.tsx index e1398f6ed..9bff2d4a4 100644 --- a/src/components/middle/message/reactions/ReactionPicker.tsx +++ b/src/components/middle/message/reactions/ReactionPicker.tsx @@ -304,7 +304,7 @@ export default memo(withGlobal((global): StateProps => { const message = chatId && messageId ? selectChatMessage(global, chatId, messageId) : undefined; const isPrivateChat = isUserId(chatId || storyPeerId || ''); const areSomeReactionsAllowed = chatFullInfo?.enabledReactions?.type === 'some'; - const { maxUniqueReactions } = global.appConfig || {}; + const { maxUniqueReactions } = global.appConfig; const areAllReactionsAllowed = chatFullInfo?.enabledReactions?.type === 'all' && chatFullInfo?.enabledReactions?.areCustomAllowed; diff --git a/src/components/middle/message/reactions/ReactionPickerLimited.tsx b/src/components/middle/message/reactions/ReactionPickerLimited.tsx index 263532190..ea531012f 100644 --- a/src/components/middle/message/reactions/ReactionPickerLimited.tsx +++ b/src/components/middle/message/reactions/ReactionPickerLimited.tsx @@ -153,7 +153,7 @@ export default memo(withGlobal( (global, { chatId }): StateProps => { const { availableReactions, topReactions } = global.reactions; - const { maxUniqueReactions } = global.appConfig || {}; + const { maxUniqueReactions } = global.appConfig; const { enabledReactions, isPaidReactionAvailable } = selectChatFullInfo(global, chatId) || {}; return { diff --git a/src/components/modals/aboutAds/AboutAdsModal.tsx b/src/components/modals/aboutAds/AboutAdsModal.tsx index 01b303ab5..4a9ff5351 100644 --- a/src/components/modals/aboutAds/AboutAdsModal.tsx +++ b/src/components/modals/aboutAds/AboutAdsModal.tsx @@ -178,7 +178,7 @@ const AboutAdsModal = ({ modal, minLevelToRestrictAds }: OwnProps & StateProps) export default memo(withGlobal( (global): StateProps => { - const minLevelToRestrictAds = global.appConfig?.channelRestrictAdsLevelMin; + const minLevelToRestrictAds = global.appConfig.channelRestrictAdsLevelMin; return { minLevelToRestrictAds, diff --git a/src/components/modals/ageVerification/AgeVerificationModal.tsx b/src/components/modals/ageVerification/AgeVerificationModal.tsx index c5b9a474b..0ce958873 100644 --- a/src/components/modals/ageVerification/AgeVerificationModal.tsx +++ b/src/components/modals/ageVerification/AgeVerificationModal.tsx @@ -86,8 +86,8 @@ const AgeVerificationModal: FC = ({ export default memo(withGlobal((global): StateProps => { const appConfig = global.appConfig; - const verifyAgeBotUsername = appConfig?.verifyAgeBotUsername; - const verifyAgeMin = appConfig?.verifyAgeMin || VERIFY_AGE_MIN_DEFAULT; + const verifyAgeBotUsername = appConfig.verifyAgeBotUsername; + const verifyAgeMin = appConfig.verifyAgeMin || VERIFY_AGE_MIN_DEFAULT; return { verifyAgeBotUsername, diff --git a/src/components/modals/collectible/CollectibleInfoModal.tsx b/src/components/modals/collectible/CollectibleInfoModal.tsx index cfcd39db3..5d3d55cc6 100644 --- a/src/components/modals/collectible/CollectibleInfoModal.tsx +++ b/src/components/modals/collectible/CollectibleInfoModal.tsx @@ -63,7 +63,6 @@ const CollectibleInfoModal: FC = ({ const handleOpenUrl = useLastCallback(() => { openUrl({ url: modal!.url, - shouldSkipModal: true, }); handleClose(); }); diff --git a/src/components/modals/frozenAccount/FrozenAccountModal.tsx b/src/components/modals/frozenAccount/FrozenAccountModal.tsx index c2b037666..9eda73243 100644 --- a/src/components/modals/frozenAccount/FrozenAccountModal.tsx +++ b/src/components/modals/frozenAccount/FrozenAccountModal.tsx @@ -129,8 +129,8 @@ const FrozenAccountModal = ({ export default memo(withGlobal( (global): StateProps => { - const freezeUntilDate = global.appConfig?.freezeUntilDate; - const freezeAppealUrl = global.appConfig?.freezeAppealUrl; + const freezeUntilDate = global.appConfig.freezeUntilDate; + const freezeAppealUrl = global.appConfig.freezeAppealUrl; const botFreezeAppeal = global.botFreezeAppealId ? selectUser(global, global.botFreezeAppealId) : undefined; const botFreezeAppealUsername = botFreezeAppeal && getMainUsername(botFreezeAppeal); diff --git a/src/components/modals/gift/GiftComposer.tsx b/src/components/modals/gift/GiftComposer.tsx index 555d01f81..fddc5af6c 100644 --- a/src/components/modals/gift/GiftComposer.tsx +++ b/src/components/modals/gift/GiftComposer.tsx @@ -428,7 +428,7 @@ export default memo(withGlobal( patternColor, customBackground, backgroundColor, - captionLimit: global.appConfig?.starGiftMaxMessageLength, + captionLimit: global.appConfig.starGiftMaxMessageLength, currentUserId: global.currentUserId, isPaymentFormLoading: tabState.isPaymentFormLoading, paidMessagesStars, diff --git a/src/components/modals/gift/GiftModal.tsx b/src/components/modals/gift/GiftModal.tsx index f01a11532..275e06914 100644 --- a/src/components/modals/gift/GiftModal.tsx +++ b/src/components/modals/gift/GiftModal.tsx @@ -528,7 +528,7 @@ export default memo(withGlobal((global, { modal }): StateProps => { const areResaleGiftsLoading = resaleGifts.isLoading !== false; return { - boostPerSentGift: global.appConfig?.boostsPerSentGift, + boostPerSentGift: global.appConfig.boostsPerSentGift, starGiftsById: starGifts?.byId, starGiftIdsByCategory: starGifts?.idsByCategory, starBalance: stars?.balance, diff --git a/src/components/modals/gift/GiftModalResaleScreen.tsx b/src/components/modals/gift/GiftModalResaleScreen.tsx index f18a4087a..e50fc04d0 100644 --- a/src/components/modals/gift/GiftModalResaleScreen.tsx +++ b/src/components/modals/gift/GiftModalResaleScreen.tsx @@ -10,10 +10,10 @@ import type { } from '../../../api/types'; import type { ResaleGiftsFilterOptions } from '../../../types'; -import { RESALE_GIFTS_LIMIT } from '../../../config'; import { selectTabState, } from '../../../global/selectors'; import buildClassName from '../../../util/buildClassName'; +import { RESALE_GIFTS_LIMIT } from '../../../limits'; import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets'; import useInfiniteScroll from '../../../hooks/useInfiniteScroll'; diff --git a/src/components/modals/gift/info/GiftInfoModal.tsx b/src/components/modals/gift/info/GiftInfoModal.tsx index 5536b521f..9bd853e92 100644 --- a/src/components/modals/gift/info/GiftInfoModal.tsx +++ b/src/components/modals/gift/info/GiftInfoModal.tsx @@ -906,8 +906,8 @@ export default memo(withGlobal( targetPeer, releasedByPeer, currentUserId, - starGiftMaxConvertPeriod: global.appConfig?.starGiftMaxConvertPeriod, - tonExplorerUrl: global.appConfig?.tonExplorerUrl, + starGiftMaxConvertPeriod: global.appConfig.starGiftMaxConvertPeriod, + tonExplorerUrl: global.appConfig.tonExplorerUrl, hasAdminRights, currentUserEmojiStatus, collectibleEmojiStatuses, diff --git a/src/components/modals/gift/resale/GiftResalePriceComposerModal.tsx b/src/components/modals/gift/resale/GiftResalePriceComposerModal.tsx index cc08d8de7..edcacedb9 100644 --- a/src/components/modals/gift/resale/GiftResalePriceComposerModal.tsx +++ b/src/components/modals/gift/resale/GiftResalePriceComposerModal.tsx @@ -176,21 +176,21 @@ const GiftResalePriceComposerModal = ({ export default memo(withGlobal( (global): StateProps => { - const configPermille = global.appConfig?.starsStargiftResaleCommissionPermille; + const configPermille = global.appConfig.starsStargiftResaleCommissionPermille; const starsStargiftResaleCommissionPermille = configPermille ? (configPermille / 1000) : undefined; - const starsStargiftResaleAmountMin = global.appConfig?.starsStargiftResaleAmountMin || 0; - const starsStargiftResaleAmountMax = global.appConfig?.starsStargiftResaleAmountMax; + const starsStargiftResaleAmountMin = global.appConfig.starsStargiftResaleAmountMin || 0; + const starsStargiftResaleAmountMax = global.appConfig.starsStargiftResaleAmountMax; - const starsUsdWithdrawRateX1000 = global.appConfig?.starsUsdWithdrawRateX1000; + const starsUsdWithdrawRateX1000 = global.appConfig.starsUsdWithdrawRateX1000; const starsUsdWithdrawRate = starsUsdWithdrawRateX1000 ? starsUsdWithdrawRateX1000 / 1000 : 1; - const tonConfigPermille = global.appConfig?.tonStargiftResaleCommissionPermille; + const tonConfigPermille = global.appConfig.tonStargiftResaleCommissionPermille; const tonStargiftResaleCommissionPermille = tonConfigPermille ? (tonConfigPermille / 1000) : 0; - const tonStargiftResaleAmountMin = convertTonFromNanos(global.appConfig?.tonStargiftResaleAmountMin || 0); - const maxTonFromConfig = global.appConfig?.tonStargiftResaleAmountMax; + const tonStargiftResaleAmountMin = convertTonFromNanos(global.appConfig.tonStargiftResaleAmountMin || 0); + const maxTonFromConfig = global.appConfig.tonStargiftResaleAmountMax; const tonStargiftResaleAmountMax = maxTonFromConfig && convertTonFromNanos(maxTonFromConfig); - const tonUsdRate = global.appConfig?.tonUsdRate; + const tonUsdRate = global.appConfig.tonUsdRate; return { starsStargiftResaleCommissionPermille, diff --git a/src/components/modals/paidReaction/PaidReactionModal.tsx b/src/components/modals/paidReaction/PaidReactionModal.tsx index c0c7102ee..4eaac3f35 100644 --- a/src/components/modals/paidReaction/PaidReactionModal.tsx +++ b/src/components/modals/paidReaction/PaidReactionModal.tsx @@ -377,7 +377,7 @@ export default memo(withGlobal( const chat = modal && selectChat(global, modal.chatId); const message = modal && selectChatMessage(global, modal.chatId, modal.messageId); const starBalance = global.stars?.balance; - const maxAmount = global.appConfig?.paidReactionMaxAmount || MAX_REACTION_AMOUNT; + const maxAmount = global.appConfig.paidReactionMaxAmount || MAX_REACTION_AMOUNT; const defaultPrivacy = global.settings.paidReactionPrivacy; const sendPaidReactionsAsPeerIds = chat?.sendPaidReactionsAsPeerIds; const currentUserId = global.currentUserId!; diff --git a/src/components/modals/stars/StarsBalanceModal.tsx b/src/components/modals/stars/StarsBalanceModal.tsx index b5ce9b043..26459c4f7 100644 --- a/src/components/modals/stars/StarsBalanceModal.tsx +++ b/src/components/modals/stars/StarsBalanceModal.tsx @@ -10,8 +10,6 @@ import { PAID_MESSAGES_PURPOSE, STARS_CURRENCY_CODE, TON_CURRENCY_CODE, - TON_TOPUP_URL_DEFAULT, - TON_USD_RATE_DEFAULT, } from '../../../config'; import { getChatTitle, getUserFullName } from '../../../global/helpers'; import { getPeerTitle } from '../../../global/helpers/peers'; @@ -298,7 +296,7 @@ const StarsBalanceModal = ({ }); const handleTonTopUp = useLastCallback(() => { - openUrl({ url: tonTopupUrl, shouldSkipModal: true }); + openUrl({ url: tonTopupUrl }); }); return ( @@ -419,8 +417,8 @@ export default memo(withGlobal( starsBalanceState: global.stars, tonBalanceState: global.ton, canBuyPremium: !selectIsPremiumPurchaseBlocked(global), - tonUsdRate: global.appConfig?.tonUsdRate || TON_USD_RATE_DEFAULT, - tonTopupUrl: global.appConfig?.tonTopupUrl || TON_TOPUP_URL_DEFAULT, + tonUsdRate: global.appConfig.tonUsdRate, + tonTopupUrl: global.appConfig.tonTopupUrl, animationLevel: selectSharedSettings(global).animationLevel, }; }, diff --git a/src/components/modals/stars/transaction/StarsTransactionModal.tsx b/src/components/modals/stars/transaction/StarsTransactionModal.tsx index 3d7902242..b4177dc0d 100644 --- a/src/components/modals/stars/transaction/StarsTransactionModal.tsx +++ b/src/components/modals/stars/transaction/StarsTransactionModal.tsx @@ -345,7 +345,7 @@ export default memo(withGlobal( (global, { modal }): StateProps => { const peerId = modal?.transaction?.peer?.type === 'peer' && modal.transaction.peer.id; const peer = peerId ? selectPeer(global, peerId) : undefined; - const paidMessageCommission = global.appConfig?.starsPaidMessageCommissionPermille; + const paidMessageCommission = global.appConfig.starsPaidMessageCommissionPermille; const currencyAmount = modal?.transaction.amount; const starsGiftSticker = modal?.transaction.isGift diff --git a/src/components/modals/suggestMessage/SuggestMessageModal.tsx b/src/components/modals/suggestMessage/SuggestMessageModal.tsx index 0e8f7e21f..7ff1d5f61 100644 --- a/src/components/modals/suggestMessage/SuggestMessageModal.tsx +++ b/src/components/modals/suggestMessage/SuggestMessageModal.tsx @@ -11,14 +11,8 @@ import { MAIN_THREAD_ID } from '../../../api/types'; import { STARS_CURRENCY_CODE, - STARS_SUGGESTED_POST_AGE_MIN, - STARS_SUGGESTED_POST_AMOUNT_MAX, - STARS_SUGGESTED_POST_AMOUNT_MIN, - STARS_SUGGESTED_POST_FUTURE_MAX, - STARS_SUGGESTED_POST_FUTURE_MIN, TON_CURRENCY_CODE, - TON_SUGGESTED_POST_AMOUNT_MAX, - TON_SUGGESTED_POST_AMOUNT_MIN } from '../../../config'; +} from '../../../config'; import { selectIsMonoforumAdmin, selectPeer } from '../../../global/selectors'; import { selectDraft } from '../../../global/selectors/messages'; import buildClassName from '../../../util/buildClassName'; @@ -29,7 +23,9 @@ import { formatStarsAsText, formatTonAsIcon, formatTonAsText } from '../../../util/localization/format'; +import { getServerTime } from '../../../util/serverTime'; +import useFlag from '../../../hooks/useFlag'; import useLang from '../../../hooks/useLang'; import useLastCallback from '../../../hooks/useLastCallback'; import useOldLang from '../../../hooks/useOldLang'; @@ -46,8 +42,6 @@ export type OwnProps = { modal: TabState['suggestMessageModal']; }; -import useFlag from '../../../hooks/useFlag'; - type StateProps = { starBalance?: ApiStarsAmount; tonBalance?: number; @@ -63,6 +57,9 @@ type StateProps = { isMonoforumAdmin?: boolean; }; +// Add 1 minute if time is less than server min, to allow user to send the message +const FUTURE_TIME_ADJUSTMENT = 1 * 60; + const SuggestMessageModal = ({ modal, starBalance, @@ -174,7 +171,9 @@ const SuggestMessageModal = ({ updateDraftSuggestedPostInfo({ price: { currency: selectedCurrency, amount: neededAmount, nanos: 0 }, - scheduleDate: scheduleDate ? scheduleDate / 1000 : undefined, + scheduleDate: scheduleDate + ? Math.max(scheduleDate / 1000, getServerTime() + futureMin + FUTURE_TIME_ADJUSTMENT) + : undefined, }); closeSuggestMessageModal(); @@ -308,14 +307,14 @@ export default memo(withGlobal( const currentDraft = modal ? selectDraft(global, modal.chatId, MAIN_THREAD_ID) : undefined; const { appConfig } = global; - const maxStarsAmount = appConfig?.starsSuggestedPostAmountMax || STARS_SUGGESTED_POST_AMOUNT_MAX; - const minStarsAmount = appConfig?.starsSuggestedPostAmountMin || STARS_SUGGESTED_POST_AMOUNT_MIN; - const ageMinSeconds = appConfig?.starsSuggestedPostAgeMin || STARS_SUGGESTED_POST_AGE_MIN; - const futureMin = appConfig?.starsSuggestedPostFutureMin || STARS_SUGGESTED_POST_FUTURE_MIN; - const futureMax = appConfig?.starsSuggestedPostFutureMax || STARS_SUGGESTED_POST_FUTURE_MAX; + const maxStarsAmount = appConfig.starsSuggestedPostAmountMax; + const minStarsAmount = appConfig.starsSuggestedPostAmountMin; + const ageMinSeconds = appConfig.starsSuggestedPostAgeMin; + const futureMin = appConfig.starsSuggestedPostFutureMin; + const futureMax = appConfig.starsSuggestedPostFutureMax; - const tonMaxAmount = appConfig?.tonSuggestedPostAmountMax || TON_SUGGESTED_POST_AMOUNT_MAX; - const tonMinAmount = appConfig?.tonSuggestedPostAmountMin || TON_SUGGESTED_POST_AMOUNT_MIN; + const tonMaxAmount = appConfig.tonSuggestedPostAmountMax; + const tonMinAmount = appConfig.tonSuggestedPostAmountMin; const isMonoforumAdmin = modal ? selectIsMonoforumAdmin(global, modal.chatId) : false; diff --git a/src/components/modals/suggestedPostApproval/SuggestedPostApprovalModal.tsx b/src/components/modals/suggestedPostApproval/SuggestedPostApprovalModal.tsx index 88369aea3..a71a821cd 100644 --- a/src/components/modals/suggestedPostApproval/SuggestedPostApprovalModal.tsx +++ b/src/components/modals/suggestedPostApproval/SuggestedPostApprovalModal.tsx @@ -4,12 +4,9 @@ import { getActions, withGlobal } from '../../../global'; import type { ApiMessage, ApiPeer } from '../../../api/types'; import type { TabState } from '../../../global/types'; -import { STARS_CURRENCY_CODE, STARS_SUGGESTED_POST_AGE_MIN, - STARS_SUGGESTED_POST_COMMISSION_PERMILLE, - STARS_SUGGESTED_POST_FUTURE_MAX, - STARS_SUGGESTED_POST_FUTURE_MIN, +import { + STARS_CURRENCY_CODE, TON_CURRENCY_CODE, - TON_SUGGESTED_POST_COMMISSION_PERMILLE, } from '../../../config'; import { getPeerFullTitle } from '../../../global/helpers/peers'; import { selectChatMessage, selectIsMonoforumAdmin, selectSender } from '../../../global/selectors'; @@ -224,13 +221,11 @@ export default memo(withGlobal( const sender = message ? selectSender(global, message) : undefined; const isAdmin = modal && selectIsMonoforumAdmin(global, modal.chatId); const { appConfig } = global; - const commissionPermille = appConfig?.starsSuggestedPostCommissionPermille - || STARS_SUGGESTED_POST_COMMISSION_PERMILLE; - const tonCommissionPermille = appConfig?.tonSuggestedPostCommissionPermille - || TON_SUGGESTED_POST_COMMISSION_PERMILLE; - const minAge = appConfig?.starsSuggestedPostAgeMin || STARS_SUGGESTED_POST_AGE_MIN; - const futureMin = (appConfig?.starsSuggestedPostFutureMin || STARS_SUGGESTED_POST_FUTURE_MIN) * 2; - const futureMax = appConfig?.starsSuggestedPostFutureMax || STARS_SUGGESTED_POST_FUTURE_MAX; + const commissionPermille = appConfig.starsSuggestedPostCommissionPermille; + const tonCommissionPermille = appConfig.tonSuggestedPostCommissionPermille; + const minAge = appConfig.starsSuggestedPostAgeMin; + const futureMin = appConfig.starsSuggestedPostFutureMin; + const futureMax = appConfig.starsSuggestedPostFutureMax; const scheduleDate = message?.suggestedPostInfo?.scheduleDate; return { diff --git a/src/components/modals/webApp/hooks/useWebAppFrame.ts b/src/components/modals/webApp/hooks/useWebAppFrame.ts index 99d85ca12..91ccadf82 100644 --- a/src/components/modals/webApp/hooks/useWebAppFrame.ts +++ b/src/components/modals/webApp/hooks/useWebAppFrame.ts @@ -386,7 +386,7 @@ const useWebAppFrame = ( if (eventType === 'web_app_verify_age') { const { passed } = eventData; - const minAge = getGlobal().appConfig?.verifyAgeMin || VERIFY_AGE_MIN_DEFAULT; + const minAge = getGlobal().appConfig.verifyAgeMin || VERIFY_AGE_MIN_DEFAULT; const ageFromParam = eventData.age || 0; if (passed && ageFromParam >= minAge) { diff --git a/src/components/right/management/ManageChannel.tsx b/src/components/right/management/ManageChannel.tsx index ca3e4cb03..d25ba3790 100644 --- a/src/components/right/management/ManageChannel.tsx +++ b/src/components/right/management/ManageChannel.tsx @@ -383,7 +383,7 @@ export default memo(withGlobal( const { management } = selectTabState(global); const { progress } = management; const { invites } = management.byChatId[chatId] || {}; - const minLevelToToggleAutoTranslation = global.appConfig?.channelAutoTranslationLevelMin; + const minLevelToToggleAutoTranslation = global.appConfig.channelAutoTranslationLevelMin; const hasAutoTranslation = chat?.hasAutoTranslation; const chatBoostLevel = chat?.level; const canToggleAutoTranslation = chatBoostLevel && minLevelToToggleAutoTranslation diff --git a/src/components/right/management/ManageGroupMembers.tsx b/src/components/right/management/ManageGroupMembers.tsx index 37d4559ad..e472a151e 100644 --- a/src/components/right/management/ManageGroupMembers.tsx +++ b/src/components/right/management/ManageGroupMembers.tsx @@ -280,7 +280,7 @@ export default memo(withGlobal( const { members, adminMembersById, areParticipantsHidden } = selectChatFullInfo(global, chatId) || {}; const isChannel = chat && isChatChannel(chat); const { userIds: localContactIds } = global.contactList || {}; - const hiddenMembersMinCount = global.appConfig?.hiddenMembersMinCount; + const hiddenMembersMinCount = global.appConfig.hiddenMembersMinCount; const canDeleteMembers = chat && (chat.isCreator || getHasAdminRight(chat, 'banUsers')); diff --git a/src/components/right/management/ManageGroupPermissions.tsx b/src/components/right/management/ManageGroupPermissions.tsx index 86b64c402..2a2e30fd9 100644 --- a/src/components/right/management/ManageGroupPermissions.tsx +++ b/src/components/right/management/ManageGroupPermissions.tsx @@ -358,7 +358,7 @@ export default memo(withGlobal( const { progress } = selectTabState(global).management; const paidMessagesStars = chat?.paidMessagesStars; - const configStarsPaidMessageCommissionPermille = global.appConfig?.starsPaidMessageCommissionPermille; + const configStarsPaidMessageCommissionPermille = global.appConfig.starsPaidMessageCommissionPermille; return { chat, diff --git a/src/components/right/management/ManageReactions.tsx b/src/components/right/management/ManageReactions.tsx index e6fddc59d..caec239b0 100644 --- a/src/components/right/management/ManageReactions.tsx +++ b/src/components/right/management/ManageReactions.tsx @@ -10,9 +10,6 @@ import type { ApiAvailableReaction, ApiChat, ApiChatReactions, ApiReaction, } from '../../../api/types'; -import { - MAX_UNIQUE_REACTIONS, -} from '../../../config'; import { isChatChannel, isSameReaction } from '../../../global/helpers'; import { selectChat, selectChatFullInfo } from '../../../global/selectors'; @@ -271,7 +268,7 @@ const ManageReactions: FC = ({ export default memo(withGlobal( (global, { chatId }): StateProps => { const chat = selectChat(global, chatId)!; - const { maxUniqueReactions = MAX_UNIQUE_REACTIONS } = global.appConfig || {}; + const { maxUniqueReactions } = global.appConfig; const chatFullInfo = selectChatFullInfo(global, chatId); const reactionsLimit = chatFullInfo?.reactionsLimit || maxUniqueReactions; diff --git a/src/components/right/statistics/BoostStatistics.tsx b/src/components/right/statistics/BoostStatistics.tsx index 49cecb6a6..66458b59c 100644 --- a/src/components/right/statistics/BoostStatistics.tsx +++ b/src/components/right/statistics/BoostStatistics.tsx @@ -429,7 +429,7 @@ export default memo(withGlobal( const chatId = boostStatistics && boostStatistics.chatId; const chat = chatId ? selectChat(global, chatId) : undefined; const isChannel = chat && isChatChannel(chat); - const giveawayBoostsPerPremium = global.appConfig?.giveawayBoostsPerPremium; + const giveawayBoostsPerPremium = global.appConfig.giveawayBoostsPerPremium; const { animationLevel } = selectSharedSettings(global); return { diff --git a/src/components/right/statistics/MonetizationStatistics.tsx b/src/components/right/statistics/MonetizationStatistics.tsx index 83ffbebe5..4972bd0ce 100644 --- a/src/components/right/statistics/MonetizationStatistics.tsx +++ b/src/components/right/statistics/MonetizationStatistics.tsx @@ -301,7 +301,7 @@ export default memo(withGlobal( const statistics = tabState.statistics.monetization; - const isChannelRevenueWithdrawalEnabled = global.appConfig?.isChannelRevenueWithdrawalEnabled; + const isChannelRevenueWithdrawalEnabled = global.appConfig.isChannelRevenueWithdrawalEnabled; return { chatId: chatId!, diff --git a/src/components/story/MediaStory.tsx b/src/components/story/MediaStory.tsx index b2c093cab..a8123e56c 100644 --- a/src/components/story/MediaStory.tsx +++ b/src/components/story/MediaStory.tsx @@ -190,7 +190,7 @@ export default memo(withGlobal((global, { story }): StateProps => { const chat = selectChat(global, story.peerId); const isProtected = chat?.isProtected; - const { maxPinnedStoriesCount } = global.appConfig || {}; + const { maxPinnedStoriesCount } = global.appConfig; const isOwn = 'isOut' in story && story.isOut; const pinnedStories = selectPinnedStories(global, story.peerId); const isPinned = pinnedStories?.some((pinnedStory) => pinnedStory.id === story.id); diff --git a/src/components/story/Story.tsx b/src/components/story/Story.tsx index c35dd5dab..c1c4da1c6 100644 --- a/src/components/story/Story.tsx +++ b/src/components/story/Story.tsx @@ -981,8 +981,8 @@ export default memo(withGlobal((global, { isMuted, isCurrentUserPremium: selectIsCurrentUserPremium(global), shouldForcePause, - storyChangelogUserId: appConfig!.storyChangelogUserId, - viewersExpirePeriod: appConfig!.storyExpirePeriod + appConfig!.storyViewersExpirePeriod, + storyChangelogUserId: appConfig.storyChangelogUserId, + viewersExpirePeriod: appConfig.storyViewersExpirePeriod, isChatExist: Boolean(chat), arePeerSettingsLoaded: Boolean(userFullInfo?.settings), stealthMode: global.stories.stealthMode, diff --git a/src/components/story/StoryViewModal.tsx b/src/components/story/StoryViewModal.tsx index 35c492ff6..8b14826bc 100644 --- a/src/components/story/StoryViewModal.tsx +++ b/src/components/story/StoryViewModal.tsx @@ -44,7 +44,7 @@ interface StateProps { isLoading?: boolean; views?: ApiTypeStoryView[]; nextOffset?: string; - viewersExpirePeriod: number; + viewersExpireDate?: number; isCurrentUserPremium?: boolean; } @@ -52,7 +52,7 @@ const REFETCH_DEBOUNCE = 250; function StoryViewModal({ story, - viewersExpirePeriod, + viewersExpireDate, views, nextOffset, isLoading, @@ -69,7 +69,7 @@ function StoryViewModal({ const lang = useOldLang(); const isOpen = Boolean(story); - const isExpired = Boolean(story?.date) && (story.date + viewersExpirePeriod) < getServerTime(); + const isExpired = Boolean(viewersExpireDate) && viewersExpireDate < getServerTime(); const { viewsCount = 0, reactionsCount = 0 } = story?.views || {}; const shouldShowJustContacts = story?.isPublic && viewsCount > STORY_VIEWS_MIN_CONTACTS_FILTER; @@ -275,11 +275,12 @@ export default memo(withGlobal((global) => { storyId, views, nextOffset, isLoading, } = viewModal || {}; const story = storyId ? selectPeerStory(global, global.currentUserId!, storyId) : undefined; + const storyExpireDate = story?.['@type'] === 'story' ? story.expireDate : undefined; return { storyId, views, - viewersExpirePeriod: appConfig!.storyExpirePeriod + appConfig!.storyViewersExpirePeriod, + viewersExpireDate: storyExpireDate ? (storyExpireDate + appConfig.storyViewersExpirePeriod) : undefined, story: story && 'content' in story ? story : undefined, nextOffset, isLoading, diff --git a/src/components/ui/ModalStarBalanceBar.tsx b/src/components/ui/ModalStarBalanceBar.tsx index 6bc5e4a4d..6fc81fa2f 100644 --- a/src/components/ui/ModalStarBalanceBar.tsx +++ b/src/components/ui/ModalStarBalanceBar.tsx @@ -5,9 +5,6 @@ import { getActions, withGlobal } from '../../global'; import type { ApiStarsAmount, ApiTonAmount } from '../../api/types'; -import { - TON_USD_RATE_DEFAULT, -} from '../../config'; import { formatStarsAmount } from '../../global/helpers/payments'; import buildClassName from '../../util/buildClassName'; import { convertTonFromNanos, convertTonToUsd, formatCurrencyAsString } from '../../util/formatCurrency'; @@ -30,7 +27,7 @@ export type OwnProps = { export type StateProps = { starBalance?: ApiStarsAmount; tonBalance?: ApiTonAmount; - tonUsdRate: number; + tonUsdRate?: number; }; function ModalStarBalanceBar({ @@ -38,8 +35,8 @@ function ModalStarBalanceBar({ tonBalance, tonUsdRate, isModalOpen, - onCloseAnimationEnd, currency, + onCloseAnimationEnd, }: StateProps & OwnProps) { const { openStarsBalanceModal, @@ -94,7 +91,7 @@ function ModalStarBalanceBar({ )}
- {isTonMode && ( + {isTonMode && Boolean(tonUsdRate) && (
{`≈ ${formatCurrencyAsString( convertTonToUsd((currentBalance as ApiTonAmount).amount, tonUsdRate, true), @@ -123,7 +120,7 @@ export default memo(withGlobal( return { starBalance: stars?.balance, tonBalance: ton?.balance, - tonUsdRate: global.appConfig?.tonUsdRate || TON_USD_RATE_DEFAULT, + tonUsdRate: global.appConfig.tonUsdRate, }; }, )(ModalStarBalanceBar)); diff --git a/src/config.ts b/src/config.ts index ec6b0279f..c3765924f 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,5 +1,5 @@ import type { - ApiLimitType, ApiLimitTypeForPromo, ApiPremiumSection, ApiReactionEmoji, + ApiLimitTypeForPromo, ApiPremiumSection, ApiReactionEmoji, } from './api/types'; import type { GiftProfileFilterOptions, @@ -94,39 +94,18 @@ export const CHAT_MEDIA_SLICE = 42; export const MESSAGE_SEARCH_SLICE = 42; export const GLOBAL_SEARCH_SLICE = 20; export const GLOBAL_TOPIC_SEARCH_SLICE = 5; -export const GLOBAL_SEARCH_CONTACTS_LIMIT = 20; export const MEMBERS_SLICE = 30; export const MEMBERS_LOAD_SLICE = 200; -export const PINNED_MESSAGES_LIMIT = 50; -export const BLOCKED_LIST_LIMIT = 100; export const PROFILE_SENSITIVE_AREA = 500; export const TOPIC_LIST_SENSITIVE_AREA = 600; -export const GROUP_CALL_PARTICIPANTS_LIMIT = 100; -export const STORY_LIST_LIMIT = 100; -export const API_GENERAL_ID_LIMIT = 100; -export const RESALE_GIFTS_LIMIT = 50; -export const TODO_ITEMS_LIMIT = 30; -export const TODO_TITLE_LENGTH_LIMIT = 32; -export const TODO_ITEM_LENGTH_LIMIT = 64; // Public Posts Search defaults export const PUBLIC_POSTS_SEARCH_DEFAULT_STARS_AMOUNT = 10; export const PUBLIC_POSTS_SEARCH_DEFAULT_TOTAL_DAILY = 2; // Suggested Posts defaults -export const STARS_SUGGESTED_POST_AMOUNT_MAX = 100000; -export const STARS_SUGGESTED_POST_AMOUNT_MIN = 5; -export const STARS_SUGGESTED_POST_COMMISSION_PERMILLE = 850; -export const STARS_SUGGESTED_POST_AGE_MIN = 86400; // 24 hours in seconds -export const STARS_SUGGESTED_POST_FUTURE_MAX = 2678400; // 31 days in seconds -export const STARS_SUGGESTED_POST_FUTURE_MIN = 300; // 5 minutes in seconds export const TON_CURRENCY_CODE = 'TON'; -export const TON_SUGGESTED_POST_COMMISSION_PERMILLE = 850; -export const TON_USD_RATE_DEFAULT = 3; export const VERIFY_AGE_MIN_DEFAULT = 18; -export const TON_TOPUP_URL_DEFAULT = 'https://fragment.com/ads/topup'; -export const TON_SUGGESTED_POST_AMOUNT_MIN = 10000000; // 0.01 TON in nanos -export const TON_SUGGESTED_POST_AMOUNT_MAX = 10000000000000; // 10 000 TON in nanos export const STORY_VIEWS_MIN_SEARCH = 15; export const STORY_MIN_REACTIONS_SORT = 10; @@ -136,14 +115,8 @@ export const MEDIA_TIMESTAMP_SAVE_MINIMUM_DURATION = 30; // 30s export const GLOBAL_SUGGESTED_CHANNELS_ID = 'global'; -// As in Telegram for Android -// https://github.com/DrKLO/Telegram/blob/51e9947527/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java#L7799 -export const TOP_REACTIONS_LIMIT = 100; - // As in Telegram for Android // https://github.com/DrKLO/Telegram/blob/51e9947527/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java#L7781 -export const RECENT_REACTIONS_LIMIT = 50; -export const REACTION_LIST_LIMIT = 100; export const REACTION_UNREAD_SLICE = 100; export const MENTION_UNREAD_SLICE = 100; export const TOPICS_SLICE = 20; @@ -401,7 +374,6 @@ export const PEER_COLOR_BG_OPACITY = '1a'; export const PEER_COLOR_BG_ACTIVE_OPACITY = '2b'; export const PEER_COLOR_GRADIENT_STEP = 5; // px export const MAX_UPLOAD_FILEPART_SIZE = 524288; -export const MAX_UNIQUE_REACTIONS = 11; export const IGNORE_UNHANDLED_ERRORS = new Set([ 'USER_CANCELED', @@ -411,25 +383,6 @@ export const IGNORE_UNHANDLED_ERRORS = new Set([ export const GROUP_CALL_VOLUME_MULTIPLIER = 100; export const GROUP_CALL_DEFAULT_VOLUME = 100 * GROUP_CALL_VOLUME_MULTIPLIER; -export const DEFAULT_LIMITS: Record = { - uploadMaxFileparts: [4000, 8000], - stickersFaved: [5, 10], - savedGifs: [200, 400], - dialogFiltersChats: [100, 200], - dialogFilters: [10, 20], - dialogFolderPinned: [5, 10], - captionLength: [1024, 4096], - channels: [500, 1000], - channelsPublic: [10, 20], - aboutLength: [70, 140], - chatlistInvites: [3, 100], - chatlistJoined: [2, 20], - recommendedChannels: [10, 100], - savedDialogsPinned: [5, 100], - moreAccounts: [3, MULTIACCOUNT_MAX_SLOTS], -}; -export const DEFAULT_MAX_MESSAGE_LENGTH = 4096; - export const ONE_TIME_MEDIA_TTL_SECONDS = 2147483647; // Premium diff --git a/src/global/actions/api/bots.ts b/src/global/actions/api/bots.ts index 7958dd384..fe492f796 100644 --- a/src/global/actions/api/bots.ts +++ b/src/global/actions/api/bots.ts @@ -1444,7 +1444,7 @@ addActionHandler('startBotFatherConversation', async (global, actions, payload): }); addActionHandler('loadBotFreezeAppeal', async (global): Promise => { - const botUrl = global.appConfig?.freezeAppealUrl; + const botUrl = global.appConfig.freezeAppealUrl; if (!botUrl) return; const botAppealUsername = botUrl ? getUsernameFromDeepLink(botUrl) : undefined; if (!botAppealUsername) return; diff --git a/src/global/actions/api/chats.ts b/src/global/actions/api/chats.ts index b51c8b8b6..3f11cd15b 100644 --- a/src/global/actions/api/chats.ts +++ b/src/global/actions/api/chats.ts @@ -2517,7 +2517,7 @@ addActionHandler('toggleTopicPinned', (global, actions, payload): ActionReturnTy chatId, topicId, isPinned, tabId = getCurrentTabId(), } = payload; - const { topicsPinnedLimit } = global.appConfig || {}; + const { topicsPinnedLimit } = global.appConfig; const chat = selectChat(global, chatId); const topics = selectTopics(global, chatId); if (!chat || !topics || !topicsPinnedLimit) return; @@ -3375,7 +3375,7 @@ async function openChatByUsername( actions.openChat({ id: TMP_CHAT_ID, tabId }); } - const starRefStartPrefixes = global.appConfig?.starRefStartPrefixes; + const starRefStartPrefixes = global.appConfig.starRefStartPrefixes; let referrer = ref; if (startParam && starRefStartPrefixes?.length) { const prefix = starRefStartPrefixes.find((p) => startParam.startsWith(p)); diff --git a/src/global/actions/api/messages.ts b/src/global/actions/api/messages.ts index a69d50732..007d93f77 100644 --- a/src/global/actions/api/messages.ts +++ b/src/global/actions/api/messages.ts @@ -34,7 +34,6 @@ import { RE_TELEGRAM_LINK, SERVICE_NOTIFICATIONS_USER_ID, STARS_CURRENCY_CODE, - STARS_SUGGESTED_POST_FUTURE_MIN, SUPPORTED_AUDIO_CONTENT_TYPES, SUPPORTED_PHOTO_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES, @@ -834,7 +833,7 @@ addActionHandler('initDraftFromSuggestedMessage', (global, actions, payload): Ac if (message.suggestedPostInfo) { const { scheduleDate, ...messageSuggestedPost } = message.suggestedPostInfo; const now = getServerTime(); - const futureMin = global.appConfig?.starsSuggestedPostFutureMin || STARS_SUGGESTED_POST_FUTURE_MIN; + const futureMin = global.appConfig.starsSuggestedPostFutureMin; const validScheduleDate = scheduleDate && scheduleDate > now + futureMin ? scheduleDate : undefined; @@ -2388,22 +2387,22 @@ addActionHandler('openUrl', (global, actions, payload): ActionReturnType => { } const { appConfig, config } = global; - if (appConfig) { - if (config?.autologinToken && appConfig.autologinDomains.includes(parsedUrl.hostname)) { - parsedUrl.searchParams.set(AUTOLOGIN_TOKEN_KEY, config.autologinToken); - window.open(parsedUrl.href, '_blank', 'noopener'); - return; - } - - if (appConfig.urlAuthDomains.includes(parsedUrl.hostname)) { - actions.closeStoryViewer({ tabId }); - - actions.requestLinkUrlAuth({ url, tabId }); - return; - } + if (config?.autologinToken && appConfig.autologinDomains.includes(parsedUrl.hostname)) { + parsedUrl.searchParams.set(AUTOLOGIN_TOKEN_KEY, config.autologinToken); + window.open(parsedUrl.href, '_blank', 'noopener'); + return; } - const shouldDisplayModal = !urlWithProtocol.match(RE_TELEGRAM_LINK) && !shouldSkipModal; + if (appConfig.urlAuthDomains.includes(parsedUrl.hostname)) { + actions.closeStoryViewer({ tabId }); + + actions.requestLinkUrlAuth({ url, tabId }); + return; + } + + const isWhitelisted = appConfig.whitelistedDomains.includes(parsedUrl.hostname); + + const shouldDisplayModal = !urlWithProtocol.match(RE_TELEGRAM_LINK) && !shouldSkipModal && !isWhitelisted; if (shouldDisplayModal) { actions.toggleSafeLinkModal({ url: isMixedScript ? parsedUrl.toString() : urlWithProtocol, tabId }); diff --git a/src/global/actions/api/payments.ts b/src/global/actions/api/payments.ts index 53fd31940..0cf69c007 100644 --- a/src/global/actions/api/payments.ts +++ b/src/global/actions/api/payments.ts @@ -1213,7 +1213,7 @@ addActionHandler('processStarGiftWithdrawal', async (global, actions, payload): return; } - actions.openUrl({ url: result.url, shouldSkipModal: true, tabId }); + actions.openUrl({ url: result.url, tabId }); actions.closeGiftWithdrawModal({ tabId }); }); diff --git a/src/global/actions/api/stars.ts b/src/global/actions/api/stars.ts index 76d41e2ab..b94491e48 100644 --- a/src/global/actions/api/stars.ts +++ b/src/global/actions/api/stars.ts @@ -4,13 +4,13 @@ import type { ActionReturnType } from '../../types'; import { DEFAULT_RESALE_GIFTS_FILTER_OPTIONS, - RESALE_GIFTS_LIMIT, STARS_CURRENCY_CODE, TON_CURRENCY_CODE, } from '../../../config'; import { getCurrentTabId } from '../../../util/establishMultitabRole'; import { buildCollectionByKey } from '../../../util/iteratees'; import { callApi } from '../../../api/gramjs'; +import { RESALE_GIFTS_LIMIT } from '../../../limits'; import { areInputSavedGiftsEqual, getRequestInputSavedStarGift } from '../../helpers/payments'; import { addActionHandler, getGlobal, setGlobal } from '../../index'; import { @@ -485,7 +485,7 @@ addActionHandler('toggleSavedGiftPinned', async (global, actions, payload): Prom const savedGifts = selectPeerSavedGifts(global, peerId, tabId); if (!savedGifts) return; - const pinLimit = global.appConfig?.savedGiftPinLimit; + const pinLimit = global.appConfig.savedGiftPinLimit; const currentPinnedGifts = savedGifts.gifts.filter((g) => g.isPinned); const newPinnedGifts = gift.isPinned ? currentPinnedGifts.filter((g) => (g.gift as ApiStarGiftUnique).slug !== (gift.gift as ApiStarGiftUnique).slug) diff --git a/src/global/actions/api/statistics.ts b/src/global/actions/api/statistics.ts index eea2c38dd..d9cee7172 100644 --- a/src/global/actions/api/statistics.ts +++ b/src/global/actions/api/statistics.ts @@ -270,7 +270,6 @@ addActionHandler('processMonetizationRevenueWithdrawalUrl', async (global, actio if ('url' in result) { actions.openUrl({ url: result.url, - shouldSkipModal: true, tabId, ignoreDeepLinks: true, }); diff --git a/src/global/actions/ui/misc.ts b/src/global/actions/ui/misc.ts index 373a42c41..2981bdc9c 100644 --- a/src/global/actions/ui/misc.ts +++ b/src/global/actions/ui/misc.ts @@ -877,7 +877,7 @@ addActionHandler('processPremiumFloodWait', (global, actions, payload): ActionRe bandwidthPremiumDownloadSpeedup, bandwidthPremiumUploadSpeedup, bandwidthPremiumNotifyPeriod, - } = global.appConfig || {}; + } = global.appConfig; const { lastPremiumBandwithNotificationDate: lastNotifiedAt } = global.settings; if (!bandwidthPremiumDownloadSpeedup || !bandwidthPremiumUploadSpeedup || !bandwidthPremiumNotifyPeriod) { diff --git a/src/global/cache.ts b/src/global/cache.ts index b919e1059..871f45254 100644 --- a/src/global/cache.ts +++ b/src/global/cache.ts @@ -13,7 +13,6 @@ import { ALL_FOLDER_ID, ANIMATION_LEVEL_DEFAULT, ARCHIVED_FOLDER_ID, DEBUG, - DEFAULT_LIMITS, GLOBAL_STATE_CACHE_ARCHIVED_CHAT_LIST_LIMIT, GLOBAL_STATE_CACHE_CHAT_LIST_LIMIT, GLOBAL_STATE_CACHE_CUSTOM_EMOJI_LIMIT, @@ -213,10 +212,6 @@ function unsafeMigrateCache(cached: GlobalState, initialState: GlobalState) { ...cached.chatFolders, }; - if (cached.appConfig && !cached.appConfig.limits) { - cached.appConfig.limits = DEFAULT_LIMITS; - } - if (!cached.chats.similarChannelsById) { cached.chats.similarChannelsById = initialState.chats.similarChannelsById; } @@ -230,7 +225,7 @@ function unsafeMigrateCache(cached: GlobalState, initialState: GlobalState) { } // Clear old color storage to optimize cache size - if (untypedCached?.appConfig?.peerColors) { + if (untypedCached?.appConfig.peerColors) { untypedCached.appConfig.peerColors = undefined; untypedCached.appConfig.darkPeerColors = undefined; } @@ -309,9 +304,6 @@ function unsafeMigrateCache(cached: GlobalState, initialState: GlobalState) { cached.cacheVersion = 2; } - if (cached.appConfig?.limits && !cached.appConfig.limits.moreAccounts) { - cached.appConfig.limits.moreAccounts = DEFAULT_LIMITS.moreAccounts; - } if (!cached.chats.notifyExceptionById) { cached.chats.notifyExceptionById = initialState.chats.notifyExceptionById; } @@ -355,6 +347,10 @@ function unsafeMigrateCache(cached: GlobalState, initialState: GlobalState) { cachedSharedSettings.animationLevel = ANIMATION_LEVEL_DEFAULT; cachedSharedSettings.performance = INITIAL_PERFORMANCE_STATE_MED; } + + if (!cached.appConfig) { + cached.appConfig = initialState.appConfig; + } } function updateCache(force?: boolean) { diff --git a/src/global/helpers/misc.ts b/src/global/helpers/misc.ts index 28572cb5b..b59f65c34 100644 --- a/src/global/helpers/misc.ts +++ b/src/global/helpers/misc.ts @@ -5,11 +5,11 @@ import type { } from '../../api/types'; import type { GlobalState } from '../types'; -import { DEFAULT_LIMITS } from '../../config'; import { isUserId } from '../../util/entities/ids'; import { partition } from '../../util/iteratees'; import { clamp } from '../../util/math'; import { getAccountsInfo } from '../../util/multiaccount'; +import { DEFAULT_LIMITS } from '../../limits'; import { getGlobal } from '..'; export function buildApiInputPrivacyRules(global: GlobalState, { @@ -51,7 +51,7 @@ export function buildApiInputPrivacyRules(global: GlobalState, { export function getCurrentMaxAccountCount() { const global = getGlobal(); - const limit = global.appConfig?.limits?.moreAccounts || DEFAULT_LIMITS.moreAccounts; + const limit = global.appConfig.limits?.moreAccounts || DEFAULT_LIMITS.moreAccounts; const accounts = getAccountsInfo(); const premiumCount = Object.values(accounts).filter((account) => account.isPremium).length; // Each premium account increases the base limit by 1, up to the maximum limit. diff --git a/src/global/initialState.ts b/src/global/initialState.ts index 91923823a..d0900098d 100644 --- a/src/global/initialState.ts +++ b/src/global/initialState.ts @@ -15,6 +15,7 @@ import { MACOS_DEFAULT_MESSAGE_TEXT_SIZE_PX, } from '../config'; import { IS_IOS, IS_MAC_OS } from '../util/browser/windowEnvironment'; +import { DEFAULT_APP_CONFIG } from '../limits'; export const INITIAL_PERFORMANCE_STATE_MAX: PerformanceType = { animatedEmoji: true, @@ -101,6 +102,7 @@ export const INITIAL_GLOBAL_STATE: GlobalState = { isAppUpdateAvailable: false, isElectronUpdateAvailable: false, shouldShowContextMenuHint: true, + appConfig: DEFAULT_APP_CONFIG, audioPlayer: { lastPlaybackRate: DEFAULT_PLAYBACK_RATE, diff --git a/src/global/reducers/stories.ts b/src/global/reducers/stories.ts index f496de2bc..590d93aac 100644 --- a/src/global/reducers/stories.ts +++ b/src/global/reducers/stories.ts @@ -107,7 +107,7 @@ export function addStoriesForPeer( if (selectIsChatWithSelf(global, peerId) || selectUser(global, peerId)?.isContact - || peerId === global.appConfig?.storyChangelogUserId) { + || peerId === global.appConfig.storyChangelogUserId) { global = updatePeerLastUpdatedAt(global, peerId); global = updateOrderedStoriesPeerIds(global, [peerId]); } diff --git a/src/global/selectors/limits.ts b/src/global/selectors/limits.ts index 27238d4f0..a51758a72 100644 --- a/src/global/selectors/limits.ts +++ b/src/global/selectors/limits.ts @@ -1,17 +1,14 @@ import type { ApiLimitType } from '../../api/types'; import type { GlobalState } from '../types'; -import { DEFAULT_LIMITS } from '../../config'; +import { DEFAULT_LIMITS } from '../../limits'; import { selectIsCurrentUserPremium } from './users'; export function selectCurrentLimit(global: T, limit: ApiLimitType) { const { appConfig } = global; - if (!appConfig) { - return DEFAULT_LIMITS[limit][0]; - } + const { limits } = appConfig; const isPremium = selectIsCurrentUserPremium(global); - const { limits } = appConfig; // When there are new limits when updating a layer, until we get a new configuration, we must use the default values const value = limits[limit]?.[isPremium ? 1 : 0] ?? DEFAULT_LIMITS[limit][isPremium ? 1 : 0]; diff --git a/src/global/selectors/messages.ts b/src/global/selectors/messages.ts index e6a85f11c..74c7a2ea6 100644 --- a/src/global/selectors/messages.ts +++ b/src/global/selectors/messages.ts @@ -23,7 +23,7 @@ import type { import { ApiMessageEntityTypes, MAIN_THREAD_ID } from '../../api/types'; import { - ANONYMOUS_USER_ID, API_GENERAL_ID_LIMIT, GENERAL_TOPIC_ID, SERVICE_NOTIFICATIONS_USER_ID, + ANONYMOUS_USER_ID, GENERAL_TOPIC_ID, SERVICE_NOTIFICATIONS_USER_ID, SVG_EXTENSIONS, WEB_APP_PLATFORM, } from '../../config'; import { IS_TRANSLATION_SUPPORTED } from '../../util/browser/windowEnvironment'; @@ -34,6 +34,7 @@ import { getMessageKey, isLocalMessageId } from '../../util/keys/messageKey'; import { MEMO_EMPTY_ARRAY } from '../../util/memo'; import { getServerTime } from '../../util/serverTime'; import { getDocumentExtension } from '../../components/common/helpers/documentInfo'; +import { API_GENERAL_ID_LIMIT } from '../../limits'; import { canSendReaction, getAllowedAttachmentOptions, @@ -77,13 +78,14 @@ import { selectIsChatWithSelf, selectRequestedChatTranslationLanguage, } from './chats'; +import { selectCurrentLimit } from './limits'; import { selectPeer, selectPeerPaidMessagesStars } from './peers'; import { selectPeerStory } from './stories'; import { selectIsStickerFavorite } from './symbols'; import { selectTabState } from './tabs'; import { selectTopic } from './topics'; import { - selectBot, selectIsCurrentUserPremium, selectUser, selectUserStatus, + selectBot, selectUser, selectUserStatus, } from './users'; export function selectCurrentMessageList( @@ -1349,9 +1351,7 @@ export function selectDefaultReaction(global: T, chatId: } export function selectMaxUserReactions(global: T): number { - const isPremium = selectIsCurrentUserPremium(global); - const { maxUserReactionsPremium = 3, maxUserReactionsDefault = 1 } = global.appConfig || {}; - return isPremium ? maxUserReactionsPremium : maxUserReactionsDefault; + return selectCurrentLimit(global, 'maxReactions'); } // Slow, not to be used in `withGlobal` @@ -1580,7 +1580,7 @@ export function selectActiveRestrictionReasons( ): ApiRestrictionReason[] { if (!restrictionReasons) return []; - const { ignoreRestrictionReasons } = global.appConfig || {}; + const { ignoreRestrictionReasons } = global.appConfig; return restrictionReasons.filter((reason) => { const isForCurrentPlatform = reason.platform === 'all' || reason.platform === WEB_APP_PLATFORM; diff --git a/src/global/selectors/symbols.ts b/src/global/selectors/symbols.ts index 4ea6bcf4d..69aa3e237 100644 --- a/src/global/selectors/symbols.ts +++ b/src/global/selectors/symbols.ts @@ -167,14 +167,14 @@ export function selectAnimatedEmojiEffect(global: T, emoj } export function selectAnimatedEmojiSound(global: T, emoji: string) { - return global?.appConfig?.emojiSounds[cleanEmoji(emoji)]; + return global?.appConfig.emojiSounds[cleanEmoji(emoji)]; } export function selectIsAlwaysHighPriorityEmoji( global: T, stickerSet: ApiStickerSetInfo | ApiStickerSet, ) { if (!('id' in stickerSet)) return false; - return stickerSet.id === global.appConfig?.defaultEmojiStatusesStickerSetId + return stickerSet.id === global.appConfig.defaultEmojiStatusesStickerSetId || stickerSet.id === RESTRICTED_EMOJI_SET_ID; } diff --git a/src/global/selectors/users.ts b/src/global/selectors/users.ts index fcaad9f1f..1d1f252f6 100644 --- a/src/global/selectors/users.ts +++ b/src/global/selectors/users.ts @@ -36,15 +36,15 @@ export function selectIsCurrentUserPremium(global: T) { } export function selectIsCurrentUserFrozen(global: T) { - return Boolean(global.appConfig?.freezeUntilDate); + return Boolean(global.appConfig.freezeUntilDate); } export function selectIsPremiumPurchaseBlocked(global: T) { - return global.appConfig?.isPremiumPurchaseBlocked ?? true; + return global.appConfig.isPremiumPurchaseBlocked ?? true; } export function selectIsGiveawayGiftsPurchaseAvailable(global: T) { - return global.appConfig?.isGiveawayGiftsPurchaseAvailable ?? true; + return global.appConfig.isGiveawayGiftsPurchaseAvailable ?? true; } /** diff --git a/src/global/types/globalState.ts b/src/global/types/globalState.ts index 8214c33e5..6c7de0361 100644 --- a/src/global/types/globalState.ts +++ b/src/global/types/globalState.ts @@ -76,7 +76,7 @@ export type GlobalState = { cacheVersion: number; isInited: boolean; config?: ApiConfig; - appConfig?: ApiAppConfig; + appConfig: ApiAppConfig; peerColors?: ApiPeerColors; timezones?: { byId: Record; diff --git a/src/limits.ts b/src/limits.ts new file mode 100644 index 000000000..e1c572ed4 --- /dev/null +++ b/src/limits.ts @@ -0,0 +1,161 @@ +import type { ApiAppConfig, ApiLimitType } from './api/types'; + +import { MULTIACCOUNT_MAX_SLOTS } from './config'; + +export const MAX_UNIQUE_REACTIONS = 11; +export const GROUP_CALL_PARTICIPANTS_LIMIT = 100; +export const STORY_LIST_LIMIT = 100; +export const API_GENERAL_ID_LIMIT = 100; +export const RESALE_GIFTS_LIMIT = 50; +export const PINNED_MESSAGES_LIMIT = 50; +export const BLOCKED_LIST_LIMIT = 100; +export const GLOBAL_SEARCH_CONTACTS_LIMIT = 20; + +// As in Telegram for Android +// https://github.com/DrKLO/Telegram/blob/51e9947527/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java#L7799 +export const TOP_REACTIONS_LIMIT = 100; +export const RECENT_REACTIONS_LIMIT = 50; +export const REACTION_LIST_LIMIT = 100; + +export const DEFAULT_LIMITS: Record = { + uploadMaxFileparts: [4000, 8000], + stickersFaved: [5, 10], + savedGifs: [200, 400], + dialogFiltersChats: [100, 200], + dialogFilters: [10, 20], + dialogFolderPinned: [5, 10], + captionLength: [1024, 4096], + channels: [500, 1000], + channelsPublic: [10, 20], + aboutLength: [70, 140], + chatlistInvites: [3, 100], + chatlistJoined: [2, 20], + recommendedChannels: [10, 100], + savedDialogsPinned: [5, 100], + maxReactions: [1, 3], + moreAccounts: [3, MULTIACCOUNT_MAX_SLOTS], +}; + +export const DEFAULT_MAX_MESSAGE_LENGTH = 4096; + +export const DEFAULT_APP_CONFIG: ApiAppConfig = { + hash: 0, + limits: { + uploadMaxFileparts: DEFAULT_LIMITS.uploadMaxFileparts, + stickersFaved: DEFAULT_LIMITS.stickersFaved, + savedGifs: DEFAULT_LIMITS.savedGifs, + dialogFiltersChats: DEFAULT_LIMITS.dialogFiltersChats, + dialogFilters: DEFAULT_LIMITS.dialogFilters, + dialogFolderPinned: DEFAULT_LIMITS.dialogFolderPinned, + captionLength: DEFAULT_LIMITS.captionLength, + channels: DEFAULT_LIMITS.channels, + channelsPublic: DEFAULT_LIMITS.channelsPublic, + aboutLength: DEFAULT_LIMITS.aboutLength, + chatlistInvites: DEFAULT_LIMITS.chatlistInvites, + chatlistJoined: DEFAULT_LIMITS.chatlistJoined, + recommendedChannels: DEFAULT_LIMITS.recommendedChannels, + savedDialogsPinned: DEFAULT_LIMITS.savedDialogsPinned, + moreAccounts: DEFAULT_LIMITS.moreAccounts, + maxReactions: DEFAULT_LIMITS.maxReactions, + }, + canDisplayAutoarchiveSetting: true, + autologinDomains: [ + 'instantview.telegram.org', + 'translations.telegram.org', + 'contest.dev', + 'contest.com', + 'bugs.telegram.org', + 'suggestions.telegram.org', + 'themes.telegram.org', + 'promote.telegram.org', + 'ads.telegram.org', + ], + channelLevelMax: 100, + boostsPerSentGift: 3, + channelRestrictAdsLevelMin: 50, + seenByExpiresAt: 604800, + seenByMaxChatMembers: 100, + defaultEmojiStatusesStickerSetId: '773947703670341676', + emojiSounds: {}, + giveawayAddPeersMax: 10, + giveawayBoostsPerPremium: 4, + giveawayCountriesMax: 10, + isGiveawayGiftsPurchaseAvailable: false, + groupTranscribeLevelMin: 6, + hiddenMembersMinCount: 100, + ignoreRestrictionReasons: [], + canLimitNewMessagesWithoutPremium: false, + readDateExpiresAt: 604800, + premiumBotUsername: 'PremiumBot', + premiumInvoiceSlug: 'abc', + premiumPromoOrder: [ + 'stories', + 'more_upload', + 'double_limits', + // 'business', + 'last_seen', + 'voice_to_text', + 'faster_download', + 'translations', + 'animated_emoji', + 'emoji_status', + 'saved_tags', + // 'peer_colors', + // 'wallpapers', + 'profile_badge', + 'message_privacy', + 'advanced_chat_management', + 'no_ads', + // 'app_icons', + 'infinite_reactions', + 'animated_userpics', + 'premium_stickers', + 'effects', + ], + isPremiumPurchaseBlocked: false, + maxUniqueReactions: 11, + starGiftMaxConvertPeriod: 7776000, + starGiftMaxMessageLength: 255, + starRefStartPrefixes: [ + '_tgr_', + ], + isStarsGiftEnabled: true, + paidReactionMaxAmount: 2500, + starsUsdWithdrawRateX1000: 1300, + storyChangelogUserId: '777000', + maxPinnedStoriesCount: 3, + starsSuggestedPostAmountMax: 100000, + starsSuggestedPostAmountMin: 5, + starsSuggestedPostAgeMin: 86400, + starsSuggestedPostFutureMin: 300, + starsSuggestedPostFutureMax: 2678400, + starsSuggestedPostCommissionPermille: 850, + tonSuggestedPostCommissionPermille: 850, + todoItemLengthMax: 64, + todoItemsMax: 30, + todoTitleLengthMax: 32, + tonSuggestedPostAmountMax: 10000000000000, + tonSuggestedPostAmountMin: 10000000, + tonTopupUrl: 'https://fragment.com/ads/topup', + storyViewersExpirePeriod: 86400, + topicsPinnedLimit: 5, + bandwidthPremiumDownloadSpeedup: 10, + bandwidthPremiumNotifyPeriod: 3600, + bandwidthPremiumUploadSpeedup: 10, + urlAuthDomains: [ + 'web.telegram.org', + 'web.t.me', + 'k.t.me', + 'z.t.me', + 'a.t.me', + ], + whitelistedDomains: [ + 'telegram.dog', + 'telegram.me', + 'telegram.org', + 't.me', + 'telesco.pe', + 'fragment.com', + 'translations.telegram.org', + ], +};