decidim-comments 0.23.2 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/decidim/comments/bundle.js.map +1 -1
  3. data/app/assets/javascripts/decidim/comments/comments.component.js.es6 +292 -0
  4. data/app/assets/javascripts/decidim/comments/comments.component.test.js +581 -0
  5. data/app/assets/javascripts/decidim/comments/comments.js.erb +1 -1
  6. data/app/cells/decidim/comments/comment/actions.erb +7 -0
  7. data/app/cells/decidim/comments/comment/alignment_badge.erb +4 -0
  8. data/app/cells/decidim/comments/comment/author.erb +1 -0
  9. data/app/cells/decidim/comments/comment/show.erb +40 -0
  10. data/app/cells/decidim/comments/comment/utilities.erb +13 -0
  11. data/app/cells/decidim/comments/comment/votes.erb +25 -0
  12. data/app/cells/decidim/comments/comment_card_cell.rb +22 -0
  13. data/app/cells/decidim/comments/comment_cell.rb +142 -8
  14. data/app/cells/decidim/comments/comment_form/comment_as.erb +10 -0
  15. data/app/cells/decidim/comments/comment_form/show.erb +24 -0
  16. data/app/cells/decidim/comments/comment_form_cell.rb +94 -0
  17. data/app/cells/decidim/comments/comment_m/top.erb +1 -1
  18. data/app/cells/decidim/comments/comment_thread/show.erb +6 -0
  19. data/app/cells/decidim/comments/comment_thread/title.erb +3 -0
  20. data/app/cells/decidim/comments/comment_thread_cell.rb +30 -0
  21. data/app/cells/decidim/comments/comments/add_comment.erb +30 -0
  22. data/app/cells/decidim/comments/comments/blocked_comments_warning.erb +3 -0
  23. data/app/cells/decidim/comments/comments/order_control.erb +37 -0
  24. data/app/cells/decidim/comments/comments/show.erb +32 -0
  25. data/app/cells/decidim/comments/comments/single_comment_warning.erb +9 -0
  26. data/app/cells/decidim/comments/comments/user_comments_blocked_warning.erb +3 -0
  27. data/app/cells/decidim/comments/comments_cell.rb +134 -0
  28. data/app/commands/decidim/comments/vote_comment.rb +34 -10
  29. data/app/controllers/decidim/comments/application_controller.rb +16 -0
  30. data/app/controllers/decidim/comments/comments_controller.rb +122 -0
  31. data/app/controllers/decidim/comments/votes_controller.rb +41 -0
  32. data/app/events/decidim/comments/comment_created_event.rb +1 -1
  33. data/app/events/decidim/comments/comment_downvoted_event.rb +8 -0
  34. data/app/events/decidim/comments/comment_upvoted_event.rb +8 -0
  35. data/app/events/decidim/comments/comment_voted_event.rb +26 -0
  36. data/app/forms/decidim/comments/comment_form.rb +6 -2
  37. data/app/models/decidim/comments/comment.rb +22 -6
  38. data/app/models/decidim/comments/seed.rb +1 -1
  39. data/app/permissions/decidim/comments/permissions.rb +59 -0
  40. data/app/queries/decidim/comments/metrics/comment_participants_metric_measure.rb +2 -2
  41. data/app/queries/decidim/comments/metrics/comments_metric_manage.rb +5 -6
  42. data/app/queries/decidim/comments/sorted_comments.rb +18 -14
  43. data/app/views/decidim/comments/comments/_comment.html.erb +5 -0
  44. data/app/views/decidim/comments/comments/_comments.html.erb +1 -0
  45. data/app/views/decidim/comments/comments/create.js.erb +16 -0
  46. data/app/views/decidim/comments/comments/error.js.erb +1 -0
  47. data/app/views/decidim/comments/comments/index.js.erb +24 -0
  48. data/app/views/decidim/comments/comments/reload.js.erb +21 -0
  49. data/app/views/decidim/comments/votes/create.js.erb +23 -0
  50. data/app/views/decidim/comments/votes/error.js.erb +1 -0
  51. data/config/locales/ar.yml +0 -2
  52. data/config/locales/ca.yml +17 -2
  53. data/config/locales/cs.yml +19 -2
  54. data/config/locales/de.yml +17 -2
  55. data/config/locales/el.yml +0 -2
  56. data/config/locales/en.yml +17 -2
  57. data/config/locales/es-MX.yml +17 -2
  58. data/config/locales/es-PY.yml +17 -2
  59. data/config/locales/es.yml +17 -2
  60. data/config/locales/eu.yml +0 -2
  61. data/config/locales/fi-plain.yml +17 -2
  62. data/config/locales/fi.yml +17 -2
  63. data/config/locales/fr-CA.yml +17 -2
  64. data/config/locales/fr.yml +17 -2
  65. data/config/locales/gl.yml +7 -2
  66. data/config/locales/hu.yml +0 -2
  67. data/config/locales/id-ID.yml +0 -2
  68. data/config/locales/is-IS.yml +0 -1
  69. data/config/locales/it.yml +4 -2
  70. data/config/locales/ja.yml +9 -5
  71. data/config/locales/lv.yml +0 -2
  72. data/config/locales/nl.yml +0 -2
  73. data/config/locales/no.yml +0 -2
  74. data/config/locales/pl.yml +21 -4
  75. data/config/locales/pt-BR.yml +0 -2
  76. data/config/locales/pt.yml +0 -2
  77. data/config/locales/ro-RO.yml +15 -2
  78. data/config/locales/ru.yml +0 -2
  79. data/config/locales/sk.yml +0 -2
  80. data/config/locales/sv.yml +7 -2
  81. data/config/locales/tr-TR.yml +7 -2
  82. data/config/locales/uk.yml +0 -1
  83. data/config/locales/zh-CN.yml +0 -2
  84. data/lib/decidim/api/add_comment_type.rb +13 -0
  85. data/lib/decidim/api/comment_mutation_type.rb +22 -0
  86. data/lib/decidim/api/comment_type.rb +89 -0
  87. data/lib/decidim/api/commentable_interface.rb +50 -0
  88. data/lib/decidim/api/commentable_mutation_type.rb +30 -0
  89. data/{app/types/decidim/comments → lib/decidim/api}/commentable_type.rb +2 -5
  90. data/lib/decidim/comments.rb +1 -3
  91. data/lib/decidim/comments/api.rb +12 -0
  92. data/lib/decidim/comments/comments_helper.rb +10 -52
  93. data/lib/decidim/comments/engine.rb +9 -7
  94. data/lib/decidim/comments/mutation_extensions.rb +22 -22
  95. data/lib/decidim/comments/query_extensions.rb +12 -14
  96. data/lib/decidim/comments/test.rb +1 -0
  97. data/lib/decidim/comments/test/shared_examples/comment_voted_event.rb +65 -0
  98. data/lib/decidim/comments/version.rb +1 -1
  99. metadata +65 -64
  100. data/app/assets/javascripts/decidim/comments/bundle.js +0 -268
  101. data/app/frontend/application/apollo_client.ts +0 -12
  102. data/app/frontend/application/application.component.test.tsx +0 -23
  103. data/app/frontend/application/application.component.tsx +0 -35
  104. data/app/frontend/application/icon.component.test.tsx +0 -38
  105. data/app/frontend/application/icon.component.tsx +0 -46
  106. data/app/frontend/comments/add_comment_form.component.test.tsx +0 -265
  107. data/app/frontend/comments/add_comment_form.component.tsx +0 -482
  108. data/app/frontend/comments/comment.component.test.tsx +0 -490
  109. data/app/frontend/comments/comment.component.tsx +0 -677
  110. data/app/frontend/comments/comment_order_selector.component.test.tsx +0 -29
  111. data/app/frontend/comments/comment_order_selector.component.tsx +0 -106
  112. data/app/frontend/comments/comment_thread.component.test.tsx +0 -82
  113. data/app/frontend/comments/comment_thread.component.tsx +0 -81
  114. data/app/frontend/comments/comments.component.test.tsx +0 -150
  115. data/app/frontend/comments/comments.component.tsx +0 -289
  116. data/app/frontend/comments/down_vote_button.component.test.tsx +0 -59
  117. data/app/frontend/comments/down_vote_button.component.tsx +0 -133
  118. data/app/frontend/comments/up_vote_button.component.test.tsx +0 -59
  119. data/app/frontend/comments/up_vote_button.component.tsx +0 -133
  120. data/app/frontend/comments/vote_button.component.tsx +0 -50
  121. data/app/frontend/comments/vote_button_component.test.tsx +0 -64
  122. data/app/frontend/entry.ts +0 -38
  123. data/app/frontend/entry_test.ts +0 -6
  124. data/app/frontend/fragments/add_comment_form_commentable.fragment.graphql +0 -4
  125. data/app/frontend/fragments/add_comment_form_session.fragment.graphql +0 -6
  126. data/app/frontend/fragments/comment.fragment.graphql +0 -14
  127. data/app/frontend/fragments/comment_data.fragment.graphql +0 -27
  128. data/app/frontend/fragments/comment_thread.fragment.graphql +0 -6
  129. data/app/frontend/fragments/down_vote_button.fragment.graphql +0 -6
  130. data/app/frontend/fragments/up_vote_button.fragment.graphql +0 -6
  131. data/app/frontend/mutations/add_comment.mutation.graphql +0 -9
  132. data/app/frontend/mutations/down_vote.mutation.graphql +0 -9
  133. data/app/frontend/mutations/up_vote.mutation.graphql +0 -9
  134. data/app/frontend/queries/comments.query.graphql +0 -26
  135. data/app/frontend/support/asset_url.ts +0 -11
  136. data/app/frontend/support/generate_comments_data.ts +0 -49
  137. data/app/frontend/support/generate_user_data.ts +0 -14
  138. data/app/frontend/support/generate_user_group_data.ts +0 -14
  139. data/app/frontend/support/graphql_transformer.js +0 -32
  140. data/app/frontend/support/load_translations.ts +0 -48
  141. data/app/frontend/support/require_all.ts +0 -10
  142. data/app/frontend/support/resolve_graphql_query.ts +0 -37
  143. data/app/frontend/support/schema.ts +0 -2026
  144. data/app/types/decidim/comments/commentable_interface.rb +0 -61
  145. data/app/types/decidim/comments/commentable_mutation_type.rb +0 -33
  146. data/lib/decidim/comments/api/add_comment_type.rb +0 -13
  147. data/lib/decidim/comments/api/comment_mutation_type.rb +0 -20
  148. data/lib/decidim/comments/api/comment_type.rb +0 -89
