Internationalization WIP

This commit is contained in:
shabinder 2021-06-25 18:34:28 +05:30
parent 08aa6d0f18
commit e50cf82f6a
7 changed files with 92 additions and 40 deletions

View File

@ -31,11 +31,12 @@ repositories {
dependencies { dependencies {
implementation("com.android.tools.build:gradle:4.1.1") implementation("com.android.tools.build:gradle:4.1.1")
implementation("org.jlleitschuh.gradle:ktlint-gradle:${Versions.ktLint}")
implementation(JetBrains.Compose.gradlePlugin) implementation(JetBrains.Compose.gradlePlugin)
implementation(JetBrains.Kotlin.gradlePlugin) implementation(JetBrains.Kotlin.gradlePlugin)
implementation(JetBrains.Kotlin.serialization) implementation(JetBrains.Kotlin.serialization)
implementation(SqlDelight.gradlePlugin) implementation(SqlDelight.gradlePlugin)
implementation("org.jlleitschuh.gradle:ktlint-gradle:${Versions.ktLint}")
implementation("de.comahe.i18n4k:i18n4k-gradle-plugin:0.1.1")
} }
kotlin { kotlin {

View File

@ -145,6 +145,10 @@ object Ktor {
val clientJs = "io.ktor:ktor-client-js:${Versions.ktor}" val clientJs = "io.ktor:ktor-client-js:${Versions.ktor}"
} }
object Internationalization {
const val dep = "de.comahe.i18n4k:i18n4k-core:0.1.1"
}
object Extras { object Extras {
const val youtubeDownloader = "io.github.shabinder:youtube-api-dl:1.2" const val youtubeDownloader = "io.github.shabinder:youtube-api-dl:1.2"
const val fuzzyWuzzy = "io.github.shabinder:fuzzywuzzy:1.1" const val fuzzyWuzzy = "io.github.shabinder:fuzzywuzzy:1.1"

View File

@ -83,6 +83,7 @@ import com.shabinder.common.main.SpotiFlyerMain
import com.shabinder.common.main.SpotiFlyerMain.HomeCategory import com.shabinder.common.main.SpotiFlyerMain.HomeCategory
import com.shabinder.common.models.DownloadRecord import com.shabinder.common.models.DownloadRecord
import com.shabinder.common.models.methods import com.shabinder.common.models.methods
import com.shabinder.common.translations.Strings
import com.shabinder.common.uikit.dialogs.DonationDialogComponent import com.shabinder.common.uikit.dialogs.DonationDialogComponent
@Composable @Composable
@ -151,16 +152,16 @@ fun HomeTabBar(
text = { text = {
Text( Text(
text = when (category) { text = when (category) {
HomeCategory.About -> "About" HomeCategory.About -> Strings.about()
HomeCategory.History -> "History" HomeCategory.History -> Strings.history()
}, },
style = MaterialTheme.typography.body2 style = MaterialTheme.typography.body2
) )
}, },
icon = { icon = {
when (category) { when (category) {
HomeCategory.About -> Icon(Icons.Outlined.Info, "Info Tab") HomeCategory.About -> Icon(Icons.Outlined.Info, Strings.infoTab())
HomeCategory.History -> Icon(Icons.Outlined.History, "History Tab") HomeCategory.History -> Icon(Icons.Outlined.History, Strings.historyTab())
} }
} }
) )
@ -183,9 +184,9 @@ fun SearchPanel(
value = link, value = link,
onValueChange = updateLink, onValueChange = updateLink,
leadingIcon = { leadingIcon = {
Icon(Icons.Rounded.Edit, "Link Text Box", tint = Color.LightGray) Icon(Icons.Rounded.Edit, Strings.linkTextBox(), tint = Color.LightGray)
}, },
label = { Text(text = "Paste Link Here...", color = Color.LightGray) }, label = { Text(text = Strings.pasteLinkHere(), color = Color.LightGray) },
singleLine = true, singleLine = true,
textStyle = TextStyle.Default.merge(TextStyle(fontSize = 18.sp, color = Color.White)), textStyle = TextStyle.Default.merge(TextStyle(fontSize = 18.sp, color = Color.White)),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Uri), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Uri),
@ -212,7 +213,7 @@ fun SearchPanel(
OutlinedButton( OutlinedButton(
modifier = Modifier.padding(12.dp).wrapContentWidth(), modifier = Modifier.padding(12.dp).wrapContentWidth(),
onClick = { onClick = {
if (link.isBlank()) methods.value.showPopUpMessage("Enter A Link!") if (link.isBlank()) methods.value.showPopUpMessage(Strings.enterALink())
else { else {
// TODO if(!isOnline(ctx)) showPopUpMessage("Check Your Internet Connection") else // TODO if(!isOnline(ctx)) showPopUpMessage("Check Your Internet Connection") else
onSearch(link) onSearch(link)
@ -228,7 +229,7 @@ fun SearchPanel(
) )
) )
) { ) {
Text(text = "Search", style = SpotiFlyerTypography.h6, modifier = Modifier.padding(4.dp)) Text(text = Strings.search(), style = SpotiFlyerTypography.h6, modifier = Modifier.padding(4.dp))
} }
} }
} }
@ -251,7 +252,7 @@ fun AboutColumn(
) { ) {
Column(modifier.padding(12.dp)) { Column(modifier.padding(12.dp)) {
Text( Text(
text = "Supported Platforms", text = Strings.supportedPlatforms(),
style = SpotiFlyerTypography.body1, style = SpotiFlyerTypography.body1,
color = colorAccent color = colorAccent
) )
@ -259,7 +260,7 @@ fun AboutColumn(
Row(horizontalArrangement = Arrangement.Center, modifier = modifier.fillMaxWidth()) { Row(horizontalArrangement = Arrangement.Center, modifier = modifier.fillMaxWidth()) {
Icon( Icon(
SpotifyLogo(), SpotifyLogo(),
"Open Spotify", "${Strings.open()} Spotify",
tint = Color.Unspecified, tint = Color.Unspecified,
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable( modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
onClick = { methods.value.openPlatform("com.spotify.music", "http://open.spotify.com") } onClick = { methods.value.openPlatform("com.spotify.music", "http://open.spotify.com") }
@ -268,7 +269,7 @@ fun AboutColumn(
Spacer(modifier = modifier.padding(start = 16.dp)) Spacer(modifier = modifier.padding(start = 16.dp))
Icon( Icon(
GaanaLogo(), GaanaLogo(),
"Open Gaana", "${Strings.open()} Gaana",
tint = Color.Unspecified, tint = Color.Unspecified,
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable( modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
onClick = { methods.value.openPlatform("com.gaana", "https://www.gaana.com") } onClick = { methods.value.openPlatform("com.gaana", "https://www.gaana.com") }
@ -277,7 +278,7 @@ fun AboutColumn(
Spacer(modifier = modifier.padding(start = 16.dp)) Spacer(modifier = modifier.padding(start = 16.dp))
Icon( Icon(
SaavnLogo(), SaavnLogo(),
"Open Jio Saavn", "${Strings.open()} Jio Saavn",
tint = Color.Unspecified, tint = Color.Unspecified,
modifier = Modifier.clickable( modifier = Modifier.clickable(
onClick = { methods.value.openPlatform("com.jio.media.jiobeats", "https://www.jiosaavn.com/") } onClick = { methods.value.openPlatform("com.jio.media.jiobeats", "https://www.jiosaavn.com/") }
@ -286,7 +287,7 @@ fun AboutColumn(
Spacer(modifier = modifier.padding(start = 16.dp)) Spacer(modifier = modifier.padding(start = 16.dp))
Icon( Icon(
YoutubeLogo(), YoutubeLogo(),
"Open Youtube", "${Strings.open()} Youtube",
tint = Color.Unspecified, tint = Color.Unspecified,
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable( modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
onClick = { methods.value.openPlatform("com.google.android.youtube", "https://m.youtube.com") } onClick = { methods.value.openPlatform("com.google.android.youtube", "https://m.youtube.com") }
@ -295,7 +296,7 @@ fun AboutColumn(
Spacer(modifier = modifier.padding(start = 12.dp)) Spacer(modifier = modifier.padding(start = 12.dp))
Icon( Icon(
YoutubeMusicLogo(), YoutubeMusicLogo(),
"Open Youtube Music", "${Strings.open()} Youtube Music",
tint = Color.Unspecified, tint = Color.Unspecified,
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable( modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
onClick = { methods.value.openPlatform("com.google.android.apps.youtube.music", "https://music.youtube.com/") } onClick = { methods.value.openPlatform("com.google.android.apps.youtube.music", "https://music.youtube.com/") }
@ -311,7 +312,7 @@ fun AboutColumn(
) { ) {
Column(modifier.padding(12.dp)) { Column(modifier.padding(12.dp)) {
Text( Text(
text = "Support Development", text = Strings.supportDevelopment(),
style = SpotiFlyerTypography.body1, style = SpotiFlyerTypography.body1,
color = colorAccent color = colorAccent
) )
@ -323,7 +324,7 @@ fun AboutColumn(
) )
.padding(vertical = 6.dp) .padding(vertical = 6.dp)
) { ) {
Icon(GithubLogo(), "Open Project Repo", Modifier.size(32.dp), tint = Color(0xFFCCCCCC)) Icon(GithubLogo(), Strings.openProjectRepo(), Modifier.size(32.dp), tint = Color(0xFFCCCCCC))
Spacer(modifier = Modifier.padding(start = 16.dp)) Spacer(modifier = Modifier.padding(start = 16.dp))
Column { Column {
Text( Text(
@ -331,7 +332,7 @@ fun AboutColumn(
style = SpotiFlyerTypography.h6 style = SpotiFlyerTypography.h6
) )
Text( Text(
text = "Star / Fork the project on Github.", text = Strings.starOrForkProject(),
style = SpotiFlyerTypography.subtitle2 style = SpotiFlyerTypography.subtitle2
) )
} }
@ -341,15 +342,15 @@ fun AboutColumn(
.clickable(onClick = { methods.value.openPlatform("", "http://github.com/Shabinder/SpotiFlyer") }), .clickable(onClick = { methods.value.openPlatform("", "http://github.com/Shabinder/SpotiFlyer") }),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Icon(Icons.Rounded.Flag, "Help Translate", Modifier.size(32.dp)) Icon(Icons.Rounded.Flag, Strings.help() + Strings.translate(), Modifier.size(32.dp))
Spacer(modifier = Modifier.padding(start = 16.dp)) Spacer(modifier = Modifier.padding(start = 16.dp))
Column { Column {
Text( Text(
text = "Translate", text = Strings.translate(),
style = SpotiFlyerTypography.h6 style = SpotiFlyerTypography.h6
) )
Text( Text(
text = "Help us translate this app in your local language.", text = Strings.helpTranslateDescription(),
style = SpotiFlyerTypography.subtitle2 style = SpotiFlyerTypography.subtitle2
) )
} }
@ -360,15 +361,15 @@ fun AboutColumn(
.clickable(onClick = openDonationDialog), .clickable(onClick = openDonationDialog),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Icon(Icons.Rounded.CardGiftcard, "Support Developer", Modifier.size(32.dp)) Icon(Icons.Rounded.CardGiftcard, Strings.supportDeveloper(), Modifier.size(32.dp))
Spacer(modifier = Modifier.padding(start = 16.dp)) Spacer(modifier = Modifier.padding(start = 16.dp))
Column { Column {
Text( Text(
text = "Donate", text = Strings.donate(),
style = SpotiFlyerTypography.h6 style = SpotiFlyerTypography.h6
) )
Text( Text(
text = "If you think I deserve to get paid for my work, you can support me here.", text = Strings.donateDescription(),
// text = "SpotiFlyer will always be, Free and Open-Source. You can however show us that you care by sending a small donation.", // text = "SpotiFlyer will always be, Free and Open-Source. You can however show us that you care by sending a small donation.",
style = SpotiFlyerTypography.subtitle2 style = SpotiFlyerTypography.subtitle2
) )
@ -383,15 +384,15 @@ fun AboutColumn(
), ),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Icon(Icons.Rounded.Share, "Share SpotiFlyer App", Modifier.size(32.dp)) Icon(Icons.Rounded.Share, Strings.share() + Strings.title() + "App", Modifier.size(32.dp))
Spacer(modifier = Modifier.padding(start = 16.dp)) Spacer(modifier = Modifier.padding(start = 16.dp))
Column { Column {
Text( Text(
text = "Share", text = Strings.share(),
style = SpotiFlyerTypography.h6 style = SpotiFlyerTypography.h6
) )
Text( Text(
text = "Share this app with your friends and family.", text = Strings.shareDescription(),
style = SpotiFlyerTypography.subtitle2 style = SpotiFlyerTypography.subtitle2
) )
} }
@ -405,17 +406,17 @@ fun AboutColumn(
), ),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Icon(Icons.Rounded.Insights, "Analytics Status", Modifier.size(32.dp)) Icon(Icons.Rounded.Insights, Strings.analytics() + Strings.status(), Modifier.size(32.dp))
Spacer(modifier = Modifier.padding(start = 16.dp)) Spacer(modifier = Modifier.padding(start = 16.dp))
Column( Column(
Modifier.weight(1f) Modifier.weight(1f)
) { ) {
Text( Text(
text = "Analytics", text = Strings.analytics(),
style = SpotiFlyerTypography.h6 style = SpotiFlyerTypography.h6
) )
Text( Text(
text = "Your Data is Anonymized and never shared with 3rd party service", text = Strings.analyticsDescription(),
style = SpotiFlyerTypography.subtitle2 style = SpotiFlyerTypography.subtitle2
) )
} }
@ -446,10 +447,10 @@ fun HistoryColumn(
if (it.isEmpty()) { if (it.isEmpty()) {
Column(Modifier.padding(8.dp).fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally) { Column(Modifier.padding(8.dp).fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally) {
Icon( Icon(
Icons.Outlined.Info, "No History Available Yet", modifier = Modifier.size(80.dp), Icons.Outlined.Info, Strings.noHistoryAvailable(), modifier = Modifier.size(80.dp),
colorOffWhite colorOffWhite
) )
Text("No History Available", style = SpotiFlyerTypography.h4.copy(fontWeight = FontWeight.Light), textAlign = TextAlign.Center) Text(Strings.noHistoryAvailable(), style = SpotiFlyerTypography.h4.copy(fontWeight = FontWeight.Light), textAlign = TextAlign.Center)
} }
} else { } else {
Box { Box {
@ -495,7 +496,7 @@ fun DownloadRecordItem(
ImageLoad( ImageLoad(
item.coverUrl, item.coverUrl,
{ loadImage(item.coverUrl) }, { loadImage(item.coverUrl) },
"Album Art", Strings.albumArt(),
modifier = Modifier.height(70.dp).width(70.dp).clip(SpotiFlyerShapes.medium) modifier = Modifier.height(70.dp).width(70.dp).clip(SpotiFlyerShapes.medium)
) )
Column(modifier = Modifier.padding(horizontal = 8.dp).height(60.dp).weight(1f), verticalArrangement = Arrangement.SpaceEvenly) { Column(modifier = Modifier.padding(horizontal = 8.dp).height(60.dp).weight(1f), verticalArrangement = Arrangement.SpaceEvenly) {
@ -506,12 +507,12 @@ fun DownloadRecordItem(
modifier = Modifier.padding(horizontal = 8.dp).fillMaxSize() modifier = Modifier.padding(horizontal = 8.dp).fillMaxSize()
) { ) {
Text(item.type, fontSize = 13.sp, color = colorOffWhite) Text(item.type, fontSize = 13.sp, color = colorOffWhite)
Text("Tracks: ${item.totalFiles}", fontSize = 13.sp, color = colorOffWhite) Text("${Strings.tracks()}: ${item.totalFiles}", fontSize = 13.sp, color = colorOffWhite)
} }
} }
Image( Image(
ShareImage(), ShareImage(),
"Research", Strings.reSearch(),
modifier = Modifier.clickable( modifier = Modifier.clickable(
onClick = { onClick = {
// if(!isOnline(ctx)) showDialog("Check Your Internet Connection") else // if(!isOnline(ctx)) showDialog("Check Your Internet Connection") else

View File

@ -59,6 +59,7 @@ import com.arkivanov.decompose.extensions.compose.jetbrains.animation.child.cros
import com.arkivanov.decompose.extensions.compose.jetbrains.subscribeAsState import com.arkivanov.decompose.extensions.compose.jetbrains.subscribeAsState
import com.shabinder.common.root.SpotiFlyerRoot import com.shabinder.common.root.SpotiFlyerRoot
import com.shabinder.common.root.SpotiFlyerRoot.Child import com.shabinder.common.root.SpotiFlyerRoot.Child
import com.shabinder.common.translations.Strings
import com.shabinder.common.uikit.splash.Splash import com.shabinder.common.uikit.splash.Splash
import com.shabinder.common.uikit.splash.SplashState import com.shabinder.common.uikit.splash.SplashState
import com.shabinder.common.uikit.utils.verticalGradientScrim import com.shabinder.common.uikit.utils.verticalGradientScrim
@ -163,7 +164,7 @@ fun AppBar(
AnimatedVisibility(isBackButtonVisible) { AnimatedVisibility(isBackButtonVisible) {
Icon( Icon(
Icons.Rounded.ArrowBackIosNew, Icons.Rounded.ArrowBackIosNew,
contentDescription = "Back Button", contentDescription = Strings.backButton(),
modifier = Modifier.clickable { onBackPressed() }, modifier = Modifier.clickable { onBackPressed() },
tint = Color.LightGray tint = Color.LightGray
) )
@ -171,12 +172,12 @@ fun AppBar(
} }
Image( Image(
SpotiFlyerLogo(), SpotiFlyerLogo(),
"SpotiFlyer Logo", Strings.spotiflyerLogo(),
Modifier.size(32.dp), Modifier.size(32.dp),
) )
Spacer(Modifier.padding(horizontal = 4.dp)) Spacer(Modifier.padding(horizontal = 4.dp))
Text( Text(
text = "SpotiFlyer", text = Strings.title(),
style = appNameStyle style = appNameStyle
) )
} }
@ -185,7 +186,7 @@ fun AppBar(
IconButton( IconButton(
onClick = { setDownloadDirectory() } onClick = { setDownloadDirectory() }
) { ) {
Icon(Icons.Filled.Settings, "Preferences", tint = Color.Gray) Icon(Icons.Filled.Settings, Strings.preferences(), tint = Color.Gray)
} }
}, },
modifier = modifier, modifier = modifier,

View File

@ -1,3 +1,5 @@
import de.comahe.i18n4k.gradle.plugin.i18n4k
/* /*
* * Copyright (c) 2021 Shabinder Singh * * Copyright (c) 2021 Shabinder Singh
* * This program is free software: you can redistribute it and/or modify * * This program is free software: you can redistribute it and/or modify
@ -20,11 +22,18 @@ plugins {
id("multiplatform-setup-test") id("multiplatform-setup-test")
id("kotlin-parcelize") id("kotlin-parcelize")
kotlin("plugin.serialization") kotlin("plugin.serialization")
id("de.comahe.i18n4k")
} }
val statelyVersion = "1.1.7" val statelyVersion = "1.1.7"
val statelyIsoVersion = "1.1.7-a1" val statelyIsoVersion = "1.1.7-a1"
i18n4k {
inputDirectory = "../../translations"
packageName = "com.shabinder.common.translations"
// sourceCodeLocales = listOf("en", "de")
}
kotlin { kotlin {
sourceSets { sourceSets {
/* /*
@ -45,6 +54,7 @@ kotlin {
implementation("co.touchlab:stately-isolate:$statelyIsoVersion") implementation("co.touchlab:stately-isolate:$statelyIsoVersion")
implementation("co.touchlab:stately-iso-collections:$statelyIsoVersion") implementation("co.touchlab:stately-iso-collections:$statelyIsoVersion")
implementation(Extras.youtubeDownloader) implementation(Extras.youtubeDownloader)
api(Internationalization.dep)
} }
} }
androidMain { androidMain {

View File

@ -1,3 +1,3 @@
package com.shabinder.common package com.shabinder.common
fun <T: Any?> T?.requireNotNull() : T = requireNotNull(this) fun <T: Any?> T?.requireNotNull() : T = requireNotNull(this)

View File

@ -0,0 +1,35 @@
title = SpotiFlyer
about = About
history = History
donate = Donate
preferences = Preferences
search = Search
supportedPlatforms = Supported Platforms
supportDevelopment = Support Development
openProjectRepo = Open Project Repo
starOrForkProject = Star / Fork the project on Github.
help = Help
translate = Translate
helpTranslateDescription = Help us translate this app in your local language.
supportDeveloper = Support Developer
donateDescription = If you think I deserve to get paid for my work, you can support me here.
share = Share
shareDescription = Share this app with your friends and family.
status = Status
analytics = Analytics
analyticsDescription = Your Data is Anonymized and never shared with 3rd party service.
noHistoryAvailable = No History Available
albumArt = Album Art
tracks = Tracks
reSearch = Re-Search
spotiflyerLogo = SpotiFlyer Logo
backButton = Back Button
infoTab = Info Tab
historyTab = History Tab
linkTextBox = Link Text Box
pasteLinkHere = Paste Link Here...
enterALink = Enter A Link!
madeWith = Made with
inIndia = in India
open = Open