GAB User Autocomplete

User Autocomplete requirement 2 of 2: show a pop-up of users that match the @mention found at the end of the text entry

// ==UserScript==
// @name         GAB User Autocomplete
// @namespace    https://gab.ai/Jeremy20_9
// @version      0.1
// @description  User Autocomplete requirement 2 of 2: show a pop-up of users that match the @mention found at the end of the text entry
// @author       Jeremiah 20:9
// @match        https://gab.ai/home
// @grant        none
// @require      https://code.jquery.com/jquery-1.8.2.js
// ==/UserScript==
var followers = localStorage.getItem("gab-user-followers");
var following = localStorage.getItem("gab-user-following");
var availableTags = [];

if(followers)
{
    availableTags = availableTags.concat(JSON.parse(followers));
}
if(following)
{
    availableTags = availableTags.concat(JSON.parse(following));
}
var subset = [];
var itvcheck = -1;
var choiceidx = 0;
function checkfortxt()
{
    if($( ".composer--open > .composer__content > textarea" ).length > 0)
    {
        clearInterval(itvcheck);
        var ops = document.createElement("div");
        $(ops).css("position", "absolute");
        $(ops).css("left", "50px");
        $(ops).css("bottom", "0px");
        $(ops).css("width", "300px");
        $(ops).css("height", "100px");
        $(ops).css("background-color", "white");
        $(ops).css("box-shadow", "0px 0px 2px rgba(0,0,0,.5)");
        $(ops).css("display", "none");
        
        $(".composer__content").append(ops);
        
        $( ".composer__content > textarea" ).on("keydown", function(evt){
            var txt = $(".composer__content > textarea").val();
            
            var regex = new RegExp("^[a-zA-Z0-9_-]+$");
            var str = String.fromCharCode(!evt.charCode ? evt.which : evt.charCode);
            if (!regex.test(str) && evt.which != 38 && evt.which != 40 && evt.which != 13 && evt.which != 8 && evt.which != 46) {
                $(ops).css("display", "none");
                return;
            }
            else if(evt.which != 38 && evt.which != 40 && evt.which != 13 && evt.which != 8 && evt.which != 46)
                txt += evt.key;
            
            var rex = /@[A-Za-z]+[A-Za-z0-9_-]*$/g;
            var userinfo = rex.exec(txt);

            if(!userinfo)
            {
                $(ops).css("display", "none");
                return;
            }
            var user = userinfo[0].substr(1); // strip the "@"
            subset = [];
            for(var a = 0; a < availableTags.length && subset.length < 3; a++)
            {
                if(user.toLowerCase() == availableTags[a].atname.toLowerCase().substr(0,user.length) || user.toLowerCase() == availableTags[a].name.toLowerCase().substr(0,user.length))
                {
                    var found = false;
                    for(var s in subset)
                    {
                        if(availableTags[a].atname == subset[s].atname)
                        {
                            found = true;
                            break;
                        }
                    }
                    if(!found)
                        subset.push(availableTags[a]);
                }
            }
            if(subset.length === 0)
            {
                $(ops).css("display", "none");
                return;
            }
            else
            {
                $(ops).css("height", (subset.length * 30) + "px");
            }
            if(evt.which == 38) // up
            {
                evt.preventDefault();
                choiceidx--;
                if(choiceidx < 0)
                    choiceidx = subset.length - 1;
            }
            else if(evt.which == 40) //down
            {
                evt.preventDefault();
                choiceidx++;
                if(choiceidx >= subset.length)
                    choiceidx = 0;
            }
            else if(evt.which == 13)
            {
                evt.preventDefault();
                $(".composer__content > textarea").val(txt.substr(0, txt.length-user.length) + subset[choiceidx].atname + " ");
                $(ops).css("display", "none");
                return;
            }
            var render = "";
            for(var c = 0; c < subset.length; c++)
            {
                render += "<div style='padding:3px; position:absolute;width:300px;height:30px;top:" + (c * 30) + "px;";
                if(c == choiceidx)
                    render += "background-color:blue;color:white;";
                else
                    render += "color:black;";
                render += "'>";
                render += "<img src='"+subset[c].pic+"' style='height:24px; width:24px; border-radius:12px; margin-right:4px' align='left' />";
                render += "" + subset[c].name + "";
                render += "<span style='margin-left:4px;font-style:italic;opacity:0.7;'>@" + subset[c].atname + "</span>";
                render += "</div>";
            }
            $(ops).html(render);
            $(ops).css("display", "block");
        });
    }
}
$("document").ready(function(){
    itvcheck = setInterval(checkfortxt, 500);
});