new version

This commit is contained in:
UrloMythus
2026-05-19 20:28:26 +02:00
parent fbee2c1855
commit bd208c63ff
99 changed files with 1287 additions and 225 deletions
+1 -1
View File
@@ -234,7 +234,7 @@
<input type="text" placeholder="Server Name (optional)"
class="server-name input-field w-full px-4 py-2.5 rounded-xl border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:border-blue-500 text-sm">
<div class="flex gap-2">
<input type="password" placeholder="API Password (optional)"
<input type="password" placeholder="Override password (blank = use main)"
class="server-password input-field flex-1 px-4 py-2.5 rounded-xl border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:border-blue-500 text-sm">
<button type="button" class="remove-server p-2.5 text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-xl transition-colors hidden">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+28 -2
View File
@@ -81,6 +81,27 @@ class MediaFlowSpeedTest {
firstServerUrl.value = baseUrl;
firstServerUrl.placeholder = `${baseUrl} (Current Instance)`;
// The top "MediaFlow API Password" (#currentApiPassword) is the
// source of truth; hydrate from localStorage (shared with the URL
// generator) and persist edits back. Per-server fields are treated
// as optional overrides (see collectServerConfigurations).
const topPw = document.getElementById('currentApiPassword');
const saved = localStorage.getItem('mediaflow_api_password');
if (topPw) {
if (saved && !topPw.value) topPw.value = saved;
topPw.addEventListener('input', () => {
const v = topPw.value.trim();
if (v) localStorage.setItem('mediaflow_api_password', v);
else localStorage.removeItem('mediaflow_api_password');
});
}
// Relabel the per-server field so users realise it's an override
// rather than a second required field.
document.querySelectorAll('.server-password').forEach(el => {
el.placeholder = 'Override password (blank = use main)';
});
// Show placeholder CDN selection initially
this.showPlaceholderCdnSelection();
this.updateCdnButtonStates();
@@ -133,7 +154,7 @@ class MediaFlowSpeedTest {
<div class="flex gap-2">
<input
type="password"
placeholder="API Password (optional)"
placeholder="Override password (blank = use main)"
class="server-password flex-1 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
>
<button
@@ -216,11 +237,16 @@ class MediaFlowSpeedTest {
// Collect server configurations
this.servers = [];
const serverInputs = document.querySelectorAll('.server-input');
// Fall back to the top #currentApiPassword when a server's per-row
// override is blank — saves single-server users from typing the
// password twice.
const mainPassword = (document.getElementById('currentApiPassword')?.value || '').trim();
serverInputs.forEach(input => {
const url = input.querySelector('.server-url').value.trim();
const name = input.querySelector('.server-name').value.trim();
const password = input.querySelector('.server-password').value.trim();
const override = input.querySelector('.server-password').value.trim();
const password = override || mainPassword;
if (url) {
this.servers.push({
+15
View File
@@ -1831,6 +1831,21 @@
localStorage.setItem('theme', newTheme);
});
// Persist the global API password across pages (speedtest, playlist
// builder) so the user only has to type it once — otherwise speedtest
// calls /proxy/stream without the password and gets 401.
(function restoreApiPassword() {
const el = document.getElementById('globalApiPassword');
if (!el) return;
const saved = localStorage.getItem('mediaflow_api_password');
if (saved) el.value = saved;
el.addEventListener('input', () => {
const v = el.value.trim();
if (v) localStorage.setItem('mediaflow_api_password', v);
else localStorage.removeItem('mediaflow_api_password');
});
})();
// Tab switching
function switchTab(tabName) {