Internationalization WIP

This commit is contained in:
shabinder 2021-06-25 19:16:38 +05:30
parent e50cf82f6a
commit 6e517e0049
11 changed files with 94 additions and 82 deletions

View File

@ -19,6 +19,7 @@ package com.shabinder.spotiflyer
import android.app.Application
import android.content.Context
import com.shabinder.common.di.initKoin
import com.shabinder.common.translations.Strings
import com.shabinder.spotiflyer.di.appModule
import org.acra.config.httpSender
import org.acra.config.notification
@ -77,10 +78,10 @@ class App: Application(), KoinComponent {
* Obeying `F-Droid Inclusion Privacy Rules`
* */
notification {
title = getString(R.string.acra_notification_title)
text = getString(R.string.acra_notification_text)
channelName = getString(R.string.acra_notification_channel)
channelDescription = getString(R.string.acra_notification_channel_desc)
title = Strings.acraNotificationTitle()
text = Strings.acraNotificationText()
channelName = "SpotiFlyer_Crashlytics"
channelDescription = "Notification Channel to send Spotiflyer Crashes."
sendOnClick = true
}
// Send Crash Report to self hosted Acrarium (FOSS)

View File

@ -43,6 +43,7 @@ import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.models.TrackDetails
import com.shabinder.common.models.event.coroutines.SuspendableEvent
import com.shabinder.common.models.event.coroutines.failure
import com.shabinder.common.translations.Strings
import com.shabinder.spotiflyer.utils.autoclear.AutoClear
import com.shabinder.spotiflyer.utils.autoclear.autoClear
import kotlinx.coroutines.Dispatchers
@ -237,7 +238,7 @@ class ForegroundService : LifecycleService() {
lifecycleScope.launch {
logger.d(TAG) { "Killing Self" }
messageList = messageList.getEmpty().apply {
set(index = 0, Message("Cleaning And Exiting",DownloadStatus.NotDownloaded))
set(index = 0, Message(Strings.cleaningAndExiting(),DownloadStatus.NotDownloaded))
}
downloadService.value.close()
downloadService.reset()
@ -257,7 +258,7 @@ class ForegroundService : LifecycleService() {
private fun createNotification(): Notification = NotificationCompat.Builder(this, CHANNEL_ID).run {
setSmallIcon(R.drawable.ic_download_arrow)
setContentTitle("Total: $total Completed:$converted Failed:$failed")
setContentTitle("${Strings.total()}: $total ${Strings.completed()}:$converted ${Strings.failed()}:$failed")
setSilent(true)
setProgress(total,failed+converted,false)
setStyle(
@ -269,7 +270,7 @@ class ForegroundService : LifecycleService() {
addLine(messageList[messageList.size - 5].asString())
}
)
addAction(R.drawable.ic_round_cancel_24, "Exit", cancelIntent)
addAction(R.drawable.ic_round_cancel_24, Strings.exit(), cancelIntent)
build()
}

View File

@ -1,6 +1,7 @@
package com.shabinder.spotiflyer.service
import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.translations.Strings
typealias Message = Pair<String, DownloadStatus>
@ -11,9 +12,9 @@ val Message.downloadStatus: DownloadStatus get() = second
val Message.progress: String get() = when (downloadStatus) {
is DownloadStatus.Downloading -> "-> ${(downloadStatus as DownloadStatus.Downloading).progress}%"
is DownloadStatus.Converting -> "-> 100%"
is DownloadStatus.Downloaded -> "-> Done"
is DownloadStatus.Failed -> "-> Failed"
is DownloadStatus.Queued -> "-> Queued"
is DownloadStatus.Downloaded -> "-> ${Strings.downloadDone}"
is DownloadStatus.Failed -> "-> ${Strings.failed()}"
is DownloadStatus.Queued -> "-> ${Strings.queued()}"
is DownloadStatus.NotDownloaded -> ""
}
@ -23,8 +24,8 @@ val emptyMessage = Message("",DownloadStatus.NotDownloaded)
// all Progress data is emitted all together from fun
fun Message.asString(): String {
val statusString = when(downloadStatus){
is DownloadStatus.Downloading -> "Downloading"
is DownloadStatus.Converting -> "Processing"
is DownloadStatus.Downloading -> Strings.downloading()
is DownloadStatus.Converting -> Strings.processing()
else -> ""
}
return "$statusString $title ${""/*progress*/}".trim()

View File

@ -1,37 +0,0 @@
<!--
~ Copyright (c) 2021 Shabinder Singh
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<resources>
<string name="app_name">SpotiFlyer</string>
<string name="home_about">About</string>
<string name="home_history">History</string>
<string name="supported_platform">Supported Platforms</string>
<string name="support_development">Support Development</string>
<string name="github_star">Star / Fork the project on Github.</string>
<string name="github">GitHub</string>
<string name="translate">Translate</string>
<string name="help_us_translate">Help us translate this app in your local language.</string>
<string name="donate">Donate</string>
<string name="donate_subtitle">If you think I deserve to get paid for my work, you can leave me some money here.</string>
<string name="share">Share</string>
<string name="share_subtitle">Share this app with your friends and family.</string>
<string name="made_with_love">Made with</string>
<string name="in_india">in India</string>
<string name="acra_notification_title">OOPS, SpotiFlyer Crashed</string>
<string name="acra_notification_text">Please Send Crash Report to App Developers, So this unfortunate event may not happen again.</string>
<string name="acra_notification_channel">SpotiFlyer_Crashlytics</string>
<string name="acra_notification_channel_desc">Notification Channel to send Spotiflyer Crashes.</string>
</resources>

View File

@ -26,6 +26,7 @@ import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import com.shabinder.common.database.R
import com.shabinder.common.translations.Strings
import kotlinx.coroutines.flow.MutableStateFlow
actual fun montserratFont() = FontFamily(
@ -43,7 +44,7 @@ actual fun pristineFont() = FontFamily(
actual fun DownloadImageTick() {
Image(
painterResource(R.drawable.ic_tick),
"Download Done"
Strings.downloadDone()
)
}
@ -51,7 +52,7 @@ actual fun DownloadImageTick() {
actual fun DownloadImageError() {
Image(
painterResource(R.drawable.ic_error),
"Error! Cant Download this track"
Strings.downloadError()
)
}
@ -59,7 +60,7 @@ actual fun DownloadImageError() {
actual fun DownloadImageArrow(modifier: Modifier) {
Image(
painterResource(R.drawable.ic_arrow),
"Start Download",
Strings.downloadStart(),
modifier
)
}

View File

@ -25,6 +25,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import com.shabinder.common.models.methods
import com.shabinder.common.translations.Strings
@OptIn(ExperimentalAnimationApi::class)
@Composable
@ -44,7 +45,7 @@ actual fun DonationDialog(
) {
Column(Modifier.padding(16.dp)) {
Text(
"We Need Your Support!",
Strings.supportUs(),
style = SpotiFlyerTypography.h5,
textAlign = TextAlign.Center,
color = colorAccent,
@ -69,7 +70,7 @@ actual fun DonationDialog(
style = SpotiFlyerTypography.h6
)
Text(
text = "Worldwide Donations",
text = Strings.worldWideDonations(),
style = SpotiFlyerTypography.subtitle2
)
}
@ -92,7 +93,7 @@ actual fun DonationDialog(
style = SpotiFlyerTypography.h6
)
Text(
text = "International Donations (Outside India).",
text = Strings.worldWideDonations(),
style = SpotiFlyerTypography.subtitle2
)
}
@ -115,7 +116,7 @@ actual fun DonationDialog(
style = SpotiFlyerTypography.h6
)
Text(
text = "Indian Donations (UPI / PayTM / PhonePe / Cards).",
text = "${Strings.indianDonations()} (UPI / PayTM / PhonePe / Cards).",
style = SpotiFlyerTypography.subtitle2
)
}
@ -127,10 +128,10 @@ actual fun DonationDialog(
modifier = Modifier.padding(horizontal = 4.dp).fillMaxWidth()
) {
OutlinedButton(onClick = onDismiss) {
Text("Dismiss.")
Text(Strings.dismiss())
}
TextButton(onClick = onSnooze, colors = ButtonDefaults.buttonColors()) {
Text("Remind Later!")
Text(Strings.remindLater())
}
}
}

View File

@ -54,6 +54,7 @@ import com.shabinder.common.list.SpotiFlyerList
import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.models.TrackDetails
import com.shabinder.common.models.methods
import com.shabinder.common.translations.Strings
import com.shabinder.common.uikit.dialogs.DonationDialogComponent
@OptIn(ExperimentalMaterialApi::class)
@ -67,7 +68,7 @@ fun SpotiFlyerListContent(
LaunchedEffect(model.errorOccurred) {
/*Handle if Any Exception Occurred*/
model.errorOccurred?.let {
methods.value.showPopUpMessage(it.message ?: "An Error Occurred, Check your Link / Connection")
methods.value.showPopUpMessage(it.message ?: Strings.errorOccurred())
component.onBackPressed()
}
}
@ -79,7 +80,7 @@ fun SpotiFlyerListContent(
Column(Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally) {
CircularProgressIndicator()
Spacer(modifier.padding(8.dp))
Text("Loading..", style = appNameStyle, color = colorPrimary)
Text("${Strings.loading()}...", style = appNameStyle, color = colorPrimary)
}
} else {
@ -142,7 +143,7 @@ fun TrackCard(
ImageLoad(
track.albumArtURL,
{ loadImage() },
"Album Art",
Strings.albumArt(),
modifier = Modifier
.width(70.dp)
.height(70.dp)
@ -156,7 +157,7 @@ fun TrackCard(
modifier = Modifier.padding(horizontal = 8.dp).fillMaxSize()
) {
Text("${track.artists.firstOrNull()}...", fontSize = 12.sp, maxLines = 1)
Text("${track.durationSec / 60} min, ${track.durationSec % 60} sec", fontSize = 12.sp, maxLines = 1, overflow = TextOverflow.Ellipsis)
Text("${track.durationSec / 60} ${Strings.minute()}, ${track.durationSec % 60} ${Strings.second()}", fontSize = 12.sp, maxLines = 1, overflow = TextOverflow.Ellipsis)
}
}
when (track.downloaded) {
@ -202,7 +203,7 @@ fun CoverImage(
ImageLoad(
coverURL,
{ loadImage(coverURL, true) },
"Cover Image",
Strings.coverImage(),
modifier = Modifier
.padding(12.dp)
.width(190.dp)
@ -225,9 +226,9 @@ fun CoverImage(
@Composable
fun DownloadAllButton(onClick: () -> Unit, modifier: Modifier = Modifier) {
ExtendedFloatingActionButton(
text = { Text("Download All") },
text = { Text(Strings.downloadAll()) },
onClick = onClick,
icon = { Icon(DownloadAllImage(), "Download All Button", tint = Color(0xFF000000)) },
icon = { Icon(DownloadAllImage(), Strings.downloadAll() + Strings.button(), tint = Color(0xFF000000)) },
backgroundColor = colorAccent,
modifier = modifier
)

View File

@ -35,6 +35,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.shabinder.common.translations.Strings
import com.shabinder.common.uikit.HeartIcon
import com.shabinder.common.uikit.SpotiFlyerLogo
import com.shabinder.common.uikit.SpotiFlyerTypography
@ -55,7 +56,7 @@ fun Splash(modifier: Modifier = Modifier, onTimeout: () -> Unit) {
delay(SplashWaitTime)
currentOnTimeout()
}
Image(SpotiFlyerLogo(), "SpotiFlyer Logo")
Image(SpotiFlyerLogo(), Strings.spotiflyerLogo())
MadeInIndia(Modifier.align(Alignment.BottomCenter))
}
}
@ -73,21 +74,21 @@ fun MadeInIndia(
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = "Made with ",
text = "${Strings.madeWith()} ",
color = colorPrimary,
fontSize = 22.sp
)
Spacer(modifier = Modifier.padding(start = 4.dp))
Icon(HeartIcon(), "Love", tint = Color.Unspecified)
Icon(HeartIcon(), Strings.love(), tint = Color.Unspecified)
Spacer(modifier = Modifier.padding(start = 4.dp))
Text(
text = " in India",
text = " ${Strings.inIndia()}",
color = colorPrimary,
fontSize = 22.sp
)
}
Text(
"by: Shabinder Singh",
Strings.byDeveloperName(),
style = SpotiFlyerTypography.h6,
color = colorAccent,
fontSize = 14.sp

View File

@ -20,9 +20,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.v1.Dialog
import com.shabinder.common.models.methods
import com.shabinder.common.translations.Strings
@OptIn(ExperimentalAnimationApi::class, androidx.compose.ui.ExperimentalComposeUiApi::class)
@Composable
@ -42,7 +42,7 @@ actual fun DonationDialog(
) {
Column(Modifier.padding(16.dp)) {
Text(
"Support Us",
Strings.supportUs(),
style = SpotiFlyerTypography.h5,
textAlign = TextAlign.Center,
color = colorAccent,
@ -67,7 +67,7 @@ actual fun DonationDialog(
style = SpotiFlyerTypography.h6
)
Text(
text = "International Donations (Outside India).",
text = Strings.worldWideDonations(),
style = SpotiFlyerTypography.subtitle2
)
}
@ -90,7 +90,7 @@ actual fun DonationDialog(
style = SpotiFlyerTypography.h6
)
Text(
text = "Indian Donations (UPI / PayTM / PhonePe / Cards).",
text = "${Strings.indianDonations()} (UPI / PayTM / PhonePe / Cards).",
style = SpotiFlyerTypography.subtitle2
)
}

View File

@ -1,41 +1,43 @@
package com.shabinder.common.models
import com.shabinder.common.translations.Strings
sealed class SpotiFlyerException(override val message: String): Exception(message) {
data class FeatureNotImplementedYet(override val message: String = "Feature not yet implemented."): SpotiFlyerException(message)
data class NoInternetException(override val message: String = "Check Your Internet Connection"): SpotiFlyerException(message)
data class FeatureNotImplementedYet(override val message: String = Strings.featureUnImplemented()): SpotiFlyerException(message)
data class NoInternetException(override val message: String = Strings.checkInternetConnection()): SpotiFlyerException(message)
data class MP3ConversionFailed(
val extraInfo:String? = null,
override val message: String = "MP3 Converter unreachable, probably BUSY ! \nCAUSE:$extraInfo"
override val message: String = "${Strings.mp3ConverterBusy()} \nCAUSE:$extraInfo"
): SpotiFlyerException(message)
data class UnknownReason(
val exception: Throwable? = null,
override val message: String = "Unknown Error"
override val message: String = Strings.unknownError()
): SpotiFlyerException(message)
data class NoMatchFound(
val trackName: String? = null,
override val message: String = "$trackName : NO Match Found!"
override val message: String = "$trackName : ${Strings.noMatchFound()}"
): SpotiFlyerException(message)
data class YoutubeLinkNotFound(
val videoID: String? = null,
override val message: String = "No Downloadable link found for videoID: $videoID"
override val message: String = "${Strings.noLinkFound()}: $videoID"
): SpotiFlyerException(message)
data class DownloadLinkFetchFailed(
val trackName: String,
val jioSaavnError: Throwable,
val ytMusicError: Throwable,
override val message: String = "No Downloadable link found for track: $trackName," +
override val message: String = "${Strings.noLinkFound()}: $trackName," +
" \n JioSaavn Error's StackTrace: ${jioSaavnError.stackTraceToString()} \n " +
" \n YtMusic Error's StackTrace: ${ytMusicError.stackTraceToString()} \n "
): SpotiFlyerException(message)
data class LinkInvalid(
val link: String? = null,
override val message: String = "Entered Link is NOT Valid!\n ${link ?: ""}"
override val message: String = "${Strings.linkNotValid()}\n ${link ?: ""}"
): SpotiFlyerException(message)
}

View File

@ -19,10 +19,48 @@ status = Status
analytics = Analytics
analyticsDescription = Your Data is Anonymized and never shared with 3rd party service.
noHistoryAvailable = No History Available
cleaningAndExiting = Cleaning And Exiting
total = Total
completed = Completed
failed = Failed
exit = Exit
downloading = Downloading
processing = Processing
queued = Queued
acraNotificationTitle = OOPS, SpotiFlyer Crashed
acraNotificationText = Please Send Crash Report to App Developers, So this unfortunate event may not happen again.
albumArt = Album Art
tracks = Tracks
coverImage = Cover Image
reSearch = Re-Search
loading = Loading
downloadAll = Download All
button = Button
errorOccurred = An Error Occurred, Check your Link / Connection
downloadDone = Download Done
downloadError = Error! Cant Download this track
downloadStart = Start Download
supportUs = We Need Your Support!
donation = Donation
worldWideDonations = World Wide Donations
indianDonations = Indian Donations Only
dismiss = Dismiss
remindLater = Remind Later
# Exceptions
mp3ConverterBusy = MP3 Converter unreachable, probably BUSY !
unknownError = Unknown Error
noMatchFound = NO Match Found!
noLinkFound = No Downloadable link found
linkNotValid = Entered Link is NOT Valid!
checkInternetConnection = Check Your Internet Connection
featureUnImplemented = Feature not yet implemented.
minute = min
second = sec
spotiflyerLogo = SpotiFlyer Logo
backButton = Back Button
infoTab = Info Tab
@ -31,5 +69,7 @@ linkTextBox = Link Text Box
pasteLinkHere = Paste Link Here...
enterALink = Enter A Link!
madeWith = Made with
love = Love
inIndia = in India
open = Open
byDeveloperName = by: Shabinder Singh