presences are now somewhat stored and displayed to the user via the contact details action.

This commit is contained in:
Daniel Gultsch 2014-02-09 00:47:11 +01:00
parent 95068ee776
commit c31101dd64
11 changed files with 429 additions and 117 deletions

View File

@ -41,24 +41,24 @@ public final class R {
public static final int section_header=0x7f02000c; public static final int section_header=0x7f02000c;
} }
public static final class id { public static final class id {
public static final int account_confirm_password_desc=0x7f0a0012; public static final int account_confirm_password_desc=0x7f0a0017;
public static final int account_delete=0x7f0a0026; public static final int account_delete=0x7f0a002b;
public static final int account_disable=0x7f0a0027; public static final int account_disable=0x7f0a002c;
public static final int account_enable=0x7f0a0028; public static final int account_enable=0x7f0a002d;
public static final int account_jid=0x7f0a0000; public static final int account_jid=0x7f0a0000;
public static final int account_list=0x7f0a001b; public static final int account_list=0x7f0a0020;
public static final int account_password=0x7f0a000f; public static final int account_password=0x7f0a0014;
public static final int account_password_confirm2=0x7f0a0013; public static final int account_password_confirm2=0x7f0a0018;
public static final int account_status=0x7f0a0002; public static final int account_status=0x7f0a0002;
public static final int account_usetls=0x7f0a0010; public static final int account_usetls=0x7f0a0015;
public static final int action_accounts=0x7f0a0023; public static final int action_accounts=0x7f0a0028;
public static final int action_add=0x7f0a001f; public static final int action_add=0x7f0a0024;
public static final int action_add_account=0x7f0a0025; public static final int action_add_account=0x7f0a002a;
public static final int action_archive=0x7f0a0022; public static final int action_archive=0x7f0a0027;
public static final int action_details=0x7f0a0021; public static final int action_details=0x7f0a0026;
public static final int action_refresh_contacts=0x7f0a0029; public static final int action_refresh_contacts=0x7f0a002e;
public static final int action_security=0x7f0a0020; public static final int action_security=0x7f0a0025;
public static final int action_settings=0x7f0a0024; public static final int action_settings=0x7f0a0029;
public static final int contactList=0x7f0a0006; public static final int contactList=0x7f0a0006;
public static final int contact_display_name=0x7f0a0008; public static final int contact_display_name=0x7f0a0008;
public static final int contact_jid=0x7f0a0009; public static final int contact_jid=0x7f0a0009;
@ -68,33 +68,39 @@ public final class R {
public static final int conversation_lastmsg=0x7f0a000c; public static final int conversation_lastmsg=0x7f0a000c;
public static final int conversation_lastupdate=0x7f0a000d; public static final int conversation_lastupdate=0x7f0a000d;
public static final int conversation_name=0x7f0a000b; public static final int conversation_name=0x7f0a000b;
public static final int edit_account_register_new=0x7f0a0011; public static final int details_account=0x7f0a0010;
public static final int list=0x7f0a0019; public static final int details_contact_jid=0x7f0a000e;
public static final int message_body=0x7f0a001d; public static final int details_contact_status=0x7f0a000f;
public static final int message_photo=0x7f0a001c; public static final int details_receive_presence=0x7f0a0012;
public static final int message_time=0x7f0a001e; public static final int details_send_presence=0x7f0a0011;
public static final int messages_view=0x7f0a0017; public static final int edit_account_register_new=0x7f0a0016;
public static final int list=0x7f0a001e;
public static final int message_body=0x7f0a0022;
public static final int message_photo=0x7f0a0021;
public static final int message_time=0x7f0a0023;
public static final int messages_view=0x7f0a001c;
public static final int new_conversation_search=0x7f0a0004; public static final int new_conversation_search=0x7f0a0004;
public static final int progressBar1=0x7f0a0003; public static final int progressBar1=0x7f0a0003;
public static final int selected_conversation=0x7f0a001a; public static final int selected_conversation=0x7f0a001f;
public static final int slidingpanelayout=0x7f0a0018; public static final int slidingpanelayout=0x7f0a001d;
public static final int textSendButton=0x7f0a0016; public static final int textSendButton=0x7f0a001b;
public static final int textView1=0x7f0a000e; public static final int textView1=0x7f0a0013;
public static final int textView2=0x7f0a0001; public static final int textView2=0x7f0a0001;
public static final int textinput=0x7f0a0015; public static final int textinput=0x7f0a001a;
public static final int textsend=0x7f0a0014; public static final int textsend=0x7f0a0019;
} }
public static final class layout { public static final class layout {
public static final int account_row=0x7f030000; public static final int account_row=0x7f030000;
public static final int activity_new_conversation=0x7f030001; public static final int activity_new_conversation=0x7f030001;
public static final int contact=0x7f030002; public static final int contact=0x7f030002;
public static final int conversation_list_row=0x7f030003; public static final int conversation_list_row=0x7f030003;
public static final int edit_account_dialog=0x7f030004; public static final int dialog_contact_details=0x7f030004;
public static final int fragment_conversation=0x7f030005; public static final int edit_account_dialog=0x7f030005;
public static final int fragment_conversations_overview=0x7f030006; public static final int fragment_conversation=0x7f030006;
public static final int manage_accounts=0x7f030007; public static final int fragment_conversations_overview=0x7f030007;
public static final int message_recieved=0x7f030008; public static final int manage_accounts=0x7f030008;
public static final int message_sent=0x7f030009; public static final int message_recieved=0x7f030009;
public static final int message_sent=0x7f03000a;
} }
public static final class menu { public static final class menu {
public static final int conversations=0x7f090000; public static final int conversations=0x7f090000;

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Jabber ID"
android:textColor="#636363"
android:textSize="20sp"/>
<TextView
android:id="@+id/details_contact_jid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="something@jabber.example.com"
android:paddingLeft="8dp"
android:textSize="14sp"/>
<TextView
android:paddingTop="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Status"
android:textColor="#636363"
android:textSize="20sp"/>
<TextView
android:paddingLeft="8dp"
android:id="@+id/details_contact_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="online"
android:textSize="14sp"/>
<TextView
android:paddingTop="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Your account"
android:textColor="#636363"
android:textSize="20sp"/>
<TextView
android:paddingLeft="8dp"
android:id="@+id/details_account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="julia@jabber.example.com" />
<TextView
android:paddingTop="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Subscription"
android:textColor="#636363"
android:textSize="20sp"/>
<CheckBox
android:id="@+id/details_send_presence"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send presence updates"
android:textSize="14sp"/>
<CheckBox
android:id="@+id/details_receive_presence"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Receive presence updates"
android:textSize="14sp"/>
</LinearLayout>

View File

@ -6,7 +6,7 @@
<string name="action_add">New conversation</string> <string name="action_add">New conversation</string>
<string name="action_accounts">Manage accounts</string> <string name="action_accounts">Manage accounts</string>
<string name="action_archive">Archive conversation</string> <string name="action_archive">Archive conversation</string>
<string name="action_details">Show details</string> <string name="action_details">Contact details</string>
<string name="action_secure">Secure conversation</string> <string name="action_secure">Secure conversation</string>
<string name="action_add_account">Add account</string> <string name="action_add_account">Add account</string>
<string name="title_activity_new_conversation">New Conversation</string> <string name="title_activity_new_conversation">New Conversation</string>

View File

@ -1,6 +1,7 @@
package de.gultsch.chat.entities; package de.gultsch.chat.entities;
import java.io.Serializable; import java.io.Serializable;
import java.util.Hashtable;
import android.content.ContentValues; import android.content.ContentValues;
import android.database.Cursor; import android.database.Cursor;
@ -16,7 +17,7 @@ public class Contact extends AbstractEntity implements Serializable {
public static final String SYSTEMACCOUNT = "systemaccount"; public static final String SYSTEMACCOUNT = "systemaccount";
public static final String PHOTOURI = "photouri"; public static final String PHOTOURI = "photouri";
public static final String OPENPGPKEY = "pgpkey"; public static final String OPENPGPKEY = "pgpkey";
public static final String LASTPRESENCE = "presence"; public static final String PRESENCES = "presences";
public static final String ACCOUNT = "accountUuid"; public static final String ACCOUNT = "accountUuid";
protected String accountUuid; protected String accountUuid;
@ -26,7 +27,7 @@ public class Contact extends AbstractEntity implements Serializable {
protected int systemAccount; protected int systemAccount;
protected String photoUri; protected String photoUri;
protected String openPGPKey; protected String openPGPKey;
protected long lastPresence; protected Presences presences = new Presences();
protected Account account; protected Account account;
@ -44,7 +45,7 @@ public class Contact extends AbstractEntity implements Serializable {
public Contact(String uuid, String account, String displayName, String jid, public Contact(String uuid, String account, String displayName, String jid,
String subscription, String photoUri, int systemAccount, String subscription, String photoUri, int systemAccount,
String pgpKey, long lastseen) { String pgpKey,String presences) {
this.uuid = uuid; this.uuid = uuid;
this.accountUuid = account; this.accountUuid = account;
this.displayName = displayName; this.displayName = displayName;
@ -53,7 +54,7 @@ public class Contact extends AbstractEntity implements Serializable {
this.photoUri = photoUri; this.photoUri = photoUri;
this.systemAccount = systemAccount; this.systemAccount = systemAccount;
this.openPGPKey = pgpKey; this.openPGPKey = pgpKey;
this.lastPresence = lastseen; this.presences = Presences.fromJsonString(presences);
} }
public String getDisplayName() { public String getDisplayName() {
@ -84,7 +85,7 @@ public class Contact extends AbstractEntity implements Serializable {
values.put(SYSTEMACCOUNT, systemAccount); values.put(SYSTEMACCOUNT, systemAccount);
values.put(PHOTOURI, photoUri); values.put(PHOTOURI, photoUri);
values.put(OPENPGPKEY, openPGPKey); values.put(OPENPGPKEY, openPGPKey);
values.put(LASTPRESENCE, lastPresence); values.put(PRESENCES, presences.toJsonString());
return values; return values;
} }
@ -97,12 +98,16 @@ public class Contact extends AbstractEntity implements Serializable {
cursor.getString(cursor.getColumnIndex(PHOTOURI)), cursor.getString(cursor.getColumnIndex(PHOTOURI)),
cursor.getInt(cursor.getColumnIndex(SYSTEMACCOUNT)), cursor.getInt(cursor.getColumnIndex(SYSTEMACCOUNT)),
cursor.getString(cursor.getColumnIndex(OPENPGPKEY)), cursor.getString(cursor.getColumnIndex(OPENPGPKEY)),
cursor.getLong(cursor.getColumnIndex(LASTPRESENCE))); cursor.getString(cursor.getColumnIndex(PRESENCES)));
} }
public void setSubscription(String subscription) { public void setSubscription(String subscription) {
this.subscription = subscription; this.subscription = subscription;
} }
public String getSubscription() {
return this.subscription;
}
public void setSystemAccount(int account) { public void setSystemAccount(int account) {
this.systemAccount = account; this.systemAccount = account;
@ -136,4 +141,20 @@ public class Contact extends AbstractEntity implements Serializable {
} }
} }
} }
public Hashtable<String, Integer> getPresences() {
return this.presences.getPresences();
}
public void updatePresence(String resource, int status) {
this.presences.updatePresence(resource, status);
}
public void removePresence(String resource) {
this.presences.removePresence(resource);
}
public int getMostAvailableStatus() {
return this.presences.getMostAvailableStatus();
}
} }

