diff options
author | Alex Auvolat <alex@adnab.me> | 2018-09-26 18:14:32 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2018-09-26 18:14:32 +0200 |
commit | 26629dc30a116204263ac4b515600649ba742ba0 (patch) | |
tree | a066688ce44e028abd188867bc92b72496d4893a | |
parent | 1a13285971ef728109011a93e676e26248b30242 (diff) | |
download | shard-26629dc30a116204263ac4b515600649ba742ba0.tar.gz shard-26629dc30a116204263ac4b515600649ba742ba0.zip |
Web UI for multiple identities
-rw-r--r-- | shardweb/assets/js/app.js | 2 | ||||
-rw-r--r-- | shardweb/config/config.exs | 2 | ||||
-rw-r--r-- | shardweb/lib/application.ex | 8 | ||||
-rw-r--r-- | shardweb/lib/shard_web.ex | 3 | ||||
-rw-r--r-- | shardweb/lib/shard_web/controllers/identity_controller.ex | 40 | ||||
-rw-r--r-- | shardweb/lib/shard_web/controllers/page_controller.ex | 20 | ||||
-rw-r--r-- | shardweb/lib/shard_web/controllers/peer_controller.ex | 25 | ||||
-rw-r--r-- | shardweb/lib/shard_web/controllers/room_controller.ex | 20 | ||||
-rw-r--r-- | shardweb/lib/shard_web/router.ex | 27 | ||||
-rw-r--r-- | shardweb/lib/shard_web/templates/identity/view.html.eex | 40 | ||||
-rw-r--r-- | shardweb/lib/shard_web/templates/layout/app.html.eex | 1 | ||||
-rw-r--r-- | shardweb/lib/shard_web/templates/page/index.html.eex | 2 | ||||
-rw-r--r-- | shardweb/lib/shard_web/templates/room/show.html.eex | 14 | ||||
-rw-r--r-- | shardweb/lib/shard_web/views/identity_view.ex | 11 | ||||
-rw-r--r-- | shardweb/lib/shard_web/views/layout_view.ex | 2 | ||||
-rw-r--r-- | shardweb/lib/shard_web/views/room_view.ex | 2 | ||||
-rw-r--r-- | shardweb/mix.exs | 4 |
17 files changed, 159 insertions, 64 deletions
diff --git a/shardweb/assets/js/app.js b/shardweb/assets/js/app.js index c98ec1b..53a0112 100644 --- a/shardweb/assets/js/app.js +++ b/shardweb/assets/js/app.js @@ -28,7 +28,7 @@ if (room_name != undefined) channel.on('shout', function (payload) { // listen to the 'shout' event var li = document.createElement("li"); // creaet new list item DOM element var name = payload.name || 'guest'; // get name from payload or set default - li.innerHTML = '<b>' + name + '</b> <small>' + payload.pk16 + '</small>: ' + payload.message; // set li contents + li.innerHTML = '<b><' + name + '</b> <small>' + payload.pk16 + '</small><b>></b> ' + payload.message; // set li contents console.log(ul.scrollTop + ' ' + ul.scrollHeight + ' ' + ul.clientHeight); var must_scroll = (ul.scrollTop >= ul.scrollHeight - ul.clientHeight - 10); diff --git a/shardweb/config/config.exs b/shardweb/config/config.exs index 65f52bc..9bf5be6 100644 --- a/shardweb/config/config.exs +++ b/shardweb/config/config.exs @@ -10,7 +10,7 @@ config :shardweb, ShardWeb.Endpoint, url: [host: "localhost"], secret_key_base: "HvLjdQ89FJDqv/g+/ya+62cghndUE6lKqTXWcgls2E8VU5Dtmxg4y8OnYaCEiQun", render_errors: [view: ShardWeb.ErrorView, accepts: ~w(html json)], - pubsub: [name: Shardweb.PubSub, + pubsub: [name: ShardWeb.PubSub, adapter: Phoenix.PubSub.PG2] # Configures Elixir's Logger diff --git a/shardweb/lib/application.ex b/shardweb/lib/application.ex index 2de7bff..94b2f32 100644 --- a/shardweb/lib/application.ex +++ b/shardweb/lib/application.ex @@ -1,4 +1,4 @@ -defmodule Shardweb.Application do +defmodule ShardWeb.Application do use Application # See https://hexdocs.pm/elixir/Application.html @@ -10,13 +10,13 @@ defmodule Shardweb.Application do children = [ # Start the endpoint when the application starts supervisor(ShardWeb.Endpoint, []), - # Start your own worker by calling: Shardweb.Worker.start_link(arg1, arg2, arg3) - # worker(Shardweb.Worker, [arg1, arg2, arg3]), + # Start your own worker by calling: ShardWeb.Worker.start_link(arg1, arg2, arg3) + # worker(ShardWeb.Worker, [arg1, arg2, arg3]), ] # See https://hexdocs.pm/elixir/Supervisor.html # for other strategies and supported options - opts = [strategy: :one_for_one, name: Shardweb.Supervisor] + opts = [strategy: :one_for_one, name: ShardWeb.Supervisor] Supervisor.start_link(children, opts) end diff --git a/shardweb/lib/shard_web.ex b/shardweb/lib/shard_web.ex index 5192806..049da29 100644 --- a/shardweb/lib/shard_web.ex +++ b/shardweb/lib/shard_web.ex @@ -20,6 +20,7 @@ defmodule ShardWeb do def controller do quote do use Phoenix.Controller, namespace: ShardWeb + import PhoenixGon.Controller import Plug.Conn import ShardWeb.Router.Helpers import ShardWeb.Gettext @@ -37,6 +38,8 @@ defmodule ShardWeb do # Use all HTML functionality (forms, tags, etc) use Phoenix.HTML + import PhoenixGon.View + import ShardWeb.Router.Helpers import ShardWeb.ErrorHelpers import ShardWeb.Gettext diff --git a/shardweb/lib/shard_web/controllers/identity_controller.ex b/shardweb/lib/shard_web/controllers/identity_controller.ex new file mode 100644 index 0000000..a4f54e7 --- /dev/null +++ b/shardweb/lib/shard_web/controllers/identity_controller.ex @@ -0,0 +1,40 @@ +defmodule ShardWeb.IdentityController do + use ShardWeb, :controller + + def view(conn, _params) do + render conn, "view.html" + end + + def update(conn, params) do + pid = SApp.Identity.find_proc(conn.assigns.pk) + info = GenServer.call(pid, :get_info) + info = %{info | nick: params["nick"]} + GenServer.call(pid, {:set_info, info}) + redirect conn, to: identity_path(conn, :view) + end + + def switch(conn, params) do + case Base.decode16(params["pk"]) do + {:ok, pk} -> + if Shard.Keys.have_sk? pk do + conn + |> put_session(:pk, pk) + |> redirect(to: identity_path(conn, :view)) + else + conn + |> put_flash(:error, "No secret key found") + |> render("view.html") + end + _ -> + conn + |> put_flash(:error, "Bad argument") + |> render("view.html") + end + end + + def create(conn, _params) do + pk = Shard.Keys.new_identity + conn = put_session(conn, :pk, pk) + redirect conn, to: identity_path(conn, :view) + end +end diff --git a/shardweb/lib/shard_web/controllers/page_controller.ex b/shardweb/lib/shard_web/controllers/page_controller.ex index a590630..305e751 100644 --- a/shardweb/lib/shard_web/controllers/page_controller.ex +++ b/shardweb/lib/shard_web/controllers/page_controller.ex @@ -4,4 +4,24 @@ defmodule ShardWeb.PageController do def index(conn, _params) do render conn, "index.html" end + + def add_peer(conn, _params) do + try do + ip = conn.params["ip"] + port = conn.params["port"] + {:ok, ip_tuple} = case :inet.parse_address(to_charlist(ip)) do + {:ok, tup} -> {:ok, tup} + _ -> + case :inet.gethostbyname(to_charlist(ip)) do + {:ok, {:hostent, _, _, :inet, 4, [ip_tup | _]}} -> {:ok, ip_tup} + _ -> :error + end + end + {port_num, _} = Integer.parse port + Shard.Manager.add_peer(ip_tuple, port_num) + rescue + _ -> nil + end + redirect conn, to: page_path(conn, :index) + end end diff --git a/shardweb/lib/shard_web/controllers/peer_controller.ex b/shardweb/lib/shard_web/controllers/peer_controller.ex deleted file mode 100644 index 0bf6ded..0000000 --- a/shardweb/lib/shard_web/controllers/peer_controller.ex +++ /dev/null @@ -1,25 +0,0 @@ -defmodule ShardWeb.PeerController do - use ShardWeb, :controller - - require Logger - - def add(conn, _params) do - try do - ip = conn.params["ip"] - port = conn.params["port"] - {:ok, ip_tuple} = case :inet.parse_address(to_charlist(ip)) do - {:ok, tup} -> {:ok, tup} - _ -> - case :inet.gethostbyname(to_charlist(ip)) do - {:ok, {:hostent, _, _, :inet, 4, [ip_tup | _]}} -> {:ok, ip_tup} - _ -> :error - end - end - {port_num, _} = Integer.parse port - Shard.Manager.add_peer(ip_tuple, port_num) - rescue - _ -> nil - end - redirect conn, to: page_path(conn, :index) - end -end diff --git a/shardweb/lib/shard_web/controllers/room_controller.ex b/shardweb/lib/shard_web/controllers/room_controller.ex index 8c98aa6..d24649b 100644 --- a/shardweb/lib/shard_web/controllers/room_controller.ex +++ b/shardweb/lib/shard_web/controllers/room_controller.ex @@ -1,27 +1,9 @@ defmodule ShardWeb.RoomController do use ShardWeb, :controller - require Logger - import PhoenixGon.Controller - def show(conn, %{"room" => room}) do - pk = get_session(conn, :pk) - {pk, conn} = cond do - pk == nil || not Shard.Keys.have_sk? pk -> - pk = Shard.Keys.get_any_identity - conn = put_session(conn, :pk, pk) - {pk, conn} - true -> - {pk, conn} - end - - name = SApp.Identity.get_nick pk - conn = put_gon(conn, chat_room: room) - conn = put_gon(conn, pk: (pk|>Base.encode16)) render conn, "show.html", - room: room, - pk: pk, - name: name + room: room end end diff --git a/shardweb/lib/shard_web/router.ex b/shardweb/lib/shard_web/router.ex index 180ebdd..4311a29 100644 --- a/shardweb/lib/shard_web/router.ex +++ b/shardweb/lib/shard_web/router.ex @@ -8,6 +8,7 @@ defmodule ShardWeb.Router do plug :protect_from_forgery plug :put_secure_browser_headers plug Plug.Parsers, parsers: [:urlencoded] + plug :check_pk end pipeline :api do @@ -18,13 +19,35 @@ defmodule ShardWeb.Router do pipe_through :browser # Use the default browser stack get "/", PageController, :index - get "/room/:room", RoomController, :show + post "/peer/add", PageController, :add_peer + + get "/identity", IdentityController, :view + post "/identity", IdentityController, :update + post "/identity/switch", IdentityController, :switch + post "/identity/create", IdentityController, :create - post "/peer/add", PeerController, :add + get "/room/:room", RoomController, :show end # Other scopes may use custom stacks. # scope "/api", ShardWeb do # pipe_through :api # end + + def check_pk(conn, _kv) do + pk1 = get_session(conn, :pk) + {conn, pk} = if pk1 == nil || not Shard.Keys.have_sk? pk1 do + pk = Shard.Keys.get_any_identity + conn = put_session(conn, :pk, pk) + {conn, pk} + else + {conn, pk1} + end + nick = SApp.Identity.get_nick pk + conn + |> assign(:pk, pk) + |> assign(:nick, nick) + |> PhoenixGon.Controller.put_gon(pk: (pk|>Base.encode16)) + end + end diff --git a/shardweb/lib/shard_web/templates/identity/view.html.eex b/shardweb/lib/shard_web/templates/identity/view.html.eex new file mode 100644 index 0000000..b9210f2 --- /dev/null +++ b/shardweb/lib/shard_web/templates/identity/view.html.eex @@ -0,0 +1,40 @@ +<h4>Identity</h4> + +<%= form_for @conn, identity_path(@conn, :update), [class: "form-horizontal"], fn f -> %> + <div class="form-group"> + <label class="col-sm-2 control-label">Public key:</label> + <div class="col-sm-10"> + <input type="text" value="<%= @pk |> Base.encode16 %>" class="form-control" disabled /> + </div> + </div> + <div class="form-group"> + <%= label :nick, "Nickname:", class: ["col-sm-2 control-label"] %> + <div class="col-sm-10"> + <%= text_input f, :nick, [class: "form-control", value: @nick] %> + </div> + </div> + <div class="form-group"> + <div class="col-sm-offset-2 col-sm-10"> + <%= submit "Update", [class: "btn btn-default"] %> + </div> + </div> +<% end %> + +<h4>Other identities</h4> + +<ul> + <%= for pk2 <- identity_list(), pk2 != @pk do %> + <li> + <%= form_for @conn, identity_path(@conn, :switch), [class: "form-inline"], fn f -> %> + <%= hidden_input f, :pk, value: (pk2 |> Base.encode16) %> + <%= submit "Switch to", [class: "btn btn-xs btn-success"] %> + <strong><%= get_nick pk2 %></strong> + <small><%= pk2 |> Base.encode16 %></small> + <% end %> + </li> + <% end %> +</ul> + +<%= form_for @conn, identity_path(@conn, :create), [class: "form-inline"], fn f -> %> + <%= submit "Create new identity", [class: "btn btn-danger"] %> +<% end %> diff --git a/shardweb/lib/shard_web/templates/layout/app.html.eex b/shardweb/lib/shard_web/templates/layout/app.html.eex index 9903775..d4b2075 100644 --- a/shardweb/lib/shard_web/templates/layout/app.html.eex +++ b/shardweb/lib/shard_web/templates/layout/app.html.eex @@ -18,6 +18,7 @@ <ul class="nav nav-pills pull-right"> <li><a href="<%= page_path(@conn, :index) %>">Home</a></li> <li><a href="<%= room_path(@conn, :show, "lobby") %>">Chat</a></li> + <li><a href="<%= identity_path(@conn, :view) %>">[<%= @nick %>]</a></li> </ul> </nav> <span class="logo"></span> diff --git a/shardweb/lib/shard_web/templates/page/index.html.eex b/shardweb/lib/shard_web/templates/page/index.html.eex index 412cbe5..2efa030 100644 --- a/shardweb/lib/shard_web/templates/page/index.html.eex +++ b/shardweb/lib/shard_web/templates/page/index.html.eex @@ -21,7 +21,7 @@ <% end %> </table> -<%= form_for @conn, peer_path(@conn, :add), [class: "form-inline"], fn f -> %> +<%= form_for @conn, page_path(@conn, :add_peer), [class: "form-inline"], fn f -> %> <%= text_input f, :ip, [class: "form-control", placeholder: "Hostname / IP address"] %> <%= text_input f, :port, [class: "form-control", placeholder: "Port", value: "4044"] %> <%= submit "Add peer", [class: "btn btn-default"] %> diff --git a/shardweb/lib/shard_web/templates/room/show.html.eex b/shardweb/lib/shard_web/templates/room/show.html.eex index bc1641a..e7b1166 100644 --- a/shardweb/lib/shard_web/templates/room/show.html.eex +++ b/shardweb/lib/shard_web/templates/room/show.html.eex @@ -12,11 +12,13 @@ <!-- The list of messages will appear here: --> <ul id='msg-list' class='row' style='list-style: none; min-height:400px; padding: 10px; max-height: 400px; overflow: scroll'></ul> -<div class="row"> - <div class="col-xs-3"> - <strong><%= @name %></strong> - </div> - <div class="col-xs-9"> - <input type="text" id="msg" class="form-control" placeholder="Your Message" autofocus> +<div class="form-horizontal"> + <div class="form-group"> + <div class="col-sm-2 control-label"> + <strong><<%= @nick %>></strong> + </div> + <div class="col-sm-10"> + <input type="text" id="msg" class="form-control" placeholder="Your Message" autofocus> + </div> </div> </div> diff --git a/shardweb/lib/shard_web/views/identity_view.ex b/shardweb/lib/shard_web/views/identity_view.ex new file mode 100644 index 0000000..63d5a50 --- /dev/null +++ b/shardweb/lib/shard_web/views/identity_view.ex @@ -0,0 +1,11 @@ +defmodule ShardWeb.IdentityView do + use ShardWeb, :view + + def identity_list do + Shard.Keys.list_identities + end + + def get_nick(pk) do + SApp.Identity.get_nick pk + end +end diff --git a/shardweb/lib/shard_web/views/layout_view.ex b/shardweb/lib/shard_web/views/layout_view.ex index 514779b..4012c38 100644 --- a/shardweb/lib/shard_web/views/layout_view.ex +++ b/shardweb/lib/shard_web/views/layout_view.ex @@ -1,5 +1,3 @@ defmodule ShardWeb.LayoutView do use ShardWeb, :view - - import PhoenixGon.View end diff --git a/shardweb/lib/shard_web/views/room_view.ex b/shardweb/lib/shard_web/views/room_view.ex index 7c102cc..7ec961b 100644 --- a/shardweb/lib/shard_web/views/room_view.ex +++ b/shardweb/lib/shard_web/views/room_view.ex @@ -1,6 +1,6 @@ defmodule ShardWeb.RoomView do use ShardWeb, :view - + def shard_list do Shard.Manager.list_shards end diff --git a/shardweb/mix.exs b/shardweb/mix.exs index a28461a..809043d 100644 --- a/shardweb/mix.exs +++ b/shardweb/mix.exs @@ -1,4 +1,4 @@ -defmodule Shardweb.Mixfile do +defmodule ShardWeb.Mixfile do use Mix.Project def project do @@ -18,7 +18,7 @@ defmodule Shardweb.Mixfile do # Type `mix help compile.app` for more information. def application do [ - mod: {Shardweb.Application, []}, + mod: {ShardWeb.Application, []}, extra_applications: [:logger, :runtime_tools] ] end |