Wire up the disposer for cleaning up unused objects, i.e disposing a VM will remove it from the view
This commit is contained in:
@@ -3,22 +3,17 @@
|
||||
namespace Hyperbar.Windows.Primary;
|
||||
|
||||
public class MediaController :
|
||||
INotificationHandler<PlayRequest>,
|
||||
IDisposable
|
||||
INotificationHandler<PlayRequest>
|
||||
{
|
||||
public MediaController(GlobalSystemMediaTransportControlsSession session)
|
||||
{
|
||||
private readonly GlobalSystemMediaTransportControlsSession session;
|
||||
|
||||
public MediaController(GlobalSystemMediaTransportControlsSession session,
|
||||
IMediator mediator)
|
||||
{
|
||||
this.session = session;
|
||||
mediator.Subscribe(this);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ValueTask Handle(PlayRequest notification,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public async ValueTask Handle(PlayRequest notification, CancellationToken cancellationToken) =>
|
||||
await session.TryPlayAsync();
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
using Windows.Media.Control;
|
||||
|
||||
namespace Hyperbar.Windows.Primary;
|
||||
|
||||
public class MediaControllerInitializer :
|
||||
IInitializer
|
||||
{
|
||||
private readonly List<GlobalSystemMediaTransportControlsSession> sessions = [];
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
GlobalSystemMediaTransportControlsSessionManager mediaTransportControlsSessionManager =
|
||||
await GlobalSystemMediaTransportControlsSessionManager.RequestAsync();
|
||||
|
||||
mediaTransportControlsSessionManager.SessionsChanged += OnSessionsChanged;
|
||||
IReadOnlyList<GlobalSystemMediaTransportControlsSession> sessions =
|
||||
mediaTransportControlsSessionManager.GetSessions();
|
||||
|
||||
foreach (var session in sessions)
|
||||
{
|
||||
this.sessions.Add(session);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSessionsChanged(GlobalSystemMediaTransportControlsSessionManager sender,
|
||||
SessionsChangedEventArgs args)
|
||||
{
|
||||
IReadOnlyList<GlobalSystemMediaTransportControlsSession> sessions =
|
||||
sender.GetSessions();
|
||||
|
||||
foreach (var session in this.sessions.ToList())
|
||||
{
|
||||
if (!sessions.Contains(session))
|
||||
{
|
||||
this.sessions.Remove(session);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var session in sessions)
|
||||
{
|
||||
if (!this.sessions.Contains(session))
|
||||
{
|
||||
this.sessions.Add(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading.Channels;
|
||||
using Windows.Media.Control;
|
||||
|
||||
namespace Hyperbar.Windows.Primary;
|
||||
|
||||
public class MediaControllerManager :
|
||||
IInitializer
|
||||
{
|
||||
private readonly ConcurrentDictionary<GlobalSystemMediaTransportControlsSession, MediaController> cachedSessions = [];
|
||||
private readonly IMediator mediator;
|
||||
private readonly Queue<MediaController> mediaControllers;
|
||||
private readonly IServiceFactory serviceFactory;
|
||||
|
||||
public MediaControllerManager(IServiceFactory serviceFactory,
|
||||
IMediator mediator,
|
||||
Queue<MediaController> mediaControllers)
|
||||
{
|
||||
this.serviceFactory = serviceFactory;
|
||||
this.mediator = mediator;
|
||||
this.mediaControllers = mediaControllers;
|
||||
}
|
||||
|
||||
private Channel<MediaController> d;
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
d = Channel.CreateUnbounded<MediaController>();
|
||||
|
||||
_ = Task.Run(async () => {
|
||||
|
||||
await foreach (var coordinates in d.Reader.ReadAllAsync())
|
||||
{
|
||||
Console.WriteLine(coordinates);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
GlobalSystemMediaTransportControlsSessionManager mediaTransportControlsSessionManager =
|
||||
await GlobalSystemMediaTransportControlsSessionManager.RequestAsync();
|
||||
mediaTransportControlsSessionManager.SessionsChanged += OnSessionsChanged;
|
||||
|
||||
IReadOnlyList<GlobalSystemMediaTransportControlsSession> sessions =
|
||||
mediaTransportControlsSessionManager.GetSessions();
|
||||
|
||||
foreach (GlobalSystemMediaTransportControlsSession session in sessions)
|
||||
{
|
||||
await InitializeSessionAsync(session);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task InitializeSessionAsync(GlobalSystemMediaTransportControlsSession session)
|
||||
{
|
||||
if (serviceFactory.Create<MediaController>(session) is MediaController mediaController)
|
||||
{
|
||||
await d.Writer.WriteAsync(mediaController);
|
||||
|
||||
mediaControllers.Enqueue(mediaController);
|
||||
|
||||
cachedSessions.TryAdd(session, mediaController);
|
||||
await mediator.PublishAsync(new Created<MediaController>(mediaController));
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnSessionsChanged(GlobalSystemMediaTransportControlsSessionManager sender,
|
||||
SessionsChangedEventArgs args)
|
||||
{
|
||||
IReadOnlyList<GlobalSystemMediaTransportControlsSession> sessions =
|
||||
sender.GetSessions();
|
||||
|
||||
foreach (KeyValuePair<GlobalSystemMediaTransportControlsSession, MediaController> session in
|
||||
cachedSessions)
|
||||
{
|
||||
if (!sessions.Contains(session.Key))
|
||||
{
|
||||
cachedSessions.TryRemove(session);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (GlobalSystemMediaTransportControlsSession session in sessions)
|
||||
{
|
||||
await InitializeSessionAsync(session);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveSession(GlobalSystemMediaTransportControlsSession session)
|
||||
{
|
||||
if (serviceFactory.Create<MediaController>(session) is MediaController mediaController)
|
||||
{
|
||||
cachedSessions.TryAdd(session, mediaController);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,17 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Hyperbar.Windows.Primary;
|
||||
|
||||
public partial class MediaInformationViewModel :
|
||||
WidgetComponentViewModel
|
||||
{
|
||||
[ObservableProperty]
|
||||
private string title = "this is a test";
|
||||
|
||||
[ObservableProperty]
|
||||
private string description = "this is a test description";
|
||||
|
||||
public MediaInformationViewModel(ITemplateFactory templateFactory) : base(templateFactory)
|
||||
{
|
||||
}
|
||||
}
|
||||
//public class MediaControllerViewModelFactory(IServiceFactory service,
|
||||
// IMediator mediator,
|
||||
// Queue<MediaController> mediaControllers) :
|
||||
// IFactory<MediaControllerViewModel>
|
||||
//{
|
||||
// public MediaControllerViewModel Create()
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
//}
|
||||
|
||||
public class MediaControllerViewModel :
|
||||
ObservableCollectionViewModel<WidgetComponentViewModel>,
|
||||
@@ -22,7 +19,8 @@ public class MediaControllerViewModel :
|
||||
{
|
||||
public MediaControllerViewModel(ITemplateFactory templateFactory,
|
||||
IServiceFactory serviceFactory,
|
||||
IMediator mediator) : base(serviceFactory, mediator)
|
||||
IMediator mediator,
|
||||
IDisposer disposer) : base(serviceFactory, mediator, disposer)
|
||||
{
|
||||
TemplateFactory = templateFactory;
|
||||
|
||||
|
||||
@@ -9,10 +9,8 @@ public class MediaControllerWidgetProvider :
|
||||
{
|
||||
public void Create(HostBuilderContext comtext, IServiceCollection services) =>
|
||||
services.AddWidgetTemplate<MediaControllerWidgetViewModel, MediaControllerWidgetView>()
|
||||
.AddTransient<IInitializer, MediaControllerInitializer>()
|
||||
.AddContentTemplate<MediaControllerViewModel, MediaControllerView>()
|
||||
.AddContentTemplate<MediaControllerViewModel, MediaControllerView>()
|
||||
.AddContentTemplate<MediaControllerViewModel, MediaControllerView>()
|
||||
.AddContentTemplate<MediaInformationViewModel, MediaInformationView>();
|
||||
.AddSingleton<Queue<MediaController>>()
|
||||
.AddSingleton<IInitializer, MediaControllerManager>()
|
||||
.AddContentTemplate<MediaControllerViewModel, MediaControllerView>();
|
||||
|
||||
}
|
||||
@@ -3,8 +3,8 @@
|
||||
public class MediaControllerWidgetViewModel(ITemplateFactory templateFactory,
|
||||
IServiceFactory serviceFactory,
|
||||
IMediator mediator,
|
||||
IEnumerable<MediaControllerViewModel> items) :
|
||||
ObservableCollectionViewModel<MediaControllerViewModel>(serviceFactory, mediator, items),
|
||||
IDisposer disposer) :
|
||||
ObservableCollectionViewModel<MediaControllerViewModel>(serviceFactory, mediator, disposer),
|
||||
IWidgetViewModel,
|
||||
ITemplatedViewModel
|
||||
{
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace Hyperbar.Windows.Primary;
|
||||
|
||||
public partial class MediaInformationViewModel :
|
||||
WidgetComponentViewModel
|
||||
{
|
||||
[ObservableProperty]
|
||||
private string title = "this is a test";
|
||||
|
||||
[ObservableProperty]
|
||||
private string description = "this is a test description";
|
||||
|
||||
public MediaInformationViewModel(IServiceFactory serviceFactory, IMediator mediator, IDisposer disposer, ITemplateFactory templateFactory) : base(serviceFactory, mediator, disposer, templateFactory)
|
||||
{
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user