mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-30 07:47:19 +00:00
Merge branch 'master' into bug3734
This commit is contained in:
commit
37d1531e37
42 files changed
+588
-112
No files matched your search
+3
-1
@@ -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
|
||||
|
||||
+21
-1
@@ -121,6 +121,26 @@ public abstract class TrackBasedTest {
|
||||
*/
|
||||
public static DynamicTrackedRaceImpl createTestTrackedRace(String regattaName, String raceName, String boatClassName,
|
||||
Iterable<Competitor> 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
|
||||
* <code>timePointForFixes</code> 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<Competitor> 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
|
||||
|
||||
+78
@@ -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]);
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -814,7 +814,8 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detachRaceLog(Serializable identifier) {
|
||||
public RaceLog detachRaceLog(Serializable identifier) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-1
@@ -457,7 +457,8 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detachRaceLog(Serializable identifier) {
|
||||
public RaceLog detachRaceLog(Serializable identifier) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -700,8 +700,10 @@ public interface TrackedRace extends Serializable, IsManagedByCache<SharedDomain
|
||||
|
||||
/**
|
||||
* Detaches the race log associated with this {@link TrackedRace}.
|
||||
*
|
||||
* @return the race log detached or {@code null} if no race log can be found by the {@code identifier}
|
||||
*/
|
||||
void detachRaceLog(Serializable identifier);
|
||||
RaceLog detachRaceLog(Serializable identifier);
|
||||
|
||||
/**
|
||||
* Detaches the link {@link RaceExecutionOrderProvider}
|
||||
|
||||
+39
-3
@@ -23,6 +23,9 @@ import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogFinishPositioningConfirmedEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.ConfirmedFinishPositioningListFinder;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.RaceStateChangedListener;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.impl.BaseRaceStateChangedListener;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CourseBase;
|
||||
@@ -87,6 +90,15 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
|
||||
*/
|
||||
private Map<Competitor, CompetitorResult> 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<Sideline> sidelines,
|
||||
WindStore windStore, GPSFixStore gpsFixStore, long delayToLiveInMillis,
|
||||
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
|
||||
@@ -95,6 +107,7 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
|
||||
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<Competitor, GPSFixMoving> {
|
||||
*/
|
||||
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
|
||||
ois.defaultReadObject();
|
||||
raceStateBasedStartTimeChangedListener = createRaceStateStartTimeChangeListener();
|
||||
listeners = new HashSet<RaceChangeListener>();
|
||||
logListener = new DynamicTrackedRaceLogListener(this);
|
||||
courseDesignChangedListeners = new HashSet<>();
|
||||
@@ -141,6 +155,19 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
|
||||
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 <code>race</code>'s
|
||||
* {@link RaceDefinition#getBoatClass()} boat class's {@link BoatClass#typicallyStartsUpwind()} result. It can be changed
|
||||
@@ -957,15 +984,24 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
|
||||
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
|
||||
|
||||
+5
-4
@@ -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
|
||||
|
||||
+2
-1
@@ -572,7 +572,8 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detachRaceLog(Serializable identifier) {
|
||||
public RaceLog detachRaceLog(Serializable identifier) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
|
||||
+6
-1
@@ -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 <R>
|
||||
* {@link Result} type provided by the actions {@link #execute(SailingDispatchContext)} method
|
||||
*/
|
||||
public interface SailingAction<R extends Result> extends Action<R, SailingDispatchContext> {
|
||||
|
||||
@GwtIncompatible
|
||||
R execute(SailingDispatchContext ctx) throws DispatchException;
|
||||
|
||||
}
|
||||
+4
-1
@@ -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();
|
||||
|
||||
+18
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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.
|
||||
* </p>
|
||||
* <p>
|
||||
* The {@link ResultWithTTL result's} time to live
|
||||
* {@link EventActionUtil#getEventStateDependentTTL(SailingDispatchContext, UUID, Duration) depends on the event's
|
||||
* state} using a duration of <i>1 minute</i> for currently running events.
|
||||
* </p>
|
||||
*/
|
||||
public class GetCompetitionFormatRacesAction implements
|
||||
SailingAction<ResultWithTTL<ListResult<RaceCompetitionFormatSeriesDTO>>>, 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;
|
||||
|
||||
+6
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@link SailingAction} implementation to load data to be shown in the events list overview, using a
|
||||
* {@link EventListDataCalculator} to prepare the appropriate data structure.
|
||||
* </p>
|
||||
*/
|
||||
public class GetEventListViewAction implements SailingAction<EventListViewDTO>, IsClientCacheable {
|
||||
@Override
|
||||
@GwtIncompatible
|
||||
|
||||
+18
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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.
|
||||
* </p>
|
||||
* <p>
|
||||
* The {@link ResultWithTTL result's} time to live
|
||||
* {@link EventActionUtil#getEventStateDependentTTL(SailingDispatchContext, UUID, Duration) depends on the event's
|
||||
* state} using a duration of <i>5 minutes</i> for currently running events.
|
||||
* </p>
|
||||
*/
|
||||
public class GetFinishedRacesAction implements SailingAction<ResultWithTTL<SortedSetResult<RaceListRaceDTO>>>,
|
||||
IsClientCacheable {
|
||||
|
||||
@@ -22,6 +34,12 @@ public class GetFinishedRacesAction implements SailingAction<ResultWithTTL<Sorte
|
||||
private GetFinishedRacesAction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 GetFinishedRacesAction(UUID eventId, String regattaId) {
|
||||
this.eventId = eventId;
|
||||
this.regattaId = regattaId;
|
||||
|
||||
+23
-1
@@ -7,12 +7,28 @@ import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.gwt.home.communication.SailingAction;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil;
|
||||
import com.sap.sailing.gwt.home.server.LiveRaceCalculator;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil.CalculationWithEvent;
|
||||
import com.sap.sailing.gwt.home.server.LiveRaceCalculator;
|
||||
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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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.
|
||||
* </p>
|
||||
* <p>
|
||||
* 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.
|
||||
* </p>
|
||||
* <p>
|
||||
* 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.
|
||||
* </p>
|
||||
*/
|
||||
public class GetLiveRacesForEventAction implements SailingAction<ResultWithTTL<SortedSetResult<LiveRaceDTO>>>,
|
||||
IsClientCacheable {
|
||||
private UUID eventId;
|
||||
@@ -21,6 +37,12 @@ public class GetLiveRacesForEventAction implements SailingAction<ResultWithTTL<S
|
||||
private GetLiveRacesForEventAction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GetLiveRacesForEventAction} instance for the given event-id.
|
||||
*
|
||||
* @param eventId
|
||||
* {@link UUID} of the event to load live races for
|
||||
*/
|
||||
public GetLiveRacesForEventAction(UUID eventId) {
|
||||
this.eventId = eventId;
|
||||
}
|
||||
|
||||
+23
-1
@@ -7,12 +7,28 @@ import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.gwt.home.communication.SailingAction;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil;
|
||||
import com.sap.sailing.gwt.home.server.LiveRaceCalculator;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil.CalculationWithEvent;
|
||||
import com.sap.sailing.gwt.home.server.LiveRaceCalculator;
|
||||
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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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.
|
||||
* </p>
|
||||
* <p>
|
||||
* 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.
|
||||
* </p>
|
||||
* <p>
|
||||
* 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.
|
||||
* </p>
|
||||
*/
|
||||
public class GetLiveRacesForRegattaAction implements SailingAction<ResultWithTTL<SortedSetResult<LiveRaceDTO>>>,
|
||||
IsClientCacheable {
|
||||
private UUID eventId;
|
||||
@@ -22,6 +38,12 @@ public class GetLiveRacesForRegattaAction implements SailingAction<ResultWithTTL
|
||||
private GetLiveRacesForRegattaAction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GetLiveRacesForRegattaAction} instance for the given event-id and regatta name.
|
||||
*
|
||||
* @param eventId {@link UUID} of the event to load live races for
|
||||
* @param regattaName {@link String name} of the regatta to load live races for
|
||||
*/
|
||||
public GetLiveRacesForRegattaAction(UUID eventId, String regattaName) {
|
||||
this.eventId = eventId;
|
||||
this.regattaName = regattaName;
|
||||
|
||||
+18
-1
@@ -9,13 +9,24 @@ import com.sap.sailing.gwt.home.communication.SailingAction;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sailing.gwt.home.communication.regatta.RegattaWithProgressDTO;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil;
|
||||
import com.sap.sailing.gwt.home.server.LeaderboardContext;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil.LeaderboardCallback;
|
||||
import com.sap.sailing.gwt.home.server.LeaderboardContext;
|
||||
import com.sap.sse.common.Duration;
|
||||
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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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.
|
||||
* </p>
|
||||
* <p>
|
||||
* The {@link ResultWithTTL result's} time to live
|
||||
* {@link EventActionUtil#getEventStateDependentTTL(SailingDispatchContext, UUID, Duration) depends on the event's
|
||||
* state} using a duration of <i>3 minutes</i> for currently running events.
|
||||
* </p>
|
||||
*/
|
||||
public class GetRegattaListViewAction implements SailingAction<ResultWithTTL<SortedSetResult<RegattaWithProgressDTO>>>,
|
||||
IsClientCacheable {
|
||||
private UUID eventId;
|
||||
@@ -24,6 +35,12 @@ public class GetRegattaListViewAction implements SailingAction<ResultWithTTL<Sor
|
||||
private GetRegattaListViewAction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GetRegattaListViewAction} instance for the given event-id.
|
||||
*
|
||||
* @param eventId
|
||||
* {@link UUID} of the event to load regattas for
|
||||
*/
|
||||
public GetRegattaListViewAction(UUID eventId) {
|
||||
this.eventId = eventId;
|
||||
}
|
||||
|
||||
+16
@@ -12,6 +12,16 @@ 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.exceptions.DispatchException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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.
|
||||
* </p>
|
||||
* <p>
|
||||
* The {@link ResultWithTTL result's} time to live is <i>5 minutes</i>.
|
||||
* </p>
|
||||
*/
|
||||
public class GetRegattaStatisticsAction implements SailingAction<ResultWithTTL<EventStatisticsDTO>>, IsClientCacheable {
|
||||
|
||||
private UUID eventId;
|
||||
@@ -20,6 +30,12 @@ public class GetRegattaStatisticsAction implements SailingAction<ResultWithTTL<E
|
||||
protected GetRegattaStatisticsAction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GetRegattaStatisticsAction} 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 GetRegattaStatisticsAction(UUID eventId, String regattaId) {
|
||||
this.eventId = eventId;
|
||||
this.regattaId = regattaId;
|
||||
|
||||
+19
@@ -7,10 +7,23 @@ import com.sap.sailing.gwt.home.communication.SailingAction;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sailing.gwt.home.communication.regatta.RegattaWithProgressDTO;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil;
|
||||
import com.sap.sailing.gwt.home.server.RaceCompetitionFormatDataCalculator;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.gwt.dispatch.shared.caching.IsClientCacheable;
|
||||
import com.sap.sse.gwt.dispatch.shared.commands.ResultWithTTL;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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.
|
||||
* </p>
|
||||
* <p>
|
||||
* The {@link ResultWithTTL result's} time to live
|
||||
* {@link EventActionUtil#getEventStateDependentTTL(SailingDispatchContext, UUID, Duration) depends on the event's
|
||||
* state} using a duration of <i>5 minutes</i> for currently running events.
|
||||
* </p>
|
||||
*/
|
||||
public class GetRegattaWithProgressAction implements SailingAction<ResultWithTTL<RegattaWithProgressDTO>>, IsClientCacheable {
|
||||
|
||||
private UUID eventId;
|
||||
@@ -20,6 +33,12 @@ public class GetRegattaWithProgressAction implements SailingAction<ResultWithTTL
|
||||
private GetRegattaWithProgressAction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GetRegattaWithProgressAction} 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 GetRegattaWithProgressAction(UUID eventId, String regattaId) {
|
||||
this.eventId = eventId;
|
||||
this.regattaId = regattaId;
|
||||
|
||||
+18
-2
@@ -13,15 +13,25 @@ import com.sap.sailing.gwt.home.communication.SailingAction;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sailing.gwt.home.communication.eventview.RegattaMetadataDTO;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil;
|
||||
import com.sap.sailing.gwt.home.server.LeaderboardContext;
|
||||
import com.sap.sailing.gwt.home.server.RaceContext;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil.LeaderboardCallback;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil.RaceCallback;
|
||||
import com.sap.sailing.gwt.home.server.LeaderboardContext;
|
||||
import com.sap.sailing.gwt.home.server.RaceContext;
|
||||
import com.sap.sailing.gwt.server.HomeServiceUtil;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.gwt.dispatch.shared.caching.IsClientCacheable;
|
||||
import com.sap.sse.gwt.dispatch.shared.commands.ResultWithTTL;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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.
|
||||
* </p>
|
||||
* <p>
|
||||
* The {@link ResultWithTTL result's} time to live is <i>2 minutes</i> for upcoming and currently running events,
|
||||
* otherwise it {@link EventActionUtil#calculateTtlForNonLiveEvent(Event, EventState) depends on the event's state}.
|
||||
* </p>
|
||||
*/
|
||||
public class GetRegattasAndLiveRacesForEventAction implements SailingAction<ResultWithTTL<RegattasAndLiveRacesDTO>>,
|
||||
IsClientCacheable {
|
||||
private UUID eventId;
|
||||
@@ -30,6 +40,12 @@ public class GetRegattasAndLiveRacesForEventAction implements SailingAction<Resu
|
||||
private GetRegattasAndLiveRacesForEventAction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GetRegattasAndLiveRacesForEventAction} instance for the given event-id.
|
||||
*
|
||||
* @param eventId
|
||||
* {@link UUID} of the event to load regattas and live races for
|
||||
*/
|
||||
public GetRegattasAndLiveRacesForEventAction(UUID eventId) {
|
||||
this.eventId = eventId;
|
||||
}
|
||||
|
||||
+17
@@ -6,12 +6,23 @@ import com.google.gwt.core.shared.GwtIncompatible;
|
||||
import com.sap.sailing.gwt.home.communication.SailingAction;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sailing.gwt.home.communication.event.statistics.EventStatisticsDTO;
|
||||
import com.sap.sailing.gwt.home.communication.event.statistics.GetEventStatisticsAction;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil;
|
||||
import com.sap.sailing.gwt.home.server.StatisticsCalculator;
|
||||
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.exceptions.DispatchException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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.
|
||||
* </p>
|
||||
* <p>
|
||||
* The {@link ResultWithTTL result's} time to live is <i>5 minutes</i>.
|
||||
* </p>
|
||||
*/
|
||||
public class GetSeriesStatisticsAction implements SailingAction<ResultWithTTL<EventStatisticsDTO>>, IsClientCacheable {
|
||||
|
||||
private UUID seriesId;
|
||||
@@ -19,6 +30,12 @@ public class GetSeriesStatisticsAction implements SailingAction<ResultWithTTL<Ev
|
||||
protected GetSeriesStatisticsAction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GetEventStatisticsAction} instance for the given series-id.
|
||||
*
|
||||
* @param seriesId
|
||||
* {@link UUID} of the series to load data for
|
||||
*/
|
||||
public GetSeriesStatisticsAction(UUID seriesId) {
|
||||
this.seriesId = seriesId;
|
||||
}
|
||||
|
||||
+32
@@ -3,12 +3,24 @@ package com.sap.sailing.gwt.home.communication.event.minileaderboard;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gwt.core.shared.GwtIncompatible;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.gwt.home.communication.SailingAction;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil;
|
||||
import com.sap.sse.gwt.dispatch.shared.caching.IsClientCacheable;
|
||||
import com.sap.sse.gwt.dispatch.shared.commands.ResultWithTTL;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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}.
|
||||
* </p>
|
||||
* <p>
|
||||
* The {@link ResultWithTTL result's} time to live is <i>1 minute</i> for currently running events, <i>2 minutes</i>
|
||||
* otherwise.
|
||||
* </p>
|
||||
*/
|
||||
public class GetMiniLeaderbordAction implements SailingAction<ResultWithTTL<GetMiniLeaderboardDTO>>, IsClientCacheable {
|
||||
private UUID eventId;
|
||||
private String leaderboardName;
|
||||
@@ -18,10 +30,30 @@ public class GetMiniLeaderbordAction implements SailingAction<ResultWithTTL<GetM
|
||||
private GetMiniLeaderbordAction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GetMiniLeaderbordAction} instance for the given event-id and leaderboard name, where the amount
|
||||
* of loaded entries is unlimited.
|
||||
*
|
||||
* @param eventId
|
||||
* {@link UUID} of the {@link Event} to load data for
|
||||
* @param leaderboardName
|
||||
* {@link String leaderboard name} to load data for
|
||||
*/
|
||||
public GetMiniLeaderbordAction(UUID eventId, String leaderboardName) {
|
||||
this(eventId, leaderboardName, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GetMiniLeaderbordAction} instance for the given event-id and leaderboard name, where the loaded
|
||||
* entries are limited to the provided amount.
|
||||
*
|
||||
* @param eventId
|
||||
* {@link UUID} of the {@link Event} to load data for
|
||||
* @param leaderboardName
|
||||
* {@link String leaderboard name} to load data for
|
||||
* @param limit
|
||||
* maximum number of entries to be loaded
|
||||
*/
|
||||
public GetMiniLeaderbordAction(UUID eventId, String leaderboardName, int limit) {
|
||||
this.eventId = eventId;
|
||||
this.leaderboardName = leaderboardName;
|
||||
|
||||
+29
-2
@@ -9,6 +9,17 @@ import com.sap.sailing.gwt.home.server.EventActionUtil;
|
||||
import com.sap.sse.gwt.dispatch.shared.caching.IsClientCacheable;
|
||||
import com.sap.sse.gwt.dispatch.shared.commands.ResultWithTTL;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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}.
|
||||
* </p>
|
||||
* <p>
|
||||
* The {@link ResultWithTTL result's} time to live is <i>1 minute</i> for currently running events, <i>2 minutes</i>
|
||||
* otherwise.
|
||||
* </p>
|
||||
*/
|
||||
public class GetMiniOverallLeaderbordAction implements SailingAction<ResultWithTTL<GetMiniLeaderboardDTO>>, IsClientCacheable {
|
||||
private UUID seriesId;
|
||||
private int limit = 0;
|
||||
@@ -17,10 +28,26 @@ public class GetMiniOverallLeaderbordAction implements SailingAction<ResultWithT
|
||||
private GetMiniOverallLeaderbordAction() {
|
||||
}
|
||||
|
||||
public GetMiniOverallLeaderbordAction(UUID eventId) {
|
||||
this(eventId, 0);
|
||||
/**
|
||||
* Creates a {@link GetMiniLeaderbordAction} instance for the given series-id, where the amount of loaded entries is
|
||||
* unlimited.
|
||||
*
|
||||
* @param seriesId
|
||||
* {@link UUID} of the series to load data for
|
||||
*/
|
||||
public GetMiniOverallLeaderbordAction(UUID seriesId) {
|
||||
this(seriesId, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GetMiniLeaderbordAction} instance for the given series-id, where the loaded
|
||||
* entries are limited to the provided amount.
|
||||
*
|
||||
* @param seriesId
|
||||
* {@link UUID} of the series to load data for
|
||||
* @param limit
|
||||
* maximum number of entries to be loaded
|
||||
*/
|
||||
public GetMiniOverallLeaderbordAction(UUID seriesId, int limit) {
|
||||
this.seriesId = seriesId;
|
||||
this.limit = limit;
|
||||
|
||||
+32
@@ -8,6 +8,7 @@ import com.google.gwt.core.shared.GwtIncompatible;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.gwt.home.communication.SailingAction;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sailing.gwt.home.communication.event.EventState;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil.CalculationWithEvent;
|
||||
import com.sap.sailing.news.EventNewsItem;
|
||||
@@ -18,6 +19,21 @@ 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.commands.ResultWithTTL;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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}.
|
||||
* </p>
|
||||
* <p>
|
||||
* The {@link ResultWithTTL result's} time to live is <i>2 minutes</i> for currently running events.
|
||||
* </p>
|
||||
* <p>
|
||||
* 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.
|
||||
* </p>
|
||||
*/
|
||||
public class GetEventOverviewNewsAction implements SailingAction<ResultWithTTL<ListResult<NewsEntryDTO>>>, IsClientCacheable {
|
||||
private UUID eventId;
|
||||
/**
|
||||
@@ -29,10 +45,26 @@ public class GetEventOverviewNewsAction implements SailingAction<ResultWithTTL<L
|
||||
private GetEventOverviewNewsAction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GetEventOverviewNewsAction} instance for the given event-id, where the amount of loaded news
|
||||
* entries is unlimited.
|
||||
*
|
||||
* @param eventId
|
||||
* {@link UUID} of the {@link Event} to load news for
|
||||
*/
|
||||
public GetEventOverviewNewsAction(UUID eventId) {
|
||||
this.eventId = eventId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GetEventOverviewNewsAction} instance for the given event-id, where the loaded news entries are
|
||||
* limited to the provided amount.
|
||||
*
|
||||
* @param eventId
|
||||
* {@link UUID} of the {@link Event} to load news for
|
||||
* @param limit
|
||||
* maximum number of news entries to be loaded
|
||||
*/
|
||||
public GetEventOverviewNewsAction(UUID eventId, int limit) {
|
||||
this.eventId = eventId;
|
||||
this.limit = limit;
|
||||
|
||||
+16
@@ -11,6 +11,16 @@ 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.exceptions.DispatchException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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.
|
||||
* </p>
|
||||
* <p>
|
||||
* The {@link ResultWithTTL result's} time to live is <i>5 minutes</i>.
|
||||
* </p>
|
||||
*/
|
||||
public class GetEventStatisticsAction implements SailingAction<ResultWithTTL<EventStatisticsDTO>>, IsClientCacheable {
|
||||
|
||||
private UUID eventId;
|
||||
@@ -18,6 +28,12 @@ public class GetEventStatisticsAction implements SailingAction<ResultWithTTL<Eve
|
||||
protected GetEventStatisticsAction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GetEventStatisticsAction} instance for the given event-id.
|
||||
*
|
||||
* @param eventId
|
||||
* {@link UUID} of the event to load data for
|
||||
*/
|
||||
public GetEventStatisticsAction(UUID eventId) {
|
||||
this.eventId = eventId;
|
||||
}
|
||||
|
||||
+12
@@ -19,6 +19,12 @@ import com.sap.sse.gwt.dispatch.shared.caching.IsClientCacheable;
|
||||
import com.sap.sse.gwt.dispatch.shared.exceptions.DispatchException;
|
||||
import com.sap.sse.shared.media.ImageDescriptor;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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.
|
||||
* </p>
|
||||
*/
|
||||
public class GetEventSeriesViewAction implements SailingAction<EventSeriesViewDTO>, IsClientCacheable {
|
||||
|
||||
private UUID id;
|
||||
@@ -27,6 +33,12 @@ public class GetEventSeriesViewAction implements SailingAction<EventSeriesViewDT
|
||||
private GetEventSeriesViewAction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GetEventSeriesViewAction} instance for the given series-id.
|
||||
*
|
||||
* @param id
|
||||
* {@link UUID} of the series to load data for
|
||||
*/
|
||||
public GetEventSeriesViewAction(UUID id) {
|
||||
super();
|
||||
this.id = id;
|
||||
|
||||
+12
@@ -15,6 +15,12 @@ import com.sap.sse.gwt.dispatch.shared.exceptions.DispatchException;
|
||||
import com.sap.sse.shared.media.ImageDescriptor;
|
||||
import com.sap.sse.shared.media.VideoDescriptor;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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.
|
||||
* </p>
|
||||
*/
|
||||
public class GetMediaForEventAction implements SailingAction<MediaDTO>, IsClientCacheable {
|
||||
|
||||
private UUID eventId;
|
||||
@@ -23,6 +29,12 @@ public class GetMediaForEventAction implements SailingAction<MediaDTO>, 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;
|
||||
}
|
||||
|
||||
+12
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* {@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}.
|
||||
* </p>
|
||||
*/
|
||||
public class GetRecentEventsAction implements SailingAction<ListResult<EventQuickfinderDTO>>, IsClientCacheable {
|
||||
|
||||
private int limit;
|
||||
@@ -22,6 +28,12 @@ public class GetRecentEventsAction implements SailingAction<ListResult<EventQuic
|
||||
protected GetRecentEventsAction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GetRecentEventsAction} instance where the loaded entries are limited to the provided amount.
|
||||
*
|
||||
* @param limit
|
||||
* maximum number of entries to be loaded
|
||||
*/
|
||||
public GetRecentEventsAction(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
+4
@@ -101,8 +101,12 @@ public class MultiRegattaListStepsBody extends UIObject implements RequiresResiz
|
||||
String[] tokens = seriesName.split(" ");
|
||||
StringBuilder initials = new StringBuilder();
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
if (tokens[i].isEmpty()) { // this may happen, e.g., in case of a FlexibleLeaderboard that does not have a series
|
||||
initials.append('R');
|
||||
} else {
|
||||
initials.append(tokens[i].charAt(0));
|
||||
}
|
||||
}
|
||||
return initials.toString();
|
||||
}
|
||||
|
||||
|
||||
+2
-7
@@ -2,12 +2,12 @@ package com.sap.sailing.gwt.home.desktop.places.event.multiregatta.mediatab;
|
||||
|
||||
import com.google.gwt.place.shared.Prefix;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.multiregatta.AbstractMultiregattaEventPlace;
|
||||
import com.sap.sailing.gwt.home.shared.app.MobileSupport;
|
||||
import com.sap.sailing.gwt.home.shared.app.HasMobileVersion;
|
||||
import com.sap.sailing.gwt.home.shared.places.PlaceTokenPrefixes;
|
||||
import com.sap.sailing.gwt.home.shared.places.event.AbstractEventPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.event.EventContext;
|
||||
|
||||
public class MultiregattaMediaPlace extends AbstractMultiregattaEventPlace implements MobileSupport {
|
||||
public class MultiregattaMediaPlace extends AbstractMultiregattaEventPlace implements HasMobileVersion {
|
||||
public MultiregattaMediaPlace(String id) {
|
||||
super(id);
|
||||
}
|
||||
@@ -23,9 +23,4 @@ public class MultiregattaMediaPlace extends AbstractMultiregattaEventPlace imple
|
||||
return new MultiregattaMediaPlace(context);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMobileVersion() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+2
-7
@@ -2,12 +2,12 @@ package com.sap.sailing.gwt.home.desktop.places.event.regatta.mediatab;
|
||||
|
||||
import com.google.gwt.place.shared.Prefix;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.regatta.AbstractEventRegattaPlace;
|
||||
import com.sap.sailing.gwt.home.shared.app.MobileSupport;
|
||||
import com.sap.sailing.gwt.home.shared.app.HasMobileVersion;
|
||||
import com.sap.sailing.gwt.home.shared.places.PlaceTokenPrefixes;
|
||||
import com.sap.sailing.gwt.home.shared.places.event.AbstractEventPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.event.EventContext;
|
||||
|
||||
public class RegattaMediaPlace extends AbstractEventRegattaPlace implements MobileSupport {
|
||||
public class RegattaMediaPlace extends AbstractEventRegattaPlace implements HasMobileVersion {
|
||||
public RegattaMediaPlace(String id, String regattaId) {
|
||||
super(id, regattaId);
|
||||
}
|
||||
@@ -29,9 +29,4 @@ public class RegattaMediaPlace extends AbstractEventRegattaPlace implements Mobi
|
||||
return new RegattaMediaPlace(context);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMobileVersion() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+2
-7
@@ -2,12 +2,12 @@ package com.sap.sailing.gwt.home.desktop.places.event.regatta.racestab;
|
||||
|
||||
import com.google.gwt.place.shared.Prefix;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.regatta.AbstractEventRegattaPlace;
|
||||
import com.sap.sailing.gwt.home.shared.app.MobileSupport;
|
||||
import com.sap.sailing.gwt.home.shared.app.HasMobileVersion;
|
||||
import com.sap.sailing.gwt.home.shared.places.PlaceTokenPrefixes;
|
||||
import com.sap.sailing.gwt.home.shared.places.event.AbstractEventPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.event.EventContext;
|
||||
|
||||
public class RegattaRacesPlace extends AbstractEventRegattaPlace implements MobileSupport {
|
||||
public class RegattaRacesPlace extends AbstractEventRegattaPlace implements HasMobileVersion {
|
||||
public RegattaRacesPlace(String id, String leaderboardName) {
|
||||
super(id, leaderboardName);
|
||||
}
|
||||
@@ -28,9 +28,4 @@ public class RegattaRacesPlace extends AbstractEventRegattaPlace implements Mobi
|
||||
return new RegattaRacesPlace(context);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMobileVersion() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+32
@@ -82,6 +82,19 @@ public final class EventActionUtil {
|
||||
return new LeaderboardContext(context, event, leaderboardGroups, leaderboard);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets or calculates the time to live for the event with the given ID, depending on its
|
||||
* {@link HomeServiceUtil#calculateEventState(com.sap.sailing.domain.base.EventBase) calculated state}.
|
||||
*
|
||||
* @param context
|
||||
* {@link SailingDispatchContext} to retrieve {@link Event}
|
||||
* @param eventId
|
||||
* {@link UUID} of the {@link Event} to get/calculate the time to live for
|
||||
* @param liveTTL
|
||||
* the {@link Duration time to live} to use if the event is currently running
|
||||
* @return the given liveTTL if the event is currently running, otherwise the
|
||||
* {@link #calculateTtlForNonLiveEvent(Event, EventState) calculated TTL}
|
||||
*/
|
||||
public static Duration getEventStateDependentTTL(SailingDispatchContext context, UUID eventId, Duration liveTTL) {
|
||||
Event event = context.getRacingEventService().getEvent(eventId);
|
||||
return getEventStateDependentTTL(event, liveTTL);
|
||||
@@ -104,6 +117,25 @@ public final class EventActionUtil {
|
||||
return callback.calculateWithEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the time to live based on the given {@link Event}'s {@link Event#getStartDate() start time} and the
|
||||
* given {@link HomeServiceUtil#calculateEventState(com.sap.sailing.domain.base.EventBase) calculated state}:
|
||||
* <p><table>
|
||||
* <tr><th>Event state </th><th>Start time </th><th>TTL </th></tr>
|
||||
* <tr><td>UPMCOMING/PLANNED</td><td>36 hours and more before</td><td>=> 1 hour</td></tr>
|
||||
* <tr><td> </td><td>less than 36 hours before</td><td>=> 30 minutes</td></tr>
|
||||
* <tr><td> </td><td>less than 3 hours before</td><td>=> 15 minutes</td></tr>
|
||||
* <tr><td> </td><td>less than 15 minutes before</td><td>=> time till start</td></tr>
|
||||
* <tr><td>FINISHED </td><td>any </td><td>=> 12 hours</td></tr>
|
||||
* <tr><td>RUNNING </td><td>any </td><td>=> [0]</td></tr>
|
||||
* </table></p>
|
||||
*
|
||||
* @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) {
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ public class MediaPlayerLifecycle implements ComponentLifecycle<MediaPlayerSetti
|
||||
|
||||
@Override
|
||||
public MediaPlayerSettings createDefaultSettings() {
|
||||
return new MediaPlayerSettings();
|
||||
return MediaPlayerSettings.readSettingsFromURL();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-5
@@ -1,5 +1,6 @@
|
||||
package com.sap.sailing.gwt.ui.client.media;
|
||||
|
||||
import com.sap.sailing.gwt.common.client.formfactor.DeviceDetector;
|
||||
import com.sap.sse.common.settings.AbstractSettings;
|
||||
import com.sap.sse.gwt.shared.GwtHttpRequestUtils;
|
||||
|
||||
@@ -8,11 +9,8 @@ public class MediaPlayerSettings extends AbstractSettings {
|
||||
|
||||
public static final String PARAM_AUTOPLAY_MEDIA = "autoSelectMedia";
|
||||
|
||||
/**
|
||||
* The default settings
|
||||
*/
|
||||
public MediaPlayerSettings() {
|
||||
this.autoPlayMedia = true;
|
||||
this.autoPlayMedia = !DeviceDetector.isMobile();
|
||||
}
|
||||
|
||||
public MediaPlayerSettings(boolean autoPlayMedia) {
|
||||
@@ -24,7 +22,7 @@ public class MediaPlayerSettings extends AbstractSettings {
|
||||
}
|
||||
|
||||
public static MediaPlayerSettings readSettingsFromURL() {
|
||||
final Boolean autoPlayMedia = GwtHttpRequestUtils.getBooleanParameter(PARAM_AUTOPLAY_MEDIA, true /* default */);
|
||||
final Boolean autoPlayMedia = GwtHttpRequestUtils.getBooleanParameter(PARAM_AUTOPLAY_MEDIA, !DeviceDetector.isMobile());
|
||||
|
||||
return new MediaPlayerSettings(autoPlayMedia);
|
||||
}
|
||||
|
||||
+21
-8
@@ -12,6 +12,7 @@ import com.google.gwt.user.client.rpc.ServiceDefTarget;
|
||||
import com.google.gwt.user.client.ui.DockLayoutPanel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.RootLayoutPanel;
|
||||
import com.sap.sailing.gwt.common.client.formfactor.DeviceDetector;
|
||||
import com.sap.sailing.gwt.ui.client.AbstractSailingEntryPoint;
|
||||
import com.sap.sailing.gwt.ui.client.LogoAndTitlePanel;
|
||||
import com.sap.sailing.gwt.ui.client.MediaService;
|
||||
@@ -25,6 +26,7 @@ import com.sap.sse.gwt.client.EntryPointHelper;
|
||||
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
|
||||
import com.sap.sse.gwt.client.player.Timer;
|
||||
import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveLifecycleWithAllSettings;
|
||||
|
||||
public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
@@ -74,6 +76,11 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
|
||||
// read perspective settings parameters from URL
|
||||
final RaceBoardPerspectiveSettings perspectiveSettings = RaceBoardPerspectiveSettings.readSettingsFromURL();
|
||||
// Determine if the charts, such as the competitor chart or the wind chart, the edit marks
|
||||
// panels, such as mark passing and mark position editors and manage media buttons should be shown.
|
||||
// Automatic selection of attached video (if any) also depends on this flag.
|
||||
// The decision is made once during initial page load based on the device type (mobile or not).
|
||||
final boolean showChartMarkEditMediaButtonsAndVideo = !DeviceDetector.isMobile();
|
||||
|
||||
sailingService.getRaceboardData(regattaName, raceName, leaderboardName, leaderboardGroupName, eventId, new AsyncCallback<RaceboardDataDTO>() {
|
||||
@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);
|
||||
PerspectiveLifecycleWithAllSettings<RaceBoardPerspectiveLifecycle, RaceBoardPerspectiveSettings> raceboardPerspectiveLifecyclesAndSettings = new PerspectiveLifecycleWithAllSettings<>(raceboardPerspectiveLifecycle,
|
||||
raceboardPerspectiveLifecycle.createDefaultSettings());
|
||||
PerspectiveCompositeSettings<RaceBoardPerspectiveSettings> defaultSettings = raceboardPerspectiveLifecycle.createDefaultSettings();
|
||||
PerspectiveCompositeSettings<RaceBoardPerspectiveSettings> perspectiveCompositeSettings =
|
||||
new PerspectiveCompositeSettings<>(perspectiveSettings, defaultSettings.getSettingsPerComponentId());
|
||||
|
||||
RaceBoardPanel raceBoardPerspective = new RaceBoardPanel(
|
||||
raceboardPerspectiveLifecyclesAndSettings, sailingService, mediaService, getUserService(),
|
||||
asyncActionsExecutor, raceboardData.getCompetitorAndTheirBoats(), timer, selectedRace.getRaceIdentifier(), leaderboardName,
|
||||
leaderboardGroupName, eventId, RaceBoardEntryPoint.this, getStringMessages(), userAgent, raceTimesInfoProvider);
|
||||
PerspectiveLifecycleWithAllSettings<RaceBoardPerspectiveLifecycle, RaceBoardPerspectiveSettings> raceboardPerspectiveLifecyclesAndSettings = new PerspectiveLifecycleWithAllSettings<>(raceboardPerspectiveLifecycle,
|
||||
perspectiveCompositeSettings);
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
+26
-16
@@ -159,13 +159,18 @@ public class RaceBoardPanel extends AbstractPerspectiveComposite<RaceBoardPerspe
|
||||
* 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. This decision is made once on startup in the {@link RaceBoardEntryPoint} class.
|
||||
* @param showChartMarkEditMediaButtonsAndVideo
|
||||
* if <code>true</code> 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<RaceBoardPerspectiveLifecycle, RaceBoardPerspectiveSettings> perspectiveLifecycleWithAllSettings,
|
||||
SailingServiceAsync sailingService, MediaServiceAsync mediaService,
|
||||
UserService userService, AsyncActionsExecutor asyncActionsExecutor, Map<CompetitorDTO, BoatDTO> competitorsAndTheirBoats,
|
||||
SailingServiceAsync sailingService, MediaServiceAsync mediaService, UserService userService,
|
||||
AsyncActionsExecutor asyncActionsExecutor, Map<CompetitorDTO, BoatDTO> 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 AbstractPerspectiveComposite<RaceBoardPerspe
|
||||
leaderboardPanel.setTitle(stringMessages.leaderboard());
|
||||
leaderboardPanel.getElement().getStyle().setMarginLeft(6, Unit.PX);
|
||||
leaderboardPanel.getElement().getStyle().setMarginTop(10, Unit.PX);
|
||||
createOneScreenView(leaderboardName, leaderboardGroupName, eventId, mainPanel, isScreenLargeEnoughToInitiallyDisplayLeaderboard, raceMap, userService); // initializes the raceMap field
|
||||
createOneScreenView(leaderboardName, leaderboardGroupName, eventId, mainPanel, isScreenLargeEnoughToInitiallyDisplayLeaderboard,
|
||||
raceMap, userService, showChartMarkEditMediaButtonsAndVideo); // initializes the raceMap field
|
||||
leaderboardPanel.addLeaderboardUpdateListener(this);
|
||||
// in case the URL configuration contains the name of a competitors filter set we try to activate it
|
||||
// FIXME the competitorsFilterSets has now moved to CompetitorSearchTextBox (which should probably be renamed); pass on the parameters to the LeaderboardPanel and see what it does with it
|
||||
@@ -263,9 +269,10 @@ public class RaceBoardPanel extends AbstractPerspectiveComposite<RaceBoardPerspe
|
||||
}
|
||||
}
|
||||
}
|
||||
racetimePanel = new RaceTimePanel(raceTimePanelLifecycle, userService, timer, timeRangeWithZoomModel, stringMessages, raceTimesInfoProvider,
|
||||
getPerspectiveSettings().isCanReplayDuringLiveRaces(), getPerspectiveSettings().isChartSupportEnabled(),
|
||||
selectedRaceIdentifier, getPerspectiveSettings().getInitialDurationAfterRaceStartInReplay());
|
||||
racetimePanel = new RaceTimePanel(raceTimePanelLifecycle, userService, timer, timeRangeWithZoomModel,
|
||||
stringMessages, raceTimesInfoProvider, getPerspectiveSettings().isCanReplayDuringLiveRaces(),
|
||||
showChartMarkEditMediaButtonsAndVideo, selectedRaceIdentifier,
|
||||
getPerspectiveSettings().getInitialDurationAfterRaceStartInReplay());
|
||||
racetimePanel.updateSettings(raceTimePanelSettings);
|
||||
timeRangeWithZoomModel.addTimeZoomChangeListener(racetimePanel);
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(racetimePanel);
|
||||
@@ -289,13 +296,15 @@ public class RaceBoardPanel extends AbstractPerspectiveComposite<RaceBoardPerspe
|
||||
* @param event
|
||||
* an optional event; may be <code>null</code> 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<RaceBoardPerspe
|
||||
// create the default leaderboard and select the right race
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(raceMap);
|
||||
List<Component<?>> componentsForSideBySideViewer = new ArrayList<Component<?>>();
|
||||
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<RaceBoardPerspe
|
||||
windChart.setVisible(false);
|
||||
windChart.getEntryWidget().setTitle(stringMessages.windChart());
|
||||
componentsForSideBySideViewer.add(windChart);
|
||||
}
|
||||
|
||||
editMarkPassingPanel = new EditMarkPassingsPanel(sailingService, selectedRaceIdentifier, stringMessages,
|
||||
competitorSelectionProvider, errorReporter, timer);
|
||||
if (showChartMarkEditMediaButtonsAndVideo) {
|
||||
editMarkPassingPanel.setLeaderboard(leaderboardPanel.getLeaderboard());
|
||||
editMarkPassingPanel.getEntryWidget().setTitle(stringMessages.editMarkPassings());
|
||||
componentsForSideBySideViewer.add(editMarkPassingPanel);
|
||||
}
|
||||
editMarkPositionPanel = new EditMarkPositionPanel(raceMap, leaderboardPanel, selectedRaceIdentifier, leaderboardName, stringMessages, sailingService, timer, timeRangeWithZoomModel,
|
||||
asyncActionsExecutor, errorReporter);
|
||||
if (showChartMarkEditMediaButtonsAndVideo) {
|
||||
editMarkPositionPanel.setLeaderboard(leaderboardPanel.getLeaderboard());
|
||||
componentsForSideBySideViewer.add(editMarkPositionPanel);
|
||||
}
|
||||
mediaPlayerManagerComponent = new MediaPlayerManagerComponent(mediaPlayerLifecycle,
|
||||
|
||||
mediaPlayerManagerComponent = new MediaPlayerManagerComponent(mediaPlayerLifecycle,
|
||||
selectedRaceIdentifier, raceTimesInfoProvider, timer, mediaService, userService, stringMessages,
|
||||
errorReporter, userAgent, this, mediaPlayerSettings);
|
||||
leaderboardAndMapViewer = new SideBySideComponentViewer(leaderboardPanel, raceMap, mediaPlayerManagerComponent,
|
||||
@@ -345,11 +359,7 @@ public class RaceBoardPanel extends AbstractPerspectiveComposite<RaceBoardPerspe
|
||||
mainPanel.add(leaderboardAndMapViewer.getViewerWidget());
|
||||
boolean showLeaderboard = getPerspectiveSettings().isShowLeaderboard() && isScreenLargeEnoughToInitiallyDisplayLeaderboard;
|
||||
setLeaderboardVisible(showLeaderboard);
|
||||
if (getPerspectiveSettings().isChartSupportEnabled()) {
|
||||
setWindChartVisible(getPerspectiveSettings().isShowWindChart());
|
||||
setCompetitorChartVisible(getPerspectiveSettings().isShowCompetitorsChart());
|
||||
}
|
||||
if (getPerspectiveSettings().isShowChartMarkEditMediaButtonsAndVideo()) {
|
||||
if (showChartMarkEditMediaButtonsAndVideo) {
|
||||
setWindChartVisible(getPerspectiveSettings().isShowWindChart());
|
||||
setCompetitorChartVisible(getPerspectiveSettings().isShowCompetitorsChart());
|
||||
}
|
||||
|
||||
+4
-34
@@ -1,7 +1,5 @@
|
||||
package com.sap.sailing.gwt.ui.raceboard;
|
||||
|
||||
import com.google.gwt.dom.client.Document;
|
||||
import com.sap.sailing.gwt.common.client.formfactor.DeviceDetector;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.impl.MillisecondsDurationImpl;
|
||||
import com.sap.sse.common.settings.AbstractSettings;
|
||||
@@ -16,20 +14,11 @@ public class RaceBoardPerspectiveSettings extends AbstractSettings {
|
||||
private final boolean showLeaderboard;
|
||||
private final boolean showWindChart;
|
||||
private final boolean showCompetitorsChart;
|
||||
|
||||
// Determine if the charts, such as the competitor chart or the wind chart, the edit marks
|
||||
// panels, such as mark passing and mark position editors and manage media buttons should be shown.
|
||||
// Automatic selection of attached video (if any) also depends on this flag.
|
||||
// The decision is made once during initial page load based on the device type (mobile or not).
|
||||
private final boolean showChartMarkEditMediaButtonsAndVideo;
|
||||
private final String activeCompetitorsFilterSetName;
|
||||
private final boolean canReplayDuringLiveRaces;
|
||||
private final boolean simulationEnabled;
|
||||
private final Duration initialDurationAfterRaceStartInReplay;
|
||||
|
||||
/** indicates whether it's enabled to display charts or not */
|
||||
private final boolean chartSupportEnabled;
|
||||
|
||||
public static final String PARAM_VIEW_MODE = "viewMode";
|
||||
public static final String PARAM_VIEW_SHOW_LEADERBOARD = "viewShowLeaderboard";
|
||||
public static final String PARAM_VIEW_SHOW_NAVIGATION_PANEL = "viewShowNavigationPanel";
|
||||
@@ -45,23 +34,19 @@ public class RaceBoardPerspectiveSettings extends AbstractSettings {
|
||||
public RaceBoardPerspectiveSettings() {
|
||||
this(/* activeCompetitorsFilterSetName */null, /* showLeaderboard */true,
|
||||
/* showWindChart */false, /* showCompetitorsChart */false,
|
||||
/* simulationEnabled */true, /* canReplayDuringLiveRaces */false, /* chartSupportEnabled */ true,
|
||||
/* showChartMarkEditMediaButtonsAndVideo */ !DeviceDetector.isMobile(),
|
||||
/* simulationEnabled */true, /* canReplayDuringLiveRaces */false,
|
||||
/* initialDurationAfterRaceStartInReplay */ null);
|
||||
}
|
||||
|
||||
public RaceBoardPerspectiveSettings(String activeCompetitorsFilterSetName, boolean showLeaderboard,
|
||||
boolean showWindChart, boolean showCompetitorsChart, boolean simulationEnabled, boolean canReplayDuringLiveRaces,
|
||||
boolean chartSupportEnabled, boolean showChartMarkEditMediaButtonsAndVideo,
|
||||
Duration initialDurationAfterRaceStartInReplay) {
|
||||
boolean showWindChart, boolean showCompetitorsChart, boolean simulationEnabled,
|
||||
boolean canReplayDuringLiveRaces, Duration initialDurationAfterRaceStartInReplay) {
|
||||
this.activeCompetitorsFilterSetName = activeCompetitorsFilterSetName;
|
||||
this.showLeaderboard = showLeaderboard;
|
||||
this.showWindChart = showWindChart;
|
||||
this.showCompetitorsChart = showCompetitorsChart;
|
||||
this.simulationEnabled = simulationEnabled;
|
||||
this.canReplayDuringLiveRaces = canReplayDuringLiveRaces;
|
||||
this.chartSupportEnabled = chartSupportEnabled;
|
||||
this.showChartMarkEditMediaButtonsAndVideo = showChartMarkEditMediaButtonsAndVideo;
|
||||
this.initialDurationAfterRaceStartInReplay = initialDurationAfterRaceStartInReplay;
|
||||
}
|
||||
|
||||
@@ -89,10 +74,6 @@ public class RaceBoardPerspectiveSettings extends AbstractSettings {
|
||||
return canReplayDuringLiveRaces;
|
||||
}
|
||||
|
||||
public boolean isChartSupportEnabled() {
|
||||
return chartSupportEnabled;
|
||||
}
|
||||
|
||||
public static RaceBoardPerspectiveSettings readSettingsFromURL() {
|
||||
final boolean showLeaderboard = GwtHttpRequestUtils.getBooleanParameter(PARAM_VIEW_SHOW_LEADERBOARD, true /* default */);
|
||||
final boolean showWindChart = GwtHttpRequestUtils.getBooleanParameter(PARAM_VIEW_SHOW_WINDCHART, false /* default */);
|
||||
@@ -101,22 +82,11 @@ public class RaceBoardPerspectiveSettings extends AbstractSettings {
|
||||
String activeCompetitorsFilterSetName = GwtHttpRequestUtils.getStringParameter(PARAM_VIEW_COMPETITOR_FILTER, null /* default */);
|
||||
final boolean canReplayWhileLiveIsPossible = GwtHttpRequestUtils.getBooleanParameter(PARAM_CAN_REPLAY_DURING_LIVE_RACES, false /* default */);
|
||||
|
||||
// Determine if the screen is large enough to display charts such as the competitor chart or the wind chart.
|
||||
// This decision is made once based on the initial screen height. Resizing the window afterwards will have
|
||||
// no impact on the chart support, i.e. they are available/unavailable based on the initial decision.
|
||||
boolean isScreenLargeEnoughToOfferChartSupport = Document.get().getClientHeight() >= 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() {
|
||||
|
||||
+1
-2
@@ -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;
|
||||
}
|
||||
|
||||
+2
-1
@@ -448,7 +448,8 @@ public class DummyTrackedRace extends TrackedRaceWithWindEssentials {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detachRaceLog(Serializable identifier) {
|
||||
public RaceLog detachRaceLog(Serializable identifier) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in new issue
Block a user