From 8248cbb56fbfe3866638763e760d0af184548f6c Mon Sep 17 00:00:00 2001 From: Klemek Date: Fri, 21 Feb 2025 19:38:58 +0100 Subject: [PATCH] DAISY UI --- index.html | 346 +++++++++++++++++++++++++++++++++++++++-------------- main.js | 112 +++++++++++++---- style.css | 154 ++---------------------- 3 files changed, 354 insertions(+), 258 deletions(-) diff --git a/index.html b/index.html index 920e22e..2b376dc 100644 --- a/index.html +++ b/index.html @@ -7,6 +7,17 @@ + + + @@ -14,104 +25,261 @@ - -
-
-

Meeting Roulette

-
-
    -
  • - Meeting started at: {{ timeText(startedAt, 2) }} -
  • -
  • - Meeting duration so far: {{ timeText(elapsedTime) }} -
  • -
  • - Remaining meeting time: {{ timeText(totalRemainingTime) }} -
  • -
  • - End estimated at: {{ timeText(estimatedEnd, 2) }} -
  • -
  • - Total meeting time: {{ timeText(totalTime) }} -
  • -
  • -   -
  • -
-
-
-   + +
+
+
+
+ Meeting Roulette +
+

🎡 Spin your meetings

+
+
+ + {{ timerParts(0) }} + {{ timerParts(1) }} + : + {{ timerParts(2) }} + : + {{ timerParts(3) }} + +
+
+ +
-

- - {{ timerText() }} - -

-
-
-

Current topic: {{ showSelected ? selectedData.text : '???' }}

-

- click to spin -

-
- - - - - +
+
Meeting duration so far
+
+ {{ timeText(elapsedTime) }} +
+
+ Started at: {{ timeText(startedAt, 2) }} +
+
+
+
Remaining meeting time
+
+ {{ timeText(totalRemainingTime) }} +
+
+ End estimated at: {{ timeText(estimatedEnd, 2) }} +
+
+
+
Total meeting time
+
+ {{ timeText(totalTime) }} +
+
+ Overtime: {{ timeText(overtimeTime) }} +
+
+
+
+
+
-
- +
+
+ Current topic: {{ showSelected ? selectedData.text : '???' }} +
+
+
+ + + + + + {{ d.text }} + + + + +
+
+
+
Discuss the current topic
+
+ Enter your topics then click the wheel to spin ! +
+
+ Start timer or click the wheel to spin +
+
 
