Fix sentry found issues (#699)
This commit is contained in:
parent
3bb50ff96e
commit
7dbac06983
30 changed files with 237 additions and 70 deletions
33
NOTICE.txt
33
NOTICE.txt
|
|
@ -1090,3 +1090,36 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
## react-native-status-bar-size
|
||||
|
||||
This product contains 'react-native-status-bar-size', Watch and respond to changes in the iOS status bar height.
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/jgkim/react-native-status-bar-size
|
||||
|
||||
* LICENSE:
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Brent Vatne
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -120,12 +120,15 @@ public class CustomPushNotification extends PushNotification {
|
|||
notification
|
||||
.setContentTitle(title)
|
||||
.setContentText(message)
|
||||
.setGroup(GROUP_KEY_MESSAGES)
|
||||
.setGroupSummary(true)
|
||||
.setSmallIcon(smallIconResId)
|
||||
.setVisibility(Notification.VISIBILITY_PRIVATE)
|
||||
.setPriority(Notification.PRIORITY_HIGH);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
notification.setGroup(GROUP_KEY_MESSAGES);
|
||||
}
|
||||
|
||||
if (numMessages > 1) {
|
||||
notification.setNumber(numMessages);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ export function selectInitialChannel(teamId) {
|
|||
// Handle case when the default channel cannot be found
|
||||
// so we need to get the first available channel of the team
|
||||
const channelsInTeam = Object.values(channels).filter((c) => c.team_id === teamId);
|
||||
const firstChannel = channelsInTeam[0].id;
|
||||
const firstChannel = channelsInTeam.length ? channelsInTeam[0].id : {id: ''};
|
||||
dispatch(setChannelDisplayName(''));
|
||||
await handleSelectChannel(firstChannel.id)(dispatch, getState);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,9 +64,17 @@ export function goToNotification(notification) {
|
|||
};
|
||||
}
|
||||
|
||||
export function setStatusBarHeight(height = 20) {
|
||||
return {
|
||||
type: ViewTypes.STATUSBAR_HEIGHT_CHANGED,
|
||||
data: height
|
||||
};
|
||||
}
|
||||
|
||||
export default {
|
||||
loadConfigAndLicense,
|
||||
queueNotification,
|
||||
clearNotification,
|
||||
goToNotification
|
||||
goToNotification,
|
||||
setStatusBarHeight
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,9 +16,15 @@ function mapStateToProps(state, ownProps) {
|
|||
|
||||
let postDraft;
|
||||
if (ownProps.rootId.length) {
|
||||
postDraft = state.views.thread.drafts[ownProps.rootId].draft;
|
||||
const threadDraft = state.views.thread.drafts[ownProps.rootId];
|
||||
if (threadDraft) {
|
||||
postDraft = threadDraft.draft;
|
||||
}
|
||||
} else if (currentChannelId) {
|
||||
postDraft = state.views.channel.drafts[currentChannelId].draft;
|
||||
const channelDraft = state.views.channel.drafts[currentChannelId];
|
||||
if (channelDraft) {
|
||||
postDraft = channelDraft.draft;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -17,9 +17,15 @@ function mapStateToProps(state, ownProps) {
|
|||
|
||||
let postDraft;
|
||||
if (ownProps.rootId.length) {
|
||||
postDraft = state.views.thread.drafts[ownProps.rootId].draft;
|
||||
const threadDraft = state.views.thread.drafts[ownProps.rootId];
|
||||
if (threadDraft) {
|
||||
postDraft = threadDraft.draft;
|
||||
}
|
||||
} else if (currentChannelId) {
|
||||
postDraft = state.views.channel.drafts[currentChannelId].draft;
|
||||
const channelDraft = state.views.channel.drafts[currentChannelId];
|
||||
if (channelDraft) {
|
||||
postDraft = channelDraft.draft;
|
||||
}
|
||||
}
|
||||
|
||||
const autocompleteChannels = {
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ function mapStateToProps(state, ownProps) {
|
|||
|
||||
return {
|
||||
...ownProps,
|
||||
currentTeam: getCurrentTeam(state),
|
||||
currentChannel: getCurrentChannel(state),
|
||||
currentTeam: getCurrentTeam(state) || {},
|
||||
currentChannel: getCurrentChannel(state) || {},
|
||||
currentDisplayName: state.views.channel.displayName,
|
||||
currentUserId,
|
||||
channels: getChannelsWithUnreadSection(state),
|
||||
|
|
|
|||
|
|
@ -101,18 +101,23 @@ class ChannelIntro extends PureComponent {
|
|||
buildDMContent = () => {
|
||||
const {currentChannelMembers, intl, theme} = this.props;
|
||||
const style = getStyleSheet(theme);
|
||||
const teammate = this.getDisplayName(currentChannelMembers[0]);
|
||||
|
||||
return (
|
||||
<Text style={style.message}>
|
||||
{intl.formatMessage({
|
||||
id: 'mobile.intro_messages.DM',
|
||||
defaultMessage: 'This is the start of your direct message history with {teammate}. Direct messages and files shared here are not shown to people outside this area.'
|
||||
}, {
|
||||
teammate
|
||||
})}
|
||||
</Text>
|
||||
);
|
||||
if (currentChannelMembers.length) {
|
||||
const teammate = this.getDisplayName(currentChannelMembers[0]);
|
||||
|
||||
return (
|
||||
<Text style={style.message}>
|
||||
{intl.formatMessage({
|
||||
id: 'mobile.intro_messages.DM',
|
||||
defaultMessage: 'This is the start of your direct message history with {teammate}. Direct messages and files shared here are not shown to people outside this area.'
|
||||
}, {
|
||||
teammate
|
||||
})}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
buildGMContent = () => {
|
||||
|
|
|
|||
|
|
@ -12,15 +12,18 @@ import {getTheme} from 'app/selectors/preferences';
|
|||
import ChannelIntro from './channel_intro';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
const currentChannel = getCurrentChannel(state);
|
||||
const currentUser = getCurrentUser(state);
|
||||
const currentChannel = getCurrentChannel(state) || {};
|
||||
const currentUser = getCurrentUser(state) || {};
|
||||
|
||||
let currentChannelMembers = [];
|
||||
if (currentChannel.type === General.DM_CHANNEL) {
|
||||
const otherChannelMember = currentChannel.name.split('__').find((m) => m !== currentUser.id);
|
||||
currentChannelMembers.push(state.entities.users.profiles[otherChannelMember]);
|
||||
const otherProfile = state.entities.users.profiles[otherChannelMember];
|
||||
if (otherProfile) {
|
||||
currentChannelMembers.push(otherProfile);
|
||||
}
|
||||
} else {
|
||||
currentChannelMembers = getProfilesInCurrentChannel(state);
|
||||
currentChannelMembers = getProfilesInCurrentChannel(state) || [];
|
||||
currentChannelMembers = currentChannelMembers.filter((m) => m.id !== currentUser.id);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import React, {PureComponent} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
View,
|
||||
|
|
@ -35,7 +35,7 @@ const ICON_PATH_FROM_FILE_TYPE = {
|
|||
word: wordIcon
|
||||
};
|
||||
|
||||
export default class FileAttachmentIcon extends Component {
|
||||
export default class FileAttachmentIcon extends PureComponent {
|
||||
static propTypes = {
|
||||
file: PropTypes.object.isRequired,
|
||||
iconHeight: PropTypes.number,
|
||||
|
|
@ -49,7 +49,7 @@ export default class FileAttachmentIcon extends Component {
|
|||
iconWidth: 60,
|
||||
wrapperHeight: 100,
|
||||
wrapperWidth: 100
|
||||
}
|
||||
};
|
||||
|
||||
getFileIconPath(file) {
|
||||
const fileType = Utils.getFileType(file);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,9 @@ const ViewTypes = keyMirror({
|
|||
|
||||
INCREASE_POST_VISIBILITY: null,
|
||||
RECEIVED_FOCUSED_POST: null,
|
||||
LOADING_POSTS: null
|
||||
LOADING_POSTS: null,
|
||||
|
||||
STATUSBAR_HEIGHT_CHANGED: null
|
||||
});
|
||||
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -10,21 +10,24 @@ import {
|
|||
Alert,
|
||||
AppState,
|
||||
InteractionManager,
|
||||
NativeModules,
|
||||
Platform
|
||||
} from 'react-native';
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
import {setJSExceptionHandler} from 'react-native-exception-handler';
|
||||
import StatusBarSizeIOS from 'react-native-status-bar-size';
|
||||
import semver from 'semver';
|
||||
|
||||
import {setAppState, setDeviceToken, setServerVersion} from 'mattermost-redux/actions/general';
|
||||
import {markChannelAsRead} from 'mattermost-redux/actions/channels';
|
||||
import {logError} from 'mattermost-redux/actions/errors';
|
||||
import {logout} from 'mattermost-redux/actions/users';
|
||||
import {close as closeWebSocket} from 'mattermost-redux/actions/websocket';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import {General} from 'mattermost-redux/constants';
|
||||
import EventEmitter from 'mattermost-redux/utils/event_emitter';
|
||||
|
||||
import {goToNotification, loadConfigAndLicense, queueNotification} from 'app/actions/views/root';
|
||||
import {goToNotification, loadConfigAndLicense, queueNotification, setStatusBarHeight} from 'app/actions/views/root';
|
||||
import {setChannelDisplayName} from 'app/actions/views/channel';
|
||||
import {NavigationTypes, ViewTypes} from 'app/constants';
|
||||
import {getTranslations} from 'app/i18n';
|
||||
|
|
@ -35,6 +38,7 @@ import configureStore from 'app/store';
|
|||
|
||||
import Config from 'assets/config';
|
||||
|
||||
const {StatusBarManager} = NativeModules;
|
||||
const store = configureStore(initialState);
|
||||
registerScreens(store, Provider);
|
||||
|
||||
|
|
@ -52,10 +56,20 @@ export default class Mattermost {
|
|||
|
||||
this.handleAppStateChange(AppState.currentState);
|
||||
Client4.setUserAgent(DeviceInfo.getUserAgent());
|
||||
|
||||
if (Platform.OS === 'ios') {
|
||||
StatusBarSizeIOS.addEventListener('willChange', this.handleStatusBarHeightChange);
|
||||
StatusBarManager.getHeight(
|
||||
(data) => {
|
||||
this.handleStatusBarHeightChange(data.height);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
errorHandler = (e, isFatal) => {
|
||||
const intl = this.getIntl();
|
||||
closeWebSocket()(store.dispatch, store.getState);
|
||||
logError(e)(store.dispatch);
|
||||
|
||||
if (isFatal) {
|
||||
|
|
@ -126,6 +140,10 @@ export default class Mattermost {
|
|||
store.dispatch(setChannelDisplayName(displayName));
|
||||
};
|
||||
|
||||
handleStatusBarHeightChange = (nextStatusBarHeight) => {
|
||||
store.dispatch(setStatusBarHeight(nextStatusBarHeight));
|
||||
};
|
||||
|
||||
handleVersionUpgrade = async () => {
|
||||
const {dispatch, getState} = store;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,8 +37,18 @@ function purge(state = false, action) {
|
|||
}
|
||||
}
|
||||
|
||||
function statusBarHeight(state = 20, action) {
|
||||
switch (action.type) {
|
||||
case ViewTypes.STATUSBAR_HEIGHT_CHANGED:
|
||||
return action.data;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export default combineReducers({
|
||||
appInitializing,
|
||||
hydrationComplete,
|
||||
purge
|
||||
purge,
|
||||
statusBarHeight
|
||||
});
|
||||
|
|
|
|||
|
|
@ -161,6 +161,10 @@ class AccountNotifications extends PureComponent {
|
|||
});
|
||||
};
|
||||
|
||||
focusMentionKeys = () => {
|
||||
this.refs.mention_keys.getWrappedInstance().focus();
|
||||
};
|
||||
|
||||
updateMentionKeys = (text) => {
|
||||
this.setState({
|
||||
mention_keys: text
|
||||
|
|
@ -280,6 +284,7 @@ class AccountNotifications extends PureComponent {
|
|||
labelId='user.settings.notifications.sensitiveWords'
|
||||
labelDefaultMessage='Other non-case sensitive words, separated by commas'
|
||||
theme={theme}
|
||||
action={this.focusMentionKeys}
|
||||
>
|
||||
<TextInputWithLocalizedPlaceholder
|
||||
ref='mention_keys'
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ sectionItem.propTypes = {
|
|||
};
|
||||
|
||||
sectionItem.defaultProps = {
|
||||
action: () => true,
|
||||
actionType: ActionTypes.DEFAULT
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import KeyboardLayout from 'app/components/layout/keyboard_layout';
|
|||
import Loading from 'app/components/loading';
|
||||
import OfflineIndicator from 'app/components/offline_indicator';
|
||||
import PostTextbox from 'app/components/post_textbox';
|
||||
import PostListRetry from 'app/components/post_list_retry';
|
||||
import StatusBar from 'app/components/status_bar';
|
||||
import {preventDoubleTap} from 'app/utils/tap';
|
||||
import {makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
|
|
@ -51,7 +52,9 @@ class Channel extends PureComponent {
|
|||
theme: PropTypes.object.isRequired,
|
||||
subscribeToHeaderEvent: PropTypes.func,
|
||||
unsubscribeFromHeaderEvent: PropTypes.func,
|
||||
webSocketRequest: PropTypes.object
|
||||
webSocketRequest: PropTypes.object,
|
||||
statusBarHeight: PropTypes.number,
|
||||
channelsRequestStatus: PropTypes.string
|
||||
};
|
||||
|
||||
componentWillMount() {
|
||||
|
|
@ -163,18 +166,32 @@ class Channel extends PureComponent {
|
|||
});
|
||||
};
|
||||
|
||||
retryLoadChannels = () => {
|
||||
this.loadChannels(this.props.currentTeam.id);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
currentTeam,
|
||||
channelsRequestStatus,
|
||||
currentChannel,
|
||||
drafts,
|
||||
intl,
|
||||
navigator,
|
||||
statusBarHeight,
|
||||
theme
|
||||
} = this.props;
|
||||
|
||||
const style = getStyleFromTheme(theme);
|
||||
|
||||
if (!currentTeam || !currentChannel) {
|
||||
if (!currentChannel.hasOwnProperty('id')) {
|
||||
if (channelsRequestStatus === RequestStatus.FAILURE) {
|
||||
return (
|
||||
<PostListRetry
|
||||
retry={this.retryLoadChannels}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<View style={style.loading}>
|
||||
<Loading/>
|
||||
|
|
@ -182,7 +199,12 @@ class Channel extends PureComponent {
|
|||
);
|
||||
}
|
||||
|
||||
const channelDraft = this.props.drafts[currentChannel.id] || {};
|
||||
const channelDraft = drafts[currentChannel.id] || {};
|
||||
|
||||
let height = 0;
|
||||
if (statusBarHeight > 20) {
|
||||
height = statusBarHeight - 20;
|
||||
}
|
||||
|
||||
return (
|
||||
<ChannelDrawer
|
||||
|
|
@ -194,7 +216,7 @@ class Channel extends PureComponent {
|
|||
<KeyboardLayout
|
||||
behavior='padding'
|
||||
style={style.keyboardLayout}
|
||||
keyboardVerticalOffset={0}
|
||||
keyboardVerticalOffset={height}
|
||||
>
|
||||
<View style={style.postList}>
|
||||
<ChannelPostList
|
||||
|
|
@ -265,7 +287,8 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
|
|||
},
|
||||
keyboardLayout: {
|
||||
backgroundColor: theme.centerChannelBg,
|
||||
flex: 1
|
||||
flex: 1,
|
||||
paddingBottom: 0
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ class ChannelPostList extends PureComponent {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.mounted = true;
|
||||
this.loadPosts(this.props.channel.id);
|
||||
}
|
||||
|
||||
|
|
@ -71,17 +72,25 @@ class ChannelPostList extends PureComponent {
|
|||
this.loadPosts(nextProps.channel.id);
|
||||
}
|
||||
|
||||
const showLoadMore = nextProps.posts.length === this.props.posts.length && nextProps.posts.length > nextProps.postVisibility;
|
||||
const showLoadMore = nextProps.posts.length >= nextProps.postVisibility;
|
||||
this.setState({
|
||||
showLoadMore
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.mounted = false;
|
||||
}
|
||||
|
||||
channelLoaded = () => {
|
||||
Animated.timing(this.state.loaderOpacity, {
|
||||
toValue: 0,
|
||||
duration: 500
|
||||
}).start(() => this.setState({channelLoaded: true}));
|
||||
}).start(() => {
|
||||
if (this.mounted) {
|
||||
this.setState({channelLoaded: true});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
goToThread = (post) => {
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ ChannelTitle.defaultProps = {
|
|||
function mapStateToProps(state) {
|
||||
return {
|
||||
applicationInitializing: state.views.root.appInitializing,
|
||||
currentChannel: getCurrentChannel(state),
|
||||
currentChannel: getCurrentChannel(state) || {},
|
||||
displayName: state.views.channel.displayName,
|
||||
theme: getTheme(state)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -27,14 +27,18 @@ import Channel from './channel';
|
|||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
const {websocket} = state.requests.general;
|
||||
const {myChannels: channelsRequest} = state.requests.channels;
|
||||
const {statusBarHeight} = state.views.root;
|
||||
|
||||
return {
|
||||
...ownProps,
|
||||
...state.views.channel,
|
||||
currentTeam: getCurrentTeam(state),
|
||||
currentChannel: getCurrentChannel(state),
|
||||
currentTeam: getCurrentTeam(state) || {},
|
||||
currentChannel: getCurrentChannel(state) || {},
|
||||
theme: getTheme(state),
|
||||
webSocketRequest: websocket
|
||||
webSocketRequest: websocket,
|
||||
statusBarHeight,
|
||||
channelsRequestStatus: channelsRequest.status
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ import ChannelAddMembers from './channel_add_members';
|
|||
function mapStateToProps(state) {
|
||||
return {
|
||||
theme: getTheme(state),
|
||||
currentChannel: getCurrentChannel(state),
|
||||
currentChannel: getCurrentChannel(state) || {},
|
||||
membersNotInChannel: getProfilesNotInCurrentChannel(state),
|
||||
currentTeam: getCurrentTeam(state),
|
||||
currentTeam: getCurrentTeam(state) || {},
|
||||
preferences: getMyPreferences(state),
|
||||
loadMoreRequestStatus: state.requests.users.getProfilesNotInChannel.status,
|
||||
addChannelMemberRequestStatus: state.requests.channels.addChannelMember,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import ChannelInfo from './channel_info';
|
|||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
const {config, license} = state.entities.general;
|
||||
const currentChannel = getCurrentChannel(state);
|
||||
const currentChannel = getCurrentChannel(state) || {};
|
||||
const currentChannelCreator = getUser(state, currentChannel.creator_id);
|
||||
const currentChannelCreatorName = currentChannelCreator && currentChannelCreator.username;
|
||||
const currentChannelStats = getCurrentChannelStats(state);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import ChannelMembers from './channel_members';
|
|||
function mapStateToProps(state) {
|
||||
return {
|
||||
theme: getTheme(state),
|
||||
currentChannel: getCurrentChannel(state),
|
||||
currentChannel: getCurrentChannel(state) || {},
|
||||
currentChannelMembers: getProfilesInCurrentChannel(state),
|
||||
currentUserId: state.entities.users.currentUserId,
|
||||
preferences: getMyPreferences(state),
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ export default class ImagePreview extends PureComponent {
|
|||
fileId: PropTypes.string.isRequired,
|
||||
files: PropTypes.array.isRequired,
|
||||
navigator: PropTypes.object,
|
||||
statusBarHeight: PropTypes.number,
|
||||
theme: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
|
|
@ -209,6 +210,17 @@ export default class ImagePreview extends PureComponent {
|
|||
render() {
|
||||
const maxImageHeight = this.state.deviceHeight - STATUSBAR_HEIGHT;
|
||||
|
||||
const marginStyle = {
|
||||
...Platform.select({
|
||||
ios: {
|
||||
marginTop: this.props.statusBarHeight
|
||||
},
|
||||
android: {
|
||||
marginTop: 10
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
return (
|
||||
<View
|
||||
style={style.wrapper}
|
||||
|
|
@ -278,7 +290,7 @@ export default class ImagePreview extends PureComponent {
|
|||
pointerEvents='box-none'
|
||||
>
|
||||
<View style={style.header}>
|
||||
<View style={style.headerControls}>
|
||||
<View style={[style.headerControls, marginStyle]}>
|
||||
<TouchableOpacity
|
||||
onPress={this.handleClose}
|
||||
style={style.headerIcon}
|
||||
|
|
@ -353,15 +365,7 @@ const style = StyleSheet.create({
|
|||
headerControls: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-around',
|
||||
flexDirection: 'row',
|
||||
...Platform.select({
|
||||
ios: {
|
||||
marginTop: 20
|
||||
},
|
||||
android: {
|
||||
marginTop: 10
|
||||
}
|
||||
})
|
||||
flexDirection: 'row'
|
||||
},
|
||||
headerIcon: {
|
||||
height: 44,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import {bindActionCreators} from 'redux';
|
||||
import {connect} from 'react-redux';
|
||||
import {Platform} from 'react-native';
|
||||
|
||||
import {addFileToFetchCache} from 'app/actions/views/file_preview';
|
||||
import {getTheme} from 'app/selectors/preferences';
|
||||
|
|
@ -10,6 +11,8 @@ import {makeGetFilesForPost} from 'mattermost-redux/selectors/entities/files';
|
|||
|
||||
import ImagePreview from './image_preview';
|
||||
|
||||
const STATUSBAR_HEIGHT = 20;
|
||||
|
||||
function makeMapStateToProps() {
|
||||
const getFilesForPost = makeGetFilesForPost();
|
||||
return function mapStateToProps(state, ownProps) {
|
||||
|
|
@ -17,7 +20,8 @@ function makeMapStateToProps() {
|
|||
...ownProps,
|
||||
fetchCache: state.views.fetchCache,
|
||||
files: getFilesForPost(state, ownProps.post),
|
||||
theme: getTheme(state)
|
||||
theme: getTheme(state),
|
||||
statusBarHeight: Platform.OS === 'ios' ? state.views.root.statusBarHeight : STATUSBAR_HEIGHT
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ function makeMapStateToProps() {
|
|||
return function mapStateToProps(state, ownProps) {
|
||||
const posts = getPostsForThread(state, ownProps);
|
||||
const threadDraft = state.views.thread.drafts[ownProps.rootId];
|
||||
const {statusBarHeight} = state.views.root;
|
||||
|
||||
return {
|
||||
...ownProps,
|
||||
|
|
@ -30,6 +31,7 @@ function makeMapStateToProps() {
|
|||
draft: threadDraft.draft,
|
||||
files: threadDraft.files,
|
||||
posts,
|
||||
statusBarHeight,
|
||||
theme: getTheme(state)
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ export default class Thread extends PureComponent {
|
|||
rootId: PropTypes.string.isRequired,
|
||||
draft: PropTypes.string.isRequired,
|
||||
theme: PropTypes.object.isRequired,
|
||||
posts: PropTypes.array.isRequired
|
||||
posts: PropTypes.array.isRequired,
|
||||
statusBarHeight: PropTypes.number
|
||||
};
|
||||
|
||||
state = {};
|
||||
|
|
@ -44,14 +45,29 @@ export default class Thread extends PureComponent {
|
|||
};
|
||||
|
||||
render() {
|
||||
const {channelId, draft, files, myMember, navigator, posts, rootId, theme} = this.props;
|
||||
const {
|
||||
channelId,
|
||||
draft,
|
||||
files,
|
||||
myMember,
|
||||
navigator,
|
||||
posts,
|
||||
rootId,
|
||||
statusBarHeight,
|
||||
theme
|
||||
} = this.props;
|
||||
const style = getStyle(theme);
|
||||
|
||||
let height = 0;
|
||||
if (statusBarHeight > 20) {
|
||||
height = statusBarHeight - 20;
|
||||
}
|
||||
|
||||
return (
|
||||
<KeyboardLayout
|
||||
behavior='padding'
|
||||
style={style.container}
|
||||
keyboardVerticalOffset={65}
|
||||
keyboardVerticalOffset={65 + height}
|
||||
>
|
||||
<StatusBar/>
|
||||
<PostList
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ function mapStateToProps(state, ownProps) {
|
|||
navigator: ownProps.navigator,
|
||||
config,
|
||||
createChannelRequest,
|
||||
currentChannel: getCurrentChannel(state),
|
||||
currentChannel: getCurrentChannel(state) || {},
|
||||
currentDisplayName: state.views.channel.displayName,
|
||||
currentUserId: getCurrentUserId(state),
|
||||
user: state.entities.users.profiles[ownProps.userId],
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ export function makeStyleSheetFromTheme(getStyleFromTheme) {
|
|||
|
||||
export function changeOpacity(oldColor, opacity) {
|
||||
let color = oldColor;
|
||||
if (color[0] === '#') {
|
||||
if (color.length && color[0] === '#') {
|
||||
color = color.slice(1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,9 +26,10 @@
|
|||
"react-native-image-picker": "jp928/react-native-image-picker#6ee35b69f3dbd6c7c66f580fd4d9eabf398703d4",
|
||||
"react-native-keyboard-aware-scroll-view": "0.2.8",
|
||||
"react-native-linear-gradient": "2.0.0",
|
||||
"react-native-navigation": "1.1.88",
|
||||
"react-native-navigation": "1.1.131",
|
||||
"react-native-notifications": "enahum/react-native-notifications.git",
|
||||
"react-native-orientation": "yamill/react-native-orientation.git",
|
||||
"react-native-orientation": "enahum/react-native-orientation.git",
|
||||
"react-native-status-bar-size": "0.3.2",
|
||||
"react-native-svg": "5.1.8",
|
||||
"react-native-swiper": "1.5.4",
|
||||
"react-native-tooltip": "enahum/react-native-tooltip",
|
||||
|
|
|
|||
16
yarn.lock
16
yarn.lock
|
|
@ -3645,7 +3645,7 @@ makeerror@1.0.x:
|
|||
|
||||
mattermost-redux@mattermost/mattermost-redux#master:
|
||||
version "0.0.1"
|
||||
resolved "https://codeload.github.com/mattermost/mattermost-redux/tar.gz/5e3133b5041e45252baa23b5a0c2e5b298198c4c"
|
||||
resolved "https://codeload.github.com/mattermost/mattermost-redux/tar.gz/92ed855365d0f014961fcd780a2d93762180ef5e"
|
||||
dependencies:
|
||||
deep-equal "1.0.1"
|
||||
harmony-reflect "1.5.1"
|
||||
|
|
@ -4528,9 +4528,9 @@ react-native-mock@^0.2.7:
|
|||
react-timer-mixin "^0.13.3"
|
||||
warning "^2.1.0"
|
||||
|
||||
react-native-navigation@1.1.88:
|
||||
version "1.1.88"
|
||||
resolved "https://registry.yarnpkg.com/react-native-navigation/-/react-native-navigation-1.1.88.tgz#22239c8c722b13a8750a5b99debd45bded13c2f5"
|
||||
react-native-navigation@1.1.131:
|
||||
version "1.1.131"
|
||||
resolved "https://registry.yarnpkg.com/react-native-navigation/-/react-native-navigation-1.1.131.tgz#79b0583def2310e93305048f7149ad1970666f51"
|
||||
dependencies:
|
||||
lodash "4.x.x"
|
||||
|
||||
|
|
@ -4541,9 +4541,13 @@ react-native-notifications@enahum/react-native-notifications.git:
|
|||
core-js "^1.0.0"
|
||||
uuid "^2.0.3"
|
||||
|
||||
react-native-orientation@yamill/react-native-orientation.git:
|
||||
react-native-orientation@enahum/react-native-orientation.git:
|
||||
version "1.17.0"
|
||||
resolved "https://codeload.github.com/yamill/react-native-orientation/tar.gz/ef221b5720ced0d9ed0c9de14082a5eabba4db7a"
|
||||
resolved "https://codeload.github.com/enahum/react-native-orientation/tar.gz/8b8495c91d8e63598874a141279cf5409e26ad3a"
|
||||
|
||||
react-native-status-bar-size@0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/react-native-status-bar-size/-/react-native-status-bar-size-0.3.2.tgz#e3ffd906f021220c256857a8de6b945f8ea3fabc"
|
||||
|
||||
react-native-svg-mock@1.0.2:
|
||||
version "1.0.2"
|
||||
|
|
|
|||
Loading…
Reference in a new issue