feat: add toggle to share history or not with invite group v2

pull/2963/head
Audric Ackermann 1 year ago
parent 392e243b08
commit 8d0bd84ef0

@ -128,10 +128,8 @@ export class SessionConversation extends React.Component<Props, State> {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public componentDidUpdate(prevProps: Props, _prevState: State) { public componentDidUpdate(prevProps: Props, _prevState: State) {
const { const { selectedConversationKey: newConversationKey, selectedConversation: newConversation } =
selectedConversationKey: newConversationKey, this.props;
selectedConversation: newConversation,
} = this.props;
const { selectedConversationKey: oldConversationKey } = prevProps; const { selectedConversationKey: oldConversationKey } = prevProps;
// if the convo is valid, and it changed, register for drag events // if the convo is valid, and it changed, register for drag events

@ -145,15 +145,8 @@ export const MessageContent = (props: Props) => {
return null; return null;
} }
const { const { direction, text, timestamp, serverTimestamp, previews, quote, attachments } =
direction, contentProps;
text,
timestamp,
serverTimestamp,
previews,
quote,
attachments,
} = contentProps;
const hasContentBeforeAttachment = !isEmpty(previews) || !isEmpty(quote) || !isEmpty(text); const hasContentBeforeAttachment = !isEmpty(previews) || !isEmpty(quote) || !isEmpty(text);

@ -21,7 +21,9 @@ type Props = {
const StyledMessageReactBar = styled.div` const StyledMessageReactBar = styled.div`
background-color: var(--emoji-reaction-bar-background-color); background-color: var(--emoji-reaction-bar-background-color);
border-radius: 25px; border-radius: 25px;
box-shadow: 0 2px 16px 0 rgba(0, 0, 0, 0.2), 0 0px 20px 0 rgba(0, 0, 0, 0.19); box-shadow:
0 2px 16px 0 rgba(0, 0, 0, 0.2),
0 0px 20px 0 rgba(0, 0, 0, 0.19);
padding: 4px 8px; padding: 4px 8px;
white-space: nowrap; white-space: nowrap;

@ -125,14 +125,8 @@ export const ExpirableReadableMessage = (props: ExpirableReadableMessageProps) =
return null; return null;
} }
const { const { messageId, direction, receivedAt, isUnread, expirationDurationMs, expirationTimestamp } =
messageId, selected;
direction,
receivedAt,
isUnread,
expirationDurationMs,
expirationTimestamp,
} = selected;
// NOTE we want messages on the left in the message detail view regardless of direction // NOTE we want messages on the left in the message detail view regardless of direction
const isIncoming = props.isDetailView ? true : direction === 'incoming'; const isIncoming = props.isDetailView ? true : direction === 'incoming';

@ -44,8 +44,8 @@ export const InteractionNotification = (props: PropsForInteractionNotification)
text = isCommunity text = isCommunity
? window.i18n('leaveCommunityFailedPleaseTryAgain') ? window.i18n('leaveCommunityFailedPleaseTryAgain')
: isGroup : isGroup
? window.i18n('leaveGroupFailedPleaseTryAgain') ? window.i18n('leaveGroupFailedPleaseTryAgain')
: window.i18n('deleteConversationFailedPleaseTryAgain'); : window.i18n('deleteConversationFailedPleaseTryAgain');
break; break;
default: default:
assertUnreachable( assertUnreachable(

@ -172,8 +172,8 @@ export const OverlayDisappearingMessages = () => {
{singleMode === 'deleteAfterRead' {singleMode === 'deleteAfterRead'
? window.i18n('disappearingMessagesModeAfterReadSubtitle') ? window.i18n('disappearingMessagesModeAfterReadSubtitle')
: singleMode === 'deleteAfterSend' : singleMode === 'deleteAfterSend'
? window.i18n('disappearingMessagesModeAfterSendSubtitle') ? window.i18n('disappearingMessagesModeAfterSendSubtitle')
: window.i18n('settingAppliesToYourMessages')} : window.i18n('settingAppliesToYourMessages')}
</HeaderSubtitle> </HeaderSubtitle>
</Header> </Header>
<DisappearingModes <DisappearingModes
@ -194,8 +194,8 @@ export const OverlayDisappearingMessages = () => {
singleMode singleMode
? disappearingModeOptions[singleMode] ? disappearingModeOptions[singleMode]
: modeSelected : modeSelected
? disappearingModeOptions[modeSelected] ? disappearingModeOptions[modeSelected]
: undefined : undefined
} }
/> />
</> </>
@ -217,8 +217,8 @@ export const OverlayDisappearingMessages = () => {
singleMode singleMode
? disappearingModeOptions[singleMode] ? disappearingModeOptions[singleMode]
: modeSelected : modeSelected
? disappearingModeOptions[modeSelected] ? disappearingModeOptions[modeSelected]
: undefined : undefined
} }
dataTestId={'disappear-set-button'} dataTestId={'disappear-set-button'}
> >

@ -1,4 +1,4 @@
import React from 'react'; import React, { useState } from 'react';
import useKey from 'react-use/lib/useKey'; import useKey from 'react-use/lib/useKey';
import { PubkeyType } from 'libsession_util_nodejs'; import { PubkeyType } from 'libsession_util_nodejs';
@ -25,10 +25,12 @@ import { SessionUtilUserGroups } from '../../session/utils/libsession/libsession
import { groupInfoActions } from '../../state/ducks/metaGroups'; import { groupInfoActions } from '../../state/ducks/metaGroups';
import { useContactsToInviteToGroup } from '../../state/selectors/conversations'; import { useContactsToInviteToGroup } from '../../state/selectors/conversations';
import { useMemberGroupChangePending } from '../../state/selectors/groups'; import { useMemberGroupChangePending } from '../../state/selectors/groups';
import { useSelectedIsGroupV2 } from '../../state/selectors/selectedConversation';
import { MemberListItem } from '../MemberListItem'; import { MemberListItem } from '../MemberListItem';
import { SessionWrapperModal } from '../SessionWrapperModal'; import { SessionWrapperModal } from '../SessionWrapperModal';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton'; import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
import { SessionSpinner } from '../basic/SessionSpinner'; import { SessionSpinner } from '../basic/SessionSpinner';
import { SessionToggle } from '../basic/SessionToggle';
type Props = { type Props = {
conversationId: string; conversationId: string;
@ -122,6 +124,8 @@ const InviteContactsDialogInner = (props: Props) => {
const membersFromRedux = useSortedGroupMembers(conversationId); const membersFromRedux = useSortedGroupMembers(conversationId);
const zombiesFromRedux = useZombies(conversationId); const zombiesFromRedux = useZombies(conversationId);
const displayName = useConversationUsername(conversationId); const displayName = useConversationUsername(conversationId);
const isGroupV2 = useSelectedIsGroupV2();
const [shareHistory, setShareHistory] = useState(false);
const { uniqueValues: selectedContacts, addTo, removeFrom } = useSet<string>(); const { uniqueValues: selectedContacts, addTo, removeFrom } = useSet<string>();
@ -149,9 +153,10 @@ const InviteContactsDialogInner = (props: Props) => {
void submitForOpenGroup(conversationId, selectedContacts); void submitForOpenGroup(conversationId, selectedContacts);
} else { } else {
if (PubKey.is03Pubkey(conversationId)) { if (PubKey.is03Pubkey(conversationId)) {
const forcedAsPubkeys = selectedContacts as Array<PubkeyType>;
const action = groupInfoActions.currentDeviceGroupMembersChange({ const action = groupInfoActions.currentDeviceGroupMembersChange({
addMembersWithoutHistory: selectedContacts as Array<PubkeyType>, addMembersWithoutHistory: shareHistory ? [] : forcedAsPubkeys,
addMembersWithHistory: [], addMembersWithHistory: shareHistory ? forcedAsPubkeys : [],
removeMembers: [], removeMembers: [],
groupPk: conversationId, groupPk: conversationId,
}); });
@ -184,7 +189,12 @@ const InviteContactsDialogInner = (props: Props) => {
return ( return (
<SessionWrapperModal title={titleText} onClose={closeDialog}> <SessionWrapperModal title={titleText} onClose={closeDialog}>
<SpacerLG /> <SpacerLG />
{isGroupV2 && (
<span style={{ display: 'flex', alignItems: 'center' }}>
Share History?{' '}
<SessionToggle active={shareHistory} onClick={() => setShareHistory(!shareHistory)} />
</span>
)}
<div className="contact-selection-list"> <div className="contact-selection-list">
{hasContacts ? ( {hasContacts ? (
validContactsForInvite.map((member: string) => ( validContactsForInvite.map((member: string) => (
@ -208,7 +218,6 @@ const InviteContactsDialogInner = (props: Props) => {
<SpacerLG /> <SpacerLG />
<SessionSpinner loading={isProcessingUIChange} /> <SessionSpinner loading={isProcessingUIChange} />
<SpacerLG /> <SpacerLG />
<div className="session-modal__button-group"> <div className="session-modal__button-group">
<SessionButton <SessionButton
text={okText} text={okText}

File diff suppressed because one or more lines are too long

@ -174,12 +174,8 @@ const setupTheme = async () => {
// Do this only if we created a new Session ID, or if we already received the initial configuration message // Do this only if we created a new Session ID, or if we already received the initial configuration message
const triggerSyncIfNeeded = async () => { const triggerSyncIfNeeded = async () => {
const us = UserUtils.getOurPubKeyStrFromCache(); const us = UserUtils.getOurPubKeyStrFromCache();
await ConvoHub.use() await ConvoHub.use().get(us).setDidApproveMe(true, true);
.get(us) await ConvoHub.use().get(us).setIsApproved(true, true);
.setDidApproveMe(true, true);
await ConvoHub.use()
.get(us)
.setIsApproved(true, true);
const didWeHandleAConfigurationMessageAlready = const didWeHandleAConfigurationMessageAlready =
(await Data.getItemById(SettingsKey.hasSyncedInitialConfigurationItem))?.value || false; (await Data.getItemById(SettingsKey.hasSyncedInitialConfigurationItem))?.value || false;
if (didWeHandleAConfigurationMessageAlready) { if (didWeHandleAConfigurationMessageAlready) {

@ -352,28 +352,29 @@ export function useIsTyping(conversationId?: string): boolean {
return useConversationPropsById(conversationId)?.isTyping || false; return useConversationPropsById(conversationId)?.isTyping || false;
} }
const getMessageExpirationProps = createSelector(getMessagePropsByMessageId, (props): const getMessageExpirationProps = createSelector(
| PropsForExpiringMessage getMessagePropsByMessageId,
| undefined => { (props): PropsForExpiringMessage | undefined => {
if (!props || isEmpty(props)) { if (!props || isEmpty(props)) {
return undefined; return undefined;
} }
const msgProps: PropsForExpiringMessage = { const msgProps: PropsForExpiringMessage = {
...pick(props.propsForMessage, [ ...pick(props.propsForMessage, [
'convoId', 'convoId',
'direction', 'direction',
'receivedAt', 'receivedAt',
'isUnread', 'isUnread',
'expirationTimestamp', 'expirationTimestamp',
'expirationDurationMs', 'expirationDurationMs',
'isExpired', 'isExpired',
]), ]),
messageId: props.propsForMessage.id, messageId: props.propsForMessage.id,
}; };
return msgProps; return msgProps;
}); }
);
export function useMessageExpirationPropsById(messageId?: string) { export function useMessageExpirationPropsById(messageId?: string) {
return useSelector((state: StateType) => { return useSelector((state: StateType) => {
@ -430,9 +431,7 @@ export function useTimerOptionsByMode(disappearingMessageMode?: string, hasOnlyO
}, [disappearingMessageMode, hasOnlyOneMode]); }, [disappearingMessageMode, hasOnlyOneMode]);
} }
export function useQuoteAuthorName( export function useQuoteAuthorName(authorId?: string): {
authorId?: string
): {
authorName: string | undefined; authorName: string | undefined;
isMe: boolean; isMe: boolean;
} { } {
@ -442,8 +441,8 @@ export function useQuoteAuthorName(
const authorName = isMe const authorName = isMe
? window.i18n('you') ? window.i18n('you')
: convoProps?.nickname || convoProps?.isPrivate : convoProps?.nickname || convoProps?.isPrivate
? convoProps?.displayNameInProfile ? convoProps?.displayNameInProfile
: undefined; : undefined;
return { authorName, isMe }; return { authorName, isMe };
} }
@ -495,12 +494,12 @@ export function useDisappearingMessageSettingText({
expirationMode === 'deleteAfterRead' expirationMode === 'deleteAfterRead'
? window.i18n('disappearingMessagesModeAfterRead') ? window.i18n('disappearingMessagesModeAfterRead')
: expirationMode === 'deleteAfterSend' : expirationMode === 'deleteAfterSend'
? window.i18n('disappearingMessagesModeAfterSend')
: expirationMode === 'legacy'
? isMe || (isGroup && !isPublic)
? window.i18n('disappearingMessagesModeAfterSend') ? window.i18n('disappearingMessagesModeAfterSend')
: window.i18n('disappearingMessagesModeAfterRead') : expirationMode === 'legacy'
: null; ? isMe || (isGroup && !isPublic)
? window.i18n('disappearingMessagesModeAfterSend')
: window.i18n('disappearingMessagesModeAfterRead')
: null;
const expireTimerText = isNumber(expireTimer) const expireTimerText = isNumber(expireTimer)
? abbreviate ? abbreviate

@ -206,9 +206,7 @@ export const declineConversationWithConfirm = ({
const okKey: LocalizerKeys = alsoBlock ? 'block' : 'delete'; const okKey: LocalizerKeys = alsoBlock ? 'block' : 'delete';
const nameToBlock = const nameToBlock =
alsoBlock && !!conversationIdOrigin alsoBlock && !!conversationIdOrigin
? ConvoHub.use() ? ConvoHub.use().get(conversationIdOrigin)?.getContactProfileNameOrShortenedPubKey()
.get(conversationIdOrigin)
?.getContactProfileNameOrShortenedPubKey()
: null; : null;
const messageKey: LocalizerKeys = isGroupV2 const messageKey: LocalizerKeys = isGroupV2
? alsoBlock && nameToBlock ? alsoBlock && nameToBlock
@ -621,9 +619,7 @@ export async function uploadOurAvatar(newAvatarDecrypted?: ArrayBuffer) {
} else { } else {
// this is a reupload. no need to generate a new profileKey // this is a reupload. no need to generate a new profileKey
const ourConvoProfileKey = const ourConvoProfileKey =
ConvoHub.use() ConvoHub.use().get(UserUtils.getOurPubKeyStrFromCache())?.getProfileKey() || null;
.get(UserUtils.getOurPubKeyStrFromCache())
?.getProfileKey() || null;
profileKey = ourConvoProfileKey ? fromHexToArray(ourConvoProfileKey) : null; profileKey = ourConvoProfileKey ? fromHexToArray(ourConvoProfileKey) : null;
if (!profileKey) { if (!profileKey) {

@ -2243,8 +2243,8 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
const interactionNotification = lastMessageModel.getInteractionNotification(); const interactionNotification = lastMessageModel.getInteractionNotification();
const lastMessageInteractionType = interactionNotification?.interactionType; const lastMessageInteractionType = interactionNotification?.interactionType;
const lastMessageInteractionStatus = lastMessageModel.getInteractionNotification() const lastMessageInteractionStatus =
?.interactionStatus; lastMessageModel.getInteractionNotification()?.interactionStatus;
const lastMessageStatus = lastMessageModel.getMessagePropStatus() || undefined; const lastMessageStatus = lastMessageModel.getMessagePropStatus() || undefined;
const lastMessageNotificationText = lastMessageModel.getNotificationText() || undefined; const lastMessageNotificationText = lastMessageModel.getNotificationText() || undefined;
// we just want to set the `status` to `undefined` if there are no `lastMessageNotificationText` // we just want to set the `status` to `undefined` if there are no `lastMessageNotificationText`

@ -487,7 +487,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
if (groupUpdate.joinedWithHistory?.length) { if (groupUpdate.joinedWithHistory?.length) {
const change: PropsForGroupUpdateAdd = { const change: PropsForGroupUpdateAdd = {
type: 'add', type: 'add',
added: groupUpdate.joined as Array<PubkeyType>, added: groupUpdate.joinedWithHistory as Array<PubkeyType>,
withHistory: true, withHistory: true,
}; };
return { change, ...sharedProps }; return { change, ...sharedProps };
@ -763,9 +763,8 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
const quoteWithData = await loadQuoteData(this.get('quote')); const quoteWithData = await loadQuoteData(this.get('quote'));
const previewWithData = await loadPreviewData(this.get('preview')); const previewWithData = await loadPreviewData(this.get('preview'));
const { hasAttachments, hasVisualMediaAttachments, hasFileAttachments } = getAttachmentMetadata( const { hasAttachments, hasVisualMediaAttachments, hasFileAttachments } =
this getAttachmentMetadata(this);
);
this.set({ hasAttachments, hasVisualMediaAttachments, hasFileAttachments }); this.set({ hasAttachments, hasVisualMediaAttachments, hasFileAttachments });
await this.commit(); await this.commit();
@ -816,8 +815,9 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
} }
window.log.info( window.log.info(
`Upload of message data for message ${this.idForLogging()} is finished in ${Date.now() - `Upload of message data for message ${this.idForLogging()} is finished in ${
start}ms.` Date.now() - start
}ms.`
); );
return { return {
body, body,
@ -1266,24 +1266,34 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
const left: Array<string> | undefined = Array.isArray(groupUpdate.left) const left: Array<string> | undefined = Array.isArray(groupUpdate.left)
? groupUpdate.left ? groupUpdate.left
: groupUpdate.left : groupUpdate.left
? [groupUpdate.left] ? [groupUpdate.left]
: undefined; : undefined;
const kicked: Array<string> | undefined = Array.isArray(groupUpdate.kicked) const kicked: Array<string> | undefined = Array.isArray(groupUpdate.kicked)
? groupUpdate.kicked ? groupUpdate.kicked
: groupUpdate.kicked : groupUpdate.kicked
? [groupUpdate.kicked] ? [groupUpdate.kicked]
: undefined; : undefined;
const joined: Array<string> | undefined = Array.isArray(groupUpdate.joined) const joined: Array<string> | undefined = Array.isArray(groupUpdate.joined)
? groupUpdate.joined ? groupUpdate.joined
: groupUpdate.joined : groupUpdate.joined
? [groupUpdate.joined] ? [groupUpdate.joined]
: undefined; : undefined;
const joinedWithHistory: Array<string> | undefined = Array.isArray(
groupUpdate.joinedWithHistory
)
? groupUpdate.joinedWithHistory
: groupUpdate.joinedWithHistory
? [groupUpdate.joinedWithHistory]
: undefined;
const forcedArrayUpdate: MessageGroupUpdate = {}; const forcedArrayUpdate: MessageGroupUpdate = {};
if (left) { if (left) {
forcedArrayUpdate.left = left; forcedArrayUpdate.left = left;
} }
if (joinedWithHistory) {
forcedArrayUpdate.joinedWithHistory = joinedWithHistory;
}
if (joined) { if (joined) {
forcedArrayUpdate.joined = joined; forcedArrayUpdate.joined = joined;
} }
@ -1404,8 +1414,8 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
return isCommunity return isCommunity
? window.i18n('leaveCommunityFailed') ? window.i18n('leaveCommunityFailed')
: isGroup : isGroup
? window.i18n('leaveGroupFailed') ? window.i18n('leaveGroupFailed')
: window.i18n('deleteConversationFailed'); : window.i18n('deleteConversationFailed');
default: default:
assertUnreachable( assertUnreachable(
interactionType, interactionType,

@ -94,7 +94,6 @@ function decodeBatchRequest(snodeResponse: SnodeResponse): NotEmptyArrayOfBatchR
try { try {
// console.error('decodeBatch: ', snodeResponse); // console.error('decodeBatch: ', snodeResponse);
if (snodeResponse.status !== 200) { if (snodeResponse.status !== 200) {
debugger;
throw new Error(`decodeBatchRequest invalid status code: ${snodeResponse.status}`); throw new Error(`decodeBatchRequest invalid status code: ${snodeResponse.status}`);
} }
const parsed = JSON.parse(snodeResponse.body); const parsed = JSON.parse(snodeResponse.body);

@ -257,6 +257,8 @@ function toRole(namespace: number) {
return 'groupInfo'; return 'groupInfo';
case SnodeNamespaces.ClosedGroupMembers: case SnodeNamespaces.ClosedGroupMembers:
return 'groupMembers'; return 'groupMembers';
case SnodeNamespaces.ClosedGroupRevokedRetrievableMessages:
return 'groupRevoked';
default: default:
return `${namespace}`; return `${namespace}`;
} }

@ -87,9 +87,11 @@ async function encryptOnionV4RequestForPubkey(
) { ) {
const plaintext = encodeV4Request(requestInfo); const plaintext = encodeV4Request(requestInfo);
return callUtilsWorker('encryptForPubkey', pubKeyX25519hex, plaintext) as Promise< return callUtilsWorker(
DestinationContext 'encryptForPubkey',
>; pubKeyX25519hex,
plaintext
) as Promise<DestinationContext>;
} }
// Returns the actual ciphertext, symmetric key that will be used // Returns the actual ciphertext, symmetric key that will be used
// for decryption, and an ephemeral_key to send to the next hop // for decryption, and an ephemeral_key to send to the next hop
@ -99,9 +101,11 @@ async function encryptForPubKey(
): Promise<DestinationContext> { ): Promise<DestinationContext> {
const plaintext = new TextEncoder().encode(JSON.stringify(requestInfo)); const plaintext = new TextEncoder().encode(JSON.stringify(requestInfo));
return callUtilsWorker('encryptForPubkey', pubKeyX25519hex, plaintext) as Promise< return callUtilsWorker(
DestinationContext 'encryptForPubkey',
>; pubKeyX25519hex,
plaintext
) as Promise<DestinationContext>;
} }
export type DestinationRelayV2 = { export type DestinationRelayV2 = {

@ -728,17 +728,16 @@ function retrieveItemWithNamespace(
): Array<RetrieveMessageItemWithNamespace> { ): Array<RetrieveMessageItemWithNamespace> {
return flatten( return flatten(
compact( compact(
results.map( results.map(result =>
result => result.messages.messages?.map(r => {
result.messages.messages?.map(r => { // throws if the result is not expected
// throws if the result is not expected const parsedItem = retrieveItemSchema.parse(r);
const parsedItem = retrieveItemSchema.parse(r); return {
return { ...omit(parsedItem, 'timestamp'),
...omit(parsedItem, 'timestamp'), namespace: result.namespace,
namespace: result.namespace, storedAt: parsedItem.timestamp,
storedAt: parsedItem.timestamp, };
}; })
})
) )
) )
); );

@ -59,9 +59,7 @@ export async function destroyMessagesAndUpdateRedux(
// trigger a refresh the last message for all those uniq conversation // trigger a refresh the last message for all those uniq conversation
conversationWithChanges.forEach(convoIdToUpdate => { conversationWithChanges.forEach(convoIdToUpdate => {
ConvoHub.use() ConvoHub.use().get(convoIdToUpdate)?.updateLastMessage();
.get(convoIdToUpdate)
?.updateLastMessage();
}); });
} }
@ -91,12 +89,8 @@ async function destroyExpiredMessages() {
window.log.info('destroyExpiredMessages: convosToRefresh:', convosToRefresh); window.log.info('destroyExpiredMessages: convosToRefresh:', convosToRefresh);
await Promise.all( await Promise.all(
convosToRefresh.map(async c => { convosToRefresh.map(async c => {
ConvoHub.use() ConvoHub.use().get(c)?.updateLastMessage();
.get(c) return ConvoHub.use().get(c)?.refreshInMemoryDetails();
?.updateLastMessage();
return ConvoHub.use()
.get(c)
?.refreshInMemoryDetails();
}) })
); );
} catch (error) { } catch (error) {
@ -278,9 +272,7 @@ function changeToDisappearingMessageType(
* This should only be used for DataExtractionNotification and CallMessages (the ones saved to the DB) currently. * This should only be used for DataExtractionNotification and CallMessages (the ones saved to the DB) currently.
* Note: this can only be called for private conversations, excluding ourselves as it throws otherwise (this wouldn't be right) * Note: this can only be called for private conversations, excluding ourselves as it throws otherwise (this wouldn't be right)
* */ * */
function forcedDeleteAfterReadMsgSetting( function forcedDeleteAfterReadMsgSetting(convo: ConversationModel): {
convo: ConversationModel
): {
expirationType: Exclude<DisappearingMessageType, 'deleteAfterSend'>; expirationType: Exclude<DisappearingMessageType, 'deleteAfterSend'>;
expireTimer: number; expireTimer: number;
} { } {
@ -307,9 +299,7 @@ function forcedDeleteAfterReadMsgSetting(
* This should only be used for the outgoing CallMessages that we keep locally only (not synced, just the "you started a call" notification) * This should only be used for the outgoing CallMessages that we keep locally only (not synced, just the "you started a call" notification)
* Note: this can only be called for private conversations, excluding ourselves as it throws otherwise (this wouldn't be right) * Note: this can only be called for private conversations, excluding ourselves as it throws otherwise (this wouldn't be right)
* */ * */
function forcedDeleteAfterSendMsgSetting( function forcedDeleteAfterSendMsgSetting(convo: ConversationModel): {
convo: ConversationModel
): {
expirationType: Exclude<DisappearingMessageType, 'deleteAfterRead'>; expirationType: Exclude<DisappearingMessageType, 'deleteAfterRead'>;
expireTimer: number; expireTimer: number;
} { } {
@ -365,7 +355,8 @@ async function checkForExpireUpdateInContentMessage(
): Promise<DisappearingMessageUpdate | undefined> { ): Promise<DisappearingMessageUpdate | undefined> {
const dataMessage = content.dataMessage as SignalService.DataMessage | undefined; const dataMessage = content.dataMessage as SignalService.DataMessage | undefined;
// We will only support legacy disappearing messages for a short period before disappearing messages v2 is unlocked // We will only support legacy disappearing messages for a short period before disappearing messages v2 is unlocked
const isDisappearingMessagesV2Released = await ReleasedFeatures.checkIsDisappearMessageV2FeatureReleased(); const isDisappearingMessagesV2Released =
await ReleasedFeatures.checkIsDisappearMessageV2FeatureReleased();
const couldBeLegacyContentMessage = couldBeLegacyDisappearingMessageContent(content); const couldBeLegacyContentMessage = couldBeLegacyDisappearingMessageContent(content);
const isLegacyDataMessage = const isLegacyDataMessage =
@ -565,9 +556,9 @@ function getMessageReadyToDisappear(
if (msgExpirationWasAlreadyUpdated) { if (msgExpirationWasAlreadyUpdated) {
const expirationStartTimestamp = messageExpirationFromRetrieve - expireTimer * 1000; const expirationStartTimestamp = messageExpirationFromRetrieve - expireTimer * 1000;
window.log.debug( window.log.debug(
`incoming DaR message already read by another device, forcing readAt ${(Date.now() - `incoming DaR message already read by another device, forcing readAt ${
expirationStartTimestamp) / (Date.now() - expirationStartTimestamp) / 1000
1000}s ago, so with ${(messageExpirationFromRetrieve - Date.now()) / 1000}s left` }s ago, so with ${(messageExpirationFromRetrieve - Date.now()) / 1000}s left`
); );
messageModel.set({ messageModel.set({
expirationStartTimestamp, expirationStartTimestamp,

@ -166,7 +166,11 @@ export async function addUpdateMessage({
if (diff.type === 'name' && diff.newName) { if (diff.type === 'name' && diff.newName) {
groupUpdate.name = diff.newName; groupUpdate.name = diff.newName;
} else if (diff.type === 'add' && diff.added) { } else if (diff.type === 'add' && diff.added) {
groupUpdate.joined = diff.added; if (diff.withHistory) {
groupUpdate.joinedWithHistory = diff.added;
} else {
groupUpdate.joined = diff.added;
}
} else if (diff.type === 'left' && diff.left) { } else if (diff.type === 'left' && diff.left) {
groupUpdate.left = diff.left; groupUpdate.left = diff.left;
} else if (diff.type === 'kicked' && diff.kicked) { } else if (diff.type === 'kicked' && diff.kicked) {

@ -784,7 +784,7 @@ async function handleMemberAddedFromUI({
const updateMessagesToPush: Array<GroupUpdateMemberChangeMessage> = []; const updateMessagesToPush: Array<GroupUpdateMemberChangeMessage> = [];
if (withHistory.length) { if (withHistory.length) {
const msgModel = await ClosedGroup.addUpdateMessage({ const msgModel = await ClosedGroup.addUpdateMessage({
diff: { type: 'add', added: withHistory, withHistory: false }, diff: { type: 'add', added: withHistory, withHistory: true },
...shared, ...shared,
}); });
const groupChange = await getWithHistoryControlMessage({ const groupChange = await getWithHistoryControlMessage({
@ -801,7 +801,7 @@ async function handleMemberAddedFromUI({
} }
if (withoutHistory.length) { if (withoutHistory.length) {
const msgModel = await ClosedGroup.addUpdateMessage({ const msgModel = await ClosedGroup.addUpdateMessage({
diff: { type: 'add', added: withoutHistory, withHistory: true }, diff: { type: 'add', added: withoutHistory, withHistory: false },
...shared, ...shared,
}); });
const groupChange = await getWithoutHistoryControlMessage({ const groupChange = await getWithoutHistoryControlMessage({

Loading…
Cancel
Save