diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index b268ef3..9788da0 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -5,6 +5,9 @@ + + \ No newline at end of file diff --git a/app/src/main/java/com/example/harmonyhub/HarmonyHubApp.kt b/app/src/main/java/com/example/harmonyhub/HarmonyHubApp.kt index d2aaa4a..c298592 100644 --- a/app/src/main/java/com/example/harmonyhub/HarmonyHubApp.kt +++ b/app/src/main/java/com/example/harmonyhub/HarmonyHubApp.kt @@ -49,6 +49,7 @@ import com.example.harmonyhub.ui.account.LoginScreen import com.example.harmonyhub.ui.account.NewPasswordScreen import com.example.harmonyhub.ui.account.RegisterScreen import com.example.harmonyhub.ui.account.VerificationScreen +import com.example.harmonyhub.ui.library.AddSongToPlaylistScreen import com.example.harmonyhub.ui.library.PlaylistSongListScreen import com.example.harmonyhub.ui.play.PlayScreen import com.example.harmonyhub.ui.profile.ProfileScreen @@ -73,6 +74,7 @@ enum class HarmonyHubScreen(@StringRes val title: Int, val icon: ImageVector) { Verification(title = R.string.verification, icon = Icons.Default.Info), NewPassword(title = R.string.newPassword, icon = Icons.Default.Lock), PlaylistSongList(title = R.string.playlistSongList, icon = Icons.Default.AccountBox), + AddSongToPlaylist(title = R.string.addSongToPlaylist, icon = Icons.Default.AccountBox), } private val gradientBackground = Brush.verticalGradient( @@ -257,8 +259,6 @@ fun HarmonyHubApp( composable(route = HarmonyHubScreen.Playlist.name) { PlaylistsScreen( onBackButtonClicked = { navController.popBackStack() }, - onAddNewPlaylistClicked = { - }, onPlaylistClicked = { navController.navigate(HarmonyHubScreen.PlaylistSongList.name) }, @@ -304,6 +304,13 @@ fun HarmonyHubApp( } composable(route = HarmonyHubScreen.PlaylistSongList.name){ PlaylistSongListScreen( + playlistName = "Playlist 1", + onBackButtonClicked = { navController.popBackStack() }, + onAddButtonClicked = { navController.navigate(HarmonyHubScreen.AddSongToPlaylist.name) } + ) + } + composable(route = HarmonyHubScreen.AddSongToPlaylist.name) { + AddSongToPlaylistScreen( playlistName = "Playlist 1", onBackButtonClicked = { navController.popBackStack() } ) diff --git a/app/src/main/java/com/example/harmonyhub/ui/components/SongCard.kt b/app/src/main/java/com/example/harmonyhub/ui/components/SongCard.kt index 4fc5fc0..f143377 100644 --- a/app/src/main/java/com/example/harmonyhub/ui/components/SongCard.kt +++ b/app/src/main/java/com/example/harmonyhub/ui/components/SongCard.kt @@ -21,13 +21,20 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -data class Song(val id: String,val name: String, val artist: String, val imageResId: Int, val url: String) +data class Song( + val id: String, + val name: String, + val artist: String, + val imageResId: Int, + val url: String +) fun Song.contains(query: String, ignoreCase: Boolean = true): Boolean { return this.name.contains(query, ignoreCase) || this.artist.contains(query, ignoreCase) @@ -36,13 +43,14 @@ fun Song.contains(query: String, ignoreCase: Boolean = true): Boolean { @Composable fun SongCard( song: Song, + more: ImageVector, onSongClick: (String) -> Unit ) { Row( modifier = Modifier .fillMaxWidth() .padding(vertical = 8.dp) - .clickable{onSongClick(song.id)}, + .clickable { onSongClick(song.id) }, verticalAlignment = Alignment.CenterVertically ) { @@ -79,9 +87,9 @@ fun SongCard( // Xử lý menu hành động tại đây }) { Icon( - imageVector = Icons.Default.MoreVert, + imageVector = more, contentDescription = "More Options", - tint = Color.Gray + tint = if (more == Icons.Default.MoreVert) Color.Gray else Color.White ) } } diff --git a/app/src/main/java/com/example/harmonyhub/ui/library/AddSongToPlaylistScreen.kt b/app/src/main/java/com/example/harmonyhub/ui/library/AddSongToPlaylistScreen.kt new file mode 100644 index 0000000..25692e4 --- /dev/null +++ b/app/src/main/java/com/example/harmonyhub/ui/library/AddSongToPlaylistScreen.kt @@ -0,0 +1,170 @@ +package com.example.harmonyhub.ui.library + +import androidx.compose.foundation.gestures.detectTapGestures +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +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.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.AddCircle +import androidx.compose.material.icons.filled.Check +import androidx.compose.material.icons.filled.Clear +import androidx.compose.material.icons.filled.Search +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.material3.TextFieldDefaults.textFieldColors +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.harmonyhub.data.SongRepository +import com.example.harmonyhub.ui.components.Song +import com.example.harmonyhub.ui.components.SongCard +import com.example.harmonyhub.ui.components.contains +import com.example.harmonyhub.ui.theme.NotoSans + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AddSongToPlaylistScreen( + playlistName: String, + onBackButtonClicked: () -> Unit, +) { + val allSongs: List = SongRepository.allSongs + + var query by remember { mutableStateOf("") } + val focusManager = LocalFocusManager.current + + // Lọc danh sách bài hát theo từ khóa + val searchResults = allSongs.filter { it.contains(query, ignoreCase = true) } + + Column( + modifier = Modifier + .fillMaxSize() + .padding(8.dp) + .pointerInput(Unit) { + detectTapGestures(onTap = { + focusManager.clearFocus() + }) + } + ) { + Spacer(modifier = Modifier.height(16.dp)) + + // Thanh tiêu đề + Row( + modifier = Modifier + .fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Row( + verticalAlignment = Alignment.CenterVertically + ) { + IconButton(onClick = { onBackButtonClicked() }) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = "Back", + modifier = Modifier.size(24.dp) + ) + } + Text( + text = "Thêm bài hát vào playlist", + style = TextStyle( + fontFamily = NotoSans, + fontWeight = FontWeight.Bold, + fontSize = 24.sp, + color = Color.White + ) + ) + } + Spacer(modifier = Modifier.weight(1f)) + + IconButton(onClick = { + /* Handle saving playlist when clicked */ + onBackButtonClicked() + }) { + Icon( + imageVector = Icons.Default.Check, + contentDescription = "Done", + tint = Color(0xFF00FAF2), + modifier = Modifier.size(24.dp) + ) + } + } + Spacer(modifier = Modifier.height(16.dp)) + + // Ô tìm kiếm + TextField( + value = query, + onValueChange = { query = it }, + placeholder = { + Text( + text = "Tìm kiếm bài hát...", + style = TextStyle(fontFamily = NotoSans, fontSize = 16.sp) + ) + }, + leadingIcon = { + Icon(imageVector = Icons.Default.Search, contentDescription = "Search") + }, + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 8.dp) + .clip(RoundedCornerShape(16.dp)), + singleLine = true, + maxLines = 1, + textStyle = TextStyle(fontFamily = NotoSans, fontSize = 20.sp), + colors = textFieldColors( + focusedIndicatorColor = Color.Transparent, + unfocusedIndicatorColor = Color.Transparent, + disabledIndicatorColor = Color.Transparent, + containerColor = Color.Gray.copy(alpha = 0.2f) + ), + trailingIcon = { + if (query.isNotEmpty()) { + IconButton(onClick = { query = "" }) { + Icon(imageVector = Icons.Default.Clear, contentDescription = "Clear") + } + } + }, + ) + Text( + text = if (query.isEmpty()) "Phát gần đây" else "Kết quả tìm kiếm", + fontFamily = NotoSans, + fontSize = 20.sp, + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(8.dp) + ) + + LazyColumn( + modifier = Modifier.fillMaxSize() + ) { + items(searchResults) { song -> + SongCard(song = song, more = Icons.Default.AddCircle, onSongClick = {}) + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/harmonyhub/ui/library/ArtistScreen.kt b/app/src/main/java/com/example/harmonyhub/ui/library/ArtistScreen.kt index 6ae547e..7e4ac20 100644 --- a/app/src/main/java/com/example/harmonyhub/ui/library/ArtistScreen.kt +++ b/app/src/main/java/com/example/harmonyhub/ui/library/ArtistScreen.kt @@ -114,7 +114,7 @@ fun ArtistScreen( painter = painterResource(id = R.drawable.icons8_circled_play_64), contentDescription = "Play", tint = Color(0xFF00FAF2), - modifier = Modifier.size(40.dp) + modifier = Modifier.size(50.dp) ) } IconButton(onClick = { /* Share Action */ }) { @@ -122,7 +122,7 @@ fun ArtistScreen( imageVector = Icons.Default.Share, contentDescription = "Share", tint = Color.White, - modifier = Modifier.size(30.dp) + modifier = Modifier.size(25.dp) ) } } @@ -144,7 +144,11 @@ fun ArtistScreen( LazyColumn { items(songs) { song -> - SongCard(song = song, onSongClick = onSongClick) + SongCard( + song = song, + more = Icons.Default.MoreVert, + onSongClick = onSongClick + ) } } } diff --git a/app/src/main/java/com/example/harmonyhub/ui/library/ArtistsFollowingScreen.kt b/app/src/main/java/com/example/harmonyhub/ui/library/ArtistsFollowingScreen.kt index 1a09d53..7a5b725 100644 --- a/app/src/main/java/com/example/harmonyhub/ui/library/ArtistsFollowingScreen.kt +++ b/app/src/main/java/com/example/harmonyhub/ui/library/ArtistsFollowingScreen.kt @@ -94,7 +94,6 @@ fun ArtistsFollowingScreen( modifier = Modifier.size(24.dp) ) } - Spacer(modifier = Modifier.width(8.dp)) Text( text = "Nghệ sĩ đang theo dõi", style = TextStyle( @@ -114,6 +113,7 @@ fun ArtistsFollowingScreen( } } + Spacer(modifier = Modifier.height(16.dp)) // Ô tìm kiếm TextField( diff --git a/app/src/main/java/com/example/harmonyhub/ui/library/DownloadScreen.kt b/app/src/main/java/com/example/harmonyhub/ui/library/DownloadScreen.kt index 8ba5d74..d5a7c77 100644 --- a/app/src/main/java/com/example/harmonyhub/ui/library/DownloadScreen.kt +++ b/app/src/main/java/com/example/harmonyhub/ui/library/DownloadScreen.kt @@ -1,5 +1,7 @@ package com.example.harmonyhub.ui.library +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.MoreVert import androidx.compose.runtime.Composable import com.example.harmonyhub.data.SongRepository import com.example.harmonyhub.ui.components.Song @@ -11,6 +13,7 @@ fun DownloadScreen(onBackButtonClicked: () -> Unit) SongList( title = "Tải xuống", + more = Icons.Default.MoreVert, songs = allSongs, onBackButtonClicked = onBackButtonClicked, ) diff --git a/app/src/main/java/com/example/harmonyhub/ui/library/FavoriteScreen.kt b/app/src/main/java/com/example/harmonyhub/ui/library/FavoriteScreen.kt index 8d9f46d..0082368 100644 --- a/app/src/main/java/com/example/harmonyhub/ui/library/FavoriteScreen.kt +++ b/app/src/main/java/com/example/harmonyhub/ui/library/FavoriteScreen.kt @@ -1,5 +1,7 @@ package com.example.harmonyhub.ui.library +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.MoreVert import androidx.compose.runtime.Composable import com.example.harmonyhub.data.SongRepository import com.example.harmonyhub.ui.components.Song @@ -12,6 +14,7 @@ fun FavoriteScreen( SongList( title = "Yêu thích", + more = Icons.Default.MoreVert, songs = allSongs, onBackButtonClicked = onBackButtonClicked, ) diff --git a/app/src/main/java/com/example/harmonyhub/ui/library/HistoryScreen.kt b/app/src/main/java/com/example/harmonyhub/ui/library/HistoryScreen.kt index f763c12..f6cad20 100644 --- a/app/src/main/java/com/example/harmonyhub/ui/library/HistoryScreen.kt +++ b/app/src/main/java/com/example/harmonyhub/ui/library/HistoryScreen.kt @@ -1,5 +1,7 @@ package com.example.harmonyhub.ui.library +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.MoreVert import androidx.compose.runtime.Composable import com.example.harmonyhub.data.SongRepository import com.example.harmonyhub.ui.components.Song @@ -11,7 +13,8 @@ fun HistoryScreen( val allSongs: List = SongRepository.allSongs SongList( - title = "Tất cả bài hát", + title = "Lịch sử phát", + more = Icons.Default.MoreVert, songs = allSongs, onBackButtonClicked = onBackButtonClicked, ) diff --git a/app/src/main/java/com/example/harmonyhub/ui/library/LibraryScreen.kt b/app/src/main/java/com/example/harmonyhub/ui/library/LibraryScreen.kt index 382c171..1605fdd 100644 --- a/app/src/main/java/com/example/harmonyhub/ui/library/LibraryScreen.kt +++ b/app/src/main/java/com/example/harmonyhub/ui/library/LibraryScreen.kt @@ -19,6 +19,8 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Surface @@ -201,6 +203,7 @@ fun LibraryScreen( items(SongRepository.allSongs.take(5)) { song -> SongCard( song = song, + more = Icons.Default.MoreVert, onSongClick = { onPlaySongClicked(song.id) } ) } diff --git a/app/src/main/java/com/example/harmonyhub/ui/library/PlaylistSongList.kt b/app/src/main/java/com/example/harmonyhub/ui/library/PlaylistSongList.kt index 23c6182..0ed8e93 100644 --- a/app/src/main/java/com/example/harmonyhub/ui/library/PlaylistSongList.kt +++ b/app/src/main/java/com/example/harmonyhub/ui/library/PlaylistSongList.kt @@ -1,19 +1,207 @@ package com.example.harmonyhub.ui.library +import androidx.compose.foundation.gestures.detectTapGestures +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +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.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.Clear +import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.material.icons.filled.Search +import androidx.compose.material.icons.filled.Share +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.material3.TextFieldDefaults.textFieldColors import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.harmonyhub.R import com.example.harmonyhub.data.SongRepository import com.example.harmonyhub.ui.components.Song +import com.example.harmonyhub.ui.components.SongCard +import com.example.harmonyhub.ui.components.contains +import com.example.harmonyhub.ui.theme.NotoSans +@OptIn(ExperimentalMaterial3Api::class) @Composable fun PlaylistSongListScreen( playlistName: String, onBackButtonClicked: () -> Unit, + onAddButtonClicked: () -> Unit, ) { val allSongs: List = SongRepository.allSongs - SongList( - title = playlistName, - songs = allSongs, - onBackButtonClicked = onBackButtonClicked, - ) -} \ No newline at end of file + var query by remember { mutableStateOf("") } + val focusManager = LocalFocusManager.current + + var showDialog by remember { mutableStateOf(false) } + val searchResults = allSongs.filter { it.contains(query, ignoreCase = true) } + + Column( + modifier = Modifier + .fillMaxSize() + .padding(8.dp) + .pointerInput(Unit) { + detectTapGestures(onTap = { + focusManager.clearFocus() + }) + } + ) { + Spacer(modifier = Modifier.height(16.dp)) + + // Thanh tiêu đề + Row( + modifier = Modifier + .fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Row( + verticalAlignment = Alignment.CenterVertically + ) { + IconButton(onClick = { onBackButtonClicked() }) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = "Back", + modifier = Modifier.size(24.dp) + ) + } + Text( + text = playlistName, + style = TextStyle( + fontFamily = NotoSans, + fontWeight = FontWeight.Bold, + fontSize = 24.sp, + color = Color.White + ) + ) + } + Spacer(modifier = Modifier.weight(1f)) + Row { + IconButton(onClick = { onAddButtonClicked() }) { + Icon( + imageVector = Icons.Default.Add, + contentDescription = "Add", + modifier = Modifier.size(24.dp) + ) + } + IconButton(onClick = { /* Handle sort button click */ }) { + Icon( + imageVector = Icons.Default.MoreVert, + contentDescription = "More options", + modifier = Modifier.size(24.dp) + ) + } + } + } + + Spacer(modifier = Modifier.height(16.dp)) + + TextField( + value = query, + onValueChange = { query = it }, + placeholder = { + Text( + text = "Tìm kiếm bài hát...", + style = TextStyle(fontFamily = NotoSans, fontSize = 16.sp) + ) + }, + leadingIcon = { + Icon(imageVector = Icons.Default.Search, contentDescription = "Search") + }, + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 8.dp) + .clip(RoundedCornerShape(16.dp)), + singleLine = true, + maxLines = 1, + textStyle = TextStyle(fontFamily = NotoSans, fontSize = 20.sp), + colors = textFieldColors( + focusedIndicatorColor = Color.Transparent, + unfocusedIndicatorColor = Color.Transparent, + disabledIndicatorColor = Color.Transparent, + containerColor = Color.Gray.copy(alpha = 0.2f) + ), + trailingIcon = { + if (query.isNotEmpty()) { + IconButton(onClick = { query = "" }) { + Icon(imageVector = Icons.Default.Clear, contentDescription = "Clear") + } + } + }, + ) + + // Thông tin số bài hát + Row( + modifier = Modifier + .fillMaxWidth() + .padding(8.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = "${searchResults.size} bài hát", + style = TextStyle( + fontFamily = NotoSans, + fontSize = 20.sp, + color = Color.Gray + ) + ) + Spacer(modifier = Modifier.weight(1f)) + Row { + IconButton(onClick = { /* Play Action */ }) { + Icon( + painter = painterResource(id = R.drawable.icons8_circled_play_64), + contentDescription = "Play", + tint = Color(0xFF00FAF2), + modifier = Modifier.size(50.dp) + ) + } + IconButton(onClick = { /* Share Action */ }) { + Icon( + imageVector = Icons.Default.Share, + contentDescription = "Share", + tint = Color.White, + modifier = Modifier.size(25.dp) + ) + } + } + } + + // Danh sách bài hát + LazyColumn( + modifier = Modifier.fillMaxSize() + ) { + items(searchResults) { song -> + SongCard(song = song, more = Icons.Default.MoreVert, onSongClick = {}) + } + } + } +} diff --git a/app/src/main/java/com/example/harmonyhub/ui/library/PlaylistsScreen.kt b/app/src/main/java/com/example/harmonyhub/ui/library/PlaylistsScreen.kt index 3ddb085..68530bb 100644 --- a/app/src/main/java/com/example/harmonyhub/ui/library/PlaylistsScreen.kt +++ b/app/src/main/java/com/example/harmonyhub/ui/library/PlaylistsScreen.kt @@ -1,8 +1,6 @@ package com.example.harmonyhub.ui.library -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.clickable -import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -57,20 +55,16 @@ import com.example.harmonyhub.ui.components.PlaylistCard import com.example.harmonyhub.ui.components.contains import com.example.harmonyhub.ui.theme.NotoSans -@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun PlaylistsScreen( onBackButtonClicked: () -> Unit, - onAddNewPlaylistClicked: (String) -> Unit, onPlaylistClicked: (String) -> Unit, ) { var query by remember { mutableStateOf("") } var showDialog by remember { mutableStateOf(false) } var newPlaylistName by remember { mutableStateOf("") } - var isDeleteDialogVisible by remember { mutableStateOf(false) } - var selectedPlaylist by remember { mutableStateOf(null) } - val focusManager = LocalFocusManager.current val allPlaylists = listOf( @@ -106,7 +100,6 @@ fun PlaylistsScreen( modifier = Modifier.size(24.dp) ) } - Spacer(modifier = Modifier.width(8.dp)) Text( text = "Danh sách phát của tôi", style = TextStyle( @@ -205,13 +198,6 @@ fun PlaylistsScreen( PlaylistCard( playlist = playlist, onClick = { onPlaylistClicked(playlist.name) }, - modifier = Modifier.combinedClickable ( - onClick = { onPlaylistClicked(playlist.name) }, - onLongClick = { - selectedPlaylist = playlist - isDeleteDialogVisible = true - } - ) ) } // Nếu hàng có lẻ số nghệ sĩ, bạn có thể thêm một khoảng trống để cân đối @@ -267,7 +253,7 @@ fun PlaylistsScreen( onDismissRequest = { showDialog = false }, title = { Text( - "Tạo Playlist Mới", + "Tạo playlist mới", fontFamily = NotoSans, fontWeight = FontWeight.Bold ) @@ -278,7 +264,7 @@ fun PlaylistsScreen( onValueChange = { newPlaylistName = it }, placeholder = { Text( - "Tên Playlist", + "Tên playlist", fontFamily = NotoSans, fontSize = 16.sp ) @@ -312,16 +298,17 @@ fun PlaylistsScreen( confirmButton = { TextButton( onClick = { - onAddNewPlaylistClicked(newPlaylistName) + onPlaylistClicked(newPlaylistName) showDialog = false - } + }, + enabled = newPlaylistName.isNotBlank() ) { Text( "OK", fontFamily = NotoSans, fontSize = 16.sp, fontWeight = FontWeight.Bold, - color = Color(0xFF00FAF2) + color = if (newPlaylistName.isNotBlank()) Color(0xFF00FAF2) else Color.Gray ) } }, @@ -339,28 +326,6 @@ fun PlaylistsScreen( ) } - // Dialog xác nhận xóa playlist - if (isDeleteDialogVisible) { - AlertDialog( - onDismissRequest = { isDeleteDialogVisible = false }, - title = { Text("Xóa playlist") }, - text = { Text("Bạn có chắc chắn muốn xóa playlist này?") }, - confirmButton = { - TextButton(onClick = { - selectedPlaylist?.let { - // Logic xóa playlist ở đây - } - isDeleteDialogVisible = false - }) { - Text("Xóa") - } - }, - dismissButton = { - TextButton(onClick = { isDeleteDialogVisible = false }) { - Text("Hủy") - } - } - ) - } + } } diff --git a/app/src/main/java/com/example/harmonyhub/ui/library/SongList.kt b/app/src/main/java/com/example/harmonyhub/ui/library/SongList.kt index 590a18a..32a5bce 100644 --- a/app/src/main/java/com/example/harmonyhub/ui/library/SongList.kt +++ b/app/src/main/java/com/example/harmonyhub/ui/library/SongList.kt @@ -33,6 +33,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.TextStyle @@ -48,6 +49,7 @@ import com.example.harmonyhub.ui.theme.NotoSans @Composable fun SongList( title: String, // Tiêu đề trang + more: ImageVector, // Hành động thêm songs: List, // Danh sách bài hát onBackButtonClicked: () -> Unit, // Xử lý nút Back ) { @@ -82,7 +84,6 @@ fun SongList( modifier = Modifier.size(24.dp) ) } - Spacer(modifier = Modifier.width(8.dp)) Text( text = title, style = TextStyle( @@ -168,7 +169,7 @@ fun SongList( modifier = Modifier.fillMaxSize() ) { items(searchResults) { song -> - SongCard(song = song , onSongClick = {}) + SongCard(song = song , more = more, onSongClick = {}) } } } diff --git a/app/src/main/java/com/example/harmonyhub/ui/search/SearchScreen.kt b/app/src/main/java/com/example/harmonyhub/ui/search/SearchScreen.kt index 86cf39e..abc2cd5 100644 --- a/app/src/main/java/com/example/harmonyhub/ui/search/SearchScreen.kt +++ b/app/src/main/java/com/example/harmonyhub/ui/search/SearchScreen.kt @@ -10,6 +10,7 @@ import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Clear +import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.filled.Search import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon @@ -97,7 +98,7 @@ fun SearchScreen( ) Text( - text = if (query.isEmpty()) "Tìm kiếm gần đây" else "Kết quả tìm kiếm", + text = if (query.isEmpty()) "Phát gần đây" else "Kết quả tìm kiếm", fontFamily = NotoSans, fontSize = 20.sp, fontWeight = FontWeight.Bold, @@ -108,7 +109,7 @@ fun SearchScreen( modifier = Modifier.fillMaxSize() ) { items(searchResults) { song -> - SongCard(song = song , onSongClick = {} ) + SongCard(song = song , more = Icons.Default.MoreVert, onSongClick = {} ) } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9862dc9..0038758 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -17,5 +17,6 @@ Verification New Password Playlist Song List + Add Song To Playlist \ No newline at end of file