mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-12-22 12:47:54 +01:00
Internationalization WIP
This commit is contained in:
parent
e50cf82f6a
commit
6e517e0049
@ -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)
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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>
|
@ -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
|
||||
)
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
@ -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
|
Loading…
Reference in New Issue
Block a user