Files
adlist_mikrotik/static/js/main.js
Mateusz Gruszczyński bc45c91d92 refactor ciagl dalszy
2025-08-29 10:46:50 +02:00

162 lines
6.0 KiB
JavaScript

(function () {
const $ = (q, c = document) => c.querySelector(q);
const $$ = (q, c = document) => Array.from(c.querySelectorAll(q));
const setTheme = (t) => { document.documentElement.setAttribute('data-theme', t); try { localStorage.setItem('theme', t) } catch { } };
const toast = (msg) => {
const el = $('#toast'); if (!el) return;
el.textContent = msg; el.classList.add('show');
clearTimeout(el._t); el._t = setTimeout(() => el.classList.remove('show'), 2000);
};
const host = () => `${location.protocol}//${location.host}`;
function buildLink(url, ip) {
if (!url || !ip) return '';
try {
const enc = encodeURIComponent(url);
const ipClean = (ip || '').trim();
return `${host()}/convert?url=${enc}&ip=${encodeURIComponent(ipClean)}`;
} catch { return ''; }
}
document.addEventListener('click', (e) => {
const t = e.target.closest('[data-action="toggle-theme"]');
if (t) {
e.preventDefault();
const cur = document.documentElement.getAttribute('data-theme') || 'dark';
setTheme(cur === 'dark' ? 'light' : 'dark');
}
});
const urlInput = $('#url-input');
const ipInput = $('#ip-input');
const ipPreset = $('#ip-preset');
const out = $('#generated-link');
const openBtn = $('#open-link');
function updatePreview() {
const link = buildLink(urlInput.value.trim(), ipInput.value.trim());
out.value = link || '';
if (link) {
openBtn.setAttribute('href', link);
openBtn.setAttribute('aria-disabled', 'false');
} else {
openBtn.setAttribute('href', '#');
openBtn.setAttribute('aria-disabled', 'true');
}
$('.result-box')?.setAttribute('data-state', link ? 'ready' : 'empty');
}
['input', 'change', 'blur'].forEach(evt => {
urlInput?.addEventListener(evt, updatePreview);
ipInput?.addEventListener(evt, updatePreview);
});
ipPreset?.addEventListener('change', () => {
const v = ipPreset.value;
if (!v) return;
if (v !== 'custom') ipInput.value = v;
ipInput.focus();
updatePreview();
});
document.addEventListener('click', (e) => {
let t = e.target;
if (t.closest('[data-action="copy"]')) {
e.preventDefault();
const btn = t.closest('[data-action="copy"]');
const sel = btn.getAttribute('data-target') || '#generated-link';
const el = $(sel);
if (!el) return;
const text = el.value || el.textContent || '';
navigator.clipboard?.writeText(text).then(() => {
btn.classList.add('copied'); setTimeout(() => btn.classList.remove('copied'), 1200);
toast('Link copied');
}).catch(() => {
// Fallback
const range = document.createRange(); range.selectNodeContents(el);
const selObj = getSelection(); selObj.removeAllRanges(); selObj.addRange(range);
try { document.execCommand('copy'); toast('Link copied'); } catch { }
selObj.removeAllRanges();
});
}
if (t.closest('[data-action="copy-text"]')) {
e.preventDefault();
const btn = t.closest('[data-action="copy-text"]');
const text = btn.getAttribute('data-text') || '';
if (!text) return;
navigator.clipboard?.writeText(text).then(() => toast('Copied'));
}
if (t.closest('[data-action="clear"]')) {
e.preventDefault();
urlInput.value = '';
updatePreview();
urlInput.focus();
}
if (t.closest('[data-action="collapse"]')) {
e.preventDefault();
const btn = t.closest('[data-action="collapse"]');
const panel = $('#' + (btn.getAttribute('aria-controls') || ''));
if (!panel) return;
const expanded = btn.getAttribute('aria-expanded') === 'true';
btn.setAttribute('aria-expanded', expanded ? 'false' : 'true');
panel.style.display = expanded ? 'none' : '';
}
});
function showError(input, msg) {
const id = input.getAttribute('id');
const box = document.querySelector(`.error[data-error-for="${id}"]`);
if (box) box.textContent = msg || '';
input.setAttribute('aria-invalid', msg ? 'true' : 'false');
}
urlInput?.addEventListener('blur', () => {
const v = urlInput.value.trim();
if (!v) return showError(urlInput, '');
try { new URL(v); showError(urlInput, ''); }
catch { showError(urlInput, 'Invalid URL'); }
});
ipInput?.addEventListener('blur', () => {
const v = ipInput.value.trim();
if (!v) return showError(ipInput, '');
const ok = /^\b\d{1,3}(?:\.\d{1,3}){3}\b$/.test(v);
showError(ipInput, ok ? '' : 'Invalid IPv4 address');
});
(function init() {
const serverLink = out?.value?.trim();
if (serverLink) {
$('.result-box')?.setAttribute('data-state', 'ready');
openBtn?.setAttribute('aria-disabled', 'false');
} else {
updatePreview();
}
})();
document.addEventListener('keydown', (e) => {
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'c') {
const text = out?.value?.trim(); if (!text) return;
navigator.clipboard?.writeText(text).then(() => toast('Link copied'));
}
});
})();
function updateThemeColor() {
const meta = document.querySelector('meta[name="theme-color"]');
if (!meta) return;
const isLight = document.documentElement.getAttribute('data-theme') === 'light';
meta.setAttribute('content', isLight ? '#f6f8fb' : '#0f1115');
}
const _setTheme = setTheme;
setTheme = function (t) { _setTheme(t); updateThemeColor(); };
document.addEventListener('DOMContentLoaded', updateThemeColor);