diff --git a/web/client/actions/geostory.js b/web/client/actions/geostory.js index b3de1a5b20..d2aecd24e8 100644 --- a/web/client/actions/geostory.js +++ b/web/client/actions/geostory.js @@ -166,12 +166,14 @@ export const toggleSettingsPanel = (withSave = false) => ({ type: TOGGLE_SETTING * @param {string} path the path of the element to modify. It can contain path like this `sections[{"id": "abc"}].contents[{"id": "def"}]` to resolve the predicate between brackets. * @param {object} element the object to update * @param {string|object} [mode="replace"] "merge" or "replace", if "merge", the object passed as element will be merged with the original one (if present and if it is an object) + * @param {object} "uniquebykey" or "undefined", if "uniquebykey" via merge mode, the key will be checked to avoid duplication of fonts */ -export const update = (path, element, mode = "replace") => ({ +export const update = (path, element, mode = "replace", options) => ({ type: UPDATE, path, element, - mode + mode, + options }); /** * updates the current page with current value of sectionId (future can be extended adding other info about current content). diff --git a/web/client/configs/localConfig.json b/web/client/configs/localConfig.json index b01959f586..50d7b92284 100644 --- a/web/client/configs/localConfig.json +++ b/web/client/configs/localConfig.json @@ -897,7 +897,33 @@ "Attribution", "Home", { - "name": "GeoStory" + "name": "GeoStory", + "cfg": { + "fontFamilies": [ + { + "family": "Arial" + }, + { + "family": "Georgia" + }, + { + "family": "Impact" + }, + { + "family": "Tahoma" + }, + { + "family": "Times New Roman" + }, + { + "family": "Titillium Web", + "src": "https://fonts.googleapis.com/css2?family=Titillium+Web" + }, + { + "family": "Verdana" + } + ] + } }, { "name": "DeleteGeoStory" }, { "name": "GeoStoryExport" }, diff --git a/web/client/plugins/GeoStory.jsx b/web/client/plugins/GeoStory.jsx index 08bfde2b3b..7df356f398 100644 --- a/web/client/plugins/GeoStory.jsx +++ b/web/client/plugins/GeoStory.jsx @@ -71,7 +71,8 @@ const GeoStory = ({ }, []); useEffect(() => { - onUpdate("settings.theme.fontFamilies", fontFamilies, "merge"); + // Appended options in actions for key handling to avoid fonts duplication + onUpdate("settings.theme.fontFamilies", fontFamilies, "merge", {uniqueByKey: "family"}); // we need to store settings for media editor // so we could use them later when we open the media editor plugin if (mediaEditorSettings) { diff --git a/web/client/plugins/__tests__/GeoStory-test.jsx b/web/client/plugins/__tests__/GeoStory-test.jsx index 70c09c1fbf..cc4e181305 100644 --- a/web/client/plugins/__tests__/GeoStory-test.jsx +++ b/web/client/plugins/__tests__/GeoStory-test.jsx @@ -41,6 +41,15 @@ describe('GeoStory Plugin', () => { expect(actions.length).toEqual(1); expect(store.getState().geostory.currentStory.settings.theme.fontFamilies).toEqual(fontFamilies); }); + it('Dispatches update action, sets fontFamilies in merge mode', () => { + const { Plugin, actions, store } = getPluginForTest(GeoStory, stateMocker({geostory})); + const fontFamilies = [{family: "test", src: "test"}]; + ReactDOM.render(<Plugin webFont={{load: () => {}}} mode="merge" fontFamilies={fontFamilies} />, document.getElementById("container")); + + // expect to have dispatched update action once from useEffect(callback, []) + expect(actions.length).toBe(1); + expect(store.getState().geostory.currentStory.settings.theme.fontFamilies).toEqual(fontFamilies); + }); it('should store the media editor setting with onUpdateMediaEditorSetting', () => { const { Plugin, actions, store } = getPluginForTest(GeoStory, stateMocker({geostory})); const mediaEditorSettings = { diff --git a/web/client/reducers/geostory.js b/web/client/reducers/geostory.js index 2f8c5822cb..0df27c5b7a 100644 --- a/web/client/reducers/geostory.js +++ b/web/client/reducers/geostory.js @@ -306,7 +306,7 @@ export default (state = INITIAL_STATE, action) => { )(state); } case UPDATE: { - const { path: rawPath, mode } = action; + const { path: rawPath, mode, options } = action; let { element: newElement } = action; const path = getEffectivePath(`currentStory.${rawPath}`, state); const oldElement = get(state, path); @@ -317,7 +317,8 @@ export default (state = INITIAL_STATE, action) => { } if (isArray(oldElement) && isArray(newElement) && mode === "merge") { - newElement = [ ...oldElement, ...newElement ]; + // check for options to filter unique options + newElement = (options?.uniqueByKey) ? uniqBy([ ...oldElement, ...newElement ], options.uniqueByKey) : [...oldElement, ...newElement ]; } return set(path, newElement, state); }