Custom Emoji: Better quality for small emojis

This commit is contained in:
Alexander Zinchuk 2022-11-18 16:05:04 +04:00
parent b69f4fb2e4
commit 0e4f9e5ae6
6 changed files with 34 additions and 11 deletions

View File

@ -30,11 +30,6 @@
border-radius: 0 !important; border-radius: 0 !important;
user-select: none !important; user-select: none !important;
:global(canvas) {
width: 100% !important;
height: 100% !important;
}
} }
.highlightCatch { .highlightCatch {

View File

@ -24,6 +24,7 @@ type OwnProps = {
noVerified?: boolean; noVerified?: boolean;
noFake?: boolean; noFake?: boolean;
withEmojiStatus?: boolean; withEmojiStatus?: boolean;
emojiStatusSize?: number;
isSavedMessages?: boolean; isSavedMessages?: boolean;
noLoopLimit?: boolean; noLoopLimit?: boolean;
onEmojiStatusClick?: NoneToVoidFunction; onEmojiStatusClick?: NoneToVoidFunction;
@ -36,6 +37,7 @@ const FullNameTitle: FC<OwnProps> = ({
noVerified, noVerified,
noFake, noFake,
withEmojiStatus, withEmojiStatus,
emojiStatusSize,
isSavedMessages, isSavedMessages,
noLoopLimit, noLoopLimit,
onEmojiStatusClick, onEmojiStatusClick,
@ -63,6 +65,7 @@ const FullNameTitle: FC<OwnProps> = ({
{withEmojiStatus && emojiStatus && ( {withEmojiStatus && emojiStatus && (
<CustomEmoji <CustomEmoji
documentId={emojiStatus.documentId} documentId={emojiStatus.documentId}
size={emojiStatusSize}
loopLimit={!noLoopLimit ? EMOJI_STATUS_LOOP_LIMIT : undefined} loopLimit={!noLoopLimit ? EMOJI_STATUS_LOOP_LIMIT : undefined}
observeIntersectionForLoading={observeIntersection} observeIntersectionForLoading={observeIntersection}
onClick={onEmojiStatusClick} onClick={onEmojiStatusClick}

View File

@ -31,6 +31,7 @@ type OwnProps = {
withFullInfo?: boolean; withFullInfo?: boolean;
withUpdatingStatus?: boolean; withUpdatingStatus?: boolean;
withVideoAvatar?: boolean; withVideoAvatar?: boolean;
emojiStatusSize?: number;
noStatusOrTyping?: boolean; noStatusOrTyping?: boolean;
noRtl?: boolean; noRtl?: boolean;
}; };
@ -56,6 +57,7 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
withFullInfo, withFullInfo,
withUpdatingStatus, withUpdatingStatus,
withVideoAvatar, withVideoAvatar,
emojiStatusSize,
noStatusOrTyping, noStatusOrTyping,
noRtl, noRtl,
user, user,
@ -141,7 +143,12 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
animationLevel={animationLevel} animationLevel={animationLevel}
/> />
<div className="info"> <div className="info">
<FullNameTitle peer={user} withEmojiStatus isSavedMessages={isSavedMessages} /> <FullNameTitle
peer={user}
withEmojiStatus
emojiStatusSize={emojiStatusSize}
isSavedMessages={isSavedMessages}
/>
{(status || (!isSavedMessages && !noStatusOrTyping)) && renderStatusOrTyping()} {(status || (!isSavedMessages && !noStatusOrTyping)) && renderStatusOrTyping()}
</div> </div>
</div> </div>

View File

@ -47,6 +47,8 @@ type StateProps =
} }
& Pick<GlobalState, 'connectionState'>; & Pick<GlobalState, 'connectionState'>;
const EMOJI_STATUS_SIZE = 24;
const ProfileInfo: FC<OwnProps & StateProps> = ({ const ProfileInfo: FC<OwnProps & StateProps> = ({
forceShowSelf, forceShowSelf,
canPlayVideo, canPlayVideo,
@ -241,6 +243,7 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
<FullNameTitle <FullNameTitle
peer={(user || chat)!} peer={(user || chat)!}
withEmojiStatus withEmojiStatus
emojiStatusSize={EMOJI_STATUS_SIZE}
isSavedMessages={isSavedMessages} isSavedMessages={isSavedMessages}
onEmojiStatusClick={handleClickPremium} onEmojiStatusClick={handleClickPremium}
noLoopLimit noLoopLimit

View File

@ -65,6 +65,7 @@ import './MiddleHeader.scss';
const ANIMATION_DURATION = 350; const ANIMATION_DURATION = 350;
const BACK_BUTTON_INACTIVE_TIME = 450; const BACK_BUTTON_INACTIVE_TIME = 450;
const EMOJI_STATUS_SIZE = 22;
type OwnProps = { type OwnProps = {
chatId: string; chatId: string;
@ -347,6 +348,7 @@ const MiddleHeader: FC<OwnProps & StateProps> = ({
withMediaViewer withMediaViewer
withUpdatingStatus withUpdatingStatus
withVideoAvatar={isReady} withVideoAvatar={isReady}
emojiStatusSize={EMOJI_STATUS_SIZE}
noRtl noRtl
/> />
) : ( ) : (

View File

@ -26,6 +26,7 @@ type Frame =
const MAX_WORKERS = 4; const MAX_WORKERS = 4;
const HIGH_PRIORITY_QUALITY = IS_SINGLE_COLUMN_LAYOUT ? 0.75 : 1; const HIGH_PRIORITY_QUALITY = IS_SINGLE_COLUMN_LAYOUT ? 0.75 : 1;
const LOW_PRIORITY_QUALITY = IS_ANDROID ? 0.5 : 0.75; const LOW_PRIORITY_QUALITY = IS_ANDROID ? 0.5 : 0.75;
const LOW_PRIORITY_QUALITY_SIZE_THRESHOLD = 24;
const HIGH_PRIORITY_CACHE_MODULO = IS_SAFARI ? 2 : 4; const HIGH_PRIORITY_CACHE_MODULO = IS_SAFARI ? 2 : 4;
const LOW_PRIORITY_CACHE_MODULO = 0; const LOW_PRIORITY_CACHE_MODULO = 0;
@ -209,8 +210,7 @@ class RLottie {
} = containerInfo; } = containerInfo;
if (!canvas.dataset.isJustCleaned || canvas.dataset.isJustCleaned === 'false') { if (!canvas.dataset.isJustCleaned || canvas.dataset.isJustCleaned === 'false') {
const { isLowPriority, quality = isLowPriority ? LOW_PRIORITY_QUALITY : HIGH_PRIORITY_QUALITY } = this.params; const sizeFactor = this.calcSizeFactor();
const sizeFactor = Math.max(DPR * quality, 1);
ensureCanvasSize(canvas, sizeFactor); ensureCanvasSize(canvas, sizeFactor);
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
canvas.dataset.isJustCleaned = 'true'; canvas.dataset.isJustCleaned = 'true';
@ -239,10 +239,9 @@ class RLottie {
onLoad?: NoneToVoidFunction, onLoad?: NoneToVoidFunction,
coords?: Params['coords'], coords?: Params['coords'],
) { ) {
const { isLowPriority, quality = isLowPriority ? LOW_PRIORITY_QUALITY : HIGH_PRIORITY_QUALITY } = this.params; const sizeFactor = this.calcSizeFactor();
let imgSize: number; let imgSize: number;
// Reduced quality only looks acceptable on high DPR screens
const sizeFactor = Math.max(DPR * quality, 1);
if (container instanceof HTMLDivElement) { if (container instanceof HTMLDivElement) {
if (!(container.parentNode instanceof HTMLElement)) { if (!(container.parentNode instanceof HTMLElement)) {
@ -313,6 +312,20 @@ class RLottie {
} }
} }
private calcSizeFactor() {
const {
isLowPriority,
size,
// Reduced quality only looks acceptable on big enough images
quality = isLowPriority && (!size || size > LOW_PRIORITY_QUALITY_SIZE_THRESHOLD)
? LOW_PRIORITY_QUALITY
: HIGH_PRIORITY_QUALITY,
} = this.params;
// Reduced quality only looks acceptable on high DPR screens
return Math.max(DPR * quality, 1);
}
private destroy() { private destroy() {
this.isDestroyed = true; this.isDestroyed = true;
this.pause(); this.pause();