mirror of
https://github.com/imgfloat/server.git
synced 2026-02-05 11:49:25 +00:00
Add channels page
This commit is contained in:
@@ -188,6 +188,50 @@ body {
|
||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.02);
|
||||
}
|
||||
|
||||
.search-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.text-input {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #1f2937;
|
||||
background: #0f172a;
|
||||
color: #e2e8f0;
|
||||
font-size: 15px;
|
||||
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.text-input:focus {
|
||||
outline: none;
|
||||
border-color: #7c3aed;
|
||||
box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.25);
|
||||
}
|
||||
|
||||
.search-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.search-row {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.search-row .text-input {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.search-row .button {
|
||||
padding: 0 16px;
|
||||
height: 46px;
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -1133,6 +1177,10 @@ body {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.tiny {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.range-value {
|
||||
color: #a5b4fc;
|
||||
font-size: 12px;
|
||||
|
||||
54
src/main/resources/static/js/landing.js
Normal file
54
src/main/resources/static/js/landing.js
Normal file
@@ -0,0 +1,54 @@
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const searchForm = document.getElementById("channel-search-form");
|
||||
const searchInput = document.getElementById("channel-search");
|
||||
const suggestions = document.getElementById("channel-suggestions");
|
||||
|
||||
if (!searchForm || !searchInput || !suggestions) {
|
||||
return;
|
||||
}
|
||||
|
||||
let channels = [];
|
||||
|
||||
function updateSuggestions(term) {
|
||||
const normalizedTerm = term.trim().toLowerCase();
|
||||
const filtered = channels
|
||||
.filter((name) => !normalizedTerm || name.includes(normalizedTerm))
|
||||
.slice(0, 20);
|
||||
|
||||
suggestions.innerHTML = "";
|
||||
filtered.forEach((name) => {
|
||||
const option = document.createElement("option");
|
||||
option.value = name;
|
||||
suggestions.appendChild(option);
|
||||
});
|
||||
}
|
||||
|
||||
async function loadChannels() {
|
||||
try {
|
||||
const response = await fetch("/api/channels");
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to load channels: ${response.status}`);
|
||||
}
|
||||
channels = await response.json();
|
||||
updateSuggestions(searchInput.value || "");
|
||||
} catch (error) {
|
||||
console.error("Could not load channel directory", error);
|
||||
}
|
||||
}
|
||||
|
||||
searchInput.addEventListener("input", (event) => {
|
||||
updateSuggestions(event.target.value || "");
|
||||
});
|
||||
|
||||
searchForm.addEventListener("submit", (event) => {
|
||||
event.preventDefault();
|
||||
const broadcaster = (searchInput.value || "").trim().toLowerCase();
|
||||
if (!broadcaster) {
|
||||
searchInput.focus();
|
||||
return;
|
||||
}
|
||||
window.location.href = `/view/${encodeURIComponent(broadcaster)}/broadcast`;
|
||||
});
|
||||
|
||||
loadChannels();
|
||||
});
|
||||
Reference in New Issue
Block a user