Merge branch 'ubilabs--tracking_app--develop' into ubilabs--tracking_app--bugfix--bug_2993

This commit is contained in:
Bennet Brunsen committed 2015-06-26 10:05:52 +02:00
commit bdf77e1a9c
59 files changed
+1018 -489

No files matched your search

+1 -1
View File
@@ -650,7 +650,7 @@ if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then
echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter extra-android-m2repository --no-ui --force --all > /dev/null
echo "Updating Android SDK (extra-google-m2repository)..." | tee -a $START_DIR/build.log
echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter extra-google-m2repository --no-ui --force --all > /dev/null
./gradlew clean build | tee -a $START_DIR/build.log
./gradlew clean build -xtest | tee -a $START_DIR/build.log
if [[ ${PIPESTATUS[0]} != 0 ]]; then
exit 100
fi
@@ -3128,7 +3128,12 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
leaderboardGroup.getDisplayName(), leaderboardGroup.getDescription());
groupDTO.displayLeaderboardsInReverseOrder = leaderboardGroup.isDisplayGroupsInReverseOrder();
for (Leaderboard leaderboard : leaderboardGroup.getLeaderboards()) {
groupDTO.leaderboards.add(createStrippedLeaderboardDTO(leaderboard, withGeoLocationData, withStatisticalData));
try {
StrippedLeaderboardDTO leaderboardDTO = createStrippedLeaderboardDTO(leaderboard, withGeoLocationData, withStatisticalData);
groupDTO.leaderboards.add(leaderboardDTO);
} catch (Exception e) {
logger.log(Level.SEVERE, "Catched exception while reading data for leaderboard " + leaderboard.getName(), e);
}
}
Leaderboard overallLeaderboard = leaderboardGroup.getOverallLeaderboard();
if (overallLeaderboard != null) {
@@ -6,6 +6,8 @@ import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.gwt.core.shared.GwtIncompatible;
import com.sap.sailing.domain.base.Event;
@@ -26,6 +28,8 @@ import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.MediaTagConstants;
public class GetEventViewAction implements Action<EventViewDTO> {
private static final Logger logger = Logger.getLogger(GetEventViewAction.class.getName());
private UUID eventId;
public GetEventViewAction() {
@@ -57,25 +61,29 @@ public class GetEventViewAction implements Action<EventViewDTO> {
for (LeaderboardGroup leaderboardGroup : event.getLeaderboardGroups()) {
for (Leaderboard leaderboard : leaderboardGroup.getLeaderboards()) {
if(leaderboard instanceof RegattaLeaderboard) {
Regatta regatta = context.getRacingEventService().getRegattaByName(leaderboard.getName());
if(isFakeSeries && !HomeServiceUtil.isPartOfEvent(event, regatta)) {
continue;
try {
if(leaderboard instanceof RegattaLeaderboard) {
Regatta regatta = context.getRacingEventService().getRegattaByName(leaderboard.getName());
if(isFakeSeries && !HomeServiceUtil.isPartOfEvent(event, regatta)) {
continue;
}
RegattaMetadataDTO regattaDTO = createRegattaMetadataDTO(leaderboardGroup, leaderboard);
regattaDTO.setStartDate(regatta.getStartDate() != null ? regatta.getStartDate().asDate() : null);
regattaDTO.setEndDate(regatta.getEndDate() != null ? regatta.getEndDate().asDate() : null);
regattaDTO.setState(HomeServiceUtil.calculateRegattaState(regattaDTO));
dto.getRegattas().add(regattaDTO);
} else if(leaderboard instanceof FlexibleLeaderboard) {
RegattaMetadataDTO regattaDTO = createRegattaMetadataDTO(leaderboardGroup, leaderboard);
regattaDTO.setStartDate(null);
regattaDTO.setEndDate(null);
regattaDTO.setState(HomeServiceUtil.calculateRegattaState(regattaDTO));
dto.getRegattas().add(regattaDTO);
}
RegattaMetadataDTO regattaDTO = createRegattaMetadataDTO(leaderboardGroup, leaderboard);
regattaDTO.setStartDate(regatta.getStartDate() != null ? regatta.getStartDate().asDate() : null);
regattaDTO.setEndDate(regatta.getEndDate() != null ? regatta.getEndDate().asDate() : null);
regattaDTO.setState(HomeServiceUtil.calculateRegattaState(regattaDTO));
dto.getRegattas().add(regattaDTO);
} else if(leaderboard instanceof FlexibleLeaderboard) {
RegattaMetadataDTO regattaDTO = createRegattaMetadataDTO(leaderboardGroup, leaderboard);
regattaDTO.setStartDate(null);
regattaDTO.setEndDate(null);
regattaDTO.setState(HomeServiceUtil.calculateRegattaState(regattaDTO));
dto.getRegattas().add(regattaDTO);
} catch (Exception e) {
logger.log(Level.SEVERE, "Catched exception while reading data for leaderboard " + leaderboard.getName(), e);
}
}
}
@@ -15,6 +15,10 @@ android {
java.srcDirs = ["src"]
res.srcDirs = ["res"]
}
test {
java.srcDirs = ["tests-jvm/src"]
}
}
signingConfigs {
@@ -46,6 +50,11 @@ dependencies {
/* Google Play Services */
compile "com.google.android.gms:play-services-location:7.3.0"
/* all local jar-libs */
compile fileTree(dir: "libs", include: ["*.jar"])
/* JVM tests */
testCompile 'junit:junit:4.12'
testCompile "org.mockito:mockito-core:1.9.5"
}
@@ -26,9 +26,13 @@ android {
}
androidTest {
java.srcDirs = ["tests/src"]
res.srcDirs = ["tests/res"]
assets.srcDirs = ["tests/assets"]
java.srcDirs = ["tests-ui/src"]
res.srcDirs = ["tests-ui/res"]
assets.srcDirs = ["tests-ui/assets"]
}
test {
java.srcDirs = ["tests-jvm/src"]
}
}
@@ -64,7 +68,6 @@ android {
}
dependencies {
/* support libraries */
compile "com.android.support:appcompat-v7:22.1.1"
@@ -75,8 +78,20 @@ dependencies {
/* local dependencies */
compile project(":mobile:com.sap.sailing.android.shared")
/* all local jar-libs */
// compile fileTree(dir: "libs", include: ["*.jar"])
/* JVM tests */
testCompile 'junit:junit:4.12'
testCompile "org.mockito:mockito-core:1.9.5"
/* UI testing with espresso */
androidTestCompile "com.android.support:support-annotations:22.1.1"
androidTestCompile "com.android.support.test:runner:0.2"
androidTestCompile "com.android.support.test:rules:0.2"
androidTestCompile "com.android.support.test.espresso:espresso-core:2.1"
androidTestCompile ("com.android.support.test.espresso:espresso-contrib:2.1") {
exclude group: "com.android.support", module: "appcompat"
exclude group: "com.android.support", module: "support-v4"
exclude module: "recyclerview-v7"
}
}
// Custom tasks
@@ -0,0 +1,14 @@
package com.sap.sailing.android.tracking.app.utils;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
public class ServiceHelperTest {
@Test
public void testServiceHelperConstructor() {
ServiceHelper serviceHelper = ServiceHelper.getInstance();
assertNotNull(serviceHelper);
}
}
@@ -26,9 +26,13 @@ android {
}
androidTest {
java.srcDirs = ["tests/src"]
res.srcDirs = ["tests/res"]
assets.srcDirs = ["tests/assets"]
java.srcDirs = ["tests-ui/src"]
res.srcDirs = ["tests-ui/res"]
assets.srcDirs = ["tests-ui/assets"]
}
test {
java.srcDirs = ["tests-jvm/src"]
}
}
@@ -73,8 +77,20 @@ dependencies {
/* local dependencies */
compile project(":mobile:com.sap.sailing.android.shared")
/* all local jar-libs */
// compile fileTree(dir: "libs", include: ["*.jar"])
/* JVM tests */
testCompile 'junit:junit:4.12'
testCompile "org.mockito:mockito-core:1.9.5"
/* UI testing with espresso */
androidTestCompile "com.android.support:support-annotations:22.1.1"
androidTestCompile "com.android.support.test:runner:0.2"
androidTestCompile "com.android.support.test:rules:0.2"
androidTestCompile "com.android.support.test.espresso:espresso-core:2.1"
androidTestCompile ("com.android.support.test.espresso:espresso-contrib:2.1") {
exclude group: "com.android.support", module: "appcompat"
exclude group: "com.android.support", module: "support-v4"
exclude module: "recyclerview-v7"
}
}
// Custom tasks
@@ -0,0 +1,16 @@
package com.sap.sailing.android.buoy.positioning.app.valueobjects;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class MarkInfoTest {
@Test
public void testMarkInfoName() {
MarkInfo markInfo = new MarkInfo();
String name = "test";
markInfo.setName(name);
assertEquals(markInfo.getName(), name);
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 787 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- pressed -->
<item android:drawable="@drawable/ic_create_yellow_36dp" android:state_pressed="true" />
<!-- default -->
<item android:drawable="@drawable/ic_create_white_36dp" />
</selector>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- pressed -->
<item android:drawable="@drawable/ic_create_yellow_36dp" android:state_pressed="true" />
<!-- default -->
<item android:drawable="@drawable/ic_create_black_36dp" />
</selector>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 853 B

@@ -86,6 +86,20 @@
android:src="@drawable/ic_info_outline_white_48dp"
tools:alpha="1"/>
<ImageView
android:id="@+id/refresh_data"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="@dimen/default_margin"
android:layout_marginRight="@dimen/default_margin_half"
android:layout_toLeftOf="@id/technical_info"
android:alpha="0"
android:background="@drawable/round_button"
android:padding="10dp"
android:src="@drawable/ic_refresh_white_48dp"
tools:alpha="1"/>
<View
android:id="@+id/view"
android:layout_width="match_parent"
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/login_view_backdrop"
@@ -16,5 +19,25 @@
android:layout_gravity="center_horizontal|bottom"
android:background="?sap_gray_black_30"
tools:layout="@layout/login_listviews"/>
</merge>
<RelativeLayout
android:id="@+id/progress_spinner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
tools:visibility="visible">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#c8000000"
android:clickable="true"/>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true"/>
</RelativeLayout>
</FrameLayout>
@@ -27,7 +27,7 @@
android:layout_margin="@dimen/default_margin"
android:background="@drawable/round_button"
android:padding="10dp"
android:src="@drawable/ic_assignment_white_48dp" />
android:src="@drawable/ic_power_settings_new_white_48dp" />
<TextView
android:id="@+id/regatta_data"
@@ -89,59 +89,12 @@
android:id="@+id/line_top"
android:layout_width="match_parent"
android:layout_height="@dimen/thick_line"
android:layout_below="@+id/buttonBar"
android:layout_below="@id/buttonBar"
android:background="?black"/>
<RelativeLayout
<include
layout="@layout/race_time_picker"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/buttonBar"
android:background="?sap_gray_black_30">
<LinearLayout
android:id="@+id/start_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:scaleX="1.55"
android:scaleY="1.55">
<NumberPicker
android:id="@+id/start_date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:descendantFocusability="blocksDescendants"/>
<include
android:id="@+id/start_time_picker"
layout="@layout/time_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"/>
</LinearLayout>
<Button
android:id="@+id/set_start_time"
style="?attr/buttonSolidSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:layout_margin="@dimen/default_margin_twice"
android:maxWidth="200dp"
android:text="@string/race_set_start"/>
<TextView
android:id="@+id/debug_time"
style="?textSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:visibility="gone"
tools:text="12:12:12"/>
</RelativeLayout>
android:layout_below="@id/buttonBar"/>
</RelativeLayout>
@@ -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="match_parent">
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
@@ -30,7 +30,7 @@
android:layout_centerVertical="true"
android:text="@string/race_summary_title"
android:textColor="?white"
android:textSize="@dimen/textSize_40" />
android:textSize="@dimen/textSize_40"/>
</RelativeLayout>
@@ -38,7 +38,7 @@
android:layout_width="match_parent"
android:layout_height="@dimen/thin_line"
android:layout_marginBottom="@dimen/default_margin_half"
android:background="?sap_gray" />
android:background="?sap_gray"/>
<LinearLayout
android:layout_width="match_parent"
@@ -52,14 +52,14 @@
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="@string/race_summary_start"
android:textAppearance="?attr/textNormal" />
android:textAppearance="?attr/textNormal"/>
<ImageView
android:id="@+id/edit_race_start_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="?create_36dp"
android:visibility="gone"
android:src="?create"
android:visibility="invisible"
tools:visibility="visible"/>
<TextView
@@ -69,12 +69,12 @@
android:layout_weight="1"
android:gravity="right"
android:textAppearance="?attr/textNormal"
tools:text="11:00:00" />
tools:text="11:00:00"/>
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
@@ -88,15 +88,14 @@
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="@string/race_summary_finish_begin"
android:textAppearance="?attr/textNormal" />
android:textAppearance="?attr/textNormal"/>
<ImageView
android:id="@+id/edit_race_finish_begin_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="?create_36dp"
android:visibility="gone"
tools:visibility="visible"/>
android:src="?create"
android:visibility="visible"/>
<TextView
android:id="@+id/race_finish_begin_time"
@@ -105,7 +104,7 @@
android:layout_weight="1"
android:gravity="right"
android:textAppearance="?attr/textNormal"
tools:text="11:12:18" />
tools:text="11:12:18"/>
<TextView
android:id="@+id/race_finish_begin_duration"
@@ -114,7 +113,7 @@
android:layout_weight="1"
android:gravity="right"
android:textAppearance="?textNormal"
tools:text="12:18 min" />
tools:text="12:18 min"/>
</LinearLayout>
<LinearLayout
@@ -128,15 +127,14 @@
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="@string/race_summary_finish_end"
android:textAppearance="?attr/textNormal" />
android:textAppearance="?attr/textNormal"/>
<ImageView
android:id="@+id/edit_race_finish_end_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="?create_36dp"
android:visibility="gone"
tools:visibility="visible"/>
android:src="?create"
android:visibility="visible"/>
<TextView
android:id="@+id/race_finish_end_time"
@@ -145,7 +143,7 @@
android:layout_weight="1"
android:gravity="right"
android:textAppearance="?attr/textNormal"
tools:text="11:16:36" />
tools:text="11:16:36"/>
<TextView
android:id="@+id/race_finish_end_duration"
@@ -154,7 +152,7 @@
android:layout_weight="1"
android:gravity="right"
android:textAppearance="?attr/textNormal"
tools:text="16:36 min" />
tools:text="16:36 min"/>
</LinearLayout>
<LinearLayout
@@ -168,7 +166,7 @@
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="@string/race_summary_finish_duration"
android:textAppearance="?attr/textNormal" />
android:textAppearance="?attr/textNormal"/>
<TextView
android:id="@+id/race_finish_duration"
@@ -177,7 +175,7 @@
android:layout_weight="2"
android:gravity="right"
android:textAppearance="?attr/textNormal"
tools:text="04:18 min" />
tools:text="04:18 min"/>
</LinearLayout>
<LinearLayout
@@ -191,7 +189,7 @@
android:layout_height="@dimen/thin_line"
android:layout_marginBottom="@dimen/default_margin_half"
android:layout_marginTop="@dimen/default_margin_half"
android:background="?sap_gray" />
android:background="?sap_gray"/>
<LinearLayout
android:layout_width="match_parent"
@@ -204,7 +202,7 @@
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="@string/race_summary_wind_direction"
android:textAppearance="?attr/textNormal" />
android:textAppearance="?attr/textNormal"/>
<TextView
android:id="@+id/wind_direction"
@@ -213,7 +211,7 @@
android:layout_weight="2"
android:gravity="right"
android:textAppearance="?attr/textNormal"
tools:text="from 192°" />
tools:text="from 192°"/>
</LinearLayout>
<LinearLayout
@@ -227,17 +225,17 @@
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="@string/race_summary_wind_speed"
android:textAppearance="?attr/textNormal" />
android:textAppearance="?attr/textNormal"/>
<TextView
android:id="@+id/wind_speed"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="2"
android:gravity="right"
android:textAppearance="?attr/textNormal"
tools:text="6.5 kts"
android:layout_gravity="center_vertical"/>
tools:text="6.5 kts"/>
</LinearLayout>
</LinearLayout>
@@ -252,7 +250,7 @@
android:layout_height="@dimen/thin_line"
android:layout_marginBottom="@dimen/default_margin_half"
android:layout_marginTop="@dimen/default_margin_half"
android:background="?sap_gray" />
android:background="?sap_gray"/>
<LinearLayout
android:layout_width="match_parent"
@@ -264,14 +262,14 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/race_summary_individual_recalls"
android:textAppearance="?attr/textNormal" />
android:textAppearance="?attr/textNormal"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:textAppearance="?attr/textNormal"
tools:text="AUT 553 GER 766 ITA 912" />
tools:text="AUT 553 GER 766 ITA 912"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="@dimen/selector_header_height"
android:background="?sap_gray">
<LinearLayout
android:id="@+id/header_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/default_margin"
android:layout_marginStart="@dimen/default_margin"
android:orientation="horizontal">
<ImageView
android:id="@+id/header_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="?chevron_left_24dp"/>
<TextView
android:id="@+id/header_headline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/set_time"
android:textAppearance="?textNormal"/>
</LinearLayout>
</RelativeLayout>
<include
layout="@layout/race_time_picker"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/header"/>
</RelativeLayout>
@@ -0,0 +1,62 @@
<?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="match_parent"
android:background="?sap_gray_black_30">
<LinearLayout
android:id="@+id/picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:scaleX="1.55"
android:scaleY="1.55">
<NumberPicker
android:id="@+id/date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:descendantFocusability="blocksDescendants"/>
<include
android:id="@+id/time_picker"
layout="@layout/time_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"/>
<NumberPicker
android:id="@+id/second_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:descendantFocusability="blocksDescendants"
android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout>
<Button
android:id="@+id/set_date_time"
style="?attr/buttonSolidXSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/picker"
android:layout_margin="@dimen/default_margin_twice"
android:maxWidth="200dp"
android:layout_centerHorizontal="true"
android:text="@string/race_set_time"/>
<TextView
android:id="@+id/debug_time"
style="?textSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:visibility="gone"
tools:text="12:12:12"/>
</RelativeLayout>
@@ -1,12 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item
android:id="@+id/options_menu_reload"
android:icon="@drawable/ic_menu_info_details"
android:title="@string/options_menu_reload"
android:visible="true"/>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/options_menu_reset"
@@ -14,11 +7,9 @@
<item
android:id="@+id/options_menu_settings"
android:icon="@drawable/settings_grey"
android:title="@string/options_menu_settings"/>
<item
android:id="@+id/options_menu_info"
android:icon="@drawable/ic_menu_info_details"
android:title="@string/options_menu_info"/>
</menu>
@@ -34,7 +34,7 @@
<string name="flag_ap">AP</string>
<string name="flag_november">November</string>
<string name="flag_jury">Jury</string>
<string name="label_login_events">Event</string>
<string name="label_login_events">Regatta</string>
<string name="label_login_course_area">Bahn</string>
<string name="label_login_position">Position</string>
<string name="login_type_viewer">Im Demo-Modus anmelden</string>
@@ -101,7 +101,6 @@
<string name="availableFinishingCompetitors">Segler</string>
<string name="choose_blue_flag_finishing">Rennen beenden</string>
<string name="drag_handle_description">Cursor</string>
<string name="options_menu_reload">Neuladen</string>
<string name="options_menu_settings">Einstellungen</string>
<string name="results_capturing_title">Ergebnislisten</string>
<string name="results_capturing_view_subject">E-Mail Betreff</string>
@@ -269,7 +268,7 @@
<string name="course">Kurs</string>
<string name="confirm_start_time">Startzeit Bestätigen</string>
<string name="confirm_start_mode">Startmodus Bestätigen</string>
<string name="login_sub_text">Wo halten Sie sich auf?</string>
<string name="login_sub_text">Bitte wählen Sie eine Regatta aus</string>
<string name="login_text">Willkommen in der SAP Sailing\nRace Committee App</string>
<string name="nav_drawer_close">Navigation-Drawer schließen</string>
<string name="nav_drawer_open">Navigation-Drawer öffnen</string>
@@ -323,7 +322,7 @@
<string name="race_reset_confirm">Rennen zurücksetzen</string>
<string name="race_reset_cancel">Nein danke</string>
<string name="race_reset_message">Möchten Sie wirklich das Rennen inklusive aller Einstellungen und getätigten Aktionen zurücksetzen? Das kann nicht rückgängig gemacht werden!</string>
<string name="race_set_start">Startzeit setzen</string>
<string name="race_set_time">Zeit setzen</string>
<string name="race_start_time_in">-#TIME#</string>
<string name="race_start_time_ago">#TIME#</string>
<string name="tomorrow">Morgen</string>
@@ -421,6 +420,12 @@
<string name="change_message">Nach den Wettfahrtregeln sind diese Daten im aktuellen Rennenstatus nicht veränderbar.\nSie könnten jedoch die falschen Eingaben korrigieren.</string>
<string name="change_title">Warnung</string>
<string name="send_mail">Sende Email...</string>
<string name="data_reload_title">Daten wurden extern verändert</string>
<string name="data_reload_message">Daten müssen neu geladen werden. Eventueller Datenverlust ist möglich.</string>
<string name="error_finished_time">Die ausgewählte Zielzeit liegt vor der Zeit, der ersten Schiffeinfahrt. Bitte überprüfe die Uhrzeit.</string>
<string name="error_finishing_time">Die ausgewählte Zeit is vor dem Rennstart. Bitte überprüfe die Uhrzeit.</string>
<string name="error_time_in_future">Die ausgewählte Zeit liegt in der Zukunft. Bitte überprüfe die Uhrzeit.</string>
<string name="error_wrong_race_state">Der RaceState hat nicht den korrekten Status (benötigt: %1$s - aktuell: %2$s)</string>
</resources>
@@ -16,6 +16,7 @@
<attr name="white_invert" format="color"/>
<!-- custom references (e.g. styles) -->
<attr name="buttonSolidXSmall" format="reference"/>
<attr name="buttonSolidSmall" format="reference"/>
<attr name="buttonSolidNormal" format="reference"/>
<attr name="textXXSmall" format="reference"/>
@@ -43,7 +44,7 @@
<attr name="chevron_left_24dp" format="reference"/>
<attr name="chevron_left_36dp" format="reference"/>
<attr name="chevron_right_36dp" format="reference"/>
<attr name="create_36dp" format="reference"/>
<attr name="create" format="reference"/>
<attr name="compass_back" format="reference"/>
<attr name="compass_needle" format="reference"/>
<attr name="course_triangle_48dp" format="reference"/>
@@ -43,7 +43,7 @@
<string name="flag_ap">AP</string>
<string name="flag_november">November</string>
<string name="flag_jury">Jury</string>
<string name="label_login_events">Event</string>
<string name="label_login_events">Regatta</string>
<string name="label_login_course_area">Area</string>
<string name="label_login_position">Position</string>
<string name="login_type_officer_on_start_vessel">Login as race officer on the selected course\'s start vessel.</string>
@@ -110,7 +110,6 @@
<string name="availableFinishingCompetitors">Competitors</string>
<string name="choose_blue_flag_finishing">Finish race</string>
<string name="drag_handle_description">Drag handle</string>
<string name="options_menu_reload">Reload</string>
<string name="options_menu_settings">Settings</string>
<string name="results_capturing_title">Race Results</string>
<string name="results_capturing_view_subject">Mail subject</string>
@@ -249,7 +248,7 @@
<string name="race_start_in_1_minute">1 Minute</string>
<string name="race_start_time_in">-#TIME#</string>
<string name="race_start_time_ago">#TIME#</string>
<string name="race_set_start">Set Start Time</string>
<string name="race_set_time">Set Time</string>
<string name="race_reset_course">Reset course</string>
<string name="no_course_active">No course active</string>
<string name="toggle_group_race_mode">Group Race?</string>
@@ -292,7 +291,7 @@
<string name="loading_events_succeded">Events loaded.</string>
<string name="login_text">Welcome to SAP Sailing\nRace Committee App</string>
<string name="login_sub_text">Where are you?</string>
<string name="login_sub_text">Please select a regatta</string>
<string name="sign_up">Sign Me Up</string>
<string name="wind_display">dd</string>
<string name="flags_abandon">Abandon</string>
@@ -444,5 +443,9 @@
<string name="send_mail">Send mail...</string>
<string name="data_reload_title">Data has changed externally</string>
<string name="data_reload_message">Data have to be reloaded. Possible data loss is possible.</string>
<string name="error_finished_time">The given finish time is earlier than the first finisher time. Please recheck the time.</string>
<string name="error_finishing_time">The selected time is before the race start.</string>
<string name="error_time_in_future">The given time is in future. Please recheck the time.</string>
<string name="error_wrong_race_state">The RaceState isn\'t in the correct state (needed: %1$s - current: %2$s)</string>
</resources>
@@ -31,6 +31,7 @@
<item name="white_invert">@color/constant_black</item>
<!-- styles -->
<item name="buttonSolidXSmall">@style/AppTheme.Dark.Button.XSmall</item>
<item name="buttonSolidSmall">@style/AppTheme.Dark.Button.Small</item>
<item name="buttonSolidNormal">@style/AppTheme.Dark.Button.Normal</item>
<item name="textXXSmall">@style/AppTheme.Dark.Text.XXSmall</item>
@@ -57,7 +58,7 @@
<item name="chevron_left_24dp">@drawable/ic_chevron_left_white_24dp</item>
<item name="chevron_left_36dp">@drawable/ic_chevron_left_white_36dp</item>
<item name="chevron_right_36dp">@drawable/ic_chevron_right_white_36dp</item>
<item name="create_36dp">@drawable/ic_create_white_36dp</item>
<item name="create">@drawable/ic_create_dark</item>
<item name="compass_back">@drawable/compass_back_dark</item>
<item name="compass_needle">@drawable/compass_needle_dark</item>
<item name="course_triangle_48dp">@drawable/course_triangle_48dp_dark</item>
@@ -115,6 +116,10 @@
<item name="android:textColorHint">?sap_light_gray</item>
</style>
<style name="AppTheme.Dark.Button.XSmall">
<item name="android:textSize">@dimen/textSize_18</item>
</style>
<style name="AppTheme.Dark.Button.Small">
<item name="android:textSize">@dimen/textSize_22</item>
</style>
@@ -34,6 +34,7 @@
<item name="white_invert">@color/constant_white</item>
<!-- styles -->
<item name="buttonSolidXSmall">@style/AppTheme.Light.Button.XSmall</item>
<item name="buttonSolidSmall">@style/AppTheme.Light.Button.Small</item>
<item name="buttonSolidNormal">@style/AppTheme.Light.Button.Normal</item>
<item name="textXXSmall">@style/AppTheme.Light.Text.XXSmall</item>
@@ -60,7 +61,7 @@
<item name="chevron_left_24dp">@drawable/ic_chevron_left_black_24dp</item>
<item name="chevron_left_36dp">@drawable/ic_chevron_left_black_36dp</item>
<item name="chevron_right_36dp">@drawable/ic_chevron_right_black_36dp</item>
<item name="create_36dp">@drawable/ic_create_black_36dp</item>
<item name="create">@drawable/ic_create_light</item>
<item name="compass_back">@drawable/compass_back_light</item>
<item name="compass_needle">@drawable/compass_needle_light</item>
<item name="course_triangle_48dp">@drawable/course_triangle_48dp_light</item>
@@ -118,6 +119,10 @@
<item name="android:textColorHint">?sap_light_gray</item>
</style>
<style name="AppTheme.Light.Button.XSmall">
<item name="android:textSize">@dimen/textSize_18</item>
</style>
<style name="AppTheme.Light.Button.Small">
<item name="android:textSize">@dimen/textSize_22</item>
</style>
@@ -1,16 +1,18 @@
package com.sap.sailing.racecommittee.app.domain;
import java.util.Collection;
import java.util.List;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.state.RaceState;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.racecommittee.app.domain.impl.Result;
import com.sap.sse.common.Named;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.WithID;
import java.util.Collection;
import java.util.List;
public interface ManagedRace extends ManagedRaceIdentifier, Named, WithID {
/**
@@ -80,4 +82,20 @@ public interface ManagedRace extends ManagedRaceIdentifier, Named, WithID {
* the retrieved list of mapItems for this race
*/
void setMapMarkers(List<MapMarker> markers);
/**
* sets the finished time, if the finished time is after the finishing time; check the {@link Result} for error message
*
* @param finishedTime finished time
* @return result object
*/
Result setFinishedTime(TimePoint finishedTime);
/**
* sets the finishing time, if the finishing time is after the start time; check the {@link Result} for error message
*
* @param finishingTime finishing time
* @return result object
*/
Result setFinishingTime(TimePoint finishingTime);
}
@@ -1,122 +1,163 @@
package com.sap.sailing.racecommittee.app.domain.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.state.RaceState;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.SeriesBase;
import com.sap.sailing.domain.base.racegroup.RaceGroup;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.domain.ManagedRaceIdentifier;
import com.sap.sailing.racecommittee.app.domain.MapMarker;
public class ManagedRaceImpl implements ManagedRace {
private static final long serialVersionUID = -4936566684992524001L;
// private static final String TAG = ManagedRace.class.getName();
private final RaceState state;
private final ManagedRaceIdentifier identifier;
private Collection<Competitor> competitors;
private List<MapMarker> mapMarkers;
private CourseBase courseOnServer;
public ManagedRaceImpl(ManagedRaceIdentifier identifier, RaceState state) {
this.state = state;
this.identifier = identifier;
this.competitors = new ArrayList<Competitor>();
this.courseOnServer = null;
}
@Override
public RaceState getState() {
return state;
}
@Override
public String getId() {
return identifier.getId();
}
@Override
public String getName() {
return identifier.getRaceName();
}
@Override
public String getRaceName() {
return getName();
}
@Override
public Fleet getFleet() {
return identifier.getFleet();
}
@Override
public SeriesBase getSeries() {
return identifier.getSeries();
}
@Override
public RaceGroup getRaceGroup() {
return identifier.getRaceGroup();
}
@Override
public ManagedRaceIdentifier getIdentifier() {
return identifier;
}
@Override
public RaceLog getRaceLog() {
return state.getRaceLog();
}
@Override
public RaceLogRaceStatus getStatus() {
return state.getStatus();
}
@Override
public CourseBase getCourseDesign() {
return state.getCourseDesign();
}
@Override
public Collection<Competitor> getCompetitors() {
return competitors;
}
@Override
public List<MapMarker> getMapMarkers(){
return mapMarkers;
}
@Override
public CourseBase getCourseOnServer() {
return courseOnServer;
}
@Override
public void setCourseOnServer(CourseBase course) {
courseOnServer = course;
}
@Override
public void setCompetitors(Collection<Competitor> competitors) {
this.competitors = competitors;
}
@Override
public void setMapMarkers(List<MapMarker> markers) {
this.mapMarkers = markers;
}
}
package com.sap.sailing.racecommittee.app.domain.impl;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishingTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.state.RaceState;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.SeriesBase;
import com.sap.sailing.domain.base.racegroup.RaceGroup;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.data.AndroidRaceLogResolver;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.domain.ManagedRaceIdentifier;
import com.sap.sailing.racecommittee.app.domain.MapMarker;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class ManagedRaceImpl implements ManagedRace {
private static final long serialVersionUID = -4936566684992524001L;
// private static final String TAG = ManagedRace.class.getName();
private final RaceState state;
private final ManagedRaceIdentifier identifier;
private Collection<Competitor> competitors;
private List<MapMarker> mapMarkers;
private CourseBase courseOnServer;
public ManagedRaceImpl(ManagedRaceIdentifier identifier, RaceState state) {
this.state = state;
this.identifier = identifier;
this.competitors = new ArrayList<Competitor>();
this.courseOnServer = null;
}
@Override
public RaceState getState() {
return state;
}
@Override
public String getId() {
return identifier.getId();
}
@Override
public String getName() {
return identifier.getRaceName();
}
@Override
public String getRaceName() {
return getName();
}
@Override
public Fleet getFleet() {
return identifier.getFleet();
}
@Override
public SeriesBase getSeries() {
return identifier.getSeries();
}
@Override
public RaceGroup getRaceGroup() {
return identifier.getRaceGroup();
}
@Override
public ManagedRaceIdentifier getIdentifier() {
return identifier;
}
@Override
public RaceLog getRaceLog() {
return state.getRaceLog();
}
@Override
public RaceLogRaceStatus getStatus() {
return state.getStatus();
}
@Override
public CourseBase getCourseDesign() {
return state.getCourseDesign();
}
@Override
public Collection<Competitor> getCompetitors() {
return competitors;
}
@Override
public List<MapMarker> getMapMarkers(){
return mapMarkers;
}
@Override
public CourseBase getCourseOnServer() {
return courseOnServer;
}
@Override
public void setCourseOnServer(CourseBase course) {
courseOnServer = course;
}
@Override
public void setCompetitors(Collection<Competitor> competitors) {
this.competitors = competitors;
}
@Override
public void setMapMarkers(List<MapMarker> markers) {
this.mapMarkers = markers;
}
@Override
public Result setFinishedTime(TimePoint finishedTime) {
Result result = new Result();
FinishingTimeFinder ftf = new FinishingTimeFinder(getRaceLog());
if (ftf.analyze() != null) {
if (finishedTime.after(MillisecondsTimePoint.now())) {
result.setError(R.string.error_time_in_future);
} else {
if (ftf.analyze().before(finishedTime)) {
getState().setFinishedTime(finishedTime);
} else {
result.setError(R.string.error_finished_time);
}
}
}
return result;
}
@Override
public Result setFinishingTime(TimePoint finishingTime) {
Result result = new Result();
StartTimeFinder stf = new StartTimeFinder(new AndroidRaceLogResolver(), getRaceLog());
if (stf.analyze() != null) {
if (finishingTime.after(MillisecondsTimePoint.now())) {
result.setError(R.string.error_time_in_future);
} else {
if (stf.analyze().getStartTime().before(finishingTime)) {
getState().setFinishingTime(finishingTime);
} else {
result.setError(R.string.error_finishing_time);
}
}
}
return result;
}
}
@@ -0,0 +1,55 @@
package com.sap.sailing.racecommittee.app.domain.impl;
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
public class Result {
public final static int OK = 0;
private int mErrorString;
private Object[] mObjects;
public Result() {
this(OK);
}
public Result(@StringRes int stringRes) {
setError(stringRes);
}
public void resetError() {
mErrorString = OK;
mObjects = null;
}
public void setError(@StringRes int stringRes) {
resetError();
if (stringRes != 0) {
mErrorString = stringRes;
}
}
public void setError(@StringRes int stringRes, @Nullable Object... objects) {
setError(stringRes);
mObjects = objects;
}
public boolean isOk() {
return (mErrorString == OK);
}
public boolean hasError() {
return (mErrorString != OK);
}
public @StringRes int getMessageId() {
return mErrorString;
}
public String getMessage(Context context) {
return context.getString(getMessageId(), mObjects);
}
}
@@ -15,9 +15,9 @@ import com.sap.sailing.racecommittee.app.data.DataManager;
*/
public class BaseActivity extends SendingServiceAwareActivity {
private static final String TAG = BaseActivity.class.getName();
protected AppPreferences preferences;
@Override
protected int getOptionsMenuResId() {
return R.menu.options_menu;
@@ -32,30 +32,25 @@ public class BaseActivity extends SendingServiceAwareActivity {
super.onCreate(savedInstanceState);
this.preferences = AppPreferences.on(getApplicationContext());
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent intent;
switch (item.getItemId()) {
case R.id.options_menu_settings:
ExLog.i(this, TAG, "Clicked SETTINGS");
intent = new Intent(this, PreferenceActivity.class);
startActivity(intent);
return true;
case R.id.options_menu_settings:
ExLog.i(this, TAG, "Clicked SETTINGS");
intent = new Intent(this, PreferenceActivity.class);
startActivity(intent);
return true;
case R.id.options_menu_reload:
ExLog.i(this, TAG, "Clicked RESET");
final boolean result = onReset();
return result;
case R.id.options_menu_info:
ExLog.i(this, TAG, "Clicked INFO");
intent = new Intent(this, SystemInformationActivity.class);
startActivity(intent);
return true;
case R.id.options_menu_info:
ExLog.i(this, TAG, "Clicked INFO");
intent = new Intent(this, SystemInformationActivity.class);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
default:
return super.onOptionsItemSelected(item);
}
}
@@ -64,10 +59,10 @@ public class BaseActivity extends SendingServiceAwareActivity {
super.onPause();
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
/**
* {@link #resetDataManager() Resets the data manager} (which all redefinitions must do) and then
* fades this activity.
* fades this activity.
*/
protected boolean onReset() {
resetDataManager();
@@ -83,7 +78,7 @@ public class BaseActivity extends SendingServiceAwareActivity {
@Override
public void onResume() {
super.onResume();
preferences = AppPreferences.on(this);
if (preferences.wakelockEnabled()) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
@@ -1,18 +1,19 @@
package com.sap.sailing.racecommittee.app.ui.activities;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.LoaderManager.LoaderCallbacks;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.view.View;
import android.view.ViewGroup;
@@ -55,6 +56,8 @@ import com.sap.sailing.racecommittee.app.utils.autoupdate.AutoUpdater;
import java.io.FileNotFoundException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.UUID;
public class LoginActivity extends BaseActivity
@@ -65,8 +68,6 @@ public class LoginActivity extends BaseActivity
private final static String TAG = LoginActivity.class.getName();
private final int RQS_GooglePlayServices = 1;
private final PositionListFragment positionFragment;
private View backdrop;
private LoginListViews loginListViews = null;
@@ -82,10 +83,8 @@ public class LoginActivity extends BaseActivity
private UUID mSelectedCourseAreaUUID;
private IntentReceiver mReceiver;
private ProgressDialog progressDialog;
private ReadonlyDataManager dataManager;
private View progressSpinner;
private ItemSelectedListener<EventBase> eventSelectionListener = new ItemSelectedListener<EventBase>() {
@@ -156,7 +155,7 @@ public class LoginActivity extends BaseActivity
switchToRacingActivity();
}
private void switchToRacingActivity(){
private void switchToRacingActivity() {
Intent intent = new Intent(LoginActivity.this, RacingActivity.class);
intent.putExtra(AppConstants.COURSE_AREA_UUID_KEY, mSelectedCourseAreaUUID);
intent.putExtra(AppConstants.EventIdTag, mSelectedEventId);
@@ -327,7 +326,6 @@ public class LoginActivity extends BaseActivity
updateSignInButtonState();
}
@Override
public void onResume() {
super.onResume();
@@ -336,15 +334,14 @@ public class LoginActivity extends BaseActivity
filter.addAction(AppConstants.INTENT_ACTION_RESET);
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filter);
Intent intent = new Intent();
intent.setAction(AppConstants.INTENT_ACTION_RESET);
Intent intent = new Intent(AppConstants.INTENT_ACTION_RESET);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (!BuildConfig.DEBUG) {
if (resultCode != ConnectionResult.SUCCESS) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices).show();
GooglePlayServicesUtil.getErrorDialog(resultCode, this, 1).show();
}
}
}
@@ -359,11 +356,11 @@ public class LoginActivity extends BaseActivity
@Override
public void onStop() {
super.onStop();
dismissProgressDialog();
dismissProgressSpinner();
}
private void setupDataManager() {
showProgressDialog();
showProgressSpinner();
DeviceConfigurationIdentifier identifier = new DeviceConfigurationIdentifierImpl(AppPreferences.on(getApplicationContext())
.getDeviceIdentifier());
@@ -372,7 +369,8 @@ public class LoginActivity extends BaseActivity
@Override
public void onLoadFailed(Exception reason) {
dismissProgressDialog();
dismissProgressSpinner();
if (reason instanceof FileNotFoundException) {
Toast.makeText(getApplicationContext(), getString(R.string.loading_configuration_not_found), Toast.LENGTH_LONG).show();
ExLog.w(LoginActivity.this, TAG, String.format("There seems to be no configuration for this device: %s", reason.toString()));
@@ -381,21 +379,17 @@ public class LoginActivity extends BaseActivity
ExLog.ex(LoginActivity.this, TAG, reason);
}
// Slide up, if events are available
if (!dataManager.getDataStore().getEvents().isEmpty()) {
slideUpBackdropDelayed();
}
slideUpBackdropDelayed();
}
@Override
public void onLoadSucceeded(DeviceConfiguration configuration, boolean isCached) {
dismissProgressDialog();
dismissProgressSpinner();
// this is our 'global' configuration, let's store it in app preferences
PreferencesDeviceConfigurationLoader.wrap(configuration, preferences).store();
Toast.makeText(LoginActivity.this, getString(R.string.loading_configuration_succeded), Toast.LENGTH_LONG).show();
// showCourseAreaListFragment(eventId);
slideUpBackdropDelayed();
}
});
@@ -404,23 +398,22 @@ public class LoginActivity extends BaseActivity
// always reload the configuration...
getLoaderManager().restartLoader(0, null, configurationLoader).forceLoad();
} else {
dismissProgressDialog();
dismissProgressSpinner();
}
}
private void showProgressDialog() {
if (progressDialog == null) {
progressDialog = new ProgressDialog(this);
progressDialog.setMessage(getString(R.string.loading_configuration));
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(true);
private void showProgressSpinner() {
if (progressSpinner == null) {
progressSpinner = findViewById(R.id.progress_spinner);
}
if (progressSpinner != null) {
progressSpinner.setVisibility(View.VISIBLE);
}
progressDialog.show();
}
private void dismissProgressDialog() {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
private void dismissProgressSpinner() {
if (progressSpinner != null && progressSpinner.getVisibility() == View.VISIBLE) {
progressSpinner.setVisibility(View.GONE);
}
}
@@ -450,26 +443,13 @@ public class LoginActivity extends BaseActivity
if (backdrop.getY() != 0) {
return;
}
long aniTime = getResources().getInteger(android.R.integer.config_longAnimTime);
final View bottomView = findViewById(R.id.login_listview);
View title = findViewById(R.id.backdrop_title);
View subTitle = findViewById(R.id.backdrop_subtitle);
View info = findViewById(R.id.technical_info);
View settings = findViewById(R.id.settings_button);
subTitle.setAlpha(0f);
ObjectAnimator frameAnimation = ObjectAnimator.ofFloat(backdrop, "y", 0, -backdrop.getHeight() + (backdrop.getHeight() / 5));
ObjectAnimator titleAnimation = ObjectAnimator.ofFloat(title, "alpha", 1f, 0f);
ObjectAnimator subTitleAnimation = ObjectAnimator.ofFloat(subTitle, "alpha", 0f, 1f);
ObjectAnimator infoAnimation = ObjectAnimator.ofFloat(info, "alpha", 0f, 1f);
ObjectAnimator settingsAnimation = ObjectAnimator.ofFloat(settings, "alpha", 0f, 1f);
ValueAnimator heightAnimation = ValueAnimator.ofInt(0, backdrop.getHeight() - (backdrop.getHeight() / 5));
heightAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
View bottomView = findViewById(R.id.login_listview);
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = bottomView.getLayoutParams();
layoutParams.height = val;
@@ -477,13 +457,30 @@ public class LoginActivity extends BaseActivity
}
});
Collection<Animator> animators = new ArrayList<>();
animators.add(heightAnimation);
animators.add(frameAnimation);
animators.add(getAlphaRevAnimator(findViewById(R.id.backdrop_title)));
animators.add(getAlphaAnimator(findViewById(R.id.backdrop_subtitle)));
animators.add(getAlphaAnimator(findViewById(R.id.refresh_data)));
animators.add(getAlphaAnimator(findViewById(R.id.technical_info)));
animators.add(getAlphaAnimator(findViewById(R.id.settings_button)));
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(heightAnimation, frameAnimation, titleAnimation, subTitleAnimation, infoAnimation, settingsAnimation);
animatorSet.setDuration(aniTime);
animatorSet.playTogether(animators);
animatorSet.setDuration(getResources().getInteger(android.R.integer.config_longAnimTime));
animatorSet.setInterpolator(new AccelerateDecelerateInterpolator());
animatorSet.start();
}
private ObjectAnimator getAlphaAnimator(@Nullable Object target) {
return ObjectAnimator.ofFloat(target, "alpha", 0f, 1f);
}
private ObjectAnimator getAlphaRevAnimator(@Nullable Object target) {
return ObjectAnimator.ofFloat(target, "alpha", 1f, 0f);
}
private class BackdropClick implements View.OnClickListener {
@Override
public void onClick(View view) {
@@ -3,11 +3,13 @@ package com.sap.sailing.racecommittee.app.ui.fragments;
import android.app.Fragment;
import android.content.Intent;
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.RelativeLayout;
import com.sap.sailing.racecommittee.app.AppConstants;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.ui.activities.PreferenceActivity;
import com.sap.sailing.racecommittee.app.ui.activities.SystemInformationActivity;
@@ -22,7 +24,7 @@ public class LoginBackdrop extends Fragment {
ImageView button = (ImageView) layout.findViewById(R.id.settings_button);
if (button != null) {
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), PreferenceActivity.class);
@@ -44,6 +46,17 @@ public class LoginBackdrop extends Fragment {
});
}
ImageView refresh = (ImageView) layout.findViewById(R.id.refresh_data);
if (refresh != null) {
refresh.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(AppConstants.INTENT_ACTION_RESET);
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);
}
});
}
return layout;
}
}
@@ -43,7 +43,6 @@ public abstract class NamedListFragment<T extends Named> extends LoggableListFra
protected abstract LoaderCallbacks<DataLoaderResult<Collection<T>>> createLoaderCallbacks(ReadonlyDataManager manager);
private void loadItems() {
setListShown(false);
setupLoader();
}
@@ -98,7 +97,6 @@ public abstract class NamedListFragment<T extends Named> extends LoggableListFra
@Override
public void onLoadFailed(Exception reason) {
setListShown(true);
namedList.clear();
listAdapter.notifyDataSetChanged();
@@ -113,7 +111,6 @@ public abstract class NamedListFragment<T extends Named> extends LoggableListFra
@Override
public void onLoadSucceeded(Collection<T> data, boolean isCached) {
setListShown(true);
namedList.clear();
//TODO: Quickfix for 2889
if (data != null) {
@@ -1,26 +1,16 @@
package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import android.widget.*;
import com.sap.sailing.android.shared.util.ViewHolder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishingTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder;
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.AndroidRaceLogResolver;
import com.sap.sailing.racecommittee.app.domain.impl.Result;
import com.sap.sailing.racecommittee.app.ui.adapters.MoreFlagsAdapter;
import com.sap.sailing.racecommittee.app.ui.adapters.MoreFlagsAdapter.MoreFlag;
import com.sap.sailing.racecommittee.app.ui.adapters.MoreFlagsAdapter.MoreFlagItemClick;
@@ -29,6 +19,9 @@ import com.sap.sailing.racecommittee.app.utils.ThemeHelper;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class MoreFlagsFragment extends BaseFragment implements MoreFlagItemClick {
private MoreFlagsAdapter mAdapter;
@@ -217,45 +210,27 @@ public class MoreFlagsFragment extends BaseFragment implements MoreFlagItemClick
}
private void setFinishTime(TimePoint finishTime) {
Result result = new Result();
switch (getArguments().getInt(START_MODE, 0)) {
case 1: // Race-State: Finishing -> End Finishing
setFinishedTime(finishTime);
if (RaceLogRaceStatus.FINISHING.equals(getRace().getStatus())) {
result = getRace().setFinishedTime(finishTime);
} else {
result.setError(R.string.error_wrong_race_state, RaceLogRaceStatus.FINISHING.name(), getRace().getStatus().name());
}
break;
default: // Race-State: Running -> Start Finishing
setFinishingTime(finishTime);
if (RaceLogRaceStatus.RUNNING.equals(getRace().getStatus())) {
result = getRace().setFinishingTime(finishTime);
} else {
result.setError(R.string.error_wrong_race_state, RaceLogRaceStatus.RUNNING.name(), getRace().getStatus().name());
}
break;
}
}
private void setFinishingTime(TimePoint finishTime) {
StartTimeFinder stf = new StartTimeFinder(new AndroidRaceLogResolver(), getRace().getRaceLog());
if (stf.analyze() != null && getRace().getStatus().equals(RaceLogRaceStatus.RUNNING)) {
if (finishTime.after(MillisecondsTimePoint.now())) {
Toast.makeText(getActivity(), "The selected time is in the future. Please recheck the time.", Toast.LENGTH_LONG).show();
} else {
if (stf.analyze().getStartTime().before(finishTime)) {
getRaceState().setFinishingTime(finishTime);
} else {
Toast.makeText(getActivity(), "The selected time is before the race start.", Toast.LENGTH_LONG).show();
}
}
}
}
private void setFinishedTime(TimePoint finishTime) {
FinishingTimeFinder ftf = new FinishingTimeFinder(getRace().getRaceLog());
if (ftf.analyze() != null && getRace().getStatus().equals(RaceLogRaceStatus.FINISHING)) {
if (finishTime.after(MillisecondsTimePoint.now())) {
Toast.makeText(getActivity(), "The given finish time is in the future. Please recheck the time.", Toast.LENGTH_LONG).show();
} else {
if (ftf.analyze().before(finishTime)) {
getRaceState().setFinishedTime(finishTime);
} else {
Toast.makeText(getActivity(), "The given finish time is earlier than than the first finisher time. Please recheck the time.", Toast.LENGTH_LONG).show();
}
}
if (result.hasError()) {
Toast.makeText(getActivity(), result.getMessageId(), Toast.LENGTH_LONG).show();
}
}
}
@@ -50,6 +50,36 @@ public class RaceSummaryFragment extends BaseFragment {
mRegionWind = ViewHolder.get(layout, R.id.region_wind);
mRegionRecall = ViewHolder.get(layout, R.id.region_individual_recalls);
View editStartTime = ViewHolder.get(layout, R.id.edit_race_start_time);
if (editStartTime != null) {
editStartTime.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
replaceFragment(RaceTimeChangeFragment.newInstance(RaceTimeChangeFragment.START_TIME_MODE), R.id.finished_content);
}
});
}
View editFinishingTime = ViewHolder.get(layout, R.id.edit_race_finish_begin_time);
if (editFinishingTime != null) {
editFinishingTime.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
replaceFragment(RaceTimeChangeFragment.newInstance(RaceTimeChangeFragment.FINISHING_TIME_MODE), R.id.finished_content);
}
});
}
View editFinishedTime = ViewHolder.get(layout, R.id.edit_race_finish_end_time);
if (editFinishedTime != null) {
editFinishedTime.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
replaceFragment(RaceTimeChangeFragment.newInstance(RaceTimeChangeFragment.FINISHED_TIME_MODE), R.id.finished_content);
}
});
}
return layout;
}
@@ -0,0 +1,189 @@
package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo;
import android.content.Intent;
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.NumberPicker;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import com.sap.sailing.racecommittee.app.AppConstants;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.domain.impl.Result;
import com.sap.sailing.racecommittee.app.utils.ThemeHelper;
import com.sap.sailing.racecommittee.app.utils.TimeUtils;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import java.util.Calendar;
public class RaceTimeChangeFragment extends BaseFragment implements View.OnClickListener {
public final static int START_TIME_MODE = 0;
public final static int FINISHING_TIME_MODE = 1;
public final static int FINISHED_TIME_MODE = 2;
private final static String START_MODE = "startMode";
private static final int FUTURE_DAYS = 3;
private static final int PAST_DAYS = -3;
private NumberPicker mDatePicker;
private TimePicker mTimePicker;
private NumberPicker mSecondPicker;
public static RaceTimeChangeFragment newInstance(int mode) {
RaceTimeChangeFragment fragment = new RaceTimeChangeFragment();
Bundle args = new Bundle();
args.putInt(START_MODE, mode);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.race_time_change, container, false);
return layout;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
View layout = getView();
if (layout == null) {
return;
}
final Calendar calendar = Calendar.getInstance();
TextView headerText = (TextView) layout.findViewById(R.id.header_headline);
if (headerText != null) {
switch (getArguments().getInt(START_MODE, 0)) {
case FINISHING_TIME_MODE:
calendar.setTime(getRaceState().getFinishingTime().asDate());
headerText.setText(getString(R.string.race_summary_finish_begin));
break;
case FINISHED_TIME_MODE:
calendar.setTime(getRaceState().getFinishedTime().asDate());
headerText.setText(getString(R.string.race_summary_finish_end));
break;
default: // START_TIME_MODE
calendar.setTime(getRaceState().getStartTime().asDate());
headerText.setText(getString(R.string.race_summary_start));
break;
}
}
mDatePicker = (NumberPicker) layout.findViewById(R.id.date_picker);
if (mDatePicker != null) {
ThemeHelper.setPickerTextColor(getActivity(), mDatePicker, ThemeHelper.getColor(getActivity(), R.attr.white));
TimeUtils.initDatePicker(getActivity(), mDatePicker, calendar, PAST_DAYS, FUTURE_DAYS, false);
mDatePicker.setValue(Math.abs(PAST_DAYS));
mDatePicker.setTag(calendar);
}
mTimePicker = (TimePicker) layout.findViewById(R.id.time_picker);
if (mTimePicker != null) {
ThemeHelper.setPickerTextColor(getActivity(), mTimePicker, ThemeHelper.getColor(getActivity(), R.attr.white));
mTimePicker.setIs24HourView(true);
mTimePicker.setCurrentHour(calendar.get(Calendar.HOUR_OF_DAY));
mTimePicker.setCurrentMinute(calendar.get(Calendar.MINUTE));
}
mSecondPicker = (NumberPicker) layout.findViewById(R.id.second_picker);
if (mSecondPicker != null) {
ThemeHelper.setPickerTextColor(getActivity(), mTimePicker, ThemeHelper.getColor(getActivity(), R.attr.white));
mSecondPicker.setVisibility(View.VISIBLE);
mSecondPicker.setMinValue(0);
mSecondPicker.setMaxValue(59);
mSecondPicker.setValue(calendar.get(Calendar.SECOND));
mSecondPicker.setFormatter(new NumberPicker.Formatter() {
@Override
public String format(int i) {
return String.format("%02d", i);
}
});
mSecondPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
if (mTimePicker != null) {
Calendar pickerTime = (Calendar) calendar.clone();
pickerTime.set(Calendar.HOUR_OF_DAY, mTimePicker.getCurrentHour());
pickerTime.set(Calendar.MINUTE, mTimePicker.getCurrentMinute());
if (oldVal == 0 && newVal == 59) {
pickerTime.add(Calendar.MINUTE, -1);
}
if (oldVal == 59 && newVal == 0) {
pickerTime.add(Calendar.MINUTE, 1);
}
mTimePicker.setCurrentHour(pickerTime.get(Calendar.HOUR_OF_DAY));
mTimePicker.setCurrentMinute(pickerTime.get(Calendar.MINUTE));
}
}
});
}
View setTime = layout.findViewById(R.id.set_date_time);
if (setTime != null) {
setTime.setOnClickListener(this);
}
View header = layout.findViewById(R.id.header);
if (header != null) {
header.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
closeFragment();
}
});
}
}
@Override
public void onClick(View v) {
TimePoint time = getPickerTime();
Result result;
switch (getArguments().getInt(START_MODE)) {
case FINISHING_TIME_MODE:
result = getRace().setFinishingTime(time);
if (result.hasError()) {
Toast.makeText(getActivity(), result.getMessage(getActivity()), Toast.LENGTH_LONG).show();
}
break;
case FINISHED_TIME_MODE:
result = getRace().setFinishedTime(time);
if (result.hasError()) {
Toast.makeText(getActivity(), result.getMessage(getActivity()), Toast.LENGTH_LONG).show();
}
break;
default: // START_TIME_MODE
getRaceState().forceNewStartTime(MillisecondsTimePoint.now(), time);
break;
}
closeFragment();
}
private TimePoint getPickerTime() {
Calendar calendar = (Calendar) mDatePicker.getTag();
calendar.add(Calendar.DAY_OF_MONTH, mDatePicker.getValue() + PAST_DAYS);
calendar.set(Calendar.HOUR_OF_DAY, mTimePicker.getCurrentHour());
calendar.set(Calendar.MINUTE, mTimePicker.getCurrentMinute());
calendar.set(Calendar.SECOND, mSecondPicker.getValue());
calendar.set(Calendar.MILLISECOND, 0);
return new MillisecondsTimePoint(calendar.getTime());
}
private void closeFragment() {
Intent intent = new Intent(AppConstants.INTENT_ACTION_SHOW_SUMMARY_CONTENT);
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);
}
}
@@ -1,7 +1,6 @@
package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.view.LayoutInflater;
@@ -25,8 +24,6 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import java.io.Serializable;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
public class StartTimeFragment extends BaseFragment
@@ -89,7 +86,7 @@ public class StartTimeFragment extends BaseFragment
mMinuteDec.setOnClickListener(this);
}
Button setStart = ViewHolder.get(layout, R.id.set_start_time);
Button setStart = ViewHolder.get(layout, R.id.set_date_time);
if (setStart != null) {
setStart.setOnClickListener(this);
}
@@ -173,13 +170,14 @@ public class StartTimeFragment extends BaseFragment
}
}
mDatePicker = ViewHolder.get(getView(), R.id.start_date_picker);
mDatePicker = ViewHolder.get(getView(), R.id.date_picker);
if (mDatePicker != null) {
ThemeHelper.setPickerTextColor(getActivity(), mDatePicker, ThemeHelper.getColor(getActivity(), R.attr.white));
mDatePicker.setOnValueChangedListener(this);
initDatePicker(time);
TimeUtils.initDatePicker(getActivity(), mDatePicker, time, PAST_DAYS, FUTURE_DAYS);
mDatePicker.setValue(Math.abs(PAST_DAYS));
}
mTimePicker = ViewHolder.get(getView(), R.id.start_time_picker);
mTimePicker = ViewHolder.get(getView(), R.id.time_picker);
if (mTimePicker != null) {
ThemeHelper.setPickerTextColor(getActivity(), mTimePicker, ThemeHelper.getColor(getActivity(), R.attr.white));
mTimePicker.setOnTimeChangedListener(this);
@@ -238,13 +236,14 @@ public class StartTimeFragment extends BaseFragment
mTimeRight.add(Calendar.MINUTE, -1);
timeRight = TimeUtils.formatDurationSince(mTimeRight.getTimeInMillis());
}
}
if (mCountdown != null) {
String countdown = getString(resId).replace("#TIME#", time);
mCountdown.setText(countdown);
mCountdown.setTag(resId);
}
if (mMinuteDec != null) {
String countdown = getString(resId).replace("#TIME#", timeLeft);
if (countdown.equals("-00:00:00")) {
@@ -252,6 +251,7 @@ public class StartTimeFragment extends BaseFragment
}
mMinuteDec.setText(countdown);
}
if (mMinuteInc != null) {
String countdown = getString(resId).replace("#TIME#", timeRight);
if (countdown.equals("-00:00:00")) {
@@ -315,7 +315,7 @@ public class StartTimeFragment extends BaseFragment
setPickerTime();
break;
case R.id.set_start_time:
case R.id.set_date_time:
changeFragment(mStartTime);
break;
@@ -366,40 +366,6 @@ public class StartTimeFragment extends BaseFragment
return new MillisecondsTimePoint(calendar.getTime());
}
private void initDatePicker(Calendar time) {
DateFormat dateFormat = DateFormat.getDateInstance();
ArrayList<String> dates = new ArrayList<>();
Calendar calendar = Calendar.getInstance();
// Past
calendar.add(Calendar.DAY_OF_MONTH, PAST_DAYS);
for (int i = PAST_DAYS; i < -1; i++) {
dates.add(dateFormat.format(calendar.getTime()));
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
dates.add(getString(R.string.yesterday));
dates.add(getString(R.string.today));
dates.add(getString(R.string.tomorrow));
// Future
calendar.add(Calendar.DAY_OF_MONTH, 2);
for (int i = 3; i <= FUTURE_DAYS + 1; i++) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
dates.add(dateFormat.format(calendar.getTime()));
}
mDatePicker.setDisplayedValues(dates.toArray(new String[dates.size()]));
mDatePicker.setMinValue(0);
mDatePicker.setMaxValue(dates.size() - 1);
mDatePicker.setWrapSelectorWheel(false);
mDatePicker.setValue(TimeUtils.daysBetween(time, Calendar.getInstance()) + Math.abs(PAST_DAYS));
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
TextView date = new TextView(getActivity());
date.setText(dateFormat.format(calendar.getTime()));
int padding = getResources().getDimensionPixelSize(R.dimen.default_padding_half);
date.setPadding(padding, padding, padding, padding);
date.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
mDatePicker.getLayoutParams().width = date.getMeasuredWidth();
}
}
private void changeFragment() {
changeFragment(null);
}
@@ -1,12 +1,18 @@
package com.sap.sailing.racecommittee.app.utils;
import java.util.Calendar;
import android.content.Context;
import android.os.Build;
import android.text.format.DateFormat;
import android.view.View;
import android.widget.NumberPicker;
import android.widget.TextView;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import java.util.ArrayList;
import java.util.Calendar;
public class TimeUtils {
private TimeUtils() {
@@ -16,19 +22,21 @@ public class TimeUtils {
public static long timeUntil(TimePoint targetTime) {
return targetTime.asMillis() - MillisecondsTimePoint.now().asMillis();
}
/**
* Formats your time to 'kk:mm:ss'.
*
* @param timePoint timestamp to format
*/
public static String formatTime(TimePoint timePoint) {
return formatTime(timePoint, "kk:mm:ss");
}
/**
* Formats your time with the help of {@link DateFormat}.
*
* @param timePoint timestamp to format
* @param format format as defined by {@link DateFormat}
* @param format format as defined by {@link DateFormat}
* @return timestamp formatted as {@link String}
*/
public static String formatTime(TimePoint timePoint, String format) {
@@ -39,7 +47,7 @@ public class TimeUtils {
int secondsTillStart = (int) Math.floor(milliseconds / 1000f);
return formatDuration(secondsTillStart);
}
public static String formatDurationUntil(long milliseconds) {
int secondsTillStart = (int) Math.ceil(milliseconds / 1000f);
return formatDuration(secondsTillStart);
@@ -73,7 +81,7 @@ public class TimeUtils {
return calendar;
}
public static int daysBetween(Calendar day1, Calendar day2){
public static int daysBetween(Calendar day1, Calendar day2) {
Calendar dayOne = (Calendar) day1.clone();
Calendar dayTwo = (Calendar) day2.clone();
@@ -109,4 +117,50 @@ public class TimeUtils {
String hoursString = hours < 10 ? "0" + Math.abs(hours) : "" + Math.abs(hours);
return String.format(timePattern, hoursString, minutesString, secondsString);
}
}
public static void initDatePicker(Context context, NumberPicker datePicker, Calendar time, int pastDays, int futureDays) {
initDatePicker(context, datePicker, time, pastDays, futureDays, true);
}
public static void initDatePicker(Context context, NumberPicker datePicker, Calendar time, int pastDays, int futureDays, boolean useWords) {
java.text.DateFormat dateFormat = java.text.DateFormat.getDateInstance();
ArrayList<String> dates = new ArrayList<>();
Calendar calendar = Calendar.getInstance();
calendar.setTime(time.getTime());
// Past
calendar.add(Calendar.DAY_OF_MONTH, pastDays);
for (int i = pastDays; i < -1; i++) {
dates.add(dateFormat.format(calendar.getTime()));
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
if (useWords) {
dates.add(context.getString(R.string.yesterday));
dates.add(context.getString(R.string.today));
dates.add(context.getString(R.string.tomorrow));
calendar.add(Calendar.DAY_OF_MONTH, 3);
} else {
for (int i = 0; i < 3; i++) {
dates.add(dateFormat.format(calendar.getTime()));
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
}
// Future
for (int i = 3; i <= futureDays + 1; i++) {
dates.add(dateFormat.format(calendar.getTime()));
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
datePicker.setDisplayedValues(dates.toArray(new String[dates.size()]));
datePicker.setMinValue(0);
datePicker.setMaxValue(dates.size() - 1);
datePicker.setWrapSelectorWheel(false);
datePicker.setValue(TimeUtils.daysBetween(calendar, Calendar.getInstance()) + Math.abs(pastDays));
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
TextView date = new TextView(context);
date.setText(dateFormat.format(calendar.getTime()));
int padding = context.getResources().getDimensionPixelSize(R.dimen.default_padding_half);
date.setPadding(padding, padding, padding, padding);
date.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
datePicker.getLayoutParams().width = date.getMeasuredWidth();
}
}
}
@@ -1,16 +1,16 @@
package com.sap.sailing.racecommittee.app.domain.impl;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.SeriesBase;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.racegroup.RaceGroup;
import com.sap.sailing.domain.base.racegroup.impl.RaceGroupImpl;
import com.sap.sailing.racecommittee.app.domain.ManagedRaceIdentifier;
import com.sap.sse.common.Util.Triple;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* This test verifies the algorithm used to escape and unescape SimpleRaceIdentifier components as used in
@@ -22,18 +22,18 @@ import com.sap.sse.common.Util.Triple;
public class SimpleRaceIdentifierEscapingTest {
@Test
public void testUnescapingSimpleRaceIdentifier() {
test("Leaderboard with trailing backslash and dot\\.", "empty", "fleet", "raceColumn");
test("Leaderboard\\.with\\.two dots", "empty", "fleet", "raceColumn");
test("Leaderboard with double backslash\\\\", "empty", "fleet", "raceColumn");
test("Leaderboard with double backslash and dot\\\\.", "empty", "fleet", "raceColumn");
test("\\Leaderboard with leading backslash", "empty", "fleet", "raceColumn");
test("\\.Leaderboard with leading backslash and dot", "empty", "fleet", "raceColumn");
test("\\\\.Leaderboard with leading double backslash and dot", "empty", "fleet", "raceColumn");
test("\\\\.Leaderboard with leading double backslash and two dots", "empty", "fleet", "raceColumn");
test("Leaderboard with trailing backslash and dot\\.", "series", "fleet", "raceColumn");
test("Leaderboard\\.with\\.two dots", "series", "fleet", "raceColumn");
test("Leaderboard with double backslash\\\\", "series", "fleet", "raceColumn");
test("Leaderboard with double backslash and dot\\\\.", "series", "fleet", "raceColumn");
test("\\Leaderboard with leading backslash", "series", "fleet", "raceColumn");
test("\\.Leaderboard with leading backslash and dot", "series", "fleet", "raceColumn");
test("\\\\.Leaderboard with leading double backslash and dot", "series", "fleet", "raceColumn");
test("\\\\.Leaderboard with leading double backslash and two dots", "series", "fleet", "raceColumn");
}
private void test(String leaderboardName, String empty, String fleetName, String raceColumnName) {
final String marshalled = build(leaderboardName, empty, fleetName, raceColumnName);
private void test(String leaderboardName, String seriesName, String fleetName, String raceColumnName) {
final String marshalled = build(leaderboardName, seriesName, fleetName, raceColumnName);
final Triple<String, String, String> parsed = FleetIdentifierImpl.unescape(marshalled);
assertEquals(leaderboardName, parsed.getA());
assertEquals(raceColumnName, parsed.getB());
@@ -41,30 +41,14 @@ public class SimpleRaceIdentifierEscapingTest {
}
private String build(final String leaderboardName, final String seriesName, final String fleetName, final String raceColumnName) {
final Fleet fleet = new FleetImpl(fleetName);
final SeriesBase series = new SeriesBase() {
private static final long serialVersionUID = 1139740910228343375L;
Fleet fleet = mock(Fleet.class);
SeriesBase series = mock(SeriesBase.class);
RaceGroup raceGroup = mock(RaceGroupImpl.class);
when(fleet.getName()).thenReturn(fleetName);
when(series.getName()).thenReturn(seriesName);
when(raceGroup.getName()).thenReturn(leaderboardName);
@Override
public String getName() {
return seriesName;
}
@Override
public void setName(String newName) {
}
@Override
public boolean isMedal() {
return false;
}
@Override
public Iterable<? extends Fleet> getFleets() {
return null;
}
};
RaceGroup raceGroup = new RaceGroupImpl(leaderboardName, /* displayName */ null, /* boatClass */ null, /* courseArea */ null, /* series */ null, /* regattaConfiguration */ null);
ManagedRaceIdentifier identifier = new ManagedRaceIdentifierImpl(raceColumnName, fleet, series, raceGroup);
return identifier.getId();
}
+4
View File
@@ -33,6 +33,10 @@ preBuild.doLast {
git_branch_or_tag = git_tag.toString().trim()
}
if (git_branch_or_tag.size() == 0) {
git_branch_or_tag = "HEAD"
}
def build_time = new Date().toString()
// save the combined build info into assets/build.info file
+22 -17
View File
@@ -9,39 +9,44 @@ We run four servers for the event:
for fast and available switching. The DB they use is called `KW2015`, and so is the replication channel. The git branch we use to merge the features we want to deploy to the event servers is called `kielerwoche2015` and the git tag used to build a release for it is called `kielerwoche2015-release`. See http://hudson.sapsailing.com/job/SAPSailingAnalytics-kielerwoche2015/ and http://hudson.sapsailing.com/job/SAPSailingAnalytics-kielerwoche2015-release/, respectively, for their Hudson jobs.
### Master 1 Server (32GB)
- Admin Console at http://ec2-54-154-151-10.eu-west-1.compute.amazonaws.com:8888/gwt/AdminConsole.html
- External IP: 54.154.151.10
- Internal IP: 172.31.24.187
### Master 1 Server (32GB, STOPPED)
### Master 2 Server (32GB)
- Admin Console at http://ec2-54-76-169-213.eu-west-1.compute.amazonaws.com:8888/gwt/AdminConsole.html
- External IP: 54.76.169.213
- Internal IP: 172.31.30.73
### Master 2 Server (32GB, STOPPED)
### Master 3 Server (64GB)
- Admin Console at http://ec2-54-171-148-10.eu-west-1.compute.amazonaws.com:8888/gwt/AdminConsole.html
- External IP: 54.171.148.10
- Internal IP: 172.31.26.119
### Master 4 Server (60GB)
- Admin Console at http://ec2-54-154-151-158.eu-west-1.compute.amazonaws.com:8888/gwt/AdminConsole.html
- External IP: 54.154.151.158
- Internal IP: 172.31.18.24
### "Current" Master
Whichever master is current, we map the main Apache URL http://kielerwoche2015-master.sapsailing.com to it. This is also the URL to use for Tablet and Smartphone configurations.
### Replica 1 server
- Admin Console at http://ec2-54-72-226-124.eu-west-1.compute.amazonaws.com:8888/gwt/AdminConsole.html
- External IP: 54.72.226.124
- Internal IP: 172.31.20.11
### Replica 1 server (STOPPED)
### Replica 2 server
- Admin Console at http://ec2-54-154-175-180.eu-west-1.compute.amazonaws.com:8888/gwt/AdminConsole.html
- External IP: 54.154.175.180
- Internal IP: 172.31.20.12
### Replica 2 server (STOPPED)
### Replica 3 Server (60GB)
- Admin Console at http://ec2-54-171-99-97.eu-west-1.compute.amazonaws.com:8888/gwt/AdminConsole.html
- External IP: 54.171.99.97
- Internal IP: 172.31.19.218
### Replica 4 Server (60GB)
- Admin Console at http://ec2-54-154-142-170.eu-west-1.compute.amazonaws.com:8888/gwt/AdminConsole.html
- External IP: 54.154.142.170
- Internal IP: 172.31.18.23
## TracTrac URL
- http://event.tractrac.com/events/event_20150616_KielerWoch/jsonservice.php for the Olympic Week
- http://event.tractrac.com/events/event_20150625_KielerWoch/jsonservice.php for the International Week
- http://club.tractrac.com/events/event_20150625_KielerWoch/jsonservice.php for the Silbernes Band
## Replication
- RabbitMQ server for replication: 52.16.112.6 (Web: http://52.16.112.6:15672/)
- RabbitMQ server for replication: 52.16.112.6 (Web: http://52.16.112.6:15672/) or internal host name rabbit.internal.sapsailing.com)
- Replication Exchange Name: KW2015
## Switching from one Master to Another