diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 6cdbf53..7790c6a 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -540,6 +540,10 @@ div#story_box div.markdown_help_toggler { width: 610px; } +div.comment_form_container { + max-width: 550px; +} + /* data tables */ table.data caption { diff --git a/app/controllers/invitations_controller.rb b/app/controllers/invitations_controller.rb index 85e4d13..5787ddf 100644 --- a/app/controllers/invitations_controller.rb +++ b/app/controllers/invitations_controller.rb @@ -7,7 +7,7 @@ class InvitationsController < ApplicationController i.email = params[:email] i.memo = params[:memo] if i.save - i.send_email(root_url) + i.send_email flash[:success] = "Successfully e-mailed invitation to " << params[:email] else diff --git a/app/controllers/login_controller.rb b/app/controllers/login_controller.rb index d0b83f4..96a7bd9 100644 --- a/app/controllers/login_controller.rb +++ b/app/controllers/login_controller.rb @@ -39,7 +39,7 @@ class LoginController < ApplicationController return forgot_password end - @found_user.initiate_password_reset_for_ip(root_url, request.remote_ip) + @found_user.initiate_password_reset_for_ip(request.remote_ip) flash.now[:success] = "Password reset instructions have been e-mailed " << "to you." diff --git a/app/mailers/email_reply.rb b/app/mailers/email_reply.rb new file mode 100644 index 0000000..d7db75e --- /dev/null +++ b/app/mailers/email_reply.rb @@ -0,0 +1,12 @@ +class EmailReply < ActionMailer::Base + default :from => "nobody@lobste.rs" + + def reply(comment, user) + @comment = comment + @user = user + + mail(:to => user.email, :from => "Lobsters ", + :subject => "[Lobsters] Reply from #{comment.user.username} on " << + "#{comment.story.title}") + end +end diff --git a/app/mailers/invitation_mailer.rb b/app/mailers/invitation_mailer.rb index e87d13a..48a30b9 100644 --- a/app/mailers/invitation_mailer.rb +++ b/app/mailers/invitation_mailer.rb @@ -1,11 +1,9 @@ class InvitationMailer < ActionMailer::Base - default from: "nobody@lobste.rs" - - def invitation(root_url, invitation) - @root_url = root_url + def invitation(invitation) @invitation = invitation - mail(to: invitation.email, from: "Lobsters Invitation ", + mail(:to => invitation.email, + :from => "Lobsters Invitation ", subject: "[Lobsters] Welcome to Lobsters") end end diff --git a/app/mailers/password_reset.rb b/app/mailers/password_reset.rb index da95239..b993ed9 100644 --- a/app/mailers/password_reset.rb +++ b/app/mailers/password_reset.rb @@ -1,12 +1,9 @@ class PasswordReset < ActionMailer::Base - default from: "nobody@lobste.rs" - - def password_reset_link(root_url, user, ip) - @root_url = root_url + def password_reset_link(user, ip) @user = user @ip = ip - mail(to: user.email, from: "Lobsters ", - subject: "[Lobsters] Reset your password") + mail(:to => user.email, :from => "Lobsters ", + :subject => "[Lobsters] Reset your password") end end diff --git a/app/models/comment.rb b/app/models/comment.rb index e3898eb..ec430b6 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -3,6 +3,8 @@ class Comment < ActiveRecord::Base belongs_to :story has_many :votes, :dependent => :delete_all + belongs_to :parent_comment, + :class_name => "Comment" attr_accessible :comment @@ -10,7 +12,7 @@ class Comment < ActiveRecord::Base :indent_level before_create :assign_short_id_and_upvote - after_create :assign_votes, :mark_submitter + after_create :assign_votes, :mark_submitter, :email_reply after_destroy :unassign_votes MAX_EDIT_MINS = 45 @@ -54,6 +56,27 @@ class Comment < ActiveRecord::Base Keystore.increment_value_for("user:#{self.user_id}:comments_posted") end + def email_reply + begin + if self.parent_comment_id && u = self.parent_comment.try(:user) + if u.email_replies? + EmailReply.reply(self, u).deliver + end + + if u.pushover_replies? + Pushover.push(u.pushover_user_key, u.pushover_device, { + :title => "Lobsters reply from #{self.user.username} on " << + "#{self.story.title}", + :message => self.plaintext_comment, + :url => self.url, + :url_title => "Reply to #{self.user.username}", + }) + end + end + rescue + end + end + # http://evanmiller.org/how-not-to-sort-by-average-rating.html # https://github.com/reddit/reddit/blob/master/r2/r2/lib/db/_sorts.pyx def confidence @@ -85,6 +108,11 @@ class Comment < ActiveRecord::Base :filter_html).to_html end + def plaintext_comment + # TODO: linkify then strip tags and convert entities back + comment + end + def flag! Story.update_counters self.id, :flaggings => 1 end @@ -132,4 +160,8 @@ class Comment < ActiveRecord::Base (Time.now.to_i - self.created_at.to_i < (60 * MAX_EDIT_MINS)) end + + def url + self.story.comments_url + "/comments/#{self.short_id}" + end end diff --git a/app/models/invitation.rb b/app/models/invitation.rb index 5251d0d..371b650 100644 --- a/app/models/invitation.rb +++ b/app/models/invitation.rb @@ -21,7 +21,7 @@ class Invitation < ActiveRecord::Base end end - def send_email(root_url) - InvitationMailer.invitation(root_url, self).deliver + def send_email + InvitationMailer.invitation(self).deliver end end diff --git a/app/models/story.rb b/app/models/story.rb index bd3450a..6d3968d 100644 --- a/app/models/story.rb +++ b/app/models/story.rb @@ -84,12 +84,12 @@ class Story < ActiveRecord::Base self.tags_to_add = [] end - def comments_url(root_url = "/") - "#{short_id_url(root_url)}/#{self.title_as_url}" + def comments_url + "#{short_id_url}/#{self.title_as_url}" end - def short_id_url(root_url = "/") - root_url + "s/#{self.short_id}" + def short_id_url + Rails.application.routes.url_helpers.root_url + "s/#{self.short_id}" end @_comment_count = nil @@ -187,8 +187,8 @@ class Story < ActiveRecord::Base u.gsub(/^_+/, "").gsub(/_+$/, "") end - def url_or_comments_url(root_url = "/") - self.url.blank? ? self.comments_url(root_url) : self.url + def url_or_comments_url + self.url.blank? ? self.comments_url : self.url end def is_editable_by_user?(user) diff --git a/app/models/user.rb b/app/models/user.rb index cdaa281..c18fc66 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -40,11 +40,11 @@ class User < ActiveRecord::Base Keystore.value_for("user:#{self.id}:comments_posted").to_i end - def initiate_password_reset_for_ip(root_url, ip) + def initiate_password_reset_for_ip(ip) self.password_reset_token = Utils.random_str(40) self.save! - PasswordReset.password_reset_link(root_url, self, ip).deliver + PasswordReset.password_reset_link(self, ip).deliver end def linkified_about diff --git a/app/views/comments/_commentbox.html.erb b/app/views/comments/_commentbox.html.erb index e5db173..f432d9c 100644 --- a/app/views/comments/_commentbox.html.erb +++ b/app/views/comments/_commentbox.html.erb @@ -1,4 +1,4 @@ -
+
<%= form_tag("/comments/#{story.short_id}", { :id => "comment_form" }) do |f| %> <% if comment.parent_comment_short_id.present? %> <%= hidden_field_tag "parent_comment_short_id", diff --git a/app/views/email_reply/reply.text.erb b/app/views/email_reply/reply.text.erb new file mode 100644 index 0000000..58e1400 --- /dev/null +++ b/app/views/email_reply/reply.text.erb @@ -0,0 +1,7 @@ +<%= @comment.user.username %> has replied to you: + + <%= word_wrap(@comment.plaintext_comment, :line_width => 72).gsub(/\n/, "\n ") %> + +You can view this reply at: + +<%= @comment.url %> diff --git a/app/views/invitation_mailer/invitation.text.erb b/app/views/invitation_mailer/invitation.text.erb index 11cff69..25e840f 100644 --- a/app/views/invitation_mailer/invitation.text.erb +++ b/app/views/invitation_mailer/invitation.text.erb @@ -4,4 +4,4 @@ The user <%= @invitation.user.username %> has invited you to the website Lobster To create an account, visit the URL below: -<%= @root_url %>invitations/<%= @invitation.code %> +<%= root_url %>invitations/<%= @invitation.code %> diff --git a/app/views/password_reset/password_reset_link.text.erb b/app/views/password_reset/password_reset_link.text.erb index 67b36cc..985d829 100644 --- a/app/views/password_reset/password_reset_link.text.erb +++ b/app/views/password_reset/password_reset_link.text.erb @@ -4,4 +4,4 @@ Someone at <%= @ip %> requested to reset your account password on lobste.rs. If you submitted this request, visit the link below to set a new password. If not, you can disregard this e-mail. -<%= @root_url %>login/set_new_password?token=<%= @user.password_reset_token %> +<%= root_url %>login/set_new_password?token=<%= @user.password_reset_token %> diff --git a/extras/pushover.rb b/extras/pushover.rb new file mode 100644 index 0000000..bf75f13 --- /dev/null +++ b/extras/pushover.rb @@ -0,0 +1,23 @@ +class Pushover + cattr_accessor :API_KEY + + # this needs to be overridden in config/initializers/production.rb + @@API_KEY = nil + + def self.push(user, device, params) + if !@@API_KEY + return + end + + begin + s = Sponge.new + s.fetch("https://api.pushover.net/1/messages.json", :post, { + :token => @@API_KEY, + :user => user, + :device => device + }.merge(params)) + rescue => e + Rails.logger.error "error sending to pushover: #{e.inspect}" + end + end +end