64 lines
1.3 KiB
C#
64 lines
1.3 KiB
C#
using decePubClient.Components.Daisy;
|
|||
|
|
|
||
|
|
namespace decePubClient.Services
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// The overlays open now, newest last (IDOverlayHost): MainLayout closes the newest when the Back button is pressed
|
||
|
|
/// while one is open, and all of them when the app goes elsewhere.
|
||
|
|
/// </summary>
|
||
|
|
public class OverlayService : IDOverlayHost
|
||
|
|
{
|
||
|
|
readonly List<Entry> open = [];
|
||
|
|
|
||
|
|
public bool HasOpen
|
||
|
|
{
|
||
|
|
get
|
||
|
|
{
|
||
|
|
lock (open)
|
||
|
|
return open.Count > 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public IDisposable Open(Func<Task> close)
|
||
|
|
{
|
||
|
|
var entry = new Entry(this, close);
|
||
|
|
lock (open)
|
||
|
|
open.Add(entry);
|
||
|
|
return entry;
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task CloseTop(CancellationToken cancellationToken = default)
|
||
|
|
{
|
||
|
|
Entry top;
|
||
|
|
lock (open)
|
||
|
|
top = open.LastOrDefault();
|
||
|
|
if (top is null)
|
||
|
|
return;
|
||
|
|
top.Dispose();
|
||
|
|
await top.Close();
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task CloseAll(CancellationToken cancellationToken = default)
|
||
|
|
{
|
||
|
|
Entry[] all;
|
||
|
|
lock (open)
|
||
|
|
{
|
||
|
|
all = [.. open];
|
||
|
|
open.Clear();
|
||
|
|
}
|
||
|
|
foreach (var entry in all.Reverse())
|
||
|
|
await entry.Close();
|
||
|
|
}
|
||
|
|
|
||
|
|
sealed class Entry(OverlayService owner, Func<Task> close) : IDisposable
|
||
|
|
{
|
||
|
|
public Func<Task> Close { get; } = close;
|
||
|
|
|
||
|
|
public void Dispose()
|
||
|
|
{
|
||
|
|
lock (owner.open)
|
||
|
|
owner.open.Remove(this);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|