decidim-core 0.26.7 → 0.26.9

Sign up to get free protection for your applications and to get access to all the features.
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: