diff --git a/app/assets/javascripts/editor.js b/app/assets/javascripts/editor.js
index 83035d0e..c7947a2e 100644
--- a/app/assets/javascripts/editor.js
+++ b/app/assets/javascripts/editor.js
@@ -11,6 +11,7 @@ $(function() {
var FILENAME_URL_PLACEHOLDER = '{filename}';
var SUCCESSFULL_PERCENTAGE = 90;
var THEME = 'ace/theme/textmate';
+ var AUTOSAVE_INTERVAL = 15 * 1000;
var editors = [];
var active_file = undefined;
@@ -317,6 +318,23 @@ $(function() {
$('button i.fa-spin').hide();
};
+ var autosaveTimer;
+ var autosaveLabel = $("#autosave-label span");
+
+ var resetSaveTimer = function(){
+ clearTimeout(autosaveTimer);
+ autosaveTimer = setTimeout(autosave, AUTOSAVE_INTERVAL);
+ };
+
+ var autosave = function(){
+ var date = new Date();
+ autosaveLabel.parent().css("visibility", "visible");
+ autosaveLabel.text(date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds());
+ autosaveLabel.text(date.toLocaleTimeString());
+ autosaveTimer = null;
+ createSubmission($('#autosave'), null);
+ }
+
var initializeEditors = function() {
$('.editor').each(function(index, element) {
var editor = ace.edit(element);
@@ -326,6 +344,12 @@ $(function() {
});
}
+
+ // listener for autosave
+ editor.getSession().on("change", function (deltaObject) {
+ resetSaveTimer();
+ });
+
var document = editor.getSession().getDocument();
// insert pre-existing code into editor. we have to use insertLines, otherwise the deltas are not properly added
var file_id = $(element).data('file-id');
@@ -983,6 +1007,13 @@ $(function() {
}
}
+ $(window).on("beforeunload", function() {
+ if(autosaveTimer){
+ autosave();
+ }
+
+ })
+
if ($('#editor').isPresent()) {
if (isBrowserSupported()) {
initializeCodePilot();
diff --git a/app/assets/stylesheets/editor.css.scss b/app/assets/stylesheets/editor.css.scss
index b2ad8f36..efcf1d25 100644
--- a/app/assets/stylesheets/editor.css.scss
+++ b/app/assets/stylesheets/editor.css.scss
@@ -31,7 +31,7 @@ button i.fa-spin {
#editor-buttons {
background-color: #008CBA;
- margin-top: 1em;
+ margin-top: 0;
width: 100%;
button {
@@ -39,7 +39,7 @@ button i.fa-spin {
}
button, .btn-group {
- width: 25%;
+ width: 33.33333%;
}
.btn-group {
@@ -80,3 +80,11 @@ button i.fa-spin {
#results {
display: none;
}
+
+#autosave-label{
+ visibility: hidden;
+ height: 1.6em;
+ text-align: right;
+ color: #777;
+ font-size: 0.8em;
+}
diff --git a/app/models/submission.rb b/app/models/submission.rb
index 70ceece8..16ca74dc 100644
--- a/app/models/submission.rb
+++ b/app/models/submission.rb
@@ -2,7 +2,7 @@ class Submission < ActiveRecord::Base
include Context
include Creation
- CAUSES = %w(assess download file render run save submit test)
+ CAUSES = %w(assess download file render run save submit test autosave)
FILENAME_URL_PLACEHOLDER = '{filename}'
belongs_to :exercise
diff --git a/app/views/exercises/_editor.html.slim b/app/views/exercises/_editor.html.slim
index 0794cb41..986af92d 100644
--- a/app/views/exercises/_editor.html.slim
+++ b/app/views/exercises/_editor.html.slim
@@ -3,9 +3,13 @@
#frames.col-sm-9
- @files.each do |file|
= render('editor_frame', exercise: exercise, file: file)
+ #autosave-label
+ = t('exercises.editor.lastsaved')
+ span
#editor-buttons.btn-group
= render('editor_button', data: {:'data-message-confirm' => t('exercises.editor.confirm_start_over'), :'data-url' => reload_exercise_path(exercise)}, icon: 'fa fa-history', id: 'start-over', label: t('exercises.editor.start_over'))
- = render('editor_button', data: {:'data-message-success' => t('submissions.create.success'), :'data-placement' => 'top', :'data-tooltip' => true}, icon: 'fa fa-save', id: 'save', label: t('exercises.editor.save'), title: t('.tooltips.save'))
+ // = render('editor_button', data: {:'data-message-success' => t('submissions.create.success'), :'data-placement' => 'top', :'data-tooltip' => true}, icon: 'fa fa-save', id: 'save', label: t('exercises.editor.save'), title: t('.tooltips.save'))
+ button style="display:none" id="autosave"
.btn-group
= render('editor_button', disabled: true, icon: 'fa fa-ban', id: 'dummy', label: t('exercises.editor.dummy'))
= render('editor_button', icon: 'fa fa-desktop', id: 'render', label: t('exercises.editor.render'))
diff --git a/config/locales/de.yml b/config/locales/de.yml
index c720077a..e7fe1857 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -170,6 +170,7 @@ de:
destroy_file: Datei löschen
download: Herunterladen
dummy: Keine Aktion
+ lastsaved: 'Zuletzt gespeichert: '
network: 'Während Ihr Code läuft, ist Port %{port} unter folgender Adresse erreichbar: %{address}.'
render: Anzeigen
run: Ausführen
diff --git a/config/locales/en.yml b/config/locales/en.yml
index ee3954d6..52d4ceb3 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -170,6 +170,7 @@ en:
destroy_file: Delete File
download: Download
dummy: No Action
+ lastsaved: 'Last saved: '
network: 'While your code is running, port %{port} is accessible using the following address: %{address}.'
render: Render
run: Run