fix: made menus more stable and verified and hooke up stuff that got lost
This commit is contained in:
@@ -2,6 +2,7 @@ defmodule BDS.BoundedAtoms do
|
||||
@moduledoc false
|
||||
|
||||
alias BDS.UI.Registry
|
||||
alias BDS.UI.MenuBar
|
||||
|
||||
@panel_tabs [:tasks, :output, :post_links, :git_log]
|
||||
@post_statuses [:draft, :published, :archived]
|
||||
@@ -37,11 +38,31 @@ defmodule BDS.BoundedAtoms do
|
||||
:view_posts,
|
||||
:view_media,
|
||||
:edit_preferences,
|
||||
:open_in_browser,
|
||||
:open_data_folder,
|
||||
:preview_post,
|
||||
:edit_menu,
|
||||
:rebuild_database,
|
||||
:reindex_text,
|
||||
:rebuild_embedding_index,
|
||||
:metadata_diff,
|
||||
:regenerate_calendar,
|
||||
:validate_translations,
|
||||
:find_duplicates,
|
||||
:generate_sitemap,
|
||||
:validate_site,
|
||||
:upload_site,
|
||||
:documentation,
|
||||
:api_documentation,
|
||||
:close_tab
|
||||
]
|
||||
@menu_actions MenuBar.default_groups(dev_mode?: true)
|
||||
|> Enum.flat_map(fn group ->
|
||||
Enum.flat_map(group.items, fn
|
||||
%{separator: true} -> []
|
||||
%{id: id} -> [id]
|
||||
end)
|
||||
end)
|
||||
|
||||
def atom(value, allowed, fallback \\ nil)
|
||||
|
||||
@@ -70,6 +91,7 @@ defmodule BDS.BoundedAtoms do
|
||||
def ai_endpoint(value, fallback \\ nil), do: atom(value, @ai_endpoints, fallback)
|
||||
def mcp_agent(value, fallback \\ nil), do: atom(value, @mcp_agents, fallback)
|
||||
def shell_command(value, fallback \\ nil), do: atom(value, @shell_commands, fallback)
|
||||
def menu_action(value, fallback \\ nil), do: atom(value, @menu_actions, fallback)
|
||||
|
||||
defp string_atom(value, allowed, fallback) do
|
||||
Enum.find(allowed, fallback, &(Atom.to_string(&1) == value))
|
||||
|
||||
@@ -279,6 +279,19 @@ defmodule BDS.Desktop.ShellCommands do
|
||||
end)
|
||||
end
|
||||
|
||||
defp dispatch("regenerate_calendar", project, _params) do
|
||||
queue_task(project, "regenerate_calendar", "Regenerate Calendar", "Generation", fn report ->
|
||||
{:ok, generation} = Generation.generate_site(project.id, [:core], on_progress: report)
|
||||
report.(1.0, "Calendar regenerated")
|
||||
|
||||
%{
|
||||
project_id: project.id,
|
||||
sections: generation.sections,
|
||||
generated_count: length(generation.generated_files)
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
defp dispatch("repair_metadata_diff", project, params) do
|
||||
items = normalize_metadata_diff_items(BDS.MapUtils.attr(params, :items, []))
|
||||
direction = BDS.MapUtils.attr(params, :direction)
|
||||
|
||||
@@ -56,6 +56,8 @@ defmodule BDS.Desktop.ShellLive do
|
||||
alias BDS.Projects
|
||||
alias BDS.Templates
|
||||
alias BDS.UI.{Commands, MenuBar, Session, Workbench}
|
||||
alias Desktop.OS
|
||||
alias BDS.Desktop.Shutdown
|
||||
|
||||
@refresh_interval 1_500
|
||||
@output_entry_limit 20
|
||||
@@ -71,6 +73,44 @@ defmodule BDS.Desktop.ShellLive do
|
||||
:api_documentation,
|
||||
:close_tab
|
||||
])
|
||||
@socket_menu_actions MapSet.new([
|
||||
:new_post,
|
||||
:import_media,
|
||||
:save,
|
||||
:publish_selected,
|
||||
:quit,
|
||||
:view_on_github,
|
||||
:report_issue,
|
||||
:about
|
||||
])
|
||||
@runtime_menu_actions MapSet.new([
|
||||
:undo,
|
||||
:redo,
|
||||
:cut,
|
||||
:copy,
|
||||
:paste,
|
||||
:delete,
|
||||
:select_all,
|
||||
:find,
|
||||
:replace,
|
||||
:reload,
|
||||
:force_reload,
|
||||
:reset_zoom,
|
||||
:zoom_in,
|
||||
:zoom_out,
|
||||
:toggle_full_screen
|
||||
])
|
||||
|
||||
def supported_menu_actions do
|
||||
@local_menu_actions
|
||||
|> MapSet.union(@socket_menu_actions)
|
||||
|> MapSet.union(@runtime_menu_actions)
|
||||
|> MapSet.union(MapSet.new([:open_in_browser, :open_data_folder]))
|
||||
|> MapSet.union(MapSet.new([:preview_post, :rebuild_database, :reindex_text]))
|
||||
|> MapSet.union(MapSet.new([:rebuild_embedding_index, :metadata_diff, :regenerate_calendar]))
|
||||
|> MapSet.union(MapSet.new([:validate_translations, :find_duplicates]))
|
||||
|> MapSet.union(MapSet.new([:generate_sitemap, :validate_site, :upload_site]))
|
||||
end
|
||||
|
||||
embed_templates("shell_live/*")
|
||||
|
||||
@@ -392,7 +432,10 @@ defmodule BDS.Desktop.ShellLive do
|
||||
if Layout.ignore_shortcut?(params) do
|
||||
{:noreply, socket}
|
||||
else
|
||||
{:noreply, reload_shell(socket, Commands.handle_shortcut(socket.assigns.workbench, params))}
|
||||
case Commands.command_for_shortcut(params) do
|
||||
nil -> {:noreply, socket}
|
||||
action -> {:noreply, handle_menu_action(socket, action)}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1833,17 +1876,99 @@ defmodule BDS.Desktop.ShellLive do
|
||||
end
|
||||
|
||||
defp handle_native_menu_action(socket, action) do
|
||||
with action_atom when not is_nil(action_atom) <- shell_command_atom(action) do
|
||||
if MapSet.member?(@local_menu_actions, action_atom) do
|
||||
reload_shell(socket, MenuBar.execute(socket.assigns.workbench, action_atom))
|
||||
else
|
||||
apply_shell_command(socket, action)
|
||||
end
|
||||
else
|
||||
_other -> append_output_entry(socket, "Menu", "Unsupported shell command", action, "error")
|
||||
case BoundedAtoms.menu_action(action) do
|
||||
nil -> append_output_entry(socket, "Menu", "Unsupported shell command", action, "error")
|
||||
action_atom -> handle_menu_action(socket, action_atom)
|
||||
end
|
||||
end
|
||||
|
||||
defp handle_menu_action(socket, action) when is_atom(action) do
|
||||
cond do
|
||||
MapSet.member?(@local_menu_actions, action) ->
|
||||
reload_shell(socket, MenuBar.execute(socket.assigns.workbench, action))
|
||||
|
||||
MapSet.member?(@socket_menu_actions, action) ->
|
||||
handle_socket_menu_action(socket, action)
|
||||
|
||||
MapSet.member?(@runtime_menu_actions, action) ->
|
||||
push_event(socket, "menu-runtime-command", %{action: Atom.to_string(action)})
|
||||
|
||||
shell_command?(action) ->
|
||||
apply_shell_command(socket, Atom.to_string(action))
|
||||
|
||||
true ->
|
||||
append_output_entry(socket, "Menu", "Unsupported shell command", Atom.to_string(action), "error")
|
||||
end
|
||||
end
|
||||
|
||||
defp handle_socket_menu_action(socket, :new_post), do: create_sidebar_item(socket, "post")
|
||||
defp handle_socket_menu_action(socket, :import_media), do: create_sidebar_item(socket, "media")
|
||||
defp handle_socket_menu_action(socket, :save), do: save_current_tab(socket)
|
||||
defp handle_socket_menu_action(socket, :publish_selected), do: publish_current_tab(socket)
|
||||
|
||||
defp handle_socket_menu_action(socket, :quit) do
|
||||
Shutdown.request_quit()
|
||||
socket
|
||||
end
|
||||
|
||||
defp handle_socket_menu_action(socket, :view_on_github) do
|
||||
OS.launch_default_browser("https://github.com/rfc1437/bDS")
|
||||
socket
|
||||
end
|
||||
|
||||
defp handle_socket_menu_action(socket, :report_issue) do
|
||||
OS.launch_default_browser("https://github.com/rfc1437/bDS/issues")
|
||||
socket
|
||||
end
|
||||
|
||||
defp handle_socket_menu_action(socket, :about) do
|
||||
append_output_entry(
|
||||
socket,
|
||||
"About",
|
||||
"Blogging Desktop Server",
|
||||
"Version #{Application.spec(:bds, :vsn) |> to_string()}",
|
||||
"info"
|
||||
)
|
||||
end
|
||||
|
||||
defp shell_command?(action), do: not is_nil(shell_command_atom(action))
|
||||
|
||||
defp save_current_tab(%{assigns: %{current_tab: %{type: :post, id: post_id}}} = socket) do
|
||||
PostEditor.persist_socket(socket, post_id, :save, &reload_shell/2, &append_output_entry/5)
|
||||
end
|
||||
|
||||
defp save_current_tab(%{assigns: %{current_tab: %{type: :media, id: media_id}}} = socket) do
|
||||
MediaEditor.persist_socket(socket, media_id, &reload_shell/2, &append_output_entry/5)
|
||||
end
|
||||
|
||||
defp save_current_tab(%{assigns: %{current_tab: %{type: :settings}}} = socket) do
|
||||
SettingsEditor.save_project(socket, &reload_shell/2, &append_output_entry/5)
|
||||
end
|
||||
|
||||
defp save_current_tab(%{assigns: %{current_tab: %{type: :menu_editor}}} = socket) do
|
||||
MenuEditor.toolbar_action(socket, "save", &reload_shell/2, &append_output_entry/5)
|
||||
end
|
||||
|
||||
defp save_current_tab(%{assigns: %{current_tab: %{type: :tags}}} = socket) do
|
||||
TagsEditor.save_tag(socket, &reload_shell/2, &append_output_entry/5)
|
||||
end
|
||||
|
||||
defp save_current_tab(%{assigns: %{current_tab: %{type: :scripts}}} = socket) do
|
||||
CodeEntityEditor.save_script(socket, &reload_shell/2, &append_output_entry/5)
|
||||
end
|
||||
|
||||
defp save_current_tab(%{assigns: %{current_tab: %{type: :templates}}} = socket) do
|
||||
CodeEntityEditor.save_template(socket, &reload_shell/2, &append_output_entry/5)
|
||||
end
|
||||
|
||||
defp save_current_tab(socket), do: reload_shell(socket, socket.assigns.workbench)
|
||||
|
||||
defp publish_current_tab(%{assigns: %{current_tab: %{type: :post, id: post_id}}} = socket) do
|
||||
PostEditor.persist_socket(socket, post_id, :publish, &reload_shell/2, &append_output_entry/5)
|
||||
end
|
||||
|
||||
defp publish_current_tab(socket), do: reload_shell(socket, socket.assigns.workbench)
|
||||
|
||||
defp apply_shell_command(socket, action, params \\ %{}),
|
||||
do: ShellCommandRunner.execute(socket, action, params, shell_command_callbacks())
|
||||
|
||||
|
||||
@@ -32,6 +32,13 @@ defmodule BDS.UI.Commands do
|
||||
]
|
||||
|
||||
def handle_shortcut(state, shortcut) when is_map(shortcut) do
|
||||
case command_for_shortcut(shortcut) do
|
||||
nil -> state
|
||||
command_id -> MenuBar.execute(state, command_id)
|
||||
end
|
||||
end
|
||||
|
||||
def command_for_shortcut(shortcut) when is_map(shortcut) do
|
||||
key = shortcut |> BDS.MapUtils.attr(:key, "") |> String.downcase()
|
||||
|
||||
primary =
|
||||
@@ -42,8 +49,8 @@ defmodule BDS.UI.Commands do
|
||||
alt = BDS.MapUtils.attr(shortcut, :alt, false)
|
||||
|
||||
case Enum.find(@menu_shortcuts, &shortcut_match?(&1, key, primary, shift, alt)) do
|
||||
%{id: command_id} -> MenuBar.execute(state, command_id)
|
||||
nil -> state
|
||||
%{id: command_id} -> command_id
|
||||
nil -> nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user