Implement new Material3 spec.

This commit is contained in:
Alex Hart
2022-05-26 17:32:52 -03:00
committed by Greyson Parrelli
parent 556e480b06
commit 1b471e163d
374 changed files with 3219 additions and 3049 deletions

View File

@@ -3,9 +3,6 @@ package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
@@ -42,7 +39,6 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.ui.bottomsheet.RecipientBottomSheetDialogFragment;
import org.thoughtcrime.securesms.util.AvatarUtil;
import org.thoughtcrime.securesms.util.BlurTransformation;
import org.thoughtcrime.securesms.util.ThemeUtil;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
@@ -58,24 +54,8 @@ public final class AvatarImageView extends AppCompatImageView {
@SuppressWarnings("unused")
private static final String TAG = Log.tag(AvatarImageView.class);
private static final Paint LIGHT_THEME_OUTLINE_PAINT = new Paint();
private static final Paint DARK_THEME_OUTLINE_PAINT = new Paint();
static {
LIGHT_THEME_OUTLINE_PAINT.setColor(Color.argb((int) (255 * 0.2), 0, 0, 0));
LIGHT_THEME_OUTLINE_PAINT.setStyle(Paint.Style.STROKE);
LIGHT_THEME_OUTLINE_PAINT.setStrokeWidth(1);
LIGHT_THEME_OUTLINE_PAINT.setAntiAlias(true);
DARK_THEME_OUTLINE_PAINT.setColor(Color.argb((int) (255 * 0.2), 255, 255, 255));
DARK_THEME_OUTLINE_PAINT.setStyle(Paint.Style.STROKE);
DARK_THEME_OUTLINE_PAINT.setStrokeWidth(1);
DARK_THEME_OUTLINE_PAINT.setAntiAlias(true);
}
private int size;
private boolean inverted;
private Paint outlinePaint;
private OnClickListener listener;
private Recipient.FallbackPhotoProvider fallbackPhotoProvider;
private boolean blurred;
@@ -105,8 +85,6 @@ public final class AvatarImageView extends AppCompatImageView {
typedArray.recycle();
}
outlinePaint = ThemeUtil.isDarkTheme(context) ? DARK_THEME_OUTLINE_PAINT : LIGHT_THEME_OUTLINE_PAINT;
unknownRecipientDrawable = new ResourceContactPhoto(R.drawable.ic_profile_outline_40, R.drawable.ic_profile_outline_20).asDrawable(context, AvatarColor.UNKNOWN, inverted);
blurred = false;
chatColors = null;
@@ -117,20 +95,6 @@ public final class AvatarImageView extends AppCompatImageView {
super.setClipBounds(clipBounds);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float width = getWidth() - getPaddingRight() - getPaddingLeft();
float height = getHeight() - getPaddingBottom() - getPaddingTop();
float cx = width / 2f;
float cy = height / 2f;
float radius = Math.min(cx, cy) - (outlinePaint.getStrokeWidth() / 2f);
canvas.translate(getPaddingLeft(), getPaddingTop());
canvas.drawCircle(cx, cy, radius, outlinePaint);
}
@Override
public void setOnClickListener(OnClickListener listener) {
this.listener = listener;

View File

@@ -11,7 +11,6 @@ import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.core.content.ContextCompat;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.attachments.Attachment;
@@ -31,7 +30,6 @@ public class ConversationItemThumbnail extends FrameLayout {
private ImageView shade;
private ConversationItemFooter footer;
private CornerMask cornerMask;
private Outliner outliner;
private Outliner pulseOutliner;
private boolean borderless;
private int[] normalBounds;
@@ -61,9 +59,6 @@ public class ConversationItemThumbnail extends FrameLayout {
this.shade = findViewById(R.id.conversation_thumbnail_shade);
this.footer = findViewById(R.id.conversation_thumbnail_footer);
this.cornerMask = new CornerMask(this);
this.outliner = new Outliner();
outliner.setColor(ContextCompat.getColor(getContext(), R.color.signal_inverse_transparent_20));
int gifWidth = ViewUtil.dpToPx(260);
if (attrs != null) {
@@ -98,10 +93,6 @@ public class ConversationItemThumbnail extends FrameLayout {
if (!borderless) {
cornerMask.mask(canvas);
if (album.getVisibility() != VISIBLE) {
outliner.draw(canvas);
}
}
if (pulseOutliner != null) {
@@ -150,7 +141,6 @@ public class ConversationItemThumbnail extends FrameLayout {
public void setCorners(int topLeft, int topRight, int bottomRight, int bottomLeft) {
cornerMask.setRadii(topLeft, topRight, bottomRight, bottomLeft);
outliner.setRadii(topLeft, topRight, bottomRight, bottomLeft);
}
public void setMinimumThumbnailWidth(int width) {

View File

@@ -7,9 +7,12 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.airbnb.lottie.SimpleColorFilter;
import org.thoughtcrime.securesms.R;
public final class ConversationScrollToView extends FrameLayout {
@@ -43,6 +46,10 @@ public final class ConversationScrollToView extends FrameLayout {
}
}
public void setUnreadCountBackgroundTint(@ColorInt int tint) {
unreadCount.getBackground().setColorFilter(new SimpleColorFilter(tint));
}
@Override
public void setOnClickListener(@Nullable OnClickListener l) {
scrollButton.setOnClickListener(l);

View File

@@ -4,8 +4,6 @@ import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.style.CharacterStyle;
import android.util.AttributeSet;
@@ -49,13 +47,11 @@ public class FromTextView extends SimpleEmojiTextView {
public void setText(Recipient recipient, @Nullable CharSequence fromString, boolean read, @Nullable String suffix) {
SpannableStringBuilder builder = new SpannableStringBuilder();
SpannableString fromSpan = new SpannableString(fromString);
fromSpan.setSpan(getFontSpan(!read), 0, fromSpan.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
if (recipient.isSelf()) {
builder.append(getContext().getString(R.string.note_to_self));
} else {
builder.append(fromSpan);
builder.append(fromString);
}
if (suffix != null) {
@@ -85,8 +81,4 @@ public class FromTextView extends SimpleEmojiTextView {
return mutedDrawable;
}
private CharacterStyle getFontSpan(boolean isBold) {
return isBold ? SpanUtil.getBoldSpan() : SpanUtil.getNormalSpan();
}
}

View File

@@ -15,6 +15,7 @@ import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.Interpolator;
import android.view.animation.TranslateAnimation;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
@@ -77,8 +78,8 @@ public class InputPanel extends LinearLayout
private LinkPreviewView linkPreview;
private EmojiToggle mediaKeyboard;
private ComposeText composeText;
private View quickCameraToggle;
private View quickAudioToggle;
private ImageButton quickCameraToggle;
private ImageButton quickAudioToggle;
private AnimatingToggle buttonToggle;
private SendButton sendButton;
private View recordingContainer;
@@ -182,7 +183,7 @@ public class InputPanel extends LinearLayout
@NonNull SlideDeck attachments,
@NonNull QuoteModel.Type quoteType)
{
this.quoteView.setQuote(glideRequests, id, author, body, false, attachments, null, null, quoteType);
this.quoteView.setQuote(glideRequests, id, author, body, false, attachments, null, quoteType);
int originalHeight = this.quoteView.getVisibility() == VISIBLE ? this.quoteView.getMeasuredHeight()
: 0;
@@ -322,13 +323,34 @@ public class InputPanel extends LinearLayout
}
public void setWallpaperEnabled(boolean enabled) {
final int iconTint;
final int textColor;
final int textHintColor;
if (enabled) {
iconTint = getContext().getResources().getColor(R.color.signal_colorNeutralInverse);
textColor = getContext().getResources().getColor(R.color.signal_colorNeutralInverse);
textHintColor = getContext().getResources().getColor(R.color.signal_colorNeutralVariantInverse);
setBackground(new ColorDrawable(getContext().getResources().getColor(R.color.wallpaper_compose_background)));
composeContainer.setBackground(Objects.requireNonNull(ContextCompat.getDrawable(getContext(), R.drawable.compose_background_wallpaper)));
quickAudioToggle.setColorFilter(iconTint);
quickCameraToggle.setColorFilter(iconTint);
} else {
setBackground(new ColorDrawable(getContext().getResources().getColor(R.color.signal_background_primary)));
iconTint = getContext().getResources().getColor(R.color.signal_colorOnSurface);
textColor = getContext().getResources().getColor(R.color.signal_colorOnSurface);
textHintColor = getContext().getResources().getColor(R.color.signal_colorOnSurfaceVariant);
setBackground(new ColorDrawable(getContext().getResources().getColor(R.color.signal_colorSurface)));
composeContainer.setBackground(Objects.requireNonNull(ContextCompat.getDrawable(getContext(), R.drawable.compose_background)));
}
mediaKeyboard.setColorFilter(iconTint);
quickAudioToggle.setColorFilter(iconTint);
quickCameraToggle.setColorFilter(iconTint);
composeText.setTextColor(textColor);
composeText.setHintTextColor(textHintColor);
quoteView.setWallpaperEnabled(enabled);
}
public void setHideForGroupState(boolean hideForGroupState) {

View File

@@ -13,7 +13,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
@@ -51,7 +50,6 @@ public class LinkPreviewView extends FrameLayout {
private int type;
private int defaultRadius;
private CornerMask cornerMask;
private Outliner outliner;
private CloseClickedListener closeClickedListener;
public LinkPreviewView(Context context) {
@@ -78,9 +76,6 @@ public class LinkPreviewView extends FrameLayout {
noPreview = findViewById(R.id.linkpreview_no_preview);
defaultRadius = getResources().getDimensionPixelSize(R.dimen.thumbnail_default_radius);
cornerMask = new CornerMask(this);
outliner = new Outliner();
outliner.setColor(ContextCompat.getColor(getContext(), R.color.signal_inverse_transparent_20));
if (attrs != null) {
TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.LinkPreviewView, 0, 0);
@@ -112,7 +107,6 @@ public class LinkPreviewView extends FrameLayout {
if (type == TYPE_COMPOSE) return;
cornerMask.mask(canvas);
outliner.draw(canvas);
}
public void setLoading() {
@@ -185,11 +179,9 @@ public class LinkPreviewView extends FrameLayout {
public void setCorners(int topStart, int topEnd) {
if (ViewUtil.isRtl(this)) {
cornerMask.setRadii(topEnd, topStart, 0, 0);
outliner.setRadii(topEnd, topStart, 0, 0);
thumbnail.setCorners(defaultRadius, topEnd, defaultRadius, defaultRadius);
} else {
cornerMask.setRadii(topStart, topEnd, 0, 0);
outliner.setRadii(topStart, topEnd, 0, 0);
thumbnail.setCorners(topStart, defaultRadius, defaultRadius, defaultRadius);
}
postInvalidate();

View File

@@ -0,0 +1,87 @@
package org.thoughtcrime.securesms.components
import android.content.Context
import android.graphics.PointF
import android.os.Build
import android.util.AttributeSet
import android.view.View
import android.view.ViewAnimationUtils
import android.widget.EditText
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.animation.addListener
import androidx.core.widget.addTextChangedListener
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.util.ViewUtil
import org.thoughtcrime.securesms.util.visible
/**
* Search Toolbar following the Signal Material3 design spec.
*/
class Material3SearchToolbar @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : ConstraintLayout(context, attrs) {
var listener: Listener? = null
private val input: EditText
private val circularRevealPoint = PointF()
init {
inflate(context, R.layout.material3_serarch_toolbar, this)
input = findViewById(R.id.search_input)
val close = findViewById<View>(R.id.search_close)
val clear = findViewById<View>(R.id.search_clear)
close.setOnClickListener { collapse() }
clear.setOnClickListener { input.setText("") }
input.addTextChangedListener(afterTextChanged = {
clear.visible = !it.isNullOrBlank()
listener?.onSearchTextChange(it?.toString() ?: "")
})
}
fun display(x: Float, y: Float) {
if (Build.VERSION.SDK_INT < 21) {
visibility = VISIBLE
ViewUtil.focusAndShowKeyboard(input)
} else if (!visible) {
circularRevealPoint.set(x, y)
val animator = ViewAnimationUtils.createCircularReveal(this, x.toInt(), y.toInt(), 0f, width.toFloat())
animator.duration = 400
visibility = VISIBLE
ViewUtil.focusAndShowKeyboard(input)
animator.start()
}
}
fun collapse() {
if (visibility == VISIBLE) {
listener?.onSearchClosed()
ViewUtil.hideKeyboard(context, input)
if (Build.VERSION.SDK_INT >= 21) {
val animator = ViewAnimationUtils.createCircularReveal(this, circularRevealPoint.x.toInt(), circularRevealPoint.y.toInt(), width.toFloat(), 0f)
animator.duration = 400
animator.addListener(onEnd = {
visibility = INVISIBLE
})
animator.start()
} else {
visibility = INVISIBLE
}
}
}
interface Listener {
fun onSearchTextChange(text: String)
fun onSearchClosed()
}
}

View File

@@ -4,7 +4,6 @@ package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -17,7 +16,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.content.ContextCompat;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.google.android.material.imageview.ShapeableImageView;
@@ -30,7 +28,7 @@ import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.components.emoji.EmojiImageView;
import org.thoughtcrime.securesms.components.mention.MentionAnnotation;
import org.thoughtcrime.securesms.conversation.colors.ChatColors;
import org.thoughtcrime.securesms.components.quotes.QuoteViewColorTheme;
import org.thoughtcrime.securesms.database.model.Mention;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
import org.thoughtcrime.securesms.mms.GlideRequests;
@@ -43,7 +41,6 @@ import org.thoughtcrime.securesms.recipients.RecipientForeverObserver;
import org.thoughtcrime.securesms.stories.StoryTextPostModel;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.Projection;
import org.thoughtcrime.securesms.util.ThemeUtil;
import org.thoughtcrime.securesms.util.Util;
import java.io.IOException;
@@ -103,6 +100,7 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
private int smallCornerRadius;
private CornerMask cornerMask;
private QuoteModel.Type quoteType;
private boolean isWallpaperEnabled;
private int thumbHeight;
private int thumbWidth;
@@ -151,19 +149,12 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
cornerMask = new CornerMask(this);
if (attrs != null) {
TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.QuoteView, 0, 0);
int primaryColor = typedArray.getColor(R.styleable.QuoteView_quote_colorPrimary, Color.BLACK);
int secondaryColor = typedArray.getColor(R.styleable.QuoteView_quote_colorSecondary, Color.BLACK);
TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.QuoteView, 0, 0);
messageType = MessageType.fromCode(typedArray.getInt(R.styleable.QuoteView_message_type, 0));
typedArray.recycle();
dismissView.setVisibility(messageType == MessageType.PREVIEW ? VISIBLE : GONE);
authorView.setTextColor(primaryColor);
bodyView.setTextColor(primaryColor);
attachmentNameView.setTextColor(primaryColor);
mediaDescriptionText.setTextColor(secondaryColor);
missingLinkText.setTextColor(primaryColor);
}
setMessageType(messageType);
@@ -211,7 +202,6 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
@Nullable CharSequence body,
boolean originalMissing,
@NonNull SlideDeck attachments,
@Nullable ChatColors chatColors,
@Nullable String storyReaction,
@NonNull QuoteModel.Type quoteType)
{
@@ -228,12 +218,7 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
setQuoteText(resolveBody(body, quoteType), attachments, originalMissing, storyReaction);
setQuoteAttachment(glideRequests, body, attachments, originalMissing);
setQuoteMissingFooter(originalMissing);
if (Build.VERSION.SDK_INT < 21 && messageType == MessageType.INCOMING && chatColors != null) {
this.setBackgroundColor(chatColors.asSingleColor());
} else {
this.setBackground(null);
}
applyColorTheme();
}
private @Nullable CharSequence resolveBody(@Nullable CharSequence body, @NonNull QuoteModel.Type quoteType) {
@@ -255,6 +240,11 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
setVisibility(GONE);
}
public void setWallpaperEnabled(boolean isWallpaperEnabled) {
this.isWallpaperEnabled = isWallpaperEnabled;
applyColorTheme();
}
@Override
public void onRecipientChanged(@NonNull Recipient recipient) {
setQuoteAuthor(recipient);
@@ -269,9 +259,6 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
}
private void setQuoteAuthor(@NonNull Recipient author) {
boolean outgoing = messageType != MessageType.INCOMING && messageType != MessageType.STORY_REPLY_INCOMING;
boolean preview = messageType == MessageType.PREVIEW || messageType == MessageType.STORY_REPLY_PREVIEW;
if (isStoryReply()) {
authorView.setText(author.isSelf() ? getContext().getString(R.string.QuoteView_your_story)
: getContext().getString(R.string.QuoteView_s_story, author.getDisplayName(getContext())));
@@ -279,19 +266,6 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
authorView.setText(author.isSelf() ? getContext().getString(R.string.QuoteView_you)
: author.getDisplayName(getContext()));
}
quoteBarView.setBackgroundColor(ContextCompat.getColor(getContext(), outgoing || isStoryReply() ? R.color.core_white : android.R.color.transparent));
int mainViewColor;
if (preview) {
mainViewColor = R.color.quote_preview_background;
} else if (!outgoing && isStoryReply()) {
mainViewColor = R.color.quote_incoming_story_background;
} else {
mainViewColor = R.color.quote_view_background;
}
mainView.setBackgroundColor(ContextCompat.getColor(getContext(), mainViewColor));
}
private boolean isStoryReply() {
@@ -450,15 +424,10 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
attachmentContainerView.setVisibility(GONE);
dismissView.setBackgroundDrawable(null);
}
if (ThemeUtil.isDarkTheme(getContext())) {
dismissView.setBackgroundResource(R.drawable.circle_alpha);
}
}
private void setQuoteMissingFooter(boolean missing) {
footerView.setVisibility(missing && !isStoryReply() ? VISIBLE : GONE);
footerView.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.quote_view_background));
}
private @Nullable StoryTextPostModel getStoryTextPost(@Nullable CharSequence body) {
@@ -515,4 +484,20 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
.build();
}
}
private void applyColorTheme() {
boolean isOutgoing = messageType != MessageType.INCOMING && messageType != MessageType.STORY_REPLY_INCOMING;
boolean isPreview = messageType == MessageType.PREVIEW || messageType == MessageType.STORY_REPLY_PREVIEW;
QuoteViewColorTheme quoteViewColorTheme = QuoteViewColorTheme.resolveTheme(isOutgoing, isPreview, isWallpaperEnabled);
quoteBarView.setBackgroundColor(quoteViewColorTheme.getBarColor(getContext()));
mainView.setBackgroundColor(quoteViewColorTheme.getBackgroundColor(getContext()));
authorView.setTextColor(quoteViewColorTheme.getForegroundColor(getContext()));
bodyView.setTextColor(quoteViewColorTheme.getForegroundColor(getContext()));
attachmentNameView.setTextColor(quoteViewColorTheme.getForegroundColor(getContext()));
mediaDescriptionText.setTextColor(quoteViewColorTheme.getForegroundColor(getContext()));
missingLinkText.setTextColor(quoteViewColorTheme.getForegroundColor(getContext()));
footerView.setBackgroundColor(quoteViewColorTheme.getBackgroundColor(getContext()));
}
}

View File

@@ -26,17 +26,17 @@ public class EmojiToggle extends AppCompatImageButton implements MediaKeyboard.M
public EmojiToggle(Context context) {
super(context);
initialize(null);
initialize();
}
public EmojiToggle(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(attrs);
initialize();
}
public EmojiToggle(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize(attrs);
initialize();
}
public void setToMedia() {
@@ -47,18 +47,11 @@ public class EmojiToggle extends AppCompatImageButton implements MediaKeyboard.M
setImageDrawable(imeToggle);
}
private void initialize(@Nullable AttributeSet attrs) {
boolean forceOutline = false;
if (attrs != null) {
TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.EmojiToggle, 0, 0);
forceOutline = typedArray.getBoolean(R.styleable.EmojiToggle_force_outline, false);
typedArray.recycle();
}
this.emojiToggle = ContextUtil.requireDrawable(getContext(), forceOutline ? R.drawable.ic_emoji_outline : R.drawable.ic_emoji);
private void initialize() {
this.emojiToggle = ContextUtil.requireDrawable(getContext(), R.drawable.ic_emoji);
this.stickerToggle = ContextUtil.requireDrawable(getContext(), R.drawable.ic_sticker_24);
this.gifToggle = ContextUtil.requireDrawable(getContext(), R.drawable.ic_gif_24);
this.imeToggle = ContextUtil.requireDrawable(getContext(), forceOutline ? R.drawable.ic_keyboard_outline_24 : R.drawable.ic_keyboard_24);
this.imeToggle = ContextUtil.requireDrawable(getContext(), R.drawable.ic_keyboard_24);
this.mediaToggle = emojiToggle;
setToMedia();

View File

@@ -0,0 +1,51 @@
package org.thoughtcrime.securesms.components.quotes
import android.content.Context
import androidx.core.content.ContextCompat
import org.thoughtcrime.securesms.R
enum class QuoteViewColorTheme(
private val backgroundColorRes: Int,
private val barColorRes: Int,
private val foregroundColorRes: Int
) {
INCOMING_WALLPAPER(
R.color.quote_view_background_incoming_wallpaper,
R.color.quote_view_bar_incoming_wallpaper,
R.color.quote_view_foreground_incoming_wallpaper
),
INCOMING_NORMAL(
R.color.quote_view_background_incoming_normal,
R.color.quote_view_bar_incoming_normal,
R.color.quote_view_foreground_incoming_normal
),
OUTGOING_WALLPAPER(
R.color.quote_view_background_outgoing_wallpaper,
R.color.quote_view_bar_outgoing_wallpaper,
R.color.quote_view_foreground_outgoing_wallpaper
),
OUTGOING_NORMAL(
R.color.quote_view_background_outgoing_normal,
R.color.quote_view_bar_outgoing_normal,
R.color.quote_view_foreground_outgoing_normal
);
fun getBackgroundColor(context: Context) = ContextCompat.getColor(context, backgroundColorRes)
fun getBarColor(context: Context) = ContextCompat.getColor(context, barColorRes)
fun getForegroundColor(context: Context) = ContextCompat.getColor(context, foregroundColorRes)
companion object {
@JvmStatic
fun resolveTheme(isOutgoing: Boolean, isPreview: Boolean, hasWallpaper: Boolean): QuoteViewColorTheme {
return when {
isPreview && hasWallpaper -> INCOMING_WALLPAPER
isPreview && !hasWallpaper -> INCOMING_NORMAL
isOutgoing && hasWallpaper -> OUTGOING_WALLPAPER
!isOutgoing && hasWallpaper -> INCOMING_WALLPAPER
isOutgoing && !hasWallpaper -> OUTGOING_NORMAL
else -> INCOMING_NORMAL
}
}
}
}

View File

@@ -6,11 +6,13 @@ import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.button.MaterialButton;
import org.thoughtcrime.securesms.R;
import java.util.concurrent.TimeUnit;
public class CallMeCountDownView extends androidx.appcompat.widget.AppCompatButton {
public class CallMeCountDownView extends MaterialButton {
private long countDownToTime;
@Nullable

View File

@@ -15,8 +15,7 @@ import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.recyclerview.OnScrollAnimationHelper
import org.thoughtcrime.securesms.components.recyclerview.ToolbarShadowAnimationHelper
import org.thoughtcrime.securesms.util.Material3OnScrollHelper
abstract class DSLSettingsFragment(
@StringRes private val titleId: Int = -1,
@@ -28,12 +27,9 @@ abstract class DSLSettingsFragment(
protected var recyclerView: RecyclerView? = null
private set
private var scrollAnimationHelper: OnScrollAnimationHelper? = null
@CallSuper
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val toolbar: Toolbar? = view.findViewById(R.id.toolbar)
val toolbarShadow: View? = view.findViewById(R.id.toolbar_shadow)
if (titleId != -1) {
toolbar?.setTitle(titleId)
@@ -48,10 +44,6 @@ abstract class DSLSettingsFragment(
toolbar?.setOnMenuItemClickListener { onOptionsItemSelected(it) }
}
if (toolbarShadow != null) {
scrollAnimationHelper = getOnScrollAnimationHelper(toolbarShadow)
}
val settingsAdapter = DSLSettingsAdapter()
recyclerView = view.findViewById<RecyclerView>(R.id.recycler).apply {
@@ -59,23 +51,25 @@ abstract class DSLSettingsFragment(
layoutManager = layoutManagerProducer(requireContext())
adapter = settingsAdapter
val helper = scrollAnimationHelper
if (helper != null) {
addOnScrollListener(helper)
getMaterial3OnScrollHelper(toolbar)?.let {
addOnScrollListener(it)
}
}
bindAdapter(settingsAdapter)
}
open fun getMaterial3OnScrollHelper(toolbar: Toolbar?): Material3OnScrollHelper? {
if (toolbar == null) {
return null
}
return Material3OnScrollHelper(requireActivity(), toolbar)
}
override fun onDestroyView() {
super.onDestroyView()
recyclerView = null
scrollAnimationHelper = null
}
protected open fun getOnScrollAnimationHelper(toolbarShadow: View): OnScrollAnimationHelper {
return ToolbarShadowAnimationHelper(toolbarShadow)
}
abstract fun bindAdapter(adapter: DSLSettingsAdapter)

View File

@@ -65,7 +65,7 @@ sealed class DSLSettingsText {
}
}
object Title2BoldModifier : TextAppearanceModifier(R.style.TextAppearance_Signal_Title2_Bold)
object TitleLargeModifier : TextAppearanceModifier(R.style.Signal_Text_TitleLarge)
object Body1BoldModifier : TextAppearanceModifier(R.style.TextAppearance_Signal_Body1_Bold)
open class TextAppearanceModifier(@StyleRes private val textAppearance: Int) : Modifier {

View File

@@ -101,7 +101,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men
clickPref(
title = DSLSettingsText.from(R.string.preferences_chats__chats),
icon = DSLSettingsIcon.from(R.drawable.ic_message_tinted_bitmap_24),
icon = DSLSettingsIcon.from(R.drawable.ic_chat_message_24),
onClick = {
findNavController().safeNavigate(R.id.action_appSettingsFragment_to_chatsSettingsFragment)
}

View File

@@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.components.settings.app.account
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.Typeface
import android.text.InputType
import android.util.DisplayMetrics
@@ -42,7 +41,7 @@ class AccountSettingsFragment : DSLSettingsFragment(R.string.AccountSettingsFrag
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == CreateKbsPinActivity.REQUEST_NEW_PIN && resultCode == CreateKbsPinActivity.RESULT_OK) {
Snackbar.make(requireView(), R.string.ConfirmKbsPinFragment__pin_created, Snackbar.LENGTH_LONG).setTextColor(Color.WHITE).show()
Snackbar.make(requireView(), R.string.ConfirmKbsPinFragment__pin_created, Snackbar.LENGTH_LONG).show()
}
}

View File

@@ -11,7 +11,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.lock.PinHashing
import org.thoughtcrime.securesms.registration.fragments.BaseRegistrationLockFragment
import org.thoughtcrime.securesms.registration.viewmodel.BaseRegistrationViewModel
import org.thoughtcrime.securesms.util.CircularProgressButtonUtil.cancelSpinning
import org.thoughtcrime.securesms.util.CommunicationActions
import org.thoughtcrime.securesms.util.SupportEmailUtil
import org.thoughtcrime.securesms.util.navigation.safeNavigate
@@ -45,7 +44,7 @@ class ChangeNumberRegistrationLockFragment : BaseRegistrationLockFragment(R.layo
override fun handleSuccessfulPinEntry(pin: String) {
val pinsDiffer: Boolean = SignalStore.kbsValues().localPinHash?.let { !PinHashing.verifyLocalPinHash(it, pin) } ?: false
cancelSpinning(pinButton)
pinButton.cancelSpinning()
if (pinsDiffer) {
findNavController().safeNavigate(ChangeNumberRegistrationLockFragmentDirections.actionChangeNumberRegistrationLockToChangeNumberPinDiffers())

View File

@@ -1,12 +1,9 @@
package org.thoughtcrime.securesms.components.settings.app.notifications.profiles
import android.graphics.Color
import android.os.Bundle
import android.view.View
import androidx.core.content.ContextCompat
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import com.dd.CircularProgressButton
import com.google.android.material.snackbar.Snackbar
import io.reactivex.rxjava3.kotlin.subscribeBy
import org.thoughtcrime.securesms.R
@@ -22,6 +19,7 @@ import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.util.LifecycleDisposable
import org.thoughtcrime.securesms.util.navigation.safeNavigate
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton
/**
* Show and allow addition of recipients to a profile during the create flow.
@@ -37,7 +35,7 @@ class AddAllowedMembersFragment : DSLSettingsFragment(layoutId = R.layout.fragme
lifecycleDisposable.bindTo(viewLifecycleOwner.lifecycle)
view.findViewById<CircularProgressButton>(R.id.add_allowed_members_profile_next).apply {
view.findViewById<CircularProgressMaterialButton>(R.id.add_allowed_members_profile_next).apply {
setOnClickListener {
findNavController().safeNavigate(AddAllowedMembersFragmentDirections.actionAddAllowedMembersFragmentToEditNotificationProfileScheduleFragment(profileId, true))
}
@@ -87,8 +85,6 @@ class AddAllowedMembersFragment : DSLSettingsFragment(layoutId = R.layout.fragme
view?.let { view ->
Snackbar.make(view, getString(R.string.NotificationProfileDetails__s_removed, removed.getDisplayName(requireContext())), Snackbar.LENGTH_LONG)
.setAction(R.string.NotificationProfileDetails__undo) { undoRemove(id) }
.setActionTextColor(ContextCompat.getColor(requireContext(), R.color.core_ultramarine_light))
.setTextColor(Color.WHITE)
.show()
}
}

View File

@@ -11,7 +11,6 @@ import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import com.dd.CircularProgressButton
import com.google.android.material.textfield.TextInputLayout
import io.reactivex.rxjava3.kotlin.subscribeBy
import org.signal.core.util.BreakIteratorCompat
@@ -24,11 +23,11 @@ import org.thoughtcrime.securesms.components.settings.app.notifications.profiles
import org.thoughtcrime.securesms.components.settings.app.notifications.profiles.models.NotificationProfileNamePreset
import org.thoughtcrime.securesms.reactions.any.ReactWithAnyEmojiBottomSheetDialogFragment
import org.thoughtcrime.securesms.util.BottomSheetUtil
import org.thoughtcrime.securesms.util.CircularProgressButtonUtil
import org.thoughtcrime.securesms.util.LifecycleDisposable
import org.thoughtcrime.securesms.util.ViewUtil
import org.thoughtcrime.securesms.util.navigation.safeNavigate
import org.thoughtcrime.securesms.util.text.AfterTextChanged
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton
/**
* Dual use Edit/Create notification profile fragment. Use to create in the create profile flow,
@@ -58,7 +57,7 @@ class EditNotificationProfileFragment : DSLSettingsFragment(layoutId = R.layout.
val title: TextView = view.findViewById(R.id.edit_notification_profile_title)
val countView: TextView = view.findViewById(R.id.edit_notification_profile_count)
val saveButton: CircularProgressButton = view.findViewById(R.id.edit_notification_profile_save)
val saveButton: CircularProgressMaterialButton = view.findViewById(R.id.edit_notification_profile_save)
val emojiView: ImageView = view.findViewById(R.id.edit_notification_profile_emoji)
val nameView: EditText = view.findViewById(R.id.edit_notification_profile_name)
val nameTextWrapper: TextInputLayout = view.findViewById(R.id.edit_notification_profile_name_wrapper)
@@ -90,8 +89,8 @@ class EditNotificationProfileFragment : DSLSettingsFragment(layoutId = R.layout.
}
lifecycleDisposable += viewModel.save(nameView.text.toString())
.doOnSubscribe { CircularProgressButtonUtil.setSpinning(saveButton) }
.doAfterTerminate { CircularProgressButtonUtil.cancelSpinning(saveButton) }
.doOnSubscribe { saveButton.setSpinning() }
.doAfterTerminate { saveButton.cancelSpinning() }
.subscribeBy(
onSuccess = { saveResult ->
when (saveResult) {

View File

@@ -15,7 +15,6 @@ import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import com.dd.CircularProgressButton
import com.google.android.material.switchmaterial.SwitchMaterial
import com.google.android.material.timepicker.MaterialTimePicker
import com.google.android.material.timepicker.TimeFormat
@@ -28,6 +27,7 @@ import org.thoughtcrime.securesms.util.ViewUtil
import org.thoughtcrime.securesms.util.formatHours
import org.thoughtcrime.securesms.util.navigation.safeNavigate
import org.thoughtcrime.securesms.util.orderOfDaysInWeek
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton
import org.thoughtcrime.securesms.util.visible
import java.time.DayOfWeek
import java.time.LocalTime
@@ -75,7 +75,7 @@ class EditNotificationProfileScheduleFragment : LoggingFragment(R.layout.fragmen
val startTime: TextView = view.findViewById(R.id.edit_notification_profile_schedule_start_time)
val endTime: TextView = view.findViewById(R.id.edit_notification_profile_schedule_end_time)
val next: CircularProgressButton = view.findViewById(R.id.edit_notification_profile_schedule__next)
val next: CircularProgressMaterialButton = view.findViewById(R.id.edit_notification_profile_schedule__next)
next.setOnClickListener {
lifecycleDisposable += viewModel.save(createMode)
.subscribeBy(

View File

@@ -1,6 +1,5 @@
package org.thoughtcrime.securesms.components.settings.app.notifications.profiles
import android.graphics.Color
import android.os.Bundle
import android.view.View
import androidx.appcompat.widget.Toolbar
@@ -147,8 +146,6 @@ class NotificationProfileDetailsFragment : DSLSettingsFragment() {
view?.let { view ->
Snackbar.make(view, getString(R.string.NotificationProfileDetails__s_removed, removed.getDisplayName(requireContext())), Snackbar.LENGTH_LONG)
.setAction(R.string.NotificationProfileDetails__undo) { undoRemove(id) }
.setActionTextColor(ContextCompat.getColor(requireContext(), R.color.core_ultramarine_light))
.setTextColor(Color.WHITE)
.show()
}
}

View File

@@ -8,7 +8,6 @@ import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import com.dd.CircularProgressButton
import io.reactivex.rxjava3.kotlin.subscribeBy
import org.thoughtcrime.securesms.ContactSelectionListFragment
import org.thoughtcrime.securesms.LoggingFragment
@@ -17,10 +16,10 @@ import org.thoughtcrime.securesms.components.ContactFilterView
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader
import org.thoughtcrime.securesms.groups.SelectionLimits
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.util.CircularProgressButtonUtil
import org.thoughtcrime.securesms.util.LifecycleDisposable
import org.thoughtcrime.securesms.util.Util
import org.thoughtcrime.securesms.util.ViewUtil
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton
import java.util.Optional
import java.util.function.Consumer
@@ -32,7 +31,7 @@ class SelectRecipientsFragment : LoggingFragment(), ContactSelectionListFragment
private val viewModel: SelectRecipientsViewModel by viewModels(factoryProducer = this::createFactory)
private val lifecycleDisposable = LifecycleDisposable()
private var addToProfile: CircularProgressButton? = null
private var addToProfile: CircularProgressMaterialButton? = null
private fun createFactory(): ViewModelProvider.Factory {
val args = SelectRecipientsFragmentArgs.fromBundle(requireArguments())
@@ -86,8 +85,8 @@ class SelectRecipientsFragment : LoggingFragment(), ContactSelectionListFragment
addToProfile = view.findViewById(R.id.select_recipients_add)
addToProfile?.setOnClickListener {
lifecycleDisposable += viewModel.updateAllowedMembers()
.doOnSubscribe { CircularProgressButtonUtil.setSpinning(addToProfile) }
.doOnTerminate { CircularProgressButtonUtil.cancelSpinning(addToProfile) }
.doOnSubscribe { addToProfile?.setSpinning() }
.doOnTerminate { addToProfile?.cancelSpinning() }
.subscribeBy(onSuccess = { findNavController().navigateUp() })
}

View File

@@ -8,7 +8,6 @@ import android.widget.Toast
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.NavHostFragment
import androidx.recyclerview.widget.RecyclerView
import com.dd.CircularProgressButton
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.settings.DSLConfiguration
import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter
@@ -22,6 +21,7 @@ import org.thoughtcrime.securesms.util.ViewUtil
import org.thoughtcrime.securesms.util.livedata.ProcessState
import org.thoughtcrime.securesms.util.livedata.distinctUntilChanged
import org.thoughtcrime.securesms.util.navigation.safeNavigate
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton
/**
* Depending on the arguments, can be used to set the universal expire timer, set expire timer
@@ -32,7 +32,7 @@ class ExpireTimerSettingsFragment : DSLSettingsFragment(
layoutId = R.layout.expire_timer_settings_fragment
) {
private lateinit var save: CircularProgressButton
private lateinit var save: CircularProgressMaterialButton
private lateinit var viewModel: ExpireTimerSettingsViewModel
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -62,9 +62,7 @@ class ExpireTimerSettingsFragment : DSLSettingsFragment(
viewModel.state.distinctUntilChanged(ExpireTimerSettingsState::saveState).observe(viewLifecycleOwner) { state ->
when (val saveState: ProcessState<Int> = state.saveState) {
is ProcessState.Working -> {
save.isClickable = false
save.isIndeterminateProgressMode = true
save.progress = 50
save.setSpinning()
}
is ProcessState.Success -> {
if (state.isGroupCreate) {
@@ -79,9 +77,7 @@ class ExpireTimerSettingsFragment : DSLSettingsFragment(
viewModel.resetError()
}
else -> {
save.isClickable = true
save.isIndeterminateProgressMode = false
save.progress = 0
save.cancelSpinning()
}
}
}

View File

@@ -160,7 +160,7 @@ class BoostFragment : DSLSettingsBottomSheetFragment(
sectionHeaderPref(
title = DSLSettingsText.from(
R.string.BoostFragment__give_signal_a_boost,
DSLSettingsText.CenterModifier, DSLSettingsText.Title2BoldModifier
DSLSettingsText.CenterModifier, DSLSettingsText.TitleLargeModifier
)
)

View File

@@ -90,7 +90,7 @@ class ManageDonationsFragment : DSLSettingsFragment(), ExpiredGiftSheet.Callback
sectionHeaderPref(
title = DSLSettingsText.from(
R.string.SubscribeFragment__signal_is_powered_by_people_like_you,
DSLSettingsText.CenterModifier, DSLSettingsText.Title2BoldModifier
DSLSettingsText.CenterModifier, DSLSettingsText.TitleLargeModifier
)
)
@@ -215,7 +215,7 @@ class ManageDonationsFragment : DSLSettingsFragment(), ExpiredGiftSheet.Callback
space(DimensionUnit.DP.toPixels(16f).toInt())
primaryButton(
tonalButton(
text = DSLSettingsText.from(R.string.ManageDonationsFragment__make_a_monthly_donation),
onClick = {
findNavController().safeNavigate(R.id.action_manageDonationsFragment_to_subscribeFragment)

View File

@@ -1,7 +1,6 @@
package org.thoughtcrime.securesms.components.settings.app.subscription.subscribe
import android.content.DialogInterface
import android.graphics.Color
import android.text.SpannableStringBuilder
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
@@ -138,7 +137,7 @@ class SubscribeFragment : DSLSettingsFragment(
sectionHeaderPref(
title = DSLSettingsText.from(
R.string.SubscribeFragment__signal_is_powered_by_people_like_you,
DSLSettingsText.CenterModifier, DSLSettingsText.Title2BoldModifier
DSLSettingsText.CenterModifier, DSLSettingsText.TitleLargeModifier
)
)
@@ -300,9 +299,7 @@ class SubscribeFragment : DSLSettingsFragment(
}
private fun onSubscriptionCancelled() {
Snackbar.make(requireView(), R.string.SubscribeFragment__your_subscription_has_been_cancelled, Snackbar.LENGTH_LONG)
.setTextColor(Color.WHITE)
.show()
Snackbar.make(requireView(), R.string.SubscribeFragment__your_subscription_has_been_cancelled, Snackbar.LENGTH_LONG).show()
requireActivity().finish()
requireActivity().startActivity(AppSettingsActivity.home(requireContext()))

View File

@@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.components.settings.conversation
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.graphics.Rect
@@ -24,6 +23,7 @@ import app.cash.exhaustive.Exhaustive
import com.google.android.flexbox.FlexboxLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import org.signal.core.util.DimensionUnit
import org.thoughtcrime.securesms.AvatarPreviewActivity
import org.thoughtcrime.securesms.BlockUnblockDialog
import org.thoughtcrime.securesms.InviteActivity
@@ -38,7 +38,6 @@ import org.thoughtcrime.securesms.badges.models.Badge
import org.thoughtcrime.securesms.badges.view.ViewBadgeBottomSheetDialogFragment
import org.thoughtcrime.securesms.components.AvatarImageView
import org.thoughtcrime.securesms.components.recyclerview.OnScrollAnimationHelper
import org.thoughtcrime.securesms.components.recyclerview.ToolbarShadowAnimationHelper
import org.thoughtcrime.securesms.components.settings.DSLConfiguration
import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter
import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment
@@ -83,7 +82,6 @@ import org.thoughtcrime.securesms.util.CommunicationActions
import org.thoughtcrime.securesms.util.ContextUtil
import org.thoughtcrime.securesms.util.ExpirationUtil
import org.thoughtcrime.securesms.util.FeatureFlags
import org.thoughtcrime.securesms.util.ThemeUtil
import org.thoughtcrime.securesms.util.ViewUtil
import org.thoughtcrime.securesms.util.navigation.safeNavigate
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog
@@ -161,6 +159,8 @@ class ConversationSettingsFragment : DSLSettingsFragment(
}
super.onViewCreated(view, savedInstanceState)
recyclerView?.addOnScrollListener(ConversationSettingsOnUserScrolledAnimationHelper(toolbarAvatarContainer, toolbarTitle, toolbarBackground))
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@@ -179,10 +179,6 @@ class ConversationSettingsFragment : DSLSettingsFragment(
}
}
override fun getOnScrollAnimationHelper(toolbarShadow: View): OnScrollAnimationHelper {
return ConversationSettingsOnUserScrolledAnimationHelper(toolbarAvatarContainer, toolbarTitle, toolbarBackground, toolbarShadow)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return if (item.itemId == R.id.action_edit) {
val args = ConversationSettingsFragmentArgs.fromBundle(requireArguments())
@@ -767,19 +763,18 @@ class ConversationSettingsFragment : DSLSettingsFragment(
showMembersAdded.membersAddedCount
)
Snackbar.make(requireView(), string, Snackbar.LENGTH_SHORT).setTextColor(Color.WHITE).show()
Snackbar.make(requireView(), string, Snackbar.LENGTH_SHORT).show()
}
private class ConversationSettingsOnUserScrolledAnimationHelper(
private val toolbarAvatar: View,
private val toolbarTitle: View,
private val toolbarBackground: View,
toolbarShadow: View
) : ToolbarShadowAnimationHelper(toolbarShadow) {
private val toolbarBackground: View
) : OnScrollAnimationHelper() {
override val duration: Long = 200L
private val actionBarSize = ThemeUtil.getThemedDimen(toolbarShadow.context, R.attr.actionBarSize)
private val actionBarSize = DimensionUnit.DP.toPixels(64f)
private val rect = Rect()
override fun getAnimationState(recyclerView: RecyclerView): AnimationState {
@@ -805,8 +800,6 @@ class ConversationSettingsFragment : DSLSettingsFragment(
}
override fun show(duration: Long) {
super.show(duration)
toolbarAvatar
.animate()
.setDuration(duration)
@@ -826,8 +819,6 @@ class ConversationSettingsFragment : DSLSettingsFragment(
}
override fun hide(duration: Long) {
super.hide(duration)
toolbarAvatar
.animate()
.setDuration(duration)

View File

@@ -158,6 +158,15 @@ class DSLConfiguration {
children.add(preference)
}
fun tonalButton(
text: DSLSettingsText,
isEnabled: Boolean = true,
onClick: () -> Unit
) {
val preference = Button.Model.Tonal(text, null, isEnabled, onClick)
children.add(preference)
}
fun secondaryButtonNoOutline(
text: DSLSettingsText,
icon: DSLSettingsIcon? = null,

View File

@@ -14,6 +14,7 @@ object Button {
fun register(mappingAdapter: MappingAdapter) {
mappingAdapter.registerFactory(Model.Primary::class.java, LayoutFactory({ ViewHolder(it) }, R.layout.dsl_button_primary))
mappingAdapter.registerFactory(Model.Tonal::class.java, LayoutFactory({ ViewHolder(it) }, R.layout.dsl_button_tonal))
mappingAdapter.registerFactory(Model.SecondaryNoOutline::class.java, LayoutFactory({ ViewHolder(it) }, R.layout.dsl_button_secondary))
}
@@ -34,6 +35,13 @@ object Button {
onClick: () -> Unit
) : Model<Primary>(title, icon, isEnabled, onClick)
class Tonal(
title: DSLSettingsText?,
icon: DSLSettingsIcon?,
isEnabled: Boolean,
onClick: () -> Unit
) : Model<Tonal>(title, icon, isEnabled, onClick)
class SecondaryNoOutline(
title: DSLSettingsText?,
icon: DSLSettingsIcon?,
@@ -44,7 +52,7 @@ object Button {
class ViewHolder<T : Model<T>>(itemView: View) : MappingViewHolder<T>(itemView) {
private val button: MaterialButton = itemView as MaterialButton
private val button: MaterialButton = itemView.findViewById(R.id.button)
override fun bind(model: T) {
button.text = model.title?.resolve(context)

View File

@@ -93,7 +93,7 @@ class VoiceNotePlayerView @JvmOverloads constructor(
playPauseToggleView.addValueCallback(
KeyPath("**"),
LottieProperty.COLOR_FILTER,
LottieValueCallback(SimpleColorFilter(ContextCompat.getColor(context, R.color.signal_icon_tint_primary)))
LottieValueCallback(SimpleColorFilter(ContextCompat.getColor(context, R.color.signal_colorOnSurface)))
)
}