Show sponsor badge next to names everywhere + update app icon
- Sponsor heart now appears in the chats list (DialogCell), chat header (ChatAvatarContainer), message author names (ChatMessageCell) and user lists (UserCell), not just on the profile screen - Added ShimmerHeartDrawable.drawStatic() for cheap static rendering in frequently-repainted list cells; header keeps the animated shimmer - Cells request sponsor status via SponsorHelper batch lookup and redraw on sponsorStatusUpdated - Regenerate launcher icon from updated foxigram4.png
|
|
@ -1663,6 +1663,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
||||||
private boolean drawName;
|
private boolean drawName;
|
||||||
private boolean drawNameLayout;
|
private boolean drawNameLayout;
|
||||||
private boolean drawNameAvatar;
|
private boolean drawNameAvatar;
|
||||||
|
private boolean drawNameSponsor;
|
||||||
|
private final android.graphics.RectF nameSponsorRect = new android.graphics.RectF();
|
||||||
|
|
||||||
private boolean drawTopic;
|
private boolean drawTopic;
|
||||||
private TopicButton topicButton;
|
private TopicButton topicButton;
|
||||||
|
|
@ -18762,6 +18764,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
||||||
} else {
|
} else {
|
||||||
currentNameString = "";
|
currentNameString = "";
|
||||||
}
|
}
|
||||||
|
drawNameSponsor = false;
|
||||||
|
if (!messageObject.isOutOwner() && currentNameStatus == null && currentNameBotVerificationId == 0
|
||||||
|
&& currentUser != null && currentUser.id != 0 && messageObject.isFromUser()
|
||||||
|
&& !UserObject.isUserSelf(currentUser) && !currentUser.verified && !currentUser.bot) {
|
||||||
|
tw.nekomimi.nekogram.helpers.SponsorHelper.requestSponsorStatus(currentUser.id);
|
||||||
|
drawNameSponsor = tw.nekomimi.nekogram.helpers.SponsorHelper.isKnownSponsor(currentUser.id);
|
||||||
|
}
|
||||||
int additionalWidth = dp(currentMessageObject.isSponsored() ? -24 : 0);
|
int additionalWidth = dp(currentMessageObject.isSponsored() ? -24 : 0);
|
||||||
CharSequence nameStringFinal = AndroidUtilities.removeDiacritics(currentNameString.replace('\n', ' ').replace('\u200F', ' '));
|
CharSequence nameStringFinal = AndroidUtilities.removeDiacritics(currentNameString.replace('\n', ' ').replace('\u200F', ' '));
|
||||||
try {
|
try {
|
||||||
|
|
@ -21910,6 +21919,14 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
||||||
Theme.chat_namePaint.setAlpha(oldAlpha);
|
Theme.chat_namePaint.setAlpha(oldAlpha);
|
||||||
canvas.restore();
|
canvas.restore();
|
||||||
|
|
||||||
|
if (drawNameSponsor && viaNameWidth <= 0) {
|
||||||
|
int sz = dp(15);
|
||||||
|
float hx = nx + nameOffsetX + nameLayoutWidth + dp(4);
|
||||||
|
float hy = ny + (nameLayout.getHeight() - sz) / 2f;
|
||||||
|
nameSponsorRect.set(hx, hy, hx + sz, hy + sz);
|
||||||
|
tw.nekomimi.nekogram.helpers.ShimmerHeartDrawable.drawStatic(canvas, nameSponsorRect, (int) (0xFF * nameAlpha));
|
||||||
|
}
|
||||||
|
|
||||||
float end;
|
float end;
|
||||||
if (currentMessagesGroup != null && !currentMessagesGroup.isDocuments) {
|
if (currentMessagesGroup != null && !currentMessagesGroup.isDocuments) {
|
||||||
int dWidth = getGroupPhotosWidth();
|
int dWidth = getGroupPhotosWidth();
|
||||||
|
|
|
||||||
|
|
@ -596,6 +596,8 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
||||||
private boolean drawVerified;
|
private boolean drawVerified;
|
||||||
private boolean drawBotVerified;
|
private boolean drawBotVerified;
|
||||||
private boolean drawPremium;
|
private boolean drawPremium;
|
||||||
|
private boolean drawSponsor;
|
||||||
|
private final android.graphics.RectF sponsorHeartRect = new android.graphics.RectF();
|
||||||
private final View emojiStatusView;
|
private final View emojiStatusView;
|
||||||
private final AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable emojiStatus;
|
private final AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable emojiStatus;
|
||||||
private final AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable botVerification;
|
private final AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable botVerification;
|
||||||
|
|
@ -1190,6 +1192,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
||||||
drawVerified = false;
|
drawVerified = false;
|
||||||
drawBotVerified = false;
|
drawBotVerified = false;
|
||||||
drawPremium = false;
|
drawPremium = false;
|
||||||
|
drawSponsor = false;
|
||||||
drawForwardIcon = false;
|
drawForwardIcon = false;
|
||||||
drawGiftIcon = false;
|
drawGiftIcon = false;
|
||||||
drawScam = 0;
|
drawScam = 0;
|
||||||
|
|
@ -1418,6 +1421,10 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
||||||
emojiStatus.setParticles(false, false);
|
emojiStatus.setParticles(false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!drawVerified && !drawPremium && drawScam == 0 && user.id != 0 && !UserObject.isUserSelf(user)) {
|
||||||
|
tw.nekomimi.nekogram.helpers.SponsorHelper.requestSponsorStatus(user.id);
|
||||||
|
drawSponsor = tw.nekomimi.nekogram.helpers.SponsorHelper.isKnownSponsor(user.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (dialogBotVerificationIcon != 0 && drawBotVerified) {
|
if (dialogBotVerificationIcon != 0 && drawBotVerified) {
|
||||||
botVerification.set(dialogBotVerificationIcon, false);
|
botVerification.set(dialogBotVerificationIcon, false);
|
||||||
|
|
@ -2260,6 +2267,13 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
||||||
if (LocaleController.isRTL) {
|
if (LocaleController.isRTL) {
|
||||||
nameLeft += w;
|
nameLeft += w;
|
||||||
}
|
}
|
||||||
|
} else if (drawSponsor) {
|
||||||
|
int w = dp(6) + dp(18);
|
||||||
|
nameWidth -= w;
|
||||||
|
nameAdditionalsForChannelSubscriber += w;
|
||||||
|
if (LocaleController.isRTL) {
|
||||||
|
nameLeft += w;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (drawBotVerified) {
|
if (drawBotVerified) {
|
||||||
nameWidth -= dp(21);
|
nameWidth -= dp(21);
|
||||||
|
|
@ -2691,6 +2705,8 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
||||||
nameMutedIconLeft = nameMuteLeft - dp(6) - Theme.dialogs_muteDrawable.getIntrinsicWidth();
|
nameMutedIconLeft = nameMuteLeft - dp(6) - Theme.dialogs_muteDrawable.getIntrinsicWidth();
|
||||||
} else if (drawScam != 0) {
|
} else if (drawScam != 0) {
|
||||||
nameMuteLeft = (int) (nameLeft + (nameWidth - widthpx) - dp(6) - (drawScam == 1 ? Theme.dialogs_scamDrawable : Theme.dialogs_fakeDrawable).getIntrinsicWidth());
|
nameMuteLeft = (int) (nameLeft + (nameWidth - widthpx) - dp(6) - (drawScam == 1 ? Theme.dialogs_scamDrawable : Theme.dialogs_fakeDrawable).getIntrinsicWidth());
|
||||||
|
} else if (drawSponsor) {
|
||||||
|
nameMuteLeft = (int) (nameLeft + (nameWidth - widthpx) - dp(6) - dp(18));
|
||||||
} else {
|
} else {
|
||||||
nameMuteLeft = (int) (nameLeft + (nameWidth - widthpx) - dp(6) - Theme.dialogs_muteDrawable.getIntrinsicWidth());
|
nameMuteLeft = (int) (nameLeft + (nameWidth - widthpx) - dp(6) - Theme.dialogs_muteDrawable.getIntrinsicWidth());
|
||||||
}
|
}
|
||||||
|
|
@ -4343,6 +4359,15 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
|
||||||
}
|
}
|
||||||
setDrawableBounds((drawScam == 1 ? Theme.dialogs_scamDrawable : Theme.dialogs_fakeDrawable), nameMuteLeft, y);
|
setDrawableBounds((drawScam == 1 ? Theme.dialogs_scamDrawable : Theme.dialogs_fakeDrawable), nameMuteLeft, y);
|
||||||
(drawScam == 1 ? Theme.dialogs_scamDrawable : Theme.dialogs_fakeDrawable).draw(canvas);
|
(drawScam == 1 ? Theme.dialogs_scamDrawable : Theme.dialogs_fakeDrawable).draw(canvas);
|
||||||
|
} else if (drawSponsor) {
|
||||||
|
int y = dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 13.5f : 16.5f);
|
||||||
|
if ((!(useForceThreeLines || SharedConfig.useThreeLinesLayout) || isForumCell()) && hasTags()) {
|
||||||
|
y -= dp(9);
|
||||||
|
}
|
||||||
|
int sz = dp(18);
|
||||||
|
int sx = nameMuteLeft - dp(1);
|
||||||
|
sponsorHeartRect.set(sx, y, sx + sz, y + sz);
|
||||||
|
tw.nekomimi.nekogram.helpers.ShimmerHeartDrawable.drawStatic(canvas, sponsorHeartRect, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drawReorder || reorderIconProgress != 0) {
|
if (drawReorder || reorderIconProgress != 0) {
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ public class UserCell extends FrameLayout implements NotificationCenter.Notifica
|
||||||
private TextView addButton;
|
private TextView addButton;
|
||||||
private ImageView mutualView;
|
private ImageView mutualView;
|
||||||
private Drawable premiumDrawable;
|
private Drawable premiumDrawable;
|
||||||
private final AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable botVerification;
|
private Drawable sponsorDrawable; private final AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable botVerification;
|
||||||
private final AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable emojiStatus;
|
private final AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable emojiStatus;
|
||||||
private ImageView closeView;
|
private ImageView closeView;
|
||||||
protected Theme.ResourcesProvider resourcesProvider;
|
protected Theme.ResourcesProvider resourcesProvider;
|
||||||
|
|
@ -712,10 +712,21 @@ public class UserCell extends FrameLayout implements NotificationCenter.Notifica
|
||||||
nameTextView.setRightDrawable(premiumDrawable);
|
nameTextView.setRightDrawable(premiumDrawable);
|
||||||
}
|
}
|
||||||
nameTextView.setRightDrawableTopPadding(-dp(0.5f));
|
nameTextView.setRightDrawableTopPadding(-dp(0.5f));
|
||||||
|
} else if (currentUser != null && currentUser.id != 0 && !UserObject.isUserSelf(currentUser)
|
||||||
|
&& !currentUser.verified && !currentUser.bot
|
||||||
|
&& tw.nekomimi.nekogram.helpers.SponsorHelper.isKnownSponsor(currentUser.id)) {
|
||||||
|
if (sponsorDrawable == null) {
|
||||||
|
sponsorDrawable = new tw.nekomimi.nekogram.helpers.ShimmerHeartDrawable(dp(16));
|
||||||
|
}
|
||||||
|
nameTextView.setRightDrawable(sponsorDrawable);
|
||||||
|
nameTextView.setRightDrawableTopPadding(-dp(0.5f));
|
||||||
} else {
|
} else {
|
||||||
nameTextView.setRightDrawable(null);
|
nameTextView.setRightDrawable(null);
|
||||||
nameTextView.setRightDrawableTopPadding(0);
|
nameTextView.setRightDrawableTopPadding(0);
|
||||||
}
|
}
|
||||||
|
if (currentUser != null && currentUser.id != 0 && !UserObject.isUserSelf(currentUser) && !currentUser.bot) {
|
||||||
|
tw.nekomimi.nekogram.helpers.SponsorHelper.requestSponsorStatus(currentUser.id);
|
||||||
|
}
|
||||||
if (currentStatus != null) {
|
if (currentStatus != null) {
|
||||||
statusTextView.setTextColor(statusColor);
|
statusTextView.setTextColor(statusColor);
|
||||||
CharSequence status = currentStatus;
|
CharSequence status = currentStatus;
|
||||||
|
|
@ -829,6 +840,8 @@ public class UserCell extends FrameLayout implements NotificationCenter.Notifica
|
||||||
public void didReceivedNotification(int id, int account, Object... args) {
|
public void didReceivedNotification(int id, int account, Object... args) {
|
||||||
if (id == NotificationCenter.emojiLoaded) {
|
if (id == NotificationCenter.emojiLoaded) {
|
||||||
nameTextView.invalidate();
|
nameTextView.invalidate();
|
||||||
|
} else if (id == NotificationCenter.sponsorStatusUpdated) {
|
||||||
|
update(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -836,6 +849,7 @@ public class UserCell extends FrameLayout implements NotificationCenter.Notifica
|
||||||
protected void onAttachedToWindow() {
|
protected void onAttachedToWindow() {
|
||||||
super.onAttachedToWindow();
|
super.onAttachedToWindow();
|
||||||
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded);
|
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded);
|
||||||
|
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.sponsorStatusUpdated);
|
||||||
emojiStatus.attach();
|
emojiStatus.attach();
|
||||||
botVerification.attach();
|
botVerification.attach();
|
||||||
}
|
}
|
||||||
|
|
@ -844,6 +858,7 @@ public class UserCell extends FrameLayout implements NotificationCenter.Notifica
|
||||||
protected void onDetachedFromWindow() {
|
protected void onDetachedFromWindow() {
|
||||||
super.onDetachedFromWindow();
|
super.onDetachedFromWindow();
|
||||||
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded);
|
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded);
|
||||||
|
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.sponsorStatusUpdated);
|
||||||
emojiStatus.detach();
|
emojiStatus.detach();
|
||||||
botVerification.detach();
|
botVerification.detach();
|
||||||
storyParams.onDetachFromWindow();
|
storyParams.onDetachFromWindow();
|
||||||
|
|
|
||||||
|
|
@ -3204,6 +3204,7 @@ public class ChatActivity extends BaseFragment implements
|
||||||
if (themeDelegate.isThemeChangeAvailable(false)) {
|
if (themeDelegate.isThemeChangeAvailable(false)) {
|
||||||
globalObserversGroup.add(NotificationCenter.needSetDayNightTheme);
|
globalObserversGroup.add(NotificationCenter.needSetDayNightTheme);
|
||||||
}
|
}
|
||||||
|
globalObserversGroup.add(NotificationCenter.sponsorStatusUpdated);
|
||||||
|
|
||||||
if (chatInvite != null) {
|
if (chatInvite != null) {
|
||||||
int timeout = chatInvite.expires - getConnectionsManager().getCurrentTime();
|
int timeout = chatInvite.expires - getConnectionsManager().getCurrentTime();
|
||||||
|
|
@ -19775,6 +19776,16 @@ public class ChatActivity extends BaseFragment implements
|
||||||
avatarContainer.setTitle(AndroidUtilities.removeRTL(AndroidUtilities.removeDiacritics(UserObject.getUserName(currentUser))), currentUser.scam, currentUser.fake, currentUser.verified, getMessagesController().isPremiumUser(currentUser), !MessagesController.isSupportUser(currentUser) ? currentUser.emoji_status : null, animated);
|
avatarContainer.setTitle(AndroidUtilities.removeRTL(AndroidUtilities.removeDiacritics(UserObject.getUserName(currentUser))), currentUser.scam, currentUser.fake, currentUser.verified, getMessagesController().isPremiumUser(currentUser), !MessagesController.isSupportUser(currentUser) ? currentUser.emoji_status : null, animated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (avatarContainer != null) {
|
||||||
|
boolean sponsor = false;
|
||||||
|
if (currentChat == null && currentUser != null && !currentUser.self
|
||||||
|
&& !currentUser.verified && !currentUser.scam && !currentUser.fake
|
||||||
|
&& !getMessagesController().isPremiumUser(currentUser)) {
|
||||||
|
tw.nekomimi.nekogram.helpers.SponsorHelper.requestSponsorStatus(currentUser.id);
|
||||||
|
sponsor = tw.nekomimi.nekogram.helpers.SponsorHelper.isKnownSponsor(currentUser.id);
|
||||||
|
}
|
||||||
|
avatarContainer.setSponsorBadge(sponsor);
|
||||||
|
}
|
||||||
setParentActivityTitle(avatarContainer.getTitleTextView().getText());
|
setParentActivityTitle(avatarContainer.getTitleTextView().getText());
|
||||||
updateTitleIcons();
|
updateTitleIcons();
|
||||||
}
|
}
|
||||||
|
|
@ -20496,6 +20507,15 @@ public class ChatActivity extends BaseFragment implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void didReceivedNotification(int id, int account, final Object... args) {
|
public void didReceivedNotification(int id, int account, final Object... args) {
|
||||||
|
if (id == NotificationCenter.sponsorStatusUpdated) {
|
||||||
|
if (avatarContainer != null) {
|
||||||
|
updateTitle(false);
|
||||||
|
}
|
||||||
|
if (chatListView != null) {
|
||||||
|
chatListView.invalidateViews();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (id == NotificationCenter.messagesDidLoad) {
|
if (id == NotificationCenter.messagesDidLoad) {
|
||||||
int guid = (Integer) args[10];
|
int guid = (Integer) args[10];
|
||||||
if (guid != classGuid) {
|
if (guid != classGuid) {
|
||||||
|
|
|
||||||
|
|
@ -950,6 +950,36 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
|
||||||
private Drawable verifiedBackground;
|
private Drawable verifiedBackground;
|
||||||
private Drawable verifiedCheck;
|
private Drawable verifiedCheck;
|
||||||
|
|
||||||
|
private boolean sponsorBadgeShown;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show/hide the FoxiGram sponsor heart next to the title. Only applied when
|
||||||
|
* the title has no scam/verified badge in {@code rightDrawable2}. Uses the
|
||||||
|
* animated {@link tw.nekomimi.nekogram.helpers.ShimmerHeartDrawable} since a
|
||||||
|
* single header is cheap to animate.
|
||||||
|
*/
|
||||||
|
public void setSponsorBadge(boolean show) {
|
||||||
|
if (show == sponsorBadgeShown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (show) {
|
||||||
|
if (rightDrawableIsScamOrVerified) {
|
||||||
|
return; // scam/verified takes precedence
|
||||||
|
}
|
||||||
|
tw.nekomimi.nekogram.helpers.ShimmerHeartDrawable heart =
|
||||||
|
new tw.nekomimi.nekogram.helpers.ShimmerHeartDrawable(dp(18));
|
||||||
|
titleTextView.setRightDrawable2(heart);
|
||||||
|
rightDrawable2ContentDescription = getString(R.string.FoxSponsorBadge);
|
||||||
|
sponsorBadgeShown = true;
|
||||||
|
} else {
|
||||||
|
if (sponsorBadgeShown) {
|
||||||
|
titleTextView.setRightDrawable2(null);
|
||||||
|
rightDrawable2ContentDescription = null;
|
||||||
|
}
|
||||||
|
sponsorBadgeShown = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setSubtitle(CharSequence value) {
|
public void setSubtitle(CharSequence value) {
|
||||||
if (lastSubtitle == null) {
|
if (lastSubtitle == null) {
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,30 @@ public class ShimmerHeartDrawable extends Drawable {
|
||||||
return sharedBitmap;
|
return sharedBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Shared heart artwork, lazily decoded. May be null if decoding failed. */
|
||||||
|
public static Bitmap getSharedBitmap() {
|
||||||
|
return loadBitmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Paint STATIC_PAINT = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw the sponsor heart statically (no shimmer) into {@code dst}. Cheap
|
||||||
|
* enough for list cells and headers that repaint frequently.
|
||||||
|
*/
|
||||||
|
public static void drawStatic(@NonNull Canvas canvas, @NonNull RectF dst, int alpha) {
|
||||||
|
Bitmap bmp = loadBitmap();
|
||||||
|
if (bmp == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (alpha < 255) {
|
||||||
|
STATIC_PAINT.setAlpha(alpha);
|
||||||
|
} else {
|
||||||
|
STATIC_PAINT.setAlpha(255);
|
||||||
|
}
|
||||||
|
canvas.drawBitmap(bmp, null, dst, STATIC_PAINT);
|
||||||
|
}
|
||||||
|
|
||||||
private void buildShine(int w) {
|
private void buildShine(int w) {
|
||||||
// A bright diagonal band, narrow relative to the badge width.
|
// A bright diagonal band, narrow relative to the badge width.
|
||||||
shineWidth = Math.max(1, (int) (w * 0.55f));
|
shineWidth = Math.max(1, (int) (w * 0.55f));
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 211 KiB After Width: | Height: | Size: 177 KiB |