thredded 1.0.1 → 1.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c38b0b431b19a2a3bcb74955be64a67835d60870754e65436e8498ca67729bc8
4
- data.tar.gz: 1b9827d5ed79af58f52c86e5badb430e1b44dfaff0381fde2390ad08ce436b26
3
+ metadata.gz: 53eeae82b8abf67177c93f92831dcecda9a990cccd1c4900ffd40a05be37a5ff
4
+ data.tar.gz: 5b94b5078dc8def361b488d0228ce06d99e111186ac1fd68da71cdd2fe4cff2a
5
5
  SHA512:
6
- metadata.gz: 43a2362878a9949d88097d77efe90c7997483e1c70f0fb505ffff1fa06e2097036d6ae6aff829120a406bac06b9e1cbb0879c1b614cf0c8205f837044a6fb105
7
- data.tar.gz: 6f59d7de62c088da6ef53bb474ab02bdc666313ff5e050f86c3a1414a7371d93d60874008dc2ce68b8df8a7601754fe9771fef1804e11e1a4060620968465917
6
+ metadata.gz: 6cb15fbeeb5e7820586999d00e041434d0b79ffced361495a070e6fce800d0bef2daa01de84c01d25769f5040bc7390cb212af00401665a2d41bb4001d6173d8
7
+ data.tar.gz: 662c8ee0e71117f274275e94f0c6e86372ff5cc29aa5256f27bdec6ed0e15c5af1053322dd3551c6ad5fca2748e413bbe5f2d34e31573e6a5d1d3705f20e164e
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
- # Thredded [![Code Climate](https://codeclimate.com/github/thredded/thredded/badges/gpa.svg)](https://codeclimate.com/github/thredded/thredded) [![Travis-CI](https://api.travis-ci.org/thredded/thredded.svg?branch=main)](https://travis-ci.org/thredded/thredded/) [![Test Coverage](https://codeclimate.com/github/thredded/thredded/badges/coverage.svg)](https://codeclimate.com/github/thredded/thredded/coverage) [![Inline docs](http://inch-ci.org/github/thredded/thredded.svg?branch=main)](http://inch-ci.org/github/thredded/thredded) [![Gitter](https://badges.gitter.im/thredded/thredded.svg)](https://gitter.im/thredded/thredded?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
1
+ # Thredded
2
+ [![Code Climate](https://codeclimate.com/github/thredded/thredded/badges/gpa.svg)](https://codeclimate.com/github/thredded/thredded) [![Test Coverage](https://codeclimate.com/github/thredded/thredded/badges/coverage.svg)](https://codeclimate.com/github/thredded/thredded/coverage) [![Inline docs](http://inch-ci.org/github/thredded/thredded.svg?branch=main)](http://inch-ci.org/github/thredded/thredded) [![Gitter](https://badges.gitter.im/thredded/thredded.svg)](https://gitter.im/thredded/thredded?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
3
+ [![CI](https://github.com/thredded/thredded/actions/workflows/build.yml/badge.svg)](https://github.com/thredded/thredded/actions/workflows/build.yml)
2
4
 
3
- _Thredded_ is a Rails 5.2+ forum/messageboard engine. Its goal is to be as simple and feature rich as possible.
5
+ _Thredded_ is a Rails 7.0+ forum/messageboard engine. Its goal is to be as simple and feature rich as possible.
4
6
 
5
7
  Some of the features currently in Thredded:
6
8
 
@@ -21,10 +23,10 @@ Some of the features currently in Thredded:
21
23
 
22
24
  Thredded works with SQLite, MySQL (v5.6.4+), and PostgreSQL. Thredded has no infrastructure
23
25
  dependencies other than the database and, if configured in the parent application, the ActiveJob
24
- backend dependency such as Redis. Currently only MRI Ruby 2.2+ is supported. We would love to
26
+ backend dependency such as Redis. Currently only MRI Ruby 3.1+ is supported. We would love to
25
27
  support JRuby and Rubinius as well.
26
28
 
27
- If you're looking for variations on a theme - see [Discourse]. However, It is a full rails
29
+ If you're looking for variations on a theme - see [Discourse]. However, it is a full rails
28
30
  application and not an engine like Thredded.
29
31
 
30
32
  [Discourse]: http://www.discourse.org/
@@ -38,6 +40,7 @@ Table of Contents
38
40
  * [Adding Thredded to an existing Rails app](#adding-thredded-to-an-existing-rails-app)
39
41
  * [Upgrading an existing install](#upgrading-an-existing-install)
40
42
  * [Migrating from Forem](#migrating-from-forem)
43
+ * [Rails compatibility](#rails-compatibility)
41
44
  * [Views and other assets](#views-and-other-assets)
42
45
  * [Standalone layout](#standalone-layout)
43
46
  * [Application layout](#application-layout)
@@ -77,7 +80,15 @@ Table of Contents
77
80
 
78
81
  ### Creating a new Rails app with Thredded
79
82
 
80
- Thredded provides an app generator that will generate a Rails app with Thredded, Devise, SimpleForm, RSpec,
83
+ > [!CAUTION]
84
+ > Please add thredded_create_app is currently out of date and needs contributors to fix it - it won't work with the latest thredded. See https://github.com/thredded/thredded_create_app if you can contribute.
85
+
86
+ <details>
87
+ <summary>
88
+ View the outdated instructions
89
+ </summary>
90
+
91
+ Thredded provides an app generator that will generate a Rails app with Thredded, Devise, SimpleForm, RSpec,
81
92
  PostgreSQL, and a basic theme and navigation that is configured to work out of the box.
82
93
 
83
94
  ```sh
@@ -91,12 +102,14 @@ Then, see the rest of this Readme for more information about using and customizi
91
102
 
92
103
  [thredded_create_app repo]: https://github.com/thredded/thredded_create_app
93
104
 
105
+ </details>
106
+
94
107
  ### Adding Thredded to an existing Rails app
95
108
 
96
109
  Add the gem to your Gemfile:
97
110
 
98
111
  ```ruby
99
- gem 'thredded', '~> 1.0'
112
+ gem 'thredded', '~> 1.2'
100
113
  ```
101
114
 
102
115
  Add the Thredded [initializer] to your parent app by running the install generator.
@@ -155,6 +168,17 @@ to Thredded.
155
168
  [forem-to-thredded]: https://github.com/thredded/thredded/wiki/Migrate-from-Forem
156
169
  [Forem]: https://github.com/rubysherpas/forem
157
170
 
171
+ ## Rails compatibility
172
+
173
+ | Rails | Latest Thredded |
174
+ |-----------------------|-----------------|
175
+ | Rails 7.0 - Rails 8.0 | Thredded 1.2 |
176
+ | Rails 6.1 | Thredded 1.1 |
177
+ | Rails 6.0 | Thredded 1.1 |
178
+ | Rails 5.2 | Thredded 1.0.1 |
179
+ | Rails 4.2 | Thredded 0.16.16 |
180
+
181
+
158
182
  ## Views and other assets
159
183
 
160
184
  ### Standalone layout
@@ -247,8 +271,7 @@ which are placed in the same order as in the source).
247
271
 
248
272
  <details><summary><b>Rails UJS version</b></summary>
249
273
 
250
- By default, thredded loads `rails-ujs`. If you're using Rails before v5.1, you need to add `rails-ujs` to
251
- your Gemfile.
274
+ By default, thredded loads `rails-ujs`.
252
275
 
253
276
  If you'd like it to use `jquery_ujs` instead, run this command from your app directory:
254
277
 
@@ -322,7 +345,7 @@ Whenever possible, use the styles and i18n to customize Thredded to your needs.
322
345
  Thredded provides view hooks to customize the UI before/after/replacing individual components.
323
346
 
324
347
  View hooks allow you to render anything in the thredded view context.
325
- For example, to render a partial after the post content textarea, add the snippet below to
348
+ For example, to render a partial after the post content textarea, add the snippet below to
326
349
  the `config/initializers/thredded.rb` initializer:
327
350
 
328
351
  ```ruby
@@ -383,7 +406,7 @@ You can also turn off the email notifier totally, or add other notifiers (e.g. P
383
406
  the `Thredded.notifiers` configuration in your initializer. See the default initializer for examples.
384
407
 
385
408
  You must configure the address the email appears to be from (`Thredded.email_from`). This address is also used as the "To" address for both email notifcations, as all the recipients are on bcc.
386
-
409
+
387
410
  ### Enabling auto-follow
388
411
 
389
412
  In some cases, you'll want all users to auto-follow new messageboard topics by default. This might be useful
@@ -413,16 +436,16 @@ Here are the steps to ensure the best support for your language if it isn't Engl
413
436
  //= require timeago/locales/de
414
437
  //= require timeago/locales/pt_BR
415
438
  //= require thredded
416
- ```
417
-
439
+ ```
440
+
418
441
  Webpack:
419
-
442
+
420
443
  ```erb
421
444
  <% timeago_root = File.join(Gem.loaded_specs['timeago_js'].full_gem_path, 'assets', 'javascripts') %>
422
445
  import "<%= File.join(timeago_root, 'timeago.js') %>";
423
446
  <%= %w[de pt_BR].map { |locale| %(import "#{File.join(timeago_root, "timeago/locales/#{locale}.js")}";) } * "\n" %>
424
447
  <%= Thredded::WebpackAssets.javascripts %>
425
- ```
448
+ ```
426
449
 
427
450
  Note that it is important that timeago and its locales are required *before* Thredded.
428
451
 
@@ -596,8 +619,6 @@ Rails.application.config.to_prepare do
596
619
  Thredded::ApplicationController.module_eval do
597
620
  # Require authentication to access the forums:
598
621
  before_action :thredded_require_login!
599
- # NB: in rails 4.2 you will need to change this to:
600
- # before_action { thredded_require_login! }
601
622
 
602
623
  # You may also want to render a login form after the
603
624
  # "Please sign in first" message:
@@ -693,9 +714,9 @@ brew install --cask chromium
693
714
  brew install --cask chromedriver
694
715
  ```
695
716
 
696
- To get better page saves (`page.save_and_open_page`) from local capybara specs ensure you are running the server locally
697
- and set `export CAPYBARA_ASSET_HOST=http://localhost:3000` (or whatever host/port your server is on) before running your
698
- test suite.
717
+ To get better page saves (`page.save_and_open_page`) from local capybara specs ensure you are running the server locally
718
+ and set `export CAPYBARA_ASSET_HOST=http://localhost:3000` (or whatever host/port your server is on) before running your
719
+ test suite.
699
720
 
700
721
  ### Ruby
701
722
 
@@ -788,25 +809,23 @@ To quickly try out _Thredded_ with the included dummy app, clone the source and
788
809
  start the included docker-compose.yml file with:
789
810
 
790
811
  ```console
791
- docker-compose build
792
- docker-compose up
812
+ docker compose build
813
+ docker compose up
793
814
  ```
794
815
 
795
816
  The above will build and run everything, daemonized, resulting in a running
796
- instance on port 9292. Running `docker-compose logs` will let you know when
817
+ instance on port 9292. Running `docker compose logs` will let you know when
797
818
  everything is up and running. Editing the source on your host machine will
798
819
  be reflected in the running docker'ized application.
799
820
 
800
- Note that when using [boot2docker](https://github.com/boot2docker/boot2docker)
801
- on a Mac make sure you visit the boot2docker host ip at
802
- `http://$(boot2docker ip):9292`.
803
-
804
- After booting up the containers you can run the test suite with the following:
821
+ You can run the test suite with the following (assuming you've already done `docker compose up`)
805
822
 
806
823
  ```console
807
- docker-compose run web bundle exec rake
824
+ docker compose exec web bundle exec rake
808
825
  ```
809
826
 
810
- The docker container uses PostgreSQL.
827
+ Alternatively you run a one-off dyno `docker compose run web bundle exec rake`
828
+
829
+ The docker container uses PostgreSQL
811
830
 
812
831
  [initializer]: https://github.com/thredded/thredded/blob/main/lib/generators/thredded/install/templates/initializer.rb
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Thredded
4
4
  module UrlsHelper # rubocop:disable Metrics/ModuleLength
5
+ include Thredded::Engine.routes.url_helpers
6
+
5
7
  class << self
6
8
  include Thredded::Engine.routes.url_helpers
7
9
  include Thredded::UrlsHelper
@@ -7,7 +7,7 @@ module Thredded
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  included do
10
- enum moderation_state: %i[pending_moderation approved blocked]
10
+ enum :moderation_state, { pending_moderation: 0, approved: 1, blocked: 2 }
11
11
  validates :moderation_state, presence: true
12
12
  end
13
13
  end
@@ -15,7 +15,7 @@ module Thredded
15
15
  @scope = @scope.joins(:topic_categories).merge(Thredded::TopicCategory.where(category_id: categories))
16
16
  end
17
17
  if text.present? || users.present?
18
- [search_topics, search_posts].compact.reduce(:union)
18
+ Thredded::Topic.union_scope(search_topics, search_posts)
19
19
  else
20
20
  @scope
21
21
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ # simplified version of active_record_union https://github.com/brianhempel/active_record_union/blob/master/lib/active_record_union/active_record/relation/union.rb
4
+
5
+ module Thredded
6
+ module UnionScope
7
+ extend ActiveSupport::Concern
8
+ class_methods do
9
+ # @param left_relation [ActiveRecord::Relation]
10
+ # @param right_relation [ActiveRecord::Relation]
11
+ # @return [ActiveRecord::Relation]
12
+ def union_scope(left_relation, right_relation)
13
+ verify_relations!(left_relation, right_relation)
14
+ union_set = ArelCompat.union_new(self, left_relation.arel, right_relation.arel)
15
+ from_table = Arel::Nodes::TableAlias.new(union_set, arel_table.name)
16
+ unscoped.from(from_table)
17
+ end
18
+
19
+ private
20
+
21
+ def verify_relations!(left_relation, right_relation)
22
+ relations = [left_relation, right_relation]
23
+ includes_relations = relations.select { |r| r.includes_values.any? }
24
+
25
+ fail ArgumentError, 'Cannot union relation with includes.' if includes_relations.any?
26
+
27
+ preload_relations = relations.select { |r| r.preload_values.any? }
28
+ fail ArgumentError, 'Cannot union relation with preload.' if preload_relations.any?
29
+
30
+ eager_load_relations = relations.select { |r| r.eager_load_values.any? }
31
+ return unless eager_load_relations.any?
32
+
33
+ fail ArgumentError, 'Cannot union relation with eager load.'
34
+ end
35
+ end
36
+ end
37
+ end
@@ -3,7 +3,9 @@
3
3
  module Thredded
4
4
  class PostModerationRecord < ActiveRecord::Base
5
5
  include Thredded::ModerationState
6
- enum previous_moderation_state: moderation_states, _prefix: :previous
6
+
7
+ enum :previous_moderation_state, moderation_states, prefix: :previous
8
+
7
9
  validates :previous_moderation_state, presence: true
8
10
 
9
11
  scope :order_newest_first, -> { order(created_at: :desc, id: :desc) }
@@ -4,6 +4,7 @@ module Thredded
4
4
  class Topic < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
5
5
  include Thredded::TopicCommon
6
6
  include Thredded::ContentModerationState
7
+ include Thredded::UnionScope
7
8
 
8
9
  scope :for_messageboard, ->(messageboard) { where(messageboard_id: messageboard.id) }
9
10
 
@@ -85,6 +86,8 @@ module Thredded
85
86
 
86
87
  delegate :name, to: :messageboard, prefix: true
87
88
 
89
+ before_create :ensure_last_post_at
90
+
88
91
  after_commit :update_messageboard_last_topic, on: :update, if: -> { previous_changes.include?('moderation_state') }
89
92
  after_commit :update_last_user_and_time_from_last_post!, if: -> { previous_changes.include?('moderation_state') }
90
93
 
@@ -203,5 +206,9 @@ module Thredded
203
206
  Thredded::Messageboard.find(messageboard_id).update_last_topic!
204
207
  end
205
208
  end
209
+
210
+ def ensure_last_post_at
211
+ self.last_post_at ||= Time.zone.now
212
+ end
206
213
  end
207
214
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Thredded
4
4
  class UserTopicFollow < ActiveRecord::Base
5
- enum reason: %i[manual posted mentioned auto]
5
+ enum :reason, { manual: 0, posted: 1, mentioned: 2, auto: 3 }
6
6
 
7
7
  belongs_to :user, inverse_of: :thredded_topic_follows, class_name: Thredded.user_class_name
8
8
  belongs_to :topic, inverse_of: :user_follows
@@ -12,7 +12,8 @@ module Thredded
12
12
 
13
13
  # shim to behave like postable-related (though actually only ever related to topic)
14
14
  alias_attribute :postable_id, :topic_id
15
- alias_attribute :postable, :topic
15
+ alias postable topic
16
+ alias postable= topic=
16
17
 
17
18
  # Creates a follow or finds the existing one.
18
19
  #
@@ -9,6 +9,7 @@ module Thredded
9
9
  :empty?,
10
10
  :[],
11
11
  :each,
12
+ :each_with_index,
12
13
  :map,
13
14
  :size,
14
15
  to: :@topic_views
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # exit on first failure
4
+ set -e
5
+ for i in {1..10}
6
+ do
7
+ echo "#$i (rspec $1)"
8
+ bundle exec rspec --format d $1 --fail-fast
9
+ done
@@ -0,0 +1,284 @@
1
+ ---
2
+ uk:
3
+ thredded:
4
+ content_moderation_states:
5
+ content_blocked_notice: Заблоковано
6
+ content_blocked_notice_with_record_html: Заблоковано користувачем %{moderator} %{time_ago}
7
+ email_notifier:
8
+ by_email: електронною поштою
9
+ emails:
10
+ message_notification:
11
+ html:
12
+ email_sent_reason_html: >-
13
+ Цей електронний лист надіслано вам, оскільки %{user} включив вас до приватної теми "<a href="%{post_url}">%{topic_title}</a>".
14
+ post_lead_html: 'Нове повідомлення від %{user} в <a href="%{post_url}">«%{topic_title}»</a>:'
15
+ unsubscribe_instructions_html: :thredded.emails.post_notification.html.unsubscribe_instructions_html
16
+ subject: Нове повідомлення від %{user} в «%{topic_title}»
17
+ text:
18
+ email_sent_reason: |-
19
+ Цей електронний лист надіслано вам, оскільки %{user} включив вас до
20
+ приватної теми «%{topic_title}».
21
+
22
+ Перейдіть сюди, щоб переглянути розмову:
23
+ %{post_url}
24
+ post_lead: 'Нове повідомлення від %{user} в «%{topic_title}»:'
25
+ unsubscribe_instructions: :thredded.emails.post_notification.text.unsubscribe_instructions
26
+ post_notification:
27
+ html:
28
+ email_sent_reason_html: >-
29
+ Цей електронний лист надіслано вам, оскільки ви стежите за цією темою: "<a href="%{post_url}">%{topic_title}</a>".
30
+ post_lead_html: '%{user} <a href="%{post_url}">написав у «%{topic_title}»</a>:'
31
+ unsubscribe_instructions_html: Щоб відписатися від цих електронних листів, оновіть свої <a href="%{preferences_url}">налаштування</a>.
32
+ subject: Новий допис у «%{topic_title}»
33
+ text:
34
+ email_sent_reason: |-
35
+ Цей електронний лист надіслано вам, оскільки ви стежите за
36
+ темою «%{topic_title}».
37
+
38
+ Перейдіть сюди, щоб переглянути розмову:
39
+ %{post_url}
40
+ post_lead: "%{user} написав у «%{topic_title}»:"
41
+ unsubscribe_instructions: |-
42
+ Щоб відписатися від цих електронних листів, оновіть свої налаштування тут:
43
+ %{unsubscribe_url}
44
+ errors:
45
+ login_required: Будь ласка, увійдіть спочатку.
46
+ not_authorized: Ви не маєте дозволу на доступ до цієї сторінки.
47
+ post_not_found: Цей допис не існує.
48
+ private_post_not_found: Це приватне повідомлення не існує.
49
+ private_topic_create_denied: Ви не маєте дозволу на створення приватних тем.
50
+ private_topic_not_found: Ця приватна тема не існує.
51
+ topic_not_found: Ця тема не існує.
52
+ form:
53
+ create_btn_submitting: Створення...
54
+ preview: Попередній перегляд
55
+ update: Оновити
56
+ update_btn_submitting: Оновлення...
57
+ messageboard:
58
+ create: Створити нову дошку повідомлень
59
+ deleted_notice: Дошку повідомлень видалено
60
+ form:
61
+ create_btn_submitting: :thredded.form.create_btn_submitting
62
+ delete: Видалити дошку повідомлень
63
+ delete_confirm: >-
64
+ Це видалить дошку повідомлень %{messageboard_name} та всі її дописи. Ви не зможете відновити її. Ви впевнені,
65
+ що хочете це зробити?
66
+ description_label: Опис
67
+ locked_label: Заблоковано
68
+ locked_notice: Ця дошка повідомлень заблокована. Лише модератори можуть створювати нові теми тут.
69
+ messageboard_group_id_label: Група дошки повідомлень
70
+ no_group: Без групи
71
+ title_label: Назва
72
+ update_btn_submitting: :thredded.form.update_btn_submitting
73
+ index:
74
+ page_title: Дошки повідомлень
75
+ last_updated_by_html: Оновлено %{time_ago} <cite>користувачем %{user}</cite>
76
+ topics_and_posts_counts: "%{posts_count} дописів у %{topics_count} темах"
77
+ topics_and_unread_topics_counts: "%{unread_topics_count} непрочитаних з %{topics_count} тем"
78
+ update: :thredded.form.update
79
+ updated_notice: Дошку повідомлень оновлено
80
+ messageboard_first_topic:
81
+ content: |-
82
+ Поки що тут не так багато.
83
+
84
+ Ці форуми працюють на [Thredded](https://github.com/thredded/thredded) v%{thredded_version}.
85
+ Ви можете зв'язатися з командою Thredded через [чат-кімнату Thredded](https://gitter.im/thredded/thredded).
86
+ Будь ласка, повідомте нам, що ви використовуєте Thredded, твітнувши [@thredded](https://twitter.com/thredded)!
87
+ title: Ласкаво просимо до першої теми вашої дошки повідомлень
88
+ messageboard_group:
89
+ create: Створити нову групу дошок повідомлень
90
+ form:
91
+ create_btn_submitting: :thredded.form.create_btn_submitting
92
+ saved: Групу дошок повідомлень %{name} створено
93
+ show:
94
+ page_title: 'Група дошок повідомлень: %{name}'
95
+ moderation:
96
+ approve_btn: Схвалити
97
+ block_btn: Заблокувати
98
+ moderation_state:
99
+ name: Стан модерації
100
+ pending:
101
+ empty:
102
+ content: Усі дописи пройшли модерацію.
103
+ title: Гарна робота!
104
+ post_approved_html: Допис схвалено користувачем %{moderator} %{time_ago}.
105
+ post_blocked_html: Допис заблоковано користувачем %{moderator} %{time_ago}.
106
+ post_deleted_notice: Цей допис було видалено.
107
+ posts_content_changed_since_moderation_html: Вміст <a href="%{post_url}">допису</a> змінився після модерації.
108
+ Нижче наведено вміст на момент модерації.
109
+ search_users:
110
+ form_label: Пошук користувачів
111
+ form_placeholder: :thredded.moderation.search_users.form_label
112
+ no_results_message: Немає користувачів, ім'я яких починається з %{query}
113
+ results_message: Користувачі з іменами, що починаються з %{query}
114
+ user:
115
+ name: Користувач
116
+ nav:
117
+ all_messageboards: Усі дошки повідомлень
118
+ edit_messageboard: Редагувати дошку повідомлень
119
+ edit_post: Редагувати допис
120
+ edit_private_topic: :thredded.nav.edit_topic
121
+ edit_topic: Редагувати
122
+ mark_all_read: Позначити все як прочитане
123
+ moderation: Модерація
124
+ moderation_activity: Активність
125
+ moderation_history: Історія
126
+ moderation_pending: Очікує
127
+ moderation_users: Користувачі
128
+ private_topics: Приватні повідомлення
129
+ settings: Налаштування сповіщень
130
+ sign_in: Увійти / Зареєструватися
131
+ sign_out: Вийти
132
+ unread_topics: Непрочитані
133
+ null_user_name: Видалений користувач
134
+ posts:
135
+ delete: Видалити допис
136
+ delete_confirm: Ви впевнені, що хочете видалити цей допис?
137
+ deleted_notice: Ваш допис видалено.
138
+ edit: :thredded.nav.edit_post
139
+ form:
140
+ content_label: Вміст
141
+ create_btn: Надіслати відповідь
142
+ create_btn_submitting: Публікація...
143
+ title_label: Додати допис
144
+ update_btn: Оновити допис
145
+ update_btn_submitting: :thredded.form.update_btn_submitting
146
+ pending_moderation_notice: Ваш допис буде опубліковано після перевірки модератором.
147
+ quote_btn: Цитувати
148
+ spoiler_summary: Спойлер - натисніть, щоб показати.
149
+ spoiler_summary_for_email: 'Спойлер - виділіть вміст нижче, щоб побачити:'
150
+ preferences:
151
+ edit:
152
+ page_title: :thredded.nav.settings
153
+ form:
154
+ auto_follow_topics:
155
+ hint: Автоматично стежити за всіма новими темами. Зміна цього налаштування змінить його для всіх дошок
156
+ повідомлень.
157
+ label: Стежити за всіма новими темами
158
+ follow_topics_on_mention:
159
+ hint: 'Коли хтось згадує вас за вашим ім''ям користувача (наприклад: @sam), ви будете стежити за темою.'
160
+ label: Стежити за темами, в яких вас згадують
161
+ messageboard_auto_follow_topics:
162
+ hint: >-
163
+ Автоматично стежити за всіма новими темами на цій дошці повідомлень. Це перевизначає відповідне налаштування
164
+ вище.
165
+ label: Стежити за всіма новими темами
166
+ messageboard_follow_topics_on_mention:
167
+ hint: >-
168
+ Коли хтось згадує вас за вашим ім'ям користувача (наприклад: @sam) на цій дошці повідомлень, ви будете
169
+ стежити за темою.
170
+ label: :thredded.preferences.form.follow_topics_on_mention.label
171
+ messageboard_notifications_for_followed_topics:
172
+ label: :thredded.preferences.form.notifications_for_followed_topics.label
173
+ notifications_for_followed_topics:
174
+ label: Сповіщення для тем, за якими ви стежите
175
+ notifications_for_private_topics:
176
+ label: Сповіщення для приватних повідомлень
177
+ submit_btn: Оновити налаштування
178
+ update_btn_submitting: :thredded.form.update_btn_submitting
179
+ global_preferences_title: Глобальні налаштування
180
+ messageboard_preferences_nav_title: Налаштування дошки повідомлень
181
+ messageboard_preferences_title_html: Налаштування для <em>%{messageboard}</em>
182
+ updated_notice: Ваші налаштування оновлено.
183
+ private_posts:
184
+ form:
185
+ content_label: Повідомлення
186
+ create_btn: Надіслати повідомлення
187
+ create_btn_submitting: Надсилання...
188
+ update_btn_submitting: :thredded.form.update_btn_submitting
189
+ private_topics:
190
+ create: :thredded.private_topics.form.create_btn
191
+ edit: Редагувати
192
+ errors:
193
+ user_ids_length: Будь ласка, вкажіть принаймні одного іншого користувача.
194
+ form:
195
+ content_label: :thredded.private_posts.form.content_label
196
+ create_btn: :thredded.private_posts.form.create_btn
197
+ create_btn_submitting: :thredded.private_posts.form.create_btn_submitting
198
+ title_label: :thredded.topics.form.title_label
199
+ title_placeholder_new: Напишіть тему цієї розмови
200
+ title_placeholder_start: Почати нову розмову
201
+ update_btn: Оновити
202
+ update_btn_submitting: :thredded.private_posts.form.update_btn_submitting
203
+ users_label: Учасники
204
+ users_placeholder: Виберіть користувачів для участі в цій розмові
205
+ no_private_topics:
206
+ create_btn: Почати першу приватну розмову
207
+ title: У вас немає приватних повідомлень.
208
+ updated_notice: Назву оновлено
209
+ recent_activity: Нещодавня активність
210
+ search:
211
+ form:
212
+ btn_submit: :thredded.search.form.label
213
+ label: Пошук
214
+ placeholder: Пошук тем і дописів
215
+ time_ago: "%{time} тому"
216
+ topics:
217
+ create: :thredded.topics.form.create_btn
218
+ delete_confirm: Ви впевнені, що хочете видалити цю тему? Це НЕ МОЖНА скасувати.
219
+ delete_topic: Видалити тему
220
+ deleted_notice: Тему видалено
221
+ edit: Редагувати тему
222
+ follow: Стежити за цією темою
223
+ followed_by: 'Стежать:'
224
+ followed_by_noone: Ніхто не стежить за цією темою
225
+ followed_notice: Тепер ви стежите за цією темою
226
+ following:
227
+ auto: Ви стежите за цією темою, оскільки увімкнено автоматичне стеження.
228
+ manual: Ви стежите за цією темою.
229
+ mentioned: Ви стежите за цією темою, оскільки вас у ній згадували.
230
+ posted: Ви стежите за цією темою, оскільки ви в ній писали.
231
+ form:
232
+ categories_placeholder: Категорії
233
+ content_label: :thredded.posts.form.content_label
234
+ create_btn: Створити нову тему
235
+ messageboard_label: Дошка повідомлень
236
+ title_label: Назва
237
+ title_placeholder: :thredded.topics.form.title_label
238
+ title_placeholder_start: Почати нову тему
239
+ update_btn: Оновити тему
240
+ in_messageboard_html: в %{messageboard_link}
241
+ locked:
242
+ label: Заблоковано
243
+ message: Цю тему заблоковано модератором.
244
+ mark_as_unread: Позначити як непрочитане звідси
245
+ not_following: Ви не стежите за цією темою.
246
+ search:
247
+ no_results_in_messageboard_message_html: Немає результатів для вашого пошуку <q>%{query}</q> в %{messageboard}
248
+ no_results_message_html: Немає результатів для вашого пошуку <q>%{query}</q>
249
+ page_title: Результати пошуку тем
250
+ results_in_messageboard_message_html: Результати пошуку для <q>%{query}</q> в %{messageboard}
251
+ results_message_html: Результати пошуку для <q>%{query}</q>
252
+ search_in_all_messageboards_btn: Шукати всюди
253
+ started_by_html: Створено %{time_ago} користувачем %{user}
254
+ sticky:
255
+ label: Закріплено
256
+ unfollow: Припинити стеження
257
+ unfollowed_notice: Ви більше не стежите за цією темою
258
+ updated_notice: Тему оновлено
259
+ unread_topics:
260
+ empty:
261
+ content: Ви прочитали все, що є. Поверніться пізніше за новим контентом!
262
+ title: Все прочитано!
263
+ page_title: Непрочитані теми
264
+ page_title_in_messageboard: "%{messageboard}: Непрочитані теми"
265
+ users:
266
+ currently_online: Зараз онлайн
267
+ last_active_html: Остання активність %{time_ago}
268
+ posted_in_topic_html: Написав у %{topic_link}
269
+ posts_count:
270
+ few: Написав %{count} рази
271
+ many: Написав %{count} разів
272
+ one: Написав один раз
273
+ other: Написав %{count} разів
274
+ recent_activity: :thredded.recent_activity
275
+ send_private_message: Надіслати приватне повідомлення
276
+ started_topic_html: Створив %{topic_link}
277
+ started_topics_count:
278
+ few: Створив %{count} теми
279
+ many: Створив %{count} тем
280
+ one: Створив %{count} тему
281
+ other: Створив %{count} тем
282
+ user_posted_in_topic_html: "%{user_link} написав у %{topic_link}"
283
+ user_since_html: Користувач з %{time_ago}
284
+ user_started_topic_html: "%{user_link} створив %{topic_link}"
@@ -15,5 +15,21 @@ module Thredded
15
15
  Arel::Nodes::Division.new(a, b)
16
16
  end
17
17
  end
18
+
19
+ # @param [#connection] engine_or_model_class
20
+ # @param [Arel::Nodes::Node] left
21
+ # @param [Arel::Nodes::Node] right
22
+ # @return [Arel::Nodes::Node] union of left and right
23
+ # extract and simplified from https://github.com/brianhempel/active_record_union/blob/master/lib/active_record_union/active_record/relation/union.rb
24
+ def union_new(engine_or_model_class, left, right)
25
+ if /sqlite/i.match?(engine_or_model_class.connection.adapter_name)
26
+ # Postgres allows ORDER BY in the UNION subqueries if each subquery is surrounded by parenthesis
27
+ # but SQLite does not allow parens around the subqueries
28
+ Arel::Nodes::Union.new(left.ast, right.ast)
29
+ else
30
+ # By default this adds parentheses which sqlite does not allow
31
+ Arel::Nodes::Union.new(left, right)
32
+ end
33
+ end
18
34
  end
19
35
  end