Browse code

Spravanie multichatu, ked posledny clovek odide alebo je vykopnuty

Cinan Rakosnik authored on 02/05/2013 at 12:24:14
Showing 9 changed files
... ...
@@ -76,6 +76,12 @@ this.App =
76 76
         )
77 77
       )
78 78
 
79
+    iClosedMultichat: (chatId, jid) ->
80
+      @trigger(event: 'app.chat.iClosedMultichat', data: {chatId: chatId, me: jid})
81
+
82
+    kickFromMultichat: (chatId, me, jidToKick) ->
83
+      @trigger(event: 'app.chat.kickFromMultichat', data: {chatId: chatId, me: me, kick: jidToKick})
84
+
79 85
     syncMultiChatContacts: (me, chatId) ->
80 86
       @trigger(event: 'app.chat.syncMultiChatContacts', data: {me: me, chatId: chatId}, success: (contacts) =>
81 87
         App.debug contacts
... ...
@@ -116,6 +122,14 @@ this.App =
116 116
           contact.setUsingMyApp()
117 117
       )
118 118
 
119
+      App._dispatcher.bind('app.chat.destroyMultichat', (data) ->
120
+        chatId = data.chat_id
121
+        chat = App.Collections.chats.findById(chatId)
122
+        if chat
123
+          App.debug 'destroying multicat from outside'
124
+          Backbone.Events.trigger('closeChat', chat, true)
125
+      )
126
+
119 127
       App._dispatcher.bind('app.chat.importChat', (chatData) ->
120 128
         newChat = new Xmpp.Models.Chat(
121 129
           chatId: chatData.chat_id,
... ...
@@ -75,8 +75,11 @@ class Xmpp.Collections.ChatsCollection extends Backbone.Collection
75 75
   initialize: ->
76 76
     _.bindAll(this)
77 77
 
78
-    Backbone.Events.on('closeChat', (tab, chat) =>
78
+    Backbone.Events.on('closeChat', (chat, ignoreCheckIfMultichat) =>
79 79
       @removeChat(chat)
80
+      if not ignoreCheckIfMultichat
81
+        if (chat.get('isMultiChat'))
82
+          App.Com.iClosedMultichat(chat.get('chatId'), App.Models.me.get('jid'))
80 83
     )
81 84
 
82 85
     Backbone.Events.on('openChat', (chat) =>
... ...
@@ -94,6 +97,7 @@ class Xmpp.Collections.ChatsCollection extends Backbone.Collection
94 94
     )
95 95
 
96 96
   removeChat: (chat) ->
97
+    @activeChat = null
97 98
     @models = _.without(@openedChats, chat)
98 99
 
99 100
   createTempContact: (jid) ->
... ...
@@ -45,8 +45,8 @@ class Xmpp.Collections.ContactsCollection extends Backbone.Collection
45 45
       @moveToActiveList(chat.get('withWhom'))
46 46
     )
47 47
 
48
-    Backbone.Events.on('closeChat', (tab, chat) =>
49
-      @moveToInactiveList(chat.get('withWhom'))
48
+    Backbone.Events.on('closeChat', (chat) =>
49
+      @moveToInactiveList('all')
50 50
     )
51 51
 
52 52
   appendContact: (contact) ->
... ...
@@ -7,6 +7,7 @@ class Xmpp.Views.Contacts.ContactView extends Backbone.View
7 7
 
8 8
   events:
9 9
     'click .invite': 'inviteToMultichat'
10
+    'click .kick': 'kickFromMultiChat'
10 11
     'click .multichat': 'newMultiChat'
11 12
     click: 'startChat'
12 13
     mouseover: 'showIcons'
... ...
@@ -72,15 +73,26 @@ class Xmpp.Views.Contacts.ContactView extends Backbone.View
72 72
     App.Collections.chats.add(newChat)
73 73
     App.Com.openNewMultiChat(App.Models.me, withWhom, newChat)
74 74
 
75
+  kickFromMultiChat: (e) ->
76
+    e.stopPropagation();
77
+    App.debug 'kick him from multichat!'
78
+
79
+    multichat = App.Collections.chats.activeChat
80
+    if not multichat or not multichat.get('isMultiChat')
81
+      return
82
+
83
+    App.Com.kickFromMultichat(multichat.get('chatId'), App.Models.me.get('jid'), @model.get('jid'))
84
+    App.Collections.contacts.moveToInactiveList(@model)
85
+
75 86
   openChatById: (chatId) ->
76
-    chat = App.Collections.chats.findById(chatId)
87
+    App.Collections.chats.findById(chatId)
77 88
 
78 89
   showIcons: ->
79 90
     activeChat = App.Collections.chats.activeChat
80 91
 
81 92
     $(@el).find('.action .multichat, .action .invite, .action .kick').hide()
82 93
 
83
-    if (@model.get('usingMyApp') == true)
94
+    if (@model.get('usingMyApp'))
84 95
       if not activeChat or not activeChat.get('isMultiChat')
85 96
         $(@el).find('.action .multichat').show()
86 97
       else if activeChat.get('isMultiChat') and activeChat.isMeOwner() and not activeChat.isAttending(@model)
... ...
@@ -6,13 +6,21 @@ class Xmpp.Views.Tabbar.TabView extends Backbone.View
6 6
   className: 'tab'
7 7
 
8 8
   events:
9
-    'click .js-close': 'closeChat'
9
+    'click .js-close': 'fireCloseChatTrigger'
10 10
     'click a div': 'switchChatWindow'
11 11
 
12 12
   initialize: () ->
13 13
     _.bindAll(this)
14 14
     @active = false
15 15
 
16
+    Backbone.Events.on('closeChat', (chat) =>
17
+      if chat == @model
18
+        @destroy()
19
+    )
20
+
21
+  fireCloseChatTrigger: ->
22
+    Backbone.Events.trigger('closeChat', @model)
23
+
16 24
   setActive: ->
17 25
     $(@el).addClass('active')
18 26
     @active = true
... ...
@@ -56,10 +64,6 @@ class Xmpp.Views.Tabbar.TabView extends Backbone.View
56 56
     if @chatWindow
57 57
       @chatWindow.hide();
58 58
 
59
-  closeChat: ->
60
-    @destroy()
61
-    Backbone.Events.trigger('closeChat', this, @model)
62
-
63 59
   hasParticipants: (who, withWhom) ->
64 60
     @model && @model.get('who') == who && @model.get('withWhom') == withWhom
65 61
 
... ...
@@ -11,15 +11,13 @@ class Xmpp.Views.Tabbar.TabbarView extends Backbone.View
11 11
       @hideCurrentChatWindow()
12 12
       @addOrSelect(chat)
13 13
     )
14
-    Backbone.Events.on('closeChat', (tab, chatModel) =>
15
-      @removeTab(tab)
16
-
17
-      if tab == @activeTab
18
-        firstTab = @selectFirstTab()
19
-        if firstTab
20
-          App.debug 'fire openChat'
21
-          Backbone.Events.trigger('openChat', firstTab.model)
22
-        #TODO: vybrat naposledy pouzity tab
14
+
15
+    Backbone.Events.on('closeChat', (chat) =>
16
+      tab = _.find(@tabs, (_tab) =>
17
+        _tab.model == chat
18
+      )
19
+
20
+      @closeTab(tab) if tab
23 21
     )
24 22
 
25 23
     @tabs = []
... ...
@@ -52,6 +50,16 @@ class Xmpp.Views.Tabbar.TabbarView extends Backbone.View
52 52
       App.debug 'zakryvam chat window'
53 53
       @activeTab.hideChat()
54 54
 
55
+  closeTab: (tab) ->
56
+    @removeTab(tab)
57
+
58
+    if tab == @activeTab
59
+      firstTab = @selectFirstTab()
60
+      if firstTab
61
+        App.debug 'fire openChat'
62
+        Backbone.Events.trigger('openChat', firstTab.model)
63
+    #TODO: vybrat naposledy pouzity tab
64
+
55 65
   removeTab: (tab) ->
56 66
     @tabs = _.without(@tabs, tab)
57 67
 
... ...
@@ -15,6 +15,10 @@ class WsChatController < WsController
15 15
                     sync_contacts_frontend(message, answer.attribute('chat_id').to_s)
16 16
                 elsif answer = message.first_element('exported_chat')
17 17
                     import_people_in_chat(message, answer.attribute('chat_id').to_s)
18
+                elsif message.attribute('destroy_multichat')
19
+                    destroy_multichat(message, message.attribute('chat_id').to_s)
20
+                elsif message.attribute('req_update_contacts')
21
+                    update_attendants_in_multichat(message, message.attribute('chat_id').to_s)
18 22
                 end
19 23
                 #TODO: upozornit na pisanie spravy
20 24
                 #TODO: odoslat informaciu o tom, ze pisem spravu
... ...
@@ -115,6 +119,46 @@ class WsChatController < WsController
115 115
         client.send(MessageBuilder::ask_for_multichat_contacts(client.jid.strip.to_s, owner, chat_id))
116 116
     end
117 117
 
118
+    def i_closed_multichat
119
+        chat_id = message[:chatId]
120
+        client  = find_client(message[:me])
121
+        me      = client.jid.strip.to_s
122
+        owner   = connection_store[:opened_chats][client][chat_id][:owner]
123
+
124
+        if owner == me
125
+            attendants = connection_store[:opened_chats][client][chat_id][:attendants]
126
+            attendants.each do |attendant|
127
+                client.send(MessageBuilder::destroy_multichat(me, attendant, chat_id))
128
+            end
129
+        else
130
+            changes = {removed: [me]}
131
+            client.send(MessageBuilder::req_update_multichat_contacts(me, owner, chat_id, changes))
132
+        end
133
+    end
134
+
135
+    def kick_from_multichat
136
+        chat_id = message[:chatId]
137
+        client  = find_client(message[:me])
138
+        me      = client.jid.strip.to_s
139
+        kick    = message[:kick]
140
+
141
+        contacts = connection_store[:opened_chats][client][chat_id][:attendants]
142
+        contacts -= [kick]
143
+
144
+        connection_store[:opened_chats][client][chat_id][:attendants] = contacts
145
+
146
+        client.send(MessageBuilder::destroy_multichat(me, kick, chat_id))
147
+
148
+        if contacts.empty?
149
+            connection_store[:opened_chats][client].delete(chat_id)
150
+            send_message 'app.chat.destroyMultichat', chat_id: chat_id
151
+        else
152
+            contacts.each do |contact|
153
+                client.send(MessageBuilder::send_multichat_contacts(client.jid.strip.to_s, contact, chat_id, contacts))
154
+            end
155
+        end
156
+    end
157
+
118 158
     private
119 159
 
120 160
     def process_incoming_message(message)
... ...
@@ -147,4 +191,31 @@ class WsChatController < WsController
147 147
             contact.text
148 148
         end
149 149
     end
150
+
151
+    def destroy_multichat(message, chat_id)
152
+        client = find_client(message.to.strip.to_s)
153
+        connection_store[:opened_chats][client].delete(chat_id)
154
+
155
+        send_message 'app.chat.destroyMultichat', chat_id: chat_id
156
+    end
157
+
158
+    def update_attendants_in_multichat(message, chat_id)
159
+        client = find_client(message.to.strip.to_s)
160
+        added = message.first_element('added')
161
+        removed = message.first_element('removed')
162
+
163
+        contacts = connection_store[:opened_chats][client][chat_id][:attendants]
164
+        contacts -= xml_contacts_to_array(removed)
165
+        contacts += xml_contacts_to_array(added)
166
+
167
+        connection_store[:opened_chats][client][chat_id][:attendants] = contacts
168
+
169
+        if contacts.empty?
170
+            destroy_multichat(message, chat_id)
171
+        else
172
+            contacts.each do |contact|
173
+                client.send(MessageBuilder::send_multichat_contacts(client.jid.strip.to_s, contact, chat_id, contacts))
174
+            end
175
+        end
176
+    end
150 177
 end
151 178
\ No newline at end of file
... ...
@@ -64,13 +64,42 @@ module MessageBuilder
64 64
         message
65 65
     end
66 66
 
67
+    def self.req_update_multichat_contacts(from, to, chat_id, changes)
68
+        message = Jabber::Message.new(to)
69
+        message.from = from
70
+        message.add_attributes('req_update_contacts' => 'true')
71
+        message.add_attributes('chat_id' => chat_id)
72
+
73
+        added   = REXML::Element.new('added')
74
+        removed = REXML::Element.new('removed')
75
+
76
+        collect_contacts(added, changes[:added])
77
+        collect_contacts(removed, changes[:removed])
78
+
79
+        message.add_element added
80
+        message.add_element removed
81
+
82
+        message
83
+    end
84
+
85
+    def self.destroy_multichat(from, to, chat_id)
86
+        message = Jabber::Message.new(to)
87
+        message.from = from
88
+        message.add_attributes('destroy_multichat' => 'true')
89
+        message.add_attributes('chat_id' => chat_id)
90
+
91
+        message
92
+    end
93
+
67 94
     private
68 95
 
69 96
     def self.collect_contacts(to_element, contacts)
70
-        contacts.each do |contact|
71
-            contact_xml = REXML::Element.new('contact')
72
-            contact_xml.text = contact
73
-            to_element.add_element contact_xml
97
+        if contacts.kind_of?(Array)
98
+            contacts.each do |contact|
99
+                contact_xml = REXML::Element.new('contact')
100
+                contact_xml.text = contact
101
+                to_element.add_element contact_xml
102
+            end
74 103
         end
75 104
     end
76 105
 end
77 106
\ No newline at end of file
... ...
@@ -66,6 +66,8 @@ WebsocketRails::EventMap.describe do
66 66
             subscribe :sendMessage,           to: WsChatController, with_method: :send_chat_message
67 67
             subscribe :startPollingMessages,  to: WsChatController, with_method: :start_polling_messages
68 68
             subscribe :syncMultiChatContacts, to: WsChatController, with_method: :sync_chat_contacts
69
+            subscribe :iClosedMultichat,      to: WsChatController, with_method: :i_closed_multichat
70
+            subscribe :kickFromMultichat,     to: WsChatController, with_method: :kick_from_multichat
69 71
         end
70 72
     end
71 73
 end