diff --git a/.env.example b/.env.example index 00d8e05..4c3a3ea 100644 --- a/.env.example +++ b/.env.example @@ -41,6 +41,9 @@ CRYPTO_KEY=f30b91e92d77a06c59b20b2272e2cfbc # Soglia in percentuale del target tempo giornaliero per l'attivazione delle frasi demotivazionali (es. 70 per il 70%) PHRASE_THRESHOLD=70 +# Immagine ironica mostrata in caso di overperformance (default over9000.jpg nella cartella public/img) +OVERPERFORMANCE_IMAGE=over9000.jpg + # Configurazioni per la consuntivazione automatica fine giornata AUTO_TIME_MIN_HOUR=18:00 AUTO_TIME_QUEUE=Assistenza diff --git a/img/over9000.jpg b/img/over9000.jpg new file mode 100644 index 0000000..fc403b4 Binary files /dev/null and b/img/over9000.jpg differ diff --git a/public/css/style.css b/public/css/style.css index 183c8ef..c847a7d 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -2403,8 +2403,8 @@ body { .timer-tooltip { position: absolute; left: 105%; - top: 50%; - transform: translateY(-50%) translateX(-8px); + top: -5px; + transform: translateX(-8px); width: 290px; background: var(--bg-secondary); border: 1px solid var(--border-light); @@ -2423,7 +2423,7 @@ body { .timer-tooltip::after { content: ""; position: absolute; - top: 50%; + top: 18px; right: 100%; transform: translateY(-50%); border-width: 6px; @@ -2433,7 +2433,7 @@ body { .timer-tooltip-border { position: absolute; - top: 50%; + top: 18px; right: 100%; transform: translateY(-50%); border-width: 7px; @@ -2444,7 +2444,7 @@ body { .sidebar-timer:hover .timer-tooltip { opacity: 1; - transform: translateY(-50%) translateX(0); + transform: translateX(0); pointer-events: auto; } diff --git a/public/img/over9000.jpg b/public/img/over9000.jpg new file mode 100644 index 0000000..e3579fd Binary files /dev/null and b/public/img/over9000.jpg differ diff --git a/public/img/over_110.jpg b/public/img/over_110.jpg new file mode 100644 index 0000000..63dec26 Binary files /dev/null and b/public/img/over_110.jpg differ diff --git a/public/img/over_120.jpg b/public/img/over_120.jpg new file mode 100644 index 0000000..48d2724 Binary files /dev/null and b/public/img/over_120.jpg differ diff --git a/public/img/over_130.jpg b/public/img/over_130.jpg new file mode 100644 index 0000000..4154efb Binary files /dev/null and b/public/img/over_130.jpg differ diff --git a/public/img/over_140.jpg b/public/img/over_140.jpg new file mode 100644 index 0000000..7f1f7a1 Binary files /dev/null and b/public/img/over_140.jpg differ diff --git a/public/img/over_150.jpg b/public/img/over_150.jpg new file mode 100644 index 0000000..3aa4075 Binary files /dev/null and b/public/img/over_150.jpg differ diff --git a/public/js/app.js b/public/js/app.js index 6457ca5..369b2f3 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -23,7 +23,7 @@ const App = { if (saved) this.tabs = JSON.parse(saved); const savedDrafts = localStorage.getItem('otrs_turbo_drafts'); if (savedDrafts) this.drafts = JSON.parse(savedDrafts); - } catch (e) {} + } catch (e) { } this.renderTabs(); }, @@ -80,7 +80,7 @@ const App = { if (e) e.stopPropagation(); this.tabs = this.tabs.filter(t => String(t.id) !== String(id)); this.saveTabs(); - + // Clear drafts for closed tab delete this.drafts[id]; localStorage.setItem('otrs_turbo_drafts', JSON.stringify(this.drafts)); @@ -104,9 +104,9 @@ const App = { return; } bar.style.display = 'flex'; - + const currentHash = window.location.hash; - + bar.innerHTML = this.tabs.map(t => { const isActive = currentHash === `#/tickets/${t.id}`; const hasEmailDraft = this.getDraft(t.id, 'email'); @@ -756,6 +756,32 @@ const App = { } } + const overDelta = Math.max(0, mathematicalPercentage - 100); + const visualBarWidth = hasOverperformance ? (100 + (overDelta * 3.5)) : percentage; + + let overImgName = 'over9000.jpg'; + let overPhraseText = ''; + + if (mathematicalPercentage > 150) { + overImgName = this.lookups?.config?.overperformanceImage || 'over9000.jpg'; + overPhraseText = "IT'S OVER 9000! Il livello di consuntivazione ha superato ogni limite!"; + } else if (mathematicalPercentage > 140) { + overImgName = 'over_150.jpg'; + overPhraseText = 'Questo livello di consuntivazione è impossibile.'; + } else if (mathematicalPercentage > 130) { + overImgName = 'over_140.jpg'; + overPhraseText = 'Io sono il principe dei Saiyan, non glielo permetterò'; + } else if (mathematicalPercentage > 120) { + overImgName = 'over_130.jpg'; + overPhraseText = 'Sono un Saiyan, non può consuntivare più di me.'; + } else if (mathematicalPercentage > 110) { + overImgName = 'over_120.jpg'; + overPhraseText = 'Non è possibile! La sua consuntivazione continua ad aumentare.'; + } else { + overImgName = 'over_110.jpg'; + overPhraseText = "C'è qualcosa di sicuro nella vita. Il più forte è al di sopra di tutti e può consuntivare tutto!"; + } + timerEl.innerHTML = `
⏱ ${todayTime} / ${targetTime} m @@ -764,21 +790,36 @@ const App = {
-
+
Progresso Giornaliero - ${mathematicalPercentage}% + ${mathematicalPercentage}% ${hasOverperformance ? '⚠️' : ''}
-
-
+
+
- ${hasOverperformance ? ` -
- ⚠️ Rilevata una overperformance allontanarsi dalla postazione immediatamente + ${hasOverperformance ? (() => { + const overImgSrc = (overImgName.startsWith('http://') || overImgName.startsWith('https://') || overImgName.startsWith('/')) ? overImgName : `img/${overImgName}`; + const imgWidth = Math.min(500, 180 + Math.round(overDelta * 10)); + return ` +
+ Rilevata una overperformance allontanarsi IMMEDIATAMENTE +
+
+ + Overperformance Meme + +
+ ${overPhraseText ? ` +
+ "${App.escapeHtml(overPhraseText)}" +
+ ` : ''} + `; + })() : ` +
+ "${phrase}"
- ` : ''} -
- "${phrase}" -
+ `}
`; // Update sidebar counts as well diff --git a/routes/lookups.js b/routes/lookups.js index 7f3e07c..1be8104 100644 --- a/routes/lookups.js +++ b/routes/lookups.js @@ -151,7 +151,8 @@ router.get('/config', async (req, res) => { phraseThreshold: parseInt(process.env.PHRASE_THRESHOLD, 10) || 70, autoTimeMinHour: process.env.AUTO_TIME_MIN_HOUR || '18:00', helpdeskEmail: process.env.OTRS_MAIL_BCC || '', - agentEmail: agentEmail + agentEmail: agentEmail, + overperformanceImage: process.env.OVERPERFORMANCE_IMAGE || 'over9000.jpg' }); });