Browse Source

Merge pull request #12085 from nextcloud/feature/use-m3-FileDetailsSharingProcessFragment

Use Material Design 3 For File Details Sharing Process Fragment
Andy Scherzinger 1 year ago
parent
commit
ae658f8b78

+ 44 - 0
app/src/main/java/com/nextcloud/utils/extensions/BundleExtensions.kt

@@ -0,0 +1,44 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Alper Ozturk
+ * Copyright (C) 2023 Alper Ozturk
+ * Copyright (C) 2023 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 <https://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.utils.extensions
+
+import android.os.Build
+import android.os.Bundle
+import android.os.Parcelable
+import java.io.Serializable
+
+fun <T : Serializable?> Bundle.getSerializableArgument(key: String, type: Class<T>): T? {
+    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+        this.getSerializable(key, type)
+    } else {
+        @Suppress("UNCHECKED_CAST")
+        this.getSerializable(key) as T
+    }
+}
+
+fun <T : Parcelable?> Bundle.getParcelableArgument(key: String, type: Class<T>): T? {
+    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+        this.getParcelable(key, type)
+    } else {
+        this.getParcelable(key)
+    }
+}

+ 69 - 61
app/src/main/java/com/owncloud/android/ui/fragment/FileDetailsSharingProcessFragment.kt

@@ -30,6 +30,8 @@ import android.view.View
 import android.view.ViewGroup
 import androidx.fragment.app.Fragment
 import com.nextcloud.client.di.Injectable
+import com.nextcloud.utils.extensions.getParcelableArgument
+import com.nextcloud.utils.extensions.getSerializableArgument
 import com.owncloud.android.R
 import com.owncloud.android.databinding.FileDetailsSharingProcessFragmentBinding
 import com.owncloud.android.datamodel.OCFile
@@ -123,7 +125,7 @@ class FileDetailsSharingProcessFragment :
     private var chosenExpDateInMills: Long = -1 // for no expiry date
 
     private var share: OCShare? = null
-    private var isReshareShown: Boolean = true // show or hide reshare option
+    private var isReShareShown: Boolean = true // show or hide reShare option
     private var isExpDateShown: Boolean = true // show or hide expiry date option
 
     private var expirationDatePickerFragment: ExpirationDatePickerDialogFragment? = null
@@ -139,18 +141,20 @@ class FileDetailsSharingProcessFragment :
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
+
         arguments?.let {
-            file = it.getParcelable(ARG_OCFILE)
+            file = it.getParcelableArgument(ARG_OCFILE, OCFile::class.java)
             shareeName = it.getString(ARG_SHAREE_NAME)
-            share = it.getParcelable(ARG_OCSHARE)
+            share = it.getParcelableArgument(ARG_OCSHARE, OCShare::class.java)
+
             if (it.containsKey(ARG_SHARE_TYPE)) {
-                shareType = it.getSerializable(ARG_SHARE_TYPE) as ShareType
+                shareType = it.getSerializableArgument(ARG_SHARE_TYPE, ShareType::class.java)!!
             } else if (share != null) {
                 shareType = share!!.shareType!!
             }
 
             shareProcessStep = it.getInt(ARG_SCREEN_TYPE, SCREEN_TYPE_PERMISSION)
-            isReshareShown = it.getBoolean(ARG_RESHARE_SHOWN, true)
+            isReShareShown = it.getBoolean(ARG_RESHARE_SHOWN, true)
             isExpDateShown = it.getBoolean(ARG_EXP_DATE_SHOWN, true)
         }
 
