turbo_chat 0.1.2 → 0.1.3
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 +4 -4
- data/README.md +192 -607
- data/app/assets/config/turbo_chat_manifest.js +6 -0
- data/app/assets/javascripts/turbo_chat/application.js +4 -0
- data/app/assets/javascripts/{chat_gem → turbo_chat}/lifecycle_events.js +1 -1
- data/app/assets/javascripts/{chat_gem → turbo_chat}/messages.js +4 -4
- data/app/assets/javascripts/{chat_gem → turbo_chat}/realtime.js +3 -3
- data/app/controllers/turbo_chat/application_controller.rb +66 -0
- data/app/controllers/{chat_gem → turbo_chat}/chat_memberships_controller.rb +4 -4
- data/app/controllers/{chat_gem → turbo_chat}/chat_messages_controller.rb +7 -7
- data/app/controllers/{chat_gem → turbo_chat}/chats_controller/event_payload_support.rb +5 -5
- data/app/controllers/{chat_gem → turbo_chat}/chats_controller/invitation_support.rb +4 -4
- data/app/controllers/{chat_gem → turbo_chat}/chats_controller.rb +10 -10
- data/app/helpers/{chat_gem → turbo_chat}/application_helper/config_support.rb +2 -2
- data/app/helpers/{chat_gem → turbo_chat}/application_helper/mention_support/entry_builder.rb +1 -1
- data/app/helpers/{chat_gem → turbo_chat}/application_helper/mention_support/permission_support.rb +2 -2
- data/app/helpers/{chat_gem → turbo_chat}/application_helper/mention_support/token_builder.rb +1 -1
- data/app/helpers/{chat_gem → turbo_chat}/application_helper/mention_support.rb +5 -5
- data/app/helpers/{chat_gem → turbo_chat}/application_helper/message_rendering.rb +11 -11
- data/app/helpers/{chat_gem → turbo_chat}/application_helper/participant_support.rb +2 -2
- data/app/helpers/turbo_chat/application_helper.rb +12 -0
- data/app/models/{chat_gem → turbo_chat}/application_record.rb +1 -1
- data/app/models/{chat_gem → turbo_chat}/chat.rb +7 -7
- data/app/models/{chat_gem → turbo_chat}/chat_membership.rb +5 -5
- data/app/models/{chat_gem → turbo_chat}/chat_message/blocked_words_moderation.rb +7 -7
- data/app/models/{chat_gem → turbo_chat}/chat_message/body_length_validation.rb +2 -2
- data/app/models/{chat_gem → turbo_chat}/chat_message/broadcasting.rb +1 -1
- data/app/models/{chat_gem → turbo_chat}/chat_message/formatting.rb +3 -3
- data/app/models/{chat_gem → turbo_chat}/chat_message/mention_validation.rb +3 -3
- data/app/models/{chat_gem → turbo_chat}/chat_message/signals.rb +2 -2
- data/app/models/{chat_gem → turbo_chat}/chat_message.rb +11 -11
- data/app/views/layouts/turbo_chat/application.html.erb +20 -0
- data/app/views/turbo_chat/chat_messages/_chat_message.html.erb +1 -0
- data/app/views/{chat_gem → turbo_chat}/chat_messages/_form.html.erb +2 -2
- data/app/views/{chat_gem → turbo_chat}/chat_messages/_message.html.erb +2 -2
- data/app/views/{chat_gem → turbo_chat}/chat_messages/_signals.html.erb +1 -1
- data/app/views/{chat_gem → turbo_chat}/chats/show.html.erb +3 -3
- data/config/routes.rb +1 -1
- data/db/migrate/20260215000000_create_turbo_chat_chats.rb +8 -0
- data/db/migrate/{20260215000001_create_chat_gem_chat_memberships.rb → 20260215000001_create_turbo_chat_chat_memberships.rb} +5 -5
- data/db/migrate/{20260215000002_create_chat_gem_chat_messages.rb → 20260215000002_create_turbo_chat_chat_messages.rb} +4 -4
- data/db/migrate/20260218000011_add_closed_at_to_turbo_chat_chats.rb +6 -0
- data/db/migrate/20260218000012_add_custom_role_key_to_chat_memberships.rb +2 -2
- data/db/migrate/20260218000013_add_invitation_accepted_to_turbo_chat_chat_memberships.rb +5 -0
- data/lib/generators/turbo_chat/install/install_generator.rb +1 -1
- data/lib/generators/turbo_chat/install/templates/turbo_chat.rb +2 -0
- data/lib/tasks/turbo_chat_tasks.rake +6 -2
- data/lib/{chat_gem → turbo_chat}/configuration.rb +4 -2
- data/lib/turbo_chat/engine.rb +29 -0
- data/lib/{chat_gem → turbo_chat}/model_extensions/chat_participant.rb +6 -6
- data/lib/{chat_gem → turbo_chat}/moderation.rb +11 -11
- data/lib/{chat_gem → turbo_chat}/permission.rb +1 -1
- data/lib/{chat_gem → turbo_chat}/signals.rb +5 -5
- data/lib/turbo_chat/version.rb +1 -3
- data/lib/turbo_chat.rb +11 -15
- metadata +53 -58
- data/app/assets/config/chat_gem_manifest.js +0 -6
- data/app/assets/javascripts/chat_gem/application.js +0 -4
- data/app/controllers/chat_gem/application_controller.rb +0 -41
- data/app/helpers/chat_gem/application_helper.rb +0 -12
- data/app/views/chat_gem/chat_messages/_chat_message.html.erb +0 -1
- data/app/views/layouts/chat_gem/application.html.erb +0 -20
- data/db/migrate/20260215000000_create_chat_gem_chats.rb +0 -8
- data/db/migrate/20260218000011_add_closed_at_to_chat_gem_chats.rb +0 -6
- data/db/migrate/20260218000013_add_invitation_accepted_to_chat_gem_chat_memberships.rb +0 -5
- data/lib/chat_gem/engine.rb +0 -29
- data/lib/chat_gem/version.rb +0 -3
- data/lib/chat_gem.rb +0 -24
- data/lib/generators/chat_gem/install/install_generator.rb +0 -18
- data/lib/generators/chat_gem/install/templates/chat_gem.rb +0 -36
- data/lib/tasks/chat_gem_tasks.rake +0 -1
- /data/app/assets/javascripts/{chat_gem → turbo_chat}/shared.js +0 -0
- /data/app/assets/stylesheets/{chat_gem → turbo_chat}/application.css +0 -0
- /data/app/views/{chat_gem → turbo_chat}/chat_messages/_signal.html.erb +0 -0
- /data/app/views/{chat_gem → turbo_chat}/chat_messages/index.html.erb +0 -0
- /data/app/views/{chat_gem → turbo_chat}/chats/index.html.erb +0 -0
- /data/app/views/{chat_gem → turbo_chat}/chats/new.html.erb +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module
|
|
1
|
+
module TurboChat
|
|
2
2
|
class ChatMessage
|
|
3
3
|
module BlockedWordsModeration
|
|
4
4
|
extend ActiveSupport::Concern
|
|
@@ -14,7 +14,7 @@ module ChatGem
|
|
|
14
14
|
|
|
15
15
|
action = blocked_words_action_from_configuration
|
|
16
16
|
emit_blocked_words_event(
|
|
17
|
-
"
|
|
17
|
+
"turbo_chat.blocked_words.detected",
|
|
18
18
|
blocked_words: matches,
|
|
19
19
|
action: action
|
|
20
20
|
)
|
|
@@ -22,7 +22,7 @@ module ChatGem
|
|
|
22
22
|
original_body = body.to_s.dup
|
|
23
23
|
scramble_blocked_words!(blocked_words)
|
|
24
24
|
emit_blocked_words_event(
|
|
25
|
-
"
|
|
25
|
+
"turbo_chat.blocked_words.scrambled",
|
|
26
26
|
blocked_words: matches,
|
|
27
27
|
action: action,
|
|
28
28
|
original_body: original_body,
|
|
@@ -33,7 +33,7 @@ module ChatGem
|
|
|
33
33
|
|
|
34
34
|
errors.add(:body, "contains blocked language")
|
|
35
35
|
emit_blocked_words_event(
|
|
36
|
-
"
|
|
36
|
+
"turbo_chat.blocked_words.rejected",
|
|
37
37
|
blocked_words: matches,
|
|
38
38
|
action: action
|
|
39
39
|
)
|
|
@@ -73,7 +73,7 @@ module ChatGem
|
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
def blocked_words_from_configuration
|
|
76
|
-
configuration =
|
|
76
|
+
configuration = TurboChat.configuration
|
|
77
77
|
return [] unless configuration.respond_to?(:effective_blocked_words)
|
|
78
78
|
|
|
79
79
|
Array(configuration.effective_blocked_words)
|
|
@@ -82,7 +82,7 @@ module ChatGem
|
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
def blocked_words_action_from_configuration
|
|
85
|
-
configuration =
|
|
85
|
+
configuration = TurboChat.configuration
|
|
86
86
|
return "reject" unless configuration.respond_to?(:effective_blocked_words_action)
|
|
87
87
|
|
|
88
88
|
configuration.effective_blocked_words_action.to_s
|
|
@@ -108,7 +108,7 @@ module ChatGem
|
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
def blocked_words_events_enabled?
|
|
111
|
-
configuration =
|
|
111
|
+
configuration = TurboChat.configuration
|
|
112
112
|
return false unless configuration.respond_to?(:emit_blocked_words_events)
|
|
113
113
|
|
|
114
114
|
ActiveModel::Type::Boolean.new.cast(configuration.emit_blocked_words_events)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module
|
|
1
|
+
module TurboChat
|
|
2
2
|
class ChatMessage
|
|
3
3
|
module BodyLengthValidation
|
|
4
4
|
extend ActiveSupport::Concern
|
|
@@ -6,7 +6,7 @@ module ChatGem
|
|
|
6
6
|
private
|
|
7
7
|
|
|
8
8
|
def body_within_max_length
|
|
9
|
-
configured_limit =
|
|
9
|
+
configured_limit = TurboChat.configuration.max_message_length
|
|
10
10
|
return if configured_limit.nil?
|
|
11
11
|
|
|
12
12
|
limit = configured_limit.to_i
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module
|
|
1
|
+
module TurboChat
|
|
2
2
|
class ChatMessage
|
|
3
3
|
module Formatting
|
|
4
4
|
extend ActiveSupport::Concern
|
|
@@ -39,7 +39,7 @@ module ChatGem
|
|
|
39
39
|
|
|
40
40
|
role = membership.effective_role_key
|
|
41
41
|
|
|
42
|
-
formatter =
|
|
42
|
+
formatter = TurboChat.configuration.role_formatter
|
|
43
43
|
formatted = apply_formatter(formatter, role, self)
|
|
44
44
|
return formatted if formatted.present?
|
|
45
45
|
|
|
@@ -55,7 +55,7 @@ module ChatGem
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def formatted_time_for(timestamp)
|
|
58
|
-
formatter =
|
|
58
|
+
formatter = TurboChat.configuration.timestamp_formatter
|
|
59
59
|
formatted = apply_formatter(formatter, timestamp, self)
|
|
60
60
|
return formatted if formatted.present?
|
|
61
61
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module
|
|
1
|
+
module TurboChat
|
|
2
2
|
class ChatMessage
|
|
3
3
|
module MentionValidation
|
|
4
4
|
extend ActiveSupport::Concern
|
|
@@ -6,7 +6,7 @@ module ChatGem
|
|
|
6
6
|
private
|
|
7
7
|
|
|
8
8
|
def mentions_allowed_for_participant
|
|
9
|
-
return unless
|
|
9
|
+
return unless TurboChat.configuration.enable_mentions
|
|
10
10
|
|
|
11
11
|
mentions = mention_tokens
|
|
12
12
|
return if mentions.empty?
|
|
@@ -32,7 +32,7 @@ module ChatGem
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def mention_permission
|
|
35
|
-
adapter =
|
|
35
|
+
adapter = TurboChat.configuration.permission_adapter
|
|
36
36
|
return nil unless adapter.respond_to?(:new)
|
|
37
37
|
|
|
38
38
|
adapter.new(participant, chat)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module
|
|
1
|
+
module TurboChat
|
|
2
2
|
class ChatMessage
|
|
3
3
|
module Signals
|
|
4
4
|
extend ActiveSupport::Concern
|
|
@@ -46,7 +46,7 @@ module ChatGem
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def replace_participant_signals_on_submit
|
|
49
|
-
return unless
|
|
49
|
+
return unless TurboChat.configuration.replace_signals_on_message_submit
|
|
50
50
|
return if chat_id.blank? || participant_type.blank? || participant_id.blank?
|
|
51
51
|
|
|
52
52
|
self.class.where(
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
module
|
|
1
|
+
module TurboChat
|
|
2
2
|
class ChatMessage < ApplicationRecord
|
|
3
3
|
MENTION_PATTERN = /(?<![[:alnum:]_])@[[:alpha:]][[:alnum:]_]{0,31}/.freeze
|
|
4
4
|
ROLE_MENTION_PATTERN = /\A@[A-Z][A-Z0-9_]{0,31}\z/.freeze
|
|
5
5
|
STREAM_NAME = :messages
|
|
6
|
-
MESSAGE_PARTIAL = "
|
|
7
|
-
CHAT_MESSAGE_PARTIAL = "
|
|
8
|
-
SIGNALS_PARTIAL = "
|
|
6
|
+
MESSAGE_PARTIAL = "turbo_chat/chat_messages/message"
|
|
7
|
+
CHAT_MESSAGE_PARTIAL = "turbo_chat/chat_messages/chat_message"
|
|
8
|
+
SIGNALS_PARTIAL = "turbo_chat/chat_messages/signals"
|
|
9
9
|
|
|
10
|
-
include
|
|
11
|
-
include
|
|
12
|
-
include
|
|
13
|
-
include
|
|
14
|
-
include
|
|
15
|
-
include
|
|
10
|
+
include TurboChat::ChatMessage::BodyLengthValidation
|
|
11
|
+
include TurboChat::ChatMessage::Formatting
|
|
12
|
+
include TurboChat::ChatMessage::MentionValidation
|
|
13
|
+
include TurboChat::ChatMessage::BlockedWordsModeration
|
|
14
|
+
include TurboChat::ChatMessage::Signals
|
|
15
|
+
include TurboChat::ChatMessage::Broadcasting
|
|
16
16
|
|
|
17
|
-
belongs_to :chat, class_name: "
|
|
17
|
+
belongs_to :chat, class_name: "TurboChat::Chat", inverse_of: :chat_messages
|
|
18
18
|
belongs_to :participant, polymorphic: true
|
|
19
19
|
|
|
20
20
|
enum :kind, { message: 0, signal: 1 }, default: :message
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>TurboChat</title>
|
|
5
|
+
<%= csrf_meta_tags %>
|
|
6
|
+
<%= csp_meta_tag %>
|
|
7
|
+
<%= action_cable_meta_tag %>
|
|
8
|
+
<% if respond_to?(:turbo_include_tags) %>
|
|
9
|
+
<%= turbo_include_tags %>
|
|
10
|
+
<% end %>
|
|
11
|
+
<%= stylesheet_link_tag "turbo_chat/application", "data-turbo-track": "reload" %>
|
|
12
|
+
<%= javascript_include_tag "turbo_chat/shared", "data-turbo-track": "reload", defer: true %>
|
|
13
|
+
<%= javascript_include_tag "turbo_chat/messages", "data-turbo-track": "reload", defer: true %>
|
|
14
|
+
<%= javascript_include_tag "turbo_chat/realtime", "data-turbo-track": "reload", defer: true %>
|
|
15
|
+
<%= javascript_include_tag "turbo_chat/lifecycle_events", "data-turbo-track": "reload", defer: true %>
|
|
16
|
+
</head>
|
|
17
|
+
<body>
|
|
18
|
+
<%= yield %>
|
|
19
|
+
</body>
|
|
20
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render "turbo_chat/chat_messages/#{chat_message.kind}", chat_message: chat_message %>
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<div class="chat-composer"
|
|
5
5
|
data-chat-composer
|
|
6
6
|
data-chat-id="<%= chat.id %>"
|
|
7
|
-
data-chat-emit-typing-events="<%=
|
|
8
|
-
data-chat-emit-message-events="<%=
|
|
7
|
+
data-chat-emit-typing-events="<%= TurboChat.configuration.emit_typing_events %>"
|
|
8
|
+
data-chat-emit-message-events="<%= TurboChat.configuration.emit_message_events %>"
|
|
9
9
|
data-chat-enable-mentions="<%= mentions_enabled %>"
|
|
10
10
|
data-chat-mention-options="<%= json_escape(mention_options.to_json) %>">
|
|
11
11
|
<%= form_with model: [chat, chat_message], data: { chat_message_form: true }, class: "chat-form" do |f| %>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<% own_message = own_chat_message?(chat_message) %>
|
|
2
|
-
<% show_timestamp =
|
|
3
|
-
<% show_role =
|
|
2
|
+
<% show_timestamp = TurboChat.configuration.show_timestamp %>
|
|
3
|
+
<% show_role = TurboChat.configuration.show_role %>
|
|
4
4
|
<% role_label = show_role ? chat_message.formatted_participant_role : nil %>
|
|
5
5
|
<% edited_message = chat_message.respond_to?(:edited?) && chat_message.edited? %>
|
|
6
6
|
<% bubble_style = chat_message_inline_style(chat_message: chat_message, own_message: own_message) %>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<% show_self_signals =
|
|
1
|
+
<% show_self_signals = TurboChat.configuration.show_self_signals %>
|
|
2
2
|
<% current_participant = respond_to?(:current_chat_participant, true) ? current_chat_participant : nil %>
|
|
3
3
|
<% current_participant_type = current_participant&.class&.base_class&.name %>
|
|
4
4
|
<% current_participant_id = current_participant&.id %>
|
|
@@ -80,15 +80,15 @@
|
|
|
80
80
|
|
|
81
81
|
<div id="<%= dom_id(@chat, :signals) %>"
|
|
82
82
|
class="chat-signals"
|
|
83
|
-
data-chat-show-self-signals="<%=
|
|
83
|
+
data-chat-show-self-signals="<%= TurboChat.configuration.show_self_signals %>"
|
|
84
84
|
data-chat-self-participant-type="<%= current_participant_type %>"
|
|
85
85
|
data-chat-self-participant-id="<%= current_participant_id %>">
|
|
86
|
-
<%= render "
|
|
86
|
+
<%= render "turbo_chat/chat_messages/signals", chat: @chat %>
|
|
87
87
|
</div>
|
|
88
88
|
</section>
|
|
89
89
|
|
|
90
90
|
<% if @can_post_message %>
|
|
91
|
-
<%= render "
|
|
91
|
+
<%= render "turbo_chat/chat_messages/form", chat: @chat, chat_message: @chat_message, chat_permission: @chat_permission %>
|
|
92
92
|
<% elsif @chat.closed? %>
|
|
93
93
|
<p class="chat-banner chat-banner--muted">This chat is closed.</p>
|
|
94
94
|
<% end %>
|
data/config/routes.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
class
|
|
1
|
+
class CreateTurboChatChatMemberships < ActiveRecord::Migration[7.0]
|
|
2
2
|
def change
|
|
3
|
-
create_table :
|
|
4
|
-
t.references :chat, null: false, foreign_key: { to_table: :
|
|
3
|
+
create_table :turbo_chat_chat_memberships do |t|
|
|
4
|
+
t.references :chat, null: false, foreign_key: { to_table: :turbo_chat_chats }
|
|
5
5
|
t.references :participant, polymorphic: true, null: false
|
|
6
6
|
t.integer :role, null: false, default: 0
|
|
7
7
|
t.boolean :muted, null: false, default: false
|
|
@@ -10,10 +10,10 @@ class CreateChatGemChatMemberships < ActiveRecord::Migration[7.0]
|
|
|
10
10
|
t.timestamps
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
add_index :
|
|
13
|
+
add_index :turbo_chat_chat_memberships,
|
|
14
14
|
%i[chat_id participant_type participant_id],
|
|
15
15
|
unique: true,
|
|
16
16
|
where: "removed_at IS NULL",
|
|
17
|
-
name: "
|
|
17
|
+
name: "index_turbo_chat_memberships_on_chat_participant_active"
|
|
18
18
|
end
|
|
19
19
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
class
|
|
1
|
+
class CreateTurboChatChatMessages < ActiveRecord::Migration[7.0]
|
|
2
2
|
def change
|
|
3
|
-
create_table :
|
|
4
|
-
t.references :chat, null: false, foreign_key: { to_table: :
|
|
3
|
+
create_table :turbo_chat_chat_messages do |t|
|
|
4
|
+
t.references :chat, null: false, foreign_key: { to_table: :turbo_chat_chats }
|
|
5
5
|
t.references :participant, polymorphic: true, null: false
|
|
6
6
|
t.text :body
|
|
7
7
|
t.integer :kind, null: false, default: 0
|
|
@@ -9,6 +9,6 @@ class CreateChatGemChatMessages < ActiveRecord::Migration[7.0]
|
|
|
9
9
|
t.timestamps
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
add_index :
|
|
12
|
+
add_index :turbo_chat_chat_messages, %i[chat_id created_at id], name: "index_turbo_chat_messages_order"
|
|
13
13
|
end
|
|
14
14
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class AddCustomRoleKeyToChatMemberships < ActiveRecord::Migration[7.0]
|
|
2
2
|
def change
|
|
3
|
-
add_column :
|
|
4
|
-
add_index :
|
|
3
|
+
add_column :turbo_chat_chat_memberships, :custom_role_key, :string
|
|
4
|
+
add_index :turbo_chat_chat_memberships, :custom_role_key
|
|
5
5
|
end
|
|
6
6
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
TurboChat.configure do |config|
|
|
2
2
|
config.permission_adapter = TurboChat::Permission
|
|
3
|
+
# If your auth method is not `current_user`, wire it here.
|
|
4
|
+
# config.current_participant_resolver = ->(controller) { controller.send(:current_member) }
|
|
3
5
|
config.max_chat_participants = 10
|
|
4
6
|
config.max_message_length = 1000
|
|
5
7
|
config.message_history_limit = 200
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
namespace :turbo_chat do
|
|
2
2
|
namespace :install do
|
|
3
|
-
desc "Install TurboChat migrations
|
|
3
|
+
desc "Install TurboChat migrations"
|
|
4
4
|
task :migrations do
|
|
5
|
-
|
|
5
|
+
previous_from = ENV["FROM"]
|
|
6
|
+
ENV["FROM"] = "turbo_chat"
|
|
7
|
+
task = Rake::Task["railties:install:migrations"]
|
|
6
8
|
task.reenable
|
|
7
9
|
task.invoke
|
|
10
|
+
ensure
|
|
11
|
+
ENV["FROM"] = previous_from
|
|
8
12
|
end
|
|
9
13
|
end
|
|
10
14
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module
|
|
1
|
+
module TurboChat
|
|
2
2
|
class Configuration
|
|
3
3
|
DEFAULT_ROLE_DEFINITIONS = {
|
|
4
4
|
"member" => {
|
|
@@ -41,6 +41,7 @@ module ChatGem
|
|
|
41
41
|
DEFAULT_BLOCKED_WORDS_ACTION = "reject".freeze
|
|
42
42
|
|
|
43
43
|
attr_accessor :permission_adapter,
|
|
44
|
+
:current_participant_resolver,
|
|
44
45
|
:max_chat_participants,
|
|
45
46
|
:max_message_length,
|
|
46
47
|
:message_history_limit,
|
|
@@ -77,7 +78,8 @@ module ChatGem
|
|
|
77
78
|
:role_formatter
|
|
78
79
|
|
|
79
80
|
def initialize
|
|
80
|
-
@permission_adapter =
|
|
81
|
+
@permission_adapter = TurboChat::Permission
|
|
82
|
+
@current_participant_resolver = nil
|
|
81
83
|
@max_chat_participants = 10
|
|
82
84
|
@max_message_length = 1000
|
|
83
85
|
@message_history_limit = 200
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module TurboChat
|
|
2
|
+
class Engine < ::Rails::Engine
|
|
3
|
+
isolate_namespace TurboChat
|
|
4
|
+
|
|
5
|
+
initializer "turbo_chat.helpers" do
|
|
6
|
+
ActiveSupport.on_load(:action_controller_base) do
|
|
7
|
+
helper TurboChat::ApplicationHelper
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
ActiveSupport.on_load(:action_view) do
|
|
11
|
+
include TurboChat::ApplicationHelper
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
initializer "turbo_chat.assets.precompile" do |app|
|
|
16
|
+
next unless app.config.respond_to?(:assets)
|
|
17
|
+
next unless app.config.assets.respond_to?(:precompile)
|
|
18
|
+
|
|
19
|
+
app.config.assets.precompile += %w[
|
|
20
|
+
turbo_chat/application.css
|
|
21
|
+
turbo_chat/application.js
|
|
22
|
+
turbo_chat/shared.js
|
|
23
|
+
turbo_chat/messages.js
|
|
24
|
+
turbo_chat/realtime.js
|
|
25
|
+
turbo_chat/lifecycle_events.js
|
|
26
|
+
]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module
|
|
1
|
+
module TurboChat
|
|
2
2
|
module ModelExtensions
|
|
3
3
|
module ChatParticipant
|
|
4
4
|
module ClassMethods
|
|
@@ -8,22 +8,22 @@ module ChatGem
|
|
|
8
8
|
has_many :chat_memberships,
|
|
9
9
|
-> { order(created_at: :asc, id: :asc) },
|
|
10
10
|
as: :participant,
|
|
11
|
-
class_name: "
|
|
11
|
+
class_name: "TurboChat::ChatMembership",
|
|
12
12
|
dependent: :destroy
|
|
13
13
|
|
|
14
14
|
has_many :chat_messages,
|
|
15
15
|
-> { order(created_at: :asc, id: :asc) },
|
|
16
16
|
as: :participant,
|
|
17
|
-
class_name: "
|
|
17
|
+
class_name: "TurboChat::ChatMessage",
|
|
18
18
|
dependent: :destroy
|
|
19
19
|
|
|
20
20
|
has_many :chats,
|
|
21
21
|
-> { distinct },
|
|
22
22
|
through: :chat_memberships,
|
|
23
23
|
source: :chat,
|
|
24
|
-
class_name: "
|
|
24
|
+
class_name: "TurboChat::Chat"
|
|
25
25
|
|
|
26
|
-
include
|
|
26
|
+
include TurboChat::ModelExtensions::ChatParticipant::InstanceMethods
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
@@ -41,5 +41,5 @@ module ChatGem
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
ActiveSupport.on_load(:active_record) do
|
|
44
|
-
extend
|
|
44
|
+
extend TurboChat::ModelExtensions::ChatParticipant::ClassMethods
|
|
45
45
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module
|
|
1
|
+
module TurboChat
|
|
2
2
|
module Moderation
|
|
3
3
|
class AuthorizationError < StandardError; end
|
|
4
4
|
class InvalidActionError < StandardError; end
|
|
@@ -12,7 +12,7 @@ module ChatGem
|
|
|
12
12
|
attributes: { muted: true }
|
|
13
13
|
)
|
|
14
14
|
|
|
15
|
-
emit_moderation_event("
|
|
15
|
+
emit_moderation_event("turbo_chat.moderation.member_muted", actor: actor, membership: updated_membership)
|
|
16
16
|
updated_membership
|
|
17
17
|
end
|
|
18
18
|
|
|
@@ -24,7 +24,7 @@ module ChatGem
|
|
|
24
24
|
attributes: { muted: false }
|
|
25
25
|
)
|
|
26
26
|
|
|
27
|
-
emit_moderation_event("
|
|
27
|
+
emit_moderation_event("turbo_chat.moderation.member_unmuted", actor: actor, membership: updated_membership)
|
|
28
28
|
updated_membership
|
|
29
29
|
end
|
|
30
30
|
|
|
@@ -34,7 +34,7 @@ module ChatGem
|
|
|
34
34
|
|
|
35
35
|
membership.update!(timed_out_until: until_time)
|
|
36
36
|
emit_moderation_event(
|
|
37
|
-
"
|
|
37
|
+
"turbo_chat.moderation.member_timed_out",
|
|
38
38
|
actor: actor,
|
|
39
39
|
membership: membership,
|
|
40
40
|
extra: { timed_out_until: membership.timed_out_until }
|
|
@@ -50,7 +50,7 @@ module ChatGem
|
|
|
50
50
|
attributes: { timed_out_until: nil }
|
|
51
51
|
)
|
|
52
52
|
|
|
53
|
-
emit_moderation_event("
|
|
53
|
+
emit_moderation_event("turbo_chat.moderation.member_timeout_cleared", actor: actor, membership: updated_membership)
|
|
54
54
|
updated_membership
|
|
55
55
|
end
|
|
56
56
|
|
|
@@ -66,7 +66,7 @@ module ChatGem
|
|
|
66
66
|
}
|
|
67
67
|
)
|
|
68
68
|
|
|
69
|
-
emit_moderation_event("
|
|
69
|
+
emit_moderation_event("turbo_chat.moderation.member_banned", actor: actor, membership: updated_membership)
|
|
70
70
|
updated_membership
|
|
71
71
|
end
|
|
72
72
|
|
|
@@ -76,21 +76,21 @@ module ChatGem
|
|
|
76
76
|
|
|
77
77
|
payload = moderation_message_payload(message)
|
|
78
78
|
message.destroy!
|
|
79
|
-
emit_moderation_event("
|
|
79
|
+
emit_moderation_event("turbo_chat.moderation.message_deleted", actor: actor, payload: payload)
|
|
80
80
|
true
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
def close_chat!(actor:, chat:)
|
|
84
84
|
authorize_chat_action!(actor: actor, chat: chat, gate: :can_close_chat?, error_message: "Not allowed to close chat")
|
|
85
85
|
chat.close!
|
|
86
|
-
emit_moderation_event("
|
|
86
|
+
emit_moderation_event("turbo_chat.moderation.chat_closed", actor: actor, payload: moderation_chat_payload(chat))
|
|
87
87
|
chat
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
def reopen_chat!(actor:, chat:)
|
|
91
91
|
authorize_chat_action!(actor: actor, chat: chat, gate: :can_reopen_chat?, error_message: "Not allowed to reopen chat")
|
|
92
92
|
chat.reopen!
|
|
93
|
-
emit_moderation_event("
|
|
93
|
+
emit_moderation_event("turbo_chat.moderation.chat_reopened", actor: actor, payload: moderation_chat_payload(chat))
|
|
94
94
|
chat
|
|
95
95
|
end
|
|
96
96
|
|
|
@@ -121,7 +121,7 @@ module ChatGem
|
|
|
121
121
|
end
|
|
122
122
|
|
|
123
123
|
def permission_for(actor, chat)
|
|
124
|
-
|
|
124
|
+
TurboChat.configuration.permission_adapter.new(actor, chat)
|
|
125
125
|
end
|
|
126
126
|
|
|
127
127
|
def emit_moderation_event(name, actor:, membership: nil, payload: nil, extra: {})
|
|
@@ -142,7 +142,7 @@ module ChatGem
|
|
|
142
142
|
end
|
|
143
143
|
|
|
144
144
|
def moderation_events_enabled?
|
|
145
|
-
config =
|
|
145
|
+
config = TurboChat.configuration
|
|
146
146
|
return false unless config.respond_to?(:emit_moderation_events)
|
|
147
147
|
|
|
148
148
|
ActiveModel::Type::Boolean.new.cast(config.emit_moderation_events)
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
module
|
|
1
|
+
module TurboChat
|
|
2
2
|
module Signals
|
|
3
3
|
module_function
|
|
4
4
|
|
|
5
5
|
def start!(chat:, participant:, signal_type: :typing)
|
|
6
|
-
|
|
6
|
+
TurboChat::ChatMessage.replace_signal!(chat: chat, participant: participant, signal_type: signal_type)
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
def replace!(chat:, participant:, signal_type: :typing)
|
|
10
|
-
|
|
10
|
+
TurboChat::ChatMessage.replace_signal!(chat: chat, participant: participant, signal_type: signal_type)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def clear!(chat:, participant:)
|
|
14
|
-
|
|
14
|
+
TurboChat::ChatMessage.clear_signals!(chat: chat, participant: participant)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def with(chat:, participant:, signal_type: :typing, &block)
|
|
18
|
-
|
|
18
|
+
TurboChat::ChatMessage.with_signal(
|
|
19
19
|
chat: chat,
|
|
20
20
|
participant: participant,
|
|
21
21
|
signal_type: signal_type,
|
data/lib/turbo_chat/version.rb
CHANGED
data/lib/turbo_chat.rb
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
require "turbo_chat/version"
|
|
2
|
+
require "turbo-rails"
|
|
3
|
+
require "turbo_chat/configuration"
|
|
4
|
+
require "turbo_chat/model_extensions/chat_participant"
|
|
5
|
+
require "turbo_chat/permission"
|
|
6
|
+
require "turbo_chat/moderation"
|
|
7
|
+
require "turbo_chat/signals"
|
|
8
|
+
require "turbo_chat/engine"
|
|
3
9
|
|
|
4
10
|
module TurboChat
|
|
5
11
|
class << self
|
|
6
12
|
def configuration
|
|
7
|
-
|
|
13
|
+
@configuration ||= TurboChat::Configuration.new
|
|
8
14
|
end
|
|
9
15
|
|
|
10
|
-
def configure
|
|
11
|
-
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def table_name_prefix
|
|
15
|
-
ChatGem.table_name_prefix
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def const_missing(name)
|
|
19
|
-
return ChatGem.const_get(name) if ChatGem.const_defined?(name)
|
|
20
|
-
|
|
21
|
-
super
|
|
16
|
+
def configure
|
|
17
|
+
yield(configuration)
|
|
22
18
|
end
|
|
23
19
|
end
|
|
24
20
|
end
|