Spaces:
Sleeping
Sleeping
File size: 10,130 Bytes
0f43e0e d8601d5 0f43e0e d8601d5 0f43e0e d8601d5 0f43e0e d8601d5 0f43e0e d8601d5 0f43e0e 2463705 0f43e0e 2463705 0f43e0e afc1774 0f43e0e d8601d5 0f43e0e d8601d5 0f43e0e d8601d5 0f43e0e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sentiment Analysis</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-900 text-white min-h-screen flex items-center justify-center font-sans p-4">
<div class="container mx-auto max-w-2xl w-full p-8 bg-gray-800 rounded-2xl shadow-2xl border border-gray-700">
<h1 class="text-4xl font-bold text-center mb-2 text-cyan-400">
Sentiment Analysis Engine
</h1>
<p id="modelName" class="text-center text-gray-400 mb-8 h-6">
(Loading model...)
</p>
<div id="errorDiv" class="hidden p-3 mb-4 bg-red-800 border border-red-600 text-red-100 rounded-lg">
<span id="errorMessage"></span>
</div>
<div class="mb-6 relative">
<label for="textInput" class="block text-lg font-medium text-gray-300 mb-2">
Enter your text:
</label>
<textarea id="textInput" rows="5"
class="w-full p-4 bg-gray-700 border border-gray-600 rounded-lg text-white text-base focus:ring-2 focus:ring-cyan-500 focus:outline-none transition duration-200"
placeholder="Type something... (e.g., 'I love this product!')"></textarea>
</div>
<div class="flex flex-col sm:flex-row gap-4">
<button id="analyzeButton"
class="w-full bg-cyan-600 hover:bg-cyan-500 text-white text-lg font-bold py-3 px-6 rounded-lg shadow-lg transition duration-300 ease-in-out transform hover:scale-105 flex items-center justify-center">
<svg id="spinner" class="animate-spin -ml-1 mr-3 h-5 w-5 text-white hidden"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z">
</path>
</svg>
<span id="buttonText">Analyze Sentiment</span>
</button>
<button id="clearButton"
class="w-full sm:w-auto bg-gray-600 hover:bg-gray-500 text-white font-bold py-3 px-6 rounded-lg transition duration-300">
Clear
</button>
</div>
<div id="result" class="mt-8 p-6 bg-gray-700 rounded-lg hidden border border-gray-600">
<h2 class="text-2xl font-semibold mb-4 text-gray-200">Analysis Result:</h2>
<div id="sentiment" class="text-4xl font-extrabold text-center flex items-center justify-center gap-4">
<span id="sentimentIcon"></span>
<span id="sentimentText"></span>
</div>
</div>
</div>
<script>
// Select all DOM elements
const textInput = document.getElementById('textInput');
const analyzeButton = document.getElementById('analyzeButton');
const clearButton = document.getElementById('clearButton');
const resultDiv = document.getElementById('result');
const sentimentText = document.getElementById('sentimentText');
const sentimentIcon = document.getElementById('sentimentIcon');
const modelNameEl = document.getElementById('modelName');
const errorDiv = document.getElementById('errorDiv');
const errorMessage = document.getElementById('errorMessage');
const spinner = document.getElementById('spinner');
const buttonText = document.getElementById('buttonText');
// API endpoints
const predictApi = 'https://anis80-sentiment-analysis-api.hf.space/predict';
const statusApi = 'https://anis80-sentiment-analysis-api.hf.space/status';
// Icon SVGs
const icons = {
positive: `<svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-green-400" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" /></svg>`,
negative: `<svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-red-400" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" /></svg>`,
neutral: `<svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-yellow-400" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM7 10a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0z" clip-rule="evenodd" /></svg>`,
other: `<svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-blue-400" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd" /></svg>`
};
// Fetch model status on page load
window.addEventListener('load', async () => {
try {
const response = await fetch(statusApi);
if (!response.ok) throw new Error('Status check failed');
const data = await response.json();
modelNameEl.textContent = `(Active Model: ${data.model_name || 'N/A'})`;
} catch (error) {
modelNameEl.textContent = '(Could not load model status)';
console.error('Error fetching status:', error);
}
});
// Analyze button click event
analyzeButton.addEventListener('click', async () => {
const text = textInput.value;
if (!text) {
showError('Please enter some text to analyze.');
return;
}
setLoading(true);
try {
const response = await fetch(predictApi, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: text })
});
let data;
const contentType = response.headers.get("content-type");
if (contentType && contentType.indexOf("application/json") !== -1) {
data = await response.json();
} else {
// If not JSON, probably an error page
const text = await response.text();
console.error('Non-JSON response:', text);
if (!response.ok) {
throw new Error('Server Error: ' + response.status + ' ' + response.statusText);
}
data = {}; // safe fallback
}
if (!response.ok) {
throw new Error(data.detail || 'Network response was not ok');
}
if (data.predicted_sentiment) {
displayResult(data.predicted_sentiment);
} else if (data.error) {
showError('Error from server: ' + data.error);
}
} catch (error) {
console.error('Fetch error:', error);
let errorMsg = 'Could not connect to the analysis server.';
if (error.message) {
errorMsg += ' Details: ' + error.message;
}
if (window.location.protocol === 'https:' && predictApi.startsWith('http:')) {
errorMsg += ' (Mixed Content Error: Cannot access HTTP API from HTTPS page)';
}
showError(errorMsg + ' Check console for more info.');
} finally {
setLoading(false);
}
});
// Clear button click event
clearButton.addEventListener('click', () => {
textInput.value = '';
resultDiv.classList.add('hidden');
errorDiv.classList.add('hidden');
});
// Function to manage loading state
function setLoading(isLoading) {
analyzeButton.disabled = isLoading;
if (isLoading) {
spinner.classList.remove('hidden');
buttonText.textContent = 'Analyzing...';
} else {
spinner.classList.add('hidden');
buttonText.textContent = 'Analyze Sentiment';
}
}
// Function to show error messages
function showError(message) {
errorMessage.textContent = message;
errorDiv.classList.remove('hidden');
resultDiv.classList.add('hidden');
}
// Function to display results
function displayResult(sentiment) {
sentimentText.textContent = sentiment;
const sentimentKey = sentiment.toLowerCase();
let iconSvg = icons.other; // Default
let colorClass = 'text-blue-400';
if (sentimentKey.includes('positive')) {
iconSvg = icons.positive;
colorClass = 'text-green-400';
} else if (sentimentKey.includes('negative')) {
iconSvg = icons.negative;
colorClass = 'text-red-400';
} else if (sentimentKey.includes('neutral')) {
iconSvg = icons.neutral;
colorClass = 'text-yellow-400';
}
sentimentIcon.innerHTML = iconSvg;
sentimentText.className = colorClass; // Only set color class
resultDiv.classList.remove('hidden');
errorDiv.classList.add('hidden');
}
</script>
</body>
</html> |