First version with a GPX export (#9) that works in a browser but, unfortunately, doesn't wotk on Adroid !
This commit is contained in:
parent
93054115a5
commit
cb4a257003
|
@ -1,28 +1,39 @@
|
|||
import { IonButton, IonIcon } from '@ionic/react';
|
||||
import { cloudDownload } from 'ionicons/icons';
|
||||
import React, { Fragment, useLayoutEffect, useRef, useState } from 'react';
|
||||
import React, { Fragment, useRef } from 'react';
|
||||
import { useDB } from 'react-pouchdb';
|
||||
import { getGpxAsXmlString } from '../../db/gpx';
|
||||
|
||||
const GpxExport: React.FC<{ gpxId: string }> = (props: { gpxId: string }) => {
|
||||
const GpxExport: React.FC<{ gpx: any }> = (props: { gpx: any }) => {
|
||||
const db = useDB();
|
||||
|
||||
const hiddenLinkElement = useRef<HTMLAnchorElement>(null);
|
||||
|
||||
const [fileDownloadUrl, setFileDownloadUrl] = useState('');
|
||||
var downloadName;
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (fileDownloadUrl !== '') {
|
||||
hiddenLinkElement.current?.click();
|
||||
URL.revokeObjectURL(fileDownloadUrl);
|
||||
setFileDownloadUrl('');
|
||||
}
|
||||
}, [fileDownloadUrl]);
|
||||
if (props.gpx.metadata.name !== undefined) {
|
||||
downloadName = props.gpx.metadata.name;
|
||||
} else if (props.gpx.gpx.metadata.name !== undefined) {
|
||||
downloadName = `${props.gpx.gpx.metadata.name}.gpx`;
|
||||
} else {
|
||||
downloadName = `track-${props.gpx.metadata.lastModified}.gpx`;
|
||||
}
|
||||
|
||||
const download = (event: any) => {
|
||||
const download = async (event: any) => {
|
||||
event.preventDefault();
|
||||
const blob = new Blob(['<gpx/>'], { type: 'application/gpx+xml' });
|
||||
console.log('download()');
|
||||
const gpxAsXml = await getGpxAsXmlString(db, props.gpx._id);
|
||||
console.log(`gpxAsXml: ${gpxAsXml}`);
|
||||
const blob = new Blob([gpxAsXml], {
|
||||
type: 'application/gpx+xml',
|
||||
});
|
||||
const fileDownloadUrl = URL.createObjectURL(blob);
|
||||
setFileDownloadUrl(fileDownloadUrl);
|
||||
console.log(`fileDownloadUrl: ${fileDownloadUrl}`);
|
||||
console.log(`hiddenLinkElement.current: ${hiddenLinkElement.current}`);
|
||||
hiddenLinkElement.current!.href = fileDownloadUrl;
|
||||
hiddenLinkElement.current?.click();
|
||||
URL.revokeObjectURL(fileDownloadUrl);
|
||||
hiddenLinkElement.current!.href = '';
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -30,13 +41,8 @@ const GpxExport: React.FC<{ gpxId: string }> = (props: { gpxId: string }) => {
|
|||
<IonButton id='gpx-export-button' onClick={download}>
|
||||
<IonIcon icon={cloudDownload} title='Export' slot='icon-only' />
|
||||
</IonButton>
|
||||
<a
|
||||
className='hidden'
|
||||
download={props.gpxId + '.gpx'}
|
||||
href={fileDownloadUrl}
|
||||
ref={hiddenLinkElement}
|
||||
>
|
||||
download it
|
||||
<a className='hidden' download={downloadName} ref={hiddenLinkElement}>
|
||||
download
|
||||
</a>
|
||||
</Fragment>
|
||||
);
|
||||
|
|
|
@ -58,7 +58,7 @@ const TrackBrowser: React.FC<{}> = () => {
|
|||
<IonItem key={gpx._id}>
|
||||
<span>{gpx.gpx.metadata.time}</span>
|
||||
<IonButtons slot='end'>
|
||||
<GpxExport gpxId={gpx._id} />
|
||||
<GpxExport gpx={gpx} />
|
||||
<IonButton
|
||||
onClick={() => {
|
||||
deleteGps(db, { _id: gpx._id, _rev: gpx._rev });
|
||||
|
|
|
@ -3,7 +3,7 @@ import {
|
|||
string_to_bytes,
|
||||
bytes_to_base64,
|
||||
} from '@openpgp/asmcrypto.js';
|
||||
import { documentSharp } from 'ionicons/icons';
|
||||
import GPX from '../lib/gpx-parser-builder';
|
||||
|
||||
export const pushGpx = async (db: any, payload: any) => {
|
||||
const gpxString = JSON.stringify(payload.gpx);
|
||||
|
@ -170,3 +170,27 @@ export const deleteCurrent = async (db: any) => {
|
|||
await deleteGps(db, docs[i]);
|
||||
}
|
||||
};
|
||||
|
||||
export const getGpx = async (db: any, gpxId: string) => {
|
||||
var gpxResult = await db.get(gpxId);
|
||||
var gpx = gpxResult.gpx;
|
||||
var trkptResults = await db.find({
|
||||
selector: {
|
||||
type: 'trkpt',
|
||||
gpx: gpx._id,
|
||||
},
|
||||
});
|
||||
var trkpts = trkptResults.docs;
|
||||
trkpts.sort((first: any, second: any) =>
|
||||
first.trkpt.time.localeCompare(second.trkpt.time)
|
||||
);
|
||||
trkpts.map((trkptDoc: any) => {
|
||||
gpx.trk[0].trkseg[0].trkpt.push(trkptDoc.trkpt);
|
||||
});
|
||||
return gpx;
|
||||
};
|
||||
|
||||
export const getGpxAsXmlString = async (db: any, gpxId: string) => {
|
||||
const gpx = new GPX(await getGpx(db, gpxId));
|
||||
return gpx.toString({});
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue