diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index be7addb51..e0ebee7f3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -9,6 +9,7 @@
android:targetSdkVersion="19" />
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/conversation_list_row.xml b/res/layout/conversation_list_row.xml
index cfac71755..303fdd1d2 100644
--- a/res/layout/conversation_list_row.xml
+++ b/res/layout/conversation_list_row.xml
@@ -38,7 +38,7 @@
android:paddingTop="3dp"/>
-
+ android:background="#e5e5e5" >
+
-
-
-
-
+
+
+
-
-
+ android:background="#e5e5e5"
+ tools:listitem="@layout/message_sent"
+ android:divider="@null"
+ android:dividerHeight="0dp">
+
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/res/layout/message_sent.xml b/res/layout/message_sent.xml
new file mode 100644
index 000000000..c690c2173
--- /dev/null
+++ b/res/layout/message_sent.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d6849e022..d48f23cd7 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9,4 +9,6 @@
Show details
Secure conversation
New Conversation
+ just now
+ sending…
diff --git a/src/de/gultsch/chat/entities/Conversation.java b/src/de/gultsch/chat/entities/Conversation.java
index 2dd8a0495..413e3d626 100644
--- a/src/de/gultsch/chat/entities/Conversation.java
+++ b/src/de/gultsch/chat/entities/Conversation.java
@@ -1,5 +1,6 @@
package de.gultsch.chat.entities;
+import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
@@ -9,6 +10,9 @@ import android.net.Uri;
public class Conversation extends AbstractEntity {
private static final long serialVersionUID = -6727528868973996739L;
+
+ public static final String TABLENAME = "conversations";
+
public static final int STATUS_AVAILABLE = 0;
public static final int STATUS_ARCHIVED = 1;
public static final int STATUS_DELETED = 2;
@@ -27,7 +31,7 @@ public class Conversation extends AbstractEntity {
private int status;
private long created;
- private transient List messages;
+ private transient List messages = null;
public Conversation(String name, Uri profilePhoto, Account account,
String contactJid) {
@@ -48,6 +52,7 @@ public class Conversation extends AbstractEntity {
}
public List getMessages() {
+ if (messages == null) this.messages = new ArrayList(); //prevent null pointer
return messages;
}
@@ -81,6 +86,10 @@ public class Conversation extends AbstractEntity {
public int getStatus() {
return this.status;
}
+
+ public long getCreated() {
+ return this.created;
+ }
public ContentValues getContentValues() {
ContentValues values = new ContentValues();
diff --git a/src/de/gultsch/chat/entities/Message.java b/src/de/gultsch/chat/entities/Message.java
index 5e5cfbe40..26e646ff4 100644
--- a/src/de/gultsch/chat/entities/Message.java
+++ b/src/de/gultsch/chat/entities/Message.java
@@ -6,6 +6,8 @@ import android.database.Cursor;
public class Message extends AbstractEntity {
private static final long serialVersionUID = 7222081895167103025L;
+
+ public static final String TABLENAME = "messages";
public static final int STATUS_RECIEVED = 0;
public static final int STATUS_UNSEND = 1;
diff --git a/src/de/gultsch/chat/persistance/DatabaseBackend.java b/src/de/gultsch/chat/persistance/DatabaseBackend.java
index dac83f586..06b9af16f 100644
--- a/src/de/gultsch/chat/persistance/DatabaseBackend.java
+++ b/src/de/gultsch/chat/persistance/DatabaseBackend.java
@@ -4,15 +4,16 @@ import java.util.ArrayList;
import java.util.List;
import de.gultsch.chat.entities.Conversation;
+import de.gultsch.chat.entities.Message;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseBackend extends SQLiteOpenHelper {
-
+
private static DatabaseBackend instance = null;
-
+
private static final String DATABASE_NAME = "history";
private static final int DATABASE_VERSION = 1;
@@ -22,7 +23,13 @@ public class DatabaseBackend extends SQLiteOpenHelper {
@Override
public void onCreate(SQLiteDatabase db) {
- db.execSQL("create table conversations (uuid TEXT, name TEXT, profilePhotoUri TEXT, accountUuid TEXT, contactJid TEXT, created NUMBER, status NUMBER)");
+ db.execSQL("create table " + Conversation.TABLENAME + " ("
+ + Conversation.UUID + " TEXT, " + Conversation.NAME + " TEXT, "
+ + Conversation.PHOTO_URI + " TEXT, " + Conversation.ACCOUNT
+ + " TEXT, " + Conversation.CONTACT + " TEXT, "
+ + Conversation.CREATED + " NUMBER, " + Conversation.STATUS
+ + " NUMBER)");
+ db.execSQL("create table "+Message.TABLENAME+ "()");
}
@Override
@@ -30,23 +37,23 @@ public class DatabaseBackend extends SQLiteOpenHelper {
// TODO Auto-generated method stub
}
-
+
public static synchronized DatabaseBackend getInstance(Context context) {
if (instance == null) {
instance = new DatabaseBackend(context);
}
return instance;
}
-
+
public void addConversation(Conversation conversation) {
SQLiteDatabase db = this.getWritableDatabase();
db.insert("conversations", null, conversation.getContentValues());
}
-
-
+
public int getConversationCount() {
SQLiteDatabase db = this.getReadableDatabase();
- Cursor cursor = db.rawQuery("select count(uuid) as count from conversations",null);
+ Cursor cursor = db.rawQuery(
+ "select count(uuid) as count from conversations", null);
cursor.moveToFirst();
return cursor.getInt(0);
}
@@ -54,9 +61,12 @@ public class DatabaseBackend extends SQLiteOpenHelper {
public List getConversations(int status) {
List list = new ArrayList();
SQLiteDatabase db = this.getReadableDatabase();
- String[] selectionArgs = {""+status};
- Cursor cursor = db.rawQuery("select * from conversations where status = ? order by created desc", selectionArgs);
- while(cursor.moveToNext()) {
+ String[] selectionArgs = { "" + status };
+ Cursor cursor = db
+ .rawQuery(
+ "select * from conversations where status = ? order by created desc",
+ selectionArgs);
+ while (cursor.moveToNext()) {
list.add(Conversation.fromCursor(cursor));
}
return list;
diff --git a/src/de/gultsch/chat/ui/ConversationActivity.java b/src/de/gultsch/chat/ui/ConversationActivity.java
index 97b937c35..4f76e9c12 100644
--- a/src/de/gultsch/chat/ui/ConversationActivity.java
+++ b/src/de/gultsch/chat/ui/ConversationActivity.java
@@ -9,6 +9,7 @@ import de.gultsch.chat.entities.Account;
import de.gultsch.chat.entities.Contact;
import de.gultsch.chat.entities.Conversation;
import de.gultsch.chat.persistance.DatabaseBackend;
+import de.gultsch.chat.utils.Beautifier;
import android.os.Bundle;
import android.app.FragmentTransaction;
import android.content.Context;
@@ -60,6 +61,8 @@ public class ConversationActivity extends XmppActivity {
}
((TextView) view.findViewById(R.id.conversation_name))
.setText(getItem(position).getName());
+ ((TextView) view.findViewById(R.id.conversation_lastupdate))
+ .setText(Beautifier.readableTimeDifference(getItem(position).getCreated()));
((ImageView) view.findViewById(R.id.conversation_image))
.setImageURI(getItem(position).getProfilePhotoUri());
return view;
diff --git a/src/de/gultsch/chat/ui/ConversationFragment.java b/src/de/gultsch/chat/ui/ConversationFragment.java
index 70ceb07c8..fca5202a7 100644
--- a/src/de/gultsch/chat/ui/ConversationFragment.java
+++ b/src/de/gultsch/chat/ui/ConversationFragment.java
@@ -2,24 +2,108 @@ package de.gultsch.chat.ui;
import de.gultsch.chat.R;
import de.gultsch.chat.entities.Conversation;
+import de.gultsch.chat.entities.Message;
+import de.gultsch.chat.utils.Beautifier;
import android.app.Fragment;
+import android.content.Context;
+import android.database.Cursor;
+import android.graphics.Typeface;
+import android.net.Uri;
import android.os.Bundle;
+import android.provider.ContactsContract.Profile;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.TextView;
public class ConversationFragment extends Fragment {
-
+
Conversation conversation;
-
+
public void setConversation(Conversation conv) {
this.conversation = conv;
}
-
+
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_conversation, container, false);
- }
+ public View onCreateView(final LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ String[] mProjection = new String[]
+ {
+ Profile._ID,
+ Profile.PHOTO_THUMBNAIL_URI
+ };
+ Cursor mProfileCursor = getActivity().getContentResolver().query(
+ Profile.CONTENT_URI,
+ mProjection ,
+ null,
+ null,
+ null);
+
+ mProfileCursor.moveToFirst();
+ final Uri profilePicture = Uri.parse(mProfileCursor.getString(1));
+
+ Log.d("gultsch","found user profile pic "+profilePicture.toString());
+
+ final View view = inflater.inflate(R.layout.fragment_conversation, container,
+ false);
+ ((ImageButton) view.findViewById(R.id.textSendButton))
+ .setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ EditText chatMsg = (EditText) view.findViewById(R.id.textinput);
+ if (chatMsg.getText().length() < 1) return;
+ Message message = new Message(conversation,chatMsg.getText().toString(),
+ Message.ENCRYPTION_NONE);
+ XmppActivity activity = (XmppActivity) getActivity();
+ activity.xmppConnectionService.sendMessage(message);
+ conversation.getMessages().add(message);
+ chatMsg.setText("");
+
+ ListView messagesView = (ListView) view.findViewById(R.id.messages_view);
+ ArrayAdapter adapter = (ArrayAdapter) messagesView.getAdapter();
+ adapter.notifyDataSetChanged();
+
+ messagesView.setSelection(conversation.getMessages().size() -1);
+ }
+ });
+
+ ListView messagesView = (ListView) view
+ .findViewById(R.id.messages_view);
+ messagesView.setAdapter(new ArrayAdapter(this.getActivity()
+ .getApplicationContext(), R.layout.message_sent,
+ this.conversation.getMessages()) {
+
+ @Override
+ public View getView(int position, View view, ViewGroup parent) {
+ Message item = getItem(position);
+ if ((item.getStatus() != Message.STATUS_RECIEVED)
+ || (item.getStatus() == Message.STATUS_SEND)) {
+ view = (View) inflater.inflate(R.layout.message_sent, null);
+ ((ImageView) view.findViewById(R.id.message_photo)).setImageURI(profilePicture);
+ }
+ ((TextView) view.findViewById(R.id.message_body)).setText(item.getBody());
+ TextView time = (TextView) view.findViewById(R.id.message_time);
+ if (item.getStatus() == Message.STATUS_UNSEND) {
+ time.setTypeface(null, Typeface.ITALIC);
+ } else {
+ time.setText(Beautifier.readableTimeDifference(item.getTimeSent()));
+ }
+ return view;
+ }
+ });
+
+ return view;
+ }
public Conversation getConversation() {
return conversation;
diff --git a/src/de/gultsch/chat/ui/XmppActivity.java b/src/de/gultsch/chat/ui/XmppActivity.java
index 991730413..c15482ac4 100644
--- a/src/de/gultsch/chat/ui/XmppActivity.java
+++ b/src/de/gultsch/chat/ui/XmppActivity.java
@@ -10,8 +10,8 @@ import android.content.ServiceConnection;
import android.os.IBinder;
public abstract class XmppActivity extends Activity {
- protected XmppConnectionService xmppConnectionService;
- protected boolean xmppConnectionServiceBound = false;
+ public XmppConnectionService xmppConnectionService;
+ public boolean xmppConnectionServiceBound = false;
protected boolean handledViewIntent = false;
protected ServiceConnection mConnection = new ServiceConnection() {
diff --git a/src/de/gultsch/chat/utils/Beautifier.java b/src/de/gultsch/chat/utils/Beautifier.java
new file mode 100644
index 000000000..43b7acc2c
--- /dev/null
+++ b/src/de/gultsch/chat/utils/Beautifier.java
@@ -0,0 +1,25 @@
+package de.gultsch.chat.utils;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class Beautifier {
+ public static String readableTimeDifference(long time) {
+ if (time==0) {
+ return "just now";
+ }
+ Date date = new Date(time);
+ long difference = (System.currentTimeMillis() - time) / 1000;
+ if (difference<60) {
+ return "just now";
+ } else if (difference<60*10) {
+ return difference / 60 + " min ago";
+ } else if (difference<60*60*24) {
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
+ return sdf.format(date);
+ } else {
+ SimpleDateFormat sdf = new SimpleDateFormat("M/D");
+ return sdf.format(date);
+ }
+ }
+}