Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions src/Baballonia.Tests/UtilsTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using Baballonia;
using JetBrains.Annotations;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Baballonia.Tests;

[TestClass]
[TestSubject(typeof(Utils))]
public class UtilsTest
{

[TestMethod]
public void TestFindSemVersionSuccess()
{
var version = Utils.FindVersionInString("1.2.3.4");
Assert.IsNotNull(version);

version = Utils.FindVersionInString("v1.2.3.4");
Assert.IsNotNull(version);

version = Utils.FindVersionInString("1.2.3.4rc");
Assert.IsNotNull(version);

version = Utils.FindVersionInString("v1.2.3.4rc");
Assert.IsNotNull(version);

version = Utils.FindVersionInString("random text v1.2.3.4rc more text");
Assert.IsNotNull(version);
}

[TestMethod]
public void TestFindSemVersionFail()
{
var version = Utils.FindVersionInString("1.2.3");
Assert.IsNull(version);

version = Utils.FindVersionInString("v1.2.3");
Assert.IsNull(version);

version = Utils.FindVersionInString("v1.2.3rc");
Assert.IsNull(version);

version = Utils.FindVersionInString("some random text");
Assert.IsNull(version);

version = Utils.FindVersionInString(null);
Assert.IsNull(version);

version = Utils.FindVersionInString("");
Assert.IsNull(version);
}
}
1 change: 1 addition & 0 deletions src/Baballonia/App.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public override void OnFrameworkInitializationCompleted()
services.AddSingleton<IMainService, MainStandalone>();
services.AddSingleton<ICalibrationService, CalibrationService>();
services.AddSingleton<DropOverlayService>();
services.AddSingleton<UpdateService>();

services.AddSingleton<MainViewModel>();
services.AddSingleton<MainWindow>();
Expand Down
44 changes: 44 additions & 0 deletions src/Baballonia/Controls/DropdownMessage.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<UserControl
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:templates="clr-namespace:Baballonia.Controls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="200"
x:Class="Baballonia.Controls.DropdownMessage">

<Grid>
<Border Background="{DynamicResource SystemChromeMediumColor}" x:DataType="templates:DropdownMessage"
BorderThickness="3"
BorderBrush="{DynamicResource SystemChromeBlackLowColor}" CornerRadius="16" Padding="10"
VerticalAlignment="Top"
HorizontalAlignment="Center">
<Grid ColumnDefinitions="Auto, *" MaxHeight="120">
<Border Padding="10" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Column="0">
<Image Source="/Assets/Icon_512x512.png" />
</Border>
<Grid Grid.Column="1" RowDefinitions="Auto, *" VerticalAlignment="Center">
<TextBlock Grid.Row="0" FontSize="20" FontWeight="Bold" TextWrapping="Wrap"
Text="{Binding $parent[templates:DropdownMessage].Title}" />
<Grid Grid.Row="1" ColumnDefinitions="*, Auto" VerticalAlignment="Center">
<TextBlock VerticalAlignment="Center" FontSize="16"
Text="{Binding $parent[templates:DropdownMessage].Message}"
TextWrapping="Wrap" />
<StackPanel Margin="10 0" Grid.Column="1" Orientation="Horizontal" Spacing="10">
<Button VerticalAlignment="Center" Background="#539E8A" Padding="15 10"
Command="{Binding $parent[templates:DropdownMessage].AcceptCommand}"
CornerRadius="99">
<TextBlock FontSize="15" FontWeight="Bold"
Text="{Binding $parent[templates:DropdownMessage].AcceptText}" Foreground="White" />
</Button>
<Button VerticalAlignment="Center" Padding="15 10" CornerRadius="99"
Command="{Binding $parent[templates:DropdownMessage].DeclineCommand}">
<TextBlock FontSize="15" Text="{Binding $parent[templates:DropdownMessage].DeclineText}" />
</Button>
</StackPanel>
</Grid>
</Grid>
</Grid>
</Border>
</Grid>
</UserControl>
74 changes: 74 additions & 0 deletions src/Baballonia/Controls/DropdownMessage.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System.Collections.ObjectModel;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
using CommunityToolkit.Mvvm.Input;

namespace Baballonia.Controls;


public class ButtonAction
{
public string Text { get; set; } = string.Empty;
public IRelayCommand? Command { get; set; }
}

