restructure project following best practices
https://go.dev/doc/modules/layout This also enables us to later import just the db interaction part say to the gemini capsule backend go project.
This commit is contained in:
parent
928c82536f
commit
360fedbebe
11 changed files with 202 additions and 169 deletions
|
|
@ -1,6 +0,0 @@
|
||||||
package gemlog
|
|
||||||
|
|
||||||
type Notification string
|
|
||||||
type ErrorMsg struct{ err error }
|
|
||||||
type GemLogsLoaded struct{ Logs []GemlogListEntry }
|
|
||||||
type GemLogLoaded struct{ Log GemlogEntry }
|
|
||||||
|
|
@ -16,7 +16,7 @@ func genBasicAuthHeader(user, password string) string {
|
||||||
return fmt.Sprintf("Basic %s", auth)
|
return fmt.Sprintf("Basic %s", auth)
|
||||||
}
|
}
|
||||||
|
|
||||||
func listGemLogs(config *Config) ([]GemlogListEntry, error) {
|
func ListGemLogs(config *Config) ([]GemlogListEntry, error) {
|
||||||
url := fmt.Sprintf("%s:%d/gemlog/_design/gemlog-cli/_view/list", config.CouchDB.Host, config.CouchDB.Port)
|
url := fmt.Sprintf("%s:%d/gemlog/_design/gemlog-cli/_view/list", config.CouchDB.Host, config.CouchDB.Port)
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -1,4 +1,4 @@
|
||||||
module gemlog-cli
|
module git.travisshears.com/travisshears/gemlog-cli
|
||||||
|
|
||||||
go 1.25.0
|
go 1.25.0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
package main
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"gemini_site/gemlog"
|
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
)
|
)
|
||||||
|
|
@ -51,7 +50,7 @@ func (m ActionListPageModel) Update(msg tea.Msg, active bool, ctx *context) (Act
|
||||||
action := actions[m.cursor]
|
action := actions[m.cursor]
|
||||||
switch action {
|
switch action {
|
||||||
case Write:
|
case Write:
|
||||||
return m, gemlog.WritePostCMD(ctx.config)
|
return m, WritePostCMD(ctx.config)
|
||||||
case Read, Delete, Edit:
|
case Read, Delete, Edit:
|
||||||
switchPageCmd := func() tea.Msg {
|
switchPageCmd := func() tea.Msg {
|
||||||
return SwitchPages{Page: EntryList}
|
return SwitchPages{Page: EntryList}
|
||||||
|
|
@ -59,7 +58,7 @@ func (m ActionListPageModel) Update(msg tea.Msg, active bool, ctx *context) (Act
|
||||||
actionToTakeCmd := func() tea.Msg {
|
actionToTakeCmd := func() tea.Msg {
|
||||||
return SelectActionToTake{ActionToTake: action}
|
return SelectActionToTake{ActionToTake: action}
|
||||||
}
|
}
|
||||||
loadGemLogsCmd := gemlog.LoadGemlogsCMD(ctx.config)
|
loadGemLogsCmd := LoadGemlogsCMD(ctx.config)
|
||||||
return m, tea.Batch(switchPageCmd, loadGemLogsCmd, actionToTakeCmd)
|
return m, tea.Batch(switchPageCmd, loadGemLogsCmd, actionToTakeCmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
151
internal/ui/app.go
Normal file
151
internal/ui/app.go
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
gemlog "git.travisshears.com/travisshears/gemlog-cli/gemlog"
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Page string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ActionList Page = "actionList"
|
||||||
|
EntryList Page = "entryList"
|
||||||
|
Entry Page = "entry"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SwitchPages struct{ Page Page }
|
||||||
|
type Notification string
|
||||||
|
type ErrorMsg struct{ err error }
|
||||||
|
type GemLogsLoaded struct{ Logs []gemlog.GemlogListEntry }
|
||||||
|
type GemLogLoaded struct{ Log gemlog.GemlogEntry }
|
||||||
|
|
||||||
|
type uiState struct {
|
||||||
|
notification string
|
||||||
|
errorTxt string
|
||||||
|
|
||||||
|
page Page
|
||||||
|
entryListPage EntryListPageModel
|
||||||
|
entryPage EntryPageModel
|
||||||
|
actionListPage ActionListPageModel
|
||||||
|
}
|
||||||
|
|
||||||
|
type context struct {
|
||||||
|
config *gemlog.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
type model struct {
|
||||||
|
ui uiState
|
||||||
|
context *context
|
||||||
|
}
|
||||||
|
|
||||||
|
func initialModel(config *gemlog.Config) model {
|
||||||
|
return model{
|
||||||
|
ui: uiState{
|
||||||
|
page: ActionList,
|
||||||
|
actionListPage: initialActionListPageModel(),
|
||||||
|
entryListPage: initialEntryListPageModel(),
|
||||||
|
entryPage: initialEntryPageModel(),
|
||||||
|
},
|
||||||
|
context: &context{
|
||||||
|
config: config,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m model) Init() tea.Cmd {
|
||||||
|
cmds := make([]tea.Cmd, 0)
|
||||||
|
cmds = append(cmds, tea.SetWindowTitle("Gemlog CLI"))
|
||||||
|
// TODO: add init commands from other pages
|
||||||
|
return tea.Batch(cmds...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
|
cmds := make([]tea.Cmd, 3)
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case SwitchPages:
|
||||||
|
m.ui.page = msg.Page
|
||||||
|
case ErrorMsg:
|
||||||
|
m.ui.errorTxt = fmt.Sprintf("%s\n\n", fmt.Errorf("%s", msg))
|
||||||
|
case Notification:
|
||||||
|
m.ui.notification = fmt.Sprintf("%s\n\n", string(msg))
|
||||||
|
case tea.KeyMsg:
|
||||||
|
switch msg.String() {
|
||||||
|
case "ctrl+c", "q":
|
||||||
|
return m, tea.Quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actionListM, cmd := m.ui.actionListPage.Update(msg, m.ui.page == ActionList, m.context)
|
||||||
|
m.ui.actionListPage = actionListM
|
||||||
|
cmds = append(cmds, cmd)
|
||||||
|
|
||||||
|
entryListM, cmd := m.ui.entryListPage.Update(msg, m.ui.page == EntryList, m.context)
|
||||||
|
m.ui.entryListPage = entryListM
|
||||||
|
cmds = append(cmds, cmd)
|
||||||
|
|
||||||
|
entrytM, cmd := m.ui.entryPage.Update(msg, m.ui.page == Entry, m.context)
|
||||||
|
m.ui.entryPage = entrytM
|
||||||
|
cmds = append(cmds, cmd)
|
||||||
|
|
||||||
|
return m, tea.Batch(cmds...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m model) View() string {
|
||||||
|
if len(m.ui.errorTxt) > 0 {
|
||||||
|
return m.ui.errorTxt
|
||||||
|
}
|
||||||
|
s := ""
|
||||||
|
if m.ui.notification != "" {
|
||||||
|
s += m.ui.notification
|
||||||
|
}
|
||||||
|
|
||||||
|
switch m.ui.page {
|
||||||
|
case ActionList:
|
||||||
|
s += m.ui.actionListPage.View()
|
||||||
|
case EntryList:
|
||||||
|
s += m.ui.entryListPage.View()
|
||||||
|
case Entry:
|
||||||
|
s += m.ui.entryPage.View()
|
||||||
|
}
|
||||||
|
|
||||||
|
s += "\nPress q to quit.\n"
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
var enableLogs bool = false
|
||||||
|
|
||||||
|
func Run() {
|
||||||
|
if enableLogs {
|
||||||
|
f, err := tea.LogToFile("debug.log", "debug")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("fatal:", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
} else {
|
||||||
|
logger := slog.New(slog.NewJSONHandler(io.Discard, nil))
|
||||||
|
slog.SetDefault(logger)
|
||||||
|
}
|
||||||
|
slog.Info("Starting gemlog cli")
|
||||||
|
config, err := gemlog.LoadConfig()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error loading config: %v", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = gemlog.CheckDBConnection(config)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error checking db connection: %v", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
p := tea.NewProgram(initialModel(config))
|
||||||
|
if _, err := p.Run(); err != nil {
|
||||||
|
fmt.Printf("Alas, there's been an error: %v", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
package gemlog
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
gemlog "git.travisshears.com/travisshears/gemlog-cli/gemlog"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DeleteGemlogCMD(config *Config, id string, rev string) tea.Cmd {
|
func DeleteGemlogCMD(config *gemlog.Config, id string, rev string) tea.Cmd {
|
||||||
return func() tea.Msg {
|
return func() tea.Msg {
|
||||||
err := DeleteGemlogEntry(config, id, rev)
|
err := gemlog.DeleteGemlogEntry(config, id, rev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrorMsg{err}
|
return ErrorMsg{err}
|
||||||
}
|
}
|
||||||
|
|
@ -17,9 +18,9 @@ func DeleteGemlogCMD(config *Config, id string, rev string) tea.Cmd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadGemlogCMD(config *Config, id string) tea.Cmd {
|
func LoadGemlogCMD(config *gemlog.Config, id string) tea.Cmd {
|
||||||
return func() tea.Msg {
|
return func() tea.Msg {
|
||||||
log, err := ReadGemlogEntry(config, id)
|
log, err := gemlog.ReadGemlogEntry(config, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrorMsg{err}
|
return ErrorMsg{err}
|
||||||
}
|
}
|
||||||
|
|
@ -27,9 +28,9 @@ func LoadGemlogCMD(config *Config, id string) tea.Cmd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadGemlogsCMD(config *Config) tea.Cmd {
|
func LoadGemlogsCMD(config *gemlog.Config) tea.Cmd {
|
||||||
return func() tea.Msg {
|
return func() tea.Msg {
|
||||||
logs, err := listGemLogs(config)
|
logs, err := gemlog.ListGemLogs(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrorMsg{err}
|
return ErrorMsg{err}
|
||||||
}
|
}
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
package main
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gemini_site/gemlog"
|
gemlog "git.travisshears.com/travisshears/gemlog-cli/gemlog"
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -16,7 +15,7 @@ func initialEntryPageModel() EntryPageModel {
|
||||||
|
|
||||||
func (m EntryPageModel) Update(msg tea.Msg, active bool, ctx *context) (EntryPageModel, tea.Cmd) {
|
func (m EntryPageModel) Update(msg tea.Msg, active bool, ctx *context) (EntryPageModel, tea.Cmd) {
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
case gemlog.GemLogLoaded:
|
case GemLogLoaded:
|
||||||
m.entry = msg.Log
|
m.entry = msg.Log
|
||||||
case tea.KeyMsg:
|
case tea.KeyMsg:
|
||||||
if !active {
|
if !active {
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
package main
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"gemini_site/gemlog"
|
|
||||||
|
|
||||||
|
gemlog "git.travisshears.com/travisshears/gemlog-cli/gemlog"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -26,7 +26,7 @@ func (m EntryListPageModel) Update(msg tea.Msg, active bool, ctx *context) (Entr
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
case SelectActionToTake:
|
case SelectActionToTake:
|
||||||
m.actionToTake = msg.ActionToTake
|
m.actionToTake = msg.ActionToTake
|
||||||
case gemlog.GemLogsLoaded:
|
case GemLogsLoaded:
|
||||||
m.entries = msg.Logs
|
m.entries = msg.Logs
|
||||||
return m, nil
|
return m, nil
|
||||||
case tea.KeyMsg:
|
case tea.KeyMsg:
|
||||||
|
|
@ -54,14 +54,14 @@ func (m EntryListPageModel) Update(msg tea.Msg, active bool, ctx *context) (Entr
|
||||||
switch m.actionToTake {
|
switch m.actionToTake {
|
||||||
// TODO: handle edit
|
// TODO: handle edit
|
||||||
case Read:
|
case Read:
|
||||||
loadCmd := gemlog.LoadGemlogCMD(ctx.config, id)
|
loadCmd := LoadGemlogCMD(ctx.config, id)
|
||||||
navCmd := func() tea.Msg {
|
navCmd := func() tea.Msg {
|
||||||
return SwitchPages{Page: Entry}
|
return SwitchPages{Page: Entry}
|
||||||
}
|
}
|
||||||
return m, tea.Sequence(loadCmd, navCmd)
|
return m, tea.Sequence(loadCmd, navCmd)
|
||||||
case Delete:
|
case Delete:
|
||||||
delCmd := gemlog.DeleteGemlogCMD(ctx.config, id, rev)
|
delCmd := DeleteGemlogCMD(ctx.config, id, rev)
|
||||||
loadCmd := gemlog.LoadGemlogsCMD(ctx.config)
|
loadCmd := LoadGemlogsCMD(ctx.config)
|
||||||
navCmd := func() tea.Msg {
|
navCmd := func() tea.Msg {
|
||||||
return SwitchPages{Page: ActionList}
|
return SwitchPages{Page: ActionList}
|
||||||
}
|
}
|
||||||
15
internal/ui/templates.go
Normal file
15
internal/ui/templates.go
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
package ui
|
||||||
|
|
||||||
|
const defaultTemplate = `title: todo
|
||||||
|
date: 2025-12-31
|
||||||
|
slug: todo
|
||||||
|
tags: cat, dog
|
||||||
|
---
|
||||||
|
|
||||||
|
Example text
|
||||||
|
|
||||||
|
=> https://travisshears.com example link
|
||||||
|
|
||||||
|
* Example list item 1
|
||||||
|
* Example list item 2
|
||||||
|
`
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package gemlog
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -7,11 +7,15 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
gemlog "git.travisshears.com/travisshears/gemlog-cli/gemlog"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func WritePostCMD(config *Config) tea.Cmd {
|
// TODO: add edit command
|
||||||
|
// func EditPostCMD(config *gemlog.Config) tea.Cmd {}
|
||||||
|
|
||||||
|
func WritePostCMD(config *gemlog.Config) tea.Cmd {
|
||||||
return func() tea.Msg {
|
return func() tea.Msg {
|
||||||
// Create a temporary file
|
// Create a temporary file
|
||||||
tmpFile, err := os.CreateTemp("/tmp", "gemlog-*.md")
|
tmpFile, err := os.CreateTemp("/tmp", "gemlog-*.md")
|
||||||
|
|
@ -61,7 +65,7 @@ func WritePostCMD(config *Config) tea.Cmd {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrorMsg{fmt.Errorf("failed to parse post: %w", err)}
|
return ErrorMsg{fmt.Errorf("failed to parse post: %w", err)}
|
||||||
}
|
}
|
||||||
if err := SaveGemlogEntry(config, &gemlogEntry); err != nil {
|
if err := gemlog.SaveGemlogEntry(config, &gemlogEntry); err != nil {
|
||||||
return ErrorMsg{fmt.Errorf("failed to save gemlog entry: %w", err)}
|
return ErrorMsg{fmt.Errorf("failed to save gemlog entry: %w", err)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,7 +75,7 @@ func WritePostCMD(config *Config) tea.Cmd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parsePost(post string) (GemlogEntry, error) {
|
func parsePost(post string) (gemlog.GemlogEntry, error) {
|
||||||
// split post on new lines
|
// split post on new lines
|
||||||
lines := strings.Split(post, "\n")
|
lines := strings.Split(post, "\n")
|
||||||
|
|
||||||
|
|
@ -85,7 +89,7 @@ func parsePost(post string) (GemlogEntry, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if separatorIndex == -1 {
|
if separatorIndex == -1 {
|
||||||
return GemlogEntry{}, fmt.Errorf("no frontmatter separator '---' found")
|
return gemlog.GemlogEntry{}, fmt.Errorf("no frontmatter separator '---' found")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract frontmatter and body
|
// Extract frontmatter and body
|
||||||
|
|
@ -103,13 +107,13 @@ func parsePost(post string) (GemlogEntry, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := yaml.Unmarshal([]byte(frontmatterYAML), &frontmatter); err != nil {
|
if err := yaml.Unmarshal([]byte(frontmatterYAML), &frontmatter); err != nil {
|
||||||
return GemlogEntry{}, fmt.Errorf("failed to parse frontmatter: %w", err)
|
return gemlog.GemlogEntry{}, fmt.Errorf("failed to parse frontmatter: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse date
|
// Parse date
|
||||||
date, err := time.Parse("2006-01-02", strings.TrimSpace(frontmatter.Date))
|
date, err := time.Parse("2006-01-02", strings.TrimSpace(frontmatter.Date))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return GemlogEntry{}, fmt.Errorf("failed to parse date: %w", err)
|
return gemlog.GemlogEntry{}, fmt.Errorf("failed to parse date: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse tags (comma-separated)
|
// Parse tags (comma-separated)
|
||||||
|
|
@ -127,7 +131,7 @@ func parsePost(post string) (GemlogEntry, error) {
|
||||||
// Join body lines
|
// Join body lines
|
||||||
body := strings.Join(bodyLines, "\n")
|
body := strings.Join(bodyLines, "\n")
|
||||||
|
|
||||||
return GemlogEntry{
|
return gemlog.GemlogEntry{
|
||||||
Title: frontmatter.Title,
|
Title: frontmatter.Title,
|
||||||
Date: date,
|
Date: date,
|
||||||
Slug: frontmatter.Slug,
|
Slug: frontmatter.Slug,
|
||||||
134
main.go
134
main.go
|
|
@ -1,139 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
ui "git.travisshears.com/travisshears/gemlog-cli/internal/ui"
|
||||||
"gemini_site/gemlog"
|
|
||||||
"log/slog"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Page string
|
|
||||||
|
|
||||||
const (
|
|
||||||
ActionList Page = "actionList"
|
|
||||||
EntryList Page = "entryList"
|
|
||||||
Entry Page = "entry"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SwitchPages struct{ Page Page }
|
|
||||||
|
|
||||||
type uiState struct {
|
|
||||||
notification string
|
|
||||||
errorTxt string
|
|
||||||
|
|
||||||
page Page
|
|
||||||
entryListPage EntryListPageModel
|
|
||||||
entryPage EntryPageModel
|
|
||||||
actionListPage ActionListPageModel
|
|
||||||
}
|
|
||||||
|
|
||||||
type context struct {
|
|
||||||
config *gemlog.Config
|
|
||||||
}
|
|
||||||
|
|
||||||
type model struct {
|
|
||||||
ui uiState
|
|
||||||
context *context
|
|
||||||
}
|
|
||||||
|
|
||||||
func initialModel(config *gemlog.Config) model {
|
|
||||||
return model{
|
|
||||||
ui: uiState{
|
|
||||||
page: ActionList,
|
|
||||||
actionListPage: initialActionListPageModel(),
|
|
||||||
entryListPage: initialEntryListPageModel(),
|
|
||||||
entryPage: initialEntryPageModel(),
|
|
||||||
},
|
|
||||||
context: &context{
|
|
||||||
config: config,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m model) Init() tea.Cmd {
|
|
||||||
cmds := make([]tea.Cmd, 0)
|
|
||||||
cmds = append(cmds, tea.SetWindowTitle("Gemlog CLI"))
|
|
||||||
// TODO: add init commands from other pages
|
|
||||||
return tea.Batch(cmds...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
||||||
cmds := make([]tea.Cmd, 3)
|
|
||||||
switch msg := msg.(type) {
|
|
||||||
case SwitchPages:
|
|
||||||
m.ui.page = msg.Page
|
|
||||||
case gemlog.ErrorMsg:
|
|
||||||
m.ui.errorTxt = fmt.Sprintf("%s\n\n", fmt.Errorf("%s", msg))
|
|
||||||
case gemlog.Notification:
|
|
||||||
m.ui.notification = fmt.Sprintf("%s\n\n", string(msg))
|
|
||||||
case tea.KeyMsg:
|
|
||||||
switch msg.String() {
|
|
||||||
case "ctrl+c", "q":
|
|
||||||
return m, tea.Quit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
actionListM, cmd := m.ui.actionListPage.Update(msg, m.ui.page == ActionList, m.context)
|
|
||||||
m.ui.actionListPage = actionListM
|
|
||||||
cmds = append(cmds, cmd)
|
|
||||||
|
|
||||||
entryListM, cmd := m.ui.entryListPage.Update(msg, m.ui.page == EntryList, m.context)
|
|
||||||
m.ui.entryListPage = entryListM
|
|
||||||
cmds = append(cmds, cmd)
|
|
||||||
|
|
||||||
entrytM, cmd := m.ui.entryPage.Update(msg, m.ui.page == Entry, m.context)
|
|
||||||
m.ui.entryPage = entrytM
|
|
||||||
cmds = append(cmds, cmd)
|
|
||||||
|
|
||||||
return m, tea.Batch(cmds...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m model) View() string {
|
|
||||||
if len(m.ui.errorTxt) > 0 {
|
|
||||||
return m.ui.errorTxt
|
|
||||||
}
|
|
||||||
s := ""
|
|
||||||
if m.ui.notification != "" {
|
|
||||||
s += m.ui.notification
|
|
||||||
}
|
|
||||||
|
|
||||||
switch m.ui.page {
|
|
||||||
case ActionList:
|
|
||||||
s += m.ui.actionListPage.View()
|
|
||||||
case EntryList:
|
|
||||||
s += m.ui.entryListPage.View()
|
|
||||||
case Entry:
|
|
||||||
s += m.ui.entryPage.View()
|
|
||||||
}
|
|
||||||
|
|
||||||
s += "\nPress q to quit.\n"
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
f, err := tea.LogToFile("debug.log", "debug")
|
ui.Run()
|
||||||
if err != nil {
|
|
||||||
fmt.Println("fatal:", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
slog.Info("Starting gemlog cli")
|
|
||||||
config, err := gemlog.LoadConfig()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Error loading config: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
err = gemlog.CheckDBConnection(config)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Error checking db connection: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
p := tea.NewProgram(initialModel(config))
|
|
||||||
if _, err := p.Run(); err != nil {
|
|
||||||
fmt.Printf("Alas, there's been an error: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue