Skip to content

Commit

Permalink
Merge pull request #107 from 'mattcarter11/singelton-sync-and-chip-lo…
Browse files Browse the repository at this point in the history
…ader' into 'dev'

Uploaded Artists: fix fetching and displaying privately owned (uploaded) artists

Also fixed:
* not all chips syncing when being selected
* don't sync if no connection. Finish sync if no error while fetching ytm data
* when syncing playlist, exclude liked playlist by id, not by order
* change text sort by date to sort by liked when songs liked filter is active
  • Loading branch information
mikooomich authored Dec 10, 2024
2 parents 099940c + 5333c96 commit 3ef82cc
Show file tree
Hide file tree
Showing 30 changed files with 821 additions and 384 deletions.
34 changes: 23 additions & 11 deletions app/src/main/java/com/dd3boh/outertune/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.dd3boh.outertune
import android.Manifest
import android.annotation.SuppressLint
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.PackageManager
Expand Down Expand Up @@ -157,6 +156,7 @@ import com.dd3boh.outertune.ui.screens.NewReleaseScreen
import com.dd3boh.outertune.ui.screens.Screens
import com.dd3boh.outertune.ui.screens.StatsScreen
import com.dd3boh.outertune.ui.screens.YouTubeBrowseScreen
import com.dd3boh.outertune.ui.screens.artist.ArtistAlbumsScreen
import com.dd3boh.outertune.ui.screens.artist.ArtistItemsScreen
import com.dd3boh.outertune.ui.screens.artist.ArtistScreen
import com.dd3boh.outertune.ui.screens.artist.ArtistSongsScreen
Expand Down Expand Up @@ -197,6 +197,7 @@ import com.dd3boh.outertune.ui.utils.appBarScrollBehavior
import com.dd3boh.outertune.ui.utils.cacheDirectoryTree
import com.dd3boh.outertune.ui.utils.getLocalThumbnail
import com.dd3boh.outertune.ui.utils.resetHeightOffset
import com.dd3boh.outertune.utils.NetworkConnectivityObserver
import com.dd3boh.outertune.utils.SyncUtils
import com.dd3boh.outertune.utils.dataStore
import com.dd3boh.outertune.utils.get
Expand Down Expand Up @@ -266,7 +267,7 @@ class MainActivity : ComponentActivity() {
} else {
startService(Intent(this, MusicService::class.java))
}
bindService(Intent(this, MusicService::class.java), serviceConnection, Context.BIND_AUTO_CREATE)
bindService(Intent(this, MusicService::class.java), serviceConnection, BIND_AUTO_CREATE)
}

override fun onStop() {
Expand Down Expand Up @@ -302,7 +303,11 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)


setContent {
val connectivityObserver = NetworkConnectivityObserver(this)
val isNetworkConnected by connectivityObserver.networkStatus.collectAsState(false)

val enableDynamicTheme by rememberPreference(DynamicThemeKey, defaultValue = true)
val darkTheme by rememberEnumPreference(DarkModeKey, defaultValue = DarkMode.AUTO)
val pureBlack by rememberPreference(PureBlackKey, defaultValue = false)
Expand Down Expand Up @@ -670,7 +675,8 @@ class MainActivity : ComponentActivity() {
LocalPlayerAwareWindowInsets provides playerAwareWindowInsets,
LocalDownloadUtil provides downloadUtil,
LocalShimmerTheme provides ShimmerTheme,
LocalSyncUtils provides syncUtils
LocalSyncUtils provides syncUtils,
LocalNetworkStatus provides isNetworkConnected
) {
Scaffold(
topBar = {
Expand Down Expand Up @@ -808,7 +814,7 @@ class MainActivity : ComponentActivity() {
}
},
bottomBar = {
Box() {
Box {
BottomSheetPlayer(
state = playerBottomSheetState,
navController = navController
Expand Down Expand Up @@ -1013,13 +1019,8 @@ class MainActivity : ComponentActivity() {
type = NavType.StringType
}
)
) { backStackEntry ->
val artistId = backStackEntry.arguments?.getString("artistId")!!
if (artistId.startsWith("LA")) {
ArtistSongsScreen(navController, scrollBehavior)
} else {
ArtistScreen(navController, scrollBehavior)
}
) {
ArtistScreen(navController, scrollBehavior)
}
composable(
route = "artist/{artistId}/songs",
Expand All @@ -1031,6 +1032,16 @@ class MainActivity : ComponentActivity() {
) {
ArtistSongsScreen(navController, scrollBehavior)
}
composable(
route = "artist/{artistId}/albums",
arguments = listOf(
navArgument("artistId") {
type = NavType.StringType
}
)
) {
ArtistAlbumsScreen(navController, scrollBehavior)
}
composable(
route = "artist/{artistId}/items?browseId={browseId}?params={params}",
arguments = listOf(
Expand Down Expand Up @@ -1197,3 +1208,4 @@ val LocalPlayerConnection = staticCompositionLocalOf<PlayerConnection?> { error(
val LocalPlayerAwareWindowInsets = compositionLocalOf<WindowInsets> { error("No WindowInsets provided") }
val LocalDownloadUtil = staticCompositionLocalOf<DownloadUtil> { error("No DownloadUtil provided") }
val LocalSyncUtils = staticCompositionLocalOf<SyncUtils> { error("No SyncUtils provided") }
val LocalNetworkStatus = staticCompositionLocalOf<Boolean> { error("No Network Status provided") }
11 changes: 11 additions & 0 deletions app/src/main/java/com/dd3boh/outertune/db/daos/AlbumsDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,17 @@ interface AlbumsDao : ArtistsDao {
""")
fun mostPlayedAlbums(fromTimeStamp: Long, limit: Int = 6): Flow<List<Album>>

@Query("""
SELECT album.*, count(song.dateDownload) downloadCount
FROM album_artist_map
JOIN album ON album_artist_map.albumId = album.id
JOIN song ON album_artist_map.albumId = song.albumId
WHERE artistId = :artistId
GROUP BY album.id
LIMIT :previewSize
""")
fun artistAlbumsPreview(artistId: String, previewSize: Int = 6): Flow<List<Album>>

@RawQuery(observedEntities = [AlbumEntity::class])
fun _getAlbum(query: SupportSQLiteQuery): Flow<List<Album>>

Expand Down
5 changes: 1 addition & 4 deletions app/src/main/java/com/dd3boh/outertune/db/daos/ArtistsDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,6 @@ interface ArtistsDao {
@Query("SELECT * FROM artist WHERE isLocal = 1")
fun allLocalArtists(): Flow<List<ArtistEntity>>

@Query("SELECT song.* FROM song_artist_map JOIN song ON song_artist_map.songId = song.id WHERE artistId = :artistId AND inLibrary IS NOT NULL LIMIT :previewSize")
fun artistSongsPreview(artistId: String, previewSize: Int = 3): Flow<List<Song>>

@Query("""
SELECT
artist.*,
Expand Down Expand Up @@ -184,7 +181,7 @@ interface ArtistsDao {
update(
artist.copy(
name = artistPage.artist.title,
thumbnailUrl = artistPage.artist.thumbnail.resize(544, 544),
thumbnailUrl = artistPage.artist.thumbnail?.resize(544, 544),
lastUpdateTime = LocalDateTime.now()
)
)
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/com/dd3boh/outertune/db/daos/SongsDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ interface SongsDao {
""")
fun songsByArtistAsc(): Flow<List<Song>>

@Query("SELECT song.* FROM song_artist_map JOIN song ON song_artist_map.songId = song.id WHERE artistId = :artistId AND inLibrary IS NOT NULL LIMIT :previewSize")
fun artistSongsPreview(artistId: String, previewSize: Int = 3): Flow<List<Song>>

@Query("SELECT * FROM song WHERE inLibrary IS NOT NULL ORDER BY totalPlayTime")
fun songsByPlayTimeAsc(): Flow<List<Song>>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ data class ArtistEntity(
val isLocal: Boolean = false
) {
val isYouTubeArtist: Boolean
get() = id.startsWith("UC")
get() = id.startsWith("UC") || id.startsWith("FEmusic_library_privately_owned_artist")

val isLocalArtist: Boolean
get() = id.startsWith("LA")
Expand Down
10 changes: 9 additions & 1 deletion app/src/main/java/com/dd3boh/outertune/extensions/ContextExt.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.dd3boh.outertune.extensions

import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import com.dd3boh.outertune.constants.InnerTubeCookieKey
import com.dd3boh.outertune.constants.YtmSyncKey
import com.dd3boh.outertune.constants.LikedAutoDownloadKey
Expand All @@ -14,10 +16,16 @@ fun Context.isSyncEnabled(): Boolean {
return runBlocking {
val ytmSync = dataStore[YtmSyncKey] ?: true
val cookie = dataStore[InnerTubeCookieKey] ?: ""
ytmSync && "SAPISID" in parseCookieString(cookie)
ytmSync && "SAPISID" in parseCookieString(cookie) && isInternetConnected()
}
}

fun Context.isInternetConnected(): Boolean {
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkCapabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
return networkCapabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) ?: false
}

fun Context.getLikeAutoDownload(): LikedAutodownloadMode {
return dataStore[LikedAutoDownloadKey].toEnum(LikedAutodownloadMode.OFF)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.dd3boh.outertune.ui.component.shimmer

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.width
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.dd3boh.outertune.constants.AppBarHeight
import com.dd3boh.outertune.ui.utils.fadingEdge
import com.valentinilk.shimmer.shimmer

@Composable
fun ArtistPagePlaceholder() {
ShimmerHost {
Box(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(4f / 3)
) {
Spacer(
modifier = Modifier
.shimmer()
.background(MaterialTheme.colorScheme.onSurface)
.fadingEdge(
top = WindowInsets.systemBars
.asPaddingValues()
.calculateTopPadding() + AppBarHeight,
bottom = 108.dp
)
)
TextPlaceholder(
height = 56.dp,
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(horizontal = 48.dp)
)
}

Row(
modifier = Modifier.padding(12.dp)
) {
ButtonPlaceholder(Modifier.weight(1f))

Spacer(Modifier.width(12.dp))

ButtonPlaceholder(Modifier.weight(1f))
}

repeat(6) {
ListItemPlaceHolder()
}
}
}
Loading

0 comments on commit 3ef82cc

Please sign in to comment.