Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased (develop)

- added: Home screen long-press shortcut to contact support
- added: Home screen long-press shortcut warning about 2FA and credentials needed after uninstall
- added: Show swap KYC/terms modal for NExchange
- added: Nym mixnet warning in Stake, Unstake, and Claim Rewards scenes
- changed: Migrate Thorchain Savers and Thorchain Yield endpoints off NineRealms to gateway.liquify.com.
Expand Down
3 changes: 3 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="wc" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>

<!-- To disable the activity lifecycle breadcrumbs integration -->
Expand Down
46 changes: 46 additions & 0 deletions android/app/src/main/java/co/edgesecure/app/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package co.edgesecure.app

import android.content.ActivityNotFoundException
import android.content.Intent
import android.content.pm.ActivityInfo
import android.os.Build
import android.os.Bundle
Expand Down Expand Up @@ -38,6 +40,50 @@ class MainActivity : ReactActivity() {
if (resources.getBoolean(R.bool.portrait_only)) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}

if (maybeOpenInBrowser(intent)) {
intent.data = null
}
}

override fun onNewIntent(intent: Intent) {
if (!maybeOpenInBrowser(intent)) {
super.onNewIntent(intent)
}
}

/**
* Opens https/http URLs in the default browser when they aren't
* registered deep link hosts handled by React Native. This prevents
* shortcut intents from being misrouted through the deep link handler.
* Returns true if the URL was opened in the browser.
*/
private fun maybeOpenInBrowser(intent: Intent?): Boolean {
val data = intent?.data ?: return false
val scheme = data.scheme
if (scheme != "https" && scheme != "http") return false

val host = data.host
if (DEEP_LINK_HOSTS.contains(host)) return false

val browserIntent = Intent(Intent.ACTION_VIEW, data)
return try {
startActivity(browserIntent)
true
} catch (e: ActivityNotFoundException) {
false
}
}

companion object {
// Mirrors the https deep-link hosts declared in AndroidManifest.xml's
// <intent-filter android:autoVerify="true"> for MainActivity. Keep in
// sync when adding or removing deep-link hosts there.
private val DEEP_LINK_HOSTS = setOf(
"deep.edge.app",
"dl.edge.app",
"return.edge.app"
)
}
Comment on lines +78 to 87
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional / nit: DEEP_LINK_HOSTS is duplicated from AndroidManifest.xml lines 60–62 (deep.edge.app, dl.edge.app, return.edge.app).

If a new deep-link host is added to the manifest, this set must be updated too — with no compile-time check to catch a mismatch. Could be brittle as the deep-link surface evolves.

Suggestion (non-blocking): read the registered hosts at runtime from the manifest (e.g. via PackageManager.getActivityInfo(componentName, GET_INTENT_FILTERS) or an Android <string-array> resource referenced by both files), or at minimum add a brief comment here pointing readers at the manifest as the source of truth.


// Edge addition
Expand Down
6 changes: 6 additions & 0 deletions android/app/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<resources>
<string name="shortcut_do_not_uninstall_short">⚠️ 2FA sichern!</string>
<string name="shortcut_do_not_uninstall_long">⚠️ Login erfordert 2FA &amp; Zugangsdaten!</string>
<string name="shortcut_contact_support_short">Support anfragen</string>
<string name="shortcut_contact_support_long">Hilfe von unseren Live-Support-Mitarbeitern</string>
</resources>
6 changes: 6 additions & 0 deletions android/app/src/main/res/values-es-rMX/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<resources>
<string name="shortcut_do_not_uninstall_short">⚠️ ¡Guarda tu 2FA!</string>
<string name="shortcut_do_not_uninstall_long">⚠️ Inicio requiere 2FA y credenciales!</string>
<string name="shortcut_contact_support_short">Contactar ayuda</string>
<string name="shortcut_contact_support_long">Obtén ayuda de nuestros agentes en vivo</string>
</resources>
6 changes: 6 additions & 0 deletions android/app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<resources>
<string name="shortcut_do_not_uninstall_short">⚠️ ¡Guarda tu 2FA!</string>
<string name="shortcut_do_not_uninstall_long">⚠️ Inicio requiere 2FA y credenciales!</string>
<string name="shortcut_contact_support_short">Contactar ayuda</string>
<string name="shortcut_contact_support_long">Obtén ayuda de nuestros agentes en vivo</string>
</resources>
6 changes: 6 additions & 0 deletions android/app/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<resources>
<string name="shortcut_do_not_uninstall_short">⚠️ Sauvez le 2FA !</string>
<string name="shortcut_do_not_uninstall_long">⚠️ Connexion nécessite 2FA &amp; identifiants !</string>
<string name="shortcut_contact_support_short">Nous contacter</string>
<string name="shortcut_contact_support_long">Aide de nos agents de support en direct</string>
</resources>
6 changes: 6 additions & 0 deletions android/app/src/main/res/values-it/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<resources>
<string name="shortcut_do_not_uninstall_short">⚠️ Salva il 2FA!</string>
<string name="shortcut_do_not_uninstall_long">⚠️ Il login richiede 2FA &amp; credenziali!</string>
<string name="shortcut_contact_support_short">Contattaci</string>
<string name="shortcut_contact_support_long">Aiuto dai nostri agenti di supporto live</string>
</resources>
6 changes: 6 additions & 0 deletions android/app/src/main/res/values-ja/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<resources>
<string name="shortcut_do_not_uninstall_short">⚠️ 2FAを先に保存!</string>
<string name="shortcut_do_not_uninstall_long">⚠️ ログインには2FAと認証情報が必要です!</string>
<string name="shortcut_contact_support_short">サポートに連絡</string>
<string name="shortcut_contact_support_long">ライブサポートスタッフに相談する</string>
</resources>
6 changes: 6 additions & 0 deletions android/app/src/main/res/values-ko/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<resources>
<string name="shortcut_do_not_uninstall_short">⚠️ 2FA 먼저 저장!</string>
<string name="shortcut_do_not_uninstall_long">⚠️ 로그인에 2FA 및 자격 증명이 필요합니다!</string>
<string name="shortcut_contact_support_short">지원 문의</string>
<string name="shortcut_contact_support_long">실시간 지원 상담원에게 도움 받기</string>
</resources>
6 changes: 6 additions & 0 deletions android/app/src/main/res/values-pt/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<resources>
<string name="shortcut_do_not_uninstall_short">⚠️ Salve o 2FA!</string>
<string name="shortcut_do_not_uninstall_long">⚠️ Login requer 2FA &amp; credenciais!</string>
<string name="shortcut_contact_support_short">Contatar suporte</string>
<string name="shortcut_contact_support_long">Obtenha ajuda dos nossos agentes ao vivo</string>
</resources>
6 changes: 6 additions & 0 deletions android/app/src/main/res/values-ru/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<resources>
<string name="shortcut_do_not_uninstall_short">⚠️ Сохрани 2FA!</string>
<string name="shortcut_do_not_uninstall_long">⚠️ Для входа нужны 2FA &amp; учётные данные!</string>
<string name="shortcut_contact_support_short">Поддержка</string>
<string name="shortcut_contact_support_long">Помощь от наших агентов поддержки</string>
</resources>
6 changes: 6 additions & 0 deletions android/app/src/main/res/values-vi/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<resources>
<string name="shortcut_do_not_uninstall_short">⚠️ Lưu 2FA trước!</string>
<string name="shortcut_do_not_uninstall_long">⚠️ Đăng nhập cần 2FA &amp; mật khẩu!</string>
<string name="shortcut_contact_support_short">Liên hệ hỗ trợ</string>
<string name="shortcut_contact_support_long">Nhận hỗ trợ từ nhân viên trực tuyến</string>
</resources>
6 changes: 6 additions & 0 deletions android/app/src/main/res/values-zh/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<resources>
<string name="shortcut_do_not_uninstall_short">⚠️ 先保存2FA!</string>
<string name="shortcut_do_not_uninstall_long">⚠️ 登录需要2FA和凭证!</string>
<string name="shortcut_contact_support_short">联系客服</string>
<string name="shortcut_contact_support_long">从我们的在线客服获取帮助</string>
</resources>
4 changes: 4 additions & 0 deletions android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
<resources>
<string name="app_name">Edge</string>
<string name="shortcut_contact_support_short">Contact Support</string>
<string name="shortcut_contact_support_long">Get help from our live support agents</string>
<string name="shortcut_do_not_uninstall_short">⚠️ Save 2FA First!</string>
<string name="shortcut_do_not_uninstall_long">⚠️ Login requires 2FA &amp; credentials!</string>
</resources>
23 changes: 23 additions & 0 deletions android/app/src/main/res/xml/shortcuts.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
Comment thread
JP0P marked this conversation as resolved.
android:shortcutId="do_not_uninstall"
android:enabled="true"
android:icon="@android:drawable/ic_dialog_alert"
android:shortcutShortLabel="@string/shortcut_do_not_uninstall_short"
android:shortcutLongLabel="@string/shortcut_do_not_uninstall_long">
<intent
android:action="android.intent.action.VIEW"
android:data="https://support.edge.app/en/articles/14439418-warning-don-t-uninstall-edge-without-your-login-credentials" />
</shortcut>
<shortcut
android:shortcutId="contact_support"
android:enabled="true"
android:icon="@android:drawable/ic_menu_help"
android:shortcutShortLabel="@string/shortcut_contact_support_short"
android:shortcutLongLabel="@string/shortcut_contact_support_long">
<intent
android:action="android.intent.action.VIEW"
android:data="https://support.edge.app/en/articles/14054649-need-help-reach-out-via-our-chat-bubble?chat=open" />
</shortcut>
</shortcuts>
48 changes: 48 additions & 0 deletions ios/edge.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
BF115CD26A29F1C032E30289 /* Pods_edge.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E261C56FB78E202F218C2DCA /* Pods_edge.framework */; };
E469AC702DC43791006A2530 /* AdServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E469AC6F2DC43791006A2530 /* AdServices.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
F0A1B2C32E8A100000000001 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F0A1B2C32E8A100000000003 /* InfoPlist.strings */; };
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional / nit: Hand-crafted Xcode UUIDs.

