Skip to content

Commit 68c31dd

Browse files
authored
Revamp index.html for 7TV Live Emote Tracker
Updated the HTML structure and styles for the 7TV Live Emote Tracker page, including new background images and improved leaderboard layout.
1 parent e25c6d6 commit 68c31dd

File tree

1 file changed

+133
-126
lines changed

1 file changed

+133
-126
lines changed

index.html

Lines changed: 133 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -2,153 +2,177 @@
22
<html lang="en">
33
<head>
44
<meta charset="UTF-8" />
5-
<title>7TV Emote Leaderboard</title>
5+
<title>7TV Live Emote Tracker</title>
66
<style>
7-
* { box-sizing: border-box; }
8-
7+
* {
8+
box-sizing: border-box;
9+
}
910
body {
11+
margin: 0;
1012
font-family: 'Inter', sans-serif;
11-
color: white;
13+
background: #0a0013;
14+
color: #fff;
1215
text-align: center;
13-
margin: 0;
14-
padding: 0;
15-
background: #0d0b12;
16+
min-height: 100vh;
17+
background-image: url("peepo.png");
18+
background-size: cover;
19+
background-position: center;
20+
background-attachment: fixed;
21+
background-repeat: no-repeat;
1622
overflow-x: hidden;
1723
}
1824

1925
body::before {
2026
content: "";
2127
position: fixed;
22-
top: 0; left: 0;
23-
width: 100%; height: 100%;
24-
background: url("8ccf8c6b-762b-4688-9be3-de591ca256b8-profile_image-300x300.png") center/cover no-repeat;
25-
filter: blur(20px) brightness(0.3);
28+
inset: 0;
29+
background: radial-gradient(circle at top left, rgba(90, 0, 255, 0.4), transparent),
30+
radial-gradient(circle at bottom right, rgba(180, 0, 255, 0.25), transparent),
31+
rgba(0, 0, 0, 0.85);
32+
backdrop-filter: blur(12px);
2633
z-index: -1;
2734
}
2835

2936
h1 {
30-
font-weight: 800;
37+
margin-top: 1.2rem;
3138
font-size: 2rem;
32-
color: #a770ff;
33-
margin-top: 2rem;
39+
color: #c8a9ff;
40+
text-shadow: 0 0 10px #a76eff, 0 0 25px #6b2cff;
41+
animation: glowPulse 2s infinite alternate;
3442
}
3543

