sara.mesquita commited on
Commit
be251cf
Β·
1 Parent(s): 6241834

UI ADJUSTS

Browse files
Files changed (1) hide show
  1. app.py +108 -81
app.py CHANGED
@@ -42,10 +42,15 @@ C_CARD = "#F4F4F0"
42
  C_RED = "#E53935"
43
  C_ORANGE = "#FB8C00"
44
 
 
 
 
 
 
 
45
  # ─── CSS ─────────────────────────────────────────────────────────────────────
46
  CSS = f"""
47
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
48
- @import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css');
49
 
50
  * {{ box-sizing: border-box; font-family: 'Inter', sans-serif; }}
51
 
@@ -54,7 +59,7 @@ CSS = f"""
54
  max-width: 480px !important;
55
  margin: 0 auto !important;
56
  padding: 0 !important;
57
- background: #f8f9fa !important; /* Fundo levemente cinza para destacar os cards */
58
  min-height: 100dvh;
59
  }}
60
 
@@ -179,7 +184,7 @@ footer {{ display: none !important; }}
179
  border: 1px solid #eaeaea !important;
180
  display: flex;
181
  flex-direction: column;
182
- gap: 20px; /* EspaΓ§amento entre os passos */
183
  }}
184
  .reg-label {{
185
  font-size: 14px;
@@ -256,23 +261,32 @@ footer {{ display: none !important; }}
256
  }}
257
  #status-card.ok {{ background: #e8f5e9; color: #2e7d32; border-left: 4px solid {C_GREEN}; padding: 14px 16px; }}
258
  #status-card.err {{ background: #ffebee; color: #b71c1c; border-left: 4px solid {C_RED}; padding: 14px 16px; }}
259
- /* GPS box */
260
- #gps-box {{
261
- display: flex;
262
- align-items: center;
263
- gap: 10px;
264
- background: {C_GREEN_L};
265
- border-radius: 10px;
266
- padding: 12px 14px;
267
- font-size: 13px;
268
- color: #2e7d32;
269
- font-weight: 500;
270
- border: 1px solid #c8e6c9;
271
- transition: all 0.3s ease;
272
- }}
273
- #gps-box i.fa-pulse {{
274
- animation: fa-pulse 1s infinite;
275
- }}
 
 
 
 
 
 
 
 
 
276
 
277
  /* Animals list */
278
  #animals-tab {{ padding: 0 0 80px; background: white; }}
@@ -321,78 +335,91 @@ footer {{ display: none !important; }}
321
  # ─── GPS JavaScript ───────────────────────────────────────────────────────────
322
  GPS_HTML = """
323
  <div id="gps-box">
324
- <span id="gps-icon" style="font-size:18px"><i class="fa-solid fa-location-crosshairs fa-pulse"></i></span>
325
- <span id="gps-text">Requesting location permission...</span>
 
 
 
326
  </div>
327
  <script>
328
  (function() {
329
- console.log('GPS script loaded');
330
-
331
  var icon = document.getElementById('gps-icon');
332
  var text = document.getElementById('gps-text');
 
333
 
334
  function setCoords(coords) {
335
- console.log('Setting coords:', coords);
336
- var tb = document.querySelector('#gps-coords textarea');
337
- if (tb) {
338
- var nativeSet = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value').set;
339
- nativeSet.call(tb, JSON.stringify(coords));
340
- tb.dispatchEvent(new Event('input', { bubbles: true }));
341
- console.log('Coords set successfully');
342
- } else {
343
- console.error('GPS coords textarea not found');
344
- }
345
  }
346
 
347
- // Verificar se geolocation estΓ‘ disponΓ­vel
348
- if (!navigator.geolocation) {
349
- console.error('Geolocation not supported');
350
- icon.innerHTML = '<i class="fa-solid fa-triangle-exclamation"></i>';
351
- text.textContent = 'GPS nΓ£o disponΓ­vel neste navegador.';
352
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
  }
354
 
355
- console.log('Requesting geolocation...');
 
356
 
357
- // OpΓ§Γ΅es mais agressivas para forΓ§ar o pedido de permissΓ£o
358
- var options = {
359
- enableHighAccuracy: true,
360
- timeout: 15000,
361
- maximumAge: 0 // ForΓ§a nova requisiΓ§Γ£o sempre
362
- };
363
-
364
- navigator.geolocation.getCurrentPosition(
365
- function(pos) {
366
- console.log('Position obtained:', pos);
367
- var lat = parseFloat(pos.coords.latitude.toFixed(5));
368
- var lng = parseFloat(pos.coords.longitude.toFixed(5));
369
- icon.innerHTML = '<i class="fa-solid fa-location-dot"></i>';
370
- text.innerHTML = '<i class="fa-solid fa-check"></i> LocalizaΓ§Γ£o: ' + lat + ', ' + lng;
371
- setCoords({ lat: lat, lng: lng });
372
- },
373
- function(err) {
374
- console.error('Geolocation error:', err.code, err.message);
375
- icon.innerHTML = '<i class="fa-solid fa-triangle-exclamation"></i>';
376
-
377
- // Mensagens mais especΓ­ficas para cada tipo de erro
378
- if (err.code === 1) {
379
- // PERMISSION_DENIED
380
- text.innerHTML = '<i class="fa-solid fa-xmark"></i> PermissΓ£o negada. Por favor, habilite a localizaΓ§Γ£o nas configuraΓ§Γ΅es do navegador.';
381
- } else if (err.code === 2) {
382
- // POSITION_UNAVAILABLE
383
- text.innerHTML = '<i class="fa-solid fa-xmark"></i> LocalizaΓ§Γ£o indisponΓ­vel. Verifique se o GPS estΓ‘ ativo.';
384
- } else if (err.code === 3) {
385
- // TIMEOUT
386
- text.innerHTML = '<i class="fa-solid fa-clock"></i> Tempo esgotado ao buscar localizaΓ§Γ£o. Tente novamente.';
387
- } else {
388
- text.innerHTML = '<i class="fa-solid fa-xmark"></i> Erro ao obter localizaΓ§Γ£o: ' + err.message;
389
- }
390
-
391
- // Registra mesmo sem GPS (com coordenadas vazias)
392
- setCoords({});
393
- },
394
- options
395
- );
396
  })();
397
  </script>
398
  """
