feat: clickable URLs in chat log
Adds a parsing step when constructing `Message` objects that scans the message content for anything that looks URL-like, and inserts new `TextChunk`s into the message content with a URIPayload set. Hovering over a URL shows an on-hover effect. Clicking a URL opens it in the default browser. Right clicking shows the hostname, with an option to open and an option to copy the URL to the clipboard.
This commit is contained in:
@@ -21,6 +21,7 @@ using Lumina.Excel.GeneratedSheets;
|
||||
using Action = System.Action;
|
||||
using DalamudPartyFinderPayload = Dalamud.Game.Text.SeStringHandling.Payloads.PartyFinderPayload;
|
||||
using ChatTwoPartyFinderPayload = ChatTwo.Util.PartyFinderPayload;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ChatTwo;
|
||||
|
||||
@@ -86,6 +87,11 @@ public sealed class PayloadHandler {
|
||||
drawn = true;
|
||||
break;
|
||||
}
|
||||
case URIPayload uri: {
|
||||
DrawUriPopup(uri);
|
||||
drawn = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ContextFooter(drawn, chunk);
|
||||
@@ -215,6 +221,11 @@ public sealed class PayloadHandler {
|
||||
DoHover(() => HoverItem(item), hoverSize);
|
||||
break;
|
||||
}
|
||||
case URIPayload uri:
|
||||
{
|
||||
DoHover(() => HoverURI(uri), hoverSize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,6 +345,11 @@ public sealed class PayloadHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private void HoverURI(URIPayload uri) {
|
||||
ImGui.TextUnformatted(string.Format(Language.Context_URLDomain, uri.Uri.Authority));
|
||||
ImGuiUtil.WarningText(Language.Context_URLWarning);
|
||||
}
|
||||
|
||||
private void LeftClickPayload(Chunk chunk, Payload? payload) {
|
||||
switch (payload) {
|
||||
case MapLinkPayload map: {
|
||||
@@ -372,6 +388,10 @@ public sealed class PayloadHandler {
|
||||
|
||||
break;
|
||||
}
|
||||
case URIPayload uri: {
|
||||
TryOpenURI(uri.Uri);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -625,4 +645,38 @@ public sealed class PayloadHandler {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void DrawUriPopup(URIPayload uri)
|
||||
{
|
||||
ImGui.TextUnformatted(string.Format(Language.Context_URLDomain, uri.Uri.Authority));
|
||||
ImGuiUtil.WarningText(Language.Context_URLWarning, false);
|
||||
ImGui.Separator();
|
||||
|
||||
if (ImGui.Selectable(Language.Context_OpenInBrowser))
|
||||
{
|
||||
TryOpenURI(uri.Uri);
|
||||
}
|
||||
|
||||
if (ImGui.Selectable(Language.Context_CopyLink))
|
||||
{
|
||||
ImGui.SetClipboardText(uri.Uri.ToString());
|
||||
WrapperUtil.AddNotification(Language.Context_CopyLinkNotification, NotificationType.Info);
|
||||
}
|
||||
}
|
||||
|
||||
private void TryOpenURI(Uri uri)
|
||||
{
|
||||
new Thread(() => {
|
||||
try
|
||||
{
|
||||
Plugin.Log.Info($"Opening URI {uri} in default browser");
|
||||
Process.Start(new ProcessStartInfo(uri.ToString()) { UseShellExecute = true });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Plugin.Log.Error($"Error opening URI: {ex}");
|
||||
WrapperUtil.AddNotification(Language.Context_OpenInBrowserError, NotificationType.Error);
|
||||
}
|
||||
}).Start();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user