thredded 0.0.1 → 0.0.3

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/thredded/application_controller.rb +9 -11
  3. data/app/controllers/thredded/emails_controller.rb +4 -0
  4. data/app/controllers/thredded/messageboards_controller.rb +1 -1
  5. data/app/controllers/thredded/posts_controller.rb +44 -48
  6. data/app/controllers/thredded/preferences_controller.rb +10 -2
  7. data/app/controllers/thredded/private_topics_controller.rb +18 -1
  8. data/app/controllers/thredded/setups_controller.rb +9 -4
  9. data/app/controllers/thredded/topics_controller.rb +47 -49
  10. data/app/decorators/thredded/post_decorator.rb +1 -1
  11. data/app/decorators/thredded/topic_decorator.rb +1 -9
  12. data/app/decorators/thredded/user_topic_decorator.rb +88 -0
  13. data/app/helpers/thredded/messageboard_helper.rb +1 -9
  14. data/app/helpers/thredded/topics_helper.rb +0 -17
  15. data/app/models/thredded/ability.rb +8 -0
  16. data/app/models/thredded/attachment.rb +0 -1
  17. data/app/models/thredded/category.rb +2 -3
  18. data/app/models/thredded/image.rb +0 -1
  19. data/app/models/thredded/messageboard.rb +15 -7
  20. data/app/models/thredded/messageboard_decorator.rb +2 -2
  21. data/app/models/thredded/messageboard_preference.rb +0 -1
  22. data/app/models/thredded/null_messageboard_preference.rb +7 -0
  23. data/app/models/thredded/null_preference.rb +8 -6
  24. data/app/models/thredded/null_topic_read.rb +15 -9
  25. data/app/models/thredded/null_user.rb +8 -0
  26. data/app/models/thredded/post.rb +13 -17
  27. data/app/models/thredded/post_notification.rb +0 -1
  28. data/app/models/thredded/private_topic.rb +11 -2
  29. data/app/models/thredded/private_user.rb +0 -1
  30. data/app/models/thredded/role.rb +0 -2
  31. data/app/models/thredded/topic.rb +27 -23
  32. data/app/models/thredded/topic_category.rb +0 -1
  33. data/app/models/thredded/user_extender.rb +2 -8
  34. data/app/models/thredded/user_topic_read.rb +5 -63
  35. data/app/views/thredded/attachments/_attachment.html.erb +7 -0
  36. data/app/views/thredded/messageboards/_messageboard.html.erb +1 -1
  37. data/app/views/thredded/post_mailer/at_notification.html.erb +1 -1
  38. data/app/views/thredded/post_mailer/at_notification.text.erb +1 -1
  39. data/app/views/thredded/posts/_post.html.erb +6 -2
  40. data/app/views/thredded/posts/index.html.erb +24 -37
  41. data/app/views/thredded/private_topics/_form.html.erb +15 -0
  42. data/app/views/thredded/private_topics/index.html.erb +33 -0
  43. data/app/views/thredded/private_topics/new.html.erb +24 -0
  44. data/app/views/thredded/shared/_currently_online.html.erb +2 -2
  45. data/app/views/thredded/shared/_topic_nav.html.erb +13 -10
  46. data/app/views/thredded/topic_mailer/message_notification.html.erb +1 -1
  47. data/app/views/thredded/topic_mailer/message_notification.text.erb +1 -1
  48. data/app/views/thredded/topics/_recent_topics_by_user.html.erb +8 -0
  49. data/app/views/thredded/topics/_topic_condensed.html.erb +6 -2
  50. data/app/views/thredded/topics/index.html.erb +5 -26
  51. data/app/views/thredded/topics/new.html.erb +1 -1
  52. data/app/views/thredded/topics/search.html.erb +6 -21
  53. data/config/initializers/griddler.rb +4 -0
  54. data/config/routes.rb +8 -5
  55. data/db/migrate/20131005032727_prevent_null_sticky_and_locked.rb +15 -0
  56. data/db/migrate/20131014014258_uniqs_on_user_topic_read.rb +9 -0
  57. data/db/migrate/20131019014258_index_necessary_columns.rb +24 -0
  58. data/lib/thredded.rb +3 -0
  59. data/lib/thredded/at_notifier.rb +4 -2
  60. data/lib/thredded/at_users.rb +2 -2
  61. data/lib/thredded/email_processor.rb +57 -55
  62. data/lib/thredded/engine.rb +1 -1
  63. data/lib/thredded/errors.rb +8 -0
  64. data/lib/thredded/post_sql_builder.rb +3 -3
  65. data/lib/thredded/post_user_permissions.rb +4 -0
  66. data/lib/thredded/private_topic_user_permissions.rb +7 -1
  67. data/lib/thredded/search_sql_builder.rb +1 -1
  68. data/lib/thredded/table_sql_builder.rb +1 -1
  69. data/lib/thredded/version.rb +1 -1
  70. metadata +21 -35
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dbf9d4e29edeea27a73efed02c03710eaa1f7530
4
- data.tar.gz: a3c14e476dbbe413c60dc52fce7c712152cd5743
3
+ metadata.gz: a68e85a7ae96d4689ef3ab6c56affe335882cf0f
4
+ data.tar.gz: 47792dcbde12d63235c02a4257931777742e1823
5
5
  SHA512:
