(search) Toggle for showing recent results

Will by default show results from the last 2 years.  May need to tune this later.
This commit is contained in:
Viktor Lofgren 2024-01-09 11:28:36 +01:00
parent d4b0539d39
commit aff690f7d6
6 changed files with 91 additions and 10 deletions

View File

@ -14,10 +14,13 @@ public class SearchQueryParamFactory {
public QueryParams forRegularSearch(SearchParameters userParams) {
SearchSubquery prototype = new SearchSubquery();
var profile = userParams.profile();
profile.addTacitTerms(prototype);
userParams.js().addTacitTerms(prototype);
userParams.adtech().addTacitTerms(prototype);
SpecificationLimit yearLimit = userParams.recent().yearLimit();
return new QueryParams(
userParams.query(),
null,
@ -26,7 +29,7 @@ public class SearchQueryParamFactory {
prototype.searchTermsPriority,
prototype.searchTermsAdvice,
profile.getQualityLimit(),
profile.getYearLimit(),
yearLimit,
profile.getSizeLimit(),
SpecificationLimit.none(),
SpecificationLimit.none(),

View File

@ -9,6 +9,7 @@ import java.nio.charset.StandardCharsets;
public record SearchParameters(String query,
SearchProfile profile,
SearchJsParameter js,
SearchRecentParameter recent,
SearchAdtechParameter adtech
) {
public String profileStr() {
@ -16,22 +17,27 @@ public record SearchParameters(String query,
}
public SearchParameters withProfile(SearchProfile profile) {
return new SearchParameters(query, profile, js, adtech);
return new SearchParameters(query, profile, js, recent, adtech);
}
public SearchParameters withJs(SearchJsParameter js) {
return new SearchParameters(query, profile, js, adtech);
return new SearchParameters(query, profile, js, recent, adtech);
}
public SearchParameters withAdtech(SearchAdtechParameter adtech) {
return new SearchParameters(query, profile, js, adtech);
return new SearchParameters(query, profile, js, recent, adtech);
}
public SearchParameters withRecent(SearchRecentParameter recent) {
return new SearchParameters(query, profile, js, recent, adtech);
}
public String renderUrl(WebsiteUrl baseUrl) {
String path = String.format("/search?query=%s&profile=%s&js=%s&adtech=%s",
String path = String.format("/search?query=%s&profile=%s&js=%s&adtech=%s&recent=%s",
URLEncoder.encode(query, StandardCharsets.UTF_8),
URLEncoder.encode(profile.filterId, StandardCharsets.UTF_8),
URLEncoder.encode(js.value, StandardCharsets.UTF_8),
URLEncoder.encode(adtech.value, StandardCharsets.UTF_8)
URLEncoder.encode(adtech.value, StandardCharsets.UTF_8),
URLEncoder.encode(recent.value, StandardCharsets.UTF_8)
);
return baseUrl.withPath(path);

View File

@ -0,0 +1,33 @@
package nu.marginalia.search.command;
import nu.marginalia.index.client.model.query.SearchSubquery;
import nu.marginalia.index.query.limit.SpecificationLimit;
import javax.annotation.Nullable;
import java.time.LocalDateTime;
import java.util.Arrays;
public enum SearchRecentParameter {
DEFAULT("default"),
RECENT("recent");
public final String value;
SearchRecentParameter(String value) {
this.value = value;
}
public static SearchRecentParameter parse(@Nullable String value) {
if (RECENT.value.equals(value)) return RECENT;
return DEFAULT;
}
public SpecificationLimit yearLimit() {
if (this == RECENT) {
return SpecificationLimit.greaterThan(LocalDateTime.now().getYear() - 1);
} else {
return SpecificationLimit.none();
}
}
}

View File

@ -5,6 +5,7 @@ import nu.marginalia.WebsiteUrl;
import nu.marginalia.search.command.SearchAdtechParameter;
import nu.marginalia.search.command.SearchJsParameter;
import nu.marginalia.search.command.SearchParameters;
import nu.marginalia.search.command.SearchRecentParameter;
import java.util.List;
@ -20,6 +21,9 @@ public class SearchFilters {
public final RemoveJsOption removeJsOption;
@Getter
public final ReduceAdtechOption reduceAdtechOption;
@Getter
public final ShowRecentOption showRecentOption;
@Getter
public final List<List<Filter>> filterGroups;
@ -30,6 +34,8 @@ public class SearchFilters {
removeJsOption = new RemoveJsOption(parameters);
reduceAdtechOption = new ReduceAdtechOption(parameters);
showRecentOption = new ShowRecentOption(parameters);
currentFilter = parameters.profile().filterId;
@ -82,6 +88,7 @@ public class SearchFilters {
this.url = parameters.withJs(toggledValue).renderUrl(SearchFilters.this.url);
}
}
public class ReduceAdtechOption {
private final SearchAdtechParameter value;
@ -108,6 +115,32 @@ public class SearchFilters {
}
}
public class ShowRecentOption {
private final SearchRecentParameter value;
@Getter
public final String url;
public boolean isSet() {
return value.equals(SearchRecentParameter.RECENT);
}
public String name() {
return "Recent Results";
}
public ShowRecentOption(SearchParameters parameters) {
this.value = parameters.recent();
var toggledValue = switch (parameters.recent()) {
case RECENT -> SearchRecentParameter.DEFAULT;
default -> SearchRecentParameter.RECENT;
};
this.url = parameters.withRecent(toggledValue).renderUrl(SearchFilters.this.url);
}
}
public class Filter {
@Getter
public final String displayName;

View File

@ -4,12 +4,9 @@ import com.google.inject.Inject;
import io.prometheus.client.Histogram;
import lombok.SneakyThrows;
import nu.marginalia.WebsiteUrl;
import nu.marginalia.search.command.SearchAdtechParameter;
import nu.marginalia.search.command.*;
import nu.marginalia.search.model.SearchProfile;
import nu.marginalia.client.Context;
import nu.marginalia.search.command.CommandEvaluator;
import nu.marginalia.search.command.SearchJsParameter;
import nu.marginalia.search.command.SearchParameters;
import nu.marginalia.search.exceptions.RedirectException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -63,6 +60,7 @@ public class SearchQueryService {
return new SearchParameters(queryParam.trim(),
SearchProfile.getSearchProfile(request.queryParams("profile")),
SearchJsParameter.parse(request.queryParams("js")),
SearchRecentParameter.parse(request.queryParams("recent")),
SearchAdtechParameter.parse(request.queryParams("adtech")));
}
catch (Exception ex) {

View File

@ -16,6 +16,14 @@
<a href="{{url}}">{{name}}</a>
</li>
{{/with}}
{{#with showRecentOption}}
<li title="Show Recent Options"
{{#if set}}aria-checked="true" class="current"{{/if}}
{{#unless set}}aria-checked="false"{{/unless}}
role="checkbox">
<a href="{{url}}">{{name}}</a>
</li>
{{/with}}
</ul>
<h3>Domains</h3>
<ul>