diff --git a/go.mod b/go.mod index 9fdfb9c..f28bdd3 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.13 require ( github.com/charmbracelet/boba v0.5.0 - github.com/charmbracelet/charm v0.2.3 + github.com/charmbracelet/charm v0.3.0 github.com/charmbracelet/glamour v0.2.0 github.com/charmbracelet/tea v0.3.0 github.com/charmbracelet/teaparty v0.0.0-20200504225426-da64445a0e0d @@ -12,5 +12,5 @@ require ( github.com/spf13/cobra v0.0.7 golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 // indirect - golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 + golang.org/x/sys v0.0.0-20200513112337-417ce2331b5c ) diff --git a/go.sum b/go.sum index 0de20b4..c2512ce 100644 --- a/go.sum +++ b/go.sum @@ -15,16 +15,14 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/calmh/randomart v1.1.0 h1:evl+iwc10LXtHdMZhzLxmsCQVmWnkXs44SbC6Uk0Il8= github.com/calmh/randomart v1.1.0/go.mod h1:DQUbPVyP+7PAs21w/AnfMKG5NioxS3TbZ2F9MSK/jFM= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/charmbracelet/boba v0.5.0 h1:H+4m+yI1aHoE/o0ncrFQpgV2tY49MdzcLsOqethsuDs= github.com/charmbracelet/boba v0.5.0/go.mod h1:xqhji08CbPctzbvCi/GzmNvIFOhnWJnkl9N8T65gnK0= -github.com/charmbracelet/charm v0.2.3 h1:PknJo1r28itf5Q0p2vuJUewvHyVZl42G0x8zPOK2aHY= -github.com/charmbracelet/charm v0.2.3/go.mod h1:Ll7xHXpIWcIflSyzP01QzwxCF+kqVVCSnVDN0MMOfSs= +github.com/charmbracelet/charm v0.3.0 h1:njtvry/gqxUlFyVJ0+VbClcyf6g7mK6RddwT21mJoSA= +github.com/charmbracelet/charm v0.3.0/go.mod h1:bZQON+c4uV9mgbZBvKzH7wA1zGII9Zfg26cL70NYdH0= github.com/charmbracelet/glamour v0.2.0 h1:mTgaiNiumpqTZp3qVM6DH9UB0NlbY17wejoMf1kM8Pg= github.com/charmbracelet/glamour v0.2.0/go.mod h1:UA27Kwj3QHialP74iU6C+Gpc8Y7IOAKupeKMLLBURWM= github.com/charmbracelet/tea v0.2.0/go.mod h1:lADjwO2mMub9qvXSCA9vAkabVWO0HeUrv4uO/lG3C+k= -github.com/charmbracelet/tea v0.2.1/go.mod h1:uA/DUzCuyIZ1NFyAdCz6k+gF8lspujo6ZvoavcSsLCM= -github.com/charmbracelet/tea v0.3.0 h1:W5F1x/IYeSCKpZl3/hM3Mn5v2KAagckabDFhhzh5sIE= github.com/charmbracelet/tea v0.3.0/go.mod h1:uA/DUzCuyIZ1NFyAdCz6k+gF8lspujo6ZvoavcSsLCM= -github.com/charmbracelet/teaparty v0.0.0-20200504225426-da64445a0e0d h1:cKZmktu4U8kTcaKM1JjM0jILREm2ABBoh5YLdrfCykQ= github.com/charmbracelet/teaparty v0.0.0-20200504225426-da64445a0e0d/go.mod h1:PsGcwPVbwjZv3XGW7qGoJ+EkhKqk2owMVUuX3IBUsTw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -149,7 +147,6 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -177,8 +174,9 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200430202703-d923437fa56d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 h1:5B6i6EAiSYyejWfvc5Rc9BbI3rzIsrrXfAQBWnYfn+w= golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200513112337-417ce2331b5c h1:kISX68E8gSkNYAFRFiDU8rl5RIn1sJYKYb/r2vMLDrU= +golang.org/x/sys v0.0.0-20200513112337-417ce2331b5c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/ui/stash.go b/ui/stash.go new file mode 100644 index 0000000..389c087 --- /dev/null +++ b/ui/stash.go @@ -0,0 +1,97 @@ +package ui + +import ( + "github.com/charmbracelet/boba" + "github.com/charmbracelet/boba/spinner" + "github.com/charmbracelet/charm" + "github.com/charmbracelet/charm/ui/common" +) + +// MSG + +type stashErrMsg error + +type gotStashMsg []*charm.Markdown + +// MODEL + +type stashState int + +const ( + stashStateInit stashState = 1 << iota + stashStateStashLoaded +) + +type stashModel struct { + cc *charm.Client + err error + state stashState + documents []*charm.Markdown + page int + spinner spinner.Model +} + +// INIT + +func stashInit(cc *charm.Client) (stashModel, boba.Cmd) { + s := spinner.NewModel() + s.Type = spinner.Dot + s.ForegroundColor = common.SpinnerColor + + m := stashModel{ + cc: cc, + spinner: s, + } + + return m, boba.Batch( + getStash(m), + spinner.Tick(s), + ) +} + +// UPDATE + +func stashUpdate(msg boba.Msg, m stashModel) (stashModel, boba.Cmd) { + switch msg := msg.(type) { + + case stashErrMsg: + m.err = msg + + case gotStashMsg: + m.documents = msg + m.state |= stashStateStashLoaded + + case spinner.TickMsg: + if (m.state & stashStateStashLoaded) == 0 { + var cmd boba.Cmd + m.spinner, cmd = spinner.Update(msg, m.spinner) + return m, cmd + } + return m, nil + } + + return m, nil +} + +// VIEW + +func stashView(m stashModel) string { + var s string + if (m.state & stashStateStashLoaded) != 0 { + + } + s += spinner.View(m.spinner) + " Loading stash..." + return s + "\n" +} + +// CMD + +func getStash(m stashModel) boba.Cmd { + return func() boba.Msg { + stash, err := m.cc.GetStash(m.page) + if err != nil { + return stashErrMsg(err) + } + return gotStashMsg(stash) + } +} diff --git a/ui/ui.go b/ui/ui.go index 64456f9..36ec67c 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -3,16 +3,16 @@ package ui import ( "errors" + "github.com/charmbracelet/boba" + "github.com/charmbracelet/boba/spinner" "github.com/charmbracelet/charm" "github.com/charmbracelet/charm/ui/common" "github.com/charmbracelet/charm/ui/keygen" - "github.com/charmbracelet/tea" - "github.com/charmbracelet/teaparty/spinner" ) -// NewProgram returns a new Tea program -func NewProgram() *tea.Program { - return tea.NewProgram(initialize, update, view, subscriptions) +// NewProgram returns a new Boba program +func NewProgram() *boba.Program { + return boba.NewProgram(initialize, update, view) } // MESSAGES @@ -30,7 +30,7 @@ const ( stateInitCharmClient state = iota stateKeygenRunning stateKeygenFinished - stateReady + stateShowStash ) type model struct { @@ -44,38 +44,41 @@ type model struct { // INIT -func initialize() (tea.Model, tea.Cmd) { +func initialize() (boba.Model, boba.Cmd) { s := spinner.NewModel() s.Type = spinner.Dot s.ForegroundColor = common.SpinnerColor return model{ - spinner: s, - state: stateInitCharmClient, - }, newCharmClient + spinner: s, + state: stateInitCharmClient, + }, boba.Batch( + newCharmClient, + spinner.Tick(s), + ) } // UPDATE -func update(msg tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) { +func update(msg boba.Msg, mdl boba.Model) (boba.Model, boba.Cmd) { m, ok := mdl.(model) if !ok { - return model{err: errors.New("could not perform assertion on model in update")}, tea.Quit + return model{err: errors.New("could not perform assertion on model in update")}, boba.Quit } switch msg := msg.(type) { - case tea.KeyMsg: + case boba.KeyMsg: switch msg.String() { case "ctrl+c": - return m, tea.Quit + return m, boba.Quit default: return m, nil } case fatalErrMsg: m.err = msg - return m, tea.Quit + return m, boba.Quit case errMsg: m.err = msg @@ -91,11 +94,14 @@ func update(msg tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) { // The keygen didn't work m.err = errors.New("SSH authentication failed") - return m, tea.Quit + return m, boba.Quit case spinner.TickMsg: - m.spinner, _ = spinner.Update(msg, m.spinner) - return m, nil + if m.state == stateInitCharmClient { + var cmd boba.Cmd + m.spinner, cmd = spinner.Update(msg, m.spinner) + return m, cmd + } case keygen.DoneMsg: m.state = stateKeygenFinished @@ -103,28 +109,30 @@ func update(msg tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) { case newCharmClientMsg: m.cc = msg - m.state = stateReady + m.state = stateShowStash return m, nil default: switch m.state { case stateKeygenRunning: - mdl, cmd := keygen.Update(msg, tea.Model(m.keygen)) + mdl, cmd := keygen.Update(msg, boba.Model(m.keygen)) keygenModel, ok := mdl.(keygen.Model) if !ok { m.err = errors.New("could not perform assertion on keygen model in main update") - return m, tea.Quit + return m, boba.Quit } m.keygen = keygenModel return m, cmd } return m, nil } + + return m, nil } // VIEW -func view(mdl tea.Model) string { +func view(mdl boba.Model) string { m, ok := mdl.(model) if !ok { return "could not perform assertion on model in view" @@ -142,43 +150,15 @@ func view(mdl tea.Model) string { s += keygen.View(m.keygen) case stateKeygenFinished: s += spinner.View(m.spinner) + " Re-initializing..." - case stateReady: + case stateShowStash: s += "Ready." } - return s -} - -// SUBSCRIPTIONS - -func subscriptions(mdl tea.Model) tea.Subs { - m, ok := mdl.(model) - if !ok { - return nil - } - - subs := make(tea.Subs) - - switch m.state { - case stateInitCharmClient: - fallthrough - case stateKeygenFinished: - sub, err := spinner.MakeSub(m.spinner) - if err == nil { - subs["glow-spin"] = sub - } - case stateKeygenRunning: - sub, err := keygen.Spin(m.keygen) - if err == nil { - subs["keygen-spin"] = sub - } - } - - return subs + return s + "\n" } // COMMANDS -func newCharmClient() tea.Msg { +func newCharmClient() boba.Msg { cfg, err := charm.ConfigFromEnv() if err != nil { return fatalErrMsg(err)