package main import ( "fmt" "github.com/charmbracelet/huh" ) func (m *model) initLoginForm() { m.loginForm = huh.NewForm( huh.NewGroup( huh.NewNote().Title("ODROID Connector").Description("Enter credentials"), huh.NewInput().Title("IP Address").Value(&m.formData.IP), huh.NewInput().Title("Username").Value(&m.formData.Username), huh.NewInput().Title("Password").Value(&m.formData.Password).EchoMode(huh.EchoModePassword), ), ).WithTheme(huh.ThemeBase()) } func (m *model) initSettingsMenu() { *m.menuSelection = "scan" m.settingsForm = huh.NewForm( huh.NewGroup( huh.NewSelect[string](). Title("Settings Menu"). Key("menu_select"). Options( huh.NewOption("1. Scan Networks", "scan"), huh.NewOption("2. Manual Connection", "manual"), huh.NewOption("3. IP Configuration", "ip"), huh.NewOption("4. AP Mode Settings", "ap"), huh.NewOption("5. System (UART/Sensor)", "system"), huh.NewOption("6. Safety (Current Limits)", "safety"), huh.NewOption("7. Account Settings", "account"), huh.NewOption("8. Reboot Device", "reboot"), huh.NewOption("Esc. Exit", "exit"), ). Value(m.menuSelection), ), ).WithTheme(huh.ThemeDracula()) } func (m *model) initWifiScanForm() { opts := make([]huh.Option[string], 0) for _, ap := range m.wifiScanList { label := fmt.Sprintf("%s (%ddBm, %s)", ap.SSID, ap.RSSI, ap.AuthMode) opts = append(opts, huh.NewOption(label, ap.SSID)) } if len(opts) == 0 { opts = append(opts, huh.NewOption("(No Networks Found - Back)", "")) } // [수정] 터미널 높이를 계산하여 리스트 최대 높이 제한 (스크롤 활성화) listHeight := 10 if m.height > 20 { listHeight = m.height - 10 // 여백 고려 } m.settingsForm = huh.NewForm( huh.NewGroup( huh.NewSelect[string](). Title("Select Wi-Fi Network"). Key("scan_ssid"). Options(opts...). Value(&m.settingsData.WifiSSID). WithHeight(listHeight), // [핵심] 높이 제한으로 터미널 뚫림 방지 ), ).WithTheme(huh.ThemeDracula()) } func (m *model) initWifiForm() { m.settingsForm = huh.NewForm( huh.NewGroup( huh.NewNote().Title("Connect to Wi-Fi"), huh.NewInput().Title("SSID").Value(&m.settingsData.WifiSSID), huh.NewInput().Title("Password").Value(&m.settingsData.WifiPass).EchoMode(huh.EchoModePassword), ), ).WithTheme(huh.ThemeDracula()) } func (m *model) initIPForm() { m.settingsForm = huh.NewForm( huh.NewGroup( huh.NewSelect[string](). Title("Network Type"). Options( huh.NewOption("DHCP", "dhcp"), huh.NewOption("Static", "static"), ). Value(&m.settingsData.NetType), ), huh.NewGroup( huh.NewNote().Title("Static IP Details"), huh.NewInput().Title("IP Address").Value(&m.settingsData.IP), huh.NewInput().Title("Gateway").Value(&m.settingsData.Gateway), huh.NewInput().Title("Subnet Mask").Value(&m.settingsData.Subnet), huh.NewInput().Title("DNS 1").Value(&m.settingsData.DNS1), huh.NewInput().Title("DNS 2").Value(&m.settingsData.DNS2), ).WithHideFunc(func() bool { // [수정] DHCP일 때 완벽히 숨김 처리 return m.settingsData.NetType != "static" }), ).WithTheme(huh.ThemeDracula()) } func (m *model) initAPForm() { m.settingsForm = huh.NewForm( huh.NewGroup( huh.NewSelect[string](). Title("WiFi Mode"). Options( huh.NewOption("Station Only (STA)", "sta"), huh.NewOption("AP + Station (APSTA)", "apsta"), ). Value(&m.settingsData.Mode), ), huh.NewGroup( huh.NewNote().Title("AP Settings"), huh.NewInput().Title("AP SSID").Value(&m.settingsData.APSSID), huh.NewInput().Title("AP Password").Value(&m.settingsData.APPass).EchoMode(huh.EchoModePassword), ).WithHideFunc(func() bool { // [수정] APSTA가 아닐 때 숨김 처리 return m.settingsData.Mode != "apsta" }), ).WithTheme(huh.ThemeDracula()) } func (m *model) initSystemForm() { m.settingsForm = huh.NewForm( huh.NewGroup( huh.NewNote().Title("System Configuration"), huh.NewSelect[string](). Title("UART Baudrate"). Options( huh.NewOption("9600", "9600"), huh.NewOption("19200", "19200"), huh.NewOption("38400", "38400"), huh.NewOption("57600", "57600"), huh.NewOption("115200", "115200"), huh.NewOption("1500000", "1500000"), ). Value(&m.settingsData.Baudrate), huh.NewInput(). Title("Sensor Period (ms)"). Value(&m.settingsData.Period), ), ).WithTheme(huh.ThemeDracula()) } func (m *model) initSafetyForm() { vinStr := fmt.Sprintf("%.2f", m.settingsData.VinLimit) mainStr := fmt.Sprintf("%.2f", m.settingsData.MainLimit) usbStr := fmt.Sprintf("%.2f", m.settingsData.UsbLimit) m.settingsForm = huh.NewForm( huh.NewGroup( huh.NewNote().Title("Current Limits (Ampere)"), // Key를 명시하여 update.go에서 안전하게 파싱 huh.NewInput().Title("VIN Limit").Value(&vinStr).Key("vin_limit"), huh.NewInput().Title("Main (12V) Limit").Value(&mainStr).Key("main_limit"), huh.NewInput().Title("USB (5V) Limit").Value(&usbStr).Key("usb_limit"), ), ).WithTheme(huh.ThemeDracula()) } func (m *model) initAccountForm() { m.settingsForm = huh.NewForm( huh.NewGroup( huh.NewNote().Title("Change Credentials"), huh.NewInput().Title("New Username").Value(&m.settingsData.NewUser), huh.NewInput().Title("New Password").Value(&m.settingsData.NewPass).EchoMode(huh.EchoModePassword), ), ).WithTheme(huh.ThemeDracula()) }