kopia lustrzana https://github.com/ryukoposting/Signal-Android
Remove gradient support from api 19.
rodzic
35930fb23a
commit
273e5f9168
|
@ -164,10 +164,9 @@ public class InputPanel extends LinearLayout
|
||||||
long id,
|
long id,
|
||||||
@NonNull Recipient author,
|
@NonNull Recipient author,
|
||||||
@NonNull CharSequence body,
|
@NonNull CharSequence body,
|
||||||
@NonNull SlideDeck attachments,
|
@NonNull SlideDeck attachments)
|
||||||
@NonNull Colorizer colorizer)
|
|
||||||
{
|
{
|
||||||
this.quoteView.setQuote(glideRequests, id, author, body, false, attachments, colorizer);
|
this.quoteView.setQuote(glideRequests, id, author, body, false, attachments, null);
|
||||||
|
|
||||||
int originalHeight = this.quoteView.getVisibility() == VISIBLE ? this.quoteView.getMeasuredHeight()
|
int originalHeight = this.quoteView.getVisibility() == VISIBLE ? this.quoteView.getMeasuredHeight()
|
||||||
: 0;
|
: 0;
|
||||||
|
|
|
@ -26,7 +26,7 @@ import org.signal.core.util.logging.Log;
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||||
import org.thoughtcrime.securesms.components.mention.MentionAnnotation;
|
import org.thoughtcrime.securesms.components.mention.MentionAnnotation;
|
||||||
import org.thoughtcrime.securesms.conversation.colors.Colorizer;
|
import org.thoughtcrime.securesms.conversation.colors.ChatColors;
|
||||||
import org.thoughtcrime.securesms.database.model.Mention;
|
import org.thoughtcrime.securesms.database.model.Mention;
|
||||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
|
@ -69,7 +69,6 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
|
||||||
private int largeCornerRadius;
|
private int largeCornerRadius;
|
||||||
private int smallCornerRadius;
|
private int smallCornerRadius;
|
||||||
private CornerMask cornerMask;
|
private CornerMask cornerMask;
|
||||||
private Colorizer colorizer;
|
|
||||||
|
|
||||||
|
|
||||||
public QuoteView(Context context) {
|
public QuoteView(Context context) {
|
||||||
|
@ -157,7 +156,7 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
|
||||||
@Nullable CharSequence body,
|
@Nullable CharSequence body,
|
||||||
boolean originalMissing,
|
boolean originalMissing,
|
||||||
@NonNull SlideDeck attachments,
|
@NonNull SlideDeck attachments,
|
||||||
@NonNull Colorizer colorizer)
|
@Nullable ChatColors chatColors)
|
||||||
{
|
{
|
||||||
if (this.author != null) this.author.removeForeverObserver(this);
|
if (this.author != null) this.author.removeForeverObserver(this);
|
||||||
|
|
||||||
|
@ -165,13 +164,18 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
|
||||||
this.author = author.live();
|
this.author = author.live();
|
||||||
this.body = body;
|
this.body = body;
|
||||||
this.attachments = attachments;
|
this.attachments = attachments;
|
||||||
this.colorizer = colorizer;
|
|
||||||
|
|
||||||
this.author.observeForever(this);
|
this.author.observeForever(this);
|
||||||
setQuoteAuthor(author);
|
setQuoteAuthor(author);
|
||||||
setQuoteText(body, attachments);
|
setQuoteText(body, attachments);
|
||||||
setQuoteAttachment(glideRequests, attachments);
|
setQuoteAttachment(glideRequests, attachments);
|
||||||
setQuoteMissingFooter(originalMissing);
|
setQuoteMissingFooter(originalMissing);
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT < 21 && messageType == MESSAGE_TYPE_INCOMING && chatColors != null) {
|
||||||
|
this.setBackgroundColor(chatColors.asSingleColor());
|
||||||
|
} else {
|
||||||
|
this.setBackground(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTopCornerSizes(boolean topLeftLarge, boolean topRightLarge) {
|
public void setTopCornerSizes(boolean topLeftLarge, boolean topRightLarge) {
|
||||||
|
|
|
@ -3506,8 +3506,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
||||||
messageRecord.getDateSent(),
|
messageRecord.getDateSent(),
|
||||||
author,
|
author,
|
||||||
body,
|
body,
|
||||||
slideDeck,
|
slideDeck);
|
||||||
fragment.getColorizer());
|
|
||||||
|
|
||||||
} else if (messageRecord.isMms() && !((MmsMessageRecord) messageRecord).getLinkPreviews().isEmpty()) {
|
} else if (messageRecord.isMms() && !((MmsMessageRecord) messageRecord).getLinkPreviews().isEmpty()) {
|
||||||
LinkPreview linkPreview = ((MmsMessageRecord) messageRecord).getLinkPreviews().get(0);
|
LinkPreview linkPreview = ((MmsMessageRecord) messageRecord).getLinkPreviews().get(0);
|
||||||
|
@ -3521,8 +3520,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
||||||
messageRecord.getDateSent(),
|
messageRecord.getDateSent(),
|
||||||
author,
|
author,
|
||||||
conversationMessage.getDisplayBody(this),
|
conversationMessage.getDisplayBody(this),
|
||||||
slideDeck,
|
slideDeck);
|
||||||
fragment.getColorizer());
|
|
||||||
} else {
|
} else {
|
||||||
SlideDeck slideDeck = messageRecord.isMms() ? ((MmsMessageRecord) messageRecord).getSlideDeck() : new SlideDeck();
|
SlideDeck slideDeck = messageRecord.isMms() ? ((MmsMessageRecord) messageRecord).getSlideDeck() : new SlideDeck();
|
||||||
|
|
||||||
|
@ -3536,8 +3534,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
||||||
messageRecord.getDateSent(),
|
messageRecord.getDateSent(),
|
||||||
author,
|
author,
|
||||||
conversationMessage.getDisplayBody(this),
|
conversationMessage.getDisplayBody(this),
|
||||||
slideDeck,
|
slideDeck);
|
||||||
fragment.getColorizer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inputPanel.clickOnComposeInput();
|
inputPanel.clickOnComposeInput();
|
||||||
|
|
|
@ -80,6 +80,7 @@ import org.thoughtcrime.securesms.components.SharedContactView;
|
||||||
import org.thoughtcrime.securesms.components.emoji.EmojiTextView;
|
import org.thoughtcrime.securesms.components.emoji.EmojiTextView;
|
||||||
import org.thoughtcrime.securesms.components.mention.MentionAnnotation;
|
import org.thoughtcrime.securesms.components.mention.MentionAnnotation;
|
||||||
import org.thoughtcrime.securesms.contactshare.Contact;
|
import org.thoughtcrime.securesms.contactshare.Contact;
|
||||||
|
import org.thoughtcrime.securesms.conversation.colors.ChatColors;
|
||||||
import org.thoughtcrime.securesms.conversation.colors.Colorizer;
|
import org.thoughtcrime.securesms.conversation.colors.Colorizer;
|
||||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
|
@ -316,7 +317,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||||
setGroupMessageStatus(messageRecord, recipient.get());
|
setGroupMessageStatus(messageRecord, recipient.get());
|
||||||
setGroupAuthorColor(messageRecord, hasWallpaper, colorizer);
|
setGroupAuthorColor(messageRecord, hasWallpaper, colorizer);
|
||||||
setAuthor(messageRecord, previousMessageRecord, nextMessageRecord, groupThread, hasWallpaper);
|
setAuthor(messageRecord, previousMessageRecord, nextMessageRecord, groupThread, hasWallpaper);
|
||||||
setQuote(messageRecord, previousMessageRecord, nextMessageRecord, groupThread, colorizer);
|
setQuote(messageRecord, previousMessageRecord, nextMessageRecord, groupThread, messageRecord.getRecipient().getChatColors());
|
||||||
setMessageSpacing(context, messageRecord, previousMessageRecord, nextMessageRecord, groupThread);
|
setMessageSpacing(context, messageRecord, previousMessageRecord, nextMessageRecord, groupThread);
|
||||||
setReactions(messageRecord);
|
setReactions(messageRecord);
|
||||||
setFooter(messageRecord, nextMessageRecord, locale, groupThread, hasWallpaper);
|
setFooter(messageRecord, nextMessageRecord, locale, groupThread, hasWallpaper);
|
||||||
|
@ -1095,14 +1096,14 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setQuote(@NonNull MessageRecord current, @NonNull Optional<MessageRecord> previous, @NonNull Optional<MessageRecord> next, boolean isGroupThread, @NonNull Colorizer colorizer) {
|
private void setQuote(@NonNull MessageRecord current, @NonNull Optional<MessageRecord> previous, @NonNull Optional<MessageRecord> next, boolean isGroupThread, @NonNull ChatColors chatColors) {
|
||||||
if (current.isMms() && !current.isMmsNotification() && ((MediaMmsMessageRecord)current).getQuote() != null) {
|
if (current.isMms() && !current.isMmsNotification() && ((MediaMmsMessageRecord)current).getQuote() != null) {
|
||||||
if (quoteView == null) {
|
if (quoteView == null) {
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
Quote quote = ((MediaMmsMessageRecord)current).getQuote();
|
Quote quote = ((MediaMmsMessageRecord)current).getQuote();
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
quoteView.setQuote(glideRequests, quote.getId(), Recipient.live(quote.getAuthor()).get(), quote.getDisplayText(), quote.isOriginalMissing(), quote.getAttachment(), colorizer);
|
quoteView.setQuote(glideRequests, quote.getId(), Recipient.live(quote.getAuthor()).get(), quote.getDisplayText(), quote.isOriginalMissing(), quote.getAttachment(), chatColors);
|
||||||
quoteView.setVisibility(View.VISIBLE);
|
quoteView.setVisibility(View.VISIBLE);
|
||||||
quoteView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
|
quoteView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,9 @@ import android.graphics.PorterDuff
|
||||||
import android.graphics.PorterDuffColorFilter
|
import android.graphics.PorterDuffColorFilter
|
||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.graphics.drawable.ShapeDrawable
|
||||||
|
import android.graphics.drawable.shapes.OvalShape
|
||||||
|
import android.os.Build
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import com.google.common.base.Objects
|
import com.google.common.base.Objects
|
||||||
import org.signal.core.util.ColorUtil
|
import org.signal.core.util.ColorUtil
|
||||||
|
@ -32,18 +35,32 @@ class ChatColors private constructor(
|
||||||
* Returns the Drawable to render the linear gradient, or null if this ChatColors is a single color.
|
* Returns the Drawable to render the linear gradient, or null if this ChatColors is a single color.
|
||||||
*/
|
*/
|
||||||
val chatBubbleMask: Drawable
|
val chatBubbleMask: Drawable
|
||||||
get() = linearGradient?.let {
|
get() {
|
||||||
RotatableGradientDrawable(
|
return when {
|
||||||
it.degrees,
|
Build.VERSION.SDK_INT < 21 -> {
|
||||||
it.colors,
|
ColorDrawable(Color.TRANSPARENT)
|
||||||
it.positions
|
}
|
||||||
)
|
linearGradient != null -> {
|
||||||
} ?: ColorDrawable(asSingleColor())
|
RotatableGradientDrawable(
|
||||||
|
linearGradient.degrees,
|
||||||
|
linearGradient.colors,
|
||||||
|
linearGradient.positions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
ColorDrawable(asSingleColor())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ColorFilter to apply to a conversation bubble or other relevant piece of UI.
|
* Returns the ColorFilter to apply to a conversation bubble or other relevant piece of UI.
|
||||||
*/
|
*/
|
||||||
val chatBubbleColorFilter: ColorFilter = PorterDuffColorFilter(Color.TRANSPARENT, PorterDuff.Mode.SRC_IN)
|
val chatBubbleColorFilter: ColorFilter = if (Build.VERSION.SDK_INT >= 21) {
|
||||||
|
PorterDuffColorFilter(Color.TRANSPARENT, PorterDuff.Mode.SRC_IN)
|
||||||
|
} else {
|
||||||
|
PorterDuffColorFilter(asSingleColor(), PorterDuff.Mode.SRC_IN)
|
||||||
|
}
|
||||||
|
|
||||||
@ColorInt
|
@ColorInt
|
||||||
fun asSingleColor(): Int {
|
fun asSingleColor(): Int {
|
||||||
|
@ -94,6 +111,12 @@ class ChatColors private constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun asCircle(): Drawable {
|
fun asCircle(): Drawable {
|
||||||
|
if (Build.VERSION.SDK_INT < 21) {
|
||||||
|
return ShapeDrawable(OvalShape()).apply {
|
||||||
|
paint.color = asSingleColor()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val toWrap: Drawable = chatBubbleMask
|
val toWrap: Drawable = chatBubbleMask
|
||||||
val path = Path()
|
val path = Path()
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.conversation.colors
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
|
import android.os.Build
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
@ -64,6 +65,10 @@ class Colorizer(private val colorizerView: ColorizerView) : RecyclerView.OnScrol
|
||||||
}
|
}
|
||||||
|
|
||||||
fun applyClipPathsToMaskedGradient(recyclerView: RecyclerView) {
|
fun applyClipPathsToMaskedGradient(recyclerView: RecyclerView) {
|
||||||
|
if (Build.VERSION.SDK_INT < 21) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val layoutManager = recyclerView.layoutManager as LinearLayoutManager
|
val layoutManager = recyclerView.layoutManager as LinearLayoutManager
|
||||||
|
|
||||||
val firstVisibleItemPosition: Int = layoutManager.findFirstVisibleItemPosition()
|
val firstVisibleItemPosition: Int = layoutManager.findFirstVisibleItemPosition()
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package org.thoughtcrime.securesms.conversation.colors.ui
|
package org.thoughtcrime.securesms.conversation.colors.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Path
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
@ -9,7 +8,8 @@ import org.thoughtcrime.securesms.R
|
||||||
import org.thoughtcrime.securesms.conversation.colors.ChatColors
|
import org.thoughtcrime.securesms.conversation.colors.ChatColors
|
||||||
import org.thoughtcrime.securesms.util.MappingAdapter
|
import org.thoughtcrime.securesms.util.MappingAdapter
|
||||||
import org.thoughtcrime.securesms.util.MappingViewHolder
|
import org.thoughtcrime.securesms.util.MappingViewHolder
|
||||||
import org.thoughtcrime.securesms.util.customizeOnDraw
|
import org.thoughtcrime.securesms.util.ViewUtil
|
||||||
|
import org.thoughtcrime.securesms.util.withFixedSize
|
||||||
|
|
||||||
class ChatColorSelectionAdapter(
|
class ChatColorSelectionAdapter(
|
||||||
context: Context,
|
context: Context,
|
||||||
|
@ -81,24 +81,8 @@ class ChatColorSelectionAdapter(
|
||||||
preview.isLongClickable = false
|
preview.isLongClickable = false
|
||||||
}
|
}
|
||||||
|
|
||||||
val mask = model.chatColors.chatBubbleMask
|
val mask = model.chatColors.asCircle()
|
||||||
preview.setImageDrawable(
|
preview.setImageDrawable(mask.withFixedSize(ViewUtil.dpToPx(56)))
|
||||||
mask.customizeOnDraw { wrapped, canvas ->
|
|
||||||
val circlePath = Path()
|
|
||||||
val bounds = canvas.clipBounds
|
|
||||||
circlePath.addCircle(
|
|
||||||
bounds.width() / 2f,
|
|
||||||
bounds.height() / 2f,
|
|
||||||
bounds.width() / 2f,
|
|
||||||
Path.Direction.CW
|
|
||||||
)
|
|
||||||
|
|
||||||
canvas.save()
|
|
||||||
canvas.clipPath(circlePath)
|
|
||||||
wrapped.draw(canvas)
|
|
||||||
canvas.restore()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.thoughtcrime.securesms.conversation.colors.ui.custom
|
package org.thoughtcrime.securesms.conversation.colors.ui.custom
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
|
@ -33,7 +34,12 @@ class CustomChatColorCreatorFragment : Fragment(R.layout.custom_chat_color_creat
|
||||||
|
|
||||||
pager.isUserInputEnabled = false
|
pager.isUserInputEnabled = false
|
||||||
pager.adapter = adapter
|
pager.adapter = adapter
|
||||||
tabLayoutMediator.attach()
|
|
||||||
|
if (Build.VERSION.SDK_INT < 21) {
|
||||||
|
tabLayout.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
tabLayoutMediator.attach()
|
||||||
|
}
|
||||||
|
|
||||||
val startPage = CustomChatColorCreatorFragmentArgs.fromBundle(requireArguments()).startPage
|
val startPage = CustomChatColorCreatorFragmentArgs.fromBundle(requireArguments()).startPage
|
||||||
pager.setCurrentItem(startPage, false)
|
pager.setCurrentItem(startPage, false)
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package org.thoughtcrime.securesms.util
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.graphics.drawable.LayerDrawable
|
||||||
|
import androidx.annotation.Px
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drawable that wraps another drawable but explicitly sets its intrinsic width and height as specified.
|
||||||
|
*/
|
||||||
|
class FixedSizeDrawable(
|
||||||
|
drawable: Drawable,
|
||||||
|
@Px private val width: Int,
|
||||||
|
@Px private val height: Int
|
||||||
|
) : LayerDrawable(arrayOf(drawable)) {
|
||||||
|
override fun getIntrinsicHeight(): Int = width
|
||||||
|
override fun getIntrinsicWidth(): Int = height
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Drawable.withFixedSize(@Px width: Int, @Px height: Int) = FixedSizeDrawable(this, width, height)
|
||||||
|
fun Drawable.withFixedSize(@Px size: Int) = withFixedSize(size, size)
|
|
@ -5,6 +5,7 @@ import android.graphics.Color;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.PorterDuffColorFilter;
|
import android.graphics.PorterDuffColorFilter;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
|
Ładowanie…
Reference in New Issue