more fixes

This commit is contained in:
Andrey Kondratev
2025-08-29 11:29:28 +05:00
parent b483ed71f2
commit cfe2b459fb
6 changed files with 99 additions and 22 deletions

View File

@@ -121,6 +121,12 @@ jobs:
# Deploy with zero downtime # Deploy with zero downtime
docker-compose --env-file .env.docker pull docker-compose --env-file .env.docker pull
# Stop existing containers if they exist
if docker-compose --env-file .env.docker ps -q | grep -q .; then
docker-compose --env-file .env.docker down --remove-orphans
fi
docker-compose --env-file .env.docker up -d docker-compose --env-file .env.docker up -d
# Cleanup old images # Cleanup old images

View File

@@ -0,0 +1,19 @@
# Notification Animation Fix
Fixed the download notification display issue where notifications appeared strangely (first in corner, then stretched).
## Problem
- `.tg-status-message` had conflicting width properties
- Complex positioning caused weird stretch animation
- Used `transform: translateX(-50%)` with multiple width calculations
## Solution
- Simplified positioning: `left/right` with `var(--tg-spacing-lg)` margins
- Removed conflicting width properties (`max-width`, `width`, `min-width`)
- Changed position from `top: 80px` to `top: 20px`
- Updated animation from `tg-slide-in` to `tg-slide-down` for natural top-to-bottom appearance
## Files Modified
- `public/style.css`: Updated `.tg-status-message` styles and animation keyframes
The notification now appears smoothly at the top of the screen without strange stretching effects.

View File

@@ -28,7 +28,7 @@
<!-- Search results will appear here --> <!-- Search results will appear here -->
</div> </div>
<div class="tg-placeholder tg-placeholder--secondary tg-hidden" id="noResults"> <div class="tg-placeholder tg-placeholder--secondary tg-hidden" id="noResults" style="display: none;">
<div class="tg-placeholder__icon">🔍</div> <div class="tg-placeholder__icon">🔍</div>
<div class="tg-placeholder__title">Ничего не найдено</div> <div class="tg-placeholder__title">Ничего не найдено</div>
<div class="tg-placeholder__description">Попробуйте изменить поисковый запрос</div> <div class="tg-placeholder__description">Попробуйте изменить поисковый запрос</div>

View File

@@ -65,6 +65,9 @@ class QuixoticApp {
this.results = document.getElementById('results') as HTMLElement; this.results = document.getElementById('results') as HTMLElement;
this.noResults = document.getElementById('noResults') as HTMLElement; this.noResults = document.getElementById('noResults') as HTMLElement;
this.welcomePlaceholder = document.getElementById('welcomePlaceholder') as HTMLElement; this.welcomePlaceholder = document.getElementById('welcomePlaceholder') as HTMLElement;
// Initialize proper state - only welcome should be visible
this.resetToWelcomeState();
} }
private bindEvents(): void { private bindEvents(): void {
@@ -74,6 +77,30 @@ class QuixoticApp {
this.search(); this.search();
} }
}); });
// Reset to welcome state when input is cleared
this.searchInput.addEventListener('input', () => {
if (this.searchInput.value.trim() === '') {
this.resetToWelcomeState();
}
});
}
private resetToWelcomeState(): void {
// Show only welcome placeholder
this.welcomePlaceholder.classList.remove('tg-hidden');
this.welcomePlaceholder.style.display = '';
// Hide all other states
this.loading.classList.add('tg-hidden');
this.loading.classList.remove('tg-spinner--visible');
this.results.classList.add('tg-hidden');
this.results.classList.remove('tg-list--visible');
this.noResults.classList.add('tg-hidden');
this.noResults.style.display = 'none';
// Enable search button
this.searchBtn.disabled = false;
} }
private async search(): Promise<void> { private async search(): Promise<void> {
@@ -107,12 +134,26 @@ class QuixoticApp {
} }
private showLoading(): void { private showLoading(): void {
// Clear any existing status messages
const existingMessage = document.querySelector('.tg-status-message');
if (existingMessage) {
existingMessage.remove();
}
// Hide welcome immediately when loading starts
this.welcomePlaceholder.classList.add('tg-hidden'); this.welcomePlaceholder.classList.add('tg-hidden');
this.welcomePlaceholder.style.display = 'none';
// Show loading spinner
this.loading.classList.remove('tg-hidden'); this.loading.classList.remove('tg-hidden');
this.loading.classList.add('tg-spinner--visible'); this.loading.classList.add('tg-spinner--visible');
// Hide other elements
this.results.classList.add('tg-hidden'); this.results.classList.add('tg-hidden');
this.results.classList.remove('tg-list--visible'); this.results.classList.remove('tg-list--visible');
this.noResults.classList.add('tg-hidden'); this.noResults.classList.add('tg-hidden');
this.noResults.style.display = 'none';
this.searchBtn.disabled = true; this.searchBtn.disabled = true;
} }
@@ -130,6 +171,12 @@ class QuixoticApp {
return; return;
} }
// Hide welcome and no results
this.welcomePlaceholder.classList.add('tg-hidden');
this.welcomePlaceholder.style.display = 'none';
this.noResults.classList.add('tg-hidden');
this.noResults.style.display = 'none';
this.results.innerHTML = videos.map(video => ` this.results.innerHTML = videos.map(video => `
<div class='tg-list-item' onclick='app.convertVideo("${video.id}", "${this.escapeHtml(video.title)}", "${this.escapeHtml(video.url)}")'> <div class='tg-list-item' onclick='app.convertVideo("${video.id}", "${this.escapeHtml(video.title)}", "${this.escapeHtml(video.url)}")'>
<div class='tg-list-item__content'> <div class='tg-list-item__content'>
@@ -150,14 +197,16 @@ class QuixoticApp {
this.results.classList.remove('tg-hidden'); this.results.classList.remove('tg-hidden');
this.results.classList.add('tg-list--visible'); this.results.classList.add('tg-list--visible');
this.noResults.classList.add('tg-hidden');
} }
private showNoResults(): void { private showNoResults(): void {
this.hideLoading(); this.hideLoading();
this.welcomePlaceholder.classList.add('tg-hidden');
this.welcomePlaceholder.style.display = 'none';
this.results.classList.add('tg-hidden'); this.results.classList.add('tg-hidden');
this.results.classList.remove('tg-list--visible'); this.results.classList.remove('tg-list--visible');
this.noResults.classList.remove('tg-hidden'); this.noResults.classList.remove('tg-hidden');
this.noResults.style.display = '';
} }
public async convertVideo(videoId: string, title: string, url: string): Promise<void> { public async convertVideo(videoId: string, title: string, url: string): Promise<void> {

View File

@@ -198,9 +198,14 @@ body {
/* Spinner component */ /* Spinner component */
.tg-spinner { .tg-spinner {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center; text-align: center;
padding: var(--tg-spacing-xxl); padding: var(--tg-spacing-xxl);
display: none; display: none;
z-index: 10;
} }
.tg-spinner.tg-spinner--visible { .tg-spinner.tg-spinner--visible {
@@ -344,47 +349,45 @@ body {
/* Status message */ /* Status message */
.tg-status-message { .tg-status-message {
position: fixed; position: fixed;
top: 80px; top: 20px;
left: 50%; left: var(--tg-spacing-lg);
transform: translateX(-50%); right: var(--tg-spacing-lg);
z-index: 1000; z-index: 1000;
padding: var(--tg-spacing-md) var(--tg-spacing-lg); padding: var(--tg-spacing-md) var(--tg-spacing-lg);
border-radius: var(--tg-border-radius); border-radius: var(--tg-border-radius);
font-size: var(--tg-font-size-sm); font-size: var(--tg-font-size-sm);
font-weight: 500; font-weight: 500;
animation: tg-slide-in 0.3s ease-out; animation: tg-slide-down 0.3s ease-out;
display: flex; display: flex;
align-items: center; align-items: center;
gap: var(--tg-spacing-sm); gap: var(--tg-spacing-sm);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25), 0 4px 12px rgba(0, 0, 0, 0.15);
max-width: calc(100vw - 32px);
width: calc(100vw - 64px);
min-width: 300px;
} }
.tg-status-message--success { .tg-status-message--success {
background: rgba(52, 199, 89, 0.1); background: #34c759;
border: 1px solid rgba(52, 199, 89, 0.3); border: 1px solid #2aa854;
color: #34c759; color: #ffffff;
} }
.tg-status-message--error { .tg-status-message--error {
background: rgba(255, 59, 48, 0.1); background: #ff3b30;
border: 1px solid rgba(255, 59, 48, 0.3); border: 1px solid #d70015;
color: var(--tg-color-destructive); color: #ffffff;
} }
.tg-status-message--info { .tg-status-message--info {
background: rgba(0, 122, 255, 0.1); background: #007aff;
border: 1px solid rgba(0, 122, 255, 0.3); border: 1px solid #0056cc;
color: var(--tg-color-button); color: #ffffff;
} }
@keyframes tg-slide-in { @keyframes tg-slide-down {
from { from {
opacity: 0; opacity: 0;
transform: translateY(-10px); transform: translateY(-20px);
} }
to { to {
opacity: 1; opacity: 1;
transform: translateY(0); transform: translateY(0);
@@ -467,4 +470,4 @@ body {
--tg-color-text: var(--tg-theme-text-color, #ffffff); --tg-color-text: var(--tg-theme-text-color, #ffffff);
--tg-color-hint: var(--tg-theme-hint-color, #8e8e93); --tg-color-hint: var(--tg-theme-hint-color, #8e8e93);
} }
} }