Skip to content

Commit 82afd64

Browse files
committed
Add update checks, About menu, and opt-in telemetry
- add Help and File menus with GitHub links and update checking - add first-run anonymous usage consent and privacy settings - track launches, updates, exports, and crash types when enabled - document telemetry collection and privacy behavior - bump version to 0.1.4
1 parent 1a80dd6 commit 82afd64

15 files changed

Lines changed: 758 additions & 3 deletions

README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,40 @@ cd .\RrRpm2
5757
dotnet run
5858
```
5959

60+
## Help and Updates
61+
62+
The app's `Help` menu opens the user guide and GitHub project page. Use
63+
`Help > Check for Updates` to compare the installed version with the latest
64+
GitHub release. When a newer release is available, the app can open its release
65+
page in the default browser.
66+
67+
## Optional Usage Statistics
68+
69+
On first launch, the app asks whether to share anonymous usage statistics with
70+
BrantLab's self-hosted telemetry service. No telemetry is sent until the user
71+
explicitly opts in.
72+
73+
When enabled, the app sends:
74+
75+
- App version, Windows version, and processor architecture
76+
- App launches and one daily-active event
77+
- Update-check results
78+
- Successful talkgroup and site export counts, grouped into broad count ranges
79+
- Exception types for unexpected errors
80+
- A randomly generated installation identifier, stored locally and transformed
81+
by the server with keyed HMAC-SHA256 before storage
82+
83+
The app never sends:
84+
85+
- RadioReference usernames, passwords, API keys, or credentials
86+
- RadioReference system IDs, talkgroup IDs, site data, or downloaded content
87+
- Filenames, file paths, CSV contents, or export values
88+
- Exception messages or stack traces
89+
90+
The choice can be changed at any time under
91+
`Help > Privacy & Usage Statistics`. Disabling statistics stops future events
92+
and deletes the locally generated installation identifier.
93+
6094
## Release Builds
6195

6296
GitHub Actions publishes a Windows x64 build when a tag starting with `v` is pushed:

RrRpm2/AboutWindow.xaml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<Window x:Class="RrRpm2.AboutWindow"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
Title="About RadioReference to RPM2"
5+
Width="450"
6+
Height="285"
7+
ResizeMode="NoResize"
8+
ShowInTaskbar="False"
9+
WindowStartupLocation="CenterOwner">
10+
<Border Padding="24" Background="#F5F7F9">
11+
<Grid>
12+
<Grid.RowDefinitions>
13+
<RowDefinition Height="Auto" />
14+
<RowDefinition Height="Auto" />
15+
<RowDefinition Height="*" />
16+
<RowDefinition Height="Auto" />
17+
</Grid.RowDefinitions>
18+
19+
<TextBlock FontSize="22"
20+
FontWeight="SemiBold"
21+
Foreground="#263238"
22+
Text="RadioReference to RPM2" />
23+
<TextBlock x:Name="VersionText"
24+
Grid.Row="1"
25+
Margin="0,5,0,18"
26+
Foreground="#546E7A" />
27+
<StackPanel Grid.Row="2">
28+
<TextBlock TextWrapping="Wrap"
29+
Text="Downloads authorized RadioReference trunked-system data and exports Harris RPM2-compatible CSV files." />
30+
<TextBlock Margin="0,16,0,0">
31+
<Hyperlink NavigateUri="https://github.com/Brantlab/RR-to-RPM2"
32+
RequestNavigate="Hyperlink_RequestNavigate">View the project on GitHub</Hyperlink>
33+
</TextBlock>
34+
<TextBlock Margin="0,8,0,0">
35+
<Hyperlink NavigateUri="https://github.com/Brantlab/RR-to-RPM2/blob/main/howtouse.md"
36+
RequestNavigate="Hyperlink_RequestNavigate">Open the user guide</Hyperlink>
37+
</TextBlock>
38+
</StackPanel>
39+
<Button Grid.Row="3"
40+
Width="82"
41+
Padding="10,4"
42+
HorizontalAlignment="Right"
43+
IsDefault="True"
44+
IsCancel="True"
45+
Content="Close"
46+
Click="CloseButton_Click" />
47+
</Grid>
48+
</Border>
49+
</Window>

RrRpm2/AboutWindow.xaml.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System.Windows;
2+
using System.Windows.Navigation;
3+
4+
namespace RrRpm2;
5+
6+
public partial class AboutWindow : Window
7+
{
8+
public AboutWindow()
9+
{
10+
InitializeComponent();
11+
VersionText.Text = $"Version {AppInfo.DisplayVersion}";
12+
}
13+
14+
private void Hyperlink_RequestNavigate(
15+
object sender,
16+
RequestNavigateEventArgs e)
17+
{
18+
AppInfo.OpenUrl(e.Uri.AbsoluteUri);
19+
e.Handled = true;
20+
}
21+
22+
private void CloseButton_Click(object sender, RoutedEventArgs e)
23+
{
24+
Close();
25+
}
26+
}

RrRpm2/App.xaml.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
using System.IO;
22
using System.Windows;
33
using System.Windows.Threading;
4+
using RrRpm2.Services;
45

56
namespace RrRpm2;
67

78
public partial class App : Application
89
{
10+
public static TelemetryService Telemetry { get; } = new();
11+
912
private static readonly string LogPath = Path.Combine(
1013
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
1114
"RR-RPM2",
@@ -34,6 +37,7 @@ public static void LogException(Exception exception)
3437
private static void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
3538
{
3639
LogException(e.Exception);
40+
_ = Telemetry.TrackCrashAsync(e.Exception);
3741
MessageBox.Show(e.Exception.Message, "RadioReference to RPM2", MessageBoxButton.OK, MessageBoxImage.Error);
3842
e.Handled = true;
3943
}
@@ -43,12 +47,14 @@ private static void OnUnhandledException(object sender, UnhandledExceptionEventA
4347
if (e.ExceptionObject is Exception exception)
4448
{
4549
LogException(exception);
50+
_ = Telemetry.TrackCrashAsync(exception);
4651
}
4752
}
4853

4954
private static void OnUnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
5055
{
5156
LogException(e.Exception);
57+
_ = Telemetry.TrackCrashAsync(e.Exception);
5258
e.SetObserved();
5359
}
5460
}

RrRpm2/AppInfo.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System.Diagnostics;
2+
using System.Reflection;
3+
4+
namespace RrRpm2;
5+
6+
internal static class AppInfo
7+
{
8+
public const string Name = "RadioReference to RPM2";
9+
public const string RepositoryUrl = "https://github.com/Brantlab/RR-to-RPM2";
10+
public const string UserGuideUrl = RepositoryUrl + "/blob/main/howtouse.md";
11+
12+
public static string DisplayVersion
13+
{
14+
get
15+
{
16+
var informationalVersion = Assembly.GetExecutingAssembly()
17+
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
18+
?.InformationalVersion;
19+
20+
return informationalVersion?.Split('+')[0]
21+
?? Assembly.GetExecutingAssembly().GetName().Version?.ToString(3)
22+
?? "Unknown";
23+
}
24+
}
25+
26+
public static Version Version
27+
{
28+
get
29+
{
30+
var numericVersion = DisplayVersion.Split('-')[0];
31+
return System.Version.TryParse(numericVersion, out var version)
32+
? version
33+
: new Version(0, 0, 0);
34+
}
35+
}
36+
37+
public static void OpenUrl(string url)
38+
{
39+
Process.Start(new ProcessStartInfo(url)
40+
{
41+
UseShellExecute = true
42+
});
43+
}
44+
}

RrRpm2/MainWindow.xaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,23 @@
3838
</Window.Resources>
3939

4040
<DockPanel Background="#F5F7F9">
41+
<Menu DockPanel.Dock="Top" Background="#FFFFFF">
42+
<MenuItem Header="_File">
43+
<MenuItem Header="E_xit" Click="ExitMenuItem_Click" />
44+
</MenuItem>
45+
<MenuItem Header="_Help">
46+
<MenuItem Header="_User Guide" Click="UserGuideMenuItem_Click" />
47+
<MenuItem Header="View on _GitHub" Click="GitHubMenuItem_Click" />
48+
<Separator />
49+
<MenuItem x:Name="CheckForUpdatesMenuItem"
50+
Header="Check for _Updates..."
51+
Click="CheckForUpdatesMenuItem_Click" />
52+
<MenuItem Header="_Privacy &amp; Usage Statistics..."
53+
Click="TelemetryPrivacyMenuItem_Click" />
54+
<Separator />
55+
<MenuItem Header="_About..." Click="AboutMenuItem_Click" />
56+
</MenuItem>
57+
</Menu>
4158
<Border DockPanel.Dock="Top" Background="#FFFFFF" BorderBrush="#D7DEE6" BorderThickness="0,0,0,1" Padding="10,8">
4259
<Grid>
4360
<Grid.ColumnDefinitions>

0 commit comments

Comments
 (0)