From ac539ab5eeaf0fefa1a34c03e0eafbe60103d375 Mon Sep 17 00:00:00 2001 From: Ezequiel De Oliveira Date: Fri, 22 May 2020 02:41:47 -0300 Subject: [PATCH 01/22] [NEW] Using react-native-notifier for notifications inApp Signed-off-by: Ezequiel De Oliveira --- app/notifications/inApp/index.js | 195 ++----------------- app/notifications/inApp/notifierComponent.js | 138 +++++++++++++ package.json | 1 + yarn.lock | 5 + 4 files changed, 165 insertions(+), 174 deletions(-) create mode 100644 app/notifications/inApp/notifierComponent.js diff --git a/app/notifications/inApp/index.js b/app/notifications/inApp/index.js index 3862846a05..8ce3b3d93d 100644 --- a/app/notifications/inApp/index.js +++ b/app/notifications/inApp/index.js @@ -1,88 +1,23 @@ import React from 'react'; -import { - View, Text, StyleSheet, TouchableOpacity, Animated, Easing -} from 'react-native'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import equal from 'deep-equal'; +import { NotifierRoot, Notifier, Easing } from 'react-native-notifier'; import { responsive } from 'react-native-responsive-ui'; -import Touchable from 'react-native-platform-touchable'; -import { hasNotch, isIOS, isTablet } from '../../utils/deviceInfo'; -import { CustomIcon } from '../../lib/Icons'; -import { themes } from '../../constants/colors'; -import Avatar from '../../containers/Avatar'; import { removeNotification as removeNotificationAction } from '../../actions/notification'; -import sharedStyles from '../../views/Styles'; -import { ROW_HEIGHT } from '../../presentation/RoomItem'; -import { withTheme } from '../../theme'; -import { getUserSelector } from '../../selectors/login'; +import NotifierComponent from './notifierComponent'; -const AVATAR_SIZE = 48; const ANIMATION_DURATION = 300; const NOTIFICATION_DURATION = 3000; -const BUTTON_HIT_SLOP = { - top: 12, right: 12, bottom: 12, left: 12 -}; -const ANIMATION_PROPS = { - duration: ANIMATION_DURATION, - easing: Easing.inOut(Easing.quad), - useNativeDriver: true -}; - -const styles = StyleSheet.create({ - container: { - height: ROW_HEIGHT, - paddingHorizontal: 14, - flex: 1, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - position: 'absolute', - zIndex: 2, - width: '100%', - borderBottomWidth: StyleSheet.hairlineWidth - }, - content: { - flex: 1, - flexDirection: 'row', - alignItems: 'center' - }, - inner: { - flex: 1 - }, - avatar: { - marginRight: 10 - }, - roomName: { - fontSize: 17, - lineHeight: 20, - ...sharedStyles.textMedium - }, - message: { - fontSize: 14, - lineHeight: 17, - ...sharedStyles.textRegular - }, - close: { - marginLeft: 10 - } -}); class NotificationBadge extends React.Component { static propTypes = { navigation: PropTypes.object, - baseUrl: PropTypes.string, - user: PropTypes.object, notification: PropTypes.object, window: PropTypes.object, - removeNotification: PropTypes.func, - theme: PropTypes.string - } - - constructor(props) { - super(props); - this.animatedValue = new Animated.Value(0); + theme: PropTypes.string, + removeNotification: PropTypes.func } shouldComponentUpdate(nextProps) { @@ -109,45 +44,26 @@ class NotificationBadge extends React.Component { if (navState && navState.routeName === 'RoomView' && navState.params && navState.params.rid === payload.rid) { return; } - this.show(); + /* Chamada da notificação */ + Notifier.showNotification({ + showAnimationDuration: ANIMATION_DURATION, + hideAnimationDuration: ANIMATION_DURATION, + duration: NOTIFICATION_DURATION, + hideOnPress: false, + showEasing: Easing.inOut(Easing.quad), + Component: NotifierComponent, + componentProps: { + navigation, + hideNotification: this.hide + } + }); } } - componentWillUnmount() { - this.clearTimeout(); - } - - show = () => { - Animated.timing( - this.animatedValue, - { - toValue: 1, - ...ANIMATION_PROPS - } - ).start(() => { - this.clearTimeout(); - this.timeout = setTimeout(() => { - this.hide(); - }, NOTIFICATION_DURATION); - }); - } - hide = () => { const { removeNotification } = this.props; - Animated.timing( - this.animatedValue, - { - toValue: 0, - ...ANIMATION_PROPS - } - ).start(); - setTimeout(removeNotification, ANIMATION_DURATION); - } - - clearTimeout = () => { - if (this.timeout) { - clearTimeout(this.timeout); - } + Notifier.hideNotification(); + removeNotification(); } getNavState = (routes) => { @@ -157,83 +73,14 @@ class NotificationBadge extends React.Component { return this.getNavState(routes.routes[routes.index]); } - goToRoom = async() => { - const { notification, navigation, baseUrl } = this.props; - const { payload } = notification; - const { rid, type, prid } = payload; - if (!rid) { - return; - } - const name = type === 'd' ? payload.sender.username : payload.name; - // if sub is not on local database, title will be null, so we use payload from notification - const { title = name } = notification; - await navigation.navigate('RoomsListView'); - navigation.navigate('RoomView', { - rid, name: title, t: type, prid, baseUrl - }); - this.hide(); - } - render() { - const { - baseUrl, user: { id: userId, token }, notification, window, theme - } = this.props; - const { message, payload } = notification; - const { type } = payload; - const name = type === 'd' ? payload.sender.username : payload.name; - // if sub is not on local database, title and avatar will be null, so we use payload from notification - const { title = name, avatar = name } = notification; - - let top = 0; - if (isIOS) { - const portrait = window.height > window.width; - if (portrait) { - top = hasNotch ? 45 : 20; - } else { - top = isTablet ? 20 : 0; - } - } - - const translateY = this.animatedValue.interpolate({ - inputRange: [0, 1], - outputRange: [-top - ROW_HEIGHT, top] - }); return ( - - - <> - - - {title} - {message} - - - - - - - + ); } } const mapStateToProps = state => ({ - user: getUserSelector(state), - baseUrl: state.server.server, notification: state.notification }); @@ -241,4 +88,4 @@ const mapDispatchToProps = dispatch => ({ removeNotification: () => dispatch(removeNotificationAction()) }); -export default responsive(connect(mapStateToProps, mapDispatchToProps)(withTheme(NotificationBadge))); +export default responsive(connect(mapStateToProps, mapDispatchToProps)((NotificationBadge))); diff --git a/app/notifications/inApp/notifierComponent.js b/app/notifications/inApp/notifierComponent.js new file mode 100644 index 0000000000..a7a425f357 --- /dev/null +++ b/app/notifications/inApp/notifierComponent.js @@ -0,0 +1,138 @@ +import React from 'react'; +import { + StyleSheet, SafeAreaView, View, Text, TouchableOpacity +} from 'react-native'; +import PropTypes from 'prop-types'; +import Touchable from 'react-native-platform-touchable'; +import { connect } from 'react-redux'; + +import Avatar from '../../containers/Avatar'; +import { CustomIcon } from '../../lib/Icons'; +import sharedStyles from '../../views/Styles'; +import { themes } from '../../constants/colors'; +import { withTheme } from '../../theme'; +import { getUserSelector } from '../../selectors/login'; +import { ROW_HEIGHT } from '../../presentation/RoomItem'; + + +const AVATAR_SIZE = 48; +const BUTTON_HIT_SLOP = { + top: 12, right: 12, bottom: 12, left: 12 +}; + +const styles = StyleSheet.create({ + container: { + height: ROW_HEIGHT, + paddingHorizontal: 14, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + width: '100%', + borderBottomWidth: StyleSheet.hairlineWidth + }, + content: { + flex: 1, + flexDirection: 'row', + alignItems: 'center' + }, + inner: { + flex: 1 + }, + avatar: { + marginRight: 10 + }, + roomName: { + fontSize: 17, + lineHeight: 20, + ...sharedStyles.textMedium + }, + message: { + fontSize: 14, + lineHeight: 17, + ...sharedStyles.textRegular + }, + close: { + marginLeft: 10 + } +}); + + +class NotifierComponent extends React.Component { + static propTypes = { + navigation: PropTypes.object, + baseUrl: PropTypes.string, + user: PropTypes.object, + notification: PropTypes.object, + theme: PropTypes.string, + hideNotification: PropTypes.func + } + + goToRoom = async() => { + const { + notification, navigation, baseUrl, hideNotification + } = this.props; + const { payload } = notification; + const { rid, type, prid } = payload; + if (!rid) { + return; + } + const name = type === 'd' ? payload.sender.username : payload.name; + // if sub is not on local database, title will be null, so we use payload from notification + const { title = name } = notification; + await navigation.navigate('RoomsListView'); + navigation.navigate('RoomView', { + rid, name: title, t: type, prid, baseUrl + }); + hideNotification(); + } + + render() { + const { + baseUrl, user: { id: userId, token }, notification, theme, hideNotification + } = this.props; + const { message, payload } = notification; + const { type } = payload; + const name = type === 'd' ? payload.sender.username : payload.name; + // if sub is not on local database, title and avatar will be null, so we use payload from notification + const { title = name, avatar = name } = notification; + + return ( + + + + <> + + + {title} + {message} + + + + + + + + + ); + } +} + +const mapStateToProps = state => ({ + user: getUserSelector(state), + baseUrl: state.server.server, + notification: state.notification +}); + +export default connect(mapStateToProps)(withTheme(NotifierComponent)); diff --git a/package.json b/package.json index 8008e38675..a5a45e419f 100644 --- a/package.json +++ b/package.json @@ -79,6 +79,7 @@ "react-native-modal": "11.5.6", "react-native-navigation-bar-color": "2.0.1", "react-native-notifications": "2.1.7", + "react-native-notifier": "^1.1.0", "react-native-orientation-locker": "1.1.8", "react-native-picker-select": "7.0.0", "react-native-platform-touchable": "^1.1.1", diff --git a/yarn.lock b/yarn.lock index a8856d70bd..157702f098 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13493,6 +13493,11 @@ react-native-notifications@2.1.7: core-js "^1.0.0" uuid "^2.0.3" +react-native-notifier@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/react-native-notifier/-/react-native-notifier-1.1.0.tgz#676bec87c17b09410d40bbcecf12d1f850129e4b" + integrity sha512-wMCNUfInu1kUxA7c9OuytadXzSqJ8YZZxol+4QwIu9hL5xhhLcfRK3PsqelZ7IFJQWY8SgXvGGh8DtILlzd9+A== + react-native-orientation-locker@1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/react-native-orientation-locker/-/react-native-orientation-locker-1.1.8.tgz#45d1c9e002496b8d286ec8932d6e3e7d341f9c85" From 1067f25ffc9c6baee16482c6f7a1f31092259ebb Mon Sep 17 00:00:00 2001 From: Ezequiel De Oliveira Date: Fri, 22 May 2020 10:25:30 -0300 Subject: [PATCH 02/22] Removing useless comment Signed-off-by: Ezequiel De Oliveira --- app/notifications/inApp/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/notifications/inApp/index.js b/app/notifications/inApp/index.js index 8ce3b3d93d..e86d229f28 100644 --- a/app/notifications/inApp/index.js +++ b/app/notifications/inApp/index.js @@ -44,7 +44,6 @@ class NotificationBadge extends React.Component { if (navState && navState.routeName === 'RoomView' && navState.params && navState.params.rid === payload.rid) { return; } - /* Chamada da notificação */ Notifier.showNotification({ showAnimationDuration: ANIMATION_DURATION, hideAnimationDuration: ANIMATION_DURATION, From bea3c7449884f8069477195e1a198e411d28eb46 Mon Sep 17 00:00:00 2001 From: Ezequiel De Oliveira Date: Wed, 3 Jun 2020 01:27:22 -0300 Subject: [PATCH 03/22] Using EventEmitter for in App notifications Signed-off-by: Ezequiel De Oliveira --- .../NotificationsInApp/NotifierComponent.js} | 0 .../NotificationsInApp}/index.js | 19 ++++++++++++++++--- app/index.js | 2 +- app/lib/methods/subscriptions/rooms.js | 5 +++-- 4 files changed, 20 insertions(+), 6 deletions(-) rename app/{notifications/inApp/notifierComponent.js => containers/NotificationsInApp/NotifierComponent.js} (100%) rename app/{notifications/inApp => containers/NotificationsInApp}/index.js (83%) diff --git a/app/notifications/inApp/notifierComponent.js b/app/containers/NotificationsInApp/NotifierComponent.js similarity index 100% rename from app/notifications/inApp/notifierComponent.js rename to app/containers/NotificationsInApp/NotifierComponent.js diff --git a/app/notifications/inApp/index.js b/app/containers/NotificationsInApp/index.js similarity index 83% rename from app/notifications/inApp/index.js rename to app/containers/NotificationsInApp/index.js index e86d229f28..1ee341d181 100644 --- a/app/notifications/inApp/index.js +++ b/app/containers/NotificationsInApp/index.js @@ -6,10 +6,12 @@ import { NotifierRoot, Notifier, Easing } from 'react-native-notifier'; import { responsive } from 'react-native-responsive-ui'; import { removeNotification as removeNotificationAction } from '../../actions/notification'; -import NotifierComponent from './notifierComponent'; +import NotifierComponent from './NotifierComponent'; +import EventEmitter from './../../utils/events'; const ANIMATION_DURATION = 300; const NOTIFICATION_DURATION = 3000; +const LISTENER = 'NotificationInApp' class NotificationBadge extends React.Component { static propTypes = { @@ -20,11 +22,16 @@ class NotificationBadge extends React.Component { removeNotification: PropTypes.func } + componentDidMount() { + EventEmitter.addEventListener(LISTENER, this.show); + } + shouldComponentUpdate(nextProps) { const { notification: nextNotification } = nextProps; const { notification: { payload }, window, theme } = this.props; + console.log(nextProps, this.props); if (nextProps.theme !== theme) { return true; } @@ -37,8 +44,13 @@ class NotificationBadge extends React.Component { return false; } - componentDidUpdate() { - const { notification: { payload }, navigation } = this.props; + componentWillMount () { + EventEmitter.removeListener(LISTENER); + } + + show = (notification) => { + const { navigation } = this.props; + const { payload } = notification; const navState = this.getNavState(navigation.state); if (payload.rid) { if (navState && navState.routeName === 'RoomView' && navState.params && navState.params.rid === payload.rid) { @@ -59,6 +71,7 @@ class NotificationBadge extends React.Component { } } + hide = () => { const { removeNotification } = this.props; Notifier.hideNotification(); diff --git a/app/index.js b/app/index.js index 8241727078..03166b775d 100644 --- a/app/index.js +++ b/app/index.js @@ -26,7 +26,7 @@ import Sidebar from './views/SidebarView'; import parseQuery from './lib/methods/helpers/parseQuery'; import { initializePushNotifications, onNotification } from './notifications/push'; import store from './lib/createStore'; -import NotificationBadge from './notifications/inApp'; +import NotificationBadge from './containers/NotificationsInApp'; import { defaultHeader, onNavigationStateChange, cardStyle, getActiveRouteName } from './utils/navigation'; diff --git a/app/lib/methods/subscriptions/rooms.js b/app/lib/methods/subscriptions/rooms.js index d6ea0f7b67..b7cd17608d 100644 --- a/app/lib/methods/subscriptions/rooms.js +++ b/app/lib/methods/subscriptions/rooms.js @@ -13,7 +13,7 @@ import { notificationReceived } from '../../../actions/notification'; import { handlePayloadUserInteraction } from '../actions'; import buildMessage from '../helpers/buildMessage'; import RocketChat from '../../rocketchat'; -import EventEmmiter from '../../../utils/events'; +import EventEmitter from '../../../utils/events'; import { removedRoom } from '../../../actions/room'; const removeListener = listener => listener.stop(); @@ -267,7 +267,7 @@ export default function subscribeRooms() { if (data.rid === roomState.rid && roomState.isDeleting) { store.dispatch(removedRoom()); } else { - EventEmmiter.emit('ROOM_REMOVED', { rid: data.rid }); + EventEmitter.emit('ROOM_REMOVED', { rid: data.rid }); } } catch (e) { log(e); @@ -320,6 +320,7 @@ export default function subscribeRooms() { } catch (e) { // do nothing } + EventEmitter.emit('NotificationInApp', notification); store.dispatch(notificationReceived(notification)); } if (/uiInteraction/.test(ev)) { From 0934a52058f21017ce7b64529b78790acb4ebacb Mon Sep 17 00:00:00 2001 From: Ezequiel De Oliveira Date: Wed, 3 Jun 2020 01:38:25 -0300 Subject: [PATCH 04/22] Using correct lifecycle to remove listener Signed-off-by: Ezequiel De Oliveira --- app/containers/NotificationsInApp/NotifierComponent.js | 2 +- app/containers/NotificationsInApp/index.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/containers/NotificationsInApp/NotifierComponent.js b/app/containers/NotificationsInApp/NotifierComponent.js index a7a425f357..817d60af35 100644 --- a/app/containers/NotificationsInApp/NotifierComponent.js +++ b/app/containers/NotificationsInApp/NotifierComponent.js @@ -6,7 +6,7 @@ import PropTypes from 'prop-types'; import Touchable from 'react-native-platform-touchable'; import { connect } from 'react-redux'; -import Avatar from '../../containers/Avatar'; +import Avatar from '../Avatar'; import { CustomIcon } from '../../lib/Icons'; import sharedStyles from '../../views/Styles'; import { themes } from '../../constants/colors'; diff --git a/app/containers/NotificationsInApp/index.js b/app/containers/NotificationsInApp/index.js index 1ee341d181..ed7c1aa7d2 100644 --- a/app/containers/NotificationsInApp/index.js +++ b/app/containers/NotificationsInApp/index.js @@ -7,11 +7,11 @@ import { responsive } from 'react-native-responsive-ui'; import { removeNotification as removeNotificationAction } from '../../actions/notification'; import NotifierComponent from './NotifierComponent'; -import EventEmitter from './../../utils/events'; +import EventEmitter from '../../utils/events'; const ANIMATION_DURATION = 300; const NOTIFICATION_DURATION = 3000; -const LISTENER = 'NotificationInApp' +const LISTENER = 'NotificationInApp'; class NotificationBadge extends React.Component { static propTypes = { @@ -44,7 +44,7 @@ class NotificationBadge extends React.Component { return false; } - componentWillMount () { + componentWillUnmount() { EventEmitter.removeListener(LISTENER); } From 6de12e351bd7f33dda47acc95f46ff013065dfcf Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 10:59:13 -0300 Subject: [PATCH 05/22] Make it work --- app/containers/NotificationsInApp/index.js | 39 ++++++++++++---------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/app/containers/NotificationsInApp/index.js b/app/containers/NotificationsInApp/index.js index 23dbc8aeeb..c12d74daae 100644 --- a/app/containers/NotificationsInApp/index.js +++ b/app/containers/NotificationsInApp/index.js @@ -8,6 +8,8 @@ import { responsive } from 'react-native-responsive-ui'; import { removeNotification as removeNotificationAction } from '../../actions/notification'; import NotifierComponent from './NotifierComponent'; import EventEmitter from '../../utils/events'; +import Navigation from '../../lib/Navigation'; +import { getActiveRoute } from '../../utils/navigation'; const ANIMATION_DURATION = 300; const NOTIFICATION_DURATION = 3000; @@ -26,22 +28,22 @@ class NotificationBadge extends React.Component { EventEmitter.addEventListener(LISTENER, this.show); } - shouldComponentUpdate(nextProps) { - const { notification: nextNotification } = nextProps; - const { - notification: { payload }, window, theme - } = this.props; - if (nextProps.theme !== theme) { - return true; - } - if (!equal(nextNotification.payload, payload)) { - return true; - } - if (nextProps.window.width !== window.width) { - return true; - } - return false; - } + // shouldComponentUpdate(nextProps) { + // const { notification: nextNotification } = nextProps; + // const { + // notification: { payload }, window, theme + // } = this.props; + // if (nextProps.theme !== theme) { + // return true; + // } + // if (!equal(nextNotification.payload, payload)) { + // return true; + // } + // if (nextProps.window.width !== window.width) { + // return true; + // } + // return false; + // } componentWillUnmount() { EventEmitter.removeListener(LISTENER); @@ -50,9 +52,10 @@ class NotificationBadge extends React.Component { show = (notification) => { const { navigation } = this.props; const { payload } = notification; - const navState = this.getNavState(navigation.state); + const state = Navigation.navigationRef.current.getRootState(); + const route = getActiveRoute(state); if (payload.rid) { - if (navState && navState.routeName === 'RoomView' && navState.params && navState.params.rid === payload.rid) { + if (route?.name === 'RoomView' && route.params?.rid === payload.rid) { return; } Notifier.showNotification({ From 7f34d8015b7863ca326fd19eb92d0eb3a2cc8143 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 11:22:07 -0300 Subject: [PATCH 06/22] Remove from redux --- app/actions/actionsTypes.js | 1 - app/actions/notification.js | 19 ----------- .../NotificationsInApp/NotifierComponent.js | 8 ++--- app/containers/NotificationsInApp/index.js | 32 ++----------------- app/lib/methods/subscriptions/rooms.js | 2 -- app/reducers/index.js | 2 -- app/reducers/notification.js | 24 -------------- 7 files changed, 7 insertions(+), 81 deletions(-) delete mode 100644 app/actions/notification.js delete mode 100644 app/reducers/notification.js diff --git a/app/actions/actionsTypes.js b/app/actions/actionsTypes.js index 78bfa41763..65c39d9c64 100644 --- a/app/actions/actionsTypes.js +++ b/app/actions/actionsTypes.js @@ -51,7 +51,6 @@ export const LOGOUT = 'LOGOUT'; // logout is always success export const SNIPPETED_MESSAGES = createRequestTypes('SNIPPETED_MESSAGES', ['OPEN', 'READY', 'CLOSE', 'MESSAGES_RECEIVED']); export const DEEP_LINKING = createRequestTypes('DEEP_LINKING', ['OPEN']); export const SORT_PREFERENCES = createRequestTypes('SORT_PREFERENCES', ['SET_ALL', 'SET']); -export const NOTIFICATION = createRequestTypes('NOTIFICATION', ['RECEIVED', 'REMOVE']); export const TOGGLE_CRASH_REPORT = 'TOGGLE_CRASH_REPORT'; export const SET_CUSTOM_EMOJIS = 'SET_CUSTOM_EMOJIS'; export const SET_ACTIVE_USERS = 'SET_ACTIVE_USERS'; diff --git a/app/actions/notification.js b/app/actions/notification.js deleted file mode 100644 index 35fc49d87e..0000000000 --- a/app/actions/notification.js +++ /dev/null @@ -1,19 +0,0 @@ -import { NOTIFICATION } from './actionsTypes'; - -export function notificationReceived(params) { - return { - type: NOTIFICATION.RECEIVED, - payload: { - title: params.title, - avatar: params.avatar, - message: params.text, - payload: params.payload - } - }; -} - -export function removeNotification() { - return { - type: NOTIFICATION.REMOVE - }; -} diff --git a/app/containers/NotificationsInApp/NotifierComponent.js b/app/containers/NotificationsInApp/NotifierComponent.js index 3b926fec45..4d702deb48 100644 --- a/app/containers/NotificationsInApp/NotifierComponent.js +++ b/app/containers/NotificationsInApp/NotifierComponent.js @@ -89,12 +89,13 @@ class NotifierComponent extends React.Component { const { baseUrl, user: { id: userId, token }, notification, theme, hideNotification } = this.props; - const { message, payload } = notification; + const { text, payload } = notification; const { type } = payload; const name = type === 'd' ? payload.sender.username : payload.name; // if sub is not on local database, title and avatar will be null, so we use payload from notification const { title = name, avatar = name } = notification; + // return null; return ( {title} - {message} + {text} @@ -130,8 +131,7 @@ class NotifierComponent extends React.Component { const mapStateToProps = state => ({ user: getUserSelector(state), - baseUrl: state.server.server, - notification: state.notification + baseUrl: state.server.server }); export default connect(mapStateToProps)(withTheme(NotifierComponent)); diff --git a/app/containers/NotificationsInApp/index.js b/app/containers/NotificationsInApp/index.js index c12d74daae..27ebe1256d 100644 --- a/app/containers/NotificationsInApp/index.js +++ b/app/containers/NotificationsInApp/index.js @@ -5,7 +5,6 @@ import equal from 'deep-equal'; import { NotifierRoot, Notifier, Easing } from 'react-native-notifier'; import { responsive } from 'react-native-responsive-ui'; -import { removeNotification as removeNotificationAction } from '../../actions/notification'; import NotifierComponent from './NotifierComponent'; import EventEmitter from '../../utils/events'; import Navigation from '../../lib/Navigation'; @@ -18,10 +17,8 @@ const LISTENER = 'NotificationInApp'; class NotificationBadge extends React.Component { static propTypes = { navigation: PropTypes.object, - notification: PropTypes.object, window: PropTypes.object, - theme: PropTypes.string, - removeNotification: PropTypes.func + theme: PropTypes.string } componentDidMount() { @@ -62,31 +59,16 @@ class NotificationBadge extends React.Component { showAnimationDuration: ANIMATION_DURATION, hideAnimationDuration: ANIMATION_DURATION, duration: NOTIFICATION_DURATION, - hideOnPress: false, showEasing: Easing.inOut(Easing.quad), Component: NotifierComponent, componentProps: { navigation, - hideNotification: this.hide + notification } }); } } - - hide = () => { - const { removeNotification } = this.props; - Notifier.hideNotification(); - removeNotification(); - } - - getNavState = (routes) => { - if (!routes.routes) { - return routes; - } - return this.getNavState(routes.routes[routes.index]); - } - render() { return ( @@ -94,12 +76,4 @@ class NotificationBadge extends React.Component { } } -const mapStateToProps = state => ({ - notification: state.notification -}); - -const mapDispatchToProps = dispatch => ({ - removeNotification: () => dispatch(removeNotificationAction()) -}); - -export default responsive(connect(mapStateToProps, mapDispatchToProps)((NotificationBadge))); +export default responsive(NotificationBadge); diff --git a/app/lib/methods/subscriptions/rooms.js b/app/lib/methods/subscriptions/rooms.js index b7cd17608d..2cf15a39c5 100644 --- a/app/lib/methods/subscriptions/rooms.js +++ b/app/lib/methods/subscriptions/rooms.js @@ -9,7 +9,6 @@ import log from '../../../utils/log'; import random from '../../../utils/random'; import store from '../../createStore'; import { roomsRequest } from '../../../actions/rooms'; -import { notificationReceived } from '../../../actions/notification'; import { handlePayloadUserInteraction } from '../actions'; import buildMessage from '../helpers/buildMessage'; import RocketChat from '../../rocketchat'; @@ -321,7 +320,6 @@ export default function subscribeRooms() { // do nothing } EventEmitter.emit('NotificationInApp', notification); - store.dispatch(notificationReceived(notification)); } if (/uiInteraction/.test(ev)) { const { type: eventType, ...args } = type; diff --git a/app/reducers/index.js b/app/reducers/index.js index dead110fbf..1ac810c334 100644 --- a/app/reducers/index.js +++ b/app/reducers/index.js @@ -9,7 +9,6 @@ import selectedUsers from './selectedUsers'; import createChannel from './createChannel'; import app from './app'; import sortPreferences from './sortPreferences'; -import notification from './notification'; import share from './share'; import crashReport from './crashReport'; import customEmojis from './customEmojis'; @@ -29,7 +28,6 @@ export default combineReducers({ room, rooms, sortPreferences, - notification, share, crashReport, customEmojis, diff --git a/app/reducers/notification.js b/app/reducers/notification.js deleted file mode 100644 index 5b1d07c9b0..0000000000 --- a/app/reducers/notification.js +++ /dev/null @@ -1,24 +0,0 @@ -import { NOTIFICATION } from '../actions/actionsTypes'; - -const initialState = { - message: '', - payload: { - type: 'p', - name: '', - rid: '' - } -}; - -export default function notification(state = initialState, action) { - switch (action.type) { - case NOTIFICATION.RECEIVED: - return { - ...state, - ...action.payload - }; - case NOTIFICATION.REMOVE: - return initialState; - default: - return state; - } -} From 0e5f423561f036ba7e45dee6b33ff99b3db317fa Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 13:24:17 -0300 Subject: [PATCH 07/22] Use built-in hide function --- .../NotificationsInApp/NotifierComponent.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/containers/NotificationsInApp/NotifierComponent.js b/app/containers/NotificationsInApp/NotifierComponent.js index 4d702deb48..6e2dfbc549 100644 --- a/app/containers/NotificationsInApp/NotifierComponent.js +++ b/app/containers/NotificationsInApp/NotifierComponent.js @@ -5,6 +5,7 @@ import { import PropTypes from 'prop-types'; import Touchable from 'react-native-platform-touchable'; import { connect } from 'react-redux'; +import { Notifier } from 'react-native-notifier'; import Avatar from '../Avatar'; import { CustomIcon } from '../../lib/Icons'; @@ -62,13 +63,12 @@ class NotifierComponent extends React.Component { baseUrl: PropTypes.string, user: PropTypes.object, notification: PropTypes.object, - theme: PropTypes.string, - hideNotification: PropTypes.func + theme: PropTypes.string } goToRoom = async() => { const { - notification, navigation, baseUrl, hideNotification + notification, navigation, baseUrl } = this.props; const { payload } = notification; const { rid, type, prid } = payload; @@ -82,12 +82,14 @@ class NotifierComponent extends React.Component { navigation.navigate('RoomView', { rid, name: title, t: type, prid, baseUrl }); - hideNotification(); + this.hideNotification(); } + hideNotification = () => Notifier.hideNotification() + render() { const { - baseUrl, user: { id: userId, token }, notification, theme, hideNotification + baseUrl, user: { id: userId, token }, notification, theme } = this.props; const { text, payload } = notification; const { type } = payload; @@ -95,7 +97,6 @@ class NotifierComponent extends React.Component { // if sub is not on local database, title and avatar will be null, so we use payload from notification const { title = name, avatar = name } = notification; - // return null; return ( - + From ff94dde151fe6265d7a219c766416143a826de84 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 14:10:05 -0300 Subject: [PATCH 08/22] Reset timer https://github.com/seniv/react-native-notifier/pull/15 --- package.json | 2 +- yarn.lock | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index df3243b440..630a705cea 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "react-native-modal": "11.5.6", "react-native-navigation-bar-color": "2.0.1", "react-native-notifications": "2.1.7", - "react-native-notifier": "^1.1.0", + "react-native-notifier": "diegolmello/react-native-notifier#fix.active-state", "react-native-orientation-locker": "1.1.8", "react-native-picker-select": "7.0.0", "react-native-platform-touchable": "^1.1.1", diff --git a/yarn.lock b/yarn.lock index 64e28bcdda..a5692a7a31 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11895,10 +11895,9 @@ react-native-notifications@2.1.7: core-js "^1.0.0" uuid "^2.0.3" -react-native-notifier@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/react-native-notifier/-/react-native-notifier-1.1.0.tgz#676bec87c17b09410d40bbcecf12d1f850129e4b" - integrity sha512-wMCNUfInu1kUxA7c9OuytadXzSqJ8YZZxol+4QwIu9hL5xhhLcfRK3PsqelZ7IFJQWY8SgXvGGh8DtILlzd9+A== +react-native-notifier@diegolmello/react-native-notifier#fix.active-state: + version "1.3.0" + resolved "https://codeload.github.com/diegolmello/react-native-notifier/tar.gz/2bc5f36dc2ba126e164ebae718755eb822eea121" react-native-orientation-locker@1.1.8: version "1.1.8" From accef16c9a13bbb1d65ad899c87c4e26340f5dc6 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 14:17:08 -0300 Subject: [PATCH 09/22] Rename --- .../NotifierComponent.js | 0 .../index.js | 25 +++---------------- app/stacks/InsideStack.js | 4 +-- app/stacks/MasterDetailStack/index.js | 4 +-- 4 files changed, 7 insertions(+), 26 deletions(-) rename app/containers/{NotificationsInApp => InAppNotification}/NotifierComponent.js (100%) rename app/containers/{NotificationsInApp => InAppNotification}/index.js (70%) diff --git a/app/containers/NotificationsInApp/NotifierComponent.js b/app/containers/InAppNotification/NotifierComponent.js similarity index 100% rename from app/containers/NotificationsInApp/NotifierComponent.js rename to app/containers/InAppNotification/NotifierComponent.js diff --git a/app/containers/NotificationsInApp/index.js b/app/containers/InAppNotification/index.js similarity index 70% rename from app/containers/NotificationsInApp/index.js rename to app/containers/InAppNotification/index.js index 27ebe1256d..024aea7a8d 100644 --- a/app/containers/NotificationsInApp/index.js +++ b/app/containers/InAppNotification/index.js @@ -14,34 +14,15 @@ const ANIMATION_DURATION = 300; const NOTIFICATION_DURATION = 3000; const LISTENER = 'NotificationInApp'; -class NotificationBadge extends React.Component { +class InAppNotification extends React.Component { static propTypes = { - navigation: PropTypes.object, - window: PropTypes.object, - theme: PropTypes.string + navigation: PropTypes.object } componentDidMount() { EventEmitter.addEventListener(LISTENER, this.show); } - // shouldComponentUpdate(nextProps) { - // const { notification: nextNotification } = nextProps; - // const { - // notification: { payload }, window, theme - // } = this.props; - // if (nextProps.theme !== theme) { - // return true; - // } - // if (!equal(nextNotification.payload, payload)) { - // return true; - // } - // if (nextProps.window.width !== window.width) { - // return true; - // } - // return false; - // } - componentWillUnmount() { EventEmitter.removeListener(LISTENER); } @@ -76,4 +57,4 @@ class NotificationBadge extends React.Component { } } -export default responsive(NotificationBadge); +export default responsive(InAppNotification); diff --git a/app/stacks/InsideStack.js b/app/stacks/InsideStack.js index d83d118a4f..9cf6126c34 100644 --- a/app/stacks/InsideStack.js +++ b/app/stacks/InsideStack.js @@ -9,7 +9,7 @@ import { } from '../utils/navigation'; import Toast from '../containers/Toast'; import Sidebar from '../views/SidebarView'; -import NotificationBadge from '../containers/NotificationsInApp'; +import InAppNotification from '../containers/InAppNotification'; // Chats Stack import RoomView from '../views/RoomView'; @@ -323,7 +323,7 @@ const InsideStackNavigator = () => { const RootInsideStack = ({ navigation, route }) => ( <> - + ); diff --git a/app/stacks/MasterDetailStack/index.js b/app/stacks/MasterDetailStack/index.js index 7f63ad7619..855008f2c0 100644 --- a/app/stacks/MasterDetailStack/index.js +++ b/app/stacks/MasterDetailStack/index.js @@ -9,7 +9,7 @@ import { defaultHeader, themedHeader, StackAnimation, FadeFromCenterModal } from '../../utils/navigation'; import Toast from '../../containers/Toast'; -import NotificationBadge from '../../containers/NotificationsInApp'; +import InAppNotification from '../../containers/InAppNotification'; import { ModalContainer } from './ModalContainer'; // Chats Stack @@ -295,7 +295,7 @@ const InsideStackNavigator = React.memo(() => { const RootInsideStack = React.memo(({ navigation, route }) => ( <> - + )); From a36f1805b232c79b48bbbbb15f1dc73c7d9c523e Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 14:23:14 -0300 Subject: [PATCH 10/22] Patch-package --- package.json | 2 +- patches/react-native-notifier+1.3.0.patch | 61 +++++++++++++++++++++++ yarn.lock | 5 +- 3 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 patches/react-native-notifier+1.3.0.patch diff --git a/package.json b/package.json index 630a705cea..59dc89ae78 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "react-native-modal": "11.5.6", "react-native-navigation-bar-color": "2.0.1", "react-native-notifications": "2.1.7", - "react-native-notifier": "diegolmello/react-native-notifier#fix.active-state", + "react-native-notifier": "^1.3.0", "react-native-orientation-locker": "1.1.8", "react-native-picker-select": "7.0.0", "react-native-platform-touchable": "^1.1.1", diff --git a/patches/react-native-notifier+1.3.0.patch b/patches/react-native-notifier+1.3.0.patch new file mode 100644 index 0000000000..e09973d945 --- /dev/null +++ b/patches/react-native-notifier+1.3.0.patch @@ -0,0 +1,61 @@ +diff --git a/node_modules/react-native-notifier/src/Notifier.tsx b/node_modules/react-native-notifier/src/Notifier.tsx +index 141bc25..ad5119a 100644 +--- a/node_modules/react-native-notifier/src/Notifier.tsx ++++ b/node_modules/react-native-notifier/src/Notifier.tsx +@@ -139,15 +139,7 @@ export class NotifierRoot extends React.PureComponent Date: Tue, 16 Jun 2020 14:39:11 -0300 Subject: [PATCH 11/22] Fix navigation --- .../InAppNotification/NotifierComponent.js | 27 ++++++++++++------- app/containers/InAppNotification/index.js | 2 -- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/app/containers/InAppNotification/NotifierComponent.js b/app/containers/InAppNotification/NotifierComponent.js index 6e2dfbc549..8b42154d1f 100644 --- a/app/containers/InAppNotification/NotifierComponent.js +++ b/app/containers/InAppNotification/NotifierComponent.js @@ -14,6 +14,8 @@ import { themes } from '../../constants/colors'; import { withTheme } from '../../theme'; import { getUserSelector } from '../../selectors/login'; import { ROW_HEIGHT } from '../../presentation/RoomItem'; +import { goRoom } from '../../utils/goRoom'; +import Navigation from '../../lib/Navigation'; const AVATAR_SIZE = 48; const BUTTON_HIT_SLOP = { @@ -59,16 +61,16 @@ const styles = StyleSheet.create({ class NotifierComponent extends React.Component { static propTypes = { - navigation: PropTypes.object, baseUrl: PropTypes.string, user: PropTypes.object, notification: PropTypes.object, - theme: PropTypes.string + theme: PropTypes.string, + isMasterDetail: PropTypes.bool } - goToRoom = async() => { + goRoom = () => { const { - notification, navigation, baseUrl + notification, isMasterDetail } = this.props; const { payload } = notification; const { rid, type, prid } = payload; @@ -78,10 +80,14 @@ class NotifierComponent extends React.Component { const name = type === 'd' ? payload.sender.username : payload.name; // if sub is not on local database, title will be null, so we use payload from notification const { title = name } = notification; - await navigation.navigate('RoomsListView'); - navigation.navigate('RoomView', { - rid, name: title, t: type, prid, baseUrl - }); + const item = { + rid, name: title, t: type, prid + }; + + if (isMasterDetail) { + Navigation.navigate('DrawerNavigator'); + } + goRoom({ item, isMasterDetail }); this.hideNotification(); } @@ -109,7 +115,7 @@ class NotifierComponent extends React.Component { > @@ -132,7 +138,8 @@ class NotifierComponent extends React.Component { const mapStateToProps = state => ({ user: getUserSelector(state), - baseUrl: state.server.server + baseUrl: state.server.server, + isMasterDetail: state.app.isMasterDetail }); export default connect(mapStateToProps)(withTheme(NotifierComponent)); diff --git a/app/containers/InAppNotification/index.js b/app/containers/InAppNotification/index.js index 024aea7a8d..380f44cd42 100644 --- a/app/containers/InAppNotification/index.js +++ b/app/containers/InAppNotification/index.js @@ -1,7 +1,5 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; -import equal from 'deep-equal'; import { NotifierRoot, Notifier, Easing } from 'react-native-notifier'; import { responsive } from 'react-native-responsive-ui'; From b2cdb4e92819d5720995ccb58aa0ddcc04511f11 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 14:40:56 -0300 Subject: [PATCH 12/22] Use Touchable --- app/containers/InAppNotification/NotifierComponent.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/containers/InAppNotification/NotifierComponent.js b/app/containers/InAppNotification/NotifierComponent.js index 8b42154d1f..5123640a58 100644 --- a/app/containers/InAppNotification/NotifierComponent.js +++ b/app/containers/InAppNotification/NotifierComponent.js @@ -1,6 +1,6 @@ import React from 'react'; import { - StyleSheet, SafeAreaView, View, Text, TouchableOpacity + StyleSheet, SafeAreaView, View, Text } from 'react-native'; import PropTypes from 'prop-types'; import Touchable from 'react-native-platform-touchable'; @@ -127,9 +127,13 @@ class NotifierComponent extends React.Component { - + - + ); From 49111c79f6cf8157480954c611d9445dcf4eeba2 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 14:44:33 -0300 Subject: [PATCH 13/22] Refactor --- app/containers/InAppNotification/index.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/app/containers/InAppNotification/index.js b/app/containers/InAppNotification/index.js index 380f44cd42..f8b8164141 100644 --- a/app/containers/InAppNotification/index.js +++ b/app/containers/InAppNotification/index.js @@ -1,7 +1,5 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { NotifierRoot, Notifier, Easing } from 'react-native-notifier'; -import { responsive } from 'react-native-responsive-ui'; import NotifierComponent from './NotifierComponent'; import EventEmitter from '../../utils/events'; @@ -13,10 +11,6 @@ const NOTIFICATION_DURATION = 3000; const LISTENER = 'NotificationInApp'; class InAppNotification extends React.Component { - static propTypes = { - navigation: PropTypes.object - } - componentDidMount() { EventEmitter.addEventListener(LISTENER, this.show); } @@ -26,7 +20,6 @@ class InAppNotification extends React.Component { } show = (notification) => { - const { navigation } = this.props; const { payload } = notification; const state = Navigation.navigationRef.current.getRootState(); const route = getActiveRoute(state); @@ -41,7 +34,6 @@ class InAppNotification extends React.Component { showEasing: Easing.inOut(Easing.quad), Component: NotifierComponent, componentProps: { - navigation, notification } }); @@ -55,4 +47,4 @@ class InAppNotification extends React.Component { } } -export default responsive(InAppNotification); +export default InAppNotification; From aa4e274330923221e841606a0cce4431e1f29945 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 14:46:35 -0300 Subject: [PATCH 14/22] Export emitter constant --- app/containers/InAppNotification/index.js | 7 ++++--- app/lib/methods/subscriptions/rooms.js | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/containers/InAppNotification/index.js b/app/containers/InAppNotification/index.js index f8b8164141..8c3fc38a4c 100644 --- a/app/containers/InAppNotification/index.js +++ b/app/containers/InAppNotification/index.js @@ -8,15 +8,16 @@ import { getActiveRoute } from '../../utils/navigation'; const ANIMATION_DURATION = 300; const NOTIFICATION_DURATION = 3000; -const LISTENER = 'NotificationInApp'; + +export const INAPP_NOTIFICATION_EMITTER = 'NotificationInApp'; class InAppNotification extends React.Component { componentDidMount() { - EventEmitter.addEventListener(LISTENER, this.show); + EventEmitter.addEventListener(INAPP_NOTIFICATION_EMITTER, this.show); } componentWillUnmount() { - EventEmitter.removeListener(LISTENER); + EventEmitter.removeListener(INAPP_NOTIFICATION_EMITTER); } show = (notification) => { diff --git a/app/lib/methods/subscriptions/rooms.js b/app/lib/methods/subscriptions/rooms.js index 2cf15a39c5..722f6337ab 100644 --- a/app/lib/methods/subscriptions/rooms.js +++ b/app/lib/methods/subscriptions/rooms.js @@ -14,6 +14,7 @@ import buildMessage from '../helpers/buildMessage'; import RocketChat from '../../rocketchat'; import EventEmitter from '../../../utils/events'; import { removedRoom } from '../../../actions/room'; +import { INAPP_NOTIFICATION_EMITTER } from '../../../containers/InAppNotification'; const removeListener = listener => listener.stop(); @@ -319,7 +320,7 @@ export default function subscribeRooms() { } catch (e) { // do nothing } - EventEmitter.emit('NotificationInApp', notification); + EventEmitter.emit(INAPP_NOTIFICATION_EMITTER, notification); } if (/uiInteraction/.test(ev)) { const { type: eventType, ...args } = type; From 4a617677603bc660703c1d41dfe76c9118b86543 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 14:55:13 -0300 Subject: [PATCH 15/22] Use hooks --- .../InAppNotification/NotifierComponent.js | 126 ++++++++---------- 1 file changed, 58 insertions(+), 68 deletions(-) diff --git a/app/containers/InAppNotification/NotifierComponent.js b/app/containers/InAppNotification/NotifierComponent.js index 5123640a58..4d27fb263e 100644 --- a/app/containers/InAppNotification/NotifierComponent.js +++ b/app/containers/InAppNotification/NotifierComponent.js @@ -11,7 +11,7 @@ import Avatar from '../Avatar'; import { CustomIcon } from '../../lib/Icons'; import sharedStyles from '../../views/Styles'; import { themes } from '../../constants/colors'; -import { withTheme } from '../../theme'; +import { useTheme } from '../../theme'; import { getUserSelector } from '../../selectors/login'; import { ROW_HEIGHT } from '../../presentation/RoomItem'; import { goRoom } from '../../utils/goRoom'; @@ -58,28 +58,24 @@ const styles = StyleSheet.create({ } }); +const hideNotification = () => Notifier.hideNotification(); -class NotifierComponent extends React.Component { - static propTypes = { - baseUrl: PropTypes.string, - user: PropTypes.object, - notification: PropTypes.object, - theme: PropTypes.string, - isMasterDetail: PropTypes.bool - } +const NotifierComponent = ({ + baseUrl, user, notification, isMasterDetail +}) => { + const { theme } = useTheme(); + const { id: userId, token } = user; + const { text, payload } = notification; + const { type } = payload; + const name = type === 'd' ? payload.sender.username : payload.name; + // if sub is not on local database, title and avatar will be null, so we use payload from notification + const { title = name, avatar = name } = notification; - goRoom = () => { - const { - notification, isMasterDetail - } = this.props; - const { payload } = notification; - const { rid, type, prid } = payload; + const onPress = () => { + const { rid, prid } = payload; if (!rid) { return; } - const name = type === 'd' ? payload.sender.username : payload.name; - // if sub is not on local database, title will be null, so we use payload from notification - const { title = name } = notification; const item = { rid, name: title, t: type, prid }; @@ -88,57 +84,51 @@ class NotifierComponent extends React.Component { Navigation.navigate('DrawerNavigator'); } goRoom({ item, isMasterDetail }); - this.hideNotification(); - } - - hideNotification = () => Notifier.hideNotification() + hideNotification(); + }; - render() { - const { - baseUrl, user: { id: userId, token }, notification, theme - } = this.props; - const { text, payload } = notification; - const { type } = payload; - const name = type === 'd' ? payload.sender.username : payload.name; - // if sub is not on local database, title and avatar will be null, so we use payload from notification - const { title = name, avatar = name } = notification; - - return ( - - + + - - <> - - - {title} - {text} - - - - - - - - - ); - } -} + <> + + + {title} + {text} + + + + + + + + + ); +}; + +NotifierComponent.propTypes = { + baseUrl: PropTypes.string, + user: PropTypes.object, + notification: PropTypes.object, + isMasterDetail: PropTypes.bool +}; const mapStateToProps = state => ({ user: getUserSelector(state), @@ -146,4 +136,4 @@ const mapStateToProps = state => ({ isMasterDetail: state.app.isMasterDetail }); -export default connect(mapStateToProps)(withTheme(NotifierComponent)); +export default connect(mapStateToProps)(NotifierComponent); From 13e154976a6c2d7bb31c3c1e960e2e2a38574e96 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 16:18:33 -0300 Subject: [PATCH 16/22] Update lib --- package.json | 2 +- patches/react-native-notifier+1.3.0.patch | 61 ----------------------- yarn.lock | 8 +-- 3 files changed, 5 insertions(+), 66 deletions(-) delete mode 100644 patches/react-native-notifier+1.3.0.patch diff --git a/package.json b/package.json index 59dc89ae78..f258cb27ba 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "react-native-modal": "11.5.6", "react-native-navigation-bar-color": "2.0.1", "react-native-notifications": "2.1.7", - "react-native-notifier": "^1.3.0", + "react-native-notifier": "^1.3.1", "react-native-orientation-locker": "1.1.8", "react-native-picker-select": "7.0.0", "react-native-platform-touchable": "^1.1.1", diff --git a/patches/react-native-notifier+1.3.0.patch b/patches/react-native-notifier+1.3.0.patch deleted file mode 100644 index e09973d945..0000000000 --- a/patches/react-native-notifier+1.3.0.patch +++ /dev/null @@ -1,61 +0,0 @@ -diff --git a/node_modules/react-native-notifier/src/Notifier.tsx b/node_modules/react-native-notifier/src/Notifier.tsx -index 141bc25..ad5119a 100644 ---- a/node_modules/react-native-notifier/src/Notifier.tsx -+++ b/node_modules/react-native-notifier/src/Notifier.tsx -@@ -139,15 +139,7 @@ export class NotifierRoot extends React.PureComponent Date: Tue, 16 Jun 2020 16:24:57 -0300 Subject: [PATCH 17/22] Memo --- app/containers/InAppNotification/NotifierComponent.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/containers/InAppNotification/NotifierComponent.js b/app/containers/InAppNotification/NotifierComponent.js index 4d27fb263e..2ead4266f0 100644 --- a/app/containers/InAppNotification/NotifierComponent.js +++ b/app/containers/InAppNotification/NotifierComponent.js @@ -60,7 +60,7 @@ const styles = StyleSheet.create({ const hideNotification = () => Notifier.hideNotification(); -const NotifierComponent = ({ +const NotifierComponent = React.memo(({ baseUrl, user, notification, isMasterDetail }) => { const { theme } = useTheme(); @@ -121,7 +121,7 @@ const NotifierComponent = ({ ); -}; +}); NotifierComponent.propTypes = { baseUrl: PropTypes.string, From 7162ff37bdbe1d4868ce48e2c4277f44c04d1587 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 16:25:08 -0300 Subject: [PATCH 18/22] Remove unnecessary config --- app/containers/InAppNotification/index.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/containers/InAppNotification/index.js b/app/containers/InAppNotification/index.js index 8c3fc38a4c..1107564e7d 100644 --- a/app/containers/InAppNotification/index.js +++ b/app/containers/InAppNotification/index.js @@ -6,9 +6,6 @@ import EventEmitter from '../../utils/events'; import Navigation from '../../lib/Navigation'; import { getActiveRoute } from '../../utils/navigation'; -const ANIMATION_DURATION = 300; -const NOTIFICATION_DURATION = 3000; - export const INAPP_NOTIFICATION_EMITTER = 'NotificationInApp'; class InAppNotification extends React.Component { @@ -29,9 +26,6 @@ class InAppNotification extends React.Component { return; } Notifier.showNotification({ - showAnimationDuration: ANIMATION_DURATION, - hideAnimationDuration: ANIMATION_DURATION, - duration: NOTIFICATION_DURATION, showEasing: Easing.inOut(Easing.quad), Component: NotifierComponent, componentProps: { From 8ed4932641490a898ad238dd34eeb5fdf67ab8a5 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 16:33:41 -0300 Subject: [PATCH 19/22] memo --- app/containers/InAppNotification/index.js | 31 ++++++++++------------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/app/containers/InAppNotification/index.js b/app/containers/InAppNotification/index.js index 1107564e7d..765f16078d 100644 --- a/app/containers/InAppNotification/index.js +++ b/app/containers/InAppNotification/index.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { memo, useEffect } from 'react'; import { NotifierRoot, Notifier, Easing } from 'react-native-notifier'; import NotifierComponent from './NotifierComponent'; @@ -8,16 +8,8 @@ import { getActiveRoute } from '../../utils/navigation'; export const INAPP_NOTIFICATION_EMITTER = 'NotificationInApp'; -class InAppNotification extends React.Component { - componentDidMount() { - EventEmitter.addEventListener(INAPP_NOTIFICATION_EMITTER, this.show); - } - - componentWillUnmount() { - EventEmitter.removeListener(INAPP_NOTIFICATION_EMITTER); - } - - show = (notification) => { +const InAppNotification = memo(() => { + const show = (notification) => { const { payload } = notification; const state = Navigation.navigationRef.current.getRootState(); const route = getActiveRoute(state); @@ -33,13 +25,16 @@ class InAppNotification extends React.Component { } }); } - } + }; + + useEffect(() => { + EventEmitter.addEventListener(INAPP_NOTIFICATION_EMITTER, show); + return () => { + EventEmitter.removeListener(INAPP_NOTIFICATION_EMITTER); + }; + }, []); - render() { - return ( - - ); - } -} + return ; +}); export default InAppNotification; From 9b03f1d6e7fabc15989c0c9da49642e7ea119823 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 16:55:56 -0300 Subject: [PATCH 20/22] Change style --- .../InAppNotification/NotifierComponent.js | 80 ++++++++++--------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/app/containers/InAppNotification/NotifierComponent.js b/app/containers/InAppNotification/NotifierComponent.js index 2ead4266f0..9ad6163a81 100644 --- a/app/containers/InAppNotification/NotifierComponent.js +++ b/app/containers/InAppNotification/NotifierComponent.js @@ -1,11 +1,11 @@ import React from 'react'; -import { - StyleSheet, SafeAreaView, View, Text -} from 'react-native'; +import { StyleSheet, View, Text } from 'react-native'; import PropTypes from 'prop-types'; import Touchable from 'react-native-platform-touchable'; import { connect } from 'react-redux'; import { Notifier } from 'react-native-notifier'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { useDeviceOrientation } from '@react-native-community/hooks'; import Avatar from '../Avatar'; import { CustomIcon } from '../../lib/Icons'; @@ -29,8 +29,9 @@ const styles = StyleSheet.create({ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', - width: '100%', - borderBottomWidth: StyleSheet.hairlineWidth + marginHorizontal: 10, + borderWidth: StyleSheet.hairlineWidth, + borderRadius: 4 }, content: { flex: 1, @@ -55,6 +56,10 @@ const styles = StyleSheet.create({ }, close: { marginLeft: 10 + }, + small: { + width: '50%', + alignSelf: 'center' } }); @@ -64,6 +69,9 @@ const NotifierComponent = React.memo(({ baseUrl, user, notification, isMasterDetail }) => { const { theme } = useTheme(); + const insets = useSafeAreaInsets(); + const { landscape } = useDeviceOrientation(); + const { id: userId, token } = user; const { text, payload } = notification; const { type } = payload; @@ -88,38 +96,38 @@ const NotifierComponent = React.memo(({ }; return ( - - + + <> + + + {title} + {text} + + + + - - <> - - - {title} - {text} - - - - - - - - + + + ); }); From 5e9206a9d33e5d69404c08e8d545141b20dee6b2 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 17:12:25 -0300 Subject: [PATCH 21/22] Refactor --- app/AppContainer.js | 100 ++++++++++++-------------- app/index.js | 43 ++++++----- app/stacks/InsideStack.js | 16 +---- app/stacks/MasterDetailStack/index.js | 14 +--- 4 files changed, 76 insertions(+), 97 deletions(-) diff --git a/app/AppContainer.js b/app/AppContainer.js index 76e2fee8ef..4242c0cda1 100644 --- a/app/AppContainer.js +++ b/app/AppContainer.js @@ -3,14 +3,12 @@ import PropTypes from 'prop-types'; import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; import { connect } from 'react-redux'; -import { SafeAreaProvider, initialWindowMetrics } from 'react-native-safe-area-context'; import Navigation from './lib/Navigation'; import { defaultHeader, getActiveRouteName, navigationTheme } from './utils/navigation'; import { ROOT_LOADING, ROOT_OUTSIDE, ROOT_NEW_SERVER, ROOT_INSIDE, ROOT_SET_USERNAME, ROOT_BACKGROUND } from './actions/app'; -import { ActionSheetProvider } from './containers/ActionSheet'; // Stacks import AuthLoadingView from './views/AuthLoadingView'; @@ -53,57 +51,53 @@ const App = React.memo(({ root, isMasterDetail }) => { }, []); return ( - - - { - const previousRouteName = Navigation.routeNameRef.current; - const currentRouteName = getActiveRouteName(state); - if (previousRouteName !== currentRouteName) { - setCurrentScreen(currentRouteName); - } - Navigation.routeNameRef.current = currentRouteName; - }} - > - - <> - {root === ROOT_LOADING || root === ROOT_BACKGROUND ? ( - - ) : null} - {root === ROOT_OUTSIDE || root === ROOT_NEW_SERVER ? ( - - ) : null} - {root === ROOT_INSIDE && isMasterDetail ? ( - - ) : null} - {root === ROOT_INSIDE && !isMasterDetail ? ( - - ) : null} - {root === ROOT_SET_USERNAME ? ( - - ) : null} - - - - - + { + const previousRouteName = Navigation.routeNameRef.current; + const currentRouteName = getActiveRouteName(state); + if (previousRouteName !== currentRouteName) { + setCurrentScreen(currentRouteName); + } + Navigation.routeNameRef.current = currentRouteName; + }} + > + + <> + {root === ROOT_LOADING || root === ROOT_BACKGROUND ? ( + + ) : null} + {root === ROOT_OUTSIDE || root === ROOT_NEW_SERVER ? ( + + ) : null} + {root === ROOT_INSIDE && isMasterDetail ? ( + + ) : null} + {root === ROOT_INSIDE && !isMasterDetail ? ( + + ) : null} + {root === ROOT_SET_USERNAME ? ( + + ) : null} + + + ); }); const mapStateToProps = state => ({ diff --git a/app/index.js b/app/index.js index 862d1b08b5..a7167e6921 100644 --- a/app/index.js +++ b/app/index.js @@ -5,6 +5,7 @@ import { Provider } from 'react-redux'; import RNUserDefaults from 'rn-user-defaults'; import { KeyCommandsEmitter } from 'react-native-keycommands'; import RNScreens from 'react-native-screens'; +import { SafeAreaProvider, initialWindowMetrics } from 'react-native-safe-area-context'; import { defaultTheme, @@ -30,6 +31,10 @@ import AppContainer from './AppContainer'; import TwoFactor from './containers/TwoFactor'; import ScreenLockedView from './views/ScreenLockedView'; import ChangePasscodeView from './views/ChangePasscodeView'; +import Toast from './containers/Toast'; +import InAppNotification from './containers/InAppNotification'; +import { ActionSheetProvider } from './containers/ActionSheet'; + RNScreens.enableScreens(); @@ -151,22 +156,28 @@ export default class Root extends React.Component { render() { const { themePreferences, theme } = this.state; return ( - - - - - - - - - - + + + + + + + + + + + + + + + + ); } } diff --git a/app/stacks/InsideStack.js b/app/stacks/InsideStack.js index 9cf6126c34..63744cd3af 100644 --- a/app/stacks/InsideStack.js +++ b/app/stacks/InsideStack.js @@ -7,9 +7,7 @@ import { ThemeContext } from '../theme'; import { defaultHeader, themedHeader, ModalAnimation, StackAnimation } from '../utils/navigation'; -import Toast from '../containers/Toast'; import Sidebar from '../views/SidebarView'; -import InAppNotification from '../containers/InAppNotification'; // Chats Stack import RoomView from '../views/RoomView'; @@ -320,16 +318,4 @@ const InsideStackNavigator = () => { ); }; -const RootInsideStack = ({ navigation, route }) => ( - <> - - - - -); -RootInsideStack.propTypes = { - navigation: PropTypes.object, - route: PropTypes.object -}; - -export default RootInsideStack; +export default InsideStackNavigator; diff --git a/app/stacks/MasterDetailStack/index.js b/app/stacks/MasterDetailStack/index.js index 855008f2c0..6998dc3929 100644 --- a/app/stacks/MasterDetailStack/index.js +++ b/app/stacks/MasterDetailStack/index.js @@ -292,16 +292,4 @@ const InsideStackNavigator = React.memo(() => { ); }); -const RootInsideStack = React.memo(({ navigation, route }) => ( - <> - - - - -)); -RootInsideStack.propTypes = { - navigation: PropTypes.object, - route: PropTypes.object -}; - -export default RootInsideStack; +export default InsideStackNavigator; From 9ef60302c98566ff0af12b8c48da00e0ac9c6e7e Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 16 Jun 2020 17:16:50 -0300 Subject: [PATCH 22/22] lint --- app/stacks/InsideStack.js | 1 - app/stacks/MasterDetailStack/index.js | 2 -- 2 files changed, 3 deletions(-) diff --git a/app/stacks/InsideStack.js b/app/stacks/InsideStack.js index 63744cd3af..147081deb7 100644 --- a/app/stacks/InsideStack.js +++ b/app/stacks/InsideStack.js @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { createStackNavigator } from '@react-navigation/stack'; import { createDrawerNavigator } from '@react-navigation/drawer'; diff --git a/app/stacks/MasterDetailStack/index.js b/app/stacks/MasterDetailStack/index.js index 6998dc3929..40b59b09eb 100644 --- a/app/stacks/MasterDetailStack/index.js +++ b/app/stacks/MasterDetailStack/index.js @@ -8,8 +8,6 @@ import { ThemeContext } from '../../theme'; import { defaultHeader, themedHeader, StackAnimation, FadeFromCenterModal } from '../../utils/navigation'; -import Toast from '../../containers/Toast'; -import InAppNotification from '../../containers/InAppNotification'; import { ModalContainer } from './ModalContainer'; // Chats Stack