Skip to content

Commit

Permalink
Added animated loading feedback while container is launching
Browse files Browse the repository at this point in the history
  • Loading branch information
fmichielssen committed Aug 11, 2017
1 parent 81526a4 commit 2b6ce25
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 11 deletions.
33 changes: 24 additions & 9 deletions src/main/java/eu/openanalytics/controllers/AppController.java
Expand Up @@ -26,6 +26,8 @@
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import eu.openanalytics.ShinyProxyApplication;
import eu.openanalytics.services.AppService;
Expand All @@ -40,23 +42,36 @@ public class AppController extends BaseController {
@Inject
AppService appService;

@RequestMapping("/app/*")
@RequestMapping(value="/app/*", method=RequestMethod.GET)
String app(ModelMap map, HttpServletRequest request) {
prepareMap(map, request);

String mapping = dockerService.getMapping(getUserName(request), getAppName(request));

String queryString = request.getQueryString();
if (queryString == null) queryString = "";
else queryString = "?" + queryString;

String mapping = dockerService.getMapping(getUserName(request), getAppName(request), false);
String contextPath = ShinyProxyApplication.getContextPath(environment);
String containerPath = contextPath + "/" + mapping + environment.getProperty("shiny.proxy.landing-page") + queryString;

map.put("container", containerPath);
map.put("appTitle", getAppTitle(request));
map.put("container", buildContainerPath(mapping, request));
map.put("heartbeatRate", environment.getProperty("shiny.proxy.heartbeat-rate", "10000"));
map.put("heartbeatPath", contextPath + "/heartbeat");

return "app";
}

@RequestMapping(value="/app/*", method=RequestMethod.POST)
@ResponseBody
String startApp(HttpServletRequest request) {
String mapping = dockerService.getMapping(getUserName(request), getAppName(request), true);
return buildContainerPath(mapping, request);
}

private String buildContainerPath(String mapping, HttpServletRequest request) {
if (mapping == null) return "";

String queryString = request.getQueryString();
queryString = (queryString == null) ? "" : "?" + queryString;

String contextPath = ShinyProxyApplication.getContextPath(environment);
String containerPath = contextPath + "/" + mapping + environment.getProperty("shiny.proxy.landing-page") + queryString;
return containerPath;
}
}
13 changes: 13 additions & 0 deletions src/main/java/eu/openanalytics/controllers/BaseController.java
Expand Up @@ -40,10 +40,15 @@
import org.springframework.ui.ModelMap;
import org.springframework.util.StreamUtils;

import eu.openanalytics.services.AppService;
import eu.openanalytics.services.UserService;
import eu.openanalytics.services.AppService.ShinyApp;

public abstract class BaseController {

@Inject
AppService appService;

@Inject
UserService userService;

Expand All @@ -70,6 +75,14 @@ protected String getAppName(String uri) {
return appName;
}

protected String getAppTitle(HttpServletRequest request) {
String appName = getAppName(request);
if (appName == null || appName.isEmpty()) return "";
ShinyApp app = appService.getApp(appName);
if (app == null || app.getDisplayName() == null || app.getDisplayName().isEmpty()) return appName;
else return app.getDisplayName();
}

protected void prepareMap(ModelMap map, HttpServletRequest request) {
map.put("title", environment.getProperty("shiny.proxy.title"));
if (logoURI == null) logoURI = toAccessibleURI(environment.getProperty("shiny.proxy.logo-url"));
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/eu/openanalytics/services/DockerService.java
Expand Up @@ -178,10 +178,10 @@ public List<Proxy> listProxies() {
}
}

public String getMapping(String userName, String appName) {
public String getMapping(String userName, String appName, boolean startNew) {
waitForLaunchingProxy(userName, appName);
Proxy proxy = findProxy(userName, appName);
if (proxy == null) {
if (proxy == null && startNew) {
// The user has no proxy yet.
proxy = startProxy(userName, appName);
}
Expand Down
15 changes: 15 additions & 0 deletions src/main/resources/static/css/default.css
Expand Up @@ -48,4 +48,19 @@ body > div#navbar { padding-top: 0px; }

#error {
padding-left: 15px;
}

.loading {
display: none;
position: fixed;
top: 150px;
width: 100%;
z-index: 9999;
background: url(../img/loading.gif) center no-repeat #fff;
}

.loading-txt {
text-align: center;
font-size: 24px;
margin-top: -50px;
}
Binary file added src/main/resources/static/img/loading.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions src/main/resources/templates/app.html
Expand Up @@ -37,6 +37,7 @@

<!-- content -->
<iframe id="shinyframe" th:src="${container}" width="100%"></iframe>
<div class="loading"><div class="loading-txt">Launching <span th:text="${appTitle}"></span>...</div></div>

<script type="text/javascript" th:inline="javascript">
function setShinyframeHeight() {
Expand All @@ -53,6 +54,21 @@
}, [[${heartbeatRate}]]);
};
heartbeat();

$(window).load(function() {
var source = $("#shinyframe").attr("src");
if (source == "") {
$(".loading").show();
$.post(window.location.pathname, function(containerPath) {
$("#shinyframe").attr("src", containerPath);
$(".loading").fadeOut("slow");
}).fail(function(request) {
var newDoc = document.open("text/html", "replace");
newDoc.write(request.responseText);
newDoc.close();
});
}
});
</script>
</body>
</html>

0 comments on commit 2b6ce25

Please sign in to comment.