now we can add timers

This commit is contained in:
Zlatko Đurić 2025-04-13 23:14:24 +02:00
parent 5510af02a1
commit cf3815446a
13 changed files with 80 additions and 34 deletions

View File

@ -21,7 +21,9 @@
"add-timer": { "add-timer": {
"timer name": "Timer Name", "timer name": "Timer Name",
"duration": "Dauer", "duration": "Dauer",
"format-hint": "Nutze den Format n (nur Sekunden), mm:ss oder hh:mm:ss für Stunden/Minuten/Sekunden.hours/minutes/seconds." "format-hint": "Nutze den Format n, mm:ss oder hh:mm:ss für Stunden/Minuten/Sekunden.",
"start-now": "Gleich anfangen"
} }
} }
} }

View File

@ -21,7 +21,8 @@
"add-timer": { "add-timer": {
"timer name": "Timer name", "timer name": "Timer name",
"duration": "Duration", "duration": "Duration",
"format-hint": "Use format n (for seconds), mm:ss or hh:mm:ss for hours/minutes/seconds." "format-hint": "Use format s, mm:ss or hh:mm:ss for hours/minutes/seconds.",
"start-now": "Start now"
} }
} }
} }

View File

@ -21,7 +21,9 @@
"add-timer": { "add-timer": {
"timer name": "Ime timera", "timer name": "Ime timera",
"duration": "Trajanje", "duration": "Trajanje",
"format-hint": "Koristi šprancu n za sekunde, mm:ss ili hh:mm:ss za sate/minute/sekunde." "format-hint": "Koristi šprancu s, mm:ss ili hh:mm:ss za sate/minute/sekunde.",
"start-now": "Pokreni odmah"
} }
} }
} }

View File

@ -9,7 +9,7 @@
"url": "https://zlatko.dev" "url": "https://zlatko.dev"
} }
], ],
"version": "0.1.0", "version": "0.1.1",
"compatibility": { "compatibility": {
"minimum": 12, "minimum": 12,
"verified": 12 "verified": 12
@ -18,7 +18,7 @@
"src/timer.js" "src/timer.js"
], ],
"styles": [ "styles": [
"styles/style.css" "styles/yat-style.css"
], ],
"languages": [ "languages": [
{ {

View File

@ -1,4 +1,5 @@
import { logger } from './logger.js'; import { logger } from './logger.js';
import { getNextName, createTimer } from './timer.repository.js';
const templatePath = `modules/yet-another-timer/templates/add-timer.hbs`; const templatePath = `modules/yet-another-timer/templates/add-timer.hbs`;
@ -11,12 +12,15 @@ export class AddTimerScreen extends FormApplication {a
id: "yet-another-timer-add-timer", id: "yet-another-timer-add-timer",
template: templatePath, template: templatePath,
title: game.i18n?.localize("YAT.status.add-timer") || "Add Timer", title: game.i18n?.localize("YAT.status.add-timer") || "Add Timer",
closeOnSubmit: false,
submitOnChange: false,
}; };
return Object.assign({}, defaults, overrides); return Object.assign({}, defaults, overrides);
} }
getData() { getData() {
return { return {
nextName: getNextName()
}; };
} }
@ -26,6 +30,13 @@ export class AddTimerScreen extends FormApplication {a
logger.debug('Activated.'); logger.debug('Activated.');
} }
_updateObject(event, formData) {
logger.debug("Adding a timer", formData, event);
createTimer(formData.duration, formData.name, formData.startNow);
this.close();
// also ping to update?
}
#handleClick(event) { #handleClick(event) {
logger.debug('**click**', event); logger.debug('**click**', event);
const el = $(event.currentTarget); const el = $(event.currentTarget);
@ -36,3 +47,5 @@ export class AddTimerScreen extends FormApplication {a
logger.debug('Data:', data); logger.debug('Data:', data);
} }
} }
export const showAddTimer = () => new AddTimerScreen().render(true);

View File

