Skip to content

Commit

Permalink
database-design branch - merging & resolving conflicts from minhnhat_…
Browse files Browse the repository at this point in the history
…branch
  • Loading branch information
thebeo2004 committed Nov 28, 2024
2 parents 61ee77b + e84a8ac commit c5e660e
Show file tree
Hide file tree
Showing 21 changed files with 822 additions and 107 deletions.
7 changes: 7 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,11 @@ dependencies {
implementation ("org.json:json:20210307") // org.json để xử lý JSON
implementation ("androidx.media3:media3-exoplayer:1.1.0")
implementation ("androidx.media3:media3-ui:1.1.0")

implementation("io.coil-kt:coil-compose:2.2.2") // Phiên bản mới nhất
implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1")
implementation ("androidx.lifecycle:lifecycle-runtime-compose:2.6.0-alpha03")
// Retrofit
implementation ("com.squareup.retrofit2:retrofit:2.9.0")
implementation ("com.squareup.retrofit2:converter-gson:2.9.0")
}
4 changes: 4 additions & 0 deletions app/src/main/java/com/example/harmonyhub/MyApplication.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.example.harmonyhub

import android.app.Application
import com.example.harmonyhub.data.repository.DefaultHomeScreenRepo
import com.example.harmonyhub.data.repository.HomeScreenRepo
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class MyApplication: Application() {
lateinit var container: HomeScreenRepo
override fun onCreate() {
super.onCreate()
container = DefaultHomeScreenRepo()
}
}
43 changes: 23 additions & 20 deletions app/src/main/java/com/example/harmonyhub/data/SongRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,29 @@ import com.example.harmonyhub.ui.components.Song

