decidim-core 0.27.5 → 0.27.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/activity_cell.rb +2 -2
  3. data/app/cells/decidim/card_cell.rb +2 -2
  4. data/app/cells/decidim/card_m/top.erb +1 -1
  5. data/app/cells/decidim/card_m_cell.rb +1 -1
  6. data/app/cells/decidim/scopes_picker/scope_picker_values.erb +1 -1
  7. data/app/cells/decidim/tags_cell.rb +3 -1
  8. data/app/cells/decidim/user_profile_cell.rb +1 -1
  9. data/app/commands/decidim/create_omniauth_registration.rb +2 -4
  10. data/app/commands/decidim/messaging/reply_to_conversation.rb +3 -0
  11. data/app/commands/decidim/messaging/start_conversation.rb +3 -0
  12. data/app/controllers/concerns/decidim/devise_authentication_methods.rb +36 -0
  13. data/app/controllers/concerns/decidim/paginable.rb +1 -1
  14. data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +1 -22
  15. data/app/controllers/decidim/devise/sessions_controller.rb +1 -24
  16. data/app/controllers/decidim/widgets_controller.rb +6 -0
  17. data/app/events/decidim/welcome_notification_event.rb +6 -9
  18. data/app/helpers/decidim/cells_paginate_helper.rb +1 -1
  19. data/app/helpers/decidim/check_boxes_tree_helper.rb +4 -4
  20. data/app/helpers/decidim/newsletters_helper.rb +83 -16
  21. data/app/helpers/decidim/resource_helper.rb +1 -1
  22. data/app/helpers/decidim/sanitize_helper.rb +9 -0
  23. data/app/helpers/decidim/user_profile_helper.rb +7 -2
  24. data/app/mailers/decidim/messaging/conversation_mailer.rb +3 -72
  25. data/app/models/decidim/push_notification_message.rb +39 -0
  26. data/app/packs/images/decidim/.keep +0 -0
  27. data/app/packs/src/decidim/input_hashtags.js +1 -1
  28. data/app/packs/src/decidim/input_mentions.js +1 -1
  29. data/app/packs/src/decidim/input_multiple_mentions.js +1 -1
  30. data/app/packs/src/decidim/vizzs/index.js +1 -1
  31. data/app/packs/stylesheets/decidim/plugins/leaflet.scss +118 -114
  32. data/app/presenters/decidim/admin_log/oauth_application_resource_presenter.rb +1 -1
  33. data/app/presenters/decidim/notification_to_mailer_presenter.rb +9 -0
  34. data/app/services/decidim/events_manager.rb +6 -0
  35. data/app/services/decidim/push_notification_message_sender.rb +36 -0
  36. data/app/services/decidim/send_push_notification.rb +22 -8
  37. data/app/views/decidim/devise/registrations/new.html.erb +2 -2
  38. data/app/views/decidim/notifications_digest_mailer/_email_content.html.erb +7 -0
  39. data/app/views/decidim/shared/_address_details.html.erb +2 -2
  40. data/app/views/layouts/decidim/_js_configuration.html.erb +1 -0
  41. data/config/locales/ar.yml +4 -2
  42. data/config/locales/bg.yml +74 -0
  43. data/config/locales/ca.yml +22 -22
  44. data/config/locales/de.yml +25 -25
  45. data/config/locales/el.yml +1 -3
  46. data/config/locales/es-MX.yml +1 -1
  47. data/config/locales/es-PY.yml +1 -1
  48. data/config/locales/es.yml +20 -20
  49. data/config/locales/eu.yml +11 -2
  50. data/config/locales/fi.yml +3 -3
  51. data/config/locales/fr-CA.yml +2 -2
  52. data/config/locales/fr.yml +2 -2
  53. data/config/locales/gl.yml +3 -0
  54. data/config/locales/he-IL.yml +1 -0
  55. data/config/locales/hu.yml +41 -8
  56. data/config/locales/it.yml +1 -3
  57. data/config/locales/ja.yml +3 -2
  58. data/config/locales/lb.yml +1 -3
  59. data/config/locales/lt.yml +0 -3
  60. data/config/locales/no.yml +1 -3
  61. data/config/locales/pl.yml +137 -1
  62. data/config/locales/pt-BR.yml +113 -21
  63. data/config/locales/pt.yml +1 -3
  64. data/config/locales/ro-RO.yml +0 -3
  65. data/config/locales/ru.yml +9 -0
  66. data/config/locales/sk.yml +2 -0
  67. data/config/locales/sv.yml +22 -2
  68. data/config/locales/tr-TR.yml +1 -3
  69. data/config/locales/uk.yml +14 -0
  70. data/config/locales/zh-CN.yml +0 -3
  71. data/config/locales/zh-TW.yml +0 -3
  72. data/decidim-core.gemspec +78 -0
  73. data/lib/decidim/acts_as_tree.rb +14 -1
  74. data/lib/decidim/asset_router/storage.rb +4 -0
  75. data/lib/decidim/attribute_encryptor.rb +6 -4
  76. data/lib/decidim/core/engine.rb +7 -3
  77. data/lib/decidim/core/test/factories.rb +308 -95
  78. data/lib/decidim/core/test/shared_examples/amendable/amendment_created_event_examples.rb +6 -26
  79. data/lib/decidim/core/test/shared_examples/amendable/amendment_promoted_event_examples.rb +8 -26
  80. data/lib/decidim/core/test/shared_examples/comments_examples.rb +32 -0
  81. data/lib/decidim/core/test/shared_examples/embed_resource_examples.rb +187 -11
  82. data/lib/decidim/core/test/shared_examples/has_attachment_collections.rb +8 -6
  83. data/lib/decidim/core/test/shared_examples/has_attachments.rb +4 -4
  84. data/lib/decidim/core/test/shared_examples/has_category.rb +27 -0
  85. data/lib/decidim/core/test/shared_examples/has_reference.rb +1 -1
  86. data/lib/decidim/core/test/shared_examples/has_space_in_mcell_examples.rb +1 -2
  87. data/lib/decidim/core/test/shared_examples/resource_endorsed_event_examples.rb +6 -3
  88. data/lib/decidim/core/test/shared_examples/resource_locator_presenter_examples.rb +134 -0
  89. data/lib/decidim/core/test/shared_examples/searchable_results_examples.rb +1 -1
  90. data/lib/decidim/core/test/shared_examples/simple_event.rb +50 -2
  91. data/lib/decidim/core/test.rb +1 -0
  92. data/lib/decidim/core/version.rb +1 -1
  93. data/lib/decidim/core.rb +1 -0
  94. data/lib/decidim/engine_router.rb +17 -4
  95. data/lib/decidim/events/base_event.rb +5 -2
  96. data/lib/decidim/events/simple_event.rb +3 -17
  97. data/lib/decidim/has_category.rb +1 -1
  98. data/lib/decidim/has_conversations.rb +91 -0
  99. data/lib/decidim/participable.rb +17 -0
  100. data/lib/decidim/view_model.rb +1 -0
  101. data/lib/decidim/webpacker/webpack/.modernizrrc +9 -0
  102. data/lib/premailer/adapter/decidim.rb +5 -4
  103. data/lib/tasks/decidim_reminders_tasks.rake +1 -0
  104. data/lib/tasks/upgrade/decidim_fix_categorization.rake +15 -0
  105. metadata +31 -30
  106. data/config/environment.rb +0 -3
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # A messsage from a conversation that will be sent as a push notification
5
+ class PushNotificationMessage
6
+ class InvalidActionError < StandardError; end
7
+
8
+ include SanitizeHelper
9
+ include Decidim::TranslatableAttributes
10
+
11
+ def initialize(recipient:, conversation:, message:)
12
+ @recipient = recipient
13
+ @conversation = conversation
14
+ @message = message
15
+ end
16
+
17
+ attr_reader :recipient, :conversation, :message
18
+
19
+ alias user recipient
20
+
21
+ def body
22
+ decidim_html_escape(translated_attribute(message))
23
+ end
24
+
25
+ def icon
26
+ organization.attached_uploader(:favicon).variant_url(:big, host: organization.host)
27
+ end
28
+
29
+ def url
30
+ EngineRouter.new("decidim", {}).public_send(:conversation_path, host: organization.host, id: @conversation)
31
+ end
32
+
33
+ private
34
+
35
+ def organization
36
+ @organization ||= recipient.organization
37
+ end
38
+ end
39
+ end
File without changes
@@ -26,7 +26,7 @@ $(() => {
26
26
 
27
27
  /* eslint no-use-before-define: ["error", { "variables": false }]*/
28
28
  let remoteSearch = function(text, cb) {
29
- $.post("/api", {query: `{hashtags(name:"${text}") {name}}`}).
29
+ $.post(window.Decidim.config.get("api_path"), {query: `{hashtags(name:"${text}") {name}}`}).
30
30
 
31
31
  then((response) => {
32
32
  let data = response.data.hashtags || {};
@@ -42,7 +42,7 @@ $(() => {
42
42
  /* eslint no-use-before-define: ["error", { "variables": false }]*/
43
43
  let remoteSearch = function(text, cb) {
44
44
  let query = `{users(filter:{wildcard:"${text}"}){nickname,name,avatarUrl,__typename,...on UserGroup{membersCount}}}`;
45
- $.post("/api", {query: query}).
45
+ $.post(window.Decidim.config.get("api_path"), {query: query}).
46
46
  then((response) => {
47
47
  let data = response.data.users || {};
48
48
  cb(data)
@@ -42,7 +42,7 @@ $(() => {
42
42
  const autoComplete = new AutoComplete($searchInput[0], {
43
43
  dataMatchKeys: ["name", "nickname"],
44
44
  dataSource: (query, callback) => {
45
- $.post("/api", {
45
+ $.post(window.Decidim.config.get("api_path"), {
46
46
  "query": `
47
47
  {
48
48
  users(filter:{wildcard:"${query}",excludeIds:[]})
@@ -19,7 +19,7 @@ $(() => {
19
19
  metricsParams.spaceId = $("#metrics #metrics-space_id").val() || null;
20
20
  }
21
21
 
22
- const fetch = (metrics) => $.post("/api", query(metrics));
22
+ const fetch = (metrics) => $.post(window.Decidim.config.get("api_path"), query(metrics));
23
23
 
24
24
  const downloadMetricData = (event) => {
25
25
  event.preventDefault();
@@ -22,8 +22,6 @@
22
22
  .leaflet-tile,
23
23
  .leaflet-marker-icon,
24
24
  .leaflet-marker-shadow{
25
- -webkit-user-select: none;
26
- -moz-user-select: none;
27
25
  user-select: none;
28
26
  -webkit-user-drag: none;
29
27
  }
@@ -45,34 +43,53 @@
45
43
  display: block;
46
44
  }
47
45
 
48
- /* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
46
+ /* .leaflet-container svg: reset svg max-width declaration shipped in Joomla! (joomla.org) 3.x */
49
47
 
50
48
  /* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
51
- .leaflet-container .leaflet-overlay-pane svg,
49
+ .leaflet-container .leaflet-overlay-pane svg{
50
+ max-width: none !important;
51
+ max-height: none !important;
52
+ }
53
+
52
54
  .leaflet-container .leaflet-marker-pane img,
53
55
  .leaflet-container .leaflet-shadow-pane img,
54
56
  .leaflet-container .leaflet-tile-pane img,
55
- .leaflet-container img.leaflet-image-layer{
57
+ .leaflet-container img.leaflet-image-layer,
58
+ .leaflet-container .leaflet-tile{
56
59
  max-width: none !important;
60
+ max-height: none !important;
61
+ width: auto;
62
+ padding: 0;
63
+ }
64
+
65
+ .leaflet-container img.leaflet-tile{
66
+ /* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
67
+ mix-blend-mode: plus-lighter;
57
68
  }
58
69
 
59
70
  .leaflet-container.leaflet-touch-zoom{
60
- -ms-touch-action: pan-x pan-y;
61
71
  touch-action: pan-x pan-y;
62
72
  }
63
73
 
64
74
  .leaflet-container.leaflet-touch-drag{
65
- -ms-touch-action: pinch-zoom;
75
+ /* Fallback for FF which does not support pinch-zoom */
76
+ touch-action: none;
66
77
  touch-action: pinch-zoom;
67
78
  }
68
79
 
69
80
  .leaflet-container.leaflet-touch-drag.leaflet-touch-zoom{
70
- -ms-touch-action: none;
71
81
  touch-action: none;
72
82
  }
73
83
 
84
+ .leaflet-container{
85
+ -webkit-tap-highlight-color: transparent;
86
+ }
87
+
88
+ .leaflet-container a{
89
+ -webkit-tap-highlight-color: rgba(51, 181, 229, .4);
90
+ }
91
+
74
92
  .leaflet-tile{
75
- filter: inherit;
76
93
  visibility: hidden;
77
94
  }
78
95
 
@@ -83,7 +100,6 @@
83
100
  .leaflet-zoom-box{
84
101
  width: 0;
85
102
  height: 0;
86
- -moz-box-sizing: border-box;
87
103
  box-sizing: border-box;
88
104
  z-index: 800;
89
105
  }
@@ -94,27 +110,40 @@
94
110
  user-select: none;
95
111
  }
96
112
 
97
- .leaflet-pane{ z-index: 400; }
113
+ .leaflet-pane{
114
+ z-index: 400;
115
+ }
98
116
 
99
- .leaflet-tile-pane{ z-index: 200; }
100
- .leaflet-overlay-pane{ z-index: 400; }
101
- .leaflet-shadow-pane{ z-index: 500; }
102
- .leaflet-marker-pane{ z-index: 600; }
103
- .leaflet-tooltip-pane{ z-index: 650; }
104
- .leaflet-popup-pane{ z-index: 700; }
117
+ .leaflet-tile-pane{
118
+ z-index: 200;
119
+ }
105
120
 
106
- .leaflet-map-pane canvas{ z-index: 100; }
107
- .leaflet-map-pane svg{ z-index: 200; }
121
+ .leaflet-overlay-pane{
122
+ z-index: 400;
123
+ }
108
124
 
109
- .leaflet-vml-shape{
110
- width: 1px;
111
- height: 1px;
125
+ .leaflet-shadow-pane{
126
+ z-index: 500;
112
127
  }
113
128
 
114
- .lvml{
115
- behavior: url(#default#VML);
116
- display: inline-block;
117
- position: absolute;
129
+ .leaflet-marker-pane{
130
+ z-index: 600;
131
+ }
132
+
133
+ .leaflet-tooltip-pane{
134
+ z-index: 650;
135
+ }
136
+
137
+ .leaflet-popup-pane{
138
+ z-index: 700;
139
+ }
140
+
141
+ .leaflet-map-pane canvas{
142
+ z-index: 100;
143
+ }
144
+
145
+ .leaflet-map-pane svg{
146
+ z-index: 200;
118
147
  }
119
148
 
120
149
  /* control positioning */
@@ -122,7 +151,6 @@
122
151
  .leaflet-control{
123
152
  position: relative;
124
153
  z-index: 800;
125
- pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
126
154
  pointer-events: auto;
127
155
  }
128
156
 
@@ -176,15 +204,8 @@
176
204
 
177
205
  /* zoom and fade animations */
178
206
 
179
- .leaflet-fade-anim .leaflet-tile{
180
- will-change: opacity;
181
- }
182
-
183
207
  .leaflet-fade-anim .leaflet-popup{
184
208
  opacity: 0;
185
- -webkit-transition: opacity .2s linear;
186
- -moz-transition: opacity .2s linear;
187
- -o-transition: opacity .2s linear;
188
209
  transition: opacity .2s linear;
189
210
  }
190
211
 
@@ -193,8 +214,6 @@
193
214
  }
194
215
 
195
216
  .leaflet-zoom-animated{
196
- -webkit-transform-origin: 0 0;
197
- -ms-transform-origin: 0 0;
198
217
  transform-origin: 0 0;
199
218
  }
200
219
 
@@ -203,17 +222,11 @@
203
222
  }
204
223
 
205
224
  .leaflet-zoom-anim .leaflet-zoom-animated{
206
- -webkit-transition: -webkit-transform .25s cubic-bezier(0, 0, .25, 1);
207
- -moz-transition: -moz-transform .25s cubic-bezier(0, 0, .25, 1);
208
- -o-transition: -o-transform .25s cubic-bezier(0, 0, .25, 1);
209
225
  transition: transform .25s cubic-bezier(0, 0, .25, 1);
210
226
  }
211
227
 
212
228
  .leaflet-zoom-anim .leaflet-tile,
213
229
  .leaflet-pan-anim .leaflet-tile{
214
- -webkit-transition: none;
215
- -moz-transition: none;
216
- -o-transition: none;
217
230
  transition: none;
218
231
  }
219
232
 
@@ -228,8 +241,7 @@
228
241
  }
229
242
 
230
243
  .leaflet-grab{
231
- cursor: -webkit-grab;
232
- cursor: -moz-grab;
244
+ cursor: grab;
233
245
  }
234
246
 
235
247
  .leaflet-crosshair,
@@ -245,9 +257,7 @@
245
257
  .leaflet-dragging .leaflet-grab,
246
258
  .leaflet-dragging .leaflet-grab .leaflet-interactive,
247
259
  .leaflet-dragging .leaflet-marker-draggable{
248
- cursor: move;
249
- cursor: -webkit-grabbing;
250
- cursor: -moz-grabbing;
260
+ cursor: grabbing;
251
261
  }
252
262
 
253
263
  /* marker & overlays interactivity */
@@ -262,7 +272,6 @@
262
272
  .leaflet-marker-icon.leaflet-interactive,
263
273
  .leaflet-image-layer.leaflet-interactive,
264
274
  .leaflet-pane > svg path.leaflet-interactive{
265
- pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
266
275
  pointer-events: auto;
267
276
  }
268
277
 
@@ -277,10 +286,6 @@
277
286
  color: #0078a8;
278
287
  }
279
288
 
280
- .leaflet-container a.leaflet-active{
281
- outline: 2px solid orange;
282
- }
283
-
284
289
  .leaflet-zoom-box{
285
290
  border: 2px dotted #38f;
286
291
  background: rgba(255, 255, 255, .5);
@@ -288,7 +293,10 @@
288
293
 
289
294
  /* general typography */
290
295
  .leaflet-container{
291
- font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
296
+ font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
297
+ font-size: 12px;
298
+ font-size: .75rem;
299
+ line-height: 1.5;
292
300
  }
293
301
 
294
302
  /* general toolbar styles */
@@ -318,7 +326,8 @@
318
326
  display: block;
319
327
  }
320
328
 
321
- .leaflet-bar a:hover{
329
+ .leaflet-bar a:hover,
330
+ .leaflet-bar a:focus{
322
331
  background-color: #f4f4f4;
323
332
  }
324
333
 
@@ -345,24 +354,27 @@
345
354
  line-height: 30px;
346
355
  }
347
356
 
357
+ .leaflet-touch .leaflet-bar a:first-child{
358
+ border-top-left-radius: 2px;
359
+ border-top-right-radius: 2px;
360
+ }
361
+
362
+ .leaflet-touch .leaflet-bar a:last-child{
363
+ border-bottom-left-radius: 2px;
364
+ border-bottom-right-radius: 2px;
365
+ }
366
+
348
367
  /* zoom control */
349
368
 
350
369
  .leaflet-control-zoom-in,
351
370
  .leaflet-control-zoom-out{
352
- font: bold 18px 'Lucida Console', Monaco, monospace;
371
+ font: bold 18px "Lucida Console", Monaco, monospace;
353
372
  text-indent: 1px;
354
373
  }
355
374
 
356
- .leaflet-control-zoom-out{
357
- font-size: 20px;
358
- }
359
-
360
- .leaflet-touch .leaflet-control-zoom-in{
361
- font-size: 22px;
362
- }
363
-
375
+ .leaflet-touch .leaflet-control-zoom-in,
364
376
  .leaflet-touch .leaflet-control-zoom-out{
365
- font-size: 24px;
377
+ font-size: 22px;
366
378
  }
367
379
 
368
380
  /* layers control */
@@ -399,6 +411,12 @@
399
411
  position: relative;
400
412
  }
401
413
 
414
+ .leaflet-control-layers-list{
415
+ border: 0;
416
+ margin: 0;
417
+ padding: 0;
418
+ }
419
+
402
420
  .leaflet-control-layers-expanded{
403
421
  padding: 6px 10px 6px 6px;
404
422
  color: #333;
@@ -406,7 +424,7 @@
406
424
  }
407
425
 
408
426
  .leaflet-control-layers-scrollbar{
409
- overflow-y: scroll;
427
+ overflow: hidden scroll;
410
428
  padding-right: 5px;
411
429
  }
412
430
 
@@ -418,6 +436,8 @@
418
436
 
419
437
  .leaflet-control-layers label{
420
438
  display: block;
439
+ font-size: 13px;
440
+ font-size: 1.08333em;
421
441
  }
422
442
 
423
443
  .leaflet-control-layers-separator{
@@ -443,19 +463,24 @@
443
463
  .leaflet-control-scale-line{
444
464
  padding: 0 5px;
445
465
  color: #333;
466
+ line-height: 1.4;
446
467
  }
447
468
 
448
469
  .leaflet-control-attribution a{
449
470
  text-decoration: none;
450
471
  }
451
472
 
452
- .leaflet-control-attribution a:hover{
473
+ .leaflet-control-attribution a:hover,
474
+ .leaflet-control-attribution a:focus{
453
475
  text-decoration: underline;
454
476
  }
455
477
 
456
- .leaflet-container .leaflet-control-attribution,
457
- .leaflet-container .leaflet-control-scale{
458
- font-size: 11px;
478
+ .leaflet-attribution-flag{
479
+ display: inline !important;
480
+ vertical-align: baseline !important;
481
+ width: 1em;
482
+ height: .6669em;
483
+ margin-right: .277em;
459
484
  }
460
485
 
461
486
  .leaflet-left .leaflet-control-scale{
@@ -471,13 +496,10 @@
471
496
  border-top: none;
472
497
  line-height: 1.1;
473
498
  padding: 2px 5px 1px;
474
- font-size: 11px;
475
499
  white-space: nowrap;
476
- overflow: hidden;
477
- -moz-box-sizing: border-box;
478
500
  box-sizing: border-box;
479
- background: #fff;
480
501
  background: rgba(255, 255, 255, .5);
502
+ text-shadow: 1px 1px #fff;
481
503
  }
482
504
 
483
505
  .leaflet-control-scale-line:not(:first-child){
@@ -517,8 +539,11 @@
517
539
  }
518
540
 
519
541
  .leaflet-popup-content{
520
- margin: 13px 19px;
521
- line-height: 1.4;
542
+ margin: 13px 24px 13px 20px;
543
+ line-height: 1.3;
544
+ font-size: 13px;
545
+ font-size: 1.08333em;
546
+ min-height: 1px;
522
547
  }
523
548
 
524
549
  .leaflet-popup-content p{
@@ -530,6 +555,7 @@
530
555
  height: 20px;
531
556
  position: absolute;
532
557
  left: 50%;
558
+ margin-top: -1px;
533
559
  margin-left: -20px;
534
560
  overflow: hidden;
535
561
  pointer-events: none;
@@ -540,10 +566,7 @@
540
566
  height: 17px;
541
567
  padding: 1px;
542
568
  margin: -10px auto 0;
543
- -webkit-transform: rotate(45deg);
544
- -moz-transform: rotate(45deg);
545
- -ms-transform: rotate(45deg);
546
- -o-transform: rotate(45deg);
569
+ pointer-events: auto;
547
570
  transform: rotate(45deg);
548
571
  }
549
572
 
@@ -558,48 +581,23 @@
558
581
  position: absolute;
559
582
  top: 0;
560
583
  right: 0;
561
- padding: 4px 4px 0 0;
562
584
  border: none;
563
585
  text-align: center;
564
- width: 18px;
565
- height: 14px;
586
+ width: 24px;
587
+ height: 24px;
566
588
  font: 16px/14px Tahoma, Verdana, sans-serif;
567
- color: #c3c3c3;
589
+ color: #757575;
568
590
  text-decoration: none;
569
- font-weight: bold;
570
591
  background: transparent;
571
592
  }
572
593
 
573
- .leaflet-container a.leaflet-popup-close-button:hover{
574
- color: #999;
594
+ .leaflet-container a.leaflet-popup-close-button:hover,
595
+ .leaflet-container a.leaflet-popup-close-button:focus{
596
+ color: #585858;
575
597
  }
576
598
 
577
599
  .leaflet-popup-scrolled{
578
600
  overflow: auto;
579
- border-bottom: 1px solid #ddd;
580
- border-top: 1px solid #ddd;
581
- }
582
-
583
- .leaflet-oldie .leaflet-popup-content-wrapper{
584
- zoom: 1;
585
- }
586
-
587
- .leaflet-oldie .leaflet-popup-tip{
588
- width: 24px;
589
- margin: 0 auto;
590
- -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
591
- filter: progid:dximagetransform.microsoft.matrix(M11=.70710678, M12=.70710678, M21=-.70710678, M22=.70710678);
592
- }
593
-
594
- .leaflet-oldie .leaflet-popup-tip-container{
595
- margin-top: -1px;
596
- }
597
-
598
- .leaflet-oldie .leaflet-control-zoom,
599
- .leaflet-oldie .leaflet-control-layers,
600
- .leaflet-oldie .leaflet-popup-content-wrapper,
601
- .leaflet-oldie .leaflet-popup-tip{
602
- border: 1px solid #999;
603
601
  }
604
602
 
605
603
  /* div icon */
@@ -620,15 +618,12 @@
620
618
  border-radius: 3px;
621
619
  color: #222;
622
620
  white-space: nowrap;
623
- -webkit-user-select: none;
624
- -moz-user-select: none;
625
- -ms-user-select: none;
626
621
  user-select: none;
627
622
  pointer-events: none;
628
623
  box-shadow: 0 1px 3px rgba(0, 0, 0, .4);
629
624
  }
630
625
 
631
- .leaflet-tooltip.leaflet-clickable{
626
+ .leaflet-tooltip.leaflet-interactive{
632
627
  cursor: pointer;
633
628
  pointer-events: auto;
634
629
  }
@@ -698,3 +693,12 @@
698
693
  margin-left: -12px;
699
694
  border-right-color: #fff;
700
695
  }
696
+
697
+ /* Printing */
698
+
699
+ @media print{
700
+ /* Prevent printers from removing background-images of controls. */
701
+ .leaflet-control{
702
+ -webkit-print-color-adjust: exact;
703
+ }
704
+ }
@@ -11,7 +11,7 @@ module Decidim
11
11
  #
12
12
  # Returns an HTML-safe String.
13
13
  def resource_path
14
- @resource_path ||= h.decidim_admin.oauth_application_path(resource)
14
+ @resource_path ||= h.decidim_system.oauth_application_path(resource)
15
15
  end
16
16
  end
17
17
  end
@@ -7,11 +7,16 @@ module Decidim
7
7
  class NotificationToMailerPresenter < SimpleDelegator
8
8
  include Decidim::TranslatableAttributes
9
9
 
10
+ EXTENDED_NOTIFICATIONS_CLASSES = [
11
+ "Decidim::Comments::CommentCreatedEvent"
12
+ ].freeze
13
+
10
14
  delegate :url_helpers, to: "Decidim::Core::Engine.routes"
11
15
  delegate :resource_title, to: :event
12
16
  delegate :resource_url, to: :event
13
17
  delegate :email_intro, to: :event
14
18
  delegate :resource_path, to: :event
19
+ delegate :safe_resource_text, to: :event
15
20
 
16
21
  def date_time
17
22
  if frequency == :daily
@@ -21,6 +26,10 @@ module Decidim
21
26
  end
22
27
  end
23
28
 
29
+ def show_extended_information?
30
+ EXTENDED_NOTIFICATIONS_CLASSES.include?(event_class)
31
+ end
32
+
24
33
  private
25
34
 
26
35
  def event
@@ -46,5 +46,11 @@ module Decidim
46
46
  def self.subscribe(event, &block)
47
47
  ActiveSupport::Notifications.subscribe(event, &block)
48
48
  end
49
+
50
+ def self.subscribe_events!
51
+ subscribe(/^decidim\.events\./) do |event_name, data|
52
+ EventPublisherJob.perform_later(event_name, data)
53
+ end
54
+ end
49
55
  end
50
56
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # A wrapper for preparing push notifications messages from conversations
5
+ # It respects the same contract as the Decidim::Messaging::ConversationMailer
6
+ class PushNotificationMessageSender
7
+ include HasConversations
8
+
9
+ def deliver
10
+ SendPushNotification.new.perform(@notification, title)
11
+ end
12
+
13
+ private
14
+
15
+ # rubocop:disable Metrics/ParameterLists
16
+ # rubocop:disable Lint/UnusedMethodArgument
17
+ #
18
+ # There are some parameters thar are not used in the method, but they are needed to
19
+ # keep the same contract as the Decidim::Messaging::ConversationMailer
20
+ def send_notification(from:, to:, conversation:, action:, message: nil, third_party: nil)
21
+ @action = action
22
+ @sender = to
23
+ @third_party = third_party
24
+
25
+ @notification = PushNotificationMessage.new(recipient: to, conversation: conversation, message: message)
26
+
27
+ self
28
+ end
29
+ # rubocop:enable Lint/UnusedMethodArgument
30
+ # rubocop:enable Metrics/ParameterLists
31
+
32
+ def title
33
+ get_subject(action: @action, sender: @sender, third_party: @third_party)
34
+ end
35
+ end
36
+ end
@@ -14,14 +14,19 @@ module Decidim
14
14
  # Send the push notification. Returns `nil` if the user didn't allowed push notifications
15
15
  # or if the subscription to push notifications doesn't exist
16
16
  #
17
- # Returns the result of the dispatch or nil if user or subscription are empty
18
- def perform(notification)
17
+ # @param notification [Decidim::Notification, Decidim::PushNotificationMessage] the notification to be sent
18
+ # @param title [String] the title of the notification. Optional.
19
+ #
20
+ # @return [Array<Net::HTTPCreated>, nil] the result of the dispatch or nil if user or subscription are empty
21
+ def perform(notification, title = nil)
19
22
  return unless Rails.application.secrets.dig(:vapid, :enabled)
23
+ raise ArgumentError, "Need to provide a title if the notification is a PushNotificationMessage" if notification.is_a?(Decidim::PushNotificationMessage) && title.nil?
24
+
25
+ user = notification.user
20
26
 
21
- I18n.with_locale(notification.user.locale || notification.user.organization.default_locale) do
22
- notification.user.notifications_subscriptions.values.map do |subscription|
23
- message_params = notification_params(Decidim::PushNotificationPresenter.new(notification))
24
- payload = build_payload(message_params, subscription)
27
+ I18n.with_locale(user.locale || user.organization.default_locale) do
28
+ user.notifications_subscriptions.values.map do |subscription|
29
+ payload = build_payload(message_params(notification, title), subscription)
25
30
  # Capture webpush exceptions in order to avoid this call to be repeated by the background job runner
26
31
  # Webpush::Error class is the parent class of all defined errors
27
32
  begin
@@ -36,9 +41,18 @@ module Decidim
36
41
 
37
42
  private
38
43
 
39
- def notification_params(notification)
44
+ def message_params(notification, title = nil)
45
+ case notification
46
+ when Decidim::PushNotificationMessage
47
+ notification_params(notification, title)
48
+ else # when Decidim::Notification
49
+ notification_params(Decidim::PushNotificationPresenter.new(notification))
50
+ end
51
+ end
52
+
53
+ def notification_params(notification, title = nil)
40
54
  {
41
- title: notification.title,
55
+ title: title.presence || notification.title,
42
56
  body: notification.body,
43
57
  icon: notification.icon,
44
58
  data: { url: notification.url }