Story: Fix unsupported display (#6452)

This commit is contained in:
zubiden 2025-11-11 14:37:40 +01:00 committed by Alexander Zinchuk
parent 4180270eb5
commit 96b41e8663
7 changed files with 52 additions and 19 deletions

View File

@ -2315,3 +2315,4 @@
"UserNoteHint" = "only visible to you";
"EditUserNoteHint" = "Notes are only visible to you.";
"AriaStoryTogglerOpen" = "Open Story List";
"StoryUnsupported" = "This story is not supported in Telegram Web A. Try viewing it in the Telegram app.";

View File

@ -22,7 +22,7 @@
object-fit: cover;
}
.expiredIcon {
.mainIcon {
font-size: 1.25rem;
line-height: 0.9375rem;
vertical-align: -0.1875rem;

View File

@ -1,4 +1,3 @@
import type React from '../../lib/teact/teact';
import {
memo, useCallback, useEffect, useRef,
} from '../../lib/teact/teact';
@ -14,6 +13,7 @@ import stopEvent from '../../util/stopEvent';
import { preventMessageInputBlurWithBubbling } from '../middle/helpers/preventMessageInputBlur';
import useContextMenuHandlers from '../../hooks/useContextMenuHandlers';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useMedia from '../../hooks/useMedia';
import useOldLang from '../../hooks/useOldLang';
@ -47,7 +47,8 @@ function MediaStory({
showNotification,
} = getActions();
const lang = useOldLang();
const lang = useLang();
const oldLang = useOldLang();
const containerRef = useRef<HTMLDivElement>();
const getTriggerElement = useLastCallback(() => containerRef.current);
@ -59,6 +60,7 @@ function MediaStory({
const isFullyLoaded = story && 'content' in story;
const isOwn = isFullyLoaded && story.isOut;
const isDeleted = story && 'isDeleted' in story;
const isUnsupportedStory = isFullyLoaded && Object.keys(story.content).length === 0;
const video = isFullyLoaded ? (story).content.video : undefined;
const duration = video && formatMediaDuration(video.duration);
const imageHash = isFullyLoaded ? getStoryMediaHash(story) : undefined;
@ -97,7 +99,7 @@ function MediaStory({
toggleStoryInProfile({ peerId, storyId: story.id, isInProfile: true });
showNotification({
message: lang('Story.ToastSavedToProfileText'),
message: oldLang('Story.ToastSavedToProfileText'),
});
handleContextMenuClose();
});
@ -107,7 +109,7 @@ function MediaStory({
toggleStoryInProfile({ peerId, storyId: story.id, isInProfile: false });
showNotification({
message: lang('Story.ToastRemovedFromProfileText'),
message: oldLang('Story.ToastRemovedFromProfileText'),
});
handleContextMenuClose();
});
@ -127,8 +129,14 @@ function MediaStory({
>
{isDeleted && (
<span>
<Icon className={styles.expiredIcon} name="story-expired" />
{lang('ExpiredStory')}
<Icon className={styles.mainIcon} name="story-expired" />
{oldLang('ExpiredStory')}
</span>
)}
{isUnsupportedStory && (
<span>
<Icon className={styles.mainIcon} name="warning" />
{lang('StoryUnsupported')}
</span>
)}
{isPinned && <Icon className={buildClassName(styles.overlayIcon, styles.pinnedIcon)} name="pin-badge" />}
@ -162,22 +170,22 @@ function MediaStory({
>
{isArchive && (
<MenuItem icon="archive" onClick={handleUnarchiveClick}>
{lang('StoryList.SaveToProfile')}
{oldLang('StoryList.SaveToProfile')}
</MenuItem>
)}
{!isArchive && (
<MenuItem icon="archive" onClick={handleArchiveClick}>
{lang('Story.Context.RemoveFromProfile')}
{oldLang('Story.Context.RemoveFromProfile')}
</MenuItem>
)}
{!isArchive && !isPinned && canPin && (
<MenuItem icon="pin" onClick={handleTogglePinned}>
{lang('StoryList.ItemAction.Pin')}
{oldLang('StoryList.ItemAction.Pin')}
</MenuItem>
)}
{!isArchive && isPinned && (
<MenuItem icon="unpin" onClick={handleTogglePinned}>
{lang('StoryList.ItemAction.Unpin')}
{oldLang('StoryList.ItemAction.Unpin')}
</MenuItem>
)}
</Menu>

View File

@ -197,6 +197,7 @@ function Story({
const isChatStory = !isUserStory;
const isChannelStory = isChatStory && isChatChannel(peer as ApiChat);
const isOut = isLoadedStory && story.isOut;
const isUnsupportedStory = isLoadedStory && Object.keys(story.content).length === 0;
const canPinToProfile = useCurrentOrPrev(
isOut ? !story.isInProfile : undefined,
@ -229,7 +230,8 @@ function Story({
);
const canPlayStory = Boolean(
hasFullData && !shouldForcePause && isAppFocused && !isComposerHasFocus && !isCaptionExpanded
(hasFullData || isUnsupportedStory)
&& !shouldForcePause && isAppFocused && !isComposerHasFocus && !isCaptionExpanded
&& !isPausedBySpacebar && !isPausedByLongPress,
);
@ -244,11 +246,11 @@ function Story({
const {
shouldRender: shouldRenderSkeleton,
transitionClassNames: skeletonTransitionClassNames,
} = useShowTransitionDeprecated(!hasFullData);
} = useShowTransitionDeprecated(!hasFullData && !isUnsupportedStory);
const {
transitionClassNames: mediaTransitionClassNames,
} = useShowTransitionDeprecated(Boolean(fullMediaData));
} = useShowTransitionDeprecated(Boolean(fullMediaData) && !isUnsupportedStory);
const thumbRef = useCanvasBlur(thumbnail, !hasThumb);
const previewTransitionClassNames = useMediaTransitionDeprecated(previewBlobUrl);
@ -340,17 +342,17 @@ function Story({
onEnd: handleLongPressEnd,
});
const isUnsupported = useUnsupportedMedia(
const isUnsupportedVideo = useUnsupportedMedia(
videoRef,
undefined,
!isVideo || !fullMediaData || isStreamingSupported,
);
const hasAllData = fullMediaData && (!altMediaHash || altMediaData);
// Play story after media has been downloaded
useEffect(() => {
if (hasAllData && !isUnsupported) handlePlayStory();
}, [hasAllData, isUnsupported]);
// Start progress to the nest slide after media has been downloaded or it is unsupported
if (hasAllData || isUnsupportedVideo || isUnsupportedStory) handlePlayStory();
}, [hasAllData, isUnsupportedVideo, isUnsupportedStory]);
useBackgroundMode(unmarkAppFocused, markAppFocused);
@ -842,6 +844,12 @@ function Story({
</OptimizedVideo>
)}
{isUnsupportedStory && (
<div className={buildClassName(styles.media, styles.unsupportedMedia)}>
<span>{lang('StoryUnsupported')}</span>
</div>
)}
{!isPausedByLongPress && !isComposerHasFocus && (
<>
<button

View File

@ -848,3 +848,13 @@
text-decoration: underline;
}
}
.unsupportedMedia {
display: flex;
align-items: center;
justify-content: center;
color: var(--color-white);
text-align: center;
text-wrap: balance;
}

View File

@ -14,6 +14,7 @@ export function getStoryMediaHash(
story: ApiStory, size: StorySize = 'preview', isAlt?: boolean,
) {
const isVideo = Boolean(story.content.video);
const isPhoto = Boolean(story.content.photo);
if (isVideo) {
if (isAlt && !story.content.altVideos) return undefined;
@ -21,7 +22,11 @@ export function getStoryMediaHash(
return getVideoMediaHash(media, size);
}
return getPhotoMediaHash(story.content.photo!, size);
if (isPhoto) {
return getPhotoMediaHash(story.content.photo!, size);
}
return undefined;
}
function getPreferredAlt(alts: ApiVideo[]) {

View File

@ -1729,6 +1729,7 @@ export interface LangPair {
'UserNoteHint': undefined;
'EditUserNoteHint': undefined;
'AriaStoryTogglerOpen': undefined;
'StoryUnsupported': undefined;
}
export interface LangPairWithVariables<V = LangVariable> {