diff --git a/app/emoji.ts b/app/emoji.ts index 7be6ee8..b3f12c6 100644 --- a/app/emoji.ts +++ b/app/emoji.ts @@ -7,7 +7,7 @@ export const EMOJI_LIST = [ "👍", "👎", "👏", - "🙌", + "😅", "🤝", "🎉", "🎂", diff --git a/app/encoding.ts b/app/encoding.ts index 23f9792..44e06f9 100644 --- a/app/encoding.ts +++ b/app/encoding.ts @@ -1,12 +1,40 @@ +// Variation selectors block https://unicode.org/charts/nameslist/n_FE00.html +// VS1..=VS16 +const VARIATION_SELECTOR_START = 0xfe00; +const VARIATION_SELECTOR_END = 0xfe0f; + +// Variation selectors supplement https://unicode.org/charts/nameslist/n_E0100.html +// VS17..=VS256 +const VARIATION_SELECTOR_SUPPLEMENT_START = 0xe0100; +const VARIATION_SELECTOR_SUPPLEMENT_END = 0xe01ef; + +export function toVariationSelector(byte: number): string | null { + if (byte >= 0 && byte < 16) { + return String.fromCodePoint(VARIATION_SELECTOR_START + byte) + } else if (byte >= 16 && byte < 256) { + return String.fromCodePoint(VARIATION_SELECTOR_SUPPLEMENT_START + byte) + } else { + return null + } +} + +export function fromVariationSelector(codePoint: number): number | null { + if (codePoint >= VARIATION_SELECTOR_START && codePoint <= VARIATION_SELECTOR_END) { + return codePoint - VARIATION_SELECTOR_START + } else if (codePoint >= VARIATION_SELECTOR_SUPPLEMENT_START && codePoint <= VARIATION_SELECTOR_SUPPLEMENT_END) { + return codePoint - VARIATION_SELECTOR_SUPPLEMENT_START + } else { + return null + } +} + export function encode(emoji: string, text: string): string { // convert the string to utf-8 bytes const bytes = new TextEncoder().encode(text) let encoded = emoji - for (const char of bytes) { - const upper = char >> 4 - const lower = char & 0b1111 - encoded += String.fromCodePoint(upper + 0xfe00, lower + 0xfe00) + for (const byte of bytes) { + encoded += toVariationSelector(byte) } return encoded @@ -14,16 +42,18 @@ export function encode(emoji: string, text: string): string { export function decode(text: string): string { let decoded = [] - - for (let i = 2; i < text.length; i += 2) { - const upper = text.charCodeAt(i) - 0xfe00 - const lower = text.charCodeAt(i + 1) - 0xfe00 + const chars = Array.from(text) - if (upper < 0 || upper > 15 || lower < 0 || lower > 15) { - break; + for (const char of chars) { + const byte = fromVariationSelector(char.codePointAt(0)!) + + if (byte === null && decoded.length > 0) { + break + } else if (byte === null) { + continue } - decoded.push((upper << 4) | lower) + decoded.push(byte) } let decodedArray = new Uint8Array(decoded) diff --git a/app/layout.tsx b/app/layout.tsx index 2489707..0f3adc9 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -12,6 +12,12 @@ export default function RootLayout({ }>) { return ( + + + {children} )