6
- metadata.gz: 07f3f002cf28edd4d5a7a30b2f10651eac57327ce22a28481aa07167922a7ad89872df0e1b8b33693b1ce52b034830212f1a6677aed5bb61138c67914f2bba36
7
- data.tar.gz: 3d03b68a94ecb9ce235ea772545c930c1b9ed62ea3e2bcbb353bf171a1dd8f63b13c79a46f65ab6d266b81ab6dd48a87478edeb5401fdd4422083140afe8d00a
6
+ metadata.gz: 34c5c730348e014f85376364231c51c6941fed5e4b0c51bf041c0bb4340427a3fdc54dd4a693aca8a7f3f5e632df13e19b15c1fc2430bd343a323e73bf5aa132
7
+ data.tar.gz: bc03a54520ce87f0454888ec6e61511d99cffcbca412f77392a60b103879b2b040153496956496785793c26bfa2dcb54f1ebc58a30a38f1c6b5bdd4977e1961f
@@ -2,21 +2,27 @@ module Thredded
2
2
  class ApplicationController < ::ApplicationController
3
3
  helper Thredded::Engine.helpers
4
4
  helper_method :messageboard, :topic, :preferences
5
+ before_filter :update_user_activity
5
6
 
6
7
  rescue_from CanCan::AccessDenied do |exception|
7
- flash[:error] = exception.message
8
- redirect_to root_path
8
+ redirect_to root_path, alert: exception.message
9
9
  end
10
10
 
11
11
  private
12
12
 
13
+ def update_user_activity
14
+ if messageboard && current_user
15
+ messageboard.update_activity_for!(current_user)
16
+ end
17
+ end
18
+
13
19
  def current_ability
14
20
  @current_ability ||= Ability.new(current_user)
15
21
  end
16
22
 
17
23
  def messageboard
18
24
  if params.key? :messageboard_id
19
- @messageboard ||= Messageboard.find(params[:messageboard_id])
25
+ @messageboard ||= Messageboard.where(slug: params[:messageboard_id]).first
20
26
  end
21
27
  end
22
28
 
@@ -38,13 +44,5 @@ module Thredded
38
44
  flash: { error: 'This messageboard does not exist.' }
39
45
  end
40
46
  end
41
-
42
- def user_messageboard_preferences
43
- @user_messageboard_preferences ||=
44
- current_user
45
- .thredded_messageboard_preferences
46
- .where(messageboard_id: messageboard)
47
- .first
48
- end
49
47
  end
50
48
  end
@@ -0,0 +1,4 @@
1
+ module Thredded
2
+ class EmailsController < ::Griddler::EmailsController
3
+ end
4
+ end
@@ -1,5 +1,5 @@
1
1
  module Thredded
2
- class MessageboardsController < ApplicationController
2
+ class MessageboardsController < Thredded::ApplicationController
3
3
  before_filter :messageboard, only: :show
4
4
 
5
5
  def index
@@ -1,28 +1,24 @@
1
1
  module Thredded
2
- class PostsController < ApplicationController
3
- include TopicsHelper
2
+ class PostsController < Thredded::ApplicationController
4
3
  load_and_authorize_resource only: [:index, :show]
