Skip to content

Commit 5b532fc

Browse files
committed
Merge branch 'develop-merge-resolve' into develop
2 parents 31f958a + ed0e36c commit 5b532fc

24 files changed

Lines changed: 964 additions & 342 deletions

.github/workflows/dotnet-desktop.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ jobs:
3333
restore-keys: |
3434
${{ runner.os }}-nuget-
3535
36-
# - name: Remove Local Source for CI
37-
# run: dotnet nuget remove source LocalNuGetPackages --configfile nuget.config
36+
- name: Remove Local Source for CI
37+
run: dotnet nuget remove source LocalNuGetPackages --configfile nuget.config
3838

3939
- name: Restore NuGet packages
4040
run: dotnet restore LunaDraw.csproj --configfile nuget.config

App.xaml

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@
44
xmlns:local="clr-namespace:LunaDraw"
55
xmlns:converters="clr-namespace:LunaDraw.Converters"
66
x:Class="LunaDraw.App">
7-
<Application.Resources>
8-
<ResourceDictionary>
9-
<ResourceDictionary.MergedDictionaries>
10-
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
11-
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
12-
</ResourceDictionary.MergedDictionaries>
7+
<Application.Resources>
8+
<ResourceDictionary>
9+
<ResourceDictionary.MergedDictionaries>
10+
<ResourceDictionary Source="Resources/Styles/Colors.xaml"/>
11+
<ResourceDictionary Source="Resources/Styles/Styles.xaml"/>
12+
</ResourceDictionary.MergedDictionaries>
1313

14-
<converters:ColorToHexConverter x:Key="ColorToHexConverter"/>
15-
<converters:IsNotNullConverter x:Key="IsNotNullConverter"/>
16-
<converters:IsNullConverter x:Key="IsNullConverter"/>
17-
<converters:InverseBoolConverter x:Key="InverseBoolConverter"/>
18-
</ResourceDictionary>
19-
</Application.Resources>
14+
<converters:ColorToHexConverter x:Key="ColorToHexConverter"/>
15+
<converters:IsNotNullConverter x:Key="IsNotNullConverter"/>
16+
<converters:IsNullConverter x:Key="IsNullConverter"/>
17+
<converters:InverseBoolConverter x:Key="InverseBoolConverter"/>
18+
<converters:Base64ToImageConverter x:Key="Base64ToImageConverter"/>
19+
</ResourceDictionary>
20+
</Application.Resources>
2021
</Application>

ClearCache.bat

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dotnet nuget locals all --clear
2+
dotnet clean
3+
for /d /r . %%d in (bin,obj) do @if exist "%%d" rd /s/q "%%d"

Components/DrawingGalleryPopup.xaml

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
44
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
55
xmlns:controls="clr-namespace:CodeSoupCafe.Maui.Controls;assembly=CodeSoupCafe.Maui"
6+
xmlns:behaviors="clr-namespace:CodeSoupCafe.Maui.Behaviors;assembly=CodeSoupCafe.Maui"
67
xmlns:viewModels="clr-namespace:LunaDraw.Logic.ViewModels"
78
x:Class="LunaDraw.Components.DrawingGalleryPopup"
89
x:Name="Popup"
@@ -47,6 +48,9 @@
4748
<controls:ItemGalleryView Grid.Row="1"
4849
x:Name="GalleryView"
4950
ItemsSource="{Binding DrawingItems}"
51+
ItemAppearingAction="{Binding OnItemAppearing}"
52+
ItemDisappearingAction="{Binding OnItemDisappearing}"
53+
RemainingItemsThreshold="10"
5054
Title="Gallery"
5155
SearchPlaceholder="Search drawings..."
5256
EmptyMessage="No drawings yet. Start creating!"
@@ -85,24 +89,29 @@
8589
<Grid>
8690
<!-- Actual thumbnail -->
8791
<Image x:Name="ThumbnailImage"
88-
Source="{Binding ThumbnailSource}"
92+
Source="{Binding ThumbnailBase64, Converter={StaticResource Base64ToImageConverter}}"
8993
Aspect="AspectFit"
9094
WidthRequest="170"
9195
HeightRequest="170"
9296
HorizontalOptions="FillAndExpand"
9397
VerticalOptions="FillAndExpand"
9498
BackgroundColor="Transparent"
95-
IsVisible="{Binding ThumbnailSource, Converter={StaticResource IsNotNullConverter}}"
96-
Loaded="OnThumbnailImageLoaded"
97-
PropertyChanged="OnThumbnailImagePropertyChanged"/>
99+
IsVisible="{Binding ThumbnailBase64, Converter={StaticResource IsNotNullConverter}}"/>
100+
101+
<!-- Loading indicator -->
102+
<ActivityIndicator IsRunning="{Binding IsLoadingThumbnail}"
103+
IsVisible="{Binding IsLoadingThumbnail}"
104+
Color="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource PrimaryDark}}"
105+
HorizontalOptions="Center"
106+
VerticalOptions="Center"/>
98107

99108
<!-- Placeholder when no thumbnail -->
100109
<Label Text="🎨"
101110
FontSize="48"
102111
HorizontalOptions="Center"
103112
VerticalOptions="Center"
104113
TextColor="{AppThemeBinding Light={StaticResource PlaceholderTextLight}, Dark={StaticResource PlaceholderTextDark}}"
105-
IsVisible="{Binding ThumbnailSource, Converter={StaticResource IsNullConverter}}"/>
114+
IsVisible="{Binding ThumbnailBase64, Converter={StaticResource IsNullConverter}}"/>
106115
</Grid>
107116
</Border>
108117

Components/DrawingGalleryPopup.xaml.cs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,6 @@ public DrawingGalleryPopup(DrawingGalleryPopupViewModel viewModel)
3636
InitializeComponent();
3737
BindingContext = viewModel;
3838

39-
viewModel.DrawingItems.CollectionChanged += (s, e) =>
40-
{
41-
GalleryView.ItemsSource = null;
42-
GalleryView.ItemsSource = viewModel.DrawingItems;
43-
};
44-
4539
viewModel.RequestClose += OnRequestClose;
4640
}
4741

@@ -53,14 +47,6 @@ private void OnDrawingItemTapped(object? sender, EventArgs e)
5347
}
5448
}
5549

56-
private void OnThumbnailImageLoaded(object? sender, EventArgs e)
57-
{
58-
}
59-
60-
private void OnThumbnailImagePropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
61-
{
62-
}
63-
6450
private async void OnRequestClose(object? sender, EventArgs e)
6551
{
6652
await this.CloseAsync();
@@ -74,10 +60,10 @@ protected override void OnHandlerChanged()
7460
if (Handler == null && BindingContext is DrawingGalleryPopupViewModel vm)
7561
{
7662
vm.RequestClose -= OnRequestClose;
77-
63+
7864
if (vm is IDisposable disposable)
7965
{
80-
disposable.Dispose();
66+
disposable.Dispose();
8167
}
8268
}
8369
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) 2025 CodeSoupCafe LLC
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*
22+
*/
23+
24+
using System.Globalization;
25+
26+
namespace LunaDraw.Converters;
27+
28+
public class Base64ToImageConverter : IValueConverter
29+
{
30+
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
31+
{
32+
if (value is not string base64String || string.IsNullOrEmpty(base64String))
33+
{
34+
return null;
35+
}
36+
37+
try
38+
{
39+
var bytes = System.Convert.FromBase64String(base64String);
40+
return ImageSource.FromStream(() => new MemoryStream(bytes));
41+
}
42+
catch
43+
{
44+
return null;
45+
}
46+
}
47+
48+
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
49+
{
50+
throw new NotImplementedException();
51+
}
52+
}

Logic/Extensions/SkiaSharpExtensions.cs

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -263,39 +263,39 @@ public static SKMatrix MaxScaleCentered(this SKCanvas canvas,
263263

264264
public static string ToHex(this SKColor color, bool includeAlpha = true)
265265
{
266-
if (includeAlpha)
267-
{
268-
return $"#{color.Alpha:X2}{color.Red:X2}{color.Green:X2}{color.Blue:X2}";
269-
}
270-
else
271-
{
272-
return $"#{color.Red:X2}{color.Green:X2}{color.Blue:X2}";
273-
}
266+
if (includeAlpha)
267+
{
268+
return $"#{color.Alpha:X2}{color.Red:X2}{color.Green:X2}{color.Blue:X2}";
269+
}
270+
else
271+
{
272+
return $"#{color.Red:X2}{color.Green:X2}{color.Blue:X2}";
273+
}
274274
}
275275

276276
public static SKColor ToSKColor(this string hex)
277277
{
278-
if (string.IsNullOrEmpty(hex))
279-
{
280-
return SKColors.Transparent;
281-
}
278+
if (string.IsNullOrEmpty(hex))
279+
{
280+
return SKColors.Transparent;
281+
}
282282

283-
// Remove # if present
284-
if (hex.StartsWith("#"))
285-
{
286-
hex = hex.Substring(1);
287-
}
283+
// Remove # if present
284+
if (hex.StartsWith("#"))
285+
{
286+
hex = hex.Substring(1);
287+
}
288288

289-
if (hex.Length == 6) // RGB
290-
{
291-
return SKColor.Parse(hex);
292-
}
293-
else if (hex.Length == 8) // ARGB
294-
{
295-
return SKColor.Parse(hex);
296-
}
297-
298-
// Default to transparent if parsing fails
299-
return SKColors.Transparent;
289+
if (hex.Length == 6) // RGB
290+
{
291+
return SKColor.Parse(hex);
292+
}
293+
else if (hex.Length == 8) // ARGB
294+
{
295+
return SKColor.Parse(hex);
296+
}
297+
298+
// Default to transparent if parsing fails
299+
return SKColors.Transparent;
300300
}
301301
}

Logic/Models/NavigationModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,4 @@ public void Reset()
5555
{
5656
ViewMatrix = SKMatrix.CreateIdentity();
5757
}
58-
}
58+
}

0 commit comments

Comments
 (0)