object SongRepository{
val allSongs = listOf(
Song(id = "1", name = "Inside1 Out", artist = "The Chainsmokers, Charlee", imageResId = R.drawable.v,
"https://p.scdn.co/mp3-preview/6b7763066dd42d94dc893f12bb135d7d5392e386?cid=d8a5ed958d274c2e8ee717e6a4b0971d"),
Song(id = "2", name = "Young", artist = "The Chainsmokers", imageResId = R.drawable.v,
"https://p.scdn.co/mp3-preview/8ede412058d9e95de0b4b3a735fe3c999498336c?cid=d8a5ed958d274c2e8ee717e6a4b0971d"),
Song(id = "3", name = "Beach House", artist = "The Chainsmokers, Sick", imageResId = R.drawable.v,
"https://p.scdn.co/mp3-preview/8bf8384cc1c01bcf22a1b92ef0a2c6290fc596e4?cid=d8a5ed958d274c2e8ee717e6a4b0971d"),
Song(id = "4", name = "Kills You Slowly", artist = "The Chainsmokers", imageResId = R.drawable.v,""),
Song(id = "5", name = "Setting Fires", artist = "The Chainsmokers, XYLO", imageResId = R.drawable.v,""),
Song(id = "6", name = "The Real Slim Shady", artist = "Eminem", imageResId = R.drawable.v,""),
Song(id = "7", name = "Lose Yourself", artist = "Eminem", imageResId = R.drawable.v,""),
Song(id = "8", name = "Bohemian Rhapsody", artist = "Queen", imageResId = R.drawable.v,""),
Song(id = "9", name = "Shape of You", artist = "Ed Sheeran", imageResId = R.drawable.v,""),
Song(id = "10", name = "Perfect", artist = "Ed Sheeran", imageResId = R.drawable.v,""),
Song(id = "11", name = "Thinking Out Loud", artist = "Ed Sheeran", imageResId = R.drawable.v,""),
Song(id = "12", name = "Photograph", artist = "Ed Sheeran", imageResId = R.drawable.v,""),
Song(id = "13", name = "Imagine Dragons", artist = "Imagine Dragons", imageResId = R.drawable.v,""),
Song(id = "14", name = "Believer", artist = "Imagine Dragons", imageResId = R.drawable.v,""),
Song(id = "15", name = "Radioactive", artist = "Imagine Dragons", imageResId = R.drawable.v,""),
Song(id = "16", name = "Thunder", artist = "Imagine Dragons", imageResId = R.drawable.v,""),
Song(id = "17", name = "Demons", artist = "Imagine Dragons", imageResId = R.drawable.v,""),
Song(id = "3ztP5O7dJSha2PG429eUCb", name = "Thiên Lý Ơi", artist = "Jack - J97",
imageResId = "https://i.scdn.co/image/ab67616d00001e0233a31cc1175e787bfea17a65",
url = "https://p.scdn.co/mp3-preview/8ede412058d9e95de0b4b3a735fe3c999498336c?cid=d8a5ed958d274c2e8ee717e6a4b0971d"),
Song(id = "7gSQxwCpEMjg8wb6Y3oqe7", name = "HÀO QUANG", artist = "ANH TRAI SAY HI",
imageResId = "https://i.scdn.co/image/ab67616d00001e02901ea2601f4f8262474a75a1",
url = "https://p.scdn.co/mp3-preview/05a875c428a96e884053a5bb500394e8503f8c18?cid=d8a5ed958d274c2e8ee717e6a4b0971d"),
Song(id = "7jLSThU5Kg1RWt19Leiaxm", name = "Chìm Sâu", artist = "RPT MCK, Trung Trần",
imageResId = "https://i.scdn.co/image/ab67616d00001e02b315e8bb7ef5e57e9a25bb0f",
url = "https://p.scdn.co/mp3-preview/0496b1c18c7653d9124a2f39e148ec3babcae737?cid=d8a5ed958d274c2e8ee717e6a4b0971d"),
Song(id = "41DlPJXKTCypXdf2eSqa03", name = "bình yên", artist = "Vũ., Binz",
imageResId = "https://i.scdn.co/image/ab67616d00001e02be066d7fd668d8a0672b1245",
url = "https://p.scdn.co/mp3-preview/90a1ce11d080ad8ec16e0b02a65f3d135c951d3c?cid=d8a5ed958d274c2e8ee717e6a4b0971d"),
Song(id = "5Bti0azlFhMattVY76qFr9", name = "Lạ lùng", artist = "Vũ.",
imageResId = "https://i.scdn.co/image/ab67616d00001e02e93fadbe305ea32872b6dd11",
url = "https://p.scdn.co/mp3-preview/7c8c36fc929c6c3f35188355e3bb37f35e4b87fd?cid=d8a5ed958d274c2e8ee717e6a4b0971d"),
Song(id = "7kpNUrBDYDoX6QKGzrBD1R", name = "Thôi Em Đừng Đi", artist = "RPT MCk, Trung Trần",
imageResId = "https://i.scdn.co/image/ab67616d00001e02b315e8bb7ef5e57e9a25bb0f",
url = "https://p.scdn.co/mp3-preview/69b768853fe8a3ef97adfc3f0a64d6f20b07e40c?cid=d8a5ed958d274c2e8ee717e6a4b0971d"),
Song(id = "4qYfRfSxsmhJ1WMaywtLyI", name = "Từng Quen", artist = "Wren Evans",
imageResId = "https://i.scdn.co/image/ab67616d00001e0271d5ffe4407f913393ecdd11",
url = "https://p.scdn.co/mp3-preview/f602709d8887fa66b008fc0001646ba55110725d?cid=d8a5ed958d274c2e8ee717e6a4b0971d"),

)
val currentPLaylist : MutableList<Song> = mutableListOf()

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.example.harmonyhub.data.network

data class Avatar(
val url: String,
val width: Int,
val height: Int
)

data class Avatars(
val avatar: List<Avatar>
)

data class Album(
val type: String,
val id: String,
val name: String,
val cover: List<Avatar>,
val artists: List<Artist>
)

data class AlbumOut(
val id: String,
val name: String,
val image: String,
val listArtist: List<String>,
)

data class Artist(
val type: String,
val id: String,
val name: String,
val visuals: Avatars? = null
)

data class ArtistOut(
val id: String,
val name: String,
val image: String?
)




data class PopularItem(
val type: String,
val id: String,
val name: String,
val cover: List<Avatar>,//album
val artists: List<Artist>,//album
val visuals: Avatars? = null,//Artist
val images: List<List<Image>>? = null


)

data class Contents(
val totalCount: Int,
val items: List<PopularItem>
)

data class SectionItem(
val type: String,
val id: String,
val title: String,
val contents: Contents
)

data class Sections(
val totalCount: Int,
val items: List<SectionItem>
)

data class Response(
val status: Boolean,
val errorId: String,
val sections: Sections
)

data class ResponseHomeScreenData(
val listPopularArtist: MutableList<ArtistOut>?,
val listPopularAlbums: MutableList<AlbumOut>?,
val listChart: MutableList<ChartOut>?
)

// Lớp cho từng playlist
data class PlaylistItem(
val type: String,
val id: String,
val name: String,
val shareUrl: String,
val description: String,
val owner: Owner,
val images: List<List<Image>>
)

// Lớp owner chứa thông tin về người sở hữu playlist
data class Owner(
val name: String,
val type: String
)

// Lớp hình ảnh của playlist
data class Image(
val url: String,
val width: Int?,
val height: Int?
)

data class ChartOut(
val name: String,
val image: String?,
val id: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package com.example.harmonyhub.data.repository


import com.example.harmonyhub.data.network.AlbumOut
import com.example.harmonyhub.data.network.ArtistOut
import com.example.harmonyhub.data.network.ChartOut

import com.example.harmonyhub.data.network.Response
import com.example.harmonyhub.data.network.ResponseHomeScreenData
import com.google.gson.Gson
import okhttp3.OkHttpClient
import okhttp3.Request

class DefaultHomeScreenRepo : HomeScreenRepo {
override suspend fun updatePopularItem(): ResponseHomeScreenData? {
val listPopularArtist : MutableList<ArtistOut>? = mutableListOf()
val listPopularAlbums: MutableList<AlbumOut>? = mutableListOf()
val listChart: MutableList<ChartOut>? = mutableListOf()

var result : ResponseHomeScreenData? = null

try {

val client = OkHttpClient()

val request = Request.Builder()
.url("https://spotify-scraper.p.rapidapi.com/v1/home")
.get()
.addHeader("x-rapidapi-key", "c18da195b0mshcdebcf46df53015p1a1b64jsn33955d1b96fc")
.addHeader("x-rapidapi-host", "spotify-scraper.p.rapidapi.com")
.build()

val response = client.newCall(request).execute()
// Kiểm tra xem phản hồi có thành công không
if (response.isSuccessful) {
val jsonResponse = response.body?.string()
//println("Response: $jsonResponse")
// Kiểm tra nếu jsonResponse không null và là chuỗi hợp lệ
if (jsonResponse != null && jsonResponse.isNotEmpty()) {
try {

val gson = Gson()
val responseData = gson.fromJson(jsonResponse, Response::class.java)

// Trích xuất dữ liệu
if (responseData.status) {
//trich xuat Popular Artise
val PopularArtist = responseData.sections.items[0].contents.items
val PopularAlbums = responseData.sections.items[1].contents.items
val PopularChart = responseData.sections.items[3].contents.items
listPopularArtist?.addAll(PopularArtist.map {
ArtistOut(it.id, it.name, it.visuals?.avatar?.get(1)?.url)
})
listPopularAlbums?.addAll(PopularAlbums.map {
AlbumOut(it.id, it.name, it.cover[1].url, it.artists.map { artist -> artist.name })
})
listChart?.addAll(PopularChart.map {
ChartOut(it.name, it.images?.get(0)?.get(0)?.url, it.id)
})

result = ResponseHomeScreenData(listPopularArtist, listPopularAlbums, listChart)
return result
// for (i in listPopularArtist!!) {
// println("${i.id} - ${i.name} - ${i.image}")
// }
// for (i in listPopularAlbums!!) {
// println("${i.id} - ${i.name} - ${i.image} ")
// for( j in i.listArtist) {
// println("${j}")
// }
// }

} else {
println("Error: Request was not successful")
}
} catch (e: Exception) {
println("Error parsing JSON: ${e.message}")
}
} else {
println("Error: JSON response is null.")
}
} else {
println("Request failed with code: ${response.code}")
}
} catch (e: Exception) {
e.printStackTrace()
null
} finally {
return result
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.harmonyhub.data.repository

import com.example.harmonyhub.data.network.ResponseHomeScreenData

interface HomeScreenRepo {
suspend fun updatePopularItem() : ResponseHomeScreenData?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.example.harmonyhub.ui.components

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow.Companion.Ellipsis
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.example.harmonyhub.ui.theme.NotoSans

@Composable
fun AlbumCard(songName: String, albumImg: String, id : String, listArtist: List<String>) {
Surface(
modifier = Modifier
.size(width = 125.dp, height = 180.dp)
.clickable { },
color = Color.Transparent
) {
Column(modifier = Modifier.padding(4.dp))
{
Box(
modifier = Modifier.size(width = 125.dp, height = 125.dp)
) {
AsyncImage(
model = ImageRequest.Builder(context = LocalContext.current)
.data(albumImg)
.crossfade(true)
.build(),
error = painterResource(com.example.harmonyhub.R.drawable.ic_broken_image),
placeholder = painterResource(id = com.example.harmonyhub.R.drawable.loading_img),
contentDescription = "Photo",
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize().clip(RoundedCornerShape(12.dp)),
)
}
Spacer(modifier = Modifier.height(4.dp))
Text(
text = songName,
style = TextStyle(
fontFamily = NotoSans,
fontWeight = FontWeight.SemiBold,
fontSize = 16.sp
),
maxLines = 1,
overflow = Ellipsis
)
val joinedNames = listArtist.joinToString(separator = ", ")
Text(
text = joinedNames,
style = TextStyle(
fontFamily = NotoSans,
fontSize = 14.sp
),
color = Color.Gray,
maxLines = 1, overflow = Ellipsis
)
}
}
}
Loading

0 comments on commit c5e660e

Please sign in to comment.