Przeglądaj źródła

Added separate router class (refactoring)

Vadik Sirekanyan 2 lat temu
rodzic
commit
0d665c1fad

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

@@ -21,7 +21,8 @@ class MainActivity : ComponentActivity() {
         super.onCreate(savedInstanceState)
         super.onCreate(savedInstanceState)
         WindowCompat.setDecorFitsSystemWindows(window, false)
         WindowCompat.setDecorFitsSystemWindows(window, false)
         setContent {
         setContent {
-            val state = rememberMainState()
+            val router = rememberRouter()
+            val state = rememberMainState(router)
             OutlineTheme {
             OutlineTheme {
                 Surface(Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
                 Surface(Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
                     BackHandler(state.drawer.isOpen) {
                     BackHandler(state.drawer.isOpen) {
@@ -33,7 +34,7 @@ class MainActivity : ComponentActivity() {
                             state.dialog = null
                             state.dialog = null
                         }
                         }
                         when (dialog) {
                         when (dialog) {
-                            is AddServerDialog -> Surface { AddServerContent(state) }
+                            is AddServerDialog -> Surface { AddServerContent(state, router) }
                             is RenameServerDialog -> Surface { RenameServerContent(state, dialog) }
                             is RenameServerDialog -> Surface { RenameServerContent(state, dialog) }
                             is RenameKeyDialog -> Surface { RenameKeyContent(state, dialog) }
                             is RenameKeyDialog -> Surface { RenameKeyContent(state, dialog) }
                             is DeleteKeyDialog -> {
                             is DeleteKeyDialog -> {

+ 8 - 23
app/src/main/java/org/sirekanyan/outline/MainState.kt

@@ -1,15 +1,11 @@
 package org.sirekanyan.outline
 package org.sirekanyan.outline
 
 
 import android.os.Parcelable
 import android.os.Parcelable
-import androidx.compose.material3.DrawerState
-import androidx.compose.material3.DrawerValue
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.LocalContext
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.CoroutineScope
@@ -34,16 +30,14 @@ import org.sirekanyan.outline.ui.SearchState
 import org.sirekanyan.outline.ui.rememberSearchState
 import org.sirekanyan.outline.ui.rememberSearchState
 
 
 @Composable
 @Composable
-fun rememberMainState(): MainState {
+fun rememberMainState(router: Router): MainState {
     val context = LocalContext.current
     val context = LocalContext.current
     val scope = rememberStateScope()
     val scope = rememberStateScope()
     val search = rememberSearchState()
     val search = rememberSearchState()
-    val page = rememberSaveable { mutableStateOf<Page>(HelloPage) }
-    val dialog = rememberSaveable { mutableStateOf<Dialog?>(null) }
     val prefs = remember { context.app().prefsDao }
     val prefs = remember { context.app().prefsDao }
     val servers = remember { context.app().serverRepository }
     val servers = remember { context.app().serverRepository }
     val keys = remember { context.app().keyRepository }
     val keys = remember { context.app().keyRepository }
-    return remember { MainState(scope, servers, keys, search, page, dialog, prefs) }
+    return remember { MainState(scope, servers, keys, search, router, prefs) }
 }
 }
 
 
 class MainState(
 class MainState(
@@ -51,15 +45,14 @@ class MainState(
     val servers: ServerRepository,
     val servers: ServerRepository,
     val keys: KeyRepository,
     val keys: KeyRepository,
     val search: SearchState,
     val search: SearchState,
-    pageState: MutableState<Page>,
-    dialogState: MutableState<Dialog?>,
+    private val router: Router,
     private val prefs: KeyValueDao,
     private val prefs: KeyValueDao,
 ) {
 ) {
 
 
-    val drawer = DrawerState(DrawerValue.Closed)
+    val drawer = router.drawer
     val drawerDisabled by derivedStateOf { search.isOpened && drawer.isClosed }
     val drawerDisabled by derivedStateOf { search.isOpened && drawer.isClosed }
-    var page by pageState
-    var dialog by dialogState
+    var page by router.pageState
+    var dialog by router.dialogState
     val selectedPage by derivedStateOf { page as? SelectedPage }
     val selectedPage by derivedStateOf { page as? SelectedPage }
     var selectedKey by mutableStateOf<Key?>(null)
     var selectedKey by mutableStateOf<Key?>(null)
     val isFabVisible by derivedStateOf { (page as? SelectedPage)?.keys is KeysIdleState }
     val isFabVisible by derivedStateOf { (page as? SelectedPage)?.keys is KeysIdleState }
@@ -74,19 +67,11 @@ class MainState(
     }
     }
 
 
     fun openDrawer() {
     fun openDrawer() {
-        scope.launch {
-            drawer.open()
-        }
+        router.openDrawer()
     }
     }
 
 
     fun closeDrawer(animated: Boolean = true) {
     fun closeDrawer(animated: Boolean = true) {
-        scope.launch {
-            if (animated) {
-                drawer.close()
-            } else {
-                drawer.snapTo(DrawerValue.Closed)
-            }
-        }
+        router.closeDrawer(animated)
     }
     }
 
 
     suspend fun refreshCurrentKeys(showLoading: Boolean) {
     suspend fun refreshCurrentKeys(showLoading: Boolean) {

+ 50 - 0
app/src/main/java/org/sirekanyan/outline/Router.kt

@@ -0,0 +1,50 @@
+package org.sirekanyan.outline
+
+import androidx.compose.material3.DrawerState
+import androidx.compose.material3.DrawerValue
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import org.sirekanyan.outline.ext.rememberStateScope
+
+@Composable
+fun rememberRouter(): Router {
+    val scope = rememberStateScope()
+    val page = rememberSaveable { mutableStateOf<Page>(HelloPage) }
+    val dialog = rememberSaveable { mutableStateOf<Dialog?>(null) }
+    return remember { Router(scope, page, dialog) }
+}
+
+class Router(
+    private val scope: CoroutineScope,
+    val pageState: MutableState<Page>,
+    val dialogState: MutableState<Dialog?>,
+) {
+
+    val drawer = DrawerState(DrawerValue.Closed)
+    var page by pageState
+    var dialog by dialogState
+
+    fun openDrawer() {
+        scope.launch {
+            drawer.open()
+        }
+    }
+
+    fun closeDrawer(animated: Boolean = true) {
+        scope.launch {
+            if (animated) {
+                drawer.close()
+            } else {
+                drawer.snapTo(DrawerValue.Closed)
+            }
+        }
+    }
+
+}

+ 6 - 5
app/src/main/java/org/sirekanyan/outline/ui/AddServerContent.kt

@@ -27,12 +27,13 @@ import androidx.compose.ui.unit.dp
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.launch
 import org.sirekanyan.outline.MainState
 import org.sirekanyan.outline.MainState
 import org.sirekanyan.outline.NotSupportedContent
 import org.sirekanyan.outline.NotSupportedContent
+import org.sirekanyan.outline.Router
 import org.sirekanyan.outline.SelectedPage
 import org.sirekanyan.outline.SelectedPage
 import org.sirekanyan.outline.api.model.createServerEntity
 import org.sirekanyan.outline.api.model.createServerEntity
 import javax.net.ssl.SSLException
 import javax.net.ssl.SSLException
 
 
 @Composable
 @Composable
-fun AddServerContent(state: MainState) {
+fun AddServerContent(state: MainState, router: Router) {
     var draft by rememberSaveable { mutableStateOf("") }
     var draft by rememberSaveable { mutableStateOf("") }
     var insecure by rememberSaveable { mutableStateOf(false) }
     var insecure by rememberSaveable { mutableStateOf(false) }
     var error by remember(draft) { mutableStateOf("") }
     var error by remember(draft) { mutableStateOf("") }
@@ -46,9 +47,9 @@ fun AddServerContent(state: MainState) {
         try {
         try {
             isLoading = true
             isLoading = true
             val server = state.servers.updateServer(createServerEntity(draft, insecure))
             val server = state.servers.updateServer(createServerEntity(draft, insecure))
-            state.dialog = null
-            state.page = SelectedPage(server)
-            state.closeDrawer(animated = false)
+            router.dialog = null
+            router.page = SelectedPage(server)
+            router.closeDrawer(animated = false)
         } catch (exception: SSLException) {
         } catch (exception: SSLException) {
             exception.printStackTrace()
             exception.printStackTrace()
             error = "Cannot establish a secure connection"
             error = "Cannot establish a secure connection"
@@ -62,7 +63,7 @@ fun AddServerContent(state: MainState) {
     Column {
     Column {
         DialogToolbar(
         DialogToolbar(
             title = "Add server",
             title = "Add server",
-            onCloseClick = { state.dialog = null },
+            onCloseClick = { router.dialog = null },
             action = "Add" to { state.scope.launch { onAddClick() } },
             action = "Add" to { state.scope.launch { onAddClick() } },
             isLoading = isLoading,
             isLoading = isLoading,
         )
         )