Skip to content

Commit

Permalink
feat: quick picks on last played songs closes #3
Browse files Browse the repository at this point in the history
  • Loading branch information
Malopieds committed Jun 27, 2024
1 parent 1abe4e2 commit eb103f2
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ val AlbumViewTypeKey = stringPreferencesKey("albumViewType")
val PlaylistViewTypeKey = stringPreferencesKey("playlistViewType")

val PlaylistEditLockKey = booleanPreferencesKey("playlistEditLock")
val QuickPicksKey = stringPreferencesKey("discover")

enum class LibraryViewType {
LIST, GRID;
Expand Down Expand Up @@ -108,6 +109,10 @@ enum class MyTopFilter {
}
}

enum class QuickPicks {
QUICK_PICKS, LAST_LISTEN
}

val TopSize = stringPreferencesKey("topSize")

val ShowLyricsKey = booleanPreferencesKey("showLyrics")
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/zionhuang/music/db/DatabaseDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,8 @@ interface DatabaseDao {
@Query("SELECT COUNT(1) FROM related_song_map WHERE songId = :songId LIMIT 1")
fun hasRelatedSongs(songId: String): Boolean

@Query("SELECT song.* FROM (SELECT * from related_song_map GROUP BY relatedSongId) map JOIN song ON song.id = map.relatedSongId where songId = :songId")
fun getRelatedSongs(songId: String): Flow<List<Song>>
@Query(
"""
UPDATE playlist_song_map SET position =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ fun HomeScreen(
onDismiss = menuState::dismiss
)
}

else -> {
}
}
Expand Down Expand Up @@ -764,6 +765,7 @@ fun HomeScreen(
onDismiss = menuState::dismiss
)
}

else -> {
}
}
Expand Down Expand Up @@ -890,8 +892,6 @@ fun HomeScreen(
playlist.author ?: run {
playlist.author = Artist(name="YouTube Music", id=null)
}
// if (playlist.author?.name?.isEmpty() == true || playlist.author?.name?.contains("Youtube Music") != true)
// playlist.author = Artist(name="YouTube Music", id=null)
YouTubeGridItem(
item = playlist,
isActive = mediaMetadata?.album?.id == playlist.id,
Expand Down Expand Up @@ -959,6 +959,7 @@ fun HomeScreen(
)
}
}

else -> navController.navigate("artist/${item.id}")
}

Expand Down Expand Up @@ -987,6 +988,7 @@ fun HomeScreen(
onDismiss = menuState::dismiss
)
}

else -> {
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ import com.zionhuang.music.constants.ContentLanguageKey
import com.zionhuang.music.constants.CountryCodeToName
import com.zionhuang.music.constants.InnerTubeCookieKey
import com.zionhuang.music.constants.LanguageCodeToName
import com.zionhuang.music.constants.LibraryFilter
import com.zionhuang.music.constants.LibraryFilter.*
import com.zionhuang.music.constants.ProxyEnabledKey
import com.zionhuang.music.constants.ProxyTypeKey
import com.zionhuang.music.constants.ProxyUrlKey
import com.zionhuang.music.constants.QuickPicks.*
import com.zionhuang.music.constants.QuickPicksKey
import com.zionhuang.music.constants.SYSTEM_DEFAULT
import com.zionhuang.music.constants.TopSize
import com.zionhuang.music.ui.component.EditTextPreference
Expand Down Expand Up @@ -64,7 +66,8 @@ fun ContentSettings(
val (proxyType, onProxyTypeChange) = rememberEnumPreference(key = ProxyTypeKey, defaultValue = Proxy.Type.HTTP)
val (proxyUrl, onProxyUrlChange) = rememberPreference(key = ProxyUrlKey, defaultValue = "host:port")
val (lengthTop, onLengthTopChange) = rememberPreference(key = TopSize, defaultValue = "50")
val (defaultChip, onDefaultChipChange) = rememberEnumPreference(key = ChipSortTypeKey, defaultValue = LibraryFilter.LIBRARY)
val (defaultChip, onDefaultChipChange) = rememberEnumPreference(key = ChipSortTypeKey, defaultValue = LIBRARY)
val (quickPicks, onQuickPicksChange) = rememberEnumPreference(key = QuickPicksKey, defaultValue = QUICK_PICKS)


Column(
Expand Down Expand Up @@ -131,10 +134,6 @@ fun ContentSettings(
)
}

PreferenceGroupTitle(
title = "MY TOP"
)

EditTextPreference(
title = { Text(stringResource(R.string.top_length)) },
value = lengthTop,
Expand All @@ -145,12 +144,33 @@ fun ContentSettings(
)

ListPreference(
title = { Text("Change default chip") },
title = { Text(stringResource(R.string.default_lib_chips)) },
selectedValue = defaultChip,
values = listOf(LibraryFilter.LIBRARY, LibraryFilter.PLAYLISTS, LibraryFilter.SONGS, LibraryFilter.ALBUMS, LibraryFilter.ARTISTS),
valueText = { it.name },
values = listOf(LIBRARY, PLAYLISTS, SONGS, ALBUMS, ARTISTS),
valueText = {
when(it) {
SONGS -> stringResource(R.string.songs)
ARTISTS -> stringResource(R.string.artists)
ALBUMS -> stringResource(R.string.albums)
PLAYLISTS -> stringResource(R.string.playlists)
LIBRARY -> stringResource(R.string.filter_library)
}
},
onValueSelected = onDefaultChipChange
)

ListPreference(
title = { Text(stringResource(R.string.set_quick_picks)) },
selectedValue = quickPicks,
values = listOf(QUICK_PICKS, LAST_LISTEN),
valueText = {
when (it) {
QUICK_PICKS -> stringResource(R.string.quick_picks)
LAST_LISTEN -> stringResource(R.string.last_song_listened)
}
},
onValueSelected = onQuickPicksChange
)
}

TopAppBar(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.zionhuang.music.viewmodels

import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.zionhuang.innertube.YouTube
Expand All @@ -11,22 +12,33 @@ import com.zionhuang.innertube.pages.ExplorePage
import com.zionhuang.innertube.pages.HomePlayList
import com.zionhuang.innertube.pages.HomeAlbumRecommendation
import com.zionhuang.innertube.pages.HomeArtistRecommendation
import com.zionhuang.music.constants.QuickPicks
import com.zionhuang.music.constants.QuickPicksKey
import com.zionhuang.music.db.MusicDatabase
import com.zionhuang.music.db.entities.Artist
import com.zionhuang.music.db.entities.Song
import com.zionhuang.music.extensions.toEnum
import com.zionhuang.music.utils.dataStore
import com.zionhuang.music.utils.reportException
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class HomeViewModel @Inject constructor(
@ApplicationContext context: Context,
val database: MusicDatabase,
) : ViewModel() {
val isRefreshing = MutableStateFlow(false)
private val quickPicksEnum = context.dataStore.data.map {
it[QuickPicksKey].toEnum(QuickPicks.QUICK_PICKS)
}.distinctUntilChanged()

val quickPicks = MutableStateFlow<List<Song>?>(null)
val explorePage = MutableStateFlow<ExplorePage?>(null)
Expand Down Expand Up @@ -55,8 +67,15 @@ class HomeViewModel @Inject constructor(

val youtubePlaylists = MutableStateFlow<List<PlaylistItem>?>(null)

private suspend fun getQuickPicks(){
when (quickPicksEnum.first()) {
QuickPicks.QUICK_PICKS -> quickPicks.value = database.quickPicks().first().shuffled().take(20)
QuickPicks.LAST_LISTEN -> songLoad()
}
}

private suspend fun load() {
quickPicks.value = database.quickPicks().first().shuffled().take(20)
getQuickPicks()
val artists = database.mostPlayedArtists(System.currentTimeMillis() - 86400000 * 7 * 2).first().shuffled().take(5)
val filteredArtists = mutableListOf<Artist>()
artists.forEach {
Expand Down Expand Up @@ -143,6 +162,17 @@ class HomeViewModel @Inject constructor(
artistLoad(artistRecommendation.value?.getOrNull(2), homeThirdArtistRecommendation)
}

private suspend fun songLoad(){
val song = database.events().first().firstOrNull()?.song
if (song != null) {
println(song.song.title)
if (database.hasRelatedSongs(song.id)){
val relatedSongs = database.getRelatedSongs(song.id).first().shuffled().take(20)
quickPicks.value = relatedSongs
}
}
}

private suspend fun albumLoad(song: Song?, next: MutableStateFlow<HomeAlbumRecommendation?>){
val albumUtils = AlbumUtils(song?.song?.albumName, song?.song?.thumbnailUrl)
YouTube.next(WatchEndpoint(videoId = song?.id)).onSuccess { res ->
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@
<string name="enable_proxy">Enable proxy</string>
<string name="proxy_type">Proxy type</string>
<string name="proxy_url">Proxy URL</string>
<string name="default_lib_chips">Change default library chip</string>
<string name="set_quick_picks">Set Quick Picks</string>
<string name="last_song_listened">Based on last song listened</string>
<string name="restart_to_take_effect">Restart to take effect</string>

<string name="player_and_audio">Player and audio</string>
Expand Down

0 comments on commit eb103f2

Please sign in to comment.