fix: Timer für jeder KÜ separate und nicht eine für alle, aktuell wird prozentzahl bei allen das gleiche angezeigt

This commit is contained in:
ISA
2025-09-08 10:46:20 +02:00
parent 9c218b2a1d
commit 72341abb23
8 changed files with 44 additions and 32 deletions

View File

@@ -6,6 +6,6 @@ NEXT_PUBLIC_USE_MOCK_BACKEND_LOOP_START=false
NEXT_PUBLIC_EXPORT_STATIC=false NEXT_PUBLIC_EXPORT_STATIC=false
NEXT_PUBLIC_USE_CGI=false NEXT_PUBLIC_USE_CGI=false
# App-Versionsnummer # App-Versionsnummer
NEXT_PUBLIC_APP_VERSION=1.6.866 NEXT_PUBLIC_APP_VERSION=1.6.867
NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter) NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter)

View File

@@ -5,5 +5,5 @@ NEXT_PUBLIC_CPL_API_PATH=/CPL
NEXT_PUBLIC_EXPORT_STATIC=true NEXT_PUBLIC_EXPORT_STATIC=true
NEXT_PUBLIC_USE_CGI=true NEXT_PUBLIC_USE_CGI=true
# App-Versionsnummer # App-Versionsnummer
NEXT_PUBLIC_APP_VERSION=1.6.866 NEXT_PUBLIC_APP_VERSION=1.6.867
NEXT_PUBLIC_CPL_MODE=production NEXT_PUBLIC_CPL_MODE=production

View File

@@ -1,3 +1,8 @@
## [1.6.867] 2025-09-08
- WIP: Timer für jeder KÜ separate und nicht eine für alle, aktuell wird prozentzahl bei allen das gleiche angezeigt
---
## [1.6.866] 2025-09-08 ## [1.6.866] 2025-09-08
- Test: Jenkinsfile - Test: Jenkinsfile

View File

@@ -1,7 +1,10 @@
"use client"; "use client";
import React from "react"; import React from "react";
import { useAppDispatch } from "@/redux/store"; import { useAppDispatch } from "@/redux/store";
import { setEvents } from "@/redux/slices/deviceEventsSlice"; import {
setEvents,
initPersistedTimings,
} from "@/redux/slices/deviceEventsSlice";
declare global { declare global {
interface Window { interface Window {
@@ -18,6 +21,25 @@ export default function DeviceEventsBridge() {
React.useEffect(() => { React.useEffect(() => {
let lastSig = ""; let lastSig = "";
// Hydrate persisted timings once
try {
const raw =
typeof window !== "undefined" &&
localStorage.getItem("deviceEventsTimingsV1");
if (raw) {
const parsed = JSON.parse(raw);
dispatch(
initPersistedTimings({
loop: parsed.loop,
tdr: parsed.tdr,
compare: parsed.compare || parsed.align,
})
);
}
} catch (e) {
// eslint-disable-next-line no-console
console.warn("DeviceEventsBridge hydration failed", e);
}
const readAndDispatch = () => { const readAndDispatch = () => {
const ksx = Array.isArray(window.loopMeasurementEvent) const ksx = Array.isArray(window.loopMeasurementEvent)
? window.loopMeasurementEvent ? window.loopMeasurementEvent

View File

@@ -1,7 +1,6 @@
"use client"; "use client";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useAppSelector, useAppDispatch } from "@/redux/store"; import { useAppSelector } from "@/redux/store";
import { initPersistedTimings } from "@/redux/slices/deviceEventsSlice";
export default function SlotActivityOverlay({ export default function SlotActivityOverlay({
slotIndex, slotIndex,
@@ -25,32 +24,11 @@ export default function SlotActivityOverlay({
const comparisonStartedAtBySlot = useAppSelector( const comparisonStartedAtBySlot = useAppSelector(
(s) => s.deviceEvents.comparisonStartedAtBySlot (s) => s.deviceEvents.comparisonStartedAtBySlot
); );
const dispatch = useAppDispatch();
const loopActive = Array.isArray(ksx) && ksx[slotIndex] === 1; const loopActive = Array.isArray(ksx) && ksx[slotIndex] === 1;
const tdrActive = Array.isArray(ksy) && ksy[slotIndex] === 1; const tdrActive = Array.isArray(ksy) && ksy[slotIndex] === 1;
const comparisonActive = Array.isArray(ksz) && ksz[slotIndex] === 1; const comparisonActive = Array.isArray(ksz) && ksz[slotIndex] === 1;
// Load persisted timings only once (on mount)
useEffect(() => {
try {
const raw = localStorage.getItem("deviceEventsTimingsV1");
if (raw) {
const parsed = JSON.parse(raw);
dispatch(
initPersistedTimings({
loop: parsed.loop,
tdr: parsed.tdr,
compare: parsed.align || parsed.compare,
})
);
}
} catch (e) {
// eslint-disable-next-line no-console
console.warn("Failed to load persisted timings", e);
}
}, [dispatch]);
// Persist whenever arrays change // Persist whenever arrays change
useEffect(() => { useEffect(() => {
try { try {

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.866", "version": "1.6.867",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.866", "version": "1.6.867",
"dependencies": { "dependencies": {
"@fontsource/roboto": "^5.1.0", "@fontsource/roboto": "^5.1.0",
"@headlessui/react": "^2.2.4", "@headlessui/react": "^2.2.4",

View File

@@ -1,6 +1,6 @@
{ {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.866", "version": "1.6.867",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev -p 3000", "dev": "next dev -p 3000",

View File

@@ -75,17 +75,24 @@ export const deviceEventsSlice = createSlice({
// Per-slot transition detection // Per-slot transition detection
for (let i = 0; i < 32; i++) { for (let i = 0; i < 32; i++) {
if (prevKsx[i] === 0 && state.ksx[i] === 1) { if (prevKsx[i] === 0 && state.ksx[i] === 1) {
state.loopStartedAtBySlot[i] = Date.now(); // Only set if no existing (hydrated) timestamp
if (!state.loopStartedAtBySlot[i]) {
state.loopStartedAtBySlot[i] = Date.now();
}
} else if (prevKsx[i] === 1 && state.ksx[i] === 0) { } else if (prevKsx[i] === 1 && state.ksx[i] === 0) {
state.loopStartedAtBySlot[i] = null; state.loopStartedAtBySlot[i] = null;
} }
if (prevKsy[i] === 0 && state.ksy[i] === 1) { if (prevKsy[i] === 0 && state.ksy[i] === 1) {
state.tdrStartedAtBySlot[i] = Date.now(); if (!state.tdrStartedAtBySlot[i]) {
state.tdrStartedAtBySlot[i] = Date.now();
}
} else if (prevKsy[i] === 1 && state.ksy[i] === 0) { } else if (prevKsy[i] === 1 && state.ksy[i] === 0) {
state.tdrStartedAtBySlot[i] = null; state.tdrStartedAtBySlot[i] = null;
} }
if (prevKsz[i] === 0 && state.ksz[i] === 1) { if (prevKsz[i] === 0 && state.ksz[i] === 1) {
state.comparisonStartedAtBySlot[i] = Date.now(); if (!state.comparisonStartedAtBySlot[i]) {
state.comparisonStartedAtBySlot[i] = Date.now();
}
} else if (prevKsz[i] === 1 && state.ksz[i] === 0) { } else if (prevKsz[i] === 1 && state.ksz[i] === 0) {
state.comparisonStartedAtBySlot[i] = null; state.comparisonStartedAtBySlot[i] = null;
} }