From fdb81ea19cd5217d1b159eabf9ea21981ca1efb6 Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Mon, 25 Sep 2017 23:44:39 +0300 Subject: [PATCH 01/14] feat(tabbar): show notifications count --- routes.js | 8 +-- src/api/index.js | 15 +++++ src/auth/screens/events.screen.js | 10 ++- src/components/index.js | 1 + src/components/notification-icon.component.js | 66 +++++++++++++++++++ src/config/colors.js | 1 + src/notifications/notifications.action.js | 24 +++++++ src/notifications/notifications.reducer.js | 17 +++++ src/notifications/notifications.type.js | 3 + .../screens/notifications.screen.js | 6 ++ 10 files changed, 143 insertions(+), 8 deletions(-) create mode 100644 src/components/notification-icon.component.js diff --git a/routes.js b/routes.js index 278033977..467263f02 100644 --- a/routes.js +++ b/routes.js @@ -8,6 +8,7 @@ import { } from 'react-navigation'; import { Icon } from 'react-native-elements'; +import { NotificationIcon } from 'components'; import { colors } from 'config'; import { translate } from 'utils'; @@ -268,12 +269,7 @@ const MainTabNavigator = TabNavigator( screen: NotificationsStackNavigator, navigationOptions: { tabBarIcon: ({ tintColor }) => - , + , }, }, Search: { diff --git a/src/api/index.js b/src/api/index.js index dbf1fc7fa..4f8609e57 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -300,6 +300,21 @@ export async function fetchMarkRepoNotificationAsRead( return response; } +export async function fetchNotificationsCount(accessToken) { + const ENDPOINT = `${root}/notifications?per_page=1`; + const response = await fetch(ENDPOINT, accessTokenParameters(accessToken)); + + let linkHeader = response.headers.get('Link'); + let count = 0; + + if (linkHeader) { + linkHeader = linkHeader.match(/page=(\d)+/g).pop(); + count = linkHeader.split('=').pop(); + } + + return count; +} + export async function fetchChangeStarStatusRepo( owner, repo, diff --git a/src/auth/screens/events.screen.js b/src/auth/screens/events.screen.js index f129a6575..af84170fc 100644 --- a/src/auth/screens/events.screen.js +++ b/src/auth/screens/events.screen.js @@ -9,19 +9,22 @@ import moment from 'moment/min/moment-with-locales.min'; import { LoadingUserListItem, UserListItem, ViewContainer } from 'components'; import { colors, fonts, normalize } from 'config'; import { emojifyText, translate } from 'utils'; -import { getUserEvents } from '../auth.action'; +import { getUserEvents } from 'auth'; +import { getNotificationsCount } from 'notifications'; const mapStateToProps = state => ({ user: state.auth.user, userEvents: state.auth.events, language: state.auth.language, isPendingEvents: state.auth.isPendingEvents, + accessToken: state.auth.accessToken, }); const mapDispatchToProps = dispatch => bindActionCreators( { getUserEvents, + getNotificationsCount, }, dispatch ); @@ -86,8 +89,11 @@ class Events extends Component { } } - getUserEvents = (user = this.props.user) => { + getUserEvents = () => { + const { user, accessToken } = this.props; + this.props.getUserEvents(user.login); + this.props.getNotificationsCount(accessToken); }; getAction = userEvent => { diff --git a/src/components/index.js b/src/components/index.js index a6b217650..aa5435432 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -25,3 +25,4 @@ export * from './user-list-item.component'; export * from './user-profile.component'; export * from './view-container.component'; export * from './image-zoom.component'; +export * from './notification-icon.component'; diff --git a/src/components/notification-icon.component.js b/src/components/notification-icon.component.js new file mode 100644 index 000000000..da4fa4a0f --- /dev/null +++ b/src/components/notification-icon.component.js @@ -0,0 +1,66 @@ +// @flow +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import { Text, View, StyleSheet } from 'react-native'; +import { Icon } from 'react-native-elements'; + +import { colors, fonts } from 'config'; + +const styles = StyleSheet.create({ + badge: { + position: 'absolute', + right: 0, + top: 0, + backgroundColor: colors.redDarkest, + borderRadius: 18, + width: 18, + height: 18, + justifyContent: 'center', + alignItems: 'center', + }, + badgeText: { + alignSelf: 'center', + fontSize: 9, + ...fonts.fontPrimary, + color: colors.white, + backgroundColor: 'transparent', + }, +}); + +const mapStateToProps = state => ({ + notificationsCount: state.notifications.notificationsCount, +}); + +class NotificationIconComponent extends Component { + props: { + iconColor: string, + notificationsCount: string, + }; + + render() { + const { iconColor, notificationsCount } = this.props; + + return ( + + + + {notificationsCount + ? + + {notificationsCount > 99 ? '99+' : notificationsCount} + + + : null} + + ); + } +} + +export const NotificationIcon = connect(mapStateToProps)( + NotificationIconComponent +); diff --git a/src/config/colors.js b/src/config/colors.js index 4f67ad65b..88cae9f20 100644 --- a/src/config/colors.js +++ b/src/config/colors.js @@ -17,6 +17,7 @@ export const colors = { darkGreen: '#27ae60', red: '#ee0701', darkRed: '#e74c3c', + redDarkest: '#da0000', white: '#ffffff', transparent: 'transparent', codeChunkBlue: '#f8f8ff', diff --git a/src/notifications/notifications.action.js b/src/notifications/notifications.action.js index 5474ae9fa..49971f7e2 100644 --- a/src/notifications/notifications.action.js +++ b/src/notifications/notifications.action.js @@ -2,6 +2,7 @@ import { fetchNotifications, fetchMarkNotificationAsRead, fetchMarkRepoNotificationAsRead, + fetchNotificationsCount, } from 'api'; import { GET_UNREAD_NOTIFICATIONS, @@ -9,6 +10,7 @@ import { GET_ALL_NOTIFICATIONS, MARK_NOTIFICATION_AS_READ, MARK_REPO_AS_READ, + GET_NOTIFICATIONS_COUNT, } from './notifications.type'; export const getUnreadNotifications = () => { @@ -120,3 +122,25 @@ export const markRepoAsRead = repoFullName => { }); }; }; + +export const getNotificationsCount = () => { + return (dispatch, getState) => { + const accessToken = getState().auth.accessToken; + + dispatch({ type: GET_NOTIFICATIONS_COUNT.PENDING }); + + fetchNotificationsCount(accessToken) + .then(data => { + dispatch({ + type: GET_NOTIFICATIONS_COUNT.SUCCESS, + payload: data, + }); + }) + .catch(error => { + dispatch({ + type: GET_NOTIFICATIONS_COUNT.ERROR, + payload: error, + }); + }); + }; +}; diff --git a/src/notifications/notifications.reducer.js b/src/notifications/notifications.reducer.js index e86c1caa2..ddd5ce35c 100644 --- a/src/notifications/notifications.reducer.js +++ b/src/notifications/notifications.reducer.js @@ -4,6 +4,7 @@ import { GET_ALL_NOTIFICATIONS, MARK_NOTIFICATION_AS_READ, MARK_REPO_AS_READ, + GET_NOTIFICATIONS_COUNT, } from './notifications.type'; const initialState = { @@ -16,6 +17,7 @@ const initialState = { isPendingMarkNotificationAsRead: false, isPendingRepoMarkAsRead: false, error: '', + notificationsCount: null, }; export const notificationsReducer = (state = initialState, action = {}) => { @@ -92,6 +94,7 @@ export const notificationsReducer = (state = initialState, action = {}) => { : notification ), isPendingMarkNotificationAsRead: false, + notificationsCount: state.notificationsCount - 1, }; case MARK_NOTIFICATION_AS_READ.ERROR: return { @@ -129,6 +132,20 @@ export const notificationsReducer = (state = initialState, action = {}) => { error: action.payload, isPendingRepoMarkAsRead: false, }; + case GET_NOTIFICATIONS_COUNT.PENDING: + return { + ...state, + }; + case GET_NOTIFICATIONS_COUNT.SUCCESS: + return { + ...state, + notificationsCount: action.payload, + }; + case GET_NOTIFICATIONS_COUNT.ERROR: + return { + ...state, + error: action.payload, + }; default: return state; } diff --git a/src/notifications/notifications.type.js b/src/notifications/notifications.type.js index 34ac71d69..c60ed8d22 100644 --- a/src/notifications/notifications.type.js +++ b/src/notifications/notifications.type.js @@ -11,3 +11,6 @@ export const MARK_NOTIFICATION_AS_READ = createActionSet( 'MARK_NOTIFICATION_AS_READ' ); export const MARK_REPO_AS_READ = createActionSet('MARK_REPO_AS_READ'); +export const GET_NOTIFICATIONS_COUNT = createActionSet( + 'GET_NOTIFICATIONS_COUNT' +); diff --git a/src/notifications/screens/notifications.screen.js b/src/notifications/screens/notifications.screen.js index bb0a01937..b3c38a7e4 100644 --- a/src/notifications/screens/notifications.screen.js +++ b/src/notifications/screens/notifications.screen.js @@ -29,6 +29,7 @@ import { getAllNotifications, markAsRead, markRepoAsRead, + getNotificationsCount, } from '../index'; const mapStateToProps = state => ({ @@ -50,6 +51,7 @@ const mapDispatchToProps = dispatch => getAllNotifications, markAsRead, markRepoAsRead, + getNotificationsCount, }, dispatch ); @@ -119,6 +121,7 @@ class Notifications extends Component { getAllNotifications: Function, markAsRead: Function, markRepoAsRead: Function, + getNotificationsCount: Function, unread: Array, participating: Array, all: Array, @@ -145,6 +148,7 @@ class Notifications extends Component { this.props.getUnreadNotifications(); this.props.getParticipatingNotifications(); this.props.getAllNotifications(); + this.props.getNotificationsCount(); } getImage(repoName) { @@ -163,6 +167,8 @@ class Notifications extends Component { } = this.props; const { type } = this.state; + this.props.getNotificationsCount(); + switch (type) { case 0: return getUnreadNotifications; From d30b9a8e13efc7d4fbe8314f8d5d5b80a92ed6ef Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Tue, 26 Sep 2017 11:36:39 +0300 Subject: [PATCH 02/14] feat(notification-icon): update badge text after mark repo notifications --- src/api/index.js | 19 +++++++++++++ src/notifications/notifications.action.js | 33 ++++++++++++++-------- src/notifications/notifications.reducer.js | 2 ++ 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/api/index.js b/src/api/index.js index 4f8609e57..a59dd7920 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -315,6 +315,25 @@ export async function fetchNotificationsCount(accessToken) { return count; } +export async function fetchRepoNotificationsCount( + owner, + repoName, + accessToken +) { + const ENDPOINT = `${root}/repos/${owner}/${repoName}/notifications?per_page=1`; + const response = await fetch(ENDPOINT, accessTokenParameters(accessToken)); + + let linkHeader = response.headers.get('Link'); + let count = 1; + + if (linkHeader) { + linkHeader = linkHeader.match(/page=(\d)+/g).pop(); + count = linkHeader.split('=').pop(); + } + + return +count; +} + export async function fetchChangeStarStatusRepo( owner, repo, diff --git a/src/notifications/notifications.action.js b/src/notifications/notifications.action.js index 49971f7e2..6347ca714 100644 --- a/src/notifications/notifications.action.js +++ b/src/notifications/notifications.action.js @@ -3,6 +3,7 @@ import { fetchMarkNotificationAsRead, fetchMarkRepoNotificationAsRead, fetchNotificationsCount, + fetchRepoNotificationsCount, } from 'api'; import { GET_UNREAD_NOTIFICATIONS, @@ -104,22 +105,30 @@ export const markAsRead = notificationID => { export const markRepoAsRead = repoFullName => { return (dispatch, getState) => { const accessToken = getState().auth.accessToken; + const [owner, repoName] = repoFullName.split('/'); dispatch({ type: MARK_REPO_AS_READ.PENDING }); - fetchMarkRepoNotificationAsRead(repoFullName, accessToken) - .then(() => { - dispatch({ - type: MARK_REPO_AS_READ.SUCCESS, - repoFullName, - }); - }) - .catch(error => { - dispatch({ - type: MARK_REPO_AS_READ.ERROR, - payload: error, + fetchRepoNotificationsCount( + owner, + repoName, + accessToken + ).then(repoNotificationsCount => { + fetchMarkRepoNotificationAsRead(repoFullName, accessToken) + .then(() => { + dispatch({ + type: MARK_REPO_AS_READ.SUCCESS, + repoFullName, + repoNotificationsCount, + }); + }) + .catch(error => { + dispatch({ + type: MARK_REPO_AS_READ.ERROR, + payload: error, + }); }); - }); + }); }; }; diff --git a/src/notifications/notifications.reducer.js b/src/notifications/notifications.reducer.js index ddd5ce35c..a567e0010 100644 --- a/src/notifications/notifications.reducer.js +++ b/src/notifications/notifications.reducer.js @@ -125,6 +125,8 @@ export const notificationsReducer = (state = initialState, action = {}) => { : notification ), isPendingRepoMarkAsRead: false, + notificationsCount: + state.notificationsCount - action.repoNotificationsCount, }; case MARK_REPO_AS_READ.ERROR: return { From e34af6fa264326f68b4210582242efe7cb41f54f Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Tue, 26 Sep 2017 12:10:08 +0300 Subject: [PATCH 03/14] feat(notification-icon): restyle --- routes.js | 5 ++++- src/components/notification-icon.component.js | 6 ++++-- src/config/colors.js | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/routes.js b/routes.js index dce354f94..8967002fe 100644 --- a/routes.js +++ b/routes.js @@ -304,6 +304,9 @@ const MainTabNavigator = TabNavigator( showLabel: false, activeTintColor: colors.primaryDark, inactiveTintColor: colors.grey, + style: { + backgroundColor: colors.alabaster, + }, }, tabBarComponent: ({ jumpToIndex, ...props }) => Date: Tue, 26 Sep 2017 20:02:31 +0300 Subject: [PATCH 04/14] refactor(api): update according with new api --- src/api/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/api/index.js b/src/api/index.js index 6d0f50258..e85c97d0a 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -312,3 +312,9 @@ export async function fetchAccessToken(code, state) { return response.json(); } + +export const fetchNotificationsCount = accessToken => + v3.count('/notifications?per_page=1', accessToken); + +export const fetchRepoNotificationsCount = (owner, repoName, accessToken) => + v3.count(`/repos/${owner}/${repoName}/notifications?per_page=1`, accessToken); From 8f61ee164a8abdedbc182ce7fd1fc454512cf974 Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Tue, 26 Sep 2017 20:03:13 +0300 Subject: [PATCH 05/14] refactor(config): rename color --- src/components/notification-icon.component.js | 2 +- src/config/colors.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/notification-icon.component.js b/src/components/notification-icon.component.js index 57b99602b..5f6262424 100644 --- a/src/components/notification-icon.component.js +++ b/src/components/notification-icon.component.js @@ -11,7 +11,7 @@ const styles = StyleSheet.create({ position: 'absolute', right: 1, top: -1, - backgroundColor: colors.redDarkest, + backgroundColor: colors.darkerRed, borderRadius: 18, width: 18, height: 18, diff --git a/src/config/colors.js b/src/config/colors.js index 6064b4c57..936c1abc9 100644 --- a/src/config/colors.js +++ b/src/config/colors.js @@ -17,7 +17,7 @@ export const colors = { darkGreen: '#27ae60', red: '#ee0701', darkRed: '#e74c3c', - redDarkest: '#da0000', + darkerRed: '#da0000', white: '#ffffff', transparent: 'transparent', codeChunkBlue: '#f8f8ff', From eff3e5a4457a8480f7abe4b2c9983f7c12ad8be6 Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Thu, 28 Sep 2017 16:56:36 +0300 Subject: [PATCH 06/14] refactor(notification-icon): extract Badge component --- src/components/badge.component.js | 38 +++++++++++++++++++ src/components/index.js | 1 + src/components/notification-icon.component.js | 36 ++---------------- 3 files changed, 43 insertions(+), 32 deletions(-) create mode 100644 src/components/badge.component.js diff --git a/src/components/badge.component.js b/src/components/badge.component.js new file mode 100644 index 000000000..88ec72f13 --- /dev/null +++ b/src/components/badge.component.js @@ -0,0 +1,38 @@ +import React from 'react'; +import { StyleSheet, View, Text } from 'react-native'; + +import { colors, fonts } from 'config'; + +type Props = { + text: string, +}; + +const styles = StyleSheet.create({ + badge: { + position: 'absolute', + right: 1, + top: -1, + backgroundColor: colors.darkerRed, + borderRadius: 18, + width: 18, + height: 18, + justifyContent: 'center', + alignItems: 'center', + borderColor: colors.alabaster, + borderWidth: 1, + }, + badgeText: { + alignSelf: 'center', + fontSize: 9, + ...fonts.fontPrimary, + color: colors.white, + backgroundColor: 'transparent', + }, +}); + +export const Badge = ({ text }: Props) => + + + {text} + + ; diff --git a/src/components/index.js b/src/components/index.js index aa5435432..70b7c05ff 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -26,3 +26,4 @@ export * from './user-profile.component'; export * from './view-container.component'; export * from './image-zoom.component'; export * from './notification-icon.component'; +export * from './badge.component'; diff --git a/src/components/notification-icon.component.js b/src/components/notification-icon.component.js index 5f6262424..d1b7287bb 100644 --- a/src/components/notification-icon.component.js +++ b/src/components/notification-icon.component.js @@ -1,33 +1,10 @@ // @flow import React, { Component } from 'react'; import { connect } from 'react-redux'; -import { Text, View, StyleSheet } from 'react-native'; +import { View } from 'react-native'; import { Icon } from 'react-native-elements'; -import { colors, fonts } from 'config'; - -const styles = StyleSheet.create({ - badge: { - position: 'absolute', - right: 1, - top: -1, - backgroundColor: colors.darkerRed, - borderRadius: 18, - width: 18, - height: 18, - justifyContent: 'center', - alignItems: 'center', - borderColor: colors.alabaster, - borderWidth: 1, - }, - badgeText: { - alignSelf: 'center', - fontSize: 9, - ...fonts.fontPrimary, - color: colors.white, - backgroundColor: 'transparent', - }, -}); +import { Badge } from 'components'; const mapStateToProps = state => ({ notificationsCount: state.notifications.notificationsCount, @@ -51,13 +28,8 @@ class NotificationIconComponent extends Component { size={33} /> - {notificationsCount - ? - - {notificationsCount > 99 ? '99+' : notificationsCount} - - - : null} + {notificationsCount && + 99 ? '99+' : notificationsCount} />} ); } From 54a3e67bbfe2d9eda80d6c52ee495d710ab5a844 Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Thu, 28 Sep 2017 17:19:22 +0300 Subject: [PATCH 07/14] refactor(events): use destructuring --- src/auth/screens/events.screen.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/auth/screens/events.screen.js b/src/auth/screens/events.screen.js index af84170fc..729daf020 100644 --- a/src/auth/screens/events.screen.js +++ b/src/auth/screens/events.screen.js @@ -77,21 +77,20 @@ const styles = StyleSheet.create({ }); class Events extends Component { - componentDidMount() { - if (this.props.user.login) { - this.getUserEvents(this.props.user); + componentDidMount(user = this.props) { + if (user.login) { + this.getUserEvents(user); } } - componentWillReceiveProps(nextProps) { - if (nextProps.user.login && !this.props.user.login) { - this.getUserEvents(nextProps.user); + // eslint-disable-next-line no-undef + componentWillReceiveProps(user = nextProps) { + if (user.login && !this.props.user.login) { + this.getUserEvents(user); } } - getUserEvents = () => { - const { user, accessToken } = this.props; - + getUserEvents = ({ user, accessToken } = this.props) => { this.props.getUserEvents(user.login); this.props.getNotificationsCount(accessToken); }; From 29ef8640af9d9f8b3bed9885f52bfcda429d56fc Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Thu, 28 Sep 2017 17:27:13 +0300 Subject: [PATCH 08/14] refactor(notifications): use destructuring --- src/notifications/screens/notifications.screen.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/notifications/screens/notifications.screen.js b/src/notifications/screens/notifications.screen.js index ad0978a22..5e902f16e 100644 --- a/src/notifications/screens/notifications.screen.js +++ b/src/notifications/screens/notifications.screen.js @@ -164,10 +164,11 @@ class Notifications extends Component { getUnreadNotifications, getParticipatingNotifications, getAllNotifications, + getNotificationsCount, } = this.props; const { type } = this.state; - this.props.getNotificationsCount(); + getNotificationsCount(); switch (type) { case 0: From f9afbc87689a1c2c463bef0145ecad4baf0cdff9 Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Thu, 28 Sep 2017 18:04:01 +0300 Subject: [PATCH 09/14] refactor(events): use destructuring --- src/auth/screens/events.screen.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/auth/screens/events.screen.js b/src/auth/screens/events.screen.js index 729daf020..1981c822b 100644 --- a/src/auth/screens/events.screen.js +++ b/src/auth/screens/events.screen.js @@ -77,16 +77,16 @@ const styles = StyleSheet.create({ }); class Events extends Component { - componentDidMount(user = this.props) { + componentDidMount({ user } = this.props) { if (user.login) { - this.getUserEvents(user); + this.getUserEvents(); } } // eslint-disable-next-line no-undef componentWillReceiveProps(user = nextProps) { if (user.login && !this.props.user.login) { - this.getUserEvents(user); + this.getUserEvents(nextProps); } } From caad62e337ffc4a77ef0a1807b9de843caf4802c Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Thu, 28 Sep 2017 18:14:13 +0300 Subject: [PATCH 10/14] fix(notification-icon): fix boolean check --- src/components/notification-icon.component.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/notification-icon.component.js b/src/components/notification-icon.component.js index d1b7287bb..c21f5a2a5 100644 --- a/src/components/notification-icon.component.js +++ b/src/components/notification-icon.component.js @@ -28,7 +28,7 @@ class NotificationIconComponent extends Component { size={33} /> - {notificationsCount && + {!!notificationsCount && 99 ? '99+' : notificationsCount} />} ); From 4f4070b791c9f86694745c34d1f8bd2b205c122d Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Thu, 28 Sep 2017 18:17:53 +0300 Subject: [PATCH 11/14] fix(fetchNotificationsCount): set zero as default count --- src/api/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/api/index.js b/src/api/index.js index e85c97d0a..dafc835f9 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -55,7 +55,7 @@ export const v3 = { return params; }, - count: async (url, accessToken) => { + count: async (url, accessToken, defaultNumber = 1) => { const finalUrl = url.indexOf('?') !== -1 ? `${url}&per_page=1` : `${url}?per_page=1`; const response = await v3.get(finalUrl, accessToken); @@ -65,7 +65,7 @@ export const v3 = { } let linkHeader = response.headers.get('Link'); - let number = 1; + let number = defaultNumber; if (linkHeader !== null) { linkHeader = linkHeader.match(/page=(\d)+/g).pop(); @@ -314,7 +314,7 @@ export async function fetchAccessToken(code, state) { } export const fetchNotificationsCount = accessToken => - v3.count('/notifications?per_page=1', accessToken); + v3.count('/notifications?per_page=1', accessToken, 0); export const fetchRepoNotificationsCount = (owner, repoName, accessToken) => v3.count(`/repos/${owner}/${repoName}/notifications?per_page=1`, accessToken); From 00bc2b611f5ffd343db5bdb904b4e16596c77f4c Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Thu, 28 Sep 2017 18:43:31 +0300 Subject: [PATCH 12/14] fix(api count): return correct value if there is no linkHeader --- src/api/index.js | 10 +++++++--- src/notifications/notifications.reducer.js | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/api/index.js b/src/api/index.js index dafc835f9..d44870388 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -55,7 +55,7 @@ export const v3 = { return params; }, - count: async (url, accessToken, defaultNumber = 1) => { + count: async (url, accessToken) => { const finalUrl = url.indexOf('?') !== -1 ? `${url}&per_page=1` : `${url}?per_page=1`; const response = await v3.get(finalUrl, accessToken); @@ -65,11 +65,15 @@ export const v3 = { } let linkHeader = response.headers.get('Link'); - let number = defaultNumber; + let number; if (linkHeader !== null) { linkHeader = linkHeader.match(/page=(\d)+/g).pop(); number = linkHeader.split('=').pop(); + } else { + number = await response.json().then(data => { + return data.length; + }); } return abbreviateNumber(number); @@ -314,7 +318,7 @@ export async function fetchAccessToken(code, state) { } export const fetchNotificationsCount = accessToken => - v3.count('/notifications?per_page=1', accessToken, 0); + v3.count('/notifications?per_page=1', accessToken); export const fetchRepoNotificationsCount = (owner, repoName, accessToken) => v3.count(`/repos/${owner}/${repoName}/notifications?per_page=1`, accessToken); diff --git a/src/notifications/notifications.reducer.js b/src/notifications/notifications.reducer.js index a567e0010..2c9d8fa22 100644 --- a/src/notifications/notifications.reducer.js +++ b/src/notifications/notifications.reducer.js @@ -94,7 +94,8 @@ export const notificationsReducer = (state = initialState, action = {}) => { : notification ), isPendingMarkNotificationAsRead: false, - notificationsCount: state.notificationsCount - 1, + notificationsCount: + state.notificationsCount && state.notificationsCount - 1, }; case MARK_NOTIFICATION_AS_READ.ERROR: return { @@ -126,6 +127,7 @@ export const notificationsReducer = (state = initialState, action = {}) => { ), isPendingRepoMarkAsRead: false, notificationsCount: + state.notificationsCount && state.notificationsCount - action.repoNotificationsCount, }; case MARK_REPO_AS_READ.ERROR: From f522c6bc7781864083418a858174d5026ed4f6c2 Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Thu, 28 Sep 2017 18:55:58 +0300 Subject: [PATCH 13/14] fix(events): remove destructuring --- src/auth/screens/events.screen.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/auth/screens/events.screen.js b/src/auth/screens/events.screen.js index 1981c822b..6b65ec063 100644 --- a/src/auth/screens/events.screen.js +++ b/src/auth/screens/events.screen.js @@ -83,9 +83,8 @@ class Events extends Component { } } - // eslint-disable-next-line no-undef - componentWillReceiveProps(user = nextProps) { - if (user.login && !this.props.user.login) { + componentWillReceiveProps(nextProps) { + if (nextProps.user.login && !this.props.user.login) { this.getUserEvents(nextProps); } } From fa12608d93d75f9700868ae5017aa3a4bf34494e Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Thu, 28 Sep 2017 21:41:01 +0300 Subject: [PATCH 14/14] refactor(events): remove destructuring --- src/auth/screens/events.screen.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/auth/screens/events.screen.js b/src/auth/screens/events.screen.js index 6b65ec063..152404c72 100644 --- a/src/auth/screens/events.screen.js +++ b/src/auth/screens/events.screen.js @@ -77,8 +77,8 @@ const styles = StyleSheet.create({ }); class Events extends Component { - componentDidMount({ user } = this.props) { - if (user.login) { + componentDidMount() { + if (this.props.user.login) { this.getUserEvents(); } }