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

Commit 4738f61

Browse files
authored
Merge pull request #4472 from withspectrum/plaintext-spike
Plaintext markdown chatinput
2 parents 77a6eca + 7888aaf commit 4738f61

File tree

24 files changed

+643
-1015
lines changed

24 files changed

+643
-1015
lines changed

api/mutations/message/addMessage.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// @flow
2-
import { markdownToDraft } from 'markdown-draft-js';
2+
import { stateFromMarkdown } from 'draft-js-import-markdown';
3+
import { convertToRaw } from 'draft-js';
34
import type { GraphQLContext } from '../../';
45
import UserError from '../../utils/UserError';
56
import { uploadImage } from '../../utils/file-storage';
@@ -87,7 +88,13 @@ export default requireAuth(async (_: any, args: Input, ctx: GraphQLContext) => {
8788

8889
if (message.messageType === 'text') {
8990
message.content.body = JSON.stringify(
90-
markdownToDraft(message.content.body)
91+
convertToRaw(
92+
stateFromMarkdown(message.content.body, {
93+
parserOptions: {
94+
breaks: true,
95+
},
96+
})
97+
)
9198
);
9299
message.messageType = 'draftjs';
93100
}

api/mutations/message/editMessage.js

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// @flow
22
import type { GraphQLContext } from '../../';
3+
import { convertToRaw } from 'draft-js';
4+
import { stateFromMarkdown } from 'draft-js-import-markdown';
35
import UserError from '../../utils/UserError';
46
import {
57
getMessage,
@@ -18,6 +20,7 @@ import { trackQueue } from 'shared/bull/queues';
1820
type Args = {
1921
input: {
2022
id: string,
23+
messageType?: 'draftjs' | 'text' | 'media',
2124
content: {
2225
body: string,
2326
},
@@ -26,7 +29,7 @@ type Args = {
2629

2730
export default requireAuth(async (_: any, args: Args, ctx: GraphQLContext) => {
2831
const {
29-
input: { id, content },
32+
input: { id, content, messageType },
3033
} = args;
3134
const { user, loaders } = ctx;
3235

@@ -43,15 +46,85 @@ export default requireAuth(async (_: any, args: Args, ctx: GraphQLContext) => {
4346
return new UserError('This message does not exist.');
4447
}
4548

46-
if (content.body === message.content.body) {
47-
return message;
49+
let body = content.body;
50+
if (messageType === 'text') {
51+
body = JSON.stringify(
52+
convertToRaw(
53+
stateFromMarkdown(body, {
54+
parserOptions: {
55+
breaks: true,
56+
},
57+
})
58+
)
59+
);
60+
messageType === 'draftjs';
4861
}
4962

5063
const eventFailed =
5164
message.threadType === 'story'
5265
? events.MESSAGE_EDITED_FAILED
5366
: events.DIRECT_MESSAGE_EDITED_FAILED;
5467

68+
if (messageType === 'draftjs') {
69+
let parsed;
70+
try {
71+
parsed = JSON.parse(body);
72+
} catch (err) {
73+
trackQueue.add({
74+
userId: user.id,
75+
event: eventFailed,
76+
properties: {
77+
reason: 'invalid draftjs data',
78+
message,
79+
},
80+
});
81+
82+
return new UserError(
83+
'Please provide serialized raw DraftJS content state as content.body'
84+
);
85+
}
86+
if (!parsed.blocks || !Array.isArray(parsed.blocks) || !parsed.entityMap) {
87+
trackQueue.add({
88+
userId: user.id,
89+
event: eventFailed,
90+
properties: {
91+
reason: 'invalid draftjs data',
92+
message,
93+
},
94+
});
95+
96+
return new UserError(
97+
'Please provide serialized raw DraftJS content state as content.body'
98+
);
99+
}
100+
if (
101+
parsed.blocks.some(
102+
({ type }) =>
103+
!type ||
104+
(type !== 'unstyled' &&
105+
type !== 'code-block' &&
106+
type !== 'blockquote')
107+
)
108+
) {
109+
trackQueue.add({
110+
userId: user.id,
111+
event: eventFailed,
112+
properties: {
113+
reason: 'invalid draftjs data',
114+
message,
115+
},
116+
});
117+
118+
return new UserError(
119+
'Invalid DraftJS block type specified. Supported block types: "unstyled", "code-block".'
120+
);
121+
}
122+
}
123+
124+
if (body === message.content.body) {
125+
return message;
126+
}
127+
55128
if (message.senderId !== user.id) {
56129
trackQueue.add({
57130
userId: user.id,
@@ -65,5 +138,14 @@ export default requireAuth(async (_: any, args: Args, ctx: GraphQLContext) => {
65138
return new UserError('You can only edit your own messages.');
66139
}
67140

68-
return editMessage(args.input, user.id);
141+
return editMessage(
142+
{
143+
...args.input,
144+
content: {
145+
body,
146+
},
147+
messageType,
148+
},
149+
user.id
150+
);
69151
});

api/mutations/thread/publishThread.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// @flow
22
const debug = require('debug')('api:mutations:thread:publish-thread');
33
import stringSimilarity from 'string-similarity';
4-
import { markdownToDraft } from 'markdown-draft-js';
4+
import { stateFromMarkdown } from 'draft-js-import-markdown';
55
import type { GraphQLContext } from '../../';
66
import UserError from '../../utils/UserError';
77
import { uploadImage } from '../../utils/file-storage';
@@ -71,7 +71,11 @@ export default requireAuth(
7171
type = 'DRAFTJS';
7272
if (thread.content.body) {
7373
thread.content.body = JSON.stringify(
74-
markdownToDraft(thread.content.body)
74+
stateFromMarkdown(thread.content.body, {
75+
parserOptions: {
76+
breaks: true,
77+
},
78+
})
7579
);
7680
}
7781
}

api/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"draft-js-embed-plugin": "^1.2.0",
3636
"draft-js-focus-plugin": "2.0.0-rc2",
3737
"draft-js-image-plugin": "2.0.0-rc8",
38+
"draft-js-import-markdown": "^1.2.3",
3839
"draft-js-linkify-plugin": "^2.0.0-beta1",
3940
"draft-js-markdown-plugin": "^1.4.4",
4041
"draft-js-plugins-editor": "^2.1.1",
@@ -76,7 +77,6 @@
7677
"lodash": "^4.17.11",
7778
"lodash.intersection": "^4.4.0",
7879
"longjohn": "^0.2.12",
79-
"markdown-draft-js": "^0.6.3",
8080
"moment": "^2.23.0",
8181
"node-env-file": "^0.1.8",
8282
"node-localstorage": "^1.3.1",

api/types/Message.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ const Message = /* GraphQL */ `
5353
5454
input EditMessageInput {
5555
id: ID!
56+
messageType: MessageTypes!
5657
content: MessageContentInput
5758
}
5859

api/yarn.lock

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3495,6 +3495,22 @@ [email protected]:
34953495
prop-types "^15.5.8"
34963496
union-class-names "^1.0.0"
34973497

3498+
draft-js-import-element@^1.2.1:
3499+
version "1.2.1"
3500+
resolved "https://registry.yarnpkg.com/draft-js-import-element/-/draft-js-import-element-1.2.1.tgz#9a6a56d74690d48d35d8d089564e6d710b4926eb"
3501+
integrity sha512-T/eCDkaU8wrTCH6c+/2BE7Vx/11GABRNU/UBiHM4D903LNFar8UfjElehpiKVf+F4rxi8dfhvTgaWrpWDfX4MA==
3502+
dependencies:
3503+
draft-js-utils "^1.2.0"
3504+
synthetic-dom "^1.2.0"
3505+
3506+
draft-js-import-markdown@^1.2.3:
3507+
version "1.2.3"
3508+
resolved "https://registry.yarnpkg.com/draft-js-import-markdown/-/draft-js-import-markdown-1.2.3.tgz#71ffc8eee1530f0349c22273681fbcb3c659c0c0"
3509+
integrity sha512-NPcXwWSsIA+uwASzdJWLQM4y+xW1vTDtDdIDHCHfP76i9cx8zYpH75GW8Ezz8L9SW2qetNcFW056Hj2yxRZ+2g==
3510+
dependencies:
3511+
draft-js-import-element "^1.2.1"
3512+
synthetic-dom "^1.2.0"
3513+
34983514
draft-js-linkify-plugin@^2.0.0-beta1:
34993515
version "2.0.1"
35003516
resolved "https://registry.yarnpkg.com/draft-js-linkify-plugin/-/draft-js-linkify-plugin-2.0.1.tgz#28978b53640ce64c639cd2821a54c24de9f79c3f"
@@ -3570,6 +3586,11 @@ draft-js-prism@ngs/draft-js-prism#6edb31c3805dd1de3fb897cc27fced6bac1bafbb:
35703586
immutable "*"
35713587
prismjs "^1.5.0"
35723588

3589+
draft-js-utils@^1.2.0:
3590+
version "1.2.0"
3591+
resolved "https://registry.yarnpkg.com/draft-js-utils/-/draft-js-utils-1.2.0.tgz#f5cb23eb167325ffed3d79882fdc317721d2fd12"
3592+
integrity sha1-9csj6xZzJf/tPXmIL9wxdyHS/RI=
3593+
35733594
[email protected], draft-js@^0.10.4, draft-js@^0.10.5, draft-js@~0.10.0:
35743595
version "0.10.5"
35753596
resolved "https://registry.yarnpkg.com/draft-js/-/draft-js-0.10.5.tgz#bfa9beb018fe0533dbb08d6675c371a6b08fa742"
@@ -6376,13 +6397,6 @@ map-visit@^1.0.0:
63766397
dependencies:
63776398
object-visit "^1.0.0"
63786399

6379-
markdown-draft-js@^0.6.3:
6380-
version "0.6.3"
6381-
resolved "https://registry.yarnpkg.com/markdown-draft-js/-/markdown-draft-js-0.6.3.tgz#5847cd3d07d7b7e3d4d87c5d7e5928c3a71bddd4"
6382-
integrity sha512-8kn53iDi9M+0jOeF5dXc2vy8tCkrcD/QlltOz9GErenWrJD+VJ5ZFRjjmPVk7TnE8f5R0DiGCDL/w8M2Lj7xQw==
6383-
dependencies:
6384-
remarkable "1.7.1"
6385-
63866400
math-random@^1.0.1:
63876401
version "1.0.1"
63886402
resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac"
@@ -8137,7 +8151,7 @@ regjsparser@^0.6.0:
81378151
dependencies:
81388152
jsesc "~0.5.0"
81398153

8140-
remarkable@1.7.1, remarkable@^1.x:
8154+
remarkable@^1.x:
81418155
version "1.7.1"
81428156
resolved "https://registry.yarnpkg.com/remarkable/-/remarkable-1.7.1.tgz#aaca4972100b66a642a63a1021ca4bac1be3bff6"
81438157
integrity sha1-qspJchALZqZCpjoQIcpLrBvjv/Y=
@@ -9024,6 +9038,11 @@ symbol-tree@^3.2.1:
90249038
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
90259039
integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=
90269040

9041+
synthetic-dom@^1.2.0:
9042+
version "1.2.0"
9043+
resolved "https://registry.yarnpkg.com/synthetic-dom/-/synthetic-dom-1.2.0.tgz#f3589aafe2b5e299f337bb32973a9be42dd5625e"
9044+
integrity sha1-81iar+K14pnzN7sylzqb5C3VYl4=
9045+
90279046
table@^4.0.2:
90289047
version "4.0.3"
90299048
resolved "https://registry.yarnpkg.com/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc"

cypress/integration/messages_spec.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ describe('/messages/new', () => {
1212

1313
it('should allow to continue composing message incase of crash or reload', () => {
1414
const newMessage = 'Persist New Message';
15-
cy.get('[contenteditable="true"]').type(newMessage);
16-
cy.get('[contenteditable="true"]').contains(newMessage);
15+
cy.get('[data-cy="chat-input"]').type(newMessage);
16+
cy.get('[data-cy="chat-input"]').contains(newMessage);
1717

1818
cy.wait(2000);
1919
// Reload page(incase page closed or crashed ,reload should have same effect)
2020
cy.reload();
21-
cy.get('[contenteditable="true"]').contains(newMessage);
21+
cy.get('[data-cy="chat-input"]').contains(newMessage);
2222
});
2323
});
2424

@@ -86,9 +86,9 @@ describe('/messages', () => {
8686
.click();
8787

8888
const newMessage = 'A new message!';
89-
cy.get('[contenteditable="true"]').type(newMessage);
89+
cy.get('[data-cy="chat-input"]').type(newMessage);
9090
cy.get('[data-cy="chat-input-send-button"]').click();
91-
cy.get('[contenteditable="true"]').type('');
91+
cy.get('[data-cy="chat-input"]').clear();
9292
cy.contains(newMessage);
9393

9494
cy.get('[data-cy="unread-dm-list-item"]').should($p => {

cypress/integration/thread/chat_input_spec.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,25 +73,25 @@ describe('chat input', () => {
7373
it('should allow authed members to send messages', () => {
7474
const newMessage = 'A new message!';
7575
cy.get('[data-cy="thread-view"]').should('be.visible');
76-
cy.get('[contenteditable="true"]').type(newMessage);
76+
cy.get('[data-cy="chat-input"]').type(newMessage);
7777
// Wait for the messages to be loaded before sending new message
7878
cy.get('[data-cy="message-group"]').should('be.visible');
7979
cy.get('[data-cy="chat-input-send-button"]').click();
8080
// Clear the chat input and make sure the message was sent by matching the text
81-
cy.get('[contenteditable="true"]').type('');
81+
cy.get('[data-cy="chat-input"]').clear();
8282
cy.contains(newMessage);
8383
});
8484

8585
it('should allow chat input to be maintained', () => {
8686
const newMessage = 'Persist New Message';
8787
cy.get('[data-cy="thread-view"]').should('be.visible');
88-
cy.get('[contenteditable="true"]').type(newMessage);
89-
cy.get('[contenteditable="true"]').contains(newMessage);
88+
cy.get('[data-cy="chat-input"]').type(newMessage);
89+
cy.get('[data-cy="chat-input"]').contains(newMessage);
9090
cy.get('[data-cy="message-group"]').should('be.visible');
9191
cy.wait(1000);
9292
// Reload page(incase page closed or crashed ,reload should have same effect)
9393
cy.reload();
94-
cy.get('[contenteditable="true"]').contains(newMessage);
94+
cy.get('[data-cy="chat-input"]').contains(newMessage);
9595
});
9696
});
9797

cypress/integration/thread_spec.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,12 @@ describe('Thread View', () => {
6969
it('should allow logged-in users to send public messages', () => {
7070
const newMessage = 'A new message!';
7171
cy.get('[data-cy="thread-view"]').should('be.visible');
72-
cy.get('[contenteditable="true"]').type(newMessage);
72+
cy.get('[data-cy="chat-input"]').type(newMessage);
7373
// Wait for the messages to be loaded before sending new message
7474
cy.get('[data-cy="message-group"]').should('be.visible');
7575
cy.get('[data-cy="chat-input-send-button"]').click();
7676
// Clear the chat input and make sure the message was sent by matching the text
77-
cy.get('[contenteditable="true"]').type('');
77+
cy.get('[data-cy="chat-input"]').clear();
7878
cy.contains(newMessage);
7979
});
8080
});
@@ -101,10 +101,10 @@ describe('Thread View', () => {
101101
it('should allow logged-in users to send private messages if they have permission', () => {
102102
const newMessage = 'A new private message!';
103103
cy.get('[data-cy="thread-view"]').should('be.visible');
104-
cy.get('[contenteditable="true"]').type(newMessage);
104+
cy.get('[data-cy="chat-input"]').type(newMessage);
105105
cy.get('[data-cy="chat-input-send-button"]').click();
106106
// Clear the chat input and make sure the message was sent by matching the text
107-
cy.get('[contenteditable="true"]').type('');
107+
cy.get('[data-cy="chat-input"]').clear();
108108
cy.contains(newMessage);
109109
});
110110
});
@@ -430,7 +430,7 @@ describe('edit message signed in', () => {
430430
.click({ force: true });
431431

432432
cy.get('[data-cy="edit-message-input"]');
433-
cy.get('[contenteditable="true"]').type(' with edits');
433+
cy.get('[data-cy="editing-chat-input"]').type(' with edits');
434434

435435
cy.get('[data-cy="edit-message-save"]').click();
436436

@@ -443,7 +443,7 @@ describe('edit message signed in', () => {
443443
});
444444
});
445445

446-
describe.only('/new/thread', () => {
446+
describe('/new/thread', () => {
447447
beforeEach(() => {
448448
cy.auth(author.id).then(() => cy.visit('/new/thread'));
449449
});

0 commit comments

Comments
 (0)