You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
5.4 KiB
HTML

{% extends "base.html" %}
{% from "_pagination.html" import pager %}
{% block title %}👥 Users{% endblock %}
{% block content %}
<h1>👥 Users</h1>
<div class="controls">
<form method="get" action="{{ url_for('web.users') }}">
<input type="text" name="q" placeholder="Search users..." value="{{ query or '' }}">
<input type="hidden" name="sort" value="{{ sort }}">
<input type="hidden" name="dir" value="{{ dir }}">
<input type="hidden" name="timeframe" value="{{ timeframe }}">
<input type="hidden" name="start" value="{{ start_date or '' }}">
<input type="hidden" name="end" value="{{ end_date or '' }}">
<button type="submit">Search</button>
</form>
<!-- sort links -->
{% set next_user_dir = 'asc' if sort != 'user' or dir == 'desc' else 'desc' %}
{% set next_site_dir = 'asc' if sort != 'site' or dir == 'desc' else 'desc' %}
{% set next_total_dir = 'asc' if sort != 'total_size' or dir == 'desc' else 'desc' %}
{% set next_count_dir = 'asc' if sort != 'video_count' or dir == 'desc' else 'desc' %}
<div class="controls">
<a href="{{ url_for('web.users', q=query, page=1, sort='user', dir=next_user_dir, timeframe=timeframe, start=start_date, end=end_date) }}">Sort: User{% if sort=='user' %} {{ '▲' if dir=='asc' else '▼' }}{% endif %}</a>
<a href="{{ url_for('web.users', q=query, page=1, sort='site', dir=next_site_dir, timeframe=timeframe, start=start_date, end=end_date) }}">Sort: Site{% if sort=='site' %} {{ '▲' if dir=='asc' else '▼' }}{% endif %}</a>
<a href="{{ url_for('web.users', q=query, page=1, sort='total_size', dir=next_total_dir, timeframe=timeframe, start=start_date, end=end_date) }}">Sort: Total Size{% if sort=='total_size' %} {{ '▲' if dir=='asc' else '▼' }}{% endif %}</a>
<a href="{{ url_for('web.users', q=query, page=1, sort='video_count', dir=next_count_dir, timeframe=timeframe, start=start_date, end=end_date) }}">Sort: Videos{% if sort=='video_count' %} {{ '▲' if dir=='asc' else '▼' }}{% endif %}</a>
1 month ago
</div>
<form method="get" action="{{ url_for('web.users') }}">
<label>Timeframe:</label>
<select name="timeframe" onchange="this.form.submit()">
<option value="all" {{ 'selected' if timeframe=='all' else '' }}>All time</option>
<option value="week" {{ 'selected' if timeframe=='week' else '' }}>This week</option>
<option value="month" {{ 'selected' if timeframe=='month' else '' }}>Last 30 days</option>
<option value="year" {{ 'selected' if timeframe=='year' else '' }}>Last 365 days</option>
<option value="custom"{{ 'selected' if timeframe=='custom' else '' }}>Custom…</option>
</select>
<input type="date" name="start" value="{{ start_date or '' }}" />
<input type="date" name="end" value="{{ end_date or '' }}" />
<input type="hidden" name="q" value="{{ query or '' }}">
<input type="hidden" name="sort" value="{{ sort }}">
<input type="hidden" name="dir" value="{{ dir }}">
<button type="submit">Apply</button>
</form>
</div>
<div class="grid">
{% for c in cards %}
<div class="card user-card" data-username="{{ c.user|lower }}">
<div class="thumb">
{% if c.thumb_urls and c.thumb_urls|length %}
{% for url in c.thumb_urls %}
<img src="{{ url }}" loading="lazy" decoding="async" alt="{{ c.user }}" {% if not loop.first %}style="display:none"{% endif %} onerror="this.style.display='none'; const n=this.nextElementSibling; if(n){ if(n.tagName==='IMG'){ n.style.display='block'; } else { n.style.display='flex'; } }">
{% endfor %}
{% endif %}
<span class="fallback">🎞️</span>
</div>
<div class="meta">
<h3>
<a href="{{ url_for('web.user_page', username=c.user) }}">{{ c.user }}</a>
{% if c.is_online %}
<span class="status-dot dot-online" title="Online"></span>
{% elif c.is_recording_offline %}
<span class="status-dot dot-record" title="Recording (offline)"></span>
1 month ago
{% else %}
<span class="status-dot dot-offline" title="Offline"></span>
1 month ago
{% endif %}
</h3>
<div class="row"><span class="muted">Site:</span> <a href="https://{{ c.site }}.com/{{ c.user }}" target="_blank" rel="noopener">{{ c.site }}</a></div>
<div class="row"><span class="muted">Total size:</span> {{ c.total_size_display }} GB</div>
<div class="row"><span class="muted">Videos:</span> {{ c.video_count }}</div>
1 month ago
</div>
</div>
{% endfor %}
</div>
{{ pager('web.users', page, total_pages, q=query, sort=sort, dir=dir, timeframe=timeframe, start=start_date, end=end_date) }}
{% endblock %}
{% block scripts %}
<script>
async function refreshStatus() {
try {
const resp = await fetch("/api/get_recording/"); if (!resp.ok) return;
const s = await resp.json();
const online = new Set(s.filter(x => x.is_online).map(x => (x.username||"").toLowerCase()));
const recOff = new Set(s.filter(x => !x.is_online).map(x => (x.username||"").toLowerCase()));
document.querySelectorAll('.card').forEach(card => {
const u = (card.dataset.username||"").toLowerCase();
const dot = card.querySelector('.status-dot'); if (!dot) return;
dot.classList.remove('dot-online','dot-record','dot-offline');
if (online.has(u)) dot.classList.add('dot-online');
else if (recOff.has(u)) dot.classList.add('dot-record');
else dot.classList.add('dot-offline');
});
} catch(e) {}
}
refreshStatus(); setInterval(refreshStatus, 20000);
</script>
{% endblock %}