/// The emoji that earn a particle burst. /// /// Ported verbatim from `POSITIVE_EMOJI_PARTICLES` in /// `desktop/src/shared/ui/EmojiBurstProvider.tsx`. Only affirmation reacts /// celebrate โ€” a ๐Ÿ˜ข or ๐Ÿ‘Ž shouldn't throw confetti โ€” so the three groups below /// are the whole gate, and both clients must agree on them or the same reaction /// bursts on one device and not the other. library; const heartParticleEmojis = [ '\u{2764}\u{FE0F}', // โค๏ธ '\u{1FA77}', // ๐Ÿฉท '\u{1F9E1}', // ๐Ÿงก '\u{1F49B}', // ๐Ÿ’› '\u{1F49A}', // ๐Ÿ’š '\u{1FA75}', // ๐Ÿฉต '\u{1F499}', // ๐Ÿ’™ '\u{1F49C}', // ๐Ÿ’œ '\u{1F90E}', // ๐ŸคŽ '\u{1F5A4}', // ๐Ÿ–ค '\u{1FA76}', // ๐Ÿฉถ '\u{1F90D}', // ๐Ÿค '\u{2764}\u{FE0F}\u{200D}\u{1F525}', // โค๏ธโ€๐Ÿ”ฅ '\u{2764}\u{FE0F}\u{200D}\u{1FA79}', // โค๏ธโ€๐Ÿฉน '\u{1F496}', // ๐Ÿ’– '\u{1F495}', // ๐Ÿ’• '\u{1F497}', // ๐Ÿ’— '\u{1F493}', // ๐Ÿ’“ '\u{1F49E}', // ๐Ÿ’ž '\u{1F498}', // ๐Ÿ’˜ '\u{1F49D}', // ๐Ÿ’ '\u{2763}\u{FE0F}', // โฃ๏ธ '\u{2665}\u{FE0F}', // โ™ฅ๏ธ ]; const positiveReactionParticleEmojis = [ '\u{1F44D}', // ๐Ÿ‘ '\u{1F44F}', // ๐Ÿ‘ '\u{1F64C}', // ๐Ÿ™Œ '\u{1F64F}', // ๐Ÿ™ '\u{1F4AF}', // ๐Ÿ’ฏ '\u{1F525}', // ๐Ÿ”ฅ '\u{2728}', // โœจ '\u{2B50}', // โญ '\u{1F31F}', // ๐ŸŒŸ '\u{1F389}', // ๐ŸŽ‰ '\u{1F38A}', // ๐ŸŽŠ '\u{1F973}', // ๐Ÿฅณ '\u{1F680}', // ๐Ÿš€ '\u{1F4AA}', // ๐Ÿ’ช ]; const positiveFaceParticleEmojis = [ '\u{1F600}', // ๐Ÿ˜€ '\u{1F603}', // ๐Ÿ˜ƒ '\u{1F604}', // ๐Ÿ˜„ '\u{1F601}', // ๐Ÿ˜ '\u{1F60A}', // ๐Ÿ˜Š '\u{1F607}', // ๐Ÿ˜‡ '\u{1F642}', // ๐Ÿ™‚ '\u{1F60D}', // ๐Ÿ˜ '\u{1F929}', // ๐Ÿคฉ '\u{1F970}', // ๐Ÿฅฐ '\u{1F618}', // ๐Ÿ˜˜ '\u{1F60B}', // ๐Ÿ˜‹ '\u{1F60E}', // ๐Ÿ˜Ž '\u{1F602}', // ๐Ÿ˜‚ '\u{1F923}', // ๐Ÿคฃ ]; const positiveEmojiParticles = [ ...heartParticleEmojis, ...positiveReactionParticleEmojis, ...positiveFaceParticleEmojis, ]; /// Emoji presentation selectors carry no meaning for this comparison, and the /// same emoji reaches us with and without one depending on where it came from /// (the emoji-mart dataset, a hand-typed reaction, an older client). Desktop /// gets away with exact set membership because its picker is the only producer; /// mobile reactions also arrive off the wire, so fold the selector away. String _foldSelectors(String emoji) => emoji.trim().replaceAll('\u{FE0F}', '').replaceAll('\u{FE0E}', ''); final Set _positiveEmojiParticleSet = { for (final emoji in positiveEmojiParticles) _foldSelectors(emoji), }; /// Whether [emoji] should burst. Mirrors desktop's `isPositiveEmojiParticle`. bool isPositiveEmojiParticle(String emoji) => _positiveEmojiParticleSet.contains(_foldSelectors(emoji));