From 08e842c6db033088a22392e2a6b93f3f87d81414 Mon Sep 17 00:00:00 2001 From: AndyLnd Date: Mon, 10 May 2021 15:27:50 +0200 Subject: [PATCH] fix: Improve UI performance of ephemeral messages (#11071) (SQCORE-633) --- src/page/template/modal/user-modal.htm | 2 +- .../components/message/EphemeralTimer.test.ts | 13 +++++++++---- src/script/components/message/EphemeralTimer.tsx | 15 ++++++++++----- .../conversation/ConversationEphemeralHandler.ts | 2 +- src/script/entity/message/Message.ts | 2 -- src/style/components/ephemeral-timer.less | 14 ++------------ 6 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/page/template/modal/user-modal.htm b/src/page/template/modal/user-modal.htm index e6b25dfc7ca..b61d0cfed2d 100644 --- a/src/page/template/modal/user-modal.htm +++ b/src/page/template/modal/user-modal.htm @@ -17,7 +17,7 @@ params="user: user, actionsViewModel: actionsViewModel, onAction: onUserAction, isSelfActivated: isActivatedAccount()" > - +
diff --git a/src/script/components/message/EphemeralTimer.test.ts b/src/script/components/message/EphemeralTimer.test.ts index 3d1ddb97523..ab6679d3e94 100644 --- a/src/script/components/message/EphemeralTimer.test.ts +++ b/src/script/components/message/EphemeralTimer.test.ts @@ -32,18 +32,23 @@ class EphemeralTimerPage extends TestPage { describe('EphemeralTimer', () => { it('shows the icon', () => { const message = new Message(); - message.ephemeral_started(Date.now()); - message.ephemeral_expires(new Date(new Date().getTime() + 10 * 60000).getTime()); + const remaining = 600_000; + const now = Date.now(); + message.ephemeral_started(now); + message.ephemeral_expires(now + remaining); + message.ephemeral_remaining(remaining); const ephemeralTimer = new EphemeralTimerPage({message}); const circle = ephemeralTimer.getCircle(); - expect(circle.props().style.animationDuration).toBe('600s'); + + expect(circle.props().style['--offset']).toBe(1); }); it('hides the icon when no ephemeral timer was started', () => { const message = new Message(); const ephemeralTimer = new EphemeralTimerPage({message}); const circle = ephemeralTimer.getCircle(); - expect(circle.props().style.animationDuration).toBe('0s'); + + expect(circle.props().style['--offset']).toBe(0); }); }); diff --git a/src/script/components/message/EphemeralTimer.tsx b/src/script/components/message/EphemeralTimer.tsx index 866ee27cafa..e729158230b 100644 --- a/src/script/components/message/EphemeralTimer.tsx +++ b/src/script/components/message/EphemeralTimer.tsx @@ -20,15 +20,20 @@ import React from 'react'; import type {Message} from '../../entity/message/Message'; -import {registerReactComponent} from 'Util/ComponentUtil'; +import {registerReactComponent, useKoSubscribableChildren} from 'Util/ComponentUtil'; export interface EphemeralTimerProps { message: Message; } const EphemeralTimer: React.FC = ({message}) => { - const started = message.ephemeral_started(); - const duration = ((message.ephemeral_expires() as number) - started) / 1000; + const { + ephemeral_remaining: remaining, + ephemeral_started: started, + ephemeral_expires: expires, + } = useKoSubscribableChildren(message, ['ephemeral_remaining', 'ephemeral_started', 'ephemeral_expires']); + + const duration = expires - started; return ( @@ -39,7 +44,7 @@ const EphemeralTimer: React.FC = ({message}) => { cx={4} cy={4} r={2} - style={{animationDelay: `${(started - Date.now()) / 1000}s`, animationDuration: `${duration}s`}} + style={{'--offset': remaining / duration || 0} as React.CSSProperties} transform="rotate(-90 4 4)" /> @@ -49,6 +54,6 @@ const EphemeralTimer: React.FC = ({message}) => { export default EphemeralTimer; registerReactComponent('ephemeral-timer', { + bindings: 'message', component: EphemeralTimer, - template: '
', }); diff --git a/src/script/conversation/ConversationEphemeralHandler.ts b/src/script/conversation/ConversationEphemeralHandler.ts index df7bfcb4633..fc481b5eb7e 100644 --- a/src/script/conversation/ConversationEphemeralHandler.ts +++ b/src/script/conversation/ConversationEphemeralHandler.ts @@ -48,7 +48,7 @@ export class ConversationEphemeralHandler extends AbstractConversationEventHandl static get CONFIG() { return { - INTERVAL_TIME: TIME_IN_MILLIS.SECOND * 0.25, + INTERVAL_TIME: TIME_IN_MILLIS.SECOND, TIMER_RANGE: { MAX: TIME_IN_MILLIS.YEAR, MIN: TIME_IN_MILLIS.SECOND, diff --git a/src/script/entity/message/Message.ts b/src/script/entity/message/Message.ts index 0be55697be2..e24385f4183 100644 --- a/src/script/entity/message/Message.ts +++ b/src/script/entity/message/Message.ts @@ -57,7 +57,6 @@ export class Message { public reaction: ReactionType; public readonly accent_color: ko.PureComputed; public readonly ephemeral_caption: ko.PureComputed; - public readonly ephemeral_duration: ko.Observable; public readonly ephemeral_expires: ko.Observable; public readonly ephemeral_remaining: ko.Observable; public readonly ephemeral_started: ko.Observable; @@ -93,7 +92,6 @@ export class Message { const remainingTime = this.ephemeral_remaining(); return remainingTime ? `${formatDurationCaption(remainingTime)} ${t('ephemeralRemaining')}` : ''; }); - this.ephemeral_duration = ko.observable(0); this.ephemeral_remaining = ko.observable(0); this.ephemeral_expires = ko.observable(false); this.ephemeral_started = ko.observable(0); diff --git a/src/style/components/ephemeral-timer.less b/src/style/components/ephemeral-timer.less index 12a686267b7..9275c0b56eb 100644 --- a/src/style/components/ephemeral-timer.less +++ b/src/style/components/ephemeral-timer.less @@ -28,21 +28,11 @@ } &__dial { - animation-name: dial-animation; - animation-timing-function: steps(40); + --offset: 1; fill: none; stroke: var(--foreground); stroke-dasharray: @strokelength; - stroke-dashoffset: @strokelength; + stroke-dashoffset: calc(@strokelength * (1 + var(--offset))); stroke-width: @strokewidth; } } - -@keyframes dial-animation { - 0% { - stroke-dashoffset: @strokelength * 2; - } - 100% { - stroke-dashoffset: @strokelength; - } -}