1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-12-14 11:23:09 +02:00
lazygit/pkg/gui/popup/popup_handler.go

198 lines
4.8 KiB
Go
Raw Normal View History

2022-01-28 11:44:36 +02:00
package popup
import (
"strings"
"sync"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/common"
"github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
)
type RealPopupHandler struct {
*common.Common
index int
sync.Mutex
2022-01-29 10:09:20 +02:00
createPopupPanelFn func(types.CreatePopupPanelOpts) error
2022-01-28 11:44:36 +02:00
onErrorFn func() error
closePopupFn func() error
2022-01-29 10:09:20 +02:00
createMenuFn func(types.CreateMenuOptions) error
2022-01-28 11:44:36 +02:00
withWaitingStatusFn func(message string, f func() error) error
toastFn func(message string)
getPromptInputFn func() string
2022-01-28 11:44:36 +02:00
}
2022-01-29 10:09:20 +02:00
var _ types.IPopupHandler = &RealPopupHandler{}
2022-01-28 11:44:36 +02:00
func NewPopupHandler(
common *common.Common,
2022-01-29 10:09:20 +02:00
createPopupPanelFn func(types.CreatePopupPanelOpts) error,
2022-01-28 11:44:36 +02:00
onErrorFn func() error,
closePopupFn func() error,
2022-01-29 10:09:20 +02:00
createMenuFn func(types.CreateMenuOptions) error,
2022-01-28 11:44:36 +02:00
withWaitingStatusFn func(message string, f func() error) error,
toastFn func(message string),
getPromptInputFn func() string,
2022-01-28 11:44:36 +02:00
) *RealPopupHandler {
return &RealPopupHandler{
Common: common,
index: 0,
createPopupPanelFn: createPopupPanelFn,
onErrorFn: onErrorFn,
closePopupFn: closePopupFn,
createMenuFn: createMenuFn,
withWaitingStatusFn: withWaitingStatusFn,
toastFn: toastFn,
getPromptInputFn: getPromptInputFn,
2022-01-28 11:44:36 +02:00
}
}
2022-01-29 10:09:20 +02:00
func (self *RealPopupHandler) Menu(opts types.CreateMenuOptions) error {
2022-01-28 11:44:36 +02:00
return self.createMenuFn(opts)
}
func (self *RealPopupHandler) Toast(message string) {
self.toastFn(message)
}
2022-01-28 11:44:36 +02:00
func (self *RealPopupHandler) WithWaitingStatus(message string, f func() error) error {
return self.withWaitingStatusFn(message, f)
}
func (self *RealPopupHandler) Error(err error) error {
if err == gocui.ErrQuit {
return err
}
return self.ErrorMsg(err.Error())
}
func (self *RealPopupHandler) ErrorMsg(message string) error {
self.Lock()
self.index++
self.Unlock()
coloredMessage := style.FgRed.Sprint(strings.TrimSpace(message))
if err := self.onErrorFn(); err != nil {
return err
}
2022-01-29 10:09:20 +02:00
return self.Ask(types.AskOpts{
2022-01-28 11:44:36 +02:00
Title: self.Tr.Error,
Prompt: coloredMessage,
})
}
2022-01-29 10:09:20 +02:00
func (self *RealPopupHandler) Ask(opts types.AskOpts) error {
2022-01-28 11:44:36 +02:00
self.Lock()
self.index++
self.Unlock()
2022-01-29 10:09:20 +02:00
return self.createPopupPanelFn(types.CreatePopupPanelOpts{
2022-01-28 11:44:36 +02:00
Title: opts.Title,
Prompt: opts.Prompt,
HandleConfirm: opts.HandleConfirm,
HandleClose: opts.HandleClose,
HandlersManageFocus: opts.HandlersManageFocus,
})
}
2022-01-29 10:09:20 +02:00
func (self *RealPopupHandler) Prompt(opts types.PromptOpts) error {
2022-01-28 11:44:36 +02:00
self.Lock()
self.index++
self.Unlock()
2022-01-29 10:09:20 +02:00
return self.createPopupPanelFn(types.CreatePopupPanelOpts{
2022-01-28 11:44:36 +02:00
Title: opts.Title,
Prompt: opts.InitialContent,
Editable: true,
HandleConfirmPrompt: opts.HandleConfirm,
2022-02-23 10:44:48 +02:00
HandleClose: opts.HandleClose,
2022-01-28 11:44:36 +02:00
FindSuggestionsFunc: opts.FindSuggestionsFunc,
2022-02-23 10:44:48 +02:00
Mask: opts.Mask,
2022-01-28 11:44:36 +02:00
})
}
func (self *RealPopupHandler) WithLoaderPanel(message string, f func() error) error {
index := 0
self.Lock()
self.index++
index = self.index
self.Unlock()
2022-01-29 10:09:20 +02:00
err := self.createPopupPanelFn(types.CreatePopupPanelOpts{
2022-01-28 11:44:36 +02:00
Prompt: message,
HasLoader: true,
})
if err != nil {
self.Log.Error(err)
return nil
}
go utils.Safe(func() {
if err := f(); err != nil {
self.Log.Error(err)
}
self.Lock()
if index == self.index {
_ = self.closePopupFn()
}
self.Unlock()
})
return nil
}
// returns the content that has currently been typed into the prompt. Useful for
// asyncronously updating the suggestions list under the prompt.
func (self *RealPopupHandler) GetPromptInput() string {
return self.getPromptInputFn()
}
2022-01-28 11:44:36 +02:00
type TestPopupHandler struct {
OnErrorMsg func(message string) error
2022-01-29 10:09:20 +02:00
OnAsk func(opts types.AskOpts) error
OnPrompt func(opts types.PromptOpts) error
2022-01-28 11:44:36 +02:00
}
2022-01-29 10:09:20 +02:00
var _ types.IPopupHandler = &TestPopupHandler{}
2022-01-23 05:40:28 +02:00
2022-01-28 11:44:36 +02:00
func (self *TestPopupHandler) Error(err error) error {
return self.ErrorMsg(err.Error())
}
func (self *TestPopupHandler) ErrorMsg(message string) error {
return self.OnErrorMsg(message)
}
2022-01-29 10:09:20 +02:00
func (self *TestPopupHandler) Ask(opts types.AskOpts) error {
2022-01-28 11:44:36 +02:00
return self.OnAsk(opts)
}
2022-01-29 10:09:20 +02:00
func (self *TestPopupHandler) Prompt(opts types.PromptOpts) error {
2022-01-28 11:44:36 +02:00
return self.OnPrompt(opts)
}
func (self *TestPopupHandler) WithLoaderPanel(message string, f func() error) error {
return f()
}
func (self *TestPopupHandler) WithWaitingStatus(message string, f func() error) error {
return f()
}
2022-01-29 10:09:20 +02:00
func (self *TestPopupHandler) Menu(opts types.CreateMenuOptions) error {
2022-01-28 11:44:36 +02:00
panic("not yet implemented")
}
func (self *TestPopupHandler) Toast(message string) {
panic("not yet implemented")
}
2022-01-23 05:40:28 +02:00
func (self *TestPopupHandler) GetPromptInput() string {
panic("not yet implemented")
}