diff --git a/src/assets/localization/fallback.strings b/src/assets/localization/fallback.strings index 95e260671..cf78b4034 100644 --- a/src/assets/localization/fallback.strings +++ b/src/assets/localization/fallback.strings @@ -2885,6 +2885,5 @@ "TextShowLess" = "less"; "AiMessageEditorFrom" = "From"; "AiMessageEditorTo" = "To"; -"TranslationToneNeutral" = "Neutral"; "ButtonHelp" = "Help"; "UnofficialSecurityRisk" = "{peer} uses an unofficial Telegram client — messages to this user may be less secure."; diff --git a/src/components/modals/webApp/WebAppModalTabContent.tsx b/src/components/modals/webApp/WebAppModalTabContent.tsx index 86814aa8b..d6de1983b 100644 --- a/src/components/modals/webApp/WebAppModalTabContent.tsx +++ b/src/components/modals/webApp/WebAppModalTabContent.tsx @@ -275,6 +275,10 @@ const WebAppModalTabContent: FC = ({ return Boolean(text?.trim().length || iconCustomEmojiId); } + function getValidHexColor(color: string | undefined) { + return color && validateHexColor(color) ? color : undefined; + } + const isMainButtonVisible = isLoaded && mainButton?.isVisible && hasBottomButtonContent( mainButton.text, mainButton.iconCustomEmojiId, @@ -674,16 +678,21 @@ const WebAppModalTabContent: FC = ({ } if (eventType === 'web_app_set_background_color') { - setBackgroundColorFromEvent(validateHexColor(eventData.color) ? eventData.color : undefined); + const validColor = getValidHexColor(eventData.color); + if (validColor) setBackgroundColorFromEvent(validColor); } if (eventType === 'web_app_set_header_color') { + const validColor = getValidHexColor(eventData.color); const key = eventData.color_key; - setHeaderColorFromEvent(eventData.color || (key ? themeParams[key] : undefined)); + const fallback = key ? themeParams[key] : undefined; + const color = validColor || fallback; + if (color) setHeaderColorFromEvent(color); } if (eventType === 'web_app_set_bottom_bar_color') { - setBottomBarColor(eventData.color); + const color = getValidHexColor(eventData.color); + if (color) setBottomBarColor(color); } if (eventType === 'web_app_data_send') { @@ -696,33 +705,43 @@ const WebAppModalTabContent: FC = ({ } if (eventType === 'web_app_setup_main_button') { - const color = eventData.color; - const textColor = eventData.text_color; - setMainButton({ - isVisible: eventData.is_visible && hasBottomButtonContent(eventData.text, eventData.icon_custom_emoji_id), - isActive: eventData.is_active, - text: eventData.text, - color, - textColor, - isProgressVisible: eventData.is_progress_visible, - iconCustomEmojiId: eventData.icon_custom_emoji_id, - hasShineEffect: eventData.has_shine_effect, + setMainButton((prevButton) => { + const color = getValidHexColor(eventData.color) || prevButton?.color + || themeParams.button_color; + const textColor = getValidHexColor(eventData.text_color) || prevButton?.textColor + || themeParams.button_text_color; + + return { + isVisible: eventData.is_visible && hasBottomButtonContent(eventData.text, eventData.icon_custom_emoji_id), + isActive: eventData.is_active, + text: eventData.text, + color, + textColor, + isProgressVisible: eventData.is_progress_visible, + iconCustomEmojiId: eventData.icon_custom_emoji_id, + hasShineEffect: eventData.has_shine_effect, + }; }); } if (eventType === 'web_app_setup_secondary_button') { - const color = eventData.color; - const textColor = eventData.text_color; - setSecondaryButton({ - isVisible: eventData.is_visible && hasBottomButtonContent(eventData.text, eventData.icon_custom_emoji_id), - isActive: eventData.is_active, - text: eventData.text, - color, - textColor, - isProgressVisible: eventData.is_progress_visible, - iconCustomEmojiId: eventData.icon_custom_emoji_id, - hasShineEffect: eventData.has_shine_effect, - position: eventData.position, + setSecondaryButton((prevButton) => { + const color = getValidHexColor(eventData.color) || prevButton?.color + || themeParams.button_color; + const textColor = getValidHexColor(eventData.text_color) || prevButton?.textColor + || themeParams.button_text_color; + + return { + isVisible: eventData.is_visible && hasBottomButtonContent(eventData.text, eventData.icon_custom_emoji_id), + isActive: eventData.is_active, + text: eventData.text, + color, + textColor, + isProgressVisible: eventData.is_progress_visible, + iconCustomEmojiId: eventData.icon_custom_emoji_id, + hasShineEffect: eventData.has_shine_effect, + position: eventData.position, + }; }); } diff --git a/src/util/media/ipRevealingMedia.ts b/src/util/media/ipRevealingMedia.ts index 33da19c82..4b241bd04 100644 --- a/src/util/media/ipRevealingMedia.ts +++ b/src/util/media/ipRevealingMedia.ts @@ -1,17 +1,26 @@ import { SVG_EXTENSIONS } from '../../config'; const UNSAFE_MIME_TYPES = new Set(['text/html', 'image/svg+xml']); +const UNSAFE_MIME_SUBTYPES = new Set(['html', 'svg+xml', 'xhtml+xml', 'xml']); const UNSAFE_EXTENSIONS = new Set([ ...SVG_EXTENSIONS, 'htm', 'html', 'svg', 'm4v', 'm3u', 'm3u8', 'xhtml', 'xml', ]); export function isIpRevealingMedia({ mimeType, extension }: { mimeType?: string; extension: string }) { - if (mimeType && UNSAFE_MIME_TYPES.has(mimeType)) { + const normalizedMimeType = mimeType?.split(';')[0].trim().toLowerCase(); + const normalizedMimeSubtype = normalizedMimeType?.split('/').pop()?.trim(); + const normalizedExtension = extension.trim().toLowerCase(); + + if (normalizedMimeType && UNSAFE_MIME_TYPES.has(normalizedMimeType)) { return true; } - if (UNSAFE_EXTENSIONS.has(extension)) { + if (normalizedMimeSubtype && UNSAFE_MIME_SUBTYPES.has(normalizedMimeSubtype)) { + return true; + } + + if (UNSAFE_EXTENSIONS.has(normalizedExtension)) { return true; }