Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ ownCloud admins and users.
* Enhancement - Workflow to build APK: [#4751](https://github.com/owncloud/android/pull/4751)
* Enhancement - List links over a space: [#4752](https://github.com/owncloud/android/issues/4752)
* Enhancement - Add a public link over a space: [#4753](https://github.com/owncloud/android/issues/4753)
* Enhancement - Remove space link: [#4757](https://github.com/owncloud/android/issues/4757)
* Enhancement - Copy permanent link of a space: [#4758](https://github.com/owncloud/android/issues/4758)
* Enhancement - Workflow to check Conventional Commits: [#4759](https://github.com/owncloud/android/pull/4759)
* Enhancement - QA Content Provider: [#4776](https://github.com/owncloud/android/pull/4776)
Expand Down Expand Up @@ -161,10 +162,12 @@ ownCloud admins and users.
https://github.com/owncloud/android/issues/4612
https://github.com/owncloud/android/issues/4763
https://github.com/owncloud/android/issues/4772
https://github.com/owncloud/android/issues/4782
https://github.com/owncloud/android/pull/4728
https://github.com/owncloud/android/pull/4765
https://github.com/owncloud/android/pull/4779
https://github.com/owncloud/android/pull/4784
https://github.com/owncloud/android/pull/4809

* Enhancement - Add a member to a space: [#4613](https://github.com/owncloud/android/issues/4613)

Expand Down Expand Up @@ -227,6 +230,14 @@ ownCloud admins and users.
https://github.com/owncloud/android/issues/4753
https://github.com/owncloud/android/pull/4794

* Enhancement - Remove space link: [#4757](https://github.com/owncloud/android/issues/4757)

A new option to remove space public links from a space has been added. It will
be only visible for users with proper permissions.

https://github.com/owncloud/android/issues/4757
https://github.com/owncloud/android/pull/4816

* Enhancement - Copy permanent link of a space: [#4758](https://github.com/owncloud/android/issues/4758)

A new option to copy and share the permanent link of a space has been added next
Expand Down
6 changes: 6 additions & 0 deletions changelog/unreleased/4816
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: Remove space link

A new option to remove space public links from a space has been added. It will be only visible for users with proper permissions.

https://github.com/owncloud/android/issues/4757
https://github.com/owncloud/android/pull/4816
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ import com.owncloud.android.domain.files.usecases.SortFilesUseCase
import com.owncloud.android.domain.files.usecases.SortFilesWithSyncInfoUseCase
import com.owncloud.android.domain.files.usecases.UpdateAlreadyDownloadedFilesPathUseCase
import com.owncloud.android.domain.links.usecases.AddLinkUseCase
import com.owncloud.android.domain.links.usecases.RemoveLinkUseCase
import com.owncloud.android.domain.members.usecases.AddMemberUseCase
import com.owncloud.android.domain.members.usecases.EditMemberUseCase
import com.owncloud.android.domain.members.usecases.RemoveMemberUseCase
Expand Down Expand Up @@ -320,4 +321,5 @@ val useCaseModule = module {

// Links
factoryOf(::AddLinkUseCase)
factoryOf(::RemoveLinkUseCase)
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class SpaceLinksAdapter(
): RecyclerView.Adapter<SpaceLinksAdapter.SpaceLinksViewHolder>() {

private var spaceLinks: List<OCLink> = emptyList()
private var canRemoveLinks = false

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SpaceLinksViewHolder {
val inflater = LayoutInflater.from(parent.context)
Expand Down Expand Up @@ -69,12 +70,21 @@ class SpaceLinksAdapter(
listener.onCopyOrSendPublicLink(spaceLink.webUrl)
}
}

removePublicLinkButton.apply {
contentDescription = holder.itemView.context.getString(R.string.content_description_delete_public_link, spaceLink.displayName)
isVisible = canRemoveLinks
setOnClickListener {
listener.onRemovePublicLink(spaceLink.id, spaceLink.displayName)
}
}
}
}

override fun getItemCount(): Int = spaceLinks.size

fun setSpaceLinks(spaceLinks: List<OCLink>) {
fun setSpaceLinks(spaceLinks: List<OCLink>, canRemoveLinks: Boolean) {
this.canRemoveLinks = canRemoveLinks
val diffCallback = SpaceLinksDiffUtil(this.spaceLinks, spaceLinks)
val diffResult = DiffUtil.calculateDiff(diffCallback)
this.spaceLinks = spaceLinks
Expand All @@ -87,5 +97,6 @@ class SpaceLinksAdapter(

interface SpaceLinksAdapterListener {
fun onCopyOrSendPublicLink(publicLinkUrl: String)
fun onRemovePublicLink(publicLinkId: String, publicLinkDisplayName: String)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,21 @@ package com.owncloud.android.presentation.spaces.links
import androidx.lifecycle.ViewModel
import com.owncloud.android.domain.links.model.OCLinkType
import com.owncloud.android.domain.links.usecases.AddLinkUseCase
import com.owncloud.android.domain.links.usecases.RemoveLinkUseCase
import com.owncloud.android.domain.spaces.model.OCSpace
import com.owncloud.android.domain.utils.Event
import com.owncloud.android.extensions.ViewModelExt.runUseCaseWithResult
import com.owncloud.android.presentation.common.UIResult
import com.owncloud.android.providers.CoroutinesDispatcherProvider
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update

class SpaceLinksViewModel(
private val addLinkUseCase: AddLinkUseCase,
private val removeLinkUseCase: RemoveLinkUseCase,
private val accountName: String,
private val space: OCSpace,
private val coroutineDispatcherProvider: CoroutinesDispatcherProvider
Expand All @@ -45,6 +49,9 @@ class SpaceLinksViewModel(
private val _addLinkResultFlow = MutableStateFlow<Event<UIResult<Unit>>?>(null)
val addLinkResultFlow: StateFlow<Event<UIResult<Unit>>?> = _addLinkResultFlow

private val _removeLinkResultFlow = MutableSharedFlow<UIResult<Unit>>()
val removeLinkResultFlow: SharedFlow<UIResult<Unit>> = _removeLinkResultFlow

init {
_addPublicLinkUIState.value = AddPublicLinkUIState()
}
Expand Down Expand Up @@ -79,6 +86,19 @@ class SpaceLinksViewModel(
}
}

fun removePublicLink(linkId: String) {
runUseCaseWithResult(
coroutineDispatcher = coroutineDispatcherProvider.io,
sharedFlow = _removeLinkResultFlow,
useCase = removeLinkUseCase,
useCaseParams = RemoveLinkUseCase.Params(
accountName = accountName,
spaceId = space.id,
linkId = linkId
)
)
}

fun resetViewModel() {
_addLinkResultFlow.value = null
_addPublicLinkUIState.value = AddPublicLinkUIState()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package com.owncloud.android.presentation.spaces.members

import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
Expand All @@ -38,6 +39,7 @@ import com.owncloud.android.domain.spaces.model.OCSpace
import com.owncloud.android.domain.spaces.model.SpaceMember
import com.owncloud.android.extensions.avoidScreenshotsIfNeeded
import com.owncloud.android.extensions.collectLatestLifecycleFlow
import com.owncloud.android.extensions.showAlertDialog
import com.owncloud.android.extensions.showErrorInSnackbar
import com.owncloud.android.extensions.showMessageInSnackbar
import com.owncloud.android.presentation.common.UIResult
Expand Down Expand Up @@ -77,7 +79,7 @@ class SpaceMembersFragment : Fragment(), SpaceMembersAdapter.SpaceMembersAdapter
private var addMemberRoles: List<OCRole> = emptyList()
private var spaceMembers: List<SpaceMember> = emptyList()
private var listener: SpaceMemberFragmentListener? = null
private var canRemoveMembers = false
private var canRemoveMembersAndLinks = false
private var canEditMembers = false
private var canReadMembers = false
private var numberOfManagers = 1
Expand All @@ -104,7 +106,7 @@ class SpaceMembersFragment : Fragment(), SpaceMembersAdapter.SpaceMembersAdapter

currentSpace = requireArguments().getParcelable<OCSpace>(ARG_CURRENT_SPACE) ?: return
savedInstanceState?.let {
canRemoveMembers = it.getBoolean(CAN_REMOVE_MEMBERS, false)
canRemoveMembersAndLinks = it.getBoolean(CAN_REMOVE_MEMBERS, false)
canEditMembers = it.getBoolean(CAN_EDIT_MEMBERS, false)
canReadMembers = it.getBoolean(CAN_READ_MEMBERS, false)
}
Expand Down Expand Up @@ -150,7 +152,7 @@ class SpaceMembersFragment : Fragment(), SpaceMembersAdapter.SpaceMembersAdapter

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putBoolean(CAN_REMOVE_MEMBERS, canRemoveMembers)
outState.putBoolean(CAN_REMOVE_MEMBERS, canRemoveMembersAndLinks)
outState.putBoolean(CAN_EDIT_MEMBERS, canEditMembers)
outState.putBoolean(CAN_READ_MEMBERS, canReadMembers)
}
Expand Down Expand Up @@ -180,6 +182,16 @@ class SpaceMembersFragment : Fragment(), SpaceMembersAdapter.SpaceMembersAdapter
listener?.copyOrSendPublicLink(publicLinkUrl, currentSpace.name)
}

override fun onRemovePublicLink(publicLinkId: String, publicLinkDisplayName: String) {
showAlertDialog(
title = getString(R.string.public_link_remove_dialog_title, publicLinkDisplayName),
message = getString(R.string.public_link_remove_dialog_message),
positiveButtonText = getString(R.string.common_yes),
positiveButtonListener = { _: DialogInterface?, _: Int -> spaceLinksViewModel.removePublicLink(publicLinkId) },
negativeButtonText = getString(R.string.common_no)
)
}

private fun subscribeToViewModels() {
observeRoles()
observeSpaceMembers()
Expand All @@ -188,6 +200,7 @@ class SpaceMembersFragment : Fragment(), SpaceMembersAdapter.SpaceMembersAdapter
observeRemoveMemberResult()
observeEditMemberResult()
observeAddLinkResult()
observeRemoveLinkResult()
}

private fun observeRoles() {
Expand Down Expand Up @@ -221,7 +234,13 @@ class SpaceMembersFragment : Fragment(), SpaceMembersAdapter.SpaceMembersAdapter
spaceMembers = it.members
addMemberRoles = it.roles
if (canReadMembers) {
spaceMembersAdapter.setSpaceMembers(spaceMembers, roles, canRemoveMembers, canEditMembers, numberOfManagers)
spaceMembersAdapter.setSpaceMembers(
spaceMembers = spaceMembers,
roles = roles,
canRemoveMembers = canRemoveMembersAndLinks,
canEditMembers = canEditMembers,
numberOfManagers = numberOfManagers
)
val hasLinks = it.links.isNotEmpty()
showOrHideEmptyView(hasLinks)
if (hasLinks) { showSpaceLinks(it.links) }
Expand All @@ -248,7 +267,13 @@ class SpaceMembersFragment : Fragment(), SpaceMembersAdapter.SpaceMembersAdapter
uiResult.data?.let { spacePermissions ->
checkPermissions(spacePermissions)
if (canReadMembers) {
spaceMembersAdapter.setSpaceMembers(spaceMembers, roles, canRemoveMembers, canEditMembers, numberOfManagers)
spaceMembersAdapter.setSpaceMembers(
spaceMembers = spaceMembers,
roles = roles,
canRemoveMembers = canRemoveMembersAndLinks,
canEditMembers = canEditMembers,
numberOfManagers = numberOfManagers
)
}
}
}
Expand Down Expand Up @@ -322,9 +347,25 @@ class SpaceMembersFragment : Fragment(), SpaceMembersAdapter.SpaceMembersAdapter
}
}

private fun observeRemoveLinkResult() {
collectLatestLifecycleFlow(spaceLinksViewModel.removeLinkResultFlow) { uiResult ->
when (uiResult) {
is UIResult.Loading -> { }
is UIResult.Success -> {
showMessageInSnackbar(getString(R.string.public_link_remove_correctly))
spaceMembersViewModel.getSpaceMembers()
}
is UIResult.Error -> {
Timber.e(uiResult.error, "Failed to remove a public link from space: ${currentSpace.id}")
showErrorInSnackbar(R.string.public_link_remove_failed, uiResult.error)
}
}
}
}

private fun checkPermissions(spacePermissions: List<String>) {
val hasCreatePermission = DRIVES_CREATE_PERMISSION in spacePermissions
canRemoveMembers = DRIVES_DELETE_PERMISSION in spacePermissions
canRemoveMembersAndLinks = DRIVES_DELETE_PERMISSION in spacePermissions
canEditMembers = DRIVES_UPDATE_PERMISSION in spacePermissions
canReadMembers = DRIVES_READ_PERMISSION in spacePermissions
binding.apply {
Expand All @@ -346,13 +387,16 @@ class SpaceMembersFragment : Fragment(), SpaceMembersAdapter.SpaceMembersAdapter
val formatter = SimpleDateFormat(DisplayUtils.DATE_FORMAT_ISO, Locale.ROOT).apply {
timeZone = TimeZone.getTimeZone("UTC")
}
spaceLinksAdapter.setSpaceLinks(spaceLinks.sortedByDescending { spaceLink ->
if (spaceLink.createdDateTime.isNotEmpty()) {
formatter.parse(spaceLink.createdDateTime)
} else {
Date(0)
}
})
spaceLinksAdapter.setSpaceLinks(
spaceLinks = spaceLinks.sortedByDescending { spaceLink ->
if (spaceLink.createdDateTime.isNotEmpty()) {
formatter.parse(spaceLink.createdDateTime)
} else {
Date(0)
}
},
canRemoveLinks = canRemoveMembersAndLinks
)
}

interface SpaceMemberFragmentListener {
Expand Down
15 changes: 14 additions & 1 deletion owncloudApp/src/main/res/layout/public_link_item.xml
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,27 @@
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="@dimen/standard_half_margin"
android:layout_marginEnd="@dimen/standard_margin"
android:layout_marginEnd="@dimen/standard_half_margin"
android:scaleType="centerCrop"
android:padding="@dimen/standard_half_padding"
android:background="?android:attr/selectableItemBackground"
android:focusable="true"
android:src="@drawable/copy_link"
android:visibility="visible"/>

<ImageButton
android:id="@+id/remove_public_link_button"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/standard_half_margin"
android:padding="@dimen/standard_half_padding"
android:background="?android:attr/selectableItemBackground"
android:focusable="true"
android:src="@drawable/ic_action_delete_grey"
android:visibility="gone"
tools:visibility="visible" />

</LinearLayout>

<View
Expand Down
4 changes: 4 additions & 0 deletions owncloudApp/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,10 @@
<string name="public_link_default_display_name">Unnamed Link</string>
<string name="public_link_add_correctly">Public link created correctly</string>
<string name="public_link_add_failed">Public link could not be created</string>
<string name="public_link_remove_dialog_title">Do you really want to remove the link: %1$s?</string>
<string name="public_link_remove_dialog_message">Recreating the same link again is not possible</string>
<string name="public_link_remove_correctly">Public link removed correctly</string>
<string name="public_link_remove_failed">Public link could not be removed</string>

<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>

Expand Down
Loading
Loading