feat: add German localization and wrap countdown visual elements for styling improvements.

This commit is contained in:
CPTN Cosmo 2025-12-22 15:17:54 +01:00
parent d39c5e3568
commit f4f549e018
5 changed files with 201 additions and 133 deletions

4
lang/de.json Normal file
View file

@ -0,0 +1,4 @@
{
"DHIC.Countdowns": "Countdowns",
"DHIC.CreateNewCountdown": "Neuen Countdown erstellen"
}

View file

@ -1,7 +1,7 @@
{ {
"id": "dh-improved-countdowns", "id": "dh-improved-countdowns",
"title": "Improved Countdowns", "title": "Improved Countdowns",
"version": "1.2.1", "version": "1.2.2",
"compatibility": { "compatibility": {
"minimum": "13", "minimum": "13",
"verified": "13" "verified": "13"
@ -35,10 +35,15 @@
"lang": "en", "lang": "en",
"name": "English", "name": "English",
"path": "lang/en.json" "path": "lang/en.json"
},
{
"lang": "de",
"name": "Deutsch",
"path": "lang/de.json"
} }
], ],
"description": "A modern, draggable countdown tracker for the Daggerheart system.", "description": "A modern, draggable countdown tracker for the Daggerheart system.",
"url": "https://github.com/cptn-cosmo/dh-improved-countdowns", "url": "https://github.com/cptn-cosmo/dh-improved-countdowns",
"manifest": "https://github.com/cptn-cosmo/dh-improved-countdowns/releases/latest/download/module.json", "manifest": "https://github.com/cptn-cosmo/dh-improved-countdowns/releases/latest/download/module.json",
"download": "https://github.com/cptn-cosmo/dh-improved-countdowns/releases/download/1.2.1/dh-improved-countdowns.zip" "download": "https://github.com/cptn-cosmo/dh-improved-countdowns/releases/download/1.2.2/dh-improved-countdowns.zip"
} }

View file

@ -43,7 +43,11 @@ export class CountdownTrackerApp extends HandlebarsApplicationMixin(ApplicationV
static initialize() { static initialize() {
this.instance = new CountdownTrackerApp(); this.instance = new CountdownTrackerApp();
const pos = game.settings.get("dh-improved-countdowns", "position"); let pos = game.settings.get("dh-improved-countdowns", "position");
if (!pos || (!pos.top && !pos.left) || (pos.top === 0 && pos.left === 0 && !pos.width)) {
// Default to top-left if no valid position is stored
pos = { top: 100, left: 100 };
}
this.instance.render(true, { position: pos }); this.instance.render(true, { position: pos });
} }

View file

@ -108,6 +108,27 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 16px; gap: 16px;
max-height: 60vh;
overflow-y: auto;
overflow-x: hidden;
padding-right: 4px;
/* Space for scrollbar */
/* Custom scrollbar for webkit */
scrollbar-width: thin;
scrollbar-color: rgba(255, 255, 255, 0.2) transparent;
}
.countdowns-list::-webkit-scrollbar {
width: 4px;
}
.countdowns-list::-webkit-scrollbar-track {
background: transparent;
}
.countdowns-list::-webkit-scrollbar-thumb {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 4px;
} }
.countdown-item { .countdown-item {
@ -125,10 +146,22 @@
letter-spacing: 0.5px; letter-spacing: 0.5px;
color: rgba(255, 255, 255, 0.8); color: rgba(255, 255, 255, 0.8);
text-align: center; text-align: center;
/* max-width removed to allow natural width, or increased if needed */
max-width: 150px; max-width: 150px;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
/* Allow wrapping */
line-height: 1.2;
transition: max-width 0.3s ease;
}
.countdown-tracker-window:not(.minimized):hover .countdown-name {
max-width: 250px;
/* Reduced from none to provide some limit, or use none */
overflow: visible;
white-space: normal;
/* Allow wrapping */
} }
.countdown-visual { .countdown-visual {
@ -137,6 +170,14 @@
gap: 10px; gap: 10px;
} }
.visual-wrapper {
position: relative;
display: flex;
align-items: center;
justify-content: center;
/* Ensure the number overlay is positioned relative to this wrapper */
}
.icon-container { .icon-container {
position: relative; position: relative;
width: 48px; width: 48px;
@ -164,10 +205,9 @@
.value-overlay { .value-overlay {
position: absolute; position: absolute;
top: 0; top: 50%;
left: 0; left: 50%;
width: 100%; transform: translate(-50%, -50%);
height: 100%;
pointer-events: none; pointer-events: none;
display: flex; display: flex;
align-items: center; align-items: center;
@ -179,9 +219,18 @@
font-weight: 800; font-weight: 800;
color: #fff; color: #fff;
text-shadow: 0 0 4px rgba(0, 0, 0, 0.9), 0 0 8px rgba(0, 0, 0, 0.9); text-shadow: 0 0 4px rgba(0, 0, 0, 0.9), 0 0 8px rgba(0, 0, 0, 0.9);
width: max-content;
/* Allow numbers to extend beyond icon width if needed */
pointer-events: none;
z-index: 10;
} }
.value-overlay.visual { .value-overlay.visual {
width: 100%;
height: 100%;
top: 0;
left: 0;
transform: none;
background: rgba(0, 0, 0, 0.2); background: rgba(0, 0, 0, 0.2);
} }

View file

@ -35,6 +35,7 @@
</a> </a>
{{/if}} {{/if}}
<div class="visual-wrapper">
<div class="icon-container {{countdown.cssClass}}" {{#if <div class="icon-container {{countdown.cssClass}}" {{#if
../isMinimized}}data-tooltip="{{countdown.name}}" {{/if}}> ../isMinimized}}data-tooltip="{{countdown.name}}" {{/if}}>
<img src="{{countdown.img}}" class="countdown-icon" /> <img src="{{countdown.img}}" class="countdown-icon" />
@ -136,22 +137,26 @@
{{else}} {{else}}
{{#if (eq ../borderEdge "bottom")}} {{#if (eq ../borderEdge "bottom")}}
<line x1="1" y1="1" x2="1" y2="47" stroke="{{../borderColor}}" stroke-width="2" <line x1="1" y1="1" x2="1" y2="47" stroke="{{../borderColor}}" stroke-width="2"
stroke-linecap="round" pathLength="100" stroke-dasharray="{{countdown.percentage}} 100" stroke-linecap="round" pathLength="100"
stroke-dasharray="{{countdown.percentage}} 100"
style="transition: stroke-dasharray 0.3s ease; opacity: 1;"> style="transition: stroke-dasharray 0.3s ease; opacity: 1;">
</line> </line>
{{else if (eq ../borderEdge "top")}} {{else if (eq ../borderEdge "top")}}
<line x1="47" y1="1" x2="47" y2="47" stroke="{{../borderColor}}" stroke-width="2" <line x1="47" y1="1" x2="47" y2="47" stroke="{{../borderColor}}" stroke-width="2"
stroke-linecap="round" pathLength="100" stroke-dasharray="{{countdown.percentage}} 100" stroke-linecap="round" pathLength="100"
stroke-dasharray="{{countdown.percentage}} 100"
style="transition: stroke-dasharray 0.3s ease; opacity: 1;"> style="transition: stroke-dasharray 0.3s ease; opacity: 1;">
</line> </line>
{{else if (eq ../borderEdge "left")}} {{else if (eq ../borderEdge "left")}}
<line x1="1" y1="1" x2="47" y2="1" stroke="{{../borderColor}}" stroke-width="2" <line x1="1" y1="1" x2="47" y2="1" stroke="{{../borderColor}}" stroke-width="2"
stroke-linecap="round" pathLength="100" stroke-dasharray="{{countdown.percentage}} 100" stroke-linecap="round" pathLength="100"
stroke-dasharray="{{countdown.percentage}} 100"
style="transition: stroke-dasharray 0.3s ease; opacity: 1;"> style="transition: stroke-dasharray 0.3s ease; opacity: 1;">
</line> </line>
{{else if (eq ../borderEdge "right")}} {{else if (eq ../borderEdge "right")}}
<line x1="1" y1="47" x2="47" y2="47" stroke="{{../borderColor}}" stroke-width="2" <line x1="1" y1="47" x2="47" y2="47" stroke="{{../borderColor}}" stroke-width="2"
stroke-linecap="round" pathLength="100" stroke-dasharray="{{countdown.percentage}} 100" stroke-linecap="round" pathLength="100"
stroke-dasharray="{{countdown.percentage}} 100"
style="transition: stroke-dasharray 0.3s ease; opacity: 1;"> style="transition: stroke-dasharray 0.3s ease; opacity: 1;">
</line> </line>
{{/if}} {{/if}}
@ -176,6 +181,7 @@
{{/if}} {{/if}}
</div> </div>
{{/if}} {{/if}}
</div>
{{#if ../showNumbers}} {{#if ../showNumbers}}
<div class="value-overlay number" style="color: {{../numberColor}};"> <div class="value-overlay number" style="color: {{../numberColor}};">