re-arrange

This commit is contained in:
Bernt Christian Egeland 2021-08-27 21:47:51 +02:00
parent 3527c1f14a
commit e2bee3ab94
4 changed files with 111 additions and 135 deletions

View File

@ -1,5 +1,5 @@
import { h, Fragment } from 'preact';
import { useCallback, useState, useEffect } from 'preact/hooks';
import { useCallback, useState, useEffect, useRef } from 'preact/hooks';
import ActivityIndicator from '../components/ActivityIndicator';
import Button from '../components/Button';
import Clip from '../icons/Clip';
@ -18,6 +18,7 @@ export default function Event({ eventId, close, scrollRef }) {
const [shouldScroll, setShouldScroll] = useState(true);
const [deleteStatus, setDeleteStatus] = useState(FetchStatus.NONE);
const setDeleteEvent = useDelete();
const eventRef = useRef(null);
useEffect(() => {
// Scroll event into view when component has been mounted.
@ -27,6 +28,21 @@ export default function Event({ eventId, close, scrollRef }) {
}
}, [data, scrollRef, eventId, shouldScroll]);
// useEffect(() => {
// const checkIfClickedOutside = (e) => {
// // If the event is open and the clicked target is not within the event window or delete modal,
// // then close the menu
// if (!showDialog && eventRef.current && !eventRef.current.contains(e.target)) {
// close(null);
// }
// };
// document.addEventListener('mousedown', checkIfClickedOutside);
// return () => {
// // Cleanup the
// document.removeEventListener('mousedown', checkIfClickedOutside);
// };
// }, [close, showDialog]);
const handleClickDelete = () => {
setShowDialog(true);
};
@ -55,7 +71,7 @@ export default function Event({ eventId, close, scrollRef }) {
}
return (
<div className="space-y-4">
<div className="space-y-4" ref={eventRef}>
<div className="grid grid-cols-6 gap-4">
<div class="col-start-1 col-end-8 md:space-x-4">
<Button color="blue" href={`${apiHost}/api/events/${eventId}/clip.mp4?download=true`} download>

View File

@ -1,39 +1,30 @@
import { h, Fragment } from 'preact';
import { useCallback, useEffect, useState, useRef } from 'preact/hooks';
import { memo } from 'preact/compat';
import { useCallback, useState } from 'preact/hooks';
import { Tr, Td } from '../../../components/Table';
import Filterable from './filterable';
import Event from '../../Event';
import { memo } from 'preact/compat';
import { useSearchString } from '../hooks/useSearchString';
const EventsRow = memo(
(
{
({
id,
apiHost,
start_time: startTime,
end_time: endTime,
handleFilter,
reachedEnd,
scrollToRef,
searchString,
lastRowRef,
handleFilter,
pathname,
searchParams,
camera,
label,
score,
top_score: score,
zones,
numberOfEvents,
idx,
searchString,
lastCellRef,
removeDefaultSearchKeys,
},
i
) => {
}) => {
const [viewEvent, setViewEvent] = useState(null);
// const [searchString, setSearchString, removeDefaultSearchKeys] = useSearchString(limit);
// const ref = useRef();
const viewEventHandler = useCallback(
(id) => {
@ -46,32 +37,19 @@ const EventsRow = memo(
[viewEvent]
);
// useEffect(() => {
// const checkIfClickedOutside = (e) => {
// // If the menu is open and the clicked target is not within the menu,
// // then close the menu
// if (viewEvent && ref.current && !ref.current.contains(e.target)) {
// setViewEvent(null);
// }
// };
// document.addEventListener('mousedown', checkIfClickedOutside);
// return () => {
// // Cleanup the event listener
// document.removeEventListener('mousedown', checkIfClickedOutside);
// };
// }, [setViewEvent, viewEvent]);
const start = new Date(parseInt(startTime * 1000, 10));
const end = new Date(parseInt(endTime * 1000, 10));
const ref = idx === numberOfEvents - 1 ? lastCellRef : undefined;
console.log('table row renders');
console.log('tablerow has been rendered');
return (
<Fragment key={id}>
<Tr data-testid={`event-${id}`} className={`${viewEvent === id ? 'border-none' : ''}`}>
<Td className="w-40">
<a onClick={() => viewEventHandler(id)} ref={ref} data-start-time={startTime} data-reached-end={reachedEnd}>
<a
onClick={() => viewEventHandler(id)}
ref={lastRowRef}
data-start-time={startTime}
data-reached-end={reachedEnd}
>
<img
ref={(el) => (scrollToRef[id] = el)}
width="150"
@ -131,36 +109,6 @@ const EventsRow = memo(
</Tr>
) : null}
</Fragment>
// <Fragment>
// <Tr>
// <Td className="w-40">
// <a
// onClick={() => viewEventHandler(id)}
// ref={lastCellRef}
// data-start-time={startTime}
// data-reached-end={reachedEnd}
// >
// <img
// ref={(el) => (scrollToRef[id] = el)}
// width="150"
// height="150"
// className="cursor-pointer"
// style="min-height: 48px; min-width: 48px;"
// src={`${apiHost}/api/events/${id}/thumbnail.jpg`}
// />
// </a>
// </Td>
// {viewEvent === id ? (
// <span ref={ref}>
// <Tr className="border-b-1">
// <Td colSpan="8">
// <Event eventId={id} close={() => setViewEvent(null)} scrollRef={scrollToRef} />
// </Td>
// </Tr>
// </span>
// ) : null}
// </Tr>
// </Fragment>
);
}
);

View File

@ -1,11 +1,10 @@
import { h } from 'preact';
import { useState, useCallback } from 'preact/hooks';
const defaultSearchString = (limit) => `include_thumbnails=0&limit=${limit}`;
export const useSearchString = (limit, searchParams) => {
const { searchParams: initialSearchParams } = new URL(window.location);
const _searchParams = searchParams ? searchParams : initialSearchParams.toString();
const _searchParams = searchParams || initialSearchParams.toString();
const [searchString, setSearchString] = useState(`${defaultSearchString(limit)}&${_searchParams}`);
@ -13,17 +12,14 @@ export const useSearchString = (limit, searchParams) => {
(limit, searchString) => {
setSearchString(`${defaultSearchString(limit)}&${searchString}`);
},
[setSearchString, defaultSearchString]
[setSearchString]
);
const removeDefaultSearchKeys = useCallback(
(searchParams) => {
const removeDefaultSearchKeys = useCallback((searchParams) => {
searchParams.delete('limit');
searchParams.delete('include_thumbnails');
searchParams.delete('before');
},
[searchParams]
);
}, []);
return [searchString, changeSearchString, removeDefaultSearchKeys];
};

View File

@ -1,4 +1,4 @@
import { h, Fragment } from 'preact';
import { h } from 'preact';
import ActivityIndicator from '../../components/ActivityIndicator';
import Heading from '../../components/Heading';
import { TableHead, Filters } from './components';
@ -22,7 +22,7 @@ export default function Events({ path: pathname, limit = API_LIMIT } = {}) {
const { data, status, deletedId } = useEvents(searchString);
const [counter, setCounter] = useState(0);
let scrollToRef = useMemo(() => Object, []);
const scrollToRef = useMemo(() => Object, []);
useEffect(() => {
if (data && !(searchString in searchStrings)) {
@ -38,23 +38,17 @@ export default function Events({ path: pathname, limit = API_LIMIT } = {}) {
}
}, [data, limit, searchString, searchStrings, deleted, deletedId]);
useEffect(() => {
setInterval(() => {
setCounter((prev) => prev + 1);
}, 1000);
}, []);
const handleFilter = useCallback(
(searchParams) => {
dispatch({ type: 'RESET' });
removeDefaultSearchKeys(searchParams);
setSearchString(limit, searchParams.toString());
route(`${pathname}?${searchParams.toString()}`);
},
[limit, pathname, setSearchString, removeDefaultSearchKeys]
);
const [entry, setIntersectNode] = useIntersectionObserver();
useEffect(() => {
if (entry && entry.isIntersecting) {
const { startTime } = entry.target.dataset;
const { searchParams } = new URL(window.location);
searchParams.set('before', parseFloat(startTime) - 0.0001);
setSearchString(limit, searchParams.toString());
}
}, [entry, limit, setSearchString]);
const lastCellRef = useCallback(
(node) => {
if (node !== null && !reachedEnd) {
@ -64,17 +58,54 @@ export default function Events({ path: pathname, limit = API_LIMIT } = {}) {
[setIntersectNode, reachedEnd]
);
useEffect(() => {
if (entry && entry.isIntersecting) {
const { startTime } = entry.target.dataset;
const { searchParams } = new URL(window.location);
searchParams.set('before', parseFloat(startTime) - 0.0001);
const handleFilter = useCallback(
(searchParams) => {
dispatch({ type: 'RESET' });
removeDefaultSearchKeys(searchParams);
setSearchString(limit, searchParams.toString());
}
}, [entry, limit]);
route(`${pathname}?${searchParams.toString()}`);
},
[limit, pathname, setSearchString, removeDefaultSearchKeys]
);
const searchParams = useMemo(() => new URLSearchParams(searchString), [searchString]);
console.log('counter ' + counter);
const RenderTableRow = useCallback(
(props) => (
<TableRow
key={props.id}
apiHost={apiHost}
scrollToRef={scrollToRef}
reachedEnd={reachedEnd}
setSearchString={setSearchString}
pathname={pathname}
searchParams={searchParams}
limit={API_LIMIT}
searchString={searchString}
handleFilter={handleFilter}
removeDefaultSearchKeys={removeDefaultSearchKeys}
{...props}
/>
),
[
reachedEnd,
apiHost,
setSearchString,
handleFilter,
pathname,
removeDefaultSearchKeys,
scrollToRef,
// searchParams,
// searchString,
]
);
useEffect(() => {
setInterval(() => {
setCounter((prev) => prev + 1);
}, 1000);
}, []);
console.log('main render', counter);
return (
<div className="space-y-4 w-full">
<Heading>Events</Heading>
@ -85,24 +116,9 @@ export default function Events({ path: pathname, limit = API_LIMIT } = {}) {
<Table className="min-w-full table-fixed">
<TableHead />
<Tbody>
{events.map(({ id, ...rest }, idx) => {
return (
<TableRow
key={id}
idx={idx}
numberOfEvents={events.length}
id={id}
apiHost={apiHost}
scrollToRef={scrollToRef}
pathname={pathname}
searchParams={searchParams}
limit={API_LIMIT}
handleFilter={handleFilter}
lastCellRef={lastCellRef}
removeDefaultSearchKeys={removeDefaultSearchKeys}
{...rest}
/>
);
{events.map((props, idx) => {
const lastRowRef = idx === events.length - 1 ? lastCellRef : undefined;
return <RenderTableRow {...props} lastRowRef={lastRowRef} idx={idx} />;
})}
</Tbody>
<Tfoot>