diff --git a/src/assets/localization/fallback.strings b/src/assets/localization/fallback.strings index 996ba6592..bd6858368 100644 --- a/src/assets/localization/fallback.strings +++ b/src/assets/localization/fallback.strings @@ -2142,9 +2142,9 @@ "TonModalHint" = "You can top-up your TON using Fragment."; "TonGiftReceived" = "TON Top-Up"; "MediaSpoilerSensitive" = "18+"; -"TitleSensitiveModal" = "18+ content"; +"TitleSensitiveModal" = "{years}+ content"; "TextSensitiveModal" = "This media may contain sensitive content suitable only for adults. Do you still want to view it?"; -"ButtonSensitiveAlways" = "Always show 18+ media"; +"ButtonSensitiveAlways" = "Always show {years}+ media"; "ButtonSensitiveView" = "View Anyway"; "TitleAgeVerificationModal" = "Age Verification"; "TextAgeVerificationModal_one" = "To access such content, you must confirm that you are at least **{count}** year old as required by UK law."; diff --git a/src/components/common/SensitiveContentConfirmModal.tsx b/src/components/common/SensitiveContentConfirmModal.tsx index 0788b0fe5..becca1541 100644 --- a/src/components/common/SensitiveContentConfirmModal.tsx +++ b/src/components/common/SensitiveContentConfirmModal.tsx @@ -1,5 +1,7 @@ -import type { FC } from '../../lib/teact/teact'; import { memo } from '../../lib/teact/teact'; +import { withGlobal } from '../../global'; + +import { VERIFY_AGE_MIN_DEFAULT } from '../../config'; import useLang from '../../hooks/useLang'; @@ -16,18 +18,23 @@ type OwnProps = { confirmHandler: NoneToVoidFunction; }; -const SensitiveContentConfirmModal: FC = ({ +type StateProps = { + verifyAgeMin: number; +}; + +const SensitiveContentConfirmModal = ({ isOpen, onClose, shouldAlwaysShow, onAlwaysShowChanged, confirmHandler, -}) => { + verifyAgeMin, +}: OwnProps & StateProps) => { const lang = useLang(); return ( = ({ {lang('TextSensitiveModal')} @@ -44,4 +51,11 @@ const SensitiveContentConfirmModal: FC = ({ ); }; -export default memo(SensitiveContentConfirmModal); +export default memo(withGlobal((global): StateProps => { + const appConfig = global.appConfig; + const verifyAgeMin = appConfig?.verifyAgeMin; + + return { + verifyAgeMin: verifyAgeMin || VERIFY_AGE_MIN_DEFAULT, + }; +})(SensitiveContentConfirmModal)); diff --git a/src/components/modals/ageVerification/AgeVerificationModal.tsx b/src/components/modals/ageVerification/AgeVerificationModal.tsx index 0804a4659..c5b9a474b 100644 --- a/src/components/modals/ageVerification/AgeVerificationModal.tsx +++ b/src/components/modals/ageVerification/AgeVerificationModal.tsx @@ -4,6 +4,8 @@ import { getActions, withGlobal } from '../../../global'; import type { TabState } from '../../../global/types'; +import { VERIFY_AGE_MIN_DEFAULT } from '../../../config'; + import useLang from '../../../hooks/useLang'; import useLastCallback from '../../../hooks/useLastCallback'; @@ -19,18 +21,17 @@ export type OwnProps = { type StateProps = { verifyAgeBotUsername?: string; + verifyAgeMin: number; }; -const AGE_REQUIRED = 18; - const AgeVerificationModal: FC = ({ modal, verifyAgeBotUsername, + verifyAgeMin, }) => { const { closeAgeVerificationModal, openChatByUsername } = getActions(); const lang = useLang(); const isOpen = Boolean(modal); - const ageRequired = AGE_REQUIRED; const handleVerifyAge = useLastCallback(() => { if (verifyAgeBotUsername) { @@ -62,10 +63,10 @@ const AgeVerificationModal: FC = ({ {lang('TitleAgeVerificationModal')}

- {lang('TextAgeVerificationModal', { count: ageRequired }, { + {lang('TextAgeVerificationModal', { count: verifyAgeMin }, { withMarkdown: true, withNodes: true, - pluralValue: ageRequired, + pluralValue: verifyAgeMin, })}

@@ -86,8 +87,10 @@ 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; return { verifyAgeBotUsername, + verifyAgeMin, }; })(AgeVerificationModal)); diff --git a/src/components/modals/webApp/hooks/useWebAppFrame.ts b/src/components/modals/webApp/hooks/useWebAppFrame.ts index 14fee0f50..99d85ca12 100644 --- a/src/components/modals/webApp/hooks/useWebAppFrame.ts +++ b/src/components/modals/webApp/hooks/useWebAppFrame.ts @@ -1,9 +1,10 @@ import type { ElementRef } from '../../../../lib/teact/teact'; import { useCallback, useEffect, useRef } from '../../../../lib/teact/teact'; -import { getActions } from '../../../../global'; +import { getActions, getGlobal } from '../../../../global'; import type { WebApp, WebAppInboundEvent, WebAppOutboundEvent } from '../../../../types/webapp'; +import { VERIFY_AGE_MIN_DEFAULT } from '../../../../config'; import { getWebAppKey } from '../../../../global/helpers'; import { extractCurrentThemeParams } from '../../../../util/themeStyle'; import { REM } from '../../../common/helpers/mediaDimensions'; @@ -385,8 +386,10 @@ const useWebAppFrame = ( if (eventType === 'web_app_verify_age') { const { passed } = eventData; + const minAge = getGlobal().appConfig?.verifyAgeMin || VERIFY_AGE_MIN_DEFAULT; + const ageFromParam = eventData.age || 0; - if (passed) { + if (passed && ageFromParam >= minAge) { showNotification({ message: { key: 'TitleAgeCheckSuccess', diff --git a/src/config.ts b/src/config.ts index ebf751318..699a80c85 100644 --- a/src/config.ts +++ b/src/config.ts @@ -120,6 +120,7 @@ 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 diff --git a/src/global/actions/api/chats.ts b/src/global/actions/api/chats.ts index 2f97a4334..b51c8b8b6 100644 --- a/src/global/actions/api/chats.ts +++ b/src/global/actions/api/chats.ts @@ -1667,10 +1667,10 @@ addActionHandler('openChatByUsername', async (global, actions, payload): Promise const chatByUsername = await fetchChatByUsername(global, username); global = getGlobal(); const user = chatByUsername && selectUser(global, chatByUsername.id); - if (!chatByUsername || !chat || !user?.hasMainMiniApp) return; + if (!chatByUsername || !user?.hasMainMiniApp) return; actions.requestMainWebView({ botId: chatByUsername.id, - peerId: chat.id, + peerId: chat?.id || chatByUsername.id, theme, startParam: startApp, mode, diff --git a/src/types/language.d.ts b/src/types/language.d.ts index cf8beb086..e96de38ae 100644 --- a/src/types/language.d.ts +++ b/src/types/language.d.ts @@ -1601,9 +1601,7 @@ export interface LangPair { 'TonModalHint': undefined; 'TonGiftReceived': undefined; 'MediaSpoilerSensitive': undefined; - 'TitleSensitiveModal': undefined; 'TextSensitiveModal': undefined; - 'ButtonSensitiveAlways': undefined; 'ButtonSensitiveView': undefined; 'TitleAgeVerificationModal': undefined; 'DescriptionAgeVerificationModal': undefined; @@ -2781,6 +2779,12 @@ export interface LangPairWithVariables { 'number': V; 'owner': V; }; + 'TitleSensitiveModal': { + 'years': V; + }; + 'ButtonSensitiveAlways': { + 'years': V; + }; } export interface LangPairPlural {