MVP version. Added actioncables for counting.
This commit is contained in:
parent
6361a50230
commit
3f97cc59b2
26
app/channels/count_channel.rb
Normal file
26
app/channels/count_channel.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class CountChannel < ApplicationCable::Channel
|
||||||
|
def subscribed
|
||||||
|
# TODO: check to make sure this is unique.
|
||||||
|
stream_from 'chat'
|
||||||
|
end
|
||||||
|
|
||||||
|
def increment(_payload = 1)
|
||||||
|
cluster = Cluster.list.values.first
|
||||||
|
cluster.increment
|
||||||
|
ActionCable.server.broadcast 'chat', message: render(cluster)
|
||||||
|
end
|
||||||
|
|
||||||
|
def decrement(_payload = 1)
|
||||||
|
cluster = Cluster.list.values.first
|
||||||
|
cluster.decrement
|
||||||
|
ActionCable.server.broadcast 'chat', message: render(cluster)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def render(cluster)
|
||||||
|
ApplicationController.new.helpers.c('counter-count', cluster: cluster)
|
||||||
|
end
|
||||||
|
end
|
|
@ -9,7 +9,7 @@ class ClusterController < ApplicationController
|
||||||
|
|
||||||
def create
|
def create
|
||||||
cluster = Cluster.new(params[:cluster])
|
cluster = Cluster.new(params[:cluster])
|
||||||
session[:cluster_uuid] = cluster.uuid;
|
session[:cluster_uuid] = cluster.uuid
|
||||||
redirect_to root_path
|
redirect_to root_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
class CounterController < ApplicationController
|
class CounterController < ApplicationController
|
||||||
before_action :associate!
|
before_action :associate!
|
||||||
|
|
||||||
def show; end
|
def show
|
||||||
|
@cluster = Cluster.get(session[:cluster_uuid])
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,3 @@
|
||||||
<section class="section">
|
<%= c("page") do %>
|
||||||
<div class="container">
|
<%= c("counter-view") %>
|
||||||
<h1 class="title">
|
<% end %>
|
||||||
Hello World
|
|
||||||
</h1>
|
|
||||||
<p class="subtitle">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="fas fa-home"></i>
|
|
||||||
</span>
|
|
||||||
My first website with <strong>Bulma</strong>!
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
13
frontend/client/cable.js
Normal file
13
frontend/client/cable.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import cable from "actioncable";
|
||||||
|
|
||||||
|
let consumer;
|
||||||
|
|
||||||
|
const createChannel = (...args) => {
|
||||||
|
if (!consumer) {
|
||||||
|
consumer = cable.createConsumer();
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumer.subscriptions.create(...args);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default createChannel;
|
20
frontend/client/counter.js
Normal file
20
frontend/client/counter.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import createChannel from "client/cable";
|
||||||
|
|
||||||
|
let callback; // declaring a variable that will hold a function later
|
||||||
|
|
||||||
|
const chat2 = createChannel("CountChannel", {
|
||||||
|
received({ message }) {
|
||||||
|
if (callback) callback.call(null, message);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const sendIncrement = (message) => chat2.perform("increment", { message });
|
||||||
|
const sendDecrement = (message) => chat2.perform("decrement", { message });
|
||||||
|
|
||||||
|
// Getting a message: this callback will be invoked once we receive
|
||||||
|
// something over ChatChannel
|
||||||
|
const setCallback = (fn) => {
|
||||||
|
callback = fn;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { sendIncrement, sendDecrement, setCallback };
|
|
@ -33,3 +33,5 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -*- mode: css; -*- */
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<%= cluster.count %>
|
12
frontend/components/counter-count/counter-count.js
Normal file
12
frontend/components/counter-count/counter-count.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import "./counter-count.pcss";
|
||||||
|
|
||||||
|
import { setCallback } from "client/counter";
|
||||||
|
|
||||||
|
window.addEventListener("DOMContentLoaded", () => {
|
||||||
|
const currentCount = document.querySelector(".count");
|
||||||
|
if (currentCount) {
|
||||||
|
setCallback((message) => {
|
||||||
|
currentCount.innerHTML = message;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
1
frontend/components/counter-count/counter-count.pcss
Normal file
1
frontend/components/counter-count/counter-count.pcss
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/* placeholder */
|
|
@ -0,0 +1,3 @@
|
||||||
|
<a class="counter-down-btn">
|
||||||
|
<i class="fas fa-angle-double-down"></i>
|
||||||
|
</a>
|
13
frontend/components/counter-down-btn/counter-down-btn.js
Normal file
13
frontend/components/counter-down-btn/counter-down-btn.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import "./counter-down-btn.pcss";
|
||||||
|
|
||||||
|
import { sendDecrement } from "client/counter";
|
||||||
|
|
||||||
|
window.addEventListener("DOMContentLoaded", () => {
|
||||||
|
const btn = document.querySelector(".counter-down-btn");
|
||||||
|
if (btn) {
|
||||||
|
btn.addEventListener("click", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
sendDecrement(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1 @@
|
||||||
|
/* placeholder */
|
|
@ -0,0 +1,3 @@
|
||||||
|
<a class="counter-up-btn">
|
||||||
|
<i class="fas fa-angle-double-up"></i>
|
||||||
|
</a>
|
13
frontend/components/counter-up-btn/counter-up-btn.js
Normal file
13
frontend/components/counter-up-btn/counter-up-btn.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import "./counter-up-btn.pcss";
|
||||||
|
|
||||||
|
import { sendIncrement } from "client/counter";
|
||||||
|
|
||||||
|
window.addEventListener("DOMContentLoaded", () => {
|
||||||
|
const btn = document.querySelector(".counter-up-btn");
|
||||||
|
if (btn) {
|
||||||
|
btn.addEventListener("click", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
sendIncrement(-1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
1
frontend/components/counter-up-btn/counter-up-btn.pcss
Normal file
1
frontend/components/counter-up-btn/counter-up-btn.pcss
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/* placeholder */
|
11
frontend/components/counter-view/_counter-view.html.erb
Normal file
11
frontend/components/counter-view/_counter-view.html.erb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<div class="counter-view">
|
||||||
|
<div class="row">
|
||||||
|
<%= c("counter-up-btn") %>
|
||||||
|
</div>
|
||||||
|
<div class="row count">
|
||||||
|
<%= c("counter-count", cluster: @cluster) %>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<%= c("counter-down-btn") %>
|
||||||
|
</div>
|
||||||
|
</div>
|
5
frontend/components/counter-view/counter-view.js
Normal file
5
frontend/components/counter-view/counter-view.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import "./counter-view.pcss";
|
||||||
|
|
||||||
|
import "components/counter-up-btn/counter-up-btn";
|
||||||
|
import "components/counter-count/counter-count";
|
||||||
|
import "components/counter-down-btn/counter-down-btn";
|
16
frontend/components/counter-view/counter-view.pcss
Normal file
16
frontend/components/counter-view/counter-view.pcss
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
.counter-view {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
& .row {
|
||||||
|
display: flex;
|
||||||
|
height: 33%;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 4rem;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
.page {
|
.page {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 700px;
|
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
max-width: 700px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,3 +2,4 @@ import "init";
|
||||||
|
|
||||||
import "components/page/page";
|
import "components/page/page";
|
||||||
import "components/cluster-view/cluster-view";
|
import "components/cluster-view/cluster-view";
|
||||||
|
import "components/counter-view/counter-view";
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"@rails/actioncable": "^6.0.0",
|
"@rails/actioncable": "^6.0.0",
|
||||||
"@rails/ujs": "^6.0.0",
|
"@rails/ujs": "^6.0.0",
|
||||||
"@rails/webpacker": "4.2.2",
|
"@rails/webpacker": "4.2.2",
|
||||||
|
"actioncable": "^5.2.4-3",
|
||||||
"bulma": "^0.8.2",
|
"bulma": "^0.8.2",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
"postcss-flexbugs-fixes": "^4.2.1",
|
"postcss-flexbugs-fixes": "^4.2.1",
|
||||||
|
|
10
test/channels/count_channel_test.rb
Normal file
10
test/channels/count_channel_test.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class CountChannelTest < ActionCable::Channel::TestCase
|
||||||
|
# test "subscribes" do
|
||||||
|
# subscribe
|
||||||
|
# assert subscription.confirmed?
|
||||||
|
# end
|
||||||
|
end
|
|
@ -1115,6 +1115,11 @@ acorn@^7.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.2.0.tgz#17ea7e40d7c8640ff54a694c889c26f31704effe"
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.2.0.tgz#17ea7e40d7c8640ff54a694c889c26f31704effe"
|
||||||
integrity sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==
|
integrity sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==
|
||||||
|
|
||||||
|
actioncable@^5.2.4-3:
|
||||||
|
version "5.2.4-3"
|
||||||
|
resolved "https://registry.yarnpkg.com/actioncable/-/actioncable-5.2.4-3.tgz#cb4d1f4a6a8164ac9abe623eca2c382fe05e7d47"
|
||||||
|
integrity sha512-SrGfg2W2GKGfYOlsOUnqjdihUhIVoyb5ewsMtpfE/Z3ZK/j5Gj2e/YWp2A7Wo+aeB1aewhPxorFxIGVRowbX4w==
|
||||||
|
|
||||||
aggregate-error@^3.0.0:
|
aggregate-error@^3.0.0:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0"
|
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0"
|
||||||
|
|
Reference in New Issue
Block a user