Changeset View
Changeset View
Standalone View
Standalone View
native/data/sqlite-context-provider.js
// @flow | // @flow | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { Alert } from 'react-native'; | import { Alert } from 'react-native'; | ||||
import ExitApp from 'react-native-exit-app'; | import ExitApp from 'react-native-exit-app'; | ||||
import { useDispatch } from 'react-redux'; | import { useDispatch } from 'react-redux'; | ||||
import { setMessageStoreMessages } from 'lib/actions/message-actions.js'; | import { setMessageStoreMessages } from 'lib/actions/message-actions.js'; | ||||
import { setThreadStoreActionType } from 'lib/actions/thread-actions'; | import { setThreadStoreActionType } from 'lib/actions/thread-actions'; | ||||
import { isStaff } from 'lib/shared/user-utils'; | |||||
import { loginActionSources } from 'lib/types/account-types'; | import { loginActionSources } from 'lib/types/account-types'; | ||||
import { fetchNewCookieFromNativeCredentials } from 'lib/utils/action-utils'; | import { fetchNewCookieFromNativeCredentials } from 'lib/utils/action-utils'; | ||||
import { getMessageForException } from 'lib/utils/errors'; | import { getMessageForException } from 'lib/utils/errors'; | ||||
import { convertClientDBThreadInfosToRawThreadInfos } from 'lib/utils/thread-ops-utils'; | import { convertClientDBThreadInfosToRawThreadInfos } from 'lib/utils/thread-ops-utils'; | ||||
import { commCoreModule } from '../native-modules'; | import { commCoreModule } from '../native-modules'; | ||||
import { useSelector } from '../redux/redux-utils'; | import { useSelector } from '../redux/redux-utils'; | ||||
import { useStaffCanSee } from '../utils/staff-utils'; | |||||
import { SQLiteContext } from './sqlite-context'; | import { SQLiteContext } from './sqlite-context'; | ||||
type Props = { | type Props = { | ||||
+children: React.Node, | +children: React.Node, | ||||
}; | }; | ||||
function SQLiteContextProvider(props: Props): React.Node { | function SQLiteContextProvider(props: Props): React.Node { | ||||
const [storeLoaded, setStoreLoaded] = React.useState<boolean>(false); | const [storeLoaded, setStoreLoaded] = React.useState<boolean>(false); | ||||
const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
const rehydrateConcluded = useSelector( | const rehydrateConcluded = useSelector( | ||||
state => !!(state._persist && state._persist.rehydrated), | state => !!(state._persist && state._persist.rehydrated), | ||||
); | ); | ||||
const cookie = useSelector(state => state.cookie); | const cookie = useSelector(state => state.cookie); | ||||
const urlPrefix = useSelector(state => state.urlPrefix); | const urlPrefix = useSelector(state => state.urlPrefix); | ||||
const viewerID = useSelector( | const staffCanSee = useStaffCanSee(); | ||||
state => state.currentUserInfo && state.currentUserInfo.id, | |||||
); | |||||
React.useEffect(() => { | React.useEffect(() => { | ||||
if (storeLoaded || !rehydrateConcluded) { | if (storeLoaded || !rehydrateConcluded) { | ||||
return; | return; | ||||
} | } | ||||
(async () => { | (async () => { | ||||
try { | try { | ||||
const threads = await commCoreModule.getAllThreads(); | const threads = await commCoreModule.getAllThreads(); | ||||
const threadInfosFromDB = convertClientDBThreadInfosToRawThreadInfos( | const threadInfosFromDB = convertClientDBThreadInfosToRawThreadInfos( | ||||
threads, | threads, | ||||
); | ); | ||||
dispatch({ | dispatch({ | ||||
type: setThreadStoreActionType, | type: setThreadStoreActionType, | ||||
payload: { threadInfos: threadInfosFromDB }, | payload: { threadInfos: threadInfosFromDB }, | ||||
}); | }); | ||||
const messages = await commCoreModule.getAllMessages(); | const messages = await commCoreModule.getAllMessages(); | ||||
dispatch({ | dispatch({ | ||||
type: setMessageStoreMessages, | type: setMessageStoreMessages, | ||||
payload: messages, | payload: messages, | ||||
}); | }); | ||||
setStoreLoaded(true); | setStoreLoaded(true); | ||||
} catch (setStoreException) { | } catch (setStoreException) { | ||||
if (__DEV__ || (viewerID && isStaff(viewerID))) { | if (staffCanSee) { | ||||
Alert.alert( | Alert.alert( | ||||
`Error setting threadStore or messageStore: ${ | `Error setting threadStore or messageStore: ${ | ||||
getMessageForException(setStoreException) ?? | getMessageForException(setStoreException) ?? | ||||
'{no exception message}' | '{no exception message}' | ||||
}`, | }`, | ||||
); | ); | ||||
} | } | ||||
try { | try { | ||||
await fetchNewCookieFromNativeCredentials( | await fetchNewCookieFromNativeCredentials( | ||||
dispatch, | dispatch, | ||||
cookie, | cookie, | ||||
urlPrefix, | urlPrefix, | ||||
loginActionSources.sqliteLoadFailure, | loginActionSources.sqliteLoadFailure, | ||||
); | ); | ||||
setStoreLoaded(true); | setStoreLoaded(true); | ||||
} catch (fetchCookieException) { | } catch (fetchCookieException) { | ||||
if (__DEV__ || (viewerID && isStaff(viewerID))) { | if (staffCanSee) { | ||||
Alert.alert( | Alert.alert( | ||||
`Error fetching new cookie from native credentials: ${ | `Error fetching new cookie from native credentials: ${ | ||||
getMessageForException(fetchCookieException) ?? | getMessageForException(fetchCookieException) ?? | ||||
'{no exception message}' | '{no exception message}' | ||||
}. Please kill the app.`, | }. Please kill the app.`, | ||||
); | ); | ||||
} else { | } else { | ||||
ExitApp.exitApp(); | ExitApp.exitApp(); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
})(); | })(); | ||||
}, [storeLoaded, urlPrefix, rehydrateConcluded, cookie, dispatch, viewerID]); | }, [ | ||||
cookie, | |||||
dispatch, | |||||
rehydrateConcluded, | |||||
staffCanSee, | |||||
storeLoaded, | |||||
urlPrefix, | |||||
]); | |||||
const contextValue = React.useMemo( | const contextValue = React.useMemo( | ||||
() => ({ | () => ({ | ||||
storeLoaded, | storeLoaded, | ||||
}), | }), | ||||
[storeLoaded], | [storeLoaded], | ||||
); | ); | ||||
return ( | return ( | ||||
<SQLiteContext.Provider value={contextValue}> | <SQLiteContext.Provider value={contextValue}> | ||||
{props.children} | {props.children} | ||||
</SQLiteContext.Provider> | </SQLiteContext.Provider> | ||||
); | ); | ||||
} | } | ||||
export { SQLiteContextProvider }; | export { SQLiteContextProvider }; |