mirror of
https://github.com/Mo3he/Axis_Cam_Tailscale.git
synced 2026-08-16 20:26:46 +00:00
Update Tailscale binaries to v1.96.4, fix UI parsing (last-match), add Check for Updates button, direct download links on homepage
This commit is contained in:
+51
-13
@@ -359,6 +359,9 @@
|
||||
<div class="info-value" id="ts-version">-</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:14px;text-align:right;">
|
||||
<button id="check-update-btn" class="log-toggle">Check for Updates</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Logs -->
|
||||
@@ -437,16 +440,35 @@
|
||||
tsIP = allIPs.length ? allIPs[allIPs.length - 1] : null;
|
||||
}
|
||||
|
||||
var nodeMatch = txt.match(/popBrowserAuthNow\("([^"]+)"\)/);
|
||||
if (!nodeMatch) nodeMatch = txt.match(/StartLoginInteractiveAs\("([^"]+)"\)/);
|
||||
var node = nodeMatch ? nodeMatch[1] : null;
|
||||
var nodeMatches = txt.match(/popBrowserAuthNow\("([^"]+)"\)/g);
|
||||
if (!nodeMatches) nodeMatches = txt.match(/StartLoginInteractiveAs\("([^"]+)"\)/g);
|
||||
var node = null;
|
||||
if (nodeMatches) {
|
||||
var nm = nodeMatches[nodeMatches.length - 1].match(/"([^"]+)"/);
|
||||
if (nm) node = nm[1];
|
||||
}
|
||||
if (!node) {
|
||||
var hostMatches = txt.match(/^\S+\s+(\S+)\s+\[\s*INFO/gm);
|
||||
if (hostMatches) {
|
||||
var hm = hostMatches[hostMatches.length - 1].match(/^\S+\s+(\S+)/);
|
||||
if (hm) node = hm[1];
|
||||
}
|
||||
}
|
||||
|
||||
var loginMatch = txt.match(/active login:\s+(\S+)/);
|
||||
var tailnet = loginMatch ? loginMatch[1] : null;
|
||||
var loginMatches = txt.match(/active login:\s+\S+/g);
|
||||
var tailnet = null;
|
||||
if (loginMatches) {
|
||||
var lm = loginMatches[loginMatches.length - 1].match(/active login:\s+(\S+)/);
|
||||
if (lm) tailnet = lm[1];
|
||||
}
|
||||
|
||||
var versionMatch = txt.match(/Program starting: v(\d+\.\d+\.\d+)/);
|
||||
if (!versionMatch) versionMatch = txt.match(/tailscaled[\s_](\d+\.\d+\.\d+)/);
|
||||
var version = versionMatch ? versionMatch[1] : null;
|
||||
var versionMatches = txt.match(/Program starting: v(\d+\.\d+\.\d+)/g);
|
||||
var version = null;
|
||||
if (versionMatches) {
|
||||
var last = versionMatches[versionMatches.length - 1];
|
||||
var vm = last.match(/v(\d+\.\d+\.\d+)/);
|
||||
if (vm) version = vm[1];
|
||||
}
|
||||
|
||||
var stateLines = txt.match(/Switching ipn state [^\n]+/g) || [];
|
||||
var lastState = stateLines.length ? stateLines[stateLines.length - 1] : '';
|
||||
@@ -542,10 +564,15 @@
|
||||
setInterval(refresh, 5000);
|
||||
|
||||
// Check for updates from GitHub
|
||||
var latestChecked = false;
|
||||
function checkForUpdate(currentVersion) {
|
||||
if (!currentVersion || latestChecked) return;
|
||||
latestChecked = true;
|
||||
var installedVersion = null;
|
||||
var autoChecked = false;
|
||||
function checkForUpdate(currentVersion, manual) {
|
||||
if (!currentVersion) return;
|
||||
installedVersion = currentVersion;
|
||||
if (!manual && autoChecked) return;
|
||||
if (!manual) autoChecked = true;
|
||||
var btn = document.getElementById('check-update-btn');
|
||||
if (manual && btn) btn.textContent = 'Checking...';
|
||||
fetch('https://api.github.com/repos/Mo3he/Axis_Cam_Tailscale/releases/latest')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
@@ -555,11 +582,22 @@
|
||||
document.getElementById('update-version').textContent = 'v' + tag;
|
||||
document.getElementById('update-banner').classList.add('visible');
|
||||
document.getElementById('ts-version').textContent = currentVersion + ' (outdated)';
|
||||
if (btn) btn.textContent = 'Update Available';
|
||||
} else {
|
||||
if (manual && btn) btn.textContent = 'Up to date';
|
||||
setTimeout(function() { if (btn) btn.textContent = 'Check for Updates'; }, 3000);
|
||||
}
|
||||
})
|
||||
.catch(function() {});
|
||||
.catch(function() {
|
||||
if (manual && btn) btn.textContent = 'Check failed';
|
||||
setTimeout(function() { if (btn) btn.textContent = 'Check for Updates'; }, 3000);
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('check-update-btn').addEventListener('click', function() {
|
||||
if (installedVersion) checkForUpdate(installedVersion, true);
|
||||
});
|
||||
|
||||
function compareVersions(a, b) {
|
||||
var pa = a.split('.').map(Number);
|
||||
var pb = b.split('.').map(Number);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -359,6 +359,9 @@
|
||||
<div class="info-value" id="ts-version">-</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:14px;text-align:right;">
|
||||
<button id="check-update-btn" class="log-toggle">Check for Updates</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Logs -->
|
||||
@@ -437,16 +440,35 @@
|
||||
tsIP = allIPs.length ? allIPs[allIPs.length - 1] : null;
|
||||
}
|
||||
|
||||
var nodeMatch = txt.match(/popBrowserAuthNow\("([^"]+)"\)/);
|
||||
if (!nodeMatch) nodeMatch = txt.match(/StartLoginInteractiveAs\("([^"]+)"\)/);
|
||||
var node = nodeMatch ? nodeMatch[1] : null;
|
||||
var nodeMatches = txt.match(/popBrowserAuthNow\("([^"]+)"\)/g);
|
||||
if (!nodeMatches) nodeMatches = txt.match(/StartLoginInteractiveAs\("([^"]+)"\)/g);
|
||||
var node = null;
|
||||
if (nodeMatches) {
|
||||
var nm = nodeMatches[nodeMatches.length - 1].match(/"([^"]+)"/);
|
||||
if (nm) node = nm[1];
|
||||
}
|
||||
if (!node) {
|
||||
var hostMatches = txt.match(/^\S+\s+(\S+)\s+\[\s*INFO/gm);
|
||||
if (hostMatches) {
|
||||
var hm = hostMatches[hostMatches.length - 1].match(/^\S+\s+(\S+)/);
|
||||
if (hm) node = hm[1];
|
||||
}
|
||||
}
|
||||
|
||||
var loginMatch = txt.match(/active login:\s+(\S+)/);
|
||||
var tailnet = loginMatch ? loginMatch[1] : null;
|
||||
var loginMatches = txt.match(/active login:\s+\S+/g);
|
||||
var tailnet = null;
|
||||
if (loginMatches) {
|
||||
var lm = loginMatches[loginMatches.length - 1].match(/active login:\s+(\S+)/);
|
||||
if (lm) tailnet = lm[1];
|
||||
}
|
||||
|
||||
var versionMatch = txt.match(/Program starting: v(\d+\.\d+\.\d+)/);
|
||||
if (!versionMatch) versionMatch = txt.match(/tailscaled[\s_](\d+\.\d+\.\d+)/);
|
||||
var version = versionMatch ? versionMatch[1] : null;
|
||||
var versionMatches = txt.match(/Program starting: v(\d+\.\d+\.\d+)/g);
|
||||
var version = null;
|
||||
if (versionMatches) {
|
||||
var last = versionMatches[versionMatches.length - 1];
|
||||
var vm = last.match(/v(\d+\.\d+\.\d+)/);
|
||||
if (vm) version = vm[1];
|
||||
}
|
||||
|
||||
var stateLines = txt.match(/Switching ipn state [^\n]+/g) || [];
|
||||
var lastState = stateLines.length ? stateLines[stateLines.length - 1] : '';
|
||||
@@ -542,10 +564,15 @@
|
||||
setInterval(refresh, 5000);
|
||||
|
||||
// Check for updates from GitHub
|
||||
var latestChecked = false;
|
||||
function checkForUpdate(currentVersion) {
|
||||
if (!currentVersion || latestChecked) return;
|
||||
latestChecked = true;
|
||||
var installedVersion = null;
|
||||
var autoChecked = false;
|
||||
function checkForUpdate(currentVersion, manual) {
|
||||
if (!currentVersion) return;
|
||||
installedVersion = currentVersion;
|
||||
if (!manual && autoChecked) return;
|
||||
if (!manual) autoChecked = true;
|
||||
var btn = document.getElementById('check-update-btn');
|
||||
if (manual && btn) btn.textContent = 'Checking...';
|
||||
fetch('https://api.github.com/repos/Mo3he/Axis_Cam_Tailscale/releases/latest')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
@@ -555,11 +582,22 @@
|
||||
document.getElementById('update-version').textContent = 'v' + tag;
|
||||
document.getElementById('update-banner').classList.add('visible');
|
||||
document.getElementById('ts-version').textContent = currentVersion + ' (outdated)';
|
||||
if (btn) btn.textContent = 'Update Available';
|
||||
} else {
|
||||
if (manual && btn) btn.textContent = 'Up to date';
|
||||
setTimeout(function() { if (btn) btn.textContent = 'Check for Updates'; }, 3000);
|
||||
}
|
||||
})
|
||||
.catch(function() {});
|
||||
.catch(function() {
|
||||
if (manual && btn) btn.textContent = 'Check failed';
|
||||
setTimeout(function() { if (btn) btn.textContent = 'Check for Updates'; }, 3000);
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('check-update-btn').addEventListener('click', function() {
|
||||
if (installedVersion) checkForUpdate(installedVersion, true);
|
||||
});
|
||||
|
||||
function compareVersions(a, b) {
|
||||
var pa = a.split('.').map(Number);
|
||||
var pb = b.split('.').map(Number);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -359,6 +359,9 @@
|
||||
<div class="info-value" id="ts-version">-</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:14px;text-align:right;">
|
||||
<button id="check-update-btn" class="log-toggle">Check for Updates</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Logs -->
|
||||
@@ -437,16 +440,35 @@
|
||||
tsIP = allIPs.length ? allIPs[allIPs.length - 1] : null;
|
||||
}
|
||||
|
||||
var nodeMatch = txt.match(/popBrowserAuthNow\("([^"]+)"\)/);
|
||||
if (!nodeMatch) nodeMatch = txt.match(/StartLoginInteractiveAs\("([^"]+)"\)/);
|
||||
var node = nodeMatch ? nodeMatch[1] : null;
|
||||
var nodeMatches = txt.match(/popBrowserAuthNow\("([^"]+)"\)/g);
|
||||
if (!nodeMatches) nodeMatches = txt.match(/StartLoginInteractiveAs\("([^"]+)"\)/g);
|
||||
var node = null;
|
||||
if (nodeMatches) {
|
||||
var nm = nodeMatches[nodeMatches.length - 1].match(/"([^"]+)"/);
|
||||
if (nm) node = nm[1];
|
||||
}
|
||||
if (!node) {
|
||||
var hostMatches = txt.match(/^\S+\s+(\S+)\s+\[\s*INFO/gm);
|
||||
if (hostMatches) {
|
||||
var hm = hostMatches[hostMatches.length - 1].match(/^\S+\s+(\S+)/);
|
||||
if (hm) node = hm[1];
|
||||
}
|
||||
}
|
||||
|
||||
var loginMatch = txt.match(/active login:\s+(\S+)/);
|
||||
var tailnet = loginMatch ? loginMatch[1] : null;
|
||||
var loginMatches = txt.match(/active login:\s+\S+/g);
|
||||
var tailnet = null;
|
||||
if (loginMatches) {
|
||||
var lm = loginMatches[loginMatches.length - 1].match(/active login:\s+(\S+)/);
|
||||
if (lm) tailnet = lm[1];
|
||||
}
|
||||
|
||||
var versionMatch = txt.match(/Program starting: v(\d+\.\d+\.\d+)/);
|
||||
if (!versionMatch) versionMatch = txt.match(/tailscaled[\s_](\d+\.\d+\.\d+)/);
|
||||
var version = versionMatch ? versionMatch[1] : null;
|
||||
var versionMatches = txt.match(/Program starting: v(\d+\.\d+\.\d+)/g);
|
||||
var version = null;
|
||||
if (versionMatches) {
|
||||
var last = versionMatches[versionMatches.length - 1];
|
||||
var vm = last.match(/v(\d+\.\d+\.\d+)/);
|
||||
if (vm) version = vm[1];
|
||||
}
|
||||
|
||||
var stateLines = txt.match(/Switching ipn state [^\n]+/g) || [];
|
||||
var lastState = stateLines.length ? stateLines[stateLines.length - 1] : '';
|
||||
@@ -542,10 +564,15 @@
|
||||
setInterval(refresh, 5000);
|
||||
|
||||
// Check for updates from GitHub
|
||||
var latestChecked = false;
|
||||
function checkForUpdate(currentVersion) {
|
||||
if (!currentVersion || latestChecked) return;
|
||||
latestChecked = true;
|
||||
var installedVersion = null;
|
||||
var autoChecked = false;
|
||||
function checkForUpdate(currentVersion, manual) {
|
||||
if (!currentVersion) return;
|
||||
installedVersion = currentVersion;
|
||||
if (!manual && autoChecked) return;
|
||||
if (!manual) autoChecked = true;
|
||||
var btn = document.getElementById('check-update-btn');
|
||||
if (manual && btn) btn.textContent = 'Checking...';
|
||||
fetch('https://api.github.com/repos/Mo3he/Axis_Cam_Tailscale/releases/latest')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
@@ -555,11 +582,22 @@
|
||||
document.getElementById('update-version').textContent = 'v' + tag;
|
||||
document.getElementById('update-banner').classList.add('visible');
|
||||
document.getElementById('ts-version').textContent = currentVersion + ' (outdated)';
|
||||
if (btn) btn.textContent = 'Update Available';
|
||||
} else {
|
||||
if (manual && btn) btn.textContent = 'Up to date';
|
||||
setTimeout(function() { if (btn) btn.textContent = 'Check for Updates'; }, 3000);
|
||||
}
|
||||
})
|
||||
.catch(function() {});
|
||||
.catch(function() {
|
||||
if (manual && btn) btn.textContent = 'Check failed';
|
||||
setTimeout(function() { if (btn) btn.textContent = 'Check for Updates'; }, 3000);
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('check-update-btn').addEventListener('click', function() {
|
||||
if (installedVersion) checkForUpdate(installedVersion, true);
|
||||
});
|
||||
|
||||
function compareVersions(a, b) {
|
||||
var pa = a.split('.').map(Number);
|
||||
var pb = b.split('.').map(Number);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+51
-13
@@ -359,6 +359,9 @@
|
||||
<div class="info-value" id="ts-version">-</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:14px;text-align:right;">
|
||||
<button id="check-update-btn" class="log-toggle">Check for Updates</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Logs -->
|
||||
@@ -437,16 +440,35 @@
|
||||
tsIP = allIPs.length ? allIPs[allIPs.length - 1] : null;
|
||||
}
|
||||
|
||||
var nodeMatch = txt.match(/popBrowserAuthNow\("([^"]+)"\)/);
|
||||
if (!nodeMatch) nodeMatch = txt.match(/StartLoginInteractiveAs\("([^"]+)"\)/);
|
||||
var node = nodeMatch ? nodeMatch[1] : null;
|
||||
var nodeMatches = txt.match(/popBrowserAuthNow\("([^"]+)"\)/g);
|
||||
if (!nodeMatches) nodeMatches = txt.match(/StartLoginInteractiveAs\("([^"]+)"\)/g);
|
||||
var node = null;
|
||||
if (nodeMatches) {
|
||||
var nm = nodeMatches[nodeMatches.length - 1].match(/"([^"]+)"/);
|
||||
if (nm) node = nm[1];
|
||||
}
|
||||
if (!node) {
|
||||
var hostMatches = txt.match(/^\S+\s+(\S+)\s+\[\s*INFO/gm);
|
||||
if (hostMatches) {
|
||||
var hm = hostMatches[hostMatches.length - 1].match(/^\S+\s+(\S+)/);
|
||||
if (hm) node = hm[1];
|
||||
}
|
||||
}
|
||||
|
||||
var loginMatch = txt.match(/active login:\s+(\S+)/);
|
||||
var tailnet = loginMatch ? loginMatch[1] : null;
|
||||
var loginMatches = txt.match(/active login:\s+\S+/g);
|
||||
var tailnet = null;
|
||||
if (loginMatches) {
|
||||
var lm = loginMatches[loginMatches.length - 1].match(/active login:\s+(\S+)/);
|
||||
if (lm) tailnet = lm[1];
|
||||
}
|
||||
|
||||
var versionMatch = txt.match(/Program starting: v(\d+\.\d+\.\d+)/);
|
||||
if (!versionMatch) versionMatch = txt.match(/tailscaled[\s_](\d+\.\d+\.\d+)/);
|
||||
var version = versionMatch ? versionMatch[1] : null;
|
||||
var versionMatches = txt.match(/Program starting: v(\d+\.\d+\.\d+)/g);
|
||||
var version = null;
|
||||
if (versionMatches) {
|
||||
var last = versionMatches[versionMatches.length - 1];
|
||||
var vm = last.match(/v(\d+\.\d+\.\d+)/);
|
||||
if (vm) version = vm[1];
|
||||
}
|
||||
|
||||
var stateLines = txt.match(/Switching ipn state [^\n]+/g) || [];
|
||||
var lastState = stateLines.length ? stateLines[stateLines.length - 1] : '';
|
||||
@@ -542,10 +564,15 @@
|
||||
setInterval(refresh, 5000);
|
||||
|
||||
// Check for updates from GitHub
|
||||
var latestChecked = false;
|
||||
function checkForUpdate(currentVersion) {
|
||||
if (!currentVersion || latestChecked) return;
|
||||
latestChecked = true;
|
||||
var installedVersion = null;
|
||||
var autoChecked = false;
|
||||
function checkForUpdate(currentVersion, manual) {
|
||||
if (!currentVersion) return;
|
||||
installedVersion = currentVersion;
|
||||
if (!manual && autoChecked) return;
|
||||
if (!manual) autoChecked = true;
|
||||
var btn = document.getElementById('check-update-btn');
|
||||
if (manual && btn) btn.textContent = 'Checking...';
|
||||
fetch('https://api.github.com/repos/Mo3he/Axis_Cam_Tailscale/releases/latest')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
@@ -555,11 +582,22 @@
|
||||
document.getElementById('update-version').textContent = 'v' + tag;
|
||||
document.getElementById('update-banner').classList.add('visible');
|
||||
document.getElementById('ts-version').textContent = currentVersion + ' (outdated)';
|
||||
if (btn) btn.textContent = 'Update Available';
|
||||
} else {
|
||||
if (manual && btn) btn.textContent = 'Up to date';
|
||||
setTimeout(function() { if (btn) btn.textContent = 'Check for Updates'; }, 3000);
|
||||
}
|
||||
})
|
||||
.catch(function() {});
|
||||
.catch(function() {
|
||||
if (manual && btn) btn.textContent = 'Check failed';
|
||||
setTimeout(function() { if (btn) btn.textContent = 'Check for Updates'; }, 3000);
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('check-update-btn').addEventListener('click', function() {
|
||||
if (installedVersion) checkForUpdate(installedVersion, true);
|
||||
});
|
||||
|
||||
function compareVersions(a, b) {
|
||||
var pa = a.split('.').map(Number);
|
||||
var pb = b.split('.').map(Number);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -359,6 +359,9 @@
|
||||
<div class="info-value" id="ts-version">-</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:14px;text-align:right;">
|
||||
<button id="check-update-btn" class="log-toggle">Check for Updates</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Logs -->
|
||||
@@ -437,16 +440,35 @@
|
||||
tsIP = allIPs.length ? allIPs[allIPs.length - 1] : null;
|
||||
}
|
||||
|
||||
var nodeMatch = txt.match(/popBrowserAuthNow\("([^"]+)"\)/);
|
||||
if (!nodeMatch) nodeMatch = txt.match(/StartLoginInteractiveAs\("([^"]+)"\)/);
|
||||
var node = nodeMatch ? nodeMatch[1] : null;
|
||||
var nodeMatches = txt.match(/popBrowserAuthNow\("([^"]+)"\)/g);
|
||||
if (!nodeMatches) nodeMatches = txt.match(/StartLoginInteractiveAs\("([^"]+)"\)/g);
|
||||
var node = null;
|
||||
if (nodeMatches) {
|
||||
var nm = nodeMatches[nodeMatches.length - 1].match(/"([^"]+)"/);
|
||||
if (nm) node = nm[1];
|
||||
}
|
||||
if (!node) {
|
||||
var hostMatches = txt.match(/^\S+\s+(\S+)\s+\[\s*INFO/gm);
|
||||
if (hostMatches) {
|
||||
var hm = hostMatches[hostMatches.length - 1].match(/^\S+\s+(\S+)/);
|
||||
if (hm) node = hm[1];
|
||||
}
|
||||
}
|
||||
|
||||
var loginMatch = txt.match(/active login:\s+(\S+)/);
|
||||
var tailnet = loginMatch ? loginMatch[1] : null;
|
||||
var loginMatches = txt.match(/active login:\s+\S+/g);
|
||||
var tailnet = null;
|
||||
if (loginMatches) {
|
||||
var lm = loginMatches[loginMatches.length - 1].match(/active login:\s+(\S+)/);
|
||||
if (lm) tailnet = lm[1];
|
||||
}
|
||||
|
||||
var versionMatch = txt.match(/Program starting: v(\d+\.\d+\.\d+)/);
|
||||
if (!versionMatch) versionMatch = txt.match(/tailscaled[\s_](\d+\.\d+\.\d+)/);
|
||||
var version = versionMatch ? versionMatch[1] : null;
|
||||
var versionMatches = txt.match(/Program starting: v(\d+\.\d+\.\d+)/g);
|
||||
var version = null;
|
||||
if (versionMatches) {
|
||||
var last = versionMatches[versionMatches.length - 1];
|
||||
var vm = last.match(/v(\d+\.\d+\.\d+)/);
|
||||
if (vm) version = vm[1];
|
||||
}
|
||||
|
||||
var stateLines = txt.match(/Switching ipn state [^\n]+/g) || [];
|
||||
var lastState = stateLines.length ? stateLines[stateLines.length - 1] : '';
|
||||
@@ -542,10 +564,15 @@
|
||||
setInterval(refresh, 5000);
|
||||
|
||||
// Check for updates from GitHub
|
||||
var latestChecked = false;
|
||||
function checkForUpdate(currentVersion) {
|
||||
if (!currentVersion || latestChecked) return;
|
||||
latestChecked = true;
|
||||
var installedVersion = null;
|
||||
var autoChecked = false;
|
||||
function checkForUpdate(currentVersion, manual) {
|
||||
if (!currentVersion) return;
|
||||
installedVersion = currentVersion;
|
||||
if (!manual && autoChecked) return;
|
||||
if (!manual) autoChecked = true;
|
||||
var btn = document.getElementById('check-update-btn');
|
||||
if (manual && btn) btn.textContent = 'Checking...';
|
||||
fetch('https://api.github.com/repos/Mo3he/Axis_Cam_Tailscale/releases/latest')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
@@ -555,11 +582,22 @@
|
||||
document.getElementById('update-version').textContent = 'v' + tag;
|
||||
document.getElementById('update-banner').classList.add('visible');
|
||||
document.getElementById('ts-version').textContent = currentVersion + ' (outdated)';
|
||||
if (btn) btn.textContent = 'Update Available';
|
||||
} else {
|
||||
if (manual && btn) btn.textContent = 'Up to date';
|
||||
setTimeout(function() { if (btn) btn.textContent = 'Check for Updates'; }, 3000);
|
||||
}
|
||||
})
|
||||
.catch(function() {});
|
||||
.catch(function() {
|
||||
if (manual && btn) btn.textContent = 'Check failed';
|
||||
setTimeout(function() { if (btn) btn.textContent = 'Check for Updates'; }, 3000);
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('check-update-btn').addEventListener('click', function() {
|
||||
if (installedVersion) checkForUpdate(installedVersion, true);
|
||||
});
|
||||
|
||||
function compareVersions(a, b) {
|
||||
var pa = a.split('.').map(Number);
|
||||
var pb = b.split('.').map(Number);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -359,6 +359,9 @@
|
||||
<div class="info-value" id="ts-version">-</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:14px;text-align:right;">
|
||||
<button id="check-update-btn" class="log-toggle">Check for Updates</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Logs -->
|
||||
@@ -437,16 +440,35 @@
|
||||
tsIP = allIPs.length ? allIPs[allIPs.length - 1] : null;
|
||||
}
|
||||
|
||||
var nodeMatch = txt.match(/popBrowserAuthNow\("([^"]+)"\)/);
|
||||
if (!nodeMatch) nodeMatch = txt.match(/StartLoginInteractiveAs\("([^"]+)"\)/);
|
||||
var node = nodeMatch ? nodeMatch[1] : null;
|
||||
var nodeMatches = txt.match(/popBrowserAuthNow\("([^"]+)"\)/g);
|
||||
if (!nodeMatches) nodeMatches = txt.match(/StartLoginInteractiveAs\("([^"]+)"\)/g);
|
||||
var node = null;
|
||||
if (nodeMatches) {
|
||||
var nm = nodeMatches[nodeMatches.length - 1].match(/"([^"]+)"/);
|
||||
if (nm) node = nm[1];
|
||||
}
|
||||
if (!node) {
|
||||
var hostMatches = txt.match(/^\S+\s+(\S+)\s+\[\s*INFO/gm);
|
||||
if (hostMatches) {
|
||||
var hm = hostMatches[hostMatches.length - 1].match(/^\S+\s+(\S+)/);
|
||||
if (hm) node = hm[1];
|
||||
}
|
||||
}
|
||||
|
||||
var loginMatch = txt.match(/active login:\s+(\S+)/);
|
||||
var tailnet = loginMatch ? loginMatch[1] : null;
|
||||
var loginMatches = txt.match(/active login:\s+\S+/g);
|
||||
var tailnet = null;
|
||||
if (loginMatches) {
|
||||
var lm = loginMatches[loginMatches.length - 1].match(/active login:\s+(\S+)/);
|
||||
if (lm) tailnet = lm[1];
|
||||
}
|
||||
|
||||
var versionMatch = txt.match(/Program starting: v(\d+\.\d+\.\d+)/);
|
||||
if (!versionMatch) versionMatch = txt.match(/tailscaled[\s_](\d+\.\d+\.\d+)/);
|
||||
var version = versionMatch ? versionMatch[1] : null;
|
||||
var versionMatches = txt.match(/Program starting: v(\d+\.\d+\.\d+)/g);
|
||||
var version = null;
|
||||
if (versionMatches) {
|
||||
var last = versionMatches[versionMatches.length - 1];
|
||||
var vm = last.match(/v(\d+\.\d+\.\d+)/);
|
||||
if (vm) version = vm[1];
|
||||
}
|
||||
|
||||
var stateLines = txt.match(/Switching ipn state [^\n]+/g) || [];
|
||||
var lastState = stateLines.length ? stateLines[stateLines.length - 1] : '';
|
||||
@@ -542,10 +564,15 @@
|
||||
setInterval(refresh, 5000);
|
||||
|
||||
// Check for updates from GitHub
|
||||
var latestChecked = false;
|
||||
function checkForUpdate(currentVersion) {
|
||||
if (!currentVersion || latestChecked) return;
|
||||
latestChecked = true;
|
||||
var installedVersion = null;
|
||||
var autoChecked = false;
|
||||
function checkForUpdate(currentVersion, manual) {
|
||||
if (!currentVersion) return;
|
||||
installedVersion = currentVersion;
|
||||
if (!manual && autoChecked) return;
|
||||
if (!manual) autoChecked = true;
|
||||
var btn = document.getElementById('check-update-btn');
|
||||
if (manual && btn) btn.textContent = 'Checking...';
|
||||
fetch('https://api.github.com/repos/Mo3he/Axis_Cam_Tailscale/releases/latest')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
@@ -555,11 +582,22 @@
|
||||
document.getElementById('update-version').textContent = 'v' + tag;
|
||||
document.getElementById('update-banner').classList.add('visible');
|
||||
document.getElementById('ts-version').textContent = currentVersion + ' (outdated)';
|
||||
if (btn) btn.textContent = 'Update Available';
|
||||
} else {
|
||||
if (manual && btn) btn.textContent = 'Up to date';
|
||||
setTimeout(function() { if (btn) btn.textContent = 'Check for Updates'; }, 3000);
|
||||
}
|
||||
})
|
||||
.catch(function() {});
|
||||
.catch(function() {
|
||||
if (manual && btn) btn.textContent = 'Check failed';
|
||||
setTimeout(function() { if (btn) btn.textContent = 'Check for Updates'; }, 3000);
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('check-update-btn').addEventListener('click', function() {
|
||||
if (installedVersion) checkForUpdate(installedVersion, true);
|
||||
});
|
||||
|
||||
function compareVersions(a, b) {
|
||||
var pa = a.split('.').map(Number);
|
||||
var pb = b.split('.').map(Number);
|
||||
|
||||
+37
-6
@@ -403,11 +403,11 @@
|
||||
<h3>Standard (Non-Root)</h3>
|
||||
<p>For Axis OS 12 and newer. Runs in user-space networking mode without root privileges.</p>
|
||||
<div class="arch-buttons">
|
||||
<a class="arch-btn" href="https://github.com/Mo3he/Axis_Cam_Tailscale/releases/latest" target="_blank" rel="noopener">
|
||||
<a class="arch-btn" data-asset="Tailscale_VPN" data-arch="aarch64" href="https://github.com/Mo3he/Axis_Cam_Tailscale/releases/latest" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||
AARCH64
|
||||
</a>
|
||||
<a class="arch-btn" href="https://github.com/Mo3he/Axis_Cam_Tailscale/releases/latest" target="_blank" rel="noopener">
|
||||
<a class="arch-btn" data-asset="Tailscale_VPN" data-arch="armv7hf" href="https://github.com/Mo3he/Axis_Cam_Tailscale/releases/latest" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||
ARM
|
||||
</a>
|
||||
@@ -419,11 +419,11 @@
|
||||
<h3>Custom Server</h3>
|
||||
<p>Supports custom Tailscale control servers and auth keys. Ideal for self-hosted Headscale setups.</p>
|
||||
<div class="arch-buttons">
|
||||
<a class="arch-btn" href="https://github.com/Mo3he/Axis_Cam_Tailscale/releases/latest" target="_blank" rel="noopener">
|
||||
<a class="arch-btn" data-asset="custom" data-arch="aarch64" href="https://github.com/Mo3he/Axis_Cam_Tailscale/releases/latest" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||
AARCH64
|
||||
</a>
|
||||
<a class="arch-btn" href="https://github.com/Mo3he/Axis_Cam_Tailscale/releases/latest" target="_blank" rel="noopener">
|
||||
<a class="arch-btn" data-asset="custom" data-arch="armv7hf" href="https://github.com/Mo3he/Axis_Cam_Tailscale/releases/latest" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||
ARM
|
||||
</a>
|
||||
@@ -435,11 +435,11 @@
|
||||
<h3>Root (Full Networking)</h3>
|
||||
<p>For Axis OS older than 12. Requires root access but provides full Tailscale networking features.</p>
|
||||
<div class="arch-buttons">
|
||||
<a class="arch-btn" href="https://github.com/Mo3he/Axis_Cam_Tailscale/releases/latest" target="_blank" rel="noopener">
|
||||
<a class="arch-btn" data-asset="ROOT" data-arch="aarch64" href="https://github.com/Mo3he/Axis_Cam_Tailscale/releases/latest" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||
AARCH64
|
||||
</a>
|
||||
<a class="arch-btn" href="https://github.com/Mo3he/Axis_Cam_Tailscale/releases/latest" target="_blank" rel="noopener">
|
||||
<a class="arch-btn" data-asset="ROOT" data-arch="armv7hf" href="https://github.com/Mo3he/Axis_Cam_Tailscale/releases/latest" target="_blank" rel="noopener">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||
ARM
|
||||
</a>
|
||||
@@ -526,6 +526,37 @@
|
||||
applyTheme(e.matches ? 'light' : 'dark');
|
||||
}
|
||||
});
|
||||
|
||||
// Rewrite download links to point directly to latest release assets
|
||||
fetch('https://api.github.com/repos/Mo3he/Axis_Cam_Tailscale/releases/latest')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
var assets = data.assets || [];
|
||||
var buttons = document.querySelectorAll('a[data-asset]');
|
||||
for (var i = 0; i < buttons.length; i++) {
|
||||
var btn = buttons[i];
|
||||
var type = btn.getAttribute('data-asset');
|
||||
var arch = btn.getAttribute('data-arch');
|
||||
for (var j = 0; j < assets.length; j++) {
|
||||
var name = assets[j].name.toLowerCase();
|
||||
var archMatch = name.indexOf(arch) !== -1;
|
||||
var typeMatch = false;
|
||||
if (type === 'Tailscale_VPN') {
|
||||
typeMatch = name.indexOf('custom') === -1 && name.indexOf('root') === -1;
|
||||
} else if (type === 'custom') {
|
||||
typeMatch = name.indexOf('custom') !== -1;
|
||||
} else if (type === 'ROOT') {
|
||||
typeMatch = name.indexOf('root') !== -1;
|
||||
}
|
||||
if (archMatch && typeMatch) {
|
||||
btn.href = assets[j].browser_download_url;
|
||||
btn.removeAttribute('target');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(function() {});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user