decidim-decidim_awesome 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE-AGPLv3.txt +661 -0
  3. data/README.md +307 -0
  4. data/Rakefile +51 -0
  5. data/app/assets/config/decidim_admin_decidim_awesome_manifest.css +3 -0
  6. data/app/assets/config/decidim_admin_decidim_awesome_manifest.js +1 -0
  7. data/app/assets/config/decidim_decidim_awesome_manifest.css +5 -0
  8. data/app/assets/config/decidim_decidim_awesome_manifest.js +2 -0
  9. data/app/assets/images/decidim/decidim_awesome/loading.gif +0 -0
  10. data/app/assets/images/decidim/decidim_awesome/platoniq-logo.png +0 -0
  11. data/app/assets/javascripts/decidim/decidim_awesome/admin.js +2 -0
  12. data/app/assets/javascripts/decidim/decidim_awesome/admin/constraints.js.es6 +54 -0
  13. data/app/assets/javascripts/decidim/decidim_awesome/application.js +4 -0
  14. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/api_fetcher.js.es6 +38 -0
  15. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/categories.js.es6 +25 -0
  16. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/map.js.es6 +215 -0
  17. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/meetings.js.es6 +129 -0
  18. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/proposals.js.es6 +78 -0
  19. data/app/assets/javascripts/decidim/decidim_awesome/editors/markdown_view.js.es6 +12 -0
  20. data/app/assets/javascripts/decidim/decidim_awesome/editors/quill_editor.js.es6 +162 -0
  21. data/app/assets/javascripts/decidim/decidim_awesome/forms/autosave.js.es6 +90 -0
  22. data/app/assets/javascripts/decidim/decidim_awesome/proposals/images.js.es6 +25 -0
  23. data/app/assets/stylesheets/decidim/decidim_awesome/admin.scss +45 -0
  24. data/app/assets/stylesheets/decidim/decidim_awesome/admin/constraints.scss +37 -0
  25. data/app/assets/stylesheets/decidim/decidim_awesome/application.scss +8 -0
  26. data/app/assets/stylesheets/decidim/decidim_awesome/awesome_iframe/iframe.scss +10 -0
  27. data/app/assets/stylesheets/decidim/decidim_awesome/awesome_map/leaflet.scss.erb +9 -0
  28. data/app/assets/stylesheets/decidim/decidim_awesome/awesome_map/map.scss +66 -0
  29. data/app/assets/stylesheets/decidim/decidim_awesome/editors/markdown_editor.scss +17 -0
  30. data/app/assets/stylesheets/decidim/decidim_awesome/editors/markdown_view.scss +27 -0
  31. data/app/assets/stylesheets/decidim/decidim_awesome/editors/quill_editor.scss +7 -0
  32. data/app/assets/stylesheets/decidim/decidim_awesome/forms/autosave.scss +17 -0
  33. data/app/awesome_overrides/presenters/decidim/proposals/proposal_presenter_override.rb +31 -0
  34. data/app/commands/decidim/decidim_awesome/admin/create_constraint.rb +47 -0
  35. data/app/commands/decidim/decidim_awesome/admin/destroy_constraint.rb +31 -0
  36. data/app/commands/decidim/decidim_awesome/admin/update_config.rb +44 -0
  37. data/app/commands/decidim/decidim_awesome/admin/update_constraint.rb +44 -0
  38. data/app/commands/decidim/decidim_awesome/create_editor_image.rb +34 -0
  39. data/app/controllers/concerns/decidim/decidim_awesome/needs_awesome_config.rb +17 -0
  40. data/app/controllers/decidim/decidim_awesome/admin/application_controller.rb +21 -0
  41. data/app/controllers/decidim/decidim_awesome/admin/checks_controller.rb +37 -0
  42. data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +44 -0
  43. data/app/controllers/decidim/decidim_awesome/admin/constraints_controller.rb +126 -0
  44. data/app/controllers/decidim/decidim_awesome/application_controller.rb +14 -0
  45. data/app/controllers/decidim/decidim_awesome/editor_images_controller.rb +50 -0
  46. data/app/controllers/decidim/decidim_awesome/iframe_component/application_controller.rb +15 -0
  47. data/app/controllers/decidim/decidim_awesome/iframe_component/iframe_controller.rb +33 -0
  48. data/app/controllers/decidim/decidim_awesome/map_component/application_controller.rb +15 -0
  49. data/app/controllers/decidim/decidim_awesome/map_component/map_controller.rb +31 -0
  50. data/app/forms/decidim/decidim_awesome/admin/config_form.rb +22 -0
  51. data/app/forms/decidim/decidim_awesome/admin/constraint_form.rb +20 -0
  52. data/app/forms/decidim/decidim_awesome/admin/intergram_form.rb +21 -0
  53. data/app/forms/decidim/decidim_awesome/editor_image_form.rb +16 -0
  54. data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +90 -0
  55. data/app/helpers/decidim/decidim_awesome/application_helper.rb +10 -0
  56. data/app/helpers/decidim/decidim_awesome/map_helper.rb +121 -0
  57. data/app/models/decidim/decidim_awesome/application_record.rb +10 -0
  58. data/app/models/decidim/decidim_awesome/awesome_config.rb +23 -0
  59. data/app/models/decidim/decidim_awesome/config_constraint.rb +13 -0
  60. data/app/models/decidim/decidim_awesome/editor_image.rb +24 -0
  61. data/app/permissions/decidim/decidim_awesome/permissions.rb +29 -0
  62. data/app/uploaders/decidim/decidim_awesome/image_uploader.rb +22 -0
  63. data/app/views/decidim/decidim_awesome/admin/checks/index.html.erb +35 -0
  64. data/app/views/decidim/decidim_awesome/admin/config/_constraints.html.erb +27 -0
  65. data/app/views/decidim/decidim_awesome/admin/config/_form_editors.html.erb +20 -0
  66. data/app/views/decidim/decidim_awesome/admin/config/_form_livechat.html.erb +44 -0
  67. data/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb +12 -0
  68. data/app/views/decidim/decidim_awesome/admin/config/_form_surveys.html.erb +9 -0
  69. data/app/views/decidim/decidim_awesome/admin/config/_modal.html.erb +11 -0
  70. data/app/views/decidim/decidim_awesome/admin/config/show.html.erb +15 -0
  71. data/app/views/decidim/decidim_awesome/admin/constraints/_form.html.erb +56 -0
  72. data/app/views/decidim/decidim_awesome/admin/constraints/new.html.erb +14 -0
  73. data/app/views/decidim/decidim_awesome/admin/constraints/show.html.erb +14 -0
  74. data/app/views/decidim/decidim_awesome/iframe_component/iframe/show.html.erb +9 -0
  75. data/app/views/decidim/decidim_awesome/map_component/map/error.erb +7 -0
  76. data/app/views/decidim/decidim_awesome/map_component/map/show.html.erb +74 -0
  77. data/app/views/layouts/decidim/_head.html.erb +5 -0
  78. data/app/views/layouts/decidim/admin/_header.html.erb +5 -0
  79. data/app/views/layouts/decidim/admin/decidim_awesome.html.erb +47 -0
  80. data/app/views/layouts/decidim/decidim_awesome/_awesome_config.html.erb +20 -0
  81. data/app/views/layouts/decidim/decidim_awesome/_intergram_widget.html.erb +16 -0
  82. data/app/views/v0.21/layouts/decidim/_head.html.erb +34 -0
  83. data/app/views/v0.21/layouts/decidim/admin/_header.html.erb +9 -0
  84. data/app/views/v0.22/layouts/decidim/_head.html.erb +36 -0
  85. data/app/views/v0.22/layouts/decidim/admin/_header.html.erb +11 -0
  86. data/config/i18n-tasks.yml +10 -0
  87. data/config/locales/ca.yml +125 -0
  88. data/config/locales/cs.yml +125 -0
  89. data/config/locales/en.yml +176 -0
  90. data/config/locales/es.yml +125 -0
  91. data/config/locales/fr.yml +125 -0
  92. data/config/locales/sv.yml +125 -0
  93. data/db/migrate/20200324170000_create_decidim_awesome_config.rb +16 -0
  94. data/db/migrate/20200324230936_create_awesome_editor_images.rb +14 -0
  95. data/db/migrate/20200403142257_create_decidim_awesome_config_constraints.rb +13 -0
  96. data/db/seeds.rb +27 -0
  97. data/lib/decidim/decidim_awesome.rb +110 -0
  98. data/lib/decidim/decidim_awesome/admin.rb +10 -0
  99. data/lib/decidim/decidim_awesome/admin_engine.rb +45 -0
  100. data/lib/decidim/decidim_awesome/awesome_helpers.rb +55 -0
  101. data/lib/decidim/decidim_awesome/checksums.yml +15 -0
  102. data/lib/decidim/decidim_awesome/config.rb +129 -0
  103. data/lib/decidim/decidim_awesome/content_renderers.rb +9 -0
  104. data/lib/decidim/decidim_awesome/content_renderers/markdown_renderer.rb +18 -0
  105. data/lib/decidim/decidim_awesome/context_analyzers.rb +11 -0
  106. data/lib/decidim/decidim_awesome/context_analyzers/component_analyzer.rb +38 -0
  107. data/lib/decidim/decidim_awesome/context_analyzers/participatory_space_analyzer.rb +31 -0
  108. data/lib/decidim/decidim_awesome/context_analyzers/request_analyzer.rb +97 -0
  109. data/lib/decidim/decidim_awesome/engine.rb +38 -0
  110. data/lib/decidim/decidim_awesome/iframe_component/component.rb +59 -0
  111. data/lib/decidim/decidim_awesome/iframe_component/engine.rb +23 -0
  112. data/lib/decidim/decidim_awesome/map_component/component.rb +74 -0
  113. data/lib/decidim/decidim_awesome/map_component/engine.rb +23 -0
  114. data/lib/decidim/decidim_awesome/system_checker.rb +63 -0
  115. data/lib/decidim/decidim_awesome/test/factories.rb +36 -0
  116. data/lib/decidim/decidim_awesome/test/shared_examples/config_examples.rb +25 -0
  117. data/lib/decidim/decidim_awesome/test/themes/css.lvh.me.css +3 -0
  118. data/lib/decidim/decidim_awesome/test/themes/erb.lvh.me.scss.erb +2 -0
  119. data/lib/decidim/decidim_awesome/test/themes/scss.lvh.me.scss +1 -0
  120. data/lib/decidim/decidim_awesome/test/themes/test-theme/body.scss +4 -0
  121. data/lib/decidim/decidim_awesome/version.rb +10 -0
  122. data/vendor/assets/images/layers-2x.png +0 -0
  123. data/vendor/assets/images/layers.png +0 -0
  124. data/vendor/assets/images/marker-icon.png +0 -0
  125. data/vendor/assets/javascripts/codemirror-4.inline-attachment.js +89 -0
  126. data/vendor/assets/javascripts/form-storage.js +824 -0
  127. data/vendor/assets/javascripts/highlight.min.js +44 -0
  128. data/vendor/assets/javascripts/image-resize.min.js +1 -0
  129. data/vendor/assets/javascripts/image-upload.min.js +6 -0
  130. data/vendor/assets/javascripts/inline-attachment.js +399 -0
  131. data/vendor/assets/javascripts/inscrybmde.min.js +7 -0
  132. data/vendor/assets/javascripts/jquery.inline-attachment.js +66 -0
  133. data/vendor/assets/javascripts/leaflet.featuregroup.subgroup.js +6 -0
  134. data/vendor/assets/stylesheets/default.min.css +1 -0
  135. data/vendor/assets/stylesheets/foundation.min.css +1 -0
  136. data/vendor/assets/stylesheets/github.min.css +2 -0
  137. data/vendor/assets/stylesheets/inscrybmde.min.css +8 -0
  138. metadata +267 -0
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ # This controller is the abstract class from which all other controllers of
6
+ # this engine inherit.
7
+ #
8
+ class ApplicationController < Decidim::ApplicationController
9
+ def permission_class_chain
10
+ [::Decidim::DecidimAwesome::Permissions] + super
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ # This controller handles image uploads for the hacked Quill editor
6
+ class EditorImagesController < DecidimAwesome::ApplicationController
7
+ include FormFactory
8
+ include NeedsAwesomeConfig
9
+
10
+ # overwrite original rescue_from to ensure we print messages from ajax methods (update)
11
+ rescue_from Decidim::ActionForbidden, with: :ajax_user_has_no_permission
12
+
13
+ def create
14
+ enforce_permission_to :create, :editor_image, awesome_config: awesome_config
15
+
16
+ @form = form(EditorImageForm).from_params(form_values)
17
+
18
+ CreateEditorImage.call(@form) do
19
+ on(:ok) do |image|
20
+ url = image.url
21
+ url = "#{request.base_url}#{url}" unless url&.start_with?("http")
22
+ render json: { url: url, message: I18n.t("decidim_awesome.editor_images.create.success", scope: "decidim") }
23
+ end
24
+
25
+ on(:invalid) do |_message|
26
+ render json: { message: I18n.t("decidim_awesome.editor_images.create.error", scope: "decidim") }, status: :unprocessable_entity
27
+ end
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ # Rescue ajax calls and print the update.js view which prints the info on the message ajax form
34
+ # Only if the request is AJAX, otherwise behave as Decidim standards
35
+ def ajax_user_has_no_permission
36
+ return user_has_no_permission unless request.xhr?
37
+
38
+ render json: { message: I18n.t("actions.unauthorized", scope: "decidim.core") }, status: :unprocessable_entity
39
+ end
40
+
41
+ def form_values
42
+ {
43
+ image: params[:image],
44
+ author_id: current_user.id,
45
+ path: request.original_fullpath
46
+ }
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ module IframeComponent
6
+ # This controller is the abstract class from which all other controllers of
7
+ # this engine inherit.
8
+ #
9
+ # Note that it inherits from `Decidim::Components::BaseController`, which
10
+ # override its layout and provide all kinds of useful methods.
11
+ class ApplicationController < Decidim::Components::BaseController
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ module IframeComponent
6
+ class IframeController < DecidimAwesome::IframeComponent::ApplicationController
7
+ ALLOWED_ATTRIBUTES = %w(src width height frameborder title allow allowpaymentrequest name referrerpolicy sandbox srcdoc allowfullscreen).freeze
8
+ helper_method :iframe, :remove_margins?, :viewport_width?
9
+
10
+ def show; end
11
+
12
+ private
13
+
14
+ def iframe
15
+ @iframe ||= sanitize(current_component.settings.iframe).html_safe
16
+ end
17
+
18
+ def sanitize(html)
19
+ sanitizer = Rails::Html::SafeListSanitizer.new
20
+ sanitizer.sanitize(html, tags: %w(iframe), attributes: ALLOWED_ATTRIBUTES)
21
+ end
22
+
23
+ def remove_margins?
24
+ current_component.settings.no_margins
25
+ end
26
+
27
+ def viewport_width?
28
+ current_component.settings.viewport_width
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ module MapComponent
6
+ # This controller is the abstract class from which all other controllers of
7
+ # this engine inherit.
8
+ #
9
+ # Note that it inherits from `Decidim::Components::BaseController`, which
10
+ # override its layout and provide all kinds of useful methods.
11
+ class ApplicationController < Decidim::Components::BaseController
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ module MapComponent
6
+ class MapController < DecidimAwesome::MapComponent::ApplicationController
7
+ helper Decidim::DecidimAwesome::MapHelper
8
+ helper_method :map_components
9
+
10
+ def show
11
+ render :error if Decidim.geocoder.blank?
12
+ end
13
+
14
+ private
15
+
16
+ def map_components
17
+ @map_components ||= current_participatory_space.components.published.filter do |component|
18
+ case component.manifest.name
19
+ when :meetings
20
+ true
21
+ when :proposals
22
+ component.settings.geocoding_enabled
23
+ else
24
+ false
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ module Admin
6
+ # A form object used to configure the endpoint.
7
+ #
8
+ class ConfigForm < Decidim::Form
9
+ attribute :allow_images_in_full_editor, Boolean
10
+ attribute :allow_images_in_small_editor, Boolean
11
+ attribute :allow_images_in_proposals, Boolean
12
+ attribute :use_markdown_editor, Boolean
13
+ attribute :allow_images_in_markdown_editor, Boolean
14
+ attribute :auto_save_forms, Boolean
15
+ attribute :intergram_for_admins, Boolean
16
+ attribute :intergram_for_admins_settings, IntergramForm
17
+ attribute :intergram_for_public, Boolean
18
+ attribute :intergram_for_public_settings, IntergramForm
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ module Admin
6
+ # A form object used to configure the endpoint.
7
+ #
8
+ class ConstraintForm < Decidim::Form
9
+ attribute :id, Integer
10
+ attribute :participatory_space_manifest, String
11
+ attribute :participatory_space_slug, String
12
+ attribute :component_manifest, String
13
+ attribute :component_id, Integer
14
+
15
+ validates :component_manifest, absence: true, if: ->(form) { form.component_id.present? || form.participatory_space_manifest == "system" }
16
+ validates :component_id, absence: true, if: ->(form) { form.component_manifest.present? }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ module Admin
6
+ # A form object used to configure the endpoint.
7
+ #
8
+ class IntergramForm < Decidim::Form
9
+ attribute :chat_id, String
10
+ attribute :require_login, Boolean
11
+ attribute :color, String
12
+ attribute :use_floating_button, Boolean
13
+ attribute :title_open, String
14
+ attribute :title_closed, String
15
+ attribute :intro_message, String
16
+ attribute :auto_response, String
17
+ attribute :auto_no_response, String
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ class EditorImageForm < Decidim::Form
6
+ mimic :editor_image
7
+
8
+ attribute :image
9
+ attribute :author_id, Integer
10
+ attribute :path, String
11
+
12
+ validates :author_id, presence: true
13
+ validates :image, presence: true
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ module Admin
6
+ module ConfigConstraintsHelpers
7
+ include Decidim::TranslatableAttributes
8
+
9
+ # returns only non :disabled vars in config
10
+ def enabled_configs(vars)
11
+ vars.filter do |var|
12
+ config_enabled? var
13
+ end
14
+ end
15
+
16
+ def config_enabled?(var)
17
+ return DecidimAwesome.config.send(var) != :disabled unless var.is_a? Array
18
+
19
+ var.detect { |v| DecidimAwesome.config.send(v) != :disabled }
20
+ end
21
+
22
+ def participatory_space_manifests
23
+ manifests = { system: I18n.t("decidim.decidim_awesome.admin.config.system") }
24
+ Decidim.participatory_space_manifests.pluck(:name).each do |name|
25
+ manifests[name.to_sym] = I18n.t("decidim.admin.menu.#{name}")
26
+ end
27
+ manifests
28
+ end
29
+
30
+ def component_manifests(space = nil)
31
+ return {} if space == "system"
32
+
33
+ Decidim.component_manifests.pluck(:name).map do |name|
34
+ [name.to_sym, I18n.t("decidim.components.#{name}.name")]
35
+ end.to_h
36
+ end
37
+
38
+ def participatory_spaces_list(manifest)
39
+ space = participatory_space_for_manifest(manifest)
40
+ return {} if space.blank?
41
+
42
+ space.where(organization: current_organization).map do |item|
43
+ [item.slug, translated_attribute(item.title)]
44
+ end.to_h
45
+ end
46
+
47
+ def components_list(manifest, slug)
48
+ space = participatory_space_for_manifest(manifest)
49
+ return {} if space.blank?
50
+
51
+ components = Component.where(participatory_space: space.find_by(slug: slug))
52
+ components.map do |item|
53
+ [item.id, "#{item.id}: #{translated_attribute(item.name)}"]
54
+ end.to_h
55
+ end
56
+
57
+ def translate_constraint_value(constraint, key)
58
+ value = constraint.settings[key]
59
+ case key.to_sym
60
+ when :participatory_space_manifest
61
+ participatory_space_manifests[value.to_sym] || value
62
+ when :participatory_space_slug
63
+ manifest = constraint.settings["participatory_space_manifest"]
64
+ participatory_spaces_list(manifest)[value] || value
65
+ when :component_manifest
66
+ component_manifests[value.to_sym] || value
67
+ when :component_id
68
+ component = Component.find_by(id: value)
69
+ return "#{component.id}: #{translated_attribute(component.name)}" if component
70
+
71
+ value
72
+ else
73
+ value
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ def participatory_space_for_manifest(manifest)
80
+ return nil if manifest.blank?
81
+
82
+ space = Decidim.find_participatory_space_manifest(manifest)
83
+ return nil unless space
84
+
85
+ space.model_class_name.constantize
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ # Custom helpers, scoped to the decidim_awesome engine.
6
+ #
7
+ module ApplicationHelper
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ module MapHelper
6
+ def dynamic_map_for(components)
7
+ return if Decidim.geocoder.blank?
8
+
9
+ map_html_options = {
10
+ class: "google-map",
11
+ id: "map",
12
+ "data-components" => components.map do |component|
13
+ {
14
+ id: component.id,
15
+ type: component.manifest.name,
16
+ name: translated_attribute(component.name),
17
+ url: Decidim::EngineRouter.main_proxy(component).root_path,
18
+ amendments: component.manifest.name == :proposals ? Decidim::Proposals::Proposal.where(component: component).only_emendations.count : 0
19
+ }
20
+ end.to_json,
21
+ "data-collapsed" => current_component.settings.collapse,
22
+ "data-markers-data" => [].to_json
23
+ }
24
+
25
+ if Decidim.geocoder[:here_api_key]
26
+ map_html_options["data-here-api-key"] = Decidim.geocoder[:here_api_key]
27
+ else
28
+ # Compatibility mode for old api_id/app_code configurations
29
+ map_html_options["data-here-app-id"] = Decidim.geocoder[:here_app_id]
30
+ map_html_options["data-here-app-code"] = Decidim.geocoder[:here_app_code]
31
+ end
32
+
33
+ content = capture { yield }.html_safe
34
+ help = content_tag(:div, class: "map__help") do
35
+ content_tag(:p, I18n.t("screen_reader_explanation", scope: "decidim.map.dynamic"), class: "show-for-sr")
36
+ end
37
+ content_tag :div, class: "awesome-map" do
38
+ map = content_tag(:div, "", map_html_options)
39
+
40
+ help + map + content
41
+ end
42
+ end
43
+
44
+ # rubocop:disable Rails/HelperInstanceVariable
45
+ def current_categories
46
+ return @current_categories if @current_categories
47
+
48
+ @golden_ratio_conjugate = 0.618033988749895
49
+ # @h = rand # use random start value
50
+ @h = 0.4
51
+ @current_categories = []
52
+ current_participatory_space.categories.first_class.each do |category|
53
+ append_category category
54
+ category.subcategories.each do |subcat|
55
+ append_category subcat
56
+ end
57
+ end
58
+ @current_categories
59
+ end
60
+
61
+ private
62
+
63
+ def append_category(category)
64
+ @h += @golden_ratio_conjugate
65
+ @h %= 1
66
+ # r,g,b = hsv_to_rgb(@h, 0.5, 0.95)
67
+ r, g, b = hsv_to_rgb(@h, 0.99, 0.96)
68
+ @current_categories.append(
69
+ id: category.id,
70
+ name: translated_attribute(category.name),
71
+ parent: category.parent&.id,
72
+ color: format("#%02x%02x%02x", r, g, b)
73
+ )
74
+ end
75
+ # rubocop:enable Rails/HelperInstanceVariable
76
+
77
+ # rubocop:disable Naming/UncommunicativeMethodParamName
78
+ # HSV values in [0..1[
79
+ # returns [r, g, b] values from 0 to 255
80
+ def hsv_to_rgb(h, s, v)
81
+ h_i = (h * 6).to_i
82
+ f = h * 6 - h_i
83
+ p = v * (1 - s)
84
+ q = v * (1 - f * s)
85
+ t = v * (1 - (1 - f) * s)
86
+ if h_i.zero?
87
+ r = v
88
+ g = t
89
+ b = p
90
+ end
91
+ if h_i == 1
92
+ r = q
93
+ g = v
94
+ b = p
95
+ end
96
+ if h_i == 2
97
+ r = p
98
+ g = v
99
+ b = t
100
+ end
101
+ if h_i == 3
102
+ r = p
103
+ g = q
104
+ b = v
105
+ end
106
+ if h_i == 4
107
+ r = t
108
+ g = p
109
+ b = v
110
+ end
111
+ if h_i == 5
112
+ r = v
113
+ g = p
114
+ b = q
115
+ end
116
+ [(r * 256).to_i, (g * 256).to_i, (b * 256).to_i]
117
+ end
118
+ # rubocop:enable Naming/UncommunicativeMethodParamName
119
+ end
120
+ end
121
+ end