feat: add alarm and distance

This commit is contained in:
Nicola Zambello 2021-12-13 20:08:36 +01:00
parent d23e7661ae
commit 266f874f1a
6 changed files with 629 additions and 368 deletions

View file

@ -8,5 +8,5 @@ charset = utf-8
[{*.css,*.scss,*.less,*.overrides,*.variables}]
indent_size = 4
[{*.js,*.json}]
[{*.js,*.json,*.ts,*.tsx,*.jsx}]
indent_size = 2

View file

@ -1,5 +1,7 @@
{
"name": "walk-up-alarm",
"author": "nzambello",
"license": "MIT",
"version": "0.0.0",
"scripts": {
"dev": "vite",
@ -7,12 +9,16 @@
"serve": "vite preview"
},
"dependencies": {
"geolib": "^3.3.3",
"rc-time-picker": "^3.7.3",
"react": "^17.0.0",
"react-dom": "^17.0.0"
"react-dom": "^17.0.0",
"use-position": "^1.0.0"
},
"devDependencies": {
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/use-position": "^0.0.0",
"@vitejs/plugin-react": "^1.0.0",
"typescript": "^4.3.2",
"vite": "^2.6.4",

View file

@ -1,45 +1,130 @@
import { useState } from 'react'
import logo from './logo.svg'
import './App.css'
import { useCallback, useState, useRef, useEffect } from "react";
import { usePosition } from "use-position";
import { getDistance } from "geolib";
import TimePicker from "rc-time-picker";
import moment from "moment";
import "./App.css";
import "rc-time-picker/assets/index.css";
import alarmMp3 from "./alarm.mp3";
import blankMp3 from "./blank.mp3";
function App() {
const [count, setCount] = useState(0)
const [alarm, setAlarm] = useState<moment.Moment | null>(null);
const [alarmSet, setAlarmSet] = useState(false);
const [stopDistance, setStopDistance] = useState(10);
const audioRef = useRef<HTMLAudioElement>(null);
const { latitude, longitude, timestamp, accuracy } = usePosition(true, {
enableHighAccuracy: true,
timeout: Infinity,
maximumAge: 0,
});
interface ICoords {
latitude: number;
longitude: number;
}
const [startCoords, setStartCoords] = useState<ICoords | null>(null);
useEffect(() => {
if (latitude && longitude && !startCoords) {
setStartCoords({ latitude, longitude });
}
}, [latitude, longitude, startCoords]);
const distance =
startCoords && latitude && longitude
? getDistance(startCoords, { latitude, longitude }, 0.01)
: 0;
useEffect(() => {
if (alarmSet && distance > stopDistance) {
setAlarmSet(false);
setAlarm(null);
}
}, [distance, alarmSet]);
const showAlarm = () => {
console.log("ALARM! Wake up!");
audioRef.current?.play();
if (!("Notification" in window)) {
alert("This browser does not support desktop notification");
} else if (Notification.permission === "granted") {
var notification = new Notification("Wake up!");
} else if (Notification.permission !== "denied") {
Notification.requestPermission().then(function (permission) {
// If the user accepts, let's create a notification
if (permission === "granted") {
var notification = new Notification("Wake up!");
}
});
}
};
const registerAlarm = useCallback(() => {
if (alarm) {
audioRef.current?.play().then(() => {
setAlarmSet(true);
if (latitude && longitude) setStartCoords({ latitude, longitude });
const delay = alarm.diff(moment());
console.log("set alarm", delay);
setTimeout(() => {
showAlarm();
}, delay);
});
}
}, [alarm]);
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>Hello Vite + React!</p>
<div className="App-header">
<TimePicker
defaultValue={moment().add(1, "hour")}
value={alarm ?? undefined}
onChange={(newTime) => setAlarm(newTime)}
showSecond={false}
/>
<input
type="number"
placeholder="distance"
min={1}
value={stopDistance}
onChange={(e) => setStopDistance(e.target.value)}
/>
<p>
<button type="button" onClick={() => setCount((count) => count + 1)}>
count is: {count}
<button type="button" onClick={registerAlarm}>
Set alarm
</button>
{alarmSet && (
<button
type="button"
onClick={() => {
setAlarm(null);
setAlarmSet(false);
}}
>
Reset
</button>
)}
</p>
<p>
Edit <code>App.tsx</code> and save to test HMR updates.
</p>
<p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
{' | '}
<a
className="App-link"
href="https://vitejs.dev/guide/features.html"
target="_blank"
rel="noopener noreferrer"
>
Vite Docs
</a>
</p>
</header>
<audio src={alarmSet ? alarmMp3 : blankMp3} ref={audioRef} />
{startCoords && (
<code>
original: {startCoords.latitude}, {startCoords.longitude}
<br />
current: {latitude}, {longitude}
<br />
accuracy: {accuracy && `${accuracy} meters`}
<br />
distance: {distance && `${distance} meters`}
</code>
)}
</div>
</div>
)
);
}
export default App
export default App;

BIN
src/alarm.mp3 Normal file

Binary file not shown.

BIN
src/blank.mp3 Normal file

Binary file not shown.

834
yarn.lock

File diff suppressed because it is too large Load diff