@ -1,5 +1,6 @@
using System.Collections.Generic ;
using System.Linq ;
using System.Text ;
using Tyrrrz.Extensions ;
namespace DiscordChatExporter.Core.Models
@ -28,14 +29,21 @@ namespace DiscordChatExporter.Core.Models
public partial class Emoji
{
private static IEnumerable < int > GetCodePoint s( string emoji )
private static IEnumerable < Rune > GetRune s( string emoji )
{
for ( var i = 0 ; i < emoji . Length ; i + = char . IsHighSurrogate ( emoji [ i ] ) ? 2 : 1 )
yield return char . ConvertToUtf32 ( emoji , i ) ;
var lastIndex = 0 ;
while ( lastIndex < emoji . Length & & Rune . TryGetRuneAt ( emoji , lastIndex , out var rune ) )
{
// Skip variant selector rune
if ( rune . Value ! = 0xfe0f )
yield return rune ;
lastIndex + = rune . Utf16SequenceLength ;
}
}
private static string GetTwemojiName ( string emoji ) = >
GetCodePoints ( emoji ) . Select ( i = > i . ToString ( "x" ) ) . JoinToString ( "-" ) ;
private static string GetTwemojiName ( IEnumerable < Rune > runes ) = >
runes. Select ( r = > r . Value . ToString ( "x" ) ) . JoinToString ( "-" ) ;
public static string GetImageUrl ( string? id , string name , bool isAnimated )
{
@ -50,9 +58,17 @@ namespace DiscordChatExporter.Core.Models
return $"https://cdn.discordapp.com/emojis/{id}.png" ;
}
// Standard unicode emoji (via twemoji)
var twemojiName = GetTwemojiName ( name ) ;
return $"https://twemoji.maxcdn.com/2/72x72/{twemojiName}.png" ;
// Standard unicode emoji
var emojiRunes = GetRunes ( name ) . ToArray ( ) ;
if ( emojiRunes . Any ( ) )
{
// Get corresponding Twemoji image
var twemojiName = GetTwemojiName ( emojiRunes ) ;
return $"https://twemoji.maxcdn.com/2/72x72/{twemojiName}.png" ;
}
// Fallback in case of failure
return name ;
}
}
}