Upgrade RN (#1102)

This commit is contained in:
enahum 2017-11-07 13:34:39 -03:00 committed by GitHub
parent 697e9a1831
commit 9910e3438d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 1310 additions and 1166 deletions

View file

@ -1,58 +1,48 @@
[ignore]
# We fork some components by platform.
; We fork some components by platform
.*/*[.]android.js
# Ignore templates with `@flow` in header
.*/local-cli/generator.*
# Ignore malformed json
.*/node_modules/y18n/test/.*\.json
# Ignore the website subdir
<PROJECT_ROOT>/website/.*
# Ignore BUCK generated dirs
; Ignore "BUCK" generated dirs
<PROJECT_ROOT>/\.buckd/
# Ignore unexpected extra @providesModule
.*/node_modules/commoner/test/source/widget/share.js
; Ignore unexpected extra "@providesModule"
.*/node_modules/.*/node_modules/fbjs/.*
# Ignore duplicate module providers
# For RN Apps installed via npm, "Libraries" folder is inside node_modules/react-native but in the source repo it is in the root
; Ignore duplicate module providers
; For RN Apps installed via npm, "Libraries" folder is inside
; "node_modules/react-native" but in the source repo it is in the root
.*/Libraries/react-native/React.js
.*/Libraries/react-native/ReactNative.js
.*/node_modules/jest-runtime/build/__tests__/.*
; Ignore polyfills
.*/Libraries/polyfills/.*
[include]
[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
node_modules/react-native/flow
flow/
node_modules/react-native/flow/
[options]
emoji=true
module.system=haste
esproposal.class_static_fields=enable
esproposal.class_instance_fields=enable
experimental.strict_type_args=true
munge_underscores=true
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState
suppress_type=$FixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-2]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-2]\\|1[0-9]\\|[1-2][0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(5[0-3]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(5[0-3]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
unsafe.enable_getters_and_setters=true
[version]
^0.32.0
^0.53.0

29
.gitignore vendored
View file

@ -1,5 +1,8 @@
assets/override
dist
*.zip
server.PID
mattermost.keystore
# OSX
#
@ -26,28 +29,27 @@ DerivedData
*.xcuserstate
project.xcworkspace
# Android/IJ
# Android/IntelliJ
#
*.iml
build/
.idea
.gradle
local.properties
*.iml
# node.js
#
node_modules/
npm-debug.log
.npminstall
# yarn
#
yarn-error.log
.yarninstall
# BUCK
buck-out/
\.buckd/
android/app/libs
android/keystores/debug.keystore
*.keystore
# Vim
[._]*.s[a-w][a-z]
@ -58,10 +60,17 @@ Session.vim
*~
tags
fastlane/report.xml
*.zip
server.PID
mattermost.keystore
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/
*/fastlane/report.xml
*/fastlane/Preview.html
*/fastlane/screenshots
# Sentry
android/sentry.properties

View file

@ -121,6 +121,7 @@ post-install:
@sed -i'' -e 's|"./lib/locales": false|"./lib/locales": "./lib/locales"|g' node_modules/intl-relativeformat/package.json
@sed -i'' -e 's|"./locale-data/complete.js": false|"./locale-data/complete.js": "./locale-data/complete.js"|g' node_modules/intl/package.json
@sed -i'' -e 's|auto("auto", Configuration.ORIENTATION_UNDEFINED, ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);|auto("auto", Configuration.ORIENTATION_UNDEFINED, ActivityInfo.SCREEN_ORIENTATION_FULL_USER);|g' node_modules/react-native-navigation/android/app/src/main/java/com/reactnativenavigation/params/Orientation.java
@sed -i'' -e "s|var AndroidTextInput = requireNativeComponent('AndroidTextInput', null);|var AndroidTextInput = requireNativeComponent('CustomTextInput', null);|g" node_modules/react-native/Libraries/Components/TextInput/TextInput.js
@cd ./node_modules/react-native-svg/ios && rm -rf PerformanceBezier && git clone https://github.com/adamwulf/PerformanceBezier.git
@cd ./node_modules/mattermost-redux && yarn run build

View file

@ -1,5 +1,3 @@
import re
# To learn about Buck see [Docs](https://buckbuild.com/).
# To run your application with Buck:
# - install Buck
@ -11,8 +9,9 @@ import re
#
lib_deps = []
for jarfile in glob(['libs/*.jar']):
name = 'jars__' + re.sub(r'^.*/([^/]+)\.jar$', r'\1', jarfile)
name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')]
lib_deps.append(':' + name)
prebuilt_jar(
name = name,
@ -20,7 +19,7 @@ for jarfile in glob(['libs/*.jar']):
)
for aarfile in glob(['libs/*.aar']):
name = 'aars__' + re.sub(r'^.*/([^/]+)\.aar$', r'\1', aarfile)
name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')]
lib_deps.append(':' + name)
android_prebuilt_aar(
name = name,
@ -28,39 +27,39 @@ for aarfile in glob(['libs/*.aar']):
)
android_library(
name = 'all-libs',
exported_deps = lib_deps
name = "all-libs",
exported_deps = lib_deps,
)
android_library(
name = 'app-code',
srcs = glob([
'src/main/java/**/*.java',
]),
deps = [
':all-libs',
':build_config',
':res',
],
name = "app-code",
srcs = glob([
"src/main/java/**/*.java",
]),
deps = [
":all-libs",
":build_config",
":res",
],
)
android_build_config(
name = 'build_config',
package = 'com.mattermost.rnbeta',
name = "build_config",
package = "com.mattermost-mobile",
)
android_resource(
name = 'res',
res = 'src/main/res',
package = 'com.mattermost.rnbeta',
name = "res",
res = "src/main/res",
package = "com.mattermost.rnbeta",
)
android_binary(
name = 'app',
package_type = 'debug',
manifest = 'src/main/AndroidManifest.xml',
keystore = '//android/keystores:debug',
deps = [
':app-code',
],
name = "app",
keystore = "//android/keystores:debug",
manifest = "src/main/AndroidManifest.xml",
package_type = "debug",
deps = [
":app-code",
],
)

View file

@ -33,6 +33,13 @@ import com.android.build.OutputFile
* // bundleInPaidRelease: true,
* // bundleInBeta: true,
*
* // whether to disable dev mode in custom build variants (by default only disabled in release)
* // for example: to disable dev mode in the staging build type (if configured)
* devDisabledInStaging: true,
* // The configuration property can be in the following formats
* // 'devDisabledIn${productFlavor}${buildType}'
* // 'devDisabledIn${buildType}'
*
* // the root of your project, i.e. where "package.json" lives
* root: "../../",
*
@ -58,13 +65,17 @@ import com.android.build.OutputFile
* inputExcludes: ["android/**", "ios/**"],
*
* // override which node gets called and with what additional arguments
* nodeExecutableAndArgs: ["node"]
* nodeExecutableAndArgs: ["node"],
*
* // supply additional arguments to the packager
* extraPackagerArgs: []
* ]
*/
project.ext.react = [
entryFile: "index.js"
]
apply from: "../../node_modules/react-native/react.gradle"
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"

View file

@ -50,6 +50,10 @@
-dontwarn com.facebook.react.**
# TextLayoutBuilder uses a non-public Android constructor within StaticLayout.
# See libs/proxy/src/main/java/com/facebook/fbui/textlayoutbuilder/proxy for details.
-dontwarn android.text.StaticLayout
# okhttp
-keepattributes Signature

View file

@ -0,0 +1,30 @@
package com.mattermost.components;
import android.content.Context;
import android.text.InputType;
import com.facebook.react.views.textinput.ReactEditText;
public class CustomTextInput extends ReactEditText {
private boolean autoScroll = false;
public CustomTextInput(Context context) {
super(context);
}
private boolean isMultiline() {
return (getInputType() & InputType.TYPE_TEXT_FLAG_MULTI_LINE) != 0;
}
@Override
public boolean isLayoutRequested() {
if (isMultiline() && !autoScroll) {
return true;
}
return false;
}
public void setAutoScroll(boolean autoScroll) {
this.autoScroll = autoScroll;
}
}

View file

@ -0,0 +1,35 @@
package com.mattermost.components;
import android.text.InputType;
import android.util.TypedValue;
import com.facebook.react.views.textinput.ReactTextInputManager;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewDefaults;
import com.facebook.react.uimanager.annotations.ReactProp;
public class CustomTextInputManager extends ReactTextInputManager {
@Override
public String getName() {
return "CustomTextInput";
}
@Override
public CustomTextInput createViewInstance(ThemedReactContext context) {
CustomTextInput editText = new CustomTextInput(context);
int inputType = editText.getInputType();
editText.setInputType(inputType & (~InputType.TYPE_TEXT_FLAG_MULTI_LINE));
editText.setReturnKeyType("done");
editText.setTextSize(
TypedValue.COMPLEX_UNIT_PX,
(int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP)));
return editText;
}
@ReactProp(name = "autoScroll", defaultBoolean = false)
public void setAutoScroll(CustomTextInput view, boolean autoScroll) {
view.setAutoScroll(autoScroll);
}
}

View file

@ -70,6 +70,11 @@ public class MainApplication extends NavigationApplication implements INotificat
);
}
@Override
public String getJSMainModuleName() {
return "index";
}
@Override
public void onCreate() {
super.onCreate();

View file

@ -10,6 +10,8 @@ import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.bridge.JavaScriptModule;
import com.mattermost.components.CustomTextInputManager;
public class MattermostPackage implements ReactPackage {
private final MainApplication mApplication;
@ -27,6 +29,8 @@ public class MattermostPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
return Arrays.<ViewManager>asList(
new CustomTextInputManager()
);
}
}

View file

@ -1,8 +1,8 @@
keystore(
name = 'debug',
store = 'debug.keystore',
properties = 'debug.keystore.properties',
visibility = [
'PUBLIC',
],
name = "debug",
properties = "debug.keystore.properties",
store = "debug.keystore",
visibility = [
"PUBLIC",
],
)

4
app.json Normal file
View file

@ -0,0 +1,4 @@
{
"name": "Mattermost",
"displayName": "Mattermost"
}

View file

@ -1,6 +1,8 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import {PostTypes} from 'mattermost-redux/action_types';
import {Client4} from 'mattermost-redux/client';
import {General} from 'mattermost-redux/constants';
import {getClientConfig, getLicenseConfig} from 'mattermost-redux/actions/general';
import {getPosts} from 'mattermost-redux/actions/posts';
@ -63,6 +65,41 @@ export function purgeOfflineStore() {
return {type: General.OFFLINE_STORE_PURGE};
}
export function createPost(post) {
return async (dispatch, getState) => {
const state = getState();
const currentUserId = state.entities.users.currentUserId;
const timestamp = Date.now();
const pendingPostId = post.pending_post_id || `${currentUserId}:${timestamp}`;
const newPost = {
...post,
pending_post_id: pendingPostId,
create_at: timestamp,
update_at: timestamp
};
try {
const payload = Client4.createPost({...newPost, create_at: 0});
dispatch({
type: PostTypes.RECEIVED_POSTS,
data: {
order: [],
posts: {
[payload.id]: payload
}
},
channelId: payload.channel_id
});
} catch (error) {
return {error};
}
return {data: true};
};
}
export default {
loadConfigAndLicense,
loadFromPushNotification,

View file

@ -387,7 +387,7 @@ export default class ChannelDrawer extends Component {
captureGestures='open'
type='static'
acceptTap={true}
acceptPanOnDrawer={true}
acceptPanOnDrawer={false}
disabled={false}
content={this.renderContent()}
tapToClose={true}

View file

@ -69,10 +69,10 @@ class List extends PureComponent {
}
componentDidUpdate(prevProps, prevState) {
if (prevState.sections !== this.state.sections && this.refs.list) {
if (prevState.sections !== this.state.sections && this.refs.list._wrapperListRef.getListRef()._viewabilityHelper) { //eslint-disable-line
this.refs.list.recordInteraction();
this.updateUnreadIndicators({
viewableItems: Array.from(this.refs.list._wrapperListRef._listRef._viewabilityHelper._viewableItems.values()) //eslint-disable-line
viewableItems: Array.from(this.refs.list._wrapperListRef.getListRef()._viewabilityHelper._viewableItems.values()) //eslint-disable-line
});
}
}
@ -286,7 +286,7 @@ class List extends PureComponent {
scrollToTop = () => {
if (this.refs.list) {
this.refs.list._wrapperListRef._listRef.scrollToOffset({ //eslint-disable-line no-underscore-dangle
this.refs.list._wrapperListRef.getListRef().scrollToOffset({ //eslint-disable-line no-underscore-dangle
x: 0,
y: 0,
animated: true

View file

@ -1,48 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {StyleSheet, View} from 'react-native';
import Svg, {
G,
Path
} from 'react-native-svg';
export default class AboveIcon extends PureComponent {
static propTypes = {
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
color: PropTypes.string.isRequired
};
render() {
const {color, height, width} = this.props;
return (
<View style={[style.container, {height, width}]}>
<Svg
width={width}
height={height}
viewBox='0 0 10 10'
>
<G transform='matrix(1,0,0,1,-20,-18)'>
<G transform='matrix(0.0330723,0,0,0.0322634,15.8132,12.3164)'>
<Path
d='M245.803,377.493C245.803,377.493 204.794,336.485 179.398,311.088C168.55,300.24 150.962,300.24 140.114,311.088C138.327,312.875 136.517,314.686 134.73,316.473C123.882,327.321 123.882,344.908 134.73,355.756C167.972,388.998 233.949,454.975 256.949,477.975C262.158,483.184 269.223,486.111 276.591,486.111C277.38,486.111 278.176,486.111 278.965,486.111C286.332,486.111 293.397,483.184 298.607,477.975C321.607,454.975 387.584,388.998 420.826,355.756C431.674,344.908 431.674,327.321 420.826,316.473C419.039,314.686 417.228,312.875 415.441,311.088C404.593,300.24 387.005,300.24 376.158,311.088C350.761,336.485 309.753,377.493 309.753,377.493C309.753,377.493 309.753,279.687 309.753,203.94C309.753,196.573 306.826,189.508 301.617,184.298C296.408,179.089 289.342,176.162 281.975,176.162C279.191,176.162 276.364,176.162 273.58,176.162C266.213,176.162 259.148,179.089 253.939,184.298C248.729,189.508 245.803,196.573 245.803,203.94L245.803,377.493Z'
fill={color}
/>
</G>
</G>
</Svg>
</View>
);
}
}
const style = StyleSheet.create({
container: {
alignItems: 'flex-start',
transform: [{rotate: '180deg'}]
}
});

View file

@ -8,12 +8,11 @@ import {
View,
ViewPropTypes
} from 'react-native';
import IonIcon from 'react-native-vector-icons/Ionicons';
import FormattedText from 'app/components/formatted_text';
import {makeStyleSheetFromTheme} from 'app/utils/theme';
import AboveIcon from './above_icon';
export default class UnreadIndicator extends PureComponent {
static propTypes = {
show: PropTypes.bool,
@ -45,10 +44,11 @@ export default class UnreadIndicator extends PureComponent {
id='sidebar.unreads'
defaultMessage='More unreads'
/>
<AboveIcon
width={12}
height={12}
<IonIcon
size={14}
name='md-arrow-round-up'
color={theme.mentionColor}
style={style.arrow}
/>
</View>
</TouchableWithoutFeedback>
@ -75,6 +75,10 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
paddingHorizontal: 4,
textAlign: 'center',
textAlignVertical: 'center'
},
arrow: {
position: 'relative',
bottom: -1
}
};
});

View file

@ -104,6 +104,10 @@ class PostTextbox extends PureComponent {
}
}
attachAutocomplete = (c) => {
this.autocomplete = c;
};
blur = () => {
this.refs.input.blur();
};
@ -119,6 +123,20 @@ class PostTextbox extends PureComponent {
return valueLength > 0 && valueLength <= MAX_MESSAGE_LENGTH;
};
changeDraft = (text) => {
const {
actions,
channelId,
rootId
} = this.props;
if (rootId) {
actions.handleCommentDraftChanged(rootId, text);
} else {
actions.handlePostDraftChanged(channelId, text);
}
};
handleAndroidKeyboard = () => {
this.blur();
};
@ -132,6 +150,50 @@ class PostTextbox extends PureComponent {
return false;
};
handleBlur = () => {
if (this.refs.input && Platform.OS === 'android') {
this.refs.input.setNativeProps({
autoScroll: false
});
}
};
handleContentSizeChange = (event) => {
let contentHeight = event.nativeEvent.layout.height;
if (contentHeight < INITIAL_HEIGHT) {
contentHeight = INITIAL_HEIGHT;
}
this.setState({
contentHeight
});
};
handleFocus = () => {
if (this.refs.input && Platform.OS === 'android') {
this.refs.input.setNativeProps({
autoScroll: true
});
}
};
handleInputSizeChange = (event) => {
this.setState({
inputWidth: event.nativeEvent.layout.width
});
};
handlePostDraftSelectionChanged = (event) => {
const cursorPosition = event.nativeEvent.selection.end;
if (this.props.rootId) {
this.props.actions.handleCommentDraftSelectionChanged(this.props.rootId, cursorPosition);
} else {
this.props.actions.handlePostDraftSelectionChanged(this.props.channelId, cursorPosition);
}
this.autocomplete.handleSelectionChange(event);
};
handleSendMessage = () => {
if (!this.canSend()) {
return;
@ -171,6 +233,60 @@ class PostTextbox extends PureComponent {
}
};
handleTextChange = (text) => {
const {
actions,
channelId,
rootId
} = this.props;
this.changeDraft(text);
actions.userTyping(channelId, rootId);
};
handleUploadFiles = (images) => {
this.props.actions.handleUploadFiles(images, this.props.rootId);
};
renderDisabledSendButton = () => {
const {theme} = this.props;
const style = getStyleSheet(theme);
return (
<View style={[style.sendButton, style.disableButton]}>
<PaperPlane
height={13}
width={15}
color={theme.buttonColor}
/>
</View>
);
};
renderSendButton = () => {
const {theme, uploadFileRequestStatus} = this.props;
const style = getStyleSheet(theme);
if (uploadFileRequestStatus === RequestStatus.STARTED) {
return this.renderDisabledSendButton();
} else if (this.canSend()) {
return (
<TouchableOpacity
onPress={this.handleSendMessage}
style={style.sendButton}
>
<PaperPlane
height={13}
width={15}
color={theme.buttonColor}
/>
</TouchableOpacity>
);
}
return null;
};
sendMessage = () => {
const {actions, currentUserId, channelId, files, rootId, value} = this.props;
@ -205,126 +321,12 @@ class PostTextbox extends PureComponent {
this.setState(nextState, callback);
};
handleUploadFiles = (images) => {
this.props.actions.handleUploadFiles(images, this.props.rootId);
};
changeDraft = (text) => {
const {
actions,
channelId,
rootId
} = this.props;
if (rootId) {
actions.handleCommentDraftChanged(rootId, text);
} else {
actions.handlePostDraftChanged(channelId, text);
}
}
sendReaction = (emoji) => {
const {actions, rootId} = this.props;
actions.addReactionToLatestPost(emoji, rootId);
this.handleTextChange('');
}
handleTextChange = (text) => {
const {
actions,
channelId,
rootId
} = this.props;
this.changeDraft(text);
actions.userTyping(channelId, rootId);
};
handleContentSizeChange = (event) => {
let contentHeight = event.nativeEvent.layout.height;
if (contentHeight < INITIAL_HEIGHT) {
contentHeight = INITIAL_HEIGHT;
}
this.setState({
contentHeight
});
};
handleInputSizeChange = (event) => {
this.setState({
inputWidth: event.nativeEvent.layout.width
});
};
handleSubmit = () => {
// Workaround for android as the multiline is not working
if (Platform.OS === 'android') {
if (this.timeout) {
clearTimeout(this.timeout);
}
this.timeout = setTimeout(() => {
let {value: msg} = this.props;
msg += '\n';
this.handleTextChange(msg);
}, 10);
}
};
attachAutocomplete = (c) => {
this.autocomplete = c;
};
renderDisabledSendButton = () => {
const {theme} = this.props;
const style = getStyleSheet(theme);
return (
<View style={[style.sendButton, style.disableButton]}>
<PaperPlane
height={13}
width={15}
color={theme.buttonColor}
/>
</View>
);
}
renderSendButton = () => {
const {theme, uploadFileRequestStatus} = this.props;
const style = getStyleSheet(theme);
if (uploadFileRequestStatus === RequestStatus.STARTED) {
return this.renderDisabledSendButton();
} else if (this.canSend()) {
return (
<TouchableOpacity
onPress={this.handleSendMessage}
style={style.sendButton}
>
<PaperPlane
height={13}
width={15}
color={theme.buttonColor}
/>
</TouchableOpacity>
);
}
return null;
}
handlePostDraftSelectionChanged = (event) => {
const cursorPosition = event.nativeEvent.selection.end;
if (this.props.rootId) {
this.props.actions.handleCommentDraftSelectionChanged(this.props.rootId, cursorPosition);
} else {
this.props.actions.handlePostDraftSelectionChanged(this.props.channelId, cursorPosition);
}
this.autocomplete.handleSelectionChange(event);
}
render() {
const {
canUploadFiles,
@ -392,13 +394,14 @@ class PostTextbox extends PureComponent {
placeholder={intl.formatMessage(placeholder)}
placeholderTextColor={changeOpacity('#000', 0.5)}
multiline={true}
numberOfLines={10}
numberOfLines={5}
blurOnSubmit={false}
underlineColorAndroid='transparent'
style={[style.input, {height: textInputHeight}]}
onSubmitEditing={this.handleSubmit}
onLayout={this.handleInputSizeChange}
keyboardType={this.state.keyboardType}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
/>
{this.renderSendButton()}
</View>

View file

@ -217,7 +217,7 @@ export default class SearchBarAndroid extends PureComponent {
styles.searchBarInput,
inputNoBackground,
{height: this.props.inputHeight},
isFocused ? {} : styles.searchBarBlurredInput
isFocused ? {paddingBottom: (this.props.inputHeight - 17) / 2} : styles.searchBarBlurredInput
]}
/>
{isFocused && value ?
@ -253,7 +253,7 @@ const styles = StyleSheet.create({
fontWeight: 'normal',
textAlignVertical: 'center',
fontSize: 15,
includeFontPadding: false
includeFontPadding: true
},
searchBarBlurredInput: {
padding: 0

View file

@ -13,7 +13,8 @@ import {
TextInput,
TouchableWithoutFeedback,
StyleSheet,
View
View,
ViewPropTypes
} from 'react-native';
import EvilIcon from 'react-native-vector-icons/EvilIcons';
import IonIcon from 'react-native-vector-icons/Ionicons';
@ -42,10 +43,10 @@ export default class Search extends Component {
inputStyle: PropTypes.oneOfType([
PropTypes.number,
PropTypes.object,
View.propTypes.style
ViewPropTypes.style
]),
onLayout: PropTypes.func,
cancelButtonStyle: View.propTypes.style,
cancelButtonStyle: ViewPropTypes.style,
autoFocus: PropTypes.bool,
placeholder: PropTypes.string,
cancelTitle: PropTypes.oneOfType([

View file

@ -23,7 +23,6 @@ import {General} from 'mattermost-redux/constants';
import {setAppState, setDeviceToken, setServerVersion} from 'mattermost-redux/actions/general';
import {markChannelAsRead} from 'mattermost-redux/actions/channels';
import {logError} from 'mattermost-redux/actions/errors';
import {createPost} from 'mattermost-redux/actions/posts';
import {logout} from 'mattermost-redux/actions/users';
import {close as closeWebSocket} from 'mattermost-redux/actions/websocket';
import {Client, Client4} from 'mattermost-redux/client';
@ -36,7 +35,7 @@ import {
setStatusBarHeight
} from 'app/actions/device';
import {
createPost,
loadConfigAndLicense,
loadFromPushNotification,
purgeOfflineStore

View file

@ -8,6 +8,7 @@ const CATEGORY = 'CAN_REPLY';
const REPLY_ACTION = 'REPLY_ACTION';
let replyCategory;
const replies = new Set();
class PushNotification {
constructor() {
@ -74,7 +75,8 @@ class PushNotification {
const text = action.text;
const badge = parseInt(action.notification._badge, 10) - 1; //eslint-disable-line no-underscore-dangle
if (this.onReply) {
if (this.onReply && !replies.has(action.completionKey)) {
replies.add(action.completionKey);
this.onReply(data, text, badge, completed);
}
} else {

View file

@ -14,7 +14,7 @@ import EventEmitter from 'mattermost-redux/utils/event_emitter';
import {getGroupDisplayNameFromUserIds} from 'mattermost-redux/utils/channel_utils';
import {displayUsername, filterProfilesMatchingTerm} from 'mattermost-redux/utils/user_utils';
import CustomSectionList from 'app/components/custom_section_list';
import CustomSectionList from 'app/components/custom_list';
import UserListRow from 'app/components/custom_list/user_list_row';
import Loading from 'app/components/loading';
import SearchBar from 'app/components/search_bar';

View file

@ -24,7 +24,7 @@ GEM
faraday_middleware (0.12.2)
faraday (>= 0.7.4, < 1.0)
fastimage (2.1.0)
fastlane (2.62.0)
fastlane (2.63.0)
CFPropertyList (>= 2.3, < 3.0.0)
addressable (>= 2.3, < 3.0.0)
babosa (>= 1.0.2, < 2.0.0)
@ -69,9 +69,9 @@ GEM
mime-types (~> 3.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
googleauth (0.5.3)
googleauth (0.6.1)
faraday (~> 0.12)
jwt (~> 1.4)
jwt (>= 1.4, < 3.0)
logging (~> 2.0)
memoist (~> 0.12)
multi_json (~> 1.11)
@ -82,7 +82,7 @@ GEM
domain_name (~> 0.5)
httpclient (2.8.3)
json (2.1.0)
jwt (1.5.6)
jwt (2.1.0)
little-plugger (1.1.4)
logging (2.2.2)
little-plugger (~> 1.1)
@ -119,21 +119,21 @@ GEM
terminal-notifier (1.8.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
tty-screen (0.5.0)
tty-screen (0.5.1)
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.4)
unicode-display_width (1.3.0)
word_wrap (1.0.0)
xcodeproj (1.5.2)
xcodeproj (1.5.3)
CFPropertyList (~> 2.3.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.2.3)
xcpretty (0.2.8)
rouge (~> 2.0.7)
xcpretty-travis-formatter (0.0.4)
xcpretty-travis-formatter (1.0.0)
xcpretty (~> 0.2, >= 0.0.7)
PLATFORMS

View file

@ -1,10 +0,0 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
/* eslint-disable no-unused-vars */
// import {AppRegistry} from 'react-native';
import Mattermost from 'app/mattermost';
// AppRegistry.registerComponent('Mattermost', () => Mattermost);
const app = new Mattermost();

View file

@ -54,6 +54,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
@ -83,6 +84,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"

View file

@ -26,7 +26,7 @@
{
NSURL *jsCodeLocation;
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor whiteColor];

View file

@ -16,6 +16,11 @@
RCT_EXPORT_MODULE();
+ (BOOL)requiresMainQueueSetup
{
return YES;
}
- (instancetype)init {
if ((self = [super init])) {
[[NSNotificationCenter defaultCenter] addObserver:self

View file

@ -15,6 +15,11 @@
RCT_EXPORT_MODULE();
+ (BOOL)requiresMainQueueSetup
{
return YES;
}
@synthesize bridge = _bridge;
- (void)dealloc

View file

@ -6,7 +6,7 @@ target 'Mattermost' do
# use_frameworks!
# Pods for Mattermost
pod 'XCDYouTubeKit', '2.5'
pod 'XCDYouTubeKit', '~> 2.5'
target 'MattermostTests' do
inherit! :search_paths

View file

@ -2,11 +2,11 @@ PODS:
- XCDYouTubeKit (2.5.0)
DEPENDENCIES:
- XCDYouTubeKit (= 2.5)
- XCDYouTubeKit (~> 2.5)
SPEC CHECKSUMS:
XCDYouTubeKit: 9db45d0f5af8fb5a47561ac7f2fe6de885f57453
PODFILE CHECKSUM: 76eab0e20eee91ac7f71b70b29082dce0d6eba08
PODFILE CHECKSUM: 100c8053d4d12b6c3889d716c02d8b6e1840ed7c
COCOAPODS: 1.3.0

View file

@ -7,91 +7,91 @@
"license": "Apache 2.0",
"private": true,
"dependencies": {
"analytics-react-native": "1.1.0",
"babel-polyfill": "6.23.0",
"analytics-react-native": "1.2.0",
"babel-polyfill": "6.26.0",
"commonmark": "hmhealey/commonmark.js#25dc6a4c456db579631797e29847752cb5e7d8d7",
"commonmark-react-renderer": "hmhealey/commonmark-react-renderer#6e259b66ae87d31d2f908effcd05776b9ea3446f",
"deep-equal": "1.0.1",
"intl": "1.2.5",
"jail-monkey": "0.0.9",
"jail-monkey": "0.1.0",
"mattermost-redux": "mattermost/mattermost-redux#master",
"prop-types": "15.5.10",
"react": "16.0.0-alpha.12",
"react-intl": "2.3.0",
"react-native": "0.48.3",
"react-native-animatable": "1.2.3",
"prop-types": "15.6.0",
"react": "16.0.0",
"react-intl": "2.4.0",
"react-native": "0.49.5",
"react-native-animatable": "1.2.4",
"react-native-bottom-sheet": "1.0.2",
"react-native-button": "1.8.2",
"react-native-circular-progress": "0.0.8",
"react-native-button": "2.1.0",
"react-native-circular-progress": "jaystramel/react-native-circular-progress",
"react-native-cookies": "3.2.0",
"react-native-device-info": "0.11.0",
"react-native-drawer": "2.4.0",
"react-native-exception-handler": "2.1.0",
"react-native-device-info": "0.12.1",
"react-native-drawer": "2.5.0",
"react-native-exception-handler": "2.3.0",
"react-native-fast-image": "1.0.0",
"react-native-fetch-blob": "0.10.8",
"react-native-image-picker": "0.26.6",
"react-native-keyboard-aware-scroll-view": "0.3.0",
"react-native-image-picker": "0.26.7",
"react-native-keyboard-aware-scroll-view": "0.4.1",
"react-native-linear-gradient": "2.3.0",
"react-native-local-auth": "enahum/react-native-local-auth.git",
"react-native-navigation": "1.1.216",
"react-native-navigation": "1.1.260",
"react-native-notifications": "enahum/react-native-notifications.git",
"react-native-orientation": "enahum/react-native-orientation.git",
"react-native-passcode-status": "1.1.0",
"react-native-sentry": "0.15.1",
"react-native-status-bar-size": "0.3.2",
"react-native-svg": "react-native-community/react-native-svg#be8797be5239085d5d09eec90a926ae8da7a8583",
"react-native-svg": "5.4.2",
"react-native-tooltip": "enahum/react-native-tooltip",
"react-native-vector-icons": "4.3.0",
"react-native-youtube": "1.0.0-beta.3",
"react-native-vector-icons": "4.4.2",
"react-native-youtube": "1.0.1",
"react-redux": "5.0.6",
"redux": "3.7.2",
"redux-batched-actions": "0.2.0",
"redux-persist": "4.9.1",
"redux-persist-transform-filter": "0.0.15",
"redux-persist-transform-filter": "0.0.16",
"redux-thunk": "2.2.0",
"reselect": "3.0.1",
"semver": "5.4.1",
"shallow-equals": "1.0.0",
"socketcluster": "5.0.4",
"socketcluster": "9.1.1",
"tinycolor2": "1.4.1",
"url-parse": "1.1.9",
"url-parse": "1.2.0",
"youtube-video-id": "0.0.2"
},
"devDependencies": {
"babel-cli": "6.26.0",
"babel-eslint": "7.2.3",
"babel-eslint": "8.0.1",
"babel-plugin-module-resolver": "2.7.1",
"babel-plugin-transform-remove-console": "6.8.5",
"babel-preset-env": "1.6.1",
"babel-preset-es2015": "6.24.1",
"babel-preset-latest": "6.24.1",
"babel-preset-react": "6.24.1",
"babel-preset-react-native": "3.0.2",
"babel-preset-react-native": "4.0.0",
"babel-preset-stage-0": "6.24.1",
"babel-register": "6.26.0",
"chai": "3.5.0",
"chai-enzyme": "0.6.1",
"chai-fetch-mock": "1.0.0",
"chai": "4.1.2",
"chai-enzyme": "0.8.0",
"chai-fetch-mock": "1.0.1",
"deep-freeze": "0.0.1",
"enzyme": "2.8.2",
"eslint": "4.6.1",
"eslint-plugin-mocha": "4.9.0",
"eslint-plugin-react": "7.3.0",
"fetch-mock": "5.10.0",
"enzyme": "3.1.1",
"eslint": "4.10.0",
"eslint-plugin-mocha": "4.11.0",
"eslint-plugin-react": "7.4.0",
"fetch-mock": "5.13.1",
"form-data": "2.3.1",
"jsdom": "10.1.0",
"jsdom": "11.3.0",
"jsdom-global": "3.0.2",
"mocha": "3.4.1",
"mocha-react-native": "0.5.0",
"mocha": "4.0.1",
"mocha-react-native": "0.6.0",
"mockery": "2.1.0",
"nyc": "10.3.2",
"react-addons-test-utils": "15.5.1",
"react-dom": "15.5.4",
"nyc": "11.3.0",
"react-addons-test-utils": "15.6.2",
"react-dom": "16.0.0",
"react-native-mock": "0.3.1",
"react-native-svg-mock": "1.0.2",
"react-test-renderer": "16.0.0-alpha.12",
"react-native-svg-mock": "1.1.0",
"react-test-renderer": "16.0.0",
"remote-redux-devtools": "0.5.12",
"remote-redux-devtools-on-debugger": "0.8.2",
"remotedev-rn-debugger": "0.8.3",
"underscore": "1.8.3"
},
"scripts": {

1748
yarn.lock

File diff suppressed because it is too large Load diff