Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port from WPF to Avalonia #361

Merged
merged 62 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
370ad0d
WIP: avalonia port
Mrxx99 Aug 13, 2023
87f503b
added UserControlBase to not have to add DoNotNotifyAttribute to ever…
Mrxx99 Aug 13, 2023
66e3b57
small fix
Mrxx99 Aug 13, 2023
6a782ae
Merge from develop
Mrxx99 Aug 13, 2023
e6f8190
removed WPF Stylet reference
Mrxx99 Aug 13, 2023
6b27939
display window icon
Mrxx99 Aug 13, 2023
59e31bb
fixed query textbox background
Mrxx99 Aug 13, 2023
df71416
Update YoutubeDownloader/YoutubeDownloader.csproj
Mrxx99 Aug 14, 2023
b132dfa
implemented some feedback
Mrxx99 Aug 14, 2023
71df82d
removed vs files
Mrxx99 Aug 14, 2023
b1c931f
Merge branch 'feature/avalonia-port' of https://github.com/Mrxx99/You…
Mrxx99 Aug 14, 2023
b6dfe67
Merge branch 'master' into feature/avalonia-port
Mrxx99 Aug 14, 2023
8ec0ba2
updated to avalonina 11.0.4
Mrxx99 Aug 19, 2023
ad75a3c
removed MessageBox.Avalonia package since it's not used
Mrxx99 Aug 19, 2023
ca8728b
updated Material.Avalonia to latest nightly
Mrxx99 Aug 20, 2023
c4a4f51
use async Task instead of async void and normal binding instead of st…
Mrxx99 Aug 22, 2023
90ed00b
try webview with CefGlue
Mrxx99 Sep 4, 2023
7070c55
Merge branch 'master' into feature/avalonia-port
Tyrrrz Sep 30, 2023
4d6503f
updated dependencies
Mrxx99 Oct 18, 2023
8197224
Merge remote-tracking branch 'origin/feature/avalonia-port' into feat…
Mrxx99 Oct 18, 2023
f9ef424
resolve merge conflicts
Mrxx99 Oct 18, 2023
a37523a
fixed csproj
Mrxx99 Oct 18, 2023
59f8ba6
updated Avalonia dependencies
Mrxx99 Feb 14, 2024
0d6c6ef
fixed search textbox theme issue
Mrxx99 Feb 14, 2024
daeb1f7
Merge remote-tracking branch 'origin/master' into feature/avalonia-port
Mrxx99 Feb 14, 2024
097073a
missing merge in SettingsView
Mrxx99 Feb 14, 2024
021903e
remove leftover exception handler from WPF
Mrxx99 Feb 15, 2024
69ae19b
working auth on Windows
Mrxx99 Feb 15, 2024
b1523bb
some setting fixes
Mrxx99 Feb 19, 2024
220c768
remove Stylet.Avalonia
Mrxx99 Feb 19, 2024
fb33cd4
fix formatting
Mrxx99 Feb 20, 2024
475f6db
fix scrollbar visible in query textbox
Mrxx99 Feb 20, 2024
2ec3918
fix not displaying title
Mrxx99 Feb 20, 2024
4e9053f
fix margin of ProcessQueryButton
Mrxx99 Feb 20, 2024
16a281d
improved style of file name template textbox
Mrxx99 Feb 20, 2024
a158bf2
some cleanup and improvements
Mrxx99 Feb 22, 2024
7fbad0e
properly getting dark mode of platform
Mrxx99 Feb 23, 2024
56acb0e
add missing close button in settings
Mrxx99 Feb 23, 2024
84e2713
removed unused control
Mrxx99 Feb 23, 2024
8941e6f
enabled compiled bindings
Mrxx99 Feb 23, 2024
386bcf0
disable close on clickaway for the popups
Mrxx99 Feb 23, 2024
157776f
calling copy error message when clicking on failure status
Mrxx99 Feb 23, 2024
18ec0ba
fixed wrongly using accent color on datagrid buttons
Mrxx99 Feb 23, 2024
bd1c358
remove commented out, not required line
Mrxx99 Feb 23, 2024
4b4c6e0
disable main grid when popup is open
Mrxx99 Feb 23, 2024
4b97414
disabled compiled bindings because of bug with generics
Mrxx99 Feb 23, 2024
eff89a9
updated Material.Avalonia to 3.4.1 to fix theme change issue
Mrxx99 Feb 26, 2024
4bbe9fa
removed unused xaml namespaces
Mrxx99 Feb 26, 2024
88d778e
improved getting toplevel
Mrxx99 Feb 26, 2024
ab96b5b
fix unsubscribing from event when view unloaded
Mrxx99 Feb 26, 2024
52af6f5
fix dialog result not recognized from command parameter
Mrxx99 Feb 26, 2024
1d9d14d
updated Material.Avalonia to 3.4.2 to include snackbar layout fix
Mrxx99 Feb 28, 2024
caac0fd
Update YoutubeDownloader/app.manifest
Mrxx99 Mar 1, 2024
f24c85e
renamed SnackbarService.PostDefault to Post
Mrxx99 Mar 1, 2024
47c471a
use MVVM toolkit commands for binding to methods
Mrxx99 Mar 1, 2024
69f5ffe
using AcitvatorUtilities.GetServiceOrCreateInstance to be able to res…
Mrxx99 Mar 1, 2024
4afc9e9
make ViewModelAwareUserControl generic, introduce ViewModel property
Mrxx99 Mar 1, 2024
880504e
removed not needed WebBrowser_OnNavigationCompleted event handler
Mrxx99 Mar 1, 2024
a100302
simplify logout button
Mrxx99 Mar 2, 2024
d66dd9e
remove unused WebView event handler
Mrxx99 Mar 5, 2024
fd72e7b
add Async PostFix and fix commands
Mrxx99 Mar 11, 2024
e1d4189
set application icon
Mrxx99 Mar 23, 2024
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
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>

