diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index 54bae7bc..8ffa1764 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -11180,17 +11180,23 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. private Drawable getFoxSponsorDrawable(int a) { if (foxSponsorDrawable[a] == null) { - Drawable d = ContextCompat.getDrawable(getParentActivity(), R.drawable.foxsponsor_badge).mutate(); - int color = getThemedColor(Theme.key_profile_verifiedBackground); - if (a == 1) { - color = dontApplyPeerColor(color); - } - d.setColorFilter(color, PorterDuff.Mode.SRC_IN); - foxSponsorDrawable[a] = d; + foxSponsorDrawable[a] = new tw.nekomimi.nekogram.helpers.ShimmerHeartDrawable(AndroidUtilities.dp(a == 1 ? 22 : 18)); } return foxSponsorDrawable[a]; } + private void showSponsorInfo() { + if (getParentActivity() == null) { + return; + } + BulletinFactory.of(ProfileActivity.this) + .createSimpleBulletin( + new tw.nekomimi.nekogram.helpers.ShimmerHeartDrawable(AndroidUtilities.dp(28)), + LocaleController.getString(R.string.FoxSponsorBadge), + LocaleController.getString(R.string.FoxSponsorBadgeInfo)) + .show(); + } + private Drawable getPremiumCrossfadeDrawable(int a) { if (premiumCrossfadeDrawable[a] == null) { premiumStarDrawable[a] = ContextCompat.getDrawable(getParentActivity(), R.drawable.msg_premium_liststar).mutate(); @@ -11550,7 +11556,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. }, resourcesProvider); } : null); Drawable leftIcon = currentEncryptedChat != null ? getLockIconDrawable() : null; - boolean rightIconIsPremium = false, rightIconIsStatus = false; + boolean rightIconIsPremium = false, rightIconIsStatus = false, rightIconIsSponsor = false; nameTextView[a].setRightDrawableOutside(a == 0); if (a == 0 && !copyFromChatActivity) { if (user.scam || user.fake) { @@ -11562,14 +11568,15 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. } else if (getMessagesController().isDialogMuted(dialogId != 0 ? dialogId : userId, topicId)) { nameTextView[a].setRightDrawable2(getThemedDrawable(Theme.key_drawable_muteIconDrawable)); nameTextViewRightDrawable2ContentDescription = LocaleController.getString(R.string.NotificationsMuted); - } else if (user.self && SponsorHelper.isSponsor(user.id)) { - nameTextView[a].setRightDrawable2(getFoxSponsorDrawable(a)); - nameTextViewRightDrawable2ContentDescription = LocaleController.getString(R.string.FoxSponsorBadge); } else { nameTextView[a].setRightDrawable2(null); nameTextViewRightDrawable2ContentDescription = null; } - if (user != null/* && !getMessagesController().premiumFeaturesBlocked()*/ && !MessagesController.isSupportUser(user) && DialogObject.getEmojiStatusDocumentId(user.emoji_status) != 0) { + if (user.self && SponsorHelper.isSponsor(user.id)) { + rightIconIsSponsor = true; + nameTextView[a].setRightDrawable(getFoxSponsorDrawable(a)); + nameTextViewRightDrawableContentDescription = LocaleController.getString(R.string.FoxSponsorBadge); + } else if (user != null/* && !getMessagesController().premiumFeaturesBlocked()*/ && !MessagesController.isSupportUser(user) && DialogObject.getEmojiStatusDocumentId(user.emoji_status) != 0) { rightIconIsStatus = true; rightIconIsPremium = false; nameTextView[a].setRightDrawable(getEmojiStatusDrawable(user.emoji_status, false, false, a)); @@ -11588,12 +11595,13 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. nameTextView[a].setRightDrawable2(getScamDrawable(user.scam ? 0 : 1)); } else if (user.verified) { nameTextView[a].setRightDrawable2(getVerifiedCrossfadeDrawable(a)); - } else if (user.self && SponsorHelper.isSponsor(user.id)) { - nameTextView[a].setRightDrawable2(getFoxSponsorDrawable(a)); } else { nameTextView[a].setRightDrawable2(null); } - if (/*!getMessagesController().premiumFeaturesBlocked() && */user != null && !MessagesController.isSupportUser(user) && DialogObject.getEmojiStatusDocumentId(user.emoji_status) != 0) { + if (user.self && SponsorHelper.isSponsor(user.id)) { + rightIconIsSponsor = true; + nameTextView[a].setRightDrawable(getFoxSponsorDrawable(a)); + } else if (/*!getMessagesController().premiumFeaturesBlocked() && */user != null && !MessagesController.isSupportUser(user) && DialogObject.getEmojiStatusDocumentId(user.emoji_status) != 0) { rightIconIsStatus = true; rightIconIsPremium = false; nameTextView[a].setRightDrawable(getEmojiStatusDrawable(user.emoji_status, true, true, a)); @@ -11612,10 +11620,12 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. nameTextView[a].setLeftDrawableOutside(false); } nameTextView[a].setLeftDrawable(leftIcon); - if (a == 1 && (rightIconIsStatus || rightIconIsPremium)) { + if (a == 1 && (rightIconIsStatus || rightIconIsPremium || rightIconIsSponsor)) { nameTextView[a].setRightDrawableOutside(true); } - if (user.self && getMessagesController().isPremiumUser(user)) { + if (rightIconIsSponsor) { + nameTextView[a].setRightDrawableOnClick(v -> showSponsorInfo()); + } else if (user.self && getMessagesController().isPremiumUser(user)) { nameTextView[a].setRightDrawableOnClick(v -> { showStatusSelect(); }); diff --git a/TMessagesProj/src/main/java/tw/nekomimi/nekogram/helpers/ShimmerHeartDrawable.java b/TMessagesProj/src/main/java/tw/nekomimi/nekogram/helpers/ShimmerHeartDrawable.java new file mode 100644 index 00000000..87c46639 --- /dev/null +++ b/TMessagesProj/src/main/java/tw/nekomimi/nekogram/helpers/ShimmerHeartDrawable.java @@ -0,0 +1,128 @@ +package tw.nekomimi.nekogram.helpers; + +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.LinearGradient; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.Shader; +import android.graphics.drawable.Drawable; + +import androidx.annotation.NonNull; + +import org.telegram.messenger.AndroidUtilities; + +/** + * A heart-shaped badge filled with a continuously moving iridescent gradient + * ("shimmer"). It self-invalidates each frame, so when attached to a view via + * {@code setRightDrawable(...)} the host keeps repainting automatically (the + * SimpleTextView drawable callback chain handles invalidation). + */ +public class ShimmerHeartDrawable extends Drawable { + + private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); + private final Path heart = new Path(); + private final Matrix gradientMatrix = new Matrix(); + + private LinearGradient gradient; + private int lastWidth = -1; + private int gradientWidth; + + // Iridescent palette swept across the heart. + private static final int[] COLORS = new int[] { + 0xFFFF4D6D, // pink-red + 0xFFFF8FA3, // light pink + 0xFFFFC2D1, // pale + 0xFFFF5C8A, // magenta + 0xFFFF1E56, // deep red + 0xFFFF4D6D, // back to start (seamless loop) + }; + + private static final long CYCLE_MS = 2200L; + private final int size; + + public ShimmerHeartDrawable() { + this(AndroidUtilities.dp(18)); + } + + public ShimmerHeartDrawable(int sizePx) { + this.size = sizePx; + paint.setStyle(Paint.Style.FILL); + } + + private void buildGradient(int width) { + gradientWidth = width * 2; + gradient = new LinearGradient(0, 0, gradientWidth, 0, COLORS, null, Shader.TileMode.MIRROR); + paint.setShader(gradient); + lastWidth = width; + } + + private void buildHeart(Rect b) { + heart.reset(); + float w = b.width(); + float h = b.height(); + float l = b.left; + float t = b.top; + // Heart path normalized to the bounds. + float cx = l + w / 2f; + heart.moveTo(cx, t + h * 0.30f); + heart.cubicTo(l + w * 0.40f, t + h * 0.05f, l + w * 0.02f, t + h * 0.18f, l + w * 0.10f, t + h * 0.45f); + heart.cubicTo(l + w * 0.17f, t + h * 0.66f, l + w * 0.40f, t + h * 0.80f, cx, t + h * 0.97f); + heart.cubicTo(l + w * 0.60f, t + h * 0.80f, l + w * 0.83f, t + h * 0.66f, l + w * 0.90f, t + h * 0.45f); + heart.cubicTo(l + w * 0.98f, t + h * 0.18f, l + w * 0.60f, t + h * 0.05f, cx, t + h * 0.30f); + heart.close(); + } + + @Override + protected void onBoundsChange(@NonNull Rect bounds) { + super.onBoundsChange(bounds); + buildHeart(bounds); + buildGradient(bounds.width()); + } + + @Override + public void draw(@NonNull Canvas canvas) { + Rect b = getBounds(); + if (b.width() == 0 || b.height() == 0) { + return; + } + if (gradient == null || lastWidth != b.width()) { + buildGradient(b.width()); + buildHeart(b); + } + float phase = (System.currentTimeMillis() % CYCLE_MS) / (float) CYCLE_MS; + gradientMatrix.reset(); + gradientMatrix.setTranslate(b.left - phase * gradientWidth, 0); + gradient.setLocalMatrix(gradientMatrix); + canvas.drawPath(heart, paint); + invalidateSelf(); + } + + @Override + public int getIntrinsicWidth() { + return size; + } + + @Override + public int getIntrinsicHeight() { + return size; + } + + @Override + public void setAlpha(int alpha) { + paint.setAlpha(alpha); + } + + @Override + public void setColorFilter(ColorFilter colorFilter) { + paint.setColorFilter(colorFilter); + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } +} diff --git a/TMessagesProj/src/main/res/drawable/foxsponsor_badge.xml b/TMessagesProj/src/main/res/drawable/foxsponsor_badge.xml deleted file mode 100644 index b2b37b9e..00000000 --- a/TMessagesProj/src/main/res/drawable/foxsponsor_badge.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/TMessagesProj/src/main/res/values-ru/strings_neko.xml b/TMessagesProj/src/main/res/values-ru/strings_neko.xml index 0e4f66ed..9e55fada 100644 --- a/TMessagesProj/src/main/res/values-ru/strings_neko.xml +++ b/TMessagesProj/src/main/res/values-ru/strings_neko.xml @@ -322,5 +322,7 @@ Снизу Эффекты бликов - Настройки доступности + Настройки специальных возможностей + Спонсор + Эта отметка выдана за поддержку проекта. Спасибо! diff --git a/TMessagesProj/src/main/res/values/strings_neko.xml b/TMessagesProj/src/main/res/values/strings_neko.xml index 87ba589d..c6fef8fd 100644 --- a/TMessagesProj/src/main/res/values/strings_neko.xml +++ b/TMessagesProj/src/main/res/values/strings_neko.xml @@ -150,6 +150,7 @@ FoxiGram %1$s\nBased on Telegram %2$s\nDesigned by %3$s Installing update... Sponsor + You received this badge for supporting the project. Thank you! Downloading update... A notification will be shown when the update completes. The app will relaunch when the update completes.