/public/messaging.js
JavaScript | 537 lines | 398 code | 69 blank | 70 comment | 17 complexity | a4f81fcceaed6bed62d3feb5e136d0a8 MD5 | raw file
- // Configuration
- var config = {
- api: 'http://192.168.0.39:8000/',
- ws_message_new: 'ws://192.168.0.39:8000/message-new/',
- ws_message_read: 'ws://192.168.0.39:8000/message-read/'
- };
- /*
- MODELS
- */
- var BaseModel = Backbone.Model.extend({
- initialize: function(options) {
- if(!_.isUndefined(options)) _.extend(this, options);
- },
- sync: function(method, model, options) {
- // Check for available access token in cookie
- // var token = $.cookie('access_token');
- if(!_.isUndefined(window.App.Session.get('auth_token')) &&
- !_.isNull(window.App.Session.get('auth_token')) &&
- window.App.Session.get('auth_token') !== 'undefined') {
- options.beforeSend = function (xhr) {
- xhr.setRequestHeader(
- 'Authorization',
- 'Token ' +
- window.App.Session.get('auth_token'));
- };
- }
- return Backbone.sync(method, model, options);
- }
- });
- var SessionModel = BaseModel.extend({
- urlRoot: config.api+'auth/',
- defaults: {
- active: false,
- username: null,
- auth_token: null
- },
- sync: function(method, model, options) {
- var self = this;
- // Check active access token
- if(!_.isUndefined(self.get('auth_token')) &&
- !_.isNull(self.get('auth_token')) &&
- self.get('auth_token') !== 'undefined') {
- // Set authorization headers
- options.beforeSend = function(xhr) {
- xhr.setRequestHeader(
- 'Authorization',
- 'Token '+
- self.get('token')
- );
- };
- }
- // Override method for logout
- if(model.url === self.urlRoot+'logout/') {
- method = 'create';
- }
- return Backbone.sync(method, model, options);
- },
- start: function(options) {
- // Get auth token from local storage
- var auth_token,
- currentSession = localStorage.getItem('session');
- if(!_.isUndefined(currentSession) && !_.isNull(currentSession)) {
- // Parse current Session to JSON object
- currentSession = JSON.parse(currentSession);
- auth_token = currentSession.auth_token;
- username = currentSession.username;
- // Set session to true, and set auth token
- this.set({
- active: true,
- username: username,
- auth_token: auth_token
- });
- // Run success callback
- options.success();
- }
- else {
- // Run error callback
- options.error();
- }
- },
- login: function(options) {
- var self = this;
- // Set login URL
- self.url = self.urlRoot + 'login/';
- // Send credentials to backend
- self.save({
- username: options.creds.username,
- password: options.creds.password
- }, {
- success: function(model) {
- // Set session as active
- self.set('active', true);
- // Remove password from model
- self.unset('password');
- // Save credentials in local storage
- var creds = model.attributes;
- localStorage.setItem('session', JSON.stringify(creds));
- // Success callback
- options.success();
- },
- error: function() {
- // Error callback
- options.error();
- }
- });
- },
- logout: function(options) {
- var self = this;
- // Set logout url
- self.url = self.urlRoot + 'logout/';
- // Send logout request
- self.destroy({
- success: function(model) {
- // Clear model
- self.clear();
- // Set active to false
- self.set('active', false);
- // Remove session from local storage
- localStorage.removeItem('session');
- // Success callback
- options.success();
- },
- error: function() {
- // Error callback
- error.callback();
- }
- });
- }
- });
- var MessageModel = BaseModel.extend({
- urlRoot: config.api+'messages/',
- url: function() {
- var url = this.urlRoot;
- if(this.id) url = url + this.id;
- return url;
- },
- defaults: {
- id: null,
- author: null,
- destination: null,
- content: null,
- created: null
- }
- });
- var NotificationModel = BaseModel.extend({
- defaults: {
- id: null,
- content_type: null,
- content_id: null,
- author: null,
- author_id: null,
- destination: null,
- destination_id: null,
- content: null,
- created: null,
- is_read: null
- }
- });
- // Immediately start session
- var AppSession = new SessionModel();
- /*
- COLLECTIONS
- */
- var MessageCollection = Backbone.Collection.extend({
- initialize: function() {
- console.log('Message Model Initialized');
- },
- url: config.api+'messages/'
- });
- var NotificationCollection = Backbone.Collection.extend({
- model: NotificationModel
- });
- // Immediately start notification
- var AppNotifications = new NotificationCollection();
- /*
- TEMPLATES AND VIEWS
- */
- var BaseView = Backbone.View.extend({
- initialize: function(options) {
- if(!_.isUndefined(options)) _.extend(this, options);
- },
- render: function(){
- this.$el.html(this.template());
- if (this.onRender) this.onRender();
- return this;
- }
- });
- var LoginView = Backbone.View.extend({
- el: '#container',
- template: _.template($('#loginTemplate').html(), {}),
- ui: {
- form: 'form#loginForm'
- },
- events: {
- 'submit form#loginForm': 'submit'
- },
- render: function(){
- this.$el.html(this.template());
- },
- submit: function(ev) {
- ev.preventDefault();
- // Get form values
- var target = ev.currentTarget,
- username = $(ev.currentTarget).find('input[name="username"]').val(),
- password = $(ev.currentTarget).find('input[name="password"]').val();
- // Check if username and password is null
- if(!_.isNull(username) && !_.isNull(password)) {
- window.App.Session.login({
- creds: {
- username: username,
- password: password
- },
- success: function() {
- // Initialize websocket
- window.App.wsInit();
- Backbone.history.navigate('#!/', {trigger: true});
- },
- error: function() {
- alert('login error');
- }
- });
- }
- }
- });
- var HeaderView = BaseView.extend({
- initialize: function(options) {
- var self = this;
- if(!_.isUndefined(options)) _.extend(this, options);
- this.listenTo(this.model, 'change', function() {
- self.render();
- });
- // Render when get a new notifications
- this.listenTo(this.notifications, 'update', function() {
- self.render();
- });
- },
- events: {
- 'click .notif-item': 'readNotification'
- },
- template: _.template($('#headerTemplate').html(), {}),
- render: function() {
- var data = {
- user: this.model.toJSON(),
- notifications: this.notifications.toJSON()
- };
- this.$el.html(this.template(data));
- return this;
- },
- readNotification: function(e) {
- var target = $(e.currentTarget),
- data_index = target.attr('data-index'),
- data_id = target.attr('data-id');
- var read = {
- id: data_id
- };
- console.log("I'm reading a notification");
- window.App.ws.message_read.send(JSON.stringify(read));
- window.App.Notifications.remove(
- window.App.Notifications.at(data_index)
- );
- }
- });
- var LayoutView = Backbone.View.extend({
- initialize: function() {
- this.childViews = {
- header: null,
- content: null
- };
- },
- el: '#container',
- region: {
- header: '#header',
- content: '#content'
- },
- template: _.template($('#layoutTemplate').html(), {}),
- render: function() {
- console.log('Rendering Header');
- this.$el.html(this.template());
- var header = new HeaderView({
- model: AppSession,
- notifications: AppNotifications
- });
- this.subRender('header', header);
- return this;
- },
- subRender: function(region, view) {
- var el = this.$(this.region[region]),
- elChildren = el.children();
- if(this.childViews[region] !== null) {
- this.childViews[region].remove();
- }
- this.childViews[region] = view;
- el.html(view.render().$el);
- return this;
- }
- });
- var InboxView = BaseView.extend({
- template: _.template($('#inboxTemplate').html(), {})
- });
- var SentView = BaseView.extend({
- template: _.template($('#sentTemplate').html(), {})
- });
- var NewMessageView = BaseView.extend({
- template: _.template($('#newMessageTemplate').html(), {}),
- events: {
- 'submit form#newMessageForm': 'submit'
- },
- submit: function(ev) {
- var self = this;
- ev.preventDefault();
- var target = ev.currentTarget,
- destination = $(target).find('input[name="destination"]').val(),
- content = $(target).find('textarea[name="content"]').val();
- this.model.save({
- destination: destination,
- content: content
- }, {
- success: function(model) {
- Backbone.history.navigate('#!/sent', {trigger: true});
- },
- error: function() {
- alert('Send Message Error');
- }
- });
- }
- });
- /*
- CONTROLLERS AND ROUTERS
- */
- var AppRouter = Backbone.Router.extend({
- routes: {
- '!/login': 'login',
- '!/logout': 'logout',
- '!/': 'inbox',
- '!/sent': 'sent',
- '!/new': 'newMessage'
- },
- layout: function() {
- // Initialize Layout
- if (!window.App.Layout) {
- window.App.Layout = new LayoutView();
- window.App.Layout.render();
- }
- },
- login: function() {
- var login = new LoginView();
- login.render();
- },
- logout: function() {
- window.App.Session.logout({
- success: function() {
- Backbone.history.navigate('#!/login', {trigger: true});
- },
- error: function() {
- alert('Error logout');
- }
- });
- },
- inbox: function() {
- // Render layout if not initialized
- this.layout();
- var inbox = new InboxView();
- window.App.Layout.subRender('content', inbox);
- },
- sent: function() {
- // Render layout if not initialized
- this.layout();
- var sent = new SentView();
- window.App.Layout.subRender('content', sent);
- },
- newMessage: function() {
- // Render layout if not initialized
- this.layout();
- var Message = new MessageModel();
- var newMessage = new NewMessageView({
- model: Message
- });
- window.App.Layout.subRender('content', newMessage);
- }
- });
- /*
- APPLICATION
- */
- function App() {
- var self = this;
- // App initialization
- this.initialize = function() {
- // Start backbone history
- Backbone.history.start();
- // Start session initialization
- this.Session.start({
- success: function() {
- // Initialize websocket
- self.wsInit();
- // Redirect to / if authenticated
- Backbone.history.navigate('!/', {trigger: true});
- },
- error: function() {
- // Redirect to login if not authenticated
- Backbone.history.navigate('!/login', {trigger: true});
- }
- });
- };
- // Initialize session
- this.Session = AppSession;
- // Initialize router
- this.Router = new AppRouter();
- // Initialize notifications
- this.Notifications = AppNotifications;
- // Initialize websocket
- this.ws = {};
- this.wsInit = function() {
- // Get username
- var username = self.Session.get('username');
- // Initialize websocket connection for new message
- this.ws.message_new = new WebSocket(
- config.ws_message_new+username
- );
- this.ws.message_new.onopen = function() {
- waitForConnection(self.ws.message_new, function() {
- console.log('Channel New Message for', username, 'is opened');
- }, 1000);
- };
- this.ws.message_new.onerror = function(error) {
- alert('Websocket error: ', error);
- };
- this.ws.message_new.onmessage = function(e){
- var data = JSON.parse(e.data);
- var newNotification = new NotificationModel(data);
- self.Notifications.add(newNotification);
- };
- // Initialize websocket connection for read message
- this.ws.message_read = new WebSocket(
- config.ws_message_read+username
- );
- this.ws.message_read.onopen = function() {
- waitForConnection(self.ws.message_read, function() {
- console.log('Channel Read Message for', username, 'is opened');
- }, 1000);
- };
- this.ws.message_read.onerror = function(error) {
- alert('Websocket error: ', error);
- };
- this.ws.message_read.onmessage = function(e){
- // var data = JSON.parse(e.data);
- console.log(e);
- };
- };
- // Run the initialization
- this.initialize();
- }
- /*
- UTILITIES
- */
- function waitForConnection(ws, cb, interval) {
- if(ws.readyState === 1) {
- cb();
- }
- else {
- setTimeout(function() {
- waitForConnection(cb, interval);
- }, interval);
- }
- }
- // Running the app
- var app = new App();
- // Register app to window
- window.App = app;