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:
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
4
package-lock.json
generated
@@ -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",
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user