rustploy-gui 0.1.21

Rustploy — desktop client (glacier-ui) for the Rustploy PaaS daemon
// Janela de LOGS AO VIVO (runtime OU build): motor Glacier próprio e ISOLADO do
// app principal, aberta via open_window por handlers/services.luau
// (open_logs_window / open_build_logs_window).
screen {
  resources {
    style """
      .log-window__body   { width: fill; height: fill; padding: 14; spacing: 10; }
      .log-window__head   { width: fill; align-y: center; spacing: 12; }
      .log-window__title  { size: 13; bold: true; color: var(--text); }
      .log-window__count  { width: fill; size: 11; color: var(--muted); }
      .log-window__scroll { width: fill; height: fill; background: var(--surface); border-radius: 4; padding: 10; }
      .log-window__editor { width: fill; height: fill; background: var(--surface); border-radius: 4; padding: 10 12; font: mono; }
    """

    script(src = "scripts/log_window.luau")
  }

  column(class = screen) {
    // Borda superior + cantos (n / nw / ne)
    row(class = resize__top) {
      column(class = "resize__corner resize__corner--nw", on_press = window:resize:nw)
      column(class = resize__edge-h, on_press = window:resize:n)
      column(class = "resize__corner resize__corner--ne", on_press = window:resize:ne)
    }

    // Banda central: borda esquerda | corpo | borda direita (w / e)
    row(class = resize__mid) {
      column(class = resize__edge-v, on_press = window:resize:w)

      column(class = resize__body) {
        // Titlebar custom (borderless)
        row(class = titlebar) {
          row(
            class = titlebar__drag,
            on_press = window:drag,
            on_double_click = window:maximize,
          ) {
            text(class = titlebar__dot, content = "●")
            text(class = titlebar__title, content = "@log_window_title")
          }

          button(class = titlebar__btn, on_click = window:minimize, text = "—")
          // Quadrado = maximizar; dois sobrepostos = restaurar (a convenção da
          // barra nativa). O estado vem do daemon do glacier, a cada resize.
          if @glacier_window_maximized {
            button(class = titlebar__btn, on_click = window:maximize) {
              container(class = titlebar__icon-box) {
                svg(class = titlebar__icon, src = "assets/icons/win_restore.svg")
              }
            }
          } else {
            button(class = titlebar__btn, on_click = window:maximize) {
              container(class = titlebar__icon-box) {
                svg(class = titlebar__icon, src = "assets/icons/win_maximize.svg")
              }
            }
          }
          button(class = "titlebar__btn titlebar__btn--close", on_click = window:close, text = "✕")
        }

        column(class = log-window__body) {
          row(class = log-window__head) {
            text(class = log-window__title, content = "@log_window_title")
            text(class = log-window__count, content = "@log_window_count linhas · ao vivo")

            button(
              class = tabs__tab,
              on_click = textarea_top:log_window_logs_text,
              text = "↑",
              tooltip = "Ir ao topo",
            )

            button(
              class = tabs__tab,
              on_click = textarea_end:log_window_logs_text,
              text = "↓",
              tooltip = "Ir ao fim",
            )

            button(
              class = tabs__tab,
              on_click = copy_ctx:log_window_logs_text,
              text = "Copiar tudo",
            )
          }

          textarea(
            class = log-window__editor,
            font = mono,
            readonly = true,
            :value = log_window_logs_text,
            placeholder = "(sem logs ainda — aguardando o serviço emitir saída)",
          )
        }
      }

      column(class = resize__edge-v, on_press = window:resize:e)
    }

    // Borda inferior + cantos (s / sw / se)
    row(class = resize__bottom) {
      column(class = "resize__corner resize__corner--sw", on_press = window:resize:sw)
      column(class = resize__edge-h, on_press = window:resize:s)
      column(class = "resize__corner resize__corner--se", on_press = window:resize:se)
    }
  }
}