thredded 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0404295457d213a2f5fdb46e8cff204fb08dc55b
4
- data.tar.gz: 11dd30fc6953380143931bb1ebd52b7dd6ec1f57
3
+ metadata.gz: fc3545dd645f403b5ae3ca2bed2d5a6ab6b3f627
4
+ data.tar.gz: ca8d375aa187a223f7a250415c36e4749328074c
5
5
  SHA512:
6
- metadata.gz: 1d66513bb8d504e9f1f6762b709f857c435a8fd6729f9e10ec08fcc0cae746e792132f3bbc64cf366c62603a6bc6fbae1fa1d6b3df9587bff8c618615a84383b
7
- data.tar.gz: 58ea29e130f147a419b27f75312411c4e6786af2320a20563ae6ee895733cbaac787168beacbb7943480690cb34622f05a119866d87f2f56978af68b48f501b9
6
+ metadata.gz: 9cf1df595f1f50cea1c495adc89ad1049024a702af881632799a9a0ea8305087a4ce1c51a55c9419465b33fb7f1af4313d979da93da5fab27ee9fcb477ba4e1c
7
+ data.tar.gz: e52bed5a33b9852a5bebcff13484ffe9ff97c7cbe93f4b0e5f470152beafc99f15c4eb6a4acf483cc5e0375b1aa3216e0a48ed5d7bc547572bb8d8eea5a12029
data/CHANGELOG.mkdn CHANGED
@@ -1,3 +1,19 @@
1
+ # 0.5.1
2
+
3
+ This is a minor bugfix release.
4
+
5
+ ## Fixed
6
+
7
+ * Security: only allow http, https, and relative iframe src protocols.
8
+ * Security: sanitization filter is applied last (no actual issues were discovered, but this is how it should be).
9
+ * Fixes multiple issues with @-mentions parsing and highlighting. [e6357ff](https://github.com/thredded/thredded/commit/e6357ffb45bf9118a9f5c7df0d436bdffe0a84c6)
10
+ * Minor CSS fixes.
11
+ * Messageboards index page title is now i18n'd.
12
+ * The "Delete Topic" now shows a confirmation dialog.
13
+ * Editing posts by deleted users no longer throws an exception.
14
+
15
+ See the full list of changes here: https://github.com/thredded/thredded/compare/v0.5.0...v0.5.1.
16
+
1
17
  # 0.5.0
2
18
 
3
19
  **NB:** If updating to this version from 0.4.x, you will need to copy and run [this migration](https://github.com/thredded/thredded/blob/5e203c8eec05919d97f4d26fa2a1fc3081e992a7/db/upgrade_migrations/20160501151908_upgrade_v0_4_to_v0_5.rb).
data/README.mkdn CHANGED
@@ -44,7 +44,7 @@ application and not an engine like Thredded.
44
44
  Add the gem to your Gemfile:
45
45
 
46
46
  ```ruby
47
- gem 'thredded', '~> 0.5.0'
47
+ gem 'thredded', '~> 0.5.1'
48
48
  ```
49
49
 
50
50
  Add the Thredded [initializer] to your parent app by running the install generator.
@@ -13,6 +13,7 @@
13
13
  margin-right: $thredded-small-spacing;
14
14
  position: relative;
15
15
  top: 6px;
16
+ vertical-align: baseline;
16
17
  width: 1.75rem; // 28px
17
18
 
18
19
  @media (min-width: $thredded-grid-container-max-width + 4rem) {
@@ -40,7 +40,7 @@
40
40
  box-shadow: none;
41
41
  margin-right: 0;
42
42
  -webkit-margin-end: 0;
43
- min-width: 18rem;
43
+ min-width: 16rem;
44
44
  text-align: left;
45
45
  }
46
46
 
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
  module Thredded
3
3
  class AtNotificationExtractor
4
+ # Matches the names in @joe, @"Joe 1", but not email@host.com.
5
+ # The matched name is captured and may contain the surrounding quotes.
6
+ MATCH_NAME_RE = /(?:^|[\s>])@([\w]+|"[\w ]+")(?=\W|$)/
7
+
4
8
  def initialize(content)
5
9
  @content = content
6
10
  end
7
11
 
8
12
  def run
9
- scanned_names = @content.scan(/@([\w]+)(\W)?/)
10
- scanned_names += @content.scan(/@"([\w\ ]+)"(\W)?/)
11
- scanned_names
12
- .map(&:first)
13
- .uniq
13
+ @content.scan(MATCH_NAME_RE).map(&:first).map { |m| m.start_with?('"') ? m[1..-2] : m }.uniq
14
14
  end
15
15
  end
16
16
  end
@@ -10,7 +10,7 @@ module Thredded
10
10
  foreign_key: 'last_user_id'
11
11
 
12
12
  scope :order_recently_updated_first, -> { order(updated_at: :desc, id: :desc) }
13
- scope :on_page, -> page_num { page(page_num).per(30) }
13
+ scope :on_page, -> (page_num) { page(page_num).per(30) }
14
14
 
15
15
  validates :hash_id, presence: true, uniqueness: true
16
16
  validates :last_user_id, presence: true
@@ -49,6 +49,7 @@ module Thredded
49
49
  end
50
50
 
51
51
  def auto_follow_and_notify
52
+ return unless user
52
53
  # need to do this in-process so that it appears to them immediately
53
54
  UserTopicFollow.create_unless_exists(user.id, postable_id, :posted)
54
55
  # everything else can happen later
@@ -5,13 +5,13 @@ module Thredded
5
5
  include TopicCommon
6
6
  include ContentModerationState
7
7
 
8
- scope :for_messageboard, -> messageboard { where(messageboard_id: messageboard.id) }
8
+ scope :for_messageboard, -> (messageboard) { where(messageboard_id: messageboard.id) }
9
9
 
10
10
  scope :stuck, -> { where(sticky: true) }
11
11
  scope :unstuck, -> { where(sticky: false) }
12
12
 
13
13
  # Using `search_query` instead of `search` to avoid conflict with Ransack.
14
- scope :search_query, -> query { ::Thredded::TopicsSearch.new(query, self).search }
14
+ scope :search_query, -> (query) { ::Thredded::TopicsSearch.new(query, self).search }
15
15
 
16
16
  scope :order_sticky_first, -> { order(sticky: :desc) }
17
17
 
@@ -1,4 +1,4 @@
1
- <% content_for :thredded_page_title, 'Messageboards' %>
1
+ <% content_for :thredded_page_title, t('thredded.messageboard.index.page_title') %>
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 %>
@@ -21,9 +21,10 @@
21
21
 
22
22
  <% if topic.can_destroy? %>
23
23
  <div class="thredded--topic-delete--wrapper">
24
- <%= form_tag topic.destroy_path, method: :delete, class: 'thredded--topic-delete-form' do %>
25
- <%= submit_tag 'Delete Topic', class: 'thredded--form--submit' %>
26
- <% end %>
24
+ <%= button_to t('thredded.topics.delete_topic'), topic.destroy_path, method: :delete,
25
+ form_class: 'thredded--topic-delete-form',
26
+ class: 'thredded--button',
27
+ 'data-confirm' => t('thredded.topics.delete_confirm') %>
27
28
  </div>
28
29
  <% end %>
29
30
  <% end %>
@@ -1,20 +1,22 @@
1
1
  ---
2
2
  en:
3
3
  thredded:
4
- form:
5
- update: Update
6
4
  errors:
7
5
  login_required: Please sign in first.
8
6
  not_authorized: You are not authorized to access this page.
9
7
  private_topic_create_denied: You are not authorized to create private topics.
10
8
  private_topic_not_found: This private topic does not exist.
9
+ form:
10
+ update: Update
11
11
  messageboard:
12
12
  create: Create a New Messageboard
13
- update: :thredded.form.update
14
13
  form:
15
14
  no_group: No Group
15
+ index:
16
+ page_title: Messageboards
16
17
  last_updated_by_html: Updated %{time_ago} <cite>by %{user}</cite>
17
18
  topics_and_posts_counts: "%{topics_count} topics / %{posts_count} posts"
19
+ update: :thredded.form.update
18
20
  updated_notice: Messageboard has been updated
19
21
  messageboard_group:
20
22
  create: Create a New Messageboard Group
@@ -22,25 +24,26 @@ en:
22
24
  approve_btn: Approve
23
25
  block_btn: Block
24
26
  pending_empty:
25
- title: Good job!
26
27
  content: All posts have been moderated.
28
+ title: Good job!
27
29
  post_approved_html: Post approved by %{moderator} %{time_ago}.
28
30
  post_blocked_html: Post blocked by %{moderator} %{time_ago}.
29
31
  post_deleted_notice: This post has been deleted.
30
- posts_content_changed_since_moderation_html: The <a href="%{post_url}">post's</a> content change since it was moderated. Below is the content at the time it was moderated.
32
+ posts_content_changed_since_moderation_html: >-
33
+ The <a href="%{post_url}">post's</a> content change since it was moderated. Below is the content at the
34
+ time it was moderated.
31
35
  nav:
32
36
  all_messageboards: All Messageboards
33
37
  edit_messageboard: Edit Messageboard
34
38
  edit_post: Edit Post
35
39
  edit_private_topic: :thredded.nav.edit_topic
36
40
  edit_topic: Edit
37
- private_topics: Private Messages
38
- settings: Notification Settings
39
41
  moderation: Moderation
40
42
  moderation_history: History
43
+ private_topics: Private Messages
44
+ settings: Notification Settings
41
45
  null_user_name: Deleted user
42
46
  posts:
43
- pending_moderation_notice: Your post will be published when it has been reviewed by a moderator.
44
47
  delete: Delete Post
45
48
  delete_confirm: Are you sure you want to delete this post?
46
49
  deleted_notice: Your post has been deleted.
@@ -49,6 +52,7 @@ en:
49
52
  content_label: Content
50
53
  create_btn: Submit Reply
51
54
  update_btn: Update Post
55
+ pending_moderation_notice: Your post will be published when it has been reviewed by a moderator.
52
56
  preferences:
53
57
  edit:
54
58
  page_title: :thredded.nav.settings
@@ -56,15 +60,15 @@ en:
56
60
  global_preferences_label: Global Settings
57
61
  messageboard_notify_on_mention:
58
62
  hint: >-
59
- When someone mentions you by your username (eg: @sam) in this messageboard you will follow
60
- the topic. You will receive emails with the contents of that post and any replies.
63
+ When someone mentions you by your username (eg: @sam) in this messageboard you will follow the topic.
64
+ You will receive emails with the contents of that post and any replies.
61
65
  label: :thredded.preferences.form.notify_on_mention.label
62
66
  messageboard_preferences_label_html: Notification Settings for <em>%{messageboard}</em>
63
67
  notify_on_mention:
64
68
  hint: >-
65
- When someone mentions you by your username (eg: @sam) you will follow the topic.
66
- You will receive emails with the contents of that post and any replies.
67
- label: "Follow topics you are mentioned in"
69
+ When someone mentions you by your username (eg: @sam) you will follow the topic. You will receive emails
70
+ with the contents of that post and any replies.
71
+ label: Follow topics you are mentioned in
68
72
  notify_on_message:
69
73
  hint: When you are added to a private conversation you will receive an email with its content.
70
74
  label: Private Message Notifications
@@ -98,8 +102,16 @@ en:
98
102
  label: Search
99
103
  placeholder: Search Topics and Posts
100
104
  topics:
105
+ delete_confirm: Are you sure you want to delete this topic? This CANNOT be undone.
106
+ delete_topic: Delete Topic
101
107
  deleted_notice: Topic deleted
102
108
  edit: Edit Topic
109
+ followed_notice: You are now following this topic
110
+ following:
111
+ manual: You are following this topic.
112
+ mentioned: You are following this topic because you were mentioned on it.
113
+ posted: You are following this topic because you posted to it.
114
+ following_will_receive_emails: You will receive email updates.
103
115
  form:
104
116
  categories_placeholder: Categories
105
117
  content_label: :thredded.posts.form.content_label
@@ -112,11 +124,5 @@ en:
112
124
  page_title: Topics Search Results
113
125
  results_message: Search Results for %{query}
114
126
  started_by_html: Started %{time_ago} by %{user}
115
- updated_notice: Topic updated
116
- followed_notice: You are now following this topic
117
127
  unfollowed_notice: You are no longer following this topic
118
- following:
119
- manual: You are following this topic.
120
- posted: You are following this topic because you posted to it.
121
- mentioned: You are following this topic because you were mentioned on it.
122
- following_will_receive_emails: You will receive email updates.
128
+ updated_notice: Topic updated
@@ -12,6 +12,8 @@ pt-BR:
12
12
  create: Criar um novo Fórum de Mensagem
13
13
  form:
14
14
  no_group: Sem Grupo
15
+ index:
16
+ page_title: Fóruns de Mensagens
15
17
  last_updated_by_html: Atualizado %{time_ago} <cite>por %{user}</cite>
16
18
  topics_and_posts_counts: "%{topics_count} tópicos / %{posts_count} posts"
17
19
  update: :thredded.form.update
@@ -101,8 +103,16 @@ pt-BR:
101
103
  label: Buscar
102
104
  placeholder: Buscar Tópicos e Posts
103
105
  topics:
106
+ delete_confirm: Você tem certeza que deseja remover este tópico? Isto não pode ser desfeito.
107
+ delete_topic: Remover Tópico
104
108
  deleted_notice: Tópico removido
105
109
  edit: Editar Tópico
110
+ followed_notice: You are now following this topic
111
+ following:
112
+ manual: You are following this topic.
113
+ mentioned: You are following this topic because you were mentioned on it.
114
+ posted: You are following this topic because you posted to it.
115
+ following_will_receive_emails: You will receive email updates.
106
116
  form:
107
117
  categories_placeholder: Categorias
108
118
  content_label: :thredded.posts.form.content_label
@@ -115,11 +125,5 @@ pt-BR:
115
125
  page_title: Tópicos dos Resultados da Busca
116
126
  results_message: Resultados de Busca para %{query}
117
127
  started_by_html: Iniciado %{time_ago} por %{user}
118
- updated_notice: Tópico atualizado
119
- followed_notice: You are now following this topic
120
128
  unfollowed_notice: You are no longer following this topic
121
- following:
122
- manual: You are following this topic.
123
- posted: You are following this topic because you posted to it.
124
- mentioned: You are following this topic because you were mentioned on it.
125
- following_will_receive_emails: You will receive email updates.
129
+ updated_notice: Tópico atualizado
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  # rubocop:disable Metrics/ClassLength
3
3
  # rubocop:disable Metrics/MethodLength
4
- # rubocop:disable Metrics/LineLength
5
4
  class CreateThredded < ActiveRecord::Migration
6
5
  def change
7
6
  unless table_exists?(:friendly_id_slugs)
@@ -12,11 +11,13 @@ class CreateThredded < ActiveRecord::Migration
12
11
  t.string :sluggable_type, limit: 50
13
12
  t.string :scope, limit: 191
14
13
  t.datetime :created_at, null: false
14
+ t.index [:slug, :sluggable_type, :scope],
15
+ name: :index_friendly_id_slugs_on_slug_and_sluggable_type_and_scope,
16
+ unique: true
17
+ t.index [:slug, :sluggable_type], name: :index_friendly_id_slugs_on_slug_and_sluggable_type
18
+ t.index [:sluggable_id], name: :index_friendly_id_slugs_on_sluggable_id
19
+ t.index [:sluggable_type], name: :index_friendly_id_slugs_on_sluggable_type
15
20
  end
16
- add_index :friendly_id_slugs, [:slug, :sluggable_type, :scope], name: :index_friendly_id_slugs_on_slug_and_sluggable_type_and_scope, unique: true
17
- add_index :friendly_id_slugs, [:slug, :sluggable_type], name: :index_friendly_id_slugs_on_slug_and_sluggable_type
18
- add_index :friendly_id_slugs, [:sluggable_id], name: :index_friendly_id_slugs_on_sluggable_id
19
- add_index :friendly_id_slugs, [:sluggable_type], name: :index_friendly_id_slugs_on_sluggable_type
20
21
  end
21
22
 
22
23
  create_table :thredded_categories do |t|
@@ -25,9 +26,9 @@ class CreateThredded < ActiveRecord::Migration
25
26
  t.string :description, limit: 255
26
27
  t.timestamps null: false
27
28
  t.string :slug, limit: 191, null: false
29
+ t.index [:messageboard_id, :slug], name: :index_thredded_categories_on_messageboard_id_and_slug, unique: true
30
+ t.index [:messageboard_id], name: :index_thredded_categories_on_messageboard_id
28
31
  end
29
- add_index :thredded_categories, [:messageboard_id, :slug], name: :index_thredded_categories_on_messageboard_id_and_slug, unique: true
30
- add_index :thredded_categories, [:messageboard_id], name: :index_thredded_categories_on_messageboard_id
31
32
  DbTextSearch::CaseInsensitive.add_index connection, :thredded_categories, :name, name: :thredded_categories_name_ci
32
33
 
33
34
  create_table :thredded_messageboards do |t|
@@ -40,17 +41,17 @@ class CreateThredded < ActiveRecord::Migration
40
41
  t.references :messageboard_group
41
42
  t.timestamps null: false
42
43
  t.index [:messageboard_group_id], name: :index_thredded_messageboards_on_messageboard_group_id
44
+ t.index [:closed], name: :index_thredded_messageboards_on_closed
45
+ t.index [:slug], name: :index_thredded_messageboards_on_slug
43
46
  end
44
- add_index :thredded_messageboards, [:closed], name: :index_thredded_messageboards_on_closed
45
- add_index :thredded_messageboards, [:slug], name: :index_thredded_messageboards_on_slug
46
47
 
47
48
  create_table :thredded_post_notifications do |t|
48
49
  t.string :email, limit: 191, null: false
49
50
  t.integer :post_id, null: false
50
51
  t.timestamps null: false
51
52
  t.string :post_type, limit: 191
53
+ t.index [:post_id, :post_type], name: :index_thredded_post_notifications_on_post
52
54
  end
53
- add_index :thredded_post_notifications, [:post_id, :post_type], name: :index_thredded_post_notifications_on_post
54
55
 
55
56
  create_table :thredded_posts do |t|
56
57
  t.integer :user_id, limit: 4
@@ -64,11 +65,11 @@ class CreateThredded < ActiveRecord::Migration
64
65
  t.index [:moderation_state, :updated_at],
65
66
  order: { updated_at: :asc },
66
67
  name: :index_thredded_posts_for_display
68
+ t.index [:messageboard_id], name: :index_thredded_posts_on_messageboard_id
69
+ t.index [:postable_id], name: :index_thredded_posts_on_postable_id
70
+ t.index [:postable_id], name: :index_thredded_posts_on_postable_id_and_postable_type
71
+ t.index [:user_id], name: :index_thredded_posts_on_user_id
67
72
  end
68
- add_index :thredded_posts, [:messageboard_id], name: :index_thredded_posts_on_messageboard_id
69
- add_index :thredded_posts, [:postable_id], name: :index_thredded_posts_on_postable_id
70
- add_index :thredded_posts, [:postable_id], name: :index_thredded_posts_on_postable_id_and_postable_type
71
- add_index :thredded_posts, [:user_id], name: :index_thredded_posts_on_user_id
72
73
  DbTextSearch::FullText.add_index connection, :thredded_posts, :content, name: :thredded_posts_content_fts
73
74
 
74
75
  create_table :thredded_private_posts do |t|
@@ -87,24 +88,24 @@ class CreateThredded < ActiveRecord::Migration
87
88
  t.integer :posts_count, default: 0
88
89
  t.string :hash_id, limit: 191, null: false
89
90
  t.timestamps null: false
91
+ t.index [:hash_id], name: :index_thredded_private_topics_on_hash_id
92
+ t.index [:slug], name: :index_thredded_private_topics_on_slug
90
93
  end
91
- add_index :thredded_private_topics, [:hash_id], name: :index_thredded_private_topics_on_hash_id
92
- add_index :thredded_private_topics, [:slug], name: :index_thredded_private_topics_on_slug
93
94
 
94
95
  create_table :thredded_private_users do |t|
95
96
  t.integer :private_topic_id, limit: 4
96
97
  t.integer :user_id, limit: 4
97
98
  t.timestamps null: false
99
+ t.index [:private_topic_id], name: :index_thredded_private_users_on_private_topic_id
100
+ t.index [:user_id], name: :index_thredded_private_users_on_user_id
98
101
  end
99
- add_index :thredded_private_users, [:private_topic_id], name: :index_thredded_private_users_on_private_topic_id
100
- add_index :thredded_private_users, [:user_id], name: :index_thredded_private_users_on_user_id
101
102
 
102
103
  create_table :thredded_topic_categories do |t|
103
104
  t.integer :topic_id, null: false
104
105
  t.integer :category_id, null: false
106
+ t.index [:category_id], name: :index_thredded_topic_categories_on_category_id
107
+ t.index [:topic_id], name: :index_thredded_topic_categories_on_topic_id
105
108
  end
106
- add_index :thredded_topic_categories, [:category_id], name: :index_thredded_topic_categories_on_category_id
107
- add_index :thredded_topic_categories, [:topic_id], name: :index_thredded_topic_categories_on_topic_id
108
109
 
109
110
  create_table :thredded_topics do |t|
110
111
  t.integer :user_id, null: false
@@ -122,11 +123,11 @@ class CreateThredded < ActiveRecord::Migration
122
123
  t.index %i(moderation_state sticky updated_at),
123
124
  order: { sticky: :desc, updated_at: :desc },
124
125
  name: :index_thredded_topics_for_display
126
+ t.index [:hash_id], name: :index_thredded_topics_on_hash_id
127
+ t.index [:messageboard_id, :slug], name: :index_thredded_topics_on_messageboard_id_and_slug, unique: true
128
+ t.index [:messageboard_id], name: :index_thredded_topics_on_messageboard_id
129
+ t.index [:user_id], name: :index_thredded_topics_on_user_id
125
130
  end
126
- add_index :thredded_topics, [:hash_id], name: :index_thredded_topics_on_hash_id
127
- add_index :thredded_topics, [:messageboard_id, :slug], name: :index_thredded_topics_on_messageboard_id_and_slug, unique: true
128
- add_index :thredded_topics, [:messageboard_id], name: :index_thredded_topics_on_messageboard_id
129
- add_index :thredded_topics, [:user_id], name: :index_thredded_topics_on_user_id
130
131
  DbTextSearch::FullText.add_index connection, :thredded_topics, :title, name: :thredded_topics_title_fts
131
132
 
132
133
  create_table :thredded_user_details do |t|
@@ -149,29 +150,29 @@ class CreateThredded < ActiveRecord::Migration
149
150
  t.references :thredded_user_detail, foreign_key: true, null: false
150
151
  t.references :thredded_messageboard, foreign_key: true, null: false
151
152
  t.datetime :last_seen_at, null: false
152
- end
153
- add_index :thredded_messageboard_users, [:thredded_messageboard_id, :thredded_user_detail_id],
153
+ t.index [:thredded_messageboard_id, :thredded_user_detail_id],
154
154
  name: :index_thredded_messageboard_users_primary
155
- add_index :thredded_messageboard_users, [:thredded_messageboard_id, :last_seen_at],
155
+ t.index [:thredded_messageboard_id, :last_seen_at],
156
156
  name: :index_thredded_messageboard_users_for_recently_active
157
+ end
157
158
 
158
159
  create_table :thredded_user_preferences do |t|
159
160
  t.integer :user_id, null: false
160
161
  t.boolean :notify_on_mention, default: true, null: false
161
162
  t.boolean :notify_on_message, default: true, null: false
162
163
  t.timestamps null: false
164
+ t.index [:user_id], name: :index_thredded_user_preferences_on_user_id
163
165
  end
164
- add_index :thredded_user_preferences, [:user_id], name: :index_thredded_user_preferences_on_user_id
165
166
 
166
167
  create_table :thredded_user_messageboard_preferences do |t|
167
168
  t.integer :user_id, null: false
168
169
  t.integer :messageboard_id, null: false
169
170
  t.boolean :notify_on_mention, default: true, null: false
170
171
  t.timestamps null: false
172
+ t.index [:user_id, :messageboard_id],
173
+ name: :thredded_user_messageboard_preferences_user_id_messageboard_id,
174
+ unique: true
171
175
  end
172
- add_index :thredded_user_messageboard_preferences, [:user_id, :messageboard_id],
173
- unique: true,
174
- name: :thredded_user_messageboard_preferences_user_id_messageboard_id
175
176
 
176
177
  %i(topic private_topic).each do |topics_table|
177
178
  table_name = :"thredded_user_#{topics_table}_read_states"
@@ -180,8 +181,8 @@ class CreateThredded < ActiveRecord::Migration
180
181
  t.integer :postable_id, null: false
181
182
  t.integer :page, default: 1, null: false
182
183
  t.timestamp :read_at, null: false
184
+ t.index [:user_id, :postable_id], name: :"#{table_name}_user_postable", unique: true
183
185
  end
184
- add_index table_name, [:user_id, :postable_id], name: :"#{table_name}_user_postable", unique: true
185
186
  end
186
187
 
187
188
  create_table :thredded_messageboard_groups do |t|
@@ -194,8 +195,8 @@ class CreateThredded < ActiveRecord::Migration
194
195
  t.integer :topic_id, null: false
195
196
  t.datetime :created_at, null: false
196
197
  t.integer :reason, limit: 1
198
+ t.index [:user_id, :topic_id], name: :thredded_user_topic_follows_user_topic, unique: true
197
199
  end
198
- add_index :thredded_user_topic_follows, [:user_id, :topic_id], name: :thredded_user_topic_follows_user_topic, unique: true
199
200
 
200
201
  create_table :thredded_post_moderation_records do |t|
201
202
  t.references :post
@@ -213,6 +214,5 @@ class CreateThredded < ActiveRecord::Migration
213
214
  end
214
215
  end
215
216
  end
216
- # rubocop:enable Metrics/LineLength
217
217
  # rubocop:enable Metrics/MethodLength
218
218
  # rubocop:enable Metrics/ClassLength
data/heroku.gemfile CHANGED
@@ -6,7 +6,6 @@ gem 'thredded', path: File.dirname(__FILE__)
6
6
 
7
7
  # Rails 5
8
8
  gem 'rails', '~> 5.0.0.racecar1'
9
- gem 'kaminari', git: 'https://github.com/amatsuda/kaminari'
10
9
  gem 'active_record_union', git: 'https://github.com/glebm/active_record_union', branch: 'rails-5-test-harness'
11
10
 
12
11
  # Make these gems available in production
data/heroku.gemfile.lock CHANGED
@@ -1,11 +1,3 @@
1
- GIT
2
- remote: https://github.com/amatsuda/kaminari
3
- revision: f93231e6e7624dde21b528726ec471029ffb8b02
4
- specs:
5
- kaminari (1.0.0.alpha)
6
- actionpack (>= 3.0.0)
7
- activesupport (>= 3.0.0)
8
-
9
1
  GIT
10
2
  remote: https://github.com/glebm/active_record_union
11
3
  revision: fde21fb8fe7d5d3cc24f1dc5d6627d92c30f10e5
@@ -17,7 +9,7 @@ GIT
17
9
  PATH
18
10
  remote: .
19
11
  specs:
20
- thredded (0.5.0)
12
+ thredded (0.5.1)
21
13
  active_record_union (>= 1.1.1)
22
14
  autoprefixer-rails
23
15
  autosize-rails
@@ -145,6 +137,9 @@ GEM
145
137
  railties (>= 3.1.0)
146
138
  turbolinks
147
139
  json (1.8.3)
140
+ kaminari (0.17.0)
141
+ actionpack (>= 3.0.0)
142
+ activesupport (>= 3.0.0)
148
143
  libv8 (3.16.14.15)
149
144
  loofah (2.0.3)
150
145
  nokogiri (>= 1.5.9)
@@ -268,7 +263,6 @@ DEPENDENCIES
268
263
  faker (>= 1.6.2)
269
264
  http_accept_language
270
265
  jquery-turbolinks
271
- kaminari!
272
266
  newrelic_rpm
273
267
  pg
274
268
  puma
@@ -12,7 +12,8 @@ namespace :thredded do
12
12
  task :emoji do
13
13
  require 'emoji'
14
14
 
15
- target = "#{Rake.original_dir}/public"
15
+ target = Rails.application.root.join('public')
16
+ STDERR.puts "Copying emoji to #{target}"
16
17
  `mkdir -p '#{target}' && cp -Rp '#{Emoji.images_path}/emoji' '#{target}'`
17
18
  end
18
19
  end
@@ -10,8 +10,9 @@ module Thredded
10
10
 
11
11
  members.each do |member|
12
12
  member_path = Thredded.user_path(view_context, member)
13
- content.gsub!(/(@#{member.to_s})\b/i,
14
- %(<a href="#{ERB::Util.html_escape member_path}">\\1</a>))
13
+ name = member.to_s
14
+ content.gsub!(/(^|[\s>])(@#{name.include?(' ') ? %("#{name}") : name})\b/i,
15
+ %(\1<a href="#{ERB::Util.html_escape member_path}">@#{ERB::Util.html_escape name}</a>))
15
16
  end
16
17
  end
17
18
 
@@ -31,6 +31,11 @@ module Thredded
31
31
  'seamless' => 'seamless',
32
32
  'sandbox' => 'allow-same-origin allow-scripts allow-forms',
33
33
  }
34
+ },
35
+ protocols: {
36
+ 'iframe' => {
37
+ 'src' => ['https', 'http', :relative]
38
+ }
34
39
  }
35
40
  )
36
41
 
@@ -38,14 +43,14 @@ module Thredded
38
43
  mattr_accessor :pipeline_filters
39
44
 
40
45
  self.pipeline_filters = [
46
+ HTML::Pipeline::AtMentionFilter,
41
47
  HTML::Pipeline::VimeoFilter,
42
48
  HTML::Pipeline::YoutubeFilter,
43
49
  HTML::Pipeline::BbcodeFilter,
44
50
  HTML::Pipeline::MarkdownFilter,
45
- HTML::Pipeline::SanitizationFilter,
46
- HTML::Pipeline::AtMentionFilter,
47
51
  HTML::Pipeline::EmojiFilter,
48
52
  HTML::Pipeline::AutolinkFilter,
53
+ HTML::Pipeline::SanitizationFilter,
49
54
  ].freeze
50
55
 
51
56
  # @param view_context [Object] the context of the rendering view.
@@ -22,13 +22,8 @@ module Thredded
22
22
 
23
23
  next unless keyword_scan.present?
24
24
  keyword_scan.each do |term|
25
- keyword_term = term.delete(' ').split(':')
26
-
27
- if found_terms_hash[keyword].nil?
28
- found_terms_hash[keyword] = []
29
- end
30
-
31
- found_terms_hash[keyword] << keyword_term[1]
25
+ found_terms_hash[keyword] ||= []
26
+ found_terms_hash[keyword] << term.delete(' ').split(':')[1]
32
27
  end
33
28
  end
34
29
 
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Thredded
3
- VERSION = '0.5.0'
3
+ VERSION = '0.5.1'
4
4
  end
data/lib/thredded.rb CHANGED
@@ -52,7 +52,7 @@ module Thredded
52
52
  self.active_user_threshold = 5.minutes
53
53
  self.admin_column = :admin
54
54
  self.avatar_url = ->(user) { Gravatar.src(user.email, 128, 'mm') }
55
- self.email_reply_to = -> postable { "#{postable.hash_id}@#{Thredded.email_incoming_host}" }
55
+ self.email_reply_to = -> (postable) { "#{postable.hash_id}@#{Thredded.email_incoming_host}" }
56
56
  self.layout = 'thredded/application'
57
57
  self.moderator_column = :admin
58
58
  self.user_name_column = :name
@@ -60,9 +60,7 @@ module Thredded
60
60
 
61
61
  # @return [Class<Thredded::UserExtender>] the user class from the host application.
62
62
  def self.user_class
63
- if @@user_class.is_a?(Class)
64
- fail 'Please use a string instead of a class'
65
- end
63
+ fail 'Please use a string instead of a class' if @@user_class.is_a?(Class)
66
64
 
67
65
  if @@user_class.is_a?(String)
68
66
  begin
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thredded
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Oliveira
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-06-09 00:00:00.000000000 Z
12
+ date: 2016-06-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bbcoder