Verbessert die Benutzeroberfläche in DiaryView.vue, indem die Struktur des Unfallformulars optimiert und die Audioinitialisierung an die Benutzerinteraktion angepasst wird. Fügt Logik zur Überprüfung von Aktivitätszeiten hinzu und stellt sicher, dass Audio nur bei aktivierter Funktion abgespielt wird.
This commit is contained in:
@@ -311,30 +311,30 @@
|
||||
<div v-if="showImage" class="memberImage">
|
||||
<img :src="imageUrl" @click="closeImage" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showAccidentForm" class="accidentForm">
|
||||
<form @submit.prevent="submitAccident">
|
||||
<div>
|
||||
<label for="memberId">Mitglied:</label>
|
||||
<select id="memberId" v-model="accident.memberId">
|
||||
<template v-for="member in members" :key="member.id" :value="member.id">
|
||||
<option v-if="participants.indexOf(member.id) >= 0" :value="member.id">{{ member.firstName + ' '
|
||||
+ member.lastName }}</option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="accident">Unfall:</label>
|
||||
<textarea id="accident" v-model="accident.accident" required></textarea>
|
||||
</div>
|
||||
<button type="button" @click="saveAccident">Eintragen</button>
|
||||
<button type="button" @click="closeAccidentForm">Schießen</button>
|
||||
<ul>
|
||||
<li v-for="accident in accidents" :key="accident.id">{{ accident.firstName + ' ' + accident.lastName +
|
||||
': '
|
||||
+ accident.accident}}</li>
|
||||
</ul>
|
||||
</form>
|
||||
<div v-if="showAccidentForm" class="accidentForm">
|
||||
<form @submit.prevent="submitAccident">
|
||||
<div>
|
||||
<label for="memberId">Mitglied:</label>
|
||||
<select id="memberId" v-model="accident.memberId">
|
||||
<template v-for="member in members" :key="member.id" :value="member.id">
|
||||
<option v-if="participants.indexOf(member.id) >= 0" :value="member.id">{{ member.firstName + ' '
|
||||
+ member.lastName }}</option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="accident">Unfall:</label>
|
||||
<textarea id="accident" v-model="accident.accident" required></textarea>
|
||||
</div>
|
||||
<button type="button" @click="saveAccident">Eintragen</button>
|
||||
<button type="button" @click="closeAccidentForm">Schießen</button>
|
||||
<ul>
|
||||
<li v-for="accident in accidents" :key="accident.id">{{ accident.firstName + ' ' + accident.lastName +
|
||||
': '
|
||||
+ accident.accident}}</li>
|
||||
</ul>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -398,9 +398,12 @@ export default {
|
||||
tagHistoryMember: null,
|
||||
tagHistory: null,
|
||||
intermediateTimes: [],
|
||||
bellSound: new Audio('/sound/bell-123742.mp3'),
|
||||
thumbSound: new Audio('/sound/thump-105302.mp3'),
|
||||
bellSound: null,
|
||||
thumbSound: null,
|
||||
soundEnabled: true,
|
||||
debugSound: true,
|
||||
timeChecker: null,
|
||||
playedActivityMarks: [],
|
||||
showAccidentForm: false,
|
||||
accident: {
|
||||
memberId: '',
|
||||
@@ -465,6 +468,8 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
async refreshDates(selectId) {
|
||||
const response = await apiClient.get(`/diary/${this.currentClub}`);
|
||||
this.dates = response.data.map(entry => ({ id: entry.id, date: entry.date }));
|
||||
@@ -592,7 +597,7 @@ export default {
|
||||
const response = await apiClient.get(`/group/${this.currentClub}/${this.date.id}`);
|
||||
this.groups = response.data;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
// ignore
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1168,6 +1173,7 @@ export default {
|
||||
if (this.timeChecker) clearInterval(this.timeChecker);
|
||||
this.timeChecker = setInterval(() => {
|
||||
const currentTime = new Date().toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
||||
// Zeit-Check Tick
|
||||
if (!this.trainingStart || !this.trainingEnd) {
|
||||
return;
|
||||
}
|
||||
@@ -1183,40 +1189,80 @@ export default {
|
||||
}
|
||||
if (startCheckTime && currentTime === startCheckTime) {
|
||||
this.playBellSound();
|
||||
}
|
||||
if (endCheckTime && currentTime === endCheckTime) {
|
||||
} else if (endCheckTime && currentTime === endCheckTime) {
|
||||
this.playBellSound();
|
||||
} else {
|
||||
// Nach letzter Aktivität (Ende) nochmal Glocke
|
||||
try { this.calculateAllItemTimes(); } catch (e) {}
|
||||
const items = Array.isArray(this.trainingPlan) ? this.trainingPlan : [];
|
||||
const lastItem = items.length ? items[items.length - 1] : null;
|
||||
const lastEnd = lastItem && lastItem.endTime ? lastItem.endTime : null;
|
||||
const lastEndSS = lastEnd ? (lastEnd.length === 5 ? lastEnd + ':00' : lastEnd) : null;
|
||||
const lastEndMM = lastEndSS ? lastEndSS.slice(0, 5) : null;
|
||||
const currentHHMM = currentTime.slice(0, 5);
|
||||
if (lastEndSS && (currentTime === lastEndSS || (currentTime.endsWith(':00') && currentHHMM === lastEndMM))) {
|
||||
this.playBellSound();
|
||||
}
|
||||
}
|
||||
if (this.intermediateTimes.includes(currentTime)) {
|
||||
// Aktivitätszeiten (Startzeiten) aus Trainingsplan prüfen
|
||||
try { this.calculateAllItemTimes(); } catch (e) {}
|
||||
const items = Array.isArray(this.trainingPlan) ? this.trainingPlan : [];
|
||||
const startTimesSS = items
|
||||
.map(it => (it && it.startTime ? (it.startTime.length === 5 ? it.startTime + ':00' : it.startTime) : null))
|
||||
.filter(Boolean);
|
||||
const startTimesMM = startTimesSS.map(t => t.slice(0, 5));
|
||||
const currentHHMM = currentTime.slice(0, 5);
|
||||
const isMatch = startTimesSS.includes(currentTime) || (currentTime.endsWith(':00') && startTimesMM.includes(currentHHMM));
|
||||
if (isMatch) {
|
||||
this.playThumbSound();
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
playBellSound() {
|
||||
this.bellSound.play();
|
||||
if (!this.soundEnabled) return;
|
||||
try {
|
||||
this.bellSound && this.bellSound.play();
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
},
|
||||
|
||||
playThumbSound() {
|
||||
this.thumbSound.play();
|
||||
if (!this.soundEnabled) return;
|
||||
try {
|
||||
this.thumbSound && this.thumbSound.play();
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
},
|
||||
|
||||
calculateIntermediateTimes() {
|
||||
// Stelle sicher, dass alle startTime-Werte aktuell sind
|
||||
try { this.calculateAllItemTimes(); } catch(e) {}
|
||||
if (!this.trainingPlan || this.trainingPlan.length === 0) {
|
||||
this.intermediateTimes = [];
|
||||
return;
|
||||
}
|
||||
let times = [];
|
||||
let currentTime = new Date("2025-01-01 " + this.trainingStart);
|
||||
this.trainingPlan.forEach(item => {
|
||||
const rawItem = JSON.parse(JSON.stringify(item));
|
||||
currentTime.setMinutes(currentTime.getMinutes() + item.duration);
|
||||
times.push(currentTime.toTimeString({ hours: '2-digit', minutes: '2-digit', seconds: '2-digit' }).slice(0, 8));
|
||||
});
|
||||
times = [...new Set(times)].sort();
|
||||
this.intermediateTimes = times.filter(time =>
|
||||
time !== this.trainingStart && time !== this.trainingEnd
|
||||
);
|
||||
function withSeconds(hhmm) {
|
||||
if (!hhmm) return null;
|
||||
const parts = hhmm.split(':');
|
||||
if (parts.length < 3) return hhmm + ':00';
|
||||
return hhmm;
|
||||
}
|
||||
const times = [];
|
||||
for (const item of this.trainingPlan) {
|
||||
if (item && item.startTime) {
|
||||
const t = withSeconds(item.startTime);
|
||||
if (t) times.push(t);
|
||||
}
|
||||
}
|
||||
const normalizedStart = withSeconds(this.trainingStart);
|
||||
const unique = Array.from(new Set(times));
|
||||
const filtered = unique.filter(t => t !== normalizedStart);
|
||||
filtered.sort();
|
||||
this.intermediateTimes = filtered;
|
||||
|
||||
},
|
||||
|
||||
async addAccident() {
|
||||
@@ -1402,6 +1448,14 @@ export default {
|
||||
},
|
||||
async mounted() {
|
||||
await this.init();
|
||||
// Versuche, Audio erst bei Nutzerinteraktion zu initialisieren (Autoplay-Policy)
|
||||
const tryInit = () => {
|
||||
if (!this.bellSound) this.bellSound = new Audio('/sound/bell-123742.mp3');
|
||||
if (!this.thumbSound) this.thumbSound = new Audio('/sound/thump-105302.mp3');
|
||||
this.soundEnabled = true;
|
||||
window.removeEventListener('click', tryInit, { once: true });
|
||||
};
|
||||
window.addEventListener('click', tryInit, { once: true });
|
||||
},
|
||||
beforeUnmount() {
|
||||
if (this.timeChecker) {
|
||||
|
||||
Reference in New Issue
Block a user