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}