Radial Pattern Background: Simplify styling (#6405)

This commit is contained in:
zubiden 2025-11-06 11:36:46 +01:00 committed by Alexander Zinchuk
parent cf8a933b4c
commit 5e68196c0c
16 changed files with 47 additions and 46 deletions

View File

@ -39,6 +39,9 @@ const GiftTransferPreview = ({
className={styles.backdrop} className={styles.backdrop}
backgroundColors={[giftAttributes.backdrop!.centerColor, giftAttributes.backdrop!.edgeColor]} backgroundColors={[giftAttributes.backdrop!.centerColor, giftAttributes.backdrop!.edgeColor]}
patternIcon={giftAttributes.pattern?.sticker} patternIcon={giftAttributes.pattern?.sticker}
ringsCount={1}
ovalFactor={1}
patternSize={12}
/> />
<AnimatedIconFromSticker <AnimatedIconFromSticker
className={styles.sticker} className={styles.sticker}

View File

@ -141,6 +141,7 @@ const SavedGift = ({
patternSize={14} patternSize={14}
ringsCount={1} ringsCount={1}
ovalFactor={1} ovalFactor={1}
withAdaptiveHeight
/> />
); );
}, [backdrop, pattern]); }, [backdrop, pattern]);

View File

@ -98,6 +98,7 @@ type StateProps = {
theme: ThemeKey; theme: ThemeKey;
isPlain?: boolean; isPlain?: boolean;
savedGifts?: ApiSavedGifts; savedGifts?: ApiSavedGifts;
hasAvatar?: boolean;
}; };
const EMOJI_STATUS_SIZE = 24; const EMOJI_STATUS_SIZE = 24;
@ -130,6 +131,7 @@ const ProfileInfo = ({
theme, theme,
isPlain, isPlain,
savedGifts, savedGifts,
hasAvatar,
onExpand, onExpand,
}: OwnProps & StateProps) => { }: OwnProps & StateProps) => {
const { const {
@ -286,7 +288,7 @@ const ProfileInfo = ({
return; return;
} }
onExpand?.(); if (hasAvatar) onExpand?.();
}); });
function handleSelectFallbackPhoto() { function handleSelectFallbackPhoto() {
@ -576,7 +578,7 @@ const ProfileInfo = ({
size="jumbo" size="jumbo"
peer={peer} peer={peer}
style={createVtnStyle('avatar', true)} style={createVtnStyle('avatar', true)}
onClick={handleMinimizedAvatarClick} onClick={hasAvatar ? handleMinimizedAvatarClick : undefined}
/> />
)} )}
@ -627,6 +629,7 @@ export default memo(withGlobal<OwnProps>(
const hasBackground = selectPeerHasProfileBackground(global, peerId); const hasBackground = selectPeerHasProfileBackground(global, peerId);
const savedGifts = selectPeerSavedGifts(global, peerId); const savedGifts = selectPeerSavedGifts(global, peerId);
const hasAvatar = Boolean(peer?.avatarPhotoId);
return { return {
user, user,
@ -646,6 +649,7 @@ export default memo(withGlobal<OwnProps>(
theme, theme,
isPlain: !hasBackground, isPlain: !hasBackground,
savedGifts, savedGifts,
hasAvatar,
}; };
}, },
)(ProfileInfo)); )(ProfileInfo));

View File

@ -29,6 +29,7 @@ type OwnProps = {
className?: string; className?: string;
clearBottomSector?: boolean; clearBottomSector?: boolean;
yPosition?: number; yPosition?: number;
withAdaptiveHeight?: boolean;
}; };
const BASE_RING_ITEM_COUNT = 8; const BASE_RING_ITEM_COUNT = 8;
@ -40,7 +41,7 @@ const DARK_LUMA_THRESHOLD = 255 * 0.2;
const DEFAULT_PATTERN_SIZE = 20; const DEFAULT_PATTERN_SIZE = 20;
const DEFAULT_RINGS_COUNT = 3; const DEFAULT_RINGS_COUNT = 3;
const DEFAULT_OVAL_FACTOR = 1.4; const DEFAULT_OVAL_FACTOR = 1.61;
const RadialPatternBackground = ({ const RadialPatternBackground = ({
backgroundColors, backgroundColors,
@ -53,6 +54,7 @@ const RadialPatternBackground = ({
clearBottomSector, clearBottomSector,
className, className,
yPosition, yPosition,
withAdaptiveHeight,
}: OwnProps) => { }: OwnProps) => {
const containerRef = useRef<HTMLDivElement>(); const containerRef = useRef<HTMLDivElement>();
const canvasRef = useRef<HTMLCanvasElement>(); const canvasRef = useRef<HTMLCanvasElement>();
@ -125,7 +127,8 @@ const RadialPatternBackground = ({
if (!width || !height) return; if (!width || !height) return;
const centerX = width / 2; const centerX = width / 2;
const centerY = yPosition !== undefined ? yPosition * dpr : height / 2; const centerY = withAdaptiveHeight ? height / 2
: yPosition !== undefined ? yPosition * dpr : width / 2;
ctx.clearRect(0, 0, width, height); ctx.clearRect(0, 0, width, height);
@ -133,8 +136,7 @@ const RadialPatternBackground = ({
x, y, sizeFactor, x, y, sizeFactor,
}) => { }) => {
const renderX = x * Math.max(width, MIN_SIZE * dpr) + centerX; const renderX = x * Math.max(width, MIN_SIZE * dpr) + centerX;
const renderY = yPosition !== undefined ? y * Math.max(width, MIN_SIZE * dpr) + centerY const renderY = y * Math.max(withAdaptiveHeight ? height : width, MIN_SIZE * dpr) + centerY;
: y * Math.max(height, MIN_SIZE * dpr) + centerY;
const size = patternSize * dpr * sizeFactor; const size = patternSize * dpr * sizeFactor;
ctx.drawImage(emojiImage, renderX - size / 2, renderY - size / 2, size, size); ctx.drawImage(emojiImage, renderX - size / 2, renderY - size / 2, size, size);

View File

@ -196,7 +196,7 @@
.uniqueBackground { .uniqueBackground {
position: absolute; position: absolute;
inset: -6rem 0 0 0; inset: 0;
} }
.uniqueValue { .uniqueValue {

View File

@ -17,16 +17,10 @@
font-weight: var(--font-weight-semibold); font-weight: var(--font-weight-semibold);
} }
.backgroundWrapper {
position: absolute;
inset: 0;
overflow: hidden;
border-radius: inherit;
}
.background { .background {
position: absolute; position: absolute;
inset: -1rem 0 0 0; inset: 0;
border-radius: inherit;
} }
.stickerWrapper { .stickerWrapper {

View File

@ -45,16 +45,15 @@ const WebPageUniqueGift = ({
onMouseEnter={!IS_TOUCH_ENV ? markHover : undefined} onMouseEnter={!IS_TOUCH_ENV ? markHover : undefined}
onMouseLeave={!IS_TOUCH_ENV ? unmarkHover : undefined} onMouseLeave={!IS_TOUCH_ENV ? unmarkHover : undefined}
> >
<div className={styles.backgroundWrapper}> <RadialPatternBackground
<RadialPatternBackground className={styles.background}
className={styles.background} backgroundColors={backgroundColors}
backgroundColors={backgroundColors} patternIcon={pattern!.sticker}
patternIcon={pattern!.sticker} centerEmptiness={0.15}
centerEmptiness={0.15} ringsCount={2}
ringsCount={2} ovalFactor={1.2}
ovalFactor={1.2} withAdaptiveHeight
/> />
</div>
<div ref={stickerRef} className={styles.stickerWrapper}> <div ref={stickerRef} className={styles.stickerWrapper}>
<StickerView <StickerView
containerRef={stickerRef} containerRef={stickerRef}

View File

@ -99,7 +99,7 @@ const StarGiftAction = ({
backgroundColors={backgroundColors} backgroundColors={backgroundColors}
patternIcon={pattern.sticker} patternIcon={pattern.sticker}
patternSize={14} patternSize={14}
yPosition={9.5 * REM} yPosition={5 * REM}
clearBottomSector clearBottomSector
/> />
</div> </div>

View File

@ -26,10 +26,10 @@ import styles from './GiftItem.module.scss';
export type OwnProps = { export type OwnProps = {
gift: ApiStarGift; gift: ApiStarGift;
observeIntersection?: ObserveFn;
onClick: (gift: ApiStarGift, target: 'original' | 'resell') => void;
isResale?: boolean; isResale?: boolean;
withTransferBadge?: boolean; withTransferBadge?: boolean;
observeIntersection?: ObserveFn;
onClick: (gift: ApiStarGift, target: 'original' | 'resell') => void;
}; };
type StateProps = { type StateProps = {
@ -39,7 +39,7 @@ type StateProps = {
const GIFT_STICKER_SIZE = 90; const GIFT_STICKER_SIZE = 90;
function GiftItemStar({ function GiftItemStar({
gift, observeIntersection, onClick, isResale, isCurrentUserPremium, withTransferBadge, gift, isResale, isCurrentUserPremium, withTransferBadge, observeIntersection, onClick,
}: OwnProps & StateProps) { }: OwnProps & StateProps) {
const { openGiftInfoModal, openPremiumModal, showNotification, checkCanSendGift } = getActions(); const { openGiftInfoModal, openPremiumModal, showNotification, checkCanSendGift } = getActions();

View File

@ -14,10 +14,6 @@
&.withManageButtons { &.withManageButtons {
--_height: 18.5rem; --_height: 18.5rem;
.radialPattern {
inset: -8rem -5% -5% -5%;
}
.sticker { .sticker {
margin-top: 2.5rem; margin-top: 2.5rem;
} }
@ -52,8 +48,7 @@
.radialPattern { .radialPattern {
position: absolute; position: absolute;
z-index: -1; z-index: -1;
inset: -5rem -5% -5% -5%; inset: 0;
height: calc(var(--height) * 1.05);
} }
.amount { .amount {

View File

@ -14,6 +14,7 @@ import {
import { IS_TOUCH_ENV } from '../../../util/browser/windowEnvironment.ts'; import { IS_TOUCH_ENV } from '../../../util/browser/windowEnvironment.ts';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
import buildStyle from '../../../util/buildStyle'; import buildStyle from '../../../util/buildStyle';
import { REM } from '../../common/helpers/mediaDimensions.ts';
import { useTransitionActiveKey } from '../../../hooks/animations/useTransitionActiveKey'; import { useTransitionActiveKey } from '../../../hooks/animations/useTransitionActiveKey';
import useFlag from '../../../hooks/useFlag'; import useFlag from '../../../hooks/useFlag';
@ -72,6 +73,7 @@ const UniqueGiftHeader = ({
className={styles.radialPattern} className={styles.radialPattern}
backgroundColors={backdropColors} backgroundColors={backdropColors}
patternIcon={patternAttribute.sticker} patternIcon={patternAttribute.sticker}
yPosition={6.5 * REM}
/> />
); );
}, [backdropAttribute, patternAttribute]); }, [backdropAttribute, patternAttribute]);

View File

@ -19,11 +19,11 @@
.radialPattern { .radialPattern {
position: absolute; position: absolute;
z-index: -1; z-index: -1;
top: -3rem; top: -1rem;
inset-inline-start: -1.5rem; inset-inline-start: -1.5rem;
width: calc(100% + 3rem); width: calc(100% + 3rem);
height: calc(100% + 2rem); height: calc(100% + 1rem);
} }
.lockIcon { .lockIcon {

View File

@ -9,6 +9,7 @@ import type { TabState } from '../../../../global/types';
import { selectIsCurrentUserPremium, selectUser } from '../../../../global/selectors'; import { selectIsCurrentUserPremium, selectUser } from '../../../../global/selectors';
import buildClassName from '../../../../util/buildClassName'; import buildClassName from '../../../../util/buildClassName';
import buildStyle from '../../../../util/buildStyle'; import buildStyle from '../../../../util/buildStyle';
import { REM } from '../../../common/helpers/mediaDimensions';
import useCurrentOrPrev from '../../../../hooks/useCurrentOrPrev'; import useCurrentOrPrev from '../../../../hooks/useCurrentOrPrev';
import useLang from '../../../../hooks/useLang'; import useLang from '../../../../hooks/useLang';
@ -73,6 +74,7 @@ const GiftStatusInfoModal = ({
className={styles.radialPattern} className={styles.radialPattern}
backgroundColors={backdropColors} backgroundColors={backdropColors}
patternIcon={patternIcon.customEmoji} patternIcon={patternIcon.customEmoji}
yPosition={6.5 * REM}
/> />
); );
}, [emojiStatus, isOpen, patternIcon]); }, [emojiStatus, isOpen, patternIcon]);

View File

@ -87,6 +87,7 @@ const GiftWithdrawModal = ({ modal, hasPassword, passwordHint }: OwnProps & Stat
<Modal <Modal
isOpen={isOpen} isOpen={isOpen}
title={lang('GiftWithdrawTitle')} title={lang('GiftWithdrawTitle')}
isCondensedHeader
hasCloseButton hasCloseButton
isSlim isSlim
onClose={handleClose} onClose={handleClose}
@ -99,6 +100,9 @@ const GiftWithdrawModal = ({ modal, hasPassword, passwordHint }: OwnProps & Stat
className={styles.backdrop} className={styles.backdrop}
backgroundColors={[giftAttributes.backdrop!.centerColor, giftAttributes.backdrop!.edgeColor]} backgroundColors={[giftAttributes.backdrop!.centerColor, giftAttributes.backdrop!.edgeColor]}
patternIcon={giftAttributes.pattern?.sticker} patternIcon={giftAttributes.pattern?.sticker}
ringsCount={1}
ovalFactor={1}
patternSize={12}
/> />
<AnimatedIconFromSticker <AnimatedIconFromSticker
className={styles.sticker} className={styles.sticker}

View File

@ -74,15 +74,10 @@
.uniqueGiftBackground { .uniqueGiftBackground {
position: absolute; position: absolute;
top: 0; inset: 0;
right: 0;
left: 0;
aspect-ratio: 1 / 1;
border-radius: 0.25rem; border-radius: 0.25rem;
} }
.giftSticker { .giftSticker {
margin-top: 0.25rem; margin: 0.25rem;
margin-inline: 0.25rem;
} }

View File

@ -193,7 +193,7 @@ export function selectPeerProfileColor<T extends GlobalState>(global: T, peer: A
const profileColor = !isCustomPeer ? peer.profileColor : undefined; const profileColor = !isCustomPeer ? peer.profileColor : undefined;
if (profileColor?.type === 'collectible') return undefined; if (profileColor?.type === 'collectible') return undefined;
const key = profileColor?.color || peerColorId; const key = profileColor?.color ?? peerColorId;
if (!key) return undefined; if (key === undefined) return undefined;
return global.peerColors?.profile?.[key]; return global.peerColors?.profile?.[key];
} }