diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 0f94e3c..593289f 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -33,6 +33,12 @@ + + + + + + diff --git a/package-lock.json b/package-lock.json index 87547fa..b02b78e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "@capacitor/android": "^4.6.1", "@capacitor/browser": "^4.1.0", "@capacitor/core": "^4.6.1", + "@capacitor/filesystem": "^4.1.4", "@capacitor/ios": "^4.6.1", "@esbuild-plugins/node-globals-polyfill": "^0.1.1", "@esbuild-plugins/node-modules-polyfill": "^0.1.4", @@ -678,6 +679,14 @@ "tslib": "^2.1.0" } }, + "node_modules/@capacitor/filesystem": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@capacitor/filesystem/-/filesystem-4.1.4.tgz", + "integrity": "sha512-ivko1RNK4hq63xhMacq8D6D97N5/SAafTsrmY/pghYrG6Cl2SEY0+IgRu7V9/VWeN3FSplyUPucjUTAFQxXN5g==", + "peerDependencies": { + "@capacitor/core": "^4.0.0" + } + }, "node_modules/@capacitor/ios": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-4.6.1.tgz", diff --git a/package.json b/package.json index 4df255e..52556d4 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "@capacitor/android": "^4.6.1", "@capacitor/browser": "^4.1.0", "@capacitor/core": "^4.6.1", + "@capacitor/filesystem": "^4.1.4", "@capacitor/ios": "^4.6.1", "@esbuild-plugins/node-globals-polyfill": "^0.1.1", "@esbuild-plugins/node-modules-polyfill": "^0.1.4", diff --git a/src/components/gpx-import/GpxImport.tsx b/src/components/gpx-import/GpxImport.tsx index cb686c8..ef25006 100644 --- a/src/components/gpx-import/GpxImport.tsx +++ b/src/components/gpx-import/GpxImport.tsx @@ -10,9 +10,13 @@ import { useI18n } from '@solid-primitives/i18n'; import { Box } from '@suid/material'; import GpxImportSingleFile from './GpxImportSingleFile'; -const GpxImport: Component = () => { - const [filesToImport, setFilesToImport] = createSignal(); +const [filesToImport, setFilesToImport] = createSignal(); +export const importUrls = (urls: string[]) => { + setFilesToImport(urls); +}; + +const GpxImport: Component = () => { const [t] = useI18n(); const onChangeHandler = (event: any) => { diff --git a/src/components/gpx-import/GpxImportSingleFile.tsx b/src/components/gpx-import/GpxImportSingleFile.tsx index af9cdf3..60f9fa2 100644 --- a/src/components/gpx-import/GpxImportSingleFile.tsx +++ b/src/components/gpx-import/GpxImportSingleFile.tsx @@ -15,6 +15,10 @@ import GPX from '../../lib/gpx-parser-builder/src/gpx'; import dispatch from '../../workers/dispatcher-main'; import GpxChooser from '../gpx-chooser'; import { currentGpxId } from '../gpx-dialog'; +import { + Filesystem as CapacitorFileSystem, + Encoding, +} from '@capacitor/filesystem'; interface Props { gpxFile: File; @@ -55,28 +59,47 @@ const GpxImportSingleFile: Component = ({ gpxFile }) => { setGpxId(currentGpxId()); }); - const gpxReader = new FileReader(); - gpxReader.readAsText(gpxFile); + const parseGpx = (content: string) => { + const gpx = GPX.parse(content); + console.log({ caller: 'GpxImportSingleFile / JSON', gpxFile, gpx }); + setStatsAndGpx({ gpx, stats: analyzeGpx(gpx) }); + }; - gpxReader.addEventListener( - 'load', - async () => { - // this will then display a text gpxfile + if (typeof gpxFile === 'string') { + CapacitorFileSystem.requestPermissions().then((permissionStatus) => { console.log({ - caller: 'GpxImportSingleFile / XML', - gpxFile, - result: gpxReader.result, + caller: 'GpxImportSingleFile / content', + permissionStatus, }); - const gpx = GPX.parse(gpxReader.result); - console.log({ caller: 'GpxImportSingleFile / JSON', gpxFile, gpx }); - setStatsAndGpx({ gpx, stats: analyzeGpx(gpx) }); - // if (gpx) { - // const startTime = new Date(findStartTime(gpx)!); - // } - }, - false - ); - + }); + CapacitorFileSystem.readFile({ + path: gpxFile, + encoding: Encoding.UTF8, + }).then((content) => { + console.log({ + caller: 'GpxImportSingleFile / content', + gpxFile, + content, + }); + parseGpx(content.data); + }); + } else { + const gpxReader = new FileReader(); + gpxReader.readAsText(gpxFile); + gpxReader.addEventListener( + 'load', + async () => { + // this will then display a text gpxfile + console.log({ + caller: 'GpxImportSingleFile / XML', + gpxFile, + result: gpxReader.result, + }); + parseGpx(gpxReader.result); + }, + false + ); + } const doImport = async () => { setState('importing'); // console.log({ caller: 'GpxImport / JSON', file, gpx }); @@ -87,13 +110,19 @@ const GpxImportSingleFile: Component = ({ gpxFile }) => { params: { id: gpxId(), gpx: statsAndGpx()?.gpx, - tech: { - lastModified: new Date(gpxFile.lastModified).toISOString(), - importDate: new Date().toISOString(), - name: gpxFile.name, - size: gpxFile.size, - type: gpxFile.type, - }, + tech: + typeof gpxFile === 'string' + ? { + importDate: new Date().toISOString(), + uri: gpxFile, + } + : { + lastModified: new Date(gpxFile.lastModified).toISOString(), + importDate: new Date().toISOString(), + name: gpxFile.name, + size: gpxFile.size, + type: gpxFile.type, + }, }, }); console.log({ diff --git a/src/components/gpx-import/index.ts b/src/components/gpx-import/index.ts index ec1d52b..55613bf 100644 --- a/src/components/gpx-import/index.ts +++ b/src/components/gpx-import/index.ts @@ -1 +1 @@ -export { default } from './GpxImport'; +export { default, importUrls } from './GpxImport'; diff --git a/src/components/map/Map.tsx b/src/components/map/Map.tsx index 63f555d..3deb25f 100644 --- a/src/components/map/Map.tsx +++ b/src/components/map/Map.tsx @@ -21,7 +21,7 @@ import { Style, Icon } from 'ol/style'; import GetLocation, { getCurrentLocation } from '../get-location'; import ShowLocationIcon from '../get-location/ShowLocationIcon.svg'; import { Back, Forward } from '../back-forward'; -import GpxImport from '../gpx-import'; +import GpxImport, { importUrls } from '../gpx-import'; import AllGpxes from '../all-gpxes'; import MapTileProvider, { mapTileProviders } from '../map-tile-provider'; import Interaction from 'ol/interaction/Interaction'; @@ -78,7 +78,10 @@ const Map: Component = () => { if (window.plugins) { window.plugins.intentShim.registerBroadcastReceiver( { - filterActions: ['android.intent.action.VIEW'], + filterActions: [ + 'android.intent.action.VIEW', + 'android.intent.action.SEND', + ], }, function (intent: any) { console.log({ @@ -89,11 +92,16 @@ const Map: Component = () => { ); window.plugins.intentShim.onIntent(function (intent: any) { console.log({ caller: 'Intent receiver', intent }); - const url = new URL(intent.data); - const q = url.search; - const [, lat, lon] = q.match(/q=([0-9.-]+),([0-9.-]+)/); - console.log({ caller: 'Intent receiver', intent, url, lat, lon }); - findLocation(navigate, [lon, lat]); + if (intent.action === 'android.intent.action.VIEW') { + const url = new URL(intent.data); + const q = url.search; + const [, lat, lon] = q.match(/q=([0-9.-]+),([0-9.-]+)/); + console.log({ caller: 'Intent receiver', intent, url, lat, lon }); + findLocation(navigate, [lon, lat]); + } else if (intent.action === 'android.intent.action.SEND') { + const uri = intent.extras['android.intent.extra.STREAM']; + importUrls([uri]); + } }); } else { console.log({