We are looking into refactoring sonatribe to be an ember-cli SPA. Using the Discourse code base as inspiration I've been spiking various parts to see exactly how feasible this would be.
This all started with us wanting to mimic the discourse header (ignoring the messy sub header):
As you can see the header is a really nice, dock-able UI and has a lot of features. My initial thoughts after looking at the code to isolate the header were that this would be near on impossible. We wanted to do this because we want the transition from sonatribe to our discourse installation to be seamless - it's important that it feels like one app. Ignoring the obvious integration points outside of UI (things like updating sonatribe or discourse when the user receives a PM - this will come later hopefully in the form of plugins). I'd never used Ember or Ruby before and so diving into the Discourse source code was a little daunting!
Reverse engineering the code I managed to stub a lot of the code for things like preload store and bound-avatar and basically get a functioning version of the header isolated into it's own ember-cli project:
The search API is a really poor knocked-together ServiceStack API which has zero optimizations so ignore the poor perf on the results!
All well and good but I was still stubbing the preload store. This is where Discourse have done the clever thing of loading the app with all of the data it needs to render itself on boot. Looking at the Discourse HTML you can see there is a lot of JS/JSON injected in. The problem here is that ember-cli doesn't really work this way. Ember-cli gives you the folder structure to develop in and uses a filesystem watcher to recompile your code (ES6, SCSS etc) into a distributable form. It even serves the index.html inside a HTTP server for you.
Discourse works this way because the SPA knows you're logged in through the presence of a user object injected into the preload store. They use omniauth which loads a popped browser window to handle the auth mechanism - once the user has authenticated it calls into a hook (window.opener.Discourse.authenticationComplete) to notify discourse that authentication has completed and sends the result. If the user successfully authenticated the browser is reloaded and because the user is authenticated the users JSON is loaded into the preload store.
So, serving the index.html as a dynamic (is that still the right term? It sounds so ASP 3.0!!!) page is pretty much a must have.
To do this we are going to need to drop the HTTP server provided by ember-cli and work out a way to push the /dist folder to another folder which can be part of a hosted project. I'm a big fan of ServiceStack but the hosted project could literally be any language/framework.
The idea here is to have 2 projects:
- ember-cli app where we can develop the JS and CSS
- an integration project where we can host index.html and inject session state and preloaded data
The "this is a test" lines are coming from the cshtml and the ember app is booted below it! All I need to do now is get the authed user from ServiceStack and serialize whatever data we need in the UI into the preload store.