tahamajs's picture
download
raw
8.1 kB
<!-- src/main/resources/static/offline.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>You're Offline - IE Research Platform</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
color: white;
}
.offline-container {
text-align: center;
padding: 2rem;
max-width: 500px;
}
.offline-icon {
font-size: 5rem;
margin-bottom: 1rem;
}
h1 {
font-size: 2rem;
margin-bottom: 1rem;
}
p {
margin-bottom: 1.5rem;
line-height: 1.6;
opacity: 0.9;
}
.saved-articles {
background: rgba(255,255,255,0.1);
border-radius: 12px;
padding: 1rem;
margin: 1.5rem 0;
text-align: left;
}
.saved-articles h3 {
margin-bottom: 0.5rem;
font-size: 1rem;
}
.saved-articles ul {
list-style: none;
}
.saved-articles li {
padding: 0.5rem 0;
border-bottom: 1px solid rgba(255,255,255,0.2);
}
.saved-articles li a {
color: white;
text-decoration: none;
}
button {
background: white;
color: #667eea;
border: none;
padding: 12px 24px;
border-radius: 25px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
margin: 0.5rem;
transition: transform 0.2s;
}
button:hover {
transform: translateY(-2px);
}
.retry-button {
background: rgba(255,255,255,0.2);
color: white;
}
.loading {
display: inline-block;
width: 20px;
height: 20px;
border: 2px solid #fff;
border-radius: 50%;
border-top-color: transparent;
animation: spin 1s linear infinite;
margin-left: 10px;
vertical-align: middle;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
</style>
</head>
<body>
<div class="offline-container">
<div class="offline-icon">๐Ÿ“ก</div>
<h1>You're Offline</h1>
<p>It looks like you've lost your internet connection. Don't worry! You can still access your saved content and continue working offline.</p>
<div class="saved-articles" id="saved-articles">
<h3>๐Ÿ“š Available Offline Content</h3>
<ul id="offline-list">
<li>Loading saved articles...</li>
</ul>
</div>
<div>
<button onclick="retryConnection()" class="retry-button" id="retry-btn">
๐Ÿ”„ Try to Reconnect
<span class="loading" style="display:none"></span>
</button>
<button onclick="goHome()">๐Ÿ  Go to Home</button>
</div>
</div>
<script>
// Load saved articles from IndexedDB
let db;
function initDB() {
const request = indexedDB.open('ResearchPlatform', 1);
request.onerror = (event) => {
console.error('IndexedDB error:', event);
document.getElementById('offline-list').innerHTML = '<li>No saved articles found</li>';
};
request.onsuccess = (event) => {
db = event.target.result;
loadSavedArticles();
};
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains('offlineArticles')) {
db.createObjectStore('offlineArticles', { keyPath: 'id' });
}
if (!db.objectStoreNames.contains('pendingActions')) {
db.createObjectStore('pendingActions', { keyPath: 'id', autoIncrement: true });
}
};
}
function loadSavedArticles() {
if (!db) {
initDB();
return;
}
const transaction = db.transaction(['offlineArticles'], 'readonly');
const store = transaction.objectStore('offlineArticles');
const request = store.getAll();
request.onsuccess = () => {
const articles = request.result;
const list = document.getElementById('offline-list');
if (articles.length === 0) {
list.innerHTML = '<li>No saved articles found. Save some articles for offline reading!</li>';
return;
}
list.innerHTML = articles.map(article => `
<li>
<a href="/article/${article.id}" onclick="return false;">
๐Ÿ“„ ${article.title}
</a>
</li>
`).join('');
};
request.onerror = () => {
document.getElementById('offline-list').innerHTML = '<li>Error loading saved articles</li>';
};
}
function retryConnection() {
const btn = document.getElementById('retry-btn');
const originalText = btn.innerHTML;
btn.innerHTML = '๐Ÿ”„ Checking connection... <span class="loading"></span>';
btn.disabled = true;
fetch('/api/health')
.then(response => {
if (response.ok) {
window.location.reload();
} else {
throw new Error('Server not responding');
}
})
.catch(() => {
btn.innerHTML = originalText;
btn.disabled = false;
alert('Still offline. Please check your internet connection and try again.');
});
}
function goHome() {
if (navigator.onLine) {
window.location.href = '/';
} else {
alert('You are still offline. Please connect to the internet first.');
}
}
// Listen for online status
window.addEventListener('online', () => {
document.querySelector('.offline-container').innerHTML += `
<div style="background: rgba(76, 175, 80, 0.9); padding: 10px; border-radius: 8px; margin-top: 1rem;">
โœ… You're back online! <a href="/" style="color: white;">Click here to refresh</a>
</div>
`;
});
// Initialize
initDB();
// Register service worker for offline capabilities
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
// Send message to get cached content
if (navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage({
type: 'GET_CACHED_ARTICLES'
});
}
});
}
</script>
</body>
</html>

Xet Storage Details

Size:
8.1 kB
ยท
Xet hash:
957b8406b91a47bf22fd5d429fd17764d532a9dbcaa071e80337dd0f78435234

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.