diff --git a/protos/SignalService.proto b/protos/SignalService.proto
index 5242d158e..853cef89b 100644
--- a/protos/SignalService.proto
+++ b/protos/SignalService.proto
@@ -146,7 +146,6 @@ message GroupUpdateMessage {
optional GroupUpdateInviteResponseMessage inviteResponse = 6;
optional GroupUpdateDeleteMemberContentMessage deleteMemberContent = 7;
optional GroupUpdateMemberLeftNotificationMessage memberLeftNotificationMessage = 8;
-
}
diff --git a/ts/components/NoticeBanner.tsx b/ts/components/NoticeBanner.tsx
index 8bd13b690..659870166 100644
--- a/ts/components/NoticeBanner.tsx
+++ b/ts/components/NoticeBanner.tsx
@@ -12,9 +12,12 @@ const StyledNoticeBanner = styled(Flex)`
padding: var(--margins-xs) var(--margins-sm);
text-align: center;
flex-shrink: 0;
+ cursor: pointer;
+
.session-icon-button {
position: absolute;
right: var(--margins-sm);
+ pointer-events: none;
}
`;
@@ -25,12 +28,12 @@ const StyledText = styled.span`
type NoticeBannerProps = {
text: string;
icon: SessionIconType;
- onButtonClick: () => void;
+ onBannerClick: () => void;
dataTestId: SessionDataTestId;
};
export const NoticeBanner = (props: NoticeBannerProps) => {
- const { text, onButtonClick, icon, dataTestId } = props;
+ const { text, onBannerClick, icon, dataTestId } = props;
return (
{
justifyContent={'center'}
alignItems={'center'}
data-testid={dataTestId}
+ onClick={event => {
+ event?.preventDefault();
+ onBannerClick();
+ }}
>
{text}
- {
- event?.preventDefault();
- onButtonClick();
- }}
- />
+
);
};
diff --git a/ts/components/SessionInboxView.tsx b/ts/components/SessionInboxView.tsx
index e17a25d17..bff9301b2 100644
--- a/ts/components/SessionInboxView.tsx
+++ b/ts/components/SessionInboxView.tsx
@@ -128,7 +128,7 @@ const SomeDeviceOutdatedSyncingNotice = () => {
return (
diff --git a/ts/components/conversation/SessionConversation.tsx b/ts/components/conversation/SessionConversation.tsx
index a5066e39a..8a28b137d 100644
--- a/ts/components/conversation/SessionConversation.tsx
+++ b/ts/components/conversation/SessionConversation.tsx
@@ -638,7 +638,7 @@ function OutdatedClientBanner(props: {
return selectedConversation.hasOutdatedClient?.length ? (
{
+ onBannerClick={() => {
const conversation = ConvoHub.use().get(selectedConversation.id);
conversation.set({ hasOutdatedClient: undefined });
void conversation.commit();
@@ -662,8 +662,8 @@ function OutdatedLegacyGroupBanner(props: {
return isLegacyGroup ? (
{
+ text={window.i18n('groupLegacyBanner', { date: 'FIXME AUDRIC' })} // Remove after QA
+ onBannerClick={() => {
showLinkVisitWarningDialog('', dispatch);
throw new Error('TODO'); // fixme audric
}}
diff --git a/ts/components/conversation/TimerNotification.tsx b/ts/components/conversation/TimerNotification.tsx
index 0f0bdf232..c768245db 100644
--- a/ts/components/conversation/TimerNotification.tsx
+++ b/ts/components/conversation/TimerNotification.tsx
@@ -1,8 +1,8 @@
import { useDispatch } from 'react-redux';
import styled from 'styled-components';
+import { PubkeyType } from 'libsession_util_nodejs';
import { PropsForExpirationTimer } from '../../state/ducks/conversations';
-import { isLegacyDisappearingModeEnabled } from '../../session/disappearing_messages/legacy';
import { UserUtils } from '../../session/utils';
import {
useSelectedConversationDisappearingMode,
@@ -10,7 +10,6 @@ import {
useSelectedExpireTimer,
useSelectedIsGroupOrCommunity,
useSelectedIsGroupV2,
- useSelectedIsLegacyGroup,
useSelectedIsPrivateFriend,
useSelectedIsPublic,
} from '../../state/selectors/selectedConversation';
@@ -26,6 +25,7 @@ import type { LocalizerComponentProps, LocalizerToken } from '../../types/locali
import { Localizer } from '../basic/Localizer';
import { SessionButtonColor } from '../basic/SessionButton';
import { SessionIcon } from '../icon';
+import { getTimerNotificationStr } from '../../models/timerNotifications';
const FollowSettingButton = styled.button`
color: var(--primary-color);
@@ -142,90 +142,25 @@ const FollowSettingsButton = (props: PropsForExpirationTimer) => {
);
};
-function useTextToRenderI18nProps(
- props: PropsForExpirationTimer
-): LocalizerComponentProps {
- const { pubkey: authorPk, profileName, expirationMode, timespanText: time, disabled } = props;
-
- const isLegacyGroup = useSelectedIsLegacyGroup();
-
- const authorIsUs = authorPk === UserUtils.getOurPubKeyStrFromCache();
-
- const name = profileName ?? authorPk;
-
- // TODO: legacy messages support will be removed in a future release
- if (isLegacyDisappearingModeEnabled(expirationMode)) {
- return {
- token: 'deleteAfterLegacyDisappearingMessagesTheyChangedTimer',
- args: {
- name: authorIsUs ? window.i18n('you') : name,
- time,
- },
- };
- }
-
- const disappearing_messages_type =
- expirationMode === 'deleteAfterRead'
- ? window.i18n('disappearingMessagesTypeRead')
- : window.i18n('disappearingMessagesTypeSent');
-
- if (isLegacyGroup) {
- if (disabled) {
- return authorIsUs
- ? {
- token: 'disappearingMessagesTurnedOffYouGroup',
- }
- : {
- token: 'disappearingMessagesTurnedOffGroup',
- args: {
- name,
- },
- };
- }
- }
-
- if (disabled) {
- return authorIsUs
- ? {
- token: isLegacyGroup
- ? 'disappearingMessagesTurnedOffYouGroup'
- : 'disappearingMessagesTurnedOffYou',
- }
- : {
- token: isLegacyGroup
- ? 'disappearingMessagesTurnedOffGroup'
- : 'disappearingMessagesTurnedOff',
- args: {
- name,
- },
- };
- }
-
- return authorIsUs
- ? {
- token: 'disappearingMessagesSetYou',
- args: {
- time,
- disappearing_messages_type,
- },
- }
- : {
- token: 'disappearingMessagesSet',
- args: {
- time,
- disappearing_messages_type,
- name,
- },
- };
-}
-
export const TimerNotification = (props: PropsForExpirationTimer) => {
- const { messageId } = props;
-
- const i18nProps = useTextToRenderI18nProps(props);
+ const { messageId, expirationMode, pubkey, timespanSeconds } = props;
+ const convoId = useSelectedConversationKey();
const isGroupOrCommunity = useSelectedIsGroupOrCommunity();
const isGroupV2 = useSelectedIsGroupV2();
const isPublic = useSelectedIsPublic();
+
+ if (!convoId) {
+ return null;
+ }
+
+ const i18nProps = getTimerNotificationStr({
+ convoId,
+ author: pubkey as PubkeyType,
+ expirationMode,
+ isGroup: isGroupOrCommunity,
+ timespanSeconds,
+ });
+
// renderOff is true when the update is put to off, or when we have a legacy group control message (as they are not expiring at all)
const renderOffIcon = props.disabled || (isGroupOrCommunity && isPublic && !isGroupV2);
diff --git a/ts/models/message.ts b/ts/models/message.ts
index 5791d1629..f196042c5 100644
--- a/ts/models/message.ts
+++ b/ts/models/message.ts
@@ -99,6 +99,8 @@ import {
} from './groupUpdate';
import { NetworkTime } from '../util/NetworkTime';
import { MessageQueue } from '../session/sending';
+import { getTimerNotificationStr } from './timerNotifications';
+import { ExpirationTimerUpdate } from '../session/disappearing_messages/types';
// tslint:disable: cyclomatic-complexity
@@ -408,8 +410,8 @@ export class MessageModel extends Backbone.Model {
}
}
if (this.isExpirationTimerUpdate()) {
- const expireTimerUpdate = this.getExpirationTimerUpdate();
- const expireTimer = expireTimerUpdate?.expireTimer;
+ const expireTimerUpdate = this.getExpirationTimerUpdate() as ExpirationTimerUpdate; // the isExpirationTimerUpdate above enforces this
+ const expireTimer = expireTimerUpdate.expireTimer;
const convo = this.getConversation();
if (!convo) {
return '';
@@ -422,39 +424,21 @@ export class MessageModel extends Backbone.Model {
);
const source = expireTimerUpdate?.source;
- const isUs = UserUtils.isUsFromCache(source);
-
- const authorName =
- ConvoHub.use()
- .get(source || '')
- ?.getNicknameOrRealUsernameOrPlaceholder() || window.i18n.stripped('unknown');
-
- if (!expireTimerUpdate || expirationMode === 'off' || !expireTimer || expireTimer === 0) {
- if (isUs) {
- return window.i18n.stripped('disappearingMessagesTurnedOffYou');
- }
- return window.i18n.stripped('disappearingMessagesTurnedOff', {
- name: authorName,
- });
- }
-
- const localizedMode =
- expirationMode === 'deleteAfterRead'
- ? window.i18n.stripped('disappearingMessagesTypeRead')
- : window.i18n.stripped('disappearingMessagesTypeSent');
+ const i18nProps = getTimerNotificationStr({
+ convoId: convo.id,
+ author: source as PubkeyType,
+ expirationMode,
+ isGroup: convo.isGroup(),
+ timespanSeconds: expireTimer,
+ });
- if (isUs) {
- return window.i18n.stripped('disappearingMessagesSetYou', {
- time: TimerOptions.getAbbreviated(expireTimerUpdate.expireTimer || 0),
- disappearing_messages_type: localizedMode,
- });
+ if ('args' in i18nProps) {
+ return window.i18n.stripped(
+ ...([i18nProps.token, i18nProps.args] as GetMessageArgs)
+ );
}
+ return window.i18n.stripped(...([i18nProps.token] as GetMessageArgs));
- return window.i18n.stripped('disappearingMessagesSet', {
- time: TimerOptions.getAbbreviated(expireTimerUpdate.expireTimer || 0),
- name: authorName,
- disappearing_messages_type: localizedMode,
- });
}
const body = this.get('body');
if (body) {
diff --git a/ts/models/timerNotifications.ts b/ts/models/timerNotifications.ts
new file mode 100644
index 000000000..ae529f7cd
--- /dev/null
+++ b/ts/models/timerNotifications.ts
@@ -0,0 +1,100 @@
+import { PubkeyType } from 'libsession_util_nodejs';
+import { ConvoHub } from '../session/conversations';
+import { PropsForExpirationTimer } from '../state/ducks/conversations';
+import { PubKey } from '../session/types';
+import { UserUtils } from '../session/utils';
+import { TimerOptions } from '../session/disappearing_messages/timerOptions';
+import { isLegacyDisappearingModeEnabled } from '../session/disappearing_messages/legacy';
+import { LocalizerComponentPropsObject } from '../types/localizer';
+
+export function getTimerNotificationStr({
+ expirationMode,
+ timespanSeconds,
+ convoId,
+ author,
+ isGroup,
+}: Pick & {
+ author: PubkeyType;
+ convoId: string;
+ isGroup: boolean;
+}): LocalizerComponentPropsObject {
+ const is03group = PubKey.is03Pubkey(convoId);
+ const authorIsUs = author === UserUtils.getOurPubKeyStrFromCache();
+ const isLegacyGroup = isGroup && !is03group;
+ const timespanText = TimerOptions.getName(timespanSeconds || 0);
+ const disabled = !timespanSeconds || timespanSeconds <= 0;
+
+ const authorName = ConvoHub.use().getContactProfileNameOrShortenedPubKey(author);
+
+ // TODO: legacy messages support will be removed in a future release
+ if (isLegacyDisappearingModeEnabled(expirationMode)) {
+ return {
+ token: 'deleteAfterLegacyDisappearingMessagesTheyChangedTimer',
+ args: {
+ name: authorIsUs ? window.i18n('you') : authorName,
+ time: timespanText,
+ },
+ } as const;
+ }
+
+ const disappearing_messages_type =
+ expirationMode === 'deleteAfterRead'
+ ? window.i18n('disappearingMessagesTypeRead')
+ : window.i18n('disappearingMessagesTypeSent');
+
+ if (isLegacyGroup || isGroup) {
+ if (disabled) {
+ return authorIsUs
+ ? {
+ token: 'disappearingMessagesTurnedOffYouGroup',
+ }
+ : {
+ token: 'disappearingMessagesTurnedOffGroup',
+ args: {
+ name: authorName,
+ },
+ };
+ }
+ return authorIsUs
+ ? {
+ token: 'disappearingMessagesSetYou',
+ args: { time: timespanText, disappearing_messages_type },
+ }
+ : {
+ token: 'disappearingMessagesSet',
+ args: { name: authorName, time: timespanText, disappearing_messages_type },
+ };
+ }
+
+ // legacy groups and groups are handled above.
+ // This can only be a private chat or Note to Self.
+ if (disabled) {
+ return authorIsUs
+ ? {
+ token: 'disappearingMessagesTurnedOffYou',
+ }
+ : {
+ token: 'disappearingMessagesTurnedOff',
+ args: {
+ name: authorName,
+ },
+ };
+ }
+
+ return authorIsUs
+ ? {
+ token: 'disappearingMessagesSetYou',
+ args: {
+ time: timespanText,
+ disappearing_messages_type,
+ },
+ }
+ : {
+ token: 'disappearingMessagesSet',
+ args: {
+ time: timespanText,
+ disappearing_messages_type,
+ name: authorName,
+ },
+ };
+}