feat: first take at UI app
This commit is contained in:
3
lib/bds/desktop/main_window.ex
Normal file
3
lib/bds/desktop/main_window.ex
Normal file
@@ -0,0 +1,3 @@
|
||||
defmodule BDS.Desktop.MainWindow do
|
||||
@moduledoc false
|
||||
end
|
||||
42
lib/bds/desktop/menu.ex
Normal file
42
lib/bds/desktop/menu.ex
Normal file
@@ -0,0 +1,42 @@
|
||||
defmodule BDS.Desktop.Menu do
|
||||
@moduledoc false
|
||||
|
||||
use Desktop.Menu
|
||||
alias Desktop.Window
|
||||
|
||||
@impl true
|
||||
def mount(menu) do
|
||||
{:ok, menu}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<menu>
|
||||
<item onclick="open">Open</item>
|
||||
<hr />
|
||||
<item onclick="quit">Quit</item>
|
||||
</menu>
|
||||
"""
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("open", menu) do
|
||||
Window.show(BDS.Desktop.MainWindow)
|
||||
{:noreply, menu}
|
||||
end
|
||||
|
||||
def handle_event("quit", menu) do
|
||||
Window.quit()
|
||||
{:noreply, menu}
|
||||
end
|
||||
|
||||
def handle_event(_, menu) do
|
||||
{:noreply, menu}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_info(_, menu) do
|
||||
{:noreply, menu}
|
||||
end
|
||||
end
|
||||
73
lib/bds/desktop/menu_bar.ex
Normal file
73
lib/bds/desktop/menu_bar.ex
Normal file
@@ -0,0 +1,73 @@
|
||||
defmodule BDS.Desktop.MenuBar do
|
||||
@moduledoc false
|
||||
|
||||
use Desktop.Menu
|
||||
alias Desktop.Window
|
||||
|
||||
def groups(opts \\ []) do
|
||||
dev_mode? = Keyword.get(opts, :dev_mode?, false)
|
||||
|
||||
[
|
||||
%{id: :app, label: "App", items: [%{id: :about, label: "About"}]},
|
||||
%{id: :file, label: "File", items: [%{id: :new_post, label: "New Post"}, %{id: :close_tab, label: "Close Tab"}]},
|
||||
%{id: :edit, label: "Edit", items: [%{id: :undo, label: "Undo"}, %{id: :redo, label: "Redo"}]},
|
||||
%{id: :view, label: "View", items: view_items(dev_mode?)},
|
||||
%{id: :window, label: "Window", items: [%{id: :minimize, label: "Minimize"}]},
|
||||
%{id: :help, label: "Help", items: [%{id: :documentation, label: "Documentation"}]}
|
||||
]
|
||||
end
|
||||
|
||||
@impl true
|
||||
def mount(menu) do
|
||||
{:ok,
|
||||
Desktop.Menu.assign(
|
||||
menu,
|
||||
:groups,
|
||||
groups(dev_mode?: Application.get_env(:bds, :dev_routes, false))
|
||||
)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<menubar>
|
||||
<%= for group <- @groups do %>
|
||||
<menu label={group.label}>
|
||||
<%= for item <- group.items do %>
|
||||
<item onclick={Atom.to_string(item.id)}>{item.label}</item>
|
||||
<% end %>
|
||||
</menu>
|
||||
<% end %>
|
||||
</menubar>
|
||||
"""
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("quit", menu) do
|
||||
Window.quit()
|
||||
{:noreply, menu}
|
||||
end
|
||||
|
||||
def handle_event(_, menu) do
|
||||
{:noreply, menu}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_info(_, menu) do
|
||||
{:noreply, menu}
|
||||
end
|
||||
|
||||
defp view_items(dev_mode?) do
|
||||
items = [
|
||||
%{id: :toggle_sidebar, label: "Toggle Sidebar"},
|
||||
%{id: :toggle_panel, label: "Toggle Panel"},
|
||||
%{id: :toggle_assistant_sidebar, label: "Toggle Assistant Sidebar"}
|
||||
]
|
||||
|
||||
if dev_mode? do
|
||||
items ++ [%{id: :toggle_dev_tools, label: "Toggle Dev Tools"}]
|
||||
else
|
||||
items
|
||||
end
|
||||
end
|
||||
end
|
||||
49
lib/bds/desktop/router.ex
Normal file
49
lib/bds/desktop/router.ex
Normal file
@@ -0,0 +1,49 @@
|
||||
defmodule BDS.Desktop.Router do
|
||||
@moduledoc false
|
||||
|
||||
use Plug.Router
|
||||
|
||||
plug :put_secret_key_base
|
||||
|
||||
plug Plug.Session,
|
||||
store: :cookie,
|
||||
key: "_bds_desktop_key",
|
||||
signing_salt: "desktop-shell"
|
||||
|
||||
plug :match
|
||||
plug Desktop.Auth
|
||||
|
||||
plug Plug.Static,
|
||||
at: "/assets",
|
||||
from: {:bds, "priv/ui"},
|
||||
only: ["app.css", "app.js"]
|
||||
|
||||
plug :dispatch
|
||||
|
||||
get "/" do
|
||||
conn
|
||||
|> Plug.Conn.put_resp_content_type("text/html")
|
||||
|> Plug.Conn.send_resp(200, BDS.Desktop.ShellController.index_html())
|
||||
end
|
||||
|
||||
get "/health" do
|
||||
Plug.Conn.send_resp(conn, 200, "ok")
|
||||
end
|
||||
|
||||
match _ do
|
||||
Plug.Conn.send_resp(conn, 404, "not found")
|
||||
end
|
||||
|
||||
defp put_secret_key_base(conn, _opts) do
|
||||
if conn.secret_key_base do
|
||||
conn
|
||||
else
|
||||
%{conn | secret_key_base: desktop_secret_key_base()}
|
||||
end
|
||||
end
|
||||
|
||||
defp desktop_secret_key_base do
|
||||
Application.get_env(:bds, :desktop)[:secret_key_base] ||
|
||||
raise "missing :desktop secret_key_base configuration"
|
||||
end
|
||||
end
|
||||
38
lib/bds/desktop/server.ex
Normal file
38
lib/bds/desktop/server.ex
Normal file
@@ -0,0 +1,38 @@
|
||||
defmodule BDS.Desktop.Server do
|
||||
@moduledoc false
|
||||
|
||||
use GenServer
|
||||
|
||||
def child_spec(opts) do
|
||||
%{
|
||||
id: __MODULE__,
|
||||
start: {__MODULE__, :start_link, [opts]}
|
||||
}
|
||||
end
|
||||
|
||||
def start_link(opts) do
|
||||
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
|
||||
end
|
||||
|
||||
def url do
|
||||
BDS.Desktop.url(port())
|
||||
end
|
||||
|
||||
def port do
|
||||
Application.get_env(:bds, :desktop)[:port] || 4010
|
||||
end
|
||||
|
||||
@impl true
|
||||
def init(_opts) do
|
||||
{:ok, bandit_pid} =
|
||||
Bandit.start_link(
|
||||
plug: BDS.Desktop.Router,
|
||||
scheme: :http,
|
||||
ip: {127, 0, 0, 1},
|
||||
port: port(),
|
||||
startup_log: false
|
||||
)
|
||||
|
||||
{:ok, %{bandit_pid: bandit_pid}}
|
||||
end
|
||||
end
|
||||
7
lib/bds/desktop/shell_controller.ex
Normal file
7
lib/bds/desktop/shell_controller.ex
Normal file
@@ -0,0 +1,7 @@
|
||||
defmodule BDS.Desktop.ShellController do
|
||||
@moduledoc false
|
||||
|
||||
def index_html do
|
||||
File.read!(Application.app_dir(:bds, ["priv", "ui", "index.html"]))
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user