From e88dcf0eafa20ad474be8f5b705d6f0db07b5267 Mon Sep 17 00:00:00 2001
From: Merith <merith@merith.xyz>
Date: Wed, 26 Feb 2025 15:09:58 -0800
Subject: [PATCH] more work

---
 cmd/m3r1-chat/chat.html |  47 -----------------
 cmd/m3r1-chat/main.go   |  63 -----------------------
 main.go                 |  76 ++++++++++++++++++++++++++++
 static/overlay.html     | 108 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 184 insertions(+), 110 deletions(-)
 delete mode 100644 cmd/m3r1-chat/chat.html
 delete mode 100644 cmd/m3r1-chat/main.go
 create mode 100644 main.go
 create mode 100644 static/overlay.html

diff --git a/cmd/m3r1-chat/chat.html b/cmd/m3r1-chat/chat.html
deleted file mode 100644
index a8c0e37..0000000
--- a/cmd/m3r1-chat/chat.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>Minecraft Twitch Chat Overlay</title>
-    <style>
-        body {
-            background-color: transparent;
-            color: white;
-            font-family: 'Minecraft', sans-serif;
-            font-size: 16px;
-            margin: 0;
-            padding: 0;
-            overflow: hidden;
-        }
-        #chat {
-            position: absolute;
-            bottom: 0;
-            left: 0;
-            width: 100%;
-            height: 30%;
-            padding: 10px;
-            box-sizing: border-box;
-            background-color: rgba(0, 0, 0, 0.5);
-            overflow-y: auto;
-        }
-        .message {
-            margin-bottom: 5px;
-        }
-    </style>
-</head>
-<body>
-    <div id="chat"></div>
-    <script>
-        async function fetchChat() {
-            const response = await fetch('/chat');
-            const data = await response.json();
-            const chat = document.getElementById('chat');
-            chat.innerHTML = data.messages.map(msg => `<div class="message">${msg}</div>`).join('');
-            chat.scrollTop = chat.scrollHeight;
-        }
-
-        setInterval(fetchChat, 1000);
-    </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/cmd/m3r1-chat/main.go b/cmd/m3r1-chat/main.go
deleted file mode 100644
index 3725a4e..0000000
--- a/cmd/m3r1-chat/main.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package main
-
-import (
-	"fmt"
-	"log"
-	"sync"
-
-	_ "embed"
-
-	"github.com/gempir/go-twitch-irc/v4"
-	"github.com/gin-gonic/gin"
-)
-
-var (
-	messages []string
-	mu       sync.Mutex
-)
-
-// go:embed chat.html
-var defaultHTML []byte
-
-func main() {
-	// Set up Twitch client
-	client := twitch.NewClient("your_bot_username", "oauth:your_oauth_token")
-
-	// Set up Gin web server
-	r := gin.Default()
-
-	// Serve static files (HTML, CSS, JS)
-	r.Static("/static", "./static")
-
-	// Endpoint to get chat messages
-	r.GET("/chat", func(c *gin.Context) {
-		mu.Lock()
-		defer mu.Unlock()
-		c.JSON(200, gin.H{
-			"messages": messages,
-		})
-	})
-
-	// Handle Twitch chat messages
-	client.OnPrivateMessage(func(message twitch.PrivateMessage) {
-		mu.Lock()
-		defer mu.Unlock()
-		messages = append(messages, fmt.Sprintf("%s: %s", message.User.Name, message.Message))
-		if len(messages) > 100 { // Keep only the last 100 messages
-			messages = messages[1:]
-		}
-	})
-
-	// Connect to Twitch chat
-	client.Join("merithtk")
-
-	go func() {
-		err := client.Connect()
-		if err != nil {
-			log.Fatalf("Error connecting to Twitch: %v", err)
-		}
-	}()
-
-	// Start the web server
-	r.Run(":8080")
-}
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..997e2ca
--- /dev/null
+++ b/main.go
@@ -0,0 +1,76 @@
+package main
+
+import (
+	"fmt"
+	"log"
+	"sync"
+
+	_ "embed"
+
+	"github.com/gempir/go-twitch-irc/v4"
+	"github.com/gin-gonic/gin"
+)
+
+var (
+	// Store chat messages for each channel
+	channelMessages = make(map[string][]string)
+	mu              sync.Mutex
+)
+
+func main() {
+	// Set up Twitch client
+	client := twitch.NewAnonymousClient() // No need to log in as a bot
+
+	// Set up Gin web server
+	r := gin.Default()
+
+	// Serve static files (HTML, CSS, JS)
+	r.Static("/static", "./static")
+
+	// Endpoint to get chat messages for a specific channel
+	r.GET("/chat/:channel", func(c *gin.Context) {
+		channel := c.Param("channel")
+		mu.Lock()
+		defer mu.Unlock()
+		messages, exists := channelMessages[channel]
+		if !exists {
+			c.JSON(200, gin.H{
+				"messages": []string{},
+			})
+			return
+		}
+		c.JSON(200, gin.H{
+			"messages": messages,
+		})
+	})
+
+	// Handle Twitch chat messages
+	client.OnPrivateMessage(func(message twitch.PrivateMessage) {
+		mu.Lock()
+		defer mu.Unlock()
+		channel := message.Channel
+		messages := channelMessages[channel]
+		messages = append(messages, fmt.Sprintf("%s: %s", message.User.Name, message.Message))
+		if len(messages) > 100 { // Keep only the last 100 messages
+			messages = messages[1:]
+		}
+		channelMessages[channel] = messages
+	})
+
+	// Automatically join channels when requested
+	r.GET("/chat/:channel/overlay", func(c *gin.Context) {
+		channel := c.Param("channel")
+		client.Join(channel)            // Join the channel if not already joined
+		c.File("./static/overlay.html") // Serve the overlay HTML
+	})
+
+	// Start the web server
+	go func() {
+		err := client.Connect()
+		if err != nil {
+			log.Fatalf("Error connecting to Twitch: %v", err)
+		}
+	}()
+
+	r.Run(":8080")
+}
diff --git a/static/overlay.html b/static/overlay.html
new file mode 100644
index 0000000..e6a662b
--- /dev/null
+++ b/static/overlay.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Minecraft Twitch Chat Overlay</title>
+    <style>
+        /* Import Minecraft font */
+        @import url('https://fonts.googleapis.com/css2?family=Minecraft&display=swap');
+
+        body {
+            background-color: transparent;
+            margin: 0;
+            padding: 0;
+            overflow: hidden;
+        }
+
+        #chat {
+            position: absolute;
+            bottom: 0;
+            left: 0;
+            width: 100%;
+            height: 30%;
+            padding: 10px;
+            box-sizing: border-box;
+            overflow-y: auto;
+            display: flex;
+            flex-direction: column;
+            justify-content: flex-end;
+            background-color: transparent;
+        }
+
+        .message {
+            font-family: 'Minecraft', sans-serif;
+            font-size: 16px;
+            color: white;
+            text-shadow: 2px 2px 0 #3f3f3f;
+            margin-bottom: 5px;
+            opacity: 0;
+            animation: fadeIn 0.5s ease-in-out forwards;
+        }
+
+        @keyframes fadeIn {
+            from {
+                opacity: 0;
+                transform: translateY(10px);
+            }
+            to {
+                opacity: 1;
+                transform: translateY(0);
+            }
+        }
+
+        /* Fade out older messages */
+        .message.fade-out {
+            animation: fadeOut 0.5s ease-in-out forwards;
+        }
+
+        @keyframes fadeOut {
+            from {
+                opacity: 1;
+                transform: translateY(0);
+            }
+            to {
+                opacity: 0;
+                transform: translateY(-10px);
+            }
+        }
+    </style>
+</head>
+<body>
+    <div id="chat"></div>
+    <script>
+        // Extract the channel name from the URL
+        const channel = window.location.pathname.split('/')[2];
+
+        // Function to fetch chat messages
+        async function fetchChat() {
+            const response = await fetch(`/chat/${channel}`);
+            const data = await response.json();
+            const chat = document.getElementById('chat');
+
+            // Clear existing messages
+            chat.innerHTML = '';
+
+            // Add new messages with fade-in animation
+            data.messages.forEach((msg, index) => {
+                const messageElement = document.createElement('div');
+                messageElement.classList.add('message');
+                messageElement.textContent = msg;
+
+                // Fade out older messages if there are more than 10
+                if (data.messages.length > 10 && index < data.messages.length - 10) {
+                    messageElement.classList.add('fade-out');
+                }
+
+                chat.appendChild(messageElement);
+            });
+
+            // Scroll to the bottom
+            chat.scrollTop = chat.scrollHeight;
+        }
+
+        // Fetch chat messages every second
+        setInterval(fetchChat, 1000);
+    </script>
+</body>
+</html>
\ No newline at end of file