diff options
Diffstat (limited to 'MatrixUtils.Web/Pages/Rooms/Index2Components')
7 files changed, 0 insertions, 603 deletions
diff --git a/MatrixUtils.Web/Pages/Rooms/Index2Components/MainTabComponents/MainTabSpaceItem.razor b/MatrixUtils.Web/Pages/Rooms/Index2Components/MainTabComponents/MainTabSpaceItem.razor deleted file mode 100644 index 6483f01..0000000 --- a/MatrixUtils.Web/Pages/Rooms/Index2Components/MainTabComponents/MainTabSpaceItem.razor +++ /dev/null @@ -1,56 +0,0 @@ -@using MatrixUtils.Abstractions -<div class="spaceListItem" style="@(SelectedSpace == Space ? "background-color: #FFFFFF33;" : "")" onclick="@SelectSpace"> - <div class="spaceListItemContainer"> - @if (IsSpaceOpened()) { - <span onclick="@ToggleSpace">▼ </span> - } - else { - <span onclick="@ToggleSpace">▶ </span> - } - - <MxcImage Circular="true" Height="32" Width="32" Homeserver="Space.Room.Homeserver" MxcUri="@Space.RoomIcon"></MxcImage> - <span class="spaceNameEllipsis">@Space.RoomName</span> - </div> - @if (IsSpaceOpened()) { - <span>meow</span> - } -</div> - -@code { - - [Parameter] - public RoomInfo Space { get; set; } - - [Parameter] - public RoomInfo SelectedSpace { get; set; } - - [Parameter] - public EventCallback<RoomInfo> SelectedSpaceChanged { get; set; } - - [Parameter] - public List<RoomInfo> OpenedSpaces { get; set; } - - protected override Task OnInitializedAsync() { - Space.PropertyChanged += (sender, args) => { StateHasChanged(); }; - return base.OnInitializedAsync(); - } - - public void ToggleSpace() { - if (OpenedSpaces.Contains(Space)) { - OpenedSpaces.Remove(Space); - } - else { - OpenedSpaces.Add(Space); - } - } - - public void SelectSpace() { - SelectedSpace = Space; - SelectedSpaceChanged.InvokeAsync(Space); - } - - public bool IsSpaceOpened() { - return OpenedSpaces.Contains(Space); - } - -} \ No newline at end of file diff --git a/MatrixUtils.Web/Pages/Rooms/Index2Components/MainTabComponents/MainTabSpaceItem.razor.css b/MatrixUtils.Web/Pages/Rooms/Index2Components/MainTabComponents/MainTabSpaceItem.razor.css deleted file mode 100644 index d6e413f..0000000 --- a/MatrixUtils.Web/Pages/Rooms/Index2Components/MainTabComponents/MainTabSpaceItem.razor.css +++ /dev/null @@ -1,29 +0,0 @@ -.spaceNameEllipsis { - padding-left: 8px; - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - vertical-align: middle; - width: calc(100% - 64px); -} - -.spaceListItem { - display: block; - width: 100%; - height: 3em; -} - -.spaceListItemContainer { - display: flex; - align-items: center; - vertical-align: center; - justify-content: space-between; - padding: 0 16px; - width: 100%; - height: 100%; -} - -.spaceListItem > img { - display: inline-block; -} \ No newline at end of file diff --git a/MatrixUtils.Web/Pages/Rooms/Index2Components/RoomsIndex2ByRoomTypeTab.razor b/MatrixUtils.Web/Pages/Rooms/Index2Components/RoomsIndex2ByRoomTypeTab.razor deleted file mode 100644 index f4cf849..0000000 --- a/MatrixUtils.Web/Pages/Rooms/Index2Components/RoomsIndex2ByRoomTypeTab.razor +++ /dev/null @@ -1,53 +0,0 @@ -@using MatrixUtils.Abstractions -@using System.Security.Cryptography -@using ArcaneLibs.Extensions -<h3>RoomsIndex2MainTab</h3> - -<div> - <div class="row"> - <div class="col-3" style="background-color: #ffffff66;"> - <LinkButton>Uncategorised rooms</LinkButton> - @foreach (var space in Data.Rooms.Where(x => x.RoomType == "m.space")) { - <div style="@("width: 100%; height: 50px; background-color: #" + RandomNumberGenerator.GetBytes(3).Append((byte)0x11).ToArray().AsHexString().Replace(" ",""))"> - <p>@space.RoomName</p> - </div> - } - </div> - <div class="col-9" style="background-color: #ff00ff66;"> - <p>omae wa mou shindeiru</p> - </div> - </div> -</div> - -@code { - - [CascadingParameter] - public Index2.RoomListViewData Data { get; set; } = null!; - - protected override async Task OnInitializedAsync() { - Data.Rooms.CollectionChanged += (sender, args) => { - DebouncedStateHasChanged(); - if (args.NewItems is { Count: > 0 }) - foreach (var newItem in args.NewItems) { - (newItem as RoomInfo).PropertyChanged += (sender, args) => { DebouncedStateHasChanged(); }; - } - }; - await base.OnInitializedAsync(); - } - - //debounce StateHasChanged, we dont want to reredner on every key stroke - - private CancellationTokenSource _debounceCts = new CancellationTokenSource(); - - private async Task DebouncedStateHasChanged() { - _debounceCts.Cancel(); - _debounceCts = new CancellationTokenSource(); - try { - await Task.Delay(100, _debounceCts.Token); - Console.WriteLine("DebouncedStateHasChanged - Calling StateHasChanged!"); - StateHasChanged(); - } - catch (TaskCanceledException) { } - } - -} \ No newline at end of file diff --git a/MatrixUtils.Web/Pages/Rooms/Index2Components/RoomsIndex2DMsTab.razor b/MatrixUtils.Web/Pages/Rooms/Index2Components/RoomsIndex2DMsTab.razor deleted file mode 100644 index f4cf849..0000000 --- a/MatrixUtils.Web/Pages/Rooms/Index2Components/RoomsIndex2DMsTab.razor +++ /dev/null @@ -1,53 +0,0 @@ -@using MatrixUtils.Abstractions -@using System.Security.Cryptography -@using ArcaneLibs.Extensions -<h3>RoomsIndex2MainTab</h3> - -<div> - <div class="row"> - <div class="col-3" style="background-color: #ffffff66;"> - <LinkButton>Uncategorised rooms</LinkButton> - @foreach (var space in Data.Rooms.Where(x => x.RoomType == "m.space")) { - <div style="@("width: 100%; height: 50px; background-color: #" + RandomNumberGenerator.GetBytes(3).Append((byte)0x11).ToArray().AsHexString().Replace(" ",""))"> - <p>@space.RoomName</p> - </div> - } - </div> - <div class="col-9" style="background-color: #ff00ff66;"> - <p>omae wa mou shindeiru</p> - </div> - </div> -</div> - -@code { - - [CascadingParameter] - public Index2.RoomListViewData Data { get; set; } = null!; - - protected override async Task OnInitializedAsync() { - Data.Rooms.CollectionChanged += (sender, args) => { - DebouncedStateHasChanged(); - if (args.NewItems is { Count: > 0 }) - foreach (var newItem in args.NewItems) { - (newItem as RoomInfo).PropertyChanged += (sender, args) => { DebouncedStateHasChanged(); }; - } - }; - await base.OnInitializedAsync(); - } - - //debounce StateHasChanged, we dont want to reredner on every key stroke - - private CancellationTokenSource _debounceCts = new CancellationTokenSource(); - - private async Task DebouncedStateHasChanged() { - _debounceCts.Cancel(); - _debounceCts = new CancellationTokenSource(); - try { - await Task.Delay(100, _debounceCts.Token); - Console.WriteLine("DebouncedStateHasChanged - Calling StateHasChanged!"); - StateHasChanged(); - } - catch (TaskCanceledException) { } - } - -} \ No newline at end of file diff --git a/MatrixUtils.Web/Pages/Rooms/Index2Components/RoomsIndex2MainTab.razor b/MatrixUtils.Web/Pages/Rooms/Index2Components/RoomsIndex2MainTab.razor deleted file mode 100644 index b163a52..0000000 --- a/MatrixUtils.Web/Pages/Rooms/Index2Components/RoomsIndex2MainTab.razor +++ /dev/null @@ -1,210 +0,0 @@ -@using MatrixUtils.Abstractions -@using System.Security.Cryptography -@using ArcaneLibs.Extensions -@using System.ComponentModel -@using System.Diagnostics -@using LibMatrix.EventTypes.Spec.State -@using MatrixUtils.Web.Pages.Rooms.Index2Components.MainTabComponents -@using Microsoft.AspNetCore.Components.Rendering -<h3>RoomsIndex2MainTab</h3> - -@* <div> *@ -@* <div class="row"> *@ -@* <div class="col-3" style="background-color: #ffffff66;"> *@ -@* <LinkButton>Uncategorised rooms</LinkButton> *@ -@* @foreach (var space in GetTopLevelSpaces()) { *@ -@* <a style="@("display:block; width: 100%; height: 50px; background-color: #" + RandomNumberGenerator.GetBytes(3).Append((byte)0x11).ToArray().AsHexString().Replace(" ", ""))"> *@ -@* <div style="vertical-align: middle;"> *@ -@* <div style="overflow:hidden; text-overflow: ellipsis; white-space: nowrap; ">@space.RoomName</div> *@ -@* </div> *@ -@* </a> *@ -@* } *@ -@* </div> *@ -@* <div class="col-9" style="background-color: #ff00ff66;"> *@ -@* <p>Placeholder for rooms list...</p> *@ -@* </div> *@ -@* </div> *@ -@* </div> *@ - -<div> - <div class="row"> - <div class="col-3" style="background-color: #ffffff22;"> - <LinkButton>Uncategorised rooms</LinkButton> - @foreach (var space in GetTopLevelSpaces()) { - @* @RecursingSpaceChildren(space) *@ - <MainTabSpaceItem Space="space" OpenedSpaces="OpenedSpaces" @bind-SelectedSpace="SelectedSpace" /> - } - </div> - <div class="col-9" style="background-color: #ff00ff66;"> - <p>Placeholder for rooms list...</p> - @if (SelectedSpace != null) { - foreach (var room in GetSpaceChildRooms(SelectedSpace)) { - <p>@room.RoomName</p> - } - } - </div> - </div> -</div> - - -@code { - - [CascadingParameter] - public Index2.RoomListViewData Data { get; set; } = null!; - - protected override async Task OnInitializedAsync() { - Data.Rooms.CollectionChanged += (sender, args) => { - DebouncedStateHasChanged(); - if (args.NewItems is { Count: > 0 }) - foreach (var newItem in args.NewItems) { - (newItem as RoomInfo).PropertyChanged += OnRoomListChanged; - (newItem as RoomInfo).StateEvents.CollectionChanged += (sender, args) => { DebouncedStateHasChanged(); }; - } - }; - foreach (var newItem in Data.Rooms) { - newItem.PropertyChanged += OnRoomListChanged; - newItem.StateEvents.CollectionChanged += (sender, args) => { DebouncedStateHasChanged(); }; - } - - await base.OnInitializedAsync(); - StateHasChanged(); - } - - private void OnRoomListChanged(object? sender, PropertyChangedEventArgs e) { - if (e.PropertyName == "RoomName" || e.PropertyName == "RoomType") - DebouncedStateHasChanged(); - } - - private CancellationTokenSource _debounceCts = new CancellationTokenSource(); - - private async Task DebouncedStateHasChanged() { - _debounceCts.Cancel(); - _debounceCts = new CancellationTokenSource(); - try { - Console.WriteLine("DebouncedStateHasChanged - Waiting 50ms..."); - await Task.Delay(50, _debounceCts.Token); - Console.WriteLine("DebouncedStateHasChanged - Calling StateHasChanged!"); - StateHasChanged(); - } - catch (TaskCanceledException) { } - } - - private List<RoomInfo> GetTopLevelSpaces() { - var spaces = Data.Rooms.Where(x => x.RoomType == "m.space").OrderBy(x => x.RoomName).ToList(); - var allSpaceChildEvents = spaces.SelectMany(x => x.StateEvents.Where(y => - y.Type == SpaceChildEventContent.EventId && - y.RawContent!.Count > 0 - )).ToList(); - - Console.WriteLine($"Child count: {allSpaceChildEvents.Count}"); - - spaces.RemoveAll(x => allSpaceChildEvents.Any(y => y.StateKey == x.Room.RoomId)); - - if (allSpaceChildEvents.Count == 0) { - Console.WriteLine("No space children found, returning nothing..."); - return []; - } - - return spaces.ToList(); - } - - private List<RoomInfo> GetSpaceChildren(RoomInfo space) { - var childEvents = space.StateEvents.Where(x => - x.Type == SpaceChildEventContent.EventId && - x.RawContent!.Count > 0 - ).ToList(); - var children = childEvents.Select(x => Data.Rooms.FirstOrDefault(y => y.Room.RoomId == x.StateKey)).Where(x => x is not null).ToList(); - return children; - } - - private List<RoomInfo> GetSpaceChildSpaces(RoomInfo space) { - var children = GetSpaceChildren(space); - var childSpaces = children.Where(x => x.RoomType == "m.space").ToList(); - return childSpaces; - } - - private List<RoomInfo> GetSpaceChildRooms(RoomInfo space) { - var children = GetSpaceChildren(space); - var childRooms = children.Where(x => x.RoomType != "m.space").ToList(); - return childRooms; - } - - private RoomInfo? SelectedSpace { get; set; } - private List<RoomInfo> OpenedSpaces { get; set; } = new List<RoomInfo>(); - - // private RenderFragment RecursingSpaceChildren(RoomInfo space, List<RoomInfo>? parents = null, int depth = 0) { - // parents ??= []; - // var totalSw = Stopwatch.StartNew(); - // var children = GetSpaceChildSpaces(space); - // - // var randomColor = RandomNumberGenerator.GetBytes(3).Append((byte)0x33).ToArray().AsHexString().Replace(" ", ""); - // var isExpanded = OpenedSpaces.Contains(space); - // - // // Console.WriteLine($"RecursingSpaceChildren::FetchData - Depth: {depth}, Space: {space.RoomName}, Children: {children.Count} - {totalSw.Elapsed}"); - // - // // var renderSw = Stopwatch.StartNew(); - // var rf = new RenderFragment(builder => { - // builder.OpenElement(0, "div"); - // //space list entry render fragment - // // builder.AddContent(1, SpaceListEntry(space)); - // builder.OpenComponent<MainTabSpaceItem>(1); - // builder.AddAttribute(2, "Space", space); - // builder.AddAttribute(2, "OpenedSpaces", OpenedSpaces); - // builder.CloseComponent(); - // builder.CloseElement(); - // //space children render fragment - // if (isExpanded) { - // builder.OpenElement(2, "div"); - // builder.AddAttribute(3, "style", "padding-left: 10px;"); - // foreach (var child in children) { - // builder.AddContent(4, RecursingSpaceChildren(child, parents.Append(space).ToList(), depth + 1)); - // } - // - // builder.CloseElement(); - // } - // }); - // - // // Console.WriteLine($"RecursingSpaceChildren::Render - Depth: {depth}, Space: {space.RoomName}, Children: {children.Count} - {renderSw.Elapsed}"); - // if (totalSw.ElapsedMilliseconds > 20) - // Console.WriteLine($"RecursingSpaceChildren::Total - Depth: {depth}, Space: {space.RoomName}, Children: {children.Count} - {totalSw.Elapsed}"); - // // Console.WriteLine($"RecursingSpaceChildren::Total - Depth: {depth}, Space: {space.RoomName}, Children: {children.Count} - {totalSw.Elapsed}"); - // return rf; - // } - - // private RenderFragment SpaceListEntry(RoomInfo space) { - // return builder => { - // { - // builder.OpenElement(0, "div"); - // builder.AddAttribute(1, "style", "display: block; width: 100%; height: 50px;"); - // builder.AddAttribute(2, "onclick", EventCallback.Factory.Create(this, () => { - // if (OpenedSpaces.Contains(space)) { - // OpenedSpaces.Remove(space); - // } - // else { - // OpenedSpaces.Add(space); - // } - // - // StateHasChanged(); - // })); - // { - // builder.OpenComponent<MxcImage>(5); - // builder.AddAttribute(6, "Homeserver", Data.Homeserver); - // builder.AddAttribute(7, "MxcUri", space.RoomIcon); - // builder.AddAttribute(8, "Circular", true); - // builder.AddAttribute(9, "Width", 32); - // builder.AddAttribute(10, "Height", 32); - // builder.CloseComponent(); - // } - // { - // // room name, ellipsized - // builder.OpenElement(11, "span"); - // builder.AddAttribute(12, "class", "spaceNameEllipsis"); - // builder.AddContent(13, space.RoomName); - // builder.CloseElement(); - // } - // builder.CloseElement(); - // } - // }; - // } - -} \ No newline at end of file diff --git a/MatrixUtils.Web/Pages/Rooms/Index2Components/RoomsIndex2MainTab.razor.css b/MatrixUtils.Web/Pages/Rooms/Index2Components/RoomsIndex2MainTab.razor.css deleted file mode 100644 index e69de29..0000000 --- a/MatrixUtils.Web/Pages/Rooms/Index2Components/RoomsIndex2MainTab.razor.css +++ /dev/null diff --git a/MatrixUtils.Web/Pages/Rooms/Index2Components/RoomsIndex2SyncContainer.razor b/MatrixUtils.Web/Pages/Rooms/Index2Components/RoomsIndex2SyncContainer.razor deleted file mode 100644 index 418ee02..0000000 --- a/MatrixUtils.Web/Pages/Rooms/Index2Components/RoomsIndex2SyncContainer.razor +++ /dev/null @@ -1,202 +0,0 @@ -@using LibMatrix.Helpers -@using LibMatrix.Responses -@using MatrixUtils.Abstractions -@using System.Diagnostics -@using System.Diagnostics.CodeAnalysis -@using LibMatrix.EventTypes.Spec.State -@using LibMatrix.Extensions -@using LibMatrix.Utilities -@using System.Collections.ObjectModel -@using ArcaneLibs -@inject ILogger<RoomsIndex2SyncContainer> logger -<pre>RoomsIndex2SyncContainer</pre> -@foreach (var (name, value) in _statusList) { - <pre>[@name] @value.Status</pre> -} - -@code { - - [Parameter] - public Index2.RoomListViewData Data { get; set; } = null!; - - private SyncHelper syncHelper; - - private Queue<KeyValuePair<string, SyncResponse.RoomsDataStructure.JoinedRoomDataStructure>> queue = new(); - - private ObservableCollection<(string name, ObservableStatus value)> _statusList = new(); - - protected override async Task OnInitializedAsync() { - _statusList.CollectionChanged += (sender, args) => { - StateHasChanged(); - if (args.NewItems is { Count: > 0 }) - foreach (var item in args.NewItems) { - if (item is not (string name, ObservableStatus value)) continue; - value.PropertyChanged += (sender, args) => { - if(value.Show) StateHasChanged(); - }; - } - }; - - while (Data.Homeserver is null) { - await Task.Delay(100); - } - - await SetUpSync(); - } - - private async Task SetUpSync() { - var status = await GetOrAddStatus("Main"); - var syncHelpers = new Dictionary<string, SyncHelper>() { - ["Main"] = new SyncHelper(Data.Homeserver, logger) { - Timeout = 30000, - FilterId = await Data.Homeserver.NamedCaches.FilterCache.GetOrSetValueAsync(CommonSyncFilters.GetBasicRoomInfo), - // MinimumDelay = TimeSpan.FromMilliseconds(5000) - } - }; - status.Status = "Initial sync... Checking server filter capability..."; - var syncRes = await syncHelpers["Main"].SyncAsync(); - if (!syncRes.Rooms?.Join?.Any(x => x.Value.State?.Events?.Any(y => y.Type == SpaceChildEventContent.EventId) ?? false) ?? true) { - status.Status = "Initial sync indicates that server supports filters, starting helpers!"; - syncHelpers.Add("SpaceRelations", new SyncHelper(Data.Homeserver, logger) { - Timeout = 30000, - FilterId = await Data.Homeserver.NamedCaches.FilterCache.GetOrSetValueAsync(CommonSyncFilters.GetSpaceRelations), - // MinimumDelay = TimeSpan.FromMilliseconds(5000) - }); - - syncHelpers.Add("Profile", new SyncHelper(Data.Homeserver, logger) { - Timeout = 30000, - FilterId = await Data.Homeserver.NamedCaches.FilterCache.GetOrSetValueAsync(CommonSyncFilters.GetOwnMemberEvents), - // MinimumDelay = TimeSpan.FromMilliseconds(5000) - }); - } - else status.Status = "Initial sync indicates that server does not support filters, continuing without extra filters!"; - - await HandleSyncResponse(syncRes); - - // profileSyncHelper = new SyncHelper(Homeserver, logger) { - // Timeout = 10000, - // Filter = profileUpdateFilter, - // MinimumDelay = TimeSpan.FromMilliseconds(5000) - // }; - // profileUpdateFilter.Room.State.Senders.Add(Homeserver.WhoAmI.UserId); - RunQueueProcessor(); - foreach (var helper in syncHelpers) { - Console.WriteLine($"Starting sync loop for {helper.Key}"); - RunSyncLoop(helper.Value, helper.Key); - } - } - - private async Task RunQueueProcessor() { - var status = await GetOrAddStatus("QueueProcessor"); - var statusd = await GetOrAddStatus("QueueProcessor/D", show: false); - while (true) { - await Task.Delay(1000); - try { - var renderTimeSw = Stopwatch.StartNew(); - while (queue.Count == 0) { - var delay = 1000; - Console.WriteLine("Queue is empty, waiting..."); - // Status2 = $"Queue is empty, waiting for {delay}ms..."; - await Task.Delay(delay); - } - - status.Status = $"Queue no longer empty after {renderTimeSw.Elapsed}!"; - renderTimeSw.Restart(); - - int maxUpdates = 5000; - while (maxUpdates-- > 0 && queue.TryDequeue(out var queueEntry)) { - var (roomId, roomData) = queueEntry; - statusd.Status = $"Dequeued room {roomId}"; - RoomInfo room; - - if (Data.Rooms.Any(x => x.Room.RoomId == roomId)) { - room = Data.Rooms.First(x => x.Room.RoomId == roomId); - statusd.Status = $"{roomId} already known with {room.StateEvents?.Count ?? 0} state events"; - } - else { - statusd.Status = $"Eencountered new room {roomId}!"; - room = new RoomInfo(Data.Homeserver!.GetRoom(roomId), roomData.State?.Events); - Data.Rooms.Add(room); - } - - if (roomData.State?.Events is { Count: > 0 }) - room.StateEvents!.MergeStateEventLists(roomData.State.Events); - else { - statusd.Status = $"Could not merge state for {room.Room.RoomId} as new data contains no state events!"; - } - - // await Task.Delay(10); - } - - status.Status = $"Got {Data.Rooms.Count} rooms so far! {queue.Count} entries left in processing queue... Parsed last response in {renderTimeSw.Elapsed}"; - - // RenderContents |= queue.Count == 0; - // await Task.Delay(Data.Rooms.Count); - } - catch (Exception e) { - Console.WriteLine("QueueWorker exception: " + e); - } - } - } - - private async Task RunSyncLoop(SyncHelper syncHelper, string name = "Unknown") { - var status = await GetOrAddStatus($"SYNC/{name}"); - status.Status = $"Initial syncing..."; - - var syncs = syncHelper.EnumerateSyncAsync(); - await foreach (var sync in syncs) { - var sw = Stopwatch.StartNew(); - status.Status = $"[{DateTime.Now}] Got {Data.Rooms.Count} rooms so far! {sync.Rooms?.Join?.Count ?? 0} new updates!"; - - await HandleSyncResponse(sync); - status.Status += $"\nProcessed sync in {sw.ElapsedMilliseconds}ms, queue length: {queue.Count}"; - } - } - - private async Task HandleSyncResponse(SyncResponse? sync) { - if (sync?.Rooms?.Join is { Count: > 0 }) - foreach (var joinedRoom in sync.Rooms.Join) - queue.Enqueue(joinedRoom); - - if (sync.Rooms.Leave is { Count: > 0 }) - foreach (var leftRoom in sync.Rooms.Leave) - if (Data.Rooms.Any(x => x.Room.RoomId == leftRoom.Key)) - Data.Rooms.Remove(Data.Rooms.First(x => x.Room.RoomId == leftRoom.Key)); - } - - private SemaphoreSlim _syncLock = new(1, 1); - - private async Task<ObservableStatus> GetOrAddStatus(string name, bool show = true, bool log = true) { - await _syncLock.WaitAsync(); - try { - if (_statusList.Any(x => x.name == name)) - return _statusList.First(x => x.name == name).value; - var status = new ObservableStatus() { - Name = name, - Log = log, - Show = show - }; - _statusList.Add((name, status)); - return status; - } - finally { - _syncLock.Release(); - } - } - - private class ObservableStatus : NotifyPropertyChanged { - private string _status = "Initialising..."; - public string Name { get; set; } = "Unknown"; - public bool Show { get; set; } = true; - public bool Log { get; set; } = true; - - public string Status { - get => _status; - set { - if(SetField(ref _status, value) && Log) - Console.WriteLine($"[{Name}]: {value}"); - } - } - } - -} \ No newline at end of file |