Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can you create an example? #3

Open
efstathiosntonas opened this issue Dec 9, 2021 · 5 comments
Open

Can you create an example? #3

efstathiosntonas opened this issue Dec 9, 2021 · 5 comments

Comments

@efstathiosntonas
Copy link

Hi @lucasfeijo, can you please share a minimum example using this module? Thanks

@lucasfeijo
Copy link
Owner

Hey @efstathiosntonas, it's been a while since I've worked with React Native, but I'll try to dig out something for you.

@efstathiosntonas
Copy link
Author

Thanks Lucas!

@lucasfeijo
Copy link
Owner

lucasfeijo commented Dec 9, 2021

This is not plug and play, I chopped it from old files I had lying around, but it's enough to demonstrate how to inject react-native-reply into a text input.

There's code to show a suggestion box above the text input when it detects an @ symbol, but you're gonna have to tweak that part.

const ChatInput = ({ conversationInfo }: ChatInputProps) => {
  const [
    mentionProps, // spread these on the text input
    {
      isMentioning,
      keyword,
      onSuggestionPick,
      setRawText: setMessage,
      rawText,
    },
  ] = useMentionsInput();

  const suggestionList = useMemo(() => {
    if (!isMentionSuggestingEnabled) return null;
    if (isMentioning && !showingSuggestions) setShowingSuggestions(true);

    // Trim out the @ from the keyword
    let trimmedKeyword = String(keyword).substring(1);
    let query = trimmedKeyword;

    // Recommend replying to the last user that posted on
    // this chat that isn't the current user
    if (keyword && !trimmedKeyword) {
      const latestMessage = _.find(
        chatData?.messages,
        ({ from_id }) => from_id !== meId
      );
      query = latestMessage ? String(latestMessage.from_id) : "";
    }

    const searchSet = canMentionAnyone ? allUsers : users;
    const results = fuzzySearchUsers(Object.values(searchSet), query);

    const atAllButton = (() => {
      if (
        !query ||
        ["a", "al", "all"].includes(query) ||
        (keyword && !trimmedKeyword)
      ) {
        return renderMentionAllButton(() =>
          onSuggestionPick({
            id: "all",
            name: "All Room Members",
            username: "all",
          })
        );
      }
      return null;
    })();

    setSuggestionsEstimatedHeight(
      (() => {
        const maxItems = 3 - (atAllButton ? 1 : 0);
        const itemsVisibleCount = Math.min(results.length, maxItems);
        const userRowsHeight = itemsVisibleCount * USER_CELL_HEIGHT;
        const extraPeek =
          (itemsVisibleCount === 3 && !atAllButton && results.length > 3) ||
          (itemsVisibleCount === 2 && atAllButton && results.length > 2)
            ? 15
            : 0;
        return (
          userRowsHeight + (atAllButton ? AT_ALL_BUTTON_HEIGHT : 0) + extraPeek
        );
      })()
    );

    useEffect(() => {
      if (showingSuggestions) {
        Animated.timing(suggestionsListHeight, {
          toValue: suggestionsEstimatedHeight,
          duration: 250,
          easing: Easing.inOut(Easing.ease),
          useNativeDriver: false,
        }).start();
      } else {
        Animated.timing(suggestionsListHeight, {
          toValue: 0,
          duration: 200,
          easing: Easing.inOut(Easing.ease),
          useNativeDriver: false,
        }).start();
      }
    }, [showingSuggestions, suggestionsEstimatedHeight]);

    return (
      <Animated.View
        style={[
          styles.mentionsContainer,
          {
            height: suggestionsListHeight,
          },
        ]}
      >
        {!_.isEmpty(keyword) && isMentioning ? (
          <FlatList
            inverted
            keyboardShouldPersistTaps={"handled"}
            data={results}
            ListHeaderComponent={atAllButton}
            renderItem={({ item }) => (
              <PersonItem
                item={searchSet[item.id]}
                term={trimmedKeyword}
                onPress={() =>
                  onSuggestionPick({
                    id: String(item.id),
                    name: item.full_name,
                    username: item.full_name,
                  })
                }
                onLongPress={() => routeTo.personDetailsInModal(item)}
              />
            )}
          />
        ) : null}
      </Animated.View>
    );
  }, [keyword, isMentioning]);

  return (
    <>
      {isMentioning && (
        <>
          <Divider />
          {suggestionList}
        </>
      )}
      <View style={styles.composeWrapper}>
        <TextInput
          {...mentionProps}
          selection={undefined}
          ref={inputRef}
          multiline
          placeholder="Message"
          keyboardType={Platform.select({
            ios: isMentionSuggestingEnabled ? "twitter" : "default",
            default: "default",
          })}
          style={{
            alignSelf: "flex-start",
            textAlignVertical: isEditorFullscreen ? "top" : "auto",
            backgroundColor: "#fff",
            fontSize: 16,
            color: "#000",
            fontWeight: "400",
            padding: 10,
            paddingTop: 8,
            minHeight: 36,
            width: "100%",
            height: isEditorFullscreen ? "100%" : "auto",
            borderColor: Colors.SKY_DARK,
            borderWidth: StyleSheet.hairlineWidth,
            borderRadius: 5,
          }}
        />
      </View>
    </>
  );
};

@efstathiosntonas
Copy link
Author

Thanks Lucas, will try it out. I was trying to inject on a TextInput for like an hour 😂😂

@star-heng
Copy link

anything else?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants