diff --git a/MindShift-Windows/MindShift-v1.0.7.apk b/MindShift-Windows/MindShift-v1.0.7.apk new file mode 100644 index 0000000..3197e79 Binary files /dev/null and b/MindShift-Windows/MindShift-v1.0.7.apk differ diff --git a/MindShift-Windows/package.json b/MindShift-Windows/package.json index 04f0e7b..d8577d0 100644 --- a/MindShift-Windows/package.json +++ b/MindShift-Windows/package.json @@ -1,6 +1,6 @@ { "name": "mindshift-cbt-therapy", - "version": "1.0.6", + "version": "1.0.7", "description": "MindShift - Your personal CBT therapy companion for Windows 11", "main": "src/main.js", "homepage": "./", diff --git a/MindShift-Windows/src/app.js b/MindShift-Windows/src/app.js index 2c1a94d..e3da632 100644 --- a/MindShift-Windows/src/app.js +++ b/MindShift-Windows/src/app.js @@ -114,8 +114,56 @@ class SoundManager { osc.start(); osc.stop(this.ctx.currentTime + 4); } + + // Ambient Generator (Pink Noise) + startAmbience(type = 'rain') { + this.stopAmbience(); + if (!this.enabled) return; + + const bufferSize = 2 * this.ctx.sampleRate; + const noiseBuffer = this.ctx.createBuffer(1, bufferSize, this.ctx.sampleRate); + const output = noiseBuffer.getChannelData(0); + + for (let i = 0; i < bufferSize; i++) { + let white = Math.random() * 2 - 1; + output[i] = (lastOut + (0.02 * white)) / 1.02; + lastOut = output[i]; + output[i] *= 3.5; // (roughly) compensate for gain + } + + this.ambienceNode = this.ctx.createBufferSource(); + this.ambienceNode.buffer = noiseBuffer; + this.ambienceNode.loop = true; + + const gainNode = this.ctx.createGain(); + // Lower volume for background + gainNode.gain.value = 0.05; + + // Simple Lowpass filter for "rain/forest" feel + const filter = this.ctx.createBiquadFilter(); + filter.type = 'lowpass'; + filter.frequency.value = type === 'rain' ? 800 : 400; + + this.ambienceNode.connect(filter); + filter.connect(gainNode); + gainNode.connect(this.ctx.destination); + + this.ambienceNode.start(); + } + + stopAmbience() { + if (this.ambienceNode) { + try { + this.ambienceNode.stop(); + } catch(e) {} + this.ambienceNode = null; + } + } } +let lastOut = 0; + + const soundManager = new SoundManager(); // Initialize app when DOM is loaded @@ -1224,13 +1272,15 @@ function quickRelax() { // --- Guided Relaxation (Mindfulness System) --- let relaxationState = { - mode: null, // 'grounding', 'body_scan', 'visualization' + mode: null, step: 0, isActive: false, isPaused: false, steps: [], timer: null, - duration: 0 + duration: 0, + preStress: 5, // 1-10 + postStress: 5 }; // Data Providers @@ -1246,40 +1296,47 @@ function getGroundingSteps() { function getBodyScanSteps() { return [ - { instruction: t('scan_intro'), duration: 5000 }, - { instruction: t('scan_feet'), duration: 8000 }, - { instruction: t('scan_legs'), duration: 8000 }, - { instruction: t('scan_stomach'), duration: 8000 }, - { instruction: t('scan_chest'), duration: 8000 }, - { instruction: t('scan_shoulders'), duration: 8000 }, - { instruction: t('scan_face'), duration: 8000 }, - { instruction: t('scan_outro'), duration: 6000 } + { instruction: t('scan_intro'), duration: 8000 }, + { instruction: t('scan_feet'), duration: 10000 }, + { instruction: t('scan_legs'), duration: 10000 }, + { instruction: t('scan_stomach'), duration: 10000 }, + { instruction: t('scan_chest'), duration: 10000 }, + { instruction: t('scan_shoulders'), duration: 10000 }, + { instruction: t('scan_face'), duration: 10000 }, + { instruction: t('scan_outro'), duration: 8000 } ]; } function getVisualizationSteps() { return [ - { instruction: t('vis_intro'), duration: 6000 }, - { instruction: t('vis_step1'), duration: 10000 }, - { instruction: t('vis_step2'), duration: 10000 }, - { instruction: t('vis_step3'), duration: 10000 }, - { instruction: t('vis_step4'), duration: 10000 }, - { instruction: t('vis_outro'), duration: 8000 } + { instruction: t('vis_intro'), duration: 8000 }, + { instruction: t('vis_step1'), duration: 12000 }, + { instruction: t('vis_step2'), duration: 12000 }, + { instruction: t('vis_step3'), duration: 12000 }, + { instruction: t('vis_step4'), duration: 12000 }, + { instruction: t('vis_outro'), duration: 10000 } ]; } // Entry Point function startGuidedRelaxation() { - relaxationState = { mode: null, step: 0, isActive: true, isPaused: false, steps: [], timer: null, duration: 0 }; + relaxationState = { + mode: null, + step: 0, + isActive: true, + isPaused: false, + steps: [], + timer: null, + duration: 0, + preStress: 5, + postStress: 5 + }; const overlay = document.createElement('div'); overlay.id = 'guided-relaxation-overlay'; overlay.className = 'guided-overlay'; document.body.appendChild(overlay); - // Add styles dynamically if not present (using the styles we wrote to guided-styles.css but injecting here for simplicity in single file context if needed, but best to rely on CSS file) - // Assuming guided-styles.css is linked or merged. For safety, we rely on the styles.css update. - renderModeSelection(); } @@ -1297,15 +1354,15 @@ function renderModeSelection() {

${t('guided_select_mode')}

-
+
🌿 ${t('mode_grounding')}
-
+
🧘 ${t('mode_body_scan')}
-
+
🌄 ${t('mode_visualization')}
@@ -1313,14 +1370,39 @@ function renderModeSelection() { `; } -function startSession(mode) { +function startPreSession(mode) { relaxationState.mode = mode; - relaxationState.step = 0; - relaxationState.isActive = true; + const overlay = document.getElementById('guided-relaxation-overlay'); + overlay.innerHTML = ` +
+ +
+ +
${t('guided_pre_stress')}
+ +
+ +
5
+
+ + + `; +} + +function startSession(mode) { + relaxationState.isActive = true; const overlay = document.getElementById('guided-relaxation-overlay'); if (overlay) overlay.className = `guided-overlay mode-${mode}`; + // Start Ambience + soundManager.startAmbience(mode === 'visualization' ? 'rain' : 'forest'); + if (mode === 'grounding') { relaxationState.steps = getGroundingSteps(); renderGroundingStep(); @@ -1384,7 +1466,7 @@ function nextGroundingSubStep() { if (relaxationState.step < relaxationState.steps.length) { renderGroundingStep(); } else { - finishSession(); + startPostSession(); } }, 1000); } @@ -1422,10 +1504,6 @@ function runAutoSession() {
- -
- -
`; // Speak and advance @@ -1438,7 +1516,7 @@ function runAutoSession() { if (relaxationState.step < relaxationState.steps.length) { runAutoSession(); } else { - finishSession(); + startPostSession(); } }, 2000); // Short pause after speech }); @@ -1450,18 +1528,52 @@ function runAutoSession() { }, 100); } +function startPostSession() { + const overlay = document.getElementById('guided-relaxation-overlay'); + if (!overlay) return; + + soundManager.stopAmbience(); // Quiet down + + overlay.innerHTML = ` +
+ +
+ +
${t('guided_post_stress')}
+ +
+ +
${relaxationState.preStress}
+
+ + + `; +} + function finishSession() { const overlay = document.getElementById('guided-relaxation-overlay'); if (overlay) { + const reduction = relaxationState.preStress - relaxationState.postStress; + let summaryText = reduction > 0 + ? `${t('guided_summary_reduced')} ${reduction} points` + : t('guided_summary_maintained'); + overlay.innerHTML = ` -
🌟
-
${t('guided_complete_title')}
-
${t('guided_complete_sub')}
- +
+
🌟
+
${t('guided_summary_title')}
+
${summaryText}
+ +
`; - speakText(`${t('guided_complete_title')} ${t('guided_complete_sub')}`); + speakText(`${t('guided_complete_title')}`); triggerSuccessPing(); // Log stats @@ -1473,6 +1585,7 @@ function finishSession() { function closeGuidedRelaxation() { relaxationState.isActive = false; + soundManager.stopAmbience(); if (relaxationState.timer) clearTimeout(relaxationState.timer); currentDotIndex = 0; const overlay = document.getElementById('guided-relaxation-overlay'); @@ -1483,6 +1596,7 @@ function closeGuidedRelaxation() { } } + // Enhanced TTS Wrapper function speakText(text, onEndCallback) { if ('speechSynthesis' in window) { diff --git a/MindShift-Windows/src/guided-styles.css b/MindShift-Windows/src/guided-styles.css index b660078..a403c46 100644 --- a/MindShift-Windows/src/guided-styles.css +++ b/MindShift-Windows/src/guided-styles.css @@ -181,3 +181,77 @@ html[dir="rtl"] .guided-controls { right: auto; left: 20px; } + +/* Stress Slider */ +.stress-slider-container { + width: 100%; + max-width: 400px; + margin: 40px 0; +} + +.stress-slider { + width: 100%; + height: 10px; + background: rgba(255,255,255,0.3); + border-radius: 5px; + outline: none; + -webkit-appearance: none; +} + +.stress-slider::-webkit-slider-thumb { + -webkit-appearance: none; + width: 30px; + height: 30px; + background: white; + border-radius: 50%; + cursor: pointer; + box-shadow: 0 2px 10px rgba(0,0,0,0.2); +} + +.stress-value { + font-size: 48px; + font-weight: bold; + margin-top: 20px; +} + +/* Settings Modal */ +.guided-settings-panel { + position: absolute; + bottom: 20px; + left: 20px; + background: rgba(0,0,0,0.6); + backdrop-filter: blur(10px); + padding: 20px; + border-radius: 20px; + display: none; + animation: slideInUp 0.3s ease; +} + +.guided-settings-panel.active { + display: block; +} + +.setting-row { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 10px; + color: white; +} + +/* Summary Card */ +.summary-card { + background: white; + color: var(--on-surface); + padding: 40px; + border-radius: 24px; + text-align: center; + animation: zoomIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); +} + +.summary-stat { + font-size: 24px; + color: var(--primary); + margin: 20px 0; + font-weight: bold; +} diff --git a/MindShift-Windows/src/translations.js b/MindShift-Windows/src/translations.js index 37c692d..6f73e18 100644 --- a/MindShift-Windows/src/translations.js +++ b/MindShift-Windows/src/translations.js @@ -101,6 +101,16 @@ export const translations = { "mode_body_scan": "Body Scan", "mode_visualization": "Visualization", + "guided_pre_stress": "How stressed are you now?", + "guided_post_stress": "How do you feel now?", + "guided_start": "Start Session", + "guided_settings": "Settings", + "guided_ambience": "Background Sounds", + "guided_voice": "Voice Guide", + "guided_summary_title": "Session Complete", + "guided_summary_reduced": "Stress Reduced by", + "guided_summary_maintained": "You maintained your calm.", + // Grounding "guided_sight_title": "Sight", "guided_sight_instruction": "Look around you.", @@ -123,22 +133,22 @@ export const translations = { "guided_complete_btn": "Complete", // Body Scan Script - "scan_intro": "Find a comfortable position and close your eyes.", - "scan_feet": "Focus on your feet. Feel the weight of them.", - "scan_legs": "Move your attention to your legs. Let them relax.", - "scan_stomach": "Notice your stomach. Breathe deeply into it.", - "scan_chest": "Feel your chest rise and fall with each breath.", - "scan_shoulders": "Release any tension in your shoulders.", - "scan_face": "Soften your jaw and forehead.", - "scan_outro": "Take a deep breath. When you're ready, open your eyes.", + "scan_intro": "Find a comfortable position and close your eyes. Let's begin by taking a few deep breaths.", + "scan_feet": "Bring your awareness to your feet. Notice any sensations of warmth, coolness, or pressure. Let them soften.", + "scan_legs": "Move your attention up to your calves and thighs. If you notice any tension, imagine it melting away with your exhale.", + "scan_stomach": "Focus on your belly. Feel it rise gently as you inhale, and fall as you exhale. Soften your stomach muscles.", + "scan_chest": "Bring your attention to your chest and heart center. Notice the rhythm of your breath. Let your shoulders drop down away from your ears.", + "scan_shoulders": "Notice your neck and throat. Let go of any tightness here. Allow your jaw to unhinge slightly.", + "scan_face": "Soften the muscles around your eyes and forehead. Let your entire face be smooth and relaxed.", + "scan_outro": "Take a moment to feel your whole body, resting in this state of relaxation. When you are ready, gently wiggle your fingers and toes, and open your eyes.", // Visualization Script - "vis_intro": "Close your eyes and imagine a peaceful place.", - "vis_step1": "You are walking in a quiet, ancient forest.", - "vis_step2": "The air is fresh and smells of pine.", - "vis_step3": "Sunlight filters through the leaves above.", - "vis_step4": "You hear a gentle stream nearby.", - "vis_outro": "Carry this peace with you. Open your eyes.", + "vis_intro": "Close your eyes and take a deep breath. We are going to take a journey to a peaceful place.", + "vis_step1": "Imagine you are standing at the edge of a lush, ancient forest. The trees are tall and protective. You feel safe here.", + "vis_step2": "As you walk deeper into the woods, the air becomes cool and fresh. You can smell the scent of pine and damp earth.", + "vis_step3": "Sunlight filters through the canopy above, creating dappled patterns of light on the soft mossy path beneath your feet.", + "vis_step4": "In the distance, you hear the gentle sound of a stream flowing over smooth stones. The sound is rhythmic and calming.", + "vis_outro": "Take a moment to absorb the peace of this place. Know that you can return here anytime. Slowly bring your awareness back to the room and open your eyes.", // Smart Breathing "breath_balance": "Balance", @@ -259,6 +269,16 @@ export const translations = { "mode_body_scan": "Сканирование тела", "mode_visualization": "Визуализация", + "guided_pre_stress": "Ваш уровень стресса?", + "guided_post_stress": "Как вы себя чувствуете?", + "guided_start": "Начать сессию", + "guided_settings": "Настройки", + "guided_ambience": "Фоновые звуки", + "guided_voice": "Голос гида", + "guided_summary_title": "Сессия завершена", + "guided_summary_reduced": "Стресс снижен на", + "guided_summary_maintained": "Вы сохранили спокойствие.", + "guided_sight_title": "Зрение", "guided_sight_instruction": "Оглянитесь вокруг.", "guided_sight_sub": "Найдите 5 вещей, которые вы видите.", @@ -280,22 +300,22 @@ export const translations = { "guided_complete_btn": "Завершить", // Body Scan Script - "scan_intro": "Примите удобное положение и закройте глаза.", - "scan_feet": "Сосредоточьтесь на ногах. Почувствуйте их вес.", - "scan_legs": "Переведите внимание на ноги. Расслабьте их.", - "scan_stomach": "Заметьте свой живот. Дышите глубоко.", - "scan_chest": "Почувствуйте, как поднимается грудь при вдохе.", - "scan_shoulders": "Отпустите напряжение в плечах.", - "scan_face": "Расслабьте челюсть и лоб.", - "scan_outro": "Сделайте глубокий вдох. Откройте глаза.", + "scan_intro": "Примите удобное положение и закройте глаза. Давайте начнем с нескольких глубоких вдохов.", + "scan_feet": "Сосредоточьтесь на ногах. Почувствуйте их вес, тепло или холод. Позвольте им расслабиться.", + "scan_legs": "Переведите внимание на голени и бедра. Если есть напряжение, представьте, как оно уходит с выдохом.", + "scan_stomach": "Заметьте свой живот. Почувствуйте, как он мягко поднимается при вдохе и опускается при выдохе.", + "scan_chest": "Перенесите внимание на грудь и сердце. Заметьте ритм дыхания. Опустите плечи.", + "scan_shoulders": "Заметьте шею и горло. Отпустите любое напряжение. Слегка разомкните челюсти.", + "scan_face": "Расслабьте мышцы вокруг глаз и лба. Пусть все лицо станет гладким и спокойным.", + "scan_outro": "Почувствуйте все свое тело в состоянии покоя. Когда будете готовы, пошевелите пальцами и откройте глаза.", // Visualization Script - "vis_intro": "Закройте глаза и представьте спокойное место.", - "vis_step1": "Вы идете по тихому древнему лесу.", - "vis_step2": "Воздух свежий и пахнет хвоей.", - "vis_step3": "Солнечный свет пробивается сквозь листву.", - "vis_step4": "Вы слышите тихий ручей неподалеку.", - "vis_outro": "Сохраните это спокойствие. Откройте глаза.", + "vis_intro": "Закройте глаза и сделайте глубокий вдох. Мы отправимся в путешествие в спокойное место.", + "vis_step1": "Представьте, что вы стоите на краю тихого древнего леса. Деревья высокие и защищают вас. Здесь безопасно.", + "vis_step2": "Вы идете вглубь леса, воздух становится прохладным и свежим. Вы чувствуете запах хвои и влажной земли.", + "vis_step3": "Солнечный свет пробивается сквозь листву, создавая узоры света на мягкой моховой тропинке под ногами.", + "vis_step4": "Вдали вы слышите тихое журчание ручья, текущего по гладким камням. Этот звук ритмичный и успокаивающий.", + "vis_outro": "Впитайте покой этого места. Знайте, что можете вернуться сюда в любой момент. Медленно откройте глаза.", // Smart Breathing "breath_balance": "Баланс", @@ -416,6 +436,16 @@ export const translations = { "mode_body_scan": "סריקת גוף", "mode_visualization": "דמיון מודרך", + "guided_pre_stress": "כמה אתם לחוצים?", + "guided_post_stress": "איך אתם מרגישים כעת?", + "guided_start": "התחל אימון", + "guided_settings": "הגדרות", + "guided_ambience": "צלילי רקע", + "guided_voice": "קול מנחה", + "guided_summary_title": "האימון הושלם", + "guided_summary_reduced": "הלחץ ירד ב-", + "guided_summary_maintained": "שמרתם על רוגע.", + "guided_sight_title": "ראייה", "guided_sight_instruction": "הביטו סביבכם.", "guided_sight_sub": "מצאו 5 דברים שאתם רואים.", @@ -437,22 +467,22 @@ export const translations = { "guided_complete_btn": "סיים", // Body Scan Script - "scan_intro": "מצאו תנוחה נוחה ועצמו עיניים.", - "scan_feet": "התמקדו בכפות הרגליים. הרגישו את המשקל שלהן.", - "scan_legs": "העבירו את תשומת הלב לרגליים. הרפו אותן.", - "scan_stomach": "שימו לב לבטן. נשמו עמוק לתוכה.", - "scan_chest": "הרגישו את החזה עולה ויורד עם כל נשימה.", - "scan_shoulders": "שחררו כל מתח בכתפיים.", - "scan_face": "הרפו את הלסת והמצח.", - "scan_outro": "קחו נשימה עמוקה. כשאתם מוכנים, פקחו עיניים.", + "scan_intro": "מצאו תנוחה נוחה ועצמו עיניים. נתחיל בכמה נשימות עמוקות.", + "scan_feet": "התמקדו בכפות הרגליים. הרגישו את המשקל שלהן, חום או קור. תנו להן להתרכך.", + "scan_legs": "העבירו את תשומת הלב לשוקיים ולירכיים. אם יש מתח, דמיינו אותו נמס עם הנשיפה.", + "scan_stomach": "שימו לב לבטן. הרגישו אותה עולה בעדינות בשאיפה ויורדת בנשיפה. הרפו את שרירי הבטן.", + "scan_chest": "העבירו את תשומת הלב לחזה וללב. שימו לב לקצב הנשימה. שחררו את הכתפיים מטה.", + "scan_shoulders": "שימו לב לצוואר ולגרון. שחררו כל מתח. אפשרו ללסת להשתחרר מעט.", + "scan_face": "הרפו את השרירים סביב העיניים והמצח. תנו לכל הפנים להיות חלקים ורגועים.", + "scan_outro": "קחו רגע להרגיש את כל הגוף במצב של רוגע. כשאתם מוכנים, הניעו בעדינות את האצבעות ופקחו עיניים.", // Visualization Script - "vis_intro": "עצמו עיניים ודמיינו מקום שליו.", - "vis_step1": "אתם הולכים ביער עתיק ושקט.", - "vis_step2": "האוויר רענן ומריח כמו אורנים.", - "vis_step3": "אור השמש מסתנן מבעד לעלים.", - "vis_step4": "אתם שומעים פלג מים עדין בקרבת מקום.", - "vis_outro": "שאו את השלווה הזו איתכם. פקחו עיניים.", + "vis_intro": "עצמו עיניים וקחו נשימה עמוקה. אנו יוצאים למסע למקום שליו.", + "vis_step1": "דמיינו שאתם עומדים בקצה של יער עתיק ושקט. העצים גבוהים ומגנים. אתם מרגישים בטוחים כאן.", + "vis_step2": "כשאתם הולכים עמוק יותר לתוך היער, האוויר נעשה קריר ורענן. אתם יכולים להריח ריח של אורנים ואדמה לחה.", + "vis_step3": "אור השמש מסתנן מבעד לחופה מעל, יוצר תבניות של אור על שביל הטחב הרך שמתחת לרגליכם.", + "vis_step4": "במרחק, אתם שומעים צליל עדין של פלג מים הזורם על אבנים חלקות. הצליל קצבי ומרגיע.", + "vis_outro": "ספגו את השלווה של המקום הזה. דעו שאתם יכולים לחזור לכאן בכל עת. החזירו את המודעות לחדר ופקחו עיניים.", // Smart Breathing "breath_balance": "איזון",