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
@@ -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