@@ -178,8 +182,8 @@ class FileDetailsSharingProcessFragment :
     }
 
     private fun themeView() {
-        viewThemeUtils.platform.colorPrimaryTextViewElement(binding.shareProcessEditShareLink)
-        viewThemeUtils.platform.colorPrimaryTextViewElement(binding.shareProcessAdvancePermissionTitle)
+        viewThemeUtils.platform.colorTextView(binding.shareProcessEditShareLink)
+        viewThemeUtils.platform.colorTextView(binding.shareProcessAdvancePermissionTitle)
 
         viewThemeUtils.platform.themeRadioButton(binding.shareProcessPermissionReadOnly)
         viewThemeUtils.platform.themeRadioButton(binding.shareProcessPermissionUploadEditing)
@@ -218,27 +222,13 @@ class FileDetailsSharingProcessFragment :
         binding.shareProcessEditShareLink.visibility = View.VISIBLE
         binding.shareProcessGroupTwo.visibility = View.GONE
 
-        if (share != null) {
-            setupModificationUI()
-        } else {
-            setupUpdateUI()
-        }
-
-        // show or hide expiry date
-        if (isExpDateShown) {
-            binding.shareProcessSetExpDateSwitch.visibility = View.VISIBLE
-        } else {
-            binding.shareProcessSetExpDateSwitch.visibility = View.GONE
-        }
+        if (share != null) setupModificationUI() else setupUpdateUI()
+        binding.shareProcessSetExpDateSwitch.visibility = if (isExpDateShown) View.VISIBLE else View.GONE
         shareProcessStep = SCREEN_TYPE_PERMISSION
     }
 
     private fun setupModificationUI() {
-        if (share?.isFolder == true) {
-            updateViewForFolder()
-        } else {
-            updateViewForFile()
-        }
+        if (share?.isFolder == true) updateViewForFolder() else updateViewForFile()
 
         // read only / allow upload and editing / file drop
         if (SharingMenuHelper.isUploadAndEditingAllowed(share)) {
@@ -250,13 +240,19 @@ class FileDetailsSharingProcessFragment :
         }
 
         shareType = share?.shareType ?: ShareType.NO_SHARED
+
         // show different text for link share and other shares
         // because we have link to share in Public Link
-        if (shareType == ShareType.PUBLIC_LINK) {
-            binding.shareProcessBtnNext.text = requireContext().resources.getString(R.string.share_copy_link)
-        } else {
-            binding.shareProcessBtnNext.text = requireContext().resources.getString(R.string.common_confirm)
-        }
+        val resources = requireContext().resources
+
+        binding.shareProcessBtnNext.text = resources.getString(
+            if (shareType == ShareType.PUBLIC_LINK) {
+                R.string.share_copy_link
+            } else {
+                R.string.common_confirm
+            }
+        )
+
         updateViewForShareType()
         binding.shareProcessSetPasswordSwitch.isChecked = share?.isPasswordProtected == true
         showPasswordInput(binding.shareProcessSetPasswordSwitch.isChecked)
@@ -278,39 +274,50 @@ class FileDetailsSharingProcessFragment :
         showExpirationDateInput(binding.shareProcessSetExpDateSwitch.isChecked)
     }
 
