From 7dfebf037014f3a36d010e09bb5a6f83e5304a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojtek=20Ba=C5=BCant?= Date: Sun, 10 Nov 2024 22:03:54 +0000 Subject: [PATCH] Go back from settings to location / edit location / review / map (#545) * Go back from settings to location / edit location / review / map * Only 'back from settings' for location if opened through map Opening location page through back button shouldn't count because then we have an infinite loop --- src/components/connect/ConnectLocation.js | 8 ++++++ src/components/connect/DisconnectReview.js | 19 +++++++++++++ src/components/connect/connectRoutes.js | 13 +++++++++ src/components/desktop/SidePane.js | 31 +++++++++++++++++++--- src/components/map/MapPage.js | 9 ++++--- src/redux/locationSlice.js | 5 ++++ src/redux/reviewSlice.js | 9 ++++++- 7 files changed, 86 insertions(+), 8 deletions(-) create mode 100644 src/components/connect/DisconnectReview.js diff --git a/src/components/connect/ConnectLocation.js b/src/components/connect/ConnectLocation.js index e1521bf2b..e286d7629 100644 --- a/src/components/connect/ConnectLocation.js +++ b/src/components/connect/ConnectLocation.js @@ -3,6 +3,7 @@ import { useDispatch, useSelector } from 'react-redux' import { fetchLocationData, + setFromSettings, setIsBeingEditedAndResetPosition, setStreetView, } from '../../redux/locationSlice' @@ -73,6 +74,13 @@ const ConnectLocation = ({ dispatch(setStreetView(isStreetView)) }, [dispatch, isStreetView]) + useEffect( + () => () => { + dispatch(setFromSettings(false)) + }, + [dispatch, locationId], + ) + useEffect(() => { if ( isBeingEdited && diff --git a/src/components/connect/DisconnectReview.js b/src/components/connect/DisconnectReview.js new file mode 100644 index 000000000..3f519c1ec --- /dev/null +++ b/src/components/connect/DisconnectReview.js @@ -0,0 +1,19 @@ +import { useEffect } from 'react' +import { useDispatch, useSelector } from 'react-redux' + +import { clearReview } from '../../redux/reviewSlice' + +const DisconnectReview = () => { + const dispatch = useDispatch() + const { review } = useSelector((state) => state.review) + + useEffect(() => { + if (review) { + dispatch(clearReview()) + } + }, [dispatch, review?.id]) //eslint-disable-line + + return null +} + +export default DisconnectReview diff --git a/src/components/connect/connectRoutes.js b/src/components/connect/connectRoutes.js index b3f2a3fc6..e50e2c52c 100644 --- a/src/components/connect/connectRoutes.js +++ b/src/components/connect/connectRoutes.js @@ -9,6 +9,7 @@ import ConnectPath from './ConnectPath' import ConnectReview from './ConnectReview' import ConnectTypes from './ConnectTypes' import DisconnectLocation from './DisconnectLocation' +import DisconnectReview from './DisconnectReview' const connectRoutes = [ /* @@ -71,6 +72,7 @@ const connectRoutes = [ * - on mobile, we need to center the map on the edited location because the UX involves panning the map on central pin * - on mobile, we need to disable the drawer when arriving from list view * - on mobile, the drawer needs the user scrolling up and down + * - on desktop, clicking location from a settings page should make 'back' go to settings instead if map * * actions: * - fetch data from backend @@ -80,6 +82,7 @@ const connectRoutes = [ * - on mobile, center and zoom on edited location * - on mobile, keep track of whether we arrived via list-locations URL * - on mobile, disable default overscroll (e.g. a refresh on scroll down in Chrome) + * - on desktop, reset the isFromSettings flag when leaving location */ } , + + /* + * DisconnectReview + * why: if we start editing the review and then go back to location or to the map, and then open settings, the back button should not take us to the abandoned review + * + * action: clear review in Redux + */ + + {({ match }) => match && } + , ] export default connectRoutes diff --git a/src/components/desktop/SidePane.js b/src/components/desktop/SidePane.js index 2582c0a94..7eeb48b44 100644 --- a/src/components/desktop/SidePane.js +++ b/src/components/desktop/SidePane.js @@ -46,14 +46,20 @@ const SidePane = () => { const history = useAppHistory() const { t } = useTranslation() const { review } = useSelector((state) => state.review) + const { + locationId, + isBeingEdited: isEditingLocation, + fromSettings, + } = useSelector((state) => state.location) const goToMap = (event) => { event.stopPropagation() history.push('/map') } - const goBack = (event) => { + + const goToSettings = (event) => { event.stopPropagation() - history.goBack() + history.push('/settings') } return ( @@ -110,7 +116,22 @@ const SidePane = () => { - + { + event.stopPropagation() + if (review) { + history.push(`/reviews/${review.id}/edit`) + } else if (locationId) { + if (isEditingLocation) { + history.push(`/locations/${locationId}/edit`) + } else { + history.push(`/locations/${locationId}`) + } + } else { + history.push('/map') + } + }} + > {t('back')} @@ -123,7 +144,9 @@ const SidePane = () => { match && ( <> - + {t('back')} diff --git a/src/components/map/MapPage.js b/src/components/map/MapPage.js index 47a2862ef..10536537e 100644 --- a/src/components/map/MapPage.js +++ b/src/components/map/MapPage.js @@ -2,12 +2,13 @@ import GoogleMapReact from 'google-map-react' import { useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { useDispatch, useSelector } from 'react-redux' +import { useLocation } from 'react-router-dom' import { toast } from 'react-toastify' import styled from 'styled-components/macro' import { VISIBLE_CLUSTER_ZOOM_LIMIT } from '../../constants/map' import { fetchFilterCounts } from '../../redux/filterSlice' -import { updatePosition } from '../../redux/locationSlice' +import { setFromSettings, updatePosition } from '../../redux/locationSlice' import { setGoogle } from '../../redux/mapSlice' import { fetchLocations } from '../../redux/viewChange' import { updateLastMapView } from '../../redux/viewportSlice' @@ -168,6 +169,7 @@ const MapPage = ({ isDesktop }) => { const { geolocation, geolocationState } = useSelector( (state) => state.geolocation, ) + const { pathname } = useLocation() const { locationId, position, @@ -247,9 +249,10 @@ const MapPage = ({ isDesktop }) => { } const handleLocationClick = (location) => { - if (!isAddingLocation && !isEditingLocation) { - history.push(`/locations/${location.id}`) + if (isDesktop && pathname.includes('/settings')) { + dispatch(setFromSettings(true)) } + history.push(`/locations/${location.id}`) } const handleNonspecificClick = ({ event }) => { diff --git a/src/redux/locationSlice.js b/src/redux/locationSlice.js index f6689b366..6b7b16571 100644 --- a/src/redux/locationSlice.js +++ b/src/redux/locationSlice.js @@ -59,6 +59,7 @@ const locationSlice = createSlice({ position: null, // {lat: number, lng: number} locationId: null, isBeingEdited: false, + fromSettings: false, form: null, tooltipOpen: false, streetViewOpen: false, @@ -151,6 +152,9 @@ const locationSlice = createSlice({ setTabIndex: (state, action) => { state.pane.tabIndex = action.payload }, + setFromSettings: (state, action) => { + state.fromSettings = action.payload + }, }, extraReducers: { [updateLastMapView]: (state, action) => { @@ -271,6 +275,7 @@ export const { setTabIndex, fullyOpenPaneDrawer, partiallyClosePaneDrawer, + setFromSettings, } = locationSlice.actions export default locationSlice.reducer diff --git a/src/redux/reviewSlice.js b/src/redux/reviewSlice.js index 99a43ba0d..6aaa5e018 100644 --- a/src/redux/reviewSlice.js +++ b/src/redux/reviewSlice.js @@ -14,10 +14,15 @@ export const fetchReviewData = createAsyncThunk( const reviewSlice = createSlice({ name: 'review', initialState: { - reviewId: null, isLoading: false, review: null, }, + reducers: { + clearReview: (state) => { + state.isLoading = false + state.review = null + }, + }, extraReducers: { [fetchReviewData.pending]: (state) => { state.isLoading = true @@ -35,4 +40,6 @@ const reviewSlice = createSlice({ }, }) +export const { clearReview } = reviewSlice.actions + export default reviewSlice.reducer