aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/de/pixart/messenger/Config.java1
-rw-r--r--src/main/java/de/pixart/messenger/entities/Conversation.java15
-rw-r--r--src/main/java/de/pixart/messenger/entities/Message.java13
-rw-r--r--src/main/java/de/pixart/messenger/http/AesGcmURLStreamHandler.java17
-rw-r--r--src/main/java/de/pixart/messenger/http/AesGcmURLStreamHandlerFactory.java15
-rw-r--r--src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java13
-rw-r--r--src/main/java/de/pixart/messenger/services/ExportLogsService.java2
-rw-r--r--src/main/java/de/pixart/messenger/services/XmppConnectionService.java44
-rw-r--r--src/main/java/de/pixart/messenger/ui/ConversationFragment.java6
-rw-r--r--src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java77
-rw-r--r--src/main/java/de/pixart/messenger/utils/MimeUtils.java7
-rw-r--r--src/main/res/drawable/rounded_rectangle_primary.xml16
-rw-r--r--src/main/res/drawable/rounded_rectangle_red.xml (renamed from src/main/res/drawable/rounded_rectangle.xml)2
-rw-r--r--src/main/res/layout/conversation_list_row.xml26
-rw-r--r--src/main/res/values/strings.xml2
15 files changed, 181 insertions, 75 deletions
diff --git a/src/main/java/de/pixart/messenger/Config.java b/src/main/java/de/pixart/messenger/Config.java
index eef639e40..8b095a149 100644
--- a/src/main/java/de/pixart/messenger/Config.java
+++ b/src/main/java/de/pixart/messenger/Config.java
@@ -94,6 +94,7 @@ public final class Config {
public static boolean PUT_AUTH_TAG_INTO_KEY = false;
public static final int MAX_DISPLAY_MESSAGE_CHARS = 4096;
+ public static final int MAX_STORAGE_MESSAGE_CHARS = 1024 * 1024 * 1024;
public static final boolean ExportLogs = true; // automatically export logs
public static final int ExportLogs_Hour = 4; //valid values from 0 to 23
diff --git a/src/main/java/de/pixart/messenger/entities/Conversation.java b/src/main/java/de/pixart/messenger/entities/Conversation.java
index 526c60f6c..4a7b45088 100644
--- a/src/main/java/de/pixart/messenger/entities/Conversation.java
+++ b/src/main/java/de/pixart/messenger/entities/Conversation.java
@@ -994,6 +994,21 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
}
}
+ public int failedCount() {
+ synchronized (this.messages) {
+ int count = 0;
+ for (int i = this.messages.size() - 1; i >= 0; --i) {
+ Message message = this.messages.get(i);
+ if ((message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) && message.getEncryption() != Message.ENCRYPTION_PGP) {
+ if (message.getStatus() == Message.STATUS_SEND_FAILED){
+ ++count;
+ }
+ }
+ }
+ return count;
+ }
+ }
+
public class Smp {
public static final int STATUS_NONE = 0;
public static final int STATUS_CONTACT_REQUESTED = 1;
diff --git a/src/main/java/de/pixart/messenger/entities/Message.java b/src/main/java/de/pixart/messenger/entities/Message.java
index 8ac7735d6..0936c86c8 100644
--- a/src/main/java/de/pixart/messenger/entities/Message.java
+++ b/src/main/java/de/pixart/messenger/entities/Message.java
@@ -9,6 +9,7 @@ import java.net.URL;
import de.pixart.messenger.Config;
import de.pixart.messenger.crypto.axolotl.FingerprintStatus;
+import de.pixart.messenger.http.AesGcmURLStreamHandler;
import de.pixart.messenger.utils.CryptoHelper;
import de.pixart.messenger.utils.GeoHelper;
import de.pixart.messenger.utils.MimeUtils;
@@ -154,6 +155,8 @@ public class Message extends AbstractEntity {
}
} catch (InvalidJidException e) {
jid = null;
+ } catch (IllegalStateException e) {
+ return null; // message too long?
}
Jid trueCounterpart;
try {
@@ -217,7 +220,7 @@ public class Message extends AbstractEntity {
} else {
values.put(TRUE_COUNTERPART, trueCounterpart.toPreppedString());
}
- values.put(BODY, body);
+ values.put(BODY, body.length() > Config.MAX_STORAGE_MESSAGE_CHARS ? body.substring(0,Config.MAX_STORAGE_MESSAGE_CHARS) : body);
values.put(TIME_SENT, timeSent);
values.put(ENCRYPTION, encryption);
values.put(STATUS, status);
@@ -657,6 +660,12 @@ public class Message extends AbstractEntity {
}
try {
URL url = new URL(body);
+ String ref = url.getRef();
+ final String protocol = url.getProtocol();
+ final boolean encrypted = ref != null && ref.matches("([A-Fa-f0-9]{2}){48}");
+ if (AesGcmURLStreamHandler.PROTOCOL_NAME.equalsIgnoreCase(protocol) && encrypted) {
+ return Decision.MUST;
+ }
if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) {
return Decision.NEVER;
} else if (oob) {
@@ -666,8 +675,6 @@ public class Message extends AbstractEntity {
if (extension == null) {
return Decision.NEVER;
}
- String ref = url.getRef();
- boolean encrypted = ref != null && ref.matches("([A-Fa-f0-9]{2}){48}");
if (encrypted) {
return Decision.MUST;
diff --git a/src/main/java/de/pixart/messenger/http/AesGcmURLStreamHandler.java b/src/main/java/de/pixart/messenger/http/AesGcmURLStreamHandler.java
new file mode 100644
index 000000000..64188c5db
--- /dev/null
+++ b/src/main/java/de/pixart/messenger/http/AesGcmURLStreamHandler.java
@@ -0,0 +1,17 @@
+package de.pixart.messenger.http;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+
+public class AesGcmURLStreamHandler extends URLStreamHandler {
+
+ public static final String PROTOCOL_NAME = "aesgcm";
+
+ @Override
+ protected URLConnection openConnection(URL url) throws IOException {
+ return new URL("https"+url.toString().substring(url.getProtocol().length())).openConnection();
+ }
+}
diff --git a/src/main/java/de/pixart/messenger/http/AesGcmURLStreamHandlerFactory.java b/src/main/java/de/pixart/messenger/http/AesGcmURLStreamHandlerFactory.java
new file mode 100644
index 000000000..b5edd2f5a
--- /dev/null
+++ b/src/main/java/de/pixart/messenger/http/AesGcmURLStreamHandlerFactory.java
@@ -0,0 +1,15 @@
+package de.pixart.messenger.http;
+
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+
+public class AesGcmURLStreamHandlerFactory implements URLStreamHandlerFactory {
+ @Override
+ public URLStreamHandler createURLStreamHandler(String protocol) {
+ if (AesGcmURLStreamHandler.PROTOCOL_NAME.equals(protocol)) {
+ return new AesGcmURLStreamHandler();
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java b/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java
index b40452f1a..ef961f6a3 100644
--- a/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java
+++ b/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java
@@ -55,7 +55,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
private static DatabaseBackend instance = null;
public static final String DATABASE_NAME = "history";
- public static final int DATABASE_VERSION = 34;
+ public static final int DATABASE_VERSION = 35;
private static String CREATE_CONTATCS_STATEMENT = "create table "
+ Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, "
@@ -145,6 +145,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
private static String START_TIMES_TABLE = "start_times";
private static String CREATE_START_TIMES_TABLE = "create table " + START_TIMES_TABLE + " (timestamp NUMBER);";
private static String CREATE_MESSAGE_TIME_INDEX = "create INDEX message_time_index ON " + Message.TABLENAME + "(" + Message.TIME_SENT + ")";
+ private static String CREATE_MESSAGE_CONVERSATION_INDEX = "create INDEX message_conversation_index ON " + Message.TABLENAME + "(" + Message.CONVERSATION + ")";
private DatabaseBackend(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
@@ -195,6 +196,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
+ ") ON DELETE CASCADE);");
db.execSQL(CREATE_MESSAGE_TIME_INDEX);
+ db.execSQL(CREATE_MESSAGE_CONVERSATION_INDEX);
db.execSQL(CREATE_CONTATCS_STATEMENT);
db.execSQL(CREATE_DISCOVERY_RESULTS_STATEMENT);
db.execSQL(CREATE_SESSIONS_STATEMENT);
@@ -393,6 +395,9 @@ public class DatabaseBackend extends SQLiteOpenHelper {
db.execSQL(CREATE_MESSAGE_TIME_INDEX);
// do nothing else at this point because we have seperated videos, images, audios and other files in different directories
}
+ if (oldVersion < 35 && newVersion >= 35) {
+ db.execSQL(CREATE_MESSAGE_CONVERSATION_INDEX);
+ }
}
private static ContentValues createFingerprintStatusContentValues(FingerprintStatus.Trust trust, boolean active) {
@@ -597,8 +602,10 @@ public class DatabaseBackend extends SQLiteOpenHelper {
cursor.moveToLast();
do {
Message message = Message.fromCursor(cursor);
- message.setConversation(conversation);
- list.add(message);
+ if (message != null) {
+ message.setConversation(conversation);
+ list.add(message);
+ }
} while (cursor.moveToPrevious());
}
cursor.close();
diff --git a/src/main/java/de/pixart/messenger/services/ExportLogsService.java b/src/main/java/de/pixart/messenger/services/ExportLogsService.java
index d7948d651..61d8a921d 100644
--- a/src/main/java/de/pixart/messenger/services/ExportLogsService.java
+++ b/src/main/java/de/pixart/messenger/services/ExportLogsService.java
@@ -119,6 +119,8 @@ public class ExportLogsService extends Service {
BufferedWriter bw = null;
try {
for (Message message : mDatabaseBackend.getMessagesIterable(conversation)) {
+ if (message == null)
+ continue;
if (message.getType() == Message.TYPE_TEXT || message.hasFileOnRemoteHost()) {
String date = simpleDateFormat.format(new Date(message.getTimeSent()));
if (bw == null) {
diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
index 55b87074a..729079f2a 100644
--- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
+++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
@@ -99,6 +99,7 @@ import de.pixart.messenger.generator.IqGenerator;
import de.pixart.messenger.generator.MessageGenerator;
import de.pixart.messenger.generator.PresenceGenerator;
import de.pixart.messenger.http.HttpConnectionManager;
+import de.pixart.messenger.http.AesGcmURLStreamHandlerFactory;
import de.pixart.messenger.parser.AbstractParser;
import de.pixart.messenger.parser.IqParser;
import de.pixart.messenger.parser.MessageParser;
@@ -143,9 +144,14 @@ import de.pixart.messenger.xmpp.stanzas.IqPacket;
import de.pixart.messenger.xmpp.stanzas.MessagePacket;
import de.pixart.messenger.xmpp.stanzas.PresencePacket;
import me.leolin.shortcutbadger.ShortcutBadger;
+import java.net.URL;
public class XmppConnectionService extends Service {
+ static {
+ URL.setURLStreamHandlerFactory(new AesGcmURLStreamHandlerFactory());
+ }
+
public static final String ACTION_REPLY_TO_CONVERSATION = "reply_to_conversations";
public static final String ACTION_CLEAR_NOTIFICATION = "clear_notification";
public static final String ACTION_DISABLE_FOREGROUND = "disable_foreground";
@@ -1717,6 +1723,7 @@ public class XmppConnectionService extends Service {
return conversation;
}
conversation = databaseBackend.findConversation(account, jid);
+ final boolean loadMessagesFromDb;
if (conversation != null) {
conversation.setStatus(Conversation.STATUS_AVAILABLE);
conversation.setAccount(account);
@@ -1727,8 +1734,8 @@ public class XmppConnectionService extends Service {
conversation.setMode(Conversation.MODE_SINGLE);
conversation.setContactJid(jid.toBareJid());
}
- conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE));
- this.databaseBackend.updateConversation(conversation);
+ databaseBackend.updateConversation(conversation);
+ loadMessagesFromDb = conversation.messagesLoaded.compareAndSet(true,false);
} else {
String conversationName;
Contact contact = account.getRoster().getContact(jid);
@@ -1744,20 +1751,31 @@ public class XmppConnectionService extends Service {
conversation = new Conversation(conversationName, account, jid.toBareJid(),
Conversation.MODE_SINGLE);
}
- this.databaseBackend.createConversation(conversation);
+ loadMessagesFromDb = false;
}
- if (account.getXmppConnection() != null
- && account.getXmppConnection().getFeatures().mam()
- && !muc) {
- if (query == null) {
- this.mMessageArchiveService.query(conversation);
- } else {
- if (query.getConversation() == null) {
- this.mMessageArchiveService.query(conversation, query.getStart());
+ final Conversation c = conversation;
+ mDatabaseExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ if (loadMessagesFromDb) {
+ c.addAll(0, databaseBackend.getMessages(c, Config.PAGE_SIZE));
+ updateConversationUi();
+ c.messagesLoaded.set(true);
+ }
+ if (account.getXmppConnection() != null
+ && account.getXmppConnection().getFeatures().mam()
+ && !muc) {
+ if (query == null) {
+ mMessageArchiveService.query(c);
+ } else {
+ if (query.getConversation() == null) {
+ mMessageArchiveService.query(c, query.getStart());
+ }
+ }
}
+ checkDeletedFiles(c);
}
- }
- checkDeletedFiles(conversation);
+ });
this.conversations.add(conversation);
updateConversationUi();
return conversation;
diff --git a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
index 7bc1a3208..db9e3981d 100644
--- a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
+++ b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
@@ -141,8 +141,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
}
activity.xmppConnectionService.loadMoreMessages(conversation, timestamp, new XmppConnectionService.OnMoreMessagesLoaded() {
@Override
- public void onMoreMessagesLoaded(final int c, Conversation conversation) {
+ public void onMoreMessagesLoaded(final int c, final Conversation conversation) {
if (ConversationFragment.this.conversation != conversation) {
+ conversation.messagesLoaded.set(true);
return;
}
activity.runOnUiThread(new Runnable() {
@@ -170,6 +171,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
if (messageLoaderToast != null) {
messageLoaderToast.cancel();
}
+ conversation.messagesLoaded.set(true);
}
});
}
@@ -1283,7 +1285,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
private boolean showLoadMoreMessages(final Conversation c) {
final boolean mam = hasMamSupport(c);
final MessageArchiveService service = activity.xmppConnectionService.getMessageArchiveService();
- return mam && (c.getLastClearHistory() != 0 || (c.countMessages() == 0 && c.hasMessagesLeftOnServer() && !service.queryInProgress(c)));
+ return mam && (c.getLastClearHistory() != 0 || (c.countMessages() == 0 && c.messagesLoaded.get() && c.hasMessagesLeftOnServer() && !service.queryInProgress(c)));
}
private boolean hasMamSupport(final Conversation c) {
diff --git a/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java
index 600ac47eb..f17b7a2ab 100644
--- a/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java
+++ b/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java
@@ -22,6 +22,7 @@ import java.util.concurrent.RejectedExecutionException;
import de.pixart.messenger.R;
import de.pixart.messenger.entities.Conversation;
import de.pixart.messenger.entities.Message;
+import de.pixart.messenger.entities.Transferable;
import de.pixart.messenger.ui.ConversationActivity;
import de.pixart.messenger.ui.XmppActivity;
import de.pixart.messenger.utils.UIHelper;
@@ -86,9 +87,10 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
ImageView imagePreview = (ImageView) view.findViewById(R.id.conversation_lastimage);
ImageView notificationStatus = (ImageView) view.findViewById(R.id.notification_status);
TextView mUnread = (TextView) view.findViewById(R.id.conversation_unread);
+ TextView mFailed = (TextView) view.findViewById(R.id.conversation_failed);
Message message = conversation.getLatestMessage();
int unreadcount = conversation.unreadCount();
- String mimeType = message.getMimeType();
+ int failedcount = conversation.failedCount();
if (!conversation.isRead()) {
convName.setTypeface(null, Typeface.BOLD);
@@ -96,61 +98,44 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
convName.setTypeface(null, Typeface.NORMAL);
}
-
- /*if (message.getTransferable() == null
- || message.getTransferable().getStatus() != Transferable.STATUS_DELETED) {
- if (mimeType != null && message.getMimeType().startsWith("video/")) {
- mLastMessage.setVisibility(View.GONE);
- imagePreview.setVisibility(View.VISIBLE);
- activity.loadVideoPreview(message, imagePreview);
- } else if (message.getFileParams().width > 0) {
- mLastMessage.setVisibility(View.GONE);
- imagePreview.setVisibility(View.VISIBLE);
- activity.loadBitmap(message, imagePreview);
- } else {
- Pair<String, Boolean> preview = UIHelper.getMessagePreview(activity, message);
- mLastMessage.setVisibility(View.VISIBLE);
- imagePreview.setVisibility(View.GONE);
- mLastMessage.setText(preview.first);
- if (preview.second) {
- if (conversation.isRead()) {
- mLastMessage.setTypeface(null, Typeface.ITALIC);
- } else {
- mLastMessage.setTypeface(null, Typeface.BOLD_ITALIC);
- }
- } else {
- if (conversation.isRead()) {
- mLastMessage.setTypeface(null, Typeface.NORMAL);
- } else {
- mLastMessage.setTypeface(null, Typeface.BOLD);
- }
- }
- }
- } else {*/
- Pair<String, Boolean> preview = UIHelper.getMessagePreview(activity, message);
- mLastMessage.setVisibility(View.VISIBLE);
- imagePreview.setVisibility(View.GONE);
- mLastMessage.setText(preview.first);
if (unreadcount > 0) {
mUnread.setVisibility(View.VISIBLE);
mUnread.setText(String.valueOf(unreadcount));
} else {
mUnread.setVisibility(View.GONE);
}
- if (preview.second) {
- if (conversation.isRead()) {
- mLastMessage.setTypeface(null, Typeface.ITALIC);
- } else {
- mLastMessage.setTypeface(null, Typeface.BOLD_ITALIC);
- }
+ if (failedcount > 0) {
+ mFailed.setVisibility(View.VISIBLE);
+ mFailed.setText(String.valueOf(failedcount));
} else {
- if (conversation.isRead()) {
- mLastMessage.setTypeface(null, Typeface.NORMAL);
+ mFailed.setVisibility(View.GONE);
+ }
+
+ if (message.getFileParams().width > 0
+ && (message.getTransferable() == null
+ || message.getTransferable().getStatus() != Transferable.STATUS_DELETED)) {
+ mLastMessage.setVisibility(View.GONE);
+ imagePreview.setVisibility(View.VISIBLE);
+ activity.loadBitmap(message, imagePreview);
+ } else {
+ Pair<String, Boolean> preview = UIHelper.getMessagePreview(activity, message);
+ mLastMessage.setVisibility(View.VISIBLE);
+ imagePreview.setVisibility(View.GONE);
+ mLastMessage.setText(preview.first);
+ if (preview.second) {
+ if (conversation.isRead()) {
+ mLastMessage.setTypeface(null, Typeface.ITALIC);
+ } else {
+ mLastMessage.setTypeface(null, Typeface.BOLD_ITALIC);
+ }
} else {
- mLastMessage.setTypeface(null, Typeface.BOLD);
+ if (conversation.isRead()) {
+ mLastMessage.setTypeface(null, Typeface.NORMAL);
+ } else {
+ mLastMessage.setTypeface(null, Typeface.BOLD);
+ }
}
}
- //}
long muted_till = conversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0);
if (muted_till == Long.MAX_VALUE) {
diff --git a/src/main/java/de/pixart/messenger/utils/MimeUtils.java b/src/main/java/de/pixart/messenger/utils/MimeUtils.java
index bdcd82bae..0e52e283f 100644
--- a/src/main/java/de/pixart/messenger/utils/MimeUtils.java
+++ b/src/main/java/de/pixart/messenger/utils/MimeUtils.java
@@ -505,7 +505,12 @@ public final class MimeUtils {
public static String guessMimeTypeFromUri(Context context, Uri uri) {
// try the content resolver
- String mimeType = context.getContentResolver().getType(uri);
+ String mimeType;
+ try {
+ mimeType = context.getContentResolver().getType(uri);
+ } catch (Throwable throwable) {
+ mimeType = null;
+ }
// try the extension
if (mimeType == null && uri.getPath() != null) {
String path = uri.getPath();
diff --git a/src/main/res/drawable/rounded_rectangle_primary.xml b/src/main/res/drawable/rounded_rectangle_primary.xml
new file mode 100644
index 000000000..3a32aa8e5
--- /dev/null
+++ b/src/main/res/drawable/rounded_rectangle_primary.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+<item>
+ <shape android:shape="rectangle">
+ <padding
+ android:bottom="2dp"
+ android:left="2dp"
+ android:right="2dp"
+ android:top="2dp" />
+ <solid android:color="@color/primary" />
+ <corners android:radius="6dp" />
+ </shape>
+</item>
+
+</layer-list> \ No newline at end of file
diff --git a/src/main/res/drawable/rounded_rectangle.xml b/src/main/res/drawable/rounded_rectangle_red.xml
index fab83eda9..a6cb17d2b 100644
--- a/src/main/res/drawable/rounded_rectangle.xml
+++ b/src/main/res/drawable/rounded_rectangle_red.xml
@@ -8,7 +8,7 @@
android:left="2dp"
android:right="2dp"
android:top="2dp" />
- <solid android:color="@color/primary" />
+ <solid android:color="@color/red800" />
<corners android:radius="6dp" />
</shape>
</item>
diff --git a/src/main/res/layout/conversation_list_row.xml b/src/main/res/layout/conversation_list_row.xml
index 195a14621..16d611ce9 100644
--- a/src/main/res/layout/conversation_list_row.xml
+++ b/src/main/res/layout/conversation_list_row.xml
@@ -46,13 +46,13 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/conversation_lastwrapper"
- android:layout_toLeftOf="@+id/conversation_unread"
android:paddingRight="4dp"
android:singleLine="true"
android:text="Awesome groupchat"
android:textColor="@color/black87"
android:textSize="?attr/TextSizeHeadline"
- android:typeface="sans" />
+ android:typeface="sans"
+ android:layout_toLeftOf="@+id/conversation_failed" />
<RelativeLayout
android:id="@+id/conversation_lastwrapper"
@@ -110,18 +110,34 @@
android:text="100"
android:textColor="@color/grey50"
android:textSize="?attr/TextSizeBody"
- android:background="@drawable/rounded_rectangle"
+ android:background="@drawable/rounded_rectangle_primary"
+ android:visibility="gone"
+ android:paddingLeft="4dp"
+ android:paddingRight="4dp"
+ android:paddingBottom="2dp"
+ android:layout_margin="1dp" />
+ <TextView
+ android:id="@+id/conversation_failed"
+ android:layout_toLeftOf="@+id/conversation_unread"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBaseline="@+id/conversation_name"
+ android:text="100"
+ android:textColor="@color/grey50"
+ android:textSize="?attr/TextSizeBody"
+ android:background="@drawable/rounded_rectangle_red"
android:visibility="gone"
android:paddingLeft="4dp"
android:paddingRight="4dp"
- android:paddingBottom="2dp" />
+ android:paddingBottom="2dp"
+ android:layout_margin="1dp" />
<TextView
android:id="@+id/conversation_lastupdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignBaseline="@+id/conversation_name"
android:layout_alignParentRight="true"
+ android:layout_alignBaseline="@+id/conversation_name"
android:paddingLeft="4dp"
android:gravity="right"
android:text="23:42"
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 4df0cc10b..4ac341344 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -729,7 +729,7 @@
<string name="transcoding_video_progress">Compressing video (%s%% completed)</string>
<string name="pref_automatically_delete_messages_description">Automatically delete messages from this device that are older than the configured time frame.</string>
<string name="pref_automatically_delete_messages">Automatic message deletion</string>
- <string name="not_fetching_history_retention_period">Overstepping local retention period.</string>
+ <string name="not_fetching_history_retention_period">Not fetching messages due to local retention period.</string>
<string name="timeout_24_hours">24 hours</string>
<string name="timeout_7_days">7 days</string>
<string name="timeout_30_days">30 days</string>