@ -2,23 +2,30 @@ import { logger } from './logger.js';
const templatePath = `modules/yet-another-timer/templates/timer-complete.hbs`; const templatePath = `modules/yet-another-timer/templates/timer-complete.hbs`;
export class TimerCompleteScreen extends FormApplication {a export class TimerCompleteScreen extends FormApplication {
static get defaultOptions() { static get defaultOptions() {
const defaults = super.defaultOptions; const defaults = super.defaultOptions;
const overrides = { const overrides = {
height: "auto", height: "auto",
id: "yet-another-timer-add-timer", resizable: true,
id: "yet-another-timer-timer-complete",
template: templatePath, template: templatePath,
title: game.i18n?.localize("YAT.timer.complete") || "Timer complete", title: game.i18n?.localize("YAT.timer.complete") || "Timer complete",
}; };
return Object.assign({}, defaults, overrides); return Object.assign({}, defaults, overrides);
} }
data = {}; data = {
names: [],
};
setData(data) { setData(data) {
this.data = data; logger.debug("Adding a completed timer", data);
if (data.name) {
// TODO: dynamically set the id somehow.
this.data.names.push(data.name);
}
} }
getData() { getData() {

View File

@ -2,6 +2,7 @@ import { logger } from "./logger.js";
import { getTimers } from "./timer.repository.js"; import { getTimers } from "./timer.repository.js";
import { getStatus, pauseTimer, resumeTimer, deleteTimer, flipTimers, subscribe } from './timer.loop.js'; import { getStatus, pauseTimer, resumeTimer, deleteTimer, flipTimers, subscribe } from './timer.loop.js';
import { TimerError } from "./error.js"; import { TimerError } from "./error.js";
import { showAddTimer } from './add-timer-screen.js';
const templatePath = `modules/yet-another-timer/templates/timer.hbs`; const templatePath = `modules/yet-another-timer/templates/timer.hbs`;
@ -31,7 +32,7 @@ export class TimerScreen extends FormApplication {
const overrides = { const overrides = {
height: "auto", height: "auto",
width: "33rem", resizable: true,
id: "yet-another-timer", id: "yet-another-timer",
template: templatePath, template: templatePath,
title: game.i18n?.localize("YAT.title") || "Yet another timer", title: game.i18n?.localize("YAT.title") || "Yet another timer",
@ -80,7 +81,7 @@ export class TimerScreen extends FormApplication {
deleteTimer(timerName); deleteTimer(timerName);
break; break;
case 'add-timer': case 'add-timer':
showAddAction() showAddTimer()
break; break;
default: default:
logger.error(`Unknown timer action: ${action}`); logger.error(`Unknown timer action: ${action}`);

View File

@ -110,6 +110,7 @@ function advance(timer, interval_ms) {
function completeTimer(timer) { function completeTimer(timer) {
logger.log(`Timer ${timer.name} completed.`); logger.log(`Timer ${timer.name} completed.`);
timer.isPaused = true; timer.isPaused = true;
timer.isComplete = true;
// ping? close something? // ping? close something?
const timerComplete = new TimerCompleteScreen(); const timerComplete = new TimerCompleteScreen();
timerComplete.setData({ name: timer.name }); timerComplete.setData({ name: timer.name });

View File

@ -89,7 +89,7 @@ function assertValidName(name) {
} }
} }
function getNextName(prefix = 0) { export function getNextName(prefix = 0) {
const name = `timer-${prefix}-${timerMap.size}` const name = `timer-${prefix}-${timerMap.size}`
if (timerMap.has(name)) { if (timerMap.has(name)) {
return getNextName(prefix + 1); return getNextName(prefix + 1);

View File

@ -1,4 +1,5 @@
.timer-card {
#yet-another-timer .timer-card {
border: 1px solid #ccc; border: 1px solid #ccc;
border-radius: 8px; border-radius: 8px;
padding: 15px; padding: 15px;
@ -10,12 +11,12 @@
vertical-align: top; vertical-align: top;
} }
.timer-card.paused { #yet-another-timer .timer-card.paused {
background-color: #eee; background-color: #eee;
opacity: 0.7; opacity: 0.7;
} }
.timer-card .title { #yet-another-timer .timer-card .title {
font-weight: bold; font-weight: bold;
font-size: 1.2em; font-size: 1.2em;
margin-bottom: 10px; margin-bottom: 10px;
@ -23,17 +24,17 @@
padding-bottom: 5px; padding-bottom: 5px;
} }
.timer-card .content p { #yet-another-timer .timer-card .content p {
margin: 5px 0; margin: 5px 0;
font-size: 0.9em; font-size: 0.9em;
} }
.timer-card .actions { #yet-another-timer .timer-card .actions {
margin-top: 15px; margin-top: 15px;
text-align: right; text-align: right;
} }
.timer-card .button { #yet-another-timer .timer-card .button {
padding: 5px 10px; padding: 5px 10px;
margin-left: 5px; margin-left: 5px;
cursor: pointer; cursor: pointer;
@ -42,16 +43,22 @@
background-color: #e0e0e0; background-color: #e0e0e0;
} }
.timer-card .button:hover { #yet-another-timer .timer-card .button:hover {
background-color: #d0d0d0; background-color: #d0d0d0;
} }
.timer-card .delete-button { #yet-another-timer .timer-card .delete-button {
background-color: #f8d7da; background-color: #f8d7da;
border-color: #f5c6cb; border-color: #f5c6cb;
color: #721c24; color: #721c24;
} }
.timer-card .delete-button:hover { #yet-another-timer .timer-card .delete-button:hover {
background-color: #f5c6cb; background-color: #f5c6cb;
} }
.yat-add-form {
display: flex;
flex-flow: column;
gap: 1rem;
}

View File

@ -1,10 +1,20 @@
<h3>{{ localize "YAT.status.add-timer" }}</h3> <h3>{{ localize "YAT.status.add-timer" }}</h3>
<form> <form class="yat-add-form">
<label>{{ localize "YAT.add-timer.timer name" }} <input name="timer-name"></label> <label>
<label>{{ localize "YAT.add-timer.duration" }} <input name="timer-duration"></label> {{ localize "YAT.add-timer.timer name" }} *:
<span class="hint">{{ localize "YAT.add-timer.format-hint" }}</span> <input type="text" name="name" value="{{ nextName }}" required>
<label>{{ localize "YAT.start-now" }} <input type="checkbox" name="timer-start-now"></label> </label>
<label>
{{ localize "YAT.add-timer.duration" }} *:
<input type="text" name="duration" pattern="\d+|\d{2}:\d{2}|\d{2}:\d{2}:\d{2}" required>
</label>
<em class="yat-hint">{{ localize "YAT.add-timer.format-hint" }}</em>
<label>
{{ localize "YAT.add-timer.start-now" }}:
<input type="checkbox" name="startNow">
</label>
<button class="button" data-action="add-timer">{{ localize "YAT.status.add-timer" }}</button> <button class="button" data-action="add-timer">{{ localize "YAT.status.add-timer" }}</button>
</form> </form>

View File

@ -1,3 +1,5 @@
<h2>{{ localize "YAT.timer.your-timer-is-complete" name=name }}!</h2> {{#each names }}
<h2>{{ localize "YAT.timer.your-timer-is-complete" name=this }}!</h2>
{{/each}}
<img src="modules/yet-another-timer/assets/time-out.jpg"> <img src="modules/yet-another-timer/assets/time-out.jpg">

View File

@ -26,13 +26,13 @@
<p>{{ localize "YAT.time-remaining" }}: {{ formatRemainingTime durationSeconds elapsedTimeSeconds }}</p> <p>{{ localize "YAT.time-remaining" }}: {{ formatRemainingTime durationSeconds elapsedTimeSeconds }}</p>
</div> </div>
<div class="actions"> <div class="actions">
{{#unless isComplete }}
{{ isPaused }} {{#if isPaused }}
{{#if isPaused }} <button class="button resume-button" data-action="resume">{{ localize "YAT.resume" }}</button>
<button class="button resume-button" data-action="resume">{{ localize "YAT.resume" }}</button> {{ else }}
{{ else }} <button class="button pause-button" data-action="pause">{{ localize "YAT.pause" }}</button>
<button class="button pause-button" data-action="pause">{{ localize "YAT.pause" }}</button> {{/if }}
{{/if }} {{/unless }}
<button class="button delete-button" data-action="delete">{{ localize "YAT.delete" }}</button> <button class="button delete-button" data-action="delete">{{ localize "YAT.delete" }}</button>
</div> </div>
</section> </section>