diff --git a/app/channels/count_channel.rb b/app/channels/count_channel.rb new file mode 100644 index 0000000..055bec2 --- /dev/null +++ b/app/channels/count_channel.rb @@ -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 diff --git a/app/controllers/cluster_controller.rb b/app/controllers/cluster_controller.rb index c6c8c6b..f0e132a 100644 --- a/app/controllers/cluster_controller.rb +++ b/app/controllers/cluster_controller.rb @@ -9,7 +9,7 @@ class ClusterController < ApplicationController def create cluster = Cluster.new(params[:cluster]) - session[:cluster_uuid] = cluster.uuid; + session[:cluster_uuid] = cluster.uuid redirect_to root_path end diff --git a/app/controllers/counter_controller.rb b/app/controllers/counter_controller.rb index f00ec59..75273e4 100644 --- a/app/controllers/counter_controller.rb +++ b/app/controllers/counter_controller.rb @@ -3,7 +3,9 @@ class CounterController < ApplicationController before_action :associate! - def show; end + def show + @cluster = Cluster.get(session[:cluster_uuid]) + end private diff --git a/app/views/counter/show.html.erb b/app/views/counter/show.html.erb index b19cab6..92daa33 100644 --- a/app/views/counter/show.html.erb +++ b/app/views/counter/show.html.erb @@ -1,13 +1,3 @@ -
-
-

- Hello World -

-

- - - - My first website with Bulma! -

