Skip to content

Commit bebdaa7

Browse files
tobiasKaminskyalperozturk96
authored andcommitted
wip
Signed-off-by: tobiasKaminsky <[email protected]> wip Signed-off-by: tobiasKaminsky <[email protected]> wip Signed-off-by: tobiasKaminsky <[email protected]> wip Signed-off-by: tobiasKaminsky <[email protected]> wip Signed-off-by: tobiasKaminsky <[email protected]> wip Signed-off-by: tobiasKaminsky <[email protected]>
1 parent 0758e25 commit bebdaa7

File tree

14 files changed

+442
-15
lines changed

14 files changed

+442
-15
lines changed

app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ import com.owncloud.android.db.ProviderMeta
9191
AutoMigration(from = 92, to = 93, spec = DatabaseMigrationUtil.ResetCapabilitiesPostMigration::class),
9292
AutoMigration(from = 93, to = 94, spec = DatabaseMigrationUtil.ResetCapabilitiesPostMigration::class),
9393
AutoMigration(from = 94, to = 95, spec = DatabaseMigrationUtil.ResetCapabilitiesPostMigration::class),
94-
AutoMigration(from = 95, to = 96)
94+
AutoMigration(from = 95, to = 96),
95+
AutoMigration(from = 96, to = 97, spec = DatabaseMigrationUtil.ResetCapabilitiesPostMigration::class)
9596
],
9697
exportSchema = true
9798
)

