aboutsummaryrefslogtreecommitdiff
path: root/src/utils/comments.tsx
blob: d7091d1e45d2dc3989ea7070b206042ed4d212ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import React from 'react';
import {StyleProp, Text, TextStyle} from 'react-native';
import {
  isMentionPartType,
  parseValue,
  Part,
  PartType,
} from 'react-native-controlled-mentions';
import TaggTypeahead from '../components/common/TaggTypeahead';
import {TAGG_LIGHT_BLUE} from '../constants';
import {UserType} from '../types';

/**
 * Part renderer
 *
 * https://github.com/dabakovich/react-native-controlled-mentions#rendering-mentioninputs-value
 */
const renderPart = (
  part: Part,
  index: number,
  handlePress: (user: UserType) => void,
) => {
  // Just plain text
  if (!part.partType) {
    return <Text key={index}>{part.text}</Text>;
  }

  // Mention type part
  if (isMentionPartType(part.partType)) {
    return (
      <Text
        key={`${index}-${part.data?.trigger}`}
        style={part.partType.textStyle}
        onPress={() => {
          if (part.data) {
            handlePress({
              userId: part.data.id,
              username: part.data.name,
            });
          }
        }}>
        {part.text}
      </Text>
    );
  }

  // Other styled part types
  return (
    <Text key={`${index}-pattern`} style={part.partType.textStyle}>
      {part.text}
    </Text>
  );
};

interface RenderProps {
  value: string;
  styles: StyleProp<TextStyle>;
  partTypes: PartType[];
  onPress: (user: UserType) => void;
}

/**
 * Value renderer. Parsing value to parts array and then mapping the array using 'renderPart'
 *
 * https://github.com/dabakovich/react-native-controlled-mentions#rendering-mentioninputs-value
 */
export const renderTextWithMentions: React.FC<RenderProps> = ({
  value,
  styles,
  partTypes,
  onPress,
}) => {
  const {parts} = parseValue(value, partTypes);
  return (
    <Text style={styles}>
      {parts.map((part, index) => renderPart(part, index, onPress))}
    </Text>
  );
};

export const mentionPartTypes: (style: 'blue' | 'white', textRef: any) => PartType[] = (
  style,
  textRef
) => {
  return [
    {
      trigger: '@',
      renderSuggestions: (props) => <TaggTypeahead textRef={textRef} {...props} />,
      allowedSpacesCount: 0,
      isInsertSpaceAfterMention: true,
      textStyle:
        style === 'blue'
          ? {color: TAGG_LIGHT_BLUE}
          : {color: 'white', fontWeight: '800'},
    },
  ];
};