Skip to content

Commit f37c493

Browse files
committed
feat: implement methods and network operation to remove a space public link
1 parent ce980b5 commit f37c493

12 files changed

Lines changed: 172 additions & 1 deletion

File tree

owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/UseCaseModule.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ import com.owncloud.android.domain.files.usecases.SortFilesUseCase
8080
import com.owncloud.android.domain.files.usecases.SortFilesWithSyncInfoUseCase
8181
import com.owncloud.android.domain.files.usecases.UpdateAlreadyDownloadedFilesPathUseCase
8282
import com.owncloud.android.domain.links.usecases.AddLinkUseCase
83+
import com.owncloud.android.domain.links.usecases.RemoveLinkUseCase
8384
import com.owncloud.android.domain.members.usecases.AddMemberUseCase
8485
import com.owncloud.android.domain.members.usecases.EditMemberUseCase
8586
import com.owncloud.android.domain.members.usecases.RemoveMemberUseCase
@@ -320,4 +321,5 @@ val useCaseModule = module {
320321

321322
// Links
322323
factoryOf(::AddLinkUseCase)
324+
factoryOf(::RemoveLinkUseCase)
323325
}

owncloudApp/src/main/java/com/owncloud/android/presentation/spaces/links/SpaceLinksViewModel.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,21 @@ package com.owncloud.android.presentation.spaces.links
2323
import androidx.lifecycle.ViewModel
2424
import com.owncloud.android.domain.links.model.OCLinkType
2525
import com.owncloud.android.domain.links.usecases.AddLinkUseCase
26+
import com.owncloud.android.domain.links.usecases.RemoveLinkUseCase
2627
import com.owncloud.android.domain.spaces.model.OCSpace
2728
import com.owncloud.android.domain.utils.Event
2829
import com.owncloud.android.extensions.ViewModelExt.runUseCaseWithResult
2930
import com.owncloud.android.presentation.common.UIResult
3031
import com.owncloud.android.providers.CoroutinesDispatcherProvider
32+
import kotlinx.coroutines.flow.MutableSharedFlow
3133
import kotlinx.coroutines.flow.MutableStateFlow
34+
import kotlinx.coroutines.flow.SharedFlow
3235
import kotlinx.coroutines.flow.StateFlow
3336
import kotlinx.coroutines.flow.update
3437

3538
class SpaceLinksViewModel(
3639
private val addLinkUseCase: AddLinkUseCase,
40+
private val removeLinkUseCase: RemoveLinkUseCase,
3741
private val accountName: String,
3842
private val space: OCSpace,
3943
private val coroutineDispatcherProvider: CoroutinesDispatcherProvider
@@ -45,6 +49,9 @@ class SpaceLinksViewModel(
4549
private val _addLinkResultFlow = MutableStateFlow<Event<UIResult<Unit>>?>(null)
4650
val addLinkResultFlow: StateFlow<Event<UIResult<Unit>>?> = _addLinkResultFlow
4751

52+
private val _removeLinkResultFlow = MutableSharedFlow<UIResult<Unit>>()
53+
val removeLinkResultFlow: SharedFlow<UIResult<Unit>> = _removeLinkResultFlow
54+
4855
init {
4956
_addPublicLinkUIState.value = AddPublicLinkUIState()
5057
}
@@ -79,6 +86,19 @@ class SpaceLinksViewModel(
7986
}
8087
}
8188

89+
fun removePublicLink(linkId: String) {
90+
runUseCaseWithResult(
91+
coroutineDispatcher = coroutineDispatcherProvider.io,
92+
sharedFlow = _removeLinkResultFlow,
93+
useCase = removeLinkUseCase,
94+
useCaseParams = RemoveLinkUseCase.Params(
95+
accountName = accountName,
96+
spaceId = space.id,
97+
linkId = linkId
98+
)
99+
)
100+
}
101+
82102
fun resetViewModel() {
83103
_addLinkResultFlow.value = null
84104
_addPublicLinkUIState.value = AddPublicLinkUIState()

owncloudApp/src/main/java/com/owncloud/android/presentation/spaces/members/SpaceMembersFragment.kt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ class SpaceMembersFragment : Fragment(), SpaceMembersAdapter.SpaceMembersAdapter
192192
title = getString(R.string.public_link_remove_dialog_title, publicLinkDisplayName),
193193
message = getString(R.string.public_link_remove_dialog_message),
194194
positiveButtonText = getString(R.string.common_yes),
195-
positiveButtonListener = { _: DialogInterface?, _: Int -> },
195+
positiveButtonListener = { _: DialogInterface?, _: Int -> spaceLinksViewModel.removePublicLink(publicLinkId) },
196196
negativeButtonText = getString(R.string.common_no)
197197
)
198198
}
@@ -205,6 +205,7 @@ class SpaceMembersFragment : Fragment(), SpaceMembersAdapter.SpaceMembersAdapter
205205
observeRemoveMemberResult()
206206
observeEditMemberResult()
207207
observeAddLinkResult()
208+
observeRemoveLinkResult()
208209
}
209210

210211
private fun observeRoles() {
@@ -351,6 +352,22 @@ class SpaceMembersFragment : Fragment(), SpaceMembersAdapter.SpaceMembersAdapter
351352
}
352353
}
353354

355+
private fun observeRemoveLinkResult() {
356+
collectLatestLifecycleFlow(spaceLinksViewModel.removeLinkResultFlow) { uiResult ->
357+
when (uiResult) {
358+
is UIResult.Loading -> { }
359+
is UIResult.Success -> {
360+
showMessageInSnackbar(getString(R.string.public_link_remove_correctly))
361+
spaceMembersViewModel.getSpaceMembers()
362+
}
363+
is UIResult.Error -> {
364+
Timber.e(uiResult.error, "Failed to remove a public link from space: ${currentSpace.id}")
365+
showErrorInSnackbar(R.string.public_link_remove_failed, uiResult.error)
366+
}
367+
}
368+
}
369+
}
370+
354371
private fun checkPermissions(spacePermissions: List<String>) {
355372
val hasCreatePermission = DRIVES_CREATE_PERMISSION in spacePermissions
356373
canRemoveMembersAndLinks = DRIVES_DELETE_PERMISSION in spacePermissions

owncloudApp/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,8 @@
934934
<string name="public_link_add_failed">Public link could not be created</string>
935935
<string name="public_link_remove_dialog_title">Do you really want to remove the link: %1$s?</string>
936936
<string name="public_link_remove_dialog_message">Recreating the same link again is not possible</string>
937+
<string name="public_link_remove_correctly">Public link removed correctly</string>
938+
<string name="public_link_remove_failed">Public link could not be removed</string>
937939

938940
<string name="feedback_dialog_get_in_contact_description"><![CDATA[ Ask for help in our <a href=\"%1$s\"><b>forum</b></a> or contribute in our <a href=\"%2$s\"><b>GitHub repo</b></a>]]></string>
939941

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* ownCloud Android client application
3+
*
4+
* @author Jorge Aguado Recio
5+
*
6+
* Copyright (C) 2026 ownCloud GmbH.
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License version 2,
10+
* as published by the Free Software Foundation.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
21+
package com.owncloud.android.lib.resources.links
22+
23+
import com.owncloud.android.lib.common.OwnCloudClient
24+
import com.owncloud.android.lib.common.http.HttpConstants
25+
import com.owncloud.android.lib.common.http.methods.nonwebdav.DeleteMethod
26+
import com.owncloud.android.lib.common.operations.RemoteOperation
27+
import com.owncloud.android.lib.common.operations.RemoteOperationResult
28+
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode
29+
import timber.log.Timber
30+
import java.net.URL
31+
32+
class RemoveRemoteLinkOperation(
33+
private val spaceId: String,
34+
private val linkId: String
35+
): RemoteOperation<Unit>() {
36+
override fun run(client: OwnCloudClient): RemoteOperationResult<Unit> {
37+
var result: RemoteOperationResult<Unit>
38+
try {
39+
val uriBuilder = client.baseUri.buildUpon().apply {
40+
appendEncodedPath(GRAPH_API_SPACES_PATH)
41+
appendEncodedPath(spaceId)
42+
appendEncodedPath(GRAPH_API_ROOT_PERMISSIONS_PATH)
43+
appendEncodedPath(linkId)
44+
}
45+
46+
val deleteMethod = DeleteMethod(URL(uriBuilder.build().toString()))
47+
48+
val status = client.executeHttpMethod(deleteMethod)
49+
50+
val response = deleteMethod.getResponseBodyAsString()
51+
52+
if (status == HttpConstants.HTTP_NO_CONTENT) {
53+
Timber.d("Successful response: $response")
54+
result = RemoteOperationResult(ResultCode.OK)
55+
} else {
56+
result = RemoteOperationResult(deleteMethod)
57+
Timber.e("Failed response while removing a space public link; status code: $status, response: $response")
58+
}
59+
} catch (e: Exception) {
60+
result = RemoteOperationResult(e)
61+
Timber.e(e, "Exception while removing a space public link")
62+
}
63+
return result
64+
}
65+
66+
companion object {
67+
private const val GRAPH_API_SPACES_PATH = "graph/v1beta1/drives/"
68+
private const val GRAPH_API_ROOT_PERMISSIONS_PATH = "root/permissions"
69+
}
70+
}

owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/links/services/LinksService.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ import com.owncloud.android.lib.resources.Service
2525

2626
interface LinksService: Service {
2727
fun addLink(spaceId: String, displayName: String, type: String, expirationDate: String?, password: String?): RemoteOperationResult<Unit>
28+
fun removeLink(spaceId: String, linkId: String): RemoteOperationResult<Unit>
2829
}

owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/links/services/OCLinksService.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ package com.owncloud.android.lib.resources.links.services
2323
import com.owncloud.android.lib.common.OwnCloudClient
2424
import com.owncloud.android.lib.common.operations.RemoteOperationResult
2525
import com.owncloud.android.lib.resources.links.AddRemoteLinkOperation
26+
import com.owncloud.android.lib.resources.links.RemoveRemoteLinkOperation
2627

2728
class OCLinksService(override val client: OwnCloudClient) : LinksService {
2829

@@ -40,4 +41,10 @@ class OCLinksService(override val client: OwnCloudClient) : LinksService {
4041
expirationDate = expirationDate,
4142
password = password
4243
).execute(client)
44+
45+
override fun removeLink(spaceId: String, linkId: String): RemoteOperationResult<Unit> =
46+
RemoveRemoteLinkOperation(
47+
spaceId = spaceId,
48+
linkId = linkId
49+
).execute(client)
4350
}

owncloudData/src/main/java/com/owncloud/android/data/links/datasources/RemoteLinksDataSource.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ import com.owncloud.android.domain.links.model.OCLinkType
2424

2525
interface RemoteLinksDataSource {
2626
fun addLink(accountName: String, spaceId: String, displayName: String, type: OCLinkType, expirationDate: String?, password: String?)
27+
fun removeLink(accountName: String, spaceId: String, linkId: String)
2728
}

owncloudData/src/main/java/com/owncloud/android/data/links/datasources/implementation/OCRemoteLinksDataSource.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,10 @@ class OCRemoteLinksDataSource(
3434
clientManager.getLinksService(accountName).addLink(spaceId, displayName, OCLinkType.toString(type), expirationDate, password)
3535
}
3636
}
37+
38+
override fun removeLink(accountName: String, spaceId: String, linkId: String) {
39+
executeRemoteOperation {
40+
clientManager.getLinksService(accountName).removeLink(spaceId, linkId)
41+
}
42+
}
3743
}

owncloudData/src/main/java/com/owncloud/android/data/links/repository/OCLinksRepository.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,8 @@ class OCLinksRepository(
3131
override fun addLink(accountName: String, spaceId: String, displayName: String, type: OCLinkType, expirationDate: String?, password: String?) {
3232
remoteLinksDataSource.addLink(accountName, spaceId, displayName, type, expirationDate, password)
3333
}
34+
35+
override fun removeLink(accountName: String, spaceId: String, linkId: String) {
36+
remoteLinksDataSource.removeLink(accountName, spaceId, linkId)
37+
}
3438
}

0 commit comments

Comments
 (0)