diff --git a/art/ic_received_indicator.svg b/art/ic_received_indicator.svg
new file mode 100644
index 00000000..d9378c60
--- /dev/null
+++ b/art/ic_received_indicator.svg
@@ -0,0 +1,76 @@
+
+
+
+
diff --git a/art/render.rb b/art/render.rb
index ed306072..5464b9f5 100755
--- a/art/render.rb
+++ b/art/render.rb
@@ -1,6 +1,6 @@
#!/bin/env ruby
resolutions={'mdpi'=> 1, 'hdpi' => 1.5, 'xhdpi' => 2, 'xxhdpi' => 3}
-images = { 'conversations.svg' => ['ic_launcher',48], 'conversations_baloon.svg' => ['ic_activity', 32], 'conversations_mono.svg' => ['ic_notification',24] }
+images = { 'conversations.svg' => ['ic_launcher',48], 'conversations_baloon.svg' => ['ic_activity', 32], 'conversations_mono.svg' => ['ic_notification',24], 'ic_received_indicator.svg' => ['ic_received_indicator',12] }
images.each do |source, result|
resolutions.each do |name, factor|
size = factor * result[1]
diff --git a/res/drawable-hdpi/ic_received_indicator.png b/res/drawable-hdpi/ic_received_indicator.png
new file mode 100644
index 00000000..b1e3f274
Binary files /dev/null and b/res/drawable-hdpi/ic_received_indicator.png differ
diff --git a/res/drawable-mdpi/ic_received_indicator.png b/res/drawable-mdpi/ic_received_indicator.png
new file mode 100644
index 00000000..88ff1efb
Binary files /dev/null and b/res/drawable-mdpi/ic_received_indicator.png differ
diff --git a/res/drawable-xhdpi/ic_received_indicator.png b/res/drawable-xhdpi/ic_received_indicator.png
new file mode 100644
index 00000000..2c871933
Binary files /dev/null and b/res/drawable-xhdpi/ic_received_indicator.png differ
diff --git a/res/drawable-xxhdpi/ic_received_indicator.png b/res/drawable-xxhdpi/ic_received_indicator.png
new file mode 100644
index 00000000..039a9ef9
Binary files /dev/null and b/res/drawable-xxhdpi/ic_received_indicator.png differ
diff --git a/res/layout/message_sent.xml b/res/layout/message_sent.xml
index 9728dc56..cb35093d 100644
--- a/res/layout/message_sent.xml
+++ b/res/layout/message_sent.xml
@@ -63,6 +63,16 @@
android:textColor="@color/secondarytext"
android:textSize="?attr/TextSizeInfo" />
+
+
-
\ No newline at end of file
+
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 1dbfdf10..9b76c94b 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -232,6 +232,8 @@
Zusätzliche Informationen
Überspringen
Benutzeroberfläche
+ Anfrage für Nachrichten Empfang
+ Wenn Nachricht vom Empfänger empfangen wurde dann erscheint ein Häckchen als Bestätigung (muss vom Client des Empfängers unterstützt werden und funktioniert nicht in jedem Fall)
Benachrichtigungen deaktivieren
Benachrichtigungen für diese Unterhaltung deaktivieren
Benachrichtigungen sind deaktiviert
@@ -256,5 +258,6 @@
Überall in der App eine größere Schrift verwenden
Absende-Knopf zeigt Online-Status an
Absende-Knopf einfärben, um den Online-Status des Kontakts zu signalisieren
+ Anderes - nicht kategorisiert
-
\ No newline at end of file
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c3e465ac..22d617f8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -255,6 +255,9 @@
Increase font size
Use larger font sizes across the entire app
Send button indicates status
+ Request message receipts
+ When message has been received by the receiver then a tick will appear as confirmation (must supported by the recipient client and does not work as any case)
Colorize send button to indicate contact status
+ Other - not categorized
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index 7d0886bc..3dab0959 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -90,6 +90,13 @@
android:summary="@string/pref_dont_save_encrypted_summary"
android:title="@string/pref_dont_save_encrypted" />
+
+
+
-
\ No newline at end of file
+
diff --git a/src/eu/siacs/conversations/entities/Message.java b/src/eu/siacs/conversations/entities/Message.java
index 9505c5cf..9507b3fc 100644
--- a/src/eu/siacs/conversations/entities/Message.java
+++ b/src/eu/siacs/conversations/entities/Message.java
@@ -326,12 +326,12 @@ public class Message extends AbstractEntity {
&& this.getType() == message.getType()
&& 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.STATUS_SEND_RECEIVED) && (message
- .getStatus() == Message.STATUS_UNSEND
- || message.getStatus() == Message.STATUS_SEND || message
- .getStatus() == Message.STATUS_SEND_DISPLAYED))));
+ && (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000)
+ && ((this.getStatus() == message.getStatus())
+ || (this.getStatus() == Message.STATUS_SEND && (message.getStatus() == Message.STATUS_UNSEND
+ || message.getStatus() == Message.STATUS_SEND))
+ || (this.getStatus() == Message.STATUS_SEND_RECEIVED
+ && message.getStatus() == Message.STATUS_SEND_DISPLAYED)));
}
public String getMergedBody() {
diff --git a/src/eu/siacs/conversations/generator/MessageGenerator.java b/src/eu/siacs/conversations/generator/MessageGenerator.java
index b6bb0bd8..d4cab3ed 100644
--- a/src/eu/siacs/conversations/generator/MessageGenerator.java
+++ b/src/eu/siacs/conversations/generator/MessageGenerator.java
@@ -27,6 +27,9 @@ public class MessageGenerator extends AbstractGenerator {
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);
diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java
index 96f45542..0e15c60f 100644
--- a/src/eu/siacs/conversations/parser/MessageParser.java
+++ b/src/eu/siacs/conversations/parser/MessageParser.java
@@ -278,6 +278,13 @@ public class MessageParser extends AbstractParser implements
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,
+ Message.STATUS_SEND_RECEIVED);
} else if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) {
Element x = packet.findChild("x",
"http://jabber.org/protocol/muc#user");
diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java
index cc56a1ea..f80bb9ef 100644
--- a/src/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/eu/siacs/conversations/services/XmppConnectionService.java
@@ -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/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java
index f58b4ddd..03d034d9 100644
--- a/src/eu/siacs/conversations/ui/ConversationActivity.java
+++ b/src/eu/siacs/conversations/ui/ConversationActivity.java
@@ -790,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/adapter/MessageAdapter.java b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java
index acf6ac3f..2392bbcf 100644
--- a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java
+++ b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java
@@ -96,6 +96,9 @@ public class MessageAdapter extends ArrayAdapter {
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) {
@@ -117,6 +120,16 @@ public class MessageAdapter extends ArrayAdapter {
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;
@@ -337,6 +350,8 @@ public class MessageAdapter extends ArrayAdapter {
.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:
@@ -515,6 +530,7 @@ public class MessageAdapter extends ArrayAdapter {
protected Button download_button;
protected ImageView image;
protected ImageView indicator;
+ protected ImageView indicatorReceived;
protected TextView time;
protected TextView messageBody;
protected ImageView contact_picture;