From d097bcd740abdf6b8987be83f69f38d6fd25afc4 Mon Sep 17 00:00:00 2001 From: Bane Stojkovic Date: Fri, 4 Apr 2025 21:49:52 +0200 Subject: [PATCH] chatbot improvements --- .../main/java/org/diylc/common/EventType.java | 10 +- .../java/org/diylc/common/IPlugInPort.java | 2 +- .../org/diylc/common/IServiceManager.java | 14 ++ .../chatbot/model/ChatMessageEntity.java | 76 +++++++++++ .../plugins/chatbot/model/IChatbotAPI.java | 11 ++ .../chatbot/model/SubscriptionEntity.java | 75 +++++++++++ .../ChatbotException.java | 2 +- .../ChatbotService.java} | 90 +++++++------ .../CloudException.java | 2 +- .../{presenter => service}/CloudListener.java | 2 +- .../CloudService.java} | 18 ++- .../NotConnectedException.java | 2 +- .../NotExistsException.java | 2 +- .../NotLoggedInException.java | 2 +- .../{presenter => service}/SearchSession.java | 13 +- .../java/org/diylc/presenter/Presenter.java | 25 +++- .../swing/plugins/chatbot/ChatbotPane.java | 122 +++++++++++++----- .../swing/plugins/chatbot/ChatbotPlugin.java | 41 +++--- .../swing/plugins/cloud/CloudPlugIn.java | 24 ++-- .../plugins/cloud/view/CommentDialog.java | 12 +- .../cloud/view/browser/CloudBrowserFrame.java | 9 +- .../view/browser/ResultsScrollPanel.java | 19 ++- .../view/browser/UploadManagerFrame.java | 3 +- 23 files changed, 437 insertions(+), 139 deletions(-) create mode 100644 diylc/diylc-core/src/main/java/org/diylc/common/IServiceManager.java create mode 100644 diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/model/ChatMessageEntity.java create mode 100644 diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/model/SubscriptionEntity.java rename diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/{presenter => service}/ChatbotException.java (95%) rename diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/{presenter/ChatbotPresenter.java => service/ChatbotService.java} (82%) rename diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/{presenter => service}/CloudException.java (95%) rename diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/{presenter => service}/CloudListener.java (95%) rename diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/{presenter/CloudPresenter.java => service/CloudService.java} (93%) rename diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/{presenter => service}/NotConnectedException.java (95%) rename diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/{presenter => service}/NotExistsException.java (95%) rename diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/{presenter => service}/NotLoggedInException.java (95%) rename diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/{presenter => service}/SearchSession.java (78%) diff --git a/diylc/diylc-core/src/main/java/org/diylc/common/EventType.java b/diylc/diylc-core/src/main/java/org/diylc/common/EventType.java index 0367deef..87a57fcb 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/common/EventType.java +++ b/diylc/diylc-core/src/main/java/org/diylc/common/EventType.java @@ -106,5 +106,13 @@ public enum EventType { /** * Signals the listeners to scroll to selection. */ - SCROLL_TO; + SCROLL_TO, + /** + * Signals that the Cloud account is logged in. + */ + CLOUD_LOGGED_IN, + /** + * Signals that the Cloud account is logged out. + */ + CLOUD_LOGGED_OUT; } diff --git a/diylc/diylc-core/src/main/java/org/diylc/common/IPlugInPort.java b/diylc/diylc-core/src/main/java/org/diylc/common/IPlugInPort.java index 7e74fc8c..43718a79 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/common/IPlugInPort.java +++ b/diylc/diylc-core/src/main/java/org/diylc/common/IPlugInPort.java @@ -57,7 +57,7 @@ import org.diylc.test.ITestProcessor; * @see EventType */ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyProcessor, IVariantProcessor, - IBlockProcessor, INetlistProcessor, ITestProcessor { + IBlockProcessor, INetlistProcessor, ITestProcessor, IServiceManager { public static final String ANTI_ALIASING_KEY = "antiAliasing"; public static final String HI_QUALITY_RENDER_KEY = "hiQualityRender"; diff --git a/diylc/diylc-core/src/main/java/org/diylc/common/IServiceManager.java b/diylc/diylc-core/src/main/java/org/diylc/common/IServiceManager.java new file mode 100644 index 00000000..a4a93d60 --- /dev/null +++ b/diylc/diylc-core/src/main/java/org/diylc/common/IServiceManager.java @@ -0,0 +1,14 @@ +package org.diylc.common; + +import org.diylc.appframework.simplemq.MessageDispatcher; +import org.diylc.plugins.chatbot.service.ChatbotService; +import org.diylc.plugins.cloud.service.CloudService; + +public interface IServiceManager { + + CloudService getCloudService(); + + ChatbotService getChatbotService(); + + MessageDispatcher getMessageDispatcher(); +} diff --git a/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/model/ChatMessageEntity.java b/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/model/ChatMessageEntity.java new file mode 100644 index 00000000..523d61a1 --- /dev/null +++ b/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/model/ChatMessageEntity.java @@ -0,0 +1,76 @@ +/* + + DIY Layout Creator (DIYLC). + Copyright (c) 2009-2018 held jointly by the individual authors. + + This file is part of DIYLC. + + DIYLC is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DIYLC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DIYLC. If not, see . + +*/ +package org.diylc.plugins.chatbot.model; + +import java.io.Serializable; +import java.util.Objects; + +public class ChatMessageEntity implements Serializable { + + private String prompt; + private String response; + private String createdOn; + + public ChatMessageEntity(String prompt, String response, String createdOn) { + this.prompt = prompt; + this.response = response; + this.createdOn = createdOn; + } + + public String getPrompt() { + return prompt; + } + + public void setPrompt(String prompt) { + this.prompt = prompt; + } + + public String getResponse() { + return response; + } + + public void setResponse(String response) { + this.response = response; + } + + public String getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(String createdOn) { + this.createdOn = createdOn; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) + return false; + ChatMessageEntity that = (ChatMessageEntity) o; + return Objects.equals(prompt, that.prompt) && Objects.equals(response, + that.response) && Objects.equals(createdOn, that.createdOn); + } + + @Override + public int hashCode() { + return Objects.hash(prompt, response, createdOn); + } +} diff --git a/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/model/IChatbotAPI.java b/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/model/IChatbotAPI.java index 9be3d2c3..95bfd7d9 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/model/IChatbotAPI.java +++ b/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/model/IChatbotAPI.java @@ -23,6 +23,8 @@ package org.diylc.plugins.chatbot.model; import com.diyfever.httpproxy.ParamName; +import java.util.List; + public interface IChatbotAPI { /** @@ -39,4 +41,13 @@ public interface IChatbotAPI { String promptChatbot(@ParamName("username") String username, @ParamName("token") String token, @ParamName("machineId") String machineId, @ParamName("project") String project, @ParamName("netlist") String netlist, @ParamName("prompt") String prompt); + + SubscriptionEntity getSubscriptionInfo(@ParamName("username") String username, @ParamName("token") String token, + @ParamName("machineId") String machineId); + + String deleteChatHistory(@ParamName("username") String username, @ParamName("token") String token, + @ParamName("machineId") String machineId, @ParamName("project") String project); + + List getChatHistory(@ParamName("username") String username, @ParamName("token") String token, + @ParamName("machineId") String machineId, @ParamName("project") String project); } diff --git a/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/model/SubscriptionEntity.java b/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/model/SubscriptionEntity.java new file mode 100644 index 00000000..a6ba89ab --- /dev/null +++ b/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/model/SubscriptionEntity.java @@ -0,0 +1,75 @@ +/* + + DIY Layout Creator (DIYLC). + Copyright (c) 2009-2018 held jointly by the individual authors. + + This file is part of DIYLC. + + DIYLC is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DIYLC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DIYLC. If not, see . + +*/ +package org.diylc.plugins.chatbot.model; + +import java.io.Serializable; +import java.util.Objects; + +public class SubscriptionEntity implements Serializable { + private String tier; + private String endDate; + private int remainingCredits; + + public SubscriptionEntity(String tier, String endDate, int remainingCredits) { + this.tier = tier; + this.endDate = endDate; + this.remainingCredits = remainingCredits; + } + + public String getTier() { + return tier; + } + + public void setTier(String tier) { + this.tier = tier; + } + + public String getEndDate() { + return endDate; + } + + public void setEndDate(String endDate) { + this.endDate = endDate; + } + + public int getRemainingCredits() { + return remainingCredits; + } + + public void setRemainingCredits(int remainingCredits) { + this.remainingCredits = remainingCredits; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) + return false; + SubscriptionEntity that = (SubscriptionEntity) o; + return remainingCredits == that.remainingCredits && Objects.equals(tier, + that.tier) && Objects.equals(endDate, that.endDate); + } + + @Override + public int hashCode() { + return Objects.hash(tier, endDate, remainingCredits); + } +} diff --git a/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/presenter/ChatbotException.java b/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/service/ChatbotException.java similarity index 95% rename from diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/presenter/ChatbotException.java rename to diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/service/ChatbotException.java index 199d99cd..65d87b26 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/presenter/ChatbotException.java +++ b/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/service/ChatbotException.java @@ -19,7 +19,7 @@ along with DIYLC. If not, see . */ -package org.diylc.plugins.chatbot.presenter; +package org.diylc.plugins.chatbot.service; public class ChatbotException extends Exception { diff --git a/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/presenter/ChatbotPresenter.java b/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/service/ChatbotService.java similarity index 82% rename from diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/presenter/ChatbotPresenter.java rename to diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/service/ChatbotService.java index 5c7ea0a8..06fa2ab7 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/presenter/ChatbotPresenter.java +++ b/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/service/ChatbotService.java @@ -19,15 +19,12 @@ along with DIYLC. If not, see . */ -package org.diylc.plugins.chatbot.presenter; +package org.diylc.plugins.chatbot.service; import com.diyfever.httpproxy.PhpFlatProxy; import com.diyfever.httpproxy.ProxyFactory; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; import org.apache.log4j.Logger; -import org.checkerframework.checker.units.qual.C; -import org.checkerframework.checker.units.qual.N; import org.diylc.appframework.miscutils.ConfigurationManager; import org.diylc.common.ComponentType; import org.diylc.common.IPlugInPort; @@ -37,28 +34,15 @@ import org.diylc.netlist.Group; import org.diylc.netlist.Netlist; import org.diylc.netlist.NetlistException; import org.diylc.netlist.Node; +import org.diylc.plugins.chatbot.model.ChatMessageEntity; import org.diylc.plugins.chatbot.model.IChatbotAPI; -import org.diylc.plugins.cloud.model.CommentEntity; +import org.diylc.plugins.chatbot.model.SubscriptionEntity; import org.diylc.plugins.cloud.model.IServiceAPI; -import org.diylc.plugins.cloud.model.ProjectEntity; -import org.diylc.plugins.cloud.model.UserEntity; -import org.diylc.plugins.cloud.presenter.CloudException; -import org.diylc.plugins.cloud.presenter.CloudPresenter; -import org.diylc.plugins.cloud.presenter.NotLoggedInException; -import org.diylc.presenter.ComparatorFactory; +import org.diylc.plugins.cloud.service.NotLoggedInException; import org.diylc.presenter.ComponentProcessor; +import org.diylc.utils.FileUtils; -import javax.swing.*; import java.awt.*; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.URL; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; import java.util.*; import java.util.List; import java.util.stream.Collectors; @@ -66,29 +50,30 @@ import java.util.stream.Collectors; import static org.diylc.utils.FileUtils.extractFileName; /** - * Contains all the back-end logic for using the cloud and manipulating projects on the cloud. + * Contains all the back-end logic for using the chatbot. * * @author Branislav Stojkovic */ -public class ChatbotPresenter { +public class ChatbotService { - private static String ERROR = "Error"; + public static final String LOG_IN_MESSAGE = + "Please log into your DIYLC Cloud account in order to use the AI Assistant"; - private final static Logger LOG = Logger.getLogger(ChatbotPresenter.class); - private static final Object SUCCESS = "Success"; - private final IPlugInPort plugInPort; + private final static Logger LOG = Logger.getLogger(ChatbotService.class); private static final ObjectMapper MAPPER = new ObjectMapper(); + public static final String WELCOME_MESSAGE = "Welcome to the DIYLC AI Assistant!"; + + private final IPlugInPort plugInPort; private IChatbotAPI service; - private String serviceUrl; - public ChatbotPresenter(IPlugInPort plugInPort) { + public ChatbotService(IPlugInPort plugInPort) { this.plugInPort = plugInPort; } private IChatbotAPI getService() { if (service == null) { - serviceUrl = + String serviceUrl = ConfigurationManager.getInstance().readString(IServiceAPI.URL_KEY, "http://www.diy-fever.com/diylc/api/v1/ai"); ProxyFactory factory = new ProxyFactory(new PhpFlatProxy()); service = factory.createProxy(IChatbotAPI.class, serviceUrl); @@ -97,7 +82,7 @@ public class ChatbotPresenter { } public String promptChatbot(String prompt) throws NotLoggedInException { - if (!CloudPresenter.Instance.isLoggedIn()) + if (!plugInPort.getCloudService().isLoggedIn()) throw new NotLoggedInException(); String currentFile = plugInPort.getCurrentFileName(); @@ -111,9 +96,10 @@ public class ChatbotPresenter { netlist = null; } - return getService().promptChatbot(CloudPresenter.Instance.getCurrentUsername(), - CloudPresenter.Instance.getCurrentToken(), - CloudPresenter.Instance.getMachineId(), fileName, netlist, prompt); + return getService().promptChatbot( + plugInPort.getCloudService().getCurrentUsername(), + plugInPort.getCloudService().getCurrentToken(), + plugInPort.getCloudService().getMachineId(), fileName, netlist, prompt); } private static final Set> PROPERTY_TYPES_TO_SKIP = Set.of(Font.class, Color.class); @@ -122,6 +108,10 @@ public class ChatbotPresenter { private String extractNetlists() throws NetlistException { List netlists = plugInPort.extractNetlists(true); + if (netlists == null) { + return null; + } + StringBuilder sb = new StringBuilder(); sb.append("Components: "); @@ -183,7 +173,7 @@ public class ChatbotPresenter { Random r = new Random(); String chatHtml = - "
Welcome to the DIYLC AI Assistant!


\n" + + "
" + WELCOME_MESSAGE + "


\n" + "
I'm here to help you design, build, and troubleshoot your electronics projects using DIY Layout Creator (DIYLC). You can ask me questions about:

\n" + // "
    \n" + "\n" + @@ -195,13 +185,35 @@ public class ChatbotPresenter { "
    \n" + "
    Feel free to ask your own question or use one of these examples to get started!

    \n"; - if (!CloudPresenter.Instance.isLoggedIn()) { - chatHtml = chatHtml + "
    Please log into your DIYLC Cloud account in order to use the AI Assistant.

    \n"; - } - return chatHtml; } + public SubscriptionEntity getSubscriptionInfo() throws NotLoggedInException { + if (!plugInPort.getCloudService().isLoggedIn()) + throw new NotLoggedInException(); + + return getService().getSubscriptionInfo(plugInPort.getCloudService().getCurrentUsername(), + plugInPort.getCloudService().getCurrentToken(), plugInPort.getCloudService().getMachineId()); + } + + public void deleteChatHistory() throws NotLoggedInException { + if (!plugInPort.getCloudService().isLoggedIn()) + throw new NotLoggedInException(); + + getService().deleteChatHistory(plugInPort.getCloudService().getCurrentUsername(), + plugInPort.getCloudService().getCurrentToken(), plugInPort.getCloudService().getMachineId(), + FileUtils.extractFileName(plugInPort.getCurrentFileName())); + } + + public List getChatHistory() throws NotLoggedInException { + if (!plugInPort.getCloudService().isLoggedIn()) + throw new NotLoggedInException(); + + return getService().getChatHistory(plugInPort.getCloudService().getCurrentUsername(), + plugInPort.getCloudService().getCurrentToken(), plugInPort.getCloudService().getMachineId(), + FileUtils.extractFileName(plugInPort.getCurrentFileName())); + } + public static final String ASSISTANT = "assistant"; public static final String SYSTEM = "system"; public static final String USER = "user"; diff --git a/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/CloudException.java b/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/CloudException.java similarity index 95% rename from diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/CloudException.java rename to diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/CloudException.java index f0525276..c12ad214 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/CloudException.java +++ b/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/CloudException.java @@ -19,7 +19,7 @@ along with DIYLC. If not, see . */ -package org.diylc.plugins.cloud.presenter; +package org.diylc.plugins.cloud.service; public class CloudException extends Exception { diff --git a/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/CloudListener.java b/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/CloudListener.java similarity index 95% rename from diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/CloudListener.java rename to diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/CloudListener.java index df44432e..ad45b6d5 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/CloudListener.java +++ b/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/CloudListener.java @@ -19,7 +19,7 @@ along with DIYLC. If not, see . */ -package org.diylc.plugins.cloud.presenter; +package org.diylc.plugins.cloud.service; public interface CloudListener { diff --git a/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/CloudPresenter.java b/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/CloudService.java similarity index 93% rename from diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/CloudPresenter.java rename to diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/CloudService.java index 9efb0c08..739f2f95 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/CloudPresenter.java +++ b/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/CloudService.java @@ -19,7 +19,7 @@ along with DIYLC. If not, see . */ -package org.diylc.plugins.cloud.presenter; +package org.diylc.plugins.cloud.service; import java.io.File; import java.io.FileOutputStream; @@ -37,6 +37,8 @@ import org.diylc.appframework.miscutils.ConfigurationManager; import com.diyfever.httpproxy.PhpFlatProxy; import com.diyfever.httpproxy.ProxyFactory; +import org.diylc.common.EventType; +import org.diylc.common.IPlugInPort; import org.diylc.common.PropertyWrapper; import org.diylc.plugins.cloud.model.CommentEntity; import org.diylc.plugins.cloud.model.IServiceAPI; @@ -50,17 +52,16 @@ import org.diylc.presenter.ComponentProcessor; * * @author Branislav Stojkovic */ -public class CloudPresenter { +public class CloudService { - public static final CloudPresenter Instance = new CloudPresenter(); - private static String USERNAME_KEY = "cloud.Username"; private static String TOKEN_KEY = "cloud.token"; private static String ERROR = "Error"; - private final static Logger LOG = Logger.getLogger(CloudPresenter.class); + private final static Logger LOG = Logger.getLogger(CloudService.class); private static final Object SUCCESS = "Success"; + private final IPlugInPort plugInPort; private IServiceAPI service; private String serviceUrl; @@ -69,7 +70,9 @@ public class CloudPresenter { private boolean loggedIn = false; - private CloudPresenter() {} + public CloudService(IPlugInPort plugInPort) { + this.plugInPort = plugInPort; + } private IServiceAPI getService() { if (service == null) { @@ -99,6 +102,7 @@ public class CloudPresenter { ConfigurationManager.getInstance().writeValue(USERNAME_KEY, username); ConfigurationManager.getInstance().writeValue(TOKEN_KEY, res); this.loggedIn = true; + this.plugInPort.getMessageDispatcher().dispatchMessage(EventType.CLOUD_LOGGED_IN); return true; } } @@ -121,6 +125,7 @@ public class CloudPresenter { } else { LOG.info("Login success"); this.loggedIn = true; + this.plugInPort.getMessageDispatcher().dispatchMessage(EventType.CLOUD_LOGGED_IN); return true; } } else @@ -130,6 +135,7 @@ public class CloudPresenter { public void logOut() { LOG.info("Logged out"); ConfigurationManager.getInstance().writeValue(TOKEN_KEY, null); + this.plugInPort.getMessageDispatcher().dispatchMessage(EventType.CLOUD_LOGGED_OUT); this.loggedIn = false; } diff --git a/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/NotConnectedException.java b/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/NotConnectedException.java similarity index 95% rename from diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/NotConnectedException.java rename to diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/NotConnectedException.java index 96835cb8..9650a1de 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/NotConnectedException.java +++ b/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/NotConnectedException.java @@ -19,7 +19,7 @@ along with DIYLC. If not, see . */ -package org.diylc.plugins.cloud.presenter; +package org.diylc.plugins.cloud.service; public class NotConnectedException extends Exception { diff --git a/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/NotExistsException.java b/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/NotExistsException.java similarity index 95% rename from diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/NotExistsException.java rename to diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/NotExistsException.java index 6c812b8e..27cef8b9 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/NotExistsException.java +++ b/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/NotExistsException.java @@ -19,7 +19,7 @@ along with DIYLC. If not, see . */ -package org.diylc.plugins.cloud.presenter; +package org.diylc.plugins.cloud.service; public class NotExistsException extends Exception { diff --git a/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/NotLoggedInException.java b/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/NotLoggedInException.java similarity index 95% rename from diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/NotLoggedInException.java rename to diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/NotLoggedInException.java index 94267e3a..17bd2614 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/NotLoggedInException.java +++ b/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/NotLoggedInException.java @@ -19,7 +19,7 @@ along with DIYLC. If not, see . */ -package org.diylc.plugins.cloud.presenter; +package org.diylc.plugins.cloud.service; public class NotLoggedInException extends Exception { diff --git a/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/SearchSession.java b/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/SearchSession.java similarity index 78% rename from diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/SearchSession.java rename to diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/SearchSession.java index e92f912b..6c0b836a 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/presenter/SearchSession.java +++ b/diylc/diylc-core/src/main/java/org/diylc/plugins/cloud/service/SearchSession.java @@ -19,10 +19,11 @@ along with DIYLC. If not, see . */ -package org.diylc.plugins.cloud.presenter; +package org.diylc.plugins.cloud.service; import java.util.List; +import org.diylc.common.IPlugInPort; import org.diylc.plugins.cloud.model.ProjectEntity; /** @@ -34,7 +35,8 @@ import org.diylc.plugins.cloud.model.ProjectEntity; * @author Branislav Stojkovic */ public class SearchSession { - + + private final IPlugInPort plugInPort; private String searchFor; private String category; private String sort; @@ -43,7 +45,8 @@ public class SearchSession { private int currentPage; private List currentResults; - public SearchSession() { + public SearchSession(IPlugInPort plugInPort) { + this.plugInPort = plugInPort; } public List startSession(String searchFor, String category, String sort) throws CloudException { @@ -52,7 +55,7 @@ public class SearchSession { this.sort = sort; this.currentPage = 1; - return currentResults = CloudPresenter.Instance.search(searchFor, category, sort, currentPage, itemsPerPage); + return currentResults = plugInPort.getCloudService().search(searchFor, category, sort, currentPage, itemsPerPage); } public boolean hasMoreData() { @@ -61,6 +64,6 @@ public class SearchSession { public List requestMoreData() throws CloudException { currentPage++; - return currentResults = CloudPresenter.Instance.search(searchFor, category, sort, currentPage, itemsPerPage); + return currentResults = plugInPort.getCloudService().search(searchFor, category, sort, currentPage, itemsPerPage); } } diff --git a/diylc/diylc-core/src/main/java/org/diylc/presenter/Presenter.java b/diylc/diylc-core/src/main/java/org/diylc/presenter/Presenter.java index 30c725c1..c43afe2c 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/presenter/Presenter.java +++ b/diylc/diylc-core/src/main/java/org/diylc/presenter/Presenter.java @@ -47,7 +47,6 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import javax.swing.JOptionPane; import org.apache.log4j.Logger; -import org.diylc.appframework.miscutils.IConfigListener; import org.diylc.appframework.miscutils.IConfigurationManager; import org.diylc.appframework.miscutils.Utils; import org.diylc.appframework.simplemq.MessageDispatcher; @@ -78,6 +77,8 @@ import org.diylc.netlist.Netlist; import org.diylc.netlist.AbstractNetlistAnalyzer; import org.diylc.netlist.NetlistBuilder; import org.diylc.netlist.NetlistException; +import org.diylc.plugins.chatbot.service.ChatbotService; +import org.diylc.plugins.cloud.service.CloudService; import org.diylc.serialization.ProjectFileManager; import org.diylc.test.DIYTest; import org.diylc.test.Snapshot; @@ -2810,7 +2811,27 @@ public class Presenter implements IPlugInPort { messageDispatcher.dispatchMessage(EventType.STATUS_MESSAGE_CHANGED); } - protected MessageDispatcher getMessageDispatcher() { + private CloudService cloudService; + + @Override + public CloudService getCloudService() { + if (cloudService == null) { + cloudService = new CloudService(this); + } + return cloudService; + } + + private ChatbotService chatbotService; + + @Override + public ChatbotService getChatbotService() { + if (chatbotService == null) { + chatbotService = new ChatbotService(this); + } + return chatbotService; + } + + public MessageDispatcher getMessageDispatcher() { return messageDispatcher; } } diff --git a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/chatbot/ChatbotPane.java b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/chatbot/ChatbotPane.java index e7516a73..b60ece6f 100644 --- a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/chatbot/ChatbotPane.java +++ b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/chatbot/ChatbotPane.java @@ -3,14 +3,16 @@ package org.diylc.swing.plugins.chatbot; import org.apache.log4j.Logger; import org.diylc.common.IPlugInPort; import org.diylc.common.ITask; -import org.diylc.plugins.chatbot.presenter.ChatbotPresenter; -import org.diylc.plugins.cloud.presenter.CloudPresenter; +import org.diylc.plugins.chatbot.model.ChatMessageEntity; +import org.diylc.plugins.chatbot.model.SubscriptionEntity; +import org.diylc.plugins.chatbot.service.ChatbotService; +import org.diylc.plugins.cloud.service.NotLoggedInException; import org.diylc.swing.ISwingUI; import javax.swing.*; import java.awt.*; -import java.io.File; -import java.util.Random; +import java.util.List; +import java.util.Objects; public class ChatbotPane extends JPanel { @@ -22,22 +24,32 @@ public class ChatbotPane extends JPanel { private static final Font MONOSPACED_FONT = new Font("Monospaced", Font.PLAIN, 12); private static final Color TERMINAL_BG = new Color(40, 40, 40); private static final Color TERMINAL_FG = new Color(200, 200, 200); + public static final String HTML_STYLE = String.format( + "", MONOSPACED_FONT.getFamily(), + MONOSPACED_FONT.getSize(), TERMINAL_FG.getRed(), TERMINAL_FG.getGreen(), + TERMINAL_FG.getBlue(), TERMINAL_BG.getRed(), TERMINAL_BG.getGreen(), TERMINAL_BG.getBlue()); private static final Color PROMPT_BG = new Color(60, 60, 60); // Slightly brighter than TERMINAL_BG private ISwingUI swingUI; private IPlugInPort plugInPort; - private ChatbotPresenter chatbotPresenter; + private ChatbotService chatbotService; private JTextArea promptArea; private JEditorPane chatEditorPane; private JButton askButton; private JButton clearButton; + private boolean loggedIn = false; + private String projectFileName = null; + public ChatbotPane(ISwingUI swingUI, IPlugInPort plugInPort) { super(); this.swingUI = swingUI; this.plugInPort = plugInPort; - this.chatbotPresenter = new ChatbotPresenter(plugInPort); + this.chatbotService = new ChatbotService(plugInPort); setName("AI Assistant"); // Set panel background color @@ -134,7 +146,7 @@ public class ChatbotPane extends JPanel { promptArea.setPreferredSize(new Dimension(200, desiredHeight)); // Add placeholder text behavior - final String placeholder = "Type your question here..."; + final String placeholder = "Ask me anything"; promptArea.setText(placeholder); promptArea.setForeground(new Color(128, 128, 128)); // Dimmer text for placeholder @@ -188,6 +200,41 @@ public class ChatbotPane extends JPanel { return promptArea; } + public void refreshChat() { + boolean currentLoggedIn = plugInPort.getCloudService().isLoggedIn(); + String currentProjectFileName = plugInPort.getCurrentFileName(); + + if (this.loggedIn == currentLoggedIn && Objects.equals(currentProjectFileName, this.projectFileName)) + return; + + this.loggedIn = currentLoggedIn; + this.projectFileName = currentProjectFileName; + + resetChat(); + try { + SubscriptionEntity subscriptionInfo = plugInPort.getChatbotService().getSubscriptionInfo(); + appendSection(ChatbotService.SYSTEM, "Subscribed to " + subscriptionInfo.getTier() + + " tier with " + subscriptionInfo.getRemainingCredits() + " remaining credits."); + } catch (NotLoggedInException e) { + LOG.error("Error getting subscription info", e); + appendSection(ChatbotService.SYSTEM, "Error getting subscription info"); + } + fetchChatHistory(); + getAskButton().setEnabled(true); + } + + private void fetchChatHistory() { + try { + List chatHistory = plugInPort.getChatbotService().getChatHistory(); + chatHistory.forEach(message -> { + appendSection(ChatbotService.USER, message.getPrompt()); + appendSection(ChatbotService.ASSISTANT, message.getResponse()); + }); + } catch (NotLoggedInException e) { + appendSection(ChatbotService.SYSTEM, "Failed to retrieve chat history."); + } + } + public JEditorPane getChatEditorPane() { if (chatEditorPane == null) { chatEditorPane = new JEditorPane("text/html", ""); @@ -196,30 +243,20 @@ public class ChatbotPane extends JPanel { chatEditorPane.setBackground(TERMINAL_BG); chatEditorPane.setForeground(TERMINAL_FG); chatEditorPane.setCaretColor(TERMINAL_FG); // Make the cursor visible on dark background - - // Set up HTML styling - String htmlStyle = String.format( - "", - MONOSPACED_FONT.getFamily(), - MONOSPACED_FONT.getSize(), - TERMINAL_FG.getRed(), TERMINAL_FG.getGreen(), TERMINAL_FG.getBlue(), - TERMINAL_BG.getRed(), TERMINAL_BG.getGreen(), TERMINAL_BG.getBlue()); - - String sampleChat = chatbotPresenter.getInitialChatContents(); chatEditorPane.setContentType("text/html"); - chatEditorPane.setText(htmlStyle + "
    " + sampleChat + "
    "); + chatEditorPane.setText(HTML_STYLE + ""); } return chatEditorPane; } + private void resetChat() { + String sampleChat = chatbotService.getInitialChatContents(); + + chatEditorPane.setContentType("text/html"); + chatEditorPane.setText(HTML_STYLE + "" + sampleChat + ""); + } + public JButton getAskButton() { if (askButton == null) { askButton = new JButton("Ask"); @@ -229,8 +266,8 @@ public class ChatbotPane extends JPanel { askButton.setBorderPainted(true); askButton.addActionListener(e -> { final String prompt = getPromptArea().getText(); - appendSection(ChatbotPresenter.USER, prompt); - appendSection(ChatbotPresenter.TEMPORARY, "Waiting for the response..."); + appendSection(ChatbotService.USER, prompt); + appendSection(ChatbotService.TEMPORARY, "Waiting for the response..."); getPromptArea().setText(null); @@ -240,19 +277,19 @@ public class ChatbotPane extends JPanel { @Override public String doInBackground() throws Exception { - return chatbotPresenter.promptChatbot(prompt); + return chatbotService.promptChatbot(prompt); } @Override public void failed(Exception e) { - appendSection(ChatbotPresenter.SYSTEM, "Failed to retrieve the response from the server. Error: " + e.getMessage()); + appendSection(ChatbotService.SYSTEM, "Failed to retrieve the response from the server."); LOG.error("Failed to retrieve the response from the server", e); getClearButton().setEnabled(true); } @Override public void complete(String result) { - appendSection(ChatbotPresenter.ASSISTANT, result); + appendSection(ChatbotService.ASSISTANT, result); getClearButton().setEnabled(true); } }, false); @@ -261,7 +298,7 @@ public class ChatbotPane extends JPanel { return askButton; } - private void appendSection(String style, String insertText) { + void appendSection(String style, String insertText) { String text = getChatEditorPane().getText(); // remove any temporary divs String regex = "(?s)]*>.*?\\s*
    \\s*"; @@ -281,6 +318,29 @@ public class ChatbotPane extends JPanel { clearButton.setForeground(TERMINAL_FG); clearButton.setFocusPainted(false); clearButton.setBorderPainted(true); + clearButton.addActionListener(e -> { + + swingUI.executeBackgroundTask(new ITask() { + + @Override + public Void doInBackground() throws Exception { + chatbotService.deleteChatHistory(); + return null; + } + + @Override + public void failed(Exception e) { + appendSection(ChatbotService.SYSTEM, "Failed to delete chat history from the server."); + LOG.error("Failed to delete chat history from the server", e); + getClearButton().setEnabled(true); + } + + @Override + public void complete(Void result) { + resetChat(); + } + }, false); + }); } return clearButton; } diff --git a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/chatbot/ChatbotPlugin.java b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/chatbot/ChatbotPlugin.java index 5ede45eb..81c1a30a 100644 --- a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/chatbot/ChatbotPlugin.java +++ b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/chatbot/ChatbotPlugin.java @@ -26,15 +26,11 @@ import org.diylc.common.BadPositionException; import org.diylc.common.EventType; import org.diylc.common.IPlugIn; import org.diylc.common.IPlugInPort; -import org.diylc.core.IDIYComponent; -import org.diylc.core.Project; -import org.diylc.plugins.cloud.presenter.CloudPresenter; import org.diylc.swing.ISwingUI; import org.diylc.swing.plugins.config.ConfigPlugin; import javax.swing.*; import java.util.EnumSet; -import java.util.Set; public class ChatbotPlugin implements IPlugIn { @@ -47,31 +43,44 @@ public class ChatbotPlugin implements IPlugIn { public ChatbotPlugin(ISwingUI swingUI) { super(); this.swingUI = swingUI; + + // Delay a test of logged in state to give it time to complete + Timer timer = new Timer(2000, e -> { + if (!plugInPort.getCloudService().isLoggedIn()) { + getChatbotPane().refreshChat(); + } + }); + timer.setRepeats(false); // Make it one-shot + timer.start(); } @Override public EnumSet getSubscribedEventTypes() { return EnumSet.of(EventType.FILE_STATUS_CHANGED, EventType.PROJECT_LOADED, - EventType.PROJECT_MODIFIED, EventType.SELECTION_CHANGED); + EventType.PROJECT_MODIFIED, EventType.SELECTION_CHANGED, EventType.CLOUD_LOGGED_IN, + EventType.CLOUD_LOGGED_OUT); } @SuppressWarnings("unchecked") @Override public void processMessage(EventType eventType, Object... params) { -// switch (eventType) { -// case PROJECT_MODIFIED: + switch (eventType) { + case PROJECT_MODIFIED: // getChatbotPane().setComponents(((Project) params[1]).getComponents(), // plugInPort.getSelectedComponents()); -// break; -// case PROJECT_LOADED: -// getChatbotPane().setComponents(((Project) params[0]).getComponents(), -// plugInPort.getSelectedComponents()); -// break; -// case SELECTION_CHANGED: + break; + case SELECTION_CHANGED: // getChatbotPane().setSelection((Set>) params[0]); -// default: -// break; -// } + break; + case FILE_STATUS_CHANGED: + case PROJECT_LOADED: + case CLOUD_LOGGED_IN: + case CLOUD_LOGGED_OUT: + getChatbotPane().refreshChat(); + break; + default: + break; + } } @Override diff --git a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/CloudPlugIn.java b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/CloudPlugIn.java index bd0d98a1..494e6b5e 100644 --- a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/CloudPlugIn.java +++ b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/CloudPlugIn.java @@ -31,6 +31,7 @@ import javax.imageio.ImageIO; import javax.swing.AbstractAction; import org.apache.log4j.Logger; import org.diylc.appframework.miscutils.InMemoryConfigurationManager; +import org.diylc.plugins.cloud.service.CloudService; import org.diylc.swingframework.ButtonDialog; import org.diylc.common.EventType; @@ -38,8 +39,7 @@ import org.diylc.common.IPlugIn; import org.diylc.common.IPlugInPort; import org.diylc.common.ITask; import org.diylc.core.IView; -import org.diylc.plugins.cloud.presenter.CloudException; -import org.diylc.plugins.cloud.presenter.CloudPresenter; +import org.diylc.plugins.cloud.service.CloudException; import org.diylc.presenter.Presenter; import org.diylc.swing.ISwingUI; import org.diylc.swing.gui.DialogFactory; @@ -63,6 +63,7 @@ public class CloudPlugIn implements IPlugIn { private IPlugInPort plugInPort; private IPlugInPort thumbnailPresenter; private ThumbnailGenerator thumbnailGenerator; + private CloudService cloudService; private LibraryAction libraryAction; @@ -106,6 +107,7 @@ public class CloudPlugIn implements IPlugIn { @Override public void connect(IPlugInPort plugInPort) { this.plugInPort = plugInPort; + this.cloudService = plugInPort.getCloudService(); initialize(); } @@ -115,7 +117,7 @@ public class CloudPlugIn implements IPlugIn { @Override public Boolean doInBackground() throws Exception { - return CloudPresenter.Instance.tryLogInWithToken(); + return cloudService.tryLogInWithToken(); } @Override @@ -244,7 +246,7 @@ public class CloudPlugIn implements IPlugIn { dialog.setVisible(true); if (ButtonDialog.OK.equals(dialog.getSelectedButtonCaption())) { try { - if (CloudPresenter.Instance.logIn(dialog.getUserName(), dialog.getPassword())) { + if (plugInPort.getCloudService().logIn(dialog.getUserName(), dialog.getPassword())) { swingUI .showMessage( "You have successfully logged into the system. You will remain logged in from this machine until logged out.", @@ -277,7 +279,7 @@ public class CloudPlugIn implements IPlugIn { @Override public void actionPerformed(ActionEvent e) { - CloudPresenter.Instance.logOut(); + cloudService.logOut(); loggedOut(); } } @@ -301,7 +303,7 @@ public class CloudPlugIn implements IPlugIn { @Override public Void doInBackground() throws Exception { - CloudPresenter.Instance.createUserAccount(dialog.getUserName(), dialog.getPassword(), dialog.getEmail(), + cloudService.createUserAccount(dialog.getUserName(), dialog.getPassword(), dialog.getEmail(), dialog.getWebsite(), dialog.getBio()); return null; } @@ -335,14 +337,14 @@ public class CloudPlugIn implements IPlugIn { public void actionPerformed(ActionEvent e) { try { final UserEditDialog dialog = - DialogFactory.getInstance().createUserEditDialog(CloudPresenter.Instance.getUserDetails()); + DialogFactory.getInstance().createUserEditDialog(plugInPort.getCloudService().getUserDetails()); dialog.setVisible(true); if (ButtonDialog.OK.equals(dialog.getSelectedButtonCaption())) { swingUI.executeBackgroundTask(new ITask() { @Override public Void doInBackground() throws Exception { - CloudPresenter.Instance.updateUserDetails(dialog.getEmail(), dialog.getWebsite(), dialog.getBio()); + cloudService.updateUserDetails(dialog.getEmail(), dialog.getWebsite(), dialog.getBio()); return null; } @@ -384,7 +386,7 @@ public class CloudPlugIn implements IPlugIn { @Override public Void doInBackground() throws Exception { - CloudPresenter.Instance.updatePassword(dialog.getOldPassword(), dialog.getNewPassword()); + cloudService.updatePassword(dialog.getOldPassword(), dialog.getNewPassword()); return null; } @@ -431,7 +433,7 @@ public class CloudPlugIn implements IPlugIn { public String[] doInBackground() throws Exception { LOG.debug("Uploading from " + file.getAbsolutePath()); thumbnailPresenter.loadProjectFromFile(file.getAbsolutePath()); - return CloudPresenter.Instance.getCategories(); + return cloudService.getCategories(); } @Override @@ -448,7 +450,7 @@ public class CloudPlugIn implements IPlugIn { @Override public Void doInBackground() throws Exception { - CloudPresenter.Instance.uploadProject(dialog.getName(), dialog.getCategory(), dialog + cloudService.uploadProject(dialog.getName(), dialog.getCategory(), dialog .getDescription(), dialog.getKeywords(), plugInPort.getCurrentVersionNumber().toString(), thumbnailFile, file, null); return null; diff --git a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/CommentDialog.java b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/CommentDialog.java index 04e6cbd0..e6f5b136 100644 --- a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/CommentDialog.java +++ b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/CommentDialog.java @@ -37,11 +37,11 @@ import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JTextArea; +import org.diylc.common.IPlugInPort; import org.diylc.common.ITask; import org.diylc.core.IView; import org.diylc.plugins.cloud.model.CommentEntity; import org.diylc.plugins.cloud.model.ProjectEntity; -import org.diylc.plugins.cloud.presenter.CloudPresenter; import org.diylc.swing.ISimpleView; import org.diylc.swing.gui.components.HTMLTextArea; @@ -57,6 +57,7 @@ public class CommentDialog extends JDialog { private static final long serialVersionUID = 1L; + private final IPlugInPort plugInPort; private ProjectEntity project; private List comments; @@ -69,8 +70,9 @@ public class CommentDialog extends JDialog { private ISimpleView cloudUI; - public CommentDialog(ISimpleView cloudUI, ProjectEntity project, List comments) { + public CommentDialog(ISimpleView cloudUI, IPlugInPort plugInPort, ProjectEntity project, List comments) { super(cloudUI.getOwnerFrame(), "Comments on " + project.getName()); + this.plugInPort = plugInPort; this.project = project; this.comments = comments; this.cloudUI = cloudUI; @@ -79,7 +81,7 @@ public class CommentDialog extends JDialog { pack(); setLocationRelativeTo(cloudUI.getOwnerFrame()); setModal(true); - if (!CloudPresenter.Instance.isLoggedIn()) { + if (!plugInPort.getCloudService().isLoggedIn()) { getReplyArea().setEnabled(false); getReplyArea().setText("Must be logged in to reply."); getSendButton().setEnabled(false); @@ -162,7 +164,7 @@ public class CommentDialog extends JDialog { @Override public Void doInBackground() throws Exception { - CloudPresenter.Instance.postComment(project.getId(), comment); + plugInPort.getCloudService().postComment(project.getId(), comment); return null; } @@ -176,7 +178,7 @@ public class CommentDialog extends JDialog { getReplyArea().setText(""); CommentEntity newComment = new CommentEntity(); newComment.setPostedAt(JUST_NOW); - newComment.setUsername(CloudPresenter.Instance.getCurrentUsername()); + newComment.setUsername(plugInPort.getCloudService().getCurrentUsername()); newComment.setComment(comment); addComment(newComment).requestFocusInWindow(); getListPanel().revalidate(); diff --git a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/browser/CloudBrowserFrame.java b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/browser/CloudBrowserFrame.java index 503b0c22..1a6a2e4d 100644 --- a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/browser/CloudBrowserFrame.java +++ b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/browser/CloudBrowserFrame.java @@ -45,8 +45,7 @@ import org.diylc.common.IPlugInPort; import org.diylc.common.ITask; import org.diylc.core.IView; import org.diylc.plugins.cloud.model.ProjectEntity; -import org.diylc.plugins.cloud.presenter.CloudPresenter; -import org.diylc.plugins.cloud.presenter.SearchSession; +import org.diylc.plugins.cloud.service.SearchSession; import org.diylc.swing.ISimpleView; import org.diylc.swing.ISwingUI; import org.diylc.utils.IconLoader; @@ -84,7 +83,7 @@ public class CloudBrowserFrame extends JFrame implements ISimpleView { this.setIconImage(IconLoader.Cloud.getImage()); this.setPreferredSize(new Dimension(700, 640)); this.plugInPort = plugInPort; - this.searchSession = new SearchSession(); + this.searchSession = new SearchSession(plugInPort); setContentPane(getSearchPanel()); this.pack(); @@ -103,7 +102,9 @@ public class CloudBrowserFrame extends JFrame implements ISimpleView { @Override public Pair doInBackground() throws Exception { - return new Pair(CloudPresenter.Instance.getCategories(), CloudPresenter.Instance.getSortings()); + return new Pair( + plugInPort.getCloudService().getCategories(), + plugInPort.getCloudService().getSortings()); } @Override diff --git a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/browser/ResultsScrollPanel.java b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/browser/ResultsScrollPanel.java index bceee21a..8154c55b 100644 --- a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/browser/ResultsScrollPanel.java +++ b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/browser/ResultsScrollPanel.java @@ -59,8 +59,7 @@ import org.diylc.common.PropertyWrapper; import org.diylc.core.IView; import org.diylc.plugins.cloud.model.CommentEntity; import org.diylc.plugins.cloud.model.ProjectEntity; -import org.diylc.plugins.cloud.presenter.CloudPresenter; -import org.diylc.plugins.cloud.presenter.SearchSession; +import org.diylc.plugins.cloud.service.SearchSession; import org.diylc.presenter.Presenter; import org.diylc.swing.ISimpleView; import org.diylc.swing.ISwingUI; @@ -234,7 +233,7 @@ public class ResultsScrollPanel extends JScrollPane { @Override public List doInBackground() throws Exception { - return CloudPresenter.Instance.getComments(project.getId()); + return plugInPort.getCloudService().getComments(project.getId()); } @Override @@ -245,7 +244,7 @@ public class ResultsScrollPanel extends JScrollPane { @Override public void complete(List result) { - CommentDialog dialog = new CommentDialog(cloudUI, project, result); + CommentDialog dialog = new CommentDialog(cloudUI, plugInPort, project, result); dialog.setVisible(true); } @@ -343,7 +342,7 @@ public class ResultsScrollPanel extends JScrollPane { editButton.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - List projectProperties = CloudPresenter.Instance.getProjectProperties(project); + List projectProperties = plugInPort.getCloudService().getProjectProperties(project); PropertyEditorDialog editor = DialogFactory.getInstance().createPropertyEditorDialog(cloudUI.getOwnerFrame(), projectProperties, "Edit Published Project", true); @@ -364,8 +363,8 @@ public class ResultsScrollPanel extends JScrollPane { @Override public ProjectEntity doInBackground() throws Exception { - CloudPresenter.Instance.updateProjectDetails(project, plugInPort.getCurrentVersionNumber().toString()); - return CloudPresenter.Instance.fetchUserUploads(project.getId()).get(0); + plugInPort.getCloudService().updateProjectDetails(project, plugInPort.getCurrentVersionNumber().toString()); + return plugInPort.getCloudService().fetchUserUploads(project.getId()).get(0); } @Override @@ -418,11 +417,11 @@ public class ResultsScrollPanel extends JScrollPane { thumbnailPresenter.loadProjectFromFile(file.getAbsolutePath()); final File thumbnailFile = File.createTempFile("upload-thumbnail", ".png"); if (ImageIO.write(thumbnailGenerator.getThumbnail(), "png", thumbnailFile)) { - CloudPresenter.Instance.replaceProjectFile( + plugInPort.getCloudService().replaceProjectFile( plugInPort.getCurrentVersionNumber().toString(), thumbnailFile, file, project.getId()); return new Pair(thumbnailGenerator.getThumbnail(), - CloudPresenter.Instance.fetchUserUploads(project.getId()).get(0)); + plugInPort.getCloudService().fetchUserUploads(project.getId()).get(0)); } else { cloudUI.showMessage( "Could not prepare temporary files to be uploaded to the cloud.", @@ -478,7 +477,7 @@ public class ResultsScrollPanel extends JScrollPane { @Override public Void doInBackground() throws Exception { - CloudPresenter.Instance.deleteProject(project.getId()); + plugInPort.getCloudService().deleteProject(project.getId()); return null; } diff --git a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/browser/UploadManagerFrame.java b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/browser/UploadManagerFrame.java index 9c55277c..6b44b88c 100644 --- a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/browser/UploadManagerFrame.java +++ b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/cloud/view/browser/UploadManagerFrame.java @@ -33,7 +33,6 @@ import org.diylc.common.IPlugInPort; import org.diylc.common.ITask; import org.diylc.core.IView; import org.diylc.plugins.cloud.model.ProjectEntity; -import org.diylc.plugins.cloud.presenter.CloudPresenter; import org.diylc.swing.ISimpleView; import org.diylc.swing.ISwingUI; import org.diylc.utils.IconLoader; @@ -80,7 +79,7 @@ public class UploadManagerFrame extends JFrame implements ISimpleView { @Override public List doInBackground() throws Exception { - return CloudPresenter.Instance.fetchUserUploads(null); + return plugInPort.getCloudService().fetchUserUploads(null); } @Override