Chat

Allows current site visitors to chat with each other
no way ~109.42.1.243 6 days ago
yes ~89.3.236.207 6 days ago
hello ~82.3.252.190 6 days ago
again ~82.3.252.190 6 days ago
another ~82.3.252.190 6 days ago
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi scelerisque dui at dapibus tincidunt. In eleifend ante sit amet rhoncus cursus. Nullam erat lacus, ultrices vel molestie eu, luctus id enim. ~82.3.252.190 6 days ago
SIema ~89.64.16.26 6 days ago
fox ~111.240.38.62 6 days ago
fsfda ~111.240.38.62 6 days ago
fdaf ~111.240.38.62 6 days ago
hi ~223.29.224.166 5 days ago
hi ~223.29.224.166 5 days ago
möp ~89.244.238.16 5 days ago
Wat ~174.233.9.61 5 days ago
Ohh hello ~132.157.66.33 5 days ago
ol ~186.54.99.19 5 days ago
wups ~187.192.187.200 5 days ago
yeao ~187.192.187.200 5 days ago
What's up ~137.97.159.78 5 days ago
Oh ~137.97.159.78 5 days ago
Red chat ~73.63.182.7 4 days ago
xyzzy ~76.95.204.84 4 days ago
junts ~76.218.232.143 4 days ago
asdsa ~186.54.44.144 4 days ago
asd ~186.54.44.144 4 days ago
oi ~201.69.253.217 4 days ago
Jj ~86.238.197.239 4 days ago
asdasd ~95.90.235.245 4 days ago
test ~71.239.22.9 4 days ago
hb ~82.10.8.32 4 days ago
whats up ~71.239.22.9 4 days ago
will it update without refresh? ~71.239.22.9 4 days ago
asd ~116.66.189.190 3 days ago
Hey ~179.162.101.1 3 days ago
delta ~190.233.206.152 3 days ago
123 ~122.117.159.176 3 days ago
.................................................... ~82.10.8.32 3 days ago
Hey! ~91.223.167.193 3 days ago
ngfnhg ~213.174.0.249 3 days ago
hfjykgkg ~213.174.0.249 3 days ago
dfsdf ~151.231.14.122 3 days ago
dfd ~151.231.14.122 3 days ago
asxaxasx ~122.175.195.50 3 days ago
hello ~88.232.14.72 3 days ago
mmmm ~81.242.141.42 3 days ago
中文测试 ~185.171.123.229 2 days ago
Testing ~24.52.219.109 2 days ago
Testing again ~70.151.49.222 2 days ago
This is slower. ~70.151.49.222 2 days ago
bah ~139.47.66.80 2 days ago
bah baj bla ~139.47.66.80 2 days ago
~139.47.66.80 2 days ago
Hhh ~91.173.77.40 2 days ago
foo ~5.44.169.211 2 days ago
fef ~78.236.182.140 1 day ago
~78.236.182.140 1 day ago
fsf ~119.160.99.52 1 day ago
x ~84.244.73.226 1 day ago
~84.244.73.226 1 day ago
sdasdas a ~186.53.127.229 1 day ago
dasdasda ~186.53.127.229 1 day ago
dasdasd ~186.53.127.229 1 day ago
dasdasd ~186.53.127.229 1 day ago
dasdasd ~186.53.127.229 1 day ago
mnm ~62.48.204.231 1 day ago
ssss ~190.113.209.249 1 day ago
wooo ~72.48.211.189 1 day ago
e ~91.234.137.252 1 day ago
ng ~91.234.137.252 1 day ago
Hehehehe ~177.53.37.4 1 day ago
yellow ~191.162.212.187 1 day ago
asd ~169.1.22.195 about 16 hours ago
dsa ~169.1.22.195 about 16 hours ago
hello great library ~213.194.188.226 about 14 hours ago
hello there ~94.153.175.14 about 12 hours ago
Test ~140.213.16.10 about 11 hours ago
Master red ~170.82.253.148 about 5 hours ago
sdasd ~187.109.134.252 about 5 hours ago
qwlfsadf foif;oaf ~170.82.253.148 about 5 hours ago
what a nice yellow chat ~109.42.1.243 6 days ago
rest ~111.240.38.62 6 days ago
fdaf ~111.240.38.62 6 days ago
sd ~186.54.99.19 5 days ago
drep ~187.192.187.200 5 days ago
Nice ~137.97.159.78 5 days ago
Hi ~137.97.159.78 5 days ago
runts ~76.218.232.143 4 days ago
asd ~116.66.189.190 3 days ago
asd ~116.66.189.190 3 days ago
efefe ~135.19.3.160 3 days ago
ddd ~88.232.14.72 3 days ago
ftft ~101.108.97.231 1 day ago
Hola ~191.162.212.187 1 day ago
fwaq ~169.1.22.195 about 16 hours ago
I like stimulus reflex ~213.194.188.226 about 14 hours ago
et ~220.80.214.114 about 10 hours ago
~220.80.214.114 about 10 hours ago
:O ~89.64.16.26 6 days ago
bad ~111.240.38.62 6 days ago
jkh ~186.54.99.19 5 days ago
drap ~187.192.187.200 5 days ago
There there ~137.97.159.78 5 days ago
asd ~116.66.189.190 3 days ago
sum ~190.233.206.152 3 days ago
d ~88.232.14.72 3 days ago
blue ~66.44.112.29 2 days ago
asd ~186.32.251.128 2 days ago
Hi ~84.104.228.17 1 day ago
green ~177.53.37.4 1 day ago
das ~169.1.22.195 about 16 hours ago
000 ~203.184.132.124 about 8 hours ago
It works (TM) ~75.3.245.198 about 5 hours ago

