kopia lustrzana https://github.com/ryukoposting/Signal-Android
Implement new Material3 spec.
rodzic
556e480b06
commit
1b471e163d
|
@ -10,12 +10,6 @@ apply plugin: 'kotlin-parcelize'
|
|||
apply from: 'static-ips.gradle'
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url "https://raw.github.com/signalapp/maven/master/circular-progress-button/releases/"
|
||||
content {
|
||||
includeGroupByRegex "com\\.github\\.dmytrodanylyk\\.circular-progress-button\\.*"
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url "https://raw.github.com/signalapp/maven/master/sqlcipher/release/"
|
||||
content {
|
||||
|
@ -508,7 +502,6 @@ dependencies {
|
|||
implementation libs.lottie
|
||||
|
||||
implementation libs.stickyheadergrid
|
||||
implementation libs.circular.progress.button
|
||||
|
||||
implementation libs.signal.android.database.sqlcipher
|
||||
implementation libs.androidx.sqlite
|
||||
|
|
|
@ -58,9 +58,9 @@ import com.google.android.material.chip.ChipGroup;
|
|||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.pnikosis.materialishprogress.ProgressWheel;
|
||||
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.components.RecyclerViewFastScroller;
|
||||
import org.thoughtcrime.securesms.components.recyclerview.ToolbarShadowAnimationHelper;
|
||||
import org.thoughtcrime.securesms.contacts.AbstractContactsCursorLoader;
|
||||
import org.thoughtcrime.securesms.contacts.ContactChip;
|
||||
import org.thoughtcrime.securesms.contacts.ContactSelectionListAdapter;
|
||||
|
@ -85,7 +85,6 @@ import org.thoughtcrime.securesms.util.UsernameUtil;
|
|||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.adapter.FixedViewsAdapter;
|
||||
import org.thoughtcrime.securesms.util.adapter.RecyclerViewConcatenateAdapterStickyHeader;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -138,8 +137,7 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
|||
private HorizontalScrollView chipGroupScrollContainer;
|
||||
private OnSelectionLimitReachedListener onSelectionLimitReachedListener;
|
||||
private AbstractContactsCursorLoaderFactoryProvider cursorFactoryProvider;
|
||||
private View shadowView;
|
||||
private ToolbarShadowAnimationHelper toolbarShadowAnimationHelper;
|
||||
|
||||
private HeaderActionProvider headerActionProvider;
|
||||
private TextView headerActionView;
|
||||
|
||||
|
@ -253,14 +251,10 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
|||
chipGroup = view.findViewById(R.id.chipGroup);
|
||||
chipGroupScrollContainer = view.findViewById(R.id.chipGroupScrollContainer);
|
||||
constraintLayout = view.findViewById(R.id.container);
|
||||
shadowView = view.findViewById(R.id.toolbar_shadow);
|
||||
headerActionView = view.findViewById(R.id.header_action);
|
||||
|
||||
toolbarShadowAnimationHelper = new ToolbarShadowAnimationHelper(shadowView);
|
||||
|
||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(requireContext());
|
||||
|
||||
recyclerView.addOnScrollListener(toolbarShadowAnimationHelper);
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.setItemAnimator(new DefaultItemAnimator() {
|
||||
@Override
|
||||
|
|
|
@ -125,10 +125,10 @@ public class MainActivity extends PassphraseRequiredActivity implements VoiceNot
|
|||
private void updateTabVisibility() {
|
||||
if (Stories.isFeatureEnabled()) {
|
||||
findViewById(R.id.conversation_list_tabs).setVisibility(View.VISIBLE);
|
||||
WindowUtil.setNavigationBarColor(getWindow(), ContextCompat.getColor(this, R.color.signal_colorSecondaryContainer));
|
||||
WindowUtil.setNavigationBarColor(getWindow(), ContextCompat.getColor(this, R.color.signal_colorSurface2));
|
||||
} else {
|
||||
findViewById(R.id.conversation_list_tabs).setVisibility(View.GONE);
|
||||
WindowUtil.setNavigationBarColor(getWindow(), ContextCompat.getColor(this, R.color.signal_background_primary));
|
||||
WindowUtil.setNavigationBarColor(getWindow(), ContextCompat.getColor(this, R.color.signal_colorBackground));
|
||||
conversationListTabsViewModel.onChatsSelected();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,14 +81,7 @@ class AvatarPickerFragment : Fragment(R.layout.avatar_picker_fragment) {
|
|||
}
|
||||
|
||||
clearButton.visible = state.canClear
|
||||
|
||||
val wasEnabled = saveButton.isEnabled
|
||||
saveButton.isEnabled = state.canSave
|
||||
if (wasEnabled != state.canSave) {
|
||||
val alpha = if (state.canSave) 1f else 0.5f
|
||||
saveButton.animate().cancel()
|
||||
saveButton.animate().alpha(alpha)
|
||||
}
|
||||
saveButton.isClickable = state.canSave
|
||||
|
||||
val items = state.selectableAvatars.map { AvatarPickerItem.Model(it, it == state.currentAvatar) }
|
||||
val selectedPosition = items.indexOfFirst { it.isSelected }
|
||||
|
@ -104,6 +97,11 @@ class AvatarPickerFragment : Fragment(R.layout.avatar_picker_fragment) {
|
|||
photoButton.setOnIconClickedListener { openGallery() }
|
||||
textButton.setOnIconClickedListener { openTextEditor(null) }
|
||||
saveButton.setOnClickListener { v ->
|
||||
if (!saveButton.isEnabled) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
saveButton.isEnabled = false
|
||||
viewModel.save(
|
||||
{
|
||||
setFragmentResult(
|
||||
|
|
|
@ -31,7 +31,7 @@ object ExpiredGiftSheetConfiguration {
|
|||
textPref(
|
||||
title = DSLSettingsText.from(
|
||||
stringId = R.string.ExpiredGiftSheetConfiguration__your_gift_badge_has_expired,
|
||||
DSLSettingsText.CenterModifier, DSLSettingsText.Title2BoldModifier
|
||||
DSLSettingsText.CenterModifier, DSLSettingsText.TitleLargeModifier
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ class GiftThanksSheet : DSLSettingsBottomSheetFragment() {
|
|||
private fun getConfiguration(recipient: Recipient): DSLConfiguration {
|
||||
return configure {
|
||||
textPref(
|
||||
title = DSLSettingsText.from(R.string.SubscribeThanksForYourSupportBottomSheetDialogFragment__thanks_for_your_support, DSLSettingsText.Title2BoldModifier, DSLSettingsText.CenterModifier)
|
||||
title = DSLSettingsText.from(R.string.SubscribeThanksForYourSupportBottomSheetDialogFragment__thanks_for_your_support, DSLSettingsText.TitleLargeModifier, DSLSettingsText.CenterModifier)
|
||||
)
|
||||
|
||||
noPadTextPref(
|
||||
|
|
|
@ -158,7 +158,7 @@ class ViewReceivedGiftBottomSheet : DSLSettingsBottomSheetFragment() {
|
|||
noPadTextPref(
|
||||
title = DSLSettingsText.from(
|
||||
charSequence = requireContext().getString(R.string.ViewReceivedGiftBottomSheet__s_sent_you_a_gift, state.recipient.getShortDisplayName(requireContext())),
|
||||
DSLSettingsText.CenterModifier, DSLSettingsText.Title2BoldModifier
|
||||
DSLSettingsText.CenterModifier, DSLSettingsText.TitleLargeModifier
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ class ViewSentGiftBottomSheet : DSLSettingsBottomSheetFragment() {
|
|||
noPadTextPref(
|
||||
title = DSLSettingsText.from(
|
||||
stringId = R.string.ViewSentGiftBottomSheet__thanks_for_your_support,
|
||||
DSLSettingsText.CenterModifier, DSLSettingsText.Title2BoldModifier
|
||||
DSLSettingsText.CenterModifier, DSLSettingsText.TitleLargeModifier
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.badges.self.featured
|
|||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import org.thoughtcrime.securesms.R
|
||||
|
@ -11,13 +12,12 @@ import org.thoughtcrime.securesms.badges.Badges
|
|||
import org.thoughtcrime.securesms.badges.Badges.displayBadges
|
||||
import org.thoughtcrime.securesms.badges.models.Badge
|
||||
import org.thoughtcrime.securesms.badges.models.BadgePreview
|
||||
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
|
||||
import org.thoughtcrime.securesms.components.settings.configure
|
||||
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
||||
import org.thoughtcrime.securesms.util.Material3OnScrollHelper
|
||||
|
||||
/**
|
||||
* Fragment which allows user to select one of their badges to be their "Featured" badge.
|
||||
|
@ -46,8 +46,8 @@ class SelectFeaturedBadgeFragment : DSLSettingsFragment(
|
|||
}
|
||||
}
|
||||
|
||||
override fun getOnScrollAnimationHelper(toolbarShadow: View): OnScrollAnimationHelper {
|
||||
return ToolbarShadowAnimationHelper(scrollShadow)
|
||||
override fun getMaterial3OnScrollHelper(toolbar: Toolbar?): Material3OnScrollHelper? {
|
||||
return Material3OnScrollHelper(requireActivity(), scrollShadow)
|
||||
}
|
||||
|
||||
override fun bindAdapter(adapter: DSLSettingsAdapter) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.thoughtcrime.securesms.badges.self.none
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.viewModels
|
||||
import org.signal.core.util.DimensionUnit
|
||||
|
@ -40,7 +41,7 @@ class BecomeASustainerFragment : DSLSettingsBottomSheetFragment() {
|
|||
title = DSLSettingsText.from(
|
||||
R.string.BecomeASustainerFragment__get_badges,
|
||||
DSLSettingsText.CenterModifier,
|
||||
DSLSettingsText.Title2BoldModifier
|
||||
DSLSettingsText.TitleLargeModifier
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -49,13 +50,15 @@ class BecomeASustainerFragment : DSLSettingsBottomSheetFragment() {
|
|||
noPadTextPref(
|
||||
title = DSLSettingsText.from(
|
||||
R.string.BecomeASustainerFragment__signal_is_a_non_profit,
|
||||
DSLSettingsText.CenterModifier
|
||||
DSLSettingsText.CenterModifier,
|
||||
DSLSettingsText.TextAppearanceModifier(R.style.Signal_Text_BodyMedium),
|
||||
DSLSettingsText.ColorModifier(ContextCompat.getColor(requireContext(), R.color.signal_colorOnSurfaceVariant))
|
||||
)
|
||||
)
|
||||
|
||||
space(DimensionUnit.DP.toPixels(77f).toInt())
|
||||
space(DimensionUnit.DP.toPixels(32f).toInt())
|
||||
|
||||
primaryButton(
|
||||
tonalButton(
|
||||
text = DSLSettingsText.from(
|
||||
R.string.BecomeASustainerMegaphone__become_a_sustainer
|
||||
),
|
||||
|
@ -65,7 +68,7 @@ class BecomeASustainerFragment : DSLSettingsBottomSheetFragment() {
|
|||
}
|
||||
)
|
||||
|
||||
space(DimensionUnit.DP.toPixels(8f).toInt())
|
||||
space(DimensionUnit.DP.toPixels(32f).toInt())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -171,6 +171,6 @@ public class BlockedUsersActivity extends PassphraseRequiredActivity implements
|
|||
throw new IllegalArgumentException("Unsupported event type " + event);
|
||||
}
|
||||
|
||||
Snackbar.make(view, getString(messageResId, displayName), Snackbar.LENGTH_SHORT).setTextColor(Color.WHITE).show();
|
||||
Snackbar.make(view, getString(messageResId, displayName), Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() })
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -61,8 +61,8 @@ public final class ContactChip extends Chip {
|
|||
.placeholder(fallbackContactPhotoDrawable)
|
||||
.fallback(fallbackContactPhotoDrawable)
|
||||
.error(fallbackContactPhotoDrawable)
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
.circleCrop()
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
.into(new CustomTarget<Drawable>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
|
||||
|
|
|
@ -28,7 +28,7 @@ class LetterHeaderDecoration(private val context: Context, private val hideDecor
|
|||
color = ContextCompat.getColor(context, R.color.signal_text_primary)
|
||||
isAntiAlias = true
|
||||
style = Paint.Style.FILL
|
||||
typeface = Typeface.create("sans-serif-medium", Typeface.BOLD)
|
||||
typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL)
|
||||
textAlign = Paint.Align.LEFT
|
||||
textSize = ViewUtil.spToPx(16f).toFloat()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -37,7 +37,6 @@ import org.thoughtcrime.securesms.R;
|
|||
import org.thoughtcrime.securesms.components.registration.PulsingFloatingActionButton;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.util.ConversationUtil;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.task.SnackbarAsyncTask;
|
||||
import org.thoughtcrime.securesms.util.views.Stub;
|
||||
|
||||
|
@ -72,14 +71,8 @@ public class ConversationListArchiveFragment extends ConversationListFragment im
|
|||
coordinator = view.findViewById(R.id.coordinator);
|
||||
list = view.findViewById(R.id.list);
|
||||
emptyState = new Stub<>(view.findViewById(R.id.empty_state));
|
||||
|
||||
if (FeatureFlags.internalUser()) {
|
||||
fab = view.findViewById(R.id.fab_new);
|
||||
cameraFab = view.findViewById(R.id.camera_fab_new);
|
||||
} else {
|
||||
fab = view.findViewById(R.id.fab_old);
|
||||
cameraFab = view.findViewById(R.id.camera_fab_old);
|
||||
}
|
||||
fab = view.findViewById(R.id.fab);
|
||||
cameraFab = view.findViewById(R.id.camera_fab);
|
||||
|
||||
toolbar.get().setNavigationOnClickListener(v -> NavHostFragment.findNavController(this).popBackStack());
|
||||
toolbar.get().setTitle(R.string.AndroidManifest_archived_conversations);
|
||||
|
|
|
@ -57,6 +57,7 @@ import androidx.appcompat.content.res.AppCompatResources;
|
|||
import androidx.appcompat.view.ActionMode;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.appcompat.widget.TooltipCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
@ -76,6 +77,7 @@ import org.greenrobot.eventbus.Subscribe;
|
|||
import org.greenrobot.eventbus.ThreadMode;
|
||||
import org.signal.core.util.DimensionUnit;
|
||||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.MainFragment;
|
||||
import org.thoughtcrime.securesms.MainNavigator;
|
||||
|
@ -85,8 +87,8 @@ import org.thoughtcrime.securesms.R;
|
|||
import org.thoughtcrime.securesms.badges.models.Badge;
|
||||
import org.thoughtcrime.securesms.badges.self.expired.CantProcessSubscriptionPaymentBottomSheetDialogFragment;
|
||||
import org.thoughtcrime.securesms.badges.self.expired.ExpiredBadgeBottomSheetDialogFragment;
|
||||
import org.thoughtcrime.securesms.components.Material3SearchToolbar;
|
||||
import org.thoughtcrime.securesms.components.RatingManager;
|
||||
import org.thoughtcrime.securesms.components.SearchToolbar;
|
||||
import org.thoughtcrime.securesms.components.UnreadPaymentsView;
|
||||
import org.thoughtcrime.securesms.components.menu.ActionItem;
|
||||
import org.thoughtcrime.securesms.components.menu.SignalBottomActionBar;
|
||||
|
@ -117,6 +119,7 @@ import org.thoughtcrime.securesms.insights.InsightsLauncher;
|
|||
import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.lock.v2.CreateKbsPinActivity;
|
||||
import org.thoughtcrime.securesms.main.Material3OnScrollHelperBinder;
|
||||
import org.thoughtcrime.securesms.mediasend.v2.MediaSelectionActivity;
|
||||
import org.thoughtcrime.securesms.megaphone.Megaphone;
|
||||
import org.thoughtcrime.securesms.megaphone.MegaphoneActionController;
|
||||
|
@ -143,7 +146,6 @@ import org.thoughtcrime.securesms.util.AppForegroundObserver;
|
|||
import org.thoughtcrime.securesms.util.AppStartup;
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil;
|
||||
import org.thoughtcrime.securesms.util.ConversationUtil;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.LifecycleDisposable;
|
||||
import org.thoughtcrime.securesms.util.PlayStoreUtil;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
|
@ -156,7 +158,6 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
|||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.WindowUtil;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.task.SnackbarAsyncTask;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
import org.thoughtcrime.securesms.util.views.Stub;
|
||||
|
@ -203,7 +204,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
private TextView searchEmptyState;
|
||||
private PulsingFloatingActionButton fab;
|
||||
private PulsingFloatingActionButton cameraFab;
|
||||
private View toolbarShadow;
|
||||
private ConversationListViewModel viewModel;
|
||||
private RecyclerView.Adapter activeAdapter;
|
||||
private ConversationListAdapter defaultAdapter;
|
||||
|
@ -254,27 +254,20 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
coordinator = view.findViewById(R.id.coordinator);
|
||||
list = view.findViewById(R.id.list);
|
||||
searchEmptyState = view.findViewById(R.id.search_no_results);
|
||||
toolbarShadow = view.findViewById(R.id.conversation_list_toolbar_shadow);
|
||||
bottomActionBar = view.findViewById(R.id.conversation_list_bottom_action_bar);
|
||||
reminderView = new Stub<>(view.findViewById(R.id.reminder));
|
||||
emptyState = new Stub<>(view.findViewById(R.id.empty_state));
|
||||
megaphoneContainer = new Stub<>(view.findViewById(R.id.megaphone_container));
|
||||
paymentNotificationView = new Stub<>(view.findViewById(R.id.payments_notification));
|
||||
voiceNotePlayerViewStub = new Stub<>(view.findViewById(R.id.voice_note_player));
|
||||
coordinator = view.findViewById(R.id.coordinator);
|
||||
list = view.findViewById(R.id.list);
|
||||
searchEmptyState = view.findViewById(R.id.search_no_results);
|
||||
bottomActionBar = view.findViewById(R.id.conversation_list_bottom_action_bar);
|
||||
reminderView = new Stub<>(view.findViewById(R.id.reminder));
|
||||
emptyState = new Stub<>(view.findViewById(R.id.empty_state));
|
||||
megaphoneContainer = new Stub<>(view.findViewById(R.id.megaphone_container));
|
||||
paymentNotificationView = new Stub<>(view.findViewById(R.id.payments_notification));
|
||||
voiceNotePlayerViewStub = new Stub<>(view.findViewById(R.id.voice_note_player));
|
||||
fab = view.findViewById(R.id.fab);
|
||||
cameraFab = view.findViewById(R.id.camera_fab);
|
||||
|
||||
if (FeatureFlags.internalUser()) {
|
||||
fab = view.findViewById(R.id.fab_new);
|
||||
cameraFab = view.findViewById(R.id.camera_fab_new);
|
||||
|
||||
fab.setVisibility(View.VISIBLE);
|
||||
cameraFab.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
fab = view.findViewById(R.id.fab_old);
|
||||
cameraFab = view.findViewById(R.id.camera_fab_old);
|
||||
}
|
||||
fab.setVisibility(View.VISIBLE);
|
||||
cameraFab.setVisibility(View.VISIBLE);
|
||||
|
||||
fab.show();
|
||||
cameraFab.show();
|
||||
|
@ -284,7 +277,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
|
||||
list.setLayoutManager(new LinearLayoutManager(requireActivity()));
|
||||
list.setItemAnimator(itemAnimator);
|
||||
list.addOnScrollListener(new ScrollListener());
|
||||
list.addItemDecoration(archiveDecoration);
|
||||
|
||||
snapToTopDataObserver = new SnapToTopDataObserver(list);
|
||||
|
@ -331,14 +323,16 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
lifecycleDisposable.bindTo(getViewLifecycleOwner());
|
||||
lifecycleDisposable.add(conversationListTabsViewModel.getTabClickEvents().filter(tab -> tab == ConversationListTab.CHATS)
|
||||
.subscribe(unused -> {
|
||||
LinearLayoutManager layoutManager = (LinearLayoutManager) list.getLayoutManager();
|
||||
int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
|
||||
LinearLayoutManager layoutManager = (LinearLayoutManager) list.getLayoutManager();
|
||||
int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
|
||||
if (firstVisibleItemPosition <= LIST_SMOOTH_SCROLL_TO_TOP_THRESHOLD) {
|
||||
list.smoothScrollToPosition(0);
|
||||
} else {
|
||||
list.scrollToPosition(0);
|
||||
}
|
||||
}));
|
||||
|
||||
requireCallback().bindScrollHelper(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -346,7 +340,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
coordinator = null;
|
||||
list = null;
|
||||
searchEmptyState = null;
|
||||
toolbarShadow = null;
|
||||
bottomActionBar = null;
|
||||
reminderView = null;
|
||||
emptyState = null;
|
||||
|
@ -377,7 +370,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
InsightsLauncher.showInsightsModal(requireContext(), requireFragmentManager());
|
||||
}
|
||||
|
||||
if ((!requireCallback().getSearchToolbar().resolved() || !requireCallback().getSearchToolbar().get().isVisible()) && list.getAdapter() != defaultAdapter) {
|
||||
if ((!requireCallback().getSearchToolbar().resolved() || !(requireCallback().getSearchToolbar().get().getVisibility() == View.VISIBLE)) && list.getAdapter() != defaultAdapter) {
|
||||
list.removeItemDecoration(searchAdapterDecoration);
|
||||
setAdapter(defaultAdapter);
|
||||
}
|
||||
|
@ -401,10 +394,11 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
long subscriptionFailureWatermark = SignalStore.donationsValues().getUnexpectedSubscriptionCancelationWatermark();
|
||||
boolean isWatermarkPriorToTimestamp = subscriptionFailureWatermark < subscriptionFailureTimestamp;
|
||||
|
||||
if (unexpectedSubscriptionCancellation != null &&
|
||||
if (unexpectedSubscriptionCancellation != null &&
|
||||
!SignalStore.donationsValues().isUserManuallyCancelled() &&
|
||||
SignalStore.donationsValues().showCantProcessDialog() &&
|
||||
isWatermarkPriorToTimestamp) {
|
||||
SignalStore.donationsValues().showCantProcessDialog() &&
|
||||
isWatermarkPriorToTimestamp)
|
||||
{
|
||||
Log.w(TAG, "Displaying bottom sheet for unexpected cancellation: " + unexpectedSubscriptionCancellation, true);
|
||||
new CantProcessSubscriptionPaymentBottomSheetDialogFragment().show(getChildFragmentManager(), BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG);
|
||||
SignalStore.donationsValues().setUnexpectedSubscriptionCancelationWatermark(subscriptionFailureTimestamp);
|
||||
|
@ -469,20 +463,31 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
super.onOptionsItemSelected(item);
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_new_group: handleCreateGroup(); return true;
|
||||
case R.id.menu_settings: handleDisplaySettings(); return true;
|
||||
case R.id.menu_clear_passphrase: handleClearPassphrase(); return true;
|
||||
case R.id.menu_mark_all_read: handleMarkAllRead(); return true;
|
||||
case R.id.menu_invite: handleInvite(); return true;
|
||||
case R.id.menu_insights: handleInsights(); return true;
|
||||
case R.id.menu_notification_profile: handleNotificationProfile(); return true;
|
||||
case R.id.menu_new_group:
|
||||
handleCreateGroup(); return true;
|
||||
case R.id.menu_settings:
|
||||
handleDisplaySettings(); return true;
|
||||
case R.id.menu_clear_passphrase:
|
||||
handleClearPassphrase(); return true;
|
||||
case R.id.menu_mark_all_read:
|
||||
handleMarkAllRead(); return true;
|
||||
case R.id.menu_invite:
|
||||
handleInvite(); return true;
|
||||
case R.id.menu_insights:
|
||||
handleInsights(); return true;
|
||||
case R.id.menu_notification_profile:
|
||||
handleNotificationProfile(); return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isSearchOpen() {
|
||||
return (requireCallback().getSearchToolbar().resolved() && requireCallback().getSearchToolbar().get().isVisible()) || activeAdapter == searchAdapter;
|
||||
return isSearchVisible() || activeAdapter == searchAdapter;
|
||||
}
|
||||
|
||||
private boolean isSearchVisible() {
|
||||
return (requireCallback().getSearchToolbar().resolved() && requireCallback().getSearchToolbar().get().getVisibility() == View.VISIBLE);
|
||||
}
|
||||
|
||||
private boolean closeSearchIfOpen() {
|
||||
|
@ -509,7 +514,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
}
|
||||
|
||||
if (requestCode == CreateKbsPinActivity.REQUEST_NEW_PIN) {
|
||||
Snackbar.make(fab, R.string.ConfirmKbsPinFragment__pin_created, Snackbar.LENGTH_LONG).setTextColor(Color.WHITE).show();
|
||||
Snackbar.make(fab, R.string.ConfirmKbsPinFragment__pin_created, Snackbar.LENGTH_LONG).show();
|
||||
viewModel.onMegaphoneCompleted(Megaphones.Event.PINS_FOR_ALL);
|
||||
}
|
||||
}
|
||||
|
@ -568,9 +573,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
|
||||
@Override
|
||||
public void onMegaphoneToastRequested(@NonNull String string) {
|
||||
Snackbar.make(fab, string, Snackbar.LENGTH_LONG)
|
||||
.setTextColor(Color.WHITE)
|
||||
.show();
|
||||
Snackbar.make(fab, string, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -616,7 +619,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
requireCallback().getSearchToolbar().get().display(requireCallback().getSearchAction().getX() + (requireCallback().getSearchAction().getWidth() / 2.0f),
|
||||
requireCallback().getSearchAction().getY() + (requireCallback().getSearchAction().getHeight() / 2.0f));
|
||||
|
||||
requireCallback().getSearchToolbar().get().setListener(new SearchToolbar.SearchListener() {
|
||||
requireCallback().getSearchToolbar().get().setListener(new Material3SearchToolbar.Listener() {
|
||||
@Override
|
||||
public void onSearchTextChange(String text) {
|
||||
String trimmed = text.trim();
|
||||
|
@ -748,7 +751,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onBackground() { }
|
||||
public void onBackground() {}
|
||||
};
|
||||
|
||||
viewModel.getUnreadPaymentsLiveData().observe(getViewLifecycleOwner(), this::onUnreadPaymentsChanged);
|
||||
|
@ -1027,7 +1030,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
Snackbar.make(fab,
|
||||
getString(R.string.conversation_list__you_can_only_pin_up_to_d_chats, MAXIMUM_PINNED_CONVERSATIONS),
|
||||
Snackbar.LENGTH_LONG)
|
||||
.setTextColor(Color.WHITE)
|
||||
.show();
|
||||
endActionModeIfActive();
|
||||
return;
|
||||
|
@ -1273,16 +1275,16 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
viewModel.endSelection();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
TypedArray color = getActivity().getTheme().obtainStyledAttributes(new int[] {android.R.attr.statusBarColor});
|
||||
TypedArray color = getActivity().getTheme().obtainStyledAttributes(new int[] { android.R.attr.statusBarColor });
|
||||
WindowUtil.setStatusBarColor(getActivity().getWindow(), color.getColor(0, Color.BLACK));
|
||||
color.recycle();
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
TypedArray lightStatusBarAttr = getActivity().getTheme().obtainStyledAttributes(new int[] {android.R.attr.windowLightStatusBar});
|
||||
TypedArray lightStatusBarAttr = getActivity().getTheme().obtainStyledAttributes(new int[] { android.R.attr.windowLightStatusBar });
|
||||
int current = getActivity().getWindow().getDecorView().getSystemUiVisibility();
|
||||
int statusBarMode = lightStatusBarAttr.getBoolean(0, false) ? current | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||
: current & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
||||
int statusBarMode = lightStatusBarAttr.getBoolean(0, false) ? current | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||
: current & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
||||
|
||||
getActivity().getWindow().getDecorView().setSystemUiVisibility(statusBarMode);
|
||||
|
||||
|
@ -1507,10 +1509,10 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
|
||||
@Override
|
||||
public int getSwipeDirs(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
|
||||
if (viewHolder.itemView instanceof ConversationListItemAction ||
|
||||
if (viewHolder.itemView instanceof ConversationListItemAction ||
|
||||
viewHolder instanceof ConversationListAdapter.HeaderViewHolder ||
|
||||
actionMode != null ||
|
||||
viewHolder.itemView.isSelected() ||
|
||||
actionMode != null ||
|
||||
viewHolder.itemView.isSelected() ||
|
||||
activeAdapter == searchAdapter)
|
||||
{
|
||||
return 0;
|
||||
|
@ -1543,8 +1545,8 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
}
|
||||
|
||||
private void onTrueSwipe(RecyclerView.ViewHolder viewHolder) {
|
||||
final long threadId = ((ConversationListItem)viewHolder.itemView).getThreadId();
|
||||
final int unreadCount = ((ConversationListItem)viewHolder.itemView).getUnreadCount();
|
||||
final long threadId = ((ConversationListItem) viewHolder.itemView).getThreadId();
|
||||
final int unreadCount = ((ConversationListItem) viewHolder.itemView).getUnreadCount();
|
||||
|
||||
onItemSwiped(threadId, unreadCount);
|
||||
}
|
||||
|
@ -1577,7 +1579,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
if (absoluteDx > 0) {
|
||||
if (archiveDrawable == null) {
|
||||
archiveDrawable = Objects.requireNonNull(AppCompatResources.getDrawable(requireContext(), getArchiveIconRes()));
|
||||
archiveDrawable.setColorFilter(new SimpleColorFilter(Color.WHITE));
|
||||
archiveDrawable.setColorFilter(new SimpleColorFilter(ContextCompat.getColor(requireContext(), R.color.signal_colorOnPrimary)));
|
||||
archiveDrawable.setBounds(0, 0, archiveDrawable.getIntrinsicWidth(), archiveDrawable.getIntrinsicHeight());
|
||||
}
|
||||
|
||||
|
@ -1628,21 +1630,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
}
|
||||
}
|
||||
|
||||
private class ScrollListener 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 final class VoiceNotePlayerViewListener implements VoiceNotePlayerView.Listener {
|
||||
|
||||
@Override
|
||||
|
@ -1673,18 +1660,27 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
|||
}
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
public interface Callback extends Material3OnScrollHelperBinder {
|
||||
@NonNull Toolbar getToolbar();
|
||||
|
||||
@NonNull ImageView getSearchAction();
|
||||
@NonNull Stub<SearchToolbar> getSearchToolbar();
|
||||
|
||||
@NonNull Stub<Material3SearchToolbar> getSearchToolbar();
|
||||
|
||||
@NonNull View getUnreadPaymentsDot();
|
||||
|
||||
@NonNull Stub<Toolbar> getBasicToolbar();
|
||||
|
||||
void updateNotificationProfileStatus(@NonNull List<NotificationProfile> notificationProfiles);
|
||||
|
||||
void updateProxyStatus(@NonNull WebSocketConnectionState state);
|
||||
|
||||
void onSearchOpened();
|
||||
|
||||
void onSearchClosed();
|
||||
|
||||
void onMultiSelectStarted();
|
||||
|
||||
void onMultiSelectFinished();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ public final class ConversationListItem extends ConstraintLayout implements Bind
|
|||
this.checkContainer = findViewById(R.id.conversation_list_item_check_container);
|
||||
this.uncheckedView = findViewById(R.id.conversation_list_item_unchecked);
|
||||
this.checkedView = findViewById(R.id.conversation_list_item_checked);
|
||||
this.thumbSize = (int) DimensionUnit.SP.toPixels(20f);
|
||||
this.thumbSize = (int) DimensionUnit.SP.toPixels(16f);
|
||||
this.thumbTarget = new GlideLiveDataTarget(thumbSize, thumbSize);
|
||||
|
||||
getLayoutTransition().setDuration(150);
|
||||
|
@ -622,7 +622,7 @@ public final class ConversationListItem extends ConstraintLayout implements Bind
|
|||
|
||||
RoundedDrawable drawable = RoundedDrawable.fromBitmap(bitmap);
|
||||
drawable.setBounds(0, 0, thumbSize, thumbSize);
|
||||
drawable.setCornerRadius(DimensionUnit.DP.toPixels(4));
|
||||
drawable.setCornerRadius(DimensionUnit.DP.toPixels(2));
|
||||
drawable.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
|
||||
|
||||
CharSequence thumbnailSpan = SpanUtil.buildCenteredImageSpan(drawable);
|
||||
|
|
|
@ -224,10 +224,10 @@ public class DeleteAccountFragment extends Fragment {
|
|||
private void handleEvent(@NonNull DeleteAccountEvent deleteAccountEvent) {
|
||||
switch (deleteAccountEvent.getType()) {
|
||||
case NO_COUNTRY_CODE:
|
||||
Snackbar.make(requireView(), R.string.DeleteAccountFragment__no_country_code, Snackbar.LENGTH_SHORT).setTextColor(Color.WHITE).show();
|
||||
Snackbar.make(requireView(), R.string.DeleteAccountFragment__no_country_code, Snackbar.LENGTH_SHORT).show();
|
||||
break;
|
||||
case NO_NATIONAL_NUMBER:
|
||||
Snackbar.make(requireView(), R.string.DeleteAccountFragment__no_number, Snackbar.LENGTH_SHORT).setTextColor(Color.WHITE).show();
|
||||
Snackbar.make(requireView(), R.string.DeleteAccountFragment__no_number, Snackbar.LENGTH_SHORT).show();
|
||||
break;
|
||||
case NOT_A_MATCH:
|
||||
new AlertDialog.Builder(requireContext())
|
||||
|
|
|
@ -13,7 +13,6 @@ import androidx.lifecycle.ViewModelProviders;
|
|||
|
||||
import com.annimon.stream.Collectors;
|
||||
import com.annimon.stream.Stream;
|
||||
import com.dd.CircularProgressButton;
|
||||
|
||||
import org.thoughtcrime.securesms.MainActivity;
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActivity;
|
||||
|
@ -27,6 +26,7 @@ import org.thoughtcrime.securesms.groups.ui.GroupMemberListView;
|
|||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
|
@ -34,10 +34,10 @@ public final class ChooseNewAdminActivity extends PassphraseRequiredActivity {
|
|||
|
||||
private static final String EXTRA_GROUP_ID = "group_id";
|
||||
|
||||
private ChooseNewAdminViewModel viewModel;
|
||||
private GroupMemberListView groupList;
|
||||
private CircularProgressButton done;
|
||||
private GroupId.V2 groupId;
|
||||
private ChooseNewAdminViewModel viewModel;
|
||||
private GroupMemberListView groupList;
|
||||
private CircularProgressMaterialButton done;
|
||||
private GroupId.V2 groupId;
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
|
||||
|
||||
|
@ -70,7 +70,6 @@ public final class ChooseNewAdminActivity extends PassphraseRequiredActivity {
|
|||
|
||||
groupList = findViewById(R.id.choose_new_admin_group_list);
|
||||
done = findViewById(R.id.choose_new_admin_done);
|
||||
done.setIndeterminateProgressMode(true);
|
||||
|
||||
initializeViewModel();
|
||||
|
||||
|
@ -80,8 +79,7 @@ public final class ChooseNewAdminActivity extends PassphraseRequiredActivity {
|
|||
.collect(Collectors.toSet())));
|
||||
|
||||
done.setOnClickListener(v -> {
|
||||
done.setClickable(false);
|
||||
done.setProgress(50);
|
||||
done.setSpinning();
|
||||
viewModel.updateAdminsAndLeave(this::handleUpdateAndLeaveResult);
|
||||
});
|
||||
}
|
||||
|
@ -116,8 +114,7 @@ public final class ChooseNewAdminActivity extends PassphraseRequiredActivity {
|
|||
startActivity(MainActivity.clearTop(this));
|
||||
finish();
|
||||
} else {
|
||||
done.setClickable(true);
|
||||
done.setProgress(0);
|
||||
done.cancelSpinning();
|
||||
//noinspection ConstantConditions
|
||||
Toast.makeText(this, GroupErrors.getUserDisplayMessage(updateResult.getFailureReason()), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
package org.thoughtcrime.securesms.groups.ui.creategroup;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.ContactSelectionActivity;
|
||||
import org.thoughtcrime.securesms.ContactSelectionListFragment;
|
||||
|
@ -25,8 +26,6 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
|
|||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.Stopwatch;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -42,9 +41,8 @@ public class CreateGroupActivity extends ContactSelectionActivity {
|
|||
|
||||
private static final short REQUEST_CODE_ADD_DETAILS = 17275;
|
||||
|
||||
private ExtendedFloatingActionButton next;
|
||||
private ValueAnimator padStart;
|
||||
private ValueAnimator padEnd;
|
||||
private MaterialButton skip;
|
||||
private FloatingActionButton next;
|
||||
|
||||
public static Intent newIntent(@NonNull Context context) {
|
||||
Intent intent = new Intent(context, CreateGroupActivity.class);
|
||||
|
@ -67,9 +65,11 @@ public class CreateGroupActivity extends ContactSelectionActivity {
|
|||
assert getSupportActionBar() != null;
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
skip = findViewById(R.id.skip);
|
||||
next = findViewById(R.id.next);
|
||||
extendSkip();
|
||||
|
||||
skip.setOnClickListener(v -> handleNextPressed());
|
||||
next.setOnClickListener(v -> handleNextPressed());
|
||||
}
|
||||
|
||||
|
@ -125,33 +125,13 @@ public class CreateGroupActivity extends ContactSelectionActivity {
|
|||
}
|
||||
|
||||
private void extendSkip() {
|
||||
next.setIconGravity(MaterialButton.ICON_GRAVITY_END);
|
||||
next.extend();
|
||||
animatePadding(24, 18);
|
||||
skip.setVisibility(View.VISIBLE);
|
||||
next.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void shrinkSkip() {
|
||||
next.setIconGravity(MaterialButton.ICON_GRAVITY_START);
|
||||
next.shrink();
|
||||
animatePadding(16, 16);
|
||||
}
|
||||
|
||||
private void animatePadding(int startDp, int endDp) {
|
||||
if (padStart != null) padStart.cancel();
|
||||
|
||||
padStart = ValueAnimator.ofInt(next.getPaddingStart(), ViewUtil.dpToPx(startDp)).setDuration(200);
|
||||
padStart.addUpdateListener(animation -> {
|
||||
ViewUtil.setPaddingStart(next, (Integer) animation.getAnimatedValue());
|
||||
});
|
||||
padStart.start();
|
||||
|
||||
if (padEnd != null) padEnd.cancel();
|
||||
|
||||
padEnd = ValueAnimator.ofInt(next.getPaddingEnd(), ViewUtil.dpToPx(endDp)).setDuration(200);
|
||||
padEnd.addUpdateListener(animation -> {
|
||||
ViewUtil.setPaddingEnd(next, (Integer) animation.getAnimatedValue());
|
||||
});
|
||||
padEnd.start();
|
||||
skip.setVisibility(View.GONE);
|
||||
next.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void handleNextPressed() {
|
||||
|
|
|
@ -19,14 +19,15 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
|
||||
|
||||
import com.airbnb.lottie.SimpleColorFilter;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.request.target.CustomTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.dd.CircularProgressButton;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.signal.core.util.EditTextUtil;
|
||||
|
@ -49,7 +50,7 @@ import org.thoughtcrime.securesms.util.FeatureFlags;
|
|||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.navigation.SafeNavigation;
|
||||
import org.thoughtcrime.securesms.util.text.AfterTextChanged;
|
||||
import org.thoughtcrime.securesms.util.views.LearnMoreTextView;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
@ -60,13 +61,13 @@ public class AddGroupDetailsFragment extends LoggingFragment {
|
|||
private static final int AVATAR_PLACEHOLDER_INSET_DP = 18;
|
||||
private static final short REQUEST_DISAPPEARING_TIMER = 28621;
|
||||
|
||||
private CircularProgressButton create;
|
||||
private Callback callback;
|
||||
private AddGroupDetailsViewModel viewModel;
|
||||
private Drawable avatarPlaceholder;
|
||||
private EditText name;
|
||||
private Toolbar toolbar;
|
||||
private View disappearingMessagesRow;
|
||||
private CircularProgressMaterialButton create;
|
||||
private Callback callback;
|
||||
private AddGroupDetailsViewModel viewModel;
|
||||
private Drawable avatarPlaceholder;
|
||||
private EditText name;
|
||||
private Toolbar toolbar;
|
||||
private View disappearingMessagesRow;
|
||||
|
||||
@Override
|
||||
public void onAttach(@NonNull Context context) {
|
||||
|
@ -94,17 +95,17 @@ public class AddGroupDetailsFragment extends LoggingFragment {
|
|||
toolbar = view.findViewById(R.id.toolbar);
|
||||
disappearingMessagesRow = view.findViewById(R.id.group_disappearing_messages_row);
|
||||
|
||||
setCreateEnabled(false, false);
|
||||
setCreateEnabled(false);
|
||||
|
||||
GroupMemberListView members = view.findViewById(R.id.member_list);
|
||||
ImageView avatar = view.findViewById(R.id.group_avatar);
|
||||
View mmsWarning = view.findViewById(R.id.mms_warning);
|
||||
LearnMoreTextView gv2Warning = view.findViewById(R.id.gv2_warning);
|
||||
View addLater = view.findViewById(R.id.add_later);
|
||||
TextView disappearingMessageValue = view.findViewById(R.id.group_disappearing_messages_value);
|
||||
|
||||
members.initializeAdapter(getViewLifecycleOwner());
|
||||
avatarPlaceholder = VectorDrawableCompat.create(getResources(), R.drawable.ic_camera_outline_32_ultramarine, requireActivity().getTheme());
|
||||
avatarPlaceholder = Objects.requireNonNull(VectorDrawableCompat.create(getResources(), R.drawable.ic_camera_outline_24, requireActivity().getTheme()));
|
||||
avatarPlaceholder.setColorFilter(new SimpleColorFilter(ContextCompat.getColor(requireContext(), R.color.signal_icon_tint_primary)));
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
avatar.setImageDrawable(new InsetDrawable(avatarPlaceholder, ViewUtil.dpToPx(AVATAR_PLACEHOLDER_INSET_DP)));
|
||||
|
@ -122,7 +123,7 @@ public class AddGroupDetailsFragment extends LoggingFragment {
|
|||
addLater.setVisibility(list.isEmpty() ? View.VISIBLE : View.GONE);
|
||||
members.setMembers(list);
|
||||
});
|
||||
viewModel.getCanSubmitForm().observe(getViewLifecycleOwner(), isFormValid -> setCreateEnabled(isFormValid, true));
|
||||
viewModel.getCanSubmitForm().observe(getViewLifecycleOwner(), this::setCreateEnabled);
|
||||
viewModel.getIsMms().observe(getViewLifecycleOwner(), isMms -> {
|
||||
disappearingMessagesRow.setVisibility(isMms ? View.GONE : View.VISIBLE);
|
||||
mmsWarning.setVisibility(isMms ? View.VISIBLE : View.GONE);
|
||||
|
@ -205,9 +206,11 @@ public class AddGroupDetailsFragment extends LoggingFragment {
|
|||
}
|
||||
|
||||
private void handleCreateClicked() {
|
||||
create.setClickable(false);
|
||||
create.setIndeterminateProgressMode(true);
|
||||
create.setProgress(50);
|
||||
if (!create.isClickable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
create.setSpinning();
|
||||
|
||||
viewModel.create();
|
||||
}
|
||||
|
@ -254,15 +257,12 @@ public class AddGroupDetailsFragment extends LoggingFragment {
|
|||
.show();
|
||||
}
|
||||
|
||||
private void setCreateEnabled(boolean isEnabled, boolean animate) {
|
||||
if (create.isEnabled() == isEnabled) {
|
||||
private void setCreateEnabled(boolean isEnabled) {
|
||||
if (create.isClickable() == isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
create.setEnabled(isEnabled);
|
||||
create.animate()
|
||||
.setDuration(animate ? 300 : 0)
|
||||
.alpha(isEnabled ? 1f : 0.5f);
|
||||
create.setClickable(isEnabled);
|
||||
}
|
||||
|
||||
private void showAvatarPicker() {
|
||||
|
|
|
@ -10,6 +10,7 @@ import android.widget.Toast;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.constraintlayout.widget.Group;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
|
@ -35,8 +36,8 @@ public final class GroupLinkInviteFriendsBottomSheetDialogFragment extends Botto
|
|||
|
||||
private Button groupLinkEnableAndShareButton;
|
||||
private Button groupLinkShareButton;
|
||||
private View memberApprovalRow;
|
||||
private View memberApprovalRow2;
|
||||
private Group controlGroup;
|
||||
private View controlOutline;
|
||||
private SwitchCompat memberApprovalSwitch;
|
||||
|
||||
private SimpleProgressDialog.DismissibleDialog busyDialog;
|
||||
|
@ -68,8 +69,8 @@ public final class GroupLinkInviteFriendsBottomSheetDialogFragment extends Botto
|
|||
|
||||
groupLinkEnableAndShareButton = view.findViewById(R.id.group_link_enable_and_share_button);
|
||||
groupLinkShareButton = view.findViewById(R.id.group_link_share_button);
|
||||
memberApprovalRow = view.findViewById(R.id.group_link_enable_and_share_approve_new_members_row);
|
||||
memberApprovalRow2 = view.findViewById(R.id.group_link_enable_and_share_approve_new_members_row2);
|
||||
controlGroup = view.findViewById(R.id.control_group);
|
||||
controlOutline = view.findViewById(R.id.group_link_enable_and_share_approve_outline);
|
||||
memberApprovalSwitch = view.findViewById(R.id.group_link_enable_and_share_approve_new_members_switch);
|
||||
|
||||
view.findViewById(R.id.group_link_enable_and_share_cancel_button).setOnClickListener(v -> dismiss());
|
||||
|
@ -91,20 +92,17 @@ public final class GroupLinkInviteFriendsBottomSheetDialogFragment extends Botto
|
|||
if (groupLinkUrlAndStatus.isEnabled()) {
|
||||
groupLinkShareButton.setVisibility(View.VISIBLE);
|
||||
groupLinkEnableAndShareButton.setVisibility(View.INVISIBLE);
|
||||
memberApprovalRow.setVisibility(View.GONE);
|
||||
memberApprovalRow2.setVisibility(View.GONE);
|
||||
|
||||
controlGroup.setVisibility(View.GONE);
|
||||
groupLinkShareButton.setOnClickListener(v -> shareGroupLinkAndDismiss(groupId));
|
||||
} else {
|
||||
memberApprovalRow.setVisibility(View.VISIBLE);
|
||||
memberApprovalRow2.setVisibility(View.VISIBLE);
|
||||
controlGroup.setVisibility(View.VISIBLE);
|
||||
|
||||
groupLinkEnableAndShareButton.setVisibility(View.VISIBLE);
|
||||
groupLinkShareButton.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
memberApprovalRow.setOnClickListener(v -> viewModel.toggleMemberApproval());
|
||||
controlOutline.setOnClickListener(v -> viewModel.toggleMemberApproval());
|
||||
|
||||
viewModel.getMemberApproval()
|
||||
.observe(getViewLifecycleOwner(), enabled -> memberApprovalSwitch.setChecked(enabled));
|
||||
|
|
|
@ -21,7 +21,6 @@ import androidx.annotation.StringRes;
|
|||
import androidx.lifecycle.ViewModelProviders;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
import com.dd.CircularProgressButton;
|
||||
|
||||
import org.signal.core.util.ResourceUtil;
|
||||
import org.thoughtcrime.securesms.LoggingFragment;
|
||||
|
@ -31,6 +30,7 @@ import org.thoughtcrime.securesms.util.CommunicationActions;
|
|||
import org.thoughtcrime.securesms.util.SupportEmailUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.text.AfterTextChanged;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -41,16 +41,16 @@ public class HelpFragment extends LoggingFragment {
|
|||
public static final int PAYMENT_INDEX = 6;
|
||||
public static final int DONATION_INDEX = 7;
|
||||
|
||||
private EditText problem;
|
||||
private CheckBox includeDebugLogs;
|
||||
private View debugLogInfo;
|
||||
private View faq;
|
||||
private CircularProgressButton next;
|
||||
private View toaster;
|
||||
private List<EmojiImageView> emoji;
|
||||
private HelpViewModel helpViewModel;
|
||||
private Spinner categorySpinner;
|
||||
private ArrayAdapter<CharSequence> categoryAdapter;
|
||||
private EditText problem;
|
||||
private CheckBox includeDebugLogs;
|
||||
private View debugLogInfo;
|
||||
private View faq;
|
||||
private CircularProgressMaterialButton next;
|
||||
private View toaster;
|
||||
private List<EmojiImageView> emoji;
|
||||
private HelpViewModel helpViewModel;
|
||||
private Spinner categorySpinner;
|
||||
private ArrayAdapter<CharSequence> categoryAdapter;
|
||||
|
||||
@Override
|
||||
public @Nullable View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
|
@ -69,7 +69,7 @@ public class HelpFragment extends LoggingFragment {
|
|||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
cancelSpinning(next);
|
||||
next.cancelSpinning();
|
||||
problem.setEnabled(true);
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ public class HelpFragment extends LoggingFragment {
|
|||
}
|
||||
|
||||
private void submitForm() {
|
||||
setSpinning(next);
|
||||
next.setSpinning();
|
||||
problem.setEnabled(false);
|
||||
|
||||
helpViewModel.onSubmitClicked(includeDebugLogs.isChecked()).observe(getViewLifecycleOwner(), result -> {
|
||||
|
@ -220,22 +220,6 @@ public class HelpFragment extends LoggingFragment {
|
|||
suffix.toString());
|
||||
}
|
||||
|
||||
private static void setSpinning(@Nullable CircularProgressButton button) {
|
||||
if (button != null) {
|
||||
button.setClickable(false);
|
||||
button.setIndeterminateProgressMode(true);
|
||||
button.setProgress(50);
|
||||
}
|
||||
}
|
||||
|
||||
private static void cancelSpinning(@Nullable CircularProgressButton button) {
|
||||
if (button != null) {
|
||||
button.setProgress(0);
|
||||
button.setIndeterminateProgressMode(false);
|
||||
button.setClickable(true);
|
||||
}
|
||||
}
|
||||
|
||||
private enum Feeling {
|
||||
ECSTATIC(R.id.help_fragment_emoji_5, R.string.HelpFragment__emoji_5, "\ud83d\ude00"),
|
||||
HAPPY(R.id.help_fragment_emoji_4, R.string.HelpFragment__emoji_4, "\ud83d\ude42"),
|
||||
|
|
|
@ -20,8 +20,6 @@ import androidx.lifecycle.ViewModelProviders;
|
|||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.dd.CircularProgressButton;
|
||||
|
||||
import org.thoughtcrime.securesms.BaseActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
|
@ -29,6 +27,7 @@ import org.thoughtcrime.securesms.util.LongClickCopySpan;
|
|||
import org.thoughtcrime.securesms.util.LongClickMovementMethod;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -39,12 +38,12 @@ public class SubmitDebugLogActivity extends BaseActivity implements SubmitDebugL
|
|||
private SubmitDebugLogAdapter adapter;
|
||||
private SubmitDebugLogViewModel viewModel;
|
||||
|
||||
private View warningBanner;
|
||||
private View editBanner;
|
||||
private CircularProgressButton submitButton;
|
||||
private AlertDialog loadingDialog;
|
||||
private View scrollToBottomButton;
|
||||
private View scrollToTopButton;
|
||||
private View warningBanner;
|
||||
private View editBanner;
|
||||
private CircularProgressMaterialButton submitButton;
|
||||
private AlertDialog loadingDialog;
|
||||
private View scrollToBottomButton;
|
||||
private View scrollToTopButton;
|
||||
|
||||
private MenuItem editMenuItem;
|
||||
private MenuItem doneMenuItem;
|
||||
|
@ -263,9 +262,7 @@ public class SubmitDebugLogActivity extends BaseActivity implements SubmitDebugL
|
|||
}
|
||||
|
||||
private void onSubmitClicked() {
|
||||
submitButton.setClickable(false);
|
||||
submitButton.setIndeterminateProgressMode(true);
|
||||
submitButton.setProgress(50);
|
||||
submitButton.setSpinning();
|
||||
|
||||
viewModel.onSubmitClicked().observe(this, result -> {
|
||||
if (result.isPresent()) {
|
||||
|
@ -274,9 +271,7 @@ public class SubmitDebugLogActivity extends BaseActivity implements SubmitDebugL
|
|||
Toast.makeText(this, R.string.SubmitDebugLogActivity_failed_to_submit_logs, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
submitButton.setClickable(true);
|
||||
submitButton.setIndeterminateProgressMode(false);
|
||||
submitButton.setProgress(0);
|
||||
submitButton.cancelSpinning();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,12 +17,13 @@ import androidx.navigation.NavDestination
|
|||
import androidx.navigation.Navigator
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.fragment.FragmentNavigatorExtras
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.signal.core.util.concurrent.SimpleTask
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.MainActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.badges.BadgeImageView
|
||||
import org.thoughtcrime.securesms.components.SearchToolbar
|
||||
import org.thoughtcrime.securesms.components.Material3SearchToolbar
|
||||
import org.thoughtcrime.securesms.components.TooltipPopup
|
||||
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
|
||||
import org.thoughtcrime.securesms.components.settings.app.notifications.manual.NotificationProfileSelectionFragment
|
||||
|
@ -36,6 +37,7 @@ import org.thoughtcrime.securesms.stories.tabs.ConversationListTabsState
|
|||
import org.thoughtcrime.securesms.stories.tabs.ConversationListTabsViewModel
|
||||
import org.thoughtcrime.securesms.util.AvatarUtil
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil
|
||||
import org.thoughtcrime.securesms.util.Material3OnScrollHelper
|
||||
import org.thoughtcrime.securesms.util.TopToastPopup
|
||||
import org.thoughtcrime.securesms.util.TopToastPopup.Companion.show
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
|
@ -45,7 +47,7 @@ import org.thoughtcrime.securesms.util.views.Stub
|
|||
import org.thoughtcrime.securesms.util.visible
|
||||
import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState
|
||||
|
||||
class MainActivityListHostFragment : Fragment(R.layout.main_activity_list_host_fragment), ConversationListFragment.Callback {
|
||||
class MainActivityListHostFragment : Fragment(R.layout.main_activity_list_host_fragment), ConversationListFragment.Callback, Material3OnScrollHelperBinder {
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(MainActivityListHostFragment::class.java)
|
||||
|
@ -53,11 +55,12 @@ class MainActivityListHostFragment : Fragment(R.layout.main_activity_list_host_f
|
|||
|
||||
private val conversationListTabsViewModel: ConversationListTabsViewModel by viewModels(ownerProducer = { requireActivity() })
|
||||
|
||||
private lateinit var _toolbarBackground: View
|
||||
private lateinit var _toolbar: Toolbar
|
||||
private lateinit var _basicToolbar: Stub<Toolbar>
|
||||
private lateinit var notificationProfileStatus: ImageView
|
||||
private lateinit var proxyStatus: ImageView
|
||||
private lateinit var _searchToolbar: Stub<SearchToolbar>
|
||||
private lateinit var _searchToolbar: Stub<Material3SearchToolbar>
|
||||
private lateinit var _searchAction: ImageView
|
||||
private lateinit var _unreadPaymentsDot: View
|
||||
|
||||
|
@ -72,6 +75,7 @@ class MainActivityListHostFragment : Fragment(R.layout.main_activity_list_host_f
|
|||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
_toolbarBackground = view.findViewById(R.id.toolbar_background)
|
||||
_toolbar = view.findViewById(R.id.toolbar)
|
||||
_basicToolbar = Stub(view.findViewById(R.id.toolbar_basic_stub))
|
||||
notificationProfileStatus = view.findViewById(R.id.conversation_list_notification_profile_status)
|
||||
|
@ -101,8 +105,8 @@ class MainActivityListHostFragment : Fragment(R.layout.main_activity_list_host_f
|
|||
if (state.tab == ConversationListTab.CHATS) {
|
||||
return
|
||||
} else {
|
||||
val cameraFab = requireView().findViewById<View>(R.id.camera_fab_new)
|
||||
val newConvoFab = requireView().findViewById<View>(R.id.fab_new)
|
||||
val cameraFab = requireView().findViewById<View>(R.id.camera_fab)
|
||||
val newConvoFab = requireView().findViewById<View>(R.id.fab)
|
||||
|
||||
val extras: Navigator.Extras? = if (cameraFab == null || newConvoFab == null) {
|
||||
null
|
||||
|
@ -187,7 +191,7 @@ class MainActivityListHostFragment : Fragment(R.layout.main_activity_list_host_f
|
|||
return _searchAction
|
||||
}
|
||||
|
||||
override fun getSearchToolbar(): Stub<SearchToolbar> {
|
||||
override fun getSearchToolbar(): Stub<Material3SearchToolbar> {
|
||||
return _searchToolbar
|
||||
}
|
||||
|
||||
|
@ -208,10 +212,12 @@ class MainActivityListHostFragment : Fragment(R.layout.main_activity_list_host_f
|
|||
}
|
||||
|
||||
override fun onMultiSelectStarted() {
|
||||
_toolbar.visible = false
|
||||
conversationListTabsViewModel.onMultiSelectStarted()
|
||||
}
|
||||
|
||||
override fun onMultiSelectFinished() {
|
||||
_toolbar.visible = true
|
||||
conversationListTabsViewModel.onMultiSelectFinished()
|
||||
}
|
||||
|
||||
|
@ -313,4 +319,14 @@ class MainActivityListHostFragment : Fragment(R.layout.main_activity_list_host_f
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun bindScrollHelper(recyclerView: RecyclerView) {
|
||||
recyclerView.addOnScrollListener(
|
||||
Material3OnScrollHelper(
|
||||
requireActivity(),
|
||||
listOf(_toolbarBackground),
|
||||
listOf(_searchToolbar, _basicToolbar)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package org.thoughtcrime.securesms.main
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
interface Material3OnScrollHelperBinder {
|
||||
fun bindScrollHelper(recyclerView: RecyclerView)
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package org.thoughtcrime.securesms.messagedetails;
|
||||
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
@ -12,7 +13,6 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.FullScreenDialogFragment;
|
||||
import org.thoughtcrime.securesms.components.recyclerview.ToolbarShadowAnimationHelper;
|
||||
import org.thoughtcrime.securesms.conversation.colors.Colorizer;
|
||||
import org.thoughtcrime.securesms.conversation.colors.RecyclerViewColorizer;
|
||||
import org.thoughtcrime.securesms.conversation.ui.error.SafetyNumberChangeDialog;
|
||||
|
@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.messagedetails.MessageDetailsViewModel.Factory
|
|||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.Material3OnScrollHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -87,6 +88,17 @@ public final class MessageDetailsFragment extends FullScreenDialogFragment {
|
|||
adapter.pauseMessageExpirationTimer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(@NonNull DialogInterface dialog) {
|
||||
super.onDismiss(dialog);
|
||||
|
||||
if (getActivity() instanceof Callback) {
|
||||
((Callback) getActivity()).onMessageDetailsFragmentDismissed();
|
||||
} else if (getParentFragment() instanceof Callback) {
|
||||
((Callback) getParentFragment()).onMessageDetailsFragmentDismissed();
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeList(@NonNull View view) {
|
||||
RecyclerView list = view.findViewById(R.id.message_details_list);
|
||||
View toolbarShadow = view.findViewById(R.id.toolbar_shadow);
|
||||
|
@ -97,7 +109,7 @@ public final class MessageDetailsFragment extends FullScreenDialogFragment {
|
|||
|
||||
list.setAdapter(adapter);
|
||||
list.setItemAnimator(null);
|
||||
list.addOnScrollListener(new ToolbarShadowAnimationHelper(toolbarShadow));
|
||||
list.addOnScrollListener(new Material3OnScrollHelper(requireActivity(), toolbarShadow));
|
||||
}
|
||||
|
||||
private void initializeViewModel() {
|
||||
|
@ -161,4 +173,8 @@ public final class MessageDetailsFragment extends FullScreenDialogFragment {
|
|||
private void onErrorClicked(@NonNull MessageRecord messageRecord) {
|
||||
SafetyNumberChangeDialog.show(requireContext(), getChildFragmentManager(), messageRecord);
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
void onMessageDetailsFragmentDismissed();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package org.thoughtcrime.securesms.messagerequests
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.core.content.ContextCompat
|
||||
import org.thoughtcrime.securesms.R
|
||||
|
||||
enum class MessageRequestBarColorTheme(
|
||||
private val containerBackgroundColor: Int,
|
||||
private val buttonBackgroundColor: Int,
|
||||
private val buttonForegroundDenyColor: Int,
|
||||
private val buttonForegroundAcceptColor: Int
|
||||
) {
|
||||
WALLPAPER(
|
||||
R.color.message_request_bar_container_background_wallpaper,
|
||||
R.color.message_request_bar_background_wallpaper,
|
||||
R.color.message_request_bar_denyForeground_wallpaper,
|
||||
R.color.message_request_bar_acceptForeground_wallpaper
|
||||
),
|
||||
NORMAL(
|
||||
R.color.message_request_bar_container_background_normal,
|
||||
R.color.message_request_bar_background_normal,
|
||||
R.color.message_request_bar_denyForeground_normal,
|
||||
R.color.message_request_bar_acceptForeground_normal
|
||||
);
|
||||
|
||||
@ColorInt
|
||||
fun getContainerButtonBackgroundColor(context: Context): Int = ContextCompat.getColor(context, containerBackgroundColor)
|
||||
|
||||
@ColorInt
|
||||
fun getButtonBackgroundColor(context: Context): Int = ContextCompat.getColor(context, buttonBackgroundColor)
|
||||
|
||||
@ColorInt
|
||||
fun getButtonForegroundDenyColor(context: Context): Int = ContextCompat.getColor(context, buttonForegroundDenyColor)
|
||||
|
||||
@ColorInt
|
||||
fun getButtonForegroundAcceptColor(context: Context): Int = ContextCompat.getColor(context, buttonForegroundAcceptColor)
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun resolveTheme(hasWallpaper: Boolean): MessageRequestBarColorTheme {
|
||||
return if (hasWallpaper) WALLPAPER else NORMAL
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package org.thoughtcrime.securesms.messagerequests;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
@ -10,6 +11,8 @@ import androidx.constraintlayout.widget.ConstraintLayout;
|
|||
import androidx.constraintlayout.widget.Group;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||
|
@ -18,17 +21,19 @@ import org.thoughtcrime.securesms.util.FeatureFlags;
|
|||
import org.thoughtcrime.securesms.util.HtmlUtil;
|
||||
import org.thoughtcrime.securesms.util.views.LearnMoreTextView;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class MessageRequestsBottomView extends ConstraintLayout {
|
||||
|
||||
private final Debouncer showProgressDebouncer = new Debouncer(250);
|
||||
|
||||
private LearnMoreTextView question;
|
||||
private Button accept;
|
||||
private Button gv1Continue;
|
||||
private View block;
|
||||
private View delete;
|
||||
private View bigDelete;
|
||||
private View bigUnblock;
|
||||
private MaterialButton accept;
|
||||
private MaterialButton gv1Continue;
|
||||
private MaterialButton block;
|
||||
private MaterialButton delete;
|
||||
private MaterialButton bigDelete;
|
||||
private MaterialButton bigUnblock;
|
||||
private View busyIndicator;
|
||||
|
||||
private Group normalButtons;
|
||||
|
@ -65,6 +70,8 @@ public class MessageRequestsBottomView extends ConstraintLayout {
|
|||
blockedButtons = findViewById(R.id.message_request_blocked_buttons);
|
||||
gv1MigrationButtons = findViewById(R.id.message_request_gv1_migration_buttons);
|
||||
busyIndicator = findViewById(R.id.message_request_busy_indicator);
|
||||
|
||||
setWallpaperEnabled(false);
|
||||
}
|
||||
|
||||
public void setMessageData(@NonNull MessageRequestViewModel.MessageData messageData) {
|
||||
|
@ -162,6 +169,24 @@ public class MessageRequestsBottomView extends ConstraintLayout {
|
|||
}
|
||||
}
|
||||
|
||||
public void setWallpaperEnabled(boolean isEnabled) {
|
||||
MessageRequestBarColorTheme theme = MessageRequestBarColorTheme.resolveTheme(isEnabled);
|
||||
|
||||
Stream.of(delete, bigDelete, block, bigUnblock, accept, gv1Continue).forEach(button -> {
|
||||
button.setBackgroundTintList(ColorStateList.valueOf(theme.getButtonBackgroundColor(getContext())));
|
||||
});
|
||||
|
||||
Stream.of(delete, bigDelete, block).forEach(button -> {
|
||||
button.setTextColor(theme.getButtonForegroundDenyColor(getContext()));
|
||||
});
|
||||
|
||||
Stream.of(accept, bigUnblock, gv1Continue).forEach(button -> {
|
||||
button.setTextColor(theme.getButtonForegroundAcceptColor(getContext()));
|
||||
});
|
||||
|
||||
setBackgroundColor(theme.getContainerButtonBackgroundColor(getContext()));
|
||||
}
|
||||
|
||||
public void setAcceptOnClickListener(OnClickListener acceptOnClickListener) {
|
||||
accept.setOnClickListener(acceptOnClickListener);
|
||||
}
|
||||
|
|
|
@ -155,7 +155,6 @@ public class PaymentsHomeFragment extends LoggingFragment {
|
|||
return;
|
||||
case DEACTIVATED:
|
||||
Snackbar.make(requireView(), R.string.PaymentsHomeFragment__payments_deactivated, Snackbar.LENGTH_SHORT)
|
||||
.setTextColor(Color.WHITE)
|
||||
.show();
|
||||
return;
|
||||
case DEACTIVATE_WITHOUT_BALANCE:
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.thoughtcrime.securesms.permissions;
|
||||
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
@ -18,13 +17,15 @@ import androidx.annotation.NonNull;
|
|||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
public class RationaleDialog {
|
||||
|
||||
public static AlertDialog.Builder createFor(@NonNull Context context, @NonNull String message, @DrawableRes int... drawables) {
|
||||
public static MaterialAlertDialogBuilder createFor(@NonNull Context context, @NonNull String message, @DrawableRes int... drawables) {
|
||||
View view = LayoutInflater.from(context).inflate(R.layout.permissions_rationale_dialog, null);
|
||||
ViewGroup header = view.findViewById(R.id.header_container);
|
||||
TextView text = view.findViewById(R.id.message);
|
||||
|
@ -54,8 +55,10 @@ public class RationaleDialog {
|
|||
|
||||
text.setText(message);
|
||||
|
||||
return new AlertDialog.Builder(context, ThemeUtil.isDarkTheme(context) ? R.style.Theme_Signal_AlertDialog_Dark_Cornered : R.style.Theme_Signal_AlertDialog_Light_Cornered)
|
||||
.setView(view);
|
||||
return new MaterialAlertDialogBuilder(context,
|
||||
ThemeUtil.isDarkTheme(context) ? R.style.Theme_Signal_AlertDialog_Dark_Cornered
|
||||
: R.style.Theme_Signal_AlertDialog_Light_Cornered)
|
||||
.setView(view);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,8 +21,6 @@ import androidx.core.view.ViewCompat;
|
|||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.dd.CircularProgressButton;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.LoggingFragment;
|
||||
import org.thoughtcrime.securesms.MainActivity;
|
||||
|
@ -42,19 +40,20 @@ import org.thoughtcrime.securesms.util.ServiceUtil;
|
|||
import org.thoughtcrime.securesms.util.SupportEmailUtil;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.navigation.SafeNavigation;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
|
||||
public class PinRestoreEntryFragment extends LoggingFragment {
|
||||
private static final String TAG = Log.tag(PinRestoreActivity.class);
|
||||
|
||||
private static final int MINIMUM_PIN_LENGTH = 4;
|
||||
|
||||
private EditText pinEntry;
|
||||
private View helpButton;
|
||||
private View skipButton;
|
||||
private CircularProgressButton pinButton;
|
||||
private TextView errorLabel;
|
||||
private TextView keyboardToggle;
|
||||
private PinRestoreViewModel viewModel;
|
||||
private EditText pinEntry;
|
||||
private View helpButton;
|
||||
private View skipButton;
|
||||
private CircularProgressMaterialButton pinButton;
|
||||
private TextView errorLabel;
|
||||
private TextView keyboardToggle;
|
||||
private PinRestoreViewModel viewModel;
|
||||
|
||||
@Override
|
||||
public @Nullable View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
|
@ -153,18 +152,18 @@ public class PinRestoreEntryFragment extends LoggingFragment {
|
|||
break;
|
||||
case EMPTY_PIN:
|
||||
Toast.makeText(requireContext(), R.string.RegistrationActivity_you_must_enter_your_registration_lock_PIN, Toast.LENGTH_LONG).show();
|
||||
cancelSpinning(pinButton);
|
||||
pinButton.cancelSpinning();
|
||||
pinEntry.getText().clear();
|
||||
enableAndFocusPinEntry();
|
||||
break;
|
||||
case PIN_TOO_SHORT:
|
||||
Toast.makeText(requireContext(), getString(R.string.RegistrationActivity_your_pin_has_at_least_d_digits_or_characters, MINIMUM_PIN_LENGTH), Toast.LENGTH_LONG).show();
|
||||
cancelSpinning(pinButton);
|
||||
pinButton.cancelSpinning();
|
||||
pinEntry.getText().clear();
|
||||
enableAndFocusPinEntry();
|
||||
break;
|
||||
case PIN_INCORRECT:
|
||||
cancelSpinning(pinButton);
|
||||
pinButton.cancelSpinning();
|
||||
pinEntry.getText().clear();
|
||||
enableAndFocusPinEntry();
|
||||
break;
|
||||
|
@ -173,7 +172,7 @@ public class PinRestoreEntryFragment extends LoggingFragment {
|
|||
break;
|
||||
case NETWORK_ERROR:
|
||||
Toast.makeText(requireContext(), R.string.RegistrationActivity_error_connecting_to_service, Toast.LENGTH_LONG).show();
|
||||
cancelSpinning(pinButton);
|
||||
pinButton.cancelSpinning();
|
||||
pinEntry.setEnabled(true);
|
||||
enableAndFocusPinEntry();
|
||||
break;
|
||||
|
@ -189,7 +188,7 @@ public class PinRestoreEntryFragment extends LoggingFragment {
|
|||
private void onPinSubmitted() {
|
||||
pinEntry.setEnabled(false);
|
||||
viewModel.onPinSubmitted(pinEntry.getText().toString(), getPinEntryKeyboardType());
|
||||
setSpinning(pinButton);
|
||||
pinButton.setSpinning();
|
||||
}
|
||||
|
||||
private void onNeedHelpClicked() {
|
||||
|
@ -232,7 +231,7 @@ public class PinRestoreEntryFragment extends LoggingFragment {
|
|||
}
|
||||
|
||||
private void handleSuccess() {
|
||||
cancelSpinning(pinButton);
|
||||
pinButton.cancelSpinning();
|
||||
SignalStore.onboarding().clearAll();
|
||||
|
||||
Activity activity = requireActivity();
|
||||
|
@ -277,20 +276,4 @@ public class PinRestoreEntryFragment extends LoggingFragment {
|
|||
ServiceUtil.getInputMethodManager(pinEntry.getContext()).showSoftInput(pinEntry, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setSpinning(@Nullable CircularProgressButton button) {
|
||||
if (button != null) {
|
||||
button.setClickable(false);
|
||||
button.setIndeterminateProgressMode(true);
|
||||
button.setProgress(50);
|
||||
}
|
||||
}
|
||||
|
||||
private static void cancelSpinning(@Nullable CircularProgressButton button) {
|
||||
if (button != null) {
|
||||
button.setProgress(0);
|
||||
button.setIndeterminateProgressMode(false);
|
||||
button.setClickable(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public class AdvancedPinPreferenceFragment extends ListSummaryPreferenceFragment
|
|||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||
if (requestCode == CreateKbsPinActivity.REQUEST_NEW_PIN && resultCode == CreateKbsPinActivity.RESULT_OK) {
|
||||
Snackbar.make(requireView(), R.string.ApplicationPreferencesActivity_pin_created, Snackbar.LENGTH_LONG).setTextColor(Color.WHITE).show();
|
||||
Snackbar.make(requireView(), R.string.ApplicationPreferencesActivity_pin_created, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ public class AdvancedPinPreferenceFragment extends ListSummaryPreferenceFragment
|
|||
PinOptOutDialog.show(requireContext(),
|
||||
() -> {
|
||||
updatePreferenceState();
|
||||
Snackbar.make(requireView(), R.string.ApplicationPreferencesActivity_pin_disabled, Snackbar.LENGTH_SHORT).setTextColor(Color.WHITE).show();
|
||||
Snackbar.make(requireView(), R.string.ApplicationPreferencesActivity_pin_disabled, Snackbar.LENGTH_SHORT).show();
|
||||
});
|
||||
} else {
|
||||
startActivityForResult(CreateKbsPinActivity.getIntentForPinCreate(requireContext()), CreateKbsPinActivity.REQUEST_NEW_PIN);
|
||||
|
|
|
@ -16,8 +16,6 @@ import androidx.core.app.ShareCompat;
|
|||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
|
||||
import com.dd.CircularProgressButton;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.contactshare.SimpleTextWatcher;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
|
@ -25,6 +23,7 @@ import org.thoughtcrime.securesms.util.CommunicationActions;
|
|||
import org.thoughtcrime.securesms.util.SignalProxyUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
import org.thoughtcrime.securesms.util.views.LearnMoreTextView;
|
||||
import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState;
|
||||
import org.whispersystems.signalservice.internal.configuration.SignalProxy;
|
||||
|
@ -33,13 +32,13 @@ import java.util.Optional;
|
|||
|
||||
public class EditProxyFragment extends Fragment {
|
||||
|
||||
private SwitchCompat proxySwitch;
|
||||
private EditText proxyText;
|
||||
private TextView proxyTitle;
|
||||
private TextView proxyStatus;
|
||||
private View shareButton;
|
||||
private CircularProgressButton saveButton;
|
||||
private EditProxyViewModel viewModel;
|
||||
private SwitchCompat proxySwitch;
|
||||
private EditText proxyText;
|
||||
private TextView proxyTitle;
|
||||
private TextView proxyStatus;
|
||||
private View shareButton;
|
||||
private CircularProgressMaterialButton saveButton;
|
||||
private EditProxyViewModel viewModel;
|
||||
|
||||
public static EditProxyFragment newInstance() {
|
||||
return new EditProxyFragment();
|
||||
|
@ -173,14 +172,10 @@ public class EditProxyFragment extends Fragment {
|
|||
private void presentSaveState(@NonNull EditProxyViewModel.SaveState state) {
|
||||
switch (state) {
|
||||
case IDLE:
|
||||
saveButton.setClickable(true);
|
||||
saveButton.setIndeterminateProgressMode(false);
|
||||
saveButton.setProgress(0);
|
||||
saveButton.cancelSpinning();
|
||||
break;
|
||||
case IN_PROGRESS:
|
||||
saveButton.setClickable(false);
|
||||
saveButton.setIndeterminateProgressMode(true);
|
||||
saveButton.setProgress(50);
|
||||
saveButton.setSpinning();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import androidx.navigation.Navigation;
|
|||
|
||||
import com.airbnb.lottie.SimpleColorFilter;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.dd.CircularProgressButton;
|
||||
|
||||
import org.signal.core.util.EditTextUtil;
|
||||
import org.signal.core.util.StreamUtil;
|
||||
|
@ -45,6 +44,7 @@ import org.thoughtcrime.securesms.util.FeatureFlags;
|
|||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.navigation.SafeNavigation;
|
||||
import org.thoughtcrime.securesms.util.text.AfterTextChanged;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
import org.thoughtcrime.securesms.util.views.LearnMoreTextView;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -62,16 +62,16 @@ public class EditProfileFragment extends LoggingFragment {
|
|||
private static final int MAX_DESCRIPTION_GLYPHS = 480;
|
||||
private static final int MAX_DESCRIPTION_BYTES = 8192;
|
||||
|
||||
private Toolbar toolbar;
|
||||
private View title;
|
||||
private ImageView avatar;
|
||||
private CircularProgressButton finishButton;
|
||||
private EditText givenName;
|
||||
private EditText familyName;
|
||||
private View reveal;
|
||||
private TextView preview;
|
||||
private ImageView avatarPreviewBackground;
|
||||
private ImageView avatarPreview;
|
||||
private Toolbar toolbar;
|
||||
private View title;
|
||||
private ImageView avatar;
|
||||
private CircularProgressMaterialButton finishButton;
|
||||
private EditText givenName;
|
||||
private EditText familyName;
|
||||
private View reveal;
|
||||
private TextView preview;
|
||||
private ImageView avatarPreviewBackground;
|
||||
private ImageView avatarPreview;
|
||||
|
||||
private Intent nextIntent;
|
||||
|
||||
|
@ -223,8 +223,7 @@ public class EditProfileFragment extends LoggingFragment {
|
|||
}
|
||||
|
||||
this.finishButton.setOnClickListener(v -> {
|
||||
this.finishButton.setIndeterminateProgressMode(true);
|
||||
this.finishButton.setProgress(50);
|
||||
this.finishButton.setSpinning();
|
||||
handleUpload();
|
||||
});
|
||||
|
||||
|
@ -313,7 +312,7 @@ public class EditProfileFragment extends LoggingFragment {
|
|||
}
|
||||
|
||||
private void handleFinishedLegacy() {
|
||||
finishButton.setProgress(0);
|
||||
finishButton.cancelSpinning();
|
||||
if (nextIntent != null) startActivity(nextIntent);
|
||||
|
||||
controller.onProfileNameUploadCompleted();
|
||||
|
@ -341,7 +340,7 @@ public class EditProfileFragment extends LoggingFragment {
|
|||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
finishButton.setProgress(0);
|
||||
finishButton.cancelSpinning();
|
||||
if (nextIntent != null && getActivity() != null) {
|
||||
startActivity(nextIntent);
|
||||
}
|
||||
|
|
|
@ -22,8 +22,6 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
|||
import androidx.recyclerview.widget.ListAdapter;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.dd.CircularProgressButton;
|
||||
|
||||
import org.signal.core.util.BreakIteratorCompat;
|
||||
import org.signal.core.util.EditTextUtil;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
@ -34,6 +32,7 @@ import org.signal.core.util.StringUtil;
|
|||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.adapter.AlwaysChangedDiffUtil;
|
||||
import org.thoughtcrime.securesms.util.text.AfterTextChanged;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
import org.whispersystems.signalservice.api.crypto.ProfileCipher;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -60,11 +59,11 @@ public class EditAboutFragment extends Fragment implements ManageProfileActivity
|
|||
new AboutPreset("\uD83D\uDE80", R.string.EditAboutFragment_working_on_something_new)
|
||||
);
|
||||
|
||||
private ImageView emojiView;
|
||||
private EditText bodyView;
|
||||
private TextView countView;
|
||||
private CircularProgressButton saveButton;
|
||||
private EditAboutViewModel viewModel;
|
||||
private ImageView emojiView;
|
||||
private EditText bodyView;
|
||||
private TextView countView;
|
||||
private CircularProgressMaterialButton saveButton;
|
||||
private EditAboutViewModel viewModel;
|
||||
|
||||
private String selectedEmoji;
|
||||
|
||||
|
@ -167,14 +166,10 @@ public class EditAboutFragment extends Fragment implements ManageProfileActivity
|
|||
private void presentSaveState(@NonNull EditAboutViewModel.SaveState state) {
|
||||
switch (state) {
|
||||
case IDLE:
|
||||
saveButton.setClickable(true);
|
||||
saveButton.setIndeterminateProgressMode(false);
|
||||
saveButton.setProgress(0);
|
||||
saveButton.cancelSpinning();
|
||||
break;
|
||||
case IN_PROGRESS:
|
||||
saveButton.setClickable(false);
|
||||
saveButton.setIndeterminateProgressMode(true);
|
||||
saveButton.setProgress(50);
|
||||
saveButton.setSpinning();
|
||||
break;
|
||||
case DONE:
|
||||
saveButton.setClickable(false);
|
||||
|
|
|
@ -16,8 +16,6 @@ import androidx.fragment.app.Fragment;
|
|||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.dd.CircularProgressButton;
|
||||
|
||||
import org.signal.core.util.EditTextUtil;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName;
|
||||
|
@ -25,6 +23,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
|||
import org.signal.core.util.StringUtil;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.text.AfterTextChanged;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
|
||||
/**
|
||||
* Simple fragment to edit your profile name.
|
||||
|
@ -33,10 +32,10 @@ public class EditProfileNameFragment extends Fragment {
|
|||
|
||||
public static final int NAME_MAX_GLYPHS = 26;
|
||||
|
||||
private EditText givenName;
|
||||
private EditText familyName;
|
||||
private CircularProgressButton saveButton;
|
||||
private EditProfileNameViewModel viewModel;
|
||||
private EditText givenName;
|
||||
private EditText familyName;
|
||||
private CircularProgressMaterialButton saveButton;
|
||||
private EditProfileNameViewModel viewModel;
|
||||
|
||||
@Override
|
||||
public @NonNull View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
|
@ -92,17 +91,13 @@ public class EditProfileNameFragment extends Fragment {
|
|||
setEditTextEnabled(familyName, true);
|
||||
break;
|
||||
case IDLE:
|
||||
saveButton.setClickable(true);
|
||||
saveButton.setIndeterminateProgressMode(false);
|
||||
saveButton.setProgress(0);
|
||||
saveButton.cancelSpinning();
|
||||
saveButton.setAlpha(1);
|
||||
setEditTextEnabled(givenName, true);
|
||||
setEditTextEnabled(familyName, true);
|
||||
break;
|
||||
case IN_PROGRESS:
|
||||
saveButton.setClickable(false);
|
||||
saveButton.setIndeterminateProgressMode(true);
|
||||
saveButton.setProgress(50);
|
||||
saveButton.setSpinning();
|
||||
saveButton.setAlpha(1);
|
||||
setEditTextEnabled(givenName, false);
|
||||
setEditTextEnabled(familyName, false);
|
||||
|
|
|
@ -16,13 +16,12 @@ import androidx.lifecycle.ViewModelProviders;
|
|||
import androidx.navigation.Navigation;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
|
||||
import com.dd.CircularProgressButton;
|
||||
|
||||
import org.thoughtcrime.securesms.LoggingFragment;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.contactshare.SimpleTextWatcher;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.UsernameUtil;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
|
||||
public class UsernameEditFragment extends LoggingFragment {
|
||||
|
||||
|
@ -30,10 +29,10 @@ public class UsernameEditFragment extends LoggingFragment {
|
|||
|
||||
private UsernameEditViewModel viewModel;
|
||||
|
||||
private EditText usernameInput;
|
||||
private TextView usernameSubtext;
|
||||
private CircularProgressButton submitButton;
|
||||
private CircularProgressButton deleteButton;
|
||||
private EditText usernameInput;
|
||||
private TextView usernameSubtext;
|
||||
private CircularProgressMaterialButton submitButton;
|
||||
private CircularProgressMaterialButton deleteButton;
|
||||
|
||||
public static UsernameEditFragment newInstance() {
|
||||
return new UsernameEditFragment();
|
||||
|
@ -84,42 +83,42 @@ public class UsernameEditFragment extends LoggingFragment {
|
|||
|
||||
switch (state.getButtonState()) {
|
||||
case SUBMIT:
|
||||
cancelSpinning(submitButton);
|
||||
submitButton.cancelSpinning();
|
||||
submitButton.setVisibility(View.VISIBLE);
|
||||
submitButton.setEnabled(true);
|
||||
submitButton.setAlpha(1);
|
||||
deleteButton.setVisibility(View.GONE);
|
||||
break;
|
||||
case SUBMIT_DISABLED:
|
||||
cancelSpinning(submitButton);
|
||||
submitButton.cancelSpinning();
|
||||
submitButton.setVisibility(View.VISIBLE);
|
||||
submitButton.setEnabled(false);
|
||||
submitButton.setAlpha(DISABLED_ALPHA);
|
||||
deleteButton.setVisibility(View.GONE);
|
||||
break;
|
||||
case SUBMIT_LOADING:
|
||||
setSpinning(submitButton);
|
||||
submitButton.setSpinning();
|
||||
submitButton.setVisibility(View.VISIBLE);
|
||||
submitButton.setAlpha(1);
|
||||
deleteButton.setVisibility(View.GONE);
|
||||
usernameInput.setEnabled(false);
|
||||
break;
|
||||
case DELETE:
|
||||
cancelSpinning(deleteButton);
|
||||
deleteButton.cancelSpinning();
|
||||
deleteButton.setVisibility(View.VISIBLE);
|
||||
deleteButton.setEnabled(true);
|
||||
deleteButton.setAlpha(1);
|
||||
submitButton.setVisibility(View.GONE);
|
||||
break;
|
||||
case DELETE_DISABLED:
|
||||
cancelSpinning(deleteButton);
|
||||
deleteButton.cancelSpinning();
|
||||
deleteButton.setVisibility(View.VISIBLE);
|
||||
deleteButton.setEnabled(false);
|
||||
deleteButton.setAlpha(DISABLED_ALPHA);
|
||||
submitButton.setVisibility(View.GONE);
|
||||
break;
|
||||
case DELETE_LOADING:
|
||||
setSpinning(deleteButton);
|
||||
deleteButton.setSpinning();
|
||||
deleteButton.setVisibility(View.VISIBLE);
|
||||
deleteButton.setAlpha(1);
|
||||
submitButton.setVisibility(View.GONE);
|
||||
|
@ -180,16 +179,4 @@ public class UsernameEditFragment extends LoggingFragment {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void setSpinning(@NonNull CircularProgressButton button) {
|
||||
button.setClickable(false);
|
||||
button.setIndeterminateProgressMode(true);
|
||||
button.setProgress(50);
|
||||
}
|
||||
|
||||
private static void cancelSpinning(@NonNull CircularProgressButton button) {
|
||||
button.setProgress(0);
|
||||
button.setIndeterminateProgressMode(false);
|
||||
button.setClickable(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,14 +14,15 @@ import androidx.fragment.app.DialogFragment;
|
|||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
|
||||
import com.dd.CircularProgressButton;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.preferences.EditProxyViewModel;
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
|
||||
/**
|
||||
* A bottom sheet shown in response to a deep link. Allows a user to set a proxy.
|
||||
|
@ -32,10 +33,10 @@ public final class ProxyBottomSheetFragment extends BottomSheetDialogFragment {
|
|||
|
||||
private static final String ARG_PROXY_LINK = "proxy_link";
|
||||
|
||||
private TextView proxyText;
|
||||
private View cancelButton;
|
||||
private CircularProgressButton useProxyButton;
|
||||
private EditProxyViewModel viewModel;
|
||||
private TextView proxyText;
|
||||
private View cancelButton;
|
||||
private CircularProgressMaterialButton useProxyButton;
|
||||
private EditProxyViewModel viewModel;
|
||||
|
||||
public static void showForProxy(@NonNull FragmentManager manager, @NonNull String proxyLink) {
|
||||
ProxyBottomSheetFragment fragment = new ProxyBottomSheetFragment();
|
||||
|
@ -86,14 +87,10 @@ public final class ProxyBottomSheetFragment extends BottomSheetDialogFragment {
|
|||
private void presentSaveState(@NonNull EditProxyViewModel.SaveState state) {
|
||||
switch (state) {
|
||||
case IDLE:
|
||||
useProxyButton.setClickable(true);
|
||||
useProxyButton.setIndeterminateProgressMode(false);
|
||||
useProxyButton.setProgress(0);
|
||||
useProxyButton.cancelSpinning();
|
||||
break;
|
||||
case IN_PROGRESS:
|
||||
useProxyButton.setClickable(false);
|
||||
useProxyButton.setIndeterminateProgressMode(true);
|
||||
useProxyButton.setProgress(50);
|
||||
useProxyButton.setSpinning();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +102,7 @@ public final class ProxyBottomSheetFragment extends BottomSheetDialogFragment {
|
|||
dismiss();
|
||||
break;
|
||||
case PROXY_FAILURE:
|
||||
new AlertDialog.Builder(requireContext())
|
||||
new MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.preferences_failed_to_connect)
|
||||
.setMessage(R.string.preferences_couldnt_connect_to_the_proxy)
|
||||
.setPositiveButton(android.R.string.ok, (d, i) -> d.dismiss())
|
||||
|
|
|
@ -14,7 +14,6 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import com.dd.CircularProgressButton;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
|
@ -26,6 +25,7 @@ import org.thoughtcrime.securesms.registration.viewmodel.BaseRegistrationViewMod
|
|||
import org.thoughtcrime.securesms.util.LifecycleDisposable;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -33,8 +33,6 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
|||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
|
||||
import static org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegate.setDebugLogSubmitMultiTapView;
|
||||
import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.cancelSpinning;
|
||||
import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.setSpinning;
|
||||
|
||||
/**
|
||||
* Base fragment used by registration and change number flow to deal with a registration locked account.
|
||||
|
@ -48,12 +46,12 @@ public abstract class BaseRegistrationLockFragment extends LoggingFragment {
|
|||
*/
|
||||
private static final int MINIMUM_PIN_LENGTH = 4;
|
||||
|
||||
private EditText pinEntry;
|
||||
private View forgotPin;
|
||||
protected CircularProgressButton pinButton;
|
||||
private TextView errorLabel;
|
||||
private TextView keyboardToggle;
|
||||
private long timeRemaining;
|
||||
private EditText pinEntry;
|
||||
private View forgotPin;
|
||||
protected CircularProgressMaterialButton pinButton;
|
||||
private TextView errorLabel;
|
||||
private TextView keyboardToggle;
|
||||
private long timeRemaining;
|
||||
|
||||
private BaseRegistrationViewModel viewModel;
|
||||
|
||||
|
@ -171,7 +169,7 @@ public abstract class BaseRegistrationLockFragment extends LoggingFragment {
|
|||
return;
|
||||
}
|
||||
|
||||
setSpinning(pinButton);
|
||||
pinButton.setSpinning();
|
||||
|
||||
Disposable verify = viewModel.verifyCodeAndRegisterAccountWithRegistrationLock(pin)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -194,7 +192,7 @@ public abstract class BaseRegistrationLockFragment extends LoggingFragment {
|
|||
}
|
||||
|
||||
public void onIncorrectKbsRegistrationLockPin(@NonNull TokenData tokenData) {
|
||||
cancelSpinning(pinButton);
|
||||
pinButton.cancelSpinning();
|
||||
pinEntry.getText().clear();
|
||||
enableAndFocusPinEntry();
|
||||
|
||||
|
@ -227,7 +225,7 @@ public abstract class BaseRegistrationLockFragment extends LoggingFragment {
|
|||
}
|
||||
|
||||
public void onRateLimited() {
|
||||
cancelSpinning(pinButton);
|
||||
pinButton.cancelSpinning();
|
||||
enableAndFocusPinEntry();
|
||||
|
||||
new MaterialAlertDialogBuilder(requireContext())
|
||||
|
@ -242,7 +240,7 @@ public abstract class BaseRegistrationLockFragment extends LoggingFragment {
|
|||
}
|
||||
|
||||
public void onError() {
|
||||
cancelSpinning(pinButton);
|
||||
pinButton.cancelSpinning();
|
||||
enableAndFocusPinEntry();
|
||||
|
||||
Toast.makeText(requireContext(), R.string.RegistrationActivity_error_connecting_to_service, Toast.LENGTH_LONG).show();
|
||||
|
|
|
@ -22,7 +22,6 @@ import androidx.navigation.NavController;
|
|||
import androidx.navigation.Navigation;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
|
||||
import com.dd.CircularProgressButton;
|
||||
import com.google.android.gms.auth.api.phone.SmsRetriever;
|
||||
import com.google.android.gms.auth.api.phone.SmsRetrieverClient;
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
|
@ -50,26 +49,25 @@ import org.thoughtcrime.securesms.util.PlayServicesUtil;
|
|||
import org.thoughtcrime.securesms.util.SupportEmailUtil;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.navigation.SafeNavigation;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
|
||||
import static org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegate.setDebugLogSubmitMultiTapView;
|
||||
import static org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegate.showConfirmNumberDialogIfTranslated;
|
||||
import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.cancelSpinning;
|
||||
import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.setSpinning;
|
||||
|
||||
public final class EnterPhoneNumberFragment extends LoggingFragment implements RegistrationNumberInputController.Callbacks {
|
||||
|
||||
private static final String TAG = Log.tag(EnterPhoneNumberFragment.class);
|
||||
|
||||
private LabeledEditText countryCode;
|
||||
private LabeledEditText number;
|
||||
private CircularProgressButton register;
|
||||
private Spinner countrySpinner;
|
||||
private View cancel;
|
||||
private ScrollView scrollView;
|
||||
private RegistrationViewModel viewModel;
|
||||
private LabeledEditText countryCode;
|
||||
private LabeledEditText number;
|
||||
private CircularProgressMaterialButton register;
|
||||
private Spinner countrySpinner;
|
||||
private View cancel;
|
||||
private ScrollView scrollView;
|
||||
private RegistrationViewModel viewModel;
|
||||
|
||||
private final LifecycleDisposable disposables = new LifecycleDisposable();
|
||||
|
||||
|
@ -179,7 +177,7 @@ public final class EnterPhoneNumberFragment extends LoggingFragment implements R
|
|||
}
|
||||
|
||||
private void handleRequestVerification(@NonNull Context context, boolean fcmSupported) {
|
||||
setSpinning(register);
|
||||
register.setSpinning();
|
||||
disableAllEntries();
|
||||
|
||||
if (fcmSupported) {
|
||||
|
@ -247,7 +245,7 @@ public final class EnterPhoneNumberFragment extends LoggingFragment implements R
|
|||
Toast.makeText(register.getContext(), R.string.RegistrationActivity_unable_to_connect_to_service, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
cancelSpinning(register);
|
||||
register.cancelSpinning();
|
||||
enableAllEntries();
|
||||
});
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import androidx.annotation.NonNull;
|
|||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
|
@ -16,14 +17,11 @@ import org.thoughtcrime.securesms.util.CommunicationActions;
|
|||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.Stopwatch;
|
||||
import org.thoughtcrime.securesms.util.SupportEmailUtil;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.navigation.SafeNavigation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.cancelSpinning;
|
||||
|
||||
public final class RegistrationLockFragment extends BaseRegistrationLockFragment {
|
||||
|
||||
private static final String TAG = Log.tag(RegistrationLockFragment.class);
|
||||
|
@ -68,7 +66,7 @@ public final class RegistrationLockFragment extends BaseRegistrationLockFragment
|
|||
|
||||
return null;
|
||||
}, none -> {
|
||||
cancelSpinning(pinButton);
|
||||
pinButton.cancelSpinning();
|
||||
SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), RegistrationLockFragmentDirections.actionSuccessfulRegistration());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -31,8 +31,6 @@ import androidx.appcompat.app.AlertDialog;
|
|||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.dd.CircularProgressButton;
|
||||
|
||||
import net.zetetic.database.sqlcipher.SQLiteDatabase;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
@ -58,25 +56,24 @@ import org.thoughtcrime.securesms.util.DateUtils;
|
|||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.navigation.SafeNavigation;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegate.setDebugLogSubmitMultiTapView;
|
||||
import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.cancelSpinning;
|
||||
import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.setSpinning;
|
||||
|
||||
public final class RestoreBackupFragment extends LoggingFragment {
|
||||
|
||||
private static final String TAG = Log.tag(RestoreBackupFragment.class);
|
||||
private static final short OPEN_DOCUMENT_TREE_RESULT_CODE = 13782;
|
||||
|
||||
private TextView restoreBackupSize;
|
||||
private TextView restoreBackupTime;
|
||||
private TextView restoreBackupProgress;
|
||||
private CircularProgressButton restoreButton;
|
||||
private View skipRestoreButton;
|
||||
private RegistrationViewModel viewModel;
|
||||
private TextView restoreBackupSize;
|
||||
private TextView restoreBackupTime;
|
||||
private TextView restoreBackupProgress;
|
||||
private CircularProgressMaterialButton restoreButton;
|
||||
private View skipRestoreButton;
|
||||
private RegistrationViewModel viewModel;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
|
@ -261,7 +258,7 @@ public final class RestoreBackupFragment extends LoggingFragment {
|
|||
InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
inputMethodManager.hideSoftInputFromWindow(prompt.getWindowToken(), 0);
|
||||
|
||||
setSpinning(restoreButton);
|
||||
restoreButton.setSpinning();
|
||||
skipRestoreButton.setVisibility(View.INVISIBLE);
|
||||
|
||||
String passphrase = prompt.getText().toString();
|
||||
|
@ -315,7 +312,7 @@ public final class RestoreBackupFragment extends LoggingFragment {
|
|||
@Override
|
||||
protected void onPostExecute(@NonNull BackupImportResult result) {
|
||||
viewModel.markBackupCompleted();
|
||||
cancelSpinning(restoreButton);
|
||||
restoreButton.cancelSpinning();
|
||||
skipRestoreButton.setVisibility(View.VISIBLE);
|
||||
|
||||
restoreBackupProgress.setText("");
|
||||
|
@ -365,7 +362,7 @@ public final class RestoreBackupFragment extends LoggingFragment {
|
|||
restoreBackupProgress.setText(getString(R.string.RegistrationActivity_d_messages_so_far, count));
|
||||
}
|
||||
|
||||
setSpinning(restoreButton);
|
||||
restoreButton.setSpinning();
|
||||
skipRestoreButton.setVisibility(View.INVISIBLE);
|
||||
|
||||
if (event.getType() == FullBackupBase.BackupEvent.Type.FINISHED) {
|
||||
|
|
|
@ -22,7 +22,6 @@ import androidx.navigation.ActivityNavigator;
|
|||
import androidx.navigation.Navigation;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
|
||||
import com.dd.CircularProgressButton;
|
||||
import com.google.i18n.phonenumbers.PhoneNumberUtil;
|
||||
import com.google.i18n.phonenumbers.Phonenumber;
|
||||
|
||||
|
@ -40,12 +39,11 @@ import org.thoughtcrime.securesms.util.CommunicationActions;
|
|||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.navigation.SafeNavigation;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegate.setDebugLogSubmitMultiTapView;
|
||||
import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.cancelSpinning;
|
||||
import static org.thoughtcrime.securesms.util.CircularProgressButtonUtil.setSpinning;
|
||||
|
||||
public final class WelcomeFragment extends LoggingFragment {
|
||||
|
||||
|
@ -74,8 +72,8 @@ public final class WelcomeFragment extends LoggingFragment {
|
|||
private static final int[] HEADERS = { R.drawable.ic_contacts_white_48dp, R.drawable.ic_folder_white_48dp };
|
||||
private static final int[] HEADERS_API_29 = { R.drawable.ic_contacts_white_48dp };
|
||||
|
||||
private CircularProgressButton continueButton;
|
||||
private RegistrationViewModel viewModel;
|
||||
private CircularProgressMaterialButton continueButton;
|
||||
private RegistrationViewModel viewModel;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
@ -164,7 +162,7 @@ public final class WelcomeFragment extends LoggingFragment {
|
|||
}
|
||||
|
||||
private void gatherInformationAndContinue(@NonNull View view) {
|
||||
setSpinning(continueButton);
|
||||
continueButton.setSpinning();
|
||||
|
||||
RestoreBackupFragment.searchForBackup(backup -> {
|
||||
Context context = getContext();
|
||||
|
@ -177,7 +175,7 @@ public final class WelcomeFragment extends LoggingFragment {
|
|||
|
||||
initializeNumber();
|
||||
|
||||
cancelSpinning(continueButton);
|
||||
continueButton.cancelSpinning();
|
||||
|
||||
if (backup == null) {
|
||||
Log.i(TAG, "Skipping backup. No backup found, or no permission to look.");
|
||||
|
|
|
@ -11,7 +11,6 @@ import androidx.lifecycle.ViewModelProvider;
|
|||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
import com.dd.CircularProgressButton;
|
||||
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
@ -28,6 +27,7 @@ import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
|||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.text.AfterTextChanged;
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
|
@ -39,12 +39,12 @@ public class ShareInterstitialActivity extends PassphraseRequiredActivity {
|
|||
|
||||
private static final String ARGS = "args";
|
||||
|
||||
private ShareInterstitialViewModel viewModel;
|
||||
private LinkPreviewViewModel linkPreviewViewModel;
|
||||
private CircularProgressButton confirm;
|
||||
private RecyclerView contactsRecycler;
|
||||
private Toolbar toolbar;
|
||||
private LinkPreviewView preview;
|
||||
private ShareInterstitialViewModel viewModel;
|
||||
private LinkPreviewViewModel linkPreviewViewModel;
|
||||
private CircularProgressMaterialButton confirm;
|
||||
private RecyclerView contactsRecycler;
|
||||
private Toolbar toolbar;
|
||||
private LinkPreviewView preview;
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
|
||||
private final ShareInterstitialSelectionAdapter adapter = new ShareInterstitialSelectionAdapter();
|
||||
|
@ -171,9 +171,7 @@ public class ShareInterstitialActivity extends PassphraseRequiredActivity {
|
|||
}
|
||||
|
||||
private void onConfirm() {
|
||||
confirm.setClickable(false);
|
||||
confirm.setIndeterminateProgressMode(true);
|
||||
confirm.setProgress(50);
|
||||
confirm.setSpinning();
|
||||
|
||||
viewModel.send(results -> {
|
||||
MultiShareDialogs.displayResultDialog(this, results, () -> {
|
||||
|
|
|
@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.stories.landing
|
|||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.transition.TransitionInflater
|
||||
|
@ -36,6 +35,7 @@ import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectFor
|
|||
import org.thoughtcrime.securesms.conversation.ui.error.SafetyNumberChangeDialog
|
||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||
import org.thoughtcrime.securesms.main.Material3OnScrollHelperBinder
|
||||
import org.thoughtcrime.securesms.mediasend.v2.MediaSelectionActivity
|
||||
import org.thoughtcrime.securesms.permissions.Permissions
|
||||
import org.thoughtcrime.securesms.stories.StoryTextPostModel
|
||||
|
@ -48,6 +48,7 @@ import org.thoughtcrime.securesms.stories.tabs.ConversationListTab
|
|||
import org.thoughtcrime.securesms.stories.tabs.ConversationListTabsViewModel
|
||||
import org.thoughtcrime.securesms.stories.viewer.StoryViewerActivity
|
||||
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
||||
import org.thoughtcrime.securesms.util.fragments.requireListener
|
||||
import org.thoughtcrime.securesms.util.visible
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
@ -97,6 +98,8 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
|||
MyStoriesItem.register(adapter)
|
||||
ExpandHeader.register(adapter)
|
||||
|
||||
requireListener<Material3OnScrollHelperBinder>().bindScrollHelper(recyclerView!!)
|
||||
|
||||
lifecycleDisposable.bindTo(viewLifecycleOwner)
|
||||
emptyNotice = requireView().findViewById(R.id.empty_notice)
|
||||
cameraFab = requireView().findViewById(R.id.camera_fab)
|
||||
|
@ -105,7 +108,7 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
|||
setEnterSharedElementCallback(object : SharedElementCallback() {
|
||||
override fun onSharedElementStart(sharedElementNames: MutableList<String>?, sharedElements: MutableList<View>?, sharedElementSnapshots: MutableList<View>?) {
|
||||
if (sharedElementNames?.contains("camera_fab") == true) {
|
||||
cameraFab.setImageResource(R.drawable.ic_compose_24)
|
||||
cameraFab.setImageResource(R.drawable.ic_compose_outline_24)
|
||||
lifecycleDisposable += Single.timer(200, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeBy {
|
||||
|
@ -279,7 +282,6 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
|||
.setPositiveButton(R.string.StoriesLandingFragment__hide) { _, _ ->
|
||||
viewModel.setHideStory(model.data.storyRecipient, true).subscribe {
|
||||
Snackbar.make(cameraFab, R.string.StoriesLandingFragment__story_hidden, Snackbar.LENGTH_SHORT)
|
||||
.setTextColor(Color.WHITE)
|
||||
.setAnchorView(cameraFab)
|
||||
.setAnimationMode(BaseTransientBottomBar.ANIMATION_MODE_FADE)
|
||||
.show()
|
||||
|
|
|
@ -11,13 +11,13 @@ import androidx.fragment.app.Fragment
|
|||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.airbnb.lottie.SimpleColorFilter
|
||||
import com.dd.CircularProgressButton
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.database.model.DistributionListId
|
||||
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
||||
import org.thoughtcrime.securesms.util.ViewUtil
|
||||
import org.thoughtcrime.securesms.util.views.CircularProgressMaterialButton
|
||||
|
||||
class EditStoryNameFragment : Fragment(R.layout.stories_edit_story_name_fragment) {
|
||||
|
||||
|
@ -35,7 +35,7 @@ class EditStoryNameFragment : Fragment(R.layout.stories_edit_story_name_fragment
|
|||
|
||||
private val lifecycleDisposable = LifecycleDisposable()
|
||||
|
||||
private lateinit var saveButton: CircularProgressButton
|
||||
private lateinit var saveButton: CircularProgressMaterialButton
|
||||
private lateinit var storyName: EditText
|
||||
private lateinit var storyNameWrapper: TextInputLayout
|
||||
|
||||
|
|
|
@ -107,7 +107,6 @@ class StoryReplyComposer @JvmOverloads constructor(
|
|||
false,
|
||||
messageRecord.slideDeck,
|
||||
null,
|
||||
null,
|
||||
QuoteModel.Type.NORMAL
|
||||
)
|
||||
|
||||
|
|
|
@ -203,7 +203,7 @@ object StoryGroupReplyItem {
|
|||
|
||||
val actions = mutableListOf<ActionItem>()
|
||||
if (model.onCopyClick != null) {
|
||||
actions += ActionItem(R.drawable.ic_copy_24_solid_tinted, context.getString(R.string.StoryGroupReplyItem__copy)) {
|
||||
actions += ActionItem(R.drawable.ic_copy_24_tinted, context.getString(R.string.StoryGroupReplyItem__copy)) {
|
||||
val toCopy: CharSequence = when (model) {
|
||||
is TextModel -> model.text.message.getDisplayBody(context)
|
||||
else -> model.messageRecord.getDisplayBody(context)
|
||||
|
@ -211,7 +211,7 @@ object StoryGroupReplyItem {
|
|||
model.onCopyClick.invoke(toCopy)
|
||||
}
|
||||
}
|
||||
actions += ActionItem(R.drawable.ic_trash_24_solid_tinted, context.getString(R.string.StoryGroupReplyItem__delete)) { model.onDeleteClick(model.messageRecord) }
|
||||
actions += ActionItem(R.drawable.ic_trash_24, context.getString(R.string.StoryGroupReplyItem__delete)) { model.onDeleteClick(model.messageRecord) }
|
||||
|
||||
SignalContextMenu.Builder(itemView, itemView.rootView as ViewGroup)
|
||||
.preferredHorizontalPosition(SignalContextMenu.HorizontalPosition.START)
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
package org.thoughtcrime.securesms.util
|
||||
|
||||
import com.dd.CircularProgressButton
|
||||
|
||||
object CircularProgressButtonUtil {
|
||||
|
||||
@JvmStatic
|
||||
fun setSpinning(button: CircularProgressButton?) {
|
||||
button?.apply {
|
||||
isClickable = false
|
||||
isIndeterminateProgressMode = true
|
||||
progress = 50
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun cancelSpinning(button: CircularProgressButton?) {
|
||||
button?.apply {
|
||||
progress = 0
|
||||
isIndeterminateProgressMode = false
|
||||
isClickable = true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package org.thoughtcrime.securesms.util
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Build
|
||||
import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.util.views.Stub
|
||||
|
||||
/**
|
||||
* Sets the view's isActivated state when the content of the attached recycler can scroll up.
|
||||
* This can be used to appropriately tint toolbar backgrounds. Also can emit the state change
|
||||
* for other purposes.
|
||||
*/
|
||||
class Material3OnScrollHelper(
|
||||
private val views: List<View>,
|
||||
private val viewStubs: List<Stub<out View>> = emptyList(),
|
||||
private val onActiveStateChanged: (Boolean) -> Unit
|
||||
) : RecyclerView.OnScrollListener() {
|
||||
|
||||
constructor(activity: Activity, views: List<View>, viewStubs: List<Stub<out View>>) : this(views, viewStubs, { updateStatusBarColor(activity, it) })
|
||||
|
||||
constructor(activity: Activity, view: View) : this(listOf(view), emptyList(), { updateStatusBarColor(activity, it) })
|
||||
|
||||
private var active: Boolean? = null
|
||||
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
updateActiveState(recyclerView.canScrollVertically(-1))
|
||||
}
|
||||
|
||||
private fun updateActiveState(isActive: Boolean) {
|
||||
if (active == isActive) {
|
||||
return
|
||||
}
|
||||
|
||||
active = isActive
|
||||
|
||||
views.forEach { it.isActivated = isActive }
|
||||
viewStubs.filter { it.resolved() }.forEach { it.get().isActivated = isActive }
|
||||
|
||||
onActiveStateChanged(isActive)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun updateStatusBarColor(activity: Activity, isActive: Boolean) {
|
||||
if (Build.VERSION.SDK_INT > 21) {
|
||||
if (isActive) {
|
||||
WindowUtil.setStatusBarColor(activity.window, ContextCompat.getColor(activity, R.color.signal_colorSurface2))
|
||||
} else {
|
||||
WindowUtil.setStatusBarColor(activity.window, ContextCompat.getColor(activity, R.color.signal_colorBackground))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -122,6 +122,15 @@ public final class Projection {
|
|||
return set(x, y, (int) (width * scale), (int) (height * scale), newCorners);
|
||||
}
|
||||
|
||||
public @NonNull Projection insetTop(int boundary) {
|
||||
Corners newCorners = this.corners == null ? null : new Corners(0,
|
||||
0,
|
||||
this.corners.bottomRight,
|
||||
this.corners.bottomLeft);
|
||||
|
||||
return set(x, y + boundary, width, height - boundary, newCorners);
|
||||
}
|
||||
|
||||
public static @NonNull Projection relativeToParent(@NonNull ViewGroup parent, @NonNull View view, @Nullable Corners corners) {
|
||||
Rect viewBounds = new Rect();
|
||||
|
||||
|
|
|
@ -75,8 +75,6 @@ public abstract class SnackbarAsyncTask<Params>
|
|||
|
||||
Snackbar.make(view, snackbarText, snackbarDuration)
|
||||
.setAction(snackbarActionText, this)
|
||||
.setActionTextColor(snackbarActionColor)
|
||||
.setTextColor(Color.WHITE)
|
||||
.show();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
package org.thoughtcrime.securesms.util.views
|
||||
|
||||
import android.animation.Animator
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.util.AttributeSet
|
||||
import android.view.ViewAnimationUtils
|
||||
import android.widget.FrameLayout
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.animation.doOnEnd
|
||||
import androidx.core.content.withStyledAttributes
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.theme.overlay.MaterialThemeOverlay
|
||||
import org.thoughtcrime.securesms.R
|
||||
import kotlin.math.max
|
||||
|
||||
/**
|
||||
* Drop-In replacement for CircularProgressButton that better supports material design.
|
||||
*/
|
||||
class CircularProgressMaterialButton @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null
|
||||
) : FrameLayout(MaterialThemeOverlay.wrap(context, attrs, 0, 0), attrs, 0) {
|
||||
init {
|
||||
inflate(getContext(), R.layout.circular_progress_material_button, this)
|
||||
}
|
||||
|
||||
private var currentState: State = State.BUTTON
|
||||
private var requestedState: State = State.BUTTON
|
||||
|
||||
private var animator: Animator? = null
|
||||
|
||||
private val materialButton: MaterialButton = findViewById(R.id.button)
|
||||
|
||||
var text: CharSequence?
|
||||
get() = materialButton.text
|
||||
set(value) {
|
||||
materialButton.text = value
|
||||
}
|
||||
|
||||
init {
|
||||
getContext().withStyledAttributes(attrs, R.styleable.CircularProgressMaterialButton) {
|
||||
val label = getString(R.styleable.CircularProgressMaterialButton_circularProgressMaterialButton__label)
|
||||
|
||||
materialButton.text = label
|
||||
}
|
||||
}
|
||||
|
||||
fun setText(@StringRes resId: Int) {
|
||||
materialButton.setText(resId)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(): Parcelable {
|
||||
return Bundle().apply {
|
||||
putParcelable(SUPER_STATE, super.onSaveInstanceState())
|
||||
putInt(STATE, if (requestedState != currentState) requestedState.code else currentState.code)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRestoreInstanceState(state: Parcelable) {
|
||||
val stateBundle = state as Bundle
|
||||
val superState: Parcelable? = stateBundle.getParcelable(SUPER_STATE)
|
||||
super.onRestoreInstanceState(superState)
|
||||
|
||||
currentState = if (materialButton.visibility == INVISIBLE) State.PROGRESS else State.BUTTON
|
||||
requestedState = State.fromCode(stateBundle.getInt(STATE))
|
||||
ensureRequestedState(false)
|
||||
}
|
||||
|
||||
override fun setOnClickListener(onClickListener: OnClickListener?) {
|
||||
materialButton.setOnClickListener(onClickListener)
|
||||
}
|
||||
|
||||
fun setSpinning() {
|
||||
transformTo(State.PROGRESS, true)
|
||||
}
|
||||
|
||||
fun cancelSpinning() {
|
||||
transformTo(State.BUTTON, true)
|
||||
}
|
||||
|
||||
private fun transformTo(state: State, animate: Boolean) {
|
||||
requestedState = state
|
||||
if (animator?.isRunning == true) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!animate || Build.VERSION.SDK_INT < 21) {
|
||||
materialButton.visibility = state.materialButtonVisibility
|
||||
currentState = state
|
||||
return
|
||||
}
|
||||
|
||||
currentState = state
|
||||
if (state == State.BUTTON) {
|
||||
materialButton.visibility = VISIBLE
|
||||
}
|
||||
|
||||
val buttonShrunkRadius = 0f
|
||||
val buttonExpandedRadius = max(measuredWidth, measuredHeight).toFloat()
|
||||
|
||||
animator = ViewAnimationUtils.createCircularReveal(
|
||||
materialButton,
|
||||
materialButton.measuredWidth / 2,
|
||||
materialButton.measuredHeight / 2,
|
||||
if (state == State.BUTTON) buttonShrunkRadius else buttonExpandedRadius,
|
||||
if (state == State.PROGRESS) buttonShrunkRadius else buttonExpandedRadius
|
||||
).apply {
|
||||
duration = ANIMATION_DURATION
|
||||
doOnEnd {
|
||||
materialButton.visibility = state.materialButtonVisibility
|
||||
ensureRequestedState(true)
|
||||
}
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
private fun ensureRequestedState(animate: Boolean) {
|
||||
if (requestedState == currentState || !isAttachedToWindow) {
|
||||
return
|
||||
}
|
||||
|
||||
transformTo(requestedState, animate)
|
||||
}
|
||||
|
||||
enum class State(val code: Int, val materialButtonVisibility: Int) {
|
||||
BUTTON(0, VISIBLE),
|
||||
PROGRESS(1, INVISIBLE);
|
||||
|
||||
companion object {
|
||||
fun fromCode(code: Int): State {
|
||||
return when (code) {
|
||||
0 -> BUTTON
|
||||
1 -> PROGRESS
|
||||
else -> error("Unexpected code $code")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val ANIMATION_DURATION = 300L
|
||||
|
||||
private val SUPER_STATE = "super_state"
|
||||
private val STATE = "state"
|
||||
}
|
||||
}
|
|
@ -4,14 +4,24 @@ import android.content.Context;
|
|||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Dimension;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Px;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
import org.signal.core.util.DimensionUnit;
|
||||
|
||||
public class SlideUpWithSnackbarBehavior extends CoordinatorLayout.Behavior<View> {
|
||||
|
||||
@Dimension(unit = Dimension.DP)
|
||||
private static final float PAD_TOP_OF_SNACKBAR_DP = 16f;
|
||||
|
||||
@Px
|
||||
private final float padTopOfSnackbar = DimensionUnit.DP.toPixels(PAD_TOP_OF_SNACKBAR_DP);
|
||||
|
||||
public SlideUpWithSnackbarBehavior(@NonNull Context context, @Nullable AttributeSet attributeSet) {
|
||||
super(context, attributeSet);
|
||||
}
|
||||
|
@ -21,7 +31,7 @@ public class SlideUpWithSnackbarBehavior extends CoordinatorLayout.Behavior<View
|
|||
@NonNull View child,
|
||||
@NonNull View dependency)
|
||||
{
|
||||
float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
|
||||
float translationY = Math.min(0, dependency.getTranslationY() - (dependency.getHeight() + padTopOfSnackbar));
|
||||
child.setTranslationY(translationY);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/signal_colorTransparent2" android:state_enabled="true"/>
|
||||
<item android:alpha="@dimen/material_emphasis_disabled_background" android:color="@color/signal_colorOnSecondaryContainer"/>
|
||||
</selector>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/signal_colorNeutralVariantInverse" android:state_enabled="true"/>
|
||||
<item android:alpha="@dimen/material_emphasis_disabled" android:color="@color/signal_colorNeutralVariantInverse"/>
|
||||
</selector>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/signal_colorSurface1" android:state_enabled="true"/>
|
||||
<item android:alpha="@dimen/material_emphasis_disabled_background" android:color="@color/signal_colorOnSurfaceVariant"/>
|
||||
</selector>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/signal_colorTransparent4" android:state_enabled="true"/>
|
||||
<item android:alpha="@dimen/material_emphasis_disabled_background" android:color="@color/signal_colorOnSecondaryContainer"/>
|
||||
</selector>
|
Some files were not shown because too many files have changed in this diff Show More
Ładowanie…
Reference in New Issue