diff --git a/pkg/gui/information_panel.go b/pkg/gui/information_panel.go index 5de212b4d..00867fb92 100644 --- a/pkg/gui/information_panel.go +++ b/pkg/gui/information_panel.go @@ -5,6 +5,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/constants" "github.com/jesseduffield/lazygit/pkg/gui/style" + "github.com/jesseduffield/lazygit/pkg/utils" "github.com/mattn/go-runewidth" ) @@ -39,11 +40,28 @@ func (gui *Gui) handleInfoClick() error { return activeMode.Reset() } + var title, url string + // if we're not in an active mode we show the donate button if cx <= runewidth.StringWidth(gui.c.Tr.Donate) { - return gui.os.OpenLink(constants.Links.Donate) + url = constants.Links.Donate + title = gui.c.Tr.Donate } else if cx <= runewidth.StringWidth(gui.c.Tr.Donate)+1+runewidth.StringWidth(gui.c.Tr.AskQuestion) { - return gui.os.OpenLink(constants.Links.Discussions) + url = constants.Links.Discussions + title = gui.c.Tr.AskQuestion } + err := gui.os.OpenLink(url) + if err != nil { + // Opening the link via the OS failed for some reason. (For example, this + // can happen if the `os.openLink` config key references a command that + // doesn't exist, or that errors when called.) + // + // In that case, rather than crash the app, fall back to simply showing a + // dialog asking the user to visit the URL. + placeholders := map[string]string{"url": url} + message := utils.ResolvePlaceholderString(gui.c.Tr.PleaseGoToURL, placeholders) + return gui.c.Alert(title, message) + } + return nil } diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 6dee00467..4fb86573f 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -585,6 +585,7 @@ type TranslationSet struct { MarkAsBaseCommit string MarkAsBaseCommitTooltip string MarkedCommitMarker string + PleaseGoToURL string Actions Actions Bisect Bisect Log Log @@ -1347,6 +1348,7 @@ func EnglishTranslationSet() TranslationSet { MarkAsBaseCommit: "Mark commit as base commit for rebase", MarkAsBaseCommitTooltip: "Select a base commit for the next rebase; this will effectively perform a 'git rebase --onto'.", MarkedCommitMarker: "↑↑↑ Will rebase from here ↑↑↑", + PleaseGoToURL: "Please go to {{.url}}", Actions: Actions{ // TODO: combine this with the original keybinding descriptions (those are all in lowercase atm) CheckoutCommit: "Checkout commit", diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index e3ef9bebc..8c9527bec 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -233,6 +233,7 @@ var tests = []*components.IntegrationTest{ ui.Accordion, ui.DoublePopup, ui.EmptyMenu, + ui.OpenLinkFailure, ui.SwitchTabFromMenu, undo.UndoCheckoutAndDrop, undo.UndoDrop, diff --git a/pkg/integration/tests/ui/open_link_failure.go b/pkg/integration/tests/ui/open_link_failure.go new file mode 100644 index 000000000..c7a223555 --- /dev/null +++ b/pkg/integration/tests/ui/open_link_failure.go @@ -0,0 +1,24 @@ +package ui + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var OpenLinkFailure = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "When opening links via the OS fails, show a dialog instead.", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) { + config.UserConfig.OS.OpenLink = "exit 42" + }, + SetupRepo: func(shell *Shell) {}, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Information().Click(0, 0) + + t.ExpectPopup().Confirmation(). + Title(Equals("Donate")). + Content(Equals("Please go to https://github.com/sponsors/jesseduffield")). + Confirm() + }, +})