thredded 0.15.5 → 0.16.0

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