Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
thalia
ThaliApp
Commits
34de57b1
Verified
Commit
34de57b1
authored
Aug 10, 2018
by
Sébastiaan Versteeg
Browse files
Rename login saga to session saga and create initialising sequence with splashscreen
parent
7602852f
Changes
19
Hide whitespace changes
Inline
Side-by-side
__tests__/actions/__snapshots__/
logi
n.spec.js.snap
→
__tests__/actions/__snapshots__/
sessio
n.spec.js.snap
View file @
34de57b1
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`
logi
n actions should create an action for a successful login 1`] = `
exports[`
sessio
n actions should create an action for a successful login 1`] = `
Object {
"payload": Object {
"token": "token",
"username": "username",
},
"type": "
LOGI
N_SUCCESS",
"type": "
SESSIO
N_SUCCESS",
}
`;
exports[`
logi
n actions should create an action for a successful user profile load 1`] = `
exports[`
sessio
n actions should create an action for a successful user profile load 1`] = `
Object {
"payload": Object {
"displayName": "displayName",
"photo": "photo",
},
"type": "
LOGI
N_PROFILE_SUCCESS",
"type": "
SESSIO
N_PROFILE_SUCCESS",
}
`;
exports[`login actions should create an action to load the user profile 1`] = `
exports[`session actions should create an action to init the session 1`] = `
Object {
"type": "SESSION_INIT",
}
`;
exports[`session actions should create an action to load the user profile 1`] = `
Object {
"payload": Object {
"token": "token",
},
"type": "
LOGI
N_PROFILE",
"type": "
SESSIO
N_PROFILE",
}
`;
exports[`
logi
n actions should create an action to log the user in 1`] = `
exports[`
sessio
n actions should create an action to log the user in 1`] = `
Object {
"payload": Object {
"pass": "password",
"user": "username",
},
"type": "LOGIN_LOGIN",
"type": "SESSION_LOGIN",
}
`;
exports[`session actions should create an action to log the user out 1`] = `
Object {
"type": "SESSION_LOGOUT",
}
`;
exports[`
logi
n actions should create an action to
log the user out
1`] = `
exports[`
sessio
n actions should create an action to
notify invalid token
1`] = `
Object {
"type": "
LOGIN_LOGOUT
",
"type": "
SESSION_TOKEN_INVALID
",
}
`;
__tests__/actions/
logi
n.spec.js
→
__tests__/actions/
sessio
n.spec.js
View file @
34de57b1
import
*
as
actions
from
'
../../app/actions/login
'
;
describe
(
'
login actions
'
,
()
=>
{
it
(
'
should expose the login actions
'
,
()
=>
{
expect
(
actions
.
SUCCESS
).
toEqual
(
'
LOGIN_SUCCESS
'
);
expect
(
actions
.
LOGIN
).
toEqual
(
'
LOGIN_LOGIN
'
);
expect
(
actions
.
LOGOUT
).
toEqual
(
'
LOGIN_LOGOUT
'
);
expect
(
actions
.
PROFILE
).
toEqual
(
'
LOGIN_PROFILE
'
);
expect
(
actions
.
PROFILE_SUCCESS
).
toEqual
(
'
LOGIN_PROFILE_SUCCESS
'
);
import
*
as
actions
from
'
../../app/actions/session
'
;
describe
(
'
session actions
'
,
()
=>
{
it
(
'
should expose the session actions
'
,
()
=>
{
expect
(
actions
.
INIT
).
toEqual
(
'
SESSION_INIT
'
);
expect
(
actions
.
SUCCESS
).
toEqual
(
'
SESSION_SUCCESS
'
);
expect
(
actions
.
LOGIN
).
toEqual
(
'
SESSION_LOGIN
'
);
expect
(
actions
.
TOKEN_INVALID
).
toEqual
(
'
SESSION_TOKEN_INVALID
'
);
expect
(
actions
.
LOGOUT
).
toEqual
(
'
SESSION_LOGOUT
'
);
expect
(
actions
.
PROFILE
).
toEqual
(
'
SESSION_PROFILE
'
);
expect
(
actions
.
PROFILE_SUCCESS
).
toEqual
(
'
SESSION_PROFILE_SUCCESS
'
);
});
it
(
'
should create an action to init the session
'
,
()
=>
{
expect
(
actions
.
init
()).
toMatchSnapshot
();
});
it
(
'
should create an action to notify invalid token
'
,
()
=>
{
expect
(
actions
.
tokenInvalid
()).
toMatchSnapshot
();
});
it
(
'
should create an action to log the user in
'
,
()
=>
{
...
...
__tests__/sagas/deepLinking.spec.js
View file @
34de57b1
...
...
@@ -6,7 +6,7 @@ import * as deepLinkingActions from '../../app/actions/deepLinking';
import
{
url
as
siteURL
,
apiRequest
,
loggedInSelector
}
from
'
../../app/utils/url
'
;
import
*
as
navigationActions
from
'
../../app/actions/navigation
'
;
import
*
as
eventActions
from
'
../../app/actions/event
'
;
import
*
as
loginActions
from
'
../../app/actions/
logi
n
'
;
import
*
as
loginActions
from
'
../../app/actions/
sessio
n
'
;
import
*
as
pizzaActions
from
'
../../app/actions/pizza
'
;
import
{
EVENT_LIST_SCENE
}
from
'
../../app/ui/components/navigator/scenes
'
;
...
...
__tests__/sagas/
logi
n.spec.js
→
__tests__/sagas/
sessio
n.spec.js
View file @
34de57b1
...
...
@@ -5,9 +5,11 @@ import Snackbar from 'react-native-snackbar';
import
{
AsyncStorage
}
from
'
react-native
'
;
import
{
Sentry
}
from
'
react-native-sentry
'
;
import
loginSaga
,
{
DISPLAYNAMEKEY
,
PHOTOKEY
,
TOKENKEY
,
USERNAMEKEY
}
from
'
../../app/sagas/login
'
;
import
sessionSaga
,
{
DISPLAYNAMEKEY
,
PHOTOKEY
,
TOKENKEY
,
USERNAMEKEY
}
from
'
../../app/sagas/session
'
;
import
{
apiRequest
}
from
'
../../app/utils/url
'
;
import
*
as
logi
nActions
from
'
../../app/actions/
logi
n
'
;
import
*
as
sessio
nActions
from
'
../../app/actions/
sessio
n
'
;
import
*
as
pushNotificationsActions
from
'
../../app/actions/pushNotifications
'
;
jest
.
mock
(
'
react-native-snackbar
'
,
()
=>
({
...
...
@@ -35,48 +37,49 @@ jest.mock('react-native-sentry', () => ({
},
}));
describe
(
'
logi
n saga
'
,
()
=>
{
describe
(
'
sessio
n saga
'
,
()
=>
{
const
error
=
new
Error
(
'
error
'
);
describe
(
'
logging in
'
,
()
=>
{
it
(
'
should show a snackbar on start
'
,
()
=>
expectSaga
(
logi
nSaga
)
.
dispatch
(
logi
nActions
.
login
(
'
username
'
,
'
password
'
))
it
(
'
should show a snackbar on start
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
dispatch
(
sessio
nActions
.
login
(
'
username
'
,
'
password
'
))
.
silentRun
()
.
then
(()
=>
{
expect
(
Snackbar
.
show
).
toBeCalledWith
(
{
title
:
'
Logging in
'
,
duration
:
Snackbar
.
LENGTH_INDEFINITE
});
{
title
:
'
Logging in
'
,
duration
:
Snackbar
.
LENGTH_INDEFINITE
},
);
}));
it
(
'
should put the result data when the request succeeds
'
,
()
=>
expectSaga
(
logi
nSaga
)
it
(
'
should put the result data when the request succeeds
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
provide
([
[
matchers
.
call
.
like
({
fn
:
apiRequest
,
args
:
[
'
token-auth
'
]
}),
{
token
:
'
abc123
'
}],
[
matchers
.
call
.
like
({
fn
:
Sentry
.
setUserContext
}),
{}],
])
.
put
(
logi
nActions
.
success
(
'
username
'
,
'
abc123
'
))
.
put
(
logi
nActions
.
profile
(
'
abc123
'
))
.
dispatch
(
logi
nActions
.
login
(
'
username
'
,
'
password
'
))
.
put
(
sessio
nActions
.
success
(
'
username
'
,
'
abc123
'
))
.
put
(
sessio
nActions
.
profile
(
'
abc123
'
))
.
dispatch
(
sessio
nActions
.
login
(
'
username
'
,
'
password
'
))
.
silentRun
());
it
(
'
should show a snackbar when the request succeeds
'
,
()
=>
expectSaga
(
logi
nSaga
)
it
(
'
should show a snackbar when the request succeeds
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
provide
([
[
matchers
.
call
.
like
({
fn
:
apiRequest
,
args
:
[
'
token-auth
'
]
}),
{
token
:
'
abc123
'
}],
[
matchers
.
call
.
like
({
fn
:
Sentry
.
setUserContext
}),
{}],
])
.
dispatch
(
logi
nActions
.
login
(
'
username
'
,
'
password
'
))
.
dispatch
(
sessio
nActions
.
login
(
'
username
'
,
'
password
'
))
.
silentRun
()
.
then
(()
=>
{
expect
(
Snackbar
.
dismiss
).
toBeCalled
();
expect
(
Snackbar
.
show
).
toBeCalledWith
(
{
title
:
'
Login successful
'
});
{
title
:
'
Login successful
'
},
);
}));
it
(
'
should save the token in the AsyncStorage when the request succeeds
'
,
()
=>
expectSaga
(
loginSaga
)
it
(
'
should save the token in the AsyncStorage when the request succeeds
'
,
()
=>
expectSaga
(
sessionSaga
)
.
provide
([
[
matchers
.
call
.
like
({
fn
:
apiRequest
,
args
:
[
'
token-auth
'
]
}),
{
token
:
'
abc123
'
}],
[
matchers
.
call
.
like
({
fn
:
Sentry
.
setUserContext
}),
{}],
])
.
dispatch
(
logi
nActions
.
login
(
'
username
'
,
'
password
'
))
.
dispatch
(
sessio
nActions
.
login
(
'
username
'
,
'
password
'
))
.
silentRun
()
.
then
(()
=>
{
expect
(
AsyncStorage
.
multiSet
).
toBeCalledWith
([
...
...
@@ -85,20 +88,21 @@ describe('login saga', () => {
]);
}));
it
(
'
should show a snackbar when the request fails
'
,
()
=>
expectSaga
(
logi
nSaga
)
it
(
'
should show a snackbar when the request fails
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
provide
([
[
matchers
.
call
.
fn
(
apiRequest
),
throwError
(
error
)],
])
.
dispatch
(
logi
nActions
.
login
(
'
username
'
,
'
password
'
))
.
dispatch
(
sessio
nActions
.
login
(
'
username
'
,
'
password
'
))
.
silentRun
()
.
then
(()
=>
{
expect
(
Snackbar
.
dismiss
).
toBeCalled
();
expect
(
Snackbar
.
show
).
toBeCalledWith
(
{
title
:
'
Login failed
'
});
{
title
:
'
Login failed
'
},
);
}));
it
(
'
should do a POST request
'
,
()
=>
expectSaga
(
logi
nSaga
)
.
dispatch
(
logi
nActions
.
login
(
'
username
'
,
'
password
'
))
it
(
'
should do a POST request
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
dispatch
(
sessio
nActions
.
login
(
'
username
'
,
'
password
'
))
.
silentRun
()
.
then
(()
=>
{
expect
(
apiRequest
).
toBeCalledWith
(
'
token-auth
'
,
{
...
...
@@ -113,29 +117,30 @@ describe('login saga', () => {
});
describe
(
'
logging out
'
,
()
=>
{
it
(
'
should remove the token from the AsyncStorage
'
,
()
=>
expectSaga
(
logi
nSaga
)
.
dispatch
(
logi
nActions
.
logout
())
it
(
'
should remove the token from the AsyncStorage
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
dispatch
(
sessio
nActions
.
logout
())
.
silentRun
()
.
then
(()
=>
{
expect
(
AsyncStorage
.
multiRemove
).
toBeCalledWith
([
USERNAMEKEY
,
TOKENKEY
]);
}));
it
(
'
should put a push notification invalidation action
'
,
()
=>
expectSaga
(
logi
nSaga
)
it
(
'
should put a push notification invalidation action
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
put
(
pushNotificationsActions
.
invalidate
())
.
dispatch
(
logi
nActions
.
logout
())
.
dispatch
(
sessio
nActions
.
logout
())
.
silentRun
());
it
(
'
should remove the token from the AsyncStorage
'
,
()
=>
expectSaga
(
logi
nSaga
)
.
dispatch
(
logi
nActions
.
logout
())
it
(
'
should remove the token from the AsyncStorage
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
dispatch
(
sessio
nActions
.
logout
())
.
silentRun
()
.
then
(()
=>
{
expect
(
Snackbar
.
show
).
toBeCalledWith
(
{
title
:
'
Logout successful
'
});
{
title
:
'
Logout successful
'
},
);
}));
});
describe
(
'
getting profile
'
,
()
=>
{
it
(
'
should put the result data when the request succeeds
'
,
()
=>
expectSaga
(
logi
nSaga
)
it
(
'
should put the result data when the request succeeds
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
provide
([
[
matchers
.
call
.
like
({
fn
:
apiRequest
,
args
:
[
'
members/me
'
]
}),
{
display_name
:
'
Johnny Test
'
,
...
...
@@ -144,11 +149,11 @@ describe('login saga', () => {
},
}],
])
.
put
(
logi
nActions
.
profileSuccess
(
'
Johnny Test
'
,
'
http://example.org/photo.png
'
))
.
dispatch
(
logi
nActions
.
profile
(
'
abc123
'
))
.
put
(
sessio
nActions
.
profileSuccess
(
'
Johnny Test
'
,
'
http://example.org/photo.png
'
))
.
dispatch
(
sessio
nActions
.
profile
(
'
abc123
'
))
.
silentRun
());
it
(
'
should save the token in the AsyncStorage when the request succeeds
'
,
()
=>
expectSaga
(
logi
nSaga
)
it
(
'
should save the token in the AsyncStorage when the request succeeds
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
provide
([
[
matchers
.
call
.
like
({
fn
:
apiRequest
,
args
:
[
'
members/me
'
]
}),
{
display_name
:
'
Johnny Test
'
,
...
...
@@ -157,7 +162,7 @@ describe('login saga', () => {
},
}],
])
.
dispatch
(
logi
nActions
.
profile
(
'
abc123
'
))
.
dispatch
(
sessio
nActions
.
profile
(
'
abc123
'
))
.
silentRun
()
.
then
(()
=>
{
expect
(
AsyncStorage
.
multiSet
).
toBeCalledWith
([
...
...
@@ -166,15 +171,15 @@ describe('login saga', () => {
]);
}));
it
(
'
should not care about errors
'
,
()
=>
expectSaga
(
logi
nSaga
)
it
(
'
should not care about errors
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
provide
([
[
matchers
.
call
.
fn
(
apiRequest
),
throwError
(
error
)],
])
.
dispatch
(
logi
nActions
.
profile
(
'
token
'
))
.
dispatch
(
sessio
nActions
.
profile
(
'
token
'
))
.
silentRun
());
it
(
'
should do a GET request
'
,
()
=>
expectSaga
(
logi
nSaga
)
.
dispatch
(
logi
nActions
.
profile
(
'
abc123
'
))
it
(
'
should do a GET request
'
,
()
=>
expectSaga
(
sessio
nSaga
)
.
dispatch
(
sessio
nActions
.
profile
(
'
abc123
'
))
.
silentRun
()
.
then
(()
=>
{
expect
(
apiRequest
).
toBeCalledWith
(
'
members/me
'
,
{
...
...
__tests__/ui/components/navigator/ReduxNavigator.spec.js
View file @
34de57b1
...
...
@@ -4,12 +4,13 @@ import configureStore from 'redux-mock-store';
import
renderer
from
'
react-test-renderer
'
;
import
ReduxNavigator
from
'
../../../../app/ui/components/navigator/ReduxNavigator
'
;
import
reducer
from
'
../../../../app/reducers
'
;
import
{
LOGIN_SCENE
}
from
'
../../../../app/ui/components/navigator/scenes
'
;
describe
(
'
ReduxNavigator component
'
,
()
=>
{
const
mockStore
=
configureStore
(
reducer
);
const
initialState
=
{
navigation
:
{
currentScene
:
'
home
'
,
currentScene
:
LOGIN_SCENE
,
previousScenes
:
[],
drawerOpen
:
false
,
},
...
...
@@ -18,8 +19,12 @@ describe('ReduxNavigator component', () => {
it
(
'
renders correctly
'
,
()
=>
{
const
tree
=
renderer
.
create
(
<
Provider
store
=
{
store
}
><
ReduxNavigator
/><
/Provider>
)
.
create
(
<
Provider
store
=
{
store
}
>
<
ReduxNavigator
/>
<
/Provider>
,
)
.
toJSON
();
expect
(
tree
).
toMatchSnapshot
();
});
});
\ No newline at end of file
});
app/actions/
logi
n.js
→
app/actions/
sessio
n.js
View file @
34de57b1
export
const
LOGIN
=
'
LOGIN_LOGIN
'
;
export
const
SUCCESS
=
'
LOGIN_SUCCESS
'
;
export
const
LOGOUT
=
'
LOGIN_LOGOUT
'
;
export
const
TOKEN_INVALID
=
'
LOGIN_TOKEN_INVALID
'
;
export
const
PROFILE
=
'
LOGIN_PROFILE
'
;
export
const
PROFILE_SUCCESS
=
'
LOGIN_PROFILE_SUCCESS
'
;
export
const
LOGIN
=
'
SESSION_LOGIN
'
;
export
const
INIT
=
'
SESSION_INIT
'
;
export
const
SUCCESS
=
'
SESSION_SUCCESS
'
;
export
const
LOGOUT
=
'
SESSION_LOGOUT
'
;
export
const
TOKEN_INVALID
=
'
SESSION_TOKEN_INVALID
'
;
export
const
PROFILE
=
'
SESSION_PROFILE
'
;
export
const
PROFILE_SUCCESS
=
'
SESSION_PROFILE_SUCCESS
'
;
export
function
success
(
username
,
token
)
{
return
{
type
:
SUCCESS
,
payload
:
{
username
,
token
}
};
...
...
@@ -13,6 +14,10 @@ export function login(user, pass) {
return
{
type
:
LOGIN
,
payload
:
{
user
,
pass
}
};
}
export
function
init
()
{
return
{
type
:
INIT
};
}
export
function
logout
()
{
return
{
type
:
LOGOUT
};
}
...
...
app/app.js
View file @
34de57b1
import
React
,
{
Component
}
from
'
react
'
;
import
{
AsyncStorage
,
Linking
,
Platform
}
from
'
react-native
'
;
import
{
Linking
,
Platform
}
from
'
react-native
'
;
import
{
applyMiddleware
,
createStore
}
from
'
redux
'
;
import
{
Provider
}
from
'
react-redux
'
;
import
{
I18nextProvider
}
from
'
react-i18next
'
;
...
...
@@ -14,7 +14,7 @@ import reducers from './reducers';
import
i18n
from
'
./utils/i18n
'
;
import
sagas
from
'
./sagas
'
;
import
ReduxNavigator
from
'
./ui/components/navigator/ReduxNavigator
'
;
import
*
as
logi
nActions
from
'
./actions/
logi
n
'
;
import
*
as
sessio
nActions
from
'
./actions/
sessio
n
'
;
import
*
as
deepLinkingActions
from
'
./actions/deepLinking
'
;
import
{
register
}
from
'
./actions/pushNotifications
'
;
...
...
@@ -22,18 +22,6 @@ const sagaMiddleware = createSagaMiddleware();
const
store
=
createStore
(
reducers
,
applyMiddleware
(
sagaMiddleware
));
sagaMiddleware
.
run
(
sagas
);
const
USERNAMEKEY
=
'
@MyStore:username
'
;
const
TOKENKEY
=
'
@MyStore:token
'
;
const
DISPLAYNAMEKEY
=
'
@MyStore:displayName
'
;
const
PHOTOKEY
=
'
@MyStore:photo
'
;
const
PUSHCATEGORYKEY
=
'
@MyStore:pushCategories
'
;
const
pairsToObject
=
(
obj
,
pair
)
=>
{
const
obj2
=
{
...
obj
};
obj2
[
pair
[
0
]]
=
pair
[
1
];
return
obj2
;
};
FCM
.
on
(
FCMEvent
.
Notification
,
async
(
notif
)
=>
{
if
(
notif
.
fcm
)
{
FCM
.
presentLocalNotification
({
...
...
@@ -63,25 +51,7 @@ class Main extends Component {
}
componentDidMount
()
{
AsyncStorage
.
multiGet
([
USERNAMEKEY
,
TOKENKEY
,
DISPLAYNAMEKEY
,
PHOTOKEY
,
PUSHCATEGORYKEY
])
.
then
(
(
result
)
=>
{
const
values
=
result
.
reduce
(
pairsToObject
,
{});
const
username
=
values
[
USERNAMEKEY
];
const
token
=
values
[
TOKENKEY
];
const
displayName
=
values
[
DISPLAYNAMEKEY
];
const
photo
=
values
[
PHOTOKEY
];
const
pushCategories
=
JSON
.
parse
(
values
[
PUSHCATEGORYKEY
]);
if
(
username
!==
null
&&
token
!==
null
)
{
store
.
dispatch
(
loginActions
.
success
(
username
,
token
));
store
.
dispatch
(
loginActions
.
profileSuccess
(
displayName
,
photo
));
store
.
dispatch
(
loginActions
.
profile
(
token
));
store
.
dispatch
(
register
(
pushCategories
));
}
},
);
store
.
dispatch
(
sessionActions
.
init
());
this
.
addDeepLinkingHandler
();
}
...
...
app/reducers/navigation.js
View file @
34de57b1
import
*
as
navigationActions
from
'
../actions/navigation
'
;
import
*
as
loginActions
from
'
../actions/login
'
;
import
*
as
sessionActions
from
'
../actions/session
'
;
import
{
LOGIN_SCENE
,
SPLASH_SCENE
}
from
'
../ui/components/navigator/scenes
'
;
const
initialState
=
{
previousScenes
:
[],
currentScene
:
'
welcome
'
,
currentScene
:
SPLASH_SCENE
,
loggedIn
:
false
,
drawerOpen
:
false
,
};
...
...
@@ -12,7 +13,7 @@ const initialState = {
export
default
function
navigate
(
state
=
initialState
,
action
=
{})
{
const
{
currentScene
,
previousScenes
,
drawerOpen
}
=
state
;
switch
(
action
.
type
)
{
case
logi
nActions
.
SUCCESS
:
{
case
sessio
nActions
.
SUCCESS
:
{
return
{
...
state
,
loggedIn
:
true
,
...
...
@@ -62,9 +63,12 @@ export default function navigate(state = initialState, action = {}) {
drawerOpen
:
action
.
payload
.
drawerOpen
,
};
}
case
loginActions
.
TOKEN_INVALID
:
case
loginActions
.
LOGOUT
:
{
return
initialState
;
case
sessionActions
.
TOKEN_INVALID
:
case
sessionActions
.
LOGOUT
:
{
return
{
...
initialState
,
currentScene
:
LOGIN_SCENE
,
};
}
default
:
return
state
;
...
...
app/reducers/session.js
View file @
34de57b1
import
{
defaultProfileImage
}
from
'
../utils/url
'
;
import
*
as
logi
nActions
from
'
../actions/
logi
n
'
;
import
*
as
sessio
nActions
from
'
../actions/
sessio
n
'
;
const
initialState
=
{
token
:
''
,
...
...
@@ -11,20 +11,20 @@ const initialState = {
export
default
function
session
(
state
=
initialState
,
action
=
{})
{
switch
(
action
.
type
)
{
case
logi
nActions
.
SUCCESS
:
case
sessio
nActions
.
SUCCESS
:
return
{
...
state
,
username
:
action
.
payload
.
username
,
token
:
action
.
payload
.
token
,
};
case
logi
nActions
.
PROFILE_SUCCESS
:
case
sessio
nActions
.
PROFILE_SUCCESS
:
return
{
...
state
,
displayName
:
action
.
payload
.
displayName
,
photo
:
action
.
payload
.
photo
,
};
case
logi
nActions
.
TOKEN_INVALID
:
case
logi
nActions
.
LOGOUT
:
case
sessio
nActions
.
TOKEN_INVALID
:
case
sessio
nActions
.
LOGOUT
:
return
initialState
;
default
:
return
state
;
...
...
app/sagas/deepLinking.js
View file @
34de57b1
...
...
@@ -5,7 +5,7 @@ import { url as siteURL, loggedInSelector } from '../utils/url';
import
*
as
deepLinkingActions
from
'
../actions/deepLinking
'
;
import
*
as
pizzaActions
from
'
../actions/pizza
'
;
import
*
as
loginActions
from
'
../actions/
logi
n
'
;
import
*
as
loginActions
from
'
../actions/
sessio
n
'
;
import
*
as
eventActions
from
'
../actions/event
'
;
import
*
as
navigationActions
from
'
../actions/navigation
'
;
...
...
app/sagas/index.js
View file @
34de57b1
import
{
all
,
fork
}
from
'
redux-saga/effects
'
;
import
logi
nSaga
from
'
./
logi
n
'
;
import
sessio
nSaga
from
'
./
sessio
n
'
;
import
eventSaga
from
'
./event
'
;
import
profileSaga
from
'
./profile
'
;
import
welcomeSaga
from
'
./welcome
'
;
...
...
@@ -14,7 +14,7 @@ import settingsSaga from './settings';
const
sagas
=
function
*
sagas
()
{
yield
all
([
fork
(
logi
nSaga
),
fork
(
sessio
nSaga
),
fork
(
eventSaga
),
fork
(
profileSaga
),
fork
(
welcomeSaga
),
...
...
app/sagas/
logi
n.js
→
app/sagas/
sessio
n.js
View file @
34de57b1
import
{
call
,
takeEvery
,
put
}
from
'
redux-saga/effects
'
;
import
{
call
,
put
,
takeEvery
}
from
'
redux-saga/effects
'
;
import
{
AsyncStorage
}
from
'
react-native
'
;
import
Snackbar
from
'
react-native-snackbar
'
;
import
{
Sentry
}
from
'
react-native-sentry
'
;
import
{
apiRequest
}
from
'
../utils/url
'
;
import
*
as
logi
nActions
from
'
../actions/
logi
n
'
;
import
*
as
sessio
nActions
from
'
../actions/
sessio
n
'
;
import
*
as
pushNotificationsActions
from
'
../actions/pushNotifications
'
;
import
{
navigate
}
from
'
../actions/navigation
'
;
import
{
LOGIN_SCENE
,
WELCOME_SCENE
}
from
'
../ui/components/navigator/scenes
'
;
export
const
USERNAMEKEY
=
'
@MyStore:username
'
;
export
const
TOKENKEY
=
'
@MyStore:token
'
;
export
const
DISPLAYNAMEKEY
=
'
@MyStore:displayName
'
;
export
const
PHOTOKEY
=
'
@MyStore:photo
'
;
export
const
PUSHCATEGORYKEY
=
'
@MyStore:pushCategories
'
;
const
login
=
function
*
login
(
action
)
{
const
pairsToObject
=
(
obj
,
pair
)
=>
{
const
obj2
=
{
...
obj
};
obj2
[
pair
[
0
]]
=
pair
[
1
];
return
obj2
;
};
const
getStoredItems
=
()
=>
AsyncStorage
.
multiGet
([
USERNAMEKEY
,
TOKENKEY
,
DISPLAYNAMEKEY
,
PHOTOKEY
,
PUSHCATEGORYKEY
,
]);
function
*
init
()
{
try
{
const
result
=
yield
call
(
getStoredItems
);
const
values
=
result
.
reduce
(
pairsToObject
,
{});
const
username
=
values
[
USERNAMEKEY
];
const
token
=
values
[
TOKENKEY
];
const
displayName
=
values
[
DISPLAYNAMEKEY
];
const
photo
=
values
[
PHOTOKEY
];
const
pushCategories
=
JSON
.
parse
(
values
[
PUSHCATEGORYKEY
]);
if
(
username
!==
null
&&
token
!==
null
)
{
yield
put
(
sessionActions
.
success
(
username
,
token
));
yield
put
(
sessionActions
.
profileSuccess
(
displayName
,
photo
));
yield
put
(
sessionActions
.
profile
(
token
));
yield
put
(
pushNotificationsActions
.
register
(
pushCategories
));
}
else
{
yield
put
(
navigate
(
LOGIN_SCENE
,
true
));
}
}
catch
(
e
)
{
Sentry
.
captureException
(
e
);
}
}
function
*
login
(
action
)
{
const
{
user
,
pass
}
=
action
.
payload
;
Snackbar
.
show
({
title
:
'
Logging in
'
,
duration
:
Snackbar
.
LENGTH_INDEFINITE
});
...
...
@@ -36,8 +73,8 @@ const login = function* login(action) {
[
USERNAMEKEY
,
user
],
[
TOKENKEY
,
token
],
]);
yield
put
(
logi
nActions
.
success
(
user
,
token
));
yield
put
(
logi
nActions
.
profile
(
token
));
yield
put
(
sessio
nActions
.
success
(
user
,
token
));
yield
put
(
sessio
nActions
.
profile
(
token
));
yield
put
(
pushNotificationsActions
.
register
());
Snackbar
.
dismiss
();
Snackbar
.
show
({
title
:
'
Login successful
'
});
...
...
@@ -45,20 +82,20 @@ const login = function* login(action) {
Snackbar
.
dismiss
();
Snackbar
.
show
({
title
:
'
Login failed
'
});
}
}
;
}
const
logout
=
function
*
logout
()
{
function
*
logout
()
{
yield
call
(
AsyncStorage
.
multiRemove
,
[
USERNAMEKEY
,
TOKENKEY
]);
yield
put
(
pushNotificationsActions
.
invalidate
());
Snackbar
.
show
({
title
:
'
Logout successful
'
});
}
;
}
const
tokenInvalid
=
function
*
tokenInvalid
()
{