activeadmin-chat 1.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/README.md +149 -0
- data/Rakefile +29 -0
- data/app/assets/config/active_admin/chat/manifest.js +0 -0
- data/app/assets/stylesheets/active_admin/chat.scss +130 -0
- data/app/assets/stylesheets/active_admin/chat/colors.scss +7 -0
- data/app/channels/active_admin/chat/admin_channel.rb +21 -0
- data/app/channels/active_admin/chat/base_channel.rb +28 -0
- data/app/channels/active_admin/chat/user_channel.rb +19 -0
- data/app/helpers/active_admin/chat/chat_helper.rb +13 -0
- data/app/views/active_admin/chat/_chat.html.erb +7 -0
- data/app/views/active_admin/chat/_list.html.erb +12 -0
- data/app/views/active_admin/chat/_message.html.erb +5 -0
- data/app/views/active_admin/chat/_messages.html.erb +3 -0
- data/app/views/active_admin/chat/show.html.erb +17 -0
- data/config/routes.rb +9 -0
- data/lib/active_admin/chat.rb +42 -0
- data/lib/active_admin/chat/application.rb +29 -0
- data/lib/active_admin/chat/engine.rb +6 -0
- data/lib/active_admin/chat/extensions.rb +13 -0
- data/lib/active_admin/chat/extensions/application.rb +83 -0
- data/lib/active_admin/chat/extensions/index_table_for.rb +23 -0
- data/lib/active_admin/chat/message_presenter.rb +24 -0
- data/lib/active_admin/chat/version.rb +5 -0
- data/lib/activeadmin-chat.rb +3 -0
- data/lib/generators/active_admin/chat/install/install_generator.rb +123 -0
- data/lib/generators/active_admin/chat/install/templates/initializers/active_admin/chat.rb.erb +8 -0
- data/lib/generators/active_admin/chat/install/templates/pages/chat.rb +2 -0
- metadata +270 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c8d98f77adf289e587a3fe87574aea5b04c0dbec
|
4
|
+
data.tar.gz: a39d14ff43fb865d774a38027ac81c437a2d78d3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ce8c7420247974431bef63d479c20df168745b7ec0ae71b2dac44ad7357fc798d3cca68cab3ce44bfcaaefc12d39c5fd71bfe7b30f1ec8554e9c55b97c4ff383
|
7
|
+
data.tar.gz: 37dcb743df2be501579b0259f03af19a077e2ee871cbc8bbe9f7d16740e0990dc20852c87f6632c5493baeb5aeade99ee9dd5da611bdf6c10edb260b8ade6a07
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2018 Rootstrap
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
# ActiveAdmin::Chat
|
2
|
+
|
3
|
+
[](https://travis-ci.org/rootstrap/activeadmin-chat)
|
4
|
+
[](https://codeclimate.com/github/rootstrap/activeadmin-chat/maintainability)
|
5
|
+
[](https://codeclimate.com/github/rootstrap/activeadmin-chat/test_coverage)
|
6
|
+
|
7
|
+
Get a chat for your ActiveAdmin app out of the box.
|
8
|
+
|
9
|
+

|
10
|
+
|
11
|
+
## Prerequisites
|
12
|
+
- It assumes you have models for your admins and users in place.
|
13
|
+
- It assumes that your users have an `email` attribute.
|
14
|
+
- For production you need to configure ActionCable by providing it with a Redis or Postgres connection in `config/cable.yml`.
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
Add to Gemfile:
|
18
|
+
```ruby
|
19
|
+
gem 'activeadmin-chat'
|
20
|
+
```
|
21
|
+
|
22
|
+
And then run:
|
23
|
+
```bash
|
24
|
+
$ bundle install
|
25
|
+
```
|
26
|
+
|
27
|
+
This gem requires Webpacker for the Javascript. Add the npm package:
|
28
|
+
```bash
|
29
|
+
$ yarn add activeadmin-chat
|
30
|
+
```
|
31
|
+
|
32
|
+
And install it:
|
33
|
+
```bash
|
34
|
+
$ yarn install
|
35
|
+
```
|
36
|
+
|
37
|
+
Install `ActiveAdmin::Chat`:
|
38
|
+
```bash
|
39
|
+
$ rails generate active_admin:chat:install
|
40
|
+
```
|
41
|
+
It will generate:
|
42
|
+
- `Conversation` and `Message` models and migrations.
|
43
|
+
- Initializer that configures the model names for conversation, message, admin user and user.
|
44
|
+
- Default chat page.
|
45
|
+
|
46
|
+
You can customize the namings of the models when installing `ActiveAdmin::Chat` with the usage of the `--conversation_model_name`, `--message_model_name`, `--admin_user_model_name` and `--user_model_name` flags.
|
47
|
+
|
48
|
+
For example:
|
49
|
+
```bash
|
50
|
+
$ rails generate active_admin:chat:install --conversation_model_name=chat
|
51
|
+
```
|
52
|
+
|
53
|
+
Once you've successfully installed `ActiveAdmin::Chat`, run:
|
54
|
+
```bash
|
55
|
+
$ rails db:migrate
|
56
|
+
```
|
57
|
+
|
58
|
+
Add including of CSS to `app/assets/stylesheets/active_admin.css.scss`:
|
59
|
+
```css
|
60
|
+
@import 'active_admin/chat';
|
61
|
+
```
|
62
|
+
|
63
|
+
Create a file named `app/javascript/packs/activeadmin-chat.js`, with the following content:
|
64
|
+
```js
|
65
|
+
import 'activeadmin-chat';
|
66
|
+
```
|
67
|
+
|
68
|
+
### Example diagram
|
69
|
+

|
70
|
+
|
71
|
+
## Usage
|
72
|
+
All you need to get the chat up and running is to authenticate your users in the websocket connection in `app/channels/application_cable/connection.rb`. It's important that you identify them as the `current_user` here, this will be used by the gem internally.
|
73
|
+
|
74
|
+
For example with the `devise` gem:
|
75
|
+
```ruby
|
76
|
+
module ApplicationCable
|
77
|
+
class Connection < ActionCable::Connection::Base
|
78
|
+
identified_by :current_user
|
79
|
+
|
80
|
+
def connect
|
81
|
+
self.current_user = find_verified_user
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def find_verified_user
|
87
|
+
verified_user = env['warden'].user
|
88
|
+
|
89
|
+
reject_unauthorized_connection unless verified_user
|
90
|
+
|
91
|
+
verified_user
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
```
|
96
|
+
|
97
|
+
## Customization
|
98
|
+
You can change the chat page name and namespace the same way you do with other ActiveAdmin pages.
|
99
|
+
|
100
|
+
If you'd like to change the chat styling you can override the following classes:
|
101
|
+
- `.active-admin-chat__title`: Title above the conversations list
|
102
|
+
- `.active-admin-chat__conversations-list-container`, `.active-admin-chat__conversations-list` and `.active-admin-chat__conversation-item`: List of conversations
|
103
|
+
- `.active-admin-chat__conversation-history-container` and `.active-admin-chat__conversation-history`: Conversation panel
|
104
|
+
- `.active-admin-chat__message-container`: Message in the conversation panel
|
105
|
+
- `.active-admin-chat__send-message-container`: Send message button
|
106
|
+
|
107
|
+
If you'd like to change the whole HTML you can do it in the chat page by specifying its content:
|
108
|
+
```ruby
|
109
|
+
ActiveAdmin.register_chat 'Chat' do
|
110
|
+
content do
|
111
|
+
# your code
|
112
|
+
end
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
If you'd like to change the controller actions you can do it in the chat page by specifying its controller:
|
117
|
+
```ruby
|
118
|
+
ActiveAdmin.register_chat 'Chat' do
|
119
|
+
controller do
|
120
|
+
def show
|
121
|
+
# your code
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
```
|
126
|
+
|
127
|
+
|
128
|
+
If you'd like to add a button in the user's index in the admin dashboard to start a chat with a user:
|
129
|
+
```ruby
|
130
|
+
ActiveAdmin.register_chat User do
|
131
|
+
index do
|
132
|
+
# your code
|
133
|
+
actions do |user|
|
134
|
+
send_message_link user
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
```
|
139
|
+
|
140
|
+
## Contributing
|
141
|
+
Bug reports (please use Issues) and pull requests are welcome on GitHub at https://github.com/rootstrap/activeadmin-chat. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
142
|
+
|
143
|
+
## License
|
144
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
145
|
+
|
146
|
+
## Credits
|
147
|
+
**Active Admin Chat** is maintained by [Rootstrap](http://www.rootstrap.com) with the help of our [contributors](https://github.com/rootstrap/activeadmin-chat/contributors).
|
148
|
+
|
149
|
+
[<img src="https://s3-us-west-1.amazonaws.com/rootstrap.com/img/rs.png" width="100"/>](http://www.rootstrap.com)
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'ActiveAdmin::Chat'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path('spec/dummy/Rakefile', __dir__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
load 'rails/tasks/statistics.rake'
|
21
|
+
|
22
|
+
require 'bundler/gem_tasks'
|
23
|
+
require 'rubocop/rake_task'
|
24
|
+
require 'rspec/core/rake_task'
|
25
|
+
|
26
|
+
RuboCop::RakeTask.new
|
27
|
+
RSpec::Core::RakeTask.new
|
28
|
+
|
29
|
+
task default: %i[rubocop spec]
|
File without changes
|
@@ -0,0 +1,130 @@
|
|
1
|
+
@import 'chat/colors';
|
2
|
+
|
3
|
+
.active-admin-chat__chat {
|
4
|
+
height: calc(100vh - 270px);
|
5
|
+
|
6
|
+
.active-admin-chat__conversations-list-container {
|
7
|
+
display: inline-block;
|
8
|
+
height: 100%;
|
9
|
+
width: 30%;
|
10
|
+
}
|
11
|
+
|
12
|
+
.active-admin-chat__title {
|
13
|
+
background-color: $active-admin-chat__lighter-grey;
|
14
|
+
background-image: linear-gradient(180deg, $active-admin-chat__lighter-grey, $active-admin-chat__light-grey);
|
15
|
+
border: solid 1px $active-admin-chat__grey;
|
16
|
+
border-color: $active-admin-chat__light-grey $active-admin-chat__light-grey $active-admin-chat__grey;
|
17
|
+
box-shadow: 0 1px 3px rgba($active-admin-chat__black, 0.12), 0 0 1px $active-admin-chat__white inset;
|
18
|
+
font-size: 14px;
|
19
|
+
font-weight: bold;
|
20
|
+
margin: 0;
|
21
|
+
padding: 10px 12px 8px;
|
22
|
+
text-shadow: $active-admin-chat__white 0 1px 0;
|
23
|
+
}
|
24
|
+
|
25
|
+
.active-admin-chat__conversations-list {
|
26
|
+
height: calc(100% - 34px);
|
27
|
+
margin: 0;
|
28
|
+
overflow-y: auto;
|
29
|
+
padding: 0;
|
30
|
+
|
31
|
+
a {
|
32
|
+
color: inherit;
|
33
|
+
text-decoration: inherit;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
.active-admin-chat__conversation-item {
|
38
|
+
border-bottom: 1px solid $active-admin-chat__lighter-grey;
|
39
|
+
cursor: pointer;
|
40
|
+
list-style: none;
|
41
|
+
padding: 10px 12px 8px;
|
42
|
+
vertical-align: top;
|
43
|
+
|
44
|
+
&:nth-child(even) {
|
45
|
+
background-color: $active-admin-chat__lightest-grey;
|
46
|
+
}
|
47
|
+
|
48
|
+
&:hover {
|
49
|
+
background-color: $active-admin-chat__lighter-grey;
|
50
|
+
}
|
51
|
+
|
52
|
+
&.selected {
|
53
|
+
background-color: $active-admin-chat__grey;
|
54
|
+
|
55
|
+
&:hover {
|
56
|
+
background-color: $active-admin-chat__grey;
|
57
|
+
}
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
.active-admin-chat__conversation-history-container {
|
62
|
+
display: inline-block;
|
63
|
+
float: right;
|
64
|
+
height: 100%;
|
65
|
+
width: 70%;
|
66
|
+
}
|
67
|
+
|
68
|
+
.active-admin-chat__conversation-history {
|
69
|
+
background-color: $active-admin-chat__lighter-grey;
|
70
|
+
display: flex;
|
71
|
+
flex-direction: column;
|
72
|
+
height: calc(100% - 61px);
|
73
|
+
overflow: auto;
|
74
|
+
padding: 0 15px;
|
75
|
+
|
76
|
+
&.no-messages {
|
77
|
+
font-size: 24px;
|
78
|
+
margin: auto;
|
79
|
+
padding: 50px;
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
.active-admin-chat__message-container {
|
84
|
+
&:first-child {
|
85
|
+
margin-top: auto;
|
86
|
+
}
|
87
|
+
|
88
|
+
div {
|
89
|
+
background-color: $active-admin-chat__white;
|
90
|
+
border-radius: 10px 10px 10px 0;
|
91
|
+
display: inline-block;
|
92
|
+
margin: 3px;
|
93
|
+
max-width: 70%;
|
94
|
+
padding: 5px;
|
95
|
+
word-break: break-word;
|
96
|
+
|
97
|
+
p {
|
98
|
+
font-size: 12px;
|
99
|
+
margin: 0 0 0 2px;
|
100
|
+
}
|
101
|
+
|
102
|
+
span {
|
103
|
+
font-size: 10px;
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
&.admin {
|
108
|
+
text-align: right;
|
109
|
+
|
110
|
+
div {
|
111
|
+
background-color: $active-admin-chat__green;
|
112
|
+
border-radius: 10px 10px 0;
|
113
|
+
}
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
.active-admin-chat__send-message-container {
|
118
|
+
background-color: $active-admin-chat__lighter-grey;
|
119
|
+
height: 61px;
|
120
|
+
|
121
|
+
input {
|
122
|
+
border: 0;
|
123
|
+
border-radius: 25px;
|
124
|
+
margin: 10px 30px;
|
125
|
+
outline: none;
|
126
|
+
padding: 15px;
|
127
|
+
width: calc(100% - 90px);
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
$active-admin-chat__lightest-grey: #fafafa;
|
2
|
+
$active-admin-chat__lighter-grey: #efefef;
|
3
|
+
$active-admin-chat__light-grey: #d4d4d4;
|
4
|
+
$active-admin-chat__grey: #cdcdcd;
|
5
|
+
$active-admin-chat__black: #000;
|
6
|
+
$active-admin-chat__white: #fff;
|
7
|
+
$active-admin-chat__green: #cbe6b8;
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Chat
|
3
|
+
class AdminChannel < ActiveAdmin::Chat::BaseChannel
|
4
|
+
private
|
5
|
+
|
6
|
+
def conversation
|
7
|
+
return unless admin? && conversation_id.present?
|
8
|
+
|
9
|
+
@conversation ||= ActiveAdmin::Chat.conversation_klass.find_by(id: conversation_id)
|
10
|
+
end
|
11
|
+
|
12
|
+
def admin?
|
13
|
+
current_user.instance_of?(ActiveAdmin::Chat.admin_user_klass)
|
14
|
+
end
|
15
|
+
|
16
|
+
def conversation_id
|
17
|
+
params[:conversation_id]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Chat
|
3
|
+
class BaseChannel < ApplicationCable::Channel
|
4
|
+
def subscribed
|
5
|
+
conversation ? stream_for(conversation) : reject
|
6
|
+
end
|
7
|
+
|
8
|
+
def speak(data)
|
9
|
+
message = conversation.public_send(
|
10
|
+
ActiveAdmin::Chat.message_relation_name.pluralize
|
11
|
+
).create!(
|
12
|
+
sender: current_user,
|
13
|
+
content: data['message']
|
14
|
+
)
|
15
|
+
|
16
|
+
message = ActiveAdmin::Chat::MessagePresenter.new(message)
|
17
|
+
ActiveAdmin::Chat::AdminChannel.broadcast_to(conversation, message)
|
18
|
+
ActiveAdmin::Chat::UserChannel.broadcast_to(conversation, message)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def conversation
|
24
|
+
raise NotImplementedError
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Chat
|
3
|
+
class UserChannel < ActiveAdmin::Chat::BaseChannel
|
4
|
+
private
|
5
|
+
|
6
|
+
def conversation
|
7
|
+
return unless user?
|
8
|
+
|
9
|
+
@conversation ||= ActiveAdmin::Chat.conversation_klass.find_by(
|
10
|
+
"#{ActiveAdmin::Chat.user_relation_name}_id": current_user.id
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def user?
|
15
|
+
current_user.instance_of?(ActiveAdmin::Chat.user_klass)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Chat
|
3
|
+
module ChatHelper
|
4
|
+
def admin_class(message)
|
5
|
+
'admin' if message.sender.class == ActiveAdmin::Chat.admin_user_klass
|
6
|
+
end
|
7
|
+
|
8
|
+
def selected_class(conversation, active_conversation)
|
9
|
+
'selected' if active_conversation && active_conversation == conversation
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div class='active-admin-chat__conversations-list-container'>
|
2
|
+
<h3 class='active-admin-chat__title'><%= ActiveAdmin::Chat.conversation_relation_name.pluralize.capitalize %></h3>
|
3
|
+
<ul class='active-admin-chat__conversations-list'>
|
4
|
+
<% conversations.each do |conversation| %>
|
5
|
+
<a href='<%= "/#{ActiveAdmin::Chat.namespace}/#{ActiveAdmin::Chat.page_name}/#{conversation.id}" %>' >
|
6
|
+
<li id='conversation-<%= conversation.id %>' class='active-admin-chat__conversation-item <%= selected_class(conversation, active_conversation) %>'>
|
7
|
+
<%= conversation.public_send(:"#{ActiveAdmin::Chat.user_relation_name}").email %>
|
8
|
+
</li>
|
9
|
+
</a>
|
10
|
+
<% end %>
|
11
|
+
</ul>
|
12
|
+
</div>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<div class='active-admin-chat__chat'>
|
2
|
+
<%= render partial: 'active_admin/chat/list' %>
|
3
|
+
|
4
|
+
<div class='active-admin-chat__conversation-history-container'>
|
5
|
+
<div class='active-admin-chat__conversation-history'>
|
6
|
+
<% if active_conversation && messages.empty? %>
|
7
|
+
<div class='active-admin-chat__conversation-history no-messages'>No messages</div>
|
8
|
+
<% else %>
|
9
|
+
<%= render partial: 'active_admin/chat/messages' %>
|
10
|
+
<% end %>
|
11
|
+
</div>
|
12
|
+
<div class='active-admin-chat__send-message-container'>
|
13
|
+
<input type='text' id='send-message' placeholder="Send message" />
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
<%= javascript_pack_tag 'activeadmin-chat' %>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
if ActiveAdmin::Chat.method_defined?(:page_name) && ActiveAdmin::Chat.page_name
|
3
|
+
namespace ActiveAdmin::Chat.namespace do
|
4
|
+
get "#{ActiveAdmin::Chat.page_name}/:id", to: "#{ActiveAdmin::Chat.page_name}#show"
|
5
|
+
post "#{ActiveAdmin::Chat.user_model_name}/:#{ActiveAdmin::Chat.user_relation_name}_id/#{ActiveAdmin::Chat.page_name}",
|
6
|
+
to: "#{ActiveAdmin::Chat.page_name}#create"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'active_admin'
|
2
|
+
require 'active_admin/chat/engine'
|
3
|
+
require 'active_admin/chat/extensions'
|
4
|
+
require 'active_admin/chat/extensions/application'
|
5
|
+
require 'active_admin/chat/application'
|
6
|
+
require 'active_admin/chat/extensions/index_table_for'
|
7
|
+
require 'active_admin/chat/message_presenter'
|
8
|
+
require 'webpacker'
|
9
|
+
|
10
|
+
module ActiveAdmin
|
11
|
+
module Chat
|
12
|
+
extend self
|
13
|
+
|
14
|
+
def application
|
15
|
+
@application ||= ::ActiveAdmin::Chat::Application.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def setup
|
19
|
+
yield(application)
|
20
|
+
end
|
21
|
+
|
22
|
+
delegate :conversation_klass, to: :application
|
23
|
+
delegate :message_klass, to: :application
|
24
|
+
delegate :admin_user_klass, to: :application
|
25
|
+
delegate :user_klass, to: :application
|
26
|
+
delegate :conversation_relation_name, to: :application
|
27
|
+
delegate :message_relation_name, to: :application
|
28
|
+
delegate :admin_user_relation_name, to: :application
|
29
|
+
delegate :user_relation_name, to: :application
|
30
|
+
delegate :page_name, to: :application
|
31
|
+
delegate :namespace, to: :application
|
32
|
+
delegate :user_model_name, to: :application
|
33
|
+
delegate :messages_per_page, to: :application
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
::ActiveAdmin.send :include, ActiveAdmin::Chat::Extensions
|
38
|
+
::ActiveAdmin::Application.send :include, ActiveAdmin::Chat::Extensions::Application
|
39
|
+
::ActiveAdmin::Views::IndexAsTable::IndexTableFor.send(
|
40
|
+
:prepend,
|
41
|
+
ActiveAdmin::Chat::Extensions::Views::IndexAsTable::IndexTableFor
|
42
|
+
)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Chat
|
3
|
+
class Application
|
4
|
+
attr_accessor :conversation_model_name, :message_model_name, :admin_user_model_name,
|
5
|
+
:user_model_name, :page_name, :namespace, :messages_per_page
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@conversation_model_name = 'conversation'
|
9
|
+
@message_model_name = 'message'
|
10
|
+
@admin_user_model_name = 'admin_user'
|
11
|
+
@user_model_name = 'user'
|
12
|
+
@namespace = 'admin'
|
13
|
+
@messages_per_page = 25
|
14
|
+
end
|
15
|
+
|
16
|
+
%i[conversation message admin_user user].each do |attribute|
|
17
|
+
define_method :"#{attribute}_klass" do
|
18
|
+
public_send("#{attribute}_model_name").pluralize.classify.constantize
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
%i[conversation message admin_user user].each do |attribute|
|
23
|
+
define_method :"#{attribute}_relation_name" do
|
24
|
+
public_send("#{attribute}_model_name").split('/').last
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Chat
|
3
|
+
module Extensions
|
4
|
+
module Application
|
5
|
+
def register_chat(name, options = {}, &block)
|
6
|
+
setup_page_configs(name, options[:namespace])
|
7
|
+
|
8
|
+
register_page name, options do
|
9
|
+
content do
|
10
|
+
render 'active_admin/chat/chat'
|
11
|
+
end
|
12
|
+
|
13
|
+
controller do
|
14
|
+
layout 'active_admin', only: :show
|
15
|
+
helper_method :messages, :active_conversation, :conversations
|
16
|
+
|
17
|
+
def show
|
18
|
+
respond_to do |format|
|
19
|
+
format.html { render 'active_admin/chat/show' }
|
20
|
+
format.json do
|
21
|
+
render json: ActiveAdmin::Chat::MessagePresenter.all(messages)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def create
|
27
|
+
conversation =
|
28
|
+
ActiveAdmin::Chat.conversation_klass
|
29
|
+
.find_or_create_by!(
|
30
|
+
"#{user_relation_name_id}": params[:"#{user_relation_name_id}"]
|
31
|
+
)
|
32
|
+
redirect_to action: 'show', id: conversation
|
33
|
+
end
|
34
|
+
|
35
|
+
def active_conversation
|
36
|
+
@active_conversation ||= ActiveAdmin::Chat.conversation_klass.find_by(
|
37
|
+
id: params[:id]
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def conversations
|
42
|
+
@conversations ||= ActiveAdmin::Chat.conversation_klass
|
43
|
+
.includes(ActiveAdmin::Chat.user_relation_name)
|
44
|
+
end
|
45
|
+
|
46
|
+
def messages
|
47
|
+
return [] unless active_conversation
|
48
|
+
|
49
|
+
page_messages = active_conversation.public_send(
|
50
|
+
ActiveAdmin::Chat.message_relation_name.pluralize
|
51
|
+
).includes(:sender).order(created_at: :desc)
|
52
|
+
|
53
|
+
if params[:created_at].present?
|
54
|
+
page_messages = page_messages.where('created_at < ?',
|
55
|
+
DateTime.parse(params[:created_at]))
|
56
|
+
end
|
57
|
+
page_messages.limit(ActiveAdmin::Chat.messages_per_page).reverse
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def user_relation_name_id
|
63
|
+
"#{ActiveAdmin::Chat.user_relation_name}_id"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# customize default chat
|
68
|
+
instance_eval(&block)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def setup_page_configs(page_name, namespace)
|
75
|
+
ActiveAdmin::Chat.setup do |config|
|
76
|
+
config.page_name = page_name.downcase
|
77
|
+
config.namespace = namespace.downcase if namespace
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Chat
|
3
|
+
module Extensions
|
4
|
+
module Views
|
5
|
+
module IndexAsTable
|
6
|
+
module IndexTableFor
|
7
|
+
def send_message_link(resource)
|
8
|
+
text_node link_to 'Send Message',
|
9
|
+
send_message_path(resource.id),
|
10
|
+
method: :post
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def send_message_path(id)
|
16
|
+
"#{ActiveAdmin::Chat.user_model_name}/#{id}/#{ActiveAdmin::Chat.page_name}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Chat
|
3
|
+
class MessagePresenter
|
4
|
+
attr_reader :message
|
5
|
+
|
6
|
+
def initialize(message)
|
7
|
+
@message = message
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.all(messages)
|
11
|
+
{ messages: messages.map { |m| new(m) } }
|
12
|
+
end
|
13
|
+
|
14
|
+
def as_json(*)
|
15
|
+
{
|
16
|
+
id: message.id,
|
17
|
+
message: message.content,
|
18
|
+
date: message.created_at.iso8601(3),
|
19
|
+
is_admin: message.sender.class == ActiveAdmin::Chat.admin_user_klass
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Chat
|
3
|
+
module Generators
|
4
|
+
class InstallGenerator < Rails::Generators::NamedBase
|
5
|
+
argument :name, default: ''
|
6
|
+
class_option :conversation_model_name, type: :string, default: 'conversation'
|
7
|
+
class_option :message_model_name, type: :string, default: 'message'
|
8
|
+
class_option :admin_user_model_name, type: :string, default: 'admin_user'
|
9
|
+
class_option :user_model_name, type: :string, default: 'user'
|
10
|
+
|
11
|
+
source_root File.expand_path('templates', __dir__)
|
12
|
+
|
13
|
+
def normalize_config
|
14
|
+
@conversation_model_name = options['conversation_model_name'].underscore.singularize
|
15
|
+
@message_model_name = options['message_model_name'].underscore.singularize
|
16
|
+
@admin_user_model_name = options['admin_user_model_name'].underscore.singularize
|
17
|
+
@user_model_name = options['user_model_name'].underscore.singularize
|
18
|
+
@messages_per_page = 25
|
19
|
+
end
|
20
|
+
|
21
|
+
def copy_initializer
|
22
|
+
template 'initializers/active_admin/chat.rb.erb',
|
23
|
+
'config/initializers/active_admin/chat.rb'
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_models
|
27
|
+
unless model_exists?(@conversation_model_name)
|
28
|
+
Rails::Generators.invoke(
|
29
|
+
'active_record:model', [
|
30
|
+
@conversation_model_name,
|
31
|
+
"#{@user_model_name.split('/').last}_id:integer:index",
|
32
|
+
'--migration',
|
33
|
+
'--timestamps'
|
34
|
+
]
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
unless model_exists?(@message_model_name)
|
39
|
+
Rails::Generators.invoke(
|
40
|
+
'active_record:model', [
|
41
|
+
@message_model_name,
|
42
|
+
'content:string',
|
43
|
+
'sender:references{polymorphic}',
|
44
|
+
"#{@conversation_model_name.split('/').last}_id:integer:index",
|
45
|
+
'created_at:datetime:index',
|
46
|
+
'updated_at:datetime',
|
47
|
+
'--migration',
|
48
|
+
'--no-timestamps'
|
49
|
+
]
|
50
|
+
)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def inject_models_contents
|
55
|
+
if model_exists?(@conversation_model_name)
|
56
|
+
inject_into_class(
|
57
|
+
model_path(@conversation_model_name),
|
58
|
+
@conversation_model_name.classify,
|
59
|
+
conversation_contents
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
if model_exists?(@message_model_name)
|
64
|
+
inject_into_class(
|
65
|
+
model_path(@message_model_name),
|
66
|
+
@message_model_name.classify,
|
67
|
+
message_contents
|
68
|
+
)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def insert_chat_page
|
73
|
+
template 'pages/chat.rb', 'app/admin/chat.rb'
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def conversation_contents
|
79
|
+
buffer = <<-CONTENT
|
80
|
+
#{add_belongs_to(@user_model_name)}
|
81
|
+
#{add_has_many(@message_model_name)}
|
82
|
+
CONTENT
|
83
|
+
|
84
|
+
buffer
|
85
|
+
end
|
86
|
+
|
87
|
+
def message_contents
|
88
|
+
buffer = <<-CONTENT
|
89
|
+
#{add_belongs_to(@conversation_model_name)}
|
90
|
+
CONTENT
|
91
|
+
|
92
|
+
buffer
|
93
|
+
end
|
94
|
+
|
95
|
+
def add_belongs_to(model_name)
|
96
|
+
if model_name.include?('/')
|
97
|
+
"belongs_to :#{model_name.split('/').last}, class_name: '#{model_name.classify}'"
|
98
|
+
else
|
99
|
+
"belongs_to :#{model_name}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def add_has_many(model_name)
|
104
|
+
relation_name = model_name.split('/').last.pluralize
|
105
|
+
|
106
|
+
if model_name.include?('/')
|
107
|
+
"has_many :#{relation_name}, class_name: #{model_name.classify}, dependent: :destroy"
|
108
|
+
else
|
109
|
+
"has_many :#{relation_name}, dependent: :destroy"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def model_exists?(model_name)
|
114
|
+
File.exist?(File.join(destination_root, model_path(model_name)))
|
115
|
+
end
|
116
|
+
|
117
|
+
def model_path(model_name)
|
118
|
+
File.join('app', 'models', "#{model_name}.rb")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
ActiveAdmin::Chat.setup do |config|
|
2
|
+
# Specify the names of the models required for the chat
|
3
|
+
config.conversation_model_name = '<%= @conversation_model_name %>'
|
4
|
+
config.message_model_name = '<%= @message_model_name %>'
|
5
|
+
config.admin_user_model_name = '<%= @admin_user_model_name %>'
|
6
|
+
config.user_model_name = '<%= @user_model_name %>'
|
7
|
+
config.messages_per_page = <%= @messages_per_page %>
|
8
|
+
end
|
metadata
ADDED
@@ -0,0 +1,270 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: activeadmin-chat
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Santiago Bartesaghi
|
8
|
+
- Federico Aldunate
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2020-10-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activeadmin
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '2.0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '2.0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rails
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '5.2'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '5.2'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: webpacker
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '5.0'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '5.0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: action-cable-testing
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 0.4.0
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.4.0
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: byebug
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 10.0.0
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 10.0.0
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: capybara
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 3.32.2
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 3.32.2
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: factory_bot_rails
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - "~>"
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: 4.11.1
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - "~>"
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 4.11.1
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: generator_spec
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - "~>"
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: 0.9.4
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - "~>"
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 0.9.4
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: puma
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - "~>"
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 4.3.3
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - "~>"
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: 4.3.3
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: rspec-rails
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - "~>"
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '3.8'
|
147
|
+
type: :development
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - "~>"
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '3.8'
|
154
|
+
- !ruby/object:Gem::Dependency
|
155
|
+
name: rubocop
|
156
|
+
requirement: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - "~>"
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: 0.59.2
|
161
|
+
type: :development
|
162
|
+
prerelease: false
|
163
|
+
version_requirements: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - "~>"
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: 0.59.2
|
168
|
+
- !ruby/object:Gem::Dependency
|
169
|
+
name: selenium-webdriver
|
170
|
+
requirement: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - "~>"
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '3.0'
|
175
|
+
type: :development
|
176
|
+
prerelease: false
|
177
|
+
version_requirements: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - "~>"
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '3.0'
|
182
|
+
- !ruby/object:Gem::Dependency
|
183
|
+
name: simplecov
|
184
|
+
requirement: !ruby/object:Gem::Requirement
|
185
|
+
requirements:
|
186
|
+
- - "~>"
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: 0.17.1
|
189
|
+
type: :development
|
190
|
+
prerelease: false
|
191
|
+
version_requirements: !ruby/object:Gem::Requirement
|
192
|
+
requirements:
|
193
|
+
- - "~>"
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
version: 0.17.1
|
196
|
+
- !ruby/object:Gem::Dependency
|
197
|
+
name: sqlite3
|
198
|
+
requirement: !ruby/object:Gem::Requirement
|
199
|
+
requirements:
|
200
|
+
- - ">="
|
201
|
+
- !ruby/object:Gem::Version
|
202
|
+
version: 1.3.0
|
203
|
+
type: :development
|
204
|
+
prerelease: false
|
205
|
+
version_requirements: !ruby/object:Gem::Requirement
|
206
|
+
requirements:
|
207
|
+
- - ">="
|
208
|
+
- !ruby/object:Gem::Version
|
209
|
+
version: 1.3.0
|
210
|
+
description: ActiveAdmin chat plugin
|
211
|
+
email:
|
212
|
+
- santiago.bartesaghi@rootstrap.com
|
213
|
+
- federico@rootstrap.com
|
214
|
+
executables: []
|
215
|
+
extensions: []
|
216
|
+
extra_rdoc_files: []
|
217
|
+
files:
|
218
|
+
- MIT-LICENSE
|
219
|
+
- README.md
|
220
|
+
- Rakefile
|
221
|
+
- app/assets/config/active_admin/chat/manifest.js
|
222
|
+
- app/assets/stylesheets/active_admin/chat.scss
|
223
|
+
- app/assets/stylesheets/active_admin/chat/colors.scss
|
224
|
+
- app/channels/active_admin/chat/admin_channel.rb
|
225
|
+
- app/channels/active_admin/chat/base_channel.rb
|
226
|
+
- app/channels/active_admin/chat/user_channel.rb
|
227
|
+
- app/helpers/active_admin/chat/chat_helper.rb
|
228
|
+
- app/views/active_admin/chat/_chat.html.erb
|
229
|
+
- app/views/active_admin/chat/_list.html.erb
|
230
|
+
- app/views/active_admin/chat/_message.html.erb
|
231
|
+
- app/views/active_admin/chat/_messages.html.erb
|
232
|
+
- app/views/active_admin/chat/show.html.erb
|
233
|
+
- config/routes.rb
|
234
|
+
- lib/active_admin/chat.rb
|
235
|
+
- lib/active_admin/chat/application.rb
|
236
|
+
- lib/active_admin/chat/engine.rb
|
237
|
+
- lib/active_admin/chat/extensions.rb
|
238
|
+
- lib/active_admin/chat/extensions/application.rb
|
239
|
+
- lib/active_admin/chat/extensions/index_table_for.rb
|
240
|
+
- lib/active_admin/chat/message_presenter.rb
|
241
|
+
- lib/active_admin/chat/version.rb
|
242
|
+
- lib/activeadmin-chat.rb
|
243
|
+
- lib/generators/active_admin/chat/install/install_generator.rb
|
244
|
+
- lib/generators/active_admin/chat/install/templates/initializers/active_admin/chat.rb.erb
|
245
|
+
- lib/generators/active_admin/chat/install/templates/pages/chat.rb
|
246
|
+
homepage: https://github.com/rootstrap/activeadmin-chat
|
247
|
+
licenses:
|
248
|
+
- MIT
|
249
|
+
metadata: {}
|
250
|
+
post_install_message:
|
251
|
+
rdoc_options: []
|
252
|
+
require_paths:
|
253
|
+
- lib
|
254
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
255
|
+
requirements:
|
256
|
+
- - ">="
|
257
|
+
- !ruby/object:Gem::Version
|
258
|
+
version: 2.5.0
|
259
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
260
|
+
requirements:
|
261
|
+
- - ">="
|
262
|
+
- !ruby/object:Gem::Version
|
263
|
+
version: '0'
|
264
|
+
requirements: []
|
265
|
+
rubyforge_project:
|
266
|
+
rubygems_version: 2.5.2.3
|
267
|
+
signing_key:
|
268
|
+
specification_version: 4
|
269
|
+
summary: ActiveAdmin chat plugin
|
270
|
+
test_files: []
|