feat: moved disappearing logic to a feature folder

only moved types and timerOptions so far
pull/2971/head
William Grant 2 years ago
parent b471900a18
commit 0212166fcc

@ -2,6 +2,7 @@ import { isNumber } from 'lodash';
import React, { useEffect, useMemo, useState } from 'react';
import { useDispatch } from 'react-redux';
import { useIsRightPanelShowing } from '../../../hooks/useUI';
import { TimerOptions } from '../../../session/disappearing_messages/timerOptions';
import { closeRightPanel, openRightPanel } from '../../../state/ducks/conversations';
import { resetRightOverlayMode, setRightOverlayMode } from '../../../state/ducks/section';
import {
@ -17,7 +18,6 @@ import {
useSelectedNotificationSetting,
useSelectedSubscriberCount,
} from '../../../state/selectors/selectedConversation';
import { ExpirationTimerOptions } from '../../../util/expiringMessages';
import { ConversationHeaderSubtitle } from './ConversationHeaderSubtitle';
export type SubtitleStrings = Record<string, string> & {
@ -96,7 +96,7 @@ export const ConversationHeaderTitle = () => {
: null;
const abbreviatedExpireTime = isNumber(expireTimer)
? ExpirationTimerOptions.getAbbreviated(expireTimer)
? TimerOptions.getAbbreviated(expireTimer)
: null;
return expireTimer && disappearingMessageSettingText

@ -1,5 +1,5 @@
import React from 'react';
import { DisappearingMessageConversationModeType } from '../../../../../util/expiringMessages';
import { DisappearingMessageConversationModeType } from '../../../../../session/disappearing_messages/types';
import { PanelButtonGroup, PanelLabel } from '../../../../buttons/PanelButton';
import { PanelRadioButton } from '../../../../buttons/PanelRadioButton';

@ -3,28 +3,26 @@ import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';
import { useTimerOptionsByMode } from '../../../../../hooks/useParamSelector';
import { setDisappearingMessagesByConvoId } from '../../../../../interactions/conversationInteractions';
import { TimerOptions } from '../../../../../session/disappearing_messages/timerOptions';
import { DisappearingMessageConversationModeType } from '../../../../../session/disappearing_messages/types';
import { closeRightPanel } from '../../../../../state/ducks/conversations';
import { resetRightOverlayMode } from '../../../../../state/ducks/section';
import {
getSelectedConversationExpirationModes,
useSelectedConversationKey,
useSelectedConversationDisappearingMode,
useSelectedConversationKey,
useSelectedExpireTimer,
useSelectedIsGroup,
useSelectedWeAreAdmin,
useSelectedIsNoteToSelf,
useSelectedWeAreAdmin,
} from '../../../../../state/selectors/selectedConversation';
import {
DEFAULT_TIMER_OPTION,
DisappearingMessageConversationModeType,
} from '../../../../../util/expiringMessages';
import { ReleasedFeatures } from '../../../../../util/releaseFeature';
import { Flex } from '../../../../basic/Flex';
import { SessionButton } from '../../../../basic/SessionButton';
import { SpacerLG, SpacerXL } from '../../../../basic/Text';
import { DisappearingModes } from './DisappearingModes';
import { Header } from './Header';
import { TimeOptions } from './TimeOptions';
import { ReleasedFeatures } from '../../../../../util/releaseFeature';
const StyledScrollContainer = styled.div`
width: 100%;
@ -65,9 +63,9 @@ function loadDefaultTimeValue(
return modeSelected !== 'off'
? modeSelected !== 'legacy'
? modeSelected === 'deleteAfterSend'
? DEFAULT_TIMER_OPTION.DELETE_AFTER_SEND
: DEFAULT_TIMER_OPTION.DELETE_AFTER_READ
: DEFAULT_TIMER_OPTION.LEGACY
? TimerOptions.DEFAULT_OPTIONS.DELETE_AFTER_SEND
: TimerOptions.DEFAULT_OPTIONS.DELETE_AFTER_READ
: TimerOptions.DEFAULT_OPTIONS.LEGACY
: 0;
}

@ -1,6 +1,6 @@
import { isEmpty } from 'lodash';
import React from 'react';
import { TimerOptionsArray } from '../../../../../util/expiringMessages';
import { TimerOptionsArray } from '../../../../../session/disappearing_messages/timerOptions';
import { PanelButtonGroup, PanelLabel } from '../../../../buttons/PanelButton';
import { PanelRadioButton } from '../../../../buttons/PanelRadioButton';

@ -7,19 +7,12 @@ import {
} from '../models/conversation';
import { isUsAnySogsFromCache } from '../session/apis/open_group_api/sogsv3/knownBlindedkeys';
import { CONVERSATION } from '../session/constants';
import { TimerOptions, TimerOptionsArray } from '../session/disappearing_messages/timerOptions';
import { PubKey } from '../session/types';
import { UserUtils } from '../session/utils';
import { StateType } from '../state/reducer';
import { getMessageExpirationProps, getMessageReactsProps } from '../state/selectors/conversations';
import { isPrivateAndFriend } from '../state/selectors/selectedConversation';
import {
DELETE_AFTER_READ_OPTIONS,
DELETE_AFTER_SEND_OPTIONS,
DELETE_LEGACY_OPTIONS,
ExpirationTimerOptions,
TIMER_OPTIONS,
TimerOptionsArray,
} from '../util/expiringMessages';
export function useAvatarPath(convoId: string | undefined) {
const convoProps = useConversationPropsById(convoId);
@ -294,32 +287,32 @@ export function useTimerOptionsByMode(disappearingMessageMode?: string, hasOnlyO
const options: TimerOptionsArray = [];
if (hasOnlyOneMode) {
options.push({
name: ExpirationTimerOptions.getName(TIMER_OPTIONS[0]),
value: TIMER_OPTIONS[0],
name: TimerOptions.getName(TimerOptions.VALUES[0]),
value: TimerOptions.VALUES[0],
});
}
switch (disappearingMessageMode) {
// TODO legacy messages support will be removed in a future release
case 'legacy':
options.push(
...DELETE_LEGACY_OPTIONS.map(option => ({
name: ExpirationTimerOptions.getName(option),
...TimerOptions.DELETE_LEGACY.map(option => ({
name: TimerOptions.getName(option),
value: option,
}))
);
break;
case 'deleteAfterRead':
options.push(
...DELETE_AFTER_READ_OPTIONS.map(option => ({
name: ExpirationTimerOptions.getName(option),
...TimerOptions.DELETE_AFTER_READ.map(option => ({
name: TimerOptions.getName(option),
value: option,
}))
);
break;
case 'deleteAfterSend':
options.push(
...DELETE_AFTER_SEND_OPTIONS.map(option => ({
name: ExpirationTimerOptions.getName(option),
...TimerOptions.DELETE_AFTER_SEND.map(option => ({
name: TimerOptions.getName(option),
value: option,
}))
);

@ -11,9 +11,11 @@ import { Data } from '../data/data';
import { SettingsKey } from '../data/settings-key';
import { uploadFileToFsWithOnionV4 } from '../session/apis/file_server_api/FileServerApi';
import { OpenGroupUtils } from '../session/apis/open_group_api/utils';
import { GetNetworkTime } from '../session/apis/snode_api/getNetworkTime';
import { getConversationController } from '../session/conversations';
import { getSodiumRenderer } from '../session/crypto';
import { getDecryptedMediaUrl } from '../session/crypto/DecryptedAttachmentsManager';
import { DisappearingMessageConversationModeType } from '../session/disappearing_messages/types';
import { perfEnd, perfStart } from '../session/utils/Performance';
import { fromHexToArray, toHex } from '../session/utils/String';
import { ConfigurationSync } from '../session/utils/job_runners/jobs/ConfigurationSyncJob';
@ -44,8 +46,6 @@ import { encryptProfile } from '../util/crypto/profileEncrypter';
import { ReleasedFeatures } from '../util/releaseFeature';
import { Storage, setLastProfileUpdateTimestamp } from '../util/storage';
import { UserGroupsWrapperActions } from '../webworker/workers/browser/libsession_worker_interface';
import { DisappearingMessageConversationModeType } from '../util/expiringMessages';
import { GetNetworkTime } from '../session/apis/snode_api/getNetworkTime';
export async function copyPublicKeyByConvoId(convoId: string) {
if (OpenGroupUtils.isOpenGroupV2(convoId)) {

@ -117,9 +117,9 @@ import {
getSubscriberCountOutsideRedux,
} from '../state/selectors/sogsRoomInfo'; // decide it it makes sense to move this to a redux slice?
import { DisappearingMessageConversationModeType } from '../session/disappearing_messages/types';
import {
changeToDisappearingMessageType,
DisappearingMessageConversationModeType,
setExpirationStartTimestamp,
} from '../util/expiringMessages';
import { markAttributesAsReadIfNeeded } from './messageFactory';

@ -1,6 +1,6 @@
import { defaults } from 'lodash';
import { DisappearingMessageConversationModeType } from '../session/disappearing_messages/types';
import { LastMessageStatusType } from '../state/ducks/conversations';
import { DisappearingMessageConversationModeType } from '../util/expiringMessages';
/**
* Private chats have always the type `Private`

@ -1,6 +1,7 @@
import Backbone from 'backbone';
import autoBind from 'auto-bind';
import filesize from 'filesize';
import {
cloneDeep,
debounce,
@ -14,28 +15,27 @@ import {
sortBy,
uniq,
} from 'lodash';
import filesize from 'filesize';
import { SignalService } from '../protobuf';
import { getMessageQueue } from '../session';
import { getConversationController } from '../session/conversations';
import { ContentMessage } from '../session/messages/outgoing';
import { ClosedGroupVisibleMessage } from '../session/messages/outgoing/visibleMessage/ClosedGroupVisibleMessage';
import { PubKey } from '../session/types';
import {
UserUtils,
uploadAttachmentsToFileServer,
uploadLinkPreviewToFileServer,
uploadQuoteThumbnailsToFileServer,
UserUtils,
} from '../session/utils';
import { ClosedGroupVisibleMessage } from '../session/messages/outgoing/visibleMessage/ClosedGroupVisibleMessage';
import {
DataExtractionNotificationMsg,
fillMessageAttributesWithDefaults,
MessageAttributes,
MessageAttributesOptionals,
MessageGroupUpdate,
MessageModelType,
PropsForDataExtractionNotification,
PropsForMessageRequestResponse,
fillMessageAttributesWithDefaults,
} from './messageType';
import { Data } from '../data/data';
@ -45,6 +45,7 @@ import { isUsAnySogsFromCache } from '../session/apis/open_group_api/sogsv3/know
import { GetNetworkTime } from '../session/apis/snode_api/getNetworkTime';
import { SnodeNamespaces } from '../session/apis/snode_api/namespaces';
import { DURATION } from '../session/constants';
import { TimerOptions } from '../session/disappearing_messages/timerOptions';
import { OpenGroupVisibleMessage } from '../session/messages/outgoing/visibleMessage/OpenGroupVisibleMessage';
import {
VisibleMessage,
@ -56,14 +57,13 @@ import {
uploadQuoteThumbnailsV3,
} from '../session/utils/AttachmentsV2';
import { perfEnd, perfStart } from '../session/utils/Performance';
import { buildSyncMessage } from '../session/utils/sync/syncUtils';
import { isUsFromCache } from '../session/utils/User';
import { buildSyncMessage } from '../session/utils/sync/syncUtils';
import {
FindAndFormatContactType,
LastMessageStatusType,
MessageModelPropsWithoutConvoProps,
MessagePropsDetails,
messagesChanged,
PropsForAttachment,
PropsForExpirationTimer,
PropsForExpiringMessage,
@ -76,9 +76,9 @@ import {
PropsForGroupUpdateName,
PropsForMessageWithoutConvoProps,
PropsForQuote,
messagesChanged,
} from '../state/ducks/conversations';
import { AttachmentTypeWithPath, isVoiceMessage } from '../types/Attachment';
import { getAttachmentMetadata } from '../types/message/initializeAttachmentMetadata';
import {
deleteExternalMessageFiles,
getAbsoluteAttachmentPath,
@ -87,12 +87,12 @@ import {
loadQuoteData,
} from '../types/MessageAttachment';
import { ReactionList } from '../types/Reaction';
import { getAttachmentMetadata } from '../types/message/initializeAttachmentMetadata';
import { roomHasBlindEnabled } from '../types/sqlSharedTypes';
import {
ExpirationTimerOptions,
setExpirationStartTimestamp,
changeToDisappearingConversationMode,
checkForExpireUpdateInContentMessage,
setExpirationStartTimestamp,
updateMessageExpiryOnSwarm,
} from '../util/expiringMessages';
import { LinkPreviews } from '../util/linkPreviews';
@ -278,7 +278,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
}
return window.i18n('timerSetTo', [
ExpirationTimerOptions.getAbbreviated(expireTimerUpdate.expireTimer || 0),
TimerOptions.getAbbreviated(expireTimerUpdate.expireTimer || 0),
]);
}
@ -340,7 +340,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
expireTimer || 0
);
const timespan = ExpirationTimerOptions.getName(expireTimer || 0);
const timespan = TimerOptions.getName(expireTimer || 0);
const disabled = !expireTimer;
const basicProps: PropsForExpirationTimer = {

@ -1,5 +1,9 @@
import { defaultsDeep } from 'lodash';
import { v4 as uuidv4 } from 'uuid';
import {
DisappearingMessageType,
ExpirationTimerUpdate,
} from '../session/disappearing_messages/types';
import {
CallNotificationType,
LastMessageStatusType,
@ -8,7 +12,6 @@ import {
import { AttachmentTypeWithPath } from '../types/Attachment';
import { Reaction, ReactionList, SortedReactionList } from '../types/Reaction';
import { READ_MESSAGE_STATE } from './conversationAttributes';
import { DisappearingMessageType, ExpirationTimerUpdate } from '../util/expiringMessages';
export type MessageModelType = 'incoming' | 'outgoing';

@ -20,12 +20,13 @@ import {
createSwarmMessageSentFromNotUs,
createSwarmMessageSentFromUs,
} from '../models/messageFactory';
import { DisappearingMessageUpdate } from '../session/disappearing_messages/types';
import { ProfileManager } from '../session/profile_manager/ProfileManager';
import { isUsFromCache } from '../session/utils/User';
import { Action, Reaction } from '../types/Reaction';
import { toLogFormat } from '../types/attachments/Errors';
import { getMessageReadyToDisappear } from '../util/expiringMessages';
import { Reactions } from '../util/reactions';
import { DisappearingMessageUpdate, getMessageReadyToDisappear } from '../util/expiringMessages';
function cleanAttachment(attachment: any) {
return {

@ -8,6 +8,7 @@ import { updateConfirmModal } from '../../state/ducks/modalDialog';
import { getSwarmPollingInstance } from '../apis/snode_api';
import { SnodeNamespaces } from '../apis/snode_api/namespaces';
import { generateClosedGroupPublicKey, generateCurve25519KeyPairWithoutPrefix } from '../crypto';
import { DisappearAfterSendOnly, DisappearingMessageType } from '../disappearing_messages/types';
import {
ClosedGroupNewMessage,
ClosedGroupNewMessageParams,
@ -16,7 +17,6 @@ import { PubKey } from '../types';
import { UserUtils } from '../utils';
import { forceSyncConfigurationNowIfNeeded } from '../utils/sync/syncUtils';
import { getConversationController } from './ConversationController';
import { DisappearAfterSendOnly, DisappearingMessageType } from '../../util/expiringMessages';
export async function createClosedGroup(groupName: string, members: Array<string>, isV3: boolean) {
const setOfMembers = new Set(members);

@ -0,0 +1,126 @@
import moment from 'moment';
import { LocalizerKeys } from '../../types/LocalizerKeys';
type TimerOptionsEntry = { name: string; value: number };
export type TimerOptionsArray = Array<TimerOptionsEntry>;
const timerOptionsDurations: Array<{
time: number;
unit: moment.DurationInputArg2;
seconds: number;
}> = [
{ time: 0, unit: 'seconds' as moment.DurationInputArg2 },
{ time: 5, unit: 'seconds' as moment.DurationInputArg2 },
{ time: 10, unit: 'seconds' as moment.DurationInputArg2 },
{ time: 30, unit: 'seconds' as moment.DurationInputArg2 },
{ time: 1, unit: 'minute' as moment.DurationInputArg2 },
{ time: 5, unit: 'minutes' as moment.DurationInputArg2 },
{ time: 30, unit: 'minutes' as moment.DurationInputArg2 },
{ time: 1, unit: 'hour' as moment.DurationInputArg2 },
{ time: 6, unit: 'hours' as moment.DurationInputArg2 },
{ time: 12, unit: 'hours' as moment.DurationInputArg2 },
{ time: 1, unit: 'day' as moment.DurationInputArg2 },
{ time: 1, unit: 'week' as moment.DurationInputArg2 },
{ time: 2, unit: 'weeks' as moment.DurationInputArg2 },
].map(o => {
const duration = moment.duration(o.time, o.unit); // 5, 'seconds'
return {
time: o.time,
unit: o.unit,
seconds: duration.asSeconds(),
};
});
function getTimerOptionName(time: number, unit: moment.DurationInputArg2) {
return (
window.i18n(['timerOption', time, unit].join('_') as LocalizerKeys) ||
moment.duration(time, unit).humanize()
);
}
function getTimerOptionAbbreviated(time: number, unit: string) {
return window.i18n(['timerOption', time, unit, 'abbreviated'].join('_') as LocalizerKeys);
}
function getName(seconds = 0) {
const o = timerOptionsDurations.find(m => m.seconds === seconds);
if (o) {
return getTimerOptionName(o.time, o.unit);
}
return [seconds, 'seconds'].join(' ');
}
function getAbbreviated(seconds = 0) {
const o = timerOptionsDurations.find(m => m.seconds === seconds);
if (o) {
return getTimerOptionAbbreviated(o.time, o.unit);
}
return [seconds, 's'].join('');
}
const VALUES: Array<number> = timerOptionsDurations.map(t => {
return t.seconds;
});
const DELETE_AFTER_READ = VALUES.filter(option => {
return (
option === 10 || // 10 seconds (for development or qa)
option === 30 || // 30 seconds (for development or qa)
option === 60 || // 1 minute (for testing)
option === 300 || // 5 minutes
option === 3600 || // 1 hour
option === 43200 || // 12 hours
option === 86400 || // 1 day
option === 604800 || // 1 week
option === 1209600 // 2 weeks
);
});
const DELETE_AFTER_SEND = VALUES.filter(option => {
return (
option === 10 || // 10 seconds (for development or qa)
option === 30 || // 30 seconds (for development or qa)
option === 60 || // 1 minute (for testing)
option === 43200 || // 12 hours
option === 86400 || // 1 day
option === 604800 || // 1 week
option === 1209600 // 2 weeks
);
});
// TODO legacy messages support will be removed in a future release
const DELETE_LEGACY = VALUES.filter(option => {
return (
option === 5 || // 5 seconds
option === 10 || // 10 seconds
option === 30 || // 30 seconds
option === 60 || // 1 minute
option === 300 || // 5 minutes
option === 1800 || // 30 minutes
option === 3600 || // 1 hour
option === 21600 || // 6 hours
option === 43200 || // 12 hours
option === 86400 || // 1 day
option === 604800 // 1 week
);
});
const DEFAULT_OPTIONS = {
DELETE_AFTER_READ: 43200, // 12 hours
DELETE_AFTER_SEND: 86400, // 1 day
// TODO legacy messages support will be removed in a future release
LEGACY: 86400, // 1 day
};
export const TimerOptions = {
DEFAULT_OPTIONS,
VALUES,
DELETE_AFTER_READ,
DELETE_AFTER_SEND,
DELETE_LEGACY,
getName,
getAbbreviated,
};

@ -0,0 +1,39 @@
// NOTE this must match Content.ExpirationType in the protobuf
export const DisappearingMessageMode = ['unknown', 'deleteAfterRead', 'deleteAfterSend'] as const;
export type DisappearingMessageType = typeof DisappearingMessageMode[number];
export type DisappearAfterSendOnly = Exclude<DisappearingMessageType, 'deleteAfterRead'>;
// TODO NOTE legacy is strictly used in the UI and is not a valid disappearing message mode
export const DisappearingMessageConversationModes = [
'off',
DisappearingMessageMode[1], // deleteAfterRead
DisappearingMessageMode[2], // deleteAfterSend
// TODO legacy messages support will be removed in a future release
'legacy',
] as const;
export type DisappearingMessageConversationModeType = typeof DisappearingMessageConversationModes[number]; // TODO we should make this type a bit more hardcoded than being just resolved as a string
// TODO legacy messages support will be removed in a future release
// expirationType and lastDisappearingMessageChangeTimestamp will no longer have an undefined option
/** Used for setting disappearing messages in conversations */
export type ExpirationTimerUpdate = {
expirationType: DisappearingMessageType | undefined;
expireTimer: number;
lastDisappearingMessageChangeTimestamp: number | undefined;
source: string;
/** updated setting from another device */
fromSync?: boolean;
};
export type DisappearingMessageUpdate = {
expirationType: DisappearingMessageType;
expirationTimer: number;
// This is used for the expirationTimerUpdate
lastDisappearingMessageChangeTimestamp?: number;
// TODO legacy messages support will be removed in a future release
isLegacyConversationSettingMessage?: boolean;
isLegacyDataMessage?: boolean;
isDisappearingMessagesV2Released?: boolean;
shouldDisappearButIsntMessage?: boolean;
isOutdated?: boolean;
};

@ -1,7 +1,6 @@
import _ from 'lodash';
import { v4 as uuidv4 } from 'uuid';
import { PubKey } from '../types';
import { getMessageQueue } from '..';
import { Data } from '../../data/data';
import { ConversationModel } from '../../models/conversation';
@ -13,23 +12,24 @@ import {
distributingClosedGroupEncryptionKeyPairs,
} from '../../receiver/closedGroups';
import { ECKeyPair } from '../../receiver/keypairs';
import {
changeToDisappearingMessageType,
setExpirationStartTimestamp,
} from '../../util/expiringMessages';
import { GetNetworkTime } from '../apis/snode_api/getNetworkTime';
import { SnodeNamespaces } from '../apis/snode_api/namespaces';
import { getConversationController } from '../conversations';
import { generateCurve25519KeyPairWithoutPrefix } from '../crypto';
import { encryptUsingSessionProtocol } from '../crypto/MessageEncrypter';
import { DisappearAfterSendOnly } from '../disappearing_messages/types';
import { ClosedGroupAddedMembersMessage } from '../messages/outgoing/controlMessage/group/ClosedGroupAddedMembersMessage';
import { ClosedGroupEncryptionPairMessage } from '../messages/outgoing/controlMessage/group/ClosedGroupEncryptionPairMessage';
import { ClosedGroupNameChangeMessage } from '../messages/outgoing/controlMessage/group/ClosedGroupNameChangeMessage';
import { ClosedGroupNewMessage } from '../messages/outgoing/controlMessage/group/ClosedGroupNewMessage';
import { ClosedGroupRemovedMembersMessage } from '../messages/outgoing/controlMessage/group/ClosedGroupRemovedMembersMessage';
import { PubKey } from '../types';
import { UserUtils } from '../utils';
import { fromHexToArray, toHex } from '../utils/String';
import {
DisappearAfterSendOnly,
changeToDisappearingMessageType,
setExpirationStartTimestamp,
} from '../../util/expiringMessages';
export type GroupInfo = {
id: string;

@ -1,6 +1,6 @@
import { SignalService } from '../../../protobuf';
import { DisappearingMessageType } from '../../../util/expiringMessages';
import { DURATION, TTL_DEFAULT } from '../../constants';
import { DisappearingMessageType } from '../../disappearing_messages/types';
import { ContentMessage } from './ContentMessage';
import { MessageParams } from './Message';

@ -1,5 +1,5 @@
import { v4 as uuidv4 } from 'uuid';
import _, { isEmpty } from 'lodash';
import { v4 as uuidv4 } from 'uuid';
import { UserUtils } from '..';
import { getMessageQueue } from '../..';
import { Data } from '../../../data/data';
@ -8,32 +8,32 @@ import { ConversationModel } from '../../../models/conversation';
import { SignalService } from '../../../protobuf';
import { ECKeyPair } from '../../../receiver/keypairs';
import { ConfigurationSyncJobDone } from '../../../shims/events';
import { ReleasedFeatures } from '../../../util/releaseFeature';
import { Storage } from '../../../util/storage';
import { getCompleteUrlFromRoom } from '../../apis/open_group_api/utils/OpenGroupUtils';
import { SnodeNamespaces } from '../../apis/snode_api/namespaces';
import { DURATION } from '../../constants';
import { getConversationController } from '../../conversations';
import { DisappearingMessageUpdate } from '../../disappearing_messages/types';
import { DataMessage } from '../../messages/outgoing';
import {
ConfigurationMessage,
ConfigurationMessageClosedGroup,
ConfigurationMessageContact,
} from '../../messages/outgoing/controlMessage/ConfigurationMessage';
import { ExpirationTimerUpdateMessage } from '../../messages/outgoing/controlMessage/ExpirationTimerUpdateMessage';
import { MessageRequestResponse } from '../../messages/outgoing/controlMessage/MessageRequestResponse';
import { SharedConfigMessage } from '../../messages/outgoing/controlMessage/SharedConfigMessage';
import { UnsendMessage } from '../../messages/outgoing/controlMessage/UnsendMessage';
import {
AttachmentPointerWithUrl,
PreviewWithAttachmentUrl,
Quote,
VisibleMessage,
} from '../../messages/outgoing/visibleMessage/VisibleMessage';
import { ConfigurationSync } from '../job_runners/jobs/ConfigurationSyncJob';
import { fromBase64ToArray, fromHexToArray } from '../String';
import { Storage } from '../../../util/storage';
import { ReleasedFeatures } from '../../../util/releaseFeature';
import { getCompleteUrlFromRoom } from '../../apis/open_group_api/utils/OpenGroupUtils';
import { PubKey } from '../../types';
import { DisappearingMessageUpdate } from '../../../util/expiringMessages';
import { ExpirationTimerUpdateMessage } from '../../messages/outgoing/controlMessage/ExpirationTimerUpdateMessage';
import { UnsendMessage } from '../../messages/outgoing/controlMessage/UnsendMessage';
import { DataMessage } from '../../messages/outgoing';
import { fromBase64ToArray, fromHexToArray } from '../String';
import { ConfigurationSync } from '../job_runners/jobs/ConfigurationSyncJob';
const ITEM_ID_LAST_SYNC_TIMESTAMP = 'lastSyncedTimestamp';

@ -16,11 +16,11 @@ import {
PropsForMessageRequestResponse,
} from '../../models/messageType';
import { getConversationController } from '../../session/conversations';
import { ReactionList } from '../../types/Reaction';
import {
DisappearingMessageConversationModeType,
DisappearingMessageType,
} from '../../util/expiringMessages';
} from '../../session/disappearing_messages/types';
import { ReactionList } from '../../types/Reaction';
export type CallNotificationType = 'missed-call' | 'started-call' | 'answered-a-call';

@ -1,17 +1,17 @@
import { isString } from 'lodash';
import { useSelector } from 'react-redux';
import { ConversationTypeEnum, isOpenOrClosedGroup } from '../../models/conversationAttributes';
import { PubKey } from '../../session/types';
import { UserUtils } from '../../session/utils';
import { StateType } from '../reducer';
import { getCanWrite, getModerators, getSubscriberCount } from './sogsRoomInfo';
import { getIsMessageSelectionMode, getSelectedConversation } from './conversations';
import {
DisappearingMessageConversationModes,
DisappearingMessageConversationModeType,
} from '../../util/expiringMessages';
DisappearingMessageConversationModes,
} from '../../session/disappearing_messages/types';
import { PubKey } from '../../session/types';
import { UserUtils } from '../../session/utils';
import { ReleasedFeatures } from '../../util/releaseFeature';
import { ReduxConversationType } from '../ducks/conversations';
import { StateType } from '../reducer';
import { getIsMessageSelectionMode, getSelectedConversation } from './conversations';
import { getCanWrite, getModerators, getSubscriberCount } from './sogsRoomInfo';
/**
* Returns the formatted text for notification setting.

@ -4,11 +4,13 @@ import Sinon from 'sinon';
import { ConversationModel } from '../../../../models/conversation';
import { ConversationTypeEnum } from '../../../../models/conversationAttributes';
import { GetNetworkTime } from '../../../../session/apis/snode_api/getNetworkTime';
import { UserUtils } from '../../../../session/utils';
import { isValidUnixTimestamp } from '../../../../session/utils/Timestamps';
import {
DisappearingMessageConversationModeType,
DisappearingMessageType,
} from '../../../../session/disappearing_messages/types';
import { UserUtils } from '../../../../session/utils';
import { isValidUnixTimestamp } from '../../../../session/utils/Timestamps';
import {
changeToDisappearingConversationMode,
changeToDisappearingMessageType,
checkForExpireUpdateInContentMessage,

@ -1,20 +1,23 @@
import { v4 as uuid } from 'uuid';
import { isEmpty } from 'lodash';
import { generateFakePubKey } from './pubkey';
import { ClosedGroupVisibleMessage } from '../../../session/messages/outgoing/visibleMessage/ClosedGroupVisibleMessage';
import { VisibleMessage } from '../../../session/messages/outgoing/visibleMessage/VisibleMessage';
import { OpenGroupMessageV2 } from '../../../session/apis/open_group_api/opengroupV2/OpenGroupMessageV2';
import { v4 as uuid } from 'uuid';
import { TestUtils } from '..';
import { OpenGroupRequestCommonType } from '../../../session/apis/open_group_api/opengroupV2/ApiUtil';
import { OpenGroupVisibleMessage } from '../../../session/messages/outgoing/visibleMessage/OpenGroupVisibleMessage';
import { MessageModel } from '../../../models/message';
import { OpenGroupRequestCommonType } from '../../../session/apis/open_group_api/opengroupV2/ApiUtil';
import { OpenGroupMessageV2 } from '../../../session/apis/open_group_api/opengroupV2/OpenGroupMessageV2';
import {
OpenGroupMessageV4,
OpenGroupReactionMessageV4,
} from '../../../session/apis/open_group_api/opengroupV2/OpenGroupServerPoller';
import { OpenGroupReaction } from '../../../types/Reaction';
import { DisappearingMessageType, ExpirationTimerUpdate } from '../../../util/expiringMessages';
import {
DisappearingMessageType,
ExpirationTimerUpdate,
} from '../../../session/disappearing_messages/types';
import { ExpirationTimerUpdateMessage } from '../../../session/messages/outgoing/controlMessage/ExpirationTimerUpdateMessage';
import { ClosedGroupVisibleMessage } from '../../../session/messages/outgoing/visibleMessage/ClosedGroupVisibleMessage';
import { OpenGroupVisibleMessage } from '../../../session/messages/outgoing/visibleMessage/OpenGroupVisibleMessage';
import { VisibleMessage } from '../../../session/messages/outgoing/visibleMessage/VisibleMessage';
import { OpenGroupReaction } from '../../../types/Reaction';
import { generateFakePubKey } from './pubkey';
export function generateVisibleMessage({
identifier,

@ -1,7 +1,5 @@
import { throttle, uniq } from 'lodash';
import moment from 'moment';
import { messagesExpired } from '../state/ducks/conversations';
import { LocalizerKeys } from '../types/LocalizerKeys';
import { initWallClockListener } from './wallClockListener';
import { Data } from '../data/data';
@ -11,50 +9,15 @@ import { ProtobufUtils, SignalService } from '../protobuf';
import { expireMessageOnSnode } from '../session/apis/snode_api/expireRequest';
import { GetNetworkTime } from '../session/apis/snode_api/getNetworkTime';
import { getConversationController } from '../session/conversations';
import {
DisappearingMessageConversationModeType,
DisappearingMessageMode,
DisappearingMessageType,
DisappearingMessageUpdate,
} from '../session/disappearing_messages/types';
import { isValidUnixTimestamp } from '../session/utils/Timestamps';
import { ReleasedFeatures } from './releaseFeature';
// NOTE this must match Content.ExpirationType in the protobuf
// TODO double check this
export const DisappearingMessageMode = ['unknown', 'deleteAfterRead', 'deleteAfterSend'] as const;
export type DisappearingMessageType = typeof DisappearingMessageMode[number];
export type DisappearAfterSendOnly = Exclude<DisappearingMessageType, 'deleteAfterRead'>;
// NOTE these cannot be imported in the nodejs side yet. We need to move the types to the own file with no window imports
// TODO legacy messages support will be removed in a future release
// TODO NOTE legacy is strictly used in the UI and is not a valid disappearing message mode
export const DisappearingMessageConversationModes = [
'off',
DisappearingMessageMode[1], // deleteAfterRead
DisappearingMessageMode[2], // deleteAfterSend
'legacy',
] as const;
export type DisappearingMessageConversationModeType = typeof DisappearingMessageConversationModes[number]; // TODO we should make this type a bit more hardcoded than being just resolved as a string
// TODO legacy messages support will be removed in a future release
// expirationType and lastDisappearingMessageChangeTimestamp will no longer have an undefined option
/** Used for setting disappearing messages in conversations */
export type ExpirationTimerUpdate = {
expirationType: DisappearingMessageType | undefined;
expireTimer: number;
lastDisappearingMessageChangeTimestamp: number | undefined;
source: string;
/** updated setting from another device */
fromSync?: boolean;
};
export type DisappearingMessageUpdate = {
expirationType: DisappearingMessageType;
expirationTimer: number;
// This is used for the expirationTimerUpdate
lastDisappearingMessageChangeTimestamp?: number;
// TODO legacy messages support will be removed in a future release
isLegacyConversationSettingMessage?: boolean;
isLegacyDataMessage?: boolean;
isDisappearingMessagesV2Released?: boolean;
shouldDisappearButIsntMessage?: boolean;
isOutdated?: boolean;
};
export async function destroyMessagesAndUpdateRedux(
messages: Array<{
conversationKey: string;
@ -125,6 +88,7 @@ async function destroyExpiredMessages() {
}
let timeout: NodeJS.Timeout | undefined;
async function checkExpiringMessages() {
// Look up the next expiring message and set a timer to destroy it
const messages = await Data.getNextExpiringMessage();
@ -178,131 +142,11 @@ const updateExpiringMessagesCheck = () => {
void throttledCheckExpiringMessages();
};
// #region Timer Options
const timerOptionsDurations: Array<{
time: number;
unit: moment.DurationInputArg2;
seconds: number;
}> = [
{ time: 0, unit: 'seconds' as moment.DurationInputArg2 },
{ time: 5, unit: 'seconds' as moment.DurationInputArg2 },
{ time: 10, unit: 'seconds' as moment.DurationInputArg2 },
{ time: 30, unit: 'seconds' as moment.DurationInputArg2 },
{ time: 1, unit: 'minute' as moment.DurationInputArg2 },
{ time: 5, unit: 'minutes' as moment.DurationInputArg2 },
{ time: 30, unit: 'minutes' as moment.DurationInputArg2 },
{ time: 1, unit: 'hour' as moment.DurationInputArg2 },
{ time: 6, unit: 'hours' as moment.DurationInputArg2 },
{ time: 12, unit: 'hours' as moment.DurationInputArg2 },
{ time: 1, unit: 'day' as moment.DurationInputArg2 },
{ time: 1, unit: 'week' as moment.DurationInputArg2 },
{ time: 2, unit: 'weeks' as moment.DurationInputArg2 },
].map(o => {
const duration = moment.duration(o.time, o.unit); // 5, 'seconds'
return {
time: o.time,
unit: o.unit,
seconds: duration.asSeconds(),
};
});
function getTimerOptionName(time: number, unit: moment.DurationInputArg2) {
return (
window.i18n(['timerOption', time, unit].join('_') as LocalizerKeys) ||
moment.duration(time, unit).humanize()
);
}
function getTimerOptionAbbreviated(time: number, unit: string) {
return window.i18n(['timerOption', time, unit, 'abbreviated'].join('_') as LocalizerKeys);
}
function getName(seconds = 0) {
const o = timerOptionsDurations.find(m => m.seconds === seconds);
if (o) {
return getTimerOptionName(o.time, o.unit);
}
return [seconds, 'seconds'].join(' ');
}
function getAbbreviated(seconds = 0) {
const o = timerOptionsDurations.find(m => m.seconds === seconds);
if (o) {
return getTimerOptionAbbreviated(o.time, o.unit);
}
return [seconds, 's'].join('');
}
type TimerOptionsEntry = { name: string; value: number };
export type TimerOptionsArray = Array<TimerOptionsEntry>;
export const TIMER_OPTIONS: Array<number> = timerOptionsDurations.map(t => {
return t.seconds;
});
export const DELETE_AFTER_READ_OPTIONS = TIMER_OPTIONS.filter(option => {
return (
option === 10 || // 10 seconds (for development or qa)
option === 30 || // 30 seconds (for development or qa)
option === 60 || // 1 minute (for testing)
option === 300 || // 5 minutes
option === 3600 || // 1 hour
option === 43200 || // 12 hours
option === 86400 || // 1 day
option === 604800 || // 1 week
option === 1209600 // 2 weeks
);
});
export const DELETE_AFTER_SEND_OPTIONS = TIMER_OPTIONS.filter(option => {
return (
option === 10 || // 10 seconds (for development or qa)
option === 30 || // 30 seconds (for development or qa)
option === 60 || // 1 minute (for testing)
option === 43200 || // 12 hours
option === 86400 || // 1 day
option === 604800 || // 1 week
option === 1209600 // 2 weeks
);
});
// TODO legacy messages support will be removed in a future release
export const DELETE_LEGACY_OPTIONS = TIMER_OPTIONS.filter(option => {
return (
option === 5 || // 5 seconds
option === 10 || // 10 seconds
option === 30 || // 30 seconds
option === 60 || // 1 minute
option === 300 || // 5 minutes
option === 1800 || // 30 minutes
option === 3600 || // 1 hour
option === 21600 || // 6 hours
option === 43200 || // 12 hours
option === 86400 || // 1 day
option === 604800 // 1 week
);
});
export const DEFAULT_TIMER_OPTION = {
DELETE_AFTER_READ: 43200, // 12 hours
DELETE_AFTER_SEND: 86400, // 1 day
// TODO legacy messages support will be removed in a future release
LEGACY: 86400, // 1 day
};
export const ExpirationTimerOptions = {
getName,
getAbbreviated,
updateExpiringMessagesCheck,
initExpiringMessageListener,
updateExpiringMessagesCheck,
};
// #endregion Timer Options
export function setExpirationStartTimestamp(
mode: DisappearingMessageConversationModeType,
timestamp?: number,

Loading…
Cancel
Save