Fix help screen documentation - incorrect key binding for viewing details
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/calmcacil/wg-admin/internal/config"
|
||||
"github.com/calmcacil/wg-admin/internal/validation"
|
||||
"github.com/calmcacil/wg-admin/internal/wireguard"
|
||||
"github.com/charmbracelet/bubbles/spinner"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/huh"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
@@ -13,8 +14,10 @@ import (
|
||||
|
||||
// AddScreen is a form for adding new WireGuard clients
|
||||
type AddScreen struct {
|
||||
form *huh.Form
|
||||
quitting bool
|
||||
form *huh.Form
|
||||
quitting bool
|
||||
spinner spinner.Model
|
||||
isCreating bool
|
||||
}
|
||||
|
||||
// Styles
|
||||
|
||||
@@ -113,7 +113,7 @@ func (s *DetailScreen) Update(msg tea.Msg) (Screen, tea.Cmd) {
|
||||
s.transferTx = msg.transferTx
|
||||
case tea.KeyMsg:
|
||||
switch msg.String() {
|
||||
case "b", "esc":
|
||||
case "q", "b", "esc":
|
||||
// Return to list screen - signal parent to switch screens
|
||||
return nil, nil
|
||||
case "d":
|
||||
@@ -174,9 +174,9 @@ func (s *DetailScreen) View() string {
|
||||
func (s *DetailScreen) renderContent() string {
|
||||
statusText := s.status
|
||||
if s.status == wireguard.StatusConnected {
|
||||
statusText = detailConnectedStyle.Render(s.status)
|
||||
statusText = detailConnectedStyle.Render("● " + s.status)
|
||||
} else {
|
||||
statusText = detailDisconnectedStyle.Render(s.status)
|
||||
statusText = detailDisconnectedStyle.Render("● " + s.status)
|
||||
}
|
||||
|
||||
// Build content
|
||||
@@ -205,7 +205,7 @@ func (s *DetailScreen) renderContent() string {
|
||||
)
|
||||
|
||||
// Add help text
|
||||
helpText := detailHelpStyle.Render("Actions: [d] Delete • [c] View Config • [b] Back")
|
||||
helpText := detailHelpStyle.Render("Actions: [d] Delete • [c] View Config • [q/b] Back")
|
||||
content = lipgloss.JoinVertical(lipgloss.Left, content, helpText)
|
||||
|
||||
return content
|
||||
|
||||
@@ -76,7 +76,6 @@ func (s *HelpScreen) View() string {
|
||||
actionsGroup := categoryStyle.Render("Actions") + "\n" +
|
||||
keyStyle.Render("a") + descStyle.Render("Add client") + "\n" +
|
||||
keyStyle.Render("d") + descStyle.Render("Delete client") + "\n" +
|
||||
keyStyle.Render("D") + descStyle.Render("Client details") + "\n" +
|
||||
keyStyle.Render("Q") + descStyle.Render("Show QR code") + "\n" +
|
||||
keyStyle.Render("r") + descStyle.Render("Refresh list") + "\n" +
|
||||
keyStyle.Render("l") + descStyle.Render("List view")
|
||||
|
||||
@@ -3,6 +3,7 @@ package screens
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/calmcacil/wg-admin/internal/tui/components"
|
||||
"github.com/calmcacil/wg-admin/internal/wireguard"
|
||||
@@ -11,16 +12,17 @@ import (
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
const statusRefreshInterval = 10 // seconds
|
||||
const statusRefreshInterval = 3 // seconds
|
||||
|
||||
// ListScreen displays a table of WireGuard clients
|
||||
type ListScreen struct {
|
||||
table table.Model
|
||||
search *components.SearchModel
|
||||
clients []ClientWithStatus
|
||||
filtered []ClientWithStatus
|
||||
sortedBy string // Column name being sorted by
|
||||
ascending bool // Sort direction
|
||||
table table.Model
|
||||
search *components.SearchModel
|
||||
clients []ClientWithStatus
|
||||
filtered []ClientWithStatus
|
||||
sortedBy string // Column name being sorted by
|
||||
ascending bool // Sort direction
|
||||
lastUpdated time.Time
|
||||
}
|
||||
|
||||
// ClientWithStatus wraps a client with its connection status
|
||||
@@ -43,9 +45,20 @@ func (s *ListScreen) Init() tea.Cmd {
|
||||
return tea.Batch(
|
||||
s.loadClients,
|
||||
wireguard.Tick(statusRefreshInterval),
|
||||
ticker(),
|
||||
)
|
||||
}
|
||||
|
||||
// ticker sends a message every second to update the time display
|
||||
func ticker() tea.Cmd {
|
||||
return tea.Tick(time.Second, func(t time.Time) tea.Msg {
|
||||
return timeTickMsg(t)
|
||||
})
|
||||
}
|
||||
|
||||
// timeTickMsg is sent every second to update the time display
|
||||
type timeTickMsg time.Time
|
||||
|
||||
// Update handles messages for the list screen
|
||||
func (s *ListScreen) Update(msg tea.Msg) (Screen, tea.Cmd) {
|
||||
var cmd tea.Cmd
|
||||
@@ -104,8 +117,11 @@ func (s *ListScreen) Update(msg tea.Msg) (Screen, tea.Cmd) {
|
||||
}
|
||||
case clientsLoadedMsg:
|
||||
s.clients = msg.clients
|
||||
s.lastUpdated = time.Now()
|
||||
s.search.SetTotalCount(len(s.clients))
|
||||
s.applyFilter()
|
||||
case timeTickMsg:
|
||||
// Trigger a re-render to update "Last updated" display
|
||||
case wireguard.StatusTickMsg:
|
||||
// Refresh status on periodic tick
|
||||
return s, s.loadClients
|
||||
@@ -132,7 +148,29 @@ func (s *ListScreen) View() string {
|
||||
Render("No matching clients found. Try a different search term.")
|
||||
}
|
||||
|
||||
return s.search.View() + "\n" + s.table.View()
|
||||
// Calculate time since last update
|
||||
timeAgo := "never"
|
||||
if !s.lastUpdated.IsZero() {
|
||||
duration := time.Since(s.lastUpdated)
|
||||
timeAgo = formatDuration(duration)
|
||||
}
|
||||
|
||||
lastUpdatedText := lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("241")).
|
||||
Render("Last updated: " + timeAgo)
|
||||
|
||||
return s.search.View() + "\n" + s.table.View() + "\n" + lastUpdatedText
|
||||
}
|
||||
|
||||
// formatDuration returns a human-readable string for the duration
|
||||
func formatDuration(d time.Duration) string {
|
||||
if d < time.Minute {
|
||||
return "just now"
|
||||
}
|
||||
if d < time.Hour {
|
||||
return fmt.Sprintf("%d min ago", int(d.Minutes()))
|
||||
}
|
||||
return fmt.Sprintf("%d hr ago", int(d.Hours()))
|
||||
}
|
||||
|
||||
// loadClients loads clients from wireguard config
|
||||
|
||||
Reference in New Issue
Block a user