The 12 new file references and the variant group use sequential identifiers (F0A1B2C32E8A100000000001F0A1B2C32E8A10000000001A) rather than randomly generated 24-char hex from Xcode. They're valid and work today, but:

  1. They depart from the rest of the file's pattern, so subsequent edits via Xcode will mix two styles.
  2. There is a small (extremely small) chance of a future collision if Xcode happens to generate a similar low-entropy ID.

Suggestion (non-blocking): open the project in Xcode and let it regenerate proper random IDs (drag the InfoPlist.strings variant group out and back in, or re-add the localizations through the Project → Info → Localizations panel). Not necessary for correctness.

/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand Down Expand Up @@ -87,6 +88,18 @@
E261C56FB78E202F218C2DCA /* Pods_edge.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_edge.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E469AC6F2DC43791006A2530 /* AdServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdServices.framework; path = System/Library/Frameworks/AdServices.framework; sourceTree = SDKROOT; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
F0A1B2C32E8A100000000002 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = edge/en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
F0A1B2C32E8A100000000010 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = edge/de.lproj/InfoPlist.strings; sourceTree = "<group>"; };
F0A1B2C32E8A100000000011 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = edge/es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
F0A1B2C32E8A100000000012 /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-MX"; path = "edge/es-MX.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
F0A1B2C32E8A100000000013 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = edge/fr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
F0A1B2C32E8A100000000014 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = edge/it.lproj/InfoPlist.strings; sourceTree = "<group>"; };
F0A1B2C32E8A100000000015 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = edge/ja.lproj/InfoPlist.strings; sourceTree = "<group>"; };
F0A1B2C32E8A100000000016 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = edge/ko.lproj/InfoPlist.strings; sourceTree = "<group>"; };
F0A1B2C32E8A100000000017 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = edge/pt.lproj/InfoPlist.strings; sourceTree = "<group>"; };
F0A1B2C32E8A100000000018 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = edge/ru.lproj/InfoPlist.strings; sourceTree = "<group>"; };
F0A1B2C32E8A100000000019 /* vi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vi; path = edge/vi.lproj/InfoPlist.strings; sourceTree = "<group>"; };
F0A1B2C32E8A10000000001A /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "edge/zh-Hans.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -110,6 +123,7 @@
3D5BD9892A4CF04C00590088 /* GoogleService-Info.plist */,
13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB61A68108700A75B9A /* Info.plist */,
F0A1B2C32E8A100000000003 /* InfoPlist.strings */,
3DB299A52BCEF2A600D867B0 /* PrivacyInfo.xcprivacy */,
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
);
Expand Down Expand Up @@ -265,6 +279,17 @@
knownRegions = (
en,
Base,
de,
es,
"es-MX",
fr,
it,
ja,
ko,
pt,
ru,
vi,
"zh-Hans",
);
mainGroup = 83CBB9F61A601CBA00E9B192;
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
Expand Down Expand Up @@ -308,6 +333,7 @@
3D5BD9C12A4D27C400590088 /* SourceSansPro-LightItalic.ttf in Resources */,
3D5BD9C22A4D27C400590088 /* SourceSansPro-BoldItalic.ttf in Resources */,
3D5BD9CF2A4D27F300590088 /* custom.ttf in Resources */,
F0A1B2C32E8A100000000001 /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -469,6 +495,28 @@
};
/* End PBXSourcesBuildPhase section */

