Skip to content

Commit

Permalink
Merge pull request #18 from musicorum-app/dev
Browse files Browse the repository at this point in the history
new feat: offline caching
  • Loading branch information
MysteryMS authored Sep 7, 2023
2 parents 1702a11 + a8880a0 commit 2ad8a79
Show file tree
Hide file tree
Showing 33 changed files with 640 additions and 200 deletions.
23 changes: 12 additions & 11 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ plugins {
id 'com.google.firebase.crashlytics'
id 'dagger.hilt.android.plugin'
id 'com.github.triplet.play' version '3.7.0'
id "io.sentry.android.gradle" version "3.4.2"
id 'com.google.devtools.ksp'
}

def appKeyStoreFile = "../upload_key.jks"
Expand All @@ -21,11 +21,11 @@ def appKeyStorePassword = System.env.KEY_STORE_PASSWORD
def appKeyAlias = System.env.KEY_ALIAS
def appKeyPassword = System.env.KEY_PASSWORD

sentry {
/*sentry {
includeProguardMapping = true
autoUploadProguardMapping = true
experimentalGuardsquareSupport = true
}
}*/

android {
namespace 'io.musicorum.mobile'
Expand All @@ -51,8 +51,8 @@ android {
applicationId "io.musicorum.mobile"
minSdk 28
targetSdk 34
versionCode 59
versionName "1.17.0-pre-release"
versionCode 60
versionName "1.18.0-pre-release"
//compileSdkPreview = "UpsideDownCake"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Expand Down Expand Up @@ -130,10 +130,11 @@ dependencies {
//implementation 'io.sentry:sentry-android:6.14.0'
//implementation 'io.sentry:sentry-compose-android:6.14.0'

//def room_version = "2.4.3"
//implementation "androidx.room:room-runtime:$room_version"
//annotationProcessor "androidx.room:room-compiler:$room_version"
//kapt "androidx.room:room-compiler:$room_version"
def room_version = "2.5.2"
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
ksp "androidx.room:room-compiler:$room_version"

implementation "com.google.dagger:hilt-android:2.44.2"
implementation 'androidx.core:core-ktx:1.10.0'
Expand All @@ -150,7 +151,7 @@ dependencies {
implementation 'com.google.firebase:firebase-analytics-ktx'
implementation 'com.google.firebase:firebase-config-ktx'
implementation platform('com.google.firebase:firebase-bom:31.0.2')
implementation 'androidx.browser:browser:1.4.0'
implementation 'androidx.browser:browser:1.6.0'
implementation "io.ktor:ktor-client-core:$ktor_version"
implementation "io.ktor:ktor-client-android:$ktor_version"
implementation "io.ktor:ktor-client-cio:$ktor_version"
Expand All @@ -175,7 +176,7 @@ dependencies {
implementation 'androidx.activity:activity-compose:1.7.1'
implementation "androidx.compose.ui:ui"
implementation "androidx.compose.ui:ui-tooling-preview"
implementation 'androidx.compose.material3:material3:1.2.0-alpha03'
implementation 'androidx.compose.material3:material3:1.2.0-alpha06'
implementation 'com.google.accompanist:accompanist-placeholder-material:0.26.5-rc'
implementation 'io.coil-kt:coil-compose:2.4.0'
implementation 'androidx.datastore:datastore-preferences:1.0.0'
Expand Down
7 changes: 3 additions & 4 deletions app/src/main/java/io/musicorum/mobile/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import com.google.android.gms.common.GoogleApiAvailability
import com.google.android.play.core.appupdate.AppUpdateManagerFactory
import com.google.android.play.core.install.model.AppUpdateType.IMMEDIATE
import com.google.android.play.core.install.model.UpdateAvailability
import com.google.android.play.core.ktx.startUpdateFlowForResult
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.ktx.Firebase
Expand Down Expand Up @@ -91,8 +92,6 @@ import io.musicorum.mobile.views.login.loginGraph
import io.musicorum.mobile.views.mostListened.MostListened
import io.musicorum.mobile.views.settings.ScrobbleSettings
import io.musicorum.mobile.views.settings.Settings
import io.sentry.android.core.SentryAndroid
import io.sentry.compose.withSentryObservableEffect
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.map
import kotlinx.serialization.decodeFromString
Expand Down Expand Up @@ -197,14 +196,14 @@ class MainActivity : ComponentActivity() {
}
if (!BuildConfig.DEBUG) {
try {
SentryAndroid.init(this)
//SentryAndroid.init(this)
} catch (_: Exception) {
}
}

setContent {
val useDarkIcons = !isSystemInDarkTheme()
navController = rememberNavController().withSentryObservableEffect()
navController = rememberNavController()//.withSentryObservableEffect()

val mostListenedViewModel: MostListenedViewModel = viewModel()
val ctx = LocalContext.current
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/io/musicorum/mobile/coil/Defaults.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ fun defaultImageRequestBuilder(
placeholderType: PlaceholderType = PlaceholderType.TRACK
): ImageRequest {
val builder = ImageRequest.Builder(LocalContext.current)
.diskCacheKey(url)
.diskCachePolicy(CachePolicy.ENABLED)
.data(url)
.crossfade(true)
.networkCachePolicy(CachePolicy.READ_ONLY)


when (placeholderType) {
PlaceholderType.ARTIST -> {
builder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@ enum class LabelType {
fun HorizontalTracksRow(
tracks: List<Track>?,
labelType: LabelType,
errored: Boolean?
) {
if (errored == true) {
if (tracks?.isEmpty() == true) {
Text(
text = stringResource(R.string.empty_tracklist_message),
style = Subtitle1,
Expand All @@ -36,9 +35,9 @@ fun HorizontalTracksRow(
modifier = Modifier
.padding(start = 20.dp)
) {
if (tracks.isNullOrEmpty()) {
if (tracks == null) {
items(4) { _ ->
GenericCardPlaceholder(visible = tracks.isNullOrEmpty())
GenericCardPlaceholder(visible = true)
}
} else {
items(tracks) { track ->
Expand Down
43 changes: 32 additions & 11 deletions app/src/main/java/io/musicorum/mobile/components/TrackCard.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,25 @@ import androidx.compose.foundation.indication
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.CloudOff
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
Expand All @@ -36,6 +42,7 @@ import io.musicorum.mobile.R
import io.musicorum.mobile.coil.defaultImageRequestBuilder
import io.musicorum.mobile.serialization.NavigationTrack
import io.musicorum.mobile.serialization.entities.Track
import io.musicorum.mobile.ui.theme.ContentSecondary
import io.musicorum.mobile.ui.theme.KindaBlack
import io.musicorum.mobile.ui.theme.MostlyRed
import io.musicorum.mobile.ui.theme.Typography
Expand Down Expand Up @@ -99,18 +106,32 @@ fun TrackCard(track: Track, labelType: LabelType) {
)
}
}

}
Row {
if (track.pending) {
Icon(
Icons.Rounded.CloudOff,
null,
modifier = Modifier
.size(23.dp)
.padding(end = 5.dp)
.align(CenterVertically),
tint = ContentSecondary
)
}
Text(
text = track.name,
textAlign = TextAlign.Start,
style = Typography.bodyLarge,
modifier = Modifier
.widthIn(10.dp, 120.dp)
.indication(interactionSource, null)
.align(CenterVertically),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
Text(
text = track.name,
textAlign = TextAlign.Start,
style = Typography.bodyLarge,
modifier = Modifier
.width(120.dp)
.padding(top = 7.dp)
.indication(interactionSource, null),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)

if (labelType == LabelType.DATE) {
val text = if (track.attributes?.nowPlaying.toBoolean()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ package io.musicorum.mobile.components
import android.text.format.DateUtils
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.CloudOff
import androidx.compose.material.icons.rounded.Favorite
import androidx.compose.material.icons.rounded.FavoriteBorder
import androidx.compose.material3.Icon
Expand All @@ -18,6 +21,8 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
Expand All @@ -41,7 +46,7 @@ import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

@Composable
fun TrackItem(
fun TrackListItem(
track: Track?,
favoriteIcon: Boolean = true,
showTimespan: Boolean = false,
Expand All @@ -61,12 +66,24 @@ fun TrackItem(
.fillMaxWidth()
.clickable { nav.navigate("track/$dest") },
headlineContent = {
Text(
text = track.name,
style = Typography.bodyLarge,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
Row {
if (track.pending) {
Icon(
Icons.Rounded.CloudOff,
null,
modifier = Modifier
.size(22.dp)
.padding(end = 5.dp)
)
}
Text(
text = track.name,
style = Typography.bodyLarge,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.align(CenterVertically)
)
}
},
colors = listColors,
supportingContent = {
Expand Down Expand Up @@ -119,7 +136,7 @@ fun TrackItem(
}

@Composable
fun TrackItem(
fun TrackListItem(
track: SearchTrack?
) {
if (track == null) return
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.musicorum.mobile.database

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import io.musicorum.mobile.database.daos.CachedScrobblesDao
import io.musicorum.mobile.models.CachedScrobble
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.internal.synchronized

@Database(entities = [CachedScrobble::class], version = 2, exportSchema = false)
abstract class CachedScrobblesDb : RoomDatabase() {
abstract fun cachedScrobblesDao(): CachedScrobblesDao

companion object {
@Volatile
private var Instance: CachedScrobblesDb? = null

@OptIn(InternalCoroutinesApi::class)
fun getDatabase(context: Context): CachedScrobblesDb {
return Instance ?: synchronized(this) {
Room.databaseBuilder(context, CachedScrobblesDb::class.java, "cachedScrobbles")
.fallbackToDestructiveMigration()
.build()
}.also { Instance = it }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.musicorum.mobile.database

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import io.musicorum.mobile.database.daos.PendingScrobblesDao
import io.musicorum.mobile.models.PendingScrobble
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.internal.synchronized

@Database(entities = [PendingScrobble::class], version = 2, exportSchema = false)
abstract class PendingScrobblesDb : RoomDatabase() {
abstract fun pendingScrobblesDao(): PendingScrobblesDao

companion object {
@Volatile
private var Instance: PendingScrobblesDb? = null

@OptIn(InternalCoroutinesApi::class)
fun getDatabase(context: Context): PendingScrobblesDb {
return Instance ?: synchronized(this) {
Room.databaseBuilder(context, PendingScrobblesDb::class.java, "pendingScrobbles")
.fallbackToDestructiveMigration()
.build()
}.also { Instance = it }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.musicorum.mobile.database.daos

import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import io.musicorum.mobile.models.CachedScrobble
import kotlinx.coroutines.flow.Flow

@Dao
interface CachedScrobblesDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(data: CachedScrobble)

@Delete
suspend fun delete(data: CachedScrobble)

@Query("SELECT * FROM cachedScrobbles")
fun getAll(): Flow<List<CachedScrobble>>

@Query("DELETE FROM cachedScrobbles")
suspend fun clearAll()
}
Loading

0 comments on commit 2ad8a79

Please sign in to comment.