Skip to content

Commit f4514aa

Browse files
committed
Revamp update notice and add manual update check
Refactored update banner styles and logic to use more generic notice classes and sessionStorage for dismissal. Added a 'Check for Updates' button in settings, manual update check functionality, and toast notifications for update status. Updated config version to 1.1.2b.
1 parent 53e9ae8 commit f4514aa

File tree

4 files changed

+108
-54
lines changed

4 files changed

+108
-54
lines changed

config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ build:
1313
- .template
1414
use_gitignore: true
1515

16-
version: '1.1.1b'
16+
version: '1.1.2b'

src/public/css/styles.css

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,7 @@ select:focus {
827827
}
828828
}
829829

830-
.update-banner {
830+
.app-notice {
831831
display: flex;
832832
align-items: center;
833833
justify-content: space-between;
@@ -844,13 +844,19 @@ select:focus {
844844
animation: slideDown 0.4s ease;
845845
}
846846

847-
.update-text i {
847+
.notice-text i {
848848
font-size: 1.1rem;
849849
margin-right: 0.5rem;
850850
color: #1e3a8a;
851851
}
852852

853-
.update-banner a {
853+
.notice-actions {
854+
display: flex;
855+
align-items: center;
856+
gap: 0.75rem;
857+
}
858+
859+
.notice-actions a {
854860
background: #3b82f6;
855861
color: #fff;
856862
text-decoration: none;
@@ -860,12 +866,12 @@ select:focus {
860866
transition: background 0.2s, transform 0.15s;
861867
}
862868

863-
.update-banner a:hover {
869+
.notice-actions a:hover {
864870
background: #2563eb;
865871
transform: translateY(-1px);
866872
}
867873

868-
.update-banner .dismiss-btn {
874+
.btn-secondary {
869875
background: transparent;
870876
color: #1e40af;
871877
border: 1px solid #93c5fd;
@@ -877,26 +883,42 @@ select:focus {
877883
transition: all 0.2s ease;
878884
}
879885

880-
.update-banner .dismiss-btn:hover {
886+
.btn-secondary:hover {
881887
background: #dbeafe;
882888
color: #1d4ed8;
883889
border-color: #3b82f6;
884890
transform: translateY(-1px);
885891
}
886892

887-
.update-actions {
888-
display: flex;
889-
align-items: center;
890-
gap: 0.75rem;
893+
.toast-message {
894+
position: fixed;
895+
bottom: 16px;
896+
right: 16px;
897+
background: #2563eb;
898+
color: #fff;
899+
padding: 0.6rem 1rem;
900+
border-radius: 6px;
901+
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
902+
font-size: 0.9rem;
903+
opacity: 0;
904+
transform: translateY(20px);
905+
transition: all 0.3s ease;
906+
z-index: 2000;
907+
}
908+
909+
.toast-message.visible {
910+
opacity: 1;
911+
transform: translateY(0);
891912
}
892913

893914
@keyframes slideDown {
894-
from {
895-
opacity: 0;
896-
transform: translateY(-10px);
897-
}
898-
to {
899-
opacity: 1;
900-
transform: translateY(0);
901-
}
915+
from { opacity: 0; transform: translateY(-10px); }
916+
to { opacity: 1; transform: translateY(0); }
917+
}
918+
919+
.info-buttons {
920+
display: flex;
921+
align-items: center;
922+
gap: 0.75rem;
923+
margin-bottom: 1rem;
902924
}

src/public/settings.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,15 @@
5555
</div>
5656

5757
<div class="group-box" data-title="Info">
58-
<button onclick="window.location.href='php-info.php'" title="View phpinfo().">
59-
<i class="ti ti-info-circle"></i>PHP Info
60-
</button>
61-
58+
<div class="info-buttons">
59+
<button onclick="window.location.href='php-info.php'" title="View phpinfo().">
60+
<i class="ti ti-info-circle"></i>PHP Info
61+
</button>
62+
63+
<button id="checkUpdatesBtn" title="Check for updates">
64+
<i class="ti ti-refresh"></i>Check for Updates
65+
</button>
66+
</div>
6267
<dl class="app-info-dl">
6368
<dt>Database Size</dt><dd><?= getFileSize(DB) ?></dd>
6469
<dt>Last updater run</dt><dd><?= htmlspecialchars($lastDynDnsRunValue) ?></dd>

src/templates/dashboard.j2

Lines changed: 58 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -39,59 +39,86 @@ if (!isset($_SESSION['user']) || empty($_SESSION['user'])) {
3939
</div>
4040

4141
<script>
42-
document.addEventListener('DOMContentLoaded', async () => {
43-
const currentVersion = '{{ cfg.version }}'; // your current app version
44-
const repo = 'TRC-Loop/CronDNS'; // your GitHub repo
45-
const releasesApi = `https://api.github.com/repos/${repo}/releases/latest`;
46-
47-
try {
48-
const res = await fetch(releasesApi, {
49-
headers: { 'User-Agent': 'CronDNS VersionCheck (crondns v{{ cfg.version }})' }
50-
});
42+
document.addEventListener('DOMContentLoaded', () => {
43+
const repo = 'TRC-Loop/CronDNS';
44+
const currentVersion = '{{ cfg.version }}';
45+
const checkButton = document.getElementById('checkUpdatesBtn');
5146
52-
if (!res.ok) return;
47+
async function checkForUpdates(manual = false) {
48+
const api = `https://api.github.com/repos/${repo}/releases/latest`;
49+
try {
50+
const res = await fetch(api, { headers: { 'User-Agent': 'CronDNS-VersionCheck' } });
51+
if (!res.ok) throw new Error('GitHub API error');
52+
const data = await res.json();
5353
54-
const data = await res.json();
55-
const latest = data.tag_name?.replace(/^v/i, '') ?? null;
56-
if (!latest) return;
54+
const latest = data.tag_name?.replace(/^v/i, '') ?? null;
55+
if (!latest) return;
5756
58-
const current = currentVersion.replace(/^v/i, '');
59-
if (isOutdated(current, latest)) showUpdateBanner(latest);
60-
} catch (err) {
61-
console.warn('Version check failed:', err);
57+
const current = currentVersion.replace(/^v/i, '');
58+
if (isOutdated(current, latest)) {
59+
showUpdateNotice(latest);
60+
if (manual) showToast(`New version available: v${latest}`);
61+
} else if (manual) {
62+
showToast(`You are up to date! (v${currentVersion})`);
63+
}
64+
} catch (err) {
65+
if (manual) showToast('Failed to check for updates.');
66+
console.warn('Version check failed:', err);
67+
}
6268
}
6369
6470
function isOutdated(current, latest) {
6571
const normalize = v => v.split(/[^0-9a-z]+/i).map(x => x.padStart(4, '0')).join('');
6672
return normalize(current) < normalize(latest);
6773
}
6874
69-
function showUpdateBanner(latest) {
70-
const dismissed = localStorage.getItem('dismissedVersion');
75+
function showUpdateNotice(latest) {
76+
const dismissed = sessionStorage.getItem('dismissedVersion');
7177
if (dismissed === latest) return;
7278
73-
const banner = document.createElement('div');
74-
banner.className = 'update-banner';
75-
banner.dataset.latest = latest;
76-
banner.innerHTML = `
77-
<div class="update-text">
79+
const notice = document.createElement('div');
80+
notice.className = 'app-notice';
81+
notice.dataset.latest = latest;
82+
notice.innerHTML = `
83+
<div class="notice-text">
7884
<i class="ti ti-alert-triangle"></i>
7985
<strong>Update available:</strong>
8086
You are using version <code>${currentVersion}</code>.
81-
The latest version is <code>${latest}</code>.
87+
Latest is <code>${latest}</code>.
8288
</div>
83-
<div class="update-actions">
89+
<div class="notice-actions">
8490
<a href="https://github.com/${repo}/releases/latest" target="_blank">Update Now</a>
85-
<button class="dismiss-btn" title="Hide this message">Dismiss</button>
91+
<button class="btn-secondary dismiss-notice">Dismiss</button>
8692
</div>
8793
`;
8894
8995
const content = document.querySelector('.content');
90-
content?.prepend(banner);
96+
content?.prepend(notice);
97+
98+
notice.querySelector('.dismiss-notice').addEventListener('click', () => {
99+
notice.remove();
100+
sessionStorage.setItem('dismissedVersion', latest);
101+
});
102+
}
103+
104+
function showToast(text) {
105+
const t = document.createElement('div');
106+
t.className = 'toast-message';
107+
t.textContent = text;
108+
document.body.appendChild(t);
109+
setTimeout(() => t.classList.add('visible'), 10);
110+
setTimeout(() => t.classList.remove('visible'), 2500);
111+
setTimeout(() => t.remove(), 3000);
112+
}
113+
114+
// Auto check on load
115+
checkForUpdates();
91116
92-
banner.querySelector('.dismiss-btn').addEventListener('click', () => {
93-
banner.remove();
94-
localStorage.setItem('dismissedVersion', latest);
117+
// Manual recheck
118+
if (checkButton) {
119+
checkButton.addEventListener('click', () => {
120+
sessionStorage.removeItem('dismissedVersion'); // clear before recheck
121+
checkForUpdates(true);
95122
});
96123
}
97124
});

0 commit comments

Comments
 (0)