main
6d86999 ยท 6 months ago 26 commits
  1package rules
  2
  3import (
  4	"github.com/The-Robin-Hood/ufWall/internal/ufw"
  5	"github.com/The-Robin-Hood/ufWall/internal/ui"
  6)
  7
  8type Table int
  9
 10const (
 11	IPv4Table Table = iota
 12	IPv6Table
 13)
 14
 15type WizardStep int
 16
 17const (
 18	StepAction WizardStep = iota
 19	StepDirection
 20	StepProtocol
 21	StepPort
 22	StepSource
 23	StepDestination
 24	StepInterface
 25	StepConfirm
 26)
 27
 28type AddWizard struct {
 29	Step       WizardStep
 30	Params     ufw.AddRuleParams
 31	Input      string
 32	InputMode  bool
 33	Options    []string
 34	Cursor     int
 35	Interfaces []string
 36	Error      string
 37}
 38
 39type MenuContext struct {
 40	Action         string
 41	SelectedRule   *ufw.Rule
 42	TotalRules     int
 43	PendingSubmenu bool
 44}
 45
 46type Model struct {
 47	styles     ui.Styles
 48	cursorLine int
 49	menu       *ui.Menu
 50	active     bool
 51
 52	// Two-table navigation
 53	activeTable    Table // Which table (IPv4 or IPv6) is currently focused
 54	ipv4CursorLine int
 55	ipv6CursorLine int
 56
 57	// Scroll offsets for each table
 58	ipv4ScrollOffset int
 59	ipv6ScrollOffset int
 60
 61	// Detail view overlay
 62	showDetails bool
 63	detailRule  *ufw.Rule
 64
 65	// Delete confirmation
 66	showDeleteConfirm bool
 67	deleteRule        *ufw.Rule
 68
 69	// Multi-step menu operations
 70	menuContext *MenuContext
 71	addWizard   *AddWizard
 72}
 73
 74const MaxVisibleRules = 7
 75
 76func New(styles ui.Styles) Model {
 77	return Model{
 78		styles:            styles,
 79		cursorLine:        0,
 80		menu:              nil,
 81		active:            false,
 82		activeTable:       IPv4Table,
 83		ipv4CursorLine:    0,
 84		ipv6CursorLine:    0,
 85		ipv4ScrollOffset:  0,
 86		ipv6ScrollOffset:  0,
 87		showDetails:       false,
 88		detailRule:        nil,
 89		showDeleteConfirm: false,
 90		deleteRule:        nil,
 91		menuContext:       nil,
 92		addWizard:         nil,
 93	}
 94}
 95
 96func (m *Model) Focus() {
 97	m.active = true
 98}
 99
100func (m *Model) Blur() {
101	m.active = false
102	m.menu = nil
103	m.showDetails = false
104	m.showDeleteConfirm = false
105	m.menuContext = nil
106	m.addWizard = nil
107}
108
109func (m Model) HasOpenMenu() bool {
110	return m.menu != nil || m.showDetails || m.showDeleteConfirm || m.addWizard != nil
111}
112
113func (m Model) GetMenu() *ui.Menu {
114	return m.menu
115}
116
117func (m Model) ShowingDetails() bool {
118	return m.showDetails
119}
120
121func (m Model) GetDetailRule() *ufw.Rule {
122	return m.detailRule
123}
124
125func (m Model) ShowingDeleteConfirm() bool {
126	return m.showDeleteConfirm
127}
128
129func (m Model) GetDeleteRule() *ufw.Rule {
130	return m.deleteRule
131}
132
133func (m Model) ActiveTable() Table {
134	return m.activeTable
135}
136
137func (m Model) IPv4CursorLine() int {
138	return m.ipv4CursorLine
139}
140
141func (m Model) IPv6CursorLine() int {
142	return m.ipv6CursorLine
143}
144
145func (m Model) CurrentCursorLine() int {
146	if m.activeTable == IPv6Table {
147		return m.ipv6CursorLine
148	}
149	return m.ipv4CursorLine
150}
151
152func (m Model) CurrentScrollOffset() int {
153	if m.activeTable == IPv6Table {
154		return m.ipv6ScrollOffset
155	}
156	return m.ipv4ScrollOffset
157}
158
159func (m Model) ShowingAddWizard() bool {
160	return m.addWizard != nil
161}
162
163func (m Model) GetAddWizard() *AddWizard {
164	return m.addWizard
165}
166
167func NewAddWizard() *AddWizard {
168	return &AddWizard{
169		Step:       StepAction,
170		Params:     ufw.AddRuleParams{},
171		Input:      "",
172		InputMode:  false,
173		Options:    ufw.Actions,
174		Cursor:     0,
175		Interfaces: ufw.GetInterfaces(),
176		Error:      "",
177	}
178}