IAMTFRMZA commited on
Commit
044981b
·
verified ·
1 Parent(s): c21364d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -31
app.py CHANGED
@@ -48,7 +48,7 @@ if "last_audio_path" not in st.session_state:
48
  if "selected_voice" not in st.session_state:
49
  st.session_state["selected_voice"] = "Jenny (US, Female)"
50
 
51
- # --- CSS for logo, chat, and input bar at top ---
52
  st.markdown("""
53
  <style>
54
  .block-container {padding-top: 1rem;}
@@ -59,36 +59,58 @@ st.markdown("""
59
  display: block;
60
  }
61
  .lor-brand-bar {
62
- width: 100vw; text-align: center; background: none;
63
- margin-bottom: 0.5em; margin-top: 0.1em;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  }
65
  .stChatMessage { max-width: 85%; border-radius: 12px; padding: 8px; margin-bottom: 10px; }
66
  .stChatMessage[data-testid="stChatMessage-user"] { background: #f0f0f0; color: #000000; }
67
  .stChatMessage[data-testid="stChatMessage-assistant"] { background: #e3f2fd; color: #000000; }
68
  .chat-history-wrapper {
69
- margin-top: 0.5em; padding-bottom: 2em; min-height: 60vh;
 
 
70
  }
71
- .input-top-bar {
72
- position: sticky; top: 0; z-index: 20;
73
- background: #191b22; padding: 0.5em 0 0.25em 0;
74
- display: flex; align-items: center; gap: 0.4em;
75
- border-bottom: 1px solid #22232c;
 
 
 
76
  }
77
- .input-top-bar .element-container { flex: 1 1 auto; }
78
- .input-top-bar input { font-size: 1.12em !important; }
79
- .clear-chat-btn { background: none; border: none; font-size: 1.4em; color: #666; cursor: pointer; }
80
  </style>
81
  """, unsafe_allow_html=True)
82
 
83
- # --- Top Branding, Mini Logo ---
84
  st.markdown("""
85
  <div class="lor-brand-bar">
86
  <img src="https://www.gameonmobile.co.za/images/GameON!-Mobile-Training-Button-logo-Medium.png" class="logo-mini" />
87
  <div style="font-size: 13px; color: #888;">Powered by GameOn</div>
 
88
  </div>
89
  """, unsafe_allow_html=True)
90
 
91
- # --- Sidebar: audio/voice controls
92
  with st.sidebar:
93
  st.markdown("### Voice Settings & Controls")
94
  selected_voice = st.selectbox(
@@ -140,7 +162,8 @@ def clear_chat_history():
140
 
141
  def display_chat_history():
142
  messages = db.collection("users").document(user_id).collection("messages").order_by("timestamp").stream()
143
- assistant_icon_html = "<img src='https://github.com/AndrewLORTech/gameonwebaiassistant/blob/main/GameGuy.jpg' width='22' style='vertical-align:middle; border-radius:50%;'/>"
 
144
  chat_msgs = []
145
  for msg in list(messages)[::-1]:
146
  data = msg.to_dict()
@@ -155,7 +178,7 @@ def display_chat_history():
155
  st.markdown('<div class="chat-history-wrapper">' + "".join(chat_msgs) + '</div>', unsafe_allow_html=True)
156
  st.markdown('<div id="chat-top-anchor"></div>', unsafe_allow_html=True)
157
 
158
- # --- TTS sanitize ---
159
  def sanitize_for_tts(text):
160
  text = html.unescape(text)
161
  text = re.sub(r'[^\x00-\x7F]+', ' ', text)
@@ -189,33 +212,30 @@ def synthesize_voice(text, voice_key, user_id):
189
  st.session_state["last_voice"] = voice
190
  return out_path
191
 
192
- # --- INPUT AT THE TOP ---
 
 
 
193
  with st.container():
194
- st.markdown('<div class="input-top-bar">', unsafe_allow_html=True)
195
- col1, col2 = st.columns([10, 1])
196
- user_input = col1.chat_input("Type your message here...")
197
- if col2.button("🗑️", help="Clear Chat", key="clear-chat-top"):
198
- clear_chat_history()
199
  st.markdown('</div>', unsafe_allow_html=True)
200
 
201
- # --- CHAT: display under input, latest on top ---
202
- display_chat_history()
203
-
204
- # --- JS: auto-scroll to top on new message ---
205
  st.markdown("""
206
  <script>
207
  window.onload = function() {
208
  var anchor = document.getElementById("chat-top-anchor");
209
  if(anchor){ anchor.scrollIntoView({ behavior: "smooth", block: "start" }); }
210
  };
211
- window.setTimeout(function(){
212
- var anchor = document.getElementById("chat-top-anchor");
213
- if(anchor){ anchor.scrollIntoView({ behavior: "smooth", block: "start" }); }
214
- }, 200);
215
  </script>
216
  """, unsafe_allow_html=True)
217
 
218
- # --- Handle user input
 
 
 
 
219
  if user_input:
220
  thread_id = get_or_create_thread_id()
221
  client.beta.threads.messages.create(thread_id=thread_id, role="user", content=user_input)
 
48
  if "selected_voice" not in st.session_state:
49
  st.session_state["selected_voice"] = "Jenny (US, Female)"
50
 
51
+ # --- CSS ---
52
  st.markdown("""
53
  <style>
54
  .block-container {padding-top: 1rem;}
 
59
  display: block;
60
  }
61
  .lor-brand-bar {
62
+ width: 100vw;
63
+ text-align: center;
64
+ background: none;
65
+ margin-bottom: 0.5em;
66
+ margin-top: 0.1em;
67
+ position: relative;
68
+ }
69
+ .clear-chat-btn-top {
70
+ position: absolute;
71
+ top: 10px;
72
+ right: 50px;
73
+ font-size: 1.4em;
74
+ color: #ccc;
75
+ background: none;
76
+ border: none;
77
+ cursor: pointer;
78
+ z-index: 1000;
79
+ transition: color 0.2s ease;
80
+ }
81
+ .clear-chat-btn-top:hover {
82
+ color: #fff;
83
  }
84
  .stChatMessage { max-width: 85%; border-radius: 12px; padding: 8px; margin-bottom: 10px; }
85
  .stChatMessage[data-testid="stChatMessage-user"] { background: #f0f0f0; color: #000000; }
86
  .stChatMessage[data-testid="stChatMessage-assistant"] { background: #e3f2fd; color: #000000; }
87
  .chat-history-wrapper {
88
+ margin-top: 0.5em;
89
+ padding-bottom: 9em;
90
+ min-height: 60vh;
91
  }
92
+ .input-bottom-bar {
93
+ position: fixed;
94
+ bottom: 3.5em;
95
+ width: 100%;
96
+ background: #191b22;
97
+ padding: 0.5em 0.6em;
98
+ border-top: 1px solid #22232c;
99
+ z-index: 999;
100
  }
 
 
 
101
  </style>
102
  """, unsafe_allow_html=True)
103
 
104
+ # --- Top Branding + clear button ---
105
  st.markdown("""
106
  <div class="lor-brand-bar">
107
  <img src="https://www.gameonmobile.co.za/images/GameON!-Mobile-Training-Button-logo-Medium.png" class="logo-mini" />
108
  <div style="font-size: 13px; color: #888;">Powered by GameOn</div>
109
+ <button class="clear-chat-btn-top" onclick="window.location.href='?clear=1'">🗑️</button>
110
  </div>
111
  """, unsafe_allow_html=True)
112
 
113
+ # --- Sidebar: voice settings ---
114
  with st.sidebar:
115
  st.markdown("### Voice Settings & Controls")
116
  selected_voice = st.selectbox(
 
162
 
163
  def display_chat_history():
164
  messages = db.collection("users").document(user_id).collection("messages").order_by("timestamp").stream()
165
+ assistant_icon_html = "<img src='https://github.com/AndrewLORTech/gameonwebaiassistant/blob/main/GameGuy.jpg?raw=true' width='22' style='vertical-align:middle; border-radius:50%;'/>"
166
+
167
  chat_msgs = []
168
  for msg in list(messages)[::-1]:
169
  data = msg.to_dict()
 
178
  st.markdown('<div class="chat-history-wrapper">' + "".join(chat_msgs) + '</div>', unsafe_allow_html=True)
179
  st.markdown('<div id="chat-top-anchor"></div>', unsafe_allow_html=True)
180
 
181
+ # --- TTS sanitization ---
182
  def sanitize_for_tts(text):
183
  text = html.unescape(text)
184
  text = re.sub(r'[^\x00-\x7F]+', ' ', text)
 
212
  st.session_state["last_voice"] = voice
213
  return out_path
214
 
215
+ # --- CHAT DISPLAY ---
216
+ display_chat_history()
217
+
218
+ # --- Bottom chat input ---
219
  with st.container():
220
+ st.markdown('<div class="input-bottom-bar">', unsafe_allow_html=True)
221
+ user_input = st.chat_input("Type your message here...")
 
 
 
222
  st.markdown('</div>', unsafe_allow_html=True)
223
 
224
+ # --- JS auto-scroll ---
 
 
 
225
  st.markdown("""
226
  <script>
227
  window.onload = function() {
228
  var anchor = document.getElementById("chat-top-anchor");
229
  if(anchor){ anchor.scrollIntoView({ behavior: "smooth", block: "start" }); }
230
  };
 
 
 
 
231
  </script>
232
  """, unsafe_allow_html=True)
233
 
234
+ # --- Handle clear button ---
235
+ if st.query_params.get("clear") == "1":
236
+ clear_chat_history()
237
+
238
+ # --- Handle user input ---
239
  if user_input:
240
  thread_id = get_or_create_thread_id()
241
  client.beta.threads.messages.create(thread_id=thread_id, role="user", content=user_input)