2022-12-11 15:20:34 +00:00
|
|
|
import { useI18n } from '@solid-primitives/i18n';
|
2022-12-12 10:41:09 +00:00
|
|
|
import {
|
|
|
|
Typography,
|
2022-12-13 06:59:28 +00:00
|
|
|
Card,
|
|
|
|
CardContent,
|
|
|
|
CardActions,
|
|
|
|
Button,
|
2022-12-13 07:24:50 +00:00
|
|
|
Box,
|
|
|
|
LinearProgress,
|
|
|
|
CircularProgress,
|
2022-12-12 10:41:09 +00:00
|
|
|
} from '@suid/material';
|
|
|
|
import { Component, createEffect, createSignal, Show } from 'solid-js';
|
2022-12-11 15:20:34 +00:00
|
|
|
import { findStartTime } from '../../lib/gpx';
|
|
|
|
import GPX from '../../lib/gpx-parser-builder/src/gpx';
|
2022-12-13 11:41:13 +00:00
|
|
|
import dispatch from '../../workers/dispatcher-main';
|
2022-12-13 07:24:50 +00:00
|
|
|
import GpxChooser from '../gpx-chooser';
|
|
|
|
import { currentGpxId } from '../gpx-dialog';
|
2023-02-04 17:22:05 +00:00
|
|
|
import {
|
|
|
|
Filesystem as CapacitorFileSystem,
|
|
|
|
Encoding,
|
|
|
|
} from '@capacitor/filesystem';
|
2022-12-11 15:20:34 +00:00
|
|
|
|
|
|
|
interface Props {
|
|
|
|
gpxFile: File;
|
|
|
|
}
|
|
|
|
|
2022-12-12 10:41:09 +00:00
|
|
|
interface StatsAndGpx {
|
|
|
|
gpx: Gpx;
|
|
|
|
stats: any;
|
|
|
|
}
|
|
|
|
|
2022-12-11 15:20:34 +00:00
|
|
|
const analyzeGpx = (gpx: Gpx | undefined) => {
|
|
|
|
if (gpx === undefined) {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
const stats = {
|
|
|
|
creator: gpx.$.creator,
|
|
|
|
nbWpts: gpx.wpt ? gpx.wpt?.length : 0,
|
|
|
|
nbRtes: gpx.rte ? gpx.rte?.length : 0,
|
|
|
|
nbTrks: gpx.trk ? gpx.trk?.length : 0,
|
2022-12-12 10:41:09 +00:00
|
|
|
trkMaybeRte:
|
|
|
|
gpx.trk &&
|
|
|
|
gpx.trk[0].trkseg &&
|
|
|
|
gpx.trk[0].trkseg[0] &&
|
|
|
|
gpx.trk[0].trkseg[0].trkpt &&
|
|
|
|
!gpx.trk[0].trkseg[0].trkpt[0].time,
|
|
|
|
startTime: findStartTime(gpx),
|
2022-12-11 15:20:34 +00:00
|
|
|
};
|
2022-12-12 10:41:09 +00:00
|
|
|
|
2022-12-11 15:20:34 +00:00
|
|
|
return stats;
|
|
|
|
};
|
|
|
|
|
|
|
|
const GpxImportSingleFile: Component<Props> = ({ gpxFile }) => {
|
|
|
|
const [t] = useI18n();
|
2022-12-12 10:41:09 +00:00
|
|
|
const [statsAndGpx, setStatsAndGpx] = createSignal<StatsAndGpx>();
|
2022-12-13 06:59:28 +00:00
|
|
|
const [state, setState] = createSignal('init');
|
2022-12-13 07:24:50 +00:00
|
|
|
const [gpxId, setGpxId] = createSignal<string>('');
|
|
|
|
createEffect(() => {
|
|
|
|
setGpxId(currentGpxId());
|
|
|
|
});
|
2022-12-11 15:20:34 +00:00
|
|
|
|
2023-02-04 17:22:05 +00:00
|
|
|
const parseGpx = (content: string) => {
|
|
|
|
const gpx = GPX.parse(content);
|
|
|
|
console.log({ caller: 'GpxImportSingleFile / JSON', gpxFile, gpx });
|
|
|
|
setStatsAndGpx({ gpx, stats: analyzeGpx(gpx) });
|
|
|
|
};
|
2022-12-11 15:20:34 +00:00
|
|
|
|
2023-02-04 17:22:05 +00:00
|
|
|
if (typeof gpxFile === 'string') {
|
|
|
|
CapacitorFileSystem.requestPermissions().then((permissionStatus) => {
|
|
|
|
console.log({
|
|
|
|
caller: 'GpxImportSingleFile / content',
|
|
|
|
permissionStatus,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
CapacitorFileSystem.readFile({
|
|
|
|
path: gpxFile,
|
|
|
|
encoding: Encoding.UTF8,
|
|
|
|
}).then((content) => {
|
2022-12-11 15:20:34 +00:00
|
|
|
console.log({
|
2023-02-04 17:22:05 +00:00
|
|
|
caller: 'GpxImportSingleFile / content',
|
2022-12-11 15:20:34 +00:00
|
|
|
gpxFile,
|
2023-02-04 17:22:05 +00:00
|
|
|
content,
|
2022-12-11 15:20:34 +00:00
|
|
|
});
|
2023-02-04 17:22:05 +00:00
|
|
|
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
|
|
|
|
);
|
|
|
|
}
|
2022-12-13 11:41:13 +00:00
|
|
|
const doImport = async () => {
|
2022-12-13 07:24:50 +00:00
|
|
|
setState('importing');
|
2022-12-13 11:41:13 +00:00
|
|
|
// console.log({ caller: 'GpxImport / JSON', file, gpx });
|
|
|
|
// if (gpx) {
|
|
|
|
// const startTime = new Date(findStartTime(gpx)!);
|
|
|
|
await dispatch({
|
|
|
|
action: 'pruneAndSaveImportedGpx',
|
|
|
|
params: {
|
|
|
|
id: gpxId(),
|
|
|
|
gpx: statsAndGpx()?.gpx,
|
2023-02-04 17:22:05 +00:00
|
|
|
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,
|
|
|
|
},
|
2022-12-13 11:41:13 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
console.log({
|
|
|
|
caller: 'GpxImport / JSON / done',
|
|
|
|
gpxFile,
|
|
|
|
gpx: statsAndGpx()?.gpx,
|
|
|
|
});
|
|
|
|
setState('done');
|
|
|
|
|
|
|
|
// } else {
|
|
|
|
// console.error({
|
|
|
|
// message: "can't parse GPX file",
|
|
|
|
// file,
|
|
|
|
// xml: fileReader.result,
|
|
|
|
// });
|
|
|
|
// }
|
|
|
|
// // TODO: error handling
|
|
|
|
// },
|
|
|
|
// false
|
|
|
|
// );
|
|
|
|
// }
|
2022-12-13 06:59:28 +00:00
|
|
|
};
|
|
|
|
|
2022-12-12 10:41:09 +00:00
|
|
|
const [selectedTrkTransform, setSelectedTrkTransform] = createSignal(
|
|
|
|
'importNonTimedTrksAsRtes'
|
|
|
|
);
|
|
|
|
|
|
|
|
const handleTrkTransformChange = (event: any) => {
|
|
|
|
setSelectedTrkTransform(event.target.value);
|
|
|
|
};
|
|
|
|
|
|
|
|
const controlTrkTransformProps = (item: string) => ({
|
|
|
|
checked: selectedTrkTransform() === item,
|
|
|
|
onChange: handleTrkTransformChange,
|
|
|
|
value: item,
|
|
|
|
name: 'trkTransform',
|
|
|
|
label: t(item),
|
|
|
|
inputProps: { 'aria-label': item },
|
|
|
|
});
|
2022-12-11 15:20:34 +00:00
|
|
|
|
|
|
|
return (
|
2022-12-13 06:59:28 +00:00
|
|
|
<Card raised>
|
|
|
|
<CardContent>
|
|
|
|
<Typography variant='h6'>
|
2022-12-11 15:20:34 +00:00
|
|
|
{t('file')}
|
|
|
|
{gpxFile.name}
|
|
|
|
</Typography>
|
2022-12-13 06:59:28 +00:00
|
|
|
</CardContent>
|
|
|
|
<CardContent>
|
|
|
|
<Show when={statsAndGpx() !== undefined}>
|
2022-12-11 15:20:34 +00:00
|
|
|
<Typography variant='body1'>
|
2022-12-12 10:41:09 +00:00
|
|
|
{t('gpxStats', statsAndGpx().stats)}{' '}
|
|
|
|
{statsAndGpx()?.stats.startTime
|
|
|
|
? t('gpxStartTime', statsAndGpx().stats)
|
|
|
|
: t('gpxNoStartTime')}
|
2022-12-11 15:20:34 +00:00
|
|
|
</Typography>
|
2022-12-13 06:59:28 +00:00
|
|
|
<Show when={statsAndGpx().stats.trkMaybeRte}>
|
2022-12-12 10:41:09 +00:00
|
|
|
<Typography variant='body1'>{t('trkMaybeRte')}</Typography>
|
2022-12-13 06:59:28 +00:00
|
|
|
</Show>
|
2022-12-13 07:24:50 +00:00
|
|
|
<Show when={state() === 'importing'}>
|
|
|
|
<LinearProgress />
|
|
|
|
</Show>
|
|
|
|
<CardActions>
|
2022-12-13 11:41:13 +00:00
|
|
|
<GpxChooser
|
|
|
|
gpxId={gpxId}
|
|
|
|
setGpxId={setGpxId}
|
|
|
|
disabled={state() != 'init'}
|
|
|
|
/>
|
2022-12-13 07:24:50 +00:00
|
|
|
<Button
|
|
|
|
variant='contained'
|
|
|
|
disabled={state() != 'init'}
|
|
|
|
onClick={doImport}
|
|
|
|
>
|
|
|
|
{t('import')}
|
|
|
|
</Button>
|
|
|
|
</CardActions>
|
2022-12-12 10:41:09 +00:00
|
|
|
</Show>
|
2022-12-13 06:59:28 +00:00
|
|
|
</CardContent>
|
|
|
|
</Card>
|
2022-12-11 15:20:34 +00:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default GpxImportSingleFile;
|