app/src/main/java/com/nextcloud/client/database/entity/CapabilityEntity.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,5 +146,7 @@ data class CapabilityEntity(
146146
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_WINDOWS_COMPATIBLE_FILENAMES)
147147
val isWCFEnabled: Int?,
148148
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_HAS_VALID_SUBSCRIPTION)
149-
val hasValidSubscription: Int?
149+
val hasValidSubscription: Int?,
150+
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_CLIENT_INTEGRATION_JSON)
151+
val clientIntegrationJson: String?
150152
)
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/*
2+
* Nextcloud - Android Client
3+
*
4+
* SPDX-FileCopyrightText: 2025 Tobias Kaminsky <[email protected]>
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
8+
package com.nextcloud.ui
9+
10+
import android.app.Activity
11+
import androidx.compose.foundation.layout.Arrangement
12+
import androidx.compose.foundation.layout.Column
13+
import androidx.compose.foundation.layout.Row
14+
import androidx.compose.foundation.layout.fillMaxWidth
15+
import androidx.compose.material3.TextButton
16+
import androidx.compose.runtime.Composable
17+
import androidx.compose.ui.Modifier
18+
import androidx.compose.ui.platform.LocalContext
19+
import androidx.compose.ui.tooling.preview.Preview
20+
import com.nextcloud.android.lib.resources.clientintegration.Button
21+
import com.nextcloud.android.lib.resources.clientintegration.ClientIntegrationUI
22+
import com.nextcloud.android.lib.resources.clientintegration.Element
23+
import com.nextcloud.android.lib.resources.clientintegration.Layout
24+
import com.nextcloud.android.lib.resources.clientintegration.Orientation
25+
import com.nextcloud.android.lib.resources.clientintegration.Text
26+
import com.nextcloud.android.lib.resources.clientintegration.URL
27+
import com.nextcloud.utils.extensions.getActivity
28+
import com.owncloud.android.utils.DisplayUtils
29+
30+
@Composable
31+
fun ClientIntegrationScreen(clientIntegrationUI: ClientIntegrationUI, baseUrl: String) {
32+
val activity = LocalContext.current.getActivity()
33+
34+
Column {
35+
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
36+
TextButton({ close(activity) }) {
37+
androidx.compose.material3.Text("X")
38+
}
39+
}
40+
41+
Row {
42+
if (clientIntegrationUI.root.orientation == Orientation.VERTICAL) {
43+
Column {
44+
clientIntegrationUI.root.rows.forEach { row ->
45+
Row {
46+
row.children.forEach { element ->
47+
DisplayElement(element, baseUrl, activity)
48+
}
49+
}
50+
}
51+
}
52+
} else {
53+
Row {
54+
clientIntegrationUI.root.rows.forEach { row ->
55+
Column {
56+
row.children.forEach { element ->
57+
DisplayElement(element, baseUrl, activity)
58+
}
59+
}
60+
}
61+
}
62+
}
63+
}
64+
}
65+
}
66+
67+
@Composable
68+
private fun DisplayElement(element: Element, baseUrl: String, activity: Activity?) {
69+
when (element) {
70+
is Button -> androidx.compose.material3.Button({ }) {
71+
androidx.compose.material3.Text(element.label)
72+
}
73+
74+
is URL -> TextButton({
75+
openLink(activity, baseUrl, element.url)
76+
}) { androidx.compose.material3.Text(element.text) }
77+
78+
is Text -> androidx.compose.material3.Text(element.text)
79+
}
80+
}
81+
82+
private fun openLink(activity: Activity?, baseUrl: String, relativeUrl: String) {
83+
activity?.let {
84+
DisplayUtils.startLinkIntent(activity, baseUrl + relativeUrl)
85+
}
86+
}
87+
88+
private fun close(activity: Activity?) {
89+
activity?.finish()
90+
}
91+
92+
@Composable
93+
@Preview
94+
private fun ClientIntegrationScreenPreviewVertical() {
95+
val clientIntegrationUI = ClientIntegrationUI(
96+
0.1,
97+
Layout(
98+
Orientation.VERTICAL,
99+
mutableListOf(
100+
com.nextcloud.android.lib.resources.clientintegration.Row(
101+
listOf(Button("Click", "Primary"), Text("123"))
102+
),
103+
com.nextcloud.android.lib.resources.clientintegration.Row(
104+
listOf(Button("Click2", "Primary"))
105+
),
106+
com.nextcloud.android.lib.resources.clientintegration.Row(
107+
listOf(URL("Analytics report created", "https://nextcloud.com"))
108+
)
109+
)
110+
)
111+
)
112+
113+
ClientIntegrationScreen(
114+
clientIntegrationUI,
115+
"http://nextcloud.local"
116+
)
117+
}
118+
119+
@Composable
120+
@Preview
121+
private fun ClientIntegrationScreenPreviewHorizontal() {
122+
val clientIntegrationUI = ClientIntegrationUI(
123+
0.1,
124+
Layout(
125+
Orientation.HORIZONTAL,
126+
mutableListOf(
127+
com.nextcloud.android.lib.resources.clientintegration.Row(
128+
listOf(Button("Click", "Primary"), Text("123"))
129+
),
130+
com.nextcloud.android.lib.resources.clientintegration.Row(
131+
listOf(Button("Click2", "Primary"))
132+
),
133+
com.nextcloud.android.lib.resources.clientintegration.Row(
134+
listOf(URL("Analytics report created", "https://nextcloud.com"))
135+
)
136+
)
137+
)
138+
)
139+
140+
ClientIntegrationScreen(clientIntegrationUI, "http://nextcloud.local")
141+
}
142+
143+
@Composable
144+
@Preview
145+
private fun ClientIntegrationScreenPreviewEmpty() {
146+
val clientIntegrationUI = ClientIntegrationUI(
147+
0.1,
148+
Layout(
149+
Orientation.HORIZONTAL,
150+
emptyList()
151+
)
152+
)
153+
154+
ClientIntegrationScreen(clientIntegrationUI, "http://nextcloud.local")
155+
}

app/src/main/java/com/nextcloud/ui/composeActivity/ComposeActivity.kt

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77
*/
88
package com.nextcloud.ui.composeActivity
99

