Fix groupV2 change rendering in notifications and left pane
Co-authored-by: Scott Nonnenberg <scott@signal.org>
This commit is contained in:
parent
b3afc327da
commit
a9bbc18fb7
|
@ -12,6 +12,7 @@ import type { GroupV2ChangeType } from '../../groups';
|
||||||
import { SignalService as Proto } from '../../protobuf';
|
import { SignalService as Proto } from '../../protobuf';
|
||||||
import type { SmartContactRendererType } from '../../groupChange';
|
import type { SmartContactRendererType } from '../../groupChange';
|
||||||
import { GroupV2Change } from './GroupV2Change';
|
import { GroupV2Change } from './GroupV2Change';
|
||||||
|
import type { FullJSXType } from '../Intl';
|
||||||
|
|
||||||
const i18n = setupI18n('en', enMessages);
|
const i18n = setupI18n('en', enMessages);
|
||||||
|
|
||||||
|
@ -25,7 +26,9 @@ const INVITEE_A = UUID.generate().toString();
|
||||||
const AccessControlEnum = Proto.AccessControl.AccessRequired;
|
const AccessControlEnum = Proto.AccessControl.AccessRequired;
|
||||||
const RoleEnum = Proto.Member.Role;
|
const RoleEnum = Proto.Member.Role;
|
||||||
|
|
||||||
const renderContact: SmartContactRendererType = (conversationId: string) => (
|
const renderContact: SmartContactRendererType<FullJSXType> = (
|
||||||
|
conversationId: string
|
||||||
|
) => (
|
||||||
<React.Fragment key={conversationId}>
|
<React.Fragment key={conversationId}>
|
||||||
{`Conversation(${conversationId})`}
|
{`Conversation(${conversationId})`}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
|
|
|
@ -28,7 +28,7 @@ export type PropsDataType = {
|
||||||
|
|
||||||
export type PropsHousekeepingType = {
|
export type PropsHousekeepingType = {
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
renderContact: SmartContactRendererType;
|
renderContact: SmartContactRendererType<FullJSXType>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PropsType = PropsDataType & PropsHousekeepingType;
|
export type PropsType = PropsDataType & PropsHousekeepingType;
|
||||||
|
@ -141,7 +141,7 @@ export function GroupV2Change(props: PropsType): ReactElement {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{renderChange(change, {
|
{renderChange<FullJSXType>(change, {
|
||||||
i18n,
|
i18n,
|
||||||
ourUuid,
|
ourUuid,
|
||||||
renderContact,
|
renderContact,
|
||||||
|
|
|
@ -53,6 +53,7 @@ import { ResetSessionNotification } from './ResetSessionNotification';
|
||||||
import type { PropsType as ProfileChangeNotificationPropsType } from './ProfileChangeNotification';
|
import type { PropsType as ProfileChangeNotificationPropsType } from './ProfileChangeNotification';
|
||||||
import { ProfileChangeNotification } from './ProfileChangeNotification';
|
import { ProfileChangeNotification } from './ProfileChangeNotification';
|
||||||
import * as log from '../../logging/log';
|
import * as log from '../../logging/log';
|
||||||
|
import type { FullJSXType } from '../Intl';
|
||||||
|
|
||||||
type CallHistoryType = {
|
type CallHistoryType = {
|
||||||
type: 'callHistory';
|
type: 'callHistory';
|
||||||
|
@ -144,7 +145,7 @@ type PropsLocalType = {
|
||||||
id: string;
|
id: string;
|
||||||
isSelected: boolean;
|
isSelected: boolean;
|
||||||
selectMessage: (messageId: string, conversationId: string) => unknown;
|
selectMessage: (messageId: string, conversationId: string) => unknown;
|
||||||
renderContact: SmartContactRendererType;
|
renderContact: SmartContactRendererType<FullJSXType>;
|
||||||
renderUniversalTimerNotification: () => JSX.Element;
|
renderUniversalTimerNotification: () => JSX.Element;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
interactionMode: InteractionModeType;
|
interactionMode: InteractionModeType;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import type { FullJSXType } from './components/Intl';
|
|
||||||
import type { LocalizerType } from './types/Util';
|
import type { LocalizerType } from './types/Util';
|
||||||
import type { ReplacementValuesType } from './types/I18N';
|
import type { ReplacementValuesType } from './types/I18N';
|
||||||
import type { UUIDStringType } from './types/UUID';
|
import type { UUIDStringType } from './types/UUID';
|
||||||
|
@ -11,42 +10,42 @@ import type { GroupV2ChangeDetailType, GroupV2ChangeType } from './groups';
|
||||||
import { SignalService as Proto } from './protobuf';
|
import { SignalService as Proto } from './protobuf';
|
||||||
import * as log from './logging/log';
|
import * as log from './logging/log';
|
||||||
|
|
||||||
export type SmartContactRendererType = (uuid: UUIDStringType) => FullJSXType;
|
export type SmartContactRendererType<T> = (uuid: UUIDStringType) => T | string;
|
||||||
export type StringRendererType = (
|
export type StringRendererType<T> = (
|
||||||
id: string,
|
id: string,
|
||||||
i18n: LocalizerType,
|
i18n: LocalizerType,
|
||||||
components?: Array<FullJSXType> | ReplacementValuesType<FullJSXType>
|
components?: Array<T | string> | ReplacementValuesType<T | string>
|
||||||
) => FullJSXType;
|
) => T | string;
|
||||||
|
|
||||||
export type RenderOptionsType = {
|
export type RenderOptionsType<T> = {
|
||||||
from?: UUIDStringType;
|
from?: UUIDStringType;
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
ourUuid: UUIDStringType;
|
ourUuid: UUIDStringType;
|
||||||
renderContact: SmartContactRendererType;
|
renderContact: SmartContactRendererType<T>;
|
||||||
renderString: StringRendererType;
|
renderString: StringRendererType<T>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const AccessControlEnum = Proto.AccessControl.AccessRequired;
|
const AccessControlEnum = Proto.AccessControl.AccessRequired;
|
||||||
const RoleEnum = Proto.Member.Role;
|
const RoleEnum = Proto.Member.Role;
|
||||||
|
|
||||||
export function renderChange(
|
export function renderChange<T>(
|
||||||
change: GroupV2ChangeType,
|
change: GroupV2ChangeType,
|
||||||
options: RenderOptionsType
|
options: RenderOptionsType<T>
|
||||||
): Array<FullJSXType> {
|
): Array<T | string> {
|
||||||
const { details, from } = change;
|
const { details, from } = change;
|
||||||
|
|
||||||
return details.map((detail: GroupV2ChangeDetailType) =>
|
return details.map((detail: GroupV2ChangeDetailType) =>
|
||||||
renderChangeDetail(detail, {
|
renderChangeDetail<T>(detail, {
|
||||||
...options,
|
...options,
|
||||||
from,
|
from,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function renderChangeDetail(
|
export function renderChangeDetail<T>(
|
||||||
detail: GroupV2ChangeDetailType,
|
detail: GroupV2ChangeDetailType,
|
||||||
options: RenderOptionsType
|
options: RenderOptionsType<T>
|
||||||
): FullJSXType {
|
): T | string {
|
||||||
const { from, i18n, ourUuid, renderContact, renderString } = options;
|
const { from, i18n, ourUuid, renderContact, renderString } = options;
|
||||||
const fromYou = Boolean(from && from === ourUuid);
|
const fromYou = Boolean(from && from === ourUuid);
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,7 @@ import {
|
||||||
isCustomError,
|
isCustomError,
|
||||||
isQuoteAMatch,
|
isQuoteAMatch,
|
||||||
} from '../messages/helpers';
|
} from '../messages/helpers';
|
||||||
|
import type { ReplacementValuesType } from '../types/I18N';
|
||||||
|
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
/* eslint-disable more/no-then */
|
/* eslint-disable more/no-then */
|
||||||
|
@ -447,11 +448,14 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
|
|
||||||
if (isGroupV2Change(attributes)) {
|
if (isGroupV2Change(attributes)) {
|
||||||
const change = this.get('groupV2Change');
|
const change = this.get('groupV2Change');
|
||||||
|
strictAssert(
|
||||||
|
change,
|
||||||
|
'getNotificationData: isGroupV2Change true, but no groupV2Change!'
|
||||||
|
);
|
||||||
|
|
||||||
const lines = window.Signal.GroupChange.renderChange(change, {
|
const lines = window.Signal.GroupChange.renderChange<string>(change, {
|
||||||
AccessControlEnum: Proto.AccessControl.AccessRequired,
|
|
||||||
i18n: window.i18n,
|
i18n: window.i18n,
|
||||||
ourConversationId: window.ConversationController.getOurConversationId(),
|
ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(),
|
||||||
renderContact: (conversationId: string) => {
|
renderContact: (conversationId: string) => {
|
||||||
const conversation =
|
const conversation =
|
||||||
window.ConversationController.get(conversationId);
|
window.ConversationController.get(conversationId);
|
||||||
|
@ -462,9 +466,8 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
renderString: (
|
renderString: (
|
||||||
key: string,
|
key: string,
|
||||||
_i18n: unknown,
|
_i18n: unknown,
|
||||||
placeholders: Array<string>
|
components: Array<string> | ReplacementValuesType<string> | undefined
|
||||||
) => window.i18n(key, placeholders),
|
) => window.i18n(key, components),
|
||||||
RoleEnum: Proto.Member.Role,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return { text: lines.join(' ') };
|
return { text: lines.join(' ') };
|
||||||
|
|
|
@ -111,6 +111,8 @@ import { CI } from './CI';
|
||||||
import { IPCEventsType, IPCEventsValuesType } from './util/createIPCEvents';
|
import { IPCEventsType, IPCEventsValuesType } from './util/createIPCEvents';
|
||||||
import { ConversationView } from './views/conversation_view';
|
import { ConversationView } from './views/conversation_view';
|
||||||
import type { SignalContextType } from './windows/context';
|
import type { SignalContextType } from './windows/context';
|
||||||
|
import { GroupV2Change } from './components/conversation/GroupV2Change';
|
||||||
|
import * as GroupChange from './groupChange';
|
||||||
|
|
||||||
export { Long } from 'long';
|
export { Long } from 'long';
|
||||||
|
|
||||||
|
@ -381,9 +383,7 @@ declare global {
|
||||||
QualifiedAddress: typeof QualifiedAddress;
|
QualifiedAddress: typeof QualifiedAddress;
|
||||||
};
|
};
|
||||||
Util: typeof Util;
|
Util: typeof Util;
|
||||||
GroupChange: {
|
GroupChange: typeof GroupChange;
|
||||||
renderChange: (change: unknown, things: unknown) => Array<string>;
|
|
||||||
};
|
|
||||||
Components: {
|
Components: {
|
||||||
AttachmentList: typeof AttachmentList;
|
AttachmentList: typeof AttachmentList;
|
||||||
ChatColorPicker: typeof ChatColorPicker;
|
ChatColorPicker: typeof ChatColorPicker;
|
||||||
|
|
Loading…
Reference in New Issue