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

Commit e885cc6

Browse files
committed
Merge branch 'alpha' of github.com:withspectrum/spectrum into 2.8.2
2 parents d998b9b + 067846e commit e885cc6

File tree

40 files changed

+262
-135
lines changed

40 files changed

+262
-135
lines changed

README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ It is difficult to grow, manage and measure the impact of online communities. Co
2222
2323
### Status
2424

25-
Spectrum has been in full-time development since March 2017 and is [part of GitHub since November 2018](https://spectrum.chat/spectrum/general/spectrum-is-joining-github~1d3eb8ee-4c99-46c0-8daf-ca35a96be6ce).
25+
Spectrum has been in full-time development since March 2017 and is [part of GitHub since November 2018](https://spectrum.chat/spectrum/general/spectrum-is-joining-github~1d3eb8ee-4c99-46c0-8daf-ca35a96be6ce). See our current priorities and what we are working on in the [main project board](https://github.com/withspectrum/spectrum/projects/23).
2626

2727
<div align="center">
2828
<img height="50px" src="public/img/cluster-1.svg" />
@@ -51,7 +51,7 @@ Spectrum has been in full-time development since March 2017 and is [part of GitH
5151

5252
## Contributing
5353

54-
**We heartily welcome any and all contributions that match [our product roadmap](https://github.com/withspectrum/spectrum/projects/19) and engineering standards!**
54+
**We heartily welcome any and all contributions that match our engineering standards!**
5555

5656
That being said, this codebase isn't your typical open source project because it's not a library or package with a limited scope—it's our entire product.
5757

@@ -67,7 +67,9 @@ If you found a technical bug on Spectrum or have ideas for features we should im
6767

6868
#### Fixing a bug or implementing a new feature
6969

70-
If you find a bug on Spectrum and open a PR that fixes it we'll review it as soon as possible to ensure it matches our engineering standards. If you want to implement a new feature, open an issue first to discuss what it'd look like and to ensure it fits in [our roadmap](https://github.com/withspectrum/spectrum/projects/19) and plans for the app.
70+
If you find a bug on Spectrum and open a PR that fixes it we'll review it as soon as possible to ensure it matches our engineering standards.
71+
72+
If you want to implement a new feature, open an issue first to discuss what it'd look like and to ensure it fits in our roadmap and plans for the app (see [the main project board](https://github.com/withspectrum/spectrum/projects/23) for planned and currently ongoing work).
7173

7274
If you want to contribute but are unsure to start, we have [a "good first issue" label](https://github.com/withspectrum/spectrum/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) which is applied to newcomer-friendly issues. Take a look at [the full list of good first issues](https://github.com/withspectrum/spectrum/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) and pick something you like! There is also [an "open" channel in the Spectrum community on Spectrum](https://spectrum.chat/spectrum/open) (how meta), if you run into troubles while trying to contribute that is the best place to talk to us.
7375

@@ -162,12 +164,11 @@ Spectrum has four big installation steps:
162164
1. **Install RethinkDB**: See [the RethinkDB documentation](https://rethinkdb.com/docs/install/) for instructions on installing it with your OS.
163165
2. **Install Redis**: See [the Redis documentation](https://redis.io/download) for instructions on installing it with your OS.
164166
3. **Install yarn**: We use [yarn](https://yarnpkg.com) to handle our JavaScript dependencies. (plain `npm` doesn't work due to our monorepo setup) See [the yarn documentation](https://yarnpkg.com/en/docs/install) for instructions on installing it.
167+
4. **Install the dependencies**: Because it's pretty tedious to install the dependencies for each worker individually we've created a script that goes through and runs `yarn install` for every worker for you: (this takes a couple minutes, so dive into the [technical docs](./docs) in the meantime)
165168

166-
Once you have RethinkDB, Redis and yarn installed locally its time to install the JavaScript dependencies. Because it's pretty tedious to install the dependencies for each worker individually we've created a script that goes through and runs `yarn install` for every worker for you: (this takes a couple minutes, so dive into the [technical docs](./docs) in the meantime)
167-
168-
```sh
169-
node shared/install-dependencies.js
170-
```
169+
```sh
170+
node shared/install-dependencies.js
171+
```
171172

172173
You've now finished installing everything! Let's migrate the database and you'll be ready to go :100:
173174

api/mutations/directMessageThread/createDirectMessageThread.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ import type { FileUpload } from 'shared/types';
1717
import { events } from 'shared/analytics';
1818
import { trackQueue } from 'shared/bull/queues';
1919
import { isAuthedResolver as requireAuth } from '../../utils/permissions';
20+
import { messageTypeObj } from 'shared/draft-utils/process-message-content';
21+
import type { MessageType } from 'shared/draft-utils/process-message-content';
2022

2123
export type CreateDirectMessageThreadInput = {
2224
input: {
2325
participants: Array<string>,
2426
message: {
25-
messageType: 'text' | 'media' | 'draftjs',
27+
messageType: MessageType,
2628
threadType: string,
2729
content: {
2830
body: string,
@@ -80,15 +82,18 @@ export default requireAuth(
8082
}
8183

8284
const handleStoreMessage = async message => {
83-
if (message.messageType === 'text' || message.messageType === 'draftjs') {
85+
if (
86+
message.messageType === messageTypeObj.text ||
87+
message.messageType === messageTypeObj.draftjs
88+
) {
8489
// once we have an id we can generate a proper message object
8590
const messageWithThread = {
8691
...message,
8792
threadId,
8893
};
8994

9095
return await storeMessage(messageWithThread, user.id);
91-
} else if (message.messageType === 'media' && message.file) {
96+
} else if (message.messageType === messageTypeObj.media && message.file) {
9297
let url;
9398
try {
9499
url = await uploadImage(message.file, 'threads', threadId);

api/mutations/message/addMessage.js

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@ import {
1919
} from '../../utils/permissions';
2020
import { trackQueue, calculateThreadScoreQueue } from 'shared/bull/queues';
2121
import { validateRawContentState } from '../../utils/validate-draft-js-input';
22+
import processMessageContent, {
23+
messageTypeObj,
24+
} from 'shared/draft-utils/process-message-content';
25+
import type { MessageType } from 'shared/draft-utils/process-message-content';
2226

2327
type Input = {
2428
message: {
2529
threadId: string,
2630
threadType: 'story' | 'directMessageThread',
27-
messageType: 'text' | 'media' | 'draftjs',
31+
messageType: MessageType,
2832
content: {
2933
body: string,
3034
},
@@ -42,20 +46,15 @@ export const addMessage = async (
4246
? events.MESSAGE_SENT_FAILED
4347
: events.DIRECT_MESSAGE_SENT_FAILED;
4448

45-
if (message.messageType === 'text') {
46-
message.content.body = JSON.stringify(
47-
convertToRaw(
48-
stateFromMarkdown(message.content.body, {
49-
parserOptions: {
50-
breaks: true,
51-
},
52-
})
53-
)
49+
if (message.messageType === messageTypeObj.text) {
50+
message.content.body = processMessageContent(
51+
messageTypeObj.text,
52+
message.content.body
5453
);
55-
message.messageType = 'draftjs';
54+
message.messageType = messageTypeObj.draftjs;
5655
}
5756

58-
if (message.messageType === 'draftjs') {
57+
if (message.messageType === messageTypeObj.draftjs) {
5958
let body;
6059
try {
6160
body = JSON.parse(message.content.body);
@@ -107,7 +106,7 @@ export const addMessage = async (
107106

108107
// construct the shape of the object to be stored in the db
109108
let messageForDb = Object.assign({}, message);
110-
if (message.file && message.messageType === 'media') {
109+
if (message.file && message.messageType === messageTypeObj.media) {
111110
const { file } = message;
112111

113112
const fileMetaData = {
@@ -186,7 +185,7 @@ export default requireAuth(async (_: any, args: Input, ctx: GraphQLContext) => {
186185
}
187186
}
188187

189-
if (message.messageType === 'media' && !message.file) {
188+
if (message.messageType === messageTypeObj.media && !message.file) {
190189
trackQueue.add({
191190
userId: user.id,
192191
event: eventFailed,

api/mutations/message/editMessage.js

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// @flow
22
import type { GraphQLContext } from '../../';
3-
import { convertToRaw } from 'draft-js';
43
import { stateFromMarkdown } from 'draft-js-import-markdown';
54
import UserError from '../../utils/UserError';
65
import {
@@ -17,11 +16,15 @@ import { events } from 'shared/analytics';
1716
import { isAuthedResolver as requireAuth } from '../../utils/permissions';
1817
import { trackQueue } from 'shared/bull/queues';
1918
import { validateRawContentState } from '../../utils/validate-draft-js-input';
19+
import processMessageContent, {
20+
messageTypeObj,
21+
} from 'shared/draft-utils/process-message-content';
22+
import type { MessageType } from 'shared/draft-utils/process-message-content';
2023

2124
type Args = {
2225
input: {
2326
id: string,
24-
messageType?: 'draftjs' | 'text' | 'media',
27+
messageType?: MessageType,
2528
content: {
2629
body: string,
2730
},
@@ -49,24 +52,16 @@ export default requireAuth(async (_: any, args: Args, ctx: GraphQLContext) => {
4952
}
5053

5154
let body = content.body;
52-
if (messageType === 'text') {
53-
body = JSON.stringify(
54-
convertToRaw(
55-
stateFromMarkdown(body, {
56-
parserOptions: {
57-
breaks: true,
58-
},
59-
})
60-
)
61-
);
62-
messageType = 'draftjs';
55+
if (messageType === messageTypeObj.text) {
56+
body = processMessageContent(messageTypeObj.text, body);
57+
messageType = messageTypeObj.draftjs;
6358
}
6459
const eventFailed =
6560
message.threadType === 'story'
6661
? events.MESSAGE_EDITED_FAILED
6762
: events.DIRECT_MESSAGE_EDITED_FAILED;
6863

69-
if (messageType === 'draftjs') {
64+
if (messageType === messageTypeObj.draftjs) {
7065
let parsed;
7166
try {
7267
parsed = JSON.parse(body);

api/mutations/thread/publishThread.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -350,15 +350,10 @@ export default requireAuth(
350350
// Post a new message with a link to the new thread to the watercooler thread if one exists
351351
if (community.watercoolerId && !channel.isPrivate) {
352352
const identifier = user.username ? `@${user.username}` : user.name;
353-
const sentence =
354-
Array.isArray(usersPreviousPublishedThreads) &&
355-
usersPreviousPublishedThreads.length === 0
356-
? `their first thread 👋`
357-
: 'a new thread 📝';
358353
await addMessage(
359354
{
360355
content: {
361-
body: `${identifier} just posted ${sentence} https://spectrum.chat/${
356+
body: `${identifier} just posted a new thread 📝 https://spectrum.chat/${
362357
community.slug
363358
}/${channel.slug}/${slugg(dbThread.content.title)}~${dbThread.id}`,
364359
},

api/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
"pre-commit": "^1.2.2",
9393
"prismjs": "^1.15.0",
9494
"query-string": "5.1.1",
95-
"ratelimiter": "^3.2.0",
95+
"ratelimiter": "^3.3.0",
9696
"raven": "^2.6.4",
9797
"react": "^15.4.1",
9898
"react-app-rewire-styled-components": "^3.0.2",

api/queries/directMessageThread/snippet.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import type { GraphQLContext } from '../../';
44
import { canViewDMThread } from '../../utils/permissions';
55
import { toPlainText, toState } from 'shared/draft-utils';
6+
import { messageTypeObj } from 'shared/draft-utils/process-message-content';
67

78
export default async (
89
{ id }: { id: string },
@@ -17,7 +18,7 @@ export default async (
1718
return loaders.directMessageSnippet.load(id).then(message => {
1819
if (!message) return 'No messages yet...';
1920
if (message.messageType === 'media') return '📷 Photo';
20-
return message.messageType === 'draftjs'
21+
return message.messageType === messageTypeObj.draftjs
2122
? toPlainText(toState(JSON.parse(message.content.body)))
2223
: message.content.body;
2324
});

api/yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7823,10 +7823,10 @@ range-parser@~1.2.0:
78237823
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
78247824
integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=
78257825

7826-
ratelimiter@^3.2.0:
7827-
version "3.2.0"
7828-
resolved "https://registry.yarnpkg.com/ratelimiter/-/ratelimiter-3.2.0.tgz#ae74cf9629daae4cc8900ec126ab28d3794070f1"
7829-
integrity sha512-zMc9X4FNmOk3RBxV95lvp13sZRtf43UJJN1FficbYiusBB09zB6gcJtK2X18dKmH+Gq0C7W6qNCHE+UJx0YwVg==
7826+
ratelimiter@^3.3.0:
7827+
version "3.3.0"
7828+
resolved "https://registry.yarnpkg.com/ratelimiter/-/ratelimiter-3.3.0.tgz#bed9882f552e1aff4d7d3281bd1ab380f94cbf74"
7829+
integrity sha512-dDax7d0XosqzOrrQyMYEiu87tHDT6Wqm9LtGlxnQVAQJtEG6bmbvgPZ6E2/g1XrIpikJyec9hrOHKZ+DuVWxgQ==
78307830

78317831
raven@^2.6.4:
78327832
version "2.6.4"

athena/queues/direct-message-notification.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { toPlainText, toState } from 'shared/draft-utils';
2020
import { sendNewDirectMessageEmailQueue } from 'shared/bull/queues';
2121
import type { Job, DirectMessageNotificationJobData } from 'shared/bull/types';
2222
import { signUser, signMessage } from 'shared/imgix';
23+
import { messageTypeObj } from 'shared/draft-utils/process-message-content';
2324

2425
export default async (job: Job<DirectMessageNotificationJobData>) => {
2526
const { message: incomingMessage, userId: currentUserId } = job.data;
@@ -115,7 +116,7 @@ export default async (job: Job<DirectMessageNotificationJobData>) => {
115116
...signedMessage,
116117
content: {
117118
body:
118-
signedMessage.messageType === 'draftjs'
119+
signedMessage.messageType === messageTypeObj.draftjs
119120
? toPlainText(toState(JSON.parse(signedMessage.content.body)))
120121
: signedMessage.content.body,
121122
},

athena/queues/moderationEvents/message.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { toState, toPlainText } from 'shared/draft-utils';
88
import getPerspectiveScore from './perspective';
99
import { _adminSendToxicContentEmailQueue } from 'shared/bull/queues';
1010
import type { Job, AdminToxicMessageJobData } from 'shared/bull/types';
11+
import { messageTypeObj } from 'shared/draft-utils/process-message-content';
1112

1213
export default async (job: Job<AdminToxicMessageJobData>) => {
1314
debug('new job for admin message moderation');
@@ -16,7 +17,7 @@ export default async (job: Job<AdminToxicMessageJobData>) => {
1617
} = job;
1718

1819
const text =
19-
message.messageType === 'draftjs'
20+
message.messageType === messageTypeObj.draftjs
2021
? toPlainText(toState(JSON.parse(message.content.body)))
2122
: message.content.body;
2223

0 commit comments

Comments
 (0)