diff --git a/cmd/root.go b/cmd/root.go index a3f4755..fff80e3 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,6 +1,7 @@ package cmd import ( + "embed" "net/url" "os" "runtime" @@ -15,6 +16,7 @@ import ( "go.uber.org/zap" ) +var EMBEDFS *embed.FS var LOG *zap.SugaredLogger var CFG config.Config @@ -109,7 +111,7 @@ var rootCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { var err error - c := ctx.New(&CFG, LOG) + c := ctx.New(EMBEDFS, &CFG, LOG) _ = loadSystems(&c) // TODO: Handle errs tui := tea.NewProgram(ui.NewModel(&c), tea.WithAltScreen()) @@ -120,7 +122,8 @@ var rootCmd = &cobra.Command{ }, } -func Execute() { +func Execute(efs *embed.FS) { + EMBEDFS = efs if err := rootCmd.Execute(); err != nil { // LOG.Errorln(err) } diff --git a/gobbs.go b/gobbs.go index 4f00046..3be7ac5 100644 --- a/gobbs.go +++ b/gobbs.go @@ -1,7 +1,14 @@ package main -import "github.com/mrusme/gobbs/cmd" +import ( + "embed" + + "github.com/mrusme/gobbs/cmd" +) + +//go:embed splashscreen.png +var EMBEDFS embed.FS func main() { - cmd.Execute() + cmd.Execute(&EMBEDFS) } diff --git a/ui/cmd/cmd.go b/ui/cmd/cmd.go index c83fee4..9fff51a 100644 --- a/ui/cmd/cmd.go +++ b/ui/cmd/cmd.go @@ -12,6 +12,7 @@ const ( WinRefreshData WinFreshData + ViewOpen ViewFocus ViewBlur ViewRefreshData diff --git a/ui/ctx/ctx.go b/ui/ctx/ctx.go index 020487a..ff38c9f 100644 --- a/ui/ctx/ctx.go +++ b/ui/ctx/ctx.go @@ -1,6 +1,8 @@ package ctx import ( + "embed" + "github.com/mrusme/gobbs/config" "github.com/mrusme/gobbs/models/forum" "github.com/mrusme/gobbs/system" @@ -12,6 +14,7 @@ type Ctx struct { Screen [2]int Content [2]int Config *config.Config + EmbedFS *embed.FS Systems []*system.System Loading bool Logger *zap.SugaredLogger @@ -22,6 +25,7 @@ type Ctx struct { } func New( + efs *embed.FS, cfg *config.Config, logger *zap.SugaredLogger, ) Ctx { @@ -29,6 +33,7 @@ func New( Screen: [2]int{0, 0}, Content: [2]int{0, 0}, Config: cfg, + EmbedFS: efs, Loading: false, Logger: logger, Theme: theme.New(cfg), diff --git a/ui/ui.go b/ui/ui.go index ece50da..790bf36 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -12,6 +12,7 @@ import ( "github.com/mrusme/gobbs/ui/ctx" "github.com/mrusme/gobbs/ui/header" "github.com/mrusme/gobbs/ui/views/posts" + "github.com/mrusme/gobbs/ui/views/splash" "github.com/mrusme/gobbs/ui/windowmanager" "github.com/mrusme/gobbs/ui/windows/msgerror" "github.com/mrusme/gobbs/ui/windows/popuplist" @@ -74,6 +75,7 @@ func NewModel(c *ctx.Ctx) Model { } m.header = header.NewModel(m.ctx) + m.views = append(m.views, splash.NewModel(m.ctx)) m.views = append(m.views, posts.NewModel(m.ctx)) m.a, _ = aggregator.New(m.ctx) @@ -84,8 +86,6 @@ func NewModel(c *ctx.Ctx) Model { func (m Model) Init() tea.Cmd { return tea.Batch( tea.EnterAltScreen, - cmd.New(cmd.ViewFocus, "*").Tea(), - cmd.New(cmd.ViewRefreshData, "*").Tea(), ) } @@ -199,6 +199,19 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg.Call { + case cmd.ViewOpen: + m.ctx.Logger.Debug("got cmd.ViewOpen") + switch msg.Target { + case posts.VIEW_ID: + m.currentView = 1 + m.viewcache = m.buildView(false) + ccmds = append(ccmds, + cmd.New(cmd.ViewFocus, "*").Tea(), + cmd.New(cmd.ViewRefreshData, "*").Tea(), + ) + return m, tea.Batch(ccmds...) + } + case cmd.WinOpen: switch msg.Target { case postshow.WIN_ID: @@ -314,7 +327,9 @@ func (m Model) buildView(cached bool) string { } else { m.ctx.Logger.Debug("generating UI viewcache") m.renderOnlyFocused = false - s.WriteString(m.header.View() + "\n") + if m.currentView > 0 { + s.WriteString(m.header.View() + "\n") + } s.WriteString(m.views[m.currentView].View()) tmp = s.String() } diff --git a/ui/views/splash/splash.go b/ui/views/splash/splash.go new file mode 100644 index 0000000..d65afb0 --- /dev/null +++ b/ui/views/splash/splash.go @@ -0,0 +1,97 @@ +package splash + +import ( + "bytes" + "image/color" + "time" + + tea "github.com/charmbracelet/bubbletea" + "github.com/eliukblau/pixterm/pkg/ansimage" + "github.com/mrusme/gobbs/ui/cmd" + "github.com/mrusme/gobbs/ui/ctx" + "github.com/mrusme/gobbs/ui/views/posts" +) + +var ( + VIEW_ID = "splash" +) + +type Model struct { + ctx *ctx.Ctx + pix *ansimage.ANSImage + splashscreen []byte +} + +func (m Model) Init() tea.Cmd { + return nil +} + +func NewModel(c *ctx.Ctx) Model { + var err error + + m := Model{ + ctx: c, + pix: nil, + } + + m.splashscreen, err = m.ctx.EmbedFS.ReadFile("splashscreen.png") + if err != nil { + m.ctx.Logger.Error(err) + } + + m.ctx.Logger.Debugf("Screen W/H: %d %d\n", m.ctx.Screen[0], m.ctx.Screen[1]) + + return m +} + +func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + var err error + + // var lcmd tea.Cmd + // m.list, lcmd = m.list.Update(msg) + // cmds = append(cmds, lcmd) + switch msg := msg.(type) { + case tea.WindowSizeMsg: + m.ctx.Screen[0] = msg.Width + m.ctx.Screen[1] = msg.Height + m.pix, err = ansimage.NewScaledFromReader( + bytes.NewReader(m.splashscreen), + m.ctx.Screen[1], + m.ctx.Screen[0], + color.Transparent, + ansimage.ScaleModeResize, + ansimage.NoDithering, + ) + if err != nil { + m.ctx.Logger.Error(err) + } + return m, m.sleep() + + } + + return m, nil +} + +func (m *Model) sleep() tea.Cmd { + return func() tea.Msg { + time.Sleep(time.Second * 5) + + c := cmd.New( + cmd.ViewOpen, + posts.VIEW_ID, + ) + return *c + } +} + +func (m Model) View() string { + return m.buildView(true) +} + +func (m Model) buildView(cached bool) string { + if m.pix != nil { + return m.pix.RenderExt(false, false) + } + + return "" +}