1import * as Container from '../util/container' 2import * as NotificationsGen from '../actions/notifications-gen' 3import * as Tabs from '../constants/tabs' 4import * as Types from '../constants/types/notifications' 5import isEqual from 'lodash/isEqual' 6 7const initialState: Types.State = { 8 badgeVersion: -1, 9 desktopAppBadgeCount: 0, 10 keyState: new Map(), 11 mobileAppBadgeCount: 0, 12 navBadges: new Map(), 13 widgetBadge: 'regular', 14} 15 16const updateWidgetBadge = (draftState: Container.Draft<Types.State>) => { 17 let widgetBadge: Types.BadgeType = 'regular' 18 const {keyState} = draftState 19 if (keyState.get('outOfSpace')) { 20 widgetBadge = 'error' 21 } else if (keyState.get('kbfsUploading')) { 22 widgetBadge = 'uploading' 23 } 24 if (widgetBadge !== draftState.widgetBadge) { 25 draftState.widgetBadge = widgetBadge 26 } 27} 28 29export default Container.makeReducer<NotificationsGen.Actions, Types.State>(initialState, { 30 [NotificationsGen.resetStore]: () => initialState, 31 [NotificationsGen.setBadgeCounts]: (draftState, action) => { 32 const {counts} = action.payload 33 const chatCount = counts.get(Tabs.chatTab) 34 if (chatCount) { 35 draftState.mobileAppBadgeCount = chatCount 36 } 37 38 // desktopAppBadgeCount is the sum of badge counts on all tabs. What 39 // happens here is for each tab we deduct the old count from the 40 // current desktopAppBadgeCount, then add the new count into it. 41 // 42 // For example, assume following existing state: 43 // 1) the overall app badge has 12, i.e. state.desktopAppBadgeCount === 12; 44 // 2) and the FS tab count is 4, i.e. state.navBadges.get(Tabs.fsTab) === 4; 45 // Now we receive `{count: {[Tabs.fsTab]: 7}}` indicating that the 46 // new FS tab badge count should become 7. So we deduct 4 from 12 and 47 // add 7, and we'd get 15. 48 // 49 // This way the app badge count is always consistent with the badged 50 // tabs. 51 draftState.desktopAppBadgeCount = [...counts.entries()].reduce<number>( 52 (count, [k, v]) => count - (draftState.navBadges.get(k) || 0) + v, 53 draftState.desktopAppBadgeCount 54 ) 55 56 const navBadges = new Map([...draftState.navBadges, ...counts]) 57 if (!isEqual(navBadges, draftState.navBadges)) { 58 draftState.navBadges = navBadges 59 } 60 updateWidgetBadge(draftState) 61 }, 62 [NotificationsGen.badgeApp]: (draftState, action) => { 63 const {key, on} = action.payload 64 const {keyState} = draftState 65 keyState.set(key, on) 66 updateWidgetBadge(draftState) 67 }, 68}) 69