diff --git a/android/app/build.gradle b/android/app/build.gradle index 5c4ff5abc..ad3578719 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -111,7 +111,7 @@ android { applicationId "com.mattermost.rnbeta" minSdkVersion 21 targetSdkVersion 23 - versionCode 90 + versionCode 91 versionName "1.7.0" multiDexEnabled true ndk { diff --git a/app/actions/views/file_upload.js b/app/actions/views/file_upload.js index c77cd0a52..bf4f29d8b 100644 --- a/app/actions/views/file_upload.js +++ b/app/actions/views/file_upload.js @@ -31,7 +31,7 @@ export function handleUploadFiles(files, rootId) { extension: fileData.extension, }); - fileData.name = encodeHeaderURIStringToUTF8(file.fileName); + fileData.name = encodeHeaderURIStringToUTF8(fileData.name); formData.append('files', fileData); formData.append('channel_id', channelId); formData.append('client_ids', clientId); @@ -60,14 +60,11 @@ export function retryFileUpload(file, rootId) { const channelId = state.entities.channels.currentChannelId; const formData = new FormData(); + const fileData = buildFileUploadData(file); - const fileData = { - uri: file.localPath, - name: file.name, - type: file.type, - }; + fileData.uri = file.localPath; - fileData.name = encodeHeaderURIStringToUTF8(file.fileName); + fileData.name = encodeHeaderURIStringToUTF8(fileData.name); formData.append('files', fileData); formData.append('channel_id', channelId); formData.append('client_ids', file.clientId); diff --git a/app/components/attachment_button.js b/app/components/attachment_button.js index dbdedc122..bb068746b 100644 --- a/app/components/attachment_button.js +++ b/app/components/attachment_button.js @@ -2,13 +2,16 @@ import React, {PureComponent} from 'react'; import PropTypes from 'prop-types'; import {injectIntl, intlShape} from 'react-intl'; import { + Alert, Platform, StyleSheet, TouchableOpacity, } from 'react-native'; import Icon from 'react-native-vector-icons/Ionicons'; import ImagePicker from 'react-native-image-picker'; +import Permissions from 'react-native-permissions'; +import {PermissionTypes} from 'app/constants'; import {changeOpacity} from 'app/utils/theme'; class AttachmentButton extends PureComponent { @@ -29,7 +32,7 @@ class AttachmentButton extends PureComponent { maxFileCount: 5, }; - attachFileFromCamera = () => { + attachFileFromCamera = async () => { const {formatMessage} = this.props.intl; const options = { quality: 1.0, @@ -55,13 +58,17 @@ class AttachmentButton extends PureComponent { }, }; - ImagePicker.launchCamera(options, (response) => { - if (response.error || response.didCancel) { - return; - } + const hasPhotoPermission = await this.hasPhotoPermission(); - this.uploadFiles([response]); - }); + if (hasPhotoPermission) { + ImagePicker.launchCamera(options, (response) => { + if (response.error || response.didCancel) { + return; + } + + this.uploadFiles([response]); + }); + } }; attachFileFromLibrary = () => { @@ -131,6 +138,59 @@ class AttachmentButton extends PureComponent { }); }; + hasPhotoPermission = async () => { + if (Platform.OS === 'ios') { + const {formatMessage} = this.props.intl; + let permissionRequest; + const hasPermissionToStorage = await Permissions.check('photo'); + + switch (hasPermissionToStorage) { + case PermissionTypes.UNDETERMINED: + permissionRequest = await Permissions.request('photo'); + if (permissionRequest !== PermissionTypes.AUTHORIZED) { + return false; + } + break; + case PermissionTypes.DENIED: { + const canOpenSettings = await Permissions.canOpenSettings(); + let grantOption = null; + if (canOpenSettings) { + grantOption = { + text: formatMessage({ + id: 'mobile.android.permission_denied_retry', + defaultMessage: 'Set permission', + }), + onPress: () => Permissions.openSettings(), + }; + } + + Alert.alert( + formatMessage({ + id: 'mobile.android.photos_permission_denied_title', + defaultMessage: 'Photo library access is required', + }), + formatMessage({ + id: 'mobile.android.photos_permission_denied_description', + defaultMessage: 'To upload images from your library, please change your permission settings.', + }), + [ + grantOption, + { + text: formatMessage({ + id: 'mobile.android.permission_denied_dismiss', + defaultMessage: 'Dismiss', + }), + }, + ] + ); + return false; + } + } + } + + return true; + }; + uploadFiles = (images) => { this.props.uploadFiles(images); }; diff --git a/app/components/channel_drawer/channels_list/filtered_list/filtered_list.js b/app/components/channel_drawer/channels_list/filtered_list/filtered_list.js index 5d87373d5..067aa6133 100644 --- a/app/components/channel_drawer/channels_list/filtered_list/filtered_list.js +++ b/app/components/channel_drawer/channels_list/filtered_list/filtered_list.js @@ -53,7 +53,6 @@ class FilteredList extends Component { }; static defaultProps = { - currentTeam: {}, currentChannel: {}, pastDirectMessages: [], }; diff --git a/app/components/channel_drawer/channels_list/filtered_list/index.js b/app/components/channel_drawer/channels_list/filtered_list/index.js index ac8fba2bd..68f3bf3e1 100644 --- a/app/components/channel_drawer/channels_list/filtered_list/index.js +++ b/app/components/channel_drawer/channels_list/filtered_list/index.js @@ -16,6 +16,7 @@ import { getOtherChannels, } from 'mattermost-redux/selectors/entities/channels'; import {getConfig} from 'mattermost-redux/selectors/entities/general'; +import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams'; import {getCurrentUserId, getProfilesInCurrentTeam, getUsers, getUserIdsInChannels, getUserStatuses} from 'mattermost-redux/selectors/entities/users'; import {getDirectShowPreferences, getTeammateNameDisplaySetting, getTheme} from 'mattermost-redux/selectors/entities/preferences'; @@ -109,6 +110,7 @@ function mapStateToProps(state) { return { channels: getChannelsWithUnreadSection(state), currentChannel: getCurrentChannel(state), + currentTeam: getCurrentTeam(state), currentUserId, otherChannels: getOtherChannels(state), groupChannelMemberDetails: getGroupChannelMemberDetails(state), diff --git a/app/components/slack_attachments/index.js b/app/components/message_attachments/index.js similarity index 91% rename from app/components/slack_attachments/index.js rename to app/components/message_attachments/index.js index 7a63401ec..ac08deabb 100644 --- a/app/components/slack_attachments/index.js +++ b/app/components/message_attachments/index.js @@ -7,9 +7,9 @@ import PropTypes from 'prop-types'; import CustomPropTypes from 'app/constants/custom_prop_types'; -import SlackAttachment from './slack_attachment'; +import MessageAttachment from './message_attachment'; -export default class SlackAttachments extends PureComponent { +export default class MessageAttachments extends PureComponent { static propTypes = { attachments: PropTypes.array.isRequired, baseTextStyle: CustomPropTypes.Style, @@ -38,7 +38,7 @@ export default class SlackAttachments extends PureComponent { attachments.forEach((attachment, i) => { content.push( - { return { container: { - borderColor: changeOpacity(theme.centerChannelColor, 0.15), - borderWidth: 1, + borderBottomColor: changeOpacity(theme.centerChannelColor, 0.15), + borderRightColor: changeOpacity(theme.centerChannelColor, 0.15), + borderTopColor: changeOpacity(theme.centerChannelColor, 0.15), + borderBottomWidth: 1, + borderRightWidth: 1, + borderTopWidth: 1, marginTop: 5, padding: 10, }, diff --git a/app/components/post_body_additional_content/post_body_additional_content.js b/app/components/post_body_additional_content/post_body_additional_content.js index 85fea118a..15831c0d5 100644 --- a/app/components/post_body_additional_content/post_body_additional_content.js +++ b/app/components/post_body_additional_content/post_body_additional_content.js @@ -18,7 +18,7 @@ import youTubeVideoId from 'youtube-video-id'; import youtubePlayIcon from 'assets/images/icons/youtube-play-icon.png'; import PostAttachmentOpenGraph from 'app/components/post_attachment_opengraph'; -import SlackAttachments from 'app/components/slack_attachments'; +import MessageAttachments from 'app/components/message_attachments'; import CustomPropTypes from 'app/constants/custom_prop_types'; import {emptyFunction} from 'app/utils/general'; import {isImageLink, isYoutubeLink} from 'app/utils/url'; @@ -109,7 +109,7 @@ export default class PostBodyAdditionalContent extends PureComponent { } const {isReplyPost, link, openGraphData, showLinkPreviews, theme} = this.props; - const attachments = this.getSlackAttachment(); + const attachments = this.getMessageAttachment(); if (attachments) { return attachments; } @@ -154,7 +154,7 @@ export default class PostBodyAdditionalContent extends PureComponent { } }; - getSlackAttachment = () => { + getMessageAttachment = () => { const { postId, postProps, @@ -169,7 +169,7 @@ export default class PostBodyAdditionalContent extends PureComponent { if (attachments && attachments.length) { return ( - { + if (!this.refs.provider) { + setTimeout(this.handleNoTeams, 200); + return; + } + const {currentUrl, navigator, theme} = this.props; const {intl} = this.refs.provider.getChildContext(); diff --git a/ios/Mattermost.xcodeproj/project.pbxproj b/ios/Mattermost.xcodeproj/project.pbxproj index e5723058b..160317d8f 100644 --- a/ios/Mattermost.xcodeproj/project.pbxproj +++ b/ios/Mattermost.xcodeproj/project.pbxproj @@ -2468,7 +2468,7 @@ CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 90; + CURRENT_PROJECT_VERSION = 91; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = UQ8HT4Q2XM; ENABLE_BITCODE = NO; @@ -2517,7 +2517,7 @@ CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 90; + CURRENT_PROJECT_VERSION = 91; DEAD_CODE_STRIPPING = NO; DEVELOPMENT_TEAM = UQ8HT4Q2XM; ENABLE_BITCODE = NO; diff --git a/ios/Mattermost/Info.plist b/ios/Mattermost/Info.plist index 7bb4d6a74..965bf8a7d 100644 --- a/ios/Mattermost/Info.plist +++ b/ios/Mattermost/Info.plist @@ -34,7 +34,7 @@ CFBundleVersion - 90 + 91 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS diff --git a/ios/MattermostShare/Info.plist b/ios/MattermostShare/Info.plist index b82b8d1de..fb798a102 100644 --- a/ios/MattermostShare/Info.plist +++ b/ios/MattermostShare/Info.plist @@ -23,7 +23,7 @@ CFBundleShortVersionString 1.7.0 CFBundleVersion - 90 + 91 NSAppTransportSecurity NSAllowsArbitraryLoads diff --git a/ios/MattermostTests/Info.plist b/ios/MattermostTests/Info.plist index d45ef9a01..2a56a9fa6 100644 --- a/ios/MattermostTests/Info.plist +++ b/ios/MattermostTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 90 + 91