Various fixes (#1461)

* Show round videos in the voices tab
* Pause audio player when starting round video playback
* Changed text for empty votes tab (taken from TDesktop)
* Capitalized month name on Shared Media tabs.
* Display title context menu button in unjoined channels or groups
* Fixed voice recording timer flickering
* Don't restart emoji animation when pressed while animation is playing
* Corrected viewport calculation for iOS15
* Changed the border color of avatars in own poll
This commit is contained in:
Alexander Zinchuk 2021-09-24 14:37:31 +03:00
parent 59be7ae021
commit c34d389252
13 changed files with 86 additions and 56 deletions

View File

@ -813,7 +813,7 @@ export async function searchMessagesLocal({
filter = new GramJs.InputMessagesFilterMusic(); filter = new GramJs.InputMessagesFilterMusic();
break; break;
case 'voice': case 'voice':
filter = new GramJs.InputMessagesFilterVoice(); filter = new GramJs.InputMessagesFilterRoundVoice();
break; break;
case 'profilePhoto': case 'profilePhoto':
filter = new GramJs.InputMessagesFilterChatPhotos(); filter = new GramJs.InputMessagesFilterChatPhotos();
@ -890,7 +890,7 @@ export async function searchMessagesGlobal({
filter = new GramJs.InputMessagesFilterMusic(); filter = new GramJs.InputMessagesFilterMusic();
break; break;
case 'voice': case 'voice':
filter = new GramJs.InputMessagesFilterVoice(); filter = new GramJs.InputMessagesFilterRoundVoice();
break; break;
case 'text': case 'text':
default: { default: {

View File

@ -170,7 +170,7 @@ const AnimatedSticker: FC<OwnProps> = ({
if (play || playSegment) { if (play || playSegment) {
if (isFrozen.current) { if (isFrozen.current) {
wasPlaying.current = true; wasPlaying.current = true;
} else { } else if (!animation.isPlaying()) {
playAnimation(noLoop); playAnimation(noLoop);
} }
} else { } else {

View File

@ -79,8 +79,8 @@ const Audio: FC<OwnProps> = ({
onCancelUpload, onCancelUpload,
onDateClick, onDateClick,
}) => { }) => {
const { content: { audio, voice }, isMediaUnread } = message; const { content: { audio, voice, video }, isMediaUnread } = message;
const isVoice = Boolean(voice); const isVoice = Boolean(voice || video);
const isSeeking = useRef<boolean>(false); const isSeeking = useRef<boolean>(false);
const playStateBeforeSeeking = useRef<boolean>(false); const playStateBeforeSeeking = useRef<boolean>(false);
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
@ -229,7 +229,7 @@ const Audio: FC<OwnProps> = ({
if (isVoice) { if (isVoice) {
return ( return (
<div className="meta" dir={isRtl ? 'rtl' : undefined}> <div className="meta" dir={isRtl ? 'rtl' : undefined}>
{formatMediaDuration(voice!.duration)} {formatMediaDuration((voice || video)!.duration)}
</div> </div>
); );
} }
@ -359,7 +359,7 @@ const Audio: FC<OwnProps> = ({
lang, audio, duration, isPlaying, playProgress, bufferedProgress, seekerRef, (isDownloadStarted || isUploading), lang, audio, duration, isPlaying, playProgress, bufferedProgress, seekerRef, (isDownloadStarted || isUploading),
date, transferProgress, onDateClick ? handleDateClick : undefined, date, transferProgress, onDateClick ? handleDateClick : undefined,
)} )}
{origin === AudioOrigin.SharedMedia && voice && renderWithTitle()} {origin === AudioOrigin.SharedMedia && (voice || video) && renderWithTitle()}
{origin === AudioOrigin.Inline && voice && renderVoice(voice, renderedWaveform, playProgress, isMediaUnread)} {origin === AudioOrigin.Inline && voice && renderVoice(voice, renderedWaveform, playProgress, isMediaUnread)}
</div> </div>
); );
@ -408,7 +408,7 @@ function renderAudio(
{date && ( {date && (
<> <>
<span className="bullet">&bull;</span> <span className="bullet">&bull;</span>
<Link className="date" onClick={handleDateClick}>{formatMediaDateTime(lang, date * 1000)}</Link> <Link className="date" onClick={handleDateClick}>{formatMediaDateTime(lang, date * 1000, true)}</Link>
</> </>
)} )}
</div> </div>

View File

@ -147,8 +147,8 @@ const File: FC<OwnProps> = ({
{sender && <span className="file-sender">{renderText(sender)}</span>} {sender && <span className="file-sender">{renderText(sender)}</span>}
{!sender && timestamp && ( {!sender && timestamp && (
<> <>
{' '} <span className="bullet" />
<Link onClick={onDateClick}>{formatMediaDateTime(lang, timestamp * 1000)}</Link> <Link onClick={onDateClick}>{formatMediaDateTime(lang, timestamp * 1000, true)}</Link>
</> </>
)} )}
</div> </div>

View File

@ -62,7 +62,7 @@ const SenderInfo: FC<OwnProps & StateProps & DispatchProps> = ({
{senderTitle && renderText(senderTitle)} {senderTitle && renderText(senderTitle)}
</div> </div>
<div className="date" dir="auto"> <div className="date" dir="auto">
{isAvatar ? lang('lng_mediaview_profile_photo') : formatMediaDateTime(lang, message!.date * 1000)} {isAvatar ? lang('lng_mediaview_profile_photo') : formatMediaDateTime(lang, message!.date * 1000, true)}
</div> </div>
</div> </div>
</div> </div>

View File

@ -162,21 +162,19 @@ const HeaderActions: FC<OwnProps & StateProps & DispatchProps> = ({
<i className="icon-search" /> <i className="icon-search" />
</Button> </Button>
)} )}
{(IS_SINGLE_COLUMN_LAYOUT || !canSubscribe) && ( <Button
<Button ref={menuButtonRef}
ref={menuButtonRef} className={isMenuOpen ? 'active' : ''}
className={isMenuOpen ? 'active' : ''} round
round ripple={!IS_SINGLE_COLUMN_LAYOUT}
ripple={!IS_SINGLE_COLUMN_LAYOUT} size="smaller"
size="smaller" color="translucent"
color="translucent" disabled={noMenu}
disabled={noMenu} ariaLabel="More actions"
ariaLabel="More actions" onClick={handleHeaderMenuOpen}
onClick={handleHeaderMenuOpen} >
> <i className="icon-more" />
<i className="icon-more" /> </Button>
</Button>
)}
{menuPosition && ( {menuPosition && (
<HeaderMenuContainer <HeaderMenuContainer
chatId={chatId} chatId={chatId}
@ -226,15 +224,8 @@ export default memo(withGlobal<OwnProps>(
const canMute = isMainThread && !isChatWithSelf && !canSubscribe; const canMute = isMainThread && !isChatWithSelf && !canSubscribe;
const canLeave = isMainThread && !canSubscribe; const canLeave = isMainThread && !canSubscribe;
const noMenu = !(
(IS_SINGLE_COLUMN_LAYOUT && canSubscribe)
|| (IS_SINGLE_COLUMN_LAYOUT && canSearch)
|| canMute
|| canLeave
);
return { return {
noMenu, noMenu: false,
isChannel, isChannel,
isRightColumnShown, isRightColumnShown,
canStartBot, canStartBot,

View File

@ -267,17 +267,19 @@
line-height: 3.5rem; line-height: 3.5rem;
height: 3.5rem; height: 3.5rem;
padding: 0 3.125rem 0 1rem; padding: 0 3.125rem 0 1rem;
font-family: "Roboto", -apple-system, BlinkMacSystemFont, "Apple Color Emoji", "Helvetica Neue", sans-serif;
&::after { &::after {
content: ''; content: '';
width: 10px; width: .75rem;
height: 10px; height: .75rem;
background: var(--color-error); background: var(--color-error);
border-radius: 5px; border-radius: .375rem;
position: absolute; position: absolute;
top: 50%; top: 50%;
margin-top: -5px; margin-top: -.375rem;
right: 1.375rem; right: 1.3125rem;
animation: recording-blink-like-macos 1.5s infinite;
} }
@media (max-width: 600px) { @media (max-width: 600px) {
@ -478,3 +480,12 @@
margin: 1rem 0; margin: 1rem 0;
} }
} }
@keyframes recording-blink-like-macos {
from {
opacity: 1;
}
to {
opacity: .3;
}
}

View File

@ -121,10 +121,14 @@
margin-top: -2px; margin-top: -2px;
.Avatar { .Avatar {
border: 1px solid var(--color-white); border: .0625rem solid var(--color-white);
margin-right: 0; margin-right: 0;
box-sizing: content-box; box-sizing: content-box;
.Message.own & {
border: .0625rem solid var(--secondary-color);
}
&:not(:first-child) { &:not(:first-child) {
margin-left: -3px; margin-left: -3px;
} }

View File

@ -18,6 +18,7 @@ import useTransitionForMedia from '../../../hooks/useTransitionForMedia';
import usePrevious from '../../../hooks/usePrevious'; import usePrevious from '../../../hooks/usePrevious';
import useBuffering from '../../../hooks/useBuffering'; import useBuffering from '../../../hooks/useBuffering';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
import { stopCurrentAudio } from '../../../util/audioPlayer';
import useHeavyAnimationCheckForVideo from '../../../hooks/useHeavyAnimationCheckForVideo'; import useHeavyAnimationCheckForVideo from '../../../hooks/useHeavyAnimationCheckForVideo';
import useVideoCleanup from '../../../hooks/useVideoCleanup'; import useVideoCleanup from '../../../hooks/useVideoCleanup';
import usePauseOnInactive from './hooks/usePauseOnInactive'; import usePauseOnInactive from './hooks/usePauseOnInactive';
@ -156,6 +157,7 @@ const RoundVideo: FC<OwnProps> = ({
if (isActivated) { if (isActivated) {
if (playerEl.paused) { if (playerEl.paused) {
safePlay(playerEl); safePlay(playerEl);
stopCurrentAudio();
} else { } else {
playerEl.pause(); playerEl.pause();
} }
@ -165,6 +167,7 @@ const RoundVideo: FC<OwnProps> = ({
playerEl.pause(); playerEl.pause();
playerEl.currentTime = 0; playerEl.currentTime = 0;
safePlay(playerEl); safePlay(playerEl);
stopCurrentAudio();
setIsActivated(true); setIsActivated(true);
} }

View File

@ -271,14 +271,16 @@ const Profile: FC<OwnProps & StateProps & DispatchProps> = ({
text = areMembersHidden ? 'You have no access to group members list.' : 'No members found'; text = areMembersHidden ? 'You have no access to group members list.' : 'No members found';
break; break;
case 'documents': case 'documents':
text = lang('lng_media_file_empty_search'); text = lang('lng_media_file_empty');
break; break;
case 'links': case 'links':
text = lang('lng_media_link_empty_search'); text = lang('lng_media_link_empty');
break;
case 'audio':
text = lang('lng_media_song_empty');
break; break;
case 'voice': case 'voice':
case 'audio': text = lang('lng_media_audio_empty');
text = lang('lng_media_song_empty_search');
break; break;
default: default:
text = lang('SharedMedia.EmptyTitle'); text = lang('SharedMedia.EmptyTitle');

View File

@ -366,7 +366,10 @@ export function getMessageContentIds(
break; break;
case 'voice': case 'voice':
validator = getMessageVoice; validator = (message: ApiMessage) => {
const video = getMessageVideo(message);
return getMessageVoice(message) || (video && video.isRound);
};
break; break;
case 'inlineMedia': case 'inlineMedia':

View File

@ -75,20 +75,26 @@ export function formatMonthAndYear(lang: LangFn, date: Date, isShort = false) {
return formatDate(lang, date, format); return formatDate(lang, date, format);
} }
export function formatHumanDate(lang: LangFn, datetime: number | Date, isShort = false, noWeekdays = false) { export function formatHumanDate(
lang: LangFn,
datetime: number | Date,
isShort = false,
noWeekdays = false,
isUpperFirst?: boolean,
) {
const date = typeof datetime === 'number' ? new Date(datetime) : datetime; const date = typeof datetime === 'number' ? new Date(datetime) : datetime;
const today = getDayStart(new Date()); const today = getDayStart(new Date());
if (!noWeekdays) { if (!noWeekdays) {
if (toIsoString(date) === toIsoString(today)) { if (toIsoString(date) === toIsoString(today)) {
return (isShort ? lowerFirst : upperFirst)(lang('Weekday.Today')); return (isUpperFirst || !isShort ? upperFirst : lowerFirst)(lang('Weekday.Today'));
} }
const yesterday = new Date(today); const yesterday = new Date(today);
yesterday.setDate(today.getDate() - 1); yesterday.setDate(today.getDate() - 1);
if (toIsoString(date) === toIsoString(yesterday)) { if (toIsoString(date) === toIsoString(yesterday)) {
return (isShort ? lowerFirst : upperFirst)(lang('Weekday.Yesterday')); return (isUpperFirst || !isShort ? upperFirst : lowerFirst)(lang('Weekday.Yesterday'));
} }
const weekAgo = new Date(today); const weekAgo = new Date(today);
@ -97,9 +103,9 @@ export function formatHumanDate(lang: LangFn, datetime: number | Date, isShort =
weekAhead.setDate(today.getDate() + 7); weekAhead.setDate(today.getDate() + 7);
if (date >= weekAgo && date <= weekAhead) { if (date >= weekAgo && date <= weekAhead) {
const weekDay = WEEKDAYS_FULL[date.getDay()]; const weekDay = WEEKDAYS_FULL[date.getDay()];
return isShort const weekDayString = isShort ? lang(`Weekday.Short${weekDay}`) : lang(`Weekday.${weekDay}`);
? lowerFirst(lang(`Weekday.Short${weekDay}`))
: upperFirst(lang(`Weekday.${weekDay}`)); return (isUpperFirst || !isShort ? upperFirst : lowerFirst)(weekDayString);
} }
} }
@ -109,7 +115,7 @@ export function formatHumanDate(lang: LangFn, datetime: number | Date, isShort =
: (withYear ? 'chatFullDate' : 'chatDate'); : (withYear ? 'chatFullDate' : 'chatDate');
const format = lang(formatKey) || 'd MMMM yyyy'; const format = lang(formatKey) || 'd MMMM yyyy';
return (isShort ? lowerFirst : upperFirst)(formatDate(lang, date, format)); return (isUpperFirst || !isShort ? upperFirst : lowerFirst)(formatDate(lang, date, format));
} }
function formatDate(lang: LangFn, date: Date, format: string) { function formatDate(lang: LangFn, date: Date, format: string) {
@ -126,10 +132,10 @@ function formatDate(lang: LangFn, date: Date, format: string) {
.replace('yyyy', String(date.getFullYear())); .replace('yyyy', String(date.getFullYear()));
} }
export function formatMediaDateTime(lang: LangFn, datetime: number | Date) { export function formatMediaDateTime(lang: LangFn, datetime: number | Date, isUpperFirst?: boolean) {
const date = typeof datetime === 'number' ? new Date(datetime) : datetime; const date = typeof datetime === 'number' ? new Date(datetime) : datetime;
return `${formatHumanDate(lang, date, true)}, ${formatTime(date)}`; return `${formatHumanDate(lang, date, true, undefined, isUpperFirst)}, ${formatTime(date)}`;
} }
export function formatMediaDuration(duration: number, maxValue?: number) { export function formatMediaDuration(duration: number, maxValue?: number) {

View File

@ -36,11 +36,21 @@ const handleResize = throttle(() => {
} }
}, 250, true); }, 250, true);
window.addEventListener('resize', handleResize);
window.addEventListener('orientationchange', handleResize); window.addEventListener('orientationchange', handleResize);
if (IS_IOS) {
window.visualViewport.addEventListener('resize', handleResize);
} else {
window.addEventListener('resize', handleResize);
}
export function updateSizes(): IDimensions { export function updateSizes(): IDimensions {
const vh = window.innerHeight * 0.01; let height: number;
if (IS_IOS) {
height = window.visualViewport.height + window.visualViewport.pageTop;
} else {
height = window.innerHeight;
}
const vh = height * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`); document.documentElement.style.setProperty('--vh', `${vh}px`);