add search functionality

This commit is contained in:
sirjonasxx 2021-08-22 02:48:45 +02:00
parent 648f5d1ca7
commit 486ce36528
8 changed files with 320 additions and 81 deletions

View File

@ -1,4 +0,0 @@
package gearth.services.internal_extensions.extensionstore.application.entities.queriedoverviews;
public class ManualQueryOverview {
}

View File

@ -0,0 +1,72 @@
package gearth.services.internal_extensions.extensionstore.application.entities.queriedoverviews;
import gearth.misc.OSValidator;
import gearth.services.internal_extensions.extensionstore.application.entities.HOverview;
import gearth.services.internal_extensions.extensionstore.repository.StoreRepository;
import gearth.services.internal_extensions.extensionstore.repository.models.StoreExtension;
import gearth.services.internal_extensions.extensionstore.repository.querying.ExtensionOrdering;
import java.util.Collections;
import java.util.List;
public class SearchedQueryOverview extends QueriedExtensionOverview {
private final String queryString;
private final ExtensionOrdering ordering;
private final List<String> filterClients;
private final List<String> filterFrameworks;
private final List<String> filterCategories;
private final boolean includeOutdated;
private final boolean invert;
public SearchedQueryOverview(HOverview parent, int startIndex, int size, StoreRepository storeRepository, String queryString, ExtensionOrdering ordering, List<String> filterClients, List<String> filterFrameworks, List<String> filterCategories, boolean includeOutdated, boolean invert) {
super(parent, startIndex, size, storeRepository);
this.queryString = queryString;
this.ordering = ordering;
this.filterClients = filterClients;
this.filterFrameworks = filterFrameworks;
this.filterCategories = filterCategories;
this.includeOutdated = includeOutdated;
this.invert = invert;
}
@Override
protected List<StoreExtension> query(int startIndex, int size) {
return storeRepository.getExtensions(startIndex, size, queryString, ordering,
Collections.singletonList(OSValidator.getOSFull()), filterClients, filterFrameworks,
filterCategories, includeOutdated, invert);
}
@Override
public Header header() {
return new Header() {
@Override
public String iconUrl() {
return "images/overviews/search.png";
}
@Override
public String title() {
return "Search";
}
@Override
public String description() {
return "Find the extension that fits your needs";
}
@Override
public String contentTitle() {
return "Search results";
}
};
}
@Override
public HOverview getNewPage(int startIndex, int size) {
return new SearchedQueryOverview(parent, startIndex, size, storeRepository,
queryString, ordering, filterClients, filterFrameworks, filterCategories,
includeOutdated, invert);
}
}

View File

