thredded 0.13.0 → 0.14.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.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +29 -25
  3. data/app/assets/images/thredded/lock.svg +1 -0
  4. data/app/assets/javascripts/thredded/components/mention_autocompletion.es6 +2 -1
  5. data/app/assets/javascripts/thredded/components/post_form.es6 +1 -1
  6. data/app/assets/javascripts/thredded/components/time_stamps.es6 +1 -1
  7. data/app/assets/javascripts/thredded/components/topic_form.es6 +1 -1
  8. data/app/assets/javascripts/thredded/components/users_select.es6 +1 -1
  9. data/app/assets/javascripts/thredded/dependencies/autosize.js +1 -0
  10. data/app/assets/javascripts/thredded/dependencies.js +1 -1
  11. data/app/assets/stylesheets/thredded/base/_variables.scss +4 -0
  12. data/app/assets/stylesheets/thredded/components/_form-list.scss +2 -1
  13. data/app/assets/stylesheets/thredded/components/_messageboard.scss +10 -1
  14. data/app/assets/stylesheets/thredded/components/_onebox.scss +0 -9
  15. data/app/assets/stylesheets/thredded/components/_post.scss +7 -1
  16. data/app/assets/stylesheets/thredded/components/_topics.scss +12 -0
  17. data/app/commands/thredded/create_messageboard.rb +3 -3
  18. data/app/commands/thredded/mark_all_read.rb +1 -1
  19. data/app/commands/thredded/notify_following_users.rb +40 -22
  20. data/app/commands/thredded/notify_private_topic_users.rb +1 -1
  21. data/app/controllers/concerns/thredded/new_post_params.rb +1 -1
  22. data/app/controllers/concerns/thredded/new_private_post_params.rb +1 -1
  23. data/app/controllers/thredded/application_controller.rb +1 -1
  24. data/app/controllers/thredded/autocomplete_users_controller.rb +1 -1
  25. data/app/controllers/thredded/messageboard_groups_controller.rb +2 -2
  26. data/app/controllers/thredded/messageboards_controller.rb +7 -7
  27. data/app/controllers/thredded/moderation_controller.rb +1 -1
  28. data/app/controllers/thredded/post_permalinks_controller.rb +1 -1
  29. data/app/controllers/thredded/post_previews_controller.rb +3 -3
  30. data/app/controllers/thredded/posts_controller.rb +9 -5
  31. data/app/controllers/thredded/preferences_controller.rb +2 -2
  32. data/app/controllers/thredded/private_post_permalinks_controller.rb +1 -1
  33. data/app/controllers/thredded/private_post_previews_controller.rb +3 -3
  34. data/app/controllers/thredded/private_posts_controller.rb +5 -5
  35. data/app/controllers/thredded/private_topic_previews_controller.rb +1 -1
  36. data/app/controllers/thredded/read_states_controller.rb +1 -1
  37. data/app/controllers/thredded/theme_previews_controller.rb +23 -23
  38. data/app/controllers/thredded/topic_previews_controller.rb +1 -1
  39. data/app/forms/thredded/private_topic_form.rb +1 -1
  40. data/app/forms/thredded/topic_form.rb +2 -2
  41. data/app/forms/thredded/user_preferences_form.rb +2 -2
  42. data/app/helpers/thredded/render_helper.rb +1 -1
  43. data/app/jobs/thredded/auto_follow_and_notify_job.rb +3 -3
  44. data/app/mailer_previews/thredded/base_mailer_preview.rb +5 -5
  45. data/app/mailer_previews/thredded/private_topic_mailer_preview.rb +1 -5
  46. data/app/mailers/thredded/post_mailer.rb +11 -6
  47. data/app/mailers/thredded/private_topic_mailer.rb +12 -8
  48. data/app/models/concerns/thredded/content_moderation_state.rb +1 -1
  49. data/app/models/thredded/topic.rb +1 -1
  50. data/app/models/thredded/user_permissions/moderate/if_moderator_column_true.rb +0 -11
  51. data/app/models/thredded/user_permissions/moderate/none.rb +0 -11
  52. data/app/models/thredded/user_permissions/write/all.rb +0 -11
  53. data/app/models/thredded/user_permissions/write/none.rb +0 -11
  54. data/app/models/thredded/user_topic_follow.rb +4 -2
  55. data/app/notifiers/thredded/email_notifier.rb +6 -2
  56. data/app/policies/thredded/messageboard_policy.rb +3 -1
  57. data/app/policies/thredded/post_policy.rb +5 -1
  58. data/app/view_models/thredded/private_topic_view.rb +1 -1
  59. data/app/view_models/thredded/topic_email_view.rb +0 -4
  60. data/app/views/thredded/messageboards/_form.html.erb +6 -0
  61. data/app/views/thredded/messageboards/_messageboard.html.erb +1 -5
  62. data/app/views/thredded/messageboards/_messageboard_meta.html.erb +13 -0
  63. data/app/views/thredded/moderation/users.html.erb +2 -2
  64. data/app/views/thredded/post_mailer/post_notification.html.erb +9 -6
  65. data/app/views/thredded/post_mailer/post_notification.text.erb +9 -5
  66. data/app/views/thredded/preferences/_form.html.erb +9 -9
  67. data/app/views/thredded/private_topic_mailer/message_notification.html.erb +10 -4
  68. data/app/views/thredded/private_topic_mailer/message_notification.text.erb +11 -8
  69. data/app/views/thredded/private_topics/new.html.erb +1 -1
  70. data/app/views/thredded/shared/nav/_standalone.html.erb +1 -1
  71. data/app/views/thredded/theme_previews/show.html.erb +6 -4
  72. data/app/views/thredded/topics/_topic.html.erb +2 -1
  73. data/app/views/thredded/topics/index.html.erb +6 -1
  74. data/app/views/thredded/topics/new.html.erb +1 -1
  75. data/app/views/thredded/topics/show.html.erb +4 -0
  76. data/config/locales/de.yml +249 -0
  77. data/config/locales/en.yml +43 -0
  78. data/config/locales/es.yml +45 -0
  79. data/config/locales/fr.yml +247 -0
  80. data/config/locales/pl.yml +43 -0
  81. data/config/locales/pt-BR.yml +45 -0
  82. data/config/locales/ru.yml +43 -1
  83. data/config/locales/zh-CN.yml +238 -0
  84. data/db/migrate/20160329231848_create_thredded.rb +3 -2
  85. data/db/upgrade_migrations/20170811090735_upgrade_thredded_v0_13_to_v_014.rb +21 -0
  86. data/lib/generators/thredded/install/templates/initializer.rb +3 -3
  87. data/lib/thredded/database_seeder.rb +12 -12
  88. data/lib/thredded/engine.rb +1 -1
  89. data/lib/thredded/html_pipeline/onebox_filter.rb +2 -1
  90. data/lib/thredded/version.rb +1 -1
  91. data/lib/thredded.rb +2 -1
  92. data/vendor/assets/javascripts/autosize.min.js +6 -0
  93. data/vendor/assets/javascripts/textcomplete.min.js +2 -1
  94. metadata +19 -12
  95. data/vendor/assets/javascripts/autosize.js +0 -290
  96. /data/{app/notifiers → lib}/thredded/base_notifier.rb +0 -0
@@ -6,14 +6,14 @@ module Thredded
6
6
 
7
7
  # Preview a new post
8
8
  def preview
9
- @private_post = PrivatePost.new(private_post_params)
10
- @private_post.postable = PrivateTopic.friendly_find!(params[:private_topic_id])
9
+ @private_post = Thredded::PrivatePost.new(private_post_params)
10
+ @private_post.postable = Thredded::PrivateTopic.friendly_find!(params[:private_topic_id])
11
11
  render_preview
12
12
  end
13
13
 
14
14
  # Preview an update to an existing post
15
15
  def update
16
- @private_post = PrivatePost.find(params[:private_post_id])
16
+ @private_post = Thredded::PrivatePost.find(params[:private_post_id])
17
17
  @private_post.assign_attributes(private_post_params)
18
18
  render_preview
19
19
  end
@@ -12,14 +12,14 @@ module Thredded
12
12
  after_action :verify_authorized
13
13
 
14
14
  def new
15
- @post_form = PrivatePostForm.new(
15
+ @post_form = Thredded::PrivatePostForm.new(
16
16
  user: thredded_current_user, topic: parent_topic, post_params: new_private_post_params
17
17
  )
18
18
  authorize_creating @post_form.post
19
19
  end
20
20
 
21
21
  def create
22
- @post_form = PrivatePostForm.new(
22
+ @post_form = Thredded::PrivatePostForm.new(
23
23
  user: thredded_current_user, topic: parent_topic, post_params: new_private_post_params
24
24
  )
25
25
  authorize_creating @post_form.post
@@ -31,7 +31,7 @@ module Thredded
31
31
  end
32
32
 
33
33
  def edit
34
- @post_form = PrivatePostForm.for_persisted(post)
34
+ @post_form = Thredded::PrivatePostForm.for_persisted(post)
35
35
  authorize @post_form.post, :update?
36
36
  return redirect_to(canonical_topic_params) unless params_match?(canonical_topic_params)
37
37
  render
@@ -39,7 +39,7 @@ module Thredded
39
39
 
40
40
  def update
41
41
  authorize post, :update?
42
- post.update_attributes(post_params.except(:user, :ip))
42
+ post.update(new_private_post_params)
43
43
 
44
44
  redirect_to post_path(post, user: thredded_current_user)
45
45
  end
@@ -79,7 +79,7 @@ module Thredded
79
79
  end
80
80
 
81
81
  def parent_topic
82
- PrivateTopic
82
+ Thredded::PrivateTopic
83
83
  .includes(:private_users)
84
84
  .friendly
85
85
  .find(params[:private_topic_id])
@@ -6,7 +6,7 @@ module Thredded
6
6
  include Thredded::RenderPreview
7
7
 
8
8
  def preview
9
- form = PrivateTopicForm.new(new_private_topic_params)
9
+ form = Thredded::PrivateTopicForm.new(new_private_topic_params)
10
10
  @private_post = form.post
11
11
  @private_post.postable = form.private_topic
12
12
  render_preview
@@ -5,7 +5,7 @@ module Thredded
5
5
  before_action :thredded_require_login!
6
6
 
7
7
  def update
8
- MarkAllRead.run(thredded_current_user) if thredded_signed_in?
8
+ Thredded::MarkAllRead.run(thredded_current_user) if thredded_signed_in?
9
9
 
10
10
  redirect_to request.referer
11
11
  end
@@ -3,32 +3,32 @@
3
3
  module Thredded
4
4
  class ThemePreviewsController < Thredded::ApplicationController
5
5
  def show # rubocop:disable Metrics/MethodLength
6
- @messageboard = Messageboard.first
6
+ @messageboard = Thredded::Messageboard.first
7
7
  fail Thredded::Errors::DatabaseEmpty unless @messageboard
8
- @user = if thredded_current_user.thredded_anonymous?
9
- Thredded.user_class.new(id: 1334, name: 'joe', email: 'joe@example.com')
10
- else
11
- thredded_current_user
12
- end
13
- @messageboards = Messageboard.all
14
- @topics = TopicsPageView.new(@user, @messageboard.topics.page(1).limit(3))
15
- @private_topics = PrivateTopicsPageView.new(@user, @user.thredded_private_topics.page(1).limit(3))
16
- topic = Topic.new(messageboard: @messageboard, title: 'Hello', slug: 'hello', user: @user)
17
- @topic = TopicView.from_user(topic, @user)
18
- @posts = TopicPostsPageView.new(@user, topic, topic.posts.page(1).limit(3))
19
- @post = topic.posts.build(id: 1337, postable: topic, content: 'Hello world', user: @user)
20
- @post_form = PostForm.for_persisted(@post)
21
- @new_post = PostForm.new(user: @user, topic: topic)
22
- @new_topic = TopicForm.new(user: @user, messageboard: @messageboard)
23
- @new_private_topic = PrivateTopicForm.new(user: @user)
24
- private_topic = PrivateTopic.new(id: 1337, title: 'Hello', user: @user, last_user: @user, users: [@user])
25
- @private_topic = PrivateTopicView.from_user(private_topic, @user)
26
- @private_posts = TopicPostsPageView.new(@user, private_topic, private_topic.posts.page(1).limit(3))
27
- @private_post = private_topic.posts.build(
8
+ @user = if thredded_current_user.thredded_anonymous?
9
+ Thredded.user_class.new(id: 1334, name: 'joe', email: 'joe@example.com')
10
+ else
11
+ thredded_current_user
12
+ end
13
+ @messageboards = Thredded::Messageboard.all
14
+ @topics = Thredded::TopicsPageView.new(@user, @messageboard.topics.page(1).limit(3))
15
+ @private_topics = Thredded::PrivateTopicsPageView.new(@user, @user.thredded_private_topics.page(1).limit(3))
16
+ topic = Thredded::Topic.new(messageboard: @messageboard, title: 'Hello', slug: 'hello', user: @user)
17
+ @topic = Thredded::TopicView.from_user(topic, @user)
18
+ @posts = Thredded::TopicPostsPageView.new(@user, topic, topic.posts.page(1).limit(3))
19
+ @post = topic.posts.build(id: 1337, postable: topic, content: 'Hello world', user: @user)
20
+ @post_form = Thredded::PostForm.for_persisted(@post)
21
+ @new_post = Thredded::PostForm.new(user: @user, topic: topic)
22
+ @new_topic = Thredded::TopicForm.new(user: @user, messageboard: @messageboard)
23
+ @new_private_topic = Thredded::PrivateTopicForm.new(user: @user)
24
+ private_topic = Thredded::PrivateTopic.new(id: 17, title: 'Hello', user: @user, last_user: @user, users: [@user])
25
+ @private_topic = Thredded::PrivateTopicView.from_user(private_topic, @user)
26
+ @private_posts = Thredded::TopicPostsPageView.new(@user, private_topic, private_topic.posts.page(1).limit(3))
27
+ @private_post = private_topic.posts.build(
28
28
  id: 1337, postable: private_topic, content: 'A private hello world', user: @user
29
29
  )
30
- @private_post_form = PrivatePostForm.for_persisted(@private_post)
31
- @preferences = UserPreferencesForm.new(user: @user, messageboard: @messageboard)
30
+ @private_post_form = Thredded::PrivatePostForm.for_persisted(@private_post)
31
+ @preferences = Thredded::UserPreferencesForm.new(user: @user, messageboard: @messageboard)
32
32
  end
33
33
  end
34
34
  end
@@ -6,7 +6,7 @@ module Thredded
6
6
  include Thredded::RenderPreview
7
7
 
8
8
  def preview
9
- form = TopicForm.new(new_topic_params)
9
+ form = Thredded::TopicForm.new(new_topic_params)
10
10
  @post = form.post
11
11
  @post.postable = form.topic
12
12
  render_preview
@@ -89,7 +89,7 @@ module Thredded
89
89
  def topic_categories
90
90
  if category_ids
91
91
  ids = category_ids.reject(&:empty?)
92
- Category.where(id: ids)
92
+ Thredded::Category.where(id: ids)
93
93
  else
94
94
  []
95
95
  end
@@ -33,7 +33,7 @@ module Thredded
33
33
  ActiveRecord::Base.transaction do
34
34
  topic.save!
35
35
  post.save!
36
- UserTopicReadState.read_on_first_post!(user, topic) if topic.previous_changes.include?(:id)
36
+ Thredded::UserTopicReadState.read_on_first_post!(user, topic) if topic.previous_changes.include?(:id)
37
37
  end
38
38
  true
39
39
  end
@@ -75,7 +75,7 @@ module Thredded
75
75
  def topic_categories
76
76
  if category_ids
77
77
  ids = category_ids.reject(&:empty?)
78
- Category.where(id: ids)
78
+ Thredded::Category.where(id: ids)
79
79
  else
80
80
  []
81
81
  end
@@ -39,7 +39,7 @@ module Thredded
39
39
 
40
40
  # Update all of the messageboards' auto_follow_topics if the global preference has changed.
41
41
  if user_preference.previous_changes.include?('auto_follow_topics')
42
- UserMessageboardPreference.where(user: @user)
42
+ Thredded::UserMessageboardPreference.where(user: @user)
43
43
  .update_all(auto_follow_topics: user_preference.auto_follow_topics)
44
44
  user_messageboard_preference.auto_follow_topics_will_change! if messageboard
45
45
  end
@@ -50,7 +50,7 @@ module Thredded
50
50
  end
51
51
 
52
52
  def messageboard_groups
53
- @messageboard_groups ||= MessageboardGroupView.grouped(@messageboards)
53
+ @messageboard_groups ||= Thredded::MessageboardGroupView.grouped(@messageboards)
54
54
  end
55
55
 
56
56
  def notifications_for_private_topics
@@ -7,7 +7,7 @@ module Thredded
7
7
  # @param expires_in [ActiveSupport::Duration]
8
8
  # @return Array<[T, String]>
9
9
  def render_collection_to_strings_with_cache(collection:, partial:, expires_in:, **opts)
10
- CollectionToStringsWithCacheRenderer.new(lookup_context).render_collection_to_strings_with_cache(
10
+ Thredded::CollectionToStringsWithCacheRenderer.new(lookup_context).render_collection_to_strings_with_cache(
11
11
  self, collection: collection, partial: partial, expires_in: expires_in, **opts
12
12
  )
13
13
  end
@@ -5,10 +5,10 @@ module Thredded
5
5
  queue_as :default
6
6
 
7
7
  def perform(post_id)
8
- post = Post.find(post_id)
8
+ post = Thredded::Post.find(post_id)
9
9
 
10
- AutofollowUsers.new(post).run
11
- NotifyFollowingUsers.new(post).run
10
+ Thredded::AutofollowUsers.new(post).run
11
+ Thredded::NotifyFollowingUsers.new(post).run
12
12
  end
13
13
  end
14
14
  end
@@ -23,7 +23,7 @@ Additionally, Markdown is extended to support the following:
23
23
 
24
24
  def mock_topic(attr = {})
25
25
  fail 'Do not assign ID here or a has_many association might get updated' if attr.key?(:id)
26
- Topic.new(
26
+ Thredded::Topic.new(
27
27
  attr.reverse_merge(
28
28
  title: 'A test topic',
29
29
  slug: 'a-test-topic',
@@ -41,7 +41,7 @@ Additionally, Markdown is extended to support the following:
41
41
 
42
42
  def mock_post(attr = {})
43
43
  topic = attr[:postable] || mock_topic
44
- Post.new(
44
+ Thredded::Post.new(
45
45
  attr.reverse_merge(
46
46
  content: 'A test post',
47
47
  created_at: Time.zone.now,
@@ -56,7 +56,7 @@ Additionally, Markdown is extended to support the following:
56
56
 
57
57
  def mock_private_topic(attr = {})
58
58
  fail 'Do not assign ID here or a has_many association might get updated' if attr.key?(:id)
59
- PrivateTopic.new(
59
+ Thredded::PrivateTopic.new(
60
60
  attr.reverse_merge(
61
61
  title: 'A test private topic',
62
62
  slug: 'a-test-private-topic',
@@ -71,7 +71,7 @@ Additionally, Markdown is extended to support the following:
71
71
 
72
72
  def mock_private_post(attr = {})
73
73
  private_topic = attr[:postable] || mock_private_topic
74
- PrivatePost.new(
74
+ Thredded::PrivatePost.new(
75
75
  attr.reverse_merge(
76
76
  content: 'A test private post',
77
77
  created_at: Time.zone.now,
@@ -85,7 +85,7 @@ Additionally, Markdown is extended to support the following:
85
85
 
86
86
  def mock_messageboard(attr = {})
87
87
  fail 'Do not assign ID here or a has_many association might get updated' if attr.key?(:id)
88
- Messageboard.new(
88
+ Thredded::Messageboard.new(
89
89
  attr.reverse_merge(
90
90
  name: 'A test messageboard',
91
91
  slug: 'a-test-messageboard',
@@ -4,12 +4,8 @@ module Thredded
4
4
  # Previews for the PrivateTopicMailer
5
5
  class PrivateTopicMailerPreview < BaseMailerPreview
6
6
  def message_notification
7
- post = mock_private_post(content: mock_content(mention_users: ['glebm']))
8
7
  PrivateTopicMailer.message_notification(
9
- mock_private_topic(posts: [
10
- post
11
- ]),
12
- post,
8
+ mock_private_post(content: mock_content(mention_users: ['glebm'])),
13
9
  %w[glebm@test.com joel@test.com]
14
10
  )
15
11
  end
@@ -3,14 +3,19 @@
3
3
  module Thredded
4
4
  class PostMailer < Thredded::BaseMailer
5
5
  def post_notification(post_id, emails)
6
- @post = find_record Thredded::Post, post_id
7
- email_details = Thredded::TopicEmailView.new(@post.postable)
6
+ @post = find_record Thredded::Post, post_id
7
+ email_details = Thredded::TopicEmailView.new(@post.postable)
8
8
  headers['X-SMTPAPI'] = email_details.smtp_api_tag('post_notification')
9
9
 
10
- mail from: email_details.no_reply,
11
- to: email_details.no_reply,
12
- bcc: emails,
13
- subject: email_details.subject
10
+ mail from: email_details.no_reply,
11
+ to: email_details.no_reply,
12
+ bcc: emails,
13
+ subject: [
14
+ Thredded.email_outgoing_prefix,
15
+ t('thredded.emails.post_notification.subject',
16
+ user: @post.user.thredded_display_name,
17
+ topic_title: @post.postable.title)
18
+ ].compact.join
14
19
  end
15
20
  end
16
21
  end
@@ -2,16 +2,20 @@
2
2
 
3
3
  module Thredded
4
4
  class PrivateTopicMailer < Thredded::BaseMailer
5
- def message_notification(private_topic_id, post_id, emails)
6
- @topic = find_record Thredded::PrivateTopic, private_topic_id
7
- @post = find_record Thredded::PrivatePost, post_id
8
- email_details = Thredded::TopicEmailView.new(@topic)
5
+ def message_notification(post_id, emails)
6
+ @post = find_record Thredded::PrivatePost, post_id
7
+ email_details = Thredded::TopicEmailView.new(@post.postable)
9
8
  headers['X-SMTPAPI'] = email_details.smtp_api_tag('private_topic_mailer')
10
9
 
11
- mail from: email_details.no_reply,
12
- to: email_details.no_reply,
13
- bcc: emails,
14
- subject: email_details.subject
10
+ mail from: email_details.no_reply,
11
+ to: email_details.no_reply,
12
+ bcc: emails,
13
+ subject: [
14
+ Thredded.email_outgoing_prefix,
15
+ t('thredded.emails.message_notification.subject',
16
+ user: @post.user.thredded_display_name,
17
+ topic_title: @post.postable.title)
18
+ ].compact.join
15
19
  end
16
20
  end
17
21
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Thredded
4
- # Moderation state of a piece of content, such as a Topic or a Post.
4
+ # Moderation state of a piece of content, such as a Thredded::Topic or a Thredded::Post.
5
5
  # Requires an integer moderation_state column, a user_id column, and a user_detail association on the including class.
6
6
  # @api private
7
7
  module ContentModerationState
@@ -172,7 +172,7 @@ module Thredded
172
172
  # Update the associated messageboard metadata that Rails does not update them automatically.
173
173
  previous_changes['messageboard_id'].each do |messageboard_id|
174
174
  Thredded::Messageboard.reset_counters(messageboard_id, :topics, :posts)
175
- Messageboard.find(messageboard_id).update_last_topic!
175
+ Thredded::Messageboard.find(messageboard_id).update_last_topic!
176
176
  end
177
177
  end
178
178
  end
@@ -5,22 +5,11 @@ module Thredded
5
5
  module Moderate
6
6
  module IfModeratorColumnTrue
7
7
  extend ActiveSupport::Concern
8
- included { extend ClassMethods }
9
8
 
10
9
  # @return [ActiveRecord::Relation<Thredded::Messageboard>] messageboards that the user can moderate
11
10
  def thredded_can_moderate_messageboards
12
11
  send(Thredded.moderator_column) ? Thredded::Messageboard.all : Thredded::Messageboard.none
13
12
  end
14
-
15
- module ClassMethods
16
- # Users that can moderate the given messageboards.
17
- #
18
- # @param _messageboards [Array<Thredded::Messageboard>]
19
- # @return [ActiveRecord::Relation<Thredded.user_class>] users that can moderate the given messageboards
20
- def thredded_messageboards_moderators(_messageboards)
21
- where(Thredded.moderator_column => true)
22
- end
23
- end
24
13
  end
25
14
  end
26
15
  end
@@ -5,22 +5,11 @@ module Thredded
5
5
  module Moderate
6
6
  module None
7
7
  extend ActiveSupport::Concern
8
- included { extend ClassMethods }
9
8
 
10
9
  # @return [ActiveRecord::Relation<Thredded::Messageboard>] messageboards that the user can moderate
11
10
  def thredded_can_moderate_messageboards
12
11
  Thredded::Messageboard.none
13
12
  end
14
-
15
- module ClassMethods
16
- # Users that can moderate the given messageboards.
17
- #
18
- # @param _messageboards [Array<Thredded::Messageboard>]
19
- # @return [ActiveRecord::Relation<Thredded.user_class>] users that can moderate the given messageboards
20
- def thredded_messageboards_moderators(_messageboards)
21
- none
22
- end
23
- end
24
13
  end
25
14
  end
26
15
  end
@@ -5,22 +5,11 @@ module Thredded
5
5
  module Write
6
6
  module All
7
7
  extend ActiveSupport::Concern
8
- included { extend ClassMethods }
9
8
 
10
9
  # @return [ActiveRecord::Relation<Thredded::Messageboard>] messageboards that the user can post in
11
10
  def thredded_can_write_messageboards
12
11
  Thredded::Messageboard.all
13
12
  end
14
-
15
- module ClassMethods
16
- # Users that can post to the given messageboards.
17
- #
18
- # @param _messageboards [Array<Thredded::Messageboard>]
19
- # @return [ActiveRecord::Relation<Thredded.user_class>] users that can post to the given messageboards
20
- def thredded_messageboards_writers(_messageboards)
21
- all
22
- end
23
- end
24
13
  end
25
14
  end
26
15
  end
@@ -5,22 +5,11 @@ module Thredded
5
5
  module Write
6
6
  module None
7
7
  extend ActiveSupport::Concern
8
- included { extend ClassMethods }
9
8
 
10
9
  # @return [ActiveRecord::Relation<Thredded::Messageboard>] messageboards that the user can post in
11
10
  def thredded_can_write_messageboards
12
11
  Thredded::Messageboard.none
13
12
  end
14
-
15
- module ClassMethods
16
- # Users that can post to the given messageboards.
17
- #
18
- # @param _messageboards [Array<Thredded::Messageboard>]
19
- # @return [ActiveRecord::Relation<Thredded.user_class>] users that can post to the given messageboards
20
- def thredded_messageboards_writers(_messageboards)
21
- none
22
- end
23
- end
24
13
  end
25
14
  end
26
15
  end
@@ -21,8 +21,10 @@ module Thredded
21
21
  #
22
22
  # @return [Thredded::UserTopicFollow]
23
23
  def self.create_unless_exists(user_id, topic_id, reason = :manual)
24
- transaction(requires_new: true) do
25
- create_with(reason: reason).find_or_create_by(user_id: user_id, topic_id: topic_id)
24
+ uncached do
25
+ transaction(requires_new: true) do
26
+ create_with(reason: reason).find_or_create_by(user_id: user_id, topic_id: topic_id)
27
+ end
26
28
  end
27
29
  rescue ActiveRecord::RecordNotUnique
28
30
  # The record has been created from another connection, retry to find it.
@@ -2,6 +2,10 @@
2
2
 
3
3
  module Thredded
4
4
  class EmailNotifier
5
+ def initialize
6
+ fail 'Please set Thredded.email_from in config/initializers/thredded.rb' if Thredded.email_from.blank?
7
+ end
8
+
5
9
  def human_name
6
10
  I18n.t('thredded.email_notifier.by_email')
7
11
  end
@@ -11,11 +15,11 @@ module Thredded
11
15
  end
12
16
 
13
17
  def new_post(post, users)
14
- PostMailer.post_notification(post.id, users.map(&:email)).deliver_now
18
+ Thredded::PostMailer.post_notification(post.id, users.map(&:email)).deliver_now
15
19
  end
16
20
 
17
21
  def new_private_post(post, users)
18
- PrivateTopicMailer.message_notification(post.postable.id, post.id, users.map(&:email)).deliver_now
22
+ Thredded::PrivateTopicMailer.message_notification(post.id, users.map(&:email)).deliver_now
19
23
  end
20
24
  end
21
25
  end
@@ -37,7 +37,9 @@ module Thredded
37
37
  end
38
38
 
39
39
  def post?
40
- @user.thredded_admin? || @user.thredded_can_write_messageboards.include?(@messageboard)
40
+ @user.thredded_admin? ||
41
+ (!@messageboard.locked? || moderate?) &&
42
+ @user.thredded_can_write_messageboards.include?(@messageboard)
41
43
  end
42
44
 
43
45
  def moderate?
@@ -26,7 +26,11 @@ module Thredded
26
26
  end
27
27
 
28
28
  def create?
29
- @user.thredded_admin? || !@post.postable.locked? && messageboard_policy.post?
29
+ @user.thredded_admin? ||
30
+ !@post.postable.locked? &&
31
+ # Users are allowed to post in unlocked topics of a locked messageboard
32
+ # only if they would be allowed to post if the messageboard wasn't locked.
33
+ @user.thredded_can_write_messageboards.include?(@post.messageboard)
30
34
  end
31
35
 
32
36
  def read?
@@ -11,7 +11,7 @@ module Thredded
11
11
 
12
12
  def self.from_user(topic, user)
13
13
  read_state = if user && !user.thredded_anonymous?
14
- UserPrivateTopicReadState
14
+ Thredded::UserPrivateTopicReadState
15
15
  .find_by(user_id: user.id, postable_id: topic.id)
16
16
  end
17
17
  new(topic, read_state, Pundit.policy!(user, topic))
@@ -11,10 +11,6 @@ module Thredded
11
11
  %({"category": ["thredded_#{@topic.private? ? 'private_topic' : @topic.messageboard.name}","#{tag}"]})
12
12
  end
13
13
 
14
- def subject
15
- "#{Thredded.email_outgoing_prefix} #{@topic.title}"
16
- end
17
-
18
14
  def no_reply
19
15
  Thredded.email_from
20
16
  end
@@ -13,6 +13,12 @@
13
13
  <%= f.collection_select :messageboard_group_id, Thredded::MessageboardGroup.all, :id, :name,
14
14
  include_blank: t('thredded.messageboard.form.no_group') %>
15
15
  </li>
16
+ <li>
17
+ <%= f.label :locked do %>
18
+ <%= f.check_box :locked %> <%= t 'thredded.messageboard.form.locked_label' %>
19
+ <% end %>
20
+ </li>
21
+
16
22
  <li>
17
23
  <%= f.submit @messageboard.persisted? ? t('thredded.messageboard.update') : t('thredded.messageboard.create'),
18
24
  class: 'thredded--form--submit',
@@ -3,11 +3,7 @@
3
3
  <%= link_to messageboard_topics_path(messageboard), class: 'thredded--messageboard' do %>
4
4
  <header class="thredded--messageboard--header">
5
5
  <h2 class="thredded--messageboard--title"><%= messageboard.name %></h2>
6
- <h3 class="thredded--messageboard--meta">
7
- <%= t 'thredded.messageboard.topics_and_posts_counts',
8
- topics_count: number_with_delimiter(messageboard.topics_count),
9
- posts_count: number_with_delimiter(messageboard.posts_count) %>
10
- </h3>
6
+ <%= render 'thredded/messageboards/messageboard_meta', messageboard: messageboard %>
11
7
  </header>
12
8
 
13
9
  <p class="thredded--messageboard--description"><%= messageboard.description %></p>
@@ -0,0 +1,13 @@
1
+ <div class="thredded--messageboard--meta">
2
+ <% if messageboard.locked? %>
3
+ <span class="thredded--messageboard--meta--locked"
4
+ title="<%= t('thredded.messageboard.form.locked_notice') %>">
5
+ <%= inline_svg('thredded/lock.svg', class: 'thredded--messageboard--meta--icon') %>
6
+ </span>
7
+ <% end %>
8
+ <h3 class="thredded--messageboard--meta--counts">
9
+ <%= t 'thredded.messageboard.topics_and_posts_counts',
10
+ topics_count: number_with_delimiter(messageboard.topics_count),
11
+ posts_count: number_with_delimiter(messageboard.posts_count) %>
12
+ </h3>
13
+ </div>
@@ -14,8 +14,8 @@
14
14
  <caption><%= page_entries_info @users %></caption>
15
15
  <thead>
16
16
  <tr>
17
- <th>User</th>
18
- <th>Moderation state</th>
17
+ <th><%= t 'thredded.moderation.user.name' %></th>
18
+ <th><%= t 'thredded.moderation.moderation_state.name' %></th>
19
19
  </tr>
20
20
  </thead>
21
21
  <tbody>
@@ -1,7 +1,10 @@
1
1
  <div class="thredded--email">
2
2
  <figure class="thredded--email-post">
3
3
  <figcaption class="thredded--email-post--author">
4
- <%= @post.user.thredded_display_name %> <%= link_to 'said', post_permalink_url(@post) %>:
4
+ <%= t 'thredded.emails.post_notification.html.post_lead_html',
5
+ user: @post.user.thredded_display_name,
6
+ post_url: post_permalink_url(@post.id),
7
+ topic_title: @post.postable.title %>
5
8
  </figcaption>
6
9
  <% cache [@post, 'content-onebox-placeholders'] do %>
7
10
  <%= render partial: 'thredded/posts/content',
@@ -11,13 +14,13 @@
11
14
  <hr/>
12
15
 
13
16
  <p>
14
- This email was sent to you because you are following this topic
15
- "<%= link_to @post.postable.title, post_permalink_url(@post.id) %>".
16
- <%= link_to 'View the conversation here', topic_url(@post.postable) %>.
17
+ <%= t 'thredded.emails.post_notification.html.email_sent_reason_html',
18
+ post_url: post_permalink_url(@post.id),
19
+ topic_title: @post.postable.title %>
17
20
  </p>
18
21
 
19
22
  <p>
20
- To unsubscribe from these emails, update your
21
- <%= link_to 'preferences', edit_messageboard_preferences_url(@post.messageboard) %>.
23
+ <%= t 'thredded.emails.post_notification.html.unsubscribe_instructions_html',
24
+ preferences_url: edit_messageboard_preferences_url(@post.messageboard) %>
22
25
  </p>
23
26
  </div>