+
+
+
+ +
+
+ +
+
+
+ @klemek + - + Github + - 2025 +
diff --git a/main.js b/main.js index 6064add..c05f080 100644 --- a/main.js +++ b/main.js @@ -1,3 +1,37 @@ +const DAISYUI_THEMES = [ + "light", + "dark", + "cupcake", + "bumblebee", + "emerald", + "corporate", + "synthwave", + "retro", + "cyberpunk", + "valentine", + "halloween", + "garden", + "forest", + "aqua", + "pastel", + "fantasy", + "luxury", + "dracula", + "cmyk", + "autumn", + "business", + "acid", + "lemonade", + "night", + "coffee", + "winter", + "dim", + "nord", + "sunset", + "caramellatte", + "abyss", +]; + let app = { data() { return { @@ -15,10 +49,12 @@ let app = { meetingStart: new Date(), elapsedTime: 0, initialSpin: true, - initialColor: Math.random() * 360, + initialColor: Math.floor(Math.random() * 4), rid: 0, beepTimer: undefined, sound: undefined, + themes: DAISYUI_THEMES, + currentTheme: "light", }; }, watch: { @@ -43,9 +79,7 @@ let app = { return this.elapsedTime + this.totalRemainingTime; }, totalExpectedTime() { - return this.data - .map((item) => item.time) - .reduce((a, b) => a + b, 0); + return this.data.map((item) => item.time).reduce((a, b) => a + b, 0); }, totalRemainingTime() { return this.filteredData @@ -62,7 +96,9 @@ let app = { estimatedEnd() { const end = new Date(this.meetingStart.getTime()); const timerDelta = (this.timerEnd - this.date) / (1000 * 60); - end.setMinutes(end.getMinutes() + this.totalTime - (this.timerStarted ? timerDelta : 0)); + end.setMinutes( + end.getMinutes() + this.totalTime - (this.timerStarted ? timerDelta : 0) + ); return end.getHours() * 60 + end.getMinutes(); }, svgData() { @@ -75,6 +111,12 @@ let app = { const angleDeg = (360 * ratio) % 360; const textScale = this.textScale(item.text, angleRad); totalAngle += angleDeg; + const colorIndex = + ((index == this.filteredData.length - 1 && index % 4 == 0 ? 1 : 0) + + index + + this.initialColor) % + 4; + const color = ["primary", "secondary", "accent", "neutral"][colorIndex]; return { id: item.id, text: item.text, @@ -86,7 +128,8 @@ let app = { angleRad / 2 )} ${Math.sin(angleRad / 2)} z`, transform: `rotate(${totalAngle - angleDeg / 2}, 0, 0)`, - color: `hsl(${this.initialColor + 100 * index} 80% 50%)`, + textStyle: `fill: var(--color-${color}-content)`, + backgroundStyle: `fill: var(--color-${color})`, from: totalAngle - angleDeg, to: totalAngle, }; @@ -103,22 +146,36 @@ let app = { overtime() { return this.timerStarted && this.timerEnd - new Date() <= 0; }, - timerText() { + timerParts(i) { const delta = this.timerStarted ? Math.floor((this.timerEnd - new Date()) / 1000) - : (this.showSelected - ? this.selectedData.time * 60 - : 0); - return `${delta < 0 ? "-" : ""}${String( - Math.floor(Math.abs(delta) / 60) - ).padStart(2, "0")}:${String(Math.abs(delta) % 60).padStart(2, "0")}`; + : this.showSelected + ? this.selectedData.time * 60 + : 0; + if (i == 0) { + return delta < 0 ? "-" : ""; + } + const hours = Math.floor(Math.abs(delta) / 3600); + if (i == 1) { + return String(hours).padStart(2, "0"); + } + const minutes = Math.floor(Math.abs(delta) / 60 - hours * 60); + if (i == 2) { + return String(minutes).padStart(2, "0"); + } + const seconds = Math.abs(delta) % 60; + return String(seconds).padStart(2, "0"); }, beep() { this.sound.play(); }, timeText(minutes, padHours = 0) { if (minutes >= 60 || padHours > 0) { - return `${Math.floor(minutes / 60).toFixed(0).padStart(padHours, "0")}h${(minutes % 60).toFixed(0).padStart(2, "0")}`; + return `${Math.floor(minutes / 60) + .toFixed(0) + .padStart(padHours, "0")}h${(minutes % 60) + .toFixed(0) + .padStart(2, "0")}`; } else { return `${(minutes % 60).toFixed(0).padStart(2, "0")}min`; } @@ -173,12 +230,14 @@ let app = { } }); if (data.length === 0) { - return [{ - id: 0, - text: '?', - time: 1, - disabled: false, - }]; + return [ + { + id: 0, + text: "?", + time: 1, + disabled: false, + }, + ]; } return data; }, @@ -217,7 +276,7 @@ let app = { }, setCookie(cname, cvalue, exdays) { const d = new Date(); - d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); + d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000); let expires = "expires=" + d.toUTCString(); console.log(cname + "=" + cvalue + "; path=/; " + expires); document.cookie = cname + "=" + cvalue + "; path=/; " + expires; @@ -225,7 +284,7 @@ let app = { getCookie(cname, defaultValue) { let name = cname + "="; let decodedCookie = decodeURIComponent(document.cookie); - let ca = decodedCookie.split(';'); + let ca = decodedCookie.split(";"); for (let i = 0; i < ca.length; i++) { let c = ca[i]; while (c.charAt(0) == " ") { @@ -237,17 +296,24 @@ let app = { } return defaultValue; }, + setTheme(value) { + this.currentTheme = value; + this.setCookie("theme", this.currentTheme); + }, }, mounted: function () { console.log("app mounted"); this.sound = new Audio("./sound.wav"); this.rawData = atob(this.getCookie("rawData", btoa(this.rawData))); + this.currentTheme = this.getCookie("theme", "light"); this.data = this.getData(); setTimeout(this.showApp); setInterval(() => { this.rid = Math.random(); if (this.timerStarted) { - document.title = this.timerText(); + document.title = `${this.timerParts(0)}${this.timerParts( + 1 + )}:${this.timerParts(2)}:${this.timerParts(3)}`; } this.elapsedTime = (new Date() - this.meetingStart) / (1000 * 60); this.date = new Date(); diff --git a/style.css b/style.css index 9184782..0fa68d4 100644 --- a/style.css +++ b/style.css @@ -1,141 +1,13 @@ -/* -================================================= -https://www.joshwcomeau.com/css/custom-css-reset/ -================================================= -*/ - -/* - 1. Use a more-intuitive box-sizing model. -*/ -*, -*::before, -*::after { - box-sizing: border-box; -} -/* - 2. Remove default margin - */ -* { - margin: 0; -} -/* - 3. Allow percentage-based heights in the application - */ -html, -body { - height: 100%; -} -/* - Typographic tweaks! - 4. Add accessible line-height - 5. Improve text rendering - */ -body { - line-height: 1.5; - -webkit-font-smoothing: antialiased; -} -/* - 6. Improve media defaults - */ -img, -picture, -video, -canvas, -svg { - display: block; - max-width: 100%; -} -/* - 7. Remove built-in form typography styles - */ -input, -button, -textarea, -select { - font: inherit; -} -/* - 8. Avoid text overflows - */ -p, -h1, -h2, -h3, -h4, -h5, -h6 { - overflow-wrap: break-word; -} -/* - 9. Create a root stacking context - */ -#root, -#__next { - isolation: isolate; -} - -/* -================================================= -CUSTOM STYLE -================================================= -*/ - -#app { - width: 100vw; - height: 100vh; - overflow: hidden; - position: relative; - display: flex; - flex-direction: row; - justify-content: center; - align-items: stretch; - background-color: #eceff1; - color: #263238; - font-family: sans-serif; -} - -.panel { - flex-grow: 2; - position: relative; -} - -.panel.right, -.panel.left { - background-color: #cfd8dc; - margin: 1em; - border-radius: 2em; - padding: 1em; -} - -.panel.middle { - height: 100%; - flex-grow: 1; -} - -.panel.middle h1 { - position: absolute; - top: 0; - width: 100%; - text-align: center; -} - -.panel.middle h2 { - position: absolute; - bottom: 0; - width: 100%; - text-align: center; -} - -.wheel { - position: relative; - height: 80%; - width: fit-content; - margin: 10% auto; +:root { + --wheel: color-mix( + in oklch, + var(--color-base-content) 30%, + var(--color-base-100) + ); } .wheel svg { transition: transform 5s ease-out; - height: 100%; } svg text { @@ -153,20 +25,10 @@ svg text { top: 50%; width: 0; height: 0; - border-right: 6vh solid #263238; + border-right: 6vh solid + color-mix(in oklch, var(--color-base-content) 40%, var(--color-base-100)); border-bottom: 2vh solid transparent; border-top: 2vh solid transparent; transform: translateY(-50%); clear: both; } - -.panel.right textarea { - background-color: #cfd8dc; - color: #263238; - font-family: sans-serif; - padding: 0.5em; - border: 1px solid #263238; - height: 100%; - width: 100%; - border-radius: 1em; -}