Files
mans 7efc16cf06
Build docker container / Build image (push) Successful in 5m27s
refactor: extract DRY template layout and add localized page titles
2026-08-05 17:43:40 +02:00

174 lines
8.7 KiB
HTML

{{ template "layout" . }}
{{ define "page_title" }}{{ .T.TitleAdvanced }}{{ end }}
{{ define "extra_css" }}
body { font-size: 1.1rem; }
.container {
width: 100%;
max-width: 1200px;
display: grid;
grid-template-columns: 1fr;
gap: 40px;
}
.section { width: 100%; }
@media (min-width: 768px) {
body { font-size: 1.3rem; }
.container {
grid-template-columns: 1fr 1fr;
gap: 50px;
}
.full-width { grid-column: 1 / -1; }
h2 { font-size: 1.6rem; }
}
{{ end }}
{{ define "content" }}
<div class="container">
<div class="section">
<h2>{{ .T.Default }} ({{ .NetAddress.Type }})</h2>
<ul id="current-ip">
<li><span class="label">{{ .T.IPAddress }}: </span><b>{{ .NetAddress.Address }}</b></li>
<li><span class="label">{{ .T.Location }}: </span><b>{{ if .Info.City }}{{ .Info.City }}, {{ end }}{{ if .Info.Region }}{{ .Info.Region }}, {{ end }}{{ if .Info.Country }}{{ .Info.Country }}{{ else }}N/A{{ end }}</b></li>
<li><span class="label">{{ .T.Coordinates }}: </span><b>{{ if .Info.Lat }}{{ .Info.Lat }}, {{ .Info.Lon }}{{ else }}N/A{{ end }}</b></li>
<li><span class="label">{{ .T.ISP }}: </span><b>{{ if .Info.ISP }}{{ .Info.ISP }}{{ else }}N/A{{ end }}</b></li>
<li><span class="label">{{ .T.ASN }}: </span><b>{{ if .Info.ASN }}{{ if .Info.ASNCode }}<a href="https://bgp.tools/as/{{ .Info.ASNCode }}" target="_blank" style="color: inherit;">{{ .Info.ASN }}</a>{{ else }}{{ .Info.ASN }}{{ end }}{{ else }}N/A{{ end }}</b></li>
<li><span class="label">{{ .T.ReverseDNS }}: </span><b>{{ if .Info.RevDNS }}{{ .Info.RevDNS }}{{ else }}N/A{{ end }}</b></li>
</ul>
</div>
<div class="section" id="other-ip-section" style="display: none;">
<h2 id="other-ip-title">{{ .T.OtherConnection }}</h2>
<ul id="other-ip">
<li><span class="label">{{ .T.IPAddress }}: </span><b id="other-ip-addr">{{ .T.Loading }}</b></li>
<li><span class="label">{{ .T.Location }}: </span><b id="other-ip-loc">{{ .T.Loading }}</b></li>
<li><span class="label">{{ .T.Coordinates }}: </span><b id="other-ip-coords">{{ .T.Loading }}</b></li>
<li><span class="label">{{ .T.ISP }}: </span><b id="other-ip-isp">{{ .T.Loading }}</b></li>
<li><span class="label">{{ .T.ASN }}: </span><b id="other-ip-asn">{{ .T.Loading }}</b></li>
<li><span class="label">{{ .T.ReverseDNS }}: </span><b id="other-ip-revdns">{{ .T.Loading }}</b></li>
</ul>
</div>
<div class="section full-width">
<h2>{{ .T.ClientInfo }}</h2>
<ul>
<li><span class="label">{{ .T.UserAgent }}: </span><b>{{ .UserAgent }}</b></li>
<li><span class="label">{{ .T.Timezone }}: </span><b id="client-timezone">{{ .T.Loading }}</b></li>
<li><span class="label">{{ .T.Language }}: </span><b id="client-language">{{ .T.Loading }}</b></li>
<li><span class="label">{{ .T.Screen }}: </span><b id="client-screen">{{ .T.Loading }}</b></li>
</ul>
</div>
</div>
{{ end }}
{{ define "nav_links" }}
<a href="/" class="nav-link">{{ .T.SimpleView }}</a>
<span style="border-left: 1px solid var(--divider-color); height: 18px; margin: 0 15px;"></span>
<a href="/headers" class="nav-link">{{ .T.HeadersView }}</a>
<span style="border-left: 1px solid var(--divider-color); height: 18px; margin: 0 15px;"></span>
<a id="copy-btn" class="nav-link">{{ .T.CopyInfo }}</a>
{{ end }}
{{ define "extra_js" }}
document.getElementById('client-timezone').innerText = Intl.DateTimeFormat().resolvedOptions().timeZone || '{{ .T.Unknown }}';
document.getElementById('client-language').innerText = navigator.language || navigator.userLanguage || '{{ .T.Unknown }}';
document.getElementById('client-screen').innerText = `${window.screen.width}x${window.screen.height} (${window.screen.colorDepth}-bit)`;
async function fetchOtherIp() {
const isIpv4 = "{{ .NetAddress.Type }}" == "IPv4";
const requestUrl = isIpv4 ? "{{ .IPv6Endpoint }}" : "{{ .IPv4Endpoint }}";
const otherType = isIpv4 ? "IPv6" : "IPv4";
document.getElementById('other-ip-title').innerText = `{{ .T.Other }} (${otherType})`;
document.getElementById('other-ip-section').style.display = 'block';
try {
const response = await fetch(requestUrl);
const data = await response.json();
if (data.address) {
document.getElementById('other-ip-addr').innerText = data.address;
const advResponse = await fetch(`/api/lookup?ip=${encodeURIComponent(data.address)}`);
const advData = await advResponse.json();
document.getElementById('other-ip-revdns').innerText = advData.rev_dns || 'N/A';
document.getElementById('other-ip-isp').innerText = advData.isp || 'N/A';
if (advData.asn) {
if (advData.asn_code) {
const a = document.createElement('a');
a.href = `https://bgp.tools/as/${encodeURIComponent(advData.asn_code)}`;
a.target = '_blank';
a.style.color = 'inherit';
a.textContent = advData.asn;
const container = document.getElementById('other-ip-asn');
container.innerHTML = '';
container.appendChild(a);
} else {
document.getElementById('other-ip-asn').innerText = advData.asn;
}
} else {
document.getElementById('other-ip-asn').innerText = 'N/A';
}
let loc = [];
if (advData.city) loc.push(advData.city);
if (advData.region) loc.push(advData.region);
if (advData.country) loc.push(advData.country);
document.getElementById('other-ip-loc').innerText = loc.length > 0 ? loc.join(', ') : 'N/A';
if (advData.lat && advData.lon) {
document.getElementById('other-ip-coords').innerText = `${advData.lat}, ${advData.lon}`;
} else {
document.getElementById('other-ip-coords').innerText = 'N/A';
}
} else {
setOtherIpUnavailable();
}
} catch (e) {
console.error(e);
setOtherIpUnavailable();
}
}
function setOtherIpUnavailable() {
document.getElementById('other-ip-addr').innerText = '{{ .T.NotDetected }}';
document.getElementById('other-ip-revdns').innerText = 'N/A';
document.getElementById('other-ip-isp').innerText = 'N/A';
document.getElementById('other-ip-asn').innerText = 'N/A';
document.getElementById('other-ip-loc').innerText = 'N/A';
document.getElementById('other-ip-coords').innerText = 'N/A';
}
fetchOtherIp();
document.getElementById('copy-btn').addEventListener('click', async (e) => {
e.preventDefault();
let info = [];
info.push("--- {{ .T.Default }} ({{ .NetAddress.Type }}) ---");
document.querySelectorAll('#current-ip li').forEach(li => info.push(li.innerText));
if (document.getElementById('other-ip-section').style.display !== 'none') {
info.push("");
info.push("--- " + document.getElementById('other-ip-title').innerText + " ---");
document.querySelectorAll('#other-ip li').forEach(li => info.push(li.innerText));
}
info.push("");
info.push("--- {{ .T.ClientInfo }} ---");
document.querySelectorAll('.full-width ul li').forEach(li => info.push(li.innerText));
try {
await navigator.clipboard.writeText(info.join('\n'));
const btn = document.getElementById('copy-btn');
btn.innerText = '{{ .T.Copied }}';
setTimeout(() => btn.innerText = '{{ .T.CopyInfo }}', 2000);
} catch (err) {
console.error('Failed to copy', err);
}
});
{{ end }}