Skip to content

Commit

Permalink
Merge branch 'dev' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
metezd authored Jul 23, 2023
2 parents ea183e9 + c9b28ee commit 2952284
Show file tree
Hide file tree
Showing 53 changed files with 1,801 additions and 347 deletions.
796 changes: 796 additions & 0 deletions app/schemas/com.zionhuang.music.db.InternalDatabase/11.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions app/src/main/java/com/zionhuang/music/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ class MainActivity : ComponentActivity() {
songs.firstOrNull()?.album?.id?.let { browseId ->
navController.navigate("album/$browseId")
}
}.onFailure {
it.printStackTrace()
}
}
} else {
Expand All @@ -365,6 +367,8 @@ class MainActivity : ComponentActivity() {
YouTube.queue(listOf(videoId))
}.onSuccess {
sharedSong = it.firstOrNull()
}.onFailure {
it.printStackTrace()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@ enum class PlaylistSongSortType {
}

enum class ArtistSortType {
CREATE_DATE, NAME, SONG_COUNT
CREATE_DATE, NAME, SONG_COUNT, PLAY_TIME
}

enum class ArtistSongSortType {
CREATE_DATE, NAME, PLAY_TIME
}

enum class AlbumSortType {
CREATE_DATE, NAME, ARTIST, YEAR, SONG_COUNT, LENGTH
CREATE_DATE, NAME, ARTIST, YEAR, SONG_COUNT, LENGTH, PLAY_TIME
}

enum class PlaylistSortType {
Expand Down
18 changes: 18 additions & 0 deletions app/src/main/java/com/zionhuang/music/constants/StatPeriod.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.zionhuang.music.constants

import java.time.LocalDateTime
import java.time.ZoneOffset

enum class StatPeriod {
`1_WEEK`, `1_MONTH`, `3_MONTH`, `6_MONTH`, `1_YEAR`, ALL;

fun toTimeMillis(): Long =
when (this) {
`1_WEEK` -> LocalDateTime.now().minusWeeks(1).toInstant(ZoneOffset.UTC).toEpochMilli()
`1_MONTH` -> LocalDateTime.now().minusMonths(1).toInstant(ZoneOffset.UTC).toEpochMilli()
`3_MONTH` -> LocalDateTime.now().minusMonths(3).toInstant(ZoneOffset.UTC).toEpochMilli()
`6_MONTH` -> LocalDateTime.now().minusMonths(6).toInstant(ZoneOffset.UTC).toEpochMilli()
`1_YEAR` -> LocalDateTime.now().minusMonths(12).toInstant(ZoneOffset.UTC).toEpochMilli()
ALL -> 0
}
}
100 changes: 86 additions & 14 deletions app/src/main/java/com/zionhuang/music/db/DatabaseDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ interface DatabaseDao {
song.artists.joinToString(separator = "") { it.name }
}
}

SongSortType.PLAY_TIME -> songsByPlayTimeAsc()
}.map { it.reversed(descending) }

Expand Down Expand Up @@ -71,6 +72,7 @@ interface DatabaseDao {
song.artists.joinToString(separator = "") { it.name }
}
}

SongSortType.PLAY_TIME -> likedSongsByPlayTimeAsc()
}.map { it.reversed(descending) }

