From 5a7fbc4c525567e018890781197f5ea8d27d518c Mon Sep 17 00:00:00 2001 From: thepra Date: Thu, 15 Oct 2026 11:51:11 +0200 Subject: [PATCH] me-web? 0.5.2: findings are offered for sharing once the last measurement is in - The offer to share now appears when the two-minute test of how long an unused connection stays open has finished, so a shared report carries its answer instead of "measuring". - Starting a new check while that test is still running no longer lets its late answer land on the new check's card. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_012CzABvBkbcFqoHdmi8b9WB --- Directory.Build.props | 2 +- src/MeWeb.App/ViewModels/MainViewModel.cs | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 71e49a5..88ed8e8 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 0.5.1 + 0.5.2 me-web? Arasaka di Hvozdikov Yevheniy © 2026 Arasaka di Hvozdikov Yevheniy diff --git a/src/MeWeb.App/ViewModels/MainViewModel.cs b/src/MeWeb.App/ViewModels/MainViewModel.cs index 7961f05..d2806b9 100644 --- a/src/MeWeb.App/ViewModels/MainViewModel.cs +++ b/src/MeWeb.App/ViewModels/MainViewModel.cs @@ -45,6 +45,8 @@ public partial class MainViewModel : ObservableObject readonly Leftovers leftovers; readonly Submissions submissions; RunReport lastRun; + int checks; + bool sent; bool revealing; bool instant; @@ -198,15 +200,20 @@ public partial class MainViewModel : ObservableObject HistoryCleared = false; AskReach = false; OfferShare = false; + sent = false; ShareResult = null; + var generation = ++checks; foreach (var card in Cards) card.Finding = card.Id == CheckId.Reach ? null : Finding.Running(card.Id); Uses.Clear(); ResetPath(platform.Device); try { - lastRun = await runner.Run((finding, run) => Dispatcher.UIThread.Post(() => Apply(finding, run)), ct); + lastRun = await runner.Run((finding, run) => Dispatcher.UIThread.Post(() => + { + if (generation == checks) Apply(finding, run); + }), ct); ShowUses(lastRun); - OfferShare = true; + OfferShare = lastRun.Stun?.Ports?.LifetimeDone != false; OnPropertyChanged(nameof(CanOpenPorts)); AskReach = lastRun.PublicV4 is not null || lastRun.PublicV6 is not null; if (!AskReach) SettleReach(null); @@ -296,6 +303,7 @@ public partial class MainViewModel : ObservableObject Shared.Add(new SubmissionViewModel(submission, Unshare)); OnPropertyChanged(nameof(ShowShared)); ShareResult = Localizer.Instance.Format("ShareSent", shared.Id, Texts.Date(shared.KeepUntil)); + sent = true; OfferShare = false; } finally @@ -474,6 +482,7 @@ public partial class MainViewModel : ObservableObject var ports = run.Stun?.Ports; if (exit is not null && run.Nat == NatKind.Shared && run.PublicV4 is not null && ports?.Pattern is PortPattern.InOrder or PortPattern.Block) exit.Details = Lines(Address($"{run.PublicV4}:{ports.Low}–{ports.High}")); + if (ports?.LifetimeDone == true && run == lastRun && !IsChecking && !sent) OfferShare = true; break; case CheckId.Addresses: var internet = Node(NodeRole.Internet);