From 1efe3c3d0abbd89b8f076d06f23cbd49d86a2d30 Mon Sep 17 00:00:00 2001 From: administrator Date: Mon, 6 Apr 2026 10:14:16 +0700 Subject: [PATCH] Show ping results in a modal dialog --- internal/gui/app.go | 72 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/internal/gui/app.go b/internal/gui/app.go index f8ad612..4ad9754 100644 --- a/internal/gui/app.go +++ b/internal/gui/app.go @@ -63,6 +63,9 @@ type ui struct { message string messageColor color.NRGBA busy bool + showModal bool + modalTitle string + modalBody string async chan func() @@ -76,6 +79,7 @@ type ui struct { testURLBtn widget.Clickable addWGManualBtn widget.Clickable addWGFileBtn widget.Clickable + closeModalBtn widget.Clickable vlessConnectBtns []widget.Clickable vlessDeleteBtns []widget.Clickable @@ -218,6 +222,9 @@ func (u *ui) handleClicks(gtx layout.Context) { for u.addWGFileBtn.Clicked(gtx) { u.addWireGuardFromFile() } + for u.closeModalBtn.Clicked(gtx) { + u.hideModal() + } for i := 0; i < minInt(len(u.configs.VLESS), len(u.vlessConnectBtns), len(u.vlessDeleteBtns), len(u.vlessPingBtns)); i++ { for u.vlessConnectBtns[i].Clicked(gtx) { @@ -245,7 +252,8 @@ func (u *ui) handleClicks(gtx layout.Context) { if !ok { return fmt.Errorf("сервер не найден") } - return fmt.Errorf("пинг %.0f мс", latency) + u.showPingModal("��������� �����", cfg.Name, latency) + return nil }) } } @@ -538,7 +546,8 @@ func (u *ui) testURL() { if !ok { return fmt.Errorf("сервер не найден") } - return fmt.Errorf("пинг %.0f мс", latency) + u.showPingModal("��������� �����", "��������� URL", latency) + return nil }) } @@ -564,10 +573,26 @@ func (u *ui) openLogs() { u.messageColor = successColor } +func (u *ui) showPingModal(title, target string, latency float64) { + u.async <- func() { + u.modalTitle = title + u.modalBody = fmt.Sprintf("%s\n\n����: %.0f ��", target, latency) + u.showModal = true + u.window.Invalidate() + } +} + +func (u *ui) hideModal() { + u.showModal = false + u.modalTitle = "" + u.modalBody = "" + u.window.Invalidate() +} + func (u *ui) layout(gtx layout.Context) layout.Dimensions { fill(gtx, bgColor) - return layout.UniformInset(unit.Dp(24)).Layout(gtx, func(gtx layout.Context) layout.Dimensions { + dims := layout.UniformInset(unit.Dp(24)).Layout(gtx, func(gtx layout.Context) layout.Dimensions { return u.contentList.Layout(gtx, 1, func(gtx layout.Context, _ int) layout.Dimensions { return layout.Flex{Axis: layout.Vertical}.Layout( gtx, @@ -579,6 +604,12 @@ func (u *ui) layout(gtx layout.Context) layout.Dimensions { ) }) }) + + if u.showModal { + u.layoutModal(gtx) + } + + return dims } func (u *ui) layoutHeader(gtx layout.Context) layout.Dimensions { @@ -1014,6 +1045,41 @@ func (u *ui) card(gtx layout.Context, bg color.NRGBA, content layout.Widget) lay return dims } +func (u *ui) layoutModal(gtx layout.Context) { + defer clip.Rect{Max: gtx.Constraints.Max}.Push(gtx.Ops).Pop() + paint.Fill(gtx.Ops, color.NRGBA{A: 160}) + + layout.Center.Layout(gtx, func(gtx layout.Context) layout.Dimensions { + return layout.UniformInset(unit.Dp(24)).Layout(gtx, func(gtx layout.Context) layout.Dimensions { + return u.card(gtx, panelColor, func(gtx layout.Context) layout.Dimensions { + return layout.UniformInset(unit.Dp(24)).Layout(gtx, func(gtx layout.Context) layout.Dimensions { + gtx.Constraints.Max.X = minInt(gtx.Constraints.Max.X, gtx.Dp(unit.Dp(420))) + return layout.Flex{Axis: layout.Vertical}.Layout( + gtx, + layout.Rigid(func(gtx layout.Context) layout.Dimensions { + lbl := material.H5(u.theme, u.modalTitle) + lbl.Color = textColor + return lbl.Layout(gtx) + }), + layout.Rigid(spacerH(12)), + layout.Rigid(func(gtx layout.Context) layout.Dimensions { + lbl := material.Body1(u.theme, u.modalBody) + lbl.Color = mutedColor + return lbl.Layout(gtx) + }), + layout.Rigid(spacerH(20)), + layout.Rigid(func(gtx layout.Context) layout.Dimensions { + return layout.E.Layout(gtx, func(gtx layout.Context) layout.Dimensions { + return u.layoutButton(gtx, &u.closeModalBtn, "OK", accentSoftColor) + }) + }), + ) + }) + }) + }) + }) +} + func fill(gtx layout.Context, c color.NRGBA) { defer clip.Rect{Max: gtx.Constraints.Max}.Push(gtx.Ops).Pop() paint.Fill(gtx.Ops, c)