feat: restrict date navigation within shared link range

This commit is contained in:
2025-08-15 01:18:18 +00:00
parent a568bf2f57
commit fa53b50fbf

View File

@@ -274,7 +274,7 @@ function Map({end, duration, slider, mapState, setMapState, setSubmenu, showDire
);
}
function Menu({duration, setDuration, end, setEnd, slider, setSlider, submenu, setSubmenu, showDirection, setShowDirection, setMapState}) {
function Menu({duration, setDuration, end, setEnd, slider, setSlider, submenu, setSubmenu, showDirection, setShowDirection, setMapState, shareStart, shareEnd}) {
const [showRange, setShowRange] = useState(false);
const chooseDuration = (x) => {
@@ -338,6 +338,22 @@ function Menu({duration, setDuration, end, setEnd, slider, setSlider, submenu, s
const range = parseSlider(end, duration, slider);
const startDate = moment(end).subtract(...duration.delta);
const isPrevDisabled = shareStart ? moment(startDate).subtract(...duration.delta).isBefore(shareStart) : false;
const isNextDisabled = shareEnd ? moment(end).add(...duration.delta).isAfter(shareEnd) : false;
const isValidDate = (current) => {
if (!shareStart || !shareEnd) {
return true;
}
const proposedStartDate = moment(current).startOf('day');
const proposedEndDate = moment(proposedStartDate).add(...duration.delta);
const isAfterOrOnShareStart = proposedStartDate.isSameOrAfter(shareStart, 'day');
const isBeforeOrOnShareEnd = proposedEndDate.isSameOrBefore(shareEnd, 'day');
return isAfterOrOnShareStart && isBeforeOrOnShareEnd;
};
const shareRange = async () => {
const shareStart = moment(range[0]).unix();
const shareEnd = moment(range[1]).unix();
@@ -442,6 +458,7 @@ function Menu({duration, setDuration, end, setEnd, slider, setSlider, submenu, s
timeFormat={false}
onChange={(x) => chooseEnd(x)}
value={startDate}
isValidDate={isValidDate}
/>
</div>
@@ -496,7 +513,7 @@ function Menu({duration, setDuration, end, setEnd, slider, setSlider, submenu, s
}
<div className='menu-container'>
<button onClick={() => prev()}>&lt;</button>
<button onClick={() => prev()} disabled={isPrevDisabled}>&lt;</button>
<button
onClick={() => setSubmenu('end')}
@@ -519,7 +536,7 @@ function Menu({duration, setDuration, end, setEnd, slider, setSlider, submenu, s
{(duration.shortLen || duration.len)} / {duration.win}
</button>
<button onClick={() => next()}>&gt;</button>
<button onClick={() => next()} disabled={isNextDisabled}>&gt;</button>
</div>
</div>
);
@@ -534,6 +551,8 @@ function App() {
const initialLng = params.get('lng');
const initialZoom = params.get('zoom');
const initialShowDirection = params.get('showDirection') === 'true';
const shareStartParam = params.get('shareStart');
const shareEndParam = params.get('shareEnd');
const initialDuration = (initialDurationId && durations[parseInt(initialDurationId, 10)]) ? durations[parseInt(initialDurationId, 10)] : durations[0];
const initialEnd = initialEndTimestamp ? moment.unix(initialEndTimestamp) : moment();
@@ -549,6 +568,9 @@ function App() {
const [submenu, setSubmenu] = useState(false);
const [showDirection, setShowDirection] = useState(initialShowDirection);
const shareStart = shareStartParam ? moment.unix(shareStartParam) : null;
const shareEnd = shareEndParam ? moment.unix(shareEndParam) : null;
const isInitialMount = useRef(true);
useEffect(() => {
if (isInitialMount.current) {
@@ -595,6 +617,8 @@ function App() {
showDirection={showDirection}
setShowDirection={setShowDirection}
setMapState={setMapState}
shareStart={shareStart}
shareEnd={shareEnd}
/>
<Map