Commit b8f72e22 authored by Jens-Christian Fischer's avatar Jens-Christian Fischer
Browse files

Keeping state

- using agent for global state of sliders
- set slider values on load
- dynamically generate n vertical sliders
parent 30bad163
......@@ -14,6 +14,8 @@ defmodule Grains do
supervisor(Grains.Endpoint, []),
# Start your own worker by calling: Grains.Worker.start_link(arg1, arg2, arg3)
# worker(Grains.Worker, [arg1, arg2, arg3]),
worker(Grains.Concounter, [0]),
worker(Grains.StatefulMap, []),
]
# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
......
defmodule Grains.Concounter do
use GenServer
def inc(pid), do: GenServer.cast(pid, :inc)
def dec(pid), do: GenServer.cast(pid, :dec)
def val(pid) do
GenServer.call(pid, :val)
end
def start_link(initial_val) do
GenServer.start_link(__MODULE__, initial_val)
end
def init(initial_val) do
{:ok, initial_val}
end
def handle_cast(:inc, val) do
{:noreply, val + 1}
end
def handle_cast(:dec, val) do
{:noreply, val - 1}
end
def handle_call(:val, _from, val) do
{:reply, val, val}
end
end
defmodule Grains.StatefulMap do
def start_link do
Agent.start_link(fn -> %{} end, name: __MODULE__)
end
def put(key, value) do
Agent.update(__MODULE__, &Map.put(&1, key, value))
end
def get(key) do
Agent.get(__MODULE__, &Map.get(&1, key))
end
def values do
Agent.get(__MODULE__, &(&1))
end
end
......@@ -3,7 +3,7 @@ defmodule Grains.Mixfile do
def project do
[app: :grains,
version: "0.0.5",
version: "0.0.6",
elixir: "~> 1.2",
elixirc_paths: elixirc_paths(Mix.env),
compilers: [:phoenix, :gettext] ++ Mix.compilers,
......
defmodule Grains.PresenceChannel do
use Grains.Web, :channel
alias Grains.Concounter
def join("presence:" <> user_id, _params, socket) do
{:ok, socket}
end
end
defmodule Grains.SliderChannel do
use Grains.Web, :channel
alias Grains.StatefulMap
alias Grains.ValueView
def join("slider:" <> slider_id, _params, socket) do
{:ok, socket}
values = StatefulMap.values()
resp = %{values: Phoenix.View.render_many(values, ValueView, "value.json") }
{:ok, resp, socket}
end
def handle_in("slider", params, socket) do
IO.puts "slider: #{params["slider"]} : #{params["value"]}"
slider = params["slider"]
value = params["value"]
StatefulMap.put(slider, value)
broadcast! socket, "slider", %{
user: %{id: "anon"},
element: params["slider"],
value: params["value"]
element: slider,
value: value
}
{:reply, :ok, socket}
......
......@@ -4,6 +4,8 @@ defmodule Grains.UserSocket do
## Channels
channel "slider:*", Grains.SliderChannel
channel "presence:*", Grains.PresenceChannel
## Transports
transport :websocket, Phoenix.Transports.WebSocket
# transport :longpoll, Phoenix.Transports.LongPoll
......
64143
\ No newline at end of file
56853
\ No newline at end of file
......@@ -16,7 +16,7 @@ import "phoenix_html";
import socket from "./socket"
import SliderPanel from "./slider";
SliderPanel.init(socket, "#sliderPanel");
SliderPanel.init(socket, "#sliderPanel", ["s1", "s2", "s3"]);
// Import local files
//
......
......@@ -4,38 +4,46 @@ let SliderPanel = {
sliderChannel : null,
init(socket, domId) {
sliders: {},
init(socket, domId, sliders) {
let that = this;
socket.connect();
this.sliderChannel = socket.channel("slider:" + domId);
this.sliderChannel.on("slider", (resp) => {
this.renderSliderValue(resp);
this.setSliderValue(resp);
});
this.sliderChannel.join()
.receive("ok", resp => console.log("joined the slider channel", resp))
.receive("ok", resp => {
resp.values.forEach( (element) => {
this.setSliderValue(element);
} );
})
.receive("error", reason => console.log("join failed", reason));
let a = new Interface.Panel({
container:document.getElementById(domId)
});
let b = new Interface.Slider({
label: 'vertical slider',
bounds:[.05,.05,.3,.9],
onvaluechange: function() {that.send_value("vertical", this.value); }
});
let c = new Interface.Slider({
bounds:[.4,.35,.55,.3],
label: 'horizontal slider',
isVertical:false,
value: 0.5,
onvaluechange: function() { that.send_value("horizontal", this.value); }
let nrSliders = sliders.length;
sliders.forEach( (s, idx) => {
this.sliders[s] = new Interface.Slider({
bounds: [(1/nrSliders) * idx, .1, 1 / nrSliders, .5],
label: s,
onvaluechange: function() {that.send_value(s, this.value); }
});
console.log(s);
a.add(this.sliders[s]);
});
a.background = 'black';
a.add(b,c);
console.log("initialized slider");
},
......@@ -46,9 +54,9 @@ let SliderPanel = {
},
renderSliderValue(resp){
let element = document.getElementById("#" + resp.element);
element.innerHTML = resp.value;
setSliderValue(resp){
let slider = this.sliders[resp.element];
slider.setValue(resp.value);
}
};
......
......@@ -4,10 +4,4 @@
the mobile web and the cloud.</p>
</div>
<div>
Vertical Value: <span id="#vertical"></span><br/>
Horizontal Value: <span id="#horizontal"></span>
</div>
<div id="#sliderPanel" class="interfacePanel"></div>
defmodule Grains.ValueView do
use Grains.Web, :view
def render("value.json", %{value: {key, value}}) do
%{ element: key,
value: value }
end
end
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment