Implemented multilingual support, the default language is English, Italian, Spanish, French and German have been added.

Other languages can be added in the future.
This commit is contained in:
Rino Russo 2023-08-20 19:11:59 +02:00
parent 964fa42a0f
commit 942962fd1f
37 changed files with 950 additions and 195 deletions

View file

@ -41,6 +41,7 @@ import androidx.compose.ui.geometry.center
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shadow
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.TextFieldValue
@ -48,6 +49,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.center
import it.vfsfitvnm.vimusic.utils.drawCircle
@ -62,8 +64,8 @@ fun TextFieldDialog(
onDismiss: () -> Unit,
onDone: (String) -> Unit,
modifier: Modifier = Modifier,
cancelText: String = "Cancel",
doneText: String = "Done",
cancelText: String = stringResource(R.string.cancel),
doneText: String = stringResource(R.string.done),
initialTextInput: String = "",
singleLine: Boolean = true,
maxLines: Int = 1,
@ -167,8 +169,8 @@ fun ConfirmationDialog(
onDismiss: () -> Unit,
onConfirm: () -> Unit,
modifier: Modifier = Modifier,
cancelText: String = "Cancel",
confirmText: String = "Confirm",
cancelText: String = stringResource(R.string.cancel),
confirmText: String = stringResource(R.string.confirm),
onCancel: () -> Unit = onDismiss
) {
val (_, typography) = LocalAppearance.current

View file

@ -40,6 +40,7 @@ import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.media3.common.MediaItem
@ -70,7 +71,6 @@ import it.vfsfitvnm.vimusic.utils.formatAsDuration
import it.vfsfitvnm.vimusic.utils.medium
import it.vfsfitvnm.vimusic.utils.semiBold
import it.vfsfitvnm.vimusic.utils.thumbnail
import kotlin.system.measureTimeMillis
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.withContext
@ -90,7 +90,7 @@ fun InHistoryMediaItemMenu(
if (isHiding) {
ConfirmationDialog(
text = "Do you really want to hide this song? Its playback time and cache will be wiped.\nThis action is irreversible.",
text = stringResource(R.string.hidesong),
onDismiss = { isHiding = false },
onConfirm = {
onDismiss()
@ -366,7 +366,7 @@ fun MediaItemMenu(
if (onAddToPlaylist != null) {
SecondaryTextButton(
text = "New playlist",
text = stringResource(R.string.new_playlist),
onClick = { isCreatingNewPlaylist = true },
alternative = true
)
@ -378,7 +378,7 @@ fun MediaItemMenu(
MenuEntry(
icon = R.drawable.playlist,
text = playlistPreview.playlist.name,
secondaryText = "${playlistPreview.songCount} songs",
secondaryText = "${playlistPreview.songCount} " + stringResource(R.string.songs),
onClick = {
onDismiss()
onAddToPlaylist(playlistPreview.playlist, playlistPreview.songCount)
@ -464,7 +464,7 @@ fun MediaItemMenu(
onStartRadio?.let { onStartRadio ->
MenuEntry(
icon = R.drawable.radio,
text = "Start radio",
text = stringResource(R.string.start_radio),
onClick = {
onDismiss()
onStartRadio()
@ -475,7 +475,7 @@ fun MediaItemMenu(
onPlayNext?.let { onPlayNext ->
MenuEntry(
icon = R.drawable.play_skip_forward,
text = "Play next",
text = stringResource(R.string.play_next),
onClick = {
onDismiss()
onPlayNext()
@ -486,7 +486,7 @@ fun MediaItemMenu(
onEnqueue?.let { onEnqueue ->
MenuEntry(
icon = R.drawable.enqueue,
text = "Enqueue",
text = stringResource(R.string.enqueue),
onClick = {
onDismiss()
onEnqueue()
@ -497,7 +497,7 @@ fun MediaItemMenu(
onGoToEqualizer?.let { onGoToEqualizer ->
MenuEntry(
icon = R.drawable.equalizer,
text = "Equalizer",
text = stringResource(R.string.equalizer),
onClick = {
onDismiss()
onGoToEqualizer()
@ -521,7 +521,7 @@ fun MediaItemMenu(
if (isShowingSleepTimerDialog) {
if (sleepTimerMillisLeft != null) {
ConfirmationDialog(
text = "Do you want to stop the sleep timer?",
text = stringResource(R.string.stop_sleep_timer),
cancelText = "No",
confirmText = "Stop",
onDismiss = { isShowingSleepTimerDialog = false },
@ -539,7 +539,7 @@ fun MediaItemMenu(
}
BasicText(
text = "Set sleep timer",
text = stringResource(R.string.set_sleep_timer),
style = typography.s.semiBold,
modifier = Modifier
.padding(vertical = 8.dp, horizontal = 24.dp)
@ -604,12 +604,12 @@ fun MediaItemMenu(
.fillMaxWidth()
) {
DialogTextButton(
text = "Cancel",
text = stringResource(R.string.cancel),
onClick = { isShowingSleepTimerDialog = false }
)
DialogTextButton(
text = "Set",
text = stringResource(R.string.set),
enabled = amount > 0,
primary = true,
onClick = {
@ -624,12 +624,15 @@ fun MediaItemMenu(
MenuEntry(
icon = R.drawable.alarm,
text = "Sleep timer",
text = stringResource(R.string.sleep_timer),
onClick = { isShowingSleepTimerDialog = true },
trailingContent = sleepTimerMillisLeft?.let {
{
BasicText(
text = "${formatAsDuration(it)} left",
text = stringResource(
R.string.left,
formatAsDuration(it)
),
style = typography.xxs.medium,
modifier = modifier
.background(
@ -647,7 +650,7 @@ fun MediaItemMenu(
if (onAddToPlaylist != null) {
MenuEntry(
icon = R.drawable.playlist,
text = "Add to playlist",
text = stringResource(R.string.add_to_playlist),
onClick = { isViewingPlaylists = true },
trailingContent = {
Image(
@ -667,7 +670,7 @@ fun MediaItemMenu(
albumInfo?.let { (albumId) ->
MenuEntry(
icon = R.drawable.disc,
text = "Go to album",
text = stringResource(R.string.go_to_album),
onClick = {
onDismiss()
onGoToAlbum(albumId)
@ -680,7 +683,7 @@ fun MediaItemMenu(
artistsInfo?.forEach { (authorId, authorName) ->
MenuEntry(
icon = R.drawable.person,
text = "More of $authorName",
text = stringResource(R.string.more_of) + " $authorName",
onClick = {
onDismiss()
onGoToArtist(authorId)
@ -692,7 +695,7 @@ fun MediaItemMenu(
onRemoveFromQueue?.let { onRemoveFromQueue ->
MenuEntry(
icon = R.drawable.trash,
text = "Remove from queue",
text = stringResource(R.string.remove_from_queue),
onClick = {
onDismiss()
onRemoveFromQueue()
@ -703,7 +706,7 @@ fun MediaItemMenu(
onRemoveFromPlaylist?.let { onRemoveFromPlaylist ->
MenuEntry(
icon = R.drawable.trash,
text = "Remove from playlist",
text = stringResource(R.string.remove_from_playlist),
onClick = {
onDismiss()
onRemoveFromPlaylist()
@ -714,7 +717,7 @@ fun MediaItemMenu(
onHideFromDatabase?.let { onHideFromDatabase ->
MenuEntry(
icon = R.drawable.trash,
text = "Hide",
text = stringResource(R.string.hide),
onClick = onHideFromDatabase
)
}
@ -722,7 +725,7 @@ fun MediaItemMenu(
onRemoveFromQuickPicks?.let {
MenuEntry(
icon = R.drawable.trash,
text = "Hide from \"Quick picks\"",
text = stringResource(R.string.hide_from_quick_picks),
onClick = {
onDismiss()
onRemoveFromQuickPicks()

View file

@ -15,6 +15,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.valentinilk.shimmer.shimmer
import it.vfsfitvnm.compose.persist.PersistMapCleanup
@ -182,8 +183,8 @@ fun AlbumScreen(browseId: String) {
tabIndex = tabIndex,
onTabChanged = { tabIndex = it },
tabColumnContent = { Item ->
Item(0, "Songs", R.drawable.musical_notes)
Item(1, "Other versions", R.drawable.disc)
Item(0, stringResource(R.string.songs), R.drawable.musical_notes)
Item(1, stringResource(R.string.other_versions), R.drawable.disc)
}
) { currentTabIndex ->
saveableStateHolder.SaveableStateProvider(key = currentTabIndex) {
@ -203,7 +204,7 @@ fun AlbumScreen(browseId: String) {
headerContent = headerContent,
initialPlaceholderCount = 1,
continuationPlaceholderCount = 1,
emptyItemsText = "This album doesn't have any alternative version",
emptyItemsText = stringResource(R.string.album_no_alternative_version),
itemsPageProvider = albumPage?.let {
({
Result.success(

View file

@ -21,6 +21,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import it.vfsfitvnm.compose.persist.persistList
import it.vfsfitvnm.vimusic.Database
@ -86,7 +87,7 @@ fun AlbumSongs(
Column(horizontalAlignment = Alignment.CenterHorizontally) {
headerContent {
SecondaryTextButton(
text = "Enqueue",
text = stringResource(R.string.enqueue),
enabled = songs.isNotEmpty(),
onClick = {
binder?.player?.enqueue(songs.map(Song::asMediaItem))

View file

@ -19,6 +19,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import it.vfsfitvnm.compose.persist.persist
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
@ -81,7 +82,7 @@ fun ArtistLocalSongs(
Column(horizontalAlignment = Alignment.CenterHorizontally) {
headerContent {
SecondaryTextButton(
text = "Enqueue",
text = stringResource(R.string.enqueue),
enabled = !songs.isNullOrEmpty(),
onClick = {
binder?.player?.enqueue(songs!!.map(Song::asMediaItem))

View file

@ -24,6 +24,7 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.innertube.Innertube
@ -103,7 +104,7 @@ fun ArtistOverview(
headerContent {
youtubeArtistPage?.shuffleEndpoint?.let { endpoint ->
SecondaryTextButton(
text = "Shuffle",
text = stringResource(R.string.shuffle),
onClick = {
binder?.stopRadio()
binder?.playRadio(endpoint)
@ -125,14 +126,14 @@ fun ArtistOverview(
.padding(endPaddingValues)
) {
BasicText(
text = "Songs",
text = stringResource(R.string.songs),
style = typography.m.semiBold,
modifier = sectionTextModifier
)
youtubeArtistPage.songsEndpoint?.let {
BasicText(
text = "View all",
text = stringResource(R.string.view_all),
style = typography.xs.secondary,
modifier = sectionTextModifier
.clickable(onClick = onViewAllSongsClick),
@ -178,14 +179,14 @@ fun ArtistOverview(
.padding(endPaddingValues)
) {
BasicText(
text = "Albums",
text = stringResource(R.string.albums),
style = typography.m.semiBold,
modifier = sectionTextModifier
)
youtubeArtistPage.albumsEndpoint?.let {
BasicText(
text = "View all",
text = stringResource(R.string.view_all),
style = typography.xs.secondary,
modifier = sectionTextModifier
.clickable(onClick = onViewAllAlbumsClick),
@ -299,7 +300,7 @@ fun ArtistOverview(
if (attributionsIndex != -1) {
BasicText(
text = "From Wikipedia under Creative Commons Attribution CC-BY-SA 3.0",
text = stringResource(R.string.from_wikipedia_cca),
style = typography.xxs.color(colorPalette.textDisabled).align(TextAlign.End),
modifier = Modifier
.padding(horizontal = 16.dp)

View file

@ -15,6 +15,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.valentinilk.shimmer.shimmer
import it.vfsfitvnm.compose.persist.PersistMapCleanup
@ -176,16 +177,17 @@ fun ArtistScreen(browseId: String) {
tabIndex = tabIndex,
onTabChanged = { tabIndex = it },
tabColumnContent = { Item ->
Item(0, "Overview", R.drawable.sparkles)
Item(1, "Songs", R.drawable.musical_notes)
Item(2, "Albums", R.drawable.disc)
Item(3, "Singles", R.drawable.disc)
Item(4, "Library", R.drawable.library)
Item(0, stringResource(R.string.overview), R.drawable.sparkles)
Item(1, stringResource(R.string.songs), R.drawable.musical_notes)
Item(2, stringResource(R.string.albums), R.drawable.disc)
Item(3, stringResource(R.string.singles), R.drawable.disc)
Item(4, stringResource(R.string.library), R.drawable.library)
},
) { currentTabIndex ->
saveableStateHolder.SaveableStateProvider(key = currentTabIndex) {
when (currentTabIndex) {
0 -> ArtistOverview(
0 -> {
ArtistOverview(
youtubeArtistPage = artistPage,
thumbnailContent = thumbnailContent,
headerContent = headerContent,
@ -194,6 +196,7 @@ fun ArtistScreen(browseId: String) {
onViewAllAlbumsClick = { tabIndex = 2 },
onViewAllSinglesClick = { tabIndex = 3 },
)
}
1 -> {
val binder = LocalPlayerServiceBinder.current
@ -267,7 +270,7 @@ fun ArtistScreen(browseId: String) {
ItemsPage(
tag = "artist/$browseId/albums",
headerContent = headerContent,
emptyItemsText = "This artist didn't release any album",
emptyItemsText = stringResource(R.string.artist_no_release_album),
itemsPageProvider = artistPage?.let {
({ continuation ->
continuation?.let {
@ -317,7 +320,7 @@ fun ArtistScreen(browseId: String) {
ItemsPage(
tag = "artist/$browseId/singles",
headerContent = headerContent,
emptyItemsText = "This artist didn't release any single",
emptyItemsText = stringResource(R.string.artist_no_release_single),
itemsPageProvider = artistPage?.let {
({ continuation ->
continuation?.let {
@ -360,7 +363,8 @@ fun ArtistScreen(browseId: String) {
)
}
4 -> ArtistLocalSongs(
4 -> {
ArtistLocalSongs(
browseId = browseId,
headerContent = headerContent,
thumbnailContent = thumbnailContent,
@ -371,3 +375,4 @@ fun ArtistScreen(browseId: String) {
}
}
}
}

View file

@ -6,6 +6,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.res.stringResource
import it.vfsfitvnm.compose.persist.PersistMapCleanup
import it.vfsfitvnm.compose.routing.RouteHandler
import it.vfsfitvnm.vimusic.R
@ -38,8 +39,8 @@ fun BuiltInPlaylistScreen(builtInPlaylist: BuiltInPlaylist) {
tabIndex = tabIndex,
onTabChanged = onTabIndexChanged,
tabColumnContent = { Item ->
Item(0, "Favorites", R.drawable.heart)
Item(1, "Offline", R.drawable.airplane)
Item(0, stringResource(R.string.favorites), R.drawable.heart)
Item(1, stringResource(R.string.offline), R.drawable.airplane)
}
) { currentTabIndex ->
saveableStateHolder.SaveableStateProvider(key = currentTabIndex) {

View file

@ -19,6 +19,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.compose.persist.persistList
import it.vfsfitvnm.vimusic.Database
@ -94,14 +95,14 @@ fun BuiltInPlaylistSongs(builtInPlaylist: BuiltInPlaylist) {
) {
Header(
title = when (builtInPlaylist) {
BuiltInPlaylist.Favorites -> "Favorites"
BuiltInPlaylist.Offline -> "Offline"
BuiltInPlaylist.Favorites -> stringResource(R.string.favorites)
BuiltInPlaylist.Offline -> stringResource(R.string.offline)
},
modifier = Modifier
.padding(bottom = 8.dp)
) {
SecondaryTextButton(
text = "Enqueue",
text = stringResource(R.string.enqueue),
enabled = songs.isNotEmpty(),
onClick = {
binder?.player?.enqueue(songs.map(Song::asMediaItem))

View file

@ -15,16 +15,15 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.compose.persist.persist
import it.vfsfitvnm.vimusic.Database
@ -85,7 +84,7 @@ fun HomeAlbums(
key = "header",
contentType = 0
) {
Header(title = "Albums") {
Header(title = stringResource(R.string.albums)) {
HeaderIconButton(
icon = R.drawable.calendar,
color = if (sortBy == AlbumSortBy.Year) colorPalette.text else colorPalette.textDisabled,

View file

@ -27,6 +27,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.compose.persist.persistList
import it.vfsfitvnm.vimusic.Database
@ -94,7 +95,7 @@ fun HomeArtistList(
contentType = 0,
span = { GridItemSpan(maxLineSpan) }
) {
Header(title = "Artists") {
Header(title = stringResource(R.string.artists)) {
HeaderIconButton(
icon = R.drawable.text,
color = if (sortBy == ArtistSortBy.Name) colorPalette.text else colorPalette.textDisabled,

View file

@ -29,6 +29,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.compose.persist.persistList
import it.vfsfitvnm.vimusic.Database
@ -69,7 +70,7 @@ fun HomePlaylists(
if (isCreatingANewPlaylist) {
TextFieldDialog(
hintText = "Enter the playlist name",
hintText = stringResource(R.string.enter_the_playlist_name),
onDismiss = {
isCreatingANewPlaylist = false
},
@ -116,9 +117,9 @@ fun HomePlaylists(
.background(colorPalette.background0)
) {
item(key = "header", contentType = 0, span = { GridItemSpan(maxLineSpan) }) {
Header(title = "Playlists") {
Header(title = stringResource(R.string.playlists)) {
SecondaryTextButton(
text = "New playlist",
text = stringResource(R.string.new_playlist),
onClick = { isCreatingANewPlaylist = true }
)
@ -164,7 +165,7 @@ fun HomePlaylists(
PlaylistItem(
icon = R.drawable.heart,
colorTint = colorPalette.red,
name = "Favorites",
name = stringResource(R.string.favorites),
songCount = null,
thumbnailSizeDp = thumbnailSizeDp,
alternative = true,
@ -178,7 +179,7 @@ fun HomePlaylists(
PlaylistItem(
icon = R.drawable.airplane,
colorTint = colorPalette.blue,
name = "Offline",
name = stringResource(R.string.offline),
songCount = null,
thumbnailSizeDp = thumbnailSizeDp,
alternative = true,

View file

@ -5,6 +5,7 @@ import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.runtime.Composable
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import it.vfsfitvnm.compose.persist.PersistMapCleanup
import it.vfsfitvnm.compose.routing.RouteHandler
import it.vfsfitvnm.compose.routing.defaultStacking
@ -119,11 +120,11 @@ fun HomeScreen(onPlaylistUrl: (String) -> Unit) {
tabIndex = tabIndex,
onTabChanged = onTabChanged,
tabColumnContent = { Item ->
Item(0, "Quick picks", R.drawable.sparkles)
Item(1, "Songs", R.drawable.musical_notes)
Item(2, "Playlists", R.drawable.playlist)
Item(3, "Artists", R.drawable.person)
Item(4, "Albums", R.drawable.disc)
Item(0, stringResource(R.string.quick_picks), R.drawable.sparkles)
Item(1, stringResource(R.string.songs), R.drawable.musical_notes)
Item(2, stringResource(R.string.playlists), R.drawable.playlist)
Item(3, stringResource(R.string.artists), R.drawable.person)
Item(4, stringResource(R.string.albums), R.drawable.disc)
}
) { currentTabIndex ->
saveableStateHolder.SaveableStateProvider(key = currentTabIndex) {

View file

@ -29,6 +29,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.compose.persist.persistList
@ -102,7 +103,7 @@ fun HomeSongs(
key = "header",
contentType = 0
) {
Header(title = "Songs") {
Header(title = stringResource(R.string.songs)) {
HeaderIconButton(
icon = R.drawable.trending,
color = if (sortBy == SongSortBy.PlayTime) colorPalette.text else colorPalette.textDisabled,

View file

@ -37,6 +37,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.compose.persist.persist
import it.vfsfitvnm.innertube.Innertube
@ -152,7 +153,7 @@ fun QuickPicks(
)
) {
Header(
title = "Quick picks",
title = stringResource(R.string.quick_picks),
modifier = Modifier
.padding(endPaddingValues)
)
@ -248,7 +249,7 @@ fun QuickPicks(
related.albums?.let { albums ->
BasicText(
text = "Related albums",
text = stringResource(R.string.related_albums),
style = typography.m.semiBold,
modifier = sectionTextModifier
)
@ -272,7 +273,7 @@ fun QuickPicks(
related.artists?.let { artists ->
BasicText(
text = "Similar artists",
text = stringResource(R.string.similar_artists),
style = typography.m.semiBold,
modifier = sectionTextModifier
)
@ -296,7 +297,7 @@ fun QuickPicks(
related.playlists?.let { playlists ->
BasicText(
text = "Playlists you might like",
text = stringResource(R.string.playlists_you_might_like),
style = typography.m.semiBold,
modifier = Modifier
.padding(horizontal = 16.dp)
@ -323,7 +324,7 @@ fun QuickPicks(
Unit
} ?: relatedPageResult?.exceptionOrNull()?.let {
BasicText(
text = "An error has occurred",
text = stringResource(R.string.an_error_has_occurred),
style = typography.s.secondary.center,
modifier = Modifier
.align(Alignment.CenterHorizontally)

View file

@ -4,6 +4,7 @@ import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.runtime.Composable
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.res.stringResource
import it.vfsfitvnm.compose.persist.PersistMapCleanup
import it.vfsfitvnm.compose.routing.RouteHandler
import it.vfsfitvnm.vimusic.R
@ -28,7 +29,7 @@ fun LocalPlaylistScreen(playlistId: Long) {
tabIndex = 0,
onTabChanged = { },
tabColumnContent = { Item ->
Item(0, "Songs", R.drawable.musical_notes)
Item(0, stringResource(R.string.songs), R.drawable.musical_notes)
}
) { currentTabIndex ->
saveableStateHolder.SaveableStateProvider(currentTabIndex) {

View file

@ -22,6 +22,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.compose.persist.persist
import it.vfsfitvnm.innertube.Innertube
@ -102,7 +103,7 @@ fun LocalPlaylistSongs(
if (isRenaming) {
TextFieldDialog(
hintText = "Enter the playlist name",
hintText = stringResource(R.string.enter_the_playlist_name),
initialTextInput = playlistWithSongs?.playlist?.name ?: "",
onDismiss = { isRenaming = false },
onDone = { text ->
@ -119,7 +120,7 @@ fun LocalPlaylistSongs(
if (isDeleting) {
ConfirmationDialog(
text = "Do you really want to delete this playlist?",
text = stringResource(R.string.delete_playlist),
onDismiss = { isDeleting = false },
onConfirm = {
query {
@ -154,7 +155,7 @@ fun LocalPlaylistSongs(
.padding(bottom = 8.dp)
) {
SecondaryTextButton(
text = "Enqueue",
text = stringResource(R.string.enqueue),
enabled = playlistWithSongs?.songs?.isNotEmpty() == true,
onClick = {
playlistWithSongs?.songs
@ -179,7 +180,7 @@ fun LocalPlaylistSongs(
playlistWithSongs?.playlist?.browseId?.let { browseId ->
MenuEntry(
icon = R.drawable.sync,
text = "Sync",
text = stringResource(R.string.sync),
onClick = {
menuState.hide()
transaction {
@ -210,7 +211,7 @@ fun LocalPlaylistSongs(
MenuEntry(
icon = R.drawable.pencil,
text = "Rename",
text = stringResource(R.string.rename),
onClick = {
menuState.hide()
isRenaming = true
@ -219,7 +220,7 @@ fun LocalPlaylistSongs(
MenuEntry(
icon = R.drawable.trash,
text = "Delete",
text = stringResource(R.string.delete),
onClick = {
menuState.hide()
isDeleting = true

View file

@ -44,6 +44,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.media3.common.C
@ -169,7 +170,7 @@ fun Lyrics(
if (isEditing) {
TextFieldDialog(
hintText = "Enter the lyrics",
hintText = stringResource(R.string.enter_the_lyrics),
initialTextInput = text ?: "",
singleLine = false,
maxLines = 10,
@ -334,8 +335,14 @@ fun Lyrics(
Menu {
MenuEntry(
icon = R.drawable.time,
text = "Show ${if (isShowingSynchronizedLyrics) "un" else ""}synchronized lyrics",
secondaryText = if (isShowingSynchronizedLyrics) null else "Provided by kugou.com",
text = stringResource(R.string.show) + " ${
if (isShowingSynchronizedLyrics) stringResource(
R.string.unsynchronized_lyrics
) else stringResource(R.string.synchronized_lyrics)
}",
secondaryText = if (isShowingSynchronizedLyrics) null else stringResource(
R.string.provided_by
) + " kugou.com",
onClick = {
menuState.hide()
isShowingSynchronizedLyrics =
@ -345,7 +352,7 @@ fun Lyrics(
MenuEntry(
icon = R.drawable.pencil,
text = "Edit lyrics",
text = stringResource(R.string.edit_lyrics),
onClick = {
menuState.hide()
isEditing = true
@ -354,7 +361,7 @@ fun Lyrics(
MenuEntry(
icon = R.drawable.search,
text = "Search lyrics online",
text = stringResource(R.string.search_lyrics_online),
onClick = {
menuState.hide()
val mediaMetadata = mediaMetadataProvider()
@ -376,7 +383,7 @@ fun Lyrics(
MenuEntry(
icon = R.drawable.download,
text = "Fetch lyrics again",
text = stringResource(R.string.fetch_lyrics_again),
enabled = lyrics != null,
onClick = {
menuState.hide()

View file

@ -48,6 +48,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
@ -331,7 +332,7 @@ fun Queue(
.height(64.dp)
) {
BasicText(
text = "${windows.size} songs",
text = "${windows.size} " + stringResource(R.string.songs),
style = typography.xxs.medium,
modifier = Modifier
.background(
@ -361,7 +362,7 @@ fun Queue(
.animateContentSize()
) {
BasicText(
text = "Queue loop ",
text = stringResource(R.string.queue_loop),
style = typography.xxs.medium,
)

View file

@ -24,6 +24,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.media3.datasource.cache.Cache
import androidx.media3.datasource.cache.CacheSpan
@ -32,6 +33,7 @@ import it.vfsfitvnm.innertube.models.bodies.PlayerBody
import it.vfsfitvnm.innertube.requests.player
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.models.Format
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.onOverlay
@ -140,27 +142,27 @@ fun StatsForNerds(
) {
Column(horizontalAlignment = Alignment.End) {
BasicText(
text = "Id",
text = stringResource(R.string.id),
style = typography.xs.medium.color(colorPalette.onOverlay)
)
BasicText(
text = "Itag",
text = stringResource(R.string.itag),
style = typography.xs.medium.color(colorPalette.onOverlay)
)
BasicText(
text = "Bitrate",
text = stringResource(R.string.bitrate),
style = typography.xs.medium.color(colorPalette.onOverlay)
)
BasicText(
text = "Size",
text = stringResource(R.string.size),
style = typography.xs.medium.color(colorPalette.onOverlay)
)
BasicText(
text = "Cached",
text = stringResource(R.string.cached),
style = typography.xs.medium.color(colorPalette.onOverlay)
)
BasicText(
text = "Loudness",
text = stringResource(R.string.loudness),
style = typography.xs.medium.color(colorPalette.onOverlay)
)
}

View file

@ -4,6 +4,7 @@ import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.runtime.Composable
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.res.stringResource
import it.vfsfitvnm.compose.persist.PersistMapCleanup
import it.vfsfitvnm.compose.routing.RouteHandler
import it.vfsfitvnm.vimusic.R
@ -27,7 +28,7 @@ fun PlaylistScreen(browseId: String) {
tabIndex = 0,
onTabChanged = { },
tabColumnContent = { Item ->
Item(0, "Songs", R.drawable.musical_notes)
Item(0, stringResource(R.string.songs), R.drawable.musical_notes)
}
) { currentTabIndex ->
saveableStateHolder.SaveableStateProvider(key = currentTabIndex) {

View file

@ -24,6 +24,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import com.valentinilk.shimmer.shimmer
import it.vfsfitvnm.compose.persist.persist
import it.vfsfitvnm.innertube.Innertube
@ -92,7 +93,7 @@ fun PlaylistSongList(
if (isImportingPlaylist) {
TextFieldDialog(
hintText = "Enter the playlist name",
hintText = stringResource(R.string.enter_the_playlist_name),
initialTextInput = playlistPage?.title ?: "",
onDismiss = { isImportingPlaylist = false },
onDone = { text ->
@ -125,7 +126,7 @@ fun PlaylistSongList(
} else {
Header(title = playlistPage?.title ?: "Unknown") {
SecondaryTextButton(
text = "Enqueue",
text = stringResource(R.string.enqueue),
enabled = playlistPage?.songsPage?.items?.isNotEmpty() == true,
onClick = {
playlistPage?.songsPage?.items?.map(Innertube.SongItem::asMediaItem)?.let { mediaItems ->

View file

@ -37,6 +37,7 @@ import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.TextFieldValue
@ -172,7 +173,7 @@ fun OnlineSearch(
if (textFieldValue.text.isNotEmpty()) {
SecondaryTextButton(
text = "Clear",
text = stringResource(R.string.clear),
onClick = { onTextFieldValueChanged(TextFieldValue()) }
)
}
@ -304,7 +305,7 @@ fun OnlineSearch(
.fillMaxSize()
) {
BasicText(
text = "An error has occurred.",
text = stringResource(R.string.error),
style = typography.s.secondary.center,
modifier = Modifier
.align(Alignment.Center)

View file

@ -14,6 +14,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.TextFieldValue
import it.vfsfitvnm.compose.persist.PersistMapCleanup
@ -66,7 +67,7 @@ fun SearchScreen(
.align(Alignment.CenterEnd)
) {
BasicText(
text = "Enter a name",
text = stringResource(R.string.enter_a_name),
maxLines = 1,
style = LocalAppearance.current.typography.xxl.secondary
)
@ -82,8 +83,8 @@ fun SearchScreen(
tabIndex = tabIndex,
onTabChanged = onTabChanged,
tabColumnContent = { Item ->
Item(0, "Online", R.drawable.globe)
Item(1, "Library", R.drawable.library)
Item(0, stringResource(R.string.online), R.drawable.globe)
Item(1, stringResource(R.string.library), R.drawable.library)
}
) { currentTabIndex ->
saveableStateHolder.SaveableStateProvider(currentTabIndex) {

View file

@ -10,6 +10,7 @@ import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.compose.persist.PersistMapCleanup
import it.vfsfitvnm.compose.persist.persistMap
@ -75,7 +76,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
)
}
val emptyItemsText = "No results found. Please try a different query or category"
val emptyItemsText = stringResource(R.string.no_results_found)
Scaffold(
topIconButtonId = R.drawable.chevron_back,
@ -83,12 +84,12 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
tabIndex = tabIndex,
onTabChanged = onTabIndexChanges,
tabColumnContent = { Item ->
Item(0, "Songs", R.drawable.musical_notes)
Item(1, "Albums", R.drawable.disc)
Item(2, "Artists", R.drawable.person)
Item(3, "Videos", R.drawable.film)
Item(4, "Playlists", R.drawable.playlist)
Item(5, "Featured", R.drawable.playlist)
Item(0, stringResource(R.string.songs), R.drawable.musical_notes)
Item(1, stringResource(R.string.albums), R.drawable.disc)
Item(2, stringResource(R.string.artists), R.drawable.person)
Item(3, stringResource(R.string.videos), R.drawable.film)
Item(4, stringResource(R.string.playlists), R.drawable.playlist)
Item(5, stringResource(R.string.featured), R.drawable.playlist)
}
) { tabIndex ->
saveableStateHolder.SaveableStateProvider(tabIndex) {

View file

@ -14,8 +14,10 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import it.vfsfitvnm.vimusic.BuildConfig
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.secondary
@ -48,7 +50,7 @@ fun About() {
SettingsEntry(
title = "GitHub",
text = "View the source code",
text = stringResource(R.string.view_the_source_code),
onClick = {
uriHandler.openUri("https://github.com/vfsfitvnm/ViMusic")
}
@ -59,16 +61,16 @@ fun About() {
SettingsEntryGroupText(title = "TROUBLESHOOTING")
SettingsEntry(
title = "Report an issue",
text = "You will be redirected to GitHub",
title = stringResource(R.string.report_an_issue),
text = stringResource(R.string.you_will_be_redirected_to_github),
onClick = {
uriHandler.openUri("https://github.com/vfsfitvnm/ViMusic/issues/new?assignees=&labels=bug&template=bug_report.yaml")
}
)
SettingsEntry(
title = "Request a feature or suggest an idea",
text = "You will be redirected to GitHub",
title = stringResource(R.string.request_a_feature_or_suggest_an_idea),
text = stringResource(R.string.you_will_be_redirected_to_github),
onClick = {
uriHandler.openUri("https://github.com/vfsfitvnm/ViMusic/issues/new?assignees=&labels=enhancement&template=feature_request.yaml")
}

View file

@ -17,8 +17,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.enums.ColorPaletteMode
import it.vfsfitvnm.vimusic.enums.ColorPaletteName
import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness
@ -62,18 +64,18 @@ fun AppearanceSettings() {
.asPaddingValues()
)
) {
Header(title = "Appearance")
Header(title = stringResource(R.string.appearance))
SettingsEntryGroupText(title = "COLORS")
SettingsEntryGroupText(title = stringResource(R.string.colors))
EnumValueSelectorSettingsEntry(
title = "Theme",
title = stringResource(R.string.theme),
selectedValue = colorPaletteName,
onValueSelected = { colorPaletteName = it }
)
EnumValueSelectorSettingsEntry(
title = "Theme mode",
title = stringResource(R.string.theme_mode),
selectedValue = colorPaletteMode,
isEnabled = colorPaletteName != ColorPaletteName.PureBlack,
onValueSelected = { colorPaletteMode = it }
@ -81,17 +83,24 @@ fun AppearanceSettings() {
SettingsGroupSpacer()
SettingsEntryGroupText(title = "SHAPES")
SettingsEntryGroupText(title = stringResource(R.string.shapes))
EnumValueSelectorSettingsEntry(
title = "Thumbnail roundness",
title = stringResource(R.string.thumbnail_roundness),
selectedValue = thumbnailRoundness,
onValueSelected = { thumbnailRoundness = it },
trailingContent = {
Spacer(
modifier = Modifier
.border(width = 1.dp, color = colorPalette.accent, shape = thumbnailRoundness.shape())
.background(color = colorPalette.background1, shape = thumbnailRoundness.shape())
.border(
width = 1.dp,
color = colorPalette.accent,
shape = thumbnailRoundness.shape()
)
.background(
color = colorPalette.background1,
shape = thumbnailRoundness.shape()
)
.size(36.dp)
)
}
@ -99,18 +108,18 @@ fun AppearanceSettings() {
SettingsGroupSpacer()
SettingsEntryGroupText(title = "TEXT")
SettingsEntryGroupText(title = stringResource(R.string.text))
SwitchSettingEntry(
title = "Use system font",
text = "Use the font applied by the system",
title = stringResource(R.string.use_system_font),
text = stringResource(R.string.use_font_by_the_system),
isChecked = useSystemFont,
onCheckedChange = { useSystemFont = it }
)
SwitchSettingEntry(
title = "Apply font padding",
text = "Add spacing around texts",
title = stringResource(R.string.apply_font_padding),
text = stringResource(R.string.add_spacing_around_texts),
isChecked = applyFontPadding,
onCheckedChange = { applyFontPadding = it }
)
@ -118,11 +127,11 @@ fun AppearanceSettings() {
if (!isAtLeastAndroid13) {
SettingsGroupSpacer()
SettingsEntryGroupText(title = "LOCKSCREEN")
SettingsEntryGroupText(title = stringResource(R.string.lockscreen))
SwitchSettingEntry(
title = "Show song cover",
text = "Use the playing song cover as the lockscreen wallpaper",
title = stringResource(R.string.show_song_cover),
text = stringResource(R.string.use_song_cover_on_lockscreen),
isChecked = isShowingThumbnailInLockscreen,
onCheckedChange = { isShowingThumbnailInLockscreen = it }
)

View file

@ -18,10 +18,12 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import coil.Coil
import coil.annotation.ExperimentalCoilApi
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.enums.CoilDiskCacheMaxSize
import it.vfsfitvnm.vimusic.enums.ExoPlayerDiskCacheMaxSize
import it.vfsfitvnm.vimusic.ui.components.themed.Header
@ -58,9 +60,9 @@ fun CacheSettings() {
.asPaddingValues()
)
) {
Header(title = "Cache")
Header(title = stringResource(R.string.cache))
SettingsDescription(text = "When the cache runs out of space, the resources that haven't been accessed for the longest time are cleared")
SettingsDescription(text = stringResource(R.string.cache_cleared))
Coil.imageLoader(context).diskCache?.let { diskCache ->
val diskCacheSize = remember(diskCache) {
@ -69,7 +71,7 @@ fun CacheSettings() {
SettingsGroupSpacer()
SettingsEntryGroupText(title = "IMAGE CACHE")
SettingsEntryGroupText(title = stringResource(R.string.image_cache))
SettingsDescription(
text = "${
@ -81,7 +83,7 @@ fun CacheSettings() {
)
EnumValueSelectorSettingsEntry(
title = "Max size",
title = stringResource(R.string.max_size),
selectedValue = coilDiskCacheMaxSize,
onValueSelected = { coilDiskCacheMaxSize = it }
)
@ -96,7 +98,7 @@ fun CacheSettings() {
SettingsGroupSpacer()
SettingsEntryGroupText(title = "SONG CACHE")
SettingsEntryGroupText(title = stringResource(R.string.song_cache))
SettingsDescription(
text = buildString {
@ -110,7 +112,7 @@ fun CacheSettings() {
)
EnumValueSelectorSettingsEntry(
title = "Max size",
title = stringResource(R.string.max_size),
selectedValue = exoPlayerDiskCacheMaxSize,
onValueSelected = { exoPlayerDiskCacheMaxSize = it }
)

View file

@ -20,8 +20,10 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.internal
import it.vfsfitvnm.vimusic.path
import it.vfsfitvnm.vimusic.query
@ -94,16 +96,16 @@ fun DatabaseSettings() {
.asPaddingValues()
)
) {
Header(title = "Database")
Header(title = stringResource(R.string.database))
SettingsEntryGroupText(title = "CLEANUP")
SettingsEntryGroupText(title = stringResource(R.string.cleanup))
SettingsEntry(
title = "Reset quick picks",
title = stringResource(R.string.reset_quick_picks),
text = if (eventsCount > 0) {
"Delete $eventsCount playback events"
stringResource(R.string.delete_playback_events, eventsCount)
} else {
"Quick picks are cleared"
stringResource(R.string.quick_picks_are_cleared)
},
isEnabled = eventsCount > 0,
onClick = { query(Database::clearEvents) }
@ -111,13 +113,13 @@ fun DatabaseSettings() {
SettingsGroupSpacer()
SettingsEntryGroupText(title = "BACKUP")
SettingsEntryGroupText(title = stringResource(R.string.backup))
SettingsDescription(text = "Personal preferences (i.e. the theme mode) and the cache are excluded.")
SettingsDescription(text = stringResource(R.string.personal_preference))
SettingsEntry(
title = "Backup",
text = "Export the database to the external storage",
title = stringResource(R.string.backup_1),
text = stringResource(R.string.export_the_database),
onClick = {
@SuppressLint("SimpleDateFormat")
val dateFormat = SimpleDateFormat("yyyyMMddHHmmss")
@ -132,13 +134,16 @@ fun DatabaseSettings() {
SettingsGroupSpacer()
SettingsEntryGroupText(title = "RESTORE")
SettingsEntryGroupText(title = stringResource(R.string.restore))
ImportantSettingsDescription(text = "Existing data will be overwritten.\n${context.applicationInfo.nonLocalizedLabel} will automatically close itself after restoring the database.")
ImportantSettingsDescription(text = stringResource(
R.string.existing_data_will_be_overwritten,
context.applicationInfo.nonLocalizedLabel
))
SettingsEntry(
title = "Restore",
text = "Import the database from the external storage",
title = stringResource(R.string.restore_1),
text = stringResource(R.string.import_the_database),
onClick = {
try {
restoreLauncher.launch(

View file

@ -28,8 +28,10 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.service.PlayerMediaBrowserService
import it.vfsfitvnm.vimusic.ui.components.themed.Header
@ -98,36 +100,36 @@ fun OtherSettings() {
.asPaddingValues()
)
) {
Header(title = "Other")
Header(title = stringResource(R.string.other))
SettingsEntryGroupText(title = "ANDROID AUTO")
SettingsEntryGroupText(title = stringResource(R.string.android_auto))
SettingsDescription(text = "Remember to enable \"Unknown sources\" in the Developer Settings of Android Auto.")
SettingsDescription(text = stringResource(R.string.enable_unknown_sources))
SwitchSettingEntry(
title = "Android Auto",
text = "Enable Android Auto support",
title = stringResource(R.string.android_auto_1),
text = stringResource(R.string.enable_android_auto_support),
isChecked = isAndroidAutoEnabled,
onCheckedChange = { isAndroidAutoEnabled = it }
)
SettingsGroupSpacer()
SettingsEntryGroupText(title = "SEARCH HISTORY")
SettingsEntryGroupText(title = stringResource(R.string.search_history))
SwitchSettingEntry(
title = "Pause search history",
text = "Neither save new searched queries nor show history",
title = stringResource(R.string.pause_search_history),
text = stringResource(R.string.neither_save_new_searched_query),
isChecked = pauseSearchHistory,
onCheckedChange = { pauseSearchHistory = it }
)
SettingsEntry(
title = "Clear search history",
title = stringResource(R.string.clear_search_history),
text = if (queriesCount > 0) {
"Delete $queriesCount search queries"
} else {
"History is empty"
stringResource(R.string.history_is_empty)
},
isEnabled = queriesCount > 0,
onClick = { query(Database::clearQueries) }
@ -135,21 +137,21 @@ fun OtherSettings() {
SettingsGroupSpacer()
SettingsEntryGroupText(title = "SERVICE LIFETIME")
SettingsEntryGroupText(title = stringResource(R.string.service_lifetime))
ImportantSettingsDescription(text = "If battery optimizations are applied, the playback notification can suddenly disappear when paused.")
ImportantSettingsDescription(text = stringResource(R.string.battery_optimizations_applied))
if (isAtLeastAndroid12) {
SettingsDescription(text = "Since Android 12, disabling battery optimizations is required for the \"Invincible service\" option to take effect.")
SettingsDescription(text = stringResource(R.string.is_android12))
}
SettingsEntry(
title = "Ignore battery optimizations",
title = stringResource(R.string.ignore_battery_optimizations),
isEnabled = !isIgnoringBatteryOptimizations,
text = if (isIgnoringBatteryOptimizations) {
"Already unrestricted"
stringResource(R.string.already_unrestricted)
} else {
"Disable background restrictions"
stringResource(R.string.disable_background_restrictions)
},
onClick = {
if (!isAtLeastAndroid6) return@SettingsEntry
@ -173,8 +175,8 @@ fun OtherSettings() {
)
SwitchSettingEntry(
title = "Invincible service",
text = "When turning off battery optimizations is not enough",
title = stringResource(R.string.invincible_service),
text = stringResource(R.string.turning_off_battery_optimizations_is_not_enough),
isChecked = isInvincibilityEnabled,
onCheckedChange = { isInvincibilityEnabled = it }
)

View file

@ -20,8 +20,10 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid6
@ -61,13 +63,13 @@ fun PlayerSettings() {
.asPaddingValues()
)
) {
Header(title = "Player & Audio")
Header(title = stringResource(R.string.player_audio))
SettingsEntryGroupText(title = "PLAYER")
SettingsEntryGroupText(title = stringResource(R.string.player))
SwitchSettingEntry(
title = "Persistent queue",
text = "Save and restore playing songs",
title = stringResource(R.string.persistent_queue),
text = stringResource(R.string.save_and_restore_playing_songs),
isChecked = persistentQueue,
onCheckedChange = {
persistentQueue = it
@ -76,8 +78,8 @@ fun PlayerSettings() {
if (isAtLeastAndroid6) {
SwitchSettingEntry(
title = "Resume playback",
text = "When a wired or bluetooth device is connected",
title = stringResource(R.string.resume_playback),
text = stringResource(R.string.when_device_is_connected),
isChecked = resumePlaybackWhenDeviceConnected,
onCheckedChange = {
resumePlaybackWhenDeviceConnected = it
@ -87,11 +89,11 @@ fun PlayerSettings() {
SettingsGroupSpacer()
SettingsEntryGroupText(title = "AUDIO")
SettingsEntryGroupText(title = stringResource(R.string.audio))
SwitchSettingEntry(
title = "Skip silence",
text = "Skip silent parts during playback",
title = stringResource(R.string.skip_silence),
text = stringResource(R.string.skip_silent_parts_during_playback),
isChecked = skipSilence,
onCheckedChange = {
skipSilence = it
@ -99,8 +101,8 @@ fun PlayerSettings() {
)
SwitchSettingEntry(
title = "Loudness normalization",
text = "Adjust the volume to a fixed level",
title = stringResource(R.string.loudness_normalization),
text = stringResource(R.string.autoadjust_the_volume),
isChecked = volumeNormalization,
onCheckedChange = {
volumeNormalization = it
@ -108,8 +110,8 @@ fun PlayerSettings() {
)
SettingsEntry(
title = "Equalizer",
text = "Interact with the system equalizer",
title = stringResource(R.string.equalizer),
text = stringResource(R.string.interact_with_the_system_equalizer),
onClick = {
val intent = Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL).apply {
putExtra(AudioEffect.EXTRA_AUDIO_SESSION, binder?.player?.audioSessionId)

View file

@ -21,6 +21,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.compose.routing.RouteHandler
import it.vfsfitvnm.vimusic.R
@ -53,12 +54,12 @@ fun SettingsScreen() {
tabIndex = tabIndex,
onTabChanged = onTabChanged,
tabColumnContent = { Item ->
Item(0, "Appearance", R.drawable.color_palette)
Item(1, "Player", R.drawable.play)
Item(2, "Cache", R.drawable.server)
Item(3, "Database", R.drawable.server)
Item(4, "Other", R.drawable.shapes)
Item(5, "About", R.drawable.information)
Item(0, stringResource(R.string.appearance), R.drawable.color_palette)
Item(1, stringResource(R.string.player), R.drawable.play)
Item(2, stringResource(R.string.cache), R.drawable.server)
Item(3, stringResource(R.string.database), R.drawable.server)
Item(4, stringResource(R.string.other), R.drawable.shapes)
Item(5, stringResource(R.string.about), R.drawable.information)
}
) { currentTabIndex ->
saveableStateHolder.SaveableStateProvider(currentTabIndex) {

View file

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="cancel">Stornieren</string>
<string name="done">Fertig</string>
<string name="hidesong">Möchten Sie diesen Song wirklich verstecken? Die Wiedergabezeit und der \nCache werden gelöscht.</string>
<string name="new_playlist">Neue playlist</string>
<string name="start_radio">Radio hören</string>
<string name="equalizer">Equalizer</string>
<string name="stop_sleep_timer">Möchten Sie den Schlaf-Timer stoppen?</string>
<string name="set_sleep_timer">Einstellen des Sleep Timers</string>
<string name="add_to_playlist">Zu Playlist hinzufügen</string>
<string name="go_to_album">Zum Album gehen</string>
<string name="remove_from_queue">Aus der playlist</string>
<string name="remove_from_playlist">Aus der Playlist entfernen</string>
<string name="hide">Verstecken</string>
<string name="hide_from_quick_picks">Ausblenden von \"Quick picks\"</string>
<string name="related_albums">Ähnliche Alben</string>
<string name="similar_artists">Ähnliche Künstler</string>
<string name="playlists_you_might_like">Playlists, die dir gefallen könnten</string>
<string name="an_error_has_occurred">Es ist ein Fehler aufgetreten</string>
<string name="albums">Alben</string>
<string name="artists">Künstlern</string>
<string name="enter_the_playlist_name">Geben Namen playlist</string>
<string name="playlists">Playlists</string>
<string name="favorites">Favoriten</string>
<string name="offline">Offline</string>
<string name="quick_picks">Quick picks</string>
<string name="songs">Lieder</string>
<string name="other_versions">Anderen Versionen</string>
<string name="album_no_alternative_version">Dieses Album hat keine alternative Version</string>
<string name="enqueue">Enqueue</string>
<string name="shuffle">Shuffle</string>
<string name="view_all">Anzeigen aller</string>
<string name="from_wikipedia_cca">Von Wikipedia unter Creative Commons Attribution CC-BY-SA 3.0</string>
<string name="overview">Übersicht</string>
<string name="singles">Einzel</string>
<string name="library">Library</string>
<string name="artist_no_release_album">Dieser Künstler hat kein Album veröffentlicht</string>
<string name="artist_no_release_single">Dieser Künstler hat keine Single veröffentlicht</string>
<string name="delete_playlist">Möchtest du diese Playlist wirklich löschen?</string>
<string name="sync">Synchronisieren</string>
<string name="rename">Umbenennen</string>
<string name="delete">löschen</string>
<string name="enter_the_lyrics">Geben Sie die lyrics</string>
<string name="edit_lyrics">Bearbeiten lyrics</string>
<string name="search_lyrics_online">Suche lyrics online</string>
<string name="fetch_lyrics_again">Wieder holen lyrics</string>
<string name="queue_loop">"Reihe Looping "</string>
<string name="id">Id</string>
<string name="itag">Itag</string>
<string name="bitrate">Bitrate</string>
<string name="size">Size</string>
<string name="cached">Cached</string>
<string name="loudness">Volumen</string>
<string name="clear">Klar</string>
<string name="error">Ein Fehler aufgetreten.</string>
<string name="enter_a_name">Suche</string>
<string name="online">Online</string>
<string name="no_results_found">Keine Ergebnisse gefunden. Bitte versuchen Sie eine andere Suchanfrage oder Kategorie</string>
<string name="videos">Videos</string>
<string name="featured">Vorgestellt</string>
<string name="view_the_source_code">Den Quellcode anzeigen</string>
<string name="report_an_issue">Ein Problem melden</string>
<string name="you_will_be_redirected_to_github">Sie werden weitergeleitet zu GitHub</string>
<string name="request_a_feature_or_suggest_an_idea">Fordern Sie ein Feature an oder schlagen Sie eine Idee vor</string>
<string name="appearance">Aussehen</string>
<string name="colors">FARBEN</string>
<string name="theme">Theme</string>
<string name="theme_mode">Themenmodus</string>
<string name="shapes">FORMEN</string>
<string name="thumbnail_roundness">Thumbnail Rundheit</string>
<string name="text">TEXT</string>
<string name="use_system_font">Systemschrift verwenden</string>
<string name="use_font_by_the_system">Verwenden Sie die vom System angewendete Schriftart</string>
<string name="apply_font_padding">Anwenden von Font Padding</string>
<string name="add_spacing_around_texts">Hinzufügen von Abständen um Texte</string>
<string name="lockscreen">SPERRBILDSCHIRM</string>
<string name="show_song_cover">Show song cover</string>
<string name="use_song_cover_on_lockscreen">Verwenden Sie die Titelabdeckung als Sperrbildschirmhintergrund</string>
<string name="cache">Cache</string>
<string name="cache_cleared">Wenn der Cache keinen Speicherplatz mehr hat, werden die Ressourcen, auf die am längsten nicht zugegriffen wurde, gelöscht</string>
<string name="image_cache">IMAGE CACHE</string>
<string name="max_size">Max Größe</string>
<string name="song_cache">SONG CACHE</string>
<string name="database">Database</string>
<string name="reset_quick_picks">Zurücksetzen quick picks</string>
<string name="quick_picks_are_cleared">Quick picks werden gelöscht</string>
<string name="backup">BACKUP</string>
<string name="personal_preference">Persönliche Einstellungen (z.B. der Theme-Modus) und der Cache sind ausgeschlossen.</string>
<string name="backup_1">Backup</string>
<string name="export_the_database">Exportieren der Datenbank in den externen Speicher</string>
<string name="restore">RESTORE</string>
<string name="restore_1">Restore</string>
<string name="import_the_database">Importieren der Datenbank aus dem externen Speicher</string>
<string name="other">Ander</string>
<string name="android_auto">ANDROID AUTO</string>
<string name="enable_unknown_sources">Denken Sie daran, \"Unbekannte Quellen\" in den Entwicklereinstellungen von Android Auto zu aktivieren.</string>
<string name="android_auto_1">Android Auto</string>
<string name="enable_android_auto_support">Unterstützung für Android Auto aktivieren</string>
<string name="search_history">SUCHVERLAUF</string>
<string name="pause_search_history">Anhalten des Suchverlaufs</string>
<string name="neither_save_new_searched_query">Keine neuen Suchabfragen speichern oder Verlauf anzeigen</string>
<string name="clear_search_history">Suchverlauf löschen</string>
<string name="history_is_empty">Geschichte ist leer</string>
<string name="service_lifetime">SERVICE LIFETIME</string>
<string name="battery_optimizations_applied">Wenn Batterieoptimierungen angewendet werden, kann die Wiedergabebenachrichtigung plötzlich verschwinden, wenn sie angehalten wird.</string>
<string name="is_android12">Seit Android 12 ist das Deaktivieren von Batterieoptimierungen erforderlich, damit die Option \"Unbesiegbarer Dienst\" wirksam wird.</string>
<string name="ignore_battery_optimizations">Ignorieren von Batterieoptimierungen</string>
<string name="already_unrestricted">Schon uneingeschränkt</string>
<string name="disable_background_restrictions">Deaktivieren von Einschränkungen im Hintergrund</string>
<string name="invincible_service">Invincible service</string>
<string name="turning_off_battery_optimizations_is_not_enough">Beim Ausschalten der Batterie Optimierungen ist nicht genug</string>
<string name="player_audio"><![CDATA[Player & Audio]]></string>
<string name="player">PLAYER</string>
<string name="persistent_queue">Persistente Warteschlange</string>
<string name="save_and_restore_playing_songs">Speichern und Wiederherstellen der Wiedergabe von Songs</string>
<string name="resume_playback">Wiedergabe fortzusetzen</string>
<string name="when_device_is_connected">Wenn ein kabelgebundenes oder Bluetooth-Gerät verbunden ist</string>
<string name="audio">AUDIO</string>
<string name="skip_silence">Stille auslassen</string>
<string name="skip_silent_parts_during_playback">Stumme Teile während der Wiedergabe überspringen</string>
<string name="loudness_normalization">Lautheitsanpassung</string>
<string name="autoadjust_the_volume">Stellen Sie die Lautstärke auf ein festes Niveau ein</string>
<string name="interact_with_the_system_equalizer">Interagieren Sie mit dem System-Equalizer</string>
<string name="about">About</string>
<string name="more_of">Mehr von</string>
<string name="sleep_timer">Sleep timer</string>
<string name="left">%1$s übrigen</string>
<string name="set">Legen Sie</string>
<string name="play_next">Play next</string>
<string name="confirm">Bestätigen</string>
<string name="show">Zeigen</string>
<string name="unsynchronized_lyrics">unsynchronisierten lyrics</string>
<string name="synchronized_lyrics">synchronisiert lyrics</string>
<string name="provided_by">Bildmaterial von</string>
<string name="cleanup">CLEANUP</string>
<string name="delete_playback_events">Löschen %1$s Wiedergabeereignisse</string>
<string name="existing_data_will_be_overwritten">Vorhandene Daten werden überschrieben.\n%1$s schließt sich automatisch nach dem Wiederherstellen der Datenbank.</string>
</resources>

View file

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="cancel">Cancela</string>
<string name="done">Ok</string>
<string name="hidesong">¿Realmente desea ocultar esta canción? El tiempo de reproducción y la caché se borrarán. Esta acción es irreversible.</string>
<string name="new_playlist">Nueva playlist</string>
<string name="start_radio">Escuchar radio</string>
<string name="equalizer">Ecualizador</string>
<string name="stop_sleep_timer">¿Apaga el temporizador de apagado?</string>
<string name="set_sleep_timer">Temporizador apagado</string>
<string name="add_to_playlist">Añadir a la playlist</string>
<string name="go_to_album">Ver álbum</string>
<string name="remove_from_queue">Remover de la cola</string>
<string name="remove_from_playlist">Remover de la playlist</string>
<string name="hide">Esconde</string>
<string name="hide_from_quick_picks">Ocultar de \"Métodos abreviados\"</string>
<string name="related_albums">Álbumes relacionados</string>
<string name="similar_artists">Artistas similares</string>
<string name="playlists_you_might_like">Playlist que podrían gustarte</string>
<string name="an_error_has_occurred">Ha habido un error</string>
<string name="albums">Álbum</string>
<string name="artists">Artistas</string>
<string name="enter_the_playlist_name">Introduzca el nombre de la playlist</string>
<string name="playlists">Playlist</string>
<string name="favorites">Favoritos</string>
<string name="offline">Offline</string>
<string name="quick_picks">Métodos abreviados</string>
<string name="songs">Canciones</string>
<string name="other_versions">Otras versiones</string>
<string name="album_no_alternative_version">El álbum no tiene versiones alternativas</string>
<string name="enqueue">Añadir a la cola</string>
<string name="shuffle">Aleatorio</string>
<string name="view_all">Mostrar todo</string>
<string name="from_wikipedia_cca">Da Wikipedia bajo Creative Commons Atribución CC-BY-SA 3.0</string>
<string name="overview">Panorámica</string>
<string name="singles">Individuales</string>
<string name="library">Librería</string>
<string name="artist_no_release_album">El artista no lanzó ningún álbum</string>
<string name="artist_no_release_single">El artista no ha lanzado ningún individuo</string>
<string name="delete_playlist">¿Realmente quieres eliminar la playlist?</string>
<string name="sync">Sincroniza</string>
<string name="rename">Cambia el nombre</string>
<string name="delete">Elimina</string>
<string name="enter_the_lyrics">Introduzca lyrics</string>
<string name="edit_lyrics">Modifica lyrics</string>
<string name="search_lyrics_online">Busca lyrics online</string>
<string name="fetch_lyrics_again">Recupera nuevamente lyrics</string>
<string name="queue_loop">"Reproducción continua "</string>
<string name="id">Id</string>
<string name="itag">Itag</string>
<string name="bitrate">Bitrate</string>
<string name="size">Tamaño</string>
<string name="cached">Descargado</string>
<string name="loudness">Volumen</string>
<string name="clear">Limpia</string>
<string name="error">Ha habido un error.</string>
<string name="enter_a_name">Busca</string>
<string name="online">Online</string>
<string name="no_results_found">Sin resultados. Cambiar la clave de búsqueda o la categoría</string>
<string name="videos">Video</string>
<string name="featured">En primer plano</string>
<string name="view_the_source_code">Ver el código fuente</string>
<string name="report_an_issue">Reportar un error</string>
<string name="you_will_be_redirected_to_github">Serás redirigido a GitHub</string>
<string name="request_a_feature_or_suggest_an_idea">Solicitar una función o sugerir una idea</string>
<string name="appearance">Apariencia</string>
<string name="colors">COLORES</string>
<string name="theme">Tema</string>
<string name="theme_mode">Modo tema</string>
<string name="shapes">FORMAS</string>
<string name="thumbnail_roundness">Miniaturas redondeadas</string>
<string name="text">TEXTO</string>
<string name="use_system_font">Usar fuentes del sistema</string>
<string name="use_font_by_the_system">Utilizar fuente aplicada por el sistema</string>
<string name="apply_font_padding">Aplicar relleno de carácter</string>
<string name="add_spacing_around_texts">Añadir espaciado en los textos</string>
<string name="lockscreen">BLOQUEO DE PANTALLA</string>
<string name="show_song_cover">Mostrar la portada de la canción</string>
<string name="use_song_cover_on_lockscreen">Use la portada de la canción que se está reproduciendo como fondo de la pantalla de bloqueo</string>
<string name="cache">Caché</string>
<string name="cache_cleared">Cuando la caché se queda sin espacio, los recursos a los que no se ha accedido durante el mayor tiempo se borran</string>
<string name="image_cache">CACHÉ IMÁGENES</string>
<string name="max_size">Tamaño máximo</string>
<string name="song_cache">CACHÉ CANCIONES</string>
<string name="database">Base de datos</string>
<string name="reset_quick_picks">Reset Métodos abreviados</string>
<string name="quick_picks_are_cleared">Métodos abreviados eliminados</string>
<string name="backup">BACKUP</string>
<string name="personal_preference">Se excluyen las preferencias personales (es decir, el modo de tema) y la caché.</string>
<string name="backup_1">Backup</string>
<string name="export_the_database">Exportar la base de datos a un medio externo</string>
<string name="restore">RESTORE</string>
<string name="restore_1">Restore</string>
<string name="import_the_database">Importar bases de datos desde un medio externo</string>
<string name="other">Otro</string>
<string name="android_auto">ANDROID AUTO</string>
<string name="enable_unknown_sources">Recuerda habilitar \"Orígenes desconocidos\" en la configuración del desarrollador de Android Auto.</string>
<string name="android_auto_1">Android Auto</string>
<string name="enable_android_auto_support">Habilitar soporte para Android Auto</string>
<string name="search_history">HISTORIAL DE BÚSQUEDA</string>
<string name="pause_search_history">Suspender el historial de búsqueda</string>
<string name="neither_save_new_searched_query">No guardar nuevas búsquedas ni mostrar el historial</string>
<string name="clear_search_history">Limpiar historial de búsqueda</string>
<string name="history_is_empty">El historial está en blanco</string>
<string name="service_lifetime">SERVICIO LIFETIME</string>
<string name="battery_optimizations_applied">Si se aplican las optimizaciones de la batería, la notificación de reproducción puede desaparecer repentinamente cuando se detiene.</string>
<string name="is_android12">A partir de Android 12, debe deshabilitar las optimizaciones de la batería para que la opción \"Servicio invencible\" surta efecto.</string>
<string name="ignore_battery_optimizations">Ignorar optimización de la batería</string>
<string name="already_unrestricted">Ya sin restricciones</string>
<string name="disable_background_restrictions">Desactivar las restricciones en segundo plano</string>
<string name="invincible_service">Invincible servicio</string>
<string name="turning_off_battery_optimizations_is_not_enough">Cuando desactivar las optimizaciones de la batería no es suficiente</string>
<string name="player_audio"><![CDATA[Player & Audio]]></string>
<string name="player">PLAYER</string>
<string name="persistent_queue">Cola persistente</string>
<string name="save_and_restore_playing_songs">Guardar y restaurar la reproducción de canciones</string>
<string name="resume_playback">Reanudar la reproducción</string>
<string name="when_device_is_connected">Cuando es collegato un dispositivo cablato o bluetooth</string>
<string name="audio">AUDIO</string>
<string name="skip_silence">Saltar el silencio</string>
<string name="skip_silent_parts_during_playback">Omitir las partes silenciosas durante la reproducción</string>
<string name="loudness_normalization">Normalización del volumen</string>
<string name="autoadjust_the_volume">Ajustar el volumen a un nivel fijo</string>
<string name="interact_with_the_system_equalizer">Interactúa con el ecualizador del sistema</string>
<string name="about">About</string>
<string name="more_of">Más sobre</string>
<string name="sleep_timer">Temporizador apagado</string>
<string name="left">%1$s restantes</string>
<string name="set">Establece</string>
<string name="play_next">Reproducir siguiente</string>
<string name="confirm">Confirma</string>
<string name="show">Muestra</string>
<string name="unsynchronized_lyrics">lyrics no sincronizadas</string>
<string name="synchronized_lyrics">lyrics sincronizadas</string>
<string name="provided_by">Proporcionado por</string>
<string name="cleanup">LIMPIEZA</string>
<string name="delete_playback_events">Eliminar %1$s eventos de reproducción</string>
<string name="existing_data_will_be_overwritten">Los datos existentes se sobrescribirán.\n%1$s se cerrará automáticamente después de restaurar la base de datos.</string>
</resources>

View file

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="cancel">Annuler</string>
<string name="done">Fait</string>
<string name="hidesong">Voulez-vous vraiment cacher cette chanson ? Son temps de lecture et son cache seront effacés.\nCette action est irréversible.</string>
<string name="new_playlist">Nouvelle playlist</string>
<string name="start_radio">Écoute la radio</string>
<string name="equalizer">Égaliseur</string>
<string name="stop_sleep_timer">Désactiver la minuterie de mise en veille?</string>
<string name="set_sleep_timer">Minuterie d\'arrêt</string>
<string name="add_to_playlist">Ajouter à la playlist</string>
<string name="go_to_album">Aller à l\'album</string>
<string name="remove_from_queue">Supprimer de la file d\'attente</string>
<string name="remove_from_playlist">Supprimer de la liste de lecture</string>
<string name="hide">Cacher</string>
<string name="hide_from_quick_picks">Cacher de \"Sélections rapides\"</string>
<string name="related_albums">Albums associés</string>
<string name="similar_artists">Artistes similaires</string>
<string name="playlists_you_might_like">Listes de lecture que vous pourriez aimer</string>
<string name="an_error_has_occurred">Une erreur est survenue</string>
<string name="albums">Albums</string>
<string name="artists">Artistes</string>
<string name="enter_the_playlist_name">Entrez le nom de la playlist</string>
<string name="playlists">Playlists</string>
<string name="favorites">Favoris</string>
<string name="offline">Offline</string>
<string name="quick_picks">Sélections rapides</string>
<string name="songs">Chansons</string>
<string name="other_versions">Autres versions</string>
<string name="album_no_alternative_version">Cet album n\'a pas de version alternative</string>
<string name="enqueue">Mettre en file d\'attente</string>
<string name="shuffle">aléatoire</string>
<string name="view_all">Voir tout</string>
<string name="from_wikipedia_cca">De Wikipedia sous Creative Commons Attribution CC-BY-SA 3.0</string>
<string name="overview">Panoramique</string>
<string name="singles">Singles</string>
<string name="library">Librairie</string>
<string name="artist_no_release_album">Cet artiste na sorti aucun album</string>
<string name="artist_no_release_single">Cet artiste na sorti aucun single</string>
<string name="delete_playlist">Voulez-vous vraiment supprimer cette playlist?</string>
<string name="sync">Synchronise</string>
<string name="rename">Renommer</string>
<string name="delete">Supprimer</string>
<string name="enter_the_lyrics">Entrer les lyrics</string>
<string name="edit_lyrics">Modifier les lyrics</string>
<string name="search_lyrics_online">Rechercher lyrics online</string>
<string name="fetch_lyrics_again">Récupérer lyrics</string>
<string name="queue_loop">"Lecture continue "</string>
<string name="id">Id</string>
<string name="itag">Itag</string>
<string name="bitrate">Bitrate</string>
<string name="size">Taille</string>
<string name="cached">Téléchargé</string>
<string name="loudness">Volume</string>
<string name="clear">Clair</string>
<string name="error">Une erreur est survenue.</string>
<string name="enter_a_name">Cherche</string>
<string name="online">Online</string>
<string name="no_results_found">Aucun résultat trouvé. Veuillez essayer une autre requête ou catégorie</string>
<string name="videos">Vidéos</string>
<string name="featured">Présenté</string>
<string name="view_the_source_code">Afficher le code source</string>
<string name="report_an_issue">Signaler un problème</string>
<string name="you_will_be_redirected_to_github">Vous allez être redirigé vers GitHub</string>
<string name="request_a_feature_or_suggest_an_idea">Demander une fonctionnalité ou suggérer une idée</string>
<string name="appearance">Appearance</string>
<string name="colors">COLORS</string>
<string name="theme">Theme</string>
<string name="theme_mode">Theme mode</string>
<string name="shapes">SHAPES</string>
<string name="thumbnail_roundness">Aspect</string>
<string name="text">TEXTE</string>
<string name="use_system_font">Utiliser la police du système</string>
<string name="use_font_by_the_system">Utilisez la police appliquée par le système</string>
<string name="apply_font_padding">Appliquer un remplissage de police</string>
<string name="add_spacing_around_texts">Add spacing around texts</string>
<string name="lockscreen">LOCKSCREEN</string>
<string name="show_song_cover">Show song cover</string>
<string name="use_song_cover_on_lockscreen">Use the playing song cover as the lockscreen wallpaper</string>
<string name="cache">Cache</string>
<string name="cache_cleared">Lorsque le cache manque despace, les ressources qui nont pas été consultées depuis le plus longtemps sont effacées</string>
<string name="image_cache">CACHE D\'IMAGE</string>
<string name="max_size">Taille max</string>
<string name="song_cache">CACHE DE CHANSONS</string>
<string name="database">Database</string>
<string name="reset_quick_picks">Réinitialiser sélections rapides</string>
<string name="quick_picks_are_cleared">Les sélections rapides sont effacés</string>
<string name="backup">BACKUP</string>
<string name="personal_preference">Les préférences personnelles (c.-à-d. le mode de thème) et le cache sont exclus.</string>
<string name="backup_1">Backup</string>
<string name="export_the_database">Exporter la base de données vers le stockage externe</string>
<string name="restore">RESTAURER</string>
<string name="restore_1">Restaurer</string>
<string name="import_the_database">Importer la base de données à partir du stockage externe</string>
<string name="other">Autre</string>
<string name="android_auto">ANDROID AUTO</string>
<string name="enable_unknown_sources">Noubliez pas dactiver \"Sources inconnues\" dans les paramètres du développeur dAndroid Auto.</string>
<string name="android_auto_1">Android Auto</string>
<string name="enable_android_auto_support">Activer le support pour Android Auto</string>
<string name="search_history">HISTORIQUE DE RECHERCHES</string>
<string name="pause_search_history">Suspendre lhistorique des recherches</string>
<string name="neither_save_new_searched_query">Ne pas enregistrer de nouvelles recherches ni afficher lhistorique</string>
<string name="clear_search_history">Effacer lhistorique de recherche</string>
<string name="history_is_empty">Lhistorique est vide</string>
<string name="service_lifetime">SERVICE LIFETIME</string>
<string name="battery_optimizations_applied">Si des optimisations de la batterie sont appliquées, la notification de lecture peut soudainement disparaître en cas de pause.</string>
<string name="is_android12">Depuis Android 12, la désactivation des optimisations de la batterie est nécessaire pour que loption \"Invincible service\" prenne effet.</string>
<string name="ignore_battery_optimizations">IIgnorer les optimisations de la batterie</string>
<string name="already_unrestricted">Déjà sans restriction</string>
<string name="disable_background_restrictions">Désactiver les restrictions en arrière-plan</string>
<string name="invincible_service">Invincible service</string>
<string name="turning_off_battery_optimizations_is_not_enough">When turning off battery optimizations is not enough</string>
<string name="player_audio"><![CDATA[Player & Audio]]></string>
<string name="player">PLAYER</string>
<string name="persistent_queue">Queue persistante</string>
<string name="save_and_restore_playing_songs">Enregistrer et restaurer la lecture des chansons</string>
<string name="resume_playback">Reprendre la lecture</string>
<string name="when_device_is_connected">Quand è collegato un dispositif câblé le bluetooth</string>
<string name="audio">AUDIO</string>
<string name="skip_silence">Ignorer le silence</string>
<string name="skip_silent_parts_during_playback">Ignorer les parties silencieuses pendant la lecture</string>
<string name="loudness_normalization">Normalisation de volume</string>
<string name="autoadjust_the_volume">Régler le volume à un niveau fixe</string>
<string name="interact_with_the_system_equalizer">Interagir avec légaliseur du système</string>
<string name="about">About</string>
<string name="more_of">Plus de</string>
<string name="sleep_timer">Minuterie d\'arrêt</string>
<string name="left">%1$s restants</string>
<string name="set">Impôt</string>
<string name="play_next">Lecture suivante</string>
<string name="confirm">Confirmer</string>
<string name="show">Montre</string>
<string name="unsynchronized_lyrics">lyrics non synchronisées</string>
<string name="synchronized_lyrics">lyrics synchronisées</string>
<string name="provided_by">Fournies par</string>
<string name="cleanup">NETTOYAGE</string>
<string name="delete_playback_events">Supprimer %1$s événements de lecture</string>
<string name="existing_data_will_be_overwritten">Les données existantes seront écrasées.\n%1$s se fermera automatiquement après la restauration de la base de données.</string>
</resources>

View file

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="cancel">Annulla</string>
<string name="done">Ok</string>
<string name="hidesong">Vuoi davvero nascondere questa canzone? Il tempo di riproduzione e la cache verranno cancellati. Questa azione è irreversibile.</string>
<string name="new_playlist">Nuova playlist</string>
<string name="start_radio">Ascolta radio</string>
<string name="equalizer">Equalizzatore</string>
<string name="stop_sleep_timer">Disattiva timer di spegnimento?</string>
<string name="set_sleep_timer">Timer spegnimento</string>
<string name="add_to_playlist">Aggiungi alla playlist</string>
<string name="go_to_album">Visualizza album</string>
<string name="remove_from_queue">Rimuovi dalla coda</string>
<string name="remove_from_playlist">Rimuovi dalla playlist</string>
<string name="hide">Nascondi</string>
<string name="hide_from_quick_picks">Nascondi da \"Scelte rapide\"</string>
<string name="related_albums">Album correlati</string>
<string name="similar_artists">Artisti simili</string>
<string name="playlists_you_might_like">Playlist che potrebbero piacerti</string>
<string name="an_error_has_occurred">C\'è stato un errore</string>
<string name="albums">Album</string>
<string name="artists">Artisti</string>
<string name="enter_the_playlist_name">Inserisci il nome della playlist</string>
<string name="playlists">Playlist</string>
<string name="favorites">Preferiti</string>
<string name="offline">Offline</string>
<string name="quick_picks">Scelte rapide</string>
<string name="songs">Brani</string>
<string name="other_versions">Altre versioni</string>
<string name="album_no_alternative_version">L\'album non ha versioni alternative</string>
<string name="enqueue">Aggiungi alla coda</string>
<string name="shuffle">Casuale</string>
<string name="view_all">Visualizza tutto</string>
<string name="from_wikipedia_cca">Da Wikipedia under Creative Commons Attribution CC-BY-SA 3.0</string>
<string name="overview">Panoramica</string>
<string name="singles">Singoli</string>
<string name="library">Libreria</string>
<string name="artist_no_release_album">L\'artista non ha rilasciato nessun album</string>
<string name="artist_no_release_single">L\'artista non ha rilasciato nessun singolo</string>
<string name="delete_playlist">Vuoi veramente eliminare la playlist?</string>
<string name="sync">Sincronizza</string>
<string name="rename">Rinomina</string>
<string name="delete">Elimina</string>
<string name="enter_the_lyrics">Inserisci lyrics</string>
<string name="edit_lyrics">Modifica lyrics</string>
<string name="search_lyrics_online">Cerca lyrics online</string>
<string name="fetch_lyrics_again">Recupera nuovamente lyrics</string>
<string name="queue_loop">"Riproduzione continua "</string>
<string name="id">Id</string>
<string name="itag">Itag</string>
<string name="bitrate">Bitrate</string>
<string name="size">Grandezza</string>
<string name="cached">Scaricato</string>
<string name="loudness">Volume</string>
<string name="clear">Pulisci</string>
<string name="error">C\'è stato un errore.</string>
<string name="enter_a_name">Cerca</string>
<string name="online">Online</string>
<string name="no_results_found">Nessun risultato. Cambia la chiave di ricerca o la categoria</string>
<string name="videos">Video</string>
<string name="featured">In primo piano</string>
<string name="view_the_source_code">Visualizza il codice sorgente</string>
<string name="report_an_issue">Segnala un bug</string>
<string name="you_will_be_redirected_to_github">Sarai reindirizzato su GitHub</string>
<string name="request_a_feature_or_suggest_an_idea">Richiedi una funzionalità o suggerisci un\'idea</string>
<string name="appearance">Aspetto</string>
<string name="colors">COLORI</string>
<string name="theme">Tema</string>
<string name="theme_mode">Modalità tema</string>
<string name="shapes">FORME</string>
<string name="thumbnail_roundness">Miniature arrotondate</string>
<string name="text">TESTO</string>
<string name="use_system_font">Usa font di sistema</string>
<string name="use_font_by_the_system">Usa font applicato dal sistema</string>
<string name="apply_font_padding">Applicare riempimento del carattere</string>
<string name="add_spacing_around_texts">Aggiungi spaziatura nei testi</string>
<string name="lockscreen">BLOCCO SCHERMO</string>
<string name="show_song_cover">Mostra copertina della canzone</string>
<string name="use_song_cover_on_lockscreen">Usa la copertina del brano in riproduzione come sfondo della schermata di blocco</string>
<string name="cache">Cache</string>
<string name="cache_cleared">Quando la cache esaurisce lo spazio, le risorse a cui non è stato effettuato l\'accesso per il tempo più lungo vengono cancellate</string>
<string name="image_cache">CACHE IMMAGINI</string>
<string name="max_size">Grandezza massima</string>
<string name="song_cache">CACHE BRANI</string>
<string name="database">Database</string>
<string name="reset_quick_picks">Reset Scelte rapide</string>
<string name="quick_picks_are_cleared">Scelte rapide cancellate</string>
<string name="backup">BACKUP</string>
<string name="personal_preference">Le preferenze personali (ovvero la modalità tema) e la cache sono escluse.</string>
<string name="backup_1">Backup</string>
<string name="export_the_database">Esporta il database su un supporto esterno</string>
<string name="restore">RIPRISTINO</string>
<string name="restore_1">Ripristino</string>
<string name="import_the_database">Importa database da un supporto esterno</string>
<string name="other">Altro</string>
<string name="android_auto">ANDROID AUTO</string>
<string name="enable_unknown_sources">Ricorda di abilitare \"Origini sconosciute\" nelle Impostazioni sviluppatore di Android Auto.</string>
<string name="android_auto_1">Android Auto</string>
<string name="enable_android_auto_support">Abilita supporto per Android Auto</string>
<string name="search_history">CRONOLOGIA RICERCHE</string>
<string name="pause_search_history">Sospendi cronologia ricerche</string>
<string name="neither_save_new_searched_query">Non salvare nuove ricerche né mostrare la cronologia</string>
<string name="clear_search_history">Pulisci cronologia ricerche</string>
<string name="history_is_empty">La cronologia è vuota</string>
<string name="service_lifetime">SERVIZIO LIFETIME</string>
<string name="battery_optimizations_applied">Se vengono applicate le ottimizzazioni della batteria, la notifica di riproduzione può scomparire improvvisamente quando viene messa in pausa.</string>
<string name="is_android12">A partire da Android 12, è necessario disabilitare le ottimizzazioni della batteria affinché l\'opzione \"Servizio invincibile\" abbia effetto.</string>
<string name="ignore_battery_optimizations">Ignora ottimizzazione batteria</string>
<string name="already_unrestricted">Già senza restrizioni</string>
<string name="disable_background_restrictions">Disabilita le restrizioni sullo sfondo</string>
<string name="invincible_service">Invincible service</string>
<string name="turning_off_battery_optimizations_is_not_enough">Quando disattivare le ottimizzazioni della batteria non è sufficiente</string>
<string name="player_audio"><![CDATA[Player & Audio]]></string>
<string name="player">PLAYER</string>
<string name="persistent_queue">Coda persistente</string>
<string name="save_and_restore_playing_songs">Salva e ripristina la riproduzione di brani</string>
<string name="resume_playback">Riprendi la riproduzione</string>
<string name="when_device_is_connected">Quando è collegato un dispositivo cablato o bluetooth</string>
<string name="audio">AUDIO</string>
<string name="skip_silence">Salta il silenzio</string>
<string name="skip_silent_parts_during_playback">Salta le parti silenziose durante la riproduzione</string>
<string name="loudness_normalization">Normalizzazione del volume</string>
<string name="autoadjust_the_volume">Regola il volume a un livello fisso</string>
<string name="interact_with_the_system_equalizer">Interagisci con l\'equalizzatore di sistema</string>
<string name="about">About</string>
<string name="more_of">Altro su</string>
<string name="sleep_timer">Timer spegnimento</string>
<string name="left">%1$s rimanenti</string>
<string name="set">Imposta</string>
<string name="play_next">Riproduci successivo</string>
<string name="confirm">Conferma</string>
<string name="show">Mostra</string>
<string name="unsynchronized_lyrics">lyrics non sincronizzate</string>
<string name="synchronized_lyrics">lyrics sincronizzate</string>
<string name="provided_by">Fornito da</string>
<string name="cleanup">PULIZIA</string>
<string name="delete_playback_events">Elimina %1$s eventi di riproduzione</string>
<string name="existing_data_will_be_overwritten">I dati esistenti verranno sovrascritti.\n%1$s si chiuderà automaticamente dopo aver ripristinato il database.</string>
</resources>

View file

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="cancel">Cancel</string>
<string name="done">Done</string>
<string name="hidesong">Do you really want to hide this song? Its playback time and cache will be wiped.\nThis action is irreversible.</string>
<string name="new_playlist">New playlist</string>
<string name="start_radio">Start radio</string>
<string name="equalizer">Equalizer</string>
<string name="stop_sleep_timer">Do you want to stop the sleep timer?</string>
<string name="set_sleep_timer">Set sleep timer</string>
<string name="add_to_playlist">Add to playlist</string>
<string name="go_to_album">Go to album</string>
<string name="remove_from_queue">Remove from queue</string>
<string name="remove_from_playlist">Remove from playlist</string>
<string name="hide">Hide</string>
<string name="hide_from_quick_picks">Hide from \"Quick picks\"</string>
<string name="related_albums">Related albums</string>
<string name="similar_artists">Similar artists</string>
<string name="playlists_you_might_like">Playlists you might like</string>
<string name="an_error_has_occurred">An error has occurred</string>
<string name="albums">Albums</string>
<string name="artists">Artists</string>
<string name="enter_the_playlist_name">Enter the playlist name</string>
<string name="playlists">Playlists</string>
<string name="favorites">Favorites</string>
<string name="offline">Offline</string>
<string name="quick_picks">Quick picks</string>
<string name="songs">Songs</string>
<string name="other_versions">Other versions</string>
<string name="album_no_alternative_version">This album doesn\'t have any alternative version</string>
<string name="enqueue">Enqueue</string>
<string name="shuffle">Shuffle</string>
<string name="view_all">View all</string>
<string name="from_wikipedia_cca">From Wikipedia under Creative Commons Attribution CC-BY-SA 3.0</string>
<string name="overview">Overview</string>
<string name="singles">Singles</string>
<string name="library">Library</string>
<string name="artist_no_release_album">This artist didn\'t release any album</string>
<string name="artist_no_release_single">This artist didn\'t release any single</string>
<string name="delete_playlist">Do you really want to delete this playlist?</string>
<string name="sync">Sync</string>
<string name="rename">Rename</string>
<string name="delete">Delete</string>
<string name="enter_the_lyrics">Enter the lyrics</string>
<string name="edit_lyrics">Edit lyrics</string>
<string name="search_lyrics_online">Search lyrics online</string>
<string name="fetch_lyrics_again">Fetch lyrics again</string>
<string name="queue_loop">"Queue loop "</string>
<string name="id">Id</string>
<string name="itag">Itag</string>
<string name="bitrate">Bitrate</string>
<string name="size">Size</string>
<string name="cached">Cached</string>
<string name="loudness">Loudness</string>
<string name="clear">Clear</string>
<string name="error">An error has occurred.</string>
<string name="enter_a_name">Enter a name</string>
<string name="online">Online</string>
<string name="no_results_found">No results found. Please try a different query or category</string>
<string name="videos">Videos</string>
<string name="featured">Featured</string>
<string name="view_the_source_code">View the source code</string>
<string name="report_an_issue">Report an issue</string>
<string name="you_will_be_redirected_to_github">You will be redirected to GitHub</string>
<string name="request_a_feature_or_suggest_an_idea">Request a feature or suggest an idea</string>
<string name="appearance">Appearance</string>
<string name="colors">COLORS</string>
<string name="theme">Theme</string>
<string name="theme_mode">Theme mode</string>
<string name="shapes">SHAPES</string>
<string name="thumbnail_roundness">Thumbnail roundness</string>
<string name="text">TEXT</string>
<string name="use_system_font">Use system font</string>
<string name="use_font_by_the_system">Use the font applied by the system</string>
<string name="apply_font_padding">Apply font padding</string>
<string name="add_spacing_around_texts">Add spacing around texts</string>
<string name="lockscreen">LOCKSCREEN</string>
<string name="show_song_cover">Show song cover</string>
<string name="use_song_cover_on_lockscreen">Use the playing song cover as the lockscreen wallpaper</string>
<string name="cache">Cache</string>
<string name="cache_cleared">When the cache runs out of space, the resources that haven\'t been accessed for the longest time are cleared</string>
<string name="image_cache">IMAGE CACHE</string>
<string name="max_size">Max size</string>
<string name="song_cache">SONG CACHE</string>
<string name="database">Database</string>
<string name="reset_quick_picks">Reset quick picks</string>
<string name="quick_picks_are_cleared">Quick picks are cleared</string>
<string name="backup">BACKUP</string>
<string name="personal_preference">Personal preferences (i.e. the theme mode) and the cache are excluded.</string>
<string name="backup_1">Backup</string>
<string name="export_the_database">Export the database to the external storage</string>
<string name="restore">RESTORE</string>
<string name="restore_1">Restore</string>
<string name="import_the_database">Import the database from the external storage</string>
<string name="other">Other</string>
<string name="android_auto">ANDROID AUTO</string>
<string name="enable_unknown_sources">Remember to enable \"Unknown sources\" in the Developer Settings of Android Auto.</string>
<string name="android_auto_1">Android Auto</string>
<string name="enable_android_auto_support">Enable Android Auto support</string>
<string name="search_history">SEARCH HISTORY</string>
<string name="pause_search_history">Pause search history</string>
<string name="neither_save_new_searched_query">Neither save new searched queries nor show history</string>
<string name="clear_search_history">Clear search history</string>
<string name="history_is_empty">History is empty</string>
<string name="service_lifetime">SERVICE LIFETIME</string>
<string name="battery_optimizations_applied">If battery optimizations are applied, the playback notification can suddenly disappear when paused.</string>
<string name="is_android12">Since Android 12, disabling battery optimizations is required for the \"Invincible service\" option to take effect.</string>
<string name="ignore_battery_optimizations">Ignore battery optimizations</string>
<string name="already_unrestricted">Already unrestricted</string>
<string name="disable_background_restrictions">Disable background restrictions</string>
<string name="invincible_service">Invincible service</string>
<string name="turning_off_battery_optimizations_is_not_enough">When turning off battery optimizations is not enough</string>
<string name="player_audio"><![CDATA[Player & Audio]]></string>
<string name="player">PLAYER</string>
<string name="persistent_queue">Persistent queue</string>
<string name="save_and_restore_playing_songs">Save and restore playing songs</string>
<string name="resume_playback">Resume playback</string>
<string name="when_device_is_connected">When a wired or bluetooth device is connected</string>
<string name="audio">AUDIO</string>
<string name="skip_silence">Skip silence</string>
<string name="skip_silent_parts_during_playback">Skip silent parts during playback</string>
<string name="loudness_normalization">Loudness normalization</string>
<string name="autoadjust_the_volume">Adjust the volume to a fixed level</string>
<string name="interact_with_the_system_equalizer">Interact with the system equalizer</string>
<string name="about">About</string>
<string name="more_of">More of</string>
<string name="sleep_timer">Sleep timer</string>
<string name="left">%1$s left</string>
<string name="set">Set</string>
<string name="play_next">Play next</string>
<string name="confirm">Confirm</string>
<string name="show">Show</string>
<string name="unsynchronized_lyrics">unsynchronized lyrics</string>
<string name="synchronized_lyrics">synchronized lyrics</string>
<string name="provided_by">Provided by</string>
<string name="cleanup">CLEANUP</string>
<string name="delete_playback_events">Delete %1$s playback events</string>
<string name="existing_data_will_be_overwritten">Existing data will be overwritten.\n%1$s will automatically close itself after restoring the database.</string>
</resources>