Эх сурвалжийг харах

Add UI Components

Signed-off-by: alperozturk <alper_ozturk@proton.me>
alperozturk 1 жил өмнө
parent
commit
6767ab8636

+ 7 - 7
app/src/main/java/com/nextcloud/client/assistant/AssistantViewModel.kt

@@ -36,7 +36,7 @@ import kotlinx.coroutines.launch
 
 
 class AssistantViewModel(context: Context, user: User) : ViewModel() {
 class AssistantViewModel(context: Context, user: User) : ViewModel() {
 
 
-    private val repository = AssistantRepository(user, context)
+    private var repository: AssistantRepository? = null
 
 
     private val _taskTypes = MutableStateFlow<TaskTypes?>(null)
     private val _taskTypes = MutableStateFlow<TaskTypes?>(null)
     val taskTypes: StateFlow<TaskTypes?> = _taskTypes
     val taskTypes: StateFlow<TaskTypes?> = _taskTypes
@@ -46,22 +46,24 @@ class AssistantViewModel(context: Context, user: User) : ViewModel() {
 
 
     init {
     init {
         viewModelScope.launch(Dispatchers.IO) {
         viewModelScope.launch(Dispatchers.IO) {
+            repository = AssistantRepository(user, context)
+
             _taskTypes.update {
             _taskTypes.update {
-                repository.getTaskTypes()
+                repository?.getTaskTypes()
             }
             }
         }
         }
     }
     }
 
 
     fun deleteTask(id: String) {
     fun deleteTask(id: String) {
         viewModelScope.launch(Dispatchers.IO) {
         viewModelScope.launch(Dispatchers.IO) {
-            repository.deleteTask(id)
+            repository?.deleteTask(id)
         }
         }
     }
     }
 
 
     fun getTask(id: String) {
     fun getTask(id: String) {
         viewModelScope.launch(Dispatchers.IO) {
         viewModelScope.launch(Dispatchers.IO) {
             _task.update {
             _task.update {
-                repository.getTask(id)
+                repository?.getTask(id)
             }
             }
         }
         }
     }
     }
@@ -69,11 +71,9 @@ class AssistantViewModel(context: Context, user: User) : ViewModel() {
     fun createTask(
     fun createTask(
         input: String,
         input: String,
         type: String,
         type: String,
-        appId: String,
-        identifier: String,
     ) {
     ) {
         viewModelScope.launch(Dispatchers.IO) {
         viewModelScope.launch(Dispatchers.IO) {
-            repository.createTask(input, type, appId, identifier)
+            repository?.createTask(input, type, identifier = " ")
         }
         }
     }
     }
 }
 }

+ 113 - 6
app/src/main/java/com/nextcloud/client/assistant/AsssistantScreen.kt

@@ -22,29 +22,136 @@
 package com.nextcloud.client.assistant
 package com.nextcloud.client.assistant
 
 
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.horizontalScroll
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.items
 import androidx.compose.foundation.lazy.items
-import androidx.compose.foundation.lazy.itemsIndexed
-import androidx.compose.material3.Scaffold
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.material3.ButtonColors
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.FilledTonalButton
 import androidx.compose.material3.Text
 import androidx.compose.material3.Text
+import androidx.compose.material3.TextField
+import androidx.compose.material3.TextFieldDefaults
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 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.unit.dp
 import androidx.compose.ui.unit.dp
+import com.google.android.material.floatingactionbutton.FloatingActionButton
+import com.nextcloud.android.common.ui.theme.utils.ColorRole
+import com.nextcloud.operations.assistant.model.OcsType
+import com.nextcloud.ui.composeComponents.SimpleAlertDialog
+import com.owncloud.android.R
 
 
 @OptIn(ExperimentalFoundationApi::class)
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 @Composable
-fun AssistantScreen(viewModel: AssistantViewModel) {
+fun AssistantScreen(viewModel: AssistantViewModel, floatingActionButton: FloatingActionButton) {
+    // TODO hide sort group, floating action and search bar
     val taskTypes by viewModel.taskTypes.collectAsState()
     val taskTypes by viewModel.taskTypes.collectAsState()
+    var selectedTaskType: String? by remember {
+        mutableStateOf(null)
+    }
+    var showAddTaskAlertDialog by remember {
+        mutableStateOf(false)
+    }
+
+    floatingActionButton.setOnClickListener {
+        showAddTaskAlertDialog = true
+    }
+
+    LazyColumn(
+        modifier = Modifier
+            .fillMaxSize()
+            .padding(16.dp)
+    ) {
+        stickyHeader {
+            taskTypes?.let { it ->
+                TaskTypesRow(selectedTaskType, data = it.ocs.data.types) { taskId ->
+                    selectedTaskType = taskId
+                }
+            }
+        }
 
 
-    LazyColumn(modifier = Modifier.fillMaxSize().padding(16.dp)) {
         items(taskTypes?.ocs?.data?.types ?: listOf()) {
         items(taskTypes?.ocs?.data?.types ?: listOf()) {
             Text(text = it.toString())
             Text(text = it.toString())
         }
         }
     }
     }
 
 
-}
+    if (showAddTaskAlertDialog) {
+        selectedTaskType?.let {
+            AddTaskAlertDialog(viewModel, it) {
+                showAddTaskAlertDialog = false
+            }
+        }
+    }
+}
+
+@Composable
+private fun AddTaskAlertDialog(viewModel: AssistantViewModel, type: String, dismiss: () -> Unit) {
+    var input by remember {
+        mutableStateOf("")
+    }
+
+    // TODO add to UI LIB
+    SimpleAlertDialog(
+        backgroundColor = Color.White,
+        textColor = Color.Black,
+        titleId = R.string.about_title,
+        description = stringResource(id = R.string.about_title),
+        dismiss = { dismiss() },
+        onComplete = { viewModel.createTask(input = input, type = type) },
+        content = {
+            TextField(
+                placeholder = {
+                    Text(
+                        text = stringResource(id = R.string.samples),
+                    )
+                },
+                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
+                value = input,
+                onValueChange = {
+                    input = it
+                },
+                singleLine = true
+            )
+        }
+    )
+}
+
+@Composable
+private fun TaskTypesRow(selectedTaskType: String?, data: List<OcsType>, selectTaskType: (String) -> Unit) {
+    Row(
+        modifier = Modifier
+            .fillMaxWidth()
+            .horizontalScroll(rememberScrollState())
+    ) {
+        data.forEach {
+            FilledTonalButton(
+                onClick = { selectTaskType(it.id) },
+                colors = ButtonDefaults.buttonColors(
+                    containerColor = if (selectedTaskType == it.id) {
+                        Color.Unspecified
+                    } else {
+                        Color.Gray
+                    }
+                )
+            ) {
+                Text(text = it.name)
+            }
+
+            Spacer(modifier = Modifier.padding(end = 8.dp))
+        }
+    }
+}

+ 97 - 0
app/src/main/java/com/nextcloud/ui/composeComponents/SimpleAlertDialog.kt

@@ -0,0 +1,97 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Alper Ozturk
+ * Copyright (C) 2024 Alper Ozturk
+ * Copyright (C) 2024 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.ui.composeComponents
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.material3.AlertDialog
+import androidx.compose.material3.Text
+import androidx.compose.material3.TextButton
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.owncloud.android.R
+
+@Composable
+fun SimpleAlertDialog(
+    backgroundColor: Color,
+    textColor: Color,
+    titleId: Int,
+    description: String?,
+    heightFraction: Float? = null,
+    content: @Composable (() -> Unit)? = null,
+    onComplete: () -> Unit,
+    dismiss: () -> Unit
+) {
+    val modifier = if (heightFraction != null) {
+        Modifier
+            .fillMaxWidth()
+            .fillMaxHeight(heightFraction)
+    } else {
+        Modifier.fillMaxWidth()
+    }
+
+    AlertDialog(
+        containerColor = backgroundColor,
+        onDismissRequest = { dismiss() },
+        title = {
+            Text(text = stringResource(id = titleId), color = textColor)
+        },
+        text = {
+            Column(modifier = modifier) {
+                if (description != null) {
+                    Text(text = description, color = textColor)
+                }
+
+                content?.let {
+                    Spacer(modifier = Modifier.height(16.dp))
+
+                    content()
+                }
+            }
+        },
+        confirmButton = {
+            TextButton(onClick = {
+                onComplete()
+                dismiss()
+            }) {
+                Text(
+                    stringResource(id = R.string.common_ok),
+                    color = textColor
+                )
+            }
+        },
+        dismissButton = {
+            TextButton(onClick = { dismiss() }) {
+                Text(
+                    stringResource(id = R.string.common_cancel),
+                    color = textColor
+                )
+            }
+        }
+    )
+}

+ 26 - 13
app/src/main/java/com/nextcloud/ui/composeFragment/ComposeFragment.kt

@@ -25,13 +25,18 @@ import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.LayoutInflater
 import android.view.View
 import android.view.View
 import android.view.ViewGroup
 import android.view.ViewGroup
+import androidx.compose.runtime.Composable
 import androidx.compose.ui.platform.ViewCompositionStrategy
 import androidx.compose.ui.platform.ViewCompositionStrategy
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.Fragment
+import com.google.android.material.floatingactionbutton.FloatingActionButton
 import com.nextcloud.client.assistant.AssistantScreen
 import com.nextcloud.client.assistant.AssistantScreen
 import com.nextcloud.client.assistant.AssistantViewModel
 import com.nextcloud.client.assistant.AssistantViewModel
 import com.nextcloud.utils.extensions.getSerializableArgument
 import com.nextcloud.utils.extensions.getSerializableArgument
+import com.owncloud.android.R
 import com.owncloud.android.databinding.FragmentComposeViewBinding
 import com.owncloud.android.databinding.FragmentComposeViewBinding
 import com.owncloud.android.ui.fragment.FileFragment
 import com.owncloud.android.ui.fragment.FileFragment
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
 
 
 class ComposeFragment : FileFragment() {
 class ComposeFragment : FileFragment() {
 
 
@@ -54,26 +59,34 @@ class ComposeFragment : FileFragment() {
 
 
         binding.composeView.apply {
         binding.composeView.apply {
             setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
             setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
-            setContent {
-                when (destination) {
-                    ComposeDestinations.AssistantScreen -> {
-                        AssistantScreen(
-                            viewModel = AssistantViewModel(
-                                context = requireContext(),
-                                user = containerActivity.storageManager.user
-                            )
-                        )
-                    }
 
 
-                    else -> {
-                    }
-                }
+            setContent {
+                Content(destination)
             }
             }
         }
         }
 
 
         return binding.root
         return binding.root
     }
     }
 
 
+    @Composable
+    private fun Content(destination: ComposeDestinations?) {
+        val floatingActionButton: FloatingActionButton = requireActivity().findViewById(R.id.fab_main)
+
+        return when (destination) {
+            ComposeDestinations.AssistantScreen -> {
+                AssistantScreen(
+                    viewModel = AssistantViewModel(
+                        context = requireContext(),
+                        user = containerActivity.storageManager.user
+                    ),
+                    floatingActionButton
+                )
+            }
+            else -> {
+            }
+        }
+    }
+
     override fun onDestroyView() {
     override fun onDestroyView() {
         super.onDestroyView()
         super.onDestroyView()
         _binding = null
         _binding = null

+ 0 - 3
app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java

@@ -555,9 +555,6 @@ public abstract class DrawerActivity extends ToolbarActivity
                 .beginTransaction()
                 .beginTransaction()
                 .replace(R.id.left_fragment_container, composeFragment)
                 .replace(R.id.left_fragment_container, composeFragment)
                 .commit();
                 .commit();
-
-
-            Log_OC.w(TAG, "ADD JETPACK Compose PAGE");
         } else {
         } else {
             if (menuItem.getItemId() >= MENU_ITEM_EXTERNAL_LINK &&
             if (menuItem.getItemId() >= MENU_ITEM_EXTERNAL_LINK &&
                 menuItem.getItemId() <= MENU_ITEM_EXTERNAL_LINK + 100) {
                 menuItem.getItemId() <= MENU_ITEM_EXTERNAL_LINK + 100) {

+ 6 - 0
settings.gradle

@@ -14,3 +14,9 @@ include ':appscan'
 //        substitute module('com.github.nextcloud:android-library') using project(':library')
 //        substitute module('com.github.nextcloud:android-library') using project(':library')
 //    }
 //    }
 //}
 //}
+
+includeBuild('/Users/alperozturk/Desktop/nextcloud/nextcloud_android_library') {
+    dependencySubstitution {
+        substitute module('com.github.nextcloud:android-library') using project(':library')
+    }
+}