mirror of
https://github.com/oxen-io/session-android.git
synced 2025-06-09 14:28:34 +00:00
Various UI adjustments to conversation updates.
This commit is contained in:
parent
9743e3689a
commit
3f983a5c82
@ -58,15 +58,22 @@ public final class LiveUpdateMessage {
|
|||||||
private static @NonNull Spannable toSpannable(@NonNull Context context, @NonNull UpdateDescription updateDescription, @NonNull String string) {
|
private static @NonNull Spannable toSpannable(@NonNull Context context, @NonNull UpdateDescription updateDescription, @NonNull String string) {
|
||||||
boolean isDarkTheme = ThemeUtil.isDarkTheme(context);
|
boolean isDarkTheme = ThemeUtil.isDarkTheme(context);
|
||||||
int drawableResource = isDarkTheme ? updateDescription.getDarkIconResource() : updateDescription.getLightIconResource();
|
int drawableResource = isDarkTheme ? updateDescription.getDarkIconResource() : updateDescription.getLightIconResource();
|
||||||
|
int tint = isDarkTheme ? updateDescription.getDarkTint() : updateDescription.getLightTint();
|
||||||
|
|
||||||
|
if (tint == 0) {
|
||||||
|
tint = ThemeUtil.getThemedColor(context, R.attr.conversation_item_update_text_color);
|
||||||
|
}
|
||||||
|
|
||||||
if (drawableResource == 0) {
|
if (drawableResource == 0) {
|
||||||
return new SpannableString(string);
|
return new SpannableString(string);
|
||||||
} else {
|
} else {
|
||||||
Drawable drawable = ContextCompat.getDrawable(context, drawableResource);
|
Drawable drawable = ContextCompat.getDrawable(context, drawableResource);
|
||||||
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
|
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
|
||||||
drawable.setColorFilter(ThemeUtil.getThemedColor(context, R.attr.conversation_item_update_text_color), PorterDuff.Mode.SRC_ATOP);
|
drawable.setColorFilter(tint, PorterDuff.Mode.SRC_ATOP);
|
||||||
|
|
||||||
return new SpannableStringBuilder().append(SpanUtil.buildImageSpan(drawable)).append(" ").append(string);
|
Spannable stringWithImage = new SpannableStringBuilder().append(SpanUtil.buildImageSpan(drawable)).append(" ").append(string);
|
||||||
|
|
||||||
|
return new SpannableString(SpanUtil.color(tint, stringWithImage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,17 @@
|
|||||||
package org.thoughtcrime.securesms.database.model;
|
package org.thoughtcrime.securesms.database.model;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
import android.text.style.RelativeSizeSpan;
|
import android.text.style.RelativeSizeSpan;
|
||||||
import android.text.style.StyleSpan;
|
import android.text.style.StyleSpan;
|
||||||
|
|
||||||
|
import androidx.annotation.ColorInt;
|
||||||
import androidx.annotation.DrawableRes;
|
import androidx.annotation.DrawableRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
@ -138,11 +141,11 @@ public abstract class MessageRecord extends DisplayRecord {
|
|||||||
} else if (isGroupQuit()) {
|
} else if (isGroupQuit()) {
|
||||||
return fromRecipient(getIndividualRecipient(), r -> context.getString(R.string.ConversationItem_group_action_left, r.getDisplayName(context)), R.drawable.ic_update_group_leave_light_16, R.drawable.ic_update_group_leave_dark_16);
|
return fromRecipient(getIndividualRecipient(), r -> context.getString(R.string.ConversationItem_group_action_left, r.getDisplayName(context)), R.drawable.ic_update_group_leave_light_16, R.drawable.ic_update_group_leave_dark_16);
|
||||||
} else if (isIncomingCall()) {
|
} else if (isIncomingCall()) {
|
||||||
return fromRecipient(getIndividualRecipient(), r -> context.getString(R.string.MessageRecord_s_called_you_date, r.getDisplayName(context), getCallDateString()), R.drawable.ic_update_audio_call_incoming_light_16, R.drawable.ic_update_audio_call_incoming_dark_16);
|
return fromRecipient(getIndividualRecipient(), r -> context.getString(R.string.MessageRecord_s_called_you_date, r.getDisplayName(context), getCallDateString(context)), R.drawable.ic_update_audio_call_incoming_light_16, R.drawable.ic_update_audio_call_incoming_dark_16);
|
||||||
} else if (isOutgoingCall()) {
|
} else if (isOutgoingCall()) {
|
||||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_you_called_date, getCallDateString()), R.drawable.ic_update_audio_call_outgoing_light_16, R.drawable.ic_update_audio_call_outgoing_dark_16);
|
return staticUpdateDescription(context.getString(R.string.MessageRecord_you_called_date, getCallDateString(context)), R.drawable.ic_update_audio_call_outgoing_light_16, R.drawable.ic_update_audio_call_outgoing_dark_16);
|
||||||
} else if (isMissedCall()) {
|
} else if (isMissedCall()) {
|
||||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_missed_call_date, getCallDateString()), R.drawable.ic_update_audio_call_missed_light_16, R.drawable.ic_update_audio_call_missed_dark_16);
|
return staticUpdateDescription(context.getString(R.string.MessageRecord_missed_call_date, getCallDateString(context)), R.drawable.ic_update_audio_call_missed_light_16, R.drawable.ic_update_audio_call_missed_dark_16, ContextCompat.getColor(context, R.color.core_red_shade), ContextCompat.getColor(context, R.color.core_red));
|
||||||
} else if (isJoined()) {
|
} else if (isJoined()) {
|
||||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_s_joined_signal, getIndividualRecipient().getDisplayName(context)), R.drawable.ic_update_group_add_light_16, R.drawable.ic_update_group_add_dark_16);
|
return staticUpdateDescription(context.getString(R.string.MessageRecord_s_joined_signal, getIndividualRecipient().getDisplayName(context)), R.drawable.ic_update_group_add_light_16, R.drawable.ic_update_group_add_dark_16);
|
||||||
} else if (isExpirationTimerUpdate()) {
|
} else if (isExpirationTimerUpdate()) {
|
||||||
@ -213,8 +216,8 @@ public abstract class MessageRecord extends DisplayRecord {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private @NonNull String getCallDateString() {
|
private @NonNull String getCallDateString(@NonNull Context context) {
|
||||||
return DateUtils.getBriefExactTimeString(Locale.getDefault(), getDateSent());
|
return DateUtils.getExtendedRelativeTimeSpanString(context, Locale.getDefault(), getDateSent());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @NonNull UpdateDescription fromRecipient(@NonNull Recipient recipient,
|
private static @NonNull UpdateDescription fromRecipient(@NonNull Recipient recipient,
|
||||||
@ -235,6 +238,15 @@ public abstract class MessageRecord extends DisplayRecord {
|
|||||||
return UpdateDescription.staticDescription(string, lightIconResource, darkIconResource);
|
return UpdateDescription.staticDescription(string, lightIconResource, darkIconResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static @NonNull UpdateDescription staticUpdateDescription(@NonNull String string,
|
||||||
|
@DrawableRes int lightIconResource,
|
||||||
|
@DrawableRes int darkIconResource,
|
||||||
|
@ColorInt int lightTint,
|
||||||
|
@ColorInt int darkTint)
|
||||||
|
{
|
||||||
|
return UpdateDescription.staticDescription(string, lightIconResource, darkIconResource, lightTint, darkTint);
|
||||||
|
}
|
||||||
|
|
||||||
private @NonNull String getProfileChangeDescription(@NonNull Context context) {
|
private @NonNull String getProfileChangeDescription(@NonNull Context context) {
|
||||||
try {
|
try {
|
||||||
byte[] decoded = Base64.decode(getBody());
|
byte[] decoded = Base64.decode(getBody());
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.thoughtcrime.securesms.database.model;
|
package org.thoughtcrime.securesms.database.model;
|
||||||
|
|
||||||
import androidx.annotation.AnyThread;
|
import androidx.annotation.AnyThread;
|
||||||
|
import androidx.annotation.ColorInt;
|
||||||
import androidx.annotation.DrawableRes;
|
import androidx.annotation.DrawableRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@ -31,12 +32,16 @@ public final class UpdateDescription {
|
|||||||
private final String staticString;
|
private final String staticString;
|
||||||
private final int lightIconResource;
|
private final int lightIconResource;
|
||||||
private final int darkIconResource;
|
private final int darkIconResource;
|
||||||
|
private final int lightTint;
|
||||||
|
private final int darkTint;
|
||||||
|
|
||||||
private UpdateDescription(@NonNull Collection<UUID> mentioned,
|
private UpdateDescription(@NonNull Collection<UUID> mentioned,
|
||||||
@Nullable StringFactory stringFactory,
|
@Nullable StringFactory stringFactory,
|
||||||
@Nullable String staticString,
|
@Nullable String staticString,
|
||||||
@DrawableRes int lightIconResource,
|
@DrawableRes int lightIconResource,
|
||||||
@DrawableRes int darkIconResource)
|
@DrawableRes int darkIconResource,
|
||||||
|
@ColorInt int lightTint,
|
||||||
|
@ColorInt int darkTint)
|
||||||
{
|
{
|
||||||
if (staticString == null && stringFactory == null) {
|
if (staticString == null && stringFactory == null) {
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
@ -46,6 +51,8 @@ public final class UpdateDescription {
|
|||||||
this.staticString = staticString;
|
this.staticString = staticString;
|
||||||
this.lightIconResource = lightIconResource;
|
this.lightIconResource = lightIconResource;
|
||||||
this.darkIconResource = darkIconResource;
|
this.darkIconResource = darkIconResource;
|
||||||
|
this.lightTint = lightTint;
|
||||||
|
this.darkTint = darkTint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,7 +71,9 @@ public final class UpdateDescription {
|
|||||||
stringFactory,
|
stringFactory,
|
||||||
null,
|
null,
|
||||||
lightIconResource,
|
lightIconResource,
|
||||||
darkIconResource);
|
darkIconResource,
|
||||||
|
0,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,7 +83,19 @@ public final class UpdateDescription {
|
|||||||
@DrawableRes int lightIconResource,
|
@DrawableRes int lightIconResource,
|
||||||
@DrawableRes int darkIconResource)
|
@DrawableRes int darkIconResource)
|
||||||
{
|
{
|
||||||
return new UpdateDescription(Collections.emptyList(), null, staticString, lightIconResource, darkIconResource);
|
return new UpdateDescription(Collections.emptyList(), null, staticString, lightIconResource, darkIconResource, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an update description that's string value is fixed with a specific tint color.
|
||||||
|
*/
|
||||||
|
public static UpdateDescription staticDescription(@NonNull String staticString,
|
||||||
|
@DrawableRes int lightIconResource,
|
||||||
|
@DrawableRes int darkIconResource,
|
||||||
|
@ColorInt int lightTint,
|
||||||
|
@ColorInt int darkTint)
|
||||||
|
{
|
||||||
|
return new UpdateDescription(Collections.emptyList(), null, staticString, lightIconResource, darkIconResource, lightTint, darkTint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isStringStatic() {
|
public boolean isStringStatic() {
|
||||||
@ -115,6 +136,14 @@ public final class UpdateDescription {
|
|||||||
return darkIconResource;
|
return darkIconResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @ColorInt int getLightTint() {
|
||||||
|
return lightTint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @ColorInt int getDarkTint() {
|
||||||
|
return darkTint;
|
||||||
|
}
|
||||||
|
|
||||||
public static UpdateDescription concatWithNewLines(@NonNull List<UpdateDescription> updateDescriptions) {
|
public static UpdateDescription concatWithNewLines(@NonNull List<UpdateDescription> updateDescriptions) {
|
||||||
if (updateDescriptions.size() == 0) {
|
if (updateDescriptions.size() == 0) {
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
|
@ -63,7 +63,7 @@ public class DateUtils extends android.text.format.DateUtils {
|
|||||||
|
|
||||||
private static String getFormattedDateTime(long time, String template, Locale locale) {
|
private static String getFormattedDateTime(long time, String template, Locale locale) {
|
||||||
final String localizedPattern = getLocalizedPattern(template, locale);
|
final String localizedPattern = getLocalizedPattern(template, locale);
|
||||||
return new SimpleDateFormat(localizedPattern, locale).format(new Date(time));
|
return setLowercaseAmPmStrings(new SimpleDateFormat(localizedPattern, locale), locale).format(new Date(time));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getBriefRelativeTimeSpanString(final Context c, final Locale locale, final long timestamp) {
|
public static String getBriefRelativeTimeSpanString(final Context c, final Locale locale, final long timestamp) {
|
||||||
@ -174,18 +174,17 @@ public class DateUtils extends android.text.format.DateUtils {
|
|||||||
return getExtendedRelativeTimeSpanString(context, locale, t1).equals(getExtendedRelativeTimeSpanString(context, locale, t2));
|
return getExtendedRelativeTimeSpanString(context, locale, t1).equals(getExtendedRelativeTimeSpanString(context, locale, t2));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getBriefExactTimeString(@NonNull Locale locale, long timestamp) {
|
private static String getLocalizedPattern(String template, Locale locale) {
|
||||||
SimpleDateFormat format = new SimpleDateFormat(getLocalizedPattern("MMM dd, hh:mm a", locale), locale);
|
return DateFormat.getBestDateTimePattern(locale, template);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static @NonNull SimpleDateFormat setLowercaseAmPmStrings(@NonNull SimpleDateFormat format, @NonNull Locale locale) {
|
||||||
DateFormatSymbols symbols = new DateFormatSymbols(locale);
|
DateFormatSymbols symbols = new DateFormatSymbols(locale);
|
||||||
|
|
||||||
symbols.setAmPmStrings(new String[] { "am", "pm"});
|
symbols.setAmPmStrings(new String[] { "am", "pm"});
|
||||||
format.setDateFormatSymbols(symbols);
|
format.setDateFormatSymbols(symbols);
|
||||||
|
|
||||||
return format.format(timestamp);
|
return format;
|
||||||
}
|
|
||||||
|
|
||||||
private static String getLocalizedPattern(String template, Locale locale) {
|
|
||||||
return DateFormat.getBestDateTimePattern(locale, template);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,6 +5,7 @@ import android.graphics.PorterDuff;
|
|||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
import android.text.style.AbsoluteSizeSpan;
|
import android.text.style.AbsoluteSizeSpan;
|
||||||
@ -60,7 +61,9 @@ public class SpanUtil {
|
|||||||
public static CharSequence buildImageSpan(@NonNull Drawable drawable) {
|
public static CharSequence buildImageSpan(@NonNull Drawable drawable) {
|
||||||
SpannableString imageSpan = new SpannableString(" ");
|
SpannableString imageSpan = new SpannableString(" ");
|
||||||
|
|
||||||
imageSpan.setSpan(new ImageSpan(drawable, DynamicDrawableSpan.ALIGN_CENTER), 0, imageSpan.length(), 0);
|
int flag = Build.VERSION.SDK_INT >= 29 ? DynamicDrawableSpan.ALIGN_CENTER : DynamicDrawableSpan.ALIGN_BASELINE;
|
||||||
|
|
||||||
|
imageSpan.setSpan(new ImageSpan(drawable, flag), 0, imageSpan.length(), 0);
|
||||||
|
|
||||||
return imageSpan;
|
return imageSpan;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/scroll_date_header"
|
android:id="@+id/scroll_date_header"
|
||||||
style="@style/Signal.Text.Caption"
|
style="@style/Signal.Text.Preview"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
style="@style/Signal.Text.Caption"
|
style="@style/Signal.Text.Preview"
|
||||||
android:textColor="?conversation_item_update_text_color"
|
android:textColor="?conversation_item_update_text_color"
|
||||||
tools:text="March 1, 2015" />
|
tools:text="March 1, 2015" />
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
<color name="core_yellow">#ffd624</color>
|
<color name="core_yellow">#ffd624</color>
|
||||||
<color name="core_red">#f44336</color>
|
<color name="core_red">#f44336</color>
|
||||||
<color name="core_red_highlight">#ef5350</color>
|
<color name="core_red_highlight">#ef5350</color>
|
||||||
|
<color name="core_red_shade">#e51d0e</color>
|
||||||
|
|
||||||
<color name="core_white">#ffffff</color>
|
<color name="core_white">#ffffff</color>
|
||||||
<color name="core_black">#000000</color>
|
<color name="core_black">#000000</color>
|
||||||
|
@ -937,10 +937,10 @@
|
|||||||
<string name="MessageRecord_left_group">You have left the group.</string>
|
<string name="MessageRecord_left_group">You have left the group.</string>
|
||||||
<string name="MessageRecord_you_updated_group">You updated the group.</string>
|
<string name="MessageRecord_you_updated_group">You updated the group.</string>
|
||||||
<string name="MessageRecord_the_group_was_updated">The group was updated.</string>
|
<string name="MessageRecord_the_group_was_updated">The group was updated.</string>
|
||||||
<string name="MessageRecord_you_called_date">You called • %1$s</string>
|
<string name="MessageRecord_you_called_date">You called · %1$s</string>
|
||||||
<string name="MessageRecord_missed_call_date">Missed call • %1$s</string>
|
<string name="MessageRecord_missed_call_date">Missed call · %1$s</string>
|
||||||
<string name="MessageRecord_s_updated_group">%s updated the group.</string>
|
<string name="MessageRecord_s_updated_group">%s updated the group.</string>
|
||||||
<string name="MessageRecord_s_called_you_date">%1$s called you • %2$s</string>
|
<string name="MessageRecord_s_called_you_date">%1$s called you · %2$s</string>
|
||||||
<string name="MessageRecord_called_s">Called %s</string>
|
<string name="MessageRecord_called_s">Called %s</string>
|
||||||
<string name="MessageRecord_s_joined_signal">%s is on Signal!</string>
|
<string name="MessageRecord_s_joined_signal">%s is on Signal!</string>
|
||||||
<string name="MessageRecord_you_disabled_disappearing_messages">You disabled disappearing messages.</string>
|
<string name="MessageRecord_you_disabled_disappearing_messages">You disabled disappearing messages.</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user