diff options
Diffstat (limited to 'app/assets/javascripts/visual_review_toolbar/store')
3 files changed, 93 insertions, 33 deletions
diff --git a/app/assets/javascripts/visual_review_toolbar/store/events.js b/app/assets/javascripts/visual_review_toolbar/store/events.js index 93996be8473..c9095c77ef1 100644 --- a/app/assets/javascripts/visual_review_toolbar/store/events.js +++ b/app/assets/javascripts/visual_review_toolbar/store/events.js @@ -1,20 +1,37 @@ import { + addMr, authorizeUser, + changeSelectedMr, logoutUser, postComment, + saveComment, toggleForm, +} from '../components'; + +import { + CHANGE_MR_ID_BUTTON, COLLAPSE_BUTTON, COMMENT_BUTTON, LOGIN, LOGOUT, -} from '../components'; + MR_ID_BUTTON, +} from '../shared'; import { state } from './state'; +import debounce from './utils'; const noop = () => {}; -const eventLookup = ({ target: { id } }) => { +// State needs to be bound here to be acted on +// because these are called by click events and +// as such are called with only the `event` object +const eventLookup = id => { switch (id) { + case CHANGE_MR_ID_BUTTON: + return () => { + saveComment(); + changeSelectedMr(state); + }; case COLLAPSE_BUTTON: return toggleForm; case COMMENT_BUTTON: @@ -22,7 +39,12 @@ const eventLookup = ({ target: { id } }) => { case LOGIN: return authorizeUser.bind(null, state); case LOGOUT: - return logoutUser; + return () => { + saveComment(); + logoutUser(state); + }; + case MR_ID_BUTTON: + return addMr.bind(null, state); default: return noop; } @@ -33,4 +55,19 @@ const updateWindowSize = wind => { state.innerHeight = wind.innerHeight; }; -export { eventLookup, updateWindowSize }; +const initializeGlobalListeners = () => { + window.addEventListener('resize', debounce(updateWindowSize.bind(null, window), 200)); + window.addEventListener('beforeunload', event => { + if (state.usingGracefulStorage) { + // if there is no browser storage support, reloading will lose the comment; this way, the user will be warned + // we assign the return value because it is required by Chrome see: https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload#Example, + event.preventDefault(); + /* eslint-disable-next-line no-param-reassign */ + event.returnValue = ''; + } + + saveComment(); + }); +}; + +export { eventLookup, initializeGlobalListeners }; diff --git a/app/assets/javascripts/visual_review_toolbar/store/index.js b/app/assets/javascripts/visual_review_toolbar/store/index.js index 7143588c0bf..07c8dd6f1d2 100644 --- a/app/assets/javascripts/visual_review_toolbar/store/index.js +++ b/app/assets/javascripts/visual_review_toolbar/store/index.js @@ -1,5 +1,11 @@ -import { eventLookup, updateWindowSize } from './events'; -import { getInitialView, initializeState } from './state'; -import debounce from './utils'; +import { eventLookup, initializeGlobalListeners } from './events'; +import { nextView, getInitialView, initializeState, setUsingGracefulStorageFlag } from './state'; -export { debounce, eventLookup, getInitialView, initializeState, updateWindowSize }; +export { + eventLookup, + getInitialView, + initializeGlobalListeners, + initializeState, + nextView, + setUsingGracefulStorageFlag, +}; diff --git a/app/assets/javascripts/visual_review_toolbar/store/state.js b/app/assets/javascripts/visual_review_toolbar/store/state.js index 22702d524b8..741a5c7d99c 100644 --- a/app/assets/javascripts/visual_review_toolbar/store/state.js +++ b/app/assets/javascripts/visual_review_toolbar/store/state.js @@ -1,8 +1,9 @@ -import { comment, login, collapseButton } from '../components'; +import { comment, login, mrForm } from '../components'; +import { localStorage, COMMENT_BOX, LOGIN, MR_ID } from '../shared'; const state = { browser: '', - href: '', + usingGracefulStorage: '', innerWidth: '', innerHeight: '', mergeRequestId: '', @@ -23,11 +24,31 @@ const getBrowserId = sUsrAg => { return aKeys[nIdx]; }; +const nextView = (appState, form = 'none') => { + const formsList = { + [COMMENT_BOX]: currentState => (currentState.token ? mrForm : login), + [LOGIN]: currentState => (currentState.mergeRequestId ? comment(currentState) : mrForm), + [MR_ID]: currentState => (currentState.token ? comment(currentState) : login), + none: currentState => { + if (!currentState.token) { + return login; + } + + if (currentState.token && !currentState.mergeRequestId) { + return mrForm; + } + + return comment(currentState); + }, + }; + + return formsList[form](appState); +}; + const initializeState = (wind, doc) => { const { innerWidth, innerHeight, - location: { href }, navigator: { platform, userAgent }, } = wind; @@ -39,7 +60,6 @@ const initializeState = (wind, doc) => { // This mutates our default state object above. It's weird but it makes the linter happy. Object.assign(state, { browser, - href, innerWidth, innerHeight, mergeRequestId, @@ -49,30 +69,27 @@ const initializeState = (wind, doc) => { projectPath, userAgent, }); -}; -function getInitialView({ localStorage }) { - const loginView = { - content: login, - toggleButton: collapseButton, - }; + return state; +}; - const commentView = { - content: comment, - toggleButton: collapseButton, - }; +const getInitialView = () => { + const token = localStorage.getItem('token'); + const mrId = localStorage.getItem('mergeRequestId'); - try { - const token = localStorage.getItem('token'); + if (token) { + state.token = token; + } - if (token) { - state.token = token; - return commentView; - } - return loginView; - } catch (err) { - return loginView; + if (mrId) { + state.mergeRequestId = mrId; } -} -export { initializeState, getInitialView, state }; + return nextView(state); +}; + +const setUsingGracefulStorageFlag = flag => { + state.usingGracefulStorage = !flag; +}; + +export { initializeState, getInitialView, nextView, setUsingGracefulStorageFlag, state }; |