Skip to content

Commit 866f679

Browse files
wip
Signed-off-by: tobiasKaminsky <tobias@kaminsky.me>
1 parent 22fe5cb commit 866f679

2 files changed

Lines changed: 114 additions & 115 deletions

File tree

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

Lines changed: 3 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -19,31 +19,16 @@ import androidx.compose.runtime.getValue
1919
import androidx.compose.runtime.mutableStateOf
2020
import androidx.compose.runtime.remember
2121
import androidx.compose.runtime.setValue
22-
import androidx.lifecycle.coroutineScope
23-
import com.google.gson.Gson
24-
import com.google.gson.GsonBuilder
2522
import com.nextcloud.android.lib.resources.clientintegration.ClientIntegrationUI
26-
import com.nextcloud.android.lib.resources.clientintegration.Element
27-
import com.nextcloud.android.lib.resources.clientintegration.ElementTypeAdapter
28-
import com.nextcloud.android.lib.resources.clientintegration.Endpoint
29-
import com.nextcloud.android.lib.resources.clientintegration.TooltipResponse
3023
import com.nextcloud.client.assistant.AssistantScreen
3124
import com.nextcloud.client.assistant.AssistantViewModel
3225
import com.nextcloud.client.assistant.repository.AssistantRepository
33-
import com.nextcloud.common.JSONRequestBody
3426
import com.nextcloud.common.NextcloudClient
35-
import com.nextcloud.operations.GetMethod
36-
import com.nextcloud.operations.PostMethod
3727
import com.nextcloud.ui.ClientIntegrationScreen
3828
import com.nextcloud.utils.extensions.getSerializableArgument
39-
import com.nextcloud.utils.extensions.showToast
4029
import com.owncloud.android.R
4130
import com.owncloud.android.databinding.ActivityComposeBinding
42-
import com.owncloud.android.lib.resources.status.Method
4331
import com.owncloud.android.ui.activity.DrawerActivity
44-
import kotlinx.coroutines.Dispatchers
45-
import kotlinx.coroutines.launch
46-
import okhttp3.RequestBody
4732

4833
class ComposeActivity : DrawerActivity() {
4934

@@ -53,9 +38,7 @@ class ComposeActivity : DrawerActivity() {
5338
const val DESTINATION = "DESTINATION"
5439
const val TITLE = "TITLE"
5540
const val TITLE_STRING = "TITLE_STRING"
56-
const val ARGS_ENDPOINT = "ARGS_ENDPOINT"
57-
const val ARGS_FILE_ID = "ARGS_FILE_ID"
58-
const val ARGS_FILE_PATH = "ARGS_FILE_PATH"
41+
const val ARGS_CLIENT_INTEGRATION_UI = "ARGS_ClIENT_INTEGRATION_UI"
5942
}
6043

6144
override fun onCreate(savedInstanceState: Bundle?) {
@@ -146,88 +129,9 @@ class ComposeActivity : DrawerActivity() {
146129
} else if (destination == ComposeDestination.ClientIntegrationScreen) {
147130
binding.bottomNavigation.visibility = View.GONE
148131

149-
val endpoint: Endpoint? = intent.getParcelableExtra(ARGS_ENDPOINT)
150-
val fileId = intent.getLongExtra(ARGS_FILE_ID, -1)
151-
val remotePath = intent.getStringExtra(ARGS_FILE_PATH).orEmpty()
152-
153-
if (nextcloudClient != null && endpoint != null) {
154-
var test by remember { mutableStateOf<String?>(null) }
155-
var baseUrl by remember { mutableStateOf<String?>(null) }
156-
lifecycle.coroutineScope.launch(Dispatchers.IO) {
157-
// construct url
158-
var url = nextcloudClient!!.baseUri.toString() + endpoint.url
159-
baseUrl = nextcloudClient!!.baseUri.toString()
160-
161-
val method = when (endpoint.method) {
162-
Method.GET -> {
163-
endpoint.params!!.forEach {
164-
when (it.value) {
165-
"{fileId}" -> url = url.replace(it.key, fileId.toString(), false)
166-
"{filePath}" -> url = url.replace(it.key, remotePath, false)
167-
}
168-
}
169-
GetMethod(url, true)
170-
}
171-
172-
Method.POST -> {
173-
val requestBody = if (endpoint.params?.isNotEmpty() == true) {
174-
val jsonRequestBody = JSONRequestBody()
175-
endpoint.params!!.forEach {
176-
when (it.value) {
177-
"{filePath}" -> jsonRequestBody.put(it.key, remotePath)
178-
"{fileId}" -> jsonRequestBody.put(it.key, fileId.toString())
179-
}
180-
}
181-
182-
jsonRequestBody.get()
183-
} else {
184-
RequestBody.EMPTY
185-
}
186-
187-
PostMethod(url, true, requestBody)
188-
}
189-
190-
else -> GetMethod(url, true)
191-
}
192-
193-
val result = try {
194-
nextcloudClient?.execute(method)
195-
} catch (exception: Exception) {
196-
val e = exception
197-
TODO("Add error handling here")
198-
}
199-
test = method.getResponseBodyAsString()
200-
}
132+
val clientIntegrationUI: ClientIntegrationUI? = intent.getParcelableExtra(ARGS_CLIENT_INTEGRATION_UI)
201133

202-
if (test != null) {
203-
var output: ClientIntegrationUI? = null
204-
try {
205-
output = parseResult(test)
206-
} catch (e: Exception) {
207-
try {
208-
val tooltipResponse = parseTooltipResult(test)
209-
showToast(tooltipResponse.tooltip)
210-
} catch (e: Exception) {
211-
showToast("Failed to start action!")
212-
onBackPressed()
213-
}
214-
}
215-
output?.let { ClientIntegrationScreen(it, baseUrl!!) }
216-
}
217-
}
134+
clientIntegrationUI?.let { ClientIntegrationScreen(it, nextcloudClient?.baseUri.toString()) }
218135
}
219136
}
220-
221-
fun parseResult(response: String?): ClientIntegrationUI {
222-
val gson =
223-
GsonBuilder()
224-
.registerTypeHierarchyAdapter(Element::class.java, ElementTypeAdapter())
225-
.create()
226-
227-
return gson.fromJson(response, ClientIntegrationUI::class.java)
228-
}
229-
230-
fun parseTooltipResult(response: String?): TooltipResponse {
231-
return Gson().fromJson(response, TooltipResponse::class.java)
232-
}
233137
}

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

Lines changed: 111 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,30 @@ import androidx.fragment.app.FragmentManager
3030
import androidx.fragment.app.setFragmentResult
3131
import androidx.lifecycle.LifecycleOwner
3232
import androidx.lifecycle.ViewModelProvider
33+
import androidx.lifecycle.coroutineScope
3334
import com.google.android.material.bottomsheet.BottomSheetBehavior
3435
import com.google.android.material.bottomsheet.BottomSheetDialog
3536
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
37+
import com.google.gson.Gson
38+
import com.google.gson.GsonBuilder
3639
import com.nextcloud.android.common.ui.theme.utils.ColorRole
40+
import com.nextcloud.android.lib.resources.clientintegration.ClientIntegrationUI
41+
import com.nextcloud.android.lib.resources.clientintegration.Element
42+
import com.nextcloud.android.lib.resources.clientintegration.ElementTypeAdapter
3743
import com.nextcloud.android.lib.resources.clientintegration.Endpoint
44+
import com.nextcloud.android.lib.resources.clientintegration.TooltipResponse
3845
import com.nextcloud.client.account.CurrentAccountProvider
3946
import com.nextcloud.client.di.Injectable
4047
import com.nextcloud.client.di.ViewModelFactory
48+
import com.nextcloud.common.JSONRequestBody
49+
import com.nextcloud.operations.GetMethod
50+
import com.nextcloud.operations.PostMethod
4151
import com.nextcloud.ui.composeActivity.ComposeActivity
4252
import com.nextcloud.ui.composeActivity.ComposeDestination
4353
import com.nextcloud.ui.fileactions.FileActionsViewModel.Companion.ARG_ENDPOINTS
4454
import com.nextcloud.utils.GlideHelper
4555
import com.nextcloud.utils.extensions.setVisibleIf
56+
import com.nextcloud.utils.extensions.showToast
4657
import com.owncloud.android.R
4758
import com.owncloud.android.databinding.FileActionsBottomSheetBinding
4859
import com.owncloud.android.databinding.FileActionsBottomSheetItemBinding
@@ -52,6 +63,7 @@ import com.owncloud.android.datamodel.SyncedFolderProvider
5263
import com.owncloud.android.datamodel.ThumbnailsCacheManager
5364
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory
5465
import com.owncloud.android.lib.resources.files.model.FileLockType
66+
import com.owncloud.android.lib.resources.status.Method
5567
import com.owncloud.android.ui.activity.ComponentsGetter
5668
import com.owncloud.android.utils.DisplayUtils
5769
import com.owncloud.android.utils.DisplayUtils.AvatarGenerationListener
@@ -61,6 +73,7 @@ import kotlinx.coroutines.CoroutineScope
6173
import kotlinx.coroutines.Dispatchers
6274
import kotlinx.coroutines.launch
6375
import kotlinx.coroutines.withContext
76+
import okhttp3.RequestBody
6477
import javax.inject.Inject
6578

6679
class FileActionsBottomSheet :
@@ -93,7 +106,7 @@ class FileActionsBottomSheet :
93106
private val thumbnailAsyncTasks = mutableListOf<ThumbnailsCacheManager.ThumbnailGenerationTask>()
94107

95108
private var endpoints: List<Endpoint>? = mutableListOf()
96-
109+
97110
fun interface ResultListener {
98111
fun onResult(@IdRes actionId: Int)
99112
}
@@ -220,7 +233,7 @@ class FileActionsBottomSheet :
220233
}
221234
// add client integration
222235
if (endpoints != null) {
223-
for(val e in endpoints) {
236+
for (val e in endpoints) {
224237
val ui = inflateClientIntegrationActionView(e)
225238
binding.fileActionsList.addView(ui)
226239
}
@@ -332,23 +345,16 @@ class FileActionsBottomSheet :
332345
val itemBinding = FileActionsBottomSheetItemBinding.inflate(layoutInflater, binding.fileActionsList, false)
333346
.apply {
334347
root.setOnClickListener {
335-
val composeActivity = Intent(context, ComposeActivity::class.java)
336-
composeActivity.putExtra(ComposeActivity.DESTINATION, ComposeDestination.ClientIntegrationScreen)
337-
composeActivity.putExtra(ComposeActivity.ARGS_ENDPOINT, endpoint)
338348
if (viewModel.uiState.value is FileActionsViewModel.UiState.LoadedForSingleFile) {
339-
composeActivity.putExtra(
340-
ComposeActivity.ARGS_FILE_ID,
341-
(viewModel.uiState.value as FileActionsViewModel.UiState.LoadedForSingleFile).titleFile?.localId
342-
)
349+
val singleFile = (viewModel.uiState.value as FileActionsViewModel.UiState.LoadedForSingleFile)
343350

344-
composeActivity.putExtra(
345-
ComposeActivity.ARGS_FILE_PATH,
346-
(viewModel.uiState.value as FileActionsViewModel.UiState.LoadedForSingleFile).titleFile?.remotePath
347-
)
351+
val fileId = singleFile.titleFile?.localId.toString()
352+
val filePath = singleFile.titleFile?.remotePath.toString()
353+
354+
requestClientIntegration(endpoint, fileId, filePath)
355+
} else {
356+
requestClientIntegration(endpoint, "", "")
348357
}
349-
composeActivity.putExtra(ComposeActivity.TITLE, endpoint.name)
350-
startActivity(composeActivity)
351-
dismiss()
352358
}
353359
text.text = endpoint.name
354360

@@ -384,6 +390,95 @@ class FileActionsBottomSheet :
384390
return itemBinding.root
385391
}
386392

393+
private fun requestClientIntegration(endpoint: Endpoint, fileId: String, filePath: String) {
394+
lifecycle.coroutineScope.launch(Dispatchers.IO) {
395+
val client = OwnCloudClientManagerFactory.getDefaultSingleton()
396+
.getNextcloudClientFor(currentUserProvider.user.toOwnCloudAccount(), context)
397+
398+
// construct url
399+
var url = client.baseUri.toString() + endpoint.url
400+
401+
val method = when (endpoint.method) {
402+
Method.GET -> {
403+
endpoint.params!!.forEach {
404+
when (it.value) {
405+
"{fileId}" -> url = url.replace(it.key, fileId, false)
406+
"{filePath}" -> url = url.replace(it.key, filePath, false)
407+
}
408+
}
409+
GetMethod(url, true)
410+
}
411+
412+
Method.POST -> {
413+
val requestBody = if (endpoint.params?.isNotEmpty() == true) {
414+
val jsonRequestBody = JSONRequestBody()
415+
endpoint.params!!.forEach {
416+
when (it.value) {
417+
"{filePath}" -> jsonRequestBody.put(it.key, filePath)
418+
"{fileId}" -> jsonRequestBody.put(it.key, fileId)
419+
}
420+
}
421+
422+
jsonRequestBody.get()
423+
} else {
424+
RequestBody.EMPTY
425+
}
426+
427+
PostMethod(url, true, requestBody)
428+
}
429+
430+
else -> GetMethod(url, true)
431+
}
432+
433+
val result = try {
434+
client.execute(method)
435+
} catch (exception: Exception) {
436+
val e = exception
437+
TODO("Add error handling here")
438+
}
439+
val response = method.getResponseBodyAsString()
440+
441+
var output: ClientIntegrationUI? = null
442+
try {
443+
output = parseClientIntegrationResult(response)
444+
startClientIntegration(endpoint, output)
445+
} catch (e: Exception) {
446+
try {
447+
val tooltipResponse = parseTooltipResult(response)
448+
449+
activity?.showToast(tooltipResponse.tooltip)
450+
} catch (e: Exception) {
451+
activity?.showToast("Failed to start action!")
452+
}
453+
dismiss()
454+
}
455+
}
456+
}
457+
458+
private fun startClientIntegration(endpoint: Endpoint, clientIntegrationUI: ClientIntegrationUI) {
459+
CoroutineScope(Dispatchers.IO).launch {
460+
val composeActivity = Intent(context, ComposeActivity::class.java)
461+
composeActivity.putExtra(ComposeActivity.DESTINATION, ComposeDestination.ClientIntegrationScreen)
462+
composeActivity.putExtra(ComposeActivity.ARGS_CLIENT_INTEGRATION_UI, clientIntegrationUI)
463+
464+
composeActivity.putExtra(ComposeActivity.TITLE, endpoint.name)
465+
startActivity(composeActivity)
466+
dismiss()
467+
}
468+
}
469+
470+
private fun parseClientIntegrationResult(response: String?): ClientIntegrationUI {
471+
val gson =
472+
GsonBuilder()
473+
.registerTypeHierarchyAdapter(Element::class.java, ElementTypeAdapter())
474+
.create()
475+
476+
return gson.fromJson(response, ClientIntegrationUI::class.java)
477+
}
478+
479+
private fun parseTooltipResult(response: String?): TooltipResponse =
480+
Gson().fromJson(response, TooltipResponse::class.java)
481+
387482
private fun dispatchActionClick(id: Int?) {
388483
if (id != null) {
389484
setFragmentResult(REQUEST_KEY, bundleOf(RESULT_KEY_ACTION_ID to id))

0 commit comments

Comments
 (0)