mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-22 18:55:12 +00:00
Improve wallpaper settings screen, conversation rendering.
Co-authored-by: Greyson Parrelli <greyson@signal.org>
This commit is contained in:
committed by
Greyson Parrelli
parent
6bcb0de43d
commit
b5712f4bd1
@@ -36,7 +36,8 @@ public interface BindableConversationItem extends Unbindable {
|
||||
@NonNull Set<ConversationMessage> batchSelected,
|
||||
@NonNull Recipient recipients,
|
||||
@Nullable String searchQuery,
|
||||
boolean pulseMention);
|
||||
boolean pulseMention,
|
||||
boolean hasWallpaper);
|
||||
|
||||
ConversationMessage getConversationMessage();
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -130,6 +131,20 @@ public class ConversationItemFooter extends LinearLayout {
|
||||
presentDeliveryStatus(messageRecord);
|
||||
}
|
||||
|
||||
public void enableBubbleBackground(@DrawableRes int drawableRes, @Nullable Integer tint) {
|
||||
setBackgroundResource(drawableRes);
|
||||
|
||||
if (tint != null) {
|
||||
getBackground().setColorFilter(tint, PorterDuff.Mode.MULTIPLY);
|
||||
} else {
|
||||
getBackground().clearColorFilter();
|
||||
}
|
||||
}
|
||||
|
||||
public void disableBubbleBackground() {
|
||||
setBackground(null);
|
||||
}
|
||||
|
||||
private void presentDate(@NonNull MessageRecord messageRecord, @NonNull Locale locale) {
|
||||
dateView.forceLayout();
|
||||
if (messageRecord.isFailed()) {
|
||||
|
||||
@@ -61,6 +61,7 @@ import android.view.WindowManager;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
@@ -258,6 +259,7 @@ import org.thoughtcrime.securesms.util.DynamicDarkToolbarTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.FullscreenHelper;
|
||||
import org.thoughtcrime.securesms.util.IdentityUtil;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.MessageUtil;
|
||||
@@ -267,6 +269,7 @@ import org.thoughtcrime.securesms.util.SmsUtil;
|
||||
import org.thoughtcrime.securesms.util.SpanUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences.MediaKeyboardMode;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.WindowUtil;
|
||||
@@ -275,6 +278,8 @@ import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SettableFuture;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.views.Stub;
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaperDimLevelUtil;
|
||||
import org.whispersystems.libsignal.InvalidMessageException;
|
||||
import org.whispersystems.libsignal.util.Pair;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
@@ -375,6 +380,8 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
||||
private Stub<View> mentionsSuggestions;
|
||||
private MaterialButton joinGroupCallButton;
|
||||
private boolean callingTooltipShown;
|
||||
private ImageView wallpaper;
|
||||
private View wallpaperDim;
|
||||
|
||||
private LinkPreviewViewModel linkPreviewViewModel;
|
||||
private ConversationSearchViewModel searchViewModel;
|
||||
@@ -414,6 +421,8 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
||||
return;
|
||||
}
|
||||
|
||||
new FullscreenHelper(this).showSystemUI();
|
||||
|
||||
ConversationIntents.Args args = ConversationIntents.Args.from(getIntent());
|
||||
|
||||
reportShortcutLaunch(args.getRecipientId());
|
||||
@@ -426,6 +435,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
||||
initializeReceivers();
|
||||
initializeActionBar();
|
||||
initializeViews();
|
||||
updateWallpaper(args.getWallpaper());
|
||||
initializeResources(args);
|
||||
initializeLinkPreviewObserver();
|
||||
initializeSearchObserver();
|
||||
@@ -1910,6 +1920,8 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
||||
messageRequestBottomView = findViewById(R.id.conversation_activity_message_request_bottom_bar);
|
||||
reactionOverlay = findViewById(R.id.conversation_reaction_scrubber);
|
||||
mentionsSuggestions = ViewUtil.findStubById(this, R.id.conversation_mention_suggestions_stub);
|
||||
wallpaper = findViewById(R.id.conversation_wallpaper);
|
||||
wallpaperDim = findViewById(R.id.conversation_wallpaper_dim);
|
||||
|
||||
ImageButton quickCameraToggle = findViewById(R.id.quick_camera_toggle);
|
||||
ImageButton inlineAttachmentButton = findViewById(R.id.inline_attachment_button);
|
||||
@@ -1976,6 +1988,16 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
||||
joinGroupCallButton.setOnClickListener(v -> handleVideo(getRecipient()));
|
||||
}
|
||||
|
||||
private void updateWallpaper(@Nullable ChatWallpaper chatWallpaper) {
|
||||
if (chatWallpaper != null) {
|
||||
chatWallpaper.loadInto(wallpaper);
|
||||
ChatWallpaperDimLevelUtil.applyDimLevelForNightMode(wallpaperDim, chatWallpaper);
|
||||
} else {
|
||||
wallpaper.setImageDrawable(null);
|
||||
wallpaperDim.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
protected void initializeActionBar() {
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
@@ -2268,6 +2290,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
||||
updateReminders();
|
||||
updateDefaultSubscriptionId(recipient.getDefaultSubscriptionId());
|
||||
initializeSecurity(isSecureText, isDefaultSms);
|
||||
updateWallpaper(recipient.getWallpaper());
|
||||
|
||||
if (searchViewItem == null || !searchViewItem.isActionViewExpanded()) {
|
||||
invalidateOptionsMenu();
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.AnyThread;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.MainThread;
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -241,7 +242,8 @@ public class ConversationAdapter
|
||||
selected,
|
||||
recipient,
|
||||
searchQuery,
|
||||
conversationMessage == recordToPulse);
|
||||
conversationMessage == recordToPulse,
|
||||
recipient.hasWallpaper());
|
||||
|
||||
if (conversationMessage == recordToPulse) {
|
||||
recordToPulse = null;
|
||||
@@ -296,6 +298,12 @@ public class ConversationAdapter
|
||||
public void onBindHeaderViewHolder(StickyHeaderViewHolder viewHolder, int position) {
|
||||
ConversationMessage conversationMessage = Objects.requireNonNull(getItem(position));
|
||||
viewHolder.setText(DateUtils.getRelativeDate(viewHolder.itemView.getContext(), locale, conversationMessage.getMessageRecord().getDateReceived()));
|
||||
|
||||
if (recipient.hasWallpaper()) {
|
||||
viewHolder.setBackgroundRes(R.drawable.wallpaper_bubble_background_8);
|
||||
} else {
|
||||
viewHolder.clearBackground();
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable ConversationMessage getItem(int position) {
|
||||
@@ -325,6 +333,12 @@ public class ConversationAdapter
|
||||
|
||||
void onBindLastSeenViewHolder(StickyHeaderViewHolder viewHolder, int position) {
|
||||
viewHolder.setText(viewHolder.itemView.getContext().getResources().getQuantityString(R.plurals.ConversationAdapter_n_unread_messages, (position + 1), (position + 1)));
|
||||
|
||||
if (recipient.hasWallpaper()) {
|
||||
viewHolder.setBackgroundRes(R.drawable.wallpaper_bubble_background_8);
|
||||
} else {
|
||||
viewHolder.clearBackground();
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasNoConversationMessages() {
|
||||
@@ -563,6 +577,14 @@ public class ConversationAdapter
|
||||
public void setText(CharSequence text) {
|
||||
textView.setText(text);
|
||||
}
|
||||
|
||||
public void setBackgroundRes(@DrawableRes int resId) {
|
||||
textView.setBackgroundResource(resId);
|
||||
}
|
||||
|
||||
public void clearBackground() {
|
||||
textView.setBackground(null);
|
||||
}
|
||||
}
|
||||
|
||||
private static class HeaderFooterViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
@@ -62,6 +62,14 @@ public class ConversationBannerView extends ConstraintLayout {
|
||||
contactDescription.setText(description);
|
||||
}
|
||||
|
||||
public void showBackgroundBubble(boolean enabled) {
|
||||
if (enabled) {
|
||||
setBackgroundResource(R.drawable.wallpaper_bubble_background_12);
|
||||
} else {
|
||||
setBackground(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void hideSubtitle() {
|
||||
contactSubtitle.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@@ -422,6 +422,7 @@ public class ConversationFragment extends LoggingFragment {
|
||||
|
||||
if (recipient != null) {
|
||||
conversationBanner.setAvatar(GlideApp.with(context), recipient);
|
||||
conversationBanner.showBackgroundBubble(recipient.hasWallpaper());
|
||||
|
||||
String title = isSelf ? context.getString(R.string.note_to_self) : recipient.getDisplayNameOrUsername(context);
|
||||
conversationBanner.setTitle(title);
|
||||
|
||||
@@ -9,8 +9,10 @@ import androidx.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.mediasend.Media;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator;
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -147,6 +149,11 @@ public class ConversationIntents {
|
||||
public boolean isFirstTimeInSelfCreatedGroup() {
|
||||
return firstTimeInSelfCreatedGroup;
|
||||
}
|
||||
|
||||
public @Nullable ChatWallpaper getWallpaper() {
|
||||
// TODO [greyson][wallpaper] Is it worth it to do this beforehand?
|
||||
return Recipient.resolved(recipientId).getWallpaper();
|
||||
}
|
||||
}
|
||||
|
||||
public final static class Builder {
|
||||
|
||||
@@ -155,7 +155,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
private boolean groupThread;
|
||||
private LiveRecipient recipient;
|
||||
private GlideRequests glideRequests;
|
||||
private ValueAnimator pulseOutlinerAlphaAnimator;
|
||||
private ValueAnimator pulseOutlinerAlphaAnimator;
|
||||
|
||||
protected ConversationItemBodyBubble bodyBubble;
|
||||
protected View reply;
|
||||
@@ -165,7 +165,6 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
private ConversationItemFooter footer;
|
||||
private ConversationItemFooter stickerFooter;
|
||||
@Nullable private TextView groupSender;
|
||||
@Nullable private TextView groupSenderProfileName;
|
||||
@Nullable private View groupSenderHolder;
|
||||
private AvatarImageView contactPhoto;
|
||||
private AlertView alertView;
|
||||
@@ -223,7 +222,6 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
this.footer = findViewById(R.id.conversation_item_footer);
|
||||
this.stickerFooter = findViewById(R.id.conversation_item_sticker_footer);
|
||||
this.groupSender = findViewById(R.id.group_message_sender);
|
||||
this.groupSenderProfileName = findViewById(R.id.group_message_sender_profile);
|
||||
this.alertView = findViewById(R.id.indicators_parent);
|
||||
this.contactPhoto = findViewById(R.id.contact_photo);
|
||||
this.contactPhotoHolder = findViewById(R.id.contact_photo_container);
|
||||
@@ -256,7 +254,8 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
@NonNull Set<ConversationMessage> batchSelected,
|
||||
@NonNull Recipient conversationRecipient,
|
||||
@Nullable String searchQuery,
|
||||
boolean pulse)
|
||||
boolean pulse,
|
||||
boolean hasWallpaper)
|
||||
{
|
||||
if (this.recipient != null) this.recipient.removeForeverObserver(this);
|
||||
if (this.conversationRecipient != null) this.conversationRecipient.removeForeverObserver(this);
|
||||
@@ -279,17 +278,17 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
setMessageShape(messageRecord, previousMessageRecord, nextMessageRecord, groupThread);
|
||||
setMediaAttributes(messageRecord, previousMessageRecord, nextMessageRecord, conversationRecipient, groupThread);
|
||||
setBodyText(messageRecord, searchQuery);
|
||||
setBubbleState(messageRecord);
|
||||
setBubbleState(messageRecord, hasWallpaper);
|
||||
setInteractionState(conversationMessage, pulse);
|
||||
setStatusIcons(messageRecord);
|
||||
setContactPhoto(recipient.get());
|
||||
setGroupMessageStatus(messageRecord, recipient.get());
|
||||
setGroupAuthorColor(messageRecord);
|
||||
setAuthor(messageRecord, previousMessageRecord, nextMessageRecord, groupThread);
|
||||
setGroupAuthorColor(messageRecord, hasWallpaper);
|
||||
setAuthor(messageRecord, previousMessageRecord, nextMessageRecord, groupThread, hasWallpaper);
|
||||
setQuote(messageRecord, previousMessageRecord, nextMessageRecord, groupThread);
|
||||
setMessageSpacing(context, messageRecord, previousMessageRecord, nextMessageRecord, groupThread);
|
||||
setReactions(messageRecord);
|
||||
setFooter(messageRecord, nextMessageRecord, locale, groupThread);
|
||||
setFooter(messageRecord, nextMessageRecord, locale, groupThread, hasWallpaper);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -344,12 +343,14 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
}
|
||||
}
|
||||
|
||||
ConversationItemFooter activeFooter = getActiveFooter(messageRecord);
|
||||
int availableWidth = getAvailableMessageBubbleWidth(footer);
|
||||
if (!hasNoBubble(messageRecord)) {
|
||||
ConversationItemFooter activeFooter = getActiveFooter(messageRecord);
|
||||
int availableWidth = getAvailableMessageBubbleWidth(footer);
|
||||
|
||||
if (activeFooter.getVisibility() != GONE && activeFooter.getMeasuredWidth() != availableWidth) {
|
||||
activeFooter.getLayoutParams().width = availableWidth;
|
||||
needsMeasure = true;
|
||||
if (activeFooter.getVisibility() != GONE && activeFooter.getMeasuredWidth() != availableWidth) {
|
||||
activeFooter.getLayoutParams().width = availableWidth;
|
||||
needsMeasure = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needsMeasure) {
|
||||
@@ -366,7 +367,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
|
||||
@Override
|
||||
public void onRecipientChanged(@NonNull Recipient modified) {
|
||||
setBubbleState(messageRecord);
|
||||
setBubbleState(messageRecord, modified.hasWallpaper());
|
||||
if (recipient.getId().equals(modified.getId())) {
|
||||
setContactPhoto(modified);
|
||||
setGroupMessageStatus(messageRecord, modified);
|
||||
@@ -409,16 +410,20 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
|
||||
/// MessageRecord Attribute Parsers
|
||||
|
||||
private void setBubbleState(MessageRecord messageRecord) {
|
||||
private void setBubbleState(MessageRecord messageRecord, boolean hasWallpaper) {
|
||||
if (messageRecord.isOutgoing() && !messageRecord.isRemoteDelete()) {
|
||||
bodyBubble.getBackground().setColorFilter(defaultBubbleColor, PorterDuff.Mode.MULTIPLY);
|
||||
footer.setTextColor(ContextCompat.getColor(context, R.color.signal_text_secondary));
|
||||
footer.setIconColor(ContextCompat.getColor(context, R.color.signal_icon_tint_secondary));
|
||||
footer.setOnlyShowSendingStatus(false, messageRecord);
|
||||
} else if (messageRecord.isRemoteDelete() || (isViewOnceMessage(messageRecord) && ViewOnceUtil.isViewed((MmsMessageRecord) messageRecord))) {
|
||||
bodyBubble.getBackground().setColorFilter(ContextCompat.getColor(context, R.color.signal_background_primary), PorterDuff.Mode.MULTIPLY);
|
||||
if (hasWallpaper) {
|
||||
bodyBubble.getBackground().setColorFilter(ContextCompat.getColor(context, R.color.wallpaper_bubble_color), PorterDuff.Mode.SRC_IN);
|
||||
} else {
|
||||
bodyBubble.getBackground().setColorFilter(ContextCompat.getColor(context, R.color.signal_background_primary), PorterDuff.Mode.MULTIPLY);
|
||||
footer.setIconColor(ContextCompat.getColor(context, R.color.signal_icon_tint_secondary));
|
||||
}
|
||||
footer.setTextColor(ContextCompat.getColor(context, R.color.signal_text_secondary));
|
||||
footer.setIconColor(ContextCompat.getColor(context, R.color.signal_icon_tint_secondary));
|
||||
footer.setOnlyShowSendingStatus(messageRecord.isRemoteDelete(), messageRecord);
|
||||
} else {
|
||||
bodyBubble.getBackground().setColorFilter(messageRecord.getRecipient().getColor().toConversationColor(context), PorterDuff.Mode.MULTIPLY);
|
||||
@@ -433,7 +438,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
pulseOutliner.setStrokeWidth(ViewUtil.dpToPx(4));
|
||||
|
||||
outliners.clear();
|
||||
if (shouldDrawBodyBubbleOutline(messageRecord)) {
|
||||
if (shouldDrawBodyBubbleOutline(messageRecord, hasWallpaper)) {
|
||||
outliners.add(outliner);
|
||||
}
|
||||
outliners.add(pulseOutliner);
|
||||
@@ -515,9 +520,13 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
pulseOutliner.setAlpha(0);
|
||||
}
|
||||
|
||||
private boolean shouldDrawBodyBubbleOutline(MessageRecord messageRecord) {
|
||||
boolean isIncomingViewedOnce = !messageRecord.isOutgoing() && isViewOnceMessage(messageRecord) && ViewOnceUtil.isViewed((MmsMessageRecord) messageRecord);
|
||||
return isIncomingViewedOnce || messageRecord.isRemoteDelete();
|
||||
private boolean shouldDrawBodyBubbleOutline(MessageRecord messageRecord, boolean hasWallpaper) {
|
||||
if (hasWallpaper) {
|
||||
return false;
|
||||
} else {
|
||||
boolean isIncomingViewedOnce = !messageRecord.isOutgoing() && isViewOnceMessage(messageRecord) && ViewOnceUtil.isViewed((MmsMessageRecord) messageRecord);
|
||||
return isIncomingViewedOnce || messageRecord.isRemoteDelete();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCaptionlessMms(MessageRecord messageRecord) {
|
||||
@@ -543,6 +552,10 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
((MmsMessageRecord)messageRecord).getSlideDeck().getThumbnailSlide().isBorderless();
|
||||
}
|
||||
|
||||
private boolean hasNoBubble(MessageRecord messageRecord) {
|
||||
return hasSticker(messageRecord) || isBorderless(messageRecord);
|
||||
}
|
||||
|
||||
private boolean hasOnlyThumbnail(MessageRecord messageRecord) {
|
||||
return hasThumbnail(messageRecord) &&
|
||||
!hasAudio(messageRecord) &&
|
||||
@@ -1074,7 +1087,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
});
|
||||
}
|
||||
|
||||
private void setFooter(@NonNull MessageRecord current, @NonNull Optional<MessageRecord> next, @NonNull Locale locale, boolean isGroupThread) {
|
||||
private void setFooter(@NonNull MessageRecord current, @NonNull Optional<MessageRecord> next, @NonNull Locale locale, boolean isGroupThread, boolean hasWallpaper) {
|
||||
ViewUtil.updateLayoutParams(footer, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
||||
|
||||
footer.setVisibility(GONE);
|
||||
@@ -1090,11 +1103,27 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
ConversationItemFooter activeFooter = getActiveFooter(current);
|
||||
activeFooter.setVisibility(VISIBLE);
|
||||
activeFooter.setMessageRecord(current, locale);
|
||||
|
||||
if (hasWallpaper && hasNoBubble((messageRecord))) {
|
||||
if (messageRecord.isOutgoing()) {
|
||||
activeFooter.enableBubbleBackground(R.drawable.wallpaper_bubble_background_tintable_11, defaultBubbleColor);
|
||||
} else {
|
||||
activeFooter.enableBubbleBackground(R.drawable.wallpaper_bubble_background_tintable_11, messageRecord.getRecipient().getColor().toConversationColor(context));
|
||||
activeFooter.setTextColor(ContextCompat.getColor(context, R.color.conversation_item_received_text_secondary_color));
|
||||
activeFooter.setIconColor(ContextCompat.getColor(context, R.color.conversation_item_received_text_secondary_color));
|
||||
}
|
||||
} else if (hasNoBubble(messageRecord)){
|
||||
activeFooter.disableBubbleBackground();
|
||||
activeFooter.setTextColor(ContextCompat.getColor(context, R.color.signal_text_secondary));
|
||||
activeFooter.setIconColor(ContextCompat.getColor(context, R.color.signal_icon_tint_secondary));
|
||||
} else {
|
||||
activeFooter.disableBubbleBackground();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ConversationItemFooter getActiveFooter(@NonNull MessageRecord messageRecord) {
|
||||
if (hasSticker(messageRecord) || isBorderless(messageRecord)) {
|
||||
if (hasNoBubble(messageRecord)) {
|
||||
return stickerFooter;
|
||||
} else if (hasSharedContact(messageRecord) && TextUtils.isEmpty(messageRecord.getDisplayBody(getContext()))) {
|
||||
return sharedContactStub.get().getFooter();
|
||||
@@ -1118,30 +1147,27 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private void setGroupMessageStatus(MessageRecord messageRecord, Recipient recipient) {
|
||||
if (groupThread && !messageRecord.isOutgoing() && groupSender != null && groupSenderProfileName != null) {
|
||||
if (groupThread && !messageRecord.isOutgoing() && groupSender != null) {
|
||||
groupSender.setText(recipient.getDisplayName(getContext()));
|
||||
groupSenderProfileName.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void setGroupAuthorColor(@NonNull MessageRecord messageRecord) {
|
||||
if (groupSender != null && groupSenderProfileName != null) {
|
||||
private void setGroupAuthorColor(@NonNull MessageRecord messageRecord, boolean hasWallpaper) {
|
||||
if (groupSender != null) {
|
||||
int stickerAuthorColor = ContextCompat.getColor(context, R.color.signal_text_primary);
|
||||
if (shouldDrawBodyBubbleOutline(messageRecord)) {
|
||||
|
||||
if (shouldDrawBodyBubbleOutline(messageRecord, hasWallpaper)) {
|
||||
groupSender.setTextColor(stickerAuthorColor);
|
||||
groupSenderProfileName.setTextColor(stickerAuthorColor);
|
||||
} else if (hasSticker(messageRecord) || isBorderless(messageRecord)) {
|
||||
} else if (!hasWallpaper && hasNoBubble(messageRecord)) {
|
||||
groupSender.setTextColor(stickerAuthorColor);
|
||||
groupSenderProfileName.setTextColor(stickerAuthorColor);
|
||||
} else {
|
||||
groupSender.setTextColor(ContextCompat.getColor(context, R.color.conversation_item_received_text_primary_color));
|
||||
groupSenderProfileName.setTextColor(ContextCompat.getColor(context, R.color.conversation_item_received_text_primary_color));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private void setAuthor(@NonNull MessageRecord current, @NonNull Optional<MessageRecord> previous, @NonNull Optional<MessageRecord> next, boolean isGroupThread) {
|
||||
private void setAuthor(@NonNull MessageRecord current, @NonNull Optional<MessageRecord> previous, @NonNull Optional<MessageRecord> next, boolean isGroupThread, boolean hasWallpaper) {
|
||||
if (isGroupThread && !current.isOutgoing()) {
|
||||
contactPhotoHolder.setVisibility(VISIBLE);
|
||||
|
||||
@@ -1149,6 +1175,13 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
!DateUtils.isSameDay(previous.get().getTimestamp(), current.getTimestamp()))
|
||||
{
|
||||
groupSenderHolder.setVisibility(VISIBLE);
|
||||
|
||||
if (hasWallpaper && hasNoBubble(current)) {
|
||||
groupSenderHolder.setBackgroundResource(R.drawable.wallpaper_bubble_background_tintable_11);
|
||||
groupSenderHolder.getBackground().setColorFilter(messageRecord.getRecipient().getColor().toConversationColor(context), PorterDuff.Mode.MULTIPLY);
|
||||
} else {
|
||||
groupSenderHolder.setBackground(null);
|
||||
}
|
||||
} else {
|
||||
groupSenderHolder.setVisibility(GONE);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -41,7 +41,7 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public final class ConversationUpdateItem extends LinearLayout
|
||||
public final class ConversationUpdateItem extends FrameLayout
|
||||
implements BindableConversationItem
|
||||
{
|
||||
private static final String TAG = ConversationUpdateItem.class.getSimpleName();
|
||||
@@ -50,6 +50,7 @@ public final class ConversationUpdateItem extends LinearLayout
|
||||
|
||||
private TextView body;
|
||||
private TextView actionButton;
|
||||
private View background;
|
||||
private ConversationMessage conversationMessage;
|
||||
private Recipient conversationRecipient;
|
||||
private Optional<MessageRecord> nextMessageRecord;
|
||||
@@ -76,6 +77,7 @@ public final class ConversationUpdateItem extends LinearLayout
|
||||
super.onFinishInflate();
|
||||
this.body = findViewById(R.id.conversation_update_body);
|
||||
this.actionButton = findViewById(R.id.conversation_update_action);
|
||||
this.background = findViewById(R.id.conversation_update_background);
|
||||
|
||||
this.setOnClickListener(new InternalClickListener(null));
|
||||
}
|
||||
@@ -90,11 +92,12 @@ public final class ConversationUpdateItem extends LinearLayout
|
||||
@NonNull Set<ConversationMessage> batchSelected,
|
||||
@NonNull Recipient conversationRecipient,
|
||||
@Nullable String searchQuery,
|
||||
boolean pulseMention)
|
||||
boolean pulseMention,
|
||||
boolean hasWallpaper)
|
||||
{
|
||||
this.batchSelected = batchSelected;
|
||||
|
||||
bind(lifecycleOwner, conversationMessage, nextMessageRecord, conversationRecipient);
|
||||
bind(lifecycleOwner, conversationMessage, nextMessageRecord, conversationRecipient, hasWallpaper);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -110,7 +113,8 @@ public final class ConversationUpdateItem extends LinearLayout
|
||||
private void bind(@NonNull LifecycleOwner lifecycleOwner,
|
||||
@NonNull ConversationMessage conversationMessage,
|
||||
@NonNull Optional<MessageRecord> nextMessageRecord,
|
||||
@NonNull Recipient conversationRecipient)
|
||||
@NonNull Recipient conversationRecipient,
|
||||
boolean hasWallpaper)
|
||||
{
|
||||
this.conversationMessage = conversationMessage;
|
||||
this.messageRecord = conversationMessage.getMessageRecord();
|
||||
@@ -125,6 +129,12 @@ public final class ConversationUpdateItem extends LinearLayout
|
||||
groupObserver.observe(lifecycleOwner, null);
|
||||
}
|
||||
|
||||
if (hasWallpaper) {
|
||||
background.setBackgroundResource(R.drawable.wallpaper_bubble_background_12);
|
||||
} else {
|
||||
background.setBackground(null);
|
||||
}
|
||||
|
||||
UpdateDescription updateDescription = Objects.requireNonNull(messageRecord.getUpdateDisplayBody(getContext()));
|
||||
LiveData<Spannable> liveUpdateMessage = LiveUpdateMessage.fromMessageDescription(getContext(), updateDescription, ContextCompat.getColor(getContext(), R.color.conversation_item_update_text_color));
|
||||
LiveData<Spannable> spannableMessage = loading(liveUpdateMessage);
|
||||
|
||||
@@ -359,7 +359,7 @@ public class RecipientDatabase extends Database {
|
||||
LAST_GV1_MIGRATE_REMINDER + " INTEGER DEFAULT 0, " +
|
||||
LAST_SESSION_RESET + " BLOB DEFAULT NULL, " +
|
||||
WALLPAPER + " BLOB DEFAULT NULL, " +
|
||||
WALLPAPER_URI + " TEXT DEFAULT NULL);";
|
||||
WALLPAPER_URI + " TEXT DEFAULT NULL);";
|
||||
|
||||
private static final String INSIGHTS_INVITEE_LIST = "SELECT " + TABLE_NAME + "." + ID +
|
||||
" FROM " + TABLE_NAME +
|
||||
@@ -1799,14 +1799,60 @@ public class RecipientDatabase extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
public void setWallpaper(@NonNull RecipientId id, @NonNull ChatWallpaper chatWallpaper) {
|
||||
Wallpaper wallpaper = chatWallpaper.serialize();
|
||||
Uri existingWallpaperUri = getWallpaperUri(id);
|
||||
public void resetAllWallpaper() {
|
||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||
String[] selection = SqlUtil.buildArgs(ID, WALLPAPER_URI);
|
||||
String where = WALLPAPER + " IS NOT NULL";
|
||||
List<Pair<RecipientId, String>> idWithWallpaper = new LinkedList<>();
|
||||
|
||||
database.beginTransaction();
|
||||
|
||||
try {
|
||||
try (Cursor cursor = database.query(TABLE_NAME, selection, where, null, null, null, null)) {
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
idWithWallpaper.add(new Pair<>(RecipientId.from(CursorUtil.requireInt(cursor, ID)),
|
||||
CursorUtil.getString(cursor, WALLPAPER_URI).orNull()));
|
||||
}
|
||||
}
|
||||
|
||||
if (idWithWallpaper.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues(2);
|
||||
values.put(WALLPAPER_URI, (String) null);
|
||||
values.put(WALLPAPER, (byte[]) null);
|
||||
|
||||
int rowsUpdated = database.update(TABLE_NAME, values, where, null);
|
||||
if (rowsUpdated == idWithWallpaper.size()) {
|
||||
for (Pair<RecipientId, String> pair : idWithWallpaper) {
|
||||
Recipient.live(pair.first()).refresh();
|
||||
if (pair.second() != null) {
|
||||
WallpaperStorage.onWallpaperDeselected(context, Uri.parse(pair.second()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new AssertionError("expected " + idWithWallpaper.size() + " but got " + rowsUpdated);
|
||||
}
|
||||
|
||||
} finally {
|
||||
database.setTransactionSuccessful();
|
||||
database.endTransaction();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setWallpaper(@NonNull RecipientId id, @Nullable ChatWallpaper chatWallpaper) {
|
||||
setWallpaper(id, chatWallpaper != null ? chatWallpaper.serialize() : null);
|
||||
}
|
||||
|
||||
private void setWallpaper(@NonNull RecipientId id, @Nullable Wallpaper wallpaper) {
|
||||
Uri existingWallpaperUri = getWallpaperUri(id);
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(WALLPAPER, wallpaper.toByteArray());
|
||||
values.put(WALLPAPER, wallpaper != null ? wallpaper.toByteArray() : null);
|
||||
|
||||
if (wallpaper.hasFile()) {
|
||||
if (wallpaper != null && wallpaper.hasFile()) {
|
||||
values.put(WALLPAPER_URI, wallpaper.getFile().getUri());
|
||||
} else {
|
||||
values.putNull(WALLPAPER_URI);
|
||||
@@ -1821,15 +1867,33 @@ public class RecipientDatabase extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable Uri getWallpaperUri(@NonNull RecipientId id) {
|
||||
public void setDimWallpaperInDarkTheme(@NonNull RecipientId id, boolean enabled) {
|
||||
Wallpaper wallpaper = getWallpaper(id);
|
||||
|
||||
if (wallpaper == null) {
|
||||
throw new IllegalStateException("No wallpaper set for " + id);
|
||||
}
|
||||
|
||||
Wallpaper updated = wallpaper.toBuilder()
|
||||
.setDimLevelInDarkTheme(enabled ? ChatWallpaper.FIXED_DIM_LEVEL_FOR_DARK_THEME : 0)
|
||||
.build();
|
||||
|
||||
setWallpaper(id, updated);
|
||||
}
|
||||
|
||||
private @Nullable Wallpaper getWallpaper(@NonNull RecipientId id) {
|
||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||
|
||||
try (Cursor cursor = db.query(TABLE_NAME, new String[] {WALLPAPER_URI}, ID_WHERE, SqlUtil.buildArgs(id), null, null, null)) {
|
||||
try (Cursor cursor = db.query(TABLE_NAME, new String[] {WALLPAPER}, ID_WHERE, SqlUtil.buildArgs(id), null, null, null)) {
|
||||
if (cursor.moveToFirst()) {
|
||||
String raw = CursorUtil.requireString(cursor, WALLPAPER_URI);
|
||||
byte[] raw = CursorUtil.requireBlob(cursor, WALLPAPER);
|
||||
|
||||
if (raw != null) {
|
||||
return Uri.parse(raw);
|
||||
try {
|
||||
return Wallpaper.parseFrom(raw);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@@ -1839,12 +1903,22 @@ public class RecipientDatabase extends Database {
|
||||
return null;
|
||||
}
|
||||
|
||||
private @Nullable Uri getWallpaperUri(@NonNull RecipientId id) {
|
||||
Wallpaper wallpaper = getWallpaper(id);
|
||||
|
||||
if (wallpaper != null && wallpaper.hasFile()) {
|
||||
return Uri.parse(wallpaper.getFile().getUri());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getWallpaperUriUsageCount(@NonNull Uri uri) {
|
||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||
String query = WALLPAPER_URI + " = ?";
|
||||
String[] args = SqlUtil.buildArgs(uri);
|
||||
|
||||
try (Cursor cursor = db.query(TABLE_NAME, new String[] { "COUNT(*)"}, query, args, null, null, null)) {
|
||||
try (Cursor cursor = db.query(TABLE_NAME, new String[] { "COUNT(*)" }, query, args, null, null, null)) {
|
||||
if (cursor.moveToFirst()) {
|
||||
return cursor.getInt(0);
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.LifecycleCursorWrapper;
|
||||
import org.thoughtcrime.securesms.util.views.LearnMoreTextView;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaperActivity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -114,6 +115,7 @@ public class ManageGroupFragment extends LoggingFragment {
|
||||
private View toggleAllMembers;
|
||||
private View groupLinkRow;
|
||||
private TextView groupLinkButton;
|
||||
private View wallpaperButton;
|
||||
|
||||
private final Recipient.FallbackPhotoProvider fallbackPhotoProvider = new Recipient.FallbackPhotoProvider() {
|
||||
@Override
|
||||
@@ -175,6 +177,7 @@ public class ManageGroupFragment extends LoggingFragment {
|
||||
toggleAllMembers = view.findViewById(R.id.toggle_all_members);
|
||||
groupLinkRow = view.findViewById(R.id.group_link_row);
|
||||
groupLinkButton = view.findViewById(R.id.group_link_button);
|
||||
wallpaperButton = view.findViewById(R.id.chat_wallpaper);
|
||||
|
||||
return view;
|
||||
}
|
||||
@@ -240,6 +243,7 @@ public class ManageGroupFragment extends LoggingFragment {
|
||||
});
|
||||
customNotificationsRow.setOnClickListener(v -> CustomNotificationsDialogFragment.create(groupRecipient.getId())
|
||||
.show(requireFragmentManager(), DIALOG_TAG));
|
||||
wallpaperButton.setOnClickListener(v -> startActivity(ChatWallpaperActivity.createIntent(requireContext(), groupRecipient.getId())));
|
||||
});
|
||||
|
||||
if (groupId.isV2()) {
|
||||
|
||||
@@ -27,7 +27,6 @@ public final class WallpaperValues extends SignalStoreValues {
|
||||
|
||||
@Override
|
||||
void onFirstEverAppLaunch() {
|
||||
|
||||
}
|
||||
|
||||
public void setWallpaper(@NonNull Context context, @Nullable ChatWallpaper wallpaper) {
|
||||
@@ -44,7 +43,9 @@ public final class WallpaperValues extends SignalStoreValues {
|
||||
getStore().beginWrite().remove(KEY_WALLPAPER).apply();
|
||||
}
|
||||
|
||||
WallpaperStorage.onWallpaperDeselected(context, currentUri);
|
||||
if (currentUri != null) {
|
||||
WallpaperStorage.onWallpaperDeselected(context, currentUri);
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable ChatWallpaper getWallpaper() {
|
||||
@@ -57,7 +58,30 @@ public final class WallpaperValues extends SignalStoreValues {
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable Uri getCurrentWallpaperUri() {
|
||||
public boolean hasWallpaperSet() {
|
||||
return getStore().getBlob(KEY_WALLPAPER, null) != null;
|
||||
}
|
||||
|
||||
public void setDimInDarkTheme(boolean enabled) {
|
||||
Wallpaper currentWallpaper = getCurrentWallpaper();
|
||||
|
||||
if (currentWallpaper != null) {
|
||||
putBlob(KEY_WALLPAPER,
|
||||
currentWallpaper.toBuilder()
|
||||
.setDimLevelInDarkTheme(enabled ? 0.2f : 0)
|
||||
.build()
|
||||
.toByteArray());
|
||||
} else {
|
||||
throw new IllegalStateException("No wallpaper currently set!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the URI of the current wallpaper. Note that this will only return a value if the
|
||||
* wallpaper is both set *and* it's an image.
|
||||
*/
|
||||
public @Nullable Uri getWallpaperUri() {
|
||||
Wallpaper currentWallpaper = getCurrentWallpaper();
|
||||
|
||||
if (currentWallpaper != null && currentWallpaper.hasFile()) {
|
||||
|
||||
@@ -88,7 +88,7 @@ final class MessageHeaderViewHolder extends RecyclerView.ViewHolder {
|
||||
conversationItem = (ConversationItem) receivedStub.inflate();
|
||||
}
|
||||
}
|
||||
conversationItem.bind(lifecycleOwner, conversationMessage, Optional.absent(), Optional.absent(), glideRequests, Locale.getDefault(), new HashSet<>(), conversationMessage.getMessageRecord().getRecipient(), null, false);
|
||||
conversationItem.bind(lifecycleOwner, conversationMessage, Optional.absent(), Optional.absent(), glideRequests, Locale.getDefault(), new HashSet<>(), conversationMessage.getMessageRecord().getRecipient(), null, false, false);
|
||||
}
|
||||
|
||||
private void bindErrorState(MessageRecord messageRecord) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import androidx.preference.ListPreference;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.ActivityTransitionUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaperActivity;
|
||||
|
||||
@@ -24,7 +25,8 @@ public class AppearancePreferenceFragment extends ListSummaryPreferenceFragment
|
||||
this.findPreference(TextSecurePreferences.THEME_PREF).setOnPreferenceChangeListener(new ListSummaryListener());
|
||||
this.findPreference(TextSecurePreferences.LANGUAGE_PREF).setOnPreferenceChangeListener(new ListSummaryListener());
|
||||
this.findPreference(WALLPAPER_PREF).setOnPreferenceClickListener(preference -> {
|
||||
startActivity(ChatWallpaperActivity.getIntent(requireContext()));
|
||||
startActivity(ChatWallpaperActivity.createIntent(requireContext()));
|
||||
ActivityTransitionUtil.setSlideInTransition(requireActivity());
|
||||
return true;
|
||||
});
|
||||
initializeListSummary((ListPreference)findPreference(TextSecurePreferences.THEME_PREF));
|
||||
|
||||
@@ -848,7 +848,18 @@ public class Recipient {
|
||||
}
|
||||
|
||||
public @Nullable ChatWallpaper getWallpaper() {
|
||||
return wallpaper;
|
||||
if (wallpaper != null) {
|
||||
return wallpaper;
|
||||
} else {
|
||||
return SignalStore.wallpaper().getWallpaper();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A cheap way to check if wallpaper is set without doing any unnecessary proto parsing.
|
||||
*/
|
||||
public boolean hasWallpaper() {
|
||||
return wallpaper != null || SignalStore.wallpaper().hasWallpaperSet();
|
||||
}
|
||||
|
||||
public boolean isSystemContact() {
|
||||
|
||||
@@ -54,6 +54,7 @@ import org.thoughtcrime.securesms.util.DateUtils;
|
||||
import org.thoughtcrime.securesms.util.LifecycleCursorWrapper;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaperActivity;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
@@ -105,6 +106,7 @@ public class ManageRecipientFragment extends LoggingFragment {
|
||||
private View secureCallButton;
|
||||
private View insecureCallButton;
|
||||
private View secureVideoCallButton;
|
||||
private View chatWallpaperButton;
|
||||
|
||||
static ManageRecipientFragment newInstance(@NonNull RecipientId recipientId, boolean fromConversation) {
|
||||
ManageRecipientFragment fragment = new ManageRecipientFragment();
|
||||
@@ -161,6 +163,7 @@ public class ManageRecipientFragment extends LoggingFragment {
|
||||
secureCallButton = view.findViewById(R.id.recipient_voice_call);
|
||||
insecureCallButton = view.findViewById(R.id.recipient_insecure_voice_call);
|
||||
secureVideoCallButton = view.findViewById(R.id.recipient_video_call);
|
||||
chatWallpaperButton = view.findViewById(R.id.chat_wallpaper);
|
||||
|
||||
return view;
|
||||
}
|
||||
@@ -270,6 +273,7 @@ public class ManageRecipientFragment extends LoggingFragment {
|
||||
secureCallButton.setOnClickListener(v -> viewModel.onSecureCall(requireActivity()));
|
||||
insecureCallButton.setOnClickListener(v -> viewModel.onInsecureCall(requireActivity()));
|
||||
secureVideoCallButton.setOnClickListener(v -> viewModel.onSecureVideoCall(requireActivity()));
|
||||
chatWallpaperButton.setOnClickListener(v -> startActivity(ChatWallpaperActivity.createIntent(requireContext(), recipientId)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import androidx.activity.ComponentActivity;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
||||
public final class ActivityTransitionUtil {
|
||||
|
||||
private ActivityTransitionUtil() {}
|
||||
|
||||
/**
|
||||
* To be used with finish
|
||||
*/
|
||||
public static void setSlideOutTransition(@NonNull ComponentActivity activity) {
|
||||
activity.overridePendingTransition(R.anim.slide_from_start, R.anim.slide_to_end);
|
||||
}
|
||||
|
||||
/**
|
||||
* To be used with startActivity
|
||||
*/
|
||||
public static void setSlideInTransition(@NonNull ComponentActivity activity) {
|
||||
activity.overridePendingTransition(R.anim.slide_from_end, R.anim.slide_to_start);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,20 +12,31 @@ import java.util.List;
|
||||
|
||||
public interface ChatWallpaper extends Parcelable {
|
||||
|
||||
List<ChatWallpaper> BUILTINS = Arrays.asList(GradientChatWallpaper.SOLID_1,
|
||||
GradientChatWallpaper.SOLID_2,
|
||||
GradientChatWallpaper.SOLID_3,
|
||||
GradientChatWallpaper.SOLID_4,
|
||||
GradientChatWallpaper.SOLID_5,
|
||||
GradientChatWallpaper.SOLID_6,
|
||||
GradientChatWallpaper.SOLID_7,
|
||||
GradientChatWallpaper.SOLID_8,
|
||||
GradientChatWallpaper.SOLID_9,
|
||||
GradientChatWallpaper.SOLID_10,
|
||||
GradientChatWallpaper.SOLID_11,
|
||||
GradientChatWallpaper.SOLID_12,
|
||||
float FIXED_DIM_LEVEL_FOR_DARK_THEME = 0.2f;
|
||||
|
||||
List<ChatWallpaper> BUILTINS = Arrays.asList(SingleColorChatWallpaper.SOLID_1,
|
||||
SingleColorChatWallpaper.SOLID_2,
|
||||
SingleColorChatWallpaper.SOLID_3,
|
||||
SingleColorChatWallpaper.SOLID_4,
|
||||
SingleColorChatWallpaper.SOLID_5,
|
||||
SingleColorChatWallpaper.SOLID_6,
|
||||
SingleColorChatWallpaper.SOLID_7,
|
||||
SingleColorChatWallpaper.SOLID_8,
|
||||
SingleColorChatWallpaper.SOLID_9,
|
||||
SingleColorChatWallpaper.SOLID_10,
|
||||
SingleColorChatWallpaper.SOLID_11,
|
||||
SingleColorChatWallpaper.SOLID_12,
|
||||
GradientChatWallpaper.GRADIENT_1,
|
||||
GradientChatWallpaper.GRADIENT_2);
|
||||
GradientChatWallpaper.GRADIENT_2,
|
||||
GradientChatWallpaper.GRADIENT_3,
|
||||
GradientChatWallpaper.GRADIENT_4,
|
||||
GradientChatWallpaper.GRADIENT_5,
|
||||
GradientChatWallpaper.GRADIENT_6,
|
||||
GradientChatWallpaper.GRADIENT_7,
|
||||
GradientChatWallpaper.GRADIENT_8,
|
||||
GradientChatWallpaper.GRADIENT_9);
|
||||
|
||||
float getDimLevelForDarkTheme();
|
||||
|
||||
void loadInto(@NonNull ImageView imageView);
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import androidx.navigation.Navigation;
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.ActivityTransitionUtil;
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
|
||||
@@ -23,11 +24,11 @@ public final class ChatWallpaperActivity extends PassphraseRequiredActivity {
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
|
||||
|
||||
public static @NonNull Intent getIntent(@NonNull Context context) {
|
||||
return getIntent(context, null);
|
||||
public static @NonNull Intent createIntent(@NonNull Context context) {
|
||||
return createIntent(context, null);
|
||||
}
|
||||
|
||||
public static @NonNull Intent getIntent(@NonNull Context context, @Nullable RecipientId recipientId) {
|
||||
public static @NonNull Intent createIntent(@NonNull Context context, @Nullable RecipientId recipientId) {
|
||||
Intent intent = new Intent(context, ChatWallpaperActivity.class);
|
||||
intent.putExtra(EXTRA_RECIPIENT_ID, recipientId);
|
||||
return intent;
|
||||
@@ -35,8 +36,7 @@ public final class ChatWallpaperActivity extends PassphraseRequiredActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState, boolean ready) {
|
||||
ChatWallpaperViewModel.Factory factory = new ChatWallpaperViewModel.Factory(getIntent(this).getParcelableExtra(EXTRA_RECIPIENT_ID));
|
||||
|
||||
ChatWallpaperViewModel.Factory factory = new ChatWallpaperViewModel.Factory(getIntent().getParcelableExtra(EXTRA_RECIPIENT_ID));
|
||||
ViewModelProviders.of(this, factory).get(ChatWallpaperViewModel.class);
|
||||
|
||||
dynamicTheme.onCreate(this);
|
||||
@@ -47,6 +47,7 @@ public final class ChatWallpaperActivity extends PassphraseRequiredActivity {
|
||||
toolbar.setNavigationOnClickListener(unused -> {
|
||||
if (!Navigation.findNavController(this, R.id.nav_host_fragment).popBackStack()) {
|
||||
finish();
|
||||
ActivityTransitionUtil.setSlideOutTransition(this);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -58,6 +59,12 @@ public final class ChatWallpaperActivity extends PassphraseRequiredActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
ActivityTransitionUtil.setSlideOutTransition(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.thoughtcrime.securesms.wallpaper;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
|
||||
public final class ChatWallpaperDimLevelUtil {
|
||||
|
||||
private ChatWallpaperDimLevelUtil() {
|
||||
}
|
||||
|
||||
public static void applyDimLevelForNightMode(@NonNull View dimmer, @NonNull ChatWallpaper chatWallpaper) {
|
||||
if (ThemeUtil.isDarkTheme(dimmer.getContext())) {
|
||||
dimmer.setAlpha(chatWallpaper.getDimLevelForDarkTheme());
|
||||
dimmer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
dimmer.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.wallpaper;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.Wallpaper;
|
||||
@@ -9,25 +10,37 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.Wallpaper;
|
||||
/**
|
||||
* Converts persisted models of wallpaper into usable {@link ChatWallpaper} instances.
|
||||
*/
|
||||
public class ChatWallpaperFactory {
|
||||
public final class ChatWallpaperFactory {
|
||||
|
||||
private ChatWallpaperFactory() {}
|
||||
|
||||
public static @NonNull ChatWallpaper create(@NonNull Wallpaper model) {
|
||||
if (model.hasSingleColor()) {
|
||||
return new GradientChatWallpaper(model.getSingleColor().getColor());
|
||||
return buildForSingleColor(model.getSingleColor(), model.getDimLevelInDarkTheme());
|
||||
} else if (model.hasLinearGradient()) {
|
||||
return buildForLinearGradinent(model.getLinearGradient());
|
||||
return buildForLinearGradinent(model.getLinearGradient(), model.getDimLevelInDarkTheme());
|
||||
} else if (model.hasFile()) {
|
||||
return buildForFile(model.getFile());
|
||||
return buildForFile(model.getFile(), model.getDimLevelInDarkTheme());
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
public static @NonNull ChatWallpaper create(@NonNull Uri uri) {
|
||||
return new UriChatWallpaper(uri);
|
||||
public static @NonNull ChatWallpaper updateWithDimming(@NonNull ChatWallpaper wallpaper, float dimLevelInDarkTheme) {
|
||||
Wallpaper model = wallpaper.serialize();
|
||||
|
||||
return create(model.toBuilder().setDimLevelInDarkTheme(dimLevelInDarkTheme).build());
|
||||
}
|
||||
|
||||
private static @NonNull ChatWallpaper buildForLinearGradinent(@NonNull Wallpaper.LinearGradient gradient) {
|
||||
public static @NonNull ChatWallpaper create(@NonNull Uri uri) {
|
||||
return new UriChatWallpaper(uri, 0f);
|
||||
}
|
||||
|
||||
private static @NonNull ChatWallpaper buildForSingleColor(@NonNull Wallpaper.SingleColor singleColor, float dimLevelInDarkTheme) {
|
||||
return new SingleColorChatWallpaper(singleColor.getColor(), dimLevelInDarkTheme);
|
||||
}
|
||||
|
||||
private static @NonNull ChatWallpaper buildForLinearGradinent(@NonNull Wallpaper.LinearGradient gradient, float dimLevelInDarkTheme) {
|
||||
int[] colors = new int[gradient.getColorsCount()];
|
||||
for (int i = 0; i < colors.length; i++) {
|
||||
colors[i] = gradient.getColors(i);
|
||||
@@ -38,11 +51,11 @@ public class ChatWallpaperFactory {
|
||||
positions[i] = gradient.getPositions(i);
|
||||
}
|
||||
|
||||
return new GradientChatWallpaper(gradient.getRotation(), colors, positions);
|
||||
return new GradientChatWallpaper(gradient.getRotation(), colors, positions, dimLevelInDarkTheme);
|
||||
}
|
||||
|
||||
private static @NonNull ChatWallpaper buildForFile(@NonNull Wallpaper.File file) {
|
||||
private static @NonNull ChatWallpaper buildForFile(@NonNull Wallpaper.File file, float dimLevelInDarkTheme) {
|
||||
Uri uri = Uri.parse(file.getUri());
|
||||
return new UriChatWallpaper(uri);
|
||||
return new UriChatWallpaper(uri, dimLevelInDarkTheme);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,14 @@ import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
|
||||
public class ChatWallpaperFragment extends Fragment {
|
||||
@Override
|
||||
@@ -26,18 +28,48 @@ public class ChatWallpaperFragment extends Fragment {
|
||||
ChatWallpaperViewModel viewModel = ViewModelProviders.of(requireActivity()).get(ChatWallpaperViewModel.class);
|
||||
ImageView chatWallpaperPreview = view.findViewById(R.id.chat_wallpaper_preview_background);
|
||||
View setWallpaper = view.findViewById(R.id.chat_wallpaper_set_wallpaper);
|
||||
|
||||
viewModel.setWallpaper(GradientChatWallpaper.GRADIENT_1);
|
||||
SwitchCompat dimInNightMode = view.findViewById(R.id.chat_wallpaper_dark_theme_dims_wallpaper);
|
||||
View chatWallpaperDim = view.findViewById(R.id.chat_wallpaper_dim);
|
||||
View clearWallpaper = view.findViewById(R.id.chat_wallpaper_clear_wallpaper);
|
||||
View resetAllWallpaper = view.findViewById(R.id.chat_wallpaper_reset_all_wallpapers);
|
||||
|
||||
viewModel.getCurrentWallpaper().observe(getViewLifecycleOwner(), wallpaper -> {
|
||||
if (wallpaper.isPresent()) {
|
||||
wallpaper.get().loadInto(chatWallpaperPreview);
|
||||
} else {
|
||||
chatWallpaperPreview.setImageDrawable(null);
|
||||
chatWallpaperPreview.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.signal_background_primary));
|
||||
}
|
||||
|
||||
dimInNightMode.setEnabled(wallpaper.isPresent());
|
||||
});
|
||||
|
||||
viewModel.getDimInDarkTheme().observe(getViewLifecycleOwner(), shouldDimInNightMode -> {
|
||||
if (shouldDimInNightMode != dimInNightMode.isChecked()) {
|
||||
dimInNightMode.setChecked(shouldDimInNightMode);
|
||||
}
|
||||
|
||||
chatWallpaperDim.setAlpha(ChatWallpaper.FIXED_DIM_LEVEL_FOR_DARK_THEME);
|
||||
chatWallpaperDim.setVisibility(shouldDimInNightMode && ThemeUtil.isDarkTheme(requireContext()) ? View.VISIBLE : View.GONE);
|
||||
});
|
||||
|
||||
setWallpaper.setOnClickListener(unused -> Navigation.findNavController(view)
|
||||
.navigate(R.id.action_chatWallpaperFragment_to_chatWallpaperSelectionFragment));
|
||||
|
||||
clearWallpaper.setOnClickListener(unused -> {
|
||||
viewModel.setWallpaper(null);
|
||||
viewModel.setDimInDarkTheme(false);
|
||||
viewModel.saveWallpaperSelection();
|
||||
});
|
||||
|
||||
resetAllWallpaper.setVisibility(viewModel.isGlobal() ? View.VISIBLE : View.GONE);
|
||||
|
||||
resetAllWallpaper.setOnClickListener(unused -> {
|
||||
viewModel.setWallpaper(null);
|
||||
viewModel.setDimInDarkTheme(false);
|
||||
viewModel.resetAllWallpaper();
|
||||
});
|
||||
|
||||
dimInNightMode.setOnCheckedChangeListener((buttonView, isChecked) -> viewModel.setDimInDarkTheme(isChecked));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,30 +8,33 @@ import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.ActivityTransitionUtil;
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.FullscreenHelper;
|
||||
import org.thoughtcrime.securesms.util.MappingModel;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class ChatWallpaperPreviewActivity extends PassphraseRequiredActivity {
|
||||
|
||||
private static final String EXTRA_CHAT_WALLPAPER = "extra.chat.wallpaper";
|
||||
private static final String EXTRA_RECIPIENT_ID = "extra.recipient.id";
|
||||
public static final String EXTRA_CHAT_WALLPAPER = "extra.chat.wallpaper";
|
||||
private static final String EXTRA_DIM_IN_DARK_MODE = "extra.dim.in.dark.mode";
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
|
||||
|
||||
public static @NonNull Intent create(@NonNull Context context, @NonNull ChatWallpaper selection, @Nullable RecipientId recipientId) {
|
||||
public static @NonNull Intent create(@NonNull Context context, @NonNull ChatWallpaper selection, boolean dimInDarkMode) {
|
||||
Intent intent = new Intent(context, ChatWallpaperPreviewActivity.class);
|
||||
|
||||
intent.putExtra(EXTRA_CHAT_WALLPAPER, selection);
|
||||
intent.putExtra(EXTRA_RECIPIENT_ID, recipientId);
|
||||
intent.putExtra(EXTRA_DIM_IN_DARK_MODE, dimInDarkMode);
|
||||
|
||||
return intent;
|
||||
}
|
||||
@@ -42,32 +45,43 @@ public class ChatWallpaperPreviewActivity extends PassphraseRequiredActivity {
|
||||
|
||||
setContentView(R.layout.chat_wallpaper_preview_activity);
|
||||
|
||||
ViewPager2 viewPager = findViewById(R.id.preview_pager);
|
||||
ChatWallpaperPreviewAdapter adapter = new ChatWallpaperPreviewAdapter();
|
||||
View submit = findViewById(R.id.preview_set_wallpaper);
|
||||
ChatWallpaperViewModel.Factory factory = new ChatWallpaperViewModel.Factory(getIntent().getParcelableExtra(EXTRA_RECIPIENT_ID));
|
||||
ChatWallpaperViewModel viewModel = ViewModelProviders.of(this, factory).get(ChatWallpaperViewModel.class);
|
||||
ChatWallpaper selected = getIntent().getParcelableExtra(EXTRA_CHAT_WALLPAPER);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
ViewPager2 viewPager = findViewById(R.id.preview_pager);
|
||||
ChatWallpaperPreviewAdapter adapter = new ChatWallpaperPreviewAdapter();
|
||||
View submit = findViewById(R.id.preview_set_wallpaper);
|
||||
ChatWallpaperRepository repository = new ChatWallpaperRepository();
|
||||
ChatWallpaper selected = getIntent().getParcelableExtra(EXTRA_CHAT_WALLPAPER);
|
||||
boolean dim = getIntent().getBooleanExtra(EXTRA_DIM_IN_DARK_MODE, false);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
|
||||
toolbar.setNavigationOnClickListener(unused -> finish());
|
||||
toolbar.setNavigationOnClickListener(unused -> {
|
||||
finish();
|
||||
ActivityTransitionUtil.setSlideOutTransition(this);
|
||||
});
|
||||
|
||||
viewPager.setAdapter(adapter);
|
||||
|
||||
adapter.submitList(Collections.singletonList(new ChatWallpaperSelectionMappingModel(selected)));
|
||||
viewModel.getWallpapers().observe(this, adapter::submitList);
|
||||
repository.getAllWallpaper(wallpapers -> adapter.submitList(Stream.of(wallpapers)
|
||||
.map(wallpaper -> ChatWallpaperFactory.updateWithDimming(wallpaper, dim ? 1f : 0f))
|
||||
.<MappingModel<?>>map(ChatWallpaperSelectionMappingModel::new)
|
||||
.toList()));
|
||||
|
||||
submit.setOnClickListener(unused -> {
|
||||
ChatWallpaperSelectionMappingModel model = (ChatWallpaperSelectionMappingModel) adapter.getCurrentList().get(viewPager.getCurrentItem());
|
||||
|
||||
viewModel.saveWallpaperSelection(model.getWallpaper());
|
||||
setResult(RESULT_OK);
|
||||
setResult(RESULT_OK, new Intent().putExtra(EXTRA_CHAT_WALLPAPER, model.getWallpaper()));
|
||||
finish();
|
||||
});
|
||||
|
||||
new FullscreenHelper(this).showSystemUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
ActivityTransitionUtil.setSlideOutTransition(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
@@ -1,14 +1,64 @@
|
||||
package org.thoughtcrime.securesms.wallpaper;
|
||||
|
||||
import androidx.annotation.MainThread;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.util.Consumer;
|
||||
|
||||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SerialExecutor;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
class ChatWallpaperRepository {
|
||||
|
||||
private static final Executor EXECUTOR = new SerialExecutor(SignalExecutors.BOUNDED);
|
||||
|
||||
@MainThread
|
||||
@Nullable ChatWallpaper getCurrentWallpaper(@Nullable RecipientId recipientId) {
|
||||
if (recipientId != null) {
|
||||
return Recipient.resolved(recipientId).getWallpaper();
|
||||
} else {
|
||||
return SignalStore.wallpaper().getWallpaper();
|
||||
}
|
||||
}
|
||||
|
||||
void getAllWallpaper(@NonNull Consumer<List<ChatWallpaper>> consumer) {
|
||||
consumer.accept(ChatWallpaper.BUILTINS);
|
||||
}
|
||||
|
||||
void saveWallpaper(@Nullable RecipientId recipientId, @Nullable ChatWallpaper chatWallpaper) {
|
||||
if (recipientId != null) {
|
||||
//noinspection CodeBlock2Expr
|
||||
EXECUTOR.execute(() -> {
|
||||
DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).setWallpaper(recipientId, chatWallpaper);
|
||||
});
|
||||
} else {
|
||||
SignalStore.wallpaper().setWallpaper(ApplicationDependencies.getApplication(), chatWallpaper);
|
||||
}
|
||||
}
|
||||
|
||||
void resetAllWallpaper() {
|
||||
SignalStore.wallpaper().setWallpaper(ApplicationDependencies.getApplication(), null);
|
||||
EXECUTOR.execute(() -> {
|
||||
DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).resetAllWallpaper();
|
||||
});
|
||||
}
|
||||
|
||||
void setDimInDarkTheme(@NonNull RecipientId recipientId, boolean dimInDarkTheme) {
|
||||
if (recipientId != null) {
|
||||
EXECUTOR.execute(() -> {
|
||||
DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).setDimWallpaperInDarkTheme(recipientId, dimInDarkTheme);
|
||||
});
|
||||
} else {
|
||||
SignalStore.wallpaper().setDimInDarkTheme(dimInDarkTheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.google.android.flexbox.FlexboxLayoutManager;
|
||||
import com.google.android.flexbox.JustifyContent;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.ActivityTransitionUtil;
|
||||
|
||||
public class ChatWallpaperSelectionFragment extends Fragment {
|
||||
|
||||
@@ -45,7 +46,8 @@ public class ChatWallpaperSelectionFragment extends Fragment {
|
||||
|
||||
@SuppressWarnings("CodeBlock2Expr")
|
||||
ChatWallpaperSelectionAdapter adapter = new ChatWallpaperSelectionAdapter(chatWallpaper -> {
|
||||
startActivityForResult(ChatWallpaperPreviewActivity.create(requireActivity(), chatWallpaper, viewModel.getRecipientId()), PREVIEW);
|
||||
startActivityForResult(ChatWallpaperPreviewActivity.create(requireActivity(), chatWallpaper, viewModel.getDimInDarkTheme().getValue()), PREVIEW);
|
||||
ActivityTransitionUtil.setSlideInTransition(requireActivity());
|
||||
});
|
||||
|
||||
flexboxLayoutManager.setJustifyContent(JustifyContent.SPACE_AROUND);
|
||||
@@ -63,9 +65,15 @@ public class ChatWallpaperSelectionFragment extends Fragment {
|
||||
if (uri == null || uri == Uri.EMPTY) {
|
||||
throw new AssertionError("Should never have an empty uri.");
|
||||
} else {
|
||||
startActivityForResult(ChatWallpaperPreviewActivity.create(requireActivity(), new UriChatWallpaper(uri), viewModel.getRecipientId()), PREVIEW);
|
||||
ChatWallpaper wallpaper = ChatWallpaperFactory.create(uri);
|
||||
viewModel.setWallpaper(wallpaper);
|
||||
viewModel.saveWallpaperSelection();
|
||||
Navigation.findNavController(requireView()).popBackStack();
|
||||
}
|
||||
} else if (requestCode == PREVIEW && resultCode == Activity.RESULT_OK) {
|
||||
} else if (requestCode == PREVIEW && resultCode == Activity.RESULT_OK && data != null) {
|
||||
ChatWallpaper chatWallpaper = data.getParcelableExtra(ChatWallpaperPreviewActivity.EXTRA_CHAT_WALLPAPER);
|
||||
viewModel.setWallpaper(chatWallpaper);
|
||||
viewModel.saveWallpaperSelection();
|
||||
Navigation.findNavController(requireView()).popBackStack();
|
||||
} else {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
@@ -11,15 +11,18 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.MappingAdapter;
|
||||
import org.thoughtcrime.securesms.util.MappingViewHolder;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
|
||||
class ChatWallpaperViewHolder extends MappingViewHolder<ChatWallpaperSelectionMappingModel> {
|
||||
|
||||
private final ImageView preview;
|
||||
private final View dimmer;
|
||||
private final EventListener eventListener;
|
||||
|
||||
public ChatWallpaperViewHolder(@NonNull View itemView, @Nullable EventListener eventListener) {
|
||||
super(itemView);
|
||||
this.preview = itemView.findViewById(R.id.chat_wallpaper_preview);
|
||||
this.dimmer = itemView.findViewById(R.id.chat_wallpaper_dim);
|
||||
this.eventListener = eventListener;
|
||||
}
|
||||
|
||||
@@ -27,6 +30,8 @@ class ChatWallpaperViewHolder extends MappingViewHolder<ChatWallpaperSelectionMa
|
||||
public void bind(@NonNull ChatWallpaperSelectionMappingModel model) {
|
||||
model.loadInto(preview);
|
||||
|
||||
ChatWallpaperDimLevelUtil.applyDimLevelForNightMode(dimmer, model.getWallpaper());
|
||||
|
||||
if (eventListener != null) {
|
||||
preview.setOnClickListener(unused -> {
|
||||
if (getAdapterPosition() != RecyclerView.NO_POSITION) {
|
||||
|
||||
@@ -4,7 +4,6 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.Transformations;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
@@ -12,6 +11,7 @@ import com.annimon.stream.Stream;
|
||||
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.MappingModel;
|
||||
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
import java.util.List;
|
||||
@@ -19,23 +19,52 @@ import java.util.Objects;
|
||||
|
||||
public class ChatWallpaperViewModel extends ViewModel {
|
||||
|
||||
private final ChatWallpaperRepository repository = new ChatWallpaperRepository();
|
||||
private final MutableLiveData<Optional<ChatWallpaper>> wallpaper = new MutableLiveData<>();
|
||||
private final MutableLiveData<List<ChatWallpaper>> builtins = new MutableLiveData<>();
|
||||
private final ChatWallpaperRepository repository = new ChatWallpaperRepository();
|
||||
private final MutableLiveData<Optional<ChatWallpaper>> wallpaper = new MutableLiveData<>();
|
||||
private final MutableLiveData<List<ChatWallpaper>> builtins = new MutableLiveData<>();
|
||||
private final MutableLiveData<Boolean> dimInDarkTheme = new MutableLiveData<>();
|
||||
private final RecipientId recipientId;
|
||||
|
||||
private ChatWallpaperViewModel(@Nullable RecipientId recipientId) {
|
||||
this.recipientId = recipientId;
|
||||
|
||||
ChatWallpaper currentWallpaper = repository.getCurrentWallpaper(recipientId);
|
||||
dimInDarkTheme.setValue(currentWallpaper != null && currentWallpaper.getDimLevelForDarkTheme() > 0f);
|
||||
wallpaper.setValue(Optional.fromNullable(currentWallpaper));
|
||||
repository.getAllWallpaper(builtins::postValue);
|
||||
}
|
||||
|
||||
void setDimInDarkTheme(boolean shouldDimInDarkTheme) {
|
||||
dimInDarkTheme.setValue(shouldDimInDarkTheme);
|
||||
|
||||
Optional<ChatWallpaper> wallpaper = this.wallpaper.getValue();
|
||||
if (wallpaper.isPresent()) {
|
||||
repository.setDimInDarkTheme(recipientId, shouldDimInDarkTheme);
|
||||
}
|
||||
}
|
||||
|
||||
void setWallpaper(@Nullable ChatWallpaper chatWallpaper) {
|
||||
wallpaper.setValue(Optional.fromNullable(chatWallpaper));
|
||||
}
|
||||
|
||||
void saveWallpaperSelection(@NonNull ChatWallpaper selected) {
|
||||
// TODO
|
||||
void saveWallpaperSelection() {
|
||||
Optional<ChatWallpaper> wallpaper = this.wallpaper.getValue();
|
||||
boolean dimInDarkTheme = this.dimInDarkTheme.getValue();
|
||||
|
||||
if (!wallpaper.isPresent()) {
|
||||
repository.saveWallpaper(recipientId, null);
|
||||
return;
|
||||
}
|
||||
|
||||
Optional<ChatWallpaper> updated = wallpaper.transform(paper -> ChatWallpaperFactory.updateWithDimming(paper, dimInDarkTheme ? ChatWallpaper.FIXED_DIM_LEVEL_FOR_DARK_THEME : 0f));
|
||||
|
||||
if (updated.isPresent()) {
|
||||
repository.saveWallpaper(recipientId, updated.get());
|
||||
}
|
||||
}
|
||||
|
||||
void resetAllWallpaper() {
|
||||
repository.resetAllWallpaper();
|
||||
}
|
||||
|
||||
public @Nullable RecipientId getRecipientId() {
|
||||
@@ -47,8 +76,19 @@ public class ChatWallpaperViewModel extends ViewModel {
|
||||
}
|
||||
|
||||
LiveData<List<MappingModel<?>>> getWallpapers() {
|
||||
return Transformations.map(Transformations.distinctUntilChanged(builtins),
|
||||
wallpapers -> Stream.of(wallpapers).<MappingModel<?>>map(ChatWallpaperSelectionMappingModel::new).toList());
|
||||
return LiveDataUtil.combineLatest(builtins, dimInDarkTheme, (wallpapers, dimInDarkMode) ->
|
||||
Stream.of(wallpapers)
|
||||
.map(paper -> ChatWallpaperFactory.updateWithDimming(paper, dimInDarkMode ? 1f : 0f))
|
||||
.<MappingModel<?>>map(ChatWallpaperSelectionMappingModel::new).toList()
|
||||
);
|
||||
}
|
||||
|
||||
LiveData<Boolean> getDimInDarkTheme() {
|
||||
return dimInDarkTheme;
|
||||
}
|
||||
|
||||
boolean isGlobal() {
|
||||
return recipientId == null;
|
||||
}
|
||||
|
||||
public static class Factory implements ViewModelProvider.Factory {
|
||||
|
||||
@@ -23,43 +23,61 @@ import java.util.Objects;
|
||||
|
||||
final class GradientChatWallpaper implements ChatWallpaper, Parcelable {
|
||||
|
||||
public static final GradientChatWallpaper SOLID_1 = new GradientChatWallpaper(0xFFE26983);
|
||||
public static final GradientChatWallpaper SOLID_2 = new GradientChatWallpaper(0xFFDF9171);
|
||||
public static final GradientChatWallpaper SOLID_3 = new GradientChatWallpaper(0xFF9E9887);
|
||||
public static final GradientChatWallpaper SOLID_4 = new GradientChatWallpaper(0xFF89AE8F);
|
||||
public static final GradientChatWallpaper SOLID_5 = new GradientChatWallpaper(0xFF32C7E2);
|
||||
public static final GradientChatWallpaper SOLID_6 = new GradientChatWallpaper(0xFF7C99B6);
|
||||
public static final GradientChatWallpaper SOLID_7 = new GradientChatWallpaper(0xFFC988E7);
|
||||
public static final GradientChatWallpaper SOLID_8 = new GradientChatWallpaper(0xFFE297C3);
|
||||
public static final GradientChatWallpaper SOLID_9 = new GradientChatWallpaper(0xFFA2A2AA);
|
||||
public static final GradientChatWallpaper SOLID_10 = new GradientChatWallpaper(0xFF146148);
|
||||
public static final GradientChatWallpaper SOLID_11 = new GradientChatWallpaper(0xFF403B91);
|
||||
public static final GradientChatWallpaper SOLID_12 = new GradientChatWallpaper(0xFF624249);
|
||||
public static final GradientChatWallpaper GRADIENT_1 = new GradientChatWallpaper(167.96f,
|
||||
new int[] { 0xFFF3DC47, 0xFFF3DA47, 0xFFF2D546, 0xFFF2CC46, 0xFFF1C146, 0xFFEFB445, 0xFFEEA544, 0xFFEC9644, 0xFFEB8743, 0xFFE97743, 0xFFE86942, 0xFFE65C41, 0xFFE55041, 0xFFE54841, 0xFFE44240, 0xFFE44040 },
|
||||
new float[] { 0.0f, 0.0807f, 0.1554f, 0.225f, 0.2904f, 0.3526f, 0.4125f, 0.471f, 0.529f, 0.5875f, 0.6474f, 0.7096f, 0.775f, 0.8446f, 0.9193f, 1f });
|
||||
public static final GradientChatWallpaper GRADIENT_2 = new GradientChatWallpaper(180f,
|
||||
new int[] { 0xFF16161D, 0xFF17171E, 0xFF1A1A22, 0xFF1F1F28, 0xFF26262F, 0xFF2D2D38, 0xFF353542, 0xFF3E3E4C, 0xFF474757, 0xFF4F4F61, 0xFF57576B, 0xFF5F5F74, 0xFF65657C, 0xFF6A6A82, 0xFF6D6D85, 0xFF6E6E87 },
|
||||
new float[] { 0.0000f, 0.0807f, 0.1554f, 0.2250f, 0.2904f, 0.3526f, 0.4125f, 0.4710f, 0.5290f, 0.5875f, 0.6474f, 0.7096f, 0.7750f, 0.8446f, 0.9193f, 1.0000f });
|
||||
public static final ChatWallpaper GRADIENT_1 = new GradientChatWallpaper(167.96f,
|
||||
new int[] { 0xFFF3DC47, 0xFFF3DA47, 0xFFF2D546, 0xFFF2CC46, 0xFFF1C146, 0xFFEFB445, 0xFFEEA544, 0xFFEC9644, 0xFFEB8743, 0xFFE97743, 0xFFE86942, 0xFFE65C41, 0xFFE55041, 0xFFE54841, 0xFFE44240, 0xFFE44040 },
|
||||
new float[] { 0.0f, 0.0807f, 0.1554f, 0.225f, 0.2904f, 0.3526f, 0.4125f, 0.471f, 0.529f, 0.5875f, 0.6474f, 0.7096f, 0.775f, 0.8446f, 0.9193f, 1f },
|
||||
0f);
|
||||
public static final ChatWallpaper GRADIENT_2 = new GradientChatWallpaper(180f,
|
||||
new int[] { 0xFF16161D, 0xFF17171E, 0xFF1A1A22, 0xFF1F1F28, 0xFF26262F, 0xFF2D2D38, 0xFF353542, 0xFF3E3E4C, 0xFF474757, 0xFF4F4F61, 0xFF57576B, 0xFF5F5F74, 0xFF65657C, 0xFF6A6A82, 0xFF6D6D85, 0xFF6E6E87 },
|
||||
new float[] { 0.0000f, 0.0807f, 0.1554f, 0.2250f, 0.2904f, 0.3526f, 0.4125f, 0.4710f, 0.5290f, 0.5875f, 0.6474f, 0.7096f, 0.7750f, 0.8446f, 0.9193f, 1.0000f },
|
||||
0f);
|
||||
public static final ChatWallpaper GRADIENT_3 = new GradientChatWallpaper(192.04f,
|
||||
new int[] { 0xFFF53844, 0xFFF33845, 0xFFEC3848, 0xFFE2384C, 0xFFD63851, 0xFFC73857, 0xFFB6385E, 0xFFA43866, 0xFF93376D, 0xFF813775, 0xFF70377C, 0xFF613782, 0xFF553787, 0xFF4B378B, 0xFF44378E, 0xFF42378F },
|
||||
new float[] { 0.0000f, 0.0075f, 0.0292f, 0.0637f, 0.1097f, 0.1659f, 0.2310f, 0.3037f, 0.3827f, 0.4666f, 0.5541f, 0.6439f, 0.7347f, 0.8252f, 0.9141f, 1.0000f },
|
||||
0f);
|
||||
public static final ChatWallpaper GRADIENT_4 = new GradientChatWallpaper(180f,
|
||||
new int[] { 0xFF0093E9, 0xFF0294E9, 0xFF0696E7, 0xFF0D99E5, 0xFF169EE3, 0xFF21A3E0, 0xFF2DA8DD, 0xFF3AAEDA, 0xFF46B5D6, 0xFF53BBD3, 0xFF5FC0D0, 0xFF6AC5CD, 0xFF73CACB, 0xFF7ACDC9, 0xFF7ECFC7, 0xFF80D0C7 },
|
||||
new float[] { 0.0000f, 0.0807f, 0.1554f, 0.2250f, 0.2904f, 0.3526f, 0.4125f, 0.4710f, 0.5290f, 0.5875f, 0.6474f, 0.7096f, 0.7750f, 0.8446f, 0.9193f, 1.0000f },
|
||||
0f);
|
||||
public static final ChatWallpaper GRADIENT_5 = new GradientChatWallpaper(192.04f,
|
||||
new int[] { 0xFFF04CE6, 0xFFEE4BE6, 0xFFE54AE5, 0xFFD949E5, 0xFFC946E4, 0xFFB644E3, 0xFFA141E3, 0xFF8B3FE2, 0xFF743CE1, 0xFF5E39E0, 0xFF4936DF, 0xFF3634DE, 0xFF2632DD, 0xFF1930DD, 0xFF112FDD, 0xFF0E2FDD },
|
||||
new float[] { 0.0000f, 0.0807f, 0.1554f, 0.2250f, 0.2904f, 0.3526f, 0.4125f, 0.4710f, 0.5290f, 0.5875f, 0.6474f, 0.7096f, 0.7750f, 0.8446f, 0.9193f, 1.0000f },
|
||||
0f);
|
||||
public static final ChatWallpaper GRADIENT_6 = new GradientChatWallpaper(180f,
|
||||
new int[] { 0xFF65CDAC, 0xFF64CDAB, 0xFF60CBA8, 0xFF5BC8A3, 0xFF55C49D, 0xFF4DC096, 0xFF45BB8F, 0xFF3CB687, 0xFF33B17F, 0xFF2AAC76, 0xFF21A76F, 0xFF1AA268, 0xFF139F62, 0xFF0E9C5E, 0xFF0B9A5B, 0xFF0A995A },
|
||||
new float[] { 0.0000f, 0.0807f, 0.1554f, 0.2250f, 0.2904f, 0.3526f, 0.4125f, 0.4710f, 0.5290f, 0.5875f, 0.6474f, 0.7096f, 0.7750f, 0.8446f, 0.9193f, 1.0000f },
|
||||
0f);
|
||||
public static final ChatWallpaper GRADIENT_7 = new GradientChatWallpaper(180f,
|
||||
new int[] { 0xFFD8E1FA, 0xFFD8E0F9, 0xFFD8DEF7, 0xFFD8DBF3, 0xFFD8D6EE, 0xFFD7D1E8, 0xFFD7CCE2, 0xFFD7C6DB, 0xFFD7BFD4, 0xFFD7B9CD, 0xFFD6B4C7, 0xFFD6AFC1, 0xFFD6AABC, 0xFFD6A7B8, 0xFFD6A5B6, 0xFFD6A4B5 },
|
||||
new float[] { 0.0000f, 0.0807f, 0.1554f, 0.2250f, 0.2904f, 0.3526f, 0.4125f, 0.4710f, 0.5290f, 0.5875f, 0.6474f, 0.7096f, 0.7750f, 0.8446f, 0.9193f, 1.0000f },
|
||||
0f);
|
||||
public static final ChatWallpaper GRADIENT_8 = new GradientChatWallpaper(180f,
|
||||
new int[] { 0xFFD8EBFD, 0xFFD7EAFD, 0xFFD5E9FD, 0xFFD2E7FD, 0xFFCDE5FD, 0xFFC8E3FD, 0xFFC3E0FD, 0xFFBDDDFC, 0xFFB7DAFC, 0xFFB2D7FC, 0xFFACD4FC, 0xFFA7D1FC, 0xFFA3CFFB, 0xFFA0CDFB, 0xFF9ECCFB, 0xFF9DCCFB },
|
||||
new float[] { 0.0000f, 0.0807f, 0.1554f, 0.2250f, 0.2904f, 0.3526f, 0.4125f, 0.4710f, 0.5290f, 0.5875f, 0.6474f, 0.7096f, 0.7750f, 0.8446f, 0.9193f, 1.0000f },
|
||||
0f);
|
||||
public static final ChatWallpaper GRADIENT_9 = new GradientChatWallpaper(192.04f,
|
||||
new int[] { 0xFFFFE5C2, 0xFFFFE4C1, 0xFFFFE2BF, 0xFFFFDFBD, 0xFFFEDBB9, 0xFFFED6B5, 0xFFFED1B1, 0xFFFDCCAC, 0xFFFDC6A8, 0xFFFDC0A3, 0xFFFCBB9F, 0xFFFCB69B, 0xFFFCB297, 0xFFFCAF95, 0xFFFCAD93, 0xFFFCAC92 },
|
||||
new float[] { 0.0000f, 0.0807f, 0.1554f, 0.2250f, 0.2904f, 0.3526f, 0.4125f, 0.4710f, 0.5290f, 0.5875f, 0.6474f, 0.7096f, 0.7750f, 0.8446f, 0.9193f, 1.0000f },
|
||||
0f);
|
||||
|
||||
|
||||
private final float degrees;
|
||||
private final int[] colors;
|
||||
private final float[] positions;
|
||||
private final float dimLevelInDarkTheme;
|
||||
|
||||
GradientChatWallpaper(int color) {
|
||||
this(0f, new int[]{color, color}, null);
|
||||
}
|
||||
|
||||
GradientChatWallpaper(float degrees, int[] colors, float[] positions) {
|
||||
this.degrees = degrees;
|
||||
this.colors = colors;
|
||||
this.positions = positions;
|
||||
GradientChatWallpaper(float degrees, int[] colors, float[] positions, float dimLevelInDarkTheme) {
|
||||
this.degrees = degrees;
|
||||
this.colors = colors;
|
||||
this.positions = positions;
|
||||
this.dimLevelInDarkTheme = dimLevelInDarkTheme;
|
||||
}
|
||||
|
||||
private GradientChatWallpaper(Parcel in) {
|
||||
degrees = in.readFloat();
|
||||
colors = in.createIntArray();
|
||||
positions = in.createFloatArray();
|
||||
degrees = in.readFloat();
|
||||
colors = in.createIntArray();
|
||||
positions = in.createFloatArray();
|
||||
dimLevelInDarkTheme = in.readFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,6 +85,7 @@ final class GradientChatWallpaper implements ChatWallpaper, Parcelable {
|
||||
dest.writeFloat(degrees);
|
||||
dest.writeIntArray(colors);
|
||||
dest.writeFloatArray(positions);
|
||||
dest.writeFloat(dimLevelInDarkTheme);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,6 +97,11 @@ final class GradientChatWallpaper implements ChatWallpaper, Parcelable {
|
||||
return new RotatableGradientDrawable(degrees, colors, positions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDimLevelForDarkTheme() {
|
||||
return dimLevelInDarkTheme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadInto(@NonNull ImageView imageView) {
|
||||
imageView.setImageDrawable(buildDrawable());
|
||||
@@ -99,6 +123,7 @@ final class GradientChatWallpaper implements ChatWallpaper, Parcelable {
|
||||
|
||||
return Wallpaper.newBuilder()
|
||||
.setLinearGradient(builder)
|
||||
.setDimLevelInDarkTheme(dimLevelInDarkTheme)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -109,12 +134,13 @@ final class GradientChatWallpaper implements ChatWallpaper, Parcelable {
|
||||
GradientChatWallpaper that = (GradientChatWallpaper) o;
|
||||
return Float.compare(that.degrees, degrees) == 0 &&
|
||||
Arrays.equals(colors, that.colors) &&
|
||||
Arrays.equals(positions, that.positions);
|
||||
Arrays.equals(positions, that.positions) &&
|
||||
Float.compare(that.dimLevelInDarkTheme, dimLevelInDarkTheme) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = Objects.hash(degrees);
|
||||
int result = Objects.hash(degrees, dimLevelInDarkTheme);
|
||||
result = 31 * result + Arrays.hashCode(colors);
|
||||
result = 31 * result + Arrays.hashCode(positions);
|
||||
return result;
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package org.thoughtcrime.securesms.wallpaper;
|
||||
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.Wallpaper;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
final class SingleColorChatWallpaper implements ChatWallpaper, Parcelable {
|
||||
|
||||
public static final ChatWallpaper SOLID_1 = new SingleColorChatWallpaper(0xFFE26983, 0f);
|
||||
public static final ChatWallpaper SOLID_2 = new SingleColorChatWallpaper(0xFFDF9171, 0f);
|
||||
public static final ChatWallpaper SOLID_3 = new SingleColorChatWallpaper(0xFF9E9887, 0f);
|
||||
public static final ChatWallpaper SOLID_4 = new SingleColorChatWallpaper(0xFF89AE8F, 0f);
|
||||
public static final ChatWallpaper SOLID_5 = new SingleColorChatWallpaper(0xFF32C7E2, 0f);
|
||||
public static final ChatWallpaper SOLID_6 = new SingleColorChatWallpaper(0xFF7C99B6, 0f);
|
||||
public static final ChatWallpaper SOLID_7 = new SingleColorChatWallpaper(0xFFC988E7, 0f);
|
||||
public static final ChatWallpaper SOLID_8 = new SingleColorChatWallpaper(0xFFE297C3, 0f);
|
||||
public static final ChatWallpaper SOLID_9 = new SingleColorChatWallpaper(0xFFA2A2AA, 0f);
|
||||
public static final ChatWallpaper SOLID_10 = new SingleColorChatWallpaper(0xFF146148, 0f);
|
||||
public static final ChatWallpaper SOLID_11 = new SingleColorChatWallpaper(0xFF403B91, 0f);
|
||||
public static final ChatWallpaper SOLID_12 = new SingleColorChatWallpaper(0xFF624249, 0f);
|
||||
|
||||
private final @ColorInt int color;
|
||||
private final float dimLevelInDarkTheme;
|
||||
|
||||
SingleColorChatWallpaper(@ColorInt int color, float dimLevelInDarkTheme) {
|
||||
this.color = color;
|
||||
this.dimLevelInDarkTheme = dimLevelInDarkTheme;
|
||||
}
|
||||
|
||||
private SingleColorChatWallpaper(Parcel in) {
|
||||
color = in.readInt();
|
||||
dimLevelInDarkTheme = in.readFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDimLevelForDarkTheme() {
|
||||
return dimLevelInDarkTheme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadInto(@NonNull ImageView imageView) {
|
||||
imageView.setImageDrawable(new ColorDrawable(color));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Wallpaper serialize() {
|
||||
Wallpaper.SingleColor.Builder builder = Wallpaper.SingleColor.newBuilder();
|
||||
|
||||
builder.setColor(color);
|
||||
|
||||
return Wallpaper.newBuilder()
|
||||
.setSingleColor(builder)
|
||||
.setDimLevelInDarkTheme(dimLevelInDarkTheme)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(color);
|
||||
dest.writeFloat(dimLevelInDarkTheme);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
SingleColorChatWallpaper that = (SingleColorChatWallpaper) o;
|
||||
return color == that.color && Float.compare(dimLevelInDarkTheme, that.dimLevelInDarkTheme) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(color, dimLevelInDarkTheme);
|
||||
}
|
||||
|
||||
public static final Creator<SingleColorChatWallpaper> CREATOR = new Creator<SingleColorChatWallpaper>() {
|
||||
@Override
|
||||
public SingleColorChatWallpaper createFromParcel(Parcel in) {
|
||||
return new SingleColorChatWallpaper(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleColorChatWallpaper[] newArray(int size) {
|
||||
return new SingleColorChatWallpaper[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -10,12 +10,21 @@ import androidx.annotation.NonNull;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.Wallpaper;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
final class UriChatWallpaper implements ChatWallpaper, Parcelable {
|
||||
|
||||
private final Uri uri;
|
||||
private final Uri uri;
|
||||
private final float dimLevelInDarkTheme;
|
||||
|
||||
public UriChatWallpaper(@NonNull Uri uri) {
|
||||
this.uri = uri;
|
||||
public UriChatWallpaper(@NonNull Uri uri, float dimLevelInDarkTheme) {
|
||||
this.uri = uri;
|
||||
this.dimLevelInDarkTheme = dimLevelInDarkTheme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDimLevelForDarkTheme() {
|
||||
return dimLevelInDarkTheme;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -29,6 +38,7 @@ final class UriChatWallpaper implements ChatWallpaper, Parcelable {
|
||||
public @NonNull Wallpaper serialize() {
|
||||
return Wallpaper.newBuilder()
|
||||
.setFile(Wallpaper.File.newBuilder().setUri(uri.toString()))
|
||||
.setDimLevelInDarkTheme(dimLevelInDarkTheme)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -40,12 +50,27 @@ final class UriChatWallpaper implements ChatWallpaper, Parcelable {
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(uri.toString());
|
||||
dest.writeFloat(dimLevelInDarkTheme);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
UriChatWallpaper that = (UriChatWallpaper) o;
|
||||
return Float.compare(that.dimLevelInDarkTheme, dimLevelInDarkTheme) == 0 &&
|
||||
uri.equals(that.uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(uri, dimLevelInDarkTheme);
|
||||
}
|
||||
|
||||
public static final Creator<UriChatWallpaper> CREATOR = new Creator<UriChatWallpaper>() {
|
||||
@Override
|
||||
public UriChatWallpaper createFromParcel(Parcel in) {
|
||||
return new UriChatWallpaper(Uri.parse(in.readString()));
|
||||
return new UriChatWallpaper(Uri.parse(in.readString()), in.readFloat());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -74,7 +74,7 @@ public final class WallpaperStorage {
|
||||
*/
|
||||
@WorkerThread
|
||||
public static void onWallpaperDeselected(@NonNull Context context, @NonNull Uri uri) {
|
||||
Uri globalUri = SignalStore.wallpaper().getCurrentWallpaperUri();
|
||||
Uri globalUri = SignalStore.wallpaper().getWallpaperUri();
|
||||
if (Objects.equals(uri, globalUri)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user