From 3abd3091ac6aa01b76bca5c6b17023d45fb084b8 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Fri, 3 May 2019 23:25:34 +0200 Subject: introduced type private_file_message to handle attachments in PMs --- .../messenger/crypto/axolotl/AxolotlService.java | 2 +- .../de/pixart/messenger/entities/Conversation.java | 4 +- .../java/de/pixart/messenger/entities/Message.java | 56 ++++++++--- .../messenger/generator/MessageGenerator.java | 4 +- .../messenger/http/HttpDownloadConnection.java | 4 +- .../messenger/http/HttpUploadConnection.java | 4 +- .../de/pixart/messenger/parser/MessageParser.java | 6 +- .../messenger/persistance/DatabaseBackend.java | 10 +- .../pixart/messenger/persistance/FileBackend.java | 11 ++- .../messenger/services/NotificationService.java | 2 +- .../messenger/services/XmppConnectionService.java | 22 +++-- .../pixart/messenger/ui/ConversationFragment.java | 9 +- .../messenger/ui/adapter/MessageAdapter.java | 103 +++++++++++++-------- 13 files changed, 150 insertions(+), 87 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java b/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java index 1a3c4436e..3b3fda228 100644 --- a/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java +++ b/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java @@ -1326,7 +1326,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } final boolean success; - if (message.getType() == Message.TYPE_PRIVATE) { + if (message.isPrivateMessage()) { success = buildHeader(axolotlMessage, message.getTrueCounterpart()); } else { success = buildHeader(axolotlMessage, (Conversation) message.getConversation()); diff --git a/src/main/java/de/pixart/messenger/entities/Conversation.java b/src/main/java/de/pixart/messenger/entities/Conversation.java index acaf9b643..7e1a9e91a 100644 --- a/src/main/java/de/pixart/messenger/entities/Conversation.java +++ b/src/main/java/de/pixart/messenger/entities/Conversation.java @@ -548,7 +548,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl final Message message = messages.get(i); if (message.getStatus() <= Message.STATUS_RECEIVED && (message.markable || isPrivateAndNonAnonymousMuc) - && message.getType() != Message.TYPE_PRIVATE) { + && !message.isPrivateMessage()) { return message; } } @@ -929,7 +929,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl synchronized (this.messages) { for (int i = this.messages.size() - 1; i >= 0; --i) { final Message message = this.messages.get(i); - if (message.getType() == Message.TYPE_PRIVATE) { + if (message.isPrivateMessage()) { continue; //it's unsafe to use private messages as anchor. They could be coming from user archive } if (message.getStatus() == Message.STATUS_RECEIVED || message.isCarbon() || message.getServerMsgId() != null) { diff --git a/src/main/java/de/pixart/messenger/entities/Message.java b/src/main/java/de/pixart/messenger/entities/Message.java index a5f81ff5b..61ed8af6d 100644 --- a/src/main/java/de/pixart/messenger/entities/Message.java +++ b/src/main/java/de/pixart/messenger/entities/Message.java @@ -58,6 +58,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable public static final int TYPE_FILE = 2; public static final int TYPE_STATUS = 3; public static final int TYPE_PRIVATE = 4; + public static final int TYPE_PRIVATE_FILE = 5; public static final String CONVERSATION = "conversationUuid"; public static final String COUNTERPART = "counterpart"; @@ -153,12 +154,12 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable } protected Message(final Conversational conversation, final String uuid, final String conversationUUid, final Jid counterpart, - final Jid trueCounterpart, final String body, final long timeSent, - final int encryption, final int status, final int type, final boolean carbon, - final String remoteMsgId, final String relativeFilePath, - final String serverMsgId, final String fingerprint, final boolean read, final boolean deleted, - final String edited, final boolean oob, final String errorMessage, final Set readByMarkers, - final boolean markable, final boolean file_deleted) { + final Jid trueCounterpart, final String body, final long timeSent, + final int encryption, final int status, final int type, final boolean carbon, + final String remoteMsgId, final String relativeFilePath, + final String serverMsgId, final String fingerprint, final boolean read, final boolean deleted, + final String edited, final boolean oob, final String errorMessage, final Set readByMarkers, + final boolean markable, final boolean file_deleted) { this.conversation = conversation; this.uuid = uuid; this.conversationUuid = conversationUUid; @@ -264,7 +265,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable } else { values.put(TRUE_COUNTERPART, trueCounterpart.toString()); } - values.put(BODY, body.length() > Config.MAX_STORAGE_MESSAGE_CHARS ? body.substring(0,Config.MAX_STORAGE_MESSAGE_CHARS) : 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); @@ -504,8 +505,8 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable return Collections.unmodifiableSet(this.readByMarkers); } - public boolean similar(Message message) { - if (type != TYPE_PRIVATE && this.serverMsgId != null && message.getServerMsgId() != null) { + boolean similar(Message message) { + if (!isPrivateMessage() && this.serverMsgId != null && message.getServerMsgId() != null) { return this.serverMsgId.equals(message.getServerMsgId()); } else if (this.body == null || this.counterpart == null) { return false; @@ -526,7 +527,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable } return (message.getRemoteMsgId().equals(this.remoteMsgId) || message.getRemoteMsgId().equals(this.uuid)) && matchingCounterpart - && (body.equals(otherBody) ||(message.getEncryption() == Message.ENCRYPTION_PGP && hasUuid)); + && (body.equals(otherBody) || (message.getEncryption() == Message.ENCRYPTION_PGP && hasUuid)); } else { return this.remoteMsgId == null && matchingCounterpart @@ -605,7 +606,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable this.edited() == message.edited() && (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && this.getBody().length() + message.getBody().length() <= Config.MAX_DISPLAY_MESSAGE_CHARS && - !message.isGeoUri()&& + !message.isGeoUri() && !this.isGeoUri() && !message.isWebUri() && !this.isWebUri() && @@ -876,8 +877,12 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable this.mPreviousMessage = null; } + public boolean isPrivateMessage() { + return type == TYPE_PRIVATE || type == TYPE_PRIVATE_FILE; + } + public boolean isFileOrImage() { - return type == TYPE_FILE || type == TYPE_IMAGE; + return type == TYPE_FILE || type == TYPE_IMAGE || type == TYPE_PRIVATE_FILE; } public boolean hasFileOnRemoteHost() { @@ -955,4 +960,31 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable } return encryption; } + + public static boolean configurePrivateMessage(final Message message) { + return configurePrivateMessage(message, false); + } + + public static boolean configurePrivateFileMessage(final Message message) { + return configurePrivateMessage(message, true); + } + + private static boolean configurePrivateMessage(final Message message, final boolean isFile) { + final Conversation conversation; + if (message.conversation instanceof Conversation) { + conversation = (Conversation) message.conversation; + } else { + return false; + } + if (conversation.getMode() == Conversation.MODE_MULTI) { + final Jid nextCounterpart = conversation.getNextCounterpart(); + if (nextCounterpart != null) { + message.setCounterpart(nextCounterpart); + message.setTrueCounterpart(conversation.getMucOptions().getTrueCounterpart(nextCounterpart)); + message.setType(isFile ? Message.TYPE_PRIVATE_FILE : Message.TYPE_PRIVATE); + return true; + } + } + return false; + } } \ No newline at end of file diff --git a/src/main/java/de/pixart/messenger/generator/MessageGenerator.java b/src/main/java/de/pixart/messenger/generator/MessageGenerator.java index 7bc39dc2e..7c1caae04 100644 --- a/src/main/java/de/pixart/messenger/generator/MessageGenerator.java +++ b/src/main/java/de/pixart/messenger/generator/MessageGenerator.java @@ -45,7 +45,7 @@ public class MessageGenerator extends AbstractGenerator { if (this.mXmppConnectionService.indicateReceived() && !isWithSelf) { packet.addChild("request", "urn:xmpp:receipts"); } - } else if (message.getType() == Message.TYPE_PRIVATE) { //TODO files and images might be private as well + } else if (message.isPrivateMessage()) { packet.setTo(message.getCounterpart()); packet.setType(MessagePacket.TYPE_CHAT); packet.addChild("x", "http://jabber.org/protocol/muc#user"); @@ -56,7 +56,7 @@ public class MessageGenerator extends AbstractGenerator { packet.setTo(message.getCounterpart().asBareJid()); packet.setType(MessagePacket.TYPE_GROUPCHAT); } - if (conversation.isSingleOrPrivateAndNonAnonymous() && message.getType() != Message.TYPE_PRIVATE) { + if (conversation.isSingleOrPrivateAndNonAnonymous() && !message.isPrivateMessage()) { packet.addChild("markable", "urn:xmpp:chat-markers:0"); } packet.setFrom(account.getJid()); diff --git a/src/main/java/de/pixart/messenger/http/HttpDownloadConnection.java b/src/main/java/de/pixart/messenger/http/HttpDownloadConnection.java index 457292e27..c53919784 100644 --- a/src/main/java/de/pixart/messenger/http/HttpDownloadConnection.java +++ b/src/main/java/de/pixart/messenger/http/HttpDownloadConnection.java @@ -50,6 +50,7 @@ public class HttpDownloadConnection implements Transferable { private Method method = Method.HTTP_UPLOAD; private final SimpleDateFormat fileDateFormat = new SimpleDateFormat("yyyyMMdd_HHmmssSSS", Locale.US); + HttpDownloadConnection(Message message, HttpConnectionManager manager) { this.message = message; this.mHttpConnectionManager = manager; @@ -450,7 +451,8 @@ public class HttpDownloadConnection implements Transferable { } private void updateImageBounds() { - message.setType(Message.TYPE_FILE); + final boolean privateMessage = message.isPrivateMessage(); + message.setType(privateMessage ? Message.TYPE_PRIVATE_FILE : Message.TYPE_FILE); final URL url; final String ref = mUrl.getRef(); if (method == Method.P1_S3) { diff --git a/src/main/java/de/pixart/messenger/http/HttpUploadConnection.java b/src/main/java/de/pixart/messenger/http/HttpUploadConnection.java index 92ccf86e1..54d6fcb1a 100644 --- a/src/main/java/de/pixart/messenger/http/HttpUploadConnection.java +++ b/src/main/java/de/pixart/messenger/http/HttpUploadConnection.java @@ -216,7 +216,9 @@ public class HttpUploadConnection implements Transferable { mXmppConnectionService.getFileBackend().updateFileParams(message, get); mXmppConnectionService.getFileBackend().updateMediaScanner(file); finish(); - message.setCounterpart(message.getConversation().getJid().asBareJid()); + if (!message.isPrivateMessage()) { + message.setCounterpart(message.getConversation().getJid().asBareJid()); + } mXmppConnectionService.resendMessage(message, delayed); } else { Log.d(Config.LOGTAG, "http upload failed because response code was " + code); diff --git a/src/main/java/de/pixart/messenger/parser/MessageParser.java b/src/main/java/de/pixart/messenger/parser/MessageParser.java index 38ed21a3a..d67e84371 100644 --- a/src/main/java/de/pixart/messenger/parser/MessageParser.java +++ b/src/main/java/de/pixart/messenger/parser/MessageParser.java @@ -658,7 +658,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece mXmppConnectionService.updateMessage(replacedMessage, uuid); if (mXmppConnectionService.confirmMessages() && replacedMessage.getStatus() == Message.STATUS_RECEIVED - && (replacedMessage.trusted() || replacedMessage.getType() == Message.TYPE_PRIVATE) + && (replacedMessage.trusted() || replacedMessage.isPrivateMessage()) //TODO do we really want to send receipts for all PMs? && remoteMsgId != null && !selfAddressed && !isTypeGroupChat) { @@ -684,7 +684,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece } boolean checkForDuplicates = (isTypeGroupChat && packet.hasChild("delay", "urn:xmpp:delay")) - || message.getType() == Message.TYPE_PRIVATE + || message.isPrivateMessage() || message.getServerMsgId() != null || (query == null && mXmppConnectionService.getMessageArchiveService().isCatchupInProgress(conversation)); if (checkForDuplicates) { @@ -744,7 +744,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece if (mXmppConnectionService.confirmMessages() && message.getStatus() == Message.STATUS_RECEIVED - && (message.trusted() || message.getType() == Message.TYPE_PRIVATE) + && (message.trusted() || message.isPrivateMessage()) && remoteMsgId != null && !selfAddressed && !isTypeGroupChat) { diff --git a/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java b/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java index e2c83321d..37f577079 100644 --- a/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java +++ b/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java @@ -841,14 +841,14 @@ public class DatabaseBackend extends SQLiteOpenHelper { if (internal) { final String name = file.getName(); if (name.endsWith(".pgp")) { - selection = "(" + Message.RELATIVE_FILE_PATH + " IN(?,?) OR (" + Message.RELATIVE_FILE_PATH + "=? and encryption in(1,4))) and type in (1,2)"; + selection = "(" + Message.RELATIVE_FILE_PATH + " IN(?,?) OR (" + Message.RELATIVE_FILE_PATH + "=? and encryption in(1,4))) and type in (1,2,5)"; selectionArgs = new String[]{file.getAbsolutePath(), name, name.substring(0, name.length() - 4)}; } else { - selection = Message.RELATIVE_FILE_PATH + " IN(?,?) and type in (1,2)"; + selection = Message.RELATIVE_FILE_PATH + " IN(?,?) and type in (1,2,5)"; selectionArgs = new String[]{file.getAbsolutePath(), name}; } } else { - selection = Message.RELATIVE_FILE_PATH + "=? and type in (1,2)"; + selection = Message.RELATIVE_FILE_PATH + "=? and type in (1,2,5)"; selectionArgs = new String[]{file.getAbsolutePath()}; } final List uuids = new ArrayList<>(); @@ -891,7 +891,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { public List getFilePathInfo() { final SQLiteDatabase db = this.getReadableDatabase(); - final Cursor cursor = db.query(Message.TABLENAME, new String[]{Message.UUID, Message.RELATIVE_FILE_PATH, Message.FILE_DELETED}, "type in (1,2) and " + Message.RELATIVE_FILE_PATH + " is not null", null, null, null, null); + final Cursor cursor = db.query(Message.TABLENAME, new String[]{Message.UUID, Message.RELATIVE_FILE_PATH, Message.DELETED}, "type in (1,2,5) and "+Message.RELATIVE_FILE_PATH+" is not null", null, null, null, null); final List list = new ArrayList<>(); while (cursor != null && cursor.moveToNext()) { list.add(new FilePathInfo(cursor.getString(0), cursor.getString(1), cursor.getInt(2) > 0)); @@ -904,7 +904,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { public List getRelativeFilePaths(String account, Jid jid, int limit) { SQLiteDatabase db = this.getReadableDatabase(); - final String SQL = "select uuid,relativeFilePath from messages where type in (1,2) and file_deleted=0 and " + Message.RELATIVE_FILE_PATH + " is not null and conversationUuid=(select uuid from conversations where accountUuid=? and (contactJid=? or contactJid like ?)) order by timeSent desc"; + final String SQL = "select uuid,relativeFilePath from messages where type in (1,2,5) and deleted=0 and " + Message.RELATIVE_FILE_PATH + " is not null and conversationUuid=(select uuid from conversations where accountUuid=? and (contactJid=? or contactJid like ?)) order by timeSent desc"; final String[] args = {account, jid.toEscapedString(), jid.toEscapedString() + "/%"}; Cursor cursor = db.rawQuery(SQL + (limit > 0 ? " limit " + String.valueOf(limit) : ""), args); List filesPaths = new ArrayList<>(); diff --git a/src/main/java/de/pixart/messenger/persistance/FileBackend.java b/src/main/java/de/pixart/messenger/persistance/FileBackend.java index e255ff225..3eaa9e406 100644 --- a/src/main/java/de/pixart/messenger/persistance/FileBackend.java +++ b/src/main/java/de/pixart/messenger/persistance/FileBackend.java @@ -350,7 +350,7 @@ public class FileBackend { if ((size == 0 || size >= mXmppConnectionService.getCompressImageSizePreference()) && mXmppConnectionService.getCompressImageSizePreference() != 0) { return false; } - if (mXmppConnectionService.getCompressImageResolutionPreference() == 0 && mXmppConnectionService.getCompressImageSizePreference() == 0 ) { + if (mXmppConnectionService.getCompressImageResolutionPreference() == 0 && mXmppConnectionService.getCompressImageSizePreference() == 0) { return true; } BitmapFactory.Options options = new BitmapFactory.Options(); @@ -679,7 +679,7 @@ public class FileBackend { frame = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); frame.eraseColor(0xff000000); } - drawOverlay(frame,R.drawable.play_video,0.75f); + drawOverlay(frame, R.drawable.play_video, 0.75f); return frame; } @@ -1036,6 +1036,7 @@ public class FileBackend { public void updateFileParams(Message message, URL url) { DownloadableFile file = getFile(message); final String mime = file.getMimeType(); + final boolean privateMessage = message.isPrivateMessage(); final boolean image = message.getType() == Message.TYPE_IMAGE || (mime != null && mime.startsWith("image/")); final boolean video = mime != null && mime.startsWith("video/"); final boolean audio = mime != null && mime.startsWith("audio/"); @@ -1065,7 +1066,7 @@ public class FileBackend { } message.setBody(body.toString()); message.setFileDeleted(false); - message.setType(image ? Message.TYPE_IMAGE : Message.TYPE_FILE); + message.setType(privateMessage ? Message.TYPE_PRIVATE_FILE : (image ? Message.TYPE_IMAGE : Message.TYPE_FILE)); } private int getMediaRuntime(File file) { @@ -1078,7 +1079,7 @@ public class FileBackend { } } - private String getAPK (File file, Context context) { + private String getAPK(File file, Context context) { String APKName; final PackageManager pm = context.getPackageManager(); final PackageInfo pi = pm.getPackageArchiveInfo(file.toString(), 0); @@ -1107,7 +1108,7 @@ public class FileBackend { return APKName; } - private String getVCard (File file) { + private String getVCard(File file) { VCard VCard = new VCard(); String VCardName = ""; try { diff --git a/src/main/java/de/pixart/messenger/services/NotificationService.java b/src/main/java/de/pixart/messenger/services/NotificationService.java index 40c848c66..27a33382d 100644 --- a/src/main/java/de/pixart/messenger/services/NotificationService.java +++ b/src/main/java/de/pixart/messenger/services/NotificationService.java @@ -876,7 +876,7 @@ public class NotificationService { return false; } final Matcher m = highlight.matcher(message.getBody()); - return (m.find() || message.getType() == Message.TYPE_PRIVATE); + return (m.find() || message.isPrivateMessage()); } else { return false; } diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java index 5917cc725..d9be63dd7 100644 --- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java +++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java @@ -505,9 +505,7 @@ public class XmppConnectionService extends Service { encryption = Message.ENCRYPTION_DECRYPTED; } Message message = new Message(conversation, uri.toString(), encryption); - if (conversation.getNextCounterpart() != null) { - message.setCounterpart(conversation.getNextCounterpart()); - } + Message.configurePrivateMessage(message); if (encryption == Message.ENCRYPTION_DECRYPTED) { getPgpEngine().encrypt(message, callback); } else { @@ -523,8 +521,12 @@ public class XmppConnectionService extends Service { } else { message = new Message(conversation, "", conversation.getNextEncryption()); } - message.setCounterpart(conversation.getNextCounterpart()); - message.setType(Message.TYPE_FILE); + if (!Message.configurePrivateFileMessage(message)) { + message.setCounterpart(conversation.getNextCounterpart()); + message.setType(Message.TYPE_FILE); + } + Log.d(Config.LOGTAG, "attachFile: type=" + message.getType()); + Log.d(Config.LOGTAG, "counterpart=" + message.getCounterpart()); final AttachFileToConversationRunnable runnable = new AttachFileToConversationRunnable(this, uri, type, message, callback); if (runnable.isVideoMessage()) { mVideoCompressionExecutor.execute(runnable); @@ -551,8 +553,11 @@ public class XmppConnectionService extends Service { } else { message = new Message(conversation, "", conversation.getNextEncryption()); } - message.setCounterpart(conversation.getNextCounterpart()); - message.setType(Message.TYPE_IMAGE); + if (!Message.configurePrivateFileMessage(message)) { + message.setCounterpart(conversation.getNextCounterpart()); + message.setType(Message.TYPE_IMAGE); + } + Log.d(Config.LOGTAG, "attachImage: type=" + message.getType()); mFileAddingExecutor.execute(() -> { try { getFileBackend().copyImageToPrivateStorage(message, uri); @@ -1618,7 +1623,7 @@ public class XmppConnectionService extends Service { } } - boolean mucMessage = conversation.getMode() == Conversation.MODE_MULTI && message.getType() != Message.TYPE_PRIVATE; + boolean mucMessage = conversation.getMode() == Conversation.MODE_MULTI && !message.isPrivateMessage(); if (mucMessage) { message.setCounterpart(conversation.getMucOptions().getSelf().getFullJid()); } @@ -1651,6 +1656,7 @@ public class XmppConnectionService extends Service { packet.addChild(ChatState.toElement(conversation.getOutgoingChatState())); } } + Log.d(Config.LOGTAG, packet.toString()); sendMessagePacket(account, packet); } } diff --git a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java index 35cea93e5..d16fad5c5 100644 --- a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java +++ b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java @@ -878,14 +878,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke final Message message; if (conversation.getCorrectingMessage() == null) { message = new Message(conversation, body, conversation.getNextEncryption()); - if (conversation.getMode() == Conversation.MODE_MULTI) { - final Jid nextCounterpart = conversation.getNextCounterpart(); - if (nextCounterpart != null) { - message.setCounterpart(nextCounterpart); - message.setTrueCounterpart(conversation.getMucOptions().getTrueCounterpart(nextCounterpart)); - message.setType(Message.TYPE_PRIVATE); - } - } + Message.configurePrivateMessage(message); } else { message = conversation.getCorrectingMessage(); message.setBody(body); diff --git a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java index b3fd88041..fcc317de9 100644 --- a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java +++ b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java @@ -36,6 +36,7 @@ import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; +import com.google.common.base.Strings; import com.squareup.picasso.Picasso; import java.io.UnsupportedEncodingException; @@ -81,6 +82,7 @@ import de.pixart.messenger.utils.StylingHelper; import de.pixart.messenger.utils.UIHelper; import de.pixart.messenger.xmpp.mam.MamReference; import pl.droidsonroids.gif.GifImageView; +import rocks.xmpp.addr.Jid; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static de.pixart.messenger.ui.SettingsActivity.PLAY_GIF_INSIDE; @@ -546,23 +548,17 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie body.setSpan(new DividerSpan(true), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } boolean startsWithQuote = handleTextQuotes(body, darkBackground); - if (message.getType() != Message.TYPE_PRIVATE) { + if (!message.isPrivateMessage()) { if (hasMeCommand) { body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } else { String privateMarker; if (message.getStatus() <= Message.STATUS_RECEIVED) { - privateMarker = activity - .getString(R.string.private_message); + privateMarker = activity.getString(R.string.private_message); } else { - final String to; - if (message.getCounterpart() != null) { - to = message.getCounterpart().getResource(); - } else { - to = ""; - } - privateMarker = activity.getString(R.string.private_message_to, to); + Jid cp = message.getCounterpart(); + privateMarker = activity.getString(R.string.private_message_to, Strings.nullToEmpty(cp == null ? null : cp.getResource())); } body.insert(0, privateMarker); int privateMarkerIndex = privateMarker.length(); @@ -612,24 +608,24 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie } } - private void displayDownloadableMessage(ViewHolder viewHolder, final Message message, String text) { + private void displayDownloadableMessage(ViewHolder viewHolder, final Message message, String text, final boolean darkBackground) { + toggleWhisperInfo(viewHolder, message, false, darkBackground); viewHolder.audioPlayer.setVisibility(View.GONE); viewHolder.image.setVisibility(View.GONE); viewHolder.gifImage.setVisibility(View.GONE); viewHolder.richlinkview.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.GONE); viewHolder.download_button.setVisibility(View.VISIBLE); viewHolder.download_button.setText(text); viewHolder.download_button.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_download_grey600_48dp, 0, 0, 0); viewHolder.download_button.setOnClickListener(v -> ConversationFragment.downloadFile(activity, message)); } - private void displayOpenableMessage(ViewHolder viewHolder, final Message message) { + private void displayOpenableMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground) { + toggleWhisperInfo(viewHolder, message, false, darkBackground); viewHolder.audioPlayer.setVisibility(View.GONE); viewHolder.image.setVisibility(View.GONE); viewHolder.gifImage.setVisibility(View.GONE); viewHolder.richlinkview.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.GONE); viewHolder.download_button.setVisibility(View.VISIBLE); final String mimeType = message.getMimeType(); if (mimeType != null) { @@ -690,21 +686,11 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie } private void displayRichLinkMessage(ViewHolder viewHolder, final Message message, boolean darkBackground) { + toggleWhisperInfo(viewHolder, message, true, darkBackground); viewHolder.audioPlayer.setVisibility(View.GONE); viewHolder.image.setVisibility(View.GONE); viewHolder.gifImage.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.VISIBLE); Editable body = new SpannableStringBuilder(message.getBody()); - if (darkBackground) { - viewHolder.messageBody.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Body1_OnDark); - } else { - viewHolder.messageBody.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Body1); - } - MyLinkify.addLinks(body, false); - viewHolder.messageBody.setAutoLinkMask(0); - viewHolder.messageBody.setText(EmojiWrapper.transform(body)); - viewHolder.messageBody.setTextIsSelectable(true); - viewHolder.messageBody.setMovementMethod(ClickableMovementMethod.getInstance()); listSelectionManager.onUpdate(viewHolder.messageBody, message); final boolean dataSaverDisabled = activity.xmppConnectionService.isDataSaverDisabled(); viewHolder.richlinkview.setVisibility(View.VISIBLE); @@ -746,9 +732,9 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie } } - private void displayLocationMessage(ViewHolder viewHolder, final Message message) { + private void displayLocationMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground) { + toggleWhisperInfo(viewHolder, message, false, darkBackground); viewHolder.audioPlayer.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.GONE); String url = GeoHelper.MapPreviewUri(message); viewHolder.gifImage.setVisibility(View.GONE); viewHolder.richlinkview.setVisibility(View.GONE); @@ -790,10 +776,10 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie } private void displayAudioMessage(ViewHolder viewHolder, Message message, boolean darkBackground) { + toggleWhisperInfo(viewHolder, message, false, darkBackground); viewHolder.image.setVisibility(View.GONE); viewHolder.gifImage.setVisibility(View.GONE); viewHolder.richlinkview.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.GONE); viewHolder.download_button.setVisibility(View.GONE); final RelativeLayout audioPlayer = viewHolder.audioPlayer; audioPlayer.setVisibility(View.VISIBLE); @@ -801,9 +787,9 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie this.audioPlayer.init(audioPlayer, message); } - private void displayImageMessage(ViewHolder viewHolder, final Message message) { + private void displayImageMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground) { + toggleWhisperInfo(viewHolder, message, false, darkBackground); viewHolder.download_button.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.GONE); viewHolder.audioPlayer.setVisibility(View.GONE); viewHolder.richlinkview.setVisibility(View.GONE); DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message); @@ -866,6 +852,44 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie } } + private void toggleWhisperInfo(ViewHolder viewHolder, final Message message, final boolean includeBody, final boolean darkBackground) { + Editable body; + if (message.isPrivateMessage()) { + final String privateMarker; + if (message.getStatus() <= Message.STATUS_RECEIVED) { + privateMarker = activity.getString(R.string.private_message); + } else { + Jid cp = message.getCounterpart(); + privateMarker = activity.getString(R.string.private_message_to, Strings.nullToEmpty(cp == null ? null : cp.getResource())); + } + body = new SpannableStringBuilder(privateMarker); + if (includeBody) { + body.append("\n"); + body.append(message.getBody()); + MyLinkify.addLinks(body, false); + viewHolder.messageBody.setAutoLinkMask(0); + viewHolder.messageBody.setTextIsSelectable(true); + viewHolder.messageBody.setMovementMethod(ClickableMovementMethod.getInstance()); + } + body.setSpan(new ForegroundColorSpan(getMessageTextColor(darkBackground, false)), 0, privateMarker.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + body.setSpan(new StyleSpan(Typeface.BOLD), 0, privateMarker.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + viewHolder.messageBody.setText(body); + viewHolder.messageBody.setVisibility(View.VISIBLE); + } else { + if (includeBody) { + body = new SpannableStringBuilder(message.getBody()); + MyLinkify.addLinks(body, false); + viewHolder.messageBody.setVisibility(View.VISIBLE); + viewHolder.messageBody.setText(body); + viewHolder.messageBody.setAutoLinkMask(0); + viewHolder.messageBody.setTextIsSelectable(true); + viewHolder.messageBody.setMovementMethod(ClickableMovementMethod.getInstance()); + } else { + viewHolder.messageBody.setVisibility(View.GONE); + } + } + } + private void loadMoreMessages(Conversation conversation) { conversation.setLastClearHistory(0, null); activity.xmppConnectionService.updateConversation(conversation); @@ -1022,19 +1046,19 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie final Transferable transferable = message.getTransferable(); if (message.isFileDeleted() || (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING)) { if (transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER) { - displayDownloadableMessage(viewHolder, message, activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message))); + displayDownloadableMessage(viewHolder, message, activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message)), darkBackground); } else if (transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER_CHECK_FILESIZE) { - displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message))); + displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message)), darkBackground); } else { displayInfoMessage(viewHolder, UIHelper.getMessagePreview(activity, message).first, darkBackground); } } else if (message.isFileOrImage() && message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED) { if (message.getFileParams().width > 0 && message.getFileParams().height > 0) { - displayImageMessage(viewHolder, message); + displayImageMessage(viewHolder, message, darkBackground); } else if (message.getFileParams().runtime > 0) { displayAudioMessage(viewHolder, message, darkBackground); } else { - displayOpenableMessage(viewHolder, message); + displayOpenableMessage(viewHolder, message, darkBackground); } } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { if (account.isPgpDecryptionServiceConnected()) { @@ -1056,7 +1080,7 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie displayInfoMessage(viewHolder, activity.getString(R.string.omemo_decryption_failed), darkBackground); } else { if (message.isGeoUri()) { - displayLocationMessage(viewHolder, message); + displayLocationMessage(viewHolder, message, darkBackground); } else if (message.bodyIsOnlyEmojis() && message.getType() != Message.TYPE_PRIVATE) { displayEmojiMessage(viewHolder, message.getBody().trim(), darkBackground); } else if (message.isXmppUri()) { @@ -1068,19 +1092,22 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, - UIHelper.getFileDescriptionString(activity, message))); + UIHelper.getFileDescriptionString(activity, message)), + darkBackground); } else { displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize_on_host, UIHelper.getFileDescriptionString(activity, message), - url.getHost())); + url.getHost()), + darkBackground); } } catch (Exception e) { displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, - UIHelper.getFileDescriptionString(activity, message))); + UIHelper.getFileDescriptionString(activity, message)), + darkBackground); } } else if (message.isWebUri()) { displayRichLinkMessage(viewHolder, message, darkBackground); -- cgit v1.2.3