hootsuite/nachos

Max chip text length

D330 opened this issue · 5 comments

D330 commented

How to set max length for chip?

You can extend DefaultChipTerminatorHandler or implement your own ChipTerminatorHandler and override the findAndHandleChipTerminators handler methods to be more stringent.

So for example, in handleChipifyCurrentToken, nothing occurs unless (tokenStart < tokenEnd). You could add an additional check here to make sure the length is of a certain range. You can further abstract this to set this length with parameters. Similar logic applies to changing terminateAllTokens, and handleChipifyToTerminator

D330 commented

@augudyne thanks. I create custom TokenizerHandler with callback and edit code so:

if (tokenStart < tokenEnd) {
            CharSequence token = text.subSequence(tokenStart, tokenEnd);
            if (controlWordListener == null || controlWordListener.onControl(token.toString())) {
                CharSequence chippedText = tokenizer.terminateToken(token, null);
                textIterator.replace(tokenStart, tokenEnd, chippedText);
                return tokenStart + chippedText.length();
            }
        }

But i want disallow input if length > maxLength... TokenizerHandler check only when inputted terminated symbol.

So here, you will add if (tokenStart < tokenEnd && (tokenEnd - tokenStart < maxLength)).

Note that there are 3 call back methods for creating chips. Add this logic in handleChipifyCurrentToken, terminateAllTokens and handleChipifyToTerminator

D330 commented

@augudyne. Ookay see please i complete this!

public class DefaultChipTerminatorHandler implements ChipTerminatorHandler {

    @Nullable
    private List<Character> mChipTerminators;

    @Nullable
    private OnControlWordListener controlWordListener;

    @Nullable
    private OnControlSymbolListener controlSymbolListener;

    @Override
    public void addChipTerminator(char character) {
        if (mChipTerminators == null) {
            mChipTerminators = new ArrayList<>();
        }

        mChipTerminators.add(character);
    }

    @Override
    public int findAndHandleChipTerminators(@NonNull ChipTokenizer tokenizer, @NonNull Editable text, int start, int end) {
        // If we don't have a tokenizer or any chip terminators, there's nothing to look for
        if (mChipTerminators == null) {
            return -1;
        }

        TextIterator textIterator = new TextIterator(text, start, end);
        int selectionIndex = -1;

        while (textIterator.hasNextCharacter()) {
            char theChar = textIterator.nextCharacter();
            if (isChipTerminator(theChar)) {
                int newSelection = handleChipifyCurrentToken(textIterator, tokenizer);
                if (newSelection != -1) {
                    selectionIndex = newSelection;
                }
            } else {
                Editable editable = textIterator.getText();
                int index = textIterator.getIndex();
                int tokenStart = tokenizer.findTokenStart(editable, index);
                int tokenEnd = tokenizer.findTokenEnd(editable, index);
                if (tokenStart < tokenEnd) {
                    CharSequence word = text.subSequence(tokenStart, tokenEnd);
                    if (controlSymbolListener != null &&
                            !controlSymbolListener.onControl(theChar, word.toString())) {
                        textIterator.deleteCharacter(true);
                    }
                }
            }
        }

        return selectionIndex;
    }

    private int handleChipifyCurrentToken(TextIterator textIterator, ChipTokenizer tokenizer) {
        textIterator.deleteCharacter(true);
        Editable text = textIterator.getText();
        int index = textIterator.getIndex();
        int tokenStart = tokenizer.findTokenStart(text, index);
        int tokenEnd = tokenizer.findTokenEnd(text, index);
        if (tokenStart < tokenEnd) {
            CharSequence token = text.subSequence(tokenStart, tokenEnd);
            if (controlWordListener == null || controlWordListener.onControl(token.toString())) {
                CharSequence chippedText = tokenizer.terminateToken(token, null);
                textIterator.replace(tokenStart, tokenEnd, chippedText);
                return tokenStart + chippedText.length();
            }
        }
        return -1;
    }

    private boolean isChipTerminator(char character) {
        return mChipTerminators != null && mChipTerminators.contains(character);
    }

    public void setControlWordListener(@Nullable OnControlWordListener controlWordListener) {
        this.controlWordListener = controlWordListener;
    }

    public void setControlSymbolListener(@Nullable OnControlSymbolListener controlSymbolListener) {
        this.controlSymbolListener = controlSymbolListener;
    }
}

(tokenStart < tokenEnd && (tokenEnd - tokenStart < maxLength))

Thanks it works, one thing to note that you should call chipInput.setChipTerminatorHandler(YourCustomHandler()) before chipInput.addChipTerminator() (or maybe before all other methods)