diff --git a/app/handlers/subscription.py b/app/handlers/subscription.py index 6622fa34..9454217b 100644 --- a/app/handlers/subscription.py +++ b/app/handlers/subscription.py @@ -1,9 +1,7 @@ -import base64 import json import logging from datetime import datetime, timedelta from typing import Dict, List, Any, Tuple, Optional -from urllib.parse import quote from aiogram import Dispatcher, types, F from aiogram.fsm.context import FSMContext @@ -5541,17 +5539,6 @@ async def handle_device_guide( return featured_app = next((app for app in apps if app.get('isFeatured', False)), apps[0]) - featured_app_id = featured_app.get('id') - other_apps = [ - app for app in apps - if isinstance(app, dict) and app.get('id') and app.get('id') != featured_app_id - ] - - other_app_names = ", ".join( - str(app.get('name')).strip() - for app in other_apps - if isinstance(app.get('name'), str) and app.get('name').strip() - ) if hide_subscription_link: link_section = ( @@ -5569,20 +5556,6 @@ async def handle_device_guide( + f"\n{subscription_link}\n\n" ) - installation_description = get_step_description(featured_app, "installationStep", db_user.language) - add_description = get_step_description(featured_app, "addSubscriptionStep", db_user.language) - connect_description = get_step_description(featured_app, "connectAndUseStep", db_user.language) - additional_before_text = format_additional_section( - featured_app.get("additionalBeforeAddSubscriptionStep"), - texts, - db_user.language, - ) - additional_after_text = format_additional_section( - featured_app.get("additionalAfterAddSubscriptionStep"), - texts, - db_user.language, - ) - guide_text = ( texts.t( "SUBSCRIPTION_DEVICE_GUIDE_TITLE", @@ -5593,36 +5566,17 @@ async def handle_device_guide( + texts.t( "SUBSCRIPTION_DEVICE_FEATURED_APP", "πŸ“‹ Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌΠΎΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅: {app_name}", - ).format(app_name=featured_app.get('name', '')) - ) - - if other_app_names: - guide_text += "\n\n" + texts.t( - "SUBSCRIPTION_DEVICE_OTHER_APPS", - "πŸ“¦ Π”Ρ€ΡƒΠ³ΠΈΠ΅ прилоТСния: {app_list}", - ).format(app_list=other_app_names) - guide_text += "\n" + texts.t( - "SUBSCRIPTION_DEVICE_OTHER_APPS_HINT", - "НаТмитС ΠΊΠ½ΠΎΠΏΠΊΡƒ \"Π”Ρ€ΡƒΠ³ΠΈΠ΅ прилоТСния\" Π½ΠΈΠΆΠ΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅.", - ) - - guide_text += "\n\n" + texts.t("SUBSCRIPTION_DEVICE_STEP_INSTALL_TITLE", "Π¨Π°Π³ 1 - Установка:") - if installation_description: - guide_text += f"\n{installation_description}" - - if additional_before_text: - guide_text += f"\n\n{additional_before_text}" - - guide_text += "\n\n" + texts.t("SUBSCRIPTION_DEVICE_STEP_ADD_TITLE", "Π¨Π°Π³ 2 - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ подписки:") - if add_description: - guide_text += f"\n{add_description}" - - guide_text += "\n\n" + texts.t("SUBSCRIPTION_DEVICE_STEP_CONNECT_TITLE", "Π¨Π°Π³ 3 - ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅:") - if connect_description: - guide_text += f"\n{connect_description}" - - guide_text += "\n\n" + texts.t("SUBSCRIPTION_DEVICE_HOW_TO_TITLE", "πŸ’‘ Как ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ:") - guide_text += "\n" + "\n".join( + ).format(app_name=featured_app['name']) + + "\n\n" + + texts.t("SUBSCRIPTION_DEVICE_STEP_INSTALL_TITLE", "Π¨Π°Π³ 1 - Установка:") + + f"\n{featured_app['installationStep']['description'][db_user.language]}\n\n" + + texts.t("SUBSCRIPTION_DEVICE_STEP_ADD_TITLE", "Π¨Π°Π³ 2 - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ подписки:") + + f"\n{featured_app['addSubscriptionStep']['description'][db_user.language]}\n\n" + + texts.t("SUBSCRIPTION_DEVICE_STEP_CONNECT_TITLE", "Π¨Π°Π³ 3 - ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅:") + + f"\n{featured_app['connectAndUseStep']['description'][db_user.language]}\n\n" + + texts.t("SUBSCRIPTION_DEVICE_HOW_TO_TITLE", "πŸ’‘ Как ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ:") + + "\n" + + "\n".join( [ texts.t( "SUBSCRIPTION_DEVICE_HOW_TO_STEP1", @@ -5630,7 +5584,7 @@ async def handle_device_guide( ), texts.t( "SUBSCRIPTION_DEVICE_HOW_TO_STEP2", - "2. НаТмитС ΠΊΠ½ΠΎΠΏΠΊΡƒ \"ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ\" Π½ΠΈΠΆΠ΅", + "2. Π‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠΉΡ‚Π΅ ссылку подписки (Π½Π°ΠΆΠΌΠΈΡ‚Π΅ Π½Π° Π½Π΅Ρ‘)", ), texts.t( "SUBSCRIPTION_DEVICE_HOW_TO_STEP3", @@ -5642,18 +5596,14 @@ async def handle_device_guide( ), ] ) - - if additional_after_text: - guide_text += f"\n\n{additional_after_text}" + ) await callback.message.edit_text( guide_text, reply_markup=get_connection_guide_keyboard( subscription_link, featured_app, - device_type, - db_user.language, - has_other_apps=bool(other_apps), + db_user.language ), parse_mode="HTML" ) @@ -5741,46 +5691,31 @@ async def handle_specific_app_guide( + f"\n{subscription_link}\n\n" ) - installation_description = get_step_description(app, "installationStep", db_user.language) - add_description = get_step_description(app, "addSubscriptionStep", db_user.language) - connect_description = get_step_description(app, "connectAndUseStep", db_user.language) - additional_before_text = format_additional_section( - app.get("additionalBeforeAddSubscriptionStep"), - texts, - db_user.language, - ) - additional_after_text = format_additional_section( - app.get("additionalAfterAddSubscriptionStep"), - texts, - db_user.language, - ) - guide_text = ( texts.t( "SUBSCRIPTION_SPECIFIC_APP_TITLE", "πŸ“± {app_name} - {device_name}", - ).format(app_name=app.get('name', ''), device_name=get_device_name(device_type, db_user.language)) + ).format(app_name=app['name'], device_name=get_device_name(device_type, db_user.language)) + "\n\n" + link_section + + texts.t("SUBSCRIPTION_DEVICE_STEP_INSTALL_TITLE", "Π¨Π°Π³ 1 - Установка:") + + f"\n{app['installationStep']['description'][db_user.language]}\n\n" + + texts.t("SUBSCRIPTION_DEVICE_STEP_ADD_TITLE", "Π¨Π°Π³ 2 - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ подписки:") + + f"\n{app['addSubscriptionStep']['description'][db_user.language]}\n\n" + + texts.t("SUBSCRIPTION_DEVICE_STEP_CONNECT_TITLE", "Π¨Π°Π³ 3 - ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅:") + + f"\n{app['connectAndUseStep']['description'][db_user.language]}" ) - guide_text += texts.t("SUBSCRIPTION_DEVICE_STEP_INSTALL_TITLE", "Π¨Π°Π³ 1 - Установка:") - if installation_description: - guide_text += f"\n{installation_description}" - - if additional_before_text: - guide_text += f"\n\n{additional_before_text}" - - guide_text += "\n\n" + texts.t("SUBSCRIPTION_DEVICE_STEP_ADD_TITLE", "Π¨Π°Π³ 2 - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ подписки:") - if add_description: - guide_text += f"\n{add_description}" - - guide_text += "\n\n" + texts.t("SUBSCRIPTION_DEVICE_STEP_CONNECT_TITLE", "Π¨Π°Π³ 3 - ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅:") - if connect_description: - guide_text += f"\n{connect_description}" - - if additional_after_text: - guide_text += f"\n\n{additional_after_text}" + if 'additionalAfterAddSubscriptionStep' in app: + additional = app['additionalAfterAddSubscriptionStep'] + guide_text += ( + "\n\n" + + texts.t( + "SUBSCRIPTION_ADDITIONAL_STEP_TITLE", + "{title}:", + ).format(title=additional['title'][db_user.language]) + + f"\n{additional['description'][db_user.language]}" + ) await callback.message.edit_text( guide_text, @@ -5923,119 +5858,14 @@ def load_app_config() -> Dict[str, Any]: config_path = settings.get_app_config_path() with open(config_path, 'r', encoding='utf-8') as f: - data = json.load(f) - if isinstance(data, dict): - return data - logger.error("НСкоррСктный Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ app-config.json: оТидаСтся ΠΎΠ±ΡŠΠ΅ΠΊΡ‚") + return json.load(f) except Exception as e: logger.error(f"Ошибка Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΊΠΎΠ½Ρ„ΠΈΠ³Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ: {e}") - - return {} - - -def get_localized_value(values: Any, language: str, default_language: str = "en") -> str: - if not isinstance(values, dict): - return "" - - candidates: List[str] = [] - normalized_language = (language or "").strip().lower() - - if normalized_language: - candidates.append(normalized_language) - if "-" in normalized_language: - candidates.append(normalized_language.split("-")[0]) - - default_language = (default_language or "").strip().lower() - if default_language and default_language not in candidates: - candidates.append(default_language) - - for candidate in candidates: - if not candidate: - continue - value = values.get(candidate) - if isinstance(value, str) and value.strip(): - return value - - for value in values.values(): - if isinstance(value, str) and value.strip(): - return value - - return "" - - -def get_step_description(app: Dict[str, Any], step_key: str, language: str) -> str: - if not isinstance(app, dict): - return "" - - step = app.get(step_key) - if not isinstance(step, dict): - return "" - - description = step.get("description") - return get_localized_value(description, language) - - -def format_additional_section(additional: Any, texts, language: str) -> str: - if not isinstance(additional, dict): - return "" - - title = get_localized_value(additional.get("title"), language) - description = get_localized_value(additional.get("description"), language) - - parts: List[str] = [] - - if title: - parts.append( - texts.t( - "SUBSCRIPTION_ADDITIONAL_STEP_TITLE", - "{title}:", - ).format(title=title) - ) - - if description: - parts.append(description) - - return "\n".join(parts) - - -def build_redirect_link(target_link: Optional[str], template: Optional[str]) -> Optional[str]: - if not target_link or not template: - return None - - normalized_target = str(target_link).strip() - normalized_template = str(template).strip() - - if not normalized_target or not normalized_template: - return None - - encoded_target = quote(normalized_target, safe="") - result = normalized_template - replaced = False - - replacements = [ - ("{subscription_link}", encoded_target), - ("{link}", encoded_target), - ("{subscription_link_raw}", normalized_target), - ("{link_raw}", normalized_target), - ] - - for placeholder, replacement in replacements: - if placeholder in result: - result = result.replace(placeholder, replacement) - replaced = True - - if not replaced: - result = f"{result}{encoded_target}" - - return result + return {} def get_apps_for_device(device_type: str, language: str = "ru") -> List[Dict[str, Any]]: - config = load_app_config() - platforms = config.get("platforms", {}) if isinstance(config, dict) else {} - - if not isinstance(platforms, dict): - return [] + config = load_app_config()['platforms'] device_mapping = { 'ios': 'ios', @@ -6046,49 +5876,32 @@ def get_apps_for_device(device_type: str, language: str = "ru") -> List[Dict[str } config_key = device_mapping.get(device_type, device_type) - apps = platforms.get(config_key, []) - return apps if isinstance(apps, list) else [] + return config.get(config_key, []) def get_device_name(device_type: str, language: str = "ru") -> str: - names = { - 'ios': 'iPhone/iPad', - 'android': 'Android', - 'windows': 'Windows', - 'mac': 'macOS', - 'tv': 'Android TV' - } + if language == "en": + names = { + 'ios': 'iPhone/iPad', + 'android': 'Android', + 'windows': 'Windows', + 'mac': 'macOS', + 'tv': 'Android TV' + } + else: + names = { + 'ios': 'iPhone/iPad', + 'android': 'Android', + 'windows': 'Windows', + 'mac': 'macOS', + 'tv': 'Android TV' + } return names.get(device_type, device_type) -def create_deep_link(app: Dict[str, Any], subscription_url: str) -> Optional[str]: - if not subscription_url: - return None - - if not isinstance(app, dict): - return subscription_url - - scheme = str(app.get("urlScheme", "")).strip() - payload = subscription_url - - if app.get("isNeedBase64Encoding"): - try: - payload = base64.b64encode(subscription_url.encode("utf-8")).decode("utf-8") - except Exception as exc: - logger.warning( - "НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ссылку подписки Π² base64 для прилоТСния %s: %s", - app.get("id"), - exc, - ) - payload = subscription_url - - scheme_link = f"{scheme}{payload}" if scheme else None - - template = settings.get_happ_cryptolink_redirect_template() - redirect_link = build_redirect_link(scheme_link, template) if scheme_link and template else None - - return redirect_link or scheme_link or subscription_url +def create_deep_link(app: Dict[str, Any], subscription_url: str) -> str: + return subscription_url def get_reset_devices_confirm_keyboard(language: str = "ru") -> InlineKeyboardMarkup: diff --git a/app/keyboards/inline.py b/app/keyboards/inline.py index aec10d24..b6cb2212 100644 --- a/app/keyboards/inline.py +++ b/app/keyboards/inline.py @@ -17,64 +17,6 @@ import logging logger = logging.getLogger(__name__) - -def _get_localized_value(values, language: str, default_language: str = "en") -> str: - if not isinstance(values, dict): - return "" - - candidates = [] - normalized_language = (language or "").strip().lower() - - if normalized_language: - candidates.append(normalized_language) - if "-" in normalized_language: - candidates.append(normalized_language.split("-")[0]) - - default_language = (default_language or "").strip().lower() - if default_language and default_language not in candidates: - candidates.append(default_language) - - for candidate in candidates: - if not candidate: - continue - value = values.get(candidate) - if isinstance(value, str) and value.strip(): - return value - - for value in values.values(): - if isinstance(value, str) and value.strip(): - return value - - return "" - - -def _build_additional_buttons(additional_section, language: str) -> List[InlineKeyboardButton]: - if not isinstance(additional_section, dict): - return [] - - buttons = additional_section.get("buttons") - if not isinstance(buttons, list): - return [] - - localized_buttons: List[InlineKeyboardButton] = [] - - for button in buttons: - if not isinstance(button, dict): - continue - - button_text = _get_localized_value(button.get("buttonText"), language) - button_link = button.get("buttonLink") - - if not button_text or not button_link: - continue - - localized_buttons.append( - InlineKeyboardButton(text=button_text, url=button_link) - ) - - return localized_buttons - - _LANGUAGE_DISPLAY_NAMES = { "ru": "πŸ‡·πŸ‡Ί Русский", "en": "πŸ‡¬πŸ‡§ English", @@ -1622,80 +1564,42 @@ def get_device_selection_keyboard(language: str = DEFAULT_LANGUAGE) -> InlineKey def get_connection_guide_keyboard( - subscription_url: str, - app: dict, - device_type: str, - language: str = DEFAULT_LANGUAGE, - has_other_apps: bool = False, + subscription_url: str, + app: dict, + language: str = DEFAULT_LANGUAGE ) -> InlineKeyboardMarkup: from app.handlers.subscription import create_deep_link texts = get_texts(language) - + keyboard = [] - + if 'installationStep' in app and 'buttons' in app['installationStep']: app_buttons = [] for button in app['installationStep']['buttons']: - button_text = _get_localized_value(button.get('buttonText'), language) - button_link = button.get('buttonLink') - - if not button_text or not button_link: - continue - + button_text = button['buttonText'].get(language, button['buttonText']['en']) app_buttons.append( - InlineKeyboardButton(text=f"πŸ“₯ {button_text}", url=button_link) + InlineKeyboardButton(text=f"πŸ“₯ {button_text}", url=button['buttonLink']) ) if len(app_buttons) == 2: keyboard.append(app_buttons) app_buttons = [] - + if app_buttons: keyboard.append(app_buttons) - - additional_before_buttons = _build_additional_buttons( - app.get('additionalBeforeAddSubscriptionStep'), - language, - ) - - for button in additional_before_buttons: - keyboard.append([button]) - - connect_link = create_deep_link(app, subscription_url) - - if connect_link: - connect_button = InlineKeyboardButton( - text=texts.t("CONNECT_BUTTON", "πŸ”— ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ"), - url=connect_link, - ) - elif settings.is_happ_cryptolink_mode(): - connect_button = InlineKeyboardButton( - text=texts.t("CONNECT_BUTTON", "πŸ”— ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ"), + + if settings.is_happ_cryptolink_mode(): + copy_button = InlineKeyboardButton( + text=texts.t("COPY_SUBSCRIPTION_LINK", "πŸ“‹ Π‘ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ссылку подписки"), callback_data="open_subscription_link", ) else: - connect_button = InlineKeyboardButton( - text=texts.t("CONNECT_BUTTON", "πŸ”— ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ"), + copy_button = InlineKeyboardButton( + text=texts.t("COPY_SUBSCRIPTION_LINK", "πŸ“‹ Π‘ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ссылку подписки"), url=subscription_url, ) - keyboard.append([connect_button]) - - additional_after_buttons = _build_additional_buttons( - app.get('additionalAfterAddSubscriptionStep'), - language, - ) - - for button in additional_after_buttons: - keyboard.append([button]) - - if has_other_apps: - keyboard.append([ - InlineKeyboardButton( - text=texts.t("OTHER_APPS_BUTTON", "πŸ“‹ Π”Ρ€ΡƒΠ³ΠΈΠ΅ прилоТСния"), - callback_data=f"app_list_{device_type}", - ) - ]) - + keyboard.append([copy_button]) + keyboard.extend([ [ InlineKeyboardButton(text=texts.t("CHOOSE_ANOTHER_DEVICE", "πŸ“± Π’Ρ‹Π±Ρ€Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠ΅ устройство"), callback_data="subscription_connect") @@ -1748,64 +1652,43 @@ def get_specific_app_keyboard( ) -> InlineKeyboardMarkup: from app.handlers.subscription import create_deep_link texts = get_texts(language) - + keyboard = [] - + if 'installationStep' in app and 'buttons' in app['installationStep']: app_buttons = [] for button in app['installationStep']['buttons']: - button_text = _get_localized_value(button.get('buttonText'), language) - button_link = button.get('buttonLink') - - if not button_text or not button_link: - continue - + button_text = button['buttonText'].get(language, button['buttonText']['en']) app_buttons.append( - InlineKeyboardButton(text=f"πŸ“₯ {button_text}", url=button_link) + InlineKeyboardButton(text=f"πŸ“₯ {button_text}", url=button['buttonLink']) ) if len(app_buttons) == 2: keyboard.append(app_buttons) app_buttons = [] - + if app_buttons: keyboard.append(app_buttons) - - additional_before_buttons = _build_additional_buttons( - app.get('additionalBeforeAddSubscriptionStep'), - language, - ) - - for button in additional_before_buttons: - keyboard.append([button]) - - connect_link = create_deep_link(app, subscription_url) - - if connect_link: - connect_button = InlineKeyboardButton( - text=texts.t("CONNECT_BUTTON", "πŸ”— ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ"), - url=connect_link, - ) - elif settings.is_happ_cryptolink_mode(): - connect_button = InlineKeyboardButton( - text=texts.t("CONNECT_BUTTON", "πŸ”— ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ"), + + if settings.is_happ_cryptolink_mode(): + copy_button = InlineKeyboardButton( + text=texts.t("COPY_SUBSCRIPTION_LINK", "πŸ“‹ Π‘ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ссылку подписки"), callback_data="open_subscription_link", ) else: - connect_button = InlineKeyboardButton( - text=texts.t("CONNECT_BUTTON", "πŸ”— ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ"), + copy_button = InlineKeyboardButton( + text=texts.t("COPY_SUBSCRIPTION_LINK", "πŸ“‹ Π‘ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ссылку подписки"), url=subscription_url, ) - keyboard.append([connect_button]) - - additional_after_buttons = _build_additional_buttons( - app.get('additionalAfterAddSubscriptionStep'), - language, - ) - - for button in additional_after_buttons: - keyboard.append([button]) - + keyboard.append([copy_button]) + + if 'additionalAfterAddSubscriptionStep' in app and 'buttons' in app['additionalAfterAddSubscriptionStep']: + for button in app['additionalAfterAddSubscriptionStep']['buttons']: + button_text = button['buttonText'].get(language, button['buttonText']['en']) + keyboard.append([ + InlineKeyboardButton(text=button_text, url=button['buttonLink']) + ]) + keyboard.extend([ [ InlineKeyboardButton(text=texts.t("OTHER_APPS_BUTTON", "πŸ“‹ Π”Ρ€ΡƒΠ³ΠΈΠ΅ прилоТСния"), callback_data=f"app_list_{device_type}") diff --git a/app/localization/locales/en.json b/app/localization/locales/en.json index 4c10c0ec..8b1cdb3a 100644 --- a/app/localization/locales/en.json +++ b/app/localization/locales/en.json @@ -435,14 +435,12 @@ "SUBSCRIPTION_DEVICE_GUIDE_TITLE": "πŸ“± Setup for {device_name}", "SUBSCRIPTION_DEVICE_LINK_TITLE": "πŸ”— Subscription link:", "SUBSCRIPTION_DEVICE_FEATURED_APP": "πŸ“‹ Recommended app: {app_name}", - "SUBSCRIPTION_DEVICE_OTHER_APPS": "πŸ“¦ Other apps: {app_list}", - "SUBSCRIPTION_DEVICE_OTHER_APPS_HINT": "Tap the \"Other apps\" button below to choose another app.", "SUBSCRIPTION_DEVICE_STEP_INSTALL_TITLE": "Step 1 - Install:", "SUBSCRIPTION_DEVICE_STEP_ADD_TITLE": "Step 2 - Add subscription:", "SUBSCRIPTION_DEVICE_STEP_CONNECT_TITLE": "Step 3 - Connect:", "SUBSCRIPTION_DEVICE_HOW_TO_TITLE": "πŸ’‘ How to connect:", "SUBSCRIPTION_DEVICE_HOW_TO_STEP1": "1. Install the app from the link above", - "SUBSCRIPTION_DEVICE_HOW_TO_STEP2": "2. Tap the \"Connect\" button below", + "SUBSCRIPTION_DEVICE_HOW_TO_STEP2": "2. Copy the subscription link (tap on it)", "SUBSCRIPTION_DEVICE_HOW_TO_STEP3": "3. Open the app and paste the link", "SUBSCRIPTION_DEVICE_HOW_TO_STEP4": "4. Connect to a server", "SUBSCRIPTION_APPS_TITLE": "πŸ“± Apps for {device_name}", diff --git a/app/localization/locales/ru.json b/app/localization/locales/ru.json index 3eb90aae..ca6ba4fd 100644 --- a/app/localization/locales/ru.json +++ b/app/localization/locales/ru.json @@ -445,14 +445,12 @@ "SUBSCRIPTION_DEVICE_GUIDE_TITLE": "πŸ“± Настройка для {device_name}", "SUBSCRIPTION_DEVICE_LINK_TITLE": "πŸ”— Бсылка подписки:", "SUBSCRIPTION_DEVICE_FEATURED_APP": "πŸ“‹ Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌΠΎΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅: {app_name}", - "SUBSCRIPTION_DEVICE_OTHER_APPS": "πŸ“¦ Π”Ρ€ΡƒΠ³ΠΈΠ΅ прилоТСния: {app_list}", - "SUBSCRIPTION_DEVICE_OTHER_APPS_HINT": "НаТмитС ΠΊΠ½ΠΎΠΏΠΊΡƒ \"Π”Ρ€ΡƒΠ³ΠΈΠ΅ прилоТСния\" Π½ΠΈΠΆΠ΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅.", "SUBSCRIPTION_DEVICE_STEP_INSTALL_TITLE": "Π¨Π°Π³ 1 - Установка:", "SUBSCRIPTION_DEVICE_STEP_ADD_TITLE": "Π¨Π°Π³ 2 - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ подписки:", "SUBSCRIPTION_DEVICE_STEP_CONNECT_TITLE": "Π¨Π°Π³ 3 - ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅:", "SUBSCRIPTION_DEVICE_HOW_TO_TITLE": "πŸ’‘ Как ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ:", "SUBSCRIPTION_DEVICE_HOW_TO_STEP1": "1. УстановитС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ссылкС Π²Ρ‹ΡˆΠ΅", - "SUBSCRIPTION_DEVICE_HOW_TO_STEP2": "2. НаТмитС ΠΊΠ½ΠΎΠΏΠΊΡƒ \"ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ\" Π½ΠΈΠΆΠ΅", + "SUBSCRIPTION_DEVICE_HOW_TO_STEP2": "2. Π‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠΉΡ‚Π΅ ссылку подписки (Π½Π°ΠΆΠΌΠΈΡ‚Π΅ Π½Π° Π½Π΅Ρ‘)", "SUBSCRIPTION_DEVICE_HOW_TO_STEP3": "3. ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ Π²ΡΡ‚Π°Π²ΡŒΡ‚Π΅ ссылку", "SUBSCRIPTION_DEVICE_HOW_TO_STEP4": "4. ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ΡΡŒ ΠΊ сСрвСру", "SUBSCRIPTION_APPS_TITLE": "πŸ“± ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ для {device_name}", diff --git a/locales/en.json b/locales/en.json index 0114b186..e4b12469 100644 --- a/locales/en.json +++ b/locales/en.json @@ -475,14 +475,12 @@ "SUBSCRIPTION_HAPP_CRYPTOLINK_BLOCK": "
{crypto_link}
", "SUBSCRIPTION_DEVICE_LINK_TITLE": "πŸ”— Subscription link:", "SUBSCRIPTION_DEVICE_FEATURED_APP": "πŸ“‹ Recommended app: {app_name}", - "SUBSCRIPTION_DEVICE_OTHER_APPS": "πŸ“¦ Other apps: {app_list}", - "SUBSCRIPTION_DEVICE_OTHER_APPS_HINT": "Tap the \"Other apps\" button below to choose another app.", "SUBSCRIPTION_DEVICE_STEP_INSTALL_TITLE": "Step 1 - Install:", "SUBSCRIPTION_DEVICE_STEP_ADD_TITLE": "Step 2 - Add subscription:", "SUBSCRIPTION_DEVICE_STEP_CONNECT_TITLE": "Step 3 - Connect:", "SUBSCRIPTION_DEVICE_HOW_TO_TITLE": "πŸ’‘ How to connect:", "SUBSCRIPTION_DEVICE_HOW_TO_STEP1": "1. Install the app from the link above", - "SUBSCRIPTION_DEVICE_HOW_TO_STEP2": "2. Tap the \"Connect\" button below", + "SUBSCRIPTION_DEVICE_HOW_TO_STEP2": "2. Copy the subscription link (tap on it)", "SUBSCRIPTION_DEVICE_HOW_TO_STEP3": "3. Open the app and paste the link", "SUBSCRIPTION_DEVICE_HOW_TO_STEP4": "4. Connect to a server", "SUBSCRIPTION_APPS_TITLE": "πŸ“± Apps for {device_name}", diff --git a/locales/ru.json b/locales/ru.json index 5fe17fbb..31d2704e 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -477,14 +477,12 @@ "SUBSCRIPTION_HAPP_CRYPTOLINK_BLOCK": "
{crypto_link}
", "SUBSCRIPTION_DEVICE_LINK_TITLE": "πŸ”— Бсылка подписки:", "SUBSCRIPTION_DEVICE_FEATURED_APP": "πŸ“‹ Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌΠΎΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅: {app_name}", - "SUBSCRIPTION_DEVICE_OTHER_APPS": "πŸ“¦ Π”Ρ€ΡƒΠ³ΠΈΠ΅ прилоТСния: {app_list}", - "SUBSCRIPTION_DEVICE_OTHER_APPS_HINT": "НаТмитС ΠΊΠ½ΠΎΠΏΠΊΡƒ \"Π”Ρ€ΡƒΠ³ΠΈΠ΅ прилоТСния\" Π½ΠΈΠΆΠ΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅.", "SUBSCRIPTION_DEVICE_STEP_INSTALL_TITLE": "Π¨Π°Π³ 1 - Установка:", "SUBSCRIPTION_DEVICE_STEP_ADD_TITLE": "Π¨Π°Π³ 2 - Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ подписки:", "SUBSCRIPTION_DEVICE_STEP_CONNECT_TITLE": "Π¨Π°Π³ 3 - ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅:", "SUBSCRIPTION_DEVICE_HOW_TO_TITLE": "πŸ’‘ Как ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ:", "SUBSCRIPTION_DEVICE_HOW_TO_STEP1": "1. УстановитС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ссылкС Π²Ρ‹ΡˆΠ΅", - "SUBSCRIPTION_DEVICE_HOW_TO_STEP2": "2. НаТмитС ΠΊΠ½ΠΎΠΏΠΊΡƒ \"ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ\" Π½ΠΈΠΆΠ΅", + "SUBSCRIPTION_DEVICE_HOW_TO_STEP2": "2. Π‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠΉΡ‚Π΅ ссылку подписки (Π½Π°ΠΆΠΌΠΈΡ‚Π΅ Π½Π° Π½Π΅Ρ‘)", "SUBSCRIPTION_DEVICE_HOW_TO_STEP3": "3. ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ Π²ΡΡ‚Π°Π²ΡŒΡ‚Π΅ ссылку", "SUBSCRIPTION_DEVICE_HOW_TO_STEP4": "4. ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ΡΡŒ ΠΊ сСрвСру", "SUBSCRIPTION_APPS_TITLE": "πŸ“± ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ для {device_name}",