aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2019-05-03 23:25:34 +0200
committerChristian Schneppe <christian@pix-art.de>2019-05-03 23:25:34 +0200
commit3abd3091ac6aa01b76bca5c6b17023d45fb084b8 (patch)
tree8a105cffc34caf7a90482e989c5d6aa95b4ebc6e /src
parentace3930d3ca1d56e679e8f38beb6a269d110b1a1 (diff)
introduced type private_file_message to handle attachments in PMs
Diffstat (limited to 'src')
-rw-r--r--src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java2
-rw-r--r--src/main/java/de/pixart/messenger/entities/Conversation.java4
-rw-r--r--src/main/java/de/pixart/messenger/entities/Message.java56
-rw-r--r--src/main/java/de/pixart/messenger/generator/MessageGenerator.java4
-rw-r--r--src/main/java/de/pixart/messenger/http/HttpDownloadConnection.java4
-rw-r--r--src/main/java/de/pixart/messenger/http/HttpUploadConnection.java4
-rw-r--r--src/main/java/de/pixart/messenger/parser/MessageParser.java6
-rw-r--r--src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java10
-rw-r--r--src/main/java/de/pixart/messenger/persistance/FileBackend.java11
-rw-r--r--src/main/java/de/pixart/messenger/services/NotificationService.java2
-rw-r--r--src/main/java/de/pixart/messenger/services/XmppConnectionService.java22
-rw-r--r--src/main/java/de/pixart/messenger/ui/ConversationFragment.java9
-rw-r--r--src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java103
-rw-r--r--src/main/res/layout/fragment_conversation.xml2
-rw-r--r--src/main/res/layout/message_content.xml28
15 files changed, 165 insertions, 102 deletions
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<ReadByMarker> 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<ReadByMarker> 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<String> uuids = new ArrayList<>();
@@ -891,7 +891,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
public List<FilePathInfo> 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<FilePathInfo> 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<FilePath> 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<FilePath> 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<Message> 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<Message> 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<Message> 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<Message> 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<Message> 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<Message> 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<Message> 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<Message> 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<Message> 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<Message> 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);
diff --git a/src/main/res/layout/fragment_conversation.xml b/src/main/res/layout/fragment_conversation.xml
index de16ae5c4..1da8a5b25 100644
--- a/src/main/res/layout/fragment_conversation.xml
+++ b/src/main/res/layout/fragment_conversation.xml
@@ -110,7 +110,7 @@
<android.support.v7.widget.RecyclerView
android:id="@+id/media_preview"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/message_bubble_sent"
android:orientation="horizontal"
diff --git a/src/main/res/layout/message_content.xml b/src/main/res/layout/message_content.xml
index bf96cef95..64414c893 100644
--- a/src/main/res/layout/message_content.xml
+++ b/src/main/res/layout/message_content.xml
@@ -2,6 +2,20 @@
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
+ <de.pixart.messenger.ui.widget.CopyTextView
+ android:id="@+id/message_body"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:autoLink="web"
+ android:longClickable="true"
+ android:textAppearance="@style/TextAppearance.Conversations.Body1" />
+
+ <de.pixart.messenger.ui.widget.RichLinkView
+ android:id="@+id/richLinkView"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxHeight="80dp" />
+
<com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/message_image"
android:layout_width="wrap_content"
@@ -28,20 +42,6 @@
android:scaleType="centerCrop"
app:riv_corner_radius="@dimen/rounded_image_border" />
- <de.pixart.messenger.ui.widget.RichLinkView
- android:id="@+id/richLinkView"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:maxHeight="80dp" />
-
- <de.pixart.messenger.ui.widget.CopyTextView
- android:id="@+id/message_body"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:autoLink="web"
- android:longClickable="true"
- android:textAppearance="@style/TextAppearance.Conversations.Body1" />
-
<Button
android:id="@+id/download_button"
android:layout_width="wrap_content"