Skip to content

Commit d7ffafb

Browse files
feat: replace languages api with languages from distribution (#330)
1 parent 65245eb commit d7ffafb

23 files changed

Lines changed: 383 additions & 230 deletions

crowdin/src/main/java/com/crowdin/platform/Crowdin.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ import com.crowdin.platform.data.model.ApiAuthConfig
1717
import com.crowdin.platform.data.model.AuthConfig
1818
import com.crowdin.platform.data.model.AuthInfo
1919
import com.crowdin.platform.data.model.LanguageData
20-
import com.crowdin.platform.data.model.LanguagesInfo
2120
import com.crowdin.platform.data.model.ManifestData
21+
import com.crowdin.platform.data.model.SupportedLanguages
2222
import com.crowdin.platform.data.parser.StringResourceParser
2323
import com.crowdin.platform.data.parser.XmlReader
2424
import com.crowdin.platform.data.remote.Connectivity
@@ -565,7 +565,12 @@ object Crowdin {
565565

566566
fun getManifest(): ManifestData? = dataManager?.getManifest()
567567

568-
fun getSupportedLanguages(): LanguagesInfo? = dataManager?.getSupportedLanguages()
568+
/**
569+
* Get all supported languages from the distribution.
570+
* @return Map where key is language code and value contains language details (name, locale).
571+
* Example: `{"de": LanguageDetails("German", "de-DE"), "it": LanguageDetails("Italian", "it-IT")}`
572+
*/
573+
fun getSupportedLanguages(): SupportedLanguages? = dataManager?.getSupportedLanguages()
569574

570575
private fun initDistributionInfo() {
571576
if (config.apiAuthConfig?.apiToken == null) {

crowdin/src/main/java/com/crowdin/platform/data/DataManager.kt

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ import com.crowdin.platform.Preferences
1010
import com.crowdin.platform.data.local.LocalRepository
1111
import com.crowdin.platform.data.model.ArrayData
1212
import com.crowdin.platform.data.model.AuthInfo
13+
import com.crowdin.platform.data.model.CachedLanguages
1314
import com.crowdin.platform.data.model.LanguageData
14-
import com.crowdin.platform.data.model.LanguagesInfo
1515
import com.crowdin.platform.data.model.ManifestData
1616
import com.crowdin.platform.data.model.PluralData
1717
import com.crowdin.platform.data.model.StringData
18+
import com.crowdin.platform.data.model.SupportedLanguages
19+
import com.crowdin.platform.data.model.SyncData
1820
import com.crowdin.platform.data.model.TextMetaData
1921
import com.crowdin.platform.data.remote.Connectivity
2022
import com.crowdin.platform.data.remote.NetworkType
@@ -32,20 +34,6 @@ internal class DataManager(
3234
private val crowdinPreferences: Preferences,
3335
private val dataChangeObserver: LocalDataChangeObserver,
3436
) : TextMetaDataProvider {
35-
companion object {
36-
private const val STATUS_OK = "ok"
37-
const val SUF_COPY = "-copy"
38-
const val DISTRIBUTION_DATA = "distribution_data"
39-
const val AUTH_INFO = "auth_info"
40-
const val DISTRIBUTION_HASH = "distribution_hash"
41-
const val MAPPING_SUF = "-mapping"
42-
const val SUPPORTED_LANGUAGES = "supported_languages"
43-
const val MANIFEST_DATA = "manifest_data"
44-
const val SYNC_DATA = "sync_data"
45-
const val EVENT_TICKETS = "event_tickets"
46-
const val EVENT_TICKETS_EXPIRATION = 1000 * 60 * 4
47-
}
48-
4937
private var loadingStateListeners: ArrayList<LoadingStateListener>? = null
5038

5139
override fun provideTextMetaData(
@@ -216,7 +204,7 @@ internal class DataManager(
216204
}
217205

218206
fun saveMapping(languageData: LanguageData) {
219-
languageData.language = languageData.language + MAPPING_SUF
207+
languageData.language += MAPPING_SUF
220208
localRepository.saveLanguageData(languageData)
221209
}
222210

@@ -266,18 +254,24 @@ internal class DataManager(
266254
}
267255

268256
@WorkerThread
269-
fun getSupportedLanguages(): LanguagesInfo? {
257+
fun getSupportedLanguages(): SupportedLanguages? {
270258
Log.v(CROWDIN_TAG, "Getting supported languages started")
271-
272-
var info: LanguagesInfo? = getData(SUPPORTED_LANGUAGES, LanguagesInfo::class.java)
273-
if (info == null) {
274-
info = remoteRepository.getSupportedLanguages()
275-
saveData(SUPPORTED_LANGUAGES, info)
259+
val syncData = crowdinPreferences.getData<SyncData>(SYNC_DATA, SyncData::class.java)
260+
val cachedLanguages = getData<CachedLanguages>(CACHED_LANGUAGES, CachedLanguages::class.java)
261+
val currentTimestamp = syncData?.timestamp ?: 0L
262+
263+
return if (cachedLanguages != null && cachedLanguages.manifestTimestamp == currentTimestamp) {
264+
cachedLanguages.languages
265+
} else {
266+
val fetchedLanguages = remoteRepository.getSupportedLanguages()
267+
if (fetchedLanguages != null) {
268+
saveData(CACHED_LANGUAGES, CachedLanguages(fetchedLanguages, currentTimestamp))
269+
} else {
270+
Log.v(CROWDIN_TAG, "Failed to fetch languages from distribution")
271+
}
272+
Log.v(CROWDIN_TAG, "Supported languages: $fetchedLanguages")
273+
fetchedLanguages
276274
}
277-
278-
Log.v(CROWDIN_TAG, "Supported languages: $info")
279-
280-
return info
281275
}
282276

283277
@WorkerThread
@@ -320,4 +314,18 @@ internal class DataManager(
320314
) {
321315
fun isExpired(): Boolean = System.currentTimeMillis() > expirationTime
322316
}
317+
318+
companion object {
319+
private const val STATUS_OK = "ok"
320+
const val SUF_COPY = "-copy"
321+
const val DISTRIBUTION_DATA = "distribution_data"
322+
const val AUTH_INFO = "auth_info"
323+
const val DISTRIBUTION_HASH = "distribution_hash"
324+
const val MAPPING_SUF = "-mapping"
325+
const val CACHED_LANGUAGES = "cached_languages"
326+
const val MANIFEST_DATA = "manifest_data"
327+
const val SYNC_DATA = "sync_data"
328+
const val EVENT_TICKETS = "event_tickets"
329+
const val EVENT_TICKETS_EXPIRATION = 1000 * 60 * 4
330+
}
323331
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.crowdin.platform.data.model
2+
3+
internal data class CachedLanguages(
4+
val languages: SupportedLanguages,
5+
val manifestTimestamp: Long,
6+
)

crowdin/src/main/java/com/crowdin/platform/data/model/LanguageInfoData.kt

Lines changed: 0 additions & 28 deletions
This file was deleted.

crowdin/src/main/java/com/crowdin/platform/data/model/LanguageMapper.kt

Lines changed: 0 additions & 13 deletions
This file was deleted.

crowdin/src/main/java/com/crowdin/platform/data/model/ManifestData.kt

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,10 @@ data class ManifestData(
99
val timestamp: Long,
1010
@SerializedName("languages")
1111
val languages: List<String>,
12-
@SerializedName("custom_languages")
13-
val customLanguages: Map<String, CustomLanguage>,
1412
@SerializedName("language_mapping")
1513
val languageMapping: Map<String, Map<String, String>>,
1614
@SerializedName("content")
1715
val content: Map<String, List<String>>,
1816
@SerializedName("mapping")
1917
val mapping: List<String>,
2018
)
21-
22-
data class CustomLanguage(
23-
@SerializedName("name")
24-
val name: String,
25-
@SerializedName("two_letters_code")
26-
val twoLettersCode: String,
27-
@SerializedName("three_letters_code")
28-
val threeLettersCode: String,
29-
@SerializedName("locale")
30-
val locale: String,
31-
@SerializedName("android_code")
32-
val androidCode: String,
33-
@SerializedName("locale_with_underscore")
34-
val localeWithUnderscore: String,
35-
)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.crowdin.platform.data.model
2+
3+
import com.google.gson.annotations.SerializedName
4+
5+
/**
6+
* Map of supported languages from distribution API.
7+
* Key: language code (e.g., "de", "de-BE", "it", "tra")
8+
* Value: language details
9+
*/
10+
typealias SupportedLanguages = Map<String, LanguageDetails>
11+
12+
data class LanguageDetails(
13+
@SerializedName("name")
14+
val name: String,
15+
@SerializedName("locale")
16+
val locale: String,
17+
)

crowdin/src/main/java/com/crowdin/platform/data/remote/CrowdingRepository.kt

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import android.util.Log
55
import androidx.annotation.WorkerThread
66
import com.crowdin.platform.Crowdin
77
import com.crowdin.platform.data.LanguageDataCallback
8-
import com.crowdin.platform.data.model.LanguageInfo
9-
import com.crowdin.platform.data.model.LanguagesInfo
8+
import com.crowdin.platform.data.model.LanguageDetails
109
import com.crowdin.platform.data.model.ManifestData
10+
import com.crowdin.platform.data.model.SupportedLanguages
1111
import com.crowdin.platform.data.model.TicketRequestBody
1212
import com.crowdin.platform.data.model.TicketResponseBody
1313
import com.crowdin.platform.data.remote.api.CrowdinApi
@@ -24,7 +24,7 @@ internal abstract class CrowdingRepository(
2424
private val distributionHash: String,
2525
) : BaseRepository() {
2626
var crowdinApi: CrowdinApi? = null
27-
var crowdinLanguages: LanguagesInfo? = null
27+
var crowdinLanguages: SupportedLanguages? = null
2828

2929
override fun getManifest(
3030
languageDataCallback: LanguageDataCallback?,
@@ -87,15 +87,18 @@ internal abstract class CrowdingRepository(
8787
languageDataCallback: LanguageDataCallback?,
8888
)
8989

90-
override fun getSupportedLanguages(): LanguagesInfo? {
90+
override fun getSupportedLanguages(): SupportedLanguages? {
9191
Log.v(Crowdin.CROWDIN_TAG, "Getting supported languages from Api started")
92+
var languages: SupportedLanguages? = null
93+
executeIO {
94+
val response = crowdinDistributionApi.getLanguages(distributionHash)?.execute()?.body()
95+
if (response != null) {
96+
languages = response
97+
}
98+
}
99+
Log.v(Crowdin.CROWDIN_TAG, "Supported languages from Api: $languages")
92100

93-
var info: LanguagesInfo? = null
94-
executeIO { info = crowdinApi?.getLanguagesInfo()?.execute()?.body() }
95-
96-
Log.v(Crowdin.CROWDIN_TAG, "Supported languages from Api: $info")
97-
98-
return info
101+
return languages
99102
}
100103

101104
@WorkerThread
@@ -105,14 +108,5 @@ internal abstract class CrowdingRepository(
105108
return result
106109
}
107110

108-
fun getLanguageInfo(sourceLanguage: String): LanguageInfo? {
109-
crowdinLanguages?.data?.forEach {
110-
val languageInfo = it.data
111-
if (languageInfo.id == sourceLanguage) {
112-
return languageInfo
113-
}
114-
}
115-
116-
return null
117-
}
111+
fun getLanguageInfo(sourceLanguage: String): LanguageDetails? = crowdinLanguages?.get(sourceLanguage)
118112
}

crowdin/src/main/java/com/crowdin/platform/data/remote/MappingRepository.kt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import com.crowdin.platform.data.DataManager
88
import com.crowdin.platform.data.DataManager.Companion.MANIFEST_DATA
99
import com.crowdin.platform.data.LanguageDataCallback
1010
import com.crowdin.platform.data.model.LanguageData
11-
import com.crowdin.platform.data.model.LanguagesInfo
1211
import com.crowdin.platform.data.model.ManifestData
12+
import com.crowdin.platform.data.model.SupportedLanguages
1313
import com.crowdin.platform.data.parser.Reader
1414
import com.crowdin.platform.data.remote.api.CrowdinDistributionApi
1515
import com.crowdin.platform.util.executeIO
@@ -23,14 +23,11 @@ internal class MappingRepository(
2323
private val dataManager: DataManager,
2424
private val distributionHash: String,
2525
private val sourceLanguage: String,
26-
) : CrowdingRepository(
27-
crowdinDistributionApi,
28-
distributionHash,
29-
) {
26+
) : CrowdingRepository(crowdinDistributionApi, distributionHash) {
3027
override fun fetchData(
3128
configuration: Configuration?,
3229
languageCode: String?,
33-
supportedLanguages: LanguagesInfo?,
30+
supportedLanguages: SupportedLanguages?,
3431
languageDataCallback: LanguageDataCallback?,
3532
) {
3633
Log.v(Crowdin.CROWDIN_TAG, "MappingRepository. Fetch data from Api started")

crowdin/src/main/java/com/crowdin/platform/data/remote/RemoteRepository.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import android.content.res.Configuration
44
import androidx.annotation.WorkerThread
55
import com.crowdin.platform.data.LanguageDataCallback
66
import com.crowdin.platform.data.model.LanguageData
7-
import com.crowdin.platform.data.model.LanguagesInfo
87
import com.crowdin.platform.data.model.ManifestData
8+
import com.crowdin.platform.data.model.SupportedLanguages
99
import com.crowdin.platform.data.model.TicketResponseBody
1010

1111
/**
@@ -17,12 +17,13 @@ internal interface RemoteRepository {
1717
*
1818
* @param configuration device configuration for locale context.
1919
* @param languageCode code to be user for search data.
20+
* @param supportedLanguages map of supported languages (code -> details).
2021
* @param languageDataCallback delivers data back to caller.
2122
*/
2223
fun fetchData(
2324
configuration: Configuration? = null,
2425
languageCode: String? = null,
25-
supportedLanguages: LanguagesInfo? = null,
26+
supportedLanguages: SupportedLanguages? = null,
2627
languageDataCallback: LanguageDataCallback? = null,
2728
)
2829

@@ -32,10 +33,10 @@ internal interface RemoteRepository {
3233
)
3334

3435
/**
35-
* Fetch all supported languages.
36+
* Fetch all supported languages as a map (language code -> details).
3637
*/
3738
@WorkerThread
38-
fun getSupportedLanguages(): LanguagesInfo?
39+
fun getSupportedLanguages(): SupportedLanguages?
3940

4041
/**
4142
* Fetch ticket for WebSocket connection.

0 commit comments

Comments
 (0)