Beispiel #1
0
export const configureReduxStore = ( currentUser, reduxStore ) => {
	debug( 'Executing Calypso configure Redux store.' );

	bindWpLocaleState( reduxStore );

	if ( currentUser.get() ) {
		// Set current user in Redux store
		setCurrentUserOnReduxStore( currentUser.get(), reduxStore );
		currentUser.on( 'change', () => {
			setCurrentUserOnReduxStore( currentUser.get(), reduxStore );
		} );
	}

	if ( config.isEnabled( 'network-connection' ) ) {
		asyncRequire( 'lib/network-connection', networkConnection =>
			networkConnection.init( reduxStore )
		);
	}
};
Beispiel #2
0
export const configureReduxStore = ( currentUser, reduxStore ) => {
	debug( 'Executing Calypso configure Redux store.' );

	bindWpLocaleState( reduxStore );

	if ( currentUser.get() ) {
		// Set current user in Redux store
		reduxStore.dispatch( receiveUser( currentUser.get() ) );
		currentUser.on( 'change', () => {
			reduxStore.dispatch( receiveUser( currentUser.get() ) );
		} );
		reduxStore.dispatch( setCurrentUserId( currentUser.get().ID ) );
		reduxStore.dispatch( setCurrentUserFlags( currentUser.get().meta.data.flags.active_flags ) );
	}

	if ( config.isEnabled( 'network-connection' ) ) {
		asyncRequire( 'lib/network-connection', networkConnection =>
			networkConnection.init( reduxStore )
		);
	}
};
Beispiel #3
0
function reduxStoreReady( reduxStore ) {
	let layoutSection, layoutElement, validSections = [];

	bindWpLocaleState( reduxStore );
	bindTitleToStore( reduxStore );

	supportUser.setReduxStore( reduxStore );

	Layout = require( 'layout' );

	if ( user.get() ) {
		// When logged in the analytics module requires user and superProps objects
		// Inject these here
		analytics.initialize( user, superProps );

		// Set current user in Redux store
		reduxStore.dispatch( receiveUser( user.get() ) );
		reduxStore.dispatch( setCurrentUserId( user.get().ID ) );

		// Create layout instance with current user prop
		layoutElement = React.createElement( Layout, {
			user: user,
			sites: sites,
			focus: layoutFocus,
			nuxWelcome: nuxWelcome,
			translatorInvitation: translatorInvitation
		} );
	} else {
		analytics.setSuperProps( superProps );
		layoutElement = React.createElement( Layout, { focus: layoutFocus } );
	}

	if ( config.isEnabled( 'perfmon' ) ) {
		// Record time spent watching slowly-flashing divs
		perfmon();
	}

	if ( config.isEnabled( 'network-connection' ) ) {
		require( 'lib/network-connection' ).init( reduxStore );
	}

	renderWithReduxStore(
		layoutElement,
		document.getElementById( 'wpcom' ),
		reduxStore
	);

	debug( 'Main layout rendered.' );

	// If `?sb` or `?sp` are present on the path set the focus of layout
	// This can be removed when the legacy version is retired.
	page( '*', function( context, next ) {
		if ( [ 'sb', 'sp' ].indexOf( context.querystring ) !== -1 ) {
			layoutSection = ( context.querystring === 'sb' ) ? 'sidebar' : 'sites';
			layoutFocus.set( layoutSection );
			page.redirect( context.pathname );
		}

		next();
	} );

	setUpContext( reduxStore );

	page( '*', require( 'lib/route/normalize' ) );

	// warn against navigating from changed, unsaved forms
	page.exit( '*', require( 'lib/mixins/protect-form' ).checkFormHandler );

	page( '*', function( context, next ) {
		var path = context.pathname;

		// Bypass this global handler for legacy routes
		// to avoid bumping stats and changing focus to the content
		if ( /.php$/.test( path ) ||
				/^\/?$/.test( path ) && ! config.isEnabled( 'reader' ) ||
				/^\/my-stats/.test( path ) ||
				/^\/notifications/.test( path ) ||
				/^\/themes/.test( path ) ||
				/^\/manage/.test( path ) ||
				/^\/plans/.test( path ) && ! config.isEnabled( 'manage/plans' ) ||
				/^\/me/.test( path ) && ! /^\/me\/billing/.test( path ) &&
				! /^\/me\/next/.test( path ) && ! config.isEnabled( 'me/my-profile' ) ) {
			return next();
		}

		// Focus UI on the content on page navigation
		if ( ! config.isEnabled( 'code-splitting' ) ) {
			layoutFocus.next();
		}

		// If `?welcome` is present, and `?tour` isn't, show the welcome message
		if ( ! context.query.tour && context.querystring === 'welcome' && context.pathname.indexOf( '/me/next' ) === -1 ) {
			// show welcome message, persistent for full sized screens
			nuxWelcome.setWelcome( viewport.isDesktop() );
		} else {
			nuxWelcome.clearTempWelcome();
		}

		// If `?tour` is present, show the guided tour
		if ( config.isEnabled( 'guided-tours' ) && context.query.tour ) {
			context.store.dispatch( showGuidedTour( {
				shouldShow: true,
				shouldDelay: /^\/(checkout|plans\/select)/.test( path ),
				tour: context.query.tour,
			} ) );
		}

		// Bump general stat tracking overall Newdash usage
		analytics.mc.bumpStat( { newdash_pageviews: 'route' } );

		next();
	} );

	page( '*', function( context, next ) {
		if ( '/me/account' !== context.path && user.get().phone_account ) {
			page( '/me/account' );
		}

		next();
	} );

	page( '*', function( context, next ) {
		emailVerification.renderNotice( context );
		next();
	} );

	if ( config.isEnabled( 'oauth' ) ) {
		// Forces OAuth users to the /login page if no token is present
		page( '*', require( 'auth/controller' ).checkToken );
	}

	// Load the application modules for the various sections and features
	sections.load();

	// delete any lingering local storage data from signup
	if ( ! startsWith( window.location.pathname, '/start' ) ) {
		[ 'signupProgress', 'signupDependencies' ].forEach( store.remove );
	}

	validSections = sections.get().reduce( function( acc, section ) {
		return section.enableLoggedOut ? acc.concat( section.paths ) : acc;
	}, [] );

	if ( ! user.get() ) {
		// Dead-end the sections the user can't access when logged out
		page( '*', function( context, next ) {
			var isValidSection = some( validSections, function( validPath ) {
				return startsWith( context.path, validPath );
			} );

			if ( '/' === context.path && config.isEnabled( 'devdocs/redirect-loggedout-homepage' ) ) {
				page.redirect( '/devdocs/start' );
				return;
			}

			if ( isValidSection ) {
				next();
			}
		} );
	}

	page( '*', function( context, next ) {
		// Reset the selected site before each route is executed. This needs to
		// occur after the sections routes execute to avoid a brief flash where
		// sites are reset but the next section is waiting to be loaded.
		if ( ! route.getSiteFragment( context.path ) && sites.getSelectedSite() ) {
			sites.resetSelectedSite();
		}

		next();
	} );

	require( 'my-sites' )();

	// clear notices
	page( '*', function( context, next ) {
		context.store.dispatch( setRouteAction( context.pathname ) );
		next();
	} );

	// clear notices
	//TODO: remove this one when notices are reduxified - it is for old notices
	page( '*', require( 'notices' ).clearNoticesOnNavigation );

	if ( config.isEnabled( 'olark' ) ) {
		require( 'lib/olark' );
	}

	if ( config.isEnabled( 'keyboard-shortcuts' ) ) {
		require( 'lib/keyboard-shortcuts/global' )( sites );
	}

	if ( config.isEnabled( 'desktop' ) ) {
		require( 'lib/desktop' ).init();
	}

	if ( config.isEnabled( 'rubberband-scroll-disable' ) ) {
		require( 'lib/rubberband-scroll-disable' )( document.body );
	}

	detectHistoryNavigation.start();
	page.start();
}
Beispiel #4
0
function reduxStoreReady( reduxStore ) {
	let layoutSection, validSections = [],
		isIsomorphic = isSectionIsomorphic( reduxStore.getState() );

	bindWpLocaleState( reduxStore );

	supportUser.setReduxStore( reduxStore );

	if ( user.get() ) {
		// When logged in the analytics module requires user and superProps objects
		// Inject these here
		analytics.initialize( user, superProps );

		// Set current user in Redux store
		reduxStore.dispatch( receiveUser( user.get() ) );
		reduxStore.dispatch( setCurrentUserId( user.get().ID ) );
		reduxStore.dispatch( setCurrentUserFlags( user.get().meta.data.flags.active_flags ) );


		const participantInPushNotificationsAbTest = config.isEnabled('push-notifications-ab-test') && abtest('browserNotifications') === 'enabled';
		if ( config.isEnabled( 'push-notifications' ) || participantInPushNotificationsAbTest ) {
			// If the browser is capable, registers a service worker & exposes the API
			reduxStore.dispatch( pushNotificationsInit() );
		}
	} else {
		analytics.setSuperProps( superProps );
	}

	if ( config.isEnabled( 'network-connection' ) ) {
		require( 'lib/network-connection' ).init( reduxStore );
	}

	// Render Layout only for non-isomorphic sections, unless logged-in.
	// Isomorphic sections will take care of rendering their Layout last themselves,
	// unless in logged-in mode, where we can't do that yet.
	// TODO: Remove the ! user.get() check once isomorphic sections render their
	// Layout themselves when logged in.
	if ( ! isIsomorphic || user.get() ) {
		renderLayout( reduxStore );
	}

	// If `?sb` or `?sp` are present on the path set the focus of layout
	// This can be removed when the legacy version is retired.
	page( '*', function( context, next ) {
		if ( [ 'sb', 'sp' ].indexOf( context.querystring ) !== -1 ) {
			layoutSection = ( context.querystring === 'sb' ) ? 'sidebar' : 'sites';
			layoutFocus.set( layoutSection );
			page.redirect( context.pathname );
		}

		next();
	} );

	setUpContext( reduxStore );

	page( '*', require( 'lib/route/normalize' ) );

	// warn against navigating from changed, unsaved forms
	page.exit( '*', require( 'lib/mixins/protect-form' ).checkFormHandler );

	page( '*', function( context, next ) {
		var path = context.pathname;

		// Bypass this global handler for legacy routes
		// to avoid bumping stats and changing focus to the content
		if ( /.php$/.test( path ) ||
				/^\/?$/.test( path ) && ! config.isEnabled( 'reader' ) ||
				/^\/my-stats/.test( path ) ||
				/^\/notifications/.test( path ) ||
				/^\/themes/.test( path ) ||
				/^\/manage/.test( path ) ||
				/^\/plans/.test( path ) && ! config.isEnabled( 'manage/plans' ) ||
				/^\/me/.test( path ) && ! /^\/me\/billing/.test( path ) &&
				! /^\/me\/next/.test( path ) && ! config.isEnabled( 'me/my-profile' ) ) {
			return next();
		}

		// Focus UI on the content on page navigation
		if ( ! config.isEnabled( 'code-splitting' ) ) {
			layoutFocus.next();
		}

		// If `?welcome` is present, and `?tour` isn't, show the welcome message
		if ( ! context.query.tour && context.querystring === 'welcome' && context.pathname.indexOf( '/me/next' ) === -1 ) {
			// show welcome message, persistent for full sized screens
			nuxWelcome.setWelcome( viewport.isDesktop() );
		} else {
			nuxWelcome.clearTempWelcome();
		}

		// Bump general stat tracking overall Newdash usage
		analytics.mc.bumpStat( { newdash_pageviews: 'route' } );

		next();
	} );

	page( '*', function( context, next ) {
		if ( '/me/account' !== context.path && user.get().phone_account ) {
			page( '/me/account' );
		}

		next();
	} );

	page( '*', emailVerification );

	if ( config.isEnabled( 'oauth' ) ) {
		// Forces OAuth users to the /login page if no token is present
		page( '*', require( 'auth/controller' ).checkToken );
	}

	// Load the application modules for the various sections and features
	sections.load();

	// delete any lingering local storage data from signup
	if ( ! startsWith( window.location.pathname, '/start' ) ) {
		[ 'signupProgress', 'signupDependencies' ].forEach( store.remove );
	}

	validSections = sections.get().reduce( function( acc, section ) {
		return section.enableLoggedOut ? acc.concat( section.paths ) : acc;
	}, [] );

	if ( ! user.get() ) {
		// Dead-end the sections the user can't access when logged out
		page( '*', function( context, next ) {
			var isValidSection = some( validSections, function( validPath ) {
				return startsWith( context.path, validPath );
			} );

			if ( '/' === context.pathname && config.isEnabled( 'devdocs/redirect-loggedout-homepage' ) ) {
				if ( config.isEnabled( 'oauth' ) ) {
					page.redirect( '/authorize' );
				} else {
					page.redirect( '/devdocs/start' );
				}
				return;
			}

			if ( isValidSection ) {
				next();
			}
		} );
	}

	page( '*', function( context, next ) {
		// Reset the selected site before each route is executed. This needs to
		// occur after the sections routes execute to avoid a brief flash where
		// sites are reset but the next section is waiting to be loaded.
		if ( ! route.getSiteFragment( context.path ) && sites.getSelectedSite() ) {
			sites.resetSelectedSite();
		}

		next();
	} );

	require( 'my-sites' )();

	// clear notices
	page( '*', function( context, next ) {
		context.store.dispatch( setRouteAction(
					context.pathname,
					context.query ) );
		next();
	} );

	// clear notices
	//TODO: remove this one when notices are reduxified - it is for old notices
	page( '*', require( 'notices' ).clearNoticesOnNavigation );

	if ( config.isEnabled( 'olark' ) ) {
		require( 'lib/olark' );
	}

	if ( config.isEnabled( 'keyboard-shortcuts' ) ) {
		require( 'lib/keyboard-shortcuts/global' )( sites );
	}

	if ( config.isEnabled( 'desktop' ) ) {
		require( 'lib/desktop' ).init();
	}

	if ( config.isEnabled( 'rubberband-scroll-disable' ) ) {
		require( 'lib/rubberband-scroll-disable' )( document.body );
	}

	if ( config.isEnabled( 'dev/test-helper' ) && document.querySelector( '.environment.is-tests' ) ) {
		require( 'lib/abtest/test-helper' )( document.querySelector( '.environment.is-tests' ) );
	}

	/*
	 * Layouts with differing React mount-points will not reconcile correctly,
	 * so remove an existing single-tree layout by re-rendering if necessary.
	 *
	 * TODO (@seear): React 15's new reconciliation algo may make this unnecessary
	 */
	page( '*', function( context, next ) {
		const sectionNotIsomorphic = ! isSectionIsomorphic( context.store.getState() );
		const previousLayoutIsSingleTree = ! isEmpty(
			document.getElementsByClassName( 'wp-singletree-layout' )
		);

		if ( sectionNotIsomorphic && previousLayoutIsSingleTree ) {
			debug( 'Re-rendering multi-tree layout' );
			renderLayout( context.store );
		}
		next();
	} );

	detectHistoryNavigation.start();
	page.start();
}