diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/RaceLogAttachOnTrackedRaceTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/RaceLogAttachOnTrackedRaceTest.java
index 109c3c3336c..221c11d3d66 100644
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/RaceLogAttachOnTrackedRaceTest.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/RaceLogAttachOnTrackedRaceTest.java
@@ -26,8 +26,10 @@ public class RaceLogAttachOnTrackedRaceTest {
private RaceLog raceLog;
@Override
- public void detachRaceLog(Serializable identifier) {
+ public RaceLog detachRaceLog(Serializable identifier) {
+ final RaceLog result = this.raceLog;
this.raceLog = null;
+ return result;
}
@Override
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackBasedTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackBasedTest.java
index 19a0138cafe..6dcd56beed5 100755
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackBasedTest.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackBasedTest.java
@@ -121,6 +121,26 @@ public abstract class TrackBasedTest {
*/
public static DynamicTrackedRaceImpl createTestTrackedRace(String regattaName, String raceName, String boatClassName,
Iterable competitors, TimePoint timePointForFixes, boolean useMarkPassingCalculator) {
+ return createTestTrackedRace(regattaName, raceName, boatClassName, competitors, timePointForFixes, useMarkPassingCalculator,
+ mock(RaceLogResolver.class));
+ }
+ /**
+ * Creates a simple two-lap upwind-downwind course for a race/event with given name and boat class name with the
+ * competitors specified. The marks are laid out such that the upwind/downwind leg detection should be alright. The
+ * start line equals the finish line and the leeward gate. Wind is coming from the north. A single wind fix with
+ * bearing 180deg (from=0deg) is added to the {@link WindSourceType#WEB} wind track using
+ * timePointForFixes as time point. The leeward gate is located at N54.4680424, E10.234451 and
+ * N54.4680424, E10.24. The windward mark is located at N54.48, E10.24.
+ * @param timePointForFixes
+ * a wind fix will be inserted into the {@link WindSourceType#WEB} wind track which is aligned with the
+ * course layout; the value of this parameter will be used as the time stamp for this wind fix. Using a
+ * time that is reasonably within the race time (mark passing times or whatever is collected for the
+ * tracked race returned by this method) is important because otherwise confidences of wind readouts may
+ * be ridiculously low.
+ * @param useMarkPassingCalculator whether or not to use the internal mark passing calculator
+ */
+ public static DynamicTrackedRaceImpl createTestTrackedRace(String regattaName, String raceName, String boatClassName,
+ Iterable competitors, TimePoint timePointForFixes, boolean useMarkPassingCalculator, RaceLogResolver raceLogResolver) {
BoatClassImpl boatClass = new BoatClassImpl(boatClassName, /* typicallyStartsUpwind */ true);
Regatta regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
RegattaImpl.getDefaultName(regattaName, boatClass.getName()), boatClass, /*startDate*/ null, /*endDate*/ null, /* trackedRegattaRegistry */ null,
@@ -143,7 +163,7 @@ public abstract class TrackBasedTest {
EmptyGPSFixStore.INSTANCE, /* delayToLiveInMillis */ 0,
/* millisecondsOverWhichToAverageWind */ 30000, /* millisecondsOverWhichToAverageSpeed */ 30000,
/* delay for wind estimation cache invalidation */ 0, useMarkPassingCalculator,
- OneDesignRankingMetric::new, mock(RaceLogResolver.class));
+ OneDesignRankingMetric::new, raceLogResolver);
// in this simplified artificial course, the top mark is exactly north of the right leeward gate
DegreePosition topPosition = new DegreePosition(54.48, 10.24);
TimePoint afterTheRace = new MillisecondsTimePoint(timePointForFixes.asMillis() + 36000000); // 10h after the fix timed
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackedRaceStartTimeUpdateForDependentStartTimeTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackedRaceStartTimeUpdateForDependentStartTimeTest.java
new file mode 100644
index 00000000000..af8f1c0cee5
--- /dev/null
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackedRaceStartTimeUpdateForDependentStartTimeTest.java
@@ -0,0 +1,78 @@
+package com.sap.sailing.domain.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Collections;
+
+import org.junit.Test;
+
+import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
+import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
+import com.sap.sailing.domain.abstractlog.race.RaceLog;
+import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
+import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
+import com.sap.sailing.domain.abstractlog.race.impl.RaceLogDependentStartTimeEventImpl;
+import com.sap.sailing.domain.abstractlog.race.impl.RaceLogImpl;
+import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartTimeEventImpl;
+import com.sap.sailing.domain.abstractlog.race.impl.SimpleRaceLogIdentifierImpl;
+import com.sap.sailing.domain.base.Competitor;
+import com.sap.sailing.domain.tracking.StartTimeChangedListener;
+import com.sap.sailing.domain.tracking.TrackedRace;
+import com.sap.sse.common.Duration;
+import com.sap.sse.common.TimePoint;
+import com.sap.sse.common.impl.MillisecondsTimePoint;
+
+public class TrackedRaceStartTimeUpdateForDependentStartTimeTest extends TrackBasedTest {
+ @Test
+ public void testStartTimeUpdateForRaceWithDependentStartTime() {
+ final Competitor hasso = createCompetitor("Hasso");
+ final RaceLog r1RaceLog = new RaceLogImpl("r1RaceLog");
+ final RaceLog r2RaceLog = new RaceLogImpl("r2RaceLog");
+ final RaceLogResolver raceLogResolver = new RaceLogResolver() {
+ @Override
+ public RaceLog resolve(SimpleRaceLogIdentifier identifier) {
+ if (identifier.getRaceColumnName().equals("R1")) {
+ return r1RaceLog;
+ } else if (identifier.getRaceColumnName().equals("R2")) {
+ return r2RaceLog;
+ }
+ return null;
+ }
+ };
+ final TrackedRace r1 = createTestTrackedRace("Regatta", "R1", "J/70", Collections.singleton(hasso),
+ MillisecondsTimePoint.now(), /* useMarkPassingCalculator */ false, raceLogResolver);
+ final TrackedRace r2 = createTestTrackedRace("Regatta", "R2", "J/70", Collections.singleton(hasso),
+ MillisecondsTimePoint.now(), /* useMarkPassingCalculator */ false, raceLogResolver);
+ r1.attachRaceLog(r1RaceLog);
+ r2.attachRaceLog(r2RaceLog);
+ final TimePoint[] r1StartTime = new TimePoint[1];
+ final TimePoint[] r2StartTime = new TimePoint[1];
+ r1.addStartTimeChangedListener(new StartTimeChangedListener() {
+ @Override
+ public void startTimeChanged(TimePoint newTimePoint) throws MalformedURLException, IOException {
+ r1StartTime[0] = newTimePoint;
+ }
+ });
+ r2.addStartTimeChangedListener(new StartTimeChangedListener() {
+ @Override
+ public void startTimeChanged(TimePoint newTimePoint) throws MalformedURLException, IOException {
+ r2StartTime[0] = newTimePoint;
+ }
+ });
+ final AbstractLogEventAuthor author = new LogEventAuthorImpl("Axel", 0);
+ final Duration startTimeDiff = Duration.ONE_MINUTE;
+ r2RaceLog.add(new RaceLogDependentStartTimeEventImpl(MillisecondsTimePoint.now(), author, /* pass */ 0,
+ new SimpleRaceLogIdentifierImpl(r1.getTrackedRegatta().getRegatta().getName(), "R1", "Default"), startTimeDiff));
+ assertNull(r2StartTime[0]);
+ final TimePoint r1StartTimeToSet = MillisecondsTimePoint.now();
+ r1RaceLog.add(new RaceLogStartTimeEventImpl(r1StartTimeToSet, author, /* pass */ 0, r1StartTimeToSet));
+ assertNotNull(r1StartTime[0]);
+ assertEquals(r1StartTimeToSet, r1StartTime[0]);
+ assertNotNull(r2StartTime[0]);
+ assertEquals(r1StartTimeToSet.plus(startTimeDiff), r2StartTime[0]);
+ }
+}
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java
index 1847ac93970..0112fbe217d 100755
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java
@@ -814,7 +814,8 @@ public class MockedTrackedRace implements DynamicTrackedRace {
}
@Override
- public void detachRaceLog(Serializable identifier) {
+ public RaceLog detachRaceLog(Serializable identifier) {
+ return null;
}
@Override
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java
index 7dc874fd299..c358d39f6ff 100755
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java
@@ -457,7 +457,8 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
}
@Override
- public void detachRaceLog(Serializable identifier) {
+ public RaceLog detachRaceLog(Serializable identifier) {
+ return null;
}
@Override
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java
index 98fd18ed4bb..314ef2c2fbe 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java
@@ -700,8 +700,10 @@ public interface TrackedRace extends Serializable, IsManagedByCache {
*/
private Map competitorResultsFromRaceLog;
+ /**
+ * When one or more race logs are attached, changes in those race logs, or in case of dependent start
+ * times even changes in other race logs, may impact this race's start time. This listener receives those start
+ * time changes, also those from races that this race's start time depends upon, and triggers an update of
+ * this race's start time caches. The field is transient, therefore needs no serialization support but needs
+ * to be restored during at the time of de-serialization.
+ */
+ private transient RaceStateChangedListener raceStateBasedStartTimeChangedListener;
+
public DynamicTrackedRaceImpl(TrackedRegatta trackedRegatta, RaceDefinition race, Iterable sidelines,
WindStore windStore, GPSFixStore gpsFixStore, long delayToLiveInMillis,
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
@@ -95,6 +107,7 @@ DynamicTrackedRace, GPSTrackListener {
super(trackedRegatta, race, sidelines, windStore, gpsFixStore, delayToLiveInMillis,
millisecondsOverWhichToAverageWind, millisecondsOverWhichToAverageSpeed,
delayForCacheInvalidationOfWindEstimation, useInternalMarkPassingAlgorithm, rankingMetricConstructor, raceLogResolver);
+ raceStateBasedStartTimeChangedListener = createRaceStateStartTimeChangeListener();
this.competitorResultsFromRaceLog = new HashMap<>();
this.logListener = new DynamicTrackedRaceLogListener(this);
if (markPassingCalculator != null) {
@@ -126,6 +139,7 @@ DynamicTrackedRace, GPSTrackListener {
*/
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
+ raceStateBasedStartTimeChangedListener = createRaceStateStartTimeChangeListener();
listeners = new HashSet();
logListener = new DynamicTrackedRaceLogListener(this);
courseDesignChangedListeners = new HashSet<>();
@@ -141,6 +155,19 @@ DynamicTrackedRace, GPSTrackListener {
return this;
}
+ private RaceStateChangedListener createRaceStateStartTimeChangeListener() {
+ return new BaseRaceStateChangedListener() {
+ @Override
+ public void onStartTimeChanged(ReadonlyRaceState state) {
+ final TimePoint oldStartTime = getStartOfRace();
+ updateStartOfRaceCacheFields();
+ if (!Util.equalsWithNull(oldStartTime, getStartOfRace())) {
+ onStartTimeChangedByRaceCommittee(getStartOfRace());
+ }
+ }
+ };
+ }
+
/**
* {@link #raceIsKnownToStartUpwind} (see also {@link #raceIsKnownToStartUpwind()}) is initialized based on the race's
* {@link RaceDefinition#getBoatClass()} boat class's {@link BoatClass#typicallyStartsUpwind()} result. It can be changed
@@ -957,15 +984,24 @@ DynamicTrackedRace, GPSTrackListener {
public void attachRaceLog(RaceLog raceLog) {
logListener.addTo(raceLog);
super.attachRaceLog(raceLog);
+ getRaceState(raceLog).addChangedListener(raceStateBasedStartTimeChangedListener);
}
@Override
- public void detachRaceLog(Serializable identifier) {
- RaceLog attachedRaceLog = attachedRaceLogs.get(identifier);
+ public RaceLog detachRaceLog(Serializable identifier) {
+ final RaceLog attachedRaceLog = attachedRaceLogs.get(identifier);
if (attachedRaceLog != null) {
logListener.removeFrom(attachedRaceLog);
}
- super.detachRaceLog(identifier);
+ final RaceLog raceLogDetached = super.detachRaceLog(identifier);
+ assert raceLogDetached == attachedRaceLog;
+ synchronized (raceStates) {
+ final ReadonlyRaceState raceState = raceStates.remove(attachedRaceLog);
+ if (raceState != null) {
+ raceState.removeChangedListener(raceStateBasedStartTimeChangedListener);
+ }
+ }
+ return attachedRaceLog;
}
@Override
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java
index 060984ac3a4..43f0001d3ef 100644
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java
@@ -403,7 +403,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
* must be established again after de-serialization by invoking {@link #setRaceLogResolver}.
*/
private transient RaceLogResolver raceLogResolver;
-
+
/**
* Constructs the tracked race with one-design ranking.
*/
@@ -565,7 +565,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
logger.log(Level.SEVERE, "Waiting for loading from stores to finish was interrupted", e);
}
}
-
+
@Override
public RankingMetric getRankingMetric() {
return rankingMetric;
@@ -905,7 +905,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
* and not {@link Object}.
*/
private final String updateStartOfRaceCacheFieldsMonitor = "";
- private void updateStartOfRaceCacheFields() {
+ protected void updateStartOfRaceCacheFields() {
synchronized (updateStartOfRaceCacheFieldsMonitor) {
TimePoint newStartTime = null;
TimePoint newStartTimeWithoutInferenceFromStartMarkPassings = null;
@@ -3513,7 +3513,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
return !attachedRaceExecutionOrderProviders.isEmpty();
}
- private ReadonlyRaceState getRaceState(RaceLog raceLog) {
+ protected ReadonlyRaceState getRaceState(RaceLog raceLog) {
ReadonlyRaceState result;
synchronized (raceStates) {
result = raceStates.get(raceLog);
@@ -3539,10 +3539,11 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
}
@Override
- public void detachRaceLog(Serializable identifier) {
- this.attachedRaceLogs.remove(identifier);
+ public RaceLog detachRaceLog(Serializable identifier) {
+ final RaceLog raceLog = this.attachedRaceLogs.remove(identifier);
updateStartOfRaceCacheFields();
updateStartAndEndOfTracking(/* waitForGPSFixesToLoad */ false);
+ return raceLog;
}
@Override
diff --git a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java
index f5ca8e23a18..983309c7b80 100755
--- a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java
+++ b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java
@@ -572,7 +572,8 @@ public class MockedTrackedRace implements DynamicTrackedRace {
}
@Override
- public void detachRaceLog(Serializable identifier) {
+ public RaceLog detachRaceLog(Serializable identifier) {
+ return null;
}
@Override
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/place/player/AutoPlayController.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/place/player/AutoPlayController.java
index 3bd593ab8ad..f980a4a7917 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/place/player/AutoPlayController.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/place/player/AutoPlayController.java
@@ -127,7 +127,7 @@ public class AutoPlayController implements RaceTimesInfoProviderListener, Leader
sailingService, mediaService, userService, asyncActionsExecutor,
result.getCompetitorAndTheirBoats(), raceboardTimer, currentLiveRace, autoPlayerConfiguration.getLeaderboardName(),
/** leaderboardGroupName */ null, /** eventId */ null, errorReporter,
- StringMessages.INSTANCE, userAgent, raceTimesInfoProvider);
+ StringMessages.INSTANCE, userAgent, raceTimesInfoProvider, true);
playerView.setContent(raceboardPerspective);
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/SailingAction.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/SailingAction.java
index 6916c74c908..8ab40468887 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/SailingAction.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/SailingAction.java
@@ -5,9 +5,14 @@ import com.sap.sse.gwt.dispatch.shared.commands.Action;
import com.sap.sse.gwt.dispatch.shared.commands.Result;
import com.sap.sse.gwt.dispatch.shared.exceptions.DispatchException;
+/**
+ * Extended {@link Action} interface, which requires a {@link SailingDispatchContext} for server-side execution.
+ *
+ * @param
+ * {@link Result} type provided by the actions {@link #execute(SailingDispatchContext)} method
+ */
public interface SailingAction extends Action {
@GwtIncompatible
R execute(SailingDispatchContext ctx) throws DispatchException;
-
}
\ No newline at end of file
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/SailingDispatchContext.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/SailingDispatchContext.java
index a7233e60d5e..f17c2ba6bb3 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/SailingDispatchContext.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/SailingDispatchContext.java
@@ -8,7 +8,10 @@ import com.sap.sailing.news.EventNewsService;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.gwt.dispatch.client.system.DispatchContext;
-
+/**
+ * {@link DispatchContext} implementation, which is passed to backend-side {@link SailingAction} executions to provide
+ * access to the required services related to the sailing domain.
+ */
public interface SailingDispatchContext extends DispatchContext {
@GwtIncompatible
RacingEventService getRacingEventService();
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/GetCompetitionFormatRacesAction.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/GetCompetitionFormatRacesAction.java
index bfc213fe9dd..7479b838571 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/GetCompetitionFormatRacesAction.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/GetCompetitionFormatRacesAction.java
@@ -13,6 +13,18 @@ import com.sap.sse.gwt.dispatch.shared.commands.ListResult;
import com.sap.sse.gwt.dispatch.shared.commands.ResultWithTTL;
import com.sap.sse.gwt.dispatch.shared.exceptions.DispatchException;
+/**
+ *
+ * {@link SailingAction} implementation to load data to be shown in the competition format races view for the
+ * {@link #GetCompetitionFormatRacesAction(UUID, String) given event- and regatta-id}, using a
+ * {@link RaceCompetitionFormatDataCalculator} to prepare the appropriate data structure.
+ *
+ *
+ * The {@link ResultWithTTL result's} time to live
+ * {@link EventActionUtil#getEventStateDependentTTL(SailingDispatchContext, UUID, Duration) depends on the event's
+ * state} using a duration of 1 minute for currently running events.
+ *
+ */
public class GetCompetitionFormatRacesAction implements
SailingAction>>, IsClientCacheable {
@@ -22,6 +34,12 @@ public class GetCompetitionFormatRacesAction implements
protected GetCompetitionFormatRacesAction() {
}
+ /**
+ * Creates a {@link GetCompetitionFormatRacesAction} instance for the given event and regatta-id.
+ *
+ * @param eventId {@link UUID} of the event to load races for
+ * @param regattaId {@link String id} of the regatta to load races for
+ */
public GetCompetitionFormatRacesAction(UUID eventId, String regattaId) {
this.eventId = eventId;
this.regattaId = regattaId;
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/GetEventListViewAction.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/GetEventListViewAction.java
index 81741e5ad66..d33f1507d2c 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/GetEventListViewAction.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/GetEventListViewAction.java
@@ -8,6 +8,12 @@ import com.sap.sailing.gwt.server.EventListDataCalculator;
import com.sap.sailing.gwt.server.HomeServiceUtil;
import com.sap.sse.gwt.dispatch.shared.caching.IsClientCacheable;
+/**
+ *
+ * {@link SailingAction} implementation to load data to be shown in the events list overview, using a
+ * {@link EventListDataCalculator} to prepare the appropriate data structure.
+ *
+ */
public class GetEventListViewAction implements SailingAction, IsClientCacheable {
@Override
@GwtIncompatible
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/GetFinishedRacesAction.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/GetFinishedRacesAction.java
index ee5a8df3853..c172a7d24a1 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/GetFinishedRacesAction.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/GetFinishedRacesAction.java
@@ -12,6 +12,18 @@ import com.sap.sse.gwt.dispatch.shared.caching.IsClientCacheable;
import com.sap.sse.gwt.dispatch.shared.commands.ResultWithTTL;
import com.sap.sse.gwt.dispatch.shared.commands.SortedSetResult;
+/**
+ *
+ * {@link SailingAction} implementation to load data to be shown in the finished races section for the
+ * {@link #GetFinishedRacesAction(UUID, String) given event- and regatta-id}, using a {@link RaceListDataCalculator} to
+ * prepare the appropriate data structure.
+ *
+ *
+ * The {@link ResultWithTTL result's} time to live
+ * {@link EventActionUtil#getEventStateDependentTTL(SailingDispatchContext, UUID, Duration) depends on the event's
+ * state} using a duration of 5 minutes for currently running events.
+ *
+ */
public class GetFinishedRacesAction implements SailingAction>>,
IsClientCacheable {
@@ -22,6 +34,12 @@ public class GetFinishedRacesAction implements SailingAction
+ * {@link SailingAction} implementation to load data to be shown in the live races section for the
+ * {@link #GetLiveRacesForEventAction(UUID) given event-id}, using a {@link LiveRaceCalculator} to prepare the
+ * appropriate data structure.
+ *
+ *
+ * The {@link ResultWithTTL result's} time to live is calculated using the {@link LiveRaceCalculator}'s internal
+ * {@link com.sap.sailing.gwt.home.server.RaceRefreshCalculator}, which is called for every race in the event.
+ *
+ *
+ * NOTE: Because there can only be live races in currently running events, this action returns an empty
+ * {@link ResultWithTTL result} with a {@link EventActionUtil#calculateTtlForNonLiveEvent(Event, EventState)
+ * state-dependent} time to live, if the {@link Event} for the given id is not currently running.
+ *
+ */
public class GetLiveRacesForEventAction implements SailingAction>>,
IsClientCacheable {
private UUID eventId;
@@ -21,6 +37,12 @@ public class GetLiveRacesForEventAction implements SailingAction
+ * {@link SailingAction} implementation to load data to be shown in the live races section for the
+ * {@link #GetLiveRacesForRegattaAction(UUID, String) given event-id and regatta name}, using a
+ * {@link LiveRaceCalculator} to prepare the appropriate data structure.
+ *
+ *
+ * The {@link ResultWithTTL result's} time to live is calculated using the {@link LiveRaceCalculator}'s internal
+ * {@link com.sap.sailing.gwt.home.server.RaceRefreshCalculator}, which is called for every race in the regatta.
+ *
+ *
+ * NOTE: Because there can only be live races in currently running events, this action returns an empty
+ * {@link ResultWithTTL result} with a {@link EventActionUtil#calculateTtlForNonLiveEvent(Event, EventState)
+ * state-dependent} time to live, if the {@link Event} for the given id is not currently running.
+ *
+ */
public class GetLiveRacesForRegattaAction implements SailingAction>>,
IsClientCacheable {
private UUID eventId;
@@ -21,7 +37,13 @@ public class GetLiveRacesForRegattaAction implements SailingAction
+ * {@link SailingAction} implementation to load data to be shown on the event overview or regattas page for the
+ * {@link #GetRegattaListViewAction(UUID) given event-id}, preparing the appropriate data structure.
+ *
+ *
+ * The {@link ResultWithTTL result's} time to live
+ * {@link EventActionUtil#getEventStateDependentTTL(SailingDispatchContext, UUID, Duration) depends on the event's
+ * state} using a duration of 3 minutes for currently running events.
+ *
+ */
public class GetRegattaListViewAction implements SailingAction>>,
IsClientCacheable {
private UUID eventId;
@@ -24,6 +35,12 @@ public class GetRegattaListViewAction implements SailingAction
+ * {@link SailingAction} implementation to load data to be shown in the statistics sections for the
+ * {@link #GetRegattaStatisticsAction(UUID) given event- and regatta-id}, using a {@link StatisticsCalculator} to prepare
+ * the appropriate data structure.
+ *
+ *
+ * The {@link ResultWithTTL result's} time to live is 5 minutes.
+ *
+ */
public class GetRegattaStatisticsAction implements SailingAction>, IsClientCacheable {
private UUID eventId;
@@ -20,6 +30,12 @@ public class GetRegattaStatisticsAction implements SailingAction
+ * {@link SailingAction} implementation to load data to be shown on the regatta overview page for the
+ * {@link #GetRegattaWithProgressAction(UUID, String) given event- and regatta-id}, using a
+ * {@link RaceCompetitionFormatDataCalculator} to prepare the appropriate data structure.
+ *
+ *
+ * The {@link ResultWithTTL result's} time to live
+ * {@link EventActionUtil#getEventStateDependentTTL(SailingDispatchContext, UUID, Duration) depends on the event's
+ * state} using a duration of 5 minutes for currently running events.
+ *
+ */
public class GetRegattaWithProgressAction implements SailingAction>, IsClientCacheable {
private UUID eventId;
@@ -20,6 +33,12 @@ public class GetRegattaWithProgressAction implements SailingAction
+ * {@link SailingAction} implementation to load data to be shown on the mobile event overview page for the
+ * {@link #GetRegattasAndLiveRacesForEventAction(UUID) given event-id}, preparing the appropriate data structure.
+ *
+ *
+ * The {@link ResultWithTTL result's} time to live is 2 minutes for upcoming and currently running events,
+ * otherwise it {@link EventActionUtil#calculateTtlForNonLiveEvent(Event, EventState) depends on the event's state}.
+ *
+ */
public class GetRegattasAndLiveRacesForEventAction implements SailingAction>,
IsClientCacheable {
private UUID eventId;
@@ -30,6 +40,12 @@ public class GetRegattasAndLiveRacesForEventAction implements SailingAction
+ * {@link SailingAction} implementation to load data to be shown in the statistics sections for the
+ * {@link #GetSeriesStatisticsAction(UUID) given series-id}, using a {@link StatisticsCalculator} to prepare the
+ * appropriate data structure.
+ *
+ *
+ * The {@link ResultWithTTL result's} time to live is 5 minutes.
+ *
+ */
public class GetSeriesStatisticsAction implements SailingAction>, IsClientCacheable {
private UUID seriesId;
@@ -19,6 +30,12 @@ public class GetSeriesStatisticsAction implements SailingAction
+ * {@link SailingAction} implementation to load data to be shown in compact leaderboard (e.g. on the event overview
+ * page) for the {@link #GetMiniLeaderbordAction(UUID, String) given event-id and leaderboard name}, where the amount of
+ * loaded entries can optionally be {@link #GetMiniLeaderbordAction(UUID, String, int) limited}.
+ *
+ *
+ * The {@link ResultWithTTL result's} time to live is 1 minute for currently running events, 2 minutes
+ * otherwise.
+ *
+ */
public class GetMiniLeaderbordAction implements SailingAction>, IsClientCacheable {
private UUID eventId;
private String leaderboardName;
@@ -18,10 +30,30 @@ public class GetMiniLeaderbordAction implements SailingAction
+ * {@link SailingAction} implementation to load data to be shown in compact leaderboard (e.g. on the series overview
+ * page) for the {@link #GetMiniOverallLeaderbordAction(UUID) given series-id}, where the amount of loaded entries can
+ * optionally be {@link #GetMiniOverallLeaderbordAction(UUID, int) limited}.
+ *
+ *
+ * The {@link ResultWithTTL result's} time to live is 1 minute for currently running events, 2 minutes
+ * otherwise.
+ *
+ */
public class GetMiniOverallLeaderbordAction implements SailingAction>, IsClientCacheable {
private UUID seriesId;
private int limit = 0;
@@ -17,10 +28,26 @@ public class GetMiniOverallLeaderbordAction implements SailingAction
+ * {@link SailingAction} implementation to load data to be shown in the news ticker section for the
+ * {@link #GetEventOverviewNewsAction(UUID) given event-id}, where the amount of loaded news entries can optionally be
+ * {@link #GetEventOverviewNewsAction(UUID, int) limited}.
+ *
+ *
+ * The {@link ResultWithTTL result's} time to live is 2 minutes for currently running events.
+ *
+ *
+ * NOTE: Because the news ticker section is only shown in currently running events, this action returns an empty
+ * {@link ResultWithTTL result} with a {@link EventActionUtil#calculateTtlForNonLiveEvent(Event, EventState)
+ * state-dependent} time to live, if the {@link Event} for the given id is not currently running.
+ *
+ */
public class GetEventOverviewNewsAction implements SailingAction>>, IsClientCacheable {
private UUID eventId;
/**
@@ -29,10 +45,26 @@ public class GetEventOverviewNewsAction implements SailingAction
+ * {@link SailingAction} implementation to load data to be shown in the statistics sections for the
+ * {@link #GetEventStatisticsAction(UUID) given event-id}, using a {@link StatisticsCalculator} to prepare the
+ * appropriate data structure.
+ *
+ *
+ * The {@link ResultWithTTL result's} time to live is 5 minutes.
+ *
+ */
public class GetEventStatisticsAction implements SailingAction>, IsClientCacheable {
private UUID eventId;
@@ -18,6 +28,12 @@ public class GetEventStatisticsAction implements SailingAction
+ * {@link SailingAction} implementation to load data to be shown in the series list overview for the
+ * {@link #GetEventSeriesViewAction(UUID) given series-id}, preparing the appropriate data structure.
+ *
+ */
public class GetEventSeriesViewAction implements SailingAction, IsClientCacheable {
private UUID id;
@@ -27,6 +33,12 @@ public class GetEventSeriesViewAction implements SailingAction
+ * {@link SailingAction} implementation to load images and videos to be shown on the media page for the
+ * {@link #GetMediaForEventAction(UUID) given event-id}, preparing the appropriate data structure.
+ *
+ */
public class GetMediaForEventAction implements SailingAction, IsClientCacheable {
private UUID eventId;
@@ -23,6 +29,12 @@ public class GetMediaForEventAction implements SailingAction, IsClient
private GetMediaForEventAction() {
}
+ /**
+ * Creates a {@link GetMediaForEventAction} instance for the given event-id.
+ *
+ * @param eventId
+ * {@link UUID} of the event to load media for
+ */
public GetMediaForEventAction(UUID eventId) {
this.eventId = eventId;
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/start/GetRecentEventsAction.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/start/GetRecentEventsAction.java
index 1084608c5ad..64cd78cb6d0 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/start/GetRecentEventsAction.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/start/GetRecentEventsAction.java
@@ -15,6 +15,12 @@ import com.sap.sse.gwt.dispatch.shared.caching.IsClientCacheable;
import com.sap.sse.gwt.dispatch.shared.commands.ListResult;
import com.sap.sse.gwt.dispatch.shared.exceptions.DispatchException;
+/**
+ *
+ * {@link SailingAction} implementation to load recent events to be shown in the event list overview, where
+ * the amount of loaded entries can be {@link #GetRecentEventsAction(int) limited}.
+ *
+ */
public class GetRecentEventsAction implements SailingAction>, IsClientCacheable {
private int limit;
@@ -22,6 +28,12 @@ public class GetRecentEventsAction implements SailingAction
+ * | Event state | Start time | TTL |
+ * | UPMCOMING/PLANNED | 36 hours and more before | => 1 hour |
+ * | | less than 36 hours before | => 30 minutes |
+ * | | less than 3 hours before | => 15 minutes |
+ * | | less than 15 minutes before | => time till start |
+ * | FINISHED | any | => 12 hours |
+ * | RUNNING | any | => [0] |
+ *
+ *
+ * @param event
+ * {@link Event} to calculate the time to live for
+ * @param eventState
+ * the {@link EventState} to calculate the time to live for
+ * @return The calculated {@link Duration time to live}
+ */
public static Duration calculateTtlForNonLiveEvent(Event event, EventState eventState) {
TimePoint now = MillisecondsTimePoint.now();
if(eventState == EventState.UPCOMING || eventState == EventState.PLANNED) {
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties
index 08cf0ef6afd..794deb9a603 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties
@@ -444,7 +444,7 @@ scoringSchemeHighPointFirstGetsTen=High Point, winner gets 10 points
scoringSchemeHighPointFirstGetsTenOrEight=High Point, winner gets 10 points (or 8)
scoringSchemeHighPointFirstGetsTenOrEightDescription=Score in points. Winner scores 10 points, 2nd - 9 points, .... A tie is broken in favour of the competitor having won most races, if tie remains then tie is broken by the rank in the last race scored.
scoringSchemeHighPointFirstGetsTwelveOrEight=High Point, winner gets 12 points (or 8)
-scoringSchemeHighPointFirstGetsTwelveOrEightDescription=Score in points. Winner scores 12 points, 2nd - 11 points, .... A tie is broken in favour of the competitor having won most races, if tie remains then tie is broken by the rank in the last race scored.
+scoringSchemeHighPointFirstGetsTwelveOrEightDescription=Score in points. Winner scores 12 points, 2nd - 11 points, .... A tie is broken in favour of the competitor with the highest score, if tie remains then tie is broken by the rank in the last race scored.
scoringSystem=Scoring system
createFlexibleLeaderboard=Create flexible leaderboard
createRegattaLeaderboard=Create regatta leaderboard
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/media/MediaPlayerLifecycle.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/media/MediaPlayerLifecycle.java
index 0a349505ddf..cfcf70911c5 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/media/MediaPlayerLifecycle.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/media/MediaPlayerLifecycle.java
@@ -20,7 +20,7 @@ public class MediaPlayerLifecycle implements ComponentLifecycle() {
@Override
@@ -100,7 +107,7 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
return;
}
- createPerspectivePage(raceboardData, perspectiveSettings);
+ createPerspectivePage(raceboardData, perspectiveSettings, showChartMarkEditMediaButtonsAndVideo);
}
@Override
@@ -119,7 +126,8 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
vp.add(new Label(message));
}
- private void createPerspectivePage(RaceboardDataDTO raceboardData, RaceBoardPerspectiveSettings perspectiveSettings) {
+ private void createPerspectivePage(RaceboardDataDTO raceboardData, RaceBoardPerspectiveSettings perspectiveSettings,
+ boolean showChartMarkEditMediaButtonsAndVideo) {
selectedRace = raceboardData.getRace();
Window.setTitle(selectedRace.getName());
Timer timer = new Timer(PlayModes.Replay, 1000l);
@@ -128,13 +136,18 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
Collections.singletonList(selectedRace.getRaceIdentifier()), 5000l /* requestInterval*/);
RaceBoardPerspectiveLifecycle raceboardPerspectiveLifecycle = new RaceBoardPerspectiveLifecycle(null, StringMessages.INSTANCE);
+ PerspectiveCompositeSettings defaultSettings = raceboardPerspectiveLifecycle.createDefaultSettings();
+ PerspectiveCompositeSettings perspectiveCompositeSettings =
+ new PerspectiveCompositeSettings<>(perspectiveSettings, defaultSettings.getSettingsPerComponentId());
+
PerspectiveLifecycleWithAllSettings raceboardPerspectiveLifecyclesAndSettings = new PerspectiveLifecycleWithAllSettings<>(raceboardPerspectiveLifecycle,
- raceboardPerspectiveLifecycle.createDefaultSettings());
+ perspectiveCompositeSettings);
- RaceBoardPanel raceBoardPerspective = new RaceBoardPanel(
- raceboardPerspectiveLifecyclesAndSettings, sailingService, mediaService, getUserService(),
- asyncActionsExecutor, raceboardData.getCompetitorAndTheirBoats(), timer, selectedRace.getRaceIdentifier(), leaderboardName,
- leaderboardGroupName, eventId, RaceBoardEntryPoint.this, getStringMessages(), userAgent, raceTimesInfoProvider);
+ RaceBoardPanel raceBoardPerspective = new RaceBoardPanel(raceboardPerspectiveLifecyclesAndSettings,
+ sailingService, mediaService, getUserService(), asyncActionsExecutor,
+ raceboardData.getCompetitorAndTheirBoats(), timer, selectedRace.getRaceIdentifier(), leaderboardName,
+ leaderboardGroupName, eventId, RaceBoardEntryPoint.this, getStringMessages(), userAgent,
+ raceTimesInfoProvider, showChartMarkEditMediaButtonsAndVideo);
RootLayoutPanel.get().add(raceBoardPerspective.getEntryWidget());
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPanel.java
index bdf895de019..0a38092c800 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPanel.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPanel.java
@@ -159,13 +159,18 @@ public class RaceBoardPanel extends AbstractPerspectiveCompositetrue charts, such as the competitor chart or the wind chart, (as well as edit mark
+ * panels and manage media buttons) are shown and a padding is provided for the RaceTimePanel that
+ * aligns its right border with that of the chart. Otherwise those components will be hidden.
*/
public RaceBoardPanel(PerspectiveLifecycleWithAllSettings perspectiveLifecycleWithAllSettings,
- SailingServiceAsync sailingService, MediaServiceAsync mediaService,
- UserService userService, AsyncActionsExecutor asyncActionsExecutor, Map competitorsAndTheirBoats,
+ SailingServiceAsync sailingService, MediaServiceAsync mediaService, UserService userService,
+ AsyncActionsExecutor asyncActionsExecutor, Map competitorsAndTheirBoats,
Timer timer, RegattaAndRaceIdentifier selectedRaceIdentifier, String leaderboardName,
String leaderboardGroupName, UUID eventId, ErrorReporter errorReporter, final StringMessages stringMessages,
- UserAgentDetails userAgent, RaceTimesInfoProvider raceTimesInfoProvider) {
+ UserAgentDetails userAgent, RaceTimesInfoProvider raceTimesInfoProvider,
+ boolean showChartMarkEditMediaButtonsAndVideo) {
super(perspectiveLifecycleWithAllSettings.getPerspectiveLifecycle(), perspectiveLifecycleWithAllSettings.getPerspectiveSettings());
this.perspectiveLifecycleWithAllSettings = perspectiveLifecycleWithAllSettings;
this.sailingService = sailingService;
@@ -250,7 +255,8 @@ public class RaceBoardPanel extends AbstractPerspectiveCompositenull or else can be used to show some context information in
* the {@link GlobalNavigationPanel}.
+ * @param showChartMarkEditMediaButtonsAndVideo
* @param isScreenLargeEnoughToOfferChartSupport
* if the screen is large enough to display charts such as the competitor chart or the wind chart, a
* padding is provided for the RaceTimePanel that aligns its right border with that of the charts, and
* the charts are created.
*/
- private void createOneScreenView(String leaderboardName, String leaderboardGroupName, UUID event, FlowPanel mainPanel,
- boolean isScreenLargeEnoughToInitiallyDisplayLeaderboard, RaceMap raceMap, UserService userService) {
-
+ private void createOneScreenView(String leaderboardName, String leaderboardGroupName, UUID event,
+ FlowPanel mainPanel, boolean isScreenLargeEnoughToInitiallyDisplayLeaderboard, RaceMap raceMap,
+ UserService userService, boolean showChartMarkEditMediaButtonsAndVideo) {
+
MediaPlayerLifecycle mediaPlayerLifecycle = perspectiveLifecycleWithAllSettings.getPerspectiveLifecycle().getMediaPlayerLifecycle();
MediaPlayerSettings mediaPlayerSettings = perspectiveLifecycleWithAllSettings.findComponentSettingsByLifecycle(mediaPlayerLifecycle);
@@ -309,7 +318,7 @@ public class RaceBoardPanel extends AbstractPerspectiveComposite> componentsForSideBySideViewer = new ArrayList>();
- if (getPerspectiveSettings().isChartSupportEnabled()) {
+ if (showChartMarkEditMediaButtonsAndVideo) {
competitorChart = new MultiCompetitorRaceChart(multiCompetitorRaceChartLifecycle, sailingService, asyncActionsExecutor,
competitorSelectionProvider, selectedRaceIdentifier, timer, timeRangeWithZoomModel, stringMessages,
errorReporter, true, true, leaderboardGroupName, leaderboardName);
@@ -324,18 +333,23 @@ public class RaceBoardPanel extends AbstractPerspectiveComposite= 600;
- final boolean chartSupportEnabled = GwtHttpRequestUtils.getBooleanParameter(PARAM_VIEW_CHART_SUPPORT_ENABLED, isScreenLargeEnoughToOfferChartSupport);
-
final Duration initialDurationAfterRaceStartInReplay = parseDuration(GwtHttpRequestUtils.getStringParameter(
PARAM_TIME_AFTER_RACE_START_AS_HOURS_COLON_MILLIS_COLON_SECONDS, null /* default */));
return new RaceBoardPerspectiveSettings(activeCompetitorsFilterSetName, showLeaderboard, showWindChart,
- showCompetitorsChart, simulationEnabled, canReplayWhileLiveIsPossible, chartSupportEnabled,
- !DeviceDetector.isMobile(), initialDurationAfterRaceStartInReplay);
- }
-
- public boolean isShowChartMarkEditMediaButtonsAndVideo() {
- return showChartMarkEditMediaButtonsAndVideo;
+ showCompetitorsChart, simulationEnabled, canReplayWhileLiveIsPossible, initialDurationAfterRaceStartInReplay);
}
public Duration getInitialDurationAfterRaceStartInReplay() {
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPerspectiveSettingsDialogComponent.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPerspectiveSettingsDialogComponent.java
index 4baf00f6dab..a895c381002 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPerspectiveSettingsDialogComponent.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPerspectiveSettingsDialogComponent.java
@@ -45,8 +45,7 @@ public class RaceBoardPerspectiveSettingsDialogComponent implements SettingsDial
public RaceBoardPerspectiveSettings getResult() {
RaceBoardPerspectiveSettings result = new RaceBoardPerspectiveSettings(initialSettings.getActiveCompetitorsFilterSetName(),
showLeaderboardCheckBox.getValue(), showWindChartCheckBox.getValue(), showCompetitorsChartCheckBox.getValue(),
- initialSettings.isSimulationEnabled(), initialSettings.isCanReplayDuringLiveRaces(), initialSettings.isChartSupportEnabled(),
- initialSettings.isShowChartMarkEditMediaButtonsAndVideo(),
+ initialSettings.isSimulationEnabled(), initialSettings.isCanReplayDuringLiveRaces(),
initialSettings.getInitialDurationAfterRaceStartInReplay());
return result;
}
diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java
index 38f8ffe8aee..4c871914bdc 100755
--- a/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java
+++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java
@@ -448,7 +448,8 @@ public class DummyTrackedRace extends TrackedRaceWithWindEssentials {
}
@Override
- public void detachRaceLog(Serializable identifier) {
+ public RaceLog detachRaceLog(Serializable identifier) {
+ return null;
}
@Override