From d3dc018260c99d24512b5b43b4cae922510e4d02 Mon Sep 17 00:00:00 2001 From: Jason Hunter Date: Wed, 2 Jun 2021 02:41:26 -0400 Subject: [PATCH] video overlay --- web/package-lock.json | 52 ------------------- web/package.json | 1 - web/src/components/Accordion.jsx | 20 ++++++++ web/src/components/Carousel.jsx | 65 ------------------------ web/src/components/RecordingPlaylist.jsx | 53 +++++++++++++++++++ web/src/components/VideoPlayer.jsx | 6 +-- web/src/index.css | 8 +++ web/src/routes/Recording.jsx | 48 ++--------------- 8 files changed, 89 insertions(+), 164 deletions(-) create mode 100644 web/src/components/Accordion.jsx delete mode 100644 web/src/components/Carousel.jsx create mode 100644 web/src/components/RecordingPlaylist.jsx diff --git a/web/package-lock.json b/web/package-lock.json index 98e65710a..856923f2b 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -5320,11 +5320,6 @@ "integrity": "sha512-9YLIBURXj4DJMFALxXw9K3Y3rwb5Fk0X5/8ipCzaN84+gKxoHK43tVKRNakCQbiEx07E8Uwhuq21BpUagFhZ8w==", "dev": true }, - "desandro-matches-selector": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/desandro-matches-selector/-/desandro-matches-selector-2.0.2.tgz", - "integrity": "sha1-cXvu1NwT59jzdi9wem1YpndCGOE=" - }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -6087,11 +6082,6 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, - "ev-emitter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ev-emitter/-/ev-emitter-1.1.1.tgz", - "integrity": "sha512-ipiDYhdQSCZ4hSbX4rMW+XzNKMD1prg/sTvoVmSLkuQ1MVlwjJQQA+sW8tMYR3BLUr9KjodFV4pvzunvRhd33Q==" - }, "exec-sh": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", @@ -6381,14 +6371,6 @@ "path-exists": "^4.0.0" } }, - "fizzy-ui-utils": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fizzy-ui-utils/-/fizzy-ui-utils-2.0.7.tgz", - "integrity": "sha512-CZXDVXQ1If3/r8s0T+v+qVeMshhfcuq0rqIFgJnrtd+Bu8GmDmqMjntjUePypVtjHXKJ6V4sw9zeyox34n9aCg==", - "requires": { - "desandro-matches-selector": "^2.0.0" - } - }, "flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -6405,19 +6387,6 @@ "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, - "flickity": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/flickity/-/flickity-2.2.2.tgz", - "integrity": "sha512-yiPMuP8tw/zN7ARgeSLZNvzK11GkzI2mp/zlYBsyttguSCROAqxj6wiN2sSfPfW3xMG3hcUHxWUXNQMlk/wYcg==", - "requires": { - "desandro-matches-selector": "^2.0.0", - "ev-emitter": "^1.1.1", - "fizzy-ui-utils": "^2.0.7", - "get-size": "^2.0.3", - "unidragger": "^2.3.0", - "unipointer": "^2.3.0" - } - }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -6528,11 +6497,6 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, - "get-size": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/get-size/-/get-size-2.0.3.tgz", - "integrity": "sha512-lXNzT/h/dTjTxRbm9BXb+SGxxzkm97h/PCIKtlN/CBCxxmkkIVV21udumMS93MuVTDX583gqc94v3RjuHmI+2Q==" - }, "get-stdin": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", @@ -11789,14 +11753,6 @@ "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", "dev": true }, - "unidragger": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unidragger/-/unidragger-2.3.1.tgz", - "integrity": "sha512-u+IgG7AG0MXJTKcdzAIYxCm+W5FcnA9M28203Awl6jIcE3/+9OtEyUX4Wv64y7XNKEVRKPot52IV4V6x7FlF5Q==", - "requires": { - "unipointer": "^2.3.0" - } - }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -11809,14 +11765,6 @@ "set-value": "^2.0.1" } }, - "unipointer": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/unipointer/-/unipointer-2.3.0.tgz", - "integrity": "sha512-m85sAoELCZhogI1owtJV3Dva7GxkHk2lI7A0otw3o0OwCuC/Q9gi7ehddigEYIAYbhkqNdri+dU1QQkrcBvirQ==", - "requires": { - "ev-emitter": "^1.0.1" - } - }, "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", diff --git a/web/package.json b/web/package.json index 55d9edd08..7f3d8f766 100644 --- a/web/package.json +++ b/web/package.json @@ -12,7 +12,6 @@ }, "dependencies": { "date-fns": "^2.21.3", - "flickity": "^2.2.2", "idb-keyval": "^5.0.2", "immer": "^8.0.1", "preact": "^10.5.9", diff --git a/web/src/components/Accordion.jsx b/web/src/components/Accordion.jsx new file mode 100644 index 000000000..ed63de59e --- /dev/null +++ b/web/src/components/Accordion.jsx @@ -0,0 +1,20 @@ +import { h } from 'preact'; +import { useState } from 'preact/hooks'; +import ArrowDropdown from '../icons/ArrowDropdown'; +import ArrowDropup from '../icons/ArrowDropup'; + +export default function Accordion({ title, children, selected = false }) { + const [active, setActive] = useState(selected); + const toggle = () => setActive(!active); + return ( +
+
+
{title}
+
+ {active ? : } +
+
+
{children}
+
+ ); +} diff --git a/web/src/components/Carousel.jsx b/web/src/components/Carousel.jsx deleted file mode 100644 index ff0682c48..000000000 --- a/web/src/components/Carousel.jsx +++ /dev/null @@ -1,65 +0,0 @@ -import { h, Component } from 'preact'; -import Flickity from 'flickity'; -import 'flickity/css/flickity.css'; - -export default class Carousel extends Component { - constructor(props) { - super(props); - - this.carousel = null; - this.flkty = null; - } - - create() { - if (this.carousel) { - this.flkty = new Flickity(this.carousel, this.props.options); - - if (this.props.flickityRef) { - this.props.flickityRef(this.flkty); - } - } - } - - destroy() { - if (this.flkty) { - this.flkty.destroy(); - this.flkty = null; - this.carousel = null; - } - } - - componentWillUpdate() { - this.destroy(); - } - - componentDidUpdate() { - this.create(); - } - - componentWillUnmount() { - this.destroy(); - } - - componentDidMount() { - this.create(); - } - - render(props) { - return h( - this.props.elementType, - { - className: this.props.className, - ref: (c) => { - this.carousel = c; - }, - }, - this.props.children - ); - } -} - -Carousel.defaultProps = { - options: {}, - className: '', - elementType: 'div', -}; diff --git a/web/src/components/RecordingPlaylist.jsx b/web/src/components/RecordingPlaylist.jsx new file mode 100644 index 000000000..466d2f47a --- /dev/null +++ b/web/src/components/RecordingPlaylist.jsx @@ -0,0 +1,53 @@ +import { h } from 'preact'; +import { useState } from 'preact/hooks'; +import { format, parseISO } from 'date-fns'; +import Accordion from '../components/Accordion'; +import Link from '../components/Link'; +import Menu from '../icons/Menu'; +import MenuOpen from '../icons/MenuOpen'; + +export default function RecordingPlaylist({ camera, recordings, selectedDate }) { + const [active, setActive] = useState(true); + const toggle = () => setActive(!active); + + const result = []; + for (const recording of recordings.slice().reverse()) { + const date = parseISO(recording.date); + result.push( + + {recording.recordings.map((item) => ( +
+ + {item.hour}:00 + + {item.events} Events +
+ ))} +
+ ); + } + + const openClass = active ? '-left-6' : 'right-0'; + + return ( +
+
+ {active ? : } +
+
+ {result} +
+
+ ); +} + +export function Heading({ title }) { + return
{title}
; +} diff --git a/web/src/components/VideoPlayer.jsx b/web/src/components/VideoPlayer.jsx index b21a9e012..2bfc63219 100644 --- a/web/src/components/VideoPlayer.jsx +++ b/web/src/components/VideoPlayer.jsx @@ -31,12 +31,12 @@ export default class VideoPlayer extends Component { } render() { - const { style } = this.props; + const { style, children } = this.props; return (
-
); diff --git a/web/src/index.css b/web/src/index.css index d55a9aabc..7f11122a0 100644 --- a/web/src/index.css +++ b/web/src/index.css @@ -25,3 +25,11 @@ transform: rotate(360deg); } } + +.vjs-playlist-modal { + position: absolute; + top: 0; + right: 0; + width: 33%; + height: 100%; +} diff --git a/web/src/routes/Recording.jsx b/web/src/routes/Recording.jsx index e1cb77a7a..2ffcba6fe 100644 --- a/web/src/routes/Recording.jsx +++ b/web/src/routes/Recording.jsx @@ -1,11 +1,8 @@ import { h } from 'preact'; -import { Link } from 'preact-router/match'; -import { closestTo, format, isEqual, parseISO } from 'date-fns'; +import { closestTo, format, parseISO } from 'date-fns'; import ActivityIndicator from '../components/ActivityIndicator'; -import Button from '../components/Button'; -import Calendar from '../components/Calendar'; -import Carousel from '../components/Carousel'; import Heading from '../components/Heading'; +import RecordingPlaylist from '../components/RecordingPlaylist'; import VideoPlayer from '../components/VideoPlayer'; import { FetchStatus, useApiHost, useRecording } from '../api'; @@ -24,32 +21,12 @@ export default function Recording({ camera, date, hour }) { ); const selectedKey = format(selectedDate, 'yyyy-MM-dd'); const [year, month, day] = selectedKey.split('-'); - const calendar = []; - const buttons = []; const playlist = []; const hours = []; for (const item of data) { - const date = parseISO(item.date); - const events = item.recordings.map((i) => i.events); - calendar.push( - - a + b)} - selected={isEqual(selectedDate, date)} - /> - - ); - if (item.date === selectedKey) { for (const recording of item.recordings) { - buttons.push( - - ); playlist.push({ name: `${selectedKey} ${recording.hour}:00`, description: `${camera} recording @ ${recording.hour}:00.`, @@ -76,24 +53,11 @@ export default function Recording({ camera, date, hour }) { } } - const selectDate = (flkty) => { - flkty.select(recordingDates.indexOf(selectedKey), false, true); - }; - - const selectHour = (flkty) => { - flkty.select(selectedHour, false, true); - }; - return (
{camera} Recordings - - {calendar} - - { if (player.playlist) { player.playlist(playlist); @@ -104,11 +68,9 @@ export default function Recording({ camera, date, hour }) { this.player = player; } }} - /> - - - {buttons} - + > + +
); }