10+
import android.annotation.SuppressLint
11+
import android.content.Intent
1012
import android.os.Bundle
1113
import android.view.MenuItem
14+
import android.view.View
1215
import androidx.compose.material3.MaterialTheme
1316
import androidx.compose.runtime.Composable
1417
import androidx.compose.runtime.LaunchedEffect
@@ -17,6 +20,7 @@ import androidx.compose.runtime.getValue
1720
import androidx.compose.runtime.mutableStateOf
1821
import androidx.compose.runtime.remember
1922
import androidx.compose.runtime.setValue
23+
import com.nextcloud.android.lib.resources.clientintegration.ClientIntegrationUI
2024
import com.nextcloud.client.assistant.AssistantScreen
2125
import com.nextcloud.client.assistant.AssistantViewModel
2226
import com.nextcloud.client.assistant.conversation.ConversationViewModel
@@ -25,6 +29,8 @@ import com.nextcloud.client.assistant.repository.local.AssistantLocalRepositoryI
2529
import com.nextcloud.client.assistant.repository.remote.AssistantRemoteRepositoryImpl
2630
import com.nextcloud.client.database.NextcloudDatabase
2731
import com.nextcloud.common.NextcloudClient
32+
import com.nextcloud.ui.ClientIntegrationScreen
33+
import com.nextcloud.utils.extensions.getSerializableArgument
2834
import com.owncloud.android.R
2935
import com.owncloud.android.databinding.ActivityComposeBinding
3036
import com.owncloud.android.ui.activity.DrawerActivity
@@ -36,6 +42,8 @@ class ComposeActivity : DrawerActivity() {
3642
companion object {
3743
const val DESTINATION = "DESTINATION"
3844
const val TITLE = "TITLE"
45+
const val TITLE_STRING = "TITLE_STRING"
46+
const val ARGS_CLIENT_INTEGRATION_UI = "ARGS_ClIENT_INTEGRATION_UI"
3947
}
4048

4149
override fun onCreate(savedInstanceState: Bundle?) {
@@ -46,12 +54,41 @@ class ComposeActivity : DrawerActivity() {
4654
val destinationId = intent.getIntExtra(DESTINATION, -1)
4755
val titleId = intent.getIntExtra(TITLE, R.string.empty)
4856

49-
setupDrawer()
57+
if (title == null || title.isEmpty()) {
58+
title = getString(intent.getIntExtra(TITLE, R.string.empty))
59+
}
60+
61+
if (destination == ComposeDestination.AssistantScreen) {
62+
setupDrawer()
5063

51-
setupToolbarShowOnlyMenuButtonAndTitle(getString(titleId)) {
52-
openDrawer()
64+
setupToolbarShowOnlyMenuButtonAndTitle(title) {
65+
openDrawer()
66+
}
67+
} else {
68+
setSupportActionBar(null)
69+
if (findViewById<View?>(R.id.appbar) != null) {
70+
findViewById<View?>(R.id.appbar)?.visibility = View.GONE
71+
}
5372
}
5473

74+
// if (false) {
75+
// val actionBar = getDelegate().supportActionBar
76+
// actionBar?.setDisplayHomeAsUpEnabled(true)
77+
// actionBar?.setDisplayShowTitleEnabled(true)
78+
//
79+
// val menuIcon = ResourcesCompat.getDrawable(
80+
// getResources(),
81+
// R.drawable.ic_arrow_back,
82+
// null
83+
// )
84+
// viewThemeUtils.androidx.themeActionBar(
85+
// this,
86+
// actionBar!!,
87+
// title!!,
88+
// menuIcon!!
89+
// )
90+
// }
91+
5592
binding.composeView.setContent {
5693
MaterialTheme(
5794
colorScheme = viewThemeUtils.getColorScheme(this),
@@ -64,12 +101,14 @@ class ComposeActivity : DrawerActivity() {
64101

65102
override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
66103
android.R.id.home -> {
67-
toggleDrawer()
104+
super.onBackPressed()
68105
true
69106
}
107+
70108
else -> super.onOptionsItemSelected(item)
71109
}
72110

111+
@SuppressLint("CoroutineCreationDuringComposition")
73112
@Composable
74113
private fun Content(destination: ComposeDestination) {
75114
val currentScreen by ComposeNavigation.currentScreen.collectAsState()
@@ -104,7 +143,15 @@ class ComposeActivity : DrawerActivity() {
104143
capability = capabilities
105144
)
106145
}
107-
else -> Unit
146+
} else if (destination == ComposeDestination.ClientIntegrationScreen) {
147+
binding.bottomNavigation.visibility = View.GONE
148+
149+
val clientIntegrationUI: ClientIntegrationUI? = intent.getParcelableExtra(ARGS_CLIENT_INTEGRATION_UI)
150+
151+
clientIntegrationUI?.let { ClientIntegrationScreen(it, nextcloudClient?.baseUri.toString()) }
152+
153+
} else {
154+
Unit
108155
}
109156
}
110157
}

app/src/main/java/com/nextcloud/ui/composeActivity/ComposeDestination.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ sealed class ComposeDestination(val id: Int) {
1313
companion object {
1414
fun fromId(id: Int): ComposeDestination = when (id) {
1515
0 -> AssistantScreen(null)
16+
1 -> ClientIntegrationScreen()
1617
else -> throw IllegalArgumentException("Unknown destination: $id")
1718
}
1819
}

app/src/main/java/com/nextcloud/ui/fileactions/FileAction.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ enum class FileAction(
6464
// Retry for offline operation
6565
RETRY(R.id.action_retry, R.string.retry, R.drawable.ic_retry);
6666

67+
constructor(id: Int, title: Int) : this(id, title, null)
68+
6769
companion object {
6870
/**
6971
* All file actions, in the order they should be displayed

0 commit comments

Comments
 (0)