diff --git a/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java b/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java index 6f2fa69..187d330 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java +++ b/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java @@ -8,6 +8,7 @@ import org.mercury_im.messenger.android.ui.roster.contacts.AndroidContactListVie import org.mercury_im.messenger.core.di.module.OpenPgpModule; import org.mercury_im.messenger.core.di.module.RxMercuryMessageStoreFactoryModule; import org.mercury_im.messenger.core.di.module.RxMercuryRosterStoreFactoryModule; +import org.mercury_im.messenger.core.di.module.StanzaIdSourceFactoryModule; import org.mercury_im.messenger.core.di.module.XmppTcpConnectionFactoryModule; import org.mercury_im.messenger.core.viewmodel.account.detail.AccountDetailsViewModel; import org.mercury_im.messenger.core.viewmodel.account.list.AccountListViewModel; @@ -48,7 +49,8 @@ import dagger.Component; XmppTcpConnectionFactoryModule.class, RxMercuryMessageStoreFactoryModule.class, OpenPgpModule.class, - RxMercuryRosterStoreFactoryModule.class + RxMercuryRosterStoreFactoryModule.class, + StanzaIdSourceFactoryModule.class }) public interface AppComponent { diff --git a/data/src/main/java/org/mercury_im/messenger/data/converter/EntityJidConverter.java b/data/src/main/java/org/mercury_im/messenger/data/converter/EntityJidConverter.java index 8be0041..3c6077a 100644 --- a/data/src/main/java/org/mercury_im/messenger/data/converter/EntityJidConverter.java +++ b/data/src/main/java/org/mercury_im/messenger/data/converter/EntityJidConverter.java @@ -1,6 +1,5 @@ package org.mercury_im.messenger.data.converter; -import org.jxmpp.jid.EntityFullJid; import org.jxmpp.jid.EntityJid; import org.jxmpp.jid.impl.JidCreate; @@ -27,18 +26,15 @@ public class EntityJidConverter implements Converter { @Override public String convertToPersisted(EntityJid value) { + if (value == null) return null; return value.toString(); } @Override public EntityJid convertToMapped(Class type, @Nullable String value) { - switch (type.getName()) { - case "EntityFullJid": - return JidCreate.entityFullFromOrThrowUnchecked(value); - case "EntityBareJid": - return JidCreate.entityBareFromOrThrowUnchecked(value); - default: - throw new IllegalArgumentException("Unknown jid type encountered: " + type.getName()); + if (value == null) { + return null; } + return JidCreate.entityFromOrThrowUnchecked(value); } } diff --git a/data/src/main/java/org/mercury_im/messenger/data/mapping/ChatMarkerMapping.java b/data/src/main/java/org/mercury_im/messenger/data/mapping/ChatMarkerMapping.java new file mode 100644 index 0000000..9a17a88 --- /dev/null +++ b/data/src/main/java/org/mercury_im/messenger/data/mapping/ChatMarkerMapping.java @@ -0,0 +1,37 @@ +package org.mercury_im.messenger.data.mapping; + +import org.jivesoftware.smackx.chat_markers.ChatMarkersState; +import org.mercury_im.messenger.entity.message.ChatMarkerState; + +public class ChatMarkerMapping { + + public static ChatMarkersState toSmackChatMarker(ChatMarkerState mercuryChatMarker) { + switch (mercuryChatMarker) { + case markable: + return ChatMarkersState.markable; + case received: + return ChatMarkersState.received; + case displayed: + return ChatMarkersState.displayed; + case acknowledged: + return ChatMarkersState.acknowledged; + default: + throw new IllegalArgumentException("Illegal ChatMarkersState: " + mercuryChatMarker); + } + } + + public static ChatMarkerState toMercuryChatMarker(ChatMarkersState smackChatMarker) { + switch (smackChatMarker) { + case markable: + return ChatMarkerState.markable; + case received: + return ChatMarkerState.received; + case displayed: + return ChatMarkerState.displayed; + case acknowledged: + return ChatMarkerState.acknowledged; + default: + throw new IllegalArgumentException("Illegal ChatMarkersState: " + smackChatMarker); + } + } +} diff --git a/data/src/main/java/org/mercury_im/messenger/data/mapping/MessageMapping.java b/data/src/main/java/org/mercury_im/messenger/data/mapping/MessageMapping.java index 2f100cd..1743197 100644 --- a/data/src/main/java/org/mercury_im/messenger/data/mapping/MessageMapping.java +++ b/data/src/main/java/org/mercury_im/messenger/data/mapping/MessageMapping.java @@ -26,6 +26,7 @@ public class MessageMapping extends AbstractMapping { @Override public MessageModel mapToModel(Message entity, MessageModel model) { model.setId(entity.getId()); + model.setChatId(entity.getChatId()); model.setSender(entity.getSender()); model.setRecipient(entity.getRecipient()); model.setTimestamp(entity.getTimestamp()); @@ -42,6 +43,7 @@ public class MessageMapping extends AbstractMapping { @Override public Message mapToEntity(MessageModel model, Message entity) { entity.setId(model.getId()); + entity.setChatId(model.getChatId()); entity.setSender(model.getSender()); entity.setRecipient(model.getRecipient()); entity.setTimestamp(model.getTimestamp()); diff --git a/data/src/main/java/org/mercury_im/messenger/data/model/AbstractMessageModel.java b/data/src/main/java/org/mercury_im/messenger/data/model/AbstractMessageModel.java index 66ed60a..687f809 100644 --- a/data/src/main/java/org/mercury_im/messenger/data/model/AbstractMessageModel.java +++ b/data/src/main/java/org/mercury_im/messenger/data/model/AbstractMessageModel.java @@ -1,9 +1,11 @@ package org.mercury_im.messenger.data.model; -import org.jxmpp.jid.EntityFullJid; -import org.mercury_im.messenger.data.converter.EntityFullJidConverter; +import org.jxmpp.jid.EntityJid; +import org.mercury_im.messenger.data.converter.EntityJidConverter; import org.mercury_im.messenger.data.converter.MessageDirectionConverter; import org.mercury_im.messenger.entity.Encryption; +import org.mercury_im.messenger.entity.message.ChatMarkerState; +import org.mercury_im.messenger.entity.message.MessageDeliveryState; import org.mercury_im.messenger.entity.message.MessageDirection; import org.pgpainless.key.OpenPgpV4Fingerprint; @@ -27,15 +29,16 @@ public abstract class AbstractMessageModel implements Persistable { UUID id; @Column(nullable = false) + @Convert(UUIDConverter.class) UUID chatId; @Column(nullable = false) - @Convert(EntityFullJidConverter.class) - EntityFullJid sender; + @Convert(EntityJidConverter.class) + EntityJid sender; @Column(nullable = false) - @Convert(EntityFullJidConverter.class) - EntityFullJid recipient; + @Convert(EntityJidConverter.class) + EntityJid recipient; @Column(name = "\"timestamp\"", nullable = false) Date timestamp; @@ -68,4 +71,10 @@ public abstract class AbstractMessageModel implements Persistable { @Column OpenPgpV4Fingerprint senderOXFingerprint; + @Column + ChatMarkerState chatMarkerState; + + @Column + MessageDeliveryState deliveryState; + } diff --git a/data/src/main/java/org/mercury_im/messenger/data/repository/RxMessageRepository.java b/data/src/main/java/org/mercury_im/messenger/data/repository/RxMessageRepository.java index 0f0d8f9..5d13646 100644 --- a/data/src/main/java/org/mercury_im/messenger/data/repository/RxMessageRepository.java +++ b/data/src/main/java/org/mercury_im/messenger/data/repository/RxMessageRepository.java @@ -1,5 +1,6 @@ package org.mercury_im.messenger.data.repository; +import org.jxmpp.jid.EntityBareJid; import org.mercury_im.messenger.core.data.repository.MessageRepository; import org.mercury_im.messenger.data.mapping.DirectChatMapping; import org.mercury_im.messenger.data.mapping.GroupChatMapping; @@ -10,7 +11,9 @@ import org.mercury_im.messenger.data.repository.dao.GroupChatDao; import org.mercury_im.messenger.data.repository.dao.MessageDao; import org.mercury_im.messenger.entity.chat.DirectChat; import org.mercury_im.messenger.entity.chat.GroupChat; +import org.mercury_im.messenger.entity.message.ChatMarkerState; import org.mercury_im.messenger.entity.message.Message; +import org.mercury_im.messenger.entity.message.MessageDeliveryState; import java.util.ArrayList; import java.util.List; @@ -105,7 +108,7 @@ public class RxMessageRepository .from(MessageModel.class) .where(MessageModel.BODY.like("%" + body + "%") - .and(MessageModel.CHAT_ID.eq(chat.getId()))) + .and(MessageModel.CHAT_ID.eq(chat.getId()))) .get().observableResult() .map(ResultDelegate::toList) .map(this::messageModelsToEntities); @@ -117,7 +120,7 @@ public class RxMessageRepository .from(MessageModel.class) .where(MessageModel.BODY.like("%" + body + "%") - .and(MessageModel.CHAT_ID.eq(chat.getId()))) + .and(MessageModel.CHAT_ID.eq(chat.getId()))) .get().observableResult() .map(ResultDelegate::toList) .map(this::messageModelsToEntities); @@ -146,6 +149,24 @@ public class RxMessageRepository .get().single().ignoreElement(); } + @Override + public Completable markMessage(String stanzaId, EntityBareJid recipientJid, ChatMarkerState state) { + return data().update(MessageModel.class) + .set(MessageModel.CHAT_MARKER_STATE, state) + .where(MessageModel.LEGACY_ID.eq(stanzaId) + .and(MessageModel.RECIPIENT.eq(recipientJid))) + .get().single().ignoreElement(); + } + + @Override + public Completable updateDeliveryState(UUID messageId, MessageDeliveryState deliveryState) { + return data().update(MessageModel.class) + .set(MessageModel.DELIVERY_STATE, deliveryState) + .where(MessageModel.ID.eq(messageId)) + .get().single() + .ignoreElement(); + } + private List messageModelsToEntities(List models) { List entities = new ArrayList<>(models.size()); for (MessageModel model : models) { diff --git a/domain/build.gradle b/domain/build.gradle index b5f2665..52fd626 100644 --- a/domain/build.gradle +++ b/domain/build.gradle @@ -1,5 +1,10 @@ apply plugin: 'java-library' +sourceSets { + //main.java.srcDirs += "${buildDir}/generated/sources/annotationProcessor/java/main/" + test.java.srcDirs += "${buildDir}/generated/sources/annotationProcessor/java/test/" +} + dependencies { implementation project(':entity') @@ -20,7 +25,9 @@ dependencies { // Dagger 2 for dependency injection implementation "com.google.dagger:dagger:$daggerVersion" + testImplementation "com.google.dagger:dagger:$daggerVersion" annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion" + testAnnotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion" compileOnly "org.projectlombok:lombok:$lombokVersion" annotationProcessor "org.projectlombok:lombok:$lombokVersion" diff --git a/domain/src/main/java/org/mercury_im/messenger/core/Messenger.java b/domain/src/main/java/org/mercury_im/messenger/core/Messenger.java index f19b3bd..741e433 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/Messenger.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/Messenger.java @@ -13,8 +13,13 @@ import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.stringprep.XmppStringprepException; import org.mercury_im.messenger.core.connection.MercuryConnection; import org.mercury_im.messenger.core.connection.MercuryConnectionManager; +import org.mercury_im.messenger.core.connection.message.MessageConsignor; +import org.mercury_im.messenger.core.connection.message.OxMessageConsignor; +import org.mercury_im.messenger.core.connection.message.PlaintextMessageConsignor; +import org.mercury_im.messenger.core.data.repository.MessageRepository; import org.mercury_im.messenger.core.exception.ConnectionNotFoundException; import org.mercury_im.messenger.core.exception.ContactAlreadyAddedException; +import org.mercury_im.messenger.entity.chat.Chat; import org.mercury_im.messenger.entity.contact.Peer; import java.io.IOException; @@ -34,12 +39,15 @@ public class Messenger { private static final Logger LOGGER = Logger.getLogger(Messenger.class.getName()); private final MercuryConnectionManager connectionManager; + private final MessageRepository messageRepository; private final SchedulersFacade schedulers; @Inject public Messenger(MercuryConnectionManager connectionManager, + MessageRepository messageRepository, SchedulersFacade schedulers) { this.connectionManager = connectionManager; + this.messageRepository = messageRepository; this.schedulers = schedulers; } @@ -127,4 +135,16 @@ public class Messenger { } return connection; } + + public MessageConsignor getMessageConsignor(Chat chat) { + switch (chat.getChatPreferences().getEncryption()) { + case plain: + return new PlaintextMessageConsignor(connectionManager, messageRepository, chat); + case ox_sign: + case ox_crypt: + case ox_signcrypt: + return new OxMessageConsignor(connectionManager, messageRepository, chat); + } + throw new AssertionError("Illegal Encryption Type: " + chat.getChatPreferences().getEncryption()); + } } diff --git a/domain/src/main/java/org/mercury_im/messenger/core/connection/MercuryConnectionManager.java b/domain/src/main/java/org/mercury_im/messenger/core/connection/MercuryConnectionManager.java index 9043a55..3a6cd3f 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/connection/MercuryConnectionManager.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/connection/MercuryConnectionManager.java @@ -159,7 +159,6 @@ public class MercuryConnectionManager { MercuryMessageStore mercuryMessageStore = messageStoreFactory.createMessageStore(account); ChatManager chatManager = ChatManager.getInstanceFor(connection.getConnection()); chatManager.addIncomingListener(mercuryMessageStore); - chatManager.addOutgoingListener(mercuryMessageStore); })); cryptoManager.initialize(connection); } diff --git a/domain/src/main/java/org/mercury_im/messenger/core/connection/MessageCenter.kt b/domain/src/main/java/org/mercury_im/messenger/core/connection/MessageCenter.kt deleted file mode 100644 index 6df4c0a..0000000 --- a/domain/src/main/java/org/mercury_im/messenger/core/connection/MessageCenter.kt +++ /dev/null @@ -1,42 +0,0 @@ -package org.mercury_im.messenger.core.connection - - -import org.mercury_im.messenger.entity.message.Message as MercuryMessage; -import org.jivesoftware.smack.packet.Message as SmackMessage; - -import java.util.UUID - -import io.reactivex.Completable -import io.reactivex.Single -import org.mercury_im.messenger.core.util.AppendCompletableToSingle -import org.mercury_im.messenger.entity.chat.Chat - -class MessageCenter(private val composer: Composer, - private val persister: Persister, - private val encryptor: Encryptor, - private val sender: Sender) { - - fun sendSingleTextMessage(chat: Chat, body: String): Single { - val messageEntity = composer.createChatMessage(chat, body) - val messageId = persister.persistPendingMessage(messageEntity) - val smackMessage = encryptor.encrypt(messageEntity) - val sendCompletable = sender.send(smackMessage); - return messageId.compose(AppendCompletableToSingle(sendCompletable)); - } - - interface Composer { - fun createChatMessage(chat: Chat, body: String): MercuryMessage - } - - interface Persister { - fun persistPendingMessage(message: MercuryMessage): Single - } - - interface Encryptor { - fun encrypt(message: MercuryMessage): SmackMessage - } - - interface Sender { - fun send(message: SmackMessage): Completable - } -} diff --git a/domain/src/main/java/org/mercury_im/messenger/core/connection/MessagePersister.java b/domain/src/main/java/org/mercury_im/messenger/core/connection/MessagePersister.java deleted file mode 100644 index 7557397..0000000 --- a/domain/src/main/java/org/mercury_im/messenger/core/connection/MessagePersister.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.mercury_im.messenger.core.connection; - -import org.mercury_im.messenger.core.data.repository.MessageRepository; -import org.mercury_im.messenger.entity.message.Message; - -import java.util.UUID; - -import io.reactivex.Single; - -public class MessagePersister implements MessageCenter.Persister { - - private final MessageRepository messageRepository; - - public MessagePersister(MessageRepository messageRepository) { - this.messageRepository = messageRepository; - } - - @Override - public Single persistPendingMessage(Message message) { - return null; - } -} diff --git a/domain/src/main/java/org/mercury_im/messenger/core/connection/SmackConfig.java b/domain/src/main/java/org/mercury_im/messenger/core/connection/SmackConfig.java index b1adfc4..f5db4ca 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/connection/SmackConfig.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/connection/SmackConfig.java @@ -1,6 +1,7 @@ package org.mercury_im.messenger.core.connection; import org.jivesoftware.smack.ReconnectionManager; +import org.jivesoftware.smack.SmackConfiguration; import org.jivesoftware.smack.roster.Roster; import org.jivesoftware.smackx.carbons.CarbonManager; import org.jivesoftware.smackx.iqversion.VersionManager; @@ -10,7 +11,7 @@ import org.jivesoftware.smackx.sid.StableUniqueStanzaIdManager; public class SmackConfig { static void staticConfiguration() { - //SmackConfiguration.DEBUG = true; + SmackConfiguration.DEBUG = true; ReconnectionManager.setEnabledPerDefault(true); ReconnectionManager.setDefaultReconnectionPolicy(ReconnectionManager.ReconnectionPolicy.RANDOM_INCREASING_DELAY); diff --git a/domain/src/main/java/org/mercury_im/messenger/core/connection/XmppTcpConnectionFactory.java b/domain/src/main/java/org/mercury_im/messenger/core/connection/XmppTcpConnectionFactory.java index 225dac5..d764333 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/connection/XmppTcpConnectionFactory.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/connection/XmppTcpConnectionFactory.java @@ -1,19 +1,31 @@ package org.mercury_im.messenger.core.connection; import org.jivesoftware.smack.AbstractXMPPConnection; +import org.jivesoftware.smack.packet.id.StanzaIdSource; +import org.jivesoftware.smack.packet.id.StanzaIdSourceFactory; import org.jivesoftware.smack.tcp.XMPPTCPConnection; import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration; import org.jxmpp.stringprep.XmppStringprepException; import org.mercury_im.messenger.entity.Account; +import javax.inject.Inject; + public class XmppTcpConnectionFactory implements XmppConnectionFactory { private static final int CONNECTION_TIMEOUT = 30 * 1000; + private final StanzaIdSourceFactory stanzaIdSourceFactory; + + @Inject + public XmppTcpConnectionFactory(StanzaIdSourceFactory stanzaIdSourceFactory) { + this.stanzaIdSourceFactory = stanzaIdSourceFactory; + } + public AbstractXMPPConnection createConnection(Account account) { try { XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder() + .setStanzaIdSourceFactory(stanzaIdSourceFactory) .setConnectTimeout(CONNECTION_TIMEOUT) .setXmppAddressAndPassword(account.getAddress(), account.getPassword()); if (account.getHost() != null) { diff --git a/domain/src/main/java/org/mercury_im/messenger/core/connection/message/AbstractMessageConsignor.java b/domain/src/main/java/org/mercury_im/messenger/core/connection/message/AbstractMessageConsignor.java new file mode 100644 index 0000000..4203d47 --- /dev/null +++ b/domain/src/main/java/org/mercury_im/messenger/core/connection/message/AbstractMessageConsignor.java @@ -0,0 +1,24 @@ +package org.mercury_im.messenger.core.connection.message; + +import org.mercury_im.messenger.core.connection.MercuryConnectionManager; +import org.mercury_im.messenger.core.data.repository.MessageRepository; +import org.mercury_im.messenger.entity.chat.Chat; + +public abstract class AbstractMessageConsignor implements MessageConsignor { + + protected final MessageComposer messageComposer; + + protected final MercuryConnectionManager connectionManager; + protected final MessageRepository messageRepository; + protected final Chat chat; + + public AbstractMessageConsignor(MessageComposer composer, + MercuryConnectionManager connectionManager, + MessageRepository messageRepository, + Chat chat) { + this.messageComposer = composer; + this.connectionManager = connectionManager; + this.messageRepository = messageRepository; + this.chat = chat; + } +} diff --git a/domain/src/main/java/org/mercury_im/messenger/core/connection/MercuryMessageComposer.java b/domain/src/main/java/org/mercury_im/messenger/core/connection/message/MessageComposer.java similarity index 66% rename from domain/src/main/java/org/mercury_im/messenger/core/connection/MercuryMessageComposer.java rename to domain/src/main/java/org/mercury_im/messenger/core/connection/message/MessageComposer.java index 8d68efc..cf0e62d 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/connection/MercuryMessageComposer.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/connection/message/MessageComposer.java @@ -1,27 +1,33 @@ -package org.mercury_im.messenger.core.connection; +package org.mercury_im.messenger.core.connection.message; +import org.jivesoftware.smack.packet.id.StandardStanzaIdSource; import org.mercury_im.messenger.entity.chat.Chat; import org.mercury_im.messenger.entity.message.Message; import org.mercury_im.messenger.entity.message.MessageDeliveryState; import org.mercury_im.messenger.entity.message.MessageDirection; +import java.util.Date; import java.util.UUID; -public class MercuryMessageComposer implements MessageCenter.Composer { +public class MessageComposer { - @Override public Message createChatMessage(Chat chat, String body) { + UUID messageId = UUID.randomUUID(); Message message = new Message(); + message.setId(messageId); + message.setChatId(chat.getId()); + + message.setLegacyStanzaId(new StandardStanzaIdSource().getNewStanzaId()); + message.setOriginId(messageId.toString()); + message.setBody(body); message.setSender(chat.getAccount().getJid()); - message.setRecipient(chat.getAddress()); + message.setRecipient(chat.getJid()); message.setDeliveryState(MessageDeliveryState.pending_delivery); message.setDirection(MessageDirection.outgoing); message.setRead(false); + message.setTimestamp(new Date()); - UUID messageId = UUID.randomUUID(); - message.setId(messageId); - message.setOriginId(messageId.toString()); return message; } } diff --git a/domain/src/main/java/org/mercury_im/messenger/core/connection/message/MessageConsignee.java b/domain/src/main/java/org/mercury_im/messenger/core/connection/message/MessageConsignee.java new file mode 100644 index 0000000..586d8b5 --- /dev/null +++ b/domain/src/main/java/org/mercury_im/messenger/core/connection/message/MessageConsignee.java @@ -0,0 +1,4 @@ +package org.mercury_im.messenger.core.connection.message; + +public interface MessageConsignee { +} diff --git a/domain/src/main/java/org/mercury_im/messenger/core/connection/message/MessageConsignor.java b/domain/src/main/java/org/mercury_im/messenger/core/connection/message/MessageConsignor.java new file mode 100644 index 0000000..f7236c6 --- /dev/null +++ b/domain/src/main/java/org/mercury_im/messenger/core/connection/message/MessageConsignor.java @@ -0,0 +1,12 @@ +package org.mercury_im.messenger.core.connection.message; + +import org.mercury_im.messenger.entity.chat.Chat; + +import java.util.UUID; + +import io.reactivex.Single; + +public interface MessageConsignor { + + Single sendTextMessage(Chat chat, String body); +} diff --git a/domain/src/main/java/org/mercury_im/messenger/core/connection/message/OxMessageConsignor.java b/domain/src/main/java/org/mercury_im/messenger/core/connection/message/OxMessageConsignor.java new file mode 100644 index 0000000..cf0cd98 --- /dev/null +++ b/domain/src/main/java/org/mercury_im/messenger/core/connection/message/OxMessageConsignor.java @@ -0,0 +1,25 @@ +package org.mercury_im.messenger.core.connection.message; + +import org.mercury_im.messenger.core.connection.MercuryConnectionManager; +import org.mercury_im.messenger.core.data.repository.MessageRepository; +import org.mercury_im.messenger.entity.chat.Chat; + +import java.util.UUID; + +import io.reactivex.Single; + +public class OxMessageConsignor extends AbstractMessageConsignor { + + public OxMessageConsignor(MercuryConnectionManager connectionManager, MessageRepository messageRepository, Chat chat) { + this(new MessageComposer(), connectionManager, messageRepository, chat); + } + + public OxMessageConsignor(MessageComposer composer, MercuryConnectionManager connectionManager, MessageRepository messageRepository, Chat chat) { + super(composer, connectionManager, messageRepository, chat); + } + + @Override + public Single sendTextMessage(Chat chat, String body) { + return null; + } +} diff --git a/domain/src/main/java/org/mercury_im/messenger/core/connection/message/PlaintextMessageConsignor.java b/domain/src/main/java/org/mercury_im/messenger/core/connection/message/PlaintextMessageConsignor.java new file mode 100644 index 0000000..9b2cd5d --- /dev/null +++ b/domain/src/main/java/org/mercury_im/messenger/core/connection/message/PlaintextMessageConsignor.java @@ -0,0 +1,91 @@ +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); + }); + } +} diff --git a/domain/src/main/java/org/mercury_im/messenger/core/data/repository/MessageRepository.java b/domain/src/main/java/org/mercury_im/messenger/core/data/repository/MessageRepository.java index 241223d..35e794f 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/data/repository/MessageRepository.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/data/repository/MessageRepository.java @@ -1,10 +1,14 @@ package org.mercury_im.messenger.core.data.repository; +import org.jxmpp.jid.EntityBareJid; import org.mercury_im.messenger.entity.chat.DirectChat; import org.mercury_im.messenger.entity.chat.GroupChat; +import org.mercury_im.messenger.entity.message.ChatMarkerState; import org.mercury_im.messenger.entity.message.Message; +import org.mercury_im.messenger.entity.message.MessageDeliveryState; import java.util.List; +import java.util.UUID; import io.reactivex.Completable; import io.reactivex.Observable; @@ -29,4 +33,8 @@ public interface MessageRepository { Single updateMessage(Message message); Completable deleteMessage(Message message); + + Completable markMessage(String stanzaId, EntityBareJid xmppAddressOfChatPartner, ChatMarkerState received); + + Completable updateDeliveryState(UUID messageId, MessageDeliveryState deliveryState); } diff --git a/domain/src/main/java/org/mercury_im/messenger/core/di/module/StanzaIdSourceFactoryModule.java b/domain/src/main/java/org/mercury_im/messenger/core/di/module/StanzaIdSourceFactoryModule.java new file mode 100644 index 0000000..23b8f88 --- /dev/null +++ b/domain/src/main/java/org/mercury_im/messenger/core/di/module/StanzaIdSourceFactoryModule.java @@ -0,0 +1,19 @@ +package org.mercury_im.messenger.core.di.module; + +import org.jivesoftware.smack.packet.id.StandardStanzaIdSource; +import org.jivesoftware.smack.packet.id.StanzaIdSourceFactory; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +@Module +public class StanzaIdSourceFactoryModule { + + @Provides + @Singleton + static StanzaIdSourceFactory provideStanzaIdSourceFactory() { + return new StandardStanzaIdSource.Factory(); + } +} diff --git a/domain/src/main/java/org/mercury_im/messenger/core/di/module/XmppTcpConnectionFactoryModule.java b/domain/src/main/java/org/mercury_im/messenger/core/di/module/XmppTcpConnectionFactoryModule.java index 88bcedc..1a2a704 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/di/module/XmppTcpConnectionFactoryModule.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/di/module/XmppTcpConnectionFactoryModule.java @@ -1,5 +1,6 @@ package org.mercury_im.messenger.core.di.module; +import org.jivesoftware.smack.packet.id.StanzaIdSourceFactory; import org.mercury_im.messenger.core.connection.XmppConnectionFactory; import org.mercury_im.messenger.core.connection.XmppTcpConnectionFactory; @@ -13,7 +14,7 @@ public class XmppTcpConnectionFactoryModule { @Provides @Singleton - static XmppConnectionFactory provideConnectionFactory() { - return new XmppTcpConnectionFactory(); + static XmppConnectionFactory provideConnectionFactory(StanzaIdSourceFactory stanzaIdSourceFactory) { + return new XmppTcpConnectionFactory(stanzaIdSourceFactory); } } diff --git a/domain/src/main/java/org/mercury_im/messenger/core/store/message/MercuryMessageStore.java b/domain/src/main/java/org/mercury_im/messenger/core/store/message/MercuryMessageStore.java index e4bb4f9..01e10eb 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/store/message/MercuryMessageStore.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/store/message/MercuryMessageStore.java @@ -29,7 +29,7 @@ import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; @Singleton -public class MercuryMessageStore implements IncomingChatMessageListener, OutgoingChatMessageListener, OxMessageListener { +public class MercuryMessageStore implements IncomingChatMessageListener, OxMessageListener { private static final Logger LOGGER = Logger.getLogger(MercuryMessageStore.class.getName()); @@ -66,8 +66,8 @@ public class MercuryMessageStore implements IncomingChatMessageListener, Outgoin message.setDirection(MessageDirection.incoming); DelayInformation delayInformation = DelayInformation.from(smackMessage); message.setTimestamp(delayInformation != null ? delayInformation.getStamp() : new Date()); - message.setSender(from.asEntityBareJidString()); - message.setRecipient(smackMessage.getTo().asBareJid().toString()); + message.setSender(from); + message.setRecipient(smackMessage.getTo().asEntityJidOrThrow()); message.setXml(smackMessage.toXML().toString()); if (smackMessage.getBody() != null) { message.setBody(smackMessage.getBody()); @@ -75,25 +75,6 @@ public class MercuryMessageStore implements IncomingChatMessageListener, Outgoin disposable.add(writeMessageToStore(from, message)); } - @Override - public void newOutgoingMessage(EntityBareJid to, - MessageBuilder smackMessage, - org.jivesoftware.smack.chat2.Chat smackChat) { - if (smackMessage.hasExtension(ExplicitMessageEncryptionElement.QNAME)) { - return; - } - Message message = new Message(); - message.setDirection(MessageDirection.outgoing); - message.setTimestamp(new Date()); - message.setSender(account.getAddress()); - message.setRecipient(to.asBareJid().toString()); - message.setXml(smackMessage.build().toXML().toString()); - if (smackMessage.getBody() != null) { - message.setBody(smackMessage.getBody()); - } - disposable.add(writeMessageToStore(to, message)); - } - private Disposable writeMessageToStore(EntityBareJid peer, Message message) { return peerRepository.getOrCreatePeer(account, peer) .flatMap(directChatRepository::getOrCreateChatWithPeer) @@ -115,8 +96,8 @@ public class MercuryMessageStore implements IncomingChatMessageListener, Outgoin message.setDirection(MessageDirection.incoming); DelayInformation delayInformation = DelayInformation.from(smackMessage); message.setTimestamp(delayInformation != null ? delayInformation.getStamp() : new Date()); - message.setSender(contact.getJid().toString()); - message.setRecipient(smackMessage.getTo().asBareJid().toString()); + message.setSender(contact.getJid().asEntityJidOrThrow()); + message.setRecipient(smackMessage.getTo().asEntityJidOrThrow()); message.setXml(smackMessage.toXML().toString()); org.jivesoftware.smack.packet.Message.Body body = decryptedPayload.getExtension(org.jivesoftware.smack.packet.Message.Body.ELEMENT, org.jivesoftware.smack.packet.Message.Body.NAMESPACE); diff --git a/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/account/LoginViewModel.java b/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/account/LoginViewModel.java index 935ceae..0c72c8f 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/account/LoginViewModel.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/account/LoginViewModel.java @@ -117,11 +117,11 @@ public class LoginViewModel implements MercuryViewModel { Account account = createAccountEntity(); - MercuryConnection connection = connectionManager.createConnection(account); + //MercuryConnection connection = connectionManager.createConnection(account); addDisposable(accountRepository.upsertAccount(account).ignoreElement() - .andThen(connection.connect()) - .andThen(connection.login()) - .andThen(connectionManager.registerConnection(connection)) + //.andThen(connection.connect()) + //.andThen(connection.login()) + //.andThen(connectionManager.registerConnection(connection)) .subscribeOn(schedulers.getNewThread()) .observeOn(schedulers.getUiScheduler()) .subscribe( diff --git a/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/chat/ChatViewModel.java b/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/chat/ChatViewModel.java index 72c786a..caa05c4 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/chat/ChatViewModel.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/chat/ChatViewModel.java @@ -19,6 +19,7 @@ import java.util.logging.Logger; import io.reactivex.Observable; import io.reactivex.Single; +import io.reactivex.functions.Function; import io.reactivex.subjects.BehaviorSubject; import lombok.Getter; @@ -35,8 +36,6 @@ public class ChatViewModel implements MercuryViewModel { @Getter private BehaviorSubject> peer = BehaviorSubject.create(); - private Single directChat; - @Getter private BehaviorSubject chat = BehaviorSubject.create(); @@ -62,13 +61,20 @@ public class ChatViewModel implements MercuryViewModel { } public void init(UUID accountId, EntityBareJid contactJid) { - Single peerSingle = contactRepository.getOrCreatePeer(accountId, contactJid); - peerSingle.flatMapObservable(contactRepository::observePeer).subscribe(peer); - directChat = peerSingle.flatMap(directChatRepository::getOrCreateChatWithPeer); + contactRepository.getOrCreatePeer(accountId, contactJid) + .flatMapObservable(contactRepository::observePeer) + .subscribe(peer); - directChat.toObservable().compose(schedulers.executeUiSafeObservable()).subscribe(chat); + peer.compose(schedulers.executeUiSafeObservable()) + .subscribe(); - Observable> allMessagesObservable = directChat.flatMapObservable(messageRepository::observeMessages); + peer.filter(Optional::isPresent).map(Optional::getItem) + .flatMap(p -> directChatRepository.getOrCreateChatWithPeer(p).toObservable()) + .subscribe(chat); + + chat.compose(schedulers.executeUiSafeObservable()).subscribe(); + + Observable> allMessagesObservable = chat.flatMap(messageRepository::observeMessages); messageQueryObservable.onNext(allMessagesObservable); messages = Observable.switchOnNext(messageQueryObservable); contactDisplayName = peer.filter(Optional::isPresent).map(Optional::getItem) @@ -77,9 +83,9 @@ public class ChatViewModel implements MercuryViewModel { public void onQueryTextChanged(String query) { if (query.trim().isEmpty()) { - messageQueryObservable.onNext(directChat.flatMapObservable(messageRepository::observeMessages)); + messageQueryObservable.onNext(chat.flatMap(messageRepository::observeMessages)); } else { - messageQueryObservable.onNext(directChat.flatMapObservable(c -> messageRepository.findMessagesWithBody(c, query))); + messageQueryObservable.onNext(chat.flatMap(c -> messageRepository.findMessagesWithBody(c, query))); } } @@ -95,9 +101,10 @@ public class ChatViewModel implements MercuryViewModel { } public void sendMessage(String body) { - addDisposable(messenger.sendEncryptedMessage(peer.getValue().getItem(), body) - .compose(schedulers.executeUiSafeCompletable()) - .subscribe(() -> LOGGER.log(Level.INFO, "Successfully sent encrypted message."), - e -> LOGGER.log(Level.SEVERE, "Error sending encrypted message.", e))); + addDisposable(messenger.getMessageConsignor(chat.getValue()) + .sendTextMessage(chat.getValue(), body) + .compose(schedulers.executeUiSafeSingle()) + .subscribe(messageId -> LOGGER.log(Level.INFO, "Successfully sent message."), + e -> LOGGER.log(Level.WARNING, "Error sending message.", e))); } } diff --git a/domain/src/test/java/org/mercury_im/messenger/learning_tests/dagger/DaggerTest.java b/domain/src/test/java/org/mercury_im/messenger/learning_tests/dagger/DaggerTest.java new file mode 100644 index 0000000..fb3ec03 --- /dev/null +++ b/domain/src/test/java/org/mercury_im/messenger/learning_tests/dagger/DaggerTest.java @@ -0,0 +1,111 @@ +package org.mercury_im.messenger.learning_tests.dagger; + +import org.junit.Test; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +import static junit.framework.TestCase.assertEquals; + +public class DaggerTest { + + @dagger.Component(modules = {SingletonModule.class}) + @Singleton + public interface Component { + + void inject(Consumer consumer); + } + + @Module + public class NewInstanceModule { + + private int DEPENDENCY_INDEX = 0; + private final String MODULE_NAME; + + public NewInstanceModule(String moduleName) { + this.MODULE_NAME = moduleName; + } + + @Provides + Dependency provideDependency() { + return new Dependency(DEPENDENCY_INDEX++, MODULE_NAME); + } + } + + @Module + public class SingletonModule { + private int DEPENDENCY_INDEX = 0; + private final String MODULE_NAME; + + public SingletonModule(String moduleName) { + this.MODULE_NAME = moduleName; + } + + @Provides + @Singleton + Dependency provideDependency() { + return new Dependency(DEPENDENCY_INDEX++, MODULE_NAME); + } + } + + + public static class Dependency { + + final int index; + final String moduleName; + + @Inject + public Dependency(int index, String moduleName) { + this.index = index; + this.moduleName = moduleName; + } + + public int getIndex() { + return index; + } + + public String getModuleName() { + return moduleName; + } + } + + public static class Consumer { + + @Inject + Dependency dependency; + + public Consumer() { + + } + + public Dependency getDependency() { + return dependency; + } + } + + @Test + public void test() { + Component component0 = DaggerDaggerTest_Component.builder().singletonModule(new SingletonModule("First")).build(); + + Consumer consumer0 = new Consumer(); + Consumer consumer1 = new Consumer(); + + component0.inject(consumer0); + component0.inject(consumer1); + + Component component1 = DaggerDaggerTest_Component.builder().singletonModule(new SingletonModule("Second")).build(); + + Consumer consumer2 = new Consumer(); + Consumer consumer3 = new Consumer(); + component1.inject(consumer2); + component1.inject(consumer3); + + assertEquals(0, consumer0.getDependency().getIndex()); + assertEquals(1, consumer1.getDependency().getIndex()); + assertEquals(0, consumer2.getDependency().getIndex()); + assertEquals(1, consumer3.getDependency().getIndex()); + } +} diff --git a/domain/src/test/java/org/mercury_im/messenger/learning_tests/rx/BehaviourSubjectSubscriptionTest.java b/domain/src/test/java/org/mercury_im/messenger/learning_tests/rx/BehaviourSubjectSubscriptionTest.java new file mode 100644 index 0000000..702101b --- /dev/null +++ b/domain/src/test/java/org/mercury_im/messenger/learning_tests/rx/BehaviourSubjectSubscriptionTest.java @@ -0,0 +1,26 @@ +package org.mercury_im.messenger.learning_tests.rx; + +import org.junit.Test; + +import io.reactivex.Observable; +import io.reactivex.subjects.BehaviorSubject; +import io.reactivex.subjects.Subject; + +import static junit.framework.TestCase.assertNotNull; + +public class BehaviourSubjectSubscriptionTest { + + @Test + public void test() throws InterruptedException { + Observable observable = Observable.just("One", "Two", "Three"); + BehaviorSubject behaviorSubject = BehaviorSubject.create(); + + observable.subscribe(behaviorSubject); + behaviorSubject.subscribe(System.out::println); + + Thread.sleep(100); + + String s = behaviorSubject.getValue(); + assertNotNull(s); + } +} diff --git a/entity/src/main/java/org/mercury_im/messenger/entity/chat/Chat.java b/entity/src/main/java/org/mercury_im/messenger/entity/chat/Chat.java index bfcd169..7818972 100644 --- a/entity/src/main/java/org/mercury_im/messenger/entity/chat/Chat.java +++ b/entity/src/main/java/org/mercury_im/messenger/entity/chat/Chat.java @@ -1,5 +1,7 @@ package org.mercury_im.messenger.entity.chat; +import org.jxmpp.jid.EntityJid; +import org.jxmpp.jid.impl.JidCreate; import org.mercury_im.messenger.entity.Account; import java.util.UUID; @@ -15,11 +17,15 @@ import lombok.Data; public abstract class Chat { UUID id; Account account; - ChatPreferences chatPreferences; + ChatPreferences chatPreferences = new ChatPreferences(); public Chat() { this.id = UUID.randomUUID(); } public abstract String getAddress(); + + public EntityJid getJid() { + return JidCreate.entityFromOrThrowUnchecked(getAddress()); + } } diff --git a/entity/src/main/java/org/mercury_im/messenger/entity/chat/ChatPreferences.java b/entity/src/main/java/org/mercury_im/messenger/entity/chat/ChatPreferences.java index 3f7aabd..589555c 100644 --- a/entity/src/main/java/org/mercury_im/messenger/entity/chat/ChatPreferences.java +++ b/entity/src/main/java/org/mercury_im/messenger/entity/chat/ChatPreferences.java @@ -1,5 +1,7 @@ package org.mercury_im.messenger.entity.chat; +import org.mercury_im.messenger.entity.Encryption; + import lombok.Data; /** @@ -12,6 +14,7 @@ public class ChatPreferences { boolean sendTypingNotificationsEnabled; boolean readNotificationsSupported; boolean sendReadNotificationsEnabled; + Encryption encryption = Encryption.plain; // TODO: Fix @Data public static class NotificationPreferences { diff --git a/entity/src/main/java/org/mercury_im/messenger/entity/chat/GroupChat.java b/entity/src/main/java/org/mercury_im/messenger/entity/chat/GroupChat.java index a90da90..1f6cf97 100644 --- a/entity/src/main/java/org/mercury_im/messenger/entity/chat/GroupChat.java +++ b/entity/src/main/java/org/mercury_im/messenger/entity/chat/GroupChat.java @@ -16,6 +16,7 @@ public class GroupChat extends Chat { Set participants; String roomAddress; String roomName; + String nickname = "NICK"; // TODO: Fix @Override public String getAddress() { diff --git a/entity/src/main/java/org/mercury_im/messenger/entity/message/ChatMarkerState.java b/entity/src/main/java/org/mercury_im/messenger/entity/message/ChatMarkerState.java new file mode 100644 index 0000000..3969391 --- /dev/null +++ b/entity/src/main/java/org/mercury_im/messenger/entity/message/ChatMarkerState.java @@ -0,0 +1,8 @@ +package org.mercury_im.messenger.entity.message; + +public enum ChatMarkerState { + markable, + received, + displayed, + acknowledged +} diff --git a/entity/src/main/java/org/mercury_im/messenger/entity/message/Message.java b/entity/src/main/java/org/mercury_im/messenger/entity/message/Message.java index 8d9a716..be3f436 100644 --- a/entity/src/main/java/org/mercury_im/messenger/entity/message/Message.java +++ b/entity/src/main/java/org/mercury_im/messenger/entity/message/Message.java @@ -1,10 +1,9 @@ package org.mercury_im.messenger.entity.message; -import org.jxmpp.jid.EntityFullJid; +import org.jxmpp.jid.EntityJid; import org.mercury_im.messenger.entity.Encryption; import java.util.Date; -import java.util.List; import java.util.UUID; import lombok.Data; @@ -13,8 +12,8 @@ import lombok.Data; public class Message { UUID id; UUID chatId; - EntityFullJid sender; - EntityFullJid recipient; + EntityJid sender; + EntityJid recipient; String body; @@ -34,6 +33,7 @@ public class Message { Encryption encryption; boolean received; boolean read; + boolean pending; public boolean isIncoming() { return getDirection() == MessageDirection.incoming; diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 97fd889..6afaae7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Sep 01 01:05:38 CEST 2019 +#Mon Jul 27 15:17:47 CEST 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip diff --git a/libs/Smack b/libs/Smack index 1267729..3003094 160000 --- a/libs/Smack +++ b/libs/Smack @@ -1 +1 @@ -Subproject commit 1267729430f2c53f966b98febf16ef7f262b94d7 +Subproject commit 30030941307262173ac7347e11235a8cadf68787 diff --git a/version.gradle b/version.gradle index 6dfecef..3853bac 100644 --- a/version.gradle +++ b/version.gradle @@ -86,7 +86,7 @@ ext { rxAndroidVersion = "2.1.1" // Dagger 2 - daggerVersion = '2.25.4' + daggerVersion = '2.28.3' // Lombok lombokVersion = '1.18.12'