summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMrYummy <elemental428@gmail.com>2017-06-15 14:27:42 +0200
committerMrYummy <elemental428@gmail.com>2017-06-15 14:29:25 +0200
commit9b50ec652cd8f80a16bd82987bd9f8eba389a2eb (patch)
treeef45cb2d37e8a49245b6b7a17562a0d3cf2b1dc0
parent80026caebc9f0cffeba3153949b393b2df64f12f (diff)
Made messages more thread-like (replies, editing, etc.)
-rw-r--r--app/controllers/messagereplies_controller.rb77
-rw-r--r--app/controllers/messages_controller.rb50
-rw-r--r--app/models/message.rb34
-rw-r--r--app/models/messagereply.rb67
-rw-r--r--app/models/user.rb2
-rw-r--r--app/views/forumthreads/show.html.erb2
-rw-r--r--app/views/messagereplies/_new.html.erb5
-rw-r--r--app/views/messagereplies/_reply.html.erb17
-rw-r--r--app/views/messagereplies/edit.html.erb15
-rw-r--r--app/views/messages/edit.html.erb17
-rw-r--r--app/views/messages/index.html.erb34
-rw-r--r--app/views/messages/show.html.erb33
-rw-r--r--app/views/threadreplies/_new.html.erb2
-rw-r--r--app/views/threadreplies/edit.html.erb2
-rw-r--r--app/views/users/show.html.erb4
-rw-r--r--config/routes.rb1
-rw-r--r--db/migrate/20170524181458_create_messages.rb3
-rw-r--r--db/migrate/20170613021450_create_messagereplies.rb13
-rw-r--r--db/migrate/20170613144233_add_user_editor_to_messages.rb5
-rw-r--r--db/schema.rb15
-rw-r--r--db/seeds.rb3
21 files changed, 380 insertions, 21 deletions
diff --git a/app/controllers/messagereplies_controller.rb b/app/controllers/messagereplies_controller.rb
new file mode 100644
index 0000000..e01501b
--- /dev/null
+++ b/app/controllers/messagereplies_controller.rb
@@ -0,0 +1,77 @@
+class MessagerepliesController < ApplicationController
+
+ def edit
+ @reply = Messagereply.find(params[:id])
+ if mod? || @reply.author.is?(current_user)
+ else
+ flash[:alert] = "You are not allowed to edit this reply"
+ redirect_to @reply.message
+ end
+ end
+
+ def create
+ message = Message.find(params[:message_id])
+ if [message.user_sender, message.user_target].include? current_user
+ @reply = Messagereply.new(reply_params)
+ @reply.user_author = current_user
+ @reply.message = message
+ if @reply.save
+ @reply.message.update_attributes(user_hidden: nil)
+ if false
+ @reply.send_new_message_reply_mail
+ end
+ position = message.replies.count - 1
+ page = position / Kaminari.config.default_per_page + 1
+ redirect_to message_path(@reply.message, page: page) + "#reply-#{@reply.id}", notice: 'Reply created!'
+ else
+ flash[:alert] = "Could not create reply."
+ redirect_to Message.find(params[:message_id])
+ end
+ else
+ flash[:alert] = "You are not allowed to create replies."
+ redirect_to Message.find(params[:message_id])
+ end
+ end
+
+ def update
+ @reply = Messagereply.find(params[:id])
+ if mod? || @reply.author.is?(current_user)
+ old_content = @reply.text_was
+ if @reply.update_attributes(reply_params)
+ if false
+ @reply.send_new_reply_mail(old_content)
+ end
+ flash[:notice] = "Reply updated!"
+ position = @reply.message.replies.index(@reply)
+ page = position / Kaminari.config.default_per_page + 1
+ redirect_to message_path(@reply.message, page: page) + "#reply-#{@reply.id}"
+ else
+ flash[:alert] = "There was a problem while updating your reply"
+ render action: "edit"
+ end
+ else
+ flash[:alert] = "You are not allowed to edit this reply"
+ redirect_to @reply.message
+ end
+ end
+
+ def destroy
+ @reply = Messagereply.find(params[:id])
+ if mod? || @reply.author.is?(current_user)
+ if @reply.destroy
+ flash[:notice] = "Reply deleted!"
+ else
+ flash[:alert] = "There was a problem while deleting this reply"
+ end
+ else
+ flash[:alert] = "You are not allowed to delete this reply"
+ end
+ redirect_to @reply.message
+ end
+
+ private
+
+ def reply_params
+ params.require(:messagereply).permit(:text)
+ end
+end
diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb
index 480a671..8f618d3 100644
--- a/app/controllers/messages_controller.rb
+++ b/app/controllers/messages_controller.rb
@@ -1,16 +1,32 @@
class MessagesController < ApplicationController
- before_filter :check_permission, only: :destroy
+ before_filter :set_current
+ def set_current
+ User.current = current_user
+ end
+
+ before_filter :check_permission, only: [:show, :edit, :update, :destroy]
def index
if current_user
- @messages = Message.where(user_target: current_user).page(params[:page])
+ @messages = Message.where("(user_sender_id = ? OR user_target_id = ?) AND (user_hidden_id != ? OR user_hidden_id IS NULL)", current_user.id, current_user.id, current_user.id).page(params[:page])
else
flash[:alert] = "Please log in to see your private messages."
redirect_to blogposts_path
end
end
+ def show
+ @replies = @message.replies.page(params[:page])
+ end
+
+ def edit
+ unless mod? || @message.author.is?(current_user)
+ flash[:alert] = "You are not allowed to edit this message!"
+ redirect_to @message
+ end
+ end
+
def new
if current_user
@message = Message.new
@@ -47,12 +63,32 @@ class MessagesController < ApplicationController
end
end
+ def update
+ if mod? || @message.user_sender.is?(current_user)
+ @message.user_editor_id = current_user.id
+ @message.attributes = message_params
+ if @message.save
+ redirect_to @message, notice: 'Message has been updated.'
+ else
+ flash[:alert] = "There was a problem while updating the message."
+ render action: "edit"
+ end
+ else
+ flash[:alert] = "You are not allowed to edit this message!"
+ redirect_to @message
+ end
+ end
+
def destroy
- if @message.user_target.is?(current_user)
+ if [@message.user_target, @message.user_sender].include?(current_user)
if @message.destroy
flash[:notice] = "Message deleted!"
else
- flash[:alert] = "There was a problem while deleting this message."
+ unless @message.user_hidden
+ flash[:alert] = "There was a problem while deleting this message."
+ else
+ Message.find(@message.id).update_attributes(user_hidden: current_user)
+ end
end
else
flash[:alert] = "You are not allowed to delete this message."
@@ -73,15 +109,15 @@ class MessagesController < ApplicationController
def message_params(add = [])
params[:message][:user_target_id] = User.find_by(ign: params[:message][:user_target].strip).try(:id)
params[:message][:user_sender_id] = User.find_by(ign: params[:message][:user_sender]).id
-
- params.require(:message).permit([:subject, :text, :user_target_id, :user_sender_id])
+ params[:message][:user_hidden_id] = User.find_by(ign: params[:message][:user_hidden]).try(:id)
+params.require(:message).permit([:subject, :text, :user_target_id, :user_sender_id])
end
private
def check_permission
@message = Message.find(params[:id])
- unless @message.user_target == current_user
+ unless [@message.user_target, @message.user_sender].include? current_user
flash[:alert] = "You are not allowed to view this message"
redirect_to home_statics_path
end
diff --git a/app/models/message.rb b/app/models/message.rb
index 3c5ad58..35c47ef 100644
--- a/app/models/message.rb
+++ b/app/models/message.rb
@@ -4,12 +4,34 @@ class Message < ActiveRecord::Base
belongs_to :user_sender, class_name: "User", foreign_key: "user_sender_id"
belongs_to :user_target, class_name: "User", foreign_key: "user_target_id"
+ belongs_to :user_editor, class_name: "User", foreign_key: "user_editor_id"
+ belongs_to :user_hidden, class_name: "User", foreign_key: "user_hidden_id"
+
validates_presence_of :user_sender, :user_target, :text, :subject
validates_length_of :text, in: 1..8000
validates_length_of :subject, in: 1..2000
+ has_many :messagereplies
+
+ accepts_nested_attributes_for :messagereplies
+
+ before_destroy :do_destroy?
+
+ def do_destroy?
+ unless user_hidden || user_sender == user_target
+ update_attributes(user_hidden: User.current)
+ return false
+ else
+ return true
+ end
+ end
+
+ def to_s
+ subject
+ end
+
def sender
@sender ||= if self.user_sender.present?
user_sender
@@ -26,6 +48,18 @@ class Message < ActiveRecord::Base
end
end
+ def editor
+ @editor ||= (self.user_editor || User.first)
+ end
+
+ def edited?
+ !!user_editor_id
+ end
+
+ def replies
+ messagereplies
+ end
+
def send_new_message_mail
begin
mail = RedstonerMailer.new_message_mail(user_target, self)
diff --git a/app/models/messagereply.rb b/app/models/messagereply.rb
new file mode 100644
index 0000000..390ed12
--- /dev/null
+++ b/app/models/messagereply.rb
@@ -0,0 +1,67 @@
+class Messagereply < ActiveRecord::Base
+
+ include MailerHelper
+ include UsersHelper
+
+ belongs_to :message
+ belongs_to :user_author, class_name: "User", foreign_key: "user_author_id"
+ belongs_to :user_editor, class_name: "User", foreign_key: "user_editor_id"
+
+
+
+ validates_presence_of :text
+ validates_length_of :text, in: 1..8000
+
+ def get_message
+ message
+ end
+
+ def author
+ @author ||= if self.user_author.present?
+ user_author
+ else
+ User.first
+ end
+ end
+
+ def editor
+ # can be nil
+ @editor ||= user_editor
+ end
+
+ def edited?
+ !!user_editor_id
+ end
+
+ def send_new_reply_mail(old_content = "")
+ users = mentions(content) - mentions(old_content)
+
+ # thread + replies
+ posts = message.replies.to_a
+ posts << message if message.author.mail_own_message_reply?
+ # only send "reply" mail when reply is new
+ unless old_content.present?
+ posts.each do |post|
+ # don't send mail to the author of this reply, don't send to banned/disabled users
+ if post.author != author && post.author.normal? && post.author.confirmed? # &&
+ users << post.author if post.author.mail_other_thread_reply?
+ end
+ end
+ end
+ # making sure we don't send multiple mails to the same user
+ users.uniq!
+
+ mails = []
+ users.each do |usr|
+ begin
+ mails << RedstonerMailer.new_thread_reply_mail(usr, self)
+ rescue => e
+ Rails.logger.error "---"
+ Rails.logger.error "WARNING: Failed to create new_thread_reply_mail (view) for reply#: #{@self.id}, user: #{@user.name}, #{@user.email}"
+ Rails.logger.error e.message
+ Rails.logger.error "---"
+ end
+ end
+ background_mailer(mails)
+ end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 9ddd4f0..4d06f80 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -24,6 +24,8 @@ class User < ActiveRecord::Base
has_many :blogposts
has_many :comments
+ cattr_accessor :current
+
# foo.bar.is?(current_user)
def is? (user)
self == user
diff --git a/app/views/forumthreads/show.html.erb b/app/views/forumthreads/show.html.erb
index 876d55d..ffec8c7 100644
--- a/app/views/forumthreads/show.html.erb
+++ b/app/views/forumthreads/show.html.erb
@@ -44,4 +44,4 @@
<% else %>
<p>Please <%= link_to "Log in", login_path(return_path: request.env['PATH_INFO']), action: "new" %> to post a reply.</p>
<% end %>
-</div> \ No newline at end of file
+</div>
diff --git a/app/views/messagereplies/_new.html.erb b/app/views/messagereplies/_new.html.erb
new file mode 100644
index 0000000..a7b7780
--- /dev/null
+++ b/app/views/messagereplies/_new.html.erb
@@ -0,0 +1,5 @@
+<%= form_for [reply.get_message, reply] do |f| %>
+ <%= render partial: "md_editor", locals: {name: "messagereply[text]", content: reply.text} %>
+ <p><%= f.submit "Reply", class: "btn blue" %></p>
+<% end %>
+
diff --git a/app/views/messagereplies/_reply.html.erb b/app/views/messagereplies/_reply.html.erb
new file mode 100644
index 0000000..c17121a
--- /dev/null
+++ b/app/views/messagereplies/_reply.html.erb
@@ -0,0 +1,17 @@
+<div class="item-group thread-reply with-avatar" id="reply-<%= reply.id %>">
+ <div class="header">
+ <%= link_to(reply.author.avatar(64), reply.author, title: reply.author.ign) %>
+ <%= render partial: "users/username", locals: { user: reply.author } %>
+ <%= link_to "#reply-#{reply.id}" do %>
+ <%= ago reply.created_at %>
+ <% end %>
+
+ <%= link_to "edit", edit_message_messagereply_path(reply.message, reply), class: "editlink" if mod? || reply.author.is?(current_user) %>
+ <div class="clear-right"></div>
+ </div>
+ <div class="items">
+ <div class="item content">
+ <%= render_md(reply.text).html_safe %>
+ </div>
+ </div>
+</div>
diff --git a/app/views/messagereplies/edit.html.erb b/app/views/messagereplies/edit.html.erb
new file mode 100644
index 0000000..978acd5
--- /dev/null
+++ b/app/views/messagereplies/edit.html.erb
@@ -0,0 +1,15 @@
+<% title "Edit Message Reply: #{@reply.message.subject}" %>
+
+<%
+ position = @reply.message.replies.index(@reply)
+ page = position / Kaminari.config.default_per_page + 1
+%>
+
+<%= link_to "Messages", messages_path %> → <%= link_to @reply.message, message_path(@reply.message, page: page) + "#reply-#{@reply.id}" %> → Edit reply
+<h1>Edit reply</h1>
+<%= form_for [@reply.message, @reply] do |f| %>
+ <%= render partial: "md_editor", locals: {name: "messagereply[text]", content: @reply.text} %>
+ <p><%= f.submit "Reply", class: "btn blue left" %></p>
+<% end %>
+<p><%= button_to "Delete reply", [@reply.message, @reply], method: "delete", data: {confirm: "Delete reply forever?"}, class: "btn red right" %></p>
+<div class="clear"></div>
diff --git a/app/views/messages/edit.html.erb b/app/views/messages/edit.html.erb
new file mode 100644
index 0000000..c1ad1ed
--- /dev/null
+++ b/app/views/messages/edit.html.erb
@@ -0,0 +1,17 @@
+<% title "Edit Thread: #{@message}" %>
+
+<h1>Edit thread</h1>
+<%= link_to "Messages", messages_path %> → <%= link_to @message, @message %> → Edit Message
+<%= form_for @message do |f|%>
+ <div class="table-cell full-width">
+ <%= f.text_field :subject, placeholder: "Subject" %>
+ </div>
+ <br>
+ <%= render partial: "md_editor", locals: {name: "message[text]", content: @message.text} %>
+ <p><%= f.submit "Update message", class: "btn blue left" %></p>
+ <%= f.hidden_field :user_sender, value: @message.user_sender %>
+ <%= f.hidden_field :user_target, value: @message.user_target %>
+<% end %>
+<%= button_to "Delete ", @message, :method => "delete", data: {confirm: "Delete message & comments forever?"}, class: "btn red right" %>
+<div class="clear"></div>
+
diff --git a/app/views/messages/index.html.erb b/app/views/messages/index.html.erb
index 036243d..de78f9b 100644
--- a/app/views/messages/index.html.erb
+++ b/app/views/messages/index.html.erb
@@ -15,13 +15,21 @@
<% @messages.each do |message| %>
<div class="item-group with-avatar">
<div class="header">
- <%= link_to(message.user_sender.avatar(64), message.user_sender, title: message.user_sender.ign) %>
- <%= render partial: "users/username", locals: { user: message.user_sender } %>
- <%= ago message.created_at %>
- <span style="font-size:18px">
+ <%
+ if current_user == message.user_sender
+ user = message.user_target
+ else
+ user = message.user_sender
+ end
+ %>
+ <%= link_to(user.avatar(64), user, title: user.ign) %>
+ <%= render partial: "users/username", locals: { user: user } %>
+ <span style="font-size:16px">
+ &nbsp;
+ <b><%= link_to message.subject, message %></b>
&nbsp; | &nbsp;
- <b><%= link_to message.subject, messages_path %></b>
</span>
+ <%= ago message.created_at %>
<div class="right">
<%= link_to "Delete message", message, :method => "delete", class: "editlink", data: {confirm: "Delete this message forever?"} %>
</div>
@@ -29,7 +37,21 @@
</div>
<div class="items">
<div class="item">
- <%= render_md(truncate message.text, length: 20, omission: "...").html_safe %>
+ <%= truncate message.text, length: 20, omission: "..." %>
+ <div class="item-info items bold">
+ <% if rpl = message.replies.last %>
+ <%= rpl.author.name %>
+ <%
+ position = message.replies.count - 1
+ page = position / Kaminari.config.default_per_page + 1
+ %>
+ <%= link_to "replied", message_path(message, page: page) + "#reply-#{rpl.id}" %>
+ <%= ago rpl.created_at %>.
+ <% else %>
+ No replies yet.
+ <% end %>
+ </div>
+ <div class="clear"></div>
</div>
</div>
</div>
diff --git a/app/views/messages/show.html.erb b/app/views/messages/show.html.erb
index e69de29..6413d30 100644
--- a/app/views/messages/show.html.erb
+++ b/app/views/messages/show.html.erb
@@ -0,0 +1,33 @@
+<%= link_to "Messages", messages_path %>
+<h1><%= title @message.subject %></h1>
+<div class="item-group thread with-avatar" id="message-<%= @message.id %>">
+ <div class="header">
+ <%= link_to(@message.sender.avatar(64), @message.sender, title: @message.sender.ign) %>
+ <%= render partial: "users/username", locals: { user: @message.sender } %>
+ <%= link_to p do %>
+ <%= ago @message.created_at %>
+ <% end %>
+ <%= link_to "edit", edit_message_path(@message), class: "editlink" if mod? || @message.sender.is?(current_user) %>
+ <div class="clear-right"></div>
+ </div>
+ <div class="items">
+ <% if @message.edited? %>
+ <div class="item edited">
+ Last edited <%= ago @message.updated_at %> by <%= link_to @message.editor.name, @message.editor %>.
+ </div>
+ <% end %>
+ <div class="item content">
+ <%= render_md(@message.text).html_safe %>
+ </div>
+ </div>
+</div>
+<div id="replies">
+ <h3><%= "#{pluralize(@message.replies.size, 'reply')}." %></h3>
+ <% @replies.each do |reply| %>
+ <%= render partial: "messagereplies/reply", locals: {reply: reply} %>
+ <% end %>
+
+ <%= paginate @replies %>
+
+ <%= render partial: "messagereplies/new", locals: {reply: Messagereply.new(message: @message)} %>
+</div>
diff --git a/app/views/threadreplies/_new.html.erb b/app/views/threadreplies/_new.html.erb
index b0c4b5e..bdf9df8 100644
--- a/app/views/threadreplies/_new.html.erb
+++ b/app/views/threadreplies/_new.html.erb
@@ -1,4 +1,4 @@
<%= form_for [reply.thread, reply] do |f| %>
<%= render partial: "md_editor", locals: {name: "threadreply[content]", content: reply.content} %>
<p><%= f.submit "Reply#{ ' (Locked)' if reply.thread.locked? }", class: "btn blue" %></p>
-<% end %> \ No newline at end of file
+<% end %>
diff --git a/app/views/threadreplies/edit.html.erb b/app/views/threadreplies/edit.html.erb
index c009cb0..d14966a 100644
--- a/app/views/threadreplies/edit.html.erb
+++ b/app/views/threadreplies/edit.html.erb
@@ -12,4 +12,4 @@
<p><%= f.submit "Reply", class: "btn blue left" %></p>
<% end %>
<p><%= button_to "Delete reply", [@reply.thread, @reply], method: "delete", data: {confirm: "Delete reply forever?"}, class: "btn red right" %></p>
-<div class="clear"></div> \ No newline at end of file
+<div class="clear"></div>
diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb
index d9eb123..a48eae2 100644
--- a/app/views/users/show.html.erb
+++ b/app/views/users/show.html.erb
@@ -11,8 +11,8 @@
<%= link_to "edit profile", edit_user_path(@user), :class => "btn blue" %>
<% end %>
<% if @user.is?(current_user) %>
- <%= link_to "Private Messages (#{Message.where(user_target: current_user).count})", messages_path, :class => "btn blue" %>
- <% else %>
+ <%= link_to "Private Messages (#{Message.where("user_sender_id = ? OR user_target_id = ?", current_user.id, current_user.id).count})", messages_path, :class => "btn blue" %>
+ <% elsif current_user %>
<%= link_to "Send this user a message", new_message_path(user_target: @user.ign), :class => "btn blue" %>
<% end %>
</div>
diff --git a/config/routes.rb b/config/routes.rb
index 309b96a..12330d4 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -42,6 +42,7 @@ Redstoner::Application.routes.draw do
end
resources :messages do
+ resources :messagereplies, path: 'replies'
collection do
post 'destroy_all'
end
diff --git a/db/migrate/20170524181458_create_messages.rb b/db/migrate/20170524181458_create_messages.rb
index a07fd9d..b253742 100644
--- a/db/migrate/20170524181458_create_messages.rb
+++ b/db/migrate/20170524181458_create_messages.rb
@@ -1,10 +1,11 @@
class CreateMessages < ActiveRecord::Migration
def change
create_table :messages do |t|
-
t.text :message
t.references :user_sender
t.references :user_target
+ t.references :user_editor
+ t.references :user_hidden
t.datetime :created_at
end
end
diff --git a/db/migrate/20170613021450_create_messagereplies.rb b/db/migrate/20170613021450_create_messagereplies.rb
new file mode 100644
index 0000000..21ef3bc
--- /dev/null
+++ b/db/migrate/20170613021450_create_messagereplies.rb
@@ -0,0 +1,13 @@
+class CreateMessagereplies < ActiveRecord::Migration
+ def change
+ create_table :messagereplies do |t|
+ t.text :text
+
+ t.references :user_author
+ t.references :user_editor
+ t.references :message
+
+ t.timestamps null: true
+ end
+ end
+end
diff --git a/db/migrate/20170613144233_add_user_editor_to_messages.rb b/db/migrate/20170613144233_add_user_editor_to_messages.rb
new file mode 100644
index 0000000..cc4c7f7
--- /dev/null
+++ b/db/migrate/20170613144233_add_user_editor_to_messages.rb
@@ -0,0 +1,5 @@
+class AddUserEditorToMessages < ActiveRecord::Migration
+ def change
+ add_reference :messages, :user_editor
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 9c631a8..269d20e 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20170525184355) do
+ActiveRecord::Schema.define(version: 20170613144233) do
create_table "blogposts", force: :cascade do |t|
t.string "title", limit: 191
@@ -76,11 +76,24 @@ ActiveRecord::Schema.define(version: 20170525184355) do
t.string "color", limit: 191
end
+ create_table "messagereplies", force: :cascade do |t|
+ t.text "text", limit: 65535
+ t.integer "user_author_id", limit: 4
+ t.integer "user_editor_id", limit: 4
+ t.integer "message_id", limit: 4
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
create_table "messages", force: :cascade do |t|
t.text "text", limit: 65535
t.integer "user_sender_id", limit: 4
t.integer "user_target_id", limit: 4
+ t.integer "user_hidden_id", limit: 4
t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "subject", limit: 191
+ t.integer "user_editor_id", limit: 4
end
create_table "register_tokens", force: :cascade do |t|
diff --git a/db/seeds.rb b/db/seeds.rb
index 78097d8..6c4946d 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -61,5 +61,6 @@ Message.create!(
user_sender_id: 2,
user_target_id: 2,
text: "This is a very long message that I will be using to test a plentitude of things. :)",
- created_at: Time.utc(0).to_datetime
+ created_at: Time.utc(0).to_datetime,
+ subject: "Hello there!"
)