1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-04-25 12:24:47 +02:00

toast notifications

This commit is contained in:
Jesse Duffield 2020-11-18 09:08:32 +11:00
parent ce928dc6c8
commit a3dfcd5a95
3 changed files with 78 additions and 31 deletions

View File

@ -1,6 +1,7 @@
package gui package gui
import ( import (
"sync"
"time" "time"
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
@ -8,33 +9,68 @@ import (
) )
type appStatus struct { type appStatus struct {
name string message string
statusType string statusType string
duration int id int
} }
type statusManager struct { type statusManager struct {
statuses []appStatus statuses []appStatus
nextId int
mutex sync.Mutex
} }
func (m *statusManager) removeStatus(name string) { func (m *statusManager) removeStatus(id int) {
m.mutex.Lock()
defer m.mutex.Unlock()
newStatuses := []appStatus{} newStatuses := []appStatus{}
for _, status := range m.statuses { for _, status := range m.statuses {
if status.name != name { if status.id != id {
newStatuses = append(newStatuses, status) newStatuses = append(newStatuses, status)
} }
} }
m.statuses = newStatuses m.statuses = newStatuses
} }
func (m *statusManager) addWaitingStatus(name string) { func (m *statusManager) addWaitingStatus(message string) int {
m.removeStatus(name) m.mutex.Lock()
defer m.mutex.Unlock()
m.nextId += 1
id := m.nextId
newStatus := appStatus{ newStatus := appStatus{
name: name, message: message,
statusType: "waiting", statusType: "waiting",
duration: 0, id: id,
} }
m.statuses = append([]appStatus{newStatus}, m.statuses...) m.statuses = append([]appStatus{newStatus}, m.statuses...)
return id
}
func (m *statusManager) addToastStatus(message string) int {
m.mutex.Lock()
defer m.mutex.Unlock()
m.nextId++
id := m.nextId
newStatus := appStatus{
message: message,
statusType: "toast",
id: id,
}
m.statuses = append([]appStatus{newStatus}, m.statuses...)
go func() {
time.Sleep(time.Second * 2)
m.removeStatus(id)
}()
return id
} }
func (m *statusManager) getStatusString() string { func (m *statusManager) getStatusString() string {
@ -43,31 +79,42 @@ func (m *statusManager) getStatusString() string {
} }
topStatus := m.statuses[0] topStatus := m.statuses[0]
if topStatus.statusType == "waiting" { if topStatus.statusType == "waiting" {
return topStatus.name + " " + utils.Loader() return topStatus.message + " " + utils.Loader()
} }
return topStatus.name return topStatus.message
} }
// WithWaitingStatus wraps a function and shows a waiting status while the function is still executing func (gui *Gui) raiseToastStatus(message string) {
func (gui *Gui) WithWaitingStatus(name string, f func() error) error { gui.statusManager.addToastStatus(message)
go utils.Safe(func() {
gui.statusManager.addWaitingStatus(name)
defer func() { gui.renderAppStatus()
gui.statusManager.removeStatus(name) }
}()
func (gui *Gui) renderAppStatus() {
go utils.Safe(func() { go utils.Safe(func() {
ticker := time.NewTicker(time.Millisecond * 50) ticker := time.NewTicker(time.Millisecond * 50)
defer ticker.Stop() defer ticker.Stop()
for range ticker.C { for range ticker.C {
appStatus := gui.statusManager.getStatusString() appStatus := gui.statusManager.getStatusString()
if appStatus == "" { if appStatus == "" {
gui.renderString("appStatus", "")
return return
} }
gui.renderString("appStatus", appStatus) gui.renderString("appStatus", appStatus)
} }
}) })
}
// WithWaitingStatus wraps a function and shows a waiting status while the function is still executing
func (gui *Gui) WithWaitingStatus(message string, f func() error) error {
go utils.Safe(func() {
id := gui.statusManager.addWaitingStatus(message)
defer func() {
gui.statusManager.removeStatus(id)
}()
gui.renderAppStatus()
if err := f(); err != nil { if err := f(); err != nil {
gui.g.Update(func(g *gocui.Gui) error { gui.g.Update(func(g *gocui.Gui) error {

View File

@ -107,9 +107,9 @@ func (gui *Gui) handleCopyPullRequestURLPress(g *gocui.Gui, v *gocui.View) error
return gui.surfaceError(err) return gui.surfaceError(err)
} }
return gui.createPopupPanel(createPopupPanelOpts{ gui.raiseToastStatus(gui.Tr.PullRequestURLCopiedToClipboard)
prompt: gui.Tr.PullRequestURLCopiedToClipboard,
}) return nil
} }
func (gui *Gui) handleGitFetch(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleGitFetch(g *gocui.Gui, v *gocui.View) error {

View File

@ -41,13 +41,13 @@ func (gui *Gui) onBackgroundUpdateCheckFinish(newVersion string, err error) erro
func (gui *Gui) startUpdating(newVersion string) { func (gui *Gui) startUpdating(newVersion string) {
gui.State.Updating = true gui.State.Updating = true
gui.statusManager.addWaitingStatus("updating") statusId := gui.statusManager.addWaitingStatus("updating")
gui.Updater.Update(newVersion, gui.onUpdateFinish) gui.Updater.Update(newVersion, func(err error) error { return gui.onUpdateFinish(statusId, err) })
} }
func (gui *Gui) onUpdateFinish(err error) error { func (gui *Gui) onUpdateFinish(statusId int, err error) error {
gui.State.Updating = false gui.State.Updating = false
gui.statusManager.removeStatus("updating") gui.statusManager.removeStatus(statusId)
gui.renderString("appStatus", "") gui.renderString("appStatus", "")
if err != nil { if err != nil {
return gui.createErrorPanel("Update failed: " + err.Error()) return gui.createErrorPanel("Update failed: " + err.Error())