include restore plugin in sdk core

pull/333/head
nightwing 2016-07-22 01:58:04 +04:00
rodzic b96a51bd31
commit cf41234af0
3 zmienionych plików z 594 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,259 @@
#c9_ide_restore {
display: none;
z-index: 1000000;
position: absolute;
height: 100%;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
#c9_ide_restore .timeout a {
color: #FFDE75;
text-decoration: none;
}
#c9_ide_restore .timeout {
position: relative;
background: #DA7A30;
z-index: 10000000;
color: white;
padding: 5px;
border-radius: 3px;
margin: 10px;
text-align: center;
display: none;
}
/* progress 3C7B0D*/
#restoring {
font-style: normal;
height: 100%;
width: 100%;
position: fixed;
text-align: center;
z-index: 100000;
left: 0;
top: 0;
.font-smoothing(~"antialiased !important");
background: white url("@{image-path}/loadingbgrepeat.png");
background-size: 1px 8px;
}
.dark #restoring{
background: black url("@{image-path}/loadingbgrepeat_dark.png");
background-size: 1px 8px;
}
#restoring .loading-progress {
font-size: 31px;
color: #4A8532;
height: 37px;
position: relative;
margin: 252px 0 0 0;
top: 30%;
}
#restoring .loading-msg {
color: #717171;
.font-smoothing(true);
margin: 58px 0 10px;
}
#restoring .loading-details{
margin: 3px 0 0 0;
font-size: 14px;
color: #858E91;
.font-smoothing(true);
font-weight: bold;
}
.stickynote {
position: absolute;
top: 30%;
left: 50%;
margin: 0px -261px;
z-index : 10000000;
.transform(~"rotate(2deg)");
}
.stickynote.casual{
bottom: 50px;
right: 50px;
left: auto;
top: auto;
margin: 0;
}
.stickynote .paper {
color: black;
width: 284px;
/*color: #f1f1f1;*/
background: #FFDE75;
padding: 25px 20px 10px 20px;
box-shadow: 1px 1px 15px rgba(0,0,0,0.12);
// font-family : Tahoma;
font-size : 15px;
text-align : left;
.font-smoothing(true);
}
.stickynote strong {
font-size: 17px;
}
.stickynote a.restore-upsell {
text-decoration: none;
display: inline-block;
padding: 5px 10px 8px 10px;
background: #39A6D7;
border-radius: 5px;
color: white;
margin-bottom: -10px;
}
.stickynote a.restore-upsell:hover {
background: #0FB6FF;
}
.stickynote .tape {
position: absolute;
top: -15px;
right: 80px;
width: 130px;
height: 35px;
background-color: rgba(255, 255, 255, 0.6);
border-left: 1px dashed rgba(0, 0, 0, 0.1);
border-right: 1px dashed rgba(0, 0, 0, 0.1);
.box-shadow(~"0px 0px 1px 0px rgba(204, 204, 204, 0.28)");
.transform(~"rotate(-2deg) skew(0,0) translate(0%,-5px)");
}
.stickynote .left-shadow {
width: 140px;
height: 140px;
bottom: -5px;
left: -12px;
position: absolute;
z-index: -6;
display: inline-block;
.box-shadow(~"-10px -10px 10px rgba(0, 0, 0, 0.12)");
.transform(~"scale(1) rotate(274deg) translate(20px, 25px) skew(9deg, 0deg)");
}
.stickynote .right-shadow {
width: 140px;
height: 140px;
bottom: -13px;
right: -4px;
position: absolute;
z-index: -6;
display: inline-block;
.box-shadow(~"-10px -10px 10px rgba(0, 0, 0, 0.12)");
.transform(~"scale(1) rotate(184deg) translate(20px, 25px) skew(9deg, 0deg)");
}
/*
Copyright (c) 2010-2012 Ivan Vanderbyl
Originally found at http://ivan.ly/ui
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/* Webkit animation keyframes */
@-webkit-keyframes animate-stripes {
to {
background-position: 0 0;
}
from {
background-position: 44px 0;
}
}
@-moz-keyframes animate-stripes {
to {
background-position: 0 0;
}
from {
background-position: 36px 0;
}
}
/* Bar which is placed behind the progress */
.ui-progress-bar {
/* Usual setup stuff */
position: relative;
width: 240px;
margin: 15px auto 10px;
height: 8px;
/* Pad right so we don't cover the borders when fully progressed */
/* For browser that don't support gradients, we'll set a blanket background colour */
background-color: rgba(157, 167, 171, 0.42);
.border-radius(~"10px");
}
.ui-progress-bar.blue .ui-progress {
background-color: #339BB9!important;
border: 1px solid #287a91;
}
.ui-progress-bar.error .ui-progress {
background-color: #C43C35 !important;
border: 1px solid #9c302a;
}
.ui-progress-bar.warning .ui-progress {
background-color: #D9B31A!important;
border: 1px solid #ab8d15;
}
.ui-progress-bar.success .ui-progress {
background-color: #57A957!important;
border: 1px solid #458845;
}
.ui-progress-bar.transition .ui-progress {
.transition(~"background-color 0.5s ease-in, border-color 1.5s ease-out, box-shadow 1.5s ease-out")
}
.ui-progress-bar .ui-progress {
/* Usual setup stuff */
position: relative;
display: block;
overflow: hidden;
/* Height should be 2px less than .ui-progress-bar so as to not cover borders and give it a look of being inset */
height: 8px;
/* Rounds the ends, we specify an excessive amount to make sure they are completely rounded */
/* Adjust to your liking, and don't forget to adjust to the same amount in .ui-progress-bar */
.border-radius(~"10px");
/* Webkit background stripes and gradient */
background: -webkit-gradient(linear, 0 0, 44 44, color-stop(0, rgba(0, 0, 0, 0.17)), color-stop(0.25, rgba(0, 0, 0, 0.17)), color-stop(0.26, rgba(0, 0, 0, 0)), color-stop(0.5, rgba(0, 0, 0, 0)), color-stop(0.51, rgba(0, 0, 0, 0.17)), color-stop(0.75, rgba(0, 0, 0, 0.17)), color-stop(0.76, rgba(0, 0, 0, 0)), color-stop(1, rgba(0, 0, 0, 0))), -webkit-gradient(linear, left bottom, left top, color-stop(0, rgba(0, 0, 0, 0)), color-stop(1, rgba(0, 0, 0, 0.35))), #EAF9FF;
background: -moz-repeating-linear-gradient(top left -30deg, rgba(0, 0, 0, 0.17), rgba(0, 0, 0, 0.17) 15px, rgba(0, 0, 0, 0) 15px, rgba(0, 0, 0, 0) 30px), -moz-linear-gradient(rgba(0, 0, 0, 0.25) 0%, rgba(0, 0, 0, 0) 100%), #EAF9FF;
/* Set the background size so the stripes work correctly */
-webkit-background-size: 44px 44px;
-moz-background-size: 36px 36px;
/* Animate */
-moz-animation: animate-stripes 2s linear infinite;
-webkit-animation: animate-stripes 2s linear infinite;
-o-animation: animate-stripes 2s linear infinite;
-ms-animation: animate-stripes 2s linear infinite;
-khtml-animation: animate-stripes 2s linear infinite;
animation: animate-stripes 2s linear infinite;
/* Style status label */
top:0px;
left:0px;
}
.dark .ui-progress-bar .ui-progress {
background: -webkit-gradient(linear, 0 0, 44 44, color-stop(0, rgba(0, 0, 0, 0.17)), color-stop(0.25, rgba(0, 0, 0, 0.17)), color-stop(0.26, rgba(0, 0, 0, 0)), color-stop(0.5, rgba(0, 0, 0, 0)), color-stop(0.51, rgba(0, 0, 0, 0.17)), color-stop(0.75, rgba(0, 0, 0, 0.17)), color-stop(0.76, rgba(0, 0, 0, 0)), color-stop(1, rgba(0, 0, 0, 0))), -webkit-gradient(linear, left bottom, left top, color-stop(0, rgba(0, 0, 0, 0)), color-stop(1, rgba(0, 0, 0, 0.35))), #4ACBFD;
background: -moz-repeating-linear-gradient(top left -30deg, rgba(0, 0, 0, 0.17), rgba(0, 0, 0, 0.17) 15px, rgba(0, 0, 0, 0) 15px, rgba(0, 0, 0, 0) 30px), -moz-linear-gradient(rgba(0, 0, 0, 0.25) 0%, rgba(0, 0, 0, 0) 100%), #4ACBFD;
/* Set the background size so the stripes work correctly */
-webkit-background-size: 44px 44px;
-moz-background-size: 36px 36px;
}

Wyświetl plik

@ -0,0 +1,37 @@
<div id="c9_ide_restore">
<div class="timeout">This is taking longer than expected. If you think there might be an issue please contact <a href="https://c9.io/support">support</a>.</div>
<div id="loadingide"></div>
<div class="stickynote">
<div class="tape"></div>
<div class="left-shadow"></div>
<div class="right-shadow"></div>
<div class="paper">
<strong>What's going on here?</strong>
<p>
We create a separate virtual machine for each workspace.
In order to provide a free
service for everyone, we hibernate workspaces of
<nobr>non-premium</nobr> users after about one week of inactivity.
This is because the virtual machines constantly use resources even if
the workspace is not actively used.
<p>
Please wait a moment while we wake up your workspace. It will
be just as you left it.
<p>
<a href="/upgrade/webide" target="_blank">Upgrade to premium</a> to make sure your workspace never
goes into hibernate.
</div>
</div>
<div id="restoring">
<div id="content" class="loading-progress">
<div class="loading-details"></div>
<div class="ui-progress-bar ui-container" id="progress_bar">
<div class="ui-progress" style="width: 100%;">
<!--<span class="ui-label" style="display:none;"></span>-->
</div>
</div>
<div class="loading-msg">Waking up your workspace from hibernation.</div>
</div>
</div>
</div>

Wyświetl plik

@ -0,0 +1,298 @@
define(function(require, exports, module) {
"use strict";
main.consumes = [
"Plugin", "ui", "vfs.endpoint", "vfs", "layout", "anims", "c9",
"c9.analytics", "layout"
];
main.provides = ["restore"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var ui = imports.ui;
var vfs = imports.vfs;
var c9 = imports.c9;
var anims = imports.anims;
var layout = imports.layout;
var endpoint = imports["vfs.endpoint"];
var analytics = imports["c9.analytics"];
/***** Initialization *****/
var plugin = new Plugin("Ajax.org", main.consumes);
var el, msgEl, detailsEl, descriptionEl, stickynoteEl, uiProgress;
var timeoutTimer, timeoutEl;
var MAX_HOT_WORKSPACES = "three";
var TIMEOUT_TIME = 15 * 60 * 1000;
var STATE_CREATED = 1;
var STATE_READY = 2;
var STATE_MIGRATING = 4;
var STATE_MARKED_FOR_ARCHIVE = 20;
var STATE_ARCHIVING = 21;
var STATE_ARCHIVED = 22;
var STATE_MARKED_FOR_RESTORE = 23;
var STATE_RESTORING = 24;
var STATE_RESIZING = 31;
var stateMessages = {};
stateMessages[STATE_CREATED] = "Creating your new workspace";
stateMessages[STATE_READY] = "Starting your workspace";
stateMessages[STATE_MIGRATING] = "Migrating your workspace to our new backend";
stateMessages[STATE_MARKED_FOR_ARCHIVE] =
stateMessages[STATE_ARCHIVING] = "Archiving your workspace";
stateMessages[STATE_ARCHIVED] =
stateMessages[STATE_MARKED_FOR_RESTORE] =
stateMessages[STATE_RESTORING] = "Waking up your workspace from hibernation.";
stateMessages[STATE_RESIZING] = "Resizing your workspace";
var defaultStateMessage = "Opening your workspace";
var description =
"<strong>You could be coding right now</strong>\n" +
"<p>\n" +
"In order to provide a free\n" +
"service for everyone, we stop workspaces after a while.\n" +
"<p>\n" +
"Premium plans offer active workspaces, which ensure that the " + MAX_HOT_WORKSPACES + "\n" +
"most recently used workspaces are never stopped.\n" +
"<p>\n" +
"<a class='restore-upsell' data-link-id='upsell-webide-migrate' href='" + options.ideBaseUrl + "/account/upgrade/webide' target='_blank'>Upgrade to premium now</a>";
var premiumStoppedDescription =
"<strong>Swapping in Workspace</strong>\n" +
"<p>\n" +
"This workspace is not one of your active workspaces and has been stopped.\n" +
"<p>\n" +
"The " + MAX_HOT_WORKSPACES + " most recently used workspaces are never stopped.\n" +
"<p>\n" +
"As part of a team plan you have more active workspaces.\n" +
"<p>\n" +
"<a class='restore-upsell' data-link-id='upsell-teams-migrate' href='" + options.ideBaseUrl + "/account/billing' target='_blank'>Upgrade to team plans now</a>";
var migrateDescription =
"<strong>What's going on here?</strong>\n" +
"<p>\n" +
"We rolled out a completely new backend infrastructure with \n" +
"improved performance and lots of new features.\n" +
"<p>\n" +
"With the new backend you get:\n" +
"<ul>\n" +
"<li>an Ubuntu VM</li>\n" +
"<li>root access using sudo</li>\n" +
"<li>ability to run services</li>\n" +
"<li>ability to install packages</li>\n" +
"</ul>\n" +
"<p>\n" +
"Please wait a moment while we move your workspace. It will\n" +
"be just as you left it.\n";
var premiumDescription =
"<strong>What's going on here?</strong>\n" +
"<p>\n" +
"We're migrating your premium workspace to a new server \n" +
"to ensure optimal performance.\n" +
"<p>\n" +
"Please wait a moment while we move your workspace. It will\n" +
"be just as you left it.\n";
var resizeDescription =
"<strong>What's going on here?</strong>\n" +
"<p>\n" +
"We're resizing your workspace\n" +
"to be exactly as you specified.\n" +
"<p>\n" +
"Please wait a moment while we resize your workspace.\n" +
"It will be just as you left it.\n";
var stateDescriptions = {
free: { casual: [STATE_MIGRATING, STATE_RESIZING] },
premium: { casual: [STATE_MIGRATING, STATE_MARKED_FOR_ARCHIVE, STATE_ARCHIVING, STATE_ARCHIVED, STATE_MARKED_FOR_RESTORE, STATE_RESTORING, STATE_RESIZING] },
};
stateDescriptions.free[STATE_CREATED] = "";
stateDescriptions.free[STATE_READY] = description;
stateDescriptions.free[STATE_MIGRATING] = migrateDescription; // different location
stateDescriptions.free[STATE_MARKED_FOR_ARCHIVE] = description;
stateDescriptions.free[STATE_ARCHIVING] = description;
stateDescriptions.free[STATE_ARCHIVED] = description;
stateDescriptions.free[STATE_MARKED_FOR_RESTORE] = description;
stateDescriptions.free[STATE_RESTORING] = description;
stateDescriptions.free[STATE_RESIZING] = resizeDescription; // different location
stateDescriptions.premium[STATE_CREATED] = "";
stateDescriptions.premium[STATE_READY] = premiumStoppedDescription;
stateDescriptions.premium[STATE_MIGRATING] = migrateDescription; // different location
stateDescriptions.premium[STATE_MARKED_FOR_ARCHIVE] = premiumDescription; // different location
stateDescriptions.premium[STATE_ARCHIVING] = premiumDescription; // different location
stateDescriptions.premium[STATE_ARCHIVED] = premiumDescription; // different location
stateDescriptions.premium[STATE_MARKED_FOR_RESTORE] = premiumDescription; // different location
stateDescriptions.premium[STATE_RESTORING] = premiumDescription; // different location
stateDescriptions.premium[STATE_RESIZING] = resizeDescription; // different location
var loaded = false;
function load() {
if (loaded) return false;
loaded = true;
endpoint.on("restore", showRestore);
vfs.on("connect", hideRestore);
}
var drawn = false;
function draw() {
if (drawn) return false;
drawn = true;
ui.insertCss(require("text!./restore.css"), plugin);
ui.insertHtml(null, require("text!./restore.html"), plugin);
el = document.getElementById("c9_ide_restore");
msgEl = document.querySelector("#c9_ide_restore .loading-msg");
detailsEl = document.querySelector("#c9_ide_restore .loading-details");
descriptionEl = document.querySelector("#c9_ide_restore .paper");
stickynoteEl = document.querySelector("#c9_ide_restore .stickynote");
uiProgress = document.querySelector("#progress_bar .ui-progress");
timeoutEl = document.querySelector("#c9_ide_restore .timeout");
}
/***** Methods *****/
var progress, maxProgress, run = 0, timer;
function animateProgress(progress, callback) {
anims.animate(uiProgress, {
width: progress + "%",
timingFunction: "cubic-bezier(.02, .01, .47, 1)",
duration: "1s"
}, callback);
}
function walk(loopId) {
if (loopId != run) return;
if (progress > 100)
return;
if (progress > maxProgress)
return (timer = setTimeout(walk.bind(null, loopId), 500));
animateProgress(progress++, function(){
timer = setTimeout(walk.bind(null, loopId), 10);
});
}
function showTimeout(){
timeoutEl.style.display = "block";
}
function showRestore(state) {
draw();
c9.startLoadTime = -1;
if (el.style.display != "block") {
uiProgress.style.width = 0;
progress = 6;
maxProgress = 10;
}
var isDark = layout.theme.indexOf("dark") > -1;
if (isDark)
el.classList.add("dark");
else
el.classList.remove("dark");
var descriptions = stateDescriptions[state.premium ? "premium" : "free"];
var description = descriptions[state.projectState || STATE_ARCHIVED];
msgEl.innerText = stateMessages[state.projectState || STATE_ARCHIVED] || defaultStateMessage;
if (description) {
descriptionEl.innerHTML = description;
var link = descriptionEl.querySelector("a.restore-upsell");
if (link)
link.addEventListener("click", trackLink, false);
stickynoteEl.style.display = "block";
if (~descriptions.casual.indexOf(state.projectState || STATE_ARCHIVED))
stickynoteEl.classList.add("casual");
else
stickynoteEl.classList.remove("casual");
}
else {
stickynoteEl.style.display = "none";
}
// we did not receive JSON
if (!state.progress || state.progress.nextProgress == 100)
return hideRestore();
// Display Message to the User
if (!/^Internal/.test(state.progress.message))
detailsEl.innerText = state.progress.message || "";
// Update Progress Bar
maxProgress = Math.max(maxProgress || 0, state.progress.nextProgress);
progress = Math.max(progress || 0, state.progress.progress);
walk(++run);
// Show Restore Screen
el.style.display = "block";
clearTimeout(timeoutTimer);
timeoutTimer = setTimeout(function(){
showTimeout();
}, TIMEOUT_TIME)
}
function trackLink(e) {
var el = e.target;
analytics.track("Clicked Internal Link", {
href: el.href,
linkId: el.dataset.linkId
});
}
function hideRestore() {
if (!el) return;
clearTimeout(timer);
progress = 101;
animateProgress(100, function(){
setTimeout(function(){
anims.animate(el, {
opacity: 0
}, function(){
el.style.display = "none";
el.style.opacity = 1;
timeoutEl.style.display = "";
});
}, 100);
});
}
/***** Lifecycle *****/
plugin.on("load", function(){
load();
});
/***** Register and define API *****/
/**
*
**/
plugin.freezePublicAPI({
show: showRestore,
hide: hideRestore
});
register(null, { "restore" : plugin });
}
});