Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: add mock UI for file syncing listing#60

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
deansheather merged 5 commits intomainfromdean/file-sync-ui-mock
Mar 25, 2025
Merged
Show file tree
Hide file tree
Changes fromall 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
1 change: 1 addition & 0 deletionsApp/App.csproj
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -65,6 +65,7 @@
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.1" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.6.250108002" />
<PackageReference Include="WinUIEx" Version="2.5.1" />
</ItemGroup>

<ItemGroup>
Expand Down
8 changes: 7 additions & 1 deletionApp/App.xaml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,12 +3,18 @@
<Application
x:Class="Coder.Desktop.App.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="using:Coder.Desktop.App.Converters">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
</ResourceDictionary.MergedDictionaries>

<converters:InverseBoolConverter x:Key="InverseBoolConverter" />
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<converters:InverseBoolToVisibilityConverter x:Key="InverseBoolToVisibilityConverter" />
<converters:FriendlyByteConverter x:Key="FriendlyByteConverter" />
</ResourceDictionary>
</Application.Resources>
</Application>
5 changes: 5 additions & 0 deletionsApp/App.xaml.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,6 +47,11 @@ public App()
services.AddTransient<SignInViewModel>();
services.AddTransient<SignInWindow>();

// FileSyncListWindow views and view models
services.AddTransient<FileSyncListViewModel>();
// FileSyncListMainPage is created by FileSyncListWindow.
services.AddTransient<FileSyncListWindow>();

// TrayWindow views and view models
services.AddTransient<TrayWindowLoadingPage>();
services.AddTransient<TrayWindowDisconnectedViewModel>();
Expand Down
5 changes: 2 additions & 3 deletionsApp/Controls/SizedFrame.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,9 +12,8 @@ public class SizedFrameEventArgs : EventArgs

/// <summary>
/// SizedFrame extends Frame by adding a SizeChanged event, which will be triggered when:
/// - The contained Page's content's size changes
/// - We switch to a different page.
///
/// - The contained Page's content's size changes
/// - We switch to a different page.
/// Sadly this is necessary because Window.Content.SizeChanged doesn't trigger when the Page's content changes.
/// </summary>
public class SizedFrame : Frame
Expand Down
33 changes: 0 additions & 33 deletionsApp/Converters/AgentStatusToColorConverter.cs
View file
Open in desktop

This file was deleted.

188 changes: 188 additions & 0 deletionsApp/Converters/DependencyObjectSelector.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
using System;
using System.Linq;
using Windows.Foundation.Collections;
using Windows.UI.Xaml.Markup;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Media;

namespace Coder.Desktop.App.Converters;

// This file uses manual DependencyProperty properties rather than
// DependencyPropertyGenerator since it doesn't seem to work properly with
// generics.

