From 51f7ac597a2f9742f82bb4e4f59db5d594a371bc Mon Sep 17 00:00:00 2001 From: Jacob Date: Sun, 7 Jan 2024 18:46:25 +0100 Subject: [PATCH] Don't recreate info dialogs each time, fixes #129 Fixes #129 --- internal/transport/bridge/recv.go | 59 +++++++++------ internal/transport/bridge/send.go | 116 ++++++++++++++++++------------ 2 files changed, 107 insertions(+), 68 deletions(-) diff --git a/internal/transport/bridge/recv.go b/internal/transport/bridge/recv.go index 1f2233fc..799d8e9c 100644 --- a/internal/transport/bridge/recv.go +++ b/internal/transport/bridge/recv.go @@ -50,12 +50,26 @@ func (r *RecvItem) setPath(path string) { r.refresh(r.index) } +// NewRecvList greates a list of progress bars. +func NewRecvList(data *RecvData) *widget.List { + list := &widget.List{ + Length: data.Length, + CreateItem: data.CreateItem, + UpdateItem: data.UpdateItem, + OnSelected: data.OnSelected, + } + data.list = list + data.setUpRecvInfoDialog() + return list +} + // RecvData is a list of progress bars that track send progress. type RecvData struct { Client *transport.Client Window fyne.Window items []*RecvItem + info recvInfoDialog deleting atomic.Bool list *widget.List @@ -95,24 +109,24 @@ func (d *RecvData) UpdateItem(i int, object fyne.CanvasObject) { func (d *RecvData) OnSelected(i int) { d.list.Unselect(i) - var infoDialog *dialog.CustomDialog - removeLabel := &widget.Label{Text: "This item has completed the transfer and can be removed."} - removeButton := &widget.Button{Icon: theme.DeleteIcon(), Importance: widget.DangerImportance, Text: "Remove", OnTapped: func() { + d.info.button.OnTapped = func() { d.remove(i) - infoDialog.Hide() - infoDialog = nil - }} + d.info.dialog.Hide() + } - removeCard := &widget.Card{Content: container.NewVBox(removeLabel, removeButton)} + if d.info.button.Disabled() { + d.info.label.Text = "This item can be removed.\nThe transfer has completed." + d.info.button.Enable() + } // Only allow failed or completed items to be removed. - if d.items[i].Value < d.items[i].Max && d.items[i].Status == nil { - removeLabel.Text = "This item can not be removed yet. The transfer needs to complete first." - removeButton.Disable() + item := d.items[i] + if item.Value < item.Max && item.Status == nil { + d.info.label.Text = "This item can't be removed yet.\nThe transfer needs to complete first." + d.info.button.Disable() } - infoDialog = dialog.NewCustom("Information", "Close", removeCard, d.Window) - infoDialog.Show() + d.info.dialog.Show() } // NewRecv creates a new send item and adds it to the items. @@ -173,14 +187,15 @@ func (d *RecvData) remove(index int) { d.deleting.Store(false) } -// NewRecvList greates a list of progress bars. -func NewRecvList(data *RecvData) *widget.List { - list := &widget.List{ - Length: data.Length, - CreateItem: data.CreateItem, - UpdateItem: data.UpdateItem, - OnSelected: data.OnSelected, - } - data.list = list - return list +func (d *RecvData) setUpRecvInfoDialog() { + d.info.label = &widget.Label{Text: "This item can be removed.\nThe transfer has completed."} + d.info.button = &widget.Button{Icon: theme.DeleteIcon(), Importance: widget.DangerImportance, Text: "Remove"} + removeCard := &widget.Card{Content: container.NewVBox(d.info.label, d.info.button)} + d.info.dialog = dialog.NewCustom("Information", "Close", removeCard, d.Window) +} + +type recvInfoDialog struct { + dialog *dialog.CustomDialog + button *widget.Button + label *widget.Label } diff --git a/internal/transport/bridge/send.go b/internal/transport/bridge/send.go index 5cb86115..97e3f121 100644 --- a/internal/transport/bridge/send.go +++ b/internal/transport/bridge/send.go @@ -42,6 +42,19 @@ func (s *SendItem) failed() { s.refresh(s.index) } +// NewSendList greates a list of progress bars. +func NewSendList(data *SendData) *widget.List { + list := &widget.List{ + Length: data.Length, + CreateItem: data.CreateItem, + UpdateItem: data.UpdateItem, + OnSelected: data.OnSelected, + } + data.list = list + data.setUpSendInfoDialog() + return list +} + // SendData is a list of progress bars that track send progress. type SendData struct { Client *transport.Client @@ -49,6 +62,7 @@ type SendData struct { Canvas fyne.Canvas items []*SendItem + info sendInfoDialog deleting atomic.Bool list *widget.List @@ -97,50 +111,36 @@ func (d *SendData) OnSelected(i int) { code.BackgroundColor = theme.OverlayBackgroundColor() code.ForegroundColor = theme.ForegroundColor() + d.info.image.Image = code.Image(100) + d.info.image.Resource = nil + d.info.image.ScaleMode = canvas.ImageScalePixels + d.info.image.Refresh() - qrcode := canvas.NewImageFromImage(code.Image(100)) - qrcode.FillMode = canvas.ImageFillOriginal - qrcode.ScaleMode = canvas.ImageScalePixels - qrcode.SetMinSize(fyne.NewSize(100, 100)) - - supportedClientsURL := util.URLToGitHubProject("/wiki/Supported-clients") - qrCodeInfo := widget.NewRichText(&widget.TextSegment{ - Style: widget.RichTextStyleInline, - Text: "A list of supported apps can be found ", - }, &widget.HyperlinkSegment{ - Text: "here", - URL: supportedClientsURL, - }, &widget.TextSegment{ - Style: widget.RichTextStyleInline, - Text: ".", - }) - qrCard := &widget.Card{Image: qrcode, Content: container.NewCenter(qrCodeInfo)} - - var infoDialog *dialog.CustomDialog - removeLabel := &widget.Label{Text: "This item can be removed.\nThe transfer has completed."} - removeButton := &widget.Button{Icon: theme.DeleteIcon(), Importance: widget.DangerImportance, Text: "Remove", OnTapped: func() { + d.info.button.OnTapped = func() { d.remove(i) - infoDialog.Hide() - infoDialog = nil - }} + d.info.dialog.Hide() + } + + if d.info.button.Disabled() { + d.info.label.Text = "This item can be removed.\nThe transfer has completed." + d.info.button.Enable() + } // Only allow failed or completed items to be removed. - if d.items[i].Value < d.items[i].Max && d.items[i].Status == nil { - removeLabel.Text = "This item can not be removed yet.\nThe transfer needs to complete first." - removeButton.Disable() + item := d.items[i] + if item.Value < item.Max && item.Status == nil { + d.info.label.Text = "This item can't be removed yet.\nThe transfer needs to complete first." + d.info.button.Disable() } else { - qrcode.Image = nil - qrcode.Resource = theme.InfoIcon() - qrcode.ScaleMode = canvas.ImageScaleSmooth - qrcode.Refresh() + d.info.image.Image = nil + d.info.image.Resource = theme.BrokenImageIcon() + d.info.image.ScaleMode = canvas.ImageScaleSmooth + d.info.image.Refresh() - qrCard.Content = &widget.Label{Text: "This transfer is not active.\nCan't show a QR code."} + // TODO: Display something like: "This transfer is not active.\nCan't show a QR code.". } - removeCard := &widget.Card{Content: container.NewVBox(removeLabel, removeButton)} - - infoDialog = dialog.NewCustom("Information", "Close", container.NewGridWithColumns(2, qrCard, removeCard), d.Window) - infoDialog.Show() + d.info.dialog.Show() } // NewSend adds data about a new send to the list and then returns the item. @@ -360,14 +360,38 @@ func (d *SendData) remove(index int) { d.deleting.Store(false) } -// NewSendList greates a list of progress bars. -func NewSendList(data *SendData) *widget.List { - list := &widget.List{ - Length: data.Length, - CreateItem: data.CreateItem, - UpdateItem: data.UpdateItem, - OnSelected: data.OnSelected, - } - data.list = list - return list +func (d *SendData) setUpSendInfoDialog() { + d.info.label = &widget.Label{Text: "This item can be removed.\nThe transfer has completed."} + d.info.button = &widget.Button{Icon: theme.DeleteIcon(), Importance: widget.DangerImportance, Text: "Remove"} + + image := &canvas.Image{} + image.FillMode = canvas.ImageFillOriginal + image.ScaleMode = canvas.ImageScalePixels + image.SetMinSize(fyne.NewSize(100, 100)) + d.info.image = image + + supportedClientsURL := util.URLToGitHubProject("/wiki/Supported-clients") + qrCodeInfo := widget.NewRichText(&widget.TextSegment{ + Style: widget.RichTextStyleInline, + Text: "A list of supported apps can be found ", + }, &widget.HyperlinkSegment{ + Text: "here", + URL: supportedClientsURL, + }, &widget.TextSegment{ + Style: widget.RichTextStyleInline, + Text: ".", + }) + qrCard := &widget.Card{Image: image, Content: container.NewCenter(qrCodeInfo)} + + removeCard := &widget.Card{Content: container.NewVBox(d.info.label, d.info.button)} + + content := container.NewGridWithColumns(2, qrCard, removeCard) + d.info.dialog = dialog.NewCustom("Information", "Close", content, d.Window) +} + +type sendInfoDialog struct { + dialog *dialog.CustomDialog + button *widget.Button + label *widget.Label + image *canvas.Image }