From 51e69375cc234052158c1ed9cd812c1324bc93b3 Mon Sep 17 00:00:00 2001 From: Paul McCarthy Date: Sun, 10 Mar 2013 22:12:04 -0700 Subject: [PATCH 1/8] search wip --- Blaze/Controllers/HomeController.cs | 28 +++++++++++++++++++++ Blaze/Global.asax.cs | 6 +++++ Blaze/Scripts/blaze/api.js | 21 ++++++++++++++++ Blaze/Scripts/blaze/chatcontroller.js | 13 +++++++++- Blaze/Scripts/blaze/chatview.js | 10 +++++++- Blaze/Scripts/blaze/models.js | 15 +++++++++--- Blaze/Views/Home/Chat.cshtml | 26 ++++++++++++++++++-- Blaze/Views/Home/_MessageTemplate.cshtml | 31 ++++++++++++++++++++++++ 8 files changed, 143 insertions(+), 7 deletions(-) diff --git a/Blaze/Controllers/HomeController.cs b/Blaze/Controllers/HomeController.cs index 335073e..c2f0b3e 100644 --- a/Blaze/Controllers/HomeController.cs +++ b/Blaze/Controllers/HomeController.cs @@ -201,6 +201,34 @@ private ActionResult HandleWebException(string fullUrl, WebException ex) return new FileStreamResult(response.GetResponseStream(), response.ContentType); } + [AuthActionFilter] + public ActionResult Search(string account, string url, string auth) + { + string fullUrl = string.Format("https://{0}.campfirenow.com/{1}?{2}&format=json", account, url, Request["QUERY_STRING"]); + var request = (HttpWebRequest)WebRequest.Create(fullUrl); + request.Method = "GET"; + request.ContentType = "application/json"; + request.Headers["Authorization"] = "Bearer " + auth; + try + { + var response = (HttpWebResponse)request.GetResponse(); + var reader = new StreamReader(response.GetResponseStream()); + var data = reader.ReadToEnd(); + dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject(data); + var processor = new MessageProcessor(); + foreach (var msg in obj.messages) + { + msg.parsed_body = processor.ProcessMessage(Convert.ToString(msg.body)); + } + string result = Newtonsoft.Json.JsonConvert.SerializeObject(obj); + return Content(result, "application/json"); + } + catch (WebException ex) + { + return HandleWebException(fullUrl, ex); + } + } + [AuthActionFilter] public ActionResult GetFile(string account, string auth, string url) { diff --git a/Blaze/Global.asax.cs b/Blaze/Global.asax.cs index 59ce33c..f1ed294 100644 --- a/Blaze/Global.asax.cs +++ b/Blaze/Global.asax.cs @@ -62,6 +62,12 @@ public static void RegisterRoutes(RouteCollection routes) new { controller = "Home", action = "Recent" } // Parameter defaults ); + routes.MapRoute( + "search_route", // Route name + "search/{account}/{*url}", // URL with parameters + new { controller = "Home", action = "Search" } // Parameter defaults + ); + routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters diff --git a/Blaze/Scripts/blaze/api.js b/Blaze/Scripts/blaze/api.js index 3fee8da..608e3b0 100644 --- a/Blaze/Scripts/blaze/api.js +++ b/Blaze/Scripts/blaze/api.js @@ -71,6 +71,27 @@ Campfire.prototype.uploadFile = function(roomId, data, callback) { // not completed yet! }; +Campfire.prototype.searchMessages = function (searchTerm, callback) { + var self = this; + var data = {}; + data['q'] = searchTerm; + var base = self.base.replace('/x', '/search'); + $.ajax({ + url: base + '/search', + data: data, + type: 'GET', + beforeSend: $.proxy(self.setAuthHeader, self), + success: function (reply) { + callback(reply.messages); + }, + error: function (xhr, txt, err) { + console && console.log('searchMessages failure: ' + txt + ' (' + err + ')'); + callback([]); + }, + dataType: 'json' + }); +}; + Campfire.prototype.sendMessage = function (roomId, type, message, isPaste, callback) { var self = this; if (message === '') { diff --git a/Blaze/Scripts/blaze/chatcontroller.js b/Blaze/Scripts/blaze/chatcontroller.js index 3da4140..3a53d97 100644 --- a/Blaze/Scripts/blaze/chatcontroller.js +++ b/Blaze/Scripts/blaze/chatcontroller.js @@ -171,7 +171,18 @@ ChatController.prototype.getUser = function (id) { } }; -ChatController.prototype.sendMessage = function(room, message, isPaste) { +ChatController.prototype.searchMessages = function (searchTerm) { + var self = this; + self.campfire.searchMessages(searchTerm, function (messages) { + $.each(messages, function (i, o) { + var user = o.user_id ? self.getUser(o.user_id) : new UserModel({ id: 0, name: '' }); + var messageModel = new MessageModel(o, user, self.currentUser, null, self.contentProcessor, self); + self.roomsModel.addSearchResult(messageModel); + }); + }); +}; + +ChatController.prototype.sendMessage = function (room, message, isPaste) { var self = this; var type = ''; if (message.indexOf("/play ") === 0) { diff --git a/Blaze/Scripts/blaze/chatview.js b/Blaze/Scripts/blaze/chatview.js index be0412a..9832e0a 100644 --- a/Blaze/Scripts/blaze/chatview.js +++ b/Blaze/Scripts/blaze/chatview.js @@ -48,6 +48,10 @@ ChatView.prototype.init = function (roomsModel, campfire) { var name = $(this).data('name'); self.changeRoom(name); }); + $('#tabs-search').live('click', function () { + var name = $(this).data('name'); + self.changeRoom(name); + }); $('#page').on('mouseover', '.gravatar', function () { var $source = $(this); @@ -229,13 +233,17 @@ ChatView.prototype.changeRoom = function (roomId) { } } }); + } else if (roomId == 'search') { + $('#tabs-' + roomId).addClass('current'); + $('#messages-' + roomId).addClass('current').show(); + $('#userlist-' + roomId).addClass('current').show(); } else { // lobby $('#tabs-' + roomId).addClass('current'); $('#messages-' + roomId).addClass('current').show(); $('#userlist-' + roomId).addClass('current').show(); } - $('#new-message').focus(); +$('#new-message').focus(); self.scrollToEnd(); }; diff --git a/Blaze/Scripts/blaze/models.js b/Blaze/Scripts/blaze/models.js index f3a193c..b91d165 100644 --- a/Blaze/Scripts/blaze/models.js +++ b/Blaze/Scripts/blaze/models.js @@ -121,7 +121,7 @@ function RoomModel(obj, user, prefs, controller) { }, this.editTopic = function () { self.isEditingTopic(true); - }; + }; } function RoomPreferencesModel(parent,pref) { @@ -225,6 +225,7 @@ function RoomsModel(chat) { }; this.inputMessage = ko.observable(''); this.isPaste = ko.observable(false); + this.searchTerm = ko.observable(''); this.sendMessage = function () { if (self.visibleRoom) { var isPaste = self.inputMessage().indexOf('\n') !== -1; @@ -261,6 +262,14 @@ function RoomsModel(chat) { this.signOut = function () { chat.signOut(); }; + this.searchMessages = function () { + chat.searchMessages(self.searchTerm()); + }; + this.searchResults = ko.observableArray([]); + this.isVisible = ko.observable(false); + this.addSearchResult = function (searchResult) { + self.searchResults.push(searchResult); + }; } function UserModel(obj) { var self = this; @@ -337,7 +346,7 @@ function MessageModel(obj, user, currentUser, prevMsg, emoji, chat) { this.showUser = ko.computed(function () { if (self.isTimestamp()) return false; - if (self.previousMessage === undefined) + if (self.previousMessage === undefined || self.previousMessage === null) return true; if(self.previousMessage.isNotification()) return true; @@ -407,4 +416,4 @@ function MessageModel(obj, user, currentUser, prevMsg, emoji, chat) { self.chat.starMessage(self); return false; }; -} \ No newline at end of file +} diff --git a/Blaze/Views/Home/Chat.cshtml b/Blaze/Views/Home/Chat.cshtml index f12e8f9..070d617 100644 --- a/Blaze/Views/Home/Chat.cshtml +++ b/Blaze/Views/Home/Chat.cshtml @@ -39,17 +39,21 @@ @@ -91,6 +95,12 @@
+ + @@ -99,6 +109,18 @@ diff --git a/Blaze/Views/Home/_MessageTemplate.cshtml b/Blaze/Views/Home/_MessageTemplate.cshtml index 43b5597..5bd0a0f 100644 --- a/Blaze/Views/Home/_MessageTemplate.cshtml +++ b/Blaze/Views/Home/_MessageTemplate.cshtml @@ -89,7 +89,7 @@ - ${when} + ${day} Open From 5a3c8fc7f0d70effedda186706a84b70741ad8b8 Mon Sep 17 00:00:00 2001 From: Paul McCarthy Date: Sun, 17 Mar 2013 22:23:29 -0700 Subject: [PATCH 4/8] transcripts from search --- Blaze/Controllers/HomeController.cs | 28 ++++++++++++++++++++++++ Blaze/Global.asax.cs | 6 +++++ Blaze/Scripts/blaze/api.js | 19 ++++++++++++++++ Blaze/Scripts/blaze/chatcontroller.js | 26 +++++++++++++++++++++- Blaze/Scripts/blaze/chatview.js | 8 ++----- Blaze/Scripts/blaze/models.js | 13 ++++++++++- Blaze/Views/Home/Chat.cshtml | 15 +++++++++---- Blaze/Views/Home/_MessageTemplate.cshtml | 2 +- 8 files changed, 104 insertions(+), 13 deletions(-) diff --git a/Blaze/Controllers/HomeController.cs b/Blaze/Controllers/HomeController.cs index c2f0b3e..f9febc3 100644 --- a/Blaze/Controllers/HomeController.cs +++ b/Blaze/Controllers/HomeController.cs @@ -229,6 +229,34 @@ public ActionResult Search(string account, string url, string auth) } } + [AuthActionFilter] + public ActionResult Transcript(string account, string url, string auth) + { + string fullUrl = string.Format("https://{0}.campfirenow.com/room/{1}?format=json", account, url, Request["QUERY_STRING"]); + var request = (HttpWebRequest)WebRequest.Create(fullUrl); + request.Method = "GET"; + request.ContentType = "application/json"; + request.Headers["Authorization"] = "Bearer " + auth; + try + { + var response = (HttpWebResponse)request.GetResponse(); + var reader = new StreamReader(response.GetResponseStream()); + var data = reader.ReadToEnd(); + dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject(data); + var processor = new MessageProcessor(); + foreach (var msg in obj.messages) + { + msg.parsed_body = processor.ProcessMessage(Convert.ToString(msg.body)); + } + string result = Newtonsoft.Json.JsonConvert.SerializeObject(obj); + return Content(result, "application/json"); + } + catch (WebException ex) + { + return HandleWebException(fullUrl, ex); + } + } + [AuthActionFilter] public ActionResult GetFile(string account, string auth, string url) { diff --git a/Blaze/Global.asax.cs b/Blaze/Global.asax.cs index f1ed294..1f3bd2f 100644 --- a/Blaze/Global.asax.cs +++ b/Blaze/Global.asax.cs @@ -68,6 +68,12 @@ public static void RegisterRoutes(RouteCollection routes) new { controller = "Home", action = "Search" } // Parameter defaults ); + routes.MapRoute( + "transcript_route", // Route name + "transcript/{account}/{*url}", // URL with parameters + new { controller = "Home", action = "Transcript" } // Parameter defaults + ); + routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters diff --git a/Blaze/Scripts/blaze/api.js b/Blaze/Scripts/blaze/api.js index 608e3b0..48c12dd 100644 --- a/Blaze/Scripts/blaze/api.js +++ b/Blaze/Scripts/blaze/api.js @@ -129,6 +129,25 @@ Campfire.prototype.starMessage = function (message) { }); }; +Campfire.prototype.transcript = function (room, message, callback) { + var self = this; + var base = self.base.replace('/x', '/transcript'); + var d = new Date(message.created_at()); + $.ajax({ + url: base + '/' + room.id() + '/transcript/' + (d.getYear() + 1900) + '/' + (d.getMonth()+1) + '/' + d.getDate(), + type: 'GET', + beforeSend: $.proxy(self.setAuthHeader, self), + success: function (reply) { + callback(reply.messages, message); + }, + error: function (xhr, txt, err) { + console && console.log('transcript failure: ' + txt + ' (' + err + ')'); + callback([]); + }, + dataType: 'json' + }); +}; + Campfire.prototype.getUsers = function (roomId, callback) { var self = this; $.ajax({ diff --git a/Blaze/Scripts/blaze/chatcontroller.js b/Blaze/Scripts/blaze/chatcontroller.js index 3a53d97..b7330dd 100644 --- a/Blaze/Scripts/blaze/chatcontroller.js +++ b/Blaze/Scripts/blaze/chatcontroller.js @@ -180,6 +180,7 @@ ChatController.prototype.searchMessages = function (searchTerm) { self.roomsModel.addSearchResult(messageModel); }); }); + self.view.changeRoom('search'); }; ChatController.prototype.sendMessage = function (room, message, isPaste) { @@ -220,4 +221,27 @@ ChatController.prototype.signOut = function () { ChatController.prototype.changeTopic = function(room) { var self = this; self.campfire.changeTopic(room.id(), room.topic()); -}; \ No newline at end of file +}; + + +ChatController.prototype.transcript = function (room, message) { + var self = this; + self.roomsModel.clearTranscriptMessages(); + self.view.changeRoom('transcript'); + self.campfire.transcript(room, message, function (messages, selectedMessage) { + $.each(messages, function (i, o) { + var user = o.user_id ? self.getUser(o.user_id) : new UserModel({ id: 0, name: '' }); + var isSeparator = self.checkForSeparator(o, room.lastMessage); + if (o.type !== 'TimestampMessage' || isSeparator) { + var messageModel = new MessageModel(o, user, self.currentUser, null, self.contentProcessor, self); + self.roomsModel.addTranscriptMessage(messageModel); + //if (messageModel.type() === 'UploadMessage') { + // self.campfire.getUploadedMessage(room.id(), o.id, function (up) { + // messageModel.parsed_body(self.getBodyForUploadedMessage(up)); + // }); + //} + } + }); + $('#messages-transcript #m-' + message.id())[0].scrollIntoView(true); + }); +}; diff --git a/Blaze/Scripts/blaze/chatview.js b/Blaze/Scripts/blaze/chatview.js index 318ec24..76596a7 100644 --- a/Blaze/Scripts/blaze/chatview.js +++ b/Blaze/Scripts/blaze/chatview.js @@ -44,11 +44,7 @@ ChatView.prototype.init = function (roomsModel, campfire) { $(this).insertAtCaret('\n'); } }); - $('#tabs-lobby').live('click', function () { - var name = $(this).data('name'); - self.changeRoom(name); - }); - $('#tabs-search').live('click', function () { + $('#tabs-lobby, #tabs-search, #tabs-transcript').on('click', function () { var name = $(this).data('name'); self.changeRoom(name); }); @@ -236,7 +232,7 @@ ChatView.prototype.changeRoom = function (roomId) { } }); $('#send-message').show(); - } else if (roomId == 'search') { + } else if (roomId == 'search' || roomId == 'transcript') { $('#tabs-' + roomId).addClass('current'); $('#messages-' + roomId).addClass('current').show(); $('#userlist-' + roomId).addClass('current').show(); diff --git a/Blaze/Scripts/blaze/models.js b/Blaze/Scripts/blaze/models.js index b02b978..70e8a4e 100644 --- a/Blaze/Scripts/blaze/models.js +++ b/Blaze/Scripts/blaze/models.js @@ -266,10 +266,17 @@ function RoomsModel(chat) { chat.searchMessages(self.searchTerm()); }; this.searchResults = ko.observableArray([]); + this.transcriptMessages = ko.observableArray([]); this.isVisible = ko.observable(false); this.addSearchResult = function (searchResult) { self.searchResults.push(searchResult); }; + this.clearTranscriptMessages = function () { + self.transcriptMessages.removeAll(); + }; + this.addTranscriptMessage = function (message) { + self.transcriptMessages.push(message); + }; } function UserModel(obj) { var self = this; @@ -314,7 +321,11 @@ function MessageModel(obj, user, currentUser, prevMsg, emoji, chat) { this.description = ko.observable(obj.description); this.descriptionIsUrl = function () { return self.description().indexOf("http") === 0; - } + }; + this.getTranscript = function () { + self.chat.transcript(self.room, self); + return false; + }; this.url = ko.observable(obj.url); this.when = ko.computed(function () { var d = new Date(self.created_at()); diff --git a/Blaze/Views/Home/Chat.cshtml b/Blaze/Views/Home/Chat.cshtml index 77b4ed1..4f92be8 100644 --- a/Blaze/Views/Home/Chat.cshtml +++ b/Blaze/Views/Home/Chat.cshtml @@ -44,16 +44,20 @@
  • -
  • +
  • + +
  • @@ -122,6 +126,9 @@ + + @@ -130,7 +137,7 @@