Supporting invitations through geo URLs

This commit is contained in:
Eric van der Vlist 2023-03-05 09:53:26 +01:00
parent aba2ddd907
commit 07cd0d04c5
4 changed files with 47 additions and 2 deletions

View File

@ -34,7 +34,9 @@
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="geo" /> <data android:scheme="geo" />
<data android:scheme="" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>

View File

@ -36,6 +36,42 @@ const fetchInvitation = () => {
}); });
}; };
export const searchInvitationInIntent = (intent: any) => {
if (intent.action !== 'android.intent.action.VIEW') {
return false;
}
let url;
try {
url = new URL(intent.data);
} catch (error) {
console.error({ caller: 'searchInvitationInIntent', intent, error });
return false;
}
if (url.protocol !== 'geo:') {
return false;
}
const q = url.search;
const matches = q.match(/invitation=(.+)/);
if (!matches) {
return false;
}
try {
const payload = matches[1];
const decoded = atob(payload);
const url = new URL(decoded);
setInvitation({ url });
fetchInvitation();
} catch {
console.warn({
caller: 'Invitation / searchInvitationInIntent',
intent,
matches,
message: 'Query is not a base64 encoded URL',
});
}
return true;
};
export const searchInvitation = () => { export const searchInvitation = () => {
const hash = location.hash; const hash = location.hash;
console.log({ caller: 'Invitation / searchInvitation', hash }); console.log({ caller: 'Invitation / searchInvitation', hash });

View File

@ -1 +1 @@
export { default, searchInvitation } from './Invitation'; export { default, searchInvitation, searchInvitationInIntent } from './Invitation';

View File

@ -46,7 +46,11 @@ import { Overlays } from '../overlays/Overlays';
import Finder, { findLocation } from '../finder'; import Finder, { findLocation } from '../finder';
import { ZoomIn } from '@suid/icons-material'; import { ZoomIn } from '@suid/icons-material';
import Note from '../note'; import Note from '../note';
import Invitation, { searchInvitation } from '../invitation'; import Invitation, {
searchInvitation,
searchInvitationInIntent,
} from '../invitation';
import { returnOrUpdate } from 'ol/extent';
const [getState, setState] = createSignal({ const [getState, setState] = createSignal({
lon: 0, lon: 0,
@ -92,6 +96,9 @@ const Map: Component = () => {
); );
window.plugins.intentShim.onIntent(function (intent: any) { window.plugins.intentShim.onIntent(function (intent: any) {
console.log({ caller: 'Intent receiver', intent }); console.log({ caller: 'Intent receiver', intent });
if (searchInvitationInIntent(intent)) {
return;
}
if (intent.action === 'android.intent.action.VIEW') { if (intent.action === 'android.intent.action.VIEW') {
const url = new URL(intent.data); const url = new URL(intent.data);
console.log({ caller: 'Intent receiver', intent, url }); console.log({ caller: 'Intent receiver', intent, url });