Spaces:
Runtime error
Runtime error
| import alertsData, {AlertTypes, AlertLevels} from '../lib/alerts/index.jsx'; | |
| import extensionData from '../lib/libraries/extensions/index.jsx'; | |
| const SHOW_ALERT = 'scratch-gui/alerts/SHOW_ALERT'; | |
| const SHOW_EXTENSION_ALERT = 'scratch-gui/alerts/SHOW_EXTENSION_ALERT'; | |
| const CLOSE_ALERT = 'scratch-gui/alerts/CLOSE_ALERT'; | |
| const CLOSE_ALERTS_WITH_ID = 'scratch-gui/alerts/CLOSE_ALERTS_WITH_ID'; | |
| const CLOSE_ALERT_WITH_ID = 'scratch-gui/alerts/CLOSE_ALERT_WITH_ID'; | |
| /** | |
| * Initial state of alerts reducer | |
| * | |
| * {bool} visible - whether the alerts are visible | |
| * {array} alertsList - list of alerts, each with properties: | |
| * * alertType (required): one of AlertTypes | |
| * * closeButton (optional): bool indicating that we should show close button | |
| * * content (optional): react element (a <FormattedMessage />) | |
| * * extentionId (optional): id string that identifies the extension | |
| * * iconURL (optional): string | |
| * * level (required): string, one of AlertLevels | |
| * * message (optional): string | |
| * * showReconnect (optional): bool | |
| */ | |
| const initialState = { | |
| visible: true, | |
| alertsList: [] | |
| }; | |
| const filterPopupAlerts = alertsList => ( | |
| alertsList.filter(curAlert => ( | |
| curAlert.alertType === AlertTypes.STANDARD || | |
| curAlert.alertType === AlertTypes.EXTENSION | |
| )) | |
| ); | |
| const filterInlineAlerts = alertsList => ( | |
| alertsList.filter(curAlert => ( | |
| curAlert.alertType === AlertTypes.INLINE | |
| )) | |
| ); | |
| const reducer = function (state, action) { | |
| if (typeof state === 'undefined') state = initialState; | |
| switch (action.type) { | |
| case SHOW_ALERT: { // intended to show standard and inline alerts, but not extensions | |
| const alertId = action.alertId; | |
| if (alertId) { | |
| const newAlert = { | |
| alertId: alertId, | |
| level: AlertLevels.WARN // default level | |
| }; | |
| const alertData = alertsData.find(thisAlertData => thisAlertData.alertId === alertId); | |
| if (alertData) { | |
| const newList = state.alertsList.filter(curAlert => ( | |
| !alertData.clearList || alertData.clearList.indexOf(curAlert.alertId) === -1 | |
| )); | |
| if (action.data && action.data.message) { | |
| newAlert.message = action.data.message; | |
| } | |
| newAlert.alertType = alertData.alertType || AlertTypes.STANDARD; | |
| newAlert.closeButton = alertData.closeButton; | |
| newAlert.content = alertData.content; | |
| newAlert.iconURL = alertData.iconURL; | |
| newAlert.iconSpinner = alertData.iconSpinner; | |
| newAlert.level = alertData.level; | |
| newAlert.showDownload = alertData.showDownload; | |
| newAlert.showSaveNow = alertData.showSaveNow; | |
| newList.push(newAlert); | |
| return Object.assign({}, state, { | |
| alertsList: newList | |
| }); | |
| } | |
| } | |
| return state; // if alert not found, show nothing | |
| } | |
| case SHOW_EXTENSION_ALERT: { | |
| const extensionId = action.data.extensionId; | |
| if (extensionId) { | |
| const extension = extensionData.find(ext => ext.extensionId === extensionId); | |
| if (extension) { | |
| const newList = state.alertsList.slice(); | |
| const newAlert = { | |
| alertType: AlertTypes.EXTENSION, | |
| closeButton: true, | |
| extensionId: extensionId, | |
| extensionName: extension.name, | |
| iconURL: extension.connectionSmallIconURL, | |
| level: AlertLevels.WARN, | |
| showReconnect: true | |
| }; | |
| newList.push(newAlert); | |
| return Object.assign({}, state, { | |
| alertsList: newList | |
| }); | |
| } | |
| } | |
| return state; // if alert not found, show nothing | |
| } | |
| case CLOSE_ALERT_WITH_ID: | |
| case CLOSE_ALERT: { | |
| if (action.alertId) { | |
| action.index = state.alertsList.findIndex(a => a.alertId === action.alertId); | |
| if (action.index === -1) return state; | |
| } | |
| const newList = state.alertsList.slice(); | |
| newList.splice(action.index, 1); | |
| return Object.assign({}, state, { | |
| alertsList: newList | |
| }); | |
| } | |
| case CLOSE_ALERTS_WITH_ID: { | |
| return Object.assign({}, state, { | |
| alertsList: state.alertsList.filter(curAlert => ( | |
| curAlert.alertId !== action.alertId | |
| )) | |
| }); | |
| } | |
| default: | |
| return state; | |
| } | |
| }; | |
| /** | |
| * Action creator to close an alert with the given index. | |
| * | |
| * @param {object} index - the index of the alert to close. | |
| * @return {object} - an object to be passed to the reducer. | |
| */ | |
| const closeAlert = function (index) { | |
| return { | |
| type: CLOSE_ALERT, | |
| index | |
| }; | |
| }; | |
| /** | |
| * Action creator to close all alerts with a given ID. | |
| * | |
| * @param {string} alertId - id string of the alert to close | |
| * @return {object} - an object to be passed to the reducer. | |
| */ | |
| const closeAlertsWithId = function (alertId) { | |
| return { | |
| type: CLOSE_ALERTS_WITH_ID, | |
| alertId | |
| }; | |
| }; | |
| /** | |
| * Action creator to close a single alert with a given ID. | |
| * | |
| * @param {string} alertId - id string of the alert to close | |
| * @return {object} - an object to be passed to the reducer. | |
| */ | |
| const closeAlertWithId = function (alertId) { | |
| return { | |
| type: CLOSE_ALERT_WITH_ID, | |
| alertId | |
| }; | |
| }; | |
| /** | |
| * Action creator to show an alert with the given alertId. | |
| * | |
| * @param {string} alertId - id string of the alert to show | |
| * @return {object} - an object to be passed to the reducer. | |
| */ | |
| const showStandardAlert = function (alertId) { | |
| return { | |
| type: SHOW_ALERT, | |
| alertId | |
| }; | |
| }; | |
| /** | |
| * Action creator to show an alert with the given input data. | |
| * | |
| * @param {object} data - data for the alert | |
| * @param {string} data.message - message for the alert | |
| * @param {string} data.extensionId - extension ID for the alert | |
| * @return {object} - an object to be passed to the reducer. | |
| */ | |
| const showExtensionAlert = function (data) { | |
| return { | |
| type: SHOW_EXTENSION_ALERT, | |
| data | |
| }; | |
| }; | |
| /** | |
| * Function to dispatch showing an alert, with optional | |
| * timeout to make it close/go away. | |
| * | |
| * @param {object} dispatch - dispatch function | |
| * @param {string} alertId - the ID of the alert | |
| */ | |
| const showAlertWithTimeout = function (dispatch, alertId) { | |
| const alertData = alertsData.find(thisAlertData => thisAlertData.alertId === alertId); | |
| if (alertData) { | |
| dispatch(showStandardAlert(alertId)); | |
| if (alertData.maxDisplaySecs) { | |
| setTimeout(() => { | |
| dispatch(closeAlertsWithId(alertId)); | |
| }, alertData.maxDisplaySecs * 1000); | |
| } | |
| } | |
| }; | |
| export { | |
| reducer as default, | |
| initialState as alertsInitialState, | |
| closeAlert, | |
| closeAlertWithId, | |
| filterInlineAlerts, | |
| filterPopupAlerts, | |
| showAlertWithTimeout, | |
| showExtensionAlert, | |
| showStandardAlert | |
| }; | |