Skip to content

Commit

Permalink
v2.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
sosauce committed Oct 4, 2024
1 parent 7f45ab2 commit 6e12963
Show file tree
Hide file tree
Showing 48 changed files with 1,313 additions and 1,738 deletions.
Empty file.
8 changes: 4 additions & 4 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ android {
applicationId = "com.sosauce.cutemusic"
minSdk = 26
targetSdk = 35
versionCode = 11
versionName = "2.1.0"

versionCode = 12
versionName = "2.2.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
Expand All @@ -27,7 +26,6 @@ android {
release {
isMinifyEnabled = true
isShrinkResources = true
isCrunchPngs = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
Expand Down Expand Up @@ -82,6 +80,8 @@ android {
implementation(libs.koin.android)
implementation(libs.koin.androidx.compose)
debugImplementation(libs.androidx.ui.tooling)
//implementation("com.materialkolor:material-kolor:1.7.1")
implementation(libs.koin.androidx.startup)
implementation(libs.jaudiotagger)
}
}
Binary file modified app/release/baselineProfiles/0/app-release.dm
Binary file not shown.
Binary file modified app/release/baselineProfiles/1/app-release.dm
Binary file not shown.
4 changes: 2 additions & 2 deletions app/release/output-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 10,
"versionName": "2.0.0",
"versionCode": 12,
"versionName": "2.2.0",
"outputFile": "app-release.apk"
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@ import androidx.datastore.preferences.preferencesDataStore
import com.sosauce.cutemusic.data.datastore.PreferencesKeys.BLACKLISTED_FOLDERS
import com.sosauce.cutemusic.data.datastore.PreferencesKeys.FOLLOW_SYS
import com.sosauce.cutemusic.data.datastore.PreferencesKeys.HAS_SEEN_TIP
import com.sosauce.cutemusic.data.datastore.PreferencesKeys.KILL_SERVICE
import com.sosauce.cutemusic.data.datastore.PreferencesKeys.SNAP_SPEED_N_PITCH
import com.sosauce.cutemusic.data.datastore.PreferencesKeys.SORT_ORDER
import com.sosauce.cutemusic.data.datastore.PreferencesKeys.SORT_ORDER_ALBUMS
import com.sosauce.cutemusic.data.datastore.PreferencesKeys.SORT_ORDER_ARTISTS
import com.sosauce.cutemusic.data.datastore.PreferencesKeys.USE_AMOLED_MODE
import com.sosauce.cutemusic.data.datastore.PreferencesKeys.USE_ART_THEME
import com.sosauce.cutemusic.data.datastore.PreferencesKeys.USE_DARK_MODE
import com.sosauce.cutemusic.data.datastore.PreferencesKeys.USE_SYSTEM_FONT

val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
private const val PREFERENCES_NAME = "settings"

data object PreferencesKeys {
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(PREFERENCES_NAME)

private data object PreferencesKeys {
val SORT_ORDER = booleanPreferencesKey("sort_order")
val SORT_ORDER_ARTISTS = booleanPreferencesKey("sort_order_artists")
val SORT_ORDER_ALBUMS = booleanPreferencesKey("sort_order_albums")
Expand All @@ -32,6 +36,7 @@ data object PreferencesKeys {
val HAS_SEEN_TIP = booleanPreferencesKey("has_seen_tip")
val SNAP_SPEED_N_PITCH = booleanPreferencesKey("snap_peed_n_pitch")
val KILL_SERVICE = booleanPreferencesKey("kill_service")
val USE_ART_THEME = booleanPreferencesKey("use_art_theme")
}

@Composable
Expand Down Expand Up @@ -74,6 +79,10 @@ fun rememberHasSeenTip() =
fun rememberSnapSpeedAndPitch() =
rememberPreference(key = SNAP_SPEED_N_PITCH, defaultValue = false)

//fun rememberKillService(context: Context) =
// rememberNonComposablePreference(key = KILL_SERVICE, defaultValue = true, context = context)
@Composable
fun rememberUseArtTheme() =
rememberPreference(key = USE_ART_THEME, defaultValue = false)

fun rememberKillService(context: Context) =
rememberNonComposablePreference(key = KILL_SERVICE, defaultValue = true, context = context)

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.datastore.preferences.core.Preferences
Expand Down Expand Up @@ -54,19 +55,19 @@ fun <T> rememberNonComposablePreference(
context: Context
): MutableState<T> {
val coroutineScope = CoroutineScope(Dispatchers.Main)
val state = mutableStateOf(defaultValue)
var state by mutableStateOf(defaultValue)

coroutineScope.launch {
context.dataStore.data
.map { preferences -> preferences[key] ?: defaultValue }
.collect { newValue ->
state.value = newValue
state = newValue
}
}

return object : MutableState<T> {
override var value: T
get() = state.value
get() = state
set(value) {
coroutineScope.launch {
context.dataStore.edit {
Expand All @@ -88,3 +89,4 @@ fun rememberIsLandscape(): Boolean {
config.orientation == Configuration.ORIENTATION_LANDSCAPE
}
}

9 changes: 5 additions & 4 deletions app/src/main/java/com/sosauce/cutemusic/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.ComponentName
import androidx.media3.session.MediaController
import androidx.media3.session.SessionToken
import com.sosauce.cutemusic.domain.repository.MediaStoreHelper
import com.sosauce.cutemusic.domain.repository.MediaStoreHelperImpl
import com.sosauce.cutemusic.main.PlaybackService
import com.sosauce.cutemusic.ui.screens.metadata.MetadataViewModel
import com.sosauce.cutemusic.ui.shared_components.MusicViewModel
Expand All @@ -14,8 +15,8 @@ import org.koin.core.module.dsl.viewModel
import org.koin.dsl.module

val appModule = module {
single {
MediaStoreHelper(androidContext())
single<MediaStoreHelper> {
MediaStoreHelperImpl(androidContext())
}
single {
MediaController.Builder(
Expand All @@ -27,10 +28,10 @@ val appModule = module {
).buildAsync()
}
viewModel {
PostViewModel(get())
PostViewModel(get(), androidApplication())
}
viewModel {
MusicViewModel(get())
MusicViewModel(get(), androidApplication())
}
viewModel {
MetadataViewModel(androidApplication())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ package com.sosauce.cutemusic.domain.model
data class Album(
val id: Long,
val name: String,
val artist: String,
val artist: String
)
Original file line number Diff line number Diff line change
@@ -1,200 +1,31 @@
package com.sosauce.cutemusic.domain.repository

import android.content.ContentUris
import android.content.Context
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.net.Uri
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.IntentSenderRequest
import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
import com.sosauce.cutemusic.domain.model.Album
import com.sosauce.cutemusic.domain.model.Artist
import com.sosauce.cutemusic.domain.model.Folder
import com.sosauce.cutemusic.utils.queryAsFlow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow

class MediaStoreHelper(
private val context: Context
) {
fun getMusics():List<MediaItem> {
interface MediaStoreHelper {

val musics = mutableListOf<MediaItem>()
fun getMusics() : List<MediaItem>

val projection = arrayOf(
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM_ID,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.SIZE,
//MediaStore.Audio.Media.IS_FAVORITE,
)
fun getAlbums(): List<Album>

fun getArtists(): List<Artist>

context.contentResolver.query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
projection,
null,
null,
)?.use { cursor ->
val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)
val titleColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)
val artistColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)
val albumIdColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID)
val folderColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)
val sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)
//val isFavColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.IS_FAVORITE)
fun getFoldersWithMusics(): List<Folder>

while (cursor.moveToNext()) {
val id = cursor.getLong(idColumn)
val title = cursor.getString(titleColumn)
val artist = cursor.getString(artistColumn)
val albumId = cursor.getLong(albumIdColumn)
val filePath = cursor.getString(folderColumn)
val folder = filePath.substring(0, filePath.lastIndexOf('/'))
val size = cursor.getLong(sizeColumn)
//val isFavorite = cursor.getInt(isFavColumn) // 1 = is favorite, 0 = no
val uri = ContentUris.withAppendedId(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
id
)
val artUri = ContentUris.appendId(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI.buildUpon(), id
).appendPath("albumart").build()
suspend fun deleteMusics(
uris: List<Uri>,
intentSenderLauncher: ActivityResultLauncher<IntentSenderRequest>
)

musics.add(
MediaItem
.Builder()
.setUri(uri)
.setMediaId(id.toString())
.setMediaMetadata(
MediaMetadata
.Builder()
.setIsBrowsable(false)
.setIsPlayable(true)
.setTitle(title)
.setArtist(artist)
.setArtworkUri(artUri)
.setExtras(Bundle().apply {
putLong("albumId", albumId)
putString("folder", folder)
putLong("size", size)
putString("path", filePath)
putString("uri", uri.toString())
// putInt("isFavorite", isFavorite)
}).build()
).build()
)
}
}

return musics
}


fun getAlbums(): List<Album> {
val albums = mutableListOf<Album>()

val projection = arrayOf(
MediaStore.Audio.Albums._ID,
MediaStore.Audio.Albums.ALBUM,
MediaStore.Audio.Albums.ARTIST,
)

context.contentResolver.query(
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
projection,
null,
null,
null
)?.use { cursor ->
val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Albums._ID)
val albumColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Albums.ALBUM)
val artistColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Albums.ARTIST)

while (cursor.moveToNext()) {
val id = cursor.getLong(idColumn)
val album = cursor.getString(albumColumn)
val artist = cursor.getString(artistColumn)

val albumInfo = Album(id, album, artist)
albums.add(albumInfo)
}
}

return albums
}

fun getArtists(): List<Artist> {
val artists = mutableListOf<Artist>()

val projection = arrayOf(
MediaStore.Audio.Artists._ID,
MediaStore.Audio.Artists.ARTIST,
)

context.contentResolver.query(
MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
projection,
null,
null,
"${MediaStore.Audio.Artists.ARTIST} ASC"
)?.use { cursor ->
val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Artists._ID)
val artistColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Artists.ARTIST)

while (cursor.moveToNext()) {
val id = cursor.getLong(idColumn)
val artist = cursor.getString(artistColumn)

val artistInfo = Artist(
id = id,
name = artist
)
artists.add(artistInfo)
}
}

return artists
}


// Only gets folder with musics in them
fun getFoldersWithMusics(): List<Folder> {

val folders = mutableListOf<Folder>()

val projection = arrayOf(
MediaStore.Audio.Media.DATA,
)

context.contentResolver.query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
projection,
null,
null,
null
)?.use {
val folderPaths = mutableSetOf<String>()
val dataIndex = it.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)

while (it.moveToNext()) {
val filePath = it.getString(dataIndex)
val folderPath = filePath.substring(0, filePath.lastIndexOf('/'))
folderPaths.add(folderPath)
}
folderPaths.forEach { path ->
val folderName = path.substring(path.lastIndexOf('/') + 1)
folders.add(
Folder(
name = folderName,
path = path,
)
)
}
}
return folders
}
suspend fun editMusic(
uris: List<Uri>,
intentSenderLauncher: ActivityResultLauncher<IntentSenderRequest>
)

}
Loading

0 comments on commit 6e12963

Please sign in to comment.