messaging_4 0.0.1
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +39 -0
- data/app/assets/javascripts/messaging/adapt.js +135 -0
- data/app/assets/javascripts/messaging/application.js +10 -0
- data/app/assets/javascripts/messaging/messages.coffee +33 -0
- data/app/assets/stylesheets/messaging/1200.css +357 -0
- data/app/assets/stylesheets/messaging/1560.css +357 -0
- data/app/assets/stylesheets/messaging/1920.css +358 -0
- data/app/assets/stylesheets/messaging/2520.css +359 -0
- data/app/assets/stylesheets/messaging/720.css +357 -0
- data/app/assets/stylesheets/messaging/960.css +357 -0
- data/app/assets/stylesheets/messaging/application.css +8 -0
- data/app/assets/stylesheets/messaging/messages.sass +225 -0
- data/app/assets/stylesheets/messaging/mobile.css +26 -0
- data/app/assets/stylesheets/messaging/reset.css +48 -0
- data/app/controllers/messaging/application_controller.rb +9 -0
- data/app/controllers/messaging/messages_controller.rb +71 -0
- data/app/helpers/messaging/application_helper.rb +4 -0
- data/app/models/messaging/message.rb +35 -0
- data/app/views/layouts/messaging/application.html.haml +62 -0
- data/app/views/messaging/messages/index.html.haml +28 -0
- data/app/views/messaging/messages/new.html.haml +11 -0
- data/app/views/messaging/messages/show.html.haml +23 -0
- data/config/routes.rb +13 -0
- data/lib/generators/messaging/devise/devise_generator.rb +34 -0
- data/lib/generators/messaging/devise/templates/messaging_user.rb.erb +23 -0
- data/lib/generators/messaging/install/install_generator.rb +12 -0
- data/lib/messaging.rb +9 -0
- data/lib/messaging/engine.rb +5 -0
- data/lib/messaging/version.rb +3 -0
- data/lib/tasks/messaging_tasks.rake +4 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +9 -0
- data/test/dummy/app/assets/stylesheets/application.css +7 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/home_controller.rb +9 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/messaging_user.rb +23 -0
- data/test/dummy/app/models/user.rb +23 -0
- data/test/dummy/app/views/layouts/application.html.haml +11 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +45 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +32 -0
- data/test/dummy/config/environments/production.rb +60 -0
- data/test/dummy/config/environments/test.rb +39 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/devise.rb +209 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/mailboxer.rb +12 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/devise.en.yml +58 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +10 -0
- data/test/dummy/db/migrate/20111204041734_devise_create_users.rb +25 -0
- data/test/dummy/db/migrate/20111204042609_create_mailboxer.rb +61 -0
- data/test/dummy/db/migrate/20111204042610_add_notified_object.rb +17 -0
- data/test/dummy/db/migrate/20111204042611_add_notification_code.rb +13 -0
- data/test/dummy/db/migrate/20111205020919_add_attachments.rb +5 -0
- data/test/dummy/db/migrate/20111213052240_devise_create_messaging_users.rb +25 -0
- data/test/dummy/db/schema.rb +99 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +26 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/test/fixtures/messaging_users.yml +11 -0
- data/test/dummy/test/fixtures/users.yml +11 -0
- data/test/dummy/test/unit/messaging_user_test.rb +7 -0
- data/test/dummy/test/unit/user_test.rb +7 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/messaging_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +281 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
.grid_1,
|
2
|
+
.grid_2,
|
3
|
+
.grid_3,
|
4
|
+
.grid_4,
|
5
|
+
.grid_5,
|
6
|
+
.grid_6,
|
7
|
+
.grid_7,
|
8
|
+
.grid_8,
|
9
|
+
.grid_9,
|
10
|
+
.grid_10,
|
11
|
+
.grid_11,
|
12
|
+
.grid_12 {
|
13
|
+
margin-left: 10px;
|
14
|
+
margin-right: 10px;
|
15
|
+
}
|
16
|
+
|
17
|
+
.alpha,
|
18
|
+
.omega {
|
19
|
+
margin-left: 0;
|
20
|
+
margin-right: 0;
|
21
|
+
}
|
22
|
+
|
23
|
+
.align_center,
|
24
|
+
.align_right {
|
25
|
+
text-align: left;
|
26
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
/* http://meyerweb.com/eric/tools/css/reset/
|
2
|
+
v2.0 | 20110126
|
3
|
+
License: none (public domain)
|
4
|
+
*/
|
5
|
+
|
6
|
+
html, body, div, span, applet, object, iframe,
|
7
|
+
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
8
|
+
a, abbr, acronym, address, big, cite, code,
|
9
|
+
del, dfn, em, img, ins, kbd, q, s, samp,
|
10
|
+
small, strike, strong, sub, sup, tt, var,
|
11
|
+
b, u, i, center,
|
12
|
+
dl, dt, dd, ol, ul, li,
|
13
|
+
fieldset, form, label, legend,
|
14
|
+
table, caption, tbody, tfoot, thead, tr, th, td,
|
15
|
+
article, aside, canvas, details, embed,
|
16
|
+
figure, figcaption, footer, header, hgroup,
|
17
|
+
menu, nav, output, ruby, section, summary,
|
18
|
+
time, mark, audio, video {
|
19
|
+
margin: 0;
|
20
|
+
padding: 0;
|
21
|
+
border: 0;
|
22
|
+
font-size: 100%;
|
23
|
+
font: inherit;
|
24
|
+
vertical-align: baseline;
|
25
|
+
}
|
26
|
+
/* HTML5 display-role reset for older browsers */
|
27
|
+
article, aside, details, figcaption, figure,
|
28
|
+
footer, header, hgroup, menu, nav, section {
|
29
|
+
display: block;
|
30
|
+
}
|
31
|
+
body {
|
32
|
+
line-height: 1;
|
33
|
+
}
|
34
|
+
ol, ul {
|
35
|
+
list-style: none;
|
36
|
+
}
|
37
|
+
blockquote, q {
|
38
|
+
quotes: none;
|
39
|
+
}
|
40
|
+
blockquote:before, blockquote:after,
|
41
|
+
q:before, q:after {
|
42
|
+
content: '';
|
43
|
+
content: none;
|
44
|
+
}
|
45
|
+
table {
|
46
|
+
border-collapse: collapse;
|
47
|
+
border-spacing: 0;
|
48
|
+
}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Messaging
|
2
|
+
class MessagesController < Messaging::ApplicationController
|
3
|
+
def index
|
4
|
+
@box = params[:box] || 'inbox'
|
5
|
+
@messages = current_user.mailbox.inbox if @box == 'inbox'
|
6
|
+
@messages = current_user.mailbox.sentbox if @box == 'sent'
|
7
|
+
@messages = current_user.mailbox.trash if @box == 'trash'
|
8
|
+
end
|
9
|
+
|
10
|
+
def new
|
11
|
+
@message = Message.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def create
|
15
|
+
@message = Message.new params[:message]
|
16
|
+
|
17
|
+
if @message.conversation_id
|
18
|
+
@conversation = Conversation.find(@message.conversation_id)
|
19
|
+
unless @conversation.is_participant?(current_user)
|
20
|
+
flash[:alert] = "You do not have permission to view that conversation."
|
21
|
+
return redirect_to root_path
|
22
|
+
end
|
23
|
+
receipt = current_user.reply_to_conversation(@conversation, @message.body, nil, true, true, @message.attachment)
|
24
|
+
else
|
25
|
+
unless @message.valid?
|
26
|
+
return render :new
|
27
|
+
end
|
28
|
+
receipt = current_user.send_message(@message.recipients, @message.body, @message.subject, true, @message.attachment)
|
29
|
+
end
|
30
|
+
flash[:notice] = "Message sent."
|
31
|
+
|
32
|
+
redirect_to message_path(receipt.conversation)
|
33
|
+
end
|
34
|
+
|
35
|
+
def show
|
36
|
+
@conversation = Conversation.find_by_id(params[:id])
|
37
|
+
unless @conversation.is_participant?(current_user)
|
38
|
+
flash[:alert] = "You do not have permission to view that conversation."
|
39
|
+
return redirect_to root_path
|
40
|
+
end
|
41
|
+
@message = Message.new conversation_id: @conversation.id
|
42
|
+
current_user.read(@conversation)
|
43
|
+
end
|
44
|
+
|
45
|
+
def trash
|
46
|
+
conversation = Conversation.find_by_id(params[:id])
|
47
|
+
if conversation
|
48
|
+
current_user.trash(conversation)
|
49
|
+
flash[:notice] = "Message sent to trash."
|
50
|
+
else
|
51
|
+
conversations = Conversation.find(params[:conversations])
|
52
|
+
conversations.each { |c| current_user.trash(c) }
|
53
|
+
flash[:notice] = "Messages sent to trash."
|
54
|
+
end
|
55
|
+
redirect_to messages_path(box: params[:current_box])
|
56
|
+
end
|
57
|
+
|
58
|
+
def untrash
|
59
|
+
conversation = Conversation.find(params[:id])
|
60
|
+
current_user.untrash(conversation)
|
61
|
+
flash[:notice] = "Message untrashed."
|
62
|
+
redirect_to messages_path(box: 'inbox')
|
63
|
+
end
|
64
|
+
|
65
|
+
def search
|
66
|
+
@search = params[:search]
|
67
|
+
@messages = current_user.search_messages(@search)
|
68
|
+
render :index
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Messaging
|
2
|
+
class Message
|
3
|
+
include ActiveModel::Validations
|
4
|
+
include ActiveModel::Conversion
|
5
|
+
extend ActiveModel::Naming
|
6
|
+
|
7
|
+
attr_accessor :recipients, :subject, :body, :conversation_id, :attachment
|
8
|
+
|
9
|
+
validates :recipients, presence: true
|
10
|
+
validates :subject, presence: true
|
11
|
+
validates :body, presence: true
|
12
|
+
|
13
|
+
def initialize(attributes = {})
|
14
|
+
attributes.each do |name, value|
|
15
|
+
send("#{name}=", value)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def persisted?
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def recipients
|
25
|
+
@recipient_list
|
26
|
+
end
|
27
|
+
|
28
|
+
def recipients=(string='')
|
29
|
+
@recipient_list = []
|
30
|
+
string.split(',').each do |s|
|
31
|
+
@recipient_list << MessagingUser.find_by_email!(s.strip) unless s.blank?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%title Messaging
|
5
|
+
%noscript
|
6
|
+
= stylesheet_link_tag "messaging/mobile"
|
7
|
+
:javascript
|
8
|
+
// Edit to suit your needs.
|
9
|
+
var ADAPT_CONFIG = {
|
10
|
+
path: '#{request.protocol}#{request.host}:#{request.port}',
|
11
|
+
dynamic: true,
|
12
|
+
range: [
|
13
|
+
'0px to 760px = #{asset_path('messaging/mobile.css')}',
|
14
|
+
'760px to 980px = #{asset_path('messaging/720.css')}',
|
15
|
+
'980px to 1280px = #{asset_path('messaging/960.css')}',
|
16
|
+
'1280px to 1600px = #{asset_path('messaging/1200.css')}',
|
17
|
+
'1600px = #{asset_path('messaging/1560.css')}',
|
18
|
+
]
|
19
|
+
};
|
20
|
+
= stylesheet_link_tag "messaging/application"
|
21
|
+
= javascript_include_tag "messaging/adapt"
|
22
|
+
= javascript_include_tag "messaging/application"
|
23
|
+
= csrf_meta_tags
|
24
|
+
%body
|
25
|
+
#wrapper
|
26
|
+
%header
|
27
|
+
.container_12
|
28
|
+
.grid_12
|
29
|
+
%h1 Messaging
|
30
|
+
= link_to "Sign out", '/messaging_users/sign_out', method: :delete, class: 'sign-out'
|
31
|
+
- if notice
|
32
|
+
#notice
|
33
|
+
.container_12
|
34
|
+
.grid_12= notice
|
35
|
+
- if alert
|
36
|
+
#alert
|
37
|
+
.container_12
|
38
|
+
.grid_12= alert
|
39
|
+
#content.container_12
|
40
|
+
.grid_2
|
41
|
+
%nav
|
42
|
+
= link_to "Compose", new_message_path, class: 'compose'
|
43
|
+
-if @box == 'inbox'
|
44
|
+
= link_to "Inbox", messages_path(box: 'inbox'), class: 'selected'
|
45
|
+
-else
|
46
|
+
= link_to "Inbox", messages_path(box: 'inbox')
|
47
|
+
-if @box == 'sent'
|
48
|
+
= link_to "Sent", messages_path(box: 'sent'), class: 'selected'
|
49
|
+
-else
|
50
|
+
= link_to "Sent", messages_path(box: 'sent')
|
51
|
+
-if @box == 'trash'
|
52
|
+
= link_to "Trash", messages_path(box: 'trash'), class: 'selected'
|
53
|
+
-else
|
54
|
+
= link_to "Trash", messages_path(box: 'trash')
|
55
|
+
= form_tag search_path do
|
56
|
+
%input{ type: 'search', placeholder: 'Search', name: 'search' }
|
57
|
+
#main.grid_10
|
58
|
+
= yield
|
59
|
+
#footer
|
60
|
+
.container_12
|
61
|
+
.grid_12
|
62
|
+
=link_to "Rails Messaging", "http://github.com/frodefi/rails-messaging/"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
- if @search
|
2
|
+
%h2 Search results for '#{@search}'
|
3
|
+
- if @box == 'inbox'
|
4
|
+
%h2 Inbox
|
5
|
+
- if @box == 'sent'
|
6
|
+
%h2 Sent
|
7
|
+
- if @box == 'trash'
|
8
|
+
%h2 Trash
|
9
|
+
= form_tag trash_messages_path, method: :delete do
|
10
|
+
= hidden_field_tag 'current_box', @box
|
11
|
+
%table#box
|
12
|
+
%tr
|
13
|
+
- unless @box == 'trash'
|
14
|
+
%th
|
15
|
+
%th Sender
|
16
|
+
%th Subject
|
17
|
+
%th Messages
|
18
|
+
%th
|
19
|
+
- @messages.each do |m|
|
20
|
+
%tr{ class: "#{ 'unread' if m.is_unread?(current_messaging_user) }" }
|
21
|
+
- unless @box == 'trash'
|
22
|
+
%td= check_box_tag '', m.id, false, class: 'delete_multiple_checkbox', name: "conversations[]"
|
23
|
+
%td= link_to m.last_sender, message_path(m)
|
24
|
+
%td= link_to m.subject, message_path(m)
|
25
|
+
%td= link_to m.count_messages, message_path(m)
|
26
|
+
%td= link_to truncate(m.last_message.body), message_path(m)
|
27
|
+
- unless @box == 'trash'
|
28
|
+
= submit_tag "Delete checked messages", id: 'delete_multiple_button'
|
@@ -0,0 +1,11 @@
|
|
1
|
+
%h2 Compose
|
2
|
+
#compose
|
3
|
+
= simple_form_for @message do |f|
|
4
|
+
= f.label :recipients, required: false
|
5
|
+
= f.input_field :recipients, data: { autocomplete_source: MessagingUser.all.map(&:name) }
|
6
|
+
= f.label :subject, required: false
|
7
|
+
= f.input_field :subject
|
8
|
+
= f.label :body, required: false
|
9
|
+
= f.input_field :body, as: :text
|
10
|
+
= f.input :attachment, as: :file
|
11
|
+
= f.button :submit, 'Send message'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#actions
|
2
|
+
- if @conversation.is_trashed?(current_messaging_user)
|
3
|
+
= link_to "Untrash", untrash_message_path(@conversation), class: :button, method: :post
|
4
|
+
- else
|
5
|
+
= link_to "Trash", trash_message_path(@conversation), class: :button, method: :delete
|
6
|
+
%h2.subject= @conversation.subject
|
7
|
+
%ul#conversation
|
8
|
+
- @conversation.messages.each do |message|
|
9
|
+
%li
|
10
|
+
.head
|
11
|
+
.from= message.sender
|
12
|
+
.date #{message.created_at.to_s(:long)} (#{time_ago_in_words(message.created_at)} ago)
|
13
|
+
.body= message.body
|
14
|
+
- if message.attachment.url
|
15
|
+
.attachment
|
16
|
+
= link_to message.attachment_identifier, message.attachment.url
|
17
|
+
#reply
|
18
|
+
= simple_form_for @message do |f|
|
19
|
+
= f.input :conversation_id, as: :hidden
|
20
|
+
= f.label :body, label: 'Reply', required: false
|
21
|
+
= f.input_field :body, as: :text, label: 'Reply'
|
22
|
+
= f.input :attachment, as: :file
|
23
|
+
= f.button :submit, 'Reply to conversation'
|
data/config/routes.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module Messaging
|
2
|
+
module Generators
|
3
|
+
class DeviseGenerator < Rails::Generators::NamedBase
|
4
|
+
desc "Uses Devise for authentication"
|
5
|
+
|
6
|
+
argument :name, :type => :string, :default => "MessagingUser"
|
7
|
+
|
8
|
+
|
9
|
+
def self.source_root
|
10
|
+
@_messaging_source_root ||= File.expand_path("../templates", __FILE__)
|
11
|
+
end
|
12
|
+
|
13
|
+
def install_devise
|
14
|
+
require 'devise'
|
15
|
+
if File.exists?(File.join(destination_root, "config", "initializers", "devise.rb"))
|
16
|
+
log :generate, "No need to install devise, already done."
|
17
|
+
else
|
18
|
+
log :generate, "devise:install"
|
19
|
+
invoke "devise:install"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_user
|
24
|
+
invoke "devise", [name]
|
25
|
+
end
|
26
|
+
|
27
|
+
def copy_model
|
28
|
+
template 'messaging_user.rb.erb', 'app/models/messaging_user.rb'
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class MessagingUser < ActiveRecord::Base
|
2
|
+
# Include default devise modules. Others available are:
|
3
|
+
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
|
4
|
+
devise :database_authenticatable, :registerable,
|
5
|
+
:recoverable, :rememberable, :trackable, :validatable
|
6
|
+
|
7
|
+
# Setup accessible (or protected) attributes for your model
|
8
|
+
attr_accessible :email, :password, :password_confirmation, :remember_me
|
9
|
+
include Mailboxer::Models::Messageable
|
10
|
+
acts_as_messageable
|
11
|
+
|
12
|
+
def name
|
13
|
+
self.to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
def mailboxer_email(message)
|
17
|
+
email
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
email
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Messaging::InstallGenerator < Rails::Generators::Base #:nodoc:
|
2
|
+
|
3
|
+
hook_for :users, :default => "devise", :desc => "User generator to run. Skip with --skip-users"
|
4
|
+
|
5
|
+
def create_migration_file
|
6
|
+
generate 'mailboxer:install'
|
7
|
+
end
|
8
|
+
|
9
|
+
def add_messaging_routes
|
10
|
+
route 'mount Messaging::Engine => "/messaging"'
|
11
|
+
end
|
12
|
+
end
|
data/lib/messaging.rb
ADDED