package main import ( "context" "log" "os" "os/signal" "syscall" "time" "github.com/gdamore/tcell/v2" "github.com/rivo/tview" ) func MonitorDevice(ctx context.Context, app *tview.Application, frame **tview.Frame, state *UIState, device *Device) { ticker := time.NewTicker(100 * time.Millisecond) // Check every 100ms defer ticker.Stop() for { select { case <-ctx.Done(): return case <-ticker.C: port, err := device.FindCardputer() if err != nil { if device.Connected { device.Close() UpdateDeviceStatus(app, *frame, state, "Cardputer disconnected", tcell.ColorRed) } } else { if !device.Connected { UpdateDeviceStatus(app, *frame, state, "Cardputer found: "+port, tcell.ColorWhite) err = device.Connect() if err != nil { UpdateDeviceStatus(app, *frame, state, "Error connecting to cardputer: "+err.Error(), tcell.ColorRed) } else { UpdateDeviceStatus(app, *frame, state, "Connected to cardputer: "+port, tcell.ColorGreen) } } else { UpdateDeviceStatus(app, *frame, state, "Connected to cardputer: "+port, tcell.ColorGreen) } } } } } func main() { // Initialize Device manager device := NewDevice() app := tview.NewApplication() var currentFrame *tview.Frame state := &UIState{ Page: "home", } frame := AppUI(app, ¤tFrame, state) currentFrame = frame app.SetRoot(frame, true) ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Set up signal handling for graceful shutdown sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) // Handle signals in a goroutine go func() { <-sigChan // Cancel context to stop monitoring cancel() // Disconnect device gracefully if device.Connected { log.Println("Disconnecting device...") if err := device.Close(); err != nil { log.Printf("Error disconnecting device: %v\n", err) } } // Stop the application app.Stop() }() go MonitorDevice(ctx, app, ¤tFrame, state, device) if err := app.Run(); err != nil { log.Fatal("Error running program:", err) } }