Home Reference Source

application/main.js

// require('babel-polyfill');
import React from 'react';
import ReactDom from 'react-dom';
import Immutable from 'immutable';

import {Router, Route, Link, browserHistory} from "react-router";
import AutobahnReact from 'autobahn-react';

import App from './components/app';

import {buildRoutes} from './routes';
import alt from './alt';

import {createStore, applyMiddleware} from 'redux';
import {Provider} from 'react-redux';

import appState from './state';
import thunkMiddleware from 'redux-thunk';

import Config from './config';
import CurrentUser from './current-user';

import {
    contentReceiveWebSocket,
    contentDeleteFromWebSocket
} from './redux/actions/content-actions';

import {
    assignmentsReceiveWebSocket
} from './redux/actions/assignment-actions';

import {
    assignmentCommentsReceiveWebSocket
} from './redux/actions/assignment-comment-actions';

import {
    snackbarShowMessage,
    snackbarClose
} from './redux/actions/snackbar-actions';

import {
    applicationSetVersion,
    applicationNotifyUpdates,
    applicationIsConnected,
    applicationFetchSettings
} from './redux/actions/application-actions';


let store = createStore(appState, applyMiddleware(thunkMiddleware));

window.React = React;
window.Store = store;

window._ceoScrollTop = function() {
    window.scrollTo(0,0);
}

// start up autobhan
let abStart = false;
store.subscribe(() => {
    if (abStart === false) {
        abStart = true;

        // build the URL
        const url = Config.get('_abep');
        const clientCode = Config.get('client_code');

        // SRN is the username, token is the password
        const srn = CurrentUser.getSrn();
        const token = Config.get('_abtok');

        let warnTimeout = null;

        // Initialize the connection, then set up the subs and start the auth process
        AutobahnReact.initialize(url + '/' + token, 'realm');

        // Library remembers the on ready state, so this will automatically
        // reconnect on a dropped connection
        AutobahnReact.Connection.onReady((details) => {
            store.dispatch(snackbarClose());
            store.dispatch(applicationIsConnected(true));
            store.dispatch(applicationFetchSettings());
            if (warnTimeout) {
                clearTimeout(warnTimeout);
                warnTimeout = null;
            }

            // just for testing
            AutobahnReact.subscribe('com.getsnworks.ceo.test', function(payload) {
                console.log(payload);
            });

            // broadcast channel allows us to broadcast a message to all users
            AutobahnReact.subscribe('com.getsnworks.ceo.broadcast', function(payload) {
                console.log(payload);
            });

            // client specific broadcast and events
            AutobahnReact.subscribe('com.getsnworks.ceo.' + clientCode + '.broadcast', function(payload) {
                console.log(payload);
            });
            AutobahnReact.subscribe('com.getsnworks.ceo.' + clientCode + '.contentupdate', function(payload) {
                store.dispatch(contentReceiveWebSocket(Immutable.fromJS(payload[0].content)));
            });
            AutobahnReact.subscribe('com.getsnworks.ceo.' + clientCode + '.contentupdate.deleted', function(payload) {
                store.dispatch(contentDeleteFromWebSocket(Immutable.fromJS(payload[0].content)));
            });
            AutobahnReact.subscribe('com.getsnworks.ceo.' + clientCode + '.assignmentupdate', function(payload) {
                store.dispatch(assignmentsReceiveWebSocket(Immutable.fromJS(payload[0].content)));
            });
            AutobahnReact.subscribe('com.getsnworks.ceo.' + clientCode + '.assignmentcommentupdate', function(payload) {
                store.dispatch(assignmentCommentsReceiveWebSocket(Immutable.fromJS(payload[0].content)));
            });
        });
        AutobahnReact.Connection.onLost((details) => {
            warnTimeout = setTimeout(() => {
                store.dispatch(snackbarShowMessage('Trying to reconnect...', 0));
            }, 2000);
            store.dispatch(applicationIsConnected(false));
        });

        // start the WampCra login process
        AutobahnReact.Auth.logIn({username: srn, password: token})
            .then(() => {
                console.log('Connected');
                store.dispatch(applicationIsConnected(true));
            })
            .catch(() => {
                store.dispatch(snackbarShowMessage('Unable to connect to server.', 0));
                console.log('Unable to connect to server.', arguments);
                store.dispatch(applicationIsConnected(false));
            });

        // check the version and notify
        const current = localStorage.getItem('_ceover');
        if (!current || current != Config.get('system_version')) {
            localStorage.setItem('_ceover', Config.get('system_version'));
            store.dispatch(applicationNotifyUpdates());
        }

        // check rebound for failed messages
        setTimeout(() => {
            if (window.Rebound && CurrentUser.getEmail().length) {
                window.Rebound.check({
                    publicToken: "5qtz5s5smnfdo2wdunocmp",
                    email: CurrentUser.getEmail(),
                    appearance: "alert",
                    position: "topRight",
                    title: "Please verify your email"
                });
            }
        }, 2000);

        // finally setup the heartbeat
        setInterval(() => {
            console.info('Dub');
            fetch('/sys/ping', {
                'credentials': 'same-origin',
            })
            .then((r) => {
                if (r.status !== 200) {
                    store.dispatch(snackbarShowMessage('Unable to connect to server.', 0));
                    store.dispatch(applicationIsConnected(false));
                    return;
                }
                console.info('Lub');
            })
            .catch(() => {
                store.dispatch(snackbarShowMessage('Unable to communicate with server.', 0));
                store.dispatch(applicationIsConnected(false));
            });

        }, 600000); // every 10 minutes
    }
});

/**
 * Main entry point for the app. Load the router and inject the routes.
 * @type {Object}
 */
ReactDom.render((
    <Provider store={store}>
        <Router history={browserHistory}>
            {buildRoutes(store)}
        </Router>
    </Provider>
), document.querySelector("#app-container"));