Updated on 2026-08-14
This commit is contained in:
commit
0470e1f010
1144 changed files with 48463 additions and 11166 deletions
|
|
@ -13,7 +13,7 @@ object SupportedLanguages {
|
|||
const val CHINESE = "zh"
|
||||
const val SPANISH = "es"
|
||||
|
||||
val supportedLangugeCodes = listOf(
|
||||
val supportedLanguageCodes = listOf(
|
||||
ENGLISH,
|
||||
RUSSIAN,
|
||||
GERMAN,
|
||||
|
|
@ -25,10 +25,17 @@ object SupportedLanguages {
|
|||
SPANISH,
|
||||
)
|
||||
|
||||
/**
|
||||
* Returns the ISO 639-1 code of the device's current language when it belongs to
|
||||
* [supportedLanguageCodes], otherwise falls back to [ENGLISH].
|
||||
*
|
||||
* Intended for callers that need a plain two-letter language code (e.g. URL path segments
|
||||
* like `tangem.com/{en|ru}/...`).
|
||||
*/
|
||||
fun getCurrentSupportedLanguageCode(): String {
|
||||
val locale = Locale.getDefault()
|
||||
|
||||
return if (supportedLangugeCodes.contains(locale.language)) {
|
||||
return if (supportedLanguageCodes.contains(locale.language)) {
|
||||
locale.language
|
||||
} else {
|
||||
ENGLISH
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
package com.tangem.utils
|
||||
|
||||
import java.util.Locale
|
||||
|
||||
@Deprecated("Use TangemBlogUrlBuilder from common module")
|
||||
object TangemBlogUrlBuilder {
|
||||
|
||||
private const val RU_LOCALE = "ru"
|
||||
private const val EN_LOCALE = "en"
|
||||
|
||||
private const val TANGEM_MAIN = "https://tangem.com/"
|
||||
|
||||
val FEE_BLOG_LINK: String
|
||||
get(): String {
|
||||
val locale = if (Locale.getDefault().language == RU_LOCALE) RU_LOCALE else EN_LOCALE
|
||||
return buildString {
|
||||
append(TANGEM_MAIN)
|
||||
append(locale)
|
||||
append("/blog/post/what-is-a-transaction-fee-and-why-do-we-need-it/")
|
||||
}
|
||||
}
|
||||
|
||||
const val RESOURCE_TO_LEARN_ABOUT_APPROVING_IN_SWAP = "https://tangem.com/en/blog/post/give-revoke-permission/"
|
||||
|
||||
const val YIELD_SUPPLY_HOW_IT_WORKS_URL = "https://tangem.com/en/blog/post/yield-mode"
|
||||
const val YIELD_SUPPLY_TOS_URL = "https://aave.com/terms-of-service"
|
||||
const val YIELD_SUPPLY_PRIVACY_URL = "https://aave.com/privacy-policy"
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.tangem.utils.annotations
|
||||
|
||||
/**
|
||||
* Marks code that should be removed when the specified feature toggle is cleaned up
|
||||
* by the `/cleanup-feature-toggles` skill.
|
||||
*
|
||||
* @property toggleName the name of the feature toggle (e.g., "GASLESS_APPROVAL_ENABLED")
|
||||
* @property description optional description of what should be done during cleanup
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Target(
|
||||
AnnotationTarget.CLASS,
|
||||
AnnotationTarget.ANNOTATION_CLASS,
|
||||
AnnotationTarget.PROPERTY,
|
||||
AnnotationTarget.FIELD,
|
||||
AnnotationTarget.LOCAL_VARIABLE,
|
||||
AnnotationTarget.VALUE_PARAMETER,
|
||||
AnnotationTarget.CONSTRUCTOR,
|
||||
AnnotationTarget.FUNCTION,
|
||||
AnnotationTarget.PROPERTY_GETTER,
|
||||
AnnotationTarget.PROPERTY_SETTER,
|
||||
AnnotationTarget.TYPE,
|
||||
AnnotationTarget.EXPRESSION,
|
||||
AnnotationTarget.FILE,
|
||||
AnnotationTarget.TYPEALIAS,
|
||||
)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class RemoveWithToggle(
|
||||
val toggleName: String,
|
||||
val description: String = "",
|
||||
)
|
||||
|
|
@ -1,11 +1,44 @@
|
|||
package com.tangem.utils.info
|
||||
|
||||
/**
|
||||
* Runtime information about the host application and device.
|
||||
*
|
||||
* Consumed by API layers to populate request headers and bodies (see
|
||||
* `RequestHeader.AppVersionPlatformHeaders` and push-notification registration) and by feature
|
||||
* code that needs to branch on platform / vendor.
|
||||
*/
|
||||
interface AppInfoProvider {
|
||||
|
||||
/** Platform identifier, e.g. `"Android"`. */
|
||||
val platform: String
|
||||
|
||||
/** Human-readable device name in the form `"$MANUFACTURER $MODEL"`, e.g. `"Google Pixel 8"`. */
|
||||
val device: String
|
||||
|
||||
/** OS release string, e.g. `"14"` on Android 14. Corresponds to `Build.VERSION.RELEASE`. */
|
||||
val osVersion: String
|
||||
|
||||
/**
|
||||
* Android API level of the running system, e.g. `34` on Android 14. Corresponds to
|
||||
* `Build.VERSION.SDK_INT`. Use this (not [osVersion]) when branching by framework capability.
|
||||
*/
|
||||
val sdkVersion: Int
|
||||
|
||||
/** Current locale as a BCP 47 language tag (e.g. `"en-US"`, `"zh-CN"`). */
|
||||
val language: String
|
||||
|
||||
/** IANA time-zone id of the device's current time zone, e.g. `"Europe/Moscow"`, `"UTC"`. */
|
||||
val timezone: String
|
||||
|
||||
/** User-visible app version string (e.g. `"5.36.4"`), matching `BuildConfig.VERSION_NAME`. */
|
||||
val appVersion: String
|
||||
|
||||
/** Monotonically-increasing internal build number, matching `BuildConfig.VERSION_CODE`. */
|
||||
val appVersionCode: Int
|
||||
|
||||
/**
|
||||
* `true` if the device manufacturer or brand is Huawei. Used to gate features that depend on
|
||||
* Google Play Services (HMS-only devices cannot rely on FCM, Play Billing, etc.).
|
||||
*/
|
||||
val isHuaweiDevice: Boolean
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
package com.tangem.utils.version
|
||||
|
||||
interface AppVersionProvider {
|
||||
|
||||
val versionName: String
|
||||
|
||||
val versionCode: Int
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
package com.tangem.utils
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import java.util.Locale
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class SupportedLanguagesTest {
|
||||
|
||||
private lateinit var originalLocale: Locale
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
originalLocale = Locale.getDefault()
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
Locale.setDefault(originalLocale)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getCurrentSupportedLanguageCode returns primary language when locale is supported`() {
|
||||
// Arrange
|
||||
Locale.setDefault(Locale("en", "US"))
|
||||
|
||||
// Act
|
||||
val actual = SupportedLanguages.getCurrentSupportedLanguageCode()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isEqualTo("en")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getCurrentSupportedLanguageCode drops region for supported language`() {
|
||||
// Arrange
|
||||
Locale.setDefault(Locale("zh", "CN"))
|
||||
|
||||
// Act
|
||||
val actual = SupportedLanguages.getCurrentSupportedLanguageCode()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isEqualTo("zh")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getCurrentSupportedLanguageCode returns ENGLISH when locale is not supported`() {
|
||||
// Arrange — pt (Portuguese) is not in supportedLanguageCodes
|
||||
Locale.setDefault(Locale("pt", "BR"))
|
||||
|
||||
// Act
|
||||
val actual = SupportedLanguages.getCurrentSupportedLanguageCode()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isEqualTo(SupportedLanguages.ENGLISH)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getCurrentSupportedLanguageCode returns ENGLISH for empty language`() {
|
||||
// Arrange
|
||||
Locale.setDefault(Locale("", ""))
|
||||
|
||||
// Act
|
||||
val actual = SupportedLanguages.getCurrentSupportedLanguageCode()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isEqualTo(SupportedLanguages.ENGLISH)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getCurrentSupportedLanguageCode supports every code in supportedLanguageCodes`() {
|
||||
SupportedLanguages.supportedLanguageCodes.forEach { code ->
|
||||
// Arrange
|
||||
Locale.setDefault(Locale(code))
|
||||
|
||||
// Act
|
||||
val actual = SupportedLanguages.getCurrentSupportedLanguageCode()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isEqualTo(code)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `supportedLanguageCodes contains the expected nine ISO 639-1 codes`() {
|
||||
// Assert
|
||||
Truth.assertThat(SupportedLanguages.supportedLanguageCodes)
|
||||
.containsExactly("en", "ru", "de", "fr", "it", "ja", "uk", "zh", "es")
|
||||
.inOrder()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue