thredded 0.16.14 → 1.0.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 +4 -4
- data/README.md +19 -7
- data/app/assets/javascripts/thredded/components/preview_area.es6 +3 -1
- data/app/controllers/concerns/thredded/render_preview.rb +6 -0
- data/app/controllers/thredded/application_controller.rb +5 -10
- data/app/controllers/thredded/topics_controller.rb +0 -6
- data/app/helpers/thredded/application_helper.rb +1 -1
- data/app/helpers/thredded/icon_helper.rb +1 -1
- data/app/helpers/thredded/urls_helper.rb +1 -1
- data/app/models/concerns/thredded/post_common.rb +5 -4
- data/app/models/concerns/thredded/topic_common.rb +1 -1
- data/app/models/concerns/thredded/user_topic_read_state_common.rb +7 -8
- data/app/models/thredded/messageboard.rb +5 -4
- data/app/models/thredded/notifications_for_followed_topics.rb +1 -1
- data/app/models/thredded/post.rb +3 -2
- data/app/models/thredded/post_moderation_record.rb +8 -9
- data/app/models/thredded/private_post.rb +2 -2
- data/app/models/thredded/private_topic.rb +4 -2
- data/app/models/thredded/topic.rb +2 -2
- data/app/models/thredded/user_detail.rb +1 -1
- data/app/models/thredded/user_extender.rb +1 -1
- data/app/models/thredded/user_private_topic_read_state.rb +3 -0
- data/app/models/thredded/user_topic_read_state.rb +3 -0
- data/app/view_models/thredded/post_view.rb +1 -0
- data/app/view_models/thredded/posts_page_view.rb +10 -9
- data/app/view_models/thredded/private_topics_page_view.rb +10 -6
- data/app/view_models/thredded/topic_posts_page_view.rb +16 -3
- data/app/view_models/thredded/topics_page_view.rb +9 -6
- data/app/views/layouts/thredded/application.html.erb +2 -2
- data/app/views/thredded/messageboards/_form.html.erb +3 -3
- data/app/views/thredded/posts_common/_actions.html.erb +1 -1
- data/app/views/thredded/posts_common/_content.html.erb +1 -1
- data/app/views/thredded/posts_common/actions/_quote.html.erb +1 -1
- data/app/views/thredded/shared/_page.html.erb +1 -1
- data/app/views/thredded/shared/nav/_moderation.html.erb +3 -3
- data/app/views/thredded/shared/nav/_notification_preferences.html.erb +1 -1
- data/app/views/thredded/shared/nav/_private_topics.html.erb +3 -3
- data/app/views/thredded/shared/nav/_standalone.html.erb +2 -2
- data/app/views/thredded/topics/_header.html.erb +1 -1
- data/bin/create_migration_fixture +23 -0
- data/config/i18n-tasks.yml +5 -0
- data/config/locales/de.yml +2 -0
- data/config/locales/en.yml +3 -1
- data/config/locales/es.yml +2 -0
- data/config/locales/fr.yml +2 -0
- data/config/locales/it.yml +4 -2
- data/config/locales/pl.yml +2 -0
- data/config/locales/pt-BR.yml +2 -0
- data/config/locales/ru.yml +2 -0
- data/config/locales/zh-CN.yml +2 -0
- data/db/upgrade_migrations/20180110200009_upgrade_thredded_v0_14_to_v0_15.rb +1 -1
- data/lib/generators/thredded/install/templates/initializer.rb +2 -2
- data/lib/thredded/arel_compat.rb +0 -32
- data/lib/thredded/base_migration.rb +1 -1
- data/lib/thredded/collection_to_strings_with_cache_renderer.rb +91 -28
- data/lib/thredded/compat.rb +35 -0
- data/lib/thredded/database_seeder.rb +11 -4
- data/lib/thredded/db_tools.rb +2 -4
- data/lib/thredded/email_transformer.rb +2 -2
- data/lib/thredded/html_pipeline/onebox_filter.rb +1 -4
- data/lib/thredded/version.rb +1 -1
- data/lib/thredded.rb +3 -23
- metadata +43 -31
- data/bin/rubocop +0 -18
@@ -1,16 +1,16 @@
|
|
1
1
|
<%= form_for messageboard, html: { class: 'thredded--form' } do |f| %>
|
2
2
|
<ul class="thredded--form-list">
|
3
3
|
<li>
|
4
|
-
<%= f.label t('thredded.messageboard.form.title_label') %>
|
4
|
+
<%= f.label :name, t('thredded.messageboard.form.title_label') %>
|
5
5
|
<%= f.text_field :name, required: true %>
|
6
6
|
<%= render 'thredded/shared/field_errors', messages: f.object.errors[:name] %>
|
7
7
|
</li>
|
8
8
|
<li>
|
9
|
-
<%= f.label t('thredded.messageboard.form.description_label') %>
|
9
|
+
<%= f.label :description, t('thredded.messageboard.form.description_label') %>
|
10
10
|
<%= f.text_field :description %>
|
11
11
|
</li>
|
12
12
|
<li>
|
13
|
-
<%= f.label t('thredded.messageboard.form.messageboard_group_id_label') %>
|
13
|
+
<%= f.label :messageboard_group_id, t('thredded.messageboard.form.messageboard_group_id_label') %>
|
14
14
|
<%= f.collection_select :messageboard_group_id, Thredded::MessageboardGroup.all, :id, :name,
|
15
15
|
include_blank: t('thredded.messageboard.form.no_group') %>
|
16
16
|
</li>
|
@@ -20,7 +20,7 @@
|
|
20
20
|
|
21
21
|
<%- if actions_html.present? %>
|
22
22
|
<div class='thredded--post--dropdown'>
|
23
|
-
<%=
|
23
|
+
<%= inline_svg_tag 'thredded/three-dot-menu.svg', class: 'thredded--post--dropdown--toggle' %>
|
24
24
|
<div class='thredded--post--dropdown--actions'>
|
25
25
|
<%= actions_html %>
|
26
26
|
</div>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= link_to t('thredded.posts.quote_btn'),
|
1
|
+
<%= link_to t('thredded.posts.quote_btn'), post.quote_url_params,
|
2
2
|
'data-thredded-quote-post' => post.quote_path,
|
3
3
|
class: 'thredded--post--quote thredded--post--dropdown--actions--item',
|
4
4
|
rel: 'nofollow' %>
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<%# If thredded JS is loaded via an [async] script, the JS may
|
9
9
|
run before or after DOMContentLoaded. Expose a flag to Thredded
|
10
10
|
so it can initialize correctly. %>
|
11
|
-
<%= javascript_tag 'data-turbolinks-eval': 'false',
|
11
|
+
<%= javascript_tag 'data-turbolinks-eval': 'false', nonce: true do %>
|
12
12
|
document.addEventListener('DOMContentLoaded', function() {
|
13
13
|
(window.Thredded = window.Thredded || {}).DOMContentLoadedFired = true;
|
14
14
|
});
|
@@ -2,9 +2,9 @@
|
|
2
2
|
<% current = current_page_moderation? %>
|
3
3
|
<li class="thredded--user-navigation--item thredded--user-navigation--moderation<%= ' thredded--is-current' if current %>">
|
4
4
|
<%= link_to current ? nav_back_path : pending_moderation_path, rel: 'nofollow' do %>
|
5
|
-
<%=
|
6
|
-
|
7
|
-
|
5
|
+
<%= inline_svg_tag 'thredded/moderation.svg',
|
6
|
+
class: 'thredded--icon',
|
7
|
+
title: t('thredded.nav.moderation') %>
|
8
8
|
<span class="thredded--nav-text"><%= t 'thredded.nav.moderation' %></span>
|
9
9
|
<% if posts_pending_moderation_count > 0 %>
|
10
10
|
<span class="thredded--user-navigation--moderation--pending-count"><%= posts_pending_moderation_count %></span>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<% current = current_page_preferences? %>
|
2
2
|
<li class="thredded--user-navigation--settings thredded--user-navigation--item<%= ' thredded--is-current' if current %>">
|
3
3
|
<%= link_to current ? nav_back_path(messageboard) : edit_preferences_path(messageboard), rel: 'nofollow' do %>
|
4
|
-
<%=
|
4
|
+
<%= inline_svg_tag 'thredded/settings.svg', class: 'thredded--icon', title: t('thredded.nav.settings') %>
|
5
5
|
<span class="thredded--nav-text"><%= t('thredded.nav.settings') %></span>
|
6
6
|
<% end %>
|
7
7
|
</li>
|
@@ -1,9 +1,9 @@
|
|
1
1
|
<% current = current_page_private_topics? %>
|
2
2
|
<li class="thredded--user-navigation--item thredded--user-navigation--private-topics<%= ' thredded--is-current' if current %>">
|
3
3
|
<%= link_to current ? nav_back_path : private_topics_path, rel: 'nofollow' do %>
|
4
|
-
<%=
|
5
|
-
|
6
|
-
|
4
|
+
<%= inline_svg_tag 'thredded/private-messages.svg',
|
5
|
+
class: 'thredded--icon',
|
6
|
+
title: t('thredded.nav.private_topics') %>
|
7
7
|
<span class="thredded--nav-text"><%= t('thredded.nav.private_topics') %></span>
|
8
8
|
<% if unread_private_topics_count > 0 -%>
|
9
9
|
<span class="thredded--user-navigation--private-topics--unread"><%= unread_private_topics_count %></span>
|
@@ -2,11 +2,11 @@
|
|
2
2
|
<% resource_name = Thredded.user_class_name.demodulize.underscore %>
|
3
3
|
<% if thredded_signed_in? %>
|
4
4
|
<%= link_to main_app.send(:"destroy_#{resource_name}_session_path"), method: :delete do %>
|
5
|
-
|
5
|
+
t('thredded.nav.sign_out')
|
6
6
|
<% end %>
|
7
7
|
<% else %>
|
8
8
|
<%= link_to main_app.send(:"new_#{resource_name}_session_path") do %>
|
9
|
-
|
9
|
+
t('thredded.nav.sign_in')
|
10
10
|
<% end %>
|
11
11
|
<% end %>
|
12
12
|
</li>
|
@@ -20,7 +20,7 @@
|
|
20
20
|
</span>
|
21
21
|
<%= button_to topic.unfollow_path, form: {class: 'thredded--topic-header--follow-info--unfollow'} do %>
|
22
22
|
<%= t('thredded.topics.unfollow') %>
|
23
|
-
<%=
|
23
|
+
<%= inline_svg_tag 'thredded/follow.svg', class: 'thredded--topic-header--follow-icon' %>
|
24
24
|
<% end %>
|
25
25
|
</div>
|
26
26
|
<% else %>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# edit constants in lib/thredded/db_tools.rb
|
4
|
+
# git checkout v0.x.0 -b create-0.x-migration-fixture
|
5
|
+
# bundle
|
6
|
+
|
7
|
+
DIR=$(pwd)
|
8
|
+
|
9
|
+
cd spec/dummy && DB=sqlite3 rails db:environment:set RAILS_ENV=development
|
10
|
+
cd $DIR
|
11
|
+
DB=sqlite3 rake db:drop db:create db:migrate db:miniseed_dump
|
12
|
+
|
13
|
+
cd spec/dummy && DB=postgresql rails db:environment:set RAILS_ENV=development
|
14
|
+
cd $DIR
|
15
|
+
DB=postgresql rake db:drop db:create db:migrate db:miniseed_dump
|
16
|
+
|
17
|
+
cd spec/dummy && DB=mysql2 rails db:environment:set RAILS_ENV=development
|
18
|
+
cd $DIR
|
19
|
+
DB=mysql2 rake db:drop db:create db:migrate db:miniseed_dump
|
20
|
+
|
21
|
+
git add `pwd`/spec/migration/*.dump
|
22
|
+
|
23
|
+
git commit -em "add sample data for 0.8 base for migration spec"
|
data/config/i18n-tasks.yml
CHANGED
data/config/locales/de.yml
CHANGED
data/config/locales/en.yml
CHANGED
@@ -127,6 +127,8 @@ en:
|
|
127
127
|
moderation_users: Users
|
128
128
|
private_topics: Private Messages
|
129
129
|
settings: Notification Settings
|
130
|
+
sign_in: Sign In / Register
|
131
|
+
sign_out: Sign Out
|
130
132
|
unread_topics: Unread
|
131
133
|
null_user_name: Deleted user
|
132
134
|
posts:
|
@@ -262,7 +264,7 @@ en:
|
|
262
264
|
last_active_html: Last active %{time_ago}
|
263
265
|
posted_in_topic_html: Posted in %{topic_link}
|
264
266
|
posts_count:
|
265
|
-
one: Posted
|
267
|
+
one: Posted once
|
266
268
|
other: Posted %{count} times
|
267
269
|
recent_activity: :thredded.recent_activity
|
268
270
|
send_private_message: Send private message
|
data/config/locales/es.yml
CHANGED
data/config/locales/fr.yml
CHANGED
data/config/locales/it.yml
CHANGED
@@ -127,6 +127,8 @@ it:
|
|
127
127
|
moderation_users: Utenti
|
128
128
|
private_topics: Messaggi Privati
|
129
129
|
settings: Impostazioni Notifiche
|
130
|
+
sign_in: Entra
|
131
|
+
sign_out: Esci
|
130
132
|
unread_topics: Non letto
|
131
133
|
null_user_name: Utente cancellato
|
132
134
|
posts:
|
@@ -266,13 +268,13 @@ it:
|
|
266
268
|
last_active_html: Ultima attività %{time_ago}
|
267
269
|
posted_in_topic_html: Ha scritto in %{topic_link}
|
268
270
|
posts_count:
|
269
|
-
one: Ha commentato
|
271
|
+
one: Ha commentato una volta
|
270
272
|
other: Ha commentato %{count} volte
|
271
273
|
recent_activity: :thredded.recent_activity
|
272
274
|
send_private_message: Invia un messaggio privato
|
273
275
|
started_topic_html: Ha iniziato %{topic_link}
|
274
276
|
started_topics_count:
|
275
|
-
one: Ha iniziato
|
277
|
+
one: Ha iniziato una discussione
|
276
278
|
other: Ha iniziato %{count} discussioni
|
277
279
|
user_posted_in_topic_html: "%{user_link} ha commentato in %{topic_link}"
|
278
280
|
user_since_html: Utente da %{time_ago}
|
data/config/locales/pl.yml
CHANGED
data/config/locales/pt-BR.yml
CHANGED
data/config/locales/ru.yml
CHANGED
data/config/locales/zh-CN.yml
CHANGED
@@ -86,6 +86,6 @@ class UpgradeThreddedV014ToV015 < Thredded::BaseMigration
|
|
86
86
|
def remove_string_limit(table, column, type: :text, indices: [])
|
87
87
|
indices.each { |(_, options)| remove_index table, name: options[:name] }
|
88
88
|
change_column table, column, type, limit: nil
|
89
|
-
indices.each { |
|
89
|
+
indices.each { |(columns, options)| add_index table, columns, **options }
|
90
90
|
end
|
91
91
|
end
|
@@ -29,8 +29,8 @@ Thredded.user_path = ->(user) {
|
|
29
29
|
# This method is used by Thredded controllers and views to fetch the currently signed-in user
|
30
30
|
Thredded.current_user_method = :"current_#{Thredded.user_class_name.demodulize.underscore}"
|
31
31
|
|
32
|
-
# User avatar URL.
|
33
|
-
Thredded.avatar_url = ->(user) {
|
32
|
+
# User avatar URL. rails_gravatar gem is used by default:
|
33
|
+
Thredded.avatar_url = ->(user) { RailsGravatar.src(user.email, 156, 'mm') }
|
34
34
|
|
35
35
|
# ==> Permissions Configuration
|
36
36
|
# By default, thredded uses a simple permission model, where all the users can post to all message boards,
|
data/lib/thredded/arel_compat.rb
CHANGED
@@ -1,27 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
unless Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR >= 2 || Rails::VERSION::MAJOR > 5
|
4
|
-
require 'thredded/rails_lt_5_2_arel_case_node.rb'
|
5
|
-
end
|
6
|
-
|
7
|
-
if Rails::VERSION::MAJOR == 4
|
8
|
-
# Make `pluck` compatible with Arel.
|
9
|
-
require 'active_record/relation'
|
10
|
-
ActiveRecord::Relation.prepend(Module.new do
|
11
|
-
def pluck(*column_names)
|
12
|
-
super(*column_names.map do |n|
|
13
|
-
if n.is_a?(Arel::Node)
|
14
|
-
Arel.sql(n.to_sql)
|
15
|
-
elsif n.is_a?(Arel::Attributes::Attribute)
|
16
|
-
n.name
|
17
|
-
else
|
18
|
-
n
|
19
|
-
end
|
20
|
-
end)
|
21
|
-
end
|
22
|
-
end)
|
23
|
-
end
|
24
|
-
|
25
3
|
module Thredded
|
26
4
|
module ArelCompat
|
27
5
|
module_function
|
@@ -37,15 +15,5 @@ module Thredded
|
|
37
15
|
Arel::Nodes::Division.new(a, b)
|
38
16
|
end
|
39
17
|
end
|
40
|
-
|
41
|
-
if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR >= 2 || Rails::VERSION::MAJOR > 5
|
42
|
-
def true_value(_engine)
|
43
|
-
true
|
44
|
-
end
|
45
|
-
else
|
46
|
-
def true_value(engine)
|
47
|
-
engine.connection.adapter_name =~ /sqlite|mysql|mariadb/i ? 1 : true
|
48
|
-
end
|
49
|
-
end
|
50
18
|
end
|
51
19
|
end
|
@@ -22,17 +22,18 @@ module Thredded
|
|
22
22
|
def render_collection_to_strings_with_cache( # rubocop:disable Metrics/ParameterLists
|
23
23
|
view_context, collection:, partial:, expires_in:, render_threads: self.class.render_threads, locals: {}, **opts
|
24
24
|
)
|
25
|
-
template = @lookup_context.find_template(partial, [], true, locals, {})
|
25
|
+
template = @lookup_context.find_template(partial, [], true, locals.keys, {})
|
26
26
|
collection = collection.to_a
|
27
|
-
instrument(:collection,
|
27
|
+
ActiveSupport::Notifications.instrument(:collection,
|
28
|
+
identifier: template.identifier,
|
29
|
+
count: collection.size) do |instrumentation_payload|
|
28
30
|
return [] if collection.blank?
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
31
|
+
|
32
|
+
# Result is a hash with the key represents the
|
33
|
+
# key used for cache lookup and the value is the item
|
34
|
+
# on which the partial is being rendered
|
35
|
+
keyed_collection, ordered_keys = collection_by_cache_keys(collection, view_context, template)
|
36
|
+
|
36
37
|
cache = collection_cache
|
37
38
|
cached_partials = cache.read_multi(*keyed_collection.keys)
|
38
39
|
instrumentation_payload[:cache_hits] = cached_partials.size if instrumentation_payload
|
@@ -44,9 +45,9 @@ module Thredded
|
|
44
45
|
partial: partial, locals: locals, **opts
|
45
46
|
).each
|
46
47
|
|
47
|
-
|
48
|
-
[
|
49
|
-
cache.write(cache_key, rendered, expires_in: expires_in)
|
48
|
+
ordered_keys.map do |cache_key|
|
49
|
+
[keyed_collection[cache_key], cached_partials[cache_key] || rendered_partials.next.tap do |rendered|
|
50
|
+
cached_partials[cache_key] = cache.write(cache_key, rendered, expires_in: expires_in)
|
50
51
|
end]
|
51
52
|
end
|
52
53
|
end
|
@@ -54,16 +55,24 @@ module Thredded
|
|
54
55
|
|
55
56
|
private
|
56
57
|
|
57
|
-
def
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
58
|
+
def collection_by_cache_keys(collection, view, template)
|
59
|
+
digest_path = digest_path_from_template(view, template)
|
60
|
+
|
61
|
+
collection.each_with_object([{}, []]) do |item, (hash, ordered_keys)|
|
62
|
+
key = expanded_cache_key(item, view, template, digest_path)
|
63
|
+
ordered_keys << key
|
64
|
+
hash[key] = item
|
64
65
|
end
|
65
66
|
end
|
66
67
|
|
68
|
+
def expanded_cache_key(key, view, template, digest_path)
|
69
|
+
key = combined_fragment_cache_key(
|
70
|
+
view,
|
71
|
+
cache_fragment_name(view, key, virtual_path: template.virtual_path, digest_path: digest_path)
|
72
|
+
)
|
73
|
+
key.frozen? ? key.dup : key # #read_multi & #write may require mutability, Dalli 2.6.0.
|
74
|
+
end
|
75
|
+
|
67
76
|
# @return [Array<String>]
|
68
77
|
def render_partials(view_context, collection:, render_threads:, **opts)
|
69
78
|
return [] if collection.empty?
|
@@ -72,25 +81,79 @@ module Thredded
|
|
72
81
|
render_partials_serial(view_context, collection, opts)
|
73
82
|
else
|
74
83
|
collection.each_slice(collection.size / num_threads).map do |slice|
|
75
|
-
Thread.start
|
84
|
+
Thread.start do
|
85
|
+
# `ActionView::PartialRenderer` mutates the contents of `opts[:locals]`, `opts[:locals][:as]` in particular:
|
86
|
+
# https://github.com/rails/rails/blob/v6.0.2.1/actionview/lib/action_view/renderer/partial_renderer.rb#L379
|
87
|
+
# https://github.com/rails/rails/blob/v6.0.2.1/actionview/lib/action_view/renderer/partial_renderer.rb#L348-L356
|
88
|
+
opts[:locals] = opts[:locals].dup if opts[:locals]
|
89
|
+
ActiveRecord::Base.connection_pool.with_connection do
|
90
|
+
render_partials_serial(view_context.dup, slice, opts)
|
91
|
+
end
|
92
|
+
end
|
76
93
|
end.flat_map(&:value)
|
77
94
|
end
|
78
95
|
end
|
79
96
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
97
|
+
if Thredded::Compat.rails_gte_61?
|
98
|
+
# @param [Array<Object>] collection
|
99
|
+
# @param [Hash] opts
|
100
|
+
# @param view_context
|
101
|
+
# @return [Array<String>]
|
102
|
+
def render_partials_serial(view_context, collection, opts)
|
103
|
+
# https://github.com/rails/rails/pull/38594
|
104
|
+
collection.map do |object|
|
105
|
+
renderer = ActionView::ObjectRenderer.new(@lookup_context, opts)
|
106
|
+
renderer.render_object_with_partial(object, opts[:partial], view_context, nil).body
|
107
|
+
end
|
108
|
+
end
|
109
|
+
else
|
110
|
+
def render_partials_serial(view_context, collection, opts)
|
111
|
+
partial_renderer = ActionView::PartialRenderer.new(@lookup_context)
|
112
|
+
collection.map { |object| render_partial(partial_renderer, view_context, **opts.merge(object: object)) }
|
113
|
+
end
|
87
114
|
end
|
88
115
|
|
89
|
-
|
116
|
+
def collection_cache
|
117
|
+
ActionView::PartialRenderer.collection_cache
|
118
|
+
end
|
119
|
+
|
120
|
+
def combined_fragment_cache_key(view, key)
|
121
|
+
view.combined_fragment_cache_key(key)
|
122
|
+
end
|
123
|
+
|
124
|
+
if Thredded::Compat.rails_gte_60?
|
125
|
+
def cache_fragment_name(view, key, virtual_path:, digest_path:)
|
126
|
+
if Thredded::Compat.rails_gte_61?
|
127
|
+
view.cache_fragment_name(key, digest_path: digest_path)
|
128
|
+
else
|
129
|
+
view.cache_fragment_name(key, virtual_path: virtual_path, digest_path: digest_path)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def digest_path_from_template(view, template)
|
134
|
+
view.digest_path_from_template(template)
|
135
|
+
end
|
136
|
+
|
90
137
|
def render_partial(partial_renderer, view_context, opts)
|
91
138
|
partial_renderer.render(view_context, opts, nil).body
|
92
139
|
end
|
93
140
|
else
|
141
|
+
def cache_fragment_name(_view, key, virtual_path:, digest_path:)
|
142
|
+
if digest_path
|
143
|
+
["#{virtual_path}:#{digest_path}", key]
|
144
|
+
else
|
145
|
+
[virtual_path, key]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def digest_path_from_template(view, template)
|
150
|
+
ActionView::Digestor.digest(
|
151
|
+
name: template.virtual_path,
|
152
|
+
finder: @lookup_context,
|
153
|
+
dependencies: view.view_cache_dependencies
|
154
|
+
).presence
|
155
|
+
end
|
156
|
+
|
94
157
|
def render_partial(partial_renderer, view_context, opts)
|
95
158
|
partial_renderer.render(view_context, opts, nil)
|
96
159
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Thredded
|
4
|
+
module Compat
|
5
|
+
class << self
|
6
|
+
# @api private
|
7
|
+
def rails_gte_60?
|
8
|
+
@rails_gte_60 = (Rails.gem_version >= Gem::Version.new('6.0.0')) if @rails_gte_60.nil?
|
9
|
+
@rails_gte_60
|
10
|
+
end
|
11
|
+
|
12
|
+
# @api private
|
13
|
+
def rails_gte_61?
|
14
|
+
@rails_gte_61 = (Rails.gem_version >= Gem::Version.new('6.1.0')) if @rails_gte_61.nil?
|
15
|
+
@rails_gte_61
|
16
|
+
end
|
17
|
+
|
18
|
+
if Rails.gem_version >= Gem::Version.new('7.0.0')
|
19
|
+
# @api private
|
20
|
+
def association_preloader(records:, associations:, scope:)
|
21
|
+
ActiveRecord::Associations::Preloader.new(
|
22
|
+
records: records, associations: associations, scope: scope
|
23
|
+
).call
|
24
|
+
end
|
25
|
+
else
|
26
|
+
# @api private
|
27
|
+
def association_preloader(records:, associations:, scope:)
|
28
|
+
ActiveRecord::Associations::Preloader.new.preload(
|
29
|
+
records, associations, scope
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'factory_bot'
|
4
|
-
require_relative '../../spec/support/
|
4
|
+
require_relative '../../spec/support/system/fake_content'
|
5
5
|
|
6
6
|
# rubocop:disable HandleExceptions
|
7
7
|
begin
|
@@ -40,6 +40,7 @@ module Thredded
|
|
40
40
|
end
|
41
41
|
|
42
42
|
include LogTime
|
43
|
+
include Thredded::ApplicationHelper
|
43
44
|
|
44
45
|
SKIP_CALLBACKS = [
|
45
46
|
[Thredded::Post, :commit, :after, :update_parent_last_user_and_time_from_last_post, on: %i[create destroy]],
|
@@ -131,7 +132,13 @@ module Thredded
|
|
131
132
|
end
|
132
133
|
|
133
134
|
def fake_post_contents
|
134
|
-
@fake_post_contents ? @fake_post_contents.sample : FakeContent.post_content
|
135
|
+
with_mentions(@fake_post_contents ? @fake_post_contents.sample : FakeContent.post_content)
|
136
|
+
end
|
137
|
+
|
138
|
+
def with_mentions(post, mentions_count: rand(3))
|
139
|
+
return post if mentions_count.zero?
|
140
|
+
|
141
|
+
([post] + Array.new(mentions_count).map { user_mention(@users.sample) }).join(' ')
|
135
142
|
end
|
136
143
|
|
137
144
|
def first_user
|
@@ -255,9 +262,9 @@ module Thredded
|
|
255
262
|
|
256
263
|
delegate :log, to: :seeder
|
257
264
|
|
258
|
-
def find_or_create(*args)
|
265
|
+
def find_or_create(*args, **kwargs)
|
259
266
|
return @stored if @stored
|
260
|
-
@stored = (find || create(*args))
|
267
|
+
@stored = (find || create(*args, **kwargs))
|
261
268
|
end
|
262
269
|
|
263
270
|
def range_of_dates_in_order(up_to: Time.zone.now, count: 1)
|
data/lib/thredded/db_tools.rb
CHANGED
@@ -10,12 +10,10 @@ module Thredded
|
|
10
10
|
verbose_was = ActiveRecord::Migration.verbose
|
11
11
|
ActiveRecord::Migration.verbose = !quiet
|
12
12
|
migrate =
|
13
|
-
if
|
13
|
+
if Thredded::Compat.rails_gte_60?
|
14
14
|
-> { ActiveRecord::MigrationContext.new(paths, ActiveRecord::SchemaMigration).migrate(nil, &filter) }
|
15
|
-
|
15
|
+
else # Rails 5.2
|
16
16
|
-> { ActiveRecord::MigrationContext.new(paths).migrate(nil, &filter) }
|
17
|
-
else
|
18
|
-
-> { ActiveRecord::Migrator.migrate(paths, &filter) }
|
19
17
|
end
|
20
18
|
if quiet
|
21
19
|
silence_active_record(&migrate)
|
@@ -17,8 +17,8 @@ module Thredded
|
|
17
17
|
end
|
18
18
|
@transformers = [Onebox, Spoiler]
|
19
19
|
|
20
|
-
# @param
|
21
|
-
def self.call(doc)
|
20
|
+
# @param dom [Nokogiri::HTML::Document]
|
21
|
+
def self.call(doc, *)
|
22
22
|
transformers.each { |transformer| transformer.call(doc) }
|
23
23
|
end
|
24
24
|
end
|
@@ -39,12 +39,10 @@ module Thredded
|
|
39
39
|
# Regardless, always store the onebox in a file cache to enable offline development,
|
40
40
|
# persistence between test runs, and to improve performance.
|
41
41
|
attr_accessor :onebox_views_cache
|
42
|
-
attr_accessor :onebox_data_cache
|
43
42
|
end
|
44
43
|
|
45
44
|
if Rails.env.development? || Rails.env.test?
|
46
45
|
self.onebox_views_cache = ActiveSupport::Cache::FileStore.new('tmp/cache/onebox-views')
|
47
|
-
self.onebox_data_cache = ActiveSupport::Cache::FileStore.new('tmp/cache/onebox-data')
|
48
46
|
end
|
49
47
|
|
50
48
|
def call
|
@@ -84,8 +82,7 @@ module Thredded
|
|
84
82
|
end
|
85
83
|
|
86
84
|
def onebox_options(_url)
|
87
|
-
{
|
88
|
-
sanitize_config: SANITIZE_CONFIG }
|
85
|
+
{ sanitize_config: SANITIZE_CONFIG }
|
89
86
|
end
|
90
87
|
|
91
88
|
def onebox_views_cache
|
data/lib/thredded/version.rb
CHANGED