Spaces:
Running
Running
Harshil Patel
commited on
Commit
Β·
67a949c
1
Parent(s):
522d1b9
Update UI drop down
Browse files
main.py
CHANGED
@@ -69,7 +69,6 @@ async def logout(request: Request):
|
|
69 |
f"https://{AUTH0_DOMAIN}/v2/logout"
|
70 |
f"?client_id={AUTH0_CLIENT_ID}"
|
71 |
f"&returnTo=http://localhost:7860/post-logout"
|
72 |
-
f"&federated"
|
73 |
)
|
74 |
return RedirectResponse(auth0_logout_url)
|
75 |
|
@@ -116,49 +115,71 @@ CSS = """
|
|
116 |
border-radius: 4px;
|
117 |
background-color: #f0f0f0;
|
118 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
#profile-name {
|
120 |
-
background-color:
|
121 |
-
color:
|
122 |
font-weight: bold;
|
123 |
padding: 10px 14px;
|
124 |
border-radius: 6px;
|
125 |
cursor: pointer;
|
126 |
user-select: none;
|
127 |
-
display: inline-
|
128 |
-
|
129 |
-
|
|
|
|
|
|
|
130 |
}
|
131 |
-
|
132 |
#profile-menu {
|
133 |
-
position: absolute
|
134 |
-
|
|
|
|
|
135 |
border: 1px solid transparent;
|
136 |
border-radius: 8px;
|
137 |
-
|
138 |
-
z-index:
|
139 |
-
|
140 |
-
|
141 |
}
|
|
|
142 |
#profile-menu.hidden {
|
143 |
display: none;
|
144 |
}
|
|
|
145 |
#profile-menu button {
|
146 |
-
background-color: #f97316; /* Orange
|
147 |
border: none;
|
148 |
-
color: white;
|
149 |
font-size: 16px;
|
|
|
150 |
text-align: left;
|
151 |
width: 100%;
|
152 |
-
padding:
|
153 |
-
margin-bottom: 5px;
|
154 |
-
border-radius: 6px;
|
155 |
cursor: pointer;
|
156 |
transition: background-color 0.2s ease;
|
|
|
157 |
}
|
|
|
158 |
#profile-menu button:hover {
|
159 |
-
background-color: #ea580c; /* Darker orange on hover
|
160 |
}
|
161 |
|
|
|
|
|
|
|
|
|
162 |
|
163 |
/* Fix dropdown issues */
|
164 |
input[type="text"], select {
|
@@ -171,6 +192,37 @@ input[type="text"], select {
|
|
171 |
overflow-y: auto;
|
172 |
}
|
173 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
"""
|
175 |
|
176 |
def run_model(message, history):
|
@@ -194,10 +246,10 @@ with gr.Blocks(css=CSS, fill_width=True, fill_height=True) as demo:
|
|
194 |
with gr.Column(scale=1, min_width=250):
|
195 |
profile_html = gr.HTML(value="""
|
196 |
<div class="profile-container">
|
197 |
-
<div id="profile-name" class="
|
198 |
-
<div id="profile-menu" class="
|
199 |
-
<button onclick="window.location.href='/login'"
|
200 |
-
<button onclick="window.location.href='/logout'"
|
201 |
</div>
|
202 |
</div>
|
203 |
""")
|
@@ -227,27 +279,71 @@ with gr.Blocks(css=CSS, fill_width=True, fill_height=True) as demo:
|
|
227 |
async () => {
|
228 |
const profileBtn = document.getElementById("profile-name");
|
229 |
const profileMenu = document.getElementById("profile-menu");
|
230 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
// Toggle menu
|
232 |
-
profileBtn.onclick = () => {
|
|
|
|
|
233 |
profileMenu.classList.toggle("hidden");
|
|
|
|
|
|
|
|
|
|
|
234 |
}
|
235 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
try {
|
237 |
const res = await fetch('/api/login-status', { credentials: 'include' });
|
238 |
const data = await res.json();
|
239 |
-
|
240 |
if (!data.status.includes("Logged out")) {
|
241 |
-
|
242 |
-
|
243 |
-
|
|
|
|
|
244 |
} else {
|
245 |
-
profileBtn.
|
246 |
-
|
247 |
-
|
|
|
248 |
}
|
249 |
-
} catch {
|
250 |
-
|
|
|
|
|
251 |
}
|
252 |
}
|
253 |
""")
|
@@ -257,4 +353,4 @@ gr.mount_gradio_app(app, demo, path="/")
|
|
257 |
# 6. Entrypoint --------------------------------------------------------
|
258 |
if __name__ == "__main__":
|
259 |
import uvicorn
|
260 |
-
uvicorn.run(app, host="0.0.0.0", port=7860)
|
|
|
69 |
f"https://{AUTH0_DOMAIN}/v2/logout"
|
70 |
f"?client_id={AUTH0_CLIENT_ID}"
|
71 |
f"&returnTo=http://localhost:7860/post-logout"
|
|
|
72 |
)
|
73 |
return RedirectResponse(auth0_logout_url)
|
74 |
|
|
|
115 |
border-radius: 4px;
|
116 |
background-color: #f0f0f0;
|
117 |
}
|
118 |
+
|
119 |
+
/* Profile style improvements */
|
120 |
+
.profile-container {
|
121 |
+
position: relative;
|
122 |
+
display: inline-block;
|
123 |
+
float: right;
|
124 |
+
margin-right: 20px;
|
125 |
+
z-index: 9999; /* Ensure this is higher than any other elements */
|
126 |
+
}
|
127 |
+
|
128 |
#profile-name {
|
129 |
+
background-color: transparent; /* Transparent background */
|
130 |
+
color: #f97316; /* Orange text */
|
131 |
font-weight: bold;
|
132 |
padding: 10px 14px;
|
133 |
border-radius: 6px;
|
134 |
cursor: pointer;
|
135 |
user-select: none;
|
136 |
+
display: inline-flex;
|
137 |
+
align-items: center;
|
138 |
+
justify-content: center;
|
139 |
+
min-width: 40px;
|
140 |
+
min-height: 40px;
|
141 |
+
border: 2px solid #f97316; /* Add border */
|
142 |
}
|
143 |
+
|
144 |
#profile-menu {
|
145 |
+
position: fixed; /* Changed from absolute to fixed for better overlay */
|
146 |
+
right: auto; /* Let JS position it precisely */
|
147 |
+
top: auto; /* Let JS position it precisely */
|
148 |
+
background-color: transparent;
|
149 |
border: 1px solid transparent;
|
150 |
border-radius: 8px;
|
151 |
+
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
152 |
+
z-index: 10000; /* Very high z-index to ensure it's on top */
|
153 |
+
overflow: visible;
|
154 |
+
width: 160px;
|
155 |
}
|
156 |
+
|
157 |
#profile-menu.hidden {
|
158 |
display: none;
|
159 |
}
|
160 |
+
|
161 |
#profile-menu button {
|
162 |
+
background-color: #f97316; /* Orange background */
|
163 |
border: none;
|
164 |
+
color: white; /* White text */
|
165 |
font-size: 16px;
|
166 |
+
border-radius: 8px;
|
167 |
text-align: left;
|
168 |
width: 100%;
|
169 |
+
padding: 12px 16px;
|
|
|
|
|
170 |
cursor: pointer;
|
171 |
transition: background-color 0.2s ease;
|
172 |
+
display: block;
|
173 |
}
|
174 |
+
|
175 |
#profile-menu button:hover {
|
176 |
+
background-color: #ea580c; /* Darker orange on hover */
|
177 |
}
|
178 |
|
179 |
+
#profile-menu button .icon {
|
180 |
+
margin-right: 8px;
|
181 |
+
color: white; /* White icon color */
|
182 |
+
}
|
183 |
|
184 |
/* Fix dropdown issues */
|
185 |
input[type="text"], select {
|
|
|
192 |
overflow-y: auto;
|
193 |
}
|
194 |
|
195 |
+
/* User avatar styles */
|
196 |
+
.user-avatar {
|
197 |
+
width: 100%;
|
198 |
+
height: 100%;
|
199 |
+
display: flex;
|
200 |
+
align-items: center;
|
201 |
+
justify-content: center;
|
202 |
+
font-weight: bold;
|
203 |
+
text-transform: uppercase;
|
204 |
+
font-size: 20px; /* Larger font size */
|
205 |
+
color: #f97316; /* Orange color */
|
206 |
+
}
|
207 |
+
|
208 |
+
/* Fix for gradio interface */
|
209 |
+
.gradio-container {
|
210 |
+
overflow: visible !important;
|
211 |
+
}
|
212 |
+
|
213 |
+
/* Fix other container issues that might cause scrolling */
|
214 |
+
body, html {
|
215 |
+
overflow-x: hidden; /* Prevent horizontal scrolling */
|
216 |
+
}
|
217 |
+
|
218 |
+
#gradio-app, .gradio-container .overflow-hidden {
|
219 |
+
overflow: visible !important; /* Override any overflow hidden that might interfere */
|
220 |
+
}
|
221 |
+
|
222 |
+
/* Ensure dropdown appears above everything */
|
223 |
+
.profile-container * {
|
224 |
+
z-index: 9999;
|
225 |
+
}
|
226 |
"""
|
227 |
|
228 |
def run_model(message, history):
|
|
|
246 |
with gr.Column(scale=1, min_width=250):
|
247 |
profile_html = gr.HTML(value="""
|
248 |
<div class="profile-container">
|
249 |
+
<div id="profile-name" class="user-avatar">G</div>
|
250 |
+
<div id="profile-menu" class="hidden">
|
251 |
+
<button id="login-btn" onclick="window.location.href='/login'"><span class="icon">π</span> Login</button>
|
252 |
+
<button id="logout-btn" onclick="window.location.href='/logout'"><span class="icon">πͺ</span> Logout</button>
|
253 |
</div>
|
254 |
</div>
|
255 |
""")
|
|
|
279 |
async () => {
|
280 |
const profileBtn = document.getElementById("profile-name");
|
281 |
const profileMenu = document.getElementById("profile-menu");
|
282 |
+
const loginBtn = document.getElementById("login-btn");
|
283 |
+
const logoutBtn = document.getElementById("logout-btn");
|
284 |
+
|
285 |
+
// Position menu and handle positioning
|
286 |
+
function positionMenu() {
|
287 |
+
const btnRect = profileBtn.getBoundingClientRect();
|
288 |
+
profileMenu.style.position = "fixed";
|
289 |
+
profileMenu.style.top = (btnRect.bottom + 5) + "px";
|
290 |
+
profileMenu.style.left = (btnRect.right - profileMenu.offsetWidth) + "px"; // Align with right edge
|
291 |
+
}
|
292 |
+
|
293 |
+
// Close menu when clicking outside
|
294 |
+
document.addEventListener('click', (event) => {
|
295 |
+
if (!profileBtn.contains(event.target) && !profileMenu.contains(event.target)) {
|
296 |
+
profileMenu.classList.add("hidden");
|
297 |
+
}
|
298 |
+
});
|
299 |
+
|
300 |
// Toggle menu
|
301 |
+
profileBtn.onclick = (e) => {
|
302 |
+
e.stopPropagation();
|
303 |
+
positionMenu(); // Position before showing
|
304 |
profileMenu.classList.toggle("hidden");
|
305 |
+
|
306 |
+
// If showing menu, make sure it's positioned correctly
|
307 |
+
if (!profileMenu.classList.contains("hidden")) {
|
308 |
+
setTimeout(positionMenu, 0); // Reposition after render
|
309 |
+
}
|
310 |
}
|
311 |
+
|
312 |
+
// Handle window resize
|
313 |
+
window.addEventListener('resize', () => {
|
314 |
+
if (!profileMenu.classList.contains("hidden")) {
|
315 |
+
positionMenu();
|
316 |
+
}
|
317 |
+
});
|
318 |
+
|
319 |
+
// Get initial letter for avatar
|
320 |
+
function getInitial(name) {
|
321 |
+
if (name && name.length > 0) {
|
322 |
+
return name.charAt(0);
|
323 |
+
}
|
324 |
+
return "?";
|
325 |
+
}
|
326 |
+
|
327 |
try {
|
328 |
const res = await fetch('/api/login-status', { credentials: 'include' });
|
329 |
const data = await res.json();
|
330 |
+
|
331 |
if (!data.status.includes("Logged out")) {
|
332 |
+
const name = data.status.replace("Logged in: ", "");
|
333 |
+
profileBtn.innerHTML = `<div class="user-avatar">${getInitial(name)}</div>`;
|
334 |
+
profileBtn.title = name;
|
335 |
+
loginBtn.style.display = "none";
|
336 |
+
logoutBtn.style.display = "block";
|
337 |
} else {
|
338 |
+
profileBtn.innerHTML = `<div class="user-avatar">G</div>`;
|
339 |
+
profileBtn.title = "Guest";
|
340 |
+
loginBtn.style.display = "block";
|
341 |
+
logoutBtn.style.display = "none";
|
342 |
}
|
343 |
+
} catch (error) {
|
344 |
+
console.error("Error fetching login status:", error);
|
345 |
+
profileBtn.innerHTML = `<div class="user-avatar">?</div>`;
|
346 |
+
profileBtn.title = "Login status unknown";
|
347 |
}
|
348 |
}
|
349 |
""")
|
|
|
353 |
# 6. Entrypoint --------------------------------------------------------
|
354 |
if __name__ == "__main__":
|
355 |
import uvicorn
|
356 |
+
uvicorn.run(app, host="0.0.0.0", port=7860)
|