prawnz11 ShashankV1 commited on
Commit
9e296a1
·
verified ·
1 Parent(s): d406590

Update homepage.py (#3)

Browse files

- Update homepage.py (c9f159aaa5e0af52756239bdc5c6b8f8cf3f0179)


Co-authored-by: Shashank Verma <ShashankV1@users.noreply.huggingface.co>

Files changed (1) hide show
  1. homepage.py +81 -265
homepage.py CHANGED
@@ -1,280 +1,96 @@
1
  import streamlit as st
2
- import random
 
 
 
 
3
  from datetime import datetime
4
 
5
- # --- IMPORTANT: Streamlit's Native Multi-Page App Setup ---
6
- # Streamlit automatically discovers pages in a 'pages' subdirectory.
7
- # This homepage.py serves as the default 'Home' page.
8
- # Navigation is handled by Streamlit's sidebar, automatically generated from pages/*.py files.
9
-
10
- # --- Optional: Drawing canvas library check ---
11
- try:
12
- from streamlit_drawable_canvas import st_canvas
13
- DRAWING_AVAILABLE = True
14
- except ImportError:
15
- DRAWING_AVAILABLE = False
16
-
17
- st.set_page_config(
18
- page_title="HappyTrails",
19
- page_icon="🐾",
20
- layout="wide",
21
- initial_sidebar_state="expanded"
22
- )
23
-
24
- # --- THEME DEFINITIONS (IMPORTANT: COPY THIS BLOCK TO ALL FILES IN THE 'PAGES' FOLDER) ---
25
- # These themes apply global styles and define character-based hero images.
26
  THEMES = {
27
  "boy": {
28
- "primary_background": "#D0E4FF", # Light blue for Spiderman
29
- "secondary_background": "#A7D2FF", # Slightly darker blue for content areas
30
- "text_color": "#202060", # Dark blue/red for text
31
- "accent_color": "#E53935", # Red for buttons/accents
32
- "hero_image": "https://placehold.co/400x300/e53935/ffffff?text=Spiderman+Theme",
33
- "welcome_message": "Ready for an adventure, {name}!" # Updated to use {name}
34
- },
35
- "girl": {
36
- "primary_background": "#FFEBFB", # Light pink/purple for Gwen Stacy
37
- "secondary_background": "#F5C7F7", # Slightly darker pink
38
- "text_color": "#7B1FA2",
39
- "accent_color": "#EC407A",
40
- "hero_image": "https://placehold.co/400x300/EC407A/ffffff?text=Gwen+Stacy+Theme",
41
- "welcome_message": "Hello, {name}! Let's make today amazing!" # Updated to use {name}
42
- },
43
- "neutral": { # Default for "Other" or if profile not set
44
- "primary_background": "#E0FFE0",
45
- "secondary_background": "#C9F0C9",
46
- "text_color": "#33691E",
47
- "accent_color": "#8BC34A",
48
- "hero_image": "https://placehold.co/400x300/8BC34A/ffffff?text=HappyTrails+Theme",
49
- "welcome_message": "Welcome to HappyTrails, {name}!" # Updated to use {name}
50
  }
51
  }
52
 
53
- # SVG Icon Definitions (Copied to all pages for independent rendering)
54
- SPIDERMAN_ICON_SVG = """
55
- <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 60 60" style="vertical-align:middle; margin-right:10px; fill:currentColor;">
56
- <circle cx="30" cy="18" r="8"/> <!-- Head -->
57
- <circle cx="30" cy="42" r="18"/> <!-- Body -->
58
- <path d="M30,26 L10,5 L5,15 L15,25" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <!-- Top-left leg -->
59
- <path d="M30,26 L50,5 L55,15 L45,25" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <!-- Top-right leg -->
60
- <path d="M30,40 L10,50 L5,55 L15,45" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <!-- Mid-left leg -->
61
- <path d="M30,40 L50,50 L55,55 L45,45" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> <!-- Mid-right leg -->
62
- </svg>
63
- """
64
-
65
- GWEN_STACY_ICON_SVG = """
66
- <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 60 60" style="vertical-align:middle; margin-right:10px; fill:currentColor;">
67
- <!-- Hood shape -->
68
- <path d="M30 5 L5 25 V55 H55 V25 L30 5 Z" fill="none" stroke="currentColor" stroke-width="2"/>
69
- <!-- Eye shapes - stylized like her mask -->
70
- <path d="M18 25 C15 20 10 25 18 35 C26 25 21 20 18 25 Z" fill="currentColor"/> <!-- Left Eye -->
71
- <path d="M42 25 C45 20 50 25 42 35 C34 25 39 20 42 25 Z" fill="currentColor"/> <!-- Right Eye -->
72
- </svg>
73
- """
74
-
75
- # Function to apply the selected theme via custom CSS (IMPORTANT: COPY THIS BLOCK TO ALL FILES IN THE 'PAGES' FOLDER)
76
- def apply_theme():
77
- selected_gender = st.session_state.user_profile.get("gender", "neutral") if "user_profile" in st.session_state else "neutral"
78
- theme = THEMES.get(selected_gender, THEMES["neutral"])
79
-
80
- # Define CSS variables for easier use
81
- st.markdown(f"""
82
  <style>
83
- :root {{
84
- --primary-background: {theme["primary_background"]};
85
- --secondary-background: {theme["secondary_background"]};
86
- --text-color: {theme["text_color"]};
87
- --accent-color: {theme["accent_color"]};
88
- }}
89
-
90
- /* Apply theme colors using CSS variables */
91
  .stApp {{
92
- background-color: var(--primary-background);
93
- color: var(--text-color); /* Fallback for general text */
94
- }}
95
- /* Target common Streamlit components for text color */
96
- /* Increased specificity for text color to override Streamlit defaults */
97
- div, p, span, li, ul, ol, strong, em,
98
- .st-emotion-cache-nahz7x, /* General text in st.write, st.markdown */
99
- .st-emotion-cache-1f8796m, /* Text inside info/warning/success boxes */
100
- .st-emotion-cache-1m6a05l, /* Streamlit headers/titles */
101
- .st-emotion-cache-jny0p5, /* Text input and text area labels */
102
- .st-emotion-cache-vk3360, /* Radio/checkbox labels */
103
- .st-emotion-cache-1k1q0z8 /* Selectbox labels */
104
- {{
105
- color: var(--text-color) !important; /* Use !important to ensure override */
106
  }}
107
-
108
- .st-emotion-cache-1jm6gvd {{ /* Targeted for the main content area background */
109
- background-color: var(--secondary-background);
110
- }}
111
- /* Headings color */
112
- h1, h2, h3, h4, h5, h6 {{
113
- color: var(--text-color) !important; /* Use !important for headings */
114
- }}
115
- /* Button styling */
116
  .stButton>button {{
117
- background-color: var(--accent-color);
118
- color: white !important; /* Force white text on buttons */
119
- border-radius: 8px;
120
- border: none;
121
- padding: 10px 20px;
122
- font-weight: bold;
123
- box-shadow: 2px 2px 5px rgba(0,0,0,0.2);
124
- }}
125
- .stButton>button:hover {{
126
- background-color: #FF7043; /* A slightly different accent on hover */
127
- transform: translateY(-2px);
128
- box-shadow: 3px 3px 6px rgba(0,0,0,0.3);
129
- }}
130
- /* Label colors for various input widgets */
131
- .stRadio > label, .stSelectbox > label, .stSlider > label, .stTextInput > label, .stTextArea > label, .stFileUploader > label {{
132
- color: var(--text-color) !important;
133
- }}
134
- /* Markdown text color - important for general text */
135
- .stMarkdown {{
136
- color: var(--text-color) !important;
137
- }}
138
- .stRadio div[role="radiogroup"] {{
139
- background-color: var(--secondary-background);
140
- padding: 10px;
141
- border-radius: 8px;
142
- }}
143
- .stSelectbox div[data-baseweb="select"] {{
144
- background-color: var(--secondary-background);
145
- border-radius: 8px;
146
- }}
147
-
148
- /* Specific styles for info/warning/success/error boxes to ensure text visibility */
149
- /* Targeting by class of the main alert container and the icon/text spans within */
150
- .st-emotion-cache-1f8796m[data-baseweb="alert"] {{ /* general alert box container */
151
- color: var(--text-color) !important; /* Text color inside alert boxes */
152
- border-left-width: 5px;
153
- border-left-style: solid;
154
- border-radius: 8px;
155
- padding: 1rem;
156
- margin-bottom: 1rem;
157
- }}
158
- .st-emotion-cache-1f8796m[data-baseweb="alert"][kind="info"] {{
159
- background-color: rgba(0, 123, 255, 0.1);
160
- border-left-color: #007bff;
161
- }}
162
- .st-emotion-cache-1f8796m[data-baseweb="alert"][kind="success"] {{
163
- background-color: rgba(40, 167, 69, 0.1);
164
- border-left-color: #28a745;
165
- }}
166
- .st-emotion-cache-1f8796m[data-baseweb="alert"][kind="warning"] {{
167
- background-color: rgba(255, 193, 7, 0.1);
168
- border-left-color: #ffc107;
169
- }}
170
- .st-emotion-cache-1f8796m[data-baseweb="alert"][kind="error"] {{
171
- background-color: rgba(220, 53, 69, 0.1);
172
- border-left-color: #dc3545;
173
- }}
174
- /* For Streamlit's chat messages to ensure readability */
175
- .stChatMessage {{
176
- background-color: var(--secondary-background) !important; /* Chat bubble background */
177
- color: var(--text-color) !important; /* Chat text color */
178
- border-radius: 12px;
179
- padding: 10px 15px;
180
- margin-bottom: 8px;
181
- }}
182
- .stChatMessage.st-user {{ /* User's message */
183
- background-color: rgba(var(--accent-color-rgb), 0.1) !important; /* Lighter accent for user */
184
- color: var(--text-color) !important;
185
- }}
186
- .stChatMessage.st-assistant {{ /* Assistant's message */
187
- background-color: rgba(var(--secondary-background-rgb), 0.8) !important; /* Secondary background for assistant */
188
- color: var(--text-color) !important;
189
- }}
190
-
191
- /* Ensuring SVGs fill with current text color */
192
- svg {{
193
- fill: currentColor;
194
  }}
195
  </style>
196
- """, unsafe_allow_html=True)
197
-
198
-
199
- # --- Session State Initialization (Global and accessible by all pages) ---
200
- # This block ensures that essential session state variables are initialized once.
201
- if 'user_profile' not in st.session_state:
202
- st.session_state.user_profile = {"name": "Friend", "age": None, "gender": "neutral", "profile_set": False}
203
- if 'conversation' not in st.session_state:
204
- st.session_state.conversation = []
205
- if 'mood_data' not in st.session_state:
206
- st.session_state.mood_data = []
207
- if 'drawings' not in st.session_state: # For Drawing Canvas (list to store image data)
208
- st.session_state.drawings = []
209
- if 'canvas_key' not in st.session_state: # For Drawing Canvas (to force clear)
210
- st.session_state.canvas_key = 0
211
-
212
- # Game-specific session states (for games_page.py)
213
- if "board" not in st.session_state: # For Tic-Tac-Toe
214
- st.session_state.board = [" " for _ in range(9)]
215
- st.session_state.player = "X"
216
- st.session_state.game_over = False
217
- st.session_state.message = "Your turn (X)!"
218
- if "game_state" not in st.session_state: # For managing game resets (Tic-Tac-Toe, WYR)
219
- st.session_state.game_state = None
220
- if "current_wyr_question" not in st.session_state: # For Would You Rather?
221
- st.session_state.current_wyr_question = None
222
- if "wyr_choice_made" not in st.session_state: # For Would You Rather?
223
- st.session_state.wyr_choice_made = False
224
- if "current_adventure" not in st.session_state: # For Adventure Jar
225
- st.session_state.current_adventure = None
226
-
227
-
228
- # --- Apply Theme Globally ---
229
- # This function is called at the very top of the script to ensure CSS is applied
230
- # before any other content is rendered, providing a consistent theme.
231
- apply_theme()
232
-
233
-
234
- # --- Main Page Content ---
235
- # This content runs only when homepage.py is the active page (i.e., when launched or 'Home' is clicked in sidebar)
236
- st.title(f"👋 Welcome to HappyTrails!")
237
-
238
- # --- User Profile Setup Section ---
239
- if not st.session_state.user_profile["profile_set"]:
240
- st.subheader("First, tell HappyTrails a little about yourself!")
241
- with st.form("user_profile_form", clear_on_submit=False):
242
- name = st.text_input("What's your name?", max_chars=20, key="profile_name_input")
243
- age = st.number_input("How old are you?", min_value=1, max_value=120, step=1, key="profile_age_input")
244
- gender_option = st.radio(
245
- "Are you a boy or a girl, or would you prefer not to say?",
246
- ["Boy", "Girl", "Other / Prefer not to say"],
247
- key="profile_gender_radio"
248
- )
249
- submit_profile = st.form_submit_button("Start My HappyTrails Adventure!")
250
-
251
- if submit_profile:
252
- if name.strip():
253
- st.session_state.user_profile["name"] = name.strip()
254
- st.session_state.user_profile["age"] = age
255
- st.session_state.user_profile["gender"] = gender_option.lower().replace(" / prefer not to say", "") # Clean up string
256
- st.session_state.user_profile["profile_set"] = True
257
- st.success(f"Hello, {st.session_state.user_profile['name']}! Get ready for fun!")
258
- st.rerun() # Rerun to apply theme and show personalized content
259
- else:
260
- st.warning("Please tell us your name!")
261
- else:
262
- # --- Personalized Welcome After Profile Setup ---
263
- current_theme = THEMES.get(st.session_state.user_profile["gender"], THEMES["neutral"])
264
-
265
- # Use f-string formatting to insert the user's name directly
266
- welcome_message_formatted = current_theme['welcome_message'].format(name=st.session_state.user_profile['name'])
267
- st.header(f"{welcome_message_formatted} 🤗")
268
-
269
- st.markdown("""
270
- #### Here’s how to get started and have fun with your digital friend:
271
-
272
- HappyTrails is your friend for every feeling! By playing games, chatting, drawing, and exploring adventures, HappyTrails helps you:
273
- - **Understand Emotions:** Track your feelings in the journal.
274
- - **Boost Creativity:** Express yourself through drawing and imagination.
275
- - **Develop Skills:** Play fun games that make you think and learn.
276
- - **Feel Heard & Safe:** Always have a friend ready to listen.
277
 
278
- You can explore all these wonderful features using the **navigation sidebar on the left**!
279
- """)
280
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ from streamlit_drawable_canvas import st_canvas
3
+ from PIL import Image
4
+ import numpy as np
5
+ import io
6
+ import base64
7
  from datetime import datetime
8
 
9
+ # ---------------------- Initialize Theme Colors (You can adjust this) ----------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  THEMES = {
11
  "boy": {
12
+ "primary_background": "#D0E4FF",
13
+ "secondary_background": "#A7C7E7",
14
+ "button_color": "#4A90E2"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  }
16
  }
17
 
18
+ theme = THEMES.get("boy", THEMES["boy"])
19
+ st.markdown(
20
+ f"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  <style>
 
 
 
 
 
 
 
 
22
  .stApp {{
23
+ background-color: {theme['primary_background']};
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  }}
 
 
 
 
 
 
 
 
 
25
  .stButton>button {{
26
+ background-color: {theme['button_color']};
27
+ color: white;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  }}
29
  </style>
30
+ """,
31
+ unsafe_allow_html=True
32
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
+ # ---------------------- Initialize Session State ----------------------
35
+ if "saved_drawings" not in st.session_state:
36
+ st.session_state.saved_drawings = []
37
+
38
+ # ---------------------- Main Page Function ----------------------
39
+ def draw_page():
40
+ st.title("🎨 HappyTrails: Draw Your Mood!")
41
+
42
+ # Canvas settings with unique keys
43
+ stroke_width = st.sidebar.slider("Brush Size", 1, 25, 5, key="brush_size_slider")
44
+ stroke_color = st.sidebar.color_picker("Stroke Color", "#000000", key="stroke_color_picker")
45
+ bg_color = st.sidebar.color_picker("Canvas Background", "#FFFFFF", key="bg_color_picker")
46
+ drawing_mode = st.sidebar.selectbox("Drawing Tool", ("freedraw", "line", "rect", "circle", "transform"), key="drawing_tool_select")
47
+ realtime_update = st.sidebar.checkbox("Update in Real Time", True, key="realtime_update_checkbox")
48
+
49
+ # Load canvas with fallback
50
+ initial_canvas_data = {"version": "5.3.0", "objects": []}
51
+
52
+ canvas_result = st_canvas(
53
+ fill_color="rgba(0, 0, 0, 0)",
54
+ stroke_width=stroke_width,
55
+ stroke_color=stroke_color,
56
+ background_color=bg_color,
57
+ background_image=None,
58
+ update_streamlit=realtime_update,
59
+ height=400,
60
+ width=600,
61
+ drawing_mode=drawing_mode,
62
+ key="canvas",
63
+ initial_drawing=initial_canvas_data
64
+ )
65
+
66
+ # Save drawing if user clicks
67
+ if st.button("💾 Save Drawing"):
68
+ if canvas_result.image_data is not None and canvas_result.image_data.sum() > 0:
69
+ drawing_data = {
70
+ "image": canvas_result.image_data,
71
+ "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
72
+ "bg_color": bg_color,
73
+ "stroke_color": stroke_color
74
+ }
75
+ st.session_state.saved_drawings.append(drawing_data)
76
+ st.success("Drawing saved!")
77
+ else:
78
+ st.warning("Canvas is empty. Draw something before saving.")
79
+
80
+ # Show saved drawings
81
+ if st.session_state.saved_drawings:
82
+ st.subheader("🖼️ Your Saved Drawings")
83
+ for i, saved in enumerate(st.session_state.saved_drawings):
84
+ st.markdown(f"*Drawing {i + 1} - {saved['timestamp']}*")
85
+ st.image(saved["image"])
86
+
87
+ # Clear saved drawings with confirmation
88
+ with st.expander("⚠️ Clear All Drawings", expanded=False):
89
+ confirm_clear = st.checkbox("Yes, delete all my drawings", key="clear_confirm_checkbox")
90
+ if confirm_clear and st.button("🗑️ Clear All My Saved Drawings"):
91
+ st.session_state.saved_drawings = []
92
+ st.success("All drawings deleted.")
93
+
94
+ # ---------------------- Run the page ----------------------
95
+ if _name_ == "_main_":
96
+ draw_page()