Browse Source

add confirm dialog before sharing files

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Marcel Hibbe 4 years ago
parent
commit
cc543a660a

+ 58 - 24
app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt

@@ -28,6 +28,7 @@ import android.content.res.Resources
 import android.graphics.Bitmap
 import android.graphics.PorterDuff
 import android.graphics.drawable.ColorDrawable
+import android.net.Uri
 import android.os.Bundle
 import android.os.Handler
 import android.os.Parcelable
@@ -105,6 +106,7 @@ import com.stfalcon.chatkit.messages.MessagesListAdapter
 import com.stfalcon.chatkit.utils.DateFormatter
 import com.vanniktech.emoji.EmojiPopup
 import com.webianks.library.PopupBubble
+import com.yarolegovich.lovelydialog.LovelyStandardDialog
 import io.reactivex.Observer
 import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.disposables.Disposable
@@ -577,28 +579,63 @@ class ChatController(args: Bundle) : BaseController(args), MessagesListAdapter
         }
     }
 
-    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
         if (requestCode == REQUEST_CODE_CHOOSE_FILE) {
             if (resultCode == RESULT_OK) {
-                uploadFile(data)
+                try {
+                    checkNotNull(intent)
+                    val files: MutableList<String> = ArrayList()
+                    intent.clipData?.let {
+                        for (index in 0 until it.itemCount) {
+                            files.add(it.getItemAt(index).uri.toString())
+                        }
+                    } ?: run {
+                        checkNotNull(intent.data)
+                        intent.data.let {
+                            files.add(intent.data.toString())
+                        }
+                    }
+                    require(files.isNotEmpty())
+
+                    var filenamesWithLinebreaks = "\n"
+                    files.forEach {
+                        var filename = UriUtils.getFileName(Uri.parse(it), context)
+                        filenamesWithLinebreaks += filename + "\n"
+                    }
+
+                    val confirmationQuestion = when(files.size) {
+                        1 -> context?.resources?.getString(R.string.nc_upload_confirm_send_single)?.let {
+                            String.format(it, title)
+                        }
+                        else -> context?.resources?.getString(R.string.nc_upload_confirm_send_multiple)?.let {
+                            String.format(it, title)
+                        }
+                    }
+
+                    LovelyStandardDialog(activity)
+                            .setPositiveButtonColorRes(R.color.nc_darkGreen)
+                            .setTitle(confirmationQuestion)
+                            .setMessage(filenamesWithLinebreaks)
+                            .setPositiveButton(R.string.nc_yes) { v ->
+                                uploadFiles(files)
+                                Toast.makeText(context, context?.resources?.getString(R.string.nc_upload_in_progess), Toast
+                                        .LENGTH_LONG).show();
+                            }
+                            .setNegativeButton(R.string.nc_no) {}
+                            .show()
+                } catch (e: IllegalStateException) {
+                    Toast.makeText(context, context?.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG).show()
+                    Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
+                } catch (e: IllegalArgumentException) {
+                    Toast.makeText(context, context?.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG).show()
+                    Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
+                }
             }
         }
     }
 
-    private fun uploadFile(intentData: Intent?) {
+    private fun uploadFiles(files: MutableList<String>) {
         try {
-            checkNotNull(intentData)
-            val files: MutableList<String> = ArrayList()
-            intentData.clipData?.let {
-                for (index in 0 until it.itemCount) {
-                    files.add(it.getItemAt(index).uri.toString())
-                }
-            } ?: run {
-                checkNotNull(intentData.data)
-                intentData.data.let {
-                    files.add(intentData.data.toString())
-                }
-            }
             require(files.isNotEmpty())
             val data: Data = Data.Builder()
                     .putStringArray(UploadAndShareFilesWorker.DEVICE_SOURCEFILES, files.toTypedArray())
@@ -609,9 +646,6 @@ class ChatController(args: Bundle) : BaseController(args), MessagesListAdapter
                     .setInputData(data)
                     .build()
             WorkManager.getInstance().enqueue(uploadWorker)
-        } catch (e: IllegalStateException) {
-            Toast.makeText(context, context?.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG).show()
-            Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
         } catch (e: IllegalArgumentException) {
             Toast.makeText(context, context?.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG).show()
             Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
@@ -1495,7 +1529,7 @@ class ChatController(args: Bundle) : BaseController(args), MessagesListAdapter
             menu.findItem(R.id.action_copy_message).isVisible = !(message as ChatMessage).isDeleted
             menu.findItem(R.id.action_reply_to_message).isVisible = (message as ChatMessage).replyable
             menu.findItem(R.id.action_delete_message).isVisible = isShowMessageDeletionButton(message)
-            if(menu.hasVisibleItems()){
+            if (menu.hasVisibleItems()) {
                 show()
             }
         }
@@ -1515,22 +1549,22 @@ class ChatController(args: Bundle) : BaseController(args), MessagesListAdapter
     private fun isShowMessageDeletionButton(message: ChatMessage): Boolean {
         if (conversationUser == null) return false
 
-        if(message.systemMessageType != ChatMessage.SystemMessageType.DUMMY) return false
+        if (message.systemMessageType != ChatMessage.SystemMessageType.DUMMY) return false
 
-        if(message.isDeleted) return false
+        if (message.isDeleted) return false
 
         val sixHoursInMillis = 6 * 3600 * 1000
         val isOlderThanSixHours = message.createdAt?.before(Date(System.currentTimeMillis() - sixHoursInMillis)) == true
-        if(isOlderThanSixHours) return false
+        if (isOlderThanSixHours) return false
 
         val isUserAllowedByPrivileges = if (message.actorId == conversationUser.userId) {
             true
         } else {
             currentConversation!!.isParticipantOwnerOrModerator
         }
-        if(!isUserAllowedByPrivileges) return false
+        if (!isUserAllowedByPrivileges) return false
 
-        if(!conversationUser.hasSpreedFeatureCapability("delete-messages")) return false
+        if (!conversationUser.hasSpreedFeatureCapability("delete-messages")) return false
 
         return true
     }

+ 2 - 24
app/src/main/java/com/nextcloud/talk/jobs/UploadAndShareFilesWorker.kt

@@ -32,6 +32,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.models.database.UserEntity
 import com.nextcloud.talk.models.json.generic.GenericOverall
 import com.nextcloud.talk.utils.ApiUtils
+import com.nextcloud.talk.utils.UriUtils
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FILE_PATHS
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
@@ -79,7 +80,7 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
 
             for (index in sourcefiles.indices) {
                 val sourcefileUri = Uri.parse(sourcefiles[index])
-                var filename = getFileName(sourcefileUri)
+                var filename = UriUtils.getFileName(sourcefileUri, context)
                 val requestBody = createRequestBody(sourcefileUri)
                 uploadFile(currentUser, ncTargetpath, filename, roomToken, requestBody)
             }
@@ -146,29 +147,6 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
         WorkManager.getInstance().enqueue(shareWorker)
     }
 
-    private fun getFileName(uri: Uri): String {
-        var filename: String? = null
-        if (uri.scheme == "content") {
-            val cursor: Cursor? = context.contentResolver.query(uri, null, null, null, null)
-            try {
-                if (cursor != null && cursor.moveToFirst()) {
-                    filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME))
-                }
-            } finally {
-                cursor?.close()
-            }
-        }
-        if (filename == null) {
-            Log.e(TAG, "failed to get DISPLAY_NAME from uri. using fallback.")
-            filename = uri.path
-            val lastIndexOfSlash = filename!!.lastIndexOf('/')
-            if (lastIndexOfSlash != -1) {
-                filename = filename.substring(lastIndexOfSlash + 1)
-            }
-        }
-        return filename
-    }
-
     companion object {
         const val TAG = "UploadFileWorker"
         const val DEVICE_SOURCEFILES = "DEVICE_SOURCEFILES"

+ 55 - 0
app/src/main/java/com/nextcloud/talk/utils/UriUtils.kt

@@ -0,0 +1,55 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Marcel Hibbe
+ * Copyright (C) 2021 Marcel Hibbe <dev@mhibbe.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.utils
+
+import android.content.Context
+import android.database.Cursor
+import android.net.Uri
+import android.provider.OpenableColumns
+import android.util.Log
+import com.nextcloud.talk.jobs.UploadAndShareFilesWorker
+
+object UriUtils {
+
+    fun getFileName(uri: Uri, context: Context?): String {
+        var filename: String? = null
+        if (uri.scheme == "content" && context != null) {
+            val cursor: Cursor? = context.contentResolver.query(uri, null, null, null, null)
+            try {
+                if (cursor != null && cursor.moveToFirst()) {
+                    filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME))
+                }
+            } finally {
+                cursor?.close()
+            }
+        }
+        if (filename == null) {
+            Log.e(UploadAndShareFilesWorker.TAG, "failed to get DISPLAY_NAME from uri. using fallback.")
+            filename = uri.path
+            val lastIndexOfSlash = filename!!.lastIndexOf('/')
+            if (lastIndexOfSlash != -1) {
+                filename = filename.substring(lastIndexOfSlash + 1)
+            }
+        }
+        return filename
+    }
+
+}

+ 1 - 0
app/src/main/res/values-night/colors.xml

@@ -26,6 +26,7 @@
 
     <color name="bg_default">#222222</color>
     <color name="bg_alt">#222222</color>
+    <color name="nc_darkGreen">#00AA00</color>
 
     <!-- Chat window incoming message text & informational -->
     <color name="nc_incoming_text_default">#D8D8D8</color>

+ 6 - 3
app/src/main/res/values/strings.xml

@@ -20,6 +20,8 @@
 
 <resources xmlns:tools="http://schemas.android.com/tools">
     <!-- Common -->
+    <string name="nc_yes">Yes</string>
+    <string name="nc_no">No</string>
     <string name="nc_common_error_sorry">Sorry, something went wrong!</string>
 
     <!-- Bottom Navigation -->
@@ -52,8 +54,6 @@
 
     <string name="nc_certificate_dialog_title">Check out the certificate</string>
     <string name="nc_certificate_dialog_text">Do you trust the until now unknown SSL certificate, issued by %1$s for %2$s, valid from %3$s to %4$s?</string>
-    <string name="nc_yes">Yes</string>
-    <string name="nc_no">No</string>
     <string name="nc_certificate_error">Your SSL setup prevented connection</string>
 
     <!-- Settings -->
@@ -329,8 +329,11 @@
     <!-- Upload -->
     <string name="nc_upload_local_file">Upload local file</string>
     <string name="nc_upload_from_nextcloud">Share from Nextcloud</string>
-    <string name="nc_upload_failed">Failed to upload file</string>
+    <string name="nc_upload_failed">Sorry, upload failed</string>
     <string name="nc_upload_choose_local_files">Choose files</string>
+    <string name="nc_upload_confirm_send_multiple">Send these files to %1$s?</string>
+    <string name="nc_upload_confirm_send_single">Send this file to %1$s?</string>
+    <string name="nc_upload_in_progess">uploading</string>
 
     <!-- Phonebook Integration -->
     <string name="nc_settings_phone_book_integration_key" translatable="false">phone_book_integration</string>