IAMTFRMZA commited on
Commit
0b0487b
·
verified ·
1 Parent(s): 1291105

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +82 -51
app.py CHANGED
@@ -46,39 +46,64 @@ if "last_audio_path" not in st.session_state:
46
  if "selected_voice" not in st.session_state:
47
  st.session_state["selected_voice"] = "Jenny (US, Female)"
48
 
49
- # --- CSS for logo, chat, and input bar at top ---
50
  st.markdown("""
51
- <style>
52
- .block-container {padding-top: 1rem;}
53
- header {visibility: hidden;}
54
- .logo-mini {
55
- width: 75px !important;
56
- margin: 0 auto 0.25em auto;
57
- display: block;
58
- }
59
- .lor-brand-bar {
60
- width: 100vw; text-align: center; background: none;
61
- margin-bottom: 0.5em; margin-top: 0.1em;
62
- }
63
- .stChatMessage { max-width: 85%; border-radius: 12px; padding: 8px; margin-bottom: 10px; }
64
- .stChatMessage[data-testid="stChatMessage-user"] { background: #f0f0f0; color: #000000; }
65
- .stChatMessage[data-testid="stChatMessage-assistant"] { background: #e3f2fd; color: #000000; }
66
- .chat-history-wrapper {
67
- margin-top: 0.5em; padding-bottom: 2em; min-height: 60vh;
68
- }
69
- .input-top-bar {
70
- position: sticky; top: 0; z-index: 20;
71
- background: #191b22; padding: 0.5em 0 0.25em 0;
72
- display: flex; align-items: center; gap: 0.4em;
73
- border-bottom: 1px solid #22232c;
74
- }
75
- .input-top-bar .element-container { flex: 1 1 auto; }
76
- .input-top-bar input { font-size: 1.12em !important; }
77
- .clear-chat-btn { background: none; border: none; font-size: 1.4em; color: #666; cursor: pointer; }
78
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  """, unsafe_allow_html=True)
80
 
81
- # --- Top Branding, Mini Logo ---
82
  st.markdown("""
83
  <div class="lor-brand-bar">
84
  <img src="https://lortechnologies.com/wp-content/uploads/2023/03/LOR-Online-Logo.svg" class="logo-mini" />
@@ -86,7 +111,7 @@ st.markdown("""
86
  </div>
87
  """, unsafe_allow_html=True)
88
 
89
- # --- Sidebar: audio/voice controls
90
  with st.sidebar:
91
  st.markdown("### Voice Settings & Controls")
92
  selected_voice = st.selectbox(
@@ -110,7 +135,7 @@ with st.sidebar:
110
  st.session_state["mute_voice"] = False
111
  st.rerun()
112
 
113
- # --- Firestore helpers ---
114
  def get_or_create_thread_id():
115
  doc_ref = db.collection("users").document(user_id)
116
  doc = doc_ref.get()
@@ -140,7 +165,7 @@ def display_chat_history():
140
  messages = db.collection("users").document(user_id).collection("messages").order_by("timestamp").stream()
141
  assistant_icon_html = "<img src='https://raw.githubusercontent.com/AndrewLORTech/lortechwebsite/main/lorain.jpg' width='22' style='vertical-align:middle; border-radius:50%;'/>"
142
  chat_msgs = []
143
- for msg in list(messages)[::-1]: # Most recent first!
144
  data = msg.to_dict()
145
  if data["role"] == "user":
146
  chat_msgs.append(
@@ -153,7 +178,7 @@ def display_chat_history():
153
  st.markdown('<div class="chat-history-wrapper">' + "".join(chat_msgs) + '</div>', unsafe_allow_html=True)
154
  st.markdown('<div id="chat-top-anchor"></div>', unsafe_allow_html=True)
155
 
156
- # --- Edge TTS synth ---
157
  async def edge_tts_synthesize(text, voice, user_id):
158
  out_path = f"output_{user_id}.mp3"
159
  communicate = edge_tts.Communicate(text, voice)
@@ -171,34 +196,40 @@ def synthesize_voice(text, voice_key, user_id):
171
  st.session_state["last_voice"] = voice
172
  return out_path
173
 
174
- # --- INPUT AT THE TOP ---
175
- with st.container():
176
- st.markdown('<div class="input-top-bar">', unsafe_allow_html=True)
177
- col1, col2 = st.columns([10, 1])
178
- user_input = col1.chat_input("Type your message here...")
179
- if col2.button("🗑️", help="Clear Chat", key="clear-chat-top"):
180
- clear_chat_history()
181
- st.markdown('</div>', unsafe_allow_html=True)
182
-
183
- # --- CHAT: display under input, latest on top ---
184
  display_chat_history()
185
 
186
- # --- JS: auto-scroll to top on new message ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  st.markdown("""
188
  <script>
189
  window.onload = function() {
190
  var anchor = document.getElementById("chat-top-anchor");
191
  if(anchor){ anchor.scrollIntoView({ behavior: "smooth", block: "start" }); }
192
  };
193
- window.setTimeout(function(){
194
- var anchor = document.getElementById("chat-top-anchor");
195
- if(anchor){ anchor.scrollIntoView({ behavior: "smooth", block: "start" }); }
196
- }, 200);
197
  </script>
198
  """, unsafe_allow_html=True)
199
 
 
 
 
 
 
 
200
  if user_input:
201
- # --- OpenAI Assistant Response ---
202
  thread_id = get_or_create_thread_id()
203
  client.beta.threads.messages.create(thread_id=thread_id, role="user", content=user_input)
204
  save_message("user", user_input)
@@ -221,4 +252,4 @@ if user_input:
221
  st.session_state["last_audio_path"] = audio_path
222
 
223
  time.sleep(0.2)
224
- st.rerun()
 
46
  if "selected_voice" not in st.session_state:
47
  st.session_state["selected_voice"] = "Jenny (US, Female)"
48
 
49
+ # --- CSS
50
  st.markdown("""
51
+ <style>
52
+ .block-container {padding-top: 1rem;}
53
+ header {visibility: hidden;}
54
+ .logo-mini {
55
+ width: 75px !important;
56
+ margin: 0 auto 0.25em auto;
57
+ display: block;
58
+ }
59
+ .lor-brand-bar {
60
+ width: 100vw; text-align: center; background: none;
61
+ margin-bottom: 0.5em; margin-top: 0.1em;
62
+ }
63
+ .stChatMessage { max-width: 85%; border-radius: 12px; padding: 8px; margin-bottom: 10px; }
64
+ .stChatMessage[data-testid="stChatMessage-user"] { background: #f0f0f0; color: #000000; }
65
+ .stChatMessage[data-testid="stChatMessage-assistant"] { background: #e3f2fd; color: #000000; }
66
+
67
+ .chat-history-wrapper {
68
+ margin-top: 0.5em;
69
+ padding-bottom: 7em;
70
+ min-height: 60vh;
71
+ }
72
+
73
+ .input-bottom-bar {
74
+ position: fixed;
75
+ bottom: 0;
76
+ width: 100%;
77
+ background: #191b22;
78
+ padding: 0.5em 0.6em;
79
+ display: flex;
80
+ align-items: center;
81
+ gap: 0.5em;
82
+ border-top: 1px solid #22232c;
83
+ z-index: 999;
84
+ }
85
+
86
+ .input-bottom-bar input {
87
+ width: 100%;
88
+ font-size: 1.1em;
89
+ padding: 0.5em;
90
+ border-radius: 8px;
91
+ border: 1px solid #333;
92
+ background: #222;
93
+ color: #fff;
94
+ }
95
+
96
+ #clear-chat {
97
+ background: none;
98
+ border: none;
99
+ font-size: 1.5em;
100
+ color: #ccc;
101
+ cursor: pointer;
102
+ }
103
+ </style>
104
  """, unsafe_allow_html=True)
105
 
106
+ # --- Branding
107
  st.markdown("""
108
  <div class="lor-brand-bar">
109
  <img src="https://lortechnologies.com/wp-content/uploads/2023/03/LOR-Online-Logo.svg" class="logo-mini" />
 
111
  </div>
112
  """, unsafe_allow_html=True)
113
 
114
+ # --- Sidebar
115
  with st.sidebar:
116
  st.markdown("### Voice Settings & Controls")
117
  selected_voice = st.selectbox(
 
135
  st.session_state["mute_voice"] = False
136
  st.rerun()
137
 
138
+ # --- Firestore helpers
139
  def get_or_create_thread_id():
140
  doc_ref = db.collection("users").document(user_id)
141
  doc = doc_ref.get()
 
165
  messages = db.collection("users").document(user_id).collection("messages").order_by("timestamp").stream()
166
  assistant_icon_html = "<img src='https://raw.githubusercontent.com/AndrewLORTech/lortechwebsite/main/lorain.jpg' width='22' style='vertical-align:middle; border-radius:50%;'/>"
167
  chat_msgs = []
168
+ for msg in list(messages)[::-1]:
169
  data = msg.to_dict()
170
  if data["role"] == "user":
171
  chat_msgs.append(
 
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
+ # --- Edge TTS synth
182
  async def edge_tts_synthesize(text, voice, user_id):
183
  out_path = f"output_{user_id}.mp3"
184
  communicate = edge_tts.Communicate(text, voice)
 
196
  st.session_state["last_voice"] = voice
197
  return out_path
198
 
199
+ # --- CHAT DISPLAY
 
 
 
 
 
 
 
 
 
200
  display_chat_history()
201
 
202
+ # --- Input Form (bottom)
203
+ st.markdown("""
204
+ <div class="input-bottom-bar">
205
+ <div style="flex: 8 1 auto;">
206
+ <form action="" method="GET">
207
+ <input type="text" name="user_input" id="user-input" placeholder="Type your message here..." />
208
+ </form>
209
+ </div>
210
+ <div style="flex: 2 0 auto; text-align: center;">
211
+ <button id="clear-chat" onclick="window.location.href='?clear=1'">🗑️</button>
212
+ </div>
213
+ </div>
214
+ """, unsafe_allow_html=True)
215
+
216
+ # --- JS auto-scroll
217
  st.markdown("""
218
  <script>
219
  window.onload = function() {
220
  var anchor = document.getElementById("chat-top-anchor");
221
  if(anchor){ anchor.scrollIntoView({ behavior: "smooth", block: "start" }); }
222
  };
 
 
 
 
223
  </script>
224
  """, unsafe_allow_html=True)
225
 
226
+ # --- Handle clear
227
+ if st.query_params.get("clear") == "1":
228
+ clear_chat_history()
229
+
230
+ # --- Handle user input
231
+ user_input = st.query_params.get("user_input")
232
  if user_input:
 
233
  thread_id = get_or_create_thread_id()
234
  client.beta.threads.messages.create(thread_id=thread_id, role="user", content=user_input)
235
  save_message("user", user_input)
 
252
  st.session_state["last_audio_path"] = audio_path
253
 
254
  time.sleep(0.2)
255
+ st.rerun()