feat: terminal UI over the shared workbench core (issue #26, phase 4)
This commit is contained in:
57
README.md
57
README.md
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
591
lib/bds/tui.ex
591
lib/bds/tui.ex
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 ""
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 d’import"
|
||||
msgid "Import failed: %{error}"
|
||||
msgstr "Échec de l’import : %{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 d’articles 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 l’application
|
||||
#: 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 l’assistant 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 d’importer 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"
|
||||
|
||||
@@ -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 nell’assistente 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"
|
||||
|
||||
@@ -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 ""
|
||||
|
||||
@@ -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
70
specs/tui.allium
Normal 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()
|
||||
}
|
||||
@@ -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
135
test/bds/tui_test.exs
Normal 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
|
||||
Reference in New Issue
Block a user