feat: Set time range and highlight selected search result
This commit is contained in:
@@ -316,6 +316,7 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
|||||||
const [showRange, setShowRange] = useState(false);
|
const [showRange, setShowRange] = useState(false);
|
||||||
const [isSearching, setIsSearching] = useState(false);
|
const [isSearching, setIsSearching] = useState(false);
|
||||||
const [searchResults, setSearchResults] = useState(null);
|
const [searchResults, setSearchResults] = useState(null);
|
||||||
|
const [activeSearchResult, setActiveSearchResult] = useState(null);
|
||||||
const scrollContainerRef = useRef(null);
|
const scrollContainerRef = useRef(null);
|
||||||
const scrollPositionRef = useRef(0);
|
const scrollPositionRef = useRef(0);
|
||||||
|
|
||||||
@@ -334,10 +335,16 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
|||||||
};
|
};
|
||||||
}, [searchResults]);
|
}, [searchResults]);
|
||||||
|
|
||||||
|
const handleSliderChange = (newSliderValue) => {
|
||||||
|
setActiveSearchResult(null);
|
||||||
|
setSlider(newSliderValue);
|
||||||
|
};
|
||||||
|
|
||||||
const chooseDuration = (x) => {
|
const chooseDuration = (x) => {
|
||||||
setSubmenu(false);
|
setSubmenu(false);
|
||||||
setSlider([0, x.num]);
|
setSlider([0, x.num]);
|
||||||
setDuration(x);
|
setDuration(x);
|
||||||
|
setActiveSearchResult(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const chooseEnd = (x) => {
|
const chooseEnd = (x) => {
|
||||||
@@ -345,42 +352,49 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
|||||||
const newEnd = x.add(...duration.delta);
|
const newEnd = x.add(...duration.delta);
|
||||||
setSlider([0, duration.num]);
|
setSlider([0, duration.num]);
|
||||||
setEnd(newEnd);
|
setEnd(newEnd);
|
||||||
|
setActiveSearchResult(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const chooseNow = (x) => {
|
const chooseNow = (x) => {
|
||||||
setSubmenu(false);
|
setSubmenu(false);
|
||||||
setSlider([0, duration.num]);
|
setSlider([0, duration.num]);
|
||||||
setEnd(moment());
|
setEnd(moment());
|
||||||
|
setActiveSearchResult(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const chooseMidnight = () => {
|
const chooseMidnight = () => {
|
||||||
setSubmenu(false);
|
setSubmenu(false);
|
||||||
setSlider([0, duration.num]);
|
setSlider([0, duration.num]);
|
||||||
setEnd(prevEnd => moment(prevEnd).startOf('day'));
|
setEnd(prevEnd => moment(prevEnd).startOf('day'));
|
||||||
|
setActiveSearchResult(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const rangeStart = (x) => {
|
const rangeStart = (x) => {
|
||||||
setSubmenu(false);
|
setSubmenu(false);
|
||||||
setEnd(moment(range[0]).add(...duration.delta));
|
setEnd(moment(range[0]).add(...duration.delta));
|
||||||
setSlider([0, duration.num]);
|
setSlider([0, duration.num]);
|
||||||
|
setActiveSearchResult(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const rangeEnd = (x) => {
|
const rangeEnd = (x) => {
|
||||||
setSubmenu(false);
|
setSubmenu(false);
|
||||||
setEnd(moment(range[1]));
|
setEnd(moment(range[1]));
|
||||||
setSlider([0, duration.num]);
|
setSlider([0, duration.num]);
|
||||||
|
setActiveSearchResult(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const next = () => {
|
const next = () => {
|
||||||
setSubmenu(false);
|
setSubmenu(false);
|
||||||
setSlider([0, duration.num]);
|
setSlider([0, duration.num]);
|
||||||
setEnd(prevEnd => moment(prevEnd).add(...duration.delta));
|
setEnd(prevEnd => moment(prevEnd).add(...duration.delta));
|
||||||
|
setActiveSearchResult(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
const prev = () => {
|
const prev = () => {
|
||||||
setSubmenu(false);
|
setSubmenu(false);
|
||||||
setSlider([0, duration.num]);
|
setSlider([0, duration.num]);
|
||||||
setEnd(prevEnd => moment(prevEnd).subtract(...duration.delta));
|
setEnd(prevEnd => moment(prevEnd).subtract(...duration.delta));
|
||||||
|
setActiveSearchResult(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
const resetToDefaults = () => {
|
const resetToDefaults = () => {
|
||||||
@@ -492,6 +506,7 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
|||||||
{ params: params }
|
{ params: params }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
setActiveSearchResult(null);
|
||||||
setSearchResults(res.data);
|
setSearchResults(res.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error during area search:', error);
|
console.error('Error during area search:', error);
|
||||||
@@ -501,6 +516,35 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const selectSearchResult = (result) => {
|
||||||
|
const resultStart = moment.unix(result.start);
|
||||||
|
const resultEnd = moment.unix(result.end);
|
||||||
|
const resultDurationSeconds = result.end - result.start;
|
||||||
|
|
||||||
|
// Find the best duration that fits the search result
|
||||||
|
let bestDuration = durations.find(d => resultDurationSeconds <= moment.duration(...d.delta).asSeconds());
|
||||||
|
if (!bestDuration) {
|
||||||
|
bestDuration = durations[durations.length - 1]; // Default to the largest duration if none fit
|
||||||
|
}
|
||||||
|
|
||||||
|
setDuration(bestDuration);
|
||||||
|
|
||||||
|
// Set the end of the window to be the end of the search result for simplicity
|
||||||
|
const newEnd = resultEnd;
|
||||||
|
setEnd(newEnd);
|
||||||
|
|
||||||
|
// Calculate the new slider positions based on the new duration and end time
|
||||||
|
const newSliderStart = (resultStart.unix() - newEnd.unix()) / bestDuration.secs + bestDuration.num;
|
||||||
|
const newSliderEnd = (resultEnd.unix() - newEnd.unix()) / bestDuration.secs + bestDuration.num;
|
||||||
|
|
||||||
|
// Clamp values to be within the slider's bounds [0, duration.num]
|
||||||
|
const clampedStart = Math.max(0, Math.floor(newSliderStart));
|
||||||
|
const clampedEnd = Math.min(bestDuration.num, Math.ceil(newSliderEnd));
|
||||||
|
|
||||||
|
setSlider([clampedStart, clampedEnd]);
|
||||||
|
setActiveSearchResult({ start: result.start, end: result.end });
|
||||||
|
};
|
||||||
|
|
||||||
const range = parseSlider(end, duration, slider);
|
const range = parseSlider(end, duration, slider);
|
||||||
const startDate = moment(end).subtract(...duration.delta);
|
const startDate = moment(end).subtract(...duration.delta);
|
||||||
|
|
||||||
@@ -600,7 +644,7 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
|||||||
min={0}
|
min={0}
|
||||||
max={duration.num}
|
max={duration.num}
|
||||||
value={slider}
|
value={slider}
|
||||||
onInput={setSlider}
|
onInput={handleSliderChange}
|
||||||
onThumbDragStart={() => setShowRange(true)}
|
onThumbDragStart={() => setShowRange(true)}
|
||||||
onThumbDragEnd={() => setShowRange(false)}
|
onThumbDragEnd={() => setShowRange(false)}
|
||||||
onRangeDragStart={() => setShowRange(true)}
|
onRangeDragStart={() => setShowRange(true)}
|
||||||
@@ -660,7 +704,7 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
|||||||
<div className='submenu-header'>
|
<div className='submenu-header'>
|
||||||
<h2>{searchResults ? 'Search Results' : 'Misc'}</h2>
|
<h2>{searchResults ? 'Search Results' : 'Misc'}</h2>
|
||||||
{searchResults ? (
|
{searchResults ? (
|
||||||
<button onClick={() => setSearchResults(null)}>< Back</button>
|
<button onClick={() => { setSearchResults(null); setActiveSearchResult(null); }}>< Back</button>
|
||||||
) : (
|
) : (
|
||||||
<button onClick={() => setSubmenu(false)}>×</button>
|
<button onClick={() => setSubmenu(false)}>×</button>
|
||||||
)}
|
)}
|
||||||
@@ -695,7 +739,11 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
|||||||
<div key={groupKey}>
|
<div key={groupKey}>
|
||||||
<h3 style={{ color: 'white', margin: '0.5em 0 0.25em', fontSize: '1em', fontWeight: 'normal', textAlign: 'center' }}>{groupKey}</h3>
|
<h3 style={{ color: 'white', margin: '0.5em 0 0.25em', fontSize: '1em', fontWeight: 'normal', textAlign: 'center' }}>{groupKey}</h3>
|
||||||
{results.map((result, index) => (
|
{results.map((result, index) => (
|
||||||
<button key={index}>
|
<button
|
||||||
|
key={index}
|
||||||
|
onClick={() => selectSearchResult(result)}
|
||||||
|
className={activeSearchResult && activeSearchResult.start === result.start && activeSearchResult.end === result.end ? 'active' : ''}
|
||||||
|
>
|
||||||
{formatShortTime(result.start)} - {formatShortTime(result.end)}
|
{formatShortTime(result.start)} - {formatShortTime(result.end)}
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
|
|||||||
Reference in New Issue
Block a user