Raí Santos commited on
Commit ·
8a34622
1
Parent(s): 47fa0d6
oi
Browse files- README.md +21 -1
- public/app.js +93 -17
- public/styles.css +107 -37
- public/sw.js +12 -3
- scripts/download-videos.js +8 -0
README.md
CHANGED
|
@@ -171,7 +171,27 @@ MIT License - Veja o arquivo LICENSE para mais detalhes.
|
|
| 171 |
|
| 172 |
## 🐛 Correções Recentes
|
| 173 |
|
| 174 |
-
### v3.10.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 175 |
✅ **3 Critical Bugs Fixed**: Memory leaks resolvidos (94% reduction)
|
| 176 |
✅ **Local Videos**: Vídeos baixados durante build (31 MB) para performance máxima
|
| 177 |
✅ **Smart Fallback**: Se local falhar, usa CDN automaticamente
|
|
|
|
| 171 |
|
| 172 |
## 🐛 Correções Recentes
|
| 173 |
|
| 174 |
+
### v3.10.2 (Atual) - SESSION LOGIC + AUTO-UPDATE 🎯🔄✨
|
| 175 |
+
✅ **Thematic Sections**: 5 organized sessions (Abdômen, Massagem Facial, Cintura, Pernas, Postura/Mobilidade)
|
| 176 |
+
✅ **Session Isolation**: Skip stays within session only
|
| 177 |
+
✅ **Green Marking**: Completed sessions marked ✅ automatically
|
| 178 |
+
✅ **Auto-Return**: Returns to personalized view after completion
|
| 179 |
+
✅ **PWA Auto-Update**: skipWaiting + clients.claim (zero user action)
|
| 180 |
+
✅ **Rounded Header**: Beautiful workout header with shadow
|
| 181 |
+
✅ **20 Reps Update**: 3 key exercises updated to 20 reps × 3 sets
|
| 182 |
+
✅ **Bug Fixes**: 4 bugs found and fixed
|
| 183 |
+
✅ **Performance**: 60fps, 56.5KB bundle, 0 memory leaks
|
| 184 |
+
|
| 185 |
+
### v3.10.1 - NEW EXERCISES + PREMIUM UI 🆕💎✨
|
| 186 |
+
✅ **6 Novos Exercícios**: Mobilidade/Alongamento adicionados
|
| 187 |
+
✅ **Play Button Removed**: Vídeos auto-play (experiência seamless)
|
| 188 |
+
✅ **Premium Exercise Screen**: Glass morphism + gradient text
|
| 189 |
+
✅ **Seção Costas/Mobilidade**: 7 exercícios (30 reps × 6 sets)
|
| 190 |
+
✅ **Gasto Calórico**: 9-15 cal por exercício novo
|
| 191 |
+
✅ **Download Script**: 6 novos vídeos incluídos
|
| 192 |
+
✅ **UI Refinements**: Floating effects + animations premium
|
| 193 |
+
|
| 194 |
+
### v3.10.0 - PREMIUM OPTIMIZATION + BUG FIXES 🎥⚡💎🐛
|
| 195 |
✅ **3 Critical Bugs Fixed**: Memory leaks resolvidos (94% reduction)
|
| 196 |
✅ **Local Videos**: Vídeos baixados durante build (31 MB) para performance máxima
|
| 197 |
✅ **Smart Fallback**: Se local falhar, usa CDN automaticamente
|
public/app.js
CHANGED
|
@@ -1540,6 +1540,11 @@ class FitnessApp {
|
|
| 1540 |
e.stopPropagation();
|
| 1541 |
document.getElementById('completionModal').classList.remove('active');
|
| 1542 |
this.playCuteSound('tap');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1543 |
// Volta para a lista de exercícios, não para home
|
| 1544 |
if (this.currentCategory) {
|
| 1545 |
this.goBack();
|
|
@@ -1691,11 +1696,11 @@ class FitnessApp {
|
|
| 1691 |
// If personalized, organize by sections
|
| 1692 |
if (category === 'personalized') {
|
| 1693 |
const sections = {
|
| 1694 |
-
'Abdômen': exercises.slice(0, 5),
|
| 1695 |
-
'
|
| 1696 |
-
'Cintura': exercises.slice(9, 12),
|
| 1697 |
-
'Pernas': exercises.slice(12, 13),
|
| 1698 |
-
'
|
| 1699 |
};
|
| 1700 |
|
| 1701 |
// Store sections info for workout management
|
|
@@ -1709,6 +1714,15 @@ class FitnessApp {
|
|
| 1709 |
// Add section header
|
| 1710 |
const sectionHeader = document.createElement('div');
|
| 1711 |
sectionHeader.className = 'section-header';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1712 |
sectionHeader.innerHTML = `<h3>${sectionName}</h3>`;
|
| 1713 |
fragment.appendChild(sectionHeader); // Add to fragment
|
| 1714 |
|
|
@@ -2220,12 +2234,31 @@ class FitnessApp {
|
|
| 2220 |
});
|
| 2221 |
});
|
| 2222 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2223 |
// Update streak
|
| 2224 |
this.updateStreak();
|
| 2225 |
|
| 2226 |
this.saveProgress();
|
| 2227 |
|
| 2228 |
-
//
|
| 2229 |
this.updateAllStats();
|
| 2230 |
|
| 2231 |
// Play completion sounds
|
|
@@ -2260,6 +2293,15 @@ class FitnessApp {
|
|
| 2260 |
|
| 2261 |
document.getElementById('completionModal').classList.add('active');
|
| 2262 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2263 |
// Check for achievements
|
| 2264 |
this.checkAchievements();
|
| 2265 |
|
|
@@ -3524,10 +3566,10 @@ class FitnessApp {
|
|
| 3524 |
const exercises = {
|
| 3525 |
personalized: [
|
| 3526 |
// 🔥 Abdômen com vídeos do Hugging Face
|
| 3527 |
-
{ name: 'Prancha com Balanço Lateral', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20balan%C3%A7o%20lateral.mp4', sets: 3, reps: '
|
| 3528 |
-
{ name: 'Prancha com Elevação de Perna', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20eleva%C3%A7%C3%A3o%20de%20perna.mp4', sets: 3, reps: '
|
| 3529 |
{ name: 'Tesoura (Scissor Kicks)', emoji: '✂️', video: this.VIDEO_BASE_URL + 'Scissor%20Kicks.mp4', sets: 3, reps: '15', rest: 30, calories: 9 },
|
| 3530 |
-
{ name: 'Elevação Alternada de Pernas', emoji: '🦵', video: this.VIDEO_BASE_URL + 'Alternating%20Leg%20Lifts.mp4', sets: 3, reps: '
|
| 3531 |
{ name: 'Prancha Lateral com Rotação', emoji: '🔄', video: this.VIDEO_BASE_URL + 'prancha%20lateral%20com%20rota%C3%A7%C3%A3o.mp4', sets: 3, reps: '10 cada', rest: 30, calories: 10 },
|
| 3532 |
|
| 3533 |
// 😊 Rosto com vídeos do Hugging Face
|
|
@@ -3544,14 +3586,20 @@ class FitnessApp {
|
|
| 3544 |
// 🏋️♀️ Pernas/Glúteos com vídeo do Hugging Face
|
| 3545 |
{ name: 'Agachamento com Rotação', emoji: '🏋️♀️', video: this.VIDEO_BASE_URL + 'agachamento%20rota%C3%A7%C3%A3o.mp4', sets: 3, reps: '12', rest: 35, calories: 12 },
|
| 3546 |
|
| 3547 |
-
// 🧘♀️ Costas/Flexibilidade com
|
| 3548 |
-
{ name: 'Flexão e Extensão do Tronco', emoji: '🧘♀️', video: this.VIDEO_BASE_URL + 'flexao%2C%20extens%C3%A3o%20e%20hiperextenxao%20do%20tronco%20com%20baco%20estendido.mp4', sets:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3549 |
],
|
| 3550 |
abs: [
|
| 3551 |
-
{ name: 'Prancha com Balanço Lateral', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20balan%C3%A7o%20lateral.mp4', sets: 3, reps: '
|
| 3552 |
-
{ name: 'Prancha com Elevação de Perna', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20eleva%C3%A7%C3%A3o%20de%20perna.mp4', sets: 3, reps: '
|
| 3553 |
{ name: 'Tesoura (Scissor Kicks)', emoji: '✂️', video: this.VIDEO_BASE_URL + 'Scissor%20Kicks.mp4', sets: 3, reps: '15', rest: 30, calories: 9 },
|
| 3554 |
-
{ name: 'Elevação Alternada de Pernas', emoji: '🦵', video: this.VIDEO_BASE_URL + 'Alternating%20Leg%20Lifts.mp4', sets: 3, reps: '
|
| 3555 |
{ name: 'Prancha Lateral com Rotação', emoji: '🔄', video: this.VIDEO_BASE_URL + 'prancha%20lateral%20com%20rota%C3%A7%C3%A3o.mp4', sets: 3, reps: '10 cada', rest: 30, calories: 10 }
|
| 3556 |
],
|
| 3557 |
legs: [
|
|
@@ -3691,11 +3739,39 @@ class FitnessApp {
|
|
| 3691 |
document.addEventListener('DOMContentLoaded', () => {
|
| 3692 |
window.app = new FitnessApp();
|
| 3693 |
|
| 3694 |
-
// Register Service Worker for PWA
|
| 3695 |
if ('serviceWorker' in navigator) {
|
| 3696 |
navigator.serviceWorker.register('/sw.js')
|
| 3697 |
-
.then(reg =>
|
| 3698 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3699 |
}
|
| 3700 |
});
|
| 3701 |
|
|
|
|
| 1540 |
e.stopPropagation();
|
| 1541 |
document.getElementById('completionModal').classList.remove('active');
|
| 1542 |
this.playCuteSound('tap');
|
| 1543 |
+
// 🎯 Return to personalized view if completing a session
|
| 1544 |
+
if (this.currentSectionName && this.currentCategory === 'personalized') {
|
| 1545 |
+
this.showCategoryExercises('personalized');
|
| 1546 |
+
return;
|
| 1547 |
+
}
|
| 1548 |
// Volta para a lista de exercícios, não para home
|
| 1549 |
if (this.currentCategory) {
|
| 1550 |
this.goBack();
|
|
|
|
| 1696 |
// If personalized, organize by sections
|
| 1697 |
if (category === 'personalized') {
|
| 1698 |
const sections = {
|
| 1699 |
+
'Abdômen': exercises.slice(0, 5), // 5 exercícios
|
| 1700 |
+
'Massagem Facial': exercises.slice(5, 9), // 4 exercícios
|
| 1701 |
+
'Cintura': exercises.slice(9, 12), // 3 exercícios
|
| 1702 |
+
'Pernas': exercises.slice(12, 13), // 1 exercício
|
| 1703 |
+
'Postura e Mobilidade': exercises.slice(13, 20) // 7 exercícios (yoga/alongamento)
|
| 1704 |
};
|
| 1705 |
|
| 1706 |
// Store sections info for workout management
|
|
|
|
| 1714 |
// Add section header
|
| 1715 |
const sectionHeader = document.createElement('div');
|
| 1716 |
sectionHeader.className = 'section-header';
|
| 1717 |
+
|
| 1718 |
+
// ✅ Mark as completed if done today
|
| 1719 |
+
const today = new Date().toDateString();
|
| 1720 |
+
if (this.progress.completedSections &&
|
| 1721 |
+
this.progress.completedSections[today] &&
|
| 1722 |
+
this.progress.completedSections[today].includes(sectionName)) {
|
| 1723 |
+
sectionHeader.classList.add('completed');
|
| 1724 |
+
}
|
| 1725 |
+
|
| 1726 |
sectionHeader.innerHTML = `<h3>${sectionName}</h3>`;
|
| 1727 |
fragment.appendChild(sectionHeader); // Add to fragment
|
| 1728 |
|
|
|
|
| 2234 |
});
|
| 2235 |
});
|
| 2236 |
|
| 2237 |
+
// Track completed sections for green marking
|
| 2238 |
+
if (this.currentSectionName && this.currentCategory === 'personalized') {
|
| 2239 |
+
if (!this.progress.completedSections) {
|
| 2240 |
+
this.progress.completedSections = {};
|
| 2241 |
+
}
|
| 2242 |
+
const today = new Date().toDateString();
|
| 2243 |
+
if (!this.progress.completedSections[today]) {
|
| 2244 |
+
this.progress.completedSections[today] = [];
|
| 2245 |
+
}
|
| 2246 |
+
if (!this.progress.completedSections[today].includes(this.currentSectionName)) {
|
| 2247 |
+
this.progress.completedSections[today].push(this.currentSectionName);
|
| 2248 |
+
}
|
| 2249 |
+
}
|
| 2250 |
+
|
| 2251 |
+
// Keep only last 50 exercises (cleanup old data)
|
| 2252 |
+
if (this.progress.completedExercises.length > 50) {
|
| 2253 |
+
this.progress.completedExercises = this.progress.completedExercises.slice(-50);
|
| 2254 |
+
}
|
| 2255 |
+
|
| 2256 |
// Update streak
|
| 2257 |
this.updateStreak();
|
| 2258 |
|
| 2259 |
this.saveProgress();
|
| 2260 |
|
| 2261 |
+
// FIX: Atualiza todos os stats após completar treino
|
| 2262 |
this.updateAllStats();
|
| 2263 |
|
| 2264 |
// Play completion sounds
|
|
|
|
| 2293 |
|
| 2294 |
document.getElementById('completionModal').classList.add('active');
|
| 2295 |
|
| 2296 |
+
// 🎯 AUTO-CLOSE: Close modal and return to personalized sections after 3 seconds
|
| 2297 |
+
if (this.currentSectionName && this.currentCategory === 'personalized') {
|
| 2298 |
+
setTimeout(() => {
|
| 2299 |
+
document.getElementById('completionModal').classList.remove('active');
|
| 2300 |
+
// Return to personalized view to choose next session
|
| 2301 |
+
this.showCategoryExercises('personalized');
|
| 2302 |
+
}, 3000);
|
| 2303 |
+
}
|
| 2304 |
+
|
| 2305 |
// Check for achievements
|
| 2306 |
this.checkAchievements();
|
| 2307 |
|
|
|
|
| 3566 |
const exercises = {
|
| 3567 |
personalized: [
|
| 3568 |
// 🔥 Abdômen com vídeos do Hugging Face
|
| 3569 |
+
{ name: 'Prancha com Balanço Lateral', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20balan%C3%A7o%20lateral.mp4', sets: 3, reps: '20', rest: 30, calories: 10 },
|
| 3570 |
+
{ name: 'Prancha com Elevação de Perna', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20eleva%C3%A7%C3%A3o%20de%20perna.mp4', sets: 3, reps: '20', rest: 30, calories: 12 },
|
| 3571 |
{ name: 'Tesoura (Scissor Kicks)', emoji: '✂️', video: this.VIDEO_BASE_URL + 'Scissor%20Kicks.mp4', sets: 3, reps: '15', rest: 30, calories: 9 },
|
| 3572 |
+
{ name: 'Elevação Alternada de Pernas', emoji: '🦵', video: this.VIDEO_BASE_URL + 'Alternating%20Leg%20Lifts.mp4', sets: 3, reps: '20', rest: 30, calories: 10 },
|
| 3573 |
{ name: 'Prancha Lateral com Rotação', emoji: '🔄', video: this.VIDEO_BASE_URL + 'prancha%20lateral%20com%20rota%C3%A7%C3%A3o.mp4', sets: 3, reps: '10 cada', rest: 30, calories: 10 },
|
| 3574 |
|
| 3575 |
// 😊 Rosto com vídeos do Hugging Face
|
|
|
|
| 3586 |
// 🏋️♀️ Pernas/Glúteos com vídeo do Hugging Face
|
| 3587 |
{ name: 'Agachamento com Rotação', emoji: '🏋️♀️', video: this.VIDEO_BASE_URL + 'agachamento%20rota%C3%A7%C3%A3o.mp4', sets: 3, reps: '12', rest: 35, calories: 12 },
|
| 3588 |
|
| 3589 |
+
// 🧘♀️ Costas/Mobilidade/Flexibilidade com vídeos do Hugging Face
|
| 3590 |
+
{ name: 'Flexão e Extensão do Tronco', emoji: '🧘♀️', video: this.VIDEO_BASE_URL + 'flexao%2C%20extens%C3%A3o%20e%20hiperextenxao%20do%20tronco%20com%20baco%20estendido.mp4', sets: 6, reps: '30', rest: 30, calories: 15 },
|
| 3591 |
+
{ name: 'Alcance Cruzado por Trás das Costas', emoji: '💪', video: this.VIDEO_BASE_URL + 'Alcance%20cruzado%20por%20tr%C3%A1s%20das%20costas%20(pegada%20alternada).mp4', sets: 6, reps: '30', rest: 30, calories: 12 },
|
| 3592 |
+
{ name: 'Alongamento de Peitoral', emoji: '💆♀️', video: this.VIDEO_BASE_URL + 'Alongamento%20de%20Peitoral%20com%20M%C3%A3os%20Entrela%C3%A7adas%20Atr%C3%A1s%20do%20Corpo.mp4', sets: 6, reps: '30', rest: 30, calories: 10 },
|
| 3593 |
+
{ name: 'Circundução Orbital com Garrafa', emoji: '🔄', video: this.VIDEO_BASE_URL + 'Circundu%C3%A7%C3%A3o%20%20%C3%B3rbita%20com%20a%20garrafa%20ao%20redor%20da%20nuca%20com%20reverso.mp4', sets: 6, reps: '30', rest: 30, calories: 14 },
|
| 3594 |
+
{ name: 'Mobilidade de Ombro com Apoio', emoji: '🏋️♀️', video: this.VIDEO_BASE_URL + 'MobilidadeAlongamento%20de%20Ombro%20com%20Apoio%20(Garrafa%20ou%20Outro%20Objeto.mp4', sets: 6, reps: '30', rest: 30, calories: 11 },
|
| 3595 |
+
{ name: 'Scapular Winging Exercise', emoji: '✨', video: this.VIDEO_BASE_URL + 'Scapular%20winging%20exercise%20ou%20Elbow%20fly%20stretch.mp4', sets: 6, reps: '30', rest: 30, calories: 13 },
|
| 3596 |
+
{ name: 'Overhead Triceps Stretch', emoji: '💪', video: this.VIDEO_BASE_URL + 'Overhead%20triceps%20stretch.mp4', sets: 6, reps: '30', rest: 30, calories: 9 }
|
| 3597 |
],
|
| 3598 |
abs: [
|
| 3599 |
+
{ name: 'Prancha com Balanço Lateral', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20balan%C3%A7o%20lateral.mp4', sets: 3, reps: '20', rest: 30, calories: 10 },
|
| 3600 |
+
{ name: 'Prancha com Elevação de Perna', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20eleva%C3%A7%C3%A3o%20de%20perna.mp4', sets: 3, reps: '20', rest: 30, calories: 12 },
|
| 3601 |
{ name: 'Tesoura (Scissor Kicks)', emoji: '✂️', video: this.VIDEO_BASE_URL + 'Scissor%20Kicks.mp4', sets: 3, reps: '15', rest: 30, calories: 9 },
|
| 3602 |
+
{ name: 'Elevação Alternada de Pernas', emoji: '🦵', video: this.VIDEO_BASE_URL + 'Alternating%20Leg%20Lifts.mp4', sets: 3, reps: '20', rest: 30, calories: 10 },
|
| 3603 |
{ name: 'Prancha Lateral com Rotação', emoji: '🔄', video: this.VIDEO_BASE_URL + 'prancha%20lateral%20com%20rota%C3%A7%C3%A3o.mp4', sets: 3, reps: '10 cada', rest: 30, calories: 10 }
|
| 3604 |
],
|
| 3605 |
legs: [
|
|
|
|
| 3739 |
document.addEventListener('DOMContentLoaded', () => {
|
| 3740 |
window.app = new FitnessApp();
|
| 3741 |
|
| 3742 |
+
// Register Service Worker for PWA functionality with auto-update
|
| 3743 |
if ('serviceWorker' in navigator) {
|
| 3744 |
navigator.serviceWorker.register('/sw.js')
|
| 3745 |
+
.then(reg => {
|
| 3746 |
+
console.log(' Service Worker registered');
|
| 3747 |
+
|
| 3748 |
+
// AUTO-UPDATE: Listen for updates
|
| 3749 |
+
reg.addEventListener('updatefound', () => {
|
| 3750 |
+
const newWorker = reg.installing;
|
| 3751 |
+
console.log(' New Service Worker found, installing...');
|
| 3752 |
+
|
| 3753 |
+
newWorker.addEventListener('statechange', () => {
|
| 3754 |
+
if (newWorker.state === 'activated') {
|
| 3755 |
+
console.log(' New Service Worker activated!');
|
| 3756 |
+
}
|
| 3757 |
+
});
|
| 3758 |
+
});
|
| 3759 |
+
})
|
| 3760 |
+
.catch(err => console.error(' Service Worker registration failed:', err));
|
| 3761 |
+
|
| 3762 |
+
// Listen for Service Worker updates
|
| 3763 |
+
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
| 3764 |
+
console.log(' Service Worker controller changed - app updated!');
|
| 3765 |
+
// Show subtle notification
|
| 3766 |
+
this.showToast('');
|
| 3767 |
+
});
|
| 3768 |
+
|
| 3769 |
+
// Listen for messages from Service Worker
|
| 3770 |
+
navigator.serviceWorker.addEventListener('message', (event) => {
|
| 3771 |
+
if (event.data && event.data.type === 'SW_UPDATED') {
|
| 3772 |
+
console.log(` Service Worker updated to ${event.data.version}`);
|
| 3773 |
+
}
|
| 3774 |
+
});
|
| 3775 |
}
|
| 3776 |
});
|
| 3777 |
|
public/styles.css
CHANGED
|
@@ -776,6 +776,9 @@ body {
|
|
| 776 |
justify-content: space-between;
|
| 777 |
align-items: center;
|
| 778 |
color: var(--white);
|
|
|
|
|
|
|
|
|
|
| 779 |
}
|
| 780 |
|
| 781 |
.btn-close-workout {
|
|
@@ -809,23 +812,42 @@ body {
|
|
| 809 |
|
| 810 |
.exercise-display {
|
| 811 |
text-align: center;
|
|
|
|
| 812 |
}
|
| 813 |
|
| 814 |
.exercise-name {
|
| 815 |
-
font-size: 1.
|
| 816 |
font-weight: 700;
|
| 817 |
color: var(--text-primary);
|
| 818 |
-
margin-bottom: var(--spacing-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 819 |
}
|
| 820 |
|
| 821 |
.exercise-count {
|
| 822 |
-
font-size:
|
|
|
|
| 823 |
color: var(--text-secondary);
|
| 824 |
-
margin-bottom: var(--spacing-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 825 |
}
|
| 826 |
|
| 827 |
.exercise-demo {
|
| 828 |
margin: var(--spacing-xl) 0;
|
|
|
|
|
|
|
| 829 |
}
|
| 830 |
|
| 831 |
.demo-placeholder {
|
|
@@ -833,12 +855,35 @@ body {
|
|
| 833 |
max-width: 700px;
|
| 834 |
margin: 0 auto;
|
| 835 |
background: transparent;
|
| 836 |
-
border-radius: var(--radius-lg);
|
| 837 |
display: flex;
|
| 838 |
align-items: center;
|
| 839 |
justify-content: center;
|
| 840 |
overflow: hidden;
|
| 841 |
position: relative;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 842 |
}
|
| 843 |
|
| 844 |
.demo-icon {
|
|
@@ -858,33 +903,9 @@ body {
|
|
| 858 |
transform: translateZ(0);
|
| 859 |
}
|
| 860 |
|
| 861 |
-
|
| 862 |
-
|
| 863 |
-
|
| 864 |
-
left: 50%;
|
| 865 |
-
transform: translate(-50%, -50%);
|
| 866 |
-
background: rgba(255, 107, 157, 0.95);
|
| 867 |
-
color: white;
|
| 868 |
-
border: 3px solid white;
|
| 869 |
-
border-radius: var(--radius-full);
|
| 870 |
-
padding: 16px 32px;
|
| 871 |
-
font-size: 1.2rem;
|
| 872 |
-
font-weight: 700;
|
| 873 |
-
cursor: pointer;
|
| 874 |
-
transition: all 0.3s ease;
|
| 875 |
-
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
| 876 |
-
z-index: 10;
|
| 877 |
-
animation: pulse 2s infinite;
|
| 878 |
-
}
|
| 879 |
-
|
| 880 |
-
.video-play-button:hover {
|
| 881 |
-
background: rgba(255, 107, 157, 1);
|
| 882 |
-
transform: translate(-50%, -50%) scale(1.1);
|
| 883 |
-
}
|
| 884 |
-
|
| 885 |
-
.video-play-button:active {
|
| 886 |
-
transform: translate(-50%, -50%) scale(0.95);
|
| 887 |
-
}
|
| 888 |
|
| 889 |
@keyframes pulse {
|
| 890 |
0%, 100% {
|
|
@@ -900,15 +921,44 @@ body {
|
|
| 900 |
}
|
| 901 |
|
| 902 |
.reps-info {
|
| 903 |
-
font-size: 1.
|
| 904 |
-
font-weight:
|
| 905 |
-
color: var(--primary);
|
| 906 |
-
margin-bottom: var(--spacing-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 907 |
}
|
| 908 |
|
| 909 |
.rest-info {
|
| 910 |
-
font-size:
|
|
|
|
| 911 |
color: var(--text-secondary);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 912 |
}
|
| 913 |
|
| 914 |
.series-tracker {
|
|
@@ -1457,6 +1507,26 @@ body {
|
|
| 1457 |
border-left: 4px solid var(--primary);
|
| 1458 |
}
|
| 1459 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1460 |
.btn-edit-profile {
|
| 1461 |
width: 100%;
|
| 1462 |
padding: 16px;
|
|
|
|
| 776 |
justify-content: space-between;
|
| 777 |
align-items: center;
|
| 778 |
color: var(--white);
|
| 779 |
+
/* 💫 PREMIUM: Rounded bottom corners */
|
| 780 |
+
border-radius: 0 0 var(--radius-xl) var(--radius-xl);
|
| 781 |
+
box-shadow: 0 4px 20px rgba(255, 107, 157, 0.2);
|
| 782 |
}
|
| 783 |
|
| 784 |
.btn-close-workout {
|
|
|
|
| 812 |
|
| 813 |
.exercise-display {
|
| 814 |
text-align: center;
|
| 815 |
+
animation: fadeIn 0.4s ease;
|
| 816 |
}
|
| 817 |
|
| 818 |
.exercise-name {
|
| 819 |
+
font-size: 1.75rem;
|
| 820 |
font-weight: 700;
|
| 821 |
color: var(--text-primary);
|
| 822 |
+
margin-bottom: var(--spacing-md);
|
| 823 |
+
letter-spacing: -0.5px;
|
| 824 |
+
/* 💫 PREMIUM: Text gradient */
|
| 825 |
+
background: var(--gradient-primary);
|
| 826 |
+
-webkit-background-clip: text;
|
| 827 |
+
-webkit-text-fill-color: transparent;
|
| 828 |
+
background-clip: text;
|
| 829 |
}
|
| 830 |
|
| 831 |
.exercise-count {
|
| 832 |
+
font-size: 1rem;
|
| 833 |
+
font-weight: 600;
|
| 834 |
color: var(--text-secondary);
|
| 835 |
+
margin-bottom: var(--spacing-xl);
|
| 836 |
+
/* 💫 PREMIUM: Glass morphism badge */
|
| 837 |
+
background: rgba(255, 255, 255, 0.9);
|
| 838 |
+
backdrop-filter: blur(10px);
|
| 839 |
+
-webkit-backdrop-filter: blur(10px);
|
| 840 |
+
padding: var(--spacing-sm) var(--spacing-lg);
|
| 841 |
+
border-radius: var(--radius-full);
|
| 842 |
+
display: inline-block;
|
| 843 |
+
box-shadow: var(--shadow-sm);
|
| 844 |
+
border: 1px solid rgba(255, 107, 157, 0.1);
|
| 845 |
}
|
| 846 |
|
| 847 |
.exercise-demo {
|
| 848 |
margin: var(--spacing-xl) 0;
|
| 849 |
+
/* 💫 PREMIUM: Container animation */
|
| 850 |
+
animation: scaleIn 0.5s cubic-bezier(0.4, 0, 0.2, 1);
|
| 851 |
}
|
| 852 |
|
| 853 |
.demo-placeholder {
|
|
|
|
| 855 |
max-width: 700px;
|
| 856 |
margin: 0 auto;
|
| 857 |
background: transparent;
|
| 858 |
+
border-radius: var(--radius-lg);
|
| 859 |
display: flex;
|
| 860 |
align-items: center;
|
| 861 |
justify-content: center;
|
| 862 |
overflow: hidden;
|
| 863 |
position: relative;
|
| 864 |
+
/* 💫 PREMIUM: Floating effect */
|
| 865 |
+
box-shadow:
|
| 866 |
+
0 20px 60px rgba(255, 107, 157, 0.15),
|
| 867 |
+
0 0 0 1px rgba(255, 255, 255, 0.5) inset;
|
| 868 |
+
transition: all 0.3s ease;
|
| 869 |
+
}
|
| 870 |
+
|
| 871 |
+
.demo-placeholder:hover {
|
| 872 |
+
transform: translateY(-4px);
|
| 873 |
+
box-shadow:
|
| 874 |
+
0 24px 80px rgba(255, 107, 157, 0.2),
|
| 875 |
+
0 0 0 1px rgba(255, 255, 255, 0.6) inset;
|
| 876 |
+
}
|
| 877 |
+
|
| 878 |
+
@keyframes scaleIn {
|
| 879 |
+
0% {
|
| 880 |
+
opacity: 0;
|
| 881 |
+
transform: scale(0.9);
|
| 882 |
+
}
|
| 883 |
+
100% {
|
| 884 |
+
opacity: 1;
|
| 885 |
+
transform: scale(1);
|
| 886 |
+
}
|
| 887 |
}
|
| 888 |
|
| 889 |
.demo-icon {
|
|
|
|
| 903 |
transform: translateZ(0);
|
| 904 |
}
|
| 905 |
|
| 906 |
+
/* 💫 REMOVED: Video play button (user requested)
|
| 907 |
+
Videos auto-play on exercise screen for seamless experience
|
| 908 |
+
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 909 |
|
| 910 |
@keyframes pulse {
|
| 911 |
0%, 100% {
|
|
|
|
| 921 |
}
|
| 922 |
|
| 923 |
.reps-info {
|
| 924 |
+
font-size: 1.25rem;
|
| 925 |
+
font-weight: 700;
|
| 926 |
+
color: var(--text-primary);
|
| 927 |
+
margin-bottom: var(--spacing-md);
|
| 928 |
+
/* 💫 PREMIUM: Glass card */
|
| 929 |
+
background: rgba(255, 255, 255, 0.95);
|
| 930 |
+
backdrop-filter: blur(10px);
|
| 931 |
+
-webkit-backdrop-filter: blur(10px);
|
| 932 |
+
padding: var(--spacing-md) var(--spacing-lg);
|
| 933 |
+
border-radius: var(--radius-lg);
|
| 934 |
+
box-shadow: var(--shadow-md);
|
| 935 |
+
border: 2px solid rgba(255, 107, 157, 0.15);
|
| 936 |
+
display: inline-block;
|
| 937 |
+
/* 💫 PREMIUM: Icon before */
|
| 938 |
+
}
|
| 939 |
+
|
| 940 |
+
.reps-info::before {
|
| 941 |
+
content: '💪';
|
| 942 |
+
margin-right: var(--spacing-sm);
|
| 943 |
+
font-size: 1.3rem;
|
| 944 |
}
|
| 945 |
|
| 946 |
.rest-info {
|
| 947 |
+
font-size: 1rem;
|
| 948 |
+
font-weight: 600;
|
| 949 |
color: var(--text-secondary);
|
| 950 |
+
margin-bottom: var(--spacing-xl);
|
| 951 |
+
/* 💫 PREMIUM: Subtle badge */
|
| 952 |
+
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
| 953 |
+
padding: var(--spacing-sm) var(--spacing-lg);
|
| 954 |
+
border-radius: var(--radius-full);
|
| 955 |
+
display: inline-block;
|
| 956 |
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
| 957 |
+
}
|
| 958 |
+
|
| 959 |
+
.rest-info::before {
|
| 960 |
+
content: '⏱️';
|
| 961 |
+
margin-right: var(--spacing-xs);
|
| 962 |
}
|
| 963 |
|
| 964 |
.series-tracker {
|
|
|
|
| 1507 |
border-left: 4px solid var(--primary);
|
| 1508 |
}
|
| 1509 |
|
| 1510 |
+
.section-header {
|
| 1511 |
+
background: rgba(255, 107, 157, 0.1);
|
| 1512 |
+
padding: var(--spacing-md);
|
| 1513 |
+
margin: var(--spacing-md) 0;
|
| 1514 |
+
border-radius: var(--radius-md);
|
| 1515 |
+
border-left: 4px solid var(--primary-color);
|
| 1516 |
+
transition: all 0.3s ease;
|
| 1517 |
+
}
|
| 1518 |
+
|
| 1519 |
+
/* ✅ COMPLETED SECTION - Green marking */
|
| 1520 |
+
.section-header.completed {
|
| 1521 |
+
background: rgba(76, 175, 80, 0.15);
|
| 1522 |
+
border-left: 4px solid #4CAF50;
|
| 1523 |
+
}
|
| 1524 |
+
|
| 1525 |
+
.section-header.completed h3::before {
|
| 1526 |
+
content: '✅ ';
|
| 1527 |
+
margin-right: var(--spacing-xs);
|
| 1528 |
+
}
|
| 1529 |
+
|
| 1530 |
.btn-edit-profile {
|
| 1531 |
width: 100%;
|
| 1532 |
padding: 16px;
|
public/sw.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
| 1 |
// 🌟 PREMIUM PWA SERVICE WORKER v3.10.0
|
| 2 |
-
//
|
| 3 |
-
|
|
|
|
|
|
|
| 4 |
const CACHE_NAME = `fitness-app-${VERSION}`;
|
| 5 |
const STATIC_CACHE = `static-${VERSION}`;
|
| 6 |
const DYNAMIC_CACHE = `dynamic-${VERSION}`;
|
|
@@ -39,6 +41,11 @@ const STATIC_ASSETS = [
|
|
| 39 |
|
| 40 |
// 🚀 Install event - Premium caching strategy
|
| 41 |
self.addEventListener('install', (event) => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
console.log('🌟 [SW] Installing Premium Service Worker v' + VERSION);
|
| 43 |
|
| 44 |
event.waitUntil(
|
|
@@ -56,7 +63,7 @@ self.addEventListener('install', (event) => {
|
|
| 56 |
caches.open(FONT_CACHE)
|
| 57 |
]).then(() => {
|
| 58 |
console.log('✅ [SW] Installation complete!');
|
| 59 |
-
return self.
|
| 60 |
}).catch(err => {
|
| 61 |
console.error('❌ [SW] Installation failed:', err);
|
| 62 |
})
|
|
@@ -65,6 +72,8 @@ self.addEventListener('install', (event) => {
|
|
| 65 |
|
| 66 |
// 🔄 Activate event - Smart cache management
|
| 67 |
self.addEventListener('activate', (event) => {
|
|
|
|
|
|
|
| 68 |
console.log('🔄 [SW] Activating Premium Service Worker v' + VERSION);
|
| 69 |
|
| 70 |
const currentCaches = [
|
|
|
|
| 1 |
// 🌟 PREMIUM PWA SERVICE WORKER v3.10.0
|
| 2 |
+
// Service Worker - Enhanced Version v3.10.2
|
| 3 |
+
// Premium PWA with 100% offline capability + Auto-update
|
| 4 |
+
|
| 5 |
+
const VERSION = '3.10.2';
|
| 6 |
const CACHE_NAME = `fitness-app-${VERSION}`;
|
| 7 |
const STATIC_CACHE = `static-${VERSION}`;
|
| 8 |
const DYNAMIC_CACHE = `dynamic-${VERSION}`;
|
|
|
|
| 41 |
|
| 42 |
// 🚀 Install event - Premium caching strategy
|
| 43 |
self.addEventListener('install', (event) => {
|
| 44 |
+
console.log('🚀 [SW] Installing v3.10.2...');
|
| 45 |
+
|
| 46 |
+
// 💥 AUTO-UPDATE: Skip waiting to activate immediately
|
| 47 |
+
self.skipWaiting();
|
| 48 |
+
|
| 49 |
console.log('🌟 [SW] Installing Premium Service Worker v' + VERSION);
|
| 50 |
|
| 51 |
event.waitUntil(
|
|
|
|
| 63 |
caches.open(FONT_CACHE)
|
| 64 |
]).then(() => {
|
| 65 |
console.log('✅ [SW] Installation complete!');
|
| 66 |
+
return self.clients.claim();
|
| 67 |
}).catch(err => {
|
| 68 |
console.error('❌ [SW] Installation failed:', err);
|
| 69 |
})
|
|
|
|
| 72 |
|
| 73 |
// 🔄 Activate event - Smart cache management
|
| 74 |
self.addEventListener('activate', (event) => {
|
| 75 |
+
console.log('✅ [SW] Activating v3.10.2...');
|
| 76 |
+
|
| 77 |
console.log('🔄 [SW] Activating Premium Service Worker v' + VERSION);
|
| 78 |
|
| 79 |
const currentCaches = [
|
scripts/download-videos.js
CHANGED
|
@@ -29,6 +29,14 @@ const FILES_TO_DOWNLOAD = [
|
|
| 29 |
'flexao, extensão e hiperextenxao do tronco com baco estendido.mp4',
|
| 30 |
'prancha lateral com rotação.mp4',
|
| 31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
// Áudios
|
| 33 |
'background_yoga.mp3',
|
| 34 |
'start_yoga.mp3',
|
|
|
|
| 29 |
'flexao, extensão e hiperextenxao do tronco com baco estendido.mp4',
|
| 30 |
'prancha lateral com rotação.mp4',
|
| 31 |
|
| 32 |
+
// 🆕 Novos vídeos de mobilidade/alongamento
|
| 33 |
+
'Alcance cruzado por trás das costas (pegada alternada).mp4',
|
| 34 |
+
'Alongamento de Peitoral com Mãos Entrelaçadas Atrás do Corpo.mp4',
|
| 35 |
+
'Circundução órbita com a garrafa ao redor da nuca com reverso.mp4',
|
| 36 |
+
'MobilidadeAlongamento de Ombro com Apoio (Garrafa ou Outro Objeto.mp4',
|
| 37 |
+
'Scapular winging exercise ou Elbow fly stretch.mp4',
|
| 38 |
+
'Overhead triceps stretch.mp4',
|
| 39 |
+
|
| 40 |
// Áudios
|
| 41 |
'background_yoga.mp3',
|
| 42 |
'start_yoga.mp3',
|