PageRenderTime 40ms CodeModel.GetById 2ms app.highlight 33ms RepoModel.GetById 1ms app.codeStats 0ms

/www/js/app.js

https://bitbucket.org/izalutsky/vchat
JavaScript | 446 lines | 313 code | 53 blank | 80 comment | 5 complexity | b0951c1cb24fed26f793311448769cbc MD5 | raw file
  1
  2(function(){
  3
  4    "use strict";
  5
  6    if (!window.vchat) {
  7        window.vchat = {};
  8    }
  9    var vchat = window.vchat;
 10
 11/**
 12 * Wraps the iScroll object, providing fix() workaround for content scrolling too high
 13 * @param nodeId id of scroller DOM element
 14 * @constructor
 15 */
 16function ScrollWrapper(nodeId){
 17    /*jshint newcap:false */
 18    this.lastScrollY = 0;
 19    this.offset = 50;
 20    this.node = document.getElementById(nodeId);
 21    this.iScroll = new iScroll(nodeId);
 22}
 23
 24/**
 25 * Limits maximum scrolling offset
 26 */
 27ScrollWrapper.prototype.fix = function(){
 28    /*
 29    if (this.iScroll.maxScrollY !== this.iScroll.lastScrollY) {
 30        this.iScroll.maxScrollY += this.node.offsetHeight - this.offset;
 31        this.lastScrollY = this.iScroll.maxScrollY;
 32    }
 33    */
 34};
 35
 36
 37
 38
 39/**
 40 * Creates an object with precompiled templating methods
 41 * @param {String[]} names Array of template names
 42 * @constructor
 43 */
 44function Templater(){
 45    var that = this;
 46    var templates = $("[data-template-name]");
 47    templates.each(function(){
 48        var element = $(this);
 49        var name = element.attr("data-template-name");
 50        var source = element.html();
 51        that[name] = Handlebars.compile(source);
 52    });
 53}
 54/*
 55    Application start code. Exeduted before creation of any models or views
 56*/
 57
 58var templater = new Templater();
 59/**
 60 * Model of Dashboard entity
 61 * @type {*}
 62 */
 63var BoardModel = Backbone.Model.extend({
 64    defaults: {
 65        boardInfo: ''
 66    },
 67
 68    initialize: function()
 69    {
 70        var that = this;
 71        $.get(
 72            "http://vapes.ws/videochat/mobile/readboard.php",
 73            function(data)
 74            {
 75                console.log(data);
 76                that.set({
 77                    boardInfo: data
 78                });
 79            }
 80        );
 81    }
 82});
 83/**
 84 * Model of a single chat message
 85 * @type {*}
 86 */
 87var ChatMessageModel = Backbone.Model.extend({
 88    defaults: {
 89        userName: "",
 90        text: ""
 91    },
 92    initialize: function(){
 93
 94    }
 95});
 96
 97/**
 98 * Collection of tweets
 99 * @type {*}
100 */
101var ChatList = Backbone.Collection.extend({
102    model: ChatMessageModel
103});
104
105/**
106 * Model of Chat entity
107 * @type {*}
108 */
109
110var ChatModel = Backbone.Model.extend({
111    defaults: {
112        timeout: 1000 * 2,
113        chatUrl: 'http://vapes.ws/videochat/mobile/readchatmessages.php',
114        chatText: '',
115        chats: new ChatList()
116    },
117
118    initialize: function()
119    {
120        var that = this;
121        that.startPoll();
122    },
123
124    startPoll: function(){
125        var that = this;
126        that.getMessages();
127        setTimeout(function(){
128            that.startPoll();
129        }, that.get("timeout"));
130    },
131
132    getMessages: function()
133    {
134        var model = this;
135        console.log(model.get("chatUrl"));
136        $.getJSON(model.get("chatUrl"), function(data){
137            console.log(data);
138            model.addMessages(data);
139        });
140    },
141
142    addMessages: function(chats)
143    {
144        var chatMessageModels = _.map(chats, function(chat){
145            console.log(chat.userName);
146            return new ChatMessageModel({
147                userName: chat.userName,
148                text: chat.userMessage
149            });
150        });
151        var collection = this.get("chats");
152        collection.reset(chatMessageModels);
153        this.trigger("change");
154    }
155});
156/**
157 * Model of Geolocation entity
158 * @type {*}
159 */
160var LocationModel = Backbone.Model.extend({
161    defaults: {
162        url: "http://vapes.ws/videochat/mobile/readlatlng.php",
163        lat: 0,
164        lng: 0
165    },
166    initialize: function(){
167        var that = this;
168        $.getJSON(
169            that.get("url"),
170            function(data){
171                if (data){
172                    that.set({
173                        lat: data.lat,
174                        lng: data.lng
175                    });
176                }
177            }
178        );
179    }
180});
181/**
182 * Model of a single tweet
183 * @type {*}
184 */
185var TweetModel = Backbone.Model.extend({
186    defaults: {
187        userName: "",
188        text: "",
189        picUrl: ""
190    },
191    initialize: function(){
192
193    }
194});
195
196/**
197 * Collection of tweets
198 * @type {*}
199 */
200var TweetList = Backbone.Collection.extend({
201    model: TweetModel
202});
203
204/* TODO refactor URLs to baseUrl */
205
206/**
207 * Model of Twitter entity
208 * @type {*}
209 */
210var TwitterModel = Backbone.Model.extend({
211    defaults: {
212        timeout: 1000 * 60,
213        tagUrl: "http://vapes.ws/videochat/mobile/readtweettag.php",
214        queryUrl: "http://vapes.ws/videochat/mobile/tweetSearch.php?act=search&q=",
215        tweets: new TweetList()
216    },
217    initialize: function(){
218        var that = this;
219        that.get("tweets").on("change", function(){        // passing collection change event to current model
220            that.trigger("change");
221        });
222        this.startPoll();
223    },
224    startPoll: function(){
225        var that = this;
226        that.queryTag();
227        setTimeout(function(){
228            that.startPoll();
229        }, that.get("timeout"));
230    },
231    queryTag: function(){
232        var model = this;
233        $.getJSON(model.get("tagUrl"), function(data){
234            var query = data.tag;
235            model.queryTweets(query);
236        });
237    },
238    queryTweets: function(query){
239        var model = this;
240        $.getJSON(model.get("queryUrl") + query, function(response){
241            model.addTweets(response.results);
242        });
243    },
244    addTweets: function(tweets){
245        var tweetModels = _.map(tweets, function(tweet){
246            return new TweetModel({
247                userName: tweet.from_user,
248                text: tweet.text,
249                picUrl: tweet.profile_image_url
250            });
251        });
252        var collection = this.get("tweets");
253        collection.reset(tweetModels);
254        this.trigger("change");
255    }
256});
257
258//TODO implement videochat model
259
260/**
261 * Main view of Dashboard entity
262 * @type {*}
263 */
264var BoardView = Backbone.View.extend({
265    initialize: function()
266    {
267        this.el = $("#text");
268        this.model.on("change", this.render, this);
269        this.iscroll = new ScrollWrapper("board");
270    },
271
272    render: function(){
273        this.el.html(this.model.get("boardInfo"));
274        this.iscroll.fix();
275    }
276});
277
278//TODO implement chat and message views
279
280var ChatView = Backbone.View.extend({
281
282    el: $("#chat"),
283
284    initialize: function()
285    {
286        this.userMessage = $("#userMessage");
287        //this.el = $("#chat");
288        //this.el2 = $("#chatMessages2");
289
290        this.model.on("change", this.render, this);
291    },
292
293    events:
294    {
295        "click #sendMessage": "onSendMessage"
296    },
297
298    render: function(){
299        var json = {
300            chats: this.model.get("chats").toJSON()
301        };
302        var chatM = templater.chats(json);
303        //this.el.children("#chatMessages").html(chatM);
304        var messages = this.$("#chatMessages");
305        messages.html(chatM);
306        //this.el2.html(chatM);
307        /*jshint newcap:false */
308        var scroll = new iScroll("chatMessages");
309        var height = messages.height();
310        scroll.pageY = height;
311        //var scroll2 = new iScroll("chatMessages2");
312    },
313
314    onSendMessage: function()
315    {
316        var uName = window.vchat.userName;
317        var uMessage = this.userMessage.val().trim();
318
319
320        console.log(uName);
321        console.log(uMessage);
322
323        $.post('http://vapes.ws/videochat/mobile/server.php', {user: uName, msg: uMessage}, function(response){
324            console.log("mess send");
325            $("#userMessage").val("");
326        });
327    }
328});
329
330/**
331 * Main view of Geolocation entity as a map
332 * @type {*}
333 */
334var LocationView = Backbone.View.extend({
335    initialize: function(){
336        this.leafletScriptPath = "./leaflet/leaflet.js";
337        vchat.loader.require(this.leafletScriptPath);
338        this.el = $("#map");
339        this.minZoom = 3;
340        this.maxZoom = 18;
341        this.initialZoom = 13;
342        this.model.on("change", this.render, this);
343    },
344    render: function(){
345        var view = this;
346        // setting fixed height to map container due to Leaflet requirements
347        this.el.height(this.el.parent().height());
348        // map needs Leaflet script to be loaded before rendering
349        vchat.loader.require(this.leafletScriptPath, function(){
350            var map = new L.Map('map');
351
352            var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
353            var osmAttrib = 'Map data © OpenStreetMap contributors';
354            var osm = new L.TileLayer(osmUrl, {
355                minZoom: view.minZoom,
356                maxZoom: view.maxZoom,
357                attribution: osmAttrib
358            });
359
360            var latitude = view.model.get("lat");
361            var longitude = view.model.get("lng");
362
363            map.setView(new L.LatLng(latitude, longitude), view.initialZoom);
364            map.addLayer(osm);
365            L.marker([latitude, longitude]).addTo(map);
366        });
367    }
368});
369/**
370 * Main view of Twitter entity as a list of tweets
371 * @type {*}
372 */
373var TwitterView = Backbone.View.extend({
374    initialize: function(){
375        this.model.on("change", this.render, this);
376        this.el = $("#tweets");
377    },
378    render: function(){
379        var json = {
380            tweets: this.model.get("tweets").toJSON()
381        };
382        var markup = templater.tweets(json);
383        this.el.html(markup);
384        /*jshint newcap:false */
385       var scroll = new iScroll("twitter");
386    }
387});
388
389
390//TODO implement video chat view with HTML5 Video
391
392var location = new LocationModel();
393var map = new LocationView({ model: location });
394
395var boardModel = new BoardModel();
396var borderView = new BoardView({ model: boardModel });
397
398var chatModel = new ChatModel();
399var chatView = new ChatView({ model: chatModel });
400
401var twitter = new TwitterModel();
402var twitterView = new TwitterView({model: twitter});
403
404
405var PageRouter = Backbone.Router.extend({
406    initialize: function(){
407        var that = this;
408        that.currentPageName = null;
409        that.pages = {};
410        that.links = {};
411        $("nav a").each(function(){
412            var link = $(this);
413            var pageName = link.attr("href").slice(1);
414            that.links[pageName] = link;
415            that.pages[pageName] = $("#" + pageName);
416        });
417    },
418    routes: {
419        ":pageName": "pageRoute"
420    },
421    pageRoute: function(pageName) {
422
423        var lastPage = this.currentPageName;
424        if (lastPage) {
425            this.pages[lastPage].css("visibility", "hidden");
426            this.links[lastPage].removeClass("selected");
427        }
428        if (this.pages[pageName]) {
429            this.pages[pageName].css("visibility", "visible");
430            this.links[pageName].addClass("selected");
431            this.currentPageName = pageName;
432        } else {
433            console.log("No such page: " + pageName);
434        }
435    }
436});
437
438var router = new PageRouter();
439Backbone.history.start();
440router.navigate("chat", {
441    replace: true,
442    trigger: true
443});
444
445
446}());