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 [isSearching, setIsSearching] = useState(false);
|
||||
const [searchResults, setSearchResults] = useState(null);
|
||||
const [activeSearchResult, setActiveSearchResult] = useState(null);
|
||||
const scrollContainerRef = useRef(null);
|
||||
const scrollPositionRef = useRef(0);
|
||||
|
||||
@@ -334,10 +335,16 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
||||
};
|
||||
}, [searchResults]);
|
||||
|
||||
const handleSliderChange = (newSliderValue) => {
|
||||
setActiveSearchResult(null);
|
||||
setSlider(newSliderValue);
|
||||
};
|
||||
|
||||
const chooseDuration = (x) => {
|
||||
setSubmenu(false);
|
||||
setSlider([0, x.num]);
|
||||
setDuration(x);
|
||||
setActiveSearchResult(null);
|
||||
};
|
||||
|
||||
const chooseEnd = (x) => {
|
||||
@@ -345,42 +352,49 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
||||
const newEnd = x.add(...duration.delta);
|
||||
setSlider([0, duration.num]);
|
||||
setEnd(newEnd);
|
||||
setActiveSearchResult(null);
|
||||
};
|
||||
|
||||
const chooseNow = (x) => {
|
||||
setSubmenu(false);
|
||||
setSlider([0, duration.num]);
|
||||
setEnd(moment());
|
||||
setActiveSearchResult(null);
|
||||
};
|
||||
|
||||
const chooseMidnight = () => {
|
||||
setSubmenu(false);
|
||||
setSlider([0, duration.num]);
|
||||
setEnd(prevEnd => moment(prevEnd).startOf('day'));
|
||||
setActiveSearchResult(null);
|
||||
};
|
||||
|
||||
const rangeStart = (x) => {
|
||||
setSubmenu(false);
|
||||
setEnd(moment(range[0]).add(...duration.delta));
|
||||
setSlider([0, duration.num]);
|
||||
setActiveSearchResult(null);
|
||||
};
|
||||
|
||||
const rangeEnd = (x) => {
|
||||
setSubmenu(false);
|
||||
setEnd(moment(range[1]));
|
||||
setSlider([0, duration.num]);
|
||||
setActiveSearchResult(null);
|
||||
};
|
||||
|
||||
const next = () => {
|
||||
setSubmenu(false);
|
||||
setSlider([0, duration.num]);
|
||||
setEnd(prevEnd => moment(prevEnd).add(...duration.delta));
|
||||
setActiveSearchResult(null);
|
||||
}
|
||||
|
||||
const prev = () => {
|
||||
setSubmenu(false);
|
||||
setSlider([0, duration.num]);
|
||||
setEnd(prevEnd => moment(prevEnd).subtract(...duration.delta));
|
||||
setActiveSearchResult(null);
|
||||
}
|
||||
|
||||
const resetToDefaults = () => {
|
||||
@@ -492,6 +506,7 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
||||
{ params: params }
|
||||
);
|
||||
|
||||
setActiveSearchResult(null);
|
||||
setSearchResults(res.data);
|
||||
} catch (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 startDate = moment(end).subtract(...duration.delta);
|
||||
|
||||
@@ -600,7 +644,7 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
||||
min={0}
|
||||
max={duration.num}
|
||||
value={slider}
|
||||
onInput={setSlider}
|
||||
onInput={handleSliderChange}
|
||||
onThumbDragStart={() => setShowRange(true)}
|
||||
onThumbDragEnd={() => setShowRange(false)}
|
||||
onRangeDragStart={() => setShowRange(true)}
|
||||
@@ -660,7 +704,7 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
||||
<div className='submenu-header'>
|
||||
<h2>{searchResults ? 'Search Results' : 'Misc'}</h2>
|
||||
{searchResults ? (
|
||||
<button onClick={() => setSearchResults(null)}>< Back</button>
|
||||
<button onClick={() => { setSearchResults(null); setActiveSearchResult(null); }}>< Back</button>
|
||||
) : (
|
||||
<button onClick={() => setSubmenu(false)}>×</button>
|
||||
)}
|
||||
@@ -695,7 +739,11 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
||||
<div key={groupKey}>
|
||||
<h3 style={{ color: 'white', margin: '0.5em 0 0.25em', fontSize: '1em', fontWeight: 'normal', textAlign: 'center' }}>{groupKey}</h3>
|
||||
{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)}
|
||||
</button>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user