Advertisement
Guest User

Untitled

a guest
Jul 19th, 2019
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.26 KB | None | 0 0
  1. import * as React from 'react';
  2. import * as unified from 'unified';
  3. import { useContext } from 'react';
  4.  
  5. import classNames from '../libs/classNames';
  6. import mentions from './remark-mentions';
  7. import { StateContext } from '..';
  8. import { traverseMentions } from '../traverse-mentions';
  9. import { User } from '../types';
  10.  
  11. import { createComponentFromProcessor } from 'remark-react-component/build/es6';
  12. import {
  13. emojis,
  14. addEmojiClasses,
  15. } from 'remark-react-component/build/es6/emojis';
  16.  
  17. const markdown = require('remark-parse');
  18.  
  19. interface Props {
  20. text: string;
  21. className?: string;
  22. }
  23.  
  24. enum ClassNames {
  25. Emoji = 'emoji',
  26. EmojiLarge = 'emoji-large',
  27. Mention = 'mention',
  28. MentionCurrentUser = 'mention--you',
  29. }
  30.  
  31. const pipeline = unified()
  32. // This is the Markdown parser
  33. .use(markdown)
  34. // Parse @mentions and :emojis: to AST nodes
  35. .use(emojis)
  36. .use(mentions);
  37.  
  38. // Build a renderer component based on the Unified pipeline above
  39. const Renderer = createComponentFromProcessor(pipeline);
  40.  
  41. const findUserFromMention = (users: User[], mention: string) =>
  42. users ? users.find((u) => u.username === mention) : null;
  43.  
  44. /**
  45. * A general text component which renders nice things from a single
  46. * text string.
  47. *
  48. * Currently supports:
  49. *
  50. * - Markdown
  51. * - Emojis (shortcodes and unicode)
  52. * - @mentions
  53. */
  54. const Text: React.FunctionComponent<Props> = (props) => {
  55. const ctx = useContext(StateContext);
  56.  
  57. return (
  58. <Renderer
  59. text={props.text}
  60. className={classNames('markdown-content', props.className)}
  61. // Here we can attach "transformers" of the AST. With them, we can
  62. // spruce up the nodes a bit, such as attaching custom class names and title
  63. // attributes.
  64. transformers={[
  65. addEmojiClasses({
  66. className: ClassNames.Emoji,
  67. classNameForOnlyEmojis: ClassNames.EmojiLarge,
  68. }),
  69. traverseMentions({
  70. title: (mention) => {
  71. const user =
  72. ctx.state.users &&
  73. findUserFromMention(ctx.state.users, mention);
  74.  
  75. if (!user) {
  76. return '';
  77. }
  78.  
  79. return user._id === ctx.state.userID
  80. ? 'This is you!'
  81. : user.profile.fullname;
  82. },
  83. className: (mention) => {
  84. const user =
  85. ctx.state.users &&
  86. findUserFromMention(ctx.state.users, mention);
  87.  
  88. if (!user) {
  89. return '';
  90. }
  91.  
  92. return user._id === ctx.state.userID
  93. ? `${ClassNames.Mention} ${
  94. ClassNames.MentionCurrentUser
  95. }`
  96. : ClassNames.Mention;
  97. },
  98. }),
  99. ]}
  100. />
  101. );
  102. };
  103.  
  104. // tslint:disable-next-line no-object-mutation
  105. Text.displayName = 'Text';
  106. // tslint:disable-next-line no-object-mutation
  107. Renderer.displayName = 'Renderer';
  108.  
  109. export default React.memo(Text);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement