From 6cc3ca266621aa02b1ca6ee74dac4dccb63682fa Mon Sep 17 00:00:00 2001 From: Lorenzo Natali Date: Tue, 11 May 2021 16:04:16 +0200 Subject: [PATCH] #6830. Disable URL update on initial scroll (#6835) * #6830. Disable URL update on initial scroll * add test and externalize actions (#31) * parametrize delay (#32) * Fixed lint Co-authored-by: Matteo V --- web/client/actions/__tests__/geostory-test.js | 9 ++++- web/client/actions/geostory.js | 3 ++ web/client/epics/__tests__/geostory-test.js | 28 ++++++++++++- web/client/epics/geostory.js | 40 ++++++++++++++----- 4 files changed, 67 insertions(+), 13 deletions(-) diff --git a/web/client/actions/__tests__/geostory-test.js b/web/client/actions/__tests__/geostory-test.js index 1028bb99d0..4240315418 100644 --- a/web/client/actions/__tests__/geostory-test.js +++ b/web/client/actions/__tests__/geostory-test.js @@ -51,10 +51,17 @@ import { updateSetting, removeResource, REMOVE_RESOURCE, updateUrlOnScroll, SET_UPDATE_URL_SCROLL, - updateMediaEditorSettings + updateMediaEditorSettings, + geostoryScrolling, + GEOSTORY_SCROLLING } from '../geostory'; describe('test geostory action creators', () => { + it('geostoryScrolling', () => { + const status = true; + const action = geostoryScrolling(status); + expect(action).toEqual({type: GEOSTORY_SCROLLING, status}); + }); it('clearSaveError', () => { const action = clearSaveError(); expect(action.type).toBe(CLEAR_SAVE_ERROR); diff --git a/web/client/actions/geostory.js b/web/client/actions/geostory.js index a1672a7020..55ca8cf4bc 100644 --- a/web/client/actions/geostory.js +++ b/web/client/actions/geostory.js @@ -17,6 +17,7 @@ export const EDIT_RESOURCE = "GEOSTORY:EDIT_RESOURCE"; export const EDIT_WEBPAGE = "GEOSTORY:EDIT_WEBPAGE"; export const ERRORS_LOGO = "GEOSTORY:ERRORS_LOGO"; export const GEOSTORY_LOADED = "GEOSTORY:GEOSTORY_LOADED"; +export const GEOSTORY_SCROLLING = "GEOSTORY:SCROLLING"; export const LOAD_GEOSTORY = "GEOSTORY:LOAD_GEOSTORY"; export const LOAD_GEOSTORY_ERROR = "GEOSTORY:LOAD_GEOSTORY_ERROR"; export const LOADING_GEOSTORY = "GEOSTORY:LOADING_GEOSTORY"; @@ -241,3 +242,5 @@ export const setPendingChanges = value => ({type: SET_PENDING_CHANGES, value}); export const updateUrlOnScroll = value => ({type: SET_UPDATE_URL_SCROLL, value}); export const updateMediaEditorSettings = mediaEditorSettings => ({ type: UPDATE_MEDIA_EDITOR_SETTINGS, mediaEditorSettings }); + +export const geostoryScrolling = (status) => ({ type: GEOSTORY_SCROLLING, status}); diff --git a/web/client/epics/__tests__/geostory-test.js b/web/client/epics/__tests__/geostory-test.js index 6602f89090..df9a2531f0 100644 --- a/web/client/epics/__tests__/geostory-test.js +++ b/web/client/epics/__tests__/geostory-test.js @@ -32,13 +32,17 @@ import { openWebPageComponentCreator, editWebPageComponent, handlePendingGeoStoryChanges, - loadStoryOnHistoryPop + loadStoryOnHistoryPop, + scrollOnLoad, + urlUpdateOnScroll } from '../geostory'; import { ADD, LOADING_GEOSTORY, loadGeostory, SET_CURRENT_STORY, + setCurrentStory, + GEOSTORY_SCROLLING, LOAD_GEOSTORY_ERROR, add, UPDATE, @@ -57,7 +61,8 @@ import { editWebPage, setResource, SET_PENDING_CHANGES, - LOAD_GEOSTORY + LOAD_GEOSTORY, + updateCurrentPage } from '../../actions/geostory'; import { SET_CONTROL_PROPERTY } from '../../actions/controls'; import { @@ -1630,6 +1635,25 @@ describe('Geostory Epics', () => { }); }); + it('urlUpdateOnScroll', (done) => { + const NUM_ACTIONS = 1; + testEpic(addTimeoutEpic(urlUpdateOnScroll, 100), NUM_ACTIONS, [updateCurrentPage({sectionId: "sectionId"})], + (actions) => { + expect(actions[0].type).toBe(TEST_TIMEOUT); + done(); + }, {geostory: {mode: "view", updateUrlOnScroll: true, resource: {id: "1"}}}); + }); + it('scrollOnLoad', (done) => { + const NUM_ACTIONS = 2; + testEpic(scrollOnLoad, NUM_ACTIONS, setCurrentStory({}), + (actions) => { + expect(actions[0].type).toBe(GEOSTORY_SCROLLING); + expect(actions[0].status).toBe(true); + expect(actions[1].type).toBe(GEOSTORY_SCROLLING); + expect(actions[1].status).toBe(false); + done(); + }); + }); describe('loadStoryOnHistoryPop', () => { it('loadStoryOnHistoryPop without shared', (done) => { const NUM_ACTIONS = 1; diff --git a/web/client/epics/geostory.js b/web/client/epics/geostory.js index dbf0505548..e0a06670cf 100644 --- a/web/client/epics/geostory.js +++ b/web/client/epics/geostory.js @@ -17,6 +17,7 @@ import words from 'lodash/words'; import get from 'lodash/get'; import isArray from 'lodash/isArray'; import isEmpty from 'lodash/isEmpty'; + import { push, LOCATION_CHANGE } from 'connected-react-router'; import uuid from 'uuid/v1'; @@ -56,7 +57,9 @@ import { EDIT_RESOURCE, UPDATE_CURRENT_PAGE, UPDATE_SETTING, - SET_CURRENT_STORY + SET_CURRENT_STORY, + geostoryScrolling, + GEOSTORY_SCROLLING } from '../actions/geostory'; import { setControlProperty } from '../actions/controls'; @@ -503,6 +506,12 @@ export const handlePendingGeoStoryChanges = action$ => ) ); +const semaphore = (sem$, start = true, condition = (c) => c) => (stream$) => + stream$ + .withLatestFrom(sem$.startWith(start)) + .filter(([, s]) => condition(s)) + .map(([e]) => e); + /** * Handle the url updates on currentPage change * @param {Observable} action$ stream of actions @@ -510,6 +519,10 @@ export const handlePendingGeoStoryChanges = action$ => */ export const urlUpdateOnScroll = (action$, {getState}) => action$.ofType(UPDATE_CURRENT_PAGE) + .let(semaphore( + action$.ofType(GEOSTORY_SCROLLING) + .map(a => !a.value) + )) .debounceTime(50) // little delay if too many UPDATE_CURRENT_PAGE actions come .switchMap(({sectionId, columnId}) => { if ( @@ -531,16 +544,23 @@ export const urlUpdateOnScroll = (action$, {getState}) => */ export const scrollOnLoad = (action$) => action$.ofType(SET_CURRENT_STORY) - .switchMap(() => { + .switchMap(({delay = 500}) => { const storyIds = window?.location?.hash?.split('/'); - if (window?.location?.hash?.includes('shared')) { - scrollToContent(storyIds[7] || storyIds[5], {block: "start", behavior: "auto"}); - } else if (storyIds.length > 5) { - scrollToContent(storyIds[6], {block: "start", behavior: "auto"}); - } else if (storyIds.length === 5) { - scrollToContent(storyIds[4], {block: 'start', behavior: "auto"}); - } - return Observable.empty(); + return Observable.of(storyIds) + .delay(delay) + .do(() => { + if (window?.location?.hash?.includes('shared')) { + scrollToContent(storyIds[7] || storyIds[5], {block: "start", behavior: "auto"}); + } else if (storyIds.length > 5) { + scrollToContent(storyIds[6], {block: "start", behavior: "auto"}); + } else if (storyIds.length === 5) { + scrollToContent(storyIds[4], {block: 'start', behavior: "auto"}); + } + } + ) + .ignoreElements() + .startWith(geostoryScrolling(true)) + .concat(Observable.of(geostoryScrolling(false)).delay(delay)); }); /**