Make valid-i18n-keys rule strict and fix most exceptions
This commit is contained in:
parent
18a6da310f
commit
11cfcb4e32
36 changed files with 796 additions and 687 deletions
|
@ -14,9 +14,11 @@ const messagesCacheKey = hashSum.digest('hex');
|
||||||
|
|
||||||
function isI18nCall(node) {
|
function isI18nCall(node) {
|
||||||
return (
|
return (
|
||||||
node.type === 'CallExpression' &&
|
(node.type === 'CallExpression' &&
|
||||||
node.callee.type === 'Identifier' &&
|
node.callee.type === 'Identifier' &&
|
||||||
node.callee.name === 'i18n'
|
node.callee.name === 'i18n') ||
|
||||||
|
(node.callee.type === 'MemberExpression' &&
|
||||||
|
node.callee.property.name === 'i18n')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,20 +38,7 @@ function valueToMessageKey(node) {
|
||||||
if (isStringLiteral(node)) {
|
if (isStringLiteral(node)) {
|
||||||
return node.value;
|
return node.value;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
if (node.type !== 'TemplateLiteral') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node.quasis.length === 1) {
|
|
||||||
return node.quasis[0].value.cooked;
|
|
||||||
}
|
|
||||||
|
|
||||||
const parts = node.quasis.map(element => {
|
|
||||||
return element.value.cooked;
|
|
||||||
});
|
|
||||||
|
|
||||||
return new RegExp(`^${parts.join('(.*)')}$`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getI18nCallMessageKey(node) {
|
function getI18nCallMessageKey(node) {
|
||||||
|
@ -80,24 +69,11 @@ function getIntlElementMessageKey(node) {
|
||||||
|
|
||||||
let value = idAttribute.value;
|
let value = idAttribute.value;
|
||||||
|
|
||||||
if (value.type === 'JSXExpressionContainer') {
|
|
||||||
value = value.expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
return valueToMessageKey(value);
|
return valueToMessageKey(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidMessageKey(key) {
|
function isValidMessageKey(key) {
|
||||||
if (typeof key === 'string') {
|
return Object.hasOwn(messages, key);
|
||||||
if (Object.hasOwn(messages, key)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (key instanceof RegExp) {
|
|
||||||
if (messageKeys.some(k => key.test(k))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -27,27 +27,68 @@ ruleTester.run('valid-i18n-keys', rule, {
|
||||||
options: [{ messagesCacheKey }],
|
options: [{ messagesCacheKey }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
code: 'i18n(`AddCaptionModal__${title}`)',
|
code: `window.i18n("AddCaptionModal__title")`,
|
||||||
options: [{ messagesCacheKey }],
|
options: [{ messagesCacheKey }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
code: `let jsx = <Intl id="AddCaptionModal__title"/>`,
|
code: `let jsx = <Intl id="AddCaptionModal__title"/>`,
|
||||||
options: [{ messagesCacheKey }],
|
options: [{ messagesCacheKey }],
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
{
|
||||||
|
code: 'i18n(`AddCaptionModal__${title}`)',
|
||||||
|
options: [{ messagesCacheKey }],
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message: "i18n()'s first argument should always be a literal string",
|
||||||
|
type: 'CallExpression',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'window.i18n(`AddCaptionModal__${title}`)',
|
||||||
|
options: [{ messagesCacheKey }],
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message: "i18n()'s first argument should always be a literal string",
|
||||||
|
type: 'CallExpression',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
code: `let jsx = <Intl id={"AddCaptionModal__title"}/>`,
|
code: `let jsx = <Intl id={"AddCaptionModal__title"}/>`,
|
||||||
options: [{ messagesCacheKey }],
|
options: [{ messagesCacheKey }],
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message:
|
||||||
|
"<Intl> must always be provided an 'id' attribute with a literal string",
|
||||||
|
type: 'JSXOpeningElement',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
code: 'let jsx = <Intl id={`AddCaptionModal__title`}/>',
|
code: 'let jsx = <Intl id={`AddCaptionModal__title`}/>',
|
||||||
options: [{ messagesCacheKey }],
|
options: [{ messagesCacheKey }],
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message:
|
||||||
|
"<Intl> must always be provided an 'id' attribute with a literal string",
|
||||||
|
type: 'JSXOpeningElement',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
code: 'let jsx = <Intl id={`AddCaptionModal__${title}`}/>',
|
code: 'let jsx = <Intl id={`AddCaptionModal__${title}`}/>',
|
||||||
options: [{ messagesCacheKey }],
|
options: [{ messagesCacheKey }],
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message:
|
||||||
|
"<Intl> must always be provided an 'id' attribute with a literal string",
|
||||||
|
type: 'JSXOpeningElement',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
],
|
|
||||||
invalid: [
|
|
||||||
{
|
{
|
||||||
code: `i18n("THIS_KEY_SHOULD_NEVER_EXIST")`,
|
code: `i18n("THIS_KEY_SHOULD_NEVER_EXIST")`,
|
||||||
options: [{ messagesCacheKey }],
|
options: [{ messagesCacheKey }],
|
||||||
|
|
|
@ -604,19 +604,23 @@ export function Headers(): JSX.Element {
|
||||||
rows={[
|
rows={[
|
||||||
{
|
{
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'conversationsHeader',
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
getHeaderText: i18n => i18n('conversationsHeader'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'messagesHeader',
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
getHeaderText: i18n => i18n('messagesHeader'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'findByUsernameHeader',
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
getHeaderText: i18n => i18n('findByUsernameHeader'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'findByPhoneNumberHeader',
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
getHeaderText: i18n => i18n('findByPhoneNumberHeader'),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
@ -629,7 +633,8 @@ export function FindByPhoneNumber(): JSX.Element {
|
||||||
rows={[
|
rows={[
|
||||||
{
|
{
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'findByPhoneNumberHeader',
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
getHeaderText: i18n => i18n('findByPhoneNumberHeader'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: RowType.StartNewConversation,
|
type: RowType.StartNewConversation,
|
||||||
|
@ -673,7 +678,8 @@ export function FindByUsername(): JSX.Element {
|
||||||
rows={[
|
rows={[
|
||||||
{
|
{
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'findByUsernameHeader',
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
getHeaderText: i18n => i18n('findByUsernameHeader'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: RowType.UsernameSearchResult,
|
type: RowType.UsernameSearchResult,
|
||||||
|
@ -745,7 +751,8 @@ export function KitchenSink(): JSX.Element {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'contactsHeader',
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
getHeaderText: i18n => i18n('contactsHeader'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: RowType.Contact,
|
type: RowType.Contact,
|
||||||
|
@ -753,7 +760,8 @@ export function KitchenSink(): JSX.Element {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'messagesHeader',
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
getHeaderText: i18n => i18n('messagesHeader'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
|
@ -765,7 +773,8 @@ export function KitchenSink(): JSX.Element {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'findByUsernameHeader',
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
getHeaderText: i18n => i18n('findByUsernameHeader'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: RowType.UsernameSearchResult,
|
type: RowType.UsernameSearchResult,
|
||||||
|
|
|
@ -103,9 +103,17 @@ type MessageRowType = {
|
||||||
|
|
||||||
type HeaderRowType = {
|
type HeaderRowType = {
|
||||||
type: RowType.Header;
|
type: RowType.Header;
|
||||||
i18nKey: string;
|
getHeaderText: (i18n: LocalizerType) => string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Exported for tests across multiple files
|
||||||
|
export function _testHeaderText(row: Row | void): string | null {
|
||||||
|
if (row?.type === RowType.Header) {
|
||||||
|
return row.getHeaderText(((key: string) => key) as LocalizerType);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
type SearchResultsLoadingFakeHeaderType = {
|
type SearchResultsLoadingFakeHeaderType = {
|
||||||
type: RowType.SearchResultsLoadingFakeHeader;
|
type: RowType.SearchResultsLoadingFakeHeader;
|
||||||
};
|
};
|
||||||
|
@ -375,18 +383,18 @@ export function ConversationList({
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case RowType.Header:
|
case RowType.Header: {
|
||||||
|
const headerText = row.getHeaderText(i18n);
|
||||||
result = (
|
result = (
|
||||||
<div
|
<div
|
||||||
className="module-conversation-list__item--header"
|
className="module-conversation-list__item--header"
|
||||||
// eslint-disable-next-line local-rules/valid-i18n-keys
|
aria-label={headerText}
|
||||||
aria-label={i18n(row.i18nKey)}
|
|
||||||
>
|
>
|
||||||
{/* eslint-disable-next-line local-rules/valid-i18n-keys */}
|
{headerText}
|
||||||
{i18n(row.i18nKey)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case RowType.MessageSearchResult:
|
case RowType.MessageSearchResult:
|
||||||
result = <>{renderMessageSearchResult?.(row.messageId)}</>;
|
result = <>{renderMessageSearchResult?.(row.messageId)}</>;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -7,6 +7,7 @@ import type { ConversationType } from '../state/ducks/conversations';
|
||||||
import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
|
import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
|
||||||
import { GroupDialog } from './GroupDialog';
|
import { GroupDialog } from './GroupDialog';
|
||||||
import { sortByTitle } from '../util/sortByTitle';
|
import { sortByTitle } from '../util/sortByTitle';
|
||||||
|
import { missingCaseError } from '../util';
|
||||||
|
|
||||||
export type DataPropsType = {
|
export type DataPropsType = {
|
||||||
conversationId: string;
|
conversationId: string;
|
||||||
|
@ -70,8 +71,6 @@ export const GroupV1MigrationDialog: React.FunctionComponent<PropsType> =
|
||||||
const keepHistory = hasMigrated
|
const keepHistory = hasMigrated
|
||||||
? i18n('GroupV1--Migration--info--keep-history')
|
? i18n('GroupV1--Migration--info--keep-history')
|
||||||
: i18n('GroupV1--Migration--migrate--keep-history');
|
: i18n('GroupV1--Migration--migrate--keep-history');
|
||||||
const migrationKey = hasMigrated ? 'after' : 'before';
|
|
||||||
const droppedMembersKey = `GroupV1--Migration--info--removed--${migrationKey}`;
|
|
||||||
|
|
||||||
let primaryButtonText: string;
|
let primaryButtonText: string;
|
||||||
let onClickPrimaryButton: () => void;
|
let onClickPrimaryButton: () => void;
|
||||||
|
@ -116,14 +115,16 @@ export const GroupV1MigrationDialog: React.FunctionComponent<PropsType> =
|
||||||
getPreferredBadge,
|
getPreferredBadge,
|
||||||
i18n,
|
i18n,
|
||||||
members: invitedMembers,
|
members: invitedMembers,
|
||||||
prefix: 'GroupV1--Migration--info--invited',
|
hasMigrated,
|
||||||
|
kind: 'invited',
|
||||||
theme,
|
theme,
|
||||||
})}
|
})}
|
||||||
{renderMembers({
|
{renderMembers({
|
||||||
getPreferredBadge,
|
getPreferredBadge,
|
||||||
i18n,
|
i18n,
|
||||||
members: droppedMembers,
|
members: droppedMembers,
|
||||||
prefix: droppedMembersKey,
|
hasMigrated,
|
||||||
|
kind: 'dropped',
|
||||||
theme,
|
theme,
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
|
@ -136,26 +137,49 @@ function renderMembers({
|
||||||
getPreferredBadge,
|
getPreferredBadge,
|
||||||
i18n,
|
i18n,
|
||||||
members,
|
members,
|
||||||
prefix,
|
hasMigrated,
|
||||||
|
kind,
|
||||||
theme,
|
theme,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
getPreferredBadge: PreferredBadgeSelectorType;
|
getPreferredBadge: PreferredBadgeSelectorType;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
members: Array<ConversationType>;
|
members: Array<ConversationType>;
|
||||||
prefix: string;
|
hasMigrated: boolean;
|
||||||
|
kind: 'invited' | 'dropped';
|
||||||
theme: ThemeType;
|
theme: ThemeType;
|
||||||
}>): React.ReactNode {
|
}>): React.ReactNode {
|
||||||
if (!members.length) {
|
if (!members.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const postfix = members.length === 1 ? '--one' : '--many';
|
let text: string;
|
||||||
const key = `${prefix}${postfix}`;
|
switch (kind) {
|
||||||
|
case 'invited':
|
||||||
|
text =
|
||||||
|
members.length === 1
|
||||||
|
? i18n('GroupV1--Migration--info--invited--one')
|
||||||
|
: i18n('GroupV1--Migration--info--invited--many');
|
||||||
|
break;
|
||||||
|
case 'dropped':
|
||||||
|
if (hasMigrated) {
|
||||||
|
text =
|
||||||
|
members.length === 1
|
||||||
|
? i18n('GroupV1--Migration--info--removed--before--one')
|
||||||
|
: i18n('GroupV1--Migration--info--removed--before--many');
|
||||||
|
} else {
|
||||||
|
text =
|
||||||
|
members.length === 1
|
||||||
|
? i18n('GroupV1--Migration--info--removed--after--one')
|
||||||
|
: i18n('GroupV1--Migration--info--removed--after--many');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw missingCaseError(kind);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* eslint-disable-next-line local-rules/valid-i18n-keys */}
|
<GroupDialog.Paragraph>{text}</GroupDialog.Paragraph>
|
||||||
<GroupDialog.Paragraph>{i18n(key)}</GroupDialog.Paragraph>
|
|
||||||
<GroupDialog.Contacts
|
<GroupDialog.Contacts
|
||||||
contacts={sortByTitle(members)}
|
contacts={sortByTitle(members)}
|
||||||
getPreferredBadge={getPreferredBadge}
|
getPreferredBadge={getPreferredBadge}
|
||||||
|
|
|
@ -71,24 +71,29 @@ export class Intl extends React.Component<Props> {
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
public override render() {
|
public override render() {
|
||||||
const { components, id, i18n, renderText = defaultRenderText } = this.props;
|
const {
|
||||||
|
components,
|
||||||
|
id,
|
||||||
|
// Indirection for linter/migration tooling
|
||||||
|
i18n: localizer,
|
||||||
|
renderText = defaultRenderText,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
log.error('Error: Intl id prop not provided');
|
log.error('Error: Intl id prop not provided');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!i18n.isLegacyFormat(id)) {
|
if (!localizer.isLegacyFormat(id)) {
|
||||||
strictAssert(
|
strictAssert(
|
||||||
!Array.isArray(components),
|
!Array.isArray(components),
|
||||||
`components cannot be an array for ICU message ${id}`
|
`components cannot be an array for ICU message ${id}`
|
||||||
);
|
);
|
||||||
const intl = i18n.getIntl();
|
const intl = localizer.getIntl();
|
||||||
return intl.formatMessage({ id }, components);
|
return intl.formatMessage({ id }, components);
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line local-rules/valid-i18n-keys
|
const text = localizer(id);
|
||||||
const text = i18n(id);
|
|
||||||
const results: Array<
|
const results: Array<
|
||||||
string | JSX.Element | Array<string | JSX.Element> | null
|
string | JSX.Element | Array<string | JSX.Element> | null
|
||||||
> = [];
|
> = [];
|
||||||
|
|
|
@ -339,7 +339,7 @@ export function SendStoryModal({
|
||||||
<EditMyStoryPrivacy
|
<EditMyStoryPrivacy
|
||||||
hasDisclaimerAbove
|
hasDisclaimerAbove
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
learnMore="SendStoryModal__privacy-disclaimer"
|
kind="privacy"
|
||||||
myStories={stagedMyStories}
|
myStories={stagedMyStories}
|
||||||
signalConnectionsCount={signalConnections.length}
|
signalConnectionsCount={signalConnections.length}
|
||||||
onClickExclude={() => {
|
onClickExclude={() => {
|
||||||
|
|
|
@ -627,7 +627,7 @@ export function DistributionListSettingsModal({
|
||||||
{isMyStory && (
|
{isMyStory && (
|
||||||
<EditMyStoryPrivacy
|
<EditMyStoryPrivacy
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
learnMore="StoriesSettings__mine__disclaimer"
|
kind="mine"
|
||||||
myStories={listToEdit}
|
myStories={listToEdit}
|
||||||
onClickExclude={() => {
|
onClickExclude={() => {
|
||||||
setPage(Page.HideStoryFrom);
|
setPage(Page.HideStoryFrom);
|
||||||
|
@ -791,7 +791,7 @@ function CheckboxRender({
|
||||||
type EditMyStoryPrivacyPropsType = {
|
type EditMyStoryPrivacyPropsType = {
|
||||||
hasDisclaimerAbove?: boolean;
|
hasDisclaimerAbove?: boolean;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
learnMore: string;
|
kind: 'privacy' | 'mine';
|
||||||
myStories: StoryDistributionListWithMembersDataType;
|
myStories: StoryDistributionListWithMembersDataType;
|
||||||
onClickExclude: () => unknown;
|
onClickExclude: () => unknown;
|
||||||
onClickOnlyShareWith: () => unknown;
|
onClickOnlyShareWith: () => unknown;
|
||||||
|
@ -805,7 +805,7 @@ type EditMyStoryPrivacyPropsType = {
|
||||||
export function EditMyStoryPrivacy({
|
export function EditMyStoryPrivacy({
|
||||||
hasDisclaimerAbove,
|
hasDisclaimerAbove,
|
||||||
i18n,
|
i18n,
|
||||||
learnMore,
|
kind,
|
||||||
myStories,
|
myStories,
|
||||||
onClickExclude,
|
onClickExclude,
|
||||||
onClickOnlyShareWith,
|
onClickOnlyShareWith,
|
||||||
|
@ -814,24 +814,30 @@ export function EditMyStoryPrivacy({
|
||||||
toggleSignalConnectionsModal,
|
toggleSignalConnectionsModal,
|
||||||
signalConnectionsCount,
|
signalConnectionsCount,
|
||||||
}: EditMyStoryPrivacyPropsType): JSX.Element {
|
}: EditMyStoryPrivacyPropsType): JSX.Element {
|
||||||
|
const learnMore = (
|
||||||
|
<button
|
||||||
|
className="StoriesSettingsModal__disclaimer__learn-more"
|
||||||
|
onClick={toggleSignalConnectionsModal}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
{i18n('StoriesSettings__mine__disclaimer--learn-more')}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
const disclaimerElement = (
|
const disclaimerElement = (
|
||||||
<div className="StoriesSettingsModal__disclaimer">
|
<div className="StoriesSettingsModal__disclaimer">
|
||||||
{/* eslint-disable-next-line local-rules/valid-i18n-keys */}
|
{kind === 'mine' ? (
|
||||||
<Intl
|
<Intl
|
||||||
components={{
|
components={{ learnMore }}
|
||||||
learnMore: (
|
i18n={i18n}
|
||||||
<button
|
id="StoriesSettings__mine__disclaimer"
|
||||||
className="StoriesSettingsModal__disclaimer__learn-more"
|
/>
|
||||||
onClick={toggleSignalConnectionsModal}
|
) : (
|
||||||
type="button"
|
<Intl
|
||||||
>
|
components={{ learnMore }}
|
||||||
{i18n('StoriesSettings__mine__disclaimer--learn-more')}
|
i18n={i18n}
|
||||||
</button>
|
id="SendStoryModal__privacy-disclaimer"
|
||||||
),
|
/>
|
||||||
}}
|
)}
|
||||||
i18n={i18n}
|
|
||||||
id={learnMore}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,9 @@ export function ToastManager({
|
||||||
if (toastType === ToastType.AddingUserToGroup) {
|
if (toastType === ToastType.AddingUserToGroup) {
|
||||||
return (
|
return (
|
||||||
<Toast onClose={hideToast} timeout={SHORT_TIMEOUT}>
|
<Toast onClose={hideToast} timeout={SHORT_TIMEOUT}>
|
||||||
{i18n(
|
{i18n('AddUserToAnotherGroupModal__toast--adding-user-to-group', {
|
||||||
'AddUserToAnotherGroupModal__toast--adding-user-to-group',
|
...toast.parameters,
|
||||||
toast.parameters
|
})}
|
||||||
)}
|
|
||||||
</Toast>
|
</Toast>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -107,7 +106,9 @@ export function ToastManager({
|
||||||
if (toastType === ToastType.CannotStartGroupCall) {
|
if (toastType === ToastType.CannotStartGroupCall) {
|
||||||
return (
|
return (
|
||||||
<Toast onClose={hideToast}>
|
<Toast onClose={hideToast}>
|
||||||
{i18n('GroupV2--cannot-start-group-call', toast.parameters)}
|
{i18n('GroupV2--cannot-start-group-call', {
|
||||||
|
...toast.parameters,
|
||||||
|
})}
|
||||||
</Toast>
|
</Toast>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -344,10 +345,9 @@ export function ToastManager({
|
||||||
if (toastType === ToastType.UserAddedToGroup) {
|
if (toastType === ToastType.UserAddedToGroup) {
|
||||||
return (
|
return (
|
||||||
<Toast onClose={hideToast}>
|
<Toast onClose={hideToast}>
|
||||||
{i18n(
|
{i18n('AddUserToAnotherGroupModal__toast--user-added-to-group', {
|
||||||
'AddUserToAnotherGroupModal__toast--user-added-to-group',
|
...toast.parameters,
|
||||||
toast.parameters
|
})}
|
||||||
)}
|
|
||||||
</Toast>
|
</Toast>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import React from 'react';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
import { Modal } from './Modal';
|
import { Modal } from './Modal';
|
||||||
import type { IntlComponentsType } from './Intl';
|
|
||||||
import { Intl } from './Intl';
|
import { Intl } from './Intl';
|
||||||
import { Emojify } from './conversation/Emojify';
|
import { Emojify } from './conversation/Emojify';
|
||||||
import type { LocalizerType, RenderTextCallbackType } from '../types/Util';
|
import type { LocalizerType, RenderTextCallbackType } from '../types/Util';
|
||||||
|
@ -19,61 +18,46 @@ export type PropsType = {
|
||||||
type ReleaseNotesType = {
|
type ReleaseNotesType = {
|
||||||
date: Date;
|
date: Date;
|
||||||
version: string;
|
version: string;
|
||||||
features: Array<{ key: string; components: IntlComponentsType }>;
|
features: Array<JSX.Element>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderText: RenderTextCallbackType = ({ key, text }) => (
|
const renderText: RenderTextCallbackType = ({ key, text }) => (
|
||||||
<Emojify key={key} text={text} />
|
<Emojify key={key} text={text} />
|
||||||
);
|
);
|
||||||
|
|
||||||
const releaseNotes: ReleaseNotesType = {
|
|
||||||
date: new Date(window.getBuildCreation?.() || Date.now()),
|
|
||||||
version: window.getVersion?.(),
|
|
||||||
features: [
|
|
||||||
{
|
|
||||||
key: 'icu:WhatsNew__v6.12--0',
|
|
||||||
components: {},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'icu:WhatsNew__v6.12--1',
|
|
||||||
components: {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
export function WhatsNewModal({
|
export function WhatsNewModal({
|
||||||
i18n,
|
i18n,
|
||||||
hideWhatsNewModal,
|
hideWhatsNewModal,
|
||||||
}: PropsType): JSX.Element {
|
}: PropsType): JSX.Element {
|
||||||
let contentNode: ReactChild;
|
let contentNode: ReactChild;
|
||||||
|
|
||||||
|
const releaseNotes: ReleaseNotesType = {
|
||||||
|
date: new Date(window.getBuildCreation?.() || Date.now()),
|
||||||
|
version: window.getVersion?.(),
|
||||||
|
features: [
|
||||||
|
<Intl
|
||||||
|
i18n={i18n}
|
||||||
|
id="icu:WhatsNew__v6.12--0"
|
||||||
|
renderText={renderText}
|
||||||
|
components={{}}
|
||||||
|
/>,
|
||||||
|
<Intl
|
||||||
|
i18n={i18n}
|
||||||
|
id="icu:WhatsNew__v6.12--1"
|
||||||
|
renderText={renderText}
|
||||||
|
components={{}}
|
||||||
|
/>,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
if (releaseNotes.features.length === 1) {
|
if (releaseNotes.features.length === 1) {
|
||||||
const { key, components } = releaseNotes.features[0];
|
contentNode = <p>{releaseNotes.features[0]}</p>;
|
||||||
contentNode = (
|
|
||||||
<p>
|
|
||||||
{/* eslint-disable-next-line local-rules/valid-i18n-keys */}
|
|
||||||
<Intl
|
|
||||||
i18n={i18n}
|
|
||||||
id={key}
|
|
||||||
renderText={renderText}
|
|
||||||
components={components}
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
contentNode = (
|
contentNode = (
|
||||||
<ul>
|
<ul>
|
||||||
{releaseNotes.features.map(({ key, components }) => (
|
{releaseNotes.features.map(element => {
|
||||||
<li key={key}>
|
return <li key={element.props.id}>{element}</li>;
|
||||||
{/* eslint-disable-next-line local-rules/valid-i18n-keys */}
|
})}
|
||||||
<Intl
|
|
||||||
i18n={i18n}
|
|
||||||
id={key}
|
|
||||||
renderText={renderText}
|
|
||||||
components={components}
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,16 +60,8 @@ export function GroupV1Migration(props: PropsType): React.ReactElement {
|
||||||
i18n('GroupV1--Migration--invited--you')
|
i18n('GroupV1--Migration--invited--you')
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{renderUsers(
|
{renderUsers(invitedMembers, i18n, 'invited')}
|
||||||
invitedMembers,
|
{renderUsers(droppedMembers, i18n, 'removed')}
|
||||||
i18n,
|
|
||||||
'GroupV1--Migration--invited'
|
|
||||||
)}
|
|
||||||
{renderUsers(
|
|
||||||
droppedMembers,
|
|
||||||
i18n,
|
|
||||||
'GroupV1--Migration--removed'
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
|
@ -106,31 +98,52 @@ export function GroupV1Migration(props: PropsType): React.ReactElement {
|
||||||
function renderUsers(
|
function renderUsers(
|
||||||
members: Array<ConversationType>,
|
members: Array<ConversationType>,
|
||||||
i18n: LocalizerType,
|
i18n: LocalizerType,
|
||||||
keyPrefix: string
|
kind: 'invited' | 'removed'
|
||||||
): React.ReactElement | null {
|
): React.ReactElement | null {
|
||||||
if (!members || members.length === 0) {
|
if (!members || members.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (members.length === 1) {
|
if (members.length === 1) {
|
||||||
|
const contact = <ContactName title={members[0].title} />;
|
||||||
return (
|
return (
|
||||||
<p>
|
<p>
|
||||||
<Intl
|
{kind === 'invited' && (
|
||||||
i18n={i18n}
|
<Intl
|
||||||
id={`${keyPrefix}--one`}
|
i18n={i18n}
|
||||||
components={{
|
id="GroupV1--Migration--invited--one"
|
||||||
contact: <ContactName title={members[0].title} />,
|
components={{ contact }}
|
||||||
}}
|
/>
|
||||||
/>
|
)}
|
||||||
|
{kind === 'removed' && (
|
||||||
|
<Intl
|
||||||
|
i18n={i18n}
|
||||||
|
id="GroupV1--Migration--removed--one"
|
||||||
|
components={{ contact }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const count = members.length.toString();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<p>
|
<p>
|
||||||
{i18n(`${keyPrefix}--many`, {
|
{kind === 'invited' && members.length > 1 && (
|
||||||
count: members.length.toString(),
|
<Intl
|
||||||
})}
|
i18n={i18n}
|
||||||
|
id="GroupV1--Migration--invited--many"
|
||||||
|
components={{ count }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{kind === 'removed' && members.length > 1 && (
|
||||||
|
<Intl
|
||||||
|
i18n={i18n}
|
||||||
|
id="GroupV1--Migration--removed--many"
|
||||||
|
components={{ count }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,26 @@ export function MandatoryProfileSharingActions({
|
||||||
}: Props): JSX.Element {
|
}: Props): JSX.Element {
|
||||||
const [mrState, setMrState] = React.useState(MessageRequestState.default);
|
const [mrState, setMrState] = React.useState(MessageRequestState.default);
|
||||||
|
|
||||||
|
const firstNameContact = (
|
||||||
|
<strong
|
||||||
|
key="name"
|
||||||
|
className="module-message-request-actions__message__name"
|
||||||
|
>
|
||||||
|
<ContactName firstName={firstName} title={title} preferFirstName />
|
||||||
|
</strong>
|
||||||
|
);
|
||||||
|
|
||||||
|
const learnMore = (
|
||||||
|
<a
|
||||||
|
href="https://support.signal.org/hc/articles/360007459591"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className="module-message-request-actions__message__learn-more"
|
||||||
|
>
|
||||||
|
{i18n('MessageRequests--learn-more')}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{mrState !== MessageRequestState.default ? (
|
{mrState !== MessageRequestState.default ? (
|
||||||
|
@ -62,34 +82,19 @@ export function MandatoryProfileSharingActions({
|
||||||
) : null}
|
) : null}
|
||||||
<div className="module-message-request-actions">
|
<div className="module-message-request-actions">
|
||||||
<p className="module-message-request-actions__message">
|
<p className="module-message-request-actions__message">
|
||||||
<Intl
|
{conversationType === 'direct' ? (
|
||||||
i18n={i18n}
|
<Intl
|
||||||
id={`MessageRequests--profile-sharing--${conversationType}`}
|
i18n={i18n}
|
||||||
components={{
|
id="MessageRequests--profile-sharing--direct"
|
||||||
firstName: (
|
components={{ firstName: firstNameContact, learnMore }}
|
||||||
<strong
|
/>
|
||||||
key="name"
|
) : (
|
||||||
className="module-message-request-actions__message__name"
|
<Intl
|
||||||
>
|
i18n={i18n}
|
||||||
<ContactName
|
id="MessageRequests--profile-sharing--group"
|
||||||
firstName={firstName}
|
components={{ firstName: firstNameContact, learnMore }}
|
||||||
title={title}
|
/>
|
||||||
preferFirstName
|
)}
|
||||||
/>
|
|
||||||
</strong>
|
|
||||||
),
|
|
||||||
learnMore: (
|
|
||||||
<a
|
|
||||||
href="https://support.signal.org/hc/articles/360007459591"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
className="module-message-request-actions__message__learn-more"
|
|
||||||
>
|
|
||||||
{i18n('MessageRequests--learn-more')}
|
|
||||||
</a>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</p>
|
</p>
|
||||||
<div className="module-message-request-actions__buttons">
|
<div className="module-message-request-actions__buttons">
|
||||||
<Button
|
<Button
|
||||||
|
|
|
@ -1251,7 +1251,10 @@ export class Message extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (giftBadge.state === GiftBadgeStates.Unopened) {
|
if (giftBadge.state === GiftBadgeStates.Unopened) {
|
||||||
const description = i18n(`icu:message--donation--unopened--${direction}`);
|
const description =
|
||||||
|
direction === 'incoming'
|
||||||
|
? i18n('icu:message--donation--unopened--incoming')
|
||||||
|
: i18n('icu:message--donation--unopened--outgoing');
|
||||||
const isRTL = getDirection(description) === 'rtl';
|
const isRTL = getDirection(description) === 'rtl';
|
||||||
const { metadataWidth } = this.state;
|
const { metadataWidth } = this.state;
|
||||||
|
|
||||||
|
@ -1931,26 +1934,23 @@ export class Message extends React.PureComponent<Props, State> {
|
||||||
isTapToViewError,
|
isTapToViewError,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const incomingString = isTapToViewExpired
|
|
||||||
? i18n('Message--tap-to-view-expired')
|
|
||||||
: i18n(
|
|
||||||
`Message--tap-to-view--incoming${
|
|
||||||
isVideo(attachments) ? '-video' : ''
|
|
||||||
}`
|
|
||||||
);
|
|
||||||
const outgoingString = i18n('Message--tap-to-view--outgoing');
|
|
||||||
const isDownloadPending = this.isAttachmentPending();
|
const isDownloadPending = this.isAttachmentPending();
|
||||||
|
|
||||||
if (isDownloadPending) {
|
if (isDownloadPending) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (isTapToViewError) {
|
||||||
// eslint-disable-next-line no-nested-ternary
|
return i18n('incomingError');
|
||||||
return isTapToViewError
|
}
|
||||||
? i18n('incomingError')
|
if (direction === 'outgoing') {
|
||||||
: direction === 'outgoing'
|
return i18n('Message--tap-to-view--outgoing');
|
||||||
? outgoingString
|
}
|
||||||
: incomingString;
|
if (isTapToViewExpired) {
|
||||||
|
return i18n('Message--tap-to-view-expired');
|
||||||
|
}
|
||||||
|
if (isVideo(attachments)) {
|
||||||
|
return i18n('Message--tap-to-view--incoming-video');
|
||||||
|
}
|
||||||
|
return i18n('Message--tap-to-view--incoming');
|
||||||
}
|
}
|
||||||
|
|
||||||
public renderTapToView(): JSX.Element {
|
public renderTapToView(): JSX.Element {
|
||||||
|
|
|
@ -26,6 +26,7 @@ import * as log from '../../logging/log';
|
||||||
import { formatDateTimeLong } from '../../util/timestamp';
|
import { formatDateTimeLong } from '../../util/timestamp';
|
||||||
import { DurationInSeconds } from '../../util/durations';
|
import { DurationInSeconds } from '../../util/durations';
|
||||||
import { format as formatRelativeTime } from '../../util/expirationTimer';
|
import { format as formatRelativeTime } from '../../util/expirationTimer';
|
||||||
|
import { missingCaseError } from '../../util';
|
||||||
|
|
||||||
export type Contact = Pick<
|
export type Contact = Pick<
|
||||||
ConversationType,
|
ConversationType,
|
||||||
|
@ -200,24 +201,49 @@ export class MessageDetail extends React.Component<Props> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private renderContactGroupHeaderText(
|
||||||
|
sendStatus: undefined | SendStatus
|
||||||
|
): string {
|
||||||
|
const { i18n } = this.props;
|
||||||
|
|
||||||
|
if (sendStatus === undefined) {
|
||||||
|
return i18n('from');
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (sendStatus) {
|
||||||
|
case SendStatus.Failed:
|
||||||
|
return i18n('MessageDetailsHeader--Failed');
|
||||||
|
case SendStatus.Pending:
|
||||||
|
return i18n('MessageDetailsHeader--Pending');
|
||||||
|
case SendStatus.Sent:
|
||||||
|
return i18n('MessageDetailsHeader--Sent');
|
||||||
|
case SendStatus.Delivered:
|
||||||
|
return i18n('MessageDetailsHeader--Delivered');
|
||||||
|
case SendStatus.Read:
|
||||||
|
return i18n('MessageDetailsHeader--Read');
|
||||||
|
case SendStatus.Viewed:
|
||||||
|
return i18n('MessageDetailsHeader--Viewed');
|
||||||
|
default:
|
||||||
|
throw missingCaseError(sendStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private renderContactGroup(
|
private renderContactGroup(
|
||||||
sendStatus: undefined | SendStatus,
|
sendStatus: undefined | SendStatus,
|
||||||
contacts: undefined | ReadonlyArray<Contact>
|
contacts: undefined | ReadonlyArray<Contact>
|
||||||
): ReactNode {
|
): ReactNode {
|
||||||
const { i18n } = this.props;
|
|
||||||
if (!contacts || !contacts.length) {
|
if (!contacts || !contacts.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const i18nKey =
|
|
||||||
sendStatus === undefined ? 'from' : `MessageDetailsHeader--${sendStatus}`;
|
|
||||||
|
|
||||||
const sortedContacts = [...contacts].sort((a, b) =>
|
const sortedContacts = [...contacts].sort((a, b) =>
|
||||||
contactSortCollator.compare(a.title, b.title)
|
contactSortCollator.compare(a.title, b.title)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const headerText = this.renderContactGroupHeaderText(sendStatus);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={i18nKey} className="module-message-detail__contact-group">
|
<div key={headerText} className="module-message-detail__contact-group">
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'module-message-detail__contact-group__header',
|
'module-message-detail__contact-group__header',
|
||||||
|
@ -225,8 +251,7 @@ export class MessageDetail extends React.Component<Props> {
|
||||||
`module-message-detail__contact-group__header--${sendStatus}`
|
`module-message-detail__contact-group__header--${sendStatus}`
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{/* eslint-disable-next-line local-rules/valid-i18n-keys */}
|
{headerText}
|
||||||
{i18n(i18nKey)}
|
|
||||||
</div>
|
</div>
|
||||||
{sortedContacts.map(contact => this.renderContact(contact))}
|
{sortedContacts.map(contact => this.renderContact(contact))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -35,6 +35,15 @@ export function MessageRequestActions({
|
||||||
}: Props): JSX.Element {
|
}: Props): JSX.Element {
|
||||||
const [mrState, setMrState] = React.useState(MessageRequestState.default);
|
const [mrState, setMrState] = React.useState(MessageRequestState.default);
|
||||||
|
|
||||||
|
const name = (
|
||||||
|
<strong
|
||||||
|
key="name"
|
||||||
|
className="module-message-request-actions__message__name"
|
||||||
|
>
|
||||||
|
<ContactName firstName={firstName} title={title} preferFirstName />
|
||||||
|
</strong>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{mrState !== MessageRequestState.default ? (
|
{mrState !== MessageRequestState.default ? (
|
||||||
|
@ -53,26 +62,34 @@ export function MessageRequestActions({
|
||||||
) : null}
|
) : null}
|
||||||
<div className="module-message-request-actions">
|
<div className="module-message-request-actions">
|
||||||
<p className="module-message-request-actions__message">
|
<p className="module-message-request-actions__message">
|
||||||
<Intl
|
{conversationType === 'direct' && isBlocked && (
|
||||||
i18n={i18n}
|
<Intl
|
||||||
id={`MessageRequests--message-${conversationType}${
|
i18n={i18n}
|
||||||
isBlocked ? '-blocked' : ''
|
id="MessageRequests--message-direct-blocked"
|
||||||
}`}
|
components={{ name }}
|
||||||
components={{
|
/>
|
||||||
name: (
|
)}
|
||||||
<strong
|
{conversationType === 'direct' && !isBlocked && (
|
||||||
key="name"
|
<Intl
|
||||||
className="module-message-request-actions__message__name"
|
i18n={i18n}
|
||||||
>
|
id="MessageRequests--message-direct"
|
||||||
<ContactName
|
components={{ name }}
|
||||||
firstName={firstName}
|
/>
|
||||||
title={title}
|
)}
|
||||||
preferFirstName
|
{conversationType === 'group' && isBlocked && (
|
||||||
/>
|
<Intl
|
||||||
</strong>
|
i18n={i18n}
|
||||||
),
|
id="MessageRequests--message-group-blocked"
|
||||||
}}
|
components={{ name }}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
{conversationType === 'group' && !isBlocked && (
|
||||||
|
<Intl
|
||||||
|
i18n={i18n}
|
||||||
|
id="MessageRequests--message-group"
|
||||||
|
components={{ name }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
<div className="module-message-request-actions__buttons">
|
<div className="module-message-request-actions__buttons">
|
||||||
<Button
|
<Button
|
||||||
|
|
|
@ -132,13 +132,23 @@ export function MessageRequestActionsConfirmation({
|
||||||
onChangeState(MessageRequestState.default);
|
onChangeState(MessageRequestState.default);
|
||||||
}}
|
}}
|
||||||
title={
|
title={
|
||||||
<Intl
|
conversationType === 'direct' ? (
|
||||||
i18n={i18n}
|
<Intl
|
||||||
id={`MessageRequests--delete-${conversationType}-confirm-title`}
|
i18n={i18n}
|
||||||
components={{
|
id="MessageRequests--delete-direct-confirm-title"
|
||||||
title: <ContactName key="name" title={title} />,
|
components={{
|
||||||
}}
|
title: <ContactName key="name" title={title} />,
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Intl
|
||||||
|
i18n={i18n}
|
||||||
|
id="MessageRequests--delete-group-confirm-title"
|
||||||
|
components={{
|
||||||
|
title: <ContactName key="name" title={title} />,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
actions={[
|
actions={[
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,32 +35,30 @@ export function SafetyNumberNotification({
|
||||||
i18n,
|
i18n,
|
||||||
toggleSafetyNumberModal,
|
toggleSafetyNumberModal,
|
||||||
}: Props): JSX.Element {
|
}: Props): JSX.Element {
|
||||||
const changeKey = isGroup
|
const name = (
|
||||||
? 'safetyNumberChangedGroup'
|
<span
|
||||||
: 'safetyNumberChanged';
|
key="external-1"
|
||||||
|
className="module-safety-number-notification__contact"
|
||||||
|
>
|
||||||
|
<ContactName
|
||||||
|
title={contact.title}
|
||||||
|
module="module-safety-number-notification__contact"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<SystemMessage
|
<SystemMessage
|
||||||
icon="safety-number"
|
icon="safety-number"
|
||||||
contents={
|
contents={
|
||||||
// eslint-disable-next-line local-rules/valid-i18n-keys
|
isGroup ? (
|
||||||
<Intl
|
<Intl
|
||||||
id={changeKey}
|
id="safetyNumberChangedGroup"
|
||||||
components={{
|
components={{ name }}
|
||||||
name: (
|
i18n={i18n}
|
||||||
<span
|
/>
|
||||||
key="external-1"
|
) : (
|
||||||
className="module-safety-number-notification__contact"
|
<Intl id="safetyNumberChanged" components={{ name }} i18n={i18n} />
|
||||||
>
|
)
|
||||||
<ContactName
|
|
||||||
title={contact.title}
|
|
||||||
module="module-safety-number-notification__contact"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
i18n={i18n}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
button={
|
button={
|
||||||
<Button
|
<Button
|
||||||
|
|
|
@ -41,51 +41,46 @@ export type Props = PropsData & PropsHousekeeping;
|
||||||
export function TimerNotification(props: Props): JSX.Element {
|
export function TimerNotification(props: Props): JSX.Element {
|
||||||
const { disabled, i18n, title, type } = props;
|
const { disabled, i18n, title, type } = props;
|
||||||
|
|
||||||
let changeKey: string;
|
|
||||||
let timespan: string;
|
let timespan: string;
|
||||||
if (props.disabled) {
|
if (props.disabled) {
|
||||||
changeKey = 'disabledDisappearingMessages';
|
|
||||||
timespan = ''; // Set to the empty string to satisfy types
|
timespan = ''; // Set to the empty string to satisfy types
|
||||||
} else {
|
} else {
|
||||||
changeKey = 'theyChangedTheTimer';
|
|
||||||
timespan = expirationTimer.format(i18n, props.expireTimer);
|
timespan = expirationTimer.format(i18n, props.expireTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const name = <ContactName key="external-1" title={title} />;
|
||||||
|
|
||||||
let message: ReactNode;
|
let message: ReactNode;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'fromOther':
|
case 'fromOther':
|
||||||
message = (
|
message = props.disabled ? (
|
||||||
// eslint-disable-next-line local-rules/valid-i18n-keys
|
|
||||||
<Intl
|
<Intl
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
id={changeKey}
|
id="disabledDisappearingMessages"
|
||||||
components={{
|
components={{ name }}
|
||||||
name: <ContactName key="external-1" title={title} />,
|
/>
|
||||||
time: timespan,
|
) : (
|
||||||
}}
|
<Intl
|
||||||
|
i18n={i18n}
|
||||||
|
id="theyChangedTheTimer"
|
||||||
|
components={{ name, time: timespan }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 'fromMe':
|
case 'fromMe':
|
||||||
message = disabled
|
message = disabled
|
||||||
? i18n('youDisabledDisappearingMessages')
|
? i18n('youDisabledDisappearingMessages')
|
||||||
: i18n('youChangedTheTimer', {
|
: i18n('youChangedTheTimer', { time: timespan });
|
||||||
time: timespan,
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case 'fromSync':
|
case 'fromSync':
|
||||||
message = disabled
|
message = disabled
|
||||||
? i18n('disappearingMessagesDisabled')
|
? i18n('disappearingMessagesDisabled')
|
||||||
: i18n('timerSetOnSync', {
|
: i18n('timerSetOnSync', { time: timespan });
|
||||||
time: timespan,
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case 'fromMember':
|
case 'fromMember':
|
||||||
message = disabled
|
message = disabled
|
||||||
? i18n('disappearingMessagesDisabledByMember')
|
? i18n('disappearingMessagesDisabledByMember')
|
||||||
: i18n('timerSetByMember', {
|
: i18n('timerSetByMember', { time: timespan });
|
||||||
time: timespan,
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log.warn('TimerNotification: unsupported type provided:', type);
|
log.warn('TimerNotification: unsupported type provided:', type);
|
||||||
|
|
|
@ -30,42 +30,64 @@ type PropsHousekeeping = {
|
||||||
|
|
||||||
export type Props = PropsData & PropsHousekeeping;
|
export type Props = PropsData & PropsHousekeeping;
|
||||||
|
|
||||||
|
function UnsupportedMessageContents({ canProcessNow, contact, i18n }: Props) {
|
||||||
|
const { isMe } = contact;
|
||||||
|
const contactName = (
|
||||||
|
<span key="external-1" className="module-unsupported-message__contact">
|
||||||
|
<ContactName
|
||||||
|
title={contact.title}
|
||||||
|
module="module-unsupported-message__contact"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
if (isMe) {
|
||||||
|
if (canProcessNow) {
|
||||||
|
return (
|
||||||
|
<Intl
|
||||||
|
id="Message--unsupported-message-ask-to-resend"
|
||||||
|
components={{ contact: contactName }}
|
||||||
|
i18n={i18n}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Intl
|
||||||
|
id="Message--from-me-unsupported-message"
|
||||||
|
components={{ contact: contactName }}
|
||||||
|
i18n={i18n}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (canProcessNow) {
|
||||||
|
return (
|
||||||
|
<Intl
|
||||||
|
id="Message--from-me-unsupported-message-ask-to-resend"
|
||||||
|
components={{ contact: contactName }}
|
||||||
|
i18n={i18n}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Intl
|
||||||
|
id="Message--from-me-unsupported-message"
|
||||||
|
components={{ contact: contactName }}
|
||||||
|
i18n={i18n}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function UnsupportedMessage({
|
export function UnsupportedMessage({
|
||||||
canProcessNow,
|
canProcessNow,
|
||||||
contact,
|
contact,
|
||||||
i18n,
|
i18n,
|
||||||
}: Props): JSX.Element {
|
}: Props): JSX.Element {
|
||||||
const { isMe } = contact;
|
|
||||||
|
|
||||||
const otherStringId = canProcessNow
|
|
||||||
? 'Message--unsupported-message-ask-to-resend'
|
|
||||||
: 'Message--unsupported-message';
|
|
||||||
const meStringId = canProcessNow
|
|
||||||
? 'Message--from-me-unsupported-message-ask-to-resend'
|
|
||||||
: 'Message--from-me-unsupported-message';
|
|
||||||
const stringId = isMe ? meStringId : otherStringId;
|
|
||||||
const icon = canProcessNow ? 'unsupported--can-process' : 'unsupported';
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SystemMessage
|
<SystemMessage
|
||||||
icon={icon}
|
icon={canProcessNow ? 'unsupported--can-process' : 'unsupported'}
|
||||||
contents={
|
contents={
|
||||||
// eslint-disable-next-line local-rules/valid-i18n-keys
|
<UnsupportedMessageContents
|
||||||
<Intl
|
canProcessNow={canProcessNow}
|
||||||
id={stringId}
|
contact={contact}
|
||||||
components={{
|
|
||||||
contact: (
|
|
||||||
<span
|
|
||||||
key="external-1"
|
|
||||||
className="module-unsupported-message__contact"
|
|
||||||
>
|
|
||||||
<ContactName
|
|
||||||
title={contact.title}
|
|
||||||
module="module-unsupported-message__contact"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,45 +25,43 @@ type PropsHousekeeping = {
|
||||||
export type Props = PropsData & PropsHousekeeping;
|
export type Props = PropsData & PropsHousekeeping;
|
||||||
|
|
||||||
export class VerificationNotification extends React.Component<Props> {
|
export class VerificationNotification extends React.Component<Props> {
|
||||||
public getStringId(): string {
|
public renderContents(): JSX.Element {
|
||||||
const { isLocal, type } = this.props;
|
const { contact, isLocal, type, i18n } = this.props;
|
||||||
|
|
||||||
|
const name = (
|
||||||
|
<ContactName
|
||||||
|
key="external-1"
|
||||||
|
title={contact.title}
|
||||||
|
module="module-verification-notification__contact"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'markVerified':
|
case 'markVerified':
|
||||||
return isLocal
|
return isLocal ? (
|
||||||
? 'youMarkedAsVerified'
|
<Intl id="youMarkedAsVerified" components={{ name }} i18n={i18n} />
|
||||||
: 'youMarkedAsVerifiedOtherDevice';
|
) : (
|
||||||
|
<Intl
|
||||||
|
id="youMarkedAsVerifiedOtherDevice"
|
||||||
|
components={{ name }}
|
||||||
|
i18n={i18n}
|
||||||
|
/>
|
||||||
|
);
|
||||||
case 'markNotVerified':
|
case 'markNotVerified':
|
||||||
return isLocal
|
return isLocal ? (
|
||||||
? 'youMarkedAsNotVerified'
|
<Intl id="youMarkedAsNotVerified" components={{ name }} i18n={i18n} />
|
||||||
: 'youMarkedAsNotVerifiedOtherDevice';
|
) : (
|
||||||
|
<Intl
|
||||||
|
id="youMarkedAsNotVerifiedOtherDevice"
|
||||||
|
components={{ name }}
|
||||||
|
i18n={i18n}
|
||||||
|
/>
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
throw missingCaseError(type);
|
throw missingCaseError(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public renderContents(): JSX.Element {
|
|
||||||
const { contact, i18n } = this.props;
|
|
||||||
const id = this.getStringId();
|
|
||||||
|
|
||||||
return (
|
|
||||||
// eslint-disable-next-line local-rules/valid-i18n-keys
|
|
||||||
<Intl
|
|
||||||
id={id}
|
|
||||||
components={{
|
|
||||||
name: (
|
|
||||||
<ContactName
|
|
||||||
key="external-1"
|
|
||||||
title={contact.title}
|
|
||||||
module="module-verification-notification__contact"
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
i18n={i18n}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override render(): JSX.Element {
|
public override render(): JSX.Element {
|
||||||
const { type } = this.props;
|
const { type } = this.props;
|
||||||
const icon = type === 'markVerified' ? 'verified' : 'verified-not';
|
const icon = type === 'markVerified' ? 'verified' : 'verified-not';
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
/* eslint-disable local-rules/valid-i18n-keys */
|
|
||||||
|
|
||||||
import React, {
|
import React, {
|
||||||
useEffect,
|
useEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
|
@ -212,7 +210,8 @@ export function ChooseGroupMembersModal({
|
||||||
if (virtualIndex === 0) {
|
if (virtualIndex === 0) {
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'contactsHeader',
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
getHeaderText: i18n => i18n('contactsHeader'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +249,8 @@ export function ChooseGroupMembersModal({
|
||||||
if (virtualIndex === 0) {
|
if (virtualIndex === 0) {
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'findByPhoneNumberHeader',
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
getHeaderText: i18n => i18n('findByPhoneNumberHeader'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (virtualIndex === 1) {
|
if (virtualIndex === 1) {
|
||||||
|
@ -268,7 +268,8 @@ export function ChooseGroupMembersModal({
|
||||||
if (virtualIndex === 0) {
|
if (virtualIndex === 0) {
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'findByUsernameHeader',
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
|
getHeaderText: i18n => i18n('findByUsernameHeader'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (virtualIndex === 1) {
|
if (virtualIndex === 1) {
|
||||||
|
@ -307,16 +308,18 @@ export function ChooseGroupMembersModal({
|
||||||
|
|
||||||
let item;
|
let item;
|
||||||
switch (row?.type) {
|
switch (row?.type) {
|
||||||
case RowType.Header:
|
case RowType.Header: {
|
||||||
|
const headerText = row.getHeaderText(i18n);
|
||||||
item = (
|
item = (
|
||||||
<div
|
<div
|
||||||
className="module-conversation-list__item--header"
|
className="module-conversation-list__item--header"
|
||||||
aria-label={i18n(row.i18nKey)}
|
aria-label={headerText}
|
||||||
>
|
>
|
||||||
{i18n(row.i18nKey)}
|
{headerText}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case RowType.ContactCheckbox:
|
case RowType.ContactCheckbox:
|
||||||
item = (
|
item = (
|
||||||
<ContactCheckbox
|
<ContactCheckbox
|
||||||
|
|
|
@ -618,8 +618,7 @@ function ConversationDetailsCallButton({
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
variant={ButtonVariant.Details}
|
variant={ButtonVariant.Details}
|
||||||
>
|
>
|
||||||
{/* eslint-disable-next-line local-rules/valid-i18n-keys */}
|
{type === 'audio' ? i18n('audio') : i18n('video')}
|
||||||
{i18n(type)}
|
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -71,11 +71,25 @@ function MediaSection({
|
||||||
const first = section.mediaItems[0];
|
const first = section.mediaItems[0];
|
||||||
const { message } = first;
|
const { message } = first;
|
||||||
const date = moment(getMessageTimestamp(message));
|
const date = moment(getMessageTimestamp(message));
|
||||||
const header =
|
|
||||||
section.type === 'yearMonth'
|
function getHeader(): string {
|
||||||
? date.format(MONTH_FORMAT)
|
switch (section.type) {
|
||||||
: // eslint-disable-next-line local-rules/valid-i18n-keys
|
case 'yearMonth':
|
||||||
i18n(section.type);
|
return date.format(MONTH_FORMAT);
|
||||||
|
case 'today':
|
||||||
|
return i18n('today');
|
||||||
|
case 'yesterday':
|
||||||
|
return i18n('yesterday');
|
||||||
|
case 'thisWeek':
|
||||||
|
return i18n('thisWeek');
|
||||||
|
case 'thisMonth':
|
||||||
|
return i18n('thisMonth');
|
||||||
|
default:
|
||||||
|
throw missingCaseError(section);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const header = getHeader();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AttachmentSection
|
<AttachmentSection
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { Emoji } from './Emoji';
|
||||||
import { dataByCategory, search } from './lib';
|
import { dataByCategory, search } from './lib';
|
||||||
import type { LocalizerType } from '../../types/Util';
|
import type { LocalizerType } from '../../types/Util';
|
||||||
import { isSingleGrapheme } from '../../util/grapheme';
|
import { isSingleGrapheme } from '../../util/grapheme';
|
||||||
|
import { missingCaseError } from '../../util';
|
||||||
|
|
||||||
export type EmojiPickDataType = {
|
export type EmojiPickDataType = {
|
||||||
skinTone?: number;
|
skinTone?: number;
|
||||||
|
@ -61,7 +62,9 @@ const categories = [
|
||||||
'object',
|
'object',
|
||||||
'symbol',
|
'symbol',
|
||||||
'flag',
|
'flag',
|
||||||
];
|
] as const;
|
||||||
|
|
||||||
|
type Category = typeof categories[number];
|
||||||
|
|
||||||
export const EmojiPicker = React.memo(
|
export const EmojiPicker = React.memo(
|
||||||
React.forwardRef<HTMLDivElement, Props>(
|
React.forwardRef<HTMLDivElement, Props>(
|
||||||
|
@ -80,7 +83,7 @@ export const EmojiPicker = React.memo(
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
const [firstRecent] = React.useState(recentEmojis);
|
const [firstRecent] = React.useState(recentEmojis);
|
||||||
const [selectedCategory, setSelectedCategory] = React.useState(
|
const [selectedCategory, setSelectedCategory] = React.useState<Category>(
|
||||||
categories[0]
|
categories[0]
|
||||||
);
|
);
|
||||||
const [searchMode, setSearchMode] = React.useState(false);
|
const [searchMode, setSearchMode] = React.useState(false);
|
||||||
|
@ -277,7 +280,7 @@ export const EmojiPicker = React.memo(
|
||||||
|
|
||||||
const { category } = e.currentTarget.dataset;
|
const { category } = e.currentTarget.dataset;
|
||||||
if (category) {
|
if (category) {
|
||||||
setSelectedCategory(category);
|
setSelectedCategory(category as Category);
|
||||||
setScrollToRow(catToRowOffsets[category]);
|
setScrollToRow(catToRowOffsets[category]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -332,11 +335,36 @@ export const EmojiPicker = React.memo(
|
||||||
findLast(catOffsetEntries, ([, row]) => rowStartIndex >= row) ||
|
findLast(catOffsetEntries, ([, row]) => rowStartIndex >= row) ||
|
||||||
categories;
|
categories;
|
||||||
|
|
||||||
setSelectedCategory(cat);
|
setSelectedCategory(cat as Category);
|
||||||
}, 10),
|
}, 10),
|
||||||
[catOffsetEntries]
|
[catOffsetEntries]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function getCategoryButtonLabel(category: Category): string {
|
||||||
|
switch (category) {
|
||||||
|
case 'recents':
|
||||||
|
return i18n('EmojiPicker__button--recents');
|
||||||
|
case 'emoji':
|
||||||
|
return i18n('EmojiPicker__button--emoji');
|
||||||
|
case 'animal':
|
||||||
|
return i18n('EmojiPicker__button--animal');
|
||||||
|
case 'food':
|
||||||
|
return i18n('EmojiPicker__button--food');
|
||||||
|
case 'activity':
|
||||||
|
return i18n('EmojiPicker__button--activity');
|
||||||
|
case 'travel':
|
||||||
|
return i18n('EmojiPicker__button--travel');
|
||||||
|
case 'object':
|
||||||
|
return i18n('EmojiPicker__button--object');
|
||||||
|
case 'symbol':
|
||||||
|
return i18n('EmojiPicker__button--symbol');
|
||||||
|
case 'flag':
|
||||||
|
return i18n('EmojiPicker__button--flag');
|
||||||
|
default:
|
||||||
|
throw missingCaseError(category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FocusTrap
|
<FocusTrap
|
||||||
focusTrapOptions={{
|
focusTrapOptions={{
|
||||||
|
@ -394,7 +422,7 @@ export const EmojiPicker = React.memo(
|
||||||
? 'module-emoji-picker__button--selected'
|
? 'module-emoji-picker__button--selected'
|
||||||
: null
|
: null
|
||||||
)}
|
)}
|
||||||
aria-label={i18n(`EmojiPicker__button--${cat}`)}
|
aria-label={getCategoryButtonLabel(cat)}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -314,7 +314,7 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper<LeftPaneCho
|
||||||
if (virtualRowIndex === 0) {
|
if (virtualRowIndex === 0) {
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'contactsHeader',
|
getHeaderText: i18n => i18n('contactsHeader'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper<LeftPaneCho
|
||||||
if (virtualRowIndex === 0) {
|
if (virtualRowIndex === 0) {
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'findByPhoneNumberHeader',
|
getHeaderText: i18n => i18n('findByPhoneNumberHeader'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (virtualRowIndex === 1) {
|
if (virtualRowIndex === 1) {
|
||||||
|
@ -363,7 +363,7 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper<LeftPaneCho
|
||||||
if (virtualRowIndex === 0) {
|
if (virtualRowIndex === 0) {
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'findByUsernameHeader',
|
getHeaderText: i18n => i18n('findByUsernameHeader'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (virtualRowIndex === 1) {
|
if (virtualRowIndex === 1) {
|
||||||
|
|
|
@ -194,7 +194,7 @@ export class LeftPaneComposeHelper extends LeftPaneHelper<LeftPaneComposePropsTy
|
||||||
if (virtualRowIndex === 0) {
|
if (virtualRowIndex === 0) {
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'contactsHeader',
|
getHeaderText: i18n => i18n('contactsHeader'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ export class LeftPaneComposeHelper extends LeftPaneHelper<LeftPaneComposePropsTy
|
||||||
if (virtualRowIndex === 0) {
|
if (virtualRowIndex === 0) {
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'groupsHeader',
|
getHeaderText: i18n => i18n('groupsHeader'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ export class LeftPaneComposeHelper extends LeftPaneHelper<LeftPaneComposePropsTy
|
||||||
if (virtualRowIndex === 0) {
|
if (virtualRowIndex === 0) {
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'findByUsernameHeader',
|
getHeaderText: i18n => i18n('findByUsernameHeader'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ export class LeftPaneComposeHelper extends LeftPaneHelper<LeftPaneComposePropsTy
|
||||||
if (virtualRowIndex === 0) {
|
if (virtualRowIndex === 0) {
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'findByPhoneNumberHeader',
|
getHeaderText: i18n => i18n('findByPhoneNumberHeader'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,12 +150,12 @@ export class LeftPaneInboxHelper extends LeftPaneHelper<LeftPaneInboxPropsType>
|
||||||
case 0:
|
case 0:
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'LeftPane--pinned',
|
getHeaderText: i18n => i18n('LeftPane--pinned'),
|
||||||
};
|
};
|
||||||
case pinnedConversations.length + 1:
|
case pinnedConversations.length + 1:
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'LeftPane--chats',
|
getHeaderText: i18n => i18n('LeftPane--chats'),
|
||||||
};
|
};
|
||||||
case pinnedConversations.length + conversations.length + 2:
|
case pinnedConversations.length + conversations.length + 2:
|
||||||
if (archivedConversationsCount) {
|
if (archivedConversationsCount) {
|
||||||
|
|
|
@ -229,7 +229,7 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<LeftPaneSearchPropsType
|
||||||
if (rowIndex === 0) {
|
if (rowIndex === 0) {
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'conversationsHeader',
|
getHeaderText: i18n => i18n('conversationsHeader'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
assertDev(
|
assertDev(
|
||||||
|
@ -250,7 +250,7 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<LeftPaneSearchPropsType
|
||||||
if (localIndex === 0) {
|
if (localIndex === 0) {
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'contactsHeader',
|
getHeaderText: i18n => i18n('contactsHeader'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
assertDev(
|
assertDev(
|
||||||
|
@ -274,7 +274,7 @@ export class LeftPaneSearchHelper extends LeftPaneHelper<LeftPaneSearchPropsType
|
||||||
if (localIndex === 0) {
|
if (localIndex === 0) {
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'messagesHeader',
|
getHeaderText: i18n => i18n('messagesHeader'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
assertDev(
|
assertDev(
|
||||||
|
|
|
@ -258,7 +258,7 @@ export class LeftPaneSetGroupMetadataHelper extends LeftPaneHelper<LeftPaneSetGr
|
||||||
if (rowIndex === 0) {
|
if (rowIndex === 0) {
|
||||||
return {
|
return {
|
||||||
type: RowType.Header,
|
type: RowType.Header,
|
||||||
i18nKey: 'setGroupMetadata__members-header',
|
getHeaderText: i18n => i18n('setGroupMetadata__members-header'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,18 @@ export function renderChangeDetail<T>(
|
||||||
detail: GroupV2ChangeDetailType,
|
detail: GroupV2ChangeDetailType,
|
||||||
options: RenderOptionsType<T>
|
options: RenderOptionsType<T>
|
||||||
): T | string | ReadonlyArray<T | string> {
|
): T | string | ReadonlyArray<T | string> {
|
||||||
const { from, i18n, ourACI, ourPNI, renderContact, renderString } = options;
|
const {
|
||||||
|
from,
|
||||||
|
i18n: localizer,
|
||||||
|
ourACI,
|
||||||
|
ourPNI,
|
||||||
|
renderContact,
|
||||||
|
renderString,
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
function i18n(id: string, components?: ReplacementValuesType<T | string>) {
|
||||||
|
return renderString(id, localizer, components);
|
||||||
|
}
|
||||||
|
|
||||||
const isOurUuid = (uuid?: UUIDStringType): boolean => {
|
const isOurUuid = (uuid?: UUIDStringType): boolean => {
|
||||||
if (!uuid) {
|
if (!uuid) {
|
||||||
|
@ -79,88 +90,88 @@ export function renderChangeDetail<T>(
|
||||||
|
|
||||||
if (detail.type === 'create') {
|
if (detail.type === 'create') {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--create--you', i18n);
|
return i18n('GroupV2--create--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--create--other', i18n, {
|
return i18n('GroupV2--create--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--create--unknown', i18n);
|
return i18n('GroupV2--create--unknown');
|
||||||
}
|
}
|
||||||
if (detail.type === 'title') {
|
if (detail.type === 'title') {
|
||||||
const { newTitle } = detail;
|
const { newTitle } = detail;
|
||||||
|
|
||||||
if (newTitle) {
|
if (newTitle) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--title--change--you', i18n, { newTitle });
|
return i18n('GroupV2--title--change--you', { newTitle });
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--title--change--other', i18n, {
|
return i18n('GroupV2--title--change--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
newTitle,
|
newTitle,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--title--change--unknown', i18n, {
|
return i18n('GroupV2--title--change--unknown', {
|
||||||
newTitle,
|
newTitle,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--title--remove--you', i18n);
|
return i18n('GroupV2--title--remove--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--title--remove--other', i18n, {
|
return i18n('GroupV2--title--remove--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--title--remove--unknown', i18n);
|
return i18n('GroupV2--title--remove--unknown');
|
||||||
}
|
}
|
||||||
if (detail.type === 'avatar') {
|
if (detail.type === 'avatar') {
|
||||||
if (detail.removed) {
|
if (detail.removed) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--avatar--remove--you', i18n);
|
return i18n('GroupV2--avatar--remove--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--avatar--remove--other', i18n, {
|
return i18n('GroupV2--avatar--remove--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--avatar--remove--unknown', i18n);
|
return i18n('GroupV2--avatar--remove--unknown');
|
||||||
}
|
}
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--avatar--change--you', i18n);
|
return i18n('GroupV2--avatar--change--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--avatar--change--other', i18n, {
|
return i18n('GroupV2--avatar--change--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--avatar--change--unknown', i18n);
|
return i18n('GroupV2--avatar--change--unknown');
|
||||||
}
|
}
|
||||||
if (detail.type === 'access-attributes') {
|
if (detail.type === 'access-attributes') {
|
||||||
const { newPrivilege } = detail;
|
const { newPrivilege } = detail;
|
||||||
|
|
||||||
if (newPrivilege === AccessControlEnum.ADMINISTRATOR) {
|
if (newPrivilege === AccessControlEnum.ADMINISTRATOR) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--access-attributes--admins--you', i18n);
|
return i18n('GroupV2--access-attributes--admins--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--access-attributes--admins--other', i18n, {
|
return i18n('GroupV2--access-attributes--admins--other', {
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--access-attributes--admins--unknown', i18n);
|
return i18n('GroupV2--access-attributes--admins--unknown');
|
||||||
}
|
}
|
||||||
if (newPrivilege === AccessControlEnum.MEMBER) {
|
if (newPrivilege === AccessControlEnum.MEMBER) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--access-attributes--all--you', i18n);
|
return i18n('GroupV2--access-attributes--all--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--access-attributes--all--other', i18n, {
|
return i18n('GroupV2--access-attributes--all--other', {
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--access-attributes--all--unknown', i18n);
|
return i18n('GroupV2--access-attributes--all--unknown');
|
||||||
}
|
}
|
||||||
log.warn(
|
log.warn(
|
||||||
`access-attributes change type, privilege ${newPrivilege} is unknown`
|
`access-attributes change type, privilege ${newPrivilege} is unknown`
|
||||||
|
@ -172,25 +183,25 @@ export function renderChangeDetail<T>(
|
||||||
|
|
||||||
if (newPrivilege === AccessControlEnum.ADMINISTRATOR) {
|
if (newPrivilege === AccessControlEnum.ADMINISTRATOR) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--access-members--admins--you', i18n);
|
return i18n('GroupV2--access-members--admins--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--access-members--admins--other', i18n, {
|
return i18n('GroupV2--access-members--admins--other', {
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--access-members--admins--unknown', i18n);
|
return i18n('GroupV2--access-members--admins--unknown');
|
||||||
}
|
}
|
||||||
if (newPrivilege === AccessControlEnum.MEMBER) {
|
if (newPrivilege === AccessControlEnum.MEMBER) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--access-members--all--you', i18n);
|
return i18n('GroupV2--access-members--all--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--access-members--all--other', i18n, {
|
return i18n('GroupV2--access-members--all--other', {
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--access-members--all--unknown', i18n);
|
return i18n('GroupV2--access-members--all--unknown');
|
||||||
}
|
}
|
||||||
log.warn(
|
log.warn(
|
||||||
`access-members change type, privilege ${newPrivilege} is unknown`
|
`access-members change type, privilege ${newPrivilege} is unknown`
|
||||||
|
@ -202,35 +213,29 @@ export function renderChangeDetail<T>(
|
||||||
|
|
||||||
if (newPrivilege === AccessControlEnum.ADMINISTRATOR) {
|
if (newPrivilege === AccessControlEnum.ADMINISTRATOR) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--access-invite-link--enabled--you', i18n);
|
return i18n('GroupV2--access-invite-link--enabled--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--access-invite-link--enabled--other',
|
'GroupV2--access-invite-link--enabled--other',
|
||||||
i18n,
|
|
||||||
{ adminName: renderContact(from) }
|
{ adminName: renderContact(from) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return renderString(
|
return i18n('GroupV2--access-invite-link--enabled--unknown');
|
||||||
'GroupV2--access-invite-link--enabled--unknown',
|
|
||||||
i18n
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (newPrivilege === AccessControlEnum.ANY) {
|
if (newPrivilege === AccessControlEnum.ANY) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--access-invite-link--disabled--you', i18n);
|
return i18n('GroupV2--access-invite-link--disabled--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--access-invite-link--disabled--other',
|
'GroupV2--access-invite-link--disabled--other',
|
||||||
i18n,
|
|
||||||
{ adminName: renderContact(from) }
|
{ adminName: renderContact(from) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return renderString(
|
return i18n('GroupV2--access-invite-link--disabled--unknown');
|
||||||
'GroupV2--access-invite-link--disabled--unknown',
|
|
||||||
i18n
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
log.warn(
|
log.warn(
|
||||||
`access-invite-link change type, privilege ${newPrivilege} is unknown`
|
`access-invite-link change type, privilege ${newPrivilege} is unknown`
|
||||||
|
@ -243,27 +248,27 @@ export function renderChangeDetail<T>(
|
||||||
|
|
||||||
if (weAreJoiner) {
|
if (weAreJoiner) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--member-add--you--you', i18n);
|
return i18n('GroupV2--member-add--you--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--member-add--you--other', i18n, {
|
return i18n('GroupV2--member-add--you--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--member-add--you--unknown', i18n);
|
return i18n('GroupV2--member-add--you--unknown');
|
||||||
}
|
}
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--member-add--other--you', i18n, {
|
return i18n('GroupV2--member-add--other--you', {
|
||||||
memberName: renderContact(uuid),
|
memberName: renderContact(uuid),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--member-add--other--other', i18n, {
|
return i18n('GroupV2--member-add--other--other', {
|
||||||
adderName: renderContact(from),
|
adderName: renderContact(from),
|
||||||
addeeName: renderContact(uuid),
|
addeeName: renderContact(uuid),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--member-add--other--unknown', i18n, {
|
return i18n('GroupV2--member-add--other--unknown', {
|
||||||
memberName: renderContact(uuid),
|
memberName: renderContact(uuid),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -276,54 +281,51 @@ export function renderChangeDetail<T>(
|
||||||
if (weAreJoiner) {
|
if (weAreJoiner) {
|
||||||
// They can't be the same, no fromYou check here
|
// They can't be the same, no fromYou check here
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--member-add--you--other', i18n, {
|
return i18n('GroupV2--member-add--you--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--member-add--you--unknown', i18n);
|
return i18n('GroupV2--member-add--you--unknown');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--member-add--invited--you', i18n, {
|
return i18n('GroupV2--member-add--invited--you', {
|
||||||
inviteeName: renderContact(uuid),
|
inviteeName: renderContact(uuid),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--member-add--invited--other', i18n, {
|
return i18n('GroupV2--member-add--invited--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
inviteeName: renderContact(uuid),
|
inviteeName: renderContact(uuid),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--member-add--invited--unknown', i18n, {
|
return i18n('GroupV2--member-add--invited--unknown', {
|
||||||
inviteeName: renderContact(uuid),
|
inviteeName: renderContact(uuid),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (weAreJoiner) {
|
if (weAreJoiner) {
|
||||||
if (inviter) {
|
if (inviter) {
|
||||||
return renderString('GroupV2--member-add--from-invite--you', i18n, {
|
return i18n('GroupV2--member-add--from-invite--you', {
|
||||||
inviterName: renderContact(inviter),
|
inviterName: renderContact(inviter),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString(
|
return i18n('GroupV2--member-add--from-invite--you-no-from');
|
||||||
'GroupV2--member-add--from-invite--you-no-from',
|
|
||||||
i18n
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (weAreInviter) {
|
if (weAreInviter) {
|
||||||
return renderString('GroupV2--member-add--from-invite--from-you', i18n, {
|
return i18n('GroupV2--member-add--from-invite--from-you', {
|
||||||
inviteeName: renderContact(uuid),
|
inviteeName: renderContact(uuid),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (inviter) {
|
if (inviter) {
|
||||||
return renderString('GroupV2--member-add--from-invite--other', i18n, {
|
return i18n('GroupV2--member-add--from-invite--other', {
|
||||||
inviteeName: renderContact(uuid),
|
inviteeName: renderContact(uuid),
|
||||||
inviterName: renderContact(inviter),
|
inviterName: renderContact(inviter),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--member-add--from-invite--other-no-from',
|
'GroupV2--member-add--from-invite--other-no-from',
|
||||||
i18n,
|
|
||||||
{
|
{
|
||||||
inviteeName: renderContact(uuid),
|
inviteeName: renderContact(uuid),
|
||||||
}
|
}
|
||||||
|
@ -333,10 +335,10 @@ export function renderChangeDetail<T>(
|
||||||
const { uuid } = detail;
|
const { uuid } = detail;
|
||||||
|
|
||||||
if (fromYou && isOurUuid(uuid)) {
|
if (fromYou && isOurUuid(uuid)) {
|
||||||
return renderString('GroupV2--member-add-from-link--you--you', i18n);
|
return i18n('GroupV2--member-add-from-link--you--you');
|
||||||
}
|
}
|
||||||
if (from && uuid === from) {
|
if (from && uuid === from) {
|
||||||
return renderString('GroupV2--member-add-from-link--other', i18n, {
|
return i18n('GroupV2--member-add-from-link--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -344,7 +346,7 @@ export function renderChangeDetail<T>(
|
||||||
// Note: this shouldn't happen, because we only capture 'add-from-link' status
|
// Note: this shouldn't happen, because we only capture 'add-from-link' status
|
||||||
// from group change events, which always have a sender.
|
// from group change events, which always have a sender.
|
||||||
log.warn('member-add-from-link change type; we have no from!');
|
log.warn('member-add-from-link change type; we have no from!');
|
||||||
return renderString('GroupV2--member-add--other--unknown', i18n, {
|
return i18n('GroupV2--member-add--other--unknown', {
|
||||||
memberName: renderContact(uuid),
|
memberName: renderContact(uuid),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -354,9 +356,9 @@ export function renderChangeDetail<T>(
|
||||||
|
|
||||||
if (weAreJoiner) {
|
if (weAreJoiner) {
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--member-add-from-admin-approval--you--other',
|
'GroupV2--member-add-from-admin-approval--you--other',
|
||||||
i18n,
|
|
||||||
{ adminName: renderContact(from) }
|
{ adminName: renderContact(from) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -366,23 +368,20 @@ export function renderChangeDetail<T>(
|
||||||
log.warn(
|
log.warn(
|
||||||
'member-add-from-admin-approval change type; we have no from, and we are joiner!'
|
'member-add-from-admin-approval change type; we have no from, and we are joiner!'
|
||||||
);
|
);
|
||||||
return renderString(
|
return i18n('GroupV2--member-add-from-admin-approval--you--unknown');
|
||||||
'GroupV2--member-add-from-admin-approval--you--unknown',
|
|
||||||
i18n
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--member-add-from-admin-approval--other--you',
|
'GroupV2--member-add-from-admin-approval--other--you',
|
||||||
i18n,
|
|
||||||
{ joinerName: renderContact(uuid) }
|
{ joinerName: renderContact(uuid) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--member-add-from-admin-approval--other--other',
|
'GroupV2--member-add-from-admin-approval--other--other',
|
||||||
i18n,
|
|
||||||
{
|
{
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
joinerName: renderContact(uuid),
|
joinerName: renderContact(uuid),
|
||||||
|
@ -393,9 +392,9 @@ export function renderChangeDetail<T>(
|
||||||
// Note: this shouldn't happen, because we only capture 'add-from-admin-approval'
|
// Note: this shouldn't happen, because we only capture 'add-from-admin-approval'
|
||||||
// status from group change events, which always have a sender.
|
// status from group change events, which always have a sender.
|
||||||
log.warn('member-add-from-admin-approval change type; we have no from');
|
log.warn('member-add-from-admin-approval change type; we have no from');
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--member-add-from-admin-approval--other--unknown',
|
'GroupV2--member-add-from-admin-approval--other--unknown',
|
||||||
i18n,
|
|
||||||
{ joinerName: renderContact(uuid) }
|
{ joinerName: renderContact(uuid) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -405,33 +404,33 @@ export function renderChangeDetail<T>(
|
||||||
|
|
||||||
if (weAreLeaver) {
|
if (weAreLeaver) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--member-remove--you--you', i18n);
|
return i18n('GroupV2--member-remove--you--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--member-remove--you--other', i18n, {
|
return i18n('GroupV2--member-remove--you--other', {
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--member-remove--you--unknown', i18n);
|
return i18n('GroupV2--member-remove--you--unknown');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--member-remove--other--you', i18n, {
|
return i18n('GroupV2--member-remove--other--you', {
|
||||||
memberName: renderContact(uuid),
|
memberName: renderContact(uuid),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (from && from === uuid) {
|
if (from && from === uuid) {
|
||||||
return renderString('GroupV2--member-remove--other--self', i18n, {
|
return i18n('GroupV2--member-remove--other--self', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--member-remove--other--other', i18n, {
|
return i18n('GroupV2--member-remove--other--other', {
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
memberName: renderContact(uuid),
|
memberName: renderContact(uuid),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--member-remove--other--unknown', i18n, {
|
return i18n('GroupV2--member-remove--other--unknown', {
|
||||||
memberName: renderContact(uuid),
|
memberName: renderContact(uuid),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -442,77 +441,59 @@ export function renderChangeDetail<T>(
|
||||||
if (newPrivilege === RoleEnum.ADMINISTRATOR) {
|
if (newPrivilege === RoleEnum.ADMINISTRATOR) {
|
||||||
if (weAreMember) {
|
if (weAreMember) {
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--member-privilege--promote--you--other',
|
'GroupV2--member-privilege--promote--you--other',
|
||||||
i18n,
|
|
||||||
{ adminName: renderContact(from) }
|
{ adminName: renderContact(from) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return renderString(
|
return i18n('GroupV2--member-privilege--promote--you--unknown');
|
||||||
'GroupV2--member-privilege--promote--you--unknown',
|
|
||||||
i18n
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString(
|
return i18n('GroupV2--member-privilege--promote--other--you', {
|
||||||
'GroupV2--member-privilege--promote--other--you',
|
memberName: renderContact(uuid),
|
||||||
i18n,
|
});
|
||||||
{ memberName: renderContact(uuid) }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString(
|
return i18n('GroupV2--member-privilege--promote--other--other', {
|
||||||
'GroupV2--member-privilege--promote--other--other',
|
adminName: renderContact(from),
|
||||||
i18n,
|
memberName: renderContact(uuid),
|
||||||
{
|
});
|
||||||
adminName: renderContact(from),
|
|
||||||
memberName: renderContact(uuid),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return renderString(
|
return i18n('GroupV2--member-privilege--promote--other--unknown', {
|
||||||
'GroupV2--member-privilege--promote--other--unknown',
|
memberName: renderContact(uuid),
|
||||||
i18n,
|
});
|
||||||
{ memberName: renderContact(uuid) }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (newPrivilege === RoleEnum.DEFAULT) {
|
if (newPrivilege === RoleEnum.DEFAULT) {
|
||||||
if (weAreMember) {
|
if (weAreMember) {
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString(
|
return i18n('GroupV2--member-privilege--demote--you--other', {
|
||||||
'GroupV2--member-privilege--demote--you--other',
|
adminName: renderContact(from),
|
||||||
i18n,
|
});
|
||||||
{ adminName: renderContact(from) }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return renderString(
|
return i18n('GroupV2--member-privilege--demote--you--unknown');
|
||||||
'GroupV2--member-privilege--demote--you--unknown',
|
|
||||||
i18n
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString(
|
return i18n('GroupV2--member-privilege--demote--other--you', {
|
||||||
'GroupV2--member-privilege--demote--other--you',
|
memberName: renderContact(uuid),
|
||||||
i18n,
|
});
|
||||||
{ memberName: renderContact(uuid) }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--member-privilege--demote--other--other',
|
'GroupV2--member-privilege--demote--other--other',
|
||||||
i18n,
|
|
||||||
{
|
{
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
memberName: renderContact(uuid),
|
memberName: renderContact(uuid),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--member-privilege--demote--other--unknown',
|
'GroupV2--member-privilege--demote--other--unknown',
|
||||||
i18n,
|
|
||||||
{ memberName: renderContact(uuid) }
|
{ memberName: renderContact(uuid) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -526,39 +507,39 @@ export function renderChangeDetail<T>(
|
||||||
const weAreInvited = isOurUuid(uuid);
|
const weAreInvited = isOurUuid(uuid);
|
||||||
if (weAreInvited) {
|
if (weAreInvited) {
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--pending-add--one--you--other', i18n, {
|
return i18n('GroupV2--pending-add--one--you--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--pending-add--one--you--unknown', i18n);
|
return i18n('GroupV2--pending-add--one--you--unknown');
|
||||||
}
|
}
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--pending-add--one--other--you', i18n, {
|
return i18n('GroupV2--pending-add--one--other--you', {
|
||||||
inviteeName: renderContact(uuid),
|
inviteeName: renderContact(uuid),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--pending-add--one--other--other', i18n, {
|
return i18n('GroupV2--pending-add--one--other--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--pending-add--one--other--unknown', i18n);
|
return i18n('GroupV2--pending-add--one--other--unknown');
|
||||||
}
|
}
|
||||||
if (detail.type === 'pending-add-many') {
|
if (detail.type === 'pending-add-many') {
|
||||||
const { count } = detail;
|
const { count } = detail;
|
||||||
|
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--pending-add--many--you', i18n, {
|
return i18n('GroupV2--pending-add--many--you', {
|
||||||
count: count.toString(),
|
count: count.toString(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--pending-add--many--other', i18n, {
|
return i18n('GroupV2--pending-add--many--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
count: count.toString(),
|
count: count.toString(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--pending-add--many--unknown', i18n, {
|
return i18n('GroupV2--pending-add--many--unknown', {
|
||||||
count: count.toString(),
|
count: count.toString(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -571,91 +552,91 @@ export function renderChangeDetail<T>(
|
||||||
|
|
||||||
if (weAreInviter) {
|
if (weAreInviter) {
|
||||||
if (sentByInvited) {
|
if (sentByInvited) {
|
||||||
return renderString('GroupV2--pending-remove--decline--you', i18n, {
|
return i18n('GroupV2--pending-remove--decline--you', {
|
||||||
inviteeName: renderContact(uuid),
|
inviteeName: renderContact(uuid),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke-invite-from-you--one--you',
|
'GroupV2--pending-remove--revoke-invite-from-you--one--you',
|
||||||
i18n,
|
|
||||||
{ inviteeName: renderContact(uuid) }
|
{ inviteeName: renderContact(uuid) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke-invite-from-you--one--other',
|
'GroupV2--pending-remove--revoke-invite-from-you--one--other',
|
||||||
i18n,
|
|
||||||
{
|
{
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
inviteeName: renderContact(uuid),
|
inviteeName: renderContact(uuid),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke-invite-from-you--one--unknown',
|
'GroupV2--pending-remove--revoke-invite-from-you--one--unknown',
|
||||||
i18n,
|
|
||||||
{ inviteeName: renderContact(uuid) }
|
{ inviteeName: renderContact(uuid) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (sentByInvited) {
|
if (sentByInvited) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--pending-remove--decline--from-you', i18n);
|
return i18n('GroupV2--pending-remove--decline--from-you');
|
||||||
}
|
}
|
||||||
if (inviter) {
|
if (inviter) {
|
||||||
return renderString('GroupV2--pending-remove--decline--other', i18n, {
|
return i18n('GroupV2--pending-remove--decline--other', {
|
||||||
memberName: renderContact(inviter),
|
memberName: renderContact(inviter),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--pending-remove--decline--unknown', i18n);
|
return i18n('GroupV2--pending-remove--decline--unknown');
|
||||||
}
|
}
|
||||||
if (inviter && sentByInviter) {
|
if (inviter && sentByInviter) {
|
||||||
if (weAreInvited) {
|
if (weAreInvited) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke-own--to-you',
|
'GroupV2--pending-remove--revoke-own--to-you',
|
||||||
i18n,
|
|
||||||
{ inviterName: renderContact(inviter) }
|
{ inviterName: renderContact(inviter) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke-own--unknown',
|
'GroupV2--pending-remove--revoke-own--unknown',
|
||||||
i18n,
|
|
||||||
{ inviterName: renderContact(inviter) }
|
{ inviterName: renderContact(inviter) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (inviter) {
|
if (inviter) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke-invite-from--one--you',
|
'GroupV2--pending-remove--revoke-invite-from--one--you',
|
||||||
i18n,
|
|
||||||
{ memberName: renderContact(inviter) }
|
{ memberName: renderContact(inviter) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke-invite-from--one--other',
|
'GroupV2--pending-remove--revoke-invite-from--one--other',
|
||||||
i18n,
|
|
||||||
{
|
{
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
memberName: renderContact(inviter),
|
memberName: renderContact(inviter),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke-invite-from--one--unknown',
|
'GroupV2--pending-remove--revoke-invite-from--one--unknown',
|
||||||
i18n,
|
|
||||||
{ memberName: renderContact(inviter) }
|
{ memberName: renderContact(inviter) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--pending-remove--revoke--one--you', i18n);
|
return i18n('GroupV2--pending-remove--revoke--one--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--pending-remove--revoke--one--other', i18n, {
|
return i18n('GroupV2--pending-remove--revoke--one--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--pending-remove--revoke--one--unknown', i18n);
|
return i18n('GroupV2--pending-remove--revoke--one--unknown');
|
||||||
}
|
}
|
||||||
if (detail.type === 'pending-remove-many') {
|
if (detail.type === 'pending-remove-many') {
|
||||||
const { count, inviter } = detail;
|
const { count, inviter } = detail;
|
||||||
|
@ -663,33 +644,33 @@ export function renderChangeDetail<T>(
|
||||||
|
|
||||||
if (weAreInviter) {
|
if (weAreInviter) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke-invite-from-you--many--you',
|
'GroupV2--pending-remove--revoke-invite-from-you--many--you',
|
||||||
i18n,
|
|
||||||
{ count: count.toString() }
|
{ count: count.toString() }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke-invite-from-you--many--other',
|
'GroupV2--pending-remove--revoke-invite-from-you--many--other',
|
||||||
i18n,
|
|
||||||
{
|
{
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
count: count.toString(),
|
count: count.toString(),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke-invite-from-you--many--unknown',
|
'GroupV2--pending-remove--revoke-invite-from-you--many--unknown',
|
||||||
i18n,
|
|
||||||
{ count: count.toString() }
|
{ count: count.toString() }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (inviter) {
|
if (inviter) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke-invite-from--many--you',
|
'GroupV2--pending-remove--revoke-invite-from--many--you',
|
||||||
i18n,
|
|
||||||
{
|
{
|
||||||
count: count.toString(),
|
count: count.toString(),
|
||||||
memberName: renderContact(inviter),
|
memberName: renderContact(inviter),
|
||||||
|
@ -697,9 +678,9 @@ export function renderChangeDetail<T>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke-invite-from--many--other',
|
'GroupV2--pending-remove--revoke-invite-from--many--other',
|
||||||
i18n,
|
|
||||||
{
|
{
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
count: count.toString(),
|
count: count.toString(),
|
||||||
|
@ -707,9 +688,9 @@ export function renderChangeDetail<T>(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke-invite-from--many--unknown',
|
'GroupV2--pending-remove--revoke-invite-from--many--unknown',
|
||||||
i18n,
|
|
||||||
{
|
{
|
||||||
count: count.toString(),
|
count: count.toString(),
|
||||||
memberName: renderContact(inviter),
|
memberName: renderContact(inviter),
|
||||||
|
@ -717,23 +698,23 @@ export function renderChangeDetail<T>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--pending-remove--revoke--many--you', i18n, {
|
return i18n('GroupV2--pending-remove--revoke--many--you', {
|
||||||
count: count.toString(),
|
count: count.toString(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke--many--other',
|
'GroupV2--pending-remove--revoke--many--other',
|
||||||
i18n,
|
|
||||||
{
|
{
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
count: count.toString(),
|
count: count.toString(),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--pending-remove--revoke--many--unknown',
|
'GroupV2--pending-remove--revoke--many--unknown',
|
||||||
i18n,
|
|
||||||
{ count: count.toString() }
|
{ count: count.toString() }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -742,9 +723,9 @@ export function renderChangeDetail<T>(
|
||||||
const weAreJoiner = isOurUuid(uuid);
|
const weAreJoiner = isOurUuid(uuid);
|
||||||
|
|
||||||
if (weAreJoiner) {
|
if (weAreJoiner) {
|
||||||
return renderString('GroupV2--admin-approval-add-one--you', i18n);
|
return i18n('GroupV2--admin-approval-add-one--you');
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--admin-approval-add-one--other', i18n, {
|
return i18n('GroupV2--admin-approval-add-one--other', {
|
||||||
joinerName: renderContact(uuid),
|
joinerName: renderContact(uuid),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -754,35 +735,29 @@ export function renderChangeDetail<T>(
|
||||||
|
|
||||||
if (weAreJoiner) {
|
if (weAreJoiner) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString(
|
return i18n('GroupV2--admin-approval-remove-one--you--you');
|
||||||
'GroupV2--admin-approval-remove-one--you--you',
|
|
||||||
i18n
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return renderString(
|
return i18n('GroupV2--admin-approval-remove-one--you--unknown');
|
||||||
'GroupV2--admin-approval-remove-one--you--unknown',
|
|
||||||
i18n
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--admin-approval-remove-one--other--you',
|
'GroupV2--admin-approval-remove-one--other--you',
|
||||||
i18n,
|
|
||||||
{ joinerName: renderContact(uuid) }
|
{ joinerName: renderContact(uuid) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (from && from === uuid) {
|
if (from && from === uuid) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--admin-approval-remove-one--other--own',
|
'GroupV2--admin-approval-remove-one--other--own',
|
||||||
i18n,
|
|
||||||
{ joinerName: renderContact(uuid) }
|
{ joinerName: renderContact(uuid) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--admin-approval-remove-one--other--other',
|
'GroupV2--admin-approval-remove-one--other--other',
|
||||||
i18n,
|
|
||||||
{
|
{
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
joinerName: renderContact(uuid),
|
joinerName: renderContact(uuid),
|
||||||
|
@ -792,9 +767,9 @@ export function renderChangeDetail<T>(
|
||||||
|
|
||||||
// We default to the user canceling their request, because it is far more likely that
|
// We default to the user canceling their request, because it is far more likely that
|
||||||
// if an admin does the denial, we'll get a change event from them.
|
// if an admin does the denial, we'll get a change event from them.
|
||||||
return renderString(
|
return i18n(
|
||||||
'GroupV2--admin-approval-remove-one--other--own',
|
'GroupV2--admin-approval-remove-one--other--own',
|
||||||
i18n,
|
|
||||||
{ joinerName: renderContact(uuid) }
|
{ joinerName: renderContact(uuid) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -803,11 +778,11 @@ export function renderChangeDetail<T>(
|
||||||
|
|
||||||
let firstMessage: T | string;
|
let firstMessage: T | string;
|
||||||
if (times === 1) {
|
if (times === 1) {
|
||||||
firstMessage = renderString('GroupV2--admin-approval-bounce--one', i18n, {
|
firstMessage = i18n('GroupV2--admin-approval-bounce--one', {
|
||||||
joinerName: renderContact(uuid),
|
joinerName: renderContact(uuid),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
firstMessage = renderString('GroupV2--admin-approval-bounce', i18n, {
|
firstMessage = i18n('GroupV2--admin-approval-bounce', {
|
||||||
joinerName: renderContact(uuid),
|
joinerName: renderContact(uuid),
|
||||||
numberOfRequests: String(times),
|
numberOfRequests: String(times),
|
||||||
});
|
});
|
||||||
|
@ -835,99 +810,99 @@ export function renderChangeDetail<T>(
|
||||||
|
|
||||||
if (privilege === AccessControlEnum.ADMINISTRATOR) {
|
if (privilege === AccessControlEnum.ADMINISTRATOR) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--group-link-add--enabled--you', i18n);
|
return i18n('GroupV2--group-link-add--enabled--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--group-link-add--enabled--other', i18n, {
|
return i18n('GroupV2--group-link-add--enabled--other', {
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--group-link-add--enabled--unknown', i18n);
|
return i18n('GroupV2--group-link-add--enabled--unknown');
|
||||||
}
|
}
|
||||||
if (privilege === AccessControlEnum.ANY) {
|
if (privilege === AccessControlEnum.ANY) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--group-link-add--disabled--you', i18n);
|
return i18n('GroupV2--group-link-add--disabled--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--group-link-add--disabled--other', i18n, {
|
return i18n('GroupV2--group-link-add--disabled--other', {
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--group-link-add--disabled--unknown', i18n);
|
return i18n('GroupV2--group-link-add--disabled--unknown');
|
||||||
}
|
}
|
||||||
log.warn(`group-link-add change type, privilege ${privilege} is unknown`);
|
log.warn(`group-link-add change type, privilege ${privilege} is unknown`);
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
if (detail.type === 'group-link-reset') {
|
if (detail.type === 'group-link-reset') {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--group-link-reset--you', i18n);
|
return i18n('GroupV2--group-link-reset--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--group-link-reset--other', i18n, {
|
return i18n('GroupV2--group-link-reset--other', {
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--group-link-reset--unknown', i18n);
|
return i18n('GroupV2--group-link-reset--unknown');
|
||||||
}
|
}
|
||||||
if (detail.type === 'group-link-remove') {
|
if (detail.type === 'group-link-remove') {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--group-link-remove--you', i18n);
|
return i18n('GroupV2--group-link-remove--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--group-link-remove--other', i18n, {
|
return i18n('GroupV2--group-link-remove--other', {
|
||||||
adminName: renderContact(from),
|
adminName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--group-link-remove--unknown', i18n);
|
return i18n('GroupV2--group-link-remove--unknown');
|
||||||
}
|
}
|
||||||
if (detail.type === 'description') {
|
if (detail.type === 'description') {
|
||||||
if (detail.removed) {
|
if (detail.removed) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--description--remove--you', i18n);
|
return i18n('GroupV2--description--remove--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--description--remove--other', i18n, {
|
return i18n('GroupV2--description--remove--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--description--remove--unknown', i18n);
|
return i18n('GroupV2--description--remove--unknown');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--description--change--you', i18n);
|
return i18n('GroupV2--description--change--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--description--change--other', i18n, {
|
return i18n('GroupV2--description--change--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--description--change--unknown', i18n);
|
return i18n('GroupV2--description--change--unknown');
|
||||||
}
|
}
|
||||||
if (detail.type === 'announcements-only') {
|
if (detail.type === 'announcements-only') {
|
||||||
if (detail.announcementsOnly) {
|
if (detail.announcementsOnly) {
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--announcements--admin--you', i18n);
|
return i18n('GroupV2--announcements--admin--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--announcements--admin--other', i18n, {
|
return i18n('GroupV2--announcements--admin--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--announcements--admin--unknown', i18n);
|
return i18n('GroupV2--announcements--admin--unknown');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromYou) {
|
if (fromYou) {
|
||||||
return renderString('GroupV2--announcements--member--you', i18n);
|
return i18n('GroupV2--announcements--member--you');
|
||||||
}
|
}
|
||||||
if (from) {
|
if (from) {
|
||||||
return renderString('GroupV2--announcements--member--other', i18n, {
|
return i18n('GroupV2--announcements--member--other', {
|
||||||
memberName: renderContact(from),
|
memberName: renderContact(from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--announcements--member--unknown', i18n);
|
return i18n('GroupV2--announcements--member--unknown');
|
||||||
}
|
}
|
||||||
if (detail.type === 'summary') {
|
if (detail.type === 'summary') {
|
||||||
return renderString('icu:GroupV2--summary', i18n);
|
return i18n('icu:GroupV2--summary');
|
||||||
}
|
}
|
||||||
|
|
||||||
throw missingCaseError(detail);
|
throw missingCaseError(detail);
|
||||||
|
|
|
@ -511,7 +511,10 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
key: string,
|
key: string,
|
||||||
_i18n: unknown,
|
_i18n: unknown,
|
||||||
components: ReplacementValuesType<string> | undefined
|
components: ReplacementValuesType<string> | undefined
|
||||||
) => window.i18n(key, components),
|
) => {
|
||||||
|
// eslint-disable-next-line local-rules/valid-i18n-keys
|
||||||
|
return window.i18n(key, components);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return { text: changes.map(({ text }) => text).join(' ') };
|
return { text: changes.map(({ text }) => text).join(' ') };
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
import * as sinon from 'sinon';
|
import * as sinon from 'sinon';
|
||||||
import { times } from 'lodash';
|
import { times } from 'lodash';
|
||||||
import { RowType } from '../../../components/ConversationList';
|
import { RowType, _testHeaderText } from '../../../components/ConversationList';
|
||||||
import { ContactCheckboxDisabledReason } from '../../../components/conversationList/ContactCheckbox';
|
import { ContactCheckboxDisabledReason } from '../../../components/conversationList/ContactCheckbox';
|
||||||
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
|
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
|
||||||
|
|
||||||
|
@ -117,10 +117,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => {
|
||||||
selectedContacts: [candidateContacts[1]],
|
selectedContacts: [candidateContacts[1]],
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(_testHeaderText(helper.getRow(0)), 'contactsHeader');
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'contactsHeader',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(1), {
|
assert.deepEqual(helper.getRow(1), {
|
||||||
type: RowType.ContactCheckbox,
|
type: RowType.ContactCheckbox,
|
||||||
contact: candidateContacts[0],
|
contact: candidateContacts[0],
|
||||||
|
@ -167,10 +164,10 @@ describe('LeftPaneChooseGroupMembersHelper', () => {
|
||||||
selectedContacts: [],
|
selectedContacts: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(
|
||||||
type: RowType.Header,
|
_testHeaderText(helper.getRow(0)),
|
||||||
i18nKey: 'findByPhoneNumberHeader',
|
'findByPhoneNumberHeader'
|
||||||
});
|
);
|
||||||
assert.deepEqual(helper.getRow(1), {
|
assert.deepEqual(helper.getRow(1), {
|
||||||
type: RowType.PhoneNumberCheckbox,
|
type: RowType.PhoneNumberCheckbox,
|
||||||
phoneNumber: {
|
phoneNumber: {
|
||||||
|
@ -192,10 +189,10 @@ describe('LeftPaneChooseGroupMembersHelper', () => {
|
||||||
selectedContacts: [],
|
selectedContacts: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(
|
||||||
type: RowType.Header,
|
_testHeaderText(helper.getRow(0)),
|
||||||
i18nKey: 'findByUsernameHeader',
|
'findByUsernameHeader'
|
||||||
});
|
);
|
||||||
assert.deepEqual(helper.getRow(1), {
|
assert.deepEqual(helper.getRow(1), {
|
||||||
type: RowType.UsernameCheckbox,
|
type: RowType.UsernameCheckbox,
|
||||||
username: 'signal',
|
username: 'signal',
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
import * as sinon from 'sinon';
|
import * as sinon from 'sinon';
|
||||||
import { RowType } from '../../../components/ConversationList';
|
import { RowType, _testHeaderText } from '../../../components/ConversationList';
|
||||||
import { FindDirection } from '../../../components/leftPane/LeftPaneHelper';
|
import { FindDirection } from '../../../components/leftPane/LeftPaneHelper';
|
||||||
import {
|
import {
|
||||||
getDefaultConversation,
|
getDefaultConversation,
|
||||||
|
@ -223,10 +223,7 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(helper.getRow(0), {
|
||||||
type: RowType.CreateNewGroup,
|
type: RowType.CreateNewGroup,
|
||||||
});
|
});
|
||||||
assert.deepEqual(helper.getRow(1), {
|
assert.deepEqual(_testHeaderText(helper.getRow(1)), 'contactsHeader');
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'contactsHeader',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(2), {
|
assert.deepEqual(helper.getRow(2), {
|
||||||
type: RowType.Contact,
|
type: RowType.Contact,
|
||||||
contact: composeContacts[0],
|
contact: composeContacts[0],
|
||||||
|
@ -258,11 +255,7 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(helper.getRow(0), {
|
||||||
type: RowType.CreateNewGroup,
|
type: RowType.CreateNewGroup,
|
||||||
});
|
});
|
||||||
|
assert.deepEqual(_testHeaderText(helper.getRow(1)), 'contactsHeader');
|
||||||
assert.deepEqual(helper.getRow(1), {
|
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'contactsHeader',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(2), {
|
assert.deepEqual(helper.getRow(2), {
|
||||||
type: RowType.Contact,
|
type: RowType.Contact,
|
||||||
contact: composeContacts[0],
|
contact: composeContacts[0],
|
||||||
|
@ -271,10 +264,7 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
type: RowType.Contact,
|
type: RowType.Contact,
|
||||||
contact: composeContacts[1],
|
contact: composeContacts[1],
|
||||||
});
|
});
|
||||||
assert.deepEqual(helper.getRow(4), {
|
assert.deepEqual(_testHeaderText(helper.getRow(4)), 'groupsHeader');
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'groupsHeader',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(5), {
|
assert.deepEqual(helper.getRow(5), {
|
||||||
type: RowType.SelectSingleGroup,
|
type: RowType.SelectSingleGroup,
|
||||||
group: composeGroups[0],
|
group: composeGroups[0],
|
||||||
|
@ -333,10 +323,10 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
uuidFetchState: {},
|
uuidFetchState: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(
|
||||||
type: RowType.Header,
|
_testHeaderText(helper.getRow(0)),
|
||||||
i18nKey: 'findByPhoneNumberHeader',
|
'findByPhoneNumberHeader'
|
||||||
});
|
);
|
||||||
assert.deepEqual(helper.getRow(1), {
|
assert.deepEqual(helper.getRow(1), {
|
||||||
type: RowType.StartNewConversation,
|
type: RowType.StartNewConversation,
|
||||||
phoneNumber: {
|
phoneNumber: {
|
||||||
|
@ -363,10 +353,10 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(
|
||||||
type: RowType.Header,
|
_testHeaderText(helper.getRow(0)),
|
||||||
i18nKey: 'findByUsernameHeader',
|
'findByUsernameHeader'
|
||||||
});
|
);
|
||||||
assert.deepEqual(helper.getRow(1), {
|
assert.deepEqual(helper.getRow(1), {
|
||||||
type: RowType.UsernameSearchResult,
|
type: RowType.UsernameSearchResult,
|
||||||
username,
|
username,
|
||||||
|
@ -389,10 +379,7 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
uuidFetchState: {},
|
uuidFetchState: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(_testHeaderText(helper.getRow(0)), 'contactsHeader');
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'contactsHeader',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(1), {
|
assert.deepEqual(helper.getRow(1), {
|
||||||
type: RowType.Contact,
|
type: RowType.Contact,
|
||||||
contact: composeContacts[0],
|
contact: composeContacts[0],
|
||||||
|
@ -401,10 +388,10 @@ describe('LeftPaneComposeHelper', () => {
|
||||||
type: RowType.Contact,
|
type: RowType.Contact,
|
||||||
contact: composeContacts[1],
|
contact: composeContacts[1],
|
||||||
});
|
});
|
||||||
assert.deepEqual(helper.getRow(3), {
|
assert.deepEqual(
|
||||||
type: RowType.Header,
|
_testHeaderText(helper.getRow(3)),
|
||||||
i18nKey: 'findByPhoneNumberHeader',
|
'findByPhoneNumberHeader'
|
||||||
});
|
);
|
||||||
assert.deepEqual(helper.getRow(4), {
|
assert.deepEqual(helper.getRow(4), {
|
||||||
type: RowType.StartNewConversation,
|
type: RowType.StartNewConversation,
|
||||||
phoneNumber: {
|
phoneNumber: {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
import * as sinon from 'sinon';
|
import * as sinon from 'sinon';
|
||||||
import { RowType } from '../../../components/ConversationList';
|
import { RowType, _testHeaderText } from '../../../components/ConversationList';
|
||||||
import { FindDirection } from '../../../components/leftPane/LeftPaneHelper';
|
import { FindDirection } from '../../../components/leftPane/LeftPaneHelper';
|
||||||
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
|
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
|
||||||
|
|
||||||
|
@ -339,10 +339,7 @@ describe('LeftPaneInboxHelper', () => {
|
||||||
pinnedConversations,
|
pinnedConversations,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(_testHeaderText(helper.getRow(0)), 'LeftPane--pinned');
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'LeftPane--pinned',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(1), {
|
assert.deepEqual(helper.getRow(1), {
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
conversation: pinnedConversations[0],
|
conversation: pinnedConversations[0],
|
||||||
|
@ -351,10 +348,7 @@ describe('LeftPaneInboxHelper', () => {
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
conversation: pinnedConversations[1],
|
conversation: pinnedConversations[1],
|
||||||
});
|
});
|
||||||
assert.deepEqual(helper.getRow(3), {
|
assert.deepEqual(_testHeaderText(helper.getRow(3)), 'LeftPane--chats');
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'LeftPane--chats',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(4), {
|
assert.deepEqual(helper.getRow(4), {
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
conversation: conversations[0],
|
conversation: conversations[0],
|
||||||
|
@ -388,10 +382,7 @@ describe('LeftPaneInboxHelper', () => {
|
||||||
archivedConversations: [getDefaultConversation()],
|
archivedConversations: [getDefaultConversation()],
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(_testHeaderText(helper.getRow(0)), 'LeftPane--pinned');
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'LeftPane--pinned',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(1), {
|
assert.deepEqual(helper.getRow(1), {
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
conversation: pinnedConversations[0],
|
conversation: pinnedConversations[0],
|
||||||
|
@ -400,10 +391,7 @@ describe('LeftPaneInboxHelper', () => {
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
conversation: pinnedConversations[1],
|
conversation: pinnedConversations[1],
|
||||||
});
|
});
|
||||||
assert.deepEqual(helper.getRow(3), {
|
assert.deepEqual(_testHeaderText(helper.getRow(3)), 'LeftPane--chats');
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'LeftPane--chats',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(4), {
|
assert.deepEqual(helper.getRow(4), {
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
conversation: conversations[0],
|
conversation: conversations[0],
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
import * as sinon from 'sinon';
|
import * as sinon from 'sinon';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { RowType } from '../../../components/ConversationList';
|
import { RowType, _testHeaderText } from '../../../components/ConversationList';
|
||||||
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
|
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
|
||||||
|
|
||||||
import { LeftPaneSearchHelper } from '../../../components/leftPane/LeftPaneSearchHelper';
|
import { LeftPaneSearchHelper } from '../../../components/leftPane/LeftPaneSearchHelper';
|
||||||
|
@ -192,10 +192,10 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
startSearchCounter: 0,
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(
|
||||||
type: RowType.Header,
|
_testHeaderText(helper.getRow(0)),
|
||||||
i18nKey: 'conversationsHeader',
|
'conversationsHeader'
|
||||||
});
|
);
|
||||||
assert.deepEqual(helper.getRow(1), {
|
assert.deepEqual(helper.getRow(1), {
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
conversation: conversations[0],
|
conversation: conversations[0],
|
||||||
|
@ -204,18 +204,12 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
conversation: conversations[1],
|
conversation: conversations[1],
|
||||||
});
|
});
|
||||||
assert.deepEqual(helper.getRow(3), {
|
assert.deepEqual(_testHeaderText(helper.getRow(3)), 'contactsHeader');
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'contactsHeader',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(4), {
|
assert.deepEqual(helper.getRow(4), {
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
conversation: contacts[0],
|
conversation: contacts[0],
|
||||||
});
|
});
|
||||||
assert.deepEqual(helper.getRow(5), {
|
assert.deepEqual(_testHeaderText(helper.getRow(5)), 'messagesHeader');
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'messagesHeader',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(6), {
|
assert.deepEqual(helper.getRow(6), {
|
||||||
type: RowType.MessageSearchResult,
|
type: RowType.MessageSearchResult,
|
||||||
messageId: messages[0].id,
|
messageId: messages[0].id,
|
||||||
|
@ -244,18 +238,12 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
startSearchCounter: 0,
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(_testHeaderText(helper.getRow(0)), 'contactsHeader');
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'contactsHeader',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(1), {
|
assert.deepEqual(helper.getRow(1), {
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
conversation: contacts[0],
|
conversation: contacts[0],
|
||||||
});
|
});
|
||||||
assert.deepEqual(helper.getRow(2), {
|
assert.deepEqual(_testHeaderText(helper.getRow(2)), 'messagesHeader');
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'messagesHeader',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(3), {
|
assert.deepEqual(helper.getRow(3), {
|
||||||
type: RowType.MessageSearchResult,
|
type: RowType.MessageSearchResult,
|
||||||
messageId: messages[0].id,
|
messageId: messages[0].id,
|
||||||
|
@ -287,10 +275,10 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
startSearchCounter: 0,
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(
|
||||||
type: RowType.Header,
|
_testHeaderText(helper.getRow(0)),
|
||||||
i18nKey: 'conversationsHeader',
|
'conversationsHeader'
|
||||||
});
|
);
|
||||||
assert.deepEqual(helper.getRow(1), {
|
assert.deepEqual(helper.getRow(1), {
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
conversation: conversations[0],
|
conversation: conversations[0],
|
||||||
|
@ -299,10 +287,7 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
conversation: conversations[1],
|
conversation: conversations[1],
|
||||||
});
|
});
|
||||||
assert.deepEqual(helper.getRow(3), {
|
assert.deepEqual(_testHeaderText(helper.getRow(3)), 'messagesHeader');
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'messagesHeader',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(4), {
|
assert.deepEqual(helper.getRow(4), {
|
||||||
type: RowType.MessageSearchResult,
|
type: RowType.MessageSearchResult,
|
||||||
messageId: messages[0].id,
|
messageId: messages[0].id,
|
||||||
|
@ -332,10 +317,7 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
startSearchCounter: 0,
|
startSearchCounter: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(_testHeaderText(helper.getRow(0)), 'conversationsHeader');
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'conversationsHeader',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(1), {
|
assert.deepEqual(helper.getRow(1), {
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
conversation: conversations[0],
|
conversation: conversations[0],
|
||||||
|
@ -344,10 +326,7 @@ describe('LeftPaneSearchHelper', () => {
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
conversation: conversations[1],
|
conversation: conversations[1],
|
||||||
});
|
});
|
||||||
assert.deepEqual(helper.getRow(3), {
|
assert.deepEqual(_testHeaderText(helper.getRow(3)), 'contactsHeader');
|
||||||
type: RowType.Header,
|
|
||||||
i18nKey: 'contactsHeader',
|
|
||||||
});
|
|
||||||
assert.deepEqual(helper.getRow(4), {
|
assert.deepEqual(helper.getRow(4), {
|
||||||
type: RowType.Conversation,
|
type: RowType.Conversation,
|
||||||
conversation: contacts[0],
|
conversation: contacts[0],
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
import * as sinon from 'sinon';
|
import * as sinon from 'sinon';
|
||||||
import { RowType } from '../../../components/ConversationList';
|
import { RowType, _testHeaderText } from '../../../components/ConversationList';
|
||||||
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
|
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
|
||||||
import { DurationInSeconds } from '../../../util/durations';
|
import { DurationInSeconds } from '../../../util/durations';
|
||||||
|
|
||||||
|
@ -92,10 +92,10 @@ describe('LeftPaneSetGroupMetadataHelper', () => {
|
||||||
selectedContacts,
|
selectedContacts,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(helper.getRow(0), {
|
assert.deepEqual(
|
||||||
type: RowType.Header,
|
_testHeaderText(helper.getRow(0)),
|
||||||
i18nKey: 'setGroupMetadata__members-header',
|
'setGroupMetadata__members-header'
|
||||||
});
|
);
|
||||||
assert.deepEqual(helper.getRow(1), {
|
assert.deepEqual(helper.getRow(1), {
|
||||||
type: RowType.Contact,
|
type: RowType.Contact,
|
||||||
contact: selectedContacts[0],
|
contact: selectedContacts[0],
|
||||||
|
|
Loading…
Reference in a new issue