EmojiPicker.pm 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package Trog::Component::EmojiPicker;
  2. use strict;
  3. use warnings;
  4. no warnings qw{experimental};
  5. use feature qw{signatures state};
  6. use JSON::MaybeXS;
  7. use Trog::Renderer;
  8. =head1 Trog::Component::EmojiPicker
  9. The emoji picker component.
  10. =head1 Termination Conditions
  11. Dies if the emoji list isn't on disk, as there's no sensible picker to show
  12. without it. It's a frontend dependency, so C<make prereq-frontend> is what
  13. puts it there.
  14. =head1 FUNCTIONS
  15. =head2 render() = STRING
  16. Render the picker as an HTML component.
  17. The emoji list ships as a flat array, which is no use to a picker with tabs, so
  18. it gets bucketed by category on the first call and memoized thereafter -- the
  19. list can't change without a redeploy.
  20. Returns the rendered body, rather than a PSGI triplet, as components are meant
  21. to be composed into a page by their caller.
  22. =cut
  23. sub render () {
  24. state %categorized;
  25. if ( !%categorized ) {
  26. my $file = 'www/scripts/list.min.json';
  27. die "Run make prereq-frontend first" unless -f $file;
  28. my $raw = File::Slurper::read_binary($file);
  29. my $emojis = JSON::MaybeXS::decode_json($raw);
  30. foreach my $emoji ( @{ $emojis->{emojis} } ) {
  31. $categorized{ $emoji->{category} } //= [];
  32. push( @{ $categorized{ $emoji->{category} } }, $emoji->{emoji} );
  33. }
  34. }
  35. return Trog::Renderer->render(
  36. contenttype => 'text/html',
  37. component => 1,
  38. template => 'emojis.tx',
  39. data => {
  40. categories => \%categorized,
  41. },
  42. );
  43. }
  44. 1;