Fix groupV2 change rendering in notifications and left pane

This commit is contained in:
Scott Nonnenberg 2021-12-16 09:44:54 -08:00 committed by GitHub
parent 364f00f37a
commit 29c3b8af89
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 34 additions and 28 deletions

View file

@ -12,6 +12,7 @@ import type { GroupV2ChangeType } from '../../groups';
import { SignalService as Proto } from '../../protobuf';
import type { SmartContactRendererType } from '../../groupChange';
import { GroupV2Change } from './GroupV2Change';
import type { FullJSXType } from '../Intl';
const i18n = setupI18n('en', enMessages);
@ -25,7 +26,9 @@ const INVITEE_A = UUID.generate().toString();
const AccessControlEnum = Proto.AccessControl.AccessRequired;
const RoleEnum = Proto.Member.Role;
const renderContact: SmartContactRendererType = (conversationId: string) => (
const renderContact: SmartContactRendererType<FullJSXType> = (
conversationId: string
) => (
<React.Fragment key={conversationId}>
{`Conversation(${conversationId})`}
</React.Fragment>

View file

@ -28,7 +28,7 @@ export type PropsDataType = {
export type PropsHousekeepingType = {
i18n: LocalizerType;
renderContact: SmartContactRendererType;
renderContact: SmartContactRendererType<FullJSXType>;
};
export type PropsType = PropsDataType & PropsHousekeepingType;
@ -141,7 +141,7 @@ export function GroupV2Change(props: PropsType): ReactElement {
return (
<>
{renderChange(change, {
{renderChange<FullJSXType>(change, {
i18n,
ourUuid,
renderContact,

View file

@ -53,6 +53,7 @@ import { ResetSessionNotification } from './ResetSessionNotification';
import type { PropsType as ProfileChangeNotificationPropsType } from './ProfileChangeNotification';
import { ProfileChangeNotification } from './ProfileChangeNotification';
import * as log from '../../logging/log';
import type { FullJSXType } from '../Intl';
type CallHistoryType = {
type: 'callHistory';
@ -144,7 +145,7 @@ type PropsLocalType = {
id: string;
isSelected: boolean;
selectMessage: (messageId: string, conversationId: string) => unknown;
renderContact: SmartContactRendererType;
renderContact: SmartContactRendererType<FullJSXType>;
renderUniversalTimerNotification: () => JSX.Element;
i18n: LocalizerType;
interactionMode: InteractionModeType;

View file

@ -1,7 +1,6 @@
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { FullJSXType } from './components/Intl';
import type { LocalizerType } from './types/Util';
import type { ReplacementValuesType } from './types/I18N';
import type { UUIDStringType } from './types/UUID';
@ -11,42 +10,42 @@ import type { GroupV2ChangeDetailType, GroupV2ChangeType } from './groups';
import { SignalService as Proto } from './protobuf';
import * as log from './logging/log';
export type SmartContactRendererType = (uuid: UUIDStringType) => FullJSXType;
export type StringRendererType = (
export type SmartContactRendererType<T> = (uuid: UUIDStringType) => T | string;
export type StringRendererType<T> = (
id: string,
i18n: LocalizerType,
components?: Array<FullJSXType> | ReplacementValuesType<FullJSXType>
) => FullJSXType;
components?: Array<T | string> | ReplacementValuesType<T | string>
) => T | string;
export type RenderOptionsType = {
export type RenderOptionsType<T> = {
from?: UUIDStringType;
i18n: LocalizerType;
ourUuid: UUIDStringType;
renderContact: SmartContactRendererType;
renderString: StringRendererType;
renderContact: SmartContactRendererType<T>;
renderString: StringRendererType<T>;
};
const AccessControlEnum = Proto.AccessControl.AccessRequired;
const RoleEnum = Proto.Member.Role;
export function renderChange(
export function renderChange<T>(
change: GroupV2ChangeType,
options: RenderOptionsType
): Array<FullJSXType> {
options: RenderOptionsType<T>
): Array<T | string> {
const { details, from } = change;
return details.map((detail: GroupV2ChangeDetailType) =>
renderChangeDetail(detail, {
renderChangeDetail<T>(detail, {
...options,
from,
})
);
}
export function renderChangeDetail(
export function renderChangeDetail<T>(
detail: GroupV2ChangeDetailType,
options: RenderOptionsType
): FullJSXType {
options: RenderOptionsType<T>
): T | string {
const { from, i18n, ourUuid, renderContact, renderString } = options;
const fromYou = Boolean(from && from === ourUuid);

View file

@ -142,6 +142,7 @@ import {
isCustomError,
isQuoteAMatch,
} from '../messages/helpers';
import type { ReplacementValuesType } from '../types/I18N';
/* eslint-disable camelcase */
/* eslint-disable more/no-then */
@ -447,11 +448,14 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
if (isGroupV2Change(attributes)) {
const change = this.get('groupV2Change');
strictAssert(
change,
'getNotificationData: isGroupV2Change true, but no groupV2Change!'
);
const lines = window.Signal.GroupChange.renderChange(change, {
AccessControlEnum: Proto.AccessControl.AccessRequired,
const lines = window.Signal.GroupChange.renderChange<string>(change, {
i18n: window.i18n,
ourConversationId: window.ConversationController.getOurConversationId(),
ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(),
renderContact: (conversationId: string) => {
const conversation =
window.ConversationController.get(conversationId);
@ -462,9 +466,8 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
renderString: (
key: string,
_i18n: unknown,
placeholders: Array<string>
) => window.i18n(key, placeholders),
RoleEnum: Proto.Member.Role,
components: Array<string> | ReplacementValuesType<string> | undefined
) => window.i18n(key, components),
});
return { text: lines.join(' ') };

6
ts/window.d.ts vendored
View file

@ -111,6 +111,8 @@ import { CI } from './CI';
import { IPCEventsType, IPCEventsValuesType } from './util/createIPCEvents';
import { ConversationView } from './views/conversation_view';
import type { SignalContextType } from './windows/context';
import { GroupV2Change } from './components/conversation/GroupV2Change';
import * as GroupChange from './groupChange';
export { Long } from 'long';
@ -408,9 +410,7 @@ declare global {
QualifiedAddress: typeof QualifiedAddress;
};
Util: typeof Util;
GroupChange: {
renderChange: (change: unknown, things: unknown) => Array<string>;
};
GroupChange: typeof GroupChange;
Components: {
AttachmentList: typeof AttachmentList;
ChatColorPicker: typeof ChatColorPicker;