Use DurationInSeconds for expireTimer

This commit is contained in:
Fedor Indutny 2022-11-16 12:18:02 -08:00 committed by GitHub
parent cf57c7aaf0
commit 6be69a7ba8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
59 changed files with 411 additions and 216 deletions

View file

@ -7,6 +7,7 @@ import { ConfirmationDialog } from './ConfirmationDialog';
import { Select } from './Select';
import type { LocalizerType } from '../types/Util';
import type { Theme } from '../util/theme';
import { DurationInSeconds } from '../util/durations';
const CSS_MODULE = 'module-disappearing-time-dialog';
@ -15,14 +16,14 @@ const DEFAULT_VALUE = 60;
export type PropsType = Readonly<{
i18n: LocalizerType;
theme?: Theme;
initialValue?: number;
onSubmit: (value: number) => void;
initialValue?: DurationInSeconds;
onSubmit: (value: DurationInSeconds) => void;
onClose: () => void;
}>;
const UNITS = ['seconds', 'minutes', 'hours', 'days', 'weeks'];
const UNIT_TO_MS = new Map<string, number>([
const UNIT_TO_SEC = new Map<string, number>([
['seconds', 1],
['minutes', 60],
['hours', 60 * 60],
@ -50,14 +51,14 @@ export function DisappearingTimeDialog(props: PropsType): JSX.Element {
let initialUnit = 'seconds';
let initialUnitValue = 1;
for (const unit of UNITS) {
const ms = UNIT_TO_MS.get(unit) || 1;
const sec = UNIT_TO_SEC.get(unit) || 1;
if (initialValue < ms) {
if (initialValue < sec) {
break;
}
initialUnit = unit;
initialUnitValue = Math.floor(initialValue / ms);
initialUnitValue = Math.floor(initialValue / sec);
}
const [unitValue, setUnitValue] = useState(initialUnitValue);
@ -84,7 +85,11 @@ export function DisappearingTimeDialog(props: PropsType): JSX.Element {
text: i18n('DisappearingTimeDialog__set'),
style: 'affirmative',
action() {
onSubmit(unitValue * (UNIT_TO_MS.get(unit) || 1));
onSubmit(
DurationInSeconds.fromSeconds(
unitValue * (UNIT_TO_SEC.get(unit) ?? 1)
)
);
},
},
]}

View file

@ -5,6 +5,7 @@ import React, { useState } from 'react';
import { DisappearingTimerSelect } from './DisappearingTimerSelect';
import { setupI18n } from '../util/setupI18n';
import { DurationInSeconds } from '../util/durations';
import enMessages from '../../_locales/en/messages.json';
export default {
@ -23,7 +24,7 @@ const TimerSelectWrap: React.FC<Props> = ({ initialValue }) => {
return (
<DisappearingTimerSelect
i18n={i18n}
value={value}
value={DurationInSeconds.fromSeconds(value)}
onChange={newValue => setValue(newValue)}
/>
);

View file

@ -7,6 +7,7 @@ import classNames from 'classnames';
import type { LocalizerType } from '../types/Util';
import * as expirationTimer from '../util/expirationTimer';
import { DurationInSeconds } from '../util/durations';
import { DisappearingTimeDialog } from './DisappearingTimeDialog';
import { Select } from './Select';
@ -16,17 +17,17 @@ const CSS_MODULE = 'module-disappearing-timer-select';
export type Props = {
i18n: LocalizerType;
value?: number;
onChange(value: number): void;
value?: DurationInSeconds;
onChange(value: DurationInSeconds): void;
};
export const DisappearingTimerSelect: React.FC<Props> = (props: Props) => {
const { i18n, value = 0, onChange } = props;
const { i18n, value = DurationInSeconds.ZERO, onChange } = props;
const [isModalOpen, setIsModalOpen] = useState(false);
let expirationTimerOptions: ReadonlyArray<{
readonly value: number;
readonly value: DurationInSeconds;
readonly text: string;
}> = expirationTimer.DEFAULT_DURATIONS_IN_SECONDS.map(seconds => {
const text = expirationTimer.format(i18n, seconds, {
@ -42,7 +43,7 @@ export const DisappearingTimerSelect: React.FC<Props> = (props: Props) => {
!expirationTimer.DEFAULT_DURATIONS_SET.has(value);
const onSelectChange = (newValue: string) => {
const intValue = parseInt(newValue, 10);
const intValue = DurationInSeconds.fromSeconds(parseInt(newValue, 10));
if (intValue === -1) {
setIsModalOpen(true);
} else {
@ -54,7 +55,7 @@ export const DisappearingTimerSelect: React.FC<Props> = (props: Props) => {
expirationTimerOptions = [
...expirationTimerOptions,
{
value: -1,
value: DurationInSeconds.fromSeconds(-1),
text: i18n(
isCustomTimeSelected
? 'selectedCustomDisappearingTimeOption'

View file

@ -13,6 +13,7 @@ import { CrashReportDialog } from './CrashReportDialog';
import type { ConversationType } from '../state/ducks/conversations';
import { MessageSearchResult } from './conversationList/MessageSearchResult';
import { setupI18n } from '../util/setupI18n';
import { DurationInSeconds } from '../util/durations';
import enMessages from '../../_locales/en/messages.json';
import { ThemeType } from '../types/Util';
import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation';
@ -953,7 +954,7 @@ export const GroupMetadataNoTimer = (): JSX.Element => (
mode: LeftPaneMode.SetGroupMetadata,
groupAvatar: undefined,
groupName: 'Group 1',
groupExpireTimer: 0,
groupExpireTimer: DurationInSeconds.ZERO,
hasError: false,
isCreating: false,
isEditingAvatar: false,
@ -975,7 +976,7 @@ export const GroupMetadataRegularTimer = (): JSX.Element => (
mode: LeftPaneMode.SetGroupMetadata,
groupAvatar: undefined,
groupName: 'Group 1',
groupExpireTimer: 24 * 3600,
groupExpireTimer: DurationInSeconds.DAY,
hasError: false,
isCreating: false,
isEditingAvatar: false,
@ -997,7 +998,7 @@ export const GroupMetadataCustomTimer = (): JSX.Element => (
mode: LeftPaneMode.SetGroupMetadata,
groupAvatar: undefined,
groupName: 'Group 1',
groupExpireTimer: 7 * 3600,
groupExpireTimer: DurationInSeconds.fromHours(7),
hasError: false,
isCreating: false,
isEditingAvatar: false,

View file

@ -28,6 +28,7 @@ import { ScrollBehavior } from '../types/Util';
import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
import { usePrevious } from '../hooks/usePrevious';
import { missingCaseError } from '../util/missingCaseError';
import type { DurationInSeconds } from '../util/durations';
import type { WidthBreakpoint } from './_util';
import { getConversationListWidthBreakpoint } from './_util';
import * as KeyboardLayout from '../services/keyboardLayout';
@ -106,7 +107,7 @@ export type PropsType = {
savePreferredLeftPaneWidth: (_: number) => void;
searchInConversation: (conversationId: string) => unknown;
setComposeGroupAvatar: (_: undefined | Uint8Array) => void;
setComposeGroupExpireTimer: (_: number) => void;
setComposeGroupExpireTimer: (_: DurationInSeconds) => void;
setComposeGroupName: (_: string) => void;
setComposeSearchTerm: (composeSearchTerm: string) => void;
showArchivedConversations: () => void;

View file

@ -12,6 +12,7 @@ import { DEFAULT_CONVERSATION_COLOR } from '../types/Colors';
import { PhoneNumberSharingMode } from '../util/phoneNumberSharingMode';
import { PhoneNumberDiscoverability } from '../util/phoneNumberDiscoverability';
import { objectMap } from '../util/objectMap';
import { DurationInSeconds } from '../util/durations';
const i18n = setupI18n('en', enMessages);
@ -107,7 +108,7 @@ const getDefaultArgs = (): PropsDataType => ({
selectedSpeaker: availableSpeakers[1],
shouldShowStoriesSettings: true,
themeSetting: 'system',
universalExpireTimer: 3600,
universalExpireTimer: DurationInSeconds.HOUR,
whoCanFindMe: PhoneNumberDiscoverability.Discoverable,
whoCanSeeMe: PhoneNumberSharingMode.Everybody,
zoomFactor: 1,
@ -186,7 +187,7 @@ BlockedMany.args = {
export const CustomUniversalExpireTimer = Template.bind({});
CustomUniversalExpireTimer.args = {
universalExpireTimer: 9000,
universalExpireTimer: DurationInSeconds.fromSeconds(9000),
};
CustomUniversalExpireTimer.story = {
name: 'Custom universalExpireTimer',

View file

@ -37,6 +37,7 @@ import {
DEFAULT_DURATIONS_SET,
format as formatExpirationTimer,
} from '../util/expirationTimer';
import { DurationInSeconds } from '../util/durations';
import { useEscapeHandling } from '../hooks/useEscapeHandling';
import { useUniqueId } from '../hooks/useUniqueId';
import { useTheme } from '../hooks/useTheme';
@ -76,7 +77,7 @@ export type PropsDataType = {
selectedMicrophone?: AudioDevice;
selectedSpeaker?: AudioDevice;
themeSetting: ThemeSettingType;
universalExpireTimer: number;
universalExpireTimer: DurationInSeconds;
whoCanFindMe: PhoneNumberDiscoverability;
whoCanSeeMe: PhoneNumberSharingMode;
zoomFactor: ZoomFactorType;
@ -280,7 +281,7 @@ export const Preferences = ({
setGlobalDefaultConversationColor,
shouldShowStoriesSettings,
themeSetting,
universalExpireTimer = 0,
universalExpireTimer = DurationInSeconds.ZERO,
whoCanFindMe,
whoCanSeeMe,
zoomFactor,
@ -954,7 +955,7 @@ export const Preferences = ({
{
value: isCustomDisappearingMessageValue
? universalExpireTimer
: -1,
: DurationInSeconds.fromSeconds(-1),
text: isCustomDisappearingMessageValue
? formatExpirationTimer(i18n, universalExpireTimer)
: i18n('selectedCustomDisappearingTimeOption'),

View file

@ -13,9 +13,10 @@ import { Intl } from './Intl';
import { Modal } from './Modal';
import { SendStatus } from '../messages/MessageSendState';
import { Theme } from '../util/theme';
import { formatDateTimeLong } from '../util/timestamp';
import { DurationInSeconds } from '../util/durations';
import { ThemeType } from '../types/Util';
import { Time } from './Time';
import { formatDateTimeLong } from '../util/timestamp';
import { groupBy } from '../util/mapUtil';
import { format as formatRelativeTime } from '../util/expirationTimer';
@ -189,7 +190,7 @@ export const StoryDetailsModal = ({
}
const timeRemaining = expirationTimestamp
? expirationTimestamp - Date.now()
? DurationInSeconds.fromMillis(expirationTimestamp - Date.now())
: undefined;
return (
@ -254,7 +255,7 @@ export const StoryDetailsModal = ({
id="StoryDetailsModal__disappears-in"
components={[
<span className="StoryDetailsModal__debugger__button__text">
{formatRelativeTime(i18n, timeRemaining / 1000, {
{formatRelativeTime(i18n, timeRemaining, {
largest: 2,
})}
</span>,

View file

@ -9,6 +9,7 @@ import { action } from '@storybook/addon-actions';
import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation';
import { getRandomColor } from '../../test-both/helpers/getRandomColor';
import { setupI18n } from '../../util/setupI18n';
import { DurationInSeconds } from '../../util/durations';
import enMessages from '../../../_locales/en/messages.json';
import { StorybookThemeContext } from '../../../.storybook/StorybookThemeContext';
import {
@ -152,7 +153,7 @@ export const PrivateConvo = (): JSX.Element => {
phoneNumber: '(202) 555-0005',
type: 'direct',
id: '7',
expireTimer: 10,
expireTimer: DurationInSeconds.fromSeconds(10),
acceptedMessageRequest: true,
},
},
@ -165,7 +166,7 @@ export const PrivateConvo = (): JSX.Element => {
phoneNumber: '(202) 555-0005',
type: 'direct',
id: '8',
expireTimer: 300,
expireTimer: DurationInSeconds.fromSeconds(300),
acceptedMessageRequest: true,
isVerified: true,
canChangeTimer: true,
@ -231,7 +232,7 @@ export const Group = (): JSX.Element => {
phoneNumber: '',
id: '11',
type: 'group',
expireTimer: 10,
expireTimer: DurationInSeconds.fromSeconds(10),
acceptedMessageRequest: true,
outgoingCallButtonStyle: OutgoingCallButtonStyle.JustVideo,
},
@ -247,7 +248,7 @@ export const Group = (): JSX.Element => {
id: '12',
type: 'group',
left: true,
expireTimer: 10,
expireTimer: DurationInSeconds.fromSeconds(10),
acceptedMessageRequest: true,
outgoingCallButtonStyle: OutgoingCallButtonStyle.JustVideo,
},
@ -262,7 +263,7 @@ export const Group = (): JSX.Element => {
phoneNumber: '',
id: '13',
type: 'group',
expireTimer: 10,
expireTimer: DurationInSeconds.fromSeconds(10),
acceptedMessageRequest: true,
outgoingCallButtonStyle: OutgoingCallButtonStyle.Join,
},
@ -277,7 +278,7 @@ export const Group = (): JSX.Element => {
phoneNumber: '',
id: '14',
type: 'group',
expireTimer: 10,
expireTimer: DurationInSeconds.fromSeconds(10),
acceptedMessageRequest: true,
outgoingCallButtonStyle: OutgoingCallButtonStyle.JustVideo,
muteExpiresAt: Infinity,

View file

@ -28,6 +28,7 @@ import * as expirationTimer from '../../util/expirationTimer';
import { missingCaseError } from '../../util/missingCaseError';
import { isInSystemContacts } from '../../util/isInSystemContacts';
import { isConversationMuted } from '../../util/isConversationMuted';
import { DurationInSeconds } from '../../util/durations';
import {
useStartCallShortcuts,
useKeyboardShortcuts,
@ -79,7 +80,7 @@ export type PropsDataType = {
export type PropsActionsType = {
onSetMuteNotifications: (seconds: number) => void;
onSetDisappearingMessages: (seconds: number) => void;
onSetDisappearingMessages: (seconds: DurationInSeconds) => void;
onDeleteMessages: () => void;
onSearchInConversation: () => void;
onOutgoingAudioCallInConversation: () => void;
@ -406,8 +407,8 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
const expireDurations: ReadonlyArray<ReactNode> = [
...expirationTimer.DEFAULT_DURATIONS_IN_SECONDS,
-1,
].map((seconds: number) => {
DurationInSeconds.fromSeconds(-1),
].map(seconds => {
let text: string;
if (seconds === -1) {

View file

@ -24,6 +24,7 @@ import { SendStatus } from '../../messages/MessageSendState';
import { WidthBreakpoint } from '../_util';
import * as log from '../../logging/log';
import { formatDateTimeLong } from '../../util/timestamp';
import { DurationInSeconds } from '../../util/durations';
import { format as formatRelativeTime } from '../../util/expirationTimer';
export type Contact = Pick<
@ -302,7 +303,7 @@ export class MessageDetail extends React.Component<Props> {
} = this.props;
const timeRemaining = expirationTimestamp
? expirationTimestamp - Date.now()
? DurationInSeconds.fromMillis(expirationTimestamp - Date.now())
: undefined;
return (
@ -422,7 +423,7 @@ export class MessageDetail extends React.Component<Props> {
{i18n('MessageDetail--disappears-in')}
</td>
<td>
{formatRelativeTime(i18n, timeRemaining / 1000, {
{formatRelativeTime(i18n, timeRemaining, {
largest: 2,
})}
</td>

View file

@ -2,13 +2,13 @@
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
import * as moment from 'moment';
import { times } from 'lodash';
import { v4 as uuid } from 'uuid';
import { text, boolean, number } from '@storybook/addon-knobs';
import { action } from '@storybook/addon-actions';
import { setupI18n } from '../../util/setupI18n';
import { DurationInSeconds } from '../../util/durations';
import enMessages from '../../../_locales/en/messages.json';
import type { PropsType } from './Timeline';
import { Timeline } from './Timeline';
@ -135,7 +135,7 @@ const items: Record<string, TimelineItemType> = {
type: 'timerNotification',
data: {
disabled: false,
expireTimer: moment.duration(2, 'hours').asSeconds(),
expireTimer: DurationInSeconds.fromHours(2),
title: "It's Me",
type: 'fromMe',
},
@ -145,7 +145,7 @@ const items: Record<string, TimelineItemType> = {
type: 'timerNotification',
data: {
disabled: false,
expireTimer: moment.duration(2, 'hours').asSeconds(),
expireTimer: DurationInSeconds.fromHours(2),
title: '(202) 555-0000',
type: 'fromOther',
},

View file

@ -7,6 +7,7 @@ import { action } from '@storybook/addon-actions';
import { EmojiPicker } from '../emoji/EmojiPicker';
import { setupI18n } from '../../util/setupI18n';
import { DurationInSeconds } from '../../util/durations';
import enMessages from '../../../_locales/en/messages.json';
import type { PropsType as TimelineItemProps } from './TimelineItem';
import { TimelineItem } from './TimelineItem';
@ -43,7 +44,10 @@ const renderContact = (conversationId: string) => (
);
const renderUniversalTimerNotification = () => (
<UniversalTimerNotification i18n={i18n} expireTimer={3600} />
<UniversalTimerNotification
i18n={i18n}
expireTimer={DurationInSeconds.HOUR}
/>
);
const getDefaultProps = () => ({
@ -138,7 +142,7 @@ export const Notification = (): JSX.Element => {
type: 'timerNotification',
data: {
phoneNumber: '(202) 555-0000',
expireTimer: 60,
expireTimer: DurationInSeconds.MINUTE,
...getDefaultConversation(),
type: 'fromOther',
},

View file

@ -2,10 +2,10 @@
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
import * as moment from 'moment';
import { boolean, number, select, text } from '@storybook/addon-knobs';
import { setupI18n } from '../../util/setupI18n';
import { DurationInSeconds } from '../../util/durations';
import enMessages from '../../../_locales/en/messages.json';
import type { Props } from './TimerNotification';
import { TimerNotification } from './TimerNotification';
@ -34,16 +34,19 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
}
: {
disabled: false,
expireTimer: number(
'expireTimer',
('expireTimer' in overrideProps ? overrideProps.expireTimer : 0) || 0
expireTimer: DurationInSeconds.fromMillis(
number(
'expireTimer',
('expireTimer' in overrideProps ? overrideProps.expireTimer : 0) ||
0
)
),
}),
});
export const SetByOther = (): JSX.Element => {
const props = createProps({
expireTimer: moment.duration(1, 'hour').asSeconds(),
expireTimer: DurationInSeconds.fromHours(1),
type: 'fromOther',
title: 'Mr. Fire',
});
@ -61,7 +64,7 @@ export const SetByOtherWithALongName = (): JSX.Element => {
const longName = '🦴🧩📴'.repeat(50);
const props = createProps({
expireTimer: moment.duration(1, 'hour').asSeconds(),
expireTimer: DurationInSeconds.fromHours(1),
type: 'fromOther',
title: longName,
});
@ -81,7 +84,7 @@ SetByOtherWithALongName.story = {
export const SetByYou = (): JSX.Element => {
const props = createProps({
expireTimer: moment.duration(1, 'hour').asSeconds(),
expireTimer: DurationInSeconds.fromHours(1),
type: 'fromMe',
title: 'Mr. Fire',
});
@ -97,7 +100,7 @@ export const SetByYou = (): JSX.Element => {
export const SetBySync = (): JSX.Element => {
const props = createProps({
expireTimer: moment.duration(1, 'hour').asSeconds(),
expireTimer: DurationInSeconds.fromHours(1),
type: 'fromSync',
title: 'Mr. Fire',
});

View file

@ -9,6 +9,7 @@ import { SystemMessage } from './SystemMessage';
import { Intl } from '../Intl';
import type { LocalizerType } from '../../types/Util';
import * as expirationTimer from '../../util/expirationTimer';
import type { DurationInSeconds } from '../../util/durations';
import * as log from '../../logging/log';
export type TimerNotificationType =
@ -27,7 +28,7 @@ export type PropsData = {
| { disabled: true }
| {
disabled: false;
expireTimer: number;
expireTimer: DurationInSeconds;
}
);

View file

@ -18,34 +18,34 @@ const i18n = setupI18n('en', enMessages);
export const Seconds = (): JSX.Element => (
<UniversalTimerNotification
i18n={i18n}
expireTimer={EXPIRE_TIMERS[0].value / 1000}
expireTimer={EXPIRE_TIMERS[0].value}
/>
);
export const Minutes = (): JSX.Element => (
<UniversalTimerNotification
i18n={i18n}
expireTimer={EXPIRE_TIMERS[1].value / 1000}
expireTimer={EXPIRE_TIMERS[1].value}
/>
);
export const Hours = (): JSX.Element => (
<UniversalTimerNotification
i18n={i18n}
expireTimer={EXPIRE_TIMERS[2].value / 1000}
expireTimer={EXPIRE_TIMERS[2].value}
/>
);
export const Days = (): JSX.Element => (
<UniversalTimerNotification
i18n={i18n}
expireTimer={EXPIRE_TIMERS[3].value / 1000}
expireTimer={EXPIRE_TIMERS[3].value}
/>
);
export const Weeks = (): JSX.Element => (
<UniversalTimerNotification
i18n={i18n}
expireTimer={EXPIRE_TIMERS[4].value / 1000}
expireTimer={EXPIRE_TIMERS[4].value}
/>
);

View file

@ -6,10 +6,11 @@ import React from 'react';
import { SystemMessage } from './SystemMessage';
import type { LocalizerType } from '../../types/Util';
import * as expirationTimer from '../../util/expirationTimer';
import type { DurationInSeconds } from '../../util/durations';
export type Props = {
i18n: LocalizerType;
expireTimer: number;
expireTimer: DurationInSeconds;
};
export const UniversalTimerNotification: React.FC<Props> = props => {

View file

@ -16,6 +16,7 @@ import type { ConversationType } from '../../../state/ducks/conversations';
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
import { makeFakeLookupConversationWithoutUuid } from '../../../test-both/helpers/fakeLookupConversationWithoutUuid';
import { ThemeType } from '../../../types/Util';
import { DurationInSeconds } from '../../../util/durations';
const i18n = setupI18n('en', enMessages);
@ -35,7 +36,10 @@ const conversation: ConversationType = getDefaultConversation({
const allCandidateContacts = times(10, () => getDefaultConversation());
const createProps = (hasGroupLink = false, expireTimer?: number): Props => ({
const createProps = (
hasGroupLink = false,
expireTimer?: DurationInSeconds
): Props => ({
addMembers: async () => {
action('addMembers');
},
@ -194,7 +198,7 @@ export const GroupEditable = (): JSX.Element => {
};
export const GroupEditableWithCustomDisappearingTimeout = (): JSX.Element => {
const props = createProps(false, 3 * 24 * 60 * 60);
const props = createProps(false, DurationInSeconds.fromDays(3));
return <ConversationDetails {...props} canEditGroupInfo />;
};

View file

@ -20,6 +20,7 @@ import type { LocalizerType, ThemeType } from '../../../types/Util';
import type { MediaItemType } from '../../../types/MediaItem';
import type { BadgeType } from '../../../badges/types';
import { missingCaseError } from '../../../util/missingCaseError';
import { DurationInSeconds } from '../../../util/durations';
import { DisappearingTimerSelect } from '../../DisappearingTimerSelect';
@ -79,7 +80,7 @@ export type StateProps = {
memberships: Array<GroupV2Membership>;
pendingApprovalMemberships: ReadonlyArray<GroupV2RequestingMembership>;
pendingMemberships: ReadonlyArray<GroupV2PendingMembership>;
setDisappearingMessages: (seconds: number) => void;
setDisappearingMessages: (seconds: DurationInSeconds) => void;
showAllMedia: () => void;
showChatColorEditor: () => void;
showGroupLinkManagement: () => void;
@ -410,7 +411,7 @@ export const ConversationDetails: React.ComponentType<Props> = ({
right={
<DisappearingTimerSelect
i18n={i18n}
value={conversation.expireTimer || 0}
value={conversation.expireTimer || DurationInSeconds.ZERO}
onChange={setDisappearingMessages}
/>
}

View file

@ -10,6 +10,7 @@ import type {
ReplaceAvatarActionType,
SaveAvatarToDiskActionType,
} from '../../types/Avatar';
import type { DurationInSeconds } from '../../util/durations';
import type { ShowConversationType } from '../../state/ducks/conversations';
export enum FindDirection {
@ -73,7 +74,7 @@ export abstract class LeftPaneHelper<T> {
i18n: LocalizerType;
removeSelectedContact: (_: string) => unknown;
setComposeGroupAvatar: (_: undefined | Uint8Array) => unknown;
setComposeGroupExpireTimer: (_: number) => void;
setComposeGroupExpireTimer: (_: DurationInSeconds) => void;
setComposeGroupName: (_: string) => unknown;
toggleComposeEditingAvatar: () => unknown;
}>

View file

@ -10,6 +10,7 @@ import { RowType } from '../ConversationList';
import type { ContactListItemConversationType } from '../conversationList/ContactListItem';
import { DisappearingTimerSelect } from '../DisappearingTimerSelect';
import type { LocalizerType } from '../../types/Util';
import type { DurationInSeconds } from '../../util/durations';
import { Alert } from '../Alert';
import { AvatarEditor } from '../AvatarEditor';
import { AvatarPreview } from '../AvatarPreview';
@ -28,7 +29,7 @@ import { AvatarColors } from '../../types/Colors';
export type LeftPaneSetGroupMetadataPropsType = {
groupAvatar: undefined | Uint8Array;
groupName: string;
groupExpireTimer: number;
groupExpireTimer: DurationInSeconds;
hasError: boolean;
isCreating: boolean;
isEditingAvatar: boolean;
@ -41,7 +42,7 @@ export class LeftPaneSetGroupMetadataHelper extends LeftPaneHelper<LeftPaneSetGr
private readonly groupName: string;
private readonly groupExpireTimer: number;
private readonly groupExpireTimer: DurationInSeconds;
private readonly hasError: boolean;
@ -128,7 +129,7 @@ export class LeftPaneSetGroupMetadataHelper extends LeftPaneHelper<LeftPaneSetGr
createGroup: () => unknown;
i18n: LocalizerType;
setComposeGroupAvatar: (_: undefined | Uint8Array) => unknown;
setComposeGroupExpireTimer: (_: number) => void;
setComposeGroupExpireTimer: (_: DurationInSeconds) => void;
setComposeGroupName: (_: string) => unknown;
toggleComposeEditingAvatar: () => unknown;
}>): ReactChild {