5
- before_filter :ensure_topic_exists
6
- before_filter :pad_post, only: :create
7
- helper_method :messageboard, :topic
4
+ helper_method :messageboard, :topic, :user_topic
5
+
6
+ rescue_from Thredded::Errors::TopicNotFound do |exception|
7
+ redirect_to messageboard_topics_path(messageboard),
8
+ alert: 'This topic does not exist.'
9
+ end
8
10
 
9
11
  def index
10
12
  authorize! :read, topic
11
13
 
12
- @post = messageboard.posts.build(topic: topic, filter: post_filter)
13
- @posts = Post.where(topic_id: topic).page(page)
14
- @read_status = UserTopicRead
15
- .find_or_create_by_user_and_topic(current_user, topic, page)
14
+ @posts = topic.posts.page(current_page)
15
+ @post = messageboard.posts.build(topic: topic, filter: post_filter)
16
16
 
17
- if not_inside_topic_and_in_an_old_page?
18
- redirect_to_later_page and return
19
- else
20
- UserTopicRead.update_read_status!(current_user, topic, page)
21
- end
17
+ update_read_status!
22
18
  end
23
19
 
24
20
  def create
25
- topic.posts.create(params[:post])
21
+ topic.posts.create(post_params)
26
22
  redirect_to :back
27
23
  end
28
24
 
@@ -31,56 +27,56 @@ module Thredded
31
27
  end
32
28
 
33
29
  def update
34
- post.update_attributes(params[:post])
30
+ post.update_attributes(post_params)
35
31
  redirect_to messageboard_topic_posts_url(messageboard, topic)
36
32
  end
37
33
 
38
34
  private
39
35
 
40
- def topic
41
- @topic ||= messageboard.topics.find(params[:topic_id])
42
- end
43
-
44
- def post
45
- @post ||= topic.posts.find(params[:id])
46
- end
47
-
48
- def post_filter
49
- user_messageboard_preferences.try(:filter) || :markdown
36
+ def post_params
37
+ params
38
+ .require(:post)
39
+ .permit!
40
+ .merge!(
41
+ ip: request.remote_ip,
42
+ user: current_user,
43
+ messageboard: messageboard,
44
+ )
50
45
  end
51
46
 
52
- def not_inside_topic_and_in_an_old_page?
53
- !internal_to_topic? && page == 1 && @read_status.page > 1
54
- end
55
-
56
- def page
57
- params[:page].nil? ? 1 : params[:page].to_i
47
+ def update_read_status!
48
+ if current_user
49
+ read_history = UserTopicRead.where(
50
+ user: current_user,
51
+ topic: topic,
52
+ ).first_or_initialize
53
+
54
+ read_history.update_attributes(
55
+ farthest_post: @posts.last,
56
+ posts_count: topic.posts_count,
57
+ page: current_page,
58
+ )
59
+ end
58
60
  end
59
61
 
