diff --git a/src/actions/index.js b/src/actions/index.js index c523161df..ad220a166 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -148,7 +148,7 @@ export function urlForState(dongleId, log_id, start, end, prime) { if (log_id) { path.push(log_id); - if (start && end && start > 0) { + if (start != null && end != null && start !== end) { path.push(start); path.push(end); } @@ -160,14 +160,22 @@ export function urlForState(dongleId, log_id, start, end, prime) { } function updateTimeline(state, dispatch, log_id, start, end, allowPathChange) { - if (!state.loop || !state.loop.startTime || !state.loop.duration || state.loop.startTime < start - || state.loop.startTime + state.loop.duration > end || state.loop.duration < end - start) { + const route = state.routes?.find((r) => r.log_id === log_id); + const loopStart = start ?? 0; + const loopEnd = end ?? route?.duration; + + if (loopEnd != null && (!state.loop || !state.loop.duration + || state.loop.startTime < loopStart || state.loop.startTime + state.loop.duration > loopEnd + || state.loop.duration < loopEnd - loopStart)) { dispatch(resetPlayback()); - dispatch(selectLoop(start, end)); + dispatch(selectLoop(loopStart, loopEnd)); } if (allowPathChange) { - const desiredPath = urlForState(state.dongleId, log_id, Math.floor(start/1000), Math.floor(end/1000), false); + const wholeRoute = start == null || (start === 0 && end === route?.duration); + const urlStart = wholeRoute ? null : Math.floor(start / 1000); + const urlEnd = wholeRoute ? null : Math.floor(end / 1000); + const desiredPath = urlForState(state.dongleId, log_id, urlStart, urlEnd, false); if (window.location.pathname !== desiredPath) { dispatch(push(desiredPath)); } @@ -189,6 +197,8 @@ export function popTimelineRange(log_id, allowPathChange = true) { } export function pushTimelineRange(log_id, start, end, allowPathChange = true) { + if (!Number.isFinite(start)) start = null; + if (!Number.isFinite(end)) end = null; return (dispatch, getState) => { const state = getState(); diff --git a/src/actions/index.test.js b/src/actions/index.test.js index 133accf52..8962fcfb7 100644 --- a/src/actions/index.test.js +++ b/src/actions/index.test.js @@ -23,6 +23,6 @@ describe('timeline actions', () => { zoom: {}, })); actionThunk(dispatch, getState); - expect(push).toBeCalledWith('/statedongle/log_id'); + expect(push).toBeCalledWith('/statedongle/log_id/0/1'); }); }); \ No newline at end of file diff --git a/src/components/Dashboard/DriveListItem.jsx b/src/components/Dashboard/DriveListItem.jsx index 00f42ccaf..aa4204f7c 100644 --- a/src/components/Dashboard/DriveListItem.jsx +++ b/src/components/Dashboard/DriveListItem.jsx @@ -84,7 +84,7 @@ const DriveListItem = (props) => { }, [drive, dispatch, isVisible, el]); const onClick = filterRegularClick( - () => dispatch(pushTimelineRange(drive.log_id, 0, drive.duration, true)), + () => dispatch(pushTimelineRange(drive.log_id, null, null, true)), ); const small = windowWidth < 580; diff --git a/src/reducers/globalState.js b/src/reducers/globalState.js index e0a394c38..1f31f36f5 100644 --- a/src/reducers/globalState.js +++ b/src/reducers/globalState.js @@ -289,7 +289,7 @@ export default function reducer(_state, action) { } break; case Types.TIMELINE_PUSH_SELECTION: { - if (!state.zoom || !action.start || !action.end || action.start < state.zoom.start || action.end > state.zoom.end) { + if (!state.zoom || action.start == null || action.end == null || action.start < state.zoom.start || action.end > state.zoom.end) { state.files = null; } @@ -300,7 +300,7 @@ export default function reducer(_state, action) { const r = state.routes?.find((route) => route.log_id === action.log_id); if (action.log_id && r) { state.currentRoute = r; - if (!action.start) { + if (action.start == null) { state.zoom = { start: 0, end: state.currentRoute.duration,