aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton@traccar.org>2022-06-13 16:58:11 -0700
committerAnton Tananaev <anton@traccar.org>2022-06-13 16:58:11 -0700
commite48d7264dec72c5daad3365e2127519fee0c8cd1 (patch)
tree7f1ea6e31d090dfaf36f62957440b418e45efc93
parent5a685addb8e1a9ff9b03399d3b06c3cc60d73e9b (diff)
downloadtrackermap-web-e48d7264dec72c5daad3365e2127519fee0c8cd1.tar.gz
trackermap-web-e48d7264dec72c5daad3365e2127519fee0c8cd1.tar.bz2
trackermap-web-e48d7264dec72c5daad3365e2127519fee0c8cd1.zip
Handle push notification tokens
-rw-r--r--modern/src/common/components/NativeInterface.js64
-rw-r--r--modern/src/index.js2
-rw-r--r--modern/src/login/LoginPage.js2
3 files changed, 68 insertions, 0 deletions
diff --git a/modern/src/common/components/NativeInterface.js b/modern/src/common/components/NativeInterface.js
new file mode 100644
index 00000000..75b954a8
--- /dev/null
+++ b/modern/src/common/components/NativeInterface.js
@@ -0,0 +1,64 @@
+import { useEffect, useState } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+import { useEffectAsync } from '../../reactHelper';
+import { sessionActions } from '../../store';
+
+export const nativePostMessage = (message) => {
+ if (window.webkit && window.webkit.messageHandlers.appInterface) {
+ window.webkit.messageHandlers.appInterface.postMessage(message);
+ }
+ if (window.appInterface) {
+ window.appInterface.postMessage(message);
+ }
+};
+
+const listeners = new Set();
+window.updateNotificationToken = (token) => {
+ listeners.forEach((listener) => listener(token));
+};
+
+const NativeInterface = () => {
+ const dispatch = useDispatch();
+
+ const user = useSelector((state) => state.session.user);
+ const [token, setToken] = useState(null);
+
+ useEffect(() => {
+ const listener = (token) => setToken(token);
+ listeners.add(listener);
+ return () => {
+ listeners.delete(listener);
+ };
+ }, [setToken]);
+
+ useEffectAsync(async () => {
+ if (user && token) {
+ setToken(null);
+
+ const tokens = user.attributes.notificationTokens?.split(',') || [];
+ const updatedUser = {
+ ...user,
+ attributes: {
+ ...user.attributes,
+ notificationTokens: [...tokens, token].join(','),
+ },
+ };
+
+ const response = await fetch(`/api/users/${user.id}`, {
+ method: 'PUT',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(updatedUser),
+ });
+
+ if (response.ok) {
+ dispatch(sessionActions.updateUser(await response.json()));
+ } else {
+ throw Error(await response.text());
+ }
+ }
+ }, [user, token, setToken]);
+
+ return null;
+};
+
+export default NativeInterface;
diff --git a/modern/src/index.js b/modern/src/index.js
index dbbf2da4..bfbb5efe 100644
--- a/modern/src/index.js
+++ b/modern/src/index.js
@@ -13,6 +13,7 @@ import theme from './common/theme';
import Navigation from './Navigation';
import preloadImages from './map/core/preloadImages';
import * as serviceWorkerRegistration from './serviceWorkerRegistration';
+import NativeInterface from './common/components/NativeInterface';
preloadImages();
@@ -31,6 +32,7 @@ ReactDOM.render(
<Navigation />
</BrowserRouter>
<ErrorHandler />
+ <NativeInterface />
</ThemeProvider>
</StyledEngineProvider>
</LocalizationProvider>
diff --git a/modern/src/login/LoginPage.js b/modern/src/login/LoginPage.js
index 0077f6bd..34d0e7d8 100644
--- a/modern/src/login/LoginPage.js
+++ b/modern/src/login/LoginPage.js
@@ -13,6 +13,7 @@ import { useLocalization, useTranslation } from '../common/components/Localizati
import LoginLayout from './LoginLayout';
import usePersistedState from '../common/util/usePersistedState';
import logoSvg from '../resources/images/logo.svg';
+import { nativePostMessage } from '../common/components/NativeInterface';
const useStyles = makeStyles((theme) => ({
legacy: {
@@ -73,6 +74,7 @@ const LoginPage = () => {
if (response.ok) {
const user = await response.json();
dispatch(sessionActions.updateUser(user));
+ nativePostMessage('login');
navigate('/');
} else {
throw Error(await response.text());