Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ea80aba
chore: Add .gitignore to exclude secrets and cache
Baibhab-Adhikari Jul 22, 2025
d8cbd22
feat: Implement emergency resources page for the emergency button fu…
Baibhab-Adhikari Jul 22, 2025
9dce751
feat: Enhance emergency page with dynamic local resource search and i…
Baibhab-Adhikari Jul 22, 2025
95928ba
Merge branch 'main' into feat/emergency-help-button-5
Baibhab-Adhikari Jul 22, 2025
5618da2
fix: Correct markdown formatting for resource tab titles in sidebar
Baibhab-Adhikari Jul 22, 2025
0c7d815
Merge branch 'main' into feat/emergency-help-button-5
Baibhab-Adhikari Jul 23, 2025
1da04a8
update .gitignore
Baibhab-Adhikari Jul 23, 2025
d21fd91
Fix API key configuration in configure_gemini function (bugfix)
Baibhab-Adhikari Jul 23, 2025
f6a3fd2
Refactor header component to remove redundant emergency button functi…
Baibhab-Adhikari Jul 23, 2025
7dcfb35
removed unnecessary comments
Baibhab-Adhikari Jul 23, 2025
120c4e8
Add additional emergency resources to GLOBAL_RESOURCES
Baibhab-Adhikari Jul 23, 2025
2b05a34
Update requirements.txt to include comprehensive package dependencies…
Baibhab-Adhikari Jul 23, 2025
a92891e
feature: separate emergency page as a functionality for the emergency…
Baibhab-Adhikari Jul 23, 2025
db28548
updated requirements.txt
Baibhab-Adhikari Jul 23, 2025
641c50b
Merge branch 'main' into feat/emergency-help-button-5
Baibhab-Adhikari Jul 23, 2025
28aa18e
fix: change GLOBAL_RESOURCES from a dictionary to a list for proper i…
Baibhab-Adhikari Jul 23, 2025
754a4a8
Merge branch 'main' into feat/emergency-help-button-5
Baibhab-Adhikari Jul 23, 2025
717331c
Add *.json to .gitignore to exclude JSON files
Baibhab-Adhikari Jul 24, 2025
e8602e1
changed emergency button color to red (secondary button type used)
Baibhab-Adhikari Jul 24, 2025
221f835
fix button color issues in emergency page
Baibhab-Adhikari Jul 24, 2025
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
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@

# Streamlit secrets and configuration
/.streamlit/

# pycache
__pycache__/
*.pyc
=======
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[codz]
Expand Down Expand Up @@ -238,3 +246,6 @@ __pycache__/
# Python virtual environments
venv/
env/

# JSON files
*.json
53 changes: 31 additions & 22 deletions TalkHeal.py
Original file line number Diff line number Diff line change
Expand Up @@ -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("""
<script>
Expand All @@ -69,4 +78,4 @@
}
setTimeout(scrollToBottom, 100);
</script>
""", unsafe_allow_html=True)
""", unsafe_allow_html=True)
Binary file removed components/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file removed components/__pycache__/__init__.cpython-313.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed components/__pycache__/header.cpython-312.pyc
Binary file not shown.
Binary file removed components/__pycache__/header.cpython-313.pyc
Binary file not shown.
Binary file removed components/__pycache__/sidebar.cpython-312.pyc
Binary file not shown.
Binary file removed components/__pycache__/sidebar.cpython-313.pyc
Binary file not shown.
Binary file removed components/__pycache__/theme_toggle.cpython-313.pyc
Binary file not shown.
78 changes: 78 additions & 0 deletions components/emergency_page.py
Original file line number Diff line number Diff line change
@@ -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("""
<div class="main-header">
<h1>Help is Available</h1>
<div class="stAlert stInfo">If you are in immediate danger, please call your local emergency number (e.g., 911) immediately.</div>
</div>
""", unsafe_allow_html=True)

st.subheader("Find Local Resources Near You")
geolocator = Nominatim(user_agent="talkheal_app")
location_query = st.text_input(
"Enter your City, State, or Country", placeholder="e.g., London, UK")

if st.button("🔍 Search for Help", type="primary"):
if location_query:
with st.spinner(f"Searching for '{location_query}'..."):
try:
location = geolocator.geocode(location_query)
if location:
# Store the essential location info
st.session_state.location_info = {
'lat': location.latitude,
'lon': location.longitude,
'name': location.address
}
else:
st.error(
f"Could not find a location for '{location_query}'. Please try again.")
st.session_state.pop('location_info', None)
except Exception as e:
st.error(f"An error occurred during search: {e}")
st.session_state.pop('location_info', None)
else:
st.warning("Please enter a location to search.")

# Display map and search link if a location has been found
if 'location_info' in st.session_state:
info = st.session_state.location_info
lat, lon, name = info['lat'], info['lon'], info['name']

st.success(f"Showing results for: {name}")

# --- Map Display ---
# Display a map centered on the user's searched location
map_url = f"https://www.openstreetmap.org/export/embed.html?bbox={lon-0.1},{lat-0.1},{lon+0.1},{lat+0.1}&layer=mapnik&marker={lat},{lon}"
st.components.v1.iframe(map_url, height=450)

# --- Dynamic Google Search Link ---
st.markdown("#### **Find Local Support**")
st.info(
"Click the button below for a comprehensive web search for support centers in your area.")

search_term = f"mental health crisis support near {name}"
encoded_search = urllib.parse.quote_plus(search_term)
search_url = f"https://www.google.com/search?q={encoded_search}"

st.markdown(
f'<a href="{search_url}" target="_blank" class="emergency_button">🔍 Search Google for local crisis centers</a>', unsafe_allow_html=True)

# --- Global Resources (Always available) ---
with st.expander("View Global Crisis Hotlines", expanded=True):
for resource in GLOBAL_RESOURCES:
st.markdown(
f"##### **{resource['name']}**: {resource['desc']} [Visit Website]({resource['url']})")
22 changes: 11 additions & 11 deletions components/header.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import streamlit as st
from streamlit_modal import Modal
import time


def render_header():
with st.container():
Expand Down Expand Up @@ -28,13 +27,14 @@ def render_header():
<p>Your Mental Health Companion 💙</p>
</div>
""", 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'<a href="{search_url}" target="_blank">🗺️ View Mental Health Centers Near {location_input}</a>', unsafe_allow_html=True)
st.success("Opening search results in a new tab...")
else:
st.warning("Please enter a city name")
# 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'<a href="{search_url}" target="_blank">🗺️ View Mental Health Centers Near {location_input}</a>', unsafe_allow_html=True)
# st.success("Opening search results in a new tab...")
# else:
# st.warning("Please enter a city name")
Loading