2022-01-28 11:44:36 +02:00
|
|
|
package popup
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/jesseduffield/gocui"
|
|
|
|
"github.com/jesseduffield/lazygit/pkg/common"
|
2022-08-01 13:58:49 +02:00
|
|
|
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
2022-01-28 11:44:36 +02:00
|
|
|
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
|
|
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
|
|
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
2022-08-07 01:44:50 +02:00
|
|
|
"github.com/sasha-s/go-deadlock"
|
2022-01-28 11:44:36 +02:00
|
|
|
)
|
|
|
|
|
2022-05-07 07:42:36 +02:00
|
|
|
type PopupHandler struct {
|
2022-01-28 11:44:36 +02:00
|
|
|
*common.Common
|
|
|
|
index int
|
2022-08-07 01:44:50 +02:00
|
|
|
deadlock.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
|
2022-08-01 13:58:49 +02:00
|
|
|
popContextFn func() error
|
|
|
|
currentContextFn func() types.Context
|
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
|
2022-01-16 05:46:53 +02:00
|
|
|
toastFn func(message string)
|
|
|
|
getPromptInputFn func() string
|
2022-01-28 11:44:36 +02:00
|
|
|
}
|
|
|
|
|
2022-05-07 07:42:36 +02:00
|
|
|
var _ types.IPopupHandler = &PopupHandler{}
|
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,
|
2022-08-01 13:58:49 +02:00
|
|
|
popContextFn func() error,
|
|
|
|
currentContextFn func() types.Context,
|
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,
|
2022-01-16 05:46:53 +02:00
|
|
|
toastFn func(message string),
|
|
|
|
getPromptInputFn func() string,
|
2022-05-07 07:42:36 +02:00
|
|
|
) *PopupHandler {
|
|
|
|
return &PopupHandler{
|
2022-01-28 11:44:36 +02:00
|
|
|
Common: common,
|
|
|
|
index: 0,
|
|
|
|
createPopupPanelFn: createPopupPanelFn,
|
|
|
|
onErrorFn: onErrorFn,
|
2022-08-01 13:58:49 +02:00
|
|
|
popContextFn: popContextFn,
|
|
|
|
currentContextFn: currentContextFn,
|
2022-01-28 11:44:36 +02:00
|
|
|
createMenuFn: createMenuFn,
|
|
|
|
withWaitingStatusFn: withWaitingStatusFn,
|
2022-01-16 05:46:53 +02:00
|
|
|
toastFn: toastFn,
|
|
|
|
getPromptInputFn: getPromptInputFn,
|
2022-01-28 11:44:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-07 07:42:36 +02:00
|
|
|
func (self *PopupHandler) Menu(opts types.CreateMenuOptions) error {
|
2022-01-28 11:44:36 +02:00
|
|
|
return self.createMenuFn(opts)
|
|
|
|
}
|
|
|
|
|
2022-05-07 07:42:36 +02:00
|
|
|
func (self *PopupHandler) Toast(message string) {
|
2022-01-16 05:46:53 +02:00
|
|
|
self.toastFn(message)
|
|
|
|
}
|
|
|
|
|
2022-05-07 07:42:36 +02:00
|
|
|
func (self *PopupHandler) WithWaitingStatus(message string, f func() error) error {
|
2022-01-28 11:44:36 +02:00
|
|
|
return self.withWaitingStatusFn(message, f)
|
|
|
|
}
|
|
|
|
|
2022-05-07 07:42:36 +02:00
|
|
|
func (self *PopupHandler) Error(err error) error {
|
2022-01-28 11:44:36 +02:00
|
|
|
if err == gocui.ErrQuit {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return self.ErrorMsg(err.Error())
|
|
|
|
}
|
|
|
|
|
2022-05-07 07:42:36 +02:00
|
|
|
func (self *PopupHandler) ErrorMsg(message string) error {
|
2022-01-28 11:44:36 +02:00
|
|
|
self.Lock()
|
|
|
|
self.index++
|
|
|
|
self.Unlock()
|
|
|
|
|
2022-04-16 07:52:27 +02:00
|
|
|
// Need to set bold here explicitly; otherwise it gets cancelled by the red colouring.
|
|
|
|
coloredMessage := style.FgRed.SetBold().Sprint(strings.TrimSpace(message))
|
2022-01-28 11:44:36 +02:00
|
|
|
if err := self.onErrorFn(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-03-30 08:48:29 +02:00
|
|
|
return self.Alert(self.Tr.Error, coloredMessage)
|
2022-01-28 11:44:36 +02:00
|
|
|
}
|
|
|
|
|
2022-05-07 07:42:36 +02:00
|
|
|
func (self *PopupHandler) Alert(title string, message string) error {
|
2022-03-30 08:48:29 +02:00
|
|
|
return self.Confirm(types.ConfirmOpts{Title: title, Prompt: message})
|
2022-03-24 12:19:08 +02:00
|
|
|
}
|
|
|
|
|
2022-05-07 07:42:36 +02:00
|
|
|
func (self *PopupHandler) Confirm(opts types.ConfirmOpts) 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-08-01 13:58:49 +02:00
|
|
|
Title: opts.Title,
|
|
|
|
Prompt: opts.Prompt,
|
|
|
|
HandleConfirm: opts.HandleConfirm,
|
|
|
|
HandleClose: opts.HandleClose,
|
2022-01-28 11:44:36 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-05-07 07:42:36 +02:00
|
|
|
func (self *PopupHandler) 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
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-05-07 07:42:36 +02:00
|
|
|
func (self *PopupHandler) WithLoaderPanel(message string, f func() error) error {
|
2022-01-28 11:44:36 +02:00
|
|
|
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()
|
2022-08-01 13:58:49 +02:00
|
|
|
if index == self.index && self.currentContextFn().GetKey() == context.CONFIRMATION_CONTEXT_KEY {
|
|
|
|
_ = self.popContextFn()
|
2022-01-28 11:44:36 +02:00
|
|
|
}
|
|
|
|
self.Unlock()
|
|
|
|
})
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-01-16 05:46:53 +02:00
|
|
|
// returns the content that has currently been typed into the prompt. Useful for
|
2022-03-24 12:19:08 +02:00
|
|
|
// asynchronously updating the suggestions list under the prompt.
|
2022-05-07 07:42:36 +02:00
|
|
|
func (self *PopupHandler) GetPromptInput() string {
|
2022-01-16 05:46:53 +02:00
|
|
|
return self.getPromptInputFn()
|
|
|
|
}
|