fixed up media controller
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
<None Remove="bin/Debug/net8.0-windows10.0.19041.0/Hyperbar.Windows.Controls.pri" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.231202003-experimental1" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.240124002-experimental2" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26031-preview" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.231202003-experimental1" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.240124002-experimental2" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26031-preview" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -5,9 +5,9 @@ using Windows.Storage.Streams;
|
||||
namespace Hyperbar.UI.Windows;
|
||||
|
||||
public class StreamToImageSourceConverter :
|
||||
ValueConverter<Stream, ImageSource>
|
||||
ValueConverter<byte[], ImageSource>
|
||||
{
|
||||
protected override ImageSource? ConvertTo(Stream value,
|
||||
protected override ImageSource? ConvertTo(byte[] value,
|
||||
Type? targetType,
|
||||
object? parameter,
|
||||
string? language)
|
||||
@@ -17,8 +17,8 @@ public class StreamToImageSourceConverter :
|
||||
return default;
|
||||
}
|
||||
|
||||
IRandomAccessStream randomAccessStream =
|
||||
WindowsRuntimeStreamExtensions.AsRandomAccessStream(value);
|
||||
MemoryStream memoryStream = new(value);
|
||||
IRandomAccessStream randomAccessStream = memoryStream.AsRandomAccessStream();
|
||||
|
||||
BitmapImage bitmapImage = new();
|
||||
bitmapImage.SetSource(randomAccessStream);
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
<PackageReference Include="CommunityToolkit.WinUI" Version="7.1.2" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls" Version="7.1.2" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls.Primitives" Version="7.1.2" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.231202003-experimental1" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.240124002-experimental2" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26031-preview" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Hyperbar.Widget.MediaController.Windows;
|
||||
|
||||
public interface IMediaButtonViewModel :
|
||||
IObservableViewModel
|
||||
{
|
||||
IRelayCommand? InvokeCommand { get; set; }
|
||||
|
||||
bool IsEnabled { get; set; }
|
||||
|
||||
string? State { get; set; }
|
||||
}
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
namespace Hyperbar.Widget.MediaController.Windows;
|
||||
|
||||
public record Previous : INotification;
|
||||
public record MediaButton(bool IsEnabled);
|
||||
@@ -4,7 +4,8 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:interactions="using:Microsoft.Xaml.Interactions.Core"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity">
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:triggers="using:CommunityToolkit.WinUI.UI.Triggers">
|
||||
<UserControl.Resources>
|
||||
<SolidColorBrush x:Key="ButtonBackground" Color="Transparent" />
|
||||
<SolidColorBrush x:Key="ButtonBorderBrush" Color="Transparent" />
|
||||
@@ -16,18 +17,49 @@
|
||||
<x:Double x:Key="ButtonHeight">40</x:Double>
|
||||
</UserControl.Resources>
|
||||
<Button
|
||||
x:Name="Button"
|
||||
Width="{StaticResource ButtonWidth}"
|
||||
Height="{StaticResource ButtonHeight}"
|
||||
Padding="{StaticResource ButtonPadding}"
|
||||
Command="{Binding Click}"
|
||||
Content="{Binding Icon}"
|
||||
Command="{x:Bind ViewModel.InvokeCommand}"
|
||||
Content="{x:Bind ViewModel.State}"
|
||||
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||
FontSize="16"
|
||||
ToolTipService.ToolTip="{Binding Text}">
|
||||
IsEnabled="False">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactions:EventTriggerBehavior EventName="Loaded">
|
||||
<interactions:InvokeCommandAction Command="{Binding Initialize}" />
|
||||
<interactions:InvokeCommandAction Command="{x:Bind ViewModel.InitializeCommand}" />
|
||||
</interactions:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup>
|
||||
<VisualState x:Name="MediaPreviousButtonState">
|
||||
<VisualState.StateTriggers>
|
||||
<triggers:IsEqualStateTrigger Value="{Binding State}" To="MediaPreviousButton" />
|
||||
</VisualState.StateTriggers>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="Button.Content" Value="" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="MediaNextButtonState">
|
||||
<VisualState.StateTriggers>
|
||||
<triggers:IsEqualStateTrigger Value="{Binding State}" To="MediaNextButton" />
|
||||
</VisualState.StateTriggers>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="Button.Content" Value="" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
<VisualStateGroup>
|
||||
<VisualState x:Name="IsEnabledState">
|
||||
<VisualState.StateTriggers>
|
||||
<triggers:IsEqualStateTrigger Value="{Binding IsEnabled}" To="True" />
|
||||
</VisualState.StateTriggers>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="Button.IsEnabled" Value="True" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Button>
|
||||
</UserControl>
|
||||
|
||||
@@ -9,5 +9,5 @@ public sealed partial class MediaButtonView :
|
||||
public MediaButtonView() =>
|
||||
this.InitializeComponent(ref _contentLoaded);
|
||||
|
||||
private MediaButtonViewModel ViewModel => (MediaButtonViewModel)DataContext;
|
||||
private IMediaButtonViewModel ViewModel => (IMediaButtonViewModel)DataContext;
|
||||
}
|
||||
|
||||
@@ -3,42 +3,33 @@ using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Hyperbar.Widget.MediaController.Windows;
|
||||
|
||||
[NotificationHandler(nameof(PlaybackButtonType))]
|
||||
public partial class MediaButtonViewModel(IServiceFactory serviceFactory,
|
||||
public partial class MediaButtonViewModel<TMediaButton>(IServiceFactory serviceFactory,
|
||||
IMediator mediator,
|
||||
IDisposer disposer,
|
||||
ITemplateFactory templateFactory,
|
||||
PlaybackButtonType playbackButtonType,
|
||||
Guid guid = default,
|
||||
string? text = null,
|
||||
string? icon = null,
|
||||
RelayCommand? command = null) :
|
||||
WidgetButtonViewModel(serviceFactory, mediator, disposer, templateFactory, guid, text, icon, command)
|
||||
IRelayCommand invokeCommand) :
|
||||
WidgetComponentViewModel(serviceFactory, mediator, disposer, templateFactory),
|
||||
INotificationHandler<Changed<TMediaButton>>,
|
||||
IMediaButtonViewModel
|
||||
where TMediaButton :
|
||||
MediaButton
|
||||
{
|
||||
[ObservableProperty]
|
||||
private PlaybackButtonType playbackButtonType = playbackButtonType;
|
||||
private IRelayCommand? invokeCommand = invokeCommand;
|
||||
|
||||
public Task Handle(Changed<MediaControllerPlaybackStatus> notification,
|
||||
[ObservableProperty]
|
||||
private bool isEnabled;
|
||||
|
||||
[ObservableProperty]
|
||||
private string? state = $"{typeof(TMediaButton).Name}";
|
||||
|
||||
public Task Handle(Changed<TMediaButton> args,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (notification.Value is MediaControllerPlaybackStatus information)
|
||||
{
|
||||
//switch (buttonType)
|
||||
//{
|
||||
// case PlaybackButtonType.Play:
|
||||
// Visible = information.Status is PlaybackStatus.Paused;
|
||||
// break;
|
||||
// case PlaybackButtonType.Pause:
|
||||
// Visible = information.Status is PlaybackStatus.Playing;
|
||||
// break;
|
||||
//}
|
||||
}
|
||||
|
||||
IsEnabled = args.Value is not null && args.Value.IsEnabled;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
//public override Task OnInitializeAsync()
|
||||
//{
|
||||
// await Mediator.PublishAsync<Request<PlaybackInformation>>();
|
||||
//}
|
||||
public override async Task InitializeAsync() =>
|
||||
await Mediator.PublishAsync<Request<TMediaButton>>();
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
using Windows.Media.Control;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using Windows.Media.Control;
|
||||
using Windows.Storage.Streams;
|
||||
|
||||
namespace Hyperbar.Widget.MediaController.Windows;
|
||||
|
||||
public class MediaController :
|
||||
INotificationHandler<Play>,
|
||||
INotificationHandler<Pause>,
|
||||
INotificationHandler<Request<MediaControllerPlaybackStatus>>,
|
||||
INotificationHandler<Request<MediaPrevious>>,
|
||||
INotificationHandler<Request<MediaNext>>,
|
||||
INotificationHandler<Request<MediaInformation>>,
|
||||
INotificationHandler<Request<MediaPreviousButton>>,
|
||||
INotificationHandler<Request<MediaNextButton>>,
|
||||
IDisposable
|
||||
{
|
||||
private readonly AsyncLock asyncLock = new();
|
||||
@@ -38,79 +41,100 @@ public class MediaController :
|
||||
disposer.Dispose(this);
|
||||
}
|
||||
|
||||
public async Task Handle(Play notification,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await session.TryPlayAsync();
|
||||
await UpdateMediaPlaybackPropertiesAsync();
|
||||
}
|
||||
|
||||
public async Task Handle(Pause notification,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await session.TryPauseAsync();
|
||||
await UpdateMediaPlaybackPropertiesAsync();
|
||||
}
|
||||
|
||||
public async Task Handle(Request<MediaControllerPlaybackStatus> args,
|
||||
CancellationToken cancellationToken) => await UpdateMediaPlaybackPropertiesAsync();
|
||||
|
||||
public async Task Handle(Request<MediaInformation> args,
|
||||
CancellationToken cancellationToken) => await UpdateMediaPropertiesAsync();
|
||||
CancellationToken cancellationToken) => await UpdateMediaInformationAsync();
|
||||
|
||||
public async Task Handle(Request<MediaNext> args,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await session.TrySkipNextAsync();
|
||||
await UpdateMediaStateAsync();
|
||||
}
|
||||
|
||||
public async Task Handle(Request<MediaPrevious> args, CancellationToken cancellationToken)
|
||||
{
|
||||
await session.TrySkipPreviousAsync();
|
||||
await UpdateMediaStateAsync();
|
||||
}
|
||||
|
||||
public async Task Handle(Request<MediaPreviousButton> args,
|
||||
CancellationToken cancellationToken) => await UpdateMediaStateAsync();
|
||||
|
||||
public async Task Handle(Request<MediaNextButton> args,
|
||||
CancellationToken cancellationToken) => await UpdateMediaStateAsync();
|
||||
|
||||
private async void OnMediaPropertiesChanged(GlobalSystemMediaTransportControlsSession sender,
|
||||
MediaPropertiesChangedEventArgs args) => await UpdateMediaPropertiesAsync();
|
||||
MediaPropertiesChangedEventArgs args)
|
||||
{
|
||||
await UpdateMediaInformationAsync();
|
||||
await UpdateMediaStateAsync();
|
||||
}
|
||||
|
||||
private async void OnPlaybackInfoChanged(GlobalSystemMediaTransportControlsSession sender,
|
||||
PlaybackInfoChangedEventArgs args) => await UpdateMediaPlaybackPropertiesAsync();
|
||||
PlaybackInfoChangedEventArgs args) => await UpdateMediaStateAsync();
|
||||
|
||||
private async Task UpdateMediaPlaybackPropertiesAsync()
|
||||
{
|
||||
using (await asyncLock)
|
||||
private async Task UpdateMediaInformationAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo = session.GetPlaybackInfo();
|
||||
|
||||
if (playbackInfo.PlaybackStatus != playbackStatus)
|
||||
{
|
||||
playbackStatus = playbackInfo.PlaybackStatus;
|
||||
await mediator.PublishAsync(new Changed<MediaControllerPlaybackStatus>(
|
||||
new MediaControllerPlaybackStatus((PlaybackStatus)playbackStatus)));
|
||||
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UpdateMediaPropertiesAsync()
|
||||
{
|
||||
using (await asyncLock)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
GlobalSystemMediaTransportControlsSessionMediaProperties mediaProperties =
|
||||
await session.TryGetMediaPropertiesAsync();
|
||||
|
||||
IRandomAccessStreamWithContentType? randomAccessStream = null;
|
||||
byte[]? buffer = null;
|
||||
|
||||
if (mediaProperties.Thumbnail is not null)
|
||||
{
|
||||
randomAccessStream =
|
||||
IRandomAccessStreamWithContentType randomAccessStream =
|
||||
await mediaProperties.Thumbnail.OpenReadAsync();
|
||||
|
||||
var stream = randomAccessStream.AsStream();
|
||||
|
||||
using MemoryStream memoryStream = new();
|
||||
await stream.CopyToAsync(memoryStream);
|
||||
buffer = memoryStream.ToArray();
|
||||
}
|
||||
|
||||
await mediator.PublishAsync(new Changed<MediaInformation>(new MediaInformation(mediaProperties.Title,
|
||||
mediaProperties.Artist, randomAccessStream is not null ? randomAccessStream.AsStream() : default)));
|
||||
mediaProperties.Artist, buffer)));
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private bool isPreviousEnabled;
|
||||
private bool isNextEnabled;
|
||||
|
||||
private async Task UpdateMediaStateAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo =
|
||||
session.GetPlaybackInfo();
|
||||
|
||||
bool isPreviousEnabled = playbackInfo.Controls.IsPreviousEnabled;
|
||||
if (this.isPreviousEnabled != isPreviousEnabled)
|
||||
{
|
||||
await mediator.PublishAsync(new Changed<MediaPreviousButton>(new
|
||||
MediaPreviousButton(isPreviousEnabled)));
|
||||
|
||||
this.isPreviousEnabled = isPreviousEnabled;
|
||||
}
|
||||
|
||||
bool isNextEnabled = playbackInfo.Controls.IsNextEnabled;
|
||||
if (this.isNextEnabled != isNextEnabled)
|
||||
{
|
||||
await mediator.PublishAsync(new Changed<MediaNextButton>(new
|
||||
MediaNextButton(isNextEnabled)));
|
||||
|
||||
this.isNextEnabled = isNextEnabled;
|
||||
}
|
||||
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
namespace Hyperbar.Widget.MediaController.Windows;
|
||||
|
||||
public record MediaControllerPlaybackStatus(PlaybackStatus Status) :
|
||||
INotification;
|
||||
@@ -1,31 +0,0 @@
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Hyperbar.Widget.MediaController.Windows;
|
||||
|
||||
public class MediaControllerPlaybackStatusHandler(IMediator mediator,
|
||||
IServiceFactory factory) :
|
||||
INotificationHandler<Changed<MediaControllerPlaybackStatus>>
|
||||
{
|
||||
public async Task Handle(Changed<MediaControllerPlaybackStatus> notification,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (notification.Value is MediaControllerPlaybackStatus mediaControllerPlaybackInformation)
|
||||
{
|
||||
if (mediaControllerPlaybackInformation.Status is PlaybackStatus.Playing)
|
||||
{
|
||||
await mediator.PublishAsync(new Replaced<WidgetComponentViewModel>(2, factory.Create<MediaButtonViewModel>(
|
||||
PlaybackButtonType.Pause, "Pause", "\uE769",
|
||||
new RelayCommand(async () => await mediator.PublishAsync<Pause>()))), nameof(MediaControllerViewModel),
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
if (mediaControllerPlaybackInformation.Status is PlaybackStatus.Paused)
|
||||
{
|
||||
await mediator.PublishAsync(new Replaced<WidgetComponentViewModel>(2, factory.Create<MediaButtonViewModel>(
|
||||
PlaybackButtonType.Pause, "Play", "\uE768",
|
||||
new RelayCommand(async () => await mediator.PublishAsync<Play>()))), nameof(MediaControllerViewModel),
|
||||
cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Hyperbar.Widget.MediaController.Windows;
|
||||
|
||||
|
||||
|
||||
[NotificationHandler(nameof(MediaControllerViewModel))]
|
||||
public class MediaControllerViewModel :
|
||||
ObservableCollectionViewModel<WidgetComponentViewModel>,
|
||||
@@ -16,17 +18,14 @@ public class MediaControllerViewModel :
|
||||
|
||||
Add<MediaInformationViewModel>();
|
||||
|
||||
Add<MediaButtonViewModel>(PlaybackButtonType.Previous,
|
||||
"Previous", "\uEB9E",
|
||||
new RelayCommand(async () => await mediator.PublishAsync<Previous>()));
|
||||
Add<MediaButtonViewModel<MediaPreviousButton>>(new RelayCommand(async () =>
|
||||
await mediator.PublishAsync<Request<MediaPrevious>>()));
|
||||
|
||||
Add<MediaButtonViewModel>(PlaybackButtonType.Pause,
|
||||
"Pause", "\uE769",
|
||||
new RelayCommand(async () => await mediator.PublishAsync<Pause>()));
|
||||
Add<MediaButtonViewModel<MediaPlayPauseButton>>(new RelayCommand(async () =>
|
||||
await mediator.PublishAsync<Request<MediaPlayPauseButton>>()));
|
||||
|
||||
Add<MediaButtonViewModel>(PlaybackButtonType.Forward,
|
||||
"Forward", "\uEB9D",
|
||||
new RelayCommand(async () => await mediator.PublishAsync<Forward>()));
|
||||
Add<MediaButtonViewModel<MediaNextButton>>(new RelayCommand(async () =>
|
||||
await mediator.PublishAsync<Request<MediaNext>>()));
|
||||
}
|
||||
|
||||
public ITemplateFactory TemplateFactory { get; set; }
|
||||
|
||||
@@ -23,9 +23,10 @@ public class MediaControllerWidget :
|
||||
.AddHandler<MediaControllerHandler>()
|
||||
.AddTransient<IFactory<MediaController, MediaControllerViewModel?>, MediaControllerViewModelFactory>()
|
||||
.AddCache<MediaController, MediaControllerViewModel>()
|
||||
.AddHandler<MediaControllerPlaybackStatusHandler>()
|
||||
.AddContentTemplate<MediaControllerViewModel, MediaControllerView>()
|
||||
.AddContentTemplate<MediaInformationViewModel, MediaInformationView>()
|
||||
.AddContentTemplate<MediaButtonViewModel, MediaButtonView>();
|
||||
.AddContentTemplate<MediaButtonViewModel<MediaPreviousButton>, MediaButtonView>()
|
||||
.AddContentTemplate<MediaButtonViewModel<MediaPlayPauseButton>, MediaButtonView>()
|
||||
.AddContentTemplate<MediaButtonViewModel<MediaNextButton>, MediaButtonView>();
|
||||
});
|
||||
}
|
||||
@@ -2,6 +2,4 @@
|
||||
|
||||
public record MediaInformation(string Title,
|
||||
string Description,
|
||||
Stream? ThumbnailSource);
|
||||
|
||||
|
||||
byte[]? Image);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
Grid.Column="0"
|
||||
Width="40"
|
||||
Height="40">
|
||||
<Image Source="{Binding ThumbnailSource, Converter={windows:StreamToImageSourceConverter}}" />
|
||||
<Image Source="{Binding Image, Converter={windows:StreamToImageSourceConverter}}" />
|
||||
</Border>
|
||||
<StackPanel Grid.Column="2">
|
||||
<TextBlock
|
||||
@@ -32,7 +32,7 @@
|
||||
TextWrapping="NoWrap" />
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactions:EventTriggerBehavior EventName="Loaded">
|
||||
<interactions:InvokeCommandAction Command="{x:Bind ViewModel.Initialize}" />
|
||||
<interactions:InvokeCommandAction Command="{x:Bind ViewModel.InitializeCommand}" />
|
||||
</interactions:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</StackPanel>
|
||||
|
||||
@@ -13,7 +13,7 @@ public partial class MediaInformationViewModel(IServiceFactory serviceFactory,
|
||||
private string? description;
|
||||
|
||||
[ObservableProperty]
|
||||
private Stream? thumbnailSource;
|
||||
private byte[]? image;
|
||||
|
||||
[ObservableProperty]
|
||||
private string? title;
|
||||
@@ -25,12 +25,12 @@ public partial class MediaInformationViewModel(IServiceFactory serviceFactory,
|
||||
{
|
||||
Title = value.Title;
|
||||
Description = value.Description;
|
||||
ThumbnailSource = value.ThumbnailSource;
|
||||
Image = value.Image;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override async Task OnInitializeAsync() =>
|
||||
public override async Task InitializeAsync() =>
|
||||
await Mediator.PublishAsync<Request<MediaInformation>>();
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
namespace Hyperbar.Widget.MediaController.Windows;
|
||||
|
||||
public record Play : INotification;
|
||||
public record MediaNext;
|
||||
@@ -0,0 +1,4 @@
|
||||
namespace Hyperbar.Widget.MediaController.Windows;
|
||||
|
||||
public record MediaNextButton(bool IsEnabled) :
|
||||
MediaButton(IsEnabled);
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
namespace Hyperbar.Widget.MediaController.Windows;
|
||||
|
||||
public record Pause : INotification;
|
||||
public record MediaPlayPause;
|
||||
@@ -0,0 +1,4 @@
|
||||
namespace Hyperbar.Widget.MediaController.Windows;
|
||||
|
||||
public record MediaPlayPauseButton(bool IsEnabled) :
|
||||
MediaButton(IsEnabled);
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
namespace Hyperbar.Widget.MediaController.Windows;
|
||||
|
||||
public record Forward : INotification;
|
||||
public record MediaPrevious;
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace Hyperbar.Widget.MediaController.Windows;
|
||||
|
||||
public record MediaPreviousButton(bool IsEnabled) :
|
||||
MediaButton(IsEnabled);
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace Hyperbar.Widget.MediaController.Windows;
|
||||
|
||||
public enum PlaybackButtonType
|
||||
{
|
||||
Previous,
|
||||
Play,
|
||||
Pause,
|
||||
Forward
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
namespace Hyperbar.Widget.MediaController.Windows;
|
||||
|
||||
public enum PlaybackStatus
|
||||
{
|
||||
Closed,
|
||||
Opened,
|
||||
Changing,
|
||||
Stopped,
|
||||
Playing,
|
||||
Paused
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.231202003-experimental1" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.240124002-experimental2" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26031-preview" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
Width="{StaticResource ButtonWidth}"
|
||||
Height="{StaticResource ButtonHeight}"
|
||||
Padding="{StaticResource ButtonPadding}"
|
||||
Command="{Binding Click}"
|
||||
Command="{Binding InvokeCommand}"
|
||||
Content="{Binding Icon}"
|
||||
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||
FontSize="16"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<SplitButton
|
||||
Height="{StaticResource ButtonHeight}"
|
||||
Margin="0,1,0,0"
|
||||
Command="{Binding Click}"
|
||||
Command="{Binding InvokeCommand}"
|
||||
Content="{Binding Icon}"
|
||||
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||
FontSize="16">
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</ItemsControl.ItemContainerTransitions>
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactions:EventTriggerBehavior EventName="Loaded">
|
||||
<interactions:InvokeCommandAction Command="{Binding Initialize}" />
|
||||
<interactions:InvokeCommandAction Command="{Binding InitializeCommand}" />
|
||||
</interactions:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</ItemsControl>
|
||||
|
||||
@@ -11,14 +11,8 @@ public partial class WidgetButtonViewModel(IServiceFactory serviceFactory,
|
||||
Guid id,
|
||||
string? text = null,
|
||||
string? icon = null,
|
||||
RelayCommand? command = null) : WidgetComponentViewModel(serviceFactory, mediator, disposer, templateFactory)
|
||||
RelayCommand? invokeCommand = null) : WidgetComponentViewModel(serviceFactory, mediator, disposer, templateFactory)
|
||||
{
|
||||
[ObservableProperty]
|
||||
private IRelayCommand? click = command;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool enabled;
|
||||
|
||||
[ObservableProperty]
|
||||
private string? icon = icon;
|
||||
|
||||
@@ -26,8 +20,11 @@ public partial class WidgetButtonViewModel(IServiceFactory serviceFactory,
|
||||
private Guid id = id;
|
||||
|
||||
[ObservableProperty]
|
||||
private string? text = text;
|
||||
private IRelayCommand? invokeCommand = invokeCommand;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool visible;
|
||||
private bool isEnabled;
|
||||
|
||||
[ObservableProperty]
|
||||
private string? text = text;
|
||||
}
|
||||
@@ -29,7 +29,7 @@
|
||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls.Primitives" Version="7.1.2" />
|
||||
<PackageReference Include="CustomExtensions.WinUI" Version="0.1.10-beta" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.231202003-experimental1" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.240124002-experimental2" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26031-preview" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
|
||||
<Manifest Include="$(ApplicationManifest)" />
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Hyperbar;
|
||||
|
||||
public interface IInitialization
|
||||
{
|
||||
ICommand Initialize { get; }
|
||||
ICommand InitializeCommand { get; }
|
||||
|
||||
Task InitializeAsync();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
namespace Hyperbar;
|
||||
|
||||
public interface IObservableCollectionViewModel<TItem>;
|
||||
public interface IObservableCollectionViewModel<TItem> :
|
||||
IObservableViewModel;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Hyperbar;
|
||||
|
||||
public interface IObservableViewModel
|
||||
{
|
||||
ICommand InitializeCommand { get; }
|
||||
}
|
||||
@@ -54,7 +54,6 @@ public partial class ObservableCollectionViewModel<TItem> :
|
||||
mediator.Subscribe(this);
|
||||
|
||||
collection.CollectionChanged += OnCollectionChanged;
|
||||
|
||||
AddRange(items);
|
||||
}
|
||||
|
||||
@@ -62,8 +61,8 @@ public partial class ObservableCollectionViewModel<TItem> :
|
||||
|
||||
public int Count => collection.Count;
|
||||
|
||||
public ICommand Initialize =>
|
||||
new AsyncRelayCommand(InitializeAsync);
|
||||
public ICommand InitializeCommand =>
|
||||
new AsyncRelayCommand(CoreInitializeAsync);
|
||||
|
||||
bool IList.IsFixedSize => false;
|
||||
|
||||
@@ -297,7 +296,7 @@ public partial class ObservableCollectionViewModel<TItem> :
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual Task OnInitializeAsync()
|
||||
public virtual Task InitializeAsync()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
@@ -370,7 +369,7 @@ public partial class ObservableCollectionViewModel<TItem> :
|
||||
private static bool IsCompatibleObject(object? value) =>
|
||||
(value is TItem) || (value == null && default(TItem) == null);
|
||||
|
||||
public async Task InitializeAsync()
|
||||
private async Task CoreInitializeAsync()
|
||||
{
|
||||
if (isInitialized)
|
||||
{
|
||||
@@ -380,8 +379,9 @@ public partial class ObservableCollectionViewModel<TItem> :
|
||||
isInitialized = true;
|
||||
|
||||
await Mediator.PublishAsync<Enumerate<TItem>>();
|
||||
await OnInitializeAsync();
|
||||
await InitializeAsync();
|
||||
}
|
||||
|
||||
private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs args) =>
|
||||
CollectionChanged?.Invoke(this, args);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user