-    /**
-     * method to update views on the basis of Share type
-     */
     private fun updateViewForShareType() {
-        // external share
-        if (shareType == ShareType.EMAIL) {
-            binding.shareProcessChangeNameSwitch.visibility = View.GONE
-            binding.shareProcessChangeNameContainer.visibility = View.GONE
-            updateViewForExternalAndLinkShare()
-        }
-        // link share
-        else if (shareType == ShareType.PUBLIC_LINK) {
-            updateViewForExternalAndLinkShare()
-            binding.shareProcessChangeNameSwitch.visibility = View.VISIBLE
-            if (share != null) {
-                binding.shareProcessChangeName.setText(share?.label)
-                binding.shareProcessChangeNameSwitch.isChecked = !TextUtils.isEmpty(share?.label)
+        when (shareType) {
+            ShareType.EMAIL -> {
+                updateViewForExternalShare()
+            }
+
+            ShareType.PUBLIC_LINK -> {
+                updateViewForLinkShare()
+            }
+
+            else -> {
+                updateViewForInternalShare()
             }
-            showChangeNameInput(binding.shareProcessChangeNameSwitch.isChecked)
         }
-        // internal share
-        else {
-            binding.shareProcessChangeNameSwitch.visibility = View.GONE
-            binding.shareProcessChangeNameContainer.visibility = View.GONE
-            binding.shareProcessHideDownloadCheckbox.visibility = View.GONE
-            binding.shareProcessAllowResharingCheckbox.visibility = View.VISIBLE
-            binding.shareProcessSetPasswordSwitch.visibility = View.GONE
-            if (share != null) {
-                if (!isReshareShown) {
-                    binding.shareProcessAllowResharingCheckbox.visibility = View.GONE
-                }
-                binding.shareProcessAllowResharingCheckbox.isChecked = SharingMenuHelper.canReshare(share)
+    }
+
+    private fun updateViewForExternalShare() {
+        binding.shareProcessChangeNameSwitch.visibility = View.GONE
+        binding.shareProcessChangeNameContainer.visibility = View.GONE
+        updateViewForExternalAndLinkShare()
+    }
+
+    private fun updateViewForLinkShare() {
+        updateViewForExternalAndLinkShare()
+        binding.shareProcessChangeNameSwitch.visibility = View.VISIBLE
+        if (share != null) {
+            binding.shareProcessChangeName.setText(share?.label)
+            binding.shareProcessChangeNameSwitch.isChecked = !TextUtils.isEmpty(share?.label)
+        }
+        showChangeNameInput(binding.shareProcessChangeNameSwitch.isChecked)
+    }
+
+    private fun updateViewForInternalShare() {
+        binding.shareProcessChangeNameSwitch.visibility = View.GONE
+        binding.shareProcessChangeNameContainer.visibility = View.GONE
+        binding.shareProcessHideDownloadCheckbox.visibility = View.GONE
+        binding.shareProcessAllowResharingCheckbox.visibility = View.VISIBLE
+        binding.shareProcessSetPasswordSwitch.visibility = View.GONE
+
+        if (share != null) {
+            if (!isReShareShown) {
+                binding.shareProcessAllowResharingCheckbox.visibility = View.GONE
             }
+            binding.shareProcessAllowResharingCheckbox.isChecked = SharingMenuHelper.canReshare(share)
         }
     }
 
@@ -337,7 +344,7 @@ class FileDetailsSharingProcessFragment :
      */
     private fun updateExpirationDateView() {
         if (share != null) {
-            if (share?.expirationDate ?: 0 > 0) {
+            if ((share?.expirationDate ?: 0) > 0) {
                 chosenExpDateInMills = share?.expirationDate ?: -1
                 binding.shareProcessSetExpDateSwitch.isChecked = true
                 binding.shareProcessSelectExpDate.text = (
@@ -464,7 +471,7 @@ class FileDetailsSharingProcessFragment :
         fileActivity?.supportFragmentManager?.beginTransaction()?.remove(this)?.commit()
     }
 
-    private fun getResharePermission(): Int {
+    private fun getReSharePermission(): Int {
         val spb = SharePermissionsBuilder()
         spb.setSharePermission(true)
         return spb.build()
@@ -516,12 +523,13 @@ class FileDetailsSharingProcessFragment :
      *  get the permissions on the basis of selection
      */
     private fun getSelectedPermission() = when {
-        binding.shareProcessAllowResharingCheckbox.isChecked -> getResharePermission()
+        binding.shareProcessAllowResharingCheckbox.isChecked -> getReSharePermission()
         binding.shareProcessPermissionReadOnly.isChecked -> OCShare.READ_PERMISSION_FLAG
         binding.shareProcessPermissionUploadEditing.isChecked -> when {
             file?.isFolder == true || share?.isFolder == true -> OCShare.MAXIMUM_PERMISSIONS_FOR_FOLDER
             else -> OCShare.MAXIMUM_PERMISSIONS_FOR_FILE
         }
+
         binding.shareProcessPermissionFileDrop.isChecked -> OCShare.CREATE_PERMISSION_FLAG
         else -> permission
     }

+ 17 - 20
app/src/main/res/layout/file_details_sharing_process_fragment.xml

@@ -62,23 +62,23 @@
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintTop_toBottomOf="@+id/share_process_edit_share_link">
 
-                <androidx.appcompat.widget.AppCompatRadioButton
+                <com.google.android.material.radiobutton.MaterialRadioButton
                     android:id="@+id/share_process_permission_read_only"
-                    android:layout_width="wrap_content"
+                    android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:minHeight="@dimen/minimum_size_for_touchable_area"
                     android:text="@string/link_share_view_only" />
 
-                <androidx.appcompat.widget.AppCompatRadioButton
+                <com.google.android.material.radiobutton.MaterialRadioButton
                     android:id="@+id/share_process_permission_upload_editing"
-                    android:layout_width="wrap_content"
+                    android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:minHeight="@dimen/minimum_size_for_touchable_area"
                     android:text="@string/link_share_allow_upload_and_editing" />
 
-                <androidx.appcompat.widget.AppCompatRadioButton
+                <com.google.android.material.radiobutton.MaterialRadioButton
                     android:id="@+id/share_process_permission_file_drop"
-                    android:layout_width="wrap_content"
+                    android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:minHeight="@dimen/minimum_size_for_touchable_area"
                     android:text="@string/link_share_file_drop" />
@@ -97,19 +97,18 @@
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintTop_toBottomOf="@+id/share_process_permission_radio_group" />
 
-            <androidx.appcompat.widget.AppCompatCheckBox
+            <com.google.android.material.checkbox.MaterialCheckBox
                 android:id="@+id/share_process_allow_resharing_checkbox"
-                android:layout_width="0dp"
+                android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:minHeight="@dimen/minimum_size_for_touchable_area"
                 android:text="@string/allow_resharing"
                 android:visibility="gone"
-                app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintTop_toBottomOf="@+id/share_process_advance_permission_title"
                 tools:visibility="visible" />
 
-            <androidx.appcompat.widget.SwitchCompat
+            <com.google.android.material.materialswitch.MaterialSwitch
                 android:id="@+id/share_process_set_password_switch"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
@@ -144,7 +143,7 @@
 
             </com.google.android.material.textfield.TextInputLayout>
 
-            <androidx.appcompat.widget.SwitchCompat
+            <com.google.android.material.materialswitch.MaterialSwitch
                 android:id="@+id/share_process_set_exp_date_switch"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
@@ -178,7 +177,7 @@
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintTop_toBottomOf="@+id/share_process_select_exp_date" />
 
-            <androidx.appcompat.widget.SwitchCompat
+            <com.google.android.material.materialswitch.MaterialSwitch
                 android:id="@+id/share_process_hide_download_checkbox"
                 android:layout_width="0dp"
                 android:layout_height="wrap_content"
@@ -191,7 +190,7 @@
                 app:layout_constraintTop_toBottomOf="@+id/share_process_exp_date_divider"
                 tools:visibility="visible" />
 
-            <androidx.appcompat.widget.SwitchCompat
+            <com.google.android.material.materialswitch.MaterialSwitch
                 android:id="@+id/share_process_change_name_switch"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
@@ -285,8 +284,8 @@
 
     <com.google.android.material.button.MaterialButton
         android:id="@+id/share_process_btn_cancel"
-        style="@style/OutlinedButton"
-        android:layout_width="0dp"
+        style="@style/Widget.Material3.Button.OutlinedButton"
+        android:layout_width="@dimen/button_width"
         android:layout_height="wrap_content"
         android:layout_marginStart="@dimen/standard_margin"
         android:layout_marginEnd="@dimen/standard_half_margin"
@@ -295,21 +294,19 @@
         app:cornerRadius="@dimen/button_corner_radius"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toStartOf="@+id/share_process_btn_next"
-        app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="@+id/share_process_btn_next" />
 
     <com.google.android.material.button.MaterialButton
         android:id="@+id/share_process_btn_next"
-        android:layout_width="0dp"
+        android:layout_width="@dimen/button_extra_width"
         android:layout_height="wrap_content"
         android:layout_marginStart="@dimen/standard_half_margin"
         android:layout_marginEnd="@dimen/standard_margin"
         android:layout_marginBottom="@dimen/standard_margin"
         android:text="@string/common_next"
-        android:theme="@style/Button.Primary"
+        android:theme="@style/Widget.Material3.Button.IconButton.Filled"
         app:cornerRadius="@dimen/button_corner_radius"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toEndOf="@+id/share_process_btn_cancel" />
+        app:layout_constraintEnd_toEndOf="parent" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 2 - 0
app/src/main/res/values/dims.xml

@@ -39,6 +39,8 @@
     <dimen name="standard_double_margin">32dp</dimen>
     <dimen name="standard_half_margin">8dp</dimen>
     <dimen name="standard_quarter_margin">4dp</dimen>
+    <dimen name="button_width">140dp</dimen>
+    <dimen name="button_extra_width">180dp</dimen>
     <dimen name="standard_eighth_margin">2dp</dimen>
     <dimen name="min_list_item_size">56dp</dimen>
     <dimen name="standard_list_item_size">72dp</dimen>