Basic dialog to start/pause/stop and clear track recording.
This commit is contained in:
1 parent
d71881dc02
commit
3235d9ae70
4 files changed
+264
-25
No files matched your search
@@ -1,15 +1,30 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { useDB } from 'react-pouchdb';
|
||||
import React, { Fragment, useRef, useState } from 'react';
|
||||
|
||||
import { useDB, useFind } from 'react-pouchdb';
|
||||
|
||||
import '../../theme/get-location.css';
|
||||
import { IonButton, IonIcon } from '@ionic/react';
|
||||
import { recordingOutline, recording } from 'ionicons/icons';
|
||||
import {
|
||||
createAnimation,
|
||||
IonButton,
|
||||
IonButtons,
|
||||
IonContent,
|
||||
IonIcon,
|
||||
IonModal,
|
||||
IonTitle,
|
||||
IonToolbar,
|
||||
} from '@ionic/react';
|
||||
import {
|
||||
recordingOutline,
|
||||
recording,
|
||||
closeCircle,
|
||||
pauseCircle,
|
||||
stop,
|
||||
} from 'ionicons/icons';
|
||||
import {
|
||||
startBackgroundGeolocation,
|
||||
stopBackgroundGeolocation,
|
||||
} from '../../lib/background-geolocation';
|
||||
import { deleteCurrent, saveCurrent } from '../../db/gpx';
|
||||
|
||||
const GpxRecord: React.FC<{}> = () => {
|
||||
const db = useDB();
|
||||
@@ -18,24 +33,152 @@ const GpxRecord: React.FC<{}> = () => {
|
||||
|
||||
const [watcher_id, setWatcher_id] = useState();
|
||||
|
||||
const toggleIsRecording = () => {
|
||||
const gpxes = useFind({
|
||||
selector: {
|
||||
type: 'gpx',
|
||||
subtype: 'current',
|
||||
},
|
||||
});
|
||||
|
||||
const hasCurrentTrack = gpxes.length > 0;
|
||||
|
||||
console.log(
|
||||
`GpxRecord, hasCurrentTrack:${hasCurrentTrack}, gpxes: ${JSON.stringify(
|
||||
gpxes
|
||||
)}`
|
||||
);
|
||||
|
||||
const modal = useRef<HTMLIonModalElement>(null);
|
||||
|
||||
const dismiss = () => {
|
||||
modal.current?.dismiss();
|
||||
};
|
||||
|
||||
const startRecording = () => {
|
||||
startBackgroundGeolocation(db).then((result) => {
|
||||
setWatcher_id(result);
|
||||
});
|
||||
setIsRecording(true);
|
||||
dismiss();
|
||||
};
|
||||
|
||||
const pauseRecording = () => {
|
||||
if (isRecording) {
|
||||
stopBackgroundGeolocation(watcher_id);
|
||||
} else {
|
||||
startBackgroundGeolocation(db).then((result) => {
|
||||
setWatcher_id(result);
|
||||
});
|
||||
}
|
||||
setIsRecording(!isRecording);
|
||||
setIsRecording(false);
|
||||
dismiss();
|
||||
};
|
||||
|
||||
const stopRecording = () => {
|
||||
saveCurrent(db);
|
||||
pauseRecording();
|
||||
};
|
||||
|
||||
const deleteRecording = () => {
|
||||
deleteCurrent(db);
|
||||
pauseRecording();
|
||||
};
|
||||
|
||||
const enterAnimation = (baseEl: HTMLElement) => {
|
||||
const root = baseEl.shadowRoot;
|
||||
|
||||
const backdropAnimation = createAnimation()
|
||||
.addElement(root?.querySelector('ion-backdrop')!)
|
||||
.fromTo('opacity', '0.01', 'var(--backdrop-opacity)');
|
||||
|
||||
const wrapperAnimation = createAnimation()
|
||||
.addElement(root?.querySelector('.modal-wrapper')!)
|
||||
.keyframes([
|
||||
{ offset: 0, opacity: '0', transform: 'scale(0)' },
|
||||
{ offset: 1, opacity: '0.99', transform: 'scale(1)' },
|
||||
]);
|
||||
|
||||
return createAnimation()
|
||||
.addElement(baseEl)
|
||||
.easing('ease-out')
|
||||
.duration(500)
|
||||
.addAnimation([backdropAnimation, wrapperAnimation]);
|
||||
};
|
||||
|
||||
const leaveAnimation = (baseEl: HTMLElement) => {
|
||||
return enterAnimation(baseEl).direction('reverse');
|
||||
};
|
||||
|
||||
return (
|
||||
<IonButton onClick={toggleIsRecording}>
|
||||
{isRecording && (
|
||||
<IonIcon slot='icon-only' icon={recording} style={{ color: 'red' }} />
|
||||
)}
|
||||
{!isRecording && <IonIcon slot='icon-only' icon={recordingOutline} />}
|
||||
</IonButton>
|
||||
<Fragment>
|
||||
<IonButton id='open-RecordDialog'>
|
||||
{isRecording && (
|
||||
<IonIcon slot='icon-only' icon={recording} style={{ color: 'red' }} />
|
||||
)}
|
||||
{!isRecording && <IonIcon slot='icon-only' icon={recordingOutline} />}
|
||||
</IonButton>
|
||||
<IonModal
|
||||
ref={modal}
|
||||
trigger='open-RecordDialog'
|
||||
enterAnimation={enterAnimation}
|
||||
leaveAnimation={leaveAnimation}
|
||||
>
|
||||
<IonToolbar>
|
||||
<IonTitle>Track recording</IonTitle>
|
||||
<IonButtons slot='end'>
|
||||
<IonButton onClick={() => dismiss()}>Close</IonButton>
|
||||
</IonButtons>
|
||||
</IonToolbar>
|
||||
<IonContent>
|
||||
{!isRecording && (
|
||||
<IonButton
|
||||
expand='block'
|
||||
color='primary'
|
||||
size='large'
|
||||
onClick={startRecording}
|
||||
>
|
||||
<IonIcon slot='start' icon={recording}></IonIcon>
|
||||
{hasCurrentTrack ? (
|
||||
<span>Resume recording</span>
|
||||
) : (
|
||||
<span>Start recording</span>
|
||||
)}
|
||||
</IonButton>
|
||||
)}
|
||||
{isRecording && (
|
||||
<IonButton
|
||||
expand='block'
|
||||
color='primary'
|
||||
size='large'
|
||||
onClick={pauseRecording}
|
||||
>
|
||||
<IonIcon slot='start' icon={pauseCircle}></IonIcon>Pause
|
||||
</IonButton>
|
||||
)}
|
||||
{hasCurrentTrack && (
|
||||
<>
|
||||
<IonButton
|
||||
expand='block'
|
||||
color='danger'
|
||||
size='large'
|
||||
onClick={stopRecording}
|
||||
>
|
||||
<IonIcon slot='start' icon={stop}></IonIcon>Stop recording
|
||||
<br />
|
||||
(and save track)
|
||||
</IonButton>
|
||||
<IonButton
|
||||
expand='block'
|
||||
color='danger'
|
||||
size='large'
|
||||
onClick={deleteRecording}
|
||||
>
|
||||
<IonIcon slot='start' icon={closeCircle}></IonIcon>Cancel
|
||||
recording
|
||||
<br />
|
||||
(and clear track)
|
||||
</IonButton>
|
||||
</>
|
||||
)}
|
||||
</IonContent>
|
||||
</IonModal>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user