package org.mercury_im.messenger.core.connection.message; import org.jivesoftware.smack.chat2.ChatManager; import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smackx.muc.MultiUserChat; import org.jivesoftware.smackx.muc.MultiUserChatManager; import org.jivesoftware.smackx.sid.element.OriginIdElement; import org.jxmpp.jid.parts.Resourcepart; import org.mercury_im.messenger.core.connection.MercuryConnection; import org.mercury_im.messenger.core.connection.MercuryConnectionManager; import org.mercury_im.messenger.core.data.repository.MessageRepository; import org.mercury_im.messenger.core.util.AppendCompletableToSingle; import org.mercury_im.messenger.entity.chat.Chat; import org.mercury_im.messenger.entity.chat.DirectChat; import org.mercury_im.messenger.entity.chat.GroupChat; import org.mercury_im.messenger.entity.message.Message; import org.mercury_im.messenger.entity.message.MessageDeliveryState; import java.util.UUID; import io.reactivex.Completable; import io.reactivex.Single; public class PlaintextMessageConsignor extends AbstractMessageConsignor { public PlaintextMessageConsignor(MercuryConnectionManager connectionManager, MessageRepository messageRepository, Chat chat) { this(new MessageComposer(), connectionManager, messageRepository, chat); } public PlaintextMessageConsignor(MessageComposer composer, MercuryConnectionManager connectionManager, MessageRepository messageRepository, Chat chat) { super(composer, connectionManager, messageRepository, chat); } @Override public Single sendTextMessage(Chat chat, String body) { Message message = messageComposer.createChatMessage(chat, body); MessageBuilder messageBuilder = commonMessageBuilder(message); Completable deliverMessage; if (chat instanceof DirectChat) { deliverMessage = sendDirectChatMessage((DirectChat) chat, messageBuilder); } else if (chat instanceof GroupChat) { deliverMessage = sendGroupChatMessage((GroupChat) chat, messageBuilder); } else { throw new AssertionError("Unknown chat type."); } Single deliverAndStore = messageRepository.insertMessage(message) .map(Message::getId) .compose(new AppendCompletableToSingle<>(deliverMessage)) .flatMap(messageId -> messageRepository.updateDeliveryState(messageId, MessageDeliveryState.delivered_to_server) .toSingle(() -> messageId)); return deliverAndStore; } private MessageBuilder commonMessageBuilder(Message message) { return MessageBuilder.buildMessage(message.getLegacyStanzaId()) .ofType(org.jivesoftware.smack.packet.Message.Type.chat) .addExtension(new OriginIdElement(message.getOriginId())) .to(chat.getJid()) .from(chat.getAccount().getJid()) .setBody(message.getBody()); } private Completable sendDirectChatMessage(DirectChat chat, MessageBuilder messageBuilder) { return Completable.fromAction(() -> { MercuryConnection connection = connectionManager.getConnection(chat.getAccount()); ChatManager chatManager = ChatManager.getInstanceFor(connection.getConnection()); org.jivesoftware.smack.chat2.Chat smackChat = chatManager.chatWith(chat.getJid().asEntityBareJid()); smackChat.send(messageBuilder.build()); }); } private Completable sendGroupChatMessage(GroupChat chat, MessageBuilder messageBuilder) { return Completable.fromAction(() -> { MercuryConnection connection = connectionManager.getConnection(chat.getAccount()); MultiUserChatManager multiUserChatManager = MultiUserChatManager.getInstanceFor(connection.getConnection()); MultiUserChat muc = multiUserChatManager.getMultiUserChat(chat.getJid().asEntityBareJid()); if (!muc.isJoined()) { muc.join(Resourcepart.from(chat.getNickname())); } muc.sendMessage(messageBuilder); }); } }