From cf85c3c1e8a3f02e042a799d95bfe326faaae164 Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Fri, 3 Aug 2018 13:18:21 -0400 Subject: [PATCH] Fix Android share extension and better handle errors (#1965) --- .../com/mattermost/share/RealPathUtil.java | 23 ++++++++++++-- assets/base/i18n/en.json | 1 + .../android/extension_post/extension_post.js | 31 ++++++++++++++----- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/android/app/src/main/java/com/mattermost/share/RealPathUtil.java b/android/app/src/main/java/com/mattermost/share/RealPathUtil.java index b66ffd831..9515277df 100644 --- a/android/app/src/main/java/com/mattermost/share/RealPathUtil.java +++ b/android/app/src/main/java/com/mattermost/share/RealPathUtil.java @@ -6,6 +6,7 @@ import android.net.Uri; import android.os.Build; import android.provider.DocumentsContract; import android.provider.MediaStore; +import android.provider.OpenableColumns; import android.content.ContentUris; import android.content.ContentResolver; import android.os.Environment; @@ -95,15 +96,33 @@ public class RealPathUtil { public static String getPathFromSavingTempFile(Context context, final Uri uri) { File tmpFile; + String fileName = null; + + // Try and get the filename from the Uri try { - String fileName = uri.getLastPathSegment(); + Cursor returnCursor = + context.getContentResolver().query(uri, null, null, null, null); + int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); + returnCursor.moveToFirst(); + fileName = returnCursor.getString(nameIndex); + } catch (Exception e) { + // just continue to get the filename with the last segment of the path + } + + try { + if (fileName == null) { + fileName = uri.getLastPathSegment().toString().trim(); + } + + File cacheDir = new File(context.getCacheDir(), "mmShare"); if (!cacheDir.exists()) { cacheDir.mkdirs(); } String mimeType = getMimeType(uri.getPath()); - tmpFile = File.createTempFile("tmp", fileName, cacheDir); + tmpFile = new File(cacheDir, fileName); + tmpFile.createNewFile(); ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r"); diff --git a/assets/base/i18n/en.json b/assets/base/i18n/en.json index ddefa5897..99def8192 100644 --- a/assets/base/i18n/en.json +++ b/assets/base/i18n/en.json @@ -2432,6 +2432,7 @@ "mobile.error_handler.description": "\nClick relaunch to open the app again. After restart, you can report the problem from the settings menu.\n", "mobile.error_handler.title": "Unexpected error occurred", "mobile.extension.authentication_required": "Authentication required: Please first login using the app.", + "mobile.extension.file_error": "There was an error reading the file to be shared.\nPlease try again.", "mobile.extension.file_limit": "Sharing is limited to a maximum of 5 files.", "mobile.extension.max_file_size": "File attachments shared in Mattermost must be less than {size}.", "mobile.extension.permission": "Mattermost needs access to the device storage to share files.", diff --git a/share_extension/android/extension_post/extension_post.js b/share_extension/android/extension_post/extension_post.js index 18ce120ec..4829e8bec 100644 --- a/share_extension/android/extension_post/extension_post.js +++ b/share_extension/android/extension_post/extension_post.js @@ -268,10 +268,7 @@ export default class ExtensionPost extends PureComponent { const text = []; const files = []; let totalSize = 0; - - this.props.navigation.setParams({ - post: this.onPost, - }); + let error; for (let i = 0; i < items.length; i++) { const item = items[i]; @@ -280,8 +277,18 @@ export default class ExtensionPost extends PureComponent { text.push(item.value); break; default: { + let fileSize = {size: 0}; const fullPath = item.value; - const fileSize = await RNFetchBlob.fs.stat(fullPath); + try { + fileSize = await RNFetchBlob.fs.stat(fullPath); + } catch (e) { + const {formatMessage} = this.context.intl; + error = formatMessage({ + id: 'mobile.extension.file_error', + defaultMessage: 'There was an error reading the file to be shared.\nPlease try again.', + }); + break; + } let filename = fullPath.replace(/^.*[\\/]/, ''); let extension = filename.split('.').pop(); if (extension === filename) { @@ -305,7 +312,13 @@ export default class ExtensionPost extends PureComponent { const value = text.join('\n'); - this.setState({files, value, hasPermission: true, totalSize}); + if (!error) { + this.props.navigation.setParams({ + post: this.onPost, + }); + } + + this.setState({error, files, value, hasPermission: true, totalSize}); } }; @@ -476,7 +489,11 @@ export default class ExtensionPost extends PureComponent { render() { const {formatMessage} = this.context.intl; const {maxFileSize, token, url} = this.props; - const {hasPermission, files, totalSize} = this.state; + const {error, hasPermission, files, totalSize} = this.state; + + if (error) { + return this.renderErrorMessage(error); + } if (token && url) { if (hasPermission === false) {