atproto explorer pdsls.dev
atproto tool

wildcard partial search

juli.ee 09d29ebc 08febe96

verified
Changed files
+29 -9
src
views
+29 -9
src/views/labels.tsx
···
.map((f) => f.trim())
.filter((f) => f.length > 0);
-
const exclusions: string[] = [];
-
const inclusions: string[] = [];
filters.forEach((f) => {
if (f.startsWith("-")) {
-
exclusions.push(f.slice(1).toLowerCase());
} else {
-
inclusions.push(f.toLowerCase());
}
});
return labels().filter((label) => {
const labelValue = label.val.toLowerCase();
-
// Check exclusions (exact match)
-
if (exclusions.some((exc) => labelValue === exc)) {
return false;
}
-
// If there are inclusions, at least one must match (partial match)
if (inclusions.length > 0) {
-
return inclusions.some((inc) => labelValue.includes(inc));
}
// If only exclusions were specified, include everything not excluded
···
<StickyOverlay>
<div class="flex w-full items-center gap-x-2">
<TextInput
-
placeholder="Filter labels (space separated, -label to exclude)"
name="filter"
value={filter()}
onInput={(e) => setFilter(e.currentTarget.value)}
···
.map((f) => f.trim())
.filter((f) => f.length > 0);
+
const exclusions: { pattern: string; hasWildcard: boolean }[] = [];
+
const inclusions: { pattern: string; hasWildcard: boolean }[] = [];
filters.forEach((f) => {
if (f.startsWith("-")) {
+
const lower = f.slice(1).toLowerCase();
+
exclusions.push({
+
pattern: lower,
+
hasWildcard: lower.includes("*"),
+
});
} else {
+
const lower = f.toLowerCase();
+
inclusions.push({
+
pattern: lower,
+
hasWildcard: lower.includes("*"),
+
});
}
});
+
const matchesPattern = (value: string, filter: { pattern: string; hasWildcard: boolean }) => {
+
if (filter.hasWildcard) {
+
// Convert wildcard pattern to regex
+
const regexPattern = filter.pattern
+
.replace(/[.+?^${}()|[\]\\]/g, "\\$&") // Escape special regex chars except *
+
.replace(/\*/g, ".*"); // Replace * with .*
+
const regex = new RegExp(`^${regexPattern}$`);
+
return regex.test(value);
+
} else {
+
return value === filter.pattern;
+
}
+
};
+
return labels().filter((label) => {
const labelValue = label.val.toLowerCase();
+
if (exclusions.some((exc) => matchesPattern(labelValue, exc))) {
return false;
}
+
// If there are inclusions, at least one must match
if (inclusions.length > 0) {
+
return inclusions.some((inc) => matchesPattern(labelValue, inc));
}
// If only exclusions were specified, include everything not excluded
···
<StickyOverlay>
<div class="flex w-full items-center gap-x-2">
<TextInput
+
placeholder="Filter labels (* for partial, -exclude)"
name="filter"
value={filter()}
onInput={(e) => setFilter(e.currentTarget.value)}