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