Skip to content

Commit

Permalink
feat(LibraryDynamicPlaylistScreen): Implement search functionality fo…
Browse files Browse the repository at this point in the history
…r dynamic playlists
  • Loading branch information
maxrave-dev committed Feb 1, 2025
1 parent d620633 commit aa53da6
Showing 1 changed file with 133 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,30 +1,46 @@
package com.maxrave.simpmusic.ui.screen.library

import android.os.Bundle
import android.util.Log
import androidx.annotation.StringRes
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Search
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.SearchBar
import androidx.compose.material3.SearchBarDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
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.unit.dp
import androidx.media3.common.util.UnstableApi
import androidx.navigation.NavController
import com.maxrave.simpmusic.R
import com.maxrave.simpmusic.data.db.entities.ArtistEntity
import com.maxrave.simpmusic.data.db.entities.SongEntity
import com.maxrave.simpmusic.extension.navigateSafe
import com.maxrave.simpmusic.ui.component.ArtistFullWidthItems
Expand All @@ -49,18 +65,48 @@ fun LibraryDynamicPlaylistScreen(

var chosenSong: SongEntity? by remember { mutableStateOf(null) }
var showBottomSheet by rememberSaveable { mutableStateOf(false) }
var showSearchBar by rememberSaveable { mutableStateOf(false) }
var query by rememberSaveable { mutableStateOf("") }

val favorite by viewModel.listFavoriteSong.collectAsState()
var tempFavorite by rememberSaveable { mutableStateOf(emptyList<SongEntity>()) }
val followed by viewModel.listFollowedArtist.collectAsState()
var tempFollowed by rememberSaveable { mutableStateOf(emptyList<ArtistEntity>()) }
val mostPlayed by viewModel.listMostPlayedSong.collectAsState()
var tempMostPlayed by rememberSaveable { mutableStateOf(emptyList<SongEntity>()) }
val downloaded by viewModel.listDownloadedSong.collectAsState()
var tempDownloaded by rememberSaveable { mutableStateOf(emptyList<SongEntity>()) }

LaunchedEffect(query) {
Log.w("LibraryDynamicPlaylistScreen", "Check query: $query")
tempFavorite = favorite.filter { it.title.contains(query, ignoreCase = true) }
Log.w("LibraryDynamicPlaylistScreen", "Check tempFavorite: $tempFavorite")
tempFollowed = followed.filter { it.name.contains(query, ignoreCase = true) }
Log.w("LibraryDynamicPlaylistScreen", "Check tempFollowed: $tempFollowed")
tempMostPlayed = mostPlayed.filter { it.title.contains(query, ignoreCase = true) }
Log.w("LibraryDynamicPlaylistScreen", "Check tempMostPlayed: $tempMostPlayed")
tempDownloaded = downloaded.filter { it.title.contains(query, ignoreCase = true) }
Log.w("LibraryDynamicPlaylistScreen", "Check tempDownloaded: $tempDownloaded")
}

LazyColumn(
modifier = Modifier.padding(top = 64.dp),
contentPadding = innerPadding,
) {
item {
AnimatedVisibility(showSearchBar) {
Spacer(Modifier.height(55.dp))
}
}
if (type == LibraryDynamicPlaylistType.Followed) {
items(followed, key = { it.channelId }) { artist ->
items(
if (query.isNotEmpty() && showSearchBar) {
tempFollowed
} else {
followed
},
key = { it.channelId },
) { artist ->
ArtistFullWidthItems(
artist,
onClickListener = {
Expand All @@ -76,9 +122,24 @@ fun LibraryDynamicPlaylistScreen(
} else {
items(
when (type) {
LibraryDynamicPlaylistType.Downloaded -> downloaded
LibraryDynamicPlaylistType.Favorite -> favorite
LibraryDynamicPlaylistType.MostPlayed -> mostPlayed
LibraryDynamicPlaylistType.Downloaded ->
if (query.isNotEmpty() && showSearchBar) {
tempDownloaded
} else {
downloaded
}
LibraryDynamicPlaylistType.Favorite ->
if (query.isNotEmpty() && showSearchBar) {
tempFavorite
} else {
favorite
}
LibraryDynamicPlaylistType.MostPlayed ->
if (query.isNotEmpty() && showSearchBar) {
tempMostPlayed
} else {
mostPlayed
}
else -> emptyList()
},
key = { it.hashCode() },
Expand Down Expand Up @@ -111,29 +172,76 @@ fun LibraryDynamicPlaylistScreen(
song = chosenSong ?: return,
)
}
TopAppBar(
title = {
Text(
text =
stringResource(
type.name(),
),
style = typo.titleMedium,
)
},
navigationIcon = {
Box(Modifier.padding(horizontal = 5.dp)) {
RippleIconButton(
R.drawable.baseline_arrow_back_ios_new_24,
Modifier
.size(32.dp),
true,
) {
navController.navigateUp()
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
TopAppBar(
title = {
Text(
text =
stringResource(
type.name(),
),
style = typo.titleMedium,
)
},
navigationIcon = {
Box(Modifier.padding(horizontal = 5.dp)) {
RippleIconButton(
R.drawable.baseline_arrow_back_ios_new_24,
Modifier
.size(32.dp),
true,
) {
navController.navigateUp()
}
}
},
actions = {
Box(Modifier.padding(horizontal = 5.dp)) {
RippleIconButton(
if (showSearchBar) R.drawable.baseline_close_24 else R.drawable.baseline_search_24,
Modifier
.size(32.dp),
true,
) {
showSearchBar = !showSearchBar
}
}
},
)
androidx.compose.animation.AnimatedVisibility(visible = showSearchBar) {
SearchBar(
modifier =
Modifier
.fillMaxWidth()
.height(45.dp)
.padding(horizontal = 12.dp),
inputField = {
CompositionLocalProvider(LocalTextStyle provides typo.bodySmall) {
SearchBarDefaults.InputField(
query = query,
onQueryChange = { query = it },
onSearch = { showSearchBar = false },
expanded = showSearchBar,
onExpandedChange = { showSearchBar = it },
placeholder = {
Text(
stringResource(R.string.search),
style = typo.bodySmall,
)
},
leadingIcon = { Icon(Icons.Rounded.Search, contentDescription = null) },
)
}
},
expanded = false,
onExpandedChange = {},
windowInsets = WindowInsets(0, 0, 0, 0),
) {
}
},
)
}
}
}

sealed class LibraryDynamicPlaylistType {
Expand Down

0 comments on commit aa53da6

Please sign in to comment.