Skip to content

Commit

Permalink
Added adding and removing OPDS entries [#5]
Browse files Browse the repository at this point in the history
  • Loading branch information
mcpierce committed Nov 24, 2023
1 parent b29e539 commit 4e97494
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,20 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import kotlinx.datetime.Clock
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
import org.comixedproject.variant.EmptyComposable
import org.comixedproject.variant.R
import org.comixedproject.variant.VariantTheme
import org.comixedproject.variant.model.OPDSServerEntry
import org.comixedproject.variant.model.opdsServerEntryTemplate
import org.comixedproject.variant.topBarFun
import org.comixedproject.variant.ui.server.EditServerDialog
import org.comixedproject.variant.ui.server.OPDSServerListScreen

@Composable
fun MainView(actionBarFun: topBarFun = { EmptyComposable() }) {
Expand Down Expand Up @@ -76,7 +81,10 @@ fun MainView(actionBarFun: topBarFun = { EmptyComposable() }) {
containerColor = MaterialTheme.colorScheme.secondary,
onClick = { showAddDialog.value = true }
) {
Icon(imageVector = Icons.Default.Add, contentDescription = "Add Server")
Icon(
imageVector = Icons.Default.Add,
contentDescription = stringResource(R.string.add_server_label)
)
}
}
},
Expand Down Expand Up @@ -110,6 +118,20 @@ fun MainView(actionBarFun: topBarFun = { EmptyComposable() }) {
}
) { padding ->
Box(Modifier.padding(padding)) {
if (showAddDialog.value) {
EditServerDialog(
opdsServerEntryTemplate,
onAdd = { entry ->
showAddDialog.value = false
if (!opdsServerList.contains(entry)) {
opdsServerList.add(entry)
}
},
onDismiss = {
showAddDialog.value = false
},
)
}
when (selectedIndex.intValue) {
0 -> OPDSServerListScreen(opdsServerList)
else -> throw Exception("No valid screen to display: selectedIndex={selectedIndex.intValue}")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* Variant - A digital comic book reading application for iPad, Android, and desktops.
* Copyright (C) 2023, The ComiXed Project
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses>
*/

package org.comixedproject.variant.ui.server

import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
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.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.OutlinedTextField
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.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import org.comixedproject.variant.R
import org.comixedproject.variant.VariantTheme
import org.comixedproject.variant.model.OPDSServerEntry

/**
* <code>EditServerDialog</code> manages a dialog for editing an OPDS server.
*
* @author Darryl L. Pierce
*/
@Composable
fun EditServerDialog(
entry: OPDSServerEntry,
onAdd: (OPDSServerEntry) -> Unit,
onDismiss: () -> Unit
) = Dialog(onDismissRequest = onDismiss) {
Surface(
border = BorderStroke(width = 1.dp, color = Color.Black),
shape = RoundedCornerShape(8.dp),
shadowElevation = 8.dp,
modifier = Modifier.fillMaxWidth()
) {
Column(
modifier = Modifier
.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 passwordVisible by remember { mutableStateOf(false) }
var isValid by remember { mutableStateOf(false) }

OutlinedTextField(
value = name,
onValueChange = { input -> name = input },
label = { Text(stringResource(R.string.server_name_label)) })
OutlinedTextField(
value = url,
onValueChange = { input -> url = input },
label = { Text(stringResource(R.string.server_url_label)) })
OutlinedTextField(
value = username,
onValueChange = { input -> username = input },
label = { Text(stringResource(R.string.username_label)) })
OutlinedTextField(
value = password,
onValueChange = { input -> password = input },
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

IconButton(onClick = { passwordVisible = !passwordVisible }) {
Icon(imageVector = image, "")
}
})
Spacer(modifier = Modifier.size(16.dp))
Row(modifier = Modifier.align(Alignment.End)) {
Button(onClick = {
onDismiss()
}) {
Text(text = stringResource(id = R.string.cancel_button))
}
Spacer(modifier = Modifier.size(16.dp))
Button(onClick = {
onAdd(OPDSServerEntry(name, url, username, password, entry.lastAccessedOn))
}) {
Text(text = stringResource(id = R.string.save_button))
}
}
}
}
}


@Preview
@Composable
fun EditServerDialogAndroidPreview() {
VariantTheme {
EditServerDialog(OPDSServerEntry(
"Server Name",
"http://www.comixedproject.org:7171/opds",
"[email protected]",
"password"
),
onAdd = {}, onDismiss = {})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses>
*/

package org.comixedproject.variant.ui
package org.comixedproject.variant.ui.server

import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses>
*/

package org.comixedproject.variant.ui
package org.comixedproject.variant.ui.server

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
Expand All @@ -42,6 +42,7 @@ import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
import org.comixedproject.variant.R
import org.comixedproject.variant.model.OPDSServerEntry
import org.comixedproject.variant.ui.AnimatedSwipeDismiss

@Composable
fun OPDSServerListScreen(opdsServerList: SnapshotStateList<OPDSServerEntry>) {
Expand Down Expand Up @@ -103,17 +104,15 @@ fun OPDSServerListScreenAndroidPreview() {
"Preview Server 2",
"http://www.comixedproject.org:7171/opds",
"comixedreader@localhost",
"comixedreader",
Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
"comixedreader"
)
)
list.add(
OPDSServerEntry(
"Preview Server 3",
"http://www.comixedproject.org:7171/opds",
"comixedreader@localhost",
"comixedreader",
Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
"comixedreader"
)
)
OPDSServerListScreen(list)
Expand Down
3 changes: 1 addition & 2 deletions composeApp/src/commonMain/kotlin/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@
*/

import androidx.compose.runtime.Composable
import org.comixedproject.variant.ui.MainView
import org.jetbrains.compose.resources.ExperimentalResourceApi

@OptIn(ExperimentalResourceApi::class)
@Composable
fun App() {
MainView()
// MainView()
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ data class OPDSServerEntry(
val url: String,
val username: String,
val password: String,
val lastAccessedOn: LocalDateTime
val lastAccessedOn: LocalDateTime? = null
) {
}
}

val opdsServerEntryTemplate = OPDSServerEntry("", "", "", "");
Original file line number Diff line number Diff line change
Expand Up @@ -44,64 +44,55 @@ class OPDSServerRepository {
"Second Entry",
"http://localhost:7171/opds",
"comixedreader@localhost",
"comixedreader",
Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
"comixedreader"
),
OPDSServerEntry(
"Third Entry",
"http://localhost:7171/opds",
"comixedreader@localhost",
"comixedreader",
Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
"comixedreader"
),
OPDSServerEntry(
"Fourth Entry",
"http://localhost:7171/opds",
"comixedreader@localhost",
"comixedreader",
Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
"comixedreader"
),
OPDSServerEntry(
"Fifth Entry",
"http://localhost:7171/opds",
"comixedreader@localhost",
"comixedreader",
Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
"comixedreader"
),
OPDSServerEntry(
"Sixth Entry",
"http://localhost:7171/opds",
"comixedreader@localhost",
"comixedreader",
Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
"comixedreader"
),
OPDSServerEntry(
"Seventh Entry",
"http://localhost:7171/opds",
"comixedreader@localhost",
"comixedreader",
Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
"comixedreader"
),
OPDSServerEntry(
"Eighth Entry",
"http://localhost:7171/opds",
"comixedreader@localhost",
"comixedreader",
Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
"comixedreader"
),
OPDSServerEntry(
"Ninth Entry",
"http://localhost:7171/opds",
"comixedreader@localhost",
"comixedreader",
Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
"comixedreader"
),
OPDSServerEntry(
"Tenth Entry",
"http://localhost:7171/opds",
"comixedreader@localhost",
"comixedreader",
Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
"comixedreader"
)
);
}
Expand Down
7 changes: 7 additions & 0 deletions composeApp/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,11 @@
<resources>
<string name="server_list">Servers</string>
<string name="delete_label">Delete</string>
<string name="add_server_label">Add Server</string>
<string name="server_name_label">Server Name</string>
<string name="server_url_label">Address</string>
<string name="username_label">Username</string>
<string name="password_label">Password</string>
<string name="cancel_button">Cancel</string>
<string name="save_button">Save</string>
</resources>

0 comments on commit 4e97494

Please sign in to comment.