dyomedea/src/components/map/Settings.tsx

179 lines
5.0 KiB
TypeScript

import React, { Fragment, useEffect, useRef } from 'react';
import { useDB } from 'react-pouchdb';
import {
IonButton,
IonButtons,
IonContent,
IonIcon,
IonInput,
IonItem,
IonLabel,
IonList,
IonListHeader,
IonModal,
IonTitle,
IonToolbar,
} from '@ionic/react';
import { options } from 'ionicons/icons';
import { enterAnimation, leaveAnimation } from '../../lib/animation';
import { useDispatch, useSelector } from 'react-redux';
import { settingsActions, SettingsState } from '../../store/settings';
import uri from '../../lib/ids';
import _ from 'lodash';
const Settings: React.FC<{}> = () => {
const dispatch = useDispatch();
const db = useDB();
useEffect(() => {
const initFromDb = async () => {
try {
const settingsFromDb = await db.get(uri('settings', {}));
console.log(
`settingsFromDb: ${JSON.stringify(settingsFromDb.settings)}`
);
dispatch(settingsActions.saveSettings(settingsFromDb.settings));
} catch {}
};
initFromDb();
}, [db, dispatch]);
const settingsState = useSelector(
(state: { settings: SettingsState }) => state.settings
);
useEffect(() => {
if (!settingsState.default) {
const settingsFromRedux = async () => {
const id = uri('settings', {});
var settingsFromDb;
try {
settingsFromDb = await db.get(id);
} catch (error) {
console.log(
`Error getting settings from db: ${JSON.stringify(error)}`
);
settingsFromDb = { _id: id, settings: {} };
}
if (!_.isEqual(settingsState, settingsFromDb.settings)) {
console.log(`settingsFromRedux: ${JSON.stringify(settingsState)}`);
settingsFromDb.settings = settingsState;
db.put(settingsFromDb);
}
};
settingsFromRedux();
}
}, [db, settingsState]);
const pseudo = useRef<HTMLIonInputElement>(null);
const minTimeInterval = useRef<HTMLIonInputElement>(null);
const minDistance = useRef<HTMLIonInputElement>(null);
const modal = useRef<HTMLIonModalElement>(null);
const dismiss = () => {
modal.current?.dismiss();
};
const save = () => {
dispatch(
settingsActions.saveSettings({
user: {
pseudo: pseudo.current?.value,
},
geolocation: {
minTimeInterval: minTimeInterval.current?.value,
minDistance: minDistance.current?.value,
},
})
);
dismiss();
};
return (
<Fragment>
<IonButton id='open-SettingsDialog'>
<IonIcon slot='icon-only' icon={options} />
</IonButton>
<IonModal
ref={modal}
trigger='open-SettingsDialog'
enterAnimation={enterAnimation}
leaveAnimation={leaveAnimation}
className='full-height'
>
<IonToolbar>
<IonTitle>Settings</IonTitle>
<IonButtons slot='end'>
<IonButton onClick={() => dismiss()}>Close</IonButton>
</IonButtons>
</IonToolbar>
<IonContent>
<IonList lines='full' class='ion-no-margin'>
<IonListHeader lines='full'>
<IonLabel>User</IonLabel>
</IonListHeader>
<IonItem>
<IonLabel>Pseudo: </IonLabel>
<IonInput
ref={pseudo}
value={settingsState.user.pseudo}
autocomplete='nickname'
></IonInput>
</IonItem>
</IonList>
<IonList lines='full' class='ion-no-margin'>
<IonListHeader lines='full'>
<IonLabel>Geolocation</IonLabel>
</IonListHeader>
<IonItem>
<IonLabel>Minimal time interval (ms): </IonLabel>
<IonInput
value={settingsState.geolocation.minTimeInterval}
ref={minTimeInterval}
inputMode='numeric'
type='number'
></IonInput>
</IonItem>
<IonItem>
<IonLabel>Minimal distance (m): </IonLabel>
<IonInput
value={settingsState.geolocation.minDistance}
ref={minDistance}
inputMode='numeric'
type='number'
></IonInput>
</IonItem>
</IonList>
<IonItem>
<IonToolbar class='secondary'>
<IonButtons slot='secondary'>
<IonButton
shape='round'
fill='solid'
color='primary'
onClick={() => save()}
>
Save
</IonButton>
<IonButton
shape='round'
fill='outline'
color='primary'
onClick={() => dismiss()}
>
Cancel
</IonButton>
</IonButtons>
</IonToolbar>
</IonItem>
</IonContent>
</IonModal>
</Fragment>
);
};
export default Settings;