Skip to content

Commit a34950d

Browse files
committed
Fix small bugs and add the starting time of the session
1 parent 3ee98bd commit a34950d

11 files changed

+104
-20
lines changed

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ The app supports both Gong Fu Cha and Western-style brewing and comes with prede
1919
- PWA support for installation on devices and subsequent offline use.
2020
- Dark mode for low-light environments.
2121
- Supports both Gong Fu Cha and Western-style brewing.
22+
- Remembers when the session was started and how many infusions have been brewed.
2223
- Choose from predefined tea presets.
2324
- Set custom initial infusion time and increment per infusion.
2425
- Timer for each infusion with a countdown and progress bar.

Diff for: src/assets/types.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ export interface TeaPreset {
66
additionalInfusions: number
77
}
88

9-
export interface Settings {
9+
export interface SessionSettings {
1010
initialTime: number
1111
incrementTime: number
1212
infusionCount: number
1313
method: BrewMethod
14+
startedAt: number
1415
savedAt: number
1516
}
1617

Diff for: src/components/CustomSettings.vue

+5-5
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
</div>
1515
</div>
1616
<div class="field">
17-
<label class="label is-size-6" for="incrementTime"
18-
>Time Increment per Infusion (seconds):</label
19-
>
17+
<label class="label is-size-6" for="incrementTime">
18+
Time Increment per Infusion (seconds):
19+
</label>
2020
<div class="control">
2121
<input
2222
id="incrementTime"
@@ -46,15 +46,15 @@ export default defineComponent({
4646
required: true,
4747
},
4848
},
49-
emits: ['updateInitialTime', 'updateInitialTime'],
49+
emits: ['updateInitialTime', 'updateIncrementTime'],
5050
methods: {
5151
updateInitialTime(event: Event) {
5252
const target = event.target as HTMLInputElement
5353
this.$emit('updateInitialTime', parseInt(target.value, 10))
5454
},
5555
updateIncrementTime(event: Event) {
5656
const target = event.target as HTMLInputElement
57-
this.$emit('updateInitialTime', parseInt(target.value, 10))
57+
this.$emit('updateIncrementTime', parseInt(target.value, 10))
5858
},
5959
},
6060
})

Diff for: src/components/SettingsPanel.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
<PresetDetails v-if="selectedPreset" :preset="selectedPreset" />
1818
<CustomSettings
1919
v-else
20-
v-model:incrementTime="incrementTime"
21-
v-model:initialTime="initialTime"
20+
:incrementTime="incrementTime"
21+
:initialTime="initialTime"
2222
@updateIncrementTime="incrementTime = $event"
2323
@updateInitialTime="initialTime = $event"
2424
/>

Diff for: src/components/TimerAdjustment.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ export default defineComponent({
6464
emits: ['updateOffsetTime'],
6565
data() {
6666
return {
67-
positivePercentageAdjustments: [10, 25, 50],
68-
negativePercentageAdjustments: [10, 25, 50].reverse(),
67+
positivePercentageAdjustments: [25, 50, 75],
68+
negativePercentageAdjustments: [25, 50, 75].reverse(),
6969
}
7070
},
7171
methods: {

Diff for: src/components/TimerDisplay.vue

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
<template>
22
<div class="content has-text-centered mt-5">
3-
<p class="title is-2">
4-
Current Infusion: <span class="has-text-weight-bold">{{ infusionCount }}</span>
3+
<p id="infusion-counter" class="title is-2">
4+
<span class="has-text-weight-bold">Current Infusion:</span>
5+
{{ infusionCount }}
6+
</p>
7+
<p id="start-time" class="title is-6">
8+
<span class="has-text-weight-bold">Started at:</span>
9+
{{ startedAt.toLocaleTimeString(undefined, dateFormatOptions) }}
510
</p>
611
<p class="title is-1">
712
<span id="timer">{{ timeRemaining.toFixed(2) }}</span>
@@ -42,6 +47,10 @@ export default defineComponent({
4247
type: Number,
4348
required: true,
4449
},
50+
startedAt: {
51+
type: Date,
52+
required: true,
53+
},
4554
},
4655
emits: ['finishInfusion', 'updateTimerRunning'],
4756
data() {
@@ -54,6 +63,7 @@ export default defineComponent({
5463
intervalId: null as number | null,
5564
beepEnd: new Audio('./audio/sonar_high.mp3'),
5665
beepWarning: new Audio('./audio/sonar_low.mp3'),
66+
dateFormatOptions: { hour: '2-digit', minute: '2-digit', hour12: false } as const,
5767
}
5868
},
5969
computed: {
@@ -190,6 +200,14 @@ export default defineComponent({
190200
</script>
191201

192202
<style scoped>
203+
#infusion-counter {
204+
margin-bottom: 0.5em;
205+
}
206+
207+
#start-time {
208+
margin-bottom: 2em;
209+
}
210+
193211
#timer {
194212
font-size: 3.5rem;
195213
font-weight: bold;

Diff for: src/components/TimerPanel.vue

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
:infusionCount="infusionCount"
88
:initialTime="initialTime"
99
:offsetTime="offsetTime"
10+
:startedAt="startedAt"
1011
@finishInfusion="finishInfusion"
1112
@updateTimerRunning="timerRunning = $event"
1213
/>
@@ -63,6 +64,10 @@ export default defineComponent({
6364
type: Number,
6465
required: true,
6566
},
67+
startedAt: {
68+
type: Date,
69+
required: true,
70+
},
6671
},
6772
emits: ['changedInfusionCount', 'finishInfusion', 'backToSettings'],
6873
data() {

Diff for: src/shared.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* Checks if the given timestamp is older than 12 hours from the current time (epoch).
3+
*
4+
* @param savedAt The timestamp to check (epoch).
5+
*/
6+
export function isOlderThan12hours(savedAt: number): boolean {
7+
if (!savedAt) return true
8+
return Date.now() - savedAt > 12 * 60 * 60 * 1000
9+
}

Diff for: src/views/AboutView.vue

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
<li>Responsive design that works well on both desktop and mobile devices.</li>
1313
<li>PWA support for installation on devices and subsequent offline use.</li>
1414
<li>Dark mode for low-light environments.</li>
15+
<li>Supports both Gong Fu Cha and Western-style brewing.</li>
16+
<li>Remembers when the session was started and how many infusions have been brewed.</li>
1517
<li>Choose from predefined tea presets.</li>
1618
<li>Set custom initial infusion time and increment per infusion.</li>
1719
<li>Timer for each infusion with a countdown and progress bar.</li>

Diff for: src/views/BrewView.vue

+26-8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
:incrementTime="incrementTime"
1414
:infusionCount="infusionCount"
1515
:initialTime="initialTime"
16+
:startedAt="new Date(startedAt)"
1617
@backToSettings="backToSettings"
1718
@changedInfusionCount="updateInfusionCount"
1819
@finishInfusion="finishInfusion"
@@ -27,8 +28,9 @@ import TimerPanel from '@/components/TimerPanel.vue'
2728
import SettingsPanel from '@/components/SettingsPanel.vue'
2829
import BackToSettings from '@/components/BackToSettings.vue'
2930
import FooterAttribution from '@/components/FooterAttribution.vue'
30-
import type { Settings, TeaPreset } from '@/assets/types'
31+
import type { SessionSettings, TeaPreset } from '@/assets/types'
3132
import { BrewMethod } from '@/assets/types'
33+
import { isOlderThan12hours } from '@/shared'
3234
3335
export default defineComponent({
3436
name: 'BrewView',
@@ -57,6 +59,7 @@ export default defineComponent({
5759
initialTime: this.customDefaults.initialTime,
5860
incrementTime: this.customDefaults.incrementTime,
5961
infusionCount: 1,
62+
startedAt: Date.now(),
6063
timerRunning: false,
6164
showSettings: false,
6265
chineseTeaProverbs: [
@@ -68,6 +71,17 @@ export default defineComponent({
6871
],
6972
}
7073
},
74+
watch: {
75+
/**
76+
* Watches for changes to the infusion count and sets the start time once the first infusion is complete.
77+
*/
78+
infusionCount(newCount) {
79+
if (newCount === 2) {
80+
const initialTimeMillis = this.initialTime * 1000
81+
this.startedAt = Date.now() - initialTimeMillis
82+
}
83+
},
84+
},
7185
methods: {
7286
/**
7387
* Confirm the settings and save them to local storage.
@@ -76,22 +90,20 @@ export default defineComponent({
7690
this.initialTime = event.initialTime
7791
this.incrementTime = event.incrementTime
7892
this.infusionCount = 1
93+
this.startedAt = Date.now()
94+
7995
this.persistSettings()
96+
8097
this.showSettings = false
8198
},
8299
/**
83100
* Load the settings from local storage.
84101
*/
85102
loadSettings() {
86-
function isOlderThan12hours(savedAt: number) {
87-
if (!savedAt) return true
88-
return Date.now() - savedAt > 12 * 60 * 60 * 1000
89-
}
90-
91103
const storedSettings = localStorage.getItem('settings')
92104
93105
if (storedSettings) {
94-
const settings: Settings = JSON.parse(storedSettings)
106+
const settings: SessionSettings = JSON.parse(storedSettings)
95107
96108
// Clear settings if:
97109
// - the settings were saved more than 12 hours ago
@@ -103,12 +115,14 @@ export default defineComponent({
103115
!settings.initialTime ||
104116
!settings.incrementTime
105117
) {
118+
console.log('Settings are outdated or malformed; discarding them')
106119
localStorage.removeItem('settings')
107120
this.showSettings = true
108121
} else {
109122
this.initialTime = settings.initialTime
110123
this.incrementTime = settings.incrementTime
111124
this.infusionCount = settings.infusionCount || 1
125+
this.startedAt = settings.startedAt || Date.now()
112126
this.showSettings = false
113127
}
114128
} else {
@@ -120,8 +134,10 @@ export default defineComponent({
120134
*/
121135
finishInfusion(event: { infusionCount: number; offsetTime: number }) {
122136
console.log(`Enjoy your tea: ${this.getRandomTeaProverb()}`)
137+
123138
this.initialTime += event.offsetTime
124139
this.infusionCount = event.infusionCount
140+
125141
this.persistSettings()
126142
},
127143
/**
@@ -145,11 +161,12 @@ export default defineComponent({
145161
* Persist the current settings to local storage.
146162
*/
147163
persistSettings() {
148-
const settings: Settings = {
164+
const settings: SessionSettings = {
149165
initialTime: this.initialTime,
150166
incrementTime: this.incrementTime,
151167
infusionCount: this.infusionCount,
152168
method: this.method,
169+
startedAt: this.startedAt,
153170
savedAt: Date.now(),
154171
}
155172
localStorage.setItem('settings', JSON.stringify(settings))
@@ -159,6 +176,7 @@ export default defineComponent({
159176
*/
160177
updateInfusionCount(infusionCount: number) {
161178
this.infusionCount = infusionCount
179+
162180
this.persistSettings()
163181
},
164182
/**

Diff for: src/views/HomeView.vue

+30
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
<script lang="ts">
5151
import { defineComponent } from 'vue'
5252
import FooterAttribution from '@/components/FooterAttribution.vue'
53+
import { BrewMethod, type SessionSettings } from '@/assets/types'
54+
import { isOlderThan12hours } from '@/shared'
5355
5456
export default defineComponent({
5557
name: 'HomeView',
@@ -63,6 +65,34 @@ export default defineComponent({
6365
selectWestern() {
6466
this.$router.push('/western-brew')
6567
},
68+
loadSettings() {
69+
const storedSettings = localStorage.getItem('settings')
70+
71+
if (storedSettings) {
72+
const settings: SessionSettings = JSON.parse(storedSettings)
73+
74+
if (isOlderThan12hours(settings.savedAt)) {
75+
console.log('Settings are outdated; discarding them')
76+
localStorage.removeItem('settings')
77+
return
78+
}
79+
80+
switch (settings.method) {
81+
case BrewMethod.GONG_FU:
82+
this.selectGongFu()
83+
break
84+
case BrewMethod.WESTERN:
85+
this.selectWestern()
86+
break
87+
default:
88+
console.warn('Unknown brewing method:', settings.method)
89+
break
90+
}
91+
}
92+
},
93+
},
94+
mounted() {
95+
this.loadSettings()
6696
},
6797
})
6898
</script>

0 commit comments

Comments
 (0)