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

Commit

Permalink
Merge pull request #109 from you-apps/select-music-folders
Browse files Browse the repository at this point in the history
feat: support for only playing music from certain directories
  • Loading branch information
Bnyro committed Jul 1, 2024
2 parents a9796e1 + 40d26ea commit a09dd4a
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 3 deletions.
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>

0 comments on commit a09dd4a

Please sign in to comment.