60
- def extra_data
61
- %Q{data-latest-read=#{@read_status.post_id || 0}} if @read_status
62
+ def topic
63
+ @topic ||= messageboard.topics.find_by_slug(params[:topic_id])
62
64
  end
63
65
 
64
- def internal_to_topic?
65
- referer = request.referer || ''
66
- referer.include?("#{topic.id}?page=") || (!topic.slug.nil? && referer.include?("#{topic.slug}?page="))
66
+ def user_topic
67
+ @user_topic ||= UserTopicDecorator.new(current_user, topic)
67
68
  end
68
69
 
69
- def redirect_to_later_page
70
- redirect_to messageboard_topic_posts_path(messageboard, topic, page: @read_status.page)
70
+ def post
71
+ @post ||= topic.posts.find(params[:id])
71
72
  end
72
73
 
73
- def pad_post
74
- params[:post][:ip] = request.remote_ip
75
- params[:post][:user] = current_user
76
- params[:post][:messageboard] = messageboard
74
+ def post_filter
75
+ messageboard.preferences_for(current_user).filter
77
76
  end
78
77
 
79
- def ensure_topic_exists
80
- if topic.blank?
81
- redirect_to default_home,
82
- flash: { error: 'This topic does not exist.' }
83
- end
78
+ def current_page
79
+ params[:page].nil? ? 1 : params[:page].to_i
84
80
  end
85
81
  end
86
82
  end
@@ -1,12 +1,12 @@
1
1
  module Thredded
2
- class PreferencesController < ApplicationController
2
+ class PreferencesController < Thredded::ApplicationController
3
3
  helper_method :preference
4
4
 
5
5
  def edit
6
6
  end
7
7
 
8
8
  def update
9
- preference.update_attributes(params[:messageboard_preference])
9
+ preference.update_attributes(preference_params)
10
10
 
11
11
  redirect_to :back, flash: { notice: 'Your preferences are updated' }
12
12
  end
@@ -16,5 +16,13 @@ module Thredded
16
16
  .where(messageboard_id: messageboard.id, user_id: current_user.id)
17
17
  .first_or_create!
18
18
  end
19
+
20
+ private
21
+
22
+ def preference_params
23
+ params
24
+ .require(:messageboard_preference)
25
+ .permit(:notify_on_mention, :notify_on_message, :filter)
26
+ end
19
27
  end
20
28
  end
@@ -1,7 +1,16 @@
1
1
  module Thredded
2
- class PrivateTopicsController < ApplicationController
2
+ class PrivateTopicsController < Thredded::ApplicationController
3
3
  before_filter :ensure_messageboard_exists
4
4
 
5
+ def index
6
+ if cannot? :read, messageboard
7
+ error = 'You are not authorized access to this messageboard.'
8
+ redirect_to default_home, flash: { error: error }
9
+ else
10
+ @private_topics = get_private_topics
11
+ end
12
+ end
13
+
5
14
  def new
6
15
  @private_topic = messageboard.private_topics.build
7
16
  @private_topic.posts.build(
@@ -21,5 +30,13 @@ module Thredded
21
30
  @private_topic = PrivateTopic.create(params[:topic])
22
31
  redirect_to messageboard_topics_url(messageboard)
23
32
  end
33
+
34
+ def get_private_topics
35
+ PrivateTopic
36
+ .for_messageboard(messageboard)
37
+ .including_roles_for(current_user)
38
+ .for_user(current_user)
39
+ .on_page(params[:page])
40
+ end
24
41
  end
25
42
  end
@@ -1,11 +1,10 @@
1
1
  module Thredded
2
- class SetupsController < ApplicationController
2
+ class SetupsController < Thredded::ApplicationController
3
3
  def new
4
4
  @messageboard = Messageboard.new
5
5
  end
6
6
 
7
7
  def create
8
- messageboard_params = params[:messageboard]
9
8
  @messageboard = Messageboard.create(messageboard_params)
10
9
 
11
10
  if @messageboard.valid?
@@ -20,6 +19,12 @@ module Thredded
20
19
 
21
20
  private
22
21
 
22
+ def messageboard_params
23
+ params
24
+ .require(:messageboard)
25
+ .permit(:description, :name, :posting_permissions, :security)
26
+ end
27
+
23
28
  def topic_params
24
29
  {
25
30
  user: current_user,
@@ -28,9 +33,9 @@ module Thredded
28
33
  posts_attributes: {
29
34
  '0' => {
30
35
  content: "There's not a whole lot here for now.",
31
- user: current_user,
32
36
  ip: '127.0.0.1',
33
- messageboard: @messageboard
37
+ messageboard: @messageboard,
38
+ user: current_user,
34
39
  }
35
40
  }
36
41
  }
@@ -1,6 +1,7 @@
1
1
  module Thredded
2
- class TopicsController < ApplicationController
2
+ class TopicsController < Thredded::ApplicationController
3
3
  before_filter :ensure_messageboard_exists
4
+ helper_method :current_page
4
5
 
5
6
  def index
6
7
  if cannot? :read, messageboard
@@ -8,24 +9,24 @@ module Thredded
8
9
  redirect_to default_home, flash: { error: error }
9
10
  end
10
11
 
11
- @sticky = get_sticky_topics
12
- @topics = get_topics
13
- @tracked_user_reads = UserTopicRead.statuses_for(current_user, @topics)
12
+ @topics = topics
14
13
  end
15
14
 
16
15
  def search
17
- @topics = get_search_results
18
- @tracked_user_reads = UserTopicRead.statuses_for(current_user, @topics)
16
+ @topics = search_results
19
17
 
20
18
  if @topics.empty?
21
19
  error = 'No topics found for this search.'
22
- redirect_to messageboard_topics_path(messageboard), flash: { error: error }
20
+ redirect_to messageboard_topics_path(messageboard),
21
+ flash: { error: error }
23
22
  end
24
23
  end
25
24
 
26
25
  def new
27
26
  @topic = messageboard.topics.build
28
- @topic.posts.build( filter: user_messageboard_preferences.try(:filter) )
27
+ @topic
28
+ .posts
29
+ .build(filter: messageboard.preferences_for(current_user).filter)
29
30
 
30
31
  unless can? :create, @topic
31
32
  error = 'Sorry, you are not authorized to post on this messageboard.'
@@ -35,13 +36,12 @@ module Thredded
35
36
  end
36
37
 
37
38
  def by_category
38
- @sticky = get_sticky_topics
39
- @topics = get_topics_by_category params[:category_id]
39
+ @topics = topics_by_category(params[:category_id])
40
40
  @category_name = Category.find(params[:category_id]).name
41
41
  end
42
42
 
43
43
  def create
44
- @topic = messageboard.topics.create(topic_params)
44
+ @topic = messageboard.topics.create(topic_and_post_params)
45
45
  redirect_to messageboard_topics_path(messageboard)
46
46
  end
47
47
 
@@ -50,14 +50,7 @@ module Thredded
50
50
  end
51
51
 
52
52
  def update
53
- params.deep_merge!({
54
- topic: {
55
- user: current_user,
56
- last_user: current_user
57
- }
58
- })
59
-
60
- topic.update_attributes(params[:topic])
53
+ topic.update_attributes(topic_params)
61
54
  redirect_to messageboard_topic_posts_url(messageboard, topic)
62
55
  end
63
56
 
@@ -65,57 +58,62 @@ module Thredded
65
58
 
66
59
  def topic
67
60
  if messageboard
68
- @topic ||= messageboard.topics.find(params[:id])
61
+ @topic ||= messageboard.topics.where(slug: params[:id]).first
69
62
  end
70
63
  end
71
64
 
72
65
  def topic_params
73
- params[:topic].deep_merge!({
74
- last_user: current_user,
75
- user: current_user,
76
- posts_attributes: {
77
- '0' => {
78
- messageboard: messageboard,
79
- ip: request.remote_ip,
80
- user: current_user,
66
+ params
67
+ .require(:topic)
68
+ .permit!
69
+ .deep_merge!({
70
+ user: current_user,
71
+ last_user: current_user
72
+ })
73
+ end
74
+
75
+ def topic_and_post_params
76
+ params
77
+ .require(:topic)
78
+ .permit!
79
+ .deep_merge!({
80
+ last_user: current_user,
81
+ user: current_user,
82
+ posts_attributes: {
83
+ '0' => {
84
+ messageboard: messageboard,
85
+ ip: request.remote_ip,
86
+ user: current_user,
87
+ }
81
88
  }
82
- }
83
- })
89
+ })
84
90
  end
85
91
 
86
- def get_search_results
92
+ def search_results
87
93
  Topic.full_text_search(params[:q], messageboard)
88
94
  end
89
95
 
90
- def get_topics_by_category(category_id)
96
+ def topics_by_category(category_id)
91
97
  topics = Category.find(category_id)
92
98
  .topics
93
99
  .unstuck
100
+ .public
94
101
  .for_messageboard(messageboard)
95
102
  .order_by_updated
96
- .on_page(params[:page])
103
+ .on_page(current_page)
97
104
  end
98
105
 
99
- def get_topics
106
+ def topics
100
107
  Topic
101
- .unstuck
108
+ .public
102
109
  .for_messageboard(messageboard)
103
- .order_by_updated.on_page(params[:page])
104
- end
105
-
106
- def get_sticky_topics
107
- if on_first_topics_page?
108
- Topic
109
- .stuck
110
- .for_messageboard(messageboard)
111
- .order('id DESC')
112
- else
113
- []
114
- end
110
+ .includes(:user_topic_reads)
111
+ .order_by_stuck_and_updated_time
112
+ .on_page(current_page)
115
113
  end
116
114
 
117
- def on_first_topics_page?
118
- params[:page].nil? || params[:page] == '1'
115
+ def current_page
116
+ params[:page] || 1
119
117
  end
120
118
  end
121
119
  end