class WsChatController < WsController def start_polling_messages connection_store[:clients].each do |client| client.add_message_callback do |message| #noinspection RubyAssignmentExpressionInConditionalInspection if message.body process_incoming_message(message) elsif request = message.first_element('sync_contacts_request') # toto mozem prijat len ako admin multichatu send_contacts(message, request.attribute('chat_id').to_s) elsif answer = message.first_element('synced_contacts') # toto mozem prijat len ako ucastnik multichatu (nie admin) sync_contacts_frontend(message, answer.attribute('chat_id').to_s) elsif answer = message.first_element('exported_chat') import_people_in_chat(message, answer.attribute('chat_id').to_s) elsif message.attribute('destroy_multichat') destroy_multichat(message, message.attribute('chat_id').to_s) elsif message.attribute('req_update_contacts') update_attendants_in_multichat(message, message.attribute('chat_id').to_s) end #TODO: upozornit na pisanie spravy #TODO: odoslat informaciu o tom, ze pisem spravu #else # send_message 'app.chat.messageState', # state: message.chat_state, # from: message.from.strip.to_s, # to: message.to.strip.to_s, # message: message.body, # chat_id: if message.attribute(:is_simulating) then message.attribute(:chat_id) end end end end def import_people_in_chat(message, chat_id) #Rails.logger.debug ['imported chat arrived', message.to_s, chat_id] client = find_client(message.to.strip.to_s) contacts = xml_contacts_to_array(message.first_element('exported_chat')) connection_store[:opened_chats] = {} if ! connection_store[:opened_chats] connection_store[:opened_chats][client] = {} if ! connection_store[:opened_chats][client] connection_store[:opened_chats][client][chat_id] = {attendants: contacts, owner: message.from.strip.to_s} #Rails.logger.debug [connection_store[:opened_chats][client], client.jid.to_s] send_message 'app.chat.importChat', owner: message.from.strip.to_s, chat_id: chat_id, contacts: contacts end # Owner vytvori najprv u seba novy multichat def new_multichat me = message[:chatOwner] hash = Digest::SHA2.hexdigest(me) id = hash + Time.now.to_f.to_s client = find_client(me) connection_store[:opened_chats] = {} if ! connection_store[:opened_chats] connection_store[:opened_chats][client] = {} if ! connection_store[:opened_chats][client] connection_store[:opened_chats][client][id] = {attendants: [], owner: me} trigger_success id: id end # Owner posle novemu cloveku informaciu o chat_id a kontaktoch def add_to_multichat client = find_client(message[:chatOwner]) chat_id = message[:chatId] add = message[:jid] connection_store[:opened_chats][client][chat_id][:attendants] << add contacts = connection_store[:opened_chats][client][chat_id][:attendants] contacts.each do |contact| client.send(MessageBuilder::export_multichat(client.jid.strip.to_s, contact, chat_id, contacts)) end trigger_success end def send_chat_message me = message[:from] client = find_client(me) if client chat_id = message[:chatId] if chat_id attendants = connection_store[:opened_chats][client][chat_id][:attendants] + [connection_store[:opened_chats][client][chat_id][:owner]] attendants -= [client.jid.strip.to_s] messages = MessageBuilder::build_multi_messages(message[:message], client.jid.strip.to_s, attendants, chat_id) #Rails.logger.debug messages else messages = [MessageBuilder::build_message(message[:message], client.jid.strip.to_s, message[:to])] end # Xmpp4r doesn't support XEP-0033 (multicast messages) messages.each do |message| client.send(message) end trigger_success message[:message] else trigger_failure end end def sync_chat_contacts client = find_client(message[:me]) chat_id = message[:chatId] owner = connection_store[:opened_chats][client][chat_id][:owner] client.send(MessageBuilder::ask_for_multichat_contacts(client.jid.strip.to_s, owner, chat_id)) end def i_closed_multichat chat_id = message[:chatId] client = find_client(message[:me]) me = client.jid.strip.to_s owner = connection_store[:opened_chats][client][chat_id][:owner] if owner == me attendants = connection_store[:opened_chats][client][chat_id][:attendants] attendants.each do |attendant| client.send(MessageBuilder::destroy_multichat(me, attendant, chat_id)) end else changes = {removed: [me]} client.send(MessageBuilder::req_update_multichat_contacts(me, owner, chat_id, changes)) end end def kick_from_multichat chat_id = message[:chatId] client = find_client(message[:me]) me = client.jid.strip.to_s kick = message[:kick] contacts = connection_store[:opened_chats][client][chat_id][:attendants] contacts -= [kick] connection_store[:opened_chats][client][chat_id][:attendants] = contacts client.send(MessageBuilder::destroy_multichat(me, kick, chat_id)) if contacts.empty? connection_store[:opened_chats][client].delete(chat_id) send_message 'app.chat.destroyMultichat', chat_id: chat_id else contacts.each do |contact| client.send(MessageBuilder::send_multichat_contacts(client.jid.strip.to_s, contact, chat_id, contacts)) end end end private def process_incoming_message(message) #Rails.logger.debug [message, message.to.strip.to_s] send_message 'app.chat.messageReceived', from: message.from.strip.to_s, to: message.to.strip.to_s, message: message.body, chat_id: message.attribute('chat_id').to_s end def send_contacts(message, chat_id) from = message.from.strip.to_s client = find_client(message.to.strip.to_s) contacts = connection_store[:opened_chats][client][chat_id][:attendants] client.send(MessageBuilder::send_multichat_contacts(client.jid.strip.to_s, from, chat_id, contacts)) end def sync_contacts_frontend(message, chat_id) contacts = xml_contacts_to_array(message.first_element('sync_contacts')) send_message 'app.chat.updateSyncedContacts', me: message.to.strip.to_s, contacts: contacts, chat_id: chat_id end def xml_contacts_to_array(xml_contacts) xml_contacts.get_elements('contact').map do |contact| contact.text end end def destroy_multichat(message, chat_id) client = find_client(message.to.strip.to_s) connection_store[:opened_chats][client].delete(chat_id) send_message 'app.chat.destroyMultichat', chat_id: chat_id end def update_attendants_in_multichat(message, chat_id) client = find_client(message.to.strip.to_s) added = message.first_element('added') removed = message.first_element('removed') contacts = connection_store[:opened_chats][client][chat_id][:attendants] contacts -= xml_contacts_to_array(removed) contacts += xml_contacts_to_array(added) connection_store[:opened_chats][client][chat_id][:attendants] = contacts if contacts.empty? destroy_multichat(message, chat_id) else contacts.each do |contact| client.send(MessageBuilder::send_multichat_contacts(client.jid.strip.to_s, contact, chat_id, contacts)) end end end end