Expand Down Expand Up @@ -142,8 +144,19 @@ interface DatabaseDao {
fun quickPicks(now: Long = System.currentTimeMillis()): Flow<List<Song>>

@Transaction
@Query("SELECT * FROM song ORDER BY totalPlayTime DESC LIMIT :limit")
fun mostPlayedSongs(limit: Int = 6): Flow<List<Song>>
@Query(
"""
SELECT *
FROM song
WHERE id IN (SELECT songId
FROM event
WHERE timestamp > :fromTimeStamp
GROUP BY songId
ORDER BY SUM(playTime) DESC
LIMIT :limit)
"""
)
fun mostPlayedSongs(fromTimeStamp: Long, limit: Int = 6): Flow<List<Song>>

@Transaction
@Query(
Expand All @@ -154,17 +167,39 @@ interface DatabaseDao {
JOIN song ON song_artist_map.songId = song.id
WHERE artistId = artist.id
AND song.inLibrary IS NOT NULL) AS songCount
FROM (SELECT artistId, SUM(playtime) AS totalPlaytime
FROM (SELECT *, (SELECT totalPlayTime FROM song WHERE id = songId) AS playtime
FROM song_artist_map)
GROUP BY artistId)
JOIN artist
ON artist.id = artistId
ORDER BY totalPlaytime DESC
FROM artist
JOIN(SELECT artistId, SUM(songTotalPlayTime) AS totalPlayTime
FROM song_artist_map
JOIN (SELECT songId, SUM(playTime) AS songTotalPlayTime
FROM event
WHERE timestamp > :fromTimeStamp
GROUP BY songId) AS e
ON song_artist_map.songId = e.songId
GROUP BY artistId
ORDER BY totalPlayTime DESC
LIMIT :limit)
ON artist.id = artistId
"""
)
fun mostPlayedArtists(fromTimeStamp: Long, limit: Int = 6): Flow<List<Artist>>

@Transaction
@Query(
"""
SELECT albumId
FROM song
JOIN (SELECT songId, SUM(playTime) AS songTotalPlayTime
FROM event
WHERE timestamp > :fromTimeStamp
GROUP BY songId) AS e
ON song.id = e.songId
WHERE albumId IS NOT NULL
GROUP BY albumId
ORDER BY SUM(songTotalPlayTime) DESC
LIMIT :limit
"""
)
fun mostPlayedArtists(limit: Int = 6): Flow<List<Artist>>
fun mostPlayedAlbums(fromTimeStamp: Long, limit: Int = 6): Flow<List<String>>

@Transaction
@Query("SELECT * FROM song WHERE id = :songId")
Expand All @@ -181,22 +216,45 @@ interface DatabaseDao {
fun lyrics(id: String?): Flow<LyricsEntity?>

@Transaction
@Query("SELECT *, (SELECT COUNT(1) FROM song_artist_map JOIN song ON song_artist_map.songId = song.id WHERE artistId = artist.id AND song.inLibrary IS NOT NULL) AS songCount FROM artist WHERE songCount > 0 ORDER BY rowId")
@Query("SELECT *, (SELECT COUNT(1) FROM song_artist_map JOIN song ON song_artist_map.songId = song.id WHERE artistId = artist.id AND song.inLibrary IS NOT NULL) AS songCount FROM artist WHERE bookmarkedAt IS NOT NULL ORDER BY bookmarkedAt")
fun artistsByCreateDateAsc(): Flow<List<Artist>>

@Transaction
@Query("SELECT *, (SELECT COUNT(1) FROM song_artist_map JOIN song ON song_artist_map.songId = song.id WHERE artistId = artist.id AND song.inLibrary IS NOT NULL) AS songCount FROM artist WHERE songCount > 0 ORDER BY name")
@Query("SELECT *, (SELECT COUNT(1) FROM song_artist_map JOIN song ON song_artist_map.songId = song.id WHERE artistId = artist.id AND song.inLibrary IS NOT NULL) AS songCount FROM artist WHERE bookmarkedAt IS NOT NULL ORDER BY name")
fun artistsByNameAsc(): Flow<List<Artist>>

@Transaction
@Query("SELECT *, (SELECT COUNT(1) FROM song_artist_map JOIN song ON song_artist_map.songId = song.id WHERE artistId = artist.id AND song.inLibrary IS NOT NULL) AS songCount FROM artist WHERE songCount > 0 ORDER BY songCount")
@Query("SELECT *, (SELECT COUNT(1) FROM song_artist_map JOIN song ON song_artist_map.songId = song.id WHERE artistId = artist.id AND song.inLibrary IS NOT NULL) AS songCount FROM artist WHERE bookmarkedAt IS NOT NULL ORDER BY songCount")
fun artistsBySongCountAsc(): Flow<List<Artist>>

@Transaction
@Query(
"""
SELECT artist.*,
(SELECT COUNT(1)
FROM song_artist_map
JOIN song ON song_artist_map.songId = song.id
WHERE artistId = artist.id
AND song.inLibrary IS NOT NULL) AS songCount
FROM artist
JOIN(SELECT artistId, SUM(totalPlayTime) AS totalPlayTime
FROM song_artist_map
JOIN song
ON song_artist_map.songId = song.id
GROUP BY artistId
ORDER BY totalPlayTime)
ON artist.id = artistId
WHERE bookmarkedAt IS NOT NULL
"""
)
fun artistsByPlayTimeAsc(): Flow<List<Artist>>

fun artists(sortType: ArtistSortType, descending: Boolean) =
when (sortType) {
ArtistSortType.CREATE_DATE -> artistsByCreateDateAsc()
ArtistSortType.NAME -> artistsByNameAsc()
ArtistSortType.SONG_COUNT -> artistsBySongCountAsc()
ArtistSortType.PLAY_TIME -> artistsByPlayTimeAsc()
}.map { it.reversed(descending) }

@Query("SELECT * FROM artist WHERE id = :id")
Expand Down Expand Up @@ -226,6 +284,19 @@ interface DatabaseDao {
@Query("SELECT * FROM album ORDER BY duration")
fun albumsByLengthAsc(): Flow<List<Album>>

@Transaction
@Query(
"""
SELECT album.*
FROM album
JOIN song
ON song.albumId = album.id
GROUP BY album.id
ORDER BY SUM(song.totalPlayTime)
"""
)
fun albumsByPlayTimeAsc(): Flow<List<Album>>

fun albums(sortType: AlbumSortType, descending: Boolean) =
when (sortType) {
AlbumSortType.CREATE_DATE -> albumsByCreateDateAsc()
Expand All @@ -239,6 +310,7 @@ interface DatabaseDao {
AlbumSortType.YEAR -> albumsByYearAsc()
AlbumSortType.SONG_COUNT -> albumsBySongCountAsc()
AlbumSortType.LENGTH -> albumsByLengthAsc()
AlbumSortType.PLAY_TIME -> albumsByPlayTimeAsc()
}.map { it.reversed(descending) }

@Transaction
Expand Down Expand Up @@ -277,7 +349,7 @@ interface DatabaseDao {
fun searchSongs(query: String, previewSize: Int = Int.MAX_VALUE): Flow<List<Song>>

@Transaction
@Query("SELECT *, (SELECT COUNT(1) FROM song_artist_map JOIN song ON song_artist_map.songId = song.id WHERE artistId = artist.id AND song.inLibrary IS NOT NULL) AS songCount FROM artist WHERE name LIKE '%' || :query || '%' AND songCount > 0 LIMIT :previewSize")
@Query("SELECT *, (SELECT COUNT(1) FROM song_artist_map JOIN song ON song_artist_map.songId = song.id WHERE artistId = artist.id AND song.inLibrary IS NOT NULL) AS songCount FROM artist WHERE name LIKE '%' || :query || '%' AND bookmarkedAt IS NOT NULL LIMIT :previewSize")
fun searchArtists(query: String, previewSize: Int = Int.MAX_VALUE): Flow<List<Artist>>

@Transaction
Expand Down
19 changes: 14 additions & 5 deletions app/src/main/java/com/zionhuang/music/db/MusicDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class MusicDatabase(
SortedSongAlbumMap::class,
PlaylistSongMapPreview::class
],
version = 10,
version = 11,
exportSchema = true,
autoMigrations = [
AutoMigration(from = 2, to = 3),
Expand All @@ -69,7 +69,8 @@ class MusicDatabase(
AutoMigration(from = 6, to = 7, spec = Migration6To7::class),
AutoMigration(from = 7, to = 8, spec = Migration7To8::class),
AutoMigration(from = 8, to = 9),
AutoMigration(from = 9, to = 10, spec = Migration9To10::class)
AutoMigration(from = 9, to = 10, spec = Migration9To10::class),
AutoMigration(from = 10, to = 11, spec = Migration10To11::class)
]
)
@TypeConverters(Converters::class)
Expand Down Expand Up @@ -99,7 +100,7 @@ val MIGRATION_1_2 = object : Migration(1, 2) {
val albumName: String? = null,
val liked: Boolean = false,
val totalPlayTime: Long = 0, // in milliseconds
val downloadState: Int = SongEntity.STATE_NOT_DOWNLOADED,
val downloadState: Int = 0,
val createDate: LocalDateTime = LocalDateTime.now(),
val modifyDate: LocalDateTime = LocalDateTime.now(),
)
Expand Down Expand Up @@ -211,7 +212,7 @@ val MIGRATION_1_2 = object : Migration(1, 2) {
"artist", SQLiteDatabase.CONFLICT_ABORT, contentValuesOf(
"id" to artist.id,
"name" to artist.name,
"createDate" to converters.dateToTimestamp(artist.createDate),
"createDate" to converters.dateToTimestamp(artist.lastUpdateTime),
"lastUpdateTime" to converters.dateToTimestamp(artist.lastUpdateTime)
)
)
Expand Down Expand Up @@ -305,4 +306,12 @@ class Migration7To8 : AutoMigrationSpec
@DeleteTable.Entries(
DeleteTable(tableName = "download")
)
class Migration9To10 : AutoMigrationSpec
class Migration9To10 : AutoMigrationSpec

@DeleteColumn.Entries(
DeleteColumn(tableName = "song", columnName = "downloadState"),
DeleteColumn(tableName = "artist", columnName = "bannerUrl"),
DeleteColumn(tableName = "artist", columnName = "description"),
DeleteColumn(tableName = "artist", columnName = "createDate")
)
class Migration10To11 : AutoMigrationSpec
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,9 @@ data class ArtistEntity(
@PrimaryKey val id: String,
val name: String,
val thumbnailUrl: String? = null,
val bannerUrl: String? = null,
val description: String? = null,
val createDate: LocalDateTime = LocalDateTime.now(),
val lastUpdateTime: LocalDateTime = LocalDateTime.now(),
val bookmarkedAt: LocalDateTime? = null,
) {
override fun toString(): String = name

val isYouTubeArtist: Boolean
get() = id.startsWith("UC")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ data class SongEntity(
val albumName: String? = null,
val liked: Boolean = false,
val totalPlayTime: Long = 0, // in milliseconds
val downloadState: Int = STATE_NOT_DOWNLOADED,
val inLibrary: LocalDateTime? = null,
) {
fun toggleLike() = copy(
Expand All @@ -25,11 +24,4 @@ data class SongEntity(
)

fun toggleLibrary() = copy(inLibrary = if (inLibrary == null) LocalDateTime.now() else null)

companion object {
const val STATE_NOT_DOWNLOADED = 0
const val STATE_PREPARING = 1
const val STATE_DOWNLOADING = 2
const val STATE_DOWNLOADED = 3
}
}
4 changes: 2 additions & 2 deletions app/src/main/java/com/zionhuang/music/ui/component/Items.kt
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ fun SongListItem(
) = ListItem(
title = song.song.title,
subtitle = joinByBullet(
song.artists.joinToString(),
song.artists.joinToString { it.name },
makeTimeString(song.song.duration * 1000L)
),
badges = badges,
Expand Down Expand Up @@ -308,7 +308,7 @@ fun AlbumListItem(
) = ListItem(
title = album.album.title,
subtitle = joinByBullet(
album.artists.joinToString(),
album.artists.joinToString { it.name },
pluralStringResource(R.plurals.n_song, album.album.songCount, album.album.songCount),
album.album.year?.toString()
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ import com.zionhuang.music.R
@Composable
fun NavigationTitle(
title: String,
modifier: Modifier = Modifier,
onClick: (() -> Unit)? = null,
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
modifier = modifier
.fillMaxWidth()
.windowInsetsPadding(WindowInsets.systemBars.only(WindowInsetsSides.Horizontal))
.clickable(enabled = onClick != null) {
Expand Down
Loading

0 comments on commit 2952284

Please sign in to comment.