Social bar UX: YT auto-add from connected account, two-box dialog (YT handle + URL/handle for other services), service auto-detection from URL domain, fediverse @user@domain support, footer repositioned (Social controls left under scenes/sources, meter centered under preview), validation with add-anyway fallback
This commit is contained in:
@@ -136,4 +136,64 @@ public static class SocialServiceIcons
|
||||
_ => $"https://{h}",
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Auto-detects the social service from a URL or fediverse handle. Supports
|
||||
/// full URLs (https://x.com/user), domain-only (x.com/user), and fediverse
|
||||
/// handles (@user@instance.tube). Returns Link/Website for unknown domains
|
||||
/// or bare handles — the caller can then ask which service it is.
|
||||
/// </summary>
|
||||
public static (SocialService service, string handle, string url) DetectService(string input)
|
||||
{
|
||||
var trimmed = input.Trim();
|
||||
|
||||
// Fediverse handle: @user@domain
|
||||
if (trimmed.StartsWith("@") && trimmed.IndexOf('@', 1) > 0)
|
||||
{
|
||||
var parts = trimmed.TrimStart('@').Split('@', 2);
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
var (user, domain) = (parts[0], parts[1]);
|
||||
return (SocialService.Link, user, $"https://{domain}/@{user}");
|
||||
}
|
||||
}
|
||||
|
||||
// Strip protocol for domain parsing
|
||||
var url = trimmed;
|
||||
if (!trimmed.StartsWith("http", StringComparison.OrdinalIgnoreCase))
|
||||
url = $"https://{trimmed}";
|
||||
|
||||
try
|
||||
{
|
||||
var uri = new Uri(url);
|
||||
var domain = uri.Host.ToLowerInvariant();
|
||||
var path = uri.AbsolutePath.Trim('/');
|
||||
|
||||
return domain switch
|
||||
{
|
||||
"youtube.com" or "www.youtube.com" or "youtu.be" => (SocialService.YouTube, path, url),
|
||||
"twitch.tv" or "www.twitch.tv" => (SocialService.Twitch, path, url),
|
||||
"x.com" or "twitter.com" => (SocialService.X, path, url),
|
||||
"instagram.com" or "www.instagram.com" => (SocialService.Instagram, path, url),
|
||||
"tiktok.com" or "www.tiktok.com" => (SocialService.TikTok, path, url),
|
||||
"facebook.com" or "www.facebook.com" or "fb.com" => (SocialService.Facebook, path, url),
|
||||
"discord.gg" or "discord.com" => (SocialService.Discord, path, url),
|
||||
"kick.com" => (SocialService.Kick, path, url),
|
||||
"threads.net" or "www.threads.net" => (SocialService.Threads, path, url),
|
||||
"bsky.app" => (SocialService.Bluesky, path, url),
|
||||
"github.com" => (SocialService.GitHub, path, url),
|
||||
"linkedin.com" or "www.linkedin.com" => (SocialService.LinkedIn, path, url),
|
||||
"pinterest.com" or "www.pinterest.com" => (SocialService.Pinterest, path, url),
|
||||
"snapchat.com" => (SocialService.Snapchat, path, url),
|
||||
"reddit.com" or "www.reddit.com" => (SocialService.Reddit, path, url),
|
||||
"wa.me" or "whatsapp.com" => (SocialService.WhatsApp, path, url),
|
||||
"t.me" => (SocialService.Telegram, path, url),
|
||||
_ => (SocialService.Website, path, url),
|
||||
};
|
||||
}
|
||||
catch
|
||||
{
|
||||
return (SocialService.Link, trimmed.TrimStart('@'), SocialServiceIcons.CanonicalUrlFor(SocialService.Link, trimmed));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user