Story: Display forwards count in channels (#4092)
This commit is contained in:
parent
b4291a1505
commit
2edd680802
@ -68,6 +68,7 @@ export function buildApiStory(peerId: string, story: GramJs.TypeStoryItem): ApiT
|
|||||||
...(closeFriends && { isForCloseFriends: true }),
|
...(closeFriends && { isForCloseFriends: true }),
|
||||||
...(noforwards && { noForwards: true }),
|
...(noforwards && { noForwards: true }),
|
||||||
...(views?.viewsCount && { viewsCount: views.viewsCount }),
|
...(views?.viewsCount && { viewsCount: views.viewsCount }),
|
||||||
|
...(views?.forwardsCount && { forwardsCount: views.forwardsCount }),
|
||||||
...(views?.reactionsCount && { reactionsCount: views.reactionsCount }),
|
...(views?.reactionsCount && { reactionsCount: views.reactionsCount }),
|
||||||
...(views?.reactions && { reactions: views.reactions.map(buildReactionCount) }),
|
...(views?.reactions && { reactions: views.reactions.map(buildReactionCount) }),
|
||||||
...(views?.recentViewers && {
|
...(views?.recentViewers && {
|
||||||
|
|||||||
@ -19,6 +19,7 @@ export interface ApiStory {
|
|||||||
isOut?: true;
|
isOut?: true;
|
||||||
noForwards?: boolean;
|
noForwards?: boolean;
|
||||||
viewsCount?: number;
|
viewsCount?: number;
|
||||||
|
forwardsCount?: number;
|
||||||
reactionsCount?: number;
|
reactionsCount?: number;
|
||||||
reactions?: ApiReactionCount[];
|
reactions?: ApiReactionCount[];
|
||||||
recentViewerIds?: string[];
|
recentViewerIds?: string[];
|
||||||
|
|||||||
@ -53,10 +53,17 @@
|
|||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.channelReaction {
|
.footerItem {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-inline-end: 0.5rem;
|
|
||||||
|
&:last-child {
|
||||||
|
padding-inline-end: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
& + & {
|
||||||
|
margin-inline-end: 0.5rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.views {
|
.views {
|
||||||
|
|||||||
@ -32,7 +32,7 @@ const StoryFooter = ({
|
|||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
viewsCount, reactionsCount, isOut, peerId, id: storyId, sentReaction,
|
viewsCount, forwardsCount, reactionsCount, isOut, peerId, id: storyId, sentReaction,
|
||||||
} = story;
|
} = story;
|
||||||
const isChannel = !isUserId(peerId);
|
const isChannel = !isUserId(peerId);
|
||||||
|
|
||||||
@ -121,37 +121,54 @@ const StoryFooter = ({
|
|||||||
round
|
round
|
||||||
onClick={handleForwardClick}
|
onClick={handleForwardClick}
|
||||||
ariaLabel={lang('Forward')}
|
ariaLabel={lang('Forward')}
|
||||||
|
className={styles.footerItem}
|
||||||
>
|
>
|
||||||
<Icon name="forward" />
|
<Icon name="forward" />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{isChannel && (
|
{isChannel && (
|
||||||
<div className={styles.channelReaction}>
|
<>
|
||||||
<Button
|
{Boolean(forwardsCount) && (
|
||||||
round
|
<div className={styles.footerItem}>
|
||||||
className={styles.reactionButton}
|
<Button
|
||||||
color="translucent"
|
round
|
||||||
size="smaller"
|
color="translucent"
|
||||||
onClick={handleLikeStory}
|
size="smaller"
|
||||||
ariaLabel={lang('AccDescrLike')}
|
nonInteractive
|
||||||
>
|
ariaLabel={lang('PublicShares')}
|
||||||
{sentReaction && (
|
>
|
||||||
<ReactionAnimatedEmoji
|
<Icon name="loop" />
|
||||||
key={'documentId' in sentReaction ? sentReaction.documentId : sentReaction.emoticon}
|
</Button>
|
||||||
containerId={containerId}
|
<span>{forwardsCount}</span>
|
||||||
reaction={sentReaction}
|
</div>
|
||||||
withEffectOnly={isSentStoryReactionHeart}
|
)}
|
||||||
/>
|
<div className={styles.footerItem}>
|
||||||
)}
|
<Button
|
||||||
{(!sentReaction || isSentStoryReactionHeart) && (
|
round
|
||||||
<Icon
|
className={styles.reactionButton}
|
||||||
name={isSentStoryReactionHeart ? 'heart' : 'heart-outline'}
|
color="translucent"
|
||||||
className={buildClassName(isSentStoryReactionHeart && styles.reactionHeart)}
|
size="smaller"
|
||||||
/>
|
onClick={handleLikeStory}
|
||||||
)}
|
ariaLabel={lang('AccDescrLike')}
|
||||||
</Button>
|
>
|
||||||
{Boolean(reactionsCount) && (<span>{reactionsCount}</span>)}
|
{sentReaction && (
|
||||||
</div>
|
<ReactionAnimatedEmoji
|
||||||
|
key={'documentId' in sentReaction ? sentReaction.documentId : sentReaction.emoticon}
|
||||||
|
containerId={containerId}
|
||||||
|
reaction={sentReaction}
|
||||||
|
withEffectOnly={isSentStoryReactionHeart}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{(!sentReaction || isSentStoryReactionHeart) && (
|
||||||
|
<Icon
|
||||||
|
name={isSentStoryReactionHeart ? 'heart' : 'heart-outline'}
|
||||||
|
className={buildClassName(isSentStoryReactionHeart && styles.reactionHeart)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
{Boolean(reactionsCount) && (<span>{reactionsCount}</span>)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -55,8 +55,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
opacity: 0.5 !important;
|
|
||||||
cursor: var(--custom-cursor, default);
|
cursor: var(--custom-cursor, default);
|
||||||
|
|
||||||
|
&:not(.non-interactive) {
|
||||||
|
opacity: 0.5 !important;
|
||||||
|
}
|
||||||
|
|
||||||
&:not(.click-allowed) {
|
&:not(.click-allowed) {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,6 +36,7 @@ export type OwnProps = {
|
|||||||
href?: string;
|
href?: string;
|
||||||
download?: string;
|
download?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
nonInteractive?: boolean;
|
||||||
allowDisabledClick?: boolean;
|
allowDisabledClick?: boolean;
|
||||||
noFastClick?: boolean;
|
noFastClick?: boolean;
|
||||||
ripple?: boolean;
|
ripple?: boolean;
|
||||||
@ -91,6 +92,7 @@ const Button: FC<OwnProps> = ({
|
|||||||
href,
|
href,
|
||||||
download,
|
download,
|
||||||
disabled,
|
disabled,
|
||||||
|
nonInteractive,
|
||||||
allowDisabledClick,
|
allowDisabledClick,
|
||||||
noFastClick = color === 'danger',
|
noFastClick = color === 'danger',
|
||||||
ripple,
|
ripple,
|
||||||
@ -110,6 +112,8 @@ const Button: FC<OwnProps> = ({
|
|||||||
|
|
||||||
const [isClicked, setIsClicked] = useState(false);
|
const [isClicked, setIsClicked] = useState(false);
|
||||||
|
|
||||||
|
const isNotInteractive = disabled || nonInteractive;
|
||||||
|
|
||||||
const fullClassName = buildClassName(
|
const fullClassName = buildClassName(
|
||||||
'Button',
|
'Button',
|
||||||
className,
|
className,
|
||||||
@ -118,7 +122,8 @@ const Button: FC<OwnProps> = ({
|
|||||||
round && 'round',
|
round && 'round',
|
||||||
pill && 'pill',
|
pill && 'pill',
|
||||||
fluid && 'fluid',
|
fluid && 'fluid',
|
||||||
disabled && 'disabled',
|
isNotInteractive && 'disabled',
|
||||||
|
nonInteractive && 'non-interactive',
|
||||||
allowDisabledClick && 'click-allowed',
|
allowDisabledClick && 'click-allowed',
|
||||||
isText && 'text',
|
isText && 'text',
|
||||||
isLoading && 'loading',
|
isLoading && 'loading',
|
||||||
@ -132,7 +137,7 @@ const Button: FC<OwnProps> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const handleClick = useLastCallback((e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => {
|
const handleClick = useLastCallback((e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||||
if ((allowDisabledClick || !disabled) && onClick) {
|
if ((allowDisabledClick || !isNotInteractive) && onClick) {
|
||||||
onClick(e);
|
onClick(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +152,7 @@ const Button: FC<OwnProps> = ({
|
|||||||
const handleMouseDown = useLastCallback((e: ReactMouseEvent<HTMLButtonElement>) => {
|
const handleMouseDown = useLastCallback((e: ReactMouseEvent<HTMLButtonElement>) => {
|
||||||
if (!noPreventDefault) e.preventDefault();
|
if (!noPreventDefault) e.preventDefault();
|
||||||
|
|
||||||
if ((allowDisabledClick || !disabled) && onMouseDown) {
|
if ((allowDisabledClick || !isNotInteractive) && onMouseDown) {
|
||||||
onMouseDown(e);
|
onMouseDown(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +178,7 @@ const Button: FC<OwnProps> = ({
|
|||||||
onTransitionEnd={onTransitionEnd}
|
onTransitionEnd={onTransitionEnd}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
{!disabled && ripple && (
|
{!isNotInteractive && ripple && (
|
||||||
<RippleEffect />
|
<RippleEffect />
|
||||||
)}
|
)}
|
||||||
</a>
|
</a>
|
||||||
@ -190,10 +195,10 @@ const Button: FC<OwnProps> = ({
|
|||||||
onContextMenu={onContextMenu}
|
onContextMenu={onContextMenu}
|
||||||
onMouseDown={handleMouseDown}
|
onMouseDown={handleMouseDown}
|
||||||
onMouseUp={onMouseUp}
|
onMouseUp={onMouseUp}
|
||||||
onMouseEnter={onMouseEnter && !disabled ? onMouseEnter : undefined}
|
onMouseEnter={onMouseEnter && !isNotInteractive ? onMouseEnter : undefined}
|
||||||
onMouseLeave={onMouseLeave && !disabled ? onMouseLeave : undefined}
|
onMouseLeave={onMouseLeave && !isNotInteractive ? onMouseLeave : undefined}
|
||||||
onTransitionEnd={onTransitionEnd}
|
onTransitionEnd={onTransitionEnd}
|
||||||
onFocus={onFocus && !disabled ? onFocus : undefined}
|
onFocus={onFocus && !isNotInteractive ? onFocus : undefined}
|
||||||
aria-label={ariaLabel}
|
aria-label={ariaLabel}
|
||||||
aria-controls={ariaControls}
|
aria-controls={ariaControls}
|
||||||
aria-haspopup={hasPopup}
|
aria-haspopup={hasPopup}
|
||||||
@ -208,7 +213,7 @@ const Button: FC<OwnProps> = ({
|
|||||||
<Spinner color={isText ? 'blue' : 'white'} />
|
<Spinner color={isText ? 'blue' : 'white'} />
|
||||||
</div>
|
</div>
|
||||||
) : children}
|
) : children}
|
||||||
{!disabled && ripple && (
|
{!isNotInteractive && ripple && (
|
||||||
<RippleEffect />
|
<RippleEffect />
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user