<PropertyGroup>
<TargetFramework>net7.0-windows</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<Version>1.10.1</Version>
<Company>Tyrrrz</Company>
<Copyright>Copyright (C) Oleksii Holub</Copyright>
Expand Down
10 changes: 5 additions & 5 deletions YoutubeDownloader.sln
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27428.2015
# Visual Studio Version 17
VisualStudioVersion = 17.7.33920.267
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YoutubeDownloader", "YoutubeDownloader\YoutubeDownloader.csproj", "{AF6D645E-DDDD-4034-B644-D5328CC893C1}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YoutubeDownloader", "YoutubeDownloader\YoutubeDownloader.csproj", "{AF6D645E-DDDD-4034-B644-D5328CC893C1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{131C2561-E5A1-43E8-BF38-40E2E23DB0A4}"
ProjectSection(SolutionItems) = preProject
Changelog.md = Changelog.md
Directory.Build.props = Directory.Build.props
License.txt = License.txt
Readme.md = Readme.md
Directory.Build.props = Directory.Build.props
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YoutubeDownloader.Core", "YoutubeDownloader.Core\YoutubeDownloader.Core.csproj", "{5122A9DE-232C-4DA8-AD76-8B72AA377D5E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YoutubeDownloader.Core", "YoutubeDownloader.Core\YoutubeDownloader.Core.csproj", "{5122A9DE-232C-4DA8-AD76-8B72AA377D5E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
540 changes: 88 additions & 452 deletions YoutubeDownloader/App.xaml

Large diffs are not rendered by default.

120 changes: 99 additions & 21 deletions YoutubeDownloader/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
using System;
using System;
using System.Net;
using System.Reflection;
using System.Windows.Media;
using MaterialDesignThemes.Wpf;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Input.Platform;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.Styling;
using AvaloniaWebView;
using Material.Styles.Themes;
using PropertyChanged;
using Stylet;
using StyletIoC;
using YoutubeDownloader.Services;
using YoutubeDownloader.Utils;
using YoutubeDownloader.ViewModels;
using YoutubeDownloader.ViewModels.Framework;

namespace YoutubeDownloader;

public partial class App
{
private static Assembly Assembly { get; } = Assembly.GetExecutingAssembly();

public static string Name { get; } = Assembly.GetName().Name!;
public new static string Name { get; } = Assembly.GetName().Name!;

public static Version Version { get; } = Assembly.GetName().Version!;

Expand All @@ -21,37 +33,103 @@
public static string ChangelogUrl { get; } = ProjectUrl + "/blob/master/Changelog.md";
}

public partial class App
[DoNotNotify]
public partial class App : StyletApplication<RootViewModel>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a specific reason you merged the bootstrapper with the App?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we need Stylet at all? I remember we discussed this and you said Avalonia already provides many of its features out of the box (such as method binding). Does Avalonia have something for binding views to view models automatically too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had started first without Stylet because it was still lacking behind in Avalonia previews when Avalonia 11 was still in preview. But since somethings changed with Avalonia till the release and also YoutubeDownloader moved forward I somewhat started again to not miss any of the changes. When I started again I used Stylet.Avalonia because it was faster. But I can again migrate of it. A drawback of the Stylet.Avalonia (which is a independet fork of Stylet) is also that is completey switched its readme to Chinese only.

Yes Avalonia has some parts already build in like binding to methods form commands (not from events) and one can easily build a general ViewLocator which is provided with the MVVM templates. I can change to that approach together with CommunityToolkit.MVVM from microsoft for some MVVM stuff. But I ended up rebuild some parts of Stylet, it would not be a problem for me since I had done that already.
You can also look at my first attempt here: https://github.dev/Mrxx99/YoutubeDownloader/tree/Avalonia/YoutubeDownloader.Avaloniav11

We could also wait until Caliburn.Micro is released (officially) for Avalonia which should be (hopefully) soon: Caliburn-Micro/Caliburn.Micro#851

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes Avalonia has some parts already build in like binding to methods form commands (not from events) and one can easily build a general ViewLocator which is provided with the MVVM templates. I can change to that approach together with CommunityToolkit.MVVM from microsoft for some MVVM stuff. But I ended up rebuild some parts of Stylet, it would not be a problem for me since I had done that already.

I'm pretty ambivalent, I think. We already have some "plumbing code" in ViewModels/Framework I think, so it wouldn't be too big of a deal if we added more. I'm also not opposed to adding 3rd party packages, as long as they're fairly widely used and are trustworthy.

I'll leave the decision up to you, let's go with whatever you think provides the best balance in terms of effort/control.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one can easily build a general ViewLocator which is provided with the MVVM templates. I can change to that approach together with CommunityToolkit.MVVM

if you're thinking of using the CommunityToolkit.MVVM tools, they also built a DependencyInjection package with source generators that:

  • Makes the service registration completely trim/AOT-friendly
  • Provides built-time diagnostics on registration errors

With that, it's possible to build an improved version of the ViewLocator. Here's a demo project from @stevemonaco that uses the DI package.

The package is experimental, but apparently it is used in production and they're just waiting for the first chance to push it into the stable Nuget feed.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The package is experimental, but apparently it is used in production and they're just waiting for the first chance to push it into the stable Nuget feed.

I asked Sergio about this in the past week or so. He said that his MEDI sourcegen is currently being used in Windows Store, but he's lacking the time to move the code base/packaging into CommunityToolkit proper.

{
private static Theme LightTheme { get; } = Theme.Create(
new MaterialDesignLightTheme(),
MediaColor.FromHex("#343838"),
MediaColor.FromHex("#F9A825")
Theme.Light,
Color.Parse("#343838"),
Color.Parse("#F9A825")
);

private static Theme DarkTheme { get; } = Theme.Create(
new MaterialDesignDarkTheme(),
MediaColor.FromHex("#E8E8E8"),
MediaColor.FromHex("#F9A825")
Theme.Dark,
Color.Parse("#E8E8E8"),
Color.Parse("#F9A825")
);

public static void SetLightTheme()
{
var paletteHelper = new PaletteHelper();
paletteHelper.SetTheme(LightTheme);
App.Current!.RequestedThemeVariant = ThemeVariant.Light;
var theme = App.Current!.LocateMaterialTheme<MaterialThemeBase>();
theme.CurrentTheme = LightTheme;

Current.Resources["SuccessBrush"] = new SolidColorBrush(Colors.DarkGreen);
Current.Resources["CanceledBrush"] = new SolidColorBrush(Colors.DarkOrange);
Current.Resources["FailedBrush"] = new SolidColorBrush(Colors.DarkRed);
Current!.Resources["SuccessBrush"] = new SolidColorBrush(Colors.DarkGreen);
Current!.Resources["CanceledBrush"] = new SolidColorBrush(Colors.DarkOrange);
Current!.Resources["FailedBrush"] = new SolidColorBrush(Colors.DarkRed);
}

public static void SetDarkTheme()
{
var paletteHelper = new PaletteHelper();
paletteHelper.SetTheme(DarkTheme);
App.Current!.RequestedThemeVariant = ThemeVariant.Dark;
var theme = App.Current!.LocateMaterialTheme<MaterialThemeBase>();
theme.CurrentTheme = DarkTheme;

Current!.Resources["SuccessBrush"] = new SolidColorBrush(Colors.LightGreen);
Current!.Resources["CanceledBrush"] = new SolidColorBrush(Colors.Orange);
Current!.Resources["FailedBrush"] = new SolidColorBrush(Colors.OrangeRed);
}

protected override void OnStart()
{
base.OnStart();

// Set the default theme.
// Preferred theme will be set later, once the settings are loaded.
//App.SetLightTheme();

// Increase maximum concurrent connections
ServicePointManager.DefaultConnectionLimit = 20;
}

public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
base.Initialize();
}

public override void OnFrameworkInitializationCompleted()
{
base.OnFrameworkInitializationCompleted();
}

public override void RegisterServices()
{
base.RegisterServices();

AvaloniaWebViewBuilder.Initialize(default);
}

protected override void ConfigureIoC(IStyletIoCBuilder builder)
{
base.ConfigureIoC(builder);

builder.Bind<SettingsService>().ToSelf().InSingletonScope();
builder.Bind<IViewModelFactory>().ToAbstractFactory();
builder.Bind<IClipboard>().ToFactory(ctx => (ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)!.MainWindow!.Clipboard);
}

protected override void OnLaunch()
{
base.OnLaunch();
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime classicDesktopStyleApplicationLifetime)
{
classicDesktopStyleApplicationLifetime.MainWindow = GetActiveWindow();
}
}

// tODO
#if !DEBUG
protected override void OnUnhandledException(DispatcherUnhandledExceptionEventArgs args)

Check failure on line 123 in YoutubeDownloader/App.xaml.cs

View workflow job for this annotation

GitHub Actions / pack

The type or namespace name 'DispatcherUnhandledExceptionEventArgs' could not be found (are you missing a using directive or an assembly reference?)
{
base.OnUnhandledException(args);

Current.Resources["SuccessBrush"] = new SolidColorBrush(Colors.LightGreen);
Current.Resources["CanceledBrush"] = new SolidColorBrush(Colors.Orange);
Current.Resources["FailedBrush"] = new SolidColorBrush(Colors.OrangeRed);
MessageBox.Show(
args.Exception.ToString(),
"Error occured",
MessageBoxButton.OK,
MessageBoxImage.Error
);
}
#endif
}
96 changes: 0 additions & 96 deletions YoutubeDownloader/Behaviors/MultiSelectionListBoxBehavior.cs

This file was deleted.

This file was deleted.

50 changes: 0 additions & 50 deletions YoutubeDownloader/Bootstrapper.cs

This file was deleted.

Loading
Loading