/* Begin PBXVariantGroup section */
F0A1B2C32E8A100000000003 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
F0A1B2C32E8A100000000002 /* en */,
F0A1B2C32E8A100000000010 /* de */,
F0A1B2C32E8A100000000011 /* es */,
F0A1B2C32E8A100000000012 /* es-MX */,
F0A1B2C32E8A100000000013 /* fr */,
F0A1B2C32E8A100000000014 /* it */,
F0A1B2C32E8A100000000015 /* ja */,
F0A1B2C32E8A100000000016 /* ko */,
F0A1B2C32E8A100000000017 /* pt */,
F0A1B2C32E8A100000000018 /* ru */,
F0A1B2C32E8A100000000019 /* vi */,
F0A1B2C32E8A10000000001A /* zh-Hans */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */

/* Begin XCBuildConfiguration section */
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
Expand Down
37 changes: 36 additions & 1 deletion ios/edge/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import RNBootSplash
import React
import ReactAppDependencyProvider
import React_RCTAppDelegate
import Sentry
import UIKit
import UserNotifications

Expand Down Expand Up @@ -49,6 +50,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
let shortcutItem = launchOptions?[.shortcutItem] as? UIApplicationShortcutItem

// Initialize SDK's:
initializeSentry()
FirebaseApp.configure()
Expand All @@ -72,7 +75,39 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
launchOptions: launchOptions
)

return true
if let shortcutItem = shortcutItem {
_ = handleShortcutItem(shortcutItem)
}

// Returning false prevents the system from invoking
// application(_:performActionFor:completionHandler:) for the same
// shortcut after a cold launch, since we already handled it above.
return shortcutItem == nil
}

func application(
_ application: UIApplication,
performActionFor shortcutItem: UIApplicationShortcutItem,
completionHandler: @escaping (Bool) -> Void
) {
let handled = handleShortcutItem(shortcutItem)
completionHandler(handled)
}

private func handleShortcutItem(_ shortcutItem: UIApplicationShortcutItem) -> Bool {
guard let urlString = shortcutItem.userInfo?["url"] as? String,
let url = URL(string: urlString) else { return false }

Comment thread
JP0P marked this conversation as resolved.
if url.scheme == "https" || url.scheme == "http" {
UIApplication.shared.open(url, options: [:]) { success in
if !success {
SentrySDK.capture(message: "Failed to open shortcut URL: \(urlString)")
}
}
return true
}

return RCTLinkingManager.application(UIApplication.shared, open: url, options: [:])
}

