Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions src/__tests__/lib/exampleData.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import type {
MessagesState,
RealmState,
} from '../../reduxTypes';
import type { Auth, Account, OutboxBase, StreamOutbox } from '../../types';
import type { Auth, Account, StreamOutbox } from '../../types';
import { UploadedAvatarURL } from '../../utils/avatar';
import { ZulipVersion } from '../../utils/zulipVersion';
import {
Expand Down Expand Up @@ -444,24 +444,18 @@ export const makeMessagesState = (messages: Message[]): MessagesState =>
*/

/**
* Properties in common among PM and stream outbox messages, with no
* interesting data.
* Boring properties common across example outbox messages.
*/
const outboxMessageBase: $Diff<OutboxBase, {| id: mixed, timestamp: mixed |}> = deepFreeze({
const outboxMessageBase = deepFreeze({
isOutbox: true,
isSent: false,
avatar_url: selfUser.avatar_url,
content: '<p>Test.</p>',
display_recipient: stream.name,
// id: ...,
markdownContent: 'Test.',
reactions: [],
sender_email: selfUser.email,
sender_full_name: selfUser.full_name,
sender_id: selfUser.user_id,
subject: 'test topic',
// timestamp: ...,
type: 'stream',
});

/**
Expand All @@ -470,12 +464,16 @@ const outboxMessageBase: $Diff<OutboxBase, {| id: mixed, timestamp: mixed |}> =
*
* `.id` is always identical to `.timestamp` and should not be supplied.
*/
export const streamOutbox = (data: $Shape<$Diff<StreamOutbox, {| id: mixed |}>>): StreamOutbox => {
export const streamOutbox = (data: $Rest<StreamOutbox, { id: mixed, ... }>): StreamOutbox => {
const { timestamp } = data;

const outputTimestamp = timestamp ?? makeTime() / 1000;
return deepFreeze({
...outboxMessageBase,
type: 'stream',
display_recipient: stream.name,
subject: 'test topic',

...data,
id: outputTimestamp,
timestamp: outputTimestamp,
Expand Down
9 changes: 5 additions & 4 deletions src/outbox/outboxActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import type {
GlobalState,
Narrow,
Outbox,
PmOutbox,
StreamOutbox,
UserOrBot,
UserId,
Action,
Expand Down Expand Up @@ -124,10 +126,9 @@ const recipientsFromIds = (ids, allUsersById, ownUser) => {
return result;
};

type DataFromNarrow = SubsetProperties<
Outbox,
{| type: mixed, display_recipient: mixed, subject: mixed |},
>;
type DataFromNarrow =
| SubsetProperties<PmOutbox, {| type: mixed, display_recipient: mixed, subject: mixed |}>
| SubsetProperties<StreamOutbox, {| type: mixed, display_recipient: mixed, subject: mixed |}>;

const extractTypeToAndSubjectFromNarrow = (
narrow: Narrow,
Expand Down
4 changes: 2 additions & 2 deletions src/outbox/outboxReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export default (state: OutboxState = initialState, action: Action): OutboxState
return messageSendStart(state, action);

case MESSAGE_SEND_COMPLETE:
return state.map(item =>
item.id !== action.local_message_id ? item : { ...item, isSent: true },
return state.map(<O: Outbox>(item: O) =>
item.id !== action.local_message_id ? item : { ...(item: O), isSent: true },
);

case DELETE_OUTBOX_MESSAGE:
Expand Down
31 changes: 17 additions & 14 deletions src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,7 @@ export type TopicExtended = {|
* Properties in common among the two different flavors of a
* `Outbox`: `PmOutbox` and `StreamOutbox`.
*/
// TODO: This distinction between `PmOutbox` and `StreamOutbox` doesn't yet
// function as fully as `PmMessage` and `StreamMessage`: for properties
// like `type` and `display_recipient` where the types differ between
// `PmMessage` and `StreamMessage`, it currently loses the information
// that those differences are connected to each other.
export type OutboxBase = $ReadOnly<{|
type OutboxBase = $ReadOnly<{|
/** Used for distinguishing from a `Message` object. */
isOutbox: true,

Expand All @@ -196,28 +191,29 @@ export type OutboxBase = $ReadOnly<{|
// `Message` but potentially separately.
Message,
{|
// TODO: Some of these have different types on `PmMessage` vs.
// `StreamMessage`; move those to `PmOutbox` and `StreamOutbox`
// respectively, to match that distinction here.
avatar_url: mixed,
content: mixed,
display_recipient: mixed,
id: mixed,
reactions: mixed,
sender_id: mixed,
sender_email: mixed,
sender_full_name: mixed,
subject: mixed,
timestamp: mixed,
type: mixed,
|},
>,
|}>;

export type PmOutbox = $ReadOnly<{|
...OutboxBase,

...SubsetProperties<PmMessage, {||}>,
...SubsetProperties<
PmMessage,
{|
type: mixed,
display_recipient: mixed,
subject: mixed,
|},
>,
|}>;

export type StreamOutbox = $ReadOnly<{|
Expand All @@ -230,7 +226,14 @@ export type StreamOutbox = $ReadOnly<{|
// argument passed to `SubsetProperties` of `StreamMessage`, below.
stream_id?: number,

...SubsetProperties<StreamMessage, {||}>,
...SubsetProperties<
StreamMessage,
{|
type: mixed,
display_recipient: mixed,
subject: mixed,
|},
>,
|}>;

/**
Expand Down
9 changes: 2 additions & 7 deletions src/utils/recipient.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* @flow strict-local */
import invariant from 'invariant';
// $FlowFixMe[untyped-import]
import isEqual from 'lodash.isequal';

Expand All @@ -12,9 +11,7 @@ export const streamNameOfStreamMessage = (message: Message | Outbox): string =>
if (message.type !== 'stream') {
throw new Error('streamNameOfStreamMessage: got PM');
}
const { display_recipient: streamName } = message;
invariant(typeof streamName === 'string', 'message type / display_recipient mismatch');
return streamName;
return message.display_recipient;
};

/** The recipients of a PM, in the form found on Message. Throws if a stream message. */
Expand All @@ -24,9 +21,7 @@ export const recipientsOfPrivateMessage = (
if (message.type !== 'private') {
throw new Error('recipientsOfPrivateMessage: got stream message');
}
const { display_recipient: recipients } = message;
invariant(typeof recipients === 'object', 'message type / display_recipient mismatch');
return recipients;
return message.display_recipient;
};

/**
Expand Down