declare var require ; declare var module ; import { logEvent , setupLogging } from './Logging' ; setupLogging ( console ) ; import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider' ; import 'babel-polyfill' ; import * as React from 'react' ; import * as ReactDOM from 'react-dom' ; import { Provider } from 'react-redux' ; import * as Redux from 'redux' ; import { Expansion , NODE_ENV , VERSION } from 'shared/schema/Constants' ; import { audioSet } from './actions/Audio' ; import { toPrevious } from './actions/Card' ; import { setDialog } from './actions/Dialog' ; import { listSavedQuests , updateStorageFreeBytes } from './actions/SavedQuests' ; import { searchAndPlay } from './actions/Search' ; import { fetchServerStatus , setServerStatus } from './actions/ServerStatus' ; import { changeSettings } from './actions/Settings' ; import { openSnackbar } from './actions/Snackbar' ; import { silentLogin } from './actions/User' ; import { AUTH_SETTINGS , INIT_DELAY , UNSUPPORTED_BROWSERS } from './Constants' ; import { getDevicePlatform , getDocument , getNavigator , getWindow , setGA } from './Globals' ; import { getStorageBoolean } from './LocalStorage' ; import { ContentSetsType , SettingsType } from './reducers/StateTypes' ; import { createAppStore , getStore } from './Store' ; import theme from './Theme' ; import Promise from 'promise-polyfill' ; import 'whatwg-fetch' ; export function setupPolyfills ( ) { const w = getWindow ( ) ; if ( ! w . Promise ) { w . Promise = Promise ; } } const Raven = require ( 'raven-js' ) ; const ReactGA = require ( 'react-ga' ) ; export type ThunkAction < R , S = { } , E = { } , A extends Redux . Action < any > = Redux . AnyAction > = ( dispatch : Redux . Dispatch < A > , getState : ( ) => S , extraArgument : E ) => R ; declare module 'redux' { export interface Dispatch < A extends Redux . Action < any > = Redux . AnyAction > { < R , E > ( asyncAction ) : R ; } } Raven . config ( AUTH_SETTINGS . RAVEN , { environment : NODE_ENV , release : VERSION , shouldSendCallback ( data ) { const supportedBrowser = ! UNSUPPORTED_BROWSERS . test ( getNavigator ( ) . userAgent ) ; return supportedBrowser && NODE_ENV !== 'dev' && ! getStore ( ) . getState ( ) . settings . simulator ; } , } ) . install ( ) ; function setupDevice ( ) { const window = getWindow ( ) ; const platform = getDevicePlatform ( ) ; document . body . className += ' ' + platform ; getStore ( ) . dispatch ( changeSettings ( { audioEnabled : getStorageBoolean ( 'audioEnabled' , ! UNSUPPORTED_BROWSERS . test ( getNavigator ( ) . userAgent ) ) , } ) ) ; if ( platform === 'android' ) { if ( window . AndroidFullScreen ) { window . AndroidFullScreen . immersiveMode ( ( ) => { } , ( ) => { } ) ; } else { } if ( /Android/ . test ( navigator . appVersion ) ) { window . addEventListener ( 'resize' , ( ) => { if ( document . activeElement ) { if ( document . activeElement . tagName === 'INPUT' || document . activeElement . tagName === 'TEXTAREA' ) { document . activeElement . scrollIntoView ( ) ; } } } ) ; } } getDocument ( ) . addEventListener ( 'backbutton' , ( ) => { getStore ( ) . dispatch ( toPrevious ( { } ) ) ; } , false ) ; getDocument ( ) . addEventListener ( 'pause' , ( ) => { getStore ( ) . dispatch ( audioSet ( { paused : true } ) ) ; } , false ) ; getDocument ( ) . addEventListener ( 'resume' , ( ) => { getStore ( ) . dispatch ( audioSet ( { paused : false } ) ) ; } , false ) ; if ( window . plugins !== undefined && window . plugins . insomnia !== undefined ) { window . plugins . insomnia . keepAwake ( ) ; } getStore ( ) . dispatch ( silentLogin ( ) ) . catch ( console . error ) ; } function setupHotReload ( ) { if ( module . hot ) { module . hot . accept ( ) ; module . hot . accept ( './components/Compositor' , ( ) => { setTimeout ( ( ) => { render ( ) ; } ) ; } ) ; } } function setupSavedQuests ( ) { getStore ( ) . dispatch ( listSavedQuests ( ) ) ; } function setupGoogleAnalytics ( ) { if ( window . location . hostname === 'localhost' || NODE_ENV === 'dev' ) { setGA ( { event : ( ) : void => { } , set : ( ) : void => { } , } ) ; return console . log ( 'Google Analytics disabled during local dev.' ) ; } ReactGA . initialize ( 'UA-47408800-9' , { gaOptions : { appName : getDevicePlatform ( ) , appVersion : VERSION , } , titleCase : false , } ) ; ReactGA . pageview ( '/' ) ; setGA ( ReactGA ) ; } function handleUrlHash ( ) { const hash = ( window . location . hash || '#' ) . substring ( 1 ) ; if ( hash . length > 10 ) { getStore ( ) . dispatch ( searchAndPlay ( hash ) ) ; } } const MAX_SNACKBAR_ERROR_RATE_MILLIS = 1000 ; let lastErrorSnackbar = 0 ; function setupOnError ( window ) { window . onerror = ( message , source , line ) => { const state = getStore ( ) . getState ( ) ; const quest = state . quest || { } ; const settings = state . settings || { } ; const questNode = quest . node && quest . node . elem && quest . node . elem [ 0 ] ; Raven . setExtraContext ( { card : state . card . key , questCardTitle : ( questNode ) ? questNode . attribs . title : '' , questId : quest . details . id , questLine : ( questNode ) ? questNode . attribs [ 'data-line' ] : '' , questName : quest . details . title || 'n/a' , settings : JSON . stringify ( settings ) , } ) ; Raven . setTagsContext ( ) ; Raven . setTagsContext ( { audio : settings . audioEnabled , multiplayer : state . multiplayer . session !== null , } ) ; Raven . captureException ( new Error ( message ) ) ; if ( quest . details . id ) { message = `Quest: ${ quest . details . title }. Error: ${ message }.` ; } const label = ( source ) ? `${ source } line ${ line }` : null ; console . error ( message , label ) ; logEvent ( 'error' , 'APP_ERROR' , { action : message , label } ) ; if ( Date . now ( ) - lastErrorSnackbar > MAX_SNACKBAR_ERROR_RATE_MILLIS ) { setTimeout ( ( ) => { getStore ( ) . dispatch ( openSnackbar ( Error ( message + ' Source: ' + label ) ) ) ; } , 0 ) ; lastErrorSnackbar = Date . now ( ) ; } return true ; } ; } function setupStorage ( document ) { try { document . cookie = 'cookietest=1' ; const ret = document . cookie . indexOf ( 'cookietest=' ) !== - 1 ; document . cookie = 'cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT' ; if ( ! ret ) { throw new Error ( 'Cookies disabled' ) ; } } catch ( err ) { setTimeout ( ( ) => { getStore ( ) . dispatch ( openSnackbar ( 'Please enable cookies for the app to function properly.' ) ) ; } , 0 ) ; } setTimeout ( ( ) => { getStore ( ) . dispatch ( updateStorageFreeBytes ( ) ) ; } , INIT_DELAY . FREE_STORAGE_MILLIS ) ; } function setupSettings ( settings ) { if ( settings ) { const contentSets = ( settings || { } ) . contentSets ; for ( const set in contentSets ) { if ( contentSets [ set as Expansion ] === null ) { getStore ( ) . dispatch ( setDialog ( 'EXPANSION_SELECT' ) ) ; break ; } } } else { getStore ( ) . dispatch ( setDialog ( 'EXPANSION_SELECT' ) ) ; } } export function init ( ) { const window = getWindow ( ) ; const document = getDocument ( ) ; setupOnError ( window ) ; createAppStore ( Raven ) ; setupStorage ( document ) ; window . platform = window . cordova ? 'cordova' : 'web' ; window . onpopstate = ( e ) => { getStore ( ) . dispatch ( toPrevious ( { } ) ) ; e . preventDefault ( ) ; } ; document . addEventListener ( 'visibilitychange' , ( ) => { if ( document . visibilityState === 'hidden' ) { getStore ( ) . dispatch ( audioSet ( { paused : true } ) ) ; } else if ( document . visibilityState === 'visible' ) { getStore ( ) . dispatch ( audioSet ( { paused : false } ) ) ; } } , false ) ; document . addEventListener ( 'deviceready' , setupDevice , false ) ; setTimeout ( ( ) => { getStore ( ) . dispatch ( silentLogin ( ) ) . catch ( console . error ) ; } , INIT_DELAY . SILENT_LOGIN_MILLIS ) ; setupPolyfills ( ) ; setupGoogleAnalytics ( ) ; setupHotReload ( ) ; setupSavedQuests ( ) ; handleUrlHash ( ) ; render ( ) ; if ( UNSUPPORTED_BROWSERS . test ( getNavigator ( ) . userAgent ) ) { getStore ( ) . dispatch ( setServerStatus ( { announcement : { open : true , message : 'Unknown browser. Please use a standard browser like Chrome or Firefox for the best experience.' , } , } ) ) ; } else { getStore ( ) . dispatch ( fetchServerStatus ( ) ) ; } setupSettings ( getStore ( ) . getState ( ) . settings ) ; } function render ( ) { const CompositorContainer = require ( './components/CompositorContainer' ) . default ; const base = getDocument ( ) . getElementById ( 'react-app' ) ; if ( ! base ) { throw new Error ( 'Could not find react-app element' ) ; } ReactDOM . unmountComponentAtNode ( base ) ; ReactDOM . render ( < MuiThemeProvider theme = { theme } > < Provider store = { getStore ( ) } > < CompositorContainer store = { getStore ( ) } / > < /Provider> < /MuiThemeProvider>, base); } declare var doInit ; if ( typeof doInit !== 'undefined' ) { Raven . context ( init ) ; }