summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/visual_review_toolbar/store
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/visual_review_toolbar/store')
-rw-r--r--app/assets/javascripts/visual_review_toolbar/store/events.js45
-rw-r--r--app/assets/javascripts/visual_review_toolbar/store/index.js14
-rw-r--r--app/assets/javascripts/visual_review_toolbar/store/state.js67
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 };