thredded 1.1.0 → 1.2.1
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 +4 -4
- data/README.md +43 -32
- data/app/models/concerns/thredded/moderation_state.rb +1 -1
- data/app/models/concerns/thredded/topics_search.rb +1 -1
- data/app/models/concerns/thredded/union_scope.rb +37 -0
- data/app/models/thredded/post_moderation_record.rb +3 -1
- data/app/models/thredded/topic.rb +7 -0
- data/app/models/thredded/user_topic_follow.rb +3 -2
- data/config/locales/uk.yml +284 -0
- data/lib/thredded/arel_compat.rb +16 -0
- data/lib/thredded/collection_to_strings_with_cache_renderer.rb +14 -25
- data/lib/thredded/compat.rb +15 -17
- data/lib/thredded/database_seeder.rb +26 -11
- data/lib/thredded/db_tools.rb +1 -1
- data/lib/thredded/engine.rb +12 -0
- data/lib/thredded/version.rb +1 -1
- data/lib/thredded.rb +0 -2
- metadata +16 -372
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be8026fdf40f38f7143784b548e10f87d2606358ae302e81f536713feb0c59a6
|
4
|
+
data.tar.gz: abcbc174119805d870fd2c51b6985524b0f9123dccdfcd26b8e206417b04b333
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c74687299ccd1435304a97057d7c2430e6c1af13bf3f62ef63a1d6fdcd811d67225782337ccc5018d97cb4cee34bfbb5d9231d0fcd041351eed8a93984ca783e
|
7
|
+
data.tar.gz: df93c85e83e7c7be26eeb8ece54167ae279ad5988fd21693a287922e492c0ddcbb25e75bbe3c460dda2cfaa991c2f7801a5eae4bb96083ceacfdada8ccccb7eb
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
# Thredded
|
1
|
+
# Thredded
|
2
|
+
[](https://codeclimate.com/github/thredded/thredded) [](https://codeclimate.com/github/thredded/thredded/coverage) [](http://inch-ci.org/github/thredded/thredded) [](https://gitter.im/thredded/thredded?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
3
|
+
[](https://github.com/thredded/thredded/actions/workflows/build.yml)
|
2
4
|
|
3
|
-
_Thredded_ is a Rails
|
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
|
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,
|
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/
|
@@ -78,7 +80,15 @@ Table of Contents
|
|
78
80
|
|
79
81
|
### Creating a new Rails app with Thredded
|
80
82
|
|
81
|
-
|
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,
|
82
92
|
PostgreSQL, and a basic theme and navigation that is configured to work out of the box.
|
83
93
|
|
84
94
|
```sh
|
@@ -92,12 +102,14 @@ Then, see the rest of this Readme for more information about using and customizi
|
|
92
102
|
|
93
103
|
[thredded_create_app repo]: https://github.com/thredded/thredded_create_app
|
94
104
|
|
105
|
+
</details>
|
106
|
+
|
95
107
|
### Adding Thredded to an existing Rails app
|
96
108
|
|
97
109
|
Add the gem to your Gemfile:
|
98
110
|
|
99
111
|
```ruby
|
100
|
-
gem 'thredded', '~> 1.
|
112
|
+
gem 'thredded', '~> 1.2'
|
101
113
|
```
|
102
114
|
|
103
115
|
Add the Thredded [initializer] to your parent app by running the install generator.
|
@@ -158,11 +170,13 @@ to Thredded.
|
|
158
170
|
|
159
171
|
## Rails compatibility
|
160
172
|
|
161
|
-
| Rails
|
162
|
-
|
163
|
-
| Rails
|
164
|
-
| Rails
|
165
|
-
| Rails
|
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 |
|
166
180
|
|
167
181
|
|
168
182
|
## Views and other assets
|
@@ -257,8 +271,7 @@ which are placed in the same order as in the source).
|
|
257
271
|
|
258
272
|
<details><summary><b>Rails UJS version</b></summary>
|
259
273
|
|
260
|
-
By default, thredded loads `rails-ujs`.
|
261
|
-
your Gemfile.
|
274
|
+
By default, thredded loads `rails-ujs`.
|
262
275
|
|
263
276
|
If you'd like it to use `jquery_ujs` instead, run this command from your app directory:
|
264
277
|
|
@@ -332,7 +345,7 @@ Whenever possible, use the styles and i18n to customize Thredded to your needs.
|
|
332
345
|
Thredded provides view hooks to customize the UI before/after/replacing individual components.
|
333
346
|
|
334
347
|
View hooks allow you to render anything in the thredded view context.
|
335
|
-
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
|
336
349
|
the `config/initializers/thredded.rb` initializer:
|
337
350
|
|
338
351
|
```ruby
|
@@ -393,7 +406,7 @@ You can also turn off the email notifier totally, or add other notifiers (e.g. P
|
|
393
406
|
the `Thredded.notifiers` configuration in your initializer. See the default initializer for examples.
|
394
407
|
|
395
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.
|
396
|
-
|
409
|
+
|
397
410
|
### Enabling auto-follow
|
398
411
|
|
399
412
|
In some cases, you'll want all users to auto-follow new messageboard topics by default. This might be useful
|
@@ -423,16 +436,16 @@ Here are the steps to ensure the best support for your language if it isn't Engl
|
|
423
436
|
//= require timeago/locales/de
|
424
437
|
//= require timeago/locales/pt_BR
|
425
438
|
//= require thredded
|
426
|
-
```
|
427
|
-
|
439
|
+
```
|
440
|
+
|
428
441
|
Webpack:
|
429
|
-
|
442
|
+
|
430
443
|
```erb
|
431
444
|
<% timeago_root = File.join(Gem.loaded_specs['timeago_js'].full_gem_path, 'assets', 'javascripts') %>
|
432
445
|
import "<%= File.join(timeago_root, 'timeago.js') %>";
|
433
446
|
<%= %w[de pt_BR].map { |locale| %(import "#{File.join(timeago_root, "timeago/locales/#{locale}.js")}";) } * "\n" %>
|
434
447
|
<%= Thredded::WebpackAssets.javascripts %>
|
435
|
-
```
|
448
|
+
```
|
436
449
|
|
437
450
|
Note that it is important that timeago and its locales are required *before* Thredded.
|
438
451
|
|
@@ -701,9 +714,9 @@ brew install --cask chromium
|
|
701
714
|
brew install --cask chromedriver
|
702
715
|
```
|
703
716
|
|
704
|
-
To get better page saves (`page.save_and_open_page`) from local capybara specs ensure you are running the server locally
|
705
|
-
and set `export CAPYBARA_ASSET_HOST=http://localhost:3000` (or whatever host/port your server is on) before running your
|
706
|
-
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.
|
707
720
|
|
708
721
|
### Ruby
|
709
722
|
|
@@ -796,25 +809,23 @@ To quickly try out _Thredded_ with the included dummy app, clone the source and
|
|
796
809
|
start the included docker-compose.yml file with:
|
797
810
|
|
798
811
|
```console
|
799
|
-
docker
|
800
|
-
docker
|
812
|
+
docker compose build
|
813
|
+
docker compose up
|
801
814
|
```
|
802
815
|
|
803
816
|
The above will build and run everything, daemonized, resulting in a running
|
804
|
-
instance on port 9292. Running `docker
|
817
|
+
instance on port 9292. Running `docker compose logs` will let you know when
|
805
818
|
everything is up and running. Editing the source on your host machine will
|
806
819
|
be reflected in the running docker'ized application.
|
807
820
|
|
808
|
-
|
809
|
-
on a Mac make sure you visit the boot2docker host ip at
|
810
|
-
`http://$(boot2docker ip):9292`.
|
811
|
-
|
812
|
-
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`)
|
813
822
|
|
814
823
|
```console
|
815
|
-
docker
|
824
|
+
docker compose exec web bundle exec rake
|
816
825
|
```
|
817
826
|
|
818
|
-
|
827
|
+
Alternatively you run a one-off dyno `docker compose run web bundle exec rake`
|
828
|
+
|
829
|
+
The docker container uses PostgreSQL
|
819
830
|
|
820
831
|
[initializer]: https://github.com/thredded/thredded/blob/main/lib/generators/thredded/install/templates/initializer.rb
|
@@ -7,7 +7,7 @@ module Thredded
|
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
9
|
included do
|
10
|
-
enum moderation_state
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
15
|
+
alias postable topic
|
16
|
+
alias postable= topic=
|
16
17
|
|
17
18
|
# Creates a follow or finds the existing one.
|
18
19
|
#
|
@@ -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}"
|
data/lib/thredded/arel_compat.rb
CHANGED
@@ -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
|
@@ -60,16 +60,16 @@ module Thredded
|
|
60
60
|
digest_path = digest_path_from_template(view, template)
|
61
61
|
|
62
62
|
collection.each_with_object([{}, []]) do |item, (hash, ordered_keys)|
|
63
|
-
key = expanded_cache_key(item, view,
|
63
|
+
key = expanded_cache_key(item, view, digest_path)
|
64
64
|
ordered_keys << key
|
65
65
|
hash[key] = item
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
def expanded_cache_key(key, view,
|
69
|
+
def expanded_cache_key(key, view, digest_path)
|
70
70
|
key = combined_fragment_cache_key(
|
71
71
|
view,
|
72
|
-
cache_fragment_name(view, key,
|
72
|
+
cache_fragment_name(view, key, digest_path: digest_path)
|
73
73
|
)
|
74
74
|
key.frozen? ? key.dup : key # #read_multi & #write may require mutability, Dalli 2.6.0.
|
75
75
|
end
|
@@ -106,22 +106,15 @@ module Thredded
|
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
renderer.render_object_with_partial(object, opts[:partial], view_context, nil).body
|
119
|
-
end
|
120
|
-
end
|
121
|
-
else
|
122
|
-
def render_partials_serial(view_context, collection, opts)
|
123
|
-
partial_renderer = ActionView::PartialRenderer.new(@lookup_context)
|
124
|
-
collection.map { |object| render_partial(partial_renderer, view_context, **opts.merge(object: object)) }
|
109
|
+
# @param [Array<Object>] collection
|
110
|
+
# @param [Hash] opts
|
111
|
+
# @param view_context
|
112
|
+
# @return [Array<String>]
|
113
|
+
def render_partials_serial(view_context, collection, opts)
|
114
|
+
# https://github.com/rails/rails/pull/38594
|
115
|
+
collection.map do |object|
|
116
|
+
renderer = ActionView::ObjectRenderer.new(@lookup_context, opts)
|
117
|
+
renderer.render_object_with_partial(object, opts[:partial], view_context, nil).body
|
125
118
|
end
|
126
119
|
end
|
127
120
|
|
@@ -133,12 +126,8 @@ module Thredded
|
|
133
126
|
view.combined_fragment_cache_key(key)
|
134
127
|
end
|
135
128
|
|
136
|
-
def cache_fragment_name(view, key,
|
137
|
-
|
138
|
-
view.cache_fragment_name(key, digest_path: digest_path)
|
139
|
-
else
|
140
|
-
view.cache_fragment_name(key, virtual_path: virtual_path, digest_path: digest_path)
|
141
|
-
end
|
129
|
+
def cache_fragment_name(view, key, digest_path:)
|
130
|
+
view.cache_fragment_name(key, digest_path: digest_path)
|
142
131
|
end
|
143
132
|
|
144
133
|
def digest_path_from_template(view, template)
|
data/lib/thredded/compat.rb
CHANGED
@@ -4,25 +4,23 @@ module Thredded
|
|
4
4
|
module Compat
|
5
5
|
class << self
|
6
6
|
# @api private
|
7
|
-
def
|
8
|
-
@
|
9
|
-
@
|
7
|
+
def rails_gte_71?
|
8
|
+
@rails_gte_71 = (Rails.gem_version >= Gem::Version.new('7.1.0')) if @rails_gte_71.nil?
|
9
|
+
@rails_gte_71
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
else
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
)
|
25
|
-
end
|
12
|
+
# @api private
|
13
|
+
def rails_gte_72?
|
14
|
+
@rails_gte_72 = (Rails.gem_version >= Gem::Version.new('7.2.0')) if @rails_gte_72.nil?
|
15
|
+
@rails_gte_72
|
16
|
+
end
|
17
|
+
|
18
|
+
# @api private
|
19
|
+
# TODO: inline this or put it somewhere else as it's no longer specific to a rails version
|
20
|
+
def association_preloader(records:, associations:, scope:)
|
21
|
+
ActiveRecord::Associations::Preloader.new(
|
22
|
+
records: records, associations: associations, scope: scope
|
23
|
+
).call
|
26
24
|
end
|
27
25
|
end
|
28
26
|
end
|
@@ -10,6 +10,7 @@ rescue NameError
|
|
10
10
|
end
|
11
11
|
# rubocop:enable HandleExceptions
|
12
12
|
module Thredded
|
13
|
+
# rubocop:disable Metrics/MethodLength
|
13
14
|
class DatabaseSeeder # rubocop:disable Metrics/ClassLength
|
14
15
|
module LogTime
|
15
16
|
def self.included(base)
|
@@ -60,8 +61,16 @@ module Thredded
|
|
60
61
|
def self.with_seeder_tweaks
|
61
62
|
# Disable callbacks to avoid creating notifications and performing unnecessary updates
|
62
63
|
DISABLE_COUNTER_CACHE.each do |klass|
|
63
|
-
|
64
|
-
|
64
|
+
if Thredded::Compat.rails_gte_72?
|
65
|
+
klass.class_eval do
|
66
|
+
class_attribute :original_counter_cached_association_names
|
67
|
+
self.original_counter_cached_association_names = counter_cached_association_names
|
68
|
+
self.counter_cached_association_names = []
|
69
|
+
end
|
70
|
+
else
|
71
|
+
klass.send(:alias_method, :original_each_counter_cached_associations, :each_counter_cached_associations)
|
72
|
+
klass.send(:define_method, :each_counter_cached_associations) {}
|
73
|
+
end
|
65
74
|
end
|
66
75
|
SKIP_CALLBACKS.each { |(klass, *args)| delete_callbacks(klass, *args) }
|
67
76
|
WRITEABLE_READONLY_ATTRIBUTES.each { |(klass, attr)| klass.readonly_attributes.delete(attr) }
|
@@ -71,9 +80,15 @@ module Thredded
|
|
71
80
|
ensure
|
72
81
|
# Re-enable callbacks and counter cache
|
73
82
|
DISABLE_COUNTER_CACHE.each do |klass|
|
74
|
-
|
75
|
-
|
76
|
-
|
83
|
+
if Thredded::Compat.rails_gte_72?
|
84
|
+
klass.class_eval do
|
85
|
+
self.counter_cached_association_names = original_counter_cached_association_names
|
86
|
+
end
|
87
|
+
else
|
88
|
+
klass.send(:remove_method, :each_counter_cached_associations)
|
89
|
+
klass.send(:alias_method, :each_counter_cached_associations, :original_each_counter_cached_associations)
|
90
|
+
klass.send(:remove_method, :original_each_counter_cached_associations)
|
91
|
+
end
|
77
92
|
end
|
78
93
|
SKIP_CALLBACKS.each do |(klass, *args)|
|
79
94
|
args = args.dup
|
@@ -150,9 +165,7 @@ module Thredded
|
|
150
165
|
end
|
151
166
|
|
152
167
|
def user_details
|
153
|
-
@user_details ||= users.
|
154
|
-
hash[user] = user.thredded_user_detail
|
155
|
-
end
|
168
|
+
@user_details ||= users.index_with(&:thredded_user_detail)
|
156
169
|
end
|
157
170
|
|
158
171
|
def first_messageboard
|
@@ -175,7 +188,7 @@ module Thredded
|
|
175
188
|
end
|
176
189
|
end
|
177
190
|
|
178
|
-
log_method_time def update_messageboards_data(**)
|
191
|
+
log_method_time def update_messageboards_data(**)
|
179
192
|
log 'Updating messageboards data...'
|
180
193
|
Messageboard.all.each do |messageboard|
|
181
194
|
messageboard.update_last_topic!
|
@@ -330,7 +343,7 @@ module Thredded
|
|
330
343
|
class FirstMessageboard < FirstSeedData
|
331
344
|
MODEL_CLASS = Messageboard
|
332
345
|
|
333
|
-
log_method_time def create(**)
|
346
|
+
log_method_time def create(**)
|
334
347
|
log 'Creating a messageboard...'
|
335
348
|
@first_messageboard = FactoryBot.create(
|
336
349
|
:messageboard,
|
@@ -384,7 +397,8 @@ module Thredded
|
|
384
397
|
class Posts < CollectionSeedData
|
385
398
|
MODEL_CLASS = Post
|
386
399
|
|
387
|
-
log_method_time def create(count: (1..1), topics: seeder.topics)
|
400
|
+
log_method_time def create(count: (1..1), topics: seeder.topics)
|
401
|
+
# rubocop:disable Metrics/MethodLength
|
388
402
|
log "Creating #{count} additional posts in each topic..."
|
389
403
|
topics.flat_map do |topic|
|
390
404
|
last_post_at = random_duration(0..256.hours).ago
|
@@ -446,4 +460,5 @@ module Thredded
|
|
446
460
|
end
|
447
461
|
end
|
448
462
|
end
|
463
|
+
# rubocop:enable Metrics/MethodLength
|
449
464
|
end
|
data/lib/thredded/db_tools.rb
CHANGED
@@ -10,7 +10,7 @@ module Thredded
|
|
10
10
|
verbose_was = ActiveRecord::Migration.verbose
|
11
11
|
ActiveRecord::Migration.verbose = !quiet
|
12
12
|
migrate =
|
13
|
-
-> { ActiveRecord::MigrationContext.new(paths
|
13
|
+
-> { ActiveRecord::MigrationContext.new(paths).migrate(nil, &filter) }
|
14
14
|
if quiet
|
15
15
|
silence_active_record(&migrate)
|
16
16
|
else
|
data/lib/thredded/engine.rb
CHANGED
@@ -20,5 +20,17 @@ module Thredded
|
|
20
20
|
thredded_manifest.js
|
21
21
|
]
|
22
22
|
end
|
23
|
+
|
24
|
+
config.after_initialize do |app|
|
25
|
+
next unless Rails.env.development? || Rails.env.test?
|
26
|
+
next unless app.config.assets.compile && app.assets
|
27
|
+
|
28
|
+
if app.assets.preprocessors.keys.exclude?('text/scss')
|
29
|
+
fail [
|
30
|
+
'Thredded requires a Sass compiler to be registered in Sprockets.',
|
31
|
+
%(Please add "sassc-rails" or "dartsass-sprockets" to your application Gemfile.),
|
32
|
+
].join(' ')
|
33
|
+
end
|
34
|
+
end
|
23
35
|
end
|
24
36
|
end
|
data/lib/thredded/version.rb
CHANGED
data/lib/thredded.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
# Backend
|
4
4
|
require 'pundit'
|
5
|
-
require 'active_record_union'
|
6
5
|
require 'db_text_search'
|
7
6
|
require 'friendly_id'
|
8
7
|
require 'html/pipeline'
|
@@ -29,7 +28,6 @@ require 'thredded/users_provider'
|
|
29
28
|
require 'autoprefixer-rails'
|
30
29
|
require 'timeago_js'
|
31
30
|
require 'sprockets/es6'
|
32
|
-
require 'sassc-rails'
|
33
31
|
|
34
32
|
require 'thredded/version'
|
35
33
|
require 'thredded/compat'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thredded
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Oliveira
|
@@ -9,22 +9,8 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2025-05-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: active_record_union
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
requirements:
|
18
|
-
- - ">="
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: 1.3.0
|
21
|
-
type: :runtime
|
22
|
-
prerelease: false
|
23
|
-
version_requirements: !ruby/object:Gem::Requirement
|
24
|
-
requirements:
|
25
|
-
- - ">="
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
version: 1.3.0
|
28
14
|
- !ruby/object:Gem::Dependency
|
29
15
|
name: db_text_search
|
30
16
|
requirement: !ruby/object:Gem::Requirement
|
@@ -127,16 +113,16 @@ dependencies:
|
|
127
113
|
name: rails
|
128
114
|
requirement: !ruby/object:Gem::Requirement
|
129
115
|
requirements:
|
130
|
-
- - "
|
116
|
+
- - ">="
|
131
117
|
- !ruby/object:Gem::Version
|
132
|
-
version:
|
118
|
+
version: '7.0'
|
133
119
|
type: :runtime
|
134
120
|
prerelease: false
|
135
121
|
version_requirements: !ruby/object:Gem::Requirement
|
136
122
|
requirements:
|
137
|
-
- - "
|
123
|
+
- - ">="
|
138
124
|
- !ruby/object:Gem::Version
|
139
|
-
version:
|
125
|
+
version: '7.0'
|
140
126
|
- !ruby/object:Gem::Dependency
|
141
127
|
name: rails_gravatar
|
142
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -158,6 +144,9 @@ dependencies:
|
|
158
144
|
- - ">="
|
159
145
|
- !ruby/object:Gem::Version
|
160
146
|
version: 2.14.1
|
147
|
+
- - "<"
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '3'
|
161
150
|
type: :runtime
|
162
151
|
prerelease: false
|
163
152
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -165,6 +154,9 @@ dependencies:
|
|
165
154
|
- - ">="
|
166
155
|
- !ruby/object:Gem::Version
|
167
156
|
version: 2.14.1
|
157
|
+
- - "<"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '3'
|
168
160
|
- !ruby/object:Gem::Dependency
|
169
161
|
name: kramdown
|
170
162
|
requirement: !ruby/object:Gem::Requirement
|
@@ -249,20 +241,6 @@ dependencies:
|
|
249
241
|
- - ">="
|
250
242
|
- !ruby/object:Gem::Version
|
251
243
|
version: '0'
|
252
|
-
- !ruby/object:Gem::Dependency
|
253
|
-
name: sassc-rails
|
254
|
-
requirement: !ruby/object:Gem::Requirement
|
255
|
-
requirements:
|
256
|
-
- - ">="
|
257
|
-
- !ruby/object:Gem::Version
|
258
|
-
version: 2.0.0
|
259
|
-
type: :runtime
|
260
|
-
prerelease: false
|
261
|
-
version_requirements: !ruby/object:Gem::Requirement
|
262
|
-
requirements:
|
263
|
-
- - ">="
|
264
|
-
- !ruby/object:Gem::Version
|
265
|
-
version: 2.0.0
|
266
244
|
- !ruby/object:Gem::Dependency
|
267
245
|
name: sprockets-es6
|
268
246
|
requirement: !ruby/object:Gem::Requirement
|
@@ -291,342 +269,6 @@ dependencies:
|
|
291
269
|
- - ">="
|
292
270
|
- !ruby/object:Gem::Version
|
293
271
|
version: 3.0.2.2
|
294
|
-
- !ruby/object:Gem::Dependency
|
295
|
-
name: capybara
|
296
|
-
requirement: !ruby/object:Gem::Requirement
|
297
|
-
requirements:
|
298
|
-
- - "~>"
|
299
|
-
- !ruby/object:Gem::Version
|
300
|
-
version: '3.0'
|
301
|
-
type: :development
|
302
|
-
prerelease: false
|
303
|
-
version_requirements: !ruby/object:Gem::Requirement
|
304
|
-
requirements:
|
305
|
-
- - "~>"
|
306
|
-
- !ruby/object:Gem::Version
|
307
|
-
version: '3.0'
|
308
|
-
- !ruby/object:Gem::Dependency
|
309
|
-
name: capybara-screenshot
|
310
|
-
requirement: !ruby/object:Gem::Requirement
|
311
|
-
requirements:
|
312
|
-
- - ">="
|
313
|
-
- !ruby/object:Gem::Version
|
314
|
-
version: '0'
|
315
|
-
type: :development
|
316
|
-
prerelease: false
|
317
|
-
version_requirements: !ruby/object:Gem::Requirement
|
318
|
-
requirements:
|
319
|
-
- - ">="
|
320
|
-
- !ruby/object:Gem::Version
|
321
|
-
version: '0'
|
322
|
-
- !ruby/object:Gem::Dependency
|
323
|
-
name: cuprite
|
324
|
-
requirement: !ruby/object:Gem::Requirement
|
325
|
-
requirements:
|
326
|
-
- - ">="
|
327
|
-
- !ruby/object:Gem::Version
|
328
|
-
version: '0.5'
|
329
|
-
type: :development
|
330
|
-
prerelease: false
|
331
|
-
version_requirements: !ruby/object:Gem::Requirement
|
332
|
-
requirements:
|
333
|
-
- - ">="
|
334
|
-
- !ruby/object:Gem::Version
|
335
|
-
version: '0.5'
|
336
|
-
- !ruby/object:Gem::Dependency
|
337
|
-
name: database_cleaner-active_record
|
338
|
-
requirement: !ruby/object:Gem::Requirement
|
339
|
-
requirements:
|
340
|
-
- - "~>"
|
341
|
-
- !ruby/object:Gem::Version
|
342
|
-
version: '2.0'
|
343
|
-
type: :development
|
344
|
-
prerelease: false
|
345
|
-
version_requirements: !ruby/object:Gem::Requirement
|
346
|
-
requirements:
|
347
|
-
- - "~>"
|
348
|
-
- !ruby/object:Gem::Version
|
349
|
-
version: '2.0'
|
350
|
-
- !ruby/object:Gem::Dependency
|
351
|
-
name: factory_bot
|
352
|
-
requirement: !ruby/object:Gem::Requirement
|
353
|
-
requirements:
|
354
|
-
- - ">="
|
355
|
-
- !ruby/object:Gem::Version
|
356
|
-
version: 5.0.2
|
357
|
-
type: :development
|
358
|
-
prerelease: false
|
359
|
-
version_requirements: !ruby/object:Gem::Requirement
|
360
|
-
requirements:
|
361
|
-
- - ">="
|
362
|
-
- !ruby/object:Gem::Version
|
363
|
-
version: 5.0.2
|
364
|
-
- !ruby/object:Gem::Dependency
|
365
|
-
name: faker
|
366
|
-
requirement: !ruby/object:Gem::Requirement
|
367
|
-
requirements:
|
368
|
-
- - ">="
|
369
|
-
- !ruby/object:Gem::Version
|
370
|
-
version: 1.9.3
|
371
|
-
type: :development
|
372
|
-
prerelease: false
|
373
|
-
version_requirements: !ruby/object:Gem::Requirement
|
374
|
-
requirements:
|
375
|
-
- - ">="
|
376
|
-
- !ruby/object:Gem::Version
|
377
|
-
version: 1.9.3
|
378
|
-
- !ruby/object:Gem::Dependency
|
379
|
-
name: launchy
|
380
|
-
requirement: !ruby/object:Gem::Requirement
|
381
|
-
requirements:
|
382
|
-
- - ">="
|
383
|
-
- !ruby/object:Gem::Version
|
384
|
-
version: '0'
|
385
|
-
type: :development
|
386
|
-
prerelease: false
|
387
|
-
version_requirements: !ruby/object:Gem::Requirement
|
388
|
-
requirements:
|
389
|
-
- - ">="
|
390
|
-
- !ruby/object:Gem::Version
|
391
|
-
version: '0'
|
392
|
-
- !ruby/object:Gem::Dependency
|
393
|
-
name: rails-controller-testing
|
394
|
-
requirement: !ruby/object:Gem::Requirement
|
395
|
-
requirements:
|
396
|
-
- - ">="
|
397
|
-
- !ruby/object:Gem::Version
|
398
|
-
version: '0'
|
399
|
-
type: :development
|
400
|
-
prerelease: false
|
401
|
-
version_requirements: !ruby/object:Gem::Requirement
|
402
|
-
requirements:
|
403
|
-
- - ">="
|
404
|
-
- !ruby/object:Gem::Version
|
405
|
-
version: '0'
|
406
|
-
- !ruby/object:Gem::Dependency
|
407
|
-
name: rspec-rails
|
408
|
-
requirement: !ruby/object:Gem::Requirement
|
409
|
-
requirements:
|
410
|
-
- - ">="
|
411
|
-
- !ruby/object:Gem::Version
|
412
|
-
version: 3.5.0
|
413
|
-
type: :development
|
414
|
-
prerelease: false
|
415
|
-
version_requirements: !ruby/object:Gem::Requirement
|
416
|
-
requirements:
|
417
|
-
- - ">="
|
418
|
-
- !ruby/object:Gem::Version
|
419
|
-
version: 3.5.0
|
420
|
-
- !ruby/object:Gem::Dependency
|
421
|
-
name: simplecov
|
422
|
-
requirement: !ruby/object:Gem::Requirement
|
423
|
-
requirements:
|
424
|
-
- - ">="
|
425
|
-
- !ruby/object:Gem::Version
|
426
|
-
version: '0'
|
427
|
-
type: :development
|
428
|
-
prerelease: false
|
429
|
-
version_requirements: !ruby/object:Gem::Requirement
|
430
|
-
requirements:
|
431
|
-
- - ">="
|
432
|
-
- !ruby/object:Gem::Version
|
433
|
-
version: '0'
|
434
|
-
- !ruby/object:Gem::Dependency
|
435
|
-
name: webmock
|
436
|
-
requirement: !ruby/object:Gem::Requirement
|
437
|
-
requirements:
|
438
|
-
- - ">="
|
439
|
-
- !ruby/object:Gem::Version
|
440
|
-
version: '0'
|
441
|
-
type: :development
|
442
|
-
prerelease: false
|
443
|
-
version_requirements: !ruby/object:Gem::Requirement
|
444
|
-
requirements:
|
445
|
-
- - ">="
|
446
|
-
- !ruby/object:Gem::Version
|
447
|
-
version: '0'
|
448
|
-
- !ruby/object:Gem::Dependency
|
449
|
-
name: http_accept_language
|
450
|
-
requirement: !ruby/object:Gem::Requirement
|
451
|
-
requirements:
|
452
|
-
- - ">="
|
453
|
-
- !ruby/object:Gem::Version
|
454
|
-
version: '0'
|
455
|
-
type: :development
|
456
|
-
prerelease: false
|
457
|
-
version_requirements: !ruby/object:Gem::Requirement
|
458
|
-
requirements:
|
459
|
-
- - ">="
|
460
|
-
- !ruby/object:Gem::Version
|
461
|
-
version: '0'
|
462
|
-
- !ruby/object:Gem::Dependency
|
463
|
-
name: kaminari-i18n
|
464
|
-
requirement: !ruby/object:Gem::Requirement
|
465
|
-
requirements:
|
466
|
-
- - ">="
|
467
|
-
- !ruby/object:Gem::Version
|
468
|
-
version: '0'
|
469
|
-
type: :development
|
470
|
-
prerelease: false
|
471
|
-
version_requirements: !ruby/object:Gem::Requirement
|
472
|
-
requirements:
|
473
|
-
- - ">="
|
474
|
-
- !ruby/object:Gem::Version
|
475
|
-
version: '0'
|
476
|
-
- !ruby/object:Gem::Dependency
|
477
|
-
name: mysql2
|
478
|
-
requirement: !ruby/object:Gem::Requirement
|
479
|
-
requirements:
|
480
|
-
- - ">="
|
481
|
-
- !ruby/object:Gem::Version
|
482
|
-
version: '0'
|
483
|
-
type: :development
|
484
|
-
prerelease: false
|
485
|
-
version_requirements: !ruby/object:Gem::Requirement
|
486
|
-
requirements:
|
487
|
-
- - ">="
|
488
|
-
- !ruby/object:Gem::Version
|
489
|
-
version: '0'
|
490
|
-
- !ruby/object:Gem::Dependency
|
491
|
-
name: pg
|
492
|
-
requirement: !ruby/object:Gem::Requirement
|
493
|
-
requirements:
|
494
|
-
- - ">="
|
495
|
-
- !ruby/object:Gem::Version
|
496
|
-
version: '0'
|
497
|
-
type: :development
|
498
|
-
prerelease: false
|
499
|
-
version_requirements: !ruby/object:Gem::Requirement
|
500
|
-
requirements:
|
501
|
-
- - ">="
|
502
|
-
- !ruby/object:Gem::Version
|
503
|
-
version: '0'
|
504
|
-
- !ruby/object:Gem::Dependency
|
505
|
-
name: puma
|
506
|
-
requirement: !ruby/object:Gem::Requirement
|
507
|
-
requirements:
|
508
|
-
- - ">="
|
509
|
-
- !ruby/object:Gem::Version
|
510
|
-
version: '0'
|
511
|
-
type: :development
|
512
|
-
prerelease: false
|
513
|
-
version_requirements: !ruby/object:Gem::Requirement
|
514
|
-
requirements:
|
515
|
-
- - ">="
|
516
|
-
- !ruby/object:Gem::Version
|
517
|
-
version: '0'
|
518
|
-
- !ruby/object:Gem::Dependency
|
519
|
-
name: rails-i18n
|
520
|
-
requirement: !ruby/object:Gem::Requirement
|
521
|
-
requirements:
|
522
|
-
- - ">="
|
523
|
-
- !ruby/object:Gem::Version
|
524
|
-
version: '0'
|
525
|
-
type: :development
|
526
|
-
prerelease: false
|
527
|
-
version_requirements: !ruby/object:Gem::Requirement
|
528
|
-
requirements:
|
529
|
-
- - ">="
|
530
|
-
- !ruby/object:Gem::Version
|
531
|
-
version: '0'
|
532
|
-
- !ruby/object:Gem::Dependency
|
533
|
-
name: rails_email_preview
|
534
|
-
requirement: !ruby/object:Gem::Requirement
|
535
|
-
requirements:
|
536
|
-
- - ">="
|
537
|
-
- !ruby/object:Gem::Version
|
538
|
-
version: 2.2.1
|
539
|
-
type: :development
|
540
|
-
prerelease: false
|
541
|
-
version_requirements: !ruby/object:Gem::Requirement
|
542
|
-
requirements:
|
543
|
-
- - ">="
|
544
|
-
- !ruby/object:Gem::Version
|
545
|
-
version: 2.2.1
|
546
|
-
- !ruby/object:Gem::Dependency
|
547
|
-
name: sqlite3
|
548
|
-
requirement: !ruby/object:Gem::Requirement
|
549
|
-
requirements:
|
550
|
-
- - ">="
|
551
|
-
- !ruby/object:Gem::Version
|
552
|
-
version: '0'
|
553
|
-
type: :development
|
554
|
-
prerelease: false
|
555
|
-
version_requirements: !ruby/object:Gem::Requirement
|
556
|
-
requirements:
|
557
|
-
- - ">="
|
558
|
-
- !ruby/object:Gem::Version
|
559
|
-
version: '0'
|
560
|
-
- !ruby/object:Gem::Dependency
|
561
|
-
name: twemoji
|
562
|
-
requirement: !ruby/object:Gem::Requirement
|
563
|
-
requirements:
|
564
|
-
- - ">="
|
565
|
-
- !ruby/object:Gem::Version
|
566
|
-
version: '0'
|
567
|
-
type: :development
|
568
|
-
prerelease: false
|
569
|
-
version_requirements: !ruby/object:Gem::Requirement
|
570
|
-
requirements:
|
571
|
-
- - ">="
|
572
|
-
- !ruby/object:Gem::Version
|
573
|
-
version: '0'
|
574
|
-
- !ruby/object:Gem::Dependency
|
575
|
-
name: web-console
|
576
|
-
requirement: !ruby/object:Gem::Requirement
|
577
|
-
requirements:
|
578
|
-
- - ">="
|
579
|
-
- !ruby/object:Gem::Version
|
580
|
-
version: '0'
|
581
|
-
type: :development
|
582
|
-
prerelease: false
|
583
|
-
version_requirements: !ruby/object:Gem::Requirement
|
584
|
-
requirements:
|
585
|
-
- - ">="
|
586
|
-
- !ruby/object:Gem::Version
|
587
|
-
version: '0'
|
588
|
-
- !ruby/object:Gem::Dependency
|
589
|
-
name: thredded-markdown_coderay
|
590
|
-
requirement: !ruby/object:Gem::Requirement
|
591
|
-
requirements:
|
592
|
-
- - ">="
|
593
|
-
- !ruby/object:Gem::Version
|
594
|
-
version: '0'
|
595
|
-
type: :development
|
596
|
-
prerelease: false
|
597
|
-
version_requirements: !ruby/object:Gem::Requirement
|
598
|
-
requirements:
|
599
|
-
- - ">="
|
600
|
-
- !ruby/object:Gem::Version
|
601
|
-
version: '0'
|
602
|
-
- !ruby/object:Gem::Dependency
|
603
|
-
name: thredded-markdown_katex
|
604
|
-
requirement: !ruby/object:Gem::Requirement
|
605
|
-
requirements:
|
606
|
-
- - ">="
|
607
|
-
- !ruby/object:Gem::Version
|
608
|
-
version: '0'
|
609
|
-
type: :development
|
610
|
-
prerelease: false
|
611
|
-
version_requirements: !ruby/object:Gem::Requirement
|
612
|
-
requirements:
|
613
|
-
- - ">="
|
614
|
-
- !ruby/object:Gem::Version
|
615
|
-
version: '0'
|
616
|
-
- !ruby/object:Gem::Dependency
|
617
|
-
name: turbolinks
|
618
|
-
requirement: !ruby/object:Gem::Requirement
|
619
|
-
requirements:
|
620
|
-
- - ">="
|
621
|
-
- !ruby/object:Gem::Version
|
622
|
-
version: '0'
|
623
|
-
type: :development
|
624
|
-
prerelease: false
|
625
|
-
version_requirements: !ruby/object:Gem::Requirement
|
626
|
-
requirements:
|
627
|
-
- - ">="
|
628
|
-
- !ruby/object:Gem::Version
|
629
|
-
version: '0'
|
630
272
|
description: |-
|
631
273
|
The best Rails 6.0+ forums engine ever. Its goal is to be as simple and feature rich as possible.
|
632
274
|
Thredded works with SQLite, MySQL (v5.6.4+), and PostgreSQL. See the demo at https://thredded.org/.
|
@@ -795,6 +437,7 @@ files:
|
|
795
437
|
- app/models/concerns/thredded/search_parser.rb
|
796
438
|
- app/models/concerns/thredded/topic_common.rb
|
797
439
|
- app/models/concerns/thredded/topics_search.rb
|
440
|
+
- app/models/concerns/thredded/union_scope.rb
|
798
441
|
- app/models/concerns/thredded/user_topic_read_state_common.rb
|
799
442
|
- app/models/thredded/category.rb
|
800
443
|
- app/models/thredded/messageboard.rb
|
@@ -989,6 +632,7 @@ files:
|
|
989
632
|
- config/locales/pl.yml
|
990
633
|
- config/locales/pt-BR.yml
|
991
634
|
- config/locales/ru.yml
|
635
|
+
- config/locales/uk.yml
|
992
636
|
- config/locales/zh-CN.yml
|
993
637
|
- config/routes.rb
|
994
638
|
- db/migrate/20160329231848_create_thredded.rb
|
@@ -1048,7 +692,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
1048
692
|
requirements:
|
1049
693
|
- - ">="
|
1050
694
|
- !ruby/object:Gem::Version
|
1051
|
-
version: '
|
695
|
+
version: '3.1'
|
1052
696
|
- - "<"
|
1053
697
|
- !ruby/object:Gem::Version
|
1054
698
|
version: '4.0'
|
@@ -1058,7 +702,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1058
702
|
- !ruby/object:Gem::Version
|
1059
703
|
version: '0'
|
1060
704
|
requirements: []
|
1061
|
-
rubygems_version: 3.
|
705
|
+
rubygems_version: 3.4.19
|
1062
706
|
signing_key:
|
1063
707
|
specification_version: 4
|
1064
708
|
summary: The best Rails forums engine ever.
|