/// <summary>
/// An item in a DependencyObjectSelector. Each item has a key and a value.
/// The default item in a DependencyObjectSelector will be the only item
/// with a null key.
/// </summary>
/// <typeparam name="TK">Key type</typeparam>
/// <typeparam name="TV">Value type</typeparam>
public class DependencyObjectSelectorItem<TK, TV> : DependencyObject
where TK : IEquatable<TK>
{
public static readonly DependencyProperty KeyProperty =
DependencyProperty.Register(nameof(Key),
typeof(TK?),
typeof(DependencyObjectSelectorItem<TK, TV>),
new PropertyMetadata(null));

public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(nameof(Value),
typeof(TV?),
typeof(DependencyObjectSelectorItem<TK, TV>),
new PropertyMetadata(null));

public TK? Key
{
get => (TK?)GetValue(KeyProperty);
set => SetValue(KeyProperty, value);
}

public TV? Value
{
get => (TV?)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
}

/// <summary>
/// Allows selecting between multiple value references based on a selected
/// key. This allows for dynamic mapping of model values to other objects.
/// The main use case is for selecting between other bound values, which
/// you cannot do with a simple ValueConverter.
/// </summary>
/// <typeparam name="TK">Key type</typeparam>
/// <typeparam name="TV">Value type</typeparam>
[ContentProperty(Name = nameof(References))]
public class DependencyObjectSelector<TK, TV> : DependencyObject
where TK : IEquatable<TK>
{
public static readonly DependencyProperty ReferencesProperty =
DependencyProperty.Register(nameof(References),
typeof(DependencyObjectCollection),
typeof(DependencyObjectSelector<TK, TV>),
new PropertyMetadata(null, ReferencesPropertyChanged));

public static readonly DependencyProperty SelectedKeyProperty =
DependencyProperty.Register(nameof(SelectedKey),
typeof(TK?),
typeof(DependencyObjectSelector<TK, TV>),
new PropertyMetadata(null, SelectedKeyPropertyChanged));

public static readonly DependencyProperty SelectedObjectProperty =
DependencyProperty.Register(nameof(SelectedObject),
typeof(TV?),
typeof(DependencyObjectSelector<TK, TV>),
new PropertyMetadata(null));

public DependencyObjectCollection? References
{
get => (DependencyObjectCollection?)GetValue(ReferencesProperty);
set
{
// Ensure unique keys and that the values are DependencyObjectSelectorItem<K, V>.
if (value != null)
{
var items = value.OfType<DependencyObjectSelectorItem<TK, TV>>().ToArray();
var keys = items.Select(i => i.Key).Distinct().ToArray();
if (keys.Length != value.Count)
throw new ArgumentException("ObservableCollection Keys must be unique.");
}

SetValue(ReferencesProperty, value);
}
}

/// <summary>
/// The key of the selected item. This should be bound to a property on
/// the model.
/// </summary>
public TK? SelectedKey
{
get => (TK?)GetValue(SelectedKeyProperty);
set => SetValue(SelectedKeyProperty, value);
}

/// <summary>
/// The selected object. This can be read from to get the matching
/// object for the selected key. If the selected key doesn't match any
/// object, this will be the value of the null key. If there is no null
/// key, this will be null.
/// </summary>
public TV? SelectedObject
{
get => (TV?)GetValue(SelectedObjectProperty);
set => SetValue(SelectedObjectProperty, value);
}

public DependencyObjectSelector()
{
References = [];
}

private void UpdateSelectedObject()
{
if (References != null)
{
// Look for a matching item a matching key, or fallback to the null
// key.
var references = References.OfType<DependencyObjectSelectorItem<TK, TV>>().ToArray();
var item = references
.FirstOrDefault(i =>
(i.Key == null && SelectedKey == null) ||
(i.Key != null && SelectedKey != null && i.Key!.Equals(SelectedKey!)))
?? references.FirstOrDefault(i => i.Key == null);
if (item is not null)
{
// Bind the SelectedObject property to the reference's Value.
// If the underlying Value changes, it will propagate to the
// SelectedObject.
BindingOperations.SetBinding
(
this,
SelectedObjectProperty,
new Binding
{
Source = item,
Path = new PropertyPath(nameof(DependencyObjectSelectorItem<TK, TV>.Value)),
}
);
return;
}
}

ClearValue(SelectedObjectProperty);
}

// Called when the References property is replaced.
private static void ReferencesPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
var self = obj as DependencyObjectSelector<TK, TV>;
if (self == null) return;
var oldValue = args.OldValue as DependencyObjectCollection;
if (oldValue != null)
oldValue.VectorChanged -= self.OnVectorChangedReferences;
var newValue = args.NewValue as DependencyObjectCollection;
if (newValue != null)
newValue.VectorChanged += self.OnVectorChangedReferences;
}

// Called when the References collection changes without being replaced.
private void OnVectorChangedReferences(IObservableVector<DependencyObject> sender, IVectorChangedEventArgs args)
{
UpdateSelectedObject();
}

// Called when SelectedKey changes.
private static void SelectedKeyPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
var self = obj as DependencyObjectSelector<TK, TV>;
self?.UpdateSelectedObject();
}
}

public sealed class StringToBrushSelectorItem : DependencyObjectSelectorItem<string, Brush>;

public sealed class StringToBrushSelector : DependencyObjectSelector<string, Brush>;
43 changes: 43 additions & 0 deletionsApp/Converters/FriendlyByteConverter.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
using System;
using Microsoft.UI.Xaml.Data;

namespace Coder.Desktop.App.Converters;

public class FriendlyByteConverter : IValueConverter
{
private static readonly string[] Suffixes = ["B", "KB", "MB", "GB", "TB", "PB", "EB"];

public object Convert(object value, Type targetType, object parameter, string language)
{
switch (value)
{
case int i:
if (i < 0) i = 0;
return FriendlyBytes((ulong)i);
case uint ui:
return FriendlyBytes(ui);
case long l:
if (l < 0) l = 0;
return FriendlyBytes((ulong)l);
case ulong ul:
return FriendlyBytes(ul);
default:
return FriendlyBytes(0);
}
}

public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}

public static string FriendlyBytes(ulong bytes)
{
if (bytes == 0)
return $"0 {Suffixes[0]}";

var place = System.Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
var num = Math.Round(bytes / Math.Pow(1024, place), 1);
return $"{num} {Suffixes[place]}";
}
}
17 changes: 17 additions & 0 deletionsApp/Converters/InverseBoolConverter.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
using System;
using Microsoft.UI.Xaml.Data;

namespace Coder.Desktop.App.Converters;

public class InverseBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return value is false;
}

public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
12 changes: 12 additions & 0 deletionsApp/Converters/InverseBoolToVisibilityConverter.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
using Microsoft.UI.Xaml;

namespace Coder.Desktop.App.Converters;

public partial class InverseBoolToVisibilityConverter : BoolToObjectConverter
{
public InverseBoolToVisibilityConverter()
{
TrueValue = Visibility.Collapsed;
FalseValue = Visibility.Visible;
}
}
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp