From 11e562d6effba33828374a82d8402ab5dd8400a1 Mon Sep 17 00:00:00 2001
From: Neven DREAN
Date: Thu, 3 Oct 2024 16:35:40 +0200
Subject: [PATCH 1/3] updated to Bandit
---
.gitignore | 2 +-
README.md | 61 ++++++++++++++-----
config/config.exs | 1 +
.../components/layouts/app.html.heex | 7 ++-
lib/counter_web/live/counter.ex | 28 +++++----
lib/counter_web/live/counter_component.ex | 2 +-
lib/counter_web/live/counter_state.ex | 8 +--
mix.exs | 27 +++++---
mix.lock | 25 +++++---
priv/static/images/logo.svg | 6 ++
test/counter_web/live/counter_test.exs | 18 ++++--
11 files changed, 127 insertions(+), 58 deletions(-)
create mode 100644 priv/static/images/logo.svg
diff --git a/.gitignore b/.gitignore
index e4daf621..090ebf4c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,7 +27,7 @@ npm-debug.log
/priv/static/cache_manifest.json
# Ignore assets that are produced by build tools.
-/priv/static/*
+#/priv/static/*
# Ignore this noise:
.DS_Store
\ No newline at end of file
diff --git a/README.md b/README.md
index 9f41a19b..b62dd5e4 100644
--- a/README.md
+++ b/README.md
@@ -146,16 +146,16 @@ When you run the command:
elixir -v
```
-You should expect to see output similar to the following:
+At the time of writing, you should expect to see output similar to the following:
```elixir
-Elixir 1.15.4 (compiled with Erlang/OTP 26)
+Elixir 1.17.3 (compiled with Erlang/OTP 26)
```
-This informs us we are using `Elixir version 1.15.4`
+This informs us we are using `Elixir version 1.17.3`
which is the _latest_ version at the time of writing.
Some of the more advanced features of Phoenix 1.7 during compilation time require elixir
-`1.14` although the code will work in previous versions.
+`1.17` although the code will work in previous versions.
@@ -171,7 +171,7 @@ mix phx.new -v
You should see something similar to the following:
```sh
-Phoenix installer v1.7.7
+Phoenix installer v1.7.14
```
If you have an earlier version,
@@ -676,7 +676,9 @@ defmodule CounterWeb.Counter do
@topic "live"
def mount(_session, _params, socket) do
- CounterWeb.Endpoint.subscribe(@topic) # subscribe to the channel
+ if connected?(socket) do
+ CounterWeb.Endpoint.subscribe(@topic) # subscribe to the channel
+ end
{:ok, assign(socket, :val, 0)}
end
@@ -721,12 +723,28 @@ The second change is on
[Line 7](https://github.com/dwyl/phoenix-liveview-counter-tutorial/blob/664228ac564a79a0dd92d06857622c1ba22cda71/lib/counter_web/live/counter.exL7)
where the
[`mount/3`](https://github.com/dwyl/phoenix-liveview-counter-tutorial/blob/d3cddb14dff911a377d0e41b916cfe57b0557606/lib/counter_web/live/counter.ex#L6)
-function now creates a subscription to the `@topic`:
+function now creates a subscription to the `@topic` when the socket is connected:
```elixir
CounterWeb.Endpoint.subscribe(@topic) # subscribe to the channel topic
```
+When the client (the browser) connects to the Phoenix server,
+a websocket connection is established.
+The interface is the `socket` and
+we know that the socket is connected
+when the [connected?/1](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#connected?/1) function returns `true`.
+This is why we only subscribe to the channel
+when the socket is connected.
+Why do we do this?
+Because a websocket connection starts with an HTTP request
+and HTTP is a stateless protocol.
+So when the client connects to the server,
+the server does not know if the client is already connected to the server.
+Once the websocket connection is established,
+the server knows that the client is connected,
+thus `connected?(ocket) == true`.
+
Each client connected to the App
subscribes to the `@topic`
so when the count is updated on any of the clients,
@@ -1371,8 +1389,9 @@ defmodule CounterWeb.Counter do
@topic Count.topic
def mount(_params, _session, socket) do
- PubSub.subscribe(Counter.PubSub, @topic)
-
+ if connected?(socket) do
+ PubSub.subscribe(Counter.PubSub, @topic)
+ end
{:ok, assign(socket, val: Count.current()) }
end
@@ -1567,6 +1586,12 @@ but not here) so the rest of the code goes into
2. We handle Presence updates and use the current count, adding joiners and
subtracting leavers to calculate the current numbers 'present'. We do that
in a pattern matched `handle_info`.
+ Notice that since we populate the socket's state in the `mount/3` callback,
+ and compute the Presence there, we need to remove the connected client
+ from the joins in the `handle_info` callback.
+ We use `Map.delete` to remove the client from the joins.
+ This works because the client is identified by the socket's `id` and Presence
+ process returns a map whose key value is the `socket.id`.
3. We publish the additional data to the client in `render`
```diff
@@ -1580,14 +1605,19 @@ defmodule CounterWeb.Counter do
+ @presence_topic "presence"
def mount(_params, _session, socket) do
- PubSub.subscribe(Counter.PubSub, @topic)
-+ Presence.track(self(), @presence_topic, socket.id, %{})
-+ CounterWeb.Endpoint.subscribe(@presence_topic)
-+
+ initial_present =
-+ Presence.list(@presence_topic)
-+ |> map_size
+ if connected?(socket) do
+ PubSub.subscribe(Counter.PubSub, @topic)
+
++ Presence.track(self(), @presence_topic, socket.id, %{})
++ CounterWeb.Endpoint.subscribe(@presence_topic)
++
++ Presence.list(@presence_topic)
++ |> map_size
++ else
++ 0
++ end
+ {:ok, assign(socket, val: Count.current(), present: initial_present) }
- {:ok, assign(socket, val: Count.current()) }
@@ -1609,6 +1639,7 @@ defmodule CounterWeb.Counter do
+ %{event: "presence_diff", payload: %{joins: joins, leaves: leaves}},
+ %{assigns: %{present: present}} = socket
+ ) do
++ {_, joins} = Map.pop!(joins, socket.id, %{})
+ new_present = present + map_size(joins) - map_size(leaves)
+
+ {:noreply, assign(socket, :present, new_present)}
diff --git a/config/config.exs b/config/config.exs
index d96c0c88..996c8620 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -10,6 +10,7 @@ import Config
# Configures the endpoint
config :counter, CounterWeb.Endpoint,
url: [host: "localhost"],
+ adapter: Bandit.PhoenixAdapter,
render_errors: [
formats: [html: CounterWeb.ErrorHTML, json: CounterWeb.ErrorJSON],
layout: false
diff --git a/lib/counter_web/components/layouts/app.html.heex b/lib/counter_web/components/layouts/app.html.heex
index 1a2aab10..7a58188f 100644
--- a/lib/counter_web/components/layouts/app.html.heex
+++ b/lib/counter_web/components/layouts/app.html.heex
@@ -9,7 +9,10 @@
-
Counter: <%= @val %>
+
Counter: <%= @val %>
-
diff --git a/lib/counter_web/live/counter_state.ex b/lib/counter_web/live/counter_state.ex
index 164a1f5d..1e01b75b 100644
--- a/lib/counter_web/live/counter_state.ex
+++ b/lib/counter_web/live/counter_state.ex
@@ -16,15 +16,15 @@ defmodule Counter.Count do
end
def incr() do
- GenServer.call @name, :incr
+ GenServer.call(@name, :incr)
end
def decr() do
- GenServer.call @name, :decr
+ GenServer.call(@name, :decr)
end
def current() do
- GenServer.call @name, :current
+ GenServer.call(@name, :current)
end
def init(start_count) do
@@ -34,7 +34,7 @@ defmodule Counter.Count do
# Implementation (Runs in GenServer process)
def handle_call(:current, _from, count) do
- {:reply, count, count}
+ {:reply, count, count}
end
def handle_call(:incr, _from, count) do
diff --git a/mix.exs b/mix.exs
index 7429c96a..dedc3c51 100644
--- a/mix.exs
+++ b/mix.exs
@@ -4,8 +4,8 @@ defmodule Counter.MixProject do
def project do
[
app: :counter,
- version: "1.7.7",
- elixir: "~> 1.14",
+ version: "1.8.0",
+ elixir: "~> 1.17",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
aliases: aliases(),
@@ -42,20 +42,29 @@ defmodule Counter.MixProject do
# Type `mix help deps` for examples and options.
defp deps do
[
- {:phoenix, "~> 1.7.7"},
- {:phoenix_html, "~> 4.0"},
+ {:phoenix, "~> 1.7.14"},
+ {:phoenix_html, "~> 4.1"},
{:phoenix_live_reload, "~> 1.2", only: :dev},
- {:phoenix_live_view, "~> 0.20.0"},
+ # TODO bump on release to {:phoenix_live_view, "~> 1.0.0"},
+ {:phoenix_live_view, "~> 1.0.0-rc.1", override: true},
{:floki, ">= 0.30.0", only: :test},
- {:esbuild, "~> 0.7", runtime: Mix.env() == :dev},
- {:tailwind, "~> 0.2.1", runtime: Mix.env() == :dev},
+ {:esbuild, "~> 0.8", runtime: Mix.env() == :dev},
+ {:tailwind, "~> 0.2", runtime: Mix.env() == :dev},
+ {:heroicons,
+ github: "tailwindlabs/heroicons",
+ tag: "v2.1.1",
+ sparse: "optimized",
+ app: false,
+ compile: false,
+ depth: 1},
{:telemetry_metrics, "~> 1.0"},
{:telemetry_poller, "~> 1.0"},
{:jason, "~> 1.2"},
- {:plug_cowboy, "~> 2.5"},
+ {:dns_cluster, "~> 0.1.1"},
+ {:bandit, "~> 1.5"},
# Track test coverage: github.com/parroty/excoveralls
- {:excoveralls, "~> 0.18.0", only: [:test, :dev]},
+ {:excoveralls, "~> 0.16.0", only: [:test, :dev]}
]
end
diff --git a/mix.lock b/mix.lock
index 398a205c..8b6f6130 100644
--- a/mix.lock
+++ b/mix.lock
@@ -1,24 +1,28 @@
%{
- "castore": {:hex, :castore, "1.0.7", "b651241514e5f6956028147fe6637f7ac13802537e895a724f90bf3e36ddd1dd", [:mix], [], "hexpm", "da7785a4b0d2a021cd1292a60875a784b6caef71e76bf4917bdee1f390455cf5"},
- "certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"},
+ "bandit": {:hex, :bandit, "1.5.7", "6856b1e1df4f2b0cb3df1377eab7891bec2da6a7fd69dc78594ad3e152363a50", [:mix], [{:hpax, "~> 1.0.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "f2dd92ae87d2cbea2fa9aa1652db157b6cba6c405cb44d4f6dd87abba41371cd"},
+ "castore": {:hex, :castore, "1.0.9", "5cc77474afadf02c7c017823f460a17daa7908e991b0cc917febc90e466a375c", [:mix], [], "hexpm", "5ea956504f1ba6f2b4eb707061d8e17870de2bee95fb59d512872c2ef06925e7"},
+ "certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"},
"cowboy": {:hex, :cowboy, "2.12.0", "f276d521a1ff88b2b9b4c54d0e753da6c66dd7be6c9fca3d9418b561828a3731", [:make, :rebar3], [{:cowlib, "2.13.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "8a7abe6d183372ceb21caa2709bec928ab2b72e18a3911aa1771639bef82651e"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
"cowlib": {:hex, :cowlib, "2.13.0", "db8f7505d8332d98ef50a3ef34b34c1afddec7506e4ee4dd4a3a266285d282ca", [:make, :rebar3], [], "hexpm", "e1e1284dc3fc030a64b1ad0d8382ae7e99da46c3246b815318a4b848873800a4"},
+ "dns_cluster": {:hex, :dns_cluster, "0.1.3", "0bc20a2c88ed6cc494f2964075c359f8c2d00e1bf25518a6a6c7fd277c9b0c66", [:mix], [], "hexpm", "46cb7c4a1b3e52c7ad4cbe33ca5079fbde4840dedeafca2baf77996c2da1bc33"},
"esbuild": {:hex, :esbuild, "0.8.1", "0cbf919f0eccb136d2eeef0df49c4acf55336de864e63594adcea3814f3edf41", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "25fc876a67c13cb0a776e7b5d7974851556baeda2085296c14ab48555ea7560f"},
- "excoveralls": {:hex, :excoveralls, "0.18.0", "b92497e69465dc51bc37a6422226ee690ab437e4c06877e836f1c18daeb35da9", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1109bb911f3cb583401760be49c02cbbd16aed66ea9509fc5479335d284da60b"},
- "file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"},
+ "excoveralls": {:hex, :excoveralls, "0.16.1", "0bd42ed05c7d2f4d180331a20113ec537be509da31fed5c8f7047ce59ee5a7c5", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "dae763468e2008cf7075a64cb1249c97cb4bc71e236c5c2b5e5cdf1cfa2bf138"},
+ "file_system": {:hex, :file_system, "1.0.1", "79e8ceaddb0416f8b8cd02a0127bdbababe7bf4a23d2a395b983c1f8b3f73edd", [:mix], [], "hexpm", "4414d1f38863ddf9120720cd976fce5bdde8e91d8283353f0e31850fa89feb9e"},
"floki": {:hex, :floki, "0.36.2", "a7da0193538c93f937714a6704369711998a51a6164a222d710ebd54020aa7a3", [:mix], [], "hexpm", "a8766c0bc92f074e5cb36c4f9961982eda84c5d2b8e979ca67f5c268ec8ed580"},
- "hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~> 2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"},
+ "hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"},
+ "heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized", depth: 1]},
+ "hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"},
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"},
- "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
- "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
+ "mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"},
+ "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"},
"phoenix": {:hex, :phoenix, "1.7.14", "a7d0b3f1bc95987044ddada111e77bd7f75646a08518942c72a8440278ae7825", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "c7859bc56cc5dfef19ecfc240775dae358cbaa530231118a9e014df392ace61a"},
"phoenix_html": {:hex, :phoenix_html, "4.1.1", "4c064fd3873d12ebb1388425a8f2a19348cef56e7289e1998e2d2fa758aa982e", [:mix], [], "hexpm", "f2f2df5a72bc9a2f510b21497fd7d2b86d932ec0598f0210fed4114adc546c6f"},
- "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.5.2", "354460993a480656b71c3887f5565f612b3bdbdd8688c83f9e6f512307067dd4", [:mix], [{:file_system, "~> 0.3 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "2bb3722f327e14a7aa47b1acf27ed633c8cd27b167e18b8237954b9b4804af39"},
- "phoenix_live_view": {:hex, :phoenix_live_view, "0.20.17", "f396bbdaf4ba227b82251eb75ac0afa6b3da5e509bc0d030206374237dfc9450", [:mix], [{:floki, "~> 0.36", [hex: :floki, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a61d741ffb78c85fdbca0de084da6a48f8ceb5261a79165b5a0b59e5f65ce98b"},
+ "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.5.3", "f2161c207fda0e4fb55165f650f7f8db23f02b29e3bff00ff7ef161d6ac1f09d", [:mix], [{:file_system, "~> 0.3 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "b4ec9cd73cb01ff1bd1cac92e045d13e7030330b74164297d1aee3907b54803c"},
+ "phoenix_live_view": {:hex, :phoenix_live_view, "1.0.0-rc.6", "47d2669995ea326e5c71f5c1bc9177109cebf211385c638faa7b5862a401e516", [:mix], [{:floki, "~> 0.36", [hex: :floki, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e56e4f1642a0b20edc2488cab30e5439595e0d8b5b259f76ef98b1c4e2e5b527"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"},
"phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"},
"plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"},
@@ -30,7 +34,8 @@
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
"telemetry_metrics": {:hex, :telemetry_metrics, "1.0.0", "29f5f84991ca98b8eb02fc208b2e6de7c95f8bb2294ef244a176675adc7775df", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f23713b3847286a534e005126d4c959ebcca68ae9582118ce436b521d1d47d5d"},
"telemetry_poller": {:hex, :telemetry_poller, "1.1.0", "58fa7c216257291caaf8d05678c8d01bd45f4bdbc1286838a28c4bb62ef32999", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9eb9d9cbfd81cbd7cdd24682f8711b6e2b691289a0de6826e58452f28c103c8f"},
+ "thousand_island": {:hex, :thousand_island, "1.3.5", "6022b6338f1635b3d32406ff98d68b843ba73b3aa95cfc27154223244f3a6ca5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2be6954916fdfe4756af3239fb6b6d75d0b8063b5df03ba76fd8a4c87849e180"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
- "websock_adapter": {:hex, :websock_adapter, "0.5.6", "0437fe56e093fd4ac422de33bf8fc89f7bc1416a3f2d732d8b2c8fd54792fe60", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "e04378d26b0af627817ae84c92083b7e97aca3121196679b73c73b99d0d133ea"},
+ "websock_adapter": {:hex, :websock_adapter, "0.5.7", "65fa74042530064ef0570b75b43f5c49bb8b235d6515671b3d250022cb8a1f9e", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "d0f478ee64deddfec64b800673fd6e0c8888b079d9f3444dd96d2a98383bdbd1"},
}
diff --git a/priv/static/images/logo.svg b/priv/static/images/logo.svg
new file mode 100644
index 00000000..9f26baba
--- /dev/null
+++ b/priv/static/images/logo.svg
@@ -0,0 +1,6 @@
+
+
+
diff --git a/test/counter_web/live/counter_test.exs b/test/counter_web/live/counter_test.exs
index 83f811ef..c3e49a5a 100644
--- a/test/counter_web/live/counter_test.exs
+++ b/test/counter_web/live/counter_test.exs
@@ -28,20 +28,30 @@ defmodule CounterWeb.CounterTest do
test "handle_info/2 Presence Update - Joiner", %{conn: conn} do
{:ok, view, html} = live(conn, "/")
assert html =~ "Connected Clients: 1"
+
send(view.pid, %{
event: "presence_diff",
- payload: %{joins: %{"phx-Fhb_dqdqsOCzKQAl" => %{metas: [%{phx_ref: "Fhb_dqdrwlCmfABl"}]}},
- leaves: %{}}})
+ payload: %{
+ joins: %{"phx-Fhb_dqdqsOCzKQAl" => %{metas: [%{phx_ref: "Fhb_dqdrwlCmfABl"}]}},
+ leaves: %{}
+ }
+ })
+
assert render(view) =~ "Connected Clients: 2"
end
test "handle_info/2 Presence Update - Leaver", %{conn: conn} do
{:ok, view, html} = live(conn, "/")
assert html =~ "Connected Clients: 1"
+
send(view.pid, %{
event: "presence_diff",
- payload: %{joins: %{},
- leaves: %{"phx-Fhb_dqdqsOCzKQAl" => %{metas: [%{phx_ref: "Fhb_dqdrwlCmfABl"}]}}}})
+ payload: %{
+ joins: %{},
+ leaves: %{"phx-Fhb_dqdqsOCzKQAl" => %{metas: [%{phx_ref: "Fhb_dqdrwlCmfABl"}]}}
+ }
+ })
+
assert render(view) =~ "Connected Clients: 0"
end
end
From 152c224f2084ea9195cc73203f935ad4df7af235 Mon Sep 17 00:00:00 2001
From: Neven DREAN
Date: Thu, 3 Oct 2024 16:36:51 +0200
Subject: [PATCH 2/3] updated to Bandit
---
lib/counter_web/live/counter.ex | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/counter_web/live/counter.ex b/lib/counter_web/live/counter.ex
index 88f398e4..72d9e0cc 100644
--- a/lib/counter_web/live/counter.ex
+++ b/lib/counter_web/live/counter.ex
@@ -5,6 +5,7 @@ defmodule CounterWeb.Counter do
alias Counter.Presence
@topic Count.topic()
+
@presence_topic "presence"
def mount(_params, _session, socket) do
From 1177026fa4acd8550c9b5dc8cbae9b47bbc9278e Mon Sep 17 00:00:00 2001
From: Neven DREAN
Date: Thu, 3 Oct 2024 17:12:04 +0200
Subject: [PATCH 3/3] updated to Bandit
---
.github/workflows/ci.yml | 4 ++--
lib/counter_web/live/counter_component.ex | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1924c967..d8372119 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -16,8 +16,8 @@ jobs:
- name: Set up Elixir
uses: erlef/setup-beam@v1
with:
- elixir-version: '1.14.2' # Define the elixir version [required]
- otp-version: '25.1.2' # Define the OTP version [required]
+ elixir-version: '1.17.3' # Define the elixir version [required]
+ otp-version: '26.2' # Define the OTP version [required]
- name: Restore dependencies cache
uses: actions/cache@v2
with:
diff --git a/lib/counter_web/live/counter_component.ex b/lib/counter_web/live/counter_component.ex
index 239ad902..eacc54ba 100644
--- a/lib/counter_web/live/counter_component.ex
+++ b/lib/counter_web/live/counter_component.ex
@@ -9,6 +9,7 @@ defmodule CounterComponent do
def render(assigns) do
~H"""
+
Counter: <%= @val %>
-