diff --git a/app/src/main/java/pl/lambada/songsync/MainActivity.kt b/app/src/main/java/pl/lambada/songsync/MainActivity.kt index 6566cec..dbc4d72 100644 --- a/app/src/main/java/pl/lambada/songsync/MainActivity.kt +++ b/app/src/main/java/pl/lambada/songsync/MainActivity.kt @@ -63,6 +63,7 @@ import java.io.File */ class MainActivity : ComponentActivity() { val viewModel: MainViewModel by viewModels() + /** * Called when the activity is starting. * @@ -100,7 +101,8 @@ class MainActivity : ComponentActivity() { viewModel.sdCardPath = sdCardPath } - val includeTranslation = dataStore.get(booleanPreferencesKey("include_translation"), false) + val includeTranslation = + dataStore.get(booleanPreferencesKey("include_translation"), false) viewModel.includeTranslation = includeTranslation val blacklist = dataStore.get(stringPreferencesKey("blacklist"), null) @@ -111,7 +113,8 @@ class MainActivity : ComponentActivity() { val hideLyrics = dataStore.get(booleanPreferencesKey("hide_lyrics"), false) viewModel.hideLyrics = hideLyrics - val provider = dataStore.get(stringPreferencesKey("provider"), Providers.SPOTIFY.displayName) + val provider = + dataStore.get(stringPreferencesKey("provider"), Providers.SPOTIFY.displayName) viewModel.provider = Providers.entries.find { it.displayName == provider }!! val embedLyrics = dataStore.get(booleanPreferencesKey("embed_lyrics"), false) @@ -160,7 +163,7 @@ class MainActivity : ComponentActivity() { } ) - Surface( modifier = Modifier.fillMaxSize() ) { + Surface(modifier = Modifier.fillMaxSize()) { if (!hasLoadedPermissions) { LoadingScreen() } else if (!hasPermissions) { @@ -194,14 +197,15 @@ class MainActivity : ComponentActivity() { NoInternetDialog( onConfirm = { finishAndRemoveTask() }, onIgnore = { - internetConnection = true // assume connected (if spotify is down, can use other providers) + internetConnection = + true // assume connected (if spotify is down, can use other providers) } ) } + } } } } -} override fun onResume() { val notificationManager = @@ -232,7 +236,8 @@ class MainActivity : ComponentActivity() { fun RequestPermissions(onGranted: () -> Unit, context: Context, onDone: () -> Unit) { var storageManager: ActivityResultLauncher? = null if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - storageManager = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { + storageManager = + rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { if (Environment.isExternalStorageManager()) { onGranted() } diff --git a/app/src/main/java/pl/lambada/songsync/data/MainViewModel.kt b/app/src/main/java/pl/lambada/songsync/data/MainViewModel.kt index 46ccdbc..1b4d990 100644 --- a/app/src/main/java/pl/lambada/songsync/data/MainViewModel.kt +++ b/app/src/main/java/pl/lambada/songsync/data/MainViewModel.kt @@ -15,7 +15,6 @@ import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.kyant.taglib.PropertyMap import com.kyant.taglib.TagLib import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @@ -134,7 +133,11 @@ class MainViewModel : ViewModel() { when (this.provider) { Providers.SPOTIFY -> SpotifyLyricsAPI().getSyncedLyrics(songLink, version) Providers.LRCLIB -> LRCLibAPI().getSyncedLyrics(this.lrcLibID) - Providers.NETEASE -> NeteaseAPI().getSyncedLyrics(this.neteaseID, includeTranslation) + Providers.NETEASE -> NeteaseAPI().getSyncedLyrics( + this.neteaseID, + includeTranslation + ) + Providers.APPLE -> AppleAPI().getSyncedLyrics(this.appleID) } } catch (e: Exception) { @@ -264,17 +267,20 @@ class MainViewModel : ViewModel() { val data: List = when { cachedFilteredSongs.value.isNotEmpty() -> cachedFilteredSongs.value cachedSongs != null -> cachedSongs!! - else -> { return@launch } + else -> { + return@launch + } } val results = data.filter { it.title?.contains(query, ignoreCase = true) == true || - it.artist?.contains(query, ignoreCase = true) == true + it.artist?.contains(query, ignoreCase = true) == true } _searchResults.value = results } } + /** * Loads all songs' folders * @param context The application context. @@ -314,10 +320,12 @@ class MainViewModel : ViewModel() { ) } } + hideLyrics -> { _cachedFilteredSongs?.value = cachedSongs!! .filter { it.filePath.toLrcFile()?.exists() != true } } + hideFolders -> { _cachedFilteredSongs?.value = cachedSongs!!.filter { !blacklistedFolders.contains( @@ -328,6 +336,7 @@ class MainViewModel : ViewModel() { ) } } + else -> { _cachedFilteredSongs?.value = emptyList() } diff --git a/app/src/main/java/pl/lambada/songsync/data/remote/lyrics_providers/others/AppleAPI.kt b/app/src/main/java/pl/lambada/songsync/data/remote/lyrics_providers/others/AppleAPI.kt index 3406077..5c6a0a7 100644 --- a/app/src/main/java/pl/lambada/songsync/data/remote/lyrics_providers/others/AppleAPI.kt +++ b/app/src/main/java/pl/lambada/songsync/data/remote/lyrics_providers/others/AppleAPI.kt @@ -43,7 +43,8 @@ class AppleAPI { songName = result.songName, artistName = result.artistName, songLink = result.url, - albumCoverLink = result.artwork.replace("{w}", "100").replace("{h}", "100").replace("{f}", "png"), + albumCoverLink = result.artwork.replace("{w}", "100").replace("{h}", "100") + .replace("{f}", "png"), appleID = result.id ) } @@ -80,11 +81,13 @@ class AppleAPI { syncedLyrics.append("<${line.endtime.toLrcTimestamp()}>\n") } } + "Line" -> { for (line in lines) { syncedLyrics.append("[${line.timestamp.toLrcTimestamp()}]${line.text[0].text}\n") } } + else -> return null } diff --git a/app/src/main/java/pl/lambada/songsync/data/remote/lyrics_providers/others/NeteaseAPI.kt b/app/src/main/java/pl/lambada/songsync/data/remote/lyrics_providers/others/NeteaseAPI.kt index 84955d0..e73b7a5 100644 --- a/app/src/main/java/pl/lambada/songsync/data/remote/lyrics_providers/others/NeteaseAPI.kt +++ b/app/src/main/java/pl/lambada/songsync/data/remote/lyrics_providers/others/NeteaseAPI.kt @@ -5,8 +5,6 @@ import io.ktor.client.request.get import io.ktor.client.request.header import io.ktor.client.request.parameter import io.ktor.client.statement.bodyAsText -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext import kotlinx.serialization.ExperimentalSerializationApi import pl.lambada.songsync.data.EmptyQueryException import pl.lambada.songsync.data.InternalErrorException @@ -15,7 +13,6 @@ import pl.lambada.songsync.domain.model.lyrics_providers.others.NeteaseLyricsRes import pl.lambada.songsync.domain.model.lyrics_providers.others.NeteaseResponse import pl.lambada.songsync.util.networking.Ktor.client import pl.lambada.songsync.util.networking.Ktor.json -import java.net.URLEncoder class NeteaseAPI { private val baseURL = "http://music.163.com/api/" diff --git a/app/src/main/java/pl/lambada/songsync/ui/Navigator.kt b/app/src/main/java/pl/lambada/songsync/ui/Navigator.kt index 10f1f28..9b8db79 100644 --- a/app/src/main/java/pl/lambada/songsync/ui/Navigator.kt +++ b/app/src/main/java/pl/lambada/songsync/ui/Navigator.kt @@ -12,8 +12,8 @@ import kotlinx.serialization.Serializable import pl.lambada.songsync.data.MainViewModel import pl.lambada.songsync.domain.model.Song import pl.lambada.songsync.ui.screens.AboutScreen -import pl.lambada.songsync.ui.screens.SearchScreen import pl.lambada.songsync.ui.screens.HomeScreen +import pl.lambada.songsync.ui.screens.SearchScreen /** * Composable function for handling navigation within the app. diff --git a/app/src/main/java/pl/lambada/songsync/ui/components/CommonTexts.kt b/app/src/main/java/pl/lambada/songsync/ui/components/CommonTexts.kt index 6819841..a4f26ae 100644 --- a/app/src/main/java/pl/lambada/songsync/ui/components/CommonTexts.kt +++ b/app/src/main/java/pl/lambada/songsync/ui/components/CommonTexts.kt @@ -40,7 +40,6 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import kotlinx.coroutines.delay -import pl.lambada.songsync.data.MainViewModel @Composable fun AnimatedText( @@ -52,10 +51,23 @@ fun AnimatedText( modifier: Modifier = Modifier, ) { if (animate) { - MarqueeText(text = text, fontSize = fontSize, fontWeight = fontWeight, modifier = modifier, color = color) - } - else { - Text(text = text, fontSize = fontSize, fontWeight = fontWeight, modifier = modifier, color = color, maxLines = 1, overflow = TextOverflow.Ellipsis) + MarqueeText( + text = text, + fontSize = fontSize, + fontWeight = fontWeight, + modifier = modifier, + color = color + ) + } else { + Text( + text = text, + fontSize = fontSize, + fontWeight = fontWeight, + modifier = modifier, + color = color, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) } } diff --git a/app/src/main/java/pl/lambada/songsync/ui/components/SwitchItem.kt b/app/src/main/java/pl/lambada/songsync/ui/components/SwitchItem.kt index 55ba5b3..80a5808 100644 --- a/app/src/main/java/pl/lambada/songsync/ui/components/SwitchItem.kt +++ b/app/src/main/java/pl/lambada/songsync/ui/components/SwitchItem.kt @@ -4,8 +4,8 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -21,7 +21,8 @@ fun SwitchItem( modifier: Modifier = Modifier, innerPaddingValues: PaddingValues = PaddingValues( horizontal = 22.dp, - vertical = 16.dp), + vertical = 16.dp + ), onClick: () -> Unit, ) { Row( diff --git a/app/src/main/java/pl/lambada/songsync/ui/screens/AboutScreen.kt b/app/src/main/java/pl/lambada/songsync/ui/screens/AboutScreen.kt index 0cb8708..d253b7c 100644 --- a/app/src/main/java/pl/lambada/songsync/ui/screens/AboutScreen.kt +++ b/app/src/main/java/pl/lambada/songsync/ui/screens/AboutScreen.kt @@ -40,7 +40,6 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment @@ -52,7 +51,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.datastore.preferences.core.booleanPreferencesKey -import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.stringPreferencesKey import androidx.navigation.NavController import kotlinx.coroutines.Dispatchers @@ -126,7 +124,10 @@ fun AboutScreen( ) { viewModel.pureBlack.value = !selected selected = !selected - dataStore.set(key = booleanPreferencesKey("pure_black"), value = selected) + dataStore.set( + key = booleanPreferencesKey("pure_black"), + value = selected + ) } } } @@ -142,7 +143,10 @@ fun AboutScreen( ) { viewModel.disableMarquee.value = !selected selected = !selected - dataStore.set(key = booleanPreferencesKey("marquee_disable"), value = selected) + dataStore.set( + key = booleanPreferencesKey("marquee_disable"), + value = selected + ) } } } @@ -157,7 +161,10 @@ fun AboutScreen( ) { viewModel.includeTranslation = !selected selected = !selected - dataStore.set(key = booleanPreferencesKey("include_translation"), value = selected) + dataStore.set( + key = booleanPreferencesKey("include_translation"), + value = selected + ) } } } @@ -306,7 +313,8 @@ fun AboutScreen( item { AboutItem(stringResource(R.string.contributors)) { Contributor.entries.forEach { - val additionalInfo = stringResource(id = it.contributionLevel.stringResource) + val additionalInfo = + stringResource(id = it.contributionLevel.stringResource) Column( modifier = Modifier .fillMaxWidth() diff --git a/app/src/main/java/pl/lambada/songsync/ui/screens/SearchScreen.kt b/app/src/main/java/pl/lambada/songsync/ui/screens/SearchScreen.kt index d5eb50a..97ae9d5 100644 --- a/app/src/main/java/pl/lambada/songsync/ui/screens/SearchScreen.kt +++ b/app/src/main/java/pl/lambada/songsync/ui/screens/SearchScreen.kt @@ -404,15 +404,17 @@ fun SharedTransitionScope.SearchScreen( val embeddedToFile = kotlin.runCatching { viewModel.embedLyricsInFile( context, - filePath ?: throw NullPointerException("filePath is null"), + filePath + ?: throw NullPointerException("filePath is null"), lrc ) } - if(embeddedToFile.isFailure) { + if (embeddedToFile.isFailure) { Toast.makeText( context, - embeddedToFile.exceptionOrNull()?.message ?: context.getString(R.string.error), + embeddedToFile.exceptionOrNull()?.message + ?: context.getString(R.string.error), Toast.LENGTH_LONG ).show() return@Button