Skip to content

Commit c846ad6

Browse files
Merge branch 'main' into emoji-mood-selector
2 parents babcc05 + 434db99 commit c846ad6

File tree

14 files changed

+330
-102
lines changed

14 files changed

+330
-102
lines changed

App.png

-790 KB
Binary file not shown.

README.md

Lines changed: 60 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,18 @@
1515
* Gemini-powered chatbot for mental health companionship
1616
* Empathetic and encouraging tone—never clinical or diagnostic
1717
* Smart conversation history with multi-threaded support
18-
* Chatbot personality tone selector
19-
18+
* **Chatbot personality tone selector**:
19+
*Compassionate Listener*, *Motivating Coach*, *Wise Friend*, *Neutral Therapist*, *Mindfulness Guide*
20+
2021
### 📘 Resource & Crisis Help
2122

23+
* Emergency Help Button — instantly access local support via Google Maps
24+
* International helpline directory and global mental health resources
2225
* Mental health resource library with live search
23-
* International emergency contacts and helpline shortcuts
24-
* Quick access to location-based therapy centers via Google Maps
26+
27+
### 🧪 Science-Backed Assessments
28+
29+
* Integrated **PsyToolkit**-verified mental health quizzes for self-evaluation
2530

2631
### 💖 Mood Tracking & Journaling
2732

@@ -34,42 +39,60 @@
3439
* Instant-start suggestions like “Feeling overwhelmed” or “How to manage stress?”
3540
* Direct conversion of journal thoughts into chatbot prompts
3641

37-
### 🎨 Clean, Minimal UI
42+
### 🎨 Themes & UI
3843

39-
* Sidebar toggling for focus-driven interaction
40-
* 3D-inspired soft pink and magenta UI, best suited for a mentally soothing and peaceful outlook
44+
* Multiple soothing themes: **Light**, **Calm Blue**, **Mint**, **Lavender**, **Pink**, and **Dark**
45+
* 3D-inspired soft pink and magenta UI for a mentally soothing experience
4146
* Smooth transitions and responsive design for mobile and desktop
4247

4348
---
4449

4550
## 🚀 Live Demo
4651

