Skip to content

Commit b73ebe0

Browse files
committed
feat: add mock UI for file syncing listing
1 parent 13ce6b9 commit b73ebe0

17 files changed

+1155
-44
lines changed

Diff for: App/App.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.1" />
6666
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.1" />
6767
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.6.250108002" />
68+
<PackageReference Include="WinUIEx" Version="2.5.1" />
6869
</ItemGroup>
6970

7071
<ItemGroup>

Diff for: App/App.xaml

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33
<Application
44
x:Class="Coder.Desktop.App.App"
55
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
6-
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
6+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
7+
xmlns:converters="using:Coder.Desktop.App.Converters">
78
<Application.Resources>
89
<ResourceDictionary>
910
<ResourceDictionary.MergedDictionaries>
1011
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
1112
</ResourceDictionary.MergedDictionaries>
13+
14+
<converters:InverseBoolConverter x:Key="InverseBoolConverter" />
15+
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
16+
<converters:InverseBoolToVisibilityConverter x:Key="InverseBoolToVisibilityConverter" />
17+
<converters:FriendlyByteConverter x:Key="FriendlyByteConverter" />
1218
</ResourceDictionary>
1319
</Application.Resources>
1420
</Application>

Diff for: App/Controls/SizedFrame.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ public class SizedFrameEventArgs : EventArgs
1212

1313
/// <summary>
1414
/// SizedFrame extends Frame by adding a SizeChanged event, which will be triggered when:
15-
/// - The contained Page's content's size changes
16-
/// - We switch to a different page.
17-
///
15+
/// - The contained Page's content's size changes
16+
/// - We switch to a different page.
1817
/// Sadly this is necessary because Window.Content.SizeChanged doesn't trigger when the Page's content changes.
1918
/// </summary>
2019
public class SizedFrame : Frame

Diff for: App/Converters/AgentStatusToColorConverter.cs

-33
This file was deleted.

Diff for: App/Converters/DependencyObjectSelector.cs

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
using System;
2+
using System.Linq;
3+
using Windows.Foundation.Collections;
4+
using Windows.UI.Xaml.Markup;
5+
using Microsoft.UI.Xaml;
6+
using Microsoft.UI.Xaml.Data;
7+
using Microsoft.UI.Xaml.Media;
8+
9+
namespace Coder.Desktop.App.Converters;
10+
11+
// This file uses manual DependencyProperty properties rather than
12+
// DependencyPropertyGenerator since it doesn't seem to work properly with
13+
// generics.
14+
15+
public class DependencyObjectSelectorItem<TK, TV> : DependencyObject
16+
where TK : IEquatable<TK>
17+
{
18+
public static readonly DependencyProperty KeyProperty =
19+
DependencyProperty.Register(nameof(Key),
20+
typeof(TK?),
21+
typeof(DependencyObjectSelectorItem<TK, TV>),
22+
new PropertyMetadata(null));
23+
24+
public static readonly DependencyProperty ValueProperty =
25+
DependencyProperty.Register(nameof(Value),
26+
typeof(TV?),
27+
typeof(DependencyObjectSelectorItem<TK, TV>),
28+
new PropertyMetadata(null));
29+
30+
public TK? Key
31+
{
32+
get => (TK?)GetValue(KeyProperty);
33+
set => SetValue(KeyProperty, value);
34+
}
35+
36+
public TV? Value
37+
{
38+
get => (TV?)GetValue(ValueProperty);
39+
set => SetValue(ValueProperty, value);
40+
}
41+
}
42+
43+
[ContentProperty(Name = nameof(References))]
44+
public class DependencyObjectSelector<TK, TV> : DependencyObject
45+
where TK : IEquatable<TK>
46+
{
47+
public static readonly DependencyProperty ReferencesProperty =
48+
DependencyProperty.Register(nameof(References),
49+
typeof(DependencyObjectCollection),
50+
typeof(DependencyObjectSelector<TK, TV>),
51+
new PropertyMetadata(null, ReferencesPropertyChanged));
52+
53+
public static readonly DependencyProperty SelectedKeyProperty =
54+
DependencyProperty.Register(nameof(SelectedKey),
55+
typeof(TK?),
56+
typeof(DependencyObjectSelector<TK, TV>),
57+
new PropertyMetadata(null, SelectedPropertyChanged));
58+
59+
public static readonly DependencyProperty SelectedObjectProperty =
60+
DependencyProperty.Register(nameof(SelectedObject),
61+
typeof(TV?),
62+
typeof(DependencyObjectSelector<TK, TV>),
63+
new PropertyMetadata(null));
64+
65+
public DependencyObjectCollection? References
66+
{
67+
get => (DependencyObjectCollection?)GetValue(ReferencesProperty);
68+
set
69+
{
70+
// Ensure unique keys and that the values are DependencyObjectSelectorItem<K, V>.
71+
if (value != null)
72+
{
73+
var items = value.OfType<DependencyObjectSelectorItem<TK, TV>>().ToArray();
74+
var keys = items.Select(i => i.Key).Distinct().ToArray();
75+
if (keys.Length != value.Count)
76+
throw new ArgumentException("ObservableCollection Keys must be unique.");
77+
}
78+
79+
SetValue(ReferencesProperty, value);
80+
}
81+
}
82+
83+
public TK? SelectedKey
84+
{
85+
get => (TK?)GetValue(SelectedKeyProperty);
86+
set => SetValue(SelectedKeyProperty, value);
87+
}
88+
89+
public TV? SelectedObject
90+
{
91+
get => (TV?)GetValue(SelectedObjectProperty);
92+
set => SetValue(SelectedObjectProperty, value);
93+
}
94+
95+
public DependencyObjectSelector()
96+
{
97+
References = [];
98+
}
99+
100+
private void OnVectorChangedReferences(IObservableVector<DependencyObject> sender, IVectorChangedEventArgs args)
101+
{
102+
UpdateSelectedObject();
103+
}
104+
105+
private void UpdateSelectedObject()
106+
{
107+
if (References != null)
108+
{
109+
var references = References.OfType<DependencyObjectSelectorItem<TK, TV>>().ToArray();
110+
var item = references
111+
.FirstOrDefault(i =>
112+
(i.Key == null && SelectedKey == null) ||
113+
(i.Key != null && SelectedKey != null && i.Key!.Equals(SelectedKey!)))
114+
?? references.FirstOrDefault(i => i.Key == null);
115+
if (item is not null)
116+
{
117+
BindingOperations.SetBinding
118+
(
119+
this,
120+
SelectedObjectProperty,
121+
new Binding
122+
{
123+
Source = item,
124+
Path = new PropertyPath(nameof(DependencyObjectSelectorItem<TK, TV>.Value)),
125+
}
126+
);
127+
return;
128+
}
129+
}
130+
131+
ClearValue(SelectedObjectProperty);
132+
}
133+
134+
private static void ReferencesPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
135+
{
136+
var self = obj as DependencyObjectSelector<TK, TV>;
137+
if (self == null) return;
138+
var oldValue = args.OldValue as DependencyObjectCollection;
139+
if (oldValue != null)
140+
oldValue.VectorChanged -= self.OnVectorChangedReferences;
141+
var newValue = args.NewValue as DependencyObjectCollection;
142+
if (newValue != null)
143+
newValue.VectorChanged += self.OnVectorChangedReferences;
144+
}
145+
146+
private static void SelectedPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
147+
{
148+
var self = obj as DependencyObjectSelector<TK, TV>;
149+
self?.UpdateSelectedObject();
150+
}
151+
}
152+
153+
public sealed class StringToBrushSelectorItem : DependencyObjectSelectorItem<string, Brush>;
154+
155+
public sealed class StringToBrushSelector : DependencyObjectSelector<string, Brush>;

Diff for: App/Converters/FriendlyByteConverter.cs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
using Microsoft.UI.Xaml.Data;
3+
4+
namespace Coder.Desktop.App.Converters;
5+
6+
public class FriendlyByteConverter : IValueConverter
7+
{
8+
private static readonly string[] Suffixes = ["B", "KB", "MB", "GB", "TB", "PB", "EB"];
9+
10+
public object Convert(object value, Type targetType, object parameter, string language)
11+
{
12+
switch (value)
13+
{
14+
case int i:
15+
if (i < 0) i = 0;
16+
return FriendlyBytes((ulong)i);
17+
case uint ui:
18+
return FriendlyBytes(ui);
19+
case long l:
20+
if (l < 0) l = 0;
21+
return FriendlyBytes((ulong)l);
22+
case ulong ul:
23+
return FriendlyBytes(ul);
24+
default:
25+
return FriendlyBytes(0);
26+
}
27+
}
28+
29+
public object ConvertBack(object value, Type targetType, object parameter, string language)
30+
{
31+
throw new NotImplementedException();
32+
}
33+
34+
public static string FriendlyBytes(ulong bytes)
35+
{
36+
if (bytes == 0)
37+
return $"0 {Suffixes[0]}";
38+
39+
var place = System.Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
40+
var num = Math.Round(bytes / Math.Pow(1024, place), 1);
41+
return $"{num} {Suffixes[place]}";
42+
}
43+
}

Diff for: App/Converters/InverseBoolConverter.cs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using Microsoft.UI.Xaml.Data;
3+
4+
namespace Coder.Desktop.App.Converters;
5+
6+
public class InverseBoolConverter : IValueConverter
7+
{
8+
public object Convert(object value, Type targetType, object parameter, string language)
9+
{
10+
return value is false;
11+
}
12+
13+
public object ConvertBack(object value, Type targetType, object parameter, string language)
14+
{
15+
throw new NotImplementedException();
16+
}
17+
}

Diff for: App/Converters/InverseBoolToVisibilityConverter.cs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using Microsoft.UI.Xaml;
2+
3+
namespace Coder.Desktop.App.Converters;
4+
5+
public partial class InverseBoolToVisibilityConverter : BoolToObjectConverter
6+
{
7+
public InverseBoolToVisibilityConverter()
8+
{
9+
TrueValue = Visibility.Collapsed;
10+
FalseValue = Visibility.Visible;
11+
}
12+
}

0 commit comments

Comments
 (0)