Skip to content

Commit

Permalink
Erorrs and other fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
mateusz-kierepka-hl committed Jan 19, 2025
1 parent f530180 commit 76c0472
Show file tree
Hide file tree
Showing 23 changed files with 542 additions and 43 deletions.
2 changes: 2 additions & 0 deletions .idea/.idea.ChatAAC/.idea/avalonia.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions ChatAAC/ChatAAC.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@
<LangVersion>default</LangVersion>
</PropertyGroup>

<PropertyGroup>
<CFBundleName>ChatAAC</CFBundleName> <!-- Also defines .app file name -->
<CFBundleDisplayName>Chat AI for AAC (Augmentative and alternative communication)</CFBundleDisplayName>
<CFBundleIdentifier>com.kierepka.chataac</CFBundleIdentifier>
<CFBundleVersion>1.0.0</CFBundleVersion>
<CFBundleShortVersionString>1</CFBundleShortVersionString>
<CFBundlePackageType>APPL</CFBundlePackageType>
<CFBundleExecutable>ChatAAC</CFBundleExecutable>
<CFBundleIconFile>ChatAAC.icns</CFBundleIconFile> <!-- Will be copied from output directory -->
<NSPrincipalClass>NSApplication</NSPrincipalClass>
<NSHighResolutionCapable>true</NSHighResolutionCapable>
</PropertyGroup>

<ItemGroup>
<AvaloniaResource Include="Assets\**"/>
</ItemGroup>
Expand All @@ -31,6 +44,7 @@
<PackageReference Include="Avalonia.Xaml.Interactivity" Version="11.2.0.6"/>
<PackageReference Include="BinToss.GroupBox.Avalonia" Version="1.0.0"/>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
<PackageReference Include="DotNet.Bundle" Version="0.9.13" />
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="9.0.0"/>
<PackageReference Include="Microsoft.SemanticKernel" Version="1.32.0"/>
<PackageReference Include="OllamaSharp" Version="4.0.17"/>
Expand All @@ -55,5 +69,9 @@
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Update="Views\EditGridWindow.axaml.cs">
<DependentUpon>EditGridWindow.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
</Project>
33 changes: 25 additions & 8 deletions ChatAAC/Converters/ColorConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,46 @@ namespace ChatAAC.Converters;

public class ColorConverter : IValueConverter
{

public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is not string colorString) return Colors.Transparent;

if (value is not string colorString) return Brushes.Transparent;
if (string.IsNullOrEmpty(colorString)) return Colors.Transparent;

Color color;

try
{
// Avalonia supports Color.Parse for hex or named colors
color = Color.Parse(colorString);
}
catch
{
color = Colors.Transparent;
}

try
{
var rgb = colorString.Split(['(', ',', ')'], StringSplitOptions.RemoveEmptyEntries)
.Skip(1) // Skip "rgb"
.Select(int.Parse).ToList();
return Color.FromArgb(255, (byte)rgb[0], (byte)rgb[1], (byte)rgb[2]);
color = Color.FromArgb(255, (byte)rgb[0], (byte)rgb[1], (byte)rgb[2]);
}
catch
{
return Colors.Transparent;
color = Colors.Transparent;
}


return new SolidColorBrush(color);
}

public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
// If you need two-way binding, parse the brush back to a string.
// Otherwise, just return null for one-way.
if (value is SolidColorBrush brush)
return brush.Color.ToString();
return null;
}


}
50 changes: 50 additions & 0 deletions ChatAAC/Converters/ContrastForegroundBrushConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using System.Globalization;
using Avalonia.Data.Converters;
using Avalonia.Media;

namespace ChatAAC.Converters
{
/// <summary>
/// Returns a brush with a contrasting color (white or black)
/// compared to the given background color.
/// </summary>
public class ContrastForegroundBrushConverter : IValueConverter
{
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is not SolidColorBrush backgroundBrush) return Brushes.Black; // fallback
var color = backgroundBrush.Color;

// Compute luminance (0..1)
var luminance = ComputeRelativeLuminance(color);

// If the background is dark, return White, else Black
return luminance < 0.5 ? Brushes.White : Brushes.Black;
}

public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
// Usually one-way binding, so no need to convert back
return null!;
}

private static double ComputeRelativeLuminance(Color color)
{
// Standard formula for relative luminance (from W3C):
// https://www.w3.org/TR/WCAG20/#relativeluminancedef
// R, G, B are in [0..1].
var r = color.R / 255.0;
var g = color.G / 255.0;
var b = color.B / 255.0;

// Apply gamma correction
r = (r <= 0.03928) ? (r / 12.92) : Math.Pow((r + 0.055) / 1.055, 2.4);
g = (g <= 0.03928) ? (g / 12.92) : Math.Pow((g + 0.055) / 1.055, 2.4);
b = (b <= 0.03928) ? (b / 12.92) : Math.Pow((b + 0.055) / 1.055, 2.4);

// 0.2126 R + 0.7152 G + 0.0722 B
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}
}
}
12 changes: 6 additions & 6 deletions ChatAAC/Converters/IntOrStringArrayConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ namespace ChatAAC.Converters;
public class IntOrStringArrayConverter : JsonConverter<string?[][]>
{
public override string?[][] Read(ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
Type typeToConvert,
JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartArray)
throw new JsonException("Expected start of array.");
Expand Down Expand Up @@ -70,15 +70,16 @@ public class IntOrStringArrayConverter : JsonConverter<string?[][]>
throw new JsonException($"Unsupported token {reader.TokenType} in inner array");
}
}

result.Add(innerList);
}

return result.Select(lst => lst.ToArray()).ToArray();
}

public override void Write(Utf8JsonWriter writer,
string?[][]? value,
JsonSerializerOptions options)
string?[][]? value,
JsonSerializerOptions options)
{
if (value == null)
{
Expand All @@ -91,16 +92,15 @@ public override void Write(Utf8JsonWriter writer,
{
writer.WriteStartArray();
foreach (var item in inner)
{
if (int.TryParse(item, out var number))
writer.WriteNumberValue(number);
else if (item == null)
writer.WriteNullValue();
else
writer.WriteStringValue(item);
}
writer.WriteEndArray();
}

writer.WriteEndArray();
}
}
4 changes: 0 additions & 4 deletions ChatAAC/Converters/IntOrStringConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,8 @@ public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerO
{
// If value can be parsed as int, write as number; otherwise, write as string
if (int.TryParse(value, out var number))
{
writer.WriteNumberValue(number);
}
else
{
writer.WriteStringValue(value);
}
}
}
18 changes: 18 additions & 0 deletions ChatAAC/Converters/NotNullToBoolConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Globalization;
using Avalonia.Data.Converters;

namespace ChatAAC.Converters;

public class NotNullToBoolConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
return value != null; // If it’s not null, return true
}

public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
return null; // Typically not used
}
}
2 changes: 1 addition & 1 deletion ChatAAC/Converters/OrderConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class OrderConverter : JsonConverter<int?[][]>
innerList.Add(reader.GetInt32());
break;
case JsonTokenType.String:
innerList.Add( int.Parse(reader.GetString() ?? "0"));
innerList.Add(int.Parse(reader.GetString() ?? "0"));
break;
case JsonTokenType.None:
case JsonTokenType.StartObject:
Expand Down
3 changes: 1 addition & 2 deletions ChatAAC/Models/Obf/Button.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ public class Button
[JsonConverter(typeof(IntOrStringConverter))]
public string Id { get; set; } = string.Empty;

[JsonPropertyName("label")]
public string Label { get; set; } = string.Empty;
[JsonPropertyName("label")] public string Label { get; set; } = string.Empty;

[JsonPropertyName("image_id")]
[JsonConverter(typeof(IntOrStringConverter))]
Expand Down
2 changes: 1 addition & 1 deletion ChatAAC/Models/Obf/LoadBoard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace ChatAAC.Models.Obf;
// Class for LoadBoard (button linked to another board)
public class LoadBoard
{
[JsonPropertyName("id")]
[JsonPropertyName("id")]
[JsonConverter(typeof(IntOrStringConverter))]
public string Id { get; set; } = string.Empty;

Expand Down
2 changes: 1 addition & 1 deletion ChatAAC/Models/Obf/ObfFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class ObfFile

[JsonPropertyName("license")] public License License { get; set; } = new();

[JsonPropertyName("id")]
[JsonPropertyName("id")]
[JsonConverter(typeof(IntOrStringConverter))]
public string Id { get; set; } = string.Empty;

Expand Down
7 changes: 4 additions & 3 deletions ChatAAC/Models/Obf/ObfLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using ChatAAC.Lang;
using ChatAAC.Lang;

namespace ChatAAC.Models.Obf;

Expand Down Expand Up @@ -64,9 +63,11 @@ public static partial class ObfLoader
// Match the corresponding image
button.Image = obfFile.Images.Find(image => image.Id == button.ImageId);
if (button.Image == null)
Console.WriteLine(Resources.ObfLoader_LoadObfAsync_No_image_found_for_button_with_ID___0_, button.Id);
Console.WriteLine(Resources.ObfLoader_LoadObfAsync_No_image_found_for_button_with_ID___0_,
button.Id);
if (string.IsNullOrEmpty(button.Label))
Console.WriteLine(Resources.ObfLoader_LoadObfAsync_Missing_label_for_button_with_ID___0_, button.Id);
Console.WriteLine(Resources.ObfLoader_LoadObfAsync_Missing_label_for_button_with_ID___0_,
button.Id);
}

return obfFile;
Expand Down
3 changes: 1 addition & 2 deletions ChatAAC/Services/BoardLoaderService.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
Expand Down Expand Up @@ -108,7 +107,7 @@ private async Task LoadObzFileAsync(string filePath)
var manifest = JsonSerializer.Deserialize<Manifest>(manifestJson);

// Construct the path to the root OBF file
var rootObfPath = Path.Combine(destinationDirectory, Path.GetFileName( manifest?.Root ?? "root.obf"));
var rootObfPath = Path.Combine(destinationDirectory, Path.GetFileName(manifest?.Root ?? "root.obf"));
if (File.Exists(rootObfPath))
// Load the root OBF file
await LoadObfFileAsync(rootObfPath);
Expand Down
2 changes: 1 addition & 1 deletion ChatAAC/ViewModels/BoardPathsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ private void CloseWindow()
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
// We look for the active window, or a specialized approach
var topMost = desktop.Windows[^1];
var topMost = desktop.Windows[^1];
topMost.Close();
}
}
Expand Down
Loading

0 comments on commit 76c0472

Please sign in to comment.