improve styling, sort dices
This commit is contained in:
@@ -23,6 +23,9 @@ class Dice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fromText(value) {
|
fromText(value) {
|
||||||
|
if (!value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const result = value.match(localeData && localeData['regex'] || dice_regex);
|
const result = value.match(localeData && localeData['regex'] || dice_regex);
|
||||||
if (result) {
|
if (result) {
|
||||||
if (result[1]) {
|
if (result[1]) {
|
||||||
@@ -51,7 +54,7 @@ class DiceHistoryEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const default_sides = [4, 6, 8, 10, 12, 20, 100];
|
const default_sides = [4, 6, 8, 10, 12, 20, 100];
|
||||||
const default_colors = ["#de324c", "#f4895f", "#f8e16f", "#95cf92", "#369acc", "#9656a2", "#6c584c"];
|
const default_colors = ["#de324c", "#f4895f", "#d8b400ff", "#95cf92", "#369acc", "#9656a2", "#6c584c"];
|
||||||
|
|
||||||
const dice_regex = new RegExp("(\\d+)?[D|d](\\d+)([\\+|\\-]\\d+)?(\\[(.+)\\])?");
|
const dice_regex = new RegExp("(\\d+)?[D|d](\\d+)([\\+|\\-]\\d+)?(\\[(.+)\\])?");
|
||||||
|
|
||||||
@@ -209,7 +212,6 @@ function renderHistory() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (redoHistory.length) {
|
if (redoHistory.length) {
|
||||||
console.log(redoHistory);
|
|
||||||
document.getElementById('history-redo-button').classList.remove("disabled");
|
document.getElementById('history-redo-button').classList.remove("disabled");
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('history-redo-button').classList.add("disabled");
|
document.getElementById('history-redo-button').classList.add("disabled");
|
||||||
@@ -217,13 +219,42 @@ function renderHistory() {
|
|||||||
|
|
||||||
history.forEach((entry) => {
|
history.forEach((entry) => {
|
||||||
if (entry.result) {
|
if (entry.result) {
|
||||||
|
// Create main history entry container
|
||||||
|
const historyEntry = document.createElement("div");
|
||||||
|
historyEntry.classList.add("history-entry");
|
||||||
|
|
||||||
|
// Create header section
|
||||||
|
const entryHeader = document.createElement("div");
|
||||||
|
entryHeader.classList.add("history-entry-header");
|
||||||
|
|
||||||
|
// Create dice label section
|
||||||
const diceLabelContainer = document.createElement("div");
|
const diceLabelContainer = document.createElement("div");
|
||||||
diceLabelContainer.classList.add("label");
|
diceLabelContainer.classList.add("label");
|
||||||
if (entry.dices) {
|
if (entry.dices) {
|
||||||
entry.dices.forEach((diceData, i) => {
|
entry.dices.forEach((diceData, i) => {
|
||||||
const dice = new Dice(diceData.sides, diceData.addition, diceData.count, diceData.color);
|
const dice = new Dice(diceData.sides, diceData.addition, diceData.count, diceData.color);
|
||||||
|
|
||||||
|
// Add dice icon
|
||||||
|
const diceIcon = document.createElement("span");
|
||||||
|
diceIcon.classList.add("dice-icon");
|
||||||
|
if (default_sides.indexOf(dice.sides) != -1) {
|
||||||
|
diceIcon.style.maskImage = `url(./assets/dices/${dice.sides}.svg)`;
|
||||||
|
} else {
|
||||||
|
diceIcon.style.maskImage = "url(./assets/dices/custom.svg)";
|
||||||
|
}
|
||||||
|
diceIcon.style.color = dice.color;
|
||||||
|
// revert b/w on dark-mode
|
||||||
|
if (darkMode) {
|
||||||
|
if (["#000", "#000000", "black", "rgb(0,0,0)", "rgb(0, 0, 0)"].indexOf(dice.color) != -1) {
|
||||||
|
diceIcon.style.color = "#fff";
|
||||||
|
} else if (["#fff", "#ffffff", "white", "rgb(255,255,255)", "rgb(255, 255, 255)"].indexOf(dice.color) != -1) {
|
||||||
|
diceIcon.style.color = "#000";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diceLabelContainer.appendChild(diceIcon);
|
||||||
|
|
||||||
const diceLabel = document.createElement("label");
|
const diceLabel = document.createElement("label");
|
||||||
diceLabel.innerHTML = dice.toText() + (i == entry.dices.length - 1 ? ": " : "");
|
diceLabel.innerHTML = dice.toText();
|
||||||
diceLabel.style.color = dice.color;
|
diceLabel.style.color = dice.color;
|
||||||
// revert b/w on dark-mode
|
// revert b/w on dark-mode
|
||||||
if (darkMode) {
|
if (darkMode) {
|
||||||
@@ -234,6 +265,7 @@ function renderHistory() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
diceLabelContainer.appendChild(diceLabel);
|
diceLabelContainer.appendChild(diceLabel);
|
||||||
|
|
||||||
if (i < entry.dices.length - 1) {
|
if (i < entry.dices.length - 1) {
|
||||||
const diceLabelAdd = document.createElement("span");
|
const diceLabelAdd = document.createElement("span");
|
||||||
diceLabelAdd.innerHTML = " + ";
|
diceLabelAdd.innerHTML = " + ";
|
||||||
@@ -241,48 +273,130 @@ function renderHistory() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
historyContainer.appendChild(diceLabelContainer);
|
|
||||||
|
|
||||||
|
// Create result display
|
||||||
const diceResult = document.createElement("span");
|
const diceResult = document.createElement("div");
|
||||||
diceResult.classList.add("result");
|
diceResult.classList.add("result");
|
||||||
diceResult.innerText = entry.result;
|
diceResult.innerText = entry.result;
|
||||||
historyContainer.appendChild(diceResult);
|
|
||||||
|
|
||||||
const diceFormulaContainer = document.createElement("span");
|
entryHeader.appendChild(diceLabelContainer);
|
||||||
diceFormulaContainer.classList.add("formula-container");
|
|
||||||
historyContainer.appendChild(diceFormulaContainer);
|
|
||||||
|
|
||||||
if (entry.formula) {
|
// Only show result in header if there's no formula
|
||||||
const diceFormulaEqual = document.createElement("span");
|
if (!entry.formula) {
|
||||||
diceFormulaEqual.innerText = " = ";
|
entryHeader.appendChild(diceResult);
|
||||||
diceFormulaContainer.appendChild(diceFormulaEqual);
|
|
||||||
const diceFormula = document.createElement("span");
|
|
||||||
diceFormula.classList.add("formula");
|
|
||||||
diceFormula.innerText = entry.formula;
|
|
||||||
diceFormulaContainer.appendChild(diceFormula);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const diceTime = document.createElement("span");
|
// Create time display
|
||||||
|
const diceTime = document.createElement("div");
|
||||||
diceTime.classList.add("time");
|
diceTime.classList.add("time");
|
||||||
historyContainer.appendChild(diceTime);
|
|
||||||
|
|
||||||
if (entry.time) {
|
if (entry.time) {
|
||||||
entry.time.locale(locale);
|
entry.time.locale(locale);
|
||||||
diceTime.innerText = entry.time.fromNow();
|
diceTime.innerText = entry.time.fromNow();
|
||||||
diceTime.title = entry.time.format("LLLL");
|
diceTime.title = entry.time.format("LLLL");
|
||||||
}
|
}
|
||||||
|
entryHeader.appendChild(diceTime);
|
||||||
|
|
||||||
|
historyEntry.appendChild(entryHeader);
|
||||||
|
|
||||||
|
// Create details section if formula exists
|
||||||
|
if (entry.formula) {
|
||||||
|
const entryDetails = document.createElement("div");
|
||||||
|
entryDetails.classList.add("history-entry-details");
|
||||||
|
|
||||||
|
const diceFormulaContainer = document.createElement("div");
|
||||||
|
diceFormulaContainer.classList.add("formula-container");
|
||||||
|
|
||||||
|
const diceFormulaResult = document.createElement("span");
|
||||||
|
diceFormulaResult.classList.add("result");
|
||||||
|
diceFormulaResult.innerText = entry.result;
|
||||||
|
|
||||||
|
const diceFormulaEqual = document.createElement("span");
|
||||||
|
diceFormulaEqual.innerText = " = ";
|
||||||
|
|
||||||
|
diceFormulaContainer.appendChild(diceFormulaResult);
|
||||||
|
diceFormulaContainer.appendChild(diceFormulaEqual);
|
||||||
|
|
||||||
|
const diceFormula = document.createElement("span");
|
||||||
|
diceFormula.classList.add("formula");
|
||||||
|
|
||||||
|
// If we have dices, show colored breakdown
|
||||||
|
if (entry.dices && entry.dices.length >= 1) {
|
||||||
|
// Parse the formula to show which dice contributed what
|
||||||
|
const formulaParts = entry.formula.split(" + ");
|
||||||
|
let partIndex = 0;
|
||||||
|
|
||||||
|
// Create a mapping of which dice contributes which parts
|
||||||
|
let dicePartMapping = [];
|
||||||
|
entry.dices.forEach(dice => {
|
||||||
|
for (let i = 0; i < dice.count; i++) {
|
||||||
|
if (partIndex < formulaParts.length && !isNaN(parseInt(formulaParts[partIndex]))) {
|
||||||
|
dicePartMapping.push({
|
||||||
|
partIndex: partIndex,
|
||||||
|
dice: dice
|
||||||
|
});
|
||||||
|
partIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
formulaParts.forEach((part, index) => {
|
||||||
|
const mapping = dicePartMapping.find(m => m.partIndex === index);
|
||||||
|
|
||||||
|
if (mapping) {
|
||||||
|
// This part comes from a dice roll
|
||||||
|
const partSpan = document.createElement("span");
|
||||||
|
partSpan.innerText = part;
|
||||||
|
partSpan.style.color = mapping.dice.color;
|
||||||
|
// revert b/w on dark-mode
|
||||||
|
if (darkMode) {
|
||||||
|
if (["#000", "#000000", "black", "rgb(0,0,0)", "rgb(0, 0, 0)"].indexOf(mapping.dice.color) != -1) {
|
||||||
|
partSpan.style.color = "#fff";
|
||||||
|
} else if (["#fff", "#ffffff", "white", "rgb(255,255,255)", "rgb(255, 255, 255)"].indexOf(mapping.dice.color) != -1) {
|
||||||
|
partSpan.style.color = "#000";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diceFormula.appendChild(partSpan);
|
||||||
|
} else {
|
||||||
|
// This is an addition value (modifier)
|
||||||
|
const partSpan = document.createElement("span");
|
||||||
|
partSpan.innerText = part;
|
||||||
|
diceFormula.appendChild(partSpan);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < formulaParts.length - 1) {
|
||||||
|
const plusSpan = document.createElement("span");
|
||||||
|
plusSpan.innerText = " + ";
|
||||||
|
diceFormula.appendChild(plusSpan);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Fallback to plain text
|
||||||
|
diceFormula.innerText = entry.formula;
|
||||||
|
}
|
||||||
|
|
||||||
|
diceFormulaContainer.appendChild(diceFormula);
|
||||||
|
entryDetails.appendChild(diceFormulaContainer);
|
||||||
|
historyEntry.appendChild(entryDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
historyContainer.appendChild(historyEntry);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
// Add separator for different roll sessions
|
||||||
historyContainer.appendChild(document.createElement("hr"));
|
historyContainer.appendChild(document.createElement("hr"));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function formula(dice) {
|
function formula(dice) {
|
||||||
|
let rolls = [];
|
||||||
|
for (let index = 0; index < dice.count; index++) {
|
||||||
|
rolls.push(Math.floor(Math.random() * dice.sides + 1));
|
||||||
|
}
|
||||||
|
rolls.sort((a, b) => b - a);
|
||||||
let formula = "";
|
let formula = "";
|
||||||
for (let index = 0; index < dice.count; index++) {
|
for (let index = 0; index < dice.count; index++) {
|
||||||
formula += Math.floor(Math.random() * dice.sides + 1);
|
formula += rolls[index];
|
||||||
if (index < dice.count - 1) {
|
if (index < dice.count - 1) {
|
||||||
formula += " + ";
|
formula += " + ";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,6 +210,9 @@ body {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
row-gap: 1em;
|
row-gap: 1em;
|
||||||
grid-template-columns: auto;
|
grid-template-columns: auto;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-container .actions {
|
.form-container .actions {
|
||||||
@@ -261,45 +264,114 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.history {
|
.history {
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(4, auto);
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 1.5em;
|
margin-top: 1.5em;
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
row-gap: 0.3em;
|
display: flex;
|
||||||
column-gap: 0.3em;
|
flex-direction: column;
|
||||||
|
gap: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history hr {
|
.history hr {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
grid-column: span 4;
|
margin: 0.5em 0;
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-entry {
|
||||||
|
background: #fff;
|
||||||
|
border: 0.15em solid #000;
|
||||||
|
padding: 1em;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-entry:hover {
|
||||||
|
background: #f1f3f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-entry-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-entry-header .label {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-entry-header .result {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin: 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-entry-header .time {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-left: auto;
|
||||||
|
min-width: 8em;
|
||||||
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history .label {
|
.history .label {
|
||||||
font-size: 1.2em;
|
font-size: 1.1em;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history .result {
|
.history .result {
|
||||||
text-align: center;
|
font-size: 1.8em;
|
||||||
font-size: 1.2em;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
color: #2c3e50;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history .time {
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #6c757d;
|
||||||
|
text-align: right;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-entry-details {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
padding-top: 0.5em;
|
||||||
|
border-top: 0.1em solid #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history .formula-container {
|
.history .formula-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin: 0 0.5em;
|
align-items: center;
|
||||||
|
font-size: 0.95em;
|
||||||
|
color: #495057;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.history .formula-container .formula {
|
.history .formula-container .formula {
|
||||||
display: flex;
|
margin-left: 0.5em;
|
||||||
margin: 0 0.5em;
|
font-family: 'Courier New', Courier, monospace;
|
||||||
|
font-size: 1.3em;
|
||||||
|
background: #f1f3f4;
|
||||||
|
padding: 0.2em 0.5em;
|
||||||
|
border: 0.1em solid #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history .time {
|
.dice-icon {
|
||||||
text-align: right;
|
display: inline-block;
|
||||||
|
width: 1.2em;
|
||||||
|
height: 1.2em;
|
||||||
|
background-color: currentColor;
|
||||||
|
mask-size: contain;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-position: center;
|
||||||
|
margin-right: 0.2em;
|
||||||
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
@@ -366,6 +438,37 @@ body.dark .form select {
|
|||||||
border-color: #fff;
|
border-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.dark .history-entry {
|
||||||
|
background: #000;
|
||||||
|
border-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark .history .result {
|
||||||
|
color: #e9ecef;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark .history .time {
|
||||||
|
color: #adb5bd;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark .history .formula-container {
|
||||||
|
color: #adb5bd;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark .history .formula-container .formula {
|
||||||
|
background: #2d3436;
|
||||||
|
color: #ddd;
|
||||||
|
border-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark .history hr {
|
||||||
|
border-top-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark .history-entry-details {
|
||||||
|
border-top-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 767px) {
|
@media screen and (max-width: 767px) {
|
||||||
.dices {
|
.dices {
|
||||||
font-size: 0.65em;
|
font-size: 0.65em;
|
||||||
@@ -381,4 +484,50 @@ body.dark .form select {
|
|||||||
min-width: auto;
|
min-width: auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.history-entry {
|
||||||
|
padding: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-entry-header {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-entry-header .label {
|
||||||
|
flex: 0 1 auto;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-entry-header .result {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-entry-header .time {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
min-width: 6em;
|
||||||
|
margin-left: auto;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history .result {
|
||||||
|
font-size: 1.5em;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history .time {
|
||||||
|
align-self: center;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history .label {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dice-icon {
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user