fix: centralised localized string for disappearing messages strings

pull/3052/head
Audric Ackermann 12 months ago
parent c8c7308000
commit c9cd6a974f
No known key found for this signature in database

@ -146,7 +146,6 @@ message GroupUpdateMessage {
optional GroupUpdateInviteResponseMessage inviteResponse = 6; optional GroupUpdateInviteResponseMessage inviteResponse = 6;
optional GroupUpdateDeleteMemberContentMessage deleteMemberContent = 7; optional GroupUpdateDeleteMemberContentMessage deleteMemberContent = 7;
optional GroupUpdateMemberLeftNotificationMessage memberLeftNotificationMessage = 8; optional GroupUpdateMemberLeftNotificationMessage memberLeftNotificationMessage = 8;
} }

@ -12,9 +12,12 @@ const StyledNoticeBanner = styled(Flex)`
padding: var(--margins-xs) var(--margins-sm); padding: var(--margins-xs) var(--margins-sm);
text-align: center; text-align: center;
flex-shrink: 0; flex-shrink: 0;
cursor: pointer;
.session-icon-button { .session-icon-button {
position: absolute; position: absolute;
right: var(--margins-sm); right: var(--margins-sm);
pointer-events: none;
} }
`; `;
@ -25,12 +28,12 @@ const StyledText = styled.span`
type NoticeBannerProps = { type NoticeBannerProps = {
text: string; text: string;
icon: SessionIconType; icon: SessionIconType;
onButtonClick: () => void; onBannerClick: () => void;
dataTestId: SessionDataTestId; dataTestId: SessionDataTestId;
}; };
export const NoticeBanner = (props: NoticeBannerProps) => { export const NoticeBanner = (props: NoticeBannerProps) => {
const { text, onButtonClick, icon, dataTestId } = props; const { text, onBannerClick, icon, dataTestId } = props;
return ( return (
<StyledNoticeBanner <StyledNoticeBanner
@ -39,17 +42,13 @@ export const NoticeBanner = (props: NoticeBannerProps) => {
justifyContent={'center'} justifyContent={'center'}
alignItems={'center'} alignItems={'center'}
data-testid={dataTestId} data-testid={dataTestId}
onClick={event => {
event?.preventDefault();
onBannerClick();
}}
> >
<StyledText>{text}</StyledText> <StyledText>{text}</StyledText>
<SessionIconButton <SessionIconButton iconType={icon} iconColor="inherit" iconSize="small" />
iconType={icon}
iconColor="inherit"
iconSize="small"
onClick={event => {
event?.preventDefault();
onButtonClick();
}}
/>
</StyledNoticeBanner> </StyledNoticeBanner>
); );
}; };

@ -128,7 +128,7 @@ const SomeDeviceOutdatedSyncingNotice = () => {
return ( return (
<NoticeBanner <NoticeBanner
text={window.i18n('deleteAfterGroupFirstReleaseConfigOutdated')} text={window.i18n('deleteAfterGroupFirstReleaseConfigOutdated')}
onButtonClick={dismiss} onBannerClick={dismiss}
icon="exit" icon="exit"
dataTestId="some-of-your-devices-outdated-inbox" dataTestId="some-of-your-devices-outdated-inbox"
/> />

@ -638,7 +638,7 @@ function OutdatedClientBanner(props: {
return selectedConversation.hasOutdatedClient?.length ? ( return selectedConversation.hasOutdatedClient?.length ? (
<NoticeBanner <NoticeBanner
text={bannerText} text={bannerText}
onButtonClick={() => { onBannerClick={() => {
const conversation = ConvoHub.use().get(selectedConversation.id); const conversation = ConvoHub.use().get(selectedConversation.id);
conversation.set({ hasOutdatedClient: undefined }); conversation.set({ hasOutdatedClient: undefined });
void conversation.commit(); void conversation.commit();
@ -662,8 +662,8 @@ function OutdatedLegacyGroupBanner(props: {
return isLegacyGroup ? ( return isLegacyGroup ? (
<NoticeBanner <NoticeBanner
text={window.i18n('groupLegacyBanner', { date: 'FIXME AUDRIC' })} text={window.i18n('groupLegacyBanner', { date: 'FIXME AUDRIC' })} // Remove after QA
onButtonClick={() => { onBannerClick={() => {
showLinkVisitWarningDialog('', dispatch); showLinkVisitWarningDialog('', dispatch);
throw new Error('TODO'); // fixme audric throw new Error('TODO'); // fixme audric
}} }}

@ -1,8 +1,8 @@
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import styled from 'styled-components'; import styled from 'styled-components';
import { PubkeyType } from 'libsession_util_nodejs';
import { PropsForExpirationTimer } from '../../state/ducks/conversations'; import { PropsForExpirationTimer } from '../../state/ducks/conversations';
import { isLegacyDisappearingModeEnabled } from '../../session/disappearing_messages/legacy';
import { UserUtils } from '../../session/utils'; import { UserUtils } from '../../session/utils';
import { import {
useSelectedConversationDisappearingMode, useSelectedConversationDisappearingMode,
@ -10,7 +10,6 @@ import {
useSelectedExpireTimer, useSelectedExpireTimer,
useSelectedIsGroupOrCommunity, useSelectedIsGroupOrCommunity,
useSelectedIsGroupV2, useSelectedIsGroupV2,
useSelectedIsLegacyGroup,
useSelectedIsPrivateFriend, useSelectedIsPrivateFriend,
useSelectedIsPublic, useSelectedIsPublic,
} from '../../state/selectors/selectedConversation'; } from '../../state/selectors/selectedConversation';
@ -26,6 +25,7 @@ import type { LocalizerComponentProps, LocalizerToken } from '../../types/locali
import { Localizer } from '../basic/Localizer'; import { Localizer } from '../basic/Localizer';
import { SessionButtonColor } from '../basic/SessionButton'; import { SessionButtonColor } from '../basic/SessionButton';
import { SessionIcon } from '../icon'; import { SessionIcon } from '../icon';
import { getTimerNotificationStr } from '../../models/timerNotifications';
const FollowSettingButton = styled.button` const FollowSettingButton = styled.button`
color: var(--primary-color); color: var(--primary-color);
@ -142,90 +142,25 @@ const FollowSettingsButton = (props: PropsForExpirationTimer) => {
); );
}; };
function useTextToRenderI18nProps(
props: PropsForExpirationTimer
): LocalizerComponentProps<LocalizerToken> {
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) => { export const TimerNotification = (props: PropsForExpirationTimer) => {
const { messageId } = props; const { messageId, expirationMode, pubkey, timespanSeconds } = props;
const convoId = useSelectedConversationKey();
const i18nProps = useTextToRenderI18nProps(props);
const isGroupOrCommunity = useSelectedIsGroupOrCommunity(); const isGroupOrCommunity = useSelectedIsGroupOrCommunity();
const isGroupV2 = useSelectedIsGroupV2(); const isGroupV2 = useSelectedIsGroupV2();
const isPublic = useSelectedIsPublic(); 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) // 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); const renderOffIcon = props.disabled || (isGroupOrCommunity && isPublic && !isGroupV2);

@ -99,6 +99,8 @@ import {
} from './groupUpdate'; } from './groupUpdate';
import { NetworkTime } from '../util/NetworkTime'; import { NetworkTime } from '../util/NetworkTime';
import { MessageQueue } from '../session/sending'; import { MessageQueue } from '../session/sending';
import { getTimerNotificationStr } from './timerNotifications';
import { ExpirationTimerUpdate } from '../session/disappearing_messages/types';
// tslint:disable: cyclomatic-complexity // tslint:disable: cyclomatic-complexity
@ -408,8 +410,8 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
} }
} }
if (this.isExpirationTimerUpdate()) { if (this.isExpirationTimerUpdate()) {
const expireTimerUpdate = this.getExpirationTimerUpdate(); const expireTimerUpdate = this.getExpirationTimerUpdate() as ExpirationTimerUpdate; // the isExpirationTimerUpdate above enforces this
const expireTimer = expireTimerUpdate?.expireTimer; const expireTimer = expireTimerUpdate.expireTimer;
const convo = this.getConversation(); const convo = this.getConversation();
if (!convo) { if (!convo) {
return ''; return '';
@ -422,39 +424,21 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
); );
const source = expireTimerUpdate?.source; const source = expireTimerUpdate?.source;
const isUs = UserUtils.isUsFromCache(source); const i18nProps = getTimerNotificationStr({
convoId: convo.id,
const authorName = author: source as PubkeyType,
ConvoHub.use() expirationMode,
.get(source || '') isGroup: convo.isGroup(),
?.getNicknameOrRealUsernameOrPlaceholder() || window.i18n.stripped('unknown'); timespanSeconds: expireTimer,
});
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');
if (isUs) { if ('args' in i18nProps) {
return window.i18n.stripped('disappearingMessagesSetYou', { return window.i18n.stripped(
time: TimerOptions.getAbbreviated(expireTimerUpdate.expireTimer || 0), ...([i18nProps.token, i18nProps.args] as GetMessageArgs<LocalizerToken>)
disappearing_messages_type: localizedMode, );
});
} }
return window.i18n.stripped(...([i18nProps.token] as GetMessageArgs<LocalizerToken>));
return window.i18n.stripped('disappearingMessagesSet', {
time: TimerOptions.getAbbreviated(expireTimerUpdate.expireTimer || 0),
name: authorName,
disappearing_messages_type: localizedMode,
});
} }
const body = this.get('body'); const body = this.get('body');
if (body) { if (body) {

@ -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<PropsForExpirationTimer, 'expirationMode' | 'timespanSeconds'> & {
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,
},
};
}
Loading…
Cancel
Save