Skip to content

Commit

Permalink
Changed the server color selection to be vertical [#35]
Browse files Browse the repository at this point in the history
  • Loading branch information
mcpierce committed Dec 10, 2023
1 parent 05b25fd commit 7674fb4
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 130 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

package org.comixedproject.variant.ui.server

import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand All @@ -27,27 +27,25 @@ import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Scaffold
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Visibility
import androidx.compose.material.icons.filled.VisibilityOff
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
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.res.stringResource
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.tooling.preview.Preview
Expand All @@ -56,6 +54,7 @@ import org.comixedproject.variant.R
import org.comixedproject.variant.VariantTheme
import org.comixedproject.variant.data.IdGenerator
import org.comixedproject.variant.model.Server
import org.comixedproject.variant.model.ServerColorChoice

/**
* Allows the user to edit an OPDS server.
Expand All @@ -68,95 +67,108 @@ fun EditServer(
onSave: (String, String, String, String, String) -> Unit,
onCancel: () -> Unit
) {
Surface(
border = BorderStroke(width = 1.dp, color = Color.Black),
shape = RoundedCornerShape(8.dp),
shadowElevation = 8.dp,
modifier = Modifier.fillMaxWidth()
) {
Column(
modifier = Modifier
.fillMaxHeight()
.padding(16.dp, 16.dp)
.verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
var name by remember { mutableStateOf(entry.name) }
var url by remember { mutableStateOf(entry.url) }
var username by remember { mutableStateOf(entry.username) }
var password by remember { mutableStateOf(entry.password) }
var serverColor by remember { mutableStateOf(entry.serverColor) }
var passwordVisible by remember { mutableStateOf(false) }
var isValid by remember { mutableStateOf(false) }
var name by remember { mutableStateOf(entry.name) }
var url by remember { mutableStateOf(entry.url) }
var username by remember { mutableStateOf(entry.username) }
var password by remember { mutableStateOf(entry.password) }
var serverColor by remember { mutableStateOf(entry.serverColor) }
var passwordVisible by remember { mutableStateOf(false) }
var isValid by remember { mutableStateOf(false) }

OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = name,
onValueChange = { input ->
name = input
isValid = checkValidity(name, url, username, password)
},
label = { Text(stringResource(R.string.server_name_label)) })
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = url,
onValueChange = { input ->
url = input
isValid = checkValidity(name, url, username, password)
},
label = { Text(stringResource(R.string.server_url_label)) })
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = username,
onValueChange = { input ->
username = input
isValid = checkValidity(name, url, username, password)
},
label = { Text(stringResource(R.string.username_label)) })
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = password,
onValueChange = { input ->
password = input
isValid = checkValidity(name, url, username, password)
},
label = {
Text(stringResource(R.string.password_label))
},
visualTransformation =
if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
trailingIcon = {
val image = if (passwordVisible) Icons.Filled.Visibility
else Icons.Filled.VisibilityOff
Scaffold(
content = { padding ->
Column(
modifier = Modifier
.fillMaxHeight()
.padding(padding),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = name,
onValueChange = { input ->
name = input
isValid = checkValidity(name, url, username, password)
},
label = { Text(stringResource(R.string.server_name_label)) })
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = url,
onValueChange = { input ->
url = input
isValid = checkValidity(name, url, username, password)
},
label = { Text(stringResource(R.string.server_url_label)) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Uri)
)
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = username,
onValueChange = { input ->
username = input
isValid = checkValidity(name, url, username, password)
},
label = { Text(stringResource(R.string.username_label)) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email)
)
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = password,
onValueChange = { input ->
password = input
isValid = checkValidity(name, url, username, password)
},
label = {
Text(stringResource(R.string.password_label))
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
visualTransformation =
if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
trailingIcon = {
val image = if (passwordVisible) Icons.Filled.Visibility
else Icons.Filled.VisibilityOff

IconButton(onClick = { passwordVisible = !passwordVisible }) {
Icon(imageVector = image, "")
}
})
ServerColorPicker(
currentColor = serverColor,
onColorPicked = { input ->
serverColor = input.hex
})
Spacer(
modifier = Modifier.weight(1.0f)
)
IconButton(onClick = { passwordVisible = !passwordVisible }) {
Icon(imageVector = image, "")
}
})
ServerColorList(
currentColor = serverColor,
onColorPicked = { serverColor = it.hex })
ServerColorChoice.COLORS.forEach { color ->
ServerColorListEntry(
color = color,
currentColor = entry.serverColor,
onColorPicked = { selected ->
serverColor = selected.hex
})
}
}
},
bottomBar = {
Row(
modifier = Modifier
.align(Alignment.End)
.fillMaxWidth()
.background(MaterialTheme.colors.primary)
) {
Button(onClick = onCancel) {
Spacer(modifier = Modifier.weight(1.0f))
Button(
modifier = Modifier.background(MaterialTheme.colors.primaryVariant),
onClick = onCancel
) {
Text(text = stringResource(id = R.string.cancel_button))
}
Spacer(modifier = Modifier.size(8.dp))
Button(onClick = {
onSave(name, url, username, password, serverColor)
}) {
Button(
modifier = Modifier.background(MaterialTheme.colors.primaryVariant),
onClick = {
onSave(name, url, username, password, serverColor)
}) {
Text(text = stringResource(id = R.string.save_button))
}
Spacer(modifier = Modifier.size(8.dp))
}
}
}
})
}

fun checkValidity(name: String, url: String, username: String, password: String): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
package org.comixedproject.variant.ui.server

import androidx.compose.ui.graphics.Color
import org.comixedproject.variant.model.ServerColorOption
import org.comixedproject.variant.model.ServerColorChoice

/**
* Converts a hex string to a color.
*/
fun ServerColorOption.Companion.fromHex(hex: String): Color {
fun ServerColorChoice.Companion.fromHex(hex: String): Color {
return Color(android.graphics.Color.parseColor(hex))
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,26 @@
package org.comixedproject.variant.ui.server

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import org.comixedproject.variant.VariantTheme
import org.comixedproject.variant.model.ServerColorOption
import org.comixedproject.variant.model.ServerColorChoice

@Composable
fun ServerColorPicker(
fun ServerColorList(
modifier: Modifier = Modifier,
currentColor: String,
onColorPicked: (ServerColorOption) -> Unit
onColorPicked: (ServerColorChoice) -> Unit
) {
LazyRow(
LazyColumn(
modifier = Modifier
.fillMaxWidth()
) {
items(ServerColorOption.COLORS.size) { itemIndex ->
val color = ServerColorOption.COLORS[itemIndex]
ServerColorOption(
items(ServerColorChoice.COLORS.size) { itemIndex ->
val color = ServerColorChoice.COLORS[itemIndex]
ServerColorListEntry(
color = color,
currentColor = currentColor,
onColorPicked = onColorPicked
Expand All @@ -49,8 +49,8 @@ fun ServerColorPicker(

@Preview
@Composable
fun ServerColorPickerPreview() {
fun ServerColorListPreview() {
VariantTheme {
ServerColorPicker(currentColor = ServerColorOption.COLORS[0].hex, onColorPicked = {})
ServerColorList(currentColor = ServerColorChoice.COLORS[0].hex, onColorPicked = {})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.comixedproject.variant.model.ServerColorOption
import org.comixedproject.variant.model.ServerColorChoice

/**
* Presents a color to the user for selection.
*
* @author Darryl L. Pierce
*/
@Composable
fun ServerColorOption(
color: ServerColorOption,
fun ServerColorListEntry(
modifier: Modifier = Modifier,
color: ServerColorChoice,
currentColor: String,
onColorPicked: (ServerColorOption) -> Unit
onColorPicked: (ServerColorChoice) -> Unit
) {
Row(
modifier = Modifier
Expand All @@ -31,8 +37,8 @@ fun ServerColorOption(
) {
val fontWeight = if (currentColor == color.hex) FontWeight.Bold else FontWeight.Normal
ServerColor(
modifier = Modifier.padding(10.dp),
color = ServerColorOption.fromHex(color.hex),
modifier = modifier.padding(10.dp),
color = ServerColorChoice.fromHex(color.hex),
size = 40.dp,
border = 2.dp
)
Expand All @@ -50,18 +56,18 @@ fun ServerColorOption(

@Preview
@Composable
fun ServerColorItemPreview() {
ServerColorOption(
color = ServerColorOption.COLORS[0],
ServerColorOption.COLORS[1].hex,
fun ServerColorListEntryPreview() {
ServerColorListEntry(
color = ServerColorChoice.COLORS[0],
currentColor = ServerColorChoice.COLORS[1].hex,
onColorPicked = {})
}

@Preview
@Composable
fun ServerColorItemCurrentPreview() {
ServerColorOption(
color = ServerColorOption.COLORS[0],
ServerColorOption.COLORS[0].hex,
fun ServerColorListEntryCurrentPreview() {
ServerColorListEntry(
color = ServerColorChoice.COLORS[0],
currentColor = ServerColorChoice.COLORS[0].hex,
onColorPicked = {})
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
import org.comixedproject.variant.data.IdGenerator
import org.comixedproject.variant.model.Server
import org.comixedproject.variant.model.ServerColorOption
import org.comixedproject.variant.model.ServerColorChoice

/**
* Displays a single server in the list of servers.
Expand Down Expand Up @@ -80,7 +80,7 @@ fun ServerListEntry(entry: Server, onClick: (Server) -> Unit) {
modifier = Modifier
.align(Alignment.CenterVertically)
.padding(8.dp),
color = ServerColorOption.fromHex(entry.serverColor),
color = ServerColorChoice.fromHex(entry.serverColor),
size = 40.dp,
border = 1.dp
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ data class Server(
val url: String,
val username: String,
val password: String,
val serverColor: String = ServerColorOption.DEFAULT.hex
val serverColor: String = ServerColorChoice.DEFAULT.hex
) {
private var _lastAccessedOn: LocalDateTime? = null
var lastAccessedOn: LocalDateTime?
Expand Down
Loading

0 comments on commit 7674fb4

Please sign in to comment.