456 files
This commit is contained in:
@@ -132,6 +132,18 @@ class TaskMateStreakCard extends LitElement {
|
||||
|
||||
.streak-emoji { font-size: 1.4rem; }
|
||||
|
||||
/* Streak freeze tokens (#925) */
|
||||
.streak-freeze {
|
||||
margin-inline-start: auto;
|
||||
padding: 2px 9px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
background: rgba(52, 152, 219, 0.14);
|
||||
color: #1f6fa8;
|
||||
}
|
||||
|
||||
/* Streak bar - visual days */
|
||||
.streak-days {
|
||||
display: flex;
|
||||
@@ -247,6 +259,9 @@ class TaskMateStreakCard extends LitElement {
|
||||
.sk-seg-cp { flex: 1; height: 9px; border-radius: 3px; background: var(--tmd-surface-2); }
|
||||
.sk-seg-cp.on { background: var(--tmd-good); }
|
||||
.sk-badges-cp { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 9px; }
|
||||
|
||||
/* Streak freeze tokens (#925), every designed layout */
|
||||
.sk-freeze { white-space: nowrap; flex: none; }
|
||||
`;
|
||||
const tokens = window.__taskmate_design && window.__taskmate_design.styles
|
||||
? window.__taskmate_design.styles() : null;
|
||||
@@ -343,6 +358,7 @@ class TaskMateStreakCard extends LitElement {
|
||||
<span class="streak-number ${streakClass}">${streak}</span>
|
||||
<span class="streak-label">${this._t('streak.day_streak')}</span>
|
||||
<span class="streak-emoji">${streakEmoji}</span>
|
||||
${this._freezeChip(child, "streak-freeze")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -370,6 +386,20 @@ class TaskMateStreakCard extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Streak-freeze tokens (#925): "❄️ N". The sensor only sends
|
||||
* streak_freezes while the feature is on, so an absent field means
|
||||
* "not in use" and renders nothing — a 0 still shows, so a child can
|
||||
* see they have none left. Used by the classic tile AND every designed
|
||||
* layout (the two-render-paths rule).
|
||||
*/
|
||||
_freezeChip(child, cls) {
|
||||
const n = child.streak_freezes;
|
||||
if (typeof n !== "number") return "";
|
||||
return html`<span class="${cls}" title="${this._t('streak.freezes_tooltip')}"
|
||||
aria-label="${this._t('streak.freezes_aria', { count: n })}">❄️ ${n}</span>`;
|
||||
}
|
||||
|
||||
_calculateStreak(completions) {
|
||||
const tz = this.hass?.config?.time_zone || Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
|
||||
@@ -577,6 +607,7 @@ class TaskMateStreakCard extends LitElement {
|
||||
<div class="muted sk-sub">${this._t('streak.day_streak')}</div>
|
||||
</div>
|
||||
<div class="big sk-count">${r.streak} ${this._streakEmoji(r.streak)}</div>
|
||||
${this._freezeChip(r.child, "chip soft sk-freeze")}
|
||||
</div>
|
||||
<div class="sk-dots">
|
||||
${r.dayDots.map((d) => html`<i class="sk-dot ${d.cssClass !== "inactive" ? "on" : ""}" title="${d.label}"></i>`)}
|
||||
@@ -598,6 +629,7 @@ class TaskMateStreakCard extends LitElement {
|
||||
<div class="muted sk-combo-label">${this._t('streak.achievements')}</div>
|
||||
</div>
|
||||
<div class="num sk-combo">x${r.streak} ${this._streakEmoji(r.streak)}</div>
|
||||
${this._freezeChip(r.child, "chip sk-freeze")}
|
||||
</div>
|
||||
<div class="sk-segs">
|
||||
${r.dayDots.map((d) => html`<i class="sk-seg ${d.cssClass !== "inactive" ? "on" : ""}"></i>`)}
|
||||
@@ -618,6 +650,7 @@ class TaskMateStreakCard extends LitElement {
|
||||
${this._av(r.child, r.tone, 34)}
|
||||
<div style="flex:1;min-width:0"><div style="font-weight:600">${r.child.name}</div></div>
|
||||
<div class="num" style="color:${tone(r.streak)}">${this._streakEmoji(r.streak)} ${this._t('common.d_streak', { count: r.streak })}</div>
|
||||
${this._freezeChip(r.child, "chip sk-freeze")}
|
||||
</div>
|
||||
<div class="sk-segs-cp">
|
||||
${r.dayDots.map((d) => html`<i class="sk-seg-cp ${d.cssClass !== "inactive" ? "on" : ""}"></i>`)}
|
||||
@@ -654,7 +687,7 @@ class TaskMateStreakCardEditor extends LitElement {
|
||||
.preset-swatch { width: 22px; height: 22px; border-radius: 50%; cursor: pointer; border: 2px solid var(--divider-color, #e0e0e0); transition: transform 0.1s; padding: 0; }
|
||||
.preset-swatch:hover { transform: scale(1.15); }
|
||||
.preset-swatch.active { border-color: var(--primary-text-color); box-shadow: 0 0 0 2px var(--primary-color); }
|
||||
.colour-reset { font-size: 0.78rem; color: var(--secondary-text-color); background: none; border: 1px solid var(--divider-color, #e0e0e0); border-radius: 4px; padding: 4px 10px; cursor: pointer; margin-left: auto; }
|
||||
.colour-reset { font-size: 0.78rem; color: var(--secondary-text-color); background: none; border: 1px solid var(--divider-color, #e0e0e0); border-radius: 4px; padding: 4px 10px; cursor: pointer; margin-inline-start: auto; }
|
||||
.colour-helper { color: var(--secondary-text-color); font-size: 0.82rem; line-height: 1.3; }
|
||||
`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user