feat: Ajout de spinners pendant l'initialisation des services
- Spinner global pendant l'initialisation des services (service.ts) - Spinner pour l'initialisation de la page d'accueil (home.ts) - Amélioration du feedback utilisateur pendant les phases d'attente - Design glassmorphism cohérent avec l'interface existante - Messages informatifs pour guider l'utilisateur - Gestion d'erreurs avec masquage automatique des spinners
This commit is contained in:
parent
60f19752d3
commit
3258b16a6e
@ -6,9 +6,99 @@ import { getCorrectDOM } from '../../utils/html.utils';
|
||||
import QrScannerComponent from '../../components/qrcode-scanner/qrcode-scanner-component';
|
||||
import { navigate, registerAllListeners } from '../../router';
|
||||
|
||||
// Home page loading spinner functions
|
||||
function showHomeLoadingSpinner(message: string = 'Loading...') {
|
||||
// Remove existing spinner if any
|
||||
hideHomeLoadingSpinner();
|
||||
|
||||
// Create spinner overlay
|
||||
const overlay = document.createElement('div');
|
||||
overlay.id = 'home-loading-overlay';
|
||||
overlay.style.cssText = `
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 9998;
|
||||
backdrop-filter: blur(3px);
|
||||
`;
|
||||
|
||||
// Create spinner content
|
||||
const spinnerContent = document.createElement('div');
|
||||
spinnerContent.style.cssText = `
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 12px;
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
max-width: 350px;
|
||||
width: 90%;
|
||||
`;
|
||||
|
||||
// Create spinner
|
||||
const spinner = document.createElement('div');
|
||||
spinner.style.cssText = `
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 3px solid #f3f3f3;
|
||||
border-top: 3px solid #3a506b;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin: 0 auto 15px auto;
|
||||
`;
|
||||
|
||||
// Create message
|
||||
const messageEl = document.createElement('div');
|
||||
messageEl.textContent = message;
|
||||
messageEl.style.cssText = `
|
||||
font-size: 14px;
|
||||
color: #3a506b;
|
||||
font-weight: 500;
|
||||
`;
|
||||
|
||||
// Add CSS animation if not already present
|
||||
if (!document.getElementById('home-spinner-styles')) {
|
||||
const style = document.createElement('style');
|
||||
style.id = 'home-spinner-styles';
|
||||
style.textContent = `
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
// Assemble spinner
|
||||
spinnerContent.appendChild(spinner);
|
||||
spinnerContent.appendChild(messageEl);
|
||||
overlay.appendChild(spinnerContent);
|
||||
|
||||
// Add to document
|
||||
document.body.appendChild(overlay);
|
||||
}
|
||||
|
||||
function hideHomeLoadingSpinner() {
|
||||
const overlay = document.getElementById('home-loading-overlay');
|
||||
if (overlay) {
|
||||
overlay.remove();
|
||||
}
|
||||
}
|
||||
|
||||
export { QrScannerComponent };
|
||||
export async function initHomePage(): Promise<void> {
|
||||
console.log('INIT-HOME');
|
||||
|
||||
// Show loading spinner during home page initialization
|
||||
showHomeLoadingSpinner('Initializing pairing interface...');
|
||||
|
||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement;
|
||||
container.querySelectorAll('.tab').forEach((tab) => {
|
||||
addSubscription(tab, 'click', () => {
|
||||
@ -20,11 +110,20 @@ export async function initHomePage(): Promise<void> {
|
||||
});
|
||||
});
|
||||
|
||||
const service = await Services.getInstance();
|
||||
const spAddress = await service.getDeviceAddress();
|
||||
// generateQRCode(spAddress);
|
||||
generateCreateBtn();
|
||||
displayEmojis(spAddress);
|
||||
try {
|
||||
const service = await Services.getInstance();
|
||||
const spAddress = await service.getDeviceAddress();
|
||||
// generateQRCode(spAddress);
|
||||
generateCreateBtn();
|
||||
displayEmojis(spAddress);
|
||||
|
||||
// Hide loading spinner after initialization
|
||||
hideHomeLoadingSpinner();
|
||||
} catch (error) {
|
||||
console.error('Error initializing home page:', error);
|
||||
hideHomeLoadingSpinner();
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Add this line to populate the select when the page loads
|
||||
await populateMemberSelect();
|
||||
|
||||
@ -15,6 +15,102 @@ const BOOTSTRAPURL = [import.meta.env.VITE_BOOTSTRAPURL || `${BASEURL}:8090`];
|
||||
const STORAGEURL = import.meta.env.VITE_STORAGEURL || `${BASEURL}:8081`;
|
||||
const BLINDBITURL = import.meta.env.VITE_BLINDBITURL || `${BASEURL}:8000`;
|
||||
const DEFAULTAMOUNT = 1000n;
|
||||
|
||||
// Global loading spinner functions
|
||||
function showGlobalLoadingSpinner(message: string = 'Loading...') {
|
||||
// Remove existing spinner if any
|
||||
hideGlobalLoadingSpinner();
|
||||
|
||||
// Create spinner overlay
|
||||
const overlay = document.createElement('div');
|
||||
overlay.id = 'global-loading-overlay';
|
||||
overlay.style.cssText = `
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 9999;
|
||||
backdrop-filter: blur(5px);
|
||||
`;
|
||||
|
||||
// Create spinner content
|
||||
const spinnerContent = document.createElement('div');
|
||||
spinnerContent.style.cssText = `
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 12px;
|
||||
padding: 40px;
|
||||
text-align: center;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
max-width: 400px;
|
||||
width: 90%;
|
||||
`;
|
||||
|
||||
// Create spinner
|
||||
const spinner = document.createElement('div');
|
||||
spinner.style.cssText = `
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 4px solid #f3f3f3;
|
||||
border-top: 4px solid #3a506b;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin: 0 auto 20px auto;
|
||||
`;
|
||||
|
||||
// Create message
|
||||
const messageEl = document.createElement('div');
|
||||
messageEl.textContent = message;
|
||||
messageEl.style.cssText = `
|
||||
font-size: 16px;
|
||||
color: #3a506b;
|
||||
font-weight: 500;
|
||||
margin-bottom: 10px;
|
||||
`;
|
||||
|
||||
// Create progress indicator
|
||||
const progressEl = document.createElement('div');
|
||||
progressEl.textContent = 'Please wait...';
|
||||
progressEl.style.cssText = `
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
`;
|
||||
|
||||
// Add CSS animation if not already present
|
||||
if (!document.getElementById('global-spinner-styles')) {
|
||||
const style = document.createElement('style');
|
||||
style.id = 'global-spinner-styles';
|
||||
style.textContent = `
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
// Assemble spinner
|
||||
spinnerContent.appendChild(spinner);
|
||||
spinnerContent.appendChild(messageEl);
|
||||
spinnerContent.appendChild(progressEl);
|
||||
overlay.appendChild(spinnerContent);
|
||||
|
||||
// Add to document
|
||||
document.body.appendChild(overlay);
|
||||
}
|
||||
|
||||
function hideGlobalLoadingSpinner() {
|
||||
const overlay = document.getElementById('global-loading-overlay');
|
||||
if (overlay) {
|
||||
overlay.remove();
|
||||
}
|
||||
}
|
||||
const EMPTY32BYTES = String('').padStart(64, '0');
|
||||
|
||||
export default class Services {
|
||||
@ -53,8 +149,16 @@ export default class Services {
|
||||
}
|
||||
|
||||
console.log('initializing services');
|
||||
|
||||
// Show global loading spinner during initialization
|
||||
showGlobalLoadingSpinner('Initializing services...');
|
||||
|
||||
Services.instance = await Services.initializing;
|
||||
Services.initializing = null; // Reset for potential future use
|
||||
|
||||
// Hide loading spinner after initialization
|
||||
hideGlobalLoadingSpinner();
|
||||
|
||||
return Services.instance;
|
||||
}
|
||||
|
||||
|
||||
@ -421,8 +421,15 @@ function showLoadingState() {
|
||||
const loadingFlow = container.querySelector('#loading-flow');
|
||||
const creatorFlow = container.querySelector('#creator-flow');
|
||||
const joinerFlow = container.querySelector('#joiner-flow');
|
||||
|
||||
if (loadingFlow) loadingFlow.style.display = 'block';
|
||||
|
||||
if (loadingFlow) {
|
||||
loadingFlow.style.display = 'block';
|
||||
// Update loading message
|
||||
const loadingText = loadingFlow.querySelector('h2');
|
||||
const loadingDesc = loadingFlow.querySelector('p');
|
||||
if (loadingText) loadingText.textContent = 'Initializing...';
|
||||
if (loadingDesc) loadingDesc.textContent = 'Setting up secure pairing interface';
|
||||
}
|
||||
if (creatorFlow) creatorFlow.style.display = 'none';
|
||||
if (joinerFlow) joinerFlow.style.display = 'none';
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user