diff --git a/client/index.js b/client/index.js index ef6d1a5cb6..887380d1ee 100644 --- a/client/index.js +++ b/client/index.js @@ -19,7 +19,7 @@ import { saveToColdStorage } from './cold-reload'; -Rx.config.longStackSupport = !!debug.enabled; +const isDev = Rx.config.longStackSupport = !!debug.enabled; const log = debug('fcc:client'); const hotReloadTimeout = 5000; @@ -39,6 +39,7 @@ const devTools = window.devToolsExtension ? window.devToolsExtension() : f => f; const shouldRouterListenForReplays = !!window.devToolsExtension; const sagaOptions = { + isDev, window, document: window.document, location: window.location diff --git a/client/sagas/index.js b/client/sagas/index.js index 3a7fee2345..2c7e2781b7 100644 --- a/client/sagas/index.js +++ b/client/sagas/index.js @@ -2,5 +2,12 @@ import errSaga from './err-saga'; import titleSaga from './title-saga'; import localStorageSaga from './local-storage-saga'; import hardGoToSaga from './hard-go-to-saga'; +import windowSaga from './window-saga'; -export default [ errSaga, titleSaga, localStorageSaga, hardGoToSaga ]; +export default [ + errSaga, + titleSaga, + localStorageSaga, + hardGoToSaga, + windowSaga +]; diff --git a/client/sagas/window-saga.js b/client/sagas/window-saga.js new file mode 100644 index 0000000000..add0d4102c --- /dev/null +++ b/client/sagas/window-saga.js @@ -0,0 +1,34 @@ +import { Observable } from 'rx'; +import { initWindowHeight } from '../../common/app/redux/types'; +import { updateWindowHeight } from '../../common/app/redux/actions'; + +function getWindowSize(document, window) { + const body = document.getElementsByTagName('body')[0]; + return window.innerHeight || + document.docElement.clientHeight || + body.clientHeight || + 0; +} + +function listenForResize(document, window) { + return Observable.fromEvent(window, 'resize') + .debounce(250) + .startWith({}) + .map(() => getWindowSize(document, window)); +} + +export default function windowSaga( + action$, + getState, + { isDev, document, window } +) { + return action$ + .filter(({ type }) => type === initWindowHeight) + .flatMap(() => { + if (isDev) { + return listenForResize(document, window); + } + return Observable.just(getWindowSize(document, window)); + }) + .map(updateWindowHeight); +} diff --git a/common/app/App.jsx b/common/app/App.jsx index d2984be6b2..9e1be2fc7d 100644 --- a/common/app/App.jsx +++ b/common/app/App.jsx @@ -8,10 +8,9 @@ import { createSelector } from 'reselect'; import { fetchUser, - updateWindowHeight, + initWindowHeight, updateNavHeight } from './redux/actions'; -import getWindowHeight from './utils/get-window-height'; import Nav from './components/Nav'; @@ -50,7 +49,7 @@ export class FreeCodeCamp extends React.Component { picture: PropTypes.string, toast: PropTypes.object, updateNavHeight: PropTypes.func, - updateWindowHeight: PropTypes.func + initWindowHeight: PropTypes.func }; componentWillReceiveProps({ toast: nextToast = {} }) { @@ -68,7 +67,7 @@ export class FreeCodeCamp extends React.Component { } componentDidMount() { - this.props.updateWindowHeight(getWindowHeight()); + this.props.initWindowHeight(); } render() { @@ -92,7 +91,7 @@ export class FreeCodeCamp extends React.Component { const wrapComponent = compose( // connect Component to Redux Store - connect(mapStateToProps, { updateWindowHeight, updateNavHeight, fetchUser }), + connect(mapStateToProps, { initWindowHeight, updateNavHeight, fetchUser }), // handles prefetching data contain(fetchContainerOptions) ); diff --git a/common/app/redux/actions.js b/common/app/redux/actions.js index b89a2494af..7cdde164cd 100644 --- a/common/app/redux/actions.js +++ b/common/app/redux/actions.js @@ -32,6 +32,7 @@ export const updatePoints = createAction(types.updatePoints); // hardGoTo(path: String) => Action export const hardGoTo = createAction(types.hardGoTo); +export const initWindowHeight = createAction(types.initWindowHeight); export const updateWindowHeight = createAction(types.updateWindowHeight); export const updateNavHeight = createAction(types.updateNavHeight); diff --git a/common/app/redux/types.js b/common/app/redux/types.js index 9860e941bc..068f7f7389 100644 --- a/common/app/redux/types.js +++ b/common/app/redux/types.js @@ -12,6 +12,7 @@ export default createTypes([ // used to hit the server 'hardGoTo', + 'initWindowHeight', 'updateWindowHeight', 'updateNavHeight', diff --git a/common/app/routes/challenges/components/Side-Panel.jsx b/common/app/routes/challenges/components/Side-Panel.jsx index 1d93526c5a..80b9b98a27 100644 --- a/common/app/routes/challenges/components/Side-Panel.jsx +++ b/common/app/routes/challenges/components/Side-Panel.jsx @@ -12,7 +12,7 @@ import ToolPanel from './Tool-Panel.jsx'; const mapStateToProps = createSelector( state => state.app.windowHeight, state => state.app.navHeight, - (windowHeight, navHeight) => ({ height: windowHeight - navHeight - 50 }) + (windowHeight, navHeight) => ({ height: windowHeight - navHeight - 20 }) ); export class SidePanel extends PureComponent { diff --git a/common/app/utils/get-window-height.js b/common/app/utils/get-window-height.js deleted file mode 100644 index 08bb5e20bf..0000000000 --- a/common/app/utils/get-window-height.js +++ /dev/null @@ -1,18 +0,0 @@ -export default function getWindowHeight() { - try { - const win = typeof window !== 'undefined' ? - window : - null; - if (!win) { - return 0; - } - const docElement = win.document.documentElement; - const body = win.document.getElementsByTagName('body')[0]; - return win.innerHeight || - docElement.clientHeight || - body.clientHeight || - 0; - } catch (e) { - return 0; - } -}