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
430f784b
Verified
Commit
430f784b
authored
Jan 17, 2018
by
Gijs Hendriksen
Committed by
Sébastiaan Versteeg
Jan 21, 2018
Browse files
Add deep linking functionality to the app
parent
daadb241
Changes
6
Hide whitespace changes
Inline
Side-by-side
android/app/src/main/AndroidManifest.xml
View file @
430f784b
...
...
@@ -25,6 +25,15 @@
<action
android:name=
"android.intent.action.MAIN"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
<intent-filter
android:label=
"@string/app_name"
>
<action
android:name=
"android.intent.action.VIEW"
/>
<category
android:name=
"android.intent.category.DEFAULT"
/>
<category
android:name=
"android.intent.category.BROWSABLE"
/>
<data
android:scheme=
"https"
/>
<data
android:host=
"thalia.nu"
/>
<data
android:path=
"/pizzas/"
/>
<data
android:pathPrefix=
"/events/"
/>
</intent-filter>
</activity>
<activity
android:name=
"com.facebook.react.devsupport.DevSettingsActivity"
/>
...
...
app/actions/deepLinking.js
0 → 100644
View file @
430f784b
export
const
DEEPLINK
=
'
DEEPLINKING_DEEPLINK
'
;
export
function
deepLink
(
url
)
{
return
{
type
:
DEEPLINK
,
payload
:
{
url
},
};
}
app/app.js
View file @
430f784b
import
React
,
{
Component
}
from
'
react
'
;
import
{
AsyncStorage
}
from
'
react-native
'
;
import
{
AsyncStorage
,
Linking
,
Platform
}
from
'
react-native
'
;
import
{
applyMiddleware
,
combineReducers
,
createStore
}
from
'
redux
'
;
import
{
Provider
}
from
'
react-redux
'
;
import
createSagaMiddleware
from
'
redux-saga
'
;
...
...
@@ -11,6 +11,7 @@ import * as reducers from './reducers';
import
sagas
from
'
./sagas
'
;
import
ReduxNavigator
from
'
./components/navigator
'
;
import
*
as
loginActions
from
'
./actions/login
'
;
import
*
as
deepLinkingActions
from
'
./actions/deepLinking
'
;
import
{
register
}
from
'
./actions/pushNotifications
'
;
const
sagaMiddleware
=
createSagaMiddleware
();
...
...
@@ -64,8 +65,28 @@ class Main extends Component {
store
.
dispatch
(
register
());
}
});
this
.
addDeepLinkingHandler
();
}
componentWillUnmount
()
{
Linking
.
removeEventListener
(
'
url
'
,
this
.
handleOpenURL
);
}
addDeepLinkingHandler
=
()
=>
{
if
(
Platform
.
OS
===
'
android
'
)
{
Linking
.
getInitialURL
().
then
((
url
)
=>
{
store
.
dispatch
(
deepLinkingActions
.
deepLink
(
url
));
});
}
else
{
Linking
.
addEventListener
(
'
url
'
,
this
.
handleOpenURL
);
}
};
handleOpenURL
=
(
event
)
=>
{
store
.
dispatch
(
deepLinkingActions
.
deepLink
(
event
.
url
));
};
render
()
{
return
(
<
Provider
store
=
{
store
}
>
...
...
app/sagas/deepLinking.js
0 → 100644
View file @
430f784b
import
{
put
,
take
,
takeEvery
,
select
}
from
'
redux-saga/effects
'
;
import
{
url
as
siteURL
,
loggedInSelector
}
from
'
../url
'
;
import
*
as
deepLinkingActions
from
'
../actions/deepLinking
'
;
import
*
as
pizzaActions
from
'
../actions/pizza
'
;
import
*
as
loginActions
from
'
../actions/login
'
;
import
*
as
eventActions
from
'
../actions/event
'
;
import
*
as
navigationActions
from
'
../actions/navigation
'
;
const
parseURL
=
(
url
)
=>
{
const
matches
=
new
RegExp
(
`^
${
siteURL
}
(/[^?]+)(?:\\?(.+))?`
).
exec
(
url
);
if
(
!
matches
)
{
return
{
path
:
''
,
params
:
{},
};
}
const
path
=
matches
[
1
];
const
params
=
{};
if
(
matches
[
2
])
{
const
pairs
=
matches
[
2
].
split
(
'
&
'
);
for
(
let
i
=
0
;
i
<
pairs
.
length
;
i
+=
1
)
{
const
pair
=
pairs
[
i
].
split
(
'
=
'
);
params
[
pair
[
0
]]
=
pair
[
1
];
}
}
return
{
path
,
params
};
};
const
deepLink
=
function
*
deepLink
(
action
)
{
const
{
url
}
=
action
.
payload
;
if
(
!
url
)
{
return
;
}
const
{
path
}
=
parseURL
(
url
);
const
loggedIn
=
yield
select
(
loggedInSelector
);
if
(
!
loggedIn
)
{
yield
take
(
loginActions
.
SUCCESS
);
}
const
patterns
=
[
{
regexp
:
new
RegExp
(
'
^/pizzas/$
'
),
action
:
pizzaActions
.
retrievePizzaInfo
,
args
:
[],
},
{
regexp
:
new
RegExp
(
'
^/events/([0-9]+)/$
'
),
action
:
eventActions
.
event
,
args
:
[],
},
{
regexp
:
new
RegExp
(
'
^/events/$
'
),
action
:
navigationActions
.
navigate
,
args
:
[
'
eventList
'
],
},
];
for
(
let
i
=
0
;
i
<
patterns
.
length
;
i
+=
1
)
{
const
pattern
=
patterns
[
i
];
const
matches
=
pattern
.
regexp
.
exec
(
path
);
if
(
matches
)
{
yield
put
(
pattern
.
action
(...
matches
.
slice
(
1
),
...
pattern
.
args
));
return
;
}
}
};
const
deepLinkingSaga
=
function
*
deepLinkingSaga
()
{
yield
takeEvery
(
deepLinkingActions
.
DEEPLINK
,
deepLink
);
};
export
default
deepLinkingSaga
;
app/sagas/index.js
View file @
430f784b
...
...
@@ -8,6 +8,7 @@ import calendarSaga from './calendar';
import
pushNotificationsSaga
from
'
./pushNotifications
'
;
import
pizzaSaga
from
'
./pizza
'
;
import
registrationSaga
from
'
./registration
'
;
import
deepLinkingSaga
from
'
./deepLinking
'
;
const
sagas
=
function
*
sagas
()
{
yield
all
([
...
...
@@ -19,6 +20,7 @@ const sagas = function* sagas() {
fork
(
pushNotificationsSaga
),
fork
(
pizzaSaga
),
fork
(
registrationSaga
),
fork
(
deepLinkingSaga
),
]);
};
...
...
app/url.js
View file @
430f784b
...
...
@@ -8,6 +8,7 @@ export const apiUrl = `${server}/api/v1`;
export
const
pizzaUrl
=
'
https://pizza.thalia.nu
'
;
export
const
defaultProfileImage
=
`
${
server
}
/static/members/images/default-avatar.jpg`
;
export
const
tokenSelector
=
state
=>
state
.
session
.
token
;
export
const
loggedInSelector
=
state
=>
state
.
navigation
.
loggedIn
;
export
class
ServerError
extends
Error
{
constructor
(
message
,
response
)
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment