feat: terminal UI over the shared workbench core (issue #26, phase 4)

This commit is contained in:
2026-07-14 20:33:30 +02:00
parent 3a8fafd2fd
commit a3ca44640c
14 changed files with 1701 additions and 295 deletions

View File

@@ -12,6 +12,7 @@ The major architectural rework is in place.
- Assets use Phoenix-default Tailwind and esbuild tooling from [assets/](/Users/gb/Projects/bDS2/assets) into [priv/static/](/Users/gb/Projects/bDS2/priv/static).
- Core editorial flows are implemented in the main application: posts, media, tags, templates, scripts, imports, preview, generation, publishing, maintenance, AI, and MCP.
- Localization is now a first-class architectural concern rather than an afterthought: UI chrome and rendered site output have separate locale flows, and post/media translation workflows are built into the domain model.
- The app boots in three modes: the desktop app, a headless server (SSH-served terminal UI + tunneled GUI), and a local TUI — see [Headless Server Mode And Terminal UI](#headless-server-mode-and-terminal-ui).
The rewrite still aims to preserve the product behavior of bDS while replacing the technical stack. The contract is product behavior, not the old implementation language or framework choices.
@@ -156,6 +157,62 @@ mix dialyzer
mix assets.build
```
## Headless Server Mode And Terminal UI
Since issue #26 the app has three boot modes, selected with the `BDS_MODE`
environment variable (any release or dev boot; default is the desktop app):
- `desktop` — the native desktop app, unchanged.
- `server` — headless: no window, loopback-only HTTP endpoint, CLI sync
watcher, and an SSH daemon serving the terminal UI. Works on macOS,
Windows, and Linux (no display needed).
- `tui` — the headless server plus a TUI attached to the launching terminal.
### Build and run a headless server
```bash
MIX_ENV=prod mix release bds --overwrite
BDS_MODE=server _build/prod/rel/bds/bin/bds start
```
The SSH daemon listens on port `2222` (`BDS_SSH_PORT` or
`config :bds, :server, ssh_port:` to change). Authentication is public-key
only: on first boot the server generates a host key and an empty
`authorized_keys` (mode 600) in `ssh/` next to the database (default
`~/Library/Application Support/BDS2/ssh/`, or under `BDS_DATABASE_PATH`).
Add your public key there, then connect from any terminal:
```bash
ssh -p 2222 <server-host> # opens the TUI
```
Each SSH connection gets its own TUI session on the server; only terminal
cells cross the wire. All clients stay synchronized through the domain
event bus (`BDS.Events`) — a post created by a pipeline or another client
appears in every open shell.
### TUI keys
`↑/↓` or `j/k` navigate · `enter` open · `n` new post · `1-5` switch view
(posts/media/templates/scripts/tags) · `r` refresh · in the editor:
`ctrl+s` save, `ctrl+p` publish, `ctrl+t` title, `ctrl+l` language,
`ctrl+g` AI suggestions (airplane-mode gated), `esc` back · `ctrl+q` quit.
Images preview inline via the terminal image protocol. The UI language is
the server-side setting shared by every client.
### Remote GUI
The HTTP endpoint stays bound to `127.0.0.1` and is never exposed; GUI
clients tunnel through the same SSH daemon and keys:
```bash
ssh -p 2222 -L 4010:127.0.0.1:4010 -N <server-host> &
open http://127.0.0.1:4010
```
A built-in "Connect to Server…" mode in the desktop app is in progress
(issue #26, phase 5).
## Monaco Editor
Monaco is bundled via esbuild using its ESM entry point (`monaco-editor/esm/vs/editor/editor.main.js`). The

View File

@@ -12,6 +12,10 @@ defmodule BDS.Application do
[{BDS.Desktop.Server, []}, BDS.CliSync.Watcher, BDS.Server]
end
# Local TUI: the headless server plus a TUI on the launching terminal, so
# a GUI (via tunnel) and the local terminal can work in parallel.
def mode_children(:tui, env), do: mode_children(:server, env) ++ [{BDS.TUI, []}]
def mode_children(:desktop, env), do: desktop_children(env)
def desktop_children(env \\ nil)

View File

@@ -11,14 +11,19 @@ defmodule BDS.Server do
"""
@doc """
Resolves the boot mode from the `BDS_MODE` environment variable.
Anything other than `"server"` (case-insensitive) is desktop mode.
Resolves the boot mode from the `BDS_MODE` environment variable:
`"server"` (headless + SSH daemon), `"tui"` (headless + SSH daemon +
a TUI attached to the launching terminal), anything else is desktop.
"""
@spec mode(String.t() | nil) :: :desktop | :server
@spec mode(String.t() | nil) :: :desktop | :server | :tui
def mode(value \\ System.get_env("BDS_MODE"))
def mode(value) when is_binary(value) do
if String.downcase(value) == "server", do: :server, else: :desktop
case String.downcase(value) do
"server" -> :server
"tui" -> :tui
_other -> :desktop
end
end
def mode(nil), do: :desktop

View File

@@ -1,38 +1,593 @@
defmodule BDS.TUI do
@moduledoc """
Terminal UI entry point (issue #26), served per SSH connection by
`ExRatatui.SSH.Daemon` in server mode and runnable locally.
Terminal UI shell (issue #26, phase 4).
Placeholder shell for now: renders the app banner while the workbench
renderer lands in a later phase. The UI locale is the server-side UI
language setting, same as the GUI.
An `ExRatatui.App` over the shared UI core: `BDS.UI.Sidebar` for view
data, `BDS.UI.PostEditor.*` for the draft/save/publish workflow, and
`BDS.Events` for multi-client synchronization. Served per SSH connection
by `ExRatatui.SSH.Daemon` in server mode and runnable locally.
## Keys
Sidebar focus: `↑/↓`/`j/k` navigate, `enter` open, `n` new post,
`1..5` switch view (posts/media/templates/scripts/tags), `r` refresh.
Editor focus: text keys edit, `ctrl+s` save, `ctrl+p` publish,
`ctrl+t` edit title, `ctrl+l` cycle language, `ctrl+g` AI suggestions,
`esc` back to sidebar. `ctrl+q` quits, `esc` also closes a media
preview. The UI locale is the server-side UI language setting.
"""
use ExRatatui.App
use Gettext, backend: BDS.Gettext
alias BDS.AI
alias BDS.Desktop.UILocale
alias BDS.Events
alias BDS.Posts
alias BDS.Projects
alias BDS.UI.PostEditor.{Draft, Metadata, Persistence}
alias BDS.UI.Sidebar
alias ExRatatui.Layout
alias ExRatatui.Layout.Rect
alias ExRatatui.Widgets.Paragraph
alias ExRatatui.Style
alias ExRatatui.Widgets.{Block, List, Paragraph, Tabs, Textarea}
@views ~w(posts media templates scripts tags)
# ── Mount ────────────────────────────────────────────────────────────────
@impl true
def mount(_opts) do
UILocale.put(BDS.Desktop.ShellData.ui_language())
{:ok, %{}}
:ok = Events.subscribe()
project_id = Projects.shell_snapshot().active_project_id
state = %{
project_id: project_id,
view: "posts",
sidebar: nil,
items: [],
selected: 0,
focus: :sidebar,
editor: nil,
preview: nil,
image: nil,
busy: false,
status: nil
}
{:ok, load_sidebar(state)}
end
@impl true
def render(_state, frame) do
text =
"bDS2 — " <>
dgettext("ui", "Blogging Desktop Server") <>
"\n\n" <>
dgettext("ui", "Press q to quit.")
[{%Paragraph{text: text}, %Rect{x: 0, y: 0, width: frame.width, height: frame.height}}]
end
# ── Events: global keys ──────────────────────────────────────────────────
@impl true
def handle_event(%ExRatatui.Event.Key{code: "q"}, state), do: {:stop, state}
def handle_event(%ExRatatui.Event.Key{code: "q", modifiers: ["ctrl"]}, state),
do: {:stop, state}
def handle_event(%ExRatatui.Event.Key{code: "esc"}, %{image: image} = state)
when image != nil,
do: {:noreply, %{state | image: nil}}
def handle_event(%ExRatatui.Event.Key{kind: "press"} = key, %{focus: :sidebar} = state),
do: sidebar_key(key, state)
def handle_event(%ExRatatui.Event.Key{kind: "press"} = key, %{focus: :editor} = state),
do: editor_key(key, state)
def handle_event(_event, state), do: {:noreply, state}
# ── Events: sidebar focus ────────────────────────────────────────────────
defp sidebar_key(%{code: code}, state) when code in ["down", "j"],
do: {:noreply, move_selection(state, 1)}
defp sidebar_key(%{code: code}, state) when code in ["up", "k"],
do: {:noreply, move_selection(state, -1)}
defp sidebar_key(%{code: code}, state) when code in ~w(1 2 3 4 5) do
view = Enum.at(@views, String.to_integer(code) - 1)
{:noreply, load_sidebar(%{state | view: view, selected: 0, image: nil})}
end
defp sidebar_key(%{code: "r"}, state), do: {:noreply, load_sidebar(state)}
defp sidebar_key(%{code: "n"}, %{project_id: project_id} = state)
when is_binary(project_id) do
case Posts.create_post(%{project_id: project_id, title: "", content: ""}) do
{:ok, post} ->
{:noreply, state |> load_sidebar() |> open_post(post.id)}
{:error, reason} ->
{:noreply, toast(state, dgettext("ui", "New Post"), inspect(reason))}
end
end
defp sidebar_key(%{code: "enter"}, state) do
case selected_item(state) do
%{route: "post", id: post_id} -> {:noreply, open_post(state, post_id)}
%{route: "media", id: media_id} -> {:noreply, open_media(state, media_id)}
%{id: _id} -> {:noreply, toast(state, view_label(state.view), dgettext("ui", "Editing this item is not available in the terminal UI yet."))}
_other -> {:noreply, state}
end
end
defp sidebar_key(%{code: "tab"}, %{editor: editor} = state) when editor != nil,
do: {:noreply, %{state | focus: :editor}}
defp sidebar_key(_key, state), do: {:noreply, state}
# ── Events: editor focus ─────────────────────────────────────────────────
defp editor_key(%{code: "esc"}, %{editor: %{editing_title?: true}} = state),
do: {:noreply, put_in(state.editor.editing_title?, false)}
defp editor_key(%{code: "esc"}, state), do: {:noreply, %{state | focus: :sidebar}}
defp editor_key(%{code: "s", modifiers: ["ctrl"]}, state), do: {:noreply, persist(state, :save)}
defp editor_key(%{code: "p", modifiers: ["ctrl"]}, state),
do: {:noreply, persist(state, :publish)}
defp editor_key(%{code: "t", modifiers: ["ctrl"]}, state),
do: {:noreply, update_in(state.editor.editing_title?, &(not &1))}
defp editor_key(%{code: "l", modifiers: ["ctrl"]}, state), do: {:noreply, cycle_language(state)}
defp editor_key(%{code: "g", modifiers: ["ctrl"]}, state),
do: {:noreply, request_ai_suggestions(state)}
defp editor_key(key, %{editor: %{editing_title?: true}} = state),
do: {:noreply, title_key(key, state)}
defp editor_key(%{code: code, modifiers: modifiers}, %{editor: editor} = state) do
:ok = ExRatatui.textarea_handle_key(editor.textarea, code, modifiers)
dirty = editor.dirty or code not in ~w(up down left right home end pageup pagedown)
{:noreply, put_in(state.editor.dirty, dirty)}
end
defp title_key(%{code: "enter"}, state), do: put_in(state.editor.editing_title?, false)
defp title_key(%{code: "backspace"}, state),
do: state |> update_in([:editor, :title], &String.slice(&1, 0..-2//1)) |> mark_dirty()
defp title_key(%{code: code, modifiers: modifiers}, state)
when byte_size(code) >= 1 and modifiers == [] do
if String.length(code) == 1 do
state |> update_in([:editor, :title], &(&1 <> code)) |> mark_dirty()
else
state
end
end
defp title_key(_key, state), do: state
defp mark_dirty(state), do: put_in(state.editor.dirty, true)
# ── Info: event bus + AI results ─────────────────────────────────────────
@impl true
def handle_info({:entity_changed, %{entity: entity, entity_id: id, action: action}}, state) do
state = load_sidebar(state)
state =
if state.editor && state.editor.post.id == id && entity == "post" do
if action == :deleted, do: %{state | editor: nil, focus: :sidebar}, else: state
else
state
end
{:noreply, state}
end
def handle_info({:settings_changed, "ui.language"}, state) do
UILocale.put(BDS.Desktop.ShellData.ui_language())
{:noreply, load_sidebar(state)}
end
def handle_info({:ai_suggestions_result, :post, post_id, result}, state) do
state = %{state | busy: false}
if state.editor && state.editor.post.id == post_id do
attrs =
%{}
|> maybe_put_suggestion(:title, Map.get(result, :title))
|> maybe_put_suggestion(:excerpt, Map.get(result, :excerpt))
case attrs == %{} || Posts.update_post(post_id, attrs) do
{:ok, _post} ->
{:noreply,
state
|> reload_editor()
|> toast(dgettext("ui", "AI Suggestions"), dgettext("ui", "Suggestions applied."))}
true ->
{:noreply, toast(state, dgettext("ui", "AI Suggestions"), dgettext("ui", "No suggestions returned."))}
{:error, reason} ->
{:noreply, toast(state, dgettext("ui", "AI Suggestions"), inspect(reason))}
end
else
{:noreply, state}
end
end
def handle_info({:ai_suggestions_error, :post, _post_id, reason}, state) do
{:noreply, toast(%{state | busy: false}, dgettext("ui", "AI Suggestions"), inspect(reason))}
end
def handle_info(_message, state), do: {:noreply, state}
# ── Render ───────────────────────────────────────────────────────────────
@impl true
def render(state, frame) do
area = %Rect{x: 0, y: 0, width: frame.width, height: frame.height}
[tabs_rect, body_rect, status_rect] = Layout.split(area, :vertical, [
{:length, 1},
{:min, 3},
{:length, 1}
])
[sidebar_rect, main_rect] = Layout.split(body_rect, :horizontal, [
{:length, min(40, div(frame.width, 3))},
{:min, 20}
])
view_tabs(state, tabs_rect) ++
sidebar_widgets(state, sidebar_rect) ++
main_widgets(state, main_rect) ++
status_widgets(state, status_rect) ++
image_widgets(state, body_rect)
end
defp view_tabs(state, rect) do
[
{%Tabs{
titles: Enum.map(@views, &view_label/1),
selected: Enum.find_index(@views, &(&1 == state.view)),
highlight_style: %Style{fg: :cyan, modifiers: [:bold]}
}, rect}
]
end
defp sidebar_widgets(state, rect) do
items =
Enum.map(state.items, fn
{:header, title} -> "── #{title}"
{:item, item} -> " #{item_label(item)}"
end)
focused? = state.focus == :sidebar
[
{%List{
items: items,
selected: state.selected,
highlight_style:
if(focused?,
do: %Style{fg: :black, bg: :cyan},
else: %Style{modifiers: [:bold]}
),
block: %Block{title: view_label(state.view), borders: [:all]}
}, rect}
]
end
defp main_widgets(%{editor: nil} = state, rect) do
text =
case selected_item(state) do
%{route: "media"} = item ->
dgettext("ui", "Press enter to preview %{name}.", name: item_label(item))
_other ->
dgettext("ui", "Select an entry and press enter to open it.")
end
[{%Paragraph{text: text, block: %Block{title: "bDS2", borders: [:all]}}, rect}]
end
defp main_widgets(%{editor: editor} = state, rect) do
[title_rect, body_rect] = Layout.split(rect, :vertical, [{:length, 3}, {:min, 3}])
title_block_label =
if editor.editing_title?,
do: dgettext("ui", "Title (editing — enter to confirm)"),
else: dgettext("ui", "Title (ctrl+t to edit)")
title_widget =
{%Paragraph{
text: editor.title,
block: %Block{title: title_block_label, borders: [:all]},
style:
if(editor.editing_title?, do: %Style{fg: :yellow}, else: %Style{})
}, title_rect}
body_title =
"#{dgettext("ui", "Content")} [#{editor.language}]" <>
if(editor.dirty, do: "", else: "")
body_widget =
{%Textarea{
state: editor.textarea,
block: %Block{title: body_title, borders: [:all]},
cursor_style:
if(state.focus == :editor and not editor.editing_title?,
do: %Style{bg: :cyan},
else: %Style{}
)
}, body_rect}
[title_widget, body_widget]
end
defp status_widgets(state, rect) do
text =
cond do
state.busy -> dgettext("ui", "Working…")
state.status -> state.status
true -> default_status(state)
end
[{%Paragraph{text: text, style: %Style{fg: :dark_gray}}, rect}]
end
defp image_widgets(%{image: nil}, _rect), do: []
defp image_widgets(%{image: %{widget: widget, title: title}}, rect) do
overlay = %Rect{
x: rect.x + 2,
y: rect.y + 1,
width: max(rect.width - 4, 10),
height: max(rect.height - 2, 5)
}
[inner] = Layout.split(overlay, :vertical, [{:min, 3}])
[
{%Block{title: title <> "" <> dgettext("ui", "esc to close"), borders: [:all]}, overlay},
{widget,
%Rect{x: inner.x + 1, y: inner.y + 1, width: inner.width - 2, height: inner.height - 2}}
]
end
defp default_status(%{focus: :sidebar}),
do:
dgettext(
"ui",
"enter open · n new post · 1-5 views · r refresh · ctrl+q quit"
)
defp default_status(%{focus: :editor}),
do:
dgettext(
"ui",
"ctrl+s save · ctrl+p publish · ctrl+t title · ctrl+l language · ctrl+g AI · esc back"
)
# ── Sidebar data ─────────────────────────────────────────────────────────
defp load_sidebar(state) do
view = Sidebar.view(state.project_id, state.view)
items = flatten_items(view, state.view)
selected =
case items do
[] -> 0
_some -> seek_item(items, clamp(state.selected, length(items)), 1)
end
%{state | sidebar: view, items: items, selected: selected}
end
defp flatten_items(view, route) do
sections =
cond do
is_list(view[:sections]) -> view[:sections]
is_list(view[:items]) -> [%{title: nil, items: view[:items]}]
true -> []
end
Enum.flat_map(sections, fn section ->
headers = if section[:title], do: [{:header, section.title}], else: []
headers ++
Enum.map(section[:items] || [], fn item ->
{:item, Map.put_new(item, :route, route_for(item, route))}
end)
end)
end
defp route_for(item, route), do: item[:route] || String.trim_trailing(route, "s")
defp move_selection(state, delta) do
count = length(state.items)
if count == 0 do
state
else
next = seek_item(state.items, clamp(state.selected + delta, count), delta)
%{state | selected: next}
end
end
# Selection skips section headers in the given direction; parks on the
# boundary when only headers remain that way.
defp seek_item(items, index, delta) do
case Enum.at(items, index) do
{:item, _} ->
index
{:header, _} ->
next = clamp(index + sign(delta), length(items))
if next == index, do: index, else: seek_item(items, next, delta)
nil ->
index
end
end
defp sign(delta) when delta < 0, do: -1
defp sign(_delta), do: 1
defp clamp(value, count), do: value |> max(0) |> min(count - 1)
defp selected_item(state) do
case Enum.at(state.items, state.selected) do
{:item, item} -> item
_other -> nil
end
end
defp item_label(item) do
title =
item[:title] || item[:name] || item[:original_name] || item[:label] || item[:id] || "?"
status = item[:status]
if status, do: "#{title} (#{status})", else: to_string(title)
end
defp view_label("posts"), do: dgettext("ui", "Posts")
defp view_label("media"), do: dgettext("ui", "Media")
defp view_label("templates"), do: dgettext("ui", "Templates")
defp view_label("scripts"), do: dgettext("ui", "Scripts")
defp view_label("tags"), do: dgettext("ui", "Tags")
# ── Post editor ──────────────────────────────────────────────────────────
defp open_post(state, post_id) do
case Posts.get_post(post_id) do
nil ->
toast(state, dgettext("ui", "Posts"), dgettext("ui", "Post not found."))
post ->
metadata = Metadata.project_metadata(post.project_id)
language = Metadata.canonical_language(post, metadata)
%{state | editor: build_editor(post, metadata, language), focus: :editor, image: nil}
end
end
defp build_editor(post, metadata, language) do
form = Draft.persisted_form(post, metadata, language)
textarea = ExRatatui.textarea_new()
:ok = ExRatatui.textarea_insert_str(textarea, form["content"] || "")
%{
post: post,
metadata: metadata,
language: language,
form: form,
title: form["title"] || "",
textarea: textarea,
editing_title?: false,
dirty: false
}
end
defp reload_editor(%{editor: nil} = state), do: state
defp reload_editor(%{editor: editor} = state) do
case Posts.get_post(editor.post.id) do
nil -> %{state | editor: nil, focus: :sidebar}
post -> %{state | editor: build_editor(post, editor.metadata, editor.language)}
end
end
defp persist(%{editor: editor} = state, action) do
draft = %{
editor.form
| "title" => editor.title,
"content" => ExRatatui.textarea_get_value(editor.textarea)
}
case Persistence.persist(editor.post, draft, editor.language, editor.metadata, action) do
{:ok, _result} ->
message =
case action do
:publish -> dgettext("ui", "Published.")
_save -> dgettext("ui", "Saved.")
end
state
|> reload_editor()
|> load_sidebar()
|> toast(editor_title(editor), message)
{:error, reason} ->
toast(state, editor_title(editor), inspect(reason))
end
end
defp cycle_language(%{editor: editor} = state) do
if editor.dirty do
toast(state, editor_title(editor), dgettext("ui", "Save before switching languages."))
else
languages = Metadata.languages(editor.metadata)
index = Enum.find_index(languages, &(&1 == editor.language)) || 0
next = Enum.at(languages, rem(index + 1, length(languages)))
%{state | editor: build_editor(editor.post, editor.metadata, next)}
end
end
defp request_ai_suggestions(%{editor: editor} = state) do
if AI.airplane_mode?() and not AI.airplane_endpoint_configured?() do
toast(
state,
dgettext("ui", "AI Suggestions"),
dgettext("ui", "AI is unavailable in airplane mode without a local endpoint.")
)
else
parent = self()
post_id = editor.post.id
language = editor.metadata.main_language || "en"
{:ok, _pid} =
Task.Supervisor.start_child(BDS.TCP.TaskSupervisor, fn ->
case AI.analyze_post(post_id, language: language) do
{:ok, result} -> send(parent, {:ai_suggestions_result, :post, post_id, result})
{:error, reason} -> send(parent, {:ai_suggestions_error, :post, post_id, reason})
end
end)
%{state | busy: true}
end
end
defp maybe_put_suggestion(attrs, _key, nil), do: attrs
defp maybe_put_suggestion(attrs, key, value) do
case String.trim(to_string(value)) do
"" -> attrs
trimmed -> Map.put(attrs, key, trimmed)
end
end
defp editor_title(editor),
do: Metadata.display_title(editor.title, editor.post.slug, editor.post.id)
# ── Media preview ────────────────────────────────────────────────────────
defp open_media(state, media_id) do
with %{} = media <- BDS.Media.get_media(media_id),
true <- String.starts_with?(to_string(media.mime_type || ""), "image/"),
project when project != nil <- Projects.get_project(media.project_id),
path = Path.join(Projects.project_data_dir(project), media.file_path),
{:ok, bytes} <- File.read(path),
{:ok, widget} <- ExRatatui.Image.new(bytes) do
%{state | image: %{title: item_media_title(media), widget: widget}}
else
false ->
toast(state, dgettext("ui", "Media"), dgettext("ui", "Only images can be previewed."))
_other ->
toast(state, dgettext("ui", "Media"), dgettext("ui", "Could not load this file."))
end
end
defp item_media_title(media), do: media.title || media.original_name || media.id
# ── Status line ──────────────────────────────────────────────────────────
defp toast(state, title, message), do: %{state | status: "#{title}: #{message}"}
end

View File

@@ -10,7 +10,7 @@ msgstr "%{canonical} = %{translation}"
msgid "%{count} mapped"
msgstr "%{count} zugeordnet"
#: lib/bds/desktop/shell_data.ex:171
#: lib/bds/desktop/shell_data.ex:173
#, elixir-autogen, elixir-format
msgid "%{count} post"
msgid_plural "%{count} posts"
@@ -81,6 +81,11 @@ msgstr "KI-Einstellungen"
#: lib/bds/desktop/shell_live/overlay_manager.ex:72
#: lib/bds/desktop/shell_live/post_editor.ex:920
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:43
#: lib/bds/tui.ex:203
#: lib/bds/tui.ex:206
#: lib/bds/tui.ex:209
#: lib/bds/tui.ex:217
#: lib/bds/tui.ex:537
#, elixir-autogen, elixir-format
msgid "AI Suggestions"
msgstr "KI-Vorschlaege"
@@ -301,7 +306,7 @@ msgstr "Tag-Archive gerendert"
msgid "Validation apply prepared"
msgstr "Anwenden der Validierung vorbereitet"
#: lib/bds/desktop/shell_data.ex:164
#: lib/bds/desktop/shell_data.ex:166
#: lib/bds/ui/sidebar.ex:331
#, elixir-autogen, elixir-format
msgid "Archived"
@@ -336,7 +341,7 @@ msgstr "Autor"
msgid "Auto"
msgstr "Automatisch"
#: lib/bds/desktop/shell_live.ex:442
#: lib/bds/desktop/shell_live.ex:443
#: lib/bds/desktop/shell_live/chat_editor.ex:234
#: lib/bds/desktop/shell_live/media_editor.ex:171
#: lib/bds/desktop/shell_live/media_editor.ex:364
@@ -486,7 +491,7 @@ msgstr "Kategorie-Standards, Render-Flags und Template-Zuordnung"
msgid "Category name is required"
msgstr "Kategoriename ist erforderlich"
#: lib/bds/desktop/shell_live.ex:780
#: lib/bds/desktop/shell_live.ex:789
#: lib/bds/desktop/shell_live/chat_editor.ex:87
#: lib/bds/desktop/shell_live/chat_editor.ex:233
#: lib/bds/desktop/shell_live/chat_editor.ex:323
@@ -584,6 +589,7 @@ msgstr "Bestaetigen"
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:375
#: lib/bds/desktop/shell_live/script_editor_html/script_editor.html.heex:34
#: lib/bds/desktop/shell_live/template_editor_html/template_editor.html.heex:32
#: lib/bds/tui.ex:308
#: lib/bds/ui/sidebar.ex:764
#, elixir-autogen, elixir-format
msgid "Content"
@@ -753,7 +759,7 @@ msgstr "Übersetzung löschen"
msgid "Delete conversation"
msgstr "Unterhaltung löschen"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:65
#: lib/bds/ui/post_editor/persistence.ex:69
#, elixir-autogen, elixir-format
msgid "Delete this unpublished draft"
msgstr "Diesen unveröffentlichten Entwurf löschen"
@@ -810,17 +816,17 @@ msgstr "Denkausgabe für das Offline-Chat-Modell deaktivieren"
msgid "Disable reasoning output for the online chat model"
msgstr "Denkausgabe für das Online-Chat-Modell deaktivieren"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:57
#: lib/bds/ui/post_editor/persistence.ex:61
#, elixir-autogen, elixir-format
msgid "Discard Changes"
msgstr "Änderungen verwerfen"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:58
#: lib/bds/ui/post_editor/persistence.ex:62
#, elixir-autogen, elixir-format
msgid "Discard Draft"
msgstr "Entwurf verwerfen"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:64
#: lib/bds/ui/post_editor/persistence.ex:68
#, elixir-autogen, elixir-format
msgid "Discard changes and restore the published version"
msgstr "Änderungen verwerfen und veröffentlichte Version wiederherstellen"
@@ -863,7 +869,7 @@ msgstr "Nicht übersetzen"
msgid "Documentation"
msgstr "Dokumentation"
#: lib/bds/desktop/shell_data.ex:162
#: lib/bds/desktop/shell_data.ex:164
#, elixir-autogen, elixir-format
msgid "Draft"
msgstr "Entwurf"
@@ -1063,7 +1069,7 @@ msgstr "Galerie"
msgid "Generate Site"
msgstr "Website generieren"
#: lib/bds/desktop/shell_live.ex:781
#: lib/bds/desktop/shell_live.ex:790
#: lib/bds/desktop/shell_live/socket_state.ex:109
#: lib/bds/ui/sidebar.ex:789
#, elixir-autogen, elixir-format
@@ -1076,8 +1082,8 @@ msgstr "Git"
msgid "Git Diff"
msgstr "Git-Diff"
#: lib/bds/desktop/shell_data.ex:226
#: lib/bds/desktop/shell_live.ex:777
#: lib/bds/desktop/shell_data.ex:228
#: lib/bds/desktop/shell_live.ex:786
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
#, elixir-autogen, elixir-format
msgid "Git Log"
@@ -1103,7 +1109,7 @@ msgstr "Startseite"
msgid "Host"
msgstr "Host"
#: lib/bds/desktop/shell_data.ex:98
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_live/index.html.heex:657
#: lib/bds/desktop/shell_live/media_editor.ex:731
#: lib/bds/desktop/shell_live/post_editor.ex:1038
@@ -1200,9 +1206,9 @@ msgstr "Importdefinitionen"
msgid "Import failed: %{error}"
msgstr "Import fehlgeschlagen: %{error}"
#: lib/bds/desktop/shell_live.ex:605
#: lib/bds/desktop/shell_live.ex:893
#: lib/bds/desktop/shell_live.ex:899
#: lib/bds/desktop/shell_live.ex:606
#: lib/bds/desktop/shell_live.ex:902
#: lib/bds/desktop/shell_live.ex:908
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
#, elixir-autogen, elixir-format
msgid "Import media"
@@ -1337,7 +1343,7 @@ msgstr "MIME-Typ"
msgid "Macros (%{count})"
msgstr "Makros (%{count})"
#: lib/bds/desktop/shell_data.ex:101
#: lib/bds/desktop/shell_data.ex:103
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:55
#, elixir-autogen, elixir-format
msgid "Main Language"
@@ -1379,6 +1385,9 @@ msgstr "Maximale Beiträge pro Seite"
#: lib/bds/desktop/shell_live/misc_editor.ex:762
#: lib/bds/desktop/shell_live/sidebar_components.ex:654
#: lib/bds/desktop/shell_live/sidebar_delete.ex:175
#: lib/bds/tui.ex:452
#: lib/bds/tui.ex:581
#: lib/bds/tui.ex:584
#: lib/bds/ui/registry.ex:30
#: lib/bds/ui/registry.ex:100
#: lib/bds/ui/sidebar.ex:558
@@ -1431,7 +1440,7 @@ msgstr "Metadaten-Diff"
msgid "Missing URLs"
msgstr "Fehlende URLs"
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_data.ex:102
#, elixir-autogen, elixir-format
msgid "Mode"
msgstr "Modus"
@@ -1466,6 +1475,7 @@ msgstr "Neue Seite"
#: lib/bds/desktop/menu_bar.ex:185
#: lib/bds/desktop/shell_live/sidebar_create.ex:41
#: lib/bds/tui.ex:103
#, elixir-autogen, elixir-format
msgid "New Post"
msgstr "Neuer Beitrag"
@@ -1644,7 +1654,7 @@ msgstr "In der Neufassung noch nicht unterstützt"
msgid "Nothing to Import"
msgstr "Nichts zu importieren"
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_data.ex:102
#: lib/bds/desktop/shell_live/index.html.heex:503
#, elixir-autogen, elixir-format
msgid "Offline"
@@ -1784,7 +1794,7 @@ msgstr "Sonstige"
msgid "Other (%{count})"
msgstr "Andere (%{count})"
#: lib/bds/desktop/shell_live.ex:776
#: lib/bds/desktop/shell_live.ex:785
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
#, elixir-autogen, elixir-format
msgid "Output"
@@ -1866,7 +1876,7 @@ msgstr "Die erkannte Sprache für dieses Medium speichern"
msgid "Post"
msgstr "Beitrag"
#: lib/bds/desktop/shell_data.ex:229
#: lib/bds/desktop/shell_data.ex:231
#: lib/bds/desktop/shell_live/panel_renderer.ex:118
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:310
#, elixir-autogen, elixir-format
@@ -1901,6 +1911,8 @@ msgstr "Beitrag gespeichert"
#: lib/bds/desktop/menu_bar.ex:202
#: lib/bds/desktop/shell_live/misc_editor.ex:664
#: lib/bds/desktop/shell_live/misc_editor.ex:761
#: lib/bds/tui.ex:451
#: lib/bds/tui.ex:462
#: lib/bds/ui/registry.ex:14
#: lib/bds/ui/sidebar.ex:271
#, elixir-autogen, elixir-format
@@ -1985,7 +1997,7 @@ msgstr "Veröffentlichen"
msgid "Publish Selected"
msgstr "Ausgewähltes veröffentlichen"
#: lib/bds/desktop/shell_data.ex:163
#: lib/bds/desktop/shell_data.ex:165
#: lib/bds/desktop/shell_live/post_editor.ex:1036
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:472
#: lib/bds/ui/sidebar.ex:324
@@ -2282,6 +2294,7 @@ msgstr "Scripting-Funktionen werden in der Neufassung auf Anwendungsebene konfig
#: lib/bds/desktop/shell_live/script_editor.ex:216
#: lib/bds/desktop/shell_live/script_editor.ex:219
#: lib/bds/desktop/shell_live/script_editor.ex:234
#: lib/bds/tui.ex:454
#: lib/bds/ui/registry.ex:38
#: lib/bds/ui/sidebar.ex:63
#: lib/bds/ui/sidebar.ex:115
@@ -2456,7 +2469,7 @@ msgstr "Chat starten"
msgid "Starting..."
msgstr "Starte..."
#: lib/bds/desktop/shell_data.ex:97
#: lib/bds/desktop/shell_data.ex:99
#: lib/bds/desktop/shell_live/import_editor.ex:1182
#: lib/bds/desktop/shell_live/import_editor.ex:1233
#, elixir-autogen, elixir-format
@@ -2529,6 +2542,7 @@ msgstr "Schlagwortname"
#: lib/bds/desktop/shell_live/tags_editor.ex:222
#: lib/bds/desktop/shell_live/tags_editor.ex:253
#: lib/bds/desktop/shell_live/tags_editor_html/tags_editor.html.heex:11
#: lib/bds/tui.ex:455
#: lib/bds/ui/registry.ex:54
#: lib/bds/ui/registry.ex:103
#: lib/bds/ui/sidebar.ex:289
@@ -2538,7 +2552,7 @@ msgstr "Schlagwortname"
msgid "Tags"
msgstr "Tags"
#: lib/bds/desktop/shell_live.ex:775
#: lib/bds/desktop/shell_live.ex:784
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
#, elixir-autogen, elixir-format
msgid "Tasks"
@@ -2584,6 +2598,7 @@ msgstr "Template-Syntax ist gültig"
#: lib/bds/desktop/shell_live/template_editor.ex:171
#: lib/bds/desktop/shell_live/template_editor.ex:176
#: lib/bds/desktop/shell_live/template_editor.ex:191
#: lib/bds/tui.ex:453
#: lib/bds/ui/registry.ex:46
#: lib/bds/ui/sidebar.ex:71
#: lib/bds/ui/sidebar.ex:122
@@ -2780,7 +2795,7 @@ msgid "Unsaved"
msgstr "Nicht gespeichert"
#: lib/bds/desktop/shell_live/import_editor.ex:871
#: lib/bds/desktop/shell_live/post_editor/post_metadata.ex:166
#: lib/bds/ui/post_editor/metadata.ex:166
#: lib/bds/ui/sidebar.ex:1108
#, elixir-autogen, elixir-format
msgid "Untitled"
@@ -3161,9 +3176,9 @@ msgid "I can help you manage your blog with rich visualizations. Try asking me t
msgstr "Ich kann dir mit interaktiven Visualisierungen bei deinem Blog helfen. Frag mich zum Beispiel nach:"
#: lib/bds/desktop/shell_live/index.html.heex:289
#, elixir-autogen, elixir-format, fuzzy
#, elixir-autogen, elixir-format
msgid "Media Files"
msgstr "Medien"
msgstr "Mediendateien"
#: lib/bds/desktop/shell_live/chat_editor_html/chat_editor.html.heex:21
#, elixir-autogen, elixir-format
@@ -3218,12 +3233,12 @@ msgstr "Willkommen beim KI-Assistenten"
msgid "Comparing database and filesystem metadata"
msgstr "Vergleicht Datenbank- und Dateisystem-Metadaten"
#: lib/bds/desktop/shell_live.ex:681
#: lib/bds/desktop/shell_live.ex:682
#, elixir-autogen, elixir-format
msgid "Added %{count} images to post"
msgstr "%{count} Bilder zum Beitrag hinzugefügt"
#: lib/bds/desktop/shell_live.ex:649
#: lib/bds/desktop/shell_live.ex:650
#, elixir-autogen, elixir-format
msgid "Added %{title}"
msgstr "%{title} hinzugefügt"
@@ -3243,18 +3258,18 @@ msgstr "Endbenutzer-Anleitung für redaktionelle Arbeitsabläufe, Medien, Vorlag
msgid "Image Import Concurrency"
msgstr "Gleichzeitige Bildimporte"
#: lib/bds/desktop/shell_live.ex:441
#: lib/bds/desktop/shell_live.ex:454
#: lib/bds/desktop/shell_live.ex:648
#: lib/bds/desktop/shell_live.ex:680
#: lib/bds/desktop/shell_live.ex:691
#: lib/bds/desktop/shell_live.ex:702
#: lib/bds/desktop/shell_live.ex:442
#: lib/bds/desktop/shell_live.ex:455
#: lib/bds/desktop/shell_live.ex:649
#: lib/bds/desktop/shell_live.ex:681
#: lib/bds/desktop/shell_live.ex:692
#: lib/bds/desktop/shell_live.ex:703
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
#, elixir-autogen, elixir-format
msgid "Add Gallery Images"
msgstr "Galerie-Bilder hinzufügen"
#: lib/bds/desktop/shell_live.ex:703
#: lib/bds/desktop/shell_live.ex:704
#, elixir-autogen, elixir-format
msgid "Failed to process %{path}: %{reason}"
msgstr "%{path} konnte nicht verarbeitet werden: %{reason}"
@@ -3445,12 +3460,12 @@ msgstr "umbenannt"
msgid "untracked"
msgstr "nicht verfolgt"
#: lib/bds/desktop/shell_live.ex:801
#: lib/bds/desktop/shell_live.ex:810
#, elixir-autogen, elixir-format
msgid "Blogmark"
msgstr "Blogmark"
#: lib/bds/desktop/shell_live.ex:844
#: lib/bds/desktop/shell_live.ex:853
#, elixir-autogen, elixir-format
msgid "Open a project before importing a blogmark."
msgstr "Öffnen Sie ein Projekt, bevor Sie ein Blogmark importieren."
@@ -3482,16 +3497,16 @@ msgid "Copy Bookmarklet to Clipboard"
msgstr "Bookmarklet in die Zwischenablage kopieren"
#: lib/bds/desktop/shell_live/overlay_manager.ex:300
#, elixir-autogen, elixir-format, fuzzy
#, elixir-autogen, elixir-format
msgid "Delete Tag"
msgstr "Loeschen"
msgstr "Tag löschen"
#: lib/bds/desktop/shell_live/settings_editor.ex:66
#, elixir-autogen, elixir-format
msgid "Failed to copy bookmarklet to clipboard"
msgstr "Bookmarklet konnte nicht in die Zwischenablage kopiert werden"
#: lib/bds/desktop/shell_live.ex:813
#: lib/bds/desktop/shell_live.ex:822
#, elixir-autogen, elixir-format
msgid "The project this blogmark targets does not exist here."
msgstr "Das Projekt, auf das dieses Blogmark verweist, existiert hier nicht."
@@ -3598,12 +3613,92 @@ msgstr "OK"
msgid "The endpoint returned no models. You can still type a model name manually."
msgstr "Der Endpunkt hat keine Modelle zurückgegeben. Sie können einen Modellnamen weiterhin manuell eingeben."
#: lib/bds/tui.ex:28
#: lib/bds/tui.ex:538
#, elixir-autogen, elixir-format
msgid "Blogging Desktop Server"
msgstr "Blogging Desktop Server"
msgid "AI is unavailable in airplane mode without a local endpoint."
msgstr "KI ist im Flugmodus ohne lokalen Endpunkt nicht verfügbar."
#: lib/bds/tui.ex:30
#: lib/bds/tui.ex:584
#, elixir-autogen, elixir-format
msgid "Press q to quit."
msgstr "Drücken Sie q zum Beenden."
msgid "Could not load this file."
msgstr "Diese Datei konnte nicht geladen werden."
#: lib/bds/tui.ex:111
#, elixir-autogen, elixir-format
msgid "Editing this item is not available in the terminal UI yet."
msgstr "Die Bearbeitung dieses Eintrags ist in der Terminal-Oberfläche noch nicht verfügbar."
#: lib/bds/tui.ex:206
#, elixir-autogen, elixir-format
msgid "No suggestions returned."
msgstr "Keine Vorschläge erhalten."
#: lib/bds/tui.ex:581
#, elixir-autogen, elixir-format
msgid "Only images can be previewed."
msgstr "Nur Bilder können in der Vorschau angezeigt werden."
#: lib/bds/tui.ex:462
#, elixir-autogen, elixir-format
msgid "Post not found."
msgstr "Beitrag nicht gefunden."
#: lib/bds/tui.ex:282
#, elixir-autogen, elixir-format
msgid "Press enter to preview %{name}."
msgstr "Drücken Sie Enter, um %{name} in der Vorschau anzuzeigen."
#: lib/bds/tui.ex:508
#, elixir-autogen, elixir-format
msgid "Published."
msgstr "Veröffentlicht."
#: lib/bds/tui.ex:524
#, elixir-autogen, elixir-format
msgid "Save before switching languages."
msgstr "Speichern Sie vor dem Sprachwechsel."
#: lib/bds/tui.ex:509
#, elixir-autogen, elixir-format
msgid "Saved."
msgstr "Gespeichert."
#: lib/bds/tui.ex:285
#, elixir-autogen, elixir-format
msgid "Select an entry and press enter to open it."
msgstr "Wählen Sie einen Eintrag aus und öffnen Sie ihn mit Enter."
#: lib/bds/tui.ex:203
#, elixir-autogen, elixir-format
msgid "Suggestions applied."
msgstr "Vorschläge übernommen."
#: lib/bds/tui.ex:297
#, elixir-autogen, elixir-format
msgid "Title (ctrl+t to edit)"
msgstr "Titel (Strg+T zum Bearbeiten)"
#: lib/bds/tui.ex:296
#, elixir-autogen, elixir-format
msgid "Title (editing — enter to confirm)"
msgstr "Titel (Bearbeitung — Enter zum Bestätigen)"
#: lib/bds/tui.ex:328
#, elixir-autogen, elixir-format
msgid "Working…"
msgstr "Wird bearbeitet…"
#: lib/bds/tui.ex:364
#, elixir-autogen, elixir-format
msgid "ctrl+s save · ctrl+p publish · ctrl+t title · ctrl+l language · ctrl+g AI · esc back"
msgstr "Strg+S Speichern · Strg+P Veröffentlichen · Strg+T Titel · Strg+L Sprache · Strg+G KI · Esc Zurück"
#: lib/bds/tui.ex:357
#, elixir-autogen, elixir-format
msgid "enter open · n new post · 1-5 views · r refresh · ctrl+q quit"
msgstr "Enter Öffnen · N Neuer Beitrag · 1-5 Ansichten · R Aktualisieren · Strg+Q Beenden"
#: lib/bds/tui.ex:349
#, elixir-autogen, elixir-format
msgid "esc to close"
msgstr "Esc zum Schließen"

View File

@@ -10,7 +10,7 @@ msgstr ""
msgid "%{count} mapped"
msgstr ""
#: lib/bds/desktop/shell_data.ex:171
#: lib/bds/desktop/shell_data.ex:173
#, elixir-autogen, elixir-format
msgid "%{count} post"
msgid_plural "%{count} posts"
@@ -81,6 +81,11 @@ msgstr ""
#: lib/bds/desktop/shell_live/overlay_manager.ex:72
#: lib/bds/desktop/shell_live/post_editor.ex:920
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:43
#: lib/bds/tui.ex:203
#: lib/bds/tui.ex:206
#: lib/bds/tui.ex:209
#: lib/bds/tui.ex:217
#: lib/bds/tui.ex:537
#, elixir-autogen, elixir-format
msgid "AI Suggestions"
msgstr ""
@@ -301,7 +306,7 @@ msgstr ""
msgid "Validation apply prepared"
msgstr ""
#: lib/bds/desktop/shell_data.ex:164
#: lib/bds/desktop/shell_data.ex:166
#: lib/bds/ui/sidebar.ex:331
#, elixir-autogen, elixir-format
msgid "Archived"
@@ -336,7 +341,7 @@ msgstr ""
msgid "Auto"
msgstr ""
#: lib/bds/desktop/shell_live.ex:442
#: lib/bds/desktop/shell_live.ex:443
#: lib/bds/desktop/shell_live/chat_editor.ex:234
#: lib/bds/desktop/shell_live/media_editor.ex:171
#: lib/bds/desktop/shell_live/media_editor.ex:364
@@ -486,7 +491,7 @@ msgstr ""
msgid "Category name is required"
msgstr ""
#: lib/bds/desktop/shell_live.ex:780
#: lib/bds/desktop/shell_live.ex:789
#: lib/bds/desktop/shell_live/chat_editor.ex:87
#: lib/bds/desktop/shell_live/chat_editor.ex:233
#: lib/bds/desktop/shell_live/chat_editor.ex:323
@@ -584,6 +589,7 @@ msgstr ""
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:375
#: lib/bds/desktop/shell_live/script_editor_html/script_editor.html.heex:34
#: lib/bds/desktop/shell_live/template_editor_html/template_editor.html.heex:32
#: lib/bds/tui.ex:308
#: lib/bds/ui/sidebar.ex:764
#, elixir-autogen, elixir-format
msgid "Content"
@@ -753,7 +759,7 @@ msgstr ""
msgid "Delete conversation"
msgstr ""
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:65
#: lib/bds/ui/post_editor/persistence.ex:69
#, elixir-autogen, elixir-format
msgid "Delete this unpublished draft"
msgstr ""
@@ -810,17 +816,17 @@ msgstr ""
msgid "Disable reasoning output for the online chat model"
msgstr ""
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:57
#: lib/bds/ui/post_editor/persistence.ex:61
#, elixir-autogen, elixir-format
msgid "Discard Changes"
msgstr ""
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:58
#: lib/bds/ui/post_editor/persistence.ex:62
#, elixir-autogen, elixir-format
msgid "Discard Draft"
msgstr ""
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:64
#: lib/bds/ui/post_editor/persistence.ex:68
#, elixir-autogen, elixir-format
msgid "Discard changes and restore the published version"
msgstr ""
@@ -863,7 +869,7 @@ msgstr ""
msgid "Documentation"
msgstr ""
#: lib/bds/desktop/shell_data.ex:162
#: lib/bds/desktop/shell_data.ex:164
#, elixir-autogen, elixir-format
msgid "Draft"
msgstr ""
@@ -1063,7 +1069,7 @@ msgstr ""
msgid "Generate Site"
msgstr ""
#: lib/bds/desktop/shell_live.ex:781
#: lib/bds/desktop/shell_live.ex:790
#: lib/bds/desktop/shell_live/socket_state.ex:109
#: lib/bds/ui/sidebar.ex:789
#, elixir-autogen, elixir-format
@@ -1076,8 +1082,8 @@ msgstr ""
msgid "Git Diff"
msgstr ""
#: lib/bds/desktop/shell_data.ex:226
#: lib/bds/desktop/shell_live.ex:777
#: lib/bds/desktop/shell_data.ex:228
#: lib/bds/desktop/shell_live.ex:786
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
#, elixir-autogen, elixir-format
msgid "Git Log"
@@ -1103,7 +1109,7 @@ msgstr ""
msgid "Host"
msgstr ""
#: lib/bds/desktop/shell_data.ex:98
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_live/index.html.heex:657
#: lib/bds/desktop/shell_live/media_editor.ex:731
#: lib/bds/desktop/shell_live/post_editor.ex:1038
@@ -1200,9 +1206,9 @@ msgstr ""
msgid "Import failed: %{error}"
msgstr ""
#: lib/bds/desktop/shell_live.ex:605
#: lib/bds/desktop/shell_live.ex:893
#: lib/bds/desktop/shell_live.ex:899
#: lib/bds/desktop/shell_live.ex:606
#: lib/bds/desktop/shell_live.ex:902
#: lib/bds/desktop/shell_live.ex:908
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
#, elixir-autogen, elixir-format
msgid "Import media"
@@ -1337,7 +1343,7 @@ msgstr ""
msgid "Macros (%{count})"
msgstr ""
#: lib/bds/desktop/shell_data.ex:101
#: lib/bds/desktop/shell_data.ex:103
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:55
#, elixir-autogen, elixir-format
msgid "Main Language"
@@ -1379,6 +1385,9 @@ msgstr ""
#: lib/bds/desktop/shell_live/misc_editor.ex:762
#: lib/bds/desktop/shell_live/sidebar_components.ex:654
#: lib/bds/desktop/shell_live/sidebar_delete.ex:175
#: lib/bds/tui.ex:452
#: lib/bds/tui.ex:581
#: lib/bds/tui.ex:584
#: lib/bds/ui/registry.ex:30
#: lib/bds/ui/registry.ex:100
#: lib/bds/ui/sidebar.ex:558
@@ -1431,7 +1440,7 @@ msgstr ""
msgid "Missing URLs"
msgstr ""
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_data.ex:102
#, elixir-autogen, elixir-format
msgid "Mode"
msgstr ""
@@ -1466,6 +1475,7 @@ msgstr ""
#: lib/bds/desktop/menu_bar.ex:185
#: lib/bds/desktop/shell_live/sidebar_create.ex:41
#: lib/bds/tui.ex:103
#, elixir-autogen, elixir-format
msgid "New Post"
msgstr ""
@@ -1644,7 +1654,7 @@ msgstr ""
msgid "Nothing to Import"
msgstr ""
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_data.ex:102
#: lib/bds/desktop/shell_live/index.html.heex:503
#, elixir-autogen, elixir-format
msgid "Offline"
@@ -1784,7 +1794,7 @@ msgstr ""
msgid "Other (%{count})"
msgstr ""
#: lib/bds/desktop/shell_live.ex:776
#: lib/bds/desktop/shell_live.ex:785
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
#, elixir-autogen, elixir-format
msgid "Output"
@@ -1866,7 +1876,7 @@ msgstr ""
msgid "Post"
msgstr ""
#: lib/bds/desktop/shell_data.ex:229
#: lib/bds/desktop/shell_data.ex:231
#: lib/bds/desktop/shell_live/panel_renderer.ex:118
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:310
#, elixir-autogen, elixir-format
@@ -1901,6 +1911,8 @@ msgstr ""
#: lib/bds/desktop/menu_bar.ex:202
#: lib/bds/desktop/shell_live/misc_editor.ex:664
#: lib/bds/desktop/shell_live/misc_editor.ex:761
#: lib/bds/tui.ex:451
#: lib/bds/tui.ex:462
#: lib/bds/ui/registry.ex:14
#: lib/bds/ui/sidebar.ex:271
#, elixir-autogen, elixir-format
@@ -1985,7 +1997,7 @@ msgstr ""
msgid "Publish Selected"
msgstr ""
#: lib/bds/desktop/shell_data.ex:163
#: lib/bds/desktop/shell_data.ex:165
#: lib/bds/desktop/shell_live/post_editor.ex:1036
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:472
#: lib/bds/ui/sidebar.ex:324
@@ -2282,6 +2294,7 @@ msgstr ""
#: lib/bds/desktop/shell_live/script_editor.ex:216
#: lib/bds/desktop/shell_live/script_editor.ex:219
#: lib/bds/desktop/shell_live/script_editor.ex:234
#: lib/bds/tui.ex:454
#: lib/bds/ui/registry.ex:38
#: lib/bds/ui/sidebar.ex:63
#: lib/bds/ui/sidebar.ex:115
@@ -2456,7 +2469,7 @@ msgstr ""
msgid "Starting..."
msgstr ""
#: lib/bds/desktop/shell_data.ex:97
#: lib/bds/desktop/shell_data.ex:99
#: lib/bds/desktop/shell_live/import_editor.ex:1182
#: lib/bds/desktop/shell_live/import_editor.ex:1233
#, elixir-autogen, elixir-format
@@ -2529,6 +2542,7 @@ msgstr ""
#: lib/bds/desktop/shell_live/tags_editor.ex:222
#: lib/bds/desktop/shell_live/tags_editor.ex:253
#: lib/bds/desktop/shell_live/tags_editor_html/tags_editor.html.heex:11
#: lib/bds/tui.ex:455
#: lib/bds/ui/registry.ex:54
#: lib/bds/ui/registry.ex:103
#: lib/bds/ui/sidebar.ex:289
@@ -2538,7 +2552,7 @@ msgstr ""
msgid "Tags"
msgstr ""
#: lib/bds/desktop/shell_live.ex:775
#: lib/bds/desktop/shell_live.ex:784
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
#, elixir-autogen, elixir-format
msgid "Tasks"
@@ -2584,6 +2598,7 @@ msgstr ""
#: lib/bds/desktop/shell_live/template_editor.ex:171
#: lib/bds/desktop/shell_live/template_editor.ex:176
#: lib/bds/desktop/shell_live/template_editor.ex:191
#: lib/bds/tui.ex:453
#: lib/bds/ui/registry.ex:46
#: lib/bds/ui/sidebar.ex:71
#: lib/bds/ui/sidebar.ex:122
@@ -2780,7 +2795,7 @@ msgid "Unsaved"
msgstr ""
#: lib/bds/desktop/shell_live/import_editor.ex:871
#: lib/bds/desktop/shell_live/post_editor/post_metadata.ex:166
#: lib/bds/ui/post_editor/metadata.ex:166
#: lib/bds/ui/sidebar.ex:1108
#, elixir-autogen, elixir-format
msgid "Untitled"
@@ -3218,12 +3233,12 @@ msgstr ""
msgid "Comparing database and filesystem metadata"
msgstr "Comparing database and filesystem metadata"
#: lib/bds/desktop/shell_live.ex:681
#: lib/bds/desktop/shell_live.ex:682
#, elixir-autogen, elixir-format
msgid "Added %{count} images to post"
msgstr "Added %{count} images to post"
#: lib/bds/desktop/shell_live.ex:649
#: lib/bds/desktop/shell_live.ex:650
#, elixir-autogen, elixir-format
msgid "Added %{title}"
msgstr "Added %{title}"
@@ -3243,18 +3258,18 @@ msgstr ""
msgid "Image Import Concurrency"
msgstr "Image Import Concurrency"
#: lib/bds/desktop/shell_live.ex:441
#: lib/bds/desktop/shell_live.ex:454
#: lib/bds/desktop/shell_live.ex:648
#: lib/bds/desktop/shell_live.ex:680
#: lib/bds/desktop/shell_live.ex:691
#: lib/bds/desktop/shell_live.ex:702
#: lib/bds/desktop/shell_live.ex:442
#: lib/bds/desktop/shell_live.ex:455
#: lib/bds/desktop/shell_live.ex:649
#: lib/bds/desktop/shell_live.ex:681
#: lib/bds/desktop/shell_live.ex:692
#: lib/bds/desktop/shell_live.ex:703
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
#, elixir-autogen, elixir-format
msgid "Add Gallery Images"
msgstr "Add Gallery Images"
#: lib/bds/desktop/shell_live.ex:703
#: lib/bds/desktop/shell_live.ex:704
#, elixir-autogen, elixir-format
msgid "Failed to process %{path}: %{reason}"
msgstr "Failed to process %{path}: %{reason}"
@@ -3445,12 +3460,12 @@ msgstr ""
msgid "untracked"
msgstr ""
#: lib/bds/desktop/shell_live.ex:801
#: lib/bds/desktop/shell_live.ex:810
#, elixir-autogen, elixir-format, fuzzy
msgid "Blogmark"
msgstr "Blogmark"
#: lib/bds/desktop/shell_live.ex:844
#: lib/bds/desktop/shell_live.ex:853
#, elixir-autogen, elixir-format
msgid "Open a project before importing a blogmark."
msgstr ""
@@ -3491,7 +3506,7 @@ msgstr ""
msgid "Failed to copy bookmarklet to clipboard"
msgstr ""
#: lib/bds/desktop/shell_live.ex:813
#: lib/bds/desktop/shell_live.ex:822
#, elixir-autogen, elixir-format
msgid "The project this blogmark targets does not exist here."
msgstr ""
@@ -3598,12 +3613,92 @@ msgstr ""
msgid "The endpoint returned no models. You can still type a model name manually."
msgstr ""
#: lib/bds/tui.ex:28
#: lib/bds/tui.ex:538
#, elixir-autogen, elixir-format
msgid "Blogging Desktop Server"
msgid "AI is unavailable in airplane mode without a local endpoint."
msgstr ""
#: lib/bds/tui.ex:30
#, elixir-autogen, elixir-format
msgid "Press q to quit."
#: lib/bds/tui.ex:584
#, elixir-autogen, elixir-format, fuzzy
msgid "Could not load this file."
msgstr ""
#: lib/bds/tui.ex:111
#, elixir-autogen, elixir-format
msgid "Editing this item is not available in the terminal UI yet."
msgstr ""
#: lib/bds/tui.ex:206
#, elixir-autogen, elixir-format
msgid "No suggestions returned."
msgstr ""
#: lib/bds/tui.ex:581
#, elixir-autogen, elixir-format
msgid "Only images can be previewed."
msgstr ""
#: lib/bds/tui.ex:462
#, elixir-autogen, elixir-format
msgid "Post not found."
msgstr ""
#: lib/bds/tui.ex:282
#, elixir-autogen, elixir-format
msgid "Press enter to preview %{name}."
msgstr ""
#: lib/bds/tui.ex:508
#, elixir-autogen, elixir-format, fuzzy
msgid "Published."
msgstr ""
#: lib/bds/tui.ex:524
#, elixir-autogen, elixir-format
msgid "Save before switching languages."
msgstr ""
#: lib/bds/tui.ex:509
#, elixir-autogen, elixir-format, fuzzy
msgid "Saved."
msgstr ""
#: lib/bds/tui.ex:285
#, elixir-autogen, elixir-format
msgid "Select an entry and press enter to open it."
msgstr ""
#: lib/bds/tui.ex:203
#, elixir-autogen, elixir-format
msgid "Suggestions applied."
msgstr ""
#: lib/bds/tui.ex:297
#, elixir-autogen, elixir-format
msgid "Title (ctrl+t to edit)"
msgstr ""
#: lib/bds/tui.ex:296
#, elixir-autogen, elixir-format
msgid "Title (editing — enter to confirm)"
msgstr ""
#: lib/bds/tui.ex:328
#, elixir-autogen, elixir-format, fuzzy
msgid "Working…"
msgstr ""
#: lib/bds/tui.ex:364
#, elixir-autogen, elixir-format
msgid "ctrl+s save · ctrl+p publish · ctrl+t title · ctrl+l language · ctrl+g AI · esc back"
msgstr ""
#: lib/bds/tui.ex:357
#, elixir-autogen, elixir-format
msgid "enter open · n new post · 1-5 views · r refresh · ctrl+q quit"
msgstr ""
#: lib/bds/tui.ex:349
#, elixir-autogen, elixir-format
msgid "esc to close"
msgstr ""

View File

@@ -10,7 +10,7 @@ msgstr "%{canonical} = %{translation}"
msgid "%{count} mapped"
msgstr "%{count} mapeados"
#: lib/bds/desktop/shell_data.ex:171
#: lib/bds/desktop/shell_data.ex:173
#, elixir-autogen, elixir-format
msgid "%{count} post"
msgid_plural "%{count} posts"
@@ -81,6 +81,11 @@ msgstr "Configuración de IA"
#: lib/bds/desktop/shell_live/overlay_manager.ex:72
#: lib/bds/desktop/shell_live/post_editor.ex:920
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:43
#: lib/bds/tui.ex:203
#: lib/bds/tui.ex:206
#: lib/bds/tui.ex:209
#: lib/bds/tui.ex:217
#: lib/bds/tui.ex:537
#, elixir-autogen, elixir-format
msgid "AI Suggestions"
msgstr "Sugerencias de IA"
@@ -301,7 +306,7 @@ msgstr "Archivos de etiquetas renderizados"
msgid "Validation apply prepared"
msgstr "Aplicación de validación preparada"
#: lib/bds/desktop/shell_data.ex:164
#: lib/bds/desktop/shell_data.ex:166
#: lib/bds/ui/sidebar.ex:331
#, elixir-autogen, elixir-format
msgid "Archived"
@@ -336,7 +341,7 @@ msgstr "Autor"
msgid "Auto"
msgstr "Automático"
#: lib/bds/desktop/shell_live.ex:442
#: lib/bds/desktop/shell_live.ex:443
#: lib/bds/desktop/shell_live/chat_editor.ex:234
#: lib/bds/desktop/shell_live/media_editor.ex:171
#: lib/bds/desktop/shell_live/media_editor.ex:364
@@ -486,7 +491,7 @@ msgstr "Valores predeterminados de categoría, opciones de renderizado y conexi
msgid "Category name is required"
msgstr "El nombre de la categoría es obligatorio"
#: lib/bds/desktop/shell_live.ex:780
#: lib/bds/desktop/shell_live.ex:789
#: lib/bds/desktop/shell_live/chat_editor.ex:87
#: lib/bds/desktop/shell_live/chat_editor.ex:233
#: lib/bds/desktop/shell_live/chat_editor.ex:323
@@ -584,6 +589,7 @@ msgstr "Confirmar"
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:375
#: lib/bds/desktop/shell_live/script_editor_html/script_editor.html.heex:34
#: lib/bds/desktop/shell_live/template_editor_html/template_editor.html.heex:32
#: lib/bds/tui.ex:308
#: lib/bds/ui/sidebar.ex:764
#, elixir-autogen, elixir-format
msgid "Content"
@@ -753,7 +759,7 @@ msgstr "Eliminar traducción"
msgid "Delete conversation"
msgstr "Eliminar conversación"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:65
#: lib/bds/ui/post_editor/persistence.ex:69
#, elixir-autogen, elixir-format
msgid "Delete this unpublished draft"
msgstr "Eliminar este borrador no publicado"
@@ -810,17 +816,17 @@ msgstr "Desactivar la salida de razonamiento del modelo de chat sin conexión"
msgid "Disable reasoning output for the online chat model"
msgstr "Desactivar la salida de razonamiento del modelo de chat en línea"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:57
#: lib/bds/ui/post_editor/persistence.ex:61
#, elixir-autogen, elixir-format
msgid "Discard Changes"
msgstr "Descartar cambios"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:58
#: lib/bds/ui/post_editor/persistence.ex:62
#, elixir-autogen, elixir-format
msgid "Discard Draft"
msgstr "Descartar borrador"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:64
#: lib/bds/ui/post_editor/persistence.ex:68
#, elixir-autogen, elixir-format
msgid "Discard changes and restore the published version"
msgstr "Descartar cambios y restaurar la versión publicada"
@@ -863,7 +869,7 @@ msgstr "No traducir"
msgid "Documentation"
msgstr "Documentación"
#: lib/bds/desktop/shell_data.ex:162
#: lib/bds/desktop/shell_data.ex:164
#, elixir-autogen, elixir-format
msgid "Draft"
msgstr "Borrador"
@@ -1063,7 +1069,7 @@ msgstr "Galeria"
msgid "Generate Site"
msgstr "Generar sitio"
#: lib/bds/desktop/shell_live.ex:781
#: lib/bds/desktop/shell_live.ex:790
#: lib/bds/desktop/shell_live/socket_state.ex:109
#: lib/bds/ui/sidebar.ex:789
#, elixir-autogen, elixir-format
@@ -1076,8 +1082,8 @@ msgstr "Git"
msgid "Git Diff"
msgstr "Diff de Git"
#: lib/bds/desktop/shell_data.ex:226
#: lib/bds/desktop/shell_live.ex:777
#: lib/bds/desktop/shell_data.ex:228
#: lib/bds/desktop/shell_live.ex:786
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
#, elixir-autogen, elixir-format
msgid "Git Log"
@@ -1103,7 +1109,7 @@ msgstr "Inicio"
msgid "Host"
msgstr "Host"
#: lib/bds/desktop/shell_data.ex:98
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_live/index.html.heex:657
#: lib/bds/desktop/shell_live/media_editor.ex:731
#: lib/bds/desktop/shell_live/post_editor.ex:1038
@@ -1200,9 +1206,9 @@ msgstr "Definiciones de importación"
msgid "Import failed: %{error}"
msgstr "La importación falló: %{error}"
#: lib/bds/desktop/shell_live.ex:605
#: lib/bds/desktop/shell_live.ex:893
#: lib/bds/desktop/shell_live.ex:899
#: lib/bds/desktop/shell_live.ex:606
#: lib/bds/desktop/shell_live.ex:902
#: lib/bds/desktop/shell_live.ex:908
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
#, elixir-autogen, elixir-format
msgid "Import media"
@@ -1337,7 +1343,7 @@ msgstr "Tipo MIME"
msgid "Macros (%{count})"
msgstr "Macros (%{count})"
#: lib/bds/desktop/shell_data.ex:101
#: lib/bds/desktop/shell_data.ex:103
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:55
#, elixir-autogen, elixir-format
msgid "Main Language"
@@ -1379,6 +1385,9 @@ msgstr "Máximo de publicaciones por página"
#: lib/bds/desktop/shell_live/misc_editor.ex:762
#: lib/bds/desktop/shell_live/sidebar_components.ex:654
#: lib/bds/desktop/shell_live/sidebar_delete.ex:175
#: lib/bds/tui.ex:452
#: lib/bds/tui.ex:581
#: lib/bds/tui.ex:584
#: lib/bds/ui/registry.ex:30
#: lib/bds/ui/registry.ex:100
#: lib/bds/ui/sidebar.ex:558
@@ -1431,7 +1440,7 @@ msgstr "Diff de metadatos"
msgid "Missing URLs"
msgstr "URLs faltantes"
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_data.ex:102
#, elixir-autogen, elixir-format
msgid "Mode"
msgstr "Modo"
@@ -1466,6 +1475,7 @@ msgstr "Nueva página"
#: lib/bds/desktop/menu_bar.ex:185
#: lib/bds/desktop/shell_live/sidebar_create.ex:41
#: lib/bds/tui.ex:103
#, elixir-autogen, elixir-format
msgid "New Post"
msgstr "Nueva entrada"
@@ -1644,7 +1654,7 @@ msgstr "Todavía no compatible en la reescritura"
msgid "Nothing to Import"
msgstr "Nada para importar"
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_data.ex:102
#: lib/bds/desktop/shell_live/index.html.heex:503
#, elixir-autogen, elixir-format
msgid "Offline"
@@ -1784,7 +1794,7 @@ msgstr "Otros"
msgid "Other (%{count})"
msgstr "Otros (%{count})"
#: lib/bds/desktop/shell_live.ex:776
#: lib/bds/desktop/shell_live.ex:785
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
#, elixir-autogen, elixir-format
msgid "Output"
@@ -1866,7 +1876,7 @@ msgstr "Guardar el idioma detectado para este medio"
msgid "Post"
msgstr "Publicación"
#: lib/bds/desktop/shell_data.ex:229
#: lib/bds/desktop/shell_data.ex:231
#: lib/bds/desktop/shell_live/panel_renderer.ex:118
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:310
#, elixir-autogen, elixir-format
@@ -1901,6 +1911,8 @@ msgstr "Artículo guardado"
#: lib/bds/desktop/menu_bar.ex:202
#: lib/bds/desktop/shell_live/misc_editor.ex:664
#: lib/bds/desktop/shell_live/misc_editor.ex:761
#: lib/bds/tui.ex:451
#: lib/bds/tui.ex:462
#: lib/bds/ui/registry.ex:14
#: lib/bds/ui/sidebar.ex:271
#, elixir-autogen, elixir-format
@@ -1985,7 +1997,7 @@ msgstr "Publicar"
msgid "Publish Selected"
msgstr "Publicar seleccionados"
#: lib/bds/desktop/shell_data.ex:163
#: lib/bds/desktop/shell_data.ex:165
#: lib/bds/desktop/shell_live/post_editor.ex:1036
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:472
#: lib/bds/ui/sidebar.ex:324
@@ -2282,6 +2294,7 @@ msgstr "Las capacidades de scripts se configuran en la capa de aplicación en la
#: lib/bds/desktop/shell_live/script_editor.ex:216
#: lib/bds/desktop/shell_live/script_editor.ex:219
#: lib/bds/desktop/shell_live/script_editor.ex:234
#: lib/bds/tui.ex:454
#: lib/bds/ui/registry.ex:38
#: lib/bds/ui/sidebar.ex:63
#: lib/bds/ui/sidebar.ex:115
@@ -2456,7 +2469,7 @@ msgstr "Iniciar chat"
msgid "Starting..."
msgstr "Iniciando..."
#: lib/bds/desktop/shell_data.ex:97
#: lib/bds/desktop/shell_data.ex:99
#: lib/bds/desktop/shell_live/import_editor.ex:1182
#: lib/bds/desktop/shell_live/import_editor.ex:1233
#, elixir-autogen, elixir-format
@@ -2529,6 +2542,7 @@ msgstr "Nombre de la etiqueta"
#: lib/bds/desktop/shell_live/tags_editor.ex:222
#: lib/bds/desktop/shell_live/tags_editor.ex:253
#: lib/bds/desktop/shell_live/tags_editor_html/tags_editor.html.heex:11
#: lib/bds/tui.ex:455
#: lib/bds/ui/registry.ex:54
#: lib/bds/ui/registry.ex:103
#: lib/bds/ui/sidebar.ex:289
@@ -2538,7 +2552,7 @@ msgstr "Nombre de la etiqueta"
msgid "Tags"
msgstr "Etiquetas"
#: lib/bds/desktop/shell_live.ex:775
#: lib/bds/desktop/shell_live.ex:784
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
#, elixir-autogen, elixir-format
msgid "Tasks"
@@ -2584,6 +2598,7 @@ msgstr "La sintaxis de la plantilla es válida"
#: lib/bds/desktop/shell_live/template_editor.ex:171
#: lib/bds/desktop/shell_live/template_editor.ex:176
#: lib/bds/desktop/shell_live/template_editor.ex:191
#: lib/bds/tui.ex:453
#: lib/bds/ui/registry.ex:46
#: lib/bds/ui/sidebar.ex:71
#: lib/bds/ui/sidebar.ex:122
@@ -2780,7 +2795,7 @@ msgid "Unsaved"
msgstr "Sin guardar"
#: lib/bds/desktop/shell_live/import_editor.ex:871
#: lib/bds/desktop/shell_live/post_editor/post_metadata.ex:166
#: lib/bds/ui/post_editor/metadata.ex:166
#: lib/bds/ui/sidebar.ex:1108
#, elixir-autogen, elixir-format
msgid "Untitled"
@@ -3161,9 +3176,9 @@ msgid "I can help you manage your blog with rich visualizations. Try asking me t
msgstr "Puedo ayudarte a gestionar tu blog con visualizaciones interactivas. Prueba a pedirme que:"
#: lib/bds/desktop/shell_live/index.html.heex:289
#, elixir-autogen, elixir-format, fuzzy
#, elixir-autogen, elixir-format
msgid "Media Files"
msgstr "Medios"
msgstr "Archivos multimedia"
#: lib/bds/desktop/shell_live/chat_editor_html/chat_editor.html.heex:21
#, elixir-autogen, elixir-format
@@ -3218,12 +3233,12 @@ msgstr "Bienvenido al asistente de IA"
msgid "Comparing database and filesystem metadata"
msgstr "Comparando metadatos de la base de datos y del sistema de archivos"
#: lib/bds/desktop/shell_live.ex:681
#: lib/bds/desktop/shell_live.ex:682
#, elixir-autogen, elixir-format
msgid "Added %{count} images to post"
msgstr "%{count} imágenes añadidas a la publicación"
#: lib/bds/desktop/shell_live.ex:649
#: lib/bds/desktop/shell_live.ex:650
#, elixir-autogen, elixir-format
msgid "Added %{title}"
msgstr "%{title} añadido"
@@ -3243,18 +3258,18 @@ msgstr "Guía del usuario para flujos editoriales, medios, plantillas, traducci
msgid "Image Import Concurrency"
msgstr "Importación simultánea de imágenes"
#: lib/bds/desktop/shell_live.ex:441
#: lib/bds/desktop/shell_live.ex:454
#: lib/bds/desktop/shell_live.ex:648
#: lib/bds/desktop/shell_live.ex:680
#: lib/bds/desktop/shell_live.ex:691
#: lib/bds/desktop/shell_live.ex:702
#: lib/bds/desktop/shell_live.ex:442
#: lib/bds/desktop/shell_live.ex:455
#: lib/bds/desktop/shell_live.ex:649
#: lib/bds/desktop/shell_live.ex:681
#: lib/bds/desktop/shell_live.ex:692
#: lib/bds/desktop/shell_live.ex:703
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
#, elixir-autogen, elixir-format
msgid "Add Gallery Images"
msgstr "Añadir imágenes a la galería"
#: lib/bds/desktop/shell_live.ex:703
#: lib/bds/desktop/shell_live.ex:704
#, elixir-autogen, elixir-format
msgid "Failed to process %{path}: %{reason}"
msgstr "No se pudo procesar %{path}: %{reason}"
@@ -3445,12 +3460,12 @@ msgstr "renombrado"
msgid "untracked"
msgstr "sin seguimiento"
#: lib/bds/desktop/shell_live.ex:801
#: lib/bds/desktop/shell_live.ex:810
#, elixir-autogen, elixir-format
msgid "Blogmark"
msgstr "Blogmark"
#: lib/bds/desktop/shell_live.ex:844
#: lib/bds/desktop/shell_live.ex:853
#, elixir-autogen, elixir-format
msgid "Open a project before importing a blogmark."
msgstr "Abre un proyecto antes de importar un blogmark."
@@ -3482,16 +3497,16 @@ msgid "Copy Bookmarklet to Clipboard"
msgstr "Copiar bookmarklet al portapapeles"
#: lib/bds/desktop/shell_live/overlay_manager.ex:300
#, elixir-autogen, elixir-format, fuzzy
#, elixir-autogen, elixir-format
msgid "Delete Tag"
msgstr "Eliminar"
msgstr "Eliminar etiqueta"
#: lib/bds/desktop/shell_live/settings_editor.ex:66
#, elixir-autogen, elixir-format
msgid "Failed to copy bookmarklet to clipboard"
msgstr "Error al copiar el bookmarklet al portapapeles"
#: lib/bds/desktop/shell_live.ex:813
#: lib/bds/desktop/shell_live.ex:822
#, elixir-autogen, elixir-format
msgid "The project this blogmark targets does not exist here."
msgstr "El proyecto al que apunta este blogmark no existe aquí."
@@ -3598,12 +3613,92 @@ msgstr "OK"
msgid "The endpoint returned no models. You can still type a model name manually."
msgstr "El endpoint no devolvió ningún modelo. Aún puedes escribir el nombre de un modelo manualmente."
#: lib/bds/tui.ex:28
#: lib/bds/tui.ex:538
#, elixir-autogen, elixir-format
msgid "Blogging Desktop Server"
msgstr "Blogging Desktop Server"
msgid "AI is unavailable in airplane mode without a local endpoint."
msgstr "La IA no está disponible en modo avión sin un punto de conexión local."
#: lib/bds/tui.ex:30
#: lib/bds/tui.ex:584
#, elixir-autogen, elixir-format
msgid "Press q to quit."
msgstr "Pulsa q para salir."
msgid "Could not load this file."
msgstr "No se pudo cargar este archivo."
#: lib/bds/tui.ex:111
#, elixir-autogen, elixir-format
msgid "Editing this item is not available in the terminal UI yet."
msgstr "La edición de este elemento aún no está disponible en la interfaz de terminal."
#: lib/bds/tui.ex:206
#, elixir-autogen, elixir-format
msgid "No suggestions returned."
msgstr "No se recibieron sugerencias."
#: lib/bds/tui.ex:581
#, elixir-autogen, elixir-format
msgid "Only images can be previewed."
msgstr "Solo se pueden previsualizar imágenes."
#: lib/bds/tui.ex:462
#, elixir-autogen, elixir-format
msgid "Post not found."
msgstr "Entrada no encontrada."
#: lib/bds/tui.ex:282
#, elixir-autogen, elixir-format
msgid "Press enter to preview %{name}."
msgstr "Pulsa Intro para previsualizar %{name}."
#: lib/bds/tui.ex:508
#, elixir-autogen, elixir-format
msgid "Published."
msgstr "Publicado."
#: lib/bds/tui.ex:524
#, elixir-autogen, elixir-format
msgid "Save before switching languages."
msgstr "Guarda antes de cambiar de idioma."
#: lib/bds/tui.ex:509
#, elixir-autogen, elixir-format
msgid "Saved."
msgstr "Guardado."
#: lib/bds/tui.ex:285
#, elixir-autogen, elixir-format
msgid "Select an entry and press enter to open it."
msgstr "Selecciona una entrada y pulsa Intro para abrirla."
#: lib/bds/tui.ex:203
#, elixir-autogen, elixir-format
msgid "Suggestions applied."
msgstr "Sugerencias aplicadas."
#: lib/bds/tui.ex:297
#, elixir-autogen, elixir-format
msgid "Title (ctrl+t to edit)"
msgstr "Título (ctrl+t para editar)"
#: lib/bds/tui.ex:296
#, elixir-autogen, elixir-format
msgid "Title (editing — enter to confirm)"
msgstr "Título (edición — Intro para confirmar)"
#: lib/bds/tui.ex:328
#, elixir-autogen, elixir-format
msgid "Working…"
msgstr "Procesando…"
#: lib/bds/tui.ex:364
#, elixir-autogen, elixir-format
msgid "ctrl+s save · ctrl+p publish · ctrl+t title · ctrl+l language · ctrl+g AI · esc back"
msgstr "ctrl+s guardar · ctrl+p publicar · ctrl+t título · ctrl+l idioma · ctrl+g IA · esc volver"
#: lib/bds/tui.ex:357
#, elixir-autogen, elixir-format
msgid "enter open · n new post · 1-5 views · r refresh · ctrl+q quit"
msgstr "intro abrir · n nueva entrada · 1-5 vistas · r actualizar · ctrl+q salir"
#: lib/bds/tui.ex:349
#, elixir-autogen, elixir-format
msgid "esc to close"
msgstr "esc para cerrar"

View File

@@ -10,7 +10,7 @@ msgstr "%{canonical} = %{translation}"
msgid "%{count} mapped"
msgstr "%{count} mappé(s)"
#: lib/bds/desktop/shell_data.ex:171
#: lib/bds/desktop/shell_data.ex:173
#, elixir-autogen, elixir-format
msgid "%{count} post"
msgid_plural "%{count} posts"
@@ -81,6 +81,11 @@ msgstr "Paramètres IA"
#: lib/bds/desktop/shell_live/overlay_manager.ex:72
#: lib/bds/desktop/shell_live/post_editor.ex:920
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:43
#: lib/bds/tui.ex:203
#: lib/bds/tui.ex:206
#: lib/bds/tui.ex:209
#: lib/bds/tui.ex:217
#: lib/bds/tui.ex:537
#, elixir-autogen, elixir-format
msgid "AI Suggestions"
msgstr "Suggestions IA"
@@ -301,7 +306,7 @@ msgstr "Archives de tags rendues"
msgid "Validation apply prepared"
msgstr "Application de la validation préparée"
#: lib/bds/desktop/shell_data.ex:164
#: lib/bds/desktop/shell_data.ex:166
#: lib/bds/ui/sidebar.ex:331
#, elixir-autogen, elixir-format
msgid "Archived"
@@ -336,7 +341,7 @@ msgstr "Auteur"
msgid "Auto"
msgstr "Automatique"
#: lib/bds/desktop/shell_live.ex:442
#: lib/bds/desktop/shell_live.ex:443
#: lib/bds/desktop/shell_live/chat_editor.ex:234
#: lib/bds/desktop/shell_live/media_editor.ex:171
#: lib/bds/desktop/shell_live/media_editor.ex:364
@@ -486,7 +491,7 @@ msgstr "Valeurs par défaut des catégories, options de rendu et liaison des mod
msgid "Category name is required"
msgstr "Le nom de la catégorie est requis"
#: lib/bds/desktop/shell_live.ex:780
#: lib/bds/desktop/shell_live.ex:789
#: lib/bds/desktop/shell_live/chat_editor.ex:87
#: lib/bds/desktop/shell_live/chat_editor.ex:233
#: lib/bds/desktop/shell_live/chat_editor.ex:323
@@ -584,6 +589,7 @@ msgstr "Confirmer"
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:375
#: lib/bds/desktop/shell_live/script_editor_html/script_editor.html.heex:34
#: lib/bds/desktop/shell_live/template_editor_html/template_editor.html.heex:32
#: lib/bds/tui.ex:308
#: lib/bds/ui/sidebar.ex:764
#, elixir-autogen, elixir-format
msgid "Content"
@@ -753,7 +759,7 @@ msgstr "Supprimer la traduction"
msgid "Delete conversation"
msgstr "Supprimer la conversation"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:65
#: lib/bds/ui/post_editor/persistence.ex:69
#, elixir-autogen, elixir-format
msgid "Delete this unpublished draft"
msgstr "Supprimer ce brouillon non publié"
@@ -810,17 +816,17 @@ msgstr "Désactiver la sortie de raisonnement pour le modèle de chat hors ligne
msgid "Disable reasoning output for the online chat model"
msgstr "Désactiver la sortie de raisonnement pour le modèle de chat en ligne"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:57
#: lib/bds/ui/post_editor/persistence.ex:61
#, elixir-autogen, elixir-format
msgid "Discard Changes"
msgstr "Annuler les modifications"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:58
#: lib/bds/ui/post_editor/persistence.ex:62
#, elixir-autogen, elixir-format
msgid "Discard Draft"
msgstr "Supprimer le brouillon"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:64
#: lib/bds/ui/post_editor/persistence.ex:68
#, elixir-autogen, elixir-format
msgid "Discard changes and restore the published version"
msgstr "Annuler les modifications et restaurer la version publiée"
@@ -863,7 +869,7 @@ msgstr "Ne pas traduire"
msgid "Documentation"
msgstr "Documentation"
#: lib/bds/desktop/shell_data.ex:162
#: lib/bds/desktop/shell_data.ex:164
#, elixir-autogen, elixir-format
msgid "Draft"
msgstr "Brouillon"
@@ -1063,7 +1069,7 @@ msgstr "Galerie"
msgid "Generate Site"
msgstr "Générer le site"
#: lib/bds/desktop/shell_live.ex:781
#: lib/bds/desktop/shell_live.ex:790
#: lib/bds/desktop/shell_live/socket_state.ex:109
#: lib/bds/ui/sidebar.ex:789
#, elixir-autogen, elixir-format
@@ -1076,8 +1082,8 @@ msgstr "Git"
msgid "Git Diff"
msgstr "Diff Git"
#: lib/bds/desktop/shell_data.ex:226
#: lib/bds/desktop/shell_live.ex:777
#: lib/bds/desktop/shell_data.ex:228
#: lib/bds/desktop/shell_live.ex:786
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
#, elixir-autogen, elixir-format
msgid "Git Log"
@@ -1103,7 +1109,7 @@ msgstr "Accueil"
msgid "Host"
msgstr "Hôte"
#: lib/bds/desktop/shell_data.ex:98
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_live/index.html.heex:657
#: lib/bds/desktop/shell_live/media_editor.ex:731
#: lib/bds/desktop/shell_live/post_editor.ex:1038
@@ -1200,9 +1206,9 @@ msgstr "Définitions dimport"
msgid "Import failed: %{error}"
msgstr "Échec de limport : %{error}"
#: lib/bds/desktop/shell_live.ex:605
#: lib/bds/desktop/shell_live.ex:893
#: lib/bds/desktop/shell_live.ex:899
#: lib/bds/desktop/shell_live.ex:606
#: lib/bds/desktop/shell_live.ex:902
#: lib/bds/desktop/shell_live.ex:908
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
#, elixir-autogen, elixir-format
msgid "Import media"
@@ -1337,7 +1343,7 @@ msgstr "Type MIME"
msgid "Macros (%{count})"
msgstr "Macros (%{count})"
#: lib/bds/desktop/shell_data.ex:101
#: lib/bds/desktop/shell_data.ex:103
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:55
#, elixir-autogen, elixir-format
msgid "Main Language"
@@ -1379,6 +1385,9 @@ msgstr "Nombre maximal darticles par page"
#: lib/bds/desktop/shell_live/misc_editor.ex:762
#: lib/bds/desktop/shell_live/sidebar_components.ex:654
#: lib/bds/desktop/shell_live/sidebar_delete.ex:175
#: lib/bds/tui.ex:452
#: lib/bds/tui.ex:581
#: lib/bds/tui.ex:584
#: lib/bds/ui/registry.ex:30
#: lib/bds/ui/registry.ex:100
#: lib/bds/ui/sidebar.ex:558
@@ -1431,7 +1440,7 @@ msgstr "Diff des métadonnées"
msgid "Missing URLs"
msgstr "URLs manquantes"
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_data.ex:102
#, elixir-autogen, elixir-format
msgid "Mode"
msgstr "Mode"
@@ -1466,6 +1475,7 @@ msgstr "Nouvelle page"
#: lib/bds/desktop/menu_bar.ex:185
#: lib/bds/desktop/shell_live/sidebar_create.ex:41
#: lib/bds/tui.ex:103
#, elixir-autogen, elixir-format
msgid "New Post"
msgstr "Nouvel article"
@@ -1644,7 +1654,7 @@ msgstr "Pas encore pris en charge dans la réécriture"
msgid "Nothing to Import"
msgstr "Rien à importer"
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_data.ex:102
#: lib/bds/desktop/shell_live/index.html.heex:503
#, elixir-autogen, elixir-format
msgid "Offline"
@@ -1784,7 +1794,7 @@ msgstr "Autre"
msgid "Other (%{count})"
msgstr "Autres (%{count})"
#: lib/bds/desktop/shell_live.ex:776
#: lib/bds/desktop/shell_live.ex:785
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
#, elixir-autogen, elixir-format
msgid "Output"
@@ -1866,7 +1876,7 @@ msgstr "Enregistrer la langue détectée pour ce média"
msgid "Post"
msgstr "Article"
#: lib/bds/desktop/shell_data.ex:229
#: lib/bds/desktop/shell_data.ex:231
#: lib/bds/desktop/shell_live/panel_renderer.ex:118
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:310
#, elixir-autogen, elixir-format
@@ -1901,6 +1911,8 @@ msgstr "Article enregistré"
#: lib/bds/desktop/menu_bar.ex:202
#: lib/bds/desktop/shell_live/misc_editor.ex:664
#: lib/bds/desktop/shell_live/misc_editor.ex:761
#: lib/bds/tui.ex:451
#: lib/bds/tui.ex:462
#: lib/bds/ui/registry.ex:14
#: lib/bds/ui/sidebar.ex:271
#, elixir-autogen, elixir-format
@@ -1985,7 +1997,7 @@ msgstr "Publier"
msgid "Publish Selected"
msgstr "Publier la sélection"
#: lib/bds/desktop/shell_data.ex:163
#: lib/bds/desktop/shell_data.ex:165
#: lib/bds/desktop/shell_live/post_editor.ex:1036
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:472
#: lib/bds/ui/sidebar.ex:324
@@ -2282,6 +2294,7 @@ msgstr "Les capacités de script sont configurées au niveau de lapplication
#: lib/bds/desktop/shell_live/script_editor.ex:216
#: lib/bds/desktop/shell_live/script_editor.ex:219
#: lib/bds/desktop/shell_live/script_editor.ex:234
#: lib/bds/tui.ex:454
#: lib/bds/ui/registry.ex:38
#: lib/bds/ui/sidebar.ex:63
#: lib/bds/ui/sidebar.ex:115
@@ -2456,7 +2469,7 @@ msgstr "Démarrer la conversation"
msgid "Starting..."
msgstr "Démarrage..."
#: lib/bds/desktop/shell_data.ex:97
#: lib/bds/desktop/shell_data.ex:99
#: lib/bds/desktop/shell_live/import_editor.ex:1182
#: lib/bds/desktop/shell_live/import_editor.ex:1233
#, elixir-autogen, elixir-format
@@ -2529,6 +2542,7 @@ msgstr "Nom du mot-clé"
#: lib/bds/desktop/shell_live/tags_editor.ex:222
#: lib/bds/desktop/shell_live/tags_editor.ex:253
#: lib/bds/desktop/shell_live/tags_editor_html/tags_editor.html.heex:11
#: lib/bds/tui.ex:455
#: lib/bds/ui/registry.ex:54
#: lib/bds/ui/registry.ex:103
#: lib/bds/ui/sidebar.ex:289
@@ -2538,7 +2552,7 @@ msgstr "Nom du mot-clé"
msgid "Tags"
msgstr "Tags"
#: lib/bds/desktop/shell_live.ex:775
#: lib/bds/desktop/shell_live.ex:784
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
#, elixir-autogen, elixir-format
msgid "Tasks"
@@ -2584,6 +2598,7 @@ msgstr "La syntaxe du template est valide"
#: lib/bds/desktop/shell_live/template_editor.ex:171
#: lib/bds/desktop/shell_live/template_editor.ex:176
#: lib/bds/desktop/shell_live/template_editor.ex:191
#: lib/bds/tui.ex:453
#: lib/bds/ui/registry.ex:46
#: lib/bds/ui/sidebar.ex:71
#: lib/bds/ui/sidebar.ex:122
@@ -2780,7 +2795,7 @@ msgid "Unsaved"
msgstr "Non enregistré"
#: lib/bds/desktop/shell_live/import_editor.ex:871
#: lib/bds/desktop/shell_live/post_editor/post_metadata.ex:166
#: lib/bds/ui/post_editor/metadata.ex:166
#: lib/bds/ui/sidebar.ex:1108
#, elixir-autogen, elixir-format
msgid "Untitled"
@@ -3161,9 +3176,9 @@ msgid "I can help you manage your blog with rich visualizations. Try asking me t
msgstr "Je peux vous aider à gérer votre blog avec des visualisations riches. Essayez par exemple :"
#: lib/bds/desktop/shell_live/index.html.heex:289
#, elixir-autogen, elixir-format, fuzzy
#, elixir-autogen, elixir-format
msgid "Media Files"
msgstr "Médias"
msgstr "Fichiers multimédias"
#: lib/bds/desktop/shell_live/chat_editor_html/chat_editor.html.heex:21
#, elixir-autogen, elixir-format
@@ -3218,12 +3233,12 @@ msgstr "Bienvenue dans lassistant IA"
msgid "Comparing database and filesystem metadata"
msgstr "Comparaison des métadonnées entre la base et le système de fichiers"
#: lib/bds/desktop/shell_live.ex:681
#: lib/bds/desktop/shell_live.ex:682
#, elixir-autogen, elixir-format
msgid "Added %{count} images to post"
msgstr "%{count} images ajoutées à l'article"
#: lib/bds/desktop/shell_live.ex:649
#: lib/bds/desktop/shell_live.ex:650
#, elixir-autogen, elixir-format
msgid "Added %{title}"
msgstr "%{title} ajouté"
@@ -3243,18 +3258,18 @@ msgstr "Guide utilisateur pour les flux éditoriaux, médias, modèles, traducti
msgid "Image Import Concurrency"
msgstr "Importation simultanée d'images"
#: lib/bds/desktop/shell_live.ex:441
#: lib/bds/desktop/shell_live.ex:454
#: lib/bds/desktop/shell_live.ex:648
#: lib/bds/desktop/shell_live.ex:680
#: lib/bds/desktop/shell_live.ex:691
#: lib/bds/desktop/shell_live.ex:702
#: lib/bds/desktop/shell_live.ex:442
#: lib/bds/desktop/shell_live.ex:455
#: lib/bds/desktop/shell_live.ex:649
#: lib/bds/desktop/shell_live.ex:681
#: lib/bds/desktop/shell_live.ex:692
#: lib/bds/desktop/shell_live.ex:703
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
#, elixir-autogen, elixir-format
msgid "Add Gallery Images"
msgstr "Ajouter des images à la galerie"
#: lib/bds/desktop/shell_live.ex:703
#: lib/bds/desktop/shell_live.ex:704
#, elixir-autogen, elixir-format
msgid "Failed to process %{path}: %{reason}"
msgstr "Impossible de traiter %{path} : %{reason}"
@@ -3445,12 +3460,12 @@ msgstr "renommé"
msgid "untracked"
msgstr "non suivi"
#: lib/bds/desktop/shell_live.ex:801
#: lib/bds/desktop/shell_live.ex:810
#, elixir-autogen, elixir-format
msgid "Blogmark"
msgstr "Blogmark"
#: lib/bds/desktop/shell_live.ex:844
#: lib/bds/desktop/shell_live.ex:853
#, elixir-autogen, elixir-format
msgid "Open a project before importing a blogmark."
msgstr "Ouvrez un projet avant dimporter un blogmark."
@@ -3482,16 +3497,16 @@ msgid "Copy Bookmarklet to Clipboard"
msgstr "Copier le bookmarklet dans le presse-papiers"
#: lib/bds/desktop/shell_live/overlay_manager.ex:300
#, elixir-autogen, elixir-format, fuzzy
#, elixir-autogen, elixir-format
msgid "Delete Tag"
msgstr "Supprimer"
msgstr "Supprimer le tag"
#: lib/bds/desktop/shell_live/settings_editor.ex:66
#, elixir-autogen, elixir-format
msgid "Failed to copy bookmarklet to clipboard"
msgstr "Échec de la copie du bookmarklet dans le presse-papiers"
#: lib/bds/desktop/shell_live.ex:813
#: lib/bds/desktop/shell_live.ex:822
#, elixir-autogen, elixir-format
msgid "The project this blogmark targets does not exist here."
msgstr "Le projet ciblé par ce blogmark n'existe pas ici."
@@ -3598,12 +3613,92 @@ msgstr "OK"
msgid "The endpoint returned no models. You can still type a model name manually."
msgstr "Le point de terminaison n'a renvoyé aucun modèle. Vous pouvez toujours saisir un nom de modèle manuellement."
#: lib/bds/tui.ex:28
#: lib/bds/tui.ex:538
#, elixir-autogen, elixir-format
msgid "Blogging Desktop Server"
msgstr "Blogging Desktop Server"
msgid "AI is unavailable in airplane mode without a local endpoint."
msgstr "L'IA n'est pas disponible en mode avion sans point de terminaison local."
#: lib/bds/tui.ex:30
#: lib/bds/tui.ex:584
#, elixir-autogen, elixir-format
msgid "Press q to quit."
msgstr "Appuyez sur q pour quitter."
msgid "Could not load this file."
msgstr "Impossible de charger ce fichier."
#: lib/bds/tui.ex:111
#, elixir-autogen, elixir-format
msgid "Editing this item is not available in the terminal UI yet."
msgstr "La modification de cet élément n'est pas encore disponible dans l'interface du terminal."
#: lib/bds/tui.ex:206
#, elixir-autogen, elixir-format
msgid "No suggestions returned."
msgstr "Aucune suggestion reçue."
#: lib/bds/tui.ex:581
#, elixir-autogen, elixir-format
msgid "Only images can be previewed."
msgstr "Seules les images peuvent être prévisualisées."
#: lib/bds/tui.ex:462
#, elixir-autogen, elixir-format
msgid "Post not found."
msgstr "Article introuvable."
#: lib/bds/tui.ex:282
#, elixir-autogen, elixir-format
msgid "Press enter to preview %{name}."
msgstr "Appuyez sur Entrée pour prévisualiser %{name}."
#: lib/bds/tui.ex:508
#, elixir-autogen, elixir-format
msgid "Published."
msgstr "Publié."
#: lib/bds/tui.ex:524
#, elixir-autogen, elixir-format
msgid "Save before switching languages."
msgstr "Enregistrez avant de changer de langue."
#: lib/bds/tui.ex:509
#, elixir-autogen, elixir-format
msgid "Saved."
msgstr "Enregistré."
#: lib/bds/tui.ex:285
#, elixir-autogen, elixir-format
msgid "Select an entry and press enter to open it."
msgstr "Sélectionnez une entrée et appuyez sur Entrée pour l'ouvrir."
#: lib/bds/tui.ex:203
#, elixir-autogen, elixir-format
msgid "Suggestions applied."
msgstr "Suggestions appliquées."
#: lib/bds/tui.ex:297
#, elixir-autogen, elixir-format
msgid "Title (ctrl+t to edit)"
msgstr "Titre (ctrl+t pour modifier)"
#: lib/bds/tui.ex:296
#, elixir-autogen, elixir-format
msgid "Title (editing — enter to confirm)"
msgstr "Titre (édition — Entrée pour confirmer)"
#: lib/bds/tui.ex:328
#, elixir-autogen, elixir-format
msgid "Working…"
msgstr "Traitement en cours…"
#: lib/bds/tui.ex:364
#, elixir-autogen, elixir-format
msgid "ctrl+s save · ctrl+p publish · ctrl+t title · ctrl+l language · ctrl+g AI · esc back"
msgstr "ctrl+s enregistrer · ctrl+p publier · ctrl+t titre · ctrl+l langue · ctrl+g IA · échap retour"
#: lib/bds/tui.ex:357
#, elixir-autogen, elixir-format
msgid "enter open · n new post · 1-5 views · r refresh · ctrl+q quit"
msgstr "entrée ouvrir · n nouvel article · 1-5 vues · r actualiser · ctrl+q quitter"
#: lib/bds/tui.ex:349
#, elixir-autogen, elixir-format
msgid "esc to close"
msgstr "échap pour fermer"

View File

@@ -10,7 +10,7 @@ msgstr "%{canonical} = %{translation}"
msgid "%{count} mapped"
msgstr "%{count} mappati"
#: lib/bds/desktop/shell_data.ex:171
#: lib/bds/desktop/shell_data.ex:173
#, elixir-autogen, elixir-format
msgid "%{count} post"
msgid_plural "%{count} posts"
@@ -81,6 +81,11 @@ msgstr "Impostazioni IA"
#: lib/bds/desktop/shell_live/overlay_manager.ex:72
#: lib/bds/desktop/shell_live/post_editor.ex:920
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:43
#: lib/bds/tui.ex:203
#: lib/bds/tui.ex:206
#: lib/bds/tui.ex:209
#: lib/bds/tui.ex:217
#: lib/bds/tui.ex:537
#, elixir-autogen, elixir-format
msgid "AI Suggestions"
msgstr "Suggerimenti IA"
@@ -301,7 +306,7 @@ msgstr "Archivi tag renderizzati"
msgid "Validation apply prepared"
msgstr "Applicazione della validazione preparata"
#: lib/bds/desktop/shell_data.ex:164
#: lib/bds/desktop/shell_data.ex:166
#: lib/bds/ui/sidebar.ex:331
#, elixir-autogen, elixir-format
msgid "Archived"
@@ -336,7 +341,7 @@ msgstr "Autore"
msgid "Auto"
msgstr "Automatico"
#: lib/bds/desktop/shell_live.ex:442
#: lib/bds/desktop/shell_live.ex:443
#: lib/bds/desktop/shell_live/chat_editor.ex:234
#: lib/bds/desktop/shell_live/media_editor.ex:171
#: lib/bds/desktop/shell_live/media_editor.ex:364
@@ -486,7 +491,7 @@ msgstr "Valori predefiniti delle categorie, opzioni di rendering e collegamento
msgid "Category name is required"
msgstr "Il nome della categoria è obbligatorio"
#: lib/bds/desktop/shell_live.ex:780
#: lib/bds/desktop/shell_live.ex:789
#: lib/bds/desktop/shell_live/chat_editor.ex:87
#: lib/bds/desktop/shell_live/chat_editor.ex:233
#: lib/bds/desktop/shell_live/chat_editor.ex:323
@@ -584,6 +589,7 @@ msgstr "Conferma"
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:375
#: lib/bds/desktop/shell_live/script_editor_html/script_editor.html.heex:34
#: lib/bds/desktop/shell_live/template_editor_html/template_editor.html.heex:32
#: lib/bds/tui.ex:308
#: lib/bds/ui/sidebar.ex:764
#, elixir-autogen, elixir-format
msgid "Content"
@@ -753,7 +759,7 @@ msgstr "Elimina traduzione"
msgid "Delete conversation"
msgstr "Elimina conversazione"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:65
#: lib/bds/ui/post_editor/persistence.ex:69
#, elixir-autogen, elixir-format
msgid "Delete this unpublished draft"
msgstr "Elimina questa bozza non pubblicata"
@@ -810,17 +816,17 @@ msgstr "Disattiva l'output di ragionamento per il modello di chat offline"
msgid "Disable reasoning output for the online chat model"
msgstr "Disattiva l'output di ragionamento per il modello di chat online"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:57
#: lib/bds/ui/post_editor/persistence.ex:61
#, elixir-autogen, elixir-format
msgid "Discard Changes"
msgstr "Annulla le modifiche"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:58
#: lib/bds/ui/post_editor/persistence.ex:62
#, elixir-autogen, elixir-format
msgid "Discard Draft"
msgstr "Elimina bozza"
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:64
#: lib/bds/ui/post_editor/persistence.ex:68
#, elixir-autogen, elixir-format
msgid "Discard changes and restore the published version"
msgstr "Annulla le modifiche e ripristina la versione pubblicata"
@@ -863,7 +869,7 @@ msgstr "Non tradurre"
msgid "Documentation"
msgstr "Documentazione"
#: lib/bds/desktop/shell_data.ex:162
#: lib/bds/desktop/shell_data.ex:164
#, elixir-autogen, elixir-format
msgid "Draft"
msgstr "Bozza"
@@ -1063,7 +1069,7 @@ msgstr "Galleria"
msgid "Generate Site"
msgstr "Genera sito"
#: lib/bds/desktop/shell_live.ex:781
#: lib/bds/desktop/shell_live.ex:790
#: lib/bds/desktop/shell_live/socket_state.ex:109
#: lib/bds/ui/sidebar.ex:789
#, elixir-autogen, elixir-format
@@ -1076,8 +1082,8 @@ msgstr "Git"
msgid "Git Diff"
msgstr "Diff Git"
#: lib/bds/desktop/shell_data.ex:226
#: lib/bds/desktop/shell_live.ex:777
#: lib/bds/desktop/shell_data.ex:228
#: lib/bds/desktop/shell_live.ex:786
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
#, elixir-autogen, elixir-format
msgid "Git Log"
@@ -1103,7 +1109,7 @@ msgstr "Home"
msgid "Host"
msgstr "Host"
#: lib/bds/desktop/shell_data.ex:98
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_live/index.html.heex:657
#: lib/bds/desktop/shell_live/media_editor.ex:731
#: lib/bds/desktop/shell_live/post_editor.ex:1038
@@ -1200,9 +1206,9 @@ msgstr "Definizioni di importazione"
msgid "Import failed: %{error}"
msgstr "Importazione non riuscita: %{error}"
#: lib/bds/desktop/shell_live.ex:605
#: lib/bds/desktop/shell_live.ex:893
#: lib/bds/desktop/shell_live.ex:899
#: lib/bds/desktop/shell_live.ex:606
#: lib/bds/desktop/shell_live.ex:902
#: lib/bds/desktop/shell_live.ex:908
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
#, elixir-autogen, elixir-format
msgid "Import media"
@@ -1337,7 +1343,7 @@ msgstr "Tipo MIME"
msgid "Macros (%{count})"
msgstr "Macro (%{count})"
#: lib/bds/desktop/shell_data.ex:101
#: lib/bds/desktop/shell_data.ex:103
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:55
#, elixir-autogen, elixir-format
msgid "Main Language"
@@ -1379,6 +1385,9 @@ msgstr "Numero massimo di post per pagina"
#: lib/bds/desktop/shell_live/misc_editor.ex:762
#: lib/bds/desktop/shell_live/sidebar_components.ex:654
#: lib/bds/desktop/shell_live/sidebar_delete.ex:175
#: lib/bds/tui.ex:452
#: lib/bds/tui.ex:581
#: lib/bds/tui.ex:584
#: lib/bds/ui/registry.ex:30
#: lib/bds/ui/registry.ex:100
#: lib/bds/ui/sidebar.ex:558
@@ -1431,7 +1440,7 @@ msgstr "Diff metadati"
msgid "Missing URLs"
msgstr "URL mancanti"
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_data.ex:102
#, elixir-autogen, elixir-format
msgid "Mode"
msgstr "Modalità"
@@ -1466,6 +1475,7 @@ msgstr "Nuova pagina"
#: lib/bds/desktop/menu_bar.ex:185
#: lib/bds/desktop/shell_live/sidebar_create.ex:41
#: lib/bds/tui.ex:103
#, elixir-autogen, elixir-format
msgid "New Post"
msgstr "Nuovo post"
@@ -1644,7 +1654,7 @@ msgstr "Non ancora supportato nella riscrittura"
msgid "Nothing to Import"
msgstr "Niente da importare"
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_data.ex:102
#: lib/bds/desktop/shell_live/index.html.heex:503
#, elixir-autogen, elixir-format
msgid "Offline"
@@ -1784,7 +1794,7 @@ msgstr "Altro"
msgid "Other (%{count})"
msgstr "Altro (%{count})"
#: lib/bds/desktop/shell_live.ex:776
#: lib/bds/desktop/shell_live.ex:785
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
#, elixir-autogen, elixir-format
msgid "Output"
@@ -1866,7 +1876,7 @@ msgstr "Salva la lingua rilevata per questo media"
msgid "Post"
msgstr "Post"
#: lib/bds/desktop/shell_data.ex:229
#: lib/bds/desktop/shell_data.ex:231
#: lib/bds/desktop/shell_live/panel_renderer.ex:118
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:310
#, elixir-autogen, elixir-format
@@ -1901,6 +1911,8 @@ msgstr "Articolo salvato"
#: lib/bds/desktop/menu_bar.ex:202
#: lib/bds/desktop/shell_live/misc_editor.ex:664
#: lib/bds/desktop/shell_live/misc_editor.ex:761
#: lib/bds/tui.ex:451
#: lib/bds/tui.ex:462
#: lib/bds/ui/registry.ex:14
#: lib/bds/ui/sidebar.ex:271
#, elixir-autogen, elixir-format
@@ -1985,7 +1997,7 @@ msgstr "Pubblica"
msgid "Publish Selected"
msgstr "Pubblica selezionati"
#: lib/bds/desktop/shell_data.ex:163
#: lib/bds/desktop/shell_data.ex:165
#: lib/bds/desktop/shell_live/post_editor.ex:1036
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:472
#: lib/bds/ui/sidebar.ex:324
@@ -2282,6 +2294,7 @@ msgstr "Le capacità di scripting sono configurate a livello applicativo nella r
#: lib/bds/desktop/shell_live/script_editor.ex:216
#: lib/bds/desktop/shell_live/script_editor.ex:219
#: lib/bds/desktop/shell_live/script_editor.ex:234
#: lib/bds/tui.ex:454
#: lib/bds/ui/registry.ex:38
#: lib/bds/ui/sidebar.ex:63
#: lib/bds/ui/sidebar.ex:115
@@ -2456,7 +2469,7 @@ msgstr "Avvia chat"
msgid "Starting..."
msgstr "Avvio..."
#: lib/bds/desktop/shell_data.ex:97
#: lib/bds/desktop/shell_data.ex:99
#: lib/bds/desktop/shell_live/import_editor.ex:1182
#: lib/bds/desktop/shell_live/import_editor.ex:1233
#, elixir-autogen, elixir-format
@@ -2529,6 +2542,7 @@ msgstr "Nome del tag"
#: lib/bds/desktop/shell_live/tags_editor.ex:222
#: lib/bds/desktop/shell_live/tags_editor.ex:253
#: lib/bds/desktop/shell_live/tags_editor_html/tags_editor.html.heex:11
#: lib/bds/tui.ex:455
#: lib/bds/ui/registry.ex:54
#: lib/bds/ui/registry.ex:103
#: lib/bds/ui/sidebar.ex:289
@@ -2538,7 +2552,7 @@ msgstr "Nome del tag"
msgid "Tags"
msgstr "Tag"
#: lib/bds/desktop/shell_live.ex:775
#: lib/bds/desktop/shell_live.ex:784
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
#, elixir-autogen, elixir-format
msgid "Tasks"
@@ -2584,6 +2598,7 @@ msgstr "La sintassi del template è valida"
#: lib/bds/desktop/shell_live/template_editor.ex:171
#: lib/bds/desktop/shell_live/template_editor.ex:176
#: lib/bds/desktop/shell_live/template_editor.ex:191
#: lib/bds/tui.ex:453
#: lib/bds/ui/registry.ex:46
#: lib/bds/ui/sidebar.ex:71
#: lib/bds/ui/sidebar.ex:122
@@ -2780,7 +2795,7 @@ msgid "Unsaved"
msgstr "Non salvato"
#: lib/bds/desktop/shell_live/import_editor.ex:871
#: lib/bds/desktop/shell_live/post_editor/post_metadata.ex:166
#: lib/bds/ui/post_editor/metadata.ex:166
#: lib/bds/ui/sidebar.ex:1108
#, elixir-autogen, elixir-format
msgid "Untitled"
@@ -3161,9 +3176,9 @@ msgid "I can help you manage your blog with rich visualizations. Try asking me t
msgstr "Posso aiutarti a gestire il tuo blog con visualizzazioni interattive. Prova a chiedermi di:"
#: lib/bds/desktop/shell_live/index.html.heex:289
#, elixir-autogen, elixir-format, fuzzy
#, elixir-autogen, elixir-format
msgid "Media Files"
msgstr "Media"
msgstr "File multimediali"
#: lib/bds/desktop/shell_live/chat_editor_html/chat_editor.html.heex:21
#, elixir-autogen, elixir-format
@@ -3218,12 +3233,12 @@ msgstr "Benvenuto nellassistente IA"
msgid "Comparing database and filesystem metadata"
msgstr "Confronto tra i metadati del database e del filesystem"
#: lib/bds/desktop/shell_live.ex:681
#: lib/bds/desktop/shell_live.ex:682
#, elixir-autogen, elixir-format
msgid "Added %{count} images to post"
msgstr "%{count} immagini aggiunte al post"
#: lib/bds/desktop/shell_live.ex:649
#: lib/bds/desktop/shell_live.ex:650
#, elixir-autogen, elixir-format
msgid "Added %{title}"
msgstr "%{title} aggiunto"
@@ -3243,18 +3258,18 @@ msgstr "Guida per l'utente finale per flussi editoriali, media, modelli, traduzi
msgid "Image Import Concurrency"
msgstr "Importazione simultanea immagini"
#: lib/bds/desktop/shell_live.ex:441
#: lib/bds/desktop/shell_live.ex:454
#: lib/bds/desktop/shell_live.ex:648
#: lib/bds/desktop/shell_live.ex:680
#: lib/bds/desktop/shell_live.ex:691
#: lib/bds/desktop/shell_live.ex:702
#: lib/bds/desktop/shell_live.ex:442
#: lib/bds/desktop/shell_live.ex:455
#: lib/bds/desktop/shell_live.ex:649
#: lib/bds/desktop/shell_live.ex:681
#: lib/bds/desktop/shell_live.ex:692
#: lib/bds/desktop/shell_live.ex:703
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
#, elixir-autogen, elixir-format
msgid "Add Gallery Images"
msgstr "Aggiungi immagini alla galleria"
#: lib/bds/desktop/shell_live.ex:703
#: lib/bds/desktop/shell_live.ex:704
#, elixir-autogen, elixir-format
msgid "Failed to process %{path}: %{reason}"
msgstr "Impossibile elaborare %{path}: %{reason}"
@@ -3445,12 +3460,12 @@ msgstr "rinominato"
msgid "untracked"
msgstr "non tracciato"
#: lib/bds/desktop/shell_live.ex:801
#: lib/bds/desktop/shell_live.ex:810
#, elixir-autogen, elixir-format
msgid "Blogmark"
msgstr "Blogmark"
#: lib/bds/desktop/shell_live.ex:844
#: lib/bds/desktop/shell_live.ex:853
#, elixir-autogen, elixir-format
msgid "Open a project before importing a blogmark."
msgstr "Apri un progetto prima di importare un blogmark."
@@ -3482,16 +3497,16 @@ msgid "Copy Bookmarklet to Clipboard"
msgstr "Copia bookmarklet negli appunti"
#: lib/bds/desktop/shell_live/overlay_manager.ex:300
#, elixir-autogen, elixir-format, fuzzy
#, elixir-autogen, elixir-format
msgid "Delete Tag"
msgstr "Elimina"
msgstr "Elimina tag"
#: lib/bds/desktop/shell_live/settings_editor.ex:66
#, elixir-autogen, elixir-format
msgid "Failed to copy bookmarklet to clipboard"
msgstr "Impossibile copiare il bookmarklet negli appunti"
#: lib/bds/desktop/shell_live.ex:813
#: lib/bds/desktop/shell_live.ex:822
#, elixir-autogen, elixir-format
msgid "The project this blogmark targets does not exist here."
msgstr "Il progetto a cui punta questo blogmark non esiste qui."
@@ -3598,12 +3613,92 @@ msgstr "OK"
msgid "The endpoint returned no models. You can still type a model name manually."
msgstr "L'endpoint non ha restituito alcun modello. Puoi comunque digitare manualmente il nome di un modello."
#: lib/bds/tui.ex:28
#: lib/bds/tui.ex:538
#, elixir-autogen, elixir-format
msgid "Blogging Desktop Server"
msgstr "Blogging Desktop Server"
msgid "AI is unavailable in airplane mode without a local endpoint."
msgstr "L'IA non è disponibile in modalità aereo senza un endpoint locale."
#: lib/bds/tui.ex:30
#: lib/bds/tui.ex:584
#, elixir-autogen, elixir-format
msgid "Press q to quit."
msgstr "Premi q per uscire."
msgid "Could not load this file."
msgstr "Impossibile caricare questo file."
#: lib/bds/tui.ex:111
#, elixir-autogen, elixir-format
msgid "Editing this item is not available in the terminal UI yet."
msgstr "La modifica di questo elemento non è ancora disponibile nell'interfaccia del terminale."
#: lib/bds/tui.ex:206
#, elixir-autogen, elixir-format
msgid "No suggestions returned."
msgstr "Nessun suggerimento ricevuto."
#: lib/bds/tui.ex:581
#, elixir-autogen, elixir-format
msgid "Only images can be previewed."
msgstr "Solo le immagini possono essere visualizzate in anteprima."
#: lib/bds/tui.ex:462
#, elixir-autogen, elixir-format
msgid "Post not found."
msgstr "Post non trovato."
#: lib/bds/tui.ex:282
#, elixir-autogen, elixir-format
msgid "Press enter to preview %{name}."
msgstr "Premi Invio per l'anteprima di %{name}."
#: lib/bds/tui.ex:508
#, elixir-autogen, elixir-format
msgid "Published."
msgstr "Pubblicato."
#: lib/bds/tui.ex:524
#, elixir-autogen, elixir-format
msgid "Save before switching languages."
msgstr "Salva prima di cambiare lingua."
#: lib/bds/tui.ex:509
#, elixir-autogen, elixir-format
msgid "Saved."
msgstr "Salvato."
#: lib/bds/tui.ex:285
#, elixir-autogen, elixir-format
msgid "Select an entry and press enter to open it."
msgstr "Seleziona una voce e premi Invio per aprirla."
#: lib/bds/tui.ex:203
#, elixir-autogen, elixir-format
msgid "Suggestions applied."
msgstr "Suggerimenti applicati."
#: lib/bds/tui.ex:297
#, elixir-autogen, elixir-format
msgid "Title (ctrl+t to edit)"
msgstr "Titolo (ctrl+t per modificare)"
#: lib/bds/tui.ex:296
#, elixir-autogen, elixir-format
msgid "Title (editing — enter to confirm)"
msgstr "Titolo (modifica — Invio per confermare)"
#: lib/bds/tui.ex:328
#, elixir-autogen, elixir-format
msgid "Working…"
msgstr "Elaborazione…"
#: lib/bds/tui.ex:364
#, elixir-autogen, elixir-format
msgid "ctrl+s save · ctrl+p publish · ctrl+t title · ctrl+l language · ctrl+g AI · esc back"
msgstr "ctrl+s salva · ctrl+p pubblica · ctrl+t titolo · ctrl+l lingua · ctrl+g IA · esc indietro"
#: lib/bds/tui.ex:357
#, elixir-autogen, elixir-format
msgid "enter open · n new post · 1-5 views · r refresh · ctrl+q quit"
msgstr "invio apri · n nuovo post · 1-5 viste · r aggiorna · ctrl+q esci"
#: lib/bds/tui.ex:349
#, elixir-autogen, elixir-format
msgid "esc to close"
msgstr "esc per chiudere"

View File

@@ -23,7 +23,7 @@ msgstr ""
msgid "%{count} mapped"
msgstr ""
#: lib/bds/desktop/shell_data.ex:171
#: lib/bds/desktop/shell_data.ex:173
#, elixir-autogen, elixir-format
msgid "%{count} post"
msgid_plural "%{count} posts"
@@ -94,6 +94,11 @@ msgstr ""
#: lib/bds/desktop/shell_live/overlay_manager.ex:72
#: lib/bds/desktop/shell_live/post_editor.ex:920
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:43
#: lib/bds/tui.ex:203
#: lib/bds/tui.ex:206
#: lib/bds/tui.ex:209
#: lib/bds/tui.ex:217
#: lib/bds/tui.ex:537
#, elixir-autogen, elixir-format
msgid "AI Suggestions"
msgstr ""
@@ -314,7 +319,7 @@ msgstr ""
msgid "Validation apply prepared"
msgstr ""
#: lib/bds/desktop/shell_data.ex:164
#: lib/bds/desktop/shell_data.ex:166
#: lib/bds/ui/sidebar.ex:331
#, elixir-autogen, elixir-format
msgid "Archived"
@@ -349,7 +354,7 @@ msgstr ""
msgid "Auto"
msgstr ""
#: lib/bds/desktop/shell_live.ex:442
#: lib/bds/desktop/shell_live.ex:443
#: lib/bds/desktop/shell_live/chat_editor.ex:234
#: lib/bds/desktop/shell_live/media_editor.ex:171
#: lib/bds/desktop/shell_live/media_editor.ex:364
@@ -499,7 +504,7 @@ msgstr ""
msgid "Category name is required"
msgstr ""
#: lib/bds/desktop/shell_live.ex:780
#: lib/bds/desktop/shell_live.ex:789
#: lib/bds/desktop/shell_live/chat_editor.ex:87
#: lib/bds/desktop/shell_live/chat_editor.ex:233
#: lib/bds/desktop/shell_live/chat_editor.ex:323
@@ -597,6 +602,7 @@ msgstr ""
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:375
#: lib/bds/desktop/shell_live/script_editor_html/script_editor.html.heex:34
#: lib/bds/desktop/shell_live/template_editor_html/template_editor.html.heex:32
#: lib/bds/tui.ex:308
#: lib/bds/ui/sidebar.ex:764
#, elixir-autogen, elixir-format
msgid "Content"
@@ -766,7 +772,7 @@ msgstr ""
msgid "Delete conversation"
msgstr ""
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:65
#: lib/bds/ui/post_editor/persistence.ex:69
#, elixir-autogen, elixir-format
msgid "Delete this unpublished draft"
msgstr ""
@@ -823,17 +829,17 @@ msgstr ""
msgid "Disable reasoning output for the online chat model"
msgstr ""
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:57
#: lib/bds/ui/post_editor/persistence.ex:61
#, elixir-autogen, elixir-format
msgid "Discard Changes"
msgstr ""
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:58
#: lib/bds/ui/post_editor/persistence.ex:62
#, elixir-autogen, elixir-format
msgid "Discard Draft"
msgstr ""
#: lib/bds/desktop/shell_live/post_editor/persistence.ex:64
#: lib/bds/ui/post_editor/persistence.ex:68
#, elixir-autogen, elixir-format
msgid "Discard changes and restore the published version"
msgstr ""
@@ -876,7 +882,7 @@ msgstr ""
msgid "Documentation"
msgstr ""
#: lib/bds/desktop/shell_data.ex:162
#: lib/bds/desktop/shell_data.ex:164
#, elixir-autogen, elixir-format
msgid "Draft"
msgstr ""
@@ -1076,7 +1082,7 @@ msgstr ""
msgid "Generate Site"
msgstr ""
#: lib/bds/desktop/shell_live.ex:781
#: lib/bds/desktop/shell_live.ex:790
#: lib/bds/desktop/shell_live/socket_state.ex:109
#: lib/bds/ui/sidebar.ex:789
#, elixir-autogen, elixir-format
@@ -1089,8 +1095,8 @@ msgstr ""
msgid "Git Diff"
msgstr ""
#: lib/bds/desktop/shell_data.ex:226
#: lib/bds/desktop/shell_live.ex:777
#: lib/bds/desktop/shell_data.ex:228
#: lib/bds/desktop/shell_live.ex:786
#: lib/bds/desktop/shell_live/panel_renderer.ex:171
#, elixir-autogen, elixir-format
msgid "Git Log"
@@ -1116,7 +1122,7 @@ msgstr ""
msgid "Host"
msgstr ""
#: lib/bds/desktop/shell_data.ex:98
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_live/index.html.heex:657
#: lib/bds/desktop/shell_live/media_editor.ex:731
#: lib/bds/desktop/shell_live/post_editor.ex:1038
@@ -1213,9 +1219,9 @@ msgstr ""
msgid "Import failed: %{error}"
msgstr ""
#: lib/bds/desktop/shell_live.ex:605
#: lib/bds/desktop/shell_live.ex:893
#: lib/bds/desktop/shell_live.ex:899
#: lib/bds/desktop/shell_live.ex:606
#: lib/bds/desktop/shell_live.ex:902
#: lib/bds/desktop/shell_live.ex:908
#: lib/bds/desktop/shell_live/sidebar_create.ex:47
#, elixir-autogen, elixir-format
msgid "Import media"
@@ -1350,7 +1356,7 @@ msgstr ""
msgid "Macros (%{count})"
msgstr ""
#: lib/bds/desktop/shell_data.ex:101
#: lib/bds/desktop/shell_data.ex:103
#: lib/bds/desktop/shell_live/settings_editor_html/settings_editor.html.heex:55
#, elixir-autogen, elixir-format
msgid "Main Language"
@@ -1392,6 +1398,9 @@ msgstr ""
#: lib/bds/desktop/shell_live/misc_editor.ex:762
#: lib/bds/desktop/shell_live/sidebar_components.ex:654
#: lib/bds/desktop/shell_live/sidebar_delete.ex:175
#: lib/bds/tui.ex:452
#: lib/bds/tui.ex:581
#: lib/bds/tui.ex:584
#: lib/bds/ui/registry.ex:30
#: lib/bds/ui/registry.ex:100
#: lib/bds/ui/sidebar.ex:558
@@ -1444,7 +1453,7 @@ msgstr ""
msgid "Missing URLs"
msgstr ""
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_data.ex:102
#, elixir-autogen, elixir-format
msgid "Mode"
msgstr ""
@@ -1479,6 +1488,7 @@ msgstr ""
#: lib/bds/desktop/menu_bar.ex:185
#: lib/bds/desktop/shell_live/sidebar_create.ex:41
#: lib/bds/tui.ex:103
#, elixir-autogen, elixir-format
msgid "New Post"
msgstr ""
@@ -1657,7 +1667,7 @@ msgstr ""
msgid "Nothing to Import"
msgstr ""
#: lib/bds/desktop/shell_data.ex:100
#: lib/bds/desktop/shell_data.ex:102
#: lib/bds/desktop/shell_live/index.html.heex:503
#, elixir-autogen, elixir-format
msgid "Offline"
@@ -1797,7 +1807,7 @@ msgstr ""
msgid "Other (%{count})"
msgstr ""
#: lib/bds/desktop/shell_live.ex:776
#: lib/bds/desktop/shell_live.ex:785
#: lib/bds/desktop/shell_live/panel_renderer.ex:83
#, elixir-autogen, elixir-format
msgid "Output"
@@ -1879,7 +1889,7 @@ msgstr ""
msgid "Post"
msgstr ""
#: lib/bds/desktop/shell_data.ex:229
#: lib/bds/desktop/shell_data.ex:231
#: lib/bds/desktop/shell_live/panel_renderer.ex:118
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:310
#, elixir-autogen, elixir-format
@@ -1914,6 +1924,8 @@ msgstr ""
#: lib/bds/desktop/menu_bar.ex:202
#: lib/bds/desktop/shell_live/misc_editor.ex:664
#: lib/bds/desktop/shell_live/misc_editor.ex:761
#: lib/bds/tui.ex:451
#: lib/bds/tui.ex:462
#: lib/bds/ui/registry.ex:14
#: lib/bds/ui/sidebar.ex:271
#, elixir-autogen, elixir-format
@@ -1998,7 +2010,7 @@ msgstr ""
msgid "Publish Selected"
msgstr ""
#: lib/bds/desktop/shell_data.ex:163
#: lib/bds/desktop/shell_data.ex:165
#: lib/bds/desktop/shell_live/post_editor.ex:1036
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:472
#: lib/bds/ui/sidebar.ex:324
@@ -2295,6 +2307,7 @@ msgstr ""
#: lib/bds/desktop/shell_live/script_editor.ex:216
#: lib/bds/desktop/shell_live/script_editor.ex:219
#: lib/bds/desktop/shell_live/script_editor.ex:234
#: lib/bds/tui.ex:454
#: lib/bds/ui/registry.ex:38
#: lib/bds/ui/sidebar.ex:63
#: lib/bds/ui/sidebar.ex:115
@@ -2469,7 +2482,7 @@ msgstr ""
msgid "Starting..."
msgstr ""
#: lib/bds/desktop/shell_data.ex:97
#: lib/bds/desktop/shell_data.ex:99
#: lib/bds/desktop/shell_live/import_editor.ex:1182
#: lib/bds/desktop/shell_live/import_editor.ex:1233
#, elixir-autogen, elixir-format
@@ -2542,6 +2555,7 @@ msgstr ""
#: lib/bds/desktop/shell_live/tags_editor.ex:222
#: lib/bds/desktop/shell_live/tags_editor.ex:253
#: lib/bds/desktop/shell_live/tags_editor_html/tags_editor.html.heex:11
#: lib/bds/tui.ex:455
#: lib/bds/ui/registry.ex:54
#: lib/bds/ui/registry.ex:103
#: lib/bds/ui/sidebar.ex:289
@@ -2551,7 +2565,7 @@ msgstr ""
msgid "Tags"
msgstr ""
#: lib/bds/desktop/shell_live.ex:775
#: lib/bds/desktop/shell_live.ex:784
#: lib/bds/desktop/shell_live/panel_renderer.ex:54
#, elixir-autogen, elixir-format
msgid "Tasks"
@@ -2597,6 +2611,7 @@ msgstr ""
#: lib/bds/desktop/shell_live/template_editor.ex:171
#: lib/bds/desktop/shell_live/template_editor.ex:176
#: lib/bds/desktop/shell_live/template_editor.ex:191
#: lib/bds/tui.ex:453
#: lib/bds/ui/registry.ex:46
#: lib/bds/ui/sidebar.ex:71
#: lib/bds/ui/sidebar.ex:122
@@ -2793,7 +2808,7 @@ msgid "Unsaved"
msgstr ""
#: lib/bds/desktop/shell_live/import_editor.ex:871
#: lib/bds/desktop/shell_live/post_editor/post_metadata.ex:166
#: lib/bds/ui/post_editor/metadata.ex:166
#: lib/bds/ui/sidebar.ex:1108
#, elixir-autogen, elixir-format
msgid "Untitled"
@@ -3231,12 +3246,12 @@ msgstr ""
msgid "Comparing database and filesystem metadata"
msgstr ""
#: lib/bds/desktop/shell_live.ex:681
#: lib/bds/desktop/shell_live.ex:682
#, elixir-autogen, elixir-format
msgid "Added %{count} images to post"
msgstr ""
#: lib/bds/desktop/shell_live.ex:649
#: lib/bds/desktop/shell_live.ex:650
#, elixir-autogen, elixir-format
msgid "Added %{title}"
msgstr ""
@@ -3256,18 +3271,18 @@ msgstr ""
msgid "Image Import Concurrency"
msgstr ""
#: lib/bds/desktop/shell_live.ex:441
#: lib/bds/desktop/shell_live.ex:454
#: lib/bds/desktop/shell_live.ex:648
#: lib/bds/desktop/shell_live.ex:680
#: lib/bds/desktop/shell_live.ex:691
#: lib/bds/desktop/shell_live.ex:702
#: lib/bds/desktop/shell_live.ex:442
#: lib/bds/desktop/shell_live.ex:455
#: lib/bds/desktop/shell_live.ex:649
#: lib/bds/desktop/shell_live.ex:681
#: lib/bds/desktop/shell_live.ex:692
#: lib/bds/desktop/shell_live.ex:703
#: lib/bds/desktop/shell_live/post_editor_html/post_editor.html.heex:420
#, elixir-autogen, elixir-format
msgid "Add Gallery Images"
msgstr ""
#: lib/bds/desktop/shell_live.ex:703
#: lib/bds/desktop/shell_live.ex:704
#, elixir-autogen, elixir-format
msgid "Failed to process %{path}: %{reason}"
msgstr ""
@@ -3458,12 +3473,12 @@ msgstr ""
msgid "untracked"
msgstr ""
#: lib/bds/desktop/shell_live.ex:801
#: lib/bds/desktop/shell_live.ex:810
#, elixir-autogen, elixir-format
msgid "Blogmark"
msgstr ""
#: lib/bds/desktop/shell_live.ex:844
#: lib/bds/desktop/shell_live.ex:853
#, elixir-autogen, elixir-format
msgid "Open a project before importing a blogmark."
msgstr ""
@@ -3504,7 +3519,7 @@ msgstr ""
msgid "Failed to copy bookmarklet to clipboard"
msgstr ""
#: lib/bds/desktop/shell_live.ex:813
#: lib/bds/desktop/shell_live.ex:822
#, elixir-autogen, elixir-format
msgid "The project this blogmark targets does not exist here."
msgstr ""
@@ -3611,12 +3626,92 @@ msgstr ""
msgid "The endpoint returned no models. You can still type a model name manually."
msgstr ""
#: lib/bds/tui.ex:28
#: lib/bds/tui.ex:538
#, elixir-autogen, elixir-format
msgid "Blogging Desktop Server"
msgid "AI is unavailable in airplane mode without a local endpoint."
msgstr ""
#: lib/bds/tui.ex:30
#: lib/bds/tui.ex:584
#, elixir-autogen, elixir-format
msgid "Press q to quit."
msgid "Could not load this file."
msgstr ""
#: lib/bds/tui.ex:111
#, elixir-autogen, elixir-format
msgid "Editing this item is not available in the terminal UI yet."
msgstr ""
#: lib/bds/tui.ex:206
#, elixir-autogen, elixir-format
msgid "No suggestions returned."
msgstr ""
#: lib/bds/tui.ex:581
#, elixir-autogen, elixir-format
msgid "Only images can be previewed."
msgstr ""
#: lib/bds/tui.ex:462
#, elixir-autogen, elixir-format
msgid "Post not found."
msgstr ""
#: lib/bds/tui.ex:282
#, elixir-autogen, elixir-format
msgid "Press enter to preview %{name}."
msgstr ""
#: lib/bds/tui.ex:508
#, elixir-autogen, elixir-format
msgid "Published."
msgstr ""
#: lib/bds/tui.ex:524
#, elixir-autogen, elixir-format
msgid "Save before switching languages."
msgstr ""
#: lib/bds/tui.ex:509
#, elixir-autogen, elixir-format
msgid "Saved."
msgstr ""
#: lib/bds/tui.ex:285
#, elixir-autogen, elixir-format
msgid "Select an entry and press enter to open it."
msgstr ""
#: lib/bds/tui.ex:203
#, elixir-autogen, elixir-format
msgid "Suggestions applied."
msgstr ""
#: lib/bds/tui.ex:297
#, elixir-autogen, elixir-format
msgid "Title (ctrl+t to edit)"
msgstr ""
#: lib/bds/tui.ex:296
#, elixir-autogen, elixir-format
msgid "Title (editing — enter to confirm)"
msgstr ""
#: lib/bds/tui.ex:328
#, elixir-autogen, elixir-format
msgid "Working…"
msgstr ""
#: lib/bds/tui.ex:364
#, elixir-autogen, elixir-format
msgid "ctrl+s save · ctrl+p publish · ctrl+t title · ctrl+l language · ctrl+g AI · esc back"
msgstr ""
#: lib/bds/tui.ex:357
#, elixir-autogen, elixir-format
msgid "enter open · n new post · 1-5 views · r refresh · ctrl+q quit"
msgstr ""
#: lib/bds/tui.ex:349
#, elixir-autogen, elixir-format
msgid "esc to close"
msgstr ""

View File

@@ -4,9 +4,10 @@
-- Distilled from: lib/bds/server.ex, lib/bds/application.ex, lib/bds/tui.ex
entity BootMode {
kind: desktop | server
kind: desktop | server | tui
-- Resolved from the BDS_MODE environment variable at application start.
-- Anything other than "server" (case-insensitive) is desktop.
-- "server" is headless; "tui" is the headless server plus a TUI on the
-- launching terminal; anything else is desktop.
}
entity SshKeyMaterial {

70
specs/tui.allium Normal file
View File

@@ -0,0 +1,70 @@
-- allium: 1
-- Terminal UI (issue #26, phase 4)
-- Scope: extension (second renderer over the shared UI core)
-- Distilled from: lib/bds/tui.ex, lib/bds/ui/sidebar.ex, lib/bds/ui/post_editor/*.ex
entity TuiState {
view: posts | media | templates | scripts | tags
focus: sidebar | editor
selected_index: Integer
editing_post: Boolean
-- The editor drives the same BDS.UI.PostEditor workflow as the GUI:
-- canonical-language edits update the post, other languages update
-- translations; publish routes through the same publishing pipeline.
}
surface TuiSurface {
facing _: TuiRuntime
provides:
TuiKeyPressed(code, modifiers)
TuiEventReceived(entity, entity_id, action)
TuiSettingsChanged(key)
}
rule SidebarNavigation {
when: TuiKeyPressed(code: "up" | "down" | "j" | "k")
-- Selection moves over the flattened sidebar items and skips
-- section headers; data comes from BDS.UI.Sidebar.view, identical
-- to the GUI sidebar content.
ensures: TuiState.selected_index.updated()
}
rule OpenEntry {
when: TuiKeyPressed(code: "enter")
-- Posts open in the editor (title + textarea seeded from the
-- persisted form). Images open in the terminal image preview.
-- Other entities report that terminal editing is not available yet.
ensures: TuiState.editing_post.updated()
}
rule SaveAndPublish {
when: TuiKeyPressed(code: "s" | "p", modifiers: "ctrl")
-- ctrl+s saves the draft, ctrl+p saves and publishes — both through
-- BDS.UI.PostEditor.Persistence, so files, embeddings, search, and
-- the event bus behave exactly as a GUI save.
ensures: PostPersisted()
}
rule AiQuickAction {
when: TuiKeyPressed(code: "g", modifiers: "ctrl")
-- One-shot AI post analysis (title/excerpt suggestions). Gated by
-- airplane mode: without a local endpoint the TUI shows a status
-- message instead of calling out.
ensures: AiSuggestionsRequestedOrRefused()
}
rule MultiClientSync {
when: TuiEventReceived(entity, entity_id, action)
-- Domain events refresh the sidebar; a post deleted elsewhere closes
-- the open editor. Keeps TUI sessions synchronized with GUI clients
-- and pipeline ingestion.
ensures: TuiState.updated()
}
rule ServerSideLocale {
when: TuiSettingsChanged(key: "ui.language")
-- The TUI re-reads the server-side UI language and re-renders; all
-- clients always share one language.
ensures: TuiRelocalized()
}

View File

@@ -14,6 +14,10 @@ defmodule BDS.ServerTest do
assert Server.mode("SERVER") == :server
end
test "recognizes tui mode" do
assert Server.mode("tui") == :tui
end
test "unknown values fall back to :desktop" do
assert Server.mode("garbage") == :desktop
end
@@ -103,6 +107,11 @@ defmodule BDS.ServerTest do
end)
end
test "tui mode is the server plus a local TUI" do
assert BDS.Application.mode_children(:tui, :prod) ==
BDS.Application.mode_children(:server, :prod) ++ [{BDS.TUI, []}]
end
test "desktop mode delegates to desktop_children" do
assert BDS.Application.mode_children(:desktop, :test) ==
BDS.Application.desktop_children(:test)

135
test/bds/tui_test.exs Normal file
View File

@@ -0,0 +1,135 @@
defmodule BDS.TUITest do
use ExUnit.Case, async: false
import Ecto.Query
alias ExRatatui.CellSession
alias ExRatatui.Event.Key
defp post_count(project_id) do
BDS.Repo.aggregate(from(p in BDS.Posts.Post, where: p.project_id == ^project_id), :count)
end
setup do
:ok = Ecto.Adapters.SQL.Sandbox.checkout(BDS.Repo)
Ecto.Adapters.SQL.Sandbox.mode(BDS.Repo, {:shared, self()})
on_exit(fn -> Ecto.Adapters.SQL.Sandbox.mode(BDS.Repo, :manual) end)
temp_dir = Path.join(System.tmp_dir!(), "bds-tui-#{System.unique_integer([:positive])}")
File.mkdir_p!(temp_dir)
on_exit(fn -> File.rm_rf(temp_dir) end)
{:ok, project} = BDS.Projects.create_project(%{name: "TUI", data_path: temp_dir})
{:ok, _} = BDS.Projects.set_active_project(project.id)
{:ok, post} =
BDS.Posts.create_post(%{
project_id: project.id,
title: "Hello TUI",
content: "terminal body",
language: "en"
})
%{project: project, post: post}
end
defp mount!(opts \\ []) do
{:ok, state} = BDS.TUI.mount(opts)
state
end
defp screen_text(state, width \\ 100, height \\ 32) do
session = CellSession.new(width, height)
frame = %ExRatatui.Frame{width: width, height: height}
:ok = CellSession.draw(session, BDS.TUI.render(state, frame))
snapshot = CellSession.take_cells(session)
:ok = CellSession.close(session)
snapshot.cells
|> Enum.group_by(& &1.row)
|> Enum.sort_by(fn {row, _} -> row end)
|> Enum.map_join("\n", fn {_row, cells} ->
cells |> Enum.sort_by(& &1.col) |> Enum.map_join("", & &1.symbol)
end)
end
defp key(code, modifiers \\ []), do: %Key{code: code, kind: "press", modifiers: modifiers}
defp press(state, code, modifiers \\ []) do
{:noreply, state} = BDS.TUI.handle_event(key(code, modifiers), state)
state
end
test "mounts against the active project and lists posts", %{post: post} do
state = mount!()
assert state.project_id == post.project_id
text = screen_text(state)
assert text =~ "Hello TUI"
end
test "navigates and opens a post in the editor", %{post: post} do
state = mount!() |> press("enter")
assert state.focus == :editor
assert state.editor.post.id == post.id
assert ExRatatui.textarea_get_value(state.editor.textarea) == "terminal body"
assert screen_text(state) =~ "terminal body"
end
test "ctrl+s persists textarea edits", %{post: post} do
state = mount!() |> press("enter")
:ok = ExRatatui.textarea_insert_str(state.editor.textarea, "more words ")
state = press(state, "s", ["ctrl"])
assert state.editor.dirty == false
assert BDS.Posts.get_post(post.id).content =~ "more words"
end
test "ctrl+p publishes the open post", %{post: post} do
state = mount!() |> press("enter") |> press("p", ["ctrl"])
published = BDS.Posts.get_post(post.id)
assert published.status == :published
assert state.editor.post.status == :published
end
test "n creates a new draft post", %{project: project} do
count_before = post_count(project.id)
state = mount!() |> press("n")
assert post_count(project.id) == count_before + 1
assert state.focus == :editor
assert state.editor.post.status == :draft
end
test "esc returns focus to the sidebar" do
state = mount!() |> press("enter") |> press("esc")
assert state.focus == :sidebar
end
test "entity_changed refreshes the sidebar", %{project: project} do
state = mount!()
{:ok, other} =
BDS.Posts.create_post(%{project_id: project.id, title: "From Pipeline", content: "x"})
{:noreply, state} =
BDS.TUI.handle_info(
{:entity_changed, %{entity: "post", entity_id: other.id, action: :created}},
state
)
assert screen_text(state) =~ "From Pipeline"
end
test "view switching shows media view" do
state = mount!() |> press("2")
assert state.view == "media"
end
test "quit key stops the app" do
assert {:stop, _state} = BDS.TUI.handle_event(key("q", ["ctrl"]), mount!())
end
end