+
`;
+ }
+}
diff --git a/src/script/components/active-timer.ts b/src/script/components/active-timer.ts
index 895ceb8..ec7cb2f 100644
--- a/src/script/components/active-timer.ts
+++ b/src/script/components/active-timer.ts
@@ -1,12 +1,19 @@
import { LitElement, css, html } from 'lit';
import { property, customElement } from 'lit/decorators.js';
-import { durationString, IntervalTimer, className } from '../timer';
+import {durationString, IntervalTimer, className, Phase} from '../timer';
import { TimerState } from '../timer-state';
@customElement('active-timer')
export class ActiveTimer extends LitElement {
@property({ type: Object }) timer!: IntervalTimer;
@property({ type: Object }) timerState!: TimerState;
+ private sounds = new Map([
+ [Phase.WARM_UP, new Audio('assets/audio/warm.mp3')],
+ [Phase.LOW_INTENSITY, new Audio('assets/audio/low.mp3')],
+ [Phase.HIGH_INTENSITY, new Audio('assets/audio/high.mp3')],
+ [Phase.REST, new Audio('assets/audio/rest.mp3')],
+ [Phase.COOLDOWN, new Audio('assets/audio/cool.mp3')],
+ ]);
static get styles() {
return css`
@@ -95,7 +102,7 @@ export class ActiveTimer extends LitElement {
updated() {
if (!this.timerState || this.timerState.timer !== this.timer) {
- this.timerState = new TimerState(this.timer, () => this.requestUpdate());
+ this.timerState = new TimerState(this.timer, () => this.requestUpdate(), this.sounds);
}
}
diff --git a/src/script/components/counter.js b/src/script/components/counter.js
new file mode 100644
index 0000000..7187570
--- /dev/null
+++ b/src/script/components/counter.js
@@ -0,0 +1,48 @@
+import { LitElement, css, html } from 'lit';
+import { property, customElement } from 'lit/decorators.js';
+
+/** @extends LitElement */
+@customElement('labeled-counter')
+export class Counter extends LitElement {
+ /** */
+ @property({ type: String })
+ label = undefined;
+ /** */
+ @property({ type: String })
+ value = undefined;
+
+ /** @static */
+ static get styles() {
+ return css `
+ .label {
+ font-size: calc();
+ text-transform: uppercase;
+ }
+
+ .label, .value {
+ margin: 0;
+ padding: 0;
+ text-align: center;
+ }
+
+ .value {
+ font-size: 2em;
+ font-weight: bold;
+ }
+ `;
+ }
+
+ constructor() {
+ super();
+ }
+
+ /** @returns {any} */
+ render() {
+ return html `
+
+
+
+
+
+ ${this.timerState.phase}
+${durationString(this.timerState.timeRemaining)}
+
+
+
+
+
+ ${this.toggleIcon()}
+
+
+
+
+
+
+
+ `;
+ }
+}
diff --git a/src/script/components/header.js b/src/script/components/header.js
new file mode 100644
index 0000000..482903b
--- /dev/null
+++ b/src/script/components/header.js
@@ -0,0 +1,71 @@
+import { LitElement, css, html } from 'lit';
+import { property, customElement } from 'lit/decorators.js';
+
+/** @extends LitElement */
+@customElement('app-header')
+export class AppHeader extends LitElement {
+ /** */
+ @property({ type: String })
+ apptitle = undefined;
+ /** */
+ @property({ type: Array })
+ timers = undefined;
+ /** */
+ @property({ type: Number })
+ selectedTimer = undefined;
+ /** @default false */
+ @property({ type: Boolean })
+ showSidebar = false;
+
+ /** @static */
+ static get styles() {
+ return css `
+
+
+ #menu-button-block {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
+
+ #menu-button-block img {
+ display: block;
+ }
+
+ .spacer {
+ width: 1em;
+ }
+
+ @media(prefers-color-scheme: light) {
+ nav fluent-anchor::part(control) {
+ color: initial;
+ }
+ }
+ `;
+ }
+
+ /** @returns {void} */
+ toggleSidebar() {
+ this.showSidebar = !this.showSidebar;
+ }
+
+ /** @returns {void} */
+ closeSidebar() {
+ this.showSidebar = false;
+ }
+
+ constructor() {
+ super();
+ }
+
+ /** @returns {any} */
+ render() {
+ return html `
+ ${this.label}
+${this.value}
+