has_messages_generators 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (23) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.mdown +43 -0
  3. data/lib/generators/base.rb +179 -0
  4. data/lib/generators/has_messages/install/USAGE +10 -0
  5. data/lib/generators/has_messages/install/install_generator.rb +126 -0
  6. data/lib/generators/has_messages/install/templates/README +26 -0
  7. data/lib/generators/has_messages/install/templates/assets/javascripts/jquery.tokeninput.js +718 -0
  8. data/lib/generators/has_messages/install/templates/assets/javascripts/messages.js +19 -0
  9. data/lib/generators/has_messages/install/templates/assets/stylesheets/messages.css +107 -0
  10. data/lib/generators/has_messages/install/templates/assets/stylesheets/token-input-facebook.css +122 -0
  11. data/lib/generators/has_messages/install/templates/controllers/messages_controller.rb +111 -0
  12. data/lib/generators/has_messages/install/templates/helpers/messages_helper.rb +2 -0
  13. data/lib/generators/has_messages/install/templates/lib/has_messages.rb +67 -0
  14. data/lib/generators/has_messages/install/templates/models/create_messages.rb +24 -0
  15. data/lib/generators/has_messages/install/templates/models/message.rb +67 -0
  16. data/lib/generators/has_messages/install/templates/views/_head.html.erb +20 -0
  17. data/lib/generators/has_messages/install/templates/views/_messages.html.erb +56 -0
  18. data/lib/generators/has_messages/install/templates/views/_tabs_panel.html.erb +11 -0
  19. data/lib/generators/has_messages/install/templates/views/index.html.erb +10 -0
  20. data/lib/generators/has_messages/install/templates/views/index.js.erb +1 -0
  21. data/lib/generators/has_messages/install/templates/views/new.html.erb +26 -0
  22. data/lib/generators/has_messages/install/templates/views/show.html.erb +35 -0
  23. metadata +78 -0
@@ -0,0 +1,19 @@
1
+ $(function() {
2
+ // Check all the checkboxes when the head one is selected
3
+ $(".checkall").live("click", function() {
4
+ $("input[type='checkbox']").attr('checked', $(this).is(':checked'));
5
+ });
6
+
7
+ // handle pagination through ajax
8
+ $("#tabs-messages .pagination a").live("click", function(e) {
9
+ $.getScript(this.href);
10
+ history.pushState(null, document.title, this.href);
11
+ e.preventDefault();
12
+ });
13
+
14
+ //bind window for postate
15
+ $(window).bind("popstate", function() {
16
+ $.getScript(location.href);
17
+ });
18
+
19
+ });
@@ -0,0 +1,107 @@
1
+ /* pretty-table */
2
+ table.pretty {
3
+ border-collapse: collapse;
4
+ }
5
+
6
+ .pretty td, .pretty th {
7
+ padding: 4px 10px;
8
+ border: solid 1px #AAA;
9
+ }
10
+
11
+ .pretty th .current {
12
+ padding-right: 12px;
13
+ background-repeat: no-repeat;
14
+ background-position: right center;
15
+ }
16
+
17
+ .pretty tr.alt { background-color: #EBEBEB; }
18
+
19
+ .pretty tr.unread { font-weight: bold; }
20
+
21
+ ul.tabs {
22
+ margin: 0;
23
+ padding: 0;
24
+ float: left;
25
+ list-style: none;
26
+ height: 32px; /*--Set height of tabs--*/
27
+ border-bottom: 1px solid #999;
28
+ border-left: 1px solid #999;
29
+ width: 100%;
30
+ }
31
+ ul.tabs li {
32
+ float: left;
33
+ margin: 0;
34
+ padding: 0;
35
+ height: 31px; /*--Subtract 1px from the height of the unordered list--*/
36
+ line-height: 31px; /*--Vertically aligns the text within the tab--*/
37
+ border: 1px solid #999;
38
+ border-left: none;
39
+ margin-bottom: -1px; /*--Pull the list item down 1px--*/
40
+ overflow: hidden;
41
+ position: relative;
42
+ background: #e0e0e0;
43
+ }
44
+ ul.tabs li a {
45
+ text-decoration: none;
46
+ color: #000;
47
+ display: block;
48
+ padding: 0 20px;
49
+ border: 1px solid #fff; /*--Gives the bevel look with a 1px white border inside the list item--*/
50
+ outline: none;
51
+ }
52
+ ul.tabs li a:hover {
53
+ background: #ccc;
54
+ }
55
+ html ul.tabs li.active, html ul.tabs li.active a:hover { /*--Makes sure that the active tab does not listen to the hover properties--*/
56
+ background: #fff;
57
+ border-bottom: 1px solid #fff; /*--Makes the active tab look like it's connected with its content--*/
58
+ }
59
+
60
+ .message {
61
+ margin: 8px 0;
62
+ padding: 8px 15px;
63
+ border: solid 1px #999;
64
+ width: 300px;
65
+ border-radius: 12px;
66
+ background-image: -webkit-gradient(
67
+ linear,
68
+ left bottom,
69
+ left top,
70
+ color-stop(0, #CCC),
71
+ color-stop(1, #F5F5F5)
72
+ );
73
+ background-image: -moz-linear-gradient(
74
+ center bottom,
75
+ #CCC 0%,
76
+ #F5F5F5 100%
77
+ );
78
+ }
79
+
80
+ .message .content a {
81
+ color: #000;
82
+ text-decoration: none;
83
+ }
84
+
85
+ .message .created_at {
86
+ color: #555;
87
+ font-size: 12px;
88
+ float: right;
89
+ }
90
+
91
+ .message .actions {
92
+ font-size: 12px;
93
+ margin-top: 5px;
94
+ }
95
+
96
+ .message .actions a {
97
+ text-decoration: none;
98
+ }
99
+
100
+ .nested_messages {
101
+ margin-left: 30px;
102
+ }
103
+
104
+ /*.nested_messages .nested_messages .nested_messages .nested_messages {
105
+ margin-left: 0;
106
+ }
107
+ */
@@ -0,0 +1,122 @@
1
+ /* Example tokeninput style #2: Facebook style */
2
+ ul.token-input-list-facebook {
3
+ overflow: hidden;
4
+ height: auto !important;
5
+ height: 1%;
6
+ width: 400px;
7
+ border: 1px solid #8496ba;
8
+ cursor: text;
9
+ font-size: 12px;
10
+ font-family: Verdana;
11
+ min-height: 1px;
12
+ z-index: 999;
13
+ margin: 0;
14
+ padding: 0;
15
+ background-color: #fff;
16
+ list-style-type: none;
17
+ clear: left;
18
+ }
19
+
20
+ ul.token-input-list-facebook li input {
21
+ border: 0;
22
+ width: 100px;
23
+ padding: 3px 8px;
24
+ background-color: white;
25
+ margin: 2px 0;
26
+ -webkit-appearance: caret;
27
+ }
28
+
29
+ li.token-input-token-facebook {
30
+ overflow: hidden;
31
+ height: auto !important;
32
+ height: 15px;
33
+ margin: 3px;
34
+ padding: 1px 3px;
35
+ background-color: #eff2f7;
36
+ color: #000;
37
+ cursor: default;
38
+ border: 1px solid #ccd5e4;
39
+ font-size: 11px;
40
+ border-radius: 5px;
41
+ -moz-border-radius: 5px;
42
+ -webkit-border-radius: 5px;
43
+ float: left;
44
+ white-space: nowrap;
45
+ }
46
+
47
+ li.token-input-token-facebook p {
48
+ display: inline;
49
+ padding: 0;
50
+ margin: 0;
51
+ }
52
+
53
+ li.token-input-token-facebook span {
54
+ color: #a6b3cf;
55
+ margin-left: 5px;
56
+ font-weight: bold;
57
+ cursor: pointer;
58
+ }
59
+
60
+ li.token-input-selected-token-facebook {
61
+ background-color: #5670a6;
62
+ border: 1px solid #3b5998;
63
+ color: #fff;
64
+ }
65
+
66
+ li.token-input-input-token-facebook {
67
+ float: left;
68
+ margin: 0;
69
+ padding: 0;
70
+ list-style-type: none;
71
+ }
72
+
73
+ div.token-input-dropdown-facebook {
74
+ position: absolute;
75
+ width: 400px;
76
+ background-color: #fff;
77
+ overflow: hidden;
78
+ border-left: 1px solid #ccc;
79
+ border-right: 1px solid #ccc;
80
+ border-bottom: 1px solid #ccc;
81
+ cursor: default;
82
+ font-size: 11px;
83
+ font-family: Verdana;
84
+ z-index: 1;
85
+ }
86
+
87
+ div.token-input-dropdown-facebook p {
88
+ margin: 0;
89
+ padding: 5px;
90
+ font-weight: bold;
91
+ color: #777;
92
+ }
93
+
94
+ div.token-input-dropdown-facebook ul {
95
+ margin: 0;
96
+ padding: 0;
97
+ }
98
+
99
+ div.token-input-dropdown-facebook ul li {
100
+ background-color: #fff;
101
+ padding: 3px;
102
+ margin: 0;
103
+ list-style-type: none;
104
+ }
105
+
106
+ div.token-input-dropdown-facebook ul li.token-input-dropdown-item-facebook {
107
+ background-color: #fff;
108
+ }
109
+
110
+ div.token-input-dropdown-facebook ul li.token-input-dropdown-item2-facebook {
111
+ background-color: #fff;
112
+ }
113
+
114
+ div.token-input-dropdown-facebook ul li em {
115
+ font-weight: bold;
116
+ font-style: normal;
117
+ }
118
+
119
+ div.token-input-dropdown-facebook ul li.token-input-selected-dropdown-item-facebook {
120
+ background-color: #3b5998;
121
+ color: #fff;
122
+ }
@@ -0,0 +1,111 @@
1
+ class MessagesController < ApplicationController
2
+ <%- if gemfile_included?("devise") -%>
3
+ before_filter :authenticate_user!
4
+ <%- end -%>
5
+ def index
6
+ @messagebox = params[:messagebox].blank? ? "inbox" : params[:messagebox]
7
+ @messages = current_user.send(@messagebox).group(:subject_id).page(params[:page]).per(10)
8
+
9
+ case @messagebox
10
+ when "trash"
11
+ @options = ["Read","Unread","Delete","Undelete"]
12
+ else
13
+ @options = ["Read","Unread","Delete"]
14
+ end
15
+ end
16
+
17
+ def show
18
+ unless params[:messagebox].blank?
19
+ message = current_user.send(params[:messagebox]).find(params[:id])
20
+
21
+ @messages = message.root.subtree
22
+ @parent_id = @messages.last.id
23
+
24
+ if @messages.last.copies
25
+ @user_tokens = @messages.last.recipient_id
26
+ @parent_id = @messages.last.ancestor_ids.last unless @parent_id.nil?
27
+ else
28
+ @user_tokens = @messages.last.sender_id
29
+ end
30
+
31
+ read_unread_messages(true, *@messages)
32
+ end
33
+ end
34
+
35
+ def new
36
+ end
37
+
38
+ def create
39
+ unless params[:user_tokens].blank? or params[:subject].blank? or params[:content].blank?
40
+ recipients = User.find(params[:user_tokens].split(",").collect { |id| id.to_i })
41
+ if current_user.send_message?(:recipients => recipients, :subject_id => params[:subject_id], :subject => params[:subject], :content => params[:content], :parent_id => params[:parent_id])
42
+ redirect_to box_messages_url(:inbox), :notice => 'Successfully send message.'
43
+ else
44
+ flash.now[:alert] = "Unable to send message."
45
+ render "new"
46
+ end
47
+ else
48
+ flash.now[:alert] = "Invalid input for sending message."
49
+ render "new"
50
+ end
51
+ end
52
+
53
+ def update
54
+ unless params[:messages].nil?
55
+ message = current_user.send(params[:messagebox]).find(params[:messages])
56
+ message.each do |message|
57
+ messages = message.root.subtree
58
+ if params[:option].downcase == "read"
59
+ read_unread_messages(true,*messages)
60
+ elsif params[:option].downcase == "unread"
61
+ read_unread_messages(false,*messages)
62
+ elsif params[:option].downcase == "delete"
63
+ delete_messages(true,*messages)
64
+ elsif params[:option].downcase == "undelete"
65
+ delete_messages(false,*messages)
66
+ end
67
+ end
68
+ end
69
+ redirect_to box_messages_url(params[:messagebox])
70
+ end
71
+
72
+ def empty
73
+ unless params[:messagebox].nil?
74
+ current_user.empty_messages(params[:messagebox].to_sym => true)
75
+ redirect_to box_messages_url(params[:messagebox]), :notice => "Successfully delete all messages."
76
+ end
77
+ end
78
+
79
+ def token
80
+ query = "%" + params[:q] + "%"
81
+ recipients = User.select("id,email").where("email like ?", query)
82
+ respond_to do |format|
83
+ format.json { render :json => recipients.map { |u| { "id" => u.id, "name" => u.email} } }
84
+ end
85
+ end
86
+
87
+ private
88
+
89
+ def read_unread_messages(isRead, *messages)
90
+ messages.each do |msg|
91
+ unless msg.copies
92
+ if isRead
93
+ msg.mark_as_read unless msg.read?
94
+ else
95
+ msg.mark_as_unread if msg.read?
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ def delete_messages(isDelete, *messages)
102
+ messages.each do |msg|
103
+ if isDelete
104
+ msg.delete
105
+ else
106
+ msg.undelete
107
+ end
108
+ end
109
+ end
110
+
111
+ end
@@ -0,0 +1,2 @@
1
+ module MessagesHelper
2
+ end
@@ -0,0 +1,67 @@
1
+ module HasMessages
2
+
3
+ def send_message?(options)
4
+ send_message(options)
5
+ true
6
+ rescue Exception => e
7
+ false
8
+ end
9
+
10
+ def send_message(options)
11
+ unless options[:recipients].nil?
12
+ transaction do
13
+ recipients = options[:recipients]
14
+ options.delete(:recipients)
15
+
16
+ options[:subject_id] = Message.sequence_subject_id if options[:subject_id].nil?
17
+
18
+ recipients.each do |rec|
19
+ # => create message copies
20
+ options[:user_id] = self.id
21
+ options[:sender_id] = self.id
22
+ options[:recipient_id] = rec.id
23
+ options[:copies] = true
24
+ Message.create(options)
25
+ # => create message
26
+ options[:user_id] = rec.id
27
+ options[:sender_id] = self.id
28
+ options[:recipient_id] = rec.id
29
+ options[:copies] = false
30
+ options[:parent_id] = Message.next_parent_id(options[:parent_id]) unless options[:parent_id].nil?
31
+ Message.create(options)
32
+ end
33
+ end
34
+ else
35
+ raise "Required recipients"
36
+ end
37
+ rescue Exception => e
38
+ raise e
39
+ end
40
+
41
+ def inbox(options = {})
42
+ options[:deleted] = false
43
+ options[:copies] = false
44
+ self.messages.where(options)
45
+ end
46
+
47
+ def outbox(options = {})
48
+ options[:deleted] = false
49
+ options[:copies] = true
50
+ self.messages.where(options)
51
+ end
52
+
53
+ def trash(options = {})
54
+ options[:deleted] = true
55
+ self.messages.where(options)
56
+ end
57
+
58
+ def empty_messages(options = {})
59
+ if options.empty? or options[:inbox] or options[:outbox]
60
+ self.inbox.update_all(:deleted => true)
61
+ self.outbox.update_all(:deleted => true)
62
+ elsif options[:trash]
63
+ self.trash.delete_all
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,24 @@
1
+ class CreateMessages < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :messages do |t|
4
+ t.integer :user_id
5
+ t.integer :sender_id
6
+ t.integer :recipient_id
7
+ t.integer :subject_id
8
+ t.string :subject
9
+ t.text :content
10
+ t.boolean :opened, :default => false
11
+ t.boolean :deleted, :default => false
12
+ t.boolean :copies, :default => false
13
+ t.string :ancestry
14
+ t.timestamps
15
+ end
16
+
17
+ add_index :messages, [:user_id, :subject_id, :ancestry], :name => "messages_idx"
18
+ end
19
+
20
+ def self.down
21
+ drop_index :messages, "messages_idx"
22
+ drop_table :messages
23
+ end
24
+ end