From 6852772bc2a0453bfdeb7f362dfe259e3ac73772 Mon Sep 17 00:00:00 2001
From: CatNoir2006 <93994507+CatNoir2006@users.noreply.github.com>
Date: Wed, 5 Aug 2026 22:41:39 +0200
Subject: [PATCH 1/2] feat(server): add optional timestamp_from/timestamp_to
range filter
Adds support for an explicit epoch_second-based timestamp range in both
the JSON API (POST/GET /api/query) and the RSS feed.
- SearchEngine: new range filter on 'timestamp' using gte/lte when
timestamp_from or timestamp_to is provided in the query.
- If an explicit range is set, the 'future: false' filter is skipped so
the two filters do not collide on the same field.
- RSSFeedGenerator: parses timestamp_from / timestamp_to from the URL
query string and forwards them to the SearchEngine.
---
server/RSSFeedGenerator.ts | 2 ++
server/SearchEngine.ts | 18 +++++++++++++++++-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/server/RSSFeedGenerator.ts b/server/RSSFeedGenerator.ts
index 10e866cf..fd182f81 100644
--- a/server/RSSFeedGenerator.ts
+++ b/server/RSSFeedGenerator.ts
@@ -71,6 +71,8 @@ export class RSSFeedGenerator {
sortBy: urlQuery.sortBy ?? 'timestamp',
sortOrder: urlQuery.sortOrder ?? 'desc',
future,
+ timestamp_from: (typeof urlQuery.timestamp_from == 'string') ? parseInt(urlQuery.timestamp_from) : undefined,
+ timestamp_to: (typeof urlQuery.timestamp_to == 'string') ? parseInt(urlQuery.timestamp_to) : undefined,
duration_min: parsedQuery.duration_min,
duration_max: parsedQuery.duration_max,
offset: (typeof urlQuery.offset == 'string') ? parseInt(urlQuery.offset) : 0,
diff --git a/server/SearchEngine.ts b/server/SearchEngine.ts
index 9799326c..eba41367 100644
--- a/server/SearchEngine.ts
+++ b/server/SearchEngine.ts
@@ -148,7 +148,23 @@ export class SearchEngine {
opensearchQuery.body.query.bool.filter.push(durationFilter);
}
- if (query.future === false) {
+ const hasExplicitTimestampRange = query.timestamp_from != undefined || query.timestamp_to != undefined;
+ if (hasExplicitTimestampRange) {
+ const timestampFilter: { range: { timestamp: { gte?: number, lte?: number } } } = {
+ range: { timestamp: {} }
+ };
+
+ if (query.timestamp_from != undefined) {
+ timestampFilter.range.timestamp.gte = query.timestamp_from;
+ }
+
+ if (query.timestamp_to != undefined) {
+ timestampFilter.range.timestamp.lte = query.timestamp_to;
+ }
+ opensearchQuery.body.query.bool.filter.push(timestampFilter);
+ }
+
+ if (query.future === false && !hasExplicitTimestampRange) {
opensearchQuery.body.query.bool.filter.push({
range: {
timestamp: { to: 'now+1h/h' }
From d26a1108f2f853bfc32ce0773f4818414dfa7e77 Mon Sep 17 00:00:00 2001
From: CatNoir2006 <93994507+CatNoir2006@users.noreply.github.com>
Date: Wed, 5 Aug 2026 23:40:16 +0200
Subject: [PATCH 2/2] feat(client): add timestamp_from/timestamp_to range
filter UI
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Adds two date inputs ('Von' / 'Bis') to the search bar that wire
through to the new server-side timestamp range filter from the
previous commit.
- store.svelte.ts: new timestampFrom/timestampTo state, included in
the request body, URL hash and trackSearch payload; getter/setter
reset the page on change like the existing future toggle.
- SearchBar.svelte: two date inputs between the 'Zukünftige' toggle
and the sort dropdown; epoch_second conversion done inline on
onchange. Styled consistently with the search input (h-10, dark
mode aware, color-scheme for native picker).
---
client/src/lib/components/SearchBar.svelte | 28 ++++++++++++++++++++++
client/src/lib/store.svelte.ts | 19 ++++++++++++++-
2 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/client/src/lib/components/SearchBar.svelte b/client/src/lib/components/SearchBar.svelte
index d7837994..cd7d5253 100644
--- a/client/src/lib/components/SearchBar.svelte
+++ b/client/src/lib/components/SearchBar.svelte
@@ -8,6 +8,19 @@
const sortValue = $derived(`${appState.sortBy}_${appState.sortOrder}`);
+ const dateFrom = $derived(appState.timestampFrom != undefined ? new Date(appState.timestampFrom * 1000).toISOString().slice(0, 10) : '');
+ const dateTo = $derived(appState.timestampTo != undefined ? new Date(appState.timestampTo * 1000).toISOString().slice(0, 10) : '');
+
+ function handleDateFromChange(event: Event) {
+ const value = (event.target as HTMLInputElement).value;
+ appState.timestampFrom = value ? Math.floor(new Date(value).getTime() / 1000) : undefined;
+ }
+
+ function handleDateToChange(event: Event) {
+ const value = (event.target as HTMLInputElement).value;
+ appState.timestampTo = value ? Math.floor(new Date(value).getTime() / 1000) : undefined;
+ }
+
function handleSortChange(event: Event) {
const target = event.target as HTMLSelectElement;
if (target) {
@@ -52,6 +65,12 @@