diff --git a/.github/workflows/autoApproveDependabot.yml b/.github/workflows/autoApproveDependabot.yml
new file mode 100644
index 000000000000..72f564f8bb71
--- /dev/null
+++ b/.github/workflows/autoApproveDependabot.yml
@@ -0,0 +1,11 @@
+name: Auto approve
+on: pull_request
+
+jobs:
+ auto-approve:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: hmarr/auto-approve-action@v2.0.0
+ if: github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]'
+ with:
+ github-token: "${{ secrets.DEPENDABOT_AUTOMERGE_TOKEN }}"
diff --git a/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showDetailsSharing.png b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showDetailsSharing.png
new file mode 100644
index 000000000000..cfa849fe3c0b
Binary files /dev/null and b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showDetailsSharing.png differ
diff --git a/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showFileDetailSharingFragment.png b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showFileDetailSharingFragment.png
index f3f1f6315e71..7423f57ced0b 100644
Binary files a/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showFileDetailSharingFragment.png and b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailFragmentStaticServerIT_showFileDetailSharingFragment.png differ
diff --git a/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileAllShareTypes.png b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileAllShareTypes.png
new file mode 100644
index 000000000000..c9634d7fc223
Binary files /dev/null and b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileAllShareTypes.png differ
diff --git a/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileNone.png b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileNone.png
new file mode 100644
index 000000000000..eed7aa4f5556
Binary files /dev/null and b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileNone.png differ
diff --git a/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileResharingNotAllowed.png b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileResharingNotAllowed.png
new file mode 100644
index 000000000000..7423f57ced0b
Binary files /dev/null and b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listSharesFileResharingNotAllowed.png differ
diff --git a/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listShares_file_allShareTypes.png b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listShares_file_allShareTypes.png
new file mode 100644
index 000000000000..c9634d7fc223
Binary files /dev/null and b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listShares_file_allShareTypes.png differ
diff --git a/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listShares_file_none.png b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listShares_file_none.png
new file mode 100644
index 000000000000..eed7aa4f5556
Binary files /dev/null and b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listShares_file_none.png differ
diff --git a/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listShares_file_resharing_not_allowed.png b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listShares_file_resharing_not_allowed.png
new file mode 100644
index 000000000000..7423f57ced0b
Binary files /dev/null and b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_listShares_file_resharing_not_allowed.png differ
diff --git a/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_publicLink_optionMenu.png b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_publicLink_optionMenu.png
new file mode 100644
index 000000000000..eed7aa4f5556
Binary files /dev/null and b/screenshots/gplay/debug/com.owncloud.android.ui.fragment.FileDetailSharingFragmentIT_publicLink_optionMenu.png differ
diff --git a/scripts/analysis/findbugs-results.txt b/scripts/analysis/findbugs-results.txt
index 18eed1357e5c..ab760c939afd 100644
--- a/scripts/analysis/findbugs-results.txt
+++ b/scripts/analysis/findbugs-results.txt
@@ -1 +1 @@
-320
+319
\ No newline at end of file
diff --git a/scripts/analysis/lint-results.txt b/scripts/analysis/lint-results.txt
index 89df7437f06f..31824795b1a7 100644
--- a/scripts/analysis/lint-results.txt
+++ b/scripts/analysis/lint-results.txt
@@ -1,2 +1,2 @@
DO NOT TOUCH; GENERATED BY DRONE
- Lint Report: 81 warnings
+ Lint Report: 80 warnings
diff --git a/src/androidTest/java/com/nextcloud/client/FileDisplayActivityIT.java b/src/androidTest/java/com/nextcloud/client/FileDisplayActivityIT.java
index 353d2daa1f0b..186cfb78461c 100644
--- a/src/androidTest/java/com/nextcloud/client/FileDisplayActivityIT.java
+++ b/src/androidTest/java/com/nextcloud/client/FileDisplayActivityIT.java
@@ -97,7 +97,7 @@ public void showShares() {
"users",
false,
"",
- OCShare.DEFAULT_PERMISSION)
+ OCShare.NO_PERMISSION)
.execute(client).isSuccess());
// share folder to circle
diff --git a/src/androidTest/java/com/owncloud/android/AbstractIT.java b/src/androidTest/java/com/owncloud/android/AbstractIT.java
index 5569a3555365..8796e0c39662 100644
--- a/src/androidTest/java/com/owncloud/android/AbstractIT.java
+++ b/src/androidTest/java/com/owncloud/android/AbstractIT.java
@@ -58,6 +58,7 @@
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID;
import static org.junit.Assert.assertTrue;
@@ -96,7 +97,7 @@ public static void beforeAll() {
Account temp = new Account("test@https://server.com", MainApp.getAccountType(targetContext));
platformAccountManager.addAccountExplicitly(temp, "password", null);
platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_OC_BASE_URL, "https://server.com");
- platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_USER_ID, "test");
+ platformAccountManager.setUserData(temp, KEY_USER_ID, "test");
final UserAccountManager userAccountManager = UserAccountManagerImpl.fromContext(targetContext);
account = userAccountManager.getAccountByName("test@https://server.com");
@@ -381,4 +382,8 @@ private String createName() {
return name;
}
+
+ public static String getUserId(User user) {
+ return AccountManager.get(targetContext).getUserData(user.toPlatformAccount(), KEY_USER_ID);
+ }
}
diff --git a/src/androidTest/java/com/owncloud/android/authentication/AuthenticatorActivityIT.kt b/src/androidTest/java/com/owncloud/android/authentication/AuthenticatorActivityIT.kt
index 63c9721f4c7f..c12d8ed10d2f 100644
--- a/src/androidTest/java/com/owncloud/android/authentication/AuthenticatorActivityIT.kt
+++ b/src/androidTest/java/com/owncloud/android/authentication/AuthenticatorActivityIT.kt
@@ -32,6 +32,7 @@ class AuthenticatorActivityIT {
}
@Test
+ @Suppress("TooGenericExceptionCaught")
fun tryCatch() {
val color = try {
Color.parseColor("1")
@@ -43,6 +44,7 @@ class AuthenticatorActivityIT {
}
@Test
+ @Suppress("TooGenericExceptionCaught")
fun tryCatch2() {
val color = try {
Color.parseColor("")
@@ -54,6 +56,7 @@ class AuthenticatorActivityIT {
}
@Test
+ @Suppress("TooGenericExceptionCaught")
fun tryCatch3() {
val color = try {
Color.parseColor(null)
@@ -65,6 +68,7 @@ class AuthenticatorActivityIT {
}
@Test
+ @Suppress("TooGenericExceptionCaught")
fun tryCatch4() {
val color = try {
Color.parseColor("abc")
diff --git a/src/androidTest/java/com/owncloud/android/datamodel/OCFileUnitTest.java b/src/androidTest/java/com/owncloud/android/datamodel/OCFileUnitTest.java
index 4f7f6e194570..5965906ab4d0 100644
--- a/src/androidTest/java/com/owncloud/android/datamodel/OCFileUnitTest.java
+++ b/src/androidTest/java/com/owncloud/android/datamodel/OCFileUnitTest.java
@@ -88,7 +88,6 @@ public void writeThenReadAsParcelable() {
mFile.setEtag(ETAG);
mFile.setSharedViaLink(true);
mFile.setSharedWithSharee(true);
- mFile.setPublicLink(PUBLIC_LINK);
mFile.setPermissions(PERMISSIONS);
mFile.setRemoteId(REMOTE_ID);
mFile.setUpdateThumbnailNeeded(true);
@@ -122,7 +121,6 @@ public void writeThenReadAsParcelable() {
assertThat(fileReadFromParcel.getEtag(), is(ETAG));
assertThat(fileReadFromParcel.isSharedViaLink(), is(true));
assertThat(fileReadFromParcel.isSharedWithSharee(), is(true));
- assertThat(fileReadFromParcel.getPublicLink(), is(PUBLIC_LINK));
assertThat(fileReadFromParcel.getPermissions(), is(PERMISSIONS));
assertThat(fileReadFromParcel.getRemoteId(), is(REMOTE_ID));
assertThat(fileReadFromParcel.isUpdateThumbnailNeeded(), is(true));
diff --git a/src/androidTest/java/com/owncloud/android/ui/fragment/AvatarIT.kt b/src/androidTest/java/com/owncloud/android/ui/fragment/AvatarIT.kt
index 82a34689f3a2..8ec894730ab5 100644
--- a/src/androidTest/java/com/owncloud/android/ui/fragment/AvatarIT.kt
+++ b/src/androidTest/java/com/owncloud/android/ui/fragment/AvatarIT.kt
@@ -40,7 +40,7 @@ class AvatarIT : AbstractIT() {
@ScreenshotTest
fun showAvatars() {
val avatarRadius = targetContext.resources.getDimension(R.dimen.list_item_avatar_icon_radius)
- val width = DisplayUtils.convertDpToPixel(40f, targetContext)
+ val width = DisplayUtils.convertDpToPixel(2 * avatarRadius, targetContext)
val sut = testActivityRule.launchActivity(null)
val fragment = AvatarTestFragment()
@@ -56,6 +56,7 @@ class AvatarIT : AbstractIT() {
fragment.addAvatar("email@server.com", avatarRadius, width, targetContext)
}
+ shortSleep()
waitForIdleSync()
screenshot(sut)
}
diff --git a/src/androidTest/java/com/owncloud/android/ui/fragment/AvatarTestFragment.kt b/src/androidTest/java/com/owncloud/android/ui/fragment/AvatarTestFragment.kt
index 70e14687c6bd..b6913983b766 100644
--- a/src/androidTest/java/com/owncloud/android/ui/fragment/AvatarTestFragment.kt
+++ b/src/androidTest/java/com/owncloud/android/ui/fragment/AvatarTestFragment.kt
@@ -45,7 +45,7 @@ internal class AvatarTestFragment : Fragment() {
}
fun addAvatar(name: String, avatarRadius: Float, width: Int, targetContext: Context) {
- val margin = 10
+ val margin = padding
val imageView = ImageView(targetContext)
imageView.setImageDrawable(TextDrawable.createNamedAvatar(name, avatarRadius))
@@ -56,4 +56,8 @@ internal class AvatarTestFragment : Fragment() {
list.addView(imageView)
}
+
+ companion object {
+ private const val padding = 10
+ }
}
diff --git a/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailFragmentStaticServerIT.kt b/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailFragmentStaticServerIT.kt
index 671fa6631454..0d5757d3de9e 100644
--- a/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailFragmentStaticServerIT.kt
+++ b/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailFragmentStaticServerIT.kt
@@ -172,7 +172,7 @@ class FileDetailFragmentStaticServerIT : AbstractIT() {
@Test
@ScreenshotTest
- fun showDetails_Sharing() {
+ fun showDetailsSharing() {
val sut = testActivityRule.launchActivity(null)
sut.addFragment(FileDetailFragment.newInstance(file, user, 1))
diff --git a/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailSharingFragmentIT.kt b/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailSharingFragmentIT.kt
new file mode 100644
index 000000000000..c644ed8bfe85
--- /dev/null
+++ b/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailSharingFragmentIT.kt
@@ -0,0 +1,630 @@
+/*
+ *
+ * Nextcloud Android client application
+ *
+ * @author Tobias Kaminsky
+ * Copyright (C) 2020 Tobias Kaminsky
+ * Copyright (C) 2020 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 .
+ */
+package com.owncloud.android.ui.fragment
+
+import android.Manifest
+import android.widget.ImageView
+import androidx.appcompat.widget.PopupMenu
+import androidx.test.espresso.intent.rule.IntentsTestRule
+import androidx.test.rule.GrantPermissionRule
+import com.nextcloud.client.TestActivity
+import com.owncloud.android.AbstractIT
+import com.owncloud.android.R
+import com.owncloud.android.datamodel.OCFile
+import com.owncloud.android.lib.resources.shares.OCShare
+import com.owncloud.android.lib.resources.shares.OCShare.CREATE_PERMISSION_FLAG
+import com.owncloud.android.lib.resources.shares.OCShare.DELETE_PERMISSION_FLAG
+import com.owncloud.android.lib.resources.shares.OCShare.MAXIMUM_PERMISSIONS_FOR_FILE
+import com.owncloud.android.lib.resources.shares.OCShare.MAXIMUM_PERMISSIONS_FOR_FOLDER
+import com.owncloud.android.lib.resources.shares.OCShare.NO_PERMISSION
+import com.owncloud.android.lib.resources.shares.OCShare.READ_PERMISSION_FLAG
+import com.owncloud.android.lib.resources.shares.OCShare.SHARE_PERMISSION_FLAG
+import com.owncloud.android.lib.resources.shares.ShareType
+import com.owncloud.android.utils.ScreenshotTest
+import org.junit.After
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+class FileDetailSharingFragmentIT : AbstractIT() {
+ @get:Rule
+ val testActivityRule = IntentsTestRule(TestActivity::class.java, true, false)
+
+ @get:Rule
+ val permissionRule: GrantPermissionRule = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE)
+
+ lateinit var file: OCFile
+ lateinit var folder: OCFile
+ lateinit var activity: TestActivity
+
+ @Before
+ fun before() {
+ activity = testActivityRule.launchActivity(null)
+ file = OCFile("/test.md").apply {
+ parentId = activity.storageManager.getFileByEncryptedRemotePath("/").fileId
+ permissions = OCFile.PERMISSION_CAN_RESHARE
+ }
+
+ folder = OCFile("/test").apply {
+ setFolder()
+ parentId = activity.storageManager.getFileByEncryptedRemotePath("/").fileId
+ permissions = OCFile.PERMISSION_CAN_RESHARE
+ }
+ }
+
+ @Test
+ @ScreenshotTest
+ fun listSharesFileNone() {
+ show(file)
+ }
+
+ @Test
+ @ScreenshotTest
+ fun listSharesFileResharingNotAllowed() {
+ file.permissions = ""
+
+ show(file)
+ }
+
+ @Test
+ @ScreenshotTest
+ @Suppress("MagicNumber")
+ fun listSharesFileAllShareTypes() {
+ OCShare(file.decryptedRemotePath).apply {
+ remoteId = 1
+ shareType = ShareType.USER
+ sharedWithDisplayName = "Admin"
+ permissions = MAXIMUM_PERMISSIONS_FOR_FILE
+ userId = getUserId(user)
+ activity.storageManager.saveShare(this)
+ }
+
+ OCShare(file.decryptedRemotePath).apply {
+ remoteId = 2
+ shareType = ShareType.GROUP
+ sharedWithDisplayName = "Group"
+ permissions = MAXIMUM_PERMISSIONS_FOR_FILE
+ userId = getUserId(user)
+ activity.storageManager.saveShare(this)
+ }
+
+ OCShare(file.decryptedRemotePath).apply {
+ remoteId = 3
+ shareType = ShareType.EMAIL
+ sharedWithDisplayName = "admin@nextcloud.server.com"
+ userId = getUserId(user)
+ activity.storageManager.saveShare(this)
+ }
+
+ OCShare(file.decryptedRemotePath).apply {
+ remoteId = 4
+ shareType = ShareType.PUBLIC_LINK
+ sharedWithDisplayName = "Customer"
+ activity.storageManager.saveShare(this)
+ }
+
+ OCShare(file.decryptedRemotePath).apply {
+ remoteId = 5
+ shareType = ShareType.PUBLIC_LINK
+ sharedWithDisplayName = "Colleagues"
+ activity.storageManager.saveShare(this)
+ }
+
+ OCShare(file.decryptedRemotePath).apply {
+ remoteId = 6
+ shareType = ShareType.FEDERATED
+ sharedWithDisplayName = "admin@nextcloud.remoteserver.com"
+ permissions = OCShare.FEDERATED_PERMISSIONS_FOR_FILE
+ userId = getUserId(user)
+ activity.storageManager.saveShare(this)
+ }
+
+ OCShare(file.decryptedRemotePath).apply {
+ remoteId = 7
+ shareType = ShareType.CIRCLE
+ sharedWithDisplayName = "Private circle"
+ permissions = SHARE_PERMISSION_FLAG
+ userId = getUserId(user)
+ activity.storageManager.saveShare(this)
+ }
+
+ OCShare(file.decryptedRemotePath).apply {
+ remoteId = 8
+ shareType = ShareType.ROOM
+ sharedWithDisplayName = "Meeting"
+ permissions = SHARE_PERMISSION_FLAG
+ userId = getUserId(user)
+ activity.storageManager.saveShare(this)
+ }
+
+ show(file)
+ }
+
+ private fun show(file: OCFile) {
+ val fragment = FileDetailSharingFragment.newInstance(file, user)
+
+ activity.addFragment(fragment)
+
+ waitForIdleSync()
+
+ screenshot(activity)
+ }
+
+ @Test
+ @Suppress("MagicNumber")
+ // public link and email are handled the same way
+ fun publicLinkOptionMenuFolder() {
+ val sut = FileDetailSharingFragment.newInstance(file, user)
+ activity.addFragment(sut)
+ shortSleep()
+ sut.refreshCapabilitiesFromDB()
+
+ val overflowMenuShareLink = ImageView(targetContext)
+ val popup = PopupMenu(targetContext, overflowMenuShareLink)
+ popup.inflate(R.menu.fragment_file_detail_sharing_public_link)
+ val publicShare = OCShare().apply {
+ isFolder = true
+ shareType = ShareType.PUBLIC_LINK
+ permissions = 17
+ }
+
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+
+ // check if items are visible
+ assertTrue(popup.menu.findItem(R.id.action_hide_file_download).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_password).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_share_expiration_date).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_share_send_link).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_share_send_note).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_edit_label).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_unshare).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_add_another_public_share_link).isVisible)
+
+ // read-only
+ assertTrue(popup.menu.findItem(R.id.link_share_read_only).isChecked)
+ assertFalse(popup.menu.findItem(R.id.link_share_allow_upload_and_editing).isChecked)
+ assertFalse(popup.menu.findItem(R.id.link_share_file_drop).isChecked)
+
+ // upload and editing
+ publicShare.permissions = MAXIMUM_PERMISSIONS_FOR_FOLDER
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertFalse(popup.menu.findItem(R.id.link_share_read_only).isChecked)
+ assertTrue(popup.menu.findItem(R.id.link_share_allow_upload_and_editing).isChecked)
+ assertFalse(popup.menu.findItem(R.id.link_share_file_drop).isChecked)
+
+ // file drop
+ publicShare.permissions = 4
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertFalse(popup.menu.findItem(R.id.link_share_read_only).isChecked)
+ assertFalse(popup.menu.findItem(R.id.link_share_allow_upload_and_editing).isChecked)
+ assertTrue(popup.menu.findItem(R.id.link_share_file_drop).isChecked)
+
+ // password protection
+ publicShare.shareWith = "someValue"
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_password).title == targetContext.getString(R.string.share_password_title)
+ )
+
+ publicShare.shareWith = ""
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_password).title == targetContext.getString(R.string.share_no_password_title)
+ )
+
+ // hide download
+ publicShare.isHideFileDownload = true
+ publicShare.permissions = MAXIMUM_PERMISSIONS_FOR_FOLDER
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(popup.menu.findItem(R.id.action_hide_file_download).isChecked)
+
+ publicShare.isHideFileDownload = false
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertFalse(popup.menu.findItem(R.id.action_hide_file_download).isChecked)
+
+ publicShare.expirationDate = 1582019340000
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_share_expiration_date).title
+ .startsWith(targetContext.getString(R.string.share_expiration_date_label).split(" ")[0])
+ )
+
+ publicShare.expirationDate = 0
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_share_expiration_date).title ==
+ targetContext.getString(R.string.share_no_expiration_date_label)
+ )
+
+ // file
+ publicShare.isFolder = false
+ publicShare.permissions = READ_PERMISSION_FLAG
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ // check if items are visible
+ assertTrue(popup.menu.findItem(R.id.action_hide_file_download).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_password).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_share_expiration_date).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_share_send_link).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_share_send_note).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_edit_label).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_unshare).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_add_another_public_share_link).isVisible)
+
+ assertFalse(popup.menu.findItem(R.id.link_share_read_only).isVisible)
+ assertFalse(popup.menu.findItem(R.id.link_share_allow_upload_and_editing).isVisible)
+ assertFalse(popup.menu.findItem(R.id.link_share_file_drop).isVisible)
+ assertTrue(popup.menu.findItem(R.id.allow_editing).isVisible)
+
+ // allow editing
+ publicShare.permissions = 17 // from server
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertFalse(popup.menu.findItem(R.id.allow_editing).isChecked)
+
+ publicShare.permissions = 19 // from server
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(popup.menu.findItem(R.id.allow_editing).isChecked)
+
+ // hide download
+ publicShare.isHideFileDownload = true
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(popup.menu.findItem(R.id.action_hide_file_download).isChecked)
+
+ publicShare.isHideFileDownload = false
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertFalse(popup.menu.findItem(R.id.action_hide_file_download).isChecked)
+
+ // password protection
+ publicShare.isPasswordProtected = true
+ publicShare.shareWith = "someValue"
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_password).title == targetContext.getString(R.string.share_password_title)
+ )
+
+ publicShare.isPasswordProtected = false
+ publicShare.shareWith = ""
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_password).title == targetContext.getString(R.string.share_no_password_title)
+ )
+
+ // expires
+ publicShare.expirationDate = 1582019340
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_share_expiration_date).title
+ .startsWith(targetContext.getString(R.string.share_expiration_date_label).split(" ")[0])
+ )
+
+ publicShare.expirationDate = 0
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_share_expiration_date).title ==
+ targetContext.getString(R.string.share_no_expiration_date_label)
+ )
+ }
+
+ @Test
+ @Suppress("MagicNumber")
+ // public link and email are handled the same way
+ fun publicLinkOptionMenuFile() {
+ val sut = FileDetailSharingFragment.newInstance(file, user)
+ activity.addFragment(sut)
+ shortSleep()
+ sut.refreshCapabilitiesFromDB()
+
+ val overflowMenuShareLink = ImageView(targetContext)
+ val popup = PopupMenu(targetContext, overflowMenuShareLink)
+ popup.inflate(R.menu.fragment_file_detail_sharing_public_link)
+ val publicShare = OCShare().apply {
+ isFolder = false
+ shareType = ShareType.PUBLIC_LINK
+ permissions = 17
+ }
+
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+
+ // check if items are visible
+ assertTrue(popup.menu.findItem(R.id.action_hide_file_download).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_password).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_share_expiration_date).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_share_send_link).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_share_send_note).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_edit_label).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_unshare).isVisible)
+ assertTrue(popup.menu.findItem(R.id.action_add_another_public_share_link).isVisible)
+
+ assertFalse(popup.menu.findItem(R.id.link_share_read_only).isVisible)
+ assertFalse(popup.menu.findItem(R.id.link_share_allow_upload_and_editing).isVisible)
+ assertFalse(popup.menu.findItem(R.id.link_share_file_drop).isVisible)
+ assertTrue(popup.menu.findItem(R.id.allow_editing).isVisible)
+
+ // password protection
+ publicShare.shareWith = "someValue"
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_password).title == targetContext.getString(R.string.share_password_title)
+ )
+
+ publicShare.shareWith = ""
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_password).title == targetContext.getString(R.string.share_no_password_title)
+ )
+
+ // hide download
+ publicShare.isHideFileDownload = true
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(popup.menu.findItem(R.id.action_hide_file_download).isChecked)
+
+ publicShare.isHideFileDownload = false
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertFalse(popup.menu.findItem(R.id.action_hide_file_download).isChecked)
+
+ // expiration date
+ publicShare.expirationDate = 1582019340000
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_share_expiration_date).title
+ .startsWith(targetContext.getString(R.string.share_expiration_date_label).split(" ")[0])
+ )
+
+ publicShare.expirationDate = 0
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_share_expiration_date).title ==
+ targetContext.getString(R.string.share_no_expiration_date_label)
+ )
+
+ publicShare.isFolder = false
+ publicShare.permissions = READ_PERMISSION_FLAG
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+
+ // allow editing
+ publicShare.permissions = 17 // from server
+ assertFalse(popup.menu.findItem(R.id.allow_editing).isChecked)
+
+ publicShare.permissions = 19 // from server
+ sut.prepareLinkOptionsMenu(popup.menu, publicShare)
+ assertTrue(popup.menu.findItem(R.id.allow_editing).isChecked)
+ }
+
+ @Test
+ @Suppress("MagicNumber")
+ // also applies for
+ // group
+ // conversation
+ // circle
+ // federated share
+ fun userOptionMenuFile() {
+ val sut = FileDetailSharingFragment.newInstance(file, user)
+ activity.addFragment(sut)
+ shortSleep()
+ sut.refreshCapabilitiesFromDB()
+
+ val overflowMenuShareLink = ImageView(targetContext)
+ val popup = PopupMenu(targetContext, overflowMenuShareLink)
+ popup.inflate(R.menu.item_user_sharing_settings)
+ val userShare = OCShare().apply {
+ isFolder = false
+ shareType = ShareType.USER
+ permissions = 17
+ }
+
+ sut.prepareUserOptionsMenu(popup.menu, userShare)
+ assertFalse(popup.menu.findItem(R.id.allow_creating).isVisible)
+ assertFalse(popup.menu.findItem(R.id.allow_deleting).isVisible)
+
+ // allow editing
+ userShare.permissions = 17 // from server
+ assertFalse(popup.menu.findItem(R.id.allow_editing).isChecked)
+
+ userShare.permissions = 19 // from server
+ sut.prepareUserOptionsMenu(popup.menu, userShare)
+ assertTrue(popup.menu.findItem(R.id.allow_editing).isChecked)
+
+ // allow reshare
+ userShare.permissions = 1 // from server
+ sut.prepareUserOptionsMenu(popup.menu, userShare)
+ assertFalse(popup.menu.findItem(R.id.allow_resharing).isChecked)
+
+ userShare.permissions = 17 // from server
+ sut.prepareUserOptionsMenu(popup.menu, userShare)
+ assertTrue(popup.menu.findItem(R.id.allow_resharing).isChecked)
+
+ // set expiration date
+ userShare.expirationDate = 1582019340000
+ sut.prepareUserOptionsMenu(popup.menu, userShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_expiration_date).title
+ .startsWith(targetContext.getString(R.string.share_expiration_date_label).split(" ")[0])
+ )
+
+ userShare.expirationDate = 0
+ sut.prepareUserOptionsMenu(popup.menu, userShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_expiration_date).title ==
+ targetContext.getString(R.string.share_no_expiration_date_label)
+ )
+
+ // note
+ assertTrue(popup.menu.findItem(R.id.action_share_send_note).isVisible)
+ }
+
+ @Test
+ @Suppress("MagicNumber")
+ // also applies for
+ // group
+ // conversation
+ // circle
+ // federated share
+ fun userOptionMenuFolder() {
+ val sut = FileDetailSharingFragment.newInstance(file, user)
+ activity.addFragment(sut)
+ shortSleep()
+ sut.refreshCapabilitiesFromDB()
+
+ val overflowMenuShareLink = ImageView(targetContext)
+ val popup = PopupMenu(targetContext, overflowMenuShareLink)
+ popup.inflate(R.menu.item_user_sharing_settings)
+ val userShare = OCShare().apply {
+ isFolder = true
+ shareType = ShareType.USER
+ permissions = 17
+ }
+
+ sut.prepareUserOptionsMenu(popup.menu, userShare)
+ assertTrue(popup.menu.findItem(R.id.allow_creating).isVisible)
+ assertTrue(popup.menu.findItem(R.id.allow_deleting).isVisible)
+
+ // allow editing
+ userShare.permissions = 17 // from server
+ assertFalse(popup.menu.findItem(R.id.allow_editing).isChecked)
+
+ userShare.permissions = 19 // from server
+ sut.prepareUserOptionsMenu(popup.menu, userShare)
+ assertTrue(popup.menu.findItem(R.id.allow_editing).isChecked)
+
+ // allow reshare
+ userShare.permissions = 1 // from server
+ sut.prepareUserOptionsMenu(popup.menu, userShare)
+ assertFalse(popup.menu.findItem(R.id.allow_resharing).isChecked)
+
+ userShare.permissions = 17 // from server
+ sut.prepareUserOptionsMenu(popup.menu, userShare)
+ assertTrue(popup.menu.findItem(R.id.allow_resharing).isChecked)
+
+ // set expiration date
+ userShare.expirationDate = 1582019340000
+ sut.prepareUserOptionsMenu(popup.menu, userShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_expiration_date).title
+ .startsWith(targetContext.getString(R.string.share_expiration_date_label).split(" ")[0])
+ )
+
+ userShare.expirationDate = 0
+ sut.prepareUserOptionsMenu(popup.menu, userShare)
+ assertTrue(
+ popup.menu.findItem(R.id.action_expiration_date).title ==
+ targetContext.getString(R.string.share_no_expiration_date_label)
+ )
+
+ // note
+ assertTrue(popup.menu.findItem(R.id.action_share_send_note).isVisible)
+ }
+
+ @Test
+ fun testUploadAndEditingSharePermissions() {
+ val sut = FileDetailSharingFragment()
+
+ val share = OCShare().apply {
+ permissions = MAXIMUM_PERMISSIONS_FOR_FOLDER
+ }
+ assertTrue(sut.isUploadAndEditingAllowed(share))
+
+ share.permissions = NO_PERMISSION
+ assertFalse(sut.isUploadAndEditingAllowed(share))
+
+ share.permissions = READ_PERMISSION_FLAG
+ assertFalse(sut.isUploadAndEditingAllowed(share))
+
+ share.permissions = CREATE_PERMISSION_FLAG
+ assertFalse(sut.isUploadAndEditingAllowed(share))
+
+ share.permissions = DELETE_PERMISSION_FLAG
+ assertFalse(sut.isUploadAndEditingAllowed(share))
+
+ share.permissions = SHARE_PERMISSION_FLAG
+ assertFalse(sut.isUploadAndEditingAllowed(share))
+ }
+
+ @Test
+ @Suppress("MagicNumber")
+ fun testReadOnlySharePermissions() {
+ val sut = FileDetailSharingFragment()
+
+ val share = OCShare().apply {
+ permissions = 17
+ }
+ assertTrue(sut.isReadOnly(share))
+
+ share.permissions = NO_PERMISSION
+ assertFalse(sut.isReadOnly(share))
+
+ share.permissions = READ_PERMISSION_FLAG
+ assertTrue(sut.isReadOnly(share))
+
+ share.permissions = CREATE_PERMISSION_FLAG
+ assertFalse(sut.isReadOnly(share))
+
+ share.permissions = DELETE_PERMISSION_FLAG
+ assertFalse(sut.isReadOnly(share))
+
+ share.permissions = SHARE_PERMISSION_FLAG
+ assertFalse(sut.isReadOnly(share))
+
+ share.permissions = MAXIMUM_PERMISSIONS_FOR_FOLDER
+ assertFalse(sut.isReadOnly(share))
+
+ share.permissions = MAXIMUM_PERMISSIONS_FOR_FILE
+ assertFalse(sut.isReadOnly(share))
+ }
+
+ @Test
+ @Suppress("MagicNumber")
+ fun testFileDropSharePermissions() {
+ val sut = FileDetailSharingFragment()
+
+ val share = OCShare().apply {
+ permissions = 4
+ }
+ assertTrue(sut.isFileDrop(share))
+
+ share.permissions = NO_PERMISSION
+ assertFalse(sut.isFileDrop(share))
+
+ share.permissions = READ_PERMISSION_FLAG
+ assertFalse(sut.isFileDrop(share))
+
+ share.permissions = CREATE_PERMISSION_FLAG
+ assertTrue(sut.isFileDrop(share))
+
+ share.permissions = DELETE_PERMISSION_FLAG
+ assertFalse(sut.isFileDrop(share))
+
+ share.permissions = SHARE_PERMISSION_FLAG
+ assertFalse(sut.isFileDrop(share))
+
+ share.permissions = MAXIMUM_PERMISSIONS_FOR_FOLDER
+ assertFalse(sut.isFileDrop(share))
+
+ share.permissions = MAXIMUM_PERMISSIONS_FOR_FILE
+ assertFalse(sut.isFileDrop(share))
+ }
+
+ @After
+ fun after() {
+ activity.storageManager.cleanShares()
+ }
+}
diff --git a/src/debug/java/com/nextcloud/client/TestActivity.kt b/src/debug/java/com/nextcloud/client/TestActivity.kt
index 4d0bfa1d630d..7a054d3eba83 100644
--- a/src/debug/java/com/nextcloud/client/TestActivity.kt
+++ b/src/debug/java/com/nextcloud/client/TestActivity.kt
@@ -32,6 +32,8 @@ import com.owncloud.android.datamodel.FileDataStorageManager
import com.owncloud.android.datamodel.OCFile
import com.owncloud.android.files.services.FileDownloader
import com.owncloud.android.files.services.FileUploader
+import com.owncloud.android.lib.resources.status.OCCapability
+import com.owncloud.android.lib.resources.status.OwnCloudVersion
import com.owncloud.android.services.OperationsService
import com.owncloud.android.ui.activity.FileActivity
import com.owncloud.android.ui.activity.OnEnforceableRefreshListener
@@ -101,6 +103,10 @@ class TestActivity :
override fun getStorageManager(): FileDataStorageManager {
if (!this::storage.isInitialized) {
storage = FileDataStorageManager(account, contentResolver)
+
+ val ocCapability = OCCapability()
+ ocCapability.versionMayor = OwnCloudVersion.nextcloud_20.majorVersionNumber
+ storage.saveCapabilities(ocCapability)
}
return storage
diff --git a/src/main/java/com/nextcloud/client/jobs/AccountRemovalWork.kt b/src/main/java/com/nextcloud/client/jobs/AccountRemovalWork.kt
index eb4cdd7482a4..6b9d2c4fd6a1 100644
--- a/src/main/java/com/nextcloud/client/jobs/AccountRemovalWork.kt
+++ b/src/main/java/com/nextcloud/client/jobs/AccountRemovalWork.kt
@@ -25,8 +25,6 @@ package com.nextcloud.client.jobs
import android.accounts.Account
import android.content.Context
-import android.os.Build
-import android.provider.DocumentsContract
import android.text.TextUtils
import androidx.work.Worker
import androidx.work.WorkerParameters
@@ -48,6 +46,7 @@ import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory
import com.owncloud.android.lib.common.utils.Log_OC
import com.owncloud.android.lib.resources.users.RemoteWipeSuccessRemoteOperation
+import com.owncloud.android.providers.DocumentsStorageProvider
import com.owncloud.android.ui.activity.ContactsPreferenceActivity
import com.owncloud.android.ui.activity.ManageAccountsActivity
import com.owncloud.android.ui.events.AccountRemovedEvent
@@ -127,11 +126,7 @@ class AccountRemovalWork(
}
}
// notify Document Provider
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- val authority = context.resources.getString(R.string.document_provider_authority)
- val rootsUri = DocumentsContract.buildRootsUri(authority)
- context.contentResolver.notifyChange(rootsUri, null)
- }
+ DocumentsStorageProvider.notifyRootsChanged(context)
return Result.success()
}
diff --git a/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java b/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java
index a20830cd1d4c..6f77d05f6a4e 100644
--- a/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java
+++ b/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java
@@ -61,7 +61,6 @@
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
-import android.provider.DocumentsContract;
import android.text.TextUtils;
import android.util.AndroidRuntimeException;
import android.view.KeyEvent;
@@ -114,6 +113,7 @@
import com.owncloud.android.lib.resources.users.GetUserInfoRemoteOperation;
import com.owncloud.android.operations.DetectAuthenticationMethodOperation.AuthenticationMethod;
import com.owncloud.android.operations.GetServerInfoOperation;
+import com.owncloud.android.providers.DocumentsStorageProvider;
import com.owncloud.android.services.OperationsService;
import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
import com.owncloud.android.ui.activity.FileDisplayActivity;
@@ -1287,11 +1287,7 @@ protected boolean createAccount(RemoteOperationResult authResult) {
setResult(RESULT_OK, intent);
// notify Document Provider
- if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- String authority = getResources().getString(R.string.document_provider_authority);
- Uri rootsUri = DocumentsContract.buildRootsUri(authority);
- getContentResolver().notifyChange(rootsUri, null);
- }
+ DocumentsStorageProvider.notifyRootsChanged(this);
return true;
}
diff --git a/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java
index bbfa32c2cb65..2f265e6cd267 100644
--- a/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java
+++ b/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java
@@ -68,6 +68,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
public class FileDataStorageManager {
@@ -230,7 +231,6 @@ public boolean saveFile(OCFile ocFile) {
cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, ocFile.getEtagOnServer());
cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, ocFile.isSharedViaLink() ? 1 : 0);
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, ocFile.isSharedWithSharee() ? 1 : 0);
- cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, ocFile.getPublicLink());
cv.put(ProviderTableMeta.FILE_PERMISSIONS, ocFile.getPermissions());
cv.put(ProviderTableMeta.FILE_REMOTE_ID, ocFile.getRemoteId());
cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, ocFile.isUpdateThumbnailNeeded());
@@ -485,7 +485,6 @@ private ContentValues createContentValueForFile(OCFile folder) {
cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, folder.getEtagOnServer());
cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, folder.isSharedViaLink() ? 1 : 0);
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, folder.isSharedWithSharee() ? 1 : 0);
- cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, folder.getPublicLink());
cv.put(ProviderTableMeta.FILE_PERMISSIONS, folder.getPermissions());
cv.put(ProviderTableMeta.FILE_REMOTE_ID, folder.getRemoteId());
cv.put(ProviderTableMeta.FILE_FAVORITE, folder.isFavorite());
@@ -520,7 +519,6 @@ private ContentValues createContentValueForFile(OCFile file, OCFile folder) {
cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, file.getEtagOnServer());
cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, file.isSharedViaLink() ? 1 : 0);
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, file.isSharedWithSharee() ? 1 : 0);
- cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions());
cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.isUpdateThumbnailNeeded());
@@ -1006,7 +1004,6 @@ private OCFile createFileInstance(Cursor cursor) {
ocFile.setEtagOnServer(cursor.getString(cursor.getColumnIndex(ProviderTableMeta.FILE_ETAG_ON_SERVER)));
ocFile.setSharedViaLink(cursor.getInt(cursor.getColumnIndex(ProviderTableMeta.FILE_SHARED_VIA_LINK)) == 1);
ocFile.setSharedWithSharee(cursor.getInt(cursor.getColumnIndex(ProviderTableMeta.FILE_SHARED_WITH_SHAREE)) == 1);
- ocFile.setPublicLink(cursor.getString(cursor.getColumnIndex(ProviderTableMeta.FILE_PUBLIC_LINK)));
ocFile.setPermissions(cursor.getString(cursor.getColumnIndex(ProviderTableMeta.FILE_PERMISSIONS)));
ocFile.setRemoteId(cursor.getString(cursor.getColumnIndex(ProviderTableMeta.FILE_REMOTE_ID)));
ocFile.setUpdateThumbnailNeeded(cursor.getInt(cursor.getColumnIndex(ProviderTableMeta.FILE_UPDATE_THUMBNAIL)) == 1);
@@ -1296,7 +1293,6 @@ private void resetShareFlagsInAllFiles() {
ContentValues cv = new ContentValues();
cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, Boolean.FALSE);
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, Boolean.FALSE);
- cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, "");
String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?";
String[] whereArgs = new String[]{account.name};
@@ -1316,7 +1312,6 @@ private void resetShareFlagsInFolder(OCFile folder) {
ContentValues contentValues = new ContentValues();
contentValues.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, Boolean.FALSE);
contentValues.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, Boolean.FALSE);
- contentValues.put(ProviderTableMeta.FILE_PUBLIC_LINK, "");
String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PARENT + " = ?";
String[] whereArgs = new String[]{account.name, String.valueOf(folder.getFileId())};
@@ -1336,7 +1331,6 @@ private void resetShareFlagInAFile(String filePath) {
ContentValues contentValues = new ContentValues();
contentValues.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, Boolean.FALSE);
contentValues.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, Boolean.FALSE);
- contentValues.put(ProviderTableMeta.FILE_PUBLIC_LINK, "");
String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PATH + " = ?";
String[] whereArgs = new String[]{account.name, filePath};
@@ -1352,7 +1346,8 @@ private void resetShareFlagInAFile(String filePath) {
}
}
- private void cleanShares() {
+ @VisibleForTesting
+ public void cleanShares() {
String where = ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?";
String[] whereArgs = new String[]{account.name};
@@ -1447,7 +1442,6 @@ public void updateSharedFiles(Collection sharedFiles) {
cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, file.getEtagOnServer());
cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, file.isSharedViaLink() ? 1 : 0);
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, file.isSharedWithSharee() ? 1 : 0);
- cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions());
cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
cv.put(ProviderTableMeta.FILE_FAVORITE, file.isFavorite());
diff --git a/src/main/java/com/owncloud/android/datamodel/OCFile.java b/src/main/java/com/owncloud/android/datamodel/OCFile.java
index 2bea653ddbf0..721d409033df 100644
--- a/src/main/java/com/owncloud/android/datamodel/OCFile.java
+++ b/src/main/java/com/owncloud/android/datamodel/OCFile.java
@@ -47,7 +47,8 @@
public class OCFile implements Parcelable, Comparable, ServerFileInterface {
private final static String PERMISSION_SHARED_WITH_ME = "S";
- private final static String PERMISSION_CAN_RESHARE = "R";
+ @VisibleForTesting
+ public final static String PERMISSION_CAN_RESHARE = "R";
private final static String PERMISSION_CAN_WRITE = "CK";
public static final String PATH_SEPARATOR = "/";
@@ -75,7 +76,6 @@ public class OCFile implements Parcelable, Comparable, ServerFileInterfa
private String etag;
private String etagOnServer;
private boolean sharedViaLink;
- private String publicLink;
private String permissions;
private String remoteId; // The fileid namespaced by the instance fileId, globally unique
private boolean updateThumbnailNeeded;
@@ -150,7 +150,6 @@ private OCFile(Parcel source) {
etag = source.readString();
etagOnServer = source.readString();
sharedViaLink = source.readInt() == 1;
- publicLink = source.readString();
permissions = source.readString();
remoteId = source.readString();
updateThumbnailNeeded = source.readInt() == 1;
@@ -184,7 +183,6 @@ public void writeToParcel(Parcel dest, int flags) {
dest.writeString(etag);
dest.writeString(etagOnServer);
dest.writeInt(sharedViaLink ? 1 : 0);
- dest.writeString(publicLink);
dest.writeString(permissions);
dest.writeString(remoteId);
dest.writeInt(updateThumbnailNeeded ? 1 : 0);
@@ -450,7 +448,6 @@ private void resetData() {
etag = null;
etagOnServer = null;
sharedViaLink = false;
- publicLink = null;
permissions = null;
remoteId = null;
updateThumbnailNeeded = false;
@@ -646,10 +643,6 @@ public boolean isSharedViaLink() {
return this.sharedViaLink;
}
- public String getPublicLink() {
- return this.publicLink;
- }
-
public String getPermissions() {
return this.permissions;
}
@@ -758,10 +751,6 @@ public void setSharedViaLink(boolean sharedViaLink) {
this.sharedViaLink = sharedViaLink;
}
- public void setPublicLink(String publicLink) {
- this.publicLink = publicLink;
- }
-
public void setPermissions(String permissions) {
this.permissions = permissions;
}
diff --git a/src/main/java/com/owncloud/android/db/ProviderMeta.java b/src/main/java/com/owncloud/android/db/ProviderMeta.java
index 591157abb9f6..a184f148015c 100644
--- a/src/main/java/com/owncloud/android/db/ProviderMeta.java
+++ b/src/main/java/com/owncloud/android/db/ProviderMeta.java
@@ -102,7 +102,6 @@ static public class ProviderTableMeta implements BaseColumns {
public static final String FILE_ETAG_ON_SERVER = "etag_on_server";
public static final String FILE_SHARED_VIA_LINK = "share_by_link";
public static final String FILE_SHARED_WITH_SHAREE = "shared_via_users";
- public static final String FILE_PUBLIC_LINK = "public_link";
public static final String FILE_PERMISSIONS = "permissions";
public static final String FILE_REMOTE_ID = "remote_id";
public static final String FILE_UPDATE_THUMBNAIL = "update_thumbnail";
@@ -137,7 +136,6 @@ static public class ProviderTableMeta implements BaseColumns {
FILE_ETAG_ON_SERVER,
FILE_SHARED_VIA_LINK,
FILE_SHARED_WITH_SHAREE,
- FILE_PUBLIC_LINK,
FILE_PERMISSIONS,
FILE_REMOTE_ID,
FILE_UPDATE_THUMBNAIL,
diff --git a/src/main/java/com/owncloud/android/files/services/FileUploader.java b/src/main/java/com/owncloud/android/files/services/FileUploader.java
index 6993c6ccc0c7..bfc8b1c22ea6 100644
--- a/src/main/java/com/owncloud/android/files/services/FileUploader.java
+++ b/src/main/java/com/owncloud/android/files/services/FileUploader.java
@@ -426,7 +426,7 @@ private Integer gatherAndStartNewUploads(
createdBy,
file,
disableRetries
- );
+ );
}
} catch (IllegalArgumentException e) {
Log_OC.e(TAG, "Not enough information provided in intent: " + e.getMessage());
@@ -455,7 +455,7 @@ private void startNewUpload(
int createdBy,
OCFile file,
boolean disableRetries
- ) {
+ ) {
OCUpload ocUpload = new OCUpload(file, user.toPlatformAccount());
ocUpload.setFileSize(file.getFileLength());
ocUpload.setNameCollisionPolicy(nameCollisionPolicy);
@@ -975,7 +975,7 @@ public static void uploadUpdateFile(
OCFile existingFile,
Integer behaviour,
NameCollisionPolicy nameCollisionPolicy
- ) {
+ ) {
uploadUpdateFile(context, account, new OCFile[]{existingFile}, behaviour, nameCollisionPolicy, true);
}
@@ -989,7 +989,7 @@ public static void uploadUpdateFile(
Integer behaviour,
NameCollisionPolicy nameCollisionPolicy,
boolean disableRetries
- ) {
+ ) {
uploadUpdateFile(context, account, new OCFile[]{existingFile}, behaviour, nameCollisionPolicy, disableRetries);
}
@@ -1003,7 +1003,7 @@ public static void uploadUpdateFile(
Integer behaviour,
NameCollisionPolicy nameCollisionPolicy,
boolean disableRetries
- ) {
+ ) {
Intent intent = new Intent(context, FileUploader.class);
intent.putExtra(FileUploader.KEY_ACCOUNT, account);
diff --git a/src/main/java/com/owncloud/android/operations/CreateShareViaLinkOperation.java b/src/main/java/com/owncloud/android/operations/CreateShareViaLinkOperation.java
index adf837063077..30a49f4f3955 100644
--- a/src/main/java/com/owncloud/android/operations/CreateShareViaLinkOperation.java
+++ b/src/main/java/com/owncloud/android/operations/CreateShareViaLinkOperation.java
@@ -52,7 +52,7 @@ protected RemoteOperationResult run(OwnCloudClient client) {
"",
false,
password,
- OCShare.DEFAULT_PERMISSION);
+ OCShare.NO_PERMISSION);
createOp.setGetShareDetails(true);
RemoteOperationResult result = createOp.execute(client);
@@ -88,7 +88,6 @@ private void updateData(OCShare share) {
// Update OCFile with data from share: ShareByLink and publicLink
OCFile file = getStorageManager().getFileByEncryptedRemotePath(path);
if (file != null) {
- file.setPublicLink(share.getShareLink());
file.setSharedViaLink(true);
getStorageManager().saveFile(file);
}
diff --git a/src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java b/src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java
index 89d32aac5be7..0b6264f2528b 100644
--- a/src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java
+++ b/src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java
@@ -576,7 +576,6 @@ private void setLocalFileDataOnUpdatedFile(OCFile remoteFile, OCFile localFile,
Log.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
}
- updatedFile.setPublicLink(localFile.getPublicLink());
updatedFile.setSharedViaLink(localFile.isSharedViaLink());
updatedFile.setSharedWithSharee(localFile.isSharedWithSharee());
} else {
diff --git a/src/main/java/com/owncloud/android/operations/SynchronizeFolderOperation.java b/src/main/java/com/owncloud/android/operations/SynchronizeFolderOperation.java
index b8cd2377c040..b05c955e72e6 100644
--- a/src/main/java/com/owncloud/android/operations/SynchronizeFolderOperation.java
+++ b/src/main/java/com/owncloud/android/operations/SynchronizeFolderOperation.java
@@ -360,7 +360,6 @@ private void updateLocalStateData(OCFile remoteFile, OCFile localFile, OCFile up
updatedFile.setUpdateThumbnailNeeded(true);
Log.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
}
- updatedFile.setPublicLink(localFile.getPublicLink());
updatedFile.setSharedViaLink(localFile.isSharedViaLink());
updatedFile.setSharedWithSharee(localFile.isSharedWithSharee());
updatedFile.setEtagInConflict(localFile.getEtagInConflict());
diff --git a/src/main/java/com/owncloud/android/operations/UnshareOperation.java b/src/main/java/com/owncloud/android/operations/UnshareOperation.java
index 2d066dced580..3988c920c2e5 100644
--- a/src/main/java/com/owncloud/android/operations/UnshareOperation.java
+++ b/src/main/java/com/owncloud/android/operations/UnshareOperation.java
@@ -68,7 +68,6 @@ protected RemoteOperationResult run(OwnCloudClient client) {
if (ShareType.PUBLIC_LINK.equals(share.getShareType())) {
file.setSharedViaLink(false);
- file.setPublicLink("");
} else if (ShareType.USER.equals(share.getShareType()) || ShareType.GROUP.equals(share.getShareType())
|| ShareType.FEDERATED.equals(share.getShareType())) {
// Check if it is the last share
diff --git a/src/main/java/com/owncloud/android/operations/UpdateShareViaLinkOperation.java b/src/main/java/com/owncloud/android/operations/UpdateShareViaLinkOperation.java
index 90229523827e..29f697961e3e 100644
--- a/src/main/java/com/owncloud/android/operations/UpdateShareViaLinkOperation.java
+++ b/src/main/java/com/owncloud/android/operations/UpdateShareViaLinkOperation.java
@@ -34,10 +34,6 @@
*/
public class UpdateShareViaLinkOperation extends SyncOperation {
private String password;
- /**
- * Enable upload permissions to update in Share resource.
- */
- private boolean publicUpload;
private Boolean hideFileDownload;
private long expirationDateInMillis;
private long shareId;
@@ -58,12 +54,6 @@ protected RemoteOperationResult run(OwnCloudClient client) {
updateOp.setHideFileDownload(hideFileDownload);
updateOp.setLabel(label);
- if (publicShare.isFolder()) {
- updateOp.setPublicUploadOnFolder(publicUpload);
- } else {
- updateOp.setPublicUploadOnFile(publicUpload);
- }
-
RemoteOperationResult result = updateOp.execute(client);
if (result.isSuccess()) {
@@ -87,10 +77,6 @@ public void setPassword(String password) {
this.password = password;
}
- public void setPublicUpload(boolean publicUpload) {
- this.publicUpload = publicUpload;
- }
-
public void setHideFileDownload(Boolean hideFileDownload) {
this.hideFileDownload = hideFileDownload;
}
diff --git a/src/main/java/com/owncloud/android/operations/UploadFileOperation.java b/src/main/java/com/owncloud/android/operations/UploadFileOperation.java
index 5e23ba0a9011..f1bbb9ae222e 100644
--- a/src/main/java/com/owncloud/android/operations/UploadFileOperation.java
+++ b/src/main/java/com/owncloud/android/operations/UploadFileOperation.java
@@ -207,8 +207,8 @@ public UploadFileOperation(UploadsStorageManager uploadsStorageManager,
}
if (TextUtils.isEmpty(upload.getLocalPath())) {
throw new IllegalArgumentException(
- "Illegal file in UploadFileOperation; storage path invalid: "
- + upload.getLocalPath());
+ "Illegal file in UploadFileOperation; storage path invalid: "
+ + upload.getLocalPath());
}
this.uploadsStorageManager = uploadsStorageManager;
diff --git a/src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.java b/src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.java
index d049e5b713d9..07aa16e6a3e5 100644
--- a/src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.java
+++ b/src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.java
@@ -135,6 +135,14 @@ public Cursor queryRoots(String[] projection) {
return result;
}
+ public static void notifyRootsChanged(Context context) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ String authority = context.getString(R.string.document_provider_authority);
+ Uri rootsUri = DocumentsContract.buildRootsUri(authority);
+ context.getContentResolver().notifyChange(rootsUri, null);
+ }
+ }
+
@Override
public Cursor queryDocument(String documentId, String[] projection) throws FileNotFoundException {
Log.d(TAG, "queryDocument(), id=" + documentId);
diff --git a/src/main/java/com/owncloud/android/providers/FileContentProvider.java b/src/main/java/com/owncloud/android/providers/FileContentProvider.java
index e8f132d7e51b..8ecc26bd1260 100644
--- a/src/main/java/com/owncloud/android/providers/FileContentProvider.java
+++ b/src/main/java/com/owncloud/android/providers/FileContentProvider.java
@@ -708,7 +708,6 @@ private void createFilesTable(SQLiteDatabase db) {
+ ProviderTableMeta.FILE_ETAG + TEXT
+ ProviderTableMeta.FILE_ETAG_ON_SERVER + TEXT
+ ProviderTableMeta.FILE_SHARED_VIA_LINK + INTEGER
- + ProviderTableMeta.FILE_PUBLIC_LINK + TEXT
+ ProviderTableMeta.FILE_PERMISSIONS + " TEXT null,"
+ ProviderTableMeta.FILE_REMOTE_ID + " TEXT null,"
+ ProviderTableMeta.FILE_UPDATE_THUMBNAIL + INTEGER //boolean
@@ -1148,10 +1147,6 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
ADD_COLUMN + ProviderTableMeta.FILE_SHARED_VIA_LINK + " INTEGER " +
" DEFAULT 0");
- db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME +
- ADD_COLUMN + ProviderTableMeta.FILE_PUBLIC_LINK + " TEXT " +
- " DEFAULT NULL");
-
// Create table OCShares
createOCSharesTable(db);
diff --git a/src/main/java/com/owncloud/android/services/OperationsService.java b/src/main/java/com/owncloud/android/services/OperationsService.java
index c615f9c22bf5..0a16e17b7f48 100644
--- a/src/main/java/com/owncloud/android/services/OperationsService.java
+++ b/src/main/java/com/owncloud/android/services/OperationsService.java
@@ -89,12 +89,10 @@ public class OperationsService extends Service {
public static final String EXTRA_ACCOUNT = "ACCOUNT";
public static final String EXTRA_SERVER_URL = "SERVER_URL";
- public static final String EXTRA_OAUTH2_QUERY_PARAMETERS = "OAUTH2_QUERY_PARAMETERS";
public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
public static final String EXTRA_NEWNAME = "NEWNAME";
public static final String EXTRA_REMOVE_ONLY_LOCAL = "REMOVE_LOCAL_COPY";
public static final String EXTRA_SYNC_FILE_CONTENTS = "SYNC_FILE_CONTENTS";
- public static final String EXTRA_RESULT = "RESULT";
public static final String EXTRA_NEW_PARENT_PATH = "NEW_PARENT_PATH";
public static final String EXTRA_FILE = "FILE";
public static final String EXTRA_FILE_VERSION = "FILE_VERSION";
@@ -103,7 +101,6 @@ public class OperationsService extends Service {
public static final String EXTRA_SHARE_WITH = "SHARE_WITH";
public static final String EXTRA_SHARE_EXPIRATION_DATE_IN_MILLIS = "SHARE_EXPIRATION_YEAR";
public static final String EXTRA_SHARE_PERMISSIONS = "SHARE_PERMISSIONS";
- public static final String EXTRA_SHARE_PUBLIC_UPLOAD = "SHARE_PUBLIC_UPLOAD";
public static final String EXTRA_SHARE_PUBLIC_LABEL = "SHARE_PUBLIC_LABEL";
public static final String EXTRA_SHARE_HIDE_FILE_DOWNLOAD = "HIDE_FILE_DOWNLOAD";
public static final String EXTRA_SHARE_ID = "SHARE_ID";
@@ -384,9 +381,7 @@ public boolean isSynchronizing(User user, OCFile file) {
* Created with the Looper of a new thread, started in {@link OperationsService#onCreate()}.
*/
private static class ServiceHandler extends Handler {
- // don't make it a final class, and don't remove the static ; lint will warn about a p
- // ossible memory leak
-
+ // don't make it a final class, and don't remove the static ; lint will warn about a possible memory leak
OperationsService mService;
@@ -428,7 +423,7 @@ private void nextOperation() {
if (next != null) {
mCurrentOperation = next.second;
- RemoteOperationResult result = null;
+ RemoteOperationResult result;
try {
/// prepare client object to send the request to the ownCloud server
if (mLastTarget == null || !mLastTarget.equals(next.first)) {
@@ -553,9 +548,9 @@ private Pair newOperation(Intent operationIntent) {
false);
updateLinkOperation.setHideFileDownload(hideFileDownload);
- if (operationIntent.hasExtra(EXTRA_SHARE_PUBLIC_UPLOAD)) {
- updateLinkOperation.setPublicUpload(true);
- }
+// if (operationIntent.hasExtra(EXTRA_SHARE_PUBLIC_UPLOAD)) {
+// updateLinkOperation.setPublicUpload(true);
+// }
if (operationIntent.hasExtra(EXTRA_SHARE_PUBLIC_LABEL)) {
updateLinkOperation.setLabel(operationIntent.getStringExtra(EXTRA_SHARE_PUBLIC_LABEL));
@@ -698,7 +693,7 @@ private Pair newOperation(Intent operationIntent) {
}
if (operation != null) {
- return new Pair(target, operation);
+ return new Pair<>(target, operation);
} else {
return null;
}
diff --git a/src/main/java/com/owncloud/android/ui/activity/FileActivity.java b/src/main/java/com/owncloud/android/ui/activity/FileActivity.java
index 2e6d5330c9c6..347a720cdc17 100644
--- a/src/main/java/com/owncloud/android/ui/activity/FileActivity.java
+++ b/src/main/java/com/owncloud/android/ui/activity/FileActivity.java
@@ -746,7 +746,6 @@ private void onUpdateNoteForShareOperationFinish(RemoteOperationResult result) {
if (result.isSuccess()) {
if (sharingFragment != null) {
- sharingFragment.refreshPublicShareFromDB();
sharingFragment.onUpdateShareInformation(result, getFile());
}
} else {
@@ -761,7 +760,6 @@ private void onUpdateShareInformation(RemoteOperationResult result, @StringRes i
if (result.isSuccess()) {
updateFileFromDB();
if (sharingFragment != null) {
- sharingFragment.refreshPublicShareFromDB();
sharingFragment.onUpdateShareInformation(result, getFile());
}
} else if (sharingFragment != null && sharingFragment.getView() != null) {
@@ -807,7 +805,6 @@ private void onCreateShareViaLinkOperationFinish(CreateShareViaLinkOperation ope
copyAndShareFileLink(this, file, link);
if (sharingFragment != null) {
- sharingFragment.refreshPublicShareFromDB();
sharingFragment.onUpdateShareInformation(result, getFile());
}
} else {
@@ -828,7 +825,7 @@ private void onCreateShareViaLinkOperationFinish(CreateShareViaLinkOperation ope
} else {
if (sharingFragment != null) {
- sharingFragment.refreshPublicShareFromDB();
+ sharingFragment.refreshSharesFromDB();
}
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content),
ErrorMessageAdapter.getErrorCauseMessage(result,
@@ -899,8 +896,8 @@ private int getAppropriatePermissions(ShareType shareType) {
if (getFile().isSharedWithMe()) {
return OCShare.READ_PERMISSION_FLAG; // minimum permissions
} else if (ShareType.FEDERATED.equals(shareType)) {
- return getFile().isFolder() ? OCShare.FEDERATED_PERMISSIONS_FOR_FOLDER_AFTER_OC9 :
- OCShare.FEDERATED_PERMISSIONS_FOR_FILE_AFTER_OC9;
+ return getFile().isFolder() ? OCShare.FEDERATED_PERMISSIONS_FOR_FOLDER :
+ OCShare.FEDERATED_PERMISSIONS_FOR_FILE;
} else {
return getFile().isFolder() ? OCShare.MAXIMUM_PERMISSIONS_FOR_FOLDER :
OCShare.MAXIMUM_PERMISSIONS_FOR_FILE;
diff --git a/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java b/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java
index 16530fabdbed..8f43e24feeed 100644
--- a/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java
+++ b/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java
@@ -70,6 +70,7 @@
import com.owncloud.android.lib.common.ExternalLink;
import com.owncloud.android.lib.common.ExternalLinkType;
import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.providers.DocumentsStorageProvider;
import com.owncloud.android.ui.asynctasks.LoadingVersionNumberTask;
import com.owncloud.android.utils.DeviceCredentialUtils;
import com.owncloud.android.utils.DisplayUtils;
@@ -641,12 +642,17 @@ private void enableLock(String lock) {
DisplayUtils.showSnackMessage(this, R.string.prefs_lock_device_credentials_not_setup);
} else {
DisplayUtils.showSnackMessage(this, R.string.prefs_lock_device_credentials_enabled);
- this.lock.setValue(LOCK_DEVICE_CREDENTIALS);
- this.lock.setSummary(this.lock.getEntry());
+ changeLockSetting(LOCK_DEVICE_CREDENTIALS);
}
}
}
+ private void changeLockSetting(String value) {
+ lock.setValue(value);
+ lock.setSummary(lock.getEntry());
+ DocumentsStorageProvider.notifyRootsChanged(this);
+ }
+
private void disableLock(String lock) {
if (LOCK_PASSCODE.equals(lock)) {
Intent i = new Intent(getApplicationContext(), PassCodeActivity.class);
@@ -819,14 +825,12 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
appPrefs.putString(PassCodeActivity.PREFERENCE_PASSCODE_D + i, passcode.substring(i - 1, i));
}
appPrefs.apply();
- lock.setValue(LOCK_PASSCODE);
- lock.setSummary(lock.getEntry());
+ changeLockSetting(LOCK_PASSCODE);
DisplayUtils.showSnackMessage(this, R.string.pass_code_stored);
}
} else if (requestCode == ACTION_CONFIRM_PASSCODE && resultCode == RESULT_OK) {
if (data.getBooleanExtra(PassCodeActivity.KEY_CHECK_RESULT, false)) {
- lock.setValue(LOCK_NONE);
- lock.setSummary(lock.getEntry());
+ changeLockSetting(LOCK_NONE);
DisplayUtils.showSnackMessage(this, R.string.pass_code_removed);
if (!LOCK_NONE.equals(pendingLock)) {
@@ -840,8 +844,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
data.getIntExtra(RequestCredentialsActivity.KEY_CHECK_RESULT,
RequestCredentialsActivity.KEY_CHECK_RESULT_FALSE) ==
RequestCredentialsActivity.KEY_CHECK_RESULT_TRUE) {
- lock.setValue(LOCK_NONE);
- lock.setSummary(lock.getEntry());
+ changeLockSetting(LOCK_NONE);
DisplayUtils.showSnackMessage(this, R.string.credentials_disabled);
if (!LOCK_NONE.equals(pendingLock)) {
enableLock(pendingLock);
diff --git a/src/main/java/com/owncloud/android/ui/activity/ShareActivity.java b/src/main/java/com/owncloud/android/ui/activity/ShareActivity.java
index 7e506f58c8b3..4ab713bcce71 100644
--- a/src/main/java/com/owncloud/android/ui/activity/ShareActivity.java
+++ b/src/main/java/com/owncloud/android/ui/activity/ShareActivity.java
@@ -145,8 +145,7 @@ private void refreshSharesFromStorageManager() {
if (shareFileFragment != null
&& shareFileFragment.isAdded()) { // only if added to the view hierarchy!!
shareFileFragment.refreshCapabilitiesFromDB();
- //shareFileFragment.refrefreshUsersOrGroupsListFromDB();
- shareFileFragment.refreshPublicShareFromDB();
+ shareFileFragment.refreshSharesFromDB();
}
}
diff --git a/src/main/java/com/owncloud/android/ui/adapter/InternalShareViewHolder.java b/src/main/java/com/owncloud/android/ui/adapter/InternalShareViewHolder.java
new file mode 100644
index 000000000000..81b77a9d9ee8
--- /dev/null
+++ b/src/main/java/com/owncloud/android/ui/adapter/InternalShareViewHolder.java
@@ -0,0 +1,74 @@
+/*
+ *
+ * Nextcloud Android client application
+ *
+ * @author Tobias Kaminsky
+ * Copyright (C) 2020 Tobias Kaminsky
+ * Copyright (C) 2020 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 .
+ */
+
+package com.owncloud.android.ui.adapter;
+
+import android.content.Context;
+import android.graphics.PorterDuff;
+import android.view.View;
+
+import com.owncloud.android.R;
+import com.owncloud.android.databinding.FileDetailsShareInternalShareLinkBinding;
+import com.owncloud.android.lib.resources.shares.OCShare;
+
+import androidx.annotation.NonNull;
+import androidx.core.content.res.ResourcesCompat;
+import androidx.recyclerview.widget.RecyclerView;
+
+class InternalShareViewHolder extends RecyclerView.ViewHolder {
+ private FileDetailsShareInternalShareLinkBinding binding;
+ private Context context;
+
+ public InternalShareViewHolder(@NonNull View itemView) {
+ super(itemView);
+ }
+
+ public InternalShareViewHolder(FileDetailsShareInternalShareLinkBinding binding, Context context) {
+ this(binding.getRoot());
+ this.binding = binding;
+ this.context = context;
+ }
+
+ public void bind(OCShare share, ShareeListAdapterListener listener) {
+ binding.copyInternalLinkIcon
+ .getBackground()
+ .setColorFilter(ResourcesCompat.getColor(context.getResources(),
+ R.color.grey_db,
+ null),
+ PorterDuff.Mode.SRC_IN);
+ binding.copyInternalLinkIcon
+ .getDrawable()
+ .mutate()
+ .setColorFilter(ResourcesCompat.getColor(context.getResources(),
+ R.color.black,
+ null),
+ PorterDuff.Mode.SRC_IN);
+
+ if (share.isFolder()) {
+ binding.shareInternalLinkText.setText(context.getString(R.string.share_internal_link_to_folder_text));
+ } else {
+ binding.shareInternalLinkText.setText(context.getString(R.string.share_internal_link_to_file_text));
+ }
+
+ binding.copyInternalContainer.setOnClickListener(l -> listener.copyInternalLink());
+ }
+}
diff --git a/src/main/java/com/owncloud/android/ui/adapter/LinkShareViewHolder.java b/src/main/java/com/owncloud/android/ui/adapter/LinkShareViewHolder.java
new file mode 100644
index 000000000000..790ffb43f4a6
--- /dev/null
+++ b/src/main/java/com/owncloud/android/ui/adapter/LinkShareViewHolder.java
@@ -0,0 +1,74 @@
+/*
+ *
+ * Nextcloud Android client application
+ *
+ * @author Tobias Kaminsky
+ * Copyright (C) 2020 Tobias Kaminsky
+ * Copyright (C) 2020 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 .
+ */
+
+package com.owncloud.android.ui.adapter;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.view.View;
+
+import com.owncloud.android.R;
+import com.owncloud.android.databinding.FileDetailsShareLinkShareItemBinding;
+import com.owncloud.android.lib.resources.shares.OCShare;
+import com.owncloud.android.lib.resources.shares.ShareType;
+import com.owncloud.android.utils.ThemeUtils;
+
+import androidx.annotation.NonNull;
+import androidx.core.content.res.ResourcesCompat;
+import androidx.recyclerview.widget.RecyclerView;
+
+class LinkShareViewHolder extends RecyclerView.ViewHolder {
+ private FileDetailsShareLinkShareItemBinding binding;
+ private Context context;
+
+ public LinkShareViewHolder(@NonNull View itemView) {
+ super(itemView);
+ }
+
+ public LinkShareViewHolder(FileDetailsShareLinkShareItemBinding binding, Context context) {
+ this(binding.getRoot());
+ this.binding = binding;
+ this.context = context;
+ }
+
+ public void bind(OCShare publicShare, ShareeListAdapterListener listener) {
+ if (ShareType.EMAIL == publicShare.getShareType()) {
+ binding.name.setText(publicShare.getSharedWithDisplayName());
+ binding.icon.setImageDrawable(ResourcesCompat.getDrawable(context.getResources(),
+ R.drawable.ic_email,
+ null));
+ binding.copyLink.setVisibility(View.GONE);
+ } else {
+ if (!TextUtils.isEmpty(publicShare.getLabel())) {
+ String text = String.format(context.getString(R.string.share_link_with_label), publicShare.getLabel());
+ binding.name.setText(text);
+ } else {
+ binding.name.setText(R.string.share_link);
+ }
+ }
+
+ ThemeUtils.colorIconImageViewWithBackground(binding.icon, context);
+
+ binding.copyLink.setOnClickListener(v -> listener.copyLink(publicShare));
+ binding.overflowMenu.setOnClickListener(v -> listener.showLinkOverflowMenu(publicShare, binding.overflowMenu));
+ }
+}
diff --git a/src/main/java/com/owncloud/android/ui/adapter/PublicShareViewHolder.java b/src/main/java/com/owncloud/android/ui/adapter/NewLinkShareViewHolder.java
similarity index 51%
rename from src/main/java/com/owncloud/android/ui/adapter/PublicShareViewHolder.java
rename to src/main/java/com/owncloud/android/ui/adapter/NewLinkShareViewHolder.java
index 98e274a45b0e..0da1388fdb70 100644
--- a/src/main/java/com/owncloud/android/ui/adapter/PublicShareViewHolder.java
+++ b/src/main/java/com/owncloud/android/ui/adapter/NewLinkShareViewHolder.java
@@ -22,41 +22,26 @@
package com.owncloud.android.ui.adapter;
-import android.content.Context;
-import android.text.TextUtils;
import android.view.View;
-import com.owncloud.android.databinding.FileDetailsSharePublicLinkItemBinding;
-import com.owncloud.android.lib.resources.shares.OCShare;
-import com.owncloud.android.utils.ThemeUtils;
+import com.owncloud.android.databinding.FileDetailsSharePublicLinkAddNewItemBinding;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
-class PublicShareViewHolder extends RecyclerView.ViewHolder {
- private FileDetailsSharePublicLinkItemBinding binding;
- private Context context;
+class NewLinkShareViewHolder extends RecyclerView.ViewHolder {
+ private FileDetailsSharePublicLinkAddNewItemBinding binding;
- public PublicShareViewHolder(@NonNull View itemView) {
+ public NewLinkShareViewHolder(@NonNull View itemView) {
super(itemView);
}
- public PublicShareViewHolder(FileDetailsSharePublicLinkItemBinding binding, Context context) {
+ public NewLinkShareViewHolder(FileDetailsSharePublicLinkAddNewItemBinding binding) {
this(binding.getRoot());
this.binding = binding;
- this.context = context;
}
- public void bind(OCShare publicShare, PublicShareInterface listener) {
- if (!TextUtils.isEmpty(publicShare.getLabel())) {
- binding.publicShareLabel.setText(publicShare.getLabel());
- }
-
- ThemeUtils.colorIconImageViewWithBackground(binding.copyInternalLinkIcon, context);
-
- binding.shareLinkCopyIcon.setOnClickListener(v -> listener.copyLink(publicShare));
-
- binding.overflowMenuShareLink.setOnClickListener(
- v -> listener.showLinkOverflowMenu(publicShare, binding.overflowMenuShareLink));
+ public void bind(ShareeListAdapterListener listener) {
+ binding.addNewPublicShareLink.setOnClickListener(v -> listener.createPublicShareLink());
}
}
diff --git a/src/main/java/com/owncloud/android/ui/adapter/PublicShareListAdapter.java b/src/main/java/com/owncloud/android/ui/adapter/PublicShareListAdapter.java
deleted file mode 100644
index abc11ecdea24..000000000000
--- a/src/main/java/com/owncloud/android/ui/adapter/PublicShareListAdapter.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- *
- * Nextcloud Android client application
- *
- * @author Tobias Kaminsky
- * Copyright (C) 2020 Tobias Kaminsky
- * Copyright (C) 2020 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 .
- */
-
-package com.owncloud.android.ui.adapter;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.ViewGroup;
-
-import com.owncloud.android.databinding.FileDetailsSharePublicLinkItemBinding;
-import com.owncloud.android.lib.resources.shares.OCShare;
-
-import java.util.List;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-public class PublicShareListAdapter extends RecyclerView.Adapter {
- private Context context;
- private List shares;
- private PublicShareInterface listener;
-
- public PublicShareListAdapter(Context context, List shares, PublicShareInterface listener) {
- this.context = context;
- this.shares = shares;
- this.listener = listener;
- }
-
- @NonNull
- @Override
- public PublicShareViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- FileDetailsSharePublicLinkItemBinding binding =
- FileDetailsSharePublicLinkItemBinding.inflate(LayoutInflater.from(context), parent, false);
-
- return new PublicShareViewHolder(binding, context);
- }
-
- @Override
- public void onBindViewHolder(@NonNull PublicShareViewHolder holder, int position) {
- OCShare share = shares.get(position);
-
- holder.bind(share, listener);
- }
-
- @Override
- public int getItemCount() {
- return shares.size();
- }
-}
diff --git a/src/main/java/com/owncloud/android/ui/adapter/ShareViewHolder.java b/src/main/java/com/owncloud/android/ui/adapter/ShareViewHolder.java
new file mode 100644
index 000000000000..c48b42277b82
--- /dev/null
+++ b/src/main/java/com/owncloud/android/ui/adapter/ShareViewHolder.java
@@ -0,0 +1,102 @@
+/*
+ *
+ * Nextcloud Android client application
+ *
+ * @author Tobias Kaminsky
+ * Copyright (C) 2020 Tobias Kaminsky
+ * Copyright (C) 2020 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 .
+ */
+
+package com.owncloud.android.ui.adapter;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.ImageView;
+
+import com.owncloud.android.R;
+import com.owncloud.android.databinding.FileDetailsShareShareItemBinding;
+import com.owncloud.android.lib.resources.shares.OCShare;
+import com.owncloud.android.ui.TextDrawable;
+
+import java.security.NoSuchAlgorithmException;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+class ShareViewHolder extends RecyclerView.ViewHolder {
+ private FileDetailsShareShareItemBinding binding;
+ private float avatarRadiusDimension;
+ private Context context;
+
+ public ShareViewHolder(@NonNull View itemView) {
+ super(itemView);
+ }
+
+ public ShareViewHolder(FileDetailsShareShareItemBinding binding, Context context) {
+ this(binding.getRoot());
+ this.binding = binding;
+ this.context = context;
+ }
+
+ public void bind(OCShare share,
+ ShareeListAdapterListener listener,
+ String userId,
+ float avatarRadiusDimension) {
+ this.avatarRadiusDimension = avatarRadiusDimension;
+ String name = share.getSharedWithDisplayName();
+
+ switch (share.getShareType()) {
+ case GROUP:
+ name = context.getString(R.string.share_group_clarification, name);
+ setImage(binding.icon, share.getSharedWithDisplayName(), R.drawable.ic_group);
+ break;
+ case ROOM:
+ name = context.getString(R.string.share_room_clarification, name);
+ setImage(binding.icon, share.getSharedWithDisplayName(), R.drawable.ic_chat_bubble);
+ break;
+ case CIRCLE:
+ binding.icon.setImageResource(R.drawable.ic_circles);
+ break;
+ case FEDERATED:
+ name = context.getString(R.string.share_remote_clarification, name);
+ setImage(binding.icon, share.getSharedWithDisplayName(), R.drawable.ic_user);
+ break;
+ default:
+ setImage(binding.icon, name, R.drawable.ic_user);
+ break;
+ }
+
+ binding.name.setText(name);
+
+ if (share.getShareWith().equalsIgnoreCase(userId) || share.getUserId().equalsIgnoreCase(userId)) {
+ binding.overflowMenu.setVisibility(View.VISIBLE);
+
+ // bind listener to edit privileges
+ binding.overflowMenu.setOnClickListener(v -> listener.showUserOverflowMenu(share, binding.overflowMenu));
+ } else {
+ binding.overflowMenu.setVisibility(View.GONE);
+ }
+ }
+
+ private void setImage(ImageView avatar, String name, @DrawableRes int fallback) {
+ try {
+ avatar.setImageDrawable(TextDrawable.createNamedAvatar(name, avatarRadiusDimension));
+ } catch (NoSuchAlgorithmException | StringIndexOutOfBoundsException e) {
+ avatar.setImageResource(fallback);
+ }
+ }
+}
diff --git a/src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapter.java b/src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapter.java
index 3faaee5dbd3e..2bde1fcd151b 100644
--- a/src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapter.java
+++ b/src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapter.java
@@ -25,132 +25,108 @@
package com.owncloud.android.ui.adapter;
-import android.accounts.Account;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
-import android.widget.PopupMenu;
-import android.widget.TextView;
import com.owncloud.android.R;
-import com.owncloud.android.datamodel.FileDataStorageManager;
-import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.databinding.FileDetailsShareInternalShareLinkBinding;
+import com.owncloud.android.databinding.FileDetailsShareLinkShareItemBinding;
+import com.owncloud.android.databinding.FileDetailsSharePublicLinkAddNewItemBinding;
+import com.owncloud.android.databinding.FileDetailsShareShareItemBinding;
import com.owncloud.android.lib.resources.shares.OCShare;
import com.owncloud.android.lib.resources.shares.ShareType;
-import com.owncloud.android.lib.resources.status.OCCapability;
-import com.owncloud.android.lib.resources.status.OwnCloudVersion;
-import com.owncloud.android.ui.TextDrawable;
-import com.owncloud.android.ui.dialog.ExpirationDatePickerDialogFragment;
-import com.owncloud.android.ui.dialog.NoteDialogFragment;
-import com.owncloud.android.ui.fragment.util.SharingMenuHelper;
import com.owncloud.android.utils.DisplayUtils;
-import com.owncloud.android.utils.ThemeUtils;
-import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
-import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
-import androidx.appcompat.widget.AppCompatCheckBox;
-import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.RecyclerView;
-import butterknife.BindView;
-import butterknife.ButterKnife;
/**
* Adapter to show a user/group/email/remote in Sharing list in file details view.
*/
-public class ShareeListAdapter extends RecyclerView.Adapter
- implements DisplayUtils.AvatarGenerationListener {
+public class ShareeListAdapter extends RecyclerView.Adapter
+ implements DisplayUtils.AvatarGenerationListener {
private ShareeListAdapterListener listener;
- private OCCapability capabilities;
- private FragmentManager fragmentManager;
private Context context;
- private int accentColor;
private List shares;
private float avatarRadiusDimension;
- private OCFile file;
private String userId;
- public ShareeListAdapter(FragmentManager fragmentManager, Context context, List shares, Account account,
- OCFile file, ShareeListAdapterListener listener, String userId) {
+ public ShareeListAdapter(Context context,
+ List shares,
+ ShareeListAdapterListener listener,
+ String userId) {
this.context = context;
- this.fragmentManager = fragmentManager;
this.shares = shares;
this.listener = listener;
- this.file = file;
this.userId = userId;
- accentColor = ThemeUtils.primaryAccentColor(context);
- capabilities = new FileDataStorageManager(account, context.getContentResolver()).getCapability(account.name);
avatarRadiusDimension = context.getResources().getDimension(R.dimen.user_icon_radius);
+
+ sortShares();
}
- @NonNull
@Override
- public UserViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.file_details_share_user_item, parent, false);
- return new UserViewHolder(v);
+ public int getItemViewType(int position) {
+ return shares.get(position).getShareType().getValue();
}
+ @NonNull
@Override
- public void onBindViewHolder(@NonNull UserViewHolder holder, int position) {
- if (shares != null && shares.size() > position) {
- final OCShare share = shares.get(position);
-
- String name = share.getSharedWithDisplayName();
-
- switch (share.getShareType()) {
- case GROUP:
- name = context.getString(R.string.share_group_clarification, name);
- setImage(holder, name, R.drawable.ic_group);
- break;
- case EMAIL:
- name = context.getString(R.string.share_email_clarification, name);
- setImage(holder, name, R.drawable.ic_email);
- break;
- case ROOM:
- name = context.getString(R.string.share_room_clarification, name);
- setImage(holder, name, R.drawable.ic_chat_bubble);
- break;
- case CIRCLE:
- holder.avatar.setImageResource(R.drawable.ic_circles);
- break;
- default:
- setImage(holder, name, R.drawable.ic_user);
- break;
- }
-
- holder.name.setText(name);
-
- if (share.getShareWith().equalsIgnoreCase(userId) || share.getUserId().equalsIgnoreCase(userId)) {
- holder.allowEditing.setVisibility(View.VISIBLE);
- holder.editShareButton.setVisibility(View.VISIBLE);
-
- ThemeUtils.tintCheckbox(holder.allowEditing, accentColor);
- holder.allowEditing.setChecked(canEdit(share));
- holder.allowEditing.setOnClickListener(v -> allowEditClick(holder.allowEditing, share));
-
- // bind listener to edit privileges
- holder.editShareButton.setOnClickListener(v -> onOverflowIconClicked(v, holder.allowEditing, share));
- } else {
- holder.allowEditing.setVisibility(View.GONE);
- holder.editShareButton.setVisibility(View.GONE);
- }
+ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ switch (ShareType.fromValue(viewType)) {
+ case PUBLIC_LINK:
+ case EMAIL:
+ return new LinkShareViewHolder(
+ FileDetailsShareLinkShareItemBinding.inflate(LayoutInflater.from(context),
+ parent,
+ false),
+ context);
+ case NEW_PUBLIC_LINK:
+ return new NewLinkShareViewHolder(
+ FileDetailsSharePublicLinkAddNewItemBinding.inflate(LayoutInflater.from(context),
+ parent,
+ false)
+ );
+ case INTERNAL:
+ return new InternalShareViewHolder(
+ FileDetailsShareInternalShareLinkBinding.inflate(LayoutInflater.from(context), parent, false),
+ context);
+ default:
+ return new ShareViewHolder(FileDetailsShareShareItemBinding.inflate(LayoutInflater.from(context),
+ parent,
+ false),
+ context);
}
}
- private void setImage(UserViewHolder holder, String name, @DrawableRes int fallback) {
- try {
- holder.avatar.setImageDrawable(TextDrawable.createNamedAvatar(name, avatarRadiusDimension));
- } catch (NoSuchAlgorithmException e) {
- holder.avatar.setImageResource(fallback);
+ @Override
+ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
+ if (shares == null || shares.size() <= position) {
+ return;
+ }
+
+ final OCShare share = shares.get(position);
+
+ if (holder instanceof LinkShareViewHolder) {
+ LinkShareViewHolder publicShareViewHolder = (LinkShareViewHolder) holder;
+ publicShareViewHolder.bind(share, listener);
+ } else if (holder instanceof InternalShareViewHolder) {
+ InternalShareViewHolder internalShareViewHolder = (InternalShareViewHolder) holder;
+ internalShareViewHolder.bind(share, listener);
+ } else if (holder instanceof NewLinkShareViewHolder) {
+ NewLinkShareViewHolder newLinkShareViewHolder = (NewLinkShareViewHolder) holder;
+ newLinkShareViewHolder.bind(listener);
+ } else {
+ ShareViewHolder userViewHolder = (ShareViewHolder) holder;
+ userViewHolder.bind(share, listener, userId, avatarRadiusDimension);
}
}
@@ -164,204 +140,10 @@ public int getItemCount() {
return shares.size();
}
- private void allowEditClick(AppCompatCheckBox checkBox, @NonNull OCShare share) {
- if (!share.isFolder()) {
- share.setPermissions(listener.updatePermissionsToShare(
- share,
- canReshare(share),
- checkBox.isChecked(),
- false,
- false,
- false
- ));
- } else {
- share.setPermissions(listener.updatePermissionsToShare(
- share,
- canReshare(share),
- checkBox.isChecked(),
- checkBox.isChecked(),
- checkBox.isChecked(),
- checkBox.isChecked()
- ));
- }
- }
-
- private void onOverflowIconClicked(View view, AppCompatCheckBox allowEditsCheckBox, OCShare share) {
- // use grey as fallback for elements where custom theming is not available
- if (ThemeUtils.themingEnabled(context)) {
- context.getTheme().applyStyle(R.style.FallbackThemingTheme, true);
- }
- PopupMenu popup = new PopupMenu(context, view);
- popup.inflate(R.menu.item_user_sharing_settings);
-
- prepareOptionsMenu(popup.getMenu(), share);
-
- popup.setOnMenuItemClickListener(item -> optionsItemSelected(popup.getMenu(), item, allowEditsCheckBox, share));
- popup.show();
- }
-
- /**
- * Updates the sharee's menu with the current permissions of the {@link OCShare}
- *
- * @param menu the menu of the sharee/shared file
- * @param share the shared file
- */
- private void prepareOptionsMenu(Menu menu, OCShare share) {
-
- MenuItem editCreateItem = menu.findItem(R.id.action_can_edit_create);
- MenuItem editChangeItem = menu.findItem(R.id.action_can_edit_change);
- MenuItem editDeleteItem = menu.findItem(R.id.action_can_edit_delete);
-
- MenuItem hideFileListingItem = menu.findItem(R.id.action_hide_file_listing);
- MenuItem passwordItem = menu.findItem(R.id.action_password);
- MenuItem expirationDateItem = menu.findItem(R.id.action_expiration_date);
-
- MenuItem reshareItem = menu.findItem(R.id.action_can_reshare);
-
- MenuItem sendNoteItem = menu.findItem(R.id.action_share_send_note);
-
- if (isReshareForbidden(share)) {
- reshareItem.setVisible(false);
- }
- reshareItem.setChecked(canReshare(share));
-
- if (share.getShareType() == ShareType.EMAIL) {
- SharingMenuHelper.setupHideFileListingMenuItem(
- hideFileListingItem,
- file.isFolder(),
- canEdit(share),
- share.getPermissions()
- );
- SharingMenuHelper.setupPasswordMenuItem(passwordItem, share.isPasswordProtected());
-
- reshareItem.setVisible(false);
- editCreateItem.setVisible(false);
- editChangeItem.setVisible(false);
- editDeleteItem.setVisible(false);
- } else {
- if (file.isFolder() && isEditOptionsAvailable(share)) {
- /// TODO change areEditOptionsAvailable in order to delete !isFederated
- editCreateItem.setChecked(canCreate(share));
- editChangeItem.setChecked(canUpdate(share));
- editDeleteItem.setChecked(canDelete(share));
- } else {
- editCreateItem.setVisible(false);
- editChangeItem.setVisible(false);
- editDeleteItem.setVisible(false);
- }
-
- hideFileListingItem.setVisible(false);
- passwordItem.setVisible(false);
-
- if (!capabilities.getVersion().isNewerOrEqual(OwnCloudVersion.nextcloud_18)) {
- expirationDateItem.setVisible(false);
- }
- }
-
- SharingMenuHelper.setupExpirationDateMenuItem(
- menu.findItem(R.id.action_expiration_date), share.getExpirationDate(), context.getResources());
-
- sendNoteItem.setVisible(capabilities.getVersion().isNoteOnShareSupported());
- }
-
- private boolean isEditOptionsAvailable(OCShare share) {
- return !ShareType.FEDERATED.equals(share.getShareType());
- }
-
- private boolean isReshareForbidden(OCShare share) {
- return ShareType.FEDERATED.equals(share.getShareType()) ||
- (capabilities != null && capabilities.getFilesSharingResharing().isFalse());
- }
-
- private boolean canEdit(OCShare share) {
- return (share.getPermissions() &
- (OCShare.CREATE_PERMISSION_FLAG | OCShare.UPDATE_PERMISSION_FLAG | OCShare.DELETE_PERMISSION_FLAG)) > 0;
- }
-
- private boolean canCreate(OCShare share) {
- return (share.getPermissions() & OCShare.CREATE_PERMISSION_FLAG) > 0;
- }
-
- private boolean canUpdate(OCShare share) {
- return (share.getPermissions() & OCShare.UPDATE_PERMISSION_FLAG) > 0;
- }
-
- private boolean canDelete(OCShare share) {
- return (share.getPermissions() & OCShare.DELETE_PERMISSION_FLAG) > 0;
- }
-
- private boolean canReshare(OCShare share) {
- return (share.getPermissions() & OCShare.SHARE_PERMISSION_FLAG) > 0;
- }
-
- private boolean optionsItemSelected(Menu menu, MenuItem item, AppCompatCheckBox allowEditsCheckBox, OCShare share) {
- switch (item.getItemId()) {
- case R.id.action_can_edit_create:
- case R.id.action_can_edit_change:
- case R.id.action_can_edit_delete: {
- item.setChecked(!item.isChecked());
- if (item.isChecked() && !allowEditsCheckBox.isChecked()) {
- allowEditsCheckBox.setChecked(true);
- }
- share.setPermissions(
- updatePermissionsToShare(
- share,
- menu.findItem(R.id.action_can_reshare).isChecked(),
- allowEditsCheckBox.isChecked(),
- menu.findItem(R.id.action_can_edit_create).isChecked(),
- menu.findItem(R.id.action_can_edit_change).isChecked(),
- menu.findItem(R.id.action_can_edit_delete).isChecked())
- );
- return true;
- }
- case R.id.action_can_reshare: {
- item.setChecked(!item.isChecked());
- share.setPermissions(
- updatePermissionsToShare(
- share,
- menu.findItem(R.id.action_can_reshare).isChecked(),
- allowEditsCheckBox.isChecked(),
- menu.findItem(R.id.action_can_edit_create).isChecked(),
- menu.findItem(R.id.action_can_edit_change).isChecked(),
- menu.findItem(R.id.action_can_edit_delete).isChecked())
- );
- return true;
- }
- case R.id.action_unshare: {
- listener.unshareWith(share);
- shares.remove(share);
- notifyDataSetChanged();
- return true;
- }
- case R.id.action_password: {
- listener.requestPasswordForShare(share, false);
- return true;
- }
- case R.id.action_expiration_date: {
- ExpirationDatePickerDialogFragment dialog = ExpirationDatePickerDialogFragment
- .newInstance(share, share.getExpirationDate());
- dialog.show(fragmentManager, ExpirationDatePickerDialogFragment.DATE_PICKER_DIALOG);
- return true;
- }
- case R.id.action_share_send_note:
- NoteDialogFragment dialog = NoteDialogFragment.newInstance(share);
- dialog.show(fragmentManager, NoteDialogFragment.NOTE_FRAGMENT);
- return true;
- default:
- return true;
- }
- }
-
- private int updatePermissionsToShare(OCShare share, boolean canReshare, boolean canEdit, boolean canEditCreate,
- boolean canEditChange, boolean canEditDelete) {
- return listener.updatePermissionsToShare(
- share,
- canReshare,
- canEdit,
- canEditCreate,
- canEditChange,
- canEditDelete
- );
+ public void addShares(List sharesToAdd) {
+ shares.addAll(sharesToAdd);
+ sortShares();
+ notifyDataSetChanged();
}
@Override
@@ -381,53 +163,46 @@ public boolean shouldCallGeneratedCallback(String tag, Object callContext) {
return false;
}
- class UserViewHolder extends RecyclerView.ViewHolder {
- @BindView(R.id.avatar)
- ImageView avatar;
- @BindView(R.id.name)
- TextView name;
- @BindView(R.id.allowEditing)
- AppCompatCheckBox allowEditing;
- @BindView(R.id.editShareButton)
- ImageView editShareButton;
+ public void remove(OCShare share) {
+ shares.remove(share);
+ notifyDataSetChanged();
+ }
- UserViewHolder(View itemView) {
- super(itemView);
- ButterKnife.bind(this, itemView);
+ /**
+ * sort all by creation time, then email/link shares on top
+ */
+ protected final void sortShares() {
+ List links = new ArrayList<>();
+ List users = new ArrayList<>();
+
+ for (OCShare share : shares) {
+ if (ShareType.PUBLIC_LINK == share.getShareType() || ShareType.EMAIL == share.getShareType()) {
+ links.add(share);
+ } else if (share.getShareType() != ShareType.INTERNAL) {
+ users.add(share);
+ }
}
- }
- public interface ShareeListAdapterListener {
- /**
- * unshare with given sharee {@link OCShare}.
- *
- * @param share the share
- */
- void unshareWith(OCShare share);
+ Collections.sort(links, (o1, o2) -> Long.compare(o2.getSharedDate(), o1.getSharedDate()));
+ Collections.sort(users, (o1, o2) -> Long.compare(o2.getSharedDate(), o1.getSharedDate()));
+
+ shares = links;
+ shares.addAll(users);
+
+ // add internal share link at end
+ shares.add(new OCShare().setShareType(ShareType.INTERNAL));
+ }
- /**
- * Updates the permissions of the {@link OCShare}.
- *
- * @param share the share to be updated
- * @param canReshare reshare permission
- * @param canEdit edit permission
- * @param canEditCreate create permission (folders only)
- * @param canEditChange change permission (folders only)
- * @param canEditDelete delete permission (folders only)
- * @return permissions value set
- */
- int updatePermissionsToShare(OCShare share,
- boolean canReshare,
- boolean canEdit,
- boolean canEditCreate,
- boolean canEditChange,
- boolean canEditDelete);
+ public List getShares() {
+ return shares;
+ }
- /**
- * Starts a dialog that requests a password to the user to protect a share.
- *
- * @param share the share for which a password shall be configured/removed
- */
- void requestPasswordForShare(OCShare share, boolean askForPassword);
+ public void removeNewPublicShare() {
+ for (OCShare share : shares) {
+ if (share.getShareType() == ShareType.NEW_PUBLIC_LINK) {
+ shares.remove(share);
+ break;
+ }
+ }
}
}
diff --git a/src/main/java/com/owncloud/android/ui/adapter/PublicShareInterface.java b/src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapterListener.java
similarity index 80%
rename from src/main/java/com/owncloud/android/ui/adapter/PublicShareInterface.java
rename to src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapterListener.java
index d34d5bb90405..c1e4926cb95c 100644
--- a/src/main/java/com/owncloud/android/ui/adapter/PublicShareInterface.java
+++ b/src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapterListener.java
@@ -26,8 +26,16 @@
import com.owncloud.android.lib.resources.shares.OCShare;
-public interface PublicShareInterface {
+public interface ShareeListAdapterListener {
void copyLink(OCShare share);
void showLinkOverflowMenu(OCShare publicShare, ImageView overflowMenuShareLink);
+
+ void showUserOverflowMenu(OCShare share, ImageView overflowMenu);
+
+ void copyInternalLink();
+
+ void createPublicShareLink();
+
+ void requestPasswordForShare(OCShare share, boolean askForPassword);
}
diff --git a/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java b/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java
index 8c61baa30f5e..8c41e97b880f 100755
--- a/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java
+++ b/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java
@@ -716,7 +716,7 @@ public SectionedViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int vie
/**
* Load upload items from {@link UploadsStorageManager}.
*/
- public void loadUploadItemsFromDb() {
+ public final void loadUploadItemsFromDb() {
Log_OC.d(TAG, "loadUploadItemsFromDb");
for (UploadGroup group : uploadGroups) {
diff --git a/src/main/java/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java b/src/main/java/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java
index 359424b56e5a..04816c21fab0 100644
--- a/src/main/java/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java
+++ b/src/main/java/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java
@@ -27,13 +27,12 @@
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
-import android.widget.TextView;
import com.owncloud.android.R;
+import com.owncloud.android.databinding.PasswordDialogBinding;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.lib.resources.shares.OCShare;
import com.owncloud.android.ui.activity.FileActivity;
@@ -41,7 +40,6 @@
import com.owncloud.android.utils.ThemeUtils;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
@@ -58,6 +56,7 @@ public class SharePasswordDialogFragment extends DialogFragment implements Dialo
private static final String ARG_ASK_FOR_PASSWORD = "ASK_FOR_PASSWORD";
public static final String PASSWORD_FRAGMENT = "PASSWORD_FRAGMENT";
+ private PasswordDialogBinding binding;
private OCFile file;
private OCShare share;
private boolean createShare;
@@ -122,12 +121,6 @@ public static SharePasswordDialogFragment newInstance(OCShare share) {
return frag;
}
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- return super.onCreateView(inflater, container, savedInstanceState);
- }
-
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
@@ -137,17 +130,18 @@ public Dialog onCreateDialog(Bundle savedInstanceState) {
askForPassword = getArguments().getBoolean(ARG_ASK_FOR_PASSWORD, false);
// Inflate the layout for the dialog
- LayoutInflater inflater = getActivity().getLayoutInflater();
- View v = inflater.inflate(R.layout.password_dialog, null);
+ LayoutInflater inflater = requireActivity().getLayoutInflater();
+ binding = PasswordDialogBinding.inflate(inflater, null, false);
+ View view = binding.getRoot();
// Setup layout
- EditText inputText = v.findViewById(R.id.share_password);
- inputText.getBackground().setColorFilter(
- ThemeUtils.primaryAccentColor(getContext()),
- PorterDuff.Mode.SRC_ATOP
- );
+ EditText inputText = binding.sharePassword;
+ inputText.setHighlightColor(ThemeUtils.primaryColor(getActivity()));
inputText.setText("");
+ ThemeUtils.themeEditText(getContext(), inputText, false);
inputText.requestFocus();
+ inputText.getBackground().setColorFilter(ThemeUtils.primaryAccentColor(getContext()),
+ PorterDuff.Mode.SRC_ATOP);
int title;
if (askForPassword) {
@@ -157,10 +151,9 @@ public Dialog onCreateDialog(Bundle savedInstanceState) {
}
// Build the dialog
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(),
- R.style.Theme_ownCloud_Dialog_NoButtonBarStyle);
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- builder.setView(v)
+ builder.setView(view)
.setPositiveButton(R.string.common_ok, this)
.setNegativeButton(R.string.common_cancel, this)
.setNeutralButton(R.string.common_delete, this)
@@ -178,11 +171,10 @@ public Dialog onCreateDialog(Bundle savedInstanceState) {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == AlertDialog.BUTTON_POSITIVE) {
- String password = ((TextView) (getDialog().findViewById(R.id.share_password))).getText().toString();
+ String password = binding.sharePassword.getText().toString();
if (!askForPassword && TextUtils.isEmpty(password)) {
- DisplayUtils.showSnackMessage(getActivity().findViewById(android.R.id.content),
- R.string.share_link_empty_password);
+ DisplayUtils.showSnackMessage(binding.getRoot(), R.string.share_link_empty_password);
return;
}
@@ -217,4 +209,10 @@ private void setPassword(boolean createShare, OCFile file, String password) {
private void setPassword(OCShare share, String password) {
((FileActivity) getActivity()).getFileOperationsHelper().setPasswordToShare(share, password);
}
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ binding = null;
+ }
}
diff --git a/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java b/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java
index 556b0bf1b7c0..81efaea17a4a 100644
--- a/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java
+++ b/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java
@@ -27,7 +27,6 @@
import android.app.SearchManager;
import android.content.Context;
import android.content.res.Resources;
-import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.InputType;
@@ -38,13 +37,12 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
import com.nextcloud.client.account.User;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.di.Injectable;
import com.owncloud.android.R;
+import com.owncloud.android.databinding.FileDetailsSharingFragmentBinding;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.lib.common.OwnCloudAccount;
@@ -53,11 +51,11 @@
import com.owncloud.android.lib.resources.shares.SharePermissionsBuilder;
import com.owncloud.android.lib.resources.shares.ShareType;
import com.owncloud.android.lib.resources.status.OCCapability;
+import com.owncloud.android.lib.resources.status.OwnCloudVersion;
import com.owncloud.android.ui.activity.FileActivity;
import com.owncloud.android.ui.activity.FileDisplayActivity;
-import com.owncloud.android.ui.adapter.PublicShareInterface;
-import com.owncloud.android.ui.adapter.PublicShareListAdapter;
import com.owncloud.android.ui.adapter.ShareeListAdapter;
+import com.owncloud.android.ui.adapter.ShareeListAdapterListener;
import com.owncloud.android.ui.decoration.SimpleListItemDividerDecoration;
import com.owncloud.android.ui.dialog.ExpirationDatePickerDialogFragment;
import com.owncloud.android.ui.dialog.NoteDialogFragment;
@@ -70,25 +68,29 @@
import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.ThemeUtils;
+import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import androidx.appcompat.widget.PopupMenu;
-import androidx.appcompat.widget.SearchView;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
-import butterknife.Unbinder;
-public class FileDetailSharingFragment extends Fragment implements ShareeListAdapter.ShareeListAdapterListener,
+import static com.owncloud.android.lib.resources.shares.OCShare.CREATE_PERMISSION_FLAG;
+import static com.owncloud.android.lib.resources.shares.OCShare.DELETE_PERMISSION_FLAG;
+import static com.owncloud.android.lib.resources.shares.OCShare.MAXIMUM_PERMISSIONS_FOR_FILE;
+import static com.owncloud.android.lib.resources.shares.OCShare.MAXIMUM_PERMISSIONS_FOR_FOLDER;
+import static com.owncloud.android.lib.resources.shares.OCShare.NO_PERMISSION;
+import static com.owncloud.android.lib.resources.shares.OCShare.READ_PERMISSION_FLAG;
+import static com.owncloud.android.lib.resources.shares.OCShare.SHARE_PERMISSION_FLAG;
+import static com.owncloud.android.lib.resources.shares.OCShare.UPDATE_PERMISSION_FLAG;
+
+public class FileDetailSharingFragment extends Fragment implements ShareeListAdapterListener,
DisplayUtils.AvatarGenerationListener,
- PublicShareInterface,
Injectable {
private static final String ARG_FILE = "FILE";
@@ -103,40 +105,7 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
private FileActivity fileActivity;
private FileDataStorageManager fileDataStorageManager;
- private Unbinder unbinder;
-
- @BindView(R.id.searchView)
- SearchView searchView;
-
- @BindView(R.id.shareUsersList)
- RecyclerView usersList;
-
- @BindView(R.id.publicShareList)
- RecyclerView publicShareList;
-
- @BindView(R.id.new_public_share)
- View addPublicShare;
-
- @BindView(R.id.shared_with_you_container)
- LinearLayout sharedWithYouContainer;
-
- @BindView(R.id.shared_with_you_avatar)
- ImageView sharedWithYouAvatar;
-
- @BindView(R.id.shared_with_you_username)
- TextView sharedWithYouUsername;
-
- @BindView(R.id.shared_with_you_note_container)
- View sharedWithYouNoteContainer;
-
- @BindView(R.id.shared_with_you_note)
- TextView sharedWithYouNote;
-
- @BindView(R.id.copy_internal_link_icon)
- ImageView internalLinkIcon;
-
- @BindView(R.id.shareInternalLinkText)
- TextView internalLinkText;
+ private FileDetailsSharingFragmentBinding binding;
@Inject UserAccountManager accountManager;
@@ -184,30 +153,29 @@ public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
refreshCapabilitiesFromDB();
- refreshPublicShareFromDB();
+ refreshSharesFromDB();
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.file_details_sharing_fragment, container, false);
- unbinder = ButterKnife.bind(this, view);
+ binding = FileDetailsSharingFragmentBinding.inflate(inflater, container, false);
+ View view = binding.getRoot();
fileOperationsHelper = fileActivity.getFileOperationsHelper();
fileDataStorageManager = fileActivity.getStorageManager();
- setupView();
+ AccountManager accountManager = AccountManager.get(getContext());
+ String userId = accountManager.getUserData(user.toPlatformAccount(),
+ com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
- // todo extract
- internalLinkIcon.getBackground().setColorFilter(getResources().getColor(R.color.grey_db),
- PorterDuff.Mode.SRC_IN);
- internalLinkIcon.getDrawable().mutate().setColorFilter(getResources().getColor(R.color.black),
- PorterDuff.Mode.SRC_IN);
+ binding.sharesList.setAdapter(new ShareeListAdapter(fileActivity,
+ new ArrayList<>(),
+ this,
+ userId));
+ binding.sharesList.setLayoutManager(new LinearLayoutManager(getContext()));
+ binding.sharesList.addItemDecoration(new SimpleListItemDividerDecoration(getContext()));
- if (file.isFolder()) {
- internalLinkText.setText(getString(R.string.share_internal_link_to_folder_text));
- } else {
- internalLinkText.setText(getString(R.string.share_internal_link_to_file_text));
- }
+ setupView();
return view;
}
@@ -215,7 +183,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
@Override
public void onDestroy() {
super.onDestroy();
- unbinder.unbind();
+ binding = null;
}
@Override
@@ -230,16 +198,17 @@ private void setupView() {
setShareWithYou();
FileDetailSharingFragmentHelper.setupSearchView(
- (SearchManager) fileActivity.getSystemService(Context.SEARCH_SERVICE), searchView,
+ (SearchManager) fileActivity.getSystemService(Context.SEARCH_SERVICE),
+ binding.searchView,
fileActivity.getComponentName());
- ThemeUtils.themeSearchView(searchView, requireContext());
+ ThemeUtils.themeSearchView(binding.searchView, requireContext());
if (file.canReshare()) {
- setShareWithUserInfo();
+ binding.searchView.setQueryHint(getResources().getString(R.string.share_search));
} else {
- searchView.setQueryHint(getResources().getString(R.string.reshare_not_allowed));
- searchView.setInputType(InputType.TYPE_NULL);
- disableSearchView(searchView);
+ binding.searchView.setQueryHint(getResources().getString(R.string.reshare_not_allowed));
+ binding.searchView.setInputType(InputType.TYPE_NULL);
+ disableSearchView(binding.searchView);
}
}
@@ -257,52 +226,32 @@ private void disableSearchView(View view) {
private void setShareWithYou() {
if (accountManager.userOwnsFile(file, user)) {
- sharedWithYouContainer.setVisibility(View.GONE);
+ binding.sharedWithYouContainer.setVisibility(View.GONE);
} else {
- sharedWithYouUsername.setText(
+ binding.sharedWithYouUsername.setText(
String.format(getString(R.string.shared_with_you_by), file.getOwnerDisplayName()));
- DisplayUtils.setAvatar(user, file.getOwnerId(), this, getResources().getDimension(
- R.dimen.file_list_item_avatar_icon_radius), getResources(), sharedWithYouAvatar,
- getContext());
- sharedWithYouAvatar.setVisibility(View.VISIBLE);
+ DisplayUtils.setAvatar(user,
+ file.getOwnerId(),
+ this,
+ getResources().getDimension(
+ R.dimen.file_list_item_avatar_icon_radius),
+ getResources(),
+ binding.sharedWithYouAvatar,
+ getContext());
+ binding.sharedWithYouAvatar.setVisibility(View.VISIBLE);
String note = file.getNote();
if (!TextUtils.isEmpty(note)) {
- sharedWithYouNote.setText(file.getNote());
- sharedWithYouNoteContainer.setVisibility(View.VISIBLE);
+ binding.sharedWithYouNote.setText(file.getNote());
+ binding.sharedWithYouNoteContainer.setVisibility(View.VISIBLE);
} else {
- sharedWithYouNoteContainer.setVisibility(View.GONE);
+ binding.sharedWithYouNoteContainer.setVisibility(View.GONE);
}
}
}
- private void setShareWithUserInfo() {
- // TODO Refactoring: create a new {@link ShareUserListAdapter} instance with every call should not be needed
- // to show share with users/groups info
- List shares = fileDataStorageManager.getSharesWithForAFile(file.getRemotePath(),
- user.toPlatformAccount().name);
- if (shares.size() > 0) {
- AccountManager accountManager = AccountManager.get(getContext());
- String userId = accountManager.getUserData(user.toPlatformAccount(),
- com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
-
- usersList.setVisibility(View.VISIBLE);
- usersList.setAdapter(new ShareeListAdapter(fileActivity.getSupportFragmentManager(),
- fileActivity,
- shares,
- user.toPlatformAccount(),
- file,
- this,
- userId));
- usersList.setLayoutManager(new LinearLayoutManager(getContext()));
- usersList.addItemDecoration(new SimpleListItemDividerDecoration(getContext()));
- } else {
- usersList.setVisibility(View.GONE);
- }
- }
-
- @OnClick(R.id.copy_internal_container)
+ @Override
public void copyInternalLink() {
OwnCloudAccount account = accountManager.getCurrentOwnCloudAccount();
@@ -318,7 +267,8 @@ private String createInternalLink(OwnCloudAccount account, OCFile file) {
return account.getBaseUri() + "/index.php/f/" + file.getLocalId();
}
- private void createShareLink() {
+ @Override
+ public void createPublicShareLink() {
if (capabilities != null && (capabilities.getFilesSharingPublicPasswordEnforced().isTrue() ||
capabilities.getFilesSharingPublicAskForOptionalPassword().isTrue())) {
// password enforced by server, request to the user before trying to create
@@ -331,26 +281,80 @@ private void createShareLink() {
}
}
- private void showSendLinkTo() {
+ private void showSendLinkTo(OCShare publicShare) {
if (file.isSharedViaLink()) {
- if (TextUtils.isEmpty(file.getPublicLink())) {
+ if (TextUtils.isEmpty(publicShare.getShareLink())) {
fileOperationsHelper.getFileWithLink(file);
} else {
- FileDisplayActivity.showShareLinkDialog(fileActivity, file, file.getPublicLink());
+ FileDisplayActivity.showShareLinkDialog(fileActivity, file, publicShare.getShareLink());
}
}
}
public void copyLink(OCShare share) {
if (file.isSharedViaLink()) {
- if (TextUtils.isEmpty(file.getPublicLink())) {
+ if (TextUtils.isEmpty(share.getShareLink())) {
fileOperationsHelper.getFileWithLink(file);
} else {
- ClipboardUtil.copyToClipboard(getActivity(), file.getPublicLink());
+ ClipboardUtil.copyToClipboard(getActivity(), share.getShareLink());
}
}
}
+ @Override
+ public void showUserOverflowMenu(OCShare share, ImageView overflowMenu) {
+ // use grey as fallback for elements where custom theming is not available
+ if (ThemeUtils.themingEnabled(requireContext())) {
+ requireContext().getTheme().applyStyle(R.style.FallbackThemingTheme, true);
+ }
+ PopupMenu popup = new PopupMenu(requireContext(), overflowMenu);
+ popup.inflate(R.menu.item_user_sharing_settings);
+ prepareUserOptionsMenu(popup.getMenu(), share);
+ popup.setOnMenuItemClickListener(item -> userOptionsItemSelected(popup.getMenu(), item, share));
+ popup.show();
+ }
+
+ /**
+ * Updates the sharee's menu with the current permissions of the {@link OCShare}
+ *
+ * @param menu the menu of the sharee/shared file
+ * @param share the shared file
+ */
+ @VisibleForTesting
+ public void prepareUserOptionsMenu(Menu menu, OCShare share) {
+ MenuItem allowEditingItem = menu.findItem(R.id.allow_editing);
+ MenuItem allowCreatingItem = menu.findItem(R.id.allow_creating);
+ MenuItem allowDeletingItem = menu.findItem(R.id.allow_deleting);
+ MenuItem expirationDateItem = menu.findItem(R.id.action_expiration_date);
+ MenuItem reshareItem = menu.findItem(R.id.allow_resharing);
+ MenuItem sendNoteItem = menu.findItem(R.id.action_share_send_note);
+
+ allowEditingItem.setChecked(canEdit(share));
+
+ if (isReshareForbidden(share)) {
+ reshareItem.setVisible(false);
+ }
+ reshareItem.setChecked(canReshare(share));
+
+ if (file.isFolder() || share.isFolder()) {
+ allowCreatingItem.setChecked(canCreate(share));
+ allowDeletingItem.setChecked(canDelete(share));
+ } else {
+ allowCreatingItem.setVisible(false);
+ allowDeletingItem.setVisible(false);
+ }
+
+ if (!capabilities.getVersion().isNewerOrEqual(OwnCloudVersion.nextcloud_18)) {
+ expirationDateItem.setVisible(false);
+ }
+
+ SharingMenuHelper.setupExpirationDateMenuItem(menu.findItem(R.id.action_expiration_date),
+ share.getExpirationDate(),
+ getResources());
+
+ sendNoteItem.setVisible(capabilities.getVersion().isNoteOnShareSupported());
+ }
+
public void showLinkOverflowMenu(OCShare publicShare, ImageView overflowMenuShareLink) {
if (ThemeUtils.themingEnabled(requireContext())) {
// use grey as fallback for elements where custom theming is not available
@@ -358,21 +362,45 @@ public void showLinkOverflowMenu(OCShare publicShare, ImageView overflowMenuShar
}
PopupMenu popup = new PopupMenu(requireContext(), overflowMenuShareLink);
- popup.inflate(R.menu.fragment_file_detail_sharing_link);
- prepareOptionsMenu(popup.getMenu(), publicShare);
- popup.setOnMenuItemClickListener(menuItem -> optionsItemSelected(menuItem, publicShare));
+ if (ShareType.EMAIL == publicShare.getShareType()) {
+ popup.inflate(R.menu.fragment_file_detail_sharing_email_link);
+ } else {
+ popup.inflate(R.menu.fragment_file_detail_sharing_public_link);
+ }
+ prepareLinkOptionsMenu(popup.getMenu(), publicShare);
+ popup.setOnMenuItemClickListener(menuItem -> linkOptionsItemSelected(menuItem, publicShare));
popup.show();
}
- private void prepareOptionsMenu(Menu menu, OCShare publicShare) {
- Resources res = requireContext().getResources();
- SharingMenuHelper.setupHideFileListingMenuItem(menu.findItem(R.id.action_hide_file_listing),
- file.isFolder(),
- menu.findItem(R.id.action_allow_editing).isChecked(),
- publicShare.getPermissions());
+ @VisibleForTesting
+ public void prepareLinkOptionsMenu(Menu menu, OCShare publicShare) {
+ if (publicShare.isFolder()) {
+ menu.setGroupVisible(R.id.folder_permission, true);
+ menu.findItem(R.id.allow_editing).setVisible(false);
+
+ // read only / allow upload and editing / file drop
+ if (isUploadAndEditingAllowed(publicShare)) {
+ menu.findItem(R.id.link_share_allow_upload_and_editing).setChecked(true);
+ } else if (isFileDrop(publicShare)) {
+ menu.findItem(R.id.link_share_file_drop).setChecked(true);
+ } else if (isReadOnly(publicShare)) {
+ menu.findItem(R.id.link_share_read_only).setChecked(true);
+ }
+ } else {
+ menu.setGroupVisible(R.id.folder_permission, false);
+ menu.findItem(R.id.allow_editing).setVisible(true);
+
+ if (publicShare.getPermissions() > PERMISSION_EDITING_ALLOWED) {
+ menu.findItem(R.id.allow_editing).setChecked(true);
+ } else {
+ menu.findItem(R.id.allow_editing).setChecked(false);
+ }
+ }
+ Resources res = requireContext().getResources();
SharingMenuHelper.setupHideFileDownload(menu.findItem(R.id.action_hide_file_download),
publicShare.isHideFileDownload(),
+ isFileDrop(publicShare),
capabilities);
SharingMenuHelper.setupPasswordMenuItem(menu.findItem(R.id.action_password),
@@ -383,36 +411,104 @@ private void prepareOptionsMenu(Menu menu, OCShare publicShare) {
res);
menu.findItem(R.id.action_share_send_note).setVisible(capabilities.getVersion().isNoteOnShareSupported());
+ }
- if (publicShare.getPermissions() > PERMISSION_EDITING_ALLOWED) {
- menu.findItem(R.id.action_allow_editing).setChecked(true);
- } else {
- menu.findItem(R.id.action_allow_editing).setChecked(false);
+ @VisibleForTesting
+ public boolean isUploadAndEditingAllowed(OCShare share) {
+ if (share.getPermissions() == NO_PERMISSION) {
+ return false;
}
+
+ return (share.getPermissions() & MAXIMUM_PERMISSIONS_FOR_FOLDER) == MAXIMUM_PERMISSIONS_FOR_FOLDER;
}
- public boolean optionsItemSelected(MenuItem item, OCShare publicShare) {
+ @VisibleForTesting
+ public boolean isReadOnly(OCShare share) {
+ if (share.getPermissions() == NO_PERMISSION) {
+ return false;
+ }
+
+ return (share.getPermissions() & ~SHARE_PERMISSION_FLAG) == READ_PERMISSION_FLAG;
+ }
+
+ @VisibleForTesting
+ public boolean isFileDrop(OCShare share) {
+ if (share.getPermissions() == NO_PERMISSION) {
+ return false;
+ }
+
+ return (share.getPermissions() & ~SHARE_PERMISSION_FLAG) == CREATE_PERMISSION_FLAG;
+ }
+
+ private boolean userOptionsItemSelected(Menu menu, MenuItem item, OCShare share) {
switch (item.getItemId()) {
- case R.id.action_allow_editing:
+ case R.id.allow_editing:
+ case R.id.allow_creating:
+ case R.id.allow_deleting:
+ case R.id.allow_resharing: {
+ item.setChecked(!item.isChecked());
+ share.setPermissions(updatePermissionsToShare(share,
+ menu.findItem(R.id.allow_resharing).isChecked(),
+ menu.findItem(R.id.allow_editing).isChecked(),
+ menu.findItem(R.id.allow_creating).isChecked(),
+ menu.findItem(R.id.allow_deleting).isChecked()));
+ return true;
+ }
+ case R.id.action_unshare: {
+ unshareWith(share);
+ ShareeListAdapter adapter = (ShareeListAdapter) binding.sharesList.getAdapter();
+ if (adapter == null) {
+ DisplayUtils.showSnackMessage(getView(), getString(R.string.failed_update_ui));
+ return true;
+ }
+ adapter.remove(share);
+
+ return true;
+ }
+ case R.id.action_expiration_date: {
+ ExpirationDatePickerDialogFragment dialog = ExpirationDatePickerDialogFragment
+ .newInstance(share, share.getExpirationDate());
+ dialog.show(fileActivity.getSupportFragmentManager(),
+ ExpirationDatePickerDialogFragment.DATE_PICKER_DIALOG);
+ return true;
+ }
+ case R.id.action_share_send_note:
+ NoteDialogFragment dialog = NoteDialogFragment.newInstance(share);
+ dialog.show(fileActivity.getSupportFragmentManager(), NoteDialogFragment.NOTE_FRAGMENT);
+ return true;
+ default:
+ return true;
+ }
+ }
+
+ public boolean linkOptionsItemSelected(MenuItem item, OCShare publicShare) {
+ switch (item.getItemId()) {
+ case R.id.link_share_read_only:
+ item.setChecked(true);
+ fileOperationsHelper.setPermissionsToShare(publicShare, READ_PERMISSION_FLAG);
+ return true;
+ case R.id.link_share_allow_upload_and_editing:
+ item.setChecked(true);
+ if (publicShare.isFolder()) {
+ fileOperationsHelper.setPermissionsToShare(publicShare, MAXIMUM_PERMISSIONS_FOR_FOLDER);
+ } else {
+ fileOperationsHelper.setPermissionsToShare(publicShare, MAXIMUM_PERMISSIONS_FOR_FILE);
+ }
+ return true;
+ case R.id.link_share_file_drop: {
+ item.setChecked(true);
+ fileOperationsHelper.setPermissionsToShare(publicShare, CREATE_PERMISSION_FLAG);
+ return true;
+ }
+ case R.id.allow_editing:
if (file.isSharedViaLink()) {
item.setChecked(!item.isChecked());
fileOperationsHelper.setUploadPermissionsToPublicShare(publicShare, item.isChecked());
}
return true;
- case R.id.action_hide_file_listing: {
- item.setChecked(!item.isChecked());
- fileOperationsHelper.setHideFileListingPermissionsToPublicShare(publicShare, item.isChecked());
- return true;
- }
case R.id.action_hide_file_download:
item.setChecked(!item.isChecked());
fileOperationsHelper.setHideFileDownloadPermissionsToPublicShare(publicShare, item.isChecked());
-
- return true;
- case R.id.action_edit_label:
- RenamePublicShareDialogFragment renameDialog = RenamePublicShareDialogFragment.newInstance(publicShare);
- renameDialog.show(fileActivity.getSupportFragmentManager(),
- RenamePublicShareDialogFragment.RENAME_PUBLIC_SHARE_FRAGMENT);
return true;
case R.id.action_password: {
requestPasswordForShare(publicShare,
@@ -427,10 +523,10 @@ public boolean optionsItemSelected(MenuItem item, OCShare publicShare) {
return true;
}
case R.id.action_share_send_link: {
- if (file.isSharedViaLink() && !TextUtils.isEmpty(file.getPublicLink())) {
- FileDisplayActivity.showShareLinkDialog(fileActivity, file, file.getPublicLink());
+ if (file.isSharedViaLink() && !TextUtils.isEmpty(publicShare.getShareLink())) {
+ FileDisplayActivity.showShareLinkDialog(fileActivity, file, publicShare.getShareLink());
} else {
- showSendLinkTo();
+ showSendLinkTo(publicShare);
}
return true;
}
@@ -438,12 +534,17 @@ public boolean optionsItemSelected(MenuItem item, OCShare publicShare) {
NoteDialogFragment noteDialog = NoteDialogFragment.newInstance(publicShare);
noteDialog.show(fileActivity.getSupportFragmentManager(), NoteDialogFragment.NOTE_FRAGMENT);
return true;
- case R.id.action_add_another_public_share_link:
- createShareLink();
+ case R.id.action_edit_label:
+ RenamePublicShareDialogFragment renameDialog = RenamePublicShareDialogFragment.newInstance(publicShare);
+ renameDialog.show(fileActivity.getSupportFragmentManager(),
+ RenamePublicShareDialogFragment.RENAME_PUBLIC_SHARE_FRAGMENT);
return true;
case R.id.action_unshare:
fileOperationsHelper.unshareShare(file, publicShare);
return true;
+ case R.id.action_add_another_public_share_link:
+ createPublicShareLink();
+ return true;
default:
return super.onOptionsItemSelected(item);
}
@@ -469,28 +570,25 @@ public void onUpdateShareInformation(RemoteOperationResult result, OCFile file)
* Get {@link OCShare} instance from DB and updates the UI.
*/
private void refreshUiFromDB() {
+ refreshSharesFromDB();
// Updates UI with new state
setupView();
}
- @Override
- public void unshareWith(OCShare share) {
+ private void unshareWith(OCShare share) {
fileOperationsHelper.unshareShare(file, share);
}
- @Override
- public int updatePermissionsToShare(OCShare share,
- boolean canReshare,
- boolean canEdit,
- boolean canEditCreate,
- boolean canEditChange,
- boolean canEditDelete) {
+ private int updatePermissionsToShare(OCShare share,
+ boolean canReshare,
+ boolean canEdit,
+ boolean canEditCreate,
+ boolean canEditDelete) {
SharePermissionsBuilder spb = new SharePermissionsBuilder();
spb.setSharePermission(canReshare);
if (file.isFolder()) {
- spb.setUpdatePermission(canEditChange)
- .setCreatePermission(canEditCreate)
+ spb.setCreatePermission(canEditCreate)
.setDeletePermission(canEditDelete);
} else {
spb.setUpdatePermission(canEdit);
@@ -531,38 +629,51 @@ public void refreshCapabilitiesFromDB() {
/**
* Get public link from the DB to fill in the "Share link" section in the UI.
- *
* Takes into account server capabilities before reading database.
*/
- public void refreshPublicShareFromDB() {
+ public void refreshSharesFromDB() {
+ ShareeListAdapter adapter = (ShareeListAdapter) binding.sharesList.getAdapter();
+
+ if (adapter == null) {
+ DisplayUtils.showSnackMessage(getView(), getString(R.string.could_not_retrieve_shares));
+ return;
+ }
+ adapter.getShares().clear();
+
+ // to show share with users/groups info
+ List shares = fileDataStorageManager.getSharesWithForAFile(file.getRemotePath(),
+ user.toPlatformAccount().name);
+
+ adapter.addShares(shares);
+
if (FileDetailSharingFragmentHelper.isPublicShareDisabled(capabilities) || !file.canReshare()) {
- publicShareList.setVisibility(View.GONE);
return;
}
// Get public share
- List shares = fileDataStorageManager.getSharesByPathAndType(file.getRemotePath(),
- ShareType.PUBLIC_LINK,
- "");
-
- if (shares.isEmpty()) {
- addPublicShare.setVisibility(View.VISIBLE);
- publicShareList.setVisibility(View.GONE);
- ImageView icon = requireView().findViewById(R.id.copy_internal_link_icon);
- icon.getBackground().setColorFilter(requireContext()
- .getResources()
- .getColor(R.color.primary_button_background_color),
- PorterDuff.Mode.SRC_IN);
- icon.getDrawable().mutate().setColorFilter(requireContext().getResources().getColor(R.color.black),
- PorterDuff.Mode.SRC_IN);
- requireView().findViewById(R.id.add_new_public_share_link).setOnClickListener(v -> createShareLink());
+ List publicShares = fileDataStorageManager.getSharesByPathAndType(file.getRemotePath(),
+ ShareType.PUBLIC_LINK,
+ "");
+
+
+ if (publicShares.isEmpty() && containsNoNewPublicShare(adapter.getShares())) {
+ publicShares.add(new OCShare().setShareType(ShareType.NEW_PUBLIC_LINK));
} else {
- addPublicShare.setVisibility(View.GONE);
- publicShareList.setVisibility(View.VISIBLE);
- publicShareList.setAdapter(new PublicShareListAdapter(getContext(), shares, this));
- publicShareList.setLayoutManager(new LinearLayoutManager(getContext()));
- publicShareList.addItemDecoration(new SimpleListItemDividerDecoration(getContext()));
+ adapter.removeNewPublicShare();
}
+
+ adapter.addShares(publicShares);
+ }
+
+
+ private boolean containsNoNewPublicShare(List shares) {
+ for (OCShare share : shares) {
+ if (share.getShareType() == ShareType.NEW_PUBLIC_LINK) {
+ return false;
+ }
+ }
+
+ return true;
}
@Override
@@ -575,11 +686,33 @@ public void onSaveInstanceState(@NonNull Bundle outState) {
@Override
public void avatarGenerated(Drawable avatarDrawable, Object callContext) {
- sharedWithYouAvatar.setImageDrawable(avatarDrawable);
+ binding.sharedWithYouAvatar.setImageDrawable(avatarDrawable);
}
@Override
public boolean shouldCallGeneratedCallback(String tag, Object callContext) {
return false;
}
+
+ private boolean isReshareForbidden(OCShare share) {
+ return ShareType.FEDERATED.equals(share.getShareType()) ||
+ capabilities != null && capabilities.getFilesSharingResharing().isFalse();
+ }
+
+ private boolean canEdit(OCShare share) {
+ return (share.getPermissions() &
+ (CREATE_PERMISSION_FLAG | UPDATE_PERMISSION_FLAG | DELETE_PERMISSION_FLAG)) > 0;
+ }
+
+ private boolean canCreate(OCShare share) {
+ return (share.getPermissions() & CREATE_PERMISSION_FLAG) > 0;
+ }
+
+ private boolean canDelete(OCShare share) {
+ return (share.getPermissions() & DELETE_PERMISSION_FLAG) > 0;
+ }
+
+ private boolean canReshare(OCShare share) {
+ return (share.getPermissions() & SHARE_PERMISSION_FLAG) > 0;
+ }
}
diff --git a/src/main/java/com/owncloud/android/ui/fragment/util/SharingMenuHelper.java b/src/main/java/com/owncloud/android/ui/fragment/util/SharingMenuHelper.java
index b322511e26ab..9d53ccc52a2d 100644
--- a/src/main/java/com/owncloud/android/ui/fragment/util/SharingMenuHelper.java
+++ b/src/main/java/com/owncloud/android/ui/fragment/util/SharingMenuHelper.java
@@ -65,11 +65,15 @@ public static void setupHideFileListingMenuItem(MenuItem fileListing,
/**
* Sets checked/visibility state on the given {@link MenuItem} based on the given criteria.
- * @param menuItem the {@link MenuItem} to be setup
+ *
+ * @param menuItem the {@link MenuItem} to be setup
* @param capabilities Capabilities of server to check if hide download is supported
*/
- public static void setupHideFileDownload(MenuItem menuItem, boolean hideFileDownload, OCCapability capabilities) {
- if (!capabilities.getVersion().isHideFileDownloadSupported()) {
+ public static void setupHideFileDownload(MenuItem menuItem,
+ boolean hideFileDownload,
+ boolean isFileDrop,
+ OCCapability capabilities) {
+ if (!capabilities.getVersion().isHideFileDownloadSupported() || isFileDrop) {
menuItem.setVisible(false);
} else {
menuItem.setVisible(true);
diff --git a/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java b/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java
index c61e7e3fe125..e81843e81c51 100755
--- a/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java
+++ b/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java
@@ -578,23 +578,6 @@ public void showShareFile(OCFile file) {
fileActivity.startActivity(intent);
}
-
- /**
- * Updates a public share on a file to set its password. Starts a request to do it in {@link OperationsService}
- *
- * @param password Password to set for the public link; null or empty string to clear the current password
- */
- public void setPasswordToPublicShare(OCShare share, String password) {
- // Set password updating share
- Intent updateShareIntent = new Intent(fileActivity, OperationsService.class);
- updateShareIntent.setAction(OperationsService.ACTION_UPDATE_PUBLIC_SHARE);
- updateShareIntent.putExtra(OperationsService.EXTRA_ACCOUNT, fileActivity.getAccount());
- updateShareIntent.putExtra(OperationsService.EXTRA_SHARE_ID, share.getId());
- updateShareIntent.putExtra(OperationsService.EXTRA_SHARE_PASSWORD, (password == null) ? "" : password);
-
- queueShareIntent(updateShareIntent);
- }
-
/**
* Updates a public share on a file to set its label. Starts a request to do it in {@link OperationsService}
*
@@ -633,23 +616,6 @@ public void setPasswordToShare(OCShare share, String password) {
}
- /**
- * Updates a public share on a file to set its expiration date. Starts a request to do it in {@link
- * OperationsService}
- *
- * @param share {@link OCShare} instance which permissions will be updated.
- * @param expirationTimeInMillis Expiration date to set. A negative value clears the current expiration date,
- * leaving the link unrestricted. Zero makes no change.
- */
- public void setExpirationDateToPublicShare(OCShare share, long expirationTimeInMillis) {
- Intent updateShareIntent = new Intent(fileActivity, OperationsService.class);
- updateShareIntent.setAction(OperationsService.ACTION_UPDATE_PUBLIC_SHARE);
- updateShareIntent.putExtra(OperationsService.EXTRA_ACCOUNT, fileActivity.getAccount());
- updateShareIntent.putExtra(OperationsService.EXTRA_SHARE_ID, share.getId());
- updateShareIntent.putExtra(OperationsService.EXTRA_SHARE_EXPIRATION_DATE_IN_MILLIS, expirationTimeInMillis);
- queueShareIntent(updateShareIntent);
- }
-
/**
* Updates a public share on a file to set its expiration date.
* Starts a request to do it in {@link OperationsService}
@@ -693,31 +659,13 @@ public void setPermissionsToShare(OCShare share, int permissions) {
*/
public void setUploadPermissionsToPublicShare(OCShare share, boolean uploadPermission) {
Intent updateShareIntent = new Intent(fileActivity, OperationsService.class);
- updateShareIntent.setAction(OperationsService.ACTION_UPDATE_PUBLIC_SHARE);
- updateShareIntent.putExtra(OperationsService.EXTRA_ACCOUNT, fileActivity.getAccount());
- updateShareIntent.putExtra(OperationsService.EXTRA_SHARE_ID, share.getId());
- updateShareIntent.putExtra(OperationsService.EXTRA_SHARE_PUBLIC_UPLOAD, uploadPermission);
- queueShareIntent(updateShareIntent);
- }
-
- /**
- * Updates a public share on a folder to set its hide file listing permission.
- * Starts a request to do it in {@link OperationsService}
- *
- * @param share {@link OCShare} instance which permissions will be updated.
- * @param hideFileListing New state of the permission for editing the folder shared via link.
- */
- public void setHideFileListingPermissionsToPublicShare(OCShare share, boolean hideFileListing) {
- Intent updateShareIntent = new Intent(fileActivity, OperationsService.class);
- updateShareIntent.setAction(OperationsService.ACTION_UPDATE_PUBLIC_SHARE);
+ updateShareIntent.setAction(OperationsService.ACTION_UPDATE_USER_SHARE);
updateShareIntent.putExtra(OperationsService.EXTRA_ACCOUNT, fileActivity.getAccount());
updateShareIntent.putExtra(OperationsService.EXTRA_SHARE_ID, share.getId());
-
- if (hideFileListing) {
- updateShareIntent.putExtra(OperationsService.EXTRA_SHARE_PERMISSIONS, OCShare.CREATE_PERMISSION_FLAG);
+ if (uploadPermission) {
+ updateShareIntent.putExtra(OperationsService.EXTRA_SHARE_PERMISSIONS, 3);
} else {
- updateShareIntent.putExtra(OperationsService.EXTRA_SHARE_PERMISSIONS,
- OCShare.FEDERATED_PERMISSIONS_FOR_FOLDER_AFTER_OC9);
+ updateShareIntent.putExtra(OperationsService.EXTRA_SHARE_PERMISSIONS, 1);
}
queueShareIntent(updateShareIntent);
diff --git a/src/main/res/drawable/ic_hide.xml b/src/main/res/drawable/ic_hide.xml
deleted file mode 100644
index dec6ba13172a..000000000000
--- a/src/main/res/drawable/ic_hide.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
diff --git a/src/main/res/drawable/ic_show.xml b/src/main/res/drawable/ic_show.xml
deleted file mode 100644
index a0ead7e544cf..000000000000
--- a/src/main/res/drawable/ic_show.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
diff --git a/src/main/res/drawable/password_visibility_selector.xml b/src/main/res/drawable/password_visibility_selector.xml
deleted file mode 100644
index 71e5a6ace792..000000000000
--- a/src/main/res/drawable/password_visibility_selector.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/res/layout/file_details_fragment.xml b/src/main/res/layout/file_details_fragment.xml
index f69a0abd22b1..e5c3ceb45ccf 100644
--- a/src/main/res/layout/file_details_fragment.xml
+++ b/src/main/res/layout/file_details_fragment.xml
@@ -23,7 +23,6 @@
android:id="@+id/detail_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:fillViewport="true"
android:orientation="vertical">
+ android:layout_height="match_parent" />
diff --git a/src/main/res/layout/file_details_share_internal_share_link.xml b/src/main/res/layout/file_details_share_internal_share_link.xml
new file mode 100644
index 000000000000..6dfe2501f4f9
--- /dev/null
+++ b/src/main/res/layout/file_details_share_internal_share_link.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/res/layout/file_details_share_public_link_item.xml b/src/main/res/layout/file_details_share_link_share_item.xml
similarity index 82%
rename from src/main/res/layout/file_details_share_public_link_item.xml
rename to src/main/res/layout/file_details_share_link_share_item.xml
index f473fc1244ef..a355a45fdeda 100644
--- a/src/main/res/layout/file_details_share_public_link_item.xml
+++ b/src/main/res/layout/file_details_share_link_share_item.xml
@@ -25,11 +25,11 @@
+ android:layout_height="@dimen/sharee_list_item_size"
+ android:orientation="horizontal">
-
-
-
-
-
+
+
+
diff --git a/src/main/res/layout/file_details_sharing_fragment.xml b/src/main/res/layout/file_details_sharing_fragment.xml
index 6778c9ecfd7e..26f93511dcde 100644
--- a/src/main/res/layout/file_details_sharing_fragment.xml
+++ b/src/main/res/layout/file_details_sharing_fragment.xml
@@ -1,5 +1,4 @@
-
-
-
+ android:layout_width="match_parent"
+ android:orientation="vertical"
+ android:paddingTop="@dimen/standard_eight_padding"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools">
+
+
-
-
+ android:layout_marginBottom="@dimen/standard_half_margin"
+ android:layout_width="match_parent"
+ android:orientation="horizontal"
+ android:paddingLeft="@dimen/standard_padding"
+ android:paddingRight="@dimen/standard_padding"
+ android:paddingTop="@dimen/standard_padding">
+
+
-
-
+ android:paddingRight="@dimen/standard_padding"
+ android:paddingTop="@dimen/standard_half_padding">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:layout_width="match_parent"
+ android:text="@string/shared_with_you_by"
+ android:textSize="16sp" />
+ android:orientation="horizontal"
+ android:paddingTop="@dimen/standard_half_padding"
+ tools:ignore="UseCompoundDrawables">
-
+
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:paddingEnd="@dimen/standard_half_padding"
+ android:paddingStart="@dimen/standard_half_padding"
+ android:textSize="16sp" />
-
-
+
+
+
diff --git a/src/main/res/layout/password_dialog.xml b/src/main/res/layout/password_dialog.xml
index 4f927a5d87db..2b5638208486 100644
--- a/src/main/res/layout/password_dialog.xml
+++ b/src/main/res/layout/password_dialog.xml
@@ -18,32 +18,20 @@
-->
+ android:layout_height="match_parent"
+ android:gravity="clip_horizontal"
+ android:orientation="vertical"
+ android:padding="@dimen/standard_padding">
-
-
-
-
-
-
+ android:ems="10"
+ android:hint="@string/hint_password"
+ android:inputType="textPassword"
+ android:autofillHints="password"
+ android:textColorHint="@color/bg_fallback_highlight">
diff --git a/src/main/res/layout/share_user_item.xml b/src/main/res/layout/share_user_item.xml
deleted file mode 100644
index befa156e9c52..000000000000
--- a/src/main/res/layout/share_user_item.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/res/layout/toolbar_standard.xml b/src/main/res/layout/toolbar_standard.xml
index 066082ba4645..481f22579b4d 100644
--- a/src/main/res/layout/toolbar_standard.xml
+++ b/src/main/res/layout/toolbar_standard.xml
@@ -39,7 +39,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize"
android:background="@color/bg_default"
- android:paddingTop="@dimen/standard_eigth_padding"
+ android:paddingTop="@dimen/standard_eight_padding"
android:visibility="gone"
tools:visibility="visible">
diff --git a/src/main/res/menu/fragment_file_detail_sharing_email_link.xml b/src/main/res/menu/fragment_file_detail_sharing_email_link.xml
new file mode 100644
index 000000000000..6fdd4d40f2c9
--- /dev/null
+++ b/src/main/res/menu/fragment_file_detail_sharing_email_link.xml
@@ -0,0 +1,68 @@
+
+
diff --git a/src/main/res/menu/fragment_file_detail_sharing_link.xml b/src/main/res/menu/fragment_file_detail_sharing_public_link.xml
similarity index 80%
rename from src/main/res/menu/fragment_file_detail_sharing_link.xml
rename to src/main/res/menu/fragment_file_detail_sharing_public_link.xml
index e7f7df85f3bd..5aa14cae89a2 100644
--- a/src/main/res/menu/fragment_file_detail_sharing_link.xml
+++ b/src/main/res/menu/fragment_file_detail_sharing_public_link.xml
@@ -1,6 +1,5 @@
-
-