Files

93 lines
2.8 KiB
C#

using NucleicApp.Services;
using NucleicProtocol.Interop;
namespace NucleicApp.ViewModels;
public enum ShellSection
{
Home,
Sessions,
Approvals,
Projects,
Settings,
}
/// Navigation state for the WinUI split shell. The future XAML layer binds to this class and
/// swaps views; session activation remains an ordinary protocol subscription intent.
public sealed class ShellViewModel : ViewModelBase, IDisposable
{
private readonly RendererStore store;
private readonly HostConnection connection;
private ShellSection section = ShellSection.Home;
private SessionDetailViewModel? selectedSession;
private HostConnectionState connectionState;
private bool disposed;
public ShellViewModel(RendererStore store, HostConnection connection)
{
this.store = store;
this.connection = connection;
connectionState = connection.State;
store.PropertyChanged += StoreChanged;
connection.StateChanged += ConnectionChanged;
Home = new HomeViewModel(store);
}
public HomeViewModel Home { get; }
public ShellSection Section { get => section; private set => Set(ref section, value); }
public SessionDetailViewModel? SelectedSession
{
get => selectedSession;
private set => Set(ref selectedSession, value);
}
public HostConnectionState ConnectionState
{
get => connectionState;
private set => Set(ref connectionState, value);
}
public int PendingApprovalCount => store.PendingApprovals.Count;
public void Navigate(ShellSection destination)
{
ObjectDisposedException.ThrowIf(disposed, this);
if (destination != ShellSection.Sessions) CloseSession();
Section = destination;
}
public ProtocolResult OpenSession(string sessionId, ulong? sinceSequence = null)
{
ObjectDisposedException.ThrowIf(disposed, this);
if (SelectedSession?.SessionId != sessionId)
{
SelectedSession?.Dispose();
SelectedSession = new SessionDetailViewModel(sessionId, store, connection);
}
Section = ShellSection.Sessions;
return SelectedSession.Activate(sinceSequence);
}
public void CloseSession()
{
SelectedSession?.Dispose();
SelectedSession = null;
}
private void StoreChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs args)
{
if (args.PropertyName == nameof(RendererStore.PendingApprovals))
Raise(nameof(PendingApprovalCount));
}
private void ConnectionChanged(HostConnectionState state) => ConnectionState = state;
public void Dispose()
{
if (disposed) return;
disposed = true;
CloseSession();
Home.Dispose();
store.PropertyChanged -= StoreChanged;
connection.StateChanged -= ConnectionChanged;
}
}