Simplify index keyword filter UI and unify q-based push target URLs
This commit is contained in:
parent
a52e0a8bb3
commit
7f45193a6f
2 changed files with 65 additions and 52 deletions
114
index.php
114
index.php
|
|
@ -125,40 +125,52 @@ usort($videos, function($a, $b) use ($videoCache) {
|
||||||
return $bd <=> $ad;
|
return $bd <=> $ad;
|
||||||
});
|
});
|
||||||
|
|
||||||
$filters = [
|
$rawKeyword = trim((string)($_GET['q'] ?? ''));
|
||||||
'f_title' => trim((string)($_GET['f_title'] ?? '')),
|
|
||||||
'f_date' => trim((string)($_GET['f_date'] ?? '')),
|
|
||||||
'f_location' => trim((string)($_GET['f_location'] ?? '')),
|
|
||||||
];
|
|
||||||
$titleExact = !empty($_GET['f_exact']) && (string)$_GET['f_exact'] === '1';
|
|
||||||
|
|
||||||
// Backward compatibility with old push URL format (?job=...)
|
// Backward compatibility with older filter/query formats.
|
||||||
$legacyJob = trim((string)($_GET['job'] ?? ''));
|
if ($rawKeyword === '') {
|
||||||
if ($filters['f_title'] === '' && $legacyJob !== '') {
|
$legacyTitle = trim((string)($_GET['f_title'] ?? ''));
|
||||||
$legacy = preg_replace('/^\d{8}[_-]/', '', $legacyJob);
|
$legacyDate = trim((string)($_GET['f_date'] ?? ''));
|
||||||
$filters['f_title'] = nice_title($legacy ?: $legacyJob);
|
$legacyLocation = trim((string)($_GET['f_location'] ?? ''));
|
||||||
|
$legacyJob = trim((string)($_GET['job'] ?? ''));
|
||||||
|
|
||||||
|
if ($legacyTitle !== '') $rawKeyword = $legacyTitle;
|
||||||
|
elseif ($legacyDate !== '') $rawKeyword = 'date=' . $legacyDate;
|
||||||
|
elseif ($legacyLocation !== '') $rawKeyword = 'location=' . $legacyLocation;
|
||||||
|
elseif ($legacyJob !== '') {
|
||||||
|
$legacy = preg_replace('/^\d{8}[_-]/', '', $legacyJob);
|
||||||
|
$rawKeyword = nice_title($legacy ?: $legacyJob);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$videos = array_values(array_filter($videos, function($v) use ($videoCache, $filters) {
|
$keywordType = 'general';
|
||||||
|
$keywordValue = $rawKeyword;
|
||||||
|
if ($rawKeyword !== '' && preg_match('/^\s*(date|location|place)\s*=\s*(.+)\s*$/i', $rawKeyword, $m)) {
|
||||||
|
$keywordType = lower_text((string)$m[1]);
|
||||||
|
if ($keywordType === 'place') $keywordType = 'location';
|
||||||
|
$keywordValue = trim((string)$m[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$videos = array_values(array_filter($videos, function($v) use ($videoCache, $keywordType, $keywordValue) {
|
||||||
|
if ($keywordValue === '') return true;
|
||||||
|
|
||||||
$name = basename($v);
|
$name = basename($v);
|
||||||
$m = $videoCache[$name]['metadata'] ?? video_metadata($v);
|
$m = $videoCache[$name]['metadata'] ?? video_metadata($v);
|
||||||
|
|
||||||
$title = (string)($m['title'] ?? '');
|
$title = (string)($m['title'] ?? '');
|
||||||
|
$description = (string)($m['description'] ?? '');
|
||||||
$date = (string)($m['date'] ?? '');
|
$date = (string)($m['date'] ?? '');
|
||||||
$sortDate = (string)($m['sort_date'] ?? '');
|
$sortDate = (string)($m['sort_date'] ?? '');
|
||||||
$location = (string)($m['location'] ?? '');
|
$location = (string)($m['location'] ?? '');
|
||||||
|
|
||||||
if ($filters['f_title'] !== '') {
|
if ($keywordType === 'date') {
|
||||||
if ($titleExact) {
|
return stripos($date, $keywordValue) !== false || stripos($sortDate, $keywordValue) !== false;
|
||||||
if (lower_text(trim($title)) !== lower_text(trim($filters['f_title']))) return false;
|
}
|
||||||
} else {
|
if ($keywordType === 'location') {
|
||||||
if (stripos($title, $filters['f_title']) === false) return false;
|
return stripos($location, $keywordValue) !== false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ($filters['f_date'] !== '' && stripos($date, $filters['f_date']) === false && stripos($sortDate, $filters['f_date']) === false) return false;
|
|
||||||
if ($filters['f_location'] !== '' && stripos($location, $filters['f_location']) === false) return false;
|
|
||||||
|
|
||||||
return true;
|
return stripos($title, $keywordValue) !== false || stripos($description, $keywordValue) !== false;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
$page = max(1, (int)($_GET['page'] ?? 1));
|
$page = max(1, (int)($_GET['page'] ?? 1));
|
||||||
|
|
@ -168,9 +180,8 @@ $pages = max(1, (int)ceil($total / $per));
|
||||||
$page = min($page, $pages);
|
$page = min($page, $pages);
|
||||||
$slice = array_slice($videos, ($page - 1) * $per, $per);
|
$slice = array_slice($videos, ($page - 1) * $per, $per);
|
||||||
|
|
||||||
$activeFilterCount = count(keep_non_empty($filters));
|
$activeFilterCount = ($keywordValue !== '') ? 1 : 0;
|
||||||
$baseParams = keep_non_empty($filters);
|
$baseParams = ($rawKeyword !== '') ? ['q' => $rawKeyword] : [];
|
||||||
if ($titleExact && ($filters['f_title'] ?? '') !== '') $baseParams['f_exact'] = '1';
|
|
||||||
?>
|
?>
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
|
|
@ -182,17 +193,21 @@ if ($titleExact && ($filters['f_title'] ?? '') !== '') $baseParams['f_exact'] =
|
||||||
<link rel="icon" type="image/png" href="assets/img/moto_travel.png">
|
<link rel="icon" type="image/png" href="assets/img/moto_travel.png">
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<style>
|
<style>
|
||||||
.filter-form{display:grid;grid-template-columns:1.4fr 1fr 1fr auto auto;gap:.55rem;align-items:end;margin:0 0 1rem}
|
.filter-form{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:.55rem;align-items:center;margin:0 0 .4rem}
|
||||||
.filter-form label{margin:0;font-size:.8rem;color:#A0A4AB;font-weight:600}
|
.filter-input-wrap{position:relative;min-width:0}
|
||||||
.filter-form input{margin-top:.2rem}
|
.filter-input-wrap input{margin:0;padding-right:2.15rem}
|
||||||
.filter-clear-x{display:inline-flex;align-items:center;justify-content:center;width:2.1rem;height:2.1rem;border-radius:50%;background:#C46A3A;border:1px solid #C46A3A;color:#111315;text-decoration:none;font-size:0;position:relative;box-shadow:0 1px 4px #0008}
|
.filter-clear-inside{position:absolute;right:.45rem;top:50%;transform:translateY(-50%);display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border-radius:50%;background:#C46A3A;color:#111315;text-decoration:none;font-size:1rem;line-height:1;font-weight:700;box-shadow:0 1px 4px #0007;transition:opacity .15s ease,transform .15s ease}
|
||||||
.filter-clear-x::before{content:'✕';font-size:1rem;line-height:1;font-weight:700;transform:translateY(-.02em)}
|
.filter-clear-inside:hover{background:#d97b48;color:#111315;transform:translateY(-50%) scale(1.05)}
|
||||||
.filter-clear-x:hover{background:#d97b48;border-color:#d97b48;color:#111315}
|
.filter-clear-inside.is-empty{opacity:.38;pointer-events:none}
|
||||||
.filter-clear-x:focus-visible{outline:2px solid #3BA7A0;outline-offset:2px}
|
.filter-submit{display:inline-grid;place-items:center;width:2.35rem;height:2.35rem;padding:0;border-radius:.5rem;background:#C46A3A;color:#111315}
|
||||||
|
.filter-submit .icon{font-size:1.02rem;line-height:1;transform:translateY(.01em)}
|
||||||
|
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
|
||||||
.filter-summary{color:#A0A4AB;font-size:.9rem;margin:0 0 .8rem}
|
.filter-summary{color:#A0A4AB;font-size:.9rem;margin:0 0 .8rem}
|
||||||
|
.video-row-head{grid-column:1 / -1;margin:0 0 .15rem}
|
||||||
|
.video-row-title{font-size:1.35rem;line-height:1.2;margin:.1rem 0 .45rem;color:#F3F4F6}
|
||||||
|
.video-row-head .meta{margin:0 0 .45rem}
|
||||||
.meta a{color:inherit;text-decoration:none}
|
.meta a{color:inherit;text-decoration:none}
|
||||||
.meta a:hover{text-decoration:underline}
|
.meta a:hover{text-decoration:underline}
|
||||||
@media (max-width:900px){.filter-form{grid-template-columns:1fr}}
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -200,17 +215,14 @@ if ($titleExact && ($filters['f_title'] ?? '') !== '') $baseParams['f_exact'] =
|
||||||
<main>
|
<main>
|
||||||
<section id="videos">
|
<section id="videos">
|
||||||
<form method="get" class="filter-form">
|
<form method="get" class="filter-form">
|
||||||
<label>Title
|
<div class="filter-input-wrap">
|
||||||
<input name="f_title" value="<?=h($filters['f_title'])?>" placeholder="Filter by title">
|
<input name="q" value="<?=h($rawKeyword)?>" placeholder="Search title/description or use date=... / location=..." aria-label="Search articles">
|
||||||
</label>
|
<a class="filter-clear-inside <?=$rawKeyword === '' ? 'is-empty' : ''?>" href="index.php" aria-label="Clear filter" title="Clear filter">×</a>
|
||||||
<label>Date
|
</div>
|
||||||
<input name="f_date" value="<?=h($filters['f_date'])?>" placeholder="YYYY-MM-DD or month/year">
|
<button type="submit" class="filter-submit" aria-label="Filter">
|
||||||
</label>
|
<span class="icon" aria-hidden="true">🔍</span>
|
||||||
<label>Location
|
<span class="sr-only">Filter</span>
|
||||||
<input name="f_location" value="<?=h($filters['f_location'])?>" placeholder="Filter by location">
|
</button>
|
||||||
</label>
|
|
||||||
<a class="filter-clear-x" href="index.php" title="Clear filters" aria-label="Clear filters">×</a>
|
|
||||||
<button type="submit">Filter</button>
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<p class="filter-summary">
|
<p class="filter-summary">
|
||||||
|
|
@ -225,11 +237,18 @@ if ($titleExact && ($filters['f_title'] ?? '') !== '') $baseParams['f_exact'] =
|
||||||
$name = basename($v);
|
$name = basename($v);
|
||||||
$url = $config['public_videos'].'/'.rawurlencode($name);
|
$url = $config['public_videos'].'/'.rawurlencode($name);
|
||||||
$m = $videoCache[$name]['metadata'] ?? video_metadata($v);
|
$m = $videoCache[$name]['metadata'] ?? video_metadata($v);
|
||||||
$dateFilterUrl = query_url(array_merge($baseParams, ['f_date' => (string)($m['date'] ?? '')]));
|
$dateFilterUrl = query_url(['q' => 'date=' . (string)($m['date'] ?? '')]);
|
||||||
$locFilterUrl = query_url(array_merge($baseParams, ['f_location' => (string)($m['location'] ?? '')]));
|
$locFilterUrl = query_url(['q' => 'location=' . (string)($m['location'] ?? '')]);
|
||||||
?>
|
?>
|
||||||
<article class="video-row">
|
<article class="video-row">
|
||||||
<time class="created-at" datetime="<?=h(date('c', filemtime($v)))?>"><?=h(date('d.m.Y H:i', filemtime($v)))?></time>
|
<time class="created-at" datetime="<?=h(date('c', filemtime($v)))?>"><?=h(date('d.m.Y H:i', filemtime($v)))?></time>
|
||||||
|
<div class="video-row-head">
|
||||||
|
<h2 class="video-row-title"><?=h($m['title'])?></h2>
|
||||||
|
<p class="meta">
|
||||||
|
<span><a href="<?=h($dateFilterUrl)?>"><?=h($m['date'])?></a></span>
|
||||||
|
<?php if(!empty($m['location'])): ?><span><a href="<?=h($locFilterUrl)?>"><?=h($m['location'])?></a></span><?php endif; ?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
<div class="video-wrapper">
|
<div class="video-wrapper">
|
||||||
<video controls controlsList="nodownload" oncontextmenu="return false" preload="metadata" src="<?=h($url)?>"></video>
|
<video controls controlsList="nodownload" oncontextmenu="return false" preload="metadata" src="<?=h($url)?>"></video>
|
||||||
<?php
|
<?php
|
||||||
|
|
@ -240,11 +259,6 @@ if ($titleExact && ($filters['f_title'] ?? '') !== '') $baseParams['f_exact'] =
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="video-info">
|
<div class="video-info">
|
||||||
<h2><?=h($m['title'])?></h2>
|
|
||||||
<p class="meta">
|
|
||||||
<span><a href="<?=h($dateFilterUrl)?>"><?=h($m['date'])?></a></span>
|
|
||||||
<?php if(!empty($m['location'])): ?><span><a href="<?=h($locFilterUrl)?>"><?=h($m['location'])?></a></span><?php endif; ?>
|
|
||||||
</p>
|
|
||||||
<?php if(!empty($m['description'])): ?><p class="description"><?=nl2br(h($m['description']), false)?></p><?php endif; ?>
|
<?php if(!empty($m['description'])): ?><p class="description"><?=nl2br(h($m['description']), false)?></p><?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|
|
||||||
|
|
@ -151,8 +151,7 @@ function try_send_show_notification($job, $jobdir, $mvlog_root = null, $logfile
|
||||||
if ($articleTitle === '') $articleTitle = mvlog_nice_title((string)$job);
|
if ($articleTitle === '') $articleTitle = mvlog_nice_title((string)$job);
|
||||||
|
|
||||||
$filterUrl = 'https://bubulescu.org/mvlog/?' . http_build_query([
|
$filterUrl = 'https://bubulescu.org/mvlog/?' . http_build_query([
|
||||||
'f_title' => $articleTitle,
|
'q' => $articleTitle,
|
||||||
'f_exact' => '1',
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$payload = json_encode([
|
$payload = json_encode([
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue