diff --git a/app/init/fetch.js b/app/init/fetch.js
index 293c0fe57..bb8f2fb14 100644
--- a/app/init/fetch.js
+++ b/app/init/fetch.js
@@ -7,7 +7,7 @@ import RNFetchBlob from 'rn-fetch-blob';
import urlParse from 'url-parse';
import {Client4} from 'mattermost-redux/client';
-import {ClientError} from 'mattermost-redux/client/client4';
+import {ClientError, HEADER_X_VERSION_ID} from 'mattermost-redux/client/client4';
import mattermostBucket from 'app/mattermost_bucket';
import mattermostManaged from 'app/mattermost_managed';
@@ -111,6 +111,13 @@ Client4.doFetchWithResponse = async (url, options) => {
Client4.setToken(token);
}
+ if (headers[HEADER_X_VERSION_ID] && !headers['Cache-Control']) {
+ const serverVersion = headers[HEADER_X_VERSION_ID];
+ if (serverVersion && Client4.serverVersion !== serverVersion) {
+ Client4.serverVersion = serverVersion; /* eslint-disable-line require-atomic-updates */
+ }
+ }
+
if (response.ok) {
const headersMap = new Map();
Object.keys(headers).forEach((key) => {
diff --git a/app/screens/select_team/index.js b/app/screens/select_team/index.js
index 944e483c7..2c55c91a0 100644
--- a/app/screens/select_team/index.js
+++ b/app/screens/select_team/index.js
@@ -4,7 +4,7 @@
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
-import {getTeams, joinTeam} from 'mattermost-redux/actions/teams';
+import {getTeams, addUserToTeam, joinTeam} from 'mattermost-redux/actions/teams';
import {logout} from 'mattermost-redux/actions/users';
import {getJoinableTeams} from 'mattermost-redux/selectors/entities/teams';
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
@@ -22,7 +22,9 @@ function mapStateToProps(state) {
teamsRequest: state.requests.teams.getTeams,
teams: getJoinableTeams(state),
isLandscape: isLandscape(state),
+ currentUserId: currentUser && currentUser.id,
currentUserIsGuest,
+ serverVersion: state.entities.general.serverVersion,
};
}
@@ -32,6 +34,7 @@ function mapDispatchToProps(dispatch) {
getTeams,
handleTeamChange,
joinTeam,
+ addUserToTeam,
logout,
}, dispatch),
};
diff --git a/app/screens/select_team/select_team.js b/app/screens/select_team/select_team.js
index 9e34ac395..d2c65a731 100644
--- a/app/screens/select_team/select_team.js
+++ b/app/screens/select_team/select_team.js
@@ -14,6 +14,7 @@ import {Navigation} from 'react-native-navigation';
import {RequestStatus} from 'mattermost-redux/constants';
import EventEmitter from 'mattermost-redux/utils/event_emitter';
+import {isMinimumServerVersion} from 'mattermost-redux/utils/helpers';
import FormattedText from 'app/components/formatted_text';
import Loading from 'app/components/loading';
@@ -34,16 +35,19 @@ export default class SelectTeam extends PureComponent {
getTeams: PropTypes.func.isRequired,
handleTeamChange: PropTypes.func.isRequired,
joinTeam: PropTypes.func.isRequired,
+ addUserToTeam: PropTypes.func.isRequired,
logout: PropTypes.func.isRequired,
}).isRequired,
componentId: PropTypes.string.isRequired,
currentUrl: PropTypes.string.isRequired,
currentUserIsGuest: PropTypes.bool.isRequired,
+ currentUserId: PropTypes.string.isRequired,
userWithoutTeams: PropTypes.bool,
teams: PropTypes.array.isRequired,
theme: PropTypes.object,
teamsRequest: PropTypes.object.isRequired,
isLandscape: PropTypes.bool.isRequired,
+ serverVersion: PropTypes.string,
};
static defaultProps = {
@@ -128,13 +132,21 @@ export default class SelectTeam extends PureComponent {
onSelectTeam = async (team) => {
this.setState({joining: true});
- const {userWithoutTeams} = this.props;
+ const {userWithoutTeams, currentUserId, serverVersion} = this.props;
const {
joinTeam,
+ addUserToTeam,
handleTeamChange,
} = this.props.actions;
- const {error} = await joinTeam(team.invite_id, team.id);
+ let error;
+ if (isMinimumServerVersion(serverVersion, 5, 18)) {
+ const result = await addUserToTeam(team.id, currentUserId);
+ error = result.error;
+ } else {
+ const result = await joinTeam(team.invite_id, team.id);
+ error = result.error;
+ }
if (error) {
Alert.alert(error.message);
this.setState({joining: false});
diff --git a/app/screens/select_team/select_team.test.js b/app/screens/select_team/select_team.test.js
index 587bed05a..bd680f892 100644
--- a/app/screens/select_team/select_team.test.js
+++ b/app/screens/select_team/select_team.test.js
@@ -27,6 +27,7 @@ describe('SelectTeam', () => {
const actions = {
getTeams,
handleTeamChange: jest.fn(),
+ addUserToTeam: jest.fn(),
joinTeam: jest.fn(),
logout: jest.fn(),
};
@@ -35,6 +36,7 @@ describe('SelectTeam', () => {
actions,
currentChannelId: 'someId',
currentUserIsGuest: false,
+ currentUserId: 'fakeid',
currentUrl: 'test',
userWithoutTeams: false,
teams: [],
@@ -44,6 +46,7 @@ describe('SelectTeam', () => {
},
componentId: 'component-id',
isLandscape: false,
+ serverVersion: '5.18',
};
test('should match snapshot for fail of teams', async () => {
@@ -100,4 +103,34 @@ describe('SelectTeam', () => {
await getTeams();
expect(wrapper.getElement()).toMatchSnapshot();
});
+
+ test('should call joinTeam versions prior to 5.18', async () => {
+ const props = {
+ ...baseProps,
+ serverVersion: '5.17',
+ };
+
+ const wrapper = shallow(
+ ,
+ );
+ wrapper.instance().onSelectTeam({id: 'test_id', invite_id: 'test_invite_id'});
+
+ expect(props.actions.joinTeam).toBeCalledWith('test_invite_id', 'test_id');
+ expect(props.actions.addUserToTeam).not.toBeCalled();
+ });
+
+ test('should call joinTeam versions posterior to 5.18', async () => {
+ const props = {
+ ...baseProps,
+ serverVersion: '5.18',
+ };
+
+ const wrapper = shallow(
+ ,
+ );
+ wrapper.instance().onSelectTeam({id: 'test_id', invite_id: 'test_invite_id'});
+
+ expect(props.actions.joinTeam).not.toBeCalled();
+ expect(props.actions.addUserToTeam).toBeCalledWith('test_id', 'fakeid');
+ });
});
diff --git a/package-lock.json b/package-lock.json
index f16826d97..090722fdb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4311,7 +4311,7 @@
"dependencies": {
"json5": {
"version": "0.5.1",
- "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
"dev": true
}
@@ -7217,9 +7217,10 @@
}
},
"mattermost-redux": {
- "version": "github:mattermost/mattermost-redux#4e3dedd8323430bf8bbd9338a2577f43b3ef5ab7",
- "from": "github:mattermost/mattermost-redux#4e3dedd8323430bf8bbd9338a2577f43b3ef5ab7",
+ "version": "github:mattermost/mattermost-redux#01b1ec33aece728954df6d93b214dadb28e65063",
+ "from": "github:mattermost/mattermost-redux#01b1ec33aece728954df6d93b214dadb28e65063",
"requires": {
+ "core-js": "3.1.4",
"form-data": "2.5.1",
"gfycat-sdk": "1.4.18",
"isomorphic-fetch": "2.2.1",
@@ -7236,6 +7237,11 @@
"shallow-equals": "1.0.0"
},
"dependencies": {
+ "core-js": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.1.4.tgz",
+ "integrity": "sha512-YNZN8lt82XIMLnLirj9MhKDFZHalwzzrL9YLt6eb0T5D0EDl4IQ90IGkua8mHbnxNrkj1d8hbdizMc0Qmg1WnQ=="
+ },
"moment-timezone": {
"version": "0.5.26",
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.26.tgz",
@@ -8285,7 +8291,7 @@
}
},
"mmjstool": {
- "version": "github:mattermost/mattermost-utilities#ce99d7a9e82128a02fd36e44720a4aef2653810d",
+ "version": "github:mattermost/mattermost-utilities#b3e2e308b8b85469849a91c21958b46a89ab33ab",
"from": "github:mattermost/mattermost-utilities",
"dev": true,
"requires": {
diff --git a/package.json b/package.json
index 7e32d06f3..85fd2aeeb 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,7 @@
"intl": "1.2.5",
"jail-monkey": "2.3.0",
"jsc-android": "241213.1.0",
- "mattermost-redux": "github:mattermost/mattermost-redux#4e3dedd8323430bf8bbd9338a2577f43b3ef5ab7",
+ "mattermost-redux": "github:mattermost/mattermost-redux#01b1ec33aece728954df6d93b214dadb28e65063",
"mime-db": "1.42.0",
"moment-timezone": "0.5.27",
"prop-types": "15.7.2",