show message draft in conversation overview
This commit is contained in:
parent
9765f26de0
commit
11dfd87672
|
@ -3,6 +3,8 @@ package eu.siacs.conversations.entities;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
@ -46,13 +48,14 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
public static final String ATTRIBUTE_MUTED_TILL = "muted_till";
|
public static final String ATTRIBUTE_MUTED_TILL = "muted_till";
|
||||||
public static final String ATTRIBUTE_ALWAYS_NOTIFY = "always_notify";
|
public static final String ATTRIBUTE_ALWAYS_NOTIFY = "always_notify";
|
||||||
public static final String ATTRIBUTE_LAST_CLEAR_HISTORY = "last_clear_history";
|
public static final String ATTRIBUTE_LAST_CLEAR_HISTORY = "last_clear_history";
|
||||||
public static final String ATTRIBUTE_NEXT_MESSAGE = "next_message";
|
|
||||||
|
|
||||||
private static final String ATTRIBUTE_CRYPTO_TARGETS = "crypto_targets";
|
|
||||||
|
|
||||||
private static final String ATTRIBUTE_NEXT_ENCRYPTION = "next_encryption";
|
|
||||||
static final String ATTRIBUTE_MUC_PASSWORD = "muc_password";
|
static final String ATTRIBUTE_MUC_PASSWORD = "muc_password";
|
||||||
|
private static final String ATTRIBUTE_NEXT_MESSAGE = "next_message";
|
||||||
|
private static final String ATTRIBUTE_NEXT_MESSAGE_TIMESTAMP = "next_message_timestamp";
|
||||||
|
private static final String ATTRIBUTE_CRYPTO_TARGETS = "crypto_targets";
|
||||||
|
private static final String ATTRIBUTE_NEXT_ENCRYPTION = "next_encryption";
|
||||||
|
protected final ArrayList<Message> messages = new ArrayList<>();
|
||||||
|
public AtomicBoolean messagesLoaded = new AtomicBoolean(true);
|
||||||
|
protected Account account = null;
|
||||||
private String draftMessage;
|
private String draftMessage;
|
||||||
private String name;
|
private String name;
|
||||||
private String contactUuid;
|
private String contactUuid;
|
||||||
|
@ -61,22 +64,59 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
private int status;
|
private int status;
|
||||||
private long created;
|
private long created;
|
||||||
private int mode;
|
private int mode;
|
||||||
|
|
||||||
private JSONObject attributes = new JSONObject();
|
private JSONObject attributes = new JSONObject();
|
||||||
|
|
||||||
private Jid nextCounterpart;
|
private Jid nextCounterpart;
|
||||||
|
|
||||||
protected final ArrayList<Message> messages = new ArrayList<>();
|
|
||||||
protected Account account = null;
|
|
||||||
|
|
||||||
private transient MucOptions mucOptions = null;
|
private transient MucOptions mucOptions = null;
|
||||||
|
|
||||||
private boolean messagesLeftOnServer = true;
|
private boolean messagesLeftOnServer = true;
|
||||||
private ChatState mOutgoingChatState = Config.DEFAULT_CHATSTATE;
|
private ChatState mOutgoingChatState = Config.DEFAULT_CHATSTATE;
|
||||||
private ChatState mIncomingChatState = Config.DEFAULT_CHATSTATE;
|
private ChatState mIncomingChatState = Config.DEFAULT_CHATSTATE;
|
||||||
private String mFirstMamReference = null;
|
private String mFirstMamReference = null;
|
||||||
private Message correctingMessage;
|
private Message correctingMessage;
|
||||||
public AtomicBoolean messagesLoaded = new AtomicBoolean(true);
|
|
||||||
|
public Conversation(final String name, final Account account, final Jid contactJid,
|
||||||
|
final int mode) {
|
||||||
|
this(java.util.UUID.randomUUID().toString(), name, null, account
|
||||||
|
.getUuid(), contactJid, System.currentTimeMillis(),
|
||||||
|
STATUS_AVAILABLE, mode, "");
|
||||||
|
this.account = account;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Conversation(final String uuid, final String name, final String contactUuid,
|
||||||
|
final String accountUuid, final Jid contactJid, final long created, final int status,
|
||||||
|
final int mode, final String attributes) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.name = name;
|
||||||
|
this.contactUuid = contactUuid;
|
||||||
|
this.accountUuid = accountUuid;
|
||||||
|
this.contactJid = contactJid;
|
||||||
|
this.created = created;
|
||||||
|
this.status = status;
|
||||||
|
this.mode = mode;
|
||||||
|
try {
|
||||||
|
this.attributes = new JSONObject(attributes == null ? "" : attributes);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
this.attributes = new JSONObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Conversation fromCursor(Cursor cursor) {
|
||||||
|
Jid jid;
|
||||||
|
try {
|
||||||
|
jid = Jid.of(cursor.getString(cursor.getColumnIndex(CONTACTJID)));
|
||||||
|
} catch (final IllegalArgumentException e) {
|
||||||
|
// Borked DB..
|
||||||
|
jid = null;
|
||||||
|
}
|
||||||
|
return new Conversation(cursor.getString(cursor.getColumnIndex(UUID)),
|
||||||
|
cursor.getString(cursor.getColumnIndex(NAME)),
|
||||||
|
cursor.getString(cursor.getColumnIndex(CONTACT)),
|
||||||
|
cursor.getString(cursor.getColumnIndex(ACCOUNT)),
|
||||||
|
jid,
|
||||||
|
cursor.getLong(cursor.getColumnIndex(CREATED)),
|
||||||
|
cursor.getInt(cursor.getColumnIndex(STATUS)),
|
||||||
|
cursor.getInt(cursor.getColumnIndex(MODE)),
|
||||||
|
cursor.getString(cursor.getColumnIndex(ATTRIBUTES)));
|
||||||
|
}
|
||||||
|
|
||||||
public boolean hasMessagesLeftOnServer() {
|
public boolean hasMessagesLeftOnServer() {
|
||||||
return messagesLeftOnServer;
|
return messagesLeftOnServer;
|
||||||
|
@ -86,7 +126,6 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
this.messagesLeftOnServer = value;
|
this.messagesLeftOnServer = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Message getFirstUnreadMessage() {
|
public Message getFirstUnreadMessage() {
|
||||||
Message first = null;
|
Message first = null;
|
||||||
synchronized (this.messages) {
|
synchronized (this.messages) {
|
||||||
|
@ -325,19 +364,19 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFirstMamReference(String reference) {
|
|
||||||
this.mFirstMamReference = reference;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFirstMamReference() {
|
public String getFirstMamReference() {
|
||||||
return this.mFirstMamReference;
|
return this.mFirstMamReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFirstMamReference(String reference) {
|
||||||
|
this.mFirstMamReference = reference;
|
||||||
|
}
|
||||||
|
|
||||||
public void setLastClearHistory(long time, String reference) {
|
public void setLastClearHistory(long time, String reference) {
|
||||||
if (reference != null) {
|
if (reference != null) {
|
||||||
setAttribute(ATTRIBUTE_LAST_CLEAR_HISTORY, String.valueOf(time) + ":" + reference);
|
setAttribute(ATTRIBUTE_LAST_CLEAR_HISTORY, String.valueOf(time) + ":" + reference);
|
||||||
} else {
|
} else {
|
||||||
setAttribute(ATTRIBUTE_LAST_CLEAR_HISTORY, String.valueOf(time));
|
setAttribute(ATTRIBUTE_LAST_CLEAR_HISTORY, time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,53 +411,25 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(@NonNull Conversation another) {
|
public int compareTo(@NonNull Conversation another) {
|
||||||
final Message left = getLatestMessage();
|
return Long.compare(another.getSortableTime(), getSortableTime());
|
||||||
final Message right = another.getLatestMessage();
|
|
||||||
if (left.getTimeSent() > right.getTimeSent()) {
|
|
||||||
return -1;
|
|
||||||
} else if (left.getTimeSent() < right.getTimeSent()) {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDraftMessage(String draftMessage) {
|
private long getSortableTime() {
|
||||||
this.draftMessage = draftMessage;
|
Draft draft = getDraft();
|
||||||
|
long messageTime = getLatestMessage().getTimeSent();
|
||||||
|
if (draft == null) {
|
||||||
|
return messageTime;
|
||||||
|
} else {
|
||||||
|
return Math.max(messageTime, draft.getTimestamp());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDraftMessage() {
|
public String getDraftMessage() {
|
||||||
return draftMessage;
|
return draftMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface OnMessageFound {
|
public void setDraftMessage(String draftMessage) {
|
||||||
void onMessageFound(final Message message);
|
this.draftMessage = draftMessage;
|
||||||
}
|
|
||||||
|
|
||||||
public Conversation(final String name, final Account account, final Jid contactJid,
|
|
||||||
final int mode) {
|
|
||||||
this(java.util.UUID.randomUUID().toString(), name, null, account
|
|
||||||
.getUuid(), contactJid, System.currentTimeMillis(),
|
|
||||||
STATUS_AVAILABLE, mode, "");
|
|
||||||
this.account = account;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Conversation(final String uuid, final String name, final String contactUuid,
|
|
||||||
final String accountUuid, final Jid contactJid, final long created, final int status,
|
|
||||||
final int mode, final String attributes) {
|
|
||||||
this.uuid = uuid;
|
|
||||||
this.name = name;
|
|
||||||
this.contactUuid = contactUuid;
|
|
||||||
this.accountUuid = accountUuid;
|
|
||||||
this.contactJid = contactJid;
|
|
||||||
this.created = created;
|
|
||||||
this.status = status;
|
|
||||||
this.mode = mode;
|
|
||||||
try {
|
|
||||||
this.attributes = new JSONObject(attributes == null ? "" : attributes);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
this.attributes = new JSONObject();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRead() {
|
public boolean isRead() {
|
||||||
|
@ -497,14 +508,14 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
return this.account;
|
return this.account;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Contact getContact() {
|
|
||||||
return this.account.getRoster().getContact(this.contactJid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAccount(final Account account) {
|
public void setAccount(final Account account) {
|
||||||
this.account = account;
|
this.account = account;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Contact getContact() {
|
||||||
|
return this.account.getRoster().getContact(this.contactJid);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Jid getJid() {
|
public Jid getJid() {
|
||||||
return this.contactJid;
|
return this.contactJid;
|
||||||
|
@ -514,6 +525,10 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
return this.status;
|
return this.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStatus(int status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
public long getCreated() {
|
public long getCreated() {
|
||||||
return this.created;
|
return this.created;
|
||||||
}
|
}
|
||||||
|
@ -532,29 +547,6 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Conversation fromCursor(Cursor cursor) {
|
|
||||||
Jid jid;
|
|
||||||
try {
|
|
||||||
jid = Jid.of(cursor.getString(cursor.getColumnIndex(CONTACTJID)));
|
|
||||||
} catch (final IllegalArgumentException e) {
|
|
||||||
// Borked DB..
|
|
||||||
jid = null;
|
|
||||||
}
|
|
||||||
return new Conversation(cursor.getString(cursor.getColumnIndex(UUID)),
|
|
||||||
cursor.getString(cursor.getColumnIndex(NAME)),
|
|
||||||
cursor.getString(cursor.getColumnIndex(CONTACT)),
|
|
||||||
cursor.getString(cursor.getColumnIndex(ACCOUNT)),
|
|
||||||
jid,
|
|
||||||
cursor.getLong(cursor.getColumnIndex(CREATED)),
|
|
||||||
cursor.getInt(cursor.getColumnIndex(STATUS)),
|
|
||||||
cursor.getInt(cursor.getColumnIndex(MODE)),
|
|
||||||
cursor.getString(cursor.getColumnIndex(ATTRIBUTES)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(int status) {
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMode() {
|
public int getMode() {
|
||||||
return this.mode;
|
return this.mode;
|
||||||
}
|
}
|
||||||
|
@ -589,14 +581,14 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
this.contactJid = jid;
|
this.contactJid = jid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNextCounterpart(Jid jid) {
|
|
||||||
this.nextCounterpart = jid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Jid getNextCounterpart() {
|
public Jid getNextCounterpart() {
|
||||||
return this.nextCounterpart;
|
return this.nextCounterpart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setNextCounterpart(Jid jid) {
|
||||||
|
this.nextCounterpart = jid;
|
||||||
|
}
|
||||||
|
|
||||||
public int getNextEncryption() {
|
public int getNextEncryption() {
|
||||||
final int defaultEncryption;
|
final int defaultEncryption;
|
||||||
AxolotlService axolotlService = account.getAxolotlService();
|
AxolotlService axolotlService = account.getAxolotlService();
|
||||||
|
@ -624,9 +616,24 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
return nextMessage == null ? "" : nextMessage;
|
return nextMessage == null ? "" : nextMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @Nullable
|
||||||
|
Draft getDraft() {
|
||||||
|
long timestamp = getLongAttribute(ATTRIBUTE_NEXT_MESSAGE_TIMESTAMP, 0);
|
||||||
|
if (timestamp > getLatestMessage().getTimeSent()) {
|
||||||
|
String message = getAttribute(ATTRIBUTE_NEXT_MESSAGE);
|
||||||
|
if (!TextUtils.isEmpty(message) && timestamp != 0) {
|
||||||
|
return new Draft(message, timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean setNextMessage(String message) {
|
public boolean setNextMessage(String message) {
|
||||||
boolean changed = !getNextMessage().equals(message);
|
boolean changed = !getNextMessage().equals(message);
|
||||||
this.setAttribute(ATTRIBUTE_NEXT_MESSAGE, message);
|
this.setAttribute(ATTRIBUTE_NEXT_MESSAGE, message);
|
||||||
|
if (changed) {
|
||||||
|
this.setAttribute(ATTRIBUTE_NEXT_MESSAGE_TIMESTAMP, TextUtils.isEmpty(message) ? 0 : System.currentTimeMillis());
|
||||||
|
}
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,6 +706,10 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
return mode == MODE_SINGLE || getBooleanAttribute(ATTRIBUTE_ALWAYS_NOTIFY, Config.ALWAYS_NOTIFY_BY_DEFAULT || isPrivateAndNonAnonymous());
|
return mode == MODE_SINGLE || getBooleanAttribute(ATTRIBUTE_ALWAYS_NOTIFY, Config.ALWAYS_NOTIFY_BY_DEFAULT || isPrivateAndNonAnonymous());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean setAttribute(String key, long value) {
|
||||||
|
return setAttribute(key, Long.toString(value));
|
||||||
|
}
|
||||||
|
|
||||||
public boolean setAttribute(String key, String value) {
|
public boolean setAttribute(String key, String value) {
|
||||||
synchronized (this.attributes) {
|
synchronized (this.attributes) {
|
||||||
try {
|
try {
|
||||||
|
@ -884,4 +895,26 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
&& !getContact().showInRoster()
|
&& !getContact().showInRoster()
|
||||||
&& sentMessagesCount() == 0;
|
&& sentMessagesCount() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface OnMessageFound {
|
||||||
|
void onMessageFound(final Message message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Draft {
|
||||||
|
private final String message;
|
||||||
|
private final long timestamp;
|
||||||
|
|
||||||
|
private Draft(String message, long timestamp) {
|
||||||
|
this.message = message;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,18 +45,45 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean cancelPotentialWork(Conversation conversation, ImageView imageView) {
|
||||||
|
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
|
||||||
|
|
||||||
|
if (bitmapWorkerTask != null) {
|
||||||
|
final Conversation oldConversation = bitmapWorkerTask.conversation;
|
||||||
|
if (oldConversation == null || conversation != oldConversation) {
|
||||||
|
bitmapWorkerTask.cancel(true);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
|
||||||
|
if (imageView != null) {
|
||||||
|
final Drawable drawable = imageView.getDrawable();
|
||||||
|
if (drawable instanceof AsyncDrawable) {
|
||||||
|
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
|
||||||
|
return asyncDrawable.getBitmapWorkerTask();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View view, @NonNull ViewGroup parent) {
|
public @NonNull
|
||||||
|
View getView(int position, View view, @NonNull ViewGroup parent) {
|
||||||
if (view == null) {
|
if (view == null) {
|
||||||
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
view = inflater.inflate(R.layout.conversation_list_row, parent, false);
|
view = inflater.inflate(R.layout.conversation_list_row, parent, false);
|
||||||
}
|
}
|
||||||
ViewHolder viewHolder = ViewHolder.get(view);
|
ViewHolder viewHolder = ViewHolder.get(view);
|
||||||
Conversation conversation = getItem(position);
|
Conversation conversation = getItem(position);
|
||||||
if (this.activity instanceof XmppActivity) {
|
if (conversation == null) {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
int c = Color.get(activity, conversation == selectedConversation ? R.attr.color_background_secondary : R.attr.color_background_primary);
|
int c = Color.get(activity, conversation == selectedConversation ? R.attr.color_background_secondary : R.attr.color_background_primary);
|
||||||
viewHolder.swipeableItem.setBackgroundColor(c);
|
viewHolder.swipeableItem.setBackgroundColor(c);
|
||||||
}
|
|
||||||
if (conversation.getMode() == Conversation.MODE_SINGLE || activity.useSubjectToIdentifyConference()) {
|
if (conversation.getMode() == Conversation.MODE_SINGLE || activity.useSubjectToIdentifyConference()) {
|
||||||
CharSequence name = conversation.getName();
|
CharSequence name = conversation.getName();
|
||||||
if (name instanceof Jid) {
|
if (name instanceof Jid) {
|
||||||
|
@ -69,7 +96,9 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Message message = conversation.getLatestMessage();
|
Message message = conversation.getLatestMessage();
|
||||||
int unreadCount = conversation.unreadCount();
|
final int unreadCount = conversation.unreadCount();
|
||||||
|
final boolean isRead = conversation.isRead();
|
||||||
|
final Conversation.Draft draft = isRead ? conversation.getDraft() : null;
|
||||||
if (unreadCount > 0) {
|
if (unreadCount > 0) {
|
||||||
viewHolder.unreadCount.setVisibility(View.VISIBLE);
|
viewHolder.unreadCount.setVisibility(View.VISIBLE);
|
||||||
viewHolder.unreadCount.setUnreadCount(unreadCount);
|
viewHolder.unreadCount.setUnreadCount(unreadCount);
|
||||||
|
@ -77,12 +106,20 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
viewHolder.unreadCount.setVisibility(View.GONE);
|
viewHolder.unreadCount.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conversation.isRead()) {
|
if (isRead) {
|
||||||
viewHolder.name.setTypeface(null, Typeface.BOLD);
|
|
||||||
} else {
|
|
||||||
viewHolder.name.setTypeface(null, Typeface.NORMAL);
|
viewHolder.name.setTypeface(null, Typeface.NORMAL);
|
||||||
|
} else {
|
||||||
|
viewHolder.name.setTypeface(null, Typeface.BOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (draft != null) {
|
||||||
|
viewHolder.lastMessageIcon.setVisibility(View.GONE);
|
||||||
|
viewHolder.lastMessage.setText(EmojiWrapper.transform(draft.getMessage()));
|
||||||
|
viewHolder.sender.setText(R.string.draft);
|
||||||
|
viewHolder.sender.setVisibility(View.VISIBLE);
|
||||||
|
viewHolder.lastMessage.setTypeface(null, Typeface.NORMAL);
|
||||||
|
viewHolder.sender.setTypeface(null, Typeface.ITALIC);
|
||||||
|
} else {
|
||||||
final boolean fileAvailable = message.getTransferable() == null || message.getTransferable().getStatus() != Transferable.STATUS_DELETED;
|
final boolean fileAvailable = message.getTransferable() == null || message.getTransferable().getStatus() != Transferable.STATUS_DELETED;
|
||||||
final boolean showPreviewText;
|
final boolean showPreviewText;
|
||||||
if (fileAvailable && (message.isFileOrImage() || message.treatAsDownloadable() || message.isGeoUri())) {
|
if (fileAvailable && (message.isFileOrImage() || message.treatAsDownloadable() || message.isGeoUri())) {
|
||||||
|
@ -125,7 +162,7 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
}
|
}
|
||||||
viewHolder.lastMessage.setVisibility(showPreviewText ? View.VISIBLE : View.GONE);
|
viewHolder.lastMessage.setVisibility(showPreviewText ? View.VISIBLE : View.GONE);
|
||||||
if (preview.second) {
|
if (preview.second) {
|
||||||
if (conversation.isRead()) {
|
if (isRead) {
|
||||||
viewHolder.lastMessage.setTypeface(null, Typeface.ITALIC);
|
viewHolder.lastMessage.setTypeface(null, Typeface.ITALIC);
|
||||||
viewHolder.sender.setTypeface(null, Typeface.NORMAL);
|
viewHolder.sender.setTypeface(null, Typeface.NORMAL);
|
||||||
} else {
|
} else {
|
||||||
|
@ -133,7 +170,7 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
viewHolder.sender.setTypeface(null, Typeface.BOLD);
|
viewHolder.sender.setTypeface(null, Typeface.BOLD);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (conversation.isRead()) {
|
if (isRead) {
|
||||||
viewHolder.lastMessage.setTypeface(null, Typeface.NORMAL);
|
viewHolder.lastMessage.setTypeface(null, Typeface.NORMAL);
|
||||||
viewHolder.sender.setTypeface(null, Typeface.NORMAL);
|
viewHolder.sender.setTypeface(null, Typeface.NORMAL);
|
||||||
} else {
|
} else {
|
||||||
|
@ -154,6 +191,7 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
} else {
|
} else {
|
||||||
viewHolder.sender.setVisibility(View.GONE);
|
viewHolder.sender.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
long muted_till = conversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0);
|
long muted_till = conversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0);
|
||||||
if (muted_till == Long.MAX_VALUE) {
|
if (muted_till == Long.MAX_VALUE) {
|
||||||
|
@ -172,7 +210,13 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
viewHolder.notificationIcon.setImageResource(ic_notifications_none);
|
viewHolder.notificationIcon.setImageResource(ic_notifications_none);
|
||||||
}
|
}
|
||||||
|
|
||||||
viewHolder.timestamp.setText(UIHelper.readableTimeDifference(activity,conversation.getLatestMessage().getTimeSent()));
|
long timestamp;
|
||||||
|
if (draft != null) {
|
||||||
|
timestamp = draft.getTimestamp();
|
||||||
|
} else {
|
||||||
|
timestamp = conversation.getLatestMessage().getTimeSent();
|
||||||
|
}
|
||||||
|
viewHolder.timestamp.setText(UIHelper.readableTimeDifference(activity, timestamp));
|
||||||
loadAvatar(conversation, viewHolder.avatar);
|
loadAvatar(conversation, viewHolder.avatar);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
|
@ -184,6 +228,27 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
super.notifyDataSetChanged();
|
super.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadAvatar(Conversation conversation, ImageView imageView) {
|
||||||
|
if (cancelPotentialWork(conversation, imageView)) {
|
||||||
|
final Bitmap bm = activity.avatarService().get(conversation, activity.getPixel(56), true);
|
||||||
|
if (bm != null) {
|
||||||
|
cancelPotentialWork(conversation, imageView);
|
||||||
|
imageView.setImageBitmap(bm);
|
||||||
|
imageView.setBackgroundColor(0x00000000);
|
||||||
|
} else {
|
||||||
|
imageView.setBackgroundColor(UIHelper.getColorForName(conversation.getName().toString()));
|
||||||
|
imageView.setImageDrawable(null);
|
||||||
|
final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
|
||||||
|
final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
|
||||||
|
imageView.setImageDrawable(asyncDrawable);
|
||||||
|
try {
|
||||||
|
task.execute(conversation);
|
||||||
|
} catch (final RejectedExecutionException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class ViewHolder {
|
public static class ViewHolder {
|
||||||
private View swipeableItem;
|
private View swipeableItem;
|
||||||
private TextView name;
|
private TextView name;
|
||||||
|
@ -218,6 +283,19 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class AsyncDrawable extends BitmapDrawable {
|
||||||
|
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
|
||||||
|
|
||||||
|
public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
|
||||||
|
super(res, bitmap);
|
||||||
|
bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitmapWorkerTask getBitmapWorkerTask() {
|
||||||
|
return bitmapWorkerTaskReference.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class BitmapWorkerTask extends AsyncTask<Conversation, Void, Bitmap> {
|
class BitmapWorkerTask extends AsyncTask<Conversation, Void, Bitmap> {
|
||||||
private final WeakReference<ImageView> imageViewReference;
|
private final WeakReference<ImageView> imageViewReference;
|
||||||
private Conversation conversation = null;
|
private Conversation conversation = null;
|
||||||
|
@ -243,63 +321,4 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadAvatar(Conversation conversation, ImageView imageView) {
|
|
||||||
if (cancelPotentialWork(conversation, imageView)) {
|
|
||||||
final Bitmap bm = activity.avatarService().get(conversation, activity.getPixel(56), true);
|
|
||||||
if (bm != null) {
|
|
||||||
cancelPotentialWork(conversation, imageView);
|
|
||||||
imageView.setImageBitmap(bm);
|
|
||||||
imageView.setBackgroundColor(0x00000000);
|
|
||||||
} else {
|
|
||||||
imageView.setBackgroundColor(UIHelper.getColorForName(conversation.getName().toString()));
|
|
||||||
imageView.setImageDrawable(null);
|
|
||||||
final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
|
|
||||||
final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
|
|
||||||
imageView.setImageDrawable(asyncDrawable);
|
|
||||||
try {
|
|
||||||
task.execute(conversation);
|
|
||||||
} catch (final RejectedExecutionException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean cancelPotentialWork(Conversation conversation, ImageView imageView) {
|
|
||||||
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
|
|
||||||
|
|
||||||
if (bitmapWorkerTask != null) {
|
|
||||||
final Conversation oldConversation = bitmapWorkerTask.conversation;
|
|
||||||
if (oldConversation == null || conversation != oldConversation) {
|
|
||||||
bitmapWorkerTask.cancel(true);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
|
|
||||||
if (imageView != null) {
|
|
||||||
final Drawable drawable = imageView.getDrawable();
|
|
||||||
if (drawable instanceof AsyncDrawable) {
|
|
||||||
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
|
|
||||||
return asyncDrawable.getBitmapWorkerTask();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static class AsyncDrawable extends BitmapDrawable {
|
|
||||||
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
|
|
||||||
|
|
||||||
public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
|
|
||||||
super(res, bitmap);
|
|
||||||
bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BitmapWorkerTask getBitmapWorkerTask() {
|
|
||||||
return bitmapWorkerTaskReference.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -734,4 +734,5 @@
|
||||||
<string name="error_trustkey_hint_mutual">Hint: In some cases this can be fixed by adding each other your contact lists.</string>
|
<string name="error_trustkey_hint_mutual">Hint: In some cases this can be fixed by adding each other your contact lists.</string>
|
||||||
<string name="disable_encryption_message">Are you sure you want to disable OMEMO encryption for this conversation?\nThis will allow your server administrator to read your messages, but it might be the only way to communicate with people using outdated clients.</string>
|
<string name="disable_encryption_message">Are you sure you want to disable OMEMO encryption for this conversation?\nThis will allow your server administrator to read your messages, but it might be the only way to communicate with people using outdated clients.</string>
|
||||||
<string name="disable_now">Disable now</string>
|
<string name="disable_now">Disable now</string>
|
||||||
|
<string name="draft">Draft:</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue