thredded 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -9,7 +9,7 @@ module Thredded
9
9
 
10
10
  def user_name
11
11
  if user
12
- user.name
12
+ user.to_s
13
13
  else
14
14
  'Anonymous'
15
15
  end
@@ -19,19 +19,11 @@ module Thredded
19
19
  classes.join(' ')
20
20
  end
21
21
 
22
- def user_link
23
- if user.nil?
24
- '<a href="#">?</a>'.html_safe
25
- else
26
- "<a href='/users/#{user_name}'>#{user_name}</a>".html_safe
27
- end
28
- end
29
-
30
22
  def last_user_link
31
23
  if last_user.nil?
32
24
  'Anonymous'
33
25
  else
34
- "<a href='/users/#{last_user.name}'>#{last_user.name}</a>".html_safe
26
+ "<a href='/users/#{last_user}'>#{last_user}</a>".html_safe
35
27
  end
36
28
  end
37
29
 
@@ -0,0 +1,88 @@
1
+ module Thredded
2
+ class UserTopicDecorator
3
+ extend ActiveModel::Naming
4
+ include ActiveModel::Conversion
5
+
6
+ def initialize(user, topic)
7
+ @user = user || NullUser.new
8
+ @topic = topic
9
+ end
10
+
11
+ def method_missing(meth, *args)
12
+ if decorated_topic.respond_to?(meth)
13
+ decorated_topic.send(meth, *args)
14
+ else
15
+ super
16
+ end
17
+ end
18
+
19
+ def respond_to?(meth)
20
+ decorated_topic.respond_to?(meth)
21
+ end
22
+
23
+ def self.decorate_all(user, topics)
24
+ topics.map do |topic|
25
+ new(user, topic)
26
+ end
27
+ end
28
+
29
+ def self.model_name
30
+ ActiveModel::Name.new(self, nil, "Topic")
31
+ end
32
+
33
+ def persisted?
34
+ false
35
+ end
36
+
37
+ def read?
38
+ topic.posts_count == read_status.posts_count
39
+ end
40
+
41
+ def farthest_page
42
+ read_status.page
43
+ end
44
+
45
+ def farthest_post
46
+ read_status.farthest_post
47
+ end
48
+
49
+ def css_class
50
+ if read?
51
+ "read #{decorated_topic.css_class}"
52
+ else
53
+ "unread #{decorated_topic.css_class}"
54
+ end
55
+ end
56
+
57
+ def user_link
58
+ if user.valid?
59
+ "<a href='/users/#{topic.user_name}'>#{topic.user_name}</a>".html_safe
60
+ else
61
+ '<a href="#">?</a>'.html_safe
62
+ end
63
+ end
64
+
65
+
66
+ def decorated_topic
67
+ @decorated_topic ||= TopicDecorator.new(topic)
68
+ end
69
+
70
+ private
71
+
72
+ attr_reader :topic, :user
73
+
74
+ def read_status
75
+ if user.valid?
76
+ @read_status ||= topic.user_topic_reads.select do |reads|
77
+ reads.user_id == user.id
78
+ end
79
+ end
80
+
81
+ if @read_status.blank?
82
+ NullTopicRead.new
83
+ else
84
+ @read_status.first
85
+ end
86
+ end
87
+ end
88
+ end
@@ -15,14 +15,6 @@ module Thredded
15
15
  #{number_to_human posts} posts".downcase
16
16
  end
17
17
 
18
- def admin_link_for(messageboard)
19
- if can? :manage, messageboard
20
- '<p class="admin"><a href="#edit">Edit</a></p>'
21
- else
22
- ''
23
- end
24
- end
25
-
26
18
  def latest_thread_for(messageboard)
27
19
  topic = messageboard.topics.first
28
20
 
@@ -43,7 +35,7 @@ module Thredded
43
35
 
44
36
  def latest_user_for(messageboard)
45
37
  if messageboard.topics.first.present? && messageboard.topics.first.user.present?
46
- messageboard.topics.first.last_user.name
38
+ messageboard.topics.first.last_user.to_s
47
39
  else
48
40
  ''
49
41
  end
@@ -1,21 +1,4 @@
1
1
  module Thredded
2
2
  module TopicsHelper
3
- require 'digest/md5'
4
-
5
- def md5(s)
6
- Digest::MD5.hexdigest(s)
7
- end
8
-
9
- def already_read(topic, tracked_user_reads)
10
- if tracked_user_reads
11
- topic_status = tracked_user_reads.select{ |t| t.topic_id == topic.id }.first
12
-
13
- if topic_status && topic_status.posts_count == topic.posts_count
14
- 'read'
15
- else
16
- 'unread'
17
- end
18
- end
19
- end
20
3
  end
21
4
  end
@@ -26,6 +26,10 @@ module Thredded
26
26
 
27
27
  cannot :manage, Thredded::PrivateTopic
28
28
 
29
+ can :list, Thredded::PrivateTopic do |private_topic|
30
+ Thredded::PrivateTopicUserPermissions.new(private_topic, user, user_details).listable?
31
+ end
32
+
29
33
  can :manage, Thredded::PrivateTopic do |private_topic|
30
34
  Thredded::PrivateTopicUserPermissions.new(private_topic, user, user_details).manageable?
31
35
  end
@@ -38,6 +42,10 @@ module Thredded
38
42
  Thredded::PrivateTopicUserPermissions.new(private_topic, user, user_details).readable?
39
43
  end
40
44
 
45
+ can :edit, Thredded::Post do |post|
46
+ Thredded::PostUserPermissions.new(post, user, user_details).editable?
47
+ end
48
+
41
49
  can :manage, Thredded::Post do |post|
42
50
  Thredded::PostUserPermissions.new(post, user, user_details).manageable?
43
51
  end
@@ -2,7 +2,6 @@ module Thredded
2
2
  class Attachment < ActiveRecord::Base
3
3
  belongs_to :post
4
4
  validates_presence_of :attachment
5
- attr_accessible :attachment
6
5
  mount_uploader :attachment, Thredded::AttachmentUploader
7
6
  before_save :update_attachment_attributes
8
7
 
@@ -1,10 +1,9 @@
1
1
  module Thredded
2
2
  class Category < ActiveRecord::Base
3
- attr_accessible :description, :messageboard_id, :name
4
- validates :name, presence: true
5
-
6
3
  belongs_to :messageboard
7
4
  has_many :topic_categories
8
5
  has_many :topics, through: :topic_categories
6
+
7
+ validates :name, presence: true
9
8
  end
10
9
  end
@@ -1,7 +1,6 @@
1
1
  module Thredded
2
2
  class Image < ActiveRecord::Base
3
3
  mount_uploader :image, ImageUploader
4
- attr_accessible :height, :orientation, :width
5
4
  validates :image, presence: true
6
5
  before_validation :save_dimensions, :save_orientation, :save_position
7
6
 
@@ -6,13 +6,6 @@ module Thredded
6
6
  extend FriendlyId
7
7
  friendly_id :name
8
8
 
9
- attr_accessible :description,
10
- :name,
11
- :posting_permission,
12
- :security
13
-
14
- default_scope where(closed: false).order('topics_count DESC')
15
-
16
9
  validates_numericality_of :topics_count
17
10
  validates_inclusion_of :security, in: SECURITY
18
11
  validates_inclusion_of :posting_permission, in: PERMISSIONS
@@ -32,6 +25,15 @@ module Thredded
32
25
  has_many :private_topics
33
26
  has_many :users, through: :roles, class_name: Thredded.user_class
34
27
 
28
+ def self.default_scope
29
+ where(closed: false).order('topics_count DESC')
30
+ end
31
+
32
+ def preferences_for(user)
33
+ @preferences_for ||=
34
+ messageboard_preferences.where(user_id: user).first || NullMessageboardPreference.new
35
+ end
36
+
35
37
  def active_users
36
38
  Role
37
39
  .joins(:user)
@@ -41,6 +43,12 @@ module Thredded
41
43
  .map(&:user)
42
44
  end
43
45
 
46
+ def update_activity_for!(user)
47
+ if role = roles.where(user_id: user).first
48
+ role.update_attribute(:last_seen, Time.now.utc)
49
+ end
50
+ end
51
+
44
52
  def decorate
45
53
  MessageboardDecorator.new(self)
46
54
  end
@@ -8,11 +8,11 @@ module Thredded
8
8
  end
9
9
 
10
10
  def category_options
11
- messageboard.categories.collect { |cat| [cat.name, cat.id] }
11
+ messageboard.categories.map { |cat| [cat.name, cat.id] }
12
12
  end
13
13
 
14
14
  def users_options
15
- messageboard.users.collect{ |user| [user.name, user.id] }
15
+ messageboard.users.map { |user| [user.to_s, user.id] }
16
16
  end
17
17
  end
18
18
  end
@@ -1,6 +1,5 @@
1
1
  module Thredded
2
2
  class MessageboardPreference < ActiveRecord::Base
3
- attr_accessible :notify_on_mention, :notify_on_message, :filter
4
3
  belongs_to :user
5
4
  belongs_to :messageboard
6
5
 
@@ -0,0 +1,7 @@
1
+ module Thredded
2
+ class NullMessageboardPreference
3
+ def filter
4
+ 'markdown'
5
+ end
6
+ end
7
+ end
@@ -1,9 +1,11 @@
1
- class NullPreference
2
- def notify_on_mention
3
- true
4
- end
1
+ module Thredded
2
+ class NullPreference
3
+ def notify_on_mention
4
+ true
5
+ end
5
6
 
6
- def notify_on_message
7
- true
7
+ def notify_on_message
8
+ true
9
+ end
8
10
  end
9
11
  end
@@ -1,13 +1,19 @@
1
- class NullTopicRead
2
- def update_status(topic)
3
- # ¯\_(ツ)_/¯
4
- end
1
+ module Thredded
2
+ class NullTopicRead
3
+ def page
4
+ 1
5
+ end
5
6
 
6
- def page
7
- 0
8
- end
7
+ def post_id
8
+ 0
9
+ end
10
+
11
+ def posts_count
12
+ 0
13
+ end
9
14
 
10
- def post_id
11
- 0
15
+ def farthest_post
16
+ Post.new
17
+ end
12
18
  end
13
19
  end
@@ -4,6 +4,10 @@ module Thredded
4
4
  false
5
5
  end
6
6
 
7
+ def thredded_private_topics
8
+ false
9
+ end
10
+
7
11
  def can_read_messageboard?(messageboard)
8
12
  messageboard.public?
9
13
  end
@@ -20,6 +24,10 @@ module Thredded
20
24
  'Anonymous User'
21
25
  end
22
26
 
27
+ def to_s
28
+ name
29
+ end
30
+
23
31
  def valid?
24
32
  false
25
33
  end
@@ -1,6 +1,8 @@
1
+ require 'thredded/at_notifier'
2
+ require 'gravtastic'
3
+
1
4
  module Thredded
2
5
  class Post < ActiveRecord::Base
3
- require 'gravtastic'
4
6
  include Gravtastic
5
7
  include Thredded::Filter::Base
6
8
  include Thredded::Filter::Textile
@@ -13,17 +15,6 @@ module Thredded
13
15
  gravtastic :user_email
14
16
  paginates_per 50
15
17
 
16
- attr_accessible :attachments_attributes,
17
- :content,
18
- :filter,
19
- :ip,
20
- :messageboard,
21
- :source,
22
- :topic,
23
- :user
24
-
25
- default_scope order: 'id ASC'
26
-
27
18
  belongs_to :messageboard, counter_cache: true
28
19
  belongs_to :topic, counter_cache: true
29
20
  belongs_to :user, class_name: Thredded.user_class
@@ -35,11 +26,11 @@ module Thredded
35
26
  validates_presence_of :content, :messageboard_id
36
27
 
37
28
  before_validation :set_user_email
38
- after_create :modify_parent_topic
29
+ after_save :notify_at_users
30
+ after_create :modify_parent_posts_counts
39
31
 
40
- def create
41
- UserDetail.increment_counter(:posts_count, user_id)
42
- super
32
+ def self.default_scope
33
+ order('id ASC')
43
34
  end
44
35
 
45
36
  def created_date
@@ -60,7 +51,8 @@ module Thredded
60
51
 
61
52
  private
62
53
 
63
- def modify_parent_topic
54
+ def modify_parent_posts_counts
55
+ UserDetail.increment_counter(:posts_count, user_id)
64
56
  topic.last_user = user
65
57
  topic.touch
66
58
  topic.save
@@ -71,5 +63,9 @@ module Thredded
71
63
  self.user_email = user.email
72
64
  end
73
65
  end
66
+
67
+ def notify_at_users
68
+ AtNotifier.new(self).notifications_for_at_users
69
+ end
74
70
  end
75
71
  end
@@ -1,6 +1,5 @@
1
1
  module Thredded
2
2
  class PostNotification < ActiveRecord::Base
3
- attr_accessible :email, :post_id
4
3
  belongs_to :post
5
4
  end
6
5
  end
@@ -2,7 +2,16 @@ module Thredded
2
2
  class PrivateTopic < Thredded::Topic
3
3
  has_many :private_users
4
4
  has_many :users, through: :private_users
5
- attr_accessible :user_id
5
+
6
+ def self.including_roles_for(user)
7
+ joins(messageboard: :roles)
8
+ .where(thredded_roles: {user_id: user.id})
9
+ end
10
+
11
+ def self.for_user(user)
12
+ joins(:private_users)
13
+ .where(thredded_private_users: {user_id: user.id})
14
+ end
6
15
 
7
16
  def add_user(user)
8
17
  if String == user.class
@@ -27,7 +36,7 @@ module Thredded
27
36
  end
28
37
 
29
38
  def users_to_sentence
30
- users.map{ |user| user.name.capitalize }.to_sentence
39
+ users.map{ |user| user.to_s.capitalize }.to_sentence
31
40
  end
32
41
  end
33
42
  end