From 83e14932a449f324aadb082938b29915e7c6ee24 Mon Sep 17 00:00:00 2001 From: evlist Date: Sat, 26 Nov 2022 22:04:08 +0100 Subject: [PATCH] GPX import. --- package-lock.json | 26 +++++-- package.json | 1 + .../gpx-import/GpxImport.module.css | 18 +++++ src/components/gpx-import/GpxImport.tsx | 74 +++++++++++++++++++ src/components/gpx-import/index.ts | 1 + src/components/map/Map.tsx | 9 +++ tsconfig.json | 7 +- 7 files changed, 128 insertions(+), 8 deletions(-) create mode 100644 src/components/gpx-import/GpxImport.module.css create mode 100644 src/components/gpx-import/GpxImport.tsx create mode 100644 src/components/gpx-import/index.ts diff --git a/package-lock.json b/package-lock.json index 41c4075..71e5fd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@solidjs/router": "^0.5.1", "@suid/icons-material": "^0.5.1", "@suid/material": "^0.8.0", + "isomorphic-xml2js": "^0.1.3", "lodash": "^4.17.21", "ol": "^7.1.0", "pouchdb": "^7.3.1", @@ -1308,8 +1309,7 @@ "node_modules/@types/node": { "version": "18.11.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", - "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", - "dev": true + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" }, "node_modules/@types/slice-ansi": { "version": "4.0.0", @@ -1332,6 +1332,14 @@ "@types/jest": "*" } }, + "node_modules/@types/xml2js": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.11.tgz", + "integrity": "sha512-JdigeAKmCyoJUiQljjr7tQG3if9NkqGUgwEUqBvV0N7LM4HyQk7UXCnusRa1lnvXAEYJ8mw8GtZWioagNztOwA==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/yargs": { "version": "17.0.14", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.14.tgz", @@ -3201,6 +3209,15 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/isomorphic-xml2js": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/isomorphic-xml2js/-/isomorphic-xml2js-0.1.3.tgz", + "integrity": "sha512-dIkT2U9ritKVWF/HfHfGwm5tTnlMnknYsv7l12oJlQQgOV2CNV65pX+FHy6HFL9YP8q0JcrlNQAFRJIN2agUmQ==", + "dependencies": { + "@types/xml2js": "^0.4.2", + "xml2js": "^0.4.19" + } + }, "node_modules/jest-diff": { "version": "29.3.1", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz", @@ -4562,8 +4579,7 @@ "node_modules/sax": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz", - "integrity": "sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==", - "dev": true + "integrity": "sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==" }, "node_modules/saxes": { "version": "6.0.0", @@ -5431,7 +5447,6 @@ "version": "0.4.23", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dev": true, "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" @@ -5444,7 +5459,6 @@ "version": "11.0.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true, "engines": { "node": ">=4.0" } diff --git a/package.json b/package.json index 6279497..62c3178 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "@solidjs/router": "^0.5.1", "@suid/icons-material": "^0.5.1", "@suid/material": "^0.8.0", + "isomorphic-xml2js": "^0.1.3", "lodash": "^4.17.21", "ol": "^7.1.0", "pouchdb": "^7.3.1", diff --git a/src/components/gpx-import/GpxImport.module.css b/src/components/gpx-import/GpxImport.module.css new file mode 100644 index 0000000..bfa1a79 --- /dev/null +++ b/src/components/gpx-import/GpxImport.module.css @@ -0,0 +1,18 @@ +.container { + position: fixed !important; + top: 6px; + margin-left: calc(100% - 80px) !important; +} +.label { + --opacity: 0.6; + --ion-background-color: white; +} + +.inputFile { + width: 0.1px; + height: 0.1px; + opacity: 0; + overflow: hidden; + /* position: absolute; */ + z-index: -1; +} diff --git a/src/components/gpx-import/GpxImport.tsx b/src/components/gpx-import/GpxImport.tsx new file mode 100644 index 0000000..42d8f66 --- /dev/null +++ b/src/components/gpx-import/GpxImport.tsx @@ -0,0 +1,74 @@ +import { Component } from 'solid-js'; + +import CloudUploadIcon from '@suid/icons-material/CloudUpload'; + +import GPX from '../../lib/gpx-parser-builder/src/gpx'; + +import css from './GpxImport.module.css'; +import { findStartTime } from '../../lib/gpx'; +import dispatch from '../../workers/dispatcher-main'; +import { intToGpxId } from '../../lib/ids'; + +const GpxImport: Component = () => { + const onChangeHandler = (event: any) => { + console.log('On change handler'); + const file: File = event.target.files[0]; + const fileReader = new FileReader(); + fileReader.readAsText(file); + + fileReader.addEventListener( + 'load', + () => { + // this will then display a text file + console.log(fileReader.result); + const gpx = GPX.parse(fileReader.result); + console.log(`gpx: ${JSON.stringify(gpx)}`); + const startTime = new Date(findStartTime(gpx)!); + dispatch({ + action: 'pruneAndSaveImportedGpx', + params: { + id: { gpx: intToGpxId(startTime.valueOf()) }, + gpx: gpx, + tech: { + lastModified: new Date(file.lastModified).toISOString(), + importDate: new Date().toISOString(), + name: file.name, + size: file.size, + type: file.type, + }, + }, + }); + // pushGpx(db, { + // gpx, + // metadata: { + // lastModified: new Date(file.lastModified).toISOString(), + // importDate: new Date().toISOString(), + // name: file.name, + // size: file.size, + // type: file.type, + // }, + // }); + }, + false + ); + }; + + return ( + <> +
+ + +
+ + ); +}; + +export default GpxImport; diff --git a/src/components/gpx-import/index.ts b/src/components/gpx-import/index.ts new file mode 100644 index 0000000..ec1d52b --- /dev/null +++ b/src/components/gpx-import/index.ts @@ -0,0 +1 @@ +export { default } from './GpxImport'; diff --git a/src/components/map/Map.tsx b/src/components/map/Map.tsx index 7e55c9b..6374838 100644 --- a/src/components/map/Map.tsx +++ b/src/components/map/Map.tsx @@ -21,6 +21,7 @@ import { Circle, Fill, Stroke, 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'; const [getState, setState] = createSignal({ lon: 0, @@ -161,6 +162,14 @@ const Map: Component = () => { ), }), + new Control({ + // @ts-ignore + element: ( +
+ +
+ ), + }), ]), }); olMap.on(['moveend'], changeListener); diff --git a/tsconfig.json b/tsconfig.json index 0f2653b..ff02822 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,11 +3,14 @@ "strict": true, "target": "ESNext", "module": "ESNext", + "allowJs": true, "moduleResolution": "node", "allowSyntheticDefaultImports": true, "esModuleInterop": true, "jsx": "preserve", "jsxImportSource": "solid-js", - "types": ["vite/client"] - } + "types": ["vite/client"], + "rootDirs": ["src"], + }, + "include": ["src"], }