thredded 0.8.4 → 0.9.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.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +48 -9
  3. data/app/assets/images/thredded/breadcrumb-chevron.svg +1 -1
  4. data/app/assets/images/thredded/follow.svg +1 -1
  5. data/app/assets/images/thredded/moderation.svg +1 -4
  6. data/app/assets/images/thredded/private-messages.svg +1 -4
  7. data/app/assets/images/thredded/settings.svg +1 -4
  8. data/app/assets/images/thredded/unfollow.svg +1 -1
  9. data/app/assets/javascripts/thredded/components/time_stamps.es6 +1 -1
  10. data/app/assets/javascripts/thredded/components/user_preferences_form.es6 +26 -49
  11. data/app/assets/javascripts/thredded/dependencies.js +2 -1
  12. data/app/assets/stylesheets/thredded/base/_grid.scss +4 -4
  13. data/app/assets/stylesheets/thredded/base/_typography.scss +18 -0
  14. data/app/assets/stylesheets/thredded/components/_base.scss +4 -0
  15. data/app/assets/stylesheets/thredded/components/_currently-online.scss +4 -0
  16. data/app/assets/stylesheets/thredded/components/_form-list.scss +5 -0
  17. data/app/assets/stylesheets/thredded/components/_messageboard.scss +3 -0
  18. data/app/assets/stylesheets/thredded/components/_post-form.scss +7 -4
  19. data/app/assets/stylesheets/thredded/components/_post.scss +3 -0
  20. data/app/assets/stylesheets/thredded/components/_topic-delete.scss +3 -0
  21. data/app/assets/stylesheets/thredded/components/_topic-header.scss +20 -0
  22. data/app/assets/stylesheets/thredded/components/_topics.scss +13 -1
  23. data/app/assets/stylesheets/thredded/layout/_main-navigation.scss +1 -1
  24. data/app/assets/stylesheets/thredded/layout/_navigation.scss +3 -1
  25. data/app/assets/stylesheets/thredded/layout/_search-navigation.scss +4 -0
  26. data/app/assets/stylesheets/thredded/layout/_user-navigation.scss +3 -0
  27. data/app/commands/thredded/at_notification_extractor.rb +1 -2
  28. data/app/commands/thredded/autofollow_mentioned_users.rb +0 -1
  29. data/app/commands/thredded/notify_following_users.rb +20 -11
  30. data/app/commands/thredded/notify_private_topic_users.rb +12 -28
  31. data/app/controllers/thredded/application_controller.rb +8 -4
  32. data/app/controllers/thredded/messageboards_controller.rb +2 -2
  33. data/app/controllers/thredded/moderation_controller.rb +12 -13
  34. data/app/controllers/thredded/posts_controller.rb +1 -1
  35. data/app/controllers/thredded/preferences_controller.rb +11 -7
  36. data/app/controllers/thredded/private_topics_controller.rb +13 -9
  37. data/app/controllers/thredded/topics_controller.rb +20 -12
  38. data/app/forms/thredded/user_preferences_form.rb +23 -4
  39. data/app/helpers/thredded/application_helper.rb +11 -1
  40. data/app/mailers/thredded/post_mailer.rb +2 -3
  41. data/app/mailers/thredded/private_topic_mailer.rb +2 -3
  42. data/app/models/concerns/thredded/content_moderation_state.rb +1 -1
  43. data/app/models/concerns/thredded/notifier_preference.rb +18 -0
  44. data/app/models/concerns/thredded/post_common.rb +5 -1
  45. data/{lib → app/models/concerns}/thredded/search_parser.rb +0 -0
  46. data/app/models/concerns/thredded/topic_common.rb +3 -3
  47. data/{lib → app/models/concerns}/thredded/topics_search.rb +2 -3
  48. data/app/models/thredded/messageboard.rb +11 -0
  49. data/app/models/thredded/messageboard_notifications_for_followed_topics.rb +29 -0
  50. data/app/models/thredded/notifications_for_followed_topics.rb +22 -0
  51. data/app/models/thredded/notifications_for_private_topics.rb +21 -0
  52. data/app/models/thredded/post.rb +5 -3
  53. data/app/models/thredded/post_moderation_record.rb +1 -1
  54. data/app/models/thredded/private_post.rb +1 -1
  55. data/app/models/thredded/private_topic.rb +8 -4
  56. data/app/models/thredded/stats.rb +1 -1
  57. data/app/models/thredded/topic.rb +10 -7
  58. data/app/models/thredded/user_detail.rb +1 -1
  59. data/app/models/thredded/user_extender.rb +3 -1
  60. data/app/models/thredded/user_preference.rb +16 -5
  61. data/app/models/thredded/user_private_topic_read_state.rb +1 -1
  62. data/app/models/thredded/user_topic_read_state.rb +1 -1
  63. data/app/notifiers/thredded/base_notifier.rb +28 -0
  64. data/app/notifiers/thredded/email_notifier.rb +34 -0
  65. data/app/policies/thredded/post_policy.rb +3 -4
  66. data/app/policies/thredded/private_post_policy.rb +2 -3
  67. data/app/policies/thredded/topic_policy.rb +1 -2
  68. data/app/view_hooks/thredded/all_view_hooks.rb +0 -3
  69. data/app/view_models/thredded/base_topic_view.rb +0 -1
  70. data/app/view_models/thredded/post_view.rb +0 -1
  71. data/app/view_models/thredded/posts_page_view.rb +1 -4
  72. data/app/view_models/thredded/private_topic_view.rb +3 -1
  73. data/app/view_models/thredded/private_topics_page_view.rb +8 -3
  74. data/app/view_models/thredded/topic_posts_page_view.rb +1 -2
  75. data/app/view_models/thredded/topic_view.rb +3 -3
  76. data/app/view_models/thredded/topics_page_view.rb +0 -1
  77. data/app/views/thredded/messageboard_groups/new.html.erb +5 -1
  78. data/app/views/thredded/messageboards/_form.html.erb +7 -2
  79. data/app/views/thredded/posts/_form.html.erb +2 -1
  80. data/app/views/thredded/posts/edit.html.erb +3 -2
  81. data/app/views/thredded/posts_common/_form.html.erb +6 -2
  82. data/app/views/thredded/preferences/_form.html.erb +41 -29
  83. data/app/views/thredded/private_posts/_form.html.erb +1 -0
  84. data/app/views/thredded/private_topics/_form.html.erb +3 -2
  85. data/app/views/thredded/private_topics/_header.html.erb +4 -0
  86. data/app/views/thredded/private_topics/_no_private_topics.html.erb +1 -1
  87. data/app/views/thredded/private_topics/_private_topic.html.erb +5 -2
  88. data/app/views/thredded/private_topics/edit.html.erb +2 -1
  89. data/app/views/thredded/private_topics/header/_participant.html.erb +1 -0
  90. data/app/views/thredded/private_topics/index.html.erb +6 -5
  91. data/app/views/thredded/private_topics/new.html.erb +0 -1
  92. data/app/views/thredded/private_topics/private_topic/_participant.html.erb +1 -0
  93. data/app/views/thredded/private_topics/show.html.erb +1 -3
  94. data/app/views/thredded/topics/_form.html.erb +1 -1
  95. data/app/views/thredded/topics/show.html.erb +4 -5
  96. data/config/locales/en.yml +22 -9
  97. data/config/locales/pt-BR.yml +22 -10
  98. data/config/routes.rb +1 -1
  99. data/db/migrate/20160329231848_create_thredded.rb +23 -3
  100. data/db/upgrade_migrations/20160410111522_upgrade_v0_2_to_v0_3.rb +1 -1
  101. data/db/upgrade_migrations/20161113161801_upgrade_v0_8_to_v0_9.rb +56 -0
  102. data/lib/generators/thredded/install/templates/initializer.rb +28 -0
  103. data/lib/thredded.rb +32 -8
  104. data/lib/thredded/content_formatter.rb +3 -2
  105. data/lib/thredded/database_seeder.rb +11 -8
  106. data/lib/thredded/db_tools.rb +82 -0
  107. data/lib/thredded/html_pipeline/wrap_iframes_filter.rb +12 -0
  108. data/lib/thredded/version.rb +1 -1
  109. metadata +18 -8
  110. data/app/models/thredded/null_preference.rb +0 -16
@@ -1,5 +1,5 @@
1
1
  @mixin thredded-breadcrumbs-chevron() {
2
- background: image-url("thredded/breadcrumb-chevron.svg") no-repeat center center;
2
+ background: asset-data-url("thredded/breadcrumb-chevron.svg") no-repeat center center;
3
3
  content: "";
4
4
  display: inline-block;
5
5
  height: 10px;
@@ -27,7 +27,9 @@
27
27
  .thredded--messageboards-index &,
28
28
  .thredded--topics-index &,
29
29
  .thredded--topic-search-results & {
30
- display: block;
30
+ @media screen {
31
+ display: block;
32
+ }
31
33
  }
32
34
  }
33
35
  .thredded--user-navigation {
@@ -85,4 +85,8 @@
85
85
  [type="submit"] {
86
86
  display: none;
87
87
  }
88
+
89
+ @media print {
90
+ display: none;
91
+ }
88
92
  }
@@ -1,5 +1,8 @@
1
1
  .thredded--user-navigation {
2
2
  @extend %thredded--nav-tabs;
3
+ @media print {
4
+ display: none;
5
+ }
3
6
  }
4
7
 
5
8
  .thredded--user-navigation--item {
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'thredded/html_pipeline/at_mention_filter'
3
2
  module Thredded
4
3
  class AtNotificationExtractor
5
4
  def initialize(post)
@@ -16,7 +15,7 @@ module Thredded
16
15
  Thredded::HtmlPipeline::AtMentionFilter.new(
17
16
  html,
18
17
  view_context: view_context,
19
- users_provider: -> (user_names) { @post.readers_from_user_names(user_names).to_a }
18
+ users_provider: ->(user_names) { @post.readers_from_user_names(user_names).to_a }
20
19
  ).mentioned_users
21
20
  end
22
21
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require_dependency 'thredded/at_notification_extractor'
3
2
  module Thredded
4
3
  class AutofollowMentionedUsers
5
4
  def initialize(post)
@@ -6,23 +6,32 @@ module Thredded
6
6
  end
7
7
 
8
8
  def run
9
- return if targeted_users.empty?
10
- PostMailer.post_notification(@post.id, targeted_users.map(&:email)).deliver_now
11
- MembersMarkedNotified.new(@post, targeted_users).run
9
+ Thredded.notifiers.each do |notifier|
10
+ notifiable_users = targeted_users(notifier)
11
+ notifier.new_post(@post, notifiable_users) if notifiable_users.present?
12
+ end
12
13
  end
13
14
 
14
- def targeted_users
15
- @targeted_users ||= @post.postable.followers.reject { |u| u == @post.user }
16
- exclude_those_opting_out_of_followed_activity_notifications @targeted_users
15
+ def targeted_users(notifier)
16
+ possible_targeted_users.select do |user|
17
+ NotificationsForFollowedTopics
18
+ .detect_or_default(user.thredded_notifications_for_followed_topics, notifier).enabled? &&
19
+ MessageboardNotificationsForFollowedTopics
20
+ .detect_or_default(messageboard_notifier_prefs_by_user_id[user.id], notifier).enabled?
21
+ end
22
+ end
23
+
24
+ def possible_targeted_users
25
+ @possible_targeted_users ||=
26
+ @post.postable.followers.includes(:thredded_notifications_for_followed_topics).reject { |u| u == @post.user }
17
27
  end
18
28
 
19
29
  private
20
30
 
21
- def exclude_those_opting_out_of_followed_activity_notifications(members)
22
- members.select do |member|
23
- member.thredded_user_preference.followed_topic_emails &&
24
- member.thredded_user_messageboard_preferences.in(@post.messageboard).followed_topic_emails
25
- end
31
+ def messageboard_notifier_prefs_by_user_id
32
+ @messageboard_notifier_prefs_by_user_id ||= MessageboardNotificationsForFollowedTopics
33
+ .where(user_id: possible_targeted_users.map(&:id))
34
+ .for_messageboard(@post.messageboard).group_by(&:user_id)
26
35
  end
27
36
  end
28
37
  end
@@ -7,42 +7,26 @@ module Thredded
7
7
  end
8
8
 
9
9
  def run
10
- members = private_topic_recipients
11
-
12
- return unless members.present?
13
- user_emails = members.map(&:email)
14
- PrivateTopicMailer
15
- .message_notification(private_topic.id, user_emails)
16
- .deliver_later
17
- mark_notified(members)
10
+ Thredded.notifiers.each do |notifier|
11
+ notifiable_users = targeted_users(notifier)
12
+ notifier.new_private_post(@post, notifiable_users) if notifiable_users.present?
13
+ end
18
14
  end
19
15
 
20
- def private_topic_recipients
21
- members = private_topic.users - [post.user]
22
- members = exclude_those_opting_out_of_message_notifications(members)
23
- members = exclude_previously_notified(members)
24
- members
16
+ def targeted_users(notifier)
17
+ users = private_topic.users.includes(:thredded_notifications_for_private_topics) - [post.user]
18
+ users = only_those_with_this_notifier_enabled(users, notifier)
19
+ users
25
20
  end
26
21
 
27
22
  private
28
23
 
29
24
  attr_reader :post, :private_topic
30
25
 
31
- def mark_notified(members)
32
- members.each do |member|
33
- post.post_notifications.create(email: member.email)
34
- end
35
- end
36
-
37
- def exclude_those_opting_out_of_message_notifications(members)
38
- members.select { |member| member.thredded_user_preference.notify_on_message? }
39
- end
40
-
41
- def exclude_previously_notified(members)
42
- emails_notified = post.post_notifications.map(&:email)
43
-
44
- members.reject do |member|
45
- emails_notified.include? member.email
26
+ def only_those_with_this_notifier_enabled(users, notifier)
27
+ users.select do |user|
28
+ NotificationsForPrivateTopics
29
+ .detect_or_default(user.thredded_notifications_for_private_topics, notifier).enabled?
46
30
  end
47
31
  end
48
32
  end
@@ -76,7 +76,7 @@ module Thredded
76
76
  end
77
77
 
78
78
  def update_user_activity
79
- return if messageboard.nil? || !signed_in?
79
+ return if !messageboard_or_nil || !signed_in?
80
80
 
81
81
  Thredded::ActivityUpdaterJob.perform_later(
82
82
  thredded_current_user.id,
@@ -88,10 +88,14 @@ module Thredded
88
88
  thredded_current_user
89
89
  end
90
90
 
91
+ # Returns the `@messageboard` instance variable.
92
+ # If `@messageboard` is not set, it first sets it to the messageboard with the slug or ID given by
93
+ # `params[:messageboard_id]`.
94
+ #
95
+ # @return [Thredded::Messageboard]
96
+ # @raise [Thredded::Errors::MessageboardNotFound] if the messageboard with the given slug does not exist.
91
97
  def messageboard
92
- @messageboard ||= params[:messageboard_id].presence && Messageboard.friendly.find(params[:messageboard_id])
93
- rescue ActiveRecord::RecordNotFound
94
- raise Thredded::Errors::MessageboardNotFound
98
+ @messageboard ||= Messageboard.friendly_find!(params[:messageboard_id])
95
99
  end
96
100
 
97
101
  def messageboard_or_nil
@@ -27,12 +27,12 @@ module Thredded
27
27
  end
28
28
 
29
29
  def edit
30
- @messageboard = Messageboard.friendly.find(params[:id])
30
+ @messageboard = Messageboard.friendly_find!(params[:id])
31
31
  authorize @messageboard, :update?
32
32
  end
33
33
 
34
34
  def update
35
- @messageboard = Messageboard.friendly.find(params[:id])
35
+ @messageboard = Messageboard.friendly_find!(params[:id])
36
36
  authorize @messageboard, :update?
37
37
  if @messageboard.update(messageboard_params)
38
38
  redirect_to messageboard_topics_path(@messageboard), notice: I18n.t('thredded.messageboard.updated_notice')
@@ -1,13 +1,11 @@
1
1
  # frozen_string_literal: true
2
- require_dependency 'thredded/moderate_post'
3
- require_dependency 'thredded/posts_page_view'
4
2
  module Thredded
5
3
  class ModerationController < Thredded::ApplicationController
6
4
  before_action :thredded_require_login!
7
5
  before_action :load_moderatable_messageboards
8
6
 
9
7
  def pending
10
- @posts = PostsPageView.new(
8
+ @posts = Thredded::PostsPageView.new(
11
9
  thredded_current_user,
12
10
  moderatable_posts
13
11
  .pending_moderation
@@ -15,9 +13,7 @@ module Thredded
15
13
  .preload(:user, :postable)
16
14
  .page(current_page)
17
15
  )
18
- if flash[:last_moderated_record_id]
19
- @last_moderated_record = accessible_post_moderation_records.find(flash[:last_moderated_record_id].to_i)
20
- end
16
+ maybe_set_last_moderated_record_flash
21
17
  end
22
18
 
23
19
  def history
@@ -27,21 +23,19 @@ module Thredded
27
23
  end
28
24
 
29
25
  def activity
30
- @posts = PostsPageView.new(
26
+ @posts = Thredded::PostsPageView.new(
31
27
  thredded_current_user,
32
28
  moderatable_posts
33
29
  .order_newest_first
34
30
  .preload(:user, :postable)
35
31
  .page(current_page)
36
32
  )
37
- if flash[:last_moderated_record_id]
38
- @last_moderated_record = accessible_post_moderation_records.find(flash[:last_moderated_record_id].to_i)
39
- end
33
+ maybe_set_last_moderated_record_flash
40
34
  end
41
35
 
42
36
  def moderate_post
43
37
  return head(:bad_request) unless Thredded::Post.moderation_states.include?(params[:moderation_state])
44
- flash[:last_moderated_record_id] = ModeratePost.run!(
38
+ flash[:last_moderated_record_id] = Thredded::ModeratePost.run!(
45
39
  post: moderatable_posts.find(params[:id]),
46
40
  moderation_state: params[:moderation_state],
47
41
  moderator: thredded_current_user,
@@ -68,7 +62,7 @@ module Thredded
68
62
  .order_newest_first
69
63
  .includes(:postable)
70
64
  .page(current_page)
71
- @posts = PostsPageView.new(thredded_current_user, posts_scope)
65
+ @posts = Thredded::PostsPageView.new(thredded_current_user, posts_scope)
72
66
  end
73
67
 
74
68
  def moderate_user
@@ -80,6 +74,11 @@ module Thredded
80
74
 
81
75
  private
82
76
 
77
+ def maybe_set_last_moderated_record_flash
78
+ return unless flash[:last_moderated_record_id]
79
+ @last_moderated_record = accessible_post_moderation_records.find(flash[:last_moderated_record_id].to_i)
80
+ end
81
+
83
82
  def moderatable_posts
84
83
  Thredded::Post.where(messageboard_id: @moderatable_messageboards)
85
84
  end
@@ -91,7 +90,7 @@ module Thredded
91
90
 
92
91
  def load_moderatable_messageboards
93
92
  @moderatable_messageboards = thredded_current_user.thredded_can_moderate_messageboards.to_a
94
- if @moderatable_messageboards.empty?
93
+ if @moderatable_messageboards.empty? # rubocop:disable Style/GuardClause
95
94
  fail Pundit::NotAuthorizedError, 'You are not authorized to perform this action.'
96
95
  end
97
96
  end
@@ -4,7 +4,7 @@ module Thredded
4
4
  include ActionView::RecordIdentifier
5
5
 
6
6
  helper_method :topic
7
- before_action :update_user_activity
7
+ after_action :update_user_activity
8
8
 
9
9
  after_action :verify_authorized
10
10
 
@@ -22,13 +22,17 @@ module Thredded
22
22
  @preferences = UserPreferencesForm.new(
23
23
  user: thredded_current_user,
24
24
  messageboard: messageboard_or_nil,
25
- params: params.fetch(:user_preferences_form, {}).permit(
26
- :followed_topic_emails,
27
- :follow_topics_on_mention,
28
- :notify_on_message,
29
- :messageboard_followed_topic_emails,
30
- :messageboard_follow_topics_on_mention
31
- )
25
+ params: preferences_params
26
+ )
27
+ end
28
+
29
+ def preferences_params
30
+ params.fetch(:user_preferences_form, {}).permit(
31
+ :follow_topics_on_mention,
32
+ :messageboard_follow_topics_on_mention,
33
+ messageboard_notifications_for_followed_topics_attributes: %i(notifier_key id messageboard_id enabled),
34
+ notifications_for_followed_topics_attributes: %i(notifier_key id enabled),
35
+ notifications_for_private_topics_attributes: %i(notifier_key id enabled)
32
36
  )
33
37
  end
34
38
  end
@@ -1,6 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require_dependency 'thredded/posts_page_view'
3
- require_dependency 'thredded/topics_page_view'
4
2
  module Thredded
5
3
  class PrivateTopicsController < Thredded::ApplicationController
6
4
  before_action :thredded_require_login!
@@ -8,15 +6,14 @@ module Thredded
8
6
  def index
9
7
  @private_topics = Thredded::PrivateTopicsPageView.new(
10
8
  thredded_current_user,
11
- PrivateTopic
9
+ Thredded::PrivateTopic
12
10
  .distinct
13
11
  .for_user(thredded_current_user)
14
12
  .order_recently_posted_first
15
- .includes(:last_user, :user)
16
13
  .page(params[:page])
17
14
  )
18
15
 
19
- PrivateTopicForm.new(user: thredded_current_user).tap do |form|
16
+ Thredded::PrivateTopicForm.new(user: thredded_current_user).tap do |form|
20
17
  @new_private_topic = form if policy(form.private_topic).create?
21
18
  end
22
19
  end
@@ -32,19 +29,21 @@ module Thredded
32
29
  @posts = Thredded::TopicPostsPageView.new(thredded_current_user, private_topic, page_scope)
33
30
 
34
31
  if signed_in?
35
- UserPrivateTopicReadState.touch!(thredded_current_user.id, private_topic.id, page_scope.last, current_page)
32
+ Thredded::UserPrivateTopicReadState.touch!(
33
+ thredded_current_user.id, private_topic.id, page_scope.last, current_page
34
+ )
36
35
  end
37
36
 
38
37
  @post = private_topic.posts.build
39
38
  end
40
39
 
41
40
  def new
42
- @private_topic = PrivateTopicForm.new(user: thredded_current_user)
41
+ @private_topic = Thredded::PrivateTopicForm.new(user: thredded_current_user)
43
42
  authorize_creating @private_topic.private_topic
44
43
  end
45
44
 
46
45
  def create
47
- @private_topic = PrivateTopicForm.new(new_private_topic_params)
46
+ @private_topic = Thredded::PrivateTopicForm.new(new_private_topic_params)
48
47
  if @private_topic.save
49
48
  redirect_to @private_topic.private_topic
50
49
  else
@@ -72,8 +71,13 @@ module Thredded
72
71
  (params[:page] || 1).to_i
73
72
  end
74
73
 
74
+ # Returns the `@private_topic` instance variable.
75
+ # If `@private_topic` is not set, it first sets it to the topic with the slug or ID given by `params[:id]`.
76
+ #
77
+ # @return [Thredded::PrivateTopic]
78
+ # @raise [Thredded::Errors::PrivateTopicNotFound] if the topic with the given slug does not exist.
75
79
  def private_topic
76
- @private_topic ||= Thredded::PrivateTopic.find_by_slug(params[:id])
80
+ @private_topic ||= Thredded::PrivateTopic.friendly_find!(params[:id])
77
81
  end
78
82
 
79
83
  def private_topic_params
@@ -1,6 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require_dependency 'thredded/posts_page_view'
3
- require_dependency 'thredded/topics_page_view'
4
2
  # rubocop:disable Metrics/ClassLength
5
3
  module Thredded
6
4
  class TopicsController < Thredded::ApplicationController
@@ -20,7 +18,7 @@ module Thredded
20
18
  .order_sticky_first.order_recently_posted_first
21
19
  .page(current_page)
22
20
  )
23
- TopicForm.new(messageboard: messageboard, user: thredded_current_user).tap do |form|
21
+ Thredded::TopicForm.new(messageboard: messageboard, user: thredded_current_user).tap do |form|
24
22
  @new_topic = form if policy(form.topic).create?
25
23
  end
26
24
  end
@@ -33,19 +31,24 @@ module Thredded
33
31
  .page(current_page)
34
32
  @posts = Thredded::TopicPostsPageView.new(thredded_current_user, topic, page_scope)
35
33
 
36
- UserTopicReadState.touch!(thredded_current_user.id, topic.id, page_scope.last, current_page) if signed_in?
34
+ if signed_in?
35
+ Thredded::UserTopicReadState.touch!(
36
+ thredded_current_user.id, topic.id, page_scope.last, current_page
37
+ )
38
+ end
37
39
 
38
40
  @new_post = messageboard.posts.build(postable: topic)
39
41
  end
40
42
 
41
43
  def search
42
- authorize_reading messageboard if messageboard_or_nil
44
+ in_messageboard = params.key?(:messageboard_id)
45
+ authorize_reading messageboard if in_messageboard
43
46
  @query = params[:q].to_s
44
47
  topics_scope = policy_scope(
45
- if messageboard_or_nil
48
+ if in_messageboard
46
49
  messageboard.topics
47
50
  else
48
- Topic.where(messageboard_id: policy_scope(Messageboard.all).pluck(:id))
51
+ Thredded::Topic.where(messageboard_id: policy_scope(Thredded::Messageboard.all).pluck(:id))
49
52
  end
50
53
  )
51
54
  @topics = Thredded::TopicsPageView.new(
@@ -59,7 +62,7 @@ module Thredded
59
62
  end
60
63
 
61
64
  def new
62
- @new_topic = TopicForm.new(new_topic_params)
65
+ @new_topic = Thredded::TopicForm.new(new_topic_params)
63
66
  authorize_creating @new_topic.topic
64
67
  end
65
68
 
@@ -77,7 +80,7 @@ module Thredded
77
80
  end
78
81
 
79
82
  def create
80
- @new_topic = TopicForm.new(new_topic_params)
83
+ @new_topic = Thredded::TopicForm.new(new_topic_params)
81
84
  authorize_creating @new_topic.topic
82
85
  if @new_topic.save
83
86
  redirect_to messageboard_topics_path(messageboard)
@@ -109,13 +112,13 @@ module Thredded
109
112
 
110
113
  def follow
111
114
  authorize topic, :read?
112
- UserTopicFollow.create_unless_exists(thredded_current_user.id, topic.id)
115
+ Thredded::UserTopicFollow.create_unless_exists(thredded_current_user.id, topic.id)
113
116
  follow_change_response(following: true)
114
117
  end
115
118
 
116
119
  def unfollow
117
120
  authorize topic, :read?
118
- UserTopicFollow.find_by(topic_id: topic.id, user_id: thredded_current_user.id).try(:destroy)
121
+ Thredded::UserTopicFollow.find_by(topic_id: topic.id, user_id: thredded_current_user.id).try(:destroy)
119
122
  follow_change_response(following: false)
120
123
  end
121
124
 
@@ -129,8 +132,13 @@ module Thredded
129
132
  end
130
133
  end
131
134
 
135
+ # Returns the `@topic` instance variable.
136
+ # If `@topic` is not set, it first sets it to the topic with the slug or ID given by `params[:id]`.
137
+ #
138
+ # @return [Thredded::Topic]
139
+ # @raise [Thredded::Errors::TopicNotFound] if the topic with the given slug does not exist.
132
140
  def topic
133
- @topic ||= messageboard.topics.find_by_slug!(params[:id])
141
+ @topic ||= messageboard.topics.friendly_find!(params[:id])
134
142
  end
135
143
 
136
144
  def topic_params