for the refact, not the result ... Live still is KO
Some checks failed
Dotnet build and test / build (push) Failing after 13m0s
Some checks failed
Dotnet build and test / build (push) Failing after 13m0s
This commit is contained in:
parent
73528d0c7c
commit
251cc9cd48
15 changed files with 170 additions and 142 deletions
|
|
@ -4,7 +4,7 @@
|
|||
<!-- https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management -->
|
||||
<PropertyGroup>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
<AvaloniaVersionBase>12.1.2</AvaloniaVersionBase>
|
||||
<AvaloniaVersionBase>12.1.3</AvaloniaVersionBase>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="Avalonia" Version="$(AvaloniaVersionBase)" />
|
||||
|
|
@ -13,15 +13,15 @@
|
|||
<PackageVersion Include="Avalonia.Desktop" Version="$(AvaloniaVersionBase)" />
|
||||
<PackageVersion Include="Avalonia.Browser" Version="$(AvaloniaVersionBase)" />
|
||||
<PackageVersion Include="Avalonia.Android" Version="$(AvaloniaVersionBase)" />
|
||||
<PackageVersion Include="Avalonia.Headless" Version="12.1.2" />
|
||||
<PackageVersion Include="Avalonia.Headless" Version="12.1.3" />
|
||||
<PackageVersion Include="Avalonia.Headless.Xunit" Version="$(AvaloniaVersionBase)" />
|
||||
<PackageVersion Include="Avalonia.Fonts.Inter" Version="$(AvaloniaVersionBase)" />
|
||||
<PackageVersion Include="LibVLCSharp.Avalonia" Version="3.10.1" />
|
||||
<PackageVersion Include="Live.Avalonia" Version="1.4.1" />
|
||||
<PackageVersion Include="Live.Avalonia" Version="1.4.2" />
|
||||
<PackageVersion Include="Mapsui" Version="5.1.0" />
|
||||
<PackageVersion Include="Mapsui.Avalonia12" Version="5.1.0" />
|
||||
<PackageVersion Include="MarkdownViewer.Core" Version="1.0.5" />
|
||||
<PackageVersion Include="Material.Avalonia" Version="3.20.0" />
|
||||
<PackageVersion Include="Material.Avalonia" Version="3.21.0" />
|
||||
<PackageVersion Include="AvaloniaUI.DiagnosticsSupport" Version="2.2.3" />
|
||||
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client" Version="10.0.12" />
|
||||
|
|
@ -36,4 +36,4 @@
|
|||
<PackageVersion Include="Xamarin.UITest" Version="4.4.2" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.12" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using Avalonia;
|
||||
using PostIt.Services;
|
||||
using PostIt.CLIOptions;
|
||||
|
||||
namespace PostIt.Desktop;
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ public class SessionStatusBannerTests
|
|||
{
|
||||
MainWindow window = new MainWindow();
|
||||
window.Show();
|
||||
var banner = window.MainView.SessionBanner;
|
||||
var banner = new SessionStatusBanner();
|
||||
var status = new SessionStatusViewModel();
|
||||
banner.DataContext = status;
|
||||
return banner;
|
||||
|
|
|
|||
|
|
@ -14,15 +14,17 @@ using PostIt.Helpers;
|
|||
using System.Globalization;
|
||||
using Live.Avalonia;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using ReactiveUI;
|
||||
using System.Reactive;
|
||||
|
||||
namespace PostIt;
|
||||
|
||||
public partial class App : Application, ILiveView
|
||||
public partial class App : Application, ILiveView, IVMPusherApp
|
||||
{
|
||||
public static bool LiveMode { get; private set; }
|
||||
private int _bootStarted;
|
||||
public string? CliConfigFileSpecification { get; private set; }
|
||||
public static string? CliConfigFileSpecification { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// DI container the platform entry points hand to ViewModels so
|
||||
|
|
@ -49,38 +51,57 @@ public partial class App : Application, ILiveView
|
|||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
|
||||
#if DEBUG
|
||||
if (Debugger.IsAttached && !IsProduction())
|
||||
{
|
||||
// Debugging requires pdb loading etc, so we disable live reloading
|
||||
// during a test run with an attached debugger.
|
||||
var window = new Window();
|
||||
window.Content = CreateView(window);
|
||||
window.Show();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (TryHandOffCustomSchemeUrl()) return;
|
||||
|
||||
this.ServiceProvider = new ServiceCollection().BuildPostItServices();
|
||||
var settings = ServiceProvider.GetRequiredService<Settings>();
|
||||
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
if (!LiveMode)
|
||||
{
|
||||
InitializeClassicDesktopLifetime(settings, desktop);
|
||||
// Debugging requires pdb loading etc, so we disable live reloading
|
||||
// during a test run with an attached debugger.
|
||||
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
InitializeClassicDesktopLifetime(settings, desktop);
|
||||
}
|
||||
else if (ApplicationLifetime is IActivityApplicationLifetime singleViewFactoryApplicationLifetime)
|
||||
{
|
||||
InitializeActivityLifetime(settings, singleViewFactoryApplicationLifetime);
|
||||
}
|
||||
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
|
||||
{
|
||||
InitializeSingleViewLifetime(settings, singleViewPlatform);
|
||||
}
|
||||
}
|
||||
else if (ApplicationLifetime is IActivityApplicationLifetime singleViewFactoryApplicationLifetime)
|
||||
else
|
||||
{
|
||||
InitializeActivityLifetime(settings, singleViewFactoryApplicationLifetime);
|
||||
}
|
||||
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
|
||||
{
|
||||
InitializeSingleViewLifetime(settings, singleViewPlatform);
|
||||
// Here, we create a new LiveViewHost, located in the 'Live.Avalonia'
|
||||
// namespace, and pass an ILiveView implementation to it. The ILiveView
|
||||
// implementation should have a parameterless constructor! Next, we
|
||||
// start listening for any changes in the source files. And then, we
|
||||
// show the LiveViewHost window. Simple enough, huh?
|
||||
var window = new LiveViewHost(this, Console.WriteLine);
|
||||
var view = ServiceProvider!.GetRequiredService<MainView>();
|
||||
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
InitializeClassicDesktopLifetime(window, view, settings, desktop);
|
||||
}
|
||||
else if (ApplicationLifetime is IActivityApplicationLifetime singleViewFactoryApplicationLifetime)
|
||||
{
|
||||
InitializeActivityLifetime(settings, singleViewFactoryApplicationLifetime);
|
||||
}
|
||||
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
|
||||
{
|
||||
InitializeSingleViewLifetime(settings, singleViewPlatform);
|
||||
}
|
||||
|
||||
window.StartWatchingSourceFilesForHotReloading();
|
||||
Console.WriteLine("LiveViewHost started for hot reloading.");
|
||||
window.Show();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
// Here we subscribe to ReactiveUI default exception handler to avoid app
|
||||
|
|
@ -89,6 +110,7 @@ public partial class App : Application, ILiveView
|
|||
//
|
||||
// In case if you are using another MV* framework, please refer to its
|
||||
// documentation explaining global exception handling.
|
||||
Console.WriteLine("Debug mode: ReactiveUI default exception handler is set.");
|
||||
RxApp.DefaultExceptionHandler = Observer.Create<Exception>(Console.WriteLine);
|
||||
#endif
|
||||
|
||||
|
|
@ -98,12 +120,50 @@ public partial class App : Application, ILiveView
|
|||
private bool IsProduction()
|
||||
{
|
||||
#if DEBUG
|
||||
return false;
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
public async Task<Page> PushPageAsync(ViewModelBase viewModel)
|
||||
{
|
||||
var template = DataTemplates.FirstOrDefault(t => t.Match(viewModel));
|
||||
if (template is null)
|
||||
{
|
||||
throw new InvalidOperationException($"No IDataTemplate found for {viewModel.GetType().Name}.");
|
||||
}
|
||||
|
||||
Control? view = template.Build(viewModel) ;
|
||||
if (view is null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Template for {viewModel.GetType().Name} returned <null>.");
|
||||
}
|
||||
|
||||
var page = view as Page;
|
||||
if (page is null)
|
||||
{
|
||||
// NavigationPage expects Page instances. Wrap any fallback control
|
||||
// (e.g. ViewLocator error TextBlock) into a ContentPage so it can render.
|
||||
page = new ContentPage { Content = view };
|
||||
}
|
||||
|
||||
page.DataContext = viewModel;
|
||||
|
||||
MainView? mainView = (Current as App).View;
|
||||
|
||||
// Avoid stacking the same singleton page twice (e.g. SettingsPage).
|
||||
var stack = mainView.NavRoot.NavigationStack;
|
||||
if (stack.Count > 0 && ReferenceEquals(stack[stack.Count - 1], page))
|
||||
{
|
||||
return page;
|
||||
}
|
||||
|
||||
await mainView.NavRoot.PushAsync(page);
|
||||
return page;
|
||||
}
|
||||
|
||||
public void InitializeSingleViewLifetime(Settings settings, ISingleViewApplicationLifetime singleViewPlatform)
|
||||
{
|
||||
singleViewPlatform.MainView = View = ServiceProvider!.GetRequiredService<MainView>();
|
||||
|
|
@ -125,37 +185,34 @@ public partial class App : Application, ILiveView
|
|||
public void InitializeClassicDesktopLifetime(Settings settings, IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
var window = ServiceProvider!.GetRequiredService<MainWindow>();
|
||||
desktop.MainWindow = window;
|
||||
this.ConfigureRootView(window.MainView);
|
||||
var mainView = (MainView)CreateView(window);
|
||||
InitializeClassicDesktopLifetime(window, mainView, settings, desktop);
|
||||
}
|
||||
|
||||
public void InitializeClassicDesktopLifetime(Window window, MainView mainView, Settings settings, IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
this.ConfigureRootView(mainView);
|
||||
ApplyStettings(settings);
|
||||
desktop.MainWindow = window;
|
||||
window.Content = mainView;
|
||||
window.Show();
|
||||
}
|
||||
|
||||
public void ConfigureRootView(MainView rootView)
|
||||
{
|
||||
// Déclencher le Boot une seule fois lors du chargement du contrôle à l'écran.
|
||||
rootView.AttachedToVisualTree += async (_, _) => await BootOnceAsync();
|
||||
|
||||
var sessionStatus = ServiceProvider!.GetRequiredService<SessionStatusViewModel>();
|
||||
sessionStatus.LogoutCompleted += () =>
|
||||
{
|
||||
// Remplacer Window.NavRoot par rootView.NavRoot
|
||||
rootView.NavRoot.PopToRootAsync();
|
||||
};
|
||||
rootView.AttachedToVisualTree += async (_, _) => await BootOnceAsync();
|
||||
|
||||
rootView.SessionBanner.DataContext = sessionStatus;
|
||||
this.View = rootView;
|
||||
}
|
||||
|
||||
private async Task BootOnceAsync()
|
||||
{
|
||||
if (Interlocked.Exchange(ref _bootStarted, 1) == 1)
|
||||
var sessionStatus = ServiceProvider!.GetRequiredService<SessionStatusViewModel>();
|
||||
sessionStatus.LogoutCompleted += () =>
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Remplacer Window.NavRoot par rootView.NavRoot
|
||||
rootView.NavRoot.PopToRootAsync();
|
||||
};
|
||||
if (rootView.DataContext==null)
|
||||
rootView.DataContext = ServiceProvider!.GetRequiredService<HomePageViewModel>();
|
||||
|
||||
var api = ServiceProvider!.GetRequiredService<YavscApiClient>();
|
||||
await BootAsync(this.ServiceProvider!, api);
|
||||
rootView.SessionBanner.DataContext = sessionStatus;
|
||||
this.View = rootView;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -177,6 +234,18 @@ public partial class App : Application, ILiveView
|
|||
settings.DarkMode ? ThemeVariant.Dark : ThemeVariant.Light;
|
||||
}
|
||||
|
||||
|
||||
private async Task BootOnceAsync()
|
||||
{
|
||||
if (Interlocked.Exchange(ref _bootStarted, 1) == 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var api = ServiceProvider!.GetRequiredService<YavscApiClient>();
|
||||
await BootAsync(this.ServiceProvider!, api);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run once after the main window is shown: try to refresh the
|
||||
/// cached OIDC tokens silently; on success, push MainPage on top
|
||||
|
|
@ -192,9 +261,9 @@ public partial class App : Application, ILiveView
|
|||
var refreshed = await api.TrySilentLoginAsync().ConfigureAwait(true);
|
||||
var sessionStatus = provider.GetRequiredService<SessionStatusViewModel>();
|
||||
sessionStatus.Refresh();
|
||||
var homePage = provider.GetRequiredService<HomePageViewModel>();
|
||||
var homePageVm = provider.GetRequiredService<HomePageViewModel>();
|
||||
var app = (App)Current!;
|
||||
await app.PushPageAsync(homePage);
|
||||
await app.PushPageAsync(homePageVm);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -250,20 +319,25 @@ public partial class App : Application, ILiveView
|
|||
await View!.NavRoot.PopAsync();
|
||||
}
|
||||
|
||||
internal void UseConfigFileWhenLoading(string configFile)
|
||||
internal static void UseConfigFileWhenLoading(string configFile)
|
||||
{
|
||||
this.CliConfigFileSpecification = configFile;
|
||||
CliConfigFileSpecification = configFile;
|
||||
}
|
||||
|
||||
internal static void EnableLiveMode()
|
||||
{
|
||||
LiveMode = true;
|
||||
}
|
||||
|
||||
public object CreateView(Window window)
|
||||
{
|
||||
if (this.ServiceProvider==null)
|
||||
if (this.ServiceProvider == null)
|
||||
{
|
||||
var serviceCollection = new ServiceCollection();
|
||||
this.ServiceProvider = serviceCollection.BuildPostItServices();
|
||||
}
|
||||
if (window.DataContext == null)
|
||||
window.DataContext = ServiceProvider!.GetRequiredService<HomePageViewModel>();
|
||||
window.DataContext = ServiceProvider!.GetRequiredService<HomePageViewModel>();
|
||||
|
||||
// The AppView class will inherit the DataContext
|
||||
// of the window. The AppView class can be a
|
||||
|
|
|
|||
|
|
@ -4,15 +4,21 @@ using Mono.Options;
|
|||
using PostIt;
|
||||
using PostIt.ViewModels;
|
||||
|
||||
namespace PostIt.CLIOptions;
|
||||
|
||||
public static class CLIOptionHandler
|
||||
{
|
||||
public static void HandleArgs(string[] args)
|
||||
{
|
||||
bool showHelp = false;
|
||||
string configFile = null;
|
||||
bool liveMode = false;
|
||||
|
||||
var options = new OptionSet {
|
||||
{ "c|configuration=", "Configuration file to load", (string v) => configFile = v },
|
||||
{ "l|live", "Enable live mode", v => liveMode = true },
|
||||
{ "v|version", "Show the application version", v => Console.WriteLine("PostIt version "
|
||||
+ typeof(App).Assembly.GetName().Version?.ToString()) },
|
||||
{ "h|help", "Show this message and exit", v => showHelp = true }
|
||||
};
|
||||
|
||||
|
|
@ -26,8 +32,11 @@ public static class CLIOptionHandler
|
|||
}
|
||||
if (configFile != null)
|
||||
{
|
||||
var app = App.Current as App;
|
||||
app.UseConfigFileWhenLoading(configFile);
|
||||
App.UseConfigFileWhenLoading(configFile);
|
||||
}
|
||||
if (liveMode)
|
||||
{
|
||||
App.EnableLiveMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,9 +39,12 @@ public static class ServiceCollectionHelpers
|
|||
var reverseGeocoding = new NominatimReverseGeocodingService();
|
||||
|
||||
// Vues
|
||||
services.AddSingleton<MainView>();
|
||||
services.AddSingleton<BlogsPage>();
|
||||
services.AddSingleton<MainWindow>();
|
||||
services.AddTransient<MainWindow>();
|
||||
services.AddTransient<MainView>();
|
||||
services.AddTransient<BlogsPage>();
|
||||
|
||||
|
||||
// Models
|
||||
services.AddSingleton<ChatViewModel>();
|
||||
|
||||
// SettingsPage is a singleton: there must be one and only one
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Controls;
|
||||
using PostIt.ViewModels;
|
||||
|
||||
namespace PostIt.Helpers;
|
||||
|
||||
public static class ViewModelBaseHelpers
|
||||
{
|
||||
public static async Task<Page> PushPageAsync(this App app, ViewModelBase vm)
|
||||
{
|
||||
var window = app.View;
|
||||
if (window is null)
|
||||
{
|
||||
throw new InvalidOperationException("MainWindow is not initialized yet.");
|
||||
}
|
||||
|
||||
var template = app.DataTemplates.FirstOrDefault(t => t.Match(vm));
|
||||
if (template is null)
|
||||
{
|
||||
throw new InvalidOperationException($"No IDataTemplate found for {vm.GetType().Name}.");
|
||||
}
|
||||
|
||||
var view = template.Build(vm);
|
||||
if (view is null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Template for {vm.GetType().Name} returned <null>.");
|
||||
}
|
||||
|
||||
var page = view as Page;
|
||||
if (page is null)
|
||||
{
|
||||
// NavigationPage expects Page instances. Wrap any fallback control
|
||||
// (e.g. ViewLocator error TextBlock) into a ContentPage so it can render.
|
||||
page = new ContentPage { Content = view };
|
||||
}
|
||||
|
||||
page.DataContext = vm;
|
||||
|
||||
// Avoid stacking the same singleton page twice (e.g. SettingsPage).
|
||||
var stack = window.NavRoot.NavigationStack;
|
||||
if (stack.Count > 0 && ReferenceEquals(stack[stack.Count - 1], page))
|
||||
{
|
||||
return page;
|
||||
}
|
||||
|
||||
await window.NavRoot.PushAsync(page);
|
||||
|
||||
return page;
|
||||
}
|
||||
}
|
||||
10
src/PostIt/PostIt/IVMPusherApp.cs
Normal file
10
src/PostIt/PostIt/IVMPusherApp.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System.Threading.Tasks;
|
||||
using PostIt.ViewModels;
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace PostIt;
|
||||
|
||||
internal interface IVMPusherApp
|
||||
{
|
||||
Task<Page> PushPageAsync(ViewModelBase viewModel);
|
||||
}
|
||||
2
src/PostIt/PostIt/Lang/Resources.Designer.cs
generated
2
src/PostIt/PostIt/Lang/Resources.Designer.cs
generated
|
|
@ -61,7 +61,7 @@ namespace Yavsc.Lang {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Bienvenue dans PostIt!.
|
||||
/// Looks up a localized string similar to Bienvenue dans PostIt !!!.
|
||||
/// </summary>
|
||||
public static string GreetingText {
|
||||
get {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<root>
|
||||
<data name="GreetingText">
|
||||
<value>Bienvenue dans PostIt!</value>
|
||||
<value>Bienvenue dans PostIt !!!</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ using System.Threading.Tasks;
|
|||
using Avalonia;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using PostIt.Helpers;
|
||||
using PostIt.Services;
|
||||
using PostIt.ViewModels.Chat;
|
||||
using Yavsc.Api.Client;
|
||||
|
|
|
|||
|
|
@ -271,10 +271,9 @@ public partial class Settings : ViewModelBase
|
|||
}
|
||||
|
||||
var app = App.Current as App;
|
||||
if (app!=null)
|
||||
if (app.CliConfigFileSpecification!=null)
|
||||
if (App.CliConfigFileSpecification!=null)
|
||||
{
|
||||
SettingsFileFullName = app.CliConfigFileSpecification;
|
||||
SettingsFileFullName = App.CliConfigFileSpecification;
|
||||
}
|
||||
|
||||
if (SettingsFileFullName is not null)
|
||||
|
|
|
|||
|
|
@ -14,20 +14,6 @@
|
|||
|
||||
<Grid RowDefinitions="Auto, *, Auto" Margin="10">
|
||||
|
||||
<!-- SECTION 1 : BARRE DE CONNEXION & PSEUDO -->
|
||||
<Border Grid.Row="0" Background="#F5F5F5" CornerRadius="5" Padding="10" Margin="0,0,0,10">
|
||||
<StackPanel Orientation="Horizontal" Spacing="10">
|
||||
<TextBox Text="{Binding ServerUrl}" Watermark="URL du Hub SignalR" Width="250" VerticalAlignment="Center"/>
|
||||
<Button Content="Connexion" Command="{Binding ConnectCommand}" IsEnabled="{Binding !IsConnected}"/>
|
||||
|
||||
<Separator Background="Gray" Width="1" Margin="5,0"/>
|
||||
|
||||
<TextBox Text="{Binding NickName}" Watermark="Nouveau Pseudo" Width="150" VerticalAlignment="Center"/>
|
||||
<Button Content="Changer Nick" Command="{Binding ChangeNickCommand}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- SECTION 2 : ESPACE CENTRAL DU CHAT -->
|
||||
<Grid Grid.Row="1" ColumnDefinitions="*, 200" Margin="0,0,0,10">
|
||||
|
||||
<!-- Journal des flux de messages & notifications -->
|
||||
|
|
@ -37,7 +23,7 @@
|
|||
<Button Content="Rejoindre Salon (Join)" Command="{Binding JoinRoomCommand}"/>
|
||||
</StackPanel>
|
||||
|
||||
<ListBox Grid.Row="1" ItemsSource="{Binding Messages}" Background="#FAFAFA" BorderBrush="#E0E0E0" BorderThickness="1">
|
||||
<ListBox Grid.Row="1" ItemsSource="{Binding Messages}" BorderBrush="#E0E0E0" BorderThickness="1">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding}" TextWrapping="Wrap"/>
|
||||
|
|
@ -47,7 +33,7 @@
|
|||
</Grid>
|
||||
|
||||
<!-- Liste des utilisateurs présents (MàJ via l'événement 'joint') -->
|
||||
<Border Grid.Column="1" Margin="10,0,0,0" BorderBrush="#E0E0E0" BorderThickness="1" Background="#FFF">
|
||||
<Border Grid.Column="1" Margin="10,0,0,0" BorderBrush="#E0E0E0" BorderThickness="1" >
|
||||
<Grid RowDefinitions="Auto, *">
|
||||
<TextBlock Grid.Row="0" Text="Membres Présents" FontWeight="Bold" Margin="5" HorizontalAlignment="Center"/>
|
||||
<ListBox Grid.Row="1" ItemsSource="{Binding ConnectedUsers}" BorderThickness="0"/>
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
FontWeight="SemiBold"
|
||||
HorizontalAlignment="Center"/>
|
||||
|
||||
<Button Content="Chat"
|
||||
<Button Content="Les Salons de discussion"
|
||||
Command="{Binding OpenChat}"
|
||||
HorizontalAlignment="Center"
|
||||
IsEnabled="{Binding SessionStatus.IsLoggedIn}"/>
|
||||
|
|
|
|||
|
|
@ -8,5 +8,5 @@
|
|||
x:Class="PostIt.Views.MainWindow"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
Title="PostIt">
|
||||
<views:MainView x:Name="MainView" />
|
||||
<views:MainView />
|
||||
</Window>
|
||||
|
|
|
|||
Loading…
Reference in a new issue