1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-10 04:07:18 +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
import (
"sync"
"time"
"github.com/jesseduffield/gocui"
@ -8,33 +9,68 @@ import (
)
type appStatus struct {
name string
message string
statusType string
duration int
id int
}
type statusManager struct {
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{}
for _, status := range m.statuses {
if status.name != name {
if status.id != id {
newStatuses = append(newStatuses, status)
}
}
m.statuses = newStatuses
}
func (m *statusManager) addWaitingStatus(name string) {
m.removeStatus(name)
func (m *statusManager) addWaitingStatus(message string) int {
m.mutex.Lock()
defer m.mutex.Unlock()
m.nextId += 1
id := m.nextId
newStatus := appStatus{
name: name,
message: message,
statusType: "waiting",
duration: 0,
id: id,
}
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 {
@ -43,31 +79,42 @@ func (m *statusManager) getStatusString() string {
}
topStatus := m.statuses[0]
if topStatus.statusType == "waiting" {
return topStatus.name + " " + utils.Loader()
return topStatus.message + " " + utils.Loader()
}
return topStatus.name
return topStatus.message
}
func (gui *Gui) raiseToastStatus(message string) {
gui.statusManager.addToastStatus(message)
gui.renderAppStatus()
}
func (gui *Gui) renderAppStatus() {
go utils.Safe(func() {
ticker := time.NewTicker(time.Millisecond * 50)
defer ticker.Stop()
for range ticker.C {
appStatus := gui.statusManager.getStatusString()
if appStatus == "" {
gui.renderString("appStatus", "")
return
}
gui.renderString("appStatus", appStatus)
}
})
}
// WithWaitingStatus wraps a function and shows a waiting status while the function is still executing
func (gui *Gui) WithWaitingStatus(name string, f func() error) error {
func (gui *Gui) WithWaitingStatus(message string, f func() error) error {
go utils.Safe(func() {
gui.statusManager.addWaitingStatus(name)
id := gui.statusManager.addWaitingStatus(message)
defer func() {
gui.statusManager.removeStatus(name)
gui.statusManager.removeStatus(id)
}()
go utils.Safe(func() {
ticker := time.NewTicker(time.Millisecond * 50)
defer ticker.Stop()
for range ticker.C {
appStatus := gui.statusManager.getStatusString()
if appStatus == "" {
return
}
gui.renderString("appStatus", appStatus)
}
})
gui.renderAppStatus()
if err := f(); err != nil {
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.createPopupPanel(createPopupPanelOpts{
prompt: gui.Tr.PullRequestURLCopiedToClipboard,
})
gui.raiseToastStatus(gui.Tr.PullRequestURLCopiedToClipboard)
return nil
}
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) {
gui.State.Updating = true
gui.statusManager.addWaitingStatus("updating")
gui.Updater.Update(newVersion, gui.onUpdateFinish)
statusId := gui.statusManager.addWaitingStatus("updating")
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.statusManager.removeStatus("updating")
gui.statusManager.removeStatus(statusId)
gui.renderString("appStatus", "")
if err != nil {
return gui.createErrorPanel("Update failed: " + err.Error())