more work

This commit is contained in:
Merith 2025-02-26 15:09:58 -08:00
parent 446eed292c
commit e88dcf0eaf
4 changed files with 184 additions and 110 deletions

View file

@ -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>

View file

@ -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")
}

76
main.go Normal file
View file

@ -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")
}

108
static/overlay.html Normal file
View file

@ -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>