hide messages
This commit is contained in:
@@ -1026,7 +1026,7 @@ class QuixoticApp {
|
|||||||
// Remove existing message if any
|
// Remove existing message if any
|
||||||
const existingMessage = document.querySelector('.tg-status-message');
|
const existingMessage = document.querySelector('.tg-status-message');
|
||||||
if (existingMessage) {
|
if (existingMessage) {
|
||||||
existingMessage.remove();
|
this.hideMessage(existingMessage as HTMLElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create message element
|
// Create message element
|
||||||
@@ -1034,15 +1034,37 @@ class QuixoticApp {
|
|||||||
messageEl.className = `tg-status-message tg-status-message--${type}`;
|
messageEl.className = `tg-status-message tg-status-message--${type}`;
|
||||||
messageEl.textContent = message;
|
messageEl.textContent = message;
|
||||||
|
|
||||||
|
// Add click handler to dismiss
|
||||||
|
let hideTimeout: NodeJS.Timeout;
|
||||||
|
|
||||||
|
const hideHandler = () => {
|
||||||
|
clearTimeout(hideTimeout);
|
||||||
|
this.hideMessage(messageEl);
|
||||||
|
};
|
||||||
|
|
||||||
|
messageEl.addEventListener('click', hideHandler);
|
||||||
|
|
||||||
// Add to body (fixed position, won't affect layout)
|
// Add to body (fixed position, won't affect layout)
|
||||||
document.body.appendChild(messageEl);
|
document.body.appendChild(messageEl);
|
||||||
|
|
||||||
// Auto-remove after 5 seconds
|
// Auto-remove after 3 seconds (было 5)
|
||||||
|
hideTimeout = setTimeout(() => {
|
||||||
|
if (messageEl.parentNode) {
|
||||||
|
this.hideMessage(messageEl);
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private hideMessage(messageEl: HTMLElement): void {
|
||||||
|
// Add hiding class for fade-out animation
|
||||||
|
messageEl.classList.add('tg-status-message--hiding');
|
||||||
|
|
||||||
|
// Remove after animation completes (300ms)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (messageEl.parentNode) {
|
if (messageEl.parentNode) {
|
||||||
messageEl.remove();
|
messageEl.remove();
|
||||||
}
|
}
|
||||||
}, 5000);
|
}, 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
private escapeHtml(text: string): string {
|
private escapeHtml(text: string): string {
|
||||||
@@ -1133,13 +1155,27 @@ class QuixoticApp {
|
|||||||
this.stopAudioPreview();
|
this.stopAudioPreview();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Play audio
|
// Play audio with autoplay error handling
|
||||||
await this.currentAudio.play();
|
try {
|
||||||
this.triggerHaptic('light');
|
await this.currentAudio.play();
|
||||||
|
this.triggerHaptic('light');
|
||||||
|
} catch (playError: any) {
|
||||||
|
console.error('Autoplay error:', playError);
|
||||||
|
|
||||||
|
// If autoplay is blocked, show message and clean up
|
||||||
|
if (playError.name === 'NotAllowedError') {
|
||||||
|
this.stopAudioPreview();
|
||||||
|
item.classList.remove('tg-list-item--loading-preview');
|
||||||
|
this.showMessage('🔇 Воспроизведение заблокировано. Нажмите еще раз.', 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw playError;
|
||||||
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Preview error:', error);
|
console.error('Preview error:', error);
|
||||||
item.classList.remove('tg-list-item--loading-preview');
|
item.classList.remove('tg-list-item--loading-preview');
|
||||||
|
this.stopAudioPreview();
|
||||||
this.showMessage('❌ Не удалось воспроизвести превью', 'error');
|
this.showMessage('❌ Не удалось воспроизвести превью', 'error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -666,6 +666,16 @@ body {
|
|||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(0, 0, 0, 0.12);
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(0, 0, 0, 0.12);
|
||||||
max-width: 320px;
|
max-width: 320px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: opacity 0.3s ease, transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tg-status-message:active {
|
||||||
|
transform: scale(0.98);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tg-status-message--hiding {
|
||||||
|
animation: tg-fade-out 0.3s ease-out forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tg-status-message--success {
|
.tg-status-message--success {
|
||||||
@@ -686,6 +696,12 @@ body {
|
|||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tg-status-message--warning {
|
||||||
|
background: #ff9500;
|
||||||
|
border: 1px solid #e68500;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes tg-slide-down {
|
@keyframes tg-slide-down {
|
||||||
from {
|
from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@@ -698,6 +714,18 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes tg-fade-out {
|
||||||
|
from {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-12px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Update notification */
|
/* Update notification */
|
||||||
.tg-update-notification {
|
.tg-update-notification {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ app.use((req: Request, res: Response, next) => {
|
|||||||
'style-src \'self\' \'unsafe-inline\'; ' +
|
'style-src \'self\' \'unsafe-inline\'; ' +
|
||||||
'img-src \'self\' data: https:; ' +
|
'img-src \'self\' data: https:; ' +
|
||||||
'font-src \'self\'; ' +
|
'font-src \'self\'; ' +
|
||||||
|
'media-src \'self\' blob: data:; ' +
|
||||||
'connect-src \'self\' https://telegram.org; ' +
|
'connect-src \'self\' https://telegram.org; ' +
|
||||||
'frame-ancestors \'self\'; ' +
|
'frame-ancestors \'self\'; ' +
|
||||||
'base-uri \'self\'; ' +
|
'base-uri \'self\'; ' +
|
||||||
|
|||||||
Reference in New Issue
Block a user