Merge branch 'image-attachments'

* image-attachments:
  Downloadable gets priority over emojis only
  Display both message body and media, where relevant
  Store oobUri and preserve message body
This commit is contained in:
Stephen Paul Weber 2022-03-08 16:19:55 -05:00
commit 426a4770f3
No known key found for this signature in database
GPG key ID: D11C2911CE519CDE
8 changed files with 142 additions and 77 deletions

View file

@ -44,7 +44,7 @@ public class IndividualMessage extends Message {
} }
private IndividualMessage(Conversational conversation, String uuid, String conversationUUid, Jid counterpart, Jid trueCounterpart, String body, long timeSent, int encryption, int status, int type, boolean carbon, String remoteMsgId, String relativeFilePath, String serverMsgId, String fingerprint, boolean read, String edited, boolean oob, String errorMessage, Set<ReadByMarker> readByMarkers, boolean markable, boolean deleted, String bodyLanguage) { private IndividualMessage(Conversational conversation, String uuid, String conversationUUid, Jid counterpart, Jid trueCounterpart, String body, long timeSent, int encryption, int status, int type, boolean carbon, String remoteMsgId, String relativeFilePath, String serverMsgId, String fingerprint, boolean read, String edited, boolean oob, String errorMessage, Set<ReadByMarker> readByMarkers, boolean markable, boolean deleted, String bodyLanguage) {
super(conversation, uuid, conversationUUid, counterpart, trueCounterpart, body, timeSent, encryption, status, type, carbon, remoteMsgId, relativeFilePath, serverMsgId, fingerprint, read, edited, oob, errorMessage, readByMarkers, markable, deleted, bodyLanguage, null); super(conversation, uuid, conversationUUid, counterpart, trueCounterpart, body, timeSent, encryption, status, type, carbon, remoteMsgId, relativeFilePath, serverMsgId, fingerprint, read, edited, oob, errorMessage, readByMarkers, markable, deleted, bodyLanguage, null, null, null);
} }
@Override @Override

View file

@ -13,6 +13,8 @@ import com.google.common.primitives.Longs;
import org.json.JSONException; import org.json.JSONException;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -101,7 +103,8 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
protected int type; protected int type;
protected boolean deleted = false; protected boolean deleted = false;
protected boolean carbon = false; protected boolean carbon = false;
protected boolean oob = false; private boolean oob = false;
protected URI oobUri = null;
protected List<Edit> edits = new ArrayList<>(); protected List<Edit> edits = new ArrayList<>();
protected String relativeFilePath; protected String relativeFilePath;
protected boolean read = true; protected boolean read = true;
@ -154,6 +157,8 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
false, false,
false, false,
null, null,
null,
null,
null); null);
} }
@ -180,6 +185,8 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
false, false,
false, false,
null, null,
null,
null,
null); null);
} }
@ -189,7 +196,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
final String remoteMsgId, final String relativeFilePath, final String remoteMsgId, final String relativeFilePath,
final String serverMsgId, final String fingerprint, final boolean read, final String serverMsgId, final String fingerprint, final boolean read,
final String edited, final boolean oob, final String errorMessage, final Set<ReadByMarker> readByMarkers, final String edited, final boolean oob, final String errorMessage, final Set<ReadByMarker> readByMarkers,
final boolean markable, final boolean deleted, final String bodyLanguage, final String subject) { final boolean markable, final boolean deleted, final String bodyLanguage, final String subject, final String oobUri, final String fileParams) {
this.conversation = conversation; this.conversation = conversation;
this.uuid = uuid; this.uuid = uuid;
this.conversationUuid = conversationUUid; this.conversationUuid = conversationUUid;
@ -207,6 +214,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
this.axolotlFingerprint = fingerprint; this.axolotlFingerprint = fingerprint;
this.read = read; this.read = read;
this.edits = Edit.fromJson(edited); this.edits = Edit.fromJson(edited);
setOob(oobUri);
this.oob = oob; this.oob = oob;
this.errorMessage = errorMessage; this.errorMessage = errorMessage;
this.readByMarkers = readByMarkers == null ? new CopyOnWriteArraySet<>() : readByMarkers; this.readByMarkers = readByMarkers == null ? new CopyOnWriteArraySet<>() : readByMarkers;
@ -214,6 +222,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
this.deleted = deleted; this.deleted = deleted;
this.bodyLanguage = bodyLanguage; this.bodyLanguage = bodyLanguage;
this.subject = subject; this.subject = subject;
if (fileParams != null) this.fileParams = new FileParams(fileParams);
} }
public static Message fromCursor(Cursor cursor, Conversation conversation) { public static Message fromCursor(Cursor cursor, Conversation conversation) {
@ -240,7 +249,9 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
cursor.getInt(cursor.getColumnIndex(MARKABLE)) > 0, cursor.getInt(cursor.getColumnIndex(MARKABLE)) > 0,
cursor.getInt(cursor.getColumnIndex(DELETED)) > 0, cursor.getInt(cursor.getColumnIndex(DELETED)) > 0,
cursor.getString(cursor.getColumnIndex(BODY_LANGUAGE)), cursor.getString(cursor.getColumnIndex(BODY_LANGUAGE)),
cursor.getString(cursor.getColumnIndex("subject")) cursor.getString(cursor.getColumnIndex("subject")),
cursor.getString(cursor.getColumnIndex("oobUri")),
cursor.getString(cursor.getColumnIndex("fileParams"))
); );
} }
@ -274,6 +285,8 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(UUID, uuid); values.put(UUID, uuid);
values.put("subject", subject); values.put("subject", subject);
values.put("oobUri", oobUri == null ? null : oobUri.toString());
values.put("fileParams", fileParams == null ? null : fileParams.toString());
return values; return values;
} }
@ -347,7 +360,11 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
} }
public String getBody() { public String getBody() {
return body; if (oobUri != null) {
return body.replace(oobUri.toString(), "");
} else {
return body;
}
} }
public synchronized void setBody(String body) { public synchronized void setBody(String body) {
@ -358,7 +375,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
this.isGeoUri = null; this.isGeoUri = null;
this.isEmojisOnly = null; this.isEmojisOnly = null;
this.treatAsDownloadable = null; this.treatAsDownloadable = null;
this.fileParams = null;
} }
public String getSubject() { public String getSubject() {
@ -523,7 +539,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
} }
public synchronized void setTransferable(Transferable transferable) { public synchronized void setTransferable(Transferable transferable) {
this.fileParams = null;
this.transferable = transferable; this.transferable = transferable;
} }
@ -711,14 +726,14 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
} }
public boolean isOOb() { public boolean isOOb() {
return oob; return oob || oobUri != null;
} }
public static class MergeSeparator { public static class MergeSeparator {
} }
public SpannableStringBuilder getMergedBody() { public SpannableStringBuilder getMergedBody() {
SpannableStringBuilder body = new SpannableStringBuilder(MessageUtils.filterLtrRtl(this.body).trim()); SpannableStringBuilder body = new SpannableStringBuilder(MessageUtils.filterLtrRtl(getBody()).trim());
Message current = this; Message current = this;
while (current.mergeable(current.next())) { while (current.mergeable(current.next())) {
current = current.next(); current = current.next();
@ -806,8 +821,17 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
} }
} }
public void setOob(boolean isOob) { public URI getOob() {
this.oob = isOob; return oobUri;
}
public void setOob(String oobUri) {
try {
this.oobUri = oobUri == null ? null : new URI(oobUri);
} catch (final URISyntaxException e) {
this.oobUri = null;
}
this.oob = this.oobUri != null;
} }
public String getMimeType() { public String getMimeType() {
@ -815,7 +839,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
if (relativeFilePath != null) { if (relativeFilePath != null) {
extension = MimeUtils.extractRelevantExtension(relativeFilePath); extension = MimeUtils.extractRelevantExtension(relativeFilePath);
} else { } else {
final String url = URL.tryParse(body.split("\n")[0]); final String url = URL.tryParse(oobUri == null ? body.split("\n")[0] : oobUri.toString());
if (url == null) { if (url == null) {
return null; return null;
} }
@ -826,14 +850,14 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
public synchronized boolean treatAsDownloadable() { public synchronized boolean treatAsDownloadable() {
if (treatAsDownloadable == null) { if (treatAsDownloadable == null) {
treatAsDownloadable = MessageUtils.treatAsDownloadable(this.body, this.oob); treatAsDownloadable = MessageUtils.treatAsDownloadable(this.body, isOOb());
} }
return treatAsDownloadable; return treatAsDownloadable;
} }
public synchronized boolean bodyIsOnlyEmojis() { public synchronized boolean bodyIsOnlyEmojis() {
if (isEmojisOnly == null) { if (isEmojisOnly == null) {
isEmojisOnly = Emoticons.isOnlyEmoji(body.replaceAll("\\s", "")); isEmojisOnly = Emoticons.isOnlyEmoji(getBody().replaceAll("\\s", ""));
} }
return isEmojisOnly; return isEmojisOnly;
} }
@ -849,35 +873,19 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
this.fileParams = null; this.fileParams = null;
} }
public synchronized void setFileParams(FileParams fileParams) {
this.fileParams = fileParams;
}
public synchronized FileParams getFileParams() { public synchronized FileParams getFileParams() {
if (fileParams == null) { if (fileParams == null) {
fileParams = new FileParams(); fileParams = new FileParams(this.body);
if (this.transferable != null) { if (this.transferable != null) {
fileParams.size = this.transferable.getFileSize(); fileParams.size = this.transferable.getFileSize();
} }
final String[] parts = body == null ? new String[0] : body.split("\\|");
switch (parts.length) { if (oobUri != null && ("http".equalsIgnoreCase(oobUri.getScheme()) || "https".equalsIgnoreCase(oobUri.getScheme()))) {
case 1: fileParams.url = oobUri.toString();
try {
fileParams.size = Long.parseLong(parts[0]);
} catch (final NumberFormatException e) {
fileParams.url = URL.tryParse(parts[0]);
}
break;
case 5:
fileParams.runtime = parseInt(parts[4]);
case 4:
fileParams.width = parseInt(parts[2]);
fileParams.height = parseInt(parts[3]);
case 2:
fileParams.url = URL.tryParse(parts[0]);
fileParams.size = Longs.tryParse(parts[1]);
break;
case 3:
fileParams.size = Longs.tryParse(parts[0]);
fileParams.width = parseInt(parts[1]);
fileParams.height = parseInt(parts[2]);
break;
} }
} }
return fileParams; return fileParams;
@ -924,9 +932,48 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
public int height = 0; public int height = 0;
public int runtime = 0; public int runtime = 0;
public FileParams() { }
public FileParams(String ser) {
final String[] parts = ser == null ? new String[0] : ser.split("\\|");
switch (parts.length) {
case 1:
try {
this.size = Long.parseLong(parts[0]);
} catch (final NumberFormatException e) {
this.url = URL.tryParse(parts[0]);
}
break;
case 5:
this.runtime = parseInt(parts[4]);
case 4:
this.width = parseInt(parts[2]);
this.height = parseInt(parts[3]);
case 2:
this.url = URL.tryParse(parts[0]);
this.size = Longs.tryParse(parts[1]);
break;
case 3:
this.size = Longs.tryParse(parts[0]);
this.width = parseInt(parts[1]);
this.height = parseInt(parts[2]);
break;
}
}
public long getSize() { public long getSize() {
return size == null ? 0 : size; return size == null ? 0 : size;
} }
public String toString() {
final StringBuilder builder = new StringBuilder();
if (url != null) builder.append(url);
if (size != null) builder.append('|').append(size.toString());
if (width > 0 || height > 0 || runtime > 0) builder.append('|').append(width);
if (height > 0 || runtime > 0) builder.append('|').append(height);
if (runtime > 0) builder.append('|').append(runtime);
return builder.toString();
}
} }
public void setFingerprint(String fingerprint) { public void setFingerprint(String fingerprint) {

View file

@ -68,22 +68,22 @@ public class HttpDownloadConnection implements Transferable {
} }
public void init(boolean interactive) { public void init(boolean interactive) {
final Message.FileParams fileParams = message.getFileParams();
if (message.isDeleted()) { if (message.isDeleted()) {
if (message.getType() == Message.TYPE_PRIVATE_FILE) { if (message.getType() == Message.TYPE_PRIVATE_FILE) {
message.setType(Message.TYPE_PRIVATE); message.setType(Message.TYPE_PRIVATE);
} else if (message.isFileOrImage()) { } else if (message.isFileOrImage()) {
message.setType(Message.TYPE_TEXT); message.setType(Message.TYPE_TEXT);
} }
message.setOob(true); message.setOob(fileParams.url);
message.setDeleted(false); message.setDeleted(false);
mXmppConnectionService.updateMessage(message); mXmppConnectionService.updateMessage(message);
} }
this.message.setTransferable(this); this.message.setTransferable(this);
try { try {
final Message.FileParams fileParams = message.getFileParams();
if (message.hasFileOnRemoteHost()) { if (message.hasFileOnRemoteHost()) {
mUrl = AesGcmURL.of(fileParams.url); mUrl = AesGcmURL.of(fileParams.url);
} else if (message.isOOb() && fileParams.url != null && fileParams.size != null) { } else if (message.isOOb() && fileParams.url != null) {
mUrl = AesGcmURL.of(fileParams.url); mUrl = AesGcmURL.of(fileParams.url);
} else { } else {
mUrl = AesGcmURL.of(message.getBody().split("\n")[0]); mUrl = AesGcmURL.of(message.getBody().split("\n")[0]);
@ -285,7 +285,7 @@ public class HttpDownloadConnection implements Transferable {
} }
final Message.FileParams fileParams = message.getFileParams(); final Message.FileParams fileParams = message.getFileParams();
FileBackend.updateFileParams(message, fileParams.url, size); FileBackend.updateFileParams(message, fileParams.url, size);
message.setOob(true); message.setOob(fileParams.url);
mXmppConnectionService.databaseBackend.updateMessage(message, true); mXmppConnectionService.databaseBackend.updateMessage(message, true);
file.setExpectedSize(size); file.setExpectedSize(size);
message.resetFileParams(); message.resetFileParams();

View file

@ -560,7 +560,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
} }
} else if (body == null && oobUrl != null) { } else if (body == null && oobUrl != null) {
message = new Message(conversation, oobUrl, Message.ENCRYPTION_NONE, status); message = new Message(conversation, oobUrl, Message.ENCRYPTION_NONE, status);
message.setOob(true); message.setOob(oobUrl);
if (CryptoHelper.isPgpEncryptedUrl(oobUrl)) { if (CryptoHelper.isPgpEncryptedUrl(oobUrl)) {
message.setEncryption(Message.ENCRYPTION_DECRYPTED); message.setEncryption(Message.ENCRYPTION_DECRYPTED);
} }
@ -577,8 +577,8 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
message.setServerMsgId(serverMsgId); message.setServerMsgId(serverMsgId);
message.setCarbon(isCarbon); message.setCarbon(isCarbon);
message.setTime(timestamp); message.setTime(timestamp);
if (body != null && body.content != null && body.content.equals(oobUrl)) { if (oobUrl != null) {
message.setOob(true); message.setOob(oobUrl);
if (CryptoHelper.isPgpEncryptedUrl(oobUrl)) { if (CryptoHelper.isPgpEncryptedUrl(oobUrl)) {
message.setEncryption(Message.ENCRYPTION_DECRYPTED); message.setEncryption(Message.ENCRYPTION_DECRYPTED);
} }

View file

@ -232,6 +232,18 @@ public class DatabaseBackend extends SQLiteOpenHelper {
db.execSQL("PRAGMA cheogram.user_version = 1"); db.execSQL("PRAGMA cheogram.user_version = 1");
} }
if(cheogramVersion < 2) {
db.execSQL(
"ALTER TABLE cheogram." + Message.TABLENAME + " " +
"ADD COLUMN oobUri TEXT"
);
db.execSQL(
"ALTER TABLE cheogram." + Message.TABLENAME + " " +
"ADD COLUMN fileParams TEXT"
);
db.execSQL("PRAGMA cheogram.user_version = 2");
}
db.setTransactionSuccessful(); db.setTransactionSuccessful();
} finally { } finally {
db.endTransaction(); db.endTransaction();
@ -1063,13 +1075,15 @@ public class DatabaseBackend extends SQLiteOpenHelper {
if (!includeBody) { if (!includeBody) {
contentValues.remove(Message.BODY); contentValues.remove(Message.BODY);
} }
return db.update(Message.TABLENAME, message.getContentValues(), Message.UUID + "=?", args) == 1; return db.update(Message.TABLENAME, message.getContentValues(), Message.UUID + "=?", args) == 1 &&
db.update("cheogram." + Message.TABLENAME, message.getCheogramContentValues(), Message.UUID + "=?", args) == 1;
} }
public boolean updateMessage(Message message, String uuid) { public boolean updateMessage(Message message, String uuid) {
SQLiteDatabase db = this.getWritableDatabase(); SQLiteDatabase db = this.getWritableDatabase();
String[] args = {uuid}; String[] args = {uuid};
return db.update(Message.TABLENAME, message.getContentValues(), Message.UUID + "=?", args) == 1; return db.update(Message.TABLENAME, message.getContentValues(), Message.UUID + "=?", args) == 1 &&
db.update("cheogram." + Message.TABLENAME, message.getCheogramContentValues(), Message.UUID + "=?", args) == 1;
} }
public void readRoster(Roster roster) { public void readRoster(Roster roster) {

View file

@ -402,9 +402,10 @@ public class FileBackend {
} }
public static void updateFileParams(Message message, String url, long size) { public static void updateFileParams(Message message, String url, long size) {
final StringBuilder body = new StringBuilder(); Message.FileParams fileParams = new Message.FileParams();
body.append(url).append('|').append(size); fileParams.url = url;
message.setBody(body.toString()); fileParams.size = size;
message.setFileParams(fileParams);
} }
public Bitmap getPreviewForUri(Attachment attachment, int size, boolean cacheOnly) { public Bitmap getPreviewForUri(Attachment attachment, int size, boolean cacheOnly) {
@ -1466,11 +1467,11 @@ public class FileBackend {
final boolean video = mime != null && mime.startsWith("video/"); final boolean video = mime != null && mime.startsWith("video/");
final boolean audio = mime != null && mime.startsWith("audio/"); final boolean audio = mime != null && mime.startsWith("audio/");
final boolean pdf = "application/pdf".equals(mime); final boolean pdf = "application/pdf".equals(mime);
final StringBuilder body = new StringBuilder(); Message.FileParams fileParams = new Message.FileParams();
if (url != null) { if (url != null) {
body.append(url); fileParams.url = url;
} }
body.append('|').append(file.getSize()); fileParams.size = file.getSize();
if (image || video || (pdf && Compatibility.runsTwentyOne())) { if (image || video || (pdf && Compatibility.runsTwentyOne())) {
try { try {
final Dimensions dimensions; final Dimensions dimensions;
@ -1482,7 +1483,8 @@ public class FileBackend {
dimensions = getImageDimensions(file); dimensions = getImageDimensions(file);
} }
if (dimensions.valid()) { if (dimensions.valid()) {
body.append('|').append(dimensions.width).append('|').append(dimensions.height); fileParams.width = dimensions.width;
fileParams.height = dimensions.height;
} }
} catch (NotAVideoFile notAVideoFile) { } catch (NotAVideoFile notAVideoFile) {
Log.d( Log.d(
@ -1491,9 +1493,9 @@ public class FileBackend {
// fall threw // fall threw
} }
} else if (audio) { } else if (audio) {
body.append("|0|0|").append(getMediaRuntime(file)); fileParams.runtime = getMediaRuntime(file);
} }
message.setBody(body.toString()); message.setFileParams(fileParams);
message.setDeleted(false); message.setDeleted(false);
message.setType( message.setType(
privateMessage privateMessage

View file

@ -517,8 +517,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
} }
} }
private void displayDownloadableMessage(ViewHolder viewHolder, final Message message, String text, final boolean darkBackground) { private void displayDownloadableMessage(ViewHolder viewHolder, final Message message, String text, final boolean darkBackground, final int type) {
toggleWhisperInfo(viewHolder, message, darkBackground); displayTextMessage(viewHolder, message, darkBackground, type);
viewHolder.image.setVisibility(View.GONE); viewHolder.image.setVisibility(View.GONE);
viewHolder.audioPlayer.setVisibility(View.GONE); viewHolder.audioPlayer.setVisibility(View.GONE);
viewHolder.download_button.setVisibility(View.VISIBLE); viewHolder.download_button.setVisibility(View.VISIBLE);
@ -526,8 +526,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
viewHolder.download_button.setOnClickListener(v -> ConversationFragment.downloadFile(activity, message)); viewHolder.download_button.setOnClickListener(v -> ConversationFragment.downloadFile(activity, message));
} }
private void displayOpenableMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground) { private void displayOpenableMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground, final int type) {
toggleWhisperInfo(viewHolder, message, darkBackground); displayTextMessage(viewHolder, message, darkBackground, type);
viewHolder.image.setVisibility(View.GONE); viewHolder.image.setVisibility(View.GONE);
viewHolder.audioPlayer.setVisibility(View.GONE); viewHolder.audioPlayer.setVisibility(View.GONE);
viewHolder.download_button.setVisibility(View.VISIBLE); viewHolder.download_button.setVisibility(View.VISIBLE);
@ -535,8 +535,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
viewHolder.download_button.setOnClickListener(v -> openDownloadable(message)); viewHolder.download_button.setOnClickListener(v -> openDownloadable(message));
} }
private void displayLocationMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground) { private void displayLocationMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground, final int type) {
toggleWhisperInfo(viewHolder, message, darkBackground); displayTextMessage(viewHolder, message, darkBackground, type);
viewHolder.image.setVisibility(View.GONE); viewHolder.image.setVisibility(View.GONE);
viewHolder.audioPlayer.setVisibility(View.GONE); viewHolder.audioPlayer.setVisibility(View.GONE);
viewHolder.download_button.setVisibility(View.VISIBLE); viewHolder.download_button.setVisibility(View.VISIBLE);
@ -544,8 +544,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
viewHolder.download_button.setOnClickListener(v -> showLocation(message)); viewHolder.download_button.setOnClickListener(v -> showLocation(message));
} }
private void displayAudioMessage(ViewHolder viewHolder, Message message, boolean darkBackground) { private void displayAudioMessage(ViewHolder viewHolder, Message message, boolean darkBackground, final int type) {
toggleWhisperInfo(viewHolder, message, darkBackground); displayTextMessage(viewHolder, message, darkBackground, type);
viewHolder.image.setVisibility(View.GONE); viewHolder.image.setVisibility(View.GONE);
viewHolder.download_button.setVisibility(View.GONE); viewHolder.download_button.setVisibility(View.GONE);
final RelativeLayout audioPlayer = viewHolder.audioPlayer; final RelativeLayout audioPlayer = viewHolder.audioPlayer;
@ -554,8 +554,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
this.audioPlayer.init(audioPlayer, message); this.audioPlayer.init(audioPlayer, message);
} }
private void displayMediaPreviewMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground) { private void displayMediaPreviewMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground, final int type) {
toggleWhisperInfo(viewHolder, message, darkBackground); displayTextMessage(viewHolder, message, darkBackground, type);
viewHolder.download_button.setVisibility(View.GONE); viewHolder.download_button.setVisibility(View.GONE);
viewHolder.audioPlayer.setVisibility(View.GONE); viewHolder.audioPlayer.setVisibility(View.GONE);
viewHolder.image.setVisibility(View.VISIBLE); viewHolder.image.setVisibility(View.VISIBLE);
@ -782,19 +782,19 @@ public class MessageAdapter extends ArrayAdapter<Message> {
final boolean unInitiatedButKnownSize = MessageUtils.unInitiatedButKnownSize(message); final boolean unInitiatedButKnownSize = MessageUtils.unInitiatedButKnownSize(message);
if (unInitiatedButKnownSize || message.isDeleted() || (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING)) { if (unInitiatedButKnownSize || message.isDeleted() || (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING)) {
if (unInitiatedButKnownSize || transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER) { if (unInitiatedButKnownSize || transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER) {
displayDownloadableMessage(viewHolder, message, activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message)), darkBackground); displayDownloadableMessage(viewHolder, message, activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message)), darkBackground, type);
} else if (transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER_CHECK_FILESIZE) { } 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)), darkBackground); displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message)), darkBackground, type);
} else { } else {
displayInfoMessage(viewHolder, UIHelper.getMessagePreview(activity, message).first, darkBackground); displayInfoMessage(viewHolder, UIHelper.getMessagePreview(activity, message).first, darkBackground);
} }
} else if (message.isFileOrImage() && message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED) { } else if (message.isFileOrImage() && message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED) {
if (message.getFileParams().width > 0 && message.getFileParams().height > 0) { if (message.getFileParams().width > 0 && message.getFileParams().height > 0) {
displayMediaPreviewMessage(viewHolder, message, darkBackground); displayMediaPreviewMessage(viewHolder, message, darkBackground, type);
} else if (message.getFileParams().runtime > 0) { } else if (message.getFileParams().runtime > 0) {
displayAudioMessage(viewHolder, message, darkBackground); displayAudioMessage(viewHolder, message, darkBackground, type);
} else { } else {
displayOpenableMessage(viewHolder, message, darkBackground); displayOpenableMessage(viewHolder, message, darkBackground, type);
} }
} else if (message.getEncryption() == Message.ENCRYPTION_PGP) { } else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
if (account.isPgpDecryptionServiceConnected()) { if (account.isPgpDecryptionServiceConnected()) {
@ -816,25 +816,25 @@ public class MessageAdapter extends ArrayAdapter<Message> {
displayInfoMessage(viewHolder, activity.getString(R.string.omemo_decryption_failed), darkBackground); displayInfoMessage(viewHolder, activity.getString(R.string.omemo_decryption_failed), darkBackground);
} else { } else {
if (message.isGeoUri()) { if (message.isGeoUri()) {
displayLocationMessage(viewHolder, message, darkBackground); displayLocationMessage(viewHolder, message, darkBackground, type);
} else if (message.bodyIsOnlyEmojis() && message.getType() != Message.TYPE_PRIVATE) {
displayEmojiMessage(viewHolder, message.getBody().trim(), darkBackground);
} else if (message.treatAsDownloadable()) { } else if (message.treatAsDownloadable()) {
try { try {
final URI uri = new URI(message.getBody()); final URI uri = message.getOob();
displayDownloadableMessage(viewHolder, displayDownloadableMessage(viewHolder,
message, message,
activity.getString(R.string.check_x_filesize_on_host, activity.getString(R.string.check_x_filesize_on_host,
UIHelper.getFileDescriptionString(activity, message), UIHelper.getFileDescriptionString(activity, message),
uri.getHost()), uri.getHost()),
darkBackground); darkBackground, type);
} catch (Exception e) { } catch (Exception e) {
displayDownloadableMessage(viewHolder, displayDownloadableMessage(viewHolder,
message, message,
activity.getString(R.string.check_x_filesize, activity.getString(R.string.check_x_filesize,
UIHelper.getFileDescriptionString(activity, message)), UIHelper.getFileDescriptionString(activity, message)),
darkBackground); darkBackground, type);
} }
} else if (message.bodyIsOnlyEmojis() && message.getType() != Message.TYPE_PRIVATE) {
displayEmojiMessage(viewHolder, message.getBody().trim(), darkBackground);
} else { } else {
displayTextMessage(viewHolder, message, darkBackground, type); displayTextMessage(viewHolder, message, darkBackground, type);
} }

View file

@ -82,6 +82,8 @@ public class MessageUtils {
} }
public static boolean treatAsDownloadable(final String body, final boolean oob) { public static boolean treatAsDownloadable(final String body, final boolean oob) {
if (oob) return true;
final String[] lines = body.split("\n"); final String[] lines = body.split("\n");
if (lines.length == 0) { if (lines.length == 0) {
return false; return false;