@@ -1,289 +0,0 @@
1
- import * as React from "react";
2
- import { graphql } from "react-apollo";
3
-
4
- const PropTypes = require("prop-types");
5
-
6
- import Application from "../application/application.component";
7
-
8
- import AddCommentForm from "./add_comment_form.component";
9
- import CommentOrderSelector from "./comment_order_selector.component";
10
- import CommentThread from "./comment_thread.component";
11
-
12
- import {
13
- GetCommentsQuery,
14
- GetCommentsQueryVariables
15
- } from "../support/schema";
16
-
17
- const { I18n, Translate } = require("react-i18nify");
18
-
19
- interface CommentsProps extends GetCommentsQuery {
20
- locale: string;
21
- toggleTranslations: boolean;
22
- loading?: boolean;
23
- orderBy: string;
24
- singleCommentId?: string;
25
- reorderComments: (orderBy: string) => void;
26
- commentsMaxLength: number;
27
- }
28
-
29
- /**
30
- * The core class of the Decidim Comments engine.
31
- * It renders a collection of comments given a commentable id and type.
32
- * @global
33
- * @class
34
- * @augments Component
35
- */
36
- export class Comments extends React.Component<CommentsProps> {
37
- public static defaultProps: any = {
38
- loading: false,
39
- session: null,
40
- commentable: {
41
- comments: []
42
- }
43
- };
44
-
45
- public static childContextTypes: any = {
46
- locale: PropTypes.string,
47
- toggleTranslations: PropTypes.bool
48
- };
49
-
50
- public getChildContext() {
51
- return {
52
- locale: this.props.locale,
53
- toggleTranslations: this.props.toggleTranslations
54
- };
55
- }
56
-
57
- public render() {
58
- const { commentable: { totalCommentsCount = 0 }, singleCommentId, loading, commentsMaxLength } = this.props;
59
- let commentClasses = "comments";
60
- let commentHeader = I18n.t("components.comments.title", { count: totalCommentsCount });
61
- if (singleCommentId && singleCommentId !== "") {
62
- commentHeader = I18n.t("components.comments.comment_details_title");
63
- }
64
-
65
- if (loading) {
66
- commentClasses += " loading-comments";
67
- commentHeader = I18n.t("components.comments.loading");
68
- }
69
-
70
- return (
71
- <div className="columns large-9" id="comments">
72
- <section className={commentClasses}>
73
- <div className="row collapse order-by">
74
- <h2 className="order-by__text section-heading">
75
- {commentHeader}
76
- </h2>
77
- {this._renderCommentOrderSelector()}
78
- </div>
79
- {this._renderSingleCommentWarning()}
80
- {this._renderBlockedCommentsWarning()}
81
- {this._renderCommentThreads()}
82
- {this._renderAddCommentForm()}
83
- {this._renderBlockedCommentsForUserWarning()}
84
- </section>
85
- </div>
86
- );
87
- }
88
-
89
- /**
90
- * Renders warning message when viewing a single comment.
91
- * @private
92
- * @returns {Void|DOMElement} - A warning message or nothing.
93
- */
94
- private _renderSingleCommentWarning() {
95
- const { singleCommentId, reorderComments, orderBy } = this.props;
96
-
97
- if (singleCommentId && singleCommentId !== "") {
98
- const newUrl = `${window.location.pathname}${window.location.search.replace(`commentId=${singleCommentId}`, "")}`;
99
-
100
- return (
101
- <div className="callout secondary">
102
- <h5>{I18n.t("components.comments.single_comment_warning_title")}</h5>
103
- <p>
104
- <Translate
105
- value="components.comments.single_comment_warning"
106
- url={newUrl}
107
- dangerousHTML={true}
108
- />
109
- </p>
110
- </div>
111
- );
112
- }
113
-
114
- return null;
115
- }
116
-
117
- /**
118
- * Renders an order selector.
119
- * @private
120
- * @returns {Void|DOMElement} - A warning message or nothing.
121
- */
122
- private _renderCommentOrderSelector() {
123
- const { singleCommentId, reorderComments, orderBy } = this.props;
124
-
125
- if (singleCommentId && singleCommentId !== "") {
126
- return null;
127
- }
128
-
129
- return (
130
- <CommentOrderSelector
131
- reorderComments={reorderComments}
132
- defaultOrderBy={orderBy}
133
- />
134
- );
135
- }
136
-
137
- /**
138
- * Renders a warning message if the commentable doesn't accept new comments.
139
- * @private
140
- * @returns {Void|DOMElement} - A warning message or nothing.
141
- */
142
- private _renderBlockedCommentsWarning() {
143
- const { commentable: { acceptsNewComments, userAllowedToComment } } = this.props;
144
-
145
- if (!acceptsNewComments && !userAllowedToComment) {
146
- return (
147
- <div className="callout warning">
148
- <p>{I18n.t("components.comments.blocked_comments_warning")}</p>
149
- </div>
150
- );
151
- }
152
-
153
- return null;
154
- }
155
-
156
- /**
157
- * Renders a warning message if the participatory_space is private and users
158
- * don't have permissions.
159
- * @private
160
- * @returns {Void|DOMElement} - A warning message or nothing.
161
- */
162
- private _renderBlockedCommentsForUserWarning() {
163
- const { commentable: { acceptsNewComments, userAllowedToComment } } = this.props;
164
-
165
- if (acceptsNewComments) {
166
- if (!userAllowedToComment) {
167
- return (
168
- <div className="callout warning">
169
- <p>{I18n.t("components.comments.blocked_comments_for_user_warning")}</p>
170
- </div>
171
- );
172
- }
173
- }
174
-
175
- return null;
176
- }
177
-
178
- /**
179
- * Iterates the comment's collection and render a CommentThread for each one
180
- * @private
181
- * @returns {ReactComponent[]} - A collection of CommentThread components
182
- */
183
- private _renderCommentThreads() {
184
- const { session, commentable, orderBy, commentsMaxLength } = this.props;
185
- const { comments, commentsHaveVotes } = commentable;
186
-
187
- return comments.map((comment) => (
188
- <CommentThread
189
- key={comment.id}
190
- comment={comment}
191
- session={session}
192
- votable={commentsHaveVotes}
193
- rootCommentable={commentable}
194
- orderBy={orderBy}
195
- commentsMaxLength={commentsMaxLength}
196
- />
197
- ));
198
- }
199
-
200
- /**
201
- * If current user is present it renders the add comment form
202
- * @private
203
- * @returns {Void|ReactComponent} - A AddCommentForm component or nothing
204
- */
205
- private _renderAddCommentForm() {
206
- const { session, commentable, orderBy, singleCommentId, commentsMaxLength } = this.props;
207
- const { acceptsNewComments, commentsHaveAlignment, userAllowedToComment } = commentable;
208
-
209
- if (singleCommentId && singleCommentId !== "") {
210
- return null;
211
- }
212
-
213
- if (acceptsNewComments && userAllowedToComment) {
214
- return (
215
- <AddCommentForm
216
- session={session}
217
- commentable={commentable}
218
- arguable={commentsHaveAlignment}
219
- rootCommentable={commentable}
220
- orderBy={orderBy}
221
- commentsMaxLength={commentsMaxLength}
222
- />
223
- );
224
- }
225
-
226
- return null;
227
- }
228
- }
229
-
230
- /**
231
- * Wrap the Comments component with a GraphQL query and children
232
- * fragments.
233
- */
234
-
235
- window.Comments = Comments;
236
-
237
- export const commentsQuery = require("../queries/comments.query.graphql");
238
-
239
- const CommentsWithData: any = graphql<GetCommentsQuery, CommentsProps>(commentsQuery, {
240
- options: {
241
- pollInterval: 15000
242
- },
243
- props: ({ ownProps, data }) => {
244
- if (data) {
245
- const { loading, session, commentable, refetch } = data;
246
-
247
- return {
248
- loading,
249
- session,
250
- commentable,
251
- orderBy: ownProps.orderBy,
252
- singleCommentId: ownProps.singleCommentId,
253
- reorderComments: (orderBy: string) => {
254
- return refetch({
255
- orderBy
256
- });
257
- }
258
- };
259
- }
260
- }
261
- })(Comments);
262
-
263
- export interface CommentsApplicationProps extends GetCommentsQueryVariables {
264
- singleCommentId: string;
265
- locale: string;
266
- toggleTranslations: boolean;
267
- commentsMaxLength: number;
268
- }
269
-
270
- /**
271
- * Wrap the CommentsWithData component within an Application component to
272
- * connect it with Apollo client and store.
273
- * @returns {ReactComponent} - A component wrapped within an Application component
274
- */
275
- const CommentsApplication: React.SFC<CommentsApplicationProps> = ({ locale, toggleTranslations, commentableId, commentableType, singleCommentId, commentsMaxLength }) => (
276
- <Application locale={locale}>
277
- <CommentsWithData
278
- commentsMaxLength={commentsMaxLength}
279
- commentableId={commentableId}
280
- commentableType={commentableType}
281
- locale={locale}
282
- toggleTranslations={toggleTranslations}
283
- orderBy="older"
284
- singleCommentId={singleCommentId}
285
- />
286
- </Application>
287
- );
288
-
289
- export default CommentsApplication;
@@ -1,59 +0,0 @@
1
- import { shallow } from "enzyme";
2
- import * as React from "react";
3
-
4
- import { DownVoteButton } from "./down_vote_button.component";
5
- import VoteButton from "./vote_button.component";
6
-
7
- import generateCommentsData from "../support/generate_comments_data";
8
- import generateUserData from "../support/generate_user_data";
9
-
10
- import { DownVoteButtonFragment } from "../support/schema";
11
-
12
- describe("<DownVoteButton />", () => {
13
- const orderBy = "older";
14
- const rootCommentable = {
15
- id: "1",
16
- type: "Decidim::DummyResources::DummyResource"
17
- };
18
- let comment: DownVoteButtonFragment;
19
- let session: any = null;
20
- const downVote = jasmine.createSpy("downVote");
21
-
22
- beforeEach(() => {
23
- const commentsData = generateCommentsData(1);
24
- session = {
25
- user: generateUserData()
26
- };
27
- comment = commentsData[0];
28
- });
29
-
30
- it("should render a VoteButton component with the correct props", () => {
31
- const wrapper = shallow(<DownVoteButton session={session} comment={comment} downVote={downVote} rootCommentable={rootCommentable} orderBy={orderBy} />);
32
- expect(wrapper.find(VoteButton).prop("buttonClassName")).toEqual("comment__votes--down");
33
- expect(wrapper.find(VoteButton).prop("iconName")).toEqual("icon-chevron-bottom");
34
- expect(wrapper.find(VoteButton).prop("votes")).toEqual(comment.downVotes);
35
- });
36
-
37
- it("should pass disabled prop as false if comment upVoted is true", () => {
38
- comment.upVoted = true;
39
- const wrapper = shallow(<DownVoteButton session={session} comment={comment} downVote={downVote} rootCommentable={rootCommentable} orderBy={orderBy} />);
40
- expect(wrapper.find(VoteButton).prop("disabled")).toBeFalsy();
41
- });
42
-
43
- it("should pass disabled prop as false if comment downVoted is true", () => {
44
- comment.downVoted = true;
45
- const wrapper = shallow(<DownVoteButton session={session} comment={comment} downVote={downVote} rootCommentable={rootCommentable} orderBy={orderBy} />);
46
- expect(wrapper.find(VoteButton).prop("disabled")).toBeFalsy();
47
- });
48
-
49
- describe("when session is not present", () => {
50
- beforeEach(() => {
51
- session = null;
52
- });
53
-
54
- it("should pass userLoggedIn as false", () => {
55
- const wrapper = shallow(<DownVoteButton session={session} comment={comment} downVote={downVote} rootCommentable={rootCommentable} orderBy={orderBy} />);
56
- expect(wrapper.find(VoteButton).prop("userLoggedIn")).toBeFalsy();
57
- });
58
- });
59
- });
@@ -1,133 +0,0 @@
1
- import * as React from "react";
2
- import { graphql, MutationFunc } from "react-apollo";
3
-
4
- const PropTypes = require("prop-types");
5
-
6
- import VoteButton from "./vote_button.component";
7
-
8
- import {
9
- AddCommentFormCommentableFragment,
10
- AddCommentFormSessionFragment,
11
- CommentFragment,
12
- DownVoteButtonFragment,
13
- DownVoteMutation,
14
- GetCommentsQuery
15
- } from "../support/schema";
16
-
17
- const { I18n } = require("react-i18nify");
18
-
19
- interface DownVoteButtonProps {
20
- session: AddCommentFormSessionFragment & {
21
- user: any;
22
- } | null;
23
- comment: DownVoteButtonFragment;
24
- downVote?: (context: any) => void;
25
- rootCommentable: AddCommentFormCommentableFragment;
26
- orderBy: string;
27
- }
28
-
29
- export const DownVoteButton: React.SFC<DownVoteButtonProps> = (
30
- {
31
- session,
32
- comment: { downVotes, upVoted, downVoted },
33
- downVote
34
- },
35
- context) => {
36
- let selectedClass = "";
37
-
38
- if (downVoted) {
39
- selectedClass = "is-vote-selected";
40
- } else if (upVoted) {
41
- selectedClass = "is-vote-notselected";
42
- }
43
-
44
- const userLoggedIn = session && session.user;
45
- const disabled = false;
46
- const voteAction = () => downVote && downVote(context);
47
-
48
- return (
49
- <VoteButton
50
- buttonClassName="comment__votes--down"
51
- iconName="icon-chevron-bottom"
52
- text={I18n.t("components.down_vote_button.text")}
53
- votes={downVotes}
54
- voteAction={voteAction}
55
- disabled={disabled}
56
- selectedClass={selectedClass}
57
- userLoggedIn={userLoggedIn}
58
- />
59
- );
60
- };
61
-
62
- DownVoteButton.contextTypes = {
63
- locale: PropTypes.string,
64
- toggleTranslations: PropTypes.bool
65
- };
66
-
67
- const downVoteMutation = require("../mutations/down_vote.mutation.graphql");
68
- const getCommentsQuery = require("../queries/comments.query.graphql");
69
-
70
- const DownVoteButtonWithMutation = graphql<DownVoteMutation, DownVoteButtonProps>(downVoteMutation, {
71
- props: ({ ownProps, mutate }: { ownProps: DownVoteButtonProps, mutate: MutationFunc<DownVoteMutation> }) => ({
72
- downVote: ({ locale, toggleTranslations }: any) => mutate({
73
- variables: {
74
- locale,
75
- toggleTranslations,
76
- id: ownProps.comment.id
77
- },
78
- optimisticResponse: {
79
- __typename: "Mutation",
80
- comment: {
81
- __typename: "CommentMutation",
82
- downVote: {
83
- __typename: "Comment",
84
- ...ownProps.comment,
85
- downVotes: ownProps.comment.downVotes + (ownProps.comment.downVoted ? -1 : 1),
86
- downVoted: true
87
- }
88
- }
89
- },
90
- update: (store, { data }: { data: DownVoteMutation }) => {
91
- const variables = {
92
- locale,
93
- toggleTranslations,
94
- commentableId: ownProps.rootCommentable.id,
95
- commentableType: ownProps.rootCommentable.type,
96
- orderBy: ownProps.orderBy,
97
- singleCommentId: null
98
- };
99
-
100
- const commentReducer = (comment: CommentFragment): CommentFragment => {
101
- const replies = comment.comments || [];
102
-
103
- if (comment.id === ownProps.comment.id && data.comment) {
104
- return data.comment.downVote;
105
- }
106
-
107
- return {
108
- ...comment,
109
- comments: replies.map(commentReducer)
110
- };
111
- };
112
-
113
- const prev = store.readQuery<GetCommentsQuery>({ query: getCommentsQuery, variables });
114
-
115
- if (prev) {
116
- store.writeQuery({
117
- query: getCommentsQuery,
118
- data: {
119
- ...prev,
120
- commentable: {
121
- ...prev.commentable,
122
- comments: prev.commentable.comments.map(commentReducer)
123
- }
124
- },
125
- variables
126
- });
127
- }
128
- }
129
- })
130
- })
131
- })(DownVoteButton);
132
-
133
- export default DownVoteButtonWithMutation;