Skip to content

Commit e90d28d

Browse files
committed
Add GQL subscriptions for barcode and config data
1 parent e441a85 commit e90d28d

File tree

13 files changed

+245
-86
lines changed

13 files changed

+245
-86
lines changed

eye_ui/assets/css/app.css

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,14 @@
1-
/* This file is for your main application css. */
1+
/* This file is for your main application css. */
2+
3+
body {
4+
padding: 0 10%;
5+
}
6+
7+
.container-fluid {
8+
text-align: center;
9+
}
10+
11+
#canvas {
12+
background-size: contain;
13+
background-repeat: no-repeat;
14+
}

eye_ui/assets/css/bootstrap_4.0.0.min.css

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

eye_ui/assets/css/phoenix.css

Lines changed: 0 additions & 77 deletions
This file was deleted.

eye_ui/assets/js/app.js

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,107 @@
1111
//
1212
// If you no longer want to use a dependency, remember
1313
// to also remove its path from "config.paths.watched".
14-
import "phoenix_html"
1514

1615
// Import local files
1716
//
1817
// Local files can be imported directly using relative
1918
// paths "./socket" or full ones "web/static/js/socket".
2019

2120
// import socket from "./socket"
21+
22+
import * as AbsintheSocket from "@absinthe/socket";
23+
import {Socket as PhoenixSocket} from "phoenix";
24+
25+
const subscribe = (socket, onResult, operation) => {
26+
const notifier = AbsintheSocket.send(socket, { operation });
27+
AbsintheSocket.observe(socket, notifier, { onResult });
28+
}
29+
30+
const phxSocket = new PhoenixSocket(`ws://${window.location.host}/socket`);
31+
const absintheSocket = AbsintheSocket.create(phxSocket);
32+
33+
// Barcode Subscription
34+
35+
const barcodeOperation = `
36+
subscription {
37+
barcodes {
38+
data
39+
points {
40+
x
41+
y
42+
}
43+
}
44+
}
45+
`;
46+
47+
const onBarcodeData = data => {
48+
const barcodes = data["data"]["barcodes"];
49+
const dots = barcodes.map(barcode => {
50+
const points = barcode["points"];
51+
return barcode["points"].map(function(point, index) {
52+
const x = point["x"];
53+
const y = point["y"];
54+
if (index == 0) {
55+
return `
56+
<circle cx="${x}" cy="${y}" r="3" stroke="red" fill="transparent" stroke-width="2"/>
57+
<text x="${x + 5}" y="${y + 5}"><tspan font-weight="bold" fill="red">${barcode["data"]}</tspan></text>
58+
`
59+
} else {
60+
return `<circle cx="${x}" cy="${y}" r="3" fill="red"/>`
61+
}
62+
}).join("\n");
63+
}).join("\n");
64+
document.getElementById("canvas").innerHTML = dots;
65+
};
66+
67+
subscribe( absintheSocket, onBarcodeData, barcodeOperation );
68+
69+
// Configuration Subscription
70+
71+
const configOperation = `
72+
subscription {
73+
config {
74+
size {
75+
width
76+
height
77+
}
78+
}
79+
}
80+
`;
81+
82+
const onConfigData = data => {
83+
const {width, height} = data["data"]["config"]["size"];
84+
document.getElementById("canvas").setAttribute("viewBox", `0 0 ${width} ${height}`);
85+
};
86+
87+
subscribe( absintheSocket, onConfigData, configOperation );
88+
89+
// Resolution Buttons
90+
91+
const setResolution = (socket, width, height) => {
92+
AbsintheSocket.send(socket, {
93+
operation: `mutation {
94+
size(width: ${width}, height: ${height}) {
95+
size {
96+
width
97+
height
98+
}
99+
}
100+
}`
101+
});
102+
};
103+
104+
document.getElementById("640x480").onclick = (event) => {
105+
event.preventDefault();
106+
setResolution(absintheSocket, 640, 480);
107+
};
108+
109+
document.getElementById("1280x720").onclick = (event) => {
110+
event.preventDefault();
111+
setResolution(absintheSocket, 1280, 720);
112+
};
113+
114+
document.getElementById("1920x1080").onclick = (event) => {
115+
event.preventDefault();
116+
setResolution(absintheSocket, 1920, 1080);
117+
};

eye_ui/assets/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"watch": "brunch watch --stdin"
77
},
88
"dependencies": {
9+
"@absinthe/socket-apollo-link": "^0.1.11",
910
"phoenix": "1.3.4"
1011
},
1112
"devDependencies": {

eye_ui/assets/static/index.html

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,29 @@
11
<!DOCTYPE html>
2-
<html>
3-
<head>
4-
<meta charset="UTF-8" />
5-
<title>Eye - Video Stream</title>
6-
</head>
7-
<body> <img src="video.mjpg" /> </body>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
7+
8+
<title>Eye - Video Stream</title>
9+
<link rel="stylesheet" href="/css/app.css">
10+
</head>
11+
12+
<body>
13+
<div class="container-fluid">
14+
15+
<div class="btn-toolbar my-2" role="toolbar" aria-label="Toolbar">
16+
<div class="btn-group mr-2" role="group" aria-label="Resolution Options">
17+
<a class="btn btn-secondary" href="#" role="button" id="640x480">640 x 480</a>
18+
<a class="btn btn-secondary" href="#" role="button" id="1280x720">1280 x 720</a>
19+
<a class="btn btn-secondary" href="#" role="button" id="1920x1080">1920 x 1080</a>
20+
</div>
21+
</div> <!-- toolbar -->
22+
23+
<svg id="canvas" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720" style="background-image: url('video.mjpg');"/>
24+
25+
</div> <!-- container -->
26+
27+
<script src="/js/app.js"></script>
28+
</body>
829
</html>

eye_ui/lib/eye_ui/application.ex

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ defmodule EyeUi.Application do
99
children = [
1010
# Start the endpoint when the application starts
1111
EyeUiWeb.Endpoint,
12-
{Task.Supervisor, [name: EyeUi.TaskSupervisor]}
12+
child_spec(Absinthe.Subscription, [EyeUiWeb.Endpoint]),
13+
{Task.Supervisor, [name: EyeUi.TaskSupervisor]},
14+
EyeUi.Publishers.Barcode
1315
]
1416

1517
# See https://hexdocs.pm/elixir/Supervisor.html
@@ -18,6 +20,10 @@ defmodule EyeUi.Application do
1820
Supervisor.start_link(children, opts)
1921
end
2022

23+
defp child_spec(module, args \\ []) do
24+
%{id: module, start: {module, :start_link, args}}
25+
end
26+
2127
# Tell Phoenix to update the endpoint configuration
2228
# whenever the application is updated.
2329
def config_change(changed, _new, removed) do

eye_ui/lib/eye_ui/publisher.ex

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
defmodule EyeUi.Publisher do
2+
3+
def publish(obj, topic) do
4+
Absinthe.Subscription.publish(EyeUiWeb.Endpoint, obj, topic)
5+
end
6+
7+
end
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
defmodule EyeUi.Publishers.Barcode do
2+
3+
require Logger
4+
5+
def child_spec(opts \\ []) do
6+
%{
7+
id: __MODULE__,
8+
start: {__MODULE__, :start_link, opts}
9+
}
10+
end
11+
12+
def start_link do
13+
Task.Supervisor.start_child(EyeUi.TaskSupervisor, & stream/0, restart: :permanent)
14+
end
15+
16+
defp stream do
17+
symbols = EyeUi.Resolvers.Barcode.get_next_scan()
18+
Logger.debug(fn -> "Publishing barcode scans: #{inspect symbols}" end)
19+
EyeUi.Publisher.publish(symbols, barcodes: "*")
20+
stream()
21+
end
22+
end
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
defmodule EyeUi.Resolvers.Barcode do
2+
3+
def get_next_scan(_parent, _args, _resolution) do
4+
{:ok, get_next_scan()}
5+
end
6+
7+
def get_next_scan do
8+
Eye.BarcodeScanner.next_scan()
9+
|> format_symbols()
10+
end
11+
12+
defp format_symbols(nil), do: []
13+
defp format_symbols(symbols), do: Enum.map(symbols, & format_symbol/1)
14+
15+
defp format_symbol(symbol), do: Map.update!(symbol, :points, & format_points/1)
16+
17+
defp format_points(points), do: Enum.map(points, & format_point/1)
18+
19+
defp format_point({x, y}), do: %{x: x, y: y}
20+
21+
end

0 commit comments

Comments
 (0)