mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Merge branch 'master' into feature-export-to-file
This commit is contained in:
commit
3efa94dce5
@ -121,6 +121,7 @@
|
||||
}
|
||||
|
||||
.settings-title {
|
||||
color : gold;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 10px;
|
||||
text-transform: uppercase;
|
||||
|
@ -99,6 +99,12 @@
|
||||
this.savedStatusService = new pskl.service.SavedStatusService(this.piskelController);
|
||||
this.savedStatusService.init();
|
||||
|
||||
this.backupService = new pskl.service.BackupService(this.piskelController);
|
||||
this.backupService.init();
|
||||
|
||||
this.beforeUnloadService = new pskl.service.BeforeUnloadService(this.piskelController);
|
||||
this.beforeUnloadService.init();
|
||||
|
||||
|
||||
if (this.isAppEngineVersion) {
|
||||
this.storageService = new pskl.service.AppEngineStorageService(this.piskelController);
|
||||
|
@ -8,9 +8,13 @@
|
||||
*/
|
||||
ns.LocalStorageController.prototype.init = function() {
|
||||
this.localStorageItemTemplate_ = pskl.utils.Template.get("local-storage-item-template");
|
||||
this.previousSessionTemplate_ = pskl.utils.Template.get("previous-session-info-template");
|
||||
|
||||
this.service_ = pskl.app.localStorageService;
|
||||
this.piskelsList = $('.local-piskels-list');
|
||||
this.prevSessionContainer = $('.previous-session');
|
||||
|
||||
this.fillRestoreSession_();
|
||||
this.fillLocalPiskelsList_();
|
||||
|
||||
this.piskelsList.click(this.onPiskelsListClick_.bind(this));
|
||||
@ -27,24 +31,58 @@
|
||||
} else if (action === 'delete') {
|
||||
if (window.confirm('This will permanently DELETE this piskel from your computer. Continue ?')) {
|
||||
this.service_.remove(name);
|
||||
$.publish(Events.CLOSE_SETTINGS_DRAWER);
|
||||
this.fillLocalPiskelsList_();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ns.LocalStorageController.prototype.fillRestoreSession_ = function () {
|
||||
var previousInfo = pskl.app.backupService.getPreviousPiskelInfo();
|
||||
if (previousInfo) {
|
||||
var info = {
|
||||
name : previousInfo.name,
|
||||
date : this.formatDate_(previousInfo.date, "{{H}}:{{m}} - {{Y}}/{{M}}/{{D}}")
|
||||
};
|
||||
|
||||
this.prevSessionContainer.html(pskl.utils.Template.replace(this.previousSessionTemplate_, info));
|
||||
$(".restore-session-button").click(this.onRestorePreviousSessionClick_.bind(this));
|
||||
} else {
|
||||
this.prevSessionContainer.html("No piskel backup was found on this browser.");
|
||||
}
|
||||
};
|
||||
|
||||
ns.LocalStorageController.prototype.onRestorePreviousSessionClick_ = function () {
|
||||
if (window.confirm('This will erase your current workspace. Continue ?')) {
|
||||
pskl.app.backupService.load();
|
||||
$.publish(Events.CLOSE_SETTINGS_DRAWER);
|
||||
}
|
||||
};
|
||||
|
||||
var pad = function (num) {
|
||||
if (num < 10) {
|
||||
return "0" + num;
|
||||
} else {
|
||||
return "" + num;
|
||||
}
|
||||
};
|
||||
|
||||
ns.LocalStorageController.prototype.formatDate_ = function (date, format) {
|
||||
date = new Date(date);
|
||||
var formattedDate = pskl.utils.Template.replace(format, {
|
||||
Y : date.getFullYear(),
|
||||
M : pad(date.getMonth() + 1),
|
||||
D : pad(date.getDate()),
|
||||
H : pad(date.getHours()),
|
||||
m : pad(date.getMinutes())
|
||||
});
|
||||
|
||||
return formattedDate;
|
||||
};
|
||||
|
||||
ns.LocalStorageController.prototype.fillLocalPiskelsList_ = function () {
|
||||
var html = "";
|
||||
var keys = this.service_.getKeys();
|
||||
|
||||
var pad = function (num) {
|
||||
if (num < 10) {
|
||||
return "0" + num;
|
||||
} else {
|
||||
return "" + num;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
keys.sort(function (k1, k2) {
|
||||
if (k1.date < k2.date) {return 1;}
|
||||
if (k1.date > k2.date) {return -1;}
|
||||
@ -52,15 +90,8 @@
|
||||
});
|
||||
|
||||
keys.forEach((function (key) {
|
||||
var date = new Date(key.date);
|
||||
var formattedDate = pskl.utils.Template.replace("{{Y}}/{{M}}/{{D}} {{H}}:{{m}}", {
|
||||
Y : date.getFullYear(),
|
||||
M : pad(date.getMonth() + 1),
|
||||
D : pad(date.getDate()),
|
||||
H : pad(date.getHours()),
|
||||
m : pad(date.getMinutes())
|
||||
});
|
||||
html += pskl.utils.Template.replace(this.localStorageItemTemplate_, {name : key.name, date : formattedDate});
|
||||
var date = this.formatDate_(key.date, "{{Y}}/{{M}}/{{D}} {{H}}:{{m}}");
|
||||
html += pskl.utils.Template.replace(this.localStorageItemTemplate_, {name : key.name, date : date});
|
||||
}).bind(this));
|
||||
|
||||
var tableBody_ = this.piskelsList.get(0).tBodies[0];
|
||||
|
@ -46,12 +46,12 @@
|
||||
} else {
|
||||
color = window.tinycolor.lighten(pixelColor, step);
|
||||
}
|
||||
if (color) {
|
||||
usedPixels[key] = true;
|
||||
this.superclass.applyToolAt.call(this, col, row, color.toRgbString(), frame, overlay, event);
|
||||
}
|
||||
}
|
||||
|
||||
if (color) {
|
||||
usedPixels[key] = true;
|
||||
this.superclass.applyToolAt.call(this, col, row, color.toRgbString(), frame, overlay, event);
|
||||
}
|
||||
};
|
||||
|
||||
ns.Lighten.prototype.releaseToolAt = function(col, row, color, frame, overlay, event) {
|
||||
|
@ -96,4 +96,10 @@
|
||||
ns.Layer.prototype.length = function () {
|
||||
return this.frames.length;
|
||||
};
|
||||
|
||||
ns.Layer.prototype.getHash = function () {
|
||||
return this.frames.map(function (frame) {
|
||||
return frame.getHash();
|
||||
}).join('-');
|
||||
};
|
||||
})();
|
@ -109,4 +109,10 @@
|
||||
var appEngineEditorHeader = $('.piskel-name').html(this.descriptor.name);
|
||||
};
|
||||
|
||||
ns.Piskel.prototype.getHash = function () {
|
||||
return this.layers.map(function (layer) {
|
||||
return layer.getHash();
|
||||
}).join('-');
|
||||
};
|
||||
|
||||
})();
|
59
src/js/service/BackupService.js
Normal file
59
src/js/service/BackupService.js
Normal file
@ -0,0 +1,59 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.service');
|
||||
var BACKUP_INTERVAL = 1000 * 30;
|
||||
|
||||
ns.BackupService = function (piskelController) {
|
||||
this.piskelController = piskelController;
|
||||
this.lastHash = null;
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.init = function () {
|
||||
var previousPiskel = window.localStorage.getItem('bkp.next.piskel');
|
||||
var previousInfo = window.localStorage.getItem('bkp.next.info');
|
||||
if (previousPiskel && previousInfo) {
|
||||
window.localStorage.setItem('bkp.prev.piskel', previousPiskel);
|
||||
window.localStorage.setItem('bkp.prev.info', previousInfo);
|
||||
}
|
||||
window.setInterval(this.backup.bind(this), BACKUP_INTERVAL);
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.backup = function () {
|
||||
var piskel = this.piskelController.getPiskel();
|
||||
var descriptor = piskel.getDescriptor();
|
||||
var hash = piskel.getHash();
|
||||
var info = {
|
||||
name : descriptor.name,
|
||||
description : descriptor.info,
|
||||
date : Date.now(),
|
||||
hash : hash
|
||||
};
|
||||
|
||||
// Do not save an unchanged piskel
|
||||
if (hash !== this.lastHash) {
|
||||
this.lastHash = hash;
|
||||
window.localStorage.setItem('bkp.next.piskel', this.piskelController.serialize());
|
||||
window.localStorage.setItem('bkp.next.info', JSON.stringify(info));
|
||||
}
|
||||
};
|
||||
|
||||
ns.BackupService.prototype.getPreviousPiskelInfo = function () {
|
||||
var previousInfo = window.localStorage.getItem('bkp.prev.info');
|
||||
if (previousInfo) {
|
||||
return JSON.parse(previousInfo);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
ns.BackupService.prototype.load = function() {
|
||||
|
||||
var previousPiskel = window.localStorage.getItem('bkp.prev.piskel');
|
||||
var previousInfo = window.localStorage.getItem('bkp.prev.info');
|
||||
previousPiskel = JSON.parse(previousPiskel);
|
||||
previousInfo = JSON.parse(previousInfo);
|
||||
|
||||
pskl.utils.serialization.Deserializer.deserialize(previousPiskel, function (piskel) {
|
||||
piskel.setDescriptor(new pskl.model.piskel.Descriptor(previousInfo.name, previousInfo.description, true));
|
||||
pskl.app.piskelController.setPiskel(piskel);
|
||||
});
|
||||
};
|
||||
})();
|
23
src/js/service/BeforeUnloadService.js
Normal file
23
src/js/service/BeforeUnloadService.js
Normal file
@ -0,0 +1,23 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.service');
|
||||
|
||||
ns.BeforeUnloadService = function (piskelController) {
|
||||
this.piskelController = piskelController;
|
||||
};
|
||||
|
||||
|
||||
ns.BeforeUnloadService.prototype.init = function () {
|
||||
window.addEventListener("beforeunload", this.onBeforeUnload.bind(this));
|
||||
};
|
||||
|
||||
ns.BeforeUnloadService.prototype.onBeforeUnload = function (evt) {
|
||||
pskl.app.backupService.backup();
|
||||
if (pskl.app.savedStatusService.isDirty()) {
|
||||
var confirmationMessage = "Your Piskel seems to have unsaved changes";
|
||||
|
||||
(evt || window.event).returnValue = confirmationMessage;
|
||||
return confirmationMessage;
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
@ -63,24 +63,39 @@
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.getPreviousSnapshotIndex_ = function (index) {
|
||||
var counter = 0;
|
||||
while (this.stateQueue[index] && !this.stateQueue[index].piskel) {
|
||||
index = index - 1;
|
||||
if(++counter > 2*SNAPSHOT_PERIOD) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.loadState = function (index) {
|
||||
if (this.isLoadStateAllowed_(index)) {
|
||||
this.lastLoadState = Date.now();
|
||||
try {
|
||||
if (this.isLoadStateAllowed_(index)) {
|
||||
this.lastLoadState = Date.now();
|
||||
|
||||
var snapshotIndex = this.getPreviousSnapshotIndex_(index);
|
||||
if (snapshotIndex < 0) {
|
||||
throw 'Could not find previous SNAPSHOT saved in history stateQueue';
|
||||
var snapshotIndex = this.getPreviousSnapshotIndex_(index);
|
||||
if (snapshotIndex < 0) {
|
||||
throw 'Could not find previous SNAPSHOT saved in history stateQueue';
|
||||
}
|
||||
var serializedPiskel = this.getSnapshotFromState_(snapshotIndex);
|
||||
var onPiskelLoadedCb = this.onPiskelLoaded_.bind(this, index, snapshotIndex);
|
||||
pskl.utils.serialization.Deserializer.deserialize(serializedPiskel, onPiskelLoadedCb);
|
||||
}
|
||||
} catch (e) {
|
||||
window.console.error("[CRITICAL ERROR] : Unable to load a history state.");
|
||||
window.console.error("Can you open an issue on http://github.com/juliandescottes/piskel or contact @piskelapp on twitter ? Thanks !");
|
||||
window.console.error("Thanks !");
|
||||
if (typeof e === "string") {
|
||||
window.console.error(e);
|
||||
} else {
|
||||
window.console.error(e.message);
|
||||
window.console.error(e.stack);
|
||||
}
|
||||
|
||||
var serializedPiskel = this.getSnapshotFromState_(snapshotIndex);
|
||||
var onPiskelLoadedCb = this.onPiskelLoaded_.bind(this, index, snapshotIndex);
|
||||
pskl.utils.serialization.Deserializer.deserialize(serializedPiskel, onPiskelLoadedCb);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -11,8 +11,6 @@
|
||||
|
||||
ns.LocalStorageService.prototype.init = function() {};
|
||||
|
||||
// localStorage.setItem('piskel_bkp', pskl.app.piskelController.serialize())
|
||||
|
||||
ns.LocalStorageService.prototype.save = function(name, description, piskel) {
|
||||
this.removeFromKeys_(name);
|
||||
this.addToKeys_(name, description, Date.now());
|
||||
|
@ -10,8 +10,6 @@
|
||||
$.subscribe(Events.PISKEL_RESET, this.onPiskelReset.bind(this));
|
||||
|
||||
$.subscribe(Events.PISKEL_SAVED, this.onPiskelSaved.bind(this));
|
||||
|
||||
window.addEventListener("beforeunload", this.onBeforeUnload.bind(this));
|
||||
};
|
||||
|
||||
ns.SavedStatusService.prototype.onPiskelReset = function () {
|
||||
@ -52,13 +50,8 @@
|
||||
}
|
||||
};
|
||||
|
||||
ns.SavedStatusService.prototype.onBeforeUnload = function (evt) {
|
||||
ns.SavedStatusService.prototype.isDirty = function (evt) {
|
||||
var piskel = this.piskelController.getPiskel();
|
||||
if (piskel.isDirty_) {
|
||||
var confirmationMessage = "Your Piskel seems to have unsaved changes";
|
||||
|
||||
(evt || window.event).returnValue = confirmationMessage;
|
||||
return confirmationMessage;
|
||||
}
|
||||
return piskel.isDirty_;
|
||||
};
|
||||
})();
|
@ -105,6 +105,8 @@
|
||||
"js/service/LocalStorageService.js",
|
||||
"js/service/GithubStorageService.js",
|
||||
"js/service/AppEngineStorageService.js",
|
||||
"js/service/BackupService.js",
|
||||
"js/service/BeforeUnloadService.js",
|
||||
"js/service/HistoryService.js",
|
||||
"js/service/SavedStatusService.js",
|
||||
"js/service/keyboard/ShortcutService.js",
|
||||
|
@ -1,4 +1,9 @@
|
||||
<div class="settings-section">
|
||||
<div class="settings-title">
|
||||
Restore previous session
|
||||
</div>
|
||||
<div class="settings-item previous-session">
|
||||
</div>
|
||||
<div class="settings-title">
|
||||
Browse Local Piskels
|
||||
</div>
|
||||
@ -15,4 +20,12 @@
|
||||
<td><a class="local-piskel-delete-link" data-action="delete" data-name="{{name}}" href="javascript:void(0);">x</a></td>
|
||||
</tr>
|
||||
</script>
|
||||
<script type="text/template" id="previous-session-info-template">
|
||||
<div>
|
||||
Restore a backup of <span style="color:gold">{{name}}</span>, saved at <span style="color:white">{{date}}</span> ?
|
||||
<div style="margin-top:10px;">
|
||||
<button type="button" class="button button-primary restore-session-button">Restore</button>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user