From b7b58b506bf836fa19b064e93443cb54fa1bada8 Mon Sep 17 00:00:00 2001 From: Brian Lovin Date: Tue, 22 May 2018 21:29:24 -0700 Subject: [PATCH 01/42] POC current user redux implementation --- mobile/actions/currentUserId.js | 13 +++++++++++++ mobile/reducers/currentUserId.js | 19 +++++++++++++++++++ mobile/reducers/index.js | 3 +++ mobile/views/Dashboard/index.js | 16 +++++++++++++++- 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 mobile/actions/currentUserId.js create mode 100644 mobile/reducers/currentUserId.js diff --git a/mobile/actions/currentUserId.js b/mobile/actions/currentUserId.js new file mode 100644 index 0000000000..5e3aee92bc --- /dev/null +++ b/mobile/actions/currentUserId.js @@ -0,0 +1,13 @@ +// @flow + +export type SetCurrentUserAction = { + type: 'SET_CURRENT_USER_ID', + id: ?string, +}; + +export const setCurrentUserId = (id: ?string) => { + return { + type: 'SET_CURRENT_USER_ID', + id, + }; +}; diff --git a/mobile/reducers/currentUserId.js b/mobile/reducers/currentUserId.js new file mode 100644 index 0000000000..c4b3be78b5 --- /dev/null +++ b/mobile/reducers/currentUserId.js @@ -0,0 +1,19 @@ +// @flow +import { type SetCurrentUserAction } from '../actions/currentUserId'; + +export type CurrentUserState = ?string; + +const initialState: CurrentUserState = null; + +export default ( + state: CurrentUserState = initialState, + action: SetCurrentUserAction +): CurrentUserState => { + switch (action.type) { + case 'SET_CURRENT_USER_ID': { + return action.id; + } + default: + return state; + } +}; diff --git a/mobile/reducers/index.js b/mobile/reducers/index.js index 6443010fba..681f2f4ec3 100644 --- a/mobile/reducers/index.js +++ b/mobile/reducers/index.js @@ -1,11 +1,14 @@ // @flow import { combineReducers } from 'redux'; import authentication, { type AuthenticationState } from './authentication'; +import currentUserId, { type CurrentUserState } from './currentUserId'; export type State = { +authentication: $Exact, + +currentUserId: CurrentUserState, }; export default combineReducers({ authentication, + currentUserId, }); diff --git a/mobile/views/Dashboard/index.js b/mobile/views/Dashboard/index.js index bc9cddafb2..a86c76791f 100644 --- a/mobile/views/Dashboard/index.js +++ b/mobile/views/Dashboard/index.js @@ -1,10 +1,13 @@ // @flow import * as React from 'react'; import { View } from 'react-native'; +import { connect } from 'react-redux'; import compose from 'recompose/compose'; import withSafeView from '../../components/SafeAreaView'; import ThreadFeed from '../../components/ThreadFeed'; import getCurrentUserEverythingFeed from '../../../shared/graphql/queries/user/getCurrentUserEverythingFeed'; +import { setCurrentUserId } from '../../actions/currentUserId'; +import type { State as ReduxState } from '../../reducers'; import { getCurrentUser, type GetUserType, @@ -16,12 +19,22 @@ const EverythingThreadFeed = compose(getCurrentUserEverythingFeed)(ThreadFeed); type Props = { navigation: Object, + dispatch: Function, data: { user?: GetUserType, }, + currentUserId: ?GetUserType, }; class Dashboard extends React.Component { + componentDidUpdate(prevProps) { + const curr = this.props; + if (!prevProps.data.user && curr.data.user) { + if (!curr.currentUserId || curr.data.user.id !== curr.currentUserId) { + return curr.dispatch(setCurrentUserId(curr.data.user.id)); + } + } + } render() { return ( @@ -33,4 +46,5 @@ class Dashboard extends React.Component { } } -export default compose(withSafeView, getCurrentUser)(Dashboard); +const map = ({ currentUserId }: ReduxState): * => ({ currentUserId }); +export default compose(connect(map), withSafeView, getCurrentUser)(Dashboard); From 4baf3bd01ceab6d01ab089c2f438066bf5cf41ee Mon Sep 17 00:00:00 2001 From: Brian Lovin Date: Tue, 22 May 2018 21:29:35 -0700 Subject: [PATCH 02/42] Fix up outdated notification types --- shared/types.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/shared/types.js b/shared/types.js index 267217f4dc..eb18a7fdfc 100644 --- a/shared/types.js +++ b/shared/types.js @@ -139,7 +139,6 @@ export type NotificationEventType = | 'REACTION_CREATED' | 'MESSAGE_CREATED' | 'THREAD_CREATED' - | 'THREAD_EDITED' | 'CHANNEL_CREATED' | 'DIRECT_MESSAGE_THREAD_CREATED' | 'USER_JOINED_COMMUNITY' @@ -147,7 +146,13 @@ export type NotificationEventType = | 'USER_APPROVED_TO_JOIN_PRIVATE_CHANNEL' | 'THREAD_LOCKED_BY_OWNER' | 'THREAD_DELETED_BY_OWNER' - | 'COMMUNITY_INVITATION'; + | 'COMMUNITY_INVITE' + | 'MENTION_THREAD' + | 'MENTION_MESSAGE' + | 'PRIVATE_CHANNEL_REQUEST_SENT' + | 'PRIVATE_CHANNEL_REQUEST_APPROVED' + | 'PRIVATE_COMMUNITY_REQUEST_SENT' + | 'PRIVATE_COMMUNITY_REQUEST_APPROVED'; type NotificationPayload = { id: string, From 34fbec9a9d503542f84effa7186e7e1a89bbf877 Mon Sep 17 00:00:00 2001 From: Brian Lovin Date: Tue, 22 May 2018 21:30:07 -0700 Subject: [PATCH 03/42] Get notifications rendering to the view --- mobile/views/Dashboard/style.js | 1 + mobile/views/Notifications/index.js | 71 +++-- mobile/views/Notifications/renderUtils.js | 49 +++ mobile/views/Notifications/renderer.js | 280 ++++++++++++++++++ mobile/views/Notifications/style.js | 0 .../notification/notificationInfo.js | 11 +- .../queries/notification/getNotifications.js | 3 +- 7 files changed, 382 insertions(+), 33 deletions(-) create mode 100644 mobile/views/Notifications/renderUtils.js create mode 100644 mobile/views/Notifications/renderer.js create mode 100644 mobile/views/Notifications/style.js diff --git a/mobile/views/Dashboard/style.js b/mobile/views/Dashboard/style.js index f2c3081388..f44ab2b6bc 100644 --- a/mobile/views/Dashboard/style.js +++ b/mobile/views/Dashboard/style.js @@ -2,6 +2,7 @@ import styled from 'styled-components/native'; export const Wrapper = styled.View` + display: flex; background-color: ${props => props.theme.bg.default}; flex: 1; `; diff --git a/mobile/views/Notifications/index.js b/mobile/views/Notifications/index.js index f395575be5..037994a530 100644 --- a/mobile/views/Notifications/index.js +++ b/mobile/views/Notifications/index.js @@ -1,6 +1,6 @@ // @flow -import React from 'react'; -import { View, Button } from 'react-native'; +import * as React from 'react'; +import { Button } from 'react-native'; import compose from 'recompose/compose'; import { connect } from 'react-redux'; import { SecureStore } from 'expo'; @@ -18,11 +18,17 @@ import subscribeExpoPush from '../../../shared/graphql/mutations/user/subscribeE import getPushNotificationToken from '../../utils/get-push-notification-token'; import type { State as ReduxState } from '../../reducers'; import type { AuthenticationState } from '../../reducers/authentication'; +import Renderer from './renderer'; +import { parseNotification } from './renderUtils'; +import type { Navigation } from '../../utils/types'; +import type { CurrentUserState } from '../../reducers/currentUserId'; type Props = { ...$Exact, mutate: (token: any) => Promise, authentication: AuthenticationState, + currentUserId: CurrentUserState, + navigation: Navigation, data: { subscribeToNewNotifications: Function, fetchMore: Function, @@ -41,10 +47,6 @@ type State = { pushNotifications: ?PushNotificationsDecision, }; -const mapStateToProps = (state: ReduxState): * => ({ - authentication: state.authentication, -}); - class Notifications extends React.Component { constructor() { super(); @@ -132,31 +134,39 @@ class Notifications extends React.Component { }; render() { - const { isLoading, hasError, data: { notifications } } = this.props; + const { + isLoading, + hasError, + data: { notifications }, + currentUserId, + navigation, + } = this.props; const { pushNotifications } = this.state; if (notifications) { return ( - - {pushNotifications != null && - pushNotifications.decision === undefined && ( -