Home Reference Source

application/components/common/simple-editor/modifier/mention.js

import {Editor, EditorState,ContentState, Modifier} from 'draft-js';

/**
 * Mention modifier injects the mentioned user name into the editor. Keep in mind
 * that it doesn't inject any data, necessarily, just the name. The name is parsed on the
 * backend, which is what decides how notifications are sent.
 * 
 * @param editorState object EditorState
 * @param store object AltStore
 * @returns object EditorState
 */
const mentionModifier = (editorState, store) => {
    
    // grab the state, then get the current block
    const selectionState = editorState.getSelection();
    const currentBlock = editorState
        .getCurrentContent()
        .getBlockForKey(editorState.getSelection().getStartKey());
	
    // get the start of the selection (since it's collapsed)
    // then get the raw text
    const start = selectionState.getStartOffset();
    let end = start;
    const text = currentBlock.getText();

    // count backward through the text until we get to an '@' symbol
    for (let i=start; i>=0; i--) {
        const char = text.charAt(i);
        if (char === '@') {
            end = i;
            break;
        }
    }
    
    // then we expand the selection to the entire mention text
    const updatedSelection = selectionState.merge({
        focusOffset: start,
        anchorOffset: end
    });

    const user = store.stores.references.getState().selectedUser;

    let mention = '@' + user.get('slug');

    // replace the expanded selection with our new text    
    const replacement = Modifier.replaceText(
        editorState.getCurrentContent(),
        updatedSelection,
        mention
    );
    
    // force the editor to focus back on the end of the text we just passed in
    return EditorState.forceSelection(
        EditorState.push(editorState, replacement, 'insert-characters'),
        replacement.getSelectionAfter()
    );                
};

export default mentionModifier;