thredded 0.7.0 → 0.8.2

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 (98) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +119 -17
  3. data/app/assets/javascripts/thredded/components/currently_online.es6 +3 -3
  4. data/app/assets/javascripts/thredded/components/flash_messages.es6 +11 -0
  5. data/app/assets/javascripts/thredded/components/post_form.es6 +21 -4
  6. data/app/assets/javascripts/thredded/components/time_stamps.es6 +8 -6
  7. data/app/assets/javascripts/thredded/components/topic_form.es6 +14 -3
  8. data/app/assets/javascripts/thredded/components/topics.es6 +3 -3
  9. data/app/assets/javascripts/thredded/components/turboforms.es6 +15 -0
  10. data/app/assets/javascripts/thredded/components/user_preferences_form.es6 +47 -20
  11. data/app/assets/javascripts/thredded/components/users_select.es6 +25 -9
  12. data/app/assets/javascripts/thredded/core/hide_soft_keyboard.es6 +6 -0
  13. data/app/assets/javascripts/thredded/core/mention_autocompletion.es6 +54 -0
  14. data/app/assets/javascripts/thredded/core/on_page_load.es6 +46 -0
  15. data/app/assets/javascripts/thredded/dependencies.js +2 -1
  16. data/app/assets/javascripts/thredded/dependencies/jquery.js +1 -0
  17. data/app/assets/javascripts/thredded/thredded.es6 +1 -0
  18. data/app/assets/stylesheets/thredded/_thredded.scss +1 -0
  19. data/app/assets/stylesheets/thredded/base/_alerts.scss +5 -1
  20. data/app/assets/stylesheets/thredded/base/_grid.scss +8 -0
  21. data/app/assets/stylesheets/thredded/base/_nav.scss +0 -5
  22. data/app/assets/stylesheets/thredded/components/_following.scss +0 -3
  23. data/app/assets/stylesheets/thredded/components/_mention-autocomplete.scss +35 -0
  24. data/app/assets/stylesheets/thredded/components/_topic-header.scss +37 -17
  25. data/app/assets/stylesheets/thredded/components/_topics.scss +13 -0
  26. data/app/assets/stylesheets/thredded/layout/_main-navigation.scss +57 -14
  27. data/app/assets/stylesheets/thredded/layout/_moderation.scss +5 -0
  28. data/app/assets/stylesheets/thredded/layout/_navigation.scss +14 -17
  29. data/app/assets/stylesheets/thredded/layout/_search-navigation.scss +15 -3
  30. data/app/assets/stylesheets/thredded/layout/_user-navigation.scss +3 -11
  31. data/app/commands/thredded/at_notification_extractor.rb +2 -2
  32. data/app/commands/thredded/autofollow_mentioned_users.rb +2 -2
  33. data/app/commands/thredded/create_messageboard.rb +45 -0
  34. data/app/commands/thredded/notify_following_users.rb +10 -0
  35. data/app/controllers/thredded/autocomplete_users_controller.rb +2 -3
  36. data/app/controllers/thredded/messageboards_controller.rb +1 -24
  37. data/app/controllers/thredded/moderation_controller.rb +1 -1
  38. data/app/controllers/thredded/post_permalinks_controller.rb +1 -1
  39. data/app/controllers/thredded/preferences_controller.rb +4 -2
  40. data/app/controllers/thredded/private_post_permalinks_controller.rb +1 -1
  41. data/app/controllers/thredded/theme_previews_controller.rb +1 -1
  42. data/app/controllers/thredded/topics_controller.rb +0 -1
  43. data/app/forms/thredded/user_preferences_form.rb +4 -2
  44. data/app/helpers/thredded/application_helper.rb +5 -0
  45. data/app/helpers/thredded/nav_helper.rb +41 -0
  46. data/app/mailer_previews/thredded/base_mailer_preview.rb +0 -1
  47. data/app/mailers/thredded/post_mailer.rb +0 -1
  48. data/app/mailers/thredded/private_topic_mailer.rb +0 -1
  49. data/app/models/concerns/thredded/user_topic_read_state_common.rb +2 -2
  50. data/app/models/thredded/messageboard.rb +0 -1
  51. data/app/models/thredded/null_preference.rb +5 -1
  52. data/app/models/thredded/private_post.rb +2 -2
  53. data/app/policies/thredded/messageboard_group_policy.rb +1 -1
  54. data/app/view_hooks/thredded/all_view_hooks.rb +68 -0
  55. data/app/view_models/thredded/post_view.rb +3 -3
  56. data/app/view_models/thredded/topic_email_view.rb +0 -4
  57. data/app/view_models/thredded/topics_page_view.rb +12 -1
  58. data/app/views/layouts/thredded/application.html.erb +5 -2
  59. data/app/views/thredded/messageboard_groups/new.html.erb +3 -1
  60. data/app/views/thredded/messageboards/edit.html.erb +3 -1
  61. data/app/views/thredded/messageboards/new.html.erb +3 -1
  62. data/app/views/thredded/moderation/_users_search_form.html.erb +4 -1
  63. data/app/views/thredded/moderation/user.html.erb +34 -28
  64. data/app/views/thredded/posts_common/_form.html.erb +6 -1
  65. data/app/views/thredded/posts_common/form/_content_field.html.erb +5 -3
  66. data/app/views/thredded/preferences/_form.html.erb +30 -12
  67. data/app/views/thredded/private_topics/_form.html.erb +4 -3
  68. data/app/views/thredded/private_topics/index.html.erb +5 -5
  69. data/app/views/thredded/search/_form.html.erb +2 -1
  70. data/app/views/thredded/shared/_flash_messages.html.erb +1 -1
  71. data/app/views/thredded/shared/_page.html.erb +10 -1
  72. data/app/views/thredded/shared/nav/_moderation.html.erb +3 -2
  73. data/app/views/thredded/shared/nav/_notification_preferences.html.erb +5 -3
  74. data/app/views/thredded/shared/nav/_private_topics.html.erb +3 -2
  75. data/app/views/thredded/topics/_form.html.erb +6 -1
  76. data/app/views/thredded/topics/_header.html.erb +8 -5
  77. data/config/locales/en.yml +15 -7
  78. data/config/locales/pt-BR.yml +21 -13
  79. data/config/routes.rb +4 -2
  80. data/db/migrate/20160329231848_create_thredded.rb +5 -5
  81. data/db/upgrade_migrations/20161019150201_upgrade_v0_7_to_v0_8.rb +31 -0
  82. data/lib/generators/thredded/install/templates/initializer.rb +20 -8
  83. data/lib/tasks/thredded_tasks.rake +0 -7
  84. data/lib/thredded.rb +19 -5
  85. data/lib/thredded/content_formatter.rb +43 -8
  86. data/lib/thredded/database_seeder.rb +7 -1
  87. data/lib/thredded/engine.rb +2 -21
  88. data/lib/{html/pipeline → thredded/html_pipeline}/at_mention_filter.rb +4 -4
  89. data/lib/thredded/html_pipeline/autolink_filter.rb +14 -0
  90. data/lib/thredded/html_pipeline/kramdown_filter.rb +34 -0
  91. data/lib/thredded/version.rb +1 -1
  92. data/lib/thredded/view_hooks/config.rb +36 -0
  93. data/lib/thredded/view_hooks/renderer.rb +29 -0
  94. data/vendor/assets/javascripts/jquery.textcomplete.js +1488 -0
  95. metadata +65 -52
  96. data/app/commands/thredded/messageboard_destroyer.rb +0 -65
  97. data/lib/html/pipeline/bbcode_filter.rb +0 -33
  98. data/lib/thredded/main_app_route_delegator.rb +0 -25
@@ -1,7 +1,12 @@
1
1
  .thredded--moderation-navigation {
2
2
  position: relative;
3
+ @include thredded-media-desktop-and-up {
4
+ margin-bottom: $thredded-base-spacing;
5
+ }
6
+
3
7
  &--items {
4
8
  @extend %thredded--nav-tabs;
9
+ margin-bottom: $thredded-small-spacing;
5
10
  }
6
11
  &--item {
7
12
  @extend %thredded--nav-tabs--item;
@@ -1,5 +1,4 @@
1
1
  .thredded--navigation {
2
- margin-bottom: $thredded-small-spacing;
3
2
  position: relative;
4
3
  .thredded--icon {
5
4
  display: none;
@@ -9,7 +8,6 @@
9
8
  @include thredded-media-tablet-and-down {
10
9
  $icon-nav-item-width: 2.625rem;
11
10
  .thredded--navigation {
12
- display: table;
13
11
  position: relative;
14
12
  width: 100%;
15
13
  }
@@ -33,20 +31,25 @@
33
31
  }
34
32
  }
35
33
  .thredded--user-navigation {
36
- display: table-footer-group;
34
+ border-bottom: none;
35
+ position: absolute;
36
+ top: 0;
37
+ right: 0;
38
+ z-index: 2;
37
39
  &-standalone {
38
40
  display: block;
39
41
  margin-bottom: 0;
40
42
  }
41
43
  %icon-nav-item {
42
- margin-right: 0;
44
+ box-sizing: border-box;
45
+ display: inline-block;
46
+ margin: 0 0 0 ($thredded-small-spacing/2);
43
47
  padding: 0;
44
- position: absolute;
45
- top: (0.8rem - $thredded-small-spacing);
46
- z-index: 2;
48
+ vertical-align: top;
47
49
  a {
50
+ position: relative;
48
51
  display: block;
49
- padding: ($thredded-small-spacing / 2) 0 ($thredded-small-spacing / 2) 0;
52
+ padding: 0.4375rem 0 0.375rem 0;
50
53
  }
51
54
  .thredded--icon {
52
55
  display: block;
@@ -55,31 +58,25 @@
55
58
  }
56
59
  }
57
60
  %icon-counter {
58
- bottom: 0.3rem;
61
+ bottom: 0.3125rem;
59
62
  position: absolute;
60
- right: -0.2rem;
63
+ right: -0.1875rem;
61
64
  }
62
65
  .thredded--nav-text {
63
66
  display: none;
64
67
  }
65
68
  &--settings {
66
69
  @extend %icon-nav-item;
67
- right: $icon-nav-item-width;
68
70
  }
69
71
  &--private-topics {
70
72
  @extend %icon-nav-item;
71
- right: 0;
72
- top: 1px;
73
- a {
74
- position: relative;
75
- }
73
+ margin-top: 1px;
76
74
  &--unread {
77
75
  @extend %icon-counter;
78
76
  }
79
77
  }
80
78
  &--moderation {
81
79
  @extend %icon-nav-item;
82
- right: $icon-nav-item-width * 2;
83
80
  &--pending-count {
84
81
  @extend %icon-counter
85
82
  }
@@ -7,6 +7,7 @@
7
7
 
8
8
  @include thredded-media-tablet-and-down {
9
9
  position: initial;
10
+ margin-bottom: $thredded-small-spacing;
10
11
  }
11
12
 
12
13
  label {
@@ -18,16 +19,17 @@
18
19
  width: 100%;
19
20
 
20
21
  @include thredded-media-desktop-and-up {
22
+ $line-height: 1rem;
21
23
  $padding-x: 0.75rem;
22
24
  background: transparent;
23
25
  border-color: transparent;
24
26
  font-size: $thredded-font-size-small;
25
- line-height: 1rem;
27
+ line-height: $line-height;
26
28
  min-width: 13rem;
27
29
  text-align: right;
28
30
  width: auto;
29
- padding: 0.90625rem $padding-x 0.8125rem $padding-x;
30
- margin-right: -($padding-x);
31
+ padding: 0.9375rem 0.75rem 0.875rem 0.75rem;
32
+ margin: -1px (-$padding-x) 0 0;
31
33
  // Webkit adds an extra padding that we need to remove.
32
34
  -webkit-margin-end: -($padding-x + 0.75rem);
33
35
 
@@ -49,9 +51,19 @@
49
51
  box-shadow: none;
50
52
  }
51
53
 
54
+ &::-webkit-search-decoration,
55
+ &::-webkit-search-cancel-button,
56
+ &::-webkit-search-results-button,
57
+ &::-webkit-search-results-decoration {
58
+ // Remove excessive padding on Safari.
59
+ max-height: $line-height;
60
+ }
61
+
52
62
  &::placeholder {
53
63
  color: $thredded-secondary-nav-color;
54
64
  transition: $thredded-action-transition;
65
+ height: inherit;
66
+ line-height: inherit;
55
67
  // Firefox applies default opacity of 0.54, while all the other browsers use 1.
56
68
  // See https://bugzilla.mozilla.org/show_bug.cgi?id=556145
57
69
  opacity: 1;
@@ -4,18 +4,10 @@
4
4
 
5
5
  .thredded--user-navigation--item {
6
6
  @extend %thredded--nav-tabs--item;
7
- }
8
7
 
9
- .thredded--preferences .thredded--user-navigation--settings,
10
- .thredded--new-private-topic .thredded--user-navigation--private-topics,
11
- .thredded--private-topics-index .thredded--user-navigation--private-topics,
12
- .thredded--private-topic-show .thredded--user-navigation--private-topics,
13
- .thredded--pending-moderation .thredded--user-navigation--moderation,
14
- .thredded--moderation-history .thredded--user-navigation--moderation,
15
- .thredded--moderation-users .thredded--user-navigation--moderation,
16
- .thredded--moderation-user .thredded--user-navigation--moderation,
17
- .thredded--moderation-activity .thredded--user-navigation--moderation {
18
- @extend %thredded--nav-tabs--item-current;
8
+ &.thredded--is-current {
9
+ @extend %thredded--nav-tabs--item-current;
10
+ }
19
11
  }
20
12
 
21
13
  .thredded--user-navigation--private-topics--unread,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- require_dependency 'html/pipeline/at_mention_filter'
2
+ require 'thredded/html_pipeline/at_mention_filter'
3
3
  module Thredded
4
4
  class AtNotificationExtractor
5
5
  def initialize(post)
@@ -13,7 +13,7 @@ module Thredded
13
13
  # * When parsing, @-mentions within <a> tags will not be considered.
14
14
  # * We can't always generate the user URL here because request.host is not available.
15
15
  html = @post.filtered_content(view_context, users_provider: nil)
16
- HTML::Pipeline::AtMentionFilter.new(
16
+ Thredded::HtmlPipeline::AtMentionFilter.new(
17
17
  html,
18
18
  view_context: view_context,
19
19
  users_provider: -> (user_names) { @post.readers_from_user_names(user_names).to_a }
@@ -24,8 +24,8 @@ module Thredded
24
24
 
25
25
  def exclude_those_opting_out_of_at_notifications(members)
26
26
  members.select do |member|
27
- member.thredded_user_preference.notify_on_mention? &&
28
- member.thredded_user_messageboard_preferences.in(post.messageboard).notify_on_mention?
27
+ member.thredded_user_preference.follow_topics_on_mention? &&
28
+ member.thredded_user_messageboard_preferences.in(post.messageboard).follow_topics_on_mention?
29
29
  end
30
30
  end
31
31
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+ module Thredded
3
+ # Creates a new messageboard and seeds it with a topic.
4
+ class CreateMessageboard
5
+ # @param messageboard [Thredded::Messageboard]
6
+ # @param user [Thredded.user_class]
7
+ def initialize(messageboard, user)
8
+ @messageboard = messageboard
9
+ @user = user
10
+ end
11
+
12
+ # @return [boolean] true if the messageboard was created and seeded with a topic successfully.
13
+ def run
14
+ Messageboard.transaction do
15
+ fail ActiveRecord::Rollback unless @messageboard.save
16
+ topic = Topic.create!(
17
+ messageboard: @messageboard,
18
+ user: @user,
19
+ title: first_topic_title
20
+ )
21
+ Post.create!(
22
+ messageboard: @messageboard,
23
+ user: @user,
24
+ postable: topic,
25
+ content: first_post_content
26
+ )
27
+ true
28
+ end
29
+ end
30
+
31
+ def first_topic_title
32
+ "Welcome to your messageboard's very first thread"
33
+ end
34
+
35
+ def first_post_content
36
+ <<-MARKDOWN
37
+ There's not a whole lot here for now.
38
+
39
+ These forums are powered by [Thredded](https://github.com/thredded/thredded) v#{Thredded::VERSION}.
40
+ You can contact the Thredded team via the [Thredded chat room](https://gitter.im/thredded/thredded).
41
+ Please let us know that you are using Thredded by tweeting [@thredded](https://twitter.com/thredded)!
42
+ MARKDOWN
43
+ end
44
+ end
45
+ end
@@ -13,6 +13,16 @@ module Thredded
13
13
 
14
14
  def targeted_users
15
15
  @targeted_users ||= @post.postable.followers.reject { |u| u == @post.user }
16
+ exclude_those_opting_out_of_followed_activity_notifications @targeted_users
17
+ end
18
+
19
+ private
20
+
21
+ def exclude_those_opting_out_of_followed_activity_notifications(members)
22
+ members.select do |member|
23
+ member.thredded_user_preference.followed_topic_emails &&
24
+ member.thredded_user_messageboard_preferences.in(@post.messageboard).followed_topic_emails
25
+ end
16
26
  end
17
27
  end
18
28
  end
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  module Thredded
3
3
  class AutocompleteUsersController < Thredded::ApplicationController
4
- MIN_QUERY_LENGTH = 2
5
- MAX_RESULTS = 20
4
+ MAX_RESULTS = 20
6
5
 
7
6
  def index
8
7
  authorize_creating PrivateTopicForm.new(user: thredded_current_user).private_topic
@@ -20,7 +19,7 @@ module Thredded
20
19
 
21
20
  def users_by_prefix
22
21
  query = params[:q].to_s.strip
23
- if query.length >= MIN_QUERY_LENGTH
22
+ if query.length >= Thredded.autocomplete_min_length
24
23
  DbTextSearch::CaseInsensitive.new(users_scope, Thredded.user_name_column).prefix(query)
25
24
  .where.not(id: thredded_current_user.id)
26
25
  .limit(MAX_RESULTS)
@@ -19,11 +19,7 @@ module Thredded
19
19
  def create
20
20
  @messageboard = Messageboard.new(messageboard_params)
21
21
  authorize_creating @messageboard
22
- if @messageboard.save
23
- Topic.transaction do
24
- @topic = Topic.create!(topic_params)
25
- @post = Post.create!(post_params)
26
- end
22
+ if Thredded::CreateMessageboard.new(@messageboard, thredded_current_user).run
27
23
  redirect_to root_path
28
24
  else
29
25
  render :new
@@ -52,24 +48,5 @@ module Thredded
52
48
  .require(:messageboard)
53
49
  .permit(:name, :description, :messageboard_group_id)
54
50
  end
55
-
56
- def topic_params
57
- {
58
- messageboard: @messageboard,
59
- user: thredded_current_user,
60
- last_user: thredded_current_user,
61
- title: "Welcome to your messageboard's very first thread",
62
- }
63
- end
64
-
65
- def post_params
66
- {
67
- messageboard: @messageboard,
68
- postable: @topic,
69
- content: "There's not a whole lot here for now.",
70
- ip: request.ip,
71
- user: thredded_current_user,
72
- }
73
- end
74
51
  end
75
52
  end
@@ -2,7 +2,7 @@
2
2
  require_dependency 'thredded/moderate_post'
3
3
  require_dependency 'thredded/posts_page_view'
4
4
  module Thredded
5
- class ModerationController < ApplicationController
5
+ class ModerationController < Thredded::ApplicationController
6
6
  before_action :thredded_require_login!
7
7
  before_action :load_moderatable_messageboards
8
8
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Thredded
3
- class PostPermalinksController < ApplicationController
3
+ class PostPermalinksController < Thredded::ApplicationController
4
4
  def show
5
5
  post = Post.find(params[:id])
6
6
  authorize post, :read?
@@ -23,9 +23,11 @@ module Thredded
23
23
  user: thredded_current_user,
24
24
  messageboard: messageboard_or_nil,
25
25
  params: params.fetch(:user_preferences_form, {}).permit(
26
- :notify_on_mention,
26
+ :followed_topic_emails,
27
+ :follow_topics_on_mention,
27
28
  :notify_on_message,
28
- :messageboard_notify_on_mention,
29
+ :messageboard_followed_topic_emails,
30
+ :messageboard_follow_topics_on_mention
29
31
  )
30
32
  )
31
33
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Thredded
3
- class PrivatePostPermalinksController < ApplicationController
3
+ class PrivatePostPermalinksController < Thredded::ApplicationController
4
4
  before_action :thredded_require_login!
5
5
  def show
6
6
  private_post = PrivatePost.find(params[:id])
@@ -9,7 +9,7 @@ module Thredded
9
9
  else
10
10
  thredded_current_user
11
11
  end
12
- @messageboards = Messageboard.where(closed: false)
12
+ @messageboards = Messageboard.all
13
13
  @topics = TopicsPageView.new(@user, @messageboard.topics.page(1).limit(3))
14
14
  @private_topics = PrivateTopicsPageView.new(@user, @user.thredded_private_topics.page(1).limit(3))
15
15
  topic = Topic.new(messageboard: @messageboard, title: 'Hello', slug: 'hello', user: @user)
@@ -18,7 +18,6 @@ module Thredded
18
18
  thredded_current_user,
19
19
  policy_scope(messageboard.topics)
20
20
  .order_sticky_first.order_recently_posted_first
21
- .includes(:categories, :last_user, :user)
22
21
  .page(current_page)
23
22
  )
24
23
  TopicForm.new(messageboard: messageboard, user: thredded_current_user).tap do |form|
@@ -8,11 +8,13 @@ module Thredded
8
8
 
9
9
  validate :validate_children
10
10
 
11
- delegate :notify_on_mention, :notify_on_mention=,
11
+ delegate :follow_topics_on_mention, :follow_topics_on_mention=,
12
12
  :notify_on_message, :notify_on_message=,
13
+ :followed_topic_emails, :followed_topic_emails=,
13
14
  to: :user_preference
14
15
 
15
- delegate :notify_on_mention, :notify_on_mention=,
16
+ delegate :follow_topics_on_mention, :follow_topics_on_mention=,
17
+ :followed_topic_emails, :followed_topic_emails=,
16
18
  to: :user_messageboard_preference,
17
19
  prefix: :messageboard
18
20
 
@@ -2,6 +2,11 @@
2
2
  module Thredded
3
3
  module ApplicationHelper
4
4
  include ::Thredded::UrlsHelper
5
+ include ::Thredded::NavHelper
6
+
7
+ def view_hooks
8
+ @view_hooks ||= Thredded.view_hooks
9
+ end
5
10
 
6
11
  def thredded_container_data
7
12
  {
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+ require 'set'
3
+ module Thredded
4
+ module NavHelper
5
+ USER_NAV_MODERATION_PAGES = Set.new(
6
+ %w(
7
+ thredded--pending-moderation
8
+ thredded--moderation-activity
9
+ thredded--moderation-history
10
+ thredded--moderation-users
11
+ thredded--moderation-user
12
+ )
13
+ )
14
+
15
+ USER_NAV_PREFERENCES_PAGES = Set.new(
16
+ %w(
17
+ thredded--preferences
18
+ )
19
+ )
20
+
21
+ USER_NAV_PRIVATE_TOPICS_PAGES = Set.new(
22
+ %w(
23
+ thredded--new-private-topic
24
+ thredded--private-topics-index
25
+ thredded--private-topic-show
26
+ )
27
+ )
28
+
29
+ def current_page_preferences?
30
+ USER_NAV_PREFERENCES_PAGES.include?(content_for(:thredded_page_id))
31
+ end
32
+
33
+ def current_page_moderation?
34
+ USER_NAV_MODERATION_PAGES.include?(content_for(:thredded_page_id))
35
+ end
36
+
37
+ def current_page_private_topics?
38
+ USER_NAV_PRIVATE_TOPICS_PAGES.include?(content_for(:thredded_page_id))
39
+ end
40
+ end
41
+ end