Răsfoiți Sursa

Added rename server button

Vadik Sirekanyan 2 ani în urmă
părinte
comite
a9c104089a

+ 4 - 2
app/src/main/java/org/sirekanyan/outline/MainActivity.kt

@@ -13,7 +13,8 @@ import kotlinx.coroutines.launch
 import org.sirekanyan.outline.ui.AddServerContent
 import org.sirekanyan.outline.ui.DeleteKeyContent
 import org.sirekanyan.outline.ui.DeleteServerContent
-import org.sirekanyan.outline.ui.EditKeyContent
+import org.sirekanyan.outline.ui.RenameKeyContent
+import org.sirekanyan.outline.ui.RenameServerContent
 import org.sirekanyan.outline.ui.theme.OutlineTheme
 
 class MainActivity : ComponentActivity() {
@@ -34,7 +35,8 @@ class MainActivity : ComponentActivity() {
                         }
                         when (dialog) {
                             is AddServerDialog -> Surface { AddServerContent(state) }
-                            is EditKeyDialog -> Surface { EditKeyContent(state, dialog) }
+                            is RenameServerDialog -> Surface { RenameServerContent(state, dialog) }
+                            is RenameKeyDialog -> Surface { RenameKeyContent(state, dialog) }
                             is DeleteKeyDialog -> {
                                 val (server, key) = dialog
                                 DeleteKeyContent(

+ 5 - 1
app/src/main/java/org/sirekanyan/outline/MainContent.kt

@@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.systemBars
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Add
 import androidx.compose.material.icons.filled.Delete
+import androidx.compose.material.icons.filled.Edit
 import androidx.compose.material3.CircularProgressIndicator
 import androidx.compose.material3.Icon
 import androidx.compose.material3.LinearProgressIndicator
@@ -123,6 +124,9 @@ fun MainContent(state: MainState) {
                         MenuItem("Sort by…", IconSort) {
                             isSortingVisible = true
                         },
+                        MenuItem("Edit", Icons.Default.Edit) {
+                            state.dialog = RenameServerDialog(page.server, server.name)
+                        },
                         MenuItem("Delete", Icons.Default.Delete) {
                             state.dialog = DeleteServerDialog(page.server, server.name)
                         },
@@ -150,7 +154,7 @@ fun MainContent(state: MainState) {
                 KeyBottomSheet(
                     key = key,
                     onDismissRequest = { state.selectedKey = null },
-                    onEditClick = { state.dialog = EditKeyDialog(page.server, key) },
+                    onEditClick = { state.dialog = RenameKeyDialog(page.server, key) },
                     onDeleteClick = { state.dialog = DeleteKeyDialog(page.server, key) },
                 )
             }

+ 3 - 1
app/src/main/java/org/sirekanyan/outline/MainState.kt

@@ -137,7 +137,9 @@ sealed class Dialog
 
 data object AddServerDialog : Dialog()
 
-data class EditKeyDialog(val server: ServerEntity, val key: Key) : Dialog()
+data class RenameServerDialog(val server: ServerEntity, val serverName: String) : Dialog()
+
+data class RenameKeyDialog(val server: ServerEntity, val key: Key) : Dialog()
 
 data class DeleteKeyDialog(val server: ServerEntity, val key: Key) : Dialog()
 

+ 7 - 0
app/src/main/java/org/sirekanyan/outline/api/OutlineApi.kt

@@ -68,6 +68,13 @@ class OutlineApi {
         return Server(name, transferMetrics?.values?.sum())
     }
 
+    suspend fun renameServer(server: ServerEntity, name: String) {
+        request(HttpMethod.Put, server, "name") {
+            contentType(ContentType.Application.Json)
+            setBody(RenameRequest(name))
+        }
+    }
+
     suspend fun getKeys(server: ServerEntity): List<Key> {
         val accessKeys = getAccessKeys(server).accessKeys
         val transferMetrics = getTransferMetrics(server)?.bytesTransferredByUserId

+ 6 - 0
app/src/main/java/org/sirekanyan/outline/api/model/Server.kt

@@ -1,3 +1,9 @@
 package org.sirekanyan.outline.api.model
 
+import android.net.Uri
+import org.sirekanyan.outline.db.model.ServerEntity
+
+fun ServerEntity.getHost(): String =
+    Uri.parse(id).host.orEmpty()
+
 class Server(val name: String, val traffic: Long?)

+ 6 - 2
app/src/main/java/org/sirekanyan/outline/repository/ServerRepository.kt

@@ -1,12 +1,12 @@
 package org.sirekanyan.outline.repository
 
-import android.net.Uri
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.map
 import org.sirekanyan.outline.api.OutlineApi
 import org.sirekanyan.outline.api.model.Key
 import org.sirekanyan.outline.api.model.Server
 import org.sirekanyan.outline.api.model.fromEntities
+import org.sirekanyan.outline.api.model.getHost
 import org.sirekanyan.outline.api.model.toEntities
 import org.sirekanyan.outline.db.KeyDao
 import org.sirekanyan.outline.db.model.KeyEntity
@@ -19,7 +19,7 @@ class ServerRepository(private val api: OutlineApi, private val keyDao: KeyDao)
     private val cache: MutableMap<String, Server> = ConcurrentHashMap()
 
     fun getCachedServer(server: ServerEntity): Server =
-        cache[server.id] ?: Server(Uri.parse(server.id).host.orEmpty(), traffic = null)
+        cache[server.id] ?: Server(server.getHost(), traffic = null)
 
     suspend fun fetchServer(server: ServerEntity): Server =
         api.getServer(server).also { fetched ->
@@ -45,4 +45,8 @@ class ServerRepository(private val api: OutlineApi, private val keyDao: KeyDao)
         keyDao.update(server, keys.toEntities(server))
     }
 
+    fun clearCache() {
+        cache.clear()
+    }
+
 }

+ 12 - 8
app/src/main/java/org/sirekanyan/outline/ui/EditKeyContent.kt → app/src/main/java/org/sirekanyan/outline/ui/RenameContent.kt

@@ -18,27 +18,31 @@ import androidx.compose.ui.text.TextRange
 import androidx.compose.ui.text.input.TextFieldValue
 import androidx.compose.ui.unit.dp
 import kotlinx.coroutines.launch
-import org.sirekanyan.outline.EditKeyDialog
 import org.sirekanyan.outline.MainState
 
 @Composable
-fun EditKeyContent(state: MainState, dialog: EditKeyDialog) {
-    val accessKey = dialog.key.accessKey
+fun RenameContent(
+    state: MainState,
+    dialogTitle: String,
+    initialName: String,
+    defaultName: String,
+    onSaveClicked: suspend (String) -> Unit,
+) {
     var draft by remember {
-        mutableStateOf(TextFieldValue(accessKey.nameOrDefault, TextRange(Int.MAX_VALUE)))
+        mutableStateOf(TextFieldValue(initialName, TextRange(Int.MAX_VALUE)))
     }
     var error by remember(draft) { mutableStateOf("") }
     var isLoading by remember { mutableStateOf(false) }
     Column {
         DialogToolbar(
-            title = "Edit key",
+            title = dialogTitle,
             onCloseClick = { state.dialog = null },
             action = "Save" to {
                 state.scope.launch {
                     val isSuccess = try {
                         isLoading = true
-                        val newName = draft.text.ifBlank { accessKey.defaultName }
-                        state.api.renameAccessKey(dialog.server, accessKey.id, newName)
+                        val newName = draft.text.ifBlank { defaultName }
+                        onSaveClicked(newName)
                         state.dialog = null
                         true
                     } catch (exception: Exception) {
@@ -64,7 +68,7 @@ fun EditKeyContent(state: MainState, dialog: EditKeyDialog) {
                 .padding(horizontal = 16.dp, vertical = 24.dp)
                 .focusRequester(focusRequester),
             label = { Text("Name") },
-            placeholder = { Text(accessKey.defaultName) },
+            placeholder = { Text(defaultName) },
             isError = error.isNotEmpty(),
             supportingText = { Text(error) },
             maxLines = 4,

+ 13 - 0
app/src/main/java/org/sirekanyan/outline/ui/RenameKeyContent.kt

@@ -0,0 +1,13 @@
+package org.sirekanyan.outline.ui
+
+import androidx.compose.runtime.Composable
+import org.sirekanyan.outline.MainState
+import org.sirekanyan.outline.RenameKeyDialog
+
+@Composable
+fun RenameKeyContent(state: MainState, dialog: RenameKeyDialog) {
+    val accessKey = dialog.key.accessKey
+    RenameContent(state, "Edit key", accessKey.name, accessKey.defaultName) { newName ->
+        state.api.renameAccessKey(dialog.server, accessKey.id, newName)
+    }
+}

+ 14 - 0
app/src/main/java/org/sirekanyan/outline/ui/RenameServerContent.kt

@@ -0,0 +1,14 @@
+package org.sirekanyan.outline.ui
+
+import androidx.compose.runtime.Composable
+import org.sirekanyan.outline.MainState
+import org.sirekanyan.outline.RenameServerDialog
+import org.sirekanyan.outline.api.model.getHost
+
+@Composable
+fun RenameServerContent(state: MainState, dialog: RenameServerDialog) {
+    RenameContent(state, "Edit server", dialog.serverName, dialog.server.getHost()) { newName ->
+        state.api.renameServer(dialog.server, newName)
+        state.servers.clearCache()
+    }
+}