36-
.controls {
37-
margin: 1.5rem auto;
44+
@keyframes glowPulse {
45+
from { text-shadow: 0 0 8px #9b59ff, 0 0 16px #823bff; }
46+
to { text-shadow: 0 0 18px #bb8cff, 0 0 32px #b57bff; }
3847
}
3948

40-
input {
41-
padding: 0.5rem 1rem;
49+
input, button {
50+
padding: 0.6rem 1rem;
51+
border: 2px solid #9146FF;
4252
border-radius: 10px;
43-
border: none;
44-
background: #1e1b24;
53+
background: #161024;
4554
color: white;
55+
margin: 0.5rem;
4656
font-size: 1rem;
47-
margin-right: 0.5rem;
57+
transition: 0.3s;
58+
box-shadow: 0 0 10px rgba(145, 70, 255, 0.3);
59+
}
60+
61+
input:focus {
62+
border-color: #b68cff;
4863
outline: none;
49-
border: 2px solid #7b4fff;
64+
box-shadow: 0 0 12px #b68cff;
5065
}
5166

5267
button {
53-
padding: 0.5rem 1rem;
54-
border-radius: 10px;
55-
border: none;
56-
font-size: 1rem;
68+
background: linear-gradient(90deg, #9146FF, #b88cff);
5769
cursor: pointer;
58-
color: white;
59-
background: linear-gradient(90deg, #7b4fff, #a770ff);
60-
transition: 0.2s;
70+
font-weight: bold;
71+
box-shadow: 0 0 12px #9146ff7a;
72+
}
73+
74+
button:hover {
75+
box-shadow: 0 0 18px #b88cff;
76+
transform: scale(1.03);
6177
}
6278

63-
button:hover { opacity: 0.8; }
79+
#title {
80+
margin-top: 0.8rem;
81+
font-size: 1.2rem;
82+
color: #c7b6ff;
83+
text-shadow: 0 0 8px #8f6cff;
84+
}
85+
86+
#tables {
87+
display: flex;
88+
justify-content: space-around;
89+
flex-wrap: wrap;
90+
margin-top: 2rem;
91+
}
6492

65-
.leaderboard {
66-
width: 80%;
67-
margin: 3rem auto;
93+
.table-container {
94+
width: 45%;
95+
min-width: 320px;
96+
background: rgba(10, 0, 25, 0.6);
97+
border: 2px solid rgba(130, 60, 255, 0.4);
6898
border-radius: 15px;
69-
overflow: hidden;
70-
box-shadow: 0 0 25px rgba(0,0,0,0.5);
99+
box-shadow: 0 0 20px rgba(145, 70, 255, 0.15);
100+
padding: 1rem;
101+
transition: 0.3s;
102+
}
103+
104+
.table-container:hover {
105+
box-shadow: 0 0 30px rgba(160, 90, 255, 0.3);
106+
}
107+
108+
h2 {
109+
color: #d2b6ff;
110+
text-shadow: 0 0 8px #a66eff;
111+
font-weight: 600;
71112
}
72113

73114
table {
74115
width: 100%;
75116
border-collapse: collapse;
76-
background: #15121a;
117+
margin-top: 1rem;
118+
background: rgba(25, 10, 40, 0.6);
119+
border-radius: 10px;
120+
overflow: hidden;
121+
}
122+
123+
th, td {
124+
padding: 10px 16px;
125+
border-bottom: 1px solid rgba(90, 50, 160, 0.3);
77126
}
78127

79128
th {
80-
background: #1c1625;
129+
background: rgba(90, 40, 160, 0.3);
130+
color: #c6a3ff;
81131
text-transform: uppercase;
82-
color: #b9aaff;
83-
padding: 0.75rem;
132+
font-size: 0.85rem;
133+
letter-spacing: 1px;
84134
}
85135

86136
td {
87-
padding: 0.75rem;
88-
border-top: 1px solid #2c2238;
89-
}
90-
91-
tr:nth-child(even) { background: #1a1723; }
92-
93-
img.avatar {
94-
width: 40px;
95-
height: 40px;
96-
border-radius: 50%;
97-
margin-right: 8px;
98-
vertical-align: middle;
99-
}
100-
101-
.tabs {
102-
display: flex;
103-
justify-content: center;
104-
margin-top: 2rem;
105-
gap: 1rem;
137+
color: #fff;
138+
font-size: 1rem;
106139
}
107140

108-
.tab {
109-
background: #1f1a28;
110-
padding: 0.6rem 1.2rem;
111-
border-radius: 10px;
112-
cursor: pointer;
113-
font-weight: bold;
114-
border: 2px solid transparent;
141+
tr:nth-child(even) {
142+
background: rgba(50, 30, 90, 0.4);
115143
}
116144

117-
.tab.active {
118-
border-color: #a770ff;
119-
background: #2b2139;
145+
tr:hover {
146+
background: rgba(100, 50, 200, 0.4);
147+
transition: 0.2s;
120148
}
121149
</style>
122150
</head>
123151
<body>
124-
<h1>7TV Emote Leaderboard (All-Time)</h1>
152+
<h1>💫 7TV Live Tracker</h1>
125153

126-
<div class="controls">
154+
<div>
127155
<input id="channelInput" placeholder="Enter Twitch channel..." />
128-
<button onclick="loadChannel()">Start Tracking</button>
156+
<button onclick="loadChannel()">Track Channel</button>
129157
</div>
130-
131-
<div class="tabs">
132-
<div class="tab active" id="userTab" onclick="showTab('users')">User Leaderboard</div>
133-
<div class="tab" id="emoteTab" onclick="showTab('emotes')">Emote Leaderboard</div>
134-
</div>
135-
136-
<div id="userLeaderboard" class="leaderboard">
137-
<table>
138-
<thead>
139-
<tr><th>#</th><th>User</th><th>Emotes Used (All Time)</th></tr>
140-
</thead>
141-
<tbody id="userTable"></tbody>
142-
</table>
143-
</div>
144-
145-
<div id="emoteLeaderboard" class="leaderboard" style="display:none;">
146-
<table>
147-
<thead>
148-
<tr><th>#</th><th>Emote</th><th>Uses</th></tr>
149-
</thead>
150-
<tbody id="emoteTable"></tbody>
151-
</table>
158+
<div id="title"></div>
159+
160+
<div id="tables">
161+
<div class="table-container">
162+
<h2>🧍 User Leaderboard</h2>
163+
<table>
164+
<thead><tr><th>#</th><th>User</th><th>Count</th></tr></thead>
165+
<tbody id="userboard"></tbody>
166+
</table>
167+
</div>
168+
169+
<div class="table-container">
170+
<h2>🎭 Emote Leaderboard</h2>
171+
<table>
172+
<thead><tr><th>#</th><th>Emote</th><th>Count</th></tr></thead>
173+
<tbody id="emoteboard"></tbody>
174+
</table>
175+
</div>
152176
</div>
153177

154178
<script>
@@ -159,9 +183,7 @@ <h1>7TV Emote Leaderboard (All-Time)</h1>
159183

160184
ws.onmessage = (e) => {
161185
const data = JSON.parse(e.data);
162-
if (data.channel !== channel) return;
163-
164-
if (data.type === "update") {
186+
if (data.channel === channel && data.type === "update") {
165187
users[data.user.id] = data.user;
166188
emoteUsage = data.emoteUsage;
167189
render();
@@ -174,40 +196,25 @@ <h1>7TV Emote Leaderboard (All-Time)</h1>
174196
const res = await fetch(`/api/channel/${channel}`);
175197
const data = await res.json();
176198
users = {};
177-
data.users.forEach(u => users[u.id] = u);
178-
emoteUsage = data.emoteUsage || {};
199+
data.users.forEach((u) => (users[u.id] = u));
200+
emoteUsage = data.emoteUsage;
201+
document.getElementById("title").innerText = `Tracking: ${channel}`;
179202
render();
180203
}
181204

182205
function render() {
183-
// user leaderboard
184-
const userSorted = Object.values(users).sort((a,b) => b.count - a.count);
185-
const userTable = document.getElementById("userTable");
186-
userTable.innerHTML = userSorted.map((u,i)=>`
187-
<tr>
188-
<td>${i+1}</td>
189-
<td><img class="avatar" src="${u.avatar}"/>${u.username}</td>
190-
<td>${u.count}</td>
191-
</tr>
192-
`).join('');
193-
194-
// emote leaderboard
195-
const emoteSorted = Object.entries(emoteUsage).sort((a,b)=>b[1]-a[1]);
196-
const emoteTable = document.getElementById("emoteTable");
197-
emoteTable.innerHTML = emoteSorted.map(([name,count],i)=>`
198-
<tr>
199-
<td>${i+1}</td>
200-
<td>${name}</td>
201-
<td>${count}</td>
202-
</tr>
203-
`).join('');
204-
}
205-
206-
function showTab(tab) {
207-
document.getElementById("userLeaderboard").style.display = tab === "users" ? "" : "none";
208-
document.getElementById("emoteLeaderboard").style.display = tab === "emotes" ? "" : "none";
209-
document.getElementById("userTab").classList.toggle("active", tab==="users");
210-
document.getElementById("emoteTab").classList.toggle("active", tab==="emotes");
206+
const sortedUsers = Object.values(users).sort((a, b) => b.count - a.count);
207+
const sortedEmotes = Object.entries(emoteUsage)
208+
.sort((a, b) => b[1] - a[1])
209+
.map(([name, count]) => ({ name, count }));
210+
211+
document.getElementById("userboard").innerHTML = sortedUsers
212+
.map((u, i) => `<tr><td>${i + 1}</td><td>${u.username}</td><td>${u.count}</td></tr>`)
213+
.join("");
214+
215+
document.getElementById("emoteboard").innerHTML = sortedEmotes
216+
.map((e, i) => `<tr><td>${i + 1}</td><td>${e.name}</td><td>${e.count}</td></tr>`)
217+
.join("");
211218
}
212219
</script>
213220
</body>

0 commit comments

Comments
 (0)