Skip to content
This repository has been archived by the owner on Aug 7, 2024. It is now read-only.

feat: support for only playing music from certain directories #109

Merged
merged 1 commit into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,34 @@ class LocalMusicRepository(
MediaStore.Audio.Media.ARTIST_ID,
MediaStore.Audio.Media.DATE_MODIFIED,
MediaStore.Audio.Media.DATE_ADDED,
MediaStore.Audio.Media.CD_TRACK_NUMBER
MediaStore.Audio.Media.CD_TRACK_NUMBER,
MediaStore.Audio.Media.RELATIVE_PATH
)

val sortOrder = "${MediaStore.Audio.Media.TITLE} ASC"

val showAllMusic = Pref.sharedPreferences.getBoolean(Pref.showAllMusicKey, true)
val musicDirectories = Pref.sharedPreferences.getStringSet(Pref.musicDirectoriesKey, setOf()).orEmpty()

var sqlQueryString = ""
if (!showAllMusic) {
for (index in musicDirectories.indices) {
sqlQueryString += "${MediaStore.Audio.Media.RELATIVE_PATH} LIKE ?"
if (index != musicDirectories.size - 1) sqlQueryString += " OR "
}
}

val query = contentResolver.query(
collection,
projection,
null,
null,
sqlQueryString,
if (!showAllMusic) musicDirectories.map {
path -> "${path}%"
}.toTypedArray() else null,
sortOrder
)
query?.use { cursor ->
val pathColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.RELATIVE_PATH)
val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)
val titleColumn =
cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import app.suhasdissa.vibeyou.backend.models.Login
import app.suhasdissa.vibeyou.backend.viewmodel.AuthViewModel
import app.suhasdissa.vibeyou.navigation.Destination
import app.suhasdissa.vibeyou.presentation.screens.settings.components.CacheSizeDialog
import app.suhasdissa.vibeyou.presentation.screens.settings.components.LocalMusicPathsDialog
import app.suhasdissa.vibeyou.presentation.screens.settings.components.SettingItem

@OptIn(ExperimentalMaterial3Api::class)
Expand All @@ -53,6 +54,7 @@ fun SettingsScreen(
val authViewModel: AuthViewModel = viewModel(factory = AuthViewModel.Factory)
val topBarBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
var showImageCacheDialog by remember { mutableStateOf(false) }
var showSelectMusicPathsDialog by remember { mutableStateOf(false) }

val view = LocalView.current
Scaffold(modifier = modifier.fillMaxSize(), topBar = {
Expand Down Expand Up @@ -115,6 +117,16 @@ fun SettingsScreen(
icon = Icons.Rounded.Storage
)
}
item {
SettingItem(
title = stringResource(R.string.local_music_paths),
description = stringResource(R.string.local_music_paths_description),
onClick = {
showSelectMusicPathsDialog = true
},
icon = Icons.Rounded.Landscape
)
}
/*
item {
SettingItem(
Expand Down Expand Up @@ -169,4 +181,9 @@ fun SettingsScreen(
showImageCacheDialog = false
}
}
if (showSelectMusicPathsDialog) {
LocalMusicPathsDialog {
showSelectMusicPathsDialog = false
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package app.suhasdissa.vibeyou.presentation.screens.settings.components

import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.RemoveCircleOutline
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.core.content.edit
import androidx.documentfile.provider.DocumentFile
import app.suhasdissa.vibeyou.R
import app.suhasdissa.vibeyou.utils.Pref
import app.suhasdissa.vibeyou.utils.rememberPreference

@Composable
fun LocalMusicPathsDialog(onDismissRequest: () -> Unit) {
val context = LocalContext.current

var allAvailableMusic by rememberPreference(key = Pref.showAllMusicKey, defaultValue = true)
val musicPaths = remember {
Pref.sharedPreferences.getStringSet(Pref.musicDirectoriesKey, setOf()).orEmpty().toMutableStateList()
}

val chooseFolderLauncher = rememberLauncherForActivityResult(contract = ActivityResultContracts.OpenDocumentTree()) { uri ->
val file = DocumentFile.fromTreeUri(context, uri ?: return@rememberLauncherForActivityResult) ?: return@rememberLauncherForActivityResult
val relativePath = file.uri.path?.split(":")?.last().toString()
musicPaths.add(relativePath)
Pref.sharedPreferences.edit {
putStringSet(Pref.musicDirectoriesKey, musicPaths.toSet())
}
}

AlertDialog(
onDismissRequest = onDismissRequest,
title = {
Text(text = stringResource(id = R.string.local_music_paths))
},
text = {
Column(
modifier = Modifier.fillMaxWidth()
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
modifier = Modifier.weight(1f),
text = stringResource(id = R.string.all_available_music)
)
Switch(checked = allAvailableMusic, onCheckedChange = {
allAvailableMusic = it
})
}

AnimatedVisibility(visible = !allAvailableMusic) {
LazyColumn {
items(musicPaths.toList()) { path ->
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
modifier = Modifier.weight(1f),
text = path
)
IconButton(
onClick = {
musicPaths.remove(path)
Pref.sharedPreferences.edit {
putStringSet(Pref.musicDirectoriesKey, musicPaths.toSet())
}
}
) {
Icon(Icons.Default.RemoveCircleOutline, contentDescription = null)
}
}
}

item {
Button(onClick = { chooseFolderLauncher.launch(null) }) {
Text(text = stringResource(id = R.string.add_folder))
}
}
}
}
}
},
confirmButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(id = R.string.ok))
}
}
)
}
2 changes: 2 additions & 0 deletions app/src/main/java/app/suhasdissa/vibeyou/utils/Pref.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ object Pref {
const val equalizerKey = "equalizer"
const val equalizerPresetKey = "equalizerPreset"
const val equalizerBandsKey = "equalizerBands"
const val showAllMusicKey = "showAllMusicKey"
const val musicDirectoriesKey = "musicDirectoriesKey"

lateinit var sharedPreferences: SharedPreferences

Expand Down
4 changes: 4 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,8 @@
<string name="enabled">Enabled</string>
<string name="none">None</string>
<string name="reset_equalizer">Reset equalizer</string>
<string name="local_music_paths">Local music paths</string>
<string name="local_music_paths_description">Select where to load local music from.</string>
<string name="add_folder">Add folder</string>
<string name="all_available_music">All available music</string>
</resources>