import { urlFromEnv } from "../common/utilities"; // TODO: relegate these URLs entirely to environment variables // const CONFIG_URL = urlFromEnv('CONFIG_EXT') const EVENT_DATA_URL = urlFromEnv("EVENTS_EXT"); const ASSOCIATIONS_URL = urlFromEnv("ASSOCIATIONS_EXT"); const SOURCES_URL = urlFromEnv("SOURCES_EXT"); const SITES_URL = urlFromEnv("SITES_EXT"); const REGIONS_URL = urlFromEnv("REGIONS_EXT"); const SHAPES_URL = urlFromEnv("SHAPES_EXT"); const domainMsg = (domainType) => `Something went wrong fetching ${domainType}. Check the URL or try disabling them in the config file.`; export function fetchDomain() { const notifications = []; function handleError(message) { notifications.push({ message, type: "error", }); return []; } return (dispatch, getState) => { const features = getState().features; dispatch(toggleFetchingDomain()); // let configPromise = Promise.resolve([]) // if (features.USE_REMOTE_CONFIG) { // configPromise = fetch(CONFIG_URL) // .then(response => response.json()) // .catch(() => handleError("Couldn't find data at the config URL you specified.")) // } // NB: EVENT_DATA_URL is a list, and so results are aggregated const eventPromise = Promise.all( EVENT_DATA_URL.map((url) => fetch(url) .then((response) => response.json()) .catch(() => handleError("events")) ) ).then((results) => results.flatMap((t) => t)); let associationsPromise = Promise.resolve([]); if (features.USE_ASSOCIATIONS) { if (!ASSOCIATIONS_URL) { associationsPromise = Promise.resolve( handleError( "USE_ASSOCIATIONS is true, but you have not provided a ASSOCIATIONS_EXT" ) ); } else { associationsPromise = fetch(ASSOCIATIONS_URL) .then((response) => response.json()) .catch(() => handleError(domainMsg("associations"))); } } let sourcesPromise = Promise.resolve([]); if (features.USE_SOURCES) { if (!SOURCES_URL) { sourcesPromise = Promise.resolve( handleError( "USE_SOURCES is true, but you have not provided a SOURCES_EXT" ) ); } else { sourcesPromise = fetch(SOURCES_URL) .then((response) => response.json()) .catch(() => handleError(domainMsg("sources"))); } } let sitesPromise = Promise.resolve([]); if (features.USE_SITES) { sitesPromise = fetch(SITES_URL) .then((response) => response.json()) .catch(() => handleError(domainMsg("sites"))); } let regionsPromise = Promise.resolve([]); if (features.USE_REGIONS) { regionsPromise = fetch(REGIONS_URL) .then((response) => response.json()) .catch(() => handleError(domainMsg("regions"))); } let shapesPromise = Promise.resolve([]); if (features.USE_SHAPES) { shapesPromise = fetch(SHAPES_URL) .then((response) => response.json()) .catch(() => handleError(domainMsg("shapes"))); } return Promise.all([ eventPromise, associationsPromise, sourcesPromise, sitesPromise, regionsPromise, shapesPromise, ]) .then((response) => { const result = { events: response[0], associations: response[1], sources: response[2], sites: response[3], regions: response[4], shapes: response[5], notifications, }; if ( Object.values(result).some((resp) => resp.hasOwnProperty("error")) ) { throw new Error( "Some URLs returned negative. If you are in development, check the server is running" ); } dispatch(toggleFetchingDomain()); dispatch(setInitialCategories(result.associations)); dispatch(setInitialShapes(result.shapes)); return result; }) .catch((err) => { dispatch(fetchError(err.message)); dispatch(toggleFetchingDomain()); // TODO: handle this appropriately in React hierarchy alert(err.message); }); }; } export const FETCH_ERROR = "FETCH_ERROR"; export function fetchError(message) { return { type: FETCH_ERROR, message, }; } export const UPDATE_DOMAIN = "UPDATE_DOMAIN"; export function updateDomain(payload) { return { type: UPDATE_DOMAIN, payload, }; } export function fetchSource(source) { return (dispatch) => { if (!SOURCES_URL) { dispatch(fetchSourceError("No source extension specified.")); } else { dispatch(toggleFetchingSources()); fetch(`${SOURCES_URL}`) .then((response) => { if (!response.ok) { throw new Error( "No sources are available at the URL specified in the config specified." ); } else { return response.json(); } }) .catch((err) => { dispatch(fetchSourceError(err.message)); dispatch(toggleFetchingSources()); }); } }; } export const UPDATE_HIGHLIGHTED = "UPDATE_HIGHLIGHTED"; export function updateHighlighted(highlighted) { return { type: UPDATE_HIGHLIGHTED, highlighted: highlighted, }; } export const UPDATE_SELECTED = "UPDATE_SELECTED"; export function updateSelected(selected) { return { type: UPDATE_SELECTED, selected: selected, }; } export const UPDATE_DISTRICT = "UPDATE_DISTRICT"; export function updateDistrict(district) { return { type: UPDATE_DISTRICT, district, }; } export const CLEAR_FILTER = "CLEAR_FILTER"; export function clearFilter(filter) { return { type: CLEAR_FILTER, filter, }; } export const TOGGLE_ASSOCIATIONS = "TOGGLE_ASSOCIATIONS"; export function toggleAssociations(association, value, shouldColor) { return { type: TOGGLE_ASSOCIATIONS, association, value, shouldColor, }; } export const TOGGLE_SHAPES = "TOGGLE_SHAPES"; export function toggleShapes(shape) { return { type: TOGGLE_SHAPES, shape, }; } export const SET_LOADING = "SET_LOADING"; export function setLoading() { return { type: SET_LOADING, }; } export const SET_NOT_LOADING = "SET_NOT_LOADING"; export function setNotLoading() { return { type: SET_NOT_LOADING, }; } export const SET_INITIAL_CATEGORIES = "SET_INITIAL_CATEGORIES"; export function setInitialCategories(values) { return { type: SET_INITIAL_CATEGORIES, values, }; } export const SET_INITIAL_SHAPES = "SET_INITIAL_SHAPES"; export function setInitialShapes(values) { return { type: SET_INITIAL_SHAPES, values, }; } export const UPDATE_TIMERANGE = "UPDATE_TIMERANGE"; export function updateTimeRange(timerange) { return { type: UPDATE_TIMERANGE, timerange, }; } export const UPDATE_DIMENSIONS = "UPDATE_DIMENSIONS"; export function updateDimensions(dims) { return { type: UPDATE_DIMENSIONS, dims, }; } export const UPDATE_NARRATIVE = "UPDATE_NARRATIVE"; export function updateNarrative(narrative) { return { type: UPDATE_NARRATIVE, narrative, }; } export const UPDATE_NARRATIVE_STEP_IDX = "UPDATE_NARRATIVE_STEP_IDX"; export function updateNarrativeStepIdx(idx) { return { type: UPDATE_NARRATIVE_STEP_IDX, idx, }; } export const UPDATE_SOURCE = "UPDATE_SOURCE"; export function updateSource(source) { return { type: UPDATE_SOURCE, source, }; } export const UPDATE_COLORING_SET = "UPDATE_COLORING_SET"; export function updateColoringSet(coloringSet) { return { type: UPDATE_COLORING_SET, coloringSet, }; } export const UPDATE_TICKS = "UPDATE_TICKS"; export function updateTicks(ticks) { return { type: UPDATE_TICKS, ticks, }; } // UI export const TOGGLE_SITES = "TOGGLE_SITES"; export function toggleSites() { return { type: TOGGLE_SITES, }; } export const TOGGLE_FETCHING_DOMAIN = "TOGGLE_FETCHING_DOMAIN"; export function toggleFetchingDomain() { return { type: TOGGLE_FETCHING_DOMAIN, }; } export const TOGGLE_FETCHING_SOURCES = "TOGGLE_FETCHING_SOURCES"; export function toggleFetchingSources() { return { type: TOGGLE_FETCHING_SOURCES, }; } export const TOGGLE_LANGUAGE = "TOGGLE_LANGUAGE"; export function toggleLanguage(language) { return { type: TOGGLE_LANGUAGE, language, }; } export const CLOSE_TOOLBAR = "CLOSE_TOOLBAR"; export function closeToolbar() { return { type: CLOSE_TOOLBAR, }; } export const TOGGLE_INFOPOPUP = "TOGGLE_INFOPOPUP"; export function toggleInfoPopup() { return { type: TOGGLE_INFOPOPUP, }; } export const TOGGLE_INTROPOPUP = "TOGGLE_INTROPOPUP"; export function toggleIntroPopup() { return { type: TOGGLE_INTROPOPUP, }; } export const TOGGLE_NOTIFICATIONS = "TOGGLE_NOTIFICATIONS"; export function toggleNotifications() { return { type: TOGGLE_NOTIFICATIONS, }; } export const MARK_NOTIFICATIONS_READ = "MARK_NOTIFICATIONS_READ"; export function markNotificationsRead() { return { type: MARK_NOTIFICATIONS_READ, }; } export const TOGGLE_COVER = "TOGGLE_COVER"; export function toggleCover() { return { type: TOGGLE_COVER, }; } export const UPDATE_SEARCH_QUERY = "UPDATE_SEARCH_QUERY"; export function updateSearchQuery(searchQuery) { return { type: UPDATE_SEARCH_QUERY, searchQuery, }; } // ERRORS export const FETCH_SOURCE_ERROR = "FETCH_SOURCE_ERROR"; export function fetchSourceError(msg) { return { type: FETCH_SOURCE_ERROR, msg, }; } export const USE_SATELLITE_TILES_OVERLAY = "USE_SATELLITE_TILES_OVERLAY"; export function useSatelliteTilesOverlay() { return { type: USE_SATELLITE_TILES_OVERLAY, }; } export const RESET_TILES_OVERLAY = "RESET_TILES_OVERLAY"; export function resetTilesOverlay() { return { type: RESET_TILES_OVERLAY, }; }