package app import ( "fmt" "log" "os" "strconv" "strings" tea "charm.land/bubbletea/v2" "github.com/anotherhadi/settuings/internal/config" aboutUI "github.com/anotherhadi/settuings/internal/ui/about" audioUI "github.com/anotherhadi/settuings/internal/ui/audio" bluetoothUI "github.com/anotherhadi/settuings/internal/ui/bluetooth" notificationsUI "github.com/anotherhadi/settuings/internal/ui/components/notifications" networkUI "github.com/anotherhadi/settuings/internal/ui/network" "github.com/sirupsen/logrus" ) var pageShortcuts = func() map[string]page { m := make(map[string]page, len(pageRegistry)) for i, e := range pageRegistry { m[strconv.Itoa(i+1)] = e.id } return m }() type Model struct { page page logPath string fatalErr error logFileErr error width int height int sidebarState sidebarState about aboutUI.Model network networkUI.Model bluetooth bluetoothUI.Model audio audioUI.Model notifications notificationsUI.Model } const logPath = "/tmp/settuings.log" // New creates the app's root model. initialPage selects the page shown on // launch (matched case-insensitively against PageNames); an empty string // falls back to the default page. It returns an error if initialPage is // non-empty and does not match a known page. func New(initialPage string) (Model, error) { startPage := pageAbout if initialPage != "" { p, ok := lookupPage(initialPage) if !ok { return Model{}, fmt.Errorf("unknown page %q (valid: %s)", initialPage, strings.Join(PageNames(), ", ")) } startPage = p } cfg := config.Global m := Model{ page: startPage, about: aboutUI.New(), network: networkUI.New(), bluetooth: bluetoothUI.New(), audio: audioUI.New(), notifications: notificationsUI.New(), sidebarState: sidebarState(cfg.TUI.DefaultSidebarState), logPath: logPath, } if lf, err := os.OpenFile(m.logPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600); err == nil { log.SetOutput(lf) logrus.SetOutput(lf) } else { m.logFileErr = err } return m, nil } func (m Model) FatalErr() error { return m.fatalErr } func (m Model) Init() tea.Cmd { cmds := []tea.Cmd{m.about.Init(), m.network.Init(), m.bluetooth.Init(), m.audio.Init()} if m.page != pageAbout { cmds = append(cmds, m.activatePage(m.page)) } if m.logFileErr != nil { err := m.logFileErr cmds = append(cmds, func() tea.Msg { return notificationsUI.NotificationMsg{ Title: "Warning", Body: "Could not open log file: " + err.Error(), Kind: notificationsUI.KindWarning, } }) } return tea.Batch(cmds...) }