@page "/expand/{statusId}" @attribute [Authorize] @inherits LocalizableComponentBase @Localizer["Thread"] @* A post with its thread (/api/v1/statuses/{id}/context): the posts it answers above, the post, the answers below. The cards do their own actions; a reply or a deletion updates the thread here. *@

@Localizer["Thread"]

@if (IsLoading) {

@Localizer["loading"]

} else if (current is null) {

@Localizer["This message doesn't exist."]

} else { @foreach (var post in ancestors) { } @foreach (var post in descendants) { } }
@code { [Inject] StatusService StatusService { get; set; } [Inject] InstanceService InstanceService { get; set; } [Inject] ILocalStorageService LocalStorage { get; set; } [Inject] IJSRuntime JS { get; set; } [Parameter] public string StatusId { get; set; } FeedPost current; List ancestors = []; List descendants = []; string loadedId; protected override async Task OnParametersSetAsync() { if (StatusId == loadedId) return; loadedId = StatusId; if (CascadingState.IsOffline) { WhenOnline(LoadData); StartOnlinePolling(); IsLoading = false; return; } await LoadData(); } async Task LoadData() { IsLoading = true; var status = await StatusService.Get(StatusId); if (status is null) { current = null; IsLoading = false; return; } var context = await StatusService.Context(status.Id); current = FeedPost.Of(status); ancestors = [.. (context?.Ancestors ?? []).Select(FeedPost.Of)]; descendants = [.. (context?.Descendants ?? []).Select(FeedPost.Of)]; IsLoading = false; var all = ancestors.Append(current).Concat(descendants).ToList(); await InstanceService.Resolve(all.Select(p => p.Host).Append(InstanceService.SelfHost)); InstanceService.Locate(all); } void Remove(FeedPost post) { if (post.Key == current?.Key) { current = null; return; } ancestors.RemoveAll(p => p.Key == post.Key); descendants.RemoveAll(p => p.Key == post.Key); } async Task Replied(FeedPost reply) { if (reply is null) return; descendants.Add(reply); await InstanceService.Resolve([reply.Host]); InstanceService.Locate([reply]); } async Task OpenTag(string tag) { var filter = await LocalStorage.GetItemAsync(nameof(FeedFilter)) ?? new(); filter.Tag = tag; filter.TimelineType = TimelineType.Tag; await LocalStorage.SetItemAsync(nameof(FeedFilter), filter); Navigation.NavigateTo(""); } async Task Back() => await JS.InvokeVoidAsync("history.back"); }