decidim-core 0.26.7 → 0.26.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/collapsible_list/show.erb +1 -1
  3. data/app/cells/decidim/version_cell.rb +1 -1
  4. data/app/cells/decidim/versions_list_cell.rb +1 -1
  5. data/app/commands/decidim/endorse_resource.rb +2 -0
  6. data/app/commands/decidim/unendorse_resource.rb +1 -1
  7. data/app/controllers/decidim/authorization_modals_controller.rb +1 -1
  8. data/app/controllers/decidim/devise/registrations_controller.rb +1 -1
  9. data/app/controllers/decidim/links_controller.rb +1 -1
  10. data/app/controllers/decidim/user_timeline_controller.rb +1 -1
  11. data/app/forms/decidim/account_form.rb +1 -1
  12. data/app/forms/decidim/notifications_settings_form.rb +0 -8
  13. data/app/forms/decidim/registration_form.rb +1 -1
  14. data/app/forms/url_validator.rb +1 -1
  15. data/app/helpers/decidim/layout_helper.rb +15 -4
  16. data/app/helpers/decidim/resource_helper.rb +2 -0
  17. data/app/jobs/decidim/data_portability_export_job.rb +3 -0
  18. data/app/jobs/decidim/open_data_job.rb +2 -0
  19. data/app/models/decidim/organization.rb +6 -0
  20. data/app/models/decidim/user.rb +9 -1
  21. data/app/packs/src/decidim/geocoding/attach_input.js +4 -1
  22. data/app/packs/src/decidim/geocoding/provider/here.js +17 -21
  23. data/app/packs/src/decidim/geocoding/provider/photon.js +1 -1
  24. data/app/packs/src/decidim/map/controller/drag_marker.js +0 -2
  25. data/app/packs/src/decidim/map/controller/markers.js +0 -1
  26. data/app/packs/src/decidim/map/controller/static.js +0 -1
  27. data/app/packs/src/decidim/map/controller.js +0 -2
  28. data/app/packs/src/decidim/map/factory.js +4 -1
  29. data/app/packs/src/decidim/map/icon.js +0 -1
  30. data/app/packs/src/decidim/map/legacy.js +0 -1
  31. data/app/packs/src/decidim/map/provider/default.js +2 -0
  32. data/app/packs/src/decidim/map/provider/here.js +2 -1
  33. data/app/queries/decidim/metrics/users_metric_manage.rb +6 -6
  34. data/app/views/decidim/notifications_settings/show.html.erb +1 -1
  35. data/config/environment.rb +3 -0
  36. data/config/locales/ar.yml +10 -15
  37. data/config/locales/bg.yml +0 -16
  38. data/config/locales/ca.yml +15 -11
  39. data/config/locales/cs.yml +28 -9
  40. data/config/locales/de.yml +84 -46
  41. data/config/locales/el.yml +106 -12
  42. data/config/locales/en.yml +4 -0
  43. data/config/locales/eo.yml +5 -3
  44. data/config/locales/es-MX.yml +13 -9
  45. data/config/locales/es-PY.yml +15 -11
  46. data/config/locales/es.yml +14 -10
  47. data/config/locales/eu.yml +383 -343
  48. data/config/locales/fi-plain.yml +27 -2
  49. data/config/locales/fi.yml +17 -13
  50. data/config/locales/fr-CA.yml +13 -9
  51. data/config/locales/fr.yml +14 -10
  52. data/config/locales/ga-IE.yml +0 -5
  53. data/config/locales/gl.yml +6 -18
  54. data/config/locales/hu.yml +31 -14
  55. data/config/locales/id-ID.yml +4 -19
  56. data/config/locales/is-IS.yml +4 -3
  57. data/config/locales/it.yml +4 -9
  58. data/config/locales/ja.yml +35 -18
  59. data/config/locales/kaa.yml +4 -0
  60. data/config/locales/lb.yml +6 -11
  61. data/config/locales/lt.yml +53 -8
  62. data/config/locales/lv.yml +0 -16
  63. data/config/locales/nl.yml +2 -7
  64. data/config/locales/no.yml +5 -10
  65. data/config/locales/pl.yml +14 -5
  66. data/config/locales/pt-BR.yml +50 -7
  67. data/config/locales/pt.yml +2 -7
  68. data/config/locales/ro-RO.yml +1 -6
  69. data/config/locales/ru.yml +2 -17
  70. data/config/locales/sk.yml +13 -19
  71. data/config/locales/sl.yml +0 -5
  72. data/config/locales/sq-AL.yml +1 -0
  73. data/config/locales/sr-CS.yml +8 -0
  74. data/config/locales/sv.yml +23 -13
  75. data/config/locales/th-TH.yml +1 -0
  76. data/config/locales/tr-TR.yml +9 -11
  77. data/config/locales/uk.yml +2 -14
  78. data/config/locales/zh-CN.yml +0 -6
  79. data/config/locales/zh-TW.yml +16 -7
  80. data/db/migrate/20181030090144_destroy_deleted_users_follows.rb +1 -1
  81. data/db/migrate/20181204110723_remove_following_users_count_from_users.rb +11 -2
  82. data/db/migrate/20181214101250_add_notification_types_to_users.rb +6 -1
  83. data/db/migrate/20190412131728_fix_user_names.rb +13 -6
  84. data/db/migrate/20200211173227_add_direct_message_types_to_users.rb +6 -1
  85. data/db/migrate/20210302150803_invalidate_all_sessions_for_deleted_users.rb +10 -3
  86. data/db/migrate/20210310120640_add_followable_counter_cache_to_users.rb +13 -3
  87. data/db/migrate/20231027142329_change_default_value_for_decidim_endorsements.rb +11 -0
  88. data/db/seeds.rb +1 -0
  89. data/lib/decidim/core/test/shared_examples/comments_examples.rb +24 -0
  90. data/lib/decidim/core/test/shared_examples/errors.rb +2 -0
  91. data/lib/decidim/core/test/shared_examples/map_examples.rb +4 -1
  92. data/lib/decidim/core/version.rb +1 -1
  93. data/lib/decidim/core.rb +44 -1
  94. data/lib/decidim/dependency_resolver.rb +278 -0
  95. data/lib/decidim/endorsable.rb +1 -1
  96. data/lib/decidim/exporters.rb +10 -1
  97. data/lib/decidim/form_builder.rb +6 -13
  98. data/lib/tasks/upgrade/decidim_deduplicate_endorsements.rake +53 -0
  99. data/lib/tasks/upgrade/decidim_user_moderation.rake +14 -0
  100. metadata +13 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2d573b856227ec581d40d90cff9a85c1f21502a1ed6278b82aa9768a434f0e9c
4
- data.tar.gz: 2ca2fff70b6e6b9314450c35ab22965b3ba60af303a2839c7716e502cb566b3a
3
+ metadata.gz: b439f283c43183815f29f97ff9bf9098c8378b8a5cb16191390bd874e83cbb05
4
+ data.tar.gz: 117c9e1d3d6f9ac3dc55c5984e717c384e5274dc198babddc8ea7a1efe29e863
5
5
  SHA512:
6
- metadata.gz: 1000d09afe7e9af0586fa14c917c77a150bf9f55adee9d0a243744799a9cf9c84aa364b0f014cdec6eda3855c10b4b15772732c979d9f15e381c8a62e78aad8f
7
- data.tar.gz: 1a4feafaa713a4fa540aab815e0306f125cc74d45599d5defbec2e9dd2cce8bc6223acd0148424b3973a0f1d6853b96cd3ee9a6fda7ff45cc91073fd2b84ac8a
6
+ metadata.gz: 299d8bcecdf6084d93845ebcb256105c79077b2b6895f177dc22ddf296cf09973f92f5c425db5a078cb5e5eb9070f4e6ea6b3ad8e4c792236a6d567de7dc155d
7
+ data.tar.gz: 906b497e36d89c374d4f80114b5a6c4633d3a6da254832d26c8a9d22fa41c7dfc23fb5ce93ffcd1170e3e2f4caec1859c0e44c661a7dcc3567e31b75c969832c
@@ -16,7 +16,7 @@
16
16
  </span>
17
17
  </div>
18
18
  <% else %>
19
- <div class="collapsible-list <%= list_class %>">
19
+ <div class="<%= list_class %>">
20
20
  <% list.each do |element| %>
21
21
  <% if cell_name %>
22
22
  <%= cell cell_name, element, cell_options %>
@@ -77,7 +77,7 @@ module Decidim
77
77
  end
78
78
 
79
79
  def resource_path
80
- resource_locator(versioned_resource).path
80
+ Decidim::ResourceLocatorPresenter.new(versioned_resource).path
81
81
  end
82
82
  end
83
83
  end
@@ -13,7 +13,7 @@ module Decidim
13
13
  end
14
14
 
15
15
  def resource_path
16
- resource_locator(versioned_resource).path
16
+ Decidim::ResourceLocatorPresenter.new(versioned_resource).path
17
17
  end
18
18
 
19
19
  def i18n_changes_title
@@ -31,6 +31,8 @@ module Decidim
31
31
  else
32
32
  broadcast(:invalid)
33
33
  end
34
+ rescue ActiveRecord::RecordNotUnique
35
+ broadcast(:invalid)
34
36
  end
35
37
 
36
38
  private
@@ -31,7 +31,7 @@ module Decidim
31
31
  query = if @current_group.present?
32
32
  @resource.endorsements.where(decidim_user_group_id: @current_group&.id)
33
33
  else
34
- @resource.endorsements.where(author: @current_user, decidim_user_group_id: nil)
34
+ @resource.endorsements.where(author: @current_user, decidim_user_group_id: 0)
35
35
  end
36
36
  query.destroy_all
37
37
  end
@@ -17,7 +17,7 @@ module Decidim
17
17
  end
18
18
 
19
19
  def current_component
20
- @current_component ||= Decidim::Component.find(params[:component_id])
20
+ @current_component ||= Decidim::Component.where(participatory_space: current_organization.participatory_spaces).find(params[:component_id])
21
21
  end
22
22
 
23
23
  def authorization_action
@@ -37,7 +37,7 @@ module Decidim
37
37
  end
38
38
 
39
39
  on(:invalid) do
40
- flash.now[:alert] = @form.errors.full_messages.join(", ") if @form.errors.full_messages.any?
40
+ flash.now[:alert] = t("error", scope: "decidim.devise.registrations.create")
41
41
  render :new
42
42
  end
43
43
  end
@@ -35,7 +35,7 @@ module Decidim
35
35
  end
36
36
 
37
37
  def external_url
38
- @external_url ||= URI.parse(params[:external_url])
38
+ @external_url ||= URI.parse(URI::Parser.new.escape(params[:external_url]))
39
39
  end
40
40
  end
41
41
  end
@@ -12,7 +12,7 @@ module Decidim
12
12
  helper_method :activities, :resource_types, :user
13
13
 
14
14
  def index
15
- raise ActionController::RoutingError, "Not Found" if current_user != user
15
+ raise ActionController::RoutingError, "Not Found" unless user && current_user == user
16
16
  end
17
17
 
18
18
  private
@@ -24,7 +24,7 @@ module Decidim
24
24
  validates :nickname, presence: true, format: { with: Decidim::User::REGEXP_NICKNAME }
25
25
 
26
26
  validates :nickname, length: { maximum: Decidim::User.nickname_max_length, allow_blank: true }
27
- validates :password, confirmation: true
27
+ validates :password, confirmation: { message: I18n.t("errors.messages.password_confirmation_message") }
28
28
  validates :password, password: { name: :name, email: :email, username: :nickname }, if: -> { password.present? }
29
29
  validates :password_confirmation, presence: true, if: :password_present
30
30
  validates :avatar, passthru: { to: Decidim::User }
@@ -41,13 +41,5 @@ module Decidim
41
41
  def direct_message_types
42
42
  allow_public_contact ? "all" : "followed-only"
43
43
  end
44
-
45
- def user_is_moderator?(user)
46
- Decidim.participatory_space_manifests.map do |manifest|
47
- participatory_space_type = manifest.model_class_name.constantize
48
- return true if participatory_space_type.moderators(user.organization).exists?(id: user.id)
49
- end
50
- false
51
- end
52
44
  end
53
45
  end
@@ -17,7 +17,7 @@ module Decidim
17
17
  validates :name, presence: true, format: { with: Decidim::User::REGEXP_NAME }
18
18
  validates :nickname, presence: true, format: { with: Decidim::User::REGEXP_NICKNAME }, length: { maximum: Decidim::User.nickname_max_length }
19
19
  validates :email, presence: true, "valid_email_2/email": { disposable: true }
20
- validates :password, confirmation: true
20
+ validates :password, confirmation: { message: I18n.t("errors.messages.password_confirmation_message") }
21
21
  validates :password, password: { name: :name, email: :email, username: :nickname }
22
22
  validates :password_confirmation, presence: true
23
23
  validates :tos_agreement, allow_nil: false, acceptance: true
@@ -6,7 +6,7 @@
6
6
  #
7
7
  class UrlValidator < ActiveModel::EachValidator
8
8
  def validate_each(record, attribute, value)
9
- record.errors[attribute] << (options[:message] || "must be a valid URL") unless url_valid?(value)
9
+ record.errors.add attribute, :url_format, **options unless url_valid?(value)
10
10
  end
11
11
 
12
12
  # a URL may be technically well-formed but may
@@ -74,8 +74,11 @@ module Decidim
74
74
  classes = _icon_classes(options) + ["external-icon"]
75
75
 
76
76
  if path.split(".").last == "svg"
77
+ icon_path = application_path(path)
78
+ return unless icon_path
79
+
77
80
  attributes = { class: classes.join(" ") }.merge(options)
78
- asset = File.read(application_path(path))
81
+ asset = File.read(icon_path)
79
82
  asset.gsub("<svg ", "<svg#{tag_builder.tag_options(attributes)} ").html_safe
80
83
  else
81
84
  image_pack_tag(path, class: classes.join(" "), style: "display: none")
@@ -83,9 +86,17 @@ module Decidim
83
86
  end
84
87
 
85
88
  def application_path(path)
86
- img_path = asset_pack_path(path)
87
- img_path = URI(img_path).path if Decidim.cors_enabled
88
- Rails.root.join("public/#{img_path}")
89
+ # Force the path to be returned without the protocol and host even when a
90
+ # custom asset host has been defined. The host parameter needs to be a
91
+ # non-nil because otherwise it will be set to the asset host at
92
+ # ActionView::Helpers::AssetUrlHelper#compute_asset_host.
93
+ img_path = asset_pack_path(path, host: "", protocol: :relative)
94
+ path = Rails.public_path.join(img_path.sub(%r{^/}, ""))
95
+ return unless File.exist?(path)
96
+
97
+ path
98
+ rescue ::Webpacker::Manifest::MissingEntryError
99
+ nil
89
100
  end
90
101
 
91
102
  # Allows to create role attribute according to accessibility rules
@@ -67,6 +67,8 @@ module Decidim
67
67
 
68
68
  # Returns an instance of ResourceLocatorPresenter with the given resource
69
69
  def resource_locator(resource)
70
+ return resource.resource_locator if resource.respond_to?(:resource_locator)
71
+
70
72
  ::Decidim::ResourceLocatorPresenter.new(resource)
71
73
  end
72
74
 
@@ -13,6 +13,9 @@ module Decidim
13
13
  save_or_upload_file(user, path)
14
14
 
15
15
  ExportMailer.data_portability_export(user, filename, password).deliver_later
16
+
17
+ # Deletes temporary file
18
+ File.delete(path)
16
19
  end
17
20
 
18
21
  private
@@ -11,6 +11,8 @@ module Decidim
11
11
  raise "Couldn't generate Open Data export" unless exporter.export.positive?
12
12
 
13
13
  organization.open_data_file.attach(io: File.open(path, "rb"), filename: organization.open_data_file_path)
14
+ # Deletes the temporary file file
15
+ File.delete(path)
14
16
  end
15
17
  end
16
18
  end
@@ -87,6 +87,12 @@ module Decidim
87
87
  @top_scopes ||= scopes.top_level
88
88
  end
89
89
 
90
+ def participatory_spaces
91
+ @participatory_spaces ||= Decidim.participatory_space_manifests.flat_map do |manifest|
92
+ manifest.participatory_spaces.call(self)
93
+ end
94
+ end
95
+
90
96
  def public_participatory_spaces
91
97
  @public_participatory_spaces ||= Decidim.participatory_space_manifests.flat_map do |manifest|
92
98
  manifest.participatory_spaces.call(self).public_spaces
@@ -202,7 +202,7 @@ module Decidim
202
202
  end
203
203
 
204
204
  def admin_terms_accepted?
205
- return true if admin_terms_accepted_at
205
+ admin_terms_accepted_at.present?
206
206
  end
207
207
 
208
208
  # Whether this user can be verified against some authorization or not.
@@ -253,6 +253,14 @@ module Decidim
253
253
  Arel.sql(%{("decidim_users"."last_sign_in_at")::text})
254
254
  end
255
255
 
256
+ def moderator?
257
+ Decidim.participatory_space_manifests.map do |manifest|
258
+ participatory_space_type = manifest.model_class_name.constantize
259
+ return true if participatory_space_type.moderators(organization).exists?(id: id)
260
+ end
261
+ false
262
+ end
263
+
256
264
  protected
257
265
 
258
266
  # Overrides devise email required validation.
@@ -125,7 +125,10 @@ export default function attachGeocoding($input, options, callback) {
125
125
  $input.on("geocoder-suggest-coordinates.decidim", (_ev, coordinates) => {
126
126
  setCoordinates(coordinates);
127
127
  geocoded = true;
128
- callback(coordinates)
128
+ if (typeof callback === "function") {
129
+ callback(coordinates);
130
+ return;
131
+ }
129
132
  });
130
133
 
131
134
  // Set the initial values if the field defines the coordinates
@@ -34,26 +34,28 @@ $(() => {
34
34
  if (`${query}`.trim().length < queryMinLength) {
35
35
  return;
36
36
  }
37
-
37
+ // Changes to the autocomplete api call based on:
38
+ // https://developer.here.com/documentation/geocoding-search-api/migration_guide/migration-geocoder/topics-api/autocomplete.html
38
39
  currentSuggestionQuery = setTimeout(() => {
39
40
  $.ajax({
40
41
  method: "GET",
41
- url: "https://autocomplete.geocoder.ls.hereapi.com/6.2/suggest.json",
42
+ url: "https://autocomplete.search.hereapi.com/v1/autocomplete",
42
43
  data: {
43
44
  apiKey: config.apiKey,
44
- query: query,
45
- language: language
45
+ // eslint-disable-next-line
46
+ q: query,
47
+ lang: language
46
48
  },
47
49
  dataType: "json"
48
50
  }).done((resp) => {
49
- if (resp.suggestions) {
50
- return callback(resp.suggestions.map((item) => {
51
+ if (resp.items) {
52
+ return callback(resp.items.map((item) => {
51
53
  const label = generateAddressLabel(item.address, addressFormat);
52
54
 
53
55
  return {
54
56
  key: label,
55
57
  value: label,
56
- locationId: item.locationId
58
+ locationId: item.id
57
59
  }
58
60
  }));
59
61
  }
@@ -65,30 +67,24 @@ $(() => {
65
67
  $input.on("geocoder-suggest-select.decidim", (_ev, selectedItem) => {
66
68
  $.ajax({
67
69
  method: "GET",
68
- url: "https://geocoder.ls.hereapi.com/6.2/geocode.json",
70
+ url: "https://lookup.search.hereapi.com/v1/lookup",
69
71
  data: {
70
72
  apiKey: config.apiKey,
71
- gen: 9,
72
- jsonattributes: 1,
73
- locationid: selectedItem.locationId
73
+ id: selectedItem.locationId
74
74
  },
75
75
  dataType: "json"
76
76
  }).done((resp) => {
77
- if (!resp.response || !Array.isArray(resp.response.view) ||
78
- resp.response.view.length < 1
77
+ if (!resp || Object.keys(resp).length < 1
79
78
  ) {
80
79
  return;
81
80
  }
82
-
83
- const view = resp.response.view[0];
84
- if (!Array.isArray(view.result) || view.result.length < 1) {
85
- return;
81
+ const position = resp.position;
82
+ if (!position || !position.lat || !position.lng) {
83
+ return
86
84
  }
87
-
88
- const result = view.result[0];
89
85
  const coordinates = [
90
- result.location.displayPosition.latitude,
91
- result.location.displayPosition.longitude
86
+ position.lat,
87
+ position.lng
92
88
  ];
93
89
 
94
90
  $input.trigger(
@@ -59,7 +59,7 @@ $(() => {
59
59
  return {
60
60
  key: label,
61
61
  value: label,
62
- coordinates: item.geometry.coordinates
62
+ coordinates: item.geometry.coordinates.reverse()
63
63
  }
64
64
  }));
65
65
  }
@@ -1,6 +1,4 @@
1
- import * as L from "leaflet";
2
1
  import MapController from "src/decidim/map/controller"
3
- import "src/decidim/vendor/leaflet-tilelayer-here"
4
2
 
5
3
  export default class MapDragMarkerController extends MapController {
6
4
  start() {
@@ -1,5 +1,4 @@
1
1
  import "src/decidim/vendor/jquery-tmpl"
2
- import * as L from "leaflet";
3
2
  import MapController from "src/decidim/map/controller"
4
3
  import "leaflet.markercluster";
5
4
 
@@ -1,4 +1,3 @@
1
- import * as L from "leaflet";
2
1
  import MapController from "src/decidim/map/controller"
3
2
 
4
3
  const openLink = window.open;
@@ -1,5 +1,3 @@
1
- import * as L from "leaflet";
2
- import "src/decidim/map/icon"
3
1
  import MapControllerRegistry from "src/decidim/map/controller_registry"
4
2
 
5
3
  export default class MapController {
@@ -1,3 +1,5 @@
1
+ import "src/decidim/map/icon"
2
+
1
3
  import MapMarkersController from "src/decidim/map/controller/markers"
2
4
  import MapStaticController from "src/decidim/map/controller/static"
3
5
  import MapDragMarkerController from "src/decidim/map/controller/drag_marker"
@@ -22,7 +24,8 @@ import MapDragMarkerController from "src/decidim/map/controller/drag_marker"
22
24
  * window.Decidim.createMapController = (mapId, config) => {
23
25
  * if (config.type === "custom") {
24
26
  * // Obviously you need to implement CustomMapController for this to
25
- * // work.
27
+ * // work. You can find an example at:
28
+ * // decidim-dev/app/packs/src/decidim/dev/test/custom_map_factory.js
26
29
  * return new window.Decidim.CustomMapController(mapId, config);
27
30
  * }
28
31
  *
@@ -1,4 +1,3 @@
1
- import * as L from "leaflet";
2
1
  import { SVGIcon } from "leaflet-svgicon"
3
2
 
4
3
  L.DivIcon.SVGIcon = SVGIcon;
@@ -1,6 +1,5 @@
1
1
  /* eslint-disable require-jsdoc */
2
2
 
3
- import * as L from "leaflet";
4
3
  import "src/decidim/map/factory"
5
4
 
6
5
  /**
@@ -1,3 +1,5 @@
1
+ import "leaflet"
2
+
1
3
  /**
2
4
  * NOTE:
3
5
  * This has to load before decidim/map in order for it to apply correctly when
@@ -1,4 +1,5 @@
1
- import * as L from "leaflet"
1
+ import "leaflet"
2
+ import "src/decidim/vendor/leaflet-tilelayer-here"
2
3
 
3
4
  /**
4
5
  * NOTE:
@@ -11,15 +11,15 @@ module Decidim
11
11
  private
12
12
 
13
13
  def query
14
- return @query if @query
15
-
16
- @query = Decidim::User.where(organization: @organization)
17
- @query = @query.where("created_at <= ?", end_time)
18
- @query
14
+ @query ||= Decidim::User.where(organization: @organization)
15
+ .where("deleted_at IS NULL OR deleted_at > ?", end_time)
16
+ .where("blocked_at IS NULL OR blocked_at > ?", end_time)
17
+ .confirmed
18
+ .where("created_at <= ?", end_time)
19
19
  end
20
20
 
21
21
  def quantity
22
- @quantity ||= @query.where("created_at >= ?", start_time).count
22
+ @quantity ||= query.where("created_at >= ?", start_time).count
23
23
  end
24
24
  end
25
25
  end
@@ -45,7 +45,7 @@
45
45
  </label>
46
46
  </div>
47
47
 
48
- <% if @notifications_settings.user_is_moderator?(current_user) %>
48
+ <% if current_user.moderator? %>
49
49
  <p><strong><%= t(".administrators") %></strong></p>
50
50
  <div class="switch tiny switch-with-label email_on_moderations">
51
51
  <label>
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Empty line for playing nice with tpope/vim-rails
@@ -391,7 +391,7 @@ ar:
391
391
  request_confirmation_instructions: طلب تعليمات التأكيد
392
392
  title: تأكيد البريد الإلكتروني
393
393
  show:
394
- close_modal: إغلاق مشروط
394
+ close_modal: اغلاق النموذج
395
395
  block_user_mailer:
396
396
  notify:
397
397
  body_1: تم حظر الحساب الخاص بك.
@@ -514,9 +514,8 @@ ar:
514
514
  already_have_an_account?: هل لديك حساب؟
515
515
  newsletter: تلقي رسالة إخبارية من حين لآخر مع المعلومات ذات الصلة
516
516
  newsletter_title: الاتصال إذن
517
- nickname_help: الاسم المستعار الخاص بك في %{organization}. يمكن أن يحتوي فقط على أحرف وأرقام، و '-' و '_'.
517
+ nickname_help: الاسم المستعار الخاص بك في %{organization}. يمكن أن يحتوي فقط على أحرف وأرقام '-' و '_'.
518
518
  password_help: "%{minimun_characters} أحرف كحد أدنى، يجب أن لا تكون شائعة جدا (مثل 123456) ويجب أن تكون مختلفة عن اسمك المستعار وعن بريدك الإلكتروني."
519
- sign_in: تسجيل الدخول
520
519
  sign_up: انشئ حسابًا
521
520
  sign_up_as:
522
521
  legend: الاشتراك باسم
@@ -537,7 +536,7 @@ ar:
537
536
  newsletter_modal:
538
537
  buttons:
539
538
  check: تحقق واستمر
540
- close_modal: إغلاق مشروط
539
+ close_modal: اغلاق النموذج
541
540
  uncheck: إبقاءه غير مختار
542
541
  notice: |-
543
542
  <p>مهلا ، هل أنت متأكد أنك لا تريد تلقي رسالة إخبارية؟<br>
@@ -574,7 +573,7 @@ ar:
574
573
  success: تم تحميل الصورة بنجاح
575
574
  drag_and_drop_help: يمكن إضافة صور عن طريق سحبها وإسقاطها أو لصقها.
576
575
  endorsable:
577
- endorsements: موافقات
576
+ endorsements: الدعم والتأييد
578
577
  endorsements_count: عد أصوات التأييدات
579
578
  endorsements:
580
579
  identities:
@@ -921,7 +920,7 @@ ar:
921
920
  body_1: أنت على وشك زيارة رابط خارجي ونرجو منك أن تتحلى بالحذر فيما يتعلق بالمحتوى الموجود في الموقع الخارجي.
922
921
  body_2: الرجاء التحقق من الرابط الذي توشك على زيارته والتأكد من التعرف عليه كموقع آمن قبل المتابعة.
923
922
  cancel: إلغاء
924
- close_modal: إغلاق مشروط
923
+ close_modal: اغلاق النموذج
925
924
  proceed: المواصلة
926
925
  title: فتح رابط خارجي
927
926
  log:
@@ -1011,7 +1010,7 @@ ar:
1011
1010
  ok: حسناً
1012
1011
  index:
1013
1012
  ago: منذ
1014
- close: إغلاق مشروط
1013
+ close: اغلاق النموذج
1015
1014
  from: من
1016
1015
  groups: فِرَقي
1017
1016
  last_message: آخر رسالة
@@ -1143,7 +1142,6 @@ ar:
1143
1142
  proposals: اقتراحات
1144
1143
  proposals_explanation: تقديم مقترحات ، ودعم المقترحات الحالية وتعزيز التغييرات التي تريد رؤيتها.
1145
1144
  footer_sub_hero:
1146
- footer_sub_hero_body: دعونا نبني مجتمعًا أكثر انفتاحًا وشفافية وتعاونًا.<br /> انضموا وشاركوا وقرّروا.
1147
1145
  footer_sub_hero_headline: مرحبًا بكم على المنصة التشاركية لـ %{organization}.
1148
1146
  register: تسجيل
1149
1147
  hero:
@@ -1174,7 +1172,7 @@ ar:
1174
1172
  refuse:
1175
1173
  modal_body: إذا رفضت ، فلن تتمكن من استخدام النظام الأساسي ، يمكنك <a href="%{data_portability_path}">تنزيل بياناتك</a> و / أو <a href="%{delete_path}">حذف حسابك</a>.
1176
1174
  modal_btn_exit: سأراجعها لاحقًا
1177
- modal_close: إغلاق مشروط
1175
+ modal_close: اغلاق النموذج
1178
1176
  modal_title: هل ترفض حقًا الأحكام والشروط المحدثة؟
1179
1177
  required_review:
1180
1178
  alert: لقد قمنا بتحديث شروط الخدمة الخاصة بنا ، يرجى مراجعتها.
@@ -1268,7 +1266,7 @@ ar:
1268
1266
  future: مستقبل
1269
1267
  past: الماضي
1270
1268
  filters_small_view:
1271
- close_modal: إغلاق مشروط
1269
+ close_modal: اغلاق النموذج
1272
1270
  filter: منقي
1273
1271
  filter_by: مصنف بواسطة
1274
1272
  unfold: كشف
@@ -1376,7 +1374,7 @@ ar:
1376
1374
  index:
1377
1375
  add_max_users: 'يمكن إضافة مستخدمين إلى المحادثة: 9 مستخدمين كحد أقصى'
1378
1376
  add_users_placeholder: البحث…
1379
- close: غلق
1377
+ close: قريب
1380
1378
  conversations_info: المحادثات خاصة. لا يمكن لأحد آخر أن يراها. يمكن بدء محادثة مع أي مشارك أو مجموعة مسجلة على المنصة.
1381
1379
  from: من
1382
1380
  last_message: آخر رسالة
@@ -1397,7 +1395,7 @@ ar:
1397
1395
  back: عرض كافة المحادثات
1398
1396
  deleted_accounts: لا يمكن أن يكون لديك محادثة مع حسابات محذوفة.
1399
1397
  not_allowed: هذا المستخدم لم يعد يستقبل المزيد من الرسائل المباشرة.
1400
- title: محادثة مع %{usernames}
1398
+ title: المحادثة مع %{usernames}
1401
1399
  update:
1402
1400
  error: لم يتم إرسال الرسالة. حاول مرة أخرى في وقت لاحق
1403
1401
  user_interests:
@@ -1564,8 +1562,6 @@ ar:
1564
1562
  updated: تم تحديث حسابك بنجاح.
1565
1563
  sessions:
1566
1564
  already_signed_out: تم الخروج بنجاح
1567
- new:
1568
- sign_in: تسجيل الدخول
1569
1565
  signed_in: تم تسجيل الدخول بنجاح
1570
1566
  signed_out: تم الخروج بنجاح
1571
1567
  shared:
@@ -1574,7 +1570,6 @@ ar:
1574
1570
  didn_t_receive_confirmation_instructions: لم تتلق تعليمات التأكيد؟
1575
1571
  didn_t_receive_unlock_instructions: لم تتلق تعليمات فتح؟
1576
1572
  forgot_your_password: نسيت رقمك السري؟
1577
- sign_in: تسجيل الدخول
1578
1573
  sign_in_with_provider: تسجيل الدخول مع %{provider}
1579
1574
  sign_up: انشئ حسابًا
1580
1575
  minimum_password_length: