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();
break;
case 'voice':
filter = new GramJs.InputMessagesFilterVoice();
filter = new GramJs.InputMessagesFilterRoundVoice();
break;
case 'profilePhoto':
filter = new GramJs.InputMessagesFilterChatPhotos();
@ -890,7 +890,7 @@ export async function searchMessagesGlobal({
filter = new GramJs.InputMessagesFilterMusic();
break;
case 'voice':
filter = new GramJs.InputMessagesFilterVoice();
filter = new GramJs.InputMessagesFilterRoundVoice();
break;
case 'text':
default: {

View File

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

View File

@ -79,8 +79,8 @@ const Audio: FC<OwnProps> = ({
onCancelUpload,
onDateClick,
}) => {
const { content: { audio, voice }, isMediaUnread } = message;
const isVoice = Boolean(voice);
const { content: { audio, voice, video }, isMediaUnread } = message;
const isVoice = Boolean(voice || video);
const isSeeking = useRef<boolean>(false);
const playStateBeforeSeeking = useRef<boolean>(false);
// eslint-disable-next-line no-null/no-null
@ -229,7 +229,7 @@ const Audio: FC<OwnProps> = ({
if (isVoice) {
return (
<div className="meta" dir={isRtl ? 'rtl' : undefined}>
{formatMediaDuration(voice!.duration)}
{formatMediaDuration((voice || video)!.duration)}
</div>
);
}
@ -359,7 +359,7 @@ const Audio: FC<OwnProps> = ({
lang, audio, duration, isPlaying, playProgress, bufferedProgress, seekerRef, (isDownloadStarted || isUploading),
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)}
</div>
);
@ -408,7 +408,7 @@ function renderAudio(
{date && (
<>
<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>

View File

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

View File

@ -62,7 +62,7 @@ const SenderInfo: FC<OwnProps & StateProps & DispatchProps> = ({
{senderTitle && renderText(senderTitle)}
</div>
<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>

View File

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

View File

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

View File

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

View File

@ -18,6 +18,7 @@ import useTransitionForMedia from '../../../hooks/useTransitionForMedia';
import usePrevious from '../../../hooks/usePrevious';
import useBuffering from '../../../hooks/useBuffering';
import buildClassName from '../../../util/buildClassName';
import { stopCurrentAudio } from '../../../util/audioPlayer';
import useHeavyAnimationCheckForVideo from '../../../hooks/useHeavyAnimationCheckForVideo';
import useVideoCleanup from '../../../hooks/useVideoCleanup';
import usePauseOnInactive from './hooks/usePauseOnInactive';
@ -156,6 +157,7 @@ const RoundVideo: FC<OwnProps> = ({
if (isActivated) {
if (playerEl.paused) {
safePlay(playerEl);
stopCurrentAudio();
} else {
playerEl.pause();
}
@ -165,6 +167,7 @@ const RoundVideo: FC<OwnProps> = ({
playerEl.pause();
playerEl.currentTime = 0;
safePlay(playerEl);
stopCurrentAudio();
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';
break;
case 'documents':
text = lang('lng_media_file_empty_search');
text = lang('lng_media_file_empty');
break;
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;
case 'voice':
case 'audio':
text = lang('lng_media_song_empty_search');
text = lang('lng_media_audio_empty');
break;
default:
text = lang('SharedMedia.EmptyTitle');

View File

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

View File

@ -75,20 +75,26 @@ export function formatMonthAndYear(lang: LangFn, date: Date, isShort = false) {
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 today = getDayStart(new Date());
if (!noWeekdays) {
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);
yesterday.setDate(today.getDate() - 1);
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);
@ -97,9 +103,9 @@ export function formatHumanDate(lang: LangFn, datetime: number | Date, isShort =
weekAhead.setDate(today.getDate() + 7);
if (date >= weekAgo && date <= weekAhead) {
const weekDay = WEEKDAYS_FULL[date.getDay()];
return isShort
? lowerFirst(lang(`Weekday.Short${weekDay}`))
: upperFirst(lang(`Weekday.${weekDay}`));
const weekDayString = isShort ? lang(`Weekday.Short${weekDay}`) : 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');
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) {
@ -126,10 +132,10 @@ function formatDate(lang: LangFn, date: Date, format: string) {
.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;
return `${formatHumanDate(lang, date, true)}, ${formatTime(date)}`;
return `${formatHumanDate(lang, date, true, undefined, isUpperFirst)}, ${formatTime(date)}`;
}
export function formatMediaDuration(duration: number, maxValue?: number) {

View File

@ -36,11 +36,21 @@ const handleResize = throttle(() => {
}
}, 250, true);
window.addEventListener('resize', handleResize);
window.addEventListener('orientationchange', handleResize);
if (IS_IOS) {
window.visualViewport.addEventListener('resize', handleResize);
} else {
window.addEventListener('resize', handleResize);
}
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`);