From 03fc824d3419b7034bc8fafeeffaf85ac314bb06 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Sat, 29 Jun 2024 00:46:47 +0200 Subject: [PATCH] [frontend] Code cleanup --- .../Components/AscendedNote.razor | 1 + Iceshrimp.Frontend/Components/Compose.razor | 43 ++- Iceshrimp.Frontend/Components/LazyNote.razor | 54 +-- .../Components/Note/NoteComponent.razor | 4 +- .../Components/Note/NoteFooter.razor | 8 +- .../Components/NotificationComponent.razor | 1 + .../Components/NotificationList.razor | 7 +- .../Components/NotificationList.razor.cs | 125 +++---- .../Components/RecursiveNote.razor | 1 + .../Components/TimelineNote.razor | 1 + .../Components/VirtualScroller.razor | 73 ++-- .../Core/Miscellaneous/RenderMfm.cs | 330 +++++++++--------- .../Core/Services/ComposeService.cs | 1 - Iceshrimp.Frontend/Pages/ProfileView.razor | 13 +- Iceshrimp.Frontend/Pages/SingleNote.razor | 6 +- Iceshrimp.NET.sln.DotSettings | 1 + 16 files changed, 341 insertions(+), 328 deletions(-) diff --git a/Iceshrimp.Frontend/Components/AscendedNote.razor b/Iceshrimp.Frontend/Components/AscendedNote.razor index 376fa025..cd98bad0 100644 --- a/Iceshrimp.Frontend/Components/AscendedNote.razor +++ b/Iceshrimp.Frontend/Components/AscendedNote.razor @@ -1,4 +1,5 @@ @using Iceshrimp.Shared.Schemas +@* ReSharper disable once RedundantUsingDirective *@ @using Iceshrimp.Frontend.Components.Note @inject NavigationManager NavigationManager
diff --git a/Iceshrimp.Frontend/Components/Compose.razor b/Iceshrimp.Frontend/Components/Compose.razor index e620e2ea..075b0fe9 100644 --- a/Iceshrimp.Frontend/Components/Compose.razor +++ b/Iceshrimp.Frontend/Components/Compose.razor @@ -1,4 +1,3 @@ -@using AngleSharp.Dom @using Iceshrimp.Assets.PhosphorIcons @using Iceshrimp.Frontend.Core.Services @using Iceshrimp.Shared.Schemas @@ -9,15 +8,17 @@ @inject IJSRuntime Js @inject ApiService ApiService @inject ComposeService ComposeService +@inject SessionService SessionService @inject IStringLocalizer Loc; -@inject SessionService SessionService
- +
@if (ReplyOrQuote != null) { @@ -57,18 +58,19 @@ private string? TextPlaceholder { get; set; } private EmojiPicker EmojiPicker { get; set; } = null!; private ElementReference Textarea { get; set; } - private NoteCreateRequest NoteDraft { get; set; } = new NoteCreateRequest + + private NoteCreateRequest NoteDraft { get; set; } = new NoteCreateRequest { Text = "", Visibility = NoteVisibility.Followers, // FIXME: Default to visibilty in settings Cw = null }; + private Dictionary AvailablePlaceholders { get; set; } = new() { { "default", "What's on your mind?" }, { "reply", "Reply goes here!" }, - { "quote", "Quote this post!" } - + { "quote", "Quote this post!" } }; RenderFragment DropdownIcon(NoteVisibility vis) @@ -99,7 +101,12 @@ { return Enum.GetValues() .Select(vis => - new DropdownElement { Icon = DropdownIcon(vis), Content = DropdownContent(vis), Selection = vis }) + new DropdownElement + { + Icon = DropdownIcon(vis), + Content = DropdownContent(vis), + Selection = vis + }) .ToList(); } @@ -124,6 +131,7 @@ { NoteDraft.Text += $"@{el} "; } + StateHasChanged(); } else if (quote != null) @@ -149,14 +157,15 @@ List mentions = []; if (noteBase.User.Id != SessionService.Current!.Id) { - var userMention = noteBase.User.Username; if (noteBase.User.Host != null) { userMention += $"@{noteBase.User.Host}"; } + mentions.Add(userMention); } + var current = $"@{SessionService.Current.Username}@{SessionService.Current.Host}"; var mfmNodes = Mfm.parse(noteBase.Text); foreach (var node in mfmNodes) @@ -166,6 +175,7 @@ mentions.Add(mentionNode.Acct); } } + mentions = mentions.Distinct().ToList(); mentions.Remove(current); return mentions; @@ -173,9 +183,14 @@ private void ResetState() { - ReplyOrQuote = null; - Attachments = new List(); - NoteDraft = new NoteCreateRequest { Text = "", Visibility = NoteVisibility.Followers, Cw = null }; + ReplyOrQuote = null; + Attachments = new List(); + NoteDraft = new NoteCreateRequest + { + Text = "", + Visibility = NoteVisibility.Followers, + Cw = null + }; TextPlaceholder = AvailablePlaceholders["default"]; } @@ -220,15 +235,13 @@ private void ToggleEmojiPicker() { EmojiPicker.Toggle(); - Console.WriteLine("showing picker"); StateHasChanged(); } - private async Task AddEmoji(EmojiResponse emoji) { - var pos = await _module.InvokeAsync("getSelectionStart"); - var text = NoteDraft.Text; + var pos = await _module.InvokeAsync("getSelectionStart"); + var text = NoteDraft.Text; var emojiString = $":{emoji.Name}"; NoteDraft.Text = text.Insert(pos, emojiString); StateHasChanged(); diff --git a/Iceshrimp.Frontend/Components/LazyNote.razor b/Iceshrimp.Frontend/Components/LazyNote.razor index 379048f1..16c298a1 100644 --- a/Iceshrimp.Frontend/Components/LazyNote.razor +++ b/Iceshrimp.Frontend/Components/LazyNote.razor @@ -3,38 +3,41 @@ @using Ljbc1994.Blazor.IntersectionObserver.API @using Ljbc1994.Blazor.IntersectionObserver.Components @inject IJSRuntime Js -@if(_init) // FIXME: We need to wait for the Component to render once before initializing the Intersection Observer. - // With the Component this is AFAIK only possible by not rendering it until then. - // The proper fix for this is to change to the Service Pattern. - // But that requires the IntersectionObserver Library to be modified to return what element an observation update is for. -{ - -
- @if (_isIntersecting) - { - - }else { -
- } -
-
+@if (_init) // FIXME: We need to wait for the Component to render once before initializing the Intersection Observer. + // With the Component this is AFAIK only possible by not rendering it until then. + // The proper fix for this is to change to the Service Pattern. + // But that requires the IntersectionObserver Library to be modified to return what element an observation update is for. +{ + +
+ @if (_isIntersecting) + { + + } + else + { +
+ } +
+
} + @code { - [Parameter][EditorRequired] public required NoteResponse Note { get; set; } - [Parameter][EditorRequired] public ElementReference Scroller { get; set; } - private IJSObjectReference? _module; - private int? Height { get; set; } = null; - private bool _isIntersecting = true; - private string margin = "200%"; - private bool _init = false; + [Parameter] [EditorRequired] public required NoteResponse Note { get; set; } + [Parameter] [EditorRequired] public ElementReference Scroller { get; set; } + + private const string Margin = "200%"; + private IJSObjectReference? _module; + private int? Height { get; set; } + private bool _isIntersecting = true; + private bool _init; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { _module = await Js.InvokeAsync("import", - "./Components/LazyNote.razor.js"); - + "./Components/LazyNote.razor.js"); } } @@ -44,10 +47,9 @@ { _init = true; } - } - private async Task Change (IntersectionObserverEntry entry) + private async Task Change(IntersectionObserverEntry entry) { if (entry.IsIntersecting == false) { diff --git a/Iceshrimp.Frontend/Components/Note/NoteComponent.razor b/Iceshrimp.Frontend/Components/Note/NoteComponent.razor index 8739212d..83d5bc33 100644 --- a/Iceshrimp.Frontend/Components/Note/NoteComponent.razor +++ b/Iceshrimp.Frontend/Components/Note/NoteComponent.razor @@ -1,4 +1,3 @@ -@using AngleSharp.Dom @using Iceshrimp.Frontend.Core.Services @using Iceshrimp.Shared.Schemas @inject ApiService ApiService; @@ -79,7 +78,6 @@ Note.Reactions[index].Count++; } - break; } @@ -121,7 +119,7 @@ public void Reply() { - ComposeService.ComposeDialog?.OpenDialog(Note, null); + ComposeService.ComposeDialog?.OpenDialog(Note); } public void Renote() diff --git a/Iceshrimp.Frontend/Components/Note/NoteFooter.razor b/Iceshrimp.Frontend/Components/Note/NoteFooter.razor index 09fafe36..2b5fcc14 100644 --- a/Iceshrimp.Frontend/Components/Note/NoteFooter.razor +++ b/Iceshrimp.Frontend/Components/Note/NoteFooter.razor @@ -1,5 +1,4 @@ @using Iceshrimp.Assets.PhosphorIcons -@using Iceshrimp.Frontend.Core.Services @using Iceshrimp.Shared.Schemas +
+ The end! +
}
@@ -53,10 +53,10 @@ private bool _overscrollBottom = false; private ElementReference _padTopRef; private ElementReference _padBotRef; - private ElementReference Scroller; - private bool _loadingTop = false; - private bool loadingBottom = false; - public bool setScroll = false; + private ElementReference _scroller; + private bool _loadingTop = false; + private bool _loadingBottom = false; + private bool _setScroll = false; private ElementReference Ref { @@ -68,18 +68,15 @@ private void InitialRender(string? id) { - var a = new List(); - a = NoteResponseList.Count < _count ? NoteResponseList : NoteResponseList.GetRange(0, _count); - - State.RenderedList = a; + State.RenderedList = NoteResponseList.Count < _count ? NoteResponseList : NoteResponseList.GetRange(0, _count); } private async Task LoadOlder() { - loadingBottom = true; + _loadingBottom = true; StateHasChanged(); await ReachedEnd.InvokeAsync(); - loadingBottom = false; + _loadingBottom = false; StateHasChanged(); } @@ -98,7 +95,6 @@ StateService.VirtualScroller.SetState("home", State); } - private async Task RemoveAbove(int amount) { for (int i = 0; i < amount; i++) @@ -109,7 +105,6 @@ } State.RenderedList.RemoveRange(0, amount); - } private async Task Down() @@ -128,10 +123,8 @@ var heightChange = 0; foreach (var el in a) { - if (State.Height.ContainsKey(el.Id)) - { - heightChange += State.Height[el.Id]; - } + if (State.Height.TryGetValue(el.Id, out var value)) + heightChange += value; } if (State.PadBottom > 0) State.PadBottom -= heightChange; @@ -155,6 +148,7 @@ State.PadBottom += height; State.Height[State.RenderedList[i].Id] = height; } + var index = NoteResponseList.IndexOf(State.RenderedList.First()); var a = NoteResponseList.GetRange(index - updateCount, updateCount); var heightChange = 0; @@ -174,8 +168,6 @@ private async Task SetupObservers() { - // Enabling root margin causes erratic virtual scroller behavior, i've not figured out why - var options = new IntersectionObserverOptions { RootMargin = "100%" }; OvrscrlObsvTop = await ObserverService.Create(OverscrollCallbackTop); OvrscrlObsvBottom = await ObserverService.Create(OverscrollCallbackBottom); @@ -192,7 +184,6 @@ } } - private async void OverscrollCallbackTop(IList list) { var entry = list.First(); @@ -242,13 +233,13 @@ private async Task GetScrollTop() { - var scrollTop = await Module.InvokeAsync("GetScrollTop", Scroller); + var scrollTop = await Module.InvokeAsync("GetScrollTop", _scroller); State.ScrollTop = scrollTop; } private async Task SetScrollTop() { - await Module.InvokeVoidAsync("SetScrollTop", State.ScrollTop, Scroller); + await Module.InvokeVoidAsync("SetScrollTop", State.ScrollTop, _scroller); } protected override void OnInitialized() @@ -256,9 +247,8 @@ try { var virtualScrollerState = StateService.VirtualScroller.GetState("home"); - State = virtualScrollerState; - setScroll = true; - + State = virtualScrollerState; + _setScroll = true; } catch (ArgumentException) { @@ -279,13 +269,12 @@ await SetupObservers(); } - if (setScroll) + if (_setScroll) { await SetScrollTop(); - setScroll = false; + _setScroll = false; } await SaveState(); } - } \ No newline at end of file diff --git a/Iceshrimp.Frontend/Core/Miscellaneous/RenderMfm.cs b/Iceshrimp.Frontend/Core/Miscellaneous/RenderMfm.cs index 6174dda2..22e00db9 100644 --- a/Iceshrimp.Frontend/Core/Miscellaneous/RenderMfm.cs +++ b/Iceshrimp.Frontend/Core/Miscellaneous/RenderMfm.cs @@ -3,176 +3,188 @@ using AngleSharp.Dom; using Iceshrimp.Parsing; using Iceshrimp.Shared.Schemas; using Microsoft.AspNetCore.Components; -using Microsoft.FSharp.Core; namespace Iceshrimp.Frontend.Core.Miscellaneous; -public class MfmRenderer +public static class MfmRenderer { - public static async Task RenderString(string text, List emoji) - { - var res = Mfm.parse(text); - var context = BrowsingContext.New(); - var document = await context.OpenNewAsync(); - var renderedMfm = MfmRenderer.RenderMultipleNodes(res, document, emoji); - var html = renderedMfm.ToHtml(); - return new MarkupString(html); - } - public static INode RenderMultipleNodes(IEnumerable nodes, IDocument document, List emoji) - { - var el = document.CreateElement("span"); - el.SetAttribute("mfm", "mfm"); - el.ClassName = "mfm"; - foreach (var node in nodes) - { - try - { - el.AppendNodes(RenderNode(node, document, emoji)); - } - catch (NotImplementedException e) - { - var fallback = document.CreateElement("span"); - fallback.TextContent = $"[Node type <{e.Message}> not implemented]"; - el.AppendNodes(fallback); - } - } + public static async Task RenderString(string text, List emoji) + { + var res = Mfm.parse(text); + var context = BrowsingContext.New(); + var document = await context.OpenNewAsync(); + var renderedMfm = RenderMultipleNodes(res, document, emoji); + var html = renderedMfm.ToHtml(); + return new MarkupString(html); + } - return el; - } - private static INode RenderNode(MfmNodeTypes.MfmNode node, IDocument document, List emoji) - { - var rendered = node switch - { - MfmNodeTypes.MfmCenterNode mfmCenterNode => throw new NotImplementedException($"{mfmCenterNode.GetType()}"), - MfmNodeTypes.MfmCodeBlockNode mfmCodeBlockNode => MfmCodeBlockNode(mfmCodeBlockNode, document), - MfmNodeTypes.MfmMathBlockNode mfmMathBlockNode => throw new NotImplementedException($"{mfmMathBlockNode.GetType()}"), - MfmNodeTypes.MfmQuoteNode mfmQuoteNode => throw new NotImplementedException($"{mfmQuoteNode.GetType()}"), - MfmNodeTypes.MfmSearchNode mfmSearchNode => throw new NotImplementedException($"{mfmSearchNode.GetType()}"), - MfmNodeTypes.MfmBlockNode mfmBlockNode => throw new NotImplementedException($"{mfmBlockNode.GetType()}"), - MfmNodeTypes.MfmBoldNode mfmBoldNode => MfmBoldNode(mfmBoldNode, document), - MfmNodeTypes.MfmEmojiCodeNode mfmEmojiCodeNode => MfmEmojiCodeNode(mfmEmojiCodeNode, document, emoji), - MfmNodeTypes.MfmFnNode mfmFnNode => throw new NotImplementedException($"{mfmFnNode.GetType()}"), - MfmNodeTypes.MfmHashtagNode mfmHashtagNode => throw new NotImplementedException($"{mfmHashtagNode.GetType()}"), - MfmNodeTypes.MfmInlineCodeNode mfmInlineCodeNode => MfmInlineCodeNode(mfmInlineCodeNode, document), - MfmNodeTypes.MfmItalicNode mfmItalicNode => MfmItalicNode(mfmItalicNode, document), - MfmNodeTypes.MfmLinkNode mfmLinkNode => MfmLinkNode(mfmLinkNode, document), - MfmNodeTypes.MfmMathInlineNode mfmMathInlineNode => throw new NotImplementedException($"{mfmMathInlineNode.GetType()}"), - MfmNodeTypes.MfmMentionNode mfmMentionNode => MfmMentionNode(mfmMentionNode, document), - MfmNodeTypes.MfmPlainNode mfmPlainNode => throw new NotImplementedException($"{mfmPlainNode.GetType()}"), - MfmNodeTypes.MfmSmallNode mfmSmallNode => throw new NotImplementedException($"{mfmSmallNode.GetType()}"), - MfmNodeTypes.MfmStrikeNode mfmStrikeNode => throw new NotImplementedException($"{mfmStrikeNode.GetType()}"), - MfmNodeTypes.MfmTextNode mfmTextNode => MfmTextNode(mfmTextNode, document), - MfmNodeTypes.MfmUrlNode mfmUrlNode => MfmUrlNode(mfmUrlNode, document), - MfmNodeTypes.MfmInlineNode mfmInlineNode => throw new NotImplementedException($"{mfmInlineNode.GetType()}"), - _ => throw new ArgumentOutOfRangeException(nameof(node)) - }; - if (node.Children.Length > 0) - { - foreach (var childNode in node.Children) - { - try - { - rendered.AppendNodes(RenderNode(childNode, document, emoji)); - } - catch (NotImplementedException e) - { - var fallback = document.CreateElement("span"); - fallback.TextContent = $"[Node type <{e.Message}> not implemented]"; - rendered.AppendNodes(fallback); - } - } - } - return rendered; - } + private static INode RenderMultipleNodes( + IEnumerable nodes, IDocument document, List emoji + ) + { + var el = document.CreateElement("span"); + el.SetAttribute("mfm", "mfm"); + el.ClassName = "mfm"; + foreach (var node in nodes) + { + try + { + el.AppendNodes(RenderNode(node, document, emoji)); + } + catch (NotImplementedException e) + { + var fallback = document.CreateElement("span"); + fallback.TextContent = $"[Node type <{e.Message}> not implemented]"; + el.AppendNodes(fallback); + } + } - private static INode MfmCodeBlockNode(MfmNodeTypes.MfmCodeBlockNode node, IDocument document) - { - var el = document.CreateElement("pre"); - var childEl = document.CreateElement("code"); - childEl.TextContent = node.Code; - el.AppendChild(childEl); - return el; - } + return el; + } - private static INode MfmInlineCodeNode(MfmNodeTypes.MfmInlineCodeNode node, IDocument document) - { - var el = document.CreateElement("code"); - el.TextContent = node.Code; - return el; - } + private static INode RenderNode(MfmNodeTypes.MfmNode node, IDocument document, List emoji) + { + var rendered = node switch + { + MfmNodeTypes.MfmCenterNode mfmCenterNode => throw new NotImplementedException($"{mfmCenterNode.GetType()}"), + MfmNodeTypes.MfmCodeBlockNode mfmCodeBlockNode => MfmCodeBlockNode(mfmCodeBlockNode, document), + MfmNodeTypes.MfmMathBlockNode mfmMathBlockNode => + throw new NotImplementedException($"{mfmMathBlockNode.GetType()}"), + MfmNodeTypes.MfmQuoteNode mfmQuoteNode => throw new NotImplementedException($"{mfmQuoteNode.GetType()}"), + MfmNodeTypes.MfmSearchNode mfmSearchNode => throw new NotImplementedException($"{mfmSearchNode.GetType()}"), + MfmNodeTypes.MfmBlockNode mfmBlockNode => throw new NotImplementedException($"{mfmBlockNode.GetType()}"), + MfmNodeTypes.MfmBoldNode mfmBoldNode => MfmBoldNode(mfmBoldNode, document), + MfmNodeTypes.MfmEmojiCodeNode mfmEmojiCodeNode => MfmEmojiCodeNode(mfmEmojiCodeNode, document, emoji), + MfmNodeTypes.MfmFnNode mfmFnNode => throw new NotImplementedException($"{mfmFnNode.GetType()}"), + MfmNodeTypes.MfmHashtagNode mfmHashtagNode => + throw new NotImplementedException($"{mfmHashtagNode.GetType()}"), + MfmNodeTypes.MfmInlineCodeNode mfmInlineCodeNode => MfmInlineCodeNode(mfmInlineCodeNode, document), + MfmNodeTypes.MfmItalicNode mfmItalicNode => MfmItalicNode(mfmItalicNode, document), + MfmNodeTypes.MfmLinkNode mfmLinkNode => MfmLinkNode(mfmLinkNode, document), + MfmNodeTypes.MfmMathInlineNode mfmMathInlineNode => + throw new NotImplementedException($"{mfmMathInlineNode.GetType()}"), + MfmNodeTypes.MfmMentionNode mfmMentionNode => MfmMentionNode(mfmMentionNode, document), + MfmNodeTypes.MfmPlainNode mfmPlainNode => throw new NotImplementedException($"{mfmPlainNode.GetType()}"), + MfmNodeTypes.MfmSmallNode mfmSmallNode => throw new NotImplementedException($"{mfmSmallNode.GetType()}"), + MfmNodeTypes.MfmStrikeNode mfmStrikeNode => throw new NotImplementedException($"{mfmStrikeNode.GetType()}"), + MfmNodeTypes.MfmTextNode mfmTextNode => MfmTextNode(mfmTextNode, document), + MfmNodeTypes.MfmUrlNode mfmUrlNode => MfmUrlNode(mfmUrlNode, document), + MfmNodeTypes.MfmInlineNode mfmInlineNode => throw new NotImplementedException($"{mfmInlineNode.GetType()}"), + _ => throw new ArgumentOutOfRangeException(nameof(node)) + }; + if (node.Children.Length > 0) + { + foreach (var childNode in node.Children) + { + try + { + rendered.AppendNodes(RenderNode(childNode, document, emoji)); + } + catch (NotImplementedException e) + { + var fallback = document.CreateElement("span"); + fallback.TextContent = $"[Node type <{e.Message}> not implemented]"; + rendered.AppendNodes(fallback); + } + } + } - private static INode MfmLinkNode(MfmNodeTypes.MfmLinkNode node, IDocument document) - { - var el = document.CreateElement("a"); - el.SetAttribute("href", node.Url); - el.ClassName = "link-node"; - return el; - } + return rendered; + } - private static INode MfmItalicNode(MfmNodeTypes.MfmItalicNode node, IDocument document) - { - var el = document.CreateElement("span"); - el.SetAttribute("style", "font-style: italic"); - return el; - } + private static INode MfmCodeBlockNode(MfmNodeTypes.MfmCodeBlockNode node, IDocument document) + { + var el = document.CreateElement("pre"); + var childEl = document.CreateElement("code"); + childEl.TextContent = node.Code; + el.AppendChild(childEl); + return el; + } - private static INode MfmEmojiCodeNode(MfmNodeTypes.MfmEmojiCodeNode node, IDocument document, List emojiList) - { - var el = document.CreateElement("span"); - el.ClassName = "emoji"; - - var emoji = emojiList.Find(p => p.Name == node.Name); - if (emoji is null) - { - el.TextContent = node.Name; - } - else - { - var image = document.CreateElement("img"); - image.SetAttribute("src", emoji.PublicUrl); - image.SetAttribute("alt", node.Name); - el.AppendChild(image); - } + private static INode MfmInlineCodeNode(MfmNodeTypes.MfmInlineCodeNode node, IDocument document) + { + var el = document.CreateElement("code"); + el.TextContent = node.Code; + return el; + } - return el; - } - private static INode MfmUrlNode(MfmNodeTypes.MfmUrlNode node, IDocument document) - { - var el = document.CreateElement("a"); - el.SetAttribute("href", node.Url); - el.ClassName = "url-node"; - el.TextContent = node.Url; - return el; - } + private static INode MfmLinkNode(MfmNodeTypes.MfmLinkNode node, IDocument document) + { + var el = document.CreateElement("a"); + el.SetAttribute("href", node.Url); + el.ClassName = "link-node"; + return el; + } - private static INode MfmBoldNode(MfmNodeTypes.MfmBoldNode node, IDocument document) - { - var el = document.CreateElement("strong"); - return el; - } - private static INode MfmTextNode(MfmNodeTypes.MfmTextNode node, IDocument document) - { - var el = document.CreateElement("span"); - el.TextContent = node.Text; - return el; - } - private static INode MfmMentionNode(MfmNodeTypes.MfmMentionNode node, IDocument document) - { - var link = document.CreateElement("a"); - link.SetAttribute("href", $"/@{node.Acct}"); - link.ClassName = "mention"; - var userPart = document.CreateElement("span"); - userPart.ClassName = "user"; - userPart.TextContent = $"@{node.Username}"; - link.AppendChild(userPart); - if (node.Host != null) - { - var hostPart = document.CreateElement("span"); - hostPart.ClassName = "host"; - hostPart.TextContent = $"@{node.Host.Value}"; - link.AppendChild(hostPart); - } + private static INode MfmItalicNode(MfmNodeTypes.MfmItalicNode _, IDocument document) + { + var el = document.CreateElement("span"); + el.SetAttribute("style", "font-style: italic"); + return el; + } - return link; - } + private static INode MfmEmojiCodeNode( + MfmNodeTypes.MfmEmojiCodeNode node, IDocument document, List emojiList + ) + { + var el = document.CreateElement("span"); + el.ClassName = "emoji"; + + var emoji = emojiList.Find(p => p.Name == node.Name); + if (emoji is null) + { + el.TextContent = node.Name; + } + else + { + var image = document.CreateElement("img"); + image.SetAttribute("src", emoji.PublicUrl); + image.SetAttribute("alt", node.Name); + el.AppendChild(image); + } + + return el; + } + + private static INode MfmUrlNode(MfmNodeTypes.MfmUrlNode node, IDocument document) + { + var el = document.CreateElement("a"); + el.SetAttribute("href", node.Url); + el.ClassName = "url-node"; + el.TextContent = node.Url; + return el; + } + + private static INode MfmBoldNode(MfmNodeTypes.MfmBoldNode _, IDocument document) + { + var el = document.CreateElement("strong"); + return el; + } + + private static INode MfmTextNode(MfmNodeTypes.MfmTextNode node, IDocument document) + { + var el = document.CreateElement("span"); + el.TextContent = node.Text; + return el; + } + + private static INode MfmMentionNode(MfmNodeTypes.MfmMentionNode node, IDocument document) + { + var link = document.CreateElement("a"); + link.SetAttribute("href", $"/@{node.Acct}"); + link.ClassName = "mention"; + var userPart = document.CreateElement("span"); + userPart.ClassName = "user"; + userPart.TextContent = $"@{node.Username}"; + link.AppendChild(userPart); + if (node.Host != null) + { + var hostPart = document.CreateElement("span"); + hostPart.ClassName = "host"; + hostPart.TextContent = $"@{node.Host.Value}"; + link.AppendChild(hostPart); + } + + return link; + } } \ No newline at end of file diff --git a/Iceshrimp.Frontend/Core/Services/ComposeService.cs b/Iceshrimp.Frontend/Core/Services/ComposeService.cs index b50ce063..7d4257ed 100644 --- a/Iceshrimp.Frontend/Core/Services/ComposeService.cs +++ b/Iceshrimp.Frontend/Core/Services/ComposeService.cs @@ -1,5 +1,4 @@ using Iceshrimp.Frontend.Components; -using Microsoft.AspNetCore.Components; namespace Iceshrimp.Frontend.Core.Services; diff --git a/Iceshrimp.Frontend/Pages/ProfileView.razor b/Iceshrimp.Frontend/Pages/ProfileView.razor index 616507b9..94e4a15e 100644 --- a/Iceshrimp.Frontend/Pages/ProfileView.razor +++ b/Iceshrimp.Frontend/Pages/ProfileView.razor @@ -5,7 +5,7 @@ @using Iceshrimp.Frontend.Components @using Iceshrimp.Frontend.Components.Note @using System.Text.RegularExpressions -@inject ApiService Api +@inject ApiService Api @if (_init) { @@ -64,11 +64,12 @@ private UserProfileResponse? Profile { get; set; } private string? MinId { get; set; } private List UserNotes { get; set; } = []; - private bool _loading = true; - private bool _init = false; - private bool _notFound = false; - private bool _error = false; - private bool _fetchLock = false; + + private bool _loading = true; + private bool _init; + private bool _notFound; + private bool _error; + private bool _fetchLock; private async Task GetNotes(string? minId) { diff --git a/Iceshrimp.Frontend/Pages/SingleNote.razor b/Iceshrimp.Frontend/Pages/SingleNote.razor index 34b35673..aaa8ebaf 100644 --- a/Iceshrimp.Frontend/Pages/SingleNote.razor +++ b/Iceshrimp.Frontend/Pages/SingleNote.razor @@ -52,9 +52,9 @@ else private IList? Ascendants { get; set; } private IJSObjectReference? Module { get; set; } private ElementReference RootNoteRef { get; set; } - private bool _init = false; - private bool _error = false; - + private bool _init; + private bool _error; + protected override async Task OnParametersSetAsync() { _init = false; diff --git a/Iceshrimp.NET.sln.DotSettings b/Iceshrimp.NET.sln.DotSettings index 3a3f76d9..df513faa 100644 --- a/Iceshrimp.NET.sln.DotSettings +++ b/Iceshrimp.NET.sln.DotSettings @@ -101,6 +101,7 @@ 1 EXPANDED NEXT_LINE + True NEXT_LINE True CHOP_IF_LONG