mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-07-30 03:23:08 +03:00
refactor credential handling
This commit is contained in:
@ -87,7 +87,6 @@ func localisedTitle(mApp *app.App, str string) string {
|
|||||||
"commitMessage": tr.CommitMessageTitle,
|
"commitMessage": tr.CommitMessageTitle,
|
||||||
"commits": tr.CommitsTitle,
|
"commits": tr.CommitsTitle,
|
||||||
"confirmation": tr.ConfirmationTitle,
|
"confirmation": tr.ConfirmationTitle,
|
||||||
"credentials": tr.CredentialsTitle,
|
|
||||||
"information": tr.InformationTitle,
|
"information": tr.InformationTitle,
|
||||||
"main": tr.MainTitle,
|
"main": tr.MainTitle,
|
||||||
"patchBuilding": tr.PatchBuildingTitle,
|
"patchBuilding": tr.PatchBuildingTitle,
|
||||||
|
@ -120,6 +120,7 @@ func (gui *Gui) prepareConfirmationPanel(
|
|||||||
hasLoader bool,
|
hasLoader bool,
|
||||||
findSuggestionsFunc func(string) []*types.Suggestion,
|
findSuggestionsFunc func(string) []*types.Suggestion,
|
||||||
editable bool,
|
editable bool,
|
||||||
|
mask bool,
|
||||||
) error {
|
) error {
|
||||||
x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(true, prompt)
|
x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(true, prompt)
|
||||||
// calling SetView on an existing view returns the same view, so I'm not bothering
|
// calling SetView on an existing view returns the same view, so I'm not bothering
|
||||||
@ -136,6 +137,7 @@ func (gui *Gui) prepareConfirmationPanel(
|
|||||||
// for now we do not support wrapping in our editor
|
// for now we do not support wrapping in our editor
|
||||||
gui.Views.Confirmation.Wrap = !editable
|
gui.Views.Confirmation.Wrap = !editable
|
||||||
gui.Views.Confirmation.FgColor = theme.GocuiDefaultTextColor
|
gui.Views.Confirmation.FgColor = theme.GocuiDefaultTextColor
|
||||||
|
gui.Views.Confirmation.Mask = runeForMask(mask)
|
||||||
|
|
||||||
gui.findSuggestions = findSuggestionsFunc
|
gui.findSuggestions = findSuggestionsFunc
|
||||||
if findSuggestionsFunc != nil {
|
if findSuggestionsFunc != nil {
|
||||||
@ -154,7 +156,25 @@ func (gui *Gui) prepareConfirmationPanel(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runeForMask(mask bool) rune {
|
||||||
|
if mask {
|
||||||
|
return '*'
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
func (gui *Gui) createPopupPanel(opts types.CreatePopupPanelOpts) error {
|
func (gui *Gui) createPopupPanel(opts types.CreatePopupPanelOpts) error {
|
||||||
|
// if a popup panel already appears we must ignore this current one. This is
|
||||||
|
// not great but it prevents lost state. The proper solution is to have a stack of
|
||||||
|
// popups. We could have a queue of types.CreatePopupPanelOpts so that if you
|
||||||
|
// close a popup and there's another one in the queue we show that.
|
||||||
|
// One important popup we don't want to interrupt is the credentials popup
|
||||||
|
// or a process might get stuck waiting on user input.
|
||||||
|
if gui.currentContext().GetKey() == context.CONFIRMATION_CONTEXT_KEY {
|
||||||
|
gui.Log.Error("ignoring create popup panel because a popup panel is already open")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// remove any previous keybindings
|
// remove any previous keybindings
|
||||||
gui.clearConfirmationViewKeyBindings()
|
gui.clearConfirmationViewKeyBindings()
|
||||||
|
|
||||||
@ -164,6 +184,7 @@ func (gui *Gui) createPopupPanel(opts types.CreatePopupPanelOpts) error {
|
|||||||
opts.HasLoader,
|
opts.HasLoader,
|
||||||
opts.FindSuggestionsFunc,
|
opts.FindSuggestionsFunc,
|
||||||
opts.Editable,
|
opts.Editable,
|
||||||
|
opts.Mask,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -24,7 +24,6 @@ const (
|
|||||||
MAIN_PATCH_BUILDING_CONTEXT_KEY types.ContextKey = "patchBuilding"
|
MAIN_PATCH_BUILDING_CONTEXT_KEY types.ContextKey = "patchBuilding"
|
||||||
MAIN_STAGING_CONTEXT_KEY types.ContextKey = "staging"
|
MAIN_STAGING_CONTEXT_KEY types.ContextKey = "staging"
|
||||||
MENU_CONTEXT_KEY types.ContextKey = "menu"
|
MENU_CONTEXT_KEY types.ContextKey = "menu"
|
||||||
CREDENTIALS_CONTEXT_KEY types.ContextKey = "credentials"
|
|
||||||
CONFIRMATION_CONTEXT_KEY types.ContextKey = "confirmation"
|
CONFIRMATION_CONTEXT_KEY types.ContextKey = "confirmation"
|
||||||
SEARCH_CONTEXT_KEY types.ContextKey = "search"
|
SEARCH_CONTEXT_KEY types.ContextKey = "search"
|
||||||
COMMIT_MESSAGE_CONTEXT_KEY types.ContextKey = "commitMessage"
|
COMMIT_MESSAGE_CONTEXT_KEY types.ContextKey = "commitMessage"
|
||||||
@ -51,7 +50,6 @@ var AllContextKeys = []types.ContextKey{
|
|||||||
MAIN_PATCH_BUILDING_CONTEXT_KEY,
|
MAIN_PATCH_BUILDING_CONTEXT_KEY,
|
||||||
MAIN_STAGING_CONTEXT_KEY, // not focusable for secondary view
|
MAIN_STAGING_CONTEXT_KEY, // not focusable for secondary view
|
||||||
MENU_CONTEXT_KEY,
|
MENU_CONTEXT_KEY,
|
||||||
CREDENTIALS_CONTEXT_KEY,
|
|
||||||
CONFIRMATION_CONTEXT_KEY,
|
CONFIRMATION_CONTEXT_KEY,
|
||||||
SEARCH_CONTEXT_KEY,
|
SEARCH_CONTEXT_KEY,
|
||||||
COMMIT_MESSAGE_CONTEXT_KEY,
|
COMMIT_MESSAGE_CONTEXT_KEY,
|
||||||
@ -80,7 +78,6 @@ type ContextTree struct {
|
|||||||
Staging types.Context
|
Staging types.Context
|
||||||
PatchBuilding types.Context
|
PatchBuilding types.Context
|
||||||
Merging types.Context
|
Merging types.Context
|
||||||
Credentials types.Context
|
|
||||||
Confirmation types.Context
|
Confirmation types.Context
|
||||||
CommitMessage types.Context
|
CommitMessage types.Context
|
||||||
Search types.Context
|
Search types.Context
|
||||||
@ -103,7 +100,6 @@ func (self *ContextTree) Flatten() []types.Context {
|
|||||||
self.Stash,
|
self.Stash,
|
||||||
self.Menu,
|
self.Menu,
|
||||||
self.Confirmation,
|
self.Confirmation,
|
||||||
self.Credentials,
|
|
||||||
self.CommitMessage,
|
self.CommitMessage,
|
||||||
self.Normal,
|
self.Normal,
|
||||||
self.Staging,
|
self.Staging,
|
||||||
|
@ -114,18 +114,6 @@ func (gui *Gui) contextTree() *context.ContextTree {
|
|||||||
OnFocus: OnFocusWrapper(func() error { return gui.renderConflictsWithLock(true) }),
|
OnFocus: OnFocusWrapper(func() error { return gui.renderConflictsWithLock(true) }),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Credentials: context.NewSimpleContext(
|
|
||||||
context.NewBaseContext(context.NewBaseContextOpts{
|
|
||||||
Kind: types.PERSISTENT_POPUP,
|
|
||||||
ViewName: "credentials",
|
|
||||||
WindowName: "credentials",
|
|
||||||
Key: context.CREDENTIALS_CONTEXT_KEY,
|
|
||||||
Focusable: true,
|
|
||||||
}),
|
|
||||||
context.ContextCallbackOpts{
|
|
||||||
OnFocus: OnFocusWrapper(gui.handleAskFocused),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Confirmation: context.NewSimpleContext(
|
Confirmation: context.NewSimpleContext(
|
||||||
context.NewBaseContext(context.NewBaseContextOpts{
|
context.NewBaseContext(context.NewBaseContextOpts{
|
||||||
Kind: types.TEMPORARY_POPUP,
|
Kind: types.TEMPORARY_POPUP,
|
||||||
|
68
pkg/gui/controllers/helpers/credentials_helper.go
Normal file
68
pkg/gui/controllers/helpers/credentials_helper.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package helpers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CredentialsHelper struct {
|
||||||
|
c *types.HelperCommon
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCredentialsHelper(
|
||||||
|
c *types.HelperCommon,
|
||||||
|
) *CredentialsHelper {
|
||||||
|
return &CredentialsHelper{
|
||||||
|
c: c,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// promptUserForCredential wait for a username, password or passphrase input from the credentials popup
|
||||||
|
func (self *CredentialsHelper) PromptUserForCredential(passOrUname oscommands.CredentialType) string {
|
||||||
|
waitGroup := sync.WaitGroup{}
|
||||||
|
waitGroup.Add(1)
|
||||||
|
|
||||||
|
userInput := ""
|
||||||
|
|
||||||
|
self.c.OnUIThread(func() error {
|
||||||
|
title, mask := self.getTitleAndMask(passOrUname)
|
||||||
|
|
||||||
|
return self.c.Prompt(types.PromptOpts{
|
||||||
|
Title: title,
|
||||||
|
Mask: mask,
|
||||||
|
HandleConfirm: func(input string) error {
|
||||||
|
userInput = input
|
||||||
|
|
||||||
|
waitGroup.Done()
|
||||||
|
|
||||||
|
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
|
||||||
|
},
|
||||||
|
HandleClose: func() error {
|
||||||
|
waitGroup.Done()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// wait for username/passwords/passphrase input
|
||||||
|
waitGroup.Wait()
|
||||||
|
|
||||||
|
return userInput + "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *CredentialsHelper) getTitleAndMask(passOrUname oscommands.CredentialType) (string, bool) {
|
||||||
|
switch passOrUname {
|
||||||
|
case oscommands.Username:
|
||||||
|
return self.c.Tr.CredentialsUsername, false
|
||||||
|
case oscommands.Password:
|
||||||
|
return self.c.Tr.CredentialsPassword, true
|
||||||
|
case oscommands.Passphrase:
|
||||||
|
return self.c.Tr.CredentialsPassphrase, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// should never land here
|
||||||
|
panic("unexpected credential request")
|
||||||
|
}
|
@ -1,57 +0,0 @@
|
|||||||
package gui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
type credentials chan string
|
|
||||||
|
|
||||||
// promptUserForCredential wait for a username, password or passphrase input from the credentials popup
|
|
||||||
func (gui *Gui) promptUserForCredential(passOrUname oscommands.CredentialType) string {
|
|
||||||
gui.credentials = make(chan string)
|
|
||||||
gui.OnUIThread(func() error {
|
|
||||||
credentialsView := gui.Views.Credentials
|
|
||||||
switch passOrUname {
|
|
||||||
case oscommands.Username:
|
|
||||||
credentialsView.Title = gui.c.Tr.CredentialsUsername
|
|
||||||
credentialsView.Mask = 0
|
|
||||||
case oscommands.Password:
|
|
||||||
credentialsView.Title = gui.c.Tr.CredentialsPassword
|
|
||||||
credentialsView.Mask = '*'
|
|
||||||
case oscommands.Passphrase:
|
|
||||||
credentialsView.Title = gui.c.Tr.CredentialsPassphrase
|
|
||||||
credentialsView.Mask = '*'
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := gui.c.PushContext(gui.State.Contexts.Credentials); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
// wait for username/passwords/passphrase input
|
|
||||||
userInput := <-gui.credentials
|
|
||||||
return userInput + "\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gui *Gui) handleSubmitCredential() error {
|
|
||||||
credentialsView := gui.Views.Credentials
|
|
||||||
message := strings.TrimSpace(credentialsView.TextArea.GetContent())
|
|
||||||
gui.credentials <- message
|
|
||||||
credentialsView.ClearTextArea()
|
|
||||||
if err := gui.c.PopContext(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gui *Gui) handleCloseCredentialsView() error {
|
|
||||||
gui.Views.Credentials.ClearTextArea()
|
|
||||||
gui.credentials <- ""
|
|
||||||
return gui.c.PopContext()
|
|
||||||
}
|
|
@ -86,7 +86,6 @@ type Gui struct {
|
|||||||
Config config.AppConfigurer
|
Config config.AppConfigurer
|
||||||
Updater *updates.Updater
|
Updater *updates.Updater
|
||||||
statusManager *statusManager
|
statusManager *statusManager
|
||||||
credentials credentials
|
|
||||||
waitForIntro sync.WaitGroup
|
waitForIntro sync.WaitGroup
|
||||||
fileWatcher *fileWatcher
|
fileWatcher *fileWatcher
|
||||||
viewBufferManagerMap map[string]*tasks.ViewBufferManager
|
viewBufferManagerMap map[string]*tasks.ViewBufferManager
|
||||||
@ -247,7 +246,6 @@ type Views struct {
|
|||||||
Options *gocui.View
|
Options *gocui.View
|
||||||
Confirmation *gocui.View
|
Confirmation *gocui.View
|
||||||
Menu *gocui.View
|
Menu *gocui.View
|
||||||
Credentials *gocui.View
|
|
||||||
CommitMessage *gocui.View
|
CommitMessage *gocui.View
|
||||||
CommitFiles *gocui.View
|
CommitFiles *gocui.View
|
||||||
Information *gocui.View
|
Information *gocui.View
|
||||||
@ -403,7 +401,6 @@ func initialViewContextMapping(contextTree *context.ContextTree) map[string]type
|
|||||||
"stash": contextTree.Stash,
|
"stash": contextTree.Stash,
|
||||||
"menu": contextTree.Menu,
|
"menu": contextTree.Menu,
|
||||||
"confirmation": contextTree.Confirmation,
|
"confirmation": contextTree.Confirmation,
|
||||||
"credentials": contextTree.Credentials,
|
|
||||||
"commitMessage": contextTree.CommitMessage,
|
"commitMessage": contextTree.CommitMessage,
|
||||||
"main": contextTree.Normal,
|
"main": contextTree.Normal,
|
||||||
"secondary": contextTree.Normal,
|
"secondary": contextTree.Normal,
|
||||||
@ -448,17 +445,6 @@ func NewGui(
|
|||||||
InitialDir: initialDir,
|
InitialDir: initialDir,
|
||||||
}
|
}
|
||||||
|
|
||||||
guiIO := oscommands.NewGuiIO(
|
|
||||||
cmn.Log,
|
|
||||||
gui.LogCommand,
|
|
||||||
gui.getCmdWriter,
|
|
||||||
gui.promptUserForCredential,
|
|
||||||
)
|
|
||||||
|
|
||||||
osCommand := oscommands.NewOSCommand(cmn, oscommands.GetPlatform(), guiIO)
|
|
||||||
|
|
||||||
gui.os = osCommand
|
|
||||||
|
|
||||||
gui.watchFilesForChanges()
|
gui.watchFilesForChanges()
|
||||||
|
|
||||||
gui.PopupHandler = popup.NewPopupHandler(
|
gui.PopupHandler = popup.NewPopupHandler(
|
||||||
@ -475,6 +461,19 @@ func NewGui(
|
|||||||
guiCommon := &guiCommon{gui: gui, IPopupHandler: gui.PopupHandler}
|
guiCommon := &guiCommon{gui: gui, IPopupHandler: gui.PopupHandler}
|
||||||
helperCommon := &types.HelperCommon{IGuiCommon: guiCommon, Common: cmn}
|
helperCommon := &types.HelperCommon{IGuiCommon: guiCommon, Common: cmn}
|
||||||
|
|
||||||
|
credentialsHelper := helpers.NewCredentialsHelper(helperCommon)
|
||||||
|
|
||||||
|
guiIO := oscommands.NewGuiIO(
|
||||||
|
cmn.Log,
|
||||||
|
gui.LogCommand,
|
||||||
|
gui.getCmdWriter,
|
||||||
|
credentialsHelper.PromptUserForCredential,
|
||||||
|
)
|
||||||
|
|
||||||
|
osCommand := oscommands.NewOSCommand(cmn, oscommands.GetPlatform(), guiIO)
|
||||||
|
|
||||||
|
gui.os = osCommand
|
||||||
|
|
||||||
// storing this stuff on the gui for now to ease refactoring
|
// storing this stuff on the gui for now to ease refactoring
|
||||||
// TODO: reset these controllers upon changing repos due to state changing
|
// TODO: reset these controllers upon changing repos due to state changing
|
||||||
gui.c = helperCommon
|
gui.c = helperCommon
|
||||||
@ -751,7 +750,6 @@ func (gui *Gui) createAllViews() error {
|
|||||||
{viewPtr: &gui.Views.Search, name: "search"},
|
{viewPtr: &gui.Views.Search, name: "search"},
|
||||||
{viewPtr: &gui.Views.SearchPrefix, name: "searchPrefix"},
|
{viewPtr: &gui.Views.SearchPrefix, name: "searchPrefix"},
|
||||||
{viewPtr: &gui.Views.CommitMessage, name: "commitMessage"},
|
{viewPtr: &gui.Views.CommitMessage, name: "commitMessage"},
|
||||||
{viewPtr: &gui.Views.Credentials, name: "credentials"},
|
|
||||||
{viewPtr: &gui.Views.Menu, name: "menu"},
|
{viewPtr: &gui.Views.Menu, name: "menu"},
|
||||||
{viewPtr: &gui.Views.Suggestions, name: "suggestions"},
|
{viewPtr: &gui.Views.Suggestions, name: "suggestions"},
|
||||||
{viewPtr: &gui.Views.Confirmation, name: "confirmation"},
|
{viewPtr: &gui.Views.Confirmation, name: "confirmation"},
|
||||||
@ -825,11 +823,6 @@ func (gui *Gui) createAllViews() error {
|
|||||||
|
|
||||||
gui.Views.Confirmation.Visible = false
|
gui.Views.Confirmation.Visible = false
|
||||||
|
|
||||||
gui.Views.Credentials.Visible = false
|
|
||||||
gui.Views.Credentials.Title = gui.c.Tr.CredentialsUsername
|
|
||||||
gui.Views.Credentials.FgColor = theme.GocuiDefaultTextColor
|
|
||||||
gui.Views.Credentials.Editable = true
|
|
||||||
|
|
||||||
gui.Views.Suggestions.Visible = false
|
gui.Views.Suggestions.Visible = false
|
||||||
|
|
||||||
gui.Views.Menu.Visible = false
|
gui.Views.Menu.Visible = false
|
||||||
|
@ -65,3 +65,7 @@ func (self *guiCommon) Render() {
|
|||||||
func (self *guiCommon) OpenSearch() {
|
func (self *guiCommon) OpenSearch() {
|
||||||
_ = self.gui.handleOpenSearch(self.gui.currentViewName())
|
_ = self.gui.handleOpenSearch(self.gui.currentViewName())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *guiCommon) OnUIThread(f func() error) {
|
||||||
|
self.gui.OnUIThread(f)
|
||||||
|
}
|
||||||
|
@ -430,18 +430,6 @@ func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBi
|
|||||||
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
||||||
Description: self.c.Tr.LcCopyCommitShaToClipboard,
|
Description: self.c.Tr.LcCopyCommitShaToClipboard,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
ViewName: "credentials",
|
|
||||||
Key: opts.GetKey(opts.Config.Universal.Confirm),
|
|
||||||
Modifier: gocui.ModNone,
|
|
||||||
Handler: self.handleSubmitCredential,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ViewName: "credentials",
|
|
||||||
Key: opts.GetKey(opts.Config.Universal.Return),
|
|
||||||
Modifier: gocui.ModNone,
|
|
||||||
Handler: self.handleCloseCredentialsView,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
ViewName: "menu",
|
ViewName: "menu",
|
||||||
Key: opts.GetKey(opts.Config.Universal.Return),
|
Key: opts.GetKey(opts.Config.Universal.Return),
|
||||||
|
@ -224,7 +224,6 @@ func (gui *Gui) onInitialViewsCreation() error {
|
|||||||
gui.Views.Menu,
|
gui.Views.Menu,
|
||||||
gui.Views.Suggestions,
|
gui.Views.Suggestions,
|
||||||
gui.Views.Confirmation,
|
gui.Views.Confirmation,
|
||||||
gui.Views.Credentials,
|
|
||||||
|
|
||||||
// this guy will cover everything else when it appears
|
// this guy will cover everything else when it appears
|
||||||
gui.Views.Limit,
|
gui.Views.Limit,
|
||||||
|
@ -109,7 +109,9 @@ func (self *RealPopupHandler) Prompt(opts types.PromptOpts) error {
|
|||||||
Prompt: opts.InitialContent,
|
Prompt: opts.InitialContent,
|
||||||
Editable: true,
|
Editable: true,
|
||||||
HandleConfirmPrompt: opts.HandleConfirm,
|
HandleConfirmPrompt: opts.HandleConfirm,
|
||||||
|
HandleClose: opts.HandleClose,
|
||||||
FindSuggestionsFunc: opts.FindSuggestionsFunc,
|
FindSuggestionsFunc: opts.FindSuggestionsFunc,
|
||||||
|
Mask: opts.Mask,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,11 @@ type IGuiCommon interface {
|
|||||||
|
|
||||||
GetAppState() *config.AppState
|
GetAppState() *config.AppState
|
||||||
SaveAppState() error
|
SaveAppState() error
|
||||||
|
|
||||||
|
// Runs the given function on the UI thread (this is for things like showing a popup asking a user for input).
|
||||||
|
// Only necessary to call if you're not already on the UI thread i.e. you're inside a goroutine.
|
||||||
|
// All controller handlers are executed on the UI thread.
|
||||||
|
OnUIThread(f func() error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type IPopupHandler interface {
|
type IPopupHandler interface {
|
||||||
@ -73,6 +78,7 @@ type CreatePopupPanelOpts struct {
|
|||||||
HandlersManageFocus bool
|
HandlersManageFocus bool
|
||||||
|
|
||||||
FindSuggestionsFunc func(string) []*Suggestion
|
FindSuggestionsFunc func(string) []*Suggestion
|
||||||
|
Mask bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type AskOpts struct {
|
type AskOpts struct {
|
||||||
@ -88,6 +94,9 @@ type PromptOpts struct {
|
|||||||
InitialContent string
|
InitialContent string
|
||||||
FindSuggestionsFunc func(string) []*Suggestion
|
FindSuggestionsFunc func(string) []*Suggestion
|
||||||
HandleConfirm func(string) error
|
HandleConfirm func(string) error
|
||||||
|
// CAPTURE THIS
|
||||||
|
HandleClose func() error
|
||||||
|
Mask bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type MenuItem struct {
|
type MenuItem struct {
|
||||||
|
@ -80,7 +80,7 @@ func (gui *Gui) globalOptionsMap() map[string]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) isPopupPanel(viewName string) bool {
|
func (gui *Gui) isPopupPanel(viewName string) bool {
|
||||||
return viewName == "commitMessage" || viewName == "credentials" || viewName == "confirmation" || viewName == "menu"
|
return viewName == "commitMessage" || viewName == "confirmation" || viewName == "menu"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) popupPanelFocused() bool {
|
func (gui *Gui) popupPanelFocused() bool {
|
||||||
|
@ -191,7 +191,6 @@ func chineseTranslationSet() TranslationSet {
|
|||||||
TagsTitle: "标签页面",
|
TagsTitle: "标签页面",
|
||||||
MenuTitle: "菜单",
|
MenuTitle: "菜单",
|
||||||
RemotesTitle: "远程页面",
|
RemotesTitle: "远程页面",
|
||||||
CredentialsTitle: "证书",
|
|
||||||
RemoteBranchesTitle: "远程分支(在远程页面中)",
|
RemoteBranchesTitle: "远程分支(在远程页面中)",
|
||||||
PatchBuildingTitle: "构建补丁中",
|
PatchBuildingTitle: "构建补丁中",
|
||||||
InformationTitle: "信息",
|
InformationTitle: "信息",
|
||||||
|
@ -161,7 +161,6 @@ func dutchTranslationSet() TranslationSet {
|
|||||||
TagsTitle: "Tags Tabblad",
|
TagsTitle: "Tags Tabblad",
|
||||||
MenuTitle: "Menu",
|
MenuTitle: "Menu",
|
||||||
RemotesTitle: "Remotes Tabblad",
|
RemotesTitle: "Remotes Tabblad",
|
||||||
CredentialsTitle: "Credentials",
|
|
||||||
RemoteBranchesTitle: "Remote Branches (in Remotes tabblad)",
|
RemoteBranchesTitle: "Remote Branches (in Remotes tabblad)",
|
||||||
PatchBuildingTitle: "Patch Bouwen",
|
PatchBuildingTitle: "Patch Bouwen",
|
||||||
InformationTitle: "Informatie",
|
InformationTitle: "Informatie",
|
||||||
|
@ -177,7 +177,6 @@ type TranslationSet struct {
|
|||||||
TagsTitle string
|
TagsTitle string
|
||||||
MenuTitle string
|
MenuTitle string
|
||||||
RemotesTitle string
|
RemotesTitle string
|
||||||
CredentialsTitle string
|
|
||||||
RemoteBranchesTitle string
|
RemoteBranchesTitle string
|
||||||
PatchBuildingTitle string
|
PatchBuildingTitle string
|
||||||
InformationTitle string
|
InformationTitle string
|
||||||
@ -748,7 +747,6 @@ func EnglishTranslationSet() TranslationSet {
|
|||||||
TagsTitle: "Tags Tab",
|
TagsTitle: "Tags Tab",
|
||||||
MenuTitle: "Menu",
|
MenuTitle: "Menu",
|
||||||
RemotesTitle: "Remotes Tab",
|
RemotesTitle: "Remotes Tab",
|
||||||
CredentialsTitle: "Credentials",
|
|
||||||
RemoteBranchesTitle: "Remote Branches (in Remotes tab)",
|
RemoteBranchesTitle: "Remote Branches (in Remotes tab)",
|
||||||
PatchBuildingTitle: "Patch Building",
|
PatchBuildingTitle: "Patch Building",
|
||||||
InformationTitle: "Information",
|
InformationTitle: "Information",
|
||||||
|
Reference in New Issue
Block a user