Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion core/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,38 @@
import openai
from gtts import gTTS
from io import BytesIO
from pydub import AudioSegment

# Workaround for Python 3.13+ where audioop was removed
try:
import audioop
except ImportError:
# Python 3.13+ - audioop was removed from standard library
# Try to create a dummy module to prevent pydub from failing
import sys
class DummyAudioop:
"""Dummy audioop module for Python 3.13+ compatibility"""
@staticmethod
def add(*args, **kwargs):
return b''
@staticmethod
def mul(*args, **kwargs):
return b''
@staticmethod
def tomono(*args, **kwargs):
return b''
@staticmethod
def tostereo(*args, **kwargs):
return b''
@staticmethod
def ratecv(*args, **kwargs):
return (b'', None)
sys.modules['audioop'] = DummyAudioop()

try:
from pydub import AudioSegment
except ImportError as e:
st.warning(f"⚠️ pydub import warning: {e}. Some audio features may be limited.")
AudioSegment = None

# Ensure OpenAI API key is available
openai.api_key = os.getenv("OPENAI_API_KEY")
Expand Down
86 changes: 85 additions & 1 deletion css/styles.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import streamlit as st
import streamlit.components.v1 as components
import base64

def get_base64_of_bin_file(bin_file):
Expand Down Expand Up @@ -1176,5 +1177,88 @@ def apply_custom_css():
outline: 2px solid var(--primary-color) !important;
outline-offset: 2px !important;
}}

/* Cursor Trail Styles */
.cursor-trail {{
position: fixed;
width: 8px;
height: 8px;
border-radius: 50%;
pointer-events: none;
z-index: 9999;
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
box-shadow: 0 0 10px rgba(99, 102, 241, 0.6), 0 0 20px rgba(236, 72, 153, 0.4);
opacity: 0.8;
transition: opacity 0.3s ease-out, transform 0.3s ease-out;
}}

.cursor-trail.fade-out {{
opacity: 0;
transform: scale(0.5);
}}
</style>
""", unsafe_allow_html=True)
""", unsafe_allow_html=True)

# Add cursor trail with hearts and sparkles using components.html()
components.html(r"""
<script>
(function() {
var targetWindow = window.parent !== window ? window.parent : window;
var targetDoc = targetWindow.document;

if (targetWindow.__cursorTrailInit) return;
targetWindow.__cursorTrailInit = true;

var trail = [];
var mx = 0, my = 0;
var len = 20;

// Only hearts and sparkles
function createTrail() {
if (!targetDoc.body) {
setTimeout(createTrail, 100);
return;
}

targetDoc.querySelectorAll('.ct-heart, .ct-sparkle').forEach(function(el) { el.remove(); });
trail = [];

for (var i = 0; i < len; i++) {
var d = targetDoc.createElement('div');
var isHeart = i % 2 === 0;
var symbol = isHeart ? 'πŸ’•' : '✨';
var color = isHeart ? '#ff69b4' : '#ffd700';
d.className = isHeart ? 'ct-heart' : 'ct-sparkle';
d.textContent = symbol;
d.style.cssText = 'position:fixed;pointer-events:none;z-index:999999;font-size:' + (12 + i * 0.5) + 'px;color:' + color + ';text-shadow:0 0 8px ' + color + ',0 0 16px ' + color + ';opacity:' + ((len-i)/len * 0.8) + ';left:0;top:0;transform:translate(-50%,-50%) rotate(' + (i * 18) + 'deg);transition:opacity 0.2s;';
targetDoc.body.appendChild(d);
trail.push({el:d, x:targetWindow.innerWidth/2, y:targetWindow.innerHeight/2, rot:i*18});
}

targetWindow.addEventListener('mousemove', function(e) {
mx = e.clientX;
my = e.clientY;
});

function animate() {
for (var i = 0; i < trail.length; i++) {
var next = trail[i+1] || {x:mx, y:my};
trail[i].x += (next.x - trail[i].x) * 0.3;
trail[i].y += (next.y - trail[i].y) * 0.3;
trail[i].rot += 2;
trail[i].el.style.left = trail[i].x + 'px';
trail[i].el.style.top = trail[i].y + 'px';
trail[i].el.style.transform = 'translate(-50%,-50%) rotate(' + trail[i].rot + 'deg) scale(' + (0.6 + i/len * 0.4) + ')';
}
targetWindow.requestAnimationFrame(animate);
}
animate();
}

if (targetDoc.readyState === "complete") createTrail();
else targetWindow.addEventListener("load", createTrail);

setTimeout(createTrail, 500);
})();
</script>
""", height=0, width=0)
75 changes: 75 additions & 0 deletions pages/About.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,81 @@ def set_page_theme_and_style():

set_page_theme_and_style()

# Add cursor trail effect with hearts only
import streamlit.components.v1 as components
components.html(r"""
<script>
(function() {
var targetWindow = window.parent !== window ? window.parent : window;
var targetDoc = targetWindow.document;

if (targetWindow.__cursorTrailInit) return;
targetWindow.__cursorTrailInit = true;

var trail = [];
var mx = 0, my = 0;
var len = 12;
var animationId = null;
var lastTime = 0;
var fps = 60;
var frameInterval = 1000 / fps;

function createTrail() {
if (!targetDoc.body) {
setTimeout(createTrail, 100);
return;
}

targetDoc.querySelectorAll('.ct-heart').forEach(function(el) { el.remove(); });
trail = [];

for (var i = 0; i < len; i++) {
var d = targetDoc.createElement('div');
var symbol = 'πŸ’•';
var color = '#ff69b4';
d.className = 'ct-heart';
d.textContent = symbol;
d.style.cssText = 'position:fixed;pointer-events:none;z-index:999999;font-size:' + (12 + i * 0.5) + 'px;color:' + color + ';text-shadow:0 0 8px ' + color + ',0 0 16px ' + color + ';opacity:' + ((len-i)/len * 0.8) + ';left:0;top:0;transform:translate(-50%,-50%) rotate(' + (i * 18) + 'deg);transition:opacity 0.2s;';
targetDoc.body.appendChild(d);
trail.push({el:d, x:targetWindow.innerWidth/2, y:targetWindow.innerHeight/2, rot:i*18});
}

targetWindow.addEventListener('mousemove', function(e) {
mx = e.clientX;
my = e.clientY;
});

function animate(currentTime) {
if (currentTime - lastTime < frameInterval) {
animationId = requestAnimationFrame(animate);
return;
}
lastTime = currentTime;

for (var i = 0; i < trail.length; i++) {
var next = trail[i+1] || {x:mx, y:my};
trail[i].x += (next.x - trail[i].x) * 0.25;
trail[i].y += (next.y - trail[i].y) * 0.25;
trail[i].rot += 1.5;

var transform = 'translate(-50%,-50%) rotate(' + trail[i].rot + 'deg) scale(' + (0.6 + i/len * 0.4) + ')';
trail[i].el.style.left = trail[i].x + 'px';
trail[i].el.style.top = trail[i].y + 'px';
trail[i].el.style.transform = transform;
}
animationId = requestAnimationFrame(animate);
}
animate();
}

if (targetDoc.readyState === "complete") createTrail();
else targetWindow.addEventListener("load", createTrail);

setTimeout(createTrail, 500);
})();
</script>
""", height=0, width=0)

# --- Header Section ---
intro_col, lottie_col = st.columns([2, 1.5])
with intro_col:
Expand Down
74 changes: 74 additions & 0 deletions pages/AppOverview.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,80 @@ def set_page_theme_and_style():

set_page_theme_and_style()

import streamlit.components.v1 as components
components.html(r"""
<script>
(function() {
var targetWindow = window.parent !== window ? window.parent : window;
var targetDoc = targetWindow.document;

if (targetWindow.__cursorTrailInit) return;
targetWindow.__cursorTrailInit = true;

var trail = [];
var mx = 0, my = 0;
var len = 12;
var animationId = null;
var lastTime = 0;
var fps = 60;
var frameInterval = 1000 / fps;

function createTrail() {
if (!targetDoc.body) {
setTimeout(createTrail, 100);
return;
}

targetDoc.querySelectorAll('.ct-heart').forEach(function(el) { el.remove(); });
trail = [];

for (var i = 0; i < len; i++) {
var d = targetDoc.createElement('div');
var symbol = 'πŸ’•';
var color = '#ff69b4';
d.className = 'ct-heart';
d.textContent = symbol;
d.style.cssText = 'position:fixed;pointer-events:none;z-index:999999;font-size:' + (12 + i * 0.5) + 'px;color:' + color + ';text-shadow:0 0 8px ' + color + ',0 0 16px ' + color + ';opacity:' + ((len-i)/len * 0.8) + ';left:0;top:0;transform:translate(-50%,-50%) rotate(' + (i * 18) + 'deg);transition:opacity 0.2s;';
targetDoc.body.appendChild(d);
trail.push({el:d, x:targetWindow.innerWidth/2, y:targetWindow.innerHeight/2, rot:i*18});
}

targetWindow.addEventListener('mousemove', function(e) {
mx = e.clientX;
my = e.clientY;
});

function animate(currentTime) {
if (currentTime - lastTime < frameInterval) {
animationId = requestAnimationFrame(animate);
return;
}
lastTime = currentTime;

for (var i = 0; i < trail.length; i++) {
var next = trail[i+1] || {x:mx, y:my};
trail[i].x += (next.x - trail[i].x) * 0.25;
trail[i].y += (next.y - trail[i].y) * 0.25;
trail[i].rot += 1.5;

var transform = 'translate(-50%,-50%) rotate(' + trail[i].rot + 'deg) scale(' + (0.6 + i/len * 0.4) + ')';
trail[i].el.style.left = trail[i].x + 'px';
trail[i].el.style.top = trail[i].y + 'px';
trail[i].el.style.transform = transform;
}
animationId = requestAnimationFrame(animate);
}
animate();
}

if (targetDoc.readyState === "complete") createTrail();
else targetWindow.addEventListener("load", createTrail);

setTimeout(createTrail, 500);
})();
</script>
""", height=0, width=0)

# --- Header Section ---
st.title("Welcome to TalkHeal")

Expand Down
79 changes: 78 additions & 1 deletion pages/Blog.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import streamlit as st
import streamlit.components.v1 as components
import base64
from datetime import datetime
import json
Expand Down Expand Up @@ -91,10 +92,86 @@ def set_background_for_theme(selected_palette="pink"):
unsafe_allow_html=True
)

# βœ… Set your background image
# Set your background image
selected_palette = st.session_state.get("palette_name", "Pink")
set_background_for_theme(selected_palette)

# Add cursor trail effect with hearts only
components.html(r"""
<script>
(function() {
var targetWindow = window.parent !== window ? window.parent : window;
var targetDoc = targetWindow.document;

if (targetWindow.__cursorTrailInit) return;
targetWindow.__cursorTrailInit = true;

var trail = [];
var mx = 0, my = 0;
var len = 12; // Reduced from 20 to 12 for better performance
var animationId = null;
var lastTime = 0;
var fps = 60; // Target 60 FPS
var frameInterval = 1000 / fps;

function createTrail() {
if (!targetDoc.body) {
setTimeout(createTrail, 100);
return;
}

targetDoc.querySelectorAll('.ct-heart').forEach(function(el) { el.remove(); });
trail = [];

for (var i = 0; i < len; i++) {
var d = targetDoc.createElement('div');
var symbol = 'πŸ’•';
var color = '#ff69b4';
d.className = 'ct-heart';
d.textContent = symbol;
d.style.cssText = 'position:fixed;pointer-events:none;z-index:999999;font-size:' + (12 + i * 0.5) + 'px;color:' + color + ';text-shadow:0 0 8px ' + color + ',0 0 16px ' + color + ';opacity:' + ((len-i)/len * 0.8) + ';left:0;top:0;transform:translate(-50%,-50%) rotate(' + (i * 18) + 'deg);transition:opacity 0.2s;';
targetDoc.body.appendChild(d);
trail.push({el:d, x:targetWindow.innerWidth/2, y:targetWindow.innerHeight/2, rot:i*18});
}

targetWindow.addEventListener('mousemove', function(e) {
mx = e.clientX;
my = e.clientY;
});

function animate(currentTime) {
// Frame limiting for smooth performance
if (currentTime - lastTime < frameInterval) {
animationId = requestAnimationFrame(animate);
return;
}
lastTime = currentTime;

for (var i = 0; i < trail.length; i++) {
var next = trail[i+1] || {x:mx, y:my};
trail[i].x += (next.x - trail[i].x) * 0.25; // Reduced from 0.3 for smoother motion
trail[i].y += (next.y - trail[i].y) * 0.25;
trail[i].rot += 1.5; // Reduced from 2 for smoother rotation

// Batch DOM updates for better performance
var transform = 'translate(-50%,-50%) rotate(' + trail[i].rot + 'deg) scale(' + (0.6 + i/len * 0.4) + ')';
trail[i].el.style.left = trail[i].x + 'px';
trail[i].el.style.top = trail[i].y + 'px';
trail[i].el.style.transform = transform;
}
animationId = requestAnimationFrame(animate);
}
animate();
}

if (targetDoc.readyState === "complete") createTrail();
else targetWindow.addEventListener("load", createTrail);

setTimeout(createTrail, 500);
})();
</script>
""", height=0, width=0)

# --- Blog Data ---
# In a real app, this might come from a database or a CMS.
# For now, we'll store it as a list of dictionaries.
Expand Down
Loading