diff --git a/.gitignore b/.gitignore index d99f03a..43fb98e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,11 @@ + +# Streamlit secrets and configuration +/.streamlit/ + +# pycache +__pycache__/ +*.pyc +======= # Byte-compiled / optimized / DLL files __pycache__/ *.py[codz] @@ -238,3 +246,6 @@ __pycache__/ # Python virtual environments venv/ env/ + +# JSON files +*.json \ No newline at end of file diff --git a/TalkHeal.py b/TalkHeal.py index 5246d83..ab1d210 100644 --- a/TalkHeal.py +++ b/TalkHeal.py @@ -8,56 +8,65 @@ from components.header import render_header from components.sidebar import render_sidebar from components.chat_interface import render_chat_interface, handle_chat_input +from components.emergency_page import render_emergency_page +# --- 1. INITIALIZE SESSION STATE --- if "chat_history" not in st.session_state: st.session_state.chat_history = [] if "conversations" not in st.session_state: st.session_state.conversations = load_conversations() if "active_conversation" not in st.session_state: st.session_state.active_conversation = -1 +if "show_emergency_page" not in st.session_state: + st.session_state.show_emergency_page = False +if "sidebar_state" not in st.session_state: + st.session_state.sidebar_state = "expanded" if "mental_disorders" not in st.session_state: st.session_state.mental_disorders = [ - "Depression & Mood Disorders", - "Anxiety & Panic Disorders", - "Bipolar Disorder", - "PTSD & Trauma", - "OCD & Related Disorders", - "Eating Disorders", - "Substance Use Disorders", - "ADHD & Neurodevelopmental", - "Personality Disorders", + "Depression & Mood Disorders", "Anxiety & Panic Disorders", "Bipolar Disorder", + "PTSD & Trauma", "OCD & Related Disorders", "Eating Disorders", + "Substance Use Disorders", "ADHD & Neurodevelopmental", "Personality Disorders", "Sleep Disorders" ] -if "sidebar_state" not in st.session_state: - st.session_state.sidebar_state = "expanded" +# --- 2. SET PAGE CONFIG --- st.set_page_config( page_title=PAGE_CONFIG["page_title"], page_icon=PAGE_CONFIG["page_icon"], layout=PAGE_CONFIG["layout"], - initial_sidebar_state=st.session_state.sidebar_state # Use session state here + initial_sidebar_state=st.session_state.sidebar_state ) +# --- 3. APPLY STYLES & CONFIGURATIONS --- apply_custom_css() - model = configure_gemini() render_sidebar() -render_header() - +# --- 5. PAGE ROUTING --- +main_area = st.container() +# handle loading conversations if not st.session_state.conversations: - saved_conversations=load_conversations() + saved_conversations = load_conversations() if saved_conversations: - st.session_state.conversations=saved_conversations - st.session_state.active_conversation = 0 + st.session_state.conversations = saved_conversations + if st.session_state.active_conversation == -1: + st.session_state.active_conversation = 0 else: create_new_conversation() st.session_state.active_conversation = 0 + st.rerun() -render_chat_interface() - -handle_chat_input(model) +# handle page routing +if st.session_state.get("show_emergency_page"): + with main_area: + render_emergency_page() +else: + # Render the standard chat interface + with main_area: + render_header() + render_chat_interface() + handle_chat_input(model) st.markdown(""" -""", unsafe_allow_html=True) \ No newline at end of file +""", unsafe_allow_html=True) diff --git a/components/__pycache__/__init__.cpython-312.pyc b/components/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index e1d4b03..0000000 Binary files a/components/__pycache__/__init__.cpython-312.pyc and /dev/null differ diff --git a/components/__pycache__/__init__.cpython-313.pyc b/components/__pycache__/__init__.cpython-313.pyc deleted file mode 100644 index 171d2dd..0000000 Binary files a/components/__pycache__/__init__.cpython-313.pyc and /dev/null differ diff --git a/components/__pycache__/chat_interface.cpython-312.pyc b/components/__pycache__/chat_interface.cpython-312.pyc deleted file mode 100644 index 653af4b..0000000 Binary files a/components/__pycache__/chat_interface.cpython-312.pyc and /dev/null differ diff --git a/components/__pycache__/chat_interface.cpython-313.pyc b/components/__pycache__/chat_interface.cpython-313.pyc deleted file mode 100644 index c6e50f5..0000000 Binary files a/components/__pycache__/chat_interface.cpython-313.pyc and /dev/null differ diff --git a/components/__pycache__/header.cpython-312.pyc b/components/__pycache__/header.cpython-312.pyc deleted file mode 100644 index 0cf4e4c..0000000 Binary files a/components/__pycache__/header.cpython-312.pyc and /dev/null differ diff --git a/components/__pycache__/header.cpython-313.pyc b/components/__pycache__/header.cpython-313.pyc deleted file mode 100644 index 333a96c..0000000 Binary files a/components/__pycache__/header.cpython-313.pyc and /dev/null differ diff --git a/components/__pycache__/sidebar.cpython-312.pyc b/components/__pycache__/sidebar.cpython-312.pyc deleted file mode 100644 index bd7a831..0000000 Binary files a/components/__pycache__/sidebar.cpython-312.pyc and /dev/null differ diff --git a/components/__pycache__/sidebar.cpython-313.pyc b/components/__pycache__/sidebar.cpython-313.pyc deleted file mode 100644 index 7b7f4d1..0000000 Binary files a/components/__pycache__/sidebar.cpython-313.pyc and /dev/null differ diff --git a/components/__pycache__/theme_toggle.cpython-313.pyc b/components/__pycache__/theme_toggle.cpython-313.pyc deleted file mode 100644 index aea237e..0000000 Binary files a/components/__pycache__/theme_toggle.cpython-313.pyc and /dev/null differ diff --git a/components/emergency_page.py b/components/emergency_page.py new file mode 100644 index 0000000..e02a5c1 --- /dev/null +++ b/components/emergency_page.py @@ -0,0 +1,78 @@ +import streamlit as st +from geopy.geocoders import Nominatim +import urllib.parse +from .sidebar import GLOBAL_RESOURCES + + +def render_emergency_page(): + """Displays emergency help page with a dynamic Google search link.""" + + if st.button("β Back to Chat", type="primary"): + st.session_state.show_emergency_page = False + # Clean up session state on exit + st.session_state.pop('location_info', None) + st.rerun() + + st.markdown(""" +
Your Mental Health Companion π
""", unsafe_allow_html=True) + ## Commented out this part of the header because the 'emergency button' functionality is quite similar, hence causing redundancy. ## - with st.expander("π Find Help Nearby"): - location_input = st.text_input("Enter your city", key="header_location_search") - if st.button("π Search Centers", key="header_search_nearby"): - if location_input: - search_url = f"https://www.google.com/maps/search/mental+health+centers+{location_input.replace(' ', '+')}" - st.markdown(f'πΊοΈ View Mental Health Centers Near {location_input}', unsafe_allow_html=True) - st.success("Opening search results in a new tab...") - else: - st.warning("Please enter a city name") \ No newline at end of file + # with st.expander("π Find Help Nearby"): + # location_input = st.text_input("Enter your city", key="header_location_search") + # if st.button("π Search Centers", key="header_search_nearby"): + # if location_input: + # search_url = f"https://www.google.com/maps/search/mental+health+centers+{location_input.replace(' ', '+')}" + # st.markdown(f'πΊοΈ View Mental Health Centers Near {location_input}', unsafe_allow_html=True) + # st.success("Opening search results in a new tab...") + # else: + # st.warning("Please enter a city name") diff --git a/components/sidebar.py b/components/sidebar.py index 9123bed..2cfa90f 100644 --- a/components/sidebar.py +++ b/components/sidebar.py @@ -3,40 +3,43 @@ from datetime import datetime from core.utils import create_new_conversation, get_current_time from core.theme import get_current_theme, toggle_theme, set_palette, PALETTES - -# Emergency contacts and resources -emergency_resources = { - "Crisis Hotlines": [ - "National Suicide Prevention Lifeline: 988", - "Crisis Text Line: Text HOME to 741741", - "SAMHSA National Helpline: 1-800-662-4357" - ], - "International": [ - "India: 9152987821 (AASRA)", - "UK: 116 123 (Samaritans)", - "Australia: 13 11 14 (Lifeline)" - ] -} +# --- Structured Emergency Resources --- +GLOBAL_RESOURCES = [ + {"name": "Befrienders Worldwide", "desc": "Emotional support to prevent suicide worldwide.", + "url": "https://www.befrienders.org/"}, + {"name": "International Association for Suicide Prevention (IASP)", "desc": "Find a crisis center anywhere in the world.", + "url": "https://www.iasp.info/resources/Crisis_Centres/"}, + {"name": "Crisis Text Line", "desc": "Text-based support available in the US, UK, Canada, and Ireland.", + "url": "https://www.crisistextline.org/"}, + {"name": "The Trevor Project", "desc": "Crisis intervention and suicide prevention for LGBTQ young people.", + "url": "https://www.thetrevorproject.org/"}, + {"name": "Child Helpline International", "desc": "A global network of child helplines for young people in need of help.", + "url": "https://www.childhelplineinternational.org/"} +] mental_health_resources_full = { "Depression & Mood Disorders": { "description": "Information on understanding and coping with depression, persistent depressive disorder, and other mood-related challenges.", "links": [ - {"label": "NIMH - Depression", "url": "https://www.nimh.nih.gov/health/topics/depression"}, - {"label": "Mayo Clinic - Depression", "url": "https://www.mayoclinic.org/diseases-conditions/depression/symptoms-causes/syc-20356007"} + {"label": "NIMH - Depression", + "url": "https://www.nimh.nih.gov/health/topics/depression"}, + {"label": "Mayo Clinic - Depression", + "url": "https://www.mayoclinic.org/diseases-conditions/depression/symptoms-causes/syc-20356007"} ] }, "Anxiety & Panic Disorders": { "description": "Guidance on managing generalized anxiety, social anxiety, panic attacks, and phobias.", "links": [ {"label": "ADAA - Anxiety & Depression", "url": "https://adaa.org/"}, - {"label": "NIMH - Anxiety Disorders", "url": "https://www.nimh.nih.gov/health/topics/anxiety-disorders"} + {"label": "NIMH - Anxiety Disorders", + "url": "https://www.nimh.nih.gov/health/topics/anxiety-disorders"} ] }, "Bipolar Disorder": { "description": "Understanding the complexities of bipolar disorder, including mood swings and treatment options.", "links": [ - {"label": "NIMH - Bipolar Disorder", "url": "https://www.nimh.nih.gov/health/topics/bipolar-disorder"} + {"label": "NIMH - Bipolar Disorder", + "url": "https://www.nimh.nih.gov/health/topics/bipolar-disorder"} ] }, "PTSD & Trauma": { @@ -54,13 +57,15 @@ "Coping Skills & Self-Care": { "description": "Practical strategies and techniques for stress management, emotional regulation, and daily well-being.", "links": [ - {"label": "HelpGuide - Stress Management", "url": "https://www.helpguide.org/articles/stress/stress-management.htm"} + {"label": "HelpGuide - Stress Management", + "url": "https://www.helpguide.org/articles/stress/stress-management.htm"} ] }, "Therapy & Treatment Options": { "description": "Overview of various therapeutic approaches, including CBT, DBT, and finding a therapist.", "links": [ - {"label": "APA - Finding a Therapist", "url": "https://www.apa.org/helpcenter/choose-therapist"} + {"label": "APA - Finding a Therapist", + "url": "https://www.apa.org/helpcenter/choose-therapist"} ] } } @@ -68,6 +73,7 @@ def render_sidebar(): """Renders the left and right sidebars.""" + with st.sidebar: st.markdown("### π¬ Conversations") if "show_quick_start_prompts" not in st.session_state: @@ -77,7 +83,7 @@ def render_sidebar(): if "send_chat_message" not in st.session_state: st.session_state.send_chat_message = False - if st.button("β New Chat", key="new_chat", use_container_width=True): + if st.button("β New Chat", key="new_chat", use_container_width=True, type="primary"): create_new_conversation() st.session_state.show_quick_start_prompts = True st.rerun() @@ -96,7 +102,7 @@ def render_sidebar(): if st.button(f"β¨ {prompt}", key=f"qp_{i}", use_container_width=True): st.session_state.pre_filled_chat_input = prompt st.session_state.send_chat_message = True - st.session_state.show_quick_start_prompts = False + st.session_state.show_quick_start_prompts = False st.rerun() st.markdown("---") @@ -118,12 +124,13 @@ def render_sidebar(): st.session_state.active_conversation = i st.rerun() with col2: - if st.button("ποΈ", key=f"delete_{i}"): + if st.button("ποΈ", key=f"delete_{i}", type="primary"): st.session_state.delete_candidate = i st.rerun() else: - st.warning("β οΈ Are you sure you want to delete this conversation?") + st.warning( + "β οΈ Are you sure you want to delete this conversation?") col_confirm, col_cancel = st.columns(2) if col_confirm.button("Yes, delete", key="confirm_delete"): @@ -131,7 +138,7 @@ def render_sidebar(): from core.utils import save_conversations save_conversations(st.session_state.conversations) - + del st.session_state.delete_candidate st.session_state.active_conversation = -1 st.rerun() @@ -151,17 +158,11 @@ def render_sidebar(): st.info("No conversations yet. Start a new chat!") st.markdown("---") - - st.markdown( - """ - - π¨ Emergency Help - - """, - unsafe_allow_html=True - ) - - st.markdown("") + + # --- DEDICATED EMERGENCY PAGE BUTTON --- + if st.button("π¨ Emergency Help", use_container_width=True, type="secondary"): + st.session_state.show_emergency_page = True + st.rerun() # --- 3. Dynamic Mood Tracker & Micro-Journal (Fixed Tip & New Button) --- with st.expander("π§ Mental Health Check"): @@ -179,7 +180,8 @@ def render_sidebar(): selected_mood_label = st.radio( "Mood Scale", options=mood_labels, - index=mood_labels.index("π Okay") if "π Okay" in mood_labels else 2, + index=mood_labels.index( + "π Okay") if "π Okay" in mood_labels else 2, key="mood_selector_radio", horizontal=True, label_visibility="collapsed" @@ -205,7 +207,6 @@ def render_sidebar(): if "mood_entry_status" not in st.session_state: st.session_state.mood_entry_status = "" - st.text_area( f"βοΈ {journal_prompt_text}", key="mood_journal_area", @@ -240,7 +241,8 @@ def render_sidebar(): st.session_state.mood_entry_status = "" st.rerun() else: - st.warning("Please enter your thoughts before asking TalkHeal.") + st.warning( + "Please enter your thoughts before asking TalkHeal.") if st.session_state.mood_tip_display: st.success(st.session_state.mood_tip_display) @@ -253,14 +255,16 @@ def render_sidebar(): with st.expander("π Resources & Knowledge Base"): st.markdown("**Explore topics or search for help:**") - resource_search_query = st.text_input("Search resources...", key="resource_search", placeholder="e.g., 'anxiety tips', 'therapy'", label_visibility="collapsed") + resource_search_query = st.text_input( + "Search resources...", key="resource_search", placeholder="e.g., 'anxiety tips', 'therapy'", label_visibility="collapsed") - if resource_search_query: + if resource_search_query: filtered_topics = [ topic for topic in mental_health_resources_full - if resource_search_query.lower() in topic.lower() or \ - any(resource_search_query.lower() in link['label'].lower() for link in mental_health_resources_full[topic]['links']) or \ - resource_search_query.lower() in mental_health_resources_full[topic]['description'].lower() + if resource_search_query.lower() in topic.lower() or + any(resource_search_query.lower() in link['label'].lower() for link in mental_health_resources_full[topic]['links']) or + resource_search_query.lower( + ) in mental_health_resources_full[topic]['description'].lower() ] if not filtered_topics: @@ -270,17 +274,19 @@ def render_sidebar(): st.markdown("**Matching Resources:**") for topic in filtered_topics: st.markdown(f"**{topic}**") - st.info(mental_health_resources_full[topic]['description']) + st.info( + mental_health_resources_full[topic]['description']) for link in mental_health_resources_full[topic]['links']: st.markdown(f"β’ [{link['label']}]({link['url']})") st.markdown("---") else: - resource_tabs = st.tabs(list(mental_health_resources_full.keys())) + resource_tabs = st.tabs( + list(mental_health_resources_full.keys())) for i, tab_title in enumerate(mental_health_resources_full.keys()): with resource_tabs[i]: topic_data = mental_health_resources_full[tab_title] - st.markdown(f"**{tab_title}") + st.markdown(f"**{tab_title}**") # fixed typo st.info(topic_data['description']) for link in topic_data['links']: st.markdown(f"β’ [{link['label']}]({link['url']})") @@ -288,28 +294,28 @@ def render_sidebar(): with st.expander("βοΈ Crisis Support"): st.markdown("**24/7 Crisis Hotlines:**") - for category, numbers in emergency_resources.items(): - st.markdown(f"**{category}:**") - for number in numbers: - st.markdown(f"β’ {number}") + for resource in GLOBAL_RESOURCES: + st.markdown( + f"**{resource['name']}**: {resource['desc']} [Visit Website]({resource['url']})") # Theme toggle in sidebar with st.expander("π¨ Theme Settings"): current_theme = get_current_theme() is_dark = current_theme["name"] == "Dark" - + # Palette selector (only for light mode) if not is_dark: palette_names = [p["name"] for p in PALETTES] selected_palette = st.selectbox( "Choose a soothing color palette:", palette_names, - index=palette_names.index(st.session_state.get("palette_name", "Light")), + index=palette_names.index( + st.session_state.get("palette_name", "Light")), key="palette_selector", ) if selected_palette != st.session_state.get("palette_name", "Light"): set_palette(selected_palette) - + # Current theme display with better styling st.markdown("""