[feat]: Add option to pass list of usernames to be considered when mention user mode is activated
When we type @ and mention user mode is activated, this arg value (which is an array of data) is used as a source to come as a list above/below where you are typing, to select from.
This will be possible once https://github.com/Expensify/react-native-live-markdown/pull/439 is merged.
@tomekzaw I see that #439 is merged. is this functionality available now?
@arpitv96171 Yes, you should be able to customize parser logic now. I believe @Kicu can provide some more details on that.
hey @arpitv96171 👋
We use react-native-live-markdown extensively in Expensify/App and I believe we're doing something similar to what you would like to achieve.
There are 3 parts to this:
- the new
parserprop onMarkdownTextInputcomponent - you need to create a worklet function and pass it with the parsing logic toMarkdownTextInput- if you want to use existing parsing logic, just importparseExpensiMarkand use it. Take a look at this: https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#worklet - you can use reanimated's shared value (https://docs.swmansion.com/react-native-reanimated/docs/core/useSharedValue) to send values to the worklet.
- when updating the shared value, you need to wrap it with
runOnRuntimeand use runtime provided byreact-native-live-markdownhere: https://github.com/Expensify/react-native-live-markdown/blob/main/src/MarkdownTextInput.tsx#L141 - this ensures that your values will actually be updated on the thread that live-markdown is running the parser.
Here's all this in action:
I'm defining a parser here: https://github.com/Expensify/App/blob/5c66742369ce506ef5ed51f1400040062000fd9f/src/components/RNMarkdownTextInput.tsx#L49-L59 in line 27 I'm defining the shared value for my list of available user mentions/logins:
const mentionsSharedVal = useSharedValue<string[]>(mentionsList)
Then the crucial part of the code is in lines 62-68
useEffect(() => {
runOnLiveMarkdownRuntime(() => {
'worklet';
mentionsSharedVal.set(mentionsList);
})();
}, [mentionsList, mentionsSharedVal]);
👆 any time my mentionsList changes, we update the sharedValue and the next time your parser runs, it will use the new data. You could probably just set the list once on init if it's static in your case.
Here is the definition of runOnLiveMarkdownRuntime:
import {getWorkletRuntime} from '@expensify/react-native-live-markdown';
import {runOnRuntime} from 'react-native-reanimated';
function runOnLiveMarkdownRuntime<Args extends unknown[], ReturnType>(worklet: (...args: Args) => ReturnType) {
return runOnRuntime(getWorkletRuntime(), worklet);
}
We use this implementation only for mobile, since worklets on web do not exist. See details here: https://github.com/Expensify/App/tree/main/src/libs/runOnLiveMarkdownRuntime
Once you have the workletized parser then you can send whatever data you need to it via sharedValue and use this data when parsing.
Feel free to ask if anything is unclear 🙂