thredded 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.mkdn +22 -2
  3. data/README.mkdn +17 -5
  4. data/app/assets/stylesheets/thredded/base/_typography.scss +9 -0
  5. data/app/assets/stylesheets/thredded/base/_variables.scss +4 -0
  6. data/app/assets/stylesheets/thredded/components/_messageboard.scss +13 -1
  7. data/app/assets/stylesheets/thredded/components/_post.scss +15 -1
  8. data/app/assets/stylesheets/thredded/layout/_search-navigation.scss +1 -1
  9. data/app/controllers/thredded/application_controller.rb +1 -1
  10. data/app/controllers/thredded/messageboard_groups_controller.rb +29 -0
  11. data/app/controllers/thredded/messageboards_controller.rb +24 -10
  12. data/app/controllers/thredded/post_permalinks_controller.rb +10 -0
  13. data/app/controllers/thredded/private_post_permalinks_controller.rb +11 -0
  14. data/app/controllers/thredded/private_topics_controller.rb +2 -1
  15. data/app/controllers/thredded/theme_previews_controller.rb +3 -2
  16. data/app/controllers/thredded/topics_controller.rb +14 -7
  17. data/app/forms/thredded/private_topic_form.rb +4 -2
  18. data/app/helpers/thredded/application_helper.rb +1 -1
  19. data/app/helpers/thredded/urls_helper.rb +5 -3
  20. data/app/mailer_previews/thredded/base_mailer_preview.rb +12 -6
  21. data/app/mailer_previews/thredded/post_mailer_preview.rb +2 -1
  22. data/app/mailer_previews/thredded/private_post_mailer_preview.rb +2 -1
  23. data/app/mailer_previews/thredded/private_topic_mailer_preview.rb +2 -1
  24. data/app/models/concerns/thredded/post_common.rb +6 -5
  25. data/app/models/thredded/messageboard.rb +18 -1
  26. data/app/models/thredded/messageboard_group.rb +11 -0
  27. data/app/models/thredded/null_user.rb +2 -6
  28. data/app/policies/thredded/messageboard_group_policy.rb +15 -0
  29. data/app/policies/thredded/messageboard_policy.rb +4 -0
  30. data/app/policies/thredded/post_policy.rb +5 -0
  31. data/app/policies/thredded/private_post_policy.rb +5 -0
  32. data/app/view_models/thredded/messageboard_group_view.rb +14 -0
  33. data/app/views/thredded/messageboard_groups/new.html.erb +20 -0
  34. data/app/views/thredded/messageboards/_form.html.erb +19 -0
  35. data/app/views/thredded/messageboards/edit.html.erb +11 -0
  36. data/app/views/thredded/messageboards/index.html.erb +14 -6
  37. data/app/views/thredded/messageboards/new.html.erb +3 -16
  38. data/app/views/thredded/post_mailer/at_notification.html.erb +1 -1
  39. data/app/views/thredded/post_mailer/at_notification.text.erb +1 -1
  40. data/app/views/thredded/posts_common/_form.html.erb +1 -1
  41. data/app/views/thredded/posts_common/form/_after_content.html.erb +0 -0
  42. data/app/views/thredded/posts_common/form/_before_content.html.erb +0 -0
  43. data/app/views/thredded/posts_common/form/_content_field.html.erb +6 -0
  44. data/app/views/thredded/private_post_mailer/at_notification.html.erb +1 -1
  45. data/app/views/thredded/private_topics/_form.html.erb +1 -1
  46. data/app/views/thredded/topics/_form.html.erb +1 -1
  47. data/app/views/thredded/topics/index.html.erb +8 -0
  48. data/app/views/thredded/users/_link.html.erb +1 -1
  49. data/config/locales/en.yml +11 -0
  50. data/config/locales/pt-BR.yml +15 -3
  51. data/config/routes.rb +12 -1
  52. data/db/migrate/20160329231848_create_thredded.rb +8 -0
  53. data/db/seeds.rb +10 -5
  54. data/db/upgrade_migrations/20160429222452_upgrade_v0_3_to_v0_4.rb +14 -0
  55. data/heroku.gemfile +1 -1
  56. data/heroku.gemfile.lock +43 -43
  57. data/lib/generators/thredded/install/USAGE +1 -6
  58. data/lib/generators/thredded/install/install_generator.rb +0 -5
  59. data/lib/thredded/engine.rb +8 -0
  60. data/lib/thredded/version.rb +1 -1
  61. data/thredded.gemspec +1 -1
  62. metadata +17 -6
  63. data/app/controllers/thredded/setups_controller.rb +0 -54
  64. data/app/views/thredded/posts/_content_field.html.erb +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a5b1a2f3452e32092928cdeaa8ccb705e9f2a7d8
4
- data.tar.gz: ff7a72e796b7dd7b20d0becc114ec3734ead905b
3
+ metadata.gz: 8023f4374b36ef9c88f7619b9768b5be2c4bca46
4
+ data.tar.gz: 9d18f2e394e2bbf3e4469735cd48ca5f0003bfd2
5
5
  SHA512:
6
- metadata.gz: 9d4db4b55939ec62cc509a46ba8fe1e67c1f919ed826637e2202adf52ed1da8b67d6b4e58943b3d4fff8cef6ed5f7420fdab39a1464cb8eebca5c316be2e79e6
7
- data.tar.gz: 6b6a9c0faa439d62c8bd53fdc7937efbd51261416e9506f0b67b1eeb659e79b706594f7c06438d447c18bdaa4780a711ed0ffd100a6ddd5941fc9604ea3c462a
6
+ metadata.gz: 8144322f3774be32136e270fdf52733062d53917882e2759a1b122280332904df9fd558085d17a4b565dea5a4f5c17dc8019a81b16b022cd471518a64b3880d1
7
+ data.tar.gz: 41d7acb3dfbe5a619cb6abb47ee313ab04e6697867ec2c09566f7a6fadf85c32547b99729c844d57a9b2248738e9d455edcaf38588693f1e9d77bb24631c1f46
data/CHANGELOG.mkdn CHANGED
@@ -1,6 +1,26 @@
1
- # MASTER
1
+ # 0.4.0 - 2016-05-21
2
2
 
