class IntroController {
constructor() {
this.state = { uploadedImages: [], isAnalyzing: false };
this.cacheEls();
if (!this.el.newsForm) return;
this.bind();
}
cacheEls() {
this.el = {
newsForm: document.getElementById('newsForm'),
newsText: document.getElementById('newsText'),
fileInput: document.getElementById('fileInput'),
uploadArea: document.getElementById('uploadArea'),
browseBtn: document.getElementById('browseBtn'),
imagePreviews: document.getElementById('imagePreviews'),
analyzeBtn: document.getElementById('analyzeBtn'),
clearBtn: document.getElementById('clearBtn'),
btnLoader: document.getElementById('btnLoader'),
charCounter: document.getElementById('charCounter'),
messageContainer: document.getElementById('messageContainer')
};
}
bind() {
this.el.newsText.addEventListener('input', () => this.updateCharCount());
this.el.browseBtn.addEventListener('click', () => this.el.fileInput.click());
this.el.fileInput.addEventListener('change', (e) => this.handleFileSelect(e));
this.el.uploadArea.addEventListener('click', () => this.el.fileInput.click());
this.el.uploadArea.addEventListener('dragover', (e) => this.dragOver(e));
this.el.uploadArea.addEventListener('dragleave', (e) => this.dragLeave(e));
this.el.uploadArea.addEventListener('drop', (e) => this.drop(e));
this.el.newsForm.addEventListener('submit', (e) => this.submit(e));
this.el.clearBtn.addEventListener('click', () => this.clearAll());
}
updateCharCount() {
const len = this.el.newsText.value.length;
this.el.charCounter.textContent = `${len}/10000`;
if (len > 9000) this.el.charCounter.style.color = 'var(--accent-error)';
else if (len > 7000) this.el.charCounter.style.color = 'var(--accent-warning)';
else this.el.charCounter.style.color = 'var(--text-muted)';
}
dragOver(e){ e.preventDefault(); this.el.uploadArea.classList.add('drag-over'); }
dragLeave(e){ e.preventDefault(); this.el.uploadArea.classList.remove('drag-over'); }
drop(e){ e.preventDefault(); this.el.uploadArea.classList.remove('drag-over'); this.processFiles(Array.from(e.dataTransfer.files)); }
handleFileSelect(e){ this.processFiles(Array.from(e.target.files)); this.el.fileInput.value = ''; }
processFiles(files){
files.forEach(file=>{
if(!file.type.startsWith('image/')){ this.toast('Invalid File','Please upload only image files','error'); return; }
if(file.size > 10*1024*1024){ this.toast('File Too Large','Image must be smaller than 10MB','error'); return; }
const reader=new FileReader();
reader.onload=(ev)=>{
const imageData={ id:Date.now()+Math.random(), name:file.name, size:this.hSize(file.size), data:ev.target.result };
this.state.uploadedImages.push(imageData);
this.renderPreview(imageData);
};
reader.readAsDataURL(file);
});
}
hSize(bytes){
if(bytes===0) return '0 B';
const k=1024, sizes=['B','KB','MB']; const i=Math.floor(Math.log(bytes)/Math.log(k));
return `${parseFloat((bytes/Math.pow(k,i)).toFixed(1))} ${sizes[i]}`;
}
renderPreview(imageData){
const el=document.createElement('div');
el.className='preview-item';
el.innerHTML=`
`;
this.el.imagePreviews.appendChild(el);
el.querySelector('.remove-btn').addEventListener('click',()=>this.removeImage(imageData.id));
}
removeImage(id){
this.state.uploadedImages=this.state.uploadedImages.filter(x=>x.id!==id);
const btn=this.el.imagePreviews.querySelector(`[data-id="${id}"]`);
btn?.closest('.preview-item')?.remove();
}
async submit(e){
e.preventDefault();
if(!this.validate()){ this.toast('Missing Information','Please add both text and at least one image.','error'); return; }
if(this.state.isAnalyzing) return;
this.state.isAnalyzing=true; this.el.analyzeBtn.disabled=true; this.el.btnLoader.classList.add('active');
this.el.analyzeBtn.querySelector('.btn-text').textContent='Analyzing...';
try{
const payload={ text:this.el.newsText.value.trim(), images:this.state.uploadedImages.map(img=>({name:img.name,data:img.data})) };
const res=await fetch('/analyze',{ method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify(payload) });
const json=await res.json();
if(json.success){ window.location.href=`/analysis/${json.analysis_id}`; }
else{ throw new Error(json.error || 'Analysis failed'); }
}catch(err){
console.error(err); this.toast('Analysis Failed', err.message,'error');
}finally{
this.state.isAnalyzing=false; this.el.analyzeBtn.disabled=false; this.el.btnLoader.classList.remove('active');
this.el.analyzeBtn.querySelector('.btn-text').textContent='Analyze News';
}
}
validate(){ return this.el.newsText.value.trim().length>0 && this.state.uploadedImages.length>0; }
clearAll(){
this.el.newsText.value=''; this.state.uploadedImages=[]; this.el.imagePreviews.innerHTML=''; this.updateCharCount();
this.toast('Cleared','All inputs have been reset.','success');
}
toast(title,text,type='info'){
const msg=document.createElement('div'); msg.className=`message ${type}`;
msg.innerHTML=`