diff --git a/art/ic_received_indicator.svg b/art/ic_received_indicator.svg new file mode 100644 index 000000000..d9378c60d --- /dev/null +++ b/art/ic_received_indicator.svg @@ -0,0 +1,76 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/art/render.rb b/art/render.rb index ed3060727..5464b9f54 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 000000000..b1e3f2748 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 000000000..88ff1efb9 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 000000000..2c8719337 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 000000000..039a9ef9b 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 9728dc56d..cb35093dc 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 1dbfdf103..9b76c94b6 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 c3e465ac9..22d617f81 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 7d0886bcf..3dab09592 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 9505c5cf7..9507b3fc5 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 b6bb0bd82..d4cab3edd 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 96f455421..0e15c60f8 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 cc56a1eac..f80bb9efc 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 f58b4ddd8..03d034d91 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 acf6ac3fd..2392bbcff 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;