@ -1,12 +1,168 @@
package gearth.services.internal_extensions.extensionstore.application.entities.search;
import gearth.services.internal_extensions.extensionstore.GExtensionStore;
import gearth.services.internal_extensions.extensionstore.application.GExtensionStoreController;
import gearth.services.internal_extensions.extensionstore.application.entities.ContentItem;
import gearth.services.internal_extensions.extensionstore.repository.StoreRepository;
import gearth.services.internal_extensions.extensionstore.repository.querying.ExtensionOrdering;
import netscape.javascript.JSObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class SearchComponent implements ContentItem {
private StoreRepository repository;
private volatile String searchKeyword;
private volatile ExtensionOrdering ordering;
private volatile Map<String, Boolean> clients;
private volatile Map<String, Boolean> categories;
private volatile Map<String, Boolean> frameworks;
public SearchComponent(StoreRepository repository) {
this.repository = repository;
this.searchKeyword = "";
this.ordering = ExtensionOrdering.ALPHABETICAL;
this.clients = new HashMap<>();
this.categories = new HashMap<>();
this.frameworks = new HashMap<>();
repository.getClients().forEach(c -> clients.put(c, true));
repository.getCategories().forEach(c -> categories.put(c.getName(), true));
repository.getFrameworks().forEach(c -> frameworks.put(c.getName(), true));
}
public void setOrdering(String ordering) {
this.ordering = ExtensionOrdering.fromString(ordering);
}
public void setSearchKeyword(String searchKeyword) {
this.searchKeyword = searchKeyword;
}
public void setClient(String client, boolean enabled) {
clients.put(client, enabled);
}
public void setCategory(String category, boolean enabled) {
categories.put(category, enabled);
}
public void setFramework(String framework, boolean enabled) {
frameworks.put(framework, enabled);
}
private void addFilterBoxHtml(StringBuilder htmlBuilder, String name, String title, Map<String, Boolean> data, String id) {
htmlBuilder.append("<div class=\"filterBox\">");
htmlBuilder.append(String.format("<p>%s</p>", title));
List<String> items = new ArrayList<>(data.keySet());
for (int i = 0; i < items.size(); i++) {
String item = items.get(i);
String checkboxId = name.toLowerCase() + i;
htmlBuilder.append(String.format("<input type=\"checkbox\" id=\"%s\"%s onchange=\"%s.set%s(&quot;%s&quot;, this.checked);\">",
checkboxId,
data.get(item) ? " checked" : "",
id,
name,
item
));
htmlBuilder.append(String.format("<label for=\"%s\">%s</label><br>", checkboxId, item));
}
htmlBuilder.append("</div>");
}
@Override
public void addHtml(int i, GExtensionStore gExtensionStore) {
String id = "search" + i + "_" + System.currentTimeMillis();
StringBuilder htmlBuilder = new StringBuilder();
htmlBuilder
.append("<div class=\"searchContainer\">")
.append("<div class=\"searchInnerContainer\">")
.append("<div class=\"centeredFlex\">")
.append("<label for=\"keyword\">Search by keyword:</label>")
.append(String.format("<input id=\"keyword\" value=\"%s\" name=\"keyword\" class=\"inputBox\" type=\"text\" " +
"oninput=\"%s.setSearchKeyword(this.value);\">", searchKeyword, id))
.append("</div>")
.append("<div class=\"centeredFlex\">")
.append("<label for=\"ordering\">Extensions ordering:</label>");
// add ordering stuff
htmlBuilder.append(String.format("<select class=\"inputBox\" name=\"ordering\" id=\"ordering\" " +
"onchange=\"%s.setOrdering(this.value);\">", id));
repository.getOrderings().forEach(o -> {
htmlBuilder.append(
String.format("<option value=\"%s\"%s>%s</option>",
o.getOrderName(),
o.getOrderName().equals(ordering.getOrderName()) ? " selected" : "",
o.getOrderName()
)
);
});
htmlBuilder
.append("</select>")
.append("</div>")
.append("<div class=\"filterStuff\">");
addFilterBoxHtml(htmlBuilder, "Client", "Clients:", clients, id);
addFilterBoxHtml(htmlBuilder, "Category", "Categories:", categories, id);
addFilterBoxHtml(htmlBuilder, "Framework", "Frameworks:", frameworks, id);
htmlBuilder
.append("</div>")
.append("<br><p>Info: you are automatically filtering on the OS you use</p>")
.append("</div>")
.append("</div>");
String searchHtml = htmlBuilder.toString();
GExtensionStoreController controller = gExtensionStore.getController();
controller.getWebView().getEngine().executeScript("document.getElementById('" + controller.getContentItemsContainer() + "').innerHTML += '" + searchHtml + "';");
JSObject window = (JSObject) controller.getWebView().getEngine().executeScript("window");
window.setMember(id, this);
}
public StoreRepository getRepository() {
return repository;
}
public List<String> getCategories() {
return categories.keySet().stream().filter(c -> categories.get(c)).collect(Collectors.toList());
}
public List<String> getClients() {
return clients.keySet().stream().filter(c -> clients.get(c)).collect(Collectors.toList());
}
public List<String> getFrameworks() {
return frameworks.keySet().stream().filter(f -> frameworks.get(f)).collect(Collectors.toList());
}
public ExtensionOrdering getOrdering() {
return ordering;
}
public String getSearchKeyword() {
return searchKeyword;
}
}

View File

