add undo/redo functionality
This commit is contained in:
@@ -57,6 +57,7 @@ let darkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: da
|
||||
|
||||
let dices = [];
|
||||
let history = [];
|
||||
let redoHistory = [];
|
||||
|
||||
let dicesContainer = document.getElementById("dices");
|
||||
let historyContainer = document.getElementById("history");
|
||||
@@ -197,9 +198,19 @@ function renderHistory() {
|
||||
historyContainer.innerHTML = "";
|
||||
if (history.length) {
|
||||
document.getElementById('history-button').classList.remove("disabled");
|
||||
document.getElementById('history-undo-button').classList.remove("disabled");
|
||||
} else {
|
||||
document.getElementById('history-button').classList.add("disabled");
|
||||
document.getElementById('history-undo-button').classList.add("disabled");
|
||||
}
|
||||
|
||||
if (redoHistory.length) {
|
||||
console.log(redoHistory);
|
||||
document.getElementById('history-redo-button').classList.remove("disabled");
|
||||
} else {
|
||||
document.getElementById('history-redo-button').classList.add("disabled");
|
||||
}
|
||||
|
||||
history.forEach((entry) => {
|
||||
if (entry.result) {
|
||||
const diceLabelContainer = document.createElement("div");
|
||||
@@ -285,6 +296,8 @@ function roll(dice, time = true) {
|
||||
}
|
||||
history.unshift(new DiceHistoryEntry([dice], f, result, time ? moment() : undefined));
|
||||
localStorage.setItem('history', JSON.stringify(history));
|
||||
redoHistory = [];
|
||||
localStorage.removeItem('redoHistory');
|
||||
renderHistory();
|
||||
}
|
||||
|
||||
@@ -399,12 +412,13 @@ function addDicesText() {
|
||||
function clearHistory() {
|
||||
history = [];
|
||||
localStorage.removeItem('history');
|
||||
localStorage.removeItem('redoHistory');
|
||||
renderHistory();
|
||||
}
|
||||
|
||||
function exportData() {
|
||||
const downloadButton = document.createElement('a');
|
||||
downloadButton.setAttribute('href', 'data:application/json;charset=utf-8,' + encodeURIComponent(JSON.stringify({ dices: dices, history: history })));
|
||||
downloadButton.setAttribute('href', 'data:application/json;charset=utf-8,' + encodeURIComponent(JSON.stringify({ dices: dices, history: history, redoHistory: redoHistory })));
|
||||
downloadButton.setAttribute('download', 'rgp-dices-' + new Date().toISOString() + '.json');
|
||||
document.body.appendChild(downloadButton);
|
||||
downloadButton.click();
|
||||
@@ -428,6 +442,10 @@ function importData(event) {
|
||||
localStorage.setItem('history', JSON.stringify(history));
|
||||
renderHistory();
|
||||
}
|
||||
if (data.redoHistory) {
|
||||
redoHistory = data.redoHistory.map((entry) => new DiceHistoryEntry(entry.dices && entry.dices.map((dice) => new Dice(dice.sides, dice.addition, dice.count, dice.color)) || undefined, entry.formula, entry.result, entry.time && moment(entry.time) || undefined));
|
||||
localStorage.setItem('redoHistory', JSON.stringify(redoHistory));
|
||||
}
|
||||
});
|
||||
|
||||
reader.readAsText(event.target.files[0]);
|
||||
@@ -461,6 +479,43 @@ function toggleDarkMode() {
|
||||
renderHistory();
|
||||
}
|
||||
|
||||
function undo() {
|
||||
while (history.length && history[0].result) {
|
||||
redoHistory.push(history.shift());
|
||||
}
|
||||
if (history.length && !history[0].result) {
|
||||
redoHistory.push(history.shift());
|
||||
}
|
||||
|
||||
localStorage.setItem('history', JSON.stringify(history));
|
||||
localStorage.setItem('redoHistory', JSON.stringify(redoHistory));
|
||||
renderHistory();
|
||||
}
|
||||
|
||||
function redo() {
|
||||
if (redoHistory.length && !redoHistory[redoHistory.length - 1].result) {
|
||||
history.unshift(redoHistory.pop());
|
||||
} else if (redoHistory.length) {
|
||||
history.unshift(new DiceHistoryEntry());
|
||||
}
|
||||
|
||||
while (redoHistory.length && redoHistory[redoHistory.length - 1].result) {
|
||||
history.unshift(redoHistory.pop());
|
||||
}
|
||||
|
||||
localStorage.setItem('history', JSON.stringify(history));
|
||||
localStorage.setItem('redoHistory', JSON.stringify(redoHistory));
|
||||
renderHistory();
|
||||
}
|
||||
|
||||
async function clearAndRefresh() {
|
||||
if ('caches' in window) {
|
||||
const keyList = await caches.keys();
|
||||
await Promise.all(keyList.map(async (key) => await caches.delete(key)));
|
||||
}
|
||||
window.location.reload()
|
||||
}
|
||||
|
||||
if (localStorage.getItem('dices')) {
|
||||
dices = JSON.parse(localStorage.getItem('dices')).map((dice) => new Dice(dice.sides, dice.addition, dice.count, dice.color));
|
||||
} else {
|
||||
@@ -473,6 +528,10 @@ if (localStorage.getItem('history')) {
|
||||
history = JSON.parse(localStorage.getItem('history')).map((entry) => new DiceHistoryEntry(entry.dices && entry.dices.map((dice) => new Dice(dice.sides, dice.addition, dice.count, dice.color)) || undefined, entry.formula, entry.result, entry.time && moment(entry.time) || undefined));
|
||||
}
|
||||
|
||||
if (localStorage.getItem('redoHistory')) {
|
||||
redoHistory = JSON.parse(localStorage.getItem('history')).map((entry) => new DiceHistoryEntry(entry.dices && entry.dices.map((dice) => new Dice(dice.sides, dice.addition, dice.count, dice.color)) || undefined, entry.formula, entry.result, entry.time && moment(entry.time) || undefined));
|
||||
}
|
||||
|
||||
document.getElementById("importFile").addEventListener("change", importData);
|
||||
|
||||
document.getElementById("inputText").addEventListener("keyup", (event) => {
|
||||
@@ -481,6 +540,27 @@ document.getElementById("inputText").addEventListener("keyup", (event) => {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.addEventListener("keyup", (event) => {
|
||||
if (!isNaN(+event.key)) {
|
||||
let number = +event.key;
|
||||
if (number == 0) {
|
||||
number = 10;
|
||||
}
|
||||
number--;
|
||||
if (number < dices.length) {
|
||||
if (history.length) {
|
||||
history.unshift(new DiceHistoryEntry());
|
||||
}
|
||||
roll(dices[number]);
|
||||
}
|
||||
} else if (event.ctrlKey && event.key.toUpperCase() === 'Z') {
|
||||
undo();
|
||||
} else if (event.ctrlKey && (event.shiftKey && event.key.toUpperCase() === 'Z' || event.key.toUpperCase() === 'Y')) {
|
||||
redo();
|
||||
}
|
||||
});
|
||||
|
||||
renderDices();
|
||||
renderHistory();
|
||||
updateCustom();
|
||||
|
||||
Reference in New Issue
Block a user