online indicators
This commit is contained in:
@@ -13,8 +13,33 @@ dashboard = Blueprint('dashboard', __name__)
|
|||||||
@dashboard.route('/')
|
@dashboard.route('/')
|
||||||
def index():
|
def index():
|
||||||
conn = get_db()
|
conn = get_db()
|
||||||
players = conn.execute('SELECT DISTINCT player, player_id FROM town_state WHERE player IS NOT NULL ORDER BY player ASC').fetchall()
|
rows = conn.execute('''
|
||||||
|
SELECT player, player_id, MAX(updated_at) as last_seen
|
||||||
|
FROM town_state
|
||||||
|
WHERE player IS NOT NULL
|
||||||
|
GROUP BY player, player_id
|
||||||
|
ORDER BY player ASC
|
||||||
|
''').fetchall()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
players = []
|
||||||
|
now = datetime.utcnow()
|
||||||
|
for r in rows:
|
||||||
|
is_online = False
|
||||||
|
if r['last_seen']:
|
||||||
|
try:
|
||||||
|
last_seen = datetime.fromisoformat(r['last_seen'])
|
||||||
|
if (now - last_seen).total_seconds() <= 150:
|
||||||
|
is_online = True
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
players.append({
|
||||||
|
'player': r['player'],
|
||||||
|
'player_id': r['player_id'],
|
||||||
|
'is_online': is_online
|
||||||
|
})
|
||||||
|
|
||||||
return render_template('index.html', players=players)
|
return render_template('index.html', players=players)
|
||||||
|
|
||||||
@dashboard.route('/player/<player_id>')
|
@dashboard.route('/player/<player_id>')
|
||||||
|
|||||||
@@ -67,7 +67,22 @@
|
|||||||
|
|
||||||
{% for p in players %}
|
{% for p in players %}
|
||||||
<a href="/player/{{ p.player_id }}" class="player-card">
|
<a href="/player/{{ p.player_id }}" class="player-card">
|
||||||
|
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||||
|
<div>
|
||||||
<strong>{{ p.player }}</strong> <span>(ID: {{ p.player_id }})</span>
|
<strong>{{ p.player }}</strong> <span>(ID: {{ p.player_id }})</span>
|
||||||
|
</div>
|
||||||
|
{% if p.is_online %}
|
||||||
|
<span style="display: flex; align-items: center; gap: 6px; background: rgba(50, 150, 50, 0.2); padding: 5px 12px; border-radius: 20px; font-size: 0.8rem; color: #7bcc7b; font-weight: bold; border: 1px solid rgba(123, 204, 123, 0.3);">
|
||||||
|
<span style="display: inline-block; width: 8px; height: 8px; background: #7bcc7b; border-radius: 50%; box-shadow: 0 0 6px #7bcc7b;"></span>
|
||||||
|
Online
|
||||||
|
</span>
|
||||||
|
{% else %}
|
||||||
|
<span style="display: flex; align-items: center; gap: 6px; background: rgba(150, 50, 50, 0.2); padding: 5px 12px; border-radius: 20px; font-size: 0.8rem; color: #cc7b7b; font-weight: bold; border: 1px solid rgba(204, 123, 123, 0.3);">
|
||||||
|
<span style="display: inline-block; width: 8px; height: 8px; background: #cc7b7b; border-radius: 50%;"></span>
|
||||||
|
Offline
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user