From c82b2e3ae6787e7d17686a61566e349b07d9f634 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Wed, 29 Jul 2015 10:16:48 -0700 Subject: [PATCH] set and render page title note this requires changes to thundercats to work see: thundercatsjs/thundercats-react/issues/3 --- common/app/App.jsx | 21 ++++++++++++++++++-- common/app/flux/Actions.js | 6 ++++++ common/app/flux/Store.js | 8 +++++--- common/app/routes/Hikes/components/Hikes.jsx | 7 +++++++ server/boot/a-react.js | 6 +++++- server/views/layout-react.jade | 4 ++++ server/views/partials/small-head.jade | 1 - 7 files changed, 46 insertions(+), 7 deletions(-) diff --git a/common/app/App.jsx b/common/app/App.jsx index 1c6c547cc3..58704002ab 100644 --- a/common/app/App.jsx +++ b/common/app/App.jsx @@ -20,9 +20,26 @@ export default contain( propTypes: { children: PropTypes.node, - username: PropTypes.string, points: PropTypes.number, - picture: PropTypes.string + picture: PropTypes.string, + title: PropTypes.string, + username: PropTypes.string + }, + + componentDidMount() { + const title = this.props.title; + this.setTitle(title); + }, + + componentWillReceiveProps(nextProps) { + if (nextProps.title !== this.props.title) { + this.setTitle(nextProps.title); + } + }, + + setTitle(title) { + const doc = typeof document !== 'undefined' ? document : {}; + doc.title = title; }, render() { diff --git a/common/app/flux/Actions.js b/common/app/flux/Actions.js index f915d34f9d..2cf852f483 100644 --- a/common/app/flux/Actions.js +++ b/common/app/flux/Actions.js @@ -4,6 +4,10 @@ import debugFactory from 'debug'; const debug = debugFactory('freecc:app:actions'); export default Actions({ + setTitle(title = 'Learn To Code') { + return { title: title + '| Free Code Camp' }; + }, + setUser({ username, picture, progressTimestamps = [] }) { return { username, @@ -11,6 +15,7 @@ export default Actions({ points: progressTimestamps.length }; }, + getUser: null }) .refs({ displayName: 'AppActions' }) @@ -28,4 +33,5 @@ export default Actions({ return appActions.setUser(user); }); }); + return appActions; }); diff --git a/common/app/flux/Store.js b/common/app/flux/Store.js index 09d50e69c0..c745e16ac0 100644 --- a/common/app/flux/Store.js +++ b/common/app/flux/Store.js @@ -1,7 +1,8 @@ import { Store } from 'thundercats'; -const { createRegistrar, setter } = Store; +const { createRegistrar, setter, fromMany } = Store; const initValue = { + title: 'Learn To Code | Free Code Camp', username: null, picture: null, points: 0 @@ -10,9 +11,10 @@ const initValue = { export default Store(initValue) .refs({ displayName: 'AppStore' }) .init(({ instance: appStore, args: [cat] }) => { - const { setUser } = cat.getActions('appActions'); + const { setUser, setTitle } = cat.getActions('appActions'); const register = createRegistrar(appStore); - register(setter(setUser)); + + register(setter(fromMany(setUser, setTitle))); return appStore; }); diff --git a/common/app/routes/Hikes/components/Hikes.jsx b/common/app/routes/Hikes/components/Hikes.jsx index f56e57f298..76632a1456 100644 --- a/common/app/routes/Hikes/components/Hikes.jsx +++ b/common/app/routes/Hikes/components/Hikes.jsx @@ -10,6 +10,7 @@ import HikesMap from './Map.jsx'; export default contain( { store: 'hikesStore', + actions: ['appActions'], fetchAction: 'hikesActions.fetchHikes', getPayload: ({ hikes, params }) => ({ isPrimed: (hikes && !!hikes.length), @@ -23,11 +24,17 @@ export default contain( displayName: 'Hikes', propTypes: { + appActions: PropTypes.object, children: PropTypes.element, currentHike: PropTypes.object, hikes: PropTypes.array }, + componentWillMount() { + const { appActions } = this.props; + appActions.setTitle('Hikes'); + }, + renderMap(hikes) { return ( diff --git a/server/boot/a-react.js b/server/boot/a-react.js index 9cf7d06f69..a723b805ad 100644 --- a/server/boot/a-react.js +++ b/server/boot/a-react.js @@ -51,9 +51,13 @@ export default function reactSubRouter(app) { // makes sure we only get one onNext and closes subscription .flatMap(function({ data, markup }) { debug('react rendered'); + const { title } = data.AppStore; res.expose(data, 'data'); // now render jade file with markup injected from react - return res.render$('layout-react', { markup: markup }); + return res.render$( + 'layout-react', + { markup, title } + ); }) .subscribe( function(markup) { diff --git a/server/views/layout-react.jade b/server/views/layout-react.jade index f77aa0ec75..70093ecb05 100644 --- a/server/views/layout-react.jade +++ b/server/views/layout-react.jade @@ -1,6 +1,10 @@ doctype html html(ng-app='profileValidation', lang='en') head + if title + title= title + else + title redirecting to | Free Code Camp include partials/small-head body.top-and-bottom-margins(style='overflow: hidden') .container diff --git a/server/views/partials/small-head.jade b/server/views/partials/small-head.jade index 552b9d815b..5913fc223c 100644 --- a/server/views/partials/small-head.jade +++ b/server/views/partials/small-head.jade @@ -7,7 +7,6 @@ link(rel='stylesheet', href='/css/lib/Vimeo.css') // End **REQUIRED** includes include meta -title redirecting to | Free Code Camp meta(charset='utf-8') meta(http-equiv='X-UA-Compatible', content='IE=edge') meta(name='viewport', content='width=device-width, initial-scale=1.0')