Code (117 LOC)

ERB (41 LOC)
app/views/chats/_demo.html.erb (16 LOC)
<ul class="nav nav-tabs">
<li class="nav-item">
<a data-toggle="tab" data-reflex="click->ChatReflex#set_color" href="#red" class="nav-link <%= "active" if active_chat?(:red) %>">Red Chat</a>
</li>
<li class="nav-item">
<a data-toggle="tab" data-reflex="click->ChatReflex#set_color" href="#yellow" class="nav-link <%= "active" if active_chat?(:yellow) %>">Yellow Chat</a>
</li>
<li class="nav-item">
<a data-toggle="tab" data-reflex="click->ChatReflex#set_color" href="#blue" class="nav-link <%= "active" if active_chat?(:blue) %>">Blue Chat</a>
</li>
</ul>
<div class="tab-content">
<%= render "color", color: "red" %>
<%= render "color", color: "yellow" %>
<%= render "color", color: "blue" %>
</div>
app/views/chats/_color.html.erb (25 LOC)
<div id="<%= color %>" data-color="<%= color %>"
data-controller="chat" data-action="chats:added@document->chat#reload cable-ready:after-morph@document->chat#scroll"
class="<%= css "tab-pane bg-white p-4 border border-top-0", "show active": active_chat?(color) %>">
<div data-target="chat.list" class="bg-light border rounded mb-2 p-3" style="height:400px; max-width:800px; overflow-y:scroll;">
<% @chats.select { |chat| chat[:color] == color }.each do |chat| %>
<% if chat_author? chat %>
<div class="<%= chat_css color %> rounded-lg border my-2 p-1 px-2 text-right w-75 float-right">
<%= chat[:message] %>
<small class="opacity-30 d-block">~me <%= distance_of_time_in_words_to_now Time.parse(chat[:created_at]) %> ago</small>
</div>
<% else %>
<div class="bg-light rounded-lg border my-2 p-1 px-2 text-left w-75 float-left">
<%= chat[:message] %>
<small class="opacity-30 d-block">~<%= chat[:author] %> <%= distance_of_time_in_words_to_now Time.parse(chat[:created_at]) %> ago</small>
</div>
<% end %>
<% end %>
</div>
<form style="max-width:800px;">
<div class="form-group">
<textarea data-target="chat.input" class="form-control border <%= chat_border_css color %>" rows="3" placeholder="Type your message..."></textarea>
</div>
<button data-action="click->chat#post" type="submit" class="btn btn-primary btn-lg">Submit</button>
</form>
</div>
JavaScript (48 LOC)
app/javascript/controllers/chat_controller.js (41 LOC)
import Rails from '@rails/ujs'
import { debounce } from 'lodash-es'
import ApplicationController from './application_controller'
let lastMessageId
const reload = controller => {
controller.stimulate('ChatReflex#reload')
}
const debouncedReload = debounce(reload, 100)
export default class extends ApplicationController {
static targets = ['list', 'input']
connect () {
super.connect()
this.scroll(100)
}
post (event) {
Rails.stopEverything(event)
lastMessageId = Math.random()
this.stimulate(
'ChatReflex#post',
this.element.dataset.color,
this.inputTarget.value,
lastMessageId
)
}
afterPost () {
this.inputTarget.value = ''
this.inputTarget.focus()
this.scroll(1)
}
scroll (delay = 10) {
const lists = document.querySelectorAll('[data-target="chat.list"]')
setTimeout(() => {
lists.forEach(e => (e.scrollTop = e.scrollHeight))
}, delay)
}
reload (event) {
const { messageId } = event.detail
if (messageId === lastMessageId) return
debouncedReload(this)
}
}
app/javascript/channels/chat_channel.js (7 LOC)
import consumer from './consumer'
import CableReady from 'cable_ready'
consumer.subscriptions.create('ChatChannel', {
received (data) {
if (data.cableReady) CableReady.perform(data.operations)
}
})
Ruby (28 LOC)
app/controllers/chats_controller.rb (6 LOC)
class ChatsController < ApplicationController
def show
session[:chat_color] ||= "red"
@chats ||= Rails.cache.read(:chats) || []
end
end
app/reflexes/chat_reflex.rb (22 LOC)
class ChatReflex < ApplicationReflex
include CableReady::Broadcaster
def post(color, message, message_id)
@chats = Rails.cache.read(:chats) || []
@chats.shift while @chats.size > 1000
@chats << {
id: message_id,
color: color,
author: request.remote_ip,
message: message,
created_at: Time.current.iso8601,
}
Rails.cache.write :chats, @chats
cable_ready["chat"].dispatch_event name: "chats:added", detail: {message_id: message_id}
cable_ready.broadcast
end
def set_color
session[:chat_color] = element[:href].delete("#")
end
def reload
end
end