Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion app/src/main/java/com/craftworks/music/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,8 @@ fun AnimatedBottomNavBar(
}
}

fun formatMilliseconds(seconds: Int): String {
// TODO("Move these utils funtions to a separated utils package")
fun formatSeconds(seconds: Int): String {
return String.format(Locale.getDefault(), "%02d:%02d", seconds / 60, seconds % 60)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.craftworks.music.data

import kotlinx.serialization.Serializable

// LEGACY CODE! MUST NOT BE USED
// TODO("Delete legacy file")
@Serializable
data class NavidromeProvider (
val id: String = "0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.craftworks.music.data.datasource.local

import androidx.media3.common.MediaItem
import com.craftworks.music.data.model.MediaData
import com.craftworks.music.data.model.MediaItem
import com.craftworks.music.data.model.toMediaItem
import com.craftworks.music.data.model.toSong
import com.craftworks.music.managers.settings.AppearanceSettingsManager
Expand Down Expand Up @@ -53,15 +53,15 @@ class LocalDataSource @Inject constructor(
return localProvider.getLocalSongs().find { it.mediaMetadata.extras?.getString("navidromeID") == songId }
}

fun getLocalArtists(): List<MediaData.Artist> {
fun getLocalArtists(): List<com.craftworks.music.data.model.MediaItem.Artist> {
return localProvider.getLocalArtists()
}

suspend fun getLocalArtistAlbums(artist: String): List<MediaItem> {
return localProvider.getAlbumsByArtistId(artist)
}

fun searchLocalArtists(query: String): List<MediaData.Artist> {
fun searchLocalArtists(query: String): List<com.craftworks.music.data.model.MediaItem.Artist> {
if (query.isBlank()) return getLocalArtists()
return localProvider.getLocalArtists().filter {
it.name.contains(query, ignoreCase = true)
Expand All @@ -85,7 +85,7 @@ class LocalDataSource @Inject constructor(
): Boolean {
val initialSong = getLocalSong(initialSongId ?: "")?.toSong()

val newPlaylist = MediaData.Playlist(
val newPlaylist = MediaItem.Playlist(
navidromeID = "Local_${UUID.randomUUID()}",
name = playlistName,
comment = "",
Expand Down Expand Up @@ -163,7 +163,7 @@ class LocalDataSource @Inject constructor(
}

// Radios
suspend fun getLocalRadios(): List<MediaData.Radio> {
suspend fun getLocalRadios(): List<com.craftworks.music.data.model.MediaItem.Radio> {
return localDataSettingsManager.localRadios.first()
}

Expand All @@ -172,7 +172,7 @@ class LocalDataSource @Inject constructor(
url: String,
homePageUrl: String?
): Boolean {
val newRadio = MediaData.Radio(
val newRadio = MediaItem.Radio(
name = name,
media = url,
homePageUrl = homePageUrl ?: "",
Expand All @@ -185,7 +185,7 @@ class LocalDataSource @Inject constructor(
return true
}

suspend fun updateLocalRadio(radio: MediaData.Radio): Boolean {
suspend fun updateLocalRadio(radio: com.craftworks.music.data.model.MediaItem.Radio): Boolean {
val currentRadiosFromStore = localDataSettingsManager.localRadios.first().toMutableList()
val index = currentRadiosFromStore.indexOfFirst { it.navidromeID == radio.navidromeID }
if (index != -1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
import com.craftworks.music.data.NavidromeLibrary
import com.craftworks.music.data.model.Lyric
import com.craftworks.music.data.model.MediaData
import com.craftworks.music.data.model.MediaItem
import com.craftworks.music.data.model.toLyric
import com.craftworks.music.data.model.toLyrics
import com.craftworks.music.managers.NavidromeManager
Expand Down Expand Up @@ -54,6 +54,8 @@ import javax.inject.Singleton
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager

// LEGACY CODE! MUST NOT BE USED
// TODO("Delete legacy file")
@Singleton
class NavidromeDataSource @Inject constructor() {
private val json = Json { ignoreUnknownKeys = true }
Expand All @@ -72,20 +74,6 @@ class NavidromeDataSource @Inject constructor() {
}

private val insecureClient: HttpClient by lazy { buildInsecureClient() }

companion object {
fun md5Hash(input: String): String {
val md = MessageDigest.getInstance("MD5")
val hashBytes = md.digest(input.toByteArray())
return hashBytes.joinToString("") { "%02x".format(it) }
}

fun generateSalt(length: Int): String {
val allowedChars = ('a'..'z') + ('A'..'Z') + ('0'..'9')
return (1..length).map { allowedChars.random() }.joinToString("")
}
}

private fun buildInsecureClient(): HttpClient {
val trustAllCerts = arrayOf<TrustManager>(
@SuppressLint("CustomX509TrustManager")
Expand Down Expand Up @@ -117,6 +105,20 @@ class NavidromeDataSource @Inject constructor() {
}
}

companion object {
fun md5Hash(input: String): String {
val md = MessageDigest.getInstance("MD5")
val hashBytes = md.digest(input.toByteArray())
return hashBytes.joinToString("") { "%02x".format(it) }
}

fun generateSalt(length: Int): String {
val allowedChars = ('a'..'z') + ('A'..'Z') + ('0'..'9')
return (1..length).map { allowedChars.random() }.joinToString("")
}
}


private suspend fun getRequest(
endpoint: String,
musicFolderIds: List<Int>? = null,
Expand Down Expand Up @@ -284,12 +286,12 @@ class NavidromeDataSource @Inject constructor() {
suspend fun getNavidromeArtists(
ignoreCachedResponse: Boolean = false,
musicFolderIds: List<Int>? = NavidromeManager.getEnabledLibraryIdsForCurrentServer(),
): List<MediaData.Artist> = withContext(Dispatchers.IO) {
): List<com.craftworks.music.data.model.MediaItem.Artist> = withContext(Dispatchers.IO) {
getRequest(
"getArtists.view?f=json",
musicFolderIds,
ignoreCachedResponse
).filterIsInstance<MediaData.Artist>()
).filterIsInstance<com.craftworks.music.data.model.MediaItem.Artist>()
}

suspend fun getNavidromeArtistAlbums(
Expand All @@ -304,25 +306,25 @@ class NavidromeDataSource @Inject constructor() {

suspend fun getNavidromeArtistInfo(
artistId: String, ignoreCachedResponse: Boolean = false
): MediaData.ArtistInfo? = withContext(Dispatchers.IO) {
): com.craftworks.music.data.model.MediaItem.ArtistInfo? = withContext(Dispatchers.IO) {
getRequest(
"getArtistInfo.view?id=$artistId",
null,
ignoreCachedResponse
).filterIsInstance<MediaData.ArtistInfo>().firstOrNull()
).filterIsInstance<com.craftworks.music.data.model.MediaItem.ArtistInfo>().firstOrNull()
}

suspend fun searchNavidromeArtists(
query: String? = "",
ignoreCachedResponse: Boolean = false,
musicFolderIds: List<Int>? = NavidromeManager.getEnabledLibraryIdsForCurrentServer(),
): List<MediaData.Artist> = withContext(Dispatchers.IO) {
): List<com.craftworks.music.data.model.MediaItem.Artist> = withContext(Dispatchers.IO) {
if (query.isNullOrBlank()) getNavidromeArtists(musicFolderIds = musicFolderIds, ignoreCachedResponse = ignoreCachedResponse)
else getRequest(
"search3.view?query=$query&artistCount=100&albumCount=0&songCount=0",
musicFolderIds,
ignoreCachedResponse
).filterIsInstance<MediaData.Artist>()
).filterIsInstance<com.craftworks.music.data.model.MediaItem.Artist>()
}

// Playlists
Expand Down Expand Up @@ -392,12 +394,12 @@ class NavidromeDataSource @Inject constructor() {
// Radios
suspend fun getNavidromeRadios(
ignoreCachedResponse: Boolean = false
): List<MediaData.Radio> = withContext(Dispatchers.IO) {
): List<com.craftworks.music.data.model.MediaItem.Radio> = withContext(Dispatchers.IO) {
getRequest(
"getInternetRadioStations.view?f=json",
null,
ignoreCachedResponse
).filterIsInstance<MediaData.Radio>()
).filterIsInstance<com.craftworks.music.data.model.MediaItem.Radio>()
}

suspend fun createNavidromeRadio(
Expand Down Expand Up @@ -434,14 +436,14 @@ class NavidromeDataSource @Inject constructor() {
suspend fun getNavidromePlainLyrics(
metadata: MediaMetadata?, ignoreCachedResponse: Boolean = false
): List<Lyric> = withContext(Dispatchers.IO) {
getRequest("getLyrics.view?artist=${metadata?.artist}&title=${metadata?.title}", null).filterIsInstance<MediaData.PlainLyrics>().getOrNull(0)?.toLyric()?.takeIf { it.text.isNotEmpty() }?.let { listOf(it) } ?: emptyList()
getRequest("getLyrics.view?artist=${metadata?.artist}&title=${metadata?.title}", null).filterIsInstance<com.craftworks.music.data.model.MediaItem.PlainLyrics>().getOrNull(0)?.toLyric()?.takeIf { it.text.isNotEmpty() }?.let { listOf(it) } ?: emptyList()
}

suspend fun getNavidromeSyncedLyrics(
songId: String, ignoreCachedResponse: Boolean = false
): List<Lyric> = withContext(Dispatchers.IO) {
getRequest("getLyricsBySongId.view?id=${songId}", null, ignoreCachedResponse)
.filterIsInstance<MediaData.StructuredLyrics>().flatMap { it.toLyrics() }
.filterIsInstance<com.craftworks.music.data.model.MediaItem.StructuredLyrics>().flatMap { it.toLyrics() }
}

// Starred Items
Expand Down
59 changes: 0 additions & 59 deletions app/src/main/java/com/craftworks/music/data/model/Album.kt

This file was deleted.

16 changes: 0 additions & 16 deletions app/src/main/java/com/craftworks/music/data/model/Artist.kt

This file was deleted.

4 changes: 2 additions & 2 deletions app/src/main/java/com/craftworks/music/data/model/Lyric.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ data class NeteaseLrc(
)

//region Convert lyric format to app format.
fun MediaData.PlainLyrics.toLyric(): Lyric {
fun MediaItem.PlainLyrics.toLyric(): Lyric {
return Lyric(
startMs = -1,
text = if (value.isBlank()) emptyList() else listOf(value)
)
}

fun MediaData.StructuredLyrics.toLyrics(): List<Lyric> {
fun MediaItem.StructuredLyrics.toLyrics(): List<Lyric> {
return line
.groupBy { if (synced) it.start!! + (offset ?: 0) else -1 }
.map { (timestamp, lines) ->
Expand Down
Loading