Commit f4bcf29c authored by jbuechele's avatar jbuechele
Browse files

Merge branch 'develop' into v2.5.0

# Conflicts:
#	ios/NotificationService/Info.plist
#	ios/ShareRocketChatRN/Info.plist
parents 47df31d6 a56dade1
......@@ -237,9 +237,13 @@ commands:
if [[ $CIRCLE_JOB == "ios-build-official" ]]; then
/usr/libexec/PlistBuddy -c "Set BugsnagAPIKey $BUGSNAG_KEY_OFFICIAL" ./RocketChatRN/Info.plist
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL YES" ./RocketChatRN/Info.plist
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL YES" ./ShareRocketChatRN/Info.plist
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL YES" ./NotificationService/Info.plist
else
/usr/libexec/PlistBuddy -c "Set BugsnagAPIKey $BUGSNAG_KEY" ./RocketChatRN/Info.plist
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./RocketChatRN/Info.plist
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./ShareRocketChatRN/Info.plist
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./NotificationService/Info.plist
fi
if [[ $APP_STORE_CONNECT_API_KEY ]]; then
......
......@@ -29,7 +29,7 @@
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:exported="true"
android:label="@string/app_name"
android:launchMode="singleTop"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
......
......@@ -11,8 +11,12 @@ import { getActiveRoute } from '../../utils/navigation';
export const INAPP_NOTIFICATION_EMITTER = 'NotificationInApp';
const InAppNotification = memo(({ rooms }) => {
const InAppNotification = memo(({ rooms, appState }) => {
const show = (notification) => {
if (appState !== 'foreground') {
return;
}
const { payload } = notification;
const state = Navigation.navigationRef.current?.getRootState();
const route = getActiveRoute(state);
......@@ -41,11 +45,13 @@ const InAppNotification = memo(({ rooms }) => {
}, (prevProps, nextProps) => dequal(prevProps.rooms, nextProps.rooms));
const mapStateToProps = state => ({
rooms: state.room.rooms
rooms: state.room.rooms,
appState: state.app.ready && state.app.foreground ? 'foreground' : 'background'
});
InAppNotification.propTypes = {
rooms: PropTypes.array
rooms: PropTypes.array,
appState: PropTypes.string
};
export default connect(mapStateToProps)(InAppNotification);
......@@ -939,7 +939,7 @@ class MessageBox extends Component {
keyboardType='twitter'
blurOnSubmit={false}
placeholder={I18n.t('New_Message')}
placeholderTextColor={themes[theme].auxiliaryTintColor}
placeholderTextColor={themes[theme].auxiliaryText}
onChangeText={this.onChangeText}
onSelectionChange={this.onSelectionChange}
underlineColorAndroid='transparent'
......
......@@ -112,16 +112,25 @@ export default class Root extends React.Component {
init = async() => {
UserPreferences.getMapAsync(THEME_PREFERENCES_KEY).then(this.setTheme);
const [notification, deepLinking] = await Promise.all([initializePushNotifications(), Linking.getInitialURL()]);
const parsedDeepLinkingURL = parseDeepLinking(deepLinking);
store.dispatch(appInitLocalSettings());
// Open app from push notification
const notification = await initializePushNotifications();
if (notification) {
onNotification(notification);
} else if (parsedDeepLinkingURL) {
return;
}
// Open app from deep linking
const deepLinking = await Linking.getInitialURL();
const parsedDeepLinkingURL = parseDeepLinking(deepLinking);
if (parsedDeepLinkingURL) {
store.dispatch(deepLinkingOpen(parsedDeepLinkingURL));
} else {
store.dispatch(appInit());
return;
}
// Open app from app icon
store.dispatch(appInit());
}
getMasterDetail = (width) => {
......
......@@ -407,7 +407,7 @@ export default function subscribeRooms() {
};
connectedListener = this.sdk.onStreamData('connected', handleConnection);
disconnectedListener = this.sdk.onStreamData('close', handleConnection);
// disconnectedListener = this.sdk.onStreamData('close', handleConnection);
streamListener = this.sdk.onStreamData('stream-notify-user', handleStreamMessageReceived);
try {
......
......@@ -177,9 +177,16 @@ const RocketChat = {
}
this.controller = new AbortController();
},
checkAndReopen() {
return this?.sdk?.checkAndReopen();
},
connect({ server, user, logoutOnError = false }) {
return new Promise((resolve) => {
if (!this.sdk || this.sdk.client.host !== server) {
if (this?.sdk?.client?.host === server) {
return resolve();
} else {
this.sdk?.disconnect?.();
this.sdk = null;
database.setActiveDB(server);
}
reduxStore.dispatch(connectRequest());
......@@ -208,11 +215,6 @@ const RocketChat = {
EventEmitter.emit('INQUIRY_UNSUBSCRIBE');
if (this.sdk) {
this.sdk.disconnect();
this.sdk = null;
}
if (this.code) {
this.code = null;
}
......@@ -240,6 +242,10 @@ const RocketChat = {
sdkConnect();
this.connectedListener = this.sdk.onStreamData('connecting', () => {
reduxStore.dispatch(connectRequest());
});
this.connectedListener = this.sdk.onStreamData('connected', () => {
reduxStore.dispatch(connectSuccess());
});
......@@ -1192,7 +1198,7 @@ const RocketChat = {
// get user roles on the server from redux
const userRoles = (shareUser?.roles || loginUser?.roles) || [];
const mergedRoles = [...new Set([...roomRoles, ...userRoles])];
return permissions.map(permission => permission.some(r => mergedRoles.includes(r) ?? false));
return permissions.map(permission => permission?.some(r => mergedRoles.includes(r) ?? false));
} catch (e) {
log(e);
}
......
......@@ -31,6 +31,14 @@ const handleInviteLink = function* handleInviteLink({ params, requireLogin = fal
}
};
const popToRoot = function popToRoot({ isMasterDetail }) {
if (isMasterDetail) {
Navigation.navigate('DrawerNavigator');
} else {
Navigation.navigate('RoomsListView');
}
};
const navigate = function* navigate({ params }) {
yield put(appStart({ root: ROOT_INSIDE }));
if (params.path) {
......@@ -38,19 +46,28 @@ const navigate = function* navigate({ params }) {
if (type !== 'invite') {
const room = yield RocketChat.canOpenRoom(params);
if (room) {
const isMasterDetail = yield select(state => state.app.isMasterDetail);
if (isMasterDetail) {
Navigation.navigate('DrawerNavigator');
} else {
Navigation.navigate('RoomsListView');
}
const item = {
name,
t: roomTypes[type],
roomUserId: RocketChat.getUidDirectMessage(room),
...room
};
yield goRoom({ item, isMasterDetail });
const isMasterDetail = yield select(state => state.app.isMasterDetail);
const focusedRooms = yield select(state => state.room.rooms);
if (focusedRooms.includes(room.rid)) {
// if there's one room on the list or last room is the one
if (focusedRooms.length === 1 || focusedRooms[0] === room.rid) {
yield goRoom({ item, isMasterDetail });
} else {
popToRoot({ isMasterDetail });
yield goRoom({ item, isMasterDetail });
}
} else {
popToRoot({ isMasterDetail });
yield goRoom({ item, isMasterDetail });
}
if (params.isCall) {
RocketChat.callJitsi(item);
......@@ -121,10 +138,10 @@ const handleOpen = function* handleOpen({ params }) {
} else {
// search if deep link's server already exists
try {
const servers = yield serversCollection.find(host);
if (servers && user) {
const hostServerRecord = yield serversCollection.find(host);
if (hostServerRecord && user) {
yield localAuthenticate(host);
yield put(selectServerRequest(host));
yield put(selectServerRequest(host, hostServerRecord.version, true, true));
yield take(types.LOGIN.SUCCESS);
yield navigate({ params });
return;
......
......@@ -12,13 +12,14 @@ const appHasComeBackToForeground = function* appHasComeBackToForeground() {
if (appRoot === ROOT_OUTSIDE) {
return;
}
const auth = yield select(state => state.login.isAuthenticated);
if (!auth) {
const login = yield select(state => state.login);
const server = yield select(state => state.server);
if (!login.isAuthenticated || login.isFetching || server.connecting || server.loading || server.changingServer) {
return;
}
try {
const server = yield select(state => state.server.server);
yield localAuthenticate(server);
yield localAuthenticate(server.server);
RocketChat.checkAndReopen();
setBadgeCount();
return yield RocketChat.setUserPresenceOnline();
} catch (e) {
......@@ -31,14 +32,6 @@ const appHasComeBackToBackground = function* appHasComeBackToBackground() {
if (appRoot === ROOT_OUTSIDE) {
return;
}
const auth = yield select(state => state.login.isAuthenticated);
if (!auth) {
return;
}
const localAuthenticated = yield select(state => state.login.isLocalAuthenticated);
if (!localAuthenticated) {
return;
}
try {
const server = yield select(state => state.server.server);
yield saveLastLocalAuthenticationSession(server);
......
......@@ -102,9 +102,6 @@ export const localAuthenticate = async(server) => {
// if screen lock is enabled
if (serverRecord?.autoLock) {
// set isLocalAuthenticated to false
store.dispatch(setLocalAuthenticated(false));
// Make sure splash screen has been hidden
RNBootSplash.hide();
......@@ -118,6 +115,9 @@ export const localAuthenticate = async(server) => {
// if last authenticated session is older than configured auto lock time, authentication is required
if (diffToLastSession >= serverRecord?.autoLockTime) {
// set isLocalAuthenticated to false
store.dispatch(setLocalAuthenticated(false));
let hasBiometry = false;
// if biometry is enabled on the app
......
......@@ -89,7 +89,6 @@ const shouldUpdateProps = [
'showUnread',
'useRealName',
'StoreLastMessage',
'appState',
'theme',
'isMasterDetail',
'refreshing',
......@@ -126,7 +125,6 @@ class RoomsListView extends React.Component {
showUnread: PropTypes.bool,
refreshing: PropTypes.bool,
StoreLastMessage: PropTypes.bool,
appState: PropTypes.string,
theme: PropTypes.string,
toggleSortDropdown: PropTypes.func,
openSearchHeader: PropTypes.func,
......@@ -135,7 +133,6 @@ class RoomsListView extends React.Component {
roomsRequest: PropTypes.func,
closeServerDropdown: PropTypes.func,
useRealName: PropTypes.bool,
connected: PropTypes.bool,
isMasterDetail: PropTypes.bool,
rooms: PropTypes.array,
width: PropTypes.number,
......@@ -276,9 +273,6 @@ class RoomsListView extends React.Component {
groupByType,
showFavorites,
showUnread,
appState,
connected,
roomsRequest,
rooms,
isMasterDetail,
insets
......@@ -294,12 +288,6 @@ class RoomsListView extends React.Component {
)
) {
this.getSubscriptions();
} else if (
appState === 'foreground'
&& appState !== prevProps.appState
&& connected
) {
roomsRequest();
}
// Update current item in case of another action triggers an update on rooms reducer
if (isMasterDetail && item?.rid !== rooms[0] && !dequal(rooms, prevProps.rooms)) {
......@@ -319,6 +307,9 @@ class RoomsListView extends React.Component {
if (this.unsubscribeBlur) {
this.unsubscribeBlur();
}
if (this.backHandler && this.backHandler.remove) {
this.backHandler.remove();
}
if (isTablet) {
EventEmitter.removeListener(KEY_COMMAND, this.handleCommands);
}
......@@ -1018,7 +1009,6 @@ const mapStateToProps = state => ({
isMasterDetail: state.app.isMasterDetail,
server: state.server.server,
changingServer: state.server.changingServer,
connected: state.server.connected,
searchText: state.rooms.searchText,
loadingServer: state.server.loading,
showServerDropdown: state.rooms.showServerDropdown,
......@@ -1029,7 +1019,6 @@ const mapStateToProps = state => ({
showFavorites: state.sortPreferences.showFavorites,
showUnread: state.sortPreferences.showUnread,
useRealName: state.settings.UI_Use_Real_Name,
appState: state.app.ready && state.app.foreground ? 'foreground' : 'background',
StoreLastMessage: state.settings.Store_Last_Message,
rooms: state.room.rooms,
queueSize: getInquiryQueueSelector(state).length,
......
......@@ -4,6 +4,8 @@
<dict>
<key>AppGroup</key>
<string>group.com.osalliance.fairchat</string>
<key>IS_OFFICIAL</key>
<false/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
......
......@@ -48,6 +48,9 @@ class ReplyNotification: RNNotificationEventHandler {
}
}
}
} else {
let body = RNNotificationParser.parseNotificationResponse(response)
RNEventEmitter.sendEvent(RNNotificationOpened, body: body)
}
}
}
......@@ -7,6 +7,8 @@
#import <react-native-notifications/RNNotificationEventHandler.h>
#import <react-native-notifications/RNNotificationCenter.h>
#import <react-native-notifications/RCTConvert+RNNotifications.h>
#import <react-native-notifications/RNEventEmitter.h>
#import <react-native-notifications/RNNotificationParser.h>
#import <react-native-simple-crypto/Aes.h>
#import <react-native-simple-crypto/Rsa.h>
#import <react-native-simple-crypto/Shared.h>
......@@ -4,6 +4,8 @@
<dict>
<key>AppGroup</key>
<string>group.com.osalliance.fairchat</string>
<key>IS_OFFICIAL</key>
<false/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
......
......@@ -2274,7 +2274,7 @@
 
"@rocket.chat/sdk@RocketChat/Rocket.Chat.js.SDK#mobile":
version "1.0.0-mobile"
resolved "https://codeload.github.com/RocketChat/Rocket.Chat.js.SDK/tar.gz/0a97c818e60670d7660868ea107b96e5ebb631af"
resolved "https://codeload.github.com/RocketChat/Rocket.Chat.js.SDK/tar.gz/0241e2fc0c29827c51655f2d46d96e7a7720d2b6"
dependencies:
js-sha256 "^0.9.0"
lru-cache "^4.1.1"
......@@ -13813,7 +13813,7 @@ rn-host-detect@1.2.0:
resolved "https://registry.yarnpkg.com/rn-host-detect/-/rn-host-detect-1.2.0.tgz#8b0396fc05631ec60c1cb8789e5070cdb04d0da0"
integrity sha512-btNg5kzHcjZZ7t7mvvV/4wNJ9e3MPgrWivkRgWURzXL0JJ0pwWlU4zrbmdlz3HHzHOxhBhHB4D+/dbMFfu4/4A==
 
rn-root-view@^1.0.3:
rn-root-view@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/rn-root-view/-/rn-root-view-1.0.3.tgz#a2cddc717278cb2175fb29b7c006e407b7f0d0e2"
integrity sha512-BIKm8hY5q8+pxK9B5ugYjqutoI9xn2JfxIZKWoaFmAl1bOIM4oXjwFQrRM1e6lFgzz99MN6Mf2dK3Alsywnvvw==
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment