Files
codeocean/app/assets/javascripts/submission_statistics.js
Sebastian Serth 4f8d313da4 Use webpack to deliver newest ACE editor
With this commit, we change the delivery method for the ACE editor from manually copied files to using yarn and webpack. As a side-change, we also modify how the mode is selected through JavaScript instead of Ruby.

Through webpack, the `modePath`, `themePath`, and `workerPath` are automatically determined and working as expected.

Closes #250
2024-03-25 10:00:04 +01:00

151 lines
4.8 KiB
JavaScript

$(document).on('turbolinks:load', function(event) {
var currentSubmission = 0;
var active_file = undefined;
var fileTrees = [];
var editor = undefined;
var fileTypeById = {};
var showActiveFile = function() {
$('tr.active').removeClass('active');
$('tr#submission-' + currentSubmission).addClass('active');
var session = editor.getSession();
var fileType = fileTypeById[active_file.file_type_id];
session.setMode(fileType.editor_mode);
session.setTabSize(fileType.indent_size);
session.setValue(active_file.content);
session.setUseSoftTabs(true);
session.setUseWrapMode(true);
// The event ready.jstree is fired too early and thus doesn't work.
var selectFileInJsTree = function() {
if (!filetree.hasClass('jstree-loading')) {
filetree.jstree("deselect_all");
filetree.jstree("select_node", active_file.file_id);
} else {
setTimeout(selectFileInJsTree, 250);
}
};
filetree = $(fileTrees[currentSubmission]);
selectFileInJsTree();
// Finally change jstree element to prevent flickering
showFileTree(currentSubmission);
};
var initializeFileTree = function() {
$('.files').each(function(index, element) {
const jsTreeConfig = $(element).data('entries')
jsTreeConfig.core.themes = {...jsTreeConfig.core.themes, name: window.getCurrentTheme() === "dark" ? "default-dark" : "default"}
const fileTree = $(element).jstree(jsTreeConfig);
$(element).on('click', 'li.jstree-leaf', function() {
var id = parseInt($(this).attr('id'));
_.each(files[currentSubmission], function(file) {
if (file.file_id === id) {
active_file = file;
}
});
showActiveFile();
});
$(document).on('theme:change', function(event) {
const newColorScheme = event.detail.currentTheme;
// Update the JStree theme
fileTree.jstree(true).set_theme(newColorScheme === "dark" ? "default-dark" : "default");
});
fileTrees.push(fileTree);
});
};
var showFileTree = function(index) {
$('.files').hide();
$(fileTrees[index]).show();
};
if ($.isController('exercises') && $('#timeline').isPresent() && event.originalEvent.data.url.includes("/statistics")) {
var slider = $('#submissions-slider>input');
var submissions = $('#data').data('submissions');
var files = $('#data').data('files');
var filetypes = $('#data').data('file-types');
var playButton = $('#play-button');
var playInterval = undefined;
editor = ace.edit('current-file');
editor.setShowPrintMargin(false);
editor.setTheme(CodeOceanEditor.THEME);
editor.$blockScrolling = Infinity;
editor.setReadOnly(true);
_.each(filetypes, function (filetype) {
filetype = JSON.parse(filetype);
fileTypeById[filetype.id] = filetype;
});
$('tr[data-id]>.clickable').each(function(index, element) {
element = $(element);
element.parent().attr('id', 'submission-' + index);
element.click(function() {
slider.val(index);
slider.change()
});
});
const handleAceThemeChangeEvent = function() {
editor.setTheme(CodeOceanEditor.THEME);
};
$(document).on('theme:change:ace', handleAceThemeChangeEvent.bind(this));
const onSliderChange = function(event) {
currentSubmission = slider.val();
var currentFiles = files[currentSubmission];
var fileIndex = 0;
_.each(currentFiles, function(file, index) {
if (file.name === active_file.name) {
fileIndex = index;
}
});
active_file = currentFiles[fileIndex];
showActiveFile();
};
slider.on('change', onSliderChange);
stopReplay = function() {
clearInterval(playInterval);
playInterval = undefined;
playButton.find('span.fa-solid').removeClass('fa-pause').addClass('fa-play')
};
playButton.on('click', function(event) {
if (playInterval === undefined) {
// Reset slider if showing newest submission.
if (parseInt(slider.val()) === submissions.length - 1) {
slider.val(0);
onSliderChange();
}
playInterval = setInterval(function() {
if ($.isController('exercises') && $('#timeline').isPresent() && slider.val() < submissions.length - 1) {
slider.val(parseInt(slider.val()) + 1);
slider.change()
} else {
stopReplay();
}
}, 1000);
playButton.find('span.fa-solid').removeClass('fa-play').addClass('fa-pause')
} else {
stopReplay();
}
});
active_file = files[0][0];
initializeFileTree();
showActiveFile();
// Start with newest submission
slider.val(submissions.length - 1);
onSliderChange();
}
});