Merge remote-tracking branch 'origin/master' into bug4134_2
@@ -18,7 +18,7 @@ BACKUP_DIRECTORIES="/etc /var/log/mongodb"
|
||||
PREFIX="database"
|
||||
|
||||
# Directory for temporary files
|
||||
TARGET_DIR=/var/lib/mysql/backup
|
||||
TARGET_DIR=/var/lib/mongodb/backup
|
||||
|
||||
# Configuration for MongoDB backup
|
||||
MONGO_PORTS="10202 10201"
|
||||
@@ -26,7 +26,7 @@ MONGO_INSTALLATION=/opt/mongodb-linux-x86_64-2.6.7
|
||||
MONGO_CMD=$MONGO_INSTALLATION/bin/mongo
|
||||
MONGOEXPORT_CMD=$MONGO_INSTALLATION/bin/mongoexport
|
||||
MONGODB_COLLECTION_WIND="WIND_TRACKS"
|
||||
MONGODB_COLLECTION_LOCAL="local"
|
||||
MONGODB_EXCLUDE_DBS="local 29erWorlds2016 29erWorlds2016-replica 49er-n17-euros2017 49er-n17-euros2017-replica 49erEuros2015 49erEuros2016 49erEuros2016-replica 49erJWC2015 49erWorlds_2016 49erWorlds_2016-replica 49erWorlds_2016-replica2 49erWorlds_2016-replica3 49erworlds2015 505-2017 505-2017-replica 505-2017-replica-1 505-2017-replica-2 505Worlds2016 505Worlds2016-replica 505_WORLDS_2015 6mworlds2017 6mworlds2017-replica 8MWORLDS2017 8MWORLDS2017-replica AustrianLeague2015 Bodenseewoche_2015 Championsleague_2015 Championsleague_2015-Replica DANISHLEAGUE2017 DANISHLEAGUE2017-replica DUTCH_LEAGUE_2017 DUTCH_LEAGUE_2017-replica DanishSailingLeague_2015 DutchSailingLeague_2015 FinnishSailingLeague_2015 GermanSailingLeague_2015 GermanSailingLeague_2015-Replica HANSESAIL2017 IDMFINN2017 KW2015 KW2015-replica KW2015-replica2 KW2017 KW2017-replica Norwegianleague_2015 POLISHLEAGUE2017 RosAtomCup_2015 SAPOPTICUP2015 SCL2017 SCL2017-replica SGCN_Smartphone_2016 SGCN_Smartphone_2016-replica SPEEDSAILING2016 SWC2016-Melbourne SWC2016-Melbourne-replica SWC2016-Qingdao SWC2016-Qingdao-replica SWC2017-Aarhus SWC2017-HYERES SWC2017-HYERES-replica SWC2017-Miami SWC2017-Miami-replica SWC2017-SANTANDER SWC2017-SANTANDER-replica SWEDISHLEAGUE2017 SWEDISHLEAGUE2017-replica TW2015 TW2015-REPLICA TW2015-test-replica TW2017 TW2017-replica WORLDCUPSYLT2015 YES2015 YES2015-REPLICA YES2015-REPLICA2 allsvenskan2015 austrianleague2016 austrianleague2017 bartsbash2015 bundesliga2-2017 bundesliga2-2017-replica bundesliga2016 bundesliga2016-replica bundesliga2016_2 bundesliga2017 bundesliga2017-replica crw2016 crw2016-replica danishleague2016 danishleague2016-replica dsl-pokal2017 dutchleague2016 dutchleague2016-replica ess2015 ess2016 ess2017 ess2017_foiling_test ess40-2015-replica2 finnishleague2016 finnishleague2017 forumvostok2016 frenchleague2017 germanleague2016-replica idmstar2016 isafwc2014 kielerwoche2016 kielerwoche2016-replica kiellauf2017 northsearegatta2017 northstreamrace2017 norwegianleague2016 norwegianleague2016-replica norwegianleague2017 norwegianleague2017-replica rsc2016 scl2016 scl2016-replica swedishleague2016 swedishleague2016-replica tw2016 tw2016-replica usoda2016 wmrt2016"
|
||||
|
||||
# Configuration for MySQL
|
||||
MYSQL_DATABASES="bugs mysql"
|
||||
@@ -40,7 +40,8 @@ BACKUP_SERVER="backup@172.31.25.136"
|
||||
BACKUP_DATE=`date +%s`
|
||||
|
||||
# Aliases
|
||||
BUP_CMD="/opt/bup/bup"
|
||||
BUP_DIR=/var/lib/mongodb/backup/bup
|
||||
BUP_CMD="/opt/bup/bup -d $BUP_DIR"
|
||||
BUP_ADDITIONAL="-r $BACKUP_SERVER:/home/backup/$PREFIX"
|
||||
BUP_IGNORES='--exclude-rx=/war/$'
|
||||
BUP_CMD_INDEX="$BUP_CMD index $BUP_IGNORES"
|
||||
@@ -92,7 +93,14 @@ show collections" | $MONGO_CMD --port $MONGO_PORT | tail -n +4 | grep -v "^syste
|
||||
else
|
||||
DB_DIR=$TARGET_DIR/mongodb-$MONGO_PORT$WIND_SUFFIX
|
||||
fi
|
||||
if [ "$i" != "$MONGODB_COLLECTION_LOCAL" -a \( "$i" != "$MONGODB_COLLECTION_WIND" -o "$PARAM" = "weekly" \) ]; then
|
||||
exclude=0
|
||||
for exclude_collection in $MONGODB_EXCLUDE_DBS; do
|
||||
if [ "$i" = "$exclude_collection" ]; then
|
||||
echo "Excluding $i from backup based on exclude list"
|
||||
exclude=1
|
||||
fi
|
||||
done
|
||||
if [ "$exclude" = "0" -a \( "$j" != "$MONGODB_COLLECTION_WIND" -o "$PARAM" = "weekly" \) ]; then
|
||||
echo " Backing up collection $j in MongoDB $i running on port $MONGO_PORT"
|
||||
echo "$MONGOEXPORT_CMD --port $MONGO_PORT -d $i -c $j > $DB_DIR/$j.json"
|
||||
mkdir -p $DB_DIR
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -184,7 +185,16 @@ public abstract class OnlineTracTracBasedTest extends AbstractTracTracLiveTest i
|
||||
getSemaphor().wait();
|
||||
}
|
||||
}
|
||||
logger.info("Stored data has been loaded for " + race.getName());
|
||||
logger.info("Stored data has been loaded for " + race.getName()+". Waiting for receivers to process it...");
|
||||
final CountDownLatch latch = new CountDownLatch(receivers.size());
|
||||
for (Receiver receiver : receivers) {
|
||||
receiver.callBackWhenLoadingQueueIsDone(r->{
|
||||
latch.countDown();
|
||||
logger.info(receiver+" done loading");
|
||||
});
|
||||
}
|
||||
latch.await();
|
||||
logger.info("Stored data has been processed by receivers");
|
||||
for (Receiver receiver : receivers) {
|
||||
logger.info("Stopping receiver "+receiver);
|
||||
receiver.stopAfterNotReceivingEventsForSomeTime(/* timeoutInMilliseconds */ 5000l);
|
||||
|
||||
@@ -2684,11 +2684,11 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
|
||||
private List<Maneuver> computeManeuvers(Competitor competitor, ManeuverDetector maneuverDetector)
|
||||
throws NoWindException {
|
||||
logger.finest("computeManeuvers(" + competitor.getName() + ") called in tracked race " + this);
|
||||
logger.info("computeManeuvers(" + competitor.getName() + ") called in tracked race " + this);
|
||||
long startedAt = System.currentTimeMillis();
|
||||
// compute the maneuvers for competitor
|
||||
List<Maneuver> result = maneuverDetector.detectManeuvers();
|
||||
logger.finest("computeManeuvers(" + competitor.getName() + ") called in tracked race " + this + " took "
|
||||
logger.info("computeManeuvers(" + competitor.getName() + ") called in tracked race " + this + " took "
|
||||
+ (System.currentTimeMillis() - startedAt) + "ms");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div id="mainContent">
|
||||
<h4 class="articleHeadline">What's New - SAP Sailing Race Manager</h4>
|
||||
<div class="innerContent">
|
||||
<h5 class="articleSubheadline">July 2016</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Finishing races in the TimePanel show the race duration of the "first ship home."</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">June 2016</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>The start time editing screen has now a "Sync to minute" button, which replaces
|
||||
the both buttons beside the countdown. This button sets the countdown to the nearest
|
||||
minute and after "Set time" the new start time will be sent to the server.</li>
|
||||
<li>The "Set Time" button in the start time editing screen remains disabled now until
|
||||
the user actually makes a change. This also helps to identify that "Set Time"
|
||||
needs to be tapped in order to transmit a change carried out using the
|
||||
"Sync to minute" button.</li>
|
||||
<li>Changing the server, signing out, changing hidden event visibility,
|
||||
and changing the regatta now properly ensures that the
|
||||
content is refreshed based on the new settings.</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">May 2016</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>A bug related to entering the passing instructions for a waypoint in the "by-marks"
|
||||
course designer has been fixed. At the same time, for now the passing instructions
|
||||
"Offset" and "Fixed Bearing" are no longer offered until the application really offers
|
||||
support for them, particularly during mark passing calculation.</li>
|
||||
<li>Swiping the start time button to the left to reach the other buttons for entering
|
||||
the racing procedure, start mode flag, etc. now works reliably, also in case
|
||||
of multi-touch which may have made the app crash before.</li>
|
||||
<li>Regatta-specific preferences now properly take precedence over the device configuration.
|
||||
They are updated from the server when the regatta content is refreshed.</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">April 2016</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Whether or not result entry during or after the finishing phase is offered is now
|
||||
a preference under "REGATTA CONFIGURATION (DEFAULT)." The device configuration managed
|
||||
on the server can remotely manage this configuration setting. With this, it is possible
|
||||
to configure up-front whether a race officer is offered the possibility to manage
|
||||
results directly from the Race Manager app. This should <em>not</em> be used if an
|
||||
external, official regatta management system is being used to capture and manage
|
||||
the official scores.</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">March 2016</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Added sign in/sign out into the app. The user has to be create in the backend, with leaderboard
|
||||
permission. Without the permission, the user can't send data to the server.</li>
|
||||
<li>We changed the QR Code, so it includes the user's access token. There is also a possibility to manual login into
|
||||
the app, if no QR Code is available. <b>The app doesn't store username and password.</b></li>
|
||||
<li>The behavior of the red share icon has also slightly changed. If it is red and tapped, it will call the server
|
||||
to check, if the users access token is still valid. If not the server response with a 401 error code and the user
|
||||
has to enter his credentials.</li>
|
||||
<li>You can force a user sign out within the overflow menu, if you need other user credentials.</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">February 2016</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Added responsive design. You can now use the app on every tablet as well as on <b>mobile phones</b>.</li>
|
||||
<li>We returned the group races switch to ESS races. It's located in the left panel bar (or top on phones).</li>
|
||||
<li>The behavior of ESS course designer is compact in two lists. The marks and rounding can be easily changed by tapping on it.</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">August 2015</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Fixes for Android Lollipop were deployed. They solve font size and other display issues.
|
||||
</li>
|
||||
<li>The true wind direction provided during wind entry in the app is now interpreted to be a
|
||||
direction based on magnetic north, not true north. This is common practice as wind readings
|
||||
are typically produced on a start vessel based on a magnetic compass device.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">July 2015</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Added support for dependent start times. Races can set their start time relative
|
||||
to another race's start time. Caveat: Currently, when aborting races on which other
|
||||
races depend, requires either aborting the dependent races before or setting an
|
||||
absolute start time on the dependent races.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">June 2015</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>Major overhaul of the entire race committee app. The app has a completely new user interface
|
||||
with a light and a dark theme. The functionality generally remained unchanged.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">July 2014</h5>
|
||||
<ul class="bulletList">
|
||||
<li>The race list is now ordered by fleets. This means we display the same order of our backend system in the RCApp.
|
||||
Now the race officials can easily use the order which is displayed and do not have to care about the fleet color order.</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">March 2014</h5>
|
||||
<ul class="bulletList">
|
||||
<li>Moved away from using a label to create a course and introduced a big button that
|
||||
eases the input of courses.</li>
|
||||
|
||||
<li>Added a new countdown button for ESS and RRS26 start configurations. Using this
|
||||
button one can easily set the start time of a race to exactly the time the countdown starts.</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">January 2014</h5>
|
||||
<ul class="bulletList">
|
||||
<li>Server-based device configuration</li>
|
||||
|
||||
<li>Device initialization with QR codes</li>
|
||||
|
||||
<li>Automatic upgrades and downgrades to match server software version</li>
|
||||
|
||||
<li>Multiple devices can work on the same race (e.g., start vessel, finishing vessel, shore control)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -108,7 +108,7 @@ public class TestWindEstimationFromManeuversOnAFew505Races extends OnlineTracTra
|
||||
CreateModelException, NotEnoughDataHasBeenAddedException {
|
||||
setUp("event_20110609_KielerWoch-505_race_4");
|
||||
Wind average = getManeuverBasedAverageWind();
|
||||
assertEquals(270, average.getFrom().getDegrees(), 9.0);
|
||||
assertEquals(265, average.getFrom().getDegrees(), 9.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -156,7 +156,7 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
this.weightedAverageMiddleCOGForManeuverType = new HashMap<>();
|
||||
long start = System.currentTimeMillis();
|
||||
Triple<Set<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>>, List<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>>, List<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>>> clusterStructure = analyzeRace(waitForLatest);
|
||||
logger.fine("Computed virtual wind fixes from maneuvers for race " + trackedRace.getRace().getName() + " in "
|
||||
logger.info("Computed virtual wind fixes from maneuvers for race " + trackedRace.getRace().getName() + " in "
|
||||
+ (System.currentTimeMillis() - start) + "ms");
|
||||
clusters = clusterStructure.getA();
|
||||
tackClusters = clusterStructure.getB();
|
||||
@@ -387,7 +387,9 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
*/
|
||||
private Triple<Set<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>>, List<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>>, List<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>>> analyzeRace(
|
||||
boolean waitForLatest) throws NotEnoughDataHasBeenAddedException {
|
||||
logger.info("Starting wind estimation");
|
||||
final Map<Maneuver, CompetitorAndBoat> maneuvers = getAllManeuvers(waitForLatest);
|
||||
logger.info("Maneuvers fixed have been queried");
|
||||
// cluster into eight clusters by middle COG first, then aggregate tack likelihoods for each, and jibe
|
||||
// likelihoods for opposite cluster
|
||||
final int numberOfClusters = 16;
|
||||
@@ -403,7 +405,7 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
IntStream.range(0, numberOfClusters / 2).mapToObj(
|
||||
(i) -> new Pair<>(new DegreeBearingImpl(((double) i) * 360. / (double) numberOfClusters
|
||||
/ 2), -45.))));
|
||||
logger.fine("K-Means maneuver clusterer for wind estimation took " + clusterer.getNumberOfIterations()
|
||||
logger.info("K-Means maneuver clusterer for wind estimation took " + clusterer.getNumberOfIterations()
|
||||
+ " iterations");
|
||||
final Set<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>> clusters = clusterer
|
||||
.getClusters();
|
||||
|
||||
|
After Width: | Height: | Size: 217 B |
|
After Width: | Height: | Size: 185 B |
|
After Width: | Height: | Size: 217 B |
|
After Width: | Height: | Size: 185 B |
|
After Width: | Height: | Size: 175 B |
|
After Width: | Height: | Size: 144 B |
|
After Width: | Height: | Size: 175 B |
|
After Width: | Height: | Size: 144 B |
|
After Width: | Height: | Size: 185 B |
|
After Width: | Height: | Size: 185 B |
|
After Width: | Height: | Size: 185 B |
|
After Width: | Height: | Size: 185 B |
|
After Width: | Height: | Size: 239 B |
|
After Width: | Height: | Size: 226 B |
|
After Width: | Height: | Size: 239 B |
|
After Width: | Height: | Size: 226 B |
|
After Width: | Height: | Size: 226 B |
|
After Width: | Height: | Size: 229 B |
|
After Width: | Height: | Size: 226 B |
|
After Width: | Height: | Size: 229 B |
@@ -54,8 +54,7 @@
|
||||
<RelativeLayout
|
||||
android:id="@+id/start_time_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/time_start"
|
||||
@@ -97,7 +96,6 @@
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="@dimen/side_padding"
|
||||
android:layout_toRightOf="@+id/start_time_container">
|
||||
|
||||
@@ -115,8 +113,22 @@
|
||||
android:visibility="invisible"
|
||||
tools:text="@string/time"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/first_vessel_duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/start_time_container"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginLeft="@dimen/side_padding"
|
||||
android:drawableLeft="?attr/flag_18dp"
|
||||
android:drawablePadding="6dp"
|
||||
android:textColor="?attr/white"
|
||||
android:textSize="@dimen/panel_button_caption_size"
|
||||
android:visibility="gone"
|
||||
tools:text="0h 23m 14s"
|
||||
tools:visibility="visible" />
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -136,4 +148,4 @@
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
</com.sap.sailing.racecommittee.app.ui.layouts.TimePanelHeaderLayout>
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -49,8 +49,7 @@
|
||||
<RelativeLayout
|
||||
android:id="@+id/start_time_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/time_start"
|
||||
@@ -91,7 +90,6 @@
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="@dimen/side_padding"
|
||||
android:layout_toRightOf="@+id/start_time_container">
|
||||
|
||||
@@ -108,7 +106,22 @@
|
||||
android:visibility="invisible"
|
||||
tools:text="@string/time"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/first_vessel_duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/start_time_container"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginLeft="@dimen/side_padding"
|
||||
android:drawableLeft="?attr/flag_24dp"
|
||||
android:drawablePadding="6dp"
|
||||
android:textAppearance="?attr/textSmall"
|
||||
android:visibility="gone"
|
||||
tools:text="0h 23m 14s"
|
||||
tools:visibility="visible" />
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -128,4 +141,4 @@
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
</com.sap.sailing.racecommittee.app.ui.layouts.TimePanelHeaderLayout>
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -365,7 +365,7 @@
|
||||
<string name="race_summary_wind_direction_value">aus %.0f°</string>
|
||||
<string name="race_summary_wind_speed">Durchschnittliche Windgeschwindigkeit</string>
|
||||
<string name="record_voice">Stimme aufzeichnen</string>
|
||||
<string name="finishing_started">Erstes Schiff im Ziel um %s</string>
|
||||
<string name="finishing_started">Erster im Ziel um %1$s</string>
|
||||
<string name="finishing_started_since">(%s)</string>
|
||||
<string name="finishing_done">Jetzt runter</string>
|
||||
<string name="finished_edit">Liste bearbeiten</string>
|
||||
|
||||
@@ -71,6 +71,8 @@
|
||||
<attr name="course_updown_48dp" format="reference" />
|
||||
<attr name="course_updown_64dp" format="reference" />
|
||||
<attr name="dns" format="reference" />
|
||||
<attr name="flag_18dp" format="reference" />
|
||||
<attr name="flag_24dp" format="reference" />
|
||||
<attr name="hearing" format="reference" />
|
||||
<attr name="link_24dp" format="reference" />
|
||||
<attr name="list_24dp" format="reference" />
|
||||
|
||||
@@ -386,7 +386,7 @@
|
||||
<string name="race_summary_individual_recalls">Individual Recalls</string>
|
||||
<string name="race_summary_time" translatable="false">%s min</string>
|
||||
<string name="record_voice">Record Voice</string>
|
||||
<string name="finishing_started">First vessel in finish at %s</string>
|
||||
<string name="finishing_started">First in finish at %1$s</string>
|
||||
<string name="finishing_started_since">(%s)</string>
|
||||
<string name="finishing_done">Down now</string>
|
||||
|
||||
|
||||
@@ -81,6 +81,8 @@
|
||||
<item name="course_updown_48dp">@drawable/course_updown_48dp_dark</item>
|
||||
<item name="course_updown_64dp">@drawable/course_updown_64dp_dark</item>
|
||||
<item name="dns">@drawable/ic_dns_white</item>
|
||||
<item name="flag_18dp">@drawable/ic_flag_white_18dp</item>
|
||||
<item name="flag_24dp">@drawable/ic_flag_white_24dp</item>
|
||||
<item name="hearing">@drawable/ic_hearing_white</item>
|
||||
<item name="link_24dp">@drawable/ic_link_white_24dp</item>
|
||||
<item name="list_both_24dp">@drawable/ic_list_both_white_24dp</item>
|
||||
|
||||
@@ -90,6 +90,8 @@
|
||||
<item name="course_updown_48dp">@drawable/course_updown_48dp_light</item>
|
||||
<item name="course_updown_64dp">@drawable/course_updown_64dp_light</item>
|
||||
<item name="dns">@drawable/ic_dns_black</item>
|
||||
<item name="flag_18dp">@drawable/ic_flag_black_18dp</item>
|
||||
<item name="flag_24dp">@drawable/ic_flag_black_24dp</item>
|
||||
<item name="hearing">@drawable/ic_hearing_black</item>
|
||||
<item name="link_24dp">@drawable/ic_link_black_24dp</item>
|
||||
<item name="list_both_24dp">@drawable/ic_list_both_black_24dp</item>
|
||||
|
||||
@@ -298,7 +298,7 @@ public class FlagPanelFragment extends BasePanelFragment {
|
||||
break;
|
||||
|
||||
case FINISHING:
|
||||
mBlueLastText.setText(TimeUtils.formatDurationSince(now.minus(getRaceState().getFinishingTime().asMillis()).asMillis()));
|
||||
mBlueLastText.setText(TimeUtils.formatTimeAgo(getActivity(), now.minus(getRaceState().getFinishingTime().asMillis()).asMillis()));
|
||||
changeVisibility(mRecallLock, mRecallLayer, View.VISIBLE);
|
||||
break;
|
||||
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
package com.sap.sailing.racecommittee.app.ui.fragments.panels;
|
||||
|
||||
import static com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderResult.ResolutionFailed.NO_START_TIME_SET;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.sap.sailing.android.shared.logging.ExLog;
|
||||
import com.sap.sailing.android.shared.util.BroadcastManager;
|
||||
@@ -30,22 +39,13 @@ import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import static com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderResult.ResolutionFailed.NO_START_TIME_SET;
|
||||
|
||||
public class TimePanelFragment extends BasePanelFragment {
|
||||
|
||||
public final static String TOGGLED = "toggled";
|
||||
private final static String TOGGLED = "toggled";
|
||||
|
||||
private RaceStateChangedListener mStateListener;
|
||||
private IntentReceiver mReceiver;
|
||||
@@ -58,10 +58,12 @@ public class TimePanelFragment extends BasePanelFragment {
|
||||
private TextView mCurrentTime;
|
||||
private TextView mHeaderTime;
|
||||
private TextView mTimeStart;
|
||||
private TextView mFirstVesselDuration;
|
||||
private ImageView mLinkIcon;
|
||||
private Boolean mLinkedRace = null;
|
||||
|
||||
private CompetitorPanelClick mClickListener;
|
||||
private TimePoint mLastFinishingTime = null;
|
||||
|
||||
public TimePanelFragment() {
|
||||
mReceiver = new IntentReceiver();
|
||||
@@ -95,6 +97,7 @@ public class TimePanelFragment extends BasePanelFragment {
|
||||
mHeaderTime = ViewHelper.get(layout, R.id.timer_text);
|
||||
mTimeStart = ViewHelper.get(layout, R.id.time_start);
|
||||
mLinkIcon = ViewHelper.get(layout, R.id.linked_race);
|
||||
mFirstVesselDuration = ViewHelper.get(layout, R.id.first_vessel_duration);
|
||||
|
||||
if (getArguments().getBoolean(TOGGLED, false)) {
|
||||
toggleMarker(layout, R.id.time_marker);
|
||||
@@ -195,6 +198,14 @@ public class TimePanelFragment extends BasePanelFragment {
|
||||
if (mLinkedRace != null && mLinkIcon != null) {
|
||||
mLinkIcon.setVisibility(mLinkedRace ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
if (mFirstVesselDuration != null && mFirstVesselDuration.getVisibility() == View.VISIBLE) {
|
||||
if (!getRaceState().getFinishingTime().equals(mLastFinishingTime)) {
|
||||
mLastFinishingTime = getRaceState().getFinishingTime();
|
||||
String raceDuration = TimeUtils.formatTimeAgo(getActivity(), mLastFinishingTime.minus(getRaceState().getStartTime().asMillis()).asMillis());
|
||||
mFirstVesselDuration.setText(raceDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void uncheckMarker(View view) {
|
||||
@@ -214,34 +225,42 @@ public class TimePanelFragment extends BasePanelFragment {
|
||||
switch (getRace().getStatus()) {
|
||||
case UNSCHEDULED:
|
||||
changeVisibility(mTimeLock, null, View.GONE);
|
||||
changeVisibility(mFirstVesselDuration, null, View.GONE);
|
||||
break;
|
||||
|
||||
case PRESCHEDULED:
|
||||
changeVisibility(mTimeLock, null, View.GONE);
|
||||
changeVisibility(mFirstVesselDuration, null, View.GONE);
|
||||
break;
|
||||
|
||||
case SCHEDULED:
|
||||
changeVisibility(mTimeLock, null, View.GONE);
|
||||
changeVisibility(mFirstVesselDuration, null, View.GONE);
|
||||
break;
|
||||
|
||||
case STARTPHASE:
|
||||
changeVisibility(mTimeLock, null, View.GONE);
|
||||
changeVisibility(mFirstVesselDuration, null, View.GONE);
|
||||
break;
|
||||
|
||||
case RUNNING:
|
||||
changeVisibility(mTimeLock, null, View.VISIBLE);
|
||||
changeVisibility(mFirstVesselDuration, null, View.GONE);
|
||||
break;
|
||||
|
||||
case FINISHING:
|
||||
changeVisibility(mTimeLock, null, View.VISIBLE);
|
||||
changeVisibility(mFirstVesselDuration, null, View.VISIBLE);
|
||||
break;
|
||||
|
||||
case FINISHED:
|
||||
changeVisibility(mTimeLock, null, View.VISIBLE);
|
||||
changeVisibility(mFirstVesselDuration, null, View.VISIBLE);
|
||||
break;
|
||||
|
||||
default:
|
||||
changeVisibility(mTimeLock, null, View.VISIBLE);
|
||||
changeVisibility(mFirstVesselDuration, null, View.GONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public class RaceFinishingFragment extends BaseFragment {
|
||||
super.notifyTick(now);
|
||||
|
||||
if (mFinishingSince != null && getRaceState().getFinishingTime() != null) {
|
||||
String timeDiff = TimeUtils.formatDurationSince(now.minus(getRaceState().getFinishingTime().asMillis()).asMillis());
|
||||
String timeDiff = TimeUtils.formatTimeAgo(getActivity(), now.minus(getRaceState().getFinishingTime().asMillis()).asMillis());
|
||||
mFinishingSince.setText(getString(R.string.finishing_started_since, timeDiff));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -506,8 +506,8 @@ public class StartTimeFragment extends BaseFragment
|
||||
mTimePicker.setIs24HourView(true);
|
||||
int hours = time.get(Calendar.HOUR_OF_DAY);
|
||||
int minutes = time.get(Calendar.MINUTE);
|
||||
if (getArguments() != null && getArguments().getInt(START_MODE, START_MODE_PRESETUP) != MODE_TIME_PANEL && mRaceId == null
|
||||
&& mStartTimeOffset == null) {
|
||||
if (getArguments() != null && getArguments().getInt(START_MODE, START_MODE_PRESETUP) != MODE_TIME_PANEL
|
||||
&& getArguments().getSerializable(MainScheduleFragment.START_TIME) == null) {
|
||||
// In 10 minutes from now, but always a 5-minute-mark.
|
||||
time.add(Calendar.MINUTE, 10);
|
||||
hours = time.get(Calendar.HOUR_OF_DAY);
|
||||
@@ -515,6 +515,7 @@ public class StartTimeFragment extends BaseFragment
|
||||
minutes = (int) (Math.ceil((minutes / 5.0)) * 5.0);
|
||||
if (minutes >= 60) {
|
||||
hours++;
|
||||
minutes = 0;
|
||||
}
|
||||
}
|
||||
mTimePicker.setCurrentHour(hours);
|
||||
@@ -623,7 +624,7 @@ public class StartTimeFragment extends BaseFragment
|
||||
break;
|
||||
|
||||
case R.id.set_start_time_relative:
|
||||
changeFragment(MillisecondsTimePoint.now(), new MillisecondsDurationImpl(mTimeOffset.getValue() * 60 * 1000), identifier);
|
||||
changeFragment(mStartTime, new MillisecondsDurationImpl(mTimeOffset.getValue() * 60 * 1000), identifier);
|
||||
break;
|
||||
|
||||
case R.id.sync_to_minute:
|
||||
@@ -772,9 +773,12 @@ public class StartTimeFragment extends BaseFragment
|
||||
viewId = R.id.race_content;
|
||||
}
|
||||
args.putAll(getArguments());
|
||||
args.putSerializable(MainScheduleFragment.START_TIME, startTime);
|
||||
args.putSerializable(MainScheduleFragment.START_TIME_DIFF, startTimeDiff);
|
||||
args.putSerializable(MainScheduleFragment.DEPENDENT_RACE, identifier);
|
||||
if (startTimeDiff == null) {
|
||||
args.putSerializable(MainScheduleFragment.START_TIME, startTime);
|
||||
} else {
|
||||
args.putSerializable(MainScheduleFragment.START_TIME_DIFF, startTimeDiff);
|
||||
args.putSerializable(MainScheduleFragment.DEPENDENT_RACE, identifier);
|
||||
}
|
||||
}
|
||||
fragment.setArguments(args);
|
||||
transaction.replace(viewId, fragment);
|
||||
|
||||