Skip to content

Commit

Permalink
Merge pull request #1 from syke9p3/feat/saving
Browse files Browse the repository at this point in the history
date generation
  • Loading branch information
syke9p3 authored Jul 21, 2024
2 parents 5ed3bcf + b0c2893 commit 9511011
Show file tree
Hide file tree
Showing 7 changed files with 219 additions and 15 deletions.
62 changes: 53 additions & 9 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { classify, modelStatus } from "./javascript/classifier.js"
import { countCharacters, isValidCharacterCount, typeWriter, updateLabelsContainer } from "./javascript/utils.js"
import { countCharacters, generateDate, getDate, getTime, isValidCharacterCount, typeWriter, updateLabelsContainer } from "./javascript/utils.js"

export const globalState = {
prevInput: '',
Expand All @@ -15,9 +15,13 @@ const clearButton = document.getElementById("clear-btn");
const exampleSelector = document.getElementById("sample-hate-speech");
const wordCountDisplay = document.getElementById("word-count");
const labelsContainer = document.getElementById("labels-container");
const outputContainer = document.getElementById("output-container");
const inputDisplayContainer = document.getElementById("input-display-container");
const inputDisplay = document.getElementById("input-display");
const inputDisplayText = document.getElementById("input-display-text");
const inputDisplayDate = document.getElementById("input-display-date");
const tweetTime = document.getElementById("tweet-time");
const tweetDate = document.getElementById("tweet-date");
const outputDisplay = document.getElementById("output-display");
const loadingDisplay = document.getElementById("loading-display");
const modelStatusDisplay = document.getElementById("model-status");
Expand Down Expand Up @@ -153,18 +157,28 @@ const setInputFieldValue = (text) => {
}

const updateSubmitButtonState = () => {
const wordCount = globalState.wordCount;
const prevInput = globalState.prevInput;

console.group("updateSubmitButtonState: ")
console.log("wordcount: ", wordCount)
console.log("prevInput: ", prevInput)
console.groupEnd()
// console.group("updateSubmitButtonState: ")
// console.log("wordcount: ", wordCount)
// console.log("prevInput: ", prevInput)
// console.groupEnd()

// Disable the submit button if input is invalid or data is being fetched
submitButton.disabled = !isValidCharacterCount(wordCount) || globalState.isLoading || globalState.prevInput === inputField.value;
submitButton.disabled = !isValidCharacterCount(globalState.wordCount) || globalState.isLoading || globalState.prevInput === inputField.value;
};

const displayDateToInputDisplay = () => {
const newDate = generateDate();
const time = getTime(newDate);
const date = getDate(newDate);

tweetTime.textContent = time;
tweetDate.textContent = date;

inputDisplayDate.style.display = "flex";

}

/**
* Takes a string and displays it to the input display in output UI.
* @param {string | {label: string, score: number}[]} output an array of labels and scores sorted by descending scores
Expand All @@ -175,6 +189,9 @@ const updateInputDisplay = (inputText) => {
inputDisplayContainer.style.display = "grid"
// inputDisplayText.textContent = inputText
typeWriter(inputDisplayText, inputText);
displayDateToInputDisplay();


}

/**
Expand Down Expand Up @@ -230,7 +247,6 @@ const updateLoadingDisplay = (isLoading) => {
labelsContainer.classList.remove("fade-out");


} else {
}
}

Expand All @@ -257,6 +273,8 @@ clearButton.onclick = (e) => {
// TEST: should reset the exampleOptions to default
// TEST: should reset word count

inputField.scrollIntoView({ behavior: "smooth" });

inputField.value = "";
updateInput()
exampleSelector.selectedIndex = 0;
Expand All @@ -270,6 +288,8 @@ clearButton.onclick = (e) => {
*/
const handleSubmitInput = async (input) => {

outputContainer.scrollIntoView({ behavior: "smooth" });

// TEST: should get output from the classifier if successful
// TEST: should display output to the UI

Expand Down Expand Up @@ -335,3 +355,27 @@ exampleSelector.oninput = () => {
handleInputChange()
debugGlobalState()
}


/** TODO
* @TODO set title attribute to analyzeBtn on hover when same prevInput and input
* @TODO date and time to post
* @TODO save results to local storage
* @TODO retrieve from local storage and display to UI
* @TODO filter results
* @TODO pagination
* @TODO count and graph results
* @TODO export as csv
* @TODO dark mode
* @TODO guide below as an article
* @TODO description for the labels with icons/emoji (take from github readme)
*/

/** FEATURES
* @FEAT input text
* @FEAT hate speech examples
* @FEAT word counter
* @FEAT clear input field
* @FEAT post like display
* @FEAT hate speech categories display
*/
21 changes: 16 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,15 @@ <h1 class="banner-title">
the system requires a minimum of <u>3 characters</u> and accepts up to a
maximum of <u>280 characters</u>.
</p>

</div>
</section>
<!-- <section>
<div>
<p>icon</p>
<p><b>Age</b></p>
<p><b>Age</b></p>
</div>
</section> -->



Expand Down Expand Up @@ -146,6 +152,11 @@ <h4 class="">MLTHSC</h4>
Let's analyze Tagalog hate speech tweet according to Age, Gender, Physical, Race, Religion
and Others.
</span>
<span id="input-display-date">
<div id="tweet-time">3:41:55 AM</div>
<div class="tweet-date-separator"></div>
<div id="tweet-date">22 Jan 2023</div>
</span>
</div>
</div>
</div>
Expand Down Expand Up @@ -248,14 +259,14 @@ <h4>Saved Posts</h4>
<div id="pagination-controls" class="pagination"></div>
</section>

<!-- Stats -->
<!-- <!-- Stats --/>
<article id="stats">
<div class="flex justify-between align-center section-header" style="padding-bottom: 10px">
<h4>Most Frequent Labels Based on Saved</h4>
</div>
<!-- No posts Container (Displayed when no labels are identified) -->
<div id="no-chart-container" style="display: none">
<!-- No posts Container (Displayed when no labels are identified) --/>
<div id="no-chart-container">
<div class="analyze_container result-fade-in">
<p>No data to analyze.</p>
</div>
Expand All @@ -267,7 +278,7 @@ <h4>Most Frequent Labels Based on Saved</h4>
</div>
<div id="legendContainer" class="legend-container"></div>
</div>
</article>
</article> -->

<!-- Webapp Instructions Section -->
<section class="instruction">
Expand Down
74 changes: 74 additions & 0 deletions javascript/events.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { classify } from "./classifier.js";
import { setGlobalInput, setGlobalWordCount, setGlobalOutput, globalState } from './state.js';
import { updateWordCountDisplay, updateOutputDisplay, setInputFieldValue, getWordCountFromInputField } from './ui.js';
import { isValidWordCount, countWords } from './utils.js';

const inputField = document.getElementById("input-text");
const submitButton = document.getElementById("analyze-btn");
const clearButton = document.getElementById("clear-btn");
const exampleSelector = document.getElementById("sample-hate-speech");

const initializeGlobalState = () => {
setGlobalInput(inputField.value);
setGlobalWordCount(getWordCountFromInputField());
};

const updateWordCount = () => {
const wordCount = getWordCountFromInputField();
setGlobalWordCount(wordCount);
updateWordCountDisplay(wordCount);
};

const updateInput = () => {
setGlobalInput(inputField.value);
};

document.addEventListener("DOMContentLoaded", function () {
initializeGlobalState();
debug('globalState.input:', globalState.input);
debug('globalState.wordCount:', globalState.wordCount);
updateWordCountDisplay(globalState.wordCount);

inputField.oninput = () => {
updateInput();
updateWordCount();
debugGlobalState();
};

clearButton.onclick = () => {
inputField.value = "";
updateInput();
exampleSelector.selectedIndex = 0;
updateWordCount();
debugGlobalState();
};

submitButton.onclick = async () => {
const wordCount = globalState.wordCount;

if (!isValidWordCount(wordCount)) {
debug('Invalid word count, not submitting input.');
return;
}

debug('Submitting input...');
globalState.isLoading = true;

try {
const output = await classify(globalState.input);
setGlobalOutput(output);
updateOutputDisplay(globalState.output);
} finally {
globalState.isLoading = false;
}

debugGlobalState();
};

exampleSelector.oninput = () => {
setInputFieldValue(exampleSelector.value);
updateWordCount();
updateInput();
debugGlobalState();
};
});
Empty file added javascript/modal.js
Empty file.
Empty file added javascript/output.js
Empty file.
50 changes: 50 additions & 0 deletions javascript/state.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
class GlobalState {
constructor() {
this._input = '';
this._output = [];
this._isLoading = false;
this._wordCount = 0;
}

get input() {
return this._input;
}

set input(value) {
this._input = value;
}

get output() {
return this._output;
}

set output(value) {
this._output = value;
}

get isLoading() {
return this._isLoading;
}

set isLoading(value) {
this._isLoading = value;
}

get wordCount() {
return this._wordCount;
}

set wordCount(value) {
this._wordCount = value;
}

debugGlobalState() {
console.group('Global State Debug:');
console.log(`Global Input: ${this._input}`);
console.log(`Global Word Count: ${this._wordCount}`);
console.log('Global Output:', this._output);
console.groupEnd();
}
}

export const globalState = new GlobalState();
27 changes: 26 additions & 1 deletion javascript/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export function countCharacters(text) {
return count;
}


/**
* Takes a number and returns true if number is between 3 and 280
* @param {number} count number of words
Expand All @@ -18,6 +17,32 @@ export const isValidCharacterCount = (count) => {
return count >= 3 && count <= 280;
}


export const generateDate = () => {
console.log(new Date())
return new Date()
}

export const getTime = (date) => {
const time = date.toLocaleTimeString();
console.log(time)
return time;
}

export const getDate = (date) => {
const monthNames = [
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
];

const day = date.getDate();
const monthIndex = date.getMonth();
const year = date.getFullYear();

return `${day} ${monthNames[monthIndex]} ${year}`;
}


debug("output.js")

const labelsContainer = document.getElementById("labels-container");
Expand Down

0 comments on commit 9511011

Please sign in to comment.