diff options
author | Marcel Hibbe <dev@mhibbe.de> | 2021-02-14 22:49:23 +0300 |
---|---|---|
committer | Marcel Hibbe <dev@mhibbe.de> | 2021-02-15 10:57:57 +0300 |
commit | cc543a660adcbd1e5d732a9ad38bcf7db621c552 (patch) | |
tree | 4bbf62922f0fb0b0df06988a51d53ee581128f63 | |
parent | 0df271cc6717ec3b24c138f02675a8dd1052d259 (diff) |
add confirm dialog before sharing files
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
5 files changed, 122 insertions, 51 deletions
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt index b95f4c8db..46b5aa4da 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt +++ b/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 } diff --git a/app/src/main/java/com/nextcloud/talk/jobs/UploadAndShareFilesWorker.kt b/app/src/main/java/com/nextcloud/talk/jobs/UploadAndShareFilesWorker.kt index 330503c2a..bbc13c299 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/UploadAndShareFilesWorker.kt +++ b/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" diff --git a/app/src/main/java/com/nextcloud/talk/utils/UriUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/UriUtils.kt new file mode 100644 index 000000000..5191036d0 --- /dev/null +++ b/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 + } + +} diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 35eb96282..7716f5ed2 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/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> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a21aaf42c..912c87291 100644 --- a/app/src/main/res/values/strings.xml +++ b/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> |