aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/eu/siacs/conversations/crypto/OtrEngine.java4
-rw-r--r--src/eu/siacs/conversations/entities/Conversation.java2
-rw-r--r--src/eu/siacs/conversations/entities/Message.java11
-rw-r--r--src/eu/siacs/conversations/entities/MucOptions.java8
-rw-r--r--src/eu/siacs/conversations/entities/Roster.java4
-rw-r--r--src/eu/siacs/conversations/generator/AbstractGenerator.java8
-rw-r--r--src/eu/siacs/conversations/generator/IqGenerator.java5
-rw-r--r--src/eu/siacs/conversations/generator/MessageGenerator.java18
-rw-r--r--src/eu/siacs/conversations/generator/PresenceGenerator.java5
-rw-r--r--src/eu/siacs/conversations/parser/AbstractParser.java2
-rw-r--r--src/eu/siacs/conversations/parser/MessageParser.java34
-rw-r--r--src/eu/siacs/conversations/parser/PresenceParser.java4
-rw-r--r--src/eu/siacs/conversations/persistance/DatabaseBackend.java10
-rw-r--r--src/eu/siacs/conversations/services/EventReceiver.java5
-rw-r--r--src/eu/siacs/conversations/services/ImageProvider.java2
-rw-r--r--src/eu/siacs/conversations/services/XmppConnectionService.java30
-rw-r--r--src/eu/siacs/conversations/ui/ChooseContactActivity.java1
-rw-r--r--src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java2
-rw-r--r--src/eu/siacs/conversations/ui/ConversationActivity.java5
-rw-r--r--src/eu/siacs/conversations/ui/ConversationFragment.java45
-rw-r--r--src/eu/siacs/conversations/ui/ManageAccountActivity.java8
-rw-r--r--src/eu/siacs/conversations/ui/SettingsActivity.java17
-rw-r--r--src/eu/siacs/conversations/ui/StartConversationActivity.java1
-rw-r--r--src/eu/siacs/conversations/ui/XmppActivity.java6
-rw-r--r--src/eu/siacs/conversations/ui/adapter/MessageAdapter.java77
-rw-r--r--src/eu/siacs/conversations/utils/UIHelper.java34
-rw-r--r--src/eu/siacs/conversations/xmpp/XmppConnection.java2
-rw-r--r--src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java4
28 files changed, 236 insertions, 118 deletions
diff --git a/src/eu/siacs/conversations/crypto/OtrEngine.java b/src/eu/siacs/conversations/crypto/OtrEngine.java
index 5dfd6fd6..e0bd0e79 100644
--- a/src/eu/siacs/conversations/crypto/OtrEngine.java
+++ b/src/eu/siacs/conversations/crypto/OtrEngine.java
@@ -18,8 +18,6 @@ import android.util.Log;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.entities.Account;
-import eu.siacs.conversations.entities.Conversation;
-import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
@@ -29,8 +27,6 @@ import net.java.otr4j.OtrPolicy;
import net.java.otr4j.OtrPolicyImpl;
import net.java.otr4j.session.InstanceTag;
import net.java.otr4j.session.SessionID;
-import net.java.otr4j.session.SessionImpl;
-import net.java.otr4j.session.SessionStatus;
public class OtrEngine implements OtrEngineHost {
diff --git a/src/eu/siacs/conversations/entities/Conversation.java b/src/eu/siacs/conversations/entities/Conversation.java
index 005b83db..8395449d 100644
--- a/src/eu/siacs/conversations/entities/Conversation.java
+++ b/src/eu/siacs/conversations/entities/Conversation.java
@@ -230,7 +230,7 @@ public class Conversation extends AbstractEntity {
return this.otrSession;
} else {
SessionID sessionId = new SessionID(
- this.getContactJid().split("/")[0], presence, "xmpp");
+ this.getContactJid().split("/",2)[0], presence, "xmpp");
this.otrSession = new SessionImpl(sessionId, getAccount()
.getOtrEngine(service));
try {
diff --git a/src/eu/siacs/conversations/entities/Message.java b/src/eu/siacs/conversations/entities/Message.java
index ce496d27..8f9885c5 100644
--- a/src/eu/siacs/conversations/entities/Message.java
+++ b/src/eu/siacs/conversations/entities/Message.java
@@ -246,9 +246,10 @@ public class Message extends AbstractEntity {
public void setPresence(String presence) {
if (presence == null) {
- this.counterpart = this.counterpart.split("/")[0];
+ this.counterpart = this.counterpart.split("/", 2)[0];
} else {
- this.counterpart = this.counterpart.split("/")[0] + "/" + presence;
+ this.counterpart = this.counterpart.split("/", 2)[0] + "/"
+ + presence;
}
}
@@ -257,7 +258,7 @@ public class Message extends AbstractEntity {
}
public String getPresence() {
- String[] counterparts = this.counterpart.split("/");
+ String[] counterparts = this.counterpart.split("/", 2);
if (counterparts.length == 2) {
return counterparts[1];
} else {
@@ -327,11 +328,11 @@ public class Message extends AbstractEntity {
&& this.getEncryption() == message.getEncryption()
&& this.getCounterpart().equals(message.getCounterpart())
&& (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && ((this
- .getStatus() == message.getStatus()) || ((this.getStatus() == Message.STATUS_SEND || this
+ .getStatus() == message.getStatus() || ((this.getStatus() == Message.STATUS_SEND || this
.getStatus() == Message.STATUS_SEND_RECEIVED) && (message
.getStatus() == Message.STATUS_UNSEND
|| message.getStatus() == Message.STATUS_SEND || message
- .getStatus() == Message.STATUS_SEND_DISPLAYED))));
+ .getStatus() == Message.STATUS_SEND_DISPLAYED)))));
}
public String getMergedBody() {
diff --git a/src/eu/siacs/conversations/entities/MucOptions.java b/src/eu/siacs/conversations/entities/MucOptions.java
index e9ab6908..676fb4f4 100644
--- a/src/eu/siacs/conversations/entities/MucOptions.java
+++ b/src/eu/siacs/conversations/entities/MucOptions.java
@@ -134,7 +134,7 @@ public class MucOptions {
}
public void processPacket(PresencePacket packet, PgpEngine pgp) {
- String[] fromParts = packet.getFrom().split("/");
+ String[] fromParts = packet.getFrom().split("/",2);
if (fromParts.length >= 2) {
String name = fromParts[1];
String type = packet.getAttribute("type");
@@ -180,7 +180,7 @@ public class MucOptions {
}
}
} else if (type.equals("unavailable")) {
- deleteUser(packet.getAttribute("from").split("/")[1]);
+ deleteUser(packet.getAttribute("from").split("/",2)[1]);
} else if (type.equals("error")) {
Element error = packet.findChild("error");
if (error.hasChild("conflict")) {
@@ -209,7 +209,7 @@ public class MucOptions {
}
public String getProposedNick() {
- String[] mucParts = conversation.getContactJid().split("/");
+ String[] mucParts = conversation.getContactJid().split("/",2);
if (conversation.getBookmark() != null
&& conversation.getBookmark().getNick() != null) {
return conversation.getBookmark().getNick();
@@ -309,7 +309,7 @@ public class MucOptions {
}
public String getJoinJid() {
- return this.conversation.getContactJid().split("/")[0] + "/"
+ return this.conversation.getContactJid().split("/",2)[0] + "/"
+ this.joinnick;
}
diff --git a/src/eu/siacs/conversations/entities/Roster.java b/src/eu/siacs/conversations/entities/Roster.java
index c6212f77..f11f0250 100644
--- a/src/eu/siacs/conversations/entities/Roster.java
+++ b/src/eu/siacs/conversations/entities/Roster.java
@@ -15,12 +15,12 @@ public class Roster {
}
public boolean hasContact(String jid) {
- String cleanJid = jid.split("/")[0];
+ String cleanJid = jid.split("/",2)[0];
return contacts.containsKey(cleanJid);
}
public Contact getContact(String jid) {
- String cleanJid = jid.split("/")[0].toLowerCase(Locale.getDefault());
+ String cleanJid = jid.split("/",2)[0].toLowerCase(Locale.getDefault());
if (contacts.containsKey(cleanJid)) {
return contacts.get(cleanJid);
} else {
diff --git a/src/eu/siacs/conversations/generator/AbstractGenerator.java b/src/eu/siacs/conversations/generator/AbstractGenerator.java
index 05d3d988..61f290e4 100644
--- a/src/eu/siacs/conversations/generator/AbstractGenerator.java
+++ b/src/eu/siacs/conversations/generator/AbstractGenerator.java
@@ -6,6 +6,8 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import eu.siacs.conversations.services.XmppConnectionService;
+
import android.util.Base64;
public abstract class AbstractGenerator {
@@ -19,6 +21,12 @@ public abstract class AbstractGenerator {
"urn:xmpp:avatar:metadata+notify" };
public final String IDENTITY_NAME = "Conversations 0.7";
public final String IDENTITY_TYPE = "phone";
+
+ protected XmppConnectionService mXmppConnectionService;
+
+ protected AbstractGenerator(XmppConnectionService service) {
+ this.mXmppConnectionService = service;
+ }
public String getCapHash() {
StringBuilder s = new StringBuilder();
diff --git a/src/eu/siacs/conversations/generator/IqGenerator.java b/src/eu/siacs/conversations/generator/IqGenerator.java
index b5ecafb5..d44bf0ca 100644
--- a/src/eu/siacs/conversations/generator/IqGenerator.java
+++ b/src/eu/siacs/conversations/generator/IqGenerator.java
@@ -4,12 +4,17 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.pep.Avatar;
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
public class IqGenerator extends AbstractGenerator {
+ public IqGenerator(XmppConnectionService service) {
+ super(service);
+ }
+
public IqPacket discoResponse(IqPacket request) {
IqPacket packet = new IqPacket(IqPacket.TYPE_RESULT);
packet.setId(request.getId());
diff --git a/src/eu/siacs/conversations/generator/MessageGenerator.java b/src/eu/siacs/conversations/generator/MessageGenerator.java
index ecfb4744..d4cab3ed 100644
--- a/src/eu/siacs/conversations/generator/MessageGenerator.java
+++ b/src/eu/siacs/conversations/generator/MessageGenerator.java
@@ -10,10 +10,15 @@ import net.java.otr4j.session.Session;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
-public class MessageGenerator {
+public class MessageGenerator extends AbstractGenerator {
+ public MessageGenerator(XmppConnectionService service) {
+ super(service);
+ }
+
private MessagePacket preparePacket(Message message, boolean addDelay) {
Conversation conversation = message.getConversation();
Account account = conversation.getAccount();
@@ -22,11 +27,14 @@ public class MessageGenerator {
packet.setTo(message.getCounterpart());
packet.setType(MessagePacket.TYPE_CHAT);
packet.addChild("markable", "urn:xmpp:chat-markers:0");
+ if (this.mXmppConnectionService.indicateReceived()) {
+ packet.addChild("request", "urn:xmpp:receipts");
+ }
} else if (message.getType() == Message.TYPE_PRIVATE) {
packet.setTo(message.getCounterpart());
packet.setType(MessagePacket.TYPE_CHAT);
} else {
- packet.setTo(message.getCounterpart().split("/")[0]);
+ packet.setTo(message.getCounterpart().split("/",2)[0]);
packet.setType(MessagePacket.TYPE_GROUPCHAT);
}
packet.setFrom(account.getFullJid());
@@ -126,7 +134,7 @@ public class MessageGenerator {
String subject) {
MessagePacket packet = new MessagePacket();
packet.setType(MessagePacket.TYPE_GROUPCHAT);
- packet.setTo(conversation.getContactJid().split("/")[0]);
+ packet.setTo(conversation.getContactJid().split("/",2)[0]);
Element subjectChild = new Element("subject");
subjectChild.setContent(subject);
packet.addChild(subjectChild);
@@ -140,13 +148,13 @@ public class MessageGenerator {
packet.setTo(contact);
packet.setFrom(conversation.getAccount().getFullJid());
Element x = packet.addChild("x", "jabber:x:conference");
- x.setAttribute("jid", conversation.getContactJid().split("/")[0]);
+ x.setAttribute("jid", conversation.getContactJid().split("/",2)[0]);
return packet;
}
public MessagePacket invite(Conversation conversation, String contact) {
MessagePacket packet = new MessagePacket();
- packet.setTo(conversation.getContactJid().split("/")[0]);
+ packet.setTo(conversation.getContactJid().split("/",2)[0]);
packet.setFrom(conversation.getAccount().getFullJid());
Element x = new Element("x");
x.setAttribute("xmlns", "http://jabber.org/protocol/muc#user");
diff --git a/src/eu/siacs/conversations/generator/PresenceGenerator.java b/src/eu/siacs/conversations/generator/PresenceGenerator.java
index 87e361f5..d896dd00 100644
--- a/src/eu/siacs/conversations/generator/PresenceGenerator.java
+++ b/src/eu/siacs/conversations/generator/PresenceGenerator.java
@@ -2,11 +2,16 @@ package eu.siacs.conversations.generator;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Contact;
+import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
public class PresenceGenerator extends AbstractGenerator {
+ public PresenceGenerator(XmppConnectionService service) {
+ super(service);
+ }
+
private PresencePacket subscription(String type, Contact contact) {
PresencePacket packet = new PresencePacket();
packet.setAttribute("type", type);
diff --git a/src/eu/siacs/conversations/parser/AbstractParser.java b/src/eu/siacs/conversations/parser/AbstractParser.java
index 25fcd921..efbf5aef 100644
--- a/src/eu/siacs/conversations/parser/AbstractParser.java
+++ b/src/eu/siacs/conversations/parser/AbstractParser.java
@@ -60,7 +60,7 @@ public abstract class AbstractParser {
protected void updateLastseen(Element packet, Account account,
boolean presenceOverwrite) {
- String[] fromParts = packet.getAttribute("from").split("/");
+ String[] fromParts = packet.getAttribute("from").split("/",2);
String from = fromParts[0];
String presence = null;
if (fromParts.length >= 2) {
diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java
index 534c9dea..0e15c60f 100644
--- a/src/eu/siacs/conversations/parser/MessageParser.java
+++ b/src/eu/siacs/conversations/parser/MessageParser.java
@@ -25,7 +25,7 @@ public class MessageParser extends AbstractParser implements
}
private Message parseChat(MessagePacket packet, Account account) {
- String[] fromParts = packet.getFrom().split("/");
+ String[] fromParts = packet.getFrom().split("/",2);
Conversation conversation = mXmppConnectionService
.findOrCreateConversation(account, fromParts[0], false);
conversation.setLatestMarkableMessageId(getMarkableMessageId(packet));
@@ -57,9 +57,9 @@ public class MessageParser extends AbstractParser implements
}
private Message parseOtrChat(MessagePacket packet, Account account) {
- boolean properlyAddressed = (packet.getTo().split("/").length == 2)
+ boolean properlyAddressed = (packet.getTo().split("/",2).length == 2)
|| (account.countPresences() == 1);
- String[] fromParts = packet.getFrom().split("/");
+ String[] fromParts = packet.getFrom().split("/",2);
Conversation conversation = mXmppConnectionService
.findOrCreateConversation(account, fromParts[0], false);
String presence;
@@ -132,7 +132,7 @@ public class MessageParser extends AbstractParser implements
private Message parseGroupchat(MessagePacket packet, Account account) {
int status;
- String[] fromParts = packet.getFrom().split("/");
+ String[] fromParts = packet.getFrom().split("/",2);
if (mXmppConnectionService.find(account.pendingConferenceLeaves,
account, fromParts[0]) != null) {
return null;
@@ -186,11 +186,13 @@ public class MessageParser extends AbstractParser implements
int status;
String fullJid;
Element forwarded;
- if (packet.hasChild("received")) {
- forwarded = packet.findChild("received").findChild("forwarded");
+ if (packet.hasChild("received", "urn:xmpp:carbons:2")) {
+ forwarded = packet.findChild("received", "urn:xmpp:carbons:2")
+ .findChild("forwarded", "urn:xmpp:forward:0");
status = Message.STATUS_RECEIVED;
- } else if (packet.hasChild("sent")) {
- forwarded = packet.findChild("sent").findChild("forwarded");
+ } else if (packet.hasChild("sent", "urn:xmpp:carbons:2")) {
+ forwarded = packet.findChild("sent", "urn:xmpp:carbons:2")
+ .findChild("forwarded", "urn:xmpp:forward:0");
status = Message.STATUS_SEND;
} else {
return null;
@@ -219,7 +221,7 @@ public class MessageParser extends AbstractParser implements
return null;
}
}
- String[] parts = fullJid.split("/");
+ String[] parts = fullJid.split("/",2);
Conversation conversation = mXmppConnectionService
.findOrCreateConversation(account, parts[0], false);
conversation.setLatestMarkableMessageId(getMarkableMessageId(packet));
@@ -251,7 +253,7 @@ public class MessageParser extends AbstractParser implements
}
private void parseError(MessagePacket packet, Account account) {
- String[] fromParts = packet.getFrom().split("/");
+ String[] fromParts = packet.getFrom().split("/",2);
mXmppConnectionService.markMessage(account, fromParts[0],
packet.getId(), Message.STATUS_SEND_FAILED);
}
@@ -265,13 +267,20 @@ public class MessageParser extends AbstractParser implements
String id = packet
.findChild("displayed", "urn:xmpp:chat-markers:0")
.getAttribute("id");
- String[] fromParts = packet.getAttribute("from").split("/");
+ String[] fromParts = packet.getAttribute("from").split("/",2);
updateLastseen(packet, account, true);
mXmppConnectionService.markMessage(account, fromParts[0], id,
Message.STATUS_SEND_DISPLAYED);
} else if (packet.hasChild("received", "urn:xmpp:chat-markers:0")) {
String id = packet.findChild("received", "urn:xmpp:chat-markers:0")
.getAttribute("id");
+ String[] fromParts = packet.getAttribute("from").split("/",2);
+ updateLastseen(packet, account, false);
+ mXmppConnectionService.markMessage(account, fromParts[0], id,
+ Message.STATUS_SEND_RECEIVED);
+ } else if (packet.hasChild("received", "urn:xmpp:receipts")) {
+ String id = packet.findChild("received", "urn:xmpp:receipts")
+ .getAttribute("id");
String[] fromParts = packet.getAttribute("from").split("/");
updateLastseen(packet, account, false);
mXmppConnectionService.markMessage(account, fromParts[0], id,
@@ -392,7 +401,8 @@ public class MessageParser extends AbstractParser implements
if (message != null) {
message.markUnread();
}
- } else if (packet.hasChild("received") || (packet.hasChild("sent"))) {
+ } else if (packet.hasChild("received", "urn:xmpp:carbons:2")
+ || (packet.hasChild("sent", "urn:xmpp:carbons:2"))) {
message = this.parseCarbonMessage(packet, account);
if (message != null) {
if (message.getStatus() == Message.STATUS_SEND) {
diff --git a/src/eu/siacs/conversations/parser/PresenceParser.java b/src/eu/siacs/conversations/parser/PresenceParser.java
index 05ffa67e..e240a858 100644
--- a/src/eu/siacs/conversations/parser/PresenceParser.java
+++ b/src/eu/siacs/conversations/parser/PresenceParser.java
@@ -22,7 +22,7 @@ public class PresenceParser extends AbstractParser implements
PgpEngine mPgpEngine = mXmppConnectionService.getPgpEngine();
if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) {
Conversation muc = mXmppConnectionService.find(account, packet
- .getAttribute("from").split("/")[0]);
+ .getAttribute("from").split("/",2)[0]);
if (muc != null) {
boolean before = muc.getMucOptions().online();
muc.getMucOptions().processPacket(packet, mPgpEngine);
@@ -32,7 +32,7 @@ public class PresenceParser extends AbstractParser implements
}
} else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) {
Conversation muc = mXmppConnectionService.find(account, packet
- .getAttribute("from").split("/")[0]);
+ .getAttribute("from").split("/",2)[0]);
if (muc != null) {
boolean before = muc.getMucOptions().online();
muc.getMucOptions().processPacket(packet, mPgpEngine);
diff --git a/src/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/eu/siacs/conversations/persistance/DatabaseBackend.java
index cda2f356..51fd79e5 100644
--- a/src/eu/siacs/conversations/persistance/DatabaseBackend.java
+++ b/src/eu/siacs/conversations/persistance/DatabaseBackend.java
@@ -32,7 +32,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
+ ") ON DELETE CASCADE, UNIQUE(" + Contact.ACCOUNT + ", "
+ Contact.JID + ") ON CONFLICT REPLACE);";
- public DatabaseBackend(Context context) {
+ private DatabaseBackend(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@@ -221,6 +221,14 @@ public class DatabaseBackend extends SQLiteOpenHelper {
String[] args = { account.getUuid() };
db.delete(Account.TABLENAME, Account.UUID + "=?", args);
}
+
+ public boolean hasEnabledAccounts() {
+ SQLiteDatabase db = this.getReadableDatabase();
+ Cursor cursor= db.rawQuery("select count("+Account.UUID+") from "+Account.TABLENAME+" where not options & (1 <<1)", null);
+ cursor.moveToFirst();
+ int count = cursor.getInt(0);
+ return (count>0);
+ }
@Override
public SQLiteDatabase getWritableDatabase() {
diff --git a/src/eu/siacs/conversations/services/EventReceiver.java b/src/eu/siacs/conversations/services/EventReceiver.java
index c0bf67f3..e2445b2a 100644
--- a/src/eu/siacs/conversations/services/EventReceiver.java
+++ b/src/eu/siacs/conversations/services/EventReceiver.java
@@ -1,5 +1,6 @@
package eu.siacs.conversations.services;
+import eu.siacs.conversations.persistance.DatabaseBackend;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -14,7 +15,9 @@ public class EventReceiver extends BroadcastReceiver {
} else {
mIntentForService.setAction("other");
}
- context.startService(mIntentForService);
+ if (intent.getAction().equals("ui") || DatabaseBackend.getInstance(context).hasEnabledAccounts()) {
+ context.startService(mIntentForService);
+ }
}
}
diff --git a/src/eu/siacs/conversations/services/ImageProvider.java b/src/eu/siacs/conversations/services/ImageProvider.java
index 15b86802..af8ab4b2 100644
--- a/src/eu/siacs/conversations/services/ImageProvider.java
+++ b/src/eu/siacs/conversations/services/ImageProvider.java
@@ -31,7 +31,7 @@ public class ImageProvider extends ContentProvider {
if (uuids == null) {
throw new FileNotFoundException();
}
- String[] uuidsSplited = uuids.split("/");
+ String[] uuidsSplited = uuids.split("/",2);
if (uuidsSplited.length != 3) {
throw new FileNotFoundException();
}
diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java
index c019682e..f80bb9ef 100644
--- a/src/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/eu/siacs/conversations/services/XmppConnectionService.java
@@ -96,8 +96,8 @@ public class XmppConnectionService extends Service {
private MessageParser mMessageParser = new MessageParser(this);
private PresenceParser mPresenceParser = new PresenceParser(this);
private IqParser mIqParser = new IqParser(this);
- private MessageGenerator mMessageGenerator = new MessageGenerator();
- private PresenceGenerator mPresenceGenerator = new PresenceGenerator();
+ private MessageGenerator mMessageGenerator = new MessageGenerator(this);
+ private PresenceGenerator mPresenceGenerator = new PresenceGenerator(this);
private List<Account> accounts;
private CopyOnWriteArrayList<Conversation> conversations = null;
@@ -585,18 +585,18 @@ public class XmppConnectionService extends Service {
}
}
+ conv.getMessages().add(message);
+ if (!account.getXmppConnection().getFeatures().sm()
+ && conv.getMode() != Conversation.MODE_MULTI) {
+ message.setStatus(Message.STATUS_SEND);
+ }
if (saveInDb) {
if (message.getEncryption() == Message.ENCRYPTION_NONE
|| saveEncryptedMessages()) {
databaseBackend.createMessage(message);
}
}
- conv.getMessages().add(message);
if ((send) && (packet != null)) {
- if (!account.getXmppConnection().getFeatures().sm()
- && conv.getMode() != Conversation.MODE_MULTI) {
- message.setStatus(Message.STATUS_SEND);
- }
sendMessagePacket(account, packet);
}
updateConversationUi();
@@ -819,15 +819,15 @@ public class XmppConnectionService extends Service {
}
});
}
-
- public List<Message> getMoreMessages(Conversation conversation,
- long timestamp) {
+
+ public int loadMoreMessages(Conversation conversation, long timestamp) {
List<Message> messages = databaseBackend.getMessages(conversation, 50,
timestamp);
for (Message message : messages) {
message.setConversation(conversation);
}
- return messages;
+ conversation.getMessages().addAll(0, messages);
+ return messages.size();
}
public List<Account> getAccounts() {
@@ -847,7 +847,7 @@ public class XmppConnectionService extends Service {
String jid) {
for (Conversation conversation : haystack) {
if ((conversation.getAccount().equals(account))
- && (conversation.getContactJid().split("/")[0].equals(jid))) {
+ && (conversation.getContactJid().split("/",2)[0].equals(jid))) {
return conversation;
}
}
@@ -1097,7 +1097,7 @@ public class XmppConnectionService extends Service {
}
private OnRenameListener renameListener = null;
- private IqGenerator mIqGenerator = new IqGenerator();
+ private IqGenerator mIqGenerator = new IqGenerator(this);
public void setOnRenameListener(OnRenameListener listener) {
this.renameListener = listener;
@@ -1566,6 +1566,10 @@ public class XmppConnectionService extends Service {
return !getPreferences().getBoolean("dont_save_encrypted", false);
}
+ public boolean indicateReceived() {
+ return getPreferences().getBoolean("indicate_received", false);
+ }
+
public void notifyUi(Conversation conversation, boolean notify) {
if (mOnConversationUpdate != null) {
mOnConversationUpdate.onConversationUpdate();
diff --git a/src/eu/siacs/conversations/ui/ChooseContactActivity.java b/src/eu/siacs/conversations/ui/ChooseContactActivity.java
index 277d21d6..62a2cbe1 100644
--- a/src/eu/siacs/conversations/ui/ChooseContactActivity.java
+++ b/src/eu/siacs/conversations/ui/ChooseContactActivity.java
@@ -82,6 +82,7 @@ public class ChooseContactActivity extends XmppActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_choose_contact);
mListView = (ListView) findViewById(R.id.choose_contact_list);
+ mListView.setFastScrollEnabled(true);
mContactsAdapter = new ListItemAdapter(this, contacts);
mListView.setAdapter(mContactsAdapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
diff --git a/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java
index 2cfa1635..76c12a47 100644
--- a/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java
+++ b/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java
@@ -201,7 +201,7 @@ public class ConferenceDetailsActivity extends XmppActivity {
private void populateView() {
mYourPhoto.setImageBitmap(conversation.getAccount().getImage(this, 48));
setTitle(conversation.getName());
- mFullJid.setText(conversation.getContactJid().split("/")[0]);
+ mFullJid.setText(conversation.getContactJid().split("/",2)[0]);
mYourNick.setText(conversation.getMucOptions().getActualNick());
mRoleAffiliaton = (TextView) findViewById(R.id.muc_role);
if (conversation.getMucOptions().online()) {
diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java
index 40ad0f33..03d034d9 100644
--- a/src/eu/siacs/conversations/ui/ConversationActivity.java
+++ b/src/eu/siacs/conversations/ui/ConversationActivity.java
@@ -16,7 +16,6 @@ import eu.siacs.conversations.utils.UIHelper;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
-import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.app.ActionBar;
import android.app.AlertDialog;
@@ -791,6 +790,10 @@ public class ConversationActivity extends XmppActivity implements
return getPreferences().getBoolean("send_button_status", false);
}
+ public boolean indicateReceived() {
+ return getPreferences().getBoolean("indicate_received", false);
+ }
+
@Override
public void onAccountUpdate() {
final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java
index e09958cb..299bf281 100644
--- a/src/eu/siacs/conversations/ui/ConversationFragment.java
+++ b/src/eu/siacs/conversations/ui/ConversationFragment.java
@@ -165,14 +165,15 @@ public class ConversationFragment extends Fragment {
if (firstVisibleItem == 0 && messagesLoaded) {
long timestamp = messageList.get(0).getTimeSent();
messagesLoaded = false;
- List<Message> messages = activity.xmppConnectionService
- .getMoreMessages(conversation, timestamp);
- messageList.addAll(0, messages);
+ int size = activity.xmppConnectionService.loadMoreMessages(
+ conversation, timestamp);
+ messageList.clear();
+ messageList.addAll(conversation.getMessages());
messageListAdapter.notifyDataSetChanged();
- if (messages.size() != 0) {
+ if (size != 0) {
messagesLoaded = true;
}
- messagesView.setSelectionFromTop(messages.size() + 1, 0);
+ messagesView.setSelectionFromTop(size + 1, 0);
}
}
};
@@ -274,11 +275,23 @@ public class ConversationFragment extends Fragment {
@Override
public void onContactPictureClicked(Message message) {
- if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
- if (message.getPresence() != null) {
- highlightInConference(message.getPresence());
+ if (message.getStatus() <= Message.STATUS_RECEIVED) {
+ if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
+ if (message.getPresence() != null) {
+ highlightInConference(message.getPresence());
+ } else {
+ highlightInConference(message
+ .getCounterpart());
+ }
} else {
- highlightInConference(message.getCounterpart());
+ Contact contact = message.getConversation()
+ .getContact();
+ if (contact.showInRoster()) {
+ activity.switchToContactDetails(contact);
+ } else {
+ activity.showAddToRosterDialog(message
+ .getConversation());
+ }
}
}
}
@@ -288,11 +301,13 @@ public class ConversationFragment extends Fragment {
@Override
public void onContactPictureLongClicked(Message message) {
- if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
- if (message.getPresence() != null) {
- privateMessageWith(message.getPresence());
- } else {
- privateMessageWith(message.getCounterpart());
+ if (message.getStatus() <= Message.STATUS_RECEIVED) {
+ if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
+ if (message.getPresence() != null) {
+ privateMessageWith(message.getPresence());
+ } else {
+ privateMessageWith(message.getCounterpart());
+ }
}
}
}
@@ -492,7 +507,7 @@ public class ConversationFragment extends Fragment {
private void messageSent() {
int size = this.messageList.size();
- if (size >= 1) {
+ if (size >= 1 && this.messagesView.getLastVisiblePosition() != size - 1) {
messagesView.setSelection(size - 1);
}
mEditMessage.setText("");
diff --git a/src/eu/siacs/conversations/ui/ManageAccountActivity.java b/src/eu/siacs/conversations/ui/ManageAccountActivity.java
index c57121da..ca17eb0d 100644
--- a/src/eu/siacs/conversations/ui/ManageAccountActivity.java
+++ b/src/eu/siacs/conversations/ui/ManageAccountActivity.java
@@ -62,7 +62,7 @@ public class ManageAccountActivity extends XmppActivity {
@Override
public void onItemClick(AdapterView<?> arg0, View view,
int position, long arg3) {
- editAccount(accountList.get(position));
+ switchToAccount(accountList.get(position));
}
});
registerForContextMenu(accountListView);
@@ -163,12 +163,6 @@ public class ManageAccountActivity extends XmppActivity {
}
}
- private void editAccount(Account account) {
- Intent intent = new Intent(this, EditAccountActivity.class);
- intent.putExtra("jid", account.getJid());
- startActivity(intent);
- }
-
private void publishAvatar(Account account) {
Intent intent = new Intent(getApplicationContext(),
PublishProfilePictureActivity.class);
diff --git a/src/eu/siacs/conversations/ui/SettingsActivity.java b/src/eu/siacs/conversations/ui/SettingsActivity.java
index 6b280719..fc361fb8 100644
--- a/src/eu/siacs/conversations/ui/SettingsActivity.java
+++ b/src/eu/siacs/conversations/ui/SettingsActivity.java
@@ -1,21 +1,27 @@
package eu.siacs.conversations.ui;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Locale;
-import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Build;
import android.os.Bundle;
+import android.preference.ListPreference;
import android.preference.PreferenceManager;
public class SettingsActivity extends XmppActivity implements
OnSharedPreferenceChangeListener {
+ private SettingsFragment mSettingsFragment;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ mSettingsFragment = new SettingsFragment();
getFragmentManager().beginTransaction()
- .replace(android.R.id.content, new SettingsFragment()).commit();
+ .replace(android.R.id.content,mSettingsFragment).commit();
}
@Override
@@ -28,6 +34,13 @@ public class SettingsActivity extends XmppActivity implements
super.onStart();
PreferenceManager.getDefaultSharedPreferences(this)
.registerOnSharedPreferenceChangeListener(this);
+ ListPreference resources = (ListPreference) mSettingsFragment.findPreference("resource");
+ if (resources!=null) {
+ ArrayList<CharSequence> entries = new ArrayList<CharSequence>(Arrays.asList(resources.getEntries()));
+ entries.add(0,Build.MODEL);
+ resources.setEntries(entries.toArray(new CharSequence[entries.size()]));
+ resources.setEntryValues(entries.toArray(new CharSequence[entries.size()]));
+ }
}
@Override
diff --git a/src/eu/siacs/conversations/ui/StartConversationActivity.java b/src/eu/siacs/conversations/ui/StartConversationActivity.java
index 6287070c..db6c1509 100644
--- a/src/eu/siacs/conversations/ui/StartConversationActivity.java
+++ b/src/eu/siacs/conversations/ui/StartConversationActivity.java
@@ -568,6 +568,7 @@ public class StartConversationActivity extends XmppActivity {
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
registerForContextMenu(getListView());
+ getListView().setFastScrollEnabled(true);
}
@Override
diff --git a/src/eu/siacs/conversations/ui/XmppActivity.java b/src/eu/siacs/conversations/ui/XmppActivity.java
index 4ee51580..351462ae 100644
--- a/src/eu/siacs/conversations/ui/XmppActivity.java
+++ b/src/eu/siacs/conversations/ui/XmppActivity.java
@@ -247,6 +247,12 @@ public abstract class XmppActivity extends Activity {
intent.putExtra("contact", contact.getJid());
startActivity(intent);
}
+
+ public void switchToAccount(Account account) {
+ Intent intent = new Intent(this, EditAccountActivity.class);
+ intent.putExtra("jid", account.getJid());
+ startActivity(intent);
+ }
protected void inviteToConversation(Conversation conversation) {
Intent intent = new Intent(getApplicationContext(),
diff --git a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java
index db01eabe..035d18c5 100644
--- a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java
+++ b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java
@@ -11,7 +11,6 @@ import eu.siacs.conversations.entities.Downloadable;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.ui.ConversationActivity;
import eu.siacs.conversations.utils.UIHelper;
-import eu.siacs.conversations.xmpp.jingle.JingleConnection;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
@@ -97,6 +96,9 @@ public class MessageAdapter extends ArrayAdapter<Message> {
String filesize = null;
String info = null;
boolean error = false;
+ if (viewHolder.indicatorReceived != null) {
+ viewHolder.indicatorReceived.setVisibility(View.GONE);
+ }
boolean multiReceived = message.getConversation().getMode() == Conversation.MODE_MULTI
&& message.getMergedStatus() <= Message.STATUS_RECEIVED;
if (message.getType() == Message.TYPE_IMAGE) {
@@ -118,6 +120,16 @@ public class MessageAdapter extends ArrayAdapter<Message> {
case Message.STATUS_OFFERED:
info = getContext().getString(R.string.offering);
break;
+ case Message.STATUS_SEND_RECEIVED:
+ if (activity.indicateReceived()) {
+ viewHolder.indicatorReceived.setVisibility(View.VISIBLE);
+ }
+ break;
+ case Message.STATUS_SEND_DISPLAYED:
+ if (activity.indicateReceived()) {
+ viewHolder.indicatorReceived.setVisibility(View.VISIBLE);
+ }
+ break;
case Message.STATUS_SEND_FAILED:
info = getContext().getString(R.string.send_failed);
error = true;
@@ -129,6 +141,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
case Message.STATUS_RECEPTION_FAILED:
info = getContext().getString(R.string.reception_failed);
error = true;
+ break;
default:
if (multiReceived) {
Contact contact = message.getContact();
@@ -155,7 +168,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
viewHolder.indicator.setVisibility(View.VISIBLE);
}
- String formatedTime = UIHelper.readableTimeDifference(getContext(),
+ String formatedTime = UIHelper.readableTimeDifferenceFull(getContext(),
message.getMergedTimeSent());
if (message.getStatus() <= Message.STATUS_RECEIVED) {
if ((filesize != null) && (info != null)) {
@@ -337,6 +350,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
.findViewById(R.id.message_body);
viewHolder.time = (TextView) view
.findViewById(R.id.message_time);
+ viewHolder.indicatorReceived = (ImageView) view
+ .findViewById(R.id.indicator_received);
view.setTag(viewHolder);
break;
case RECEIVED:
@@ -406,6 +421,36 @@ public class MessageAdapter extends ArrayAdapter<Message> {
return view;
}
+ if (viewHolder.contact_picture != null) {
+ viewHolder.contact_picture
+ .setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ if (MessageAdapter.this.mOnContactPictureClickedListener != null) {
+ MessageAdapter.this.mOnContactPictureClickedListener
+ .onContactPictureClicked(item);
+ ;
+ }
+
+ }
+ });
+ viewHolder.contact_picture
+ .setOnLongClickListener(new OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View v) {
+ if (MessageAdapter.this.mOnContactPictureLongClickedListener != null) {
+ MessageAdapter.this.mOnContactPictureLongClickedListener
+ .onContactPictureLongClicked(item);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ });
+ }
+
if (type == RECEIVED) {
if (item.getConversation().getMode() == Conversation.MODE_MULTI) {
Contact contact = item.getContact();
@@ -420,33 +465,6 @@ public class MessageAdapter extends ArrayAdapter<Message> {
viewHolder.contact_picture.setImageBitmap(mBitmapCache.get(
name, getContext()));
}
- viewHolder.contact_picture
- .setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- if (MessageAdapter.this.mOnContactPictureClickedListener != null) {
- MessageAdapter.this.mOnContactPictureClickedListener
- .onContactPictureClicked(item);
- ;
- }
-
- }
- });
- viewHolder.contact_picture
- .setOnLongClickListener(new OnLongClickListener() {
-
- @Override
- public boolean onLongClick(View v) {
- if (MessageAdapter.this.mOnContactPictureLongClickedListener != null) {
- MessageAdapter.this.mOnContactPictureLongClickedListener
- .onContactPictureLongClicked(item);
- return true;
- } else {
- return false;
- }
- }
- });
}
}
@@ -512,6 +530,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
protected Button download_button;
protected ImageView image;
protected ImageView indicator;
+ protected ImageView indicatorReceived;
protected TextView time;
protected TextView messageBody;
protected ImageView contact_picture;
diff --git a/src/eu/siacs/conversations/utils/UIHelper.java b/src/eu/siacs/conversations/utils/UIHelper.java
index 54c370ef..f6e66cdb 100644
--- a/src/eu/siacs/conversations/utils/UIHelper.java
+++ b/src/eu/siacs/conversations/utils/UIHelper.java
@@ -51,10 +51,21 @@ public class UIHelper {
private static final int BG_COLOR = 0xFF181818;
private static final int FG_COLOR = 0xFFFAFAFA;
private static final int TRANSPARENT = 0x00000000;
- private static final int DATE_NO_YEAR_FLAGS = DateUtils.FORMAT_SHOW_DATE
+ private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE
| DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL;
+ private static final int FULL_DATE_FLAGS = DateUtils.FORMAT_SHOW_TIME
+ | DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE;
public static String readableTimeDifference(Context context, long time) {
+ return readableTimeDifference(context, time, false);
+ }
+
+ public static String readableTimeDifferenceFull(Context context, long time) {
+ return readableTimeDifference(context, time, true);
+ }
+
+ private static String readableTimeDifference(Context context, long time,
+ boolean fullDate) {
if (time == 0) {
return context.getString(R.string.just_now);
}
@@ -67,12 +78,17 @@ public class UIHelper {
} else if (difference < 60 * 15) {
return context.getString(R.string.minutes_ago,
Math.round(difference / 60.0));
- } else if (today(date) || difference < 6 * 60 * 60) {
+ } else if (today(date)) {
java.text.DateFormat df = DateFormat.getTimeFormat(context);
return df.format(date);
} else {
- return DateUtils.formatDateTime(context, date.getTime(),
- DATE_NO_YEAR_FLAGS);
+ if (fullDate) {
+ return DateUtils.formatDateTime(context, date.getTime(),
+ FULL_DATE_FLAGS);
+ } else {
+ return DateUtils.formatDateTime(context, date.getTime(),
+ SHORT_DATE_FLAGS);
+ }
}
}
@@ -353,14 +369,15 @@ public class UIHelper {
Pattern highlight = generateNickHighlightPattern(nick);
Matcher m = highlight.matcher(currentCon.getLatestMessage()
.getBody());
- notify = m.find();
+ notify = m.find()
+ || (currentCon.getLatestMessage().getType() == Message.TYPE_PRIVATE);
}
List<Conversation> unread = new ArrayList<Conversation>();
for (Conversation conversation : conversations) {
if (conversation.getMode() == Conversation.MODE_MULTI) {
if ((!conversation.isRead())
- && ((wasHighlighted(conversation) || (alwaysNotify)))) {
+ && ((wasHighlightedOrPrivate(conversation) || (alwaysNotify)))) {
unread.add(conversation);
}
} else {
@@ -466,7 +483,7 @@ public class UIHelper {
}
}
- private static boolean wasHighlighted(Conversation conversation) {
+ private static boolean wasHighlightedOrPrivate(Conversation conversation) {
List<Message> messages = conversation.getMessages();
String nick = conversation.getMucOptions().getActualNick();
Pattern highlight = generateNickHighlightPattern(nick);
@@ -475,7 +492,8 @@ public class UIHelper {
break;
} else {
Matcher m = highlight.matcher(messages.get(i).getBody());
- if (m.find()) {
+ if (m.find()
+ || messages.get(i).getType() == Message.TYPE_PRIVATE) {
return true;
}
}
diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java
index e7b25e26..e02c772d 100644
--- a/src/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -657,7 +657,7 @@ public class XmppConnection implements Runnable {
if (bind != null) {
Element jid = bind.findChild("jid");
if (jid != null) {
- account.setResource(jid.getContent().split("/")[1]);
+ account.setResource(jid.getContent().split("/",2)[1]);
if (streamFeatures.hasChild("sm", "urn:xmpp:sm:3")) {
smVersion = 3;
EnablePacket enable = new EnablePacket(smVersion);
diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
index f42482e8..4eac99e6 100644
--- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
+++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
@@ -256,12 +256,12 @@ public class JingleConnection implements Downloadable {
this.status = STATUS_INITIATED;
Conversation conversation = this.mXmppConnectionService
.findOrCreateConversation(account,
- packet.getFrom().split("/")[0], false);
+ packet.getFrom().split("/",2)[0], false);
this.message = new Message(conversation, "", Message.ENCRYPTION_NONE);
this.message.setType(Message.TYPE_IMAGE);
this.message.setStatus(Message.STATUS_RECEIVED_OFFER);
this.message.setDownloadable(this);
- String[] fromParts = packet.getFrom().split("/");
+ String[] fromParts = packet.getFrom().split("/",2);
this.message.setPresence(fromParts[1]);
this.account = account;
this.initiator = packet.getFrom();