public partial class DropdownMessage : UserControl
{
public static readonly StyledProperty<IImage?> ImageSourceProperty =
AvaloniaProperty.Register<DropdownMessage, IImage?>(nameof(ImageSource));
public static readonly StyledProperty<string> TitleProperty =
AvaloniaProperty.Register<DropdownMessage, string>(nameof(Title), string.Empty);
public static readonly StyledProperty<string> MessageProperty =
AvaloniaProperty.Register<DropdownMessage, string>(nameof(Message), string.Empty);
public static readonly StyledProperty<string> AcceptProperty =
AvaloniaProperty.Register<DropdownMessage, string>(nameof(AcceptText), string.Empty);
public static readonly StyledProperty<string> DeclineProperty =
AvaloniaProperty.Register<DropdownMessage, string>(nameof(DeclineText), string.Empty);
public static readonly StyledProperty<IRelayCommand?> AcceptCommandProperty =
AvaloniaProperty.Register<DropdownMessage, IRelayCommand?>(nameof(AcceptCommand));
public static readonly StyledProperty<IRelayCommand?> DeclineCommandProperty =
AvaloniaProperty.Register<DropdownMessage, IRelayCommand?>(nameof(DeclineCommand));
public IImage? ImageSource
{
get => GetValue(ImageSourceProperty);
set => SetValue(ImageSourceProperty, value);
}
public string Title
{
get => GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
public string Message
{
get => GetValue(MessageProperty);
set => SetValue(MessageProperty, value);
}
public string AcceptText
{
get => GetValue(AcceptProperty);
set => SetValue(AcceptProperty, value);
}
public string DeclineText
{
get => GetValue(DeclineProperty);
set => SetValue(DeclineProperty, value);
}

public IRelayCommand? AcceptCommand
{
get => GetValue(AcceptCommandProperty);
set => SetValue(AcceptCommandProperty, value);
}
public IRelayCommand? DeclineCommand
{
get => GetValue(DeclineCommandProperty);
set => SetValue(DeclineCommandProperty, value);
}

public DropdownMessage()
{
InitializeComponent();
}
}

4 changes: 2 additions & 2 deletions src/Baballonia/Services/GithubService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ static GithubService()

private static readonly HttpClient Client = new();

public async Task<List<GithubContributor>> GetContributors(string owner, string repo)
public async Task<List<GithubContributor>> FetchContributors(string owner, string repo)
{
var response = await Client.GetAsync($"https://api.github.com/repos/{owner}/{repo}/contributors");
if (!response.IsSuccessStatusCode)
Expand All @@ -30,7 +30,7 @@ public async Task<List<GithubContributor>> GetContributors(string owner, string
return JsonSerializer.Deserialize<List<GithubContributor>>(content)!;
}

public async Task<GithubRelease> GetReleases(string owner, string repo)
public async Task<GithubRelease> FetchLatestReleaseInfo(string owner, string repo)
{
var response = await Client.GetAsync($"https://api.github.com/repos/{owner}/{repo}/releases/latest");
if (!response.IsSuccessStatusCode)
Expand Down
69 changes: 69 additions & 0 deletions src/Baballonia/Services/UpdateService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System;
using System.Diagnostics;
using System.Net.Http;
using System.Reflection;
using System.Text.Json;
using System.Threading.Tasks;
using Baballonia.Models;

namespace Baballonia.Services;

public class UpdateService
{
private GithubRelease? _fetchedLatest = null;
private readonly GithubService _githubService;

public UpdateService(GithubService githubService)
{
_githubService = githubService;
}

public async Task<Version?> TryGetLatestVersion()
{
if (_fetchedLatest != null)
return Utils.FindVersionInString(_fetchedLatest.tag_name);

GithubRelease res;
try
{
res = await _githubService.FetchLatestReleaseInfo("Project-Babble", "Baballonia");
_fetchedLatest = res;
}
catch
{
return null;
}

var latestVersion = Utils.FindVersionInString(res.tag_name);

return latestVersion;
}

/// <summary>
/// Checks if current assembly is of the latest release from by the github releases
/// In absence of internet or github api assumes that current version is latest
/// </summary>
/// <returns>true if yes or error, false if no</returns>
public async Task<bool> IsLatest()
{
var latestVersion = await TryGetLatestVersion();
if (latestVersion == null)
return true;

var currentVersion = Assembly.GetExecutingAssembly().GetName().Version;
if (currentVersion == null)
throw new InvalidOperationException("Challenge Complete!: How Did We Get Here? No Assembly version found");

var versionDifference = currentVersion.CompareTo(latestVersion);

// false only if newer version exists
return versionDifference >= 0;
}

public void NavigateToLatestWebPage()
{
string url = "https://github.com/Project-Babble/Baballonia/releases/latest";
Utils.OpenUrl(url);
}

}
30 changes: 30 additions & 0 deletions src/Baballonia/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,34 @@ public static string GenerateMD5(string filepath)
var hash = hasher.ComputeHash(stream);
return BitConverter.ToString(hash).Replace("-", "");
}


/// <summary>
/// Tries to find a Version in a string using sliding window search
/// </summary>
/// <param name="str">input string</param>
/// <returns>A valid Version or null on faliure</returns>
public static Version? FindVersionInString(string str)
{
if (str == null)
return null;
var semVersionSize = "1.2.3.4".Length;
if (str.Length < semVersionSize)
return null;

Version? ver = null;
for (var i = 0; i <= str.Length - semVersionSize; i++)
{
try
{
ver = new Version(str.Substring(i, semVersionSize));
}
catch(Exception)
{
//ignore
}
}

return ver;
}
}
Loading