mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-25 03:11:10 +01:00
Implement new Material3 spec.
This commit is contained in:
committed by
Greyson Parrelli
parent
556e480b06
commit
1b471e163d
@@ -0,0 +1,32 @@
|
||||
package org.thoughtcrime.securesms.conversation
|
||||
|
||||
import androidx.core.view.doOnNextLayout
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.signal.core.util.DimensionUnit
|
||||
|
||||
/**
|
||||
* Adds necessary padding to each side of the given RecyclerView in order to ensure that
|
||||
* if all buttons can fit in the visible real-estate on screen, they are centered.
|
||||
*/
|
||||
class AttachmentButtonCenterHelper(private val recyclerView: RecyclerView) : RecyclerView.AdapterDataObserver() {
|
||||
|
||||
private val itemWidth: Float = DimensionUnit.DP.toPixels(88f)
|
||||
private val defaultPadding: Float = DimensionUnit.DP.toPixels(16f)
|
||||
|
||||
override fun onChanged() {
|
||||
val itemCount = recyclerView.adapter?.itemCount ?: return
|
||||
val requiredSpace = itemWidth * itemCount
|
||||
|
||||
recyclerView.doOnNextLayout {
|
||||
if (it.measuredWidth >= requiredSpace) {
|
||||
val extraSpace = it.measuredWidth - requiredSpace
|
||||
val availablePadding = extraSpace / 2f
|
||||
it.post {
|
||||
it.setPadding(availablePadding.toInt(), it.paddingTop, availablePadding.toInt(), it.paddingBottom)
|
||||
}
|
||||
} else {
|
||||
it.setPadding(defaultPadding.toInt(), it.paddingTop, defaultPadding.toInt(), it.paddingBottom)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,6 +78,8 @@ public class AttachmentKeyboard extends FrameLayout implements InputAwareLayout.
|
||||
mediaList.setAdapter(mediaAdapter);
|
||||
buttonList.setAdapter(buttonAdapter);
|
||||
|
||||
buttonAdapter.registerAdapterDataObserver(new AttachmentButtonCenterHelper(buttonList));
|
||||
|
||||
mediaList.setLayoutManager(new GridLayoutManager(context, 1, GridLayoutManager.HORIZONTAL, false));
|
||||
buttonList.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
|
||||
|
||||
|
||||
@@ -7,11 +7,11 @@ import org.thoughtcrime.securesms.R;
|
||||
|
||||
public enum AttachmentKeyboardButton {
|
||||
|
||||
GALLERY(R.string.AttachmentKeyboard_gallery, R.drawable.ic_photo_album_outline_32),
|
||||
FILE(R.string.AttachmentKeyboard_file, R.drawable.ic_file_outline_32),
|
||||
PAYMENT(R.string.AttachmentKeyboard_payment, R.drawable.ic_payments_32),
|
||||
CONTACT(R.string.AttachmentKeyboard_contact, R.drawable.ic_contact_circle_outline_32),
|
||||
LOCATION(R.string.AttachmentKeyboard_location, R.drawable.ic_location_outline_32);
|
||||
GALLERY(R.string.AttachmentKeyboard_gallery, R.drawable.ic_gallery_outline_24),
|
||||
FILE(R.string.AttachmentKeyboard_file, R.drawable.ic_file_outline_24),
|
||||
PAYMENT(R.string.AttachmentKeyboard_payment, R.drawable.ic_payments_24),
|
||||
CONTACT(R.string.AttachmentKeyboard_contact, R.drawable.ic_contact_outline_24),
|
||||
LOCATION(R.string.AttachmentKeyboard_location, R.drawable.ic_location_outline_24);
|
||||
|
||||
private final int titleRes;
|
||||
private final int iconRes;
|
||||
|
||||
@@ -79,8 +79,8 @@ class AttachmentKeyboardButtonAdapter extends RecyclerView.Adapter<AttachmentKey
|
||||
public ButtonViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
|
||||
this.image = itemView.findViewById(R.id.attachment_button_image);
|
||||
this.title = itemView.findViewById(R.id.attachment_button_title);
|
||||
this.image = itemView.findViewById(R.id.icon);
|
||||
this.title = itemView.findViewById(R.id.label);
|
||||
}
|
||||
|
||||
void bind(@NonNull AttachmentKeyboardButton button, boolean wallpaperEnabled, @NonNull Listener listener) {
|
||||
@@ -88,12 +88,6 @@ class AttachmentKeyboardButtonAdapter extends RecyclerView.Adapter<AttachmentKey
|
||||
title.setText(button.getTitleRes());
|
||||
|
||||
itemView.setOnClickListener(v -> listener.onClick(button));
|
||||
|
||||
if (wallpaperEnabled) {
|
||||
itemView.setBackgroundResource(R.drawable.attachment_keyboard_button_wallpaper_background);
|
||||
} else {
|
||||
itemView.setBackgroundResource(R.drawable.attachment_keyboard_button_background);
|
||||
}
|
||||
}
|
||||
|
||||
void recycle() {
|
||||
|
||||
@@ -25,7 +25,6 @@ import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.AnyThread;
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.LayoutRes;
|
||||
@@ -40,7 +39,6 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.exoplayer2.MediaItem;
|
||||
|
||||
import org.signal.core.util.ThreadUtil;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.paging.PagingController;
|
||||
import org.thoughtcrime.securesms.BindableConversationItem;
|
||||
@@ -65,10 +63,8 @@ import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
@@ -348,22 +344,22 @@ public class ConversationAdapter
|
||||
|
||||
if (type == HEADER_TYPE_POPOVER_DATE) {
|
||||
if (hasWallpaper) {
|
||||
viewHolder.setBackgroundRes(R.drawable.wallpaper_bubble_background_8);
|
||||
viewHolder.setBackgroundRes(R.drawable.wallpaper_bubble_background_18);
|
||||
} else {
|
||||
viewHolder.setBackgroundRes(R.drawable.sticky_date_header_background);
|
||||
}
|
||||
} else if (type == HEADER_TYPE_INLINE_DATE) {
|
||||
if (hasWallpaper) {
|
||||
viewHolder.setBackgroundRes(R.drawable.wallpaper_bubble_background_8);
|
||||
viewHolder.setBackgroundRes(R.drawable.wallpaper_bubble_background_18);
|
||||
} else {
|
||||
viewHolder.clearBackground();
|
||||
}
|
||||
}
|
||||
|
||||
if (hasWallpaper && ThemeUtil.isDarkTheme(context)) {
|
||||
viewHolder.setTextColor(ContextCompat.getColor(context, R.color.core_grey_15));
|
||||
viewHolder.setTextColor(ContextCompat.getColor(context, R.color.signal_colorNeutralInverse));
|
||||
} else {
|
||||
viewHolder.setTextColor(ContextCompat.getColor(context, R.color.signal_text_secondary));
|
||||
viewHolder.setTextColor(ContextCompat.getColor(context, R.color.signal_colorOnSurfaceVariant));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,7 +396,7 @@ public class ConversationAdapter
|
||||
viewHolder.setText(viewHolder.itemView.getContext().getResources().getQuantityString(R.plurals.ConversationAdapter_n_unread_messages, count, count));
|
||||
|
||||
if (hasWallpaper) {
|
||||
viewHolder.setBackgroundRes(R.drawable.wallpaper_bubble_background_8);
|
||||
viewHolder.setBackgroundRes(R.drawable.wallpaper_bubble_background_18);
|
||||
viewHolder.setDividerColor(viewHolder.itemView.getResources().getColor(R.color.transparent_black_80));
|
||||
} else {
|
||||
viewHolder.clearBackground();
|
||||
|
||||
@@ -49,10 +49,12 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.app.WindowDecorActionBar;
|
||||
import androidx.appcompat.view.ActionMode;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.app.ActivityOptionsCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.ViewKt;
|
||||
@@ -132,6 +134,7 @@ import org.thoughtcrime.securesms.jobs.MultiDeviceViewOnceOpenJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
||||
import org.thoughtcrime.securesms.longmessage.LongMessageFragment;
|
||||
import org.thoughtcrime.securesms.main.Material3OnScrollHelperBinder;
|
||||
import org.thoughtcrime.securesms.messagedetails.MessageDetailsFragment;
|
||||
import org.thoughtcrime.securesms.messagerequests.MessageRequestState;
|
||||
import org.thoughtcrime.securesms.messagerequests.MessageRequestViewModel;
|
||||
@@ -239,7 +242,6 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
private Animation mentionButtonOutAnimation;
|
||||
private OnScrollListener conversationScrollListener;
|
||||
private int lastSeenScrollOffset;
|
||||
private View toolbarShadow;
|
||||
private Stopwatch startupStopwatch;
|
||||
private LayoutTransition layoutTransition;
|
||||
private TransitionListener transitionListener;
|
||||
@@ -290,7 +292,6 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
scrollToBottomButton = view.findViewById(R.id.scroll_to_bottom);
|
||||
scrollToMentionButton = view.findViewById(R.id.scroll_to_mention);
|
||||
scrollDateHeader = view.findViewById(R.id.scroll_date_header);
|
||||
toolbarShadow = requireActivity().findViewById(R.id.conversation_toolbar_shadow);
|
||||
reactionsShade = view.findViewById(R.id.reactions_shade);
|
||||
bottomActionBar = view.findViewById(R.id.conversation_bottom_action_bar);
|
||||
|
||||
@@ -321,6 +322,8 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
list.addItemDecoration(multiselectItemDecoration);
|
||||
list.setItemAnimator(conversationItemAnimator);
|
||||
|
||||
((Material3OnScrollHelperBinder) requireParentFragment()).bindScrollHelper(list);
|
||||
|
||||
getViewLifecycleOwner().getLifecycle().addObserver(multiselectItemDecoration);
|
||||
|
||||
snapToTopDataObserver = new ConversationSnapToTopDataObserver(list, new ConversationScrollRequestValidator());
|
||||
@@ -352,7 +355,12 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
this.messageCountsViewModel = new ViewModelProvider(getParentFragment()).get(MessageCountsViewModel.class);
|
||||
this.conversationViewModel = new ViewModelProvider(getParentFragment(), new ConversationViewModel.Factory()).get(ConversationViewModel.class);
|
||||
|
||||
disposables.add(conversationViewModel.getChatColors().subscribe(recyclerViewColorizer::setChatColors));
|
||||
disposables.add(conversationViewModel.getChatColors().subscribe(chatColors -> {
|
||||
recyclerViewColorizer.setChatColors(chatColors);
|
||||
scrollToMentionButton.setUnreadCountBackgroundTint(chatColors.asSingleColor());
|
||||
scrollToBottomButton.setUnreadCountBackgroundTint(chatColors.asSingleColor());
|
||||
}));
|
||||
|
||||
disposables.add(conversationViewModel.getMessageData().subscribe(messageData -> {
|
||||
SignalLocalMetrics.ConversationOpen.onDataPostedToMain();
|
||||
|
||||
@@ -428,7 +436,6 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
getChildFragmentManager().setFragmentResultListener(ViewReceivedGiftBottomSheet.REQUEST_KEY, getViewLifecycleOwner(), (key, bundle) -> {
|
||||
if (bundle.getBoolean(ViewReceivedGiftBottomSheet.RESULT_NOT_NOW, false)) {
|
||||
Snackbar.make(view.getRootView(), R.string.ConversationFragment__you_can_redeem_your_badge_later, Snackbar.LENGTH_SHORT)
|
||||
.setTextColor(Color.WHITE)
|
||||
.show();
|
||||
}
|
||||
});
|
||||
@@ -544,6 +551,13 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
}
|
||||
|
||||
public void onWallpaperChanged(@Nullable ChatWallpaper wallpaper) {
|
||||
if (scrollDateHeader != null) {
|
||||
scrollDateHeader.setBackgroundResource(wallpaper != null ? R.drawable.sticky_date_header_background_wallpaper
|
||||
: R.drawable.sticky_date_header_background);
|
||||
scrollDateHeader.setTextColor(ContextCompat.getColor(requireContext(), wallpaper != null ? R.color.sticky_header_foreground_wallpaper
|
||||
: R.color.signal_colorOnSurfaceVariant));
|
||||
}
|
||||
|
||||
if (list != null) {
|
||||
ConversationAdapter adapter = getListAdapter();
|
||||
|
||||
@@ -686,7 +700,6 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
|
||||
conversationScrollListener = new ConversationScrollListener(requireContext());
|
||||
list.addOnScrollListener(conversationScrollListener);
|
||||
list.addOnScrollListener(new ShadowScrollListener());
|
||||
|
||||
if (oldThreadId != threadId) {
|
||||
ApplicationDependencies.getTypingStatusRepository().getTypists(oldThreadId).removeObservers(getViewLifecycleOwner());
|
||||
@@ -694,10 +707,6 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
}
|
||||
|
||||
private void initializeListAdapter() {
|
||||
if (threadId == -1) {
|
||||
toolbarShadow.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (this.recipient != null) {
|
||||
if (getListAdapter() != null && getListAdapter().isForRecipientId(this.recipient.getId())) {
|
||||
Log.d(TAG, "List adapter already initialized for " + this.recipient.getId());
|
||||
@@ -1069,7 +1078,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
}
|
||||
|
||||
private void handleDisplayDetails(ConversationMessage message) {
|
||||
MessageDetailsFragment.create(message.getMessageRecord(), recipient.getId()).show(getChildFragmentManager(), null);
|
||||
MessageDetailsFragment.create(message.getMessageRecord(), recipient.getId()).show(getParentFragment().getChildFragmentManager(), null);
|
||||
}
|
||||
|
||||
private void handleForwardMessageParts(Set<MultiselectPart> multiselectParts) {
|
||||
@@ -1301,9 +1310,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
if (!TextSecurePreferences.hasSeenSwipeToReplyTooltip(requireContext())) {
|
||||
int text = ViewUtil.isLtr(requireContext()) ? R.string.ConversationFragment_you_can_swipe_to_the_right_reply
|
||||
: R.string.ConversationFragment_you_can_swipe_to_the_left_reply;
|
||||
Snackbar.make(list, text, Snackbar.LENGTH_LONG)
|
||||
.setTextColor(Color.WHITE)
|
||||
.show();
|
||||
Snackbar.make(list, text, Snackbar.LENGTH_LONG).show();
|
||||
|
||||
TextSecurePreferences.setHasSeenSwipeToReplyTooltip(requireContext(), true);
|
||||
}
|
||||
@@ -1409,6 +1416,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
void setThreadId(long threadId);
|
||||
void handleReplyMessage(ConversationMessage conversationMessage);
|
||||
void onMessageActionToolbarOpened();
|
||||
void onMessageActionToolbarClosed();
|
||||
void onBottomActionBarVisibilityChanged(int visibility);
|
||||
void onForwardClicked();
|
||||
void onMessageRequest(@NonNull MessageRequestViewModel viewModel);
|
||||
@@ -1513,7 +1521,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
|
||||
if (actionMode != null) return;
|
||||
|
||||
MessageRecord messageRecord = item.getConversationMessage().getMessageRecord();;
|
||||
MessageRecord messageRecord = item.getConversationMessage().getMessageRecord();
|
||||
|
||||
if (messageRecord.isSecure() &&
|
||||
!messageRecord.isRemoteDelete() &&
|
||||
@@ -2191,6 +2199,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
list.invalidateItemDecorations();
|
||||
setBottomActionBarVisibility(false);
|
||||
actionMode = null;
|
||||
listener.onMessageActionToolbarClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2242,21 +2251,6 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
}
|
||||
}
|
||||
|
||||
private class ShadowScrollListener extends RecyclerView.OnScrollListener {
|
||||
@Override
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||
if (recyclerView.canScrollVertically(-1)) {
|
||||
if (toolbarShadow.getVisibility() != View.VISIBLE) {
|
||||
ViewUtil.fadeIn(toolbarShadow, 250);
|
||||
}
|
||||
} else {
|
||||
if (toolbarShadow.getVisibility() != View.GONE) {
|
||||
ViewUtil.fadeOut(toolbarShadow, 250);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class TransitionListener implements Animator.AnimatorListener {
|
||||
|
||||
private final ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Typeface;
|
||||
@@ -569,6 +570,10 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
if (conversationRecipient.getId().equals(modified.getId())) {
|
||||
setBubbleState(messageRecord, modified, modified.hasWallpaper(), colorizer);
|
||||
|
||||
if (quoteView != null) {
|
||||
quoteView.setWallpaperEnabled(modified.hasWallpaper());
|
||||
}
|
||||
|
||||
if (audioViewStub.resolved()) {
|
||||
setAudioViewTint(messageRecord);
|
||||
}
|
||||
@@ -606,7 +611,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
}
|
||||
|
||||
private void initializeAttributes() {
|
||||
defaultBubbleColor = ContextCompat.getColor(context, R.color.signal_background_secondary);
|
||||
defaultBubbleColor = ContextCompat.getColor(context, R.color.signal_colorSurfaceVariant);
|
||||
defaultBubbleColorForWallpaper = ContextCompat.getColor(context, R.color.conversation_item_wallpaper_bubble_color);
|
||||
}
|
||||
|
||||
@@ -728,8 +733,8 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
this.hasWallpaper = hasWallpaper;
|
||||
|
||||
ViewUtil.updateLayoutParams(bodyBubble, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
||||
bodyText.setTextColor(ContextCompat.getColor(getContext(), R.color.signal_text_primary));
|
||||
bodyText.setLinkTextColor(ContextCompat.getColor(getContext(), R.color.signal_text_primary));
|
||||
bodyText.setTextColor(colorizer.getIncomingBodyTextColor(context, hasWallpaper));
|
||||
bodyText.setLinkTextColor(colorizer.getIncomingBodyTextColor(context, hasWallpaper));
|
||||
|
||||
if (messageRecord.isOutgoing() && !messageRecord.isRemoteDelete()) {
|
||||
bodyBubble.getBackground().setColorFilter(recipient.getChatColors().getChatBubbleColorFilter());
|
||||
@@ -751,9 +756,9 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
footer.setOnlyShowSendingStatus(messageRecord.isRemoteDelete(), messageRecord);
|
||||
} else {
|
||||
bodyBubble.getBackground().setColorFilter(getDefaultBubbleColor(hasWallpaper), PorterDuff.Mode.SRC_IN);
|
||||
footer.setTextColor(ContextCompat.getColor(context, R.color.signal_text_secondary));
|
||||
footer.setIconColor(ContextCompat.getColor(context, R.color.signal_text_secondary));
|
||||
footer.setRevealDotColor(ContextCompat.getColor(context, R.color.signal_text_secondary));
|
||||
footer.setTextColor(colorizer.getIncomingFooterTextColor(context, hasWallpaper));
|
||||
footer.setIconColor(colorizer.getIncomingFooterIconColor(context, hasWallpaper));
|
||||
footer.setRevealDotColor(colorizer.getIncomingFooterIconColor(context, hasWallpaper));
|
||||
footer.setOnlyShowSendingStatus(false, messageRecord);
|
||||
}
|
||||
|
||||
@@ -788,15 +793,16 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
private void setAudioViewTint(MessageRecord messageRecord) {
|
||||
if (hasAudio(messageRecord)) {
|
||||
if (!messageRecord.isOutgoing()) {
|
||||
audioViewStub.get().setTint(getContext().getResources().getColor(R.color.conversation_item_incoming_audio_foreground_tint));
|
||||
if (hasWallpaper) {
|
||||
audioViewStub.get().setTint(getContext().getResources().getColor(R.color.conversation_item_incoming_audio_foreground_tint_wallpaper));
|
||||
audioViewStub.get().setProgressAndPlayBackgroundTint(getContext().getResources().getColor(R.color.conversation_item_incoming_audio_play_pause_background_tint_wallpaper));
|
||||
} else {
|
||||
audioViewStub.get().setTint(getContext().getResources().getColor(R.color.conversation_item_incoming_audio_foreground_tint_normal));
|
||||
audioViewStub.get().setProgressAndPlayBackgroundTint(getContext().getResources().getColor(R.color.conversation_item_incoming_audio_play_pause_background_tint_normal));
|
||||
}
|
||||
} else {
|
||||
audioViewStub.get().setTint(Color.WHITE);
|
||||
audioViewStub.get().setProgressAndPlayBackgroundTint(getContext().getResources().getColor(R.color.transparent_white_20));
|
||||
audioViewStub.get().setTint(getContext().getResources().getColor(R.color.conversation_item_outgoing_audio_foreground_tint));
|
||||
audioViewStub.get().setProgressAndPlayBackgroundTint(getContext().getResources().getColor(R.color.signal_colorTransparent2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1089,6 +1095,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
|
||||
linkPreviewStub.get().setOnClickListener(linkPreviewClickListener);
|
||||
linkPreviewStub.get().setOnLongClickListener(passthroughClickListener);
|
||||
linkPreviewStub.get().setBackgroundColor(getDefaultBubbleColor(hasWallpaper));
|
||||
|
||||
footer.setVisibility(VISIBLE);
|
||||
} else if (hasAudio(messageRecord)) {
|
||||
@@ -1470,10 +1477,10 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
quote.getDisplayText(),
|
||||
quote.isOriginalMissing(),
|
||||
quote.getAttachment(),
|
||||
chatColors,
|
||||
isStoryReaction(current) ? current.getBody() : null,
|
||||
quote.getQuoteType());
|
||||
|
||||
quoteView.setWallpaperEnabled(hasWallpaper);
|
||||
quoteView.setVisibility(View.VISIBLE);
|
||||
quoteView.setTextSize(TypedValue.COMPLEX_UNIT_SP, SignalStore.settings().getMessageFontSize());
|
||||
quoteView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
@@ -1951,6 +1958,10 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
|
||||
@Override
|
||||
public @NonNull ProjectionList getColorizerProjections(@NonNull ViewGroup coordinateRoot) {
|
||||
return getSnapshotProjections(coordinateRoot, true);
|
||||
}
|
||||
|
||||
public @NonNull ProjectionList getSnapshotProjections(@NonNull ViewGroup coordinateRoot, boolean clipOutMedia) {
|
||||
colorizerProjections.clear();
|
||||
|
||||
if (messageRecord.isOutgoing() &&
|
||||
@@ -1961,6 +1972,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
{
|
||||
Projection bodyBubbleToRoot = Projection.relativeToParent(coordinateRoot, bodyBubble, bodyBubbleCorners).translateX(bodyBubble.getTranslationX());
|
||||
Projection videoToBubble = bodyBubble.getVideoPlayerProjection();
|
||||
Projection mediaThumb = clipOutMedia && mediaThumbnailStub.resolved() ? Projection.relativeToParent(coordinateRoot, mediaThumbnailStub.require(), null) : null;
|
||||
|
||||
float translationX = Util.halfOffsetFromScale(bodyBubble.getWidth(), bodyBubble.getScaleX());
|
||||
float translationY = Util.halfOffsetFromScale(bodyBubble.getHeight(), bodyBubble.getScaleY());
|
||||
@@ -1981,6 +1993,13 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
}
|
||||
|
||||
colorizerProjections.addAll(projections);
|
||||
} else if (hasThumbnail(messageRecord) && mediaThumb != null) {
|
||||
colorizerProjections.add(
|
||||
bodyBubbleToRoot.insetTop(mediaThumb.getHeight())
|
||||
.scale(bodyBubble.getScaleX())
|
||||
.translateX(translationX)
|
||||
.translateY(translationY)
|
||||
);
|
||||
} else {
|
||||
colorizerProjections.add(
|
||||
bodyBubbleToRoot.scale(bodyBubble.getScaleX())
|
||||
@@ -1988,6 +2007,10 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
.translateY(translationY)
|
||||
);
|
||||
}
|
||||
|
||||
if (mediaThumb != null) {
|
||||
mediaThumb.release();
|
||||
}
|
||||
}
|
||||
|
||||
if (messageRecord.isOutgoing() &&
|
||||
@@ -2007,21 +2030,6 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
}
|
||||
}
|
||||
|
||||
if (!messageRecord.isOutgoing() &&
|
||||
hasQuote(messageRecord) &&
|
||||
quoteView != null &&
|
||||
bodyBubble.getVisibility() == VISIBLE)
|
||||
{
|
||||
bodyBubble.setQuoteViewProjection(quoteView.getProjection(bodyBubble));
|
||||
|
||||
float bubbleOffsetFromScale = Util.halfOffsetFromScale(bodyBubble.getHeight(), bodyBubble.getScaleY());
|
||||
Projection cProj = quoteView.getProjection(coordinateRoot)
|
||||
.translateX(bodyBubble.getTranslationX() + this.getTranslationX() + Util.halfOffsetFromScale(quoteView.getWidth(), bodyBubble.getScaleX()))
|
||||
.translateY(bubbleOffsetFromScale - quoteView.getY() + (quoteView.getY() * bodyBubble.getScaleY()))
|
||||
.scale(bodyBubble.getScaleX());
|
||||
colorizerProjections.add(cProj);
|
||||
}
|
||||
|
||||
for (int i = 0; i < colorizerProjections.size(); i++) {
|
||||
colorizerProjections.get(i).translateY(getTranslationY());
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ object ConversationItemSelection {
|
||||
bodyBubble.scaleX = 1.0f
|
||||
bodyBubble.scaleY = 1.0f
|
||||
|
||||
val projections = conversationItem.getColorizerProjections(list)
|
||||
val projections = conversationItem.getSnapshotProjections(list, false)
|
||||
|
||||
val path = Path()
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
@@ -68,6 +69,7 @@ import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.IdRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -81,11 +83,14 @@ import androidx.core.content.pm.ShortcutInfoCompat;
|
||||
import androidx.core.content.pm.ShortcutManagerCompat;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.core.view.MenuItemCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.airbnb.lottie.SimpleColorFilter;
|
||||
import com.annimon.stream.Collectors;
|
||||
import com.annimon.stream.Stream;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
@@ -212,6 +217,7 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel;
|
||||
import org.thoughtcrime.securesms.main.Material3OnScrollHelperBinder;
|
||||
import org.thoughtcrime.securesms.maps.PlacePickerActivity;
|
||||
import org.thoughtcrime.securesms.mediaoverview.MediaOverviewActivity;
|
||||
import org.thoughtcrime.securesms.mediasend.Media;
|
||||
@@ -282,6 +288,7 @@ import org.thoughtcrime.securesms.util.DrawableUtil;
|
||||
import org.thoughtcrime.securesms.util.FullscreenHelper;
|
||||
import org.thoughtcrime.securesms.util.IdentityUtil;
|
||||
import org.thoughtcrime.securesms.util.LifecycleDisposable;
|
||||
import org.thoughtcrime.securesms.util.Material3OnScrollHelper;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.MessageRecordUtil;
|
||||
import org.thoughtcrime.securesms.util.MessageUtil;
|
||||
@@ -319,6 +326,8 @@ import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import kotlin.Unit;
|
||||
|
||||
import static org.thoughtcrime.securesms.TransportOption.Type;
|
||||
import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||
|
||||
@@ -349,7 +358,9 @@ public class ConversationParentFragment extends Fragment
|
||||
GifKeyboardPageFragment.Host,
|
||||
EmojiKeyboardPageFragment.Callback,
|
||||
EmojiSearchFragment.Callback,
|
||||
StickerKeyboardPageFragment.Callback
|
||||
StickerKeyboardPageFragment.Callback,
|
||||
Material3OnScrollHelperBinder,
|
||||
MessageDetailsFragment.Callback
|
||||
{
|
||||
|
||||
private static final int SHORTCUT_ICON_SIZE = Build.VERSION.SDK_INT >= 26 ? ViewUtil.dpToPx(72) : ViewUtil.dpToPx(48 + 16 * 2);
|
||||
@@ -419,6 +430,7 @@ public class ConversationParentFragment extends Fragment
|
||||
private ImageView wallpaper;
|
||||
private View wallpaperDim;
|
||||
private Toolbar toolbar;
|
||||
private View toolbarBackground;
|
||||
private BroadcastReceiver pinnedShortcutReceiver;
|
||||
|
||||
private LinkPreviewViewModel linkPreviewViewModel;
|
||||
@@ -433,7 +445,7 @@ public class ConversationParentFragment extends Fragment
|
||||
private DraftViewModel draftViewModel;
|
||||
private VoiceNoteMediaController voiceNoteMediaController;
|
||||
private VoiceNotePlayerView voiceNotePlayerView;
|
||||
|
||||
private Material3OnScrollHelper material3OnScrollHelper;
|
||||
|
||||
private LiveRecipient recipient;
|
||||
private long threadId;
|
||||
@@ -1114,6 +1126,9 @@ public class ConversationParentFragment extends Fragment
|
||||
}
|
||||
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
|
||||
int toolbarTextAndIconColor = getResources().getColor(wallpaper.getDrawable() != null ? R.color.signal_colorNeutralInverse : R.color.signal_colorOnSurface);
|
||||
setToolbarActionItemTint(toolbar, toolbarTextAndIconColor);
|
||||
}
|
||||
|
||||
public void invalidateOptionsMenu() {
|
||||
@@ -1743,7 +1758,10 @@ public class ConversationParentFragment extends Fragment
|
||||
}
|
||||
}
|
||||
|
||||
noLongerMemberBanner.setVisibility(leftGroup ? View.VISIBLE : View.GONE);
|
||||
if (messageRequestBottomView.getVisibility() == View.GONE) {
|
||||
noLongerMemberBanner.setVisibility(leftGroup ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
requestingMemberBanner.setVisibility(canCancelRequest ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (canCancelRequest) {
|
||||
@@ -2092,6 +2110,7 @@ public class ConversationParentFragment extends Fragment
|
||||
|
||||
private void initializeViews(View view) {
|
||||
toolbar = view.findViewById(R.id.toolbar);
|
||||
toolbarBackground = view.findViewById(R.id.toolbar_background);
|
||||
titleView = view.findViewById(R.id.conversation_title_view);
|
||||
buttonToggle = view.findViewById(R.id.button_toggle);
|
||||
sendButton = view.findViewById(R.id.send_button);
|
||||
@@ -2124,7 +2143,6 @@ public class ConversationParentFragment extends Fragment
|
||||
Stub<ConversationReactionOverlay> reactionOverlayStub = ViewUtil.findStubById(view, R.id.conversation_reaction_scrubber_stub);
|
||||
reactionDelegate = new ConversationReactionDelegate(reactionOverlayStub);
|
||||
|
||||
|
||||
noLongerMemberBanner = view.findViewById(R.id.conversation_no_longer_member_banner);
|
||||
cannotSendInAnnouncementGroupBanner = ViewUtil.findStubById(view, R.id.conversation_cannot_send_announcement_stub);
|
||||
requestingMemberBanner = view.findViewById(R.id.conversation_requesting_banner);
|
||||
@@ -2156,7 +2174,7 @@ public class ConversationParentFragment extends Fragment
|
||||
linkPreviewViewModel.onTransportChanged(newTransport.isSms());
|
||||
composeText.setTransport(newTransport);
|
||||
|
||||
buttonToggle.getBackground().setColorFilter(newTransport.getBackgroundColor(), PorterDuff.Mode.MULTIPLY);
|
||||
buttonToggle.getBackground().setColorFilter(getButtonToggleBackgroundColor(newTransport), PorterDuff.Mode.MULTIPLY);
|
||||
buttonToggle.getBackground().invalidateSelf();
|
||||
|
||||
if (manuallySelected) recordTransportPreference(newTransport);
|
||||
@@ -2200,6 +2218,18 @@ public class ConversationParentFragment extends Fragment
|
||||
});
|
||||
|
||||
voiceNoteMediaController.getVoiceNotePlaybackState().observe(getViewLifecycleOwner(), inputPanel.getPlaybackStateObserver());
|
||||
|
||||
material3OnScrollHelper = new Material3OnScrollHelper(Collections.singletonList(toolbarBackground), Collections.emptyList(), this::updateStatusBarColor);
|
||||
}
|
||||
|
||||
private @ColorInt int getButtonToggleBackgroundColor(TransportOption newTransport) {
|
||||
if (newTransport.isSms()) {
|
||||
return newTransport.getBackgroundColor();
|
||||
} else if (recipient != null) {
|
||||
return getRecipient().getChatColors().asSingleColor();
|
||||
} else {
|
||||
return newTransport.getBackgroundColor();
|
||||
}
|
||||
}
|
||||
|
||||
private @NonNull VoiceNotePlayerView requireVoiceNotePlayerView() {
|
||||
@@ -2221,12 +2251,12 @@ public class ConversationParentFragment extends Fragment
|
||||
attachmentKeyboardStub.get().setWallpaperEnabled(true);
|
||||
}
|
||||
|
||||
int toolbarColor = getResources().getColor(R.color.conversation_toolbar_color_wallpaper);
|
||||
toolbar.setBackgroundColor(toolbarColor);
|
||||
// TODO [alex] LargeScreenSupport -- statusBarBox
|
||||
if (Build.VERSION.SDK_INT > 23) {
|
||||
WindowUtil.setStatusBarColor(requireActivity().getWindow(), toolbarColor);
|
||||
}
|
||||
toolbarBackground.setBackgroundResource(R.color.material3_toolbar_background_wallpaper);
|
||||
updateStatusBarColor(toolbarBackground.isActivated());
|
||||
int toolbarTextAndIconColor = getResources().getColor(R.color.signal_colorNeutralInverse);
|
||||
toolbar.setTitleTextColor(toolbarTextAndIconColor);
|
||||
setToolbarActionItemTint(toolbar, toolbarTextAndIconColor);
|
||||
|
||||
} else {
|
||||
wallpaper.setImageDrawable(null);
|
||||
wallpaperDim.setVisibility(View.GONE);
|
||||
@@ -2235,14 +2265,56 @@ public class ConversationParentFragment extends Fragment
|
||||
attachmentKeyboardStub.get().setWallpaperEnabled(false);
|
||||
}
|
||||
|
||||
int toolbarColor = getResources().getColor(R.color.conversation_toolbar_color);
|
||||
toolbar.setBackgroundColor(toolbarColor);
|
||||
// TODO [alex] LargeScreenSupport -- statusBarBox
|
||||
if (Build.VERSION.SDK_INT > 23) {
|
||||
WindowUtil.setStatusBarColor(requireActivity().getWindow(), toolbarColor);
|
||||
}
|
||||
toolbarBackground.setBackgroundResource(R.color.material3_toolbar_background);
|
||||
updateStatusBarColor(toolbarBackground.isActivated());
|
||||
int toolbarTextAndIconColor = getResources().getColor(R.color.signal_colorOnSurface);
|
||||
toolbar.setTitleTextColor(toolbarTextAndIconColor);
|
||||
setToolbarActionItemTint(toolbar, toolbarTextAndIconColor);
|
||||
}
|
||||
fragment.onWallpaperChanged(chatWallpaper);
|
||||
messageRequestBottomView.setWallpaperEnabled(chatWallpaper != null);
|
||||
}
|
||||
|
||||
private Unit updateStatusBarColor(boolean isActive) {
|
||||
// TODO [alex] LargeScreenSupport -- statusBarBox
|
||||
if (Build.VERSION.SDK_INT > 23) {
|
||||
boolean hasWallpaper = wallpaper.getDrawable() != null;
|
||||
int toolbarColor = isActive ? getActiveToolbarColor(requireContext(), hasWallpaper)
|
||||
: getInactiveToolbarColor(requireContext(), hasWallpaper);
|
||||
|
||||
WindowUtil.setStatusBarColor(requireActivity().getWindow(), toolbarColor);
|
||||
}
|
||||
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
|
||||
private static @ColorInt int getActiveToolbarColor(@NonNull Context context, boolean hasWallpaper) {
|
||||
int colorRes = hasWallpaper ? R.color.conversation_toolbar_color_wallpaper_scrolled
|
||||
: R.color.signal_colorSurface2;
|
||||
|
||||
return ContextCompat.getColor(context, colorRes);
|
||||
}
|
||||
|
||||
private static @ColorInt int getInactiveToolbarColor(@NonNull Context context, boolean hasWallpaper) {
|
||||
int colorRes = hasWallpaper ? R.color.conversation_toolbar_color_wallpaper
|
||||
: R.color.signal_colorBackground;
|
||||
|
||||
return ContextCompat.getColor(context, colorRes);
|
||||
}
|
||||
|
||||
private void setToolbarActionItemTint(@NonNull Toolbar toolbar, @ColorInt int tint) {
|
||||
for (int i = 0; i < toolbar.getMenu().size(); i++) {
|
||||
MenuItem menuItem = toolbar.getMenu().getItem(i);
|
||||
MenuItemCompat.setIconTintList(menuItem, ColorStateList.valueOf(tint));
|
||||
}
|
||||
|
||||
if (toolbar.getNavigationIcon() != null) {
|
||||
toolbar.getNavigationIcon().setColorFilter(new SimpleColorFilter(tint));
|
||||
}
|
||||
|
||||
if (toolbar.getOverflowIcon() != null) {
|
||||
toolbar.getOverflowIcon().setColorFilter(new SimpleColorFilter(tint));
|
||||
}
|
||||
}
|
||||
|
||||
protected void initializeActionBar() {
|
||||
@@ -3547,6 +3619,16 @@ public class ConversationParentFragment extends Fragment
|
||||
StickerSearchDialogFragment.show(getChildFragmentManager());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindScrollHelper(@NonNull RecyclerView recyclerView) {
|
||||
recyclerView.addOnScrollListener(material3OnScrollHelper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageDetailsFragmentDismissed() {
|
||||
updateStatusBarColor(toolbarBackground.isActivated());
|
||||
}
|
||||
|
||||
// Listeners
|
||||
|
||||
private final class DeleteCanceledVoiceNoteListener implements ListenableFuture.Listener<VoiceNoteDraft> {
|
||||
@@ -3950,6 +4032,12 @@ public class ConversationParentFragment extends Fragment
|
||||
@Override
|
||||
public void onMessageActionToolbarOpened() {
|
||||
searchViewItem.collapseActionView();
|
||||
toolbar.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageActionToolbarClosed() {
|
||||
toolbar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -4206,18 +4294,23 @@ public class ConversationParentFragment extends Fragment
|
||||
{
|
||||
Log.d(TAG, "[presentMessageRequestState] Have extra, so ignoring provided state.");
|
||||
messageRequestBottomView.setVisibility(View.GONE);
|
||||
inputPanel.setVisibility(View.VISIBLE);
|
||||
} else if (isPushGroupV1Conversation() && !isActiveGroup()) {
|
||||
Log.d(TAG, "[presentMessageRequestState] Inactive push group V1, so ignoring provided state.");
|
||||
messageRequestBottomView.setVisibility(View.GONE);
|
||||
inputPanel.setVisibility(View.VISIBLE);
|
||||
} else if (messageData == null) {
|
||||
Log.d(TAG, "[presentMessageRequestState] Null messageData. Ignoring.");
|
||||
} else if (messageData.getMessageState() == MessageRequestState.NONE) {
|
||||
Log.d(TAG, "[presentMessageRequestState] No message request necessary.");
|
||||
messageRequestBottomView.setVisibility(View.GONE);
|
||||
inputPanel.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
Log.d(TAG, "[presentMessageRequestState] " + messageData.getMessageState());
|
||||
messageRequestBottomView.setMessageData(messageData);
|
||||
messageRequestBottomView.setVisibility(View.VISIBLE);
|
||||
noLongerMemberBanner.setVisibility(View.GONE);
|
||||
inputPanel.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
invalidateOptionsMenu();
|
||||
|
||||
@@ -13,8 +13,10 @@ import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.content.res.ColorStateListInflaterCompat;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.Observer;
|
||||
@@ -175,14 +177,6 @@ public final class ConversationUpdateItem extends FrameLayout
|
||||
textColor = ContextCompat.getColor(getContext(), R.color.core_grey_15);
|
||||
}
|
||||
|
||||
if (!ThemeUtil.isDarkTheme(getContext())) {
|
||||
if (hasWallpaper) {
|
||||
actionButton.setStrokeColor(ColorStateList.valueOf(getResources().getColor(R.color.core_grey_45)));
|
||||
} else {
|
||||
actionButton.setStrokeColor(ColorStateList.valueOf(getResources().getColor(R.color.signal_button_secondary_stroke)));
|
||||
}
|
||||
}
|
||||
|
||||
UpdateDescription updateDescription = Objects.requireNonNull(messageRecord.getUpdateDisplayBody(getContext(), eventListener::onRecipientNameClicked));
|
||||
LiveData<SpannableString> liveUpdateMessage = LiveUpdateMessage.fromMessageDescription(getContext(), updateDescription, textColor, true);
|
||||
LiveData<SpannableString> spannableMessage = loading(liveUpdateMessage);
|
||||
@@ -195,6 +189,8 @@ public final class ConversationUpdateItem extends FrameLayout
|
||||
shouldCollapse(messageRecord, nextMessageRecord),
|
||||
hasWallpaper);
|
||||
|
||||
presentActionButton(hasWallpaper);
|
||||
|
||||
updateSelectedState();
|
||||
}
|
||||
|
||||
@@ -645,6 +641,16 @@ public final class ConversationUpdateItem extends FrameLayout
|
||||
}
|
||||
}
|
||||
|
||||
private void presentActionButton(boolean hasWallpaper) {
|
||||
if (hasWallpaper) {
|
||||
actionButton.setBackgroundTintList(AppCompatResources.getColorStateList(getContext(), R.color.conversation_update_item_button_background_wallpaper));
|
||||
actionButton.setTextColor(AppCompatResources.getColorStateList(getContext(), R.color.conversation_update_item_button_text_color_wallpaper));
|
||||
} else {
|
||||
actionButton.setBackgroundTintList(AppCompatResources.getColorStateList(getContext(), R.color.conversation_update_item_button_background_normal));
|
||||
actionButton.setTextColor(AppCompatResources.getColorStateList(getContext(), R.color.conversation_update_item_button_text_color_normal));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSameType(@NonNull MessageRecord current, @NonNull MessageRecord candidate) {
|
||||
return (current.isGroupUpdate() && candidate.isGroupUpdate()) ||
|
||||
(current.isProfileChange() && candidate.isProfileChange()) ||
|
||||
|
||||
@@ -16,7 +16,6 @@ import androidx.annotation.ColorInt
|
||||
import com.google.common.base.Objects
|
||||
import kotlinx.parcelize.IgnoredOnParcel
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.signal.core.util.ColorUtil
|
||||
import org.thoughtcrime.securesms.components.RotatableGradientDrawable
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.ChatColor
|
||||
import org.thoughtcrime.securesms.util.customizeOnDraw
|
||||
@@ -77,10 +76,7 @@ class ChatColors(
|
||||
}
|
||||
|
||||
if (linearGradient != null) {
|
||||
val start = linearGradient.colors.first()
|
||||
val end = linearGradient.colors.last()
|
||||
|
||||
return ColorUtil.blendARGB(start, end, 0.5f)
|
||||
return linearGradient.colors.last()
|
||||
}
|
||||
|
||||
throw AssertionError()
|
||||
|
||||
@@ -9,13 +9,9 @@ object ChatColorsPalette {
|
||||
// region Default
|
||||
|
||||
@JvmField
|
||||
val ULTRAMARINE = ChatColors.forGradient(
|
||||
val ULTRAMARINE = ChatColors.forColor(
|
||||
ChatColors.Id.BuiltIn,
|
||||
ChatColors.LinearGradient(
|
||||
180.0f,
|
||||
intArrayOf(0xFF0552F0.toInt(), 0xFF2C6BED.toInt()),
|
||||
floatArrayOf(0f, 1f)
|
||||
)
|
||||
0xFF315FF4.toInt()
|
||||
)
|
||||
|
||||
// endregion
|
||||
|
||||
@@ -22,17 +22,44 @@ class Colorizer {
|
||||
|
||||
@ColorInt
|
||||
fun getOutgoingBodyTextColor(context: Context): Int {
|
||||
return ContextCompat.getColor(context, R.color.white)
|
||||
return ContextCompat.getColor(context, R.color.conversation_outgoing_body_color)
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
fun getOutgoingFooterTextColor(context: Context): Int {
|
||||
return ContextCompat.getColor(context, R.color.conversation_item_outgoing_footer_fg)
|
||||
return ContextCompat.getColor(context, R.color.conversation_outgoing_footer_color)
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
fun getOutgoingFooterIconColor(context: Context): Int {
|
||||
return ContextCompat.getColor(context, R.color.conversation_item_outgoing_footer_fg)
|
||||
return ContextCompat.getColor(context, R.color.conversation_outgoing_footer_color)
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
fun getIncomingBodyTextColor(context: Context, hasWallpaper: Boolean): Int {
|
||||
return if (hasWallpaper) {
|
||||
ContextCompat.getColor(context, R.color.signal_colorNeutralInverse)
|
||||
} else {
|
||||
ContextCompat.getColor(context, R.color.signal_colorOnSurface)
|
||||
}
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
fun getIncomingFooterTextColor(context: Context, hasWallpaper: Boolean): Int {
|
||||
return if (hasWallpaper) {
|
||||
ContextCompat.getColor(context, R.color.signal_colorNeutralVariantInverse)
|
||||
} else {
|
||||
ContextCompat.getColor(context, R.color.signal_colorOnSurfaceVariant)
|
||||
}
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
fun getIncomingFooterIconColor(context: Context, hasWallpaper: Boolean): Int {
|
||||
return if (hasWallpaper) {
|
||||
ContextCompat.getColor(context, R.color.signal_colorNeutralVariantInverse)
|
||||
} else {
|
||||
ContextCompat.getColor(context, R.color.signal_colorOnSurfaceVariant)
|
||||
}
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
|
||||
Reference in New Issue
Block a user