Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"start": "electron ."
},
"dependencies": {
"cncserver": "2.5.0",
"bytes": "^2.4.0",
"cncserver": "2.5.1",
"d3plus": "^1.9.3",
"fs-plus": "^2.8.1",
"hersheytext": "^0.5.1",
Expand Down
9 changes: 9 additions & 0 deletions resources/_i18n/robopaint.en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,17 @@
"calibrate": "Calibrate height",
"help": "Help! (Open web docs)",
"settings": "Settings",
"history": "SVG History",
"version": "v"
},
"history": {
"none": "No Recent SVGs found.",
"delete": {
"message": "Delete this file from your history?",
"detail": "The SVG cache file will be removed from this list and from your computer, this cannot be undone.",
"confirm": "Delete"
}
},
"bubble": {
"edit": "Create",
"printauto": "Print",
Expand Down
1 change: 1 addition & 0 deletions resources/images/icons/delete.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions resources/images/icons/history.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions resources/main.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
<span class="left">
<a id="bar-home" class="selected mode tipped" href="/" data-i18n="[title]nav.toolbar.home">&nbsp;</a>
<span class="separator">&nbsp;</span>
<a id="bar-history" class="tipped" href="#" data-i18n="[title]nav.toolbar.history">&nbsp;</a>
<ul id="history" style="display:none"></ul>
<a id="bar-load" class="icon-picture tipped" href="#" data-i18n="[title]nav.toolbar.open">&nbsp;</a>
<ul id="loadlist" style="display:none">
<li>No files. Add *.SVG to ./resources/svgs</li>
Expand Down
141 changes: 130 additions & 11 deletions resources/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ var remote = require('remote');
var mainWindow = remote.getCurrentWindow();
var app = remote.require('app');
var path = require('path');
var bytes = require('bytes');
var appPath = path.join(app.getAppPath(), '/');
var rpRequire = require(appPath + 'resources/rp_modules/rp.require');

Expand Down Expand Up @@ -124,6 +125,9 @@ function startInitialization() {
// Load the quickload list
initQuickload();

// Load the history list.
initHistoryload();

// Prep the connection status overlay
$stat = $('body.home h1');
$options = $('.options', $stat);
Expand Down Expand Up @@ -171,6 +175,11 @@ function createSubwindow(callback) {
});
};

// Hide the floating menus on focus.
$subwindow.on('focus', function(){
$('#history, #loadlist').fadeOut('fast');
});

// Make the mode window visible (should only happen when it's ready);
$subwindow.showMe = function(callback){
$('#loader').css('opacity', 0);
Expand Down Expand Up @@ -199,6 +208,9 @@ function createSubwindow(callback) {
case 'modeReady':
$subwindow.showMe();
break;
case 'svgUpdate': // Mode has updated the shared SVG data.
robopaint.reloadHistory();
break;
case 'modeLoadFail':
robopaint.switchMode('home');

Expand Down Expand Up @@ -643,12 +655,13 @@ function initQuickload() {
var svgs = fs.readdirSync(paths[0]);

// Bind Quick Load Hover
$load.click(function(e) {
$load.click(function() {
if ($loadList.is(':visible')) {
$loadList.fadeOut('slow');
} else {
$loadList.css('left', $load.offset().left + $load.width());
$loadList.fadeIn('fast');
$('#history').fadeOut('fast');
}
return false;
});
Expand All @@ -669,25 +682,131 @@ function initQuickload() {
}

// Bind loadlist item click load
$('a', $loadList).click(function(e) {
$('a', $loadList).click(function() {
$loadList.fadeOut('slow');
var fileContents = fs.readFileSync($(this).data('file'), 'utf-8');

// Push the files contents into the localstorage object
window.localStorage.setItem('svgedit-default', fileContents);
robopaint.setModeSVG($(this).data('file'));
return false;
});
}

// Tell the current mode that it happened.
cncserver.pushToMode('loadSVG');
/**
* Simple wrapper for set the "current" SVG data for the current mode.
*
* @param {string} svgFile
* The file path to the XML/SVG string data to set.
* @return {undefined}
*/
robopaint.setModeSVG = function(svgFile) {
fs.readFile(svgFile, function(err, fileContents){
if (!err) {
// Push the files contents into the localstorage object
window.localStorage.setItem('svgedit-default', fileContents);

// Resave the cache and update the history list.
robopaint.utils.saveSVGCacheFile(fileContents);
robopaint.reloadHistory();

// Tell the current mode that it happened.
cncserver.pushToMode('loadSVG');

// Switch to print default if the current mode doesn't support SVGs
if (robopaint.currentMode.robopaint.opensvg !== true) {
$('#bar-print').click();
}
}
});
};

// Switch to print default if the current mode doesn't support SVGs
if (robopaint.currentMode.robopaint.opensvg !== true) {
$('#bar-print').click();
/**
* Initialize and bind the history Quickload file list functionality
*/
function initHistoryload() {
var $button = $('#bar-history');
var $historyList = $('#history');

// Bind click activate.
$button.click(function() {
if ($historyList.is(':visible')) {
$historyList.fadeOut('slow');
} else {
$historyList.css('left', $button.offset().left + $button.width());
$historyList.fadeIn('fast');
$('#loadlist').fadeOut('fast');
}
return false;
});

// Bind dynamic history item click load.
$historyList.on('click', 'a', function() {
$historyList.fadeOut('slow');
robopaint.setModeSVG($(this).data('file'));
return false;
});

robopaint.reloadHistory();
}

// Reload the history content list (called elsewhere during updates);
robopaint.reloadHistory = function() {
var $historyList = $('#history');
var svgPath = robopaint.utils.getSVGCachePath();
var svgs = fs.readdirSync(svgPath);
svgs.sort(function(a, b) {
return fs.statSync(path.join(svgPath, b)).mtime.getTime() -
fs.statSync(path.join(svgPath, a)).mtime.getTime();
});

// Truncate the SVGs file list via the writable length property.
if (svgs.length > 50) {
svgs.length = 50;
}

// Load in SVG files for quick loading
if (svgs.length > 0) {
$historyList.html('');
for(var i in svgs) {
var svgFile = path.join(svgPath, svgs[i]);
var stats = fs.statSync(svgFile);
$('<li>').append(
$('<span>').addClass('delete').click(function(){
var $parent = $(this).parents('li');
mainWindow.dialog({
t: 'MessageBox',
type: 'warning',
message: i18n.t('nav.history.delete.message'),
cancelId: 0,
detail: i18n.t('nav.history.delete.detail'),
buttons: [
i18n.t('common.action.cancel'),
i18n.t('nav.history.delete.confirm')
]
}, function(deleteFile) {
if (deleteFile === 1) {
var svgFile = $parent.find('a').data('file');
fs.unlink(svgFile, function(){
$parent.slideUp('fast', function(){
$parent.remove();
robopaint.reloadHistory();
});
});
}
});
}),
$('<a>').data('file', svgFile).attr('href', '#').append(
$('<img>').attr('src', svgFile),
$('<span>').text(stats.mtime),
$('<b>').text(bytes(stats.size))
)
).appendTo($historyList);
}
} else {
// No history items!
$historyList.html(
'<li><h4 data-i18n="nav.history.none">' +
i18n.t('nav.history.none') + '</h4></li>'
);
}
};

/**
* Fetches all colorsets available from the colorsets dir
Expand Down
21 changes: 18 additions & 3 deletions resources/mode.preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ var appPath = app.getAppPath();
var i18n = window.i18n = require('i18next-client');
var $ = require('jquery');
var _ = require('underscore');
var rpRequire = window.rpRequire = require(appPath + '/resources/rp_modules/rp.require');
var rpRequire = window.rpRequire = require(
appPath + '/resources/rp_modules/rp.require'
);

// There are a number of async loads that must be complete before we can say
// that mode preloading is actually done. Because of load race conditions, these
// might load out of any kind of order, so each of these must be true before we
Expand All @@ -49,7 +52,10 @@ var robopaint = window.robopaint = {
robopaint.settings = robopaint.utils.getSettings();
window.cncserver = {};
robopaint.cncserver = window.cncserver;
rpRequire('cnc_api')(robopaint.cncserver, robopaint.utils.getAPIServer(robopaint.settings));
rpRequire('cnc_api')(
robopaint.cncserver,
robopaint.utils.getAPIServer(robopaint.settings)
);
robopaint.cncserver.api.settings.bot(function(b){
robopaint.canvas = robopaint.utils.getRPCanvas(b);
robopaint.currentBot = robopaint.utils.getCurrentBot(b);
Expand All @@ -61,6 +67,7 @@ robopaint.cncserver.api.settings.bot(function(b){
// Add in a small API for getting and setting the SVG content, as the storage
// may change, but the API shouldn't need to.
robopaint.svg = {
cachePath: path.join(app.getPath('userData'), 'svg-cache'),
wrap: function(inner) {
if (!inner) inner = '';

Expand All @@ -69,7 +76,7 @@ robopaint.svg = {
inner + '</svg>';
},
isEmpty: function() {
return localStorage['svgedit-default'] == false;
return localStorage['svgedit-default'] === false;
},
load: function() {
var svg = localStorage['svgedit-default'];
Expand All @@ -81,6 +88,13 @@ robopaint.svg = {
return svg;
},
save: function(svgData) {
// Save cache (if data):
if (svgData) {
robopaint.utils.saveSVGCacheFile(svgData);
ipc.sendToHost('svgUpdate'); // Tell RP main about the update.
}

// Save data to localStorage.
localStorage['svgedit-default'] = svgData;
}
};
Expand Down Expand Up @@ -371,6 +385,7 @@ function handleCNCServerMessages(name, data) {
translateMode();
break;
default:
// Trigger Generic onMessage handler.
if (_.isFunction(mode.onMessage)) mode.onMessage(name, data);
}
}
Expand Down
31 changes: 31 additions & 0 deletions resources/rp_modules/robopaint.utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,37 @@ var utils = {
delete localStorage[this.settingsStorageKey(extraKey)];
},

/**
* Return the path of where ot save the SVG cache files.
*
* @return {string}
* Full path to the svg-cache folder in the user data directory.
*/
getSVGCachePath: function () {
var remote = require('remote');
var app = remote.require('app');
return require('path').join(app.getPath('userData'), 'svg-cache');
},

/**
* Save SVG data as a hashed file in the cache folder.
*
* @param {string} svgData
* XML/SVG data to be saved & hashed.
*
* @return {undefined}
*/
saveSVGCacheFile: function (svgData) {
if (svgData) {
var hash = require('crypto')
.createHash('md5')
.update(svgData)
.digest("hex");
var file = require('path').join(robopaint.utils.getSVGCachePath(), hash + '.svg');
require('fs-plus').writeFileSync(file, svgData);
}
},

/**
* Return the object required for the CNCServer DOM API wrapper server object
*/
Expand Down
Loading