Storing imported tracks in local "forage".
This commit is contained in:
1 parent
bb2130793d
commit
d0bac1c509
9 files changed
+1276
-53
No files matched your search
+4
-1
@@ -22,13 +22,16 @@ import '@ionic/react/css/display.css';
|
||||
import './theme/variables.css';
|
||||
|
||||
import Map from './components/map/map';
|
||||
import DbContextProvider from './db/db-context-provider';
|
||||
|
||||
setupIonicReact();
|
||||
|
||||
const App: React.FC = () => (
|
||||
<IonApp>
|
||||
<Provider store={store}>
|
||||
<Map />
|
||||
<DbContextProvider>
|
||||
<Map />
|
||||
</DbContextProvider>
|
||||
</Provider>
|
||||
</IonApp>
|
||||
);
|
||||
|
||||
@@ -14,7 +14,7 @@ const GpxImport: React.FC<{}> = () => {
|
||||
|
||||
const onChangeHandler = (event: any) => {
|
||||
console.log('On change handler');
|
||||
const file = event.target.files[0];
|
||||
const file: File = event.target.files[0];
|
||||
const fileReader = new FileReader();
|
||||
fileReader.readAsText(file);
|
||||
|
||||
@@ -24,7 +24,18 @@ const GpxImport: React.FC<{}> = () => {
|
||||
// this will then display a text file
|
||||
console.log(fileReader.result);
|
||||
const track = GPX.parse(fileReader.result);
|
||||
dispatch(tracksActions.push(JSON.parse(JSON.stringify(track))));
|
||||
dispatch(
|
||||
tracksActions.push({
|
||||
track: JSON.parse(JSON.stringify(track)),
|
||||
metadata: {
|
||||
lastModified: new Date(file.lastModified).toISOString(),
|
||||
importDate: new Date().toISOString(),
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
type: file.type,
|
||||
},
|
||||
})
|
||||
);
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
@@ -1,11 +1,31 @@
|
||||
import React from 'react';
|
||||
import React, { useContext, useEffect } from 'react';
|
||||
|
||||
import { DbContext } from '../../db/db-context-provider';
|
||||
import { lat2tile, lon2tile } from '../../lib/geo';
|
||||
import { zoom0 } from '../../store/map';
|
||||
|
||||
const Track: React.FC<{ track: any }> = (props) => {
|
||||
const trkseg = props.track.trk[0].trkseg[0];
|
||||
const Track: React.FC<{ track: any; id: string }> = (props) => {
|
||||
const dbContext = useContext(DbContext);
|
||||
|
||||
useEffect(() => {
|
||||
const store = dbContext.tracksStore;
|
||||
const checkDb = async () => {
|
||||
store.getItem(props.id).then((value) => {
|
||||
if (value === null) {
|
||||
store.setItem(props.id, props.track).then((value) => {
|
||||
console.log(
|
||||
`Track ${props.id} saved in the ${store.driver()} Database.`
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
if (dbContext.ready) {
|
||||
checkDb();
|
||||
}
|
||||
}, [dbContext, props]);
|
||||
|
||||
const trkseg = props.track.track.trk[0].trkseg[0];
|
||||
const d = trkseg.trkpt.reduce(
|
||||
(previous: string, current: any, index: number) => {
|
||||
const action = index === 0 ? 'M' : index === 1 ? 'L' : '';
|
||||
|
||||
@@ -1,33 +1,15 @@
|
||||
import React, { Fragment, useEffect } from 'react';
|
||||
import React, { Fragment, useContext } from 'react';
|
||||
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { Drivers, Storage } from '@ionic/storage';
|
||||
import * as CordovaSQLiteDriver from 'localforage-cordovasqlitedriver';
|
||||
|
||||
import Track from './track';
|
||||
|
||||
var store: Storage;
|
||||
|
||||
const Tracks: React.FC<{}> = () => {
|
||||
useEffect(() => {
|
||||
store = new Storage({
|
||||
driverOrder: [
|
||||
CordovaSQLiteDriver._driver,
|
||||
Drivers.IndexedDB,
|
||||
Drivers.LocalStorage,
|
||||
],
|
||||
});
|
||||
store
|
||||
.defineDriver(CordovaSQLiteDriver)
|
||||
.then(() => console.log('CordovaSQLiteDriver registered'));
|
||||
}, []);
|
||||
|
||||
const tracks = useSelector((state: { tracks: any }) => state.tracks.tracks);
|
||||
return (
|
||||
<Fragment>
|
||||
{Object.keys(tracks).map((key: any) => (
|
||||
<Track key={key} track={tracks[key]} />
|
||||
<Track key={key} id={key} track={tracks[key]} />
|
||||
))}
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import react, { useEffect, useState } from 'react';
|
||||
|
||||
import * as CordovaSQLiteDriver from 'localforage-cordovasqlitedriver';
|
||||
import localforage from 'localforage';
|
||||
|
||||
const initialDbContext = { ready: false, tracksStore: localforage };
|
||||
export const DbContext = react.createContext(initialDbContext);
|
||||
|
||||
const DbContextProvider: react.FC<{
|
||||
children?: JSX.Element;
|
||||
}> = (props: { children?: JSX.Element }) => {
|
||||
const [store, setStore] = useState(localforage);
|
||||
const [ready, setReady] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const config = {
|
||||
name: 'dyomedea',
|
||||
driver: [
|
||||
CordovaSQLiteDriver._driver,
|
||||
localforage.INDEXEDDB,
|
||||
localforage.WEBSQL,
|
||||
localforage.LOCALSTORAGE,
|
||||
],
|
||||
};
|
||||
const newStore = localforage.createInstance({
|
||||
storeName: 'tracks',
|
||||
...config,
|
||||
});
|
||||
setStore(newStore);
|
||||
setReady(true);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<DbContext.Provider value={{ ready, tracksStore: store }}>
|
||||
{props.children}
|
||||
</DbContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export default DbContextProvider;
|
||||
+28
-2
@@ -1,5 +1,12 @@
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
|
||||
import {
|
||||
Sha256,
|
||||
Sha512,
|
||||
string_to_bytes,
|
||||
bytes_to_base64,
|
||||
} from '@openpgp/asmcrypto.js';
|
||||
|
||||
interface TracksState {
|
||||
tracks: { [index: string]: any };
|
||||
}
|
||||
@@ -13,10 +20,29 @@ const tracksSlice = createSlice({
|
||||
initialState: initialTracks,
|
||||
reducers: {
|
||||
add: (state, action) => {
|
||||
state.tracks[action.payload.id] = action.payload.track;
|
||||
const { id, ...data } = action.payload;
|
||||
state.tracks[action.payload.id] = data;
|
||||
},
|
||||
push: (state, action) => {
|
||||
state.tracks[crypto.randomUUID()] = action.payload;
|
||||
const sha = new Sha512();
|
||||
const result = sha
|
||||
.process(string_to_bytes(JSON.stringify(action.payload.track)))
|
||||
.finish().result;
|
||||
var id;
|
||||
if (result === null) {
|
||||
console.log(`Can't hash`);
|
||||
id = crypto.randomUUID();
|
||||
} else {
|
||||
id = bytes_to_base64(result);
|
||||
console.log(`Digest: ${id}`);
|
||||
}
|
||||
if (state.tracks.hasOwnProperty(id)) {
|
||||
console.log('Track had already been imported');
|
||||
} else {
|
||||
state.tracks[id] = {
|
||||
...action.payload,
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user