View File

@ -0,0 +1,76 @@
package de.gultsch.chat.entities;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map.Entry;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class Presences {
public static final int CHAT = -1;
public static final int ONLINE = 0;
public static final int AWAY = 1;
public static final int XA = 2;
public static final int DND = 3;
public static final int OFFLINE = 4;
private Hashtable<String, Integer> presences = new Hashtable<String, Integer>();
public Hashtable<String, Integer> getPresences() {
return this.presences;
}
public void updatePresence(String resource, int status) {
this.presences.put(resource, status);
}
public void removePresence(String resource) {
this.presences.remove(resource);
}
public int getMostAvailableStatus() {
int status = OFFLINE;
Iterator<Entry<String, Integer>> it = presences.entrySet().iterator();
while (it.hasNext()) {
Entry<String, Integer> entry = it.next();
if (entry.getValue()<status) status = entry.getValue();
}
return status;
}
public String toJsonString() {
JSONArray json = new JSONArray();
Iterator<Entry<String, Integer>> it = presences.entrySet().iterator();
while (it.hasNext()) {
Entry<String, Integer> entry = it.next();
JSONObject jObj = new JSONObject();
try {
jObj.put("resource", entry.getKey());
jObj.put("status", entry.getValue());
} catch (JSONException e) {
}
json.put(jObj);
}
return json.toString();
}
public static Presences fromJsonString(String jsonString) {
Presences presences = new Presences();
try {
JSONArray json = new JSONArray(jsonString);
for (int i = 0; i < json.length(); ++i) {
JSONObject jObj = json.getJSONObject(i);
presences.updatePresence(jObj.getString("resource"),
jObj.getInt("status"));
}
} catch (JSONException e1) {
}
return presences;
}
}

