thredded 0.7.0 → 0.8.2

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