Skip to content

Commit

Permalink
refactor: tag value separators setting
Browse files Browse the repository at this point in the history
  • Loading branch information
zyrouge committed Dec 29, 2023
1 parent 5594687 commit 2e8c1e3
Show file tree
Hide file tree
Showing 7 changed files with 274 additions and 6 deletions.
9 changes: 9 additions & 0 deletions .phrasey/schema.toml
Original file line number Diff line number Diff line change
Expand Up @@ -614,3 +614,12 @@ parameters = ["x"]

[[keys]]
name = "MiniPlayerTextMarquee"

[[keys]]
name = "AddItem"

[[keys]]
name = "ArtistTagValueSeparators"

[[keys]]
name = "GenreTagValueSeparators"
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class AlbumRepository(private val symphony: Symphony) {
private val searcher = FuzzySearcher<String>(
options = listOf(
FuzzySearchOption({ v -> get(v)?.name?.let { compareString(it) } }, 3),
FuzzySearchOption({ v -> get(v)?.artists?.let { compareIterable(it) } })
FuzzySearchOption({ v -> get(v)?.artists?.let { compareCollection(it) } })
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class SongRepository(private val symphony: Symphony) {
options = listOf(
FuzzySearchOption({ v -> get(v)?.title?.let { compareString(it) } }, 3),
FuzzySearchOption({ v -> get(v)?.filename?.let { compareString(it) } }, 2),
FuzzySearchOption({ v -> get(v)?.artists?.let { compareIterable(it) } }),
FuzzySearchOption({ v -> get(v)?.artists?.let { compareCollection(it) } }),
FuzzySearchOption({ v -> get(v)?.album?.let { compareString(it) } })
)
)
Expand Down
30 changes: 30 additions & 0 deletions app/src/main/java/io/github/zyrouge/symphony/ui/view/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import androidx.compose.material.icons.filled.PhotoSizeSelectLarge
import androidx.compose.material.icons.filled.Recommend
import androidx.compose.material.icons.filled.RuleFolder
import androidx.compose.material.icons.filled.SkipNext
import androidx.compose.material.icons.filled.SpaceBar
import androidx.compose.material.icons.filled.Storage
import androidx.compose.material.icons.filled.TextFormat
import androidx.compose.material.icons.filled.TextIncrease
Expand Down Expand Up @@ -87,6 +88,7 @@ import io.github.zyrouge.symphony.ui.view.settings.SettingsFloatInputTile
import io.github.zyrouge.symphony.ui.view.settings.SettingsLinkTile
import io.github.zyrouge.symphony.ui.view.settings.SettingsMultiFolderTile
import io.github.zyrouge.symphony.ui.view.settings.SettingsMultiOptionTile
import io.github.zyrouge.symphony.ui.view.settings.SettingsMultiTextOptionTile
import io.github.zyrouge.symphony.ui.view.settings.SettingsOptionTile
import io.github.zyrouge.symphony.ui.view.settings.SettingsSideHeading
import io.github.zyrouge.symphony.ui.view.settings.SettingsSimpleTile
Expand Down Expand Up @@ -134,6 +136,8 @@ fun SettingsView(context: ViewContext) {
val songsFilterPattern by context.symphony.settings.songsFilterPattern.collectAsState()
val blacklistFolders by context.symphony.settings.blacklistFolders.collectAsState()
val whitelistFolders by context.symphony.settings.whitelistFolders.collectAsState()
val artistTagSeparators by context.symphony.settings.artistTagSeparators.collectAsState()
val genreTagSeparators by context.symphony.settings.genreTagSeparators.collectAsState()
val checkForUpdates by context.symphony.settings.checkForUpdates.collectAsState()
val showUpdateToast by context.symphony.settings.showUpdateToast.collectAsState()
val fontScale by context.symphony.settings.fontScale.collectAsState()
Expand Down Expand Up @@ -699,6 +703,32 @@ fun SettingsView(context: ViewContext) {
refetchLibrary()
}
)
SettingsMultiTextOptionTile(
context,
icon = {
Icon(Icons.Filled.SpaceBar, null)
},
title = {
Text(context.symphony.t.ArtistTagValueSeparators)
},
values = artistTagSeparators.toList(),
onChange = {
context.symphony.settings.setArtistTagSeparators(it)
},
)
SettingsMultiTextOptionTile(
context,
icon = {
Icon(Icons.Filled.SpaceBar, null)
},
title = {
Text(context.symphony.t.GenreTagValueSeparators)
},
values = genreTagSeparators.toList(),
onChange = {
context.symphony.settings.setGenreTagSeparators(it)
},
)
SettingsSimpleTile(
icon = {
Icon(Icons.Filled.Storage, null)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
package io.github.zyrouge.symphony.ui.view.settings

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Card
import androidx.compose.material3.DividerDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import io.github.zyrouge.symphony.ui.components.ScaffoldDialog
import io.github.zyrouge.symphony.ui.helpers.ViewContext

@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@Composable
fun SettingsMultiTextOptionTile(
context: ViewContext,
icon: @Composable () -> Unit,
title: @Composable () -> Unit,
values: List<String>,
allowDuplicates: Boolean = false,
onReset: (() -> Unit)? = null,
onChange: (List<String>) -> Unit,
) {
var isOpen by remember { mutableStateOf(false) }

Card(
colors = SettingsTileDefaults.cardColors(),
onClick = { isOpen = !isOpen }
) {
ListItem(
colors = SettingsTileDefaults.listItemColors(),
leadingContent = { icon() },
headlineContent = { title() },
supportingContent = {
Text(context.symphony.t.XItems(values.size.toString()))
},
)
}

if (isOpen) {
var showAddDialog by remember { mutableStateOf(false) }
val nValues = remember {
mutableStateListOf(*values.toTypedArray())
}
val modified by remember(values, nValues) {
derivedStateOf { values != nValues }
}

when {
!showAddDialog -> ScaffoldDialog(
onDismissRequest = {
if (!modified) {
isOpen = false
}
},
title = title,
content = {
Box(modifier = Modifier.padding(start = 20.dp, end = 20.dp, top = 16.dp)) {
FlowRow(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(
8.dp,
Alignment.CenterHorizontally,
),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
nValues.forEachIndexed { i, x ->
Row(
modifier = Modifier
.border(
1.dp,
MaterialTheme.colorScheme.outline,
RoundedCornerShape(8.dp),
)
.padding(4.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Spacer(modifier = Modifier.width(8.dp))
Text(
x,
color = MaterialTheme.colorScheme.primary,
style = LocalTextStyle.current.copy(
fontWeight = FontWeight.Bold,
),
)
Spacer(modifier = Modifier.width(4.dp))
IconButton(
modifier = Modifier.size(24.dp),
onClick = {
nValues.removeAt(i)
}
) {
Icon(
Icons.Filled.Close,
null,
modifier = Modifier.size(12.dp),
)
}
}
}
}
}
},
actions = {
TextButton(
onClick = {
showAddDialog = true
}
) {
Text(context.symphony.t.AddItem)
}
Spacer(modifier = Modifier.weight(1f))
onReset?.let {
TextButton(
onClick = {
it()
isOpen = false
}
) {
Text(context.symphony.t.Reset)
}
}
TextButton(
onClick = {
isOpen = false
}
) {
Text(context.symphony.t.Cancel)
}
TextButton(
enabled = modified,
onClick = {
onChange(nValues)
isOpen = false
}
) {
Text(context.symphony.t.Done)
}
},
)

else -> {
var input by remember { mutableStateOf("") }

ScaffoldDialog(
onDismissRequest = {
showAddDialog = false
},
title = title,
content = {
Box(
modifier = Modifier
.padding(start = 20.dp, end = 20.dp, top = 16.dp)
) {
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
singleLine = true,
colors = TextFieldDefaults.colors(
focusedContainerColor = Color.Transparent,
unfocusedContainerColor = Color.Transparent,
unfocusedIndicatorColor = DividerDefaults.color,
),
value = input,
onValueChange = {
input = it
}
)
}
},
actions = {
TextButton(
onClick = {
showAddDialog = false
}
) {
Text(context.symphony.t.Cancel)
}
TextButton(
enabled = input.isNotEmpty(),
onClick = {
if (
input.isNotEmpty() &&
(allowDuplicates || !nValues.contains(input))
) {
nValues.add(input)
}
showAddDialog = false
}
) {
Text(context.symphony.t.Done)
}
},
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@ import kotlin.math.min
class FuzzySearchComparator(val input: String) {
fun compareString(value: String) = Fuzzy.compare(input, value)

fun compareIterable(values: Iterable<String>): Float {
fun compareCollection(values: Collection<String>): Float {
var weight = 0f
var size = 0
values.forEach {
weight += compareString(it)
size++
}
return weight / min(1, size)
return weight / min(1, values.size)
}
}

Expand Down
3 changes: 3 additions & 0 deletions i18n/en.toml
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,6 @@ SeparatePage = "Separate page"
UnknownAlbumX = "Unknown album ({x})"
CopiedXToClipboard = "Copied '{x}' to clipboard"
MiniPlayerTextMarquee = "Mini-player text marquee"
AddItem = "Add item"
ArtistTagValueSeparators = "Artist tag value separators"
GenreTagValueSeparators = "Genre tag value separators"

0 comments on commit 2e8c1e3

Please sign in to comment.