| ... | ... |
@@ -143,6 +143,9 @@ this.App = |
| 143 | 143 |
setHistory: (me, chatId, attendant, state, onSuccess) -> |
| 144 | 144 |
App.Com.trigger(event: 'app.chat.setHistorySaving', data: {me: me, chatId: chatId, attendant: attendant, enable: state}, success: onSuccess)
|
| 145 | 145 |
|
| 146 |
+ loadHistory: (me, chatId, attendant, step, onSuccess) -> |
|
| 147 |
+ App.Com.trigger(event: 'app.chat.loadHistory', data: {me: me, chatId: chatId, attendant: attendant, step: step}, success: onSuccess)
|
|
| 148 |
+ |
|
| 146 | 149 |
_setupBackboneComponents: -> |
| 147 | 150 |
App.Collections.contacts = new Xmpp.Collections.ContactsCollection() |
| 148 | 151 |
App.Collections.chats = new Xmpp.Collections.ChatsCollection() |
| ... | ... |
@@ -100,6 +100,5 @@ class Xmpp.Collections.ChatsCollection extends Backbone.Collection |
| 100 | 100 |
@activeChat = null |
| 101 | 101 |
@models = _.without(@openedChats, chat) |
| 102 | 102 |
|
| 103 |
- createTempContact: (jid) -> |
|
| 104 |
- newTempContact = new Xmpp.Models.Contact(jid: jid, belongsTo: [App.Models.me]) |
|
| 105 |
- newTempContact |
|
| 106 | 103 |
\ No newline at end of file |
| 104 |
+ @createTempContact: (jid) -> |
|
| 105 |
+ new Xmpp.Models.Contact(id: jid, jid: jid, belongsTo: [App.Models.me]) |
|
| 107 | 106 |
\ No newline at end of file |
| ... | ... |
@@ -1,6 +1,6 @@ |
| 1 | 1 |
.conversation.clear.border |
| 2 | 2 |
.history-settings |
| 3 |
- %a.left{href: '#'} #{I18n.t('chat.history.load')}
|
|
| 3 |
+ %a.left.load-history{href: '#'} #{I18n.t('chat.history.load')}
|
|
| 4 | 4 |
|
| 5 | 5 |
%input.hidden{ type: 'checkbox', name: 'enable-history', value: '1', id: 'ihistory', checked: 'checked'}
|
| 6 | 6 |
%label.right.action.enabled{ for: 'ihistory' } #{I18n.t('chat.history.disable')}
|
| ... | ... |
@@ -7,10 +7,12 @@ class Xmpp.Views.Chat.WindowView extends Backbone.View |
| 7 | 7 |
|
| 8 | 8 |
maxHistoryLength: 20 |
| 9 | 9 |
savingHistory: true |
| 10 |
+ historyStep: 0 |
|
| 10 | 11 |
|
| 11 | 12 |
events: |
| 12 | 13 |
'submit #msg-writer': (e) -> @sendMessage(e) |
| 13 | 14 |
'change .history-settings input': 'changeHistorySettings' |
| 15 |
+ 'click .history-settings .load-history': 'loadHistory' |
|
| 14 | 16 |
|
| 15 | 17 |
initialize: (options) -> |
| 16 | 18 |
_.bindAll(this) |
| ... | ... |
@@ -18,12 +20,15 @@ class Xmpp.Views.Chat.WindowView extends Backbone.View |
| 18 | 18 |
@tab = options.tab |
| 19 | 19 |
|
| 20 | 20 |
chatId = @tab.getChatId() |
| 21 |
- attendant = if not chatId then @tab.getAttendant().getPreferredResource() else null |
|
| 21 |
+ attendant = if not chatId then @tab.getAttendant().get('jid') else null
|
|
| 22 |
+ |
|
| 22 | 23 |
App.Com.checkSavingHistory(App.Models.me.get('jid'), chatId, attendant, (canSave) =>
|
| 23 | 24 |
@savingHistory = canSave |
| 24 | 25 |
@_changeHistoryVisibly(@savingHistory) |
| 25 | 26 |
) |
| 26 | 27 |
|
| 28 |
+ @loadHistory() |
|
| 29 |
+ |
|
| 27 | 30 |
render: -> |
| 28 | 31 |
historyStackHtml = _.map(@historyStack, (view) -> |
| 29 | 32 |
view.render().el.outerHTML |
| ... | ... |
@@ -87,11 +92,14 @@ class Xmpp.Views.Chat.WindowView extends Backbone.View |
| 87 | 87 |
@log(messageView) |
| 88 | 88 |
Backbone.Events.trigger('resizeWorkspace')
|
| 89 | 89 |
|
| 90 |
- log: (view) -> |
|
| 90 |
+ log: (view, isHistoryMessage) -> |
|
| 91 | 91 |
if (@historyStack.length + 1 >= @maxHistoryLength) |
| 92 | 92 |
@historyStack = @historyStack.slice(@historyStack.length - @maxHistoryLength + 1) |
| 93 | 93 |
|
| 94 |
- @historyStack.push(view) |
|
| 94 |
+ if not isHistoryMessage? || isHistoryMessage == false |
|
| 95 |
+ @historyStack.push(view) |
|
| 96 |
+ else |
|
| 97 |
+ @historyStack.unshift(view) |
|
| 95 | 98 |
|
| 96 | 99 |
changeHistorySettings: (e) -> |
| 97 | 100 |
$input = $(e.currentTarget) |
| ... | ... |
@@ -113,4 +121,29 @@ class Xmpp.Views.Chat.WindowView extends Backbone.View |
| 113 | 113 |
toDisable = '.enabled' |
| 114 | 114 |
|
| 115 | 115 |
$(@el).find(".action#{toEnable}, .current#{toEnable}").show()
|
| 116 |
- $(@el).find(".action#{toDisable}, .current#{toDisable}").hide()
|
|
| 117 | 116 |
\ No newline at end of file |
| 117 |
+ $(@el).find(".action#{toDisable}, .current#{toDisable}").hide()
|
|
| 118 |
+ |
|
| 119 |
+ prependHistoryMessage: (user, date, msg) -> |
|
| 120 |
+ messageView = new Xmpp.Views.Chat.MessageView(user: user, date: date, message: msg, fromMe: user.get('jid') == App.Models.me.get('jid'))
|
|
| 121 |
+ $(@el).find('.messages').prepend(messageView.render().el)
|
|
| 122 |
+ @log(messageView, true) |
|
| 123 |
+ |
|
| 124 |
+ loadHistory: -> |
|
| 125 |
+ chatId = @tab.getChatId() |
|
| 126 |
+ attendant = if not chatId then @tab.getAttendant().get('jid') else null
|
|
| 127 |
+ |
|
| 128 |
+ App.Com.loadHistory(App.Models.me.get('jid'), chatId, attendant, @historyStep, (result) =>
|
|
| 129 |
+ App.debug result |
|
| 130 |
+ |
|
| 131 |
+ _.each(result.history.reverse(), (message) => |
|
| 132 |
+ jid = App.stripJid(message.from) |
|
| 133 |
+ if App.Models.me.get('jid') == jid
|
|
| 134 |
+ contact = App.Models.me |
|
| 135 |
+ else |
|
| 136 |
+ contact = App.Collections.contacts.findByJid(jid) || Xmpp.Collections.ChatsCollection.createTempContact(jid) |
|
| 137 |
+ |
|
| 138 |
+ @prependHistoryMessage(contact, new Date(message.created_at), message.message) |
|
| 139 |
+ ) |
|
| 140 |
+ |
|
| 141 |
+ @historyStep++ unless _.isEmpty(result.history) |
|
| 142 |
+ ) |
| ... | ... |
@@ -1,5 +1,7 @@ |
| 1 | 1 |
class WsChatController < WsController |
| 2 | 2 |
|
| 3 |
+ require 'message_builder' |
|
| 4 |
+ |
|
| 3 | 5 |
def start_polling_messages |
| 4 | 6 |
connection_store[:clients].each do |client| |
| 5 | 7 |
client.add_message_callback do |message| |
| ... | ... |
@@ -228,6 +230,19 @@ class WsChatController < WsController |
| 228 | 228 |
User.set_history_saving(save, me, attendant, chat_id) && trigger_success |
| 229 | 229 |
end |
| 230 | 230 |
|
| 231 |
+ def load_history |
|
| 232 |
+ me = message[:me] |
|
| 233 |
+ attendant = message[:attendant] |
|
| 234 |
+ chat_id = message[:chatId] |
|
| 235 |
+ page = message[:step] |
|
| 236 |
+ per_page = 10 |
|
| 237 |
+ |
|
| 238 |
+ trigger_failure unless find_client(me) |
|
| 239 |
+ |
|
| 240 |
+ history = History.page_history(me, attendant || chat_id, page, per_page) |
|
| 241 |
+ trigger_success history: history |
|
| 242 |
+ end |
|
| 243 |
+ |
|
| 231 | 244 |
private |
| 232 | 245 |
|
| 233 | 246 |
def process_incoming_message(from, me, body, chat_id = nil) |
| ... | ... |
@@ -24,4 +24,19 @@ class History |
| 24 | 24 |
|
| 25 | 25 |
history.save |
| 26 | 26 |
end |
| 27 |
+ |
|
| 28 |
+ def self.page_history(me, with, page, per_page) |
|
| 29 |
+ # Aggregation DSL: WIP (https://github.com/mongoid/origin/pull/59) |
|
| 30 |
+ History.collection.aggregate([ |
|
| 31 |
+ {'$match' => {me: me, _with: with}},
|
|
| 32 |
+ {'$limit' => 1},
|
|
| 33 |
+ {'$project' => {:messages => 1}},
|
|
| 34 |
+ {'$unwind' => '$messages'},
|
|
| 35 |
+ {'$sort' => {'messages.created_at' => -1}},
|
|
| 36 |
+ {'$skip' => page * per_page},
|
|
| 37 |
+ {'$limit' => per_page},
|
|
| 38 |
+ {'$sort' => {'messages.created_at' => 1}},
|
|
| 39 |
+ {'$project' => {message: '$messages.message', from: '$messages.from', created_at: '$messages.created_at'}}
|
|
| 40 |
+ ]) |
|
| 41 |
+ end |
|
| 27 | 42 |
end |
| ... | ... |
@@ -72,6 +72,7 @@ WebsocketRails::EventMap.describe do |
| 72 | 72 |
subscribe :switchOwnership, to: WsChatController, with_method: :switch_ownership |
| 73 | 73 |
subscribe :canSaveHistory, to: WsChatController, with_method: :can_save_conversation? |
| 74 | 74 |
subscribe :setHistorySaving, to: WsChatController, with_method: :set_history_saving |
| 75 |
+ subscribe :loadHistory, to: WsChatController, with_method: :load_history |
|
| 75 | 76 |
end |
| 76 | 77 |
end |
| 77 | 78 |
end |