MVP version. Added actioncables for counting.

This commit is contained in:
James Patrick 2020-05-23 06:23:20 -04:00
parent 6361a50230
commit 3f97cc59b2
24 changed files with 166 additions and 16 deletions

View 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

View File

@ -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

View File

@ -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

View File

@ -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
View 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;

View 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 };

View File

@ -33,3 +33,5 @@
} }
} }
} }
/* -*- mode: css; -*- */

View File

@ -0,0 +1 @@
<%= cluster.count %>

View 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;
});
}
});

View File

@ -0,0 +1 @@
/* placeholder */

View File

@ -0,0 +1,3 @@
<a class="counter-down-btn">
<i class="fas fa-angle-double-down"></i>
</a>

View 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);
});
}
});

View File

@ -0,0 +1 @@
/* placeholder */

View File

@ -0,0 +1,3 @@
<a class="counter-up-btn">
<i class="fas fa-angle-double-up"></i>
</a>

View 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);
});
}
});

View File

@ -0,0 +1 @@
/* placeholder */

View 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>

View 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";

View 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;
}
}

View File

@ -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;
} }

View File

@ -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";

View File

@ -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",

View 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

View File

@ -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"