Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F32158984
redux-setup.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
redux-setup.js
View Options
// @flow
import
{
AppState
as
NativeAppState
,
Platform
,
Alert
}
from
'react-native'
;
import
Orientation
from
'react-native-orientation-locker'
;
import
{
createStore
,
applyMiddleware
,
type
Store
,
compose
}
from
'redux'
;
import
{
persistStore
,
persistReducer
}
from
'redux-persist'
;
import
thunk
from
'redux-thunk'
;
import
{
setDeviceTokenActionTypes
}
from
'lib/actions/device-actions'
;
import
{
logOutActionTypes
,
deleteAccountActionTypes
,
logInActionTypes
,
}
from
'lib/actions/user-actions'
;
import
baseReducer
from
'lib/reducers/master-reducer'
;
import
{
invalidSessionDowngrade
,
invalidSessionRecovery
,
}
from
'lib/shared/account-utils'
;
import
{
defaultEnabledApps
}
from
'lib/types/enabled-apps'
;
import
{
defaultCalendarFilters
}
from
'lib/types/filter-types'
;
import
type
{
Dispatch
,
BaseAction
}
from
'lib/types/redux-types'
;
import
type
{
SetSessionPayload
}
from
'lib/types/session-types'
;
import
{
defaultConnectionInfo
,
incrementalStateSyncActionType
,
}
from
'lib/types/socket-types'
;
import
{
updateTypes
}
from
'lib/types/update-types'
;
import
{
reduxLoggerMiddleware
}
from
'lib/utils/action-logger'
;
import
{
setNewSessionActionType
}
from
'lib/utils/action-utils'
;
import
{
defaultNavInfo
}
from
'../navigation/default-state'
;
import
{
getGlobalNavContext
}
from
'../navigation/icky-global'
;
import
{
activeMessageListSelector
}
from
'../navigation/nav-selectors'
;
import
{
defaultNotifPermissionAlertInfo
}
from
'../push/alerts'
;
import
{
reduceThreadIDsToNotifIDs
}
from
'../push/reducer'
;
import
reactotron
from
'../reactotron'
;
import
{
defaultDeviceCameraInfo
}
from
'../types/camera'
;
import
{
defaultConnectivityInfo
}
from
'../types/connectivity'
;
import
{
defaultGlobalThemeInfo
}
from
'../types/themes'
;
import
{
defaultURLPrefix
,
natNodeServer
,
setCustomServer
,
getDevServerHostname
,
}
from
'../utils/url-utils'
;
import
{
resetUserStateActionType
,
recordNotifPermissionAlertActionType
,
recordAndroidNotificationActionType
,
clearAndroidNotificationsActionType
,
rescindAndroidNotificationActionType
,
updateDimensionsActiveType
,
updateConnectivityActiveType
,
updateThemeInfoActionType
,
updateDeviceCameraInfoActionType
,
updateDeviceOrientationActionType
,
updateThreadLastNavigatedActionType
,
backgroundActionTypes
,
setReduxStateActionType
,
type
Action
,
}
from
'./action-types'
;
import
{
remoteReduxDevServerConfig
}
from
'./dev-tools'
;
import
{
defaultDimensionsInfo
}
from
'./dimensions-updater.react'
;
import
{
persistConfig
,
setPersistor
}
from
'./persist'
;
import
type
{
AppState
}
from
'./state-types'
;
const
defaultState
=
({
navInfo
:
defaultNavInfo
,
currentUserInfo
:
null
,
entryStore
:
{
entryInfos
:
{},
daysToEntries
:
{},
lastUserInteractionCalendar
:
0
,
},
threadStore
:
{
threadInfos
:
{},
},
userStore
:
{
userInfos
:
{},
inconsistencyReports
:
[],
},
messageStore
:
{
messages
:
{},
threads
:
{},
local
:
{},
currentAsOf
:
0
,
},
updatesCurrentAsOf
:
0
,
loadingStatuses
:
{},
calendarFilters
:
defaultCalendarFilters
,
cookie
:
null
,
deviceToken
:
null
,
dataLoaded
:
false
,
urlPrefix
:
defaultURLPrefix
,
customServer
:
natNodeServer
,
threadIDsToNotifIDs
:
{},
notifPermissionAlertInfo
:
defaultNotifPermissionAlertInfo
,
connection
:
defaultConnectionInfo
(
Platform
.
OS
),
watchedThreadIDs
:
[],
lifecycleState
:
'active'
,
enabledApps
:
defaultEnabledApps
,
reportStore
:
{
enabledReports
:
{
crashReports
:
__DEV__
,
inconsistencyReports
:
__DEV__
,
mediaReports
:
__DEV__
,
},
queuedReports
:
[],
},
nextLocalID
:
0
,
_persist
:
null
,
dimensions
:
defaultDimensionsInfo
,
connectivity
:
defaultConnectivityInfo
,
globalThemeInfo
:
defaultGlobalThemeInfo
,
deviceCameraInfo
:
defaultDeviceCameraInfo
,
deviceOrientation
:
Orientation
.
getInitialOrientation
(),
frozen
:
false
,
}
:
AppState
);
function
reducer
(
state
:
AppState
=
defaultState
,
action
:
Action
)
{
if
(
action
.
type
===
setReduxStateActionType
)
{
return
action
.
payload
.
state
;
}
if
(
(
action
.
type
===
setNewSessionActionType
&&
invalidSessionDowngrade
(
state
,
action
.
payload
.
sessionChange
.
currentUserInfo
,
action
.
payload
.
preRequestUserState
,
))
||
(
action
.
type
===
logOutActionTypes
.
success
&&
invalidSessionDowngrade
(
state
,
action
.
payload
.
currentUserInfo
,
action
.
payload
.
preRequestUserState
,
))
||
(
action
.
type
===
deleteAccountActionTypes
.
success
&&
invalidSessionDowngrade
(
state
,
action
.
payload
.
currentUserInfo
,
action
.
payload
.
preRequestUserState
,
))
)
{
return
state
;
}
if
(
(
action
.
type
===
setNewSessionActionType
&&
action
.
payload
.
sessionChange
.
currentUserInfo
&&
invalidSessionRecovery
(
state
,
action
.
payload
.
sessionChange
.
currentUserInfo
,
action
.
payload
.
source
,
))
||
(
action
.
type
===
logInActionTypes
.
success
&&
invalidSessionRecovery
(
state
,
action
.
payload
.
currentUserInfo
,
action
.
payload
.
source
,
))
)
{
return
state
;
}
const
threadIDsToNotifIDs
=
reduceThreadIDsToNotifIDs
(
state
.
threadIDsToNotifIDs
,
action
,
);
state
=
{
...
state
,
threadIDsToNotifIDs
};
if
(
action
.
type
===
recordAndroidNotificationActionType
||
action
.
type
===
clearAndroidNotificationsActionType
||
action
.
type
===
rescindAndroidNotificationActionType
)
{
return
state
;
}
if
(
action
.
type
===
setCustomServer
)
{
return
{
...
state
,
customServer
:
action
.
payload
,
};
}
else
if
(
action
.
type
===
recordNotifPermissionAlertActionType
)
{
return
{
...
state
,
notifPermissionAlertInfo
:
{
totalAlerts
:
state
.
notifPermissionAlertInfo
.
totalAlerts
+
1
,
lastAlertTime
:
action
.
payload
.
time
,
},
};
}
else
if
(
action
.
type
===
resetUserStateActionType
)
{
const
cookie
=
state
.
cookie
&&
state
.
cookie
.
startsWith
(
'anonymous='
)
?
state
.
cookie
:
null
;
const
currentUserInfo
=
state
.
currentUserInfo
&&
state
.
currentUserInfo
.
anonymous
?
state
.
currentUserInfo
:
null
;
return
{
...
state
,
currentUserInfo
,
cookie
,
};
}
else
if
(
action
.
type
===
updateDimensionsActiveType
)
{
return
{
...
state
,
dimensions
:
{
...
state
.
dimensions
,
...
action
.
payload
,
},
};
}
else
if
(
action
.
type
===
updateConnectivityActiveType
)
{
return
{
...
state
,
connectivity
:
action
.
payload
,
};
}
else
if
(
action
.
type
===
updateThemeInfoActionType
)
{
return
{
...
state
,
globalThemeInfo
:
{
...
state
.
globalThemeInfo
,
...
action
.
payload
,
},
};
}
else
if
(
action
.
type
===
updateDeviceCameraInfoActionType
)
{
return
{
...
state
,
deviceCameraInfo
:
{
...
state
.
deviceCameraInfo
,
...
action
.
payload
,
},
};
}
else
if
(
action
.
type
===
updateDeviceOrientationActionType
)
{
return
{
...
state
,
deviceOrientation
:
action
.
payload
,
};
}
else
if
(
action
.
type
===
setDeviceTokenActionTypes
.
success
)
{
return
{
...
state
,
deviceToken
:
action
.
payload
,
};
}
else
if
(
action
.
type
===
updateThreadLastNavigatedActionType
)
{
const
{
threadID
,
time
}
=
action
.
payload
;
if
(
state
.
messageStore
.
threads
[
threadID
])
{
state
=
{
...
state
,
messageStore
:
{
...
state
.
messageStore
,
threads
:
{
...
state
.
messageStore
.
threads
,
[
threadID
]
:
{
...
state
.
messageStore
.
threads
[
threadID
],
lastNavigatedTo
:
time
,
},
},
},
};
}
return
state
;
}
if
(
action
.
type
===
setNewSessionActionType
)
{
sessionInvalidationAlert
(
action
.
payload
);
state
=
{
...
state
,
cookie
:
action
.
payload
.
sessionChange
.
cookie
,
};
}
else
if
(
action
.
type
===
incrementalStateSyncActionType
)
{
let
wipeDeviceToken
=
false
;
for
(
const
update
of
action
.
payload
.
updatesResult
.
newUpdates
)
{
if
(
update
.
type
===
updateTypes
.
BAD_DEVICE_TOKEN
&&
update
.
deviceToken
===
state
.
deviceToken
)
{
wipeDeviceToken
=
true
;
break
;
}
}
if
(
wipeDeviceToken
)
{
state
=
{
...
state
,
deviceToken
:
null
,
};
}
}
state
=
baseReducer
(
state
,
(
action
:
BaseAction
));
return
fixUnreadActiveThread
(
state
,
action
);
}
function
sessionInvalidationAlert
(
payload
:
SetSessionPayload
)
{
if
(
!
payload
.
sessionChange
.
cookieInvalidated
||
!
payload
.
preRequestUserState
||
!
payload
.
preRequestUserState
.
currentUserInfo
||
payload
.
preRequestUserState
.
currentUserInfo
.
anonymous
)
{
return
;
}
if
(
payload
.
error
===
'client_version_unsupported'
)
{
const
app
=
Platform
.
select
({
ios
:
'App Store'
,
android
:
'Play Store'
,
});
Alert
.
alert
(
'App out of date'
,
"Your app version is pretty old, and the server doesn't know how to "
+
`speak to it anymore. Please use the
${
app
}
app to update!`
,
[{
text
:
'OK'
}],
{
cancelable
:
true
},
);
}
else
{
Alert
.
alert
(
'Session invalidated'
,
"We're sorry, but your session was invalidated by the server. "
+
'Please log in again.'
,
[{
text
:
'OK'
}],
{
cancelable
:
true
},
);
}
}
// Makes sure a currently focused thread is never unread. Note that we consider
// a backgrounded NativeAppState to actually be active if it last changed to
// inactive more than 10 seconds ago. This is because there is a delay when
// NativeAppState is updating in response to a foreground, and actions don't get
// processed more than 10 seconds after a backgrounding anyways. However we
// don't consider this for action types that can be expected to happen while the
// app is backgrounded.
function
fixUnreadActiveThread
(
state
:
AppState
,
action
:
*
)
:
AppState
{
const
navContext
=
getGlobalNavContext
();
const
activeThread
=
activeMessageListSelector
(
navContext
);
if
(
activeThread
&&
(
NativeAppState
.
currentState
===
'active'
||
(
appLastBecameInactive
+
10000
<
Date
.
now
()
&&
!
backgroundActionTypes
.
has
(
action
.
type
)))
&&
state
.
threadStore
.
threadInfos
[
activeThread
]
&&
state
.
threadStore
.
threadInfos
[
activeThread
].
currentUser
.
unread
)
{
state
=
{
...
state
,
threadStore
:
{
...
state
.
threadStore
,
threadInfos
:
{
...
state
.
threadStore
.
threadInfos
,
[
activeThread
]
:
{
...
state
.
threadStore
.
threadInfos
[
activeThread
],
currentUser
:
{
...
state
.
threadStore
.
threadInfos
[
activeThread
].
currentUser
,
unread
:
false
,
},
},
},
},
};
}
return
state
;
}
let
appLastBecameInactive
=
0
;
function
appBecameInactive
()
{
appLastBecameInactive
=
Date
.
now
();
}
const
middlewares
=
[
thunk
,
reduxLoggerMiddleware
];
if
(
__DEV__
)
{
const
createDebugger
=
require
(
'redux-flipper'
).
default
;
middlewares
.
push
(
createDebugger
());
}
const
middleware
=
applyMiddleware
(...
middlewares
);
let
composeFunc
=
compose
;
if
(
__DEV__
&&
global
.
HermesInternal
)
{
const
{
composeWithDevTools
}
=
require
(
'remote-redux-devtools/src'
);
composeFunc
=
composeWithDevTools
({
name
:
'Redux'
,
hostname
:
getDevServerHostname
(),
...
remoteReduxDevServerConfig
,
});
}
else
if
(
global
.
__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
)
{
composeFunc
=
global
.
__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
({
name
:
'Redux'
,
});
}
let
enhancers
;
if
(
reactotron
)
{
enhancers
=
composeFunc
(
middleware
,
reactotron
.
createEnhancer
());
}
else
{
enhancers
=
composeFunc
(
middleware
);
}
const
store
:
Store
<
AppState
,
*>
=
createStore
(
persistReducer
(
persistConfig
,
reducer
),
defaultState
,
enhancers
,
);
const
persistor
=
persistStore
(
store
);
setPersistor
(
persistor
);
const
unsafeDispatch
:
any
=
store
.
dispatch
;
const
dispatch
:
Dispatch
=
unsafeDispatch
;
export
{
store
,
dispatch
,
appBecameInactive
};
File Metadata
Details
Attached
Mime Type
text/x-java
Expires
Sun, Dec 7, 4:24 PM (6 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5839549
Default Alt Text
redux-setup.js (11 KB)
Attached To
Mode
rCOMM Comm
Attached
Detach File
Event Timeline
Log In to Comment