-
-
+<%= c("page") do %> + <%= c("counter-view") %> +<% end %> diff --git a/frontend/client/cable.js b/frontend/client/cable.js new file mode 100644 index 0000000..43fcd46 --- /dev/null +++ b/frontend/client/cable.js @@ -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; diff --git a/frontend/client/counter.js b/frontend/client/counter.js new file mode 100644 index 0000000..a4ed0c5 --- /dev/null +++ b/frontend/client/counter.js @@ -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 }; diff --git a/frontend/components/cluster-new/cluster-new.pcss b/frontend/components/cluster-new/cluster-new.pcss index e3df3ed..fbc60c8 100644 --- a/frontend/components/cluster-new/cluster-new.pcss +++ b/frontend/components/cluster-new/cluster-new.pcss @@ -33,3 +33,5 @@ } } } + +/* -*- mode: css; -*- */ diff --git a/frontend/components/counter-count/_counter-count.html.erb b/frontend/components/counter-count/_counter-count.html.erb new file mode 100644 index 0000000..dbad357 --- /dev/null +++ b/frontend/components/counter-count/_counter-count.html.erb @@ -0,0 +1 @@ +<%= cluster.count %> diff --git a/frontend/components/counter-count/counter-count.js b/frontend/components/counter-count/counter-count.js new file mode 100644 index 0000000..c29bbe1 --- /dev/null +++ b/frontend/components/counter-count/counter-count.js @@ -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; + }); + } +}); diff --git a/frontend/components/counter-count/counter-count.pcss b/frontend/components/counter-count/counter-count.pcss new file mode 100644 index 0000000..545eb34 --- /dev/null +++ b/frontend/components/counter-count/counter-count.pcss @@ -0,0 +1 @@ +/* placeholder */ diff --git a/frontend/components/counter-down-btn/_counter-down-btn.html.erb b/frontend/components/counter-down-btn/_counter-down-btn.html.erb new file mode 100644 index 0000000..265ad73 --- /dev/null +++ b/frontend/components/counter-down-btn/_counter-down-btn.html.erb @@ -0,0 +1,3 @@ + + + diff --git a/frontend/components/counter-down-btn/counter-down-btn.js b/frontend/components/counter-down-btn/counter-down-btn.js new file mode 100644 index 0000000..877c8e9 --- /dev/null +++ b/frontend/components/counter-down-btn/counter-down-btn.js @@ -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); + }); + } +}); diff --git a/frontend/components/counter-down-btn/counter-down-btn.pcss b/frontend/components/counter-down-btn/counter-down-btn.pcss new file mode 100644 index 0000000..545eb34 --- /dev/null +++ b/frontend/components/counter-down-btn/counter-down-btn.pcss @@ -0,0 +1 @@ +/* placeholder */ diff --git a/frontend/components/counter-up-btn/_counter-up-btn.html.erb b/frontend/components/counter-up-btn/_counter-up-btn.html.erb new file mode 100644 index 0000000..0e6c2e7 --- /dev/null +++ b/frontend/components/counter-up-btn/_counter-up-btn.html.erb @@ -0,0 +1,3 @@ + + + diff --git a/frontend/components/counter-up-btn/counter-up-btn.js b/frontend/components/counter-up-btn/counter-up-btn.js new file mode 100644 index 0000000..e9e26a3 --- /dev/null +++ b/frontend/components/counter-up-btn/counter-up-btn.js @@ -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); + }); + } +}); diff --git a/frontend/components/counter-up-btn/counter-up-btn.pcss b/frontend/components/counter-up-btn/counter-up-btn.pcss new file mode 100644 index 0000000..545eb34 --- /dev/null +++ b/frontend/components/counter-up-btn/counter-up-btn.pcss @@ -0,0 +1 @@ +/* placeholder */ diff --git a/frontend/components/counter-view/_counter-view.html.erb b/frontend/components/counter-view/_counter-view.html.erb new file mode 100644 index 0000000..c005fc2 --- /dev/null +++ b/frontend/components/counter-view/_counter-view.html.erb @@ -0,0 +1,11 @@ +
+
+ <%= c("counter-up-btn") %> +
+
+ <%= c("counter-count", cluster: @cluster) %> +
+
+ <%= c("counter-down-btn") %> +
+
diff --git a/frontend/components/counter-view/counter-view.js b/frontend/components/counter-view/counter-view.js new file mode 100644 index 0000000..c3293c9 --- /dev/null +++ b/frontend/components/counter-view/counter-view.js @@ -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"; diff --git a/frontend/components/counter-view/counter-view.pcss b/frontend/components/counter-view/counter-view.pcss new file mode 100644 index 0000000..6bc2912 --- /dev/null +++ b/frontend/components/counter-view/counter-view.pcss @@ -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; + } +} diff --git a/frontend/components/page/page.pcss b/frontend/components/page/page.pcss index 1247a4d..02fd664 100644 --- a/frontend/components/page/page.pcss +++ b/frontend/components/page/page.pcss @@ -1,6 +1,6 @@ .page { height: 100vh; - width: 700px; margin: 0 auto; + max-width: 700px; overflow: hidden; } diff --git a/frontend/packs/application.js b/frontend/packs/application.js index f39197d..be20391 100644 --- a/frontend/packs/application.js +++ b/frontend/packs/application.js @@ -2,3 +2,4 @@ import "init"; import "components/page/page"; import "components/cluster-view/cluster-view"; +import "components/counter-view/counter-view"; diff --git a/package.json b/package.json index d81cc5f..3a04330 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "@rails/actioncable": "^6.0.0", "@rails/ujs": "^6.0.0", "@rails/webpacker": "4.2.2", + "actioncable": "^5.2.4-3", "bulma": "^0.8.2", "normalize.css": "^8.0.1", "postcss-flexbugs-fixes": "^4.2.1", diff --git a/test/channels/count_channel_test.rb b/test/channels/count_channel_test.rb new file mode 100644 index 0000000..891e0d7 --- /dev/null +++ b/test/channels/count_channel_test.rb @@ -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 diff --git a/yarn.lock b/yarn.lock index 25f8477..5ac797e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1115,6 +1115,11 @@ acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.2.0.tgz#17ea7e40d7c8640ff54a694c889c26f31704effe" 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: version "3.0.1" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0"