load race column factors at login

This commit is contained in:
Peter Siegmund
2016-04-13 15:12:19 +02:00
parent 8942bdf6fc
commit 61089e2b83
22 changed files with 413 additions and 133 deletions
@@ -0,0 +1,12 @@
package com.sap.sailing.domain.common.impl;
public class RaceColumnConstants {
public static final String LEADERBOARD_NAME = "leaderboard_name";
public static final String LEADERBOARD_DISPLAY_NAME = "leaderboard_display_name";
public static final String RACE_COLUMNS = "race_columns";
public static final String RACE_COLUMN_NAME = "race_column_name";
public static final String EXPLICIT_FACTOR = "explicit_factor";
public static final String FACTOR = "factor";
}
@@ -0,0 +1,57 @@
package com.sap.sailing.domain.base.impl;
import java.util.HashMap;
public class RaceColumnFactorImpl {
private final String leaderboard_name;
private final String leaderboard_display_name;
private final HashMap<String, RaceColumn> race_columns;
public RaceColumnFactorImpl(String leaderboard_name, String leaderboard_display_name) {
this.leaderboard_name = leaderboard_name;
this.leaderboard_display_name = leaderboard_display_name;
race_columns = new HashMap<>();
}
public String getLeaderboardName() {
return leaderboard_name;
}
public String getLeaderboardDisplayName() {
return leaderboard_display_name;
}
public HashMap<String, RaceColumn> getRaceColumns() {
return race_columns;
}
public void addRaceColumn(String race_column_name, Double explicit_factor, Double factor) {
race_columns.put(race_column_name, new RaceColumn(race_column_name, explicit_factor, factor));
}
public class RaceColumn {
private final String race_column_name;
private final Double explicit_factor;
private final Double factor;
public RaceColumn(String race_column_name, Double explicit_factor, Double factor) {
this.race_column_name = race_column_name;
this.explicit_factor = explicit_factor;
this.factor = factor;
}
public String getRaceColumnName() {
return race_column_name;
}
public Double getExplicitFactor() {
return explicit_factor;
}
public Double getFactor() {
return factor;
}
}
}
@@ -0,0 +1,29 @@
package com.sap.sailing.server.gateway.deserialization.impl;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.impl.RaceColumnFactorImpl;
import com.sap.sailing.domain.common.impl.RaceColumnConstants;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
public class RaceColumnFactorJsonDeserializer implements JsonDeserializer<RaceColumnFactorImpl> {
@Override
public RaceColumnFactorImpl deserialize(JSONObject object) throws JsonDeserializationException {
String leaderboard_name = (String) object.get(RaceColumnConstants.LEADERBOARD_NAME);
String leaderboard_display_name = (String) object.get(RaceColumnConstants.LEADERBOARD_DISPLAY_NAME);
RaceColumnFactorImpl raceColumnFactor = new RaceColumnFactorImpl(leaderboard_name, leaderboard_display_name);
JSONArray race_columns = (JSONArray) object.get(RaceColumnConstants.RACE_COLUMNS);
int size = race_columns.size();
for (int i = 0; i < size; i++) {
JSONObject data = (JSONObject) race_columns.get(i);
String race_column_name = (String) data.get(RaceColumnConstants.RACE_COLUMN_NAME);
Double explicit_factor = (Double) data.get(RaceColumnConstants.EXPLICIT_FACTOR);
Double factor = (Double) data.get(RaceColumnConstants.FACTOR);
raceColumnFactor.addRaceColumn(race_column_name, explicit_factor, factor);
}
return raceColumnFactor;
}
}
@@ -678,16 +678,16 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
private JSONObject getJsonForColumnFactors(final Leaderboard leaderboard, final Iterable<RaceColumn> raceColumns) {
final JSONObject json = new JSONObject();
json.put("leaderboard_name", leaderboard.getName());
json.put("leaderboard_display_name", leaderboard.getDisplayName());
json.put(RaceColumnConstants.LEADERBOARD_NAME, leaderboard.getName());
json.put(RaceColumnConstants.LEADERBOARD_DISPLAY_NAME, leaderboard.getDisplayName());
final JSONArray raceColumnsAsJson = new JSONArray();
json.put("race_columns", raceColumnsAsJson);
json.put(RaceColumnConstants.RACE_COLUMNS, raceColumnsAsJson);
for (final RaceColumn rc : raceColumns) {
final JSONObject raceColumnAsJson = new JSONObject();
raceColumnsAsJson.add(raceColumnAsJson);
raceColumnAsJson.put("race_column_name", rc.getName());
raceColumnAsJson.put("explicit_factor", rc.getExplicitFactor());
raceColumnAsJson.put("factor", rc.getFactor());
raceColumnAsJson.put(RaceColumnConstants.RACE_COLUMN_NAME, rc.getName());
raceColumnAsJson.put(RaceColumnConstants.EXPLICIT_FACTOR, rc.getExplicitFactor());
raceColumnAsJson.put(RaceColumnConstants.FACTOR, rc.getFactor());
}
return json;
}
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/constant_light_gray"/>
<padding
android:left="5dp"
android:right="5dp"
android:top="@dimen/thin_line"/>
<corners
android:bottomLeftRadius="3dp"
android:bottomRightRadius="3dp"/>
</shape>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/constant_black"/>
<padding
android:left="5dp"
android:right="5dp"
android:top="@dimen/thin_line"/>
<corners
android:bottomLeftRadius="3dp"
android:bottomRightRadius="3dp"/>
</shape>
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="@dimen/navigation_drawer_cell_height">
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="@dimen/navigation_drawer_cell_height">
<RelativeLayout
android:id="@+id/panel_right"
@@ -24,7 +24,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textAppearance="?attr/textXLarge"
tools:text="13:36" />
tools:text="13:36"/>
<TextView
android:id="@+id/race_started"
@@ -32,7 +32,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/race_started"
android:textAppearance="?attr/textXSmall" />
android:textAppearance="?attr/textXSmall"/>
<TextView
android:id="@+id/race_finished"
@@ -40,7 +40,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/race_finished"
android:textAppearance="?attr/textXSmall" />
android:textAppearance="?attr/textXSmall"/>
</LinearLayout>
<TextView
@@ -51,7 +51,7 @@
android:text="@string/race_unscheduled"
android:textColor="?attr/sap_light_gray"
android:textSize="@dimen/textSize_18"
android:visibility="gone" />
android:visibility="gone"/>
<ImageView
android:id="@+id/update_badge"
@@ -62,7 +62,7 @@
android:scaleType="matrix"
android:src="@drawable/updated"
android:visibility="gone"
tools:visibility="visible" />
tools:visibility="visible"/>
</RelativeLayout>
<RelativeLayout
@@ -76,7 +76,7 @@
android:id="@+id/race_marker"
android:layout_width="@dimen/obesity_line"
android:layout_height="match_parent"
android:src="?attr/marker_race" />
android:src="?attr/marker_race"/>
<LinearLayout
android:id="@+id/additional_info"
@@ -93,7 +93,7 @@
android:layout_margin="5dp"
android:src="?attr/link_24dp"
android:visibility="gone"
tools:visibility="visible" />
tools:visibility="visible"/>
<LinearLayout
android:id="@+id/race_flag"
@@ -110,7 +110,7 @@
android:layout_height="25dp"
android:layout_gravity="center"
android:scaleType="centerInside"
tools:src="@drawable/flag_alpha_64dp" />
tools:src="@drawable/flag_alpha_64dp"/>
<TextView
android:id="@+id/flag_timer"
@@ -119,7 +119,7 @@
android:layout_gravity="center"
android:drawableLeft="?attr/arrow_down"
android:textAppearance="?attr/textXSmall"
tools:text="01:12" />
tools:text="01:12"/>
</LinearLayout>
</LinearLayout>
@@ -141,7 +141,7 @@
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?attr/textNormal"
tools:text="Race 3" />
tools:text="Race 3"/>
<TextView
android:id="@+id/depends_on"
@@ -152,13 +152,23 @@
android:textAppearance="?attr/textXSmall"
android:visibility="gone"
tools:text="5 minutes after ABC"
tools:visibility="visible" />
tools:visibility="visible"/>
</LinearLayout>
</RelativeLayout>
<TextView
android:id="@+id/explicit_factor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="?attr/factor_background"
android:textAppearance="?attr/textXSmall"
android:textColor="?attr/white_invert"
tools:text="x 3.5"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="@dimen/thin_line"
android:layout_alignParentBottom="true"
android:background="?attr/black" />
android:background="?attr/black"/>
</RelativeLayout>
@@ -507,5 +507,6 @@
<string name="abort_title">Rennen abbrechen</string>
<string name="abort_hint">Welche laufenden Rennen möchten Sie abbrechen?</string>
<string name="abort_dismiss">Verwerfen</string>
<string name="explicit_factor">x %1$s</string>
</resources>
@@ -38,6 +38,8 @@
<attr name="editText" format="reference"/>
<attr name="floatLabel" format="reference"/>
<attr name="factor_background" format="reference"/>
<!-- drawable -->
<attr name="add" format="reference"/>
<attr name="access_time_18dp" format="reference"/>
@@ -98,7 +98,7 @@
<string name="preference_dependent_races_offset_key" translatable="false">dependentRacesOffset</string>
<integer name="preference_dependent_races_offset_default">5</integer>
<string name="preference_allow_edit_race_factor_key" translatable="false">raceFactor</string>
<bool name="preference_allow_edit_race_factor_default">false</bool>
<bool name="preference_allow_edit_race_factor_default">true</bool>
<string name="preference_allow_demo_key" translatable="false">allow_demo</string>
<bool name="preference_allow_demo_default">false</bool>
@@ -534,5 +534,6 @@
<string name="abort_title">Abort Races</string>
<string name="abort_hint">Which running races do you want to abort?</string>
<string name="abort_dismiss">Dismiss</string>
<string name="race_factor_format" translatable="false">x #.####</string>
</resources>
@@ -51,6 +51,8 @@
<item name="textPanelHeader">@style/AppTheme.Dark.Text.PanelHeader</item>
<item name="floatLabel">@style/AppTheme.Dark.Text.FloatLabel</item>
<item name="factor_background">@drawable/factor_background_dark</item>
<!-- drawable -->
<item name="add">@drawable/ic_add_dark</item>
<item name="access_time_18dp">@drawable/ic_access_time_white_18dp</item>
@@ -60,6 +60,8 @@
<item name="textPanelHeader">@style/AppTheme.Light.Text.PanelHeader</item>
<item name="floatLabel">@style/AppTheme.Light.Text.FloatLabel</item>
<item name="factor_background">@drawable/factor_background_light</item>
<!-- drawables -->
<item name="add">@drawable/ic_add_light</item>
<item name="access_time_18dp">@drawable/ic_access_time_black_18dp</item>
@@ -37,6 +37,7 @@ import com.sap.sailing.domain.base.impl.CompetitorImpl;
import com.sap.sailing.domain.base.impl.CourseAreaImpl;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.MarkImpl;
import com.sap.sailing.domain.base.impl.RaceColumnFactorImpl;
import com.sap.sailing.domain.base.impl.StrippedEventImpl;
import com.sap.sailing.domain.base.racegroup.RaceGroup;
import com.sap.sailing.domain.base.racegroup.SeriesWithRows;
@@ -254,4 +255,8 @@ public class OfflineDataManager extends DataManager {
return null;
}
@Override
public LoaderCallbacks<DataLoaderResult<RaceColumnFactorImpl>> createRaceColumnFactorLoader(LoadClient<RaceColumnFactorImpl> callback) {
return null;
}
}
@@ -28,6 +28,8 @@ import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.DeviceConfigurationIdentifier;
import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
import com.sap.sailing.domain.base.impl.RaceColumnFactorImpl;
import com.sap.sailing.domain.common.impl.RaceColumnConstants;
import com.sap.sailing.domain.common.racelog.RaceLogServletConstants;
import com.sap.sailing.racecommittee.app.AppConstants;
import com.sap.sailing.racecommittee.app.AppPreferences;
@@ -51,6 +53,7 @@ import com.sap.sailing.racecommittee.app.data.parsers.DeviceConfigurationParser;
import com.sap.sailing.racecommittee.app.data.parsers.EventsDataParser;
import com.sap.sailing.racecommittee.app.data.parsers.ManagedRacesDataParser;
import com.sap.sailing.racecommittee.app.data.parsers.MarksDataParser;
import com.sap.sailing.racecommittee.app.data.parsers.RaceColumnsParser;
import com.sap.sailing.racecommittee.app.domain.CoursePosition;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.domain.ManagedRaceIdentifier;
@@ -73,6 +76,7 @@ import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserial
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardGroupBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.NationalityJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.PersonJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.RaceColumnFactorJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.RegattaConfigurationJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.TeamJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.VenueJsonDeserializer;
@@ -85,6 +89,9 @@ import com.sap.sse.common.Util;
public class OnlineDataManager extends DataManager {
private static final String TAG = OnlineDataManager.class.getName();
public static final String LEADERBOARD = "leaderboard";
public static final String RACE_COLUMN = "raceColumn";
protected OnlineDataManager(Context context, DataStore dataStore, SharedDomainFactory domainFactory) {
super(context, dataStore, domainFactory);
}
@@ -110,12 +117,11 @@ public class OnlineDataManager extends DataManager {
@Override
public LoaderCallbacks<DataLoaderResult<Collection<EventBase>>> createEventsLoader(
LoadClient<Collection<EventBase>> callback) {
return new DataLoaderCallbacks<Collection<EventBase>>(callback, new LoaderCreator<Collection<EventBase>>() {
return new DataLoaderCallbacks<>(callback, new LoaderCreator<Collection<EventBase>>() {
@Override
public Loader<DataLoaderResult<Collection<EventBase>>> create(int id, Bundle args) throws Exception {
ExLog.i(context, TAG, String.format("Creating Events-OnlineDataLoader %d", id));
EventBaseJsonDeserializer serializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(
new CourseAreaJsonDeserializer(domainFactory)), new LeaderboardGroupBaseJsonDeserializer());
EventBaseJsonDeserializer serializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(new CourseAreaJsonDeserializer(domainFactory)), new LeaderboardGroupBaseJsonDeserializer());
DataParser<Collection<EventBase>> parser = new EventsDataParser(serializer);
DataHandler<Collection<EventBase>> handler = new EventsDataHandler(OnlineDataManager.this);
@@ -123,8 +129,7 @@ public class OnlineDataManager extends DataManager {
List<Util.Pair<String, Object>> params = new ArrayList<>();
params.add(new Util.Pair<String, Object>("showNonPublic", AppPreferences.on(context).showNonPublic()));
URL url = UrlHelper.generateUrl(preferences.getServerBaseURL(), "/sailingserver/api/v1/events", params);
return new OnlineDataLoader<Collection<EventBase>>(context,
url, parser, handler);
return new OnlineDataLoader<>(context, url, parser, handler);
}
}, getContext());
}
@@ -132,57 +137,53 @@ public class OnlineDataManager extends DataManager {
@Override
public LoaderCallbacks<DataLoaderResult<Collection<CourseArea>>> createCourseAreasLoader(
final Serializable parentEventId, LoadClient<Collection<CourseArea>> callback) {
return new ImmediateDataLoaderCallbacks<Collection<CourseArea>>(context, callback,
new Callable<Collection<CourseArea>>() {
@Override
public Collection<CourseArea> call() throws Exception {
if (dataStore.hasEvent(parentEventId)) {
EventBase event = dataStore.getEvent(parentEventId);
return dataStore.getCourseAreas(event);
} else {
return new ImmediateDataLoaderCallbacks<>(context, callback, new Callable<Collection<CourseArea>>() {
@Override
public Collection<CourseArea> call() throws Exception {
if (dataStore.hasEvent(parentEventId)) {
EventBase event = dataStore.getEvent(parentEventId);
return dataStore.getCourseAreas(event);
} else {
// throw new DataLoadingException(String.format(
// "Unable to load course areas for unknown event %s.", parentEventId));
//TODO: Quickfix for #2889
return null;
}
}
});
//TODO: Quickfix for #2889
return null;
}
}
});
}
@Override
public LoaderCallbacks<DataLoaderResult<Collection<CourseArea>>> createCourseAreasLoader(
final EventBase parentEvent, LoadClient<Collection<CourseArea>> callback) {
// TODO Auto-generated method stub
return new ImmediateDataLoaderCallbacks<Collection<CourseArea>>(context, callback,
new Callable<Collection<CourseArea>>() {
@Override
public Collection<CourseArea> call() throws Exception {
return new ImmediateDataLoaderCallbacks<>(context, callback, new Callable<Collection<CourseArea>>() {
@Override
public Collection<CourseArea> call() throws Exception {
return dataStore.getCourseAreas(parentEvent);
return dataStore.getCourseAreas(parentEvent);
}
});
}
});
}
@Override
public LoaderCallbacks<DataLoaderResult<Collection<ManagedRace>>> createRacesLoader(
final Serializable courseAreaId, LoadClient<Collection<ManagedRace>> callback) {
return new DataLoaderCallbacks<Collection<ManagedRace>>(callback, new LoaderCreator<Collection<ManagedRace>>() {
return new DataLoaderCallbacks<>(callback, new LoaderCreator<Collection<ManagedRace>>() {
@Override
public Loader<DataLoaderResult<Collection<ManagedRace>>> create(int id, Bundle args) throws Exception {
ExLog.i(context, TAG, String.format("Creating races-OnlineDataLoader %d", id));
ConfigurationLoader<RegattaConfiguration> globalConfiguration = PreferencesRegattaConfigurationLoader
.loadFromPreferences(preferences);
ConfigurationLoader<RegattaConfiguration> globalConfiguration = PreferencesRegattaConfigurationLoader.loadFromPreferences(preferences);
DataParser<Collection<ManagedRace>> parser = new ManagedRacesDataParser(preferences.getAuthor(),
globalConfiguration, RaceGroupDeserializer.create(domainFactory,
RegattaConfigurationJsonDeserializer.create()));
DataParser<Collection<ManagedRace>> parser = new ManagedRacesDataParser(preferences
.getAuthor(), globalConfiguration, RaceGroupDeserializer.create(domainFactory, RegattaConfigurationJsonDeserializer.create()));
DataHandler<Collection<ManagedRace>> handler = new ManagedRacesDataHandler(OnlineDataManager.this);
List<Util.Pair<String, Object>> params = new ArrayList<>();
params.add(new Util.Pair<String, Object>(RaceLogServletConstants.PARAM_COURSE_AREA_FILTER, courseAreaId.toString()));
params.add(new Util.Pair<String, Object>(RaceLogServletConstants.PARAMS_CLIENT_UUID, MessageSendingService.uuid));
URL url = UrlHelper.generateUrl(preferences.getServerBaseURL(), "/sailingserver/rc/racegroups", params);
return new OnlineDataLoader<Collection<ManagedRace>>(context, url, parser, handler);
return new OnlineDataLoader<>(context, url, parser, handler);
}
}, getContext());
}
@@ -190,7 +191,7 @@ public class OnlineDataManager extends DataManager {
@Override
public LoaderCallbacks<DataLoaderResult<Collection<Mark>>> createMarksLoader(final ManagedRace managedRace,
LoadClient<Collection<Mark>> callback) {
return new DataLoaderCallbacks<Collection<Mark>>(callback, new LoaderCreator<Collection<Mark>>() {
return new DataLoaderCallbacks<>(callback, new LoaderCreator<Collection<Mark>>() {
@Override
public Loader<DataLoaderResult<Collection<Mark>>> create(int id, Bundle args) throws Exception {
ExLog.i(context, TAG, String.format("Creating marks-OnlineDataLoader %d", id));
@@ -209,7 +210,7 @@ public class OnlineDataManager extends DataManager {
params.add(new Util.Pair<String, Object>(RaceLogServletConstants.PARAMS_RACE_COLUMN_NAME, raceColumnName));
params.add(new Util.Pair<String, Object>(RaceLogServletConstants.PARAMS_RACE_FLEET_NAME, fleetName));
URL url = UrlHelper.generateUrl(preferences.getServerBaseURL(), "/sailingserver/rc/marks", params);
return new OnlineDataLoader<Collection<Mark>>(context, url, parser, handler);
return new OnlineDataLoader<>(context, url, parser, handler);
}
}, getContext());
}
@@ -217,13 +218,11 @@ public class OnlineDataManager extends DataManager {
@Override
public LoaderCallbacks<DataLoaderResult<CourseBase>> createCourseLoader(final ManagedRace managedRace,
LoadClient<CourseBase> callback) {
return new DataLoaderCallbacks<CourseBase>(callback, new LoaderCreator<CourseBase>() {
return new DataLoaderCallbacks<>(callback, new LoaderCreator<CourseBase>() {
@Override
public Loader<DataLoaderResult<CourseBase>> create(int id, Bundle args) throws Exception {
ExLog.i(context, TAG, String.format("Creating Course-OnlineDataLoader %d", id));
JsonDeserializer<CourseBase> courseBaseDeserializer = new CourseBaseDeserializer(
new WaypointDeserializer(new ControlPointDeserializer(new MarkDeserializer(domainFactory),
new GateDeserializer(domainFactory, new MarkDeserializer(domainFactory)))));
JsonDeserializer<CourseBase> courseBaseDeserializer = new CourseBaseDeserializer(new WaypointDeserializer(new ControlPointDeserializer(new MarkDeserializer(domainFactory), new GateDeserializer(domainFactory, new MarkDeserializer(domainFactory)))));
DataParser<CourseBase> parser = new CourseBaseParser(courseBaseDeserializer);
DataHandler<CourseBase> handler = new CourseBaseHandler(OnlineDataManager.this, managedRace);
@@ -239,7 +238,7 @@ public class OnlineDataManager extends DataManager {
params.add(new Util.Pair<String, Object>(RaceLogServletConstants.PARAMS_RACE_FLEET_NAME, fleetName));
URL url = UrlHelper.generateUrl(preferences.getServerBaseURL(), "/sailingserver/rc/currentcourse", params);
return new OnlineDataLoader<CourseBase>(context, url, parser, handler);
return new OnlineDataLoader<>(context, url, parser, handler);
}
}, getContext());
}
@@ -247,17 +246,13 @@ public class OnlineDataManager extends DataManager {
@Override
public LoaderCallbacks<DataLoaderResult<Collection<Competitor>>> createCompetitorsLoader(
final ManagedRace managedRace, LoadClient<Collection<Competitor>> callback) {
return new DataLoaderCallbacks<Collection<Competitor>>(callback, new LoaderCreator<Collection<Competitor>>() {
return new DataLoaderCallbacks<>(callback, new LoaderCreator<Collection<Competitor>>() {
@Override
public Loader<DataLoaderResult<Collection<Competitor>>> create(int id, Bundle args) throws Exception {
ExLog.i(context, TAG, String.format("Creating Competitor-OnlineDataLoader %d", id));
JsonDeserializer<Competitor> competitorDeserializer = new CompetitorJsonDeserializer(
domainFactory.getCompetitorStore(), new TeamJsonDeserializer(new PersonJsonDeserializer(
new NationalityJsonDeserializer(domainFactory))), new BoatJsonDeserializer(
new BoatClassJsonDeserializer(domainFactory)));
JsonDeserializer<Competitor> competitorDeserializer = new CompetitorJsonDeserializer(domainFactory.getCompetitorStore(), new TeamJsonDeserializer(new PersonJsonDeserializer(new NationalityJsonDeserializer(domainFactory))), new BoatJsonDeserializer(new BoatClassJsonDeserializer(domainFactory)));
DataParser<Collection<Competitor>> parser = new CompetitorsDataParser(competitorDeserializer);
DataHandler<Collection<Competitor>> handler = new CompetitorsDataHandler(OnlineDataManager.this,
managedRace);
DataHandler<Collection<Competitor>> handler = new CompetitorsDataHandler(OnlineDataManager.this, managedRace);
ManagedRaceIdentifier identifier = managedRace.getIdentifier();
@@ -270,7 +265,7 @@ public class OnlineDataManager extends DataManager {
params.add(new Util.Pair<String, Object>(RaceLogServletConstants.PARAMS_RACE_COLUMN_NAME, raceColumnName));
params.add(new Util.Pair<String, Object>(RaceLogServletConstants.PARAMS_RACE_FLEET_NAME, fleetName));
URL url = UrlHelper.generateUrl(preferences.getServerBaseURL(), "/sailingserver/rc/competitors", params);
return new OnlineDataLoader<Collection<Competitor>>(context, url, parser, handler);
return new OnlineDataLoader<>(context, url, parser, handler);
}
}, getContext());
}
@@ -278,19 +273,17 @@ public class OnlineDataManager extends DataManager {
@Override
public LoaderCallbacks<DataLoaderResult<DeviceConfiguration>> createConfigurationLoader(
final DeviceConfigurationIdentifier identifier, LoadClient<DeviceConfiguration> callback) {
return new DataLoaderCallbacks<DeviceConfiguration>(callback, new LoaderCreator<DeviceConfiguration>() {
return new DataLoaderCallbacks<>(callback, new LoaderCreator<DeviceConfiguration>() {
@Override
public Loader<DataLoaderResult<DeviceConfiguration>> create(int id, Bundle args) throws Exception {
ExLog.i(context, TAG, String.format("Creating Configuration-OnlineDataLoader %d", id));
DataHandler<DeviceConfiguration> handler = new NullDataHandler<DeviceConfiguration>();
DataParser<DeviceConfiguration> parser = new DeviceConfigurationParser(
DeviceConfigurationJsonDeserializer.create());
DataParser<DeviceConfiguration> parser = new DeviceConfigurationParser(DeviceConfigurationJsonDeserializer.create());
String encodedIdentifier = identifier.getClientIdentifier();
List<Util.Pair<String, Object>> params = new ArrayList<>();
params.add(new Util.Pair<String, Object>("client", encodedIdentifier));
URL url = UrlHelper.generateUrl(preferences.getServerBaseURL(), "/sailingserver/rc/configuration", params);
return new OnlineDataLoader<DeviceConfiguration>(context,
url, parser, handler);
return new OnlineDataLoader<>(context, url, parser, handler);
}
}, getContext());
}
@@ -326,5 +319,25 @@ public class OnlineDataManager extends DataManager {
return url;
}
@Override
public LoaderCallbacks<DataLoaderResult<RaceColumnFactorImpl>> createRaceColumnFactorLoader(LoadClient<RaceColumnFactorImpl> callback) {
return new DataLoaderCallbacks<>(callback, new LoaderCreator<RaceColumnFactorImpl>() {
@Override
public Loader<DataLoaderResult<RaceColumnFactorImpl>> create(int id, Bundle args) throws Exception {
if (args == null || args.getString(LEADERBOARD) == null) {
throw new IllegalArgumentException("You need an leaderboard as bundle arg (" + LEADERBOARD + ").");
}
ExLog.i(context, TAG, String.format("Creating RaceColumnFactorLoader %d", id));
DataHandler<RaceColumnFactorImpl> handler = new NullDataHandler<>();
DataParser<RaceColumnFactorImpl> parser = new RaceColumnsParser(new RaceColumnFactorJsonDeserializer());
List<Util.Pair<String, Object>> params = new ArrayList<>();
if (args.getString(RACE_COLUMN) != null) {
params.add(new Util.Pair<String, Object>(RaceColumnConstants.RACE_COLUMNS, args.getString(RACE_COLUMN)));
}
URL url = UrlHelper.generateUrl(preferences.getServerBaseURL(), "/sailingserver/api/v1/leaderboards/" + args.getString(LEADERBOARD) + "/racecolumnfactors", params);
return new OnlineDataLoader<>(context, url, parser, handler);
}
}, getContext());
}
}
@@ -5,6 +5,7 @@ import java.util.Collection;
import android.app.LoaderManager;
import android.app.LoaderManager.LoaderCallbacks;
import android.support.annotation.Nullable;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseArea;
@@ -17,6 +18,7 @@ import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
import com.sap.sailing.racecommittee.app.data.loaders.DataLoaderResult;
import com.sap.sailing.racecommittee.app.domain.CoursePosition;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.domain.base.impl.RaceColumnFactorImpl;
import com.sap.sailing.racecommittee.app.ui.fragments.lists.PositionListFragment;
/**
@@ -42,7 +44,7 @@ public interface ReadonlyDataManager {
*
* @return the {@link DataStore}.
*/
public DataStore getDataStore();
DataStore getDataStore();
/**
* Creates a new {@link LoaderCallbacks} object for loading {@link EventBase}s.
@@ -53,8 +55,7 @@ public interface ReadonlyDataManager {
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
*/
public LoaderCallbacks<DataLoaderResult<Collection<EventBase>>> createEventsLoader(
LoadClient<Collection<EventBase>> callback);
LoaderCallbacks<DataLoaderResult<Collection<EventBase>>> createEventsLoader(LoadClient<Collection<EventBase>> callback);
/**
* Creates a new {@link LoaderCallbacks} object for loading {@link CourseArea}s.
@@ -65,24 +66,20 @@ public interface ReadonlyDataManager {
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
*/
public LoaderCallbacks<DataLoaderResult<Collection<CourseArea>>> createCourseAreasLoader(
Serializable parentEventId, LoadClient<Collection<CourseArea>> callback);
LoaderCallbacks<DataLoaderResult<Collection<CourseArea>>> createCourseAreasLoader(Serializable parentEventId,
LoadClient<Collection<CourseArea>> callback);
LoaderCallbacks<DataLoaderResult<Collection<CourseArea>>> createCourseAreasLoader(EventBase parentEvent,
LoadClient<Collection<CourseArea>> callback);
public LoaderCallbacks<DataLoaderResult<Collection<CourseArea>>> createCourseAreasLoader(
EventBase parentEvent, LoadClient<Collection<CourseArea>> callback);
/**
* Creates a new {@link LoaderCallbacks} object for loading racing referee positions.
*
* @param callback
* {@link LoadClient} implementing your data handling code.
* @return {@link LoaderCallbacks} to be used in
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
*/
public LoaderCallbacks<DataLoaderResult<Collection<CoursePosition>>> createPositionLoader(
PositionListFragment positionListFragment);
LoaderCallbacks<DataLoaderResult<Collection<CoursePosition>>> createPositionLoader(PositionListFragment positionListFragment);
/**
* Creates a new {@link LoaderCallbacks} object for loading {@link ManagedRace}s of a specific {@link CourseArea}.
@@ -95,8 +92,8 @@ public interface ReadonlyDataManager {
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
*/
public LoaderCallbacks<DataLoaderResult<Collection<ManagedRace>>> createRacesLoader(Serializable courseAreaId,
LoadClient<Collection<ManagedRace>> callback);
LoaderCallbacks<DataLoaderResult<Collection<ManagedRace>>> createRacesLoader(Serializable courseAreaId,
LoadClient<Collection<ManagedRace>> callback);
/**
* Creates a new {@link LoaderCallbacks} object for loading a race's {@link Mark}s.
@@ -109,8 +106,7 @@ public interface ReadonlyDataManager {
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
*/
public LoaderCallbacks<DataLoaderResult<Collection<Mark>>> createMarksLoader(ManagedRace managedRace,
LoadClient<Collection<Mark>> callback);
LoaderCallbacks<DataLoaderResult<Collection<Mark>>> createMarksLoader(ManagedRace managedRace, LoadClient<Collection<Mark>> callback);
/**
* Creates a new {@link LoaderCallbacks} object for loading a race's {@link CourseBase}.
@@ -123,8 +119,7 @@ public interface ReadonlyDataManager {
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
*/
public LoaderCallbacks<DataLoaderResult<CourseBase>> createCourseLoader(ManagedRace managedRace,
LoadClient<CourseBase> callback);
LoaderCallbacks<DataLoaderResult<CourseBase>> createCourseLoader(ManagedRace managedRace, LoadClient<CourseBase> callback);
/**
* Creates a new {@link LoaderCallbacks} object for loading {@link Competitor}s.
@@ -135,8 +130,8 @@ public interface ReadonlyDataManager {
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
*/
public LoaderCallbacks<DataLoaderResult<Collection<Competitor>>> createCompetitorsLoader(ManagedRace managedRace,
LoadClient<Collection<Competitor>> callback);
LoaderCallbacks<DataLoaderResult<Collection<Competitor>>> createCompetitorsLoader(ManagedRace managedRace,
LoadClient<Collection<Competitor>> callback);
/**
* Creates a new {@link LoaderCallbacks} object for loading a client's configuration.
@@ -147,8 +142,22 @@ public interface ReadonlyDataManager {
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
*/
public LoaderCallbacks<DataLoaderResult<DeviceConfiguration>> createConfigurationLoader(DeviceConfigurationIdentifier identifier,
LoadClient<DeviceConfiguration> callback);
LoaderCallbacks<DataLoaderResult<DeviceConfiguration>> createConfigurationLoader(DeviceConfigurationIdentifier identifier,
LoadClient<DeviceConfiguration> callback);
public String getMapUrl(String baseUrl, ManagedRace race, String eventId, boolean showWindCharts, boolean showStreamlets, boolean showSimulation, boolean showMapControls);
String getMapUrl(String baseUrl, ManagedRace race, String eventId, boolean showWindCharts, boolean showStreamlets, boolean showSimulation,
boolean showMapControls);
/**
* Create a new {@link LoaderCallbacks} object for loading the race columns (e.g. factors)
*
* @param leaderboard
* @param race_column
* @param callback
*
* @return {@link LoaderCallbacks} to be used in
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
*/
LoaderCallbacks<DataLoaderResult<RaceColumnFactorImpl>> createRaceColumnFactorLoader(LoadClient<RaceColumnFactorImpl> callback);
}
@@ -0,0 +1,26 @@
package com.sap.sailing.racecommittee.app.data.parsers;
import java.io.Reader;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import com.sap.sailing.domain.base.impl.RaceColumnFactorImpl;
import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
import com.sap.sailing.server.gateway.deserialization.impl.RaceColumnFactorJsonDeserializer;
public class RaceColumnsParser implements DataParser<RaceColumnFactorImpl> {
private RaceColumnFactorJsonDeserializer deserializer;
public RaceColumnsParser(RaceColumnFactorJsonDeserializer deserializer) {
this.deserializer = deserializer;
}
@Override
public RaceColumnFactorImpl parse(Reader reader) throws Exception {
Object parsedResult = JSONValue.parseWithException(reader);
JSONObject jsonObject = Helpers.toJSONObjectSafe(parsedResult);
return deserializer.deserialize(jsonObject);
}
}
@@ -104,4 +104,14 @@ public interface ManagedRace extends ManagedRaceIdentifier, Named, WithID {
* @return result object
*/
Result setFinishingTime(TimePoint finishingTime);
/**
* @return factor
*/
Double getExplicitFactor();
/**
* @param factor
*/
void setExplicitFactor(Double factor);
}
@@ -31,6 +31,7 @@ public class ManagedRaceImpl implements ManagedRace {
private List<MapMarker> mapMarkers;
private CourseBase courseOnServer;
private ManagedRaceCalculator calculator;
private Double factor;
public ManagedRaceImpl(ManagedRaceIdentifier identifier, RaceState state) {
this.state = state;
@@ -177,6 +178,16 @@ public class ManagedRaceImpl implements ManagedRace {
return result;
}
@Override
public Double getExplicitFactor() {
return factor;
}
@Override
public void setExplicitFactor(Double factor) {
this.factor = factor;
}
@Override
public String toString() {
return "ManagedRaceImpl [identifier=" + identifier + "]";
@@ -3,10 +3,42 @@ package com.sap.sailing.racecommittee.app.ui.activities;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Random;
import android.annotation.TargetApi;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AlertDialog;
import android.support.v7.internal.widget.TintImageView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.util.AppUtils;
import com.sap.sailing.android.shared.util.BitmapHelper;
@@ -16,12 +48,14 @@ import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderResult;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.impl.RaceColumnFactorImpl;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.racecommittee.app.AppConstants;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.data.DataManager;
import com.sap.sailing.racecommittee.app.data.DataStore;
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
import com.sap.sailing.racecommittee.app.data.ReadonlyDataManager;
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
@@ -47,42 +81,13 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import android.annotation.TargetApi;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AlertDialog;
import android.support.v7.internal.widget.TintImageView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
public class RacingActivity extends SessionActivity implements RaceListCallbacks {
private static final String TAG = RacingActivity.class.getName();
private static final String WIND = "wind";
private static final String RACE = "race";
private static final int RacesLoaderId = 2;
private ProgressBar mProgressSpinner;
private IntentReceiver mReceiver;
@@ -607,6 +612,39 @@ public class RacingActivity extends SessionActivity implements RaceListCallbacks
transaction.commit();
}
private void loadRaceColumnFactors(Collection<ManagedRace> data) {
HashSet<String> leaderboards = new HashSet<>();
for (ManagedRace race : data) {
if (!leaderboards.contains(race.getRaceGroup().getName())) {
leaderboards.add(race.getRaceGroup().getName());
}
}
Random random = new Random();
for (String leaderboard : leaderboards) {
Bundle args = new Bundle();
args.putString(OnlineDataManager.LEADERBOARD, leaderboard);
getLoaderManager().initLoader(random.nextInt(), args, dataManager.createRaceColumnFactorLoader(new RaceColumnFactorLoadClient()));
}
}
private class RaceColumnFactorLoadClient implements LoadClient<RaceColumnFactorImpl> {
@Override
public void onLoadFailed(Exception reason) {
ExLog.e(RacingActivity.this, TAG, "Error loading race columns factors: " + reason.getMessage());
}
@Override
public void onLoadSucceeded(RaceColumnFactorImpl data, boolean isCached) {
for (ManagedRace race : dataManager.getDataStore().getRaces()) {
if (data.getRaceColumns().containsKey(race.getRaceName())) {
RaceColumnFactorImpl.RaceColumn column = data.getRaceColumns().get(race.getRaceName());
race.setExplicitFactor(column.getExplicitFactor());
}
}
}
}
private class RaceLoadClient implements LoadClient<Collection<ManagedRace>> {
private CourseArea courseArea;
@@ -647,6 +685,8 @@ public class RacingActivity extends SessionActivity implements RaceListCallbacks
registerOnService(data);
mRaceList.setupOn(data);
loadRaceColumnFactors(data);
Toast.makeText(RacingActivity.this, String.format(getString(R.string.racing_load_success), data.size()), Toast.LENGTH_SHORT).show();
}
@@ -1,5 +1,6 @@
package com.sap.sailing.racecommittee.app.ui.adapters.racelist;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.List;
@@ -71,7 +72,9 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
private RaceListDataType mSelectedRace;
private ViewGroup panel_left;
private ViewGroup panel_right;
private TextView explicit_factor;
private int flag_size;
private DecimalFormat factor_format;
public ManagedRaceListAdapter(Context context, List<RaceListDataType> viewItems) {
super(context, 0);
@@ -82,6 +85,7 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
mResources = getContext().getResources();
dateFormat = new SimpleDateFormat("kk:mm", getContext().getResources().getConfiguration().locale);
flag_size = getContext().getResources().getInteger(R.integer.flag_size);
factor_format = new DecimalFormat(context.getString(R.string.race_factor_format));
}
@Override
@@ -220,6 +224,12 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
}
}
Double factor = race.getRace().getExplicitFactor();
if (factor != null) {
explicit_factor.setText(factor_format.format(factor));
explicit_factor.setVisibility(View.VISIBLE);
}
updateFlag(race.getRace(), now);
}
return convertView;
@@ -279,6 +289,7 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
fleet_series = ViewHelper.get(layout, R.id.fleet_series);
has_dependent_races = ViewHelper.get(layout, R.id.has_dependent_races);
depends_on = ViewHelper.get(layout, R.id.depends_on);
explicit_factor = ViewHelper.get(layout, R.id.explicit_factor);
}
private void resetValues(View layout) {
@@ -320,6 +331,9 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
depends_on.setTextColor(ThemeHelper.getColor(getContext(), R.attr.sap_light_gray));
depends_on.setVisibility(View.GONE);
}
if (explicit_factor != null) {
explicit_factor.setVisibility(View.GONE);
}
setMarker(0);
}
}
@@ -1,5 +1,7 @@
package com.sap.sailing.racecommittee.app.ui.fragments.panels;
import java.text.DecimalFormat;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -53,6 +55,8 @@ public class SetupPanelFragment extends BasePanelFragment {
private PanelButton mButtonCourse;
private PanelButton mButtonWind;
private DecimalFormat mFactorFormat;
public SetupPanelFragment() {
mReceiver = new IntentReceiver();
}
@@ -76,6 +80,8 @@ public class SetupPanelFragment extends BasePanelFragment {
layout = inflater.inflate(R.layout.race_panel_setup, container, false);
}
mFactorFormat = new DecimalFormat(container.getContext().getString(R.string.race_factor_format));
mStateListener = new RaceStateChangedListener();
mProcedureListener = new RaceProcedureChangedListener();
@@ -169,11 +175,6 @@ public class SetupPanelFragment extends BasePanelFragment {
mButtonRaceGroup.setVisibility(View.GONE);
}
if (mButtonFactor != null) {
mButtonFactor.setVisibility(preferences.isRaceFactorChangeAllow() ? View.VISIBLE : View.GONE);
mButtonFactor.setPanelText("");
}
if (getRaceState().getRacingProcedure() instanceof RRS26RacingProcedure) {
if (mButtonMode != null) {
RRS26RacingProcedure typedProcedure = getRaceState().getTypedRacingProcedure();
@@ -200,6 +201,11 @@ public class SetupPanelFragment extends BasePanelFragment {
}
}
if (mButtonFactor != null) {
mButtonFactor.setVisibility(preferences.isRaceFactorChangeAllow() ? View.VISIBLE : View.GONE);
mButtonFactor.setPanelText(mFactorFormat.format(getRace().getExplicitFactor()));
}
if (mButtonCourse != null) {
mButtonCourse.setPanelText(getCourseName());
}