@@ -581,7 +608,7 @@ def get_stats_html():
581
 
582
 
583
  # ─── Gradio app ───────────────────────────────────────────────────────────────
584
- with gr.Blocks(css=CSS, theme=gr.themes.Base(), title="Spotted Animal") as demo:
585
 
586
  # Top bar
587
  gr.HTML(
 
42
  C_RED = "#E53935"
43
  C_ORANGE = "#FB8C00"
44
 
45
+ # ─── Head HTML para carregar Γ­cones ──────────────────────────────────────────
46
+ # Esta Γ© a forma correta de injetar bibliotecas externas no Gradio
47
+ HEAD_HTML = """
48
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" crossorigin="anonymous">
49
+ """
50
+
51
  # ─── CSS ─────────────────────────────────────────────────────────────────────
52
  CSS = f"""
53
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
 
54
 
55
  * {{ box-sizing: border-box; font-family: 'Inter', sans-serif; }}
56
 
 
59
  max-width: 480px !important;
60
  margin: 0 auto !important;
61
  padding: 0 !important;
62
+ background: #f8f9fa !important;
63
  min-height: 100dvh;
64
  }}
65
 
 
184
  border: 1px solid #eaeaea !important;
185
  display: flex;
186
  flex-direction: column;
187
+ gap: 20px;
188
  }}
189
  .reg-label {{
190
  font-size: 14px;
 
261
  }}
262
  #status-card.ok {{ background: #e8f5e9; color: #2e7d32; border-left: 4px solid {C_GREEN}; padding: 14px 16px; }}
263
  #status-card.err {{ background: #ffebee; color: #b71c1c; border-left: 4px solid {C_RED}; padding: 14px 16px; }}
264
+
265
+ /* GPS box */
266
+ #gps-box {{
267
+ display: flex;
268
+ align-items: center;
269
+ gap: 10px;
270
+ background: {C_GREEN_L};
271
+ border-radius: 10px;
272
+ padding: 12px 14px;
273
+ font-size: 13px;
274
+ color: #2e7d32;
275
+ font-weight: 500;
276
+ border: 1px solid #c8e6c9;
277
+ transition: all 0.3s ease;
278
+ }}
279
+ #gps-btn {{
280
+ transition: all 0.2s ease;
281
+ }}
282
+ #gps-btn:hover:not(:disabled) {{
283
+ transform: scale(1.05);
284
+ box-shadow: 0 2px 8px rgba(56, 140, 89, 0.4);
285
+ }}
286
+ #gps-btn:disabled {{
287
+ opacity: 0.7;
288
+ cursor: not-allowed;
289
+ }}
290
 
291
  /* Animals list */
292
  #animals-tab {{ padding: 0 0 80px; background: white; }}
 
335
  # ─── GPS JavaScript ───────────────────────────────────────────────────────────
336
  GPS_HTML = """
337
  <div id="gps-box">
338
+ <span id="gps-icon" style="font-size:18px"><i class="fa-solid fa-location-crosshairs"></i></span>
339
+ <span id="gps-text">Click the button to detect location</span>
340
+ <button id="gps-btn" style="margin-left:auto;background:#388C59;color:white;border:none;padding:6px 12px;border-radius:6px;font-size:12px;font-weight:600;cursor:pointer;">
341
+ <i class="fa-solid fa-location-dot"></i> Get Location
342
+ </button>
343
  </div>
344
  <script>
345
  (function() {
 
 
346
  var icon = document.getElementById('gps-icon');
347
  var text = document.getElementById('gps-text');
348
+ var btn = document.getElementById('gps-btn');
349
 
350
  function setCoords(coords) {
351
+ // Aguarda o Gradio renderizar o textarea
352
+ setTimeout(function() {
353
+ var tb = document.querySelector('#gps-coords textarea');
354
+ if (tb) {
355
+ var nativeSet = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value').set;
356
+ nativeSet.call(tb, JSON.stringify(coords));
357
+ tb.dispatchEvent(new Event('input', { bubbles: true }));
358
+ }
359
+ }, 100);
 
360
  }
361
 
362
+ function requestLocation() {
363
+ if (!navigator.geolocation) {
364
+ icon.innerHTML = '<i class="fa-solid fa-triangle-exclamation"></i>';
365
+ text.textContent = 'GPS not available in this browser';
366
+ btn.style.display = 'none';
367
+ return;
368
+ }
369
+
370
+ btn.disabled = true;
371
+ btn.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> Detecting...';
372
+ icon.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i>';
373
+ text.textContent = 'Waiting for GPS...';
374
+
375
+ navigator.geolocation.getCurrentPosition(
376
+ function(pos) {
377
+ var lat = parseFloat(pos.coords.latitude.toFixed(5));
378
+ var lng = parseFloat(pos.coords.longitude.toFixed(5));
379
+
380
+ icon.innerHTML = '<i class="fa-solid fa-check"></i>';
381
+ text.innerHTML = '<strong>Location detected:</strong> ' + lat + ', ' + lng;
382
+ btn.innerHTML = '<i class="fa-solid fa-rotate"></i> Update';
383
+ btn.disabled = false;
384
+ btn.style.background = '#2d7a4a';
385
+
386
+ setCoords({ lat: lat, lng: lng });
387
+ },
388
+ function(err) {
389
+ icon.innerHTML = '<i class="fa-solid fa-triangle-exclamation"></i>';
390
+ btn.innerHTML = '<i class="fa-solid fa-location-dot"></i> Try Again';
391
+ btn.disabled = false;
392
+ btn.style.background = '#E53935';
393
+
394
+ if (err.code === 1) {
395
+ text.innerHTML = '<strong>Permission denied.</strong> Enable location in browser settings.';
396
+ } else if (err.code === 2) {
397
+ text.innerHTML = '<strong>Location unavailable.</strong> Check if GPS is enabled.';
398
+ } else if (err.code === 3) {
399
+ text.innerHTML = '<strong>Timeout.</strong> GPS took too long to respond.';
400
+ } else {
401
+ text.textContent = 'Error: ' + err.message;
402
+ }
403
+
404
+ setCoords({});
405
+ },
406
+ {
407
+ enableHighAccuracy: true,
408
+ timeout: 15000,
409
+ maximumAge: 0
410
+ }
411
+ );
412
  }
413
 
414
+ // Evento de clique no botΓ£o
415
+ btn.addEventListener('click', requestLocation);
416
 
417
+ // Tenta automaticamente apΓ³s 500ms (apΓ³s Gradio carregar)
418
+ setTimeout(function() {
419
+ if (navigator.geolocation) {
420
+ requestLocation();
421
+ }
422
+ }, 500);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
423
  })();
424
  </script>
425
  """
 
608
 
609
 
610
  # ─── Gradio app ───────────────────────────────────────────────────────────────
611
+ with gr.Blocks(css=CSS, head=HEAD_HTML, theme=gr.themes.Base(), title="Spotted Animal") as demo:
612
 
613
  # Top bar
614
  gr.HTML(