Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -646,51 +646,293 @@ def show_main_app():
|
|
| 646 |
username = st.session_state.username
|
| 647 |
|
| 648 |
st.set_page_config(page_title="DilBot - Emotional AI", page_icon="🧠")
|
| 649 |
-
|
| 650 |
st.markdown("""
|
| 651 |
<style>
|
| 652 |
-
/*
|
| 653 |
.stApp {
|
| 654 |
-
background-color: #
|
|
|
|
|
|
|
| 655 |
}
|
| 656 |
-
|
| 657 |
-
|
| 658 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 659 |
border-radius: 10px;
|
| 660 |
-
padding:
|
| 661 |
-
|
| 662 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 663 |
}
|
| 664 |
-
|
| 665 |
-
|
|
|
|
| 666 |
border-radius: 10px;
|
| 667 |
-
|
| 668 |
-
|
| 669 |
-
|
| 670 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 671 |
}
|
| 672 |
-
/* Style for expanders */
|
| 673 |
.streamlit-expanderHeader {
|
| 674 |
-
background-color: #
|
| 675 |
-
border
|
| 676 |
-
|
| 677 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 678 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 679 |
</style>
|
| 680 |
""", unsafe_allow_html=True)
|
| 681 |
# --- END CUSTOM CSS ---
|
|
|
|
| 682 |
|
| 683 |
-
|
| 684 |
col1, col2 = st.columns([4, 1])
|
| 685 |
with col1:
|
| 686 |
st.title(f"🧠 DilBot - Welcome back, {username}!")
|
| 687 |
-
st.markdown("Your personal emotional AI companion")
|
| 688 |
with col2:
|
| 689 |
if st.button("Logout", key="logout_btn"):
|
| 690 |
st.session_state.authenticated = False
|
| 691 |
st.session_state.username = None
|
| 692 |
st.rerun()
|
| 693 |
-
|
| 694 |
# Quote categories
|
| 695 |
quote_categories = {
|
| 696 |
"Grief": ["Grief is the price we pay for love.", "Tears are the silent language of grief.", "What we have once enjoyed we can never lose; all that we love deeply becomes a part of us."],
|
|
@@ -698,15 +940,28 @@ def show_main_app():
|
|
| 698 |
"Healing": ["Every wound has its own time to heal.", "It's okay to take your time to feel better.", "Healing is not linear, and that's perfectly okay."],
|
| 699 |
"Relationships": ["The best relationships are built on trust.", "Love is not about possession but appreciation.", "Healthy relationships require both people to show up authentically."]
|
| 700 |
}
|
| 701 |
-
|
| 702 |
# UI for quote selection and file upload
|
| 703 |
-
|
| 704 |
-
|
| 705 |
-
|
| 706 |
-
|
| 707 |
-
|
| 708 |
-
|
| 709 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 710 |
|
| 711 |
# Handle vectorstore
|
| 712 |
current_quotes = []
|
|
@@ -736,17 +991,18 @@ def show_main_app():
|
|
| 736 |
st.success("✅ Voice transcribed successfully!")
|
| 737 |
|
| 738 |
# Input area
|
|
|
|
| 739 |
user_input = st.text_area(
|
| 740 |
-
"
|
| 741 |
value=st.session_state.transcribed_text,
|
| 742 |
-
height=
|
| 743 |
-
placeholder="
|
| 744 |
)
|
| 745 |
-
|
| 746 |
final_input = user_input.strip() or st.session_state.transcribed_text.strip()
|
| 747 |
|
| 748 |
# Main interaction button
|
| 749 |
-
if st.button("🧠 Talk to DilBot", type="primary"):
|
| 750 |
if not final_input:
|
| 751 |
st.warning("⚠️ Please enter something to share or upload a voice message.")
|
| 752 |
else:
|
|
@@ -779,32 +1035,31 @@ Respond as DilBot with warmth, empathy, and understanding. Keep it conversationa
|
|
| 779 |
save_user_journal(username, final_input, emotion, score, response)
|
| 780 |
|
| 781 |
# Display results
|
| 782 |
-
|
| 783 |
-
with
|
|
|
|
|
|
|
| 784 |
st.success(f"**Emotion Detected:** {emotion.capitalize()} ({round(score*100)}% confidence)")
|
| 785 |
-
|
| 786 |
if is_crisis(final_input):
|
| 787 |
-
st.error("🚨 Crisis detected! Please reach out to a mental health professional immediately."
|
| 788 |
-
|
| 789 |
-
|
| 790 |
-
|
| 791 |
-
|
| 792 |
-
|
| 793 |
-
|
| 794 |
-
|
| 795 |
-
|
| 796 |
-
|
| 797 |
-
|
| 798 |
-
|
| 799 |
-
|
| 800 |
-
|
| 801 |
-
|
| 802 |
-
|
| 803 |
-
|
| 804 |
-
|
| 805 |
-
|
| 806 |
-
# Clear transcribed text after successful interaction
|
| 807 |
-
st.session_state.transcribed_text = ""
|
| 808 |
|
| 809 |
# User's personal dashboard
|
| 810 |
st.markdown("---")
|
|
@@ -816,6 +1071,7 @@ Respond as DilBot with warmth, empathy, and understanding. Keep it conversationa
|
|
| 816 |
if journal_data:
|
| 817 |
# Mood tracker
|
| 818 |
st.subheader("📈 Your Daily Mood Tracker")
|
|
|
|
| 819 |
|
| 820 |
# Prepare data for chart
|
| 821 |
df_data = []
|
|
@@ -827,47 +1083,48 @@ Respond as DilBot with warmth, empathy, and understanding. Keep it conversationa
|
|
| 827 |
})
|
| 828 |
|
| 829 |
if df_data:
|
| 830 |
-
|
| 831 |
-
|
| 832 |
-
|
| 833 |
-
|
| 834 |
-
|
| 835 |
-
|
| 836 |
-
|
| 837 |
-
|
| 838 |
-
|
| 839 |
-
|
| 840 |
-
|
| 841 |
|
| 842 |
# Recent conversations
|
| 843 |
st.subheader("💬 Recent Conversations")
|
| 844 |
recent_entries = journal_data[-5:] if len(journal_data) >= 5 else journal_data
|
| 845 |
-
|
| 846 |
-
|
| 847 |
-
|
| 848 |
-
|
| 849 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 850 |
|
| 851 |
# Statistics
|
| 852 |
st.subheader("📊 Your Emotional Statistics")
|
| 853 |
col1, col2, col3 = st.columns(3)
|
| 854 |
-
|
| 855 |
with col1:
|
| 856 |
st.metric("Total Conversations", len(journal_data))
|
| 857 |
-
|
| 858 |
with col2:
|
| 859 |
emotions = [entry['emotion'] for entry in journal_data]
|
| 860 |
most_common = max(set(emotions), key=emotions.count) if emotions else "None"
|
| 861 |
st.metric("Most Common Emotion", most_common.capitalize())
|
| 862 |
-
|
| 863 |
with col3:
|
| 864 |
if journal_data:
|
| 865 |
avg_confidence = sum(entry['confidence'] for entry in journal_data) / len(journal_data)
|
| 866 |
st.metric("Avg. Confidence", f"{avg_confidence:.1f}%")
|
| 867 |
-
|
| 868 |
else:
|
| 869 |
st.info("🌟 Start your first conversation with DilBot to see your personal dashboard!")
|
| 870 |
-
|
| 871 |
st.markdown("---")
|
| 872 |
st.caption("Built by Members of CSG Hackathon Team | Your data is stored privately and securely")
|
| 873 |
|
|
|
|
| 646 |
username = st.session_state.username
|
| 647 |
|
| 648 |
st.set_page_config(page_title="DilBot - Emotional AI", page_icon="🧠")
|
| 649 |
+
# --- CUSTOM CSS FOR MAIN APP ---
|
| 650 |
st.markdown("""
|
| 651 |
<style>
|
| 652 |
+
/* Global Styles & Background */
|
| 653 |
.stApp {
|
| 654 |
+
background-color: #f0f2f6; /* Light, calming background */
|
| 655 |
+
color: #333333; /* Darker default text color for better readability */
|
| 656 |
+
font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; /* Modern, clean font */
|
| 657 |
}
|
| 658 |
+
|
| 659 |
+
/* Header & Titles */
|
| 660 |
+
h1, h2, h3, h4, h5, h6 {
|
| 661 |
+
color: #4A4A4A; /* Slightly darker grey for headings */
|
| 662 |
+
margin-top: 1.5rem;
|
| 663 |
+
margin-bottom: 0.8rem;
|
| 664 |
+
}
|
| 665 |
+
h1 {
|
| 666 |
+
font-size: 2.5em;
|
| 667 |
+
font-weight: 700;
|
| 668 |
+
color: #7289da; /* DilBot's primary color */
|
| 669 |
+
}
|
| 670 |
+
h2 {
|
| 671 |
+
font-size: 1.8em;
|
| 672 |
+
font-weight: 600;
|
| 673 |
+
border-bottom: 1px solid #e0e0e0; /* Subtle line under subheaders */
|
| 674 |
+
padding-bottom: 0.5rem;
|
| 675 |
+
margin-bottom: 1.5rem;
|
| 676 |
+
}
|
| 677 |
+
h3 {
|
| 678 |
+
font-size: 1.5em;
|
| 679 |
+
font-weight: 600;
|
| 680 |
+
color: #555555;
|
| 681 |
+
}
|
| 682 |
+
|
| 683 |
+
/* Metrics (Total Conversations, Most Common Emotion, Avg. Confidence) */
|
| 684 |
+
[data-testid="stMetric"] {
|
| 685 |
+
background-color: #ffffff;
|
| 686 |
+
border: 1px solid #e0e0e0;
|
| 687 |
border-radius: 10px;
|
| 688 |
+
padding: 15px;
|
| 689 |
+
box-shadow: 0 4px 8px rgba(0,0,0,0.05);
|
| 690 |
+
text-align: center;
|
| 691 |
+
margin-bottom: 1rem;
|
| 692 |
+
}
|
| 693 |
+
[data-testid="stMetricLabel"] {
|
| 694 |
+
font-size: 0.9em;
|
| 695 |
+
color: #666666;
|
| 696 |
+
margin-bottom: 5px;
|
| 697 |
+
}
|
| 698 |
+
[data-testid="stMetricValue"] {
|
| 699 |
+
font-size: 2.2em;
|
| 700 |
+
font-weight: 700;
|
| 701 |
+
color: #7289da; /* Match DilBot's primary color */
|
| 702 |
+
}
|
| 703 |
+
|
| 704 |
+
/* Buttons */
|
| 705 |
+
.stButton>button {
|
| 706 |
+
background-color: #7289da; /* DilBot's primary blue/purple */
|
| 707 |
+
color: white;
|
| 708 |
+
border: none;
|
| 709 |
+
border-radius: 8px;
|
| 710 |
+
padding: 10px 20px;
|
| 711 |
+
font-size: 1em;
|
| 712 |
+
font-weight: bold;
|
| 713 |
+
transition: background-color 0.3s ease, transform 0.2s ease;
|
| 714 |
+
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
| 715 |
+
cursor: pointer;
|
| 716 |
+
}
|
| 717 |
+
.stButton>button:hover {
|
| 718 |
+
background-color: #5b6fb8; /* Darker shade on hover */
|
| 719 |
+
transform: translateY(-2px); /* Slight lift effect */
|
| 720 |
+
}
|
| 721 |
+
.stButton>button:active {
|
| 722 |
+
background-color: #4a5a90;
|
| 723 |
+
transform: translateY(0);
|
| 724 |
+
}
|
| 725 |
+
/* Style for the logout button specifically if different */
|
| 726 |
+
[data-testid="stSidebarNav"] + div > .stButton > button { /* Adjust selector if needed for top-right logout */
|
| 727 |
+
background-color: #dc3545; /* Red for logout */
|
| 728 |
+
}
|
| 729 |
+
[data-testid="stSidebarNav"] + div > .stButton > button:hover {
|
| 730 |
+
background-color: #c82333;
|
| 731 |
+
}
|
| 732 |
+
|
| 733 |
+
|
| 734 |
+
/* Text Inputs and Text Areas */
|
| 735 |
+
.stTextInput>div>div>input, .stTextArea>div>div>textarea {
|
| 736 |
+
border-radius: 8px;
|
| 737 |
+
border: 1px solid #ced4da; /* Light grey border */
|
| 738 |
+
padding: 12px 15px;
|
| 739 |
+
font-size: 1em;
|
| 740 |
+
color: #333333;
|
| 741 |
+
box-shadow: inset 0 1px 3px rgba(0,0,0,0.05);
|
| 742 |
+
transition: border-color 0.3s ease, box-shadow 0.3s ease;
|
| 743 |
+
}
|
| 744 |
+
.stTextInput>div>div>input:focus, .stTextArea>div>div>textarea:focus {
|
| 745 |
+
border-color: #7289da; /* Highlight on focus */
|
| 746 |
+
box-shadow: 0 0 0 0.2rem rgba(114, 137, 218, 0.25);
|
| 747 |
+
outline: none;
|
| 748 |
+
}
|
| 749 |
+
.stTextInput>label, .stTextArea>label {
|
| 750 |
+
font-weight: 600;
|
| 751 |
+
color: #555555;
|
| 752 |
+
margin-bottom: 5px; /* Add some space below label */
|
| 753 |
+
}
|
| 754 |
+
|
| 755 |
+
/* Selectbox (Dropdown) */
|
| 756 |
+
.stSelectbox>div>div>div {
|
| 757 |
+
border-radius: 8px;
|
| 758 |
+
border: 1px solid #ced4da;
|
| 759 |
+
padding: 8px 12px;
|
| 760 |
+
font-size: 1em;
|
| 761 |
+
color: #333333;
|
| 762 |
+
box-shadow: inset 0 1px 3px rgba(0,0,0,0.05);
|
| 763 |
+
}
|
| 764 |
+
.stSelectbox>label {
|
| 765 |
+
font-weight: 600;
|
| 766 |
+
color: #555555;
|
| 767 |
}
|
| 768 |
+
|
| 769 |
+
/* File Uploader */
|
| 770 |
+
[data-testid="stFileUploaderDropzone"] {
|
| 771 |
border-radius: 10px;
|
| 772 |
+
border: 2px dashed #a0a8b4; /* Dashed border */
|
| 773 |
+
background-color: #ffffff;
|
| 774 |
+
padding: 20px;
|
| 775 |
+
transition: border-color 0.3s ease, background-color 0.3s ease;
|
| 776 |
+
margin-bottom: 1rem; /* Space below uploader */
|
| 777 |
+
}
|
| 778 |
+
[data-testid="stFileUploaderDropzone"]:hover {
|
| 779 |
+
border-color: #7289da; /* Highlight on hover */
|
| 780 |
+
background-color: #f7f7f7;
|
| 781 |
+
}
|
| 782 |
+
/* Hide the redundant 'Drag and drop file here' text */
|
| 783 |
+
[data-testid="stFileUploaderDropzone"] p:first-child {
|
| 784 |
+
display: none;
|
| 785 |
+
}
|
| 786 |
+
[data-testid="stFileUploaderFileName"] {
|
| 787 |
+
font-size: 0.9em;
|
| 788 |
+
color: #555;
|
| 789 |
+
margin-top: 5px;
|
| 790 |
+
}
|
| 791 |
+
|
| 792 |
+
|
| 793 |
+
/* Information, Success, Error, Warning Boxes */
|
| 794 |
+
[data-testid="stAlert"] {
|
| 795 |
+
border-radius: 8px;
|
| 796 |
+
padding: 15px 20px;
|
| 797 |
+
margin-bottom: 1rem;
|
| 798 |
+
font-size: 1em;
|
| 799 |
+
line-height: 1.5;
|
| 800 |
+
}
|
| 801 |
+
[data-testid="stAlert"] .css-1aumx4k { /* Inner div for icon/text */
|
| 802 |
+
align-items: center;
|
| 803 |
+
}
|
| 804 |
+
/* Specific styles for each type */
|
| 805 |
+
[data-testid="stAlert"] .streamlit-warning {
|
| 806 |
+
background-color: #fff3cd; /* Light yellow */
|
| 807 |
+
color: #664d03;
|
| 808 |
+
border-left: 5px solid #ffc107; /* Yellow border */
|
| 809 |
+
}
|
| 810 |
+
[data-testid="stAlert"] .streamlit-success {
|
| 811 |
+
background-color: #d1e7dd; /* Light green */
|
| 812 |
+
color: #0f5132;
|
| 813 |
+
border-left: 5px solid #198754; /* Green border */
|
| 814 |
+
}
|
| 815 |
+
[data-testid="stAlert"] .streamlit-error {
|
| 816 |
+
background-color: #f8d7da; /* Light red */
|
| 817 |
+
color: #842029;
|
| 818 |
+
border-left: 5px solid #dc3545; /* Red border */
|
| 819 |
+
}
|
| 820 |
+
[data-testid="stAlert"] .streamlit-info {
|
| 821 |
+
background-color: #cfe2ff; /* Light blue */
|
| 822 |
+
color: #055160;
|
| 823 |
+
border-left: 5px solid #0dcaf0; /* Cyan border */
|
| 824 |
+
}
|
| 825 |
+
|
| 826 |
+
|
| 827 |
+
/* Markdown for Quote and Response */
|
| 828 |
+
.stMarkdown h3 { /* For "DilBot's Response" title */
|
| 829 |
+
font-size: 1.6em;
|
| 830 |
+
color: #7289da;
|
| 831 |
+
margin-top: 2rem;
|
| 832 |
+
margin-bottom: 1rem;
|
| 833 |
+
}
|
| 834 |
+
/* Styling for the blockquote (DilBot's response) */
|
| 835 |
+
.stMarkdown blockquote {
|
| 836 |
+
background-color: #ffffff;
|
| 837 |
+
border-left: 6px solid #7289da; /* Accent border */
|
| 838 |
+
padding: 15px 20px;
|
| 839 |
+
margin: 1.5rem 0;
|
| 840 |
+
border-radius: 10px;
|
| 841 |
+
font-style: italic;
|
| 842 |
+
color: #4a4a4a;
|
| 843 |
+
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
| 844 |
+
line-height: 1.6;
|
| 845 |
+
}
|
| 846 |
+
.stMarkdown blockquote p { /* Ensure text inside blockquote is styled */
|
| 847 |
+
margin-bottom: 0;
|
| 848 |
+
}
|
| 849 |
+
|
| 850 |
+
/* Quote for you (st.info) */
|
| 851 |
+
.stInfo { /* Target the st.info for quotes specifically if needed */
|
| 852 |
+
background-color: #e6f7ff; /* Lighter blue for quote box */
|
| 853 |
+
border-left: 6px solid #4893c5; /* Accent border */
|
| 854 |
+
color: #004085;
|
| 855 |
+
border-radius: 8px;
|
| 856 |
+
padding: 15px 20px;
|
| 857 |
+
margin-top: 1.5rem;
|
| 858 |
+
font-style: italic;
|
| 859 |
+
}
|
| 860 |
+
.stInfo span[data-baseweb="tag"] { /* Targeting the '💭 Quote for you:' part */
|
| 861 |
+
font-weight: bold;
|
| 862 |
+
color: #004085;
|
| 863 |
+
}
|
| 864 |
+
|
| 865 |
+
|
| 866 |
+
/* Audio Player */
|
| 867 |
+
.stAudio {
|
| 868 |
+
margin-top: 1.5rem;
|
| 869 |
+
margin-bottom: 2rem;
|
| 870 |
+
}
|
| 871 |
+
|
| 872 |
+
/* Expander styling (for conversations) */
|
| 873 |
+
.streamlit-expanderContent {
|
| 874 |
+
background-color: #f8f9fa; /* Light background for content */
|
| 875 |
+
border-left: 3px solid #ced4da;
|
| 876 |
+
padding: 10px 15px;
|
| 877 |
+
border-bottom-left-radius: 8px;
|
| 878 |
+
border-bottom-right-radius: 8px;
|
| 879 |
+
margin-top: -10px; /* Adjust to sit right under header */
|
| 880 |
}
|
|
|
|
| 881 |
.streamlit-expanderHeader {
|
| 882 |
+
background-color: #ffffff;
|
| 883 |
+
border: 1px solid #e0e0e0;
|
| 884 |
+
border-radius: 8px;
|
| 885 |
+
padding: 10px 15px;
|
| 886 |
+
margin-bottom: 0.5rem;
|
| 887 |
+
cursor: pointer;
|
| 888 |
+
transition: background-color 0.2s ease;
|
| 889 |
+
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
| 890 |
+
}
|
| 891 |
+
.streamlit-expanderHeader:hover {
|
| 892 |
+
background-color: #f5f5f5;
|
| 893 |
}
|
| 894 |
+
.streamlit-expanderHeader > div > div > p { /* Target expander title text */
|
| 895 |
+
font-weight: 500;
|
| 896 |
+
color: #333333;
|
| 897 |
+
}
|
| 898 |
+
.stExpander.css-1r0f5rs.e1gf0vsg1 { /* specific class for closed expander */
|
| 899 |
+
/* You might need to inspect to get the exact class for closed/open state */
|
| 900 |
+
/* border-radius: 8px; */
|
| 901 |
+
}
|
| 902 |
+
|
| 903 |
+
|
| 904 |
+
/* Horizontal rule */
|
| 905 |
+
hr {
|
| 906 |
+
border-top: 1px solid #e0e0e0;
|
| 907 |
+
margin-top: 2rem;
|
| 908 |
+
margin-bottom: 2rem;
|
| 909 |
+
}
|
| 910 |
+
|
| 911 |
+
/* Caption (footer) */
|
| 912 |
+
.stMarkdown small {
|
| 913 |
+
color: #888888;
|
| 914 |
+
font-size: 0.85em;
|
| 915 |
+
margin-top: 2rem;
|
| 916 |
+
display: block; /* Make sure it takes its own line */
|
| 917 |
+
text-align: center;
|
| 918 |
+
}
|
| 919 |
+
|
| 920 |
</style>
|
| 921 |
""", unsafe_allow_html=True)
|
| 922 |
# --- END CUSTOM CSS ---
|
| 923 |
+
|
| 924 |
|
| 925 |
+
# Header with logout
|
| 926 |
col1, col2 = st.columns([4, 1])
|
| 927 |
with col1:
|
| 928 |
st.title(f"🧠 DilBot - Welcome back, {username}!")
|
| 929 |
+
st.markdown("<p style='font-size: 1.1em; color: #666666;'>Your personal emotional AI companion</p>", unsafe_allow_html=True) # Styled tagline
|
| 930 |
with col2:
|
| 931 |
if st.button("Logout", key="logout_btn"):
|
| 932 |
st.session_state.authenticated = False
|
| 933 |
st.session_state.username = None
|
| 934 |
st.rerun()
|
| 935 |
+
|
| 936 |
# Quote categories
|
| 937 |
quote_categories = {
|
| 938 |
"Grief": ["Grief is the price we pay for love.", "Tears are the silent language of grief.", "What we have once enjoyed we can never lose; all that we love deeply becomes a part of us."],
|
|
|
|
| 940 |
"Healing": ["Every wound has its own time to heal.", "It's okay to take your time to feel better.", "Healing is not linear, and that's perfectly okay."],
|
| 941 |
"Relationships": ["The best relationships are built on trust.", "Love is not about possession but appreciation.", "Healthy relationships require both people to show up authentically."]
|
| 942 |
}
|
| 943 |
+
|
| 944 |
# UI for quote selection and file upload
|
| 945 |
+
# Use st.container for better visual grouping
|
| 946 |
+
st.markdown("### 📝 Input Your Thoughts") # New subheader for input section
|
| 947 |
+
with st.container(border=True): # New feature in Streamlit for container with border
|
| 948 |
+
col1, col2 = st.columns(2)
|
| 949 |
+
with col1:
|
| 950 |
+
selected_category = st.selectbox("🎯 Choose a quote theme:", list(quote_categories.keys()))
|
| 951 |
+
with col2:
|
| 952 |
+
st.markdown("##### 📁 Custom Quotes & Voice Input") # Smaller header
|
| 953 |
+
uploaded_quotes = st.file_uploader("Upload your own quotes (.txt)", type=["txt"], key="quote_uploader")
|
| 954 |
+
uploaded_audio = st.file_uploader("Upload a voice message (.wav)", type=["wav"], key="audio_uploader")
|
| 955 |
+
|
| 956 |
+
# Voice transcription button moved for better flow
|
| 957 |
+
if uploaded_audio and st.button("🎙️ Transcribe Voice Message", key="transcribe_btn"): # Updated button text
|
| 958 |
+
with st.spinner("Transcribing your voice..."):
|
| 959 |
+
transcribed = transcribe_audio_file(uploaded_audio)
|
| 960 |
+
if transcribed.startswith("Error:"):
|
| 961 |
+
st.error(transcribed)
|
| 962 |
+
else:
|
| 963 |
+
st.session_state.transcribed_text = transcribed
|
| 964 |
+
st.success("✅ Voice transcribed successfully!")
|
| 965 |
|
| 966 |
# Handle vectorstore
|
| 967 |
current_quotes = []
|
|
|
|
| 991 |
st.success("✅ Voice transcribed successfully!")
|
| 992 |
|
| 993 |
# Input area
|
| 994 |
+
st.markdown("##### 💬 What's on your mind?")
|
| 995 |
user_input = st.text_area(
|
| 996 |
+
"Share your thoughts, feelings, or experiences...", # Removed redundant label
|
| 997 |
value=st.session_state.transcribed_text,
|
| 998 |
+
height=150, # Slightly increased height
|
| 999 |
+
placeholder="Type here or use your transcribed voice message..."
|
| 1000 |
)
|
| 1001 |
+
|
| 1002 |
final_input = user_input.strip() or st.session_state.transcribed_text.strip()
|
| 1003 |
|
| 1004 |
# Main interaction button
|
| 1005 |
+
if st.button("🧠 Talk to DilBot", type="primary", use_container_width=True):
|
| 1006 |
if not final_input:
|
| 1007 |
st.warning("⚠️ Please enter something to share or upload a voice message.")
|
| 1008 |
else:
|
|
|
|
| 1035 |
save_user_journal(username, final_input, emotion, score, response)
|
| 1036 |
|
| 1037 |
# Display results
|
| 1038 |
+
st.markdown("### 🤖 DilBot's Conversation:") # New title for conversation output
|
| 1039 |
+
with st.container(border=True): # Container for the conversation output
|
| 1040 |
+
# User's input presented in a div
|
| 1041 |
+
st.markdown(f"<div class='user-message'>**You:** {final_input}</div>", unsafe_allow_html=True)
|
| 1042 |
st.success(f"**Emotion Detected:** {emotion.capitalize()} ({round(score*100)}% confidence)")
|
| 1043 |
+
|
| 1044 |
if is_crisis(final_input):
|
| 1045 |
+
st.error("🚨 Crisis detected! Please reach out to a mental health professional immediately. "
|
| 1046 |
+
"You are not alone. Consider contacting a helpline like the National Suicide Prevention Lifeline (988 in the US) or a local emergency service.") # Enhanced crisis message
|
| 1047 |
+
|
| 1048 |
+
if current_quotes:
|
| 1049 |
+
model = SentenceTransformer("all-MiniLM-L6-v2")
|
| 1050 |
+
quote_embeddings = model.encode(current_quotes, convert_to_tensor=True)
|
| 1051 |
+
user_embedding = model.encode(final_input, convert_to_tensor=True)
|
| 1052 |
+
sims = util.pytorch_cos_sim(user_embedding, quote_embeddings)[0]
|
| 1053 |
+
best_match = sims.argmax().item()
|
| 1054 |
+
selected_quote = current_quotes[best_match]
|
| 1055 |
+
st.info(f"💭 **Quote for you:** *{selected_quote}*")
|
| 1056 |
+
|
| 1057 |
+
# DilBot's response presented in a blockquote with custom styling
|
| 1058 |
+
st.markdown("### 🤖 DilBot's Response:")
|
| 1059 |
+
st.markdown(f"> {response}") # Using your existing markdown blockquote
|
| 1060 |
+
|
| 1061 |
+
speak(response, username)
|
| 1062 |
+
st.session_state.transcribed_text = ""
|
|
|
|
|
|
|
|
|
|
| 1063 |
|
| 1064 |
# User's personal dashboard
|
| 1065 |
st.markdown("---")
|
|
|
|
| 1071 |
if journal_data:
|
| 1072 |
# Mood tracker
|
| 1073 |
st.subheader("📈 Your Daily Mood Tracker")
|
| 1074 |
+
with st.container(border=True):
|
| 1075 |
|
| 1076 |
# Prepare data for chart
|
| 1077 |
df_data = []
|
|
|
|
| 1083 |
})
|
| 1084 |
|
| 1085 |
if df_data:
|
| 1086 |
+
chart = alt.Chart(alt.Data(values=df_data)).mark_bar().encode(
|
| 1087 |
+
x=alt.X('date:N', title='Date'),
|
| 1088 |
+
y=alt.Y('count():Q', title='Frequency'),
|
| 1089 |
+
color=alt.Color('emotion:N', title='Emotion'),
|
| 1090 |
+
tooltip=['date:N', 'emotion:N', 'count():Q']
|
| 1091 |
+
).properties(
|
| 1092 |
+
width=600,
|
| 1093 |
+
height=300,
|
| 1094 |
+
title="Your Emotional Journey Over Time"
|
| 1095 |
+
).interactive() # Make chart interactive for zoom/pan
|
| 1096 |
+
st.altair_chart(chart, use_container_width=True)
|
| 1097 |
|
| 1098 |
# Recent conversations
|
| 1099 |
st.subheader("💬 Recent Conversations")
|
| 1100 |
recent_entries = journal_data[-5:] if len(journal_data) >= 5 else journal_data
|
| 1101 |
+
|
| 1102 |
+
with st.container(border=True): # Wrap recent conversations in a container
|
| 1103 |
+
if recent_entries:
|
| 1104 |
+
for i, entry in enumerate(reversed(recent_entries)):
|
| 1105 |
+
with st.expander(f"📅 {entry['date']} - {entry['emotion'].capitalize()} ({entry['confidence']}%)"):
|
| 1106 |
+
st.markdown(f"**You said:** {entry['user_input']}")
|
| 1107 |
+
st.markdown(f"**DilBot replied:** {entry['response']}")
|
| 1108 |
+
else:
|
| 1109 |
+
st.info("No recent conversations yet. Start talking to DilBot!")
|
| 1110 |
|
| 1111 |
# Statistics
|
| 1112 |
st.subheader("📊 Your Emotional Statistics")
|
| 1113 |
col1, col2, col3 = st.columns(3)
|
| 1114 |
+
|
| 1115 |
with col1:
|
| 1116 |
st.metric("Total Conversations", len(journal_data))
|
|
|
|
| 1117 |
with col2:
|
| 1118 |
emotions = [entry['emotion'] for entry in journal_data]
|
| 1119 |
most_common = max(set(emotions), key=emotions.count) if emotions else "None"
|
| 1120 |
st.metric("Most Common Emotion", most_common.capitalize())
|
|
|
|
| 1121 |
with col3:
|
| 1122 |
if journal_data:
|
| 1123 |
avg_confidence = sum(entry['confidence'] for entry in journal_data) / len(journal_data)
|
| 1124 |
st.metric("Avg. Confidence", f"{avg_confidence:.1f}%")
|
|
|
|
| 1125 |
else:
|
| 1126 |
st.info("🌟 Start your first conversation with DilBot to see your personal dashboard!")
|
| 1127 |
+
|
| 1128 |
st.markdown("---")
|
| 1129 |
st.caption("Built by Members of CSG Hackathon Team | Your data is stored privately and securely")
|
| 1130 |
|