aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/eu/siacs/conversations/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/eu/siacs/conversations/parser')
-rw-r--r--src/main/java/eu/siacs/conversations/parser/AbstractParser.java30
-rw-r--r--src/main/java/eu/siacs/conversations/parser/IqParser.java8
-rw-r--r--src/main/java/eu/siacs/conversations/parser/MessageParser.java59
-rw-r--r--src/main/java/eu/siacs/conversations/parser/PresenceParser.java8
4 files changed, 85 insertions, 20 deletions
diff --git a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java
index 9b3e239c..473195bd 100644
--- a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java
+++ b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java
@@ -1,5 +1,7 @@
package eu.siacs.conversations.parser;
+import android.util.Log;
+
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -41,8 +43,14 @@ public abstract class AbstractParser {
if (stamp == null) {
return now;
}
- long time = parseTimestamp(stamp).getTime();
- return now < time ? now : time;
+ /*long time = parseTimestamp(stamp).getTime();
+ return now < time ? now : time;*/
+ try {
+ long time = parseTimestamp(stamp).getTime();
+ return now < time ? now : time;
+ } catch (ParseException e) {
+ return now;
+ }
}
/**
@@ -53,17 +61,29 @@ public abstract class AbstractParser {
* @return Date
* @throws ParseException
*/
- public static Date parseTimestamp(String timestamp) {
- try {
+ public static Date parseTimestamp(String timestamp) throws ParseException {
+ /*try {
+ Log.d("TIMESTAMP", timestamp);
return DatatypeFactory.newInstance().newXMLGregorianCalendar(timestamp).toGregorianCalendar().getTime();
} catch (DatatypeConfigurationException e) {
+ Log.d("TIMESTAMP", e.getMessage());
return new Date();
- }
+ }*/
+ timestamp = timestamp.replace("Z", "+0000");
+ SimpleDateFormat dateFormat;
+ timestamp = timestamp.substring(0,19)+timestamp.substring(timestamp.length() -5,timestamp.length());
+ dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ",Locale.US);
+ return dateFormat.parse(timestamp);
}
protected void updateLastseen(final Element packet, final Account account,
final boolean presenceOverwrite) {
final Jid from = packet.getAttributeAsJid("from");
+ updateLastseen(packet, account, from, presenceOverwrite);
+ }
+
+ protected void updateLastseen(final Element packet, final Account account, final Jid from,
+ final boolean presenceOverwrite) {
final String presence = from == null || from.isBareJid() ? "" : from.getResourcepart();
final Contact contact = account.getRoster().getContact(from);
final long timestamp = getTimestamp(packet);
diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java
index 6430c296..6039d395 100644
--- a/src/main/java/eu/siacs/conversations/parser/IqParser.java
+++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java
@@ -134,9 +134,11 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
mXmppConnectionService.getJingleConnectionManager()
.deliverIbbPacket(account, packet);
} else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) {
- final IqPacket response = mXmppConnectionService.getIqGenerator()
- .discoResponse(packet);
- account.getXmppConnection().sendIqPacket(response, null);
+ final IqPacket response = mXmppConnectionService.getIqGenerator().discoResponse(packet);
+ mXmppConnectionService.sendIqPacket(account, response, null);
+ } else if (packet.hasChild("query","jabber:iq:version")) {
+ final IqPacket response = mXmppConnectionService.getIqGenerator().versionResponse(packet);
+ mXmppConnectionService.sendIqPacket(account,response,null);
} else if (packet.hasChild("ping", "urn:xmpp:ping")) {
final IqPacket response = packet.generateResponse(IqPacket.TYPE.RESULT);
mXmppConnectionService.sendIqPacket(account, response, null);
diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
index 49efb004..8ae9b642 100644
--- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java
+++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
@@ -14,6 +14,7 @@ import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.OnMessagePacketReceived;
+import eu.siacs.conversations.xmpp.chatstate.ChatState;
import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.pep.Avatar;
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
@@ -24,13 +25,27 @@ public class MessageParser extends AbstractParser implements
super(service);
}
+ private boolean extractChatState(Conversation conversation, final Element element) {
+ ChatState state = ChatState.parse(element);
+ if (state != null && conversation != null) {
+ final Account account = conversation.getAccount();
+ Jid from = element.getAttributeAsJid("from");
+ if (from != null && from.toBareJid().equals(account.getJid().toBareJid())) {
+ conversation.setOutgoingChatState(state);
+ return false;
+ } else {
+ return conversation.setIncomingChatState(state);
+ }
+ }
+ return false;
+ }
+
private Message parseChat(MessagePacket packet, Account account) {
- final Jid jid = packet.getFrom();
+ final Jid jid = packet.getFrom();
if (jid == null) {
return null;
}
Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, jid.toBareJid(), false);
- updateLastseen(packet, account, true);
String pgpBody = getPgpBody(packet);
Message finishedMessage;
if (pgpBody != null) {
@@ -45,16 +60,22 @@ public class MessageParser extends AbstractParser implements
finishedMessage.markable = isMarkable(packet);
if (conversation.getMode() == Conversation.MODE_MULTI
&& !jid.isBareJid()) {
+ final Jid trueCounterpart = conversation.getMucOptions()
+ .getTrueCounterpart(jid.getResourcepart());
+ if (trueCounterpart != null) {
+ updateLastseen(packet, account, trueCounterpart, false);
+ }
finishedMessage.setType(Message.TYPE_PRIVATE);
- finishedMessage.setTrueCounterpart(conversation.getMucOptions()
- .getTrueCounterpart(jid.getResourcepart()));
+ finishedMessage.setTrueCounterpart(trueCounterpart);
if (conversation.hasDuplicateMessage(finishedMessage)) {
return null;
}
-
+ } else {
+ updateLastseen(packet, account, true);
}
finishedMessage.setCounterpart(jid);
finishedMessage.setTime(getTimestamp(packet));
+ extractChatState(conversation,packet);
return finishedMessage;
}
@@ -69,10 +90,11 @@ public class MessageParser extends AbstractParser implements
.findOrCreateConversation(account, from.toBareJid(), false);
String presence;
if (from.isBareJid()) {
- presence = "";
+ presence = "";
} else {
presence = from.getResourcepart();
}
+ extractChatState(conversation, packet);
updateLastseen(packet, account, true);
String body = packet.getBody();
if (body.matches("^\\?OTRv\\d{1,2}\\?.*")) {
@@ -97,6 +119,7 @@ public class MessageParser extends AbstractParser implements
}
}
try {
+ conversation.setLastReceivedOtrMessageId(packet.getId());
Session otrSession = conversation.getOtrSession();
SessionStatus before = otrSession.getSessionStatus();
body = otrSession.transformReceiving(body);
@@ -123,6 +146,7 @@ public class MessageParser extends AbstractParser implements
finishedMessage.setRemoteMsgId(packet.getId());
finishedMessage.markable = isMarkable(packet);
finishedMessage.setCounterpart(from);
+ conversation.setLastReceivedOtrMessageId(null);
return finishedMessage;
} catch (Exception e) {
conversation.resetOtrSession();
@@ -132,7 +156,7 @@ public class MessageParser extends AbstractParser implements
private Message parseGroupchat(MessagePacket packet, Account account) {
int status;
- final Jid from = packet.getFrom();
+ final Jid from = packet.getFrom();
if (from == null) {
return null;
}
@@ -142,6 +166,10 @@ public class MessageParser extends AbstractParser implements
}
Conversation conversation = mXmppConnectionService
.findOrCreateConversation(account, from.toBareJid(), true);
+ final Jid trueCounterpart = conversation.getMucOptions().getTrueCounterpart(from.getResourcepart());
+ if (trueCounterpart != null) {
+ updateLastseen(packet, account, trueCounterpart, false);
+ }
if (packet.hasChild("subject")) {
conversation.setHasMessagesLeftOnServer(true);
conversation.getMucOptions().setSubject(packet.findChild("subject").getContent());
@@ -275,6 +303,7 @@ public class MessageParser extends AbstractParser implements
finishedMessage = new Message(conversation, body,
Message.ENCRYPTION_NONE, status);
}
+ extractChatState(conversation,message);
finishedMessage.setTime(getTimestamp(message));
finishedMessage.setRemoteMsgId(message.getAttribute("id"));
finishedMessage.markable = isMarkable(message);
@@ -362,6 +391,9 @@ public class MessageParser extends AbstractParser implements
private void parseNonMessage(Element packet, Account account) {
final Jid from = packet.getAttributeAsJid("from");
+ if (extractChatState(from == null ? null : mXmppConnectionService.find(account,from), packet)) {
+ mXmppConnectionService.updateConversationUi();
+ }
Element invite = extractInvite(packet);
if (invite != null) {
Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, from, true);
@@ -377,14 +409,19 @@ public class MessageParser extends AbstractParser implements
Element event = packet.findChild("event",
"http://jabber.org/protocol/pubsub#event");
parseEvent(event, from, account);
- } else if (from != null
- && packet.hasChild("displayed", "urn:xmpp:chat-markers:0")) {
+ } else if (from != null && packet.hasChild("displayed", "urn:xmpp:chat-markers:0")) {
String id = packet
.findChild("displayed", "urn:xmpp:chat-markers:0")
.getAttribute("id");
updateLastseen(packet, account, true);
- mXmppConnectionService.markMessage(account, from.toBareJid(),
- id, Message.STATUS_SEND_DISPLAYED);
+ final Message displayedMessage = mXmppConnectionService.markMessage(account, from.toBareJid(), id, Message.STATUS_SEND_DISPLAYED);
+ Message message = displayedMessage == null ? null :displayedMessage.prev();
+ while (message != null
+ && message.getStatus() == Message.STATUS_SEND_RECEIVED
+ && message.getTimeSent() < displayedMessage.getTimeSent()) {
+ mXmppConnectionService.markMessage(message, Message.STATUS_SEND_DISPLAYED);
+ message = message.prev();
+ }
} else if (from != null
&& packet.hasChild("received", "urn:xmpp:chat-markers:0")) {
String id = packet.findChild("received", "urn:xmpp:chat-markers:0")
diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java
index accb56ea..7505b091 100644
--- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java
+++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java
@@ -1,5 +1,7 @@
package eu.siacs.conversations.parser;
+import java.util.ArrayList;
+
import eu.siacs.conversations.crypto.PgpEngine;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Contact;
@@ -27,8 +29,12 @@ public class PresenceParser extends AbstractParser implements
final MucOptions mucOptions = conversation.getMucOptions();
boolean before = mucOptions.online();
int count = mucOptions.getUsers().size();
+ final ArrayList<MucOptions.User> tileUserBefore = new ArrayList<>(mucOptions.getUsers().subList(0,Math.min(mucOptions.getUsers().size(),5)));
mucOptions.processPacket(packet, mPgpEngine);
- mXmppConnectionService.getAvatarService().clear(conversation);
+ final ArrayList<MucOptions.User> tileUserAfter = new ArrayList<>(mucOptions.getUsers().subList(0,Math.min(mucOptions.getUsers().size(),5)));
+ if (!tileUserAfter.equals(tileUserBefore)) {
+ mXmppConnectionService.getAvatarService().clear(conversation);
+ }
if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUsers().size())) {
mXmppConnectionService.updateConversationUi();
} else if (mucOptions.online()) {