Skip to content
This repository was archived by the owner on Oct 11, 2022. It is now read-only.

Commit b3a8c31

Browse files
authored
Merge pull request #4167 from withspectrum/2.4.56
2.4.56
2 parents 69b2a6c + 42481d2 commit b3a8c31

File tree

18 files changed

+737
-161
lines changed

18 files changed

+737
-161
lines changed

api/models/message.js

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ import {
1515
} from './thread';
1616
import { events } from 'shared/analytics';
1717
import { trackQueue } from 'shared/bull/queues';
18+
import type { DBMessage } from 'shared/types';
1819

1920
export type MessageTypes = 'text' | 'media';
20-
export type Message = Object;
2121

22-
export const getMessage = (messageId: string): Promise<Message> => {
22+
export const getMessage = (messageId: string): Promise<DBMessage> => {
2323
return db
2424
.table('messages')
2525
.get(messageId)
@@ -30,7 +30,7 @@ export const getMessage = (messageId: string): Promise<Message> => {
3030
});
3131
};
3232

33-
export const getManyMessages = (messageIds: string[]): Promise<Message[]> => {
33+
export const getManyMessages = (messageIds: string[]): Promise<DBMessage[]> => {
3434
return db
3535
.table('messages')
3636
.getAll(...messageIds)
@@ -82,14 +82,14 @@ export const getMessages = (
8282
last,
8383
before,
8484
}: { ...BackwardsPaginationOptions, ...ForwardsPaginationOptions }
85-
): Promise<Array<Message>> => {
85+
): Promise<Array<DBMessage>> => {
8686
// $FlowIssue
8787
if (last || before) return getBackwardsMessages(threadId, { last, before });
8888
// $FlowIssue
8989
return getForwardMessages(threadId, { first, after });
9090
};
9191

92-
export const getLastMessage = (threadId: string): Promise<Message> => {
92+
export const getLastMessage = (threadId: string): Promise<DBMessage> => {
9393
return db
9494
.table('messages')
9595
.getAll(threadId, { index: 'threadId' })
@@ -109,7 +109,7 @@ export const getLastMessages = (threadIds: Array<string>): Promise<Object> => {
109109
};
110110

111111
// prettier-ignore
112-
export const getMediaMessagesForThread = (threadId: string): Promise<Array<Message>> => {
112+
export const getMediaMessagesForThread = (threadId: string): Promise<Array<DBMessage>> => {
113113
return db
114114
.table('messages')
115115
.getAll(threadId, { index: 'threadId' })
@@ -119,7 +119,7 @@ export const getMediaMessagesForThread = (threadId: string): Promise<Array<Messa
119119
};
120120

121121
// prettier-ignore
122-
export const storeMessage = (message: Message, userId: string): Promise<Message> => {
122+
export const storeMessage = (message: Object, userId: string): Promise<DBMessage> => {
123123
// Insert a message
124124
return db
125125
.table('messages')
@@ -289,3 +289,56 @@ export const userHasMessagesInThread = (threadId: string, userId: string) => {
289289
.contains(userId)
290290
.run();
291291
};
292+
293+
type EditInput = {
294+
id: string,
295+
content: {
296+
body: string,
297+
},
298+
};
299+
300+
// prettier-ignore
301+
export const editMessage = (message: EditInput, userId: string): Promise<DBMessage> => {
302+
// Insert a message
303+
return db
304+
.table('messages')
305+
.get(message.id)
306+
.update(
307+
{
308+
content: message.content,
309+
modifiedAt: new Date(),
310+
edits: db.branch(
311+
db.row.hasFields('edits'),
312+
db.row('edits').append({
313+
content: db.row('content'),
314+
timestamp: db.row('modifiedAt'),
315+
}),
316+
[{
317+
content: db.row('content'),
318+
timstamp: db.row('timestamp')
319+
}]
320+
),
321+
},
322+
{ returnChanges: 'always' }
323+
)
324+
.run()
325+
.then(result => result.changes[0].new_val || result.changes[0].old_val)
326+
.then(message => {
327+
if (message.threadType === 'directMessageThread') {
328+
trackQueue.add({
329+
userId,
330+
event: events.DIRECT_MESSAGE_EDITED,
331+
context: { messageId: message.id },
332+
});
333+
}
334+
if (message.threadType === 'story') {
335+
trackQueue.add({
336+
userId,
337+
event: events.MESSAGE_EDITED,
338+
context: { messageId: message.id },
339+
});
340+
}
341+
342+
return message;
343+
});
344+
};

api/models/thread.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ export const getViewableThreadsByUser = async (
219219
...publicChannelIds,
220220
...publicCommunityIds,
221221
];
222-
const distinctIds = allIds.filter((x, i, a) => a.indexOf(x) == i);
222+
const distinctIds = allIds.filter((x, i, a) => a.indexOf(x) === i);
223223
let validChannelIds = intersection(distinctIds, publishedChannelIds);
224224
let validCommunityIds = intersection(distinctIds, publishedCommunityIds);
225225

@@ -317,11 +317,11 @@ export const getViewableParticipantThreadsByUser = async (
317317
const participantThreadIds = participantChannelIds.map(c => c.threadId);
318318
const distinctParticipantChannelIds = participantChannelIds
319319
.map(c => c.channelId)
320-
.filter((x, i, a) => a.indexOf(x) == i);
320+
.filter((x, i, a) => a.indexOf(x) === i);
321321

322322
const distinctParticipantCommunityIds = participantCommunityIds
323323
.map(c => c.communityId)
324-
.filter((x, i, a) => a.indexOf(x) == i);
324+
.filter((x, i, a) => a.indexOf(x) === i);
325325

326326
// get a list of all the channels that are public
327327
const publicChannelIds = await db
@@ -344,7 +344,7 @@ export const getViewableParticipantThreadsByUser = async (
344344
...currentUsersCommunityIds,
345345
...publicCommunityIds,
346346
];
347-
const distinctIds = allIds.filter((x, i, a) => a.indexOf(x) == i);
347+
const distinctIds = allIds.filter((x, i, a) => a.indexOf(x) === i);
348348
let validChannelIds = intersection(
349349
distinctIds,
350350
distinctParticipantChannelIds
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// @flow
2+
import type { GraphQLContext } from '../../';
3+
import UserError from '../../utils/UserError';
4+
import {
5+
getMessage,
6+
editMessage,
7+
userHasMessagesInThread,
8+
getMessages,
9+
} from '../../models/message';
10+
import { setThreadLastActive } from '../../models/thread';
11+
import { deleteParticipantInThread } from '../../models/usersThreads';
12+
import { getUserPermissionsInChannel } from '../../models/usersChannels';
13+
import { getUserPermissionsInCommunity } from '../../models/usersCommunities';
14+
import { events } from 'shared/analytics';
15+
import { isAuthedResolver as requireAuth } from '../../utils/permissions';
16+
import { trackQueue } from 'shared/bull/queues';
17+
18+
type Args = {
19+
input: {
20+
id: string,
21+
content: {
22+
body: string,
23+
},
24+
},
25+
};
26+
27+
export default requireAuth(async (_: any, args: Args, ctx: GraphQLContext) => {
28+
const {
29+
input: { id, content },
30+
} = args;
31+
const { user, loaders } = ctx;
32+
33+
const message = await getMessage(id);
34+
35+
if (!message) {
36+
trackQueue.add({
37+
userId: user.id,
38+
event: events.MESSAGE_EDITED_FAILED,
39+
properties: {
40+
reason: 'message not found',
41+
},
42+
});
43+
return new UserError('This message does not exist.');
44+
}
45+
46+
if (content.body === message.content.body) {
47+
return message;
48+
}
49+
50+
const eventFailed =
51+
message.threadType === 'story'
52+
? events.MESSAGE_EDITED_FAILED
53+
: events.DIRECT_MESSAGE_EDITED_FAILED;
54+
55+
if (message.senderId !== user.id) {
56+
trackQueue.add({
57+
userId: user.id,
58+
event: eventFailed,
59+
context: { messageId: id },
60+
properties: {
61+
reason: 'message not sent by user',
62+
},
63+
});
64+
65+
return new UserError('You can only edit your own messages.');
66+
}
67+
68+
return editMessage(args.input, user.id);
69+
});

api/mutations/message/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
// @flow
22
import addMessage from './addMessage';
33
import deleteMessage from './deleteMessage';
4+
import editMessage from './editMessage';
45

56
module.exports = {
67
Mutation: {
78
addMessage,
89
deleteMessage,
10+
editMessage,
911
},
1012
};

api/types/Message.js

Lines changed: 51 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,70 @@
11
// @flow
22
const Message = /* GraphQL */ `
3-
enum MessageTypes {
4-
text
5-
media
6-
draftjs
7-
}
3+
enum MessageTypes {
4+
text
5+
media
6+
draftjs
7+
}
88
9-
enum ThreadTypes {
10-
story
11-
directMessageThread
12-
}
9+
enum ThreadTypes {
10+
story
11+
directMessageThread
12+
}
1313
14-
type MessageContent {
15-
body: String!
16-
}
14+
type MessageContent {
15+
body: String!
16+
}
1717
18-
type ReactionData {
19-
count: Int!
20-
hasReacted: Boolean
21-
}
18+
type ReactionData {
19+
count: Int!
20+
hasReacted: Boolean
21+
}
2222
23-
type Message {
24-
id: ID!
25-
timestamp: Date!
26-
thread: Thread
27-
content: MessageContent!
23+
type Message {
24+
id: ID!
25+
timestamp: Date!
26+
thread: Thread
27+
content: MessageContent!
2828
author: ThreadParticipant! @cost(complexity: 2)
2929
reactions: ReactionData @cost(complexity: 1)
30-
messageType: MessageTypes!
30+
messageType: MessageTypes!
3131
parent: Message
32+
modifiedAt: Date
33+
sender: User! @deprecated(reason: "Use Message.author field instead")
34+
}
3235
33-
sender: User! @deprecated(reason:"Use Message.author field instead")
34-
}
36+
input MessageContentInput {
37+
body: String
38+
}
3539
36-
input MessageContentInput {
37-
body: String
38-
}
39-
40-
input MessageInput {
41-
threadId: ID!
42-
threadType: ThreadTypes!
43-
messageType: MessageTypes!
44-
content: MessageContentInput!
40+
input MessageInput {
41+
threadId: ID!
42+
threadType: ThreadTypes!
43+
messageType: MessageTypes!
44+
content: MessageContentInput!
4545
parentId: String
46-
file: Upload
47-
}
46+
file: Upload
47+
}
4848
49-
extend type Query {
50-
message(id: ID!): Message
51-
getMediaMessagesForThread(threadId: ID!): [Message]
52-
}
49+
extend type Query {
50+
message(id: ID!): Message
51+
getMediaMessagesForThread(threadId: ID!): [Message]
52+
}
5353
54+
input EditMessageInput {
55+
id: ID!
56+
content: MessageContentInput
57+
}
5458
55-
extend type Mutation {
56-
addMessage(message: MessageInput!): Message
57-
deleteMessage(id: ID!): Boolean
58-
}
59+
extend type Mutation {
60+
addMessage(message: MessageInput!): Message
61+
deleteMessage(id: ID!): Boolean
62+
editMessage(input: EditMessageInput!): Message
63+
}
5964
60-
extend type Subscription {
61-
messageAdded(thread: ID!): Message
62-
}
65+
extend type Subscription {
66+
messageAdded(thread: ID!): Message
67+
}
6368
`;
6469

6570
module.exports = Message;

0 commit comments

Comments
 (0)