diff --git a/src/dispatcher/index.js b/src/dispatcher/index.js index 58ecbee3c..cc846662c 100644 --- a/src/dispatcher/index.js +++ b/src/dispatcher/index.js @@ -13,6 +13,7 @@ import tracking from './tracking'; import server from './server'; import notifications from './notifications'; import plugins from './plugins'; +import user from './user'; import type {Logger} from '../fb-interfaces/Logger.js'; import type {Store} from '../reducers/index.js'; @@ -27,4 +28,5 @@ export default (store: Store, logger: Logger) => server, notifications, plugins, + user, ].forEach(fn => fn(store, logger)); diff --git a/src/dispatcher/user.js b/src/dispatcher/user.js new file mode 100644 index 000000000..f8b0974d1 --- /dev/null +++ b/src/dispatcher/user.js @@ -0,0 +1,27 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type {Store} from '../reducers/index.js'; +import type {Logger} from '../fb-interfaces/Logger.js'; +import {login} from '../reducers/user'; +import {getUser, logoutUser} from '../fb-stubs/user'; + +export default (store: Store, logger: Logger) => { + getUser() + .then(user => { + store.dispatch(login(user)); + }) + .catch(console.debug); + + let prevUserName = store.getState().user.name; + store.subscribe(() => { + if (prevUserName && !store.getState().user.name) { + logoutUser(); + } + prevUserName = store.getState().user.name; + }); +}; diff --git a/src/fb-stubs/user.js b/src/fb-stubs/user.js new file mode 100644 index 000000000..940551e46 --- /dev/null +++ b/src/fb-stubs/user.js @@ -0,0 +1,18 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +export function getUser() { + return Promise.reject(); +} + +export async function graphQLQuery(query: string) { + return Promise.reject(); +} + +export function logoutUser(): Promise { + return Promise.reject(); +} diff --git a/src/reducers/__tests__/user.node.js b/src/reducers/__tests__/user.node.js new file mode 100644 index 000000000..caad3e0bf --- /dev/null +++ b/src/reducers/__tests__/user.node.js @@ -0,0 +1,24 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import {default as reducer, login, logout} from '../user'; + +test('login', () => { + const userData = {username: 'Jane Doe'}; + const res = reducer({}, login(userData)); + expect(res).toEqual(userData); +}); + +test('logout', () => { + const res = reducer( + { + username: 'Jane Doe', + }, + logout(), + ); + expect(res).toEqual({}); +}); diff --git a/src/reducers/index.js b/src/reducers/index.js index 9e5e10c5f..ab63e0542 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -11,6 +11,7 @@ import connections from './connections.js'; import pluginStates from './pluginStates.js'; import notifications from './notifications.js'; import plugins from './plugins.js'; +import user from './user.js'; import {persistReducer} from 'redux-persist'; import storage from 'redux-persist/lib/storage/index.js'; @@ -35,6 +36,7 @@ import type { State as PluginsState, Action as PluginsAction, } from './plugins.js'; +import type {State as UserState, Action as UserAction} from './user.js'; import type {Store as ReduxStore} from 'redux'; type Actions = @@ -43,6 +45,7 @@ type Actions = | PluginStatesAction | NotificationsAction | PluginsAction + | UserAction | {|type: 'INIT'|}; export type State = {| @@ -51,6 +54,7 @@ export type State = {| pluginStates: PluginStatesState, notifications: NotificationsState, plugins: PluginsState, + user: UserState, |}; export type Store = ReduxStore; @@ -79,4 +83,11 @@ export default combineReducers<_, Actions>({ notifications, ), plugins, + user: persistReducer( + { + key: 'user', + storage, + }, + user, + ), }); diff --git a/src/reducers/user.js b/src/reducers/user.js new file mode 100644 index 000000000..93cc5f2fd --- /dev/null +++ b/src/reducers/user.js @@ -0,0 +1,51 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +export type User = { + name?: string, + profile_picture?: { + uri: string, + }, +}; + +export type State = User; + +export type Action = + | { + type: 'LOGIN', + payload: User, + } + | { + type: 'LOGOUT', + }; + +const INITIAL_STATE: State = {}; + +export default function reducer( + state: State = INITIAL_STATE, + action: Action, +): State { + if (action.type === 'LOGOUT') { + return {}; + } else if (action.type === 'LOGIN') { + return { + ...state, + ...action.payload, + }; + } else { + return state; + } +} + +export const login = (payload: User): Action => ({ + type: 'LOGIN', + payload, +}); + +export const logout = (): Action => ({ + type: 'LOGOUT', +});