diff --git a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/GExtensionStore.java b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/GExtensionStore.java index 64cee2f..1060092 100644 --- a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/GExtensionStore.java +++ b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/GExtensionStore.java @@ -6,6 +6,7 @@ import gearth.services.internal_extensions.extensionstore.application.GExtension import gearth.services.internal_extensions.extensionstore.application.entities.queriedoverviews.ByDateOverview; import gearth.services.internal_extensions.extensionstore.repository.StoreFetch; import gearth.services.internal_extensions.extensionstore.repository.StoreRepository; +import javafx.application.HostServices; @ExtensionInfo( Title = "G-ExtensionStore", @@ -56,4 +57,9 @@ public class GExtensionStore extends ExtensionForm { protected boolean canLeave() { return false; } + + @Override + public HostServices getHostServices() { + return super.getHostServices(); + } } diff --git a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/GExtensionStoreLauncher.java b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/GExtensionStoreLauncher.java index b94c5fb..9ed4fe3 100644 --- a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/GExtensionStoreLauncher.java +++ b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/GExtensionStoreLauncher.java @@ -22,7 +22,7 @@ public class GExtensionStoreLauncher extends InternalExtensionFormLauncher 1) { diff --git a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/entities/extensiondetails/StoreExtensionDetailsItem.java b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/entities/extensiondetails/StoreExtensionDetailsItem.java index d94d060..416f7cf 100644 --- a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/entities/extensiondetails/StoreExtensionDetailsItem.java +++ b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/entities/extensiondetails/StoreExtensionDetailsItem.java @@ -1,19 +1,192 @@ package gearth.services.internal_extensions.extensionstore.application.entities.extensiondetails; import gearth.services.internal_extensions.extensionstore.GExtensionStore; +import gearth.services.internal_extensions.extensionstore.application.GExtensionStoreController; +import gearth.services.internal_extensions.extensionstore.application.WebUtils; import gearth.services.internal_extensions.extensionstore.application.entities.ContentItem; +import gearth.services.internal_extensions.extensionstore.application.entities.HOverview; +import gearth.services.internal_extensions.extensionstore.repository.models.ExtCategory; import gearth.services.internal_extensions.extensionstore.repository.models.StoreExtension; +import netscape.javascript.JSObject; +import org.apache.commons.io.IOUtils; +import org.json.JSONObject; + +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.stream.Collectors; public class StoreExtensionDetailsItem implements ContentItem { - private final StoreExtension storeExtension; + private final static String HABBO_API_URL = "https://www.habbo{hotel}/api/public/users?name={user}"; + private static final String OUTFIT_URL = "https://www.habbo.com/habbo-imaging/avatarimage?&figure={figureString}&direction=2&head_direction=2"; + private static final Map userToFigure = new HashMap<>(); - public StoreExtensionDetailsItem(StoreExtension storeExtension) { + private final HOverview parent; + private final StoreExtension storeExtension; + private GExtensionStore gExtensionStore = null; + + private String avatarImageUrl = ""; + private String id; + + public StoreExtensionDetailsItem(StoreExtension storeExtension, HOverview parent) { this.storeExtension = storeExtension; + this.parent = parent; + } + + private void fetchLooks() { + StoreExtension.Author mainAuthor = storeExtension.getAuthors().get(0); + if (mainAuthor.getUsername() != null && mainAuthor.getHotel() != null) { + String key = mainAuthor.getName() + "\t" + mainAuthor.getHotel(); + synchronized (userToFigure) { + if (userToFigure.containsKey(key)) { + avatarImageUrl = userToFigure.get(key); + } + else { + new Thread(() -> { + try { + JSONObject habboData = new JSONObject(IOUtils.toString( + new URL(HABBO_API_URL.replace("{hotel}", mainAuthor.getHotel()).replace("{user}", + mainAuthor.getUsername())).openStream(), StandardCharsets.UTF_8)); + + if (habboData.has("figureString")) { + avatarImageUrl = OUTFIT_URL.replace("{figureString}", habboData.getString("figureString")); + synchronized (userToFigure) { + userToFigure.put(key, avatarImageUrl); + } + if (gExtensionStore != null && gExtensionStore.getController().getCurrentOverview() == parent) { + gExtensionStore.getController().reloadOverview(); + } + } + + } catch (IOException ignore) { + + } + + }).start(); + } + } + } + } + + private String getContents() { + StringBuilder contentBuilder = new StringBuilder(); + + String descriptionQuoted = Arrays.stream(storeExtension.getDescription().split("\r\n|\r|\n")) + .map(s -> "> " + s + "\n").collect(Collectors.joining()); + + if (storeExtension.getReadme() != null) { + descriptionQuoted = descriptionQuoted + "> \n> --url:README-" + storeExtension.getReadme() + "\n"; + } + + contentBuilder + .append(String.format("*%s*", storeExtension.getTitle())).append(" - v").append(storeExtension.getVersion()).append("\n\n") + .append("*Description*\n").append(descriptionQuoted).append("\n \n") + .append("*Author(s):* ").append(storeExtension.getAuthors().stream().map(StoreExtension.Author::getName).collect(Collectors.joining(", "))).append("\n\n") + .append("*Categories:* ").append(storeExtension.getCategories().stream().map(ExtCategory::getName).collect(Collectors.joining(", "))).append("\n\n"); + + contentBuilder.append("*Technical information*").append("\n") + .append("> Language: ").append(storeExtension.getLanguage()).append("\n") + .append("> Source: --url:Click Here-").append(storeExtension.getSource()).append("\n") + .append("> Framework: ").append(storeExtension.getFramework().getFramework().getName()).append(" - v").append(storeExtension.getFramework().getVersion()).append("\n") + .append("> Systems: ").append(String.join(", ", storeExtension.getCompatibility().getSystems())).append("\n \n"); + + if (storeExtension.getFramework().getFramework().isInstallationRequired()) { + contentBuilder.append("Warning: the framework requires --url:additional installations-") + .append(storeExtension.getFramework().getFramework().getInstallationInstructions()).append(" !\n"); + } + if (!storeExtension.isStable()) { + contentBuilder.append("Warning: this extension has been marked unstable!\n"); + } + + contentBuilder.append("\n*Screenshot: *").append("\n") + .append("--img:").append(gExtensionStore.getRepository().getResourceUrl(String.format("store/extensions/%s/screenshot.png", storeExtension.getTitle()))); + + return contentBuilder.toString(); + } + + public void openUrl(String url) { + gExtensionStore.getHostServices().showDocument(url); + } + + + private String contentsInHtml() { + String comment = WebUtils.escapeMessage(getContents()); + List lines = new ArrayList<>(Arrays.asList(comment.split("
"))); + + boolean isquoting = false; + boolean justEndedQuoting = false; + + for (int i = 0; i < lines.size(); i++) { + String line = lines.get(i); + + if (!isquoting && line.startsWith(">")) { + isquoting = true; + line = "
" + line.substring(line.startsWith("> ") ? 5 : 4); + } + else if (isquoting && line.startsWith(">")) { + line = line.substring(line.startsWith("> ") ? 5 : 4); + } + else if (isquoting && !line.startsWith(">")) { + justEndedQuoting = true; + isquoting = false; + String prev = lines.get(i - 1); + lines.set(i-1, prev.substring(0, prev.length() - 4) + "
"); + } + + if (justEndedQuoting && line.length() == 0) continue; + justEndedQuoting = false; + + line = line.replaceAll("\\*([^*]*)\\*", "$1") + .replaceAll("_([^_<>]*)_", "$1") + .replaceAll("(^| |>)@([^ <>]*)($| |<)", "$1$2$3") + .replaceAll("--img:([^ ]*)", "\"extension") + .replaceAll("--url:([^-]*)-(https?:[^ ]*)", + String.format("$1", id)); +// .replaceAll("([^\";])(https?:[^ ]*)", +// String.format("$1$2", id)); + + lines.set(i, line + (i == lines.size() - 1 ? "" : "
")); + } + + return String.join("", lines); } @Override public void addHtml(int i, GExtensionStore gExtensionStore) { + this.gExtensionStore = gExtensionStore; + StoreExtension.Author mainAuthor = storeExtension.getAuthors().get(0); + fetchLooks(); + + id = "extdetail" + i + "_" + System.currentTimeMillis(); + + StringBuilder htmlBuilder = new StringBuilder() + .append("
") + + .append("
") + .append("
").append(WebUtils.elapsedSince(storeExtension.getUpdateDate())).append(" ago
") + .append("
") + + .append("
") + .append("
") + .append("
").append(WebUtils.escapeMessage(mainAuthor.getName())).append("
") + .append("
").append(mainAuthor.getReputation()).append(" reputation
") + .append("
").append(mainAuthor.getExtensionsCount()).append(" releases
") + .append("
\"\"
") // todo look + .append("
") + .append("
").append(contentsInHtml()).append("
") + .append("
") + + .append("
") + .append("
"); + + String forum = htmlBuilder.toString(); + GExtensionStoreController c = gExtensionStore.getController(); + c.getWebView().getEngine().executeScript("document.getElementById('" + c.getContentItemsContainer() + "').innerHTML += '" + forum + "';"); + + JSObject window = (JSObject) c.getWebView().getEngine().executeScript("window"); + window.setMember(id, this); } } diff --git a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/entities/extensiondetails/StoreExtensionDetailsOverview.java b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/entities/extensiondetails/StoreExtensionDetailsOverview.java index 136d6fc..1aeeeea 100644 --- a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/entities/extensiondetails/StoreExtensionDetailsOverview.java +++ b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/entities/extensiondetails/StoreExtensionDetailsOverview.java @@ -59,8 +59,8 @@ public class StoreExtensionDetailsOverview extends HOverview { @Override public String buttonText() { int mode = mode(); - return mode == 2 ? "Update" : "Install"; -// return mode == 0 ? "Install" : (mode == 1 ? "Remove" : "Update"); +// return mode == 2 ? "Update" : "Install"; + return mode == 0 ? "Install" : (mode == 1 ? "Installed" : "Update"); } @Override @@ -70,7 +70,7 @@ public class StoreExtensionDetailsOverview extends HOverview { @Override public List getContentItems() { - return Collections.singletonList(new StoreExtensionDetailsItem(extension)); + return Collections.singletonList(new StoreExtensionDetailsItem(extension, this)); } @Override diff --git a/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/css/category_overview.css b/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/css/category_overview.css deleted file mode 100644 index fd042d5..0000000 --- a/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/css/category_overview.css +++ /dev/null @@ -1,51 +0,0 @@ - -.thread_item { - -webkit-user-select: none; - - min-height: 41px; - display: flex; - - overflow: hidden; - white-space: nowrap; -} - -.thread_item > div { - border-style: solid; - border-color: #bab8b4; - border-width: 0 0 0 1px; -} - -.thread_settings { - flex: 0 1 auto; - display: flex; - flex-flow: column; - - width: 20px; - min-width: 20px; -} - -.thread_info { - flex: 1 1 auto; - min-width: 0; - - padding-left: 3px; - padding-top: 2px; -} - -.thread_msgs { - flex: 0 1 auto; - - width: 140px; - min-width: 140px; - padding-left: 4px; - - padding-top: 2px; -} - -.thread_delete_report { - flex: 0 1 auto; - - width: 50px; - min-width: 50px; - display: flex; -} diff --git a/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/css/comments_overview.css b/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/css/comments_overview.css index 76a3e47..3cbf2ee 100644 --- a/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/css/comments_overview.css +++ b/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/css/comments_overview.css @@ -33,16 +33,16 @@ font-size: 13px; margin: 7px 0 0 3px; } -.ch_index { - flex: 0 0 auto; - color: white; - font-size: 13px; - margin: 7px 4px 0 0; -} -.ch_buttons { - flex: 0 0 auto; - display: flex; -} +/*.ch_index {*/ +/* flex: 0 0 auto;*/ +/* color: white;*/ +/* font-size: 13px;*/ +/* margin: 7px 4px 0 0;*/ +/*}*/ +/*.ch_buttons {*/ +/* flex: 0 0 auto;*/ +/* display: flex;*/ +/*}*/ @@ -66,6 +66,13 @@ min-width: 0; } +.cb_content img { + max-width: 450px; + border-width: 1px; + border-color: black; + border-style: solid; +} + .cbc_quote { background-color: #cccccc; margin: 3px 10px 3px 16px; @@ -87,16 +94,18 @@ margin: 8px 0 0 5px; } -.cba_messages { +.cba_text { flex: 0 0 auto; min-height: 15px; font-size: 13px; margin: 2px 0 0 5px; + color: #444; } + .cba_look { - margin: -17px 0 0 -7px; + margin: -15px 0 0 -7px; height: 0; } @@ -109,23 +118,23 @@ background-color: #ffffff; } -.comment_unread > .cb_author { - background-color: #c8eff8; -} -.comment_unread > .cb_content { - background-color: #fef4da; -} +/*.comment_unread > .cb_author {*/ +/* background-color: #c8eff8;*/ +/*}*/ +/*.comment_unread > .cb_content {*/ +/* background-color: #fef4da;*/ +/*}*/ -.comment_hidden > .cb_author { - background-color: #d7d7cf; -} -.comment_hidden > .cb_content { - background-color: #e9e9e0; -} +/*.comment_hidden > .cb_author {*/ +/* background-color: #d7d7cf;*/ +/*}*/ +/*.comment_hidden > .cb_content {*/ +/* background-color: #e9e9e0;*/ +/*}*/ -.comment_staffhidden > .cb_author { - background-color: #fedfd3; -} -.comment_staffhidden > .cb_content { - background-color: #fdc6bb; -} \ No newline at end of file +/*.comment_staffhidden > .cb_author {*/ +/* background-color: #fedfd3;*/ +/*}*/ +/*.comment_staffhidden > .cb_content {*/ +/* background-color: #fdc6bb;*/ +/*}*/ \ No newline at end of file diff --git a/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/css/content.css b/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/css/content.css index e7fdfc4..8f3bc2c 100644 --- a/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/css/content.css +++ b/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/css/content.css @@ -11,6 +11,7 @@ min-height: 0; overflow-y: auto; + overflow-x: hidden; display: flex; flex-flow: column; diff --git a/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/index.html b/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/index.html index 057e506..24611ae 100644 --- a/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/index.html +++ b/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/index.html @@ -9,7 +9,6 @@ -