thredded 0.15.5 → 0.16.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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -7
  3. data/app/assets/stylesheets/thredded/_thredded.scss +1 -0
  4. data/app/assets/stylesheets/thredded/components/_messageboard.scss +16 -3
  5. data/app/assets/stylesheets/thredded/utilities/_flex.scss +3 -0
  6. data/app/commands/thredded/mark_all_read.rb +3 -7
  7. data/app/controllers/thredded/messageboards_controller.rb +4 -1
  8. data/app/controllers/thredded/moderation_controller.rb +7 -2
  9. data/app/controllers/thredded/private_topics_controller.rb +1 -5
  10. data/app/controllers/thredded/theme_previews_controller.rb +5 -1
  11. data/app/controllers/thredded/topics_controller.rb +1 -1
  12. data/app/forms/thredded/post_form.rb +1 -1
  13. data/app/forms/thredded/private_post_form.rb +1 -1
  14. data/app/forms/thredded/private_topic_form.rb +2 -0
  15. data/app/forms/thredded/topic_form.rb +2 -1
  16. data/app/forms/thredded/user_preferences_form.rb +5 -1
  17. data/app/models/concerns/thredded/post_common.rb +10 -6
  18. data/app/models/concerns/thredded/topic_common.rb +4 -8
  19. data/app/models/concerns/thredded/user_topic_read_state_common.rb +56 -62
  20. data/app/models/thredded/messageboard.rb +27 -1
  21. data/app/models/thredded/post.rb +6 -0
  22. data/app/models/thredded/private_topic.rb +12 -2
  23. data/app/models/thredded/topic.rb +8 -3
  24. data/app/models/thredded/user_extender.rb +0 -7
  25. data/app/models/thredded/user_private_topic_read_state.rb +35 -0
  26. data/app/models/thredded/user_topic_read_state.rb +41 -0
  27. data/app/view_models/thredded/messageboard_group_view.rb +24 -7
  28. data/app/view_models/thredded/messageboard_view.rb +50 -0
  29. data/app/views/thredded/messageboards/_messageboard.html.erb +8 -18
  30. data/app/views/thredded/messageboards/index.html.erb +6 -1
  31. data/app/views/thredded/messageboards/messageboard/_description.html.erb +1 -0
  32. data/app/views/thredded/messageboards/messageboard/_header.html.erb +6 -0
  33. data/app/views/thredded/messageboards/messageboard/_last_updated.html.erb +7 -0
  34. data/app/views/thredded/messageboards/messageboard/_meta.html.erb +19 -0
  35. data/app/views/thredded/messageboards/messageboard/_unread_followed_topics_badge.html.erb +6 -0
  36. data/app/views/thredded/preferences/_messageboards_nav_item.html.erb +1 -1
  37. data/app/views/thredded/private_posts/_private_post.html.erb +1 -1
  38. data/app/views/thredded/theme_previews/show.html.erb +10 -4
  39. data/app/views/thredded/topics/_topic.html.erb +1 -1
  40. data/app/views/thredded/topics/unread.html.erb +1 -1
  41. data/config/locales/de.yml +1 -0
  42. data/config/locales/en.yml +2 -1
  43. data/config/locales/es.yml +1 -0
  44. data/config/locales/fr.yml +1 -0
  45. data/config/locales/it.yml +1 -0
  46. data/config/locales/pl.yml +1 -0
  47. data/config/locales/pt-BR.yml +1 -0
  48. data/config/locales/ru.yml +1 -0
  49. data/config/locales/zh-CN.yml +1 -0
  50. data/db/migrate/20160329231848_create_thredded.rb +5 -0
  51. data/db/upgrade_migrations/20180930063614_upgrade_thredded_v0_15_to_v0_16.rb +40 -0
  52. data/lib/generators/thredded/install/templates/initializer.rb +4 -4
  53. data/lib/thredded/arel_compat.rb +18 -24
  54. data/lib/thredded/content_formatter.rb +1 -1
  55. data/lib/thredded/database_seeder.rb +7 -6
  56. data/lib/thredded/version.rb +1 -1
  57. metadata +24 -18
  58. data/app/views/thredded/messageboards/_messageboard_meta.html.erb +0 -13
  59. data/lib/tasks/thredded_tasks.rake +0 -14
@@ -37,6 +37,8 @@ module Thredded
37
37
  after_commit :update_parent_last_user_and_time_from_last_post, on: %i[create destroy]
38
38
  after_commit :update_parent_last_user_and_time_from_last_post_if_moderation_state_changed, on: :update
39
39
 
40
+ after_commit :update_unread_posts_count_if_moderation_state_changed, on: :update
41
+
40
42
  after_commit :auto_follow_and_notify, on: %i[create update]
41
43
 
42
44
  # Finds the post by its ID, or raises {Thredded::Errors::PostNotFound}.
@@ -83,5 +85,9 @@ module Thredded
83
85
  def update_parent_last_user_and_time_from_last_post_if_moderation_state_changed
84
86
  update_parent_last_user_and_time_from_last_post if previous_changes.include?('moderation_state')
85
87
  end
88
+
89
+ def update_unread_posts_count_if_moderation_state_changed
90
+ update_unread_posts_count if previous_changes.include?('moderation_state')
91
+ end
86
92
  end
87
93
  end
@@ -29,7 +29,11 @@ module Thredded
29
29
  dependent: :destroy
30
30
  has_one :first_post, # rubocop:disable Rails/InverseOf
31
31
  -> { order_oldest_first },
32
- class_name: 'Thredded::PrivatePost',
32
+ class_name: 'Thredded::PrivatePost',
33
+ foreign_key: :postable_id
34
+ has_one :last_post, # rubocop:disable Rails/InverseOf
35
+ -> { order_newest_first },
36
+ class_name: 'Thredded::PrivatePost',
33
37
  foreign_key: :postable_id
34
38
  has_many :private_users,
35
39
  inverse_of: :private_topic,
@@ -39,7 +43,7 @@ module Thredded
39
43
  class_name: 'Thredded::UserPrivateTopicReadState',
40
44
  foreign_key: :postable_id,
41
45
  inverse_of: :postable,
42
- dependent: :destroy
46
+ dependent: :delete_all
43
47
 
44
48
  # Private topics with that have exactly the given participants.
45
49
  scope :has_exact_participants, ->(users) {
@@ -100,5 +104,11 @@ module Thredded
100
104
  def ensure_user_in_private_users
101
105
  users << user if user.present? && !users.include?(user)
102
106
  end
107
+
108
+ class << self
109
+ def post_class
110
+ Thredded::PrivatePost
111
+ end
112
+ end
103
113
  end
104
114
  end
@@ -64,7 +64,7 @@ module Thredded
64
64
  foreign_key: :postable_id
65
65
  has_one :last_post, # rubocop:disable Rails/InverseOf
66
66
  -> { order_newest_first },
67
- class_name: 'Thredded::Post',
67
+ class_name: 'Thredded::Post',
68
68
  foreign_key: :postable_id
69
69
 
70
70
  has_many :topic_categories, inverse_of: :topic, dependent: :delete_all
@@ -73,7 +73,7 @@ module Thredded
73
73
  class_name: 'Thredded::UserTopicReadState',
74
74
  foreign_key: :postable_id,
75
75
  inverse_of: :postable,
76
- dependent: :destroy
76
+ dependent: :delete_all
77
77
  has_many :user_follows,
78
78
  class_name: 'Thredded::UserTopicFollow',
79
79
  inverse_of: :topic,
@@ -115,6 +115,10 @@ module Thredded
115
115
 
116
116
  public
117
117
 
118
+ def post_class
119
+ Thredded::Post
120
+ end
121
+
118
122
  # @param user [Thredded.user_class]
119
123
  # @return [Array<[TopicCommon, UserTopicReadStateCommon, UserTopicFollow]>]
120
124
  def with_read_and_follow_states(user)
@@ -174,9 +178,10 @@ module Thredded
174
178
  end
175
179
 
176
180
  def handle_messageboard_change_after_commit
177
- # Update the `posts.messageboard_id` column. The column is just a performance optimization,
181
+ # Update `messageboard_id` columns. These columns are a performance optimization,
178
182
  # so use update_all to avoid validitaing, triggering callbacks, and updating the timestamps:
179
183
  posts.update_all(messageboard_id: messageboard_id)
184
+ user_read_states.update_all(messageboard_id: messageboard_id)
180
185
 
181
186
  # Update the associated messageboard metadata that Rails does not update them automatically.
182
187
  previous_changes['messageboard_id'].each do |messageboard_id|
@@ -45,13 +45,6 @@ module Thredded
45
45
  has_many :thredded_post_moderation_records, foreign_key: 'post_user_id', inverse_of: :post_user
46
46
  has_many :thredded_post_moderated_records, foreign_key: 'moderator_id', inverse_of: :moderator
47
47
  end
48
-
49
- scope :left_join_thredded_user_details, -> {
50
- users = arel_table
51
- user_details = Thredded::UserDetail.arel_table
52
- joins(users.join(user_details, Arel::Nodes::OuterJoin)
53
- .on(users[:id].eq(user_details[:user_id])).join_sources)
54
- }
55
48
  end
56
49
 
57
50
  def thredded_user_preference
@@ -9,5 +9,40 @@ module Thredded
9
9
  belongs_to :postable,
10
10
  class_name: 'Thredded::PrivateTopic',
11
11
  inverse_of: :user_read_states
12
+
13
+ class << self
14
+ def topic_class
15
+ Thredded::PrivateTopic
16
+ end
17
+
18
+ def visible_posts_scope(_user)
19
+ Thredded::PrivatePost.all
20
+ end
21
+
22
+ # @param [Integer] user_id
23
+ # @param [Thredded::PrivatePost] post
24
+ # @param [Boolean] overwrite_newer
25
+ def touch!(user_id, post, overwrite_newer: false)
26
+ state = find_or_initialize_by(user_id: user_id, postable_id: post.postable_id)
27
+ return if !overwrite_newer && state.read_at? && state.read_at >= post.created_at
28
+ state.read_at = post.created_at
29
+ state.update!(state.calculate_post_counts)
30
+ end
31
+
32
+ # @param [Thredded.user_class] user
33
+ # @param [Thredded::PrivatePost] post
34
+ def read_on_first_post!(user, post)
35
+ create!(user: user, postable_id: post.postable_id, read_at: post.created_at, read_posts_count: 1,
36
+ unread_posts_count: 0)
37
+ end
38
+
39
+ protected
40
+
41
+ # @param [Array<Thredded.user_class>] users
42
+ # @return [Array<[id, unread_count, read_count]>]
43
+ def calculate_post_counts_for_users(users)
44
+ where(user_id: users.map(&:id)).calculate_post_counts
45
+ end
46
+ end
12
47
  end
13
48
  end
@@ -9,5 +9,46 @@ module Thredded
9
9
  belongs_to :postable,
10
10
  class_name: 'Thredded::Topic',
11
11
  inverse_of: :user_read_states
12
+ belongs_to :messageboard,
13
+ class_name: 'Thredded::Messageboard',
14
+ inverse_of: :user_topic_read_states
15
+
16
+ class << self
17
+ def topic_class
18
+ Thredded::Topic
19
+ end
20
+
21
+ def visible_posts_scope(user)
22
+ Thredded::Post.moderation_state_visible_to_user(user)
23
+ end
24
+
25
+ # @param [Integer] user_id
26
+ # @param [Thredded::Post] post
27
+ # @param [Boolean] overwrite_newer
28
+ def touch!(user_id, post, overwrite_newer: false)
29
+ state = find_or_initialize_by(user_id: user_id, postable_id: post.postable_id)
30
+ return if !overwrite_newer && state.read_at? && state.read_at >= post.created_at
31
+ state.messageboard_id = post.messageboard_id
32
+ state.read_at = post.created_at
33
+ state.update!(state.calculate_post_counts)
34
+ end
35
+
36
+ # @param [Thredded.user_class] user
37
+ # @param [Thredded::Post] post
38
+ def read_on_first_post!(user, post)
39
+ create!(user: user, postable_id: post.postable_id, messageboard_id: post.messageboard_id,
40
+ read_at: post.created_at, read_posts_count: 1, unread_posts_count: 0)
41
+ end
42
+
43
+ protected
44
+
45
+ # @param [Array<Thredded.user_class>] users
46
+ # @return [Array<[id, unread_count, read_count]>]
47
+ def calculate_post_counts_for_users(users)
48
+ users
49
+ .group_by { |user| visible_posts_scope(user) }
50
+ .flat_map { |s, u| where(user_id: u.map(&:id)).merge(s).calculate_post_counts }
51
+ end
52
+ end
12
53
  end
13
54
  end
@@ -6,19 +6,36 @@ module Thredded
6
6
  delegate :name, to: :@group, allow_nil: true
7
7
  attr_reader :group, :messageboards
8
8
 
9
- # @param messageboard_scope [ActiveRecord::Relation<Thredded::Messageboard>]
9
+ # @param [ActiveRecord::Relation<Thredded::Messageboard>] messageboards_scope
10
+ # @param [Thredded.user_class] user The user viewing the messageboards.
11
+ # @param [Boolean] with_unread_topics_counts
10
12
  # @return [Array<MessageboardGroupView>]
11
- def self.grouped(messageboard_scope)
12
- messageboard_scope.preload(last_topic: [:last_user])
13
+ def self.grouped(messageboards_scope, user: nil, with_unread_topics_counts: user && !user.thredded_anonymous?)
14
+ scope = messageboards_scope.preload(last_topic: [:last_user])
13
15
  .eager_load(:group)
14
16
  .order(Arel.sql('COALESCE(thredded_messageboard_groups.position, 0) ASC, thredded_messageboard_groups.id ASC'))
15
17
  .ordered
16
- .group_by(&:group)
17
- .map { |(group, messageboards)| MessageboardGroupView.new(group, messageboards) }
18
+ if with_unread_topics_counts
19
+ topics_scope = Pundit.policy_scope!(user, Thredded::Topic)
20
+ unread_topics_counts = messageboards_scope.unread_topics_counts(user: user, topics_scope: topics_scope)
21
+ unread_followed_topics_counts = messageboards_scope.unread_topics_counts(
22
+ user: user, topics_scope: topics_scope.followed_by(user)
23
+ )
24
+ end
25
+ scope.group_by(&:group).map do |(group, messageboards)|
26
+ MessageboardGroupView.new(group, messageboards.map do |messageboard|
27
+ MessageboardView.new(
28
+ messageboard,
29
+ unread_topics_count: with_unread_topics_counts && unread_topics_counts[messageboard.id] || 0,
30
+ unread_followed_topics_count:
31
+ with_unread_topics_counts && unread_followed_topics_counts[messageboard.id] || 0
32
+ )
33
+ end)
34
+ end
18
35
  end
19
36
 
20
- # @param group Thredded::MessageboardGroup
21
- # @param messageboards [Thredded::TopicCommon]
37
+ # @param [Thredded::MessageboardGroup] group
38
+ # @param [Array<Thredded::MessageboardView>] messageboards
22
39
  def initialize(group, messageboards)
23
40
  @group = group
24
41
  @messageboards = messageboards
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thredded
4
+ # A view model for Messageboard.
5
+ class MessageboardView
6
+ delegate :name,
7
+ :description,
8
+ :locked?,
9
+ :topics_count,
10
+ :posts_count,
11
+ :last_topic,
12
+ :last_user,
13
+ to: :@messageboard
14
+
15
+ # @return [Integer]
16
+ attr_reader :unread_topics_count
17
+
18
+ # @return [Integer]
19
+ attr_reader :unread_followed_topics_count
20
+
21
+ # @param [Thredded::Messageboard] messageboard
22
+ # @param [Integer] unread_topics_count
23
+ # @param [Integer] unread_followed_topics_count
24
+ def initialize(messageboard, unread_topics_count: 0, unread_followed_topics_count: 0)
25
+ @messageboard = messageboard
26
+ @unread_topics_count = unread_topics_count
27
+ @unread_followed_topics_count = unread_followed_topics_count
28
+ end
29
+
30
+ # @return [Boolean]
31
+ def unread_topics?
32
+ !@unread_topics_count.zero?
33
+ end
34
+
35
+ # @return [Boolean]
36
+ def unread_followed_topics?
37
+ !@unread_followed_topics_count.zero?
38
+ end
39
+
40
+ # @return [String]
41
+ def path
42
+ Thredded::UrlsHelper.messageboard_topics_path(@messageboard)
43
+ end
44
+
45
+ # @return [String]
46
+ def edit_preferences_path
47
+ Thredded::UrlsHelper.edit_messageboard_preferences_path(@messageboard)
48
+ end
49
+ end
50
+ end
@@ -1,20 +1,10 @@
1
- <% if policy(messageboard).read? %>
2
- <%= view_hooks.messageboards_index.messageboard.render self, messageboard: messageboard do %>
3
- <%= link_to messageboard_topics_path(messageboard), class: 'thredded--messageboard' do %>
4
- <header class="thredded--messageboard--header">
5
- <h2 class="thredded--messageboard--title"><%= messageboard.name %></h2>
6
- <%= render 'thredded/messageboards/messageboard_meta', messageboard: messageboard %>
7
- </header>
8
-
9
- <p class="thredded--messageboard--description"><%= messageboard.description %></p>
10
-
11
- <% if messageboard.last_topic %>
12
- <p class="thredded--messageboard--byline">
13
- <%= t 'thredded.messageboard.last_updated_by_html',
14
- time_ago: time_ago(messageboard.last_topic.last_post_at),
15
- user: messageboard.last_user.thredded_display_name %>
16
- </p>
17
- <% end %>
18
- <% end %>
1
+ <%= view_hooks.messageboards_index.messageboard.render self, messageboard: messageboard do %>
2
+ <%= link_to messageboard.path,
3
+ class: ['thredded--messageboard',
4
+ *('thredded--messageboard--has-unread-topics' if messageboard.unread_topics?),
5
+ *('thredded--messageboard--has-unread-followed-topics' if messageboard.unread_followed_topics?)] do %>
6
+ <%= render 'thredded/messageboards/messageboard/header', messageboard: messageboard %>
7
+ <%= render 'thredded/messageboards/messageboard/description', messageboard: messageboard %>
8
+ <%= render 'thredded/messageboards/messageboard/last_updated', messageboard: messageboard %>
19
9
  <% end %>
20
10
  <% end %>
@@ -2,6 +2,10 @@
2
2
  <% content_for :thredded_page_id, 'thredded--messageboards-index' %>
3
3
  <% content_for :thredded_breadcrumbs, render('thredded/shared/breadcrumbs') %>
4
4
  <%= thredded_page do %>
5
+ <div class="thredded--svg-definitions">
6
+ <%= inline_svg 'thredded/follow.svg', id: 'thredded-follow-icon', title: nil %>
7
+ <%= inline_svg 'thredded/lock.svg', id: 'thredded-lock-icon', title: nil %>
8
+ </div>
5
9
  <%= view_hooks.messageboards_index.container.render self, groups: @groups do %>
6
10
  <section class="thredded--main-section thredded--messageboards">
7
11
  <%= view_hooks.messageboards_index.list.render self, groups: @groups do %>
@@ -11,7 +15,8 @@
11
15
  <% end %>
12
16
  <div class="thredded--messageboards-group">
13
17
  <%= view_hooks.messageboards_index.group.render self, group: group do %>
14
- <%= render group.messageboards %>
18
+ <%= render partial: 'thredded/messageboards/messageboard',
19
+ collection: group.messageboards %>
15
20
  <% end %>
16
21
  </div>
17
22
  <% end %>
@@ -0,0 +1 @@
1
+ <p class="thredded--messageboard--description"><%= messageboard.description %></p>
@@ -0,0 +1,6 @@
1
+ <header class="thredded--messageboard--header">
2
+ <h2 class="thredded--messageboard--title"><%= messageboard.name %></h2>
3
+ <%= render 'thredded/messageboards/messageboard/unread_followed_topics_badge', messageboard: messageboard %>
4
+ <span class="thredded--flex-spacer"></span>
5
+ <%= render 'thredded/messageboards/messageboard/meta', messageboard: messageboard %>
6
+ </header>
@@ -0,0 +1,7 @@
1
+ <% if messageboard.last_topic %>
2
+ <p class="thredded--messageboard--byline">
3
+ <%= t 'thredded.messageboard.last_updated_by_html',
4
+ time_ago: time_ago(messageboard.last_topic.last_post_at),
5
+ user: messageboard.last_user.thredded_display_name %>
6
+ </p>
7
+ <% end %>
@@ -0,0 +1,19 @@
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
+ <svg class="thredded--messageboard--meta--icon" role="img"><use xlink:href="#thredded-lock-icon"></use></svg>
6
+ </span>
7
+ <% end %>
8
+ <h3 class="thredded--messageboard--meta--counts">
9
+ <% if messageboard.unread_topics? %>
10
+ <%= t 'thredded.messageboard.topics_and_unread_topics_counts',
11
+ topics_count: number_with_delimiter(messageboard.topics_count),
12
+ unread_topics_count: number_with_delimiter(messageboard.unread_topics_count) %>
13
+ <% else %>
14
+ <%= t 'thredded.messageboard.topics_and_posts_counts',
15
+ topics_count: number_with_delimiter(messageboard.topics_count),
16
+ posts_count: number_with_delimiter(messageboard.posts_count) %>
17
+ <% end %>
18
+ </h3>
19
+ </div>
@@ -0,0 +1,6 @@
1
+ <% if messageboard.unread_followed_topics? %>
2
+ <span class="thredded--messageboard--unread-followed-topics-count">
3
+ <svg class="thredded--messageboard--unread-followed-icon" role="img"><use xlink:href="#thredded-follow-icon"></use></svg>
4
+ <%= number_with_delimiter messageboard.unread_followed_topics_count %>
5
+ </span>
6
+ <% end %>
@@ -1,2 +1,2 @@
1
- <%= link_to messageboard.name, edit_messageboard_preferences_path(messageboard),
1
+ <%= link_to messageboard.name, messageboard.edit_preferences_path,
2
2
  class: 'thredded--preferences--messageboards-nav--item thredded--messageboard' %>
@@ -3,5 +3,5 @@
3
3
  <%= content_tag :article, id: dom_id(private_post), class: "thredded--post thredded--#{private_post.read_state}--post" do %>
4
4
  <%= render 'thredded/posts_common/actions', post: private_post, actions: local_assigns[:actions] %>
5
5
  <%= render 'thredded/posts_common/header', post: private_post %>
6
- <%= content || render('thredded/private_posts/content', post: post) %>
6
+ <%= content || render('thredded/private_posts/content', post: private_post) %>
7
7
  <% end %>
@@ -9,9 +9,15 @@
9
9
  <%= thredded_page do %>
10
10
  <%= render 'section_title', label: 'messageboards#index', href: messageboards_path %>
11
11
  <%= content_tag :section, class: 'thredded--thredded--main-section thredded--messageboards' do %>
12
- <%= render @messageboards %>
13
- <div class="thredded--messageboard--create">
14
- <a class="thredded--button" href="<%= new_messageboard_path %>">
12
+ <div class="thredded--svg-definitions">
13
+ <%= inline_svg 'thredded/follow.svg', id: 'thredded-follow-icon', title: nil %>
14
+ <%= inline_svg 'thredded/lock.svg', id: 'thredded-lock-icon', title: nil %>
15
+ </div>
16
+ <div class="thredded--messageboards-group">
17
+ <%= render partial: 'thredded/messageboards/messageboard', collection: @messageboard_views %>
18
+ </div>
19
+ <div class="thredded--messageboards--actions">
20
+ <a class="thredded--button" href="<%= new_messageboard_path %>" rel="nofollow">
15
21
  <%= t 'thredded.messageboard.create' %>
16
22
  </a>
17
23
  </div>
@@ -82,7 +88,7 @@
82
88
  <%= render 'section_title', label: 'private_topics#show', href: private_topic_path(@private_topic) %>
83
89
  <section class="thredded--thredded--main-section">
84
90
  <%= render 'thredded/private_topics/header', topic: @private_topic %>
85
- <%= render @private_posts %>
91
+ <%= render partial: 'thredded/private_posts/private_post', collection: @private_posts %>
86
92
  <%= render 'thredded/private_posts/form',
87
93
  post: @private_post_form,
88
94
  button_text: t('thredded.private_posts.form.create_btn')
@@ -5,7 +5,7 @@
5
5
  <div class="thredded--topics--posts-count"><%= topic.posts_count %></div>
6
6
 
7
7
  <div class="thredded--topics--follow-info" title="<%= topic_follow_reason_text topic.follow_reason %>">
8
- <svg class="thredded--topics--follow-icon" viewBox="0 0 116 121" role="img">
8
+ <svg class="thredded--topics--follow-icon" role="img">
9
9
  <% if topic.followed? %>
10
10
  <use xlink:href="#thredded-follow-icon"></use>
11
11
  <% else %>
@@ -7,7 +7,7 @@
7
7
 
8
8
  <%= thredded_page do %>
9
9
  <% if @topics.present? %>
10
- <div class="thredded--svg-definitions ">
10
+ <div class="thredded--svg-definitions">
11
11
  <%= inline_svg 'thredded/follow.svg', id: 'thredded-follow-icon', title: nil %>
12
12
  <%= inline_svg 'thredded/unfollow.svg', id: 'thredded-unfollow-icon' %>
13
13
  </div>