diff --git a/art/ic_received_indicator.svg b/art/ic_received_indicator.svg
new file mode 100644
index 0000000000000000000000000000000000000000..d9378c60dde503e54a4de1ce0b4b8185f47cff3d
--- /dev/null
+++ b/art/ic_received_indicator.svg
@@ -0,0 +1,76 @@
+
+
+
+
diff --git a/art/render.rb b/art/render.rb
index ed3060727ee19fc5b0afd2e50bbe6c7b01ec53a5..5464b9f54e1fbad7d6aaa01dcbbc0c270f687dd4 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 0000000000000000000000000000000000000000..b1e3f27486a20085b651510660b0a07a5cf751ea
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 0000000000000000000000000000000000000000..88ff1efb90664e193981d988003767bfd62b9772
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 0000000000000000000000000000000000000000..2c8719337380416ddd15afb0f46924e90da01ea8
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 0000000000000000000000000000000000000000..039a9ef9ba6d588442aec93dd251eef7345538c2
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 9728dc56d8a6012cc2efe338c0942810409cf8c2..cb35093dcd438e7aa347063b2d16d8609f553c2a 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 1dbfdf10359a4413ecca1aadee3edd5f37a8d188..9b76c94b6ca96e7e740c349cc2b274bf62628895 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 c3e465ac934784fdebdb4b60413da25b66221d2c..22d617f81ff9bda5be5a5d4db6d6bce16c8d5aed 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 7d0886bcfd17274fb1508f1783fac68c09e08269..3dab09592458d1af68ea5d3a06fa757fdb484e08 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 9505c5cf7c3a770a1ff8ee7401f08e516d80473e..9507b3fc567b08916ff18a511d882f9dd69f18c0 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 b6bb0bd822bfa83bbca1b29ebbde1cf51ebc8a60..d4cab3edd032efe774e1fc2080fbada49bce85dd 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 96f455421df648a5cd69ad545529d9dd607f0b90..0e15c60f8346a7ed379b50c1aabf1e0c69ed10f1 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 cc56a1eac4f59e17d77b07d7bb855b3bdd6f00c3..f80bb9efc44cc60e48b50beff1c3978d663468a9 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 f58b4ddd8a9765e95f0af72fa250ddd3f89c0496..03d034d91e25697f02fc532aaabbe0f95236c8cf 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 acf6ac3fd963bbb3f0fb2ea9c641ef56c4d405c5..2392bbcffc1af92506f80a3f024c1a832234ff88 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;