/**
Expand Down
33 changes: 33 additions & 0 deletions ios/edge/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,39 @@
</array>
<key>CFBundleVersion</key>
<string>99999999</string>
<key>UIApplicationShortcutItems</key>
Comment thread
JP0P marked this conversation as resolved.
<array>
<dict>
<key>UIApplicationShortcutItemTitle</key>
<string>SHORTCUT_UNINSTALL_TITLE</string>
<key>UIApplicationShortcutItemSubtitle</key>
<string>SHORTCUT_UNINSTALL_SUBTITLE</string>
<key>UIApplicationShortcutItemIconSymbolName</key>
<string>nosign</string>
<key>UIApplicationShortcutItemType</key>
Comment thread
JP0P marked this conversation as resolved.
<string>co.edgesecure.app.do_not_uninstall</string>
<key>UIApplicationShortcutItemUserInfo</key>
<dict>
<key>url</key>
<string>https://support.edge.app/en/articles/14439418-warning-don-t-uninstall-edge-without-your-login-credentials</string>
</dict>
</dict>
<dict>
<key>UIApplicationShortcutItemTitle</key>
<string>SHORTCUT_SUPPORT_TITLE</string>
<key>UIApplicationShortcutItemSubtitle</key>
<string>SHORTCUT_SUPPORT_SUBTITLE</string>
<key>UIApplicationShortcutItemIconSymbolName</key>
<string>message.fill</string>
<key>UIApplicationShortcutItemType</key>
<string>co.edgesecure.app.contact_support</string>
<key>UIApplicationShortcutItemUserInfo</key>
<dict>
<key>url</key>
<string>https://support.edge.app/en/articles/14054649-need-help-reach-out-via-our-chat-bubble?chat=open</string>
</dict>
</dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>https</string>
Expand Down
4 changes: 4 additions & 0 deletions ios/edge/de.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"SHORTCUT_UNINSTALL_TITLE" = "⚠️ 2FA sichern!";
"SHORTCUT_UNINSTALL_SUBTITLE" = "Login erfordert 2FA & Zugangsdaten!";
"SHORTCUT_SUPPORT_TITLE" = "Support anfragen";
"SHORTCUT_SUPPORT_SUBTITLE" = "Hilfe von unseren Live-Support-Mitarbeitern";
7 changes: 7 additions & 0 deletions ios/edge/en.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* Home screen shortcut: uninstall warning */
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional / process question: This PR ships hand/AI-translated copy for 12 locales without going through Crowdin (which the repo normally uses for translations).

A few of the translations look like they would benefit from a real translator pass — e.g. Support kontakt. (DE, looks truncated), Связаться (RU, just "Contact" rather than "Contact Support"). It also creates a parallel translation pipeline that future shortcut additions will need to remember to update.

Suggestion (non-blocking): confirm with the team whether native shortcut strings should be added to Crowdin going forward, or formally accept this as a one-off carve-out and document it (e.g. in a brief note in the README or a comment in the .lproj files) so future contributors don't unknowingly let it drift.

"SHORTCUT_UNINSTALL_TITLE" = "⚠️ Save 2FA First!";
"SHORTCUT_UNINSTALL_SUBTITLE" = "Login requires 2FA & credentials!";

/* Home screen shortcut: contact support */
"SHORTCUT_SUPPORT_TITLE" = "Contact Support";
"SHORTCUT_SUPPORT_SUBTITLE" = "Get help from our live support agents";
4 changes: 4 additions & 0 deletions ios/edge/es-MX.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"SHORTCUT_UNINSTALL_TITLE" = "⚠️ ¡Guarda tu 2FA!";
"SHORTCUT_UNINSTALL_SUBTITLE" = "Inicio requiere 2FA y credenciales!";
"SHORTCUT_SUPPORT_TITLE" = "Contactar ayuda";
"SHORTCUT_SUPPORT_SUBTITLE" = "Obtén ayuda de nuestros agentes en vivo";
4 changes: 4 additions & 0 deletions ios/edge/es.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"SHORTCUT_UNINSTALL_TITLE" = "⚠️ ¡Guarda tu 2FA!";
"SHORTCUT_UNINSTALL_SUBTITLE" = "Inicio requiere 2FA y credenciales!";
"SHORTCUT_SUPPORT_TITLE" = "Contactar ayuda";
"SHORTCUT_SUPPORT_SUBTITLE" = "Obtén ayuda de nuestros agentes en vivo";
Loading
Loading