View File

@ -8,10 +8,12 @@ import de.gultsch.chat.entities.Account;
import de.gultsch.chat.entities.Contact; import de.gultsch.chat.entities.Contact;
import de.gultsch.chat.entities.Conversation; import de.gultsch.chat.entities.Conversation;
import de.gultsch.chat.entities.Message; import de.gultsch.chat.entities.Message;
import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.util.Log; import android.util.Log;
public class DatabaseBackend extends SQLiteOpenHelper { public class DatabaseBackend extends SQLiteOpenHelper {
@ -53,7 +55,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
db.execSQL("create table " + Contact.TABLENAME + "(" + Contact.UUID db.execSQL("create table " + Contact.TABLENAME + "(" + Contact.UUID
+ " TEXT PRIMARY KEY, " + Contact.ACCOUNT + " TEXT, " + " TEXT PRIMARY KEY, " + Contact.ACCOUNT + " TEXT, "
+ Contact.DISPLAYNAME + " TEXT," + Contact.JID + " TEXT," + Contact.DISPLAYNAME + " TEXT," + Contact.JID + " TEXT,"
+ Contact.LASTPRESENCE + " NUMBER, " + Contact.OPENPGPKEY + Contact.PRESENCES + " TEXT, " + Contact.OPENPGPKEY
+ " TEXT," + Contact.PHOTOURI + " TEXT," + Contact.SUBSCRIPTION + " TEXT," + Contact.PHOTOURI + " TEXT," + Contact.SUBSCRIPTION
+ " TEXT," + Contact.SYSTEMACCOUNT + " NUMBER, " + " TEXT," + Contact.SYSTEMACCOUNT + " NUMBER, "
+ "FOREIGN KEY(" + Contact.ACCOUNT + ") REFERENCES " + "FOREIGN KEY(" + Contact.ACCOUNT + ") REFERENCES "
@ -199,6 +201,15 @@ public class DatabaseBackend extends SQLiteOpenHelper {
+ "=?", args); + "=?", args);
} }
public void clearPresences(Account account) {
SQLiteDatabase db = this.getWritableDatabase();
String[] args = { account.getUuid() };
ContentValues values = new ContentValues();
values.put(Contact.PRESENCES,"[]");
db.update(Contact.TABLENAME, values, Contact.ACCOUNT
+ "=?", args);
}
public void mergeContacts(List<Contact> contacts) { public void mergeContacts(List<Contact> contacts) {
SQLiteDatabase db = this.getWritableDatabase(); SQLiteDatabase db = this.getWritableDatabase();
for (int i = 0; i < contacts.size(); i++) { for (int i = 0; i < contacts.size(); i++) {

View File

@ -8,6 +8,7 @@ import de.gultsch.chat.entities.Account;
import de.gultsch.chat.entities.Contact; import de.gultsch.chat.entities.Contact;
import de.gultsch.chat.entities.Conversation; import de.gultsch.chat.entities.Conversation;
import de.gultsch.chat.entities.Message; import de.gultsch.chat.entities.Message;
import de.gultsch.chat.entities.Presences;
import de.gultsch.chat.persistance.DatabaseBackend; import de.gultsch.chat.persistance.DatabaseBackend;
import de.gultsch.chat.ui.OnAccountListChangedListener; import de.gultsch.chat.ui.OnAccountListChangedListener;
import de.gultsch.chat.ui.OnConversationListChangedListener; import de.gultsch.chat.ui.OnConversationListChangedListener;
@ -58,56 +59,46 @@ public class XmppConnectionService extends Service {
@Override @Override
public void onMessagePacketReceived(Account account, public void onMessagePacketReceived(Account account,
MessagePacket packet) { MessagePacket packet) {
Conversation conversation = null; if ((packet.getType() == MessagePacket.TYPE_CHAT)
String fullJid = packet.getFrom(); || (packet.getType() == MessagePacket.TYPE_GROUPCHAT)) {
String counterPart = null; boolean notify = true;
if (packet.getType() == MessagePacket.TYPE_CHAT) { if (!packet.hasChild("body")) {
String jid = fullJid.split("/")[0]; return;
counterPart = fullJid; }
Contact contact = findOrCreateContact(account,jid); Conversation conversation = null;
conversation = findOrCreateConversation(account, contact,false); String fullJid = packet.getFrom();
} else if (packet.getType() == MessagePacket.TYPE_GROUPCHAT) {
String[] fromParts = fullJid.split("/"); String[] fromParts = fullJid.split("/");
if (fromParts.length != 2) { String jid = fromParts[0];
return; Contact contact = findOrCreateContact(account, jid);
} boolean muc = (packet.getType() == MessagePacket.TYPE_GROUPCHAT);
if (packet.hasChild("subject")) { String counterPart = null;
return; int status = Message.STATUS_RECIEVED;
} conversation = findOrCreateConversation(account, contact, muc);
if (packet.hasChild("delay")) { if (muc) {
return; if ((fromParts.length==1)||(packet.hasChild("subject"))||(packet.hasChild("delay"))) {
} return;
String muc = fromParts[0];
counterPart = fromParts[1];
if (counterPart.equals(account.getUsername())) {
return;
}
for (int i = 0; i < conversations.size(); ++i) {
if (conversations.get(i).getContactJid().equals(muc)) {
conversation = conversations.get(i);
break;
} }
counterPart = fromParts[1];
if (counterPart.equals(account.getUsername())) {
status = Message.STATUS_SEND;
notify = false;
}
} else {
counterPart = fullJid;
} }
if (conversation == null) {
Log.d(LOGTAG, "couldnt find muc");
}
}
if (conversation != null) {
Log.d(LOGTAG, packet.toString());
Message message = new Message(conversation, counterPart, Message message = new Message(conversation, counterPart,
packet.getBody(), Message.ENCRYPTION_NONE, packet.getBody(), Message.ENCRYPTION_NONE, status);
Message.STATUS_RECIEVED);
conversation.getMessages().add(message); conversation.getMessages().add(message);
databaseBackend.createMessage(message); databaseBackend.createMessage(message);
if (convChangedListener != null) { if (convChangedListener != null) {
convChangedListener.onConversationListChanged(); convChangedListener.onConversationListChanged();
} else { } else {
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); if (notify) {
mNotificationManager.notify(2342, UIHelper NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
.getUnreadMessageNotification( mNotificationManager.notify(2342, UIHelper
getApplicationContext(), conversation)); .getUnreadMessageNotification(
getApplicationContext(), conversation));
}
} }
} }
} }
@ -120,19 +111,45 @@ public class XmppConnectionService extends Service {
accountChangedListener.onAccountListChangedListener(); accountChangedListener.onAccountListChangedListener();
} }
if (account.getStatus() == Account.STATUS_ONLINE) { if (account.getStatus() == Account.STATUS_ONLINE) {
databaseBackend.clearPresences(account);
connectMultiModeConversations(account); connectMultiModeConversations(account);
} }
} }
}; };
private OnPresencePacketReceived presenceListener = new OnPresencePacketReceived() { private OnPresencePacketReceived presenceListener = new OnPresencePacketReceived() {
@Override @Override
public void onPresencePacketReceived(Account account, PresencePacket packet) { public void onPresencePacketReceived(Account account,
String jid = packet.getAttribute("from"); PresencePacket packet) {
String[] fromParts = packet.getAttribute("from").split("/");
Contact contact = findOrCreateContact(account, fromParts[0]);
if (contact.getUuid()==null) {
//most likely muc, self or roster not synced
Log.d(LOGTAG,"got presence for non contact "+packet.toString());
}
String type = packet.getAttribute("type"); String type = packet.getAttribute("type");
if (type==null) { if (type == null) {
//Log.d(LOGTAG,"online presence from "+jid); Element show = packet.findChild("show");
if (show==null) {
contact.updatePresence(fromParts[1],Presences.ONLINE);
} else if (show.getContent().equals("away")) {
contact.updatePresence(fromParts[1],Presences.AWAY);
} else if (show.getContent().equals("xa")) {
contact.updatePresence(fromParts[1],Presences.XA);
} else if (show.getContent().equals("chat")) {
contact.updatePresence(fromParts[1],Presences.CHAT);
} else if (show.getContent().equals("dnd")) {
contact.updatePresence(fromParts[1],Presences.DND);
}
databaseBackend.updateContact(contact);
} else if (type.equals("unavailable")) {
if (fromParts.length!=2) {
Log.d(LOGTAG,"received presence with no resource "+packet.toString());
} else {
contact.removePresence(fromParts[1]);
databaseBackend.updateContact(contact);
}
} }
} }
}; };
@ -176,11 +193,6 @@ public class XmppConnectionService extends Service {
return connection; return connection;
} }
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public void sendMessage(final Account account, final Message message) { public void sendMessage(final Account account, final Message message) {
Log.d(LOGTAG, "sending message for " + account.getJid() + " to: " Log.d(LOGTAG, "sending message for " + account.getJid() + " to: "
+ message.getCounterpart()); + message.getCounterpart());
@ -194,14 +206,17 @@ public class XmppConnectionService extends Service {
packet.setTo(message.getCounterpart()); packet.setTo(message.getCounterpart());
packet.setFrom(account.getJid()); packet.setFrom(account.getJid());
packet.setBody(message.getBody()); packet.setBody(message.getBody());
connections.get(account).sendMessagePacket(packet); if (account.getStatus()==Account.STATUS_ONLINE) {
message.setStatus(Message.STATUS_SEND); connections.get(account).sendMessagePacket(packet);
databaseBackend.updateMessage(message); message.setStatus(Message.STATUS_SEND);
databaseBackend.updateMessage(message);
}
} }
public void getRoster(Account account, final OnRosterFetchedListener listener) { public void getRoster(Account account,
final OnRosterFetchedListener listener) {
List<Contact> contacts = databaseBackend.getContacts(account); List<Contact> contacts = databaseBackend.getContacts(account);
for(int i=0; i < contacts.size(); ++i) { for (int i = 0; i < contacts.size(); ++i) {
contacts.get(i).setAccount(account); contacts.get(i).setAccount(account);
} }
if (listener != null) { if (listener != null) {
@ -278,7 +293,8 @@ public class XmppConnectionService extends Service {
jid, jid,
phoneContact phoneContact
.getString("photouri")); .getString("photouri"));
contact.setSystemAccount(phoneContact.getInt("phoneid")); contact.setSystemAccount(phoneContact
.getInt("phoneid"));
} else { } else {
if (name == null) { if (name == null) {
name = jid.split("@")[0]; name = jid.split("@")[0];
@ -331,18 +347,19 @@ public class XmppConnectionService extends Service {
public List<Message> getMessages(Conversation conversation) { public List<Message> getMessages(Conversation conversation) {
return databaseBackend.getMessages(conversation, 100); return databaseBackend.getMessages(conversation, 100);
} }
public Contact findOrCreateContact(Account account, String jid) { public Contact findOrCreateContact(Account account, String jid) {
Contact contact = databaseBackend.findContact(account,jid); Contact contact = databaseBackend.findContact(account, jid);
if (contact!=null) { if (contact != null) {
contact.setAccount(account);
return contact; return contact;
} else { } else {
return new Contact(account,jid.split("@")[0], jid, null); return new Contact(account, jid.split("@")[0], jid, null);
} }
} }
public Conversation findOrCreateConversation(Account account, public Conversation findOrCreateConversation(Account account,
Contact contact,boolean muc) { Contact contact, boolean muc) {
for (Conversation conv : this.getConversations()) { for (Conversation conv : this.getConversations()) {
if ((conv.getAccount().equals(account)) if ((conv.getAccount().equals(account))
&& (conv.getContactJid().equals(contact.getJid()))) { && (conv.getContactJid().equals(contact.getJid()))) {
@ -356,7 +373,7 @@ public class XmppConnectionService extends Service {
conversation.setAccount(account); conversation.setAccount(account);
if (muc) { if (muc) {
conversation.setMode(Conversation.MODE_MULTI); conversation.setMode(Conversation.MODE_MULTI);
if (account.getStatus()==Account.STATUS_ONLINE) { if (account.getStatus() == Account.STATUS_ONLINE) {
joinMuc(account, conversation); joinMuc(account, conversation);
} }
} else { } else {
@ -368,7 +385,7 @@ public class XmppConnectionService extends Service {
conversation = new Conversation(contact.getDisplayName(), conversation = new Conversation(contact.getDisplayName(),
contact.getProfilePhoto(), account, contact.getJid(), contact.getProfilePhoto(), account, contact.getJid(),
Conversation.MODE_MULTI); Conversation.MODE_MULTI);
if (account.getStatus()==Account.STATUS_ONLINE) { if (account.getStatus() == Account.STATUS_ONLINE) {
joinMuc(account, conversation); joinMuc(account, conversation);
} }
} else { } else {
@ -463,7 +480,7 @@ public class XmppConnectionService extends Service {
} }
} }
} }
public void joinMuc(Account account, Conversation conversation) { public void joinMuc(Account account, Conversation conversation) {
String muc = conversation.getContactJid(); String muc = conversation.getContactJid();
PresencePacket packet = new PresencePacket(); PresencePacket packet = new PresencePacket();
@ -471,11 +488,15 @@ public class XmppConnectionService extends Service {
Element x = new Element("x"); Element x = new Element("x");
x.setAttribute("xmlns", "http://jabber.org/protocol/muc"); x.setAttribute("xmlns", "http://jabber.org/protocol/muc");
packet.addChild(x); packet.addChild(x);
connections.get(conversation.getAccount()).sendPresencePacket( connections.get(conversation.getAccount()).sendPresencePacket(packet);
packet);
} }
public void disconnectMultiModeConversations() { public void disconnectMultiModeConversations() {
} }
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}

View File

@ -7,6 +7,7 @@ import java.util.List;
import de.gultsch.chat.R; import de.gultsch.chat.R;
import de.gultsch.chat.R.id; import de.gultsch.chat.R.id;
import de.gultsch.chat.entities.Contact;
import de.gultsch.chat.entities.Conversation; import de.gultsch.chat.entities.Conversation;
import de.gultsch.chat.utils.UIHelper; import de.gultsch.chat.utils.UIHelper;
import android.net.Uri; import android.net.Uri;
@ -257,6 +258,12 @@ public class ConversationActivity extends XmppActivity {
xmppConnectionService.archiveConversation(conv); xmppConnectionService.archiveConversation(conv);
selectedConversation = conversationList.get(0); selectedConversation = conversationList.get(0);
break; break;
case R.id.action_details:
DialogContactDetails details = new DialogContactDetails();
Contact contact = xmppConnectionService.findOrCreateContact(this.getSelectedConversation().getAccount(),this.getSelectedConversation().getContactJid());
details.setContact(contact);
details.show(getFragmentManager(), "details");
break;
default: default:
break; break;
} }

View File

@ -59,7 +59,9 @@ public class ConversationFragment extends Fragment {
conversation.getMessages().add(message); conversation.getMessages().add(message);
chatMsg.setText(""); chatMsg.setText("");
messageList.add(message); if (conversation.getMode()==Conversation.MODE_SINGLE) {
messageList.add(message);
}
activity.updateConversationList(); activity.updateConversationList();
@ -155,9 +157,6 @@ public class ConversationFragment extends Fragment {
@Override @Override
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
Log.d("gultsch","conversationfragment onStart");
final ConversationActivity activity = (ConversationActivity) getActivity(); final ConversationActivity activity = (ConversationActivity) getActivity();
if (activity.xmppConnectionServiceBound) { if (activity.xmppConnectionServiceBound) {
@ -174,7 +173,6 @@ public class ConversationFragment extends Fragment {
} }
public void onBackendConnected() { public void onBackendConnected() {
Log.d("gultsch","calling on backend connected in conversation fragment");
final ConversationActivity activity = (ConversationActivity) getActivity(); final ConversationActivity activity = (ConversationActivity) getActivity();
this.conversation = activity.getSelectedConversation(); this.conversation = activity.getSelectedConversation();
updateMessages(); updateMessages();

View File

@ -0,0 +1,82 @@
package de.gultsch.chat.ui;
import de.gultsch.chat.R;
import de.gultsch.chat.entities.Contact;
import de.gultsch.chat.entities.Presences;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
public class DialogContactDetails extends DialogFragment {
private Contact contact = null;
boolean displayingInRoster = false;
public void setContact(Contact contact) {
this.contact = contact;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_contact_details, null);
TextView contactJid = (TextView) view.findViewById(R.id.details_contact_jid);
TextView accountJid = (TextView) view.findViewById(R.id.details_account);
TextView status = (TextView) view.findViewById(R.id.details_contact_status);
CheckBox send = (CheckBox) view.findViewById(R.id.details_send_presence);
CheckBox receive = (CheckBox) view.findViewById(R.id.details_receive_presence);
boolean subscriptionSend = false;
boolean subscriptionReceive = false;
if (contact.getSubscription().equals("both")) {
subscriptionReceive = true;
subscriptionSend = true;
} else if (contact.getSubscription().equals("from")) {
subscriptionSend = true;
} else if (contact.getSubscription().equals("to")) {
subscriptionReceive = true;
}
switch (contact.getMostAvailableStatus()) {
case Presences.CHAT:
status.setText("free to chat");
break;
case Presences.ONLINE:
status.setText("online");
break;
case Presences.AWAY:
status.setText("away");
break;
case Presences.XA:
status.setText("extended away");
break;
case Presences.DND:
status.setText("do not disturb");
break;
case Presences.OFFLINE:
status.setText("offline");
break;
default:
status.setText("offline");
break;
}
send.setChecked(subscriptionSend);
receive.setChecked(subscriptionReceive);
contactJid.setText(contact.getJid());
accountJid.setText(contact.getAccount().getJid());
builder.setView(view);
builder.setTitle(contact.getDisplayName());
builder.setNeutralButton("Done", null);
builder.setPositiveButton("Remove from roster", null);
return builder.create();
}
}

View File

@ -24,6 +24,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ListView; import android.widget.ListView;
@ -185,6 +186,18 @@ public class NewConversationActivity extends XmppActivity {
} }
} }
}); });
contactsView.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int pos, long arg3) {
Contact clickedContact = aggregatedContacts.get(pos);
DialogContactDetails dialog = new DialogContactDetails();
dialog.setContact(clickedContact);
dialog.show(getFragmentManager(), "details");
return true;
}
});
} }
public void showIsMucDialogIfNeeded(final Contact clickedContact) { public void showIsMucDialogIfNeeded(final Contact clickedContact) {