Basic auto-complete functionality added. Just need to finish up with toke command memory and permission map system.

This commit is contained in:
rainbow napkin 2025-01-04 04:00:58 -05:00
parent 8f45048ab6
commit 23a71a5478
5 changed files with 132 additions and 20 deletions

View file

@ -77,7 +77,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
<i class="chat-panel chat-panel-control control-prompt bi-magic" id="chat-panel-admin-icon"></i>
<i class="chat-panel chat-panel-control control-prompt bi-images" id="chat-panel-emote-icon"></i>
<span id="chat-panel-prompt-span">
<p id="chat-panel-prompt-autocomplete" class="chat-panel"><span id="chat-panel-prompt-autocomplete-filler"></span><span id="chat-panel-autocomplete-display"></span></p>
<p id="chat-panel-prompt-autocomplete" class="chat-panel"><span id="chat-panel-prompt-autocomplete-filler"></span><span id="chat-panel-prompt-autocomplete-display"></span></p>
<input class="chat-panel chat-panel-control control-prompt" id="chat-panel-prompt" placeholder="Chat...">
</span>
<button class="chat-panel chat-panel-control positive-button" id="chat-panel-send-button">Send</button>

View file

@ -274,11 +274,14 @@ span.user-entry{
#chat-panel-prompt{
font-size: 10pt;
margin-left: 0.5em;
user-select: none;
}
#chat-panel-prompt-autocomplete{
position: absolute;
text-wrap: nowrap;
cursor: pointer;
user-select: none;
font-size: 10pt;
z-index: 10;
margin: 0;
@ -288,6 +291,7 @@ span.user-entry{
#chat-panel-prompt-autocomplete-filler{
visibility: hidden;
user-select: none;
}
.toke{

View file

@ -288,7 +288,7 @@ p.channel-guide-entry-item{
}
#chat-panel-prompt-autocomplete{
color: var(--focus0);
color: var(--accent0-alt1);
text-shadow: var(--focus-glow0-alt0);
}

View file

@ -54,7 +54,9 @@ class chatBox{
setupInput(){
//Chat bar
this.chatPrompt.addEventListener("keydown", this.send.bind(this));
this.chatPrompt.addEventListener("input", this.checkAutocomplete.bind(this));
this.chatPrompt.addEventListener("keydown", this.tabComplete.bind(this));
this.chatPrompt.addEventListener("input", this.displayAutocomplete.bind(this));
this.autocompleteDisplay.addEventListener("click", this.tabComplete.bind(this));
this.sendButton.addEventListener("click", this.send.bind(this));
this.settingsIcon.addEventListener("click", ()=>{this.client.cPanel.setActivePanel(new panelObj(client))});
this.adminIcon.addEventListener("click", ()=>{this.client.cPanel.setActivePanel(new panelObj(client))});
@ -135,7 +137,7 @@ class chatBox{
catChat(text){
this.chatPrompt.value += text;
this.checkAutocomplete();
this.displayAutocomplete();
}
send(event){
@ -145,12 +147,84 @@ class chatBox{
}
}
checkAutocomplete(event){
displayAutocomplete(event){
//Find current match
const match = this.checkAutocomplete();
//Set placeholder to space out the autocomplete display
this.autocompletePlaceholder.innerHTML = this.chatPrompt.value;
//Set the autocomplete display
this.autocompleteDisplay.innerHTML = match.match.replace(match.word, '');
}
tabComplete(event){
//If we hit tab or this isn't a keyboard event
if(event.key == "Tab" || event.key == null){
//Prevent default action
event.preventDefault();
//return focus to the chat prompt
this.chatPrompt.focus();
//Grab autocompletion match
const match = this.checkAutocomplete()
//If we have a match
if(match.match != ''){
//Autocomplete the current word
this.chatPrompt.value += match.match.replace(match.word, '');
//Clear out the autocomplete display
this.autocompleteDisplay.innerHTML = '';
}
}
}
checkAutocomplete(input = this.chatPrompt.value){
//Rebuild this fucker every time because it really doesn't take that much compute power and emotes/used tokes change
//Worst case we could store it persistantly and update as needed but I think that might be much
const dictionary = this.commandPreprocessor.buildAutocompleteDictionary();
this.autocompletePlaceholder.innerHTML = this.chatPrompt.value;
const dictionary = this.commandPreprocessor.buildAutocompleteDictionary();
//Split our input by whitespace
const splitInput = input.split(/\s/g);
//Get the current word we're working on
const word = splitInput[splitInput.length - 1];
let matches = [];
//Run through dictionary sets
for(let set of Object.keys(dictionary)){
//Go through the current definitions of the current dictionary set
//I went with a for loop instead of a filter beacuse I wanted to pull the processed definition with pre/postfix
//and also directly push it into a shared array :P
for(let cmd of dictionary[set].cmds){
//Append the proper prefix/postfix to the current command
const definition = (`${dictionary[set].prefix}${cmd}${dictionary[set].postfix}`)
//if definition starts with the current word
if(word == '' ? false : definition.indexOf(word) == 0){
//Add definition to match list
matches.push(definition);
}
}
}
//If we found jack shit
if(matches.length == 0){
//Return jack shit
return {
match: '',
word
};
//If we got something
}else{
//return our top match
return {
match: matches[0],
word
};
}
}
handleClientInfo(data){

View file

@ -143,22 +143,56 @@ class commandPreprocessor{
return foundEmote;
}
getEmoteNames(){
//Create an empty array to hold names
let names = [];
//For every set of emotes
for(let set of Object.keys(this.emotes)){
//for every emote in the current set of emotes
for(let emote of this.emotes[set]){
//push the name of the emote to the name list
names.push(emote.name);
}
}
//return our list of names
return names;
}
buildAutocompleteDictionary(){
//This isn't complete, just a placeholder for now
let dictionary = {
tokes: [
"toke"
],
serverCMD: [
"whisper",
"announce",
"serverannounce",
"clear",
"kick"
],
localCMD:[
"high"
]
tokes: {
prefix: '!',
postfix: '',
cmds: [
"toke"
]
},
serverCMD: {
prefix: '!',
postfix: '',
cmds: [
"whisper",
"announce",
"serverannounce",
"clear",
"kick"
]
},
localCMD:{
prefix: '/',
postfix: '',
cmds: [
"high"
]
},
emotes:{
prefix:'[',
postfix:']',
cmds: this.getEmoteNames()
}
};
return dictionary;