Skip to content

Commit 87e1c26

Browse files
committed
feat: add blazor reconnect
1 parent 5860b66 commit 87e1c26

1 file changed

Lines changed: 164 additions & 1 deletion

File tree

TelegramDownloader/Pages/_Layout.cshtml

Lines changed: 164 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,100 @@
2929

3030

3131

32+
<!-- Reconnection UI -->
33+
<div id="reconnect-modal" style="display: none;">
34+
<div class="reconnect-overlay"></div>
35+
<div class="reconnect-dialog">
36+
<div class="reconnect-icon">
37+
<i class="bi bi-wifi-off"></i>
38+
</div>
39+
<h4>Connection Lost</h4>
40+
<p id="reconnect-status">Attempting to reconnect...</p>
41+
<div class="reconnect-spinner"></div>
42+
<button id="reconnect-reload" style="display: none;" onclick="location.reload()">
43+
<i class="bi bi-arrow-clockwise"></i> Reload Page
44+
</button>
45+
</div>
46+
</div>
47+
48+
<style>
49+
#reconnect-modal {
50+
position: fixed;
51+
top: 0;
52+
left: 0;
53+
width: 100%;
54+
height: 100%;
55+
z-index: 99999;
56+
}
57+
.reconnect-overlay {
58+
position: absolute;
59+
top: 0;
60+
left: 0;
61+
width: 100%;
62+
height: 100%;
63+
background: rgba(0, 0, 0, 0.7);
64+
backdrop-filter: blur(4px);
65+
}
66+
.reconnect-dialog {
67+
position: absolute;
68+
top: 50%;
69+
left: 50%;
70+
transform: translate(-50%, -50%);
71+
background: #1e1e2e;
72+
border: 1px solid rgba(255, 255, 255, 0.1);
73+
border-radius: 1rem;
74+
padding: 2rem;
75+
text-align: center;
76+
color: white;
77+
min-width: 300px;
78+
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.5);
79+
}
80+
.reconnect-icon {
81+
font-size: 3rem;
82+
color: #f59e0b;
83+
margin-bottom: 1rem;
84+
}
85+
.reconnect-dialog h4 {
86+
margin: 0 0 0.5rem 0;
87+
font-weight: 600;
88+
}
89+
.reconnect-dialog p {
90+
margin: 0 0 1.5rem 0;
91+
color: rgba(255, 255, 255, 0.6);
92+
font-size: 0.9rem;
93+
}
94+
.reconnect-spinner {
95+
width: 40px;
96+
height: 40px;
97+
border: 3px solid rgba(255, 255, 255, 0.1);
98+
border-top-color: #0088cc;
99+
border-radius: 50%;
100+
margin: 0 auto;
101+
animation: spin 1s linear infinite;
102+
}
103+
@@keyframes spin {
104+
to { transform: rotate(360deg); }
105+
}
106+
#reconnect-reload {
107+
margin-top: 1.5rem;
108+
padding: 0.75rem 1.5rem;
109+
background: linear-gradient(135deg, #0088cc 0%, #0066aa 100%);
110+
border: none;
111+
border-radius: 0.5rem;
112+
color: white;
113+
font-weight: 500;
114+
cursor: pointer;
115+
display: inline-flex;
116+
align-items: center;
117+
gap: 0.5rem;
118+
transition: all 0.2s ease;
119+
}
120+
#reconnect-reload:hover {
121+
background: linear-gradient(135deg, #0099dd 0%, #0077bb 100%);
122+
transform: translateY(-1px);
123+
}
124+
</style>
125+
32126
<div id="blazor-error-ui">
33127
<environment include="Staging,Production">
34128
An error has occurred. This application may no longer respond until reloaded.
@@ -41,7 +135,76 @@
41135
</div>
42136
<script src="https://cdn.jsdelivr.net/npm/intl-tel-input@23.0.12/build/js/intlTelInput.min.js"></script>
43137
<script src="js/phonecodes.js"></script>
44-
<script src="_framework/blazor.server.js"></script>
138+
<script src="_framework/blazor.server.js" autostart="false"></script>
139+
<script>
140+
// Blazor reconnection handler
141+
(function () {
142+
const modal = document.getElementById('reconnect-modal');
143+
const status = document.getElementById('reconnect-status');
144+
const spinner = document.querySelector('.reconnect-spinner');
145+
const reloadBtn = document.getElementById('reconnect-reload');
146+
let reconnectAttempts = 0;
147+
const maxAttempts = 10;
148+
149+
function showModal(message, showReload = false) {
150+
modal.style.display = 'block';
151+
status.textContent = message;
152+
spinner.style.display = showReload ? 'none' : 'block';
153+
reloadBtn.style.display = showReload ? 'inline-flex' : 'none';
154+
}
155+
156+
function hideModal() {
157+
modal.style.display = 'none';
158+
reconnectAttempts = 0;
159+
}
160+
161+
Blazor.start({
162+
reconnectionHandler: {
163+
onConnectionDown: (options, error) => {
164+
reconnectAttempts = 0;
165+
showModal('Connection lost. Reconnecting...');
166+
console.log('Blazor connection down:', error);
167+
},
168+
onConnectionUp: () => {
169+
hideModal();
170+
console.log('Blazor connection restored');
171+
}
172+
},
173+
reconnectionOptions: {
174+
maxRetries: maxAttempts,
175+
retryIntervalMilliseconds: (previousAttempts) => {
176+
reconnectAttempts = previousAttempts + 1;
177+
178+
if (reconnectAttempts >= maxAttempts) {
179+
showModal('Unable to reconnect. Please reload the page.', true);
180+
return null; // Stop retrying
181+
}
182+
183+
showModal(`Reconnecting... Attempt ${reconnectAttempts}/${maxAttempts}`);
184+
185+
// Exponential backoff: 1s, 2s, 4s, 8s... max 30s
186+
const delay = Math.min(1000 * Math.pow(2, previousAttempts), 30000);
187+
return delay;
188+
}
189+
}
190+
});
191+
192+
// Auto-reload when tab becomes visible if connection was lost
193+
document.addEventListener('visibilitychange', () => {
194+
if (document.visibilityState === 'visible') {
195+
// Check if Blazor circuit is still connected
196+
if (modal.style.display === 'block') {
197+
// Connection was lost, try to reconnect or reload
198+
setTimeout(() => {
199+
if (modal.style.display === 'block') {
200+
location.reload();
201+
}
202+
}, 3000);
203+
}
204+
}
205+
});
206+
})();
207+
</script>
45208
<script src="js/bootstrap5/bootstrap.bundle.min.js"></script>
46209
<!-- Add chart.js reference if chart components are used in your application. -->
47210
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

0 commit comments

Comments
 (0)