@ -3,6 +3,8 @@ package gearth.services.internal_extensions.extensionstore.application.entities.
import gearth.services.internal_extensions.extensionstore.GExtensionStore;
import gearth.services.internal_extensions.extensionstore.application.entities.ContentItem;
import gearth.services.internal_extensions.extensionstore.application.entities.HOverview;
import gearth.services.internal_extensions.extensionstore.application.entities.extensiondetails.StoreExtensionDetailsOverview;
import gearth.services.internal_extensions.extensionstore.application.entities.queriedoverviews.SearchedQueryOverview;
import gearth.services.internal_extensions.extensionstore.repository.StoreRepository;
import java.util.Collections;
@ -10,27 +12,32 @@ import java.util.List;
public class SearchOverview extends HOverview {
private static SearchComponent searchComponent = null;
private final StoreRepository storeRepository;
public SearchOverview(HOverview parent, StoreRepository storeRepository) {
super(null, 0, 1);
this.storeRepository = storeRepository;
if (searchComponent == null || searchComponent.getRepository() != storeRepository) {
searchComponent = new SearchComponent(storeRepository);
}
}
@Override
public String buttonText() {
return null;
return "Search";
}
@Override
public boolean buttonEnabled() {
return false;
return true;
}
@Override
public List<? extends ContentItem> getContentItems() {
return Collections.singletonList(new SearchComponent());
return Collections.singletonList(searchComponent);
}
@Override
@ -40,7 +47,21 @@ public class SearchOverview extends HOverview {
@Override
public void buttonClick(GExtensionStore gExtensionStore) {
// nothing
gExtensionStore.getController().pushOverview(
new SearchedQueryOverview(
gExtensionStore.getController().getCurrentOverview(),
0,
GExtensionStore.PAGESIZE,
storeRepository,
searchComponent.getSearchKeyword(),
searchComponent.getOrdering(),
searchComponent.getClients(),
searchComponent.getFrameworks(),
searchComponent.getCategories(),
false,
false
)
);
}
@Override

View File

@ -18,4 +18,13 @@ public enum ExtensionOrdering {
public String getOrderName() {
return orderName;
}
public static ExtensionOrdering fromString(String text) {
for (ExtensionOrdering b : ExtensionOrdering.values()) {
if (b.orderName.equalsIgnoreCase(text)) {
return b;
}
}
return null;
}
}

View File

@ -1,72 +0,0 @@
.a_container {
margin: 0 2px 2px 2px;
background-color: #e9e9e1;
flex: 1 1 auto;
display: flex;
flex-direction: column;
padding: 8px 3px 0 3px;
}
.a_subcontainer {
flex: 1 1 auto;
display: flex;
flex-direction: column;
}
.a_lbl {
flex: 0 0 auto;
color: white;
background-color: #3179ac;
height: 13px;
max-height: 13px;
line-height: 13px;
font-size: 13px;
padding: 4px 3px;
}
.a_txt {
border: none;
margin: 0;
padding: 2px 3px;
overflow: auto;
outline: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
resize: none;
}
.a_subject {
flex: 0 0 auto;
background-color: white;
height: 18px;
max-height: 18px;
overflow: hidden;
font-size: 15px;
line-height: 21px;
}
.a_div {
flex: 0 0 auto;
height: 6px;
max-height: 6px;
}
.a_message {
flex: 1 1 auto;
background-color: white;
}
#a_content_buttons {
flex: 0 0 38px;
margin: 13px 17px 13px 17px;
display: flex;
}

View File

@ -0,0 +1,55 @@
.searchContainer {
background-color: #d4eaf5;
width: 100%;
min-height: 0;
flex: 1;
overflow-y: auto;
}
.searchInnerContainer {
display: flex;
flex-direction: column;
min-width: 0;
padding: 10px;
}
.centeredFlex {
/*justify-content: center;*/
display: flex;
align-items: center
}
.inputBox {
margin-left: 10px;
}
.filterBox {
margin-right: 15px;
padding: 0 10px 10px 10px;
border: 1px solid #666;
border-radius: 5px;
}
.filterStuff {
margin-top: 10px;
display: flex;
}
/*.searchFiller {*/
/* flex: 1;*/
/* margin-bottom: auto;*/
/*}*/
.searchInnerContainer p, .searchInnerContainer label {
margin: 8px 0;
color: #454545;
min-width: 0;
}

View File

@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>G-Forum</title>
<title>G-ExtensionStore</title>
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/layout.css">
@ -12,6 +12,8 @@
<link rel="stylesheet" href="css/extension_overview.css">
<link rel="stylesheet" href="css/comments_overview.css">
<link rel="stylesheet" href="css/search.css">
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Ubuntu:regular,bold&subset=Latin">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="js/script.js"></script>