add undo/redo functionality
This commit is contained in:
parent
75a79fb700
commit
c4d2349b6a
1
assets/redo.svg
Normal file
1
assets/redo.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#000000"><path d="M396-200q-97 0-166.5-63T160-420q0-94 69.5-157T396-640h252L544-744l56-56 200 200-200 200-56-56 104-104H396q-63 0-109.5 40T240-420q0 60 46.5 100T396-280h284v80H396Z"/></svg>
|
After Width: | Height: | Size: 287 B |
1
assets/undo.svg
Normal file
1
assets/undo.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#000000"><path d="M280-200v-80h284q63 0 109.5-40T720-420q0-60-46.5-100T564-560H312l104 104-56 56-200-200 200-200 56 56-104 104h252q97 0 166.5 63T800-420q0 94-69.5 157T564-200H280Z"/></svg>
|
After Width: | Height: | Size: 286 B |
1
assets/update.svg
Normal file
1
assets/update.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#000000"><path d="M204-318q-22-38-33-78t-11-82q0-134 93-228t227-94h7l-64-64 56-56 160 160-160 160-56-56 64-64h-7q-100 0-170 70.5T240-478q0 26 6 51t18 49l-60 60ZM481-40 321-200l160-160 56 56-64 64h7q100 0 170-70.5T720-482q0-26-6-51t-18-49l60-60q22 38 33 78t11 82q0 134-93 228t-227 94h-7l64 64-56 56Z"/></svg>
|
After Width: | Height: | Size: 405 B |
10
index.html
10
index.html
@ -3,7 +3,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Role Playing Game Dices</title>
|
<title>Role Playing Game Dices</title>
|
||||||
<meta name="application-name" content="Role Playing Game Dices">
|
<meta name="application-name" content="Role Playing Game Dices">
|
||||||
<meta name="application-version" content="v0.2.1">
|
<meta name="application-version" content="v0.2.2">
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
|
||||||
@ -49,6 +49,9 @@
|
|||||||
<li onclick="toggleDarkMode()"><img id="dark-mode-icon" src="./assets/dark.svg"><span
|
<li onclick="toggleDarkMode()"><img id="dark-mode-icon" src="./assets/dark.svg"><span
|
||||||
id="dark-mode-text">Dark Mode</span></li>
|
id="dark-mode-text">Dark Mode</span></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<ul class="menu">
|
||||||
|
<li onclick="clearAndRefresh()"><img id="dark-mode-icon" src="./assets/update.svg"><span>Try to Update</span></li>
|
||||||
|
</ul>
|
||||||
<script>
|
<script>
|
||||||
Sidebar();
|
Sidebar();
|
||||||
</script>
|
</script>
|
||||||
@ -68,13 +71,16 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="history-container">
|
<div class="history-container">
|
||||||
<div class="history" id="history"></div>
|
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
|
<button id="history-undo-button" onclick="undo()"><img src="./assets/undo.svg"></button>
|
||||||
<button id="history-button" onclick="clearHistory()"><img src="./assets/history.svg"> Clear
|
<button id="history-button" onclick="clearHistory()"><img src="./assets/history.svg"> Clear
|
||||||
History</button>
|
History</button>
|
||||||
|
<button id="history-redo-button" onclick="redo()"><img src="./assets/redo.svg"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="history" id="history"></div>
|
||||||
|
|
||||||
<div class="form-container">
|
<div class="form-container">
|
||||||
<div class="form">
|
<div class="form">
|
||||||
<input type="text" id="inputText" placeholder="1D6+1 + 2W4">
|
<input type="text" id="inputText" placeholder="1D6+1 + 2W4">
|
||||||
|
82
script.js
82
script.js
@ -57,6 +57,7 @@ let darkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: da
|
|||||||
|
|
||||||
let dices = [];
|
let dices = [];
|
||||||
let history = [];
|
let history = [];
|
||||||
|
let redoHistory = [];
|
||||||
|
|
||||||
let dicesContainer = document.getElementById("dices");
|
let dicesContainer = document.getElementById("dices");
|
||||||
let historyContainer = document.getElementById("history");
|
let historyContainer = document.getElementById("history");
|
||||||
@ -197,9 +198,19 @@ function renderHistory() {
|
|||||||
historyContainer.innerHTML = "";
|
historyContainer.innerHTML = "";
|
||||||
if (history.length) {
|
if (history.length) {
|
||||||
document.getElementById('history-button').classList.remove("disabled");
|
document.getElementById('history-button').classList.remove("disabled");
|
||||||
|
document.getElementById('history-undo-button').classList.remove("disabled");
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('history-button').classList.add("disabled");
|
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) => {
|
history.forEach((entry) => {
|
||||||
if (entry.result) {
|
if (entry.result) {
|
||||||
const diceLabelContainer = document.createElement("div");
|
const diceLabelContainer = document.createElement("div");
|
||||||
@ -285,6 +296,8 @@ function roll(dice, time = true) {
|
|||||||
}
|
}
|
||||||
history.unshift(new DiceHistoryEntry([dice], f, result, time ? moment() : undefined));
|
history.unshift(new DiceHistoryEntry([dice], f, result, time ? moment() : undefined));
|
||||||
localStorage.setItem('history', JSON.stringify(history));
|
localStorage.setItem('history', JSON.stringify(history));
|
||||||
|
redoHistory = [];
|
||||||
|
localStorage.removeItem('redoHistory');
|
||||||
renderHistory();
|
renderHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,12 +412,13 @@ function addDicesText() {
|
|||||||
function clearHistory() {
|
function clearHistory() {
|
||||||
history = [];
|
history = [];
|
||||||
localStorage.removeItem('history');
|
localStorage.removeItem('history');
|
||||||
|
localStorage.removeItem('redoHistory');
|
||||||
renderHistory();
|
renderHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
function exportData() {
|
function exportData() {
|
||||||
const downloadButton = document.createElement('a');
|
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');
|
downloadButton.setAttribute('download', 'rgp-dices-' + new Date().toISOString() + '.json');
|
||||||
document.body.appendChild(downloadButton);
|
document.body.appendChild(downloadButton);
|
||||||
downloadButton.click();
|
downloadButton.click();
|
||||||
@ -428,6 +442,10 @@ function importData(event) {
|
|||||||
localStorage.setItem('history', JSON.stringify(history));
|
localStorage.setItem('history', JSON.stringify(history));
|
||||||
renderHistory();
|
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]);
|
reader.readAsText(event.target.files[0]);
|
||||||
@ -461,6 +479,43 @@ function toggleDarkMode() {
|
|||||||
renderHistory();
|
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')) {
|
if (localStorage.getItem('dices')) {
|
||||||
dices = JSON.parse(localStorage.getItem('dices')).map((dice) => new Dice(dice.sides, dice.addition, dice.count, dice.color));
|
dices = JSON.parse(localStorage.getItem('dices')).map((dice) => new Dice(dice.sides, dice.addition, dice.count, dice.color));
|
||||||
} else {
|
} 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));
|
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("importFile").addEventListener("change", importData);
|
||||||
|
|
||||||
document.getElementById("inputText").addEventListener("keyup", (event) => {
|
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();
|
renderDices();
|
||||||
renderHistory();
|
renderHistory();
|
||||||
updateCustom();
|
updateCustom();
|
||||||
|
@ -245,7 +245,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.history-container {
|
.history-container {
|
||||||
margin: 2em 0;
|
margin: 0.5em 0;
|
||||||
max-width: 99vw;
|
max-width: 99vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user