47-
Experience TalkHeal live here:
48-
👉 [![**TalkHeal**](https://img.shields.io/badge/View-Live%20Demo-brightgreen?style=for-the-badge)](https://www.google.com/search?q=https://TalkHeal.streamlit.app)
49-
50-
<div align="center">
51-
<p>
52-
53-
[![Open Source Love svg1](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/)
54-
![PRs Welcome](https://img.shields.io/badge/PRs-Welcome-brightgreen.svg?style=flat)
55-
![Visitors](https://api.visitorbadge.io/api/Visitors?path=eccentriccoder01%2FTalkHeal%20&countColor=%23263759&style=flat)
56-
![GitHub Forks](https://img.shields.io/github/forks/eccentriccoder01/TalkHeal)
57-
![GitHub Repo Stars](https://img.shields.io/github/stars/eccentriccoder01/TalkHeal)
58-
![GitHub Contributors](https://img.shields.io/github/contributors/eccentriccoder01/TalkHeal)
59-
![GitHub Last Commit](https://img.shields.io/github/last-commit/eccentriccoder01/TalkHeal)
60-
![GitHub Repo Size](https://img.shields.io/github/repo-size/eccentriccoder01/TalkHeal)
61-
![GitHub Total Lines](https://sloc.xyz/github/eccentriccoder01/TalkHeal)
62-
![Github](https://img.shields.io/github/license/eccentriccoder01/TalkHeal)
63-
![GitHub Issues](https://img.shields.io/github/issues/eccentriccoder01/TalkHeal)
64-
![GitHub Closed Issues](https://img.shields.io/github/issues-closed-raw/eccentriccoder01/TalkHeal)
65-
![GitHub Pull Requests](https://img.shields.io/github/issues-pr/eccentriccoder01/TalkHeal)
66-
![GitHub Closed Pull Requests](https://img.shields.io/github/issues-pr-closed/eccentriccoder01/TalkHeal)
67-
</p>
68-
</div>
52+
### 🎯 **Experience TalkHeal live now!**
53+
🔗 [https://TalkHeal.streamlit.app](https://TalkHeal.streamlit.app)
54+
55+
---
56+
57+
## 📊 Project Stats
58+
59+
<p align="center">
60+
<a href="https://github.com/eccentriccoder01/TalkHeal">
61+
<img alt="GitHub Stars" src="https://img.shields.io/github/stars/eccentriccoder01/TalkHeal?style=flat-square" />
62+
</a>
63+
<a href="https://github.com/eccentriccoder01/TalkHeal/fork">
64+
<img alt="GitHub Forks" src="https://img.shields.io/github/forks/eccentriccoder01/TalkHeal?style=flat-square" />
65+
</a>
66+
<a href="https://github.com/eccentriccoder01/TalkHeal/graphs/contributors">
67+
<img alt="Contributors" src="https://img.shields.io/github/contributors/eccentriccoder01/TalkHeal?style=flat-square" />
68+
</a>
69+
<a href="https://github.com/eccentriccoder01/TalkHeal/issues">
70+
<img alt="Open Issues" src="https://img.shields.io/github/issues/eccentriccoder01/TalkHeal?style=flat-square" />
71+
</a>
72+
<a href="https://github.com/eccentriccoder01/TalkHeal/pulls">
73+
<img alt="Open Pull Requests" src="https://img.shields.io/github/issues-pr/eccentriccoder01/TalkHeal?style=flat-square" />
74+
</a>
75+
<a href="https://github.com/eccentriccoder01/TalkHeal/commits/main">
76+
<img alt="Last Commit" src="https://img.shields.io/github/last-commit/eccentriccoder01/TalkHeal?style=flat-square" />
77+
</a>
78+
<a href="https://github.com/eccentriccoder01/TalkHeal/blob/main/LICENSE">
79+
<img alt="License" src="https://img.shields.io/github/license/eccentriccoder01/TalkHeal?style=flat-square" />
80+
</a>
81+
</p>
82+
83+
---
84+
85+
> 💡 **PRs Welcome!** We love contributions. Check out the [Contribution Guidelines](CONTRIBUTING.md) to get started.
6986
7087
## 📸 Screenshots
7188

72-
<div align="center"><img src="App.png"/></div>
89+
<div align="center">
90+
<img src="light_ss.jpg" alt="Main Screenshot" width="600"/>
91+
<br>
92+
<img src="dark_ss.jpg" width="200"/></a>
93+
<img src="blue_ss.jpg" width="200"/></a>
94+
<img src="lav_ss.jpg" width="200"/></a>
95+
</div>
7396

7497
## 📺 Video Explanation
7598

@@ -138,7 +161,6 @@ Report bugs and issues or propose improvements through our GitHub repository.
138161
- Add Screenshots and updated website links to help us understand what changes is all about.
139162

140163
- Check the [CONTRIBUTING.md](CONTRIBUTING.md) for detailed steps...
141-
142164

143165
## Contributing is fun🧡
144166

@@ -147,9 +169,15 @@ Whether it's a new feature, design improvement, or a bug fix — your voice matt
147169

148170
Your insights are invaluable to us. Reach out to us team for any inquiries, feedback, or concerns.
149171

172+
## 👥 Contributors
173+
174+
Thanks to these wonderful people for contributing 💖
175+
176+
[![Contributors](https://contrib.rocks/image?repo=eccentriccoder01/TalkHeal)](https://github.com/eccentriccoder01/TalkHeal/graphs/contributors)
177+
150178
## 📄 License
151179

152-
This project is open-source and available under the MIT License.
180+
This project is open-source and available under the [MIT License](LICENSE).
153181

154182
## 📞 Contact
155183

TalkHeal.py

Lines changed: 90 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,38 @@
66
from core.config import PAGE_CONFIG
77
st.set_page_config(**PAGE_CONFIG)
88

9+
import google.generativeai as genai
10+
import streamlit as st
11+
12+
# --- API Key Setup ---
913
GEMINI_API_KEY = st.secrets["GEMINI_API_KEY"]
1014

11-
# --- 2. CONTINUED IMPORTS ---
12-
from core.utils import save_conversations, load_conversations, get_current_time, create_new_conversation
13-
from core.config import configure_gemini, get_tone_prompt, get_selected_mood
15+
# --- Initialize Database ---
16+
from core.db import init_db, create_user, get_user_by_username, create_chat, add_message, get_messages
17+
init_db()
18+
19+
# --- Imports ---
20+
from core.utils import save_conversations, load_conversations, get_current_time, create_new_conversation, get_ai_response
21+
from core.config import configure_gemini, PAGE_CONFIG, get_tone_prompt, get_selected_mood
22+
1423
from css.styles import apply_custom_css
1524
from components.header import render_header
1625
from components.sidebar import render_sidebar
17-
from components.chat_interface import render_chat_interface, handle_chat_input
26+
from components.chat_interface import render_chat_interface
1827
from components.emergency_page import render_emergency_page
28+
# --- Database Setup ---
29+
from core.db import init_db, get_messages, add_message, create_chat
30+
from core.db import get_user_by_username, create_user
31+
init_db()
1932

20-
# --- 3. SESSION STATE INITIALIZATION ---
33+
# --- Session State Initialization ---
2134
if "chat_history" not in st.session_state:
2235
st.session_state.chat_history = []
2336
if "conversations" not in st.session_state:
2437
st.session_state.conversations = load_conversations()
2538
if "active_conversation" not in st.session_state:
2639
st.session_state.active_conversation = -1
40+
2741
if "show_emergency_page" not in st.session_state:
2842
st.session_state.show_emergency_page = False
2943
if "sidebar_state" not in st.session_state:
@@ -40,17 +54,80 @@
4054
if "selected_mood" not in st.session_state:
4155
st.session_state.selected_mood = "🙂" # Default emoji mood
4256

57+
if "user_id" not in st.session_state:
58+
st.session_state.user_id = None
59+
if "active_chat_id" not in st.session_state:
60+
st.session_state.active_chat_id = None
61+
62+
4363
# --- 4. STYLES & GEMINI SETUP ---
4464
apply_custom_css()
4565
model = configure_gemini()
4666

47-
# --- 5. SIDEBAR ---
67+
# --- 4. TONE SELECTION DROPDOWN & EMOJI MOOD IN SIDEBAR ---
68+
TONE_OPTIONS = {
69+
"Compassionate Listener": "You are a compassionate listener — soft, empathetic, patient — like a therapist who listens without judgment.",
70+
"Motivating Coach": "You are a motivating coach — energetic, encouraging, and action-focused — helping the user push through rough days.",
71+
"Wise Friend": "You are a wise friend — thoughtful, poetic, and reflective — giving soulful responses and timeless advice.",
72+
"Neutral Therapist": "You are a neutral therapist — balanced, logical, and non-intrusive — asking guiding questions using CBT techniques.",
73+
"Mindfulness Guide": "You are a mindfulness guide — calm, slow, and grounding — focused on breathing, presence, and awareness."
74+
}
75+
76+
def get_tone_prompt():
77+
return TONE_OPTIONS.get(st.session_state.get("selected_tone", "Compassionate Listener"), TONE_OPTIONS["Compassionate Listener"])
78+
79+
# --- 5. RENDER SIDEBAR ---
80+
def render_sidebar():
81+
from core.db import get_chats_for_user, create_chat
82+
83+
with st.sidebar:
84+
st.header("🧠 Choose Your AI Tone")
85+
selected_tone = st.selectbox(
86+
"Select a personality tone:",
87+
options=list(TONE_OPTIONS.keys()),
88+
index=0
89+
)
90+
st.session_state.selected_tone = selected_tone
91+
92+
# Emoji Mood Selector (if implemented in sidebar)
93+
MOOD_OPTIONS = {
94+
"😊": "Happy",
95+
"😢": "Sad",
96+
"😡": "Angry",
97+
"😨": "Anxious",
98+
"😌": "Calm",
99+
"😕": "Confused",
100+
"🥱": "Tired",
101+
"😶": "Numb"
102+
}
103+
st.markdown("### 🌤️ How are you feeling?")
104+
selected_mood = st.radio(
105+
"Select your current mood:",
106+
options=list(MOOD_OPTIONS.keys()),
107+
horizontal=True
108+
)
109+
st.session_state.selected_mood = selected_mood
110+
111+
st.write(f"Current Mood: {MOOD_OPTIONS.get(selected_mood, 'Happy')}")
112+
113+
# Chat list from DB
114+
if "user_id" in st.session_state and st.session_state.user_id:
115+
chats = get_chats_for_user(st.session_state.user_id)
116+
for chat in chats:
117+
if st.button(chat["title"], key=f"chat_{chat['id']}"):
118+
st.session_state.active_chat_id = chat["id"]
119+
st.rerun()
120+
if st.button("➕ New Chat"):
121+
chat_id = create_chat(st.session_state.user_id, "Untitled Chat")
122+
st.session_state.active_chat_id = chat_id
123+
st.rerun()
124+
125+
# --- 6. CALL SIDEBAR ---
48126
render_sidebar()
49127

50128
# --- 6. MAIN PAGE ROUTING LOGIC ---
51129
main_area = st.container()
52-
53-
# Load conversations or start a new one
130+
# --- 8. LOAD CONVERSATIONS OR START A NEW ONE ---
54131
if not st.session_state.conversations:
55132
saved_convos = load_conversations()
56133
if saved_convos:
@@ -62,19 +139,18 @@
62139
st.session_state.active_conversation = 0
63140
st.rerun()
64141

65-
# --- 7. MAIN VIEW DISPLAY ---
66142
if st.session_state.get("show_emergency_page"):
67143
with main_area:
68144
render_emergency_page()
69145
else:
70146
with main_area:
71147
render_header()
72-
st.subheader(f"🗣️ Current Chatbot Tone: **{st.session_state['selected_tone']}**")
73-
st.markdown(f"**🧠 Mood Selected:** {get_selected_mood()}")
74-
render_chat_interface()
75-
handle_chat_input(model, system_prompt=get_tone_prompt())
148+
# --- 9. CHAT INTERFACE ---
149+
st.subheader(f"🗣️ Current Chatbot Tone: **{st.session_state['selected_tone']}**")
150+
st.markdown(f"**🧠 Mood Selected:** {get_selected_mood()}")
151+
render_chat_interface()
152+
handle_chat_input(model, system_prompt=get_tone_prompt())
76153

77-
# --- 8. AUTO SCROLL SCRIPT ---
78154
st.markdown("""
79155
<script>
80156
function scrollToBottom() {

blue_ss.jpg

161 KB
Loading

components/chat_interface.py

Lines changed: 23 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,38 @@
11
import streamlit as st
2-
import streamlit.components.v1 as components
3-
from datetime import datetime
4-
from core.utils import get_current_time, get_ai_response, save_conversations
5-
6-
# Inject JS to get user's local time zone
7-
def set_user_time_in_session():
8-
if "user_time_offset" not in st.session_state:
9-
components.html("""
10-
<script>
11-
const offset = new Date().getTimezoneOffset();
12-
const time = new Date().toLocaleString();
13-
const data = {offset: offset, time: time};
14-
window.parent.postMessage({type: 'USER_TIME', data: data}, '*');
15-
</script>
16-
""", height=0)
2+
from core.db import get_messages, add_message
3+
from core.utils import get_current_time, get_ai_response
174

5+
def render_chat_interface(model):
6+
chat_id = st.session_state.get("active_chat_id")
7+
if not chat_id:
8+
st.info("Start a new chat to begin.")
9+
return
10+
11+
messages = get_messages(chat_id)
12+
if not messages:
1813
st.markdown("""
19-
<script>
20-
window.addEventListener("message", (event) => {
21-
if (event.data.type === "USER_TIME") {
22-
const payload = JSON.stringify(event.data.data);
23-
fetch("/", {
24-
method: "POST",
25-
headers: {"Content-Type": "application/json"},
26-
body: payload
27-
}).then(() => location.reload());
28-
}
29-
});
30-
</script>
14+
<div class="welcome-message">
15+
<strong>Hello! I'm TalkHeal, your mental health companion</strong><br>
16+
How are you feeling today? You can write it down below or for a fresh start click on "➕ New Chat" 😊
17+
</div>
3118
""", unsafe_allow_html=True)
3219

33-
set_user_time_in_session()
34-
35-
# Display chat messages
36-
def render_chat_interface():
37-
if st.session_state.active_conversation >= 0:
38-
active_convo = st.session_state.conversations[st.session_state.active_conversation]
39-
40-
if not active_convo["messages"]:
20+
for msg in messages:
21+
if msg["sender"] == "user":
4122
st.markdown(f"""
42-
<div class="welcome-message">
43-
<strong>Hello! I'm TalkHeal, your mental health companion 🤗</strong><br>
44-
How are you feeling today? You can write below or start a new topic.
45-
<div class="message-time">{get_current_time()}</div>
23+
<div class="user-message">
24+
{msg["message"]}
25+
<div class="message-time">{msg["timestamp"]}</div>
4626
</div>
4727
""", unsafe_allow_html=True)
48-
49-
for msg in active_convo["messages"]:
50-
css_class = "user-message" if msg["sender"] == "user" else "bot-message"
28+
else:
5129
st.markdown(f"""
52-
<div class="{css_class}">
30+
<div class="bot-message">
5331
{msg["message"]}
54-
<div class="message-time">{msg["time"]}</div>
32+
<div class="message-time">{msg["timestamp"]}</div>
5533
</div>
5634
""", unsafe_allow_html=True)
5735

58-
# Handle chat input and generate AI response
59-
def handle_chat_input(model, system_prompt):
60-
if "pre_filled_chat_input" not in st.session_state:
61-
st.session_state.pre_filled_chat_input = ""
62-
initial_value = st.session_state.pre_filled_chat_input
63-
st.session_state.pre_filled_chat_input = ""
64-
6536
with st.form(key="chat_form", clear_on_submit=True):
6637
col1, col2 = st.columns([5, 1])
6738
with col1:
@@ -131,5 +102,4 @@ def format_memory(convo_history, max_turns=10):
131102
"time": get_current_time()
132103
})
133104

134-
save_conversations(st.session_state.conversations)
135-
st.rerun()
105+

0 commit comments

Comments
 (0)