Star Icon: Simplify styling (#6732)

This commit is contained in:
zubiden 2026-03-05 12:43:25 +01:00 committed by Alexander Zinchuk
parent 08337bf397
commit 97100f899f
65 changed files with 1356 additions and 1053 deletions

2012
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -90,7 +90,7 @@
"eslint-plugin-tt-multitab": "git+https://github.com/zubiden/eslint-plugin-tt-multitab#137cf50",
"eslint-plugin-unused-imports": "^4.3.0",
"fake-indexeddb": "^6.2.5",
"fantasticon": "^4.1.0",
"@twbs/fantasticon": "^3.1.0",
"git-revision-webpack-plugin": "^5.0.0",
"gitlog": "^5.1.0",
"html-webpack-plugin": "^5.6.6",

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="m15.289 23.671-6.001 3.676a1.325 1.325 0 0 1-1.976-1.456l.929-3.657a4.6 4.6 0 0 1 2.466-3.013l6.547-3.143a.613.613 0 0 0-.37-1.157l-7.288 1.262a5.11 5.11 0 0 1-4.153-1.118l-2.302-1.929a1.324 1.324 0 0 1 .748-2.337l7.034-.55c.497-.039.93-.353 1.121-.814l2.714-6.55a1.325 1.325 0 0 1 2.448 0l2.714 6.55c.191.46.624.775 1.121.814l7.073.553a1.325 1.325 0 0 1 .757 2.329l-5.394 4.599c-.38.324-.545.833-.429 1.318l1.658 6.889a1.325 1.325 0 0 1-1.98 1.44l-6.05-3.707c-.425-.26-.96-.26-1.384 0z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="m15.289 23.671-6.001 3.676a1.325 1.325 0 0 1-1.976-1.456l.929-3.657a4.6 4.6 0 0 1 2.466-3.013l6.547-3.143a.613.613 0 0 0-.37-1.157l-7.288 1.262a5.11 5.11 0 0 1-4.153-1.118l-2.302-1.929a1.324 1.324 0 0 1 .748-2.337l7.034-.55c.497-.039.93-.353 1.121-.814l2.714-6.55a1.325 1.325 0 0 1 2.448 0l2.714 6.55c.191.46.624.775 1.121.814l7.073.553a1.325 1.325 0 0 1 .757 2.329l-5.394 4.599c-.38.324-.545.833-.429 1.318l1.658 6.889a1.325 1.325 0 0 1-1.98 1.44l-6.05-3.707c-.425-.26-.96-.26-1.384 0z"/></svg>

Before

Width:  |  Height:  |  Size: 567 B

After

Width:  |  Height:  |  Size: 568 B

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -1668,12 +1668,12 @@
"GiftWithdrawWait_other" = "In {days} days, you'll be able to send this collectible to any TON blockchain address outside Telegram for sale or auction.";
"ChatGroups_one" = "{count} group";
"ChatGroups_other" = "{count} groups";
"StarsAmount" = "⭐️{amount}";
"StarsAmount" = "⭐️{amount}";
"StarsAmountText_one" = "{amount} Star";
"StarsAmountText_other" = "{amount} Stars";
"AllGiftsCategory" = "All gifts";
"PremiumGiftDescription" = "Premium";
"SendPaidReaction" = "Send ⭐️{amount}";
"SendPaidReaction" = "Send ⭐️{amount}";
"StarsPay" = "Confirm and Pay {amount}";
"StarsReactionTerms" = "By sending Stars you agree to the {link}";
"StarsReactionLinkText" = "Terms of Service";
@ -1689,7 +1689,7 @@
"StarsSubscribeInfo" = "By subscribing you agree to the {link}";
"StarsSubscribeInfoLinkText" = "Terms of Service";
"StarsSubscribeInfoLink" = "https://telegram.org/tos/stars";
"StarsPerMonth" = "⭐️{amount}/month";
"StarsPerMonth" = "⭐️{amount}/month";
"StarsBalance" = "Balance";
"OpenApp" = "Open App";
"PopularApps" = "Popular Apps";
@ -2066,7 +2066,7 @@
"ActionGiftStarsTitle_one" = "{amount} Star";
"ActionGiftStarsTitle_other" = "{amount} Stars";
"ActionGiftStarsText" = "Use Stars to unlock content and services on Telegram.";
"TonAmount" = "💎{amount}";
"TonAmount" = "💎{amount}";
"TonAmountText_one" = "{amount} TON";
"TonAmountText_other" = "{amount} TON";
"ActionGiftCostCrypto" = "{cryptoPrice} ({price})";
@ -2125,7 +2125,7 @@
"ButtonUndo" = "Undo";
"ActionPaidOneMessageOutgoing" = "You paid {amount} to send a message";
"ActionPaidOneMessageIncoming" = "{user} paid {amount} to send a message";
"PaneMessagePaidMessageCharge" = "{peer} must pay {amount} for each message to you.";
"PaneMessagePaidMessageCharge" = "**{peer}** must pay **{amount}** for each message to you.";
"ConfirmRemoveMessageFee" = "Yes";
"ConfirmDialogMessageRemoveFee" = "Are you sure you want to allow **{peer}** to message you for free?";
"ConfirmDialogRemoveFeeRefundStars" = "Refund already paid **{amount}**";

View File

@ -98,10 +98,6 @@
.paidStarsBadgeText {
display: inline-flex;
align-items: center;
.star-amount-icon {
margin-inline-start: 0;
}
}
&.cancel {

View File

@ -2482,7 +2482,7 @@ const Composer: FC<OwnProps & StateProps> = ({
fluid
>
<div className="paidStarsBadgeText">
<Icon name="star" className={buildClassName('star-amount-icon', className)} />
<Icon name="star" />
<AnimatedCounter
ref={counterRef}
text={lang.number(starsForAllMessages)}

View File

@ -1,11 +1,13 @@
.root {
--_status-size: 1.25rem;
display: flex !important;
gap: 0.25rem;
align-items: center;
.statusTransition {
width: 1.25em !important;
height: 1.25em !important;
width: var(--_status-size) !important;
height: var(--_status-size) !important;
}
}

View File

@ -1,5 +1,3 @@
import type { FC } from '../../lib/teact/teact';
import type React from '../../lib/teact/teact';
import { memo, useMemo } from '../../lib/teact/teact';
import { getActions } from '../../global';
@ -19,6 +17,7 @@ import {
} from '../../global/helpers';
import { isApiPeerUser } from '../../global/helpers/peers';
import buildClassName from '../../util/buildClassName';
import buildStyle from '../../util/buildStyle';
import { copyTextToClipboard } from '../../util/clipboard';
import stopEvent from '../../util/stopEvent';
import renderText from './helpers/renderText';
@ -56,7 +55,7 @@ type OwnProps = {
observeIntersection?: ObserveFn;
};
const FullNameTitle: FC<OwnProps> = ({
const FullNameTitle = ({
className,
style,
peer,
@ -74,7 +73,7 @@ const FullNameTitle: FC<OwnProps> = ({
withStatusTextColor,
onEmojiStatusClick,
observeIntersection,
}) => {
}: OwnProps) => {
const { showNotification } = getActions();
const oldLang = useOldLang();
@ -125,7 +124,10 @@ const FullNameTitle: FC<OwnProps> = ({
const botVerificationIconId = realPeer?.botVerificationIconId;
return (
<div className={buildClassName('title', styles.root, className)} style={style}>
<div
className={buildClassName('title', styles.root, className)}
style={buildStyle(emojiStatusSize ? `--_status-size: ${emojiStatusSize}px` : undefined, style)}
>
{botVerificationIconId && (
<CustomEmoji
documentId={botVerificationIconId}

View File

@ -27,6 +27,7 @@ import './Avatar.scss';
import appStyles from '../App.module.scss';
import styles from './UiLoader.module.scss';
import starIconPath from '../../assets/icons/star/star.webp';
import lockPreviewPath from '../../assets/lock.png';
import monkeyPath from '../../assets/monkey.svg';
import spoilerMaskPath from '../../assets/spoilers/mask.svg';
@ -84,6 +85,7 @@ const preloadTasks = {
.then(preloadFonts),
preloadAvatars(),
preloadImage(spoilerMaskPath),
preloadImage(starIconPath),
localizationReadyPromise,
]),
authPhoneNumber: () => Promise.all([

View File

@ -35,9 +35,7 @@
}
.star {
margin-inline-start: 0 !important;
margin-inline-end: 0.125rem;
font-size: 0.75rem !important;
font-size: 0.75rem;
}
.priceBadge {
@ -46,15 +44,15 @@
overflow: visible;
height: 1.5rem !important;
height: 1.5rem;
margin-top: 0.625rem;
padding-block: 0.375rem;
font-size: 0.6875rem !important;
font-weight: var(--font-weight-semibold) !important;
font-size: 0.6875rem;
font-weight: var(--font-weight-semibold);
line-height: 1;
background-color: var(--color-light-shadow) !important;
-webkit-backdrop-filter: blur(0.5rem);
background-color: var(--color-light-shadow);
backdrop-filter: blur(0.5rem);
}

View File

@ -191,9 +191,9 @@ const SavedGift = ({
nonInteractive
size="tiny"
withSparkleEffect
noSparkleAnimation
pill
fluid
inline
>
{resellPrice.currency === 'TON'
? formatTonAsIcon(lang, resellPrice.amount, { shouldConvertFromNanos: true, className: styles.star })

View File

@ -1,7 +1,7 @@
.root {
--color-fill: var(--color-primary);
display: flex;
display: inline-block;
flex-shrink: 0;
width: 1rem;
height: 1rem;
@ -10,28 +10,30 @@
.middle {
width: 1.25rem;
height: 1.25rem;
font-size: 1rem !important;
}
.big {
width: 1.5rem;
height: 1.5rem;
font-size: 1rem !important;
}
.adaptive {
display: inline-block;
width: 1em;
height: 1em;
line-height: 1;
vertical-align: text-top;
}
.svg {
.svg, .img {
width: 100%;
height: 100%;
}
.img {
vertical-align: bottom;
}
.clickable {
pointer-events: auto;
cursor: var(--custom-cursor, pointer);

View File

@ -1,4 +1,3 @@
import type { FC } from '../../../lib/teact/teact';
import { memo } from '../../../lib/teact/teact';
import buildClassName from '../../../util/buildClassName';
@ -7,11 +6,14 @@ import useUniqueId from '../../../hooks/useUniqueId';
import styles from './StarIcon.module.scss';
import StarWebp from '../../../assets/icons/star/star.webp';
type OwnProps = {
type?: 'gold' | 'premium' | 'regular';
size?: 'small' | 'middle' | 'big' | 'adaptive';
className?: string;
style?: string;
forceVector?: boolean;
onClick?: VoidFunction;
};
@ -19,20 +21,21 @@ type OwnProps = {
const STAR_PATH = 'M6.63869 12.1902L3.50621 14.1092C3.18049 14.3087 2.75468 14.2064 2.55515 13.8807C2.45769 13.7216 2.42864 13.5299 2.47457 13.3491L2.95948 11.4405C3.13452 10.7515 3.60599 10.1756 4.24682 9.86791L7.6642 8.22716C7.82352 8.15067 7.89067 7.95951 7.81418 7.80019C7.75223 7.67116 7.61214 7.59896 7.47111 7.62338L3.66713 8.28194C2.89387 8.41581 2.1009 8.20228 1.49941 7.69823L0.297703 6.69116C0.00493565 6.44581 -0.0335059 6.00958 0.211842 5.71682C0.33117 5.57442 0.502766 5.48602 0.687982 5.47153L4.35956 5.18419C4.61895 5.16389 4.845 4.99974 4.94458 4.75937L6.36101 1.3402C6.5072 0.987302 6.91179 0.819734 7.26469 0.965925C7.43413 1.03612 7.56876 1.17075 7.63896 1.3402L9.05539 4.75937C9.15496 4.99974 9.38101 5.16389 9.6404 5.18419L13.3322 5.47311C13.713 5.50291 13.9975 5.83578 13.9677 6.2166C13.9534 6.39979 13.8667 6.56975 13.7269 6.68896L10.9114 9.08928C10.7131 9.25826 10.6267 9.52425 10.6876 9.77748L11.5532 13.3733C11.6426 13.7447 11.414 14.1182 11.0427 14.2076C10.8642 14.2506 10.676 14.2208 10.5195 14.1249L7.36128 12.1902C7.13956 12.0544 6.8604 12.0544 6.63869 12.1902Z';
/* eslint-enable @stylistic/max-len */
const StarIcon: FC<OwnProps> = ({
const StarIcon = ({
type = 'regular',
size = 'small',
className,
style,
forceVector,
onClick,
}) => {
}: OwnProps) => {
const randomId = useUniqueId();
const validSvgRandomId = `svg-${randomId}`; // ID must start with a letter
const renderIcon = () => {
switch (type) {
case 'gold':
return <GoldStarIcon randomId={validSvgRandomId} />;
return <GoldStarIcon randomId={validSvgRandomId} asVector={forceVector} />;
case 'premium':
return <PremiumStarIcon randomId={validSvgRandomId} />;
default:
@ -57,7 +60,13 @@ const StarIcon: FC<OwnProps> = ({
);
};
function GoldStarIcon({ randomId }: { randomId: string }) {
function GoldStarIcon({ randomId, asVector }: { randomId: string; asVector?: boolean }) {
if (!asVector) {
return (
<img src={StarWebp} alt="" className={styles.img} />
);
}
const mask1Id = `${randomId}-mask1`;
const mask2Id = `${randomId}-mask2`;
const gradient1Id = `${randomId}-gradient1`;

View File

@ -315,12 +315,6 @@
color: #fff;
}
}
.star-amount-icon {
margin-inline: 0;
line-height: initial;
vertical-align: text-top;
}
}
&[dir="rtl"] {

View File

@ -130,6 +130,7 @@ const PublicPostsSearchLauncher = ({
color="primary"
disabled={!searchQuery}
noForcedUpperCase
inline
onClick={handlePaidSearchClick}
>
{lang('PublicPostsSearchForStars', {

View File

@ -88,8 +88,3 @@
align-items: center;
font-weight: var(--font-weight-medium);
}
.starIcon {
margin-inline-start: 0 !important;
margin-inline-end: 0.0625rem !important;
}

View File

@ -66,7 +66,6 @@ function RequirementToContactMessage({
paidMessagesStars,
{
asFont: true,
className: styles.starIcon,
containerClassName: styles.starIconContainer,
}),
}, {

View File

@ -86,11 +86,6 @@
}
}
.sendButtonStar {
margin-inline-start: 0 !important;
margin-inline-end: 0.125rem !important;
}
.attachments {
overflow: auto;
display: flex;

View File

@ -638,7 +638,6 @@ const AttachmentModal = ({
lang,
attachmentsLength * paidMessagesStars,
{
className: styles.sendButtonStar,
asFont: true,
},
) : lang('Send');
@ -766,6 +765,7 @@ const AttachmentModal = ({
ref={mainButtonRef}
className={styles.send}
size="smaller"
inline
onClick={handleSendClick}
onContextMenu={canShowCustomSendMenu ? handleContextMenu : undefined}
>

View File

@ -15,7 +15,7 @@ export default function renderKeyboardButtonText(lang: LangFn, button: ApiKeyboa
}
if (button.type === 'buy') {
return replaceWithTeact(button.text, STARS_ICON_PLACEHOLDER, <Icon className="star-currency-icon" name="star" />);
return replaceWithTeact(button.text, STARS_ICON_PLACEHOLDER, <Icon name="star" />);
}
return renderText(button.text);

View File

@ -8,11 +8,6 @@
padding-block: 0.125rem;
overflow-wrap: anywhere;
:global(.star-amount-icon) {
margin-inline: 0 !important;
vertical-align: text-bottom;
}
}
.contentBox {

View File

@ -13,12 +13,6 @@
position: relative;
margin-top: 0.5rem;
.description-text {
.star-amount-icon {
margin-inline-start: 0;
}
}
&.has-image {
.content-inner:not(.forwarded-message) & {
margin: 0.5rem -0.5rem -0.375rem;

View File

@ -33,16 +33,6 @@
white-space: nowrap;
}
.message-price-stars-container {
display: inline-flex;
align-items: center;
}
.message-price-star-icon {
margin-inline-start: 0 !important;
margin-inline-end: 0.0625rem !important;
}
.message-price {
display: inline-flex;
align-items: center;

View File

@ -198,8 +198,6 @@ const MessageMeta: FC<OwnProps> = ({
{
formatStarsAsIcon(lang, paidMessageStars, {
asFont: true,
className: 'message-price-star-icon',
containerClassName: 'message-price-stars-container',
})
}
</span>

View File

@ -16,23 +16,10 @@
}
.message {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 0.375rem;
font-size: 1rem;
}
.messageStars {
display: inline-flex;
align-items: center;
padding-inline: 0.25rem;
font-weight: var(--font-weight-medium);
}
.messageStarIcon {
margin-inline-start: 0 !important;
margin-inline-end: 0.125rem !important;
}

View File

@ -16,13 +16,11 @@ import {
import { formatStarsAsIcon } from '../../../util/localization/format';
import useLang from '../../../hooks/useLang';
// import useTimeout from '../../../hooks/schedulers/useTimeout';
import useLastCallback from '../../../hooks/useLastCallback';
import useHeaderPane, { type PaneState } from '../hooks/useHeaderPane';
import Button from '../../ui/Button';
// import CustomEmoji from '../../common/CustomEmoji';
import styles from './PaidMessageChargePane.module.scss';
type OwnProps = {
@ -65,7 +63,7 @@ const PaidMessageChargePane: FC<OwnProps & StateProps> = ({
peer: peerName,
amount: formatStarsAsIcon(lang,
chargedPaidMessageStars,
{ asFont: true, className: styles.messageStarIcon, containerClassName: styles.messageStars }),
{ asFont: true }),
}, {
withMarkdown: true,
withNodes: true,
@ -73,9 +71,9 @@ const PaidMessageChargePane: FC<OwnProps & StateProps> = ({
return (
<div ref={ref} className={styles.root}>
<div className={styles.message}>
<span className={styles.message}>
{message}
</div>
</span>
<Button
isText
noForcedUpperCase

View File

@ -21,7 +21,7 @@
min-height: 6.25rem;
margin-top: calc(-2.25rem * 2); // Centered minus center shift
background-image: url('../../../assets/icons/GoldStar.svg');
background-image: url('../../../assets/icons/star/GoldStar.svg');
background-repeat: no-repeat;
background-position: center;
background-size: contain;
@ -41,7 +41,7 @@
width: 100%;
height: 100%;
background-image: url('../../../assets/icons/GoldStarFill.svg');
background-image: url('../../../assets/icons/star/GoldStarFill.svg');
background-repeat: no-repeat;
background-position: center;
background-size: contain;

View File

@ -132,12 +132,6 @@
margin-bottom: 1rem;
}
.main-button {
display: flex;
font-size: 1rem;
font-weight: var(--font-weight-semibold);
}
.buttonSubtitle {
display: block;
font-size: 0.8125rem;

View File

@ -409,10 +409,10 @@ function GiftComposer({
</div>
)}
<Button
className={styles.mainButton}
size={auctionTimeLeft ? undefined : 'smaller'}
onClick={handleMainButtonClick}
isLoading={isPaymentFormLoading}
inline
noForcedUpperCase
>
{giftAuction ? (

View File

@ -75,19 +75,17 @@
.buy {
margin-top: 0.625rem;
font-size: 0.6875rem !important;
font-size: 0.75rem !important;
font-weight: var(--font-weight-semibold) !important;
line-height: 1;
}
.transferBadge {
font-size: 0.8125rem !important;
font-size: 0.8125rem;
}
.star {
margin-inline-start: 0 !important;
margin-inline-end: 0.125rem;
font-size: 0.75rem !important;
font-size: inherit;
}
.auction,
@ -111,12 +109,6 @@
color: var(--color-stars);
}
.starsPriceIcon {
margin-inline-start: 0 !important;
margin-inline-end: 0.125rem !important;
vertical-align: text-top !important;
}
.radialPattern {
position: absolute;
inset: 0;

View File

@ -89,7 +89,7 @@ function GiftItemPremium({
{optionByStars && (
<div className={styles.starsPriceBlock}>
{lang('GiftPremiumStarsPrice', {
stars: (formatStarsAsIcon(lang, optionByStars.amount, { className: styles.starsPriceIcon })),
stars: (formatStarsAsIcon(lang, optionByStars.amount)),
}, { withNodes: true, withMarkdown: true })}
</div>
)}

View File

@ -222,6 +222,7 @@ function GiftItemStar({
withSparkleEffect={isVisible && !withTransferBadge}
pill
fluid
inline
>
{badgeContent}
</Button>

View File

@ -72,10 +72,6 @@
}
.amount {
display: flex;
gap: 0.25rem;
align-items: center;
margin-bottom: 0.125rem;
font-size: 1.125rem;

View File

@ -10,6 +10,7 @@ import type {
ApiTypeCurrencyAmount,
} from '../../../api/types';
import { NNBSP } from '../../../config.ts';
import {
formatStarsTransactionAmount,
} from '../../../global/helpers/payments';
@ -148,13 +149,12 @@ const UniqueGiftHeader = ({
/>
)}
{resellPrice && (
<p className={styles.amount}>
<span>
{formatStarsTransactionAmount(lang, resellPrice)}
</span>
{resellPrice.currency === 'XTR' && <StarIcon type="gold" size="middle" />}
{resellPrice.currency === 'TON' && <Icon name="toncoin" />}
</p>
<span className={styles.amount}>
{formatStarsTransactionAmount(lang, resellPrice)}
{NNBSP}
{resellPrice.currency === 'XTR' && <StarIcon type="gold" size="adaptive" />}
{resellPrice.currency === 'TON' && <Icon className="in-text-icon" name="toncoin" />}
</span>
)}
{children}
</div>

View File

@ -102,7 +102,7 @@ function ActiveAuctionItem({ auction }: { auction: ApiStarGiftAuctionState }) {
</div>
<div className="subtitle">
{lang('GiftAuctionBidPosition', {
amount: formatStarsAsIcon(lang, userState.bidAmount!, { noStyles: true }),
amount: formatStarsAsIcon(lang, userState.bidAmount!),
position: lang.number(bidPosition),
}, {
withNodes: true,

View File

@ -60,7 +60,6 @@
.infoCardValue {
display: flex;
gap: 0.25rem;
align-items: center;
justify-content: center;
@ -197,19 +196,11 @@
}
.bidderAmount {
display: flex;
gap: 0.25rem;
align-items: center;
font-size: 0.9375rem;
font-weight: var(--font-weight-medium);
color: var(--color-text-secondary);
}
.buttonStar {
margin-inline-start: 0 !important;
}
.giftSticker {
margin-right: 0.25rem;
}

View File

@ -200,8 +200,7 @@ const GiftAuctionBidModal = ({
<div className={styles.infoCards}>
<div className={styles.infoCard}>
<div className={styles.infoCardValue}>
<StarIcon type="gold" size="adaptive" />
{lang.number(currentMinBid)}
{formatStarsAsIcon(lang, currentMinBid, { withWrapper: true })}
</div>
<div className={styles.infoCardLabel}>{lang('GiftAuctionMinimumBid')}</div>
</div>
@ -269,8 +268,7 @@ const GiftAuctionBidModal = ({
{currentUserPeer && <FullNameTitle peer={currentUserPeer} className={styles.bidderName} />}
</div>
<div className={styles.bidderAmount}>
<StarIcon type="gold" size="adaptive" />
{lang.number(selectedBidAmount)}
{formatStarsAsIcon(lang, selectedBidAmount)}
</div>
</div>
</div>
@ -304,8 +302,7 @@ const GiftAuctionBidModal = ({
</Transition>
{amount !== undefined && (
<div className={styles.bidderAmount}>
<StarIcon type="gold" size="adaptive" />
{lang.number(amount)}
{formatStarsAsIcon(lang, amount)}
</div>
)}
</div>
@ -363,11 +360,11 @@ const GiftAuctionBidModal = ({
{renderUserBid()}
{renderTopWinners()}
<Button noForcedUpperCase onClick={handleSubmit}>
<Button noForcedUpperCase inline onClick={handleSubmit}>
{lang(userState?.bidAmount ? 'GiftAuctionAddToBid' : 'GiftAuctionPlaceBidButton', {
amount: formatStarsAsIcon(lang,
userState?.bidAmount ? selectedBidAmount - userState.bidAmount : selectedBidAmount,
{ asFont: true, className: styles.buttonStar }),
{ asFont: true }),
}, { withNodes: true })}
</Button>
<ConfirmDialog

View File

@ -157,9 +157,6 @@
}
.footerHint {
display: flex;
align-items: center;
font-size: 0.75rem;
line-height: 1.125rem;
color: var(--color-white);

View File

@ -306,17 +306,17 @@ const GiftInfoModal = ({
if (canBuyGift) {
return (
<Button className={styles.buyButton} onClick={handleBuyGift}>
<div>
<span>
{lang('ButtonBuyGift', {
stars: formatCurrency(lang, resellPrice.amount, resellPrice.currency, { asFontIcon: true }),
}, { withNodes: true })}
</div>
</span>
{resellPrice?.currency === TON_CURRENCY_CODE && Boolean(resellPriceInStars) && (
<div className={styles.footerHint}>
<span className={styles.footerHint}>
{lang('GiftBuyEqualsTo', {
stars: formatStarsAsIcon(lang, resellPriceInStars.amount, { asFont: true }),
}, { withNodes: true })}
</div>
</span>
)}
</Button>
);
@ -614,7 +614,7 @@ const GiftInfoModal = ({
tableData.push([
lang('GiftInfoValue'),
<div className={styles.giftValue}>
{formatStarsAsIcon(lang, starsValue, { className: styles.starAmountIcon })}
{formatStarsAsIcon(lang, starsValue, { className: styles.starAmountIcon, withWrapper: true })}
{canManage && hasConvertOption && Boolean(starsToConvert) && (
<BadgeButton onClick={openConvertConfirm}>
{lang('GiftInfoConvert', { amount: starsToConvert }, { pluralValue: starsToConvert })}

View File

@ -167,7 +167,7 @@ const GiftResalePriceComposerModal = ({
{lang('OnlyAcceptTONDescription')}
</div>
<Button noForcedUpperCase disabled={!isPriceCorrect} onClick={handleSellGift}>
<Button inline noForcedUpperCase disabled={!isPriceCorrect} onClick={handleSellGift}>
{isPriceCorrect && lang('ButtonSellGift', {
stars: isPriceInTon ? formatTonAsIcon(lang, price)
: formatStarsAsIcon(lang, price, { asFont: true }),

View File

@ -144,7 +144,7 @@ const GiftUpgradeModal = ({ modal, recipient }: OwnProps & StateProps) => {
const formattedPriceElement = useMemo(() => (upgradeStars ? (
<span>
<Icon name="star" className="star-amount-icon" />
<Icon name="star" />
<AnimatedCounter text={lang.number(upgradeStars)} />
</span>
) : undefined), [lang, upgradeStars]);

View File

@ -141,10 +141,6 @@
background-image: var(--stars-gradient);
}
.buttonStar {
margin-inline-start: 0.25rem;
}
.topPeer {
overflow: hidden;
flex-basis: 0;

View File

@ -351,12 +351,13 @@ const PaidReactionModal = ({
label={oldLang('StarsReactionShowMeInTopSenders')}
/>
<Button
inline
onClick={handleSend}
>
{lang('SendPaidReaction', { amount: starsAmount }, {
withNodes: true,
specialReplacement: {
[STARS_ICON_PLACEHOLDER]: <Icon className={styles.buttonStar} name="star" />,
[STARS_ICON_PLACEHOLDER]: <Icon name="star" className="in-text-icon" />,
},
})}
</Button>

View File

@ -3,7 +3,7 @@ import { getActions } from '../../../global';
import type { ApiTypeCurrencyAmount } from '../../../api/types';
import { STARS_CURRENCY_CODE, TON_CURRENCY_CODE } from '../../../config';
import { NNBSP, STARS_CURRENCY_CODE, TON_CURRENCY_CODE } from '../../../config';
import { formatStarsAmount } from '../../../global/helpers/payments';
import buildClassName from '../../../util/buildClassName';
import { convertCurrencyFromBaseUnit } from '../../../util/formatCurrency';
@ -32,9 +32,12 @@ const BalanceBlock = ({ balance, className, withAddButton }: OwnProps) => {
const renderStarsAmount = () => {
return (
<>
<StarIcon type="gold" size="middle" />
{balance !== undefined && balance.currency === STARS_CURRENCY_CODE
? formatStarsAmount(lang, balance) : '…'}
<span>
<StarIcon type="gold" size="adaptive" />
{NNBSP}
{balance !== undefined && balance.currency === STARS_CURRENCY_CODE
? formatStarsAmount(lang, balance) : '…'}
</span>
{withAddButton && (
<BadgeButton
className={styles.addStarsButton}
@ -52,10 +55,11 @@ const BalanceBlock = ({ balance, className, withAddButton }: OwnProps) => {
const renderTonAmount = () => {
return (
<>
<span>
<Icon name="toncoin" />
{NNBSP}
{balance !== undefined ? convertCurrencyFromBaseUnit(balance.amount, balance.currency) : '…'}
</>
</span>
);
};

View File

@ -284,12 +284,6 @@
margin-top: 1rem;
}
.paymentButtonStar {
--color-fill: white !important;
margin-inline-start: 0;
}
.transactions, .subscriptions {
display: flex;
flex-direction: column;

View File

@ -198,9 +198,9 @@ const StarPaymentModal = ({
<div className={styles.description}>
{renderText(descriptionText, ['simple_markdown', 'emoji'])}
</div>
<Button className={styles.paymentButton} onClick={handlePayment} isLoading={isLoading}>
<Button className={styles.paymentButton} inline onClick={handlePayment} isLoading={isLoading}>
{lang(isBotSubscription ? 'StarsSubscribeBotButtonMonth' : 'StarsPay', {
amount: formatStarsAsIcon(lang, amount!, { asFont: true, className: styles.paymentButtonStar }),
amount: formatStarsAsIcon(lang, amount!, { asFont: true }),
}, {
withNodes: true,
})}

View File

@ -30,7 +30,7 @@ import StarTopupOptionList from '../StarTopupOptionList';
import styles from './StarsGiftModal.module.scss';
import StarLogo from '../../../../assets/icons/GoldStar.svg';
import StarLogo from '../../../../assets/icons/star/GoldStar.svg';
import StarsBackground from '../../../../assets/stars-bg.png';
export type OwnProps = {

View File

@ -30,10 +30,7 @@
}
.statusPricing {
display: flex;
flex-shrink: 0;
gap: 0.25rem;
align-items: center;
}
.amount {

View File

@ -6,6 +6,7 @@ import type {
} from '../../../../api/types';
import type { GlobalState } from '../../../../global/types';
import { NNBSP } from '../../../../config';
import { getPeerTitle } from '../../../../global/helpers/peers';
import { selectPeer } from '../../../../global/selectors';
import { formatDateToString } from '../../../../util/dates/dateFormat';
@ -84,6 +85,7 @@ const StarsSubscriptionItem = ({ subscription }: OwnProps) => {
<>
<div className={styles.statusPricing}>
<StarIcon className={styles.star} type="gold" size="adaptive" />
{NNBSP}
<span className={styles.amount}>
{formatInteger(pricing.amount)}
</span>

View File

@ -30,8 +30,6 @@
}
.amount {
display: flex;
align-items: center;
color: var(--color-text-secondary);
text-align: center;
}
@ -64,10 +62,6 @@
@include mixins.filter-outline(1px, var(--color-background));
}
.amountStar {
font-size: 1.25rem;
}
.secondary {
color: var(--color-text-secondary);
}

View File

@ -152,16 +152,16 @@ const StarsSubscriptionModal: FC<OwnProps & StateProps> = ({
centerShift={AVATAR_SPARKLES_CENTER_SHIFT}
/>
<h1 className={styles.title}>{title || oldLang('StarsSubscriptionTitle')}</h1>
<p className={styles.amount}>
<span className={styles.amount}>
{lang('StarsPerMonth', {
amount: pricing.amount,
}, {
withNodes: true,
specialReplacement: {
[STARS_ICON_PLACEHOLDER]: <StarIcon className={styles.amountStar} size="adaptive" type="gold" />,
[STARS_ICON_PLACEHOLDER]: <StarIcon size="adaptive" type="gold" />,
},
})}
</p>
</span>
</div>
);

View File

@ -23,10 +23,7 @@
}
.stars {
display: flex;
flex-shrink: 0;
gap: 0.25rem;
align-items: center;
}
.amount {

View File

@ -8,7 +8,7 @@ import type {
import type { GlobalState } from '../../../../global/types';
import type { CustomPeer } from '../../../../types';
import { STARS_CURRENCY_CODE, TON_CURRENCY_CODE } from '../../../../config';
import { NNBSP, STARS_CURRENCY_CODE, TON_CURRENCY_CODE } from '../../../../config';
import { buildStarsTransactionCustomPeer,
formatStarsTransactionAmount,
shouldUseCustomPeer } from '../../../../global/helpers/payments';
@ -187,15 +187,18 @@ const StarsTransactionItem = ({ transaction, className }: OwnProps) => {
{data.status && ` — (${data.status})`}
</p>
</div>
<div className={styles.stars}>
<span className={styles.stars}>
<span
className={buildClassName(styles.amount, amountColorClass)}
>
{formatStarsTransactionAmount(lang, amount)}
</span>
{amount.currency === STARS_CURRENCY_CODE && <StarIcon className={styles.star} type="gold" size="adaptive" />}
{amount.currency === TON_CURRENCY_CODE && <Icon name="toncoin" className={amountColorClass} />}
</div>
{NNBSP}
{amount.currency === STARS_CURRENCY_CODE && <StarIcon type="gold" size="adaptive" />}
{amount.currency === TON_CURRENCY_CODE && (
<Icon name="toncoin" className={buildClassName('in-text-icon', amountColorClass)} />
)}
</span>
</div>
);
};

View File

@ -30,10 +30,6 @@
}
.amount {
display: flex;
gap: 0.25rem;
align-items: center;
font-size: 1rem;
font-weight: var(--font-weight-medium);
line-height: 1.325;
@ -71,6 +67,7 @@
.refunded {
margin-bottom: 0;
margin-inline-start: 0.125rem;
padding: 0.25em 0.5em;
border-radius: var(--border-radius-messages-small);
@ -81,11 +78,6 @@
background-color: rgba(var(--color-text-green-rgb), 0.2);
}
.totalStars {
display: inline-flex;
align-items: center;
}
.starIcon {
margin-inline-start: 0 !important;
line-height: 1 !important;

View File

@ -9,7 +9,7 @@ import type {
import type { TabState } from '../../../../global/types';
import { MediaViewerOrigin } from '../../../../types';
import { STARS_CURRENCY_CODE } from '../../../../config';
import { NNBSP, STARS_CURRENCY_CODE } from '../../../../config';
import { getMessageLink } from '../../../../global/helpers';
import {
buildStarsTransactionCustomPeer,
@ -188,18 +188,19 @@ const StarsTransactionModal: FC<OwnProps & StateProps> = ({
)}
{Boolean(title) && <h1 className={styles.title}>{title}</h1>}
<p className={styles.description}>{description}</p>
<p className={styles.amount}>
<span
className={buildClassName(styles.amount, amountColorClass)}
>
<span className={styles.amount}>
<span className={amountColorClass}>
{formatStarsTransactionAmount(lang, amount)}
</span>
{amount.currency === STARS_CURRENCY_CODE && <StarIcon type="gold" size="middle" />}
{amount.currency === 'TON' && <Icon name="toncoin" className={amountColorClass} />}
{NNBSP}
{amount.currency === STARS_CURRENCY_CODE && <StarIcon type="gold" size="adaptive" />}
{amount.currency === 'TON' && (
<Icon name="toncoin" className={buildClassName('in-text-icon', amountColorClass)} />
)}
{transaction.isRefund && (
<p className={styles.refunded}>{lang('Refunded')}</p>
)}
</p>
</span>
{Boolean(transaction.paidMessages && transaction.starRefCommision && paidMessageCommission) && (
<p className={styles.description}>
{lang(
@ -272,7 +273,7 @@ const StarsTransactionModal: FC<OwnProps & StateProps> = ({
lang('PaidMessageTransactionTotal'),
formatStarsAsIcon(lang,
transaction.amount.amount / ((100 - transaction.starRefCommision) / 100),
{ asFont: false, className: styles.starIcon, containerClassName: styles.totalStars }),
{ asFont: false, className: styles.starIcon, withWrapper: true }),
]);
}

View File

@ -283,6 +283,7 @@ const SuggestMessageModal = ({
className={styles.offerButton}
onClick={handleOffer}
disabled={isDisabled}
inline
>
{isInSuggestChangesMode ? lang('ButtonUpdateTerms')
: currencyAmount ? lang('ButtonOfferAmount', {

View File

@ -80,6 +80,7 @@ const ConfirmDialog: FC<OwnProps> = ({
<Button
className="confirm-dialog-button"
isText
inline
onClick={confirmHandler}
color={confirmIsDestructive ? 'danger' : 'primary'}
disabled={isConfirmDisabled}

View File

@ -38,10 +38,6 @@
}
}
.starIcon {
margin-inline-start: 0 !important;
}
.tonInUsdDescription {
color: var(--color-text-secondary);
}

View File

@ -18,9 +18,9 @@ import Link from './Link';
import styles from './ModalStarBalanceBar.module.scss';
export type OwnProps = {
onCloseAnimationEnd?: () => void;
isModalOpen?: true;
currency?: 'TON' | 'XTR';
onCloseAnimationEnd?: () => void;
};
export type StateProps = {
@ -73,18 +73,14 @@ function ModalStarBalanceBar({
<div>
{isTonMode ? (
lang('ModalStarsBalanceBarDescription', {
stars: formatTonAsIcon(lang, convertTonFromNanos(currentBalance.amount), {
className: styles.starIcon,
}),
stars: formatTonAsIcon(lang, convertTonFromNanos(currentBalance.amount)),
}, {
withNodes: true,
withMarkdown: true,
})
) : (
lang('ModalStarsBalanceBarDescription', {
stars: formatStarsAsIcon(lang, formatStarsAmount(lang, currentBalance as ApiStarsAmount), {
className: styles.starIcon,
}),
stars: formatStarsAsIcon(lang, formatStarsAmount(lang, currentBalance as ApiStarsAmount)),
}, {
withNodes: true,
withMarkdown: true,

View File

@ -26,7 +26,7 @@ export const DEBUG = process.env.APP_ENV !== 'production';
export const DEBUG_MORE = false;
export const DEBUG_LOG_FILENAME = 'tt-log.json';
export const STRICTERDOM_ENABLED = DEBUG;
export const FORCE_FALLBACK_LANG = false;
export const FORCE_FALLBACK_LANG = DEBUG;
export const BETA_CHANGELOG_URL = 'https://telegra.ph/WebA-Beta-03-20';
@ -141,6 +141,9 @@ export const DEFAULT_MESSAGE_TEXT_SIZE_PX = 16;
export const IOS_DEFAULT_MESSAGE_TEXT_SIZE_PX = 17;
export const MACOS_DEFAULT_MESSAGE_TEXT_SIZE_PX = 15;
export const NBSP = '\u00A0';
export const NNBSP = '\u202F';
export const FOLDERS_POSITION_TOP = 'top';
export const FOLDERS_POSITION_LEFT = 'left';
export const FOLDERS_POSITION_DEFAULT = FOLDERS_POSITION_TOP;

View File

@ -347,18 +347,9 @@ body:not(.is-ios) {
opacity: 0;
}
.star-currency-icon {
font-size: 1rem !important;
vertical-align: text-top;
}
// Increase specificity to override the default icon style
.ton-amount-icon.ton-amount-icon,
.star-amount-icon.star-amount-icon {
margin-inline-start: 0.375em; // Prevent sticking to the text without using `white-space: pre`
margin-inline-end: 0.2em; // Prevent sticking to the text without using `white-space: pre`
line-height: inherit; // Vertical centring
vertical-align: text-top; // As regular text
.in-text-icon {
line-height: inherit;
vertical-align: bottom;
}
.next-arrow-icon {

View File

@ -27,13 +27,16 @@ export function formatTonAsIcon(
lang: LangFn,
amount: number | string,
options?: {
className?: string; containerClassName?: string; shouldConvertFromNanos?: boolean;
className?: string;
containerClassName?: string;
withWrapper?: boolean;
shouldConvertFromNanos?: boolean;
}) {
const { className, containerClassName, shouldConvertFromNanos } = options || {};
const { className, containerClassName, withWrapper, shouldConvertFromNanos } = options || {};
const formattedAmount = shouldConvertFromNanos ? convertTonFromNanos(Number(amount)) : amount;
const icon = <Icon name="toncoin" className={buildClassName('ton-amount-icon', className)} />;
const icon = <Icon name="toncoin" className={buildClassName('in-text-icon', className)} />;
if (containerClassName) {
if (containerClassName || withWrapper) {
return (
<span className={containerClassName}>
{lang('TonAmount', { amount: formattedAmount }, {
@ -58,14 +61,14 @@ export function formatStarsAsIcon(lang: LangFn, amount: number | string, options
asFont?: boolean;
className?: string;
containerClassName?: string;
noStyles?: boolean;
withWrapper?: boolean;
}) {
const { asFont, className, containerClassName, noStyles } = options || {};
const { asFont, className, containerClassName, withWrapper } = options || {};
const icon = asFont
? <Icon name="star" className={buildClassName(!noStyles && 'star-amount-icon', className)} />
: <StarIcon type="gold" className={buildClassName(!noStyles && 'star-amount-icon', className)} size="adaptive" />;
? <Icon name="star" className={buildClassName('in-text-icon', className)} />
: <StarIcon type="gold" className={className} size="adaptive" />;
if (containerClassName) {
if (containerClassName || withWrapper) {
return (
<span className={containerClassName}>
{lang('StarsAmount', { amount }, {