main
6d86999 ยท 6 months ago 26 commits
  1package app
  2
  3import (
  4	"fmt"
  5	"github.com/The-Robin-Hood/ufWall/internal/sections/rules"
  6	"github.com/The-Robin-Hood/ufWall/internal/ui"
  7
  8	"github.com/charmbracelet/lipgloss"
  9)
 10
 11func (m model) renderCenteredOverlay(overlay, background string) string {
 12	dimmed := "\x1b[2m" + lipgloss.NewStyle().Faint(true).Render(background) + "\x1b[0m"
 13	overlayW := lipgloss.Width(overlay)
 14	overlayH := lipgloss.Height(overlay)
 15	x := (m.width - overlayW) / 2
 16	y := (m.height - overlayH) / 2
 17	return PlaceOverlay(x, y, overlay, dimmed)
 18}
 19
 20func (m model) View() string {
 21	const minWidth, minHeight = 87, 30
 22	const containerWidth, containerHeight = minWidth - 5, minHeight - 3
 23	if m.width < minWidth || m.height < minHeight {
 24		return lipgloss.Place(
 25			m.width,
 26			m.height,
 27			lipgloss.Center,
 28			lipgloss.Center,
 29			m.styles.Error.Render(fmt.Sprintf("Terminal too small!\nMinimum: %dx%d\nCurrent: %dx%d", minWidth, minHeight, m.width, m.height)),
 30		)
 31	}
 32
 33	if m.err != nil {
 34		footer := ui.Footer(m.styles, m.activeSection, containerWidth)
 35		return lipgloss.JoinVertical(
 36			lipgloss.Center,
 37			"",
 38			m.styles.Error.Render(fmt.Sprintf("%v", m.err)),
 39			"",
 40			footer,
 41		)
 42	}
 43
 44	if !m.stats.Active {
 45		prompt := lipgloss.JoinVertical(
 46			lipgloss.Center,
 47			m.styles.Error.Render("Firewall is disabled"),
 48			"",
 49			lipgloss.NewStyle().Foreground(lipgloss.Color("241")).Render("Press Space to activate"),
 50			lipgloss.NewStyle().Foreground(lipgloss.Color("241")).Render("Press Esc or Q to quit"),
 51		)
 52		return lipgloss.Place(
 53			m.width,
 54			m.height,
 55			lipgloss.Center,
 56			lipgloss.Center,
 57			prompt,
 58		)
 59	}
 60
 61	title := m.styles.Title.
 62		Width(containerWidth).
 63		Render("Firewall Manager")
 64
 65	infoSection := lipgloss.JoinHorizontal(
 66		lipgloss.Top,
 67		m.statsSection.View(m.stats),
 68		m.policySection.View(m.policy),
 69	)
 70
 71	content := lipgloss.JoinVertical(
 72		lipgloss.Left,
 73		infoSection,
 74		m.rulesSection.View(rules.RulesData{IPv4: m.ipv4Rules, IPv6: m.ipv6Rules}),
 75	)
 76
 77	layout := lipgloss.JoinVertical(
 78		lipgloss.Left,
 79		title,
 80		"",
 81		content,
 82		"",
 83		ui.Footer(m.styles, m.activeSection, containerWidth),
 84	)
 85
 86	layout = lipgloss.Place(
 87		m.width,
 88		m.height,
 89		lipgloss.Center,
 90		lipgloss.Center,
 91		layout,
 92	)
 93
 94	if m.rulesSection.ShowingDeleteConfirm() {
 95		return m.renderCenteredOverlay(m.rulesSection.DeleteConfirmView(), layout)
 96	}
 97
 98	if m.rulesSection.ShowingDetails() {
 99		return m.renderCenteredOverlay(m.rulesSection.DetailView(), layout)
100	}
101
102	if m.rulesSection.ShowingAddWizard() {
103		return m.renderCenteredOverlay(m.rulesSection.AddWizardView(), layout)
104	}
105
106	if menu := m.statsSection.GetMenu(); menu != nil {
107		return m.renderCenteredOverlay(menu.View(m.styles), layout)
108	}
109
110	if menu := m.rulesSection.GetMenu(); menu != nil {
111		return m.renderCenteredOverlay(menu.View(m.styles), layout)
112	}
113
114	return layout
115}