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