improve styling, sort dices
This commit is contained in:
@@ -23,6 +23,9 @@ class Dice {
|
||||
}
|
||||
|
||||
fromText(value) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
const result = value.match(localeData && localeData['regex'] || dice_regex);
|
||||
if (result) {
|
||||
if (result[1]) {
|
||||
@@ -51,7 +54,7 @@ class DiceHistoryEntry {
|
||||
}
|
||||
|
||||
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+)?(\\[(.+)\\])?");
|
||||
|
||||
@@ -209,7 +212,6 @@ function renderHistory() {
|
||||
}
|
||||
|
||||
if (redoHistory.length) {
|
||||
console.log(redoHistory);
|
||||
document.getElementById('history-redo-button').classList.remove("disabled");
|
||||
} else {
|
||||
document.getElementById('history-redo-button').classList.add("disabled");
|
||||
@@ -217,13 +219,42 @@ function renderHistory() {
|
||||
|
||||
history.forEach((entry) => {
|
||||
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");
|
||||
diceLabelContainer.classList.add("label");
|
||||
if (entry.dices) {
|
||||
entry.dices.forEach((diceData, i) => {
|
||||
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");
|
||||
diceLabel.innerHTML = dice.toText() + (i == entry.dices.length - 1 ? ": " : "");
|
||||
diceLabel.innerHTML = dice.toText();
|
||||
diceLabel.style.color = dice.color;
|
||||
// revert b/w on dark-mode
|
||||
if (darkMode) {
|
||||
@@ -234,6 +265,7 @@ function renderHistory() {
|
||||
}
|
||||
}
|
||||
diceLabelContainer.appendChild(diceLabel);
|
||||
|
||||
if (i < entry.dices.length - 1) {
|
||||
const diceLabelAdd = document.createElement("span");
|
||||
diceLabelAdd.innerHTML = " + ";
|
||||
@@ -241,48 +273,130 @@ function renderHistory() {
|
||||
}
|
||||
})
|
||||
}
|
||||
historyContainer.appendChild(diceLabelContainer);
|
||||
|
||||
|
||||
const diceResult = document.createElement("span");
|
||||
// Create result display
|
||||
const diceResult = document.createElement("div");
|
||||
diceResult.classList.add("result");
|
||||
diceResult.innerText = entry.result;
|
||||
historyContainer.appendChild(diceResult);
|
||||
|
||||
const diceFormulaContainer = document.createElement("span");
|
||||
diceFormulaContainer.classList.add("formula-container");
|
||||
historyContainer.appendChild(diceFormulaContainer);
|
||||
entryHeader.appendChild(diceLabelContainer);
|
||||
|
||||
if (entry.formula) {
|
||||
const diceFormulaEqual = document.createElement("span");
|
||||
diceFormulaEqual.innerText = " = ";
|
||||
diceFormulaContainer.appendChild(diceFormulaEqual);
|
||||
const diceFormula = document.createElement("span");
|
||||
diceFormula.classList.add("formula");
|
||||
diceFormula.innerText = entry.formula;
|
||||
diceFormulaContainer.appendChild(diceFormula);
|
||||
// Only show result in header if there's no formula
|
||||
if (!entry.formula) {
|
||||
entryHeader.appendChild(diceResult);
|
||||
}
|
||||
|
||||
const diceTime = document.createElement("span");
|
||||
// Create time display
|
||||
const diceTime = document.createElement("div");
|
||||
diceTime.classList.add("time");
|
||||
historyContainer.appendChild(diceTime);
|
||||
|
||||
if (entry.time) {
|
||||
entry.time.locale(locale);
|
||||
diceTime.innerText = entry.time.fromNow();
|
||||
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 {
|
||||
// Add separator for different roll sessions
|
||||
historyContainer.appendChild(document.createElement("hr"));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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 = "";
|
||||
for (let index = 0; index < dice.count; index++) {
|
||||
formula += Math.floor(Math.random() * dice.sides + 1);
|
||||
formula += rolls[index];
|
||||
if (index < dice.count - 1) {
|
||||
formula += " + ";
|
||||
}
|
||||
|
||||
@@ -210,6 +210,9 @@ body {
|
||||
align-items: center;
|
||||
row-gap: 1em;
|
||||
grid-template-columns: auto;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-container .actions {
|
||||
@@ -261,45 +264,114 @@ body {
|
||||
}
|
||||
|
||||
.history {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, auto);
|
||||
width: 100%;
|
||||
margin-top: 1.5em;
|
||||
margin-bottom: 0.5em;
|
||||
row-gap: 0.3em;
|
||||
column-gap: 0.3em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.8em;
|
||||
}
|
||||
|
||||
.history hr {
|
||||
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 {
|
||||
font-size: 1.2em;
|
||||
font-size: 1.1em;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
}
|
||||
|
||||
.history .result {
|
||||
text-align: center;
|
||||
font-size: 1.2em;
|
||||
font-size: 1.8em;
|
||||
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 {
|
||||
display: flex;
|
||||
margin: 0 0.5em;
|
||||
align-items: center;
|
||||
font-size: 0.95em;
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
|
||||
.history .formula-container .formula {
|
||||
display: flex;
|
||||
margin: 0 0.5em;
|
||||
margin-left: 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 {
|
||||
text-align: right;
|
||||
.dice-icon {
|
||||
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 {
|
||||
@@ -366,6 +438,37 @@ body.dark .form select {
|
||||
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) {
|
||||
.dices {
|
||||
font-size: 0.65em;
|
||||
@@ -381,4 +484,50 @@ body.dark .form select {
|
||||
min-width: auto;
|
||||
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