Slightly prettier UI
This commit is contained in:
parent
7832f6e6b8
commit
9a14492e47
6
main.py
6
main.py
@ -671,6 +671,12 @@ def serve_maskable_icon():
|
|||||||
return send_from_directory("static", 'icon512_maskable.png',
|
return send_from_directory("static", 'icon512_maskable.png',
|
||||||
mimetype='image/png')
|
mimetype='image/png')
|
||||||
|
|
||||||
|
@app.route('/screenshot1.png')
|
||||||
|
def serve_screenshot_1():
|
||||||
|
return send_from_directory("static", 'screenshot1.png',
|
||||||
|
mimetype='image/png')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Start Qt process
|
# Start Qt process
|
||||||
qt_proc = multiprocessing.Process(target=qt_process)
|
qt_proc = multiprocessing.Process(target=qt_process)
|
||||||
|
|||||||
@ -2,6 +2,14 @@
|
|||||||
"theme_color":"#222222",
|
"theme_color":"#222222",
|
||||||
"background_color":"#222222",
|
"background_color":"#222222",
|
||||||
"start_url": "/",
|
"start_url": "/",
|
||||||
|
"screenshots":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"src": "screenshot1.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "1080x2017"
|
||||||
|
}
|
||||||
|
],
|
||||||
"icons":
|
"icons":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
|||||||
BIN
static/screenshot1.png
Normal file
BIN
static/screenshot1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
@ -1,5 +1,6 @@
|
|||||||
<!-- Updated HTML/CSS for the index() function in Flask -->
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>IPMPV</title>
|
<title>IPMPV</title>
|
||||||
<link rel="manifest" href="/manifest.json">
|
<link rel="manifest" href="/manifest.json">
|
||||||
@ -17,28 +18,30 @@
|
|||||||
--text-color: white;
|
--text-color: white;
|
||||||
--on-state: #007700;
|
--on-state: #007700;
|
||||||
--off-state: #770000;
|
--off-state: #770000;
|
||||||
|
--on-border: #229922;
|
||||||
|
--off-border: #992222;
|
||||||
--border-radius: 15px;
|
--border-radius: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: var(--primary-bg);
|
background-color: var(--primary-bg);
|
||||||
font-family: Fira Sans Regular, Arial, sans-serif;
|
font-family: "Fira Sans", Arial, sans-serif;
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.controls {
|
.controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@ -49,7 +52,7 @@
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.channel {
|
.channel {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -61,21 +64,21 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.25);
|
box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
.channel img {
|
.channel img {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
.group-container {
|
.group-container {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||||
gap: 0 20px;
|
gap: 0 20px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.group {
|
.group {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -87,152 +90,158 @@
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: rgba(255, 255, 255, 0.05);
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
font-family: "Fira Sans", Arial, sans-serif;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
min-width: 120px;
|
min-width: 200px;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
border: 1px solid #353535;
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
border: none;
|
transition: background-color 0.2s, transform 0.1s, border-color 0.2s;
|
||||||
transition: background-color 0.2s, transform 0.1s;
|
|
||||||
background-color: var(--secondary-bg);
|
background-color: var(--secondary-bg);
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Control buttons layout */
|
/* Control buttons layout */
|
||||||
.control-button {
|
.control-button {
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
flex: 0 1 auto;
|
flex: 0 1 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.url-input-container {
|
.url-input-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
margin: 10px auto;
|
margin: 10px auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.url-input-group {
|
.url-input-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
|
font-family: "Fira Sans", Arial, sans-serif;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
border: none;
|
border: 1px solid #444444;
|
||||||
background-color: var(--input-bg);
|
background-color: var(--input-bg);
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.osd-toggle {
|
.osd-toggle {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin: 10px 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#osd-on-btn {
|
#osd-on-btn {
|
||||||
border-radius: var(--border-radius) 0 0 var(--border-radius);
|
border-radius: var(--border-radius) 0 0 var(--border-radius);
|
||||||
min-width: 80px;
|
min-width: 80px;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
|
border-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#osd-off-btn {
|
#osd-off-btn {
|
||||||
border-radius: 0 var(--border-radius) var(--border-radius) 0;
|
border-radius: 0 var(--border-radius) var(--border-radius) 0;
|
||||||
min-width: 80px;
|
min-width: 80px;
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
|
border-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#latency-btn {
|
#latency-btn {
|
||||||
min-width: 60px;
|
min-width: 60px;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
border-right: 0;
|
||||||
|
border-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-url-input {
|
.custom-url-input {
|
||||||
border-radius: var(--border-radius) 0 0 var(--border-radius);
|
border-radius: var(--border-radius) 0 0 var(--border-radius);
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
|
border-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-btn {
|
.input-btn {
|
||||||
border-radius: 0 var(--border-radius) var(--border-radius) 0;
|
border-radius: 0 var(--border-radius) var(--border-radius) 0;
|
||||||
display: block;
|
display: block;
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
|
border-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:hover {
|
button:hover {
|
||||||
background-color: var(--button-hover);
|
background-color: var(--button-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
button:active {
|
button:active {
|
||||||
background-color: var(--button-active);
|
background-color: var(--button-active);
|
||||||
transform: scale(0.97);
|
transform: scale(0.97);
|
||||||
}
|
}
|
||||||
|
|
||||||
button.OFF {
|
button.OFF {
|
||||||
background-color: var(--off-state);
|
background-color: var(--off-state);
|
||||||
|
border: 1px solid var(--off-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
button.ON {
|
button.ON {
|
||||||
background-color: var(--on-state);
|
background-color: var(--on-state);
|
||||||
|
border: 1px solid var(--on-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sections */
|
/* Sections */
|
||||||
.section {
|
.section {
|
||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
margin: 15px 0;
|
margin: 15px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
margin: 15px 0 10px 0;
|
margin: 15px 0 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For tablets and larger screens */
|
/* For tablets and larger screens */
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
.channel button {
|
.channel button {
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.control-button {
|
.control-button {
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.url-input-group {
|
.url-input-group {
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-url-input {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-btn {
|
.input-btn {
|
||||||
min-width: 120px;
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For larger desktops - maintain original spacing */
|
/* For larger desktops - maintain original spacing */
|
||||||
@media (min-width: 1200px) {
|
@media (min-width: 1200px) {
|
||||||
.channel img {
|
.channel img {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
@ -240,54 +249,99 @@
|
|||||||
|
|
||||||
/* Mobile touch improvements */
|
/* Mobile touch improvements */
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767px) {
|
||||||
button, input {
|
|
||||||
padding: 14px; /* Larger touch targets */
|
button,
|
||||||
|
input {
|
||||||
|
padding: 14px;
|
||||||
|
/* Larger touch targets */
|
||||||
margin: 8px 4px;
|
margin: 8px 4px;
|
||||||
width: 100%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
min-width: unset;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.group-container {
|
.group-container {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.controls {
|
.controls {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.osd-toggle {
|
||||||
|
width: 85%;
|
||||||
|
margin: 8px 4px;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.control-button {
|
.control-button {
|
||||||
width: 100%;
|
width: 90%;
|
||||||
max-width: none;
|
max-width: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.url-input-group {
|
.url-input-group {
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-url-input {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-url-input {
|
||||||
|
width: 90%;
|
||||||
|
min-width: 200px;
|
||||||
|
border-right: 1px solid #444444;
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
#latency-btn {
|
#latency-btn {
|
||||||
width: 100%;
|
width: 90%;
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-btn {
|
.input-btn {
|
||||||
width: 100%;
|
width: 90%;
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
|
border-left: 1px solid #353535;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#osd-on-btn {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
margin-left: 4px;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#osd-off-btn {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
margin-right: 4px;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>Welcome to IPMPV</h1>
|
<h1>Welcome to IPMPV</h1>
|
||||||
<p>Current Channel: <span id="current-channel">%CURRENT_CHANNEL%</span></p>
|
<p>Current Channel: <span id="current-channel">%CURRENT_CHANNEL%</span></p>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<button class="control-button" onclick="stopPlayer()">Stop</button>
|
<button class="control-button" onclick="stopPlayer()">Stop</button>
|
||||||
<button id="retroarch-btn" class="%RETROARCH_STATE%" onclick="toggleRetroArch()">
|
<button id="retroarch-btn" class="%RETROARCH_STATE%" onclick="toggleRetroArch()">
|
||||||
@ -300,7 +354,7 @@
|
|||||||
Resolution: <span id="resolution-state">%RESOLUTION%</span>
|
Resolution: <span id="resolution-state">%RESOLUTION%</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h2>Toggle OSD</h2>
|
<h2>Toggle OSD</h2>
|
||||||
<div class="osd-toggle">
|
<div class="osd-toggle">
|
||||||
@ -308,7 +362,7 @@
|
|||||||
<button id="osd-off-btn" onclick="hideOSD()">off</button>
|
<button id="osd-off-btn" onclick="hideOSD()">off</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h2>Play Custom URL</h2>
|
<h2>Play Custom URL</h2>
|
||||||
<div class="url-input-container">
|
<div class="url-input-container">
|
||||||
@ -321,24 +375,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>All Channels</h2>
|
<h2>All Channels</h2>
|
||||||
<div class="group-container">
|
<div class="group-container">
|
||||||
<!-- Channel groups will be inserted here -->
|
<!-- Channel groups will be inserted here -->
|
||||||
%CHANNEL_GROUPS%
|
%CHANNEL_GROUPS%
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Improve mobile touch experience
|
// Improve mobile touch experience
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
// Add active/touch state for all buttons
|
// Add active/touch state for all buttons
|
||||||
const buttons = document.querySelectorAll('button');
|
const buttons = document.querySelectorAll('button');
|
||||||
buttons.forEach(button => {
|
buttons.forEach(button => {
|
||||||
button.addEventListener('touchstart', function() {
|
button.addEventListener('touchstart', function () {
|
||||||
this.classList.add('touching');
|
this.classList.add('touching');
|
||||||
});
|
});
|
||||||
button.addEventListener('touchend', function() {
|
button.addEventListener('touchend', function () {
|
||||||
this.classList.remove('touching');
|
this.classList.remove('touching');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -346,23 +400,23 @@
|
|||||||
// Auto hide address bar on mobile
|
// Auto hide address bar on mobile
|
||||||
window.scrollTo(0, 1);
|
window.scrollTo(0, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
function playCustomURL() {
|
function playCustomURL() {
|
||||||
const url = document.getElementById("custom-url").value;
|
const url = document.getElementById("custom-url").value;
|
||||||
if (!url.trim()) return; // Ignore empty input
|
if (!url.trim()) return; // Ignore empty input
|
||||||
|
|
||||||
// Show loading indicator
|
// Show loading indicator
|
||||||
const playButton = document.querySelector('.input-btn');
|
const playButton = document.querySelector('.input-btn');
|
||||||
const originalText = playButton.textContent;
|
const originalText = playButton.textContent;
|
||||||
playButton.textContent = "Loading...";
|
playButton.textContent = "Loading...";
|
||||||
playButton.disabled = true;
|
playButton.disabled = true;
|
||||||
|
|
||||||
fetch(`/play_custom?url=${encodeURIComponent(url)}`)
|
fetch(`/play_custom?url=${encodeURIComponent(url)}`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
playButton.textContent = originalText;
|
playButton.textContent = originalText;
|
||||||
playButton.disabled = false;
|
playButton.disabled = false;
|
||||||
|
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
// Show toast instead of alert on mobile
|
// Show toast instead of alert on mobile
|
||||||
showToast("Now playing: " + url);
|
showToast("Now playing: " + url);
|
||||||
@ -376,7 +430,7 @@
|
|||||||
showToast("Connection error. Please try again.");
|
showToast("Connection error. Please try again.");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleLatency() {
|
function toggleLatency() {
|
||||||
fetch(`/toggle_latency`)
|
fetch(`/toggle_latency`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
@ -385,7 +439,7 @@
|
|||||||
document.getElementById("latency-btn").className = data.state ? "ON" : "OFF";
|
document.getElementById("latency-btn").className = data.state ? "ON" : "OFF";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleRetroArch() {
|
function toggleRetroArch() {
|
||||||
fetch(`/toggle_retroarch`)
|
fetch(`/toggle_retroarch`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
@ -394,7 +448,7 @@
|
|||||||
document.getElementById("retroarch-btn").className = data.state ? "ON" : "OFF";
|
document.getElementById("retroarch-btn").className = data.state ? "ON" : "OFF";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleResolution() {
|
function toggleResolution() {
|
||||||
fetch(`/toggle_resolution`)
|
fetch(`/toggle_resolution`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
@ -402,20 +456,20 @@
|
|||||||
document.getElementById("resolution-state").textContent = data.res;
|
document.getElementById("resolution-state").textContent = data.res;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopPlayer() {
|
function stopPlayer() {
|
||||||
fetch(`/stop_player`).then(() => window.location.reload());
|
fetch(`/stop_player`).then(() => window.location.reload());
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeChannel(index) {
|
function changeChannel(index) {
|
||||||
// Show loading indicator
|
// Show loading indicator
|
||||||
const channelButtons = document.querySelectorAll('.channel button');
|
const channelButtons = document.querySelectorAll('.channel button');
|
||||||
channelButtons.forEach(btn => {
|
channelButtons.forEach(btn => {
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
showToast("Loading channel...");
|
showToast("Loading channel...");
|
||||||
|
|
||||||
fetch(`/channel?index=${index}`)
|
fetch(`/channel?index=${index}`)
|
||||||
.then(() => window.location.reload())
|
.then(() => window.location.reload())
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
@ -425,7 +479,7 @@
|
|||||||
showToast("Error loading channel. Try again.");
|
showToast("Error loading channel. Try again.");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleDeinterlace() {
|
function toggleDeinterlace() {
|
||||||
fetch(`/toggle_deinterlace`)
|
fetch(`/toggle_deinterlace`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
@ -434,15 +488,15 @@
|
|||||||
document.getElementById("deinterlace-btn").className = data.state ? "ON" : "OFF";
|
document.getElementById("deinterlace-btn").className = data.state ? "ON" : "OFF";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function showOSD() {
|
function showOSD() {
|
||||||
fetch(`/show_osd`).then(response => response.json());
|
fetch(`/show_osd`).then(response => response.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideOSD() {
|
function hideOSD() {
|
||||||
fetch(`/hide_osd`).then(response => response.json());
|
fetch(`/hide_osd`).then(response => response.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mobile-friendly toast notification
|
// Mobile-friendly toast notification
|
||||||
function showToast(message) {
|
function showToast(message) {
|
||||||
const toast = document.createElement('div');
|
const toast = document.createElement('div');
|
||||||
@ -458,9 +512,9 @@
|
|||||||
toast.style.borderRadius = '25px';
|
toast.style.borderRadius = '25px';
|
||||||
toast.style.zIndex = '1000';
|
toast.style.zIndex = '1000';
|
||||||
toast.style.maxWidth = '80%';
|
toast.style.maxWidth = '80%';
|
||||||
|
|
||||||
document.body.appendChild(toast);
|
document.body.appendChild(toast);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
toast.style.opacity = '0';
|
toast.style.opacity = '0';
|
||||||
toast.style.transition = 'opacity 0.5s ease';
|
toast.style.transition = 'opacity 0.5s ease';
|
||||||
@ -471,4 +525,5 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Loading…
Reference in New Issue
Block a user