3
- ## 0.3.2 - 2016-05-04
3
+ **NB:** If updating to this version from 0.3.x, you will need to copy and run [this migration](https://github.com/thredded/thredded/blob/559fc205b9ee405abfe3968b981254f01f928027/db/upgrade_migrations/20160429222452_upgrade_v0_3_to_v0_4.rb).
4
+
5
+ ## Fixed
6
+
7
+ * Results from messageboards that cannot be read by the user no longer appear in the search results. [77293c](https://github.com/thredded/thredded/commit/77293c88980ec97f178d9a47405fdf915cd36ccc)
8
+ * Word-wrap is no longer a hard one (wraps in the middle of a word), and now wraps in a more
9
+ acceptable spot - after words, at hyphens, etc.
10
+ * Mailers now use permalinks to posts that always redirect to the correct page number. [#301](https://github.com/thredded/thredded/pull/301)
11
+
12
+ ## Added
13
+
14
+ * Messageboard groups ([#261](https://github.com/thredded/thredded/issues/261)) and editing ([#303](https://github.com/thredded/thredded/pull/303)).
15
+ * Spoiler(s) tag for post contents [5c8102a](https://github.com/thredded/thredded/commit/5c8102) `[spoiler]vader is luke's father[spoiler]`
16
+ * Styled blockquote tags.
17
+ * Empty partials before and after post textareas (for customization and extensibility) [#293](https://github.com/thredded/thredded/pull/293)
18
+ * New topic form page now allows pre-filling the fields from URL parameters. [#297](https://github.com/thredded/thredded/issues/297)
19
+ * Date format fix for dates older than 1 week. [9d71ba](https://github.com/thredded/thredded/commit/9d71ba2f1ddeac761e084e872a4b0a84ab62e35c)
20
+
21
+ See the full list of changes here: https://github.com/thredded/thredded/compare/v0.3.2...v0.4.0.
22
+
23
+ # 0.3.2 - 2016-05-04
4
24
 
5
25
  * Main app routes are delegated correctly when using the standalone layout. [8a2ff56](https://github.com/thredded/thredded/commit/8a2ff56f73afe0d6e8e8ecede9666b8d65817fa3)
6
26
  * Posts now have `word-break: break-all` applied to prevent overly long string form breaking the layout. [#267](https://github.com/thredded/thredded/issues/267)
data/README.mkdn CHANGED
@@ -37,18 +37,17 @@ dependencies other than the database and, if configured in the parent applicatio
37
37
  backend dependency such as Redis. Currently only MRI Ruby 2.2+ is supported. We would love to
38
38
  support JRuby and Rubinius as well.
39
39
 
40
- If you're looking for variations on a theme - see [Forem] and [Discourse]. Forem is also an engine,
41
- while Discourse is a full app.
40
+ If you're looking for variations on a theme - see [Discourse]. However, It is a full rails
41
+ application and not an engine like Thredded.
42
42
 
43
43
  [Discourse]: http://www.discourse.org/
44
- [Forem]: https://github.com/rubysherpas/forem
45
44
 
46
45
  ## Installation
47
46
 
48
47
  Add the gem to your Gemfile:
49
48
 
50
49
  ```ruby
51
- gem 'thredded', '~> 0.3.2'
50
+ gem 'thredded', '~> 0.4.0'
52
51
  ```
53
52
 
54
53
  Add the Thredded [initializer] to your parent app by running the install generator.
@@ -89,10 +88,11 @@ DbTextSearch::CaseInsensitive.add_index(
89
88
 
90
89
  ### Migrating from Forem
91
90
 
92
- Using [Forem]? Thredded provides [a migration][forem-to-thredded] to copy all your existing forums from Forem over
91
+ Are you currently using [Forem]? Thredded provides [a migration][forem-to-thredded] to copy all of your existing data from Forem over
93
92
  to Thredded.
94
93
 
95
94
  [forem-to-thredded]: https://github.com/thredded/thredded/wiki/Migrate-from-Forem
95
+ [Forem]: https://github.com/rubysherpas/forem
96
96
 
97
97
  ## Views and other assets
98
98
 
@@ -147,6 +147,18 @@ mkdir -p app/views/thredded/posts && cp "$(bundle show thredded)/$_/_post.html.e
147
147
  customizations are still compatible with the new version of thredded. This is difficult and error-prone.
148
148
  Whenever possible, use the styles and i18n to customize Thredded to your needs.
149
149
 
150
+ #### Empty view partials included for customization
151
+
152
+ There are 2 empty view partials included in the gem that exist for the purpose of being overridden
153
+ in the parent app *if desired*. They are:
154
+
155
+ * `app/views/thredded/posts_common/form/_before_content.html.erb`
156
+ * `app/views/thredded/posts_common/form/_after_content.html.erb`
157
+
158
+ And are rendered directly before, and directly after the textarea where users type their post
159
+ contents. These exist in the case where a messageboard would like to add things like, wysiwyg/wymean
160
+ editors, buttons, help links, help copy, further customization for the textarea, etc.
161
+
150
162
  ## Theming
151
163
 
152
164
  The engine comes by default with a light and effective implementation of the
@@ -39,3 +39,12 @@
39
39
  fill: currentColor;
40
40
  }
41
41
 
42
+ %thredded--blockquote {
43
+ margin: 0 0 0.75rem;
44
+ border-left: solid 5px $thredded-blockquote-border-color;
45
+ padding: 1rem;
46
+
47
+ p:last-of-type {
48
+ margin-bottom: 0;
49
+ }
50
+ }
@@ -31,6 +31,9 @@ $thredded-nav-color: $thredded-text-color !default;
31
31
  $thredded-nav-hover-color: $thredded-action-color !default;
32
32
  $thredded-nav-current-color: $thredded-action-color !default;
33
33
  $thredded-secondary-nav-color: $thredded-secondary-text-color !default;
34
+ $thredded-spoiler-hidden-color: $thredded-light-gray !default;
35
+ $thredded-spoiler-shown-color: black !default;
36
+
34
37
 
35
38
  // Colors of alerts and flash messages
36
39
  $thredded-alert-danger-background: #fbe3e4 !default;
@@ -45,6 +48,7 @@ $thredded-alert-warning-color: #8a6d3b !default;
45
48
  // Borders
46
49
  $thredded-base-border-color: $thredded-light-gray !default;
47
50
  $thredded-base-border: 1px solid $thredded-base-border-color !default;
51
+ $thredded-blockquote-border-color: $thredded-light-gray !default;
48
52
 
49
53
  // Form inputs
50
54
  $thredded-form-background: $thredded-background-color !default;
@@ -50,6 +50,18 @@
50
50
  margin-bottom: 0;
51
51
  }
52
52
 
53
- &--messageboard--create {
53
+ &--messageboards--actions {
54
54
  text-align: center;
55
+ a {
56
+ display: block;
57
+ margin-top: $thredded-small-spacing;
58
+ }
59
+ @include thredded-media-tablet-and-up {
60
+ a {
61
+ display: inline-block;
62
+ }
63
+ a + a {
64
+ margin-left: $thredded-small-spacing;
65
+ }
66
+ }
55
67
  }
@@ -57,7 +57,7 @@
57
57
  &--post--content {
58
58
  font-size: 1.063rem; // 17px
59
59
  line-height: 1.65;
60
- word-break: break-all;
60
+ word-break: break-word;
61
61
  a {
62
62
  @extend %thredded--link;
63
63
  }
@@ -74,4 +74,18 @@
74
74
  table {
75
75
  @extend %thredded--table;
76
76
  }
77
+ blockquote {
78
+ @extend %thredded--blockquote;
79
+ }
80
+
81
+ &--spoiler {
82
+ color: $thredded-spoiler-hidden-color;
83
+ background-color: $thredded-spoiler-hidden-color;
84
+ cursor: pointer;
85
+
86
+ &:hover,
87
+ &:focus {
88
+ color: $thredded-spoiler-shown-color;
89
+ }
90
+ }
77
91
  }
@@ -23,7 +23,7 @@
23
23
  border-color: transparent;
24
24
  font-size: $thredded-font-size-small;
25
25
  line-height: 1rem;
26
- min-width: 12.8125rem;
26
+ min-width: 13rem;
27
27
  text-align: right;
28
28
  width: auto;
29
29
  padding: 0.90625rem $padding-x 0.8125rem $padding-x;
@@ -95,7 +95,7 @@ module Thredded
95
95
  end
96
96
 
97
97
  def update_user_activity
98
- return if messageboard.nil?
98
+ return if messageboard.nil? || !signed_in?
99
99
 
100
100
  Thredded::ActivityUpdaterJob.perform_later(
101
101
  thredded_current_user.id,
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thredded
4
+ class MessageboardGroupsController < Thredded::ApplicationController
5
+ def new
6
+ @messageboard_group = MessageboardGroup.new
7
+ authorize @messageboard_group, :create?
8
+ end
9
+
10
+ def create
11
+ @messageboard_group = MessageboardGroup.new(messageboard_group_params)
12
+ authorize @messageboard_group, :create?
13
+
14
+ if @messageboard_group.save
15
+ redirect_to root_path
16
+ else
17
+ render action: :new
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def messageboard_group_params
24
+ params
25
+ .require(:messageboard_group)
26
+ .permit(:name)
27
+ end
28
+ end
29
+ end
@@ -1,42 +1,56 @@
1
1
  # frozen_string_literal: true
2
2
  module Thredded
3
3
  class MessageboardsController < Thredded::ApplicationController
4
+ before_action :thredded_require_login!, only: [:new, :create, :edit, :update]
5
+
4
6
  def index
5
- @messageboards = thredded_current_user.thredded_can_read_messageboards
7
+ @groups = thredded_current_user
8
+ .thredded_can_read_messageboards
9
+ .preload(:group).group_by(&:group)
10
+ .map { |(group, messageboards)| MessageboardGroupView.new(group, messageboards) }
6
11
  end
7
12
 
8
13
  def new
9
14
  @messageboard = Messageboard.new
15
+ @messageboard_group = MessageboardGroup.all
10
16
  authorize_creating @messageboard
11
17
  end
12
18
 
13
19
  def create
14
20
  @messageboard = Messageboard.new(messageboard_params)
15
21
  authorize_creating @messageboard
16
-
17
- if signed_in? && @messageboard.save
22
+ if @messageboard.save
18
23
  Topic.transaction do
19
24
  @topic = Topic.create!(topic_params)
20
25
  @post = Post.create!(post_params)
21
26
  end
22
-
23
27
  redirect_to root_path
24
28
  else
25
- show_sign_in_error unless signed_in?
26
- render action: :new
29
+ render :new
27
30
  end
28
31
  end
29
32
 
30
- private
33
+ def edit
34
+ @messageboard = Messageboard.friendly.find(params[:id])
35
+ authorize @messageboard, :update?
36
+ end
31
37
 
32
- def show_sign_in_error
33
- flash.now[:error] = 'You are not signed in. Sign in or create an account before creating your messageboard.'
38
+ def update
39
+ @messageboard = Messageboard.friendly.find(params[:id])
40
+ authorize @messageboard, :update?
41
+ if @messageboard.update(messageboard_params)
42
+ redirect_to messageboard_topics_path(@messageboard), notice: I18n.t('thredded.messageboard.updated_notice')
43
+ else
44
+ render :new
45
+ end
34
46
  end
35
47
 
48
+ private
49
+
36
50
  def messageboard_params
37
51
  params
38
52
  .require(:messageboard)
39
- .permit(:description, :name, :posting_permission, :security)
53
+ .permit(:name, :description, :messageboard_group_id)
40
54
  end
41
55
 
42
56
  def topic_params
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ module Thredded
3
+ class PostPermalinksController < ApplicationController
4
+ def show
5
+ post = Post.find(params[:id])
6
+ authorize post, :read?
7
+ redirect_to post_url(post), status: :found
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+ module Thredded
3
+ class PrivatePostPermalinksController < ApplicationController
4
+ before_action :thredded_require_login!
5
+ def show
6
+ private_post = PrivatePost.find(params[:id])
7
+ authorize private_post, :read?
8
+ redirect_to post_url(private_post), status: :found
9
+ end
10
+ end
11
+ end
@@ -13,7 +13,8 @@ module Thredded
13
13
  .for_user(thredded_current_user)
14
14
  .order_recently_updated_first
15
15
  .includes(:last_user, :user)
16
- .page(params[:page]))
16
+ .page(params[:page])
17
+ )
17
18
 
18
19
  PrivateTopicForm.new(user: thredded_current_user).tap do |form|
19
20
  @new_private_topic = form if policy(form.private_topic).create?
@@ -23,8 +23,9 @@ module Thredded
23
23
  @private_topic = PrivateTopicView.from_user(private_topic, @user)
24
24
  @private_posts = PostsPageView.new(@user, private_topic, private_topic.posts.page(1).limit(3))
25
25
  @private_post = private_topic.posts.build(
26
- id: 1337, postable: private_topic, content: 'A private hello world', user: @user)
27
- @preferences = UserPreferencesForm.new(user: @user, messageboard: @messageboard)
26
+ id: 1337, postable: private_topic, content: 'A private hello world', user: @user
27
+ )
28
+ @preferences = UserPreferencesForm.new(user: @user, messageboard: @messageboard)
28
29
  end
29
30
  end
30
31
  end
@@ -15,7 +15,8 @@ module Thredded
15
15
  messageboard.topics
16
16
  .order_sticky_first.order_recently_updated_first
17
17
  .includes(:categories, :last_user, :user)
18
- .page(current_page))
18
+ .page(current_page)
19
+ )
19
20
  TopicForm.new(messageboard: messageboard, user: thredded_current_user).tap do |form|
20
21
  @new_topic = form if policy(form.topic).create?
21
22
  end
@@ -36,17 +37,23 @@ module Thredded
36
37
 
37
38
  def search
38
39
  @query = params[:q].to_s
40
+ topics_scope = if messageboard_or_nil
41
+ messageboard.topics
42
+ else
43
+ Topic.where(messageboard_id: thredded_current_user.thredded_can_read_messageboards.pluck(:id))
44
+ end
39
45
  @topics = Thredded::TopicsPageView.new(
40
46
  thredded_current_user,
41
- (messageboard_or_nil ? messageboard.topics : Topic)
47
+ topics_scope
42
48
  .search_query(@query)
43
49
  .order_recently_updated_first
44
50
  .includes(:categories, :last_user, :user)
45
- .page(current_page))
51
+ .page(current_page)
52
+ )
46
53
  end
47
54
 
48
55
  def new
49
- @new_topic = TopicForm.new(messageboard: messageboard, user: thredded_current_user)
56
+ @new_topic = TopicForm.new(new_topic_params)
50
57
  authorize_creating @new_topic.topic
51
58
  end
52
59
 
@@ -58,7 +65,8 @@ module Thredded
58
65
  @category.topics
59
66
  .unstuck
60
67
  .order_recently_updated_first
61
- .page(current_page))
68
+ .page(current_page)
69
+ )
62
70
  render :index
63
71
  end
64
72
 
@@ -103,12 +111,11 @@ module Thredded
103
111
  params
104
112
  .require(:topic)
105
113
  .permit(:title, :locked, :sticky, category_ids: [])
106
- .merge(user: thredded_current_user)
107
114
  end
108
115
 
109
116
  def new_topic_params
110
117
  params
111
- .require(:topic)
118
+ .fetch(:topic, {})
112
119
  .permit(:title, :locked, :sticky, :content, category_ids: [])
113
120
  .merge(
114
121
  messageboard: messageboard,
@@ -49,13 +49,15 @@ module Thredded
49
49
  title: title,
50
50
  users: private_users,
51
51
  user: non_null_user,
52
- last_user: non_null_user)
52
+ last_user: non_null_user
53
+ )
53
54
  end
54
55
 
55
56
  def post
56
57
  @post ||= private_topic.posts.build(
57
58
  content: content,
58
- user: non_null_user)
59
+ user: non_null_user
60
+ )
59
61
  end
60
62
 
61
63
  private
@@ -20,7 +20,7 @@ module Thredded
20
20
  # @param datetime [DateTime]
21
21
  # @return [String] html_safe datetime presentation
22
22
  def time_ago(datetime)
23
- timeago_tag datetime, lang: I18n.locale.to_s.downcase, date_only: false, nojs: true
23
+ timeago_tag datetime, lang: I18n.locale.to_s.downcase, format: :short, nojs: true
24
24
  end
25
25
 
26
26
  def paginate(collection, args = {})
@@ -22,12 +22,14 @@ module Thredded
22
22
  if topic.private?
23
23
  private_topic_url(
24
24
  topic.slug,
25
- params)
25
+ params
26
+ )
26
27
  else
27
28
  messageboard_topic_url(
28
29
  topic.messageboard.slug,
29
30
  topic.slug,
30
- params)
31
+ params
32
+ )
31
33
  end
32
34
  end
33
35
 
@@ -41,7 +43,7 @@ module Thredded
41
43
  # @return [String] URL of the topic page with the post anchor.
42
44
  def post_url(post, params = {})
43
45
  params = params.dup
44
- params[:anchor] ||= dom_id(post)
46
+ params[:anchor] ||= ActionView::RecordIdentifier.dom_id(post)
45
47
  params[:page] ||= post.page
46
48
  topic_url(post.postable, params)
47
49
  end
@@ -30,7 +30,8 @@ MARKDOWN
30
30
  sticky: [false, true].sample,
31
31
  updated_at: Time.zone.now,
32
32
  user: mock_user,
33
- ))
33
+ )
34
+ )
34
35
  end
35
36
 
36
37
  def mock_post(attr = {})
@@ -44,7 +45,8 @@ MARKDOWN
44
45
  postable: topic,
45
46
  updated_at: Time.zone.now,
46
47
  user: topic.last_user,
47
- ))
48
+ )
49
+ )
48
50
  end
49
51
 
50
52
  def mock_private_topic(attr = {})
@@ -58,7 +60,8 @@ MARKDOWN
58
60
  posts_count: 1 + rand(42),
59
61
  updated_at: Time.zone.now,
60
62
  user: mock_user,
61
- ))
63
+ )
64
+ )
62
65
  end
63
66
 
64
67
  def mock_private_post(attr = {})
@@ -71,7 +74,8 @@ MARKDOWN
71
74
  postable: private_topic,
72
75
  updated_at: Time.zone.now,
73
76
  user: private_topic.last_user,
74
- ))
77
+ )
78
+ )
75
79
  end
76
80
 
77
81
  def mock_messageboard(attr = {})
@@ -86,7 +90,8 @@ MARKDOWN
86
90
  posts_count: rand(1337),
87
91
  topics_count: rand(42),
88
92
  updated_at: Time.zone.now,
89
- ))
93
+ )
94
+ )
90
95
  end
91
96
 
92
97
  def mock_user(attr = {})
@@ -95,7 +100,8 @@ MARKDOWN
95
100
  attr.reverse_merge(
96
101
  Thredded.user_name_column => name,
97
102
  email: "#{name.downcase}@test.com",
98
- ))
103
+ )
104
+ )
99
105
  end
100
106
  end
101
107
  end
@@ -5,7 +5,8 @@ module Thredded
5
5
  def at_notification
6
6
  PostMailer.at_notification(
7
7
  mock_post(content: mock_content(mention_users: %w(glebm joel))),
8
- %w(glebm@test.com joel@test.com))
8
+ %w(glebm@test.com joel@test.com)
9
+ )
9
10
  end
10
11
  end
11
12
  end
@@ -5,7 +5,8 @@ module Thredded
5
5
  def at_notification
6
6
  PrivatePostMailer.at_notification(
7
7
  mock_private_post(content: mock_content(mention_users: %w(glebm joel))),
8
- %w(glebm@test.com joel@test.com))
8
+ %w(glebm@test.com joel@test.com)
9
+ )
9
10
  end
10
11
  end
11
12
  end
@@ -9,7 +9,8 @@ module Thredded
9
9
  mock_private_post(content: mock_content(mention_users: ['glebm']), postable: private_topic)
10
10
  ]
11
11
  end,
12
- %w(glebm@test.com joel@test.com))
12
+ %w(glebm@test.com joel@test.com)
13
+ )
13
14
  end
14
15
  end
15
16
  end
@@ -17,21 +17,22 @@ module Thredded
17
17
  end
18
18
  ].freeze
19
19
 
20
- WHITELIST_ELEMENTS = HTML::Pipeline::SanitizationFilter::WHITELIST[:elements] + [
21
- 'iframe',
22
- ].freeze
20
+ WHITELIST_ELEMENTS = HTML::Pipeline::SanitizationFilter::WHITELIST[:elements] + %w(
21
+ iframe span
22
+ ).freeze
23
23
 
24
24
  WHITELIST = HTML::Pipeline::SanitizationFilter::WHITELIST.deep_merge(
25
25
  elements: WHITELIST_ELEMENTS,
26
26
  transformers: WHITELIST_TRANSFORMERS,
27
27
  attributes: {
28
28
  'a' => %w(href rel),
29
- 'iframe' => %w(src width height frameborder allowfullscreen sandbox seamless)
29
+ 'iframe' => %w(src width height frameborder allowfullscreen sandbox seamless),
30
+ 'span' => %w(class),
30
31
  },
31
32
  add_attributes: {
32
33
  'iframe' => {
33
34
  'seamless' => 'seamless',
34
- 'sandbox' => 'allow-forms allow-scripts'
35
+ 'sandbox' => 'allow-forms allow-scripts',
35
36
  }
36
37
  }
37
38
  ).freeze
@@ -6,7 +6,16 @@ module Thredded
6
6
  use: [:slugged, :reserved],
7
7
  # Avoid route conflicts
8
8
  reserved_words: ::Thredded::FriendlyIdReservedWordsAndPagination.new(
9
- %w(messageboards preferences private-topics autocomplete-users theme-preview)
9
+ %w(
10
+ admin
11
+ autocomplete-users
12
+ messageboards
13
+ posts
14
+ preferences
15
+ private-posts
16
+ private-topics
17
+ theme-preview
18
+ )
10
19
  )
11
20
 
12
21
  validates :name, uniqueness: true, length: { maximum: 60 }, presence: true
@@ -33,8 +42,16 @@ module Thredded
33
42
  through: :recently_active_user_details,
34
43
  source: :user
35
44
 
45
+ belongs_to :group,
46
+ inverse_of: :messageboards,
47
+ foreign_key: :messageboard_group_id,
48
+ class_name: 'Thredded::MessageboardGroup'
49
+
36
50
  default_scope { where(closed: false).order(topics_count: :desc) }
37
51
 
52
+ scope :top_level_messageboards, -> { where(group: nil) }
53
+ scope :by_messageboard_group, ->(group) { where(group: group.id) }
54
+
38
55
  def latest_user
39
56
  latest_topic.last_user
40
57
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+ module Thredded
3
+ class MessageboardGroup < ActiveRecord::Base
4
+ has_many :messageboards,
5
+ inverse_of: :group,
6
+ foreign_key: :messageboard_group_id,
7
+ dependent: :nullify
8
+
9
+ validates :name, presence: true
10
+ end
11
+ end
@@ -12,15 +12,11 @@ module Thredded
12
12
  end
13
13
 
14
14
  def id
15
- 0
16
- end
17
-
18
- def member_of?(_)
19
- false
15
+ nil
20
16
  end
21
17
 
22
18
  def name
23
- 'Anonymous User'
19
+ I18n.t('thredded.null_user_name')
24
20
  end
25
21
 
26
22
  def to_s
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ module Thredded
3
+ class MessageboardGroupPolicy
4
+ # @param user [Thredded.user_class]
5
+ # @param messageboard_group [Thredded::MessageboardGroup]
6
+ def initialize(user, group)
7
+ @user = user
8
+ @group = group
9
+ end
10
+
11
+ def create?
12
+ @user.thredded_admin?
13
+ end
14
+ end
15
+ end