Implemented a few ToDo's
- Check required fields before publishing - Allow cancelling of package downloading - Check for JsonConverter attribute - Improved read/unread message separator
This commit is contained in:
parent
5bc2096a24
commit
785ddbd5b2
@ -54,12 +54,13 @@ namespace PettingZoo.Tapeti
|
||||
progressWindow.Top = windowBounds.Top + (windowBounds.Height - progressWindow.Height) / 2;
|
||||
progressWindow.Show();
|
||||
|
||||
var cancellationToken = progressWindow.CancellationToken;
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO allow cancelling (by closing the progress window and optionally a Cancel button)
|
||||
var assemblies = await args.Assemblies.GetAssemblies(progressWindow, CancellationToken.None);
|
||||
var assemblies = await args.Assemblies.GetAssemblies(progressWindow, cancellationToken);
|
||||
|
||||
// var classes =
|
||||
var examples = LoadExamples(assemblies);
|
||||
@ -94,10 +95,11 @@ namespace PettingZoo.Tapeti
|
||||
// ReSharper disable once ConstantConditionalAccessQualifier - if I remove it, there's a "Dereference of a possibly null reference" warning instead
|
||||
progressWindow?.Close();
|
||||
|
||||
MessageBox.Show($"Error while loading assembly: {e.Message}", "Petting Zoo - Exception", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
if (e is not OperationCanceledException)
|
||||
MessageBox.Show($"Error while loading assembly: {e.Message}", "Petting Zoo - Exception", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}, CancellationToken.None);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace PettingZoo.Tapeti
|
||||
@ -59,7 +60,20 @@ namespace PettingZoo.Tapeti
|
||||
actualType = equivalentType;
|
||||
|
||||
|
||||
// TODO check for JsonConverter attribute? doubt we'll be able to generate a nice value for it, but at least we can provide a placeholder
|
||||
try
|
||||
{
|
||||
if (type.GetCustomAttribute<JsonConverterAttribute>() != null)
|
||||
{
|
||||
// This type uses custom Json conversion so there's no way to know how to provide an example.
|
||||
// We could try to create an instance of the type and pass it through the converter, but for now we'll
|
||||
// just output a placeholder.
|
||||
return "<custom JsonConverter - manual input required>";
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Move along
|
||||
}
|
||||
|
||||
// String is also a class
|
||||
if (actualType == typeof(string))
|
||||
|
@ -60,6 +60,15 @@ namespace PettingZoo.Tapeti.UI.PackageProgress {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cancel.
|
||||
/// </summary>
|
||||
public static string ButtonCancel {
|
||||
get {
|
||||
return ResourceManager.GetString("ButtonCancel", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Reading message classes....
|
||||
/// </summary>
|
||||
|
@ -112,11 +112,14 @@
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ButtonCancel" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="WindowTitle" xml:space="preserve">
|
||||
<value>Reading message classes...</value>
|
||||
</data>
|
||||
|
@ -5,10 +5,13 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:packageProgress="clr-namespace:PettingZoo.Tapeti.UI.PackageProgress"
|
||||
mc:Ignorable="d"
|
||||
Height="80"
|
||||
Width="400"
|
||||
Title="{x:Static packageProgress:PackageProgressStrings.WindowTitle}"
|
||||
ResizeMode="NoResize"
|
||||
WindowStyle="ToolWindow">
|
||||
<ProgressBar Height="25" Margin="16" VerticalAlignment="Center" Name="Progress" Maximum="100" />
|
||||
WindowStyle="ToolWindow"
|
||||
SizeToContent="Height">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<ProgressBar Height="25" Margin="16" VerticalAlignment="Center" Name="Progress" Maximum="100" />
|
||||
<Button HorizontalAlignment="Center" Margin="0,0,0,16" Content="{x:Static packageProgress:PackageProgressStrings.ButtonCancel}" Click="CancelButton_OnClick" />
|
||||
</StackPanel>
|
||||
</Window>
|
||||
|
@ -1,4 +1,7 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace PettingZoo.Tapeti.UI.PackageProgress
|
||||
{
|
||||
@ -7,9 +10,19 @@ namespace PettingZoo.Tapeti.UI.PackageProgress
|
||||
/// </summary>
|
||||
public partial class PackageProgressWindow : IProgress<int>
|
||||
{
|
||||
private readonly CancellationTokenSource cancellationTokenSource = new();
|
||||
|
||||
public CancellationToken CancellationToken => cancellationTokenSource.Token;
|
||||
|
||||
|
||||
public PackageProgressWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Closed += (_, _) =>
|
||||
{
|
||||
cancellationTokenSource.Cancel();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -20,5 +33,11 @@ namespace PettingZoo.Tapeti.UI.PackageProgress
|
||||
Progress.Value = value;
|
||||
});
|
||||
}
|
||||
|
||||
private void CancelButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
cancellationTokenSource.Cancel();
|
||||
((Button)sender).IsEnabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,6 @@ namespace PettingZoo.Tapeti.UI.PackageSelection
|
||||
public ICommand AssemblyBrowse => assemblyBrowse;
|
||||
|
||||
|
||||
// TODO hint for extra assemblies path
|
||||
public static string HintNuGetSources => string.Format(PackageSelectionStrings.HintNuGetSources, PettingZooPaths.InstallationRoot, PettingZooPaths.AppDataRoot);
|
||||
|
||||
public string NuGetSearchTerm
|
||||
|
@ -1,12 +1,12 @@
|
||||
Must-have
|
||||
---------
|
||||
- Check required fields before enabling Publish button
|
||||
|
||||
|
||||
Should-have
|
||||
-----------
|
||||
- Save / load publisher messages (either as templates or to disk)
|
||||
- Tapeti: export received messages to Tapeti.Cmd JSON file / Tapeti.Cmd command-line
|
||||
- Tapeti: import Tapeti.Cmd JSON file into Subscriber-esque tab for easier browsing
|
||||
- Tapeti: fetch NuGet dependencies to improve the chances of succesfully loading the assembly, instead of the current "extraAssembliesPaths" workaround
|
||||
|
||||
|
||||
|
@ -45,7 +45,9 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
public bool SendToExchange
|
||||
{
|
||||
get => sendToExchange;
|
||||
set => SetField(ref sendToExchange, value, otherPropertiesChanged: new[] { nameof(SendToQueue), nameof(ExchangeVisibility), nameof(QueueVisibility), nameof(Title) });
|
||||
set => SetField(ref sendToExchange, value,
|
||||
delegateCommandsChanged: new [] { publishCommand },
|
||||
otherPropertiesChanged: new[] { nameof(SendToQueue), nameof(ExchangeVisibility), nameof(QueueVisibility), nameof(Title) });
|
||||
}
|
||||
|
||||
|
||||
@ -59,21 +61,21 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
public string Exchange
|
||||
{
|
||||
get => exchange;
|
||||
set => SetField(ref exchange, value);
|
||||
set => SetField(ref exchange, value, delegateCommandsChanged: new[] { publishCommand });
|
||||
}
|
||||
|
||||
|
||||
public string RoutingKey
|
||||
{
|
||||
get => routingKey;
|
||||
set => SetField(ref routingKey, value, otherPropertiesChanged: new[] { nameof(Title) });
|
||||
set => SetField(ref routingKey, value, delegateCommandsChanged: new[] { publishCommand }, otherPropertiesChanged: new[] { nameof(Title) });
|
||||
}
|
||||
|
||||
|
||||
public string Queue
|
||||
{
|
||||
get => queue;
|
||||
set => SetField(ref queue, value, otherPropertiesChanged: new[] { nameof(Title) });
|
||||
set => SetField(ref queue, value, delegateCommandsChanged: new[] { publishCommand }, otherPropertiesChanged: new[] { nameof(Title) });
|
||||
}
|
||||
|
||||
|
||||
@ -183,6 +185,17 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
|
||||
private bool PublishCanExecute()
|
||||
{
|
||||
if (SendToExchange)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Exchange) || string.IsNullOrWhiteSpace(RoutingKey))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Queue))
|
||||
return false;
|
||||
}
|
||||
|
||||
return messageTypePublishCommand?.CanExecute(null) ?? false;
|
||||
}
|
||||
|
||||
@ -197,6 +210,11 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
if (rawPublisherView == null)
|
||||
{
|
||||
rawPublisherViewModel = new RawPublisherViewModel(connection, this);
|
||||
rawPublisherViewModel.PublishCommand.CanExecuteChanged += (_, _) =>
|
||||
{
|
||||
publishCommand.RaiseCanExecuteChanged();
|
||||
};
|
||||
|
||||
rawPublisherView ??= new RawPublisherView(rawPublisherViewModel);
|
||||
}
|
||||
else
|
||||
@ -213,6 +231,11 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
if (tapetiPublisherView == null)
|
||||
{
|
||||
tapetiPublisherViewModel = new TapetiPublisherViewModel(connection, this, exampleGenerator);
|
||||
tapetiPublisherViewModel.PublishCommand.CanExecuteChanged += (_, _) =>
|
||||
{
|
||||
publishCommand.RaiseCanExecuteChanged();
|
||||
};
|
||||
|
||||
tapetiPublisherView ??= new TapetiPublisherView(tapetiPublisherViewModel);
|
||||
|
||||
if (tabHostWindow != null)
|
||||
|
@ -115,7 +115,7 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
public string Payload
|
||||
{
|
||||
get => payload;
|
||||
set => SetField(ref payload, value);
|
||||
set => SetField(ref payload, value, delegateCommandsChanged: new [] { publishCommand });
|
||||
}
|
||||
|
||||
|
||||
@ -267,10 +267,9 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
}
|
||||
|
||||
|
||||
private static bool PublishCanExecute()
|
||||
private bool PublishCanExecute()
|
||||
{
|
||||
// TODO validate input
|
||||
return true;
|
||||
return !string.IsNullOrWhiteSpace(Payload);
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,10 +36,15 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
|
||||
public string ClassName
|
||||
{
|
||||
get => string.IsNullOrEmpty(className) ? AssemblyName + "." : className;
|
||||
get => string.IsNullOrWhiteSpace(className)
|
||||
? string.IsNullOrWhiteSpace(AssemblyName)
|
||||
? ""
|
||||
: AssemblyName + "."
|
||||
: className;
|
||||
|
||||
set
|
||||
{
|
||||
if (SetField(ref className, value))
|
||||
if (SetField(ref className, value, delegateCommandsChanged: new[] { publishCommand }))
|
||||
validatingExample = null;
|
||||
}
|
||||
}
|
||||
@ -48,7 +53,7 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
public string AssemblyName
|
||||
{
|
||||
get => assemblyName;
|
||||
set => SetField(ref assemblyName, value, otherPropertiesChanged:
|
||||
set => SetField(ref assemblyName, value, delegateCommandsChanged: new[] { publishCommand }, otherPropertiesChanged:
|
||||
string.IsNullOrEmpty(value) || string.IsNullOrEmpty(className)
|
||||
? new [] { nameof(ClassName) }
|
||||
: null
|
||||
@ -59,7 +64,7 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
public string Payload
|
||||
{
|
||||
get => payload;
|
||||
set => SetField(ref payload, value);
|
||||
set => SetField(ref payload, value, delegateCommandsChanged: new[] { publishCommand });
|
||||
}
|
||||
|
||||
|
||||
@ -164,12 +169,15 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
}
|
||||
|
||||
|
||||
private static bool PublishCanExecute()
|
||||
private bool PublishCanExecute()
|
||||
{
|
||||
// TODO validate input
|
||||
return true;
|
||||
return
|
||||
!string.IsNullOrWhiteSpace(assemblyName) &&
|
||||
!string.IsNullOrWhiteSpace(ClassName) &&
|
||||
!string.IsNullOrWhiteSpace(Payload);
|
||||
}
|
||||
|
||||
|
||||
public void HostWindowChanged(Window? hostWindow)
|
||||
{
|
||||
tabHostWindow = hostWindow;
|
||||
|
@ -7,6 +7,7 @@
|
||||
xmlns:res="clr-namespace:PettingZoo.UI.Tab.Subscriber"
|
||||
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
|
||||
xmlns:avalonedit="http://icsharpcode.net/sharpdevelop/avalonedit"
|
||||
xmlns:connection="clr-namespace:PettingZoo.Core.Connection;assembly=PettingZoo.Core"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
@ -24,48 +25,46 @@
|
||||
<ListBox Grid.Column="0" Grid.Row="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
ItemsSource="{Binding Messages}"
|
||||
SelectedItem="{Binding Path=SelectedMessage, Mode=TwoWay}"
|
||||
ui:ListBox.AutoScroll="True"
|
||||
x:Name="ReferenceControlForBorder">
|
||||
x:Name="ReferenceControlForBorder"
|
||||
Grid.IsSharedSizeScope="True">
|
||||
<ListBox.Resources>
|
||||
<ui:BindingProxy x:Key="ContextMenuProxy" Data="{Binding}" />
|
||||
<CollectionViewSource x:Key="Messages"
|
||||
Source="{Binding Messages}" />
|
||||
<CollectionViewSource x:Key="UnreadMessages"
|
||||
Source="{Binding UnreadMessages}" />
|
||||
</ListBox.Resources>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" MinWidth="150" SharedSizeGroup="DateTime"/>
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- TODO insert as non-focusable item instead, so it's not part of the selection (and perhaps also fixes the bug mentioned in SubscriberViewModel) -->
|
||||
<Grid Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2">
|
||||
<ListBox.ItemsSource>
|
||||
<CompositeCollection>
|
||||
<CollectionContainer Collection="{Binding Source={StaticResource Messages}}" />
|
||||
<ListBoxItem HorizontalContentAlignment="Stretch" IsEnabled="False" IsHitTestVisible="False">
|
||||
<Grid Visibility="{Binding UnreadMessagesVisibility}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition SharedSizeGroup="DateTime" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid.Visibility>
|
||||
<MultiBinding Converter="{StaticResource SameMessageVisibilityConverter}">
|
||||
<Binding RelativeSource="{RelativeSource Self}" Path="DataContext" />
|
||||
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ListBox}}" Path="DataContext.NewMessage" />
|
||||
</MultiBinding>
|
||||
</Grid.Visibility>
|
||||
|
||||
<Separator Grid.Column="0" Margin="0,0,8,0" />
|
||||
<TextBlock Grid.Column="1" Text="{x:Static res:SubscriberViewStrings.LabelNewMessages}" HorizontalAlignment="Center" Background="{Binding Background, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" Foreground="{x:Static SystemColors.GrayTextBrush}" />
|
||||
<Separator Grid.Column="2" Margin="8,0,0,0" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ListBoxItem>
|
||||
<CollectionContainer Collection="{Binding Source={StaticResource UnreadMessages}}" />
|
||||
</CompositeCollection>
|
||||
</ListBox.ItemsSource>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type connection:ReceivedMessageInfo}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" MinWidth="150" SharedSizeGroup="DateTime"/>
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="1" Text="{Binding ReceivedTimestamp, StringFormat=g}" Style="{StaticResource Timestamp}" />
|
||||
<TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding RoutingKey}" Style="{StaticResource RoutingKey}" />
|
||||
<TextBlock Grid.Column="0" Text="{Binding ReceivedTimestamp, StringFormat=g}" Style="{StaticResource Timestamp}" />
|
||||
<TextBlock Grid.Column="1" Text="{Binding RoutingKey}" Style="{StaticResource RoutingKey}" />
|
||||
|
||||
<Grid.ContextMenu>
|
||||
<ContextMenu>
|
||||
|
@ -1,17 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Threading;
|
||||
using PettingZoo.Core.Connection;
|
||||
using PettingZoo.Core.Rendering;
|
||||
using PettingZoo.WPF.ViewModel;
|
||||
|
||||
// TODO if the "New message" line is visible when this tab is undocked, the line in the ListBox does not shrink. Haven't been able to figure out yet how to solve it
|
||||
|
||||
namespace PettingZoo.UI.Tab.Subscriber
|
||||
{
|
||||
public class SubscriberViewModel : BaseViewModel, ITabToolbarCommands, ITabActivate
|
||||
@ -29,7 +27,6 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
private readonly DelegateCommand createPublisherCommand;
|
||||
|
||||
private bool tabActive;
|
||||
private ReceivedMessageInfo? newMessage;
|
||||
private Timer? newMessageTimer;
|
||||
private int unreadCount;
|
||||
|
||||
@ -39,7 +36,8 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
// ReSharper disable once UnusedMember.Global - it is, but via a proxy
|
||||
public ICommand CreatePublisherCommand => createPublisherCommand;
|
||||
|
||||
public ObservableCollection<ReceivedMessageInfo> Messages { get; }
|
||||
public ObservableCollectionEx<ReceivedMessageInfo> Messages { get; }
|
||||
public ObservableCollectionEx<ReceivedMessageInfo> UnreadMessages { get; }
|
||||
|
||||
public ReceivedMessageInfo? SelectedMessage
|
||||
{
|
||||
@ -52,11 +50,7 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
}
|
||||
|
||||
|
||||
public ReceivedMessageInfo? NewMessage
|
||||
{
|
||||
get => newMessage;
|
||||
set => SetField(ref newMessage, value);
|
||||
}
|
||||
public Visibility UnreadMessagesVisibility => UnreadMessages.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
|
||||
public string SelectedMessageBody =>
|
||||
@ -85,7 +79,8 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
|
||||
dispatcher = Dispatcher.CurrentDispatcher;
|
||||
|
||||
Messages = new ObservableCollection<ReceivedMessageInfo>();
|
||||
Messages = new ObservableCollectionEx<ReceivedMessageInfo>();
|
||||
UnreadMessages = new ObservableCollectionEx<ReceivedMessageInfo>();
|
||||
clearCommand = new DelegateCommand(ClearExecute, ClearCanExecute);
|
||||
|
||||
toolbarCommands = new[]
|
||||
@ -103,6 +98,8 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
private void ClearExecute()
|
||||
{
|
||||
Messages.Clear();
|
||||
UnreadMessages.Clear();
|
||||
RaisePropertyChanged(nameof(UnreadMessagesVisibility));
|
||||
clearCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
@ -135,10 +132,13 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
unreadCount++;
|
||||
RaisePropertyChanged(nameof(Title));
|
||||
|
||||
NewMessage ??= args.MessageInfo;
|
||||
UnreadMessages.Add(args.MessageInfo);
|
||||
if (UnreadMessages.Count == 1)
|
||||
RaisePropertyChanged(nameof(UnreadMessagesVisibility));
|
||||
}
|
||||
else
|
||||
Messages.Add(args.MessageInfo);
|
||||
|
||||
Messages.Add(args.MessageInfo);
|
||||
clearCommand.RaiseCanExecuteChanged();
|
||||
});
|
||||
}
|
||||
@ -161,7 +161,7 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
|
||||
RaisePropertyChanged(nameof(Title));
|
||||
|
||||
if (NewMessage == null)
|
||||
if (UnreadMessages.Count == 0)
|
||||
return;
|
||||
|
||||
newMessageTimer?.Dispose();
|
||||
@ -170,7 +170,23 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
{
|
||||
dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
NewMessage = null;
|
||||
if (UnreadMessages.Count == 0)
|
||||
return;
|
||||
|
||||
Messages.BeginUpdate();
|
||||
UnreadMessages.BeginUpdate();
|
||||
try
|
||||
{
|
||||
Messages.AddRange(UnreadMessages);
|
||||
UnreadMessages.Clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
UnreadMessages.EndUpdate();
|
||||
Messages.EndUpdate();
|
||||
}
|
||||
|
||||
RaisePropertyChanged(nameof(UnreadMessagesVisibility));
|
||||
});
|
||||
},
|
||||
null,
|
||||
@ -178,6 +194,7 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
Timeout.InfiniteTimeSpan);
|
||||
}
|
||||
|
||||
|
||||
public void Deactivate()
|
||||
{
|
||||
if (newMessageTimer != null)
|
||||
@ -186,7 +203,6 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
newMessageTimer = null;
|
||||
}
|
||||
|
||||
NewMessage = null;
|
||||
tabActive = false;
|
||||
}
|
||||
}
|
||||
@ -197,22 +213,21 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
public DesignTimeSubscriberViewModel() : base(null!, null!, null!, new DesignTimeSubscriber())
|
||||
{
|
||||
for (var i = 1; i <= 5; i++)
|
||||
Messages.Add(new ReceivedMessageInfo(
|
||||
"designtime",
|
||||
$"designtime.message.{i}",
|
||||
Encoding.UTF8.GetBytes(@"Design-time message"),
|
||||
(i > 2 ? UnreadMessages : Messages).Add(new ReceivedMessageInfo(
|
||||
"designtime",
|
||||
$"designtime.message.{i}",
|
||||
Encoding.UTF8.GetBytes(@"Design-time message"),
|
||||
new MessageProperties(null)
|
||||
{
|
||||
ContentType = "text/fake",
|
||||
ReplyTo = "/dev/null"
|
||||
},
|
||||
},
|
||||
DateTime.Now));
|
||||
|
||||
SelectedMessage = Messages[2];
|
||||
NewMessage = Messages[2];
|
||||
SelectedMessage = UnreadMessages[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private class DesignTimeSubscriber : ISubscriber
|
||||
{
|
||||
public ValueTask DisposeAsync()
|
||||
|
Loading…
Reference in New Issue
Block a user