Merge pull request #1661 from oxen-io/feature/ses-2655

SES-2655 standardise thread body
This commit is contained in:
ThomasSession 2024-09-11 08:57:15 +10:00 committed by GitHub
commit b452a17b42
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 60 additions and 61 deletions

View File

@ -18,7 +18,9 @@
package org.thoughtcrime.securesms.database.model;
import static org.session.libsession.utilities.StringSubstitutionConstants.APP_NAME_KEY;
import static org.session.libsession.utilities.StringSubstitutionConstants.AUTHOR_KEY;
import static org.session.libsession.utilities.StringSubstitutionConstants.DISAPPEARING_MESSAGES_TYPE_KEY;
import static org.session.libsession.utilities.StringSubstitutionConstants.MESSAGE_SNIPPET_KEY;
import static org.session.libsession.utilities.StringSubstitutionConstants.NAME_KEY;
import static org.session.libsession.utilities.StringSubstitutionConstants.TIME_KEY;
@ -119,62 +121,54 @@ public class ThreadRecord extends DisplayRecord {
@Override
public CharSequence getDisplayBody(@NonNull Context context) {
if (isGroupUpdateMessage()) {
return emphasisAdded(context.getString(R.string.groupUpdated));
return context.getString(R.string.groupUpdated);
} else if (isOpenGroupInvitation()) {
return emphasisAdded(context.getString(R.string.communityInvitation));
return context.getString(R.string.communityInvitation);
} else if (MmsSmsColumns.Types.isLegacyType(type)) {
String txt = Phrase.from(context, R.string.messageErrorOld)
return Phrase.from(context, R.string.messageErrorOld)
.put(APP_NAME_KEY, context.getString(R.string.app_name))
.format().toString();
return emphasisAdded(txt);
} else if (MmsSmsColumns.Types.isDraftMessageType(type)) {
String draftText = context.getString(R.string.draft);
return emphasisAdded(draftText + " " + getBody(), 0, draftText.length());
return draftText + " " + getBody();
} else if (SmsDatabase.Types.isOutgoingCall(type)) {
String txt = Phrase.from(context, R.string.callsYouCalled)
return Phrase.from(context, R.string.callsYouCalled)
.put(NAME_KEY, getName())
.format().toString();
return emphasisAdded(txt);
} else if (SmsDatabase.Types.isIncomingCall(type)) {
String txt = Phrase.from(context, R.string.callsCalledYou)
return Phrase.from(context, R.string.callsCalledYou)
.put(NAME_KEY, getName())
.format().toString();
return emphasisAdded(txt);
} else if (SmsDatabase.Types.isMissedCall(type)) {
String txt = Phrase.from(context, R.string.callsMissedCallFrom)
return Phrase.from(context, R.string.callsMissedCallFrom)
.put(NAME_KEY, getName())
.format().toString();
return emphasisAdded(txt);
} else if (SmsDatabase.Types.isExpirationTimerUpdate(type)) {
int seconds = (int) (getExpiresIn() / 1000);
if (seconds <= 0) {
String txt = Phrase.from(context, R.string.disappearingMessagesTurnedOff)
return Phrase.from(context, R.string.disappearingMessagesTurnedOff)
.put(NAME_KEY, getName())
.format().toString();
return emphasisAdded(txt);
}
// Implied that disappearing messages is enabled..
String time = ExpirationUtil.getExpirationDisplayValue(context, seconds);
String disappearAfterWhat = getDisappearingMsgExpiryTypeString(context); // Disappear after send or read?
String txt = Phrase.from(context, R.string.disappearingMessagesSet)
return Phrase.from(context, R.string.disappearingMessagesSet)
.put(NAME_KEY, getName())
.put(TIME_KEY, time)
.put(DISAPPEARING_MESSAGES_TYPE_KEY, disappearAfterWhat)
.format().toString();
return emphasisAdded(txt);
} else if (MmsSmsColumns.Types.isMediaSavedExtraction(type)) {
String txt = Phrase.from(context, R.string.attachmentsMediaSaved)
return Phrase.from(context, R.string.attachmentsMediaSaved)
.put(NAME_KEY, getName())
.format().toString();
return emphasisAdded(txt);
} else if (MmsSmsColumns.Types.isScreenshotExtraction(type)) {
String txt = Phrase.from(context, R.string.screenshotTaken)
return Phrase.from(context, R.string.screenshotTaken)
.put(NAME_KEY, getName())
.format().toString();
return emphasisAdded(txt);
} else if (MmsSmsColumns.Types.isMessageRequestResponse(type)) {
if (lastMessage.getRecipient().getAddress().serialize().equals(
@ -186,7 +180,7 @@ public class ThreadRecord extends DisplayRecord {
);
}
return emphasisAdded(context.getString(R.string.messageRequestsAccepted));
return context.getString(R.string.messageRequestsAccepted);
} else if (getCount() == 0) {
return new SpannableString(context.getString(R.string.messageEmpty));
} else {
@ -199,20 +193,37 @@ public class ThreadRecord extends DisplayRecord {
return new SpannableString("");
// Old behaviour was: return new SpannableString(emphasisAdded(context.getString(R.string.mediaMessage)));
} else {
return new SpannableString(getBody());
return getNonControlMessageDisplayBody(context);
}
}
}
private SpannableString emphasisAdded(String sequence) {
return emphasisAdded(sequence, 0, sequence.length());
}
/**
* Logic to get the body for non control messages
*/
public CharSequence getNonControlMessageDisplayBody(@NonNull Context context) {
Recipient recipient = getRecipient();
// The logic will differ depending on the type.
// 1-1, note to self and control messages (we shouldn't have any in here, but leaving the
// logic to be safe) do not need author details
if (recipient.isLocalNumber() || recipient.is1on1() ||
(lastMessage != null && lastMessage.isControlMessage())
) {
return getBody();
} else { // for groups (new, legacy, communities) show either 'You' or the contact's name
String prefix = "";
if (lastMessage != null && lastMessage.isOutgoing()) {
prefix = context.getString(R.string.you);
}
else if(lastMessage != null){
prefix = lastMessage.getIndividualRecipient().toShortString();
}
private SpannableString emphasisAdded(String sequence, int start, int end) {
SpannableString spannable = new SpannableString(sequence);
spannable.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC),
start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannable;
return Phrase.from(context.getString(R.string.messageSnippetGroup))
.put(AUTHOR_KEY, prefix)
.put(MESSAGE_SNIPPET_KEY, getBody())
.format().toString();
}
}
public long getCount() { return count; }

View File

@ -103,7 +103,7 @@ class ConversationView : LinearLayout {
}
binding.muteIndicatorImageView.setImageResource(drawableRes)
binding.snippetTextView.text = highlightMentions(
text = thread.getSnippet(),
text = thread.getDisplayBody(context),
formatOnly = true, // no styling here, only text formatting
threadID = thread.threadId,
context = context
@ -139,16 +139,5 @@ class ConversationView : LinearLayout {
recipient.isLocalNumber -> context.getString(R.string.noteToSelf)
else -> recipient.toShortString() // Internally uses the Contact API
}
private fun ThreadRecord.getSnippet(): CharSequence = listOfNotNull(
getSnippetPrefix(),
getDisplayBody(context)
).joinToString(": ")
private fun ThreadRecord.getSnippetPrefix(): CharSequence? = when {
recipient.isLocalNumber || lastMessage?.isControlMessage == true -> null
lastMessage?.isOutgoing == true -> resources.getString(R.string.you)
else -> lastMessage?.individualRecipient?.toShortString()
}
// endregion
}

View File

@ -49,14 +49,11 @@ abstract class Slide(@JvmField protected val context: Context, protected val att
// A missing file name is the legacy way to determine if an audio attachment is
// a voice note vs. other arbitrary audio attachments.
if (attachment.isVoiceNote || attachment.fileName.isNullOrEmpty()) {
val baseString = context.getString(R.string.messageVoice)
val languageIsLTR = Util.usingLeftToRightLanguage(context)
val attachmentString = if (languageIsLTR) {
"🎙 $baseString"
} else {
"$baseString 🎙"
}
return Optional.fromNullable(attachmentString)
val voiceTxt = Phrase.from(context, R.string.messageVoiceSnippet)
.put(EMOJI_KEY, "🎙")
.format().toString()
return Optional.fromNullable(voiceTxt)
}
}
val txt = Phrase.from(context, R.string.attachmentsNotification)
@ -66,19 +63,19 @@ abstract class Slide(@JvmField protected val context: Context, protected val att
}
private fun emojiForMimeType(): String {
return if (MediaUtil.isGif(attachment)) {
"🎡"
} else if (MediaUtil.isImage(attachment)) {
"📷"
} else if (MediaUtil.isVideo(attachment)) {
"🎥"
} else if (MediaUtil.isAudio(attachment)) {
"🎧"
} else if (MediaUtil.isFile(attachment)) {
"📎"
} else {
return when{
MediaUtil.isGif(attachment) -> "🎡"
MediaUtil.isImage(attachment) -> "📷"
MediaUtil.isVideo(attachment) -> "🎥"
MediaUtil.isAudio(attachment) -> "🎧"
MediaUtil.isFile(attachment) -> "📎"
// We don't provide emojis for other mime-types such as VCARD
""
else -> ""
}
}

View File

@ -4,6 +4,7 @@ package org.session.libsession.utilities
// Note: The substitution will be to {app_name} etc. in the strings - but do NOT include the curly braces in these keys!
object StringSubstitutionConstants {
const val ACCOUNT_ID_KEY = "account_id"
const val AUTHOR_KEY = "author"
const val APP_NAME_KEY = "app_name"
const val COMMUNITY_NAME_KEY = "community_name"
const val CONVERSATION_COUNT_KEY = "conversation_count"
@ -17,6 +18,7 @@ object StringSubstitutionConstants {
const val GROUP_NAME_KEY = "group_name"
const val MEMBERS_KEY = "members"
const val MESSAGE_COUNT_KEY = "message_count"
const val MESSAGE_SNIPPET_KEY = "message_snippet"
const val NAME_KEY = "name"
const val OTHER_NAME_KEY = "other_name"
const val QUERY_KEY = "query"