Skip to content

Commit

Permalink
feat: Added Spotify song information retrieve
Browse files Browse the repository at this point in the history
Signed-off-by: Gabriel Fontán <[email protected]>
  • Loading branch information
BobbyESP committed Jul 29, 2024
1 parent cdad156 commit 0dd9dab
Show file tree
Hide file tree
Showing 20 changed files with 972 additions and 761 deletions.
1 change: 0 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions app/src/main/java/com/bobbyesp/metadator/ext/Song.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ fun Song.toParcelableSong(): ParcelableSong {
return ParcelableSong(
name = this.title,
mainArtist = mainArtist,
localSongPath = this.path,
localPath = this.path,
artworkPath = this.artworkPath,
fileName = this.fileName
filename = this.fileName
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import kotlinx.serialization.Serializable
data class ParcelableSong(
val name: String,
val mainArtist: String,
val localSongPath: String,
val localPath: String,
@Serializable(with = UriSerializer::class) val artworkPath: Uri? = null,
val fileName: String
val filename: String
) : Parcelable
117 changes: 71 additions & 46 deletions app/src/main/java/com/bobbyesp/metadator/presentation/Navigation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.bobbyesp.metadator.presentation

import android.annotation.SuppressLint
import android.app.Activity
import android.util.Log
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.IntentSenderRequest
import androidx.activity.result.contract.ActivityResultContracts
Expand Down Expand Up @@ -91,8 +90,10 @@ import com.bobbyesp.metadator.presentation.pages.mediaplayer.MediaplayerViewMode
import com.bobbyesp.metadator.presentation.pages.mediaplayer.player.CollapsedPlayerHeight
import com.bobbyesp.metadator.presentation.pages.mediaplayer.player.PlayerAnimationSpec
import com.bobbyesp.metadator.presentation.pages.settings.SettingsPage
import com.bobbyesp.metadator.presentation.pages.settings.modules.GeneralSettingsPage
import com.bobbyesp.metadator.presentation.pages.utilities.tageditor.rework.MetadataEditorPage
import com.bobbyesp.metadator.presentation.pages.utilities.tageditor.rework.MetadataEditorVM
import com.bobbyesp.metadator.presentation.pages.utilities.tageditor.spotify.MetadataBsVM
import com.bobbyesp.ui.components.bottomsheet.draggable.rememberDraggableBottomSheetState
import com.bobbyesp.ui.components.tags.RoundedTag
import com.bobbyesp.ui.motion.animatedComposable
Expand Down Expand Up @@ -344,60 +345,84 @@ fun Navigator() {
}
}

navigation<Route.UtilitiesNavigator>(
startDestination = Route.UtilitiesNavigator.TagEditor::class,
) {
slideInVerticallyComposable<Route.UtilitiesNavigator.TagEditor>(
typeMap = mapOf(typeOf<ParcelableSong>() to parcelableType<ParcelableSong>()),
) {
val song = it.toRoute<Route.UtilitiesNavigator.TagEditor>()
utilitiesNavigation { navController.popBackStack() }
settingsNavigation { navController.popBackStack() }
}
}
}
}
}
}

val viewModel = hiltViewModel<MetadataEditorVM>()
val state = viewModel.state.collectAsStateWithLifecycle()
fun NavGraphBuilder.utilitiesNavigation(
onNavigateBack: () -> Unit
) {
navigation<Route.UtilitiesNavigator>(
startDestination = Route.UtilitiesNavigator.TagEditor::class,
) {
slideInVerticallyComposable<Route.UtilitiesNavigator.TagEditor>(
typeMap = mapOf(typeOf<ParcelableSong>() to parcelableType<ParcelableSong>()),
) {
val song = it.toRoute<Route.UtilitiesNavigator.TagEditor>()

val securityErrorHandler =
rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartIntentSenderForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
viewModel.savePropertyMap(
audioPath = song.selectedSong.localSongPath
)
navController.popBackStack()
}
}
val viewModel = hiltViewModel<MetadataEditorVM>()
val bsViewModel = hiltViewModel<MetadataBsVM>()

LaunchedEffect(true) {
viewModel.eventFlow.collectLatest { event ->
Log.i("MetadataEditor", "Event received: $event")
when (event) {
is MetadataEditorVM.Companion.UiEvent.RequestPermission -> {
val intent =
IntentSenderRequest.Builder(event.intent)
.build()
securityErrorHandler.launch(intent)
}
val state = viewModel.state.collectAsStateWithLifecycle()
val bsState = bsViewModel.viewStateFlow.collectAsStateWithLifecycle()
val securityErrorHandler =
rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartIntentSenderForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
viewModel.savePropertyMap(
audioPath = song.selectedSong.localPath
)
onNavigateBack()
}
}

MetadataEditorVM.Companion.UiEvent.SaveSuccess -> {
navController.popBackStack()
}
}
}
}
LaunchedEffect(true) {
viewModel.eventFlow.collectLatest { event ->
when (event) {
is MetadataEditorVM.UiEvent.RequestPermission -> {
val intent =
IntentSenderRequest.Builder(event.intent)
.build()
securityErrorHandler.launch(intent)
}

MetadataEditorPage(
state = state,
receivedSong = song.selectedSong,
) { receivedEvent ->
viewModel.onEvent(receivedEvent)
}
}
is MetadataEditorVM.UiEvent.SaveSuccess -> {
onNavigateBack()
}
}
}
}

settingsNavigation { navController.popBackStack() }
LaunchedEffect(true) {
bsViewModel.outerEventsFlow.collectLatest { event ->
when (event) {
is MetadataBsVM.OuterEvent.SaveMetadata -> {
event.modifiedFields.forEach { field ->
viewModel.onEvent(
MetadataEditorVM.Event.UpdateProperty(
field.key,
field.value
)
)
}
}
}
}
}

MetadataEditorPage(
state = state,
bsViewState = bsState,
receivedAudio = song.selectedSong,
onBsEvent = bsViewModel::onEvent,
onEvent = viewModel::onEvent
)
}
}
}
Expand All @@ -415,7 +440,7 @@ fun NavGraphBuilder.settingsNavigation(
}

animatedComposable<Route.SettingsNavigator.Settings.General> {
Text("General")
GeneralSettingsPage()
}

animatedComposable<Route.SettingsNavigator.Settings.Appearance> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Palette
import androidx.compose.material.icons.rounded.Settings
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.LargeTopAppBar
Expand Down Expand Up @@ -57,6 +58,16 @@ fun SettingsPage(
.nestedScroll(scrollBehavior.nestedScrollConnection),
contentPadding = paddingValues
) {
item {
SettingItem(
title = stringResource(id = R.string.general),
description = stringResource(id = R.string.general_description),
icon = Icons.Rounded.Settings,
onClick = {
navController.navigate(Route.SettingsNavigator.Settings.General)
}
)
}
item {
SettingItem(
title = stringResource(id = R.string.appearance),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.bobbyesp.metadator.presentation.pages.settings.modules

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MediumTopAppBar
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource
import com.bobbyesp.metadator.R
import com.bobbyesp.metadator.presentation.common.LocalNavController
import com.bobbyesp.ui.components.button.BackButton
import com.bobbyesp.ui.components.preferences.PreferenceSwitch
import com.bobbyesp.utilities.preferences.Preferences
import com.bobbyesp.utilities.preferences.PreferencesKeys.MARQUEE_TEXT
import com.bobbyesp.utilities.preferences.booleanState

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun GeneralSettingsPage() {
val useMarqueeText = MARQUEE_TEXT.booleanState

val navController = LocalNavController.current
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(
rememberTopAppBarState(),
canScroll = { true }
)

Scaffold(
modifier = Modifier
.fillMaxSize()
.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
MediumTopAppBar(
title = {
Text(
text = stringResource(id = R.string.general),
style = MaterialTheme.typography.titleLarge
)
},
scrollBehavior = scrollBehavior,
navigationIcon = {
BackButton {
navController.popBackStack()
}
}
)
}
) { paddingValues ->
LazyColumn(
modifier = Modifier
.fillMaxSize()
.nestedScroll(scrollBehavior.nestedScrollConnection),
contentPadding = paddingValues
) {
item {
PreferenceSwitch(
title = stringResource(R.string.marquee_text),
description = stringResource(R.string.marquee_text_description),
isChecked = useMarqueeText.value,
onClick = {
useMarqueeText.value = !useMarqueeText.value
Preferences.updateValue(MARQUEE_TEXT, useMarqueeText.value)
}
)
}
}
}
}
Loading

0 comments on commit 0dd9dab

Please sign in to comment.