diff --git a/.gitignore b/.gitignore index 8a9ad2c573d..5b4b102919c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,35 @@ -/target -www-test -war -build.log -reporting.log -.metadata -*.class -*.swp -*~ -manifest.txt -java/com.sap.sailing.gwt.ui/gwt-unitCache/* -java/com.sap.sailing.gwt.ui/war/WEB-INF/deploy/* -java/com.sap.sse.security.ui/WEB-INF/deploy/* -sailing_debug0* -dist -build -/java/.settings/org.eclipse.jdt.core.prefs -/java/com.sap.sailing.server.gateway.serialization.test/.settings/*.prefs -.DS_Store -java/com.sap.sailing.simulator/bin/com/sap/sailing/simulator/Simulator.gwt.xml -/mobile/com.sap.sailing.racecommittee.app/res/values/keys.xml +/target +www-test +war +build.log +reporting.log +.metadata +*.class +*.swp +*~ +manifest.txt +java/com.sap.sailing.gwt.ui/gwt-unitCache/* +java/com.sap.sailing.gwt.ui/war/WEB-INF/deploy/* +java/com.sap.sse.security.ui/WEB-INF/deploy/* +sailing_debug0* +dist +build +/java/.settings/org.eclipse.jdt.core.prefs +/java/com.sap.sailing.server.gateway.serialization.test/.settings/*.prefs +.DS_Store +java/com.sap.sailing.simulator/bin/com/sap/sailing/simulator/Simulator.gwt.xml +/mobile/com.sap.sailing.racecommittee.app/res/values/keys.xml +java/com.sap.sailing.gwt.ui/SailingGWT Remote Profiling (Run-Mode only).launch +java/com.sap.sailing.gwt.ui/SailingGWT.launch + +## Android Studio and Intellij and Android in general +gen/ +.idea/ +*.ipr +*.iws +*.iml +out/ +.gradle +local.properties +git.xml +build.info diff --git a/Operating-Igtimi-WindBots/windbot-operations.md b/Operating-Igtimi-WindBots/windbot-operations.md index a7acb6b583f..0184705a8f7 100644 --- a/Operating-Igtimi-WindBots/windbot-operations.md +++ b/Operating-Igtimi-WindBots/windbot-operations.md @@ -2,6 +2,8 @@ For wind measurements we're trying to consistently use Igtimi WindBot equipment. The AdminConsole has a tab "Igtimi Accounts" where accounts for the Igtimi YachtBot web site can be managed. WindBots associated with any of these accounts will feed their wind readings, when active, into races being tracked. Operations of the WindBots mainly needs to take care of charging the devices, turning them on when they leave the harbor and turning them off when they leave the race course. This can also be delegated to race officials carrying these devices on their vessels. +# Status LEDs + The devices have three LEDs whose status works as follows: 1. The three LED’s are “power”, “connection”, and “GPS” in order from top to bottom. @@ -10,4 +12,16 @@ The devices have three LEDs whose status works as follows: 4. Fast flashing means that function can’t start or has failed - e.g. SIM not inserted. i.e. you shouldn’t see this 5. During sync, the “power” light blips and the “connection” LED should stay on until the sync has finished. -More information on running the WindBots can be found [here](https://igtimi.desk.com/customer/portal/articles/1494533-yachtbot-tracker-basic-operation?b_id=1690). \ No newline at end of file +More information on running the WindBots can be found [here](https://igtimi.desk.com/customer/portal/articles/1494533-yachtbot-tracker-basic-operation?b_id=1690). + +# Update Firmware + +[How to update the firmware](https://igtimi.desk.com/customer/portal/articles/1122866-how-to-update-the-firmware-in-the-yachtbot-trackers?b_id=1690) + +# WindBot User Guide (v. 1.0 R3) + +[User Guide v. 1.0 R3](wiki/uploads/WindBot%20User%20Guide%201.0%20R3.pdf) + +# Is the WindBot waterproof and does it sink if dropped it in the water? + +Yes and yes. \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000000..04c172858b7 --- /dev/null +++ b/build.gradle @@ -0,0 +1,22 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:1.0.0' + } +} + +allprojects { + repositories { + mavenCentral() + } + version = "1.0.0-SNAPSHOT" + tasks.withType(JavaCompile) { + sourceCompatibility = "1.7" + targetCompatibility = "1.7" + } +} diff --git a/configuration/androidWaitForEmulator.sh b/configuration/androidWaitForEmulator.sh new file mode 100755 index 00000000000..440ae64ff25 --- /dev/null +++ b/configuration/androidWaitForEmulator.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Originally written by Ralf Kistner , but placed in the public domain + +set +e + +bootanim="" +failcounter=0 +timeout_in_sec=600 + +until [[ "$bootanim" =~ "stopped" ]]; do + bootanim=`adb -e shell getprop init.svc.bootanim 2>&1 &` + if [[ "$bootanim" =~ "device not found" || "$bootanim" =~ "device offline" + || "$bootanim" =~ "running" ]]; then + let "failcounter += 1" + echo "Waiting for emulator to start" + if [[ $failcounter -gt timeout_in_sec ]]; then + echo "Timeout ($timeout_in_sec seconds) reached; failed to start emulator" + exit 1 + fi + fi + sleep 1 +done + +echo "Emulator is ready" diff --git a/configuration/buildAndUpdateProduct.sh b/configuration/buildAndUpdateProduct.sh index eb9c5e3fe87..e0c1f86847a 100755 --- a/configuration/buildAndUpdateProduct.sh +++ b/configuration/buildAndUpdateProduct.sh @@ -190,15 +190,20 @@ if [[ $@ == "" ]]; then exit 2 fi +rm $START_DIR/build.log if [[ "$@" == "clean" ]]; then + ./gradlew clean + if [[ $? != 0 ]]; then + exit 100 + fi cd $PROJECT_HOME/java rm -rf com.sap.$PROJECT_TYPE.gwt.ui/com.sap.$PROJECT_TYPE.* rm -rf com.sap.sse.security.ui/com.sap.sse.security.ui.* cd $PROJECT_HOME echo "Using following command: mvn $extra -DargLine=\"$APP_PARAMETERS\" -fae -s $MAVEN_SETTINGS $clean" echo "Maven version used: `mvn --version`" - mvn $extra -DargLine="$APP_PARAMETERS" -fae -s $MAVEN_SETTINGS $clean 2>&1 | tee $START_DIR/build.log + mvn $extra -DargLine="$APP_PARAMETERS" -fae -s $MAVEN_SETTINGS $clean 2>&1 | tee -a $START_DIR/build.log MVN_EXIT_CODE=${PIPESTATUS[0]} echo "Maven exit code is $MVN_EXIT_CODE" exit 0 @@ -533,8 +538,10 @@ if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then echo "INFO: Activating proxy profile" extra="$extra -P no-debug.with-proxy" MAVEN_SETTINGS=$MAVEN_SETTINGS_PROXY + ANDROID_OPTIONS="--proxy-host proxy --proxy-port 8080" else extra="$extra -P no-debug.without-proxy" + ANDROID_OPTIONS="" fi cd $PROJECT_HOME/java @@ -570,7 +577,7 @@ if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then #build local p2 repo echo "Using following command (pwd: java/com.sap.sailing.targetplatform.base): mvn -fae -s $MAVEN_SETTINGS $clean compile" echo "Maven version used: `mvn --version`" - (cd com.sap.$PROJECT_TYPE.targetplatform.base; mvn -fae -s $MAVEN_SETTINGS $clean compile 2>&1 | tee $START_DIR/build.log) + (cd com.sap.$PROJECT_TYPE.targetplatform.base; mvn -fae -s $MAVEN_SETTINGS $clean compile 2>&1 | tee -a $START_DIR/build.log) # now get the exit status from mvn, and not that of tee which is what $? contains now MVN_EXIT_CODE=${PIPESTATUS[0]} echo "Maven exit code is $MVN_EXIT_CODE" @@ -612,6 +619,10 @@ if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then echo "ANDROID_HOME=$ANDROID_HOME" PATH=$PATH:$ANDROID_HOME/tools PATH=$PATH:$ANDROID_HOME/platform-tools + ANDROID="$ANDROID_HOME/tools/android" + if [ \! -x "$ANDROID" ]; then + ANDROID="$ANDROID_HOME/tools/android.bat" + fi RC_APP_VERSION=`grep "android:versionCode=" mobile/com.sap.$PROJECT_TYPE.racecommittee.app/AndroidManifest.xml | cut -d "\"" -f 2` echo "RC_APP_VERSION=$RC_APP_VERSION" @@ -620,6 +631,56 @@ if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then TRACKING_APP_VERSION=`grep "android:versionCode=" mobile/com.sap.$PROJECT_TYPE.android.tracking.app/AndroidManifest.xml | cut -d "\"" -f 2` echo "TRACKING_APP_VERSION=$TRACKING_APP_VERSION" extra="$extra -Dtracking-app-version=$TRACKING_APP_VERSION" + + NOW=$(date +"%s") + BUILD_TOOLS=22.0.0 + TARGET_API=22 + TEST_API=18 + ANDROID_ABI=armeabi-v7a + AVD_NAME="androidTest-${NOW}" + echo "Updating Android SDK (tools)..." | tee -a $START_DIR/build.log + echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter tools --no-ui --force --all > /dev/null + echo "Updating Android SDK (platform-tools)..." | tee -a $START_DIR/build.log + echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter platform-tools --no-ui --force --all > /dev/null + echo "Updating Android SDK (build-tools-${BUILD_TOOLS})..." | tee -a $START_DIR/build.log + echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter build-tools-${BUILD_TOOLS} --no-ui --force --all > /dev/null + echo "Updating Android SDK (android-${TARGET_API})..." | tee -a $START_DIR/build.log + echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter android-${TARGET_API} --no-ui --force --all > /dev/null + echo "Updating Android SDK (extra-android-m2repository)..." | tee -a $START_DIR/build.log + 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 + if [[ $? != 0 ]]; then + exit 100 + fi + # testing deactivated due to errors in hudson + if [ $testing -eq 1 ]; then + adb emu kill + echo "Downloading image (sys-img-${ANDROID_ABI}-android-${TEST_API})..." | tee -a $START_DIR/build.log + echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter sys-img-${ANDROID_ABI}-android-${TEST_API} --no-ui --force --all > /dev/null + echo no | "$ANDROID" create avd --name ${AVD_NAME} --target android-${TEST_API} --abi ${ANDROID_ABI} --force -p ${START_DIR}/emulator + echo "Starting emulator..." | tee -a $START_DIR/build.log + emulator -avd ${AVD_NAME} -no-skin -no-audio -no-window & + echo "Waiting for startup..." | tee -a $START_DIR/build.log + adb wait-for-device + sleep 60 + $PROJECT_HOME/configuration/androidWaitForEmulator.sh + if [[ $? != 0 ]]; then + adb emu kill + "$ANDROID" delete avd --name ${AVD_NAME} + exit 102 + fi + adb shell input keyevent 82 & + ./gradlew deviceCheck connectedCheck | tee -a $START_DIR/build.log + if [[ $? != 0 ]]; then + adb emu kill + "$ANDROID" delete avd --name ${AVD_NAME} + exit 101 + fi + adb emu kill + "$ANDROID" delete avd --name ${AVD_NAME} + fi else echo "INFO: Deactivating mobile modules" extra="$extra -P !with-mobile" @@ -636,7 +697,7 @@ if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then echo "Using following command: mvn $extra -DargLine=\"$APP_PARAMETERS\" -fae -s $MAVEN_SETTINGS $clean install" echo "Maven version used: `mvn --version`" - mvn $extra -DargLine="$APP_PARAMETERS" -fae -s $MAVEN_SETTINGS $clean install 2>&1 | tee $START_DIR/build.log + mvn $extra -DargLine="$APP_PARAMETERS" -fae -s $MAVEN_SETTINGS $clean install 2>&1 | tee -a $START_DIR/build.log # now get the exit status from mvn, and not that of tee which is what $? contains now MVN_EXIT_CODE=${PIPESTATUS[0]} echo "Maven exit code is $MVN_EXIT_CODE" diff --git a/configuration/sign_apps.sh b/configuration/sign_apps.sh new file mode 100755 index 00000000000..2b652d8c052 --- /dev/null +++ b/configuration/sign_apps.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +find_project_home () +{ + if [[ "$1" == '/' ]] || [[ "$1" == "" ]]; then + echo "" + return 0 + fi + + if [ ! -d "$1/.git" ]; then + PARENT_DIR="`cd "$1/..";pwd`" + OUTPUT=$(find_project_home "$PARENT_DIR") + + if [ "$OUTPUT" = "" ] && [ -d "$PARENT_DIR/$CODE_DIRECTORY" ] && [ -d "$PARENT_DIR/$CODE_DIRECTORY/.git" ]; then + OUTPUT="$PARENT_DIR/$CODE_DIRECTORY" + fi + echo $OUTPUT + return 0 + fi + + echo $1 | sed -e 's/\/cygdrive\/\([a-zA-Z]\)/\1:/' +} + +sign_apk() +{ + ALIAS=$1 + PROJECT_NAME=$2 + PROJECT_UNALIGNED=$PROJECT_NAME-unaligned.apk + + cd $PROJECT_HOME/mobile/$PROJECT_NAME/build/outputs/apk + rm $PROJECT_NAME.apk + cp $PROJECT_NAME-release-unsigned.apk $PROJECT_UNALIGNED + + jarsigner -verbose -tsa -sigalg SHA1withRSA -digestalg SHA1 -keystore $PROJECT_HOME/mobile/android-keystore/STG.jks $PROJECT_UNALIGNED $ALIAS + $ANDROID_HOME/build-tools/$BUILD_TOOLS/zipalign -v 4 $PROJECT_UNALIGNED $PROJECT_NAME.apk +} + +if [ $# -eq 0 ]; then + echo "Usage: $0 " + exit 2 +fi + +# this holds for default installation +BUILD_TOOLS="21.1.2" +USER_HOME=~ +START_DIR="`pwd`" + +if [ "$PROJECT_HOME" = "" ]; then + PROJECT_HOME=$(find_project_home "$START_DIR") +fi + +# if project_home is still empty we could not determine any suitable directory +if [[ "$PROJECT_HOME" == "" ]]; then + echo "Could neither determine nor get PROJECT_HOME. Please provide it by setting an environment variable with this name." + exit 1 +fi + +sign_apk $1 com.sap.sailing.android.tracking.app +sign_apk $1 com.sap.sailing.racecommittee.app diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000000..1d3591c8a4c --- /dev/null +++ b/gradle.properties @@ -0,0 +1,18 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000000..8c0fb64a869 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000..0c71e760dc9 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Apr 10 15:27:10 PDT 2013 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip diff --git a/gradlew b/gradlew new file mode 100755 index 00000000000..91a7e269e19 --- /dev/null +++ b/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000000..aec99730b4e --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/java/com.googlecode.java-diff-utils/build.gradle b/java/com.googlecode.java-diff-utils/build.gradle new file mode 100644 index 00000000000..f0a8d88d703 --- /dev/null +++ b/java/com.googlecode.java-diff-utils/build.gradle @@ -0,0 +1,7 @@ +apply plugin: "java" + +sourceSets { + main { + java.srcDirs = ["src"] + } +} diff --git a/java/com.sap.sailing.dashboards.gwt/RibDashboard.css b/java/com.sap.sailing.dashboards.gwt/RibDashboard.css index 5801933ad0e..ef3be51375d 100644 --- a/java/com.sap.sailing.dashboards.gwt/RibDashboard.css +++ b/java/com.sap.sailing.dashboards.gwt/RibDashboard.css @@ -77,4 +77,62 @@ height: 22.5pt; z-index: 1; } + +.wrongOrientationNotification { + position: absolute !important; + top: 50%; + right: 50%; + background-color: white; + z-index: 2; +} + +.wrongOrientationNotification_shown { + width: 200px; + height: 200px; + margin-right: -100px; + margin-top: -100px; + border-radius: 100px; + -webkit-transition: all 700ms cubic-bezier(0.480, 0, 0.000, 1); + /* older webkit */ + -webkit-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250); + -moz-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250); + -o-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250); + transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250); + opacity: 1.0; +} + +.wrongOrientationNotification_hidden { + width: 0px; + height: 0px; + marin-right: 0px; + margin-top: 0px; + border-radius: 0px; + overflow: hidden; + -webkit-transition: all 300ms; + /* older webkit */ + -webkit-transition: all 300ms; + -moz-transition: all 300ms; + -o-transition: all 300ms; + transition: all 300ms; + opacity: 0.0; +} + +.wrongOrientationNotification_logo { + max-width: 40%; + max-height: 40%; + margin: 30%; + margin-top: 23% +} + +.wrongOrientationNotification_text { + position: absolute; + width: 100%; + height: 14px; + top: 76%; + line-height: 10px; + text-align: center; + font-weight: bold; + font-size: 13px; + color: grey; + font-family: "Arial"; } \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/SailingDashboardsGWT.launch b/java/com.sap.sailing.dashboards.gwt/SailingDashboardsGWT.launch new file mode 100755 index 00000000000..f6c7bd03e29 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/SailingDashboardsGWT.launch @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com.sap.sailing.dashboards.gwt/WEB-INF/web.xml b/java/com.sap.sailing.dashboards.gwt/WEB-INF/web.xml index cb08850f5a8..46e9142f142 100644 --- a/java/com.sap.sailing.dashboards.gwt/WEB-INF/web.xml +++ b/java/com.sap.sailing.dashboards.gwt/WEB-INF/web.xml @@ -4,6 +4,20 @@ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> + + default + org.eclipse.jetty.servlet.DefaultServlet + + + dirAllowed + false + + + useFileMappedBuffer + false + + + Rib Dashboard Service RibDashboardService diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardEntryPoint.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardEntryPoint.java index 85d80d871c6..564c84d4e51 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardEntryPoint.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardEntryPoint.java @@ -8,6 +8,8 @@ import com.googlecode.mgwt.ui.client.MGWTSettings; import com.googlecode.mgwt.ui.client.MGWTSettings.StatusBarStyle; import com.googlecode.mgwt.ui.client.MGWTSettings.ViewPort; import com.googlecode.mgwt.ui.client.MGWTStyle; +import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetriever; +import com.sap.sailing.dashboards.gwt.client.dataretriever.WindBotDataRetriever; import com.sap.sailing.gwt.ui.client.SailingService; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; @@ -61,6 +63,6 @@ public class RibDashboardEntryPoint extends AbstractEntryPoint { @Override protected StringMessages createStringMessages() { - return GWT.create(StringMessages.class); + return StringMessages.INSTANCE; } } \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardImageResources.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardImageResources.java index ccd89fffb8a..9962fb67cfb 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardImageResources.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardImageResources.java @@ -41,4 +41,7 @@ public interface RibDashboardImageResources extends ClientBundle { @Source("images/settings.png") ImageResource settings(); + + @Source("images/rotatedevice.png") + ImageResource rotatedevice(); } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.java index 6ef44cc1011..f427de40676 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.java @@ -17,6 +17,12 @@ import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.LayoutPanel; import com.google.gwt.user.client.ui.Widget; import com.googlecode.mgwt.ui.client.widget.carousel.Carousel; +import com.sap.sailing.dashboards.gwt.client.dataretriever.NumberOfWindBotsChangeListener; +import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetriever; +import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetrieverListener; +import com.sap.sailing.dashboards.gwt.client.dataretriever.WindBotDataRetrieverProvider; +import com.sap.sailing.dashboards.gwt.client.eventlogo.EventLogo; +import com.sap.sailing.dashboards.gwt.client.notifications.WrongDeviceOrientationNotification; import com.sap.sailing.dashboards.gwt.client.startanalysis.StartlineAnalysisComponent; import com.sap.sailing.dashboards.gwt.client.startlineadvantage.StartLineAdvantageComponent; import com.sap.sailing.dashboards.gwt.client.windchart.WindBotComponent; @@ -89,9 +95,10 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr initWidget(uiBinder.createAndBindUi(this)); initLogos(); windcharthint.getElement().setInnerText(stringConstants.dashboardWindChartHint()); - windloadinghintleft.setInnerText(stringConstants.dashboardWindBotLoading()); - windloadinghintright.setInnerText(stringConstants.dashboardWindBotLoading()); - loadAndDisplayEventLogo(sailingServiceAsync); + windloadinghintleft.setInnerHTML(stringConstants.dashboardWindBotLoadingText()+"
"+stringConstants.dashboardWindBotLoadingMessage()); + windloadinghintright.setInnerHTML(stringConstants.dashboardWindBotLoadingText()+"
"+stringConstants.dashboardWindBotLoadingMessage()); + loadAndAddEventLogo(sailingServiceAsync); + initAndAddWrongOrientationNotification(); } private void initLogos() { @@ -101,7 +108,7 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr Document.get().getBody().appendChild(logo.getElement()); } - private void loadAndDisplayEventLogo(SailingServiceAsync sailingServiceAsync){ + private void loadAndAddEventLogo(SailingServiceAsync sailingServiceAsync){ String eventId = Window.Location.getParameter(EVENT_ID_PARAMETER); if (eventId != null) { EventLogo eventLogo = EventLogo.getEventLogoFromEventId(sailingServiceAsync, eventId); @@ -110,6 +117,11 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr } } } + + private void initAndAddWrongOrientationNotification(){ + WrongDeviceOrientationNotification wrongDeviceOrientationNotification = new WrongDeviceOrientationNotification(); + Document.get().getBody().appendChild(wrongDeviceOrientationNotification.getElement()); + } private void initWindBotComponents(List windBotIDs, WindBotDataRetrieverProvider windBotDataRetrieverProvider) { diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/NumberOfWindBotsChangeListener.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/NumberOfWindBotsChangeListener.java similarity index 76% rename from java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/NumberOfWindBotsChangeListener.java rename to java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/NumberOfWindBotsChangeListener.java index b2df0114d35..7417b78ec50 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/NumberOfWindBotsChangeListener.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/NumberOfWindBotsChangeListener.java @@ -1,4 +1,4 @@ -package com.sap.sailing.dashboards.gwt.client; +package com.sap.sailing.dashboards.gwt.client.dataretriever; import java.util.List; diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardDataRetriever.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/RibDashboardDataRetriever.java similarity index 97% rename from java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardDataRetriever.java rename to java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/RibDashboardDataRetriever.java index 6484878ec31..8a30861de5d 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardDataRetriever.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/RibDashboardDataRetriever.java @@ -1,4 +1,4 @@ -package com.sap.sailing.dashboards.gwt.client; +package com.sap.sailing.dashboards.gwt.client.dataretriever; import java.util.ArrayList; import java.util.Collections; @@ -7,6 +7,7 @@ import java.util.List; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; +import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync; import com.sap.sailing.dashboards.gwt.client.actions.GetRibDashboardRaceInfoAction; import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardDataRetrieverListener.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/RibDashboardDataRetrieverListener.java similarity index 81% rename from java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardDataRetrieverListener.java rename to java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/RibDashboardDataRetrieverListener.java index 652c939da0b..ee2e95944c1 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardDataRetrieverListener.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/RibDashboardDataRetrieverListener.java @@ -1,7 +1,7 @@ /** * */ -package com.sap.sailing.dashboards.gwt.client; +package com.sap.sailing.dashboards.gwt.client.dataretriever; import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO; diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/WindBotDataRetriever.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/WindBotDataRetriever.java similarity index 89% rename from java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/WindBotDataRetriever.java rename to java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/WindBotDataRetriever.java index 4d3503f7007..a202fa5a449 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/WindBotDataRetriever.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/WindBotDataRetriever.java @@ -1,8 +1,10 @@ -package com.sap.sailing.dashboards.gwt.client; +package com.sap.sailing.dashboards.gwt.client.dataretriever; import java.util.ArrayList; import java.util.Date; +import java.util.HashSet; import java.util.List; +import java.util.Set; import com.google.gwt.user.client.rpc.AsyncCallback; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; @@ -24,9 +26,13 @@ public class WindBotDataRetriever implements TimeListener, RaceSelectionChangeLi private List windBotDataRetrieverListeners; private List windBotIDsInLiveRace; - private static final int WIND_CHART_RESOLUTION_IN_MILLISECONDS = 5000; - public static final String LODA_WIND_CHART_DATA_CATEGORY = "loadWindChartData"; + private final Set windSourceTypeNames; + private final int WIND_CHART_RESOLUTION_IN_MILLISECONDS = 5000; + private final int ONE_HOUR_IN_MILLISECONDS = 1000*60*60; + private final String LODA_WIND_CHART_DATA_CATEGORY = "loadWindChartData"; private boolean didInitialLoading; + + public WindBotDataRetriever(SailingServiceAsync sailingService) { this.sailingService = sailingService; @@ -36,15 +42,17 @@ public class WindBotDataRetriever implements TimeListener, RaceSelectionChangeLi numberOfWindBotsChangeListeners = new ArrayList(); windBotDataRetrieverListeners = new ArrayList(); windBotIDsInLiveRace = new ArrayList(); + windSourceTypeNames = new HashSet<>(); + windSourceTypeNames.add(WindSourceType.EXPEDITION.name()); } private void loadWindBotData(Date from, Date to, RegattaAndRaceIdentifier selectedRaceIdentifier) { if(!didInitialLoading){ didInitialLoading = true; - from = new Date(from.getTime()-1000*60*15); + from = new Date(from.getTime()-ONE_HOUR_IN_MILLISECONDS); } GetWindInfoAction getWindInfoAction = new GetWindInfoAction(sailingService, selectedRaceIdentifier, from, to, - WIND_CHART_RESOLUTION_IN_MILLISECONDS, null, /* + WIND_CHART_RESOLUTION_IN_MILLISECONDS, windSourceTypeNames, /* * onlyUpToNewestEvent==true because we don't want to * overshoot the evidence so far */true); diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/WindBotDataRetrieverListener.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/WindBotDataRetrieverListener.java similarity index 74% rename from java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/WindBotDataRetrieverListener.java rename to java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/WindBotDataRetrieverListener.java index 0491e771f45..3392152ee2d 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/WindBotDataRetrieverListener.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/WindBotDataRetrieverListener.java @@ -1,4 +1,4 @@ -package com.sap.sailing.dashboards.gwt.client; +package com.sap.sailing.dashboards.gwt.client.dataretriever; import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO; diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/WindBotDataRetrieverProvider.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/WindBotDataRetrieverProvider.java similarity index 87% rename from java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/WindBotDataRetrieverProvider.java rename to java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/WindBotDataRetrieverProvider.java index 771432fa8d7..5e9909d07e7 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/WindBotDataRetrieverProvider.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/dataretriever/WindBotDataRetrieverProvider.java @@ -1,4 +1,4 @@ -package com.sap.sailing.dashboards.gwt.client; +package com.sap.sailing.dashboards.gwt.client.dataretriever; import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO; diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/device/Orientation.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/device/Orientation.java index 13b8902f5c1..ffd2dcbae8d 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/device/Orientation.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/device/Orientation.java @@ -3,6 +3,8 @@ package com.sap.sailing.dashboards.gwt.client.device; import java.util.ArrayList; import java.util.List; +import com.sap.sse.common.Util.Pair; + /** * * @author Alexander Ries (D062114) @@ -62,8 +64,38 @@ public class Orientation { } public void notifiyListenerAboutHeadingChange(double orientationHeading) { + Pair orienationPair = new Pair(getOrientationTypeForHeadingInSafari(orientationHeading), new Double(orientationHeading)); for (OrientationListener orientationListener : orientationListeners) { - orientationListener.orientationChanged(orientationHeading); + orientationListener.orientationChanged(orienationPair); } } + + + private OrientationType getOrientationTypeForHeadingInSafari(double heading){ + OrientationType orientationType = null; + if (heading > -45 && heading <= 0 || heading > 0 && heading < 45){ + orientationType = OrientationType.PORTRAIT_UP; + }else if (heading > 45 && heading < 135){ + orientationType = OrientationType.LANDSCAPE_RIGHT; + }else if (heading > 135 && heading <= 180 || heading >=-180 && heading < -135){ + orientationType = OrientationType.PORTRAIT_DOWN; + }else if (heading > -135 && heading < -45){ + orientationType = OrientationType.LANDSCAPE_LEFT; + } + return orientationType; + } + + private OrientationType getOrientationTypeForHeadingInChrome(double heading){ + OrientationType orientationType = null; + if (heading > -45 && heading <= 0 || heading > 0 && heading < 45){ + orientationType = OrientationType.LANDSCAPE_RIGHT; + }else if (heading > 45 && heading < 135){ + orientationType = OrientationType.PORTRAIT_DOWN; + }else if (heading > 135 && heading <= 180 || heading >=-180 && heading < -135){ + orientationType = OrientationType.LANDSCAPE_LEFT; + }else if (heading > -135 && heading < -45){ + orientationType = OrientationType.PORTRAIT_UP; + } + return orientationType; + } } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/device/OrientationListener.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/device/OrientationListener.java index e276a6e2503..7c65e05d6a8 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/device/OrientationListener.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/device/OrientationListener.java @@ -1,6 +1,11 @@ package com.sap.sailing.dashboards.gwt.client.device; +import com.sap.sse.common.Util.Pair; + public interface OrientationListener { - public void orientationChanged(double orientationHeading); + /** + * Returns a Pair containing the {@link OrientationType} and the exact angle. + * */ + public void orientationChanged(Pair orientation); } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/device/OrientationType.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/device/OrientationType.java new file mode 100644 index 00000000000..f5a38235b0f --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/device/OrientationType.java @@ -0,0 +1,6 @@ +package com.sap.sailing.dashboards.gwt.client.device; + + +public enum OrientationType { + PORTRAIT_UP, PORTRAIT_DOWN, LANDSCAPE_RIGHT, LANDSCAPE_LEFT; +} diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/EventLogo.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/eventlogo/EventLogo.java similarity index 96% rename from java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/EventLogo.java rename to java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/eventlogo/EventLogo.java index 5e37cd9ad59..27c06e0ee36 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/EventLogo.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/eventlogo/EventLogo.java @@ -1,4 +1,4 @@ -package com.sap.sailing.dashboards.gwt.client; +package com.sap.sailing.dashboards.gwt.client.eventlogo; import java.util.UUID; diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/i18n/StringMessages.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/i18n/StringMessages.java new file mode 100644 index 00000000000..1d4c983efc5 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/i18n/StringMessages.java @@ -0,0 +1,9 @@ +package com.sap.sailing.dashboards.gwt.client.i18n; + +import com.google.gwt.core.client.GWT; + +public interface StringMessages extends com.sap.sailing.gwt.ui.client.StringMessages { + public static final StringMessages INSTANCE = GWT.create(StringMessages.class); + + String sampleText(); +} diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/i18n/StringMessages.properties b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/i18n/StringMessages.properties new file mode 100644 index 00000000000..7c4958102d1 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/i18n/StringMessages.properties @@ -0,0 +1 @@ +sampleText=some Text \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/i18n/StringMessages_de.properties b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/i18n/StringMessages_de.properties new file mode 100644 index 00000000000..25aed4d11f3 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/i18n/StringMessages_de.properties @@ -0,0 +1 @@ +sampleText=irgendein Text \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/bottomnotification/BottomNotification.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/notifications/BottomNotification.java similarity index 97% rename from java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/bottomnotification/BottomNotification.java rename to java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/notifications/BottomNotification.java index e08a13de8ad..a7ed50c836a 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/bottomnotification/BottomNotification.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/notifications/BottomNotification.java @@ -1,4 +1,4 @@ -package com.sap.sailing.dashboards.gwt.client.bottomnotification; +package com.sap.sailing.dashboards.gwt.client.notifications; import java.util.ArrayList; import java.util.List; diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/bottomnotification/BottomNotificationClickListener.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/notifications/BottomNotificationClickListener.java similarity index 61% rename from java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/bottomnotification/BottomNotificationClickListener.java rename to java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/notifications/BottomNotificationClickListener.java index 37e3afe8aa6..bc63fd8d55b 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/bottomnotification/BottomNotificationClickListener.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/notifications/BottomNotificationClickListener.java @@ -1,4 +1,4 @@ -package com.sap.sailing.dashboards.gwt.client.bottomnotification; +package com.sap.sailing.dashboards.gwt.client.notifications; public interface BottomNotificationClickListener { diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/bottomnotification/BottomNotificationType.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/notifications/BottomNotificationType.java similarity index 94% rename from java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/bottomnotification/BottomNotificationType.java rename to java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/notifications/BottomNotificationType.java index 5cf13a670b0..c12e7c7df15 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/bottomnotification/BottomNotificationType.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/notifications/BottomNotificationType.java @@ -1,4 +1,4 @@ -package com.sap.sailing.dashboards.gwt.client.bottomnotification; +package com.sap.sailing.dashboards.gwt.client.notifications; import com.sap.sailing.gwt.ui.client.StringMessages; diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/notifications/WrongDeviceOrientationNotification.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/notifications/WrongDeviceOrientationNotification.java new file mode 100644 index 00000000000..d8fc6d10f94 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/notifications/WrongDeviceOrientationNotification.java @@ -0,0 +1,67 @@ +package com.sap.sailing.dashboards.gwt.client.notifications; + +import com.google.gwt.user.client.ui.AbsolutePanel; +import com.google.gwt.user.client.ui.Image; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.RootLayoutPanel; +import com.sap.sailing.dashboards.gwt.client.RibDashboardImageResources; +import com.sap.sailing.dashboards.gwt.client.device.Orientation; +import com.sap.sailing.dashboards.gwt.client.device.OrientationListener; +import com.sap.sailing.dashboards.gwt.client.device.OrientationType; +import com.sap.sailing.dashboards.gwt.client.visualeffects.BlurEffect; +import com.sap.sse.common.Util.Pair; + +public class WrongDeviceOrientationNotification extends AbsolutePanel implements OrientationListener { + + private Label rotateDeviceLabel; + + public WrongDeviceOrientationNotification() { + super(); + this.addStyleName("wrongOrientationNotification"); + this.addStyleName("wrongOrientationNotification_hidden"); + + Image rotateDeviceIcon = new Image(); + rotateDeviceIcon.setResource(RibDashboardImageResources.INSTANCE.rotatedevice()); + rotateDeviceIcon.getElement().addClassName("wrongOrientationNotification_logo"); + add(rotateDeviceIcon); + + rotateDeviceLabel = new Label(); + rotateDeviceLabel.getElement().addClassName("wrongOrientationNotification_text"); + rotateDeviceLabel.setText("Rotate Device"); + add(rotateDeviceLabel); + + Orientation.getInstance().addListener(this); + Orientation.getInstance().triggerDeviceOrientationRead(); + } + + public void show() { + this.removeStyleName("wrongOrientationNotification_hidden"); + this.addStyleName("wrongOrientationNotification_shown"); + BlurEffect.getInstance().addToView(RootLayoutPanel.get()); + } + + public void hide() { + this.removeStyleName("wrongOrientationNotification_shown"); + this.addStyleName("wrongOrientationNotification_hidden"); + BlurEffect.getInstance().removeFromView(RootLayoutPanel.get()); + } + + @Override + public void orientationChanged(Pair orientation) { + OrientationType orientationType = orientation.getA(); + switch (orientationType) { + case PORTRAIT_UP: + show(); + break; + case PORTRAIT_DOWN: + show(); + break; + case LANDSCAPE_RIGHT: + hide(); + break; + case LANDSCAPE_LEFT: + hide(); + break; + } + } +} diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionPopup.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionPopup.css index 5542abe5ae5..a2ba055f0f5 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionPopup.css +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionPopup.css @@ -75,13 +75,3 @@ transition: margin-top ease-in-out 500ms; margin-top: -600pt; } - -.blurred { - -webkit-filter: blur(10pt) brightness(0.92); - filter: blur(10pt) brightness(0.92); -} - -.not_blurred { - -webkit-filter: blur(0pt) brightness(1); - filter: blur(0pt) brightness(1); -} \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionPopup.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionPopup.java index df7c24d2f42..0adc18b350c 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionPopup.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionPopup.java @@ -17,6 +17,7 @@ import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.RootLayoutPanel; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.dashboards.gwt.client.visualeffects.BlurEffect; import com.sap.sailing.domain.common.dto.CompetitorDTO; public class CompetitorSelectionPopup extends Composite implements HasWidgets, CompetitorTableRowSelectionListener { @@ -27,10 +28,6 @@ public class CompetitorSelectionPopup extends Composite implements HasWidgets, C String popuphide(); String buttonshow(); - - String blurred(); - - String not_blurred(); } @UiField @@ -68,16 +65,14 @@ public class CompetitorSelectionPopup extends Composite implements HasWidgets, C this.button.setText("OK"); this.getElement().addClassName(style.popupshow()); this.getElement().removeClassName(style.popuphide()); - RootLayoutPanel.get().addStyleName(style.blurred()); - RootLayoutPanel.get().removeStyleName(style.not_blurred()); + BlurEffect.getInstance().addToView(RootLayoutPanel.get()); isVisible = true; } public void hide() { this.getElement().addClassName(style.popuphide()); this.getElement().removeClassName(style.popupshow()); - RootLayoutPanel.get().addStyleName(style.not_blurred()); - RootLayoutPanel.get().removeStyleName(style.blurred()); + BlurEffect.getInstance().removeFromView(RootLayoutPanel.get()); RootPanel.get().remove(this); isVisible = false; } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/SettingsButtonWithSelectionIndicationLabel.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/SettingsButtonWithSelectionIndicationLabel.css index 2d5f668017e..3231255779b 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/SettingsButtonWithSelectionIndicationLabel.css +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/SettingsButtonWithSelectionIndicationLabel.css @@ -10,11 +10,8 @@ } .settings_button_image { - position: absolute; height: 23.5pt; width: 23.5pt; - right: 10pt; - top: 17.5pt; } .settings_indication_label { diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/SettingsButtonWithSelectionIndicationLabel.ui.xml b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/SettingsButtonWithSelectionIndicationLabel.ui.xml index ea530ceeb03..865b2a2a998 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/SettingsButtonWithSelectionIndicationLabel.ui.xml +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/SettingsButtonWithSelectionIndicationLabel.ui.xml @@ -5,8 +5,9 @@ type='com.sap.sailing.dashboards.gwt.client.popups.competitorselection.SettingsButtonWithSelectionIndicationLabel.SettingsButtonWithSelectionIndicationLabelStyle' src='SettingsButtonWithSelectionIndicationLabel.css'> - - + + + \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysisCard.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysisCard.java index 4b20f319ec9..ad19b946bde 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysisCard.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysisCard.java @@ -136,10 +136,10 @@ public class StartlineAnalysisCard extends Composite implements HasWidgets, Star com.sap.sse.gwt.client.player.Timer timer = new com.sap.sse.gwt.client.player.Timer(PlayModes.Live, 1000l); timer.pause(); ArrayList zoomTypes = new ArrayList(); - if(startAnalysisDTO.racingProcedureType.equals(RacingProcedureType.GateStart)){ - timer.setTime(startAnalysisDTO.timeOfStartInMilliSeconds+startAnalysisDTO.tailLenghtInMilliseconds); + if (startAnalysisDTO.racingProcedureType.equals(RacingProcedureType.GateStart)) { + timer.setTime(startAnalysisDTO.timeOfStartInMilliSeconds + startAnalysisDTO.tailLenghtInMilliseconds); zoomTypes.add(ZoomTypes.BUOYS); - }else{ + } else { timer.setTime(startAnalysisDTO.timeOfStartInMilliSeconds); zoomTypes.add(ZoomTypes.TAILS); } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysisComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysisComponent.java index 9b26dfb0827..ea464aecefa 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysisComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysisComponent.java @@ -24,9 +24,9 @@ import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.dashboards.gwt.client.RibDashboardImageResources; import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync; -import com.sap.sailing.dashboards.gwt.client.bottomnotification.BottomNotification; -import com.sap.sailing.dashboards.gwt.client.bottomnotification.BottomNotificationClickListener; -import com.sap.sailing.dashboards.gwt.client.bottomnotification.BottomNotificationType; +import com.sap.sailing.dashboards.gwt.client.notifications.BottomNotification; +import com.sap.sailing.dashboards.gwt.client.notifications.BottomNotificationClickListener; +import com.sap.sailing.dashboards.gwt.client.notifications.BottomNotificationType; import com.sap.sailing.dashboards.gwt.client.popups.competitorselection.CompetitorSelectionListener; import com.sap.sailing.dashboards.gwt.client.popups.competitorselection.CompetitorSelectionPopup; import com.sap.sailing.dashboards.gwt.client.popups.competitorselection.SettingsButtonWithSelectionIndicationLabel; diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java index d7a6b1ed132..03ebbcb4ae7 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java @@ -1,8 +1,8 @@ package com.sap.sailing.dashboards.gwt.client.startlineadvantage; import com.google.gwt.i18n.client.NumberFormat; -import com.sap.sailing.dashboards.gwt.client.RibDashboardDataRetriever; -import com.sap.sailing.dashboards.gwt.client.RibDashboardDataRetrieverListener; +import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetriever; +import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetrieverListener; import com.sap.sailing.dashboards.gwt.client.startanalysis.StartlineAdvantageType; import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO; import com.sap.sailing.gwt.ui.client.StringMessages; diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/BlurEffect.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/BlurEffect.css new file mode 100644 index 00000000000..6d533471683 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/BlurEffect.css @@ -0,0 +1,11 @@ +@CHARSET "UTF-8"; + +.blurred { + -webkit-filter: blur(10pt) brightness(0.92); + filter: blur(10pt) brightness(0.92); +} + +.not_blurred { + -webkit-filter: blur(0pt) brightness(1); + filter: blur(0pt) brightness(1); +} \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/BlurEffect.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/BlurEffect.java new file mode 100644 index 00000000000..17dbdb55da4 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/BlurEffect.java @@ -0,0 +1,34 @@ +package com.sap.sailing.dashboards.gwt.client.visualeffects; + +import com.google.gwt.core.shared.GWT; +import com.google.gwt.user.client.ui.Widget; + + +public class BlurEffect { + + private static BlurEffect INSTANCE = null; + private VisualEffectsResources visualEffectsResources = GWT.create(VisualEffectsResources.class); + + private BlurEffect() { + visualEffectsResources.blurEffectStyle().ensureInjected(); + } + + public static BlurEffect getInstance() { + synchronized (BlurEffect.class) { + if (INSTANCE == null) { + INSTANCE = new BlurEffect(); + } + } + return INSTANCE; + } + + public void addToView(Widget widget){ + widget.removeStyleName(visualEffectsResources.blurEffectStyle().not_blurred()); + widget.addStyleName(visualEffectsResources.blurEffectStyle().blurred()); + } + + public void removeFromView(Widget widget){ + widget.removeStyleName(visualEffectsResources.blurEffectStyle().blurred()); + widget.addStyleName(visualEffectsResources.blurEffectStyle().not_blurred()); + } +} diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/BlurEffectStyle.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/BlurEffectStyle.java new file mode 100644 index 00000000000..ec1306d820f --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/BlurEffectStyle.java @@ -0,0 +1,13 @@ +package com.sap.sailing.dashboards.gwt.client.visualeffects; + +import com.google.gwt.resources.client.CssResource; +import com.google.gwt.resources.client.CssResource.Shared; + +@Shared +public interface BlurEffectStyle extends CssResource{ + + public String blurred(); + + public String not_blurred(); +} + diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/VisualEffectsResources.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/VisualEffectsResources.java new file mode 100644 index 00000000000..f87efb9d50c --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/VisualEffectsResources.java @@ -0,0 +1,9 @@ +package com.sap.sailing.dashboards.gwt.client.visualeffects; + +import com.google.gwt.resources.client.ClientBundle; + +public interface VisualEffectsResources extends ClientBundle{ + + @Source("BlurEffect.css") + BlurEffectStyle blurEffectStyle(); +} diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/VerticalWindChart.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/VerticalWindChart.java index c5e195bc0bb..0d4806a87c9 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/VerticalWindChart.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/VerticalWindChart.java @@ -26,6 +26,8 @@ import org.moxieapps.gwt.highcharts.client.plotOptions.BarPlotOptions; import org.moxieapps.gwt.highcharts.client.plotOptions.Marker; import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.resources.client.CssResource; import com.google.gwt.uibinder.client.UiBinder; @@ -90,8 +92,8 @@ public class VerticalWindChart extends Composite implements HasWidgets { initWidget(uiBinder.createAndBindUi(this)); } - public @UiConstructor VerticalWindChart(String positiveFillColor, String negativeFillColor) { - initVerticalWindChartWithColors(positiveFillColor, negativeFillColor); + public @UiConstructor VerticalWindChart(String positiveFillColorAsHex, String negativeFillColorAsHex) { + initVerticalWindChartWithColors(positiveFillColorAsHex, negativeFillColorAsHex); initWidget(uiBinder.createAndBindUi(this)); } @@ -175,18 +177,24 @@ public class VerticalWindChart extends Composite implements HasWidgets { * {@link #setXAxisExtremesForSeriesPointRangeIsSmallerThanChartDisplayIntervall()} and * {@link #setXAxisExtremesForSeriesPointRangeIsBiggerThanChartDisplayIntervall()}. * */ - public void addPointsToSeriesWithAverage(Point[] points, double average) { - if (verticalWindChartSeries == null) { - initVerticalWindChartSeries(); - verticalWindChartSeries.setPoints(points, true); - } else { - for (Point point : points) { - verticalWindChartSeries.addPoint(point, true, false, false); + public void addPointsToSeriesWithAverage(final Point[] points, final double average) { + Scheduler.get().scheduleDeferred(new ScheduledCommand() { + + @Override + public void execute() { + if (verticalWindChartSeries == null) { + initVerticalWindChartSeries(); + verticalWindChartSeries.setPoints(points, true); + } else { + for (Point point : points) { + verticalWindChartSeries.addPoint(point, true, false, false); + } + } + verticalWindChartSeries.updateThreshold("" + average); + adaptVerticalWindChartExtemes(); + verticalWindChart.setSizeToMatchContainer(); } - } - verticalWindChartSeries.updateThreshold("" + average); - adaptVerticalWindChartExtemes(); - verticalWindChart.setSizeToMatchContainer(); + }); } /** @@ -194,23 +202,7 @@ public class VerticalWindChart extends Composite implements HasWidgets { * interval or not. So there are two cases where the extreme points of the x-axis get calculated differently. * */ private void adaptVerticalWindChartExtemes() { - if (getVerticalWindChartSeriesPointsTimeRangeInMilliseconds() < chartIntervallinMinutes * 60 * 1000) { - setXAxisExtremesForSeriesPointRangeIsSmallerThanChartDisplayIntervall(); - } else { setXAxisExtremesForSeriesPointRangeIsBiggerThanChartDisplayIntervall(); - } - } - - /** - * When the time range of the series points is smaller than the current selected display interval represented by - * either LARGE_DISPLAY_INTERVALL_IN_MINUTES or SMALL_DISPLAY_INTERVALL_IN_MINUTES the x-axis extremes min value is - * the the first points time and the maximum value the min value plus the selected display interval. The chart gets - * other extremes, because the values fit easily into the selected display interval. - * */ - private void setXAxisExtremesForSeriesPointRangeIsSmallerThanChartDisplayIntervall() { - long minimumExtremeValueInMillis = getFirstPointOfVerticalWindChartSeries().getX().longValue(); - long maximumExtremeValueInMillis = minimumExtremeValueInMillis + chartIntervallinMinutes * 60 * 1000; - verticalWindChart.getXAxis().setExtremes(minimumExtremeValueInMillis, maximumExtremeValueInMillis, true, true); } /** @@ -220,29 +212,11 @@ public class VerticalWindChart extends Composite implements HasWidgets { * gets other extremes, because the values do not fit anymore into the selected display interval. * */ private void setXAxisExtremesForSeriesPointRangeIsBiggerThanChartDisplayIntervall() { - long maximumExtremeValueInMillis = getLastPointOfVerticalWindChartSeries().getX().longValue(); - long minimumExtremeValueInMillis = maximumExtremeValueInMillis - chartIntervallinMinutes * 60 * 1000; - verticalWindChart.getXAxis().setExtremes(minimumExtremeValueInMillis, maximumExtremeValueInMillis, true, true); + long maximumExtremeValueInMillis = getLastPointOfVerticalWindChartSeries().getX().longValue(); + long minimumExtremeValueInMillis = maximumExtremeValueInMillis - chartIntervallinMinutes * 60 * 1000; + verticalWindChart.getXAxis().setExtremes(minimumExtremeValueInMillis, maximumExtremeValueInMillis, true, true); } - private long getVerticalWindChartSeriesPointsTimeRangeInMilliseconds() { - Point[] seriesPoints = verticalWindChartSeries.getPoints(); - long pointRangeInMilliseconds; - int seriesPointsLenght = seriesPoints.length; - if (seriesPointsLenght > 0 && seriesPoints[0].getX() != null) { - long earliesPointAsTimestamp = seriesPoints[0].getX().longValue(); - long latestPointAsTimestamp; - if (seriesPointsLenght > 1) { - latestPointAsTimestamp = seriesPoints[seriesPointsLenght - 1].getX().longValue(); - } else { - latestPointAsTimestamp = earliesPointAsTimestamp; - } - pointRangeInMilliseconds = latestPointAsTimestamp - earliesPointAsTimestamp; - } else { - pointRangeInMilliseconds = 0; - } - return pointRangeInMilliseconds; - } private Point getLastPointOfVerticalWindChartSeries() { Point lastPointOfVerticalWindChartSeries = null; @@ -256,16 +230,6 @@ public class VerticalWindChart extends Composite implements HasWidgets { return lastPointOfVerticalWindChartSeries; } - private Point getFirstPointOfVerticalWindChartSeries() { - Point firstPointOfVerticalWindChartSeries = null; - Point[] seriesPoints = verticalWindChartSeries.getPoints(); - int seriesPointsLenght = seriesPoints.length; - if (seriesPointsLenght > 0) { - firstPointOfVerticalWindChartSeries = seriesPoints[0]; - } - return firstPointOfVerticalWindChartSeries; - } - public void addVerticalWindChartClickListener(VerticalWindChartClickListener verticalWindChartClickListener) { verticalWindChartClickListeners.add(verticalWindChartClickListener); } @@ -291,8 +255,13 @@ public class VerticalWindChart extends Composite implements HasWidgets { } else { chartIntervallinMinutes = SMALL_DISPLAY_INTERVALL_IN_MINUTES; } - adaptVerticalWindChartExtemes(); - notifyVerticalWindChartClickListeners(chartIntervallinMinutes); + Scheduler.get().scheduleFinally(new ScheduledCommand() { + + @Override + public void execute() { + adaptVerticalWindChartExtemes(); + notifyVerticalWindChartClickListeners(chartIntervallinMinutes); + }}); } @Override diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.java index 164fcd170c2..bd00160790c 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.java @@ -15,8 +15,8 @@ import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.dashboards.gwt.client.RibDashboardDataRetrieverListener; -import com.sap.sailing.dashboards.gwt.client.WindBotDataRetrieverListener; +import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetrieverListener; +import com.sap.sailing.dashboards.gwt.client.dataretriever.WindBotDataRetrieverListener; import com.sap.sailing.dashboards.gwt.client.startlineadvantage.LiveAverageComponent; import com.sap.sailing.dashboards.gwt.client.windchart.compass.LocationPointerCompass; import com.sap.sailing.dashboards.gwt.shared.MovingAverage; @@ -85,14 +85,14 @@ public class WindBotComponent extends Composite implements HasWidgets, WindBotDa * One of two {@link VerticalWindChart}s that shows the wind fixes speed measured by the wind bot in a chart * vertically. * */ - @UiField + @UiField(provided = true) public VerticalWindChart trueWindSpeedVerticalWindChart; /** * One of two {@link VerticalWindChart}s that shows the wind fixes direction measured by the wind bot in a chart * vertically. * */ - @UiField + @UiField(provided = true) public VerticalWindChart trueWindDirectionVerticalWindChart; /** @@ -104,6 +104,7 @@ public class WindBotComponent extends Composite implements HasWidgets, WindBotDa private String windBotId; private StringMessages stringConstants; + private final static String UNIT_WIND_DIRECTION = "°"; public WindBotComponent(String windBotId) { this.windBotId = windBotId; @@ -119,7 +120,9 @@ public class WindBotComponent extends Composite implements HasWidgets, WindBotDa movingAverageSpeed = new MovingAverage(500); movingAverageDirection = new MovingAverage(500); trueWindSpeedLiveAverageComponent = new LiveAverageComponent(stringConstants.dashboardTrueWindSpeed(), stringConstants.dashboardTrueWindSpeedUnit()); - trueWindDirectionLiveAverageComponent = new LiveAverageComponent(stringConstants.dashboardTrueWindDirection(), stringConstants.dashboardTrueWindDirectionUnit()); + trueWindDirectionLiveAverageComponent = new LiveAverageComponent(stringConstants.dashboardTrueWindDirection(), UNIT_WIND_DIRECTION); + trueWindSpeedVerticalWindChart = new VerticalWindChart("#008FFF", "#6ADBFF"); + trueWindDirectionVerticalWindChart = new VerticalWindChart("#008FFF", "#6ADBFF"); initWidget(uiBinder.createAndBindUi(this)); windBotNamePanel.getElement().setInnerText(stringConstants.dashboardWindBot()+" "+ windBotId); trueWindSpeedVerticalWindChart.addVerticalWindChartClickListener(trueWindSpeedLiveAverageComponent); @@ -197,16 +200,16 @@ public class WindBotComponent extends Composite implements HasWidgets, WindBotDa Point[] points = new Point[windFixes.size()]; int counter = 0; if (windtype.equals(WindType.DIRECTION)) { - Point previouspoint = new Point(windFixes.get(0).requestTimepoint, windFixes.get(0).trueWindBearingDeg); + Point previouspoint = new Point(windFixes.get(0).requestTimepoint, windFixes.get(0).trueWindFromDeg); for (WindDTO windDTO : windFixes) { double nextSinusValue = 0; if (inSimulationMode == true) { nextSinusValue = directionSinWave.getNexNumber(); } - points[counter] = new Point(windDTO.requestTimepoint, windDTO.trueWindBearingDeg + nextSinusValue); + points[counter] = new Point(windDTO.requestTimepoint, windDTO.trueWindFromDeg + nextSinusValue); points[counter] = adaptWindDirectionPointToStayCloseToLastPoint(previouspoint, points[counter]); previouspoint = points[counter]; - movingAverageDirection.add(windDTO.trueWindBearingDeg + nextSinusValue); + movingAverageDirection.add(windDTO.trueWindFromDeg + nextSinusValue); counter++; } } else if (windtype.equals(WindType.SPEED)) { diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.ui.xml b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.ui.xml index 2096d43b130..ef3a9e37080 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.ui.xml +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.ui.xml @@ -23,14 +23,12 @@ + styleName="{style.wind_bot_component_windchart}"> + styleName="{style.wind_bot_component_windchart}"> orientation) { + setAngleOffsetAtListeners(orientation.getB().doubleValue()); } } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startanalysis/AbstractStartAnalysisCreationValidator.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startanalysis/AbstractStartAnalysisCreationValidator.java index 5402bdfc340..68a31a162bb 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startanalysis/AbstractStartAnalysisCreationValidator.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startanalysis/AbstractStartAnalysisCreationValidator.java @@ -6,24 +6,49 @@ import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Waypoint; import com.sap.sailing.domain.tracking.MarkPassing; import com.sap.sailing.domain.tracking.TrackedRace; +import com.sap.sse.common.TimePoint; public abstract class AbstractStartAnalysisCreationValidator { - private static int MINIMUM_NUMBER_COMPETITORS_FOR_STARTANALYSIS = 3; + private static int MINIMUM_MARKPASSIINGS_AT_FIRST_MARK = 3; + private static long MINIMUM_RACE_PROGRESSION_IN_MILLISECONDS = 6*60*1000; protected boolean threeCompetitorsPassedSecondWayPoint(TrackedRace trackedRace){ Waypoint secondWaypoint = trackedRace.getRace().getCourse().getFirstLeg().getTo(); Iterator markPassingsInOrder = trackedRace.getMarkPassingsInOrder(secondWaypoint).iterator(); - int counter = 0; - while (markPassingsInOrder.hasNext()) { + int markPassingsCounter = 0; + while (markPassingsInOrder.hasNext() && markPassingsCounter < MINIMUM_MARKPASSIINGS_AT_FIRST_MARK) { markPassingsInOrder.next(); - counter ++; + markPassingsCounter ++; } - return counter >= MINIMUM_NUMBER_COMPETITORS_FOR_STARTANALYSIS ? true : false; + return markPassingsCounter >= MINIMUM_MARKPASSIINGS_AT_FIRST_MARK ? true : false; } - protected boolean competitorPassedSecondWayPoint(Competitor competitor, TrackedRace trackedRace){ + private boolean competitorPassedSecondWayPoint(Competitor competitor, TrackedRace trackedRace){ Waypoint secondWaypoint = trackedRace.getRace().getCourse().getFirstLeg().getTo(); return trackedRace.getMarkPassing(competitor, secondWaypoint) == null ? false : true; } + + private boolean gateStartGolfFlagIsDown(TrackedRace trackedRace){ + if(trackedRace.getGateStartGolfDownTime() != 0){ + return true; + }else{ + TimePoint timeStartOfRace = trackedRace.getStartOfRace(); + TimePoint timeNewestEvent = trackedRace.getTimePointOfNewestEvent(); + if(timeStartOfRace != null && timeNewestEvent != null){ + if(timeStartOfRace.asMillis()+MINIMUM_RACE_PROGRESSION_IN_MILLISECONDS > timeNewestEvent.asMillis()){ + return true; + } + } + } + return false; + } + + protected boolean raceProgressedFarEnough(Competitor competitor, TrackedRace trackedRace){ + if(trackedRace.isGateStart()){ + return gateStartGolfFlagIsDown(trackedRace); + }else{ + return competitorPassedSecondWayPoint(competitor, trackedRace); + } + } } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startanalysis/StartAnalysisCreationController.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startanalysis/StartAnalysisCreationController.java index 978e3bfe486..5cbb7bf866f 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startanalysis/StartAnalysisCreationController.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startanalysis/StartAnalysisCreationController.java @@ -21,7 +21,7 @@ public class StartAnalysisCreationController extends AbstractStartAnalysisCreati public StartAnalysisDTO checkStartAnalysisForCompetitorInTrackedRace(Competitor competitor, TrackedRace trackedRace) { StartAnalysisDTO startAnalysisDTO; if (threeCompetitorsPassedSecondWayPoint(trackedRace) && - competitorPassedSecondWayPoint(competitor, trackedRace)) + raceProgressedFarEnough(competitor, trackedRace)) { logger.log(Level.INFO, "Trigger StartAnalysisDTO creation"); startAnalysisDTO = startAnalysisDTOFactory.createStartAnalysisForCompetitorAndTrackedRace(competitor, trackedRace); diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startanalysis/StartAnalysisDTOFactory.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startanalysis/StartAnalysisDTOFactory.java index 3697abdc4ab..8a395078acf 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startanalysis/StartAnalysisDTOFactory.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startanalysis/StartAnalysisDTOFactory.java @@ -34,6 +34,7 @@ public class StartAnalysisDTOFactory extends AbstractStartAnalysisCreationValida private static int MINIMUM_NUMBER_COMPETITORS_FOR_STARTANALYSIS = 3; private static int DEFAULT_GATE_START_INTERVALL_IN_MILLISECONDS = 5*60*1000; + private static int ONE_MINUTE_INTERVALL_IN_MILLISECONDS = 60*1000; private static final Logger logger = Logger.getLogger(StartAnalysisDTOFactory.class.getName()); @@ -72,7 +73,6 @@ public class StartAnalysisDTOFactory extends AbstractStartAnalysisCreationValida if (trackedRace.isGateStart()) { logger.log(Level.INFO, "IS GATESTART"); startAnalysisDTO.racingProcedureType = RacingProcedureType.GateStart; -// Waypoint startLineWaypoint = trackedRace.getStartLine(trackedRace.getStartOfRace()).getWaypoint(); long timePointOfGolfDownTime = trackedRace.getGateStartGolfDownTime(); startAnalysisDTO.timeOfStartInMilliSeconds = trackedRace.getStartOfRace().asMillis(); if(timePointOfGolfDownTime < trackedRace.getStartOfRace().asMillis() || timePointOfGolfDownTime == 0){ @@ -83,6 +83,7 @@ public class StartAnalysisDTOFactory extends AbstractStartAnalysisCreationValida } else { startAnalysisDTO.racingProcedureType = RacingProcedureType.ESS; startAnalysisDTO.timeOfStartInMilliSeconds = trackedRace.getStartOfRace().asMillis(); + startAnalysisDTO.tailLenghtInMilliseconds = ONE_MINUTE_INTERVALL_IN_MILLISECONDS; } startAnalysisDTO.regattaAndRaceIdentifier = trackedRace.getRaceIdentifier(); logger.log(Level.INFO, "Created StartAnalysis For Competitor " + competitor.getName() + " and "+ trackedRace.getRace().getName()); diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/resources/com/sap/sailing/dashboards/gwt/client/images/rotatedevice.png b/java/com.sap.sailing.dashboards.gwt/src/main/resources/com/sap/sailing/dashboards/gwt/client/images/rotatedevice.png new file mode 100644 index 00000000000..6a48d2af821 Binary files /dev/null and b/java/com.sap.sailing.dashboards.gwt/src/main/resources/com/sap/sailing/dashboards/gwt/client/images/rotatedevice.png differ diff --git a/java/com.sap.sailing.datamining/META-INF/MANIFEST.MF b/java/com.sap.sailing.datamining/META-INF/MANIFEST.MF index 214ca92a24d..de3ca8708a3 100644 --- a/java/com.sap.sailing.datamining/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.datamining/META-INF/MANIFEST.MF @@ -16,8 +16,7 @@ Require-Bundle: com.sap.sailing.domain, com.sap.sse.datamining.shared, com.sap.sse, com.sap.sse.common, - org.eclipse.osgi, - com.sap.sailing.polars + org.eclipse.osgi Bundle-ClassPath: . Bundle-Activator: com.sap.sailing.datamining.Activator Bundle-ActivationPolicy: lazy diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasLeaderboardContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasLeaderboardContext.java index 20c90e1e87e..bed837c4156 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasLeaderboardContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasLeaderboardContext.java @@ -1,7 +1,7 @@ package com.sap.sailing.datamining.data; import com.sap.sailing.domain.leaderboard.Leaderboard; -import com.sap.sailing.polars.PolarDataService; +import com.sap.sailing.domain.polars.PolarDataService; public interface HasLeaderboardContext { diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasLeaderboardGroupContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasLeaderboardGroupContext.java index eeed74ce12a..e8fff6c3914 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasLeaderboardGroupContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasLeaderboardGroupContext.java @@ -1,7 +1,7 @@ package com.sap.sailing.datamining.data; import com.sap.sailing.domain.leaderboard.LeaderboardGroup; -import com.sap.sailing.polars.PolarDataService; +import com.sap.sailing.domain.polars.PolarDataService; public interface HasLeaderboardGroupContext { diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasTrackedLegOfCompetitorContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasTrackedLegOfCompetitorContext.java index 72849ec0aa9..73060766132 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasTrackedLegOfCompetitorContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasTrackedLegOfCompetitorContext.java @@ -2,9 +2,9 @@ package com.sap.sailing.datamining.data; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor; -import com.sap.sse.datamining.shared.Unit; import com.sap.sse.datamining.shared.annotations.Connector; import com.sap.sse.datamining.shared.annotations.Statistic; +import com.sap.sse.datamining.shared.data.Unit; public interface HasTrackedLegOfCompetitorContext { diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/LeaderboardGroupRetrievalProcessor.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/LeaderboardGroupRetrievalProcessor.java index dc3857ce70d..6e4a8acecfa 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/LeaderboardGroupRetrievalProcessor.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/LeaderboardGroupRetrievalProcessor.java @@ -5,7 +5,7 @@ import java.util.concurrent.ExecutorService; import java.util.stream.Collectors; import com.sap.sailing.datamining.impl.data.LeaderboardGroupWithContext; -import com.sap.sailing.polars.PolarDataService; +import com.sap.sailing.domain.polars.PolarDataService; import com.sap.sailing.server.RacingEventService; import com.sap.sse.datamining.components.Processor; import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor; diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/LeaderboardGroupWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/LeaderboardGroupWithContext.java index 38bfe4c5e42..621aba4f6e4 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/LeaderboardGroupWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/LeaderboardGroupWithContext.java @@ -2,7 +2,7 @@ package com.sap.sailing.datamining.impl.data; import com.sap.sailing.datamining.data.HasLeaderboardGroupContext; import com.sap.sailing.domain.leaderboard.LeaderboardGroup; -import com.sap.sailing.polars.PolarDataService; +import com.sap.sailing.domain.polars.PolarDataService; public class LeaderboardGroupWithContext implements HasLeaderboardGroupContext { diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/LeaderboardWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/LeaderboardWithContext.java index 6e13878cecb..9f2ced4e8af 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/LeaderboardWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/LeaderboardWithContext.java @@ -2,7 +2,7 @@ package com.sap.sailing.datamining.impl.data; import com.sap.sailing.datamining.data.HasLeaderboardContext; import com.sap.sailing.domain.leaderboard.Leaderboard; -import com.sap.sailing.polars.PolarDataService; +import com.sap.sailing.domain.polars.PolarDataService; public class LeaderboardWithContext implements HasLeaderboardContext { diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceResultOfCompetitorWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceResultOfCompetitorWithContext.java index 9c406c8bc85..59784993ce5 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceResultOfCompetitorWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceResultOfCompetitorWithContext.java @@ -20,11 +20,11 @@ import com.sap.sailing.domain.common.Tack; import com.sap.sailing.domain.common.scalablevalue.impl.ScalableSpeed; import com.sap.sailing.domain.common.tracking.GPSFixMoving; import com.sap.sailing.domain.leaderboard.Leaderboard; +import com.sap.sailing.domain.polars.PolarDataService; import com.sap.sailing.domain.tracking.GPSFixTrack; import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.WindWithConfidence; -import com.sap.sailing.polars.PolarDataService; import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; diff --git a/java/com.sap.sailing.domain.common/build.gradle b/java/com.sap.sailing.domain.common/build.gradle new file mode 100644 index 00000000000..15527d8ed39 --- /dev/null +++ b/java/com.sap.sailing.domain.common/build.gradle @@ -0,0 +1,14 @@ +apply plugin: "java" + +sourceSets { + main { + java.srcDirs = ["src"] + } +} + +dependencies { + /* local dependencies */ + compile project(":java:com.sap.sse.common") + compile project(":java:com.sap.sse.security.common") + compile project(":java:com.sap.sse.datamining.shared") +} diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/AbstractPosition.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/AbstractPosition.java index 03eeb9b64b8..b317e1aa2a5 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/AbstractPosition.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/AbstractPosition.java @@ -190,4 +190,48 @@ public class AbstractPosition implements Position { return "(" + getLatDeg() + "," + getLngDeg() + ")"; } + @Override + public Position getIntersection(Bearing thisBearing, Position to, Bearing toBearing) { + /* + * See http://www.movable-type.co.uk/scripts/latlong-vectors.html#intersection for explanation + */ + double radBearing1 = thisBearing.getRadians(); + double radLatPos1 = getLatRad(); + double radLngPos1 = getLngRad(); + double[] greatCircle1 = createGreatCircleVector(radBearing1, radLatPos1, radLngPos1); + double radBearing2 = toBearing.getRadians(); + double radLatPos2 = to.getLatRad(); + double radLngPos2 = to.getLngRad(); + double[] greatCircle2 = createGreatCircleVector(radBearing2, radLatPos2, radLngPos2); + double[] intersection1 = computeCrossProductOf3PartVectors(greatCircle1, greatCircle2); + double[] intersection2 = computeCrossProductOf3PartVectors(greatCircle2, greatCircle1); + Position intersectionPosition1 = cartesianVectorToPosition(intersection1); + Position intersectionPosition2 = cartesianVectorToPosition(intersection2); + Distance sumOfDistances1 = getDistance(intersectionPosition1).add(intersectionPosition1.getDistance(to)); + Distance sumOfDistances2 = getDistance(intersectionPosition2).add(intersectionPosition2.getDistance(to)); + return sumOfDistances1.compareTo(sumOfDistances2) < 0 ? intersectionPosition1 : intersectionPosition2; + } + + private Position cartesianVectorToPosition(double[] vector) { + double lat = Math.atan2(vector[2], Math.sqrt(vector[0]*vector[0] + vector[1]*vector[1])); + double lng = Math.atan2(vector[1], vector[0]); + return new RadianPosition(lat, lng); + } + + private double[] computeCrossProductOf3PartVectors(double[] vec1, double[] vec2) { + double[] crossProduct= new double[3]; + crossProduct[0] = vec1[1]*vec2[2] - vec1[2]*vec2[1]; + crossProduct[1] = vec1[2]*vec2[0] - vec1[0]*vec2[2]; + crossProduct[2] = vec1[0]*vec2[1] - vec1[1]*vec2[0]; + return crossProduct; + } + + private double[] createGreatCircleVector(double radBearing, double radLatPos, double radLngPos) { + double[] greatCircle = new double[3]; + greatCircle[0] = Math.sin(radLngPos) * Math.cos(radBearing) - Math.sin(radLatPos) * Math.cos(radLngPos) * Math.sin(radBearing); + greatCircle[1] = -Math.cos(radLngPos) * Math.cos(radBearing) - Math.sin(radLatPos) * Math.sin(radLngPos) * Math.sin(radBearing); + greatCircle[2] = Math.cos(radLatPos) * Math.sin(radBearing); + return greatCircle; + } + } diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/BoatClassMasterdata.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/BoatClassMasterdata.java index b1690aba141..201eb9b3b59 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/BoatClassMasterdata.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/BoatClassMasterdata.java @@ -43,6 +43,7 @@ public enum BoatClassMasterdata { NACRA_17 ("Nacra 17", true, 5.25, 2.59, BoatHullType.CATAMARAN, true, "N17", "Nacra-17"), OK ("OK Dinghy", true, 5.25, 2.59, BoatHullType.MONOHULL, false, "OK-Dinghy", "OK-Jolle", "OK"), OPTIMIST ("Optimist", true, 2.34, 1.07, BoatHullType.MONOHULL, false, "Opti", "Optimist Dinghy"), + PIRAT ("Pirat", true, 5.00, 1.61, BoatHullType.MONOHULL, false, "Pirate", "Piraten"), PLATU_25 ("Platu 25", true, 7.53, 2.62, BoatHullType.MONOHULL, true, "Platu", "Platu-25", "PLA", "B25"), RS_X ("RS:X", true, 2.86, 0.93, BoatHullType.SURFERBOARD, false, "RS-X", "RSX", "RS:X"), SONAR ("Sonar", true, 7.01, 2.39, BoatHullType.MONOHULL, true), diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/LegIdentifier.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/LegIdentifier.java new file mode 100644 index 00000000000..73ca7a2e740 --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/LegIdentifier.java @@ -0,0 +1,7 @@ +package com.sap.sailing.domain.common; + +public interface LegIdentifier extends RegattaAndRaceIdentifier { + RaceIdentifier getRaceIdentifier(); + String getLegName(); + int getLegNumber(); +} diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/LegIdentifierImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/LegIdentifierImpl.java new file mode 100644 index 00000000000..9800153f114 --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/LegIdentifierImpl.java @@ -0,0 +1,62 @@ +package com.sap.sailing.domain.common; + +public class LegIdentifierImpl extends RegattaNameAndRaceName implements LegIdentifier { + private static final long serialVersionUID = 3599904513673776450L; + private RaceIdentifier raceIdentifier = null; + private String legName; + + LegIdentifierImpl() {} + + public LegIdentifierImpl(RegattaAndRaceIdentifier raceIdentifier, String legName) { + super(raceIdentifier.getRegattaName(), raceIdentifier.getRaceName()); + this.raceIdentifier = raceIdentifier; + this.legName = legName; + } + + @Override + public RaceIdentifier getRaceIdentifier() { + return this.raceIdentifier; + } + + + @Override + public String getLegName() { + return legName; + } + + @Override + public int getLegNumber() { + return Integer.parseInt(legName)-1; + } + + @Override + public String toString() { + return getRegattaName() + "/" + getRaceName() + "/" + getLegName(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((legName == null) ? 0 : legName.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + LegIdentifierImpl other = (LegIdentifierImpl) obj; + if (legName == null) { + if (other.legName != null) + return false; + } else if (!legName.equals(other.legName)) + return false; + return true; + } + +} diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/Position.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/Position.java index 1856b1517d8..743a32d9f2d 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/Position.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/Position.java @@ -104,5 +104,16 @@ public interface Position extends Serializable { * The method executes efficiently and requires only one call to the cosine method. */ double getQuickApproximateNauticalMileDistance(Position p); + + /** + * Computes the intersection of two paths. The first path is defined by the underlying position and the parameter + * thisBearing. The second path is defined by parameters to and toBearing + * + * @param thisBearing defines first path with this position + * @param to defines second path with toBearing + * @param toBearing defines second path to position + * @return position of intersection. Since there are usually 2 intersections, we return the smaller intersection. + */ + Position getIntersection(Bearing thisBearing, Position to, Bearing toBearing); } diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/Speed.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/Speed.java index 06e375055e4..24cf5a802ed 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/Speed.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/Speed.java @@ -4,8 +4,8 @@ import java.io.Serializable; import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; -import com.sap.sse.datamining.shared.Unit; import com.sap.sse.datamining.shared.annotations.Statistic; +import com.sap.sse.datamining.shared.data.Unit; /** * A speed, convertible in various units of measure. Can be negative. diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/RacingProcedureType.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/RacingProcedureType.java index cae4906ed3e..2ae2e1dc64b 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/RacingProcedureType.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/RacingProcedureType.java @@ -13,7 +13,8 @@ public enum RacingProcedureType { RRS26("Fix Line Start (RRS26)"), GateStart("Gate Start"), ESS("\"Extreme Sailing Series\"-Start"), - BASIC("Basic Countdown Start"); + BASIC("Basic Countdown Start"), + LEAGUE("League Start"); private String displayName; diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/racelog/tracking/impl/MongoGPSFixStoreImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/racelog/tracking/impl/MongoGPSFixStoreImpl.java index d2ed5bd4f6b..d01b682e045 100755 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/racelog/tracking/impl/MongoGPSFixStoreImpl.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/racelog/tracking/impl/MongoGPSFixStoreImpl.java @@ -40,6 +40,7 @@ import com.sap.sse.common.TimeRange; import com.sap.sse.common.TypeBasedServiceFinder; import com.sap.sse.common.TypeBasedServiceFinderFactory; import com.sap.sse.common.Util; +import com.sap.sse.common.WithID; import com.sap.sse.common.impl.TimeRangeImpl; /** @@ -109,7 +110,6 @@ public class MongoGPSFixStoreImpl implements MongoGPSFixStore { public void loadCompetitorTrack(DynamicGPSFixTrack track, AbstractLog log, Competitor competitor) throws NoCorrespondingServiceRegisteredException, TransformationException{ List> mappings = new DeviceCompetitorMappingFinder<>(log).analyze().get(competitor); - if (mappings != null) { for (DeviceMapping mapping : mappings) { loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true /*inclusive*/); @@ -197,6 +197,12 @@ public class MongoGPSFixStoreImpl implements MongoGPSFixStore { loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true /*inclusive*/); } + @Override + public void loadTrack(DynamicGPSFixTrack track, DeviceMapping mapping) + throws NoCorrespondingServiceRegisteredException, TransformationException { + loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true); + } + private DBObject getDeviceQuery(DeviceIdentifier device) throws TransformationException, NoCorrespondingServiceRegisteredException { Object dbDeviceId = MongoObjectFactoryImpl.storeDeviceId(deviceServiceFinder, device); @@ -229,4 +235,5 @@ public class MongoGPSFixStoreImpl implements MongoGPSFixStore { } return ((Number) result.get(FieldNames.NUM_FIXES.name())).longValue(); } + } diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter.testsupport/src/com/sap/sailing/domain/racelog/tracking/test/mock/MockGPSFixMongoServiceFinder.java b/java/com.sap.sailing.domain.racelogtrackingadapter.testsupport/src/com/sap/sailing/domain/racelog/tracking/test/mock/MockGPSFixMongoServiceFinder.java index 5d5423be556..84bb3a4cc66 100644 --- a/java/com.sap.sailing.domain.racelogtrackingadapter.testsupport/src/com/sap/sailing/domain/racelog/tracking/test/mock/MockGPSFixMongoServiceFinder.java +++ b/java/com.sap.sailing.domain.racelogtrackingadapter.testsupport/src/com/sap/sailing/domain/racelog/tracking/test/mock/MockGPSFixMongoServiceFinder.java @@ -4,6 +4,8 @@ import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import com.sap.sailing.domain.common.tracking.impl.CompactGPSFixImpl; +import com.sap.sailing.domain.common.tracking.impl.CompactGPSFixMovingImpl; import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl; import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl; import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl; @@ -21,8 +23,10 @@ public class MockGPSFixMongoServiceFinder implements TypeBasedServiceFinder marks = new HashSet<>(); course.getWaypoints().forEach(wp->Util.addAll(wp.getMarks(), marks)); - Set competitors = new RegisteredCompetitorsAnalyzer<>(fromRaceLog).analyze(); + final Set competitors = new RegisteredCompetitorsAnalyzer<>(fromRaceLog).analyze(); + final List raceLogDeviceMarkMappingEvents = new AllEventsOfTypeFinder<>(fromRaceLog, /* only unrevoked */ true, RaceLogDeviceMarkMappingEvent.class).analyze(); for (RaceLog toRaceLog : toRaceLogs) { if (course == null || !new RaceLogTrackingStateAnalyzer(toRaceLog).analyze().isForTracking()) { continue; } - CourseBase to = new CourseDataImpl("Copy of \"" + course.getName()); + CourseBase newCourse = new CourseDataImpl("Copy of \"" + course.getName() + "\""); TimePoint now = MillisecondsTimePoint.now(); int i = 0; revokeAlreadyDefinedMarks(toRaceLog, service.getServerAuthor()); for (Waypoint oldWaypoint : course.getWaypoints()) { - to.addWaypoint(i++, oldWaypoint); + newCourse.addWaypoint(i++, oldWaypoint); } for (Mark mark : marks) { RaceLogEvent event = RaceLogEventFactory.INSTANCE.createDefineMarkEvent(now, service.getServerAuthor(), toRaceLog.getCurrentPassId(), mark); toRaceLog.add(event); } + for (RaceLogEvent raceLogDeviceMarkMappingEvent : raceLogDeviceMarkMappingEvents) { + toRaceLog.add(raceLogDeviceMarkMappingEvent); + } int passId = toRaceLog.getCurrentPassId(); RaceLogEvent newCourseEvent = RaceLogEventFactory.INSTANCE.createCourseDesignChangedEvent(now, - service.getServerAuthor(), passId, to); + service.getServerAuthor(), passId, newCourse); toRaceLog.add(newCourseEvent); registerCompetitors(service, toRaceLog, competitors); } diff --git a/java/com.sap.sailing.domain.shared.android/META-INF/MANIFEST.MF b/java/com.sap.sailing.domain.shared.android/META-INF/MANIFEST.MF index 6431fe5e794..5e841b9aafc 100644 --- a/java/com.sap.sailing.domain.shared.android/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.domain.shared.android/META-INF/MANIFEST.MF @@ -35,6 +35,7 @@ Export-Package: com.sap.sailing.domain.abstractlog, com.sap.sailing.domain.abstractlog.regatta.events, com.sap.sailing.domain.abstractlog.regatta.events.impl, com.sap.sailing.domain.abstractlog.regatta.impl, + com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl, com.sap.sailing.domain.abstractlog.shared.analyzing, com.sap.sailing.domain.abstractlog.shared.events, com.sap.sailing.domain.base, diff --git a/java/com.sap.sailing.domain.shared.android/build.gradle b/java/com.sap.sailing.domain.shared.android/build.gradle new file mode 100644 index 00000000000..b75064f8383 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/build.gradle @@ -0,0 +1,15 @@ +apply plugin: "java" + +sourceSets { + main { + java.srcDirs = ["src"] + } +} + +dependencies { + /* local dependencies */ + compile project(":java:com.sap.sailing.domain.common") + compile project(":java:com.sap.sse.common") + compile project(":java:com.sap.sse.datamining.shared") + compile project(":java:com.sap.sse.shared.android") +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/impl/ReadonlyRacingProcedureFactory.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/impl/ReadonlyRacingProcedureFactory.java index 69f7e652ffe..4062f7a9893 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/impl/ReadonlyRacingProcedureFactory.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/impl/ReadonlyRacingProcedureFactory.java @@ -11,6 +11,7 @@ import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.ReadonlyRac import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.basic.impl.BasicRacingProcedureImpl; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.ess.impl.ESSRacingProcedureImpl; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.gate.impl.GateStartRacingProcedureImpl; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.impl.LeagueRacingProcedureImpl; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.rrs26.impl.RRS26RacingProcedureImpl; import com.sap.sailing.domain.base.configuration.ConfigurationLoader; import com.sap.sailing.domain.base.configuration.RegattaConfiguration; @@ -48,6 +49,8 @@ public class ReadonlyRacingProcedureFactory implements RacingProcedureFactory { return new RRS26RacingProcedureImpl(raceLog, author, factory, loadedConfiguration.getRRS26Configuration()); case BASIC: return new BasicRacingProcedureImpl(raceLog, author, factory, loadedConfiguration.getBasicConfiguration()); + case LEAGUE: + return new LeagueRacingProcedureImpl(raceLog, author, factory, loadedConfiguration.getLeagueConfiguration()); default: throw new UnsupportedOperationException("Unknown racing procedure " + type.toString()); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/LeagueRacingProcedure.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/LeagueRacingProcedure.java new file mode 100755 index 00000000000..ffbd1b0bba8 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/LeagueRacingProcedure.java @@ -0,0 +1,7 @@ +package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league; + +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure; + +public interface LeagueRacingProcedure extends RacingProcedure { + +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/LeagueRacingProcedureChangedListener.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/LeagueRacingProcedureChangedListener.java new file mode 100644 index 00000000000..21f54c2e45b --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/LeagueRacingProcedureChangedListener.java @@ -0,0 +1,6 @@ +package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league; + +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedureChangedListener; + +public interface LeagueRacingProcedureChangedListener extends RacingProcedureChangedListener { +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeaguePrerequisite.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeaguePrerequisite.java new file mode 100755 index 00000000000..291c8ec9e6e --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeaguePrerequisite.java @@ -0,0 +1,22 @@ +package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.impl; + +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedurePrerequisite; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.BaseRacingProcedurePrerequisite; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.LeagueRacingProcedure; +import com.sap.sse.common.TimePoint; + +/** + * Easy access to the {@link LeagueRacingProcedure}. + */ +public abstract class LeaguePrerequisite extends BaseRacingProcedurePrerequisite implements RacingProcedurePrerequisite { + + public LeaguePrerequisite(FulfillmentFunction function, LeagueRacingProcedure procedure, TimePoint originalNow, + TimePoint originalStartTime) { + super(function, procedure, originalNow, originalStartTime); + } + + protected LeagueRacingProcedure getProcedure() { + return (LeagueRacingProcedure) procedure; + } + +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeagueRacingProcedureChangedListeners.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeagueRacingProcedureChangedListeners.java new file mode 100644 index 00000000000..e0bece8f93e --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeagueRacingProcedureChangedListeners.java @@ -0,0 +1,8 @@ +package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.impl; + +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.RacingProcedureChangedListeners; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.LeagueRacingProcedureChangedListener; + +public class LeagueRacingProcedureChangedListeners extends RacingProcedureChangedListeners implements + LeagueRacingProcedureChangedListener { +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeagueRacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeagueRacingProcedureImpl.java new file mode 100755 index 00000000000..2ba9189ad0a --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/racingprocedure/league/impl/LeagueRacingProcedureImpl.java @@ -0,0 +1,154 @@ +package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.impl; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; +import com.sap.sailing.domain.abstractlog.race.RaceLog; +import com.sap.sailing.domain.abstractlog.race.RaceLogEventFactory; +import com.sap.sailing.domain.abstractlog.race.state.RaceStateEvent; +import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateEventImpl; +import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateEvents; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.FlagPoleState; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedureChangedListener; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedurePrerequisite; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedurePrerequisite.FulfillmentFunction; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.BaseRacingProcedure; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.NoMorePrerequisite; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.RacingProcedureChangedListeners; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.LeagueRacingProcedure; +import com.sap.sailing.domain.base.configuration.procedures.LeagueConfiguration; +import com.sap.sailing.domain.common.racelog.FlagPole; +import com.sap.sailing.domain.common.racelog.Flags; +import com.sap.sailing.domain.common.racelog.RacingProcedureType; +import com.sap.sse.common.TimePoint; + +// TODO consider subclassing RRS26RacingProcedureImpl instead of this copy&paste orgy... +public class LeagueRacingProcedureImpl extends BaseRacingProcedure implements LeagueRacingProcedure { + private final static long startPhaseClassUpInterval = 3 * 60 * 1000; // minutes * seconds * milliseconds + private final static long startPhaseStartModeUpInterval = 2 * 60 * 1000; // minutes * seconds * milliseconds + private final static long startPhaseStartModeDownInterval = 1 * 60 * 1000; // minutes * seconds * milliseconds + + private final static Flags startmodeFlag = Flags.PAPA; + + public LeagueRacingProcedureImpl(RaceLog raceLog, AbstractLogEventAuthor author, + RaceLogEventFactory factory, LeagueConfiguration configuration) { + super(raceLog, author, factory, configuration); + update(); + } + + @Override + public RacingProcedureType getType() { + return RacingProcedureType.LEAGUE; + } + + @Override + public boolean hasIndividualRecall() { + boolean hasRecall = super.hasIndividualRecall(); + if (!hasRecall) { + return false; + } else { + return hasRecall; + } + } + + @Override + protected boolean hasIndividualRecallByDefault() { + return true; + } + + @Override + public RacingProcedurePrerequisite checkPrerequisitesForStart(TimePoint now, TimePoint startTime, + FulfillmentFunction function) { + return new NoMorePrerequisite(function); + } + + @Override + public boolean isStartphaseActive(TimePoint startTime, TimePoint now) { + if (now.before(startTime)) { + long timeTillStart = startTime.minus(now.asMillis()).asMillis(); + return timeTillStart < startPhaseClassUpInterval; + } + return false; + } + + public boolean processStateEvent(RaceStateEvent event) { + switch (event.getEventName()) { + case RRS26_STARTMODE_UP: + case RRS26_CLASS_UP: + case RRS26_STARTMODE_DOWN: + getChangedListeners().onActiveFlagsChanged(this); + return true; + default: + return super.processStateEvent(event); + } + } + + @Override + protected Collection createStartStateEvents(TimePoint startTime) { + // Remark: We are reusing here CLASS_UP, STARTMODE_UP and STARTMODE_DOWN from the RRS26 procedure + // The question is why there are no generic CLASS_UP, STARTMODE_UP and STARTMODE_DOWN events + return Arrays. asList( + new RaceStateEventImpl(startTime.minus(startPhaseClassUpInterval), RaceStateEvents.RRS26_CLASS_UP), + new RaceStateEventImpl(startTime.minus(startPhaseStartModeUpInterval), RaceStateEvents.RRS26_STARTMODE_UP), + new RaceStateEventImpl(startTime.minus(startPhaseStartModeDownInterval), RaceStateEvents.RRS26_STARTMODE_DOWN), + new RaceStateEventImpl(startTime, RaceStateEvents.START)); + } + + @Override + public FlagPoleState getActiveFlags(TimePoint startTime, TimePoint now) { + Flags classFlag = getConfiguration().getClassFlag() != null ? + getConfiguration().getClassFlag() : Flags.CLASS; + if (now.before(startTime.minus(startPhaseClassUpInterval))) { + return new FlagPoleState( + Arrays.asList(new FlagPole(classFlag, false), new FlagPole(startmodeFlag, false)), + null, + Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, false)), + startTime.minus(startPhaseClassUpInterval)); + } else if (now.before(startTime.minus(startPhaseStartModeUpInterval))) { + return new FlagPoleState( + Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, false)), + startTime.minus(startPhaseClassUpInterval), + Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, true)), + startTime.minus(startPhaseStartModeUpInterval)); + } else if (now.before(startTime.minus(startPhaseStartModeDownInterval))) { + return new FlagPoleState( + Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, true)), + startTime.minus(startPhaseStartModeUpInterval), + Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, false)), + startTime.minus(startPhaseStartModeDownInterval)); + } else if (now.before(startTime)) { + return new FlagPoleState( + Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, false)), + startTime.minus(startPhaseStartModeDownInterval), + Arrays.asList(new FlagPole(classFlag, false), new FlagPole(startmodeFlag, false)), + startTime); + } else { + if (isIndividualRecallDisplayed(now)) { + return new FlagPoleState( + Arrays.asList(new FlagPole(Flags.XRAY, true)), + getIndividualRecallDisplayedTime(), + Arrays.asList(new FlagPole(Flags.XRAY, false)), + getIndividualRecallRemovalTime()); + } else if (isFinished(now)) { + return new FlagPoleState( + Arrays.asList(new FlagPole(Flags.BLUE, false)), getFinishedTime()); + } else if (isInFinishingPhase(now)) { + return new FlagPoleState( + Arrays.asList(new FlagPole(Flags.BLUE, true)), + getFinishingTime(), + Arrays.asList(new FlagPole(Flags.BLUE, false)), + null); + } else { + TimePoint recallRemoved = getIndividualRecallRemovalTime(); + return new FlagPoleState(Collections.emptyList(), recallRemoved == null ? startTime : recallRemoved); + } + } + } + + @Override + protected RacingProcedureChangedListeners createChangedListenerContainer() { + return new LeagueRacingProcedureChangedListeners(); + } +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/tracking/analyzing/impl/RegattaLogOpenEndedDeviceMappingCloser.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/tracking/analyzing/impl/RegattaLogOpenEndedDeviceMappingCloser.java new file mode 100644 index 00000000000..03e9945894f --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/tracking/analyzing/impl/RegattaLogOpenEndedDeviceMappingCloser.java @@ -0,0 +1,31 @@ +package com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl; + +import java.io.Serializable; +import java.util.UUID; + +import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; +import com.sap.sailing.domain.abstractlog.regatta.RegattaLog; +import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent; +import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor; +import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent; +import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogCloseOpenEndedDeviceMappingEventImpl; +import com.sap.sailing.domain.abstractlog.shared.analyzing.OpenEndedDeviceMappingCloser; +import com.sap.sailing.domain.racelogtracking.DeviceMapping; +import com.sap.sse.common.TimePoint; +import com.sap.sse.common.impl.MillisecondsTimePoint; + +public class RegattaLogOpenEndedDeviceMappingCloser extends + OpenEndedDeviceMappingCloser { + + public RegattaLogOpenEndedDeviceMappingCloser(RegattaLog log, DeviceMapping mapping, AbstractLogEventAuthor author, + TimePoint closingTimePoint) { + super(log, mapping, author, closingTimePoint); + } + + @Override + protected RegattaLogCloseOpenEndedDeviceMappingEvent createCloseEvent(TimePoint logicalTimePoint, + Serializable eventToCloseId) { + return new RegattaLogCloseOpenEndedDeviceMappingEventImpl(MillisecondsTimePoint.now(), author, + logicalTimePoint, UUID.randomUUID(), eventToCloseId, closingTimePoint); + } +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/analyzing/DeviceCompetitorMappingFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/analyzing/DeviceCompetitorMappingFinder.java index d3193e3083f..c562f1e6066 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/analyzing/DeviceCompetitorMappingFinder.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/analyzing/DeviceCompetitorMappingFinder.java @@ -21,7 +21,6 @@ public class DeviceCompetitorMappingFinder>>> createAnalyzer(AbstractLog log) { return new DeviceCompetitorMappingFinder(log); } - } public DeviceCompetitorMappingFinder(LogT log) { diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/CompetitorChangeListener.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/CompetitorChangeListener.java index a72bbbb6721..3eefc4c815d 100755 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/CompetitorChangeListener.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/CompetitorChangeListener.java @@ -1,5 +1,7 @@ package com.sap.sailing.domain.base; +import java.net.URI; + import com.sap.sse.common.Color; public interface CompetitorChangeListener extends BoatChangeListener, NationalityChangeListener { @@ -8,4 +10,6 @@ public interface CompetitorChangeListener extends BoatChangeListener, Nationalit void nameChanged(String oldName, String newName); void emailChanged(String oldEmail, String newEmail); + + void flagImageChanged(URI oldFlagImageURI, URI newFlagImageURI); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/RegattaConfiguration.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/RegattaConfiguration.java index c2aebdeb662..cf45996625e 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/RegattaConfiguration.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/RegattaConfiguration.java @@ -5,6 +5,7 @@ import java.io.Serializable; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure; import com.sap.sailing.domain.base.configuration.procedures.ESSConfiguration; import com.sap.sailing.domain.base.configuration.procedures.GateStartConfiguration; +import com.sap.sailing.domain.base.configuration.procedures.LeagueConfiguration; import com.sap.sailing.domain.base.configuration.procedures.RRS26Configuration; import com.sap.sailing.domain.common.CourseDesignerMode; import com.sap.sailing.domain.common.racelog.RacingProcedureType; @@ -42,7 +43,13 @@ public interface RegattaConfiguration extends Serializable, Cloneable { * @return null if there is no configuration. */ ESSConfiguration getESSConfiguration(); - + + /** + * Gets the configuration for league races. + * @return null if there is no configuration. + */ + LeagueConfiguration getLeagueConfiguration(); + /** * Gets the configuration for Basic races. * @return null if there is no configuration. diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/EmptyRegattaConfiguration.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/EmptyRegattaConfiguration.java index 799654d8425..76e5fc9fdb7 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/EmptyRegattaConfiguration.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/EmptyRegattaConfiguration.java @@ -21,6 +21,7 @@ public class EmptyRegattaConfiguration extends RegattaConfigurationImpl implemen setGateStartConfiguration(new GateStartConfigurationImpl()); setESSConfiguration(new ESSConfigurationImpl()); setBasicConfiguration(new RacingProcedureConfigurationImpl()); + setLeagueConfiguration(new LeagueConfigurationImpl()); return clone(); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/LeagueConfigurationImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/LeagueConfigurationImpl.java new file mode 100644 index 00000000000..1b18ffa2b8f --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/LeagueConfigurationImpl.java @@ -0,0 +1,20 @@ +package com.sap.sailing.domain.base.configuration.impl; + +import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration; +import com.sap.sailing.domain.base.configuration.procedures.LeagueConfiguration; + +public class LeagueConfigurationImpl extends RacingProcedureConfigurationImpl implements LeagueConfiguration { + private static final long serialVersionUID = 3625803505541394766L; + + protected LeagueConfigurationImpl copy() { + LeagueConfigurationImpl copy = (LeagueConfigurationImpl) super.copy(new LeagueConfigurationImpl()); + return copy; + } + + @Override + public RacingProcedureConfiguration merge(RacingProcedureConfiguration update) { + LeagueConfigurationImpl target = (LeagueConfigurationImpl) super.merge(update); + return target; + } + +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/RegattaConfigurationImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/RegattaConfigurationImpl.java index bfc8f0eda91..965f5070b74 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/RegattaConfigurationImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/RegattaConfigurationImpl.java @@ -4,6 +4,7 @@ import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration; import com.sap.sailing.domain.base.configuration.RegattaConfiguration; import com.sap.sailing.domain.base.configuration.procedures.ESSConfiguration; import com.sap.sailing.domain.base.configuration.procedures.GateStartConfiguration; +import com.sap.sailing.domain.base.configuration.procedures.LeagueConfiguration; import com.sap.sailing.domain.base.configuration.procedures.RRS26Configuration; import com.sap.sailing.domain.common.CourseDesignerMode; import com.sap.sailing.domain.common.racelog.RacingProcedureType; @@ -18,6 +19,7 @@ public class RegattaConfigurationImpl implements RegattaConfiguration { private RRS26Configuration rrs26Configuration; private GateStartConfiguration gateStartConfiguration; private ESSConfiguration essConfiguration; + private LeagueConfiguration leagueConfiguration; private RacingProcedureConfiguration basicConfiguration; @Override @@ -65,6 +67,15 @@ public class RegattaConfigurationImpl implements RegattaConfiguration { this.essConfiguration = essConfiguration; } + @Override + public LeagueConfiguration getLeagueConfiguration() { + return leagueConfiguration; + } + + public void setLeagueConfiguration(LeagueConfiguration leagueConfiguration) { + this.leagueConfiguration = leagueConfiguration; + } + @Override public RacingProcedureConfiguration getBasicConfiguration() { return basicConfiguration; @@ -83,6 +94,7 @@ public class RegattaConfigurationImpl implements RegattaConfiguration { copy.setGateStartConfiguration(gateStartConfiguration); copy.setESSConfiguration(essConfiguration); copy.setBasicConfiguration(basicConfiguration); + copy.setLeagueConfiguration(leagueConfiguration); return copy; } @@ -112,6 +124,10 @@ public class RegattaConfigurationImpl implements RegattaConfiguration { target.setBasicConfiguration( (RacingProcedureConfiguration) target.getBasicConfiguration().merge(update.getBasicConfiguration())); } + if (update.getLeagueConfiguration() != null) { + target.setLeagueConfiguration( + (LeagueConfiguration) target.getLeagueConfiguration().merge(update.getLeagueConfiguration())); + } return target; } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/procedures/LeagueConfiguration.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/procedures/LeagueConfiguration.java new file mode 100644 index 00000000000..1cf4fdfa3c7 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/procedures/LeagueConfiguration.java @@ -0,0 +1,7 @@ +package com.sap.sailing.domain.base.configuration.procedures; + +import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration; + +public interface LeagueConfiguration extends RacingProcedureConfiguration { + +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/CompetitorImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/CompetitorImpl.java index 6fcdf0a67de..c6219199e53 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/CompetitorImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/CompetitorImpl.java @@ -145,6 +145,12 @@ public class CompetitorImpl implements DynamicCompetitor { @Override public void setFlagImage(URI flagImage) { + final URI oldFlagImage = this.flagImage; this.flagImage = flagImage; + if (!Util.equalsWithNull(oldFlagImage, flagImage)) { + for (CompetitorChangeListener listener : getListeners()) { + listener.flagImageChanged(oldFlagImage, flagImage); + } + } } } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/SharedDomainFactoryImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/SharedDomainFactoryImpl.java index 35602ff97bd..f30cf88fb37 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/SharedDomainFactoryImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/SharedDomainFactoryImpl.java @@ -179,10 +179,14 @@ public class SharedDomainFactoryImpl implements SharedDomainFactory { @Override public ControlPointWithTwoMarks getOrCreateControlPointWithTwoMarks(Serializable id, String name, Mark left, Mark right) { - if (controlPointWithTwoMarksCache.containsKey(id)) { - return controlPointWithTwoMarksCache.get(id); + final ControlPointWithTwoMarks result; + final ControlPointWithTwoMarks fromCache = controlPointWithTwoMarksCache.get(id); + if (fromCache != null) { + result = fromCache; + } else { + result = createControlPointWithTwoMarks(id, left, right, name); } - return createControlPointWithTwoMarks(id, left, right, name); + return result; } @Override diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/racegroup/RaceGroup.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/racegroup/RaceGroup.java index 9a920e05f7b..d68e0b4e04c 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/racegroup/RaceGroup.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/racegroup/RaceGroup.java @@ -47,4 +47,10 @@ public interface RaceGroup extends Named { * Gets configuration objects for {@link RacingProcedure}s of this {@link RaceGroup}'s races. */ public RegattaConfiguration getRegattaConfiguration(); + + /** + * An optional (may be null0 non-identifying name that may, e.g., be a short name + * for the necessarily unique and therefore potentially longer, maybe clumsy full {@link #getName()}. + */ + String getDisplayName(); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/racegroup/impl/RaceGroupImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/racegroup/impl/RaceGroupImpl.java index 2f6eac28f39..cb3a9e84d9f 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/racegroup/impl/RaceGroupImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/racegroup/impl/RaceGroupImpl.java @@ -10,29 +10,39 @@ import com.sap.sse.common.impl.NamedImpl; public class RaceGroupImpl extends NamedImpl implements RaceGroup { private static final long serialVersionUID = 7760879536339600827L; - + + private final String displayName; private final BoatClass boatClass; private final CourseArea courseArea; private final Iterable series; private final RegattaConfiguration regattaConfiguration; - public RaceGroupImpl(String name, BoatClass boatClass, CourseArea courseArea, Iterable series, - RegattaConfiguration regattaConfiguration) { + public RaceGroupImpl(String name, String displayName, BoatClass boatClass, CourseArea courseArea, + Iterable series, RegattaConfiguration regattaConfiguration) { super(name); + this.displayName = displayName; this.boatClass = boatClass; this.courseArea = courseArea; this.series = series; this.regattaConfiguration = regattaConfiguration; } + @Override + public String getDisplayName() { + return displayName; + } + + @Override public CourseArea getDefaultCourseArea() { return courseArea; } + @Override public Iterable getSeries() { return series; } + @Override public BoatClass getBoatClass() { return boatClass; } diff --git a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryImpl.java b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryImpl.java index 769fa9b6dd8..8ab7f08b9c2 100755 --- a/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryImpl.java +++ b/java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryImpl.java @@ -319,7 +319,7 @@ public class DomainFactoryImpl implements DomainFactory { for (Mark mark : marks) { // TODO bug 1043: propagate the mark names to the waypoint names com.sap.sailing.domain.base.ControlPoint domainControlPoint = getOrCreateControlPoint(mark.getDevices()); - newDomainControlPoints.add(new com.sap.sse.common.Util.Pair(domainControlPoint, null)); + newDomainControlPoints.add(new com.sap.sse.common.Util.Pair<>(domainControlPoint, PassingInstruction.None)); } courseToUpdate.update(newDomainControlPoints, baseDomainFactory); } diff --git a/java/com.sap.sailing.domain.swisstimingreplayadapter/src/com/sap/sailing/domain/swisstimingreplayadapter/impl/SwissTimingReplayToDomainAdapter.java b/java/com.sap.sailing.domain.swisstimingreplayadapter/src/com/sap/sailing/domain/swisstimingreplayadapter/impl/SwissTimingReplayToDomainAdapter.java index 93092e40b72..fa87e202b21 100755 --- a/java/com.sap.sailing.domain.swisstimingreplayadapter/src/com/sap/sailing/domain/swisstimingreplayadapter/impl/SwissTimingReplayToDomainAdapter.java +++ b/java/com.sap.sailing.domain.swisstimingreplayadapter/src/com/sap/sailing/domain/swisstimingreplayadapter/impl/SwissTimingReplayToDomainAdapter.java @@ -53,6 +53,7 @@ import com.sap.sailing.domain.tracking.impl.MarkPassingImpl; import com.sap.sailing.domain.tracking.impl.TrackedRaceStatusImpl; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; +import com.sap.sse.common.Util.Pair; import com.sap.sse.common.impl.MillisecondsTimePoint; import difflib.PatchFailedException; @@ -294,9 +295,9 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter { Course course = race.getCourse(); try { // TODO: Does SwissTiming also deliver the passing side for course marks? - List> courseToUpdate = new ArrayList>(); + List> courseToUpdate = new ArrayList<>(); for (ControlPoint cp : currentCourseDefinition) { - courseToUpdate.add(new com.sap.sse.common.Util.Pair(cp, null)); + courseToUpdate.add(new Pair(cp, PassingInstruction.None)); } course.update(courseToUpdate, domainFactory.getBaseDomainFactory()); } catch (PatchFailedException e) { diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/AbstractTracTracLiveTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/AbstractTracTracLiveTest.java index 901f7dd24a5..98180307380 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/AbstractTracTracLiveTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/AbstractTracTracLiveTest.java @@ -149,9 +149,9 @@ public abstract class AbstractTracTracLiveTest extends StoredTrackBasedTest { } public static Iterable> getTracTracControlPointsWithPassingInstructions(Iterable controlPoints) { - List> ttControlPoints = new ArrayList>(); + List> ttControlPoints = new ArrayList<>(); for (IControl cp : controlPoints) { - ttControlPoints.add(new Pair(new ControlPointAdapter(cp), null)); + ttControlPoints.add(new Pair(new ControlPointAdapter(cp), PassingInstruction.None)); } return ttControlPoints; } diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/CompetitorListenerTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/CompetitorListenerTest.java index ca8acdfaa70..0c3a2217219 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/CompetitorListenerTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/CompetitorListenerTest.java @@ -7,6 +7,8 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import org.junit.Before; import org.junit.Test; @@ -45,6 +47,12 @@ public class CompetitorListenerTest extends AbstractSerializationTest { private Color newColor; private DynamicCompetitor competitor; private DomainFactoryImpl baseDomainFactory; + private boolean emailChanged; + private String oldEmail; + private String newEmail; + private boolean flagImageChanged; + private URI oldFlagImageURL; + private URI newFlagImageURL; @Before public void setUp() { @@ -63,6 +71,12 @@ public class CompetitorListenerTest extends AbstractSerializationTest { colorChanged = false; oldColor = null; newColor = null; + emailChanged = false; + oldEmail = null; + newEmail = null; + flagImageChanged = false; + oldFlagImageURL = null; + newFlagImageURL = null; listener = new CompetitorChangeListener() { private static final long serialVersionUID = 4581029778988240209L; @@ -97,7 +111,16 @@ public class CompetitorListenerTest extends AbstractSerializationTest { @Override public void emailChanged(String oldEmail, String newEmail) { - //TODO + emailChanged = true; + CompetitorListenerTest.this.oldEmail = oldEmail; + CompetitorListenerTest.this.newEmail = newEmail; + } + + @Override + public void flagImageChanged(URI oldFlagImageURL, URI newFlagImageURL) { + flagImageChanged = true; + CompetitorListenerTest.this.oldFlagImageURL = oldFlagImageURL; + CompetitorListenerTest.this.newFlagImageURL = newFlagImageURL; } }; competitor.addCompetitorChangeListener(listener); @@ -126,6 +149,22 @@ public class CompetitorListenerTest extends AbstractSerializationTest { assertFalse(nationalityChanged); } + @Test + public void testFlagChange() throws URISyntaxException { + competitor.setFlagImage(new URI("http://www.something.de/pic.png")); + assertTrue(flagImageChanged); + assertNull(oldFlagImageURL); + assertEquals(new URI("http://www.something.de/pic.png"), newFlagImageURL); + } + + @Test + public void testEmailChange() throws URISyntaxException { + competitor.setEmail("hasso.plattner@sap.com"); + assertTrue(emailChanged); + assertNull(oldEmail); + assertEquals("hasso.plattner@sap.com", newEmail); + } + @Test public void testSimpleCompetitorListenerPatternForSailId() { final String myOldSailId = competitor.getBoat().getSailID(); diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/CourseUpdateTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/CourseUpdateTest.java index b7f07a53906..07eb229db4a 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/CourseUpdateTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/CourseUpdateTest.java @@ -2,6 +2,7 @@ package com.sap.sailing.domain.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; @@ -31,6 +32,7 @@ import com.sap.sailing.domain.base.Waypoint; import com.sap.sailing.domain.base.impl.CourseImpl; import com.sap.sailing.domain.base.impl.MarkImpl; import com.sap.sailing.domain.base.impl.WaypointImpl; +import com.sap.sailing.domain.common.PassingInstruction; import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore; import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore; import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet; @@ -47,6 +49,7 @@ import com.sap.sailing.domain.tractracadapter.impl.ControlPointAdapter; import com.sap.sailing.domain.tractracadapter.impl.DomainFactoryImpl; import com.sap.sailing.domain.tractracadapter.impl.RaceCourseReceiver; import com.sap.sse.common.Util; +import com.sap.sse.common.Util.Pair; import com.sap.sse.common.Util.Triple; import com.tractrac.model.lib.api.event.CreateModelException; import com.tractrac.model.lib.api.event.IRace; @@ -166,6 +169,35 @@ public class CourseUpdateTest extends AbstractTracTracLiveTest { assertEquals(wp2, deletedWaypoints.iterator().next()); } + /** + * A test failing before bug 2858 was fixed: updating only the {@link PassingInstructions} of a {@link Waypoint#getPassingInstructions() waypoint} + * would have left the waypoint in place, not updating the course properly. + */ + @Test + public void testWaypointListDiffWithDifferentPassingInstructionsOnly() throws PatchFailedException { + Waypoint wp1 = new WaypointImpl(new MarkImpl("b1"), PassingInstruction.Port); + Waypoint wp2 = new WaypointImpl(new MarkImpl("b2"), PassingInstruction.Port); + Waypoint wp3 = new WaypointImpl(new MarkImpl("b3"), PassingInstruction.Port); + Waypoint wp4 = new WaypointImpl(new MarkImpl("b4"), PassingInstruction.Port); + List waypoints = new ArrayList(4); + waypoints.add(wp1); + waypoints.add(wp2); + waypoints.add(wp3); + waypoints.add(wp4); + Course course = new CourseImpl("Test Course", waypoints); + List> changedControlPoints = new ArrayList<>(); + changedControlPoints.add(new Pair<>(wp1.getControlPoint(), PassingInstruction.Starboard)); + changedControlPoints.add(new Pair<>(wp2.getControlPoint(), wp2.getPassingInstructions())); + changedControlPoints.add(new Pair<>(wp3.getControlPoint(), wp3.getPassingInstructions())); + changedControlPoints.add(new Pair<>(wp4.getControlPoint(), wp4.getPassingInstructions())); + course.update(changedControlPoints, com.sap.sailing.domain.base.DomainFactory.INSTANCE); + + assertNotSame(wp1, Util.get(course.getWaypoints(), 0)); + assertSame(wp2, Util.get(course.getWaypoints(), 1)); + assertSame(wp3, Util.get(course.getWaypoints(), 2)); + assertSame(wp4, Util.get(course.getWaypoints(), 3)); + } + @Test public void testLastWaypointRemoved() throws PatchFailedException, InterruptedException { final boolean[] result = new boolean[1]; diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TargetTimeEstimationTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TargetTimeEstimationTest.java new file mode 100644 index 00000000000..b4a8a8bf09a --- /dev/null +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TargetTimeEstimationTest.java @@ -0,0 +1,199 @@ +package com.sap.sailing.domain.test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.junit.Test; + +import com.sap.sailing.domain.base.BoatClass; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.Leg; +import com.sap.sailing.domain.base.RaceDefinition; +import com.sap.sailing.domain.base.SpeedWithBearingWithConfidence; +import com.sap.sailing.domain.base.SpeedWithConfidence; +import com.sap.sailing.domain.base.Waypoint; +import com.sap.sailing.domain.base.impl.SpeedWithBearingWithConfidenceImpl; +import com.sap.sailing.domain.base.impl.SpeedWithConfidenceImpl; +import com.sap.sailing.domain.common.Bearing; +import com.sap.sailing.domain.common.LegType; +import com.sap.sailing.domain.common.NoWindException; +import com.sap.sailing.domain.common.Position; +import com.sap.sailing.domain.common.SpeedWithBearing; +import com.sap.sailing.domain.common.Tack; +import com.sap.sailing.domain.common.Wind; +import com.sap.sailing.domain.common.WindSource; +import com.sap.sailing.domain.common.WindSourceType; +import com.sap.sailing.domain.common.impl.DegreeBearingImpl; +import com.sap.sailing.domain.common.impl.DegreePosition; +import com.sap.sailing.domain.common.impl.KnotSpeedImpl; +import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl; +import com.sap.sailing.domain.common.impl.WindImpl; +import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException; +import com.sap.sailing.domain.polars.PolarDataService; +import com.sap.sailing.domain.tracking.TrackedLeg; +import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl; +import com.sap.sailing.domain.tracking.impl.TrackedLegImpl; +import com.sap.sse.common.Duration; +import com.sap.sse.common.TimePoint; +import com.sap.sse.common.impl.MillisecondsTimePoint; + +public class TargetTimeEstimationTest { + + @Test + public void simpleReachTargetTimeEstimation() throws NotEnoughDataHasBeenAddedException, NoWindException { + // Setup mock objects + PolarDataService mockedPolars = mock(PolarDataService.class); + BoatClass mockedBoatClass = mock(BoatClass.class); + Position centerOfCourse = new DegreePosition(54.432800, 10.193655); + TimePoint timepoint = new MillisecondsTimePoint(1431426491696l); + Bearing windBearing = new DegreeBearingImpl(90); + SpeedWithBearing windSpeedWithBearing = new KnotSpeedWithBearingImpl(10, windBearing); + Wind wind = new WindImpl(centerOfCourse, timepoint, windSpeedWithBearing); + Position startOfLeg = new DegreePosition(54.434648, 10.193312); + Position endOfLeg = new DegreePosition(54.430454, 10.193226); + Bearing legBearing = startOfLeg.getBearingGreatCircle(endOfLeg); + SpeedWithConfidence boatSpeedWithConfidence = new SpeedWithConfidenceImpl(new KnotSpeedImpl(12), 1, null); + DynamicTrackedRaceImpl trackedRace = mock(DynamicTrackedRaceImpl.class); + when(trackedRace.getCenterOfCourse(timepoint)).thenReturn(centerOfCourse); + WindSource source = mock(WindSource.class); + Set sources = Collections.singleton(source); + when(trackedRace.getWindSources(WindSourceType.TRACK_BASED_ESTIMATION)).thenReturn(sources); + when(trackedRace.getWind(any(Position.class), eq(timepoint), eq(sources))).thenReturn(wind); + + RaceDefinition race = mock(RaceDefinition.class); + when(race.getBoatClass()).thenReturn(mockedBoatClass); + + when(trackedRace.getRace()).thenReturn(race); + + Leg leg = mock(Leg.class); + Waypoint from = mock(Waypoint.class); + Waypoint to = mock(Waypoint.class); + when(leg.getFrom()).thenReturn(from); + when(leg.getTo()).thenReturn(to); + + when(trackedRace.getApproximatePosition(from, timepoint)).thenReturn(startOfLeg); + when(trackedRace.getApproximatePosition(to, timepoint)).thenReturn(endOfLeg); + + when(mockedPolars.getSpeed(mockedBoatClass, wind, windBearing.getDifferenceTo(legBearing))).thenReturn(boatSpeedWithConfidence); + + HashSet competitors = new HashSet(); + TrackedLeg trackedLeg = new TrackedLegImpl(trackedRace, leg, competitors); + + //Actual test of functionality + Duration duration = trackedLeg.getEstimatedTimeToComplete(mockedPolars, timepoint); + assertEquals(75494, duration.asMillis(), 100); + + } + + @Test + public void simpleUpwindTargetTimeEstimation() throws NotEnoughDataHasBeenAddedException, NoWindException { + // Setup mock objects + PolarDataService mockedPolars = mock(PolarDataService.class); + BoatClass mockedBoatClass = mock(BoatClass.class); + Position centerOfCourse = new DegreePosition(54.432800, 10.193655); + TimePoint timepoint = new MillisecondsTimePoint(1431426491696l); + Bearing windBearing = new DegreeBearingImpl(-175); + SpeedWithBearing windSpeedWithBearing = new KnotSpeedWithBearingImpl(10, windBearing); + Wind wind = new WindImpl(centerOfCourse, timepoint, windSpeedWithBearing); + Position endOfLeg = new DegreePosition(54.434648, 10.193312); + Position startOfLeg = new DegreePosition(54.430454, 10.193226); + + DynamicTrackedRaceImpl trackedRace = mock(DynamicTrackedRaceImpl.class); + when(trackedRace.getCenterOfCourse(timepoint)).thenReturn(centerOfCourse); + WindSource source = mock(WindSource.class); + Set sources = Collections.singleton(source); + when(trackedRace.getWindSources(WindSourceType.TRACK_BASED_ESTIMATION)).thenReturn(sources); + when(trackedRace.getWind(any(Position.class), eq(timepoint), eq(sources))).thenReturn(wind); + + RaceDefinition race = mock(RaceDefinition.class); + when(race.getBoatClass()).thenReturn(mockedBoatClass); + + when(trackedRace.getRace()).thenReturn(race); + + Leg leg = mock(Leg.class); + Waypoint from = mock(Waypoint.class); + Waypoint to = mock(Waypoint.class); + when(leg.getFrom()).thenReturn(from); + when(leg.getTo()).thenReturn(to); + + when(trackedRace.getApproximatePosition(from, timepoint)).thenReturn(startOfLeg); + when(trackedRace.getApproximatePosition(to, timepoint)).thenReturn(endOfLeg); + + + SpeedWithBearing speedWithBearingPort = new KnotSpeedWithBearingImpl(6, new DegreeBearingImpl(-45)); + SpeedWithBearingWithConfidence boatSpeedWithBearingWithConfidencePort = new SpeedWithBearingWithConfidenceImpl(speedWithBearingPort, 1, null); + when(mockedPolars.getAverageSpeedWithBearing(mockedBoatClass, wind, LegType.UPWIND, Tack.PORT)).thenReturn(boatSpeedWithBearingWithConfidencePort); + + SpeedWithBearing speedWithBearingStarboard = new KnotSpeedWithBearingImpl(6, new DegreeBearingImpl(45)); + SpeedWithBearingWithConfidence boatSpeedWithBearingWithConfidenceStarboard = new SpeedWithBearingWithConfidenceImpl(speedWithBearingStarboard, 1, null); + when(mockedPolars.getAverageSpeedWithBearing(mockedBoatClass, wind, LegType.UPWIND, Tack.STARBOARD)).thenReturn(boatSpeedWithBearingWithConfidenceStarboard); + + HashSet competitors = new HashSet(); + TrackedLeg trackedLeg = new TrackedLegImpl(trackedRace, leg, competitors); + + //Actual test of functionality + Duration duration = trackedLeg.getEstimatedTimeToComplete(mockedPolars, timepoint); + assertEquals(213513, duration.asMillis(), 100); + + } + + @Test + public void simpleDownwindTargetTimeEstimation() throws NotEnoughDataHasBeenAddedException, NoWindException { + // Setup mock objects + PolarDataService mockedPolars = mock(PolarDataService.class); + BoatClass mockedBoatClass = mock(BoatClass.class); + Position centerOfCourse = new DegreePosition(54.432800, 10.193655); + TimePoint timepoint = new MillisecondsTimePoint(1431426491696l); + Bearing windBearing = new DegreeBearingImpl(5); + SpeedWithBearing windSpeedWithBearing = new KnotSpeedWithBearingImpl(10, windBearing); + Wind wind = new WindImpl(centerOfCourse, timepoint, windSpeedWithBearing); + Position endOfLeg = new DegreePosition(54.434648, 10.193312); + Position startOfLeg = new DegreePosition(54.430454, 10.193226); + + DynamicTrackedRaceImpl trackedRace = mock(DynamicTrackedRaceImpl.class); + when(trackedRace.getCenterOfCourse(timepoint)).thenReturn(centerOfCourse); + WindSource source = mock(WindSource.class); + Set sources = Collections.singleton(source); + when(trackedRace.getWindSources(WindSourceType.TRACK_BASED_ESTIMATION)).thenReturn(sources); + when(trackedRace.getWind(any(Position.class), eq(timepoint), eq(sources))).thenReturn(wind); + + RaceDefinition race = mock(RaceDefinition.class); + when(race.getBoatClass()).thenReturn(mockedBoatClass); + + when(trackedRace.getRace()).thenReturn(race); + + Leg leg = mock(Leg.class); + Waypoint from = mock(Waypoint.class); + Waypoint to = mock(Waypoint.class); + when(leg.getFrom()).thenReturn(from); + when(leg.getTo()).thenReturn(to); + + when(trackedRace.getApproximatePosition(from, timepoint)).thenReturn(startOfLeg); + when(trackedRace.getApproximatePosition(to, timepoint)).thenReturn(endOfLeg); + + + SpeedWithBearing speedWithBearingPort = new KnotSpeedWithBearingImpl(11, new DegreeBearingImpl(150)); + SpeedWithBearingWithConfidence boatSpeedWithBearingWithConfidencePort = new SpeedWithBearingWithConfidenceImpl(speedWithBearingPort, 1, null); + when(mockedPolars.getAverageSpeedWithBearing(mockedBoatClass, wind, LegType.DOWNWIND, Tack.PORT)).thenReturn(boatSpeedWithBearingWithConfidencePort); + + SpeedWithBearing speedWithBearingStarboard = new KnotSpeedWithBearingImpl(11, new DegreeBearingImpl(-150)); + SpeedWithBearingWithConfidence boatSpeedWithBearingWithConfidenceStarboard = new SpeedWithBearingWithConfidenceImpl(speedWithBearingStarboard, 1, null); + when(mockedPolars.getAverageSpeedWithBearing(mockedBoatClass, wind, LegType.DOWNWIND, Tack.STARBOARD)).thenReturn(boatSpeedWithBearingWithConfidenceStarboard); + + HashSet competitors = new HashSet(); + TrackedLeg trackedLeg = new TrackedLegImpl(trackedRace, leg, competitors); + + //Actual test of functionality + Duration duration = trackedLeg.getEstimatedTimeToComplete(mockedPolars, timepoint); + assertEquals(95090, duration.asMillis(), 100); + + } + +} diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/WindEstimationOnConstructedTracksTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/WindEstimationOnConstructedTracksTest.java index 1537167d054..bec8592bcdb 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/WindEstimationOnConstructedTracksTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/WindEstimationOnConstructedTracksTest.java @@ -149,7 +149,9 @@ public class WindEstimationOnConstructedTracksTest extends StoredTrackBasedTest Wind combinedWindDirection = combinedTrack.getAveragedWind(/* position */ null, now); // The course layout makes a wind estimation around 7deg. The confidence of the cluster based wind estimation is a lot // higher that that of the course layout wind (currently at approximately 10E-13), we will end up quite near 180 deg. - assertEquals(180.0, combinedWindDirection.getBearing().getDegrees(), 0.2); + // Update 04/24/15: Since polar data service is not available here, the confidence will not be as good as it once was. + // So we have quite a big delta in the assert + assertEquals(180.0, combinedWindDirection.getBearing().getDegrees(), 0.9); } /** diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java index 327cca309aa..aa2a2d12451 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java @@ -40,6 +40,8 @@ import com.sap.sailing.domain.common.racelog.Flags; import com.sap.sailing.domain.common.tracking.GPSFix; import com.sap.sailing.domain.common.tracking.GPSFixMoving; import com.sap.sailing.domain.leaderboard.ScoringScheme; +import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException; +import com.sap.sailing.domain.polars.PolarDataService; import com.sap.sailing.domain.racelog.tracking.GPSFixStore; import com.sap.sailing.domain.regattalike.RegattaLikeIdentifier; import com.sap.sailing.domain.regattalike.RegattaLikeListener; @@ -66,6 +68,7 @@ import com.sap.sailing.domain.tracking.WindStore; import com.sap.sailing.domain.tracking.WindTrack; import com.sap.sailing.domain.tracking.WindWithConfidence; import com.sap.sailing.domain.tracking.impl.WindTrackImpl; +import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; @@ -904,4 +907,15 @@ public class MockedTrackedRace implements DynamicTrackedRace { // TODO Auto-generated method stub return 0; } + + @Override + public void setPolarDataService(PolarDataService polarDataService) { + } + + @Override + public Duration getEstimatedTimeToComplete(TimePoint timepoint) throws NotEnoughDataHasBeenAddedException, + NoWindException { + // TODO Auto-generated method stub + return null; + } } diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java index 31edf4eac3b..05e4ff232bf 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java @@ -31,6 +31,8 @@ import com.sap.sailing.domain.common.WindSource; import com.sap.sailing.domain.common.WindSourceType; import com.sap.sailing.domain.common.tracking.GPSFix; import com.sap.sailing.domain.common.tracking.GPSFixMoving; +import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException; +import com.sap.sailing.domain.polars.PolarDataService; import com.sap.sailing.domain.racelog.tracking.GPSFixStore; import com.sap.sailing.domain.tracking.CourseDesignChangedListener; import com.sap.sailing.domain.tracking.GPSFixTrack; @@ -51,6 +53,7 @@ import com.sap.sailing.domain.tracking.WindStore; import com.sap.sailing.domain.tracking.WindTrack; import com.sap.sailing.domain.tracking.WindWithConfidence; import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl; +import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; @@ -591,12 +594,12 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace { public GPSFixTrack getTrack(Mark mark) { return null; } - + @Override public long getGateStartGolfDownTime() { return 0; } - + @Override public boolean isUsingMarkPassingCalculator() { // TODO Auto-generated method stub @@ -608,5 +611,16 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace { // TODO Auto-generated method stub return 0; } - + + @Override + public void setPolarDataService(PolarDataService polarDataService) { + } + + @Override + public Duration getEstimatedTimeToComplete(TimePoint timepoint) throws NotEnoughDataHasBeenAddedException, + NoWindException { + // TODO Auto-generated method stub + return null; + } + } diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java index cc0ed888875..556272dc7c9 100755 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java +++ b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java @@ -159,7 +159,7 @@ public class DomainFactoryImpl implements DomainFactory { @Override public void updateCourseWaypoints(Course courseToUpdate, Iterable> controlPoints) throws PatchFailedException { - List> newDomainControlPoints = new ArrayList>(); + List> newDomainControlPoints = new ArrayList<>(); for (com.sap.sse.common.Util.Pair tractracControlPoint : controlPoints) { com.sap.sailing.domain.base.ControlPoint newDomainControlPoint = getOrCreateControlPoint(tractracControlPoint.getA()); newDomainControlPoints.add(new com.sap.sse.common.Util.Pair(newDomainControlPoint, tractracControlPoint.getB())); diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/RaceCourseReceiver.java b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/RaceCourseReceiver.java index 114ce6d2508..a474744717d 100755 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/RaceCourseReceiver.java +++ b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/RaceCourseReceiver.java @@ -24,6 +24,7 @@ import com.sap.sailing.domain.tracking.WindStore; import com.sap.sailing.domain.tractracadapter.DomainFactory; import com.sap.sailing.domain.tractracadapter.TracTracControlPoint; import com.sap.sse.common.TimePoint; +import com.sap.sse.common.Util.Pair; import com.sap.sse.common.Util.Triple; import com.sap.sse.common.impl.MillisecondsTimePoint; import com.tractrac.model.lib.api.event.IEvent; @@ -113,11 +114,11 @@ public class RaceCourseReceiver extends AbstractReceiverWithQueue courseWaypointPassingInstructions = getDomainFactory().getMetadataParser().parsePassingInstructionData(routeMetadataString, routeControlPoints); - List> ttControlPoints = new ArrayList<>(); + final List> ttControlPoints = new ArrayList<>(); int i = 0; for (IControl cp : event.getA().getControls()) { - PassingInstruction passingInstructions = courseWaypointPassingInstructions.containsKey(i) ? courseWaypointPassingInstructions.get(i) : null; - ttControlPoints.add(new com.sap.sse.common.Util.Pair(ttControlPointsForAllOriginalEventControlPoints.get(cp), passingInstructions)); + PassingInstruction passingInstructions = courseWaypointPassingInstructions.containsKey(i) ? courseWaypointPassingInstructions.get(i) : PassingInstruction.None; + ttControlPoints.add(new Pair(ttControlPointsForAllOriginalEventControlPoints.get(cp), passingInstructions)); i++; } diff --git a/java/com.sap.sailing.domain/META-INF/MANIFEST.MF b/java/com.sap.sailing.domain/META-INF/MANIFEST.MF index abcdb4207e4..a3c31e2a903 100755 --- a/java/com.sap.sailing.domain/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.domain/META-INF/MANIFEST.MF @@ -17,6 +17,7 @@ Export-Package: com.sap.sailing.domain.base, com.sap.sailing.domain.markpassingcalculation.impl, com.sap.sailing.domain.markpassingcalculation.splining, com.sap.sailing.domain.masterdataimport, + com.sap.sailing.domain.polars, com.sap.sailing.domain.racelog, com.sap.sailing.domain.racelog.impl, com.sap.sailing.domain.racelog.tracking, @@ -38,4 +39,5 @@ Require-Bundle: com.googlecode.java-diff-utils;bundle-version="1.3.0", com.sap.sse.datamining.shared, com.sap.sse.common, com.sap.sse, - com.sap.sse.shared.android + com.sap.sse.shared.android, + org.apache.commons.math diff --git a/java/com.sap.sailing.domain/build.gradle b/java/com.sap.sailing.domain/build.gradle new file mode 100644 index 00000000000..1471791ff1d --- /dev/null +++ b/java/com.sap.sailing.domain/build.gradle @@ -0,0 +1,16 @@ +apply plugin: "java" + +sourceSets { + main { + java.srcDirs = ["src"] + } +} + +dependencies { + /* local dependencies */ + compile project(":java:com.googlecode.java-diff-utils") + compile project(":java:com.sap.sailing.domain.common") + compile project(":java:com.sap.sailing.domain.shared.android") + compile project(":java:com.sap.sailing.geocoding") + compile project(":java:com.sap.sse.replication") +} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/CourseImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/CourseImpl.java index 7310de66791..636172c525b 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/CourseImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/CourseImpl.java @@ -23,7 +23,7 @@ import com.sap.sailing.domain.base.Leg; import com.sap.sailing.domain.base.Waypoint; import com.sap.sailing.domain.common.PassingInstruction; import com.sap.sailing.util.CourseAsWaypointList; -import com.sap.sse.common.Util; +import com.sap.sse.common.Util.Pair; import com.sap.sse.common.impl.NamedImpl; import com.sap.sse.concurrent.LockUtil; import com.sap.sse.concurrent.NamedReentrantReadWriteLock; @@ -330,33 +330,33 @@ public class CourseImpl extends NamedImpl implements Course { } @Override - public void update(Iterable> newControlPoints, DomainFactory baseDomainFactory) throws PatchFailedException { + public void update(Iterable> newControlPoints, DomainFactory baseDomainFactory) throws PatchFailedException { Patch patch = null; synchronized (updateMonitor) { lockForRead(); try { Iterable courseWaypoints = getWaypoints(); List newWaypointList = new LinkedList(); - // key existing waypoints by control points and re-use each one at most once during construction of the + // key existing waypoints by (ControlPoint, PassingInstruction) pairs and re-use them during construction of the // new waypoint list; since several waypoints can have the same control point, the map goes from - // control point to List. The waypoints in the lists are held in the order of their + // Pair to List. The waypoints in the lists are held in the order of their // occurrence in courseToUpdate.getWaypoints(). - Map> existingWaypointsByControlPoint = new HashMap>(); + final Map, List> existingWaypointsByControlPoint = new HashMap<>(); for (Waypoint waypoint : courseWaypoints) { - List wpl = existingWaypointsByControlPoint.get(waypoint.getControlPoint()); + final Pair key = new Pair<>(waypoint.getControlPoint(), waypoint.getPassingInstructions()); + List wpl = existingWaypointsByControlPoint.get(key); if (wpl == null) { wpl = new ArrayList(); - existingWaypointsByControlPoint.put(waypoint.getControlPoint(), wpl); + existingWaypointsByControlPoint.put(key, wpl); } wpl.add(waypoint); } - for (Util.Pair newDomainControlPoint : newControlPoints) { - List waypoints = existingWaypointsByControlPoint.get(newDomainControlPoint.getA()); + for (Pair newDomainControlPoint : newControlPoints) { + List waypoints = existingWaypointsByControlPoint.get(new Pair<>(newDomainControlPoint.getA(), newDomainControlPoint.getB())); Waypoint waypoint; if (waypoints == null || waypoints.isEmpty()) { // must be a new control point for which we don't have a waypoint yet - waypoint = baseDomainFactory.createWaypoint(newDomainControlPoint.getA(), - newDomainControlPoint.getB()); + waypoint = baseDomainFactory.createWaypoint(newDomainControlPoint.getA(), newDomainControlPoint.getB()); } else { waypoint = waypoints.remove(0); // take the first from the list } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RegattaImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RegattaImpl.java index 5170bb3b1b5..45e5348b2d3 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RegattaImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RegattaImpl.java @@ -573,7 +573,7 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene for (Event event : eventFetcher.getAllEvents()) { event.removeRegatta(this); for (CourseArea courseArea : event.getVenue().getCourseAreas()) { - if (defaultCourseArea != null && courseArea.getId().equals(defaultCourseArea)) { + if (defaultCourseArea != null && courseArea.getId().equals(defaultCourseArea.getId())) { event.addRegatta(this); } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/LeaderboardCacheManager.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/LeaderboardCacheManager.java index 6dfe6c5521a..38ad728922b 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/LeaderboardCacheManager.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/LeaderboardCacheManager.java @@ -1,5 +1,6 @@ package com.sap.sailing.domain.leaderboard; +import java.net.URI; import java.util.Collections; import java.util.HashSet; import java.util.Map; @@ -22,6 +23,7 @@ import com.sap.sailing.domain.tracking.RaceChangeListener; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener; import com.sap.sse.common.Color; +import com.sap.sse.common.TimePoint; import com.sap.sse.concurrent.ConcurrentWeakHashMap; import com.sap.sse.concurrent.LockUtil; import com.sap.sse.concurrent.NamedReentrantReadWriteLock; @@ -121,7 +123,11 @@ public class LeaderboardCacheManager { public void emailChanged(String oldEmail, String newEmail) { //ignore (email not shown in leaderboard) } - + + @Override + public void flagImageChanged(URI oldFlagImageURL, URI newFlagImageURL) { + removeFromCache(leaderboard); + } } private class CacheInvalidationUponScoreCorrectionListener implements ScoreCorrectionListener { @@ -151,6 +157,17 @@ public class LeaderboardCacheManager { public void isSuppressedChanged(Competitor competitor, boolean newIsSuppressed) { removeFromCache(leaderboard); } + + @Override + public void timePointOfLastCorrectionsValidityChanged(TimePoint oldTimePointOfLastCorrectionsValidity, + TimePoint newTimePointOfLastCorrectionsValidity) { + removeFromCache(leaderboard); + } + + @Override + public void commentChanged(String oldComment, String newComment) { + removeFromCache(leaderboard); + } } private final LeaderboardCache leaderboardCache; diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoreCorrectionListener.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoreCorrectionListener.java index 698d1c7b934..0cdf41e2f3f 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoreCorrectionListener.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/ScoreCorrectionListener.java @@ -3,6 +3,7 @@ package com.sap.sailing.domain.leaderboard; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.RaceColumn; import com.sap.sailing.domain.common.MaxPointsReason; +import com.sap.sse.common.TimePoint; public interface ScoreCorrectionListener { void correctedScoreChanced(Competitor competitor, RaceColumn raceColumn, Double oldCorrectedScore, Double newCorrectedScore); @@ -12,4 +13,8 @@ public interface ScoreCorrectionListener { void carriedPointsChanged(Competitor competitor, Double oldCarriedPoints, Double newCarriedPoints); void isSuppressedChanged(Competitor competitor, boolean newIsSuppressed); + + void timePointOfLastCorrectionsValidityChanged(TimePoint oldTimePointOfLastCorrectionsValidity, TimePoint newTimePointOfLastCorrectionsValidity); + + void commentChanged(String oldComment, String newComment); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/SettableScoreCorrection.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/SettableScoreCorrection.java index b41b658e73d..7d5cad8055b 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/SettableScoreCorrection.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/SettableScoreCorrection.java @@ -40,5 +40,8 @@ public interface SettableScoreCorrection extends ScoreCorrection { void notifyListenersAboutCarriedPointsChange(Competitor competitor, Double oldCarriedPoints, Double newCarriedPoints); void notifyListenersAboutIsSuppressedChange(Competitor competitor, boolean suppressed); + + void notifyListenersAboutLastCorrectionsValidityChanged(TimePoint oldTimePointOfLastCorrectionsValidity, TimePoint newTimePointOfLastCorrectionsValidity); + void notifyListenersAboutCommentChanged(String oldComment, String newComment); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java index df71d9f4a28..a2c387c7b45 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java @@ -377,7 +377,9 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race @Override public void setCarriedPoints(Competitor competitor, double carriedPoints) { Double oldCarriedPoints = this.carriedPoints.put(competitor, carriedPoints); - getScoreCorrection().notifyListenersAboutCarriedPointsChange(competitor, oldCarriedPoints, carriedPoints); + if (!Util.equalsWithNull(oldCarriedPoints, carriedPoints)) { + getScoreCorrection().notifyListenersAboutCarriedPointsChange(competitor, oldCarriedPoints, carriedPoints); + } } @Override @@ -394,7 +396,9 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race @Override public void unsetCarriedPoints(Competitor competitor) { Double oldCarriedPoints = carriedPoints.remove(competitor); - getScoreCorrection().notifyListenersAboutCarriedPointsChange(competitor, oldCarriedPoints, null); + if (oldCarriedPoints != null) { + getScoreCorrection().notifyListenersAboutCarriedPointsChange(competitor, oldCarriedPoints, null); + } } @Override @@ -411,7 +415,9 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race public void setDisplayName(Competitor competitor, String displayName) { String oldDisplayName = displayNames.get(competitor); displayNames.put(competitor, displayName); - getRaceColumnListeners().notifyListenersAboutCompetitorDisplayNameChanged(competitor, oldDisplayName, displayName); + if (!Util.equalsWithNull(oldDisplayName, displayName)) { + getRaceColumnListeners().notifyListenersAboutCompetitorDisplayNameChanged(competitor, oldDisplayName, displayName); + } } @Override diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java index 725ddd97fcb..0ca5b8372ca 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java @@ -124,6 +124,21 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection { } } + @Override + public void notifyListenersAboutLastCorrectionsValidityChanged(TimePoint oldTimePointOfLastCorrectionsValidity, + TimePoint newTimePointOfLastCorrectionsValidity) { + for (ScoreCorrectionListener listener : getScoreCorrectionListeners()) { + listener.timePointOfLastCorrectionsValidityChanged(oldTimePointOfLastCorrectionsValidity, newTimePointOfLastCorrectionsValidity); + } + } + + @Override + public void notifyListenersAboutCommentChanged(String oldComment, String newComment) { + for (ScoreCorrectionListener listener : getScoreCorrectionListeners()) { + listener.commentChanged(oldComment, newComment); + } + } + @Override public void setMaxPointsReason(Competitor competitor, RaceColumn raceColumn, MaxPointsReason reason) { com.sap.sse.common.Util.Pair key = raceColumn.getKey(competitor); @@ -483,12 +498,20 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection { @Override public void setTimePointOfLastCorrectionsValidity(TimePoint timePointOfLastCorrectionsValidity) { + final TimePoint oldTimePointOfLastCorrectionsValidity = this.timePointOfLastCorrectionsValidity; this.timePointOfLastCorrectionsValidity = timePointOfLastCorrectionsValidity; + if (!Util.equalsWithNull(oldTimePointOfLastCorrectionsValidity, timePointOfLastCorrectionsValidity)) { + notifyListenersAboutLastCorrectionsValidityChanged(oldTimePointOfLastCorrectionsValidity, timePointOfLastCorrectionsValidity); + } } @Override public void setComment(String scoreCorrectionComment) { + final String oldComment = this.comment; this.comment = scoreCorrectionComment; + if (!Util.equalsWithNull(oldComment, scoreCorrectionComment)) { + notifyListenersAboutCommentChanged(oldComment, scoreCorrectionComment); + } } protected Leaderboard getLeaderboard() { diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/AbstractMetaLeaderboard.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/AbstractMetaLeaderboard.java index ed2b4aa9c40..d7618dd1cb1 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/AbstractMetaLeaderboard.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/AbstractMetaLeaderboard.java @@ -87,6 +87,17 @@ public abstract class AbstractMetaLeaderboard extends AbstractSimpleLeaderboardI public void isSuppressedChanged(Competitor competitor, boolean newIsSuppressed) { getScoreCorrection().notifyListenersAboutIsSuppressedChange(competitor, newIsSuppressed); } + + @Override + public void timePointOfLastCorrectionsValidityChanged(TimePoint oldTimePointOfLastCorrectionsValidity, + TimePoint newTimePointOfLastCorrectionsValidity) { + getScoreCorrection().notifyListenersAboutLastCorrectionsValidityChanged(oldTimePointOfLastCorrectionsValidity, newTimePointOfLastCorrectionsValidity); + } + + @Override + public void commentChanged(String oldComment, String newComment) { + getScoreCorrection().notifyListenersAboutCommentChanged(oldComment, newComment); + } } public AbstractMetaLeaderboard(String name, ScoringScheme scoringScheme, diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassingcalculation/impl/CandidateFinderImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassingcalculation/impl/CandidateFinderImpl.java index 3d161ae60fd..2f6c58aabd2 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassingcalculation/impl/CandidateFinderImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassingcalculation/impl/CandidateFinderImpl.java @@ -479,7 +479,7 @@ public class CandidateFinderImpl implements CandidateFinder { } } List wayPointXTEs = xtes.get(w); - int size = wayPointXTEs.size(); + int size = wayPointXTEs == null ? 0 : wayPointXTEs.size(); if (size > 0) { Double xte = wayPointXTEs.get(0).getMeters(); if (xte == 0) { @@ -710,11 +710,7 @@ public class CandidateFinderImpl implements CandidateFinder { boolean singleMark = false; switch (instruction) { case Port: - singleMark = true; - break; case Starboard: - singleMark = true; - break; case FixedBearing: singleMark = true; break; diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/masterdataimport/TopLevelMasterData.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/masterdataimport/TopLevelMasterData.java index 753278e985f..768b39cc6f3 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/masterdataimport/TopLevelMasterData.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/masterdataimport/TopLevelMasterData.java @@ -8,19 +8,41 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.UUID; +import java.util.logging.Logger; +import com.sap.sailing.domain.abstractlog.AbstractLogEvent; +import com.sap.sailing.domain.abstractlog.race.RaceLog; +import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; +import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDeviceMarkMappingEvent; +import com.sap.sailing.domain.abstractlog.regatta.RegattaLog; +import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent; +import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent; +import com.sap.sailing.domain.abstractlog.shared.events.DeviceMappingEvent; import com.sap.sailing.domain.base.CourseArea; import com.sap.sailing.domain.base.Event; import com.sap.sailing.domain.base.Fleet; import com.sap.sailing.domain.base.RaceColumn; import com.sap.sailing.domain.base.Regatta; +import com.sap.sailing.domain.common.RaceIdentifier; +import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; import com.sap.sailing.domain.common.RegattaIdentifier; import com.sap.sailing.domain.common.WindSource; import com.sap.sailing.domain.common.media.MediaTrack; +import com.sap.sailing.domain.common.racelog.tracking.TransformationException; +import com.sap.sailing.domain.common.tracking.GPSFix; import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.leaderboard.LeaderboardGroup; import com.sap.sailing.domain.leaderboard.RegattaLeaderboard; +import com.sap.sailing.domain.racelog.tracking.GPSFixStore; +import com.sap.sailing.domain.racelogtracking.DeviceIdentifier; +import com.sap.sailing.domain.racelogtracking.impl.DeviceMappingImpl; +import com.sap.sailing.domain.tracking.DynamicGPSFixTrack; import com.sap.sailing.domain.tracking.TrackedRace; +import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl; +import com.sap.sailing.domain.tracking.impl.DynamicGPSFixTrackImpl; +import com.sap.sse.common.NoCorrespondingServiceRegisteredException; +import com.sap.sse.common.WithID; +import com.sap.sse.common.impl.TimeRangeImpl; /** * Holds all information needed for a master data import. @@ -29,27 +51,113 @@ import com.sap.sailing.domain.tracking.TrackedRace; * */ public class TopLevelMasterData implements Serializable { + + private static final Logger logger = Logger.getLogger(TopLevelMasterData.class.getName()); private static final long serialVersionUID = 4820893865792553281L; private final Map> raceIdStringsForRegatta; - private final Set allMediaTracks; + private final Set filteredMediaTracks; private final Set leaderboardGroups; private final Set windTrackMasterData; private final Map> eventForLeaderboardGroup; + private final Map> raceLogTrackingFixes; public TopLevelMasterData(final Set groupsToExport, final Iterable allEvents, final Map regattaForRaceIdString, final Collection allMediaTracks, - boolean exportWind) { + GPSFixStore gpsFixStore, boolean exportWind) { this.raceIdStringsForRegatta = convertToRaceIdStringsForRegattaMap(regattaForRaceIdString); - this.allMediaTracks = new HashSet(); - this.allMediaTracks.addAll(allMediaTracks); this.leaderboardGroups = groupsToExport; + this.raceLogTrackingFixes = getAllRelevantRaceLogTrackingFixes(gpsFixStore); if (exportWind) { this.windTrackMasterData = fillWindMap(groupsToExport); } else { this.windTrackMasterData = new HashSet(); } this.eventForLeaderboardGroup = createEventMap(groupsToExport, allEvents); + this.filteredMediaTracks = new HashSet(); + filterMediaTracks(allMediaTracks, this.filteredMediaTracks); + } + + private Map> getAllRelevantRaceLogTrackingFixes(GPSFixStore gpsFixStore) { + Map> relevantFixes = new HashMap<>(); + + //Add fixes for regatta log mappings + for (Regatta regatta : getAllRegattas()) { + RegattaLog regattaLog = regatta.getRegattaLog(); + try { + regattaLog.lockForRead(); + for (RegattaLogEvent logEvent : regattaLog.getRawFixes()) { + addAllFixesIfMappingEvent(gpsFixStore, relevantFixes, logEvent); + } + } finally { + regattaLog.unlockAfterRead(); + } + } + //Add fixes for race log mapping + for (LeaderboardGroup group : leaderboardGroups) { + for (Leaderboard leaderboard : group.getLeaderboards()) { + for (RaceColumn raceColumn : leaderboard.getRaceColumns()) { + for (Fleet fleet : raceColumn.getFleets()) { + RaceLog raceLog = raceColumn.getRaceLog(fleet); + try { + raceLog.lockForRead(); + for (RaceLogEvent logEvent : raceLog.getRawFixes()) { + addAllFixesIfMappingEvent(gpsFixStore, relevantFixes, logEvent); + } + } finally { + raceLog.unlockAfterRead(); + } + } + } + } + } + return relevantFixes; + } + + private void addAllFixesIfMappingEvent(GPSFixStore gpsFixStore, Map> relevantFixes, + AbstractLogEvent logEvent) { + if (logEvent instanceof DeviceMappingEvent) { + DeviceMappingEvent mappingEvent = (DeviceMappingEvent) logEvent; + try { + addAllFixesForMappingEvent(gpsFixStore, relevantFixes, mappingEvent); + } catch (NoCorrespondingServiceRegisteredException | TransformationException e) { + logger.severe("Failed to add fixes to exportdata for mapping Event"); + e.printStackTrace(); + } + } + } + + private void addAllFixesForMappingEvent(GPSFixStore gpsFixStore, Map> relevantFixes, + DeviceMappingEvent mappingEvent) throws NoCorrespondingServiceRegisteredException, TransformationException { + DynamicGPSFixTrack track; + if (isMarkMappingEvent(mappingEvent)) { + track = new DynamicGPSFixTrackImpl(mappingEvent.getMappedTo(), 10000); + } else { + track = new DynamicGPSFixMovingTrackImpl(mappingEvent.getMappedTo(), 1000); + } + DeviceIdentifier device = mappingEvent.getDevice(); + gpsFixStore.loadTrack(track, new DeviceMappingImpl(mappingEvent.getMappedTo(), device, + new TimeRangeImpl(mappingEvent.getFrom(), mappingEvent.getTo()))); + if (!relevantFixes.containsKey(device)) { + relevantFixes.put(device, new HashSet<>()); + } + Set fixes = relevantFixes.get(device); + try { + track.lockForRead(); + for (GPSFix fix : track.getRawFixes()) { + fixes.add(fix); + } + } finally { + track.unlockAfterRead(); + } + } + + private boolean isMarkMappingEvent(DeviceMappingEvent mappingEvent) { + boolean isMarkMappingEvent = false; + if (mappingEvent instanceof RaceLogDeviceMarkMappingEvent || mappingEvent instanceof RegattaLogDeviceMarkMappingEvent) { + isMarkMappingEvent = true; + } + return isMarkMappingEvent; } /** @@ -134,8 +242,8 @@ public class TopLevelMasterData implements Serializable { } } - public Collection getAllMediaTracks() { - return allMediaTracks; + public Collection getFilteredMediaTracks() { + return this.filteredMediaTracks; } public Collection getLeaderboardGroups() { @@ -186,4 +294,45 @@ public class TopLevelMasterData implements Serializable { } return regattas; } + + /** + * Copies only those media tracks from allMediaTracks to filteredMediaTracks which are + * assigned to races related to the exported LeaderboardGroup. + */ + private void filterMediaTracks(Collection allMediaTracks, Set filteredMediaTracks) { + Set raceIdentitifiersForMediaExport = collectRaceIdentifiersForMediaExport(); + for (MediaTrack mediaTrack : allMediaTracks) { + for (RegattaAndRaceIdentifier raceIdentifier : mediaTrack.assignedRaces) { + if (raceIdentitifiersForMediaExport.contains(raceIdentifier)) { + filteredMediaTracks.add(mediaTrack); + continue; + } + } + } + } + + /** + * Returns the set of races (in form of raceIdentifiers) related to the exported LeaderboardGroup. + * + */ + private Set collectRaceIdentifiersForMediaExport() { + Set raceIdentifiers = new HashSet<>(); + for (LeaderboardGroup leaderboardGroup : leaderboardGroups) { + for (Leaderboard leaderboard : leaderboardGroup.getLeaderboards()) { + for (RaceColumn raceColumn : leaderboard.getRaceColumns()) { + for (Fleet fleet : raceColumn.getFleets()) { + RaceIdentifier raceIdentifier = raceColumn.getRaceIdentifier(fleet); + if (raceIdentifier != null) { + raceIdentifiers.add(raceIdentifier); + } + } + } + } + } + return raceIdentifiers; + } + + public Map> getRaceLogTrackingFixes() { + return raceLogTrackingFixes; + } } diff --git a/java/com.sap.sailing.polars/src/com/sap/sailing/polars/NoPolarDataAvailableException.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polars/NoPolarDataAvailableException.java similarity index 96% rename from java/com.sap.sailing.polars/src/com/sap/sailing/polars/NoPolarDataAvailableException.java rename to java/com.sap.sailing.domain/src/com/sap/sailing/domain/polars/NoPolarDataAvailableException.java index dcefa34b9af..f8787e8abe0 100644 --- a/java/com.sap.sailing.polars/src/com/sap/sailing/polars/NoPolarDataAvailableException.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polars/NoPolarDataAvailableException.java @@ -1,4 +1,4 @@ -package com.sap.sailing.polars; +package com.sap.sailing.domain.polars; import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.common.Bearing; diff --git a/java/com.sap.sailing.polars/src/com/sap/sailing/polars/regression/NotEnoughDataHasBeenAddedException.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polars/NotEnoughDataHasBeenAddedException.java similarity index 92% rename from java/com.sap.sailing.polars/src/com/sap/sailing/polars/regression/NotEnoughDataHasBeenAddedException.java rename to java/com.sap.sailing.domain/src/com/sap/sailing/domain/polars/NotEnoughDataHasBeenAddedException.java index 6b8c54683b8..9376fc53d80 100644 --- a/java/com.sap.sailing.polars/src/com/sap/sailing/polars/regression/NotEnoughDataHasBeenAddedException.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polars/NotEnoughDataHasBeenAddedException.java @@ -1,4 +1,4 @@ -package com.sap.sailing.polars.regression; +package com.sap.sailing.domain.polars; public class NotEnoughDataHasBeenAddedException extends Exception { diff --git a/java/com.sap.sailing.polars/src/com/sap/sailing/polars/PolarDataService.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polars/PolarDataService.java old mode 100755 new mode 100644 similarity index 90% rename from java/com.sap.sailing.polars/src/com/sap/sailing/polars/PolarDataService.java rename to java/com.sap.sailing.domain/src/com/sap/sailing/domain/polars/PolarDataService.java index 292b8e3c991..637d96d9b58 --- a/java/com.sap.sailing.polars/src/com/sap/sailing/polars/PolarDataService.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polars/PolarDataService.java @@ -1,4 +1,4 @@ -package com.sap.sailing.polars; +package com.sap.sailing.domain.polars; import java.util.Set; import java.util.concurrent.ExecutionException; @@ -17,10 +17,9 @@ import com.sap.sailing.domain.common.PolarSheetGenerationSettings; import com.sap.sailing.domain.common.PolarSheetsData; import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.Tack; +import com.sap.sailing.domain.common.confidence.BearingWithConfidence; import com.sap.sailing.domain.common.tracking.GPSFixMoving; import com.sap.sailing.domain.tracking.TrackedRace; -import com.sap.sailing.polars.mining.MovingAverageProcessor; -import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException; import com.sap.sse.common.Util.Pair; /** @@ -206,7 +205,30 @@ public interface PolarDataService { */ PolynomialFunction getSpeedRegressionFunction(BoatClass boatClass, double trueWindAngle) throws NotEnoughDataHasBeenAddedException; + /** + * For Upwind and Downwind returns the typical angle needed for a maneuver. + * + * @param boatClass + * @param maneuverType + * needs to be Tack or Jibe + * @param windSpeed + * Since the maneuver angle is windSpeed depended, supply it here + * @return angle with confidence as supplied by polars. Angle is always >= 0 + * @throws NotEnoughDataHasBeenAddedException + */ + BearingWithConfidence getManeuverAngle(BoatClass boatClass, ManeuverType maneuverType, Speed windSpeed) + throws NotEnoughDataHasBeenAddedException; + void raceFinishedLoading(TrackedRace race); + /** + * See {@link #getAverageSpeedWithBearing(BoatClass, Speed, LegType, Tack, boolean)} + * Always use regression + */ + SpeedWithBearingWithConfidence getAverageSpeedWithBearing(BoatClass boatClass, Speed windSpeed, + LegType legType, Tack tack) throws NotEnoughDataHasBeenAddedException; + + void insertExistingFixes(TrackedRace trackedRace); + } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/tracking/EmptyGPSFixStore.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/tracking/EmptyGPSFixStore.java index 083235812d7..af04e4c82a5 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/tracking/EmptyGPSFixStore.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/tracking/EmptyGPSFixStore.java @@ -3,12 +3,15 @@ package com.sap.sailing.domain.racelog.tracking; import com.sap.sailing.domain.abstractlog.AbstractLog; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Mark; +import com.sap.sailing.domain.common.racelog.tracking.TransformationException; import com.sap.sailing.domain.common.tracking.GPSFix; import com.sap.sailing.domain.common.tracking.GPSFixMoving; import com.sap.sailing.domain.racelogtracking.DeviceIdentifier; import com.sap.sailing.domain.racelogtracking.DeviceMapping; import com.sap.sailing.domain.tracking.DynamicGPSFixTrack; +import com.sap.sse.common.NoCorrespondingServiceRegisteredException; import com.sap.sse.common.TimeRange; +import com.sap.sse.common.WithID; public enum EmptyGPSFixStore implements GPSFixStore { INSTANCE; @@ -57,4 +60,10 @@ public enum EmptyGPSFixStore implements GPSFixStore { public long getNumberOfFixes(DeviceIdentifier device) { return 0; } + + @Override + public void loadTrack(DynamicGPSFixTrack track, DeviceMapping mapping) + throws NoCorrespondingServiceRegisteredException, TransformationException { + + } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/tracking/GPSFixStore.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/tracking/GPSFixStore.java index d10fda223e2..6db39a883c1 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/tracking/GPSFixStore.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/tracking/GPSFixStore.java @@ -13,6 +13,7 @@ import com.sap.sailing.domain.racelogtracking.DeviceMapping; import com.sap.sailing.domain.tracking.DynamicGPSFixTrack; import com.sap.sse.common.NoCorrespondingServiceRegisteredException; import com.sap.sse.common.TimeRange; +import com.sap.sse.common.WithID; public interface GPSFixStore { @@ -39,6 +40,12 @@ public interface GPSFixStore { */ void loadMarkTrack(DynamicGPSFixTrack track, DeviceMapping mapping) throws TransformationException, NoCorrespondingServiceRegisteredException; + + /** + * Load all fixes for both marks and competitors according to the {@code mapping}. + */ + void loadTrack(DynamicGPSFixTrack track, DeviceMapping mapping) + throws NoCorrespondingServiceRegisteredException, TransformationException; void storeFix(DeviceIdentifier device, GPSFix fix) throws TransformationException, NoCorrespondingServiceRegisteredException; diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/regattalike/BaseRegattaLikeImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/regattalike/BaseRegattaLikeImpl.java index cd89d7797b2..392dc0fb8ae 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/regattalike/BaseRegattaLikeImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/regattalike/BaseRegattaLikeImpl.java @@ -16,7 +16,7 @@ public class BaseRegattaLikeImpl implements IsRegattaLike { private final RegattaLikeIdentifier identifier; private transient Set listeners = new HashSet<>(); - public BaseRegattaLikeImpl(RegattaLikeIdentifier identifier, RegattaLogStore store) { + public BaseRegattaLikeImpl(final RegattaLikeIdentifier identifier, RegattaLogStore store) { regattaLog = store.getRegattaLog(identifier, /*ignoreCache*/ true); this.identifier = identifier; diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedLeg.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedLeg.java index d7d0f35982f..6c5a9c97827 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedLeg.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedLeg.java @@ -10,7 +10,10 @@ import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.LegType; import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.Position; +import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException; +import com.sap.sailing.domain.polars.PolarDataService; import com.sap.sailing.domain.tracking.impl.TrackedLegImpl; +import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; public interface TrackedLeg extends Serializable { @@ -107,4 +110,13 @@ public interface TrackedLeg extends Serializable { */ Position getMiddleOfLeg(TimePoint at); + /** + * @param timepoint Used for positions of marks and wind information + * @return estimated time it takes to complete the leg + * @throws NotEnoughDataHasBeenAddedException thrown if not enough polar data has been added or polar data service + * is not available + * @throws NoWindException no wind available. unable to determine legtypes for given timepoint + */ + Duration getEstimatedTimeToComplete(PolarDataService polarDataService, TimePoint timepoint) throws NotEnoughDataHasBeenAddedException, NoWindException; + } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java index 0b0f7d5f392..ccf7e3f9ddb 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java @@ -37,7 +37,10 @@ import com.sap.sailing.domain.common.racelog.Flags; import com.sap.sailing.domain.common.racelog.RacingProcedureType; import com.sap.sailing.domain.common.tracking.GPSFix; import com.sap.sailing.domain.common.tracking.GPSFixMoving; +import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException; +import com.sap.sailing.domain.polars.PolarDataService; import com.sap.sailing.domain.racelog.tracking.GPSFixStore; +import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; @@ -769,5 +772,16 @@ public interface TrackedRace extends Serializable { Distance getAdditionalGateStartDistance(Competitor competitor, TimePoint timePoint); boolean isUsingMarkPassingCalculator(); + + /** + * @param timepoint Used for positions of marks and wind information + * @return estimated time it takes to complete the race + * @throws NotEnoughDataHasBeenAddedException thrown if not enough polar data has been added or polar data service + * is not available + * @throws NoWindException + */ + Duration getEstimatedTimeToComplete(TimePoint timepoint) throws NotEnoughDataHasBeenAddedException, NoWindException; + + void setPolarDataService(PolarDataService polarDataService); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java index 038478a20ae..f4dad5056a7 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java @@ -478,6 +478,7 @@ DynamicTrackedRace, GPSTrackListener { // clearMarkPassings(...) as well as inside the subsequent for-loop. It is important to always first obtain the mark passings lock // for the competitor mark passings before obtaining the lock for the mark passings in order for the waypoint to avoid // deadlocks. + getRace().getCourse().lockForRead(); LockUtil.lockForWrite(markPassingsLock); try { clearMarkPassings(competitor); @@ -529,6 +530,7 @@ DynamicTrackedRace, GPSTrackListener { } } finally { LockUtil.unlockAfterWrite(markPassingsLock); + getRace().getCourse().unlockAfterRead(); } updated(timePointOfLatestEvent); triggerManeuverCacheRecalculation(competitor); @@ -660,7 +662,8 @@ DynamicTrackedRace, GPSTrackListener { if ((startOfTracking == null || !startOfTracking.minus(TrackedRaceImpl.TIME_BEFORE_START_TO_TRACK_WIND_MILLIS).after(wind.getTimePoint()) || (startOfRace != null && !startOfRace.minus(TrackedRaceImpl.TIME_BEFORE_START_TO_TRACK_WIND_MILLIS).after(wind.getTimePoint()))) && - (endOfTracking == null || endOfTracking.plus(TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS).after(wind.getTimePoint()) || + // Caution: don't add to endOfTracking; it may be the end of time, leading to a wrap-around / overflow + (endOfTracking == null || endOfTracking.after(wind.getTimePoint().minus(TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS)) || (endOfRace != null && endOfRace.plus(TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS).after(wind.getTimePoint())))) { result = getOrCreateWindTrack(windSource).add(wind); updated(/* time point */null); // wind events shouldn't advance race time diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegImpl.java index 029a0677d0e..258dccc8faa 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegImpl.java @@ -13,23 +13,31 @@ import java.util.Set; import java.util.concurrent.Callable; import java.util.logging.Logger; +import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Leg; +import com.sap.sailing.domain.base.SpeedWithBearingWithConfidence; +import com.sap.sailing.domain.base.SpeedWithConfidence; import com.sap.sailing.domain.common.Bearing; import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.LegType; import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.Position; +import com.sap.sailing.domain.common.Speed; +import com.sap.sailing.domain.common.Tack; import com.sap.sailing.domain.common.Wind; import com.sap.sailing.domain.common.WindSource; import com.sap.sailing.domain.common.WindSourceType; import com.sap.sailing.domain.common.impl.MeterDistance; +import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException; +import com.sap.sailing.domain.polars.PolarDataService; import com.sap.sailing.domain.tracking.TrackedLeg; import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.TrackedRaceStatus; import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache; import com.sap.sailing.domain.tracking.WindPositionMode; +import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; @@ -368,4 +376,44 @@ public class TrackedLegImpl implements TrackedLeg { return result; } + @Override + public Duration getEstimatedTimeToComplete(PolarDataService polarDataService, TimePoint timepoint) + throws NotEnoughDataHasBeenAddedException, NoWindException { + Position centralPosition = trackedRace.getCenterOfCourse(timepoint); + Wind wind = trackedRace.getWind(centralPosition, timepoint, getTrackedRace().getWindSources(WindSourceType.TRACK_BASED_ESTIMATION)); + Position from = trackedRace.getApproximatePosition(leg.getFrom(), timepoint); + Position to = trackedRace.getApproximatePosition(leg.getTo(), timepoint); + LegType legType = getLegType(timepoint); + BoatClass boatClass = trackedRace.getRace().getBoatClass(); + Duration result; + if (legType == LegType.REACHING) { + Bearing trueWindAngle = wind.getBearing().getDifferenceTo(from.getBearingGreatCircle(to)); + SpeedWithConfidence reachSpeed = polarDataService.getSpeed(boatClass, wind, trueWindAngle); + Distance distance = from.getDistance(to); + result = reachSpeed.getObject().getDuration(distance); + } else { + SpeedWithBearingWithConfidence portSpeedAndBearing = polarDataService.getAverageSpeedWithBearing( + boatClass, wind, legType, Tack.PORT); + SpeedWithBearingWithConfidence starboardSpeedAndBearing = polarDataService.getAverageSpeedWithBearing( + boatClass, wind, legType, Tack.STARBOARD); + result = estimateTargetTimeTacking(from, to, portSpeedAndBearing, starboardSpeedAndBearing, wind); + } + return result; + } + + private Duration estimateTargetTimeTacking(Position from, Position to, + SpeedWithBearingWithConfidence portSpeedAndBearing, + SpeedWithBearingWithConfidence starboardSpeedAndBearing, Wind wind) { + Bearing portBearing = portSpeedAndBearing.getObject().getBearing(); + Bearing starboardBearing = starboardSpeedAndBearing.getObject().getBearing(); + Position intersection = from.getIntersection(portBearing, to, starboardBearing); + Distance fromToIntersection = from.getDistance(intersection); + Speed portSpeed = portSpeedAndBearing.getObject(); + Duration duration1 = portSpeed.getDuration(fromToIntersection); + Distance fromToTo = intersection.getDistance(to); + Speed starboardSpeed = starboardSpeedAndBearing.getObject(); + Duration duration2 = starboardSpeed.getDuration(fromToTo); + return duration1.plus(duration2); + } + } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java index 8251fab3321..6492f3de69c 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java @@ -101,6 +101,8 @@ import com.sap.sailing.domain.common.tracking.GPSFixMoving; import com.sap.sailing.domain.confidence.ConfidenceBasedWindAverager; import com.sap.sailing.domain.confidence.ConfidenceFactory; import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator; +import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException; +import com.sap.sailing.domain.polars.PolarDataService; import com.sap.sailing.domain.racelog.tracking.GPSFixStore; import com.sap.sailing.domain.racelogtracking.DeviceMapping; import com.sap.sailing.domain.tracking.DynamicGPSFixTrack; @@ -128,6 +130,7 @@ import com.sap.sse.common.TimePoint; import com.sap.sse.common.Timed; import com.sap.sse.common.Util; import com.sap.sse.common.Util.Pair; +import com.sap.sse.common.impl.MillisecondsDurationImpl; import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.concurrent.LockUtil; import com.sap.sse.concurrent.NamedReentrantReadWriteLock; @@ -317,6 +320,8 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl */ private transient ShortTimeWindCache shortTimeWindCache; + private transient PolarDataService polarDataService; + public TrackedRaceImpl(final TrackedRegatta trackedRegatta, RaceDefinition race, final Iterable sidelines, final WindStore windStore, final GPSFixStore gpsFixStore, long delayToLiveInMillis, final long millisecondsOverWhichToAverageWind, @@ -1860,40 +1865,66 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl BearingWithConfidence resultBearing = null; ScalablePosition scaledPosition = null; int numberOfFixesConsideredForScaledPosition = 0; + Set estimationExcluded = new HashSet<>(); + estimationExcluded.addAll(getWindSources(WindSourceType.TRACK_BASED_ESTIMATION)); + estimationExcluded.addAll(getWindSources(WindSourceType.COURSE_BASED)); if (bearings != null) { - BearingWithConfidenceCluster[] bearingClustersUpwind = bearings.get(LegType.UPWIND).getA().splitInTwo( - getMinimumAngleBetweenDifferentTacksUpwind(), timePoint); - if (!bearingClustersUpwind[0].isEmpty() && !bearingClustersUpwind[1].isEmpty()) { - BearingWithConfidence average0 = bearingClustersUpwind[0].getAverage(timePoint); - BearingWithConfidence average1 = bearingClustersUpwind[1].getAverage(timePoint); - upwindNumberOfRelevantBoats = Math - .min(bearingClustersUpwind[0].size(), bearingClustersUpwind[1].size()); - confidence = Math.min(average0.getConfidence(), average1.getConfidence()) - * getRace().getBoatClass().getUpwindWindEstimationConfidence(upwindNumberOfRelevantBoats); - reversedUpwindAverage = new BearingWithConfidenceImpl(average0.getObject() - .middle(average1.getObject()).reverse(), confidence, timePoint); - scaledPosition = bearings.get(LegType.UPWIND).getB(); - numberOfFixesConsideredForScaledPosition += bearings.get(LegType.UPWIND).getA().size(); + int numberOfFixesUpwind = bearings.get(LegType.UPWIND).getA().size(); + if (numberOfFixesUpwind > 0) { + ScalablePosition upwindPosition = bearings.get(LegType.UPWIND).getB(); + Pair minimumAngleBetweenDifferentTacksUpwindWithConfidence = getMinimumAngleBetweenDifferentTacksUpwind(getWind( + upwindPosition.divide(numberOfFixesUpwind), timePoint, estimationExcluded)); + BearingWithConfidenceCluster[] bearingClustersUpwind = bearings + .get(LegType.UPWIND) + .getA() + .splitInTwo( + minimumAngleBetweenDifferentTacksUpwindWithConfidence.getA(), + timePoint); + if (!bearingClustersUpwind[0].isEmpty() && !bearingClustersUpwind[1].isEmpty()) { + BearingWithConfidence average0 = bearingClustersUpwind[0].getAverage(timePoint); + BearingWithConfidence average1 = bearingClustersUpwind[1].getAverage(timePoint); + upwindNumberOfRelevantBoats = Math.min(bearingClustersUpwind[0].size(), + bearingClustersUpwind[1].size()); + confidence = Math.min(average0.getConfidence(), average1.getConfidence()) + * getRace().getBoatClass().getUpwindWindEstimationConfidence(upwindNumberOfRelevantBoats) + * minimumAngleBetweenDifferentTacksUpwindWithConfidence.getB(); + reversedUpwindAverage = new BearingWithConfidenceImpl(average0.getObject() + .middle(average1.getObject()).reverse(), confidence, timePoint); + scaledPosition = upwindPosition; + numberOfFixesConsideredForScaledPosition += bearings.get(LegType.UPWIND).getA().size(); + } } BearingWithConfidenceImpl downwindAverage = null; int downwindNumberOfRelevantBoats = 0; - BearingWithConfidenceCluster[] bearingClustersDownwind = bearings.get(LegType.DOWNWIND).getA() - .splitInTwo(getMinimumAngleBetweenDifferentTacksDownwind(), timePoint); - if (!bearingClustersDownwind[0].isEmpty() && !bearingClustersDownwind[1].isEmpty()) { - BearingWithConfidence average0 = bearingClustersDownwind[0].getAverage(timePoint); - BearingWithConfidence average1 = bearingClustersDownwind[1].getAverage(timePoint); - downwindNumberOfRelevantBoats = Math.min(bearingClustersDownwind[0].size(), - bearingClustersDownwind[1].size()); - confidence = Math.min(average0.getConfidence(), average1.getConfidence()) - * getRace().getBoatClass().getDownwindWindEstimationConfidence(downwindNumberOfRelevantBoats); - downwindAverage = new BearingWithConfidenceImpl(average0.getObject().middle( - average1.getObject()), confidence, timePoint); - if (scaledPosition == null) { - scaledPosition = bearings.get(LegType.DOWNWIND).getB(); - } else { - scaledPosition.add(bearings.get(LegType.DOWNWIND).getB()); + int numberOfFixesDownwind = bearings.get(LegType.DOWNWIND).getA().size(); + if (numberOfFixesDownwind > 0) { + ScalablePosition downwindPosition = bearings.get(LegType.DOWNWIND).getB(); + Pair minimumAngleBetweenDifferentTacksDownwindWithConfidence = getMinimumAngleBetweenDifferentTacksDownwind(getWind( + downwindPosition.divide(numberOfFixesDownwind), timePoint, estimationExcluded)); + BearingWithConfidenceCluster[] bearingClustersDownwind = bearings + .get(LegType.DOWNWIND) + .getA() + .splitInTwo( + minimumAngleBetweenDifferentTacksDownwindWithConfidence.getA(), + timePoint); + if (!bearingClustersDownwind[0].isEmpty() && !bearingClustersDownwind[1].isEmpty()) { + BearingWithConfidence average0 = bearingClustersDownwind[0].getAverage(timePoint); + BearingWithConfidence average1 = bearingClustersDownwind[1].getAverage(timePoint); + downwindNumberOfRelevantBoats = Math.min(bearingClustersDownwind[0].size(), + bearingClustersDownwind[1].size()); + confidence = Math.min(average0.getConfidence(), average1.getConfidence()) + * getRace().getBoatClass().getDownwindWindEstimationConfidence( + downwindNumberOfRelevantBoats) + * minimumAngleBetweenDifferentTacksDownwindWithConfidence.getB(); + downwindAverage = new BearingWithConfidenceImpl(average0.getObject().middle( + average1.getObject()), confidence, timePoint); + if (scaledPosition == null) { + scaledPosition = downwindPosition; + } else { + scaledPosition.add(downwindPosition); + } + numberOfFixesConsideredForScaledPosition += bearings.get(LegType.DOWNWIND).getA().size(); } - numberOfFixesConsideredForScaledPosition += bearings.get(LegType.DOWNWIND).getA().size(); } BearingWithConfidenceCluster resultCluster = new BearingWithConfidenceCluster(weigher); assert upwindNumberOfRelevantBoats == 0 || reversedUpwindAverage != null; @@ -2715,12 +2746,41 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl return getRace().getBoatClass().getManeuverDegreeAngleThreshold(); } - private double getMinimumAngleBetweenDifferentTacksDownwind() { - return getRace().getBoatClass().getMinimumAngleBetweenDifferentTacksDownwind(); + private Pair getMinimumAngleBetweenDifferentTacksDownwind(Wind wind) { + Pair result; + double defaultAngle = getRace().getBoatClass().getMinimumAngleBetweenDifferentTacksDownwind(); + double threshold = 20; + result = usePolarsIfPossible(wind, defaultAngle, LegType.DOWNWIND, threshold); + return result; + } + + private Pair getMinimumAngleBetweenDifferentTacksUpwind(Wind wind) { + Pair result; + double defaultAngle = getRace().getBoatClass().getMinimumAngleBetweenDifferentTacksUpwind(); + double threshold = 10; + result = usePolarsIfPossible(wind, defaultAngle, LegType.UPWIND, threshold); + return result; } - private double getMinimumAngleBetweenDifferentTacksUpwind() { - return getRace().getBoatClass().getMinimumAngleBetweenDifferentTacksUpwind(); + private Pair usePolarsIfPossible(Wind wind, double defaultAngle, LegType legType, double threshold) { + Pair result; + if (polarDataService != null) { + try { + BearingWithConfidence average = polarDataService.getManeuverAngle(getRace().getBoatClass(), + legType == LegType.DOWNWIND ? ManeuverType.JIBE : ManeuverType.TACK, wind); + double averageAngleInDegMinusThreshold = average.getObject().getDegrees() - threshold; + if (averageAngleInDegMinusThreshold < defaultAngle) { + result = new Pair(defaultAngle, 0.1); + } else { + result = new Pair(averageAngleInDegMinusThreshold, average.getConfidence()); + } + } catch (NotEnoughDataHasBeenAddedException | IllegalArgumentException e) { + result = new Pair(defaultAngle, 0.1); + } + } else { + result = new Pair(defaultAngle, 0.1); + } + return result; } private long getApproximateManeuverDurationInMilliseconds() { @@ -3422,13 +3482,12 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl @Override public long getGateStartGolfDownTime() { long result = 0; - if (isGateStart()) { + Boolean isGateStart = isGateStart(); + if (isGateStart != null && isGateStart.booleanValue() == true) { for (RaceLog raceLog : attachedRaceLogs.values()) { raceLog.lockForRead(); for(RaceLogEvent raceLogEvent: raceLog.getRawFixes()) { - logger.log(Level.INFO, ""+raceLogEvent.getClass().getName()); if(raceLogEvent.getClass().equals(RaceLogGateLineOpeningTimeEventImpl.class)){ - logger.log(Level.INFO, "GOT RIGHT EVENT"+raceLogEvent.getClass().getName()); RaceLogGateLineOpeningTimeEvent raceLogGateLineOpeningTimeEvent = (RaceLogGateLineOpeningTimeEvent) raceLogEvent; result = raceLogGateLineOpeningTimeEvent.getGateLineOpeningTimes().getGolfDownTime(); } @@ -3455,5 +3514,24 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl } return result; } + + @Override + public Duration getEstimatedTimeToComplete(TimePoint timepoint) throws NotEnoughDataHasBeenAddedException, + NoWindException { + if (polarDataService == null) { + throw new NotEnoughDataHasBeenAddedException("Target time estimation failed. No polar service available."); + } + Duration durationOfAllLegs = new MillisecondsDurationImpl(0); + for (TrackedLeg leg : trackedLegs.values()) { + Duration durationOfLeg = leg.getEstimatedTimeToComplete(polarDataService, timepoint); + durationOfAllLegs = durationOfAllLegs.plus(durationOfLeg); + } + return durationOfAllLegs; + } + + @Override + public void setPolarDataService(PolarDataService polarDataService) { + this.polarDataService = polarDataService; + } } diff --git a/java/com.sap.sailing.feature.p2build/raceanalysis.product b/java/com.sap.sailing.feature.p2build/raceanalysis.product index 36b1d6445f4..520588e980e 100755 --- a/java/com.sap.sailing.feature.p2build/raceanalysis.product +++ b/java/com.sap.sailing.feature.p2build/raceanalysis.product @@ -48,6 +48,7 @@ + diff --git a/java/com.sap.sailing.feature/feature.xml b/java/com.sap.sailing.feature/feature.xml index 2aad440fdba..18033f4cc45 100755 --- a/java/com.sap.sailing.feature/feature.xml +++ b/java/com.sap.sailing.feature/feature.xml @@ -444,4 +444,11 @@ Computes leaderboard information for sailing races and offers RESTful APIs to al version="0.0.0" unpack="false"/> + + diff --git a/java/com.sap.sailing.freg.resultimport/src/com/sap/sailing/freg/resultimport/impl/ScoreCorrectionProviderImpl.java b/java/com.sap.sailing.freg.resultimport/src/com/sap/sailing/freg/resultimport/impl/ScoreCorrectionProviderImpl.java index 22344d07ba5..5453a3bf383 100755 --- a/java/com.sap.sailing.freg.resultimport/src/com/sap/sailing/freg/resultimport/impl/ScoreCorrectionProviderImpl.java +++ b/java/com.sap.sailing.freg.resultimport/src/com/sap/sailing/freg/resultimport/impl/ScoreCorrectionProviderImpl.java @@ -86,4 +86,9 @@ public class ScoreCorrectionProviderImpl implements ScoreCorrectionProvider, Res } return null; } + + @Override + public String getOptionalSampleURL() { + return null; + } } diff --git a/java/com.sap.sailing.geocoding/build.gradle b/java/com.sap.sailing.geocoding/build.gradle new file mode 100644 index 00000000000..992bcdc7a95 --- /dev/null +++ b/java/com.sap.sailing.geocoding/build.gradle @@ -0,0 +1,14 @@ +apply plugin: "java" + +sourceSets { + main { + java.srcDirs = ["src"] + } +} + +dependencies { + compile "com.googlecode.json-simple:json-simple:1.1.1" + + /* local dependencies */ + compile project(":java:com.sap.sailing.domain.common") +} diff --git a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java index aa46c6881da..026e4ff0ac0 100755 --- a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java +++ b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java @@ -38,6 +38,8 @@ import com.sap.sailing.domain.common.racelog.Flags; import com.sap.sailing.domain.common.tracking.GPSFix; import com.sap.sailing.domain.common.tracking.GPSFixMoving; import com.sap.sailing.domain.leaderboard.ScoringScheme; +import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException; +import com.sap.sailing.domain.polars.PolarDataService; import com.sap.sailing.domain.racelog.tracking.GPSFixStore; import com.sap.sailing.domain.regattalike.RegattaLikeIdentifier; import com.sap.sailing.domain.regattalike.RegattaLikeListener; @@ -64,6 +66,7 @@ import com.sap.sailing.domain.tracking.WindStore; import com.sap.sailing.domain.tracking.WindTrack; import com.sap.sailing.domain.tracking.WindWithConfidence; import com.sap.sailing.domain.tracking.impl.WindTrackImpl; +import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; @@ -902,4 +905,15 @@ public class MockedTrackedRace implements DynamicTrackedRace { // TODO Auto-generated method stub return 0; } + + @Override + public void setPolarDataService(PolarDataService polarDataService) { + } + + @Override + public Duration getEstimatedTimeToComplete(TimePoint timepoint) throws NotEnoughDataHasBeenAddedException, + NoWindException { + // TODO Auto-generated method stub + return null; + } } diff --git a/java/com.sap.sailing.gwt.ui/.settings/org.eclipse.core.resources.prefs b/java/com.sap.sailing.gwt.ui/.settings/org.eclipse.core.resources.prefs index 548f1163d5a..eea2dc034bb 100755 --- a/java/com.sap.sailing.gwt.ui/.settings/org.eclipse.core.resources.prefs +++ b/java/com.sap.sailing.gwt.ui/.settings/org.eclipse.core.resources.prefs @@ -1,3 +1,7 @@ eclipse.preferences.version=1 +encoding//src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.properties=UTF-8 +encoding//src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_cn.properties=UTF-8 +encoding//src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties=UTF-8 +encoding//src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_cn.properties=UTF-8 encoding//src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties=UTF-8 encoding//src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties=UTF-8 diff --git a/java/com.sap.sailing.gwt.ui/CommonControls.css b/java/com.sap.sailing.gwt.ui/CommonControls.css index ebe33c16fb5..150a3183574 100755 --- a/java/com.sap.sailing.gwt.ui/CommonControls.css +++ b/java/com.sap.sailing.gwt.ui/CommonControls.css @@ -25,7 +25,6 @@ body ::-webkit-scrollbar-button { body ::-webkit-scrollbar-track { border-left: 6px solid transparent; border-right: 1px solid transparent; - background-clip: padding-box; } .collapsablePanel { @@ -339,8 +338,10 @@ body ::-webkit-scrollbar-track { } .gwt-TabBar { - background: #ccc; - padding-top: 6px; + margin-top: 20px; + border-bottom: 1px solid #dedede; + margin-bottom: 10px; + } .gwt-TabBar .gwt-TabBarFirst { @@ -352,22 +353,27 @@ body ::-webkit-scrollbar-track { .gwt-TabBar .gwt-TabBarItem { margin-left: 4px; - padding: 4px 8px 4px 8px; + padding: 10px 12px; cursor: pointer; cursor: hand; - color: white; + color: black; font-weight: normal; text-align: center; - background: #8E8E8E; - -moz-border-radius: 3px 3px 0px 0px; - border-radius: 3px 3px 0px 0px; + background: #ebebeb; + border-radius: 4px 4px 0px 0px; + border-left: 1px solid #dedede; + border-top: 1px solid #dedede; + border-right: 1px solid #dedede; + } +.gwt-TabBarItem:FOCUS { + outline: none; +} .gwt-TabBar .gwt-TabBarItem-selected { cursor: default; background: white; - color: #333; - font-weight: bold; + color: black; } .gwt-TabBar .gwt-TabBarItem-disabled { @@ -696,76 +702,54 @@ body ::-webkit-scrollbar-track { .gwt-DialogBox { line-height: 1.4; + background-color: #cecece; + border: 1px solid #3e3e3e; + border-radius: 4px; + box-shadow: 0px 0px 10px 0px #3e3e3e; +} + +.gwt-PopupPanelGlass { + background-color: rgba(140,140,140,0.5); } .gwt-DialogBox .Caption { font-size: 14px; padding: 8px 10px; - background-color: #cecece; - border: 1px solid #cecece; - -webkit-border-top-left-radius: 5px; - -webkit-border-top-right-radius: 5px; - -moz-border-radius-topleft: 5px; - -moz-border-radius-topright: 5px; - -o-border-radius-topleft: 5px; - -o-border-radius-topright: 5px; - -ms-border-radius-topleft: 5px; - -ms-border-radius-topright: 5px; - border-top-left-radius: 5px; - border-top-right-radius: 5px; - font-family: OpenSansSemiBold, Verdana, Arial, sans-serif; + background-color: #ededed; + border-bottom: 1px solid #3e3e3e; + font-family: OpenSansSemiBold, Verdana, Arial, sans-serif; } .gwt-DialogBox .dialogContent { background: #ffffff; padding: 10px; - border: 1px solid #cecece; - -webkit-border-bottom-right-radius: 5px; - -webkit-border-bottom-left-radius: 5px; - -o-border-bottom-right-radius: 5px; - -o-border-bottom-left-radius: 5px; - -ms-border-bottom-right-radius: 5px; - -ms-border-bottom-left-radius: 5px; - -moz-border-radius-bottomright: 5px; - -moz-border-radius-bottomleft: 5px; - border-bottom-right-radius: 5px; - border-bottom-left-radius: 5px; + + } .gwt-Button, .gwt-Button:visited { - font-family: OpenSansSemiBold, Verdana, Arial, sans-serif; + font-size: 0,9rem; + display: inline-block; + color: #fff; border: none; - background: url(images/btn-cta-orangeleft.png) center top repeat-x; - display: inline-block; - padding: 2px 10px 4px; - color: #fff; - text-decoration: none; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - -o-border-radius: 5px; - -ms-border-radius: 5px; - border-radius: 5px; - border-bottom: 1px solid rgba(0, 0, 0, 0.25); - cursor: pointer; - height: 24px; - white-space: nowrap; - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); - -o-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); - -ms-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); - text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.25); + padding: 5px 10px; + border-radius: 4px; + background-color: #efaa00; + -webkit-transition: background-color 0.2s; + -moz-transition: background-color 0.2s; + transition: background-color 0.2s; + text-decoration: none; + cursor: pointer; } .gwt-Button:active { - top: 1px; - position: relative; border: none; } .gwt-Button:hover { - background: url(images/btn-cta-orangeleft.png) center -30px repeat-x; - cursor: pointer; + background-color: #d79900; + outline: none; + text-decoration: none; } .gwt-Button[disabled] { @@ -935,3 +919,9 @@ video { padding: 8px 2px; font-size: 10px; } + + +label { + padding-left: 4px; +} + diff --git a/java/com.sap.sailing.gwt.ui/Home.html b/java/com.sap.sailing.gwt.ui/Home.html index fff59cd0aba..dce5c8e20f6 100644 --- a/java/com.sap.sailing.gwt.ui/Home.html +++ b/java/com.sap.sailing.gwt.ui/Home.html @@ -42,8 +42,8 @@ - - + + diff --git a/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF b/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF index 26eb1466b06..5dc0cd4fa7b 100644 --- a/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF @@ -46,13 +46,11 @@ Require-Bundle: com.sap.sailing.domain, com.sap.sse, com.sap.sse.security.common, com.sap.sse.filestorage, - org.apache.shiro.core;bundle-version="1.2.2" + org.apache.shiro.core;bundle-version="1.2.2", + com.sap.sse.gwt.theme Bundle-Activator: com.sap.sailing.gwt.ui.server.Activator Bundle-ActivationPolicy: lazy -Import-Package: com.sap.sailing.polars, - com.sap.sailing.polars.factory, - com.sap.sailing.polars.regression, - javax.jms;version="1.1.0", +Import-Package: javax.jms;version="1.1.0", javax.servlet;version="3.1.0", javax.servlet.descriptor;version="3.1.0", javax.servlet.http;version="3.1.0", diff --git a/java/com.sap.sailing.gwt.ui/SailingGWT Remote Profiling (Run-Mode only).launch b/java/com.sap.sailing.gwt.ui/SailingGWT Remote Profiling (Run-Mode only).launch old mode 100644 new mode 100755 diff --git a/java/com.sap.sailing.gwt.ui/SailingGWT sdm.launch b/java/com.sap.sailing.gwt.ui/SailingGWT sdm.launch index 949b0f66cee..3589088c95b 100755 --- a/java/com.sap.sailing.gwt.ui/SailingGWT sdm.launch +++ b/java/com.sap.sailing.gwt.ui/SailingGWT sdm.launch @@ -36,6 +36,7 @@ + diff --git a/java/com.sap.sailing.gwt.ui/SailingGWT.launch b/java/com.sap.sailing.gwt.ui/SailingGWT.launch index ce32176a98c..ae72a466d25 100755 --- a/java/com.sap.sailing.gwt.ui/SailingGWT.launch +++ b/java/com.sap.sailing.gwt.ui/SailingGWT.launch @@ -34,6 +34,7 @@ + diff --git a/java/com.sap.sailing.gwt.ui/SettingsDialog.css b/java/com.sap.sailing.gwt.ui/SettingsDialog.css index f0f54b31d75..cfb8175cc32 100644 --- a/java/com.sap.sailing.gwt.ui/SettingsDialog.css +++ b/java/com.sap.sailing.gwt.ui/SettingsDialog.css @@ -4,16 +4,11 @@ } .dialogInnerHeadline { - border: 1px solid #CCCCCC; + border-bottom: 1px solid #CCCCCC; font-family: OpenSansSemiBold,Arial,Verdana,sans-serif; height: 21px; - padding: 2px 0 0 7px; - border-radius: 3px; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - -o-border-radius: 3px; - -ms-border-radius: 3px; - margin: 0 0 10px 0; + padding: 2px 0 0 2px; + margin-bottom: 4px; } .dialogInnerHeadlineOther { @@ -27,5 +22,5 @@ } .SettingsDialogComponent .gwt-CheckBox { - padding: 0 10px 0 0; + padding: 0 10px 10px 0; } diff --git a/java/com.sap.sailing.gwt.ui/WEB-INF/.gitignore b/java/com.sap.sailing.gwt.ui/WEB-INF/.gitignore index f80255dd5c0..3c6742f8d29 100755 --- a/java/com.sap.sailing.gwt.ui/WEB-INF/.gitignore +++ b/java/com.sap.sailing.gwt.ui/WEB-INF/.gitignore @@ -1,2 +1 @@ -deploy -classes \ No newline at end of file +deploy \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/WEB-INF/classes/.gitignore b/java/com.sap.sailing.gwt.ui/WEB-INF/classes/.gitignore new file mode 100755 index 00000000000..22e83649f7d --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/WEB-INF/classes/.gitignore @@ -0,0 +1 @@ +/* \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/WEB-INF/web.xml b/java/com.sap.sailing.gwt.ui/WEB-INF/web.xml index 2c9a4ee5997..0db072b48c4 100755 --- a/java/com.sap.sailing.gwt.ui/WEB-INF/web.xml +++ b/java/com.sap.sailing.gwt.ui/WEB-INF/web.xml @@ -63,6 +63,16 @@ /service/sailing + + Home Service + HomeService + com.sap.sailing.gwt.home.server.HomeServiceImpl + + + HomeService + /service/home + + Media Service MediaService diff --git a/java/com.sap.sailing.gwt.ui/images/home/arrow-down-grey.png b/java/com.sap.sailing.gwt.ui/images/home/arrow-down-grey.png new file mode 100644 index 00000000000..85a2c447304 Binary files /dev/null and b/java/com.sap.sailing.gwt.ui/images/home/arrow-down-grey.png differ diff --git a/java/com.sap.sailing.gwt.ui/images/home/breadcrumb-arrow.png b/java/com.sap.sailing.gwt.ui/images/home/breadcrumb-arrow.png new file mode 100644 index 00000000000..2c456ead3a9 Binary files /dev/null and b/java/com.sap.sailing.gwt.ui/images/home/breadcrumb-arrow.png differ diff --git a/java/com.sap.sailing.gwt.ui/images/home/dropdown__button--arrow@2x.png b/java/com.sap.sailing.gwt.ui/images/home/dropdown__button--arrow@2x.png new file mode 100644 index 00000000000..5ec5ecafb08 Binary files /dev/null and b/java/com.sap.sailing.gwt.ui/images/home/dropdown__button--arrow@2x.png differ diff --git a/java/com.sap.sailing.gwt.ui/images/home/dropdown__check@2x.png b/java/com.sap.sailing.gwt.ui/images/home/dropdown__check@2x.png new file mode 100644 index 00000000000..900b294bccf Binary files /dev/null and b/java/com.sap.sailing.gwt.ui/images/home/dropdown__check@2x.png differ diff --git a/java/com.sap.sailing.gwt.ui/images/home/facebook-logo.svg b/java/com.sap.sailing.gwt.ui/images/home/facebook-logo.svg new file mode 100644 index 00000000000..034a7386e24 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/images/home/facebook-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/images/home/logo-small@2x.png b/java/com.sap.sailing.gwt.ui/images/home/logo-small@2x.png new file mode 100644 index 00000000000..e5d2daf91f3 Binary files /dev/null and b/java/com.sap.sailing.gwt.ui/images/home/logo-small@2x.png differ diff --git a/java/com.sap.sailing.gwt.ui/images/home/search-icon@2x.png b/java/com.sap.sailing.gwt.ui/images/home/search-icon@2x.png new file mode 100644 index 00000000000..9a9c7f5b691 Binary files /dev/null and b/java/com.sap.sailing.gwt.ui/images/home/search-icon@2x.png differ diff --git a/java/com.sap.sailing.gwt.ui/images/home/social-icons.png b/java/com.sap.sailing.gwt.ui/images/home/social-icons.png deleted file mode 100644 index f9566384566..00000000000 Binary files a/java/com.sap.sailing.gwt.ui/images/home/social-icons.png and /dev/null differ diff --git a/java/com.sap.sailing.gwt.ui/images/home/solutions-simulator.png b/java/com.sap.sailing.gwt.ui/images/home/solutions-simulator.png index 9123f6fccaf..a1e9beb92f0 100644 Binary files a/java/com.sap.sailing.gwt.ui/images/home/solutions-simulator.png and b/java/com.sap.sailing.gwt.ui/images/home/solutions-simulator.png differ diff --git a/java/com.sap.sailing.gwt.ui/images/home/twitter-logo.svg b/java/com.sap.sailing.gwt.ui/images/home/twitter-logo.svg new file mode 100644 index 00000000000..5094bb1fed0 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/images/home/twitter-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/images/home/upcoming-events-icon.png b/java/com.sap.sailing.gwt.ui/images/home/upcoming-events-icon.png new file mode 100644 index 00000000000..1dceb90736d Binary files /dev/null and b/java/com.sap.sailing.gwt.ui/images/home/upcoming-events-icon.png differ diff --git a/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-1.3.15.css b/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-1.3.15.css deleted file mode 100644 index 2570f48dfd8..00000000000 --- a/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-1.3.15.css +++ /dev/null @@ -1,57 +0,0 @@ -@charset "UTF-8"; -/* Slider */ -.slick-slider { position: relative; display: block; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -ms-touch-action: pan-y; touch-action: pan-y; -webkit-tap-highlight-color: transparent; } - -.slick-list { position: relative; overflow: hidden; display: block; margin: 0; padding: 0; } -.slick-list:focus { outline: none; } -.slick-loading .slick-list { background: #fff url("./ajax-loader.gif") center center no-repeat; } -.slick-list.dragging { cursor: pointer; cursor: hand; } - -.slick-slider .slick-track { -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } - -.slick-track { position: relative; left: 0; top: 0; display: block; } -.slick-track:before, .slick-track:after { content: ""; display: table; } -.slick-track:after { clear: both; } -.slick-loading .slick-track { visibility: hidden; } - -.slick-slide { float: left; height: 100%; min-height: 1px; display: none; } -[dir="rtl"] .slick-slide { float: right; } -.slick-slide img { display: block; } -.slick-slide.slick-loading img { display: none; } -.slick-slide.dragging img { pointer-events: none; } -.slick-initialized .slick-slide { display: block; } -.slick-loading .slick-slide { visibility: hidden; } -.slick-vertical .slick-slide { display: block; height: auto; border: 1px solid transparent; } - -/* Icons */ -@font-face { font-family: "slick"; src: url("./fonts/slick.eot"); src: url("./fonts/slick.eot?#iefix") format("embedded-opentype"), url("./fonts/slick.woff") format("woff"), url("./fonts/slick.ttf") format("truetype"), url("./fonts/slick.svg#slick") format("svg"); font-weight: normal; font-style: normal; } -/* Arrows */ -.slick-prev, .slick-next { position: absolute; display: block; height: 20px; width: 20px; line-height: 0; font-size: 0; cursor: pointer; background: transparent; color: transparent; top: 50%; margin-top: -10px; padding: 0; border: none; outline: none; } -.slick-prev:hover, .slick-prev:focus, .slick-next:hover, .slick-next:focus { outline: none; background: transparent; color: transparent; } -.slick-prev:hover:before, .slick-prev:focus:before, .slick-next:hover:before, .slick-next:focus:before { opacity: 1; } -.slick-prev.slick-disabled:before, .slick-next.slick-disabled:before { opacity: 0.25; } - -.slick-prev:before, .slick-next:before { font-family: "slick"; font-size: 20px; line-height: 1; color: white; opacity: 0.75; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } - -.slick-prev { left: -25px; } -[dir="rtl"] .slick-prev { left: auto; right: -25px; } -.slick-prev:before { content: "←"; } -[dir="rtl"] .slick-prev:before { content: "→"; } - -.slick-next { right: -25px; } -[dir="rtl"] .slick-next { left: -25px; right: auto; } -.slick-next:before { content: "→"; } -[dir="rtl"] .slick-next:before { content: "←"; } - -/* Dots */ -.slick-slider { margin-bottom: 30px; } - -.slick-dots { position: absolute; bottom: -45px; list-style: none; display: block; text-align: center; padding: 0; width: 100%; } -.slick-dots li { position: relative; display: inline-block; height: 20px; width: 20px; margin: 0 5px; padding: 0; cursor: pointer; } -.slick-dots li button { border: 0; background: transparent; display: block; height: 20px; width: 20px; outline: none; line-height: 0; font-size: 0; color: transparent; padding: 5px; cursor: pointer; } -.slick-dots li button:hover, .slick-dots li button:focus { outline: none; } -.slick-dots li button:hover:before, .slick-dots li button:focus:before { opacity: 1; } -.slick-dots li button:before { position: absolute; top: 0; left: 0; content: "•"; width: 20px; height: 20px; font-family: "slick"; font-size: 6px; line-height: 20px; text-align: center; color: black; opacity: 0.25; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } -.slick-dots li.slick-active button:before { color: black; opacity: 0.75; } - -/*# sourceMappingURL=slick.css.map */ diff --git a/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-1.3.15.css.map b/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-1.3.15.css.map deleted file mode 100644 index 9f0499ad5e6..00000000000 --- a/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-1.3.15.css.map +++ /dev/null @@ -1,7 +0,0 @@ -{ -"version": 3, -"mappings": ";;AAuCA,aAAc,GACV,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,KAAK,EACd,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,UAAU,EAC3B,qBAAqB,EAAE,IAAI,EAC3B,mBAAmB,EAAE,IAAI,EACzB,kBAAkB,EAAE,IAAI,EACxB,gBAAgB,EAAE,IAAI,EACtB,eAAe,EAAE,IAAI,EACrB,WAAW,EAAE,IAAI,EACjB,gBAAgB,EAAE,KAAK,EACvB,YAAY,EAAE,KAAK,EACnB,2BAA2B,EAAE,WAAW;;AAE5C,WAAY,GACR,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,KAAK,EACd,MAAM,EAAE,CAAC,EACT,OAAO,EAAE,CAAC;AAEV,iBAAQ,GACJ,OAAO,EAAE,IAAI;AAGjB,0BAAiB,GACb,UAAU,EAAE,qDAA+D;AAG/E,oBAAW,GACP,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,IAAI;;AAGpB,0BAA2B,GACvB,iBAAiB,EAAE,oBAAoB,EACvC,cAAc,EAAE,oBAAoB,EACpC,aAAa,EAAE,oBAAoB,EACnC,YAAY,EAAE,oBAAoB,EAClC,SAAS,EAAE,oBAAoB;;AAGnC,YAAa,GACT,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,CAAC,EACP,GAAG,EAAE,CAAC,EACN,OAAO,EAAE,KAAK;AAEd,uCACQ,GACJ,OAAO,EAAE,EAAE,EACX,OAAO,EAAE,KAAK;AAGlB,kBAAQ,GACJ,KAAK,EAAE,IAAI;AAGf,2BAAiB,GACb,UAAU,EAAE,MAAM;;AAG1B,YAAa,GACT,KAAK,EAAE,IAAI,EACX,MAAM,EAAE,IAAI,EACZ,UAAU,EAAE,GAAG,EAWf,OAAO,EAAE,IAAI;AAVb,wBAAc,GACV,KAAK,EAAE,KAAK;AAEhB,gBAAI,GACA,OAAO,EAAE,KAAK;AAElB,8BAAoB,GAChB,OAAO,EAAE,IAAI;AAKjB,yBAAe,GACX,cAAc,EAAE,IAAI;AAGxB,+BAAqB,GACjB,OAAO,EAAE,KAAK;AAGlB,2BAAiB,GACb,UAAU,EAAE,MAAM;AAGtB,4BAAkB,GACd,OAAO,EAAE,KAAK,EACd,MAAM,EAAE,IAAI,EACZ,MAAM,EAAE,qBAAqB;;;AAMnC,UASC,GARG,WAAW,EAAC,OAAO,EACnB,GAAG,EAAK,wBAA2B,EACnC,GAAG,EAAK,gMAA8D,EAItE,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM;;AAMxB,wBACY,GACR,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,KAAK,EACd,MAAM,EAAE,IAAI,EACZ,KAAK,EAAE,IAAI,EACX,WAAW,EAAE,CAAC,EACd,SAAS,EAAE,CAAC,EACZ,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,WAAW,EACvB,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,KAAK,EACjB,OAAO,EAAE,CAAC,EACV,MAAM,EAAE,IAAI,EACZ,OAAO,EAAE,IAAI;AACb,0EAAiB,GACf,OAAO,EAAE,IAAI,EACb,UAAU,EAAE,WAAW,EACvB,KAAK,EAAE,WAAW;AAClB,sGAAS,GACP,OAAO,EA/JI,CAAC;AAkKhB,oEAAwB,GACpB,OAAO,EAlKM,IAAG;;AAqKxB,sCAAuC,GACnC,WAAW,EAjLK,OAAO,EAkLvB,SAAS,EAAE,IAAI,EACf,WAAW,EAAE,CAAC,EACd,KAAK,EAlLW,KAAK,EAmLrB,OAAO,EA5KO,IAAG,EA6KjB,sBAAsB,EAAE,WAAW,EACnC,uBAAuB,EAAE,SAAS;;AAEtC,WAAY,GACR,IAAI,EAAE,KAAK;AACX,uBAAc,GACV,IAAI,EAAG,IAAI,EACX,KAAK,EAAE,KAAK;AAEhB,kBAAS,GACL,OAAO,EA3LQ,GAAO;AA4LtB,8BAAc,GACV,OAAO,EA5LI,GAAO;;AAgM9B,WAAY,GACR,KAAK,EAAE,KAAK;AACZ,uBAAc,GACV,IAAI,EAAG,KAAK,EACZ,KAAK,EAAE,IAAI;AAEf,kBAAS,GACL,OAAO,EAvMQ,GAAO;AAwMtB,8BAAc,GACV,OAAO,EA1MI,GAAO;;;AAiN9B,aAAc,GACV,aAAa,EAAE,IAAI;;AAEvB,WAAY,GACR,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,KAAK,EACb,UAAU,EAAE,IAAI,EAChB,OAAO,EAAE,KAAK,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,CAAC,EACV,KAAK,EAAE,IAAI;AAEX,cAAG,GACC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,IAAI,EACZ,KAAK,EAAE,IAAI,EACX,MAAM,EAAE,KAAK,EACb,OAAO,EAAE,CAAC,EACV,MAAM,EAAE,OAAO;AAEf,qBAAO,GACH,MAAM,EAAE,CAAC,EACT,UAAU,EAAE,WAAW,EACvB,OAAO,EAAE,KAAK,EACd,MAAM,EAAE,IAAI,EACZ,KAAK,EAAE,IAAI,EACX,OAAO,EAAE,IAAI,EACb,WAAW,EAAE,CAAC,EACd,SAAS,EAAE,CAAC,EACZ,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,GAAG,EACZ,MAAM,EAAE,OAAO;AACf,wDAAiB,GACb,OAAO,EAAE,IAAI;AACb,sEAAS,GACP,OAAO,EAhPN,CAAC;AAoPR,4BAAS,GACL,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,CAAC,EACP,OAAO,EA3PD,GAAO,EA4Pb,KAAK,EAAE,IAAI,EACX,MAAM,EAAE,IAAI,EACZ,WAAW,EArQP,OAAO,EAsQX,SAAS,EA9PR,GAAG,EA+PJ,WAAW,EAAE,IAAI,EACjB,UAAU,EAAE,MAAM,EAClB,KAAK,EArQI,KAAgB,EAsQzB,OAAO,EA/PF,IAAG,EAgQR,sBAAsB,EAAE,WAAW,EACnC,uBAAuB,EAAE,SAAS;AAK1C,yCAA6B,GACzB,KAAK,EA9QQ,KAAgB,EA+Q7B,OAAO,EA1QD,IAAG", -"sources": ["slick.scss"], -"names": [], -"file": "slick.css" -} diff --git a/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-1.3.15.min.js b/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-1.3.15.min.js deleted file mode 100644 index ae481fab867..00000000000 --- a/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-1.3.15.min.js +++ /dev/null @@ -1,18 +0,0 @@ -/* - _ _ _ _ - ___| (_) ___| | __ (_)___ -/ __| | |/ __| |/ / | / __| -\__ \ | | (__| < _ | \__ \ -|___/_|_|\___|_|\_(_)/ |___/ - |__/ - - Version: 1.3.15 - Author: Ken Wheeler - Website: http://kenwheeler.github.io - Docs: http://kenwheeler.github.io/slick - Repo: http://github.com/kenwheeler/slick - Issues: http://github.com/kenwheeler/slick/issues - - */ - -!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):"undefined"!=typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){"use strict";var b=window.Slick||{};b=function(){function c(c,d){var f,g,e=this;if(e.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:a(c),appendDots:a(c),arrows:!0,asNavFor:null,prevArrow:'',nextArrow:'',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(a,b){return'"},dots:!1,dotsClass:"slick-dots",draggable:!0,easing:"linear",fade:!1,focusOnSelect:!1,infinite:!0,initialSlide:0,lazyLoad:"ondemand",onBeforeChange:null,onAfterChange:null,onInit:null,onReInit:null,onSetPosition:null,pauseOnHover:!0,pauseOnDotsHover:!1,respondTo:"window",responsive:null,rtl:!1,slide:"div",slidesToShow:1,slidesToScroll:1,speed:500,swipe:!0,swipeToSlide:!1,touchMove:!0,touchThreshold:5,useCSS:!0,variableWidth:!1,vertical:!1,waitForAnimate:!0},e.initials={animating:!1,dragging:!1,autoPlayTimer:null,currentDirection:0,currentLeft:null,currentSlide:0,direction:1,$dots:null,listWidth:null,listHeight:null,loadIndex:0,$nextArrow:null,$prevArrow:null,slideCount:null,slideWidth:null,$slideTrack:null,$slides:null,sliding:!1,slideOffset:0,swipeLeft:null,$list:null,touchObject:{},transformsEnabled:!1},a.extend(e,e.initials),e.activeBreakpoint=null,e.animType=null,e.animProp=null,e.breakpoints=[],e.breakpointSettings=[],e.cssTransitions=!1,e.paused=!1,e.positionProp=null,e.respondTo=null,e.shouldClick=!0,e.$slider=a(c),e.$slidesCache=null,e.transformType=null,e.transitionType=null,e.windowWidth=0,e.windowTimer=null,e.options=a.extend({},e.defaults,d),e.currentSlide=e.options.initialSlide,e.originalSettings=e.options,f=e.options.responsive||null,f&&f.length>-1){e.respondTo=e.options.respondTo||"window";for(g in f)f.hasOwnProperty(g)&&(e.breakpoints.push(f[g].breakpoint),e.breakpointSettings[f[g].breakpoint]=f[g].settings);e.breakpoints.sort(function(a,b){return b-a})}e.autoPlay=a.proxy(e.autoPlay,e),e.autoPlayClear=a.proxy(e.autoPlayClear,e),e.changeSlide=a.proxy(e.changeSlide,e),e.clickHandler=a.proxy(e.clickHandler,e),e.selectHandler=a.proxy(e.selectHandler,e),e.setPosition=a.proxy(e.setPosition,e),e.swipeHandler=a.proxy(e.swipeHandler,e),e.dragHandler=a.proxy(e.dragHandler,e),e.keyHandler=a.proxy(e.keyHandler,e),e.autoPlayIterator=a.proxy(e.autoPlayIterator,e),e.instanceUid=b++,e.htmlExpr=/^(?:\s*(<[\w\W]+>)[^>]*)$/,e.init(),e.checkResponsive()}var b=0;return c}(),b.prototype.addSlide=function(b,c,d){var e=this;if("boolean"==typeof c)d=c,c=null;else if(0>c||c>=e.slideCount)return!1;e.unload(),"number"==typeof c?0===c&&0===e.$slides.length?a(b).appendTo(e.$slideTrack):d?a(b).insertBefore(e.$slides.eq(c)):a(b).insertAfter(e.$slides.eq(c)):d===!0?a(b).prependTo(e.$slideTrack):a(b).appendTo(e.$slideTrack),e.$slides=e.$slideTrack.children(this.options.slide),e.$slideTrack.children(this.options.slide).detach(),e.$slideTrack.append(e.$slides),e.$slides.each(function(b,c){a(c).attr("index",b)}),e.$slidesCache=e.$slides,e.reinit()},b.prototype.animateSlide=function(b,c){var d={},e=this;if(1===e.options.slidesToShow&&e.options.adaptiveHeight===!0&&e.options.vertical===!1){var f=e.$slides.eq(e.currentSlide).outerHeight(!0);e.$list.animate({height:f},e.options.speed)}e.options.rtl===!0&&e.options.vertical===!1&&(b=-b),e.transformsEnabled===!1?e.options.vertical===!1?e.$slideTrack.animate({left:b},e.options.speed,e.options.easing,c):e.$slideTrack.animate({top:b},e.options.speed,e.options.easing,c):e.cssTransitions===!1?a({animStart:e.currentLeft}).animate({animStart:b},{duration:e.options.speed,easing:e.options.easing,step:function(a){e.options.vertical===!1?(d[e.animType]="translate("+a+"px, 0px)",e.$slideTrack.css(d)):(d[e.animType]="translate(0px,"+a+"px)",e.$slideTrack.css(d))},complete:function(){c&&c.call()}}):(e.applyTransition(),d[e.animType]=e.options.vertical===!1?"translate3d("+b+"px, 0px, 0px)":"translate3d(0px,"+b+"px, 0px)",e.$slideTrack.css(d),c&&setTimeout(function(){e.disableTransition(),c.call()},e.options.speed))},b.prototype.asNavFor=function(b){var c=this,d=null!=c.options.asNavFor?a(c.options.asNavFor).getSlick():null;null!=d&&d.slideHandler(b,!0)},b.prototype.applyTransition=function(a){var b=this,c={};c[b.transitionType]=b.options.fade===!1?b.transformType+" "+b.options.speed+"ms "+b.options.cssEase:"opacity "+b.options.speed+"ms "+b.options.cssEase,b.options.fade===!1?b.$slideTrack.css(c):b.$slides.eq(a).css(c)},b.prototype.autoPlay=function(){var a=this;a.autoPlayTimer&&clearInterval(a.autoPlayTimer),a.slideCount>a.options.slidesToShow&&a.paused!==!0&&(a.autoPlayTimer=setInterval(a.autoPlayIterator,a.options.autoplaySpeed))},b.prototype.autoPlayClear=function(){var a=this;a.autoPlayTimer&&clearInterval(a.autoPlayTimer)},b.prototype.autoPlayIterator=function(){var a=this;a.options.infinite===!1?1===a.direction?(a.currentSlide+1===a.slideCount-1&&(a.direction=0),a.slideHandler(a.currentSlide+a.options.slidesToScroll)):(0===a.currentSlide-1&&(a.direction=1),a.slideHandler(a.currentSlide-a.options.slidesToScroll)):a.slideHandler(a.currentSlide+a.options.slidesToScroll)},b.prototype.buildArrows=function(){var b=this;b.options.arrows===!0&&b.slideCount>b.options.slidesToShow&&(b.$prevArrow=a(b.options.prevArrow),b.$nextArrow=a(b.options.nextArrow),b.htmlExpr.test(b.options.prevArrow)&&b.$prevArrow.appendTo(b.options.appendArrows),b.htmlExpr.test(b.options.nextArrow)&&b.$nextArrow.appendTo(b.options.appendArrows),b.options.infinite!==!0&&b.$prevArrow.addClass("slick-disabled"))},b.prototype.buildDots=function(){var c,d,b=this;if(b.options.dots===!0&&b.slideCount>b.options.slidesToShow){for(d='
    ',c=0;c<=b.getDotCount();c+=1)d+="
  • "+b.options.customPaging.call(this,b,c)+"
  • ";d+="
",b.$dots=a(d).appendTo(b.options.appendDots),b.$dots.find("li").first().addClass("slick-active")}},b.prototype.buildOut=function(){var b=this;b.$slides=b.$slider.children(b.options.slide+":not(.slick-cloned)").addClass("slick-slide"),b.slideCount=b.$slides.length,b.$slides.each(function(b,c){a(c).attr("index",b)}),b.$slidesCache=b.$slides,b.$slider.addClass("slick-slider"),b.$slideTrack=0===b.slideCount?a('
').appendTo(b.$slider):b.$slides.wrapAll('
').parent(),b.$list=b.$slideTrack.wrap('
').parent(),b.$slideTrack.css("opacity",0),b.options.centerMode===!0&&(b.options.slidesToScroll=1),a("img[data-lazy]",b.$slider).not("[src]").addClass("slick-loading"),b.setupInfinite(),b.buildArrows(),b.buildDots(),b.updateDots(),b.options.accessibility===!0&&b.$list.prop("tabIndex",0),b.setSlideClasses("number"==typeof this.currentSlide?this.currentSlide:0),b.options.draggable===!0&&b.$list.addClass("draggable")},b.prototype.checkResponsive=function(){var c,d,e,b=this,f=b.$slider.width(),g=window.innerWidth||a(window).width();if("window"===b.respondTo?e=g:"slider"===b.respondTo?e=f:"min"===b.respondTo&&(e=Math.min(g,f)),b.originalSettings.responsive&&b.originalSettings.responsive.length>-1&&null!==b.originalSettings.responsive){d=null;for(c in b.breakpoints)b.breakpoints.hasOwnProperty(c)&&ed.options.slidesToShow&&d.slideHandler(d.currentSlide-g,!1,c);break;case"next":g=0===f?d.options.slidesToScroll:f,d.slideCount>d.options.slidesToShow&&d.slideHandler(d.currentSlide+g,!1,c);break;case"index":var k=0===b.data.index?0:b.data.index||a(b.target).parent().index()*d.options.slidesToScroll;if(i=d.getNavigableIndexes(),j=0,i[k]&&i[k]===k)if(k>i[i.length-1])k=i[i.length-1];else for(var l in i){if(kb.options.slidesToShow&&(b.slideOffset=-1*b.slideWidth*b.options.slidesToShow,e=-1*d*b.options.slidesToShow),0!==b.slideCount%b.options.slidesToScroll&&a+b.options.slidesToScroll>b.slideCount&&b.slideCount>b.options.slidesToShow&&(a>b.slideCount?(b.slideOffset=-1*(b.options.slidesToShow-(a-b.slideCount))*b.slideWidth,e=-1*(b.options.slidesToShow-(a-b.slideCount))*d):(b.slideOffset=-1*b.slideCount%b.options.slidesToScroll*b.slideWidth,e=-1*b.slideCount%b.options.slidesToScroll*d))):a+b.options.slidesToShow>b.slideCount&&(b.slideOffset=(a+b.options.slidesToShow-b.slideCount)*b.slideWidth,e=(a+b.options.slidesToShow-b.slideCount)*d),b.slideCount<=b.options.slidesToShow&&(b.slideOffset=0,e=0),b.options.centerMode===!0&&b.options.infinite===!0?b.slideOffset+=b.slideWidth*Math.floor(b.options.slidesToShow/2)-b.slideWidth:b.options.centerMode===!0&&(b.slideOffset=0,b.slideOffset+=b.slideWidth*Math.floor(b.options.slidesToShow/2)),c=b.options.vertical===!1?-1*a*b.slideWidth+b.slideOffset:-1*a*d+e,b.options.variableWidth===!0&&(g=b.slideCount<=b.options.slidesToShow||b.options.infinite===!1?b.$slideTrack.children(".slick-slide").eq(a):b.$slideTrack.children(".slick-slide").eq(a+b.options.slidesToShow),c=g[0]?-1*g[0].offsetLeft:0,b.options.centerMode===!0&&(g=b.options.infinite===!1?b.$slideTrack.children(".slick-slide").eq(a):b.$slideTrack.children(".slick-slide").eq(a+b.options.slidesToShow+1),c=g[0]?-1*g[0].offsetLeft:0,c+=(b.$list.width()-g.outerWidth())/2)),c},b.prototype.getNavigableIndexes=function(){for(var a=this,b=0,c=0,d=[];b-1*b.swipeLeft?(d=e,!1):void 0}),c=Math.abs(a(d).attr("index")-b.currentSlide)}return b.options.slidesToScroll},b.prototype.init=function(){var b=this;a(b.$slider).hasClass("slick-initialized")||(a(b.$slider).addClass("slick-initialized"),b.buildOut(),b.setProps(),b.startLoad(),b.loadSlider(),b.initializeEvents(),b.updateArrows(),b.updateDots()),null!==b.options.onInit&&b.options.onInit.call(this,b)},b.prototype.initArrowEvents=function(){var a=this;a.options.arrows===!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.on("click.slick",{message:"previous"},a.changeSlide),a.$nextArrow.on("click.slick",{message:"next"},a.changeSlide))},b.prototype.initDotEvents=function(){var b=this;b.options.dots===!0&&b.slideCount>b.options.slidesToShow&&a("li",b.$dots).on("click.slick",{message:"index"},b.changeSlide),b.options.dots===!0&&b.options.pauseOnDotsHover===!0&&b.options.autoplay===!0&&a("li",b.$dots).on("mouseenter.slick",function(){b.paused=!0,b.autoPlayClear()}).on("mouseleave.slick",function(){b.paused=!1,b.autoPlay()})},b.prototype.initializeEvents=function(){var b=this;b.initArrowEvents(),b.initDotEvents(),b.$list.on("touchstart.slick mousedown.slick",{action:"start"},b.swipeHandler),b.$list.on("touchmove.slick mousemove.slick",{action:"move"},b.swipeHandler),b.$list.on("touchend.slick mouseup.slick",{action:"end"},b.swipeHandler),b.$list.on("touchcancel.slick mouseleave.slick",{action:"end"},b.swipeHandler),b.$list.on("click.slick",b.clickHandler),b.options.pauseOnHover===!0&&b.options.autoplay===!0&&(b.$list.on("mouseenter.slick",function(){b.paused=!0,b.autoPlayClear()}),b.$list.on("mouseleave.slick",function(){b.paused=!1,b.autoPlay()})),b.options.accessibility===!0&&b.$list.on("keydown.slick",b.keyHandler),b.options.focusOnSelect===!0&&a(b.options.slide,b.$slideTrack).on("click.slick",b.selectHandler),a(window).on("orientationchange.slick.slick-"+b.instanceUid,function(){b.checkResponsive(),b.setPosition()}),a(window).on("resize.slick.slick-"+b.instanceUid,function(){a(window).width()!==b.windowWidth&&(clearTimeout(b.windowDelay),b.windowDelay=window.setTimeout(function(){b.windowWidth=a(window).width(),b.checkResponsive(),b.setPosition()},50))}),a("*[draggable!=true]",b.$slideTrack).on("dragstart",function(a){a.preventDefault()}),a(window).on("load.slick.slick-"+b.instanceUid,b.setPosition),a(document).on("ready.slick.slick-"+b.instanceUid,b.setPosition)},b.prototype.initUI=function(){var a=this;a.options.arrows===!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.show(),a.$nextArrow.show()),a.options.dots===!0&&a.slideCount>a.options.slidesToShow&&a.$dots.show(),a.options.autoplay===!0&&a.autoPlay()},b.prototype.keyHandler=function(a){var b=this;37===a.keyCode&&b.options.accessibility===!0?b.changeSlide({data:{message:"previous"}}):39===a.keyCode&&b.options.accessibility===!0&&b.changeSlide({data:{message:"next"}})},b.prototype.lazyLoad=function(){function g(b){a("img[data-lazy]",b).each(function(){var b=a(this),c=a(this).attr("data-lazy");b.load(function(){b.animate({opacity:1},200)}).css({opacity:0}).attr("src",c).removeAttr("data-lazy").removeClass("slick-loading")})}var c,d,e,f,b=this;b.options.centerMode===!0?b.options.infinite===!0?(e=b.currentSlide+(b.options.slidesToShow/2+1),f=e+b.options.slidesToShow+2):(e=Math.max(0,b.currentSlide-(b.options.slidesToShow/2+1)),f=2+(b.options.slidesToShow/2+1)+b.currentSlide):(e=b.options.infinite?b.options.slidesToShow+b.currentSlide:b.currentSlide,f=e+b.options.slidesToShow,b.options.fade===!0&&(e>0&&e--,f<=b.slideCount&&f++)),c=b.$slider.find(".slick-slide").slice(e,f),g(c),b.slideCount<=b.options.slidesToShow?(d=b.$slider.find(".slick-slide"),g(d)):b.currentSlide>=b.slideCount-b.options.slidesToShow?(d=b.$slider.find(".slick-cloned").slice(0,b.options.slidesToShow),g(d)):0===b.currentSlide&&(d=b.$slider.find(".slick-cloned").slice(-1*b.options.slidesToShow),g(d))},b.prototype.loadSlider=function(){var a=this;a.setPosition(),a.$slideTrack.css({opacity:1}),a.$slider.removeClass("slick-loading"),a.initUI(),"progressive"===a.options.lazyLoad&&a.progressiveLazyLoad()},b.prototype.postSlide=function(a){var b=this;null!==b.options.onAfterChange&&b.options.onAfterChange.call(this,b,a),b.animating=!1,b.setPosition(),b.swipeLeft=null,b.options.autoplay===!0&&b.paused===!1&&b.autoPlay()},b.prototype.progressiveLazyLoad=function(){var c,d,b=this;c=a("img[data-lazy]",b.$slider).length,c>0&&(d=a("img[data-lazy]",b.$slider).first(),d.attr("src",d.attr("data-lazy")).removeClass("slick-loading").load(function(){d.removeAttr("data-lazy"),b.progressiveLazyLoad()}).error(function(){d.removeAttr("data-lazy"),b.progressiveLazyLoad()}))},b.prototype.refresh=function(){var b=this,c=b.currentSlide;b.destroy(),a.extend(b,b.initials),b.init(),b.changeSlide({data:{message:"index",index:c}},!0)},b.prototype.reinit=function(){var b=this;b.$slides=b.$slideTrack.children(b.options.slide).addClass("slick-slide"),b.slideCount=b.$slides.length,b.currentSlide>=b.slideCount&&0!==b.currentSlide&&(b.currentSlide=b.currentSlide-b.options.slidesToScroll),b.slideCount<=b.options.slidesToShow&&(b.currentSlide=0),b.setProps(),b.setupInfinite(),b.buildArrows(),b.updateArrows(),b.initArrowEvents(),b.buildDots(),b.updateDots(),b.initDotEvents(),b.options.focusOnSelect===!0&&a(b.options.slide,b.$slideTrack).on("click.slick",b.selectHandler),b.setSlideClasses(0),b.setPosition(),null!==b.options.onReInit&&b.options.onReInit.call(this,b)},b.prototype.removeSlide=function(a,b,c){var d=this;return"boolean"==typeof a?(b=a,a=b===!0?0:d.slideCount-1):a=b===!0?--a:a,d.slideCount<1||0>a||a>d.slideCount-1?!1:(d.unload(),c===!0?d.$slideTrack.children().remove():d.$slideTrack.children(this.options.slide).eq(a).remove(),d.$slides=d.$slideTrack.children(this.options.slide),d.$slideTrack.children(this.options.slide).detach(),d.$slideTrack.append(d.$slides),d.$slidesCache=d.$slides,d.reinit(),void 0)},b.prototype.setCSS=function(a){var d,e,b=this,c={};b.options.rtl===!0&&(a=-a),d="left"==b.positionProp?a+"px":"0px",e="top"==b.positionProp?a+"px":"0px",c[b.positionProp]=a,b.transformsEnabled===!1?b.$slideTrack.css(c):(c={},b.cssTransitions===!1?(c[b.animType]="translate("+d+", "+e+")",b.$slideTrack.css(c)):(c[b.animType]="translate3d("+d+", "+e+", 0px)",b.$slideTrack.css(c)))},b.prototype.setDimensions=function(){var b=this;if(b.options.vertical===!1?b.options.centerMode===!0&&b.$list.css({padding:"0px "+b.options.centerPadding}):(b.$list.height(b.$slides.first().outerHeight(!0)*b.options.slidesToShow),b.options.centerMode===!0&&b.$list.css({padding:b.options.centerPadding+" 0px"})),b.listWidth=b.$list.width(),b.listHeight=b.$list.height(),b.options.vertical===!1&&b.options.variableWidth===!1)b.slideWidth=Math.ceil(b.listWidth/b.options.slidesToShow),b.$slideTrack.width(Math.ceil(b.slideWidth*b.$slideTrack.children(".slick-slide").length));else if(b.options.variableWidth===!0){var c=0;b.slideWidth=Math.ceil(b.listWidth/b.options.slidesToShow),b.$slideTrack.children(".slick-slide").each(function(){c+=Math.ceil(a(this).outerWidth(!0))}),b.$slideTrack.width(Math.ceil(c)+1)}else b.slideWidth=Math.ceil(b.listWidth),b.$slideTrack.height(Math.ceil(b.$slides.first().outerHeight(!0)*b.$slideTrack.children(".slick-slide").length));var d=b.$slides.first().outerWidth(!0)-b.$slides.first().width();b.options.variableWidth===!1&&b.$slideTrack.children(".slick-slide").width(b.slideWidth-d)},b.prototype.setFade=function(){var c,b=this;b.$slides.each(function(d,e){c=-1*b.slideWidth*d,b.options.rtl===!0?a(e).css({position:"relative",right:c,top:0,zIndex:800,opacity:0}):a(e).css({position:"relative",left:c,top:0,zIndex:800,opacity:0})}),b.$slides.eq(b.currentSlide).css({zIndex:900,opacity:1})},b.prototype.setHeight=function(){var a=this;if(1===a.options.slidesToShow&&a.options.adaptiveHeight===!0&&a.options.vertical===!1){var b=a.$slides.eq(a.currentSlide).outerHeight(!0);a.$list.css("height",b)}},b.prototype.setPosition=function(){var a=this;a.setDimensions(),a.setHeight(),a.options.fade===!1?a.setCSS(a.getLeft(a.currentSlide)):a.setFade(),null!==a.options.onSetPosition&&a.options.onSetPosition.call(this,a)},b.prototype.setProps=function(){var a=this,b=document.body.style;a.positionProp=a.options.vertical===!0?"top":"left","top"===a.positionProp?a.$slider.addClass("slick-vertical"):a.$slider.removeClass("slick-vertical"),(void 0!==b.WebkitTransition||void 0!==b.MozTransition||void 0!==b.msTransition)&&a.options.useCSS===!0&&(a.cssTransitions=!0),void 0!==b.OTransform&&(a.animType="OTransform",a.transformType="-o-transform",a.transitionType="OTransition",void 0===b.perspectiveProperty&&void 0===b.webkitPerspective&&(a.animType=!1)),void 0!==b.MozTransform&&(a.animType="MozTransform",a.transformType="-moz-transform",a.transitionType="MozTransition",void 0===b.perspectiveProperty&&void 0===b.MozPerspective&&(a.animType=!1)),void 0!==b.webkitTransform&&(a.animType="webkitTransform",a.transformType="-webkit-transform",a.transitionType="webkitTransition",void 0===b.perspectiveProperty&&void 0===b.webkitPerspective&&(a.animType=!1)),void 0!==b.msTransform&&(a.animType="msTransform",a.transformType="-ms-transform",a.transitionType="msTransition",void 0===b.msTransform&&(a.animType=!1)),void 0!==b.transform&&a.animType!==!1&&(a.animType="transform",a.transformType="transform",a.transitionType="transition"),a.transformsEnabled=null!==a.animType&&a.animType!==!1},b.prototype.setSlideClasses=function(a){var c,d,e,f,b=this;b.$slider.find(".slick-slide").removeClass("slick-active").removeClass("slick-center"),d=b.$slider.find(".slick-slide"),b.options.centerMode===!0?(c=Math.floor(b.options.slidesToShow/2),b.options.infinite===!0&&(a>=c&&a<=b.slideCount-1-c?b.$slides.slice(a-c,a+c+1).addClass("slick-active"):(e=b.options.slidesToShow+a,d.slice(e-c+1,e+c+2).addClass("slick-active")),0===a?d.eq(d.length-1-b.options.slidesToShow).addClass("slick-center"):a===b.slideCount-1&&d.eq(b.options.slidesToShow).addClass("slick-center")),b.$slides.eq(a).addClass("slick-center")):a>=0&&a<=b.slideCount-b.options.slidesToShow?b.$slides.slice(a,a+b.options.slidesToShow).addClass("slick-active"):d.length<=b.options.slidesToShow?d.addClass("slick-active"):(f=b.slideCount%b.options.slidesToShow,e=b.options.infinite===!0?b.options.slidesToShow+a:a,b.options.slidesToShow==b.options.slidesToScroll&&b.slideCount-ab.options.slidesToShow)){for(e=b.options.centerMode===!0?b.options.slidesToShow+1:b.options.slidesToShow,c=b.slideCount;c>b.slideCount-e;c-=1)d=c-1,a(b.$slides[d]).clone(!0).attr("id","").attr("index",d-b.slideCount).prependTo(b.$slideTrack).addClass("slick-cloned");for(c=0;e>c;c+=1)d=c,a(b.$slides[d]).clone(!0).attr("id","").attr("index",d+b.slideCount).appendTo(b.$slideTrack).addClass("slick-cloned");b.$slideTrack.find(".slick-cloned").find("[id]").each(function(){a(this).attr("id","")})}},b.prototype.selectHandler=function(b){var c=this,d=parseInt(a(b.target).parents(".slick-slide").attr("index"));return d||(d=0),c.slideCount<=c.options.slidesToShow?(c.$slider.find(".slick-slide").removeClass("slick-active"),c.$slides.eq(d).addClass("slick-active"),c.options.centerMode===!0&&(c.$slider.find(".slick-slide").removeClass("slick-center"),c.$slides.eq(d).addClass("slick-center")),c.asNavFor(d),void 0):(c.slideHandler(d),void 0)},b.prototype.slideHandler=function(a,b,c){var d,e,f,g,i=null,j=this;return b=b||!1,j.animating===!0&&j.options.waitForAnimate===!0||j.options.fade===!0&&j.currentSlide===a||j.slideCount<=j.options.slidesToShow?void 0:(b===!1&&j.asNavFor(a),d=a,i=j.getLeft(d),g=j.getLeft(j.currentSlide),j.currentLeft=null===j.swipeLeft?g:j.swipeLeft,j.options.infinite===!1&&j.options.centerMode===!1&&(0>a||a>j.getDotCount()*j.options.slidesToScroll)?(j.options.fade===!1&&(d=j.currentSlide,c!==!0?j.animateSlide(g,function(){j.postSlide(d)}):j.postSlide(d)),void 0):j.options.infinite===!1&&j.options.centerMode===!0&&(0>a||a>j.slideCount-j.options.slidesToScroll)?(j.options.fade===!1&&(d=j.currentSlide,c!==!0?j.animateSlide(g,function(){j.postSlide(d)}):j.postSlide(d)),void 0):(j.options.autoplay===!0&&clearInterval(j.autoPlayTimer),e=0>d?0!==j.slideCount%j.options.slidesToScroll?j.slideCount-j.slideCount%j.options.slidesToScroll:j.slideCount+d:d>=j.slideCount?0!==j.slideCount%j.options.slidesToScroll?0:d-j.slideCount:d,j.animating=!0,null!==j.options.onBeforeChange&&a!==j.currentSlide&&j.options.onBeforeChange.call(this,j,j.currentSlide,e),f=j.currentSlide,j.currentSlide=e,j.setSlideClasses(j.currentSlide),j.updateDots(),j.updateArrows(),j.options.fade===!0?(c!==!0?j.fadeSlide(f,e,function(){j.postSlide(e)}):j.postSlide(e),void 0):(c!==!0?j.animateSlide(i,function(){j.postSlide(e)}):j.postSlide(e),void 0)))},b.prototype.startLoad=function(){var a=this;a.options.arrows===!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.hide(),a.$nextArrow.hide()),a.options.dots===!0&&a.slideCount>a.options.slidesToShow&&a.$dots.hide(),a.$slider.addClass("slick-loading")},b.prototype.swipeDirection=function(){var a,b,c,d,e=this;return a=e.touchObject.startX-e.touchObject.curX,b=e.touchObject.startY-e.touchObject.curY,c=Math.atan2(b,a),d=Math.round(180*c/Math.PI),0>d&&(d=360-Math.abs(d)),45>=d&&d>=0?e.options.rtl===!1?"left":"right":360>=d&&d>=315?e.options.rtl===!1?"left":"right":d>=135&&225>=d?e.options.rtl===!1?"right":"left":"vertical"},b.prototype.swipeEnd=function(){var b=this;if(b.dragging=!1,b.shouldClick=b.touchObject.swipeLength>10?!1:!0,void 0===b.touchObject.curX)return!1;if(b.touchObject.swipeLength>=b.touchObject.minSwipe)switch(b.swipeDirection()){case"left":b.slideHandler(b.currentSlide+b.getSlideCount()),b.currentDirection=0,b.touchObject={};break;case"right":b.slideHandler(b.currentSlide-b.getSlideCount()),b.currentDirection=1,b.touchObject={}}else b.touchObject.startX!==b.touchObject.curX&&(b.slideHandler(b.currentSlide),b.touchObject={})},b.prototype.swipeHandler=function(a){var b=this;if(!(b.options.swipe===!1||"ontouchend"in document&&b.options.swipe===!1||b.options.draggable===!1&&-1!==a.type.indexOf("mouse")))switch(b.touchObject.fingerCount=a.originalEvent&&void 0!==a.originalEvent.touches?a.originalEvent.touches.length:1,b.touchObject.minSwipe=b.listWidth/b.options.touchThreshold,a.data.action){case"start":b.swipeStart(a);break;case"move":b.swipeMove(a);break;case"end":b.swipeEnd(a)}},b.prototype.swipeMove=function(a){var c,d,e,f,b=this;return f=void 0!==a.originalEvent?a.originalEvent.touches:null,!b.dragging||f&&1!==f.length?!1:(c=b.getLeft(b.currentSlide),b.touchObject.curX=void 0!==f?f[0].pageX:a.clientX,b.touchObject.curY=void 0!==f?f[0].pageY:a.clientY,b.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(b.touchObject.curX-b.touchObject.startX,2))),d=b.swipeDirection(),"vertical"!==d?(void 0!==a.originalEvent&&b.touchObject.swipeLength>4&&a.preventDefault(),e=(b.options.rtl===!1?1:-1)*(b.touchObject.curX>b.touchObject.startX?1:-1),b.swipeLeft=b.options.vertical===!1?c+b.touchObject.swipeLength*e:c+b.touchObject.swipeLength*(b.$list.height()/b.listWidth)*e,b.options.fade===!0||b.options.touchMove===!1?!1:b.animating===!0?(b.swipeLeft=null,!1):(b.setCSS(b.swipeLeft),void 0)):void 0)},b.prototype.swipeStart=function(a){var c,b=this;return 1!==b.touchObject.fingerCount||b.slideCount<=b.options.slidesToShow?(b.touchObject={},!1):(void 0!==a.originalEvent&&void 0!==a.originalEvent.touches&&(c=a.originalEvent.touches[0]),b.touchObject.startX=b.touchObject.curX=void 0!==c?c.pageX:a.clientX,b.touchObject.startY=b.touchObject.curY=void 0!==c?c.pageY:a.clientY,b.dragging=!0,void 0)},b.prototype.unfilterSlides=function(){var a=this;null!==a.$slidesCache&&(a.unload(),a.$slideTrack.children(this.options.slide).detach(),a.$slidesCache.appendTo(a.$slideTrack),a.reinit())},b.prototype.unload=function(){var b=this;a(".slick-cloned",b.$slider).remove(),b.$dots&&b.$dots.remove(),b.$prevArrow&&"object"!=typeof b.options.prevArrow&&b.$prevArrow.remove(),b.$nextArrow&&"object"!=typeof b.options.nextArrow&&b.$nextArrow.remove(),b.$slides.removeClass("slick-slide slick-active slick-visible").css("width","")},b.prototype.updateArrows=function(){var b,a=this;b=Math.floor(a.options.slidesToShow/2),a.options.arrows===!0&&a.options.infinite!==!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.removeClass("slick-disabled"),a.$nextArrow.removeClass("slick-disabled"),0===a.currentSlide?(a.$prevArrow.addClass("slick-disabled"),a.$nextArrow.removeClass("slick-disabled")):a.currentSlide>=a.slideCount-a.options.slidesToShow&&a.options.centerMode===!1?(a.$nextArrow.addClass("slick-disabled"),a.$prevArrow.removeClass("slick-disabled")):a.currentSlide>a.slideCount-a.options.slidesToShow+b&&a.options.centerMode===!0&&(a.$nextArrow.addClass("slick-disabled"),a.$prevArrow.removeClass("slick-disabled")))},b.prototype.updateDots=function(){var a=this;null!==a.$dots&&(a.$dots.find("li").removeClass("slick-active"),a.$dots.find("li").eq(Math.floor(a.currentSlide/a.options.slidesToScroll)).addClass("slick-active"))},a.fn.slick=function(a){var c=this;return c.each(function(c,d){d.slick=new b(d,a)})},a.fn.slickAdd=function(a,b,c){var d=this;return d.each(function(d,e){e.slick.addSlide(a,b,c)})},a.fn.slickCurrentSlide=function(){var a=this;return a.get(0).slick.getCurrent()},a.fn.slickFilter=function(a){var b=this;return b.each(function(b,c){c.slick.filterSlides(a)})},a.fn.slickGoTo=function(a,b){var c=this;return c.each(function(c,d){d.slick.changeSlide({data:{message:"index",index:parseInt(a)}},b)})},a.fn.slickNext=function(){var a=this;return a.each(function(a,b){b.slick.changeSlide({data:{message:"next"}})})},a.fn.slickPause=function(){var a=this;return a.each(function(a,b){b.slick.autoPlayClear(),b.slick.paused=!0})},a.fn.slickPlay=function(){var a=this;return a.each(function(a,b){b.slick.paused=!1,b.slick.autoPlay()})},a.fn.slickPrev=function(){var a=this;return a.each(function(a,b){b.slick.changeSlide({data:{message:"previous"}})})},a.fn.slickRemove=function(a,b){var c=this;return c.each(function(c,d){d.slick.removeSlide(a,b)})},a.fn.slickRemoveAll=function(){var a=this;return a.each(function(a,b){b.slick.removeSlide(null,null,!0)})},a.fn.slickGetOption=function(a){var b=this;return b.get(0).slick.options[a]},a.fn.slickSetOption=function(a,b,c){var d=this;return d.each(function(d,e){e.slick.options[a]=b,c===!0&&(e.slick.unload(),e.slick.reinit())})},a.fn.slickUnfilter=function(){var a=this;return a.each(function(a,b){b.slick.unfilterSlides()})},a.fn.unslick=function(){var a=this;return a.each(function(a,b){b.slick&&b.slick.destroy()})},a.fn.getSlick=function(){var a=null,b=this;return b.each(function(b,c){a=c.slick}),a}}); \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-1.5.0.css b/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-1.5.0.css new file mode 100644 index 00000000000..59119f4e6b2 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-1.5.0.css @@ -0,0 +1,116 @@ +/* Slider */ +.slick-slider +{ + position: relative; + + display: block; + + -moz-box-sizing: border-box; + box-sizing: border-box; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + -webkit-touch-callout: none; + -khtml-user-select: none; + -ms-touch-action: pan-y; + touch-action: pan-y; + -webkit-tap-highlight-color: transparent; +} + +.slick-list +{ + position: relative; + + display: block; + overflow: hidden; + + margin: 0; + padding: 0; +} +.slick-list:focus +{ + outline: none; +} +.slick-list.dragging +{ + cursor: pointer; + cursor: hand; +} + +.slick-slider .slick-track, +.slick-slider .slick-list +{ + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); + -o-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} + +.slick-track +{ + position: relative; + top: 0; + left: 0; + + display: block; +} +.slick-track:before, +.slick-track:after +{ + display: table; + + content: ''; +} +.slick-track:after +{ + clear: both; +} +.slick-loading .slick-track +{ + visibility: hidden; +} + +.slick-slide +{ + display: none; + float: left; + + height: 100%; + min-height: 1px; +} +[dir='rtl'] .slick-slide +{ + float: right; +} +.slick-slide img +{ + display: block; +} +.slick-slide.slick-loading img +{ + display: none; +} +.slick-slide.dragging img +{ + pointer-events: none; +} +.slick-initialized .slick-slide +{ + display: block; +} +.slick-loading .slick-slide +{ + visibility: hidden; +} +.slick-vertical .slick-slide +{ + display: block; + + height: auto; + + border: 1px solid transparent; +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-1.5.0.min.js b/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-1.5.0.min.js new file mode 100644 index 00000000000..475450b874c --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-1.5.0.min.js @@ -0,0 +1,20 @@ +/* + _ _ _ _ + ___| (_) ___| | __ (_)___ +/ __| | |/ __| |/ / | / __| +\__ \ | | (__| < _ | \__ \ +|___/_|_|\___|_|\_(_)/ |___/ + |__/ + + Version: 1.5.0 + Author: Ken Wheeler + Website: http://kenwheeler.github.io + Docs: http://kenwheeler.github.io/slick + Repo: http://github.com/kenwheeler/slick + Issues: http://github.com/kenwheeler/slick/issues + + */ +/* global window, document, define, jQuery, setInterval, clearInterval */ + +!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):"undefined"!=typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){"use strict";var b=window.Slick||{};b=function(){function c(c,d){var f,g,h,e=this;if(e.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:a(c),appendDots:a(c),arrows:!0,asNavFor:null,prevArrow:'',nextArrow:'',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(a,b){return'"},dots:!1,dotsClass:"slick-dots",draggable:!0,easing:"linear",edgeFriction:.35,fade:!1,focusOnSelect:!1,infinite:!0,initialSlide:0,lazyLoad:"ondemand",mobileFirst:!1,pauseOnHover:!0,pauseOnDotsHover:!1,respondTo:"window",responsive:null,rows:1,rtl:!1,slide:"",slidesPerRow:1,slidesToShow:1,slidesToScroll:1,speed:500,swipe:!0,swipeToSlide:!1,touchMove:!0,touchThreshold:5,useCSS:!0,variableWidth:!1,vertical:!1,verticalSwiping:!1,waitForAnimate:!0},e.initials={animating:!1,dragging:!1,autoPlayTimer:null,currentDirection:0,currentLeft:null,currentSlide:0,direction:1,$dots:null,listWidth:null,listHeight:null,loadIndex:0,$nextArrow:null,$prevArrow:null,slideCount:null,slideWidth:null,$slideTrack:null,$slides:null,sliding:!1,slideOffset:0,swipeLeft:null,$list:null,touchObject:{},transformsEnabled:!1},a.extend(e,e.initials),e.activeBreakpoint=null,e.animType=null,e.animProp=null,e.breakpoints=[],e.breakpointSettings=[],e.cssTransitions=!1,e.hidden="hidden",e.paused=!1,e.positionProp=null,e.respondTo=null,e.rowCount=1,e.shouldClick=!0,e.$slider=a(c),e.$slidesCache=null,e.transformType=null,e.transitionType=null,e.visibilityChange="visibilitychange",e.windowWidth=0,e.windowTimer=null,f=a(c).data("slick")||{},e.options=a.extend({},e.defaults,f,d),e.currentSlide=e.options.initialSlide,e.originalSettings=e.options,g=e.options.responsive||null,g&&g.length>-1){e.respondTo=e.options.respondTo||"window";for(h in g)g.hasOwnProperty(h)&&(e.breakpoints.push(g[h].breakpoint),e.breakpointSettings[g[h].breakpoint]=g[h].settings);e.breakpoints.sort(function(a,b){return e.options.mobileFirst===!0?a-b:b-a})}"undefined"!=typeof document.mozHidden?(e.hidden="mozHidden",e.visibilityChange="mozvisibilitychange"):"undefined"!=typeof document.msHidden?(e.hidden="msHidden",e.visibilityChange="msvisibilitychange"):"undefined"!=typeof document.webkitHidden&&(e.hidden="webkitHidden",e.visibilityChange="webkitvisibilitychange"),e.autoPlay=a.proxy(e.autoPlay,e),e.autoPlayClear=a.proxy(e.autoPlayClear,e),e.changeSlide=a.proxy(e.changeSlide,e),e.clickHandler=a.proxy(e.clickHandler,e),e.selectHandler=a.proxy(e.selectHandler,e),e.setPosition=a.proxy(e.setPosition,e),e.swipeHandler=a.proxy(e.swipeHandler,e),e.dragHandler=a.proxy(e.dragHandler,e),e.keyHandler=a.proxy(e.keyHandler,e),e.autoPlayIterator=a.proxy(e.autoPlayIterator,e),e.instanceUid=b++,e.htmlExpr=/^(?:\s*(<[\w\W]+>)[^>]*)$/,e.init(),e.checkResponsive(!0)}var b=0;return c}(),b.prototype.addSlide=b.prototype.slickAdd=function(b,c,d){var e=this;if("boolean"==typeof c)d=c,c=null;else if(0>c||c>=e.slideCount)return!1;e.unload(),"number"==typeof c?0===c&&0===e.$slides.length?a(b).appendTo(e.$slideTrack):d?a(b).insertBefore(e.$slides.eq(c)):a(b).insertAfter(e.$slides.eq(c)):d===!0?a(b).prependTo(e.$slideTrack):a(b).appendTo(e.$slideTrack),e.$slides=e.$slideTrack.children(this.options.slide),e.$slideTrack.children(this.options.slide).detach(),e.$slideTrack.append(e.$slides),e.$slides.each(function(b,c){a(c).attr("data-slick-index",b)}),e.$slidesCache=e.$slides,e.reinit()},b.prototype.animateHeight=function(){var a=this;if(1===a.options.slidesToShow&&a.options.adaptiveHeight===!0&&a.options.vertical===!1){var b=a.$slides.eq(a.currentSlide).outerHeight(!0);a.$list.animate({height:b},a.options.speed)}},b.prototype.animateSlide=function(b,c){var d={},e=this;e.animateHeight(),e.options.rtl===!0&&e.options.vertical===!1&&(b=-b),e.transformsEnabled===!1?e.options.vertical===!1?e.$slideTrack.animate({left:b},e.options.speed,e.options.easing,c):e.$slideTrack.animate({top:b},e.options.speed,e.options.easing,c):e.cssTransitions===!1?(e.options.rtl===!0&&(e.currentLeft=-e.currentLeft),a({animStart:e.currentLeft}).animate({animStart:b},{duration:e.options.speed,easing:e.options.easing,step:function(a){a=Math.ceil(a),e.options.vertical===!1?(d[e.animType]="translate("+a+"px, 0px)",e.$slideTrack.css(d)):(d[e.animType]="translate(0px,"+a+"px)",e.$slideTrack.css(d))},complete:function(){c&&c.call()}})):(e.applyTransition(),b=Math.ceil(b),d[e.animType]=e.options.vertical===!1?"translate3d("+b+"px, 0px, 0px)":"translate3d(0px,"+b+"px, 0px)",e.$slideTrack.css(d),c&&setTimeout(function(){e.disableTransition(),c.call()},e.options.speed))},b.prototype.asNavFor=function(b){var c=this,d=null!==c.options.asNavFor?a(c.options.asNavFor).slick("getSlick"):null;null!==d&&d.slideHandler(b,!0)},b.prototype.applyTransition=function(a){var b=this,c={};c[b.transitionType]=b.options.fade===!1?b.transformType+" "+b.options.speed+"ms "+b.options.cssEase:"opacity "+b.options.speed+"ms "+b.options.cssEase,b.options.fade===!1?b.$slideTrack.css(c):b.$slides.eq(a).css(c)},b.prototype.autoPlay=function(){var a=this;a.autoPlayTimer&&clearInterval(a.autoPlayTimer),a.slideCount>a.options.slidesToShow&&a.paused!==!0&&(a.autoPlayTimer=setInterval(a.autoPlayIterator,a.options.autoplaySpeed))},b.prototype.autoPlayClear=function(){var a=this;a.autoPlayTimer&&clearInterval(a.autoPlayTimer)},b.prototype.autoPlayIterator=function(){var a=this;a.options.infinite===!1?1===a.direction?(a.currentSlide+1===a.slideCount-1&&(a.direction=0),a.slideHandler(a.currentSlide+a.options.slidesToScroll)):(0===a.currentSlide-1&&(a.direction=1),a.slideHandler(a.currentSlide-a.options.slidesToScroll)):a.slideHandler(a.currentSlide+a.options.slidesToScroll)},b.prototype.buildArrows=function(){var b=this;b.options.arrows===!0&&b.slideCount>b.options.slidesToShow&&(b.$prevArrow=a(b.options.prevArrow),b.$nextArrow=a(b.options.nextArrow),b.htmlExpr.test(b.options.prevArrow)&&b.$prevArrow.appendTo(b.options.appendArrows),b.htmlExpr.test(b.options.nextArrow)&&b.$nextArrow.appendTo(b.options.appendArrows),b.options.infinite!==!0&&b.$prevArrow.addClass("slick-disabled"))},b.prototype.buildDots=function(){var c,d,b=this;if(b.options.dots===!0&&b.slideCount>b.options.slidesToShow){for(d='
    ',c=0;c<=b.getDotCount();c+=1)d+="
  • "+b.options.customPaging.call(this,b,c)+"
  • ";d+="
",b.$dots=a(d).appendTo(b.options.appendDots),b.$dots.find("li").first().addClass("slick-active").attr("aria-hidden","false")}},b.prototype.buildOut=function(){var b=this;b.$slides=b.$slider.children(":not(.slick-cloned)").addClass("slick-slide"),b.slideCount=b.$slides.length,b.$slides.each(function(b,c){a(c).attr("data-slick-index",b)}),b.$slidesCache=b.$slides,b.$slider.addClass("slick-slider"),b.$slideTrack=0===b.slideCount?a('
').appendTo(b.$slider):b.$slides.wrapAll('
').parent(),b.$list=b.$slideTrack.wrap('
').parent(),b.$slideTrack.css("opacity",0),(b.options.centerMode===!0||b.options.swipeToSlide===!0)&&(b.options.slidesToScroll=1),a("img[data-lazy]",b.$slider).not("[src]").addClass("slick-loading"),b.setupInfinite(),b.buildArrows(),b.buildDots(),b.updateDots(),b.options.accessibility===!0&&b.$list.prop("tabIndex",0),b.setSlideClasses("number"==typeof this.currentSlide?this.currentSlide:0),b.options.draggable===!0&&b.$list.addClass("draggable")},b.prototype.buildRows=function(){var b,c,d,e,f,g,h,a=this;if(e=document.createDocumentFragment(),g=a.$slider.children(),a.options.rows>1){for(h=a.options.slidesPerRow*a.options.rows,f=Math.ceil(g.length/h),b=0;f>b;b++){var i=document.createElement("div");for(c=0;c-1&&null!==c.originalSettings.responsive){e=null;for(d in c.breakpoints)c.breakpoints.hasOwnProperty(d)&&(c.originalSettings.mobileFirst===!1?fc.breakpoints[d]&&(e=c.breakpoints[d]));null!==e?null!==c.activeBreakpoint?e!==c.activeBreakpoint&&(c.activeBreakpoint=e,"unslick"===c.breakpointSettings[e]?c.unslick():(c.options=a.extend({},c.originalSettings,c.breakpointSettings[e]),b===!0&&(c.currentSlide=c.options.initialSlide),c.refresh())):(c.activeBreakpoint=e,"unslick"===c.breakpointSettings[e]?c.unslick():(c.options=a.extend({},c.originalSettings,c.breakpointSettings[e]),b===!0&&(c.currentSlide=c.options.initialSlide),c.refresh())):null!==c.activeBreakpoint&&(c.activeBreakpoint=null,c.options=c.originalSettings,b===!0&&(c.currentSlide=c.options.initialSlide),c.refresh())}},b.prototype.changeSlide=function(b,c){var f,g,h,d=this,e=a(b.target);switch(e.is("a")&&b.preventDefault(),h=0!==d.slideCount%d.options.slidesToScroll,f=h?0:(d.slideCount-d.currentSlide)%d.options.slidesToScroll,b.data.message){case"previous":g=0===f?d.options.slidesToScroll:d.options.slidesToShow-f,d.slideCount>d.options.slidesToShow&&d.slideHandler(d.currentSlide-g,!1,c);break;case"next":g=0===f?d.options.slidesToScroll:f,d.slideCount>d.options.slidesToShow&&d.slideHandler(d.currentSlide+g,!1,c);break;case"index":var i=0===b.data.index?0:b.data.index||a(b.target).parent().index()*d.options.slidesToScroll;d.slideHandler(d.checkNavigable(i),!1,c);break;default:return}},b.prototype.checkNavigable=function(a){var c,d,b=this;if(c=b.getNavigableIndexes(),d=0,a>c[c.length-1])a=c[c.length-1];else for(var e in c){if(ab.options.slidesToShow&&a("li",b.$dots).off("click.slick",b.changeSlide),b.options.dots===!0&&b.options.pauseOnDotsHover===!0&&b.options.autoplay===!0&&a("li",b.$dots).off("mouseenter.slick",b.setPaused.bind(b,!0)).off("mouseleave.slick",b.setPaused.bind(b,!1)),b.options.arrows===!0&&b.slideCount>b.options.slidesToShow&&(b.$prevArrow&&b.$prevArrow.off("click.slick",b.changeSlide),b.$nextArrow&&b.$nextArrow.off("click.slick",b.changeSlide)),b.$list.off("touchstart.slick mousedown.slick",b.swipeHandler),b.$list.off("touchmove.slick mousemove.slick",b.swipeHandler),b.$list.off("touchend.slick mouseup.slick",b.swipeHandler),b.$list.off("touchcancel.slick mouseleave.slick",b.swipeHandler),b.$list.off("click.slick",b.clickHandler),b.options.autoplay===!0&&a(document).off(b.visibilityChange,b.visibility),b.$list.off("mouseenter.slick",b.setPaused.bind(b,!0)),b.$list.off("mouseleave.slick",b.setPaused.bind(b,!1)),b.options.accessibility===!0&&b.$list.off("keydown.slick",b.keyHandler),b.options.focusOnSelect===!0&&a(b.$slideTrack).children().off("click.slick",b.selectHandler),a(window).off("orientationchange.slick.slick-"+b.instanceUid,b.orientationChange),a(window).off("resize.slick.slick-"+b.instanceUid,b.resize),a("[draggable!=true]",b.$slideTrack).off("dragstart",b.preventDefault),a(window).off("load.slick.slick-"+b.instanceUid,b.setPosition),a(document).off("ready.slick.slick-"+b.instanceUid,b.setPosition)},b.prototype.cleanUpRows=function(){var b,a=this;a.options.rows>1&&(b=a.$slides.children().children(),b.removeAttr("style"),a.$slider.html(b))},b.prototype.clickHandler=function(a){var b=this;b.shouldClick===!1&&(a.stopImmediatePropagation(),a.stopPropagation(),a.preventDefault())},b.prototype.destroy=function(){var b=this;b.autoPlayClear(),b.touchObject={},b.cleanUpEvents(),a(".slick-cloned",b.$slider).remove(),b.$dots&&b.$dots.remove(),b.$prevArrow&&"object"!=typeof b.options.prevArrow&&b.$prevArrow.remove(),b.$nextArrow&&"object"!=typeof b.options.nextArrow&&b.$nextArrow.remove(),b.$slides&&(b.$slides.removeClass("slick-slide slick-active slick-center slick-visible").attr("aria-hidden","true").removeAttr("data-slick-index").css({position:"",left:"",top:"",zIndex:"",opacity:"",width:""}),b.$slider.html(b.$slides)),b.cleanUpRows(),b.$slider.removeClass("slick-slider"),b.$slider.removeClass("slick-initialized")},b.prototype.disableTransition=function(a){var b=this,c={};c[b.transitionType]="",b.options.fade===!1?b.$slideTrack.css(c):b.$slides.eq(a).css(c)},b.prototype.fadeSlide=function(a,b){var c=this;c.cssTransitions===!1?(c.$slides.eq(a).css({zIndex:1e3}),c.$slides.eq(a).animate({opacity:1},c.options.speed,c.options.easing,b)):(c.applyTransition(a),c.$slides.eq(a).css({opacity:1,zIndex:1e3}),b&&setTimeout(function(){c.disableTransition(a),b.call()},c.options.speed))},b.prototype.filterSlides=b.prototype.slickFilter=function(a){var b=this;null!==a&&(b.unload(),b.$slideTrack.children(this.options.slide).detach(),b.$slidesCache.filter(a).appendTo(b.$slideTrack),b.reinit())},b.prototype.getCurrent=b.prototype.slickCurrentSlide=function(){var a=this;return a.currentSlide},b.prototype.getDotCount=function(){var a=this,b=0,c=0,d=0;if(a.options.infinite===!0)d=Math.ceil(a.slideCount/a.options.slidesToScroll);else if(a.options.centerMode===!0)d=a.slideCount;else for(;bb.options.slidesToShow&&(b.slideOffset=-1*b.slideWidth*b.options.slidesToShow,e=-1*d*b.options.slidesToShow),0!==b.slideCount%b.options.slidesToScroll&&a+b.options.slidesToScroll>b.slideCount&&b.slideCount>b.options.slidesToShow&&(a>b.slideCount?(b.slideOffset=-1*(b.options.slidesToShow-(a-b.slideCount))*b.slideWidth,e=-1*(b.options.slidesToShow-(a-b.slideCount))*d):(b.slideOffset=-1*b.slideCount%b.options.slidesToScroll*b.slideWidth,e=-1*b.slideCount%b.options.slidesToScroll*d))):a+b.options.slidesToShow>b.slideCount&&(b.slideOffset=(a+b.options.slidesToShow-b.slideCount)*b.slideWidth,e=(a+b.options.slidesToShow-b.slideCount)*d),b.slideCount<=b.options.slidesToShow&&(b.slideOffset=0,e=0),b.options.centerMode===!0&&b.options.infinite===!0?b.slideOffset+=b.slideWidth*Math.floor(b.options.slidesToShow/2)-b.slideWidth:b.options.centerMode===!0&&(b.slideOffset=0,b.slideOffset+=b.slideWidth*Math.floor(b.options.slidesToShow/2)),c=b.options.vertical===!1?-1*a*b.slideWidth+b.slideOffset:-1*a*d+e,b.options.variableWidth===!0&&(f=b.slideCount<=b.options.slidesToShow||b.options.infinite===!1?b.$slideTrack.children(".slick-slide").eq(a):b.$slideTrack.children(".slick-slide").eq(a+b.options.slidesToShow),c=f[0]?-1*f[0].offsetLeft:0,b.options.centerMode===!0&&(f=b.options.infinite===!1?b.$slideTrack.children(".slick-slide").eq(a):b.$slideTrack.children(".slick-slide").eq(a+b.options.slidesToShow+1),c=f[0]?-1*f[0].offsetLeft:0,c+=(b.$list.width()-f.outerWidth())/2)),c},b.prototype.getOption=b.prototype.slickGetOption=function(a){var b=this;return b.options[a]},b.prototype.getNavigableIndexes=function(){var e,a=this,b=0,c=0,d=[];for(a.options.infinite===!1?(e=a.slideCount-a.options.slidesToShow+1,a.options.centerMode===!0&&(e=a.slideCount)):(b=-1*a.options.slidesToScroll,c=-1*a.options.slidesToScroll,e=2*a.slideCount);e>b;)d.push(b),b=c+a.options.slidesToScroll,c+=a.options.slidesToScroll<=a.options.slidesToShow?a.options.slidesToScroll:a.options.slidesToShow;return d},b.prototype.getSlick=function(){return this},b.prototype.getSlideCount=function(){var c,d,e,b=this;return e=b.options.centerMode===!0?b.slideWidth*Math.floor(b.options.slidesToShow/2):0,b.options.swipeToSlide===!0?(b.$slideTrack.find(".slick-slide").each(function(c,f){return f.offsetLeft-e+a(f).outerWidth()/2>-1*b.swipeLeft?(d=f,!1):void 0}),c=Math.abs(a(d).attr("data-slick-index")-b.currentSlide)||1):b.options.slidesToScroll},b.prototype.goTo=b.prototype.slickGoTo=function(a,b){var c=this;c.changeSlide({data:{message:"index",index:parseInt(a)}},b)},b.prototype.init=function(){var b=this;a(b.$slider).hasClass("slick-initialized")||(a(b.$slider).addClass("slick-initialized"),b.buildRows(),b.buildOut(),b.setProps(),b.startLoad(),b.loadSlider(),b.initializeEvents(),b.updateArrows(),b.updateDots()),b.$slider.trigger("init",[b])},b.prototype.initArrowEvents=function(){var a=this;a.options.arrows===!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.on("click.slick",{message:"previous"},a.changeSlide),a.$nextArrow.on("click.slick",{message:"next"},a.changeSlide))},b.prototype.initDotEvents=function(){var b=this;b.options.dots===!0&&b.slideCount>b.options.slidesToShow&&a("li",b.$dots).on("click.slick",{message:"index"},b.changeSlide),b.options.dots===!0&&b.options.pauseOnDotsHover===!0&&b.options.autoplay===!0&&a("li",b.$dots).on("mouseenter.slick",b.setPaused.bind(b,!0)).on("mouseleave.slick",b.setPaused.bind(b,!1))},b.prototype.initializeEvents=function(){var b=this;b.initArrowEvents(),b.initDotEvents(),b.$list.on("touchstart.slick mousedown.slick",{action:"start"},b.swipeHandler),b.$list.on("touchmove.slick mousemove.slick",{action:"move"},b.swipeHandler),b.$list.on("touchend.slick mouseup.slick",{action:"end"},b.swipeHandler),b.$list.on("touchcancel.slick mouseleave.slick",{action:"end"},b.swipeHandler),b.$list.on("click.slick",b.clickHandler),b.options.autoplay===!0&&a(document).on(b.visibilityChange,b.visibility.bind(b)),b.$list.on("mouseenter.slick",b.setPaused.bind(b,!0)),b.$list.on("mouseleave.slick",b.setPaused.bind(b,!1)),b.options.accessibility===!0&&b.$list.on("keydown.slick",b.keyHandler),b.options.focusOnSelect===!0&&a(b.$slideTrack).children().on("click.slick",b.selectHandler),a(window).on("orientationchange.slick.slick-"+b.instanceUid,b.orientationChange.bind(b)),a(window).on("resize.slick.slick-"+b.instanceUid,b.resize.bind(b)),a("[draggable!=true]",b.$slideTrack).on("dragstart",b.preventDefault),a(window).on("load.slick.slick-"+b.instanceUid,b.setPosition),a(document).on("ready.slick.slick-"+b.instanceUid,b.setPosition)},b.prototype.initUI=function(){var a=this;a.options.arrows===!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.show(),a.$nextArrow.show()),a.options.dots===!0&&a.slideCount>a.options.slidesToShow&&a.$dots.show(),a.options.autoplay===!0&&a.autoPlay()},b.prototype.keyHandler=function(a){var b=this;37===a.keyCode&&b.options.accessibility===!0?b.changeSlide({data:{message:"previous"}}):39===a.keyCode&&b.options.accessibility===!0&&b.changeSlide({data:{message:"next"}})},b.prototype.lazyLoad=function(){function g(b){a("img[data-lazy]",b).each(function(){var b=a(this),c=a(this).attr("data-lazy"),d=document.createElement("img");d.onload=function(){b.animate({opacity:1},200)},d.src=c,b.css({opacity:0}).attr("src",c).removeAttr("data-lazy").removeClass("slick-loading")})}var c,d,e,f,b=this;b.options.centerMode===!0?b.options.infinite===!0?(e=b.currentSlide+(b.options.slidesToShow/2+1),f=e+b.options.slidesToShow+2):(e=Math.max(0,b.currentSlide-(b.options.slidesToShow/2+1)),f=2+(b.options.slidesToShow/2+1)+b.currentSlide):(e=b.options.infinite?b.options.slidesToShow+b.currentSlide:b.currentSlide,f=e+b.options.slidesToShow,b.options.fade===!0&&(e>0&&e--,f<=b.slideCount&&f++)),c=b.$slider.find(".slick-slide").slice(e,f),g(c),b.slideCount<=b.options.slidesToShow?(d=b.$slider.find(".slick-slide"),g(d)):b.currentSlide>=b.slideCount-b.options.slidesToShow?(d=b.$slider.find(".slick-cloned").slice(0,b.options.slidesToShow),g(d)):0===b.currentSlide&&(d=b.$slider.find(".slick-cloned").slice(-1*b.options.slidesToShow),g(d))},b.prototype.loadSlider=function(){var a=this;a.setPosition(),a.$slideTrack.css({opacity:1}),a.$slider.removeClass("slick-loading"),a.initUI(),"progressive"===a.options.lazyLoad&&a.progressiveLazyLoad()},b.prototype.next=b.prototype.slickNext=function(){var a=this;a.changeSlide({data:{message:"next"}})},b.prototype.orientationChange=function(){var a=this;a.checkResponsive(),a.setPosition()},b.prototype.pause=b.prototype.slickPause=function(){var a=this;a.autoPlayClear(),a.paused=!0},b.prototype.play=b.prototype.slickPlay=function(){var a=this;a.paused=!1,a.autoPlay()},b.prototype.postSlide=function(a){var b=this;b.$slider.trigger("afterChange",[b,a]),b.animating=!1,b.setPosition(),b.swipeLeft=null,b.options.autoplay===!0&&b.paused===!1&&b.autoPlay()},b.prototype.prev=b.prototype.slickPrev=function(){var a=this;a.changeSlide({data:{message:"previous"}})},b.prototype.preventDefault=function(a){a.preventDefault()},b.prototype.progressiveLazyLoad=function(){var c,d,b=this;c=a("img[data-lazy]",b.$slider).length,c>0&&(d=a("img[data-lazy]",b.$slider).first(),d.attr("src",d.attr("data-lazy")).removeClass("slick-loading").load(function(){d.removeAttr("data-lazy"),b.progressiveLazyLoad(),b.options.adaptiveHeight===!0&&b.setPosition()}).error(function(){d.removeAttr("data-lazy"),b.progressiveLazyLoad()}))},b.prototype.refresh=function(){var b=this,c=b.currentSlide;b.destroy(),a.extend(b,b.initials),b.init(),b.changeSlide({data:{message:"index",index:c}},!1)},b.prototype.reinit=function(){var b=this;b.$slides=b.$slideTrack.children(b.options.slide).addClass("slick-slide"),b.slideCount=b.$slides.length,b.currentSlide>=b.slideCount&&0!==b.currentSlide&&(b.currentSlide=b.currentSlide-b.options.slidesToScroll),b.slideCount<=b.options.slidesToShow&&(b.currentSlide=0),b.setProps(),b.setupInfinite(),b.buildArrows(),b.updateArrows(),b.initArrowEvents(),b.buildDots(),b.updateDots(),b.initDotEvents(),b.options.focusOnSelect===!0&&a(b.$slideTrack).children().on("click.slick",b.selectHandler),b.setSlideClasses(0),b.setPosition(),b.$slider.trigger("reInit",[b])},b.prototype.resize=function(){var b=this;a(window).width()!==b.windowWidth&&(clearTimeout(b.windowDelay),b.windowDelay=window.setTimeout(function(){b.windowWidth=a(window).width(),b.checkResponsive(),b.setPosition()},50))},b.prototype.removeSlide=b.prototype.slickRemove=function(a,b,c){var d=this;return"boolean"==typeof a?(b=a,a=b===!0?0:d.slideCount-1):a=b===!0?--a:a,d.slideCount<1||0>a||a>d.slideCount-1?!1:(d.unload(),c===!0?d.$slideTrack.children().remove():d.$slideTrack.children(this.options.slide).eq(a).remove(),d.$slides=d.$slideTrack.children(this.options.slide),d.$slideTrack.children(this.options.slide).detach(),d.$slideTrack.append(d.$slides),d.$slidesCache=d.$slides,d.reinit(),void 0)},b.prototype.setCSS=function(a){var d,e,b=this,c={};b.options.rtl===!0&&(a=-a),d="left"==b.positionProp?Math.ceil(a)+"px":"0px",e="top"==b.positionProp?Math.ceil(a)+"px":"0px",c[b.positionProp]=a,b.transformsEnabled===!1?b.$slideTrack.css(c):(c={},b.cssTransitions===!1?(c[b.animType]="translate("+d+", "+e+")",b.$slideTrack.css(c)):(c[b.animType]="translate3d("+d+", "+e+", 0px)",b.$slideTrack.css(c)))},b.prototype.setDimensions=function(){var a=this;a.options.vertical===!1?a.options.centerMode===!0&&a.$list.css({padding:"0px "+a.options.centerPadding}):(a.$list.height(a.$slides.first().outerHeight(!0)*a.options.slidesToShow),a.options.centerMode===!0&&a.$list.css({padding:a.options.centerPadding+" 0px"})),a.listWidth=a.$list.width(),a.listHeight=a.$list.height(),a.options.vertical===!1&&a.options.variableWidth===!1?(a.slideWidth=Math.ceil(a.listWidth/a.options.slidesToShow),a.$slideTrack.width(Math.ceil(a.slideWidth*a.$slideTrack.children(".slick-slide").length))):a.options.variableWidth===!0?a.$slideTrack.width(5e3*a.slideCount):(a.slideWidth=Math.ceil(a.listWidth),a.$slideTrack.height(Math.ceil(a.$slides.first().outerHeight(!0)*a.$slideTrack.children(".slick-slide").length)));var b=a.$slides.first().outerWidth(!0)-a.$slides.first().width();a.options.variableWidth===!1&&a.$slideTrack.children(".slick-slide").width(a.slideWidth-b)},b.prototype.setFade=function(){var c,b=this;b.$slides.each(function(d,e){c=-1*b.slideWidth*d,b.options.rtl===!0?a(e).css({position:"relative",right:c,top:0,zIndex:800,opacity:0}):a(e).css({position:"relative",left:c,top:0,zIndex:800,opacity:0})}),b.$slides.eq(b.currentSlide).css({zIndex:900,opacity:1})},b.prototype.setHeight=function(){var a=this;if(1===a.options.slidesToShow&&a.options.adaptiveHeight===!0&&a.options.vertical===!1){var b=a.$slides.eq(a.currentSlide).outerHeight(!0);a.$list.css("height",b)}},b.prototype.setOption=b.prototype.slickSetOption=function(a,b,c){var d=this;d.options[a]=b,c===!0&&(d.unload(),d.reinit())},b.prototype.setPosition=function(){var a=this;a.setDimensions(),a.setHeight(),a.options.fade===!1?a.setCSS(a.getLeft(a.currentSlide)):a.setFade(),a.$slider.trigger("setPosition",[a])},b.prototype.setProps=function(){var a=this,b=document.body.style;a.positionProp=a.options.vertical===!0?"top":"left","top"===a.positionProp?a.$slider.addClass("slick-vertical"):a.$slider.removeClass("slick-vertical"),(void 0!==b.WebkitTransition||void 0!==b.MozTransition||void 0!==b.msTransition)&&a.options.useCSS===!0&&(a.cssTransitions=!0),void 0!==b.OTransform&&(a.animType="OTransform",a.transformType="-o-transform",a.transitionType="OTransition",void 0===b.perspectiveProperty&&void 0===b.webkitPerspective&&(a.animType=!1)),void 0!==b.MozTransform&&(a.animType="MozTransform",a.transformType="-moz-transform",a.transitionType="MozTransition",void 0===b.perspectiveProperty&&void 0===b.MozPerspective&&(a.animType=!1)),void 0!==b.webkitTransform&&(a.animType="webkitTransform",a.transformType="-webkit-transform",a.transitionType="webkitTransition",void 0===b.perspectiveProperty&&void 0===b.webkitPerspective&&(a.animType=!1)),void 0!==b.msTransform&&(a.animType="msTransform",a.transformType="-ms-transform",a.transitionType="msTransition",void 0===b.msTransform&&(a.animType=!1)),void 0!==b.transform&&a.animType!==!1&&(a.animType="transform",a.transformType="transform",a.transitionType="transition"),a.transformsEnabled=null!==a.animType&&a.animType!==!1},b.prototype.setSlideClasses=function(a){var c,d,e,f,b=this;b.$slider.find(".slick-slide").removeClass("slick-active").attr("aria-hidden","true").removeClass("slick-center"),d=b.$slider.find(".slick-slide"),b.options.centerMode===!0?(c=Math.floor(b.options.slidesToShow/2),b.options.infinite===!0&&(a>=c&&a<=b.slideCount-1-c?b.$slides.slice(a-c,a+c+1).addClass("slick-active").attr("aria-hidden","false"):(e=b.options.slidesToShow+a,d.slice(e-c+1,e+c+2).addClass("slick-active").attr("aria-hidden","false")),0===a?d.eq(d.length-1-b.options.slidesToShow).addClass("slick-center"):a===b.slideCount-1&&d.eq(b.options.slidesToShow).addClass("slick-center")),b.$slides.eq(a).addClass("slick-center")):a>=0&&a<=b.slideCount-b.options.slidesToShow?b.$slides.slice(a,a+b.options.slidesToShow).addClass("slick-active").attr("aria-hidden","false"):d.length<=b.options.slidesToShow?d.addClass("slick-active").attr("aria-hidden","false"):(f=b.slideCount%b.options.slidesToShow,e=b.options.infinite===!0?b.options.slidesToShow+a:a,b.options.slidesToShow==b.options.slidesToScroll&&b.slideCount-ab.options.slidesToShow)){for(e=b.options.centerMode===!0?b.options.slidesToShow+1:b.options.slidesToShow,c=b.slideCount;c>b.slideCount-e;c-=1)d=c-1,a(b.$slides[d]).clone(!0).attr("id","").attr("data-slick-index",d-b.slideCount).prependTo(b.$slideTrack).addClass("slick-cloned");for(c=0;e>c;c+=1)d=c,a(b.$slides[d]).clone(!0).attr("id","").attr("data-slick-index",d+b.slideCount).appendTo(b.$slideTrack).addClass("slick-cloned");b.$slideTrack.find(".slick-cloned").find("[id]").each(function(){a(this).attr("id","")})}},b.prototype.setPaused=function(a){var b=this;b.options.autoplay===!0&&b.options.pauseOnHover===!0&&(b.paused=a,b.autoPlayClear())},b.prototype.selectHandler=function(b){var c=this,d=a(b.target).is(".slick-slide")?a(b.target):a(b.target).parents(".slick-slide"),e=parseInt(d.attr("data-slick-index"));return e||(e=0),c.slideCount<=c.options.slidesToShow?(c.$slider.find(".slick-slide").removeClass("slick-active").attr("aria-hidden","true"),c.$slides.eq(e).addClass("slick-active").attr("aria-hidden","false"),c.options.centerMode===!0&&(c.$slider.find(".slick-slide").removeClass("slick-center"),c.$slides.eq(e).addClass("slick-center")),c.asNavFor(e),void 0):(c.slideHandler(e),void 0)},b.prototype.slideHandler=function(a,b,c){var d,e,f,g,h=null,i=this;return b=b||!1,i.animating===!0&&i.options.waitForAnimate===!0||i.options.fade===!0&&i.currentSlide===a||i.slideCount<=i.options.slidesToShow?void 0:(b===!1&&i.asNavFor(a),d=a,h=i.getLeft(d),g=i.getLeft(i.currentSlide),i.currentLeft=null===i.swipeLeft?g:i.swipeLeft,i.options.infinite===!1&&i.options.centerMode===!1&&(0>a||a>i.getDotCount()*i.options.slidesToScroll)?(i.options.fade===!1&&(d=i.currentSlide,c!==!0?i.animateSlide(g,function(){i.postSlide(d)}):i.postSlide(d)),void 0):i.options.infinite===!1&&i.options.centerMode===!0&&(0>a||a>i.slideCount-i.options.slidesToScroll)?(i.options.fade===!1&&(d=i.currentSlide,c!==!0?i.animateSlide(g,function(){i.postSlide(d)}):i.postSlide(d)),void 0):(i.options.autoplay===!0&&clearInterval(i.autoPlayTimer),e=0>d?0!==i.slideCount%i.options.slidesToScroll?i.slideCount-i.slideCount%i.options.slidesToScroll:i.slideCount+d:d>=i.slideCount?0!==i.slideCount%i.options.slidesToScroll?0:d-i.slideCount:d,i.animating=!0,i.$slider.trigger("beforeChange",[i,i.currentSlide,e]),f=i.currentSlide,i.currentSlide=e,i.setSlideClasses(i.currentSlide),i.updateDots(),i.updateArrows(),i.options.fade===!0?(c!==!0?i.fadeSlide(e,function(){i.postSlide(e)}):i.postSlide(e),i.animateHeight(),void 0):(c!==!0?i.animateSlide(h,function(){i.postSlide(e)}):i.postSlide(e),void 0)))},b.prototype.startLoad=function(){var a=this;a.options.arrows===!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.hide(),a.$nextArrow.hide()),a.options.dots===!0&&a.slideCount>a.options.slidesToShow&&a.$dots.hide(),a.$slider.addClass("slick-loading")},b.prototype.swipeDirection=function(){var a,b,c,d,e=this;return a=e.touchObject.startX-e.touchObject.curX,b=e.touchObject.startY-e.touchObject.curY,c=Math.atan2(b,a),d=Math.round(180*c/Math.PI),0>d&&(d=360-Math.abs(d)),45>=d&&d>=0?e.options.rtl===!1?"left":"right":360>=d&&d>=315?e.options.rtl===!1?"left":"right":d>=135&&225>=d?e.options.rtl===!1?"right":"left":e.options.verticalSwiping===!0?d>=35&&135>=d?"left":"right":"vertical"},b.prototype.swipeEnd=function(){var c,b=this;if(b.dragging=!1,b.shouldClick=b.touchObject.swipeLength>10?!1:!0,void 0===b.touchObject.curX)return!1;if(b.touchObject.edgeHit===!0&&b.$slider.trigger("edge",[b,b.swipeDirection()]),b.touchObject.swipeLength>=b.touchObject.minSwipe)switch(b.swipeDirection()){case"left":c=b.options.swipeToSlide?b.checkNavigable(b.currentSlide+b.getSlideCount()):b.currentSlide+b.getSlideCount(),b.slideHandler(c),b.currentDirection=0,b.touchObject={},b.$slider.trigger("swipe",[b,"left"]);break;case"right":c=b.options.swipeToSlide?b.checkNavigable(b.currentSlide-b.getSlideCount()):b.currentSlide-b.getSlideCount(),b.slideHandler(c),b.currentDirection=1,b.touchObject={},b.$slider.trigger("swipe",[b,"right"])}else b.touchObject.startX!==b.touchObject.curX&&(b.slideHandler(b.currentSlide),b.touchObject={})},b.prototype.swipeHandler=function(a){var b=this; +if(!(b.options.swipe===!1||"ontouchend"in document&&b.options.swipe===!1||b.options.draggable===!1&&-1!==a.type.indexOf("mouse")))switch(b.touchObject.fingerCount=a.originalEvent&&void 0!==a.originalEvent.touches?a.originalEvent.touches.length:1,b.touchObject.minSwipe=b.listWidth/b.options.touchThreshold,b.options.verticalSwiping===!0&&(b.touchObject.minSwipe=b.listHeight/b.options.touchThreshold),a.data.action){case"start":b.swipeStart(a);break;case"move":b.swipeMove(a);break;case"end":b.swipeEnd(a)}},b.prototype.swipeMove=function(a){var d,e,f,g,h,b=this;return h=void 0!==a.originalEvent?a.originalEvent.touches:null,!b.dragging||h&&1!==h.length?!1:(d=b.getLeft(b.currentSlide),b.touchObject.curX=void 0!==h?h[0].pageX:a.clientX,b.touchObject.curY=void 0!==h?h[0].pageY:a.clientY,b.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(b.touchObject.curX-b.touchObject.startX,2))),b.options.verticalSwiping===!0&&(b.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(b.touchObject.curY-b.touchObject.startY,2)))),e=b.swipeDirection(),"vertical"!==e?(void 0!==a.originalEvent&&b.touchObject.swipeLength>4&&a.preventDefault(),g=(b.options.rtl===!1?1:-1)*(b.touchObject.curX>b.touchObject.startX?1:-1),b.options.verticalSwiping===!0&&(g=b.touchObject.curY>b.touchObject.startY?1:-1),f=b.touchObject.swipeLength,b.touchObject.edgeHit=!1,b.options.infinite===!1&&(0===b.currentSlide&&"right"===e||b.currentSlide>=b.getDotCount()&&"left"===e)&&(f=b.touchObject.swipeLength*b.options.edgeFriction,b.touchObject.edgeHit=!0),b.swipeLeft=b.options.vertical===!1?d+f*g:d+f*(b.$list.height()/b.listWidth)*g,b.options.verticalSwiping===!0&&(b.swipeLeft=d+f*g),b.options.fade===!0||b.options.touchMove===!1?!1:b.animating===!0?(b.swipeLeft=null,!1):(b.setCSS(b.swipeLeft),void 0)):void 0)},b.prototype.swipeStart=function(a){var c,b=this;return 1!==b.touchObject.fingerCount||b.slideCount<=b.options.slidesToShow?(b.touchObject={},!1):(void 0!==a.originalEvent&&void 0!==a.originalEvent.touches&&(c=a.originalEvent.touches[0]),b.touchObject.startX=b.touchObject.curX=void 0!==c?c.pageX:a.clientX,b.touchObject.startY=b.touchObject.curY=void 0!==c?c.pageY:a.clientY,b.dragging=!0,void 0)},b.prototype.unfilterSlides=b.prototype.slickUnfilter=function(){var a=this;null!==a.$slidesCache&&(a.unload(),a.$slideTrack.children(this.options.slide).detach(),a.$slidesCache.appendTo(a.$slideTrack),a.reinit())},b.prototype.unload=function(){var b=this;a(".slick-cloned",b.$slider).remove(),b.$dots&&b.$dots.remove(),b.$prevArrow&&"object"!=typeof b.options.prevArrow&&b.$prevArrow.remove(),b.$nextArrow&&"object"!=typeof b.options.nextArrow&&b.$nextArrow.remove(),b.$slides.removeClass("slick-slide slick-active slick-visible").attr("aria-hidden","true").css("width","")},b.prototype.unslick=function(){var a=this;a.destroy()},b.prototype.updateArrows=function(){var b,a=this;b=Math.floor(a.options.slidesToShow/2),a.options.arrows===!0&&a.options.infinite!==!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.removeClass("slick-disabled"),a.$nextArrow.removeClass("slick-disabled"),0===a.currentSlide?(a.$prevArrow.addClass("slick-disabled"),a.$nextArrow.removeClass("slick-disabled")):a.currentSlide>=a.slideCount-a.options.slidesToShow&&a.options.centerMode===!1?(a.$nextArrow.addClass("slick-disabled"),a.$prevArrow.removeClass("slick-disabled")):a.currentSlide>=a.slideCount-1&&a.options.centerMode===!0&&(a.$nextArrow.addClass("slick-disabled"),a.$prevArrow.removeClass("slick-disabled")))},b.prototype.updateDots=function(){var a=this;null!==a.$dots&&(a.$dots.find("li").removeClass("slick-active").attr("aria-hidden","true"),a.$dots.find("li").eq(Math.floor(a.currentSlide/a.options.slidesToScroll)).addClass("slick-active").attr("aria-hidden","false"))},b.prototype.visibility=function(){var a=this;document[a.hidden]?(a.paused=!0,a.autoPlayClear()):(a.paused=!1,a.autoPlay())},a.fn.slick=function(){var g,a=this,c=arguments[0],d=Array.prototype.slice.call(arguments,1),e=a.length,f=0;for(f;e>f;f++)if("object"==typeof c||"undefined"==typeof c?a[f].slick=new b(a[f],c):g=a[f].slick[c].apply(a[f].slick,d),"undefined"!=typeof g)return g;return a}}); \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-theme-1.5.0.css b/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-theme-1.5.0.css new file mode 100644 index 00000000000..715f0fdf1a6 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/js/jquery.slick/slick-theme-1.5.0.css @@ -0,0 +1,90 @@ +@charset 'UTF-8'; + +/* Dots */ +.slick-slider +{ + margin-bottom: 30px; +} + +.slick-dots +{ + position: absolute; + bottom: -45px; + + display: block; + + width: 100%; + padding: 0; + + list-style: none; + + text-align: center; +} +.slick-dots li +{ + position: relative; + + display: inline-block; + + width: 20px; + height: 20px; + margin: 0 5px; + padding: 0; + + cursor: pointer; +} +.slick-dots li button +{ + font-size: 0; + line-height: 0; + + display: block; + + width: 20px; + height: 20px; + padding: 5px; + + cursor: pointer; + + color: transparent; + border: 0; + outline: none; + background: transparent; +} +.slick-dots li button:hover, +.slick-dots li button:focus +{ + outline: none; +} +.slick-dots li button:hover:before, +.slick-dots li button:focus:before +{ + opacity: 1; +} +.slick-dots li button:before +{ + font-family: 'slick'; + font-size: 6px; + line-height: 20px; + + position: absolute; + top: 0; + left: 0; + + width: 20px; + height: 20px; + + content: '•'; + text-align: center; + + opacity: .25; + color: black; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.slick-dots li.slick-active button:before +{ + opacity: .75; + color: black; +} diff --git a/java/com.sap.sailing.gwt.ui/pom.xml b/java/com.sap.sailing.gwt.ui/pom.xml index b31d4236d43..834e3e43b56 100755 --- a/java/com.sap.sailing.gwt.ui/pom.xml +++ b/java/com.sap.sailing.gwt.ui/pom.xml @@ -68,6 +68,12 @@ 1.0.0-SNAPSHOT sources + + com.sap.sailing + com.sap.sse.gwt.theme + 1.0.0-SNAPSHOT + sources + com.sap.sailing com.sap.sse.gwt.adminconsole diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/app/AbstractApplicationClientFactory.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/app/AbstractApplicationClientFactory.java index c2f99c7786d..7417ed706fc 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/app/AbstractApplicationClientFactory.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/app/AbstractApplicationClientFactory.java @@ -5,6 +5,8 @@ import com.google.gwt.place.shared.Place; import com.google.gwt.place.shared.PlaceController; import com.google.web.bindery.event.shared.EventBus; import com.sap.sailing.gwt.autoplay.client.place.start.StartPlace; +import com.sap.sailing.gwt.home.client.HomeService; +import com.sap.sailing.gwt.home.client.HomeServiceAsync; import com.sap.sailing.gwt.ui.client.MediaService; import com.sap.sailing.gwt.ui.client.MediaServiceAsync; import com.sap.sailing.gwt.ui.client.SailingService; @@ -13,6 +15,7 @@ import com.sap.sse.security.ui.client.SecureClientFactoryImpl; public abstract class AbstractApplicationClientFactory extends SecureClientFactoryImpl implements AutoPlayAppClientFactory { private final SailingServiceAsync sailingService; + private final HomeServiceAsync homeService; private final MediaServiceAsync mediaService; private final PlaceNavigator navigator; @@ -20,6 +23,7 @@ public abstract class AbstractApplicationClientFactory extends SecureClientFacto super(root, eventBus, placeController); navigator = new PlaceNavigatorImpl(placeController); sailingService = GWT.create(SailingService.class); + homeService = GWT.create(HomeService.class); mediaService = GWT.create(MediaService.class); } @@ -33,6 +37,11 @@ public abstract class AbstractApplicationClientFactory extends SecureClientFacto return sailingService; } + @Override + public HomeServiceAsync getHomeService() { + return homeService; + } + @Override public MediaServiceAsync getMediaService() { return mediaService; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/place/start/DesktopStartView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/place/start/DesktopStartView.ui.xml index e424d441fb8..1b1afa2f0ff 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/place/start/DesktopStartView.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/place/start/DesktopStartView.ui.xml @@ -7,7 +7,7 @@
-
+
Display language:
@@ -15,7 +15,7 @@
-
+
Start browser in full screen mode:
@@ -23,7 +23,7 @@
-
+
Event:
@@ -31,7 +31,7 @@
-
+
Leaderboard:
@@ -39,7 +39,7 @@
-
+
Leaderboard Auto-Zoom:
@@ -47,7 +47,7 @@
-
+
Leaderboard Zoom-Factor:
@@ -55,7 +55,7 @@
-
+
Auto-Play video:
@@ -63,7 +63,7 @@
-
+
 
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/AbstractMapTokenizer.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/AbstractMapTokenizer.java new file mode 100644 index 00000000000..8f8d98f4a06 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/AbstractMapTokenizer.java @@ -0,0 +1,67 @@ +package com.sap.sailing.gwt.common.client; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +import com.google.gwt.place.shared.Place; +import com.google.gwt.place.shared.PlaceTokenizer; + +public abstract class AbstractMapTokenizer

implements PlaceTokenizer

{ + + private static final Logger logger = Logger.getLogger(AbstractMapTokenizer.class.getName()); + + @Override + public P getPlace(String token) { + return getPlaceFromParameters(toParameterMap(token)); + } + + protected abstract P getPlaceFromParameters(Map parameters); + + protected abstract Map getParameters(P place); + + @Override + public String getToken(P place) { + return toToken(getParameters(place)); + } + + private String toToken(Map parameters) { + StringBuilder stringBuilder = new StringBuilder(); + + for (Map.Entry entry : parameters.entrySet()) { + if(entry.getValue() == null || entry.getValue().isEmpty()) { + continue; + } + if(stringBuilder.length() > 0) { + stringBuilder.append("&"); + } + stringBuilder.append(entry.getKey() + "=" + entry.getValue()); + } + + return stringBuilder.toString(); + } + + private Map toParameterMap(String placeParametersAsToken) { + List list = Arrays.asList(placeParametersAsToken.split("&")); + + if (list == null || list.size() < 1) { + logger.warning("Token empty, no-op"); + Collections.emptyMap(); + } + + Map result = new HashMap<>(); + for (String listItem : list) { + String[] nvPair = listItem.split("="); + if (nvPair == null || nvPair.length != 2) { + logger.warning("Invalid parameters"); + continue; + } + result.put(nvPair[0], nvPair[1]); + } + return result; + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/BoatClassImageResolver.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/BoatClassImageResolver.java index fe597f843ff..c2b75a1b71b 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/BoatClassImageResolver.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/BoatClassImageResolver.java @@ -6,6 +6,12 @@ import java.util.Map; import com.google.gwt.resources.client.ImageResource; import com.sap.sailing.domain.common.BoatClassMasterdata; +/** + * All images are expected to be 140x140px with transparent background. + * + * @author Steffen Tobias Wagner, Axel Uhl (D043530) + * + */ public class BoatClassImageResolver { private static Map boatClassIconsMap; private static BoatClassImageResources imageResources = BoatClassImageResources.INSTANCE; @@ -52,6 +58,7 @@ public class BoatClassImageResolver { boatClassIconsMap.put(BoatClassMasterdata.NACRA_17.getDisplayName(), imageResources.Nacra17Icon()); boatClassIconsMap.put(BoatClassMasterdata.OK.getDisplayName(), imageResources.OKIcon()); boatClassIconsMap.put(BoatClassMasterdata.OPTIMIST.getDisplayName(), imageResources.OptimistIcon()); + boatClassIconsMap.put(BoatClassMasterdata.PIRAT.getDisplayName(), imageResources.PiratIcon()); boatClassIconsMap.put(BoatClassMasterdata.PLATU_25.getDisplayName(), imageResources.Platu25Icon()); boatClassIconsMap.put(BoatClassMasterdata.RS_X.getDisplayName(), imageResources.RSXIcon()); boatClassIconsMap.put(BoatClassMasterdata.SONAR.getDisplayName(), imageResources.SonarIcon()); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/BoatClassImageResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/BoatClassImageResources.java index 911c62da4c5..1bdcd27c88e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/BoatClassImageResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/BoatClassImageResources.java @@ -115,6 +115,9 @@ public interface BoatClassImageResources extends ClientBundle { @Source("com/sap/sailing/gwt/ui/client/images/boatclass/OPTIMIST.png") ImageResource OptimistIcon(); + @Source("com/sap/sailing/gwt/ui/client/images/boatclass/PIRAT.png") + ImageResource PiratIcon(); + @Source("com/sap/sailing/gwt/ui/client/images/boatclass/PLATU_25.png") ImageResource Platu25Icon(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/DateUtil.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/DateUtil.java index 4823984dbcf..758b10af4ec 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/DateUtil.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/DateUtil.java @@ -57,4 +57,10 @@ public class DateUtil { Date now = new Date(); return date.before(now) && !isToday(date); } + + public static int daysFromNow(Date date) { + long day = date.getTime() / DAY_IN_MILLIS; + long today= new Date().getTime() / DAY_IN_MILLIS; + return (int) (day - today); + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/LinkUtil.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/LinkUtil.java new file mode 100644 index 00000000000..1bd1bf1867d --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/LinkUtil.java @@ -0,0 +1,19 @@ +package com.sap.sailing.gwt.common.client; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.ui.impl.HyperlinkImpl; + +public final class LinkUtil { + private static final HyperlinkImpl HYPERLINK_IMPL = GWT.create(HyperlinkImpl.class); + + private LinkUtil() { + } + + public static boolean handleLinkClick(Event event) { + if(event.getTypeInt() != Event.ONCLICK) { + return false; + } + return HYPERLINK_IMPL.handleAsClick(event); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/SharedResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/SharedResources.java index fa7328bcd73..086fa1a8429 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/SharedResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/SharedResources.java @@ -3,7 +3,6 @@ package com.sap.sailing.gwt.common.client; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.CssResource; -import com.google.gwt.resources.client.CssResource.Shared; public interface SharedResources extends ClientBundle { public static final SharedResources INSTANCE = GWT.create(SharedResources.class); @@ -14,20 +13,24 @@ public interface SharedResources extends ClientBundle { @Source("com/sap/sailing/gwt/home/media.gss") MediaCss mediaCss(); - @Shared - public interface MainCss extends CssResource { - String grid(); - String stackenblochen(); + public interface MainCss extends CssResource{ String wrapper(); String navbar(); String navbar_button(); + String navbar_buttonhidden(); String navbar_buttonactive(); String button(); + String buttonsmall(); + String buttonstrong(); String buttoninactive(); + String buttonprimary(); + String buttonred(); String buttonrefresh(); - String buttonsearch(); String buttonarrowdown(); + String buttonsearch(); + String buttonarrowrightwhite(); String label(); + String labellarge(); String morelink(); String dummy(); String mainsection(); @@ -36,22 +39,19 @@ public interface SharedResources extends ClientBundle { String mainsection_navigation(); String lightbox(); String lightbox_overlay(); - String lightbox_overlayhidden(); String lightbox_content(); - String lightbox_contenthidden(); - String lightbox_content_enlargeditem(); - String lightbox_content_enlargeditem_caption(); - String lightbox_content_enlargeditem_close(); - String media_slideshow_controls(); - String lightbox_data(); - String lightbox_item(); + String lightbox_close(); + String stickyheader(); + String slideto(); + String slidetonav(); + String slidetoactive(); } - - @Shared - public interface MediaCss extends CssResource { + + public interface MediaCss extends CssResource{ + String grid(); + String stackenblochen(); String column(); String columns(); - String small1(); String small2(); String small3(); @@ -76,11 +76,14 @@ public interface SharedResources extends ClientBundle { String smalloffset9(); String smalloffset10(); String smalloffset11(); - String smallcentered(); - String smalluncentered(); String showonsmall(); String hideonsmall(); - + String showonmedium(); + String hideonmedium(); + String showonlarge(); + String hideonlarge(); + String smallcentered(); + String smalluncentered(); String medium1(); String medium2(); String medium3(); @@ -107,9 +110,6 @@ public interface SharedResources extends ClientBundle { String mediumoffset11(); String mediumcentered(); String mediumuncentered(); - String showonmedium(); - String hideonmedium(); - String large1(); String large2(); String large3(); @@ -136,9 +136,5 @@ public interface SharedResources extends ClientBundle { String largeoffset11(); String largecentered(); String largeuncentered(); - String showonlarge(); - String hideonlarge(); - - } } \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/Breadcrumb.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/Breadcrumb.css new file mode 100644 index 00000000000..6b97d0e9135 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/Breadcrumb.css @@ -0,0 +1,35 @@ +@CHARSET "UTF-8"; + +.event_header__breadcrumb { + font-size: 15px; + font-size: 1rem; + font-size: 0.866666666666667em; + font-weight: 600; + padding: 0.666666666666667em 0; +} + +.event_header__breadcrumb__item { + position: relative; + display: inline-block; + padding-left: 1.923076923076923em; + color: #666; +} + +.event_header__breadcrumb__item:before { + content: ' '; + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAUCAYAAAC58NwRAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo2OUUzNjU2OTYyN0ExMUU0OTkzRUFBMUUyRUFGQjM4NyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo2OUUzNjU2QTYyN0ExMUU0OTkzRUFBMUUyRUFGQjM4NyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjY5RTM2NTY3NjI3QTExRTQ5OTNFQUExRTJFQUZCMzg3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjY5RTM2NTY4NjI3QTExRTQ5OTNFQUExRTJFQUZCMzg3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+yfJlBgAAAK5JREFUeNpinDlz5goGBgZXIM4F4mUMBAATEDsBsRAQLwLiKGI0RADxdyBmJkYTSMM+IPYkVhMTlD5IrCYmJDZRmpjQ+CBNbvg0MWGx9Qg+TUw4/IZTExOeEIRp+oKkSZeJgTTAhk+DDRBvB2IeIP4LxIlAfJaJBMWLQRIsOBTvAmJOdMXYPI1XMboGe0KKkTXYQ92MVzFyfiBKMUzDCmIVI+eHd0AcR0gxCAAEGACmPjby/HEDIgAAAABJRU5ErkJggg=="); + height: 100%; + width: 6px; + position: absolute; + background-size: contain; + background-position: center center; + background-repeat: no-repeat; + left: 0.666666666666667em; +} +.event_header__breadcrumb__item:first-of-type { + padding-left: 0; +} +.event_header__breadcrumb__item:first-of-type:before { + display: none; +} + diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/BreadcrumbPane.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/BreadcrumbPane.java new file mode 100644 index 00000000000..6961adfc4f0 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/BreadcrumbPane.java @@ -0,0 +1,80 @@ +package com.sap.sailing.gwt.common.client.controls.tabbar; + +import com.google.gwt.core.shared.GWT; +import com.google.gwt.dom.client.AnchorElement; +import com.google.gwt.dom.client.DivElement; +import com.google.gwt.dom.client.Document; +import com.google.gwt.resources.client.ClientBundle; +import com.google.gwt.resources.client.CssResource; +import com.google.gwt.safehtml.shared.SafeUri; +import com.google.gwt.safehtml.shared.UriUtils; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.EventListener; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.common.client.LinkUtil; + +/** + * @author zhorvath + * + */ +public class BreadcrumbPane extends Widget { + + interface Resources extends ClientBundle { + @Source("Breadcrumb.css") + Style style(); + } + + interface Style extends CssResource { + + String event_header__breadcrumb(); + + String event_header__breadcrumb__item(); + + } + + private static Resources resources; + + private static Resources getResources() { + if (resources == null) { + resources = GWT.create(Resources.class); + resources.style().ensureInjected(); + } + return resources; + } + + private final Style style = getResources().style(); + + private final DivElement breadcrumDiv; + + public BreadcrumbPane() { + breadcrumDiv = Document.get().createDivElement(); + breadcrumDiv.addClassName(style.event_header__breadcrumb()); + + setElement(breadcrumDiv); + } + + public void addBreadcrumbItem(String title, String link, final Runnable runnable) { + addBreadcrumbItem(title, UriUtils.fromString(link), runnable); + } + + public void addBreadcrumbItem(String title, SafeUri link, final Runnable runnable) { + AnchorElement breadcrumItem = Document.get().createAnchorElement(); + breadcrumItem.setHref(link); + breadcrumItem.setInnerText(title); + breadcrumItem.addClassName(style.event_header__breadcrumb__item()); + + breadcrumDiv.appendChild(breadcrumItem); + + Event.sinkEvents(breadcrumItem, Event.ONCLICK); + Event.setEventListener(breadcrumItem, new EventListener() { + @Override + public void onBrowserEvent(Event event) { + if (LinkUtil.handleLinkClick(event)) { + event.stopPropagation(); + event.preventDefault(); + runnable.run(); + } + } + }); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/TabBar.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/TabBar.java new file mode 100644 index 00000000000..e159845c347 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/TabBar.java @@ -0,0 +1,118 @@ +package com.sap.sailing.gwt.common.client.controls.tabbar; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gwt.core.shared.GWT; +import com.google.gwt.dom.client.AnchorElement; +import com.google.gwt.dom.client.DivElement; +import com.google.gwt.dom.client.Document; +import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.EventTarget; +import com.google.gwt.event.logical.shared.HasSelectionHandlers; +import com.google.gwt.event.logical.shared.SelectionEvent; +import com.google.gwt.event.logical.shared.SelectionHandler; +import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.place.shared.Place; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.common.client.LinkUtil; +import com.sap.sailing.gwt.common.client.SharedResources; +import com.sap.sailing.gwt.common.client.SharedResources.MainCss; + +/** + * Capsulates functionality for a tab bar. + * + * @author zhorvath + * + */ +public class TabBar extends Widget implements HasSelectionHandlers> { + + private final MainCss style = SharedResources.INSTANCE.mainCss(); + + private final List> knownPlaceClasses = new ArrayList<>(); + private final DivElement tabBarDiv; + + public TabBar() { + tabBarDiv = Document.get().createDivElement(); + tabBarDiv.addClassName(style.navbar()); + + setElement(tabBarDiv); + + sinkEvents(Event.ONCLICK); + } + + @Override + public void onBrowserEvent(Event event) { + EventTarget eventTarget = event.getEventTarget(); + + if (Element.is(eventTarget)) { + // An event target can be any JavaScript object, but we are interested in events related to DOM events only + Element element = eventTarget.cast(); + + if (LinkUtil.handleLinkClick(event)) { + // The user clicked somewhere into the tab bar -> we have to find the tab that was clicked + for (int i = 0; i < tabBarDiv.getChildCount(); i++) { + if (tabBarDiv.getChild(i).isOrHasChild(element)) { + event.stopPropagation(); + event.preventDefault(); + // the specific tab was clicked -> fire SelectionEvent with the associated place + GWT.log("Found " + knownPlaceClasses.get(i)); + SelectionEvent.fire(this, knownPlaceClasses.get(i)); + break; + } + } + } + } + + super.onBrowserEvent(event); + } + + /** + * Selects the tab associated with the given place. + * + * @param place + * the place that should get selected. + */ + public void select(Place place) { + GWT.log("Should activate: " + place.getClass().getName()); + // remove all previous selections + for (int i = 0; i < tabBarDiv.getChildCount(); i++) { + Element.as(tabBarDiv.getChild(i)).removeClassName(style.navbar_buttonactive()); + } + // find the tab that has to be selected for the given place + for (int i = 0; i < knownPlaceClasses.size(); i++) { + if (place.getClass().equals(knownPlaceClasses.get(i))) { + GWT.log("Activate: " + place.getClass().getName()); + // found the associated tab -> set the selected style. + Element.as(tabBarDiv.getChild(i)).addClassName(style.navbar_buttonactive()); + } + } + } + + /** + * Adds a tab with an associated place to be fired when the tab is selected + * + * TODO: create custom widget for tab + * + * @param title + * the label of the tab header. + * @param place + * the place that should be associated with the tab. + */ + public void addTab(String title, Class place, String link) { + AnchorElement tabElement = Document.get().createAnchorElement(); + tabElement.setHref(link); + tabElement.setInnerText(title); + tabElement.addClassName(style.navbar_button()); + + tabBarDiv.appendChild(tabElement); + knownPlaceClasses.add(place); + } + + /** {@inheritDoc} */ + @Override + public HandlerRegistration addSelectionHandler(SelectionHandler> handler) { + return addHandler(handler, SelectionEvent.getType()); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/TabPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/TabPanel.java new file mode 100644 index 00000000000..50b483643de --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/TabPanel.java @@ -0,0 +1,181 @@ +package com.sap.sailing.gwt.common.client.controls.tabbar; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.event.logical.shared.SelectionEvent; +import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.place.shared.Place; +import com.google.gwt.place.shared.PlaceHistoryMapper; +import com.google.gwt.safehtml.shared.SafeUri; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiChild; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.uibinder.client.UiHandler; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.IsWidget; +import com.google.gwt.user.client.ui.SimplePanel; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView.State; + +/** + * Defines whole layout for site, including the header with the breadcrumbs and tab bar, and the content. + *

+ * Created by pgtaboada on 25.11.14. + */ + +public class TabPanel extends Composite { + private static TabPanelUiBinder ourUiBinder = GWT.create(TabPanelUiBinder.class); + private final Map, TabView> knownTabs = new LinkedHashMap<>(); + private final Map, String> knownTabTitles = new HashMap<>(); + + @UiField + SimplePanel additionalHeader; + @UiField + SimplePanel tabContentPanelUi; + @UiField + TabBar tabBar; + @UiField BreadcrumbPane breadcrumbs; + @UiField FlowPanel tabExtension; + private TabView currentTab; + + + private final PlaceHistoryMapper historyMapper; + private final PRESENTER presenter; + + public TabPanel(PRESENTER presenter, PlaceHistoryMapper historyMapper) { + this.presenter = presenter; + this.historyMapper = historyMapper; + initWidget(ourUiBinder.createAndBindUi(this)); + } + + public TabView getCurrentTab() { + return currentTab; + } + + @UiChild + public void addHeader(Widget widget) { + additionalHeader.setWidget(widget); + } + + /** + * Adds all tabs to the tab bar. + * + * @param tab + * The tab to add + * @param title + * The label for the tab. + */ + @UiChild + public void addTabContent(final TabView tab, String title) { + + GWT.log("Adding TAB: " + title); + + // TODO: check if place class already known, reject... + tab.setPresenter(presenter); + final Class classForActivation = tab.getPlaceClassForActivation(); + knownTabs.put(classForActivation, tab); + knownTabTitles.put(classForActivation, title); + + if(tab.getState() == State.VISIBLE) { + String link = "#" + historyMapper.getToken(tab.placeToFire()); + tabBar.addTab(title, classForActivation, link); + } + } + + /** + * Handles given SelectionEvent, when tab is clicked. Fires a TabPanelPlaceSelectionEvent. The listener to this + * event should properly fire place change events. + * + * @param event + */ + @UiHandler("tabBar") + void onTabSelection(SelectionEvent> event) { + + TabView selectedTabActivity = knownTabs.get(event.getSelectedItem()); + if (selectedTabActivity != null) { + GWT.log("Tab selection: " + selectedTabActivity.getPlaceClassForActivation().getName()); + if (currentTab != null) { + currentTab.stop(); + } + fireEvent(new TabPanelPlaceSelectionEvent(selectedTabActivity)); + } + + } + + /** + * Starts the tab Activity and selects the tab based on the given Place. + * + * @param placeToGo + * the given place. + */ + public void activatePlace(Place placeToGo) { + if (knownTabs.containsKey(placeToGo.getClass())) { + final TabView newTab = knownTabs.get(placeToGo.getClass()); + + if (newTab.getState() == State.NOT_AVAILABLE_REDIRECT + || newTab.getState() == State.NOT_AVAILABLE_SHOW_NEXT_AVAILABLE) { + for(TabView tab : knownTabs.values()) { + if(tab.getState() == State.VISIBLE) { + // TODO is this redirect wanted? Just silently select another tab? + if (currentTab != null) { + currentTab.stop(); + } + + if (newTab.getState() == State.NOT_AVAILABLE_REDIRECT) { + fireEvent(new TabPanelPlaceSelectionEvent(tab)); + } else { + activatePlace(tab.placeToFire()); + } + return; + } + } + } + + newTab.start(placeToGo, tabContentPanelUi); + tabBar.select(placeToGo); + + currentTab = newTab; + + } + + } + + /** + * Directly sets the content of the current widget until it is reloaded/ reset + * + * @param widget + */ + public void overrideCurrentContentInTab(IsWidget widget) { + tabContentPanelUi.setWidget(widget); + } + + public void addBreadcrumbItem(String title, String link, final Runnable runnable) { + breadcrumbs.addBreadcrumbItem(title, link, runnable); + } + + public void addBreadcrumbItem(String title, SafeUri link, final Runnable runnable) { + breadcrumbs.addBreadcrumbItem(title, link, runnable); + } + + public HandlerRegistration addTabPanelPlaceSelectionEventHandler(TabPanelPlaceSelectionEvent.Handler handler) { + return addHandler(handler, TabPanelPlaceSelectionEvent.TYPE); + } + + interface TabPanelUiBinder extends UiBinder> { + } + + public String getCurrentTabTitle() { + if (currentTab == null) + return null; + return knownTabTitles.get(currentTab.getPlaceClassForActivation()); + } + + @UiChild + public void addTabExtension(IsWidget widget) { + tabExtension.add(widget); + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/TabPanel.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/TabPanel.ui.xml new file mode 100644 index 00000000000..029329befcb --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/TabPanel.ui.xml @@ -0,0 +1,59 @@ + + + + .header { + position: relative; + font-size: 1rem; + color: #666; + background: #f2f2f2; + border-bottom: 1px solid #dedede; + } + + .breadcrumb { + font-size: 1rem; + /* @alternate */ font-size: 0.866666666666667em; + font-weight: 600; + padding: 0.666666666666667em 0; + } + + .back:hover { + background-color: #cfcfcf; + } + + .content { + width: 100%; + height: 100%; + } + + .navigation { + /* font-size: 0; */ + margin-bottom: -1px; + } + .tabExtension { + float: right; + margin-left: 0.5em; + } + + + +

+
+ +
+
+ +
+
+ + +
+
+ + + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/TabPanelPlaceSelectionEvent.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/TabPanelPlaceSelectionEvent.java new file mode 100644 index 00000000000..b9b882f8de5 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/TabPanelPlaceSelectionEvent.java @@ -0,0 +1,40 @@ +package com.sap.sailing.gwt.common.client.controls.tabbar; + +import com.google.gwt.event.shared.EventHandler; +import com.google.gwt.event.shared.GwtEvent; + +/** + * Created by pgtaboada on 01.12.14. + */ +public class TabPanelPlaceSelectionEvent extends GwtEvent { + + public final static Type TYPE = new Type(); + + private TabView selectedActivity; + + public TabPanelPlaceSelectionEvent(TabView selectedActivity) { + this.selectedActivity = selectedActivity; + } + + @Override + public Type getAssociatedType() { + return TYPE; + } + + public TabView getSelectedActivity() { + return selectedActivity; + } + + @Override + protected void dispatch(Handler handler) { + + handler.onTabSelected(this); + } + + public interface Handler extends EventHandler { + + void onTabSelected(TabPanelPlaceSelectionEvent event); + + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/TabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/TabView.java new file mode 100644 index 00000000000..c6516c80e2a --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/controls/tabbar/TabView.java @@ -0,0 +1,44 @@ +package com.sap.sailing.gwt.common.client.controls.tabbar; + +import com.google.gwt.place.shared.Place; +import com.google.gwt.user.client.ui.AcceptsOneWidget; + +/** + * Defines lifecycle handling for the tab view. + *

+ *

+ * Created by pgtaboada on 25.11.14. + */ +public interface TabView { + + public enum State { + VISIBLE, INVISIBLE, NOT_AVAILABLE_REDIRECT, NOT_AVAILABLE_SHOW_NEXT_AVAILABLE + } + + /** + * The place type that activates this tab. + * + * @return + */ + Class getPlaceClassForActivation(); + + /** + * Lifecycle method that triggers tab view start + * + * @param placeToGo + * @param contentArea + */ + void start(PLACE requestedPlace, AcceptsOneWidget contentArea); + + void setPresenter(PRESENTER presenter); + + /** + * Tells the tab that it is going to be deactiviated (not visible anymore), because of tab switch + */ + void stop(); + + PLACE placeToFire(); + + // TODO implement as defender method when Java 8 is ready as this is "VISIBLE" in most cases + State getState(); +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.java index 1d3e8f06b79..bc8d8abdc4b 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.java @@ -1,8 +1,11 @@ package com.sap.sailing.gwt.common.client.i18n; import com.google.gwt.core.client.GWT; +import com.google.gwt.i18n.client.LocalizableResource.DefaultLocale; import com.google.gwt.i18n.client.Messages; + +@DefaultLocale("en") public interface TextMessages extends Messages { public static final TextMessages INSTANCE = GWT.create(TextMessages.class); @@ -41,6 +44,7 @@ public interface TextMessages extends Messages { String overview(); String sapSailing(); String search(); + String startSimulator(); String countdownDays(); String countdownHours(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.properties index 89290630dcd..883c330a638 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.properties @@ -33,6 +33,7 @@ whatsNew=What''s new overview=Overview sapSailing=SAP Sailing search=Search +startSimulator=Start Simulator countdownDays=Days countdownHours=Hrs @@ -65,7 +66,7 @@ eventHeaderOverview=Overview eventHeaderRaces=Schedule eventHeaderRegattas=Regattas seriesHeaderOverview=About the Series -seriesHeaderUpcoming=Upcoming Events +seriesHeaderUpcoming=Upcoming seriesHeaderRecent=Recent Events seriesHeaderLeaderboard=Leaderboard seriesOverviewHeaderRecent=Latest Series Events @@ -112,15 +113,15 @@ eventRegattaRacesLegendAudio=Audio Stream eventSponsorsTitle=Event Sponsorships footerJobs=Jobs footerCopyright=\u00A9 2015 SAP Sailing Analytics -footerLanguage=SAP Sailing offered in +footerLanguage=SAP Sailing in footerLegal=Legal Disclosure footerPrivacy=Privacy footerFeedback=Feedback headerEvents=Events headerHome=Home -headerLogo=SAP Sailing Analytics +headerLogo=Sailing Analytics headerSearch=Search -headerSearchPlaceholder=Search SAPSailing.com +headerSearchPlaceholder=Search headerSolutions=Solutions headerSponsoring=Sponsoring latestRaceResultsHeadline=Latest Official Race Results diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_cn.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_cn.properties new file mode 100644 index 00000000000..ade865f9df7 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_cn.properties @@ -0,0 +1,183 @@ +socialFooterShare=Share this on +home=主页 +aboutUs=关于我们 +contact=联络 +sponsoring=赞助商 +solutions=解决方案 +events=比赛 +german=德语 +english=英语 +officalEventWebsite=官方活动网站 +leg=站 +races=赛事 +moreInfo=更多信息 +viewAnalysis=观看分析 +overallLeaderboard=总排行榜 +pleaseEnterASearchTerm=请输入搜索词 +pleaseTryAgain=请再试一次 +reloadPage=重新载入页面 +errorMessageLoadingData=加载该页的数据时出错 +errorMessageNoSuchLeaderboard=无法利用这词寻找排行榜 +raceNotScheduled=没有确认时间 +regattaDetails=帆船赛细节 +regatta=帆船赛 +competitorsAnalytics=队伍分析 +chooseChart=选择图标类型 +series=系列 +regattaLeaderboards=帆船赛排行榜 +features=功能 +releaseNotes=软件更新发布 +whatsNew=最新信息 +overview=概览 +sapSailing=SAP帆船 +search=搜索 +startSimulator=启动模拟器 +live=实时 +finished=结束 +watchNow=马上观看 +lastUpdate=最后更新 +leaderboard=排行榜 +eventHeaderMedia=媒体 +eventHeaderOverview=概览 +eventHeaderRaces=赛程 +eventHeaderRegattas=帆船赛 +seriesHeaderOverview=关于比赛系列 +seriesHeaderUpcoming=未来赛事 +seriesHeaderRecent=最近赛事 +seriesHeaderLeaderboard=排行榜 +eventsOverviewRecentEvents=赛事 +eventsOverviewRecentCountries=国家 +eventsOverviewRecentSailors=运动员 +eventsOverviewRecentTrackedRaces=赛事(含比赛分析) +eventResultsHeadline=比赛结果 +eventResultsBoatClassesDropDown=所有帆船级别 +eventOverviewMoreEvents=更多赛事 +eventOverviewRecentEvents=最近赛事 +eventOverviewUpcomingDate=日期 +eventOverviewUpcomingEvent=赛事 +eventOverviewUpcomingLocation=地点 +eventOverviewUpcomingSchedule=未来赛程 +eventOverviewUpcomingSeries=系列 +eventOverviewUpcomingTeaser=更多赛事即将公布 +eventQuickfinderTitle=赛事快速查找 +eventRegattaHeaderLeaderboard=排行榜 +eventRegattaHeaderRaceRaces=赛事 +eventRegattaListAllBoatClasses=所有帆船级别 +eventRegattaLeaderboardCompetitor=比赛队伍 +eventRegattaLeaderboardExtendLeaderboard=详细排行榜 +eventRegattaLeaderboardFinishedMessage=没有更多比赛 +eventRegattaLeaderboardLastScoreUpdate=最后积分更新 +eventRegattaLeaderboardName=队伍名称 +eventRegattaLeaderboardRegattaRank=帆船赛排名 +eventRegattaLeaderboardTotalPoints=总积分 +eventRegattaRaceWatch=实时观看 +eventRegattaRaceAnalyse=赛事分析 +eventRegattaRaceNotTracked=不含比赛分析 +mainEventShowAll=显示所有赛事 +mainEventTitle=最新帆船赛事 +mainMediaSubtitle= +mainMediaTitle=照片 +mainMediaVideosSubtitle= +mainMediaVideosTitle=最新视频 +mainSponsorsReadMore=阅读更多 +mediaTeaserPhotosTitle=照片 +mediaTeaserVideosTitle=视频 +regattaCompetitors=比赛队伍\竞争对手 +regattaRaces=赛事 +regattaTracked=Tracked  +regattaRegattaStarts=帆船比赛即将开始 +regattaPts=积分 +regattaCourse=帆船赛程 +regattaArea=地点 +regattaFinishedAt=结束时间为 +regattaScheduledAt=开始时间为 +regattaStartedAt=开始时间为 +regattasResultsTitle=比赛结果 +searchResultHeaderButton=搜寻 +searchResultHeaderLabel=您的搜寻 +searchResultsFound=搜寻结果 +searchResultHeaderPlaceholder=输入您的搜寻关键词 +searchResultMore=更多 +searchResultSearch=搜寻 +searchResultSearchAgain=重新搜寻 +searchResultSortLabel=排序方式 +searchResultSortNewest=最近 +searchResultSortOldest=最旧 +searchResultSortRelevance=相关性 +solutionsSAPNav=SAP帆船比赛分析 +solutionsSAPHeadline=SAP帆船比赛分析 +countdownDays=Days +countdownHours=Hrs +countdownMinutes=Min +countdownSeconds=Sec +countdownDay=Day +countdownHour=Hour +countdownMinute=Min +countdownSecond=Sec +boxNewsUpdateMoreLink=Report news +boxNewsUpdateTitle=News Update +boxUpcomingRacesCountdownStarted1=Started +boxUpcomingRacesCountdownStarted2=hrs and +boxUpcomingRacesCountdownStarted3=minutes ago +boxUpcomingRacesCountdownStarting1=Starting in +boxUpcomingRacesCountdownStarting2=hrs and +boxUpcomingRacesCountdownStarting3=minutes +boxUpcomingRacesMoreLink=Event Schedule +boxUpcomingRacesTitle=Upcoming Races Today +boxWeather=Weather +boxWeatherUnit=KTS +defaultTitle=SAP帆船 +seriesOverviewHeaderRecent=Latest Series Events +seriesOverviewReadMore=More +eventRegattaRaceFinished=Finished at: +eventRegattaRaceStarted=Started at: +eventRegattaRaceScheduled=Scheduled for: +eventRegattaRaceRace=Race +eventRegattaRaceWind=Wind Strength: +eventRegattaRaceWinner=Winner +eventRegattaRaceLeader=Leader +eventRegattaRacesLegendGps=Tracking +eventRegattaRacesLegendWind=Wind Data +eventRegattaRacesLegendVideo=Video Stream +eventRegattaRacesLegendAudio=Audio Stream +eventSponsorsTitle=Event Sponsorships +footerJobs=Jobs +footerCopyright=\u00A9 2015 SAP帆船 +footerLanguage=SAP Sailing offered in +footerLegal=Legal Disclosure +footerPrivacy=Privacy +footerFeedback=Feedback +headerEvents=比赛 +headerHome=主页 +headerLogo=SAP帆船 +headerSearch=搜索 +headerSearchPlaceholder=搜索 +headerSolutions=Solutions +headerSponsoring=Sponsoring +latestRaceResultsHeadline=Latest Official Race Results +latestRaceResultsIsNew=New +latestRaceResultsIsUpdated=Updated +latestRaceResultsRaceCountLabel=Result after +latestRaceResultsRaceCountUnit=races +latestRaceResultsRefresh=refresh +leaderboardQuickAccessLabel=Leaderboard Quick Access +searchResultCount=About 2,450 results where found for 'Schnitzel' +sharingEmail=Send an email +sharingFacebook=Share on Facebook +sharingTwitter=Tweet about it +socialFooterTitle=Recommend SAP Sailing Analytics +solutionsSAPText1=By delivering real time analytics around race rankings, speeds, maneuvers, bearings etc., SAP is helping to simplify and demystify the complex sport of sailing. +solutionsSAPText2=SAP Sailing Analytics provide insights and transparency to the world of sailing by utilizing Cloud and In-Memory Technology, processing GPS and wind measurement data in real time and visualizing contents in various frontends accessible from anywhere. +solutionsRaceNav=Race Committee App +solutionsRaceHeadline=Race Committee App +solutionsRaceText=The SAP Race Committee App delivers greater efficiency and control to race organizers by automating and simplifying their manual tasks and communication during running sailing regattas. The Race Committee App helps simplify the operation of running and managing race events to help race committees operate smarter. +solutionsPostNav=Post-Race Analytics +solutionsPostHeadline=Post-Race Analytics +solutionsPostText=Access to data collected at sailing events gives sailors the opportunity to assess and analyse their performances to help develop strategies and sail better.
SAP Business Analytics solutions provide sailors, coaches, fans and media with tools to browse and analyse historical data across many regattas and races. SAP HANA allows them to learn about performance patterns, tendencies and sailor profiles in a simple, fast and efficient way in order to optimize their own performance and develop successful strategies for future regattas. +solutionsTrainingNav=Training Diary +solutionsTrainingHeadline=SAP Sail Better \u2013 STG Training Diary +solutionsTrainingText=The STG Training Diary supports the daily documentation and analysis of an athlete\u2019s physical condition and training efforts in the areas of water training, physical training, boat work, mental, theory as well as other activities like education or travel. +solutionsSimulatorNav=Strategy Simulator +solutionsSimulatorHeadline=Strategy Simulator +solutionsSimulatorText=Choosing the right strategy can provide great competitive advantage during a race. The Strategy Simulator simplifies determining the best sailing strategy for various wind conditions and water currents. Since wind and current can be changed in the simulation right away, the robustness of a strategy can be easily evaluated even for uncertain weather conditions. + diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_de.properties index a0d670101dd..7e657fa0e03 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_de.properties @@ -1,4 +1,4 @@ -chartSelectionHint=Hinweis: Sie können auch Ergebnisstabelle (im Menü ERGEBNISSE) nutzen, um die im Diagramm angezeigten Teilnehmer auszuwählen. +chartSelectionHint=Hinweis: Sie können auch Ergebnisstabelle (im Menü ERGEBNISSE) nutzen, um die im Diagramm angezeigten Teilnehmer auszuwählen. chooseALanguage=Wähle eine Sprache events=Veranstaltungen home=Startseite @@ -13,7 +13,7 @@ officalEventWebsite=Offizielle Internetseite leg=Schenkel races=Rennen moreInfo=Weitere Informationen -viewAnalysis=Analyzen ansehen +viewAnalysis=Analysen ansehen overallLeaderboard=Gesamtergebnis pleaseEnterASearchTerm=Bitte gebe einen Suchbegriff ein. pleaseTryAgain=Bitte versuchen sie es erneut... @@ -30,9 +30,10 @@ regattaLeaderboards=Regattaergebnisse features=Funktionen releaseNotes=Anmerkungen zur Version whatsNew=Neuigkeiten -overview=Übersicht +overview=Übersicht sapSailing=SAP Sailing search=Suche +startSimulator=Simulator starten countdownDays=Tage countdownHours=Std. @@ -65,7 +66,7 @@ eventHeaderOverview=Übersicht eventHeaderRaces=Zeitplan eventHeaderRegattas=Regatten seriesHeaderOverview=Über die Serie -seriesHeaderUpcoming=Noch kommende Veranstaltungen +seriesHeaderUpcoming=Demnächst seriesHeaderRecent=Letzte Veranstaltungen seriesHeaderLeaderboard=Ergebnisliste seriesOverviewHeaderRecent=Letzte Serienveranstaltungen @@ -97,7 +98,7 @@ eventRegattaLeaderboardRegattaRank=Platz in der Regatta eventRegattaLeaderboardTotalPoints=Gesamtpunkte eventRegattaRaceWatch=Live ansehen eventRegattaRaceAnalyse=Rennen analysieren -eventRegattaRaceNotTracked=Nicht getracked +eventRegattaRaceNotTracked=Nicht getrackt eventRegattaRaceFinished=Beendet um: eventRegattaRaceStarted=Gestartet um: eventRegattaRaceScheduled=Geplant um: @@ -118,7 +119,7 @@ footerPrivacy=Datenschutz footerFeedback=Feedback headerEvents=Veranstaltungen headerHome=Startseite -headerLogo=SAP Sailing Analytics +headerLogo=Sailing Analytics headerSearch=Suche in SAPSailing.com headerSearchPlaceholder=Suche headerSolutions=Lösungen @@ -133,7 +134,7 @@ leaderboardQuickAccessLabel=Ergebnisliste Schnellzugang mainEventShowAll=Zeige alle Veranstaltungen mainEventTitle=Die letzten Veranstaltungen aus der Segelwelt mainMediaSubtitle=Hier gibt es die aktuellsten und schönsten Impressionen aus deiner beliebtesten Segelveranstaltung. -mainMediaTitle=Segeln liebt Fotographie +mainMediaTitle=Segeln liebt Fotografie mainMediaVideosSubtitle=Tauche ein in die Welt des Segelns und besuche auch die anderen Veranstaltungen für mehr Videos. mainMediaVideosTitle= Die Letzten Videoeinträge mainSponsorsReadMore=Lese mehr @@ -141,7 +142,7 @@ mediaTeaserPhotosTitle=Fotos mediaTeaserVideosTitle=Videos regattaCompetitors=Teilnehmer regattaRaces=Rennen -regattaTracked=Getracked +regattaTracked=Getrackt regattaRegattaStarts=Regatta wird starten regattaPts=Pkt. regattaCourse=Kurs diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/HomeEntryPoint.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/HomeEntryPoint.java index e0aa0674cd7..4f03e7b0cb0 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/HomeEntryPoint.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/HomeEntryPoint.java @@ -16,6 +16,7 @@ public class HomeEntryPoint extends AbstractMvpEntryPoint { public void doOnModuleLoad() { ApplicationClientFactory clientFactory = GWT.create(ApplicationClientFactory.class); EntryPointHelper.registerASyncService((ServiceDefTarget) clientFactory.getSailingService(), RemoteServiceMappingConstants.sailingServiceRemotePath); + EntryPointHelper.registerASyncService((ServiceDefTarget) clientFactory.getHomeService(), RemoteServiceMappingConstants.homeServiceRemotePath); ApplicationHistoryMapper applicationHistoryMapper = GWT.create(ApplicationHistoryMapper.class); initMvp(clientFactory, applicationHistoryMapper, new ApplicationActivityMapper(clientFactory)); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/HomeService.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/HomeService.java new file mode 100644 index 00000000000..fec9e54fc9f --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/HomeService.java @@ -0,0 +1,24 @@ +package com.sap.sailing.gwt.home.client; + +import java.util.UUID; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.sap.sailing.gwt.ui.shared.eventlist.EventListViewDTO; +import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO; +import com.sap.sailing.gwt.ui.shared.fakeseries.EventSeriesViewDTO; +import com.sap.sailing.gwt.ui.shared.media.MediaDTO; +import com.sap.sailing.gwt.ui.shared.start.StartViewDTO; + +public interface HomeService extends RemoteService { + EventViewDTO getEventViewById(UUID id); + + EventSeriesViewDTO getEventSeriesViewById(UUID id); + + MediaDTO getMediaForEvent(UUID eventId); + + MediaDTO getMediaForEventSeries(UUID seriesId); + + EventListViewDTO getEventListView() throws Exception; + + StartViewDTO getStartView() throws Exception; +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/HomeServiceAsync.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/HomeServiceAsync.java new file mode 100644 index 00000000000..d05f1fd754c --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/HomeServiceAsync.java @@ -0,0 +1,28 @@ +package com.sap.sailing.gwt.home.client; + +import java.util.UUID; + +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.sap.sailing.gwt.ui.shared.eventlist.EventListViewDTO; +import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO; +import com.sap.sailing.gwt.ui.shared.fakeseries.EventSeriesViewDTO; +import com.sap.sailing.gwt.ui.shared.media.MediaDTO; +import com.sap.sailing.gwt.ui.shared.start.StartViewDTO; + + +/** + * The async counterpart of {@link HomeService} + */ +public interface HomeServiceAsync { + void getEventViewById(UUID id, AsyncCallback callback); + + void getEventSeriesViewById(UUID id, AsyncCallback asyncCallback); + + void getMediaForEvent(UUID eventId, AsyncCallback callback); + + void getMediaForEventSeries(UUID seriesId, AsyncCallback callback); + + void getEventListView(AsyncCallback callback); + + void getStartView(AsyncCallback callback); +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/AbstractApplicationClientFactory.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/AbstractApplicationClientFactory.java index 9af08b973a3..c60e07f10ef 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/AbstractApplicationClientFactory.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/AbstractApplicationClientFactory.java @@ -4,6 +4,8 @@ import com.google.gwt.core.client.GWT; import com.google.gwt.place.shared.Place; import com.google.gwt.place.shared.PlaceController; import com.google.web.bindery.event.shared.EventBus; +import com.sap.sailing.gwt.home.client.HomeService; +import com.sap.sailing.gwt.home.client.HomeServiceAsync; import com.sap.sailing.gwt.home.client.place.start.StartPlace; import com.sap.sailing.gwt.ui.client.MediaService; import com.sap.sailing.gwt.ui.client.MediaServiceAsync; @@ -14,6 +16,7 @@ import com.sap.sse.security.ui.client.SecureClientFactoryImpl; public abstract class AbstractApplicationClientFactory extends SecureClientFactoryImpl implements ApplicationClientFactory { private final SailingServiceAsync sailingService; + private final HomeServiceAsync homeService; private final MediaServiceAsync mediaService; private final HomePlacesNavigator navigator; @@ -21,6 +24,7 @@ public abstract class AbstractApplicationClientFactory extends SecureClientFacto super(root, eventBus, placeController); navigator = new HomePlacesNavigator(placeController); sailingService = GWT.create(SailingService.class); + homeService = GWT.create(HomeService.class); mediaService = GWT.create(MediaService.class); } @@ -34,6 +38,11 @@ public abstract class AbstractApplicationClientFactory extends SecureClientFacto return sailingService; } + @Override + public HomeServiceAsync getHomeService() { + return homeService; + } + @Override public MediaServiceAsync getMediaService() { return mediaService; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/AbstractPlaceNavigator.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/AbstractPlaceNavigator.java index 8370895d0cc..9573cde5f49 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/AbstractPlaceNavigator.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/AbstractPlaceNavigator.java @@ -1,15 +1,19 @@ package com.sap.sailing.gwt.home.client.app; +import com.google.gwt.core.client.GWT; import com.google.gwt.place.shared.Place; import com.google.gwt.place.shared.PlaceController; -import com.google.gwt.place.shared.PlaceTokenizer; import com.google.gwt.user.client.History; import com.google.gwt.user.client.Window; public abstract class AbstractPlaceNavigator implements PlaceNavigator { protected final PlaceController placeController; - public final static String DEFAULT_SAPSAILING_SERVER = "www.sapsailing.com"; - public final static String DEFAULT_SAPSAILING_SERVER_URL = "http://" + DEFAULT_SAPSAILING_SERVER; + + private final ApplicationHistoryMapper mapper = GWT.create(ApplicationHistoryMapper.class); + + public final static String DEFAULT_SAPSAILING_SERVER = "www.sapsailing.com"; + public final static String DEFAULT_SAPSAILING_DEV_SERVER = "dev.sapsailing.com"; + public final static String DEFAULT_SAPSAILING_SERVER_URL = "http://" + DEFAULT_SAPSAILING_SERVER; protected AbstractPlaceNavigator(PlaceController placeController) { this.placeController = placeController; @@ -25,20 +29,24 @@ public abstract class AbstractPlaceNavigator implements PlaceNavigator { } } - protected PlaceNavigation createLocalPlaceNavigation(T destinationPlace, PlaceTokenizer tokenizer) { - return new PlaceNavigation(null, destinationPlace, tokenizer, false); + protected PlaceNavigation createLocalPlaceNavigation(T destinationPlace) { + return new PlaceNavigation(null, destinationPlace, false, this); } - protected PlaceNavigation createGlobalPlaceNavigation(T destinationPlace, PlaceTokenizer tokenizer) { - return new PlaceNavigation(destinationPlace, tokenizer); + + protected PlaceNavigation createGlobalPlaceNavigation(T destinationPlace) { + return new PlaceNavigation(destinationPlace, this); } - protected PlaceNavigation createPlaceNavigation(String baseUrl, boolean isOnRemoteServer, T destinationPlace, PlaceTokenizer tokenizer) { - return new PlaceNavigation(baseUrl, destinationPlace, tokenizer, isOnRemoteServer); + + protected PlaceNavigation createPlaceNavigation(String baseUrl, boolean isOnRemoteServer, + T destinationPlace) { + return new PlaceNavigation(baseUrl, destinationPlace, isOnRemoteServer, this); } - - public void pushPlaceToHistoryStack(T destinationPlace, PlaceTokenizer tokenizer) { - String placeHistoryToken = destinationPlace.getClass().getSimpleName() + ":" + tokenizer.getToken(destinationPlace); + + + public void pushPlaceToHistoryStack(T destinationPlace) { + String placeHistoryToken = mapper.getToken(destinationPlace); History.newItem(placeHistoryToken, false); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/ApplicationActivityMapper.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/ApplicationActivityMapper.java index 21b1ca13d04..1c79dc4f2f8 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/ApplicationActivityMapper.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/ApplicationActivityMapper.java @@ -7,16 +7,33 @@ import com.sap.sailing.gwt.home.client.place.aboutus.AboutUsActivityProxy; import com.sap.sailing.gwt.home.client.place.aboutus.AboutUsPlace; import com.sap.sailing.gwt.home.client.place.contact.ContactActivityProxy; import com.sap.sailing.gwt.home.client.place.contact.ContactPlace; +import com.sap.sailing.gwt.home.client.place.error.ErrorActivityProxy; +import com.sap.sailing.gwt.home.client.place.error.ErrorPlace; +import com.sap.sailing.gwt.home.client.place.event.AbstractEventPlace; import com.sap.sailing.gwt.home.client.place.event.EventActivityProxy; -import com.sap.sailing.gwt.home.client.place.event.EventPlace; +import com.sap.sailing.gwt.home.client.place.event.EventContext; +import com.sap.sailing.gwt.home.client.place.event.EventDefaultPlace; +import com.sap.sailing.gwt.home.client.place.event.legacy.EventPlace; +import com.sap.sailing.gwt.home.client.place.event.legacy.RegattaPlace; +import com.sap.sailing.gwt.home.client.place.event.legacy.SeriesPlace; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs.MultiregattaMediaPlace; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs.MultiregattaOverviewPlace; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs.MultiregattaRegattasPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaCompetitorAnalyticsPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaLeaderboardPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaMediaPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaOverviewPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaRacesPlace; import com.sap.sailing.gwt.home.client.place.events.EventsActivityProxy; import com.sap.sailing.gwt.home.client.place.events.EventsPlace; -import com.sap.sailing.gwt.home.client.place.regatta.RegattaActivityProxy; -import com.sap.sailing.gwt.home.client.place.regatta.RegattaPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.AbstractSeriesPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesContext; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesDefaultPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.tabs.EventSeriesCompetitorAnalyticsPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.tabs.EventSeriesLeaderboardsPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.tabs.EventSeriesOverallLeaderboardPlace; import com.sap.sailing.gwt.home.client.place.searchresult.SearchResultActivityProxy; import com.sap.sailing.gwt.home.client.place.searchresult.SearchResultPlace; -import com.sap.sailing.gwt.home.client.place.series.SeriesActivityProxy; -import com.sap.sailing.gwt.home.client.place.series.SeriesPlace; import com.sap.sailing.gwt.home.client.place.solutions.SolutionsActivityProxy; import com.sap.sailing.gwt.home.client.place.solutions.SolutionsPlace; import com.sap.sailing.gwt.home.client.place.sponsoring.SponsoringActivityProxy; @@ -38,10 +55,19 @@ public class ApplicationActivityMapper implements ActivityMapper { public Activity getActivity(Place place) { if (place instanceof AboutUsPlace) { return new AboutUsActivityProxy((AboutUsPlace) place, clientFactory); + } else if (place instanceof ErrorPlace) { + return new ErrorActivityProxy((ErrorPlace) place, clientFactory); } else if (place instanceof ContactPlace) { return new ContactActivityProxy((ContactPlace) place, clientFactory); } else if (place instanceof EventPlace) { - return new EventActivityProxy((EventPlace) place, clientFactory); + // return new EventActivityProxy((EventPlace) place, clientFactory); + // rerouting old place to new place to make bookmarked URLs to work with the new interface. + return getActivity(getRealEventPlace((EventPlace) place)); + } else if (place instanceof AbstractEventPlace) { + AbstractEventPlace eventPlace = (AbstractEventPlace) place; + return new EventActivityProxy(eventPlace, clientFactory, clientFactory.getHomePlacesNavigator()); + } else if (place instanceof AbstractSeriesPlace) { + return new com.sap.sailing.gwt.home.client.place.fakeseries.SeriesActivityProxy((AbstractSeriesPlace) place, clientFactory, clientFactory.getHomePlacesNavigator()); } else if (place instanceof EventsPlace) { return new EventsActivityProxy((EventsPlace) place, clientFactory); } else if (place instanceof StartPlace) { @@ -53,13 +79,93 @@ public class ApplicationActivityMapper implements ActivityMapper { } else if (place instanceof WhatsNewPlace) { return new WhatsNewActivityProxy((WhatsNewPlace) place, clientFactory); } else if (place instanceof RegattaPlace) { - return new RegattaActivityProxy((RegattaPlace) place, clientFactory); +// return new RegattaActivityProxy((RegattaPlace) place, clientFactory); + // rerouting old place to new place to make bookmarked URLs to work with the new interface. + return getActivity(getRealRegattaPlace((RegattaPlace) place)); } else if (place instanceof SeriesPlace) { - return new SeriesActivityProxy((SeriesPlace) place, clientFactory); +// return new SeriesActivityProxy((SeriesPlace) place, clientFactory); + // rerouting old place to new place to make bookmarked URLs to work with the new interface. + return getActivity(getRealSeriesPlace((SeriesPlace) place)); } else if (place instanceof SearchResultPlace) { return new SearchResultActivityProxy((SearchResultPlace) place, clientFactory); } else { return null; } } + + private Place getRealRegattaPlace(RegattaPlace place) { + String eventId = place.getEventUuidAsString(); + if(eventId == null || eventId.isEmpty()) { + return new EventsPlace(); + } + EventContext eventContext = new EventContext().withId(eventId); + String regattaId = place.getLeaderboardIdAsNameString(); + boolean hasRegattaId = (regattaId != null && !regattaId.isEmpty()); + + // TODO evaluate additional parameters + + if(hasRegattaId) { + switch (place.getNavigationTab()) { + case CompetitorAnalytics: + return new RegattaCompetitorAnalyticsPlace(eventContext); + case Leaderboard: + return new RegattaLeaderboardPlace(eventContext); + } + } + return new EventDefaultPlace(eventContext); + } + + @SuppressWarnings("incomplete-switch") + private Place getRealEventPlace(EventPlace place) { + String eventId = place.getEventUuidAsString(); + if(eventId == null || eventId.isEmpty()) { + return new EventsPlace(); + } + EventContext eventContext = new EventContext().withId(eventId); + String regattaId = place.getLeaderboardIdAsNameString(); + boolean hasRegattaId = (regattaId != null && !regattaId.isEmpty()); + if(hasRegattaId) { + eventContext.withRegattaId(regattaId); + + switch (place.getNavigationTab()) { + case Media: + return new RegattaMediaPlace(eventContext); + case Overview: + return new RegattaOverviewPlace(eventContext); + case Regatta: + return new RegattaRacesPlace(eventContext); + } + } else { + switch (place.getNavigationTab()) { + // TODO some places aren't implemented yet + case Media: + return new MultiregattaMediaPlace(eventContext); + case Overview: + return new MultiregattaOverviewPlace(eventContext); + case Schedule: + // Schedule not implemented yet -> using race list + case Regattas: + return new MultiregattaRegattasPlace(eventContext); + } + } + + return new EventDefaultPlace(eventContext); + } + + private Place getRealSeriesPlace(SeriesPlace place) { + String seriesId = place.getEventUuidAsString(); + SeriesContext context = new SeriesContext().withId(seriesId); + + // TODO evaluate additional parameters + + switch (place.getNavigationTab()) { + case OverallLeaderboard: + return new EventSeriesOverallLeaderboardPlace(context); + case RegattaLeaderboards: + return new EventSeriesLeaderboardsPlace(context); + case CompetitorAnalytics: + return new EventSeriesCompetitorAnalyticsPlace(context); + } + return new SeriesDefaultPlace(context); + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/ApplicationClientFactory.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/ApplicationClientFactory.java index 24748bf5b11..94ffce103a9 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/ApplicationClientFactory.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/ApplicationClientFactory.java @@ -2,11 +2,11 @@ package com.sap.sailing.gwt.home.client.app; import com.sap.sailing.gwt.home.client.place.aboutus.AboutUsClientFactory; import com.sap.sailing.gwt.home.client.place.contact.ContactClientFactory; +import com.sap.sailing.gwt.home.client.place.error.ErrorClientFactory; import com.sap.sailing.gwt.home.client.place.event.EventClientFactory; +import com.sap.sailing.gwt.home.client.place.event.legacy.SeriesClientFactory; import com.sap.sailing.gwt.home.client.place.events.EventsClientFactory; -import com.sap.sailing.gwt.home.client.place.regatta.RegattaClientFactory; import com.sap.sailing.gwt.home.client.place.searchresult.SearchResultClientFactory; -import com.sap.sailing.gwt.home.client.place.series.SeriesClientFactory; import com.sap.sailing.gwt.home.client.place.solutions.SolutionsClientFactory; import com.sap.sailing.gwt.home.client.place.sponsoring.SponsoringClientFactory; import com.sap.sailing.gwt.home.client.place.start.StartClientFactory; @@ -14,6 +14,6 @@ import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewClientFactory; public interface ApplicationClientFactory extends AboutUsClientFactory, ContactClientFactory, EventClientFactory, EventsClientFactory, StartClientFactory, SponsoringClientFactory, SolutionsClientFactory, SearchResultClientFactory, - WhatsNewClientFactory, RegattaClientFactory, SeriesClientFactory { + WhatsNewClientFactory, SeriesClientFactory, ErrorClientFactory { HomePlacesNavigator getHomePlacesNavigator(); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/ApplicationHistoryMapper.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/ApplicationHistoryMapper.java index 8e84054afa1..08f8f0475ee 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/ApplicationHistoryMapper.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/ApplicationHistoryMapper.java @@ -4,18 +4,56 @@ import com.google.gwt.place.shared.PlaceHistoryMapper; import com.google.gwt.place.shared.WithTokenizers; import com.sap.sailing.gwt.home.client.place.aboutus.AboutUsPlace; import com.sap.sailing.gwt.home.client.place.contact.ContactPlace; -import com.sap.sailing.gwt.home.client.place.event.EventPlace; +import com.sap.sailing.gwt.home.client.place.event.EventDefaultPlace; +import com.sap.sailing.gwt.home.client.place.event.legacy.EventPlace; +import com.sap.sailing.gwt.home.client.place.event.legacy.RegattaPlace; +import com.sap.sailing.gwt.home.client.place.event.legacy.SeriesPlace; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs.MultiregattaMediaPlace; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs.MultiregattaOverviewPlace; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs.MultiregattaRegattasPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaCompetitorAnalyticsPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaLeaderboardPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaMediaPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaOverviewPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaRacesPlace; import com.sap.sailing.gwt.home.client.place.events.EventsPlace; -import com.sap.sailing.gwt.home.client.place.regatta.RegattaPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesDefaultPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.tabs.EventSeriesCompetitorAnalyticsPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.tabs.EventSeriesLeaderboardsPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.tabs.EventSeriesOverallLeaderboardPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.tabs.SeriesEventsPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.tabs.SeriesMediaPlace; import com.sap.sailing.gwt.home.client.place.searchresult.SearchResultPlace; -import com.sap.sailing.gwt.home.client.place.series.SeriesPlace; import com.sap.sailing.gwt.home.client.place.solutions.SolutionsPlace; import com.sap.sailing.gwt.home.client.place.sponsoring.SponsoringPlace; import com.sap.sailing.gwt.home.client.place.start.StartPlace; import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewPlace; -@WithTokenizers({ AboutUsPlace.Tokenizer.class, ContactPlace.Tokenizer.class, EventPlace.Tokenizer.class, EventsPlace.Tokenizer.class, - SolutionsPlace.Tokenizer.class, WhatsNewPlace.Tokenizer.class, SponsoringPlace.Tokenizer.class, SearchResultPlace.Tokenizer.class, StartPlace.Tokenizer.class, - RegattaPlace.Tokenizer.class, SeriesPlace.Tokenizer.class }) +@WithTokenizers({ AboutUsPlace.Tokenizer.class, ContactPlace.Tokenizer.class, EventPlace.Tokenizer.class, + EventsPlace.Tokenizer.class, SolutionsPlace.Tokenizer.class, WhatsNewPlace.Tokenizer.class, + SponsoringPlace.Tokenizer.class, SearchResultPlace.Tokenizer.class, StartPlace.Tokenizer.class, + RegattaPlace.Tokenizer.class, SeriesPlace.Tokenizer.class, + // Event tab places... + EventDefaultPlace.Tokenizer.class, + // Multiregatta places: + MultiregattaOverviewPlace.Tokenizer.class, + MultiregattaRegattasPlace.Tokenizer.class, + MultiregattaMediaPlace.Tokenizer.class, + // Regatta places: + RegattaOverviewPlace.Tokenizer.class, + RegattaRacesPlace.Tokenizer.class, + RegattaLeaderboardPlace.Tokenizer.class, + RegattaCompetitorAnalyticsPlace.Tokenizer.class, + RegattaMediaPlace.Tokenizer.class, + // Fake series places: + SeriesDefaultPlace.Tokenizer.class, + RegattaOverviewPlace.Tokenizer.class, + SeriesEventsPlace.Tokenizer.class, + EventSeriesCompetitorAnalyticsPlace.Tokenizer.class, + EventSeriesOverallLeaderboardPlace.Tokenizer.class, + EventSeriesLeaderboardsPlace.Tokenizer.class, + SeriesMediaPlace.Tokenizer.class + +}) public interface ApplicationHistoryMapper extends PlaceHistoryMapper { } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/HomePlacesNavigator.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/HomePlacesNavigator.java index 689e9abe727..a1e9a6b4289 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/HomePlacesNavigator.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/HomePlacesNavigator.java @@ -1,22 +1,28 @@ package com.sap.sailing.gwt.home.client.app; +import java.util.HashMap; +import java.util.Map; + import com.google.gwt.place.shared.PlaceController; import com.sap.sailing.gwt.home.client.place.aboutus.AboutUsPlace; import com.sap.sailing.gwt.home.client.place.contact.ContactPlace; -import com.sap.sailing.gwt.home.client.place.event.EventPlace; -import com.sap.sailing.gwt.home.client.place.event.EventPlace.EventNavigationTabs; +import com.sap.sailing.gwt.home.client.place.event.AbstractEventPlace; +import com.sap.sailing.gwt.home.client.place.event.EventDefaultPlace; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs.MultiregattaRegattasPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.AbstractEventRegattaPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaCompetitorAnalyticsPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaLeaderboardPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaOverviewPlace; import com.sap.sailing.gwt.home.client.place.events.EventsPlace; -import com.sap.sailing.gwt.home.client.place.regatta.RegattaPlace; -import com.sap.sailing.gwt.home.client.place.regatta.RegattaPlace.RegattaNavigationTabs; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesDefaultPlace; import com.sap.sailing.gwt.home.client.place.searchresult.SearchResultPlace; -import com.sap.sailing.gwt.home.client.place.series.SeriesPlace; -import com.sap.sailing.gwt.home.client.place.series.SeriesPlace.SeriesNavigationTabs; import com.sap.sailing.gwt.home.client.place.solutions.SolutionsPlace; import com.sap.sailing.gwt.home.client.place.solutions.SolutionsPlace.SolutionsNavigationTabs; import com.sap.sailing.gwt.home.client.place.sponsoring.SponsoringPlace; import com.sap.sailing.gwt.home.client.place.start.StartPlace; import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewPlace; import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewPlace.WhatsNewNavigationTabs; +import com.sap.sailing.gwt.ui.client.EntryPointLinkFactory; public class HomePlacesNavigator extends AbstractPlaceNavigator { @@ -25,56 +31,75 @@ public class HomePlacesNavigator extends AbstractPlaceNavigator { } public PlaceNavigation getHomeNavigation() { - return createGlobalPlaceNavigation(new StartPlace(), new StartPlace.Tokenizer()); + return createGlobalPlaceNavigation(new StartPlace()); } public PlaceNavigation getEventsNavigation() { - return createGlobalPlaceNavigation(new EventsPlace(), new EventsPlace.Tokenizer()); + return createGlobalPlaceNavigation(new EventsPlace()); } public PlaceNavigation getSolutionsNavigation(SolutionsNavigationTabs navigationTab) { - return createLocalPlaceNavigation(new SolutionsPlace(navigationTab), new SolutionsPlace.Tokenizer()); + return createLocalPlaceNavigation(new SolutionsPlace(navigationTab)); } public PlaceNavigation getWhatsNewNavigation(WhatsNewNavigationTabs navigationTab) { - return createLocalPlaceNavigation(new WhatsNewPlace(navigationTab), new WhatsNewPlace.Tokenizer()); + return createLocalPlaceNavigation(new WhatsNewPlace(navigationTab)); } + public String getSimulatorURL() { + Map parameters = new HashMap(); + return EntryPointLinkFactory.createSimulatorLink(parameters); + } + public PlaceNavigation getSponsoringNavigation() { - return createGlobalPlaceNavigation(new SponsoringPlace(), new SponsoringPlace.Tokenizer()); + return createGlobalPlaceNavigation(new SponsoringPlace()); } public PlaceNavigation getAboutUsNavigation() { - return createGlobalPlaceNavigation(new AboutUsPlace(), new AboutUsPlace.Tokenizer()); + return createGlobalPlaceNavigation(new AboutUsPlace()); } public PlaceNavigation getContactNavigation() { - return createGlobalPlaceNavigation(new ContactPlace(), new ContactPlace.Tokenizer()); + return createGlobalPlaceNavigation(new ContactPlace()); + } + + public PlaceNavigation getEventRegattasNavigation(String eventUuidAsString, String baseUrl, boolean isOnRemoteServer) { + MultiregattaRegattasPlace eventPlace = new MultiregattaRegattasPlace(eventUuidAsString); + return createPlaceNavigation(baseUrl, isOnRemoteServer, eventPlace); + } + + public PlaceNavigation getEventSeriesNavigation(String seriesId, String baseUrl, boolean isOnRemoteServer) { + SeriesDefaultPlace place = new SeriesDefaultPlace(seriesId); + return createPlaceNavigation(baseUrl, isOnRemoteServer, place); } - public PlaceNavigation getEventNavigation(String eventUuidAsString, String baseUrl, boolean isOnRemoteServer) { - EventPlace eventPlace = new EventPlace(eventUuidAsString, EventNavigationTabs.Regattas, null); - return createPlaceNavigation(baseUrl, isOnRemoteServer, eventPlace, new EventPlace.Tokenizer()); + public PlaceNavigation getEventNavigation(String eventUuidAsString, String baseUrl, boolean isOnRemoteServer) { + EventDefaultPlace eventPlace = new EventDefaultPlace(eventUuidAsString); + return createPlaceNavigation(baseUrl, isOnRemoteServer, eventPlace); + } + + public

PlaceNavigation

getEventNavigation(P place, String baseUrl, + boolean isOnRemoteServer) { + return createPlaceNavigation(baseUrl, isOnRemoteServer, place); } - public PlaceNavigation getRegattaNavigation(String eventUuidAsString, String leaderboardIdAsNameString, String baseUrl, boolean isOnRemoteServer) { - EventPlace eventPlace = new EventPlace(eventUuidAsString, EventNavigationTabs.Regatta, leaderboardIdAsNameString); - return createPlaceNavigation(baseUrl, isOnRemoteServer, eventPlace, new EventPlace.Tokenizer()); + @SuppressWarnings({ "unchecked", "rawtypes" }) + public PlaceNavigation getRegattaNavigation(String eventUuidAsString, String leaderboardIdAsNameString, String baseUrl, boolean isOnRemoteServer) { + RegattaOverviewPlace eventPlace = new RegattaOverviewPlace(eventUuidAsString, leaderboardIdAsNameString); + return (PlaceNavigation) createPlaceNavigation(baseUrl, isOnRemoteServer, eventPlace); } - /** this place will be merged into the common regatta view as tab later on */ - public PlaceNavigation getRegattaAnalyticsNavigation(String eventUuidAsString, RegattaNavigationTabs navigationTab, String leaderboardIdAsNameString, String baseUrl, boolean isOnRemoteServer) { - RegattaPlace regattaPlace = new RegattaPlace(eventUuidAsString, navigationTab, leaderboardIdAsNameString, true, true); - return createPlaceNavigation(baseUrl, isOnRemoteServer, regattaPlace, new RegattaPlace.Tokenizer()); + public PlaceNavigation getCompetitorAnalyticsNavigation(String eventUuidAsString, String regattaId, String baseUrl, boolean isOnRemoteServer) { + RegattaCompetitorAnalyticsPlace regattaPlace = new RegattaCompetitorAnalyticsPlace(eventUuidAsString, regattaId); + return createPlaceNavigation(baseUrl, isOnRemoteServer, regattaPlace); } - - /** this place will be merged into the common series event view as tab later on */ - public PlaceNavigation getSeriesAnalyticsNavigation(String eventUuidAsString, SeriesNavigationTabs navigationTab, String leaderboardIdAsNameString, String baseUrl, boolean isOnRemoteServer) { - SeriesPlace seriesPlace = new SeriesPlace(eventUuidAsString, navigationTab, leaderboardIdAsNameString, true, true); - return createPlaceNavigation(baseUrl, isOnRemoteServer, seriesPlace, new SeriesPlace.Tokenizer()); + + public PlaceNavigation getLeaderboardNavigation(String eventUuidAsString, String regattaId, String baseUrl, boolean isOnRemoteServer) { + RegattaLeaderboardPlace regattaPlace = new RegattaLeaderboardPlace(eventUuidAsString, regattaId); + return createPlaceNavigation(baseUrl, isOnRemoteServer, regattaPlace); } public PlaceNavigation getSearchResultNavigation(String searchQuery) { - return createGlobalPlaceNavigation(new SearchResultPlace(searchQuery), new SearchResultPlace.Tokenizer()); + return createGlobalPlaceNavigation(new SearchResultPlace(searchQuery)); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/PlaceNavigation.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/PlaceNavigation.java index 4dabed6b71f..b3834e248eb 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/PlaceNavigation.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/PlaceNavigation.java @@ -2,28 +2,31 @@ package com.sap.sailing.gwt.home.client.app; import com.google.gwt.core.client.GWT; import com.google.gwt.place.shared.Place; -import com.google.gwt.place.shared.PlaceTokenizer; import com.google.gwt.user.client.Window; public class PlaceNavigation { + private final PlaceNavigator placeNavigator; + + private final ApplicationHistoryMapper mapper = GWT.create(ApplicationHistoryMapper.class); + private final T destinationPlace; - private final PlaceTokenizer tokenizer; private final String baseUrl; private final boolean isDestinationOnRemoteServer; - - public PlaceNavigation(T destinationPlace, PlaceTokenizer tokenizer) { + + public PlaceNavigation(T destinationPlace, PlaceNavigator placeNavigator) { + this.placeNavigator = placeNavigator; this.destinationPlace = destinationPlace; - this.tokenizer = tokenizer; String locationURL = getLocationURL(); - this.isDestinationOnRemoteServer = !(isLocationOnLocalhost(locationURL) || isLocationOnDefaultSapSailingServer(locationURL)); - this.baseUrl = isDestinationOnRemoteServer ? AbstractPlaceNavigator.DEFAULT_SAPSAILING_SERVER_URL : locationURL; + this.isDestinationOnRemoteServer = !(isLocationOnLocalhostOrDevServer(locationURL) || isLocationOnDefaultSapSailingServer(locationURL)); + this.baseUrl = isDestinationOnRemoteServer ? AbstractPlaceNavigator.DEFAULT_SAPSAILING_SERVER_URL : locationURL; } - public PlaceNavigation(String baseUrl, T destinationPlace, PlaceTokenizer tokenizer, boolean isDestinationOnRemoteServer) { + public PlaceNavigation(String baseUrl, T destinationPlace, boolean isDestinationOnRemoteServer, + PlaceNavigator placeNavigator) { this.destinationPlace = destinationPlace; - this.tokenizer = tokenizer; this.isDestinationOnRemoteServer = isDestinationOnRemoteServer; - this.baseUrl = isDestinationOnRemoteServer ? baseUrl : getLocationURL(); + this.placeNavigator = placeNavigator; + this.baseUrl = isDestinationOnRemoteServer ? baseUrl : getLocationURL(); } public String getTargetUrl() { @@ -32,7 +35,7 @@ public class PlaceNavigation { public String getHistoryUrl() { String placeUrl = buildPlaceUrl(); - if(placeUrl.startsWith("#")) { + if (placeUrl.startsWith("#")) { placeUrl = placeUrl.substring(1, placeUrl.length()); } return placeUrl; @@ -44,10 +47,10 @@ public class PlaceNavigation { private String buildPlaceUrl() { String url = ""; - if(isRemotePlace()) { + if (isRemotePlace()) { url = baseUrl + "/gwt/Home.html"; - if(!GWT.isProdMode()) { - url += "?gwt.codesvr=127.0.0.1:9997"; + if (!GWT.isProdMode()) { + url += "?gwt.codesvr=127.0.0.1:9997"; } url += getPlaceToken(); } else { @@ -55,24 +58,30 @@ public class PlaceNavigation { } return url; } - + public boolean isRemotePlace() { return isDestinationOnRemoteServer; } private String getPlaceToken() { - return "#" + destinationPlace.getClass().getSimpleName() + ":" + tokenizer.getToken(destinationPlace); + return "#" + mapper.getToken(destinationPlace); + } private boolean isLocationOnDefaultSapSailingServer(String urlToCheck) { return urlToCheck.contains(HomePlacesNavigator.DEFAULT_SAPSAILING_SERVER); } - private boolean isLocationOnLocalhost(String urlToCheck) { - return urlToCheck.contains("localhost") || urlToCheck.contains("127.0.0.1"); + private boolean isLocationOnLocalhostOrDevServer(String urlToCheck) { + return urlToCheck.contains("localhost") || urlToCheck.contains("127.0.0.1") + || urlToCheck.contains(HomePlacesNavigator.DEFAULT_SAPSAILING_DEV_SERVER); } - + private String getLocationURL() { return Window.Location.getProtocol() + "//" + Window.Location.getHostName() + ":" + Window.Location.getPort(); } + + public void goToPlace() { + placeNavigator.goToPlace(this); + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/SmartphoneApplicationClientFactory.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/SmartphoneApplicationClientFactory.java index 590a3777541..c1e7dd596c7 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/SmartphoneApplicationClientFactory.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/SmartphoneApplicationClientFactory.java @@ -1,26 +1,13 @@ package com.sap.sailing.gwt.home.client.app; -import java.util.List; - import com.google.gwt.event.shared.SimpleEventBus; import com.google.gwt.place.shared.PlaceController; import com.google.web.bindery.event.shared.EventBus; import com.sap.sailing.gwt.home.client.place.error.TabletAndDesktopErrorView; -import com.sap.sailing.gwt.home.client.place.event.EventPlace.EventNavigationTabs; -import com.sap.sailing.gwt.home.client.place.event.EventView; -import com.sap.sailing.gwt.home.client.place.event.EventWithoutRegattasView; -import com.sap.sailing.gwt.home.client.place.event.TabletAndDesktopEventView; -import com.sap.sailing.gwt.home.client.place.event.TabletAndDesktopEventWithoutRegattasView; import com.sap.sailing.gwt.home.client.place.events.EventsView; import com.sap.sailing.gwt.home.client.place.events.TabletAndDesktopEventsView; -import com.sap.sailing.gwt.home.client.place.regatta.RegattaAnalyticsView; -import com.sap.sailing.gwt.home.client.place.regatta.RegattaPlace.RegattaNavigationTabs; -import com.sap.sailing.gwt.home.client.place.regatta.TabletAndDesktopRegattaView; import com.sap.sailing.gwt.home.client.place.searchresult.SearchResultView; import com.sap.sailing.gwt.home.client.place.searchresult.TabletAndDesktopSearchResultView; -import com.sap.sailing.gwt.home.client.place.series.SeriesAnalyticsView; -import com.sap.sailing.gwt.home.client.place.series.SeriesPlace.SeriesNavigationTabs; -import com.sap.sailing.gwt.home.client.place.series.TabletAndDesktopSeriesView; import com.sap.sailing.gwt.home.client.place.solutions.SolutionsPlace.SolutionsNavigationTabs; import com.sap.sailing.gwt.home.client.place.solutions.SolutionsView; import com.sap.sailing.gwt.home.client.place.solutions.TabletAndDesktopSolutionsView; @@ -28,12 +15,9 @@ import com.sap.sailing.gwt.home.client.place.sponsoring.SponsoringView; import com.sap.sailing.gwt.home.client.place.sponsoring.TabletAndDesktopSponsoringView; import com.sap.sailing.gwt.home.client.place.start.StartView; import com.sap.sailing.gwt.home.client.place.start.TabletAndDesktopStartView; +import com.sap.sailing.gwt.home.client.place.whatsnew.TabletAndDesktopWhatsNewView; import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewPlace.WhatsNewNavigationTabs; import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewView; -import com.sap.sailing.gwt.home.client.place.whatsnew.TabletAndDesktopWhatsNewView; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sailing.gwt.ui.shared.RaceGroupDTO; -import com.sap.sse.gwt.client.player.Timer; public class SmartphoneApplicationClientFactory extends AbstractApplicationClientFactory implements ApplicationClientFactory { @@ -46,18 +30,9 @@ public class SmartphoneApplicationClientFactory extends AbstractApplicationClien } private SmartphoneApplicationClientFactory(EventBus eventBus, PlaceController placeController) { - super(new TabletAndDesktopApplicationView(new HomePlacesNavigator(placeController)), eventBus, placeController); + super(new TabletAndDesktopApplicationView(new HomePlacesNavigator(placeController), eventBus), eventBus, placeController); } - @Override - public EventView createEventView(EventDTO event, EventNavigationTabs navigationTab, List raceGroups, String leaderboardName, Timer timerForClientServerOffset) { - return new TabletAndDesktopEventView(getSailingService(), event, navigationTab, raceGroups, leaderboardName, timerForClientServerOffset, getHomePlacesNavigator()); - } - - @Override - public EventWithoutRegattasView createEventWithoutRegattasView(EventDTO event) { - return new TabletAndDesktopEventWithoutRegattasView(getSailingService(), event, getHomePlacesNavigator()); - } @Override public EventsView createEventsView() { @@ -66,7 +41,7 @@ public class SmartphoneApplicationClientFactory extends AbstractApplicationClien @Override public TabletAndDesktopErrorView createErrorView(String errorMessage, Throwable errorReason) { - return new TabletAndDesktopErrorView(errorMessage, errorReason); + return new TabletAndDesktopErrorView(errorMessage, errorReason, null); } @Override @@ -83,16 +58,6 @@ public class SmartphoneApplicationClientFactory extends AbstractApplicationClien return new TabletAndDesktopSolutionsView(navigationTab, getHomePlacesNavigator()); } - @Override - public RegattaAnalyticsView createRegattaAnalyticsView(EventDTO event, String leaderboardName, RegattaNavigationTabs navigationTab, Timer timerForClientServerOffset) { - return new TabletAndDesktopRegattaView(event, leaderboardName, navigationTab, timerForClientServerOffset, getHomePlacesNavigator()); - } - - @Override - public SeriesAnalyticsView createSeriesAnalyticsView(EventDTO event, String leaderboardName, SeriesNavigationTabs navigationTab, Timer timerForClientServerOffset) { - return new TabletAndDesktopSeriesView(event, leaderboardName, navigationTab, timerForClientServerOffset, getHomePlacesNavigator()); - } - @Override public SearchResultView createSearchResultView() { return new TabletAndDesktopSearchResultView(getHomePlacesNavigator()); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/TabletAndDesktopApplicationClientFactory.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/TabletAndDesktopApplicationClientFactory.java index 0601da5349a..fecba98b5c2 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/TabletAndDesktopApplicationClientFactory.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/TabletAndDesktopApplicationClientFactory.java @@ -1,26 +1,13 @@ package com.sap.sailing.gwt.home.client.app; -import java.util.List; - import com.google.gwt.event.shared.SimpleEventBus; import com.google.gwt.place.shared.PlaceController; import com.google.web.bindery.event.shared.EventBus; import com.sap.sailing.gwt.home.client.place.error.TabletAndDesktopErrorView; -import com.sap.sailing.gwt.home.client.place.event.EventPlace.EventNavigationTabs; -import com.sap.sailing.gwt.home.client.place.event.EventView; -import com.sap.sailing.gwt.home.client.place.event.EventWithoutRegattasView; -import com.sap.sailing.gwt.home.client.place.event.TabletAndDesktopEventView; -import com.sap.sailing.gwt.home.client.place.event.TabletAndDesktopEventWithoutRegattasView; import com.sap.sailing.gwt.home.client.place.events.EventsView; import com.sap.sailing.gwt.home.client.place.events.TabletAndDesktopEventsView; -import com.sap.sailing.gwt.home.client.place.regatta.RegattaAnalyticsView; -import com.sap.sailing.gwt.home.client.place.regatta.RegattaPlace.RegattaNavigationTabs; -import com.sap.sailing.gwt.home.client.place.regatta.TabletAndDesktopRegattaView; import com.sap.sailing.gwt.home.client.place.searchresult.SearchResultView; import com.sap.sailing.gwt.home.client.place.searchresult.TabletAndDesktopSearchResultView; -import com.sap.sailing.gwt.home.client.place.series.SeriesAnalyticsView; -import com.sap.sailing.gwt.home.client.place.series.SeriesPlace.SeriesNavigationTabs; -import com.sap.sailing.gwt.home.client.place.series.TabletAndDesktopSeriesView; import com.sap.sailing.gwt.home.client.place.solutions.SolutionsPlace.SolutionsNavigationTabs; import com.sap.sailing.gwt.home.client.place.solutions.SolutionsView; import com.sap.sailing.gwt.home.client.place.solutions.TabletAndDesktopSolutionsView; @@ -28,12 +15,9 @@ import com.sap.sailing.gwt.home.client.place.sponsoring.SponsoringView; import com.sap.sailing.gwt.home.client.place.sponsoring.TabletAndDesktopSponsoringView; import com.sap.sailing.gwt.home.client.place.start.StartView; import com.sap.sailing.gwt.home.client.place.start.TabletAndDesktopStartView; -import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewView; import com.sap.sailing.gwt.home.client.place.whatsnew.TabletAndDesktopWhatsNewView; import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewPlace.WhatsNewNavigationTabs; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sailing.gwt.ui.shared.RaceGroupDTO; -import com.sap.sse.gwt.client.player.Timer; +import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewView; public class TabletAndDesktopApplicationClientFactory extends AbstractApplicationClientFactory implements ApplicationClientFactory { @@ -46,22 +30,12 @@ public class TabletAndDesktopApplicationClientFactory extends AbstractApplicatio } private TabletAndDesktopApplicationClientFactory(EventBus eventBus, PlaceController placeController) { - super(new TabletAndDesktopApplicationView(new HomePlacesNavigator(placeController)), eventBus, placeController); - } - - @Override - public EventView createEventView(EventDTO event, EventNavigationTabs navigationTab, List raceGroups, String leaderboardName, Timer timerForClientServerOffset) { - return new TabletAndDesktopEventView(getSailingService(), event, navigationTab, raceGroups, leaderboardName, timerForClientServerOffset, getHomePlacesNavigator()); + super(new TabletAndDesktopApplicationView(new HomePlacesNavigator(placeController), eventBus), eventBus, placeController); } @Override public TabletAndDesktopErrorView createErrorView(String errorMessage, Throwable errorReason) { - return new TabletAndDesktopErrorView(errorMessage, errorReason); - } - - @Override - public EventWithoutRegattasView createEventWithoutRegattasView(EventDTO event) { - return new TabletAndDesktopEventWithoutRegattasView(getSailingService(), event, getHomePlacesNavigator()); + return new TabletAndDesktopErrorView(errorMessage, errorReason, null); } @Override @@ -83,16 +57,6 @@ public class TabletAndDesktopApplicationClientFactory extends AbstractApplicatio public SolutionsView createSolutionsView(SolutionsNavigationTabs navigationTab) { return new TabletAndDesktopSolutionsView(navigationTab, getHomePlacesNavigator()); } - - @Override - public RegattaAnalyticsView createRegattaAnalyticsView(EventDTO event, String leaderboardName, RegattaNavigationTabs navigationTab, Timer timerForClientServerOffset) { - return new TabletAndDesktopRegattaView(event, leaderboardName, navigationTab, timerForClientServerOffset, getHomePlacesNavigator()); - } - - @Override - public SeriesAnalyticsView createSeriesAnalyticsView(EventDTO event, String leaderboardName, SeriesNavigationTabs navigationTab, Timer timerForClientServerOffset) { - return new TabletAndDesktopSeriesView(event, leaderboardName, navigationTab, timerForClientServerOffset, getHomePlacesNavigator()); - } @Override public SearchResultView createSearchResultView() { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/TabletAndDesktopApplicationView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/TabletAndDesktopApplicationView.java index 22caa7813be..45482e80fa1 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/TabletAndDesktopApplicationView.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/TabletAndDesktopApplicationView.java @@ -7,6 +7,7 @@ import com.google.gwt.user.client.ui.AcceptsOneWidget; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; +import com.google.web.bindery.event.shared.EventBus; import com.sap.sailing.gwt.home.client.shared.footer.Footer; import com.sap.sailing.gwt.home.client.shared.header.Header; import com.sap.sailing.gwt.ui.client.StringMessages; @@ -34,8 +35,8 @@ public class TabletAndDesktopApplicationView extends Composite implements Applic @UiField SimplePanel mainContentPanel; - public TabletAndDesktopApplicationView(HomePlacesNavigator navigator) { - headerPanel = new Header(navigator); + public TabletAndDesktopApplicationView(HomePlacesNavigator navigator, EventBus eventBus) { + headerPanel = new Header(navigator, eventBus); footerPanel = new Footer(navigator); initWidget(uiBinder.createAndBindUi(this)); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/TabletAndDesktopApplicationView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/TabletAndDesktopApplicationView.ui.xml index c0926ee297e..1120c108018 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/TabletAndDesktopApplicationView.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/TabletAndDesktopApplicationView.ui.xml @@ -1,10 +1,18 @@ - - - - - + xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"> + + + .mainContent { + height: 100%; + } + + + +

+ + +
+ + diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/error/ErrorActivity.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/error/ErrorActivity.java index 189b6a60a33..6a22db60803 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/error/ErrorActivity.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/error/ErrorActivity.java @@ -2,17 +2,46 @@ package com.sap.sailing.gwt.home.client.place.error; import com.google.gwt.activity.shared.AbstractActivity; import com.google.gwt.event.shared.EventBus; +import com.google.gwt.user.client.Command; import com.google.gwt.user.client.ui.AcceptsOneWidget; public class ErrorActivity extends AbstractActivity { + private ErrorPlace currentPlace; + private ErrorClientFactory clientFactory; + public ErrorActivity(ErrorPlace place, ErrorClientFactory clientFactory) { + this.currentPlace = place; + this.clientFactory = clientFactory; } @Override public void start(AcceptsOneWidget panel, EventBus eventBus) { // TODO: the error place should get the error message from the place - panel.setWidget(new TabletAndDesktopErrorView(null, null)); + final TabletAndDesktopErrorView view; + + Command reloadCommand = null; + if (currentPlace.getComingFrom() != null) { + reloadCommand = new Command() { + + @Override + public void execute() { + clientFactory.getPlaceController().goTo(currentPlace.getComingFrom()); + } + }; + } + + if (currentPlace.hasCustomErrorMessages()) { + view = new TabletAndDesktopErrorView( + currentPlace.getErrorMessage(), + currentPlace.getErrorMessageDetail(), + currentPlace.getException(), reloadCommand); + } else { + view = new TabletAndDesktopErrorView(currentPlace.getErrorMessageDetail(), currentPlace.getException(), + reloadCommand); + } + + panel.setWidget(view); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/error/ErrorPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/error/ErrorPlace.java index ce4847ad853..5a7d34443df 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/error/ErrorPlace.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/error/ErrorPlace.java @@ -1,10 +1,62 @@ package com.sap.sailing.gwt.home.client.place.error; +import com.google.gwt.place.shared.Place; import com.google.gwt.place.shared.PlaceTokenizer; import com.sap.sailing.gwt.common.client.AbstractBasePlace; public class ErrorPlace extends AbstractBasePlace { + /** + * Place provided for reload action + */ + private Place comingFrom; + + /** + * Custom error messages + */ + private String errorMessage; + + /** + * Detail error message + */ + private final String errorMessageDetail; + + public ErrorPlace(String errorMessageDetail) { + this.errorMessageDetail = errorMessageDetail; + } + + /** + * Exception ocurred + */ + private Throwable exception; + + public Place getComingFrom() { + return comingFrom; + } + + public void setComingFrom(Place comingFrom) { + this.comingFrom = comingFrom; + } + + public String getErrorMessage() { + return errorMessage; + } + + public String getErrorMessageDetail() { + return errorMessageDetail; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + public Throwable getException() { + return exception; + } + + public void setException(Throwable exception) { + this.exception = exception; + } + public static class Tokenizer implements PlaceTokenizer { @Override public String getToken(ErrorPlace place) { @@ -13,7 +65,12 @@ public class ErrorPlace extends AbstractBasePlace { @Override public ErrorPlace getPlace(String token) { - return new ErrorPlace(); + return new ErrorPlace(""); } } + + public boolean hasCustomErrorMessages() { + + return errorMessage != null && !errorMessage.isEmpty(); + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/error/TabletAndDesktopErrorView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/error/TabletAndDesktopErrorView.java index f36be64b41d..5ab936bf7fa 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/error/TabletAndDesktopErrorView.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/error/TabletAndDesktopErrorView.java @@ -3,6 +3,7 @@ package com.sap.sailing.gwt.home.client.place.error; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.Command; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.gwt.home.client.shared.error.ErrorMessage; @@ -16,9 +17,14 @@ public class TabletAndDesktopErrorView extends Composite implements ErrorView { @UiField(provided=true) ErrorMessage errorMessage; - public TabletAndDesktopErrorView(String errorMessageText, Throwable errorReason) { - errorMessage = new ErrorMessage(errorMessageText, errorReason); - + public TabletAndDesktopErrorView(String errorMessageTextDetail, Throwable errorReason, Command reloadCommand) { + errorMessage = new ErrorMessage(errorMessageTextDetail, errorReason, reloadCommand); + initWidget(uiBinder.createAndBindUi(this)); + } + + public TabletAndDesktopErrorView(String customMessageText, String errorMessageTextDetail, Throwable errorReason, + Command reloadCommand) { + errorMessage = new ErrorMessage(customMessageText, errorMessageTextDetail, errorReason, reloadCommand); initWidget(uiBinder.createAndBindUi(this)); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/AbstractEventActivity.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/AbstractEventActivity.java new file mode 100755 index 00000000000..5a870881991 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/AbstractEventActivity.java @@ -0,0 +1,286 @@ +package com.sap.sailing.gwt.home.client.place.event; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.google.gwt.activity.shared.AbstractActivity; +import com.google.gwt.core.shared.GWT; +import com.google.gwt.place.shared.Place; +import com.google.gwt.safehtml.shared.SafeUri; +import com.google.gwt.safehtml.shared.UriUtils; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; +import com.sap.sailing.domain.common.dto.RaceDTO; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.HomeServiceAsync; +import com.sap.sailing.gwt.home.client.app.ApplicationHistoryMapper; +import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.place.event.regatta.AbstractEventRegattaPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaOverviewPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaRacesPlace; +import com.sap.sailing.gwt.home.client.place.events.EventsPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesDefaultPlace; +import com.sap.sailing.gwt.home.client.place.start.StartPlace; +import com.sap.sailing.gwt.home.client.shared.placeholder.InfoPlaceholder; +import com.sap.sailing.gwt.ui.client.EntryPointLinkFactory; +import com.sap.sailing.gwt.ui.client.SailingServiceAsync; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sailing.gwt.ui.raceboard.RaceBoardViewConfiguration; +import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; +import com.sap.sailing.gwt.ui.shared.RaceGroupDTO; +import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; +import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO; +import com.sap.sailing.gwt.ui.shared.eventview.HasRegattaMetadata; +import com.sap.sailing.gwt.ui.shared.media.MediaDTO; +import com.sap.sse.gwt.client.mvp.ErrorView; +import com.sap.sse.gwt.client.player.Timer; +import com.sap.sse.gwt.client.player.Timer.PlayModes; + +public abstract class AbstractEventActivity extends AbstractActivity implements + EventView.Presenter { + + protected final PLACE currentPlace; + + protected final EventContext ctx; + + protected final EventClientFactory clientFactory; + + private final Timer timerForClientServerOffset; + + protected final HomePlacesNavigator homePlacesNavigator; + + private static final ApplicationHistoryMapper historyMapper = GWT.create(ApplicationHistoryMapper.class); + + public AbstractEventActivity(PLACE place, EventClientFactory clientFactory, HomePlacesNavigator homePlacesNavigator) { + this.currentPlace = place; + this.homePlacesNavigator = homePlacesNavigator; + this.ctx = new EventContext(place.getCtx()); + this.timerForClientServerOffset = new Timer(PlayModes.Replay); + this.clientFactory = clientFactory; + } + + public HomeServiceAsync getHomeService() { + return clientFactory.getHomeService(); + } + + public SailingServiceAsync getSailingService() { + return clientFactory.getSailingService(); + } + + @Override + public EventContext getCtx() { + return ctx; + } + + @Override + public void handleTabPlaceSelection(TabView selectedActivity) { + Place tabPlaceToGo = selectedActivity.placeToFire(); + clientFactory.getPlaceController().goTo(tabPlaceToGo); + } + + public void navigateTo(Place place) { + clientFactory.getPlaceController().goTo(place); + } + + @Override + public SafeUri getUrl(AbstractEventPlace place) { + String token = historyMapper.getToken(place); + return UriUtils.fromString("#" + token); + } + + @Override + public HasRegattaMetadata getRegattaMetadata() { + return ctx.getRegatta(); + } + + @Override + public Timer getTimerForClientServerOffset() { + return timerForClientServerOffset; + } + + @Override + public AbstractEventRegattaPlace getPlaceForRegatta(String regattaId) { + return new RegattaOverviewPlace(contextForRegatta(regattaId)); + } + + @Override + public RegattaRacesPlace getPlaceForRegattaRaces(String regattaId) { + return new RegattaRacesPlace(contextForRegatta(regattaId)); + } + + protected EventContext contextForRegatta(String regattaId) { + return new EventContext(ctx).withRegattaId(regattaId); + } + + public String getRaceViewerURL(StrippedLeaderboardDTO leaderboard, RaceDTO race) { + RegattaAndRaceIdentifier raceIdentifier = race.getRaceIdentifier(); + return EntryPointLinkFactory + .createRaceBoardLink(createRaceBoardLinkParameters(leaderboard.name, raceIdentifier)); + } + + private Map createRaceBoardLinkParameters(String leaderboardName, + RegattaAndRaceIdentifier raceIdentifier) { + Map linkParams = new HashMap(); + linkParams.put("eventId", ctx.getEventId()); + linkParams.put("leaderboardName", leaderboardName); + linkParams.put("raceName", raceIdentifier.getRaceName()); + // TODO this must only be forwarded if there is a logged-on user + // linkParams.put(RaceBoardViewConfiguration.PARAM_CAN_REPLAY_DURING_LIVE_RACES, "true"); + linkParams.put(RaceBoardViewConfiguration.PARAM_VIEW_SHOW_MAPCONTROLS, "true"); + linkParams.put(RaceBoardViewConfiguration.PARAM_VIEW_SHOW_NAVIGATION_PANEL, "true"); + linkParams.put("regattaName", raceIdentifier.getRegattaName()); + return linkParams; + } + + @Override + public PlaceNavigation getHomeNavigation() { + return homePlacesNavigator.getHomeNavigation(); + } + + @Override + public PlaceNavigation getEventsNavigation() { + return homePlacesNavigator.getEventsNavigation(); + } + + @Override + public PlaceNavigation getCurrentEventNavigation() { + return homePlacesNavigator.getEventNavigation(ctx.getEventId(), null, false); + } + + @Override + public PlaceNavigation getCurrentEventSeriesNavigation() { + return homePlacesNavigator.getEventSeriesNavigation(ctx.getEventId(), null, false); + } + + @Override + public PlaceNavigation getRegattaRacesNavigation(String regattaId) { + return homePlacesNavigator.getEventNavigation(getPlaceForRegattaRaces(regattaId), null, false); + } + + @Override + public PlaceNavigation getRegattaNavigation(String regattaId) { + return homePlacesNavigator.getEventNavigation(getPlaceForRegatta(regattaId), null, false); + } + + @Override + public void ensureRegattaStructure(final AsyncCallback> callback) { + if (ctx.getRaceGroups() != null) { + callback.onSuccess(ctx.getRaceGroups()); + return; + } + + final EventViewDTO eventDTO = ctx.getEventDTO(); + + ensureLeaderboardGroups(new AsyncCallback>() { + @Override + public void onSuccess(final List leaderboardGroups) { + final long clientTimeWhenRequestWasSent = System.currentTimeMillis(); + + getSailingService().getRegattaStructureOfEvent(eventDTO.getId(), + new AsyncCallback>() { + @Override + public void onSuccess(List raceGroups) { + if (raceGroups.size() > 0) { + for (LeaderboardGroupDTO leaderboardGroupDTO : leaderboardGroups) { + final long clientTimeWhenResponseWasReceived = System.currentTimeMillis(); + if (leaderboardGroupDTO.getAverageDelayToLiveInMillis() != null) { + timerForClientServerOffset.setLivePlayDelayInMillis(leaderboardGroupDTO + .getAverageDelayToLiveInMillis()); + } + timerForClientServerOffset.adjustClientServerOffset(clientTimeWhenRequestWasSent, + leaderboardGroupDTO.getCurrentServerTime(), clientTimeWhenResponseWasReceived); + } + ctx.withRaceGroups(raceGroups); + callback.onSuccess(raceGroups); + } else { + getView().showErrorInCurrentTab(new InfoPlaceholder(StringMessages.INSTANCE.noDataForEvent())); + } + } + + @Override + public void onFailure(Throwable caught) { + // TODO @FM: extract error message + ErrorView errorView = clientFactory.createErrorView( + "Error while loading the regatta structure with service getRegattaStructureOfEvent()", caught); + getView().showErrorInCurrentTab(errorView); + // TODO: notify callback of failure? + // callback.onFailure(caught); + + } + }); + } + @Override + public void onFailure(Throwable caught) { + } + }); + } + + @Override + public void ensureLeaderboardGroups(final AsyncCallback> callback) { + if (ctx.getLeaderboardGroups() != null) { + callback.onSuccess(ctx.getLeaderboardGroups()); + return; + } + + final EventViewDTO eventDTO = ctx.getEventDTO(); + + getSailingService().getLeaderboardGroupsByEventId(eventDTO.getId(), + new AsyncCallback>() { + @Override + public void onSuccess(ArrayList leaderboardGroups) { + ctx.withLeaderboardGroups(leaderboardGroups); + callback.onSuccess(leaderboardGroups); + } + + @Override + public void onFailure(Throwable caught) { + // TODO @FM: extract error message + ErrorView errorView = clientFactory.createErrorView( + "Error while loading the leaderboard structure with service getLeaderboardGroupsByEventId()", caught); + getView().showErrorInCurrentTab(errorView); + // TODO: notify callback of failure? + // callback.onFailure(caught); + + } + }); + } + + @Override + public void ensureMedia(final AsyncCallback callback) { + if (ctx.getMedia() != null) { + callback.onSuccess(ctx.getMedia()); + return; + } + + getHomeService().getMediaForEvent(ctx.getEventDTO().getId(), new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + // TODO @FM: extract error message + ErrorView errorView = clientFactory.createErrorView("Load media failure for event", caught); + getView().showErrorInCurrentTab(errorView); + // TODO: notify callback of failure? + // callback.onFailure(caught); + } + + @Override + public void onSuccess(MediaDTO result) { + ctx.withMedia(result); + callback.onSuccess(result); + } + }); + } + + @Override + public boolean hasMedia() { + if (showRegattaMetadata()) { + return false; + } + return ctx.getEventDTO().isHasMedia(); + } + + protected abstract EventView getView(); + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/AbstractEventComposite.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/AbstractEventComposite.java deleted file mode 100644 index 26e4eac4649..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/AbstractEventComposite.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event; - -import com.google.gwt.user.client.ui.Composite; -import com.sap.sailing.gwt.ui.shared.EventDTO; - -/** - * A base class for a content composite related to an sailing event - * @author Frank - * - */ -public class AbstractEventComposite extends Composite { - private final EventDTO event; - private final EventPlaceNavigator pageNavigator; - - public AbstractEventComposite(EventDTO event, EventPlaceNavigator pageNavigator) { - this.event = event; - this.pageNavigator = pageNavigator; - } - - public EventDTO getEvent() { - return event; - } - - public EventPlaceNavigator getPageNavigator() { - return pageNavigator; - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/AbstractEventPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/AbstractEventPlace.java new file mode 100755 index 00000000000..2605c5b1e9b --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/AbstractEventPlace.java @@ -0,0 +1,58 @@ +package com.sap.sailing.gwt.home.client.place.event; + +import java.util.HashMap; +import java.util.Map; + +import com.google.gwt.place.shared.Place; +import com.sap.sailing.gwt.common.client.AbstractMapTokenizer; +import com.sap.sailing.gwt.common.client.i18n.TextMessages; +import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO.EventType; + +public abstract class AbstractEventPlace extends Place { + private final EventContext ctx; + + protected AbstractEventPlace(EventContext ctx) { + this.ctx = ctx; + } + + public EventContext getCtx() { + return ctx; + } + + public AbstractEventPlace(String eventUuidAsString) { + this.ctx = new EventContext(); + ctx.withId(eventUuidAsString); + } + + public String getTitle(String eventName) { + return TextMessages.INSTANCE.sapSailing() + " - " + eventName; + } + + public String getEventUuidAsString() { + return ctx.getEventId(); + } + + public String getRegattaId() { + return ctx.getRegattaId(); + } + + public static abstract class Tokenizer extends AbstractMapTokenizer { + private final static String PARAM_EVENTID = "eventId"; + private final static String PARAM_REGATTAID = "regattaId"; + protected PLACE getPlaceFromParameters(Map parameters) { + return getRealPlace(new EventContext().withId(parameters.get(PARAM_EVENTID)).withRegattaId(parameters.get(PARAM_REGATTAID))); + } + + protected Map getParameters(PLACE place) { + Map parameters = new HashMap<>(); + EventContext context = place.getCtx(); + parameters.put(PARAM_EVENTID, context.getEventId()); + if(context.getEventDTO() == null || context.getEventDTO().getType() == EventType.MULTI_REGATTA) { + parameters.put(PARAM_REGATTAID, context.getRegattaId()); + } + return parameters; + } + + protected abstract PLACE getRealPlace(EventContext context); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventActivity.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventActivity.java deleted file mode 100755 index 655932ccbca..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventActivity.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event; - -import java.util.Date; -import java.util.List; -import java.util.UUID; - -import com.google.gwt.activity.shared.AbstractActivity; -import com.google.gwt.event.shared.EventBus; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.rpc.AsyncCallback; -import com.google.gwt.user.client.ui.AcceptsOneWidget; -import com.sap.sailing.gwt.home.client.shared.placeholder.Placeholder; -import com.sap.sailing.gwt.ui.regattaoverview.RegattaRaceStatesSettings; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; -import com.sap.sailing.gwt.ui.shared.RaceGroupDTO; -import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO; -import com.sap.sse.gwt.client.async.MarkedAsyncCallback; -import com.sap.sse.gwt.client.mvp.ErrorView; -import com.sap.sse.gwt.client.player.TimeListener; -import com.sap.sse.gwt.client.player.Timer; -import com.sap.sse.gwt.client.player.Timer.PlayModes; - -public class EventActivity extends AbstractActivity { - private final EventClientFactory clientFactory; - - private final EventPlace eventPlace; - private final Timer timerForClientServerOffset; - - private final long serverUpdateRateInMs = 10000; - private final Timer serverUpdateTimer; - private final RegattaRaceStatesSettings raceStatesSettings; - - private EventView view; - private EventDTO event; - - public EventActivity(EventPlace place, EventClientFactory clientFactory) { - this.clientFactory = clientFactory; - this.eventPlace = place; - - this.view = null; - this.event = null; - - timerForClientServerOffset = new Timer(PlayModes.Replay); - serverUpdateTimer = new Timer(PlayModes.Live, serverUpdateRateInMs); - - raceStatesSettings = new RegattaRaceStatesSettings(); - } - - @Override - public void start(final AcceptsOneWidget panel, final EventBus eventBus) { - panel.setWidget(new Placeholder()); - - final long clientTimeWhenRequestWasSent = System.currentTimeMillis(); - try { - final UUID eventUUID = UUID.fromString(eventPlace.getEventUuidAsString()); - clientFactory.getSailingService().getEventById(eventUUID, true, new AsyncCallback() { - @Override - public void onSuccess(final EventDTO event) { - if(event != null) { - loadRegattaStructureAndCreateEventView(panel, clientTimeWhenRequestWasSent, event); - } else { - createErrorView("No such event with UUID " + eventUUID, null, panel); - } - } - - @Override - public void onFailure(Throwable caught) { - createErrorView("Error while loading the event with service getEventById()", caught, panel); - } - }); - } catch (IllegalArgumentException e) { - createErrorView("Could not parse a valid UUID from the parameter 'eventID'.", null, panel); - } - } - - private void loadRegattaStructureAndCreateEventView(final AcceptsOneWidget panel, final long clientTimeWhenRequestWasSent, final EventDTO event) { - this.event = event; - - if(event.getLeaderboardGroups().size() > 0) { - clientFactory.getSailingService().getRegattaStructureOfEvent(event.id, new AsyncCallback>() { - @Override - public void onSuccess(List raceGroups) { - if(raceGroups.size() > 0) { - for(LeaderboardGroupDTO leaderboardGroupDTO: event.getLeaderboardGroups()) { - final long clientTimeWhenResponseWasReceived = System.currentTimeMillis(); - if (leaderboardGroupDTO.getAverageDelayToLiveInMillis() != null) { - timerForClientServerOffset.setLivePlayDelayInMillis(leaderboardGroupDTO.getAverageDelayToLiveInMillis()); - } - timerForClientServerOffset.adjustClientServerOffset(clientTimeWhenRequestWasSent, leaderboardGroupDTO.getCurrentServerTime(), clientTimeWhenResponseWasReceived); - } - createEventView(event, raceGroups, panel); - - if(event.isRunning()) { - // create update time for race states only for running events - serverUpdateTimer.addTimeListener(new TimeListener() { - @Override - public void timeChanged(Date newTime, Date oldTime) { - loadAndUpdateEventRaceStatesLog(); - } - }); - } - - } else { - createEventWithoutRegattasView(event, panel); - } - } - - @Override - public void onFailure(Throwable caught) { - createErrorView("Error while loading the regatta structure with service getRegattaStructureOfEvent()", caught, panel); - } - }); - } else { - createEventWithoutRegattasView(event, panel); - } - } - - private void createErrorView(String errorMessage, Throwable errorReason, AcceptsOneWidget panel) { - ErrorView view = clientFactory.createErrorView(errorMessage, errorReason); - panel.setWidget(view.asWidget()); - } - - private void createEventView(EventDTO event, List raceGroups, AcceptsOneWidget panel) { - view = clientFactory.createEventView(event, eventPlace.getNavigationTab(), raceGroups, eventPlace.getLeaderboardIdAsNameString(), timerForClientServerOffset); - panel.setWidget(view.asWidget()); - Window.setTitle(eventPlace.getTitle(event.getName())); - } - - private void createEventWithoutRegattasView(EventDTO event, AcceptsOneWidget panel) { - // no leaderboard groups defined yet -> show a teaser page - EventWithoutRegattasView view = clientFactory.createEventWithoutRegattasView(event); - panel.setWidget(view.asWidget()); - Window.setTitle(eventPlace.getTitle(event.getName())); - } - - protected void loadAndUpdateEventRaceStatesLog() { - if(view != null && event != null) { - final long clientTimeWhenRequestWasSent = System.currentTimeMillis(); - - clientFactory.getSailingService().getRaceStateEntriesForRaceGroup(event.id, raceStatesSettings.getVisibleCourseAreas(), - raceStatesSettings.getVisibleRegattas(), raceStatesSettings.isShowOnlyCurrentlyRunningRaces(), raceStatesSettings.isShowOnlyRacesOfSameDay(), - new MarkedAsyncCallback>( - new AsyncCallback>() { - @Override - public void onFailure(Throwable cause) { - Window.setStatus("Error while loading the race states with service getRaceStateEntriesForRaceGroup()"); - } - - @Override - public void onSuccess(List result) { - final long clientTimeWhenResponseWasReceived = System.currentTimeMillis(); - Date serverTimeDuringRequest = null; - for (RegattaOverviewEntryDTO entryDTO : result) { - if (entryDTO.currentServerTime != null) { - serverTimeDuringRequest = entryDTO.currentServerTime; - } - } - view.updateEventRaceStates(result); - timerForClientServerOffset.adjustClientServerOffset(clientTimeWhenRequestWasSent, serverTimeDuringRequest, clientTimeWhenResponseWasReceived); - } - })); - } - } - -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventActivityProxy.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventActivityProxy.java old mode 100755 new mode 100644 index 3773caba152..be0dc64d40e --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventActivityProxy.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventActivityProxy.java @@ -1,25 +1,138 @@ package com.sap.sailing.gwt.home.client.place.event; +import java.util.UUID; + import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; +import com.sap.sailing.gwt.home.client.place.error.ErrorPlace; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.AbstractMultiregattaEventPlace; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaActivity; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs.MultiregattaMediaPlace; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs.MultiregattaOverviewPlace; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs.MultiregattaRegattasPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.AbstractEventRegattaPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.EventRegattaActivity; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaLeaderboardPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaMediaPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaOverviewPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaRacesPlace; +import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO; +import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO.EventType; import com.sap.sse.gwt.client.mvp.AbstractActivityProxy; public class EventActivityProxy extends AbstractActivityProxy { - private final EventClientFactory clientFactory; - private final EventPlace place; + private AbstractEventPlace place; + private EventContext ctx; + private EventClientFactory clientFactory; + private HomePlacesNavigator homePlacesNavigator; - public EventActivityProxy(EventPlace place, EventClientFactory clientFactory) { + public EventActivityProxy(AbstractEventPlace place, EventClientFactory clientFactory, + HomePlacesNavigator homePlacesNavigator) { this.place = place; + this.homePlacesNavigator = homePlacesNavigator; + this.ctx = this.place.getCtx(); this.clientFactory = clientFactory; } @Override protected void startAsync() { + if (ctx.getEventDTO() != null) { + afterEventLoad(); + } else { + final UUID eventUUID = UUID.fromString(ctx.getEventId()); + + clientFactory.getHomeService().getEventViewById(eventUUID, new AsyncCallback() { + @Override + public void onSuccess(final EventViewDTO event) { + ctx.updateContext(event); + afterEventLoad(); + } + + @Override + public void onFailure(Throwable caught) { + // TODO @FM: extract text? + ErrorPlace errorPlace = new ErrorPlace("Error while loading the event with service getEventViewById()"); + // TODO @FM: reload sinnvoll hier? + errorPlace.setComingFrom(place); + clientFactory.getPlaceController().goTo(errorPlace); + } + }); + + } + } + + private void afterEventLoad() { + if(place instanceof EventDefaultPlace) { + place = getRealPlace(); + } + place = verifyAndAdjustPlace(); + afterLoad(); + } + + private void afterLoad() { GWT.runAsync(new AbstractRunAsyncCallback() { @Override public void onSuccess() { - super.onSuccess(new EventActivity(place, clientFactory)); + if(place instanceof AbstractEventRegattaPlace) { + super.onSuccess(new EventRegattaActivity((AbstractEventRegattaPlace) place, clientFactory, + homePlacesNavigator)); + } + if(place instanceof AbstractMultiregattaEventPlace) { + super.onSuccess(new EventMultiregattaActivity((AbstractMultiregattaEventPlace) place, + clientFactory, homePlacesNavigator)); + } } }); } + + private AbstractEventPlace getRealPlace() { + EventViewDTO event = ctx.getEventDTO(); + + if(event.getType() == EventType.SERIES_EVENT || event.getType() == EventType.SINGLE_REGATTA) { + if (event.isFinished()) { + return new RegattaLeaderboardPlace(new EventContext(ctx).withRegattaId(null)); + } else { + return new RegattaOverviewPlace(new EventContext(ctx).withRegattaId(null)); + } + } + return new MultiregattaOverviewPlace(place.getCtx()); + } + + /** + * Checks if the place is valid for the given event. + * If not, the place is automatically being adjusted. + */ + private AbstractEventPlace verifyAndAdjustPlace() { + EventContext contextWithoutRegatta = new EventContext(ctx).withRegattaId(null); + // TODO check if regatta ID is valid + if(place instanceof AbstractMultiregattaEventPlace && ctx.getEventDTO().getType() != EventType.MULTI_REGATTA) { + // Events with a type other than multi regatta only have regatta level pages + if(place instanceof MultiregattaRegattasPlace) { + return new RegattaRacesPlace(contextWithoutRegatta); + } + if(place instanceof MultiregattaMediaPlace) { + return new RegattaMediaPlace(contextWithoutRegatta); + } + return new RegattaOverviewPlace(contextWithoutRegatta); + } + + if(place instanceof AbstractEventRegattaPlace) { + boolean regattaKnown = ctx.getEventDTO().isRegattaIDKnown(ctx.getRegattaId()); + if(ctx.getEventDTO().getType() != EventType.MULTI_REGATTA && ctx.getRegattaId() != null && !regattaKnown) { + // Regatta ID unknown but unnecessary ... + ctx.withRegattaId(null); + } else if(ctx.getEventDTO().getType() == EventType.MULTI_REGATTA && !regattaKnown) { + return new MultiregattaRegattasPlace(contextWithoutRegatta); + } + } + + if(place instanceof RegattaMediaPlace && ctx.getEventDTO().getType() == EventType.MULTI_REGATTA) { + // The media page for multi regatta events is on event level only but not on regatta level + return new MultiregattaMediaPlace(new EventContext(ctx).withRegattaId(null)); + } + // no adjustment necessary + return place; + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventClientFactory.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventClientFactory.java index 0b84acfc123..698ef275bc9 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventClientFactory.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventClientFactory.java @@ -1,15 +1,6 @@ package com.sap.sailing.gwt.home.client.place.event; -import java.util.List; - -import com.sap.sailing.gwt.home.client.place.event.EventPlace.EventNavigationTabs; import com.sap.sailing.gwt.ui.client.SailingClientFactory; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sailing.gwt.ui.shared.RaceGroupDTO; -import com.sap.sse.gwt.client.player.Timer; public interface EventClientFactory extends SailingClientFactory { - EventView createEventView(EventDTO event, EventNavigationTabs navigationTab, List raceGroups, String leaderboardName, Timer timerForClientServerOffset); - - EventWithoutRegattasView createEventWithoutRegattasView(EventDTO event); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventContext.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventContext.java new file mode 100644 index 00000000000..6e5e81df66e --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventContext.java @@ -0,0 +1,132 @@ +package com.sap.sailing.gwt.home.client.place.event; + +import java.util.List; + +import com.sap.sailing.gwt.home.client.place.event.regatta.RegattaAnalyticsDataManager; +import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; +import com.sap.sailing.gwt.ui.shared.RaceGroupDTO; +import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO; +import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO.EventType; +import com.sap.sailing.gwt.ui.shared.eventview.RegattaMetadataDTO; +import com.sap.sailing.gwt.ui.shared.media.MediaDTO; + +/** + * Common context used by the different tabs in the event place. + * + * @author pgtaboada + * + */ +public class EventContext { + private String eventId; + private String regattaId; + private List raceGroups; + private List leaderboardGroups; + private RegattaAnalyticsDataManager regattaAnalyticsManager; + + /** + * Common state required by all tabs/ places in event + */ + private EventViewDTO eventDTO; + private MediaDTO media; + + public EventContext() { + } + + public EventContext(EventContext ctx) { + updateContext(ctx.getEventDTO()); + withRaceGroups(ctx.raceGroups); + withLeaderboardGroups(ctx.leaderboardGroups); + withMedia(ctx.media); + withRegattaId(ctx.regattaId); + withRegattaAnalyticsManager(ctx.regattaAnalyticsManager); + } + + public EventContext withId(String eventId) { + this.eventId = eventId; + return this; + } + + public EventContext withRegattaId(String regattaId) { + this.regattaId = regattaId; + return this; + } + + /** + * Used to update context with dto instance + */ + public EventContext updateContext(EventViewDTO dto) { + this.eventDTO = dto; + if (eventDTO == null) { + withId(null); + } else { + withId(dto.getId().toString()); + } + return this; + } + + public EventViewDTO getEventDTO() { + return eventDTO; + } + + public String getEventId() { + return eventId; + } + + public String getRegattaId() { + if(regattaId != null) { + return regattaId; + } + if(eventDTO != null && (eventDTO.getType() == EventType.SINGLE_REGATTA || eventDTO.getType() == EventType.SERIES_EVENT)) { + return eventDTO.getRegattas().get(0).getDisplayName(); + } + return null; + } + + public RegattaMetadataDTO getRegatta() { + if(regattaId == null || eventDTO == null) { + return null; + } + for (RegattaMetadataDTO regatta : eventDTO.getRegattas()) { + if(regattaId.equals(regatta.getId())) { + return regatta; + } + } + return null; + } + + public List getRaceGroups() { + return raceGroups; + } + + public EventContext withRaceGroups(List raceGroups) { + this.raceGroups = raceGroups; + return this; + } + + public List getLeaderboardGroups() { + return leaderboardGroups; + } + + public EventContext withLeaderboardGroups(List leaderboardGroups) { + this.leaderboardGroups = leaderboardGroups; + return this; + } + + public RegattaAnalyticsDataManager getRegattaAnalyticsManager() { + return regattaAnalyticsManager; + } + + public EventContext withRegattaAnalyticsManager(RegattaAnalyticsDataManager regattaAnalyticsManager) { + this.regattaAnalyticsManager = regattaAnalyticsManager; + return this; + } + + public MediaDTO getMedia() { + return media; + } + + public EventContext withMedia(MediaDTO mediaDTO) { + this.media = mediaDTO; + return this; + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventDefaultPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventDefaultPlace.java new file mode 100644 index 00000000000..b942e541316 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventDefaultPlace.java @@ -0,0 +1,22 @@ +package com.sap.sailing.gwt.home.client.place.event; + +import com.google.gwt.place.shared.Prefix; + +public class EventDefaultPlace extends AbstractEventPlace { + + public EventDefaultPlace(EventContext ctx) { + super(ctx); + } + + public EventDefaultPlace(String eventUuidAsString) { + super(eventUuidAsString); + } + + @Prefix(EventPrefixes.EventDefault) + public static class Tokenizer extends AbstractEventPlace.Tokenizer { + @Override + protected EventDefaultPlace getRealPlace(EventContext context) { + return new EventDefaultPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventPlaceNavigator.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventPlaceNavigator.java deleted file mode 100644 index f3f33b0ec56..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventPlaceNavigator.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event; - -import com.sap.sailing.domain.common.dto.RaceDTO; -import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; -import com.sap.sailing.gwt.ui.shared.RaceGroupDTO; -import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; - -public interface EventPlaceNavigator { - void goToOverview(); - void goToRegattas(); - void goToSchedule(); - void goToMedia(); - void goToRegattaRaces(LeaderboardGroupDTO leaderboardGroup, StrippedLeaderboardDTO leaderboard, RaceGroupDTO raceGroup); - String getRaceViewerURL(StrippedLeaderboardDTO leaderboard, RaceDTO race); - void openOverallLeaderboardViewer(LeaderboardGroupDTO leaderboardGroup); - void openLeaderboardViewer(LeaderboardGroupDTO leaderboardGroup, StrippedLeaderboardDTO leaderboard); -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventPrefixes.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventPrefixes.java new file mode 100644 index 00000000000..4ee6f8f7556 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventPrefixes.java @@ -0,0 +1,22 @@ +package com.sap.sailing.gwt.home.client.place.event; + + +public class EventPrefixes { + + public static final String EventDefault = "/event/"; + public static final String MultiregattaOverview = "/multiregatta/overview/"; + public static final String MultiregattaRegattas = "/multiregatta/regattas/"; + public static final String MultiregattaMedia = "/multiregatta/media/"; + public static final String RegattaOverview = "/regatta/overview/"; + public static final String RegattaRaces = "/regatta/races/"; + public static final String RegattaLeaderboard = "/regatta/leaderboard/"; + public static final String RegattaCompetitorAnalytics = "/regatta/competitoranalytics/"; + public static final String RegattaMedia = "/regatta/media/"; + public static final String SeriesDefault = "/series/"; + public static final String SeriesOverview = "/series/overview/"; + public static final String SeriesEvents = "/series/events/"; + public static final String EventSeriesCompetitorAnalytics = "/series/competitoranalytics/"; + public static final String EventSeriesOverallLeaderboard = "/series/overallleaderboard/"; + public static final String EventSeriesLeaderboards = "/series/leaderboards/"; + public static final String EventSeriesMedia = "/series/media/"; +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventView.java index 19d2679f743..a8018b466ac 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventView.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventView.java @@ -2,11 +2,83 @@ package com.sap.sailing.gwt.home.client.place.event; import java.util.List; -import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO; +import com.google.gwt.place.shared.Place; +import com.google.gwt.safehtml.shared.SafeUri; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.IsWidget; +import com.sap.sailing.domain.common.dto.RaceDTO; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.HomeServiceAsync; +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.place.event.regatta.AbstractEventRegattaPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaRacesPlace; +import com.sap.sailing.gwt.home.client.place.events.EventsPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesDefaultPlace; +import com.sap.sailing.gwt.home.client.place.start.StartPlace; +import com.sap.sailing.gwt.ui.client.SailingServiceAsync; +import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; +import com.sap.sailing.gwt.ui.shared.RaceGroupDTO; +import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; +import com.sap.sailing.gwt.ui.shared.eventview.HasRegattaMetadata; +import com.sap.sailing.gwt.ui.shared.media.MediaDTO; +import com.sap.sse.gwt.client.player.Timer; -public interface EventView { - Widget asWidget(); +public interface EventView extends IsWidget { + + public interface Presenter { + EventContext getCtx(); + + void handleTabPlaceSelection(TabView selectedActivity); + + SafeUri getUrl(AbstractEventPlace place); + void navigateTo(Place place); + boolean needsSelectionInHeader(); + void forPlaceSelection(PlaceCallback callback); + Timer getTimerForClientServerOffset(); + SailingServiceAsync getSailingService(); + HomeServiceAsync getHomeService(); + + AbstractEventRegattaPlace getPlaceForRegatta(String regattaId); + AbstractEventRegattaPlace getPlaceForRegattaRaces(String regattaId); + + PlaceNavigation getHomeNavigation(); + PlaceNavigation getEventsNavigation(); + PlaceNavigation getCurrentEventNavigation(); + PlaceNavigation getCurrentEventSeriesNavigation(); + + boolean showRegattaMetadata(); + HasRegattaMetadata getRegattaMetadata(); + + String getRaceViewerURL(StrippedLeaderboardDTO leaderboard, RaceDTO race); + + PlaceNavigation getRegattaRacesNavigation(String regattaName); + PlaceNavigation getRegattaNavigation(String regattaName); + + void ensureRegattaStructure(AsyncCallback> callback); + void ensureLeaderboardGroups(AsyncCallback> callback); + void ensureMedia(AsyncCallback asyncCallback); + + boolean hasMedia(); + } - void updateEventRaceStates(List racesStateEntries); + public interface PlaceCallback { + void forPlace(AbstractEventPlace place, String title, boolean active); + } + + /** + * This is the presenter the view can talk to. + * + * @param currentPresenter + */ + void registerPresenter(PRES currentPresenter); + + /** + * Tell the view to process tabbar place navigation + * + * @param place + */ + void navigateTabsTo(PLACE place); + + void showErrorInCurrentTab(IsWidget errorView); + } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventWithoutRegattasView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventWithoutRegattasView.java deleted file mode 100644 index 24eacd20417..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventWithoutRegattasView.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event; - -import com.google.gwt.user.client.ui.Widget; - -public interface EventWithoutRegattasView { - Widget asWidget(); -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/TabletAndDesktopEventView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/TabletAndDesktopEventView.java deleted file mode 100644 index 8f063bd1395..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/TabletAndDesktopEventView.java +++ /dev/null @@ -1,223 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.domain.common.LeaderboardNameConstants; -import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; -import com.sap.sailing.domain.common.dto.RaceDTO; -import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; -import com.sap.sailing.gwt.home.client.place.event.EventPlace.EventNavigationTabs; -import com.sap.sailing.gwt.home.client.place.event.header.EventHeader; -import com.sap.sailing.gwt.home.client.place.event.media.EventMedia; -import com.sap.sailing.gwt.home.client.place.event.overview.EventOverview; -import com.sap.sailing.gwt.home.client.place.event.regattalist.EventRegattaList; -import com.sap.sailing.gwt.home.client.place.event.regattaraces.EventRegattaRaces; -import com.sap.sailing.gwt.home.client.place.event.schedule.EventSchedule; -import com.sap.sailing.gwt.home.client.shared.eventsponsors.EventSponsors; -import com.sap.sailing.gwt.ui.client.EntryPointLinkFactory; -import com.sap.sailing.gwt.ui.client.SailingServiceAsync; -import com.sap.sailing.gwt.ui.raceboard.RaceBoardViewConfiguration; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; -import com.sap.sailing.gwt.ui.shared.RaceGroupDTO; -import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO; -import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; -import com.sap.sse.common.Util.Triple; -import com.sap.sse.gwt.client.player.Timer; - -public class TabletAndDesktopEventView extends Composite implements EventView, EventPlaceNavigator { - private static EventViewUiBinder uiBinder = GWT.create(EventViewUiBinder.class); - - interface EventViewUiBinder extends UiBinder { - } - - @UiField(provided=true) EventHeader eventHeader; - @UiField(provided=true) EventOverview eventOverview; - @UiField(provided=true) EventSchedule eventSchedule; - @UiField(provided=true) EventMedia eventMedia; - @UiField(provided=true) EventRegattaList eventRegattaList; - @UiField(provided=true) EventRegattaRaces eventRegattaRaces; - - @UiField EventSponsors eventSponsors; - - private final List pageElements; - private final EventDTO event; - - @SuppressWarnings("unused") - private EventPlace currentInternalPlace; - - public TabletAndDesktopEventView(SailingServiceAsync sailingService, EventDTO event, EventNavigationTabs navigationTab, List raceGroups, String leaderboardName, - Timer timerForClientServerOffset, HomePlacesNavigator navigator) { - this.event = event; - Map> regattaStructure = getRegattaStructure(event, raceGroups); - - eventHeader = new EventHeader(event, navigator, this); - eventRegattaList = new EventRegattaList(event, regattaStructure, timerForClientServerOffset, navigator, this); - eventRegattaRaces = new EventRegattaRaces(event, timerForClientServerOffset, navigator, this); - eventOverview = new EventOverview(event, this); - eventSchedule = new EventSchedule(event, this); - eventMedia = new EventMedia(event, this); - - initWidget(uiBinder.createAndBindUi(this)); - - pageElements = Arrays.asList(new Widget[] { eventOverview, eventRegattaList, eventRegattaRaces, eventMedia, eventSchedule }); - - Triple selectedRegatta = null; - if(leaderboardName != null) { - selectedRegatta = regattaStructure.get(leaderboardName); - } - - // in case we only have one regatta/leaderboard we go directly to the 'races' page - if(selectedRegatta == null && regattaStructure.size() == 1) { - selectedRegatta = regattaStructure.get(0); - } - - if(selectedRegatta != null && (navigationTab == EventNavigationTabs.Regatta || !event.isFakeSeries())) { - goToRegattaRaces(selectedRegatta.getC(), selectedRegatta.getB(), selectedRegatta.getA()); - } else { - goToRegattas(); - } - if(event.getSponsorImageURLs() != null && event.getSponsorImageURLs().size() > 0) { - eventSponsors.setVisible(false); - eventSponsors.setEventSponsors(event.getSponsorImageURLs()); - } else { - eventSponsors.setVisible(false); - eventSponsors.setEventSponsors(null); - } - } - - @Override - public void updateEventRaceStates(List racesStateEntries) { - - } - - @Override - public void goToOverview() { - setVisibleEventElement(eventOverview); - eventHeader.setFullsizeHeader(); - - currentInternalPlace = new EventPlace(event.id.toString(), EventNavigationTabs.Overview, null); - } - - @Override - public void goToRegattas() { - setVisibleEventElement(eventRegattaList); - eventHeader.setFullsizeHeader(); - - currentInternalPlace = new EventPlace(event.id.toString(), EventNavigationTabs.Regattas, null); - } - - @Override - public void goToRegattaRaces(LeaderboardGroupDTO leaderboardGroup, StrippedLeaderboardDTO leaderboard, RaceGroupDTO raceGroup) { - eventRegattaRaces.setRaces(leaderboardGroup, false, leaderboard, raceGroup); - eventHeader.setCompactHeader(); - setVisibleEventElement(eventRegattaRaces); - - currentInternalPlace = new EventPlace(event.id.toString(), EventNavigationTabs.Regatta, leaderboard.name); - } - - @Override - public void goToSchedule() { - setVisibleEventElement(eventSchedule); - eventHeader.setFullsizeHeader(); - - currentInternalPlace = new EventPlace(event.id.toString(), EventNavigationTabs.Schedule, null); - } - - @Override - public void goToMedia() { - setVisibleEventElement(eventMedia); - eventHeader.setFullsizeHeader(); - - currentInternalPlace = new EventPlace(event.id.toString(), EventNavigationTabs.Media, null); - } - - public String getRaceViewerURL(StrippedLeaderboardDTO leaderboard, RaceDTO race) { - RegattaAndRaceIdentifier raceIdentifier = race.getRaceIdentifier(); - return EntryPointLinkFactory.createRaceBoardLink(createRaceBoardLinkParameters(leaderboard.name, raceIdentifier)); - } - - @Override - public void openLeaderboardViewer(LeaderboardGroupDTO leaderboardGroup, StrippedLeaderboardDTO leaderboard) { - String link = EntryPointLinkFactory.createLeaderboardLink(createLeaderboardLinkParameters(leaderboardGroup, leaderboard)); - Window.open(link, "_blank", ""); - } - - @Override - public void openOverallLeaderboardViewer(LeaderboardGroupDTO leaderboardGroup) { - String link = EntryPointLinkFactory.createLeaderboardLink(createOverallLeaderboardLinkParameters(leaderboardGroup)); - Window.open(link, "_blank", ""); - } - - private Map createOverallLeaderboardLinkParameters(LeaderboardGroupDTO leaderboardGroup) { - Map linkParams = new HashMap(); - linkParams.put("eventId", event.id.toString()); - linkParams.put("name", leaderboardGroup.getName() + " " + LeaderboardNameConstants.OVERALL); - linkParams.put("showRaceDetails", "true"); - if(leaderboardGroup.getDisplayName() != null) { - linkParams.put("displayName", leaderboardGroup.getDisplayName()); - } - linkParams.put("leaderboardGroupName", leaderboardGroup.getName()); - return linkParams; - } - - private Map createRaceBoardLinkParameters(String leaderboardName, RegattaAndRaceIdentifier raceIdentifier) { - Map linkParams = new HashMap(); - linkParams.put("eventId", event.id.toString()); - linkParams.put("leaderboardName", leaderboardName); - linkParams.put("raceName", raceIdentifier.getRaceName()); - // TODO this must only be forwarded if there is a logged-on user -// linkParams.put(RaceBoardViewConfiguration.PARAM_CAN_REPLAY_DURING_LIVE_RACES, "true"); - linkParams.put(RaceBoardViewConfiguration.PARAM_VIEW_SHOW_MAPCONTROLS, "true"); - linkParams.put(RaceBoardViewConfiguration.PARAM_VIEW_SHOW_NAVIGATION_PANEL, "true"); - linkParams.put("regattaName", raceIdentifier.getRegattaName()); - return linkParams; - } - - private Map createLeaderboardLinkParameters(LeaderboardGroupDTO leaderboardGroup, StrippedLeaderboardDTO leaderboard) { - Map linkParams = new HashMap(); - linkParams.put("eventId", event.id.toString()); - linkParams.put("name", leaderboard.name); - linkParams.put("showRaceDetails", "true"); - if (leaderboard.displayName != null) { - linkParams.put("displayName", leaderboard.displayName); - } - if(leaderboardGroup != null) { - linkParams.put("leaderboardGroupName", leaderboardGroup.getName()); - } - return linkParams; - } - - private void setVisibleEventElement(Widget visibleWidget) { - for (Widget element : pageElements) { - element.setVisible(element == visibleWidget); - } - } - - private Map> getRegattaStructure(EventDTO event, List raceGroups) { - Map> result = new HashMap<>(); - Map raceGroupsMap = new HashMap<>(); - for (RaceGroupDTO raceGroup: raceGroups) { - raceGroupsMap.put(raceGroup.getName(), raceGroup); - } - - for (LeaderboardGroupDTO leaderboardGroup : event.getLeaderboardGroups()) { - for(StrippedLeaderboardDTO leaderboard: leaderboardGroup.getLeaderboards()) { - String leaderboardName = leaderboard.name; - result.put(leaderboardName, new Triple(raceGroupsMap.get(leaderboardName), - leaderboard, leaderboardGroup)); - } - } - return result; - } - -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/TabletAndDesktopEventView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/TabletAndDesktopEventView.ui.xml deleted file mode 100644 index 82fd9abf7f8..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/TabletAndDesktopEventView.ui.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/TabletAndDesktopEventWithoutRegattasView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/TabletAndDesktopEventWithoutRegattasView.java deleted file mode 100644 index b5b9934bbd1..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/TabletAndDesktopEventWithoutRegattasView.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; -import com.sap.sailing.gwt.home.client.place.event.header.EventHeader; -import com.sap.sailing.gwt.ui.client.SailingServiceAsync; -import com.sap.sailing.gwt.ui.shared.EventDTO; - -public class TabletAndDesktopEventWithoutRegattasView extends Composite implements EventWithoutRegattasView { - private static EventViewUiBinder uiBinder = GWT.create(EventViewUiBinder.class); - - interface EventViewUiBinder extends UiBinder { - } - - @UiField(provided=true) EventHeader eventHeader; - - public TabletAndDesktopEventWithoutRegattasView(SailingServiceAsync sailingService, EventDTO event, HomePlacesNavigator placeNavigator) { - eventHeader = new EventHeader(event, placeNavigator); - - initWidget(uiBinder.createAndBindUi(this)); - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/TabletAndDesktopEventWithoutRegattasView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/TabletAndDesktopEventWithoutRegattasView.ui.xml deleted file mode 100644 index 2e91dfd09ac..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/TabletAndDesktopEventWithoutRegattasView.ui.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - .infoPanel { - height: 300px; - padding-top: 2em; - } - - - -
-
- There is no information available about the regattas of this event yet. -
-
-
-
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/CompactEventHeader.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/CompactEventHeader.java deleted file mode 100644 index 957e55051ba..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/CompactEventHeader.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.header; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.dom.client.ImageElement; -import com.google.gwt.dom.client.SpanElement; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.uibinder.client.UiHandler; -import com.google.gwt.user.client.Event; -import com.google.gwt.user.client.ui.Anchor; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.Widget; -import com.google.gwt.user.client.ui.impl.HyperlinkImpl; -import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; -import com.sap.sailing.gwt.home.client.app.PlaceNavigation; -import com.sap.sailing.gwt.home.client.place.event.EventPlace; -import com.sap.sailing.gwt.ui.shared.CourseAreaDTO; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; -import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; - -public class CompactEventHeader extends Composite { - private static CompactHeaderUiBinder uiBinder = GWT.create(CompactHeaderUiBinder.class); - - interface CompactHeaderUiBinder extends UiBinder { - } - - private static final HyperlinkImpl HYPERLINK_IMPL = GWT.create(HyperlinkImpl.class); - - @UiField Anchor regattaLink; - @UiField Anchor regattaLink2; - @UiField ImageElement eventLogo; - @UiField SpanElement eventNameSpan; - - private final EventDTO event; - private final HomePlacesNavigator placeNavigator; - private final PlaceNavigation regattaNavigation; - - public CompactEventHeader(EventDTO event, String leaderboardName, HomePlacesNavigator placeNavigator) { - this.event = event; - this.placeNavigator = placeNavigator; - - EventHeaderResources.INSTANCE.css().ensureInjected(); - - initWidget(uiBinder.createAndBindUi(this)); - - regattaNavigation = placeNavigator.getRegattaNavigation(event.id.toString(), leaderboardName, event.getBaseURL(), event.isOnRemoteServer()); - regattaLink.setHref(regattaNavigation.getTargetUrl()); - regattaLink2.setHref(regattaNavigation.getTargetUrl()); - - updateUI(); - } - - private StrippedLeaderboardDTO findLeaderboardWithSameCourseArea(EventDTO event) { - for(LeaderboardGroupDTO leaderboardGroup: event.getLeaderboardGroups()) { - for(StrippedLeaderboardDTO leaderboard: leaderboardGroup.getLeaderboards()) { - for(CourseAreaDTO courseArea: event.venue.getCourseAreas()) { - if(leaderboard.defaultCourseAreaId != null && leaderboard.defaultCourseAreaId.equals(courseArea.id)) { - return leaderboard; - } - } - } - } - return null; - } - - private void updateUI() { - boolean isSeries = event.isFakeSeries(); - - String eventName = event.getName(); - if(isSeries) { - LeaderboardGroupDTO leaderboardGroupDTO = event.getLeaderboardGroups().get(0); - eventName = leaderboardGroupDTO.getDisplayName() != null ? leaderboardGroupDTO.getDisplayName() : leaderboardGroupDTO.getName(); - - StrippedLeaderboardDTO leaderboardFittingToEvent = findLeaderboardWithSameCourseArea(event); - if(leaderboardFittingToEvent != null) { - } else { - } - } else { - } - eventNameSpan.setInnerText(eventName); - String logoUrl = event.getLogoImageURL() != null ? event.getLogoImageURL() : EventHeaderResources.INSTANCE.defaultEventLogoImage().getSafeUri().asString(); - eventLogo.setSrc(logoUrl); - } - - @UiHandler("regattaLink") - void gotoRegattaClicked(ClickEvent event) { - handleClickEvent(event, regattaNavigation); - } - - @UiHandler("regattaLink2") - void gotoRegatta2Clicked(ClickEvent event) { - handleClickEvent(event, regattaNavigation); - } - - private void handleClickEvent(ClickEvent e, PlaceNavigation placeNavigation) { - if (HYPERLINK_IMPL.handleAsClick((Event) e.getNativeEvent())) { - placeNavigator.goToPlace(placeNavigation); - e.preventDefault(); - } - } - -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/CompactEventHeader.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/CompactEventHeader.ui.xml deleted file mode 100644 index 7e3fb498de0..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/CompactEventHeader.ui.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - -
-
-
- - - - - - -
-
-
-
-
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/EventHeader.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/EventHeader.gss deleted file mode 100644 index 882411e8673..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/EventHeader.gss +++ /dev/null @@ -1,241 +0,0 @@ -.dropdown { - font-size: 15px; - /* @alternate */ font-size: 1rem; - width: 20em; - max-width: 100%; - display: inline-block; - text-align: left; -} -.dropdown_head { - cursor: pointer; - display: block; -} -.dropdown_head_title { - cursor: pointer; - background: #f8f8f8; - color: #666; - height: 2.733333333333333em; - line-height: 2.666666666666667em; - padding-left: 1em; - font-weight: 700; -} -.dropdown_head_titlebutton { - float: right; -} -.dropdown_content { - position: absolute; - z-index: 1; - background: #f6f9fc; - display: none; - width: 20em; - height: auto; - max-height: 23.333333333333332em; - overflow: auto; - -webkit-box-shadow: 0 0.066666666666667em 0.266666666666667em #ccc; - box-shadow: 0 0.066666666666667em 0.266666666666667em #ccc; - border-bottom: solid 1px #ccc; -} -.dropdown_content_link { - display: block; - cursor: pointer; - padding: 1.333333333333333em 1em; - border-bottom: 1px solid #ddd; -} -.dropdown_content_link:hover, -.dropdown_content_link:focus { - background: #f8f8f8; - text-decoration: none; -} -.dropdown_content_link:hover .dropdown_content_link_title, -.dropdown_content_link:focus .dropdown_content_link_title { - text-decoration: underline; -} -.dropdown_content_link_title { - color: #008fcc; - display: block; - font-weight: 700; - font-size: 1.2em; -} -.dropdown_content_link_subtitle { - color: #666; - font-size: 1.066666666666667em; -} -.leaderboardquickaccess { - font-size: 15px; - /* @alternate */ font-size: 1rem; - text-align: right; -} -.eventheaderwrapper { - font-size: 15px; - /* @alternate */ font-size: 1rem; -} -.eventheaderwrapper[data-navigationtype='compact'] .eventheader, -.eventheaderwrapper[data-navigationtype='compact'] .eventnavigationnormal { - display: none; -} -.eventheaderwrapper[data-navigationtype='normal'] .eventnavigationcompact { - display: none; -} -.eventheaderwrapper[data-navigationtype='normal'] .eventnavigationcompactfloating { - -webkit-transition: top 0.4s; - -moz-transition: top 0.4s; - -o-transition: top 0.4s; - -ms-transition: top 0.4s; - transition: top 0.4s; -} -.eventheader { - font-size: 15px; - /* @alternate */ font-size: 1rem; - background: #f2f2f2; - padding: 2em 0; - border-bottom: 1px solid darkgray; -} -.eventheader_intro { - padding-left: 10.333333333333334em; - min-height: 9.333333333333334em; - position: relative; -} -.eventheader_intro_description { - font-size: 15px; - /* @alternate */ font-size: 1rem; -} -.eventheader_intro_logo { - -webkit-box-shadow: 0 0 5px rgba(204,204,204,0.25); - box-shadow: 0 0 5px rgba(204,204,204,0.25); - position: absolute; - top: 0; - left: 0; - max-width: 140px; - max-height: 140px; - width: auto; - height: auto; -} -.eventheader_intro_logo_image { - border: solid 5px #fff; - max-height: 100%; -} -.eventheader_intro_name { - display: inline-block; - margin: 0 0.333333333333333em 0 0; -} -.eventheader_intro_details { - margin-bottom: 0.666666666666667em; - padding-bottom: 0.666666666666667em; - border-bottom: 1px solid #ddd; - font-weight: 600; - color: #333; -} -.eventheader_intro_details_item { - display: inline-block; - border-right: 1px solid #ddd; - padding: 0.266666666666667em 0.666666666666667em 0.266666666666667em 0; - margin-right: 0.666666666666667em; -} -.eventheader_intro_details_itemlink { - color: inherit; -} -.eventheader_intro_details_item:first-child { - padding-left: 0; -} -.eventheader_intro_details_item:nth-child(2) { - border: none; -} -.eventheader_intro_details_item:last-child { - display: block; - padding: 0; - border: none; - margin: 0; -} -@media (min-width: 50em) { - .eventheader_intro_details_item:nth-child(2) { - border-right: 1px solid #ddd; - } - .eventheader_intro_details_item:last-child { - display: inline-block; - } -} -.eventheader_sharing { - text-align: right; -} -.eventheader_sharing_item { - display: inline-block; - height: 2.666666666666667em; - width: 2.666666666666667em; - margin-left: 0.333333333333333em; - background-position: center center; - background-repeat: no-repeat; -} -.eventheader_sharing_itememail { - background-color: #f0ab00; - background-image: url("images/home/email-icon.png"); -} -.eventheader_sharing_itememail:hover, -.eventheader_sharing_itememail:focus { - background-color: #d89a00; -} -.eventheader_sharing_itemtwitter { - background-color: #32b5e2; - background-image: url("images/home/twitter-icon.png"); -} -.eventheader_sharing_itemtwitter:hover, -.eventheader_sharing_itemtwitter:focus { - background-color: #1faada; -} -.eventheader_sharing_itemfacebook { - background-color: #3b5998; - background-image: url("images/home/facebook-icon.png"); -} -.eventheader_sharing_itemfacebook:hover, -.eventheader_sharing_itemfacebook:focus { - background-color: #355089; -} -.locationicon { - vertical-align: text-bottom; - margin-right: 0.333333333333333em; -} -.eventnavigation { - font-size: 15px; - /* @alternate */ font-size: 1rem; -} -.eventnavigationnormal { - position: relative; -} -.eventnavigationcompact, -.eventnavigationcompactfloating { - background: #f2f2f2; - margin: 0; - padding: 1em 0; -} -.eventnavigationcompact_logo, -.eventnavigationcompactfloating_logo { - border: solid 2px #fff; - -webkit-box-shadow: 0 0 5px rgba(204,204,204,0.25); - box-shadow: 0 0 5px rgba(204,204,204,0.25); - margin-right: 0.666666666666667em; -} -.eventnavigationcompactfloating { - position: fixed; - top: -8em; - left: 0; - right: 0; - z-index: 5; -} -.eventnavigationcompactfloating.eventnavigationfixed { - top: 0; -} -.eventnavigation_link { - text-transform: uppercase; - margin-right: 0.625em; - background-color: #ccc; -} -.eventnavigation_link:hover, -.eventnavigation_link:focus { - background-color: #b8b8b8; -} -.eventnavigation_linkactive { - background-color: #f0ab00; -} -.eventnavigation_linkactive:hover, -.eventnavigation_linkactive:focus { - background-color: #d89a00; -} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/EventHeader.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/EventHeader.java deleted file mode 100644 index 2541b07cdc6..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/EventHeader.java +++ /dev/null @@ -1,354 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.header; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.dom.client.DivElement; -import com.google.gwt.dom.client.ImageElement; -import com.google.gwt.dom.client.SpanElement; -import com.google.gwt.dom.client.Style.Display; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.uibinder.client.UiHandler; -import com.google.gwt.user.client.Event; -import com.google.gwt.user.client.ui.Anchor; -import com.google.gwt.user.client.ui.Widget; -import com.google.gwt.user.client.ui.impl.HyperlinkImpl; -import com.sap.sailing.domain.common.LeaderboardNameConstants; -import com.sap.sailing.gwt.common.client.i18n.TextMessages; -import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; -import com.sap.sailing.gwt.home.client.app.PlaceNavigation; -import com.sap.sailing.gwt.home.client.place.event.AbstractEventComposite; -import com.sap.sailing.gwt.home.client.place.event.EventPlace; -import com.sap.sailing.gwt.home.client.place.event.EventPlaceNavigator; -import com.sap.sailing.gwt.home.client.place.series.SeriesPlace; -import com.sap.sailing.gwt.home.client.place.series.SeriesPlace.SeriesNavigationTabs; -import com.sap.sailing.gwt.home.client.shared.EventDatesFormatterUtil; -import com.sap.sailing.gwt.ui.shared.CourseAreaDTO; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; -import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; - -public class EventHeader extends AbstractEventComposite { - private static EventHeaderUiBinder uiBinder = GWT.create(EventHeaderUiBinder.class); - - interface EventHeaderUiBinder extends UiBinder { - } - - private static final HyperlinkImpl HYPERLINK_IMPL = GWT.create(HyperlinkImpl.class); - -// @UiField Anchor overviewLink; - @UiField Anchor regattasLink; -// @UiField Anchor scheduleLink; -// @UiField Anchor mediaLink; -// -// @UiField Anchor overviewLink2; - @UiField Anchor regattasLink2; -// @UiField Anchor scheduleLink2; -// @UiField Anchor mediaLink2; -// -// @UiField Anchor overviewLink3; -// @UiField Anchor regattasLink3; -// @UiField Anchor scheduleLink3; -// @UiField Anchor mediaLink3; - @UiField Anchor officalWebsiteAnchor; - @UiField Anchor twitterAnchor; - @UiField Anchor facebookAnchor; - @UiField DivElement seriesLeaderboardDiv; - @UiField Anchor seriesLeaderboardAnchor; - - @UiField DivElement eventHeaderWrapperDiv; - @UiField DivElement regattaNameInSeriesDiv; - @UiField SpanElement eventNameSpan; - @UiField SpanElement eventName2Span; -// @UiField SpanElement eventName3; - @UiField DivElement eventDateDiv; - @UiField DivElement eventDescriptionDiv; - @UiField SpanElement venueNameSpan; - @UiField DivElement isLiveDiv; - @UiField DivElement isFinishedDiv; - - @UiField ImageElement eventLogo; - @UiField ImageElement eventLogo2; -// @UiField ImageElement eventLogo3; - -// private final List links1; -// private final List links2; -// private final List links3; - - private final HomePlacesNavigator placeNavigator; - private PlaceNavigation seriesAnalyticsNavigation = null; - private PlaceNavigation regattasNavigation = null; - - public EventHeader(EventDTO event, HomePlacesNavigator placeNavigator, EventPlaceNavigator pageNavigator) { - super(event, pageNavigator); - - this.placeNavigator = placeNavigator; - initResources(); - -// links1 = Arrays.asList(new Anchor[] { overviewLink, regattasLink, scheduleLink, mediaLink }); -// links2 = Arrays.asList(new Anchor[] { overviewLink2, regattasLink2, scheduleLink2, mediaLink2 }); -// links3 = Arrays.asList(new Anchor[] { overviewLink3, regattasLink3, scheduleLink3, mediaLink3 }); -// setActiveLink(links1, overviewLink); -// setActiveLink(links2, overviewLink2); -// setActiveLink(links3, overviewLink3); - - if(event.isRunning()) { - isFinishedDiv.getStyle().setDisplay(Display.NONE); - } else if (event.isFinished()) { - isLiveDiv.getStyle().setDisplay(Display.NONE); - } else { - isFinishedDiv.getStyle().setDisplay(Display.NONE); - isLiveDiv.getStyle().setDisplay(Display.NONE); - } - - setFullsizeHeader(); - updateUI(); - } - - public EventHeader(EventDTO event, HomePlacesNavigator placeNavigator) { - super(event, null); - - this.placeNavigator = placeNavigator; - initResources(); - - isFinishedDiv.getStyle().setDisplay(Display.NONE); - isLiveDiv.getStyle().setDisplay(Display.NONE); - - setFullsizeHeader(); - updateUI(); - } - - private void initResources() { - EventHeaderResources.INSTANCE.css().ensureInjected(); - - initWidget(uiBinder.createAndBindUi(this)); - } - - public void setFullsizeHeader() { - eventHeaderWrapperDiv.setAttribute("data-navigationtype", "normal"); - } - - public void setCompactHeader() { - eventHeaderWrapperDiv.setAttribute("data-navigationtype", "compact"); - EventDTO event = getEvent(); - - PlaceNavigation regattaDetailsNavigation = placeNavigator.getEventNavigation(event.id.toString(), event.getBaseURL(), event.isOnRemoteServer()); - regattasLink.setHref(regattaDetailsNavigation.getTargetUrl()); - regattasLink2.setHref(regattaDetailsNavigation.getTargetUrl()); - } - - private StrippedLeaderboardDTO findLeaderboardWithSameCourseArea(EventDTO event) { - for(LeaderboardGroupDTO leaderboardGroup: event.getLeaderboardGroups()) { - for(StrippedLeaderboardDTO leaderboard: leaderboardGroup.getLeaderboards()) { - for(CourseAreaDTO courseArea: event.venue.getCourseAreas()) { - if(leaderboard.defaultCourseAreaId != null && leaderboard.defaultCourseAreaId.equals(courseArea.id)) { - return leaderboard; - } - } - } - } - return null; - } - - private void updateUI() { - EventDTO event = getEvent(); - boolean isSeries = event.isFakeSeries(); - - String eventName = event.getName(); - - regattasNavigation = placeNavigator.getEventNavigation(event.id.toString(), event.getBaseURL(), event.isOnRemoteServer()); - if(isSeries) { - LeaderboardGroupDTO leaderboardGroupDTO = event.getLeaderboardGroups().get(0); - eventName = leaderboardGroupDTO.getDisplayName() != null ? leaderboardGroupDTO.getDisplayName() : leaderboardGroupDTO.getName(); - - String overallLeaderboardName = leaderboardGroupDTO.getName() + " " + LeaderboardNameConstants.OVERALL; - seriesAnalyticsNavigation = placeNavigator.getSeriesAnalyticsNavigation(event.id.toString(), SeriesNavigationTabs.OverallLeaderboard, overallLeaderboardName, event.getBaseURL(), event.isOnRemoteServer()); - seriesLeaderboardAnchor.setHref(seriesAnalyticsNavigation.getTargetUrl()); - - StrippedLeaderboardDTO leaderboardFittingToEvent = findLeaderboardWithSameCourseArea(event); - if (leaderboardFittingToEvent != null) { - regattaNameInSeriesDiv.setInnerText(leaderboardFittingToEvent.displayName); - } else { - regattaNameInSeriesDiv.getStyle().setDisplay(Display.NONE); - } - } else { - seriesLeaderboardDiv.getStyle().setDisplay(Display.NONE); - regattaNameInSeriesDiv.getStyle().setDisplay(Display.NONE); - } - - eventNameSpan.setInnerHTML(eventName); - eventName2Span.setInnerHTML(eventName); -// eventName3.setInnerHTML(event.getName()); - venueNameSpan.setInnerHTML(event.venue.getName()); - eventDateDiv.setInnerHTML(EventDatesFormatterUtil.formatDateRangeWithYear(event.startDate, event.endDate)); - - if(event.getDescription() != null) { - eventDescriptionDiv.setInnerHTML(event.getDescription()); - } - if(event.getOfficialWebsiteURL() != null) { - String title = event.getOfficialWebsiteURL(); - if(title.startsWith("http://")) { - title = title.substring("http://".length(), title.length()); - } - if(title.length() > 35) { - title = TextMessages.INSTANCE.officalEventWebsite(); - } - officalWebsiteAnchor.setText(title); - officalWebsiteAnchor.setHref(event.getOfficialWebsiteURL()); - } else { - officalWebsiteAnchor.setVisible(false); - } - if(event.getTwitterURL() != null) { - twitterAnchor.setHref(event.getTwitterURL()); - } else { - twitterAnchor.setVisible(false); - } - if(event.getFacebookURL() != null) { - facebookAnchor.setHref(event.getFacebookURL()); - } else { - facebookAnchor.setVisible(false); - } - - String logoUrl = event.getLogoImageURL() != null ? event.getLogoImageURL() : EventHeaderResources.INSTANCE.defaultEventLogoImage().getSafeUri().asString();; - eventLogo.setSrc(logoUrl); - eventLogo2.setSrc(logoUrl); -// eventLogo3.setSrc(logoUrl); - } - -// @UiHandler("overviewLink") -// void overviewClicked(ClickEvent event) { -// showOverview(); -// } -// -// @UiHandler("overviewLink2") -// void overview2Clicked(ClickEvent event) { -// showOverview(); -// } -// -// @UiHandler("overviewLink3") -// void overview3Clicked(ClickEvent event) { -// showOverview(); -// } - -// private void showOverview() { -// pageNavigator.goToOverview(); -// setActiveLink(links1, overviewLink); -// setActiveLink(links2, overviewLink2); -// setActiveLink(links3, overviewLink3); -// } - - @UiHandler("regattasLink") - void regattasClicked(ClickEvent event) { - showRegattas(event); - } - - @UiHandler("regattasLink2") - void regattas2Clicked(ClickEvent event) { - showRegattas(event); - } - - @UiHandler("seriesLeaderboardAnchor") - void seriesLeaderboardClicked(ClickEvent e) { - EventDTO event = getEvent(); - if(event.isFakeSeries()) { - handleClickEvent(e, seriesAnalyticsNavigation); - } - } - -// @UiHandler("regattasLink3") -// void regattas3Clicked(ClickEvent event) { -// showRegattas(); -// } -// - private void showRegattas(ClickEvent e) { - handleClickEvent(e, regattasNavigation); -// setActiveLink(links1, regattasLink); -// setActiveLink(links2, regattasLink2); -// setActiveLink(links3, regattasLink3); - } - -// @UiHandler("scheduleLink") -// void scheduleClicked(ClickEvent event) { -// showSchedule(); -// } -// -// @UiHandler("scheduleLink2") -// void schedule2Clicked(ClickEvent event) { -// showSchedule(); -// } -// -// @UiHandler("scheduleLink3") -// void schedule3Clicked(ClickEvent event) { -// showSchedule(); -// } -// -// private void showSchedule() { -// pageNavigator.goToSchedule(); -// setActiveLink(links1, scheduleLink); -// setActiveLink(links2, scheduleLink2); -// setActiveLink(links3, scheduleLink3); -// } -// -// @UiHandler("mediaLink") -// void mediaClicked(ClickEvent event) { -// showMedia(); -// } -// -// @UiHandler("mediaLink2") -// void media2Clicked(ClickEvent event) { -// showMedia(); -// } -// -// @UiHandler("mediaLink3") -// void media3Clicked(ClickEvent event) { -// showMedia(); -// } -// -// private void showMedia() { -// pageNavigator.goToMedia(); -// setActiveLink(links1, mediaLink); -// setActiveLink(links2, mediaLink2); -// setActiveLink(links3, mediaLink3); -// } - - private void handleClickEvent(ClickEvent e, PlaceNavigation placeNavigation) { - if (HYPERLINK_IMPL.handleAsClick((Event) e.getNativeEvent())) { - placeNavigator.goToPlace(placeNavigation); - e.preventDefault(); - } - } - - @Override - protected void onLoad() { - super.onLoad(); - - initNormalNavigation(); - } - - private void initNormalNavigation() { -// Window.addWindowScrollHandler(new Window.ScrollHandler() { -// public void onWindowScroll(Window.ScrollEvent event) { -// int scrollY = Math.max(0, Window.getScrollTop()); -// int navNormalOffset = eventNavigationNormalDiv.getOffsetTop(); -// -// if (scrollY > navNormalOffset) { -// eventNavigationFloatingDiv.addClassName(EventHeaderResources.INSTANCE.css().eventnavigationfixed()); -// } else { -// eventNavigationFloatingDiv.removeClassName(EventHeaderResources.INSTANCE.css() -// .eventnavigationfixed()); -// } -// } -// }); - } - -// private void setActiveLink(List linksToSet, Anchor link) { -// final String activeStyle = EventHeaderResources.INSTANCE.css().eventnavigation_linkactive(); -// for (Anchor l : linksToSet) { -// if (l == link) { -// l.addStyleName(activeStyle); -// } else { -// l.removeStyleName(activeStyle); -// } -// } -// } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/EventHeader.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/EventHeader.ui.xml deleted file mode 100644 index 026aede7a8f..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/EventHeader.ui.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - .action { - float: right; - text-align: center; - text-transform: uppercase; - cursor: pointer; - margin-top: 0.5em; - margin-bottom: 0.5em; - } - .action_link { - background-color: #008FCC; - color: white; - } - .action_link:hover { - background-color: #0177ab; - } - - - - -
-
-
-
-
-
-

-
-
-
-
-
-
- - -
- -
-
-
-
-
-
- - -
-
-
- -
-
-
-
-
-
-
-
- - - - - - -
-
-
- -
-
-
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/legacy/EventPlace.java similarity index 97% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventPlace.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/legacy/EventPlace.java index c41a9d27c17..549d060a6dd 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/EventPlace.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/legacy/EventPlace.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.home.client.place.event; +package com.sap.sailing.gwt.home.client.place.event.legacy; import com.google.gwt.place.shared.PlaceTokenizer; import com.sap.sailing.gwt.common.client.AbstractBasePlace; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/RegattaPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/legacy/RegattaPlace.java similarity index 98% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/RegattaPlace.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/legacy/RegattaPlace.java index adbb88eb0d8..54d9c32fe02 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/RegattaPlace.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/legacy/RegattaPlace.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.home.client.place.regatta; +package com.sap.sailing.gwt.home.client.place.event.legacy; import com.google.gwt.place.shared.PlaceTokenizer; import com.sap.sailing.gwt.common.client.AbstractBasePlace; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/legacy/SeriesClientFactory.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/legacy/SeriesClientFactory.java new file mode 100644 index 00000000000..d12160232d2 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/legacy/SeriesClientFactory.java @@ -0,0 +1,9 @@ +package com.sap.sailing.gwt.home.client.place.event.legacy; + +import com.sap.sailing.gwt.ui.client.SailingClientFactory; + +public interface SeriesClientFactory extends SailingClientFactory { + + // SeriesAnalyticsView createSeriesAnalyticsView(EventDTO event, String leaderboardName, SeriesNavigationTabs + // navigationTab, Timer timerForClientServerOffset); +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/SeriesPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/legacy/SeriesPlace.java similarity index 98% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/SeriesPlace.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/legacy/SeriesPlace.java index b88229cc942..87d1775e7e6 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/SeriesPlace.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/legacy/SeriesPlace.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.home.client.place.series; +package com.sap.sailing.gwt.home.client.place.event.legacy; import com.google.gwt.place.shared.PlaceTokenizer; import com.sap.sailing.gwt.common.client.AbstractBasePlace; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/media/EventMedia.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/media/EventMedia.java deleted file mode 100644 index 1f2c48ba25d..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/media/EventMedia.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.media; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.gwt.home.client.place.event.AbstractEventComposite; -import com.sap.sailing.gwt.home.client.place.event.EventPlaceNavigator; -import com.sap.sailing.gwt.ui.shared.EventDTO; - -public class EventMedia extends AbstractEventComposite { - private static EventMediaUiBinder uiBinder = GWT.create(EventMediaUiBinder.class); - - interface EventMediaUiBinder extends UiBinder { - } - - public EventMedia(EventDTO event, EventPlaceNavigator placeNavigator) { - super(event, placeNavigator); - - EventMediaResources.INSTANCE.css().ensureInjected(); - initWidget(uiBinder.createAndBindUi(this)); - } - -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/media/EventMediaResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/media/EventMediaResources.java deleted file mode 100644 index c49570e68b5..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/media/EventMediaResources.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.media; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.resources.client.ClientBundle; -import com.google.gwt.resources.client.CssResource; - -public interface EventMediaResources extends ClientBundle { - public static final EventMediaResources INSTANCE = GWT.create(EventMediaResources.class); - - @Source("com/sap/sailing/gwt/home/client/place/event/media/EventMedia.css") - LocalCss css(); - - public interface LocalCss extends CssResource { - - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/AbstractMultiregattaEventPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/AbstractMultiregattaEventPlace.java new file mode 100644 index 00000000000..645efd183f3 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/AbstractMultiregattaEventPlace.java @@ -0,0 +1,15 @@ +package com.sap.sailing.gwt.home.client.place.event.multiregatta; + +import com.sap.sailing.gwt.home.client.place.event.AbstractEventPlace; +import com.sap.sailing.gwt.home.client.place.event.EventContext; + +public abstract class AbstractMultiregattaEventPlace extends AbstractEventPlace { + + public AbstractMultiregattaEventPlace(EventContext ctx) { + super(ctx); + } + + public AbstractMultiregattaEventPlace(String eventUuidAsString) { + super(eventUuidAsString); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/EventMultiregattaActivity.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/EventMultiregattaActivity.java new file mode 100644 index 00000000000..f95bff48377 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/EventMultiregattaActivity.java @@ -0,0 +1,46 @@ +package com.sap.sailing.gwt.home.client.place.event.multiregatta; + +import com.google.gwt.event.shared.EventBus; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; +import com.sap.sailing.gwt.home.client.place.event.AbstractEventActivity; +import com.sap.sailing.gwt.home.client.place.event.EventClientFactory; +import com.sap.sailing.gwt.home.client.place.event.EventView; +import com.sap.sailing.gwt.home.client.place.event.EventView.PlaceCallback; + +public class EventMultiregattaActivity extends AbstractEventActivity implements EventMultiregattaView.Presenter { + + private EventMultiregattaView currentView = new TabletAndDesktopEventView(); + + public EventMultiregattaActivity(AbstractMultiregattaEventPlace place, EventClientFactory clientFactory, + HomePlacesNavigator homePlacesNavigator) { + super(place, clientFactory, homePlacesNavigator); + } + + @Override + public void start(final AcceptsOneWidget panel, final EventBus eventBus) { + currentView.registerPresenter(this); + panel.setWidget(currentView); + currentView.navigateTabsTo(currentPlace); + } + + @Override + public boolean needsSelectionInHeader() { + return false; + } + + @Override + public void forPlaceSelection(PlaceCallback callback) { + } + + @Override + public boolean showRegattaMetadata() { + return false; + } + + @Override + protected EventView getView() { + return currentView; + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/EventMultiregattaView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/EventMultiregattaView.java new file mode 100644 index 00000000000..b0f01fb6932 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/EventMultiregattaView.java @@ -0,0 +1,10 @@ +package com.sap.sailing.gwt.home.client.place.event.multiregatta; + +import com.sap.sailing.gwt.home.client.place.event.EventView; + +public interface EventMultiregattaView extends EventView { + + public interface Presenter extends EventView.Presenter { + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/MultiregattaTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/MultiregattaTabView.java new file mode 100644 index 00000000000..1d205db2d9a --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/MultiregattaTabView.java @@ -0,0 +1,8 @@ +package com.sap.sailing.gwt.home.client.place.event.multiregatta; + +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; + +public interface MultiregattaTabView extends + TabView { + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/TabletAndDesktopEventView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/TabletAndDesktopEventView.java new file mode 100644 index 00000000000..0aa52270092 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/TabletAndDesktopEventView.java @@ -0,0 +1,93 @@ +package com.sap.sailing.gwt.home.client.place.event.multiregatta; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.uibinder.client.UiHandler; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.IsWidget; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabPanel; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabPanelPlaceSelectionEvent; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.common.client.i18n.TextMessages; +import com.sap.sailing.gwt.home.client.app.ApplicationHistoryMapper; +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.place.event.partials.header.EventHeader; +import com.sap.sailing.gwt.ui.client.StringMessages; + +public class TabletAndDesktopEventView extends Composite implements EventMultiregattaView { + private static final ApplicationHistoryMapper historyMapper = GWT + . create(ApplicationHistoryMapper.class); + + private static MyBinder uiBinder = GWT.create(MyBinder.class); + + private Presenter currentPresenter; + + interface MyBinder extends UiBinder { + } + + @UiField StringMessages i18n; + + @UiField(provided = true) + TabPanel tabPanelUi; + + @UiField(provided = true) + EventHeader eventHeader; + + public TabletAndDesktopEventView() { + } + + @Override + public void registerPresenter(final Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + tabPanelUi = new TabPanel<>(currentPresenter, historyMapper); + + eventHeader = new EventHeader(currentPresenter); + + initWidget(uiBinder.createAndBindUi(this)); + + initBreadCrumbs(); + } + + @Override + public void navigateTabsTo(AbstractMultiregattaEventPlace place) { + tabPanelUi.activatePlace(place); + StringBuilder titleBuilder = new StringBuilder(TextMessages.INSTANCE.sapSailing()).append(" - "); + + titleBuilder.append(currentPresenter.showRegattaMetadata() ? currentPresenter.getRegattaMetadata() + .getDisplayName() : currentPresenter.getCtx().getEventDTO().getDisplayName()); + String currentTabTitle = tabPanelUi.getCurrentTabTitle(); + if (currentTabTitle != null && !currentTabTitle.isEmpty()) { + titleBuilder.append(" - ").append(currentTabTitle); + } + Window.setTitle(titleBuilder.toString()); + } + + @SuppressWarnings("unchecked") + @UiHandler("tabPanelUi") + public void onTabSelection(TabPanelPlaceSelectionEvent e) { + currentPresenter.handleTabPlaceSelection((TabView) e.getSelectedActivity()); + } + + private void initBreadCrumbs() { + addBreadCrumbItem(i18n.home(), currentPresenter.getHomeNavigation()); + addBreadCrumbItem(i18n.events(), currentPresenter.getEventsNavigation()); + addBreadCrumbItem(currentPresenter.getCtx().getEventDTO().getDisplayName(), currentPresenter.getCurrentEventNavigation()); + } + + private void addBreadCrumbItem(String label, final PlaceNavigation placeNavigation) { + tabPanelUi.addBreadcrumbItem(label, placeNavigation.getTargetUrl(), new Runnable() { + @Override + public void run() { + placeNavigation.goToPlace(); + } + }); + } + + @Override + public void showErrorInCurrentTab(IsWidget errorView) { + tabPanelUi.overrideCurrentContentInTab(errorView); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/TabletAndDesktopEventView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/TabletAndDesktopEventView.ui.xml new file mode 100644 index 00000000000..60df643a019 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/TabletAndDesktopEventView.ui.xml @@ -0,0 +1,63 @@ + + + + + .header { + position: relative; + width: 100%; + margin: 0; + padding: 0; + } + + .mainHeader { + width: 66.6666666666667%; + } + + .sharingHeader { + width: 33.3333333333333%; + float: right; + padding: 0 1rem; + position: + relative; + padding: 1.333333333333333em 0; + text-align: right; + + background-color: maroon; + height: 2rem; + } + + .breadcrumb, .intro { + box-sizing: border-box; + -moz-box-sizing: border-box; + } + + .breadcrumb { + font-size: 0.866666666666667em; + font-weight: 600; + } + + .intro { + height: 5em; + } + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaMediaPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaMediaPlace.java new file mode 100644 index 00000000000..ec467b32afe --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaMediaPlace.java @@ -0,0 +1,25 @@ +package com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs; + +import com.google.gwt.place.shared.Prefix; +import com.sap.sailing.gwt.home.client.place.event.AbstractEventPlace; +import com.sap.sailing.gwt.home.client.place.event.EventContext; +import com.sap.sailing.gwt.home.client.place.event.EventPrefixes; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.AbstractMultiregattaEventPlace; + +public class MultiregattaMediaPlace extends AbstractMultiregattaEventPlace { + public MultiregattaMediaPlace(String id) { + super(id); + } + + public MultiregattaMediaPlace(EventContext context) { + super(context); + } + + @Prefix(EventPrefixes.MultiregattaMedia) + public static class Tokenizer extends AbstractEventPlace.Tokenizer { + @Override + protected MultiregattaMediaPlace getRealPlace(EventContext context) { + return new MultiregattaMediaPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaMediaTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaMediaTabView.java new file mode 100644 index 00000000000..05311947236 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaMediaTabView.java @@ -0,0 +1,85 @@ +package com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.MultiregattaTabView; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView.Presenter; +import com.sap.sailing.gwt.home.client.shared.media.MediaPage; +import com.sap.sailing.gwt.ui.shared.media.MediaDTO; + +/** + * Created by pgtaboada on 25.11.14. + */ +public class MultiregattaMediaTabView extends Composite implements MultiregattaTabView { + + public MultiregattaMediaTabView() { + + } + + @Override + public Class getPlaceClassForActivation() { + return MultiregattaMediaPlace.class; + } + + @Override + public TabView.State getState() { + return TabView.State.INVISIBLE; + // TODO return currentPresenter.hasMedia() ? TabView.State.VISIBLE : TabView.State.INVISIBLE; + } + + @Override + public void start(MultiregattaMediaPlace myPlace, AcceptsOneWidget contentArea) { + final MediaPage mediaPage = new MediaPage(); + + currentPresenter.ensureMedia(new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + // TODO Auto-generated method stub + + } + + @Override + public void onSuccess(MediaDTO media) { + mediaPage.setMedia(media); + } + }); + + initWidget(mediaPage); + + // TODO do we need UiBinder here? +// initWidget(ourUiBinder.createAndBindUi(this)); + + contentArea.setWidget(this); + } + + @Override + public void stop() { + + } + + // TODO delete UiBinder if we do not need it for the new media page implementation + interface MyBinder extends UiBinder { + } + + @SuppressWarnings("unused") + private static MyBinder ourUiBinder = GWT.create(MyBinder.class); + private Presenter currentPresenter; + + @Override + public MultiregattaMediaPlace placeToFire() { + return new MultiregattaMediaPlace(currentPresenter.getCtx()); + } + + @Override + public void setPresenter(EventMultiregattaView.Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + + } + +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaMediaTabView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaMediaTabView.ui.xml new file mode 100644 index 00000000000..c149137f7f0 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaMediaTabView.ui.xml @@ -0,0 +1,6 @@ + + +

This is MEDIA tab

+
+
\ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaOverviewPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaOverviewPlace.java new file mode 100644 index 00000000000..31d96486219 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaOverviewPlace.java @@ -0,0 +1,25 @@ +package com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs; + +import com.google.gwt.place.shared.Prefix; +import com.sap.sailing.gwt.home.client.place.event.AbstractEventPlace; +import com.sap.sailing.gwt.home.client.place.event.EventContext; +import com.sap.sailing.gwt.home.client.place.event.EventPrefixes; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.AbstractMultiregattaEventPlace; + +public class MultiregattaOverviewPlace extends AbstractMultiregattaEventPlace { + public MultiregattaOverviewPlace(String id) { + super(id); + } + + public MultiregattaOverviewPlace(EventContext context) { + super(context); + } + + @Prefix(EventPrefixes.MultiregattaOverview) + public static class Tokenizer extends AbstractEventPlace.Tokenizer { + @Override + protected MultiregattaOverviewPlace getRealPlace(EventContext context) { + return new MultiregattaOverviewPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaOverviewTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaOverviewTabView.java new file mode 100644 index 00000000000..ca367093dae --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaOverviewTabView.java @@ -0,0 +1,64 @@ +package com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView.Presenter; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.MultiregattaTabView; + +/** + * Created by pgtaboada on 25.11.14. + */ +public class MultiregattaOverviewTabView extends Composite implements MultiregattaTabView { + + private Presenter currentPresenter; + + public MultiregattaOverviewTabView() { + + } + + @Override + public Class getPlaceClassForActivation() { + return MultiregattaOverviewPlace.class; + } + + @Override + public void setPresenter(EventMultiregattaView.Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + + } + + @Override + public TabView.State getState() { + // TODO activate + return TabView.State.NOT_AVAILABLE_SHOW_NEXT_AVAILABLE; + } + + @Override + public void start(MultiregattaOverviewPlace myPlace, AcceptsOneWidget contentArea) { + + initWidget(ourUiBinder.createAndBindUi(this)); + + contentArea.setWidget(this); + } + + @Override + public void stop() { + + } + + interface MyBinder extends UiBinder { + } + + private static MyBinder ourUiBinder = GWT.create(MyBinder.class); + + @Override + public MultiregattaOverviewPlace placeToFire() { + return new MultiregattaOverviewPlace(currentPresenter.getCtx()); + } + +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaOverviewTabView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaOverviewTabView.ui.xml new file mode 100644 index 00000000000..211aed550be --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaOverviewTabView.ui.xml @@ -0,0 +1,6 @@ + + +

This is multiregatta overview tab

+
+
\ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaRegattasPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaRegattasPlace.java new file mode 100644 index 00000000000..66d1e28ca43 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaRegattasPlace.java @@ -0,0 +1,25 @@ +package com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs; + +import com.google.gwt.place.shared.Prefix; +import com.sap.sailing.gwt.home.client.place.event.AbstractEventPlace; +import com.sap.sailing.gwt.home.client.place.event.EventContext; +import com.sap.sailing.gwt.home.client.place.event.EventPrefixes; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.AbstractMultiregattaEventPlace; + +public class MultiregattaRegattasPlace extends AbstractMultiregattaEventPlace { + public MultiregattaRegattasPlace(String id) { + super(id); + } + + public MultiregattaRegattasPlace(EventContext context) { + super(context); + } + + @Prefix(EventPrefixes.MultiregattaRegattas) + public static class Tokenizer extends AbstractEventPlace.Tokenizer { + @Override + protected MultiregattaRegattasPlace getRealPlace(EventContext context) { + return new MultiregattaRegattasPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaRegattasTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaRegattasTabView.java new file mode 100644 index 00000000000..6a3d682f9dd --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaRegattasTabView.java @@ -0,0 +1,116 @@ +package com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView.Presenter; +import com.sap.sailing.gwt.home.client.place.event.multiregatta.MultiregattaTabView; +import com.sap.sailing.gwt.home.client.place.event.partials.eventregatta.EventRegattaList; +import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; +import com.sap.sailing.gwt.ui.shared.RaceGroupDTO; +import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; +import com.sap.sse.common.Util.Triple; + +/** + * Created by pgtaboada on 25.11.14. + */ +public class MultiregattaRegattasTabView extends Composite implements MultiregattaTabView { + + @UiField FlowPanel content; + private Presenter currentPresenter; + + public MultiregattaRegattasTabView() { + + } + + @Override + public Class getPlaceClassForActivation() { + return MultiregattaRegattasPlace.class; + } + + @Override + public void setPresenter(EventMultiregattaView.Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + } + + @Override + public TabView.State getState() { + return TabView.State.VISIBLE; + } + + @Override + public void start(final MultiregattaRegattasPlace myPlace, final AcceptsOneWidget contentArea) { + + // TODO: understand, and than move this into appropiate place (probably context) + currentPresenter.ensureRegattaStructure(new AsyncCallback>() { + @Override + public void onSuccess(List raceGroups) { + if (raceGroups.size() > 0) { + initView(contentArea); + } else { + // createEventWithoutRegattasView(event, panel); + } + } + + @Override + public void onFailure(Throwable caught) { + // createErrorView( + // "Error while loading the regatta structure with service getRegattaStructureOfEvent()", + // caught, panel); + } + }); + } + + protected void initView(AcceptsOneWidget contentArea) { + Map> regattaStructure = getRegattaStructure(); + EventRegattaList eventRegattaList = new EventRegattaList(regattaStructure, currentPresenter); +// initWidget(ourUiBinder.createAndBindUi(this)); +// contentArea.setWidget(this); + contentArea.setWidget(eventRegattaList); + } + + private Map> getRegattaStructure() { + Map> result = new HashMap<>(); + Map raceGroupsMap = new HashMap<>(); + for (RaceGroupDTO raceGroup: currentPresenter.getCtx().getRaceGroups()) { + raceGroupsMap.put(raceGroup.getName(), raceGroup); + } + + for (LeaderboardGroupDTO leaderboardGroup : currentPresenter.getCtx().getLeaderboardGroups()) { + for(StrippedLeaderboardDTO leaderboard: leaderboardGroup.getLeaderboards()) { + String leaderboardName = leaderboard.name; + result.put(leaderboardName, new Triple(raceGroupsMap.get(leaderboardName), + leaderboard, leaderboardGroup)); + } + } + return result; + } + + @Override + public void stop() { + + } + + interface MyBinder extends UiBinder { + } + + @SuppressWarnings("unused") + private static MyBinder ourUiBinder = GWT.create(MyBinder.class); + + @Override + public MultiregattaRegattasPlace placeToFire() { + return new MultiregattaRegattasPlace(currentPresenter.getCtx()); + } + +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaRegattasTabView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaRegattasTabView.ui.xml new file mode 100644 index 00000000000..bd48416fe56 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/multiregatta/tabs/MultiregattaRegattasTabView.ui.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldcompetitorcharts/OldCompetitorCharts.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldcompetitorcharts/OldCompetitorCharts.ui.xml index 68d7122a180..4fc8dd3f63d 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldcompetitorcharts/OldCompetitorCharts.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldcompetitorcharts/OldCompetitorCharts.ui.xml @@ -5,9 +5,16 @@ - + + .marginFix { + margin-top: 2rem; + + } + + + -
+

diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldleaderboard/OldLeaderboard.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldleaderboard/OldLeaderboard.css index 2e19c7583eb..3a65cbb94e7 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldleaderboard/OldLeaderboard.css +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldleaderboard/OldLeaderboard.css @@ -1,5 +1,5 @@ .oldLeaderboardPanel { - background-color:#f8f8f8; +/* background-color:#f8f8f8; */ padding: 0 10px 10px 10px; width: 100%; font-weight: bold; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldleaderboard/OldLeaderboard.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldleaderboard/OldLeaderboard.java index 8d32307f86c..f2efcd9a58d 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldleaderboard/OldLeaderboard.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldleaderboard/OldLeaderboard.java @@ -41,32 +41,35 @@ public class OldLeaderboard extends Composite { @UiField ParagraphElement lastScoringUpdateTextDiv; @UiField ParagraphElement lastScoringCommentDiv; @UiField ParagraphElement scoringSchemeDiv; + @UiField + EventRegattaLeaderboardResources local_res; private LeaderboardPanel leaderboardPanel; private Timer autoRefreshTimer; public OldLeaderboard() { this.leaderboardPanel = null; - EventRegattaLeaderboardResources.INSTANCE.css().ensureInjected(); OldLeaderboardResources.INSTANCE.css().ensureInjected(); - initWidget(uiBinder.createAndBindUi(this)); - settingsAnchor.setTitle(StringMessages.INSTANCE.settings()); autoRefreshAnchor.setTitle(StringMessages.INSTANCE.refresh()); } @UiHandler("autoRefreshAnchor") void toogleAutoRefreshClicked(ClickEvent event) { - if(autoRefreshTimer != null) { + autoRefreshAnchor.removeStyleName(local_res.css().regattaleaderboard_meta_reload_live()); + autoRefreshAnchor.removeStyleName(local_res.css().regattaleaderboard_meta_reload_playing()); + if (autoRefreshTimer != null) { if (autoRefreshTimer.getPlayState() == PlayStates.Playing) { autoRefreshTimer.pause(); - autoRefreshAnchor.getElement().getStyle().setBackgroundColor("#8ab54e"); + // autoRefreshAnchor.getElement().getStyle().setBackgroundColor("#8ab54e"); + // autoRefreshAnchor.addStyleName(local_res.css().regattaleaderboard_meta_reload_playing()); } else { // playing the standalone leaderboard means putting it into live mode autoRefreshTimer.setPlayMode(PlayModes.Live); - autoRefreshAnchor.getElement().getStyle().setBackgroundColor("red"); + // autoRefreshAnchor.getElement().getStyle().setBackgroundColor("red"); + autoRefreshAnchor.addStyleName(local_res.css().regattaleaderboard_meta_reload_live()); } } } @@ -87,12 +90,11 @@ public class OldLeaderboard extends Composite { public void setLeaderboard(LeaderboardPanel leaderboardPanel, final Timer timer) { this.autoRefreshTimer = timer; this.leaderboardPanel = leaderboardPanel; - oldLeaderboardPanel.add(leaderboardPanel); } public void updatedLeaderboard(LeaderboardDTO leaderboard, boolean hasLiveRace) { - if(leaderboard != null) { + if (leaderboard != null) { lastScoringCommentDiv.setInnerText(leaderboard.getComment() != null ? leaderboard.getComment() : ""); scoringSchemeDiv.setInnerText(leaderboard.scoringScheme != null ? ScoringSchemeTypeFormatter.getDescription(leaderboard.scoringScheme, StringMessages.INSTANCE) : ""); if (leaderboard.getTimePointOfLastCorrectionsValidity() != null) { @@ -105,7 +107,13 @@ public class OldLeaderboard extends Composite { lastScoringUpdateTimeDiv.setInnerText(""); lastScoringUpdateTextDiv.setInnerText(""); } + lastScoringUpdateTextDiv.getStyle().setVisibility(!hasLiveRace ? Visibility.VISIBLE : Visibility.HIDDEN); lastScoringUpdateTimeDiv.getStyle().setVisibility(!hasLiveRace ? Visibility.VISIBLE : Visibility.HIDDEN); } } + + public void hideRefresh() { + autoRefreshAnchor.setVisible(false); + lastScoringUpdateTimeDiv.getStyle().setVisibility(Visibility.HIDDEN); + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldleaderboard/OldLeaderboard.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldleaderboard/OldLeaderboard.ui.xml index 56f6dc4dbf8..f9f2813bf97 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldleaderboard/OldLeaderboard.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldleaderboard/OldLeaderboard.ui.xml @@ -6,13 +6,13 @@ - -
-
+ +
+

-
+

@@ -20,8 +20,10 @@
+
-
+
+
- - - - - - - - - - diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaTabView.java new file mode 100644 index 00000000000..266416e8488 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaTabView.java @@ -0,0 +1,7 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta; + +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; + +public interface RegattaTabView extends TabView { + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/TabletAndDesktopEventView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/TabletAndDesktopEventView.java new file mode 100644 index 00000000000..d611104801b --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/TabletAndDesktopEventView.java @@ -0,0 +1,134 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Style; +import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.uibinder.client.UiHandler; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.Anchor; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.IsWidget; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.common.client.LinkUtil; +import com.sap.sailing.gwt.common.client.SharedResources; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabPanel; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabPanelPlaceSelectionEvent; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.common.client.i18n.TextMessages; +import com.sap.sailing.gwt.home.client.app.ApplicationHistoryMapper; +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.place.event.partials.header.EventHeader; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesDefaultPlace; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO.EventType; + +public class TabletAndDesktopEventView extends Composite implements EventRegattaView { + private static final ApplicationHistoryMapper historyMapper = GWT + . create(ApplicationHistoryMapper.class); + + private static MyBinder uiBinder = GWT.create(MyBinder.class); + + private Presenter currentPresenter; + + interface MyBinder extends UiBinder { + } + + @UiField + StringMessages i18n; + + @UiField(provided = true) + TabPanel tabPanelUi; + + @UiField(provided = true) + EventHeader eventHeader; + + public TabletAndDesktopEventView() { + } + + @Override + public void registerPresenter(final Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + tabPanelUi = new TabPanel<>(currentPresenter, historyMapper); + + eventHeader = new EventHeader(currentPresenter); + + initWidget(uiBinder.createAndBindUi(this)); + + initBreadCrumbs(); + + if(currentPresenter.getCtx().getEventDTO().getType() == EventType.SERIES_EVENT) { + final PlaceNavigation currentEventSeriesNavigation = currentPresenter.getCurrentEventSeriesNavigation(); + Anchor seriesAnchor = new Anchor(currentPresenter.getCtx().getEventDTO().getSeriesName()); + seriesAnchor.setHref(currentEventSeriesNavigation.getTargetUrl()); + seriesAnchor.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + if (LinkUtil.handleLinkClick(event.getNativeEvent().cast())) { + event.preventDefault(); + currentEventSeriesNavigation.goToPlace(); + } + } + }); + seriesAnchor.setStyleName(SharedResources.INSTANCE.mainCss().button()); + seriesAnchor.addStyleName(SharedResources.INSTANCE.mainCss().buttonprimary()); + Style style = seriesAnchor.getElement().getStyle(); + style.setFontSize(16, Unit.PX); + style.setPadding(0.75, Unit.EM); + tabPanelUi.addTabExtension(seriesAnchor); + } + } + + @Override + public void navigateTabsTo(AbstractEventRegattaPlace place) { + tabPanelUi.activatePlace(place); + StringBuilder titleBuilder = new StringBuilder(TextMessages.INSTANCE.sapSailing()).append(" - "); + + titleBuilder.append(currentPresenter.showRegattaMetadata() ? currentPresenter.getRegattaMetadata() + .getDisplayName() : currentPresenter.getCtx().getEventDTO().getDisplayName()); + String currentTabTitle = tabPanelUi.getCurrentTabTitle(); + if (currentTabTitle != null && !currentTabTitle.isEmpty()) { + titleBuilder.append(" - ").append(currentTabTitle); + } + Window.setTitle(titleBuilder.toString()); + } + + @SuppressWarnings("unchecked") + @UiHandler("tabPanelUi") + public void onTabSelection(TabPanelPlaceSelectionEvent e) { + currentPresenter.handleTabPlaceSelection((TabView) e.getSelectedActivity()); + } + + private void initBreadCrumbs() { + addBreadCrumbItem(i18n.home(), currentPresenter.getHomeNavigation()); + addBreadCrumbItem(i18n.events(), currentPresenter.getEventsNavigation()); + if(currentPresenter.getCtx().getEventDTO().getType() == EventType.SERIES_EVENT) { + addBreadCrumbItem(currentPresenter.getCtx().getEventDTO().getSeriesName(), currentPresenter.getCurrentEventSeriesNavigation()); + } + addBreadCrumbItem(currentPresenter.getCtx().getEventDTO().getLocationOrDisplayName(), currentPresenter.getCurrentEventNavigation()); + + if(currentPresenter.showRegattaMetadata()) { + addBreadCrumbItem(currentPresenter.getRegattaMetadata().getDisplayName(), currentPresenter.getCurrentRegattaOverviewNavigation()); + } + } + + private void addBreadCrumbItem(String label, final PlaceNavigation placeNavigation) { + tabPanelUi.addBreadcrumbItem(label, placeNavigation.getTargetUrl(), new Runnable() { + @Override + public void run() { + placeNavigation.goToPlace(); + } + }); + } + + @Override + public void showErrorInCurrentTab(IsWidget errorView) { + tabPanelUi.overrideCurrentContentInTab(errorView); + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/TabletAndDesktopEventView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/TabletAndDesktopEventView.ui.xml new file mode 100644 index 00000000000..733602b111c --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/TabletAndDesktopEventView.ui.xml @@ -0,0 +1,70 @@ + + + + + .header { + position: relative; + width: 100%; + margin: 0; + padding: 0; + } + + .mainHeader { + width: 66.6666666666667%; + } + + .sharingHeader { + width: 33.3333333333333%; + float: right; + padding: 0 1rem; + position: + relative; + padding: 1.333333333333333em 0; + text-align: right; + + background-color: maroon; + height: 2rem; + } + + .breadcrumb, .intro { + box-sizing: border-box; + -moz-box-sizing: border-box; + } + + .breadcrumb { + font-size: 0.866666666666667em; + font-weight: 600; + } + + .intro { + height: 5em; + } + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaCompetitorAnalyticsPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaCompetitorAnalyticsPlace.java new file mode 100644 index 00000000000..a433f8b6669 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaCompetitorAnalyticsPlace.java @@ -0,0 +1,31 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta.tabs; + +import com.google.gwt.place.shared.Prefix; +import com.sap.sailing.gwt.home.client.place.event.AbstractEventPlace; +import com.sap.sailing.gwt.home.client.place.event.EventContext; +import com.sap.sailing.gwt.home.client.place.event.EventPrefixes; +import com.sap.sailing.gwt.home.client.place.event.regatta.AbstractEventRegattaPlace; + +public class RegattaCompetitorAnalyticsPlace extends AbstractEventRegattaPlace { + public RegattaCompetitorAnalyticsPlace(String id, String regattaId) { + super(id, regattaId); + } + + public RegattaCompetitorAnalyticsPlace(EventContext context) { + super(context); + } + + @Override + public AbstractEventRegattaPlace newInstanceWithContext(EventContext ctx) { + return new RegattaCompetitorAnalyticsPlace(ctx); + } + + @Prefix(EventPrefixes.RegattaCompetitorAnalytics) + public static class Tokenizer extends AbstractEventPlace.Tokenizer { + + @Override + protected RegattaCompetitorAnalyticsPlace getRealPlace(EventContext context) { + return new RegattaCompetitorAnalyticsPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaCompetitorAnalyticsTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaCompetitorAnalyticsTabView.java new file mode 100644 index 00000000000..c1fee41b07f --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaCompetitorAnalyticsTabView.java @@ -0,0 +1,139 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta.tabs; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.sap.sailing.domain.common.DetailType; +import com.sap.sailing.domain.common.RaceIdentifier; +import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.LeaderboardDTO; +import com.sap.sailing.domain.common.dto.RaceColumnDTO; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.place.event.oldcompetitorcharts.OldCompetitorCharts; +import com.sap.sailing.gwt.home.client.place.event.regatta.EventRegattaView; +import com.sap.sailing.gwt.home.client.place.event.regatta.EventRegattaView.Presenter; +import com.sap.sailing.gwt.home.client.place.event.regatta.RegattaAnalyticsDataManager; +import com.sap.sailing.gwt.home.client.shared.placeholder.Placeholder; +import com.sap.sailing.gwt.ui.client.CompetitorSelectionChangeListener; +import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel; +import com.sap.sse.common.Util; + +/** + * Created by pgtaboada on 25.11.14. + */ +public class RegattaCompetitorAnalyticsTabView extends SharedLeaderboardRegattaTabView { + + interface MyBinder extends UiBinder { + } + + private static MyBinder ourUiBinder = GWT.create(MyBinder.class); + private Presenter currentPresenter; + + private final int MAX_COMPETITORS_IN_CHART = 30; + + public RegattaCompetitorAnalyticsTabView() { + super(); + } + + @UiField + protected OldCompetitorCharts competitorCharts; + + @Override + public Class getPlaceClassForActivation() { + return RegattaCompetitorAnalyticsPlace.class; + } + + @Override + public TabView.State getState() { + return currentPresenter.getCtx().getEventDTO().isHasAnalytics() ? TabView.State.VISIBLE : TabView.State.INVISIBLE; + } + + @Override + public void start(RegattaCompetitorAnalyticsPlace myPlace, AcceptsOneWidget contentArea) { + contentArea.setWidget(new Placeholder()); + String regattaId = myPlace.getRegattaId(); + + if (regattaId != null && !regattaId.isEmpty()) { + String leaderboardName = regattaId; + RegattaAnalyticsDataManager regattaAnalyticsManager = currentPresenter.getCtx().getRegattaAnalyticsManager(); + if(regattaAnalyticsManager.getLeaderboardPanel() == null) { + createSharedLeaderboardPanel(leaderboardName, regattaAnalyticsManager); + } + + initWidget(ourUiBinder.createAndBindUi(this)); + + DetailType initialDetailType = DetailType.REGATTA_RANK; + if (regattaAnalyticsManager.getMultiCompetitorChart() == null) { + regattaAnalyticsManager.createMultiCompetitorChart(leaderboardName, initialDetailType); + } + competitorCharts.setChart(regattaAnalyticsManager.getMultiCompetitorChart(), getAvailableDetailsTypes(), + initialDetailType); + + regattaAnalyticsManager.showCompetitorChart(competitorCharts.getSelectedChartDetailType()); + contentArea.setWidget(this); + } + } + + private List getAvailableDetailsTypes() { + List availableDetailsTypes = new ArrayList(); + availableDetailsTypes.add(DetailType.REGATTA_RANK); + availableDetailsTypes.add(DetailType.REGATTA_TOTAL_POINTS_SUM); + return availableDetailsTypes; + } + + @Override + public void stop() { + } + + @Override + public RegattaCompetitorAnalyticsPlace placeToFire() { + return new RegattaCompetitorAnalyticsPlace(currentPresenter.getCtx()); + } + + @Override + public void setPresenter(EventRegattaView.Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + } + + public boolean isSmallWidth() { + int width = Window.getClientWidth(); + return width <= 720; + } + + @Override + public void updatedLeaderboard(LeaderboardDTO leaderboard) { + // adjust the competitor selection for the chart in case the leaderboard changed + updateCompetitorSelection(); + } + + private void updateCompetitorSelection() { + RegattaAnalyticsDataManager regattaAnalyticsManager = currentPresenter.getCtx().getRegattaAnalyticsManager(); + CompetitorSelectionModel competitorSelectionProvider = regattaAnalyticsManager.getCompetitorSelectionProvider(); + + // preselect the top N competitors in case there was no selection before and there too many competitors for a chart + int competitorsCount = Util.size(competitorSelectionProvider.getAllCompetitors()); + int selectedCompetitorsCount = Util.size(competitorSelectionProvider.getSelectedCompetitors()); + + if(selectedCompetitorsCount == 0 && competitorsCount > MAX_COMPETITORS_IN_CHART) { + List selectedCompetitors = new ArrayList(); + Iterator allCompetitorsIt = competitorSelectionProvider.getAllCompetitors().iterator(); + int counter = 0; + while(counter < MAX_COMPETITORS_IN_CHART) { + selectedCompetitors.add(allCompetitorsIt.next()); + counter++; + } + competitorSelectionProvider.setSelection(selectedCompetitors, (CompetitorSelectionChangeListener[]) null); + } + } + + @Override + public void currentRaceSelected(RaceIdentifier raceIdentifier, RaceColumnDTO raceColumn) { + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaCompetitorAnalyticsTabView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaCompetitorAnalyticsTabView.ui.xml new file mode 100644 index 00000000000..c4fb98c9694 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaCompetitorAnalyticsTabView.ui.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaLeaderboardPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaLeaderboardPlace.java new file mode 100644 index 00000000000..a05821360ba --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaLeaderboardPlace.java @@ -0,0 +1,30 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta.tabs; + +import com.google.gwt.place.shared.Prefix; +import com.sap.sailing.gwt.home.client.place.event.AbstractEventPlace; +import com.sap.sailing.gwt.home.client.place.event.EventContext; +import com.sap.sailing.gwt.home.client.place.event.EventPrefixes; +import com.sap.sailing.gwt.home.client.place.event.regatta.AbstractEventRegattaPlace; + +public class RegattaLeaderboardPlace extends AbstractEventRegattaPlace { + public RegattaLeaderboardPlace(String id, String regattaId) { + super(id, regattaId); + } + + public RegattaLeaderboardPlace(EventContext context) { + super(context); + } + + @Override + public AbstractEventRegattaPlace newInstanceWithContext(EventContext ctx) { + return new RegattaLeaderboardPlace(ctx); + } + + @Prefix(EventPrefixes.RegattaLeaderboard) + public static class Tokenizer extends AbstractEventPlace.Tokenizer { + @Override + protected RegattaLeaderboardPlace getRealPlace(EventContext context) { + return new RegattaLeaderboardPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaLeaderboardTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaLeaderboardTabView.java new file mode 100644 index 00000000000..1157b16b1b5 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaLeaderboardTabView.java @@ -0,0 +1,100 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta.tabs; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.google.gwt.user.client.ui.Label; +import com.sap.sailing.domain.common.RaceIdentifier; +import com.sap.sailing.domain.common.dto.LeaderboardDTO; +import com.sap.sailing.domain.common.dto.RaceColumnDTO; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.place.event.oldleaderboard.OldLeaderboard; +import com.sap.sailing.gwt.home.client.place.event.regatta.EventRegattaView; +import com.sap.sailing.gwt.home.client.place.event.regatta.EventRegattaView.Presenter; +import com.sap.sailing.gwt.home.client.place.event.regatta.RegattaAnalyticsDataManager; +import com.sap.sailing.gwt.home.client.shared.placeholder.Placeholder; +import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel; +import com.sap.sailing.gwt.ui.shared.general.EventState; + +/** + * Created by pgtaboada on 25.11.14. + */ +public class RegattaLeaderboardTabView extends SharedLeaderboardRegattaTabView { + interface MyBinder extends UiBinder { + } + + private static MyBinder ourUiBinder = GWT.create(MyBinder.class); + + private Presenter currentPresenter; + + @UiField + protected OldLeaderboard leaderboard; + + public RegattaLeaderboardTabView() { + super(); + } + + @Override + public Class getPlaceClassForActivation() { + return RegattaLeaderboardPlace.class; + } + + @Override + public void setPresenter(EventRegattaView.Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + } + + @Override + public TabView.State getState() { + return currentPresenter.getCtx().getEventDTO().isHasAnalytics() ? TabView.State.VISIBLE : TabView.State.INVISIBLE; + } + + @Override + public void start(final RegattaLeaderboardPlace myPlace, final AcceptsOneWidget contentArea) { + contentArea.setWidget(new Placeholder()); + String regattaId = myPlace.getRegattaId(); + if (regattaId != null && !regattaId.isEmpty()) { + String leaderboardName = regattaId; + RegattaAnalyticsDataManager regattaAnalyticsManager = currentPresenter.getCtx().getRegattaAnalyticsManager(); + LeaderboardPanel leaderboardPanel = regattaAnalyticsManager.getLeaderboardPanel(); + if(leaderboardPanel == null) { + leaderboardPanel = createSharedLeaderboardPanel(leaderboardName, regattaAnalyticsManager); + } + initWidget(ourUiBinder.createAndBindUi(this)); + leaderboard.setLeaderboard(leaderboardPanel, currentPresenter.getAutoRefreshTimer()); + if (currentPresenter.getCtx().getEventDTO().getState() == EventState.RUNNING) { + // TODO: start autorefresh? + } + regattaAnalyticsManager.hideCompetitorChart(); + contentArea.setWidget(this); + } else { + contentArea.setWidget(new Label("No leaderboard specified, cannot proceed to leaderboardpage")); + new com.google.gwt.user.client.Timer() { + @Override + public void run() { + currentPresenter.getHomeNavigation().goToPlace(); + } + }.schedule(3000); + } + } + + @Override + public void updatedLeaderboard(LeaderboardDTO leaderboard) { + this.leaderboard.updatedLeaderboard(leaderboard, true); + } + + @Override + public void currentRaceSelected(RaceIdentifier raceIdentifier, RaceColumnDTO raceColumn) { + } + + @Override + public void stop() { + } + + @Override + public RegattaLeaderboardPlace placeToFire() { + return new RegattaLeaderboardPlace(currentPresenter.getCtx()); + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaLeaderboardTabView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaLeaderboardTabView.ui.xml new file mode 100644 index 00000000000..56023e89c66 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaLeaderboardTabView.ui.xml @@ -0,0 +1,15 @@ + + + + .outerBox { + padding-top: 10px; + + } + + + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaMediaPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaMediaPlace.java new file mode 100644 index 00000000000..37849df2791 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaMediaPlace.java @@ -0,0 +1,31 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta.tabs; + +import com.google.gwt.place.shared.Prefix; +import com.sap.sailing.gwt.home.client.place.event.AbstractEventPlace; +import com.sap.sailing.gwt.home.client.place.event.EventContext; +import com.sap.sailing.gwt.home.client.place.event.EventPrefixes; +import com.sap.sailing.gwt.home.client.place.event.regatta.AbstractEventRegattaPlace; + +public class RegattaMediaPlace extends AbstractEventRegattaPlace { + public RegattaMediaPlace(String id, String regattaId) { + super(id, regattaId); + } + + public RegattaMediaPlace(EventContext context) { + super(context); + } + + @Override + public AbstractEventRegattaPlace newInstanceWithContext(EventContext ctx) { + return new RegattaMediaPlace(ctx); + } + + @Prefix(EventPrefixes.RegattaMedia) + public static class Tokenizer extends AbstractEventPlace.Tokenizer { + + @Override + protected RegattaMediaPlace getRealPlace(EventContext context) { + return new RegattaMediaPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaMediaTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaMediaTabView.java new file mode 100644 index 00000000000..c38a4588151 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaMediaTabView.java @@ -0,0 +1,84 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta.tabs; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.place.event.regatta.EventRegattaView; +import com.sap.sailing.gwt.home.client.place.event.regatta.RegattaTabView; +import com.sap.sailing.gwt.home.client.place.event.regatta.EventRegattaView.Presenter; +import com.sap.sailing.gwt.home.client.shared.media.MediaPage; +import com.sap.sailing.gwt.ui.shared.media.MediaDTO; + +/** + * Created by pgtaboada on 25.11.14. + */ +public class RegattaMediaTabView extends Composite implements RegattaTabView { + + public RegattaMediaTabView() { + + } + + @Override + public Class getPlaceClassForActivation() { + return RegattaMediaPlace.class; + } + + @Override + public TabView.State getState() { + return TabView.State.INVISIBLE; + // TODO return currentPresenter.hasMedia() ? TabView.State.VISIBLE : TabView.State.INVISIBLE; + } + + @Override + public void start(RegattaMediaPlace myPlace, AcceptsOneWidget contentArea) { + final MediaPage mediaPage = new MediaPage(); + + currentPresenter.ensureMedia(new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + // TODO Auto-generated method stub + + } + + @Override + public void onSuccess(MediaDTO media) { + mediaPage.setMedia(media); + } + }); + + initWidget(mediaPage); + + // TODO do we need UiBinder here? +// initWidget(ourUiBinder.createAndBindUi(this)); + + contentArea.setWidget(this); + } + + @Override + public void stop() { + + } + + // TODO delete UiBinder if we do not need it for the new media page implementation + interface MyBinder extends UiBinder { + } + + @SuppressWarnings("unused") + private static MyBinder ourUiBinder = GWT.create(MyBinder.class); + private Presenter currentPresenter; + + @Override + public RegattaMediaPlace placeToFire() { + return new RegattaMediaPlace(currentPresenter.getCtx()); + } + + @Override + public void setPresenter(EventRegattaView.Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + } + +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaMediaTabView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaMediaTabView.ui.xml new file mode 100644 index 00000000000..c149137f7f0 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaMediaTabView.ui.xml @@ -0,0 +1,6 @@ + + +

This is MEDIA tab

+
+
\ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaOverviewPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaOverviewPlace.java new file mode 100644 index 00000000000..e93f67324fe --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaOverviewPlace.java @@ -0,0 +1,31 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta.tabs; + +import com.google.gwt.place.shared.Prefix; +import com.sap.sailing.gwt.home.client.place.event.AbstractEventPlace; +import com.sap.sailing.gwt.home.client.place.event.EventContext; +import com.sap.sailing.gwt.home.client.place.event.EventPrefixes; +import com.sap.sailing.gwt.home.client.place.event.regatta.AbstractEventRegattaPlace; + +public class RegattaOverviewPlace extends AbstractEventRegattaPlace { + public RegattaOverviewPlace(String id, String regattaId) { + super(id, regattaId); + } + + public RegattaOverviewPlace(EventContext context) { + super(context); + } + + @Override + public AbstractEventRegattaPlace newInstanceWithContext(EventContext ctx) { + return new RegattaOverviewPlace(ctx); + } + + @Prefix(EventPrefixes.RegattaOverview) + public static class Tokenizer extends AbstractEventPlace.Tokenizer { + + @Override + protected RegattaOverviewPlace getRealPlace(EventContext context) { + return new RegattaOverviewPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaOverviewTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaOverviewTabView.java new file mode 100644 index 00000000000..d5dad70100f --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaOverviewTabView.java @@ -0,0 +1,62 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta.tabs; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.place.event.regatta.EventRegattaView; +import com.sap.sailing.gwt.home.client.place.event.regatta.EventRegattaView.Presenter; +import com.sap.sailing.gwt.home.client.place.event.regatta.RegattaTabView; + +/** + * Created by pgtaboada on 25.11.14. + */ +public class RegattaOverviewTabView extends Composite implements RegattaTabView { + + public RegattaOverviewTabView() { + + } + + @Override + public Class getPlaceClassForActivation() { + return RegattaOverviewPlace.class; + } + + @Override + public TabView.State getState() { + return TabView.State.NOT_AVAILABLE_SHOW_NEXT_AVAILABLE; + } + + @Override + public void start(RegattaOverviewPlace myPlace, AcceptsOneWidget contentArea) { + + initWidget(ourUiBinder.createAndBindUi(this)); + + contentArea.setWidget(this); + } + + @Override + public void stop() { + + } + + interface MyBinder extends UiBinder { + } + + private static MyBinder ourUiBinder = GWT.create(MyBinder.class); + private Presenter currentPresenter; + + @Override + public RegattaOverviewPlace placeToFire() { + return new RegattaOverviewPlace(currentPresenter.getCtx()); + } + + @Override + public void setPresenter(EventRegattaView.Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + + } + +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaOverviewTabView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaOverviewTabView.ui.xml new file mode 100644 index 00000000000..927b29d4a6e --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaOverviewTabView.ui.xml @@ -0,0 +1,7 @@ + + + +

This is regatta overview tab

+
+
\ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaRacesPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaRacesPlace.java new file mode 100644 index 00000000000..b044d7b6aaa --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaRacesPlace.java @@ -0,0 +1,30 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta.tabs; + +import com.google.gwt.place.shared.Prefix; +import com.sap.sailing.gwt.home.client.place.event.AbstractEventPlace; +import com.sap.sailing.gwt.home.client.place.event.EventContext; +import com.sap.sailing.gwt.home.client.place.event.EventPrefixes; +import com.sap.sailing.gwt.home.client.place.event.regatta.AbstractEventRegattaPlace; + +public class RegattaRacesPlace extends AbstractEventRegattaPlace { + public RegattaRacesPlace(String id, String leaderboardName) { + super(id, leaderboardName); + } + + public RegattaRacesPlace(EventContext context) { + super(context); + } + + @Override + public AbstractEventRegattaPlace newInstanceWithContext(EventContext ctx) { + return new RegattaRacesPlace(ctx); + } + + @Prefix(EventPrefixes.RegattaRaces) + public static class Tokenizer extends AbstractEventPlace.Tokenizer { + @Override + protected RegattaRacesPlace getRealPlace(EventContext context) { + return new RegattaRacesPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaRacesTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaRacesTabView.java new file mode 100644 index 00000000000..33cec046313 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaRacesTabView.java @@ -0,0 +1,130 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta.tabs; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.place.event.partials.regattaraces.EventRegattaRaces; +import com.sap.sailing.gwt.home.client.place.event.regatta.EventRegattaView.Presenter; +import com.sap.sailing.gwt.home.client.place.event.regatta.RegattaTabView; +import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; +import com.sap.sailing.gwt.ui.shared.RaceGroupDTO; +import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; +import com.sap.sse.common.Util.Triple; + +/** + * Created by pgtaboada on 25.11.14. + */ +public class RegattaRacesTabView extends Composite implements RegattaTabView { + + interface MyBinder extends UiBinder { + } + + private static MyBinder ourUiBinder = GWT.create(MyBinder.class); + + private Presenter currentPresenter; + + @UiField(provided = true) + protected EventRegattaRaces regattaRaces; + + public RegattaRacesTabView() { + + } + + @Override + public void setPresenter(Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + + } + + @Override + public TabView.State getState() { + return TabView.State.VISIBLE; + } + + @Override + public void start(RegattaRacesPlace myPlace, final AcceptsOneWidget contentArea) { + + // TODO: understand, and than move this into appropiate place (probably context) + final String selectedRegattaId = myPlace.getCtx().getRegattaId(); + + currentPresenter.ensureRegattaStructure(new AsyncCallback>() { + @Override + public void onSuccess(List raceGroups) { + if (raceGroups.size() > 0) { + Map> regattaStructure = getRegattaStructure(); + + Triple selectedRegatta = regattaStructure + .get(selectedRegattaId); + + regattaRaces = new EventRegattaRaces(currentPresenter); + + regattaRaces.setRaces(selectedRegatta.getC(), false, selectedRegatta.getB(), + selectedRegatta.getA()); + + // if (eventDTO.isRunning()) { + // // create update time for race states only for running events + // serverUpdateTimer.addTimeListener(new TimeListener() { + // @Override + // public void timeChanged(Date newTime, Date oldTime) { + // loadAndUpdateEventRaceStatesLog(); + // } + // }); + // } + initWidget(ourUiBinder.createAndBindUi(RegattaRacesTabView.this)); + contentArea.setWidget(RegattaRacesTabView.this); + } else { + // createEventWithoutRegattasView(event, panel); + } + } + + @Override + public void onFailure(Throwable caught) { + // createErrorView( + // "Error while loading the regatta structure with service getRegattaStructureOfEvent()", + // caught, panel); + } + }); + } + + @Override + public void stop() { + + } + + @Override + public RegattaRacesPlace placeToFire() { + return new RegattaRacesPlace(currentPresenter.getCtx()); + } + + @Override + public Class getPlaceClassForActivation() { + return RegattaRacesPlace.class; + } + + private Map> getRegattaStructure() { + Map> result = new HashMap<>(); + Map raceGroupsMap = new HashMap<>(); + for (RaceGroupDTO raceGroup : currentPresenter.getCtx().getRaceGroups()) { + raceGroupsMap.put(raceGroup.getName(), raceGroup); + } + + for (LeaderboardGroupDTO leaderboardGroup : currentPresenter.getCtx().getLeaderboardGroups()) { + for (StrippedLeaderboardDTO leaderboard : leaderboardGroup.getLeaderboards()) { + String leaderboardName = leaderboard.name; + result.put(leaderboardName, new Triple( + raceGroupsMap.get(leaderboardName), leaderboard, leaderboardGroup)); + } + } + return result; + } + +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaRacesTabView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaRacesTabView.ui.xml new file mode 100644 index 00000000000..aa3273ec11a --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/RegattaRacesTabView.ui.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/SharedLeaderboardRegattaTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/SharedLeaderboardRegattaTabView.java new file mode 100644 index 00000000000..a681f82c2f9 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/tabs/SharedLeaderboardRegattaTabView.java @@ -0,0 +1,41 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta.tabs; + +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.Composite; +import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; +import com.sap.sailing.gwt.home.client.place.event.regatta.AbstractEventRegattaPlace; +import com.sap.sailing.gwt.home.client.place.event.regatta.RegattaAnalyticsDataManager; +import com.sap.sailing.gwt.home.client.place.event.regatta.RegattaTabView; +import com.sap.sailing.gwt.home.client.place.event.utils.EventParamUtils; +import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener; +import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel; +import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings; +import com.sap.sailing.gwt.ui.leaderboard.LeaderboardUrlSettings; +import com.sap.sse.gwt.shared.GwtHttpRequestUtils; + +/** + * An abstract regatta tabView with some shared functions between the leaderboard tab and competitors chart tab + */ +public abstract class SharedLeaderboardRegattaTabView extends Composite implements RegattaTabView, + LeaderboardUpdateListener { + + public SharedLeaderboardRegattaTabView() { + } + + public LeaderboardPanel createSharedLeaderboardPanel(String leaderboardName, RegattaAnalyticsDataManager regattaAnalyticsManager) { + boolean autoExpandLastRaceColumn = GwtHttpRequestUtils.getBooleanParameter( + LeaderboardUrlSettings.PARAM_AUTO_EXPAND_LAST_RACE_COLUMN, false); + final LeaderboardSettings leaderboardSettings = EventParamUtils + .createLeaderboardSettingsFromURLParameters(Window.Location.getParameterMap()); + final RegattaAndRaceIdentifier preselectedRace = EventParamUtils.getPreselectedRace(Window.Location.getParameterMap()); + LeaderboardPanel leaderboardPanel = regattaAnalyticsManager.createLeaderboardPanel( // + leaderboardSettings, // + preselectedRace, // + "leaderboardGroupName", // TODO: keep using magic string? ask frank! + leaderboardName, // + true, + autoExpandLastRaceColumn); + leaderboardPanel.addLeaderboardUpdateListener(this); + return leaderboardPanel; + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalytics.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalytics.css deleted file mode 100644 index 15352534e8d..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalytics.css +++ /dev/null @@ -1,5 +0,0 @@ -.oldLeaderboardPanel { - background-color:#f8f8f8; - padding: 0 10px 10px 10px; - width: 100%; -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalytics.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalytics.java deleted file mode 100644 index 5decb1a1230..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalytics.java +++ /dev/null @@ -1,209 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.regattaanalytics; - -import java.util.ArrayList; -import java.util.List; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.dom.client.DivElement; -import com.google.gwt.dom.client.SpanElement; -import com.google.gwt.dom.client.Style.Visibility; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.uibinder.client.UiHandler; -import com.google.gwt.user.client.Event; -import com.google.gwt.user.client.History; -import com.google.gwt.user.client.ui.Anchor; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.HTMLPanel; -import com.google.gwt.user.client.ui.Widget; -import com.google.gwt.user.client.ui.impl.HyperlinkImpl; -import com.sap.sailing.domain.common.DetailType; -import com.sap.sailing.domain.common.RaceIdentifier; -import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; -import com.sap.sailing.domain.common.dto.FleetDTO; -import com.sap.sailing.domain.common.dto.LeaderboardDTO; -import com.sap.sailing.domain.common.dto.RaceColumnDTO; -import com.sap.sailing.gwt.common.client.SharedResources; -import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; -import com.sap.sailing.gwt.home.client.app.PlaceNavigation; -import com.sap.sailing.gwt.home.client.place.event.header.CompactEventHeader; -import com.sap.sailing.gwt.home.client.place.event.oldcompetitorcharts.OldCompetitorCharts; -import com.sap.sailing.gwt.home.client.place.event.oldleaderboard.OldLeaderboard; -import com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources; -import com.sap.sailing.gwt.home.client.place.regatta.RegattaPlace; -import com.sap.sailing.gwt.home.client.place.regatta.RegattaPlace.RegattaNavigationTabs; -import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener; -import com.sap.sailing.gwt.ui.client.SailingServiceAsync; -import com.sap.sailing.gwt.ui.client.StringMessages; -import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sse.common.Util.Pair; -import com.sap.sse.gwt.client.ErrorReporter; -import com.sap.sse.gwt.client.async.AsyncActionsExecutor; -import com.sap.sse.gwt.client.player.Timer; -import com.sap.sse.gwt.client.useragent.UserAgentDetails; - -public class RegattaAnalytics extends Composite implements LeaderboardUpdateListener { - private static RegattaAnalyticsUiBinder uiBinder = GWT.create(RegattaAnalyticsUiBinder.class); - - interface RegattaAnalyticsUiBinder extends UiBinder { - } - - private static final HyperlinkImpl HYPERLINK_IMPL = GWT.create(HyperlinkImpl.class); - - @UiField OldLeaderboard oldLeaderboardComposite; - @UiField OldCompetitorCharts oldCompetitorChartsComposite; - @UiField(provided=true) CompactEventHeader eventHeader; - - @UiField SpanElement title; - @UiField DivElement liveRaceDiv; - - @UiField HTMLPanel leaderboardTabPanel; - @UiField HTMLPanel competitorChartsTabPanel; - private HTMLPanel activeTabPanel; - private Anchor activeAnchor; - - @UiField Anchor leaderboardAnchor; - @UiField Anchor competitorChartsAnchor; - - private final PlaceNavigation leaderboardNavigation; - private final PlaceNavigation competitorChartsNavigation; - - private RegattaAnalyticsDataManager regattaAnalyticsManager; - private Timer autoRefreshTimer; - private RegattaNavigationTabs navigationTab; - - public RegattaAnalytics(EventDTO event, String leaderboardName, RegattaNavigationTabs navigationTab, Timer timerForClientServerOffset, HomePlacesNavigator placesNavigator) { - this.navigationTab = navigationTab; - - eventHeader = new CompactEventHeader(event, leaderboardName, placesNavigator); - - EventRegattaLeaderboardResources.INSTANCE.css().ensureInjected(); - RegattaAnalyticsResources.INSTANCE.css().ensureInjected(); - - initWidget(uiBinder.createAndBindUi(this)); - - title.setInnerText(leaderboardName); - - competitorChartsTabPanel.setVisible(false); - leaderboardTabPanel.setVisible(false); - liveRaceDiv.getStyle().setVisibility(Visibility.HIDDEN); - - leaderboardNavigation = placesNavigator.getRegattaAnalyticsNavigation(event.id.toString(), RegattaNavigationTabs.Leaderboard, leaderboardName, - event.getBaseURL(), event.isOnRemoteServer()); - competitorChartsNavigation = placesNavigator.getRegattaAnalyticsNavigation(event.id.toString(), RegattaNavigationTabs.CompetitorAnalytics, leaderboardName, - event.getBaseURL(), event.isOnRemoteServer()); - - leaderboardAnchor.setHref(leaderboardNavigation.getTargetUrl()); - competitorChartsAnchor.setHref(competitorChartsNavigation.getTargetUrl()); - } - - public void createRegattaAnalyticsViewer(final SailingServiceAsync sailingService, final AsyncActionsExecutor asyncActionsExecutor, - final Timer timer, final LeaderboardSettings leaderboardSettings, final RegattaAndRaceIdentifier preselectedRace, - final String leaderboardGroupName, String leaderboardName, final ErrorReporter errorReporter, - final UserAgentDetails userAgent, boolean showRaceDetails, - boolean autoExpandLastRaceColumn, boolean showOverallLeaderboard) { - this.autoRefreshTimer = timer; - regattaAnalyticsManager = new RegattaAnalyticsDataManager(sailingService, asyncActionsExecutor, timer, errorReporter, userAgent); - regattaAnalyticsManager.createLeaderboardPanel(leaderboardSettings, preselectedRace, leaderboardGroupName, - leaderboardName, showRaceDetails, autoExpandLastRaceColumn); - - List availableDetailsTypes = new ArrayList(); - DetailType initialDetailType = DetailType.REGATTA_RANK; - availableDetailsTypes.add(DetailType.REGATTA_RANK); - availableDetailsTypes.add(DetailType.REGATTA_TOTAL_POINTS_SUM); - regattaAnalyticsManager.createMultiCompetitorChart(leaderboardName, initialDetailType); - - oldLeaderboardComposite.setLeaderboard(regattaAnalyticsManager.getLeaderboardPanel(), autoRefreshTimer); - regattaAnalyticsManager.getLeaderboardPanel().addLeaderboardUpdateListener(this); - - oldCompetitorChartsComposite.setChart(regattaAnalyticsManager.getMultiCompetitorChart(), availableDetailsTypes, initialDetailType); - regattaAnalyticsManager.hideCompetitorChart(); - - switch(navigationTab) { - case Leaderboard: - setActiveTabPanel(leaderboardTabPanel, leaderboardAnchor); - break; - case CompetitorAnalytics: - setActiveTabPanel(competitorChartsTabPanel, competitorChartsAnchor); - DetailType selectedChartDetailType = oldCompetitorChartsComposite.getSelectedChartDetailType(); - regattaAnalyticsManager.showCompetitorChart(selectedChartDetailType); - break; - } - } - - @Override - public void updatedLeaderboard(LeaderboardDTO leaderboard) { - if(activeTabPanel == leaderboardTabPanel) { - StringMessages stringMessages = StringMessages.INSTANCE; - - if(leaderboard != null) { - List> liveRaces = leaderboard.getLiveRaces(autoRefreshTimer.getLiveTimePointInMillis()); - boolean hasLiveRace = !liveRaces.isEmpty(); - if (hasLiveRace) { - String liveRaceText = ""; - if(liveRaces.size() == 1) { - Pair liveRace = liveRaces.get(0); - liveRaceText = stringMessages.raceIsLive("'" + liveRace.getA().getRaceColumnName() + "'"); - } else { - String raceNames = ""; - for (Pair liveRace : liveRaces) { - raceNames += "'" + liveRace.getA().getRaceColumnName() + "', "; - } - // remove last ", " - raceNames = raceNames.substring(0, raceNames.length() - 2); - liveRaceText = stringMessages.racesAreLive(raceNames); - } - liveRaceDiv.setInnerText(liveRaceText); - } else { - liveRaceDiv.setInnerText(""); - } - liveRaceDiv.getStyle().setVisibility(hasLiveRace ? Visibility.VISIBLE : Visibility.HIDDEN); - - oldLeaderboardComposite.updatedLeaderboard(leaderboard, hasLiveRace); - } - } - } - - @Override - public void currentRaceSelected(RaceIdentifier raceIdentifier, RaceColumnDTO raceColumn) { - } - - @UiHandler("leaderboardAnchor") - void leaderboardTabClicked(ClickEvent event) { - setActiveTabPanel(leaderboardTabPanel, leaderboardAnchor); - regattaAnalyticsManager.hideCompetitorChart(); - handleClickEvent(event, leaderboardNavigation); - } - - @UiHandler("competitorChartsAnchor") - void competitorChartsTabClicked(ClickEvent event) { - setActiveTabPanel(competitorChartsTabPanel, competitorChartsAnchor); - DetailType selectedChartDetailType = oldCompetitorChartsComposite.getSelectedChartDetailType(); - regattaAnalyticsManager.showCompetitorChart(selectedChartDetailType); - oldCompetitorChartsComposite.updateSelectionState(regattaAnalyticsManager.getCompetitorSelectionProvider()); - handleClickEvent(event, competitorChartsNavigation); - } - - private void setActiveTabPanel(HTMLPanel newActivePanel, Anchor newActiveAnchor) { - if(activeTabPanel != null) { - activeTabPanel.setVisible(false); - activeAnchor.removeStyleName(SharedResources.INSTANCE.mainCss().navbar_buttonactive()); - } - - activeTabPanel = newActivePanel; - activeAnchor = newActiveAnchor; - activeTabPanel.setVisible(true); - activeAnchor.addStyleName(SharedResources.INSTANCE.mainCss().navbar_buttonactive()); - } - - private void handleClickEvent(ClickEvent e, PlaceNavigation placeNavigation) { - if (HYPERLINK_IMPL.handleAsClick((Event) e.getNativeEvent())) { - // don't use the placecontroller for navigation here as we want to avoid a page reload - History.newItem(placeNavigation.getHistoryUrl(), false); - e.preventDefault(); - } - } -} - diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalytics.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalytics.ui.xml deleted file mode 100644 index 5ac6f2a3d85..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalytics.ui.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - -
-
-

- - -

-
- -
-
-
- - -
-
- - - - - - -
-
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalyticsResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalyticsResources.java deleted file mode 100644 index af11376b30a..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalyticsResources.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.regattaanalytics; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.resources.client.ClientBundle; -import com.google.gwt.resources.client.CssResource; - -public interface RegattaAnalyticsResources extends ClientBundle { - public static final RegattaAnalyticsResources INSTANCE = GWT.create(RegattaAnalyticsResources.class); - - @Source("com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalytics.css") - LocalCss css(); - - public interface LocalCss extends CssResource { - String oldLeaderboardPanel(); - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaheader/EventRegattaHeader.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaheader/EventRegattaHeader.gss deleted file mode 100644 index 07553abf5ff..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaheader/EventRegattaHeader.gss +++ /dev/null @@ -1,164 +0,0 @@ -/** - * The header of a regatta of an event - */ -.eventregattaheader { - font-size: 16px; - font-size: 1rem; -} -.regattanavigation { - font-size: 16px; - font-size: 1rem; - text-align: center; - border-bottom: 1px solid #ddd; -} -.regattanavigation_link { - display: inline-block; - margin-right: 1.875em; - padding: 0.9375em 0 0.6875em 0; - border-bottom: 0.25em solid transparent; - font-weight: 600; - color: #666; -} -.regattanavigation_link:hover, -.regattanavigation_link:focus { - border-bottom-color: #ddd; - text-decoration: none; - color: #333; -} -.regattanavigation_linkactive { - border-bottom-color: #f0ab00; -} -.regattanavigation_linkactive:hover, -.regattanavigation_linkactive:focus { - border-bottom-color: #d89a00; -} -.regatta { - font-size: 16px; - font-size: 1rem; - border-bottom: 1px solid #d9d9d9; - padding: 1.25em 0; -} -.regattacompact { - border-top: 1px solid #ccc; - padding-left: 3.75em; - padding-right: 3.75em; -} -.regattacompact .regatta_intro_details_itemhideoncompact { - display: none; -} -.regattalink:hover { - background-color: #fafafa; -} -.regattalink:hover .regatta_intro_image { - opacity: 0.9; - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)"; - filter: alpha(opacity=90); -} -.regattalink:nth-child(even) { - background-color: #f8f8f8; -} -.regattalink:nth-child(even):hover { - background-color: #f3f3f3; -} -.regatta_intro { - display: block; - padding-left: 9.6875em; - min-height: 8.75em; - position: relative; -} -.regatta_intro:hover, -.regatta_intro:focus { - text-decoration: none; -} -.regatta_intro_image { - border: 1px solid #ccc; - position: absolute; - top: 0; - left: 0; -} -.regatta_intro_header { - margin-bottom: 0.625em; - padding-top: 0.3125em; - padding-bottom: 0.625em; - border-bottom: 1px solid #d9d9d9; - position: relative; -} -.regatta_intro_header_logo { - vertical-align: middle; -} -.regatta_intro_header_name { - display: inline-block; - font-size: 1.25em; - margin: 0; - margin-right: 0.25em; -} -.regatta_intro_header_name:hover { - text-decoration: underline; -} -.regatta_intro_header_labels { - display: inline-block; - position: absolute; - right: 0; - top: 0.1875em; -} -.regatta_intro_header_labels .label { - vertical-align: baseline; -} -.regatta_intro_races { - position: relative; - min-height: 1.875em; - margin-bottom: 0.625em; - padding-bottom: 0.625em; - padding-left: 0.3125em; - border-bottom: 1px solid #d9d9d9; -} -.regatta_intro_races_race { - display: inline-block; - background-color: #ccc; - height: 0.625em; - width: 0.9375em; - -webkit-transform: skew(-45deg); - -moz-transform: skew(-45deg); - -o-transform: skew(-45deg); - -ms-transform: skew(-45deg); - transform: skew(-45deg); -} -.regatta_intro_races_race[data-finished='true'], -.regatta_intro_races_race[data-finished='data-finished'] { - background-color: #f0ab00; -} -.regatta_intro_meta { - position: relative; - font-weight: 600; -} -.regatta_intro_meta_scoring { - color: #008fcc; - display: inline-block; -} -.regatta_intro_meta_leaderboardlink { - position: absolute; - top: 0; - right: 0; - text-transform: uppercase; - line-height: 2.8125em; -} -.regatta_intro_details { - font-weight: 600; - color: #666; -} -.regatta_intro_details_item { - display: inline-block; - margin-right: 2.1875em; -} -.regatta_intro_details_item:last-child { - margin-right: 0; -} -.regatta_intro_details_item_sub { - display: inline; -} -.regatta_intro_details_item_sub:last-child:after { - content: ''; -} -.regatta_intro_details_item_value { - color: #008fcc; -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaheader/EventRegattaHeader.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaheader/EventRegattaHeader.java deleted file mode 100644 index ca66d13baba..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaheader/EventRegattaHeader.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.regattaheader; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.dom.client.DivElement; -import com.google.gwt.dom.client.SpanElement; -import com.google.gwt.dom.client.Style.Visibility; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.uibinder.client.UiHandler; -import com.google.gwt.user.client.ui.Anchor; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.gwt.home.client.place.event.EventPlaceNavigator; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; -import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; -import com.sap.sse.gwt.client.player.Timer; - -public class EventRegattaHeader extends Composite { - private static EventRegattaHeaderUiBinder uiBinder = GWT.create(EventRegattaHeaderUiBinder.class); - - interface EventRegattaHeaderUiBinder extends UiBinder { - } - - @SuppressWarnings("unused") - private final EventDTO event; - private final Timer timerForClientServerOffset; - private final EventPlaceNavigator pageNavigator; - private StrippedLeaderboardDTO leaderboard; - - @UiField SpanElement regattaName; - @UiField SpanElement leaderboardGroupName; - @UiField SpanElement regattaPhase; - @UiField SpanElement competitorsCount; - @UiField DivElement isLiveDiv; - @UiField Anchor leaderboardLink; - - public EventRegattaHeader(EventDTO event, Timer timerForClientServerOffset, EventPlaceNavigator pageNavigator) { - this.event = event; - this.timerForClientServerOffset = timerForClientServerOffset; - this.pageNavigator = pageNavigator; - - EventRegattaHeaderResources.INSTANCE.css().ensureInjected(); - initWidget(uiBinder.createAndBindUi(this)); - } - - public void setData(LeaderboardGroupDTO leaderboardGroup, StrippedLeaderboardDTO leaderboard) { - this.leaderboard = leaderboard; - - boolean hasLiveRace = leaderboard.hasLiveRace(timerForClientServerOffset.getLiveTimePointInMillis()); - isLiveDiv.setAttribute("data-labeltype", hasLiveRace ? "live" : ""); - - regattaName.setInnerText(leaderboard.displayName != null ? leaderboard.displayName : leaderboard.name); - leaderboardGroupName.setInnerText(leaderboardGroup.getName()); - - if(leaderboard.rows != null) { - competitorsCount.setInnerText(String.valueOf(leaderboard.rows.size())); - } else { - competitorsCount.getStyle().setVisibility(Visibility.HIDDEN); - } - regattaPhase.setInnerText(calculateCurrentRegattaPhase(leaderboard)); - } - - private String calculateCurrentRegattaPhase(StrippedLeaderboardDTO leaderboard) { - return ""; - } - - @UiHandler("leaderboardLink") - public void goToLeaderboard(ClickEvent e) { - pageNavigator.openLeaderboardViewer(null, leaderboard); - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaheader/EventRegattaHeader.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaheader/EventRegattaHeader.ui.xml deleted file mode 100644 index 5a4f9ec1f1f..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaheader/EventRegattaHeader.ui.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - -
- -
-
-
-
-
- -

-
-
-
-
-
-
-
Phase -
-
-
- Leaderboard -
-
-
-
-
-
-
-
 
-
-
-
-
-
-
- -
- - -
-
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaheader/EventRegattaHeaderResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaheader/EventRegattaHeaderResources.java deleted file mode 100644 index f346f4c0e51..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaheader/EventRegattaHeaderResources.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.regattaheader; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.resources.client.ClientBundle; -import com.google.gwt.resources.client.CssResource; - -public interface EventRegattaHeaderResources extends ClientBundle { - public static final EventRegattaHeaderResources INSTANCE = GWT.create(EventRegattaHeaderResources.class); - - @Source("com/sap/sailing/gwt/home/client/place/event/regattaheader/EventRegattaHeader.gss") - LocalCss css(); - - public interface LocalCss extends CssResource { - String eventregattaheader(); - String regattanavigation(); - String regattanavigation_link(); - String regattanavigation_linkactive(); - String regatta(); - String regattacompact(); - String regatta_intro_details_itemhideoncompact(); - String regattalink(); - String regatta_intro_image(); - String regatta_intro(); - String regatta_intro_header(); - String regatta_intro_header_logo(); - String regatta_intro_header_name(); - String regatta_intro_header_labels(); - String label(); - String regatta_intro_races(); - String regatta_intro_races_race(); - String regatta_intro_meta(); - String regatta_intro_meta_scoring(); - String regatta_intro_meta_leaderboardlink(); - String regatta_intro_details(); - String regatta_intro_details_item(); - String regatta_intro_details_item_sub(); - String regatta_intro_details_item_value(); - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/EventRegattaLeaderboard.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/EventRegattaLeaderboard.gss similarity index 93% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/EventRegattaLeaderboard.css rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/EventRegattaLeaderboard.gss index 427b670805c..0e653bcf738 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/EventRegattaLeaderboard.css +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/EventRegattaLeaderboard.gss @@ -41,7 +41,7 @@ margin-left: 5rem; margin-right: 5rem; font-size: 15px; - font-size: 1rem; + /* @alternate */ font-size: 1rem; width: 100%; } .regattaleaderboard_meta { @@ -94,11 +94,19 @@ background-position: center center; } .regattaleaderboard_meta_reload { - background-color: #8ab54e; + background-color: #9f9f9f; background-image: url("images/home/reload.png"); } +.regattaleaderboard_meta_reload_live { + background-color: red; +} +.regattaleaderboard_meta_reload_playing { + background-color: #f0ab00; +} + + .regattaleaderboard_meta_reload:hover { - background-color: #7ca445; + background-color: #909090; } .regattaleaderboard_meta_settings { display: inline-block; @@ -108,12 +116,12 @@ width: 2.666666666666667em; height: 2.666666666666667em; margin: 0 0 0 0.666666666666667em; - background-color: #f0ab00; + background-color: #9f9f9f; background-image: url("images/home/settings.png"); - background-size: 50%; + background-size: 40%; } .regattaleaderboard_table { - margin-top: 0.666666666666667em; + margin-bottom: 20px; } .regattaleaderboard_header { background: #f2f2f2; @@ -208,3 +216,10 @@ width: 100%; table-layout: fixed; } +.marginFix { + margin-top:2rem; +} +.letItScroll { + overflow-x: auto; + margin: 10px 0px; +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/EventRegattaLeaderboard.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/EventRegattaLeaderboard.ui.xml deleted file mode 100644 index 3870de9a216..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/EventRegattaLeaderboard.ui.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - -
-
-
-

{#if navigation.isLive} -
{/if navigation.isLive} -
-
-
-
-

{leaderboard.scoringComment}

-

-
-
-
-

-

{leaderboard.lastScoringUpdate}

-
-
-
-
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldmultileaderboard/OldMultiLeaderboard.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldmultileaderboard/OldMultiLeaderboard.css index 4dc5ec994e4..03187bbfe5a 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldmultileaderboard/OldMultiLeaderboard.css +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldmultileaderboard/OldMultiLeaderboard.css @@ -1,6 +1,2 @@ .oldMultiLeaderboardPanel { - background-color:#f8f8f8; - padding: 0 10px 10px 10px; - width: 100%; - font-weight: bold; } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldmultileaderboard/OldMultiLeaderboard.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldmultileaderboard/OldMultiLeaderboard.java index 40195da6306..374edd07d03 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldmultileaderboard/OldMultiLeaderboard.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldmultileaderboard/OldMultiLeaderboard.java @@ -40,7 +40,10 @@ public class OldMultiLeaderboard extends Composite { @UiField ParagraphElement lastScoringUpdateTimeDiv; @UiField ParagraphElement lastScoringUpdateTextDiv; @UiField ParagraphElement lastScoringCommentDiv; - @UiField ParagraphElement scoringSchemeDiv; + @UiField + ParagraphElement scoringSchemeDiv; + @UiField + EventRegattaLeaderboardResources local_res; private MultiLeaderboardPanel multiLeaderboardPanel; private Timer autoRefreshTimer; @@ -57,13 +60,18 @@ public class OldMultiLeaderboard extends Composite { @UiHandler("autoRefreshAnchor") void toogleAutoRefreshClicked(ClickEvent event) { if(autoRefreshTimer != null) { + autoRefreshAnchor.removeStyleName(local_res.css().regattaleaderboard_meta_reload_live()); + autoRefreshAnchor.removeStyleName(local_res.css().regattaleaderboard_meta_reload_playing()); if (autoRefreshTimer.getPlayState() == PlayStates.Playing) { autoRefreshTimer.pause(); - autoRefreshAnchor.getElement().getStyle().setBackgroundColor("#f0ab00"); + // autoRefreshAnchor.getElement().getStyle().setBackgroundColor("#f0ab00"); + // autoRefreshAnchor.addStyleName(local_res.css().regattaleaderboard_meta_reload_playing()); + } else { // playing the standalone leaderboard means putting it into live mode autoRefreshTimer.setPlayMode(PlayModes.Live); - autoRefreshAnchor.getElement().getStyle().setBackgroundColor("red"); + // autoRefreshAnchor.getElement().getStyle().setBackgroundColor(r); + autoRefreshAnchor.addStyleName(local_res.css().regattaleaderboard_meta_reload_live()); } } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldmultileaderboard/OldMultiLeaderboard.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldmultileaderboard/OldMultiLeaderboard.ui.xml index 6bf4b5d7afd..0c6496bf821 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldmultileaderboard/OldMultiLeaderboard.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/oldmultileaderboard/OldMultiLeaderboard.ui.xml @@ -6,31 +6,33 @@ - -
-
-

-

-
-
-
-

-

-
- - -
- -
- - - - -
- - -
-
+ +
+
+

+

- +
+
+

+

+
+ + +
+
+ +
+
+ + + + +
+ + +
+
+
+
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/overview/EventOverview.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/overview/EventOverview.gss deleted file mode 100644 index 21e5c533e21..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/overview/EventOverview.gss +++ /dev/null @@ -1,464 +0,0 @@ -/** - * The overview page of an event - */ -.latestraceresults { - font-size: 16px; - /* @alternate */ font-size: 1rem; - margin-top: 1.875em; - margin-bottom: 4.0625em; -} -.latestraceresults_refresh { - float: right; -} -.latestraceresults_headline { - border-bottom: solid 1px #ccc; - margin: 0; - padding: 0 0 0.5em 0; -} -.latestraceresults_link { - cursor: pointer; -} -.latestraceresults_link:hover, -.latestraceresults_link:focus { - text-decoration: none; - background-color: #f8f8f8; -} -.latestraceresults_link:hover .latestraceresults_link_title, -.latestraceresults_link:focus .latestraceresults_link_title { - text-decoration: underline; -} -.latestraceresults_detail { - background-color: #f8f8f8; -} -.latestraceresults_detail_wrapper { - margin-top: 1.25em; -} -.latestraceresults_detail_wrapper_medal { - border-bottom: solid 1px #ccc; - padding-top: 0.625em; - height: 2.875em; - color: #333; -} -.latestraceresults_detail_wrapper_medal.last { - border-bottom: none; -} -.latestraceresults_detail_wrapper_thumb { - border: solid 1px #ccc; -} -.latestraceresults_detail_wrapper_more { - padding: 1.25em 0 0.625em; -} -.latestraceresults_link, -.latestraceresults_detail { - display: block; - border-bottom: solid 1px #ddd; - padding: 0.625em; -} -.latestraceresults_link_title, -.latestraceresults_detail_title { - color: #008fcc; - float: left; - font-weight: 700; -} -.latestraceresults_link_raceCount, -.latestraceresults_detail_raceCount { - color: #333; - display: inline-block; -} -.latestraceresults_link_datetime, -.latestraceresults_detail_datetime { - color: #999; - float: right; - margin-right: 0.625em; -} -.columns .latestraceresults_detail_wrapperimage { - max-width: none; -} -.mediateaser { - font-size: 16px; - /* @alternate */ font-size: 1rem; - margin-top: 1.875em; - margin-bottom: 4.0625em; -} -.mediateaser_title { - margin-bottom: 0.375em; -} -.mediateaser_title_link { - color: #008fcc; -} -.mediateaser_title_value { - font-weight: 400; -} -.mediateaser_photo { - background-position: center center; - background-repeat: no-repeat; - -webkit-background-size: cover; - -moz-background-size: cover; - background-size: cover; -} -.mediateaser_photomain { - height: 22.1875em; - margin-right: -0.9375rem; -} -.mediateaser_photothumb { - height: 10.625em; -} -.mediateaser_photothumb:first-child { - margin-bottom: 0.9375em; -} -.mediateaser_video { - position: relative; - height: 26.875em; - background-position: center center; - background-repeat: no-repeat; - -webkit-background-size: cover; - -moz-background-size: cover; - background-size: cover; -} -.mediateaser_video:hover { - cursor: pointer; -} -.playablevideo_buttonplay { - position: absolute; - top: 50%; - left: 50%; - height: 7.125em; - width: 7.125em; - margin-top: -3.5625em; - margin-left: -3.5625em; - background: url("../images/play-icon.png") no-repeat; -} -.box { - display: block; - color: inherit; - background: #f8f8f8; - margin-top: 1.875em; -} -.boxlink { - text-decoration: none; -} -.boxlink:hover { - background: #f0f0f0; - text-decoration: none; -} -.boxlink:hover .box_header { - background: #e6e6e6; -} -.boxlink:hover h2, -.boxlink:hover h3, -.boxlink:hover h4, -.boxlink:hover h5 { - text-decoration: underline; -} -.box h2, -.box h3, -.box h4, -.box h5 { - margin: 0; -} -.box_header { - background: #eee; - border-bottom: 1px solid #dfdfdf; - padding: 1.25em; -} -.box_header_title { - font-size: 1.25em; - display: inline-block; -} -.box_content { - border-bottom: 1px solid #dfdfdf; - padding: 0.9375em 1.25em; -} -.box_content:last-child { - border-bottom: none; -} -.box_contentlink { - display: block; - color: inherit; - text-decoration: none; -} -.box_contentlink:hover, -.box_contentlink:focus { - background: #f5f5f5; - text-decoration: none; -} -.upcomingraceshort { - font-size: 16px; - /* @alternate */ font-size: 1rem; - padding: 0.8125em 0.625em; - zoom: 1; -} -.upcomingraceshort:before, -.upcomingraceshort:after { - content: ""; - display: table; -} -.upcomingraceshort:after { - clear: both; -} -.upcomingraceshort:hover .upcomingraceshort_name { - text-decoration: underline; -} -.upcomingraceshort_date { - float: left; - width: 20%; - text-align: center; - line-height: 1; -} -.upcomingraceshort_date_today { - font-size: 1.125em; - margin: 0.375em 0; -} -.upcomingraceshort_date_day { - font-size: 1.125em; - font-weight: 700; -} -.upcomingraceshort_date_month { - font-size: 0.75em; - text-transform: uppercase; -} -.upcomingraceshort_name { - float: left; - width: 100%; - color: #008fcc; - font-size: 1.125em; - font-weight: 800; -} -.upcomingraceshort_subtitle { - font-size: 0.875em; - font-weight: 600; - margin-top: -emCalc(3px); -} -.upcomingraceshort_details { - position: absolute; - right: 1.125em; - margin-top: 1.5625em; - width: 20%; - text-align: center; -} -.upcomingraceshort_details[data-countdown='true'], -.upcomingraceshort_details[data-countdown='data-countdown'] { - color: #f00; -} -.upcomingraceshort_countdown { - color: #666; - font-size: 0.875em; - font-weight: 100; -} -.weathershort { - font-size: 16px; - /* @alternate */ font-size: 1rem; - font-weight: 600; - background: #eee; - height: 5em; - white-space: nowrap; -} -.weathershort .grid { - height: 100%; - float: left; - width: 60%; - padding: 0; - margin: 0; -} -.weathershort_title { - float: left; - width: 40%; -} -.weathershort_title h3 { - font-size: 1.25em; - padding: 1.375em 0 1.375em 0.75em; -} -.weathershort_data { - padding: 2.8125em 0 0 0; - background-repeat: no-repeat; - background-position: center 0.9375em; - text-align: center; - border-left: solid 1px #ddd; - height: 100%; -} -.weathershort_datatemperature { - background-image: url("../images/weather-sunny.png"); -} -.weathershort_datawindspeed { - background-image: url("../images/weather-wind-speed.png"); -} -.weathershort_datawinddirection { - background-image: url("../images/weather-wind-direction.png"); -} -.newsupdate { - font-size: 16px; - /* @alternate */ font-size: 1rem; -} -.newsupdate_date { - font-size: 0.875em; - color: #949494; - display: block; -} -.dropdown { - font-size: 16px; - /* @alternate */ font-size: 1rem; - width: 18.75em; - display: inline-block; -} -.dropdown:hover .dropdown_content, -.dropdown:focus .dropdown_content { - display: block; -} -.dropdown_head { - cursor: pointer; - display: block; -} -.dropdown_head_title { - cursor: pointer; - background: #f8f8f8; - color: #666; - height: 2.5625em; - line-height: 2.5em; - padding-left: 0.9375em; - font-weight: 700; -} -.dropdown_head_titlebutton { - float: right; -} -.dropdown_content { - position: absolute; - z-index: 1; - background: #f6f9fc; - display: none; - width: 18.75em; - height: auto; - max-height: 21.875em; - overflow: auto; - -webkit-box-shadow: 0 0.0625em 0.25em #ccc; - box-shadow: 0 0.0625em 0.25em #ccc; - border-bottom: solid 1px #ccc; -} -.dropdown_content_link { - display: block; - cursor: pointer; - padding: 1.25em 0.9375em; - border-bottom: 1px solid #ddd; -} -.dropdown_content_link:hover, -.dropdown_content_link:focus { - background: #f8f8f8; - text-decoration: none; -} -.dropdown_content_link:hover .dropdown_content_link_title, -.dropdown_content_link:focus .dropdown_content_link_title { - text-decoration: underline; -} -.dropdown_content_link_title { - color: #008fcc; - display: block; - font-weight: 700; - font-size: 1.125em; -} -.dropdown_content_link_subtitle { - color: #666; - font-size: 1em; -} -.eventquickfinder.dropdown { - font-size: 16px; - /* @alternate */ font-size: 1rem; - float: right; -} -.eventlivebox { - font-size: 16px; - /* @alternate */ font-size: 1rem; - margin-top: 1.875em; -} -.eventlivebox_video_container { - position: relative; - height: 26.875em; - background-position: center center; - background-repeat: no-repeat; - -webkit-background-size: cover; - -moz-background-size: cover; - background-size: cover; -} -.eventlivebox_video_container_captionlayer { - background: #000; - opacity: 0.4; - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; - filter: alpha(opacity=40); - position: absolute; - bottom: 0px; - height: 5em; - width: 100%; -} -.eventlivebox_video_container_caption { - position: absolute; - bottom: 0px; - font-size: 1.5em; - color: #008fcc; - font-weight: 700; - padding: 0.9375em 1.25em; -} -.eventlivebox_video_container_caption .label { - margin-right: 0.9375em; -} -.eventlivebox_video_container:hover, -.eventlivebox_video_container:focus { - cursor: pointer; -} -.eventlivebox_video_container:hover .eventlivebox_video_container_caption, -.eventlivebox_video_container:focus .eventlivebox_video_container_caption { - text-decoration: underline; -} -.eventlivebox_linklist { - border-left: solid 1px #ccc; - border-right: solid 1px #ccc; -} -.eventlivebox_linklist_link { - display: inline-block; - border-bottom: solid 1px #ccc; - width: 100%; -} -.eventlivebox_linklist_link:hover, -.eventlivebox_linklist_link:focus { - background: #fafafa; - text-decoration: none; -} -.eventlivebox_linklist_link:hover .eventlivebox_linklist_link_title, -.eventlivebox_linklist_link:focus .eventlivebox_linklist_link_title { - text-decoration: underline; -} -.eventlivebox_linklist_link_icon { - float: left; - width: 3.625em; - height: 3.625em; - background-repeat: no-repeat; - background-position: left top; - -webkit-background-size: cover; - -moz-background-size: cover; - background-size: cover; - border: solid 1px #ccc; - margin: 1.25em; -} -.eventlivebox_linklist_link_icon[data-type="audio"] { - background-image: url("../images/icon/audio.png"); -} -.eventlivebox_linklist_link_icon[data-type="diagram"] { - background-image: url("../images/icon/diagram.png"); -} -.eventlivebox_linklist_link_icon[data-type="video"] { - background-image: url("../images/icon/video.png"); -} -.eventlivebox_linklist_link_title { - font-weight: 700; - display: block; - font-size: 1.25em; - margin-top: 1.25em; -} -.eventlivebox_linklist_link_title .label { - margin: -0.25em 0 0 0.3125em; -} -.eventlivebox_linklist_link_description { - color: #666; - padding-right: 0.625em; -} -.eventoverview { - font-size: 16px; - /* @alternate */ font-size: 1rem; -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/overview/EventOverview.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/overview/EventOverview.java deleted file mode 100644 index 6b9ff29c203..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/overview/EventOverview.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.overview; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.gwt.home.client.place.event.AbstractEventComposite; -import com.sap.sailing.gwt.home.client.place.event.EventPlaceNavigator; -import com.sap.sailing.gwt.ui.shared.EventDTO; - -public class EventOverview extends AbstractEventComposite { - private static EventOverviewUiBinder uiBinder = GWT.create(EventOverviewUiBinder.class); - - interface EventOverviewUiBinder extends UiBinder { - } - - public EventOverview(EventDTO event, EventPlaceNavigator pageNavigator) { - super(event, pageNavigator); - - EventOverviewResources.INSTANCE.css().ensureInjected(); - initWidget(uiBinder.createAndBindUi(this)); - - updateUI(); - } - - private void updateUI() { - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/overview/EventOverview.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/overview/EventOverview.ui.xml deleted file mode 100644 index 11c4e592a22..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/overview/EventOverview.ui.xml +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - - - diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/overview/EventOverviewResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/overview/EventOverviewResources.java deleted file mode 100644 index 6f0a09878df..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/overview/EventOverviewResources.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.overview; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.resources.client.ClientBundle; -import com.google.gwt.resources.client.CssResource; - -public interface EventOverviewResources extends ClientBundle { - public static final EventOverviewResources INSTANCE = GWT.create(EventOverviewResources.class); - - @Source("com/sap/sailing/gwt/home/client/place/event/overview/EventOverview.gss") - LocalCss css(); - - public interface LocalCss extends CssResource { - String latestraceresults(); - String latestraceresults_refresh(); - String latestraceresults_headline(); - String latestraceresults_link(); - String latestraceresults_link_title(); - String latestraceresults_detail(); - String latestraceresults_detail_wrapper(); - String latestraceresults_detail_wrapper_medal(); - String last(); - String latestraceresults_detail_wrapper_thumb(); - String latestraceresults_detail_wrapper_more(); - String latestraceresults_detail_title(); - String latestraceresults_link_raceCount(); - String latestraceresults_detail_raceCount(); - String latestraceresults_link_datetime(); - String latestraceresults_detail_datetime(); - String columns(); - String latestraceresults_detail_wrapperimage(); - String mediateaser(); - String mediateaser_title(); - String mediateaser_title_link(); - String mediateaser_title_value(); - String mediateaser_photo(); - String mediateaser_photomain(); - String mediateaser_photothumb(); - String mediateaser_video(); - String playablevideo_buttonplay(); - String box(); - String boxlink(); - String box_header(); - String box_header_title(); - String box_content(); - String box_contentlink(); - String upcomingraceshort(); - String upcomingraceshort_name(); - String upcomingraceshort_date(); - String upcomingraceshort_date_today(); - String upcomingraceshort_date_day(); - String upcomingraceshort_date_month(); - String upcomingraceshort_subtitle(); - String upcomingraceshort_details(); - String upcomingraceshort_countdown(); - String weathershort(); - String grid(); - String weathershort_title(); - String weathershort_data(); - String weathershort_datatemperature(); - String weathershort_datawindspeed(); - String weathershort_datawinddirection(); - String newsupdate(); - String newsupdate_date(); - String dropdown(); - String dropdown_content(); - String dropdown_head(); - String dropdown_head_title(); - String dropdown_head_titlebutton(); - String dropdown_content_link(); - String dropdown_content_link_title(); - String dropdown_content_link_subtitle(); - String eventquickfinder(); - String eventlivebox(); - String eventlivebox_video_container(); - String eventlivebox_video_container_captionlayer(); - String eventlivebox_video_container_caption(); - String label(); - String eventlivebox_linklist(); - String eventlivebox_linklist_link(); - String eventlivebox_linklist_link_title(); - String eventlivebox_linklist_link_icon(); - String eventlivebox_linklist_link_description(); - String eventoverview(); - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/Regatta.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/Regatta.gss similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/Regatta.gss rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/Regatta.gss diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/Regatta.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/Regatta.java similarity index 67% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/Regatta.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/Regatta.java index f35469ef404..ed1b6eb3225 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/Regatta.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/Regatta.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.home.client.place.event.regatta; +package com.sap.sailing.gwt.home.client.place.event.partials; import java.util.ArrayList; import java.util.List; @@ -17,22 +17,18 @@ import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Widget; -import com.google.gwt.user.client.ui.impl.HyperlinkImpl; import com.sap.sailing.gwt.common.client.BoatClassImageResolver; import com.sap.sailing.gwt.common.client.BoatClassImageResources; -import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; +import com.sap.sailing.gwt.common.client.LinkUtil; import com.sap.sailing.gwt.home.client.app.PlaceNavigation; -import com.sap.sailing.gwt.home.client.place.event.EventPlace; -import com.sap.sailing.gwt.home.client.place.event.EventPlaceNavigator; -import com.sap.sailing.gwt.home.client.place.regatta.RegattaPlace; -import com.sap.sailing.gwt.home.client.place.regatta.RegattaPlace.RegattaNavigationTabs; +import com.sap.sailing.gwt.home.client.place.event.EventView; +import com.sap.sailing.gwt.home.client.place.event.EventView.Presenter; import com.sap.sailing.gwt.home.client.shared.LongNamesUtil; -import com.sap.sailing.gwt.ui.shared.EventDTO; import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; import com.sap.sailing.gwt.ui.shared.RaceGroupDTO; import com.sap.sailing.gwt.ui.shared.RaceGroupSeriesDTO; import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; -import com.sap.sse.gwt.client.player.Timer; +import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO; public class Regatta extends Composite { private static RegattaUiBinder uiBinder = GWT.create(RegattaUiBinder.class); @@ -40,10 +36,7 @@ public class Regatta extends Composite { interface RegattaUiBinder extends UiBinder { } - private static final HyperlinkImpl HYPERLINK_IMPL = GWT.create(HyperlinkImpl.class); - - private final EventDTO event; - private final Timer timerForClientServerOffset; + private final EventViewDTO event; private RaceGroupDTO raceGroup; private final List phasesElements; private LeaderboardGroupDTO leaderboardGroup; @@ -73,28 +66,20 @@ public class Regatta extends Composite { // @UiField(provided=true) RegattaCompetitor competitorWithRank3; @UiField Anchor regattaDetailsLink; - @UiField Anchor leaderboardLink; @UiField Image boatClassImage; - private PlaceNavigation leaderboardNavigation; - private PlaceNavigation regattaNavigation; - private final HomePlacesNavigator placesNavigator; - private final EventPlaceNavigator eventPlaceNavigator; + private Presenter presenter; + + private PlaceNavigation regattaNavigation; - public Regatta(EventDTO event, Timer timerForClientServerOffset, boolean isSingleView, HomePlacesNavigator placesNavigator, EventPlaceNavigator eventPlaceNavigator) { - this.event = event; - this.timerForClientServerOffset = timerForClientServerOffset; + public Regatta(boolean isSingleView, EventView.Presenter presenter) { + this.event = presenter.getCtx().getEventDTO(); this.isSingleView = isSingleView; - this.placesNavigator = placesNavigator; - this.eventPlaceNavigator = eventPlaceNavigator; + this.presenter = presenter; phasesElements = new ArrayList(); - -// competitorWithRank1 = new RegattaCompetitor(1, null); -// competitorWithRank2 = new RegattaCompetitor(2, null); -// competitorWithRank3 = new RegattaCompetitor(3, null); - + RegattaResources.INSTANCE.css().ensureInjected(); initWidget(uiBinder.createAndBindUi(this)); @@ -107,16 +92,12 @@ public class Regatta extends Composite { if(isSingleView) { regattaDetailsLink.setVisible(false); - leaderboardNavigation = placesNavigator.getRegattaAnalyticsNavigation(event.id.toString(), RegattaNavigationTabs.Leaderboard, - leaderboard.name, event.getBaseURL(), event.isOnRemoteServer()); - leaderboardLink.setHref(leaderboardNavigation.getTargetUrl()); } else { - leaderboardLink.setVisible(false); - regattaNavigation = placesNavigator.getRegattaNavigation(event.id.toString(), leaderboard.name, event.getBaseURL(), event.isOnRemoteServer()); + regattaNavigation = presenter.getRegattaNavigation(leaderboard.regattaName != null ? leaderboard.regattaName : leaderboard.name); regattaDetailsLink.setHref(regattaNavigation.getTargetUrl()); } - boolean hasLiveRace = leaderboard.hasLiveRace(timerForClientServerOffset.getLiveTimePointInMillis()); + boolean hasLiveRace = leaderboard.hasLiveRace(presenter.getTimerForClientServerOffset().getLiveTimePointInMillis()); if(!hasLiveRace) { isLiveDiv.getStyle().setDisplay(Display.NONE); } @@ -131,10 +112,10 @@ public class Regatta extends Composite { String regattaDisplayName = leaderboard.displayName != null ? leaderboard.displayName : leaderboard.name; regattaNameHeading.setInnerText(regattaDisplayName); if(hasMultipleLeaderboardGroups && leaderboardGroup.getName() != null) { - leaderboardGroupName.setInnerText(LongNamesUtil.shortenLeaderboardGroupName(event.getName(), leaderboardGroup.getName())); + leaderboardGroupName.setInnerText(LongNamesUtil.shortenLeaderboardGroupName(event.getDisplayName(), leaderboardGroup.getName())); leaderboardGroupName.setAttribute("data-labeltype", "group1"); } else { - leaderboardGroupNameDiv.getStyle().setDisplay(Display.NONE); + leaderboardGroupNameDiv.removeFromParent(); } if(leaderboard.competitorsCount > 0) { @@ -156,7 +137,7 @@ public class Regatta extends Composite { } else { for(RaceGroupSeriesDTO series: raceGroup.getSeries()) { RegattaPhase regattaPhase = new RegattaPhase(series, leaderboardGroup, - leaderboard, raceGroup, eventPlaceNavigator, timerForClientServerOffset); + leaderboard, raceGroup, presenter); regattaPhasesPanel.appendChild(regattaPhase.getElement()); phasesElements.add(regattaPhase); } @@ -171,15 +152,10 @@ public class Regatta extends Composite { void regattaDetailsLinkClicked(ClickEvent e) { handleClickEvent(e, regattaNavigation); } - - @UiHandler("leaderboardLink") - void leaderboardLinkClicked(ClickEvent e) { - handleClickEvent(e, leaderboardNavigation); - } - private void handleClickEvent(ClickEvent e, PlaceNavigation placeNavigation) { - if (HYPERLINK_IMPL.handleAsClick((Event) e.getNativeEvent())) { - placesNavigator.goToPlace(placeNavigation); + private void handleClickEvent(ClickEvent e, PlaceNavigation place) { + if (LinkUtil.handleLinkClick((Event) e.getNativeEvent())) { + place.goToPlace(); e.preventDefault(); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/Regatta.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/Regatta.ui.xml similarity index 91% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/Regatta.ui.xml rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/Regatta.ui.xml index ea3f3fba3a9..b3de40450a5 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/Regatta.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/Regatta.ui.xml @@ -4,18 +4,18 @@ xmlns:s="urn:import:com.sap.sailing.gwt.home.client.place.event"> - +
-
+
-
+

@@ -29,7 +29,7 @@
 
 
-
+
@@ -38,7 +38,6 @@
-
-
-
- ✓  -
+
+
+
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattalist/EventRegattaListResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/eventregatta/EventRegattaListResources.java similarity index 69% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattalist/EventRegattaListResources.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/eventregatta/EventRegattaListResources.java index 2604af94c79..f73cab9acbb 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattalist/EventRegattaListResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/eventregatta/EventRegattaListResources.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.home.client.place.event.regattalist; +package com.sap.sailing.gwt.home.client.place.event.partials.eventregatta; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ClientBundle; @@ -7,11 +7,15 @@ import com.google.gwt.resources.client.CssResource; public interface EventRegattaListResources extends ClientBundle { public static final EventRegattaListResources INSTANCE = GWT.create(EventRegattaListResources.class); - @Source("com/sap/sailing/gwt/home/client/place/event/regattalist/EventRegattaList.css") + @Source("EventRegattaList.gss") LocalCss css(); public interface LocalCss extends CssResource { + String item(); + String selectedItem(); String eventregattalist(); String eventregattalist_navigation(); + + String regattaGroupsNavigationPanel(); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/DropdownItem.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/DropdownItem.java new file mode 100644 index 00000000000..d832e2791ac --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/DropdownItem.java @@ -0,0 +1,38 @@ +package com.sap.sailing.gwt.home.client.place.event.partials.header; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.AnchorElement; +import com.google.gwt.dom.client.DivElement; +import com.google.gwt.dom.client.Element; +import com.google.gwt.safehtml.shared.SafeUri; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.Widget; + +public class DropdownItem extends Widget { + + private static DropdownItemUiBinder uiBinder = GWT.create(DropdownItemUiBinder.class); + + interface DropdownItemUiBinder extends UiBinder { + } + + @UiField EventHeaderResources local_res; + + @UiField + AnchorElement link; + + @UiField + DivElement title; + + public DropdownItem(String text, SafeUri link, boolean active) { + setElement(uiBinder.createAndBindUi(this)); + + if(active) { + getElement().addClassName(local_res.css().dropdownregattas_content_linkactive()); + } + + this.link.setHref(link); + this.title.setInnerText(text); + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/DropdownItem.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/DropdownItem.ui.xml new file mode 100644 index 00000000000..90758db8881 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/DropdownItem.ui.xml @@ -0,0 +1,16 @@ + + + + + + + .important { + font-weight: bold; + } + + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/EventHeader.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/EventHeader.gss new file mode 100644 index 00000000000..2f0408dba82 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/EventHeader.gss @@ -0,0 +1,310 @@ +/** + * The header of the pages to an event + */ +.jsdropdown { + position: relative; +} +.jsdropdown_head, +.jsdropdown_content { + text-indent: 0; +} +.dropdown { + font-size: 1rem; + width: 20em; + max-width: 100%; + display: inline-block; + text-align: left; +} +.dropdown_head { + display: block; +} +.dropdown_head_title { + font-size: 1.866666666666667em; + cursor: pointer; + background: #f8f8f8; + color: #cfcfcf; + height: 1.464285714285714em; + line-height: 1.428571428571429em; + padding-left: 0.535714285714286em; + font-weight: 700; +} +.dropdown_head_title_button { + float: right; +} +.dropdown_content { + position: absolute; + z-index: 1; + background: #f6f9fc; + display: none; + width: 20em; + height: auto; + max-height: 23.333333333333332em; + overflow: auto; + box-shadow: 0 0.066666666666667em 0.266666666666667em #eee; + border-bottom: solid 1px #eee; +} +.jsdropdownactive .dropdown_content { + display: block; +} +.dropdown_content_link { + display: block; + cursor: pointer; + padding: 1.333333333333333em 3.333333333333333em 1em 1em; + border-bottom: 1px solid #f4f4f4; +} +.dropdown_content_link:hover, +.dropdown_content_link:focus { + background: #f8f8f8; + text-decoration: none; +} +.dropdown_content_link:hover .dropdown_content_link_title, +.dropdown_content_link:focus .dropdown_content_link_title { + text-decoration: underline; +} +.dropdown_content_link_title { + color: #008fcc; + display: block; + font-weight: 600; + font-size: 1.2em; +} +.dropdown_content_link_subtitle { + color: #cfcfcf; + font-size: 1.066666666666667em; +} +.dropdownregattas { + width: 100%; + min-width: 21.333333333333332em; + margin-left: -0.666666666666667em; +} +.dropdownregattas_head { + display: inherit; +} +.dropdownregattas_head_title { + padding-left: 0.357142857142857em; + background: #f2f2f2; + color: #333; + border-radius: 0.107142857142857em; + border: 1px solid transparent; +} +.dropdownregattas_head_title:hover { + border: 1px solid #cfcfcf; + background-color: #eee; + text-decoration: none; +} +.dropdownregattas_head_title_button { + position: relative; + display: inline-block; + margin-left: 0.714285714285714em; + top: 50%; + height: 0.285714285714286em; + width: 0.428571428571429em; + background-image: url("images/home/dropdown__button--arrow@2x.png"); + background-position: center bottom; + background-repeat: no-repeat; + background-size: 100%; + -webkit-transform: translate(-50%, -50%); + -moz-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + float: none; +} +.dropdownregattas_content { + width: auto; + background-color: #fff; + border: 1px solid #ccc; + box-shadow: 0.133333333333333em 0.133333333333333em 0.333333333333333em #ccc; +} +.dropdownregattas_content_link { + position: relative; + border: none; +} +.dropdownregattas_content_link:hover { + text-decoration: none; +} +.dropdownregattas_content_linkactive:after { + content: ''; + position: absolute; + right: 1.333333333333333em; + top: 50%; + height: 0.933333333333333em; + width: 0.933333333333333em; + background-image: url("images/home/dropdown__check@2x.png"); + background-repeat: no-repeat; + background-position: right center; + background-size: contain; + -webkit-transform: translate(0, -50%); + -moz-transform: translate(0, -50%); + -ms-transform: translate(0, -50%); + transform: translate(0, -50%); +} +.dropdownregattas_content_link_title { + color: #666; +} +.leaderboardquickaccess { + font-size: 1rem; + text-align: right; +} +.eventheader { + position: relative; + font-size: 1rem; + color: #666; + background: #f2f2f2; + border-bottom: 1px solid #dedede; +} +.eventheader_breadcrumb { + font-size: 1rem; + /* @alternate */font-size: 0.866666666666667em; + font-weight: 600; + padding: 0.666666666666667em 0; +} +.eventheader_breadcrumbback { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 1.333333333333333em; + border-right: 1px solid #cfcfcf; + background-color: #dedede; + background-image: url("images/home/breadcrumb-arrow__back.png"); + background-position: center center; + background-repeat: no-repeat; + background-size: 50%; + -webkit-transition: background-color 0.2s, border-color 0.2s; + -moz-transition: background-color 0.2s, border-color 0.2s; + transition: background-color 0.2s, border-color 0.2s; +} +.eventheader_breadcrumbback:hover { + background-color: #cfcfcf; +} +.eventheader_intro { + padding-left: 6em; + margin: 0.666666666666667em 0; + min-height: 5em; + position: relative; +} +.eventheader_intro_logo { + position: absolute; + top: 0; + left: 0; + width: 5em; + height: 5em; + border: 0.333333333333333em solid #f6f9fc; + box-shadow: 0 0 5px rgba(238,238,238,0.5); +} +.eventheader_intro_logo_image { + height: 100%; + width: 100%; + background-position: center; + background-size: contain; + background-repeat: no-repeat; +} +.eventheader_intro_name { + display: inline-block; + margin: 0 0.333333333333333em 0 0; + font-size: 1.866666666666667em; + color: #333; +} +.eventheader_intro_details { + margin-bottom: 0.666666666666667em; + padding-bottom: 0.666666666666667em; + font-weight: 700; + color: #333; +} +.eventheader_intro_details_item { + display: inline-block; + border-left: 1px solid #cfcfcf; + margin: 0.266666666666667em 0 0.266666666666667em 0.333333333333333em; + padding-left: 0.666666666666667em; + color: #666; +} +.eventheader_intro_details_itemlink { + color: inherit; +} +.eventheader_intro_details_item:first-child { + margin-left: 0; + padding-left: 0; + border: none; +} +.eventheader_status { + text-align: right; +} +.eventheader_status_title { + text-transform: uppercase; +} +.eventheader_status_body { + font-size: 1rem; +} +.locationicon { + vertical-align: text-bottom; + margin-right: 0.333333333333333em; +} +.eventnavigation { + font-size: 0; + margin-bottom: -1px; +} +.eventnavigationnormal { + position: relative; +} +.eventnavigation_dropdown { + display: inline-block; + position: relative; +} +.eventnavigation_dropdown_toggle { + cursor: pointer; + display: inline-block; +} +@media (min-width: 61em) { + .eventnavigation_dropdown_toggle { + display: none; + } +} +.eventnavigation_dropdown_toggle_icon { + display: inline-block; + position: relative; + top: 50%; + width: 0.8em; + height: 0.533333333333333em; + vertical-align: middle; + background-image: url("images/home/dropdown__button--arrow@2x.png"); + background-size: 100%; + background-repeat: no-repeat; + background-position: center bottom; +} +.eventnavigation_dropdown_container { + position: absolute; + left: 0; + z-index: 99; +} +@media (min-width: 61em) { + .eventnavigation_dropdown_container { + display: inline-block; + position: relative; + left: auto; + } +} +.eventnavigation_dropdown_containerhidden { + display: none; +} +@media (min-width: 61em) { + .eventnavigation_dropdown_containerhidden { + display: inline-block; + } +} +.eventnavigation_dropdown_container .navbar_button { + border-top-width: 0; + width: 16.666666666666668em; +} +@media (min-width: 61em) { + .eventnavigation_dropdown_container .navbar_button { + border-top-width: 1px; + width: auto; + } +} +@media (min-width: 61em) { + .eventnavigation_dropdown_container .navbar_buttonhidden { + display: inline-block; + } +} +.eventnavigation .navbar_button { + font-size: 1.2rem; +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/EventHeader.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/EventHeader.java new file mode 100644 index 00000000000..88863dccfa5 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/EventHeader.java @@ -0,0 +1,247 @@ +package com.sap.sailing.gwt.home.client.place.event.partials.header; + +import java.util.Date; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.dom.client.AnchorElement; +import com.google.gwt.dom.client.DivElement; +import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.EventTarget; +import com.google.gwt.dom.client.HeadingElement; +import com.google.gwt.dom.client.SpanElement; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.Event.NativePreviewEvent; +import com.google.gwt.user.client.Event.NativePreviewHandler; +import com.google.gwt.user.client.EventListener; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.Widget; +import com.google.web.bindery.event.shared.HandlerRegistration; +import com.sap.sailing.gwt.common.client.LinkUtil; +import com.sap.sailing.gwt.common.client.i18n.TextMessages; +import com.sap.sailing.gwt.home.client.place.event.AbstractEventPlace; +import com.sap.sailing.gwt.home.client.place.event.EventView; +import com.sap.sailing.gwt.home.client.place.event.EventView.PlaceCallback; +import com.sap.sailing.gwt.home.client.place.event.EventView.Presenter; +import com.sap.sailing.gwt.home.client.shared.EventDatesFormatterUtil; +import com.sap.sailing.gwt.home.client.shared.LabelTypeUtil; +import com.sap.sailing.gwt.home.client.shared.sharing.SharingButtons; +import com.sap.sailing.gwt.home.client.shared.sharing.SharingMetadataProvider; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO; +import com.sap.sailing.gwt.ui.shared.eventview.HasRegattaMetadata; + +public class EventHeader extends Composite { + private static EventHeaderUiBinder uiBinder = GWT.create(EventHeaderUiBinder.class); + + interface EventHeaderUiBinder extends UiBinder { + } + + @UiField StringMessages i18n; + + @UiField DivElement eventLogo; + @UiField HeadingElement staticTitle; + @UiField SpanElement eventName; + @UiField DivElement eventState; + @UiField DivElement dropdownTitle; + @UiField SpanElement dropdownEventName; + @UiField DivElement dropdownEventState; + @UiField AnchorElement dropdownTrigger; + @UiField DivElement eventDate; + @UiField SpanElement eventVenue; + @UiField DivElement eventVenueContainer; + @UiField AnchorElement eventLink; + @UiField DivElement competitors; + @UiField DivElement races; + @UiField DivElement trackedRaces; + @UiField DivElement eventCategory; + + @UiField FlowPanel dropdownContent; + + @UiField SharingButtons sharing; + + private EventViewDTO event; + + private Presenter presenter; + + private HandlerRegistration reg; + boolean dropdownShown = false; + + public EventHeader(EventView.Presenter presenter) { + this.event = presenter.getCtx().getEventDTO(); + this.presenter = presenter; + + EventHeaderResources.INSTANCE.css().ensureInjected(); + initWidget(uiBinder.createAndBindUi(this)); + + initFields(); + initSharing(); + } + + private void initSharing() { + sharing.setUp(new SharingMetadataProvider() { + @Override + public String getShortText() { + // TODO regatta details? + String dateString = EventDatesFormatterUtil.formatDateRangeWithYear(event.getStartDate(), event.getEndDate()); + return StringMessages.INSTANCE.eventSharingShortText(event.getDisplayName(), event.getLocationOrVenue(), dateString); + } + + @Override + public String getLongText(String url) { + // TODO regatta details? + String dateString = EventDatesFormatterUtil.formatDateRangeWithYear(event.getStartDate(), event.getEndDate()); + return StringMessages.INSTANCE.eventSharingLongText(event.getDisplayName(), event.getLocationOrVenue(), dateString, url); + } + }); + } + + private void initFields() { + String logoUrl = event.getLogoImageURL() != null ? event.getLogoImageURL() : EventHeaderResources.INSTANCE.defaultEventLogoImage().getSafeUri().asString(); + eventLogo.getStyle().setBackgroundImage("url(" + logoUrl + ")"); + eventLogo.setTitle(event.getDisplayName()); + + String nameToShow; + if(presenter.showRegattaMetadata()) { + HasRegattaMetadata regattaMetadata = presenter.getRegattaMetadata(); + nameToShow = regattaMetadata.getDisplayName(); + + if(regattaMetadata.getCompetitorsCount() > 0) { + competitors.setInnerText((i18n.competitorsCount(regattaMetadata.getCompetitorsCount()))); + } else { + hide(competitors); + } + if(regattaMetadata.getRaceCount() > 0) { + races.setInnerText((i18n.racesCount(regattaMetadata.getRaceCount()))); + } else { + hide(races); + } + if(regattaMetadata.getTrackedRacesCount() > 0) { + trackedRaces.setInnerText(i18n.trackedRacesCount(regattaMetadata.getTrackedRacesCount())); + } else { + hide(trackedRaces); + } + if(regattaMetadata.getBoatCategory() != null) { + eventCategory.setInnerText(regattaMetadata.getBoatCategory()); + } else { + hide(eventCategory); + } + Date startDate = regattaMetadata.getStartDate() != null ? regattaMetadata.getStartDate() : event.getStartDate(); + Date endDate = regattaMetadata.getEndDate() != null ? regattaMetadata.getEndDate() : event.getEndDate(); + eventDate.setInnerHTML(EventDatesFormatterUtil.formatDateRangeWithYear(startDate, endDate)); + + hide(eventVenueContainer, eventLink); + } else { + nameToShow = event.getDisplayName(); + eventDate.setInnerHTML(EventDatesFormatterUtil.formatDateRangeWithYear(event.getStartDate(), event.getEndDate())); + String venue = event.getLocationAndVenue(); + if(event.getVenueCountry() != null && !event.getVenueCountry().isEmpty()) { + venue += ", " + event.getVenueCountry(); + } + eventVenue.setInnerText(venue); + + if(event.getOfficialWebsiteURL() != null) { + String title = withoutPrefix(event.getOfficialWebsiteURL(), "http://", "https://"); + if(title.length() > 35) { + title = TextMessages.INSTANCE.officalEventWebsite(); + } + eventLink.setInnerText(title); + eventLink.setHref(event.getOfficialWebsiteURL()); + } else { + hide(eventLink); + } + + hide(competitors, races, trackedRaces); + } + + initTitleAndSelection(nameToShow); + } + + private void initTitleAndSelection(String nameToShow) { + if(!presenter.needsSelectionInHeader()) { + eventName.setInnerText(nameToShow); + LabelTypeUtil.renderLabelType(eventState, event.getState().getStateMarker()); + hide(dropdownTitle); + } else { + dropdownEventName.setInnerText(nameToShow); + LabelTypeUtil.renderLabelType(dropdownEventState, presenter.showRegattaMetadata() ? presenter.getRegattaMetadata().getState().getStateMarker() : event.getState().getStateMarker()); + hide(staticTitle); + + initDropdown(); + } + } + + private void initDropdown() { + Event.sinkEvents(dropdownTrigger, Event.ONCLICK); + Event.setEventListener(dropdownTrigger, new EventListener() { + @Override + public void onBrowserEvent(Event event) { + if(dropdownShown) { + return; + } + dropdownTitle.addClassName(EventHeaderResources.INSTANCE.css().jsdropdownactive()); + dropdownShown = true; + reg = Event.addNativePreviewHandler(new NativePreviewHandler() { + @Override + public void onPreviewNativeEvent(NativePreviewEvent event) { + EventTarget eventTarget = event.getNativeEvent().getEventTarget(); + if(!Element.is(eventTarget)) { + return; + } + Element evtElement = Element.as(eventTarget); + if(event.getTypeInt() == Event.ONCLICK && !dropdownContent.getElement().isOrHasChild(evtElement)) { + Scheduler.get().scheduleDeferred(new ScheduledCommand() { + @Override + public void execute() { + dropdownTitle.removeClassName(EventHeaderResources.INSTANCE.css().jsdropdownactive()); + dropdownShown = false; + reg.removeHandler(); + reg = null; + } + }); + } + } + }); + } + }); + + presenter.forPlaceSelection(new PlaceCallback() { + @Override + public void forPlace(final AbstractEventPlace place, String title, boolean active) { + DropdownItem dropdownItem = new DropdownItem(title, presenter.getUrl(place), active); + dropdownItem.addDomHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + if(LinkUtil.handleLinkClick((Event) event.getNativeEvent())) { + event.preventDefault(); + presenter.navigateTo(place); + } + } + }, ClickEvent.getType()); + dropdownContent.add(dropdownItem); + } + }); + } + + private String withoutPrefix(String title, String... prefixes) { + for (String prefix : prefixes) { + if(title.startsWith(prefix)) { + return title.substring(prefix.length(), title.length()); + } + } + return title; + } + + private void hide(Element... elementsToHide) { + for (Element element : elementsToHide) { +// element.getStyle().setDisplay(Display.NONE); + element.removeFromParent(); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/EventHeader.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/EventHeader.ui.xml new file mode 100644 index 00000000000..4c94e3af3bd --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/EventHeader.ui.xml @@ -0,0 +1,67 @@ + + + + + + +
+
+
+
+
+ +
+ + + + + + +
+ +

+ + +
+
+ +

+
+ +
+
+
+ + +
+ + + +
+
+
+
+ +
+ +
+
+
+
+ +
+ + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/EventHeaderResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/EventHeaderResources.java similarity index 52% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/EventHeaderResources.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/EventHeaderResources.java index 21bd3c3c77b..e4d95969fd1 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/header/EventHeaderResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/header/EventHeaderResources.java @@ -1,53 +1,61 @@ -package com.sap.sailing.gwt.home.client.place.event.header; +package com.sap.sailing.gwt.home.client.place.event.partials.header; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.CssResource; -import com.google.gwt.resources.client.CssResource.Shared; import com.google.gwt.resources.client.ImageResource; public interface EventHeaderResources extends ClientBundle { public static final EventHeaderResources INSTANCE = GWT.create(EventHeaderResources.class); - @Source("com/sap/sailing/gwt/home/client/place/event/header/EventHeader.gss") + @Source("EventHeader.gss") LocalCss css(); - @Shared public interface LocalCss extends CssResource { + String jsdropdown(); + String jsdropdown_head(); + String jsdropdown_content(); String dropdown(); String dropdown_head(); String dropdown_head_title(); - String dropdown_head_titlebutton(); + String dropdown_head_title_button(); String dropdown_content(); + String jsdropdownactive(); String dropdown_content_link(); String dropdown_content_link_title(); String dropdown_content_link_subtitle(); + String dropdownregattas(); + String dropdownregattas_head(); + String dropdownregattas_head_title(); + String dropdownregattas_head_title_button(); + String dropdownregattas_content(); + String dropdownregattas_content_link(); + String dropdownregattas_content_linkactive(); + String dropdownregattas_content_link_title(); String leaderboardquickaccess(); - String eventheaderwrapper(); String eventheader(); - String eventnavigationnormal(); - String eventnavigationcompact(); - String eventnavigationcompactfloating(); + String eventheader_breadcrumb(); + String eventheader_breadcrumbback(); String eventheader_intro(); - String eventheader_intro_description(); String eventheader_intro_logo(); String eventheader_intro_logo_image(); String eventheader_intro_name(); String eventheader_intro_details(); String eventheader_intro_details_item(); String eventheader_intro_details_itemlink(); - String eventheader_sharing(); - String eventheader_sharing_item(); - String eventheader_sharing_itememail(); - String eventheader_sharing_itemtwitter(); - String eventheader_sharing_itemfacebook(); + String eventheader_status(); + String eventheader_status_title(); + String eventheader_status_body(); String locationicon(); String eventnavigation(); - String eventnavigation_link(); - String eventnavigation_linkactive(); - String eventnavigationcompact_logo(); - String eventnavigationcompactfloating_logo(); - String eventnavigationfixed(); + String eventnavigationnormal(); + String eventnavigation_dropdown(); + String eventnavigation_dropdown_toggle(); + String eventnavigation_dropdown_toggle_icon(); + String eventnavigation_dropdown_container(); + String eventnavigation_dropdown_containerhidden(); + String navbar_button(); + String navbar_buttonhidden(); } @Source("com/sap/sailing/gwt/home/images/default_event_logo.jpg") diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeader.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeader.css new file mode 100644 index 00000000000..9a134001372 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeader.css @@ -0,0 +1,79 @@ +/** + * The header of a regatta of an event + */ +.regattaheader { + font-size: 1rem; + margin-top: 2em; + padding: 0.666666666666667em; + overflow: hidden; + border-radius: 0.333333333333333em; + border: 1px solid #dedede; + background-color: #f2f2f2; +} +.regattaheaderlink { + display: block; + margin-top: 0; + border: none; + border-radius: 0; + color: #0a0a0a; +} +.regattaheader_logo { + float: left; + width: 4em; + height: 3.333333333333333em; + margin-right: 0.666666666666667em; + text-align: center; + line-height: 3.333333333333333em; + border-right: 1px solid #ccc; + padding-right: 0.666666666666667em; +} +.regattaheader_logo img { + display: inline-block; + text-align: center; + vertical-align: middle; +} +.regattaheader_content { + float: left; + width: 80%; + overflow: hidden; +} +.regattaheader_content_title { + font-size: 1.466666666666667em; + font-weight: 700; + height: 1.363636363636364em; + line-height: 1.363636363636364em; +} +.regattaheader_content_details { + height: 1.333333333333333em; +} +.regattaheader_content_details_item { + float: left; + font-size: 13px; + font-weight: 600; + color: #666; + padding: 0 0.666666666666667em; + border-right: 1px solid #ccc; +} +.regattaheader_content_details_item:first-of-type { + padding-left: 0; +} +.regattaheader_content_details_item:last-of-type { + border: none; + padding-right: 0; +} +.regattaheader_arrow { + float: right; + width: 5%; + line-height: 3.333333333333333em; + text-align: right; +} +.regattaheader_arrow:before { + content: ''; + display: inline-block; + margin-left: 0.333333333333333em; + width: 0.8em; + height: 1.333333333333333em; + background-image: url("../images/home/breadcrumb-arrow.png"); + background-size: contain; + background-repeat: no-repeat; +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeader.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeader.java new file mode 100644 index 00000000000..50e553081e1 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeader.java @@ -0,0 +1,26 @@ +package com.sap.sailing.gwt.home.client.place.event.partials.regattaHeader; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sailing.gwt.ui.shared.eventview.RegattaReferenceDTO; + +public class RegattaHeader extends Composite { + private static EventHeaderUiBinder uiBinder = GWT.create(EventHeaderUiBinder.class); + + interface EventHeaderUiBinder extends UiBinder { + } + + @UiField StringMessages i18n; + + + public RegattaHeader(RegattaReferenceDTO regattaRefDTO) { + + RegattaHeaderResources.INSTANCE.css().ensureInjected(); + initWidget(uiBinder.createAndBindUi(this)); + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeader.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeader.ui.xml new file mode 100644 index 00000000000..1304c8dd297 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeader.ui.xml @@ -0,0 +1,30 @@ + + + + + + + + +
+
+
+ + + + + + +
+
+
+ +
+
+
+
+
\ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeaderBody.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeaderBody.ui.xml new file mode 100644 index 00000000000..dac8b67d8b1 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeaderBody.ui.xml @@ -0,0 +1,59 @@ + + + + + + + + +
+ +
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+
\ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeaderResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeaderResources.java new file mode 100644 index 00000000000..5234b07d59b --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeaderResources.java @@ -0,0 +1,23 @@ +package com.sap.sailing.gwt.home.client.place.event.partials.regattaHeader; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.resources.client.ClientBundle; +import com.google.gwt.resources.client.CssResource; + +public interface RegattaHeaderResources extends ClientBundle { + public static final RegattaHeaderResources INSTANCE = GWT.create(RegattaHeaderResources.class); + + @Source("RegattaHeader.css") + LocalCss css(); + + public interface LocalCss extends CssResource { + String regattaheader(); + String regattaheaderlink(); + String regattaheader_logo(); + String regattaheader_content(); + String regattaheader_content_title(); + String regattaheader_content_details(); + String regattaheader_content_details_item(); + String regattaheader_arrow(); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRaces.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRaces.gss similarity index 99% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRaces.gss rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRaces.gss index b9445eb6ff4..ee66c9be278 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRaces.gss +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRaces.gss @@ -189,15 +189,15 @@ } .eventregattarace_action { float: right; - width: 13%; text-align: center; text-transform: uppercase; cursor: pointer; } .eventregattarace_action_watch, .eventregattarace_action_analyze { - width: 9.666666666666666em; - max-width: 100%; + width: 10em; + padding-left: 10px; + padding-right: 10px; } .eventregattarace_action_watch { background-color: #f00; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRaces.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRaces.java similarity index 67% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRaces.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRaces.java index ba74db48285..fb46fa59d68 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRaces.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRaces.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.home.client.place.event.regattaraces; +package com.sap.sailing.gwt.home.client.place.event.partials.regattaraces; import java.util.ArrayList; import java.util.List; @@ -6,20 +6,18 @@ import java.util.List; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; -import com.sap.sailing.gwt.home.client.place.event.AbstractEventComposite; -import com.sap.sailing.gwt.home.client.place.event.EventPlaceNavigator; -import com.sap.sailing.gwt.home.client.place.event.regatta.Regatta; -import com.sap.sailing.gwt.ui.shared.EventDTO; +import com.sap.sailing.gwt.home.client.place.event.EventView; +import com.sap.sailing.gwt.home.client.place.event.EventView.Presenter; +import com.sap.sailing.gwt.home.client.place.event.partials.Regatta; import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; import com.sap.sailing.gwt.ui.shared.RaceGroupDTO; import com.sap.sailing.gwt.ui.shared.RaceGroupSeriesDTO; import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; -import com.sap.sse.gwt.client.player.Timer; -public class EventRegattaRaces extends AbstractEventComposite { +public class EventRegattaRaces extends Composite { private static EventRegattaRacesUiBinder uiBinder = GWT.create(EventRegattaRacesUiBinder.class); interface EventRegattaRacesUiBinder extends UiBinder { @@ -30,16 +28,15 @@ public class EventRegattaRaces extends AbstractEventComposite { @UiField HTMLPanel regattaPhasesPanel; @UiField HTMLPanel rootPanel; - private final Timer timerForClientServerOffset; private final List phaseElements; + private final Presenter presenter; - public EventRegattaRaces(EventDTO event, Timer timerForClientServerOffset, HomePlacesNavigator placeNavigator, EventPlaceNavigator pageNavigator) { - super(event, pageNavigator); - this.timerForClientServerOffset = timerForClientServerOffset; + public EventRegattaRaces(EventView.Presenter presenter) { + this.presenter = presenter; phaseElements = new ArrayList(); - regatta = new Regatta(event, timerForClientServerOffset, true, placeNavigator, pageNavigator); + regatta = new Regatta(true, presenter); EventRegattaRacesResources.INSTANCE.css().ensureInjected(); initWidget(uiBinder.createAndBindUi(this)); @@ -55,13 +52,13 @@ public class EventRegattaRaces extends AbstractEventComposite { int regattaPhases = raceGroup.getSeries().size(); if(regattaPhases > 1) { for(RaceGroupSeriesDTO series: raceGroup.getSeries()) { - EventRegattaRacesPhase regattaPhase = new EventRegattaRacesPhase(leaderboard, series, timerForClientServerOffset, getPageNavigator()); + EventRegattaRacesPhase regattaPhase = new EventRegattaRacesPhase(leaderboard, series, presenter); regattaPhasesPanel.getElement().appendChild(regattaPhase.getElement()); phaseElements.add(regattaPhase); } } else { RaceGroupSeriesDTO raceGroupSeriesDTO = raceGroup.getSeries().get(0); - EventRegattaRacesPhase regattaPhase = new EventRegattaRacesPhase(leaderboard, raceGroupSeriesDTO, timerForClientServerOffset, getPageNavigator()); + EventRegattaRacesPhase regattaPhase = new EventRegattaRacesPhase(leaderboard, raceGroupSeriesDTO, presenter); regattaPhasesPanel.getElement().appendChild(regattaPhase.getElement()); phaseElements.add(regattaPhase); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRaces.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRaces.ui.xml similarity index 90% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRaces.ui.xml rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRaces.ui.xml index 12c85bc9fd7..11bef605ea3 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRaces.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRaces.ui.xml @@ -1,23 +1,23 @@ + xmlns:s="urn:import:com.sap.sailing.gwt.home.client.place.event.partials"> - + - +
-
+
-
+
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesFleet.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesFleet.java similarity index 94% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesFleet.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesFleet.java index fb7091b32d7..059e1e2c3fd 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesFleet.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesFleet.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.home.client.place.event.regattaraces; +package com.sap.sailing.gwt.home.client.place.event.partials.regattaraces; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.DivElement; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesFleet.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesFleet.ui.xml similarity index 91% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesFleet.ui.xml rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesFleet.ui.xml index 498f8bfc8f1..030dd4ba815 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesFleet.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesFleet.ui.xml @@ -4,7 +4,7 @@ xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"> - +
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesFleetGroup.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesFleetGroup.java similarity index 83% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesFleetGroup.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesFleetGroup.java index 13f4b44faab..6969d7eba46 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesFleetGroup.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesFleetGroup.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.home.client.place.event.regattaraces; +package com.sap.sailing.gwt.home.client.place.event.partials.regattaraces; import java.util.ArrayList; import java.util.Date; @@ -13,11 +13,10 @@ import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.domain.common.dto.FleetDTO; import com.sap.sailing.domain.common.dto.RaceColumnDTO; -import com.sap.sailing.gwt.home.client.place.event.EventPlaceNavigator; +import com.sap.sailing.gwt.home.client.place.event.EventView; import com.sap.sailing.gwt.home.client.shared.EventDatesFormatterUtil; import com.sap.sailing.gwt.ui.shared.RaceGroupSeriesDTO; import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; -import com.sap.sse.gwt.client.player.Timer; public class EventRegattaRacesFleetGroup extends Composite { private static EventRegattaRacesFleetGroupUiBinder uiBinder = GWT.create(EventRegattaRacesFleetGroupUiBinder.class); @@ -29,7 +28,7 @@ public class EventRegattaRacesFleetGroup extends Composite { @UiField DivElement racesFromToDate; @UiField DivElement racesFleetPanel; - public EventRegattaRacesFleetGroup(StrippedLeaderboardDTO leaderboard, RaceGroupSeriesDTO series, List fleetsToShow, Timer timerForClientServerOffset, EventPlaceNavigator pageNavigator) { + public EventRegattaRacesFleetGroup(StrippedLeaderboardDTO leaderboard, RaceGroupSeriesDTO series, List fleetsToShow, EventView.Presenter presenter) { EventRegattaRacesResources.INSTANCE.css().ensureInjected(); initWidget(uiBinder.createAndBindUi(this)); @@ -37,28 +36,28 @@ public class EventRegattaRacesFleetGroup extends Composite { EventRegattaRacesFleet eventRegattaRacesFleet = new EventRegattaRacesFleet(fleet, 0); fleetsPanel.appendChild(eventRegattaRacesFleet.getElement()); - updateFleetRacesUI(leaderboard, series, fleet, timerForClientServerOffset, pageNavigator); + updateFleetRacesUI(leaderboard, series, fleet, presenter); } } - public EventRegattaRacesFleetGroup(StrippedLeaderboardDTO leaderboard, RaceGroupSeriesDTO series, Timer timerForClientServerOffset, EventPlaceNavigator pageNavigator) { + public EventRegattaRacesFleetGroup(StrippedLeaderboardDTO leaderboard, RaceGroupSeriesDTO series, EventView.Presenter presenter) { EventRegattaRacesResources.INSTANCE.css().ensureInjected(); initWidget(uiBinder.createAndBindUi(this)); fleetsPanel.getStyle().setDisplay(Display.NONE); FleetDTO defaultFleet = series.getFleets().get(0); - updateFleetRacesUI(leaderboard, series, defaultFleet, timerForClientServerOffset, pageNavigator); + updateFleetRacesUI(leaderboard, series, defaultFleet, presenter); } - private void updateFleetRacesUI(StrippedLeaderboardDTO leaderboard, RaceGroupSeriesDTO series, FleetDTO fleet, Timer timerForClientServerOffset, EventPlaceNavigator pageNavigator) { + private void updateFleetRacesUI(StrippedLeaderboardDTO leaderboard, RaceGroupSeriesDTO series, FleetDTO fleet, EventView.Presenter presenter) { Date fromDate = null; Date toDate = null; List racesOfFleet = getRacesOfFleet(leaderboard, series, fleet); for(RaceColumnDTO raceColumn: racesOfFleet) { RaceColumnDTO raceColumnFromLeaderboard = leaderboard.getRaceColumnByName(raceColumn.getName()); - EventRegattaRacesRace race = new EventRegattaRacesRace(leaderboard, fleet, raceColumnFromLeaderboard, timerForClientServerOffset, pageNavigator); + EventRegattaRacesRace race = new EventRegattaRacesRace(leaderboard, fleet, raceColumnFromLeaderboard, presenter); racesFleetPanel.appendChild(race.getElement()); Date startDate = raceColumnFromLeaderboard.getStartDate(fleet); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesFleetGroup.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesFleetGroup.ui.xml similarity index 92% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesFleetGroup.ui.xml rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesFleetGroup.ui.xml index 6c14b87026f..a15ce58430f 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesFleetGroup.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesFleetGroup.ui.xml @@ -4,7 +4,7 @@ xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"> - +
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesNavigationLink.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesNavigationLink.java similarity index 92% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesNavigationLink.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesNavigationLink.java index 71be5c07fdc..cc18389a319 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesNavigationLink.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesNavigationLink.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.home.client.place.event.regattaraces; +package com.sap.sailing.gwt.home.client.place.event.partials.regattaraces; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.SpanElement; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesNavigationLink.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesNavigationLink.ui.xml similarity index 90% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesNavigationLink.ui.xml rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesNavigationLink.ui.xml index 3d320cddc0b..4ae22638b26 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesNavigationLink.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesNavigationLink.ui.xml @@ -4,7 +4,7 @@ xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"> - + diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesPhase.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesPhase.java similarity index 83% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesPhase.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesPhase.java index 8ef13b24331..7903ea48185 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesPhase.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesPhase.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.home.client.place.event.regattaraces; +package com.sap.sailing.gwt.home.client.place.event.partials.regattaraces; import java.util.ArrayList; import java.util.List; @@ -12,10 +12,9 @@ import com.google.gwt.user.client.ui.UIObject; import com.sap.sailing.domain.common.LeaderboardNameConstants; import com.sap.sailing.domain.common.dto.FleetDTO; import com.sap.sailing.gwt.common.client.i18n.TextMessages; -import com.sap.sailing.gwt.home.client.place.event.EventPlaceNavigator; +import com.sap.sailing.gwt.home.client.place.event.EventView; import com.sap.sailing.gwt.ui.shared.RaceGroupSeriesDTO; import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; -import com.sap.sse.gwt.client.player.Timer; public class EventRegattaRacesPhase extends UIObject { private static EventRegattaRacesPhaseUiBinder uiBinder = GWT.create(EventRegattaRacesPhaseUiBinder.class); @@ -26,7 +25,7 @@ public class EventRegattaRacesPhase extends UIObject { @UiField SpanElement phaseName; @UiField DivElement fleetGroupsPanel; - public EventRegattaRacesPhase(StrippedLeaderboardDTO leaderboard, RaceGroupSeriesDTO series, Timer timerForClientServerOffset, EventPlaceNavigator pageNavigator) { + public EventRegattaRacesPhase(StrippedLeaderboardDTO leaderboard, RaceGroupSeriesDTO series, EventView.Presenter presenter) { EventRegattaRacesResources.INSTANCE.css().ensureInjected(); setElement(uiBinder.createAndBindUi(this)); @@ -43,18 +42,18 @@ public class EventRegattaRacesPhase extends UIObject { // ordered fleets are splitted into different fleet groups -> e.g. Gold Silver List fleetsToShow = new ArrayList(); fleetsToShow.add(fleet); - EventRegattaRacesFleetGroup fleetGroup = new EventRegattaRacesFleetGroup(leaderboard, series, fleetsToShow, timerForClientServerOffset, pageNavigator); + EventRegattaRacesFleetGroup fleetGroup = new EventRegattaRacesFleetGroup(leaderboard, series, fleetsToShow, presenter); fleetGroupsPanel.appendChild(fleetGroup.getElement()); } } else { // unordered fleets are NOT splitted into different fleet groups -> e.g. Blue, Yellow List fleetsToShow = new ArrayList(series.getFleets()); - EventRegattaRacesFleetGroup fleetGroup = new EventRegattaRacesFleetGroup(leaderboard, series, fleetsToShow, timerForClientServerOffset, pageNavigator); + EventRegattaRacesFleetGroup fleetGroup = new EventRegattaRacesFleetGroup(leaderboard, series, fleetsToShow, presenter); fleetGroupsPanel.appendChild(fleetGroup.getElement()); } } else { // single fleet - EventRegattaRacesFleetGroup fleetGroup = new EventRegattaRacesFleetGroup(leaderboard, series, timerForClientServerOffset, pageNavigator); + EventRegattaRacesFleetGroup fleetGroup = new EventRegattaRacesFleetGroup(leaderboard, series, presenter); fleetGroupsPanel.appendChild(fleetGroup.getElement()); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesPhase.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesPhase.ui.xml similarity index 90% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesPhase.ui.xml rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesPhase.ui.xml index c5f8568f38d..339e80cdcb0 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesPhase.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesPhase.ui.xml @@ -4,7 +4,7 @@ xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"> - +

diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRace.java similarity index 92% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRace.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRace.java index 813aff20a21..b1738436e4d 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRace.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRace.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.home.client.place.event.regattaraces; +package com.sap.sailing.gwt.home.client.place.event.partials.regattaraces; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.DivElement; @@ -16,10 +16,10 @@ import com.sap.sailing.domain.common.dto.CompetitorDTO; import com.sap.sailing.domain.common.dto.FleetDTO; import com.sap.sailing.domain.common.dto.RaceColumnDTO; import com.sap.sailing.domain.common.dto.RaceDTO; +import com.sap.sailing.gwt.home.client.place.event.EventView; +import com.sap.sailing.gwt.home.client.place.event.EventView.Presenter; import com.sap.sailing.domain.common.dto.RaceDTO.RaceLiveState; -import com.sap.sailing.gwt.home.client.place.event.EventPlaceNavigator; import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; -import com.sap.sse.gwt.client.player.Timer; public class EventRegattaRacesRace extends Composite { private static EventRegattaRacesRaceUiBinder uiBinder = GWT.create(EventRegattaRacesRaceUiBinder.class); @@ -63,12 +63,12 @@ public class EventRegattaRacesRace extends Composite { private final DateTimeFormat raceTimeFormat = DateTimeFormat.getFormat("EEE, h:mm a"); private final RaceDTO race; - private final Timer timerForClientServerOffset; private Element[] allConditionalElements; + private final Presenter presenter; - public EventRegattaRacesRace(StrippedLeaderboardDTO leaderboard, FleetDTO fleet, RaceColumnDTO raceColumn, Timer timerForClientServerOffset, EventPlaceNavigator pageNavigator) { - this.timerForClientServerOffset = timerForClientServerOffset; + public EventRegattaRacesRace(StrippedLeaderboardDTO leaderboard, FleetDTO fleet, RaceColumnDTO raceColumn, EventView.Presenter presenter) { + this.presenter = presenter; race = raceColumn.getRace(fleet); EventRegattaRacesResources.INSTANCE.css().ensureInjected(); @@ -85,7 +85,7 @@ public class EventRegattaRacesRace extends Composite { raceName2.setInnerText(raceColumn.getName()); if(race != null && race.trackedRace != null) { - String raceViewerURL = pageNavigator.getRaceViewerURL(leaderboard, race); + String raceViewerURL = presenter.getRaceViewerURL(leaderboard, race); analyzeRaceLink.setHref(raceViewerURL); watchRaceLink.setHref(raceViewerURL); } @@ -100,7 +100,7 @@ public class EventRegattaRacesRace extends Composite { hideElement(el); } - RaceLiveState liveState = race != null ? race.getLiveState(timerForClientServerOffset.getLiveTimePointInMillis()) : RaceLiveState.NOT_TRACKED; + RaceLiveState liveState = race != null ? race.getLiveState(presenter.getTimerForClientServerOffset().getLiveTimePointInMillis()) : RaceLiveState.NOT_TRACKED; switch(liveState) { case NOT_TRACKED: showElement(raceNotTrackedDiv); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRace.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRace.ui.xml similarity index 98% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRace.ui.xml rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRace.ui.xml index b0b47ba2bc2..dbf0cc923e5 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRace.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRace.ui.xml @@ -4,7 +4,7 @@ xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"> - +
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRaceProgressItem.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRaceProgressItem.java similarity index 89% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRaceProgressItem.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRaceProgressItem.java index e4a89801fbd..7677469d8ea 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRaceProgressItem.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRaceProgressItem.java @@ -1,11 +1,11 @@ -package com.sap.sailing.gwt.home.client.place.event.regattaraces; +package com.sap.sailing.gwt.home.client.place.event.partials.regattaraces; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.DivElement; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.UIObject; -import com.sap.sailing.gwt.home.client.place.event.regatta.RegattaResources; +import com.sap.sailing.gwt.home.client.place.event.partials.RegattaResources; public class EventRegattaRacesRaceProgressItem extends UIObject { private static EventRegattaRacesRaceProgressItemUiBinder uiBinder = GWT.create(EventRegattaRacesRaceProgressItemUiBinder.class); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRaceProgressItem.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRaceProgressItem.ui.xml similarity index 89% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRaceProgressItem.ui.xml rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRaceProgressItem.ui.xml index 0135da9c19f..9870e839e55 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRaceProgressItem.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRaceProgressItem.ui.xml @@ -4,6 +4,6 @@ xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"> - +
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRaceday.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRaceday.java similarity index 93% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRaceday.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRaceday.java index 9a2430eeac1..7e374044918 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRaceday.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRaceday.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.home.client.place.event.regattaraces; +package com.sap.sailing.gwt.home.client.place.event.partials.regattaraces; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.DivElement; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRaceday.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRaceday.ui.xml similarity index 91% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRaceday.ui.xml rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRaceday.ui.xml index 8b83deb84ce..240383e279e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRaceday.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesRaceday.ui.xml @@ -4,7 +4,7 @@ xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"> - +
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesResources.java similarity index 93% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesResources.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesResources.java index 16f7a4157f3..04301953cb1 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaraces/EventRegattaRacesResources.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.home.client.place.event.regattaraces; +package com.sap.sailing.gwt.home.client.place.event.partials.regattaraces; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ClientBundle; @@ -8,7 +8,7 @@ import com.google.gwt.resources.client.CssResource.Shared; public interface EventRegattaRacesResources extends ClientBundle { public static final EventRegattaRacesResources INSTANCE = GWT.create(EventRegattaRacesResources.class); - @Source("com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRaces.gss") + @Source("EventRegattaRaces.gss") LocalCss css(); @Shared diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/AbstractEventRegattaPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/AbstractEventRegattaPlace.java new file mode 100644 index 00000000000..d8e6a282a46 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/AbstractEventRegattaPlace.java @@ -0,0 +1,18 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta; + +import com.sap.sailing.gwt.home.client.place.event.AbstractEventPlace; +import com.sap.sailing.gwt.home.client.place.event.EventContext; + +public abstract class AbstractEventRegattaPlace extends AbstractEventPlace { + + public AbstractEventRegattaPlace(EventContext ctx) { + super(ctx); + } + + public AbstractEventRegattaPlace(String eventUuidAsString, String regattaId) { + super(eventUuidAsString); + getCtx().withRegattaId(regattaId); + } + + public abstract AbstractEventRegattaPlace newInstanceWithContext(EventContext ctx); +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/EventRegattaActivity.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/EventRegattaActivity.java new file mode 100644 index 00000000000..39d95c2d5fd --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/EventRegattaActivity.java @@ -0,0 +1,91 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta; + +import com.google.gwt.event.shared.EventBus; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.place.event.AbstractEventActivity; +import com.sap.sailing.gwt.home.client.place.event.EventClientFactory; +import com.sap.sailing.gwt.home.client.place.event.EventContext; +import com.sap.sailing.gwt.home.client.place.event.EventView; +import com.sap.sailing.gwt.home.client.place.event.EventView.PlaceCallback; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaOverviewPlace; +import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO; +import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO.EventType; +import com.sap.sailing.gwt.ui.shared.eventview.RegattaReferenceDTO; +import com.sap.sailing.gwt.ui.shared.general.EventReferenceDTO; +import com.sap.sse.gwt.client.async.AsyncActionsExecutor; +import com.sap.sse.gwt.client.player.Timer; +import com.sap.sse.gwt.client.player.Timer.PlayModes; +import com.sap.sse.gwt.client.player.Timer.PlayStates; +import com.sap.sse.gwt.client.useragent.UserAgentDetails; + +public class EventRegattaActivity extends AbstractEventActivity implements EventRegattaView.Presenter { + private EventRegattaView currentView = new TabletAndDesktopEventView(); + private final UserAgentDetails userAgent = new UserAgentDetails(Window.Navigator.getUserAgent()); + private final AsyncActionsExecutor asyncActionsExecutor = new AsyncActionsExecutor(); + private final long delayBetweenAutoAdvancesInMilliseconds = 3000l; + + public EventRegattaActivity(AbstractEventRegattaPlace place, EventClientFactory clientFactory, + HomePlacesNavigator homePlacesNavigator) { + super(place, clientFactory, homePlacesNavigator); + if (this.ctx.getRegattaAnalyticsManager() == null) { + ctx.withRegattaAnalyticsManager(new RegattaAnalyticsDataManager( + clientFactory.getSailingService(), + asyncActionsExecutor, + new Timer(PlayModes.Live, PlayStates.Paused, delayBetweenAutoAdvancesInMilliseconds), + clientFactory.getErrorReporter(), + userAgent)); + } + } + + @Override + public void start(final AcceptsOneWidget panel, final EventBus eventBus) { + currentView.registerPresenter(this); + panel.setWidget(currentView); + currentView.navigateTabsTo(currentPlace); + } + + @Override + public boolean needsSelectionInHeader() { + EventViewDTO event = ctx.getEventDTO(); + return (event.getType() == EventType.SERIES_EVENT || event.getType() == EventType.MULTI_REGATTA); + } + + @Override + public void forPlaceSelection(PlaceCallback callback) { + EventViewDTO event = ctx.getEventDTO(); + if (event.getType() == EventType.SERIES_EVENT) { + for(EventReferenceDTO seriesEvent : event.getEventsOfSeries()) { + AbstractEventRegattaPlace place = currentPlace.newInstanceWithContext(new EventContext().withId(seriesEvent.getId().toString())); + callback.forPlace(place, seriesEvent.getDisplayName(), (event.getId().equals(seriesEvent.getId()))); + } + } else { + for(RegattaReferenceDTO regatta : event.getRegattas()) { + AbstractEventRegattaPlace place = currentPlace.newInstanceWithContext(contextForRegatta(regatta.getId())); + callback.forPlace(place, regatta.getDisplayName(), (ctx.getRegattaId().equals(regatta.getId()))); + } + } + } + + @Override + public boolean showRegattaMetadata() { + return ctx.getEventDTO().getType() == EventType.MULTI_REGATTA && ctx.getRegatta() != null; + } + + @Override + public PlaceNavigation getCurrentRegattaOverviewNavigation() { + return homePlacesNavigator.getEventNavigation(new RegattaOverviewPlace(ctx), null, false); + } + + @Override + public Timer getAutoRefreshTimer() { + return ctx.getRegattaAnalyticsManager().getTimer(); + } + + @Override + protected EventView getView() { + return currentView; + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/EventRegattaView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/EventRegattaView.java new file mode 100644 index 00000000000..bb1a9b946ae --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/EventRegattaView.java @@ -0,0 +1,16 @@ +package com.sap.sailing.gwt.home.client.place.event.regatta; + +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.place.event.EventView; +import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.RegattaOverviewPlace; +import com.sap.sse.gwt.client.player.Timer; + +public interface EventRegattaView extends EventView { + + public interface Presenter extends EventView.Presenter { + + PlaceNavigation getCurrentRegattaOverviewNavigation(); + + Timer getAutoRefreshTimer(); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalyticsDataManager.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaAnalyticsDataManager.java similarity index 78% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalyticsDataManager.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaAnalyticsDataManager.java index d6d9a959c04..67441dc299e 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalyticsDataManager.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaAnalyticsDataManager.java @@ -1,13 +1,7 @@ -package com.sap.sailing.gwt.home.client.place.event.regattaanalytics; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; +package com.sap.sailing.gwt.home.client.place.event.regatta; import com.sap.sailing.domain.common.DetailType; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; -import com.sap.sailing.domain.common.dto.CompetitorDTO; -import com.sap.sailing.gwt.ui.client.CompetitorSelectionChangeListener; import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel; import com.sap.sailing.gwt.ui.client.DebugIdHelper; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; @@ -16,7 +10,6 @@ import com.sap.sailing.gwt.ui.client.shared.charts.MultiCompetitorLeaderboardCha import com.sap.sailing.gwt.ui.client.shared.charts.MultiCompetitorLeaderboardChartSettings; import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel; import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings; -import com.sap.sse.common.Util; import com.sap.sse.common.settings.AbstractSettings; import com.sap.sse.gwt.client.ErrorReporter; import com.sap.sse.gwt.client.async.AsyncActionsExecutor; @@ -40,7 +33,6 @@ public class RegattaAnalyticsDataManager { private final UserAgentDetails userAgent; private final SailingServiceAsync sailingService; private final Timer timer; - private final int MAX_COMPETITORS_IN_CHART = 30; public RegattaAnalyticsDataManager(final SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor, Timer timer, ErrorReporter errorReporter, UserAgentDetails userAgent) { this.competitorSelectionProvider = new CompetitorSelectionModel(/* hasMultiSelection */true); @@ -56,7 +48,7 @@ public class RegattaAnalyticsDataManager { public LeaderboardPanel createLeaderboardPanel(final LeaderboardSettings leaderboardSettings, final RegattaAndRaceIdentifier preselectedRace, final String leaderboardGroupName, String leaderboardName, boolean showRaceDetails, boolean autoExpandLastRaceColumn) { - if(leaderboardPanel == null) { + if (leaderboardPanel == null) { leaderboardPanel = new LeaderboardPanel(sailingService, asyncActionsExecutor, leaderboardSettings, true, preselectedRace, competitorSelectionProvider, timer, leaderboardGroupName, leaderboardName, errorReporter, StringMessages.INSTANCE, userAgent, showRaceDetails, /* competitorSearchTextBox */ null, /* showSelectionCheckbox */ true, /* raceTimesInfoProvider */null, autoExpandLastRaceColumn, /* adjustTimerDelay */ @@ -87,21 +79,6 @@ public class RegattaAnalyticsDataManager { } public void showCompetitorChart(DetailType chartDetailType) { - // preselect the top N competitors in case there was no selection before and there too many competitors for a chart - int competitorsCount = Util.size(competitorSelectionProvider.getAllCompetitors()); - int selectedCompetitorsCount = Util.size(competitorSelectionProvider.getSelectedCompetitors()); - - if(selectedCompetitorsCount == 0 && competitorsCount > MAX_COMPETITORS_IN_CHART) { - List selectedCompetitors = new ArrayList(); - Iterator allCompetitorsIt = competitorSelectionProvider.getAllCompetitors().iterator(); - int counter = 0; - while(counter < MAX_COMPETITORS_IN_CHART) { - selectedCompetitors.add(allCompetitorsIt.next()); - counter++; - } - competitorSelectionProvider.setSelection(selectedCompetitors, (CompetitorSelectionChangeListener[]) null); - } - MultiCompetitorLeaderboardChart multiCompetitorChart = getMultiCompetitorChart(); MultiCompetitorLeaderboardChartSettings settings = new MultiCompetitorLeaderboardChartSettings(chartDetailType); multiCompetitorChart.updateSettings(settings); @@ -113,8 +90,10 @@ public class RegattaAnalyticsDataManager { public void hideCompetitorChart() { MultiCompetitorLeaderboardChart multiCompetitorChart = getMultiCompetitorChart(); - multiCompetitorChart.setVisible(false); - timer.removeTimeListener(multiCompetitorChart); + if (multiCompetitorChart != null) { + multiCompetitorChart.setVisible(false); + timer.removeTimeListener(multiCompetitorChart); + } } public void showLeaderboardSettingsDialog() { @@ -132,4 +111,8 @@ public class RegattaAnalyticsDataManager { dialog.ensureDebugId(debugIdPrefix + "SettingsDialog"); dialog.show(); } + + public Timer getTimer() { + return timer; + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaCompetitor.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaCompetitor.java deleted file mode 100644 index 4ae86df3d8d..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaCompetitor.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.regatta; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.dom.client.SpanElement; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.domain.common.dto.CompetitorDTO; - -public class RegattaCompetitor extends Composite { - private static RegattaCompetitorUiBinder uiBinder = GWT.create(RegattaCompetitorUiBinder.class); - - interface RegattaCompetitorUiBinder extends UiBinder { - } - - @UiField SpanElement competitorRank; - @UiField SpanElement competitorNationality; - @UiField SpanElement competitorName; - @UiField SpanElement competitorTotalPoints; - - public RegattaCompetitor(Integer rank, CompetitorDTO competitor) { - - RegattaResources.INSTANCE.css().ensureInjected(); - initWidget(uiBinder.createAndBindUi(this)); - - competitorRank.setInnerText(String.valueOf(rank)); - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaCompetitor.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaCompetitor.ui.xml deleted file mode 100644 index d150d87d35c..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaCompetitor.ui.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - .panel { - display: inline-block; - } - - -
- .  -  -  -
-
-
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaFleet.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaFleet.java deleted file mode 100644 index 477037c1095..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaFleet.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.regatta; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.Widget; - -public class RegattaFleet extends Composite { - private static RegattaFleetUiBinder uiBinder = GWT.create(RegattaFleetUiBinder.class); - - interface RegattaFleetUiBinder extends UiBinder { - } - - public RegattaFleet() { - - RegattaResources.INSTANCE.css().ensureInjected(); - initWidget(uiBinder.createAndBindUi(this)); - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaFleet.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaFleet.ui.xml deleted file mode 100644 index 408ed66337e..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaFleet.ui.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - -
-
{fleet.name}
-
-
{fleet.phase.name} - {fleet.race.name} -
-
-
- {#if regatta.isScheduled} {/if regatta.isScheduled} - {#if regatta.isLive} {/if regatta.isLive} - {#if regatta.isFinished} {/if regatta.isFinished}{fleet.time} -
-
-
-
-
 {fleet.course}
-
-
 {fleet.area}
-
- {#if regatta.isLive}{/if regatta.isLive} -
- - - - - - - {#each competitor in leaderboard.competitors}{/each leaderboard.competitors} -
- - {#each columnName in leaderboard.columnNames}{/each leaderboard.columnNames} - -
-
-
-
- - diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/EventRegattaLeaderboardResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/EventRegattaLeaderboardResources.java index 1cf346f3656..c1a0d393c05 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/EventRegattaLeaderboardResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/EventRegattaLeaderboardResources.java @@ -7,7 +7,7 @@ import com.google.gwt.resources.client.CssResource; public interface EventRegattaLeaderboardResources extends ClientBundle { public static final EventRegattaLeaderboardResources INSTANCE = GWT.create(EventRegattaLeaderboardResources.class); - @Source("com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/EventRegattaLeaderboard.css") + @Source("EventRegattaLeaderboard.gss") LocalCss css(); public interface LocalCss extends CssResource { @@ -33,6 +33,10 @@ public interface EventRegattaLeaderboardResources extends ClientBundle { String regattaleaderboard_meta_scoring_text(); String regattaleaderboard_meta_update_text(); String regattaleaderboard_meta_reload(); + + String regattaleaderboard_meta_reload_playing(); + String regattaleaderboard_meta_reload_live(); + String regattaleaderboard_meta_settings_button(); String regattaleaderboard_meta_settings(); String regattaleaderboard_table(); @@ -58,5 +62,7 @@ public interface EventRegattaLeaderboardResources extends ClientBundle { String leaderboardcompetitor_item_table(); String leaderboardcompetitor_itemcenter_table(); String leaderboardcompetitorshort(); + String marginFix(); + String letItScroll(); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/RegattaLeaderboardCompetitor.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/RegattaLeaderboardCompetitor.ui.xml deleted file mode 100644 index 0ed1f0a3601..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/RegattaLeaderboardCompetitor.ui.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - {competitor.rank} - {competitor.nationality}{competitor.sailID} - {competitor.name} - - - {#each raceScore in competitor.raceScores}{/each competitor.raceScores} - -
- - {competitor.totalPoints} - -
-
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/RegattaLeaderboardCompetitorRaceScore.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/RegattaLeaderboardCompetitorRaceScore.ui.xml deleted file mode 100644 index cfa45861dae..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/RegattaLeaderboardCompetitorRaceScore.ui.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - -{raceScore.totalPoints} - - diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/RegattaLeaderboardHeaderColumn.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/RegattaLeaderboardHeaderColumn.ui.xml deleted file mode 100644 index 00c3741bf3f..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/RegattaLeaderboardHeaderColumn.ui.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - -{columnName} - - diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattalist/EventRegattaList.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattalist/EventRegattaList.css deleted file mode 100644 index 5ec8c1c90cd..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattalist/EventRegattaList.css +++ /dev/null @@ -1,8 +0,0 @@ -.eventregattalist { - font-size: 15px; - font-size: 1rem; -} -.eventregattalist_navigation { - padding: 1.333333333333333em 0; - border-bottom: 1px solid #ccc; -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/schedule/EventSchedule.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/schedule/EventSchedule.css deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/schedule/EventSchedule.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/schedule/EventSchedule.java deleted file mode 100644 index 1d65d2d726e..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/schedule/EventSchedule.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.schedule; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.gwt.home.client.place.event.AbstractEventComposite; -import com.sap.sailing.gwt.home.client.place.event.EventPlaceNavigator; -import com.sap.sailing.gwt.ui.shared.EventDTO; - -public class EventSchedule extends AbstractEventComposite { - private static EventScheduleUiBinder uiBinder = GWT.create(EventScheduleUiBinder.class); - - interface EventScheduleUiBinder extends UiBinder { - } - - public EventSchedule(EventDTO event, EventPlaceNavigator placeNavigator) { - super(event, placeNavigator); - - EventScheduleResources.INSTANCE.css().ensureInjected(); - initWidget(uiBinder.createAndBindUi(this)); - } - -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/schedule/EventSchedule.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/schedule/EventSchedule.ui.xml deleted file mode 100644 index 2642391d7e8..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/schedule/EventSchedule.ui.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - Event Media - - diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/schedule/EventScheduleResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/schedule/EventScheduleResources.java deleted file mode 100644 index 14510abb681..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/schedule/EventScheduleResources.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.schedule; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.resources.client.ClientBundle; -import com.google.gwt.resources.client.CssResource; - -public interface EventScheduleResources extends ClientBundle { - public static final EventScheduleResources INSTANCE = GWT.create(EventScheduleResources.class); - - @Source("com/sap/sailing/gwt/home/client/place/event/schedule/EventSchedule.css") - LocalCss css(); - - public interface LocalCss extends CssResource { - - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalytics.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalytics.css deleted file mode 100644 index bf31e228ea4..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalytics.css +++ /dev/null @@ -1,11 +0,0 @@ -.oldLeaderboardPanel { - background-color:#f8f8f8; - padding: 0 10px 10px 10px; - width: 100%; -} - -.oldMultiLeaderboardPanel { - background-color:#f8f8f8; - padding: 0 10px 10px 10px; - width: 100%; -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalytics.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalytics.java deleted file mode 100644 index aedd0e0a078..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalytics.java +++ /dev/null @@ -1,244 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.seriesanalytics; - -import java.util.ArrayList; -import java.util.List; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.dom.client.DivElement; -import com.google.gwt.dom.client.SpanElement; -import com.google.gwt.dom.client.Style.Visibility; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.uibinder.client.UiHandler; -import com.google.gwt.user.client.Event; -import com.google.gwt.user.client.History; -import com.google.gwt.user.client.ui.Anchor; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.HTMLPanel; -import com.google.gwt.user.client.ui.Widget; -import com.google.gwt.user.client.ui.impl.HyperlinkImpl; -import com.sap.sailing.domain.common.DetailType; -import com.sap.sailing.domain.common.LeaderboardNameConstants; -import com.sap.sailing.domain.common.RaceIdentifier; -import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; -import com.sap.sailing.domain.common.dto.FleetDTO; -import com.sap.sailing.domain.common.dto.LeaderboardDTO; -import com.sap.sailing.domain.common.dto.RaceColumnDTO; -import com.sap.sailing.gwt.common.client.SharedResources; -import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; -import com.sap.sailing.gwt.home.client.app.PlaceNavigation; -import com.sap.sailing.gwt.home.client.place.event.header.CompactEventHeader; -import com.sap.sailing.gwt.home.client.place.event.oldcompetitorcharts.OldCompetitorCharts; -import com.sap.sailing.gwt.home.client.place.event.oldleaderboard.OldLeaderboard; -import com.sap.sailing.gwt.home.client.place.event.oldmultileaderboard.OldMultiLeaderboard; -import com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources; -import com.sap.sailing.gwt.home.client.place.series.SeriesPlace; -import com.sap.sailing.gwt.home.client.place.series.SeriesPlace.SeriesNavigationTabs; -import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener; -import com.sap.sailing.gwt.ui.client.SailingServiceAsync; -import com.sap.sailing.gwt.ui.client.StringMessages; -import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sse.common.Util.Pair; -import com.sap.sse.gwt.client.ErrorReporter; -import com.sap.sse.gwt.client.async.AsyncActionsExecutor; -import com.sap.sse.gwt.client.player.Timer; -import com.sap.sse.gwt.client.useragent.UserAgentDetails; - -public class EventSeriesAnalytics extends Composite implements LeaderboardUpdateListener { - private static EventSeriesAnalyticsUiBinder uiBinder = GWT.create(EventSeriesAnalyticsUiBinder.class); - - interface EventSeriesAnalyticsUiBinder extends UiBinder { - } - - private static final HyperlinkImpl HYPERLINK_IMPL = GWT.create(HyperlinkImpl.class); - - @UiField OldLeaderboard oldOverallLeaderboardComposite; - @UiField OldCompetitorCharts oldCompetitorChartsComposite; - @UiField OldMultiLeaderboard oldRegattaLeaderboardsComposite; - @UiField(provided=true) CompactEventHeader eventHeader; - - @UiField SpanElement title; - @UiField DivElement liveRaceDiv; - - @UiField HTMLPanel overallLeaderboardTabPanel; - @UiField HTMLPanel regattaLeaderboardsTabPanel; - @UiField HTMLPanel competitorChartsTabPanel; - @UiField Anchor overallLeaderboardAnchor; - @UiField Anchor regattaLeaderboardsAnchor; - @UiField Anchor competitorChartsAnchor; - - private final PlaceNavigation overallLeaderboardNavigation; - private final PlaceNavigation regattaLeaderboardsNavigation; - private final PlaceNavigation competitorChartsNavigation; - - private HTMLPanel activeTabPanel; - private Widget activeContentWidget; - private Anchor activeAnchor; - private EventSeriesAnalyticsDataManager eventSeriesAnalyticsManager; - private Timer autoRefreshTimer; - private SeriesNavigationTabs navigationTab; - - public EventSeriesAnalytics(EventDTO event, String leaderboardName, SeriesNavigationTabs navigationTab, Timer timerForClientServerOffset, HomePlacesNavigator placesNavigator) { - this.navigationTab = navigationTab; - - eventHeader = new CompactEventHeader(event, leaderboardName, placesNavigator); - - EventRegattaLeaderboardResources.INSTANCE.css().ensureInjected(); - EventSeriesAnalyticsResources.INSTANCE.css().ensureInjected(); - - initWidget(uiBinder.createAndBindUi(this)); - - String seriesTitle = leaderboardName; - if(seriesTitle.endsWith(LeaderboardNameConstants.OVERALL)) { - seriesTitle = seriesTitle.substring(0, seriesTitle.length() - LeaderboardNameConstants.OVERALL.length()); - seriesTitle = seriesTitle.trim(); - } - title.setInnerText(seriesTitle); - - overallLeaderboardTabPanel.setVisible(false); - regattaLeaderboardsTabPanel.setVisible(false); - competitorChartsTabPanel.setVisible(false); - liveRaceDiv.getStyle().setVisibility(Visibility.HIDDEN); - - overallLeaderboardNavigation = placesNavigator.getSeriesAnalyticsNavigation(event.id.toString(), SeriesNavigationTabs.OverallLeaderboard, leaderboardName, - event.getBaseURL(), event.isOnRemoteServer()); - regattaLeaderboardsNavigation = placesNavigator.getSeriesAnalyticsNavigation(event.id.toString(), SeriesNavigationTabs.RegattaLeaderboards, leaderboardName, - event.getBaseURL(), event.isOnRemoteServer()); - competitorChartsNavigation = placesNavigator.getSeriesAnalyticsNavigation(event.id.toString(), SeriesNavigationTabs.CompetitorAnalytics, leaderboardName, - event.getBaseURL(), event.isOnRemoteServer()); - - overallLeaderboardAnchor.setHref(overallLeaderboardNavigation.getTargetUrl()); - regattaLeaderboardsAnchor.setHref(regattaLeaderboardsNavigation.getTargetUrl()); - competitorChartsAnchor.setHref(competitorChartsNavigation.getTargetUrl()); - } - - public void createSeriesAnalyticsViewer(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor, - Timer timer, LeaderboardSettings leaderboardSettings, String preselectedLeaderboardName, RegattaAndRaceIdentifier preselectedRace, - String leaderboardGroupName, String metaLeaderboardName, ErrorReporter errorReporter, - UserAgentDetails userAgent, boolean showRaceDetails, - boolean autoExpandLastRaceColumn, boolean showSeriesLeaderboards) { - this.autoRefreshTimer = timer; - eventSeriesAnalyticsManager = new EventSeriesAnalyticsDataManager(sailingService, asyncActionsExecutor, timer, errorReporter, userAgent); - eventSeriesAnalyticsManager.createOverallLeaderboardPanel(leaderboardSettings, preselectedRace, leaderboardGroupName, metaLeaderboardName, showRaceDetails, autoExpandLastRaceColumn); - eventSeriesAnalyticsManager.createMultiLeaderboardPanel(leaderboardSettings, null /*preSelectedLeaderboardName */, preselectedRace, leaderboardGroupName, metaLeaderboardName, showRaceDetails, autoExpandLastRaceColumn); - - DetailType initialDetailType = DetailType.OVERALL_RANK; - List availableDetailsTypes = new ArrayList(); - availableDetailsTypes.add(DetailType.OVERALL_RANK); - availableDetailsTypes.add(DetailType.REGATTA_TOTAL_POINTS_SUM); - - eventSeriesAnalyticsManager.createMultiCompetitorChart(metaLeaderboardName, DetailType.OVERALL_RANK); - - oldOverallLeaderboardComposite.setLeaderboard(eventSeriesAnalyticsManager.getLeaderboardPanel(), timer); - oldRegattaLeaderboardsComposite.setMultiLeaderboard(eventSeriesAnalyticsManager.getMultiLeaderboardPanel(), timer); - - oldCompetitorChartsComposite.setChart(eventSeriesAnalyticsManager.getMultiCompetitorChart(), availableDetailsTypes, initialDetailType); - eventSeriesAnalyticsManager.hideCompetitorChart(); - - eventSeriesAnalyticsManager.getLeaderboardPanel().addLeaderboardUpdateListener(this); - eventSeriesAnalyticsManager.getMultiLeaderboardPanel().addLeaderboardUpdateListener(this); - - switch(navigationTab) { - case OverallLeaderboard: - setActiveTabPanel(overallLeaderboardTabPanel, eventSeriesAnalyticsManager.getLeaderboardPanel(), overallLeaderboardAnchor); - break; - case RegattaLeaderboards: - setActiveTabPanel(regattaLeaderboardsTabPanel, eventSeriesAnalyticsManager.getMultiLeaderboardPanel(), regattaLeaderboardsAnchor); - break; - case CompetitorAnalytics: - setActiveTabPanel(competitorChartsTabPanel, eventSeriesAnalyticsManager.getMultiCompetitorChart(), competitorChartsAnchor); - DetailType selectedChartDetailType = oldCompetitorChartsComposite.getSelectedChartDetailType(); - eventSeriesAnalyticsManager.showCompetitorChart(selectedChartDetailType); - break; - } - - activeContentWidget = eventSeriesAnalyticsManager.getLeaderboardPanel(); - } - - @Override - public void updatedLeaderboard(LeaderboardDTO leaderboard) { - if(activeTabPanel == overallLeaderboardTabPanel) { - StringMessages stringMessages = StringMessages.INSTANCE; - - if(leaderboard != null) { - List> liveRaces = leaderboard.getLiveRaces(autoRefreshTimer.getLiveTimePointInMillis()); - boolean hasLiveRace = !liveRaces.isEmpty(); - if (hasLiveRace) { - String liveRaceText = ""; - if(liveRaces.size() == 1) { - Pair liveRace = liveRaces.get(0); - liveRaceText = stringMessages.raceIsLive("'" + liveRace.getA().getRaceColumnName() + "'"); - } else { - String raceNames = ""; - for (Pair liveRace : liveRaces) { - raceNames += "'" + liveRace.getA().getRaceColumnName() + "', "; - } - // remove last ", " - raceNames = raceNames.substring(0, raceNames.length() - 2); - liveRaceText = stringMessages.racesAreLive(raceNames); - } - liveRaceDiv.setInnerText(liveRaceText); - } else { - liveRaceDiv.setInnerText(""); - } - liveRaceDiv.getStyle().setVisibility(hasLiveRace ? Visibility.VISIBLE : Visibility.HIDDEN); - - oldOverallLeaderboardComposite.updatedLeaderboard(leaderboard, hasLiveRace); - } - } else if(activeTabPanel == regattaLeaderboardsTabPanel) { - oldRegattaLeaderboardsComposite.updatedMultiLeaderboard(leaderboard, false); - } - } - - @Override - public void currentRaceSelected(RaceIdentifier raceIdentifier, RaceColumnDTO raceColumn) { - } - - @UiHandler("overallLeaderboardAnchor") - void overallLeaderboardTabClicked(ClickEvent event) { - setActiveTabPanel(overallLeaderboardTabPanel, eventSeriesAnalyticsManager.getLeaderboardPanel(), overallLeaderboardAnchor); - handleClickEvent(event, overallLeaderboardNavigation); - } - - @UiHandler("regattaLeaderboardsAnchor") - void regattaLeaderboardsTabClicked(ClickEvent event) { - setActiveTabPanel(regattaLeaderboardsTabPanel, eventSeriesAnalyticsManager.getMultiLeaderboardPanel(), regattaLeaderboardsAnchor); - handleClickEvent(event, regattaLeaderboardsNavigation); - } - - @UiHandler("competitorChartsAnchor") - void competitorChartsTabClicked(ClickEvent event) { - setActiveTabPanel(competitorChartsTabPanel, eventSeriesAnalyticsManager.getMultiCompetitorChart(), competitorChartsAnchor); - DetailType selectedChartDetailType = oldCompetitorChartsComposite.getSelectedChartDetailType(); - eventSeriesAnalyticsManager.showCompetitorChart(selectedChartDetailType); - oldCompetitorChartsComposite.updateSelectionState(eventSeriesAnalyticsManager.getCompetitorSelectionProvider()); - handleClickEvent(event, competitorChartsNavigation); - } - - private void setActiveTabPanel(HTMLPanel newActivePanel, Widget newActiveContentWidget, Anchor newActiveAnchor) { - if(activeTabPanel != null) { - activeTabPanel.setVisible(false); - activeAnchor.removeStyleName(SharedResources.INSTANCE.mainCss().navbar_buttonactive()); - } - if(activeContentWidget != null) { - activeContentWidget.setVisible(false); - } - - activeTabPanel = newActivePanel; - activeContentWidget = newActiveContentWidget; - activeAnchor = newActiveAnchor; - activeTabPanel.setVisible(true); - activeContentWidget.setVisible(true); - activeAnchor.addStyleName(SharedResources.INSTANCE.mainCss().navbar_buttonactive()); - } - - private void handleClickEvent(ClickEvent e, PlaceNavigation placeNavigation) { - if (HYPERLINK_IMPL.handleAsClick((Event) e.getNativeEvent())) { - // don't use the placecontroller for navigation here as we want to avoid a page reload - History.newItem(placeNavigation.getHistoryUrl(), false); - e.preventDefault(); - } - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalytics.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalytics.ui.xml deleted file mode 100644 index 81a4b52324e..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalytics.ui.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - -
-
-

- - -

-
- -
-
-
- - - -
-
- - - - - - - - - -
-
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalyticsResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalyticsResources.java deleted file mode 100644 index 8673dd74640..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalyticsResources.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.event.seriesanalytics; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.resources.client.ClientBundle; -import com.google.gwt.resources.client.CssResource; - -public interface EventSeriesAnalyticsResources extends ClientBundle { - public static final EventSeriesAnalyticsResources INSTANCE = GWT.create(EventSeriesAnalyticsResources.class); - - @Source("com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalytics.css") - LocalCss css(); - - public interface LocalCss extends CssResource { - String oldLeaderboardPanel(); - String oldMultiLeaderboardPanel(); - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/utils/EventParamUtils.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/utils/EventParamUtils.java new file mode 100644 index 00000000000..1c9e1699e7d --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/utils/EventParamUtils.java @@ -0,0 +1,137 @@ +package com.sap.sailing.gwt.home.client.place.event.utils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import com.google.gwt.user.client.Window; +import com.sap.sailing.domain.common.DetailType; +import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; +import com.sap.sailing.domain.common.RegattaNameAndRaceName; +import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings; +import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings.RaceColumnSelectionStrategies; +import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettingsFactory; +import com.sap.sailing.gwt.ui.leaderboard.LeaderboardUrlSettings; + +public class EventParamUtils { + + public static RegattaAndRaceIdentifier getPreselectedRace(Map> parameterMap) { + RegattaAndRaceIdentifier result; + if (parameterMap.containsKey(LeaderboardUrlSettings.PARAM_RACE_NAME) + && parameterMap.get(LeaderboardUrlSettings.PARAM_RACE_NAME).size() == 1 + && parameterMap.containsKey(LeaderboardUrlSettings.PARAM_REGATTA_NAME) + && parameterMap.get(LeaderboardUrlSettings.PARAM_REGATTA_NAME).size() == 1) { + result = new RegattaNameAndRaceName(parameterMap.get(LeaderboardUrlSettings.PARAM_REGATTA_NAME).get(0), + parameterMap.get(LeaderboardUrlSettings.PARAM_RACE_NAME).get(0)); + } else { + result = null; + } + return result; + } + + public static List getDetailTypeListFromParamValue(List list) { + List result = new ArrayList(); + if (list != null) { + for (String entry : list) { + try { + result.add(DetailType.valueOf(entry)); + } catch (IllegalArgumentException e) { + } + } + } + return result; + } + + public static LeaderboardSettings createLeaderboardSettingsFromURLParameters(Map> parameterMap) { + LeaderboardSettings result; + Long refreshIntervalMillis = parameterMap.containsKey(LeaderboardUrlSettings.PARAM_REFRESH_INTERVAL_MILLIS) ? Long + .valueOf(parameterMap.get(LeaderboardUrlSettings.PARAM_REFRESH_INTERVAL_MILLIS).get(0)) : null; + RaceColumnSelectionStrategies raceColumnSelectionStrategy; + final Integer numberOfLastRacesToShow; + if (parameterMap.containsKey(LeaderboardUrlSettings.PARAM_NAME_LAST_N)) { + raceColumnSelectionStrategy = RaceColumnSelectionStrategies.LAST_N; + numberOfLastRacesToShow = Integer + .valueOf(parameterMap.get(LeaderboardUrlSettings.PARAM_NAME_LAST_N).get(0)); + } else if (WindowUtils.isSmallWidth()) { + raceColumnSelectionStrategy = RaceColumnSelectionStrategies.LAST_N; + int width = Window.getClientWidth(); + numberOfLastRacesToShow = (width - 275) / 40; + } else { + raceColumnSelectionStrategy = RaceColumnSelectionStrategies.EXPLICIT; + numberOfLastRacesToShow = null; + } + if (parameterMap.containsKey(LeaderboardUrlSettings.PARAM_RACE_NAME) + || parameterMap.containsKey(LeaderboardUrlSettings.PARAM_RACE_DETAIL) + || parameterMap.containsKey(LeaderboardUrlSettings.PARAM_LEG_DETAIL) + || parameterMap.containsKey(LeaderboardUrlSettings.PARAM_MANEUVER_DETAIL) + || parameterMap.containsKey(LeaderboardUrlSettings.PARAM_OVERALL_DETAIL) + || parameterMap.containsKey(LeaderboardUrlSettings.PARAM_SHOW_ADDED_SCORES) + || parameterMap + .containsKey(LeaderboardUrlSettings.PARAM_SHOW_OVERALL_COLUMN_WITH_NUMBER_OF_RACES_COMPLETED)) { + List maneuverDetails = getDetailTypeListFromParamValue(parameterMap + .get(LeaderboardUrlSettings.PARAM_MANEUVER_DETAIL)); + List raceDetails = getDetailTypeListFromParamValue(parameterMap + .get(LeaderboardUrlSettings.PARAM_RACE_DETAIL)); + List overallDetails = getDetailTypeListFromParamValue(parameterMap + .get(LeaderboardUrlSettings.PARAM_OVERALL_DETAIL)); + if (overallDetails.isEmpty()) { + overallDetails = Collections.singletonList(DetailType.REGATTA_RANK); + } + List legDetails = getDetailTypeListFromParamValue(parameterMap + .get(LeaderboardUrlSettings.PARAM_LEG_DETAIL)); + List namesOfRacesToShow = EventParamUtils.getStringListFromParamValue(parameterMap + .get(LeaderboardUrlSettings.PARAM_RACE_NAME)); + boolean showAddedScores = parameterMap.containsKey(LeaderboardUrlSettings.PARAM_SHOW_ADDED_SCORES) ? Boolean + .valueOf(parameterMap.get(LeaderboardUrlSettings.PARAM_SHOW_ADDED_SCORES).get(0)) : false; + boolean showOverallColumnWithNumberOfRacesSailedPerCompetitor = parameterMap + .containsKey(LeaderboardUrlSettings.PARAM_SHOW_OVERALL_COLUMN_WITH_NUMBER_OF_RACES_COMPLETED) ? Boolean + .valueOf(parameterMap.get( + LeaderboardUrlSettings.PARAM_SHOW_OVERALL_COLUMN_WITH_NUMBER_OF_RACES_COMPLETED).get(0)) + : false; + boolean autoExpandPreSelectedRace = parameterMap + .containsKey(LeaderboardUrlSettings.PARAM_AUTO_EXPAND_PRESELECTED_RACE) ? Boolean + .valueOf(parameterMap.get(LeaderboardUrlSettings.PARAM_AUTO_EXPAND_PRESELECTED_RACE).get(0)) + : (namesOfRacesToShow != null && namesOfRacesToShow.size() == 1); + boolean showCompetitorSailIdColumn = true; + boolean showCompetitorFullNameColumn = true; + if (parameterMap.containsKey(LeaderboardUrlSettings.PARAM_SHOW_COMPETITOR_NAME_COLUMNS)) { + String value = parameterMap.get(LeaderboardUrlSettings.PARAM_SHOW_COMPETITOR_NAME_COLUMNS).get(0); + if (value.equals(LeaderboardUrlSettings.COMPETITOR_NAME_COLUMN_FULL_NAME)) { + showCompetitorSailIdColumn = false; + } else if (value.equals(LeaderboardUrlSettings.COMPETITOR_NAME_COLUMN_SAIL_ID)) { + showCompetitorFullNameColumn = false; + } else if (value.trim().equals("")) { + showCompetitorFullNameColumn = false; + showCompetitorSailIdColumn = false; + } + } + result = new LeaderboardSettings(maneuverDetails, legDetails, raceDetails, overallDetails, + /* namesOfRaceColumnsToShow */null, namesOfRacesToShow, numberOfLastRacesToShow, autoExpandPreSelectedRace, + refreshIntervalMillis, /* sort by column */ + (namesOfRacesToShow != null && !namesOfRacesToShow.isEmpty()) ? namesOfRacesToShow.get(0) : null, + /* ascending */true, /* updateUponPlayStateChange */raceDetails.isEmpty() && legDetails.isEmpty(), + raceColumnSelectionStrategy, showAddedScores, + showOverallColumnWithNumberOfRacesSailedPerCompetitor, showCompetitorSailIdColumn, + showCompetitorFullNameColumn); + + } else { + final List overallDetails = Collections.singletonList(DetailType.REGATTA_RANK); + result = LeaderboardSettingsFactory.getInstance() + .createNewDefaultSettings(null, null, + /* overallDetails */overallDetails, null, + /* autoExpandFirstRace */false, refreshIntervalMillis, numberOfLastRacesToShow, + raceColumnSelectionStrategy); + } + return result; + } + + public static List getStringListFromParamValue(List list) { + List result = new ArrayList(); + if (list != null) { + result.addAll(list); + } + return result; + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/utils/WindowUtils.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/utils/WindowUtils.java new file mode 100644 index 00000000000..172318bb871 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/utils/WindowUtils.java @@ -0,0 +1,12 @@ +package com.sap.sailing.gwt.home.client.place.event.utils; + +import com.google.gwt.user.client.Window; + +public class WindowUtils { + + public static boolean isSmallWidth() { + int width = Window.getClientWidth(); + return width <= 720; + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/AbstractEventsView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/AbstractEventsView.java index 449a9289ac4..69168b8d0ab 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/AbstractEventsView.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/AbstractEventsView.java @@ -1,77 +1,16 @@ package com.sap.sailing.gwt.home.client.place.events; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import com.google.gwt.user.client.ui.Composite; -import com.sap.sailing.gwt.common.client.DateUtil; -import com.sap.sailing.gwt.ui.shared.EventBaseDTO; +import com.sap.sailing.gwt.ui.shared.eventlist.EventListViewDTO; public abstract class AbstractEventsView extends Composite implements EventsView { - private final Map> recentEventsByYearOrderedByEndDate; - private final List upcomingEvents; - - public AbstractEventsView() { - recentEventsByYearOrderedByEndDate = new HashMap>(); - upcomingEvents = new ArrayList(); - } + protected EventListViewDTO eventListView; @Override - public void setEvents(List events) { - for (EventBaseDTO event : events) { - if (event.startDate != null && event.endDate != null) { - if (DateUtil.isDayInPast(event.startDate) || event.isRunning()) { - // recent event or live event - int year = DateUtil.getYear(event.startDate); - List eventsOfYear = recentEventsByYearOrderedByEndDate.get(year); - if (eventsOfYear == null) { - eventsOfYear = new ArrayList(); - recentEventsByYearOrderedByEndDate.put(year, eventsOfYear); - } - eventsOfYear.add(event); - } else { - // upcoming event - upcomingEvents.add(event); - } - } - } - for (List eventsPerYear : recentEventsByYearOrderedByEndDate.values()) { - Collections.sort(eventsPerYear, EVENTS_BY_DESCENDING_DATE_COMPARATOR); - } - Collections.sort(upcomingEvents, EVENTS_BY_ASCENDING_DATE_COMPARATOR); + public void setEvents(EventListViewDTO eventListView) { + this.eventListView = eventListView; updateEventsUI(); } protected abstract void updateEventsUI(); - - /** - * Returns a map whose keys denote years and whose values are event lists ordered by descending - * {@link EventBaseDTO#endDate end date}. Note that the iteration order for the map entries is undefined - * and in particular is not enumerating the years in any well-defined order. - */ - public Map> getRecentEventsByYearOrderedByEndDate() { - return recentEventsByYearOrderedByEndDate; - } - - public List getUpcomingEvents() { - return upcomingEvents; - } - - public static Comparator EVENTS_BY_ASCENDING_DATE_COMPARATOR = new Comparator() { - @Override - public int compare(EventBaseDTO e1, EventBaseDTO e2) { - return e1.endDate.compareTo(e2.endDate); - } - }; - - public static Comparator EVENTS_BY_DESCENDING_DATE_COMPARATOR = new Comparator() { - @Override - public int compare(EventBaseDTO e1, EventBaseDTO e2) { - return e2.endDate.compareTo(e1.endDate); - } - }; } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/CollapseAnimation.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/CollapseAnimation.java new file mode 100644 index 00000000000..bb6510092f0 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/CollapseAnimation.java @@ -0,0 +1,66 @@ +package com.sap.sailing.gwt.home.client.place.events; + +import com.google.gwt.animation.client.Animation; +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.Style.Display; +import com.google.gwt.dom.client.Style.Overflow; +import com.google.gwt.dom.client.Style.Unit; + +public class CollapseAnimation extends Animation { + + private Element elementToAnimate; + + private boolean show = true; + private int effectiveHeight; + + public CollapseAnimation(Element elementToAnimate) { + this(elementToAnimate, true); + } + + public CollapseAnimation(Element elementToAnimate, int effectiveHeight) { + this(elementToAnimate, false); + this.effectiveHeight = effectiveHeight; + } + + public CollapseAnimation(Element elementToAnimate, boolean showInitial) { + this.elementToAnimate = elementToAnimate; + this.show = showInitial; + elementToAnimate.getStyle().setOverflow(Overflow.HIDDEN); + if(!showInitial) { + elementToAnimate.getStyle().setDisplay(Display.NONE); + } + } + + @Override + protected void onComplete() { + if(!show) { + elementToAnimate.getStyle().setDisplay(Display.NONE); + } else { + elementToAnimate.getStyle().clearHeight(); + } + } + + @Override + protected void onUpdate(double progress) { + if(!show) { + progress = 1.0 - progress; + } + elementToAnimate.getStyle().setHeight(effectiveHeight * progress, Unit.PX); + } + + public void animate(boolean show) { + if(show && effectiveHeight == 0) { + Scheduler.get().scheduleDeferred(new ScheduledCommand() { + @Override + public void execute() { + effectiveHeight = elementToAnimate.getScrollHeight(); + } + }); + } + elementToAnimate.getStyle().clearDisplay(); + this.show = show; + run(500); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/EventsActivity.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/EventsActivity.java index 158283d5195..6b90cd181a9 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/EventsActivity.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/EventsActivity.java @@ -1,14 +1,12 @@ package com.sap.sailing.gwt.home.client.place.events; -import java.util.List; - import com.google.gwt.activity.shared.AbstractActivity; import com.google.gwt.event.shared.EventBus; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.AcceptsOneWidget; import com.sap.sailing.gwt.home.client.shared.placeholder.Placeholder; -import com.sap.sailing.gwt.ui.shared.EventBaseDTO; +import com.sap.sailing.gwt.ui.shared.eventlist.EventListViewDTO; import com.sap.sse.gwt.client.mvp.ErrorView; public class EventsActivity extends AbstractActivity { @@ -24,20 +22,20 @@ public class EventsActivity extends AbstractActivity { @Override public void start(final AcceptsOneWidget panel, EventBus eventBus) { panel.setWidget(new Placeholder()); - - clientFactory.getSailingService().getPublicEventsOfAllSailingServers(new AsyncCallback>() { + + clientFactory.getHomeService().getEventListView(new AsyncCallback() { @Override - public void onSuccess(List events) { + public void onSuccess(EventListViewDTO eventListView) { final EventsView eventsView = clientFactory.createEventsView(); panel.setWidget(eventsView.asWidget()); Window.setTitle(place.getTitle()); - - eventsView.setEvents(events); + + eventsView.setEvents(eventListView); } - + @Override public void onFailure(Throwable caught) { - final ErrorView view = clientFactory.createErrorView("Error while loading the sailing server instances with service getPublicEventsOfAllSailingServers()", caught); + final ErrorView view = clientFactory.createErrorView("Error while loading the sailing server instances with service getEventListView()", caught); panel.setWidget(view.asWidget()); } }); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/EventsPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/EventsPlace.java index bacc260b41c..e78e98f3206 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/EventsPlace.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/EventsPlace.java @@ -12,7 +12,7 @@ public class EventsPlace extends Place { public static class Tokenizer implements PlaceTokenizer { @Override public String getToken(EventsPlace place) { - return null; + return ""; } @Override diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/EventsView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/EventsView.java index d8dd79952d6..5662fd6c1c9 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/EventsView.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/EventsView.java @@ -1,12 +1,8 @@ package com.sap.sailing.gwt.home.client.place.events; -import java.util.List; +import com.google.gwt.user.client.ui.IsWidget; +import com.sap.sailing.gwt.ui.shared.eventlist.EventListViewDTO; -import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.gwt.ui.shared.EventBaseDTO; - -public interface EventsView { - Widget asWidget(); - - void setEvents(List events); +public interface EventsView extends IsWidget { + void setEvents(EventListViewDTO eventListView); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/TabletAndDesktopEventsView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/TabletAndDesktopEventsView.java index f05e5d8410e..496d5003aa1 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/TabletAndDesktopEventsView.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/TabletAndDesktopEventsView.java @@ -1,60 +1,61 @@ package com.sap.sailing.gwt.home.client.place.events; import com.google.gwt.core.client.GWT; -import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.uibinder.client.UiHandler; -import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.gwt.common.client.SharedResources; +import com.sap.sailing.gwt.common.client.controls.tabbar.BreadcrumbPane; import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; import com.sap.sailing.gwt.home.client.place.events.recent.EventsOverviewRecent; import com.sap.sailing.gwt.home.client.place.events.upcoming.EventsOverviewUpcoming; +import com.sap.sailing.gwt.home.client.place.start.StartPlace; +import com.sap.sailing.gwt.ui.client.StringMessages; public class TabletAndDesktopEventsView extends AbstractEventsView { private static EventsPageViewUiBinder uiBinder = GWT.create(EventsPageViewUiBinder.class); - private final SharedResources homeRes = GWT.create(SharedResources.class); - interface EventsPageViewUiBinder extends UiBinder { } + @UiField StringMessages i18n; @UiField(provided=true) EventsOverviewRecent recentEventsWidget; @UiField(provided=true) EventsOverviewUpcoming upcomingEventsWidget; - @UiField Anchor recentEventsLink; - @UiField Anchor upcomingEventsLink; + @UiField BreadcrumbPane breadcrumbs; + + private final HomePlacesNavigator navigator; public TabletAndDesktopEventsView(HomePlacesNavigator navigator) { super(); + this.navigator = navigator; recentEventsWidget = new EventsOverviewRecent(navigator); upcomingEventsWidget = new EventsOverviewUpcoming(navigator); - upcomingEventsWidget.setVisible(false); initWidget(uiBinder.createAndBindUi(this)); - } - - @UiHandler("recentEventsLink") - void recentsEventsClicked(ClickEvent event) { - recentEventsWidget.setVisible(true); - upcomingEventsWidget.setVisible(false); - recentEventsLink.getElement().addClassName(homeRes.mainCss().navbar_buttonactive()); - upcomingEventsLink.getElement().removeClassName(homeRes.mainCss().navbar_buttonactive()); + initBreadCrumbs(); } - @UiHandler("upcomingEventsLink") - void upcomingEventsClicked(ClickEvent event) { - recentEventsWidget.setVisible(false); - upcomingEventsWidget.setVisible(true); - - upcomingEventsLink.getElement().addClassName(homeRes.mainCss().navbar_buttonactive()); - recentEventsLink.getElement().removeClassName(homeRes.mainCss().navbar_buttonactive()); + private void initBreadCrumbs() { + final PlaceNavigation homeNavigation = navigator.getHomeNavigation(); + breadcrumbs.addBreadcrumbItem(i18n.home(), homeNavigation.getTargetUrl(), new Runnable() { + @Override + public void run() { + navigator.goToPlace(homeNavigation); + } + }); + final PlaceNavigation eventsNavigation = navigator.getEventsNavigation(); + breadcrumbs.addBreadcrumbItem(i18n.events(), eventsNavigation.getTargetUrl(), new Runnable() { + @Override + public void run() { + navigator.goToPlace(eventsNavigation); + } + }); } - + @Override protected void updateEventsUI() { - recentEventsWidget.updateEvents(getRecentEventsByYearOrderedByEndDate()); - upcomingEventsWidget.updateEvents(getUpcomingEvents()); + recentEventsWidget.updateEvents(eventListView.getRecentEvents()); + upcomingEventsWidget.updateEvents(eventListView.getUpcomingEvents()); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/TabletAndDesktopEventsView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/TabletAndDesktopEventsView.ui.xml index 56fd43568e8..efb3f24bf7b 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/TabletAndDesktopEventsView.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/TabletAndDesktopEventsView.ui.xml @@ -2,24 +2,26 @@ - - - - .events-overview-navigation { - font-size: 1rem; - } - - -
-
-
- - -
-
-
- - -
+ xmlns:g="urn:import:com.google.gwt.user.client.ui" + xmlns:c="urn:import:com.sap.sailing.gwt.common.client.controls.tabbar"> + + + + .events-overview-navigation { + font-size: 1rem; + } + .breadcrumb { + font-size: 1rem; + /* @alternate */ font-size: 0.866666666666667em; + font-weight: 600; + padding: 0.666666666666667em 0; + } + + +
+ + + +
+
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecent.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecent.gss index 635f294ebfe..c8a04ca2a75 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecent.gss +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecent.gss @@ -1,91 +1,60 @@ -.eventteasercontainer { - font-size: 15px; - /* @alternate */ font-size: 1rem; - text-align: center; - width: 100%; - height: 24em; -} -.eventteaser { - font-size: 15px; - /* @alternate */ font-size: 1rem; - display: inline-block; - margin-bottom: 3em; - text-align: left; - max-width: 100%; -} -.eventteaser:hover { - text-decoration: none; -} -.eventteaser:hover .eventteaser_name { - text-decoration: underline; -} -.eventteaser:hover .eventteaser_image { - opacity: 0.9; - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)"; - filter: alpha(opacity=90); -} -.eventteaser_image { - position: relative; - display: inline-block; - max-width: 100%; -} -.eventteaser_series { - position: absolute; - bottom: 0; - right: 0; -} -.eventteaser_name { - font-size: 1.466666666666667em; - font-weight: bold; - color: #008fcc; - margin-top: 0.333333333333333em; -} -.eventteaser_location { - color: #222; -} +/** + * The overview over recent events + */ .eventsoverviewnavigation { - font-size: 15px; - /* @alternate */ font-size: 1rem; + font-size: 1rem; } .eventsoverviewnavigation .gridalternator { overflow: visible; } +.accordion { + font-size: 1rem; +} +.accordion_trigger { + font-size: inherit; +} +.accordion_content { + font-size: inherit; +} .eventsoverviewrecent { - font-size: 15px; - /* @alternate */ font-size: 1rem; + font-size: 1rem; + padding-top: 2em; } .eventsoverviewrecent_year { - border-bottom: 1px solid #ccc; - transiton: opacity 0.1s; +/* border-bottom: 1px solid #ebebeb; */ + -webkit-transition: opacity 0.1s; + -moz-transition: opacity 0.1s; + transition: opacity 0.1s; + border: 1px solid #dedede; + border-radius: .333333333333333em; + margin-bottom:10px; + margin-top: 20px; + } -.eventsoverviewrecent_year:nth-child(even) { - background: #f8f8f8; -} -.eventsoverviewrecent_year:nth-child(even) .eventsoverviewrecent_year_header:hover, -.eventsoverviewrecent_year:nth-child(even) .eventsoverviewrecent_year_header:focus { - background-color: #f3f3f3; -} -.eventsoverviewrecent_yearcollapsed .eventsoverviewrecent_year_header_info_arrow_image { +.eventsoverviewrecent_year.accordioncollapsed .eventsoverviewrecent_year_header_info_arrow_image { -webkit-transform: rotate(0deg); - -moz-transform: rotate(0deg); - -o-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + transform: rotate(0deg); } .eventsoverviewrecent_year_header { padding: 0.666666666666667em; cursor: pointer; + background-color: #f2f2f2; + border-bottom: 1px solid #dedede; + } .eventsoverviewrecent_year_header:hover, .eventsoverviewrecent_year_header:focus { - background-color: #fcfcfc; +/* background-color: #ebebeb; */ } .eventsoverviewrecent_year_header:hover .eventsoverviewrecent_year_header_title, .eventsoverviewrecent_year_header:focus .eventsoverviewrecent_year_header_title { - text-decoration: underline; +/* text-decoration: underline; */ } .eventsoverviewrecent_year_header_title { margin-bottom: 0; + line-height: 1.944444444444444em; } .eventsoverviewrecent_year_header_info { float: right; @@ -94,15 +63,18 @@ padding: 0.466666666666667em 1.133333333333333em; } .eventsoverviewrecent_year_header_info_arrow_image { + width: 1.333333333333333em; + vertical-align: middle; -webkit-transform: rotate(180deg); - -moz-transform: rotate(180deg); - -o-transform: rotate(180deg); - -ms-transform: rotate(180deg); - transform: rotate(180deg); - transiton: transform 0.4s; + -moz-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); + -webkit-transition: -webkit-transform 0.4s; + -moz-transition: -moz-transform 0.4s; + transition: transform 0.4s; } .eventsoverviewrecent_year_header_info_item { - border-right: 1px solid #ccc; + border-right: 1px solid #ebebeb; padding: 0.466666666666667em 1.133333333333333em; } .eventsoverviewrecent_year_header_info_item_value { @@ -114,3 +86,11 @@ margin-top: 0.666666666666667em; padding-bottom: 1.333333333333333em; } +.eventsoverviewrecent_year_content_floattoinlineblock { + font-size: 0; +} +.eventsoverviewrecent_year_content_floattoinlineblock_child { + float: none; + vertical-align: top; + display: inline-block; +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecent.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecent.java index 9d912e5d3ee..bfdca619a4f 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecent.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecent.java @@ -1,22 +1,15 @@ package com.sap.sailing.gwt.home.client.place.events.recent; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Map.Entry; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.HTMLPanel; +import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; -import com.sap.sailing.gwt.ui.shared.EventBaseDTO; +import com.sap.sailing.gwt.ui.shared.eventlist.EventListYearDTO; public class EventsOverviewRecent extends Composite { @@ -27,49 +20,25 @@ public class EventsOverviewRecent extends Composite { private final HomePlacesNavigator navigator; - @UiField HTMLPanel recentEventsPerYearPanel; - - private final Map recentEventsComposites; + @UiField FlowPanel year; public EventsOverviewRecent(HomePlacesNavigator navigator) { this.navigator = navigator; - recentEventsComposites = new HashMap(); EventsOverviewRecentResources.INSTANCE.css().ensureInjected(); initWidget(uiBinder.createAndBindUi(this)); } - public void updateEvents(Map> recentEventsByYearOrderedByEndDate) { + public void updateEvents(List years) { // remove old widgets - recentEventsPerYearPanel.clear(); - recentEventsComposites.clear(); - // recent events of this year - LinkedHashMap> recentEventsOrderedDescendingByYearOrderedDescendingByEndDate = - sortEventsDescendingByYear(recentEventsByYearOrderedByEndDate); + year.clear(); + boolean oneYearIsExpanded = false; - for (Entry> e : recentEventsOrderedDescendingByYearOrderedDescendingByEndDate.entrySet()) { - int currentYear = e.getKey(); - EventsOverviewRecentYear recentEventsOfOneYear = new EventsOverviewRecentYear(currentYear, e.getValue(), navigator); - recentEventsPerYearPanel.add(recentEventsOfOneYear); - recentEventsComposites.put(currentYear, recentEventsOfOneYear); - if (oneYearIsExpanded == true) { - recentEventsOfOneYear.hideContent(); - } else { - recentEventsOfOneYear.showContent(); - oneYearIsExpanded = true; - } + for (EventListYearDTO yearDTO : years) { + EventsOverviewRecentYear recentEventsOfOneYear = new EventsOverviewRecentYear(yearDTO, navigator, !oneYearIsExpanded); + year.add(recentEventsOfOneYear); + + oneYearIsExpanded = true; } } - - private LinkedHashMap> sortEventsDescendingByYear( - Map> recentEventsByYearOrderedByEndDate) { - LinkedHashMap> result = new LinkedHashMap<>(); - List yearKeysInDescendingOrder = new ArrayList<>(recentEventsByYearOrderedByEndDate.keySet()); - Collections.sort(yearKeysInDescendingOrder); - for (ListIterator i=yearKeysInDescendingOrder.listIterator(yearKeysInDescendingOrder.size()); i.hasPrevious(); ) { - Integer year = i.previous(); - result.put(year, recentEventsByYearOrderedByEndDate.get(year)); - } - return result; - } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecent.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecent.ui.xml index 7bf133beddc..52cff6db9ff 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecent.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecent.ui.xml @@ -2,13 +2,9 @@ - - + + - - -
- -
-
-
+ + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecentResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecentResources.java index feb782f23d9..b48dae53416 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecentResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecentResources.java @@ -11,24 +11,23 @@ public interface EventsOverviewRecentResources extends ClientBundle { LocalCss css(); public interface LocalCss extends CssResource { - String eventteasercontainer(); - String eventteaser(); - String eventteaser_name(); - String eventteaser_image(); - String eventteaser_series(); - String eventteaser_location(); String eventsoverviewnavigation(); String gridalternator(); + String accordion(); + String accordion_trigger(); + String accordion_content(); String eventsoverviewrecent(); String eventsoverviewrecent_year(); - String eventsoverviewrecent_year_header(); - String eventsoverviewrecent_yearcollapsed(); + String accordioncollapsed(); String eventsoverviewrecent_year_header_info_arrow_image(); + String eventsoverviewrecent_year_header(); String eventsoverviewrecent_year_header_title(); String eventsoverviewrecent_year_header_info(); String eventsoverviewrecent_year_header_info_arrow(); String eventsoverviewrecent_year_header_info_item(); String eventsoverviewrecent_year_header_info_item_value(); String eventsoverviewrecent_year_content(); + String eventsoverviewrecent_year_content_floattoinlineblock(); + String eventsoverviewrecent_year_content_floattoinlineblock_child(); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecentYear.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecentYear.java index 436c9bb00a7..451514b2bf5 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecentYear.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecentYear.java @@ -4,17 +4,23 @@ import java.util.List; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.DivElement; +import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.SpanElement; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; -import com.sap.sailing.gwt.home.client.shared.recentevent.RecentEvent; -import com.sap.sailing.gwt.ui.shared.EventBaseDTO; +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.place.event.EventDefaultPlace; +import com.sap.sailing.gwt.home.client.place.events.CollapseAnimation; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sailing.gwt.ui.shared.eventlist.EventListEventDTO; +import com.sap.sailing.gwt.ui.shared.eventlist.EventListYearDTO; public class EventsOverviewRecentYear extends Composite { @@ -25,34 +31,59 @@ public class EventsOverviewRecentYear extends Composite { @UiField SpanElement year; @UiField SpanElement eventsCount; -// @UiField SpanElement countriesCount; -// @UiField SpanElement sailorsCount; -// @UiField SpanElement trackedRacesCount; - @UiField DivElement recentEventsTeaserPanel; - @UiField HTMLPanel contentDiv; + @UiField SpanElement countriesCount; + @UiField SpanElement sailorsCount; + @UiField SpanElement trackedRacesCount; + @UiField Element countriesContainer; + @UiField Element sailorsContainer; + @UiField Element trackedRacesContainer; + @UiField FlowPanel recentEventsTeaserPanel; + @UiField DivElement contentDiv; @UiField HTMLPanel headerDiv; + @UiField StringMessages i18n; private boolean isContentVisible; - public EventsOverviewRecentYear(Integer year, List events, HomePlacesNavigator navigator) { + private final CollapseAnimation animation; + + public EventsOverviewRecentYear(EventListYearDTO yearDTO, HomePlacesNavigator navigator, boolean showInitial) { + List events = yearDTO.getEvents(); + EventsOverviewRecentResources.INSTANCE.css().ensureInjected(); initWidget(uiBinder.createAndBindUi(this)); - this.year.setInnerText(String.valueOf(year)); - this.eventsCount.setInnerText(String.valueOf(events.size())); -// this.countriesCount.setInnerText("tbd."); -// this.sailorsCount.setInnerText("tbd."); -// this.trackedRacesCount.setInnerText("tbd."); - for (EventBaseDTO eventDTO : events) { - RecentEvent recentEvent = new RecentEvent(navigator, eventDTO); - recentEventsTeaserPanel.appendChild(recentEvent.getElement()); + + this.year.setInnerText(String.valueOf(yearDTO.getYear())); + this.eventsCount.setInnerText(i18n.eventsCount(events.size())); + if(yearDTO.getSailorCount() > 0) { + sailorsCount.setInnerText(i18n.competitorsCount(yearDTO.getSailorCount())); + } else { + sailorsContainer.removeFromParent(); + } + if(yearDTO.getCountryCount() > 0) { + countriesCount.setInnerText(i18n.countriesCount(yearDTO.getCountryCount())); + } else { + countriesContainer.removeFromParent(); + } + if(yearDTO.getTrackedRacesCount() > 0) { + trackedRacesCount.setInnerText(i18n.trackedRacesCount(yearDTO.getTrackedRacesCount())); + } else { + trackedRacesContainer.removeFromParent(); + } + for (EventListEventDTO eventDTO : events) { + PlaceNavigation eventNavigation = navigator.getEventNavigation(eventDTO.getId().toString(), eventDTO.getBaseURL(), eventDTO.isOnRemoteServer()); + RecentEventTeaser recentEvent = new RecentEventTeaser(eventNavigation, eventDTO, eventDTO.getState().getListStateMarker()); + recentEventsTeaserPanel.add(recentEvent); } - isContentVisible = true; headerDiv.addDomHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { onHeaderCicked(); } }, ClickEvent.getType()); + + isContentVisible = showInitial; + animation = new CollapseAnimation(contentDiv, showInitial); + updateAccordionState(); } private void onHeaderCicked() { @@ -60,22 +91,16 @@ public class EventsOverviewRecentYear extends Composite { updateContentVisibility(); } - public void hideContent() { - isContentVisible = false; - updateContentVisibility(); + private void updateContentVisibility() { + animation.animate(isContentVisible); + updateAccordionState(); } - public void showContent() { - isContentVisible = true; - updateContentVisibility(); - } - - private void updateContentVisibility() { - contentDiv.setVisible(isContentVisible); + private void updateAccordionState() { if(isContentVisible) { - headerDiv.getElement().removeClassName(EventsOverviewRecentResources.INSTANCE.css().eventsoverviewrecent_yearcollapsed()); + getElement().removeClassName(EventsOverviewRecentResources.INSTANCE.css().accordioncollapsed()); } else { - headerDiv.getElement().addClassName(EventsOverviewRecentResources.INSTANCE.css().eventsoverviewrecent_yearcollapsed()); + getElement().addClassName(EventsOverviewRecentResources.INSTANCE.css().accordioncollapsed()); } } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecentYear.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecentYear.ui.xml index 22c87b63a82..bda511001da 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecentYear.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/EventsOverviewRecentYear.ui.xml @@ -1,46 +1,63 @@ - - - - -
- -
-
-

+ xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"> + + + + + .quickFix { + padding: 0px 10px 10px 10px; + + } + + + +
+
+

+ +

+
+
+ + + + + + + + +
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
+
+ + + + +
-
- - - - - - -
-
-
-
-
-
-
- -
-
-
-
-
- + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/RecentEventTeaser.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/RecentEventTeaser.java new file mode 100644 index 00000000000..49ea90cea4e --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/RecentEventTeaser.java @@ -0,0 +1,27 @@ +package com.sap.sailing.gwt.home.client.place.events.recent; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.shared.event.EventTeaser; +import com.sap.sailing.gwt.ui.shared.general.EventMetadataDTO; +import com.sap.sailing.gwt.ui.shared.general.LabelType; + +public class RecentEventTeaser extends Composite { + + private static RecentEventTeaserUiBinder uiBinder = GWT.create(RecentEventTeaserUiBinder.class); + + interface RecentEventTeaserUiBinder extends UiBinder { + } + + @UiField(provided = true) EventTeaser eventTeaser; + + public RecentEventTeaser(final PlaceNavigation placeNavigation, final EventMetadataDTO event, LabelType labelType) { + eventTeaser = new EventTeaser(placeNavigation, event, labelType); + initWidget(uiBinder.createAndBindUi(this)); + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/RecentEventTeaser.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/RecentEventTeaser.ui.xml new file mode 100644 index 00000000000..dd1953b290d --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/recent/RecentEventTeaser.ui.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.css deleted file mode 100644 index 5386bc11ee0..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.css +++ /dev/null @@ -1,62 +0,0 @@ -/** - * The overview over upcoming events - */ -.eventsoverviewupcoming { - font-size: 16px; - font-size: 1rem; - padding-bottom: 4.6875em; -} -.eventsoverviewupcoming_teaser { - font-size: 1.125em; - font-weight: bold; - color: #008fcc; - margin-top: 1.6875em; -} -.eventslist { - font-size: 16px; - font-size: 1rem; -} -.eventslist_header { - font-size: 1em; - font-weight: 600; - text-transform: uppercase; - color: #008fcc; - background: #f2f2f2; - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; -} -.eventslist_header_item { - padding-top: 1.875em; - padding-bottom: 1.75em; -} -.eventslist_header_itemseries { - text-align: right; -} -.eventslist_event { - background: #fff; - border-bottom: 1px solid #ddd; - -webkit-transition: 0.2s background; - -moz-transition: 0.2s background; - -o-transition: 0.2s background; - -ms-transition: 0.2s background; - transition: 0.2s background; -} -.eventslist_event:hover, -.eventslist_event:focus { - background: #fafafa; -} -.eventslist_event:hover .eventslist_event_itemname, -.eventslist_event:focus .eventslist_event_itemname { - text-decoration: underline; -} -.eventslist_event_link { - color: #333; - padding-top: 1.875em; - padding-bottom: 1.75em; -} -.eventslist_event_item { - font-size: 1.125em; -} -.eventslist_event_itemseries { - text-align: right; -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.gss new file mode 100644 index 00000000000..992db7c51f5 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.gss @@ -0,0 +1,151 @@ +/** + * The overview over upcoming events + */ +.accordion { + font-size: 1rem; +} +.accordion_trigger { + font-size: inherit; +} +.accordion_content { + font-size: inherit; +} +.eventsoverviewupcoming { + font-size: 1rem; + margin-top: 1.333333333333333em; + border: 1px solid #dedede; + border-radius: 0.333333333333333em; +} +.eventsoverviewupcoming.accordioncollapsed .eventsoverviewupcoming_header_info_arrow_image { + -webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + transform: rotate(0deg); +} +.eventsoverviewupcoming.accordioncollapsed .eventsoverviewupcoming_header { + border-bottom: none; +} +.eventsoverviewupcoming_header { + cursor: pointer; + border-bottom: 1px solid #dedede; + padding: 0.666666666666667em 1em; + background: #f2f2f2; + color: #333; +} +.eventsoverviewupcoming_header_icon { + width: 2em; + margin-top: -0.266666666666667em; + vertical-align: middle; +} +.eventsoverviewupcoming_header_title { + margin: 0; + padding-top: 0.266666666666667em; + display: inline-block; + margin-left: 0.666666666666667em; +} +.eventsoverviewupcoming_header a { + color: #333; + text-decoration: none; +} +.eventsoverviewupcoming_header_ticker { + margin-left: 0.333333333333333em; + white-space: nowrap; + overflow: hidden; + vertical-align: middle; + text-overflow: ellipsis; + width: 66%; + display: inline-block; +} +@media (min-width: 61em) { + .eventsoverviewupcoming_header_ticker { + width: 77%; + } +} +.eventsoverviewupcoming_header_tickerhide { + display: none; +} +.eventsoverviewupcoming_header_info { + float: right; + white-space: nowrap; +} +.eventsoverviewupcoming_header_info_arrow { + padding: 0.466666666666667em 1.133333333333333em; +} +.eventsoverviewupcoming_header_info_arrow_image { + width: 1.333333333333333em; + min-width: 1.333333333333333em; + vertical-align: middle; + -webkit-transform: rotate(180deg); + -moz-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); + -webkit-transition: -webkit-transform 0.4s; + -moz-transition: -moz-transform 0.4s; + transition: transform 0.4s; +} +.eventsoverviewupcoming_header_info_item { + border-right: 1px solid #ebebeb; + padding: 0.466666666666667em 1.133333333333333em; +} +.eventsoverviewupcoming_header_info_item_value { + font-weight: 700; + color: #008fcc; + margin-right: 0.533333333333333em; +} +.eventsoverviewupcoming_content { + padding-bottom: 0; + border-bottom: 0; + background: none; +} +.eventsoverviewupcoming_content_event { + height: 3.333333333333333em; + padding-left: 1em; + padding-right: 1em; + line-height: 3.333333333333333em; + border-bottom: 1px solid #dedede; +} +.eventsoverviewupcoming_content_event:last-child { + border-bottom: none; +} +.eventsoverviewupcoming_content_event_name { + font-weight: 700; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + width: 60%; +} +@media (min-width: 800px) { + .eventsoverviewupcoming_content_event_name { + width: 41.66666%; + } +} +.eventsoverviewupcoming_content_event_name:hover { + text-decoration: underline; +} +.eventsoverviewupcoming_content_event_location { + white-space: nowrap; + color: #333; + text-align: right; + width: 40%; +} +@media (min-width: 800px) { + .eventsoverviewupcoming_content_event_location { + width: 33.33333%; + text-align: left; + } +} +.eventsoverviewupcoming_content_event_countdown { + color: #333; + white-space: nowrap; + text-align: right; + display: none; +} +@media (min-width: 800px) { + .eventsoverviewupcoming_content_event_countdown { + display: block; + } +} +.eventsoverviewupcoming_content_event_countdown img { + vertical-align: middle; + width: 0.533333333333333em; +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.java index 69b8e92c738..9e4c9ae9691 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.java @@ -4,17 +4,24 @@ import java.util.ArrayList; import java.util.List; import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.SpanElement; +import com.google.gwt.dom.client.Style.Display; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; -import com.sap.sailing.gwt.ui.shared.EventBaseDTO; +import com.sap.sailing.gwt.home.client.place.events.CollapseAnimation; +import com.sap.sailing.gwt.home.client.shared.EventDatesFormatterUtil; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sailing.gwt.ui.shared.eventlist.EventListEventDTO; public class EventsOverviewUpcoming extends Composite { - - @UiField HTMLPanel eventsPlaceholder; interface EventsOverviewUiBinder extends UiBinder { } @@ -23,23 +30,95 @@ public class EventsOverviewUpcoming extends Composite { private final HomePlacesNavigator navigator; - private final List upcomingEventComposites; + private final List tickerStrings; + + @UiField HTMLPanel header; + @UiField FlowPanel eventsPlaceholder; + @UiField SpanElement eventsCount; + @UiField SpanElement ticker; + @UiField SpanElement colon; + + @UiField StringMessages i18n; + + private boolean isContentVisible = true; + + private int currentTickerOffset; + + private final CollapseAnimation eventsAnimation; + + private Timer tickerTimer = new Timer() { + @Override + public void run() { + nextTicker(false); + } + }; + + private final CollapseAnimation tickerAnimation; public EventsOverviewUpcoming(HomePlacesNavigator navigator) { this.navigator = navigator; - upcomingEventComposites = new ArrayList(); + tickerStrings = new ArrayList<>(); EventsOverviewUpcomingResources.INSTANCE.css().ensureInjected(); initWidget(uiBinder.createAndBindUi(this)); + + eventsAnimation = new CollapseAnimation(eventsPlaceholder.getElement()); + tickerAnimation = new CollapseAnimation(ticker); + + header.addDomHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + onHeaderCicked(); + } + }, ClickEvent.getType()); + } + + public void updateEvents(ArrayList arrayList) { + setVisible(arrayList.size() > 0); + eventsPlaceholder.clear(); + tickerStrings.clear(); + for (EventListEventDTO event : arrayList) { + EventsOverviewUpcomingEvent upcomingEvent = new EventsOverviewUpcomingEvent(event, navigator); + tickerStrings.add(event.getDisplayName() + ", " + event.getVenue() + ", " + + EventDatesFormatterUtil.formatDateRangeWithoutYear(event.getStartDate(), event.getEndDate())); + eventsPlaceholder.getElement().appendChild(upcomingEvent.getElement()); + } + eventsCount.setInnerText(i18n.eventsCount(arrayList.size())); } - public void updateEvents(List events) { - eventsPlaceholder.clear(); - upcomingEventComposites.clear(); - for (EventBaseDTO event : events) { - UpcomingEvent upcomingEvent = new UpcomingEvent(event, navigator); - upcomingEventComposites.add(upcomingEvent); - eventsPlaceholder.getElement().appendChild(upcomingEvent.getElement()); + private void onHeaderCicked() { + isContentVisible = !isContentVisible; + updateContentVisibility(); + } + + private void updateContentVisibility() { + eventsAnimation.animate(isContentVisible); + if(isContentVisible) { + colon.getStyle().setDisplay(Display.NONE); + getElement().removeClassName(EventsOverviewUpcomingResources.INSTANCE.css().accordioncollapsed()); + ticker.setInnerText(""); + ticker.getStyle().setDisplay(Display.NONE); + tickerTimer.cancel(); + tickerAnimation.cancel(); + } else { + colon.getStyle().clearDisplay(); + getElement().addClassName(EventsOverviewUpcomingResources.INSTANCE.css().accordioncollapsed()); + if(tickerStrings.isEmpty()) { + ticker.setInnerText(""); + ticker.getStyle().setDisplay(Display.NONE); + } else { + nextTicker(true); + } } } + + protected void nextTicker(boolean restart) { + currentTickerOffset = restart ? 0 : (currentTickerOffset + 1) % tickerStrings.size(); + ticker.setInnerText(tickerStrings.get(currentTickerOffset)); + ticker.getStyle().clearDisplay(); + tickerAnimation.animate(true); + if(tickerStrings.size() > 1) { + tickerTimer.schedule(3000); + } + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.ui.xml index a3170d53a7a..78f99b4f9ac 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.ui.xml @@ -2,36 +2,46 @@ - - + + + - - - -
-
-
-
-

-
-
-
-
-
-
-
-
-
-
- - - -
-
-
-
-
-
-
-
+ + + +
+
+ + + +

+ :

+ + +
+ +
+ + + + + +
+
+ +
+
+
+ +
+
+
+ +
+
+ + + +
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/UpcomingEvent.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcomingEvent.java similarity index 53% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/UpcomingEvent.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcomingEvent.java index 6cd65818706..7038c4b81aa 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/UpcomingEvent.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcomingEvent.java @@ -1,6 +1,7 @@ package com.sap.sailing.gwt.home.client.place.events.upcoming; import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.SpanElement; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.uibinder.client.UiBinder; @@ -9,45 +10,45 @@ import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.common.client.DateUtil; import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; import com.sap.sailing.gwt.home.client.app.PlaceNavigation; -import com.sap.sailing.gwt.home.client.place.event.EventPlace; +import com.sap.sailing.gwt.home.client.place.event.EventDefaultPlace; import com.sap.sailing.gwt.home.client.shared.EventDatesFormatterUtil; -import com.sap.sailing.gwt.ui.shared.EventBaseDTO; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sailing.gwt.ui.shared.eventlist.EventListEventDTO; -public class UpcomingEvent extends Composite { +public class EventsOverviewUpcomingEvent extends Composite { - @UiField SpanElement eventName; - @UiField SpanElement seriesName; + @UiField DivElement eventName; @UiField SpanElement venueName; @UiField SpanElement eventStartDate; @UiField Anchor eventOverviewLink; + @UiField DivElement days; - private final HomePlacesNavigator navigator; - private final PlaceNavigation eventNavigation; + private final PlaceNavigation eventNavigation; - interface UpcomingEventUiBinder extends UiBinder { + interface UpcomingEventUiBinder extends UiBinder { } private static UpcomingEventUiBinder uiBinder = GWT.create(UpcomingEventUiBinder.class); - public UpcomingEvent(final EventBaseDTO event, final HomePlacesNavigator navigator) { - this.navigator = navigator; - + public EventsOverviewUpcomingEvent(final EventListEventDTO event, final HomePlacesNavigator navigator) { EventsOverviewUpcomingResources.INSTANCE.css().ensureInjected(); initWidget(uiBinder.createAndBindUi(this)); - eventNavigation = navigator.getEventNavigation(event.id.toString(), event.getBaseURL(), event.isOnRemoteServer()); + eventNavigation = navigator.getEventNavigation(event.getId().toString(), event.getBaseURL(), event.isOnRemoteServer()); eventOverviewLink.setHref(eventNavigation.getTargetUrl()); - eventName.setInnerText(event.getName()); - venueName.setInnerText(event.venue.getName()); - eventStartDate.setInnerText(EventDatesFormatterUtil.formatDateRangeWithoutYear(event.startDate, event.endDate)); + eventName.setInnerText(event.getDisplayName()); + venueName.setInnerText(event.getVenue()); + eventStartDate.setInnerText(EventDatesFormatterUtil.formatDateRangeWithoutYear(event.getStartDate(), event.getEndDate())); + days.setInnerText(StringMessages.INSTANCE.upcommingEventStartsInDays(DateUtil.daysFromNow(event.getStartDate()))); } @UiHandler("eventOverviewLink") public void goToEventOverview(ClickEvent e) { - navigator.goToPlace(eventNavigation); + eventNavigation.goToPlace(); e.preventDefault(); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcomingEvent.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcomingEvent.ui.xml new file mode 100644 index 00000000000..b70d82b55d4 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcomingEvent.ui.xml @@ -0,0 +1,18 @@ + + + + + + + +
+
+ , + +
+
starts in days
+ + + diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcomingResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcomingResources.java index 531f22ca0e9..824c4b236e0 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcomingResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcomingResources.java @@ -7,20 +7,29 @@ import com.google.gwt.resources.client.CssResource; public interface EventsOverviewUpcomingResources extends ClientBundle { public static final EventsOverviewUpcomingResources INSTANCE = GWT.create(EventsOverviewUpcomingResources.class); - @Source("com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.css") + @Source("com/sap/sailing/gwt/home/client/place/events/upcoming/EventsOverviewUpcoming.gss") LocalCss css(); public interface LocalCss extends CssResource { + String accordion(); + String accordion_trigger(); + String accordion_content(); String eventsoverviewupcoming(); - String eventsoverviewupcoming_teaser(); - String eventslist(); - String eventslist_header(); - String eventslist_header_item(); - String eventslist_header_itemseries(); - String eventslist_event(); - String eventslist_event_itemname(); - String eventslist_event_link(); - String eventslist_event_item(); - String eventslist_event_itemseries(); + String accordioncollapsed(); + String eventsoverviewupcoming_header_info_arrow_image(); + String eventsoverviewupcoming_header(); + String eventsoverviewupcoming_header_icon(); + String eventsoverviewupcoming_header_title(); + String eventsoverviewupcoming_header_ticker(); + String eventsoverviewupcoming_header_tickerhide(); + String eventsoverviewupcoming_header_info(); + String eventsoverviewupcoming_header_info_arrow(); + String eventsoverviewupcoming_header_info_item(); + String eventsoverviewupcoming_header_info_item_value(); + String eventsoverviewupcoming_content(); + String eventsoverviewupcoming_content_event(); + String eventsoverviewupcoming_content_event_name(); + String eventsoverviewupcoming_content_event_location(); + String eventsoverviewupcoming_content_event_countdown(); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/UpcomingEvent.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/UpcomingEvent.ui.xml deleted file mode 100644 index 8af6f136799..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/events/upcoming/UpcomingEvent.ui.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - -
-
-
-
-
-
-
-
-
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/AbstractSeriesActivity.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/AbstractSeriesActivity.java new file mode 100644 index 00000000000..819192a3a71 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/AbstractSeriesActivity.java @@ -0,0 +1,110 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries; + +import java.util.UUID; + +import com.google.gwt.activity.shared.AbstractActivity; +import com.google.gwt.core.shared.GWT; +import com.google.gwt.place.shared.Place; +import com.google.gwt.safehtml.shared.SafeUri; +import com.google.gwt.safehtml.shared.UriUtils; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.app.ApplicationHistoryMapper; +import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.place.event.EventDefaultPlace; +import com.sap.sailing.gwt.home.client.place.event.legacy.SeriesClientFactory; +import com.sap.sailing.gwt.home.client.place.events.EventsPlace; +import com.sap.sailing.gwt.home.client.place.start.StartPlace; +import com.sap.sailing.gwt.ui.shared.media.MediaDTO; +import com.sap.sse.gwt.client.mvp.ErrorView; + +public abstract class AbstractSeriesActivity extends AbstractActivity implements SeriesView.Presenter { + + protected final PLACE currentPlace; + protected final SeriesContext ctx; + protected final SeriesClientFactory clientFactory; + + protected final HomePlacesNavigator homePlacesNavigator; + + private static final ApplicationHistoryMapper historyMapper = GWT.create(ApplicationHistoryMapper.class); + + public AbstractSeriesActivity(PLACE place, SeriesClientFactory clientFactory, HomePlacesNavigator homePlacesNavigator) { + this.currentPlace = place; + this.ctx = new SeriesContext(place.getCtx()); + this.clientFactory = clientFactory; + this.homePlacesNavigator = homePlacesNavigator; + } + + @Override + public SeriesContext getCtx() { + return ctx; + } + + @Override + public void handleTabPlaceSelection(TabView selectedActivity) { + Place tabPlaceToGo = selectedActivity.placeToFire(); + clientFactory.getPlaceController().goTo(tabPlaceToGo); + } + + public void navigateTo(Place place) { + clientFactory.getPlaceController().goTo(place); + } + + @Override + public SafeUri getUrl(AbstractSeriesPlace place) { + String token = historyMapper.getToken(place); + return UriUtils.fromString("#" + token); + } + + @Override + public PlaceNavigation getHomeNavigation() { + return homePlacesNavigator.getHomeNavigation(); + } + + @Override + public PlaceNavigation getEventsNavigation() { + return homePlacesNavigator.getEventsNavigation(); + } + + @Override + public PlaceNavigation getEventNavigation(UUID eventId) { + return homePlacesNavigator.getEventNavigation(eventId.toString(), null, false); + } + + @Override + public PlaceNavigation getCurrentEventSeriesNavigation() { + return homePlacesNavigator.getEventSeriesNavigation(ctx.getSeriesId(), null, false); + } + + @Override + public void ensureMedia(final AsyncCallback callback) { + if(ctx.getMedia() != null) { + callback.onSuccess(ctx.getMedia()); + return; + } + clientFactory.getHomeService().getMediaForEventSeries(ctx.getSeriesDTO().getId(), new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + // TODO @FM: extract error message + ErrorView errorView = clientFactory.createErrorView("Load media failure for series", caught); + getView().showErrorInCurrentTab(errorView); + // TODO: notify callback of failure? + // callback.onFailure(caught); + } + + @Override + public void onSuccess(MediaDTO result) { + ctx.withMedia(result); + callback.onSuccess(result); + } + }); + } + + @Override + public boolean hasMedia() { + return ctx.getSeriesDTO().isHasMedia(); + } + + protected abstract SeriesView getView(); +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/AbstractSeriesPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/AbstractSeriesPlace.java new file mode 100644 index 00000000000..6e25d8dbfd0 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/AbstractSeriesPlace.java @@ -0,0 +1,49 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries; + +import java.util.HashMap; +import java.util.Map; + +import com.google.gwt.place.shared.Place; +import com.sap.sailing.gwt.common.client.AbstractMapTokenizer; +import com.sap.sailing.gwt.common.client.i18n.TextMessages; + +public abstract class AbstractSeriesPlace extends Place { + private final SeriesContext ctx; + + protected AbstractSeriesPlace(SeriesContext ctx) { + this.ctx = ctx; + } + + public SeriesContext getCtx() { + return ctx; + } + + public AbstractSeriesPlace(String eventUuidAsString) { + this.ctx = new SeriesContext(); + ctx.withId(eventUuidAsString); + } + + public String getTitle(String eventName) { + return TextMessages.INSTANCE.sapSailing() + " - " + eventName; + } + + public String getSeriesUuidAsString() { + return ctx.getSeriesId(); + } + + public static abstract class Tokenizer extends AbstractMapTokenizer { + private final static String PARAM_EVENTID = "seriesId"; + protected PLACE getPlaceFromParameters(Map parameters) { + return getRealPlace(new SeriesContext().withId(parameters.get(PARAM_EVENTID))); + } + + protected Map getParameters(PLACE place) { + Map parameters = new HashMap<>(); + SeriesContext context = place.getCtx(); + parameters.put(PARAM_EVENTID, context.getSeriesId()); + return parameters; + } + + protected abstract PLACE getRealPlace(SeriesContext context); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/AbstractSeriesTabPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/AbstractSeriesTabPlace.java new file mode 100644 index 00000000000..ce88c3f6ccc --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/AbstractSeriesTabPlace.java @@ -0,0 +1,13 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries; + + +public abstract class AbstractSeriesTabPlace extends AbstractSeriesPlace { + + public AbstractSeriesTabPlace(SeriesContext ctx) { + super(ctx); + } + + public AbstractSeriesTabPlace(String eventUuidAsString) { + super(eventUuidAsString); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalyticsDataManager.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/EventSeriesAnalyticsDataManager.java similarity index 94% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalyticsDataManager.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/EventSeriesAnalyticsDataManager.java index a9536a8e4b9..703b2b15836 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalyticsDataManager.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/EventSeriesAnalyticsDataManager.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.home.client.place.event.seriesanalytics; +package com.sap.sailing.gwt.home.client.place.fakeseries; import java.util.ArrayList; import java.util.Iterator; @@ -64,8 +64,8 @@ public class EventSeriesAnalyticsDataManager { if(overallLeaderboardPanel == null) { overallLeaderboardPanel = new LeaderboardPanel(sailingService, asyncActionsExecutor, leaderboardSettings, true, preselectedRace, competitorSelectionProvider, timer, leaderboardGroupName, leaderboardName, errorReporter, - StringMessages.INSTANCE, userAgent, showRaceDetails, /* competitorSearchTextBox */ null, /* showSelectionCheckbox */ true, /* raceTimesInfoProvider */null, autoExpandLastRaceColumn, /* adjustTimerDelay */ - true, false, false); + StringMessages.INSTANCE, userAgent, showRaceDetails, /* competitorSearchTextBox */ null, /* showSelectionCheckbox */ true, + /* raceTimesInfoProvider */null, autoExpandLastRaceColumn, /* adjustTimerDelay */ true, false, false); } return overallLeaderboardPanel; } @@ -133,8 +133,10 @@ public class EventSeriesAnalyticsDataManager { public void hideCompetitorChart() { MultiCompetitorLeaderboardChart multiCompetitorChart = getMultiCompetitorChart(); - multiCompetitorChart.setVisible(false); - timer.removeTimeListener(multiCompetitorChart); + if (multiCompetitorChart != null) { + multiCompetitorChart.setVisible(false); + timer.removeTimeListener(multiCompetitorChart); + } } public void showOverallLeaderboardSettingsDialog() { @@ -156,4 +158,8 @@ public class EventSeriesAnalyticsDataManager { dialog.ensureDebugId(debugIdPrefix + "SettingsDialog"); dialog.show(); } + + public Timer getTimer() { + return timer; + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesActivity.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesActivity.java new file mode 100644 index 00000000000..843c4786f22 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesActivity.java @@ -0,0 +1,139 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries; + +import java.util.UUID; + +import com.google.gwt.activity.shared.AbstractActivity; +import com.google.gwt.core.shared.GWT; +import com.google.gwt.event.shared.EventBus; +import com.google.gwt.place.shared.Place; +import com.google.gwt.safehtml.shared.SafeUri; +import com.google.gwt.safehtml.shared.UriUtils; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.app.ApplicationHistoryMapper; +import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.place.event.EventDefaultPlace; +import com.sap.sailing.gwt.home.client.place.event.legacy.SeriesClientFactory; +import com.sap.sailing.gwt.home.client.place.events.EventsPlace; +import com.sap.sailing.gwt.home.client.place.start.StartPlace; +import com.sap.sailing.gwt.ui.shared.media.MediaDTO; +import com.sap.sse.gwt.client.async.AsyncActionsExecutor; +import com.sap.sse.gwt.client.player.Timer; +import com.sap.sse.gwt.client.player.Timer.PlayModes; +import com.sap.sse.gwt.client.player.Timer.PlayStates; +import com.sap.sse.gwt.client.useragent.UserAgentDetails; + +public class SeriesActivity extends AbstractActivity implements SeriesView.Presenter { + + protected final AbstractSeriesTabPlace currentPlace; + protected final SeriesContext ctx; + protected final SeriesClientFactory clientFactory; + + protected final HomePlacesNavigator homePlacesNavigator; + + private static final ApplicationHistoryMapper historyMapper = GWT.create(ApplicationHistoryMapper.class); + + private SeriesView currentView = new TabletAndDesktopSeriesView(); + + private final UserAgentDetails userAgent = new UserAgentDetails(Window.Navigator.getUserAgent()); + private final AsyncActionsExecutor asyncActionsExecutor = new AsyncActionsExecutor(); + private final long delayBetweenAutoAdvancesInMilliseconds = 3000l; + + public SeriesActivity(AbstractSeriesTabPlace place, SeriesClientFactory clientFactory, HomePlacesNavigator homePlacesNavigator) { + this.currentPlace = place; + this.ctx = new SeriesContext(place.getCtx()); + this.clientFactory = clientFactory; + this.homePlacesNavigator = homePlacesNavigator; + + if (this.ctx.getAnalyticsManager() == null) { + ctx.withAnalyticsManager(new EventSeriesAnalyticsDataManager( // + clientFactory.getSailingService(), // + asyncActionsExecutor, // + new Timer(PlayModes.Live, PlayStates.Paused, delayBetweenAutoAdvancesInMilliseconds), // + clientFactory.getErrorReporter(), // + userAgent)); + + } + } + + @Override + public void start(final AcceptsOneWidget panel, final EventBus eventBus) { + currentView.registerPresenter(this); + panel.setWidget(currentView); + currentView.navigateTabsTo(currentPlace); + } + + @Override + public SeriesContext getCtx() { + return ctx; + } + + @Override + public void handleTabPlaceSelection(TabView selectedActivity) { + Place tabPlaceToGo = selectedActivity.placeToFire(); + clientFactory.getPlaceController().goTo(tabPlaceToGo); + } + + public void navigateTo(Place place) { + clientFactory.getPlaceController().goTo(place); + } + + @Override + public SafeUri getUrl(AbstractSeriesPlace place) { + String token = historyMapper.getToken(place); + return UriUtils.fromString("#" + token); + } + + @Override + public PlaceNavigation getHomeNavigation() { + return homePlacesNavigator.getHomeNavigation(); + } + + @Override + public PlaceNavigation getEventsNavigation() { + return homePlacesNavigator.getEventsNavigation(); + } + + @Override + public PlaceNavigation getEventNavigation(UUID eventId) { + return homePlacesNavigator.getEventNavigation(eventId.toString(), null, false); + } + + @Override + public PlaceNavigation getCurrentEventSeriesNavigation() { + return homePlacesNavigator.getEventSeriesNavigation(ctx.getSeriesId(), null, false); + } + + @Override + public void ensureMedia(final AsyncCallback callback) { + if(ctx.getMedia() != null) { + callback.onSuccess(ctx.getMedia()); + return; + } + clientFactory.getHomeService().getMediaForEventSeries(ctx.getSeriesDTO().getId(), new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + callback.onFailure(caught); + } + + @Override + public void onSuccess(MediaDTO result) { + ctx.withMedia(result); + callback.onSuccess(result); + } + }); + } + + @Override + public boolean hasMedia() { + return ctx.getSeriesDTO().isHasMedia(); + } + + @Override + public Timer getAutoRefreshTimer() { + return ctx.getAnalyticsManager().getTimer(); + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesActivityProxy.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesActivityProxy.java new file mode 100644 index 00000000000..03d13e04331 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesActivityProxy.java @@ -0,0 +1,78 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries; + +import java.util.UUID; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; +import com.sap.sailing.gwt.home.client.place.error.ErrorPlace; +import com.sap.sailing.gwt.home.client.place.event.legacy.SeriesClientFactory; +import com.sap.sailing.gwt.home.client.place.fakeseries.tabs.EventSeriesOverallLeaderboardPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.tabs.SeriesEventsPlace; +import com.sap.sailing.gwt.ui.shared.fakeseries.EventSeriesViewDTO; +import com.sap.sse.gwt.client.mvp.AbstractActivityProxy; + +public class SeriesActivityProxy extends AbstractActivityProxy { + + private final AbstractSeriesPlace place; + private SeriesContext ctx; + private SeriesClientFactory clientFactory; + private final HomePlacesNavigator homePlacesNavigator; + + public SeriesActivityProxy(AbstractSeriesPlace place, SeriesClientFactory clientFactory, + HomePlacesNavigator homePlacesNavigator) { + this.place = place; + this.ctx = place.getCtx(); + this.clientFactory = clientFactory; + this.homePlacesNavigator = homePlacesNavigator; + } + + @Override + protected void startAsync() { + if (ctx.getSeriesDTO() != null) { + afterLoad(); + } else { + final UUID seriesUUID = UUID.fromString(ctx.getSeriesId()); + clientFactory.getHomeService().getEventSeriesViewById(seriesUUID, new AsyncCallback() { + @Override + public void onSuccess(final EventSeriesViewDTO event) { + ctx.updateContext(event); + afterLoad(); + } + @Override + public void onFailure(Throwable caught) { + // TODO @FM: extract text? + ErrorPlace errorPlace = new ErrorPlace( + "Error while loading the series with service getEventSeriesViewById()"); + // TODO @FM: reload sinnvoll hier? + errorPlace.setComingFrom(place); + clientFactory.getPlaceController().goTo(errorPlace); + } + }); + } + } + + private void afterLoad() { + GWT.runAsync(new AbstractRunAsyncCallback() { + @Override + public void onSuccess() { + final AbstractSeriesPlace placeToStart; + if (place instanceof SeriesDefaultPlace) { + placeToStart = getRealPlace(); + } else { + placeToStart = place; + } + super.onSuccess(new SeriesActivity((AbstractSeriesTabPlace) placeToStart, clientFactory, + homePlacesNavigator)); + } + }); + } + + private AbstractSeriesPlace getRealPlace() { + if (ctx.getSeriesDTO().isHasAnalytics()) { + return new EventSeriesOverallLeaderboardPlace(ctx); + } else { + return new SeriesEventsPlace(ctx); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesContext.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesContext.java new file mode 100644 index 00000000000..615b3c13685 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesContext.java @@ -0,0 +1,78 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries; + +import com.sap.sailing.gwt.ui.shared.fakeseries.EventSeriesViewDTO; +import com.sap.sailing.gwt.ui.shared.media.MediaDTO; + +/** + * Common context used by the different tabs in the series place. + * + * @author pgtaboada + * + */ +public class SeriesContext { + + private String seriesId; + + private EventSeriesViewDTO seriesDTO; + + private MediaDTO media; + + private EventSeriesAnalyticsDataManager analyticsManager; + + + public SeriesContext() { + } + + public SeriesContext(SeriesContext ctx) { + updateContext(ctx.getSeriesDTO()); + withMedia(ctx.media); + withAnalyticsManager(ctx.analyticsManager); + } + + public SeriesContext withId(String eventId) { + this.seriesId = eventId; + return this; + } + + /** + * Used to update context with dto instance + * + * @param dto + * @return + */ + public SeriesContext updateContext(EventSeriesViewDTO dto) { + this.seriesDTO = dto; + if (seriesDTO == null) { + withId(null); + } else { + withId(dto.getId().toString()); + } + return this; + } + + public EventSeriesViewDTO getSeriesDTO() { + return seriesDTO; + } + + public String getSeriesId() { + return seriesId; + } + + public MediaDTO getMedia() { + return media; + } + + public SeriesContext withMedia(MediaDTO media) { + this.media = media; + return this; + } + + public EventSeriesAnalyticsDataManager getAnalyticsManager() { + return analyticsManager; + } + + public SeriesContext withAnalyticsManager(EventSeriesAnalyticsDataManager regattaAnalyticsManager) { + this.analyticsManager = regattaAnalyticsManager; + return this; + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesDefaultPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesDefaultPlace.java new file mode 100644 index 00000000000..0e35359853c --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesDefaultPlace.java @@ -0,0 +1,24 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries; + +import com.google.gwt.place.shared.Prefix; +import com.sap.sailing.gwt.home.client.place.event.EventPrefixes; + + +public class SeriesDefaultPlace extends AbstractSeriesPlace { + + public SeriesDefaultPlace(SeriesContext ctx) { + super(ctx); + } + + public SeriesDefaultPlace(String eventUuidAsString) { + super(eventUuidAsString); + } + + @Prefix(EventPrefixes.SeriesDefault) + public static class Tokenizer extends AbstractSeriesPlace.Tokenizer { + @Override + protected SeriesDefaultPlace getRealPlace(SeriesContext context) { + return new SeriesDefaultPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesTabView.java new file mode 100644 index 00000000000..da8a7f0d828 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesTabView.java @@ -0,0 +1,6 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries; + +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; + +public interface SeriesTabView extends TabView { +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesView.java new file mode 100644 index 00000000000..7eb4ea80a4a --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/SeriesView.java @@ -0,0 +1,55 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries; + +import java.util.UUID; + +import com.google.gwt.place.shared.Place; +import com.google.gwt.safehtml.shared.SafeUri; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.IsWidget; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.place.event.EventDefaultPlace; +import com.sap.sailing.gwt.home.client.place.events.EventsPlace; +import com.sap.sailing.gwt.home.client.place.start.StartPlace; +import com.sap.sailing.gwt.ui.shared.media.MediaDTO; +import com.sap.sse.gwt.client.player.Timer; + +public interface SeriesView extends IsWidget { + + public interface Presenter { + SeriesContext getCtx(); + + void handleTabPlaceSelection(TabView selectedActivity); + + SafeUri getUrl(AbstractSeriesPlace place); + void navigateTo(Place place); + + PlaceNavigation getHomeNavigation(); + PlaceNavigation getEventsNavigation(); + PlaceNavigation getCurrentEventSeriesNavigation(); + + PlaceNavigation getEventNavigation(UUID eventId); + + void ensureMedia(AsyncCallback asyncCallback); + boolean hasMedia(); + + Timer getAutoRefreshTimer(); + } + + /** + * This is the presenter the view can talk to. + * + * @param currentPresenter + */ + void registerPresenter(PRES currentPresenter); + + /** + * Tell the view to process tabbar place navigation + * + * @param place + */ + void navigateTabsTo(PLACE place); + + void showErrorInCurrentTab(IsWidget errorView); + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/TabletAndDesktopSeriesView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/TabletAndDesktopSeriesView.java new file mode 100644 index 00000000000..79aa6eea3e9 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/TabletAndDesktopSeriesView.java @@ -0,0 +1,92 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.uibinder.client.UiHandler; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.IsWidget; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabPanel; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabPanelPlaceSelectionEvent; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.common.client.i18n.TextMessages; +import com.sap.sailing.gwt.home.client.app.ApplicationHistoryMapper; +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.place.fakeseries.partials.header.SeriesHeader; +import com.sap.sailing.gwt.ui.client.StringMessages; + +public class TabletAndDesktopSeriesView extends Composite implements SeriesView { + private static final ApplicationHistoryMapper historyMapper = GWT. create(ApplicationHistoryMapper.class); + + private static MyBinder uiBinder = GWT.create(MyBinder.class); + + private SeriesView.Presenter currentPresenter; + + interface MyBinder extends UiBinder { + } + + @UiField StringMessages i18n; + + @UiField(provided = true) + TabPanel tabPanelUi; + + @UiField(provided = true) + SeriesHeader seriesHeader; + + public TabletAndDesktopSeriesView() { + } + + @Override + public void registerPresenter(final SeriesView.Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + tabPanelUi = new TabPanel<>(currentPresenter, historyMapper); + + seriesHeader = new SeriesHeader(currentPresenter); + + initWidget(uiBinder.createAndBindUi(this)); + + initBreadCrumbs(); + } + + @Override + public void navigateTabsTo(AbstractSeriesTabPlace place) { + tabPanelUi.activatePlace(place); + StringBuilder titleBuilder = new StringBuilder(TextMessages.INSTANCE.sapSailing()).append(" - "); + + titleBuilder.append(currentPresenter.getCtx().getSeriesDTO().getDisplayName()); + + String currentTabTitle = tabPanelUi.getCurrentTabTitle(); + if (currentTabTitle != null && !currentTabTitle.isEmpty()) { + titleBuilder.append(" - ").append(currentTabTitle); + } + Window.setTitle(titleBuilder.toString()); + } + + @SuppressWarnings("unchecked") + @UiHandler("tabPanelUi") + public void onTabSelection(TabPanelPlaceSelectionEvent e) { + currentPresenter.handleTabPlaceSelection((TabView) e.getSelectedActivity()); + } + + private void initBreadCrumbs() { + addBreadCrumbItem(i18n.home(), currentPresenter.getHomeNavigation()); + addBreadCrumbItem(i18n.events(), currentPresenter.getEventsNavigation()); + addBreadCrumbItem(currentPresenter.getCtx().getSeriesDTO().getDisplayName(), currentPresenter.getCurrentEventSeriesNavigation()); + } + + private void addBreadCrumbItem(String label, final PlaceNavigation placeNavigation) { + tabPanelUi.addBreadcrumbItem(label, placeNavigation.getTargetUrl(), new Runnable() { + @Override + public void run() { + placeNavigation.goToPlace(); + } + }); + } + + @Override + public void showErrorInCurrentTab(IsWidget errorView) { + tabPanelUi.overrideCurrentContentInTab(errorView); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/TabletAndDesktopSeriesView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/TabletAndDesktopSeriesView.ui.xml new file mode 100644 index 00000000000..fc19cf52381 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/TabletAndDesktopSeriesView.ui.xml @@ -0,0 +1,72 @@ + + + + + + .header { + position: relative; + width: 100%; + margin: 0; + padding: 0; + } + + .mainHeader { + width: 66.6666666666667%; + } + + .sharingHeader { + width: 33.3333333333333%; + float: right; + padding: 0 1rem; + position: relative; + padding: 1.333333333333333em 0; + text-align: right; + + background-color: maroon; + height: 2rem; + } + + .breadcrumb, .intro { + box-sizing: border-box; + -moz-box-sizing: border-box; + } + + .breadcrumb { + font-size: 0.866666666666667em; + font-weight: 600; + } + + .intro { + height: 5em; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/partials/header/SeriesHeader.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/partials/header/SeriesHeader.gss new file mode 100644 index 00000000000..14a144f1b81 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/partials/header/SeriesHeader.gss @@ -0,0 +1,114 @@ +/** + * The header of the pages to an event series + */ +.leaderboardquickaccess { + font-size: 1rem; + text-align: right; +} +.eventheader { + position: relative; + font-size: 1rem; + color: #666; + background: #f2f2f2; + border-bottom: 1px solid #dedede; +} +.eventheader_breadcrumb { + font-size: 1rem; + /* @alternate */font-size: 0.866666666666667em; + font-weight: 600; + padding: 0.666666666666667em 0; +} +.eventheader_breadcrumbback { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 1.333333333333333em; + border-right: 1px solid #cfcfcf; + background-color: #dedede; + background-image: url("images/home/breadcrumb-arrow__back.png"); + background-position: center center; + background-repeat: no-repeat; + background-size: 50%; + -webkit-transition: background-color 0.2s, border-color 0.2s; + -moz-transition: background-color 0.2s, border-color 0.2s; + transition: background-color 0.2s, border-color 0.2s; +} +.eventheader_breadcrumbback:hover { + background-color: #cfcfcf; +} +.eventheader_intro { + padding-left: 6em; + margin: 0.666666666666667em 0; + min-height: 5em; + position: relative; +} +.eventheader_intro_logo { + position: absolute; + top: 0; + left: 0; + width: 5em; + height: 5em; + border: 0.333333333333333em solid #f6f9fc; + box-shadow: 0 0 5px rgba(238,238,238,0.5); +} +.eventheader_intro_logo_image { + height: 100%; + width: 100%; + background-position: center; + background-size: contain; + background-repeat: no-repeat; +} +.eventheader_intro_name { + display: inline-block; + margin: 0 0.333333333333333em 0 0; + font-size: 1.866666666666667em; + color: #333; +} +.eventheader_intro_details { + margin-bottom: 0.666666666666667em; + padding-bottom: 0.666666666666667em; + font-weight: 700; + color: #333; +} +.eventheader_intro_details_item { + display: inline-block; + border-left: 1px solid #cfcfcf; + margin: 0.266666666666667em 0 0.266666666666667em 0.333333333333333em; + padding-left: 0.666666666666667em; + color: #666; +} +.eventheader_intro_details_item_inactive { + color: #AAA; +} +.eventheader_intro_details_itemlink { + color: inherit; +} +.eventheader_intro_details_item:first-child { + margin-left: 0; + padding-left: 0; + border: none; +} +.eventheader_status { + text-align: right; +} +.eventheader_status_title { + text-transform: uppercase; +} +.eventheader_status_body { + font-size: 1rem; +} +.locationicon { + vertical-align: text-bottom; + margin-right: 0.333333333333333em; +} +.eventnavigation { + font-size: 0; + margin-bottom: -1px; +} +.eventnavigationnormal { + position: relative; +} +.eventnavigation .navbar_button { + font-size: 1.2rem; +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/partials/header/SeriesHeader.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/partials/header/SeriesHeader.java new file mode 100644 index 00000000000..75454a9f3df --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/partials/header/SeriesHeader.java @@ -0,0 +1,106 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries.partials.header; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.DivElement; +import com.google.gwt.dom.client.SpanElement; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.ui.Anchor; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.InlineLabel; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.common.client.LinkUtil; +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.place.event.EventDefaultPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesView; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesView.Presenter; +import com.sap.sailing.gwt.home.client.shared.LabelTypeUtil; +import com.sap.sailing.gwt.home.client.shared.sharing.SharingButtons; +import com.sap.sailing.gwt.home.client.shared.sharing.SharingMetadataProvider; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sailing.gwt.ui.shared.fakeseries.EventSeriesViewDTO; +import com.sap.sailing.gwt.ui.shared.general.EventMetadataDTO; +import com.sap.sailing.gwt.ui.shared.general.EventState; + +public class SeriesHeader extends Composite { + private static SeriesHeaderUiBinder uiBinder = GWT.create(SeriesHeaderUiBinder.class); + + interface SeriesHeaderUiBinder extends UiBinder { + } + + @UiField StringMessages i18n; + + @UiField DivElement eventLogo; + @UiField SpanElement eventName; + @UiField DivElement eventState; + @UiField FlowPanel venues; + + @UiField SharingButtons sharing; + + private EventSeriesViewDTO series; + + private Presenter presenter; + + boolean dropdownShown = false; + + public SeriesHeader(SeriesView.Presenter presenter) { + this.series = presenter.getCtx().getSeriesDTO(); + this.presenter = presenter; + + SeriesHeaderResources.INSTANCE.css().ensureInjected(); + initWidget(uiBinder.createAndBindUi(this)); + + initFields(); + initSharing(); + } + + private void initSharing() { + sharing.setUp(new SharingMetadataProvider() { + @Override + public String getShortText() { + return StringMessages.INSTANCE.seriesSharingShortText(series.getDisplayName()); + } + + @Override + public String getLongText(String url) { + return StringMessages.INSTANCE.seriesSharingLongText(series.getDisplayName(), url); + } + }); + } + + private void initFields() { + String logoUrl = series.getLogoImageURL() != null ? series.getLogoImageURL() : SeriesHeaderResources.INSTANCE.defaultEventLogoImage().getSafeUri().asString(); + eventLogo.getStyle().setBackgroundImage("url(" + logoUrl + ")"); + eventLogo.setTitle(series.getDisplayName()); + eventName.setInnerText(series.getDisplayName()); + LabelTypeUtil.renderLabelType(eventState, series.getState().getStateMarker()); + + for (EventMetadataDTO eventOfSeries : series.getEvents()) { + if(eventOfSeries.getState() == EventState.PLANNED) { + InlineLabel eventLabel = new InlineLabel(eventOfSeries.getLocationOrVenue()); + eventLabel.addStyleName(SeriesHeaderResources.INSTANCE.css().eventheader_intro_details_item()); + eventLabel.addStyleName(SeriesHeaderResources.INSTANCE.css().eventheader_intro_details_item_inactive()); + venues.add(eventLabel); + } else { + Anchor eventAnchor = new Anchor(eventOfSeries.getLocationOrVenue()); + eventAnchor.addStyleName(SeriesHeaderResources.INSTANCE.css().eventheader_intro_details_item()); + final PlaceNavigation eventNavigation = presenter.getEventNavigation(eventOfSeries.getId()); + eventAnchor.setHref(eventNavigation.getTargetUrl()); + venues.add(eventAnchor); + eventAnchor.addClickHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + if(LinkUtil.handleLinkClick(Event.as(event.getNativeEvent()))) { + event.preventDefault(); + eventNavigation.goToPlace(); + } + } + }); + } + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/partials/header/SeriesHeader.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/partials/header/SeriesHeader.ui.xml new file mode 100644 index 00000000000..3827a9889ef --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/partials/header/SeriesHeader.ui.xml @@ -0,0 +1,29 @@ + + + + + + +
+
+
+
+
+

+ + +
+
+ +

+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/partials/header/SeriesHeaderResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/partials/header/SeriesHeaderResources.java new file mode 100644 index 00000000000..9a12f899aed --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/partials/header/SeriesHeaderResources.java @@ -0,0 +1,39 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries.partials.header; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.resources.client.ClientBundle; +import com.google.gwt.resources.client.CssResource; +import com.google.gwt.resources.client.ImageResource; + +public interface SeriesHeaderResources extends ClientBundle { + public static final SeriesHeaderResources INSTANCE = GWT.create(SeriesHeaderResources.class); + + @Source("SeriesHeader.gss") + LocalCss css(); + + public interface LocalCss extends CssResource { + String leaderboardquickaccess(); + String eventheader(); + String eventheader_breadcrumb(); + String eventheader_breadcrumbback(); + String eventheader_intro(); + String eventheader_intro_logo(); + String eventheader_intro_logo_image(); + String eventheader_intro_name(); + String eventheader_intro_details(); + String eventheader_intro_details_item(); + String eventheader_intro_details_item_inactive(); + String eventheader_intro_details_itemlink(); + String eventheader_status(); + String eventheader_status_title(); + String eventheader_status_body(); + String locationicon(); + String eventnavigation(); + String eventnavigationnormal(); + String navbar_button(); + } + + @Source("com/sap/sailing/gwt/home/images/default_event_logo.jpg") + ImageResource defaultEventLogoImage(); + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesCompetitorAnalyticsPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesCompetitorAnalyticsPlace.java new file mode 100644 index 00000000000..78f707c1632 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesCompetitorAnalyticsPlace.java @@ -0,0 +1,25 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries.tabs; + +import com.google.gwt.place.shared.Prefix; +import com.sap.sailing.gwt.home.client.place.event.EventPrefixes; +import com.sap.sailing.gwt.home.client.place.fakeseries.AbstractSeriesPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.AbstractSeriesTabPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesContext; + +public class EventSeriesCompetitorAnalyticsPlace extends AbstractSeriesTabPlace { + public EventSeriesCompetitorAnalyticsPlace(String id) { + super(id); + } + + public EventSeriesCompetitorAnalyticsPlace(SeriesContext context) { + super(context); + } + + @Prefix(EventPrefixes.EventSeriesCompetitorAnalytics) + public static class Tokenizer extends AbstractSeriesPlace.Tokenizer { + @Override + protected EventSeriesCompetitorAnalyticsPlace getRealPlace(SeriesContext context) { + return new EventSeriesCompetitorAnalyticsPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesCompetitorAnalyticsTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesCompetitorAnalyticsTabView.java new file mode 100644 index 00000000000..c537f0c6a49 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesCompetitorAnalyticsTabView.java @@ -0,0 +1,126 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries.tabs; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.sap.sailing.domain.common.DetailType; +import com.sap.sailing.domain.common.RaceIdentifier; +import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.LeaderboardDTO; +import com.sap.sailing.domain.common.dto.RaceColumnDTO; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.place.event.oldcompetitorcharts.OldCompetitorCharts; +import com.sap.sailing.gwt.home.client.place.fakeseries.EventSeriesAnalyticsDataManager; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesView; +import com.sap.sailing.gwt.home.client.shared.placeholder.Placeholder; +import com.sap.sailing.gwt.ui.client.CompetitorSelectionChangeListener; +import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel; +import com.sap.sse.common.Util; + +/** + * Created by pgtaboada on 25.11.14. + */ +public class EventSeriesCompetitorAnalyticsTabView extends SharedLeaderboardEventSeriesTabView { + interface MyBinder extends UiBinder { + } + + private static MyBinder ourUiBinder = GWT.create(MyBinder.class); + private SeriesView.Presenter currentPresenter; + + @UiField + protected OldCompetitorCharts competitorCharts; + + private final int MAX_COMPETITORS_IN_CHART = 30; + + public EventSeriesCompetitorAnalyticsTabView() { + super(); + } + + @Override + public Class getPlaceClassForActivation() { + return EventSeriesCompetitorAnalyticsPlace.class; + } + + @Override + public TabView.State getState() { + return currentPresenter.getCtx().getSeriesDTO().isHasAnalytics() ? TabView.State.VISIBLE : TabView.State.INVISIBLE; + } + + @Override + public void start(EventSeriesCompetitorAnalyticsPlace myPlace, AcceptsOneWidget contentArea) { + contentArea.setWidget(new Placeholder()); + String leaderboardName = myPlace.getCtx().getSeriesDTO().getLeaderboardId(); + if (leaderboardName != null && !leaderboardName.isEmpty()) { + EventSeriesAnalyticsDataManager eventSeriesAnalyticsManager = currentPresenter.getCtx().getAnalyticsManager(); + if(eventSeriesAnalyticsManager.getLeaderboardPanel() == null) { + createSharedLeaderboardPanel(leaderboardName, eventSeriesAnalyticsManager); + } + initWidget(ourUiBinder.createAndBindUi(this)); + + DetailType initialDetailType = DetailType.OVERALL_RANK; + if (eventSeriesAnalyticsManager.getMultiCompetitorChart() == null) { + eventSeriesAnalyticsManager.createMultiCompetitorChart(leaderboardName, initialDetailType); + } + competitorCharts.setChart(eventSeriesAnalyticsManager.getMultiCompetitorChart(), getAvailableDetailsTypes(), initialDetailType); + eventSeriesAnalyticsManager.showCompetitorChart(competitorCharts.getSelectedChartDetailType()); + contentArea.setWidget(this); + } + } + + private List getAvailableDetailsTypes() { + List availableDetailsTypes = new ArrayList(); + availableDetailsTypes.add(DetailType.OVERALL_RANK); + availableDetailsTypes.add(DetailType.REGATTA_TOTAL_POINTS_SUM); + return availableDetailsTypes; + } + + @Override + public void stop() { + } + + @Override + public EventSeriesCompetitorAnalyticsPlace placeToFire() { + return new EventSeriesCompetitorAnalyticsPlace(currentPresenter.getCtx()); + } + + @Override + public void setPresenter(SeriesView.Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + } + + @Override + public void updatedLeaderboard(LeaderboardDTO leaderboard) { + // adjust the competitor selection for the chart in case the leaderboard changed + updateCompetitorSelection(); + } + + private void updateCompetitorSelection() { + EventSeriesAnalyticsDataManager eventSeriesAnalyticsManager = currentPresenter.getCtx().getAnalyticsManager(); + CompetitorSelectionModel competitorSelectionProvider = eventSeriesAnalyticsManager.getCompetitorSelectionProvider(); + + // preselect the top N competitors in case there was no selection before and there too many competitors for a chart + int competitorsCount = Util.size(competitorSelectionProvider.getAllCompetitors()); + int selectedCompetitorsCount = Util.size(competitorSelectionProvider.getSelectedCompetitors()); + + if(selectedCompetitorsCount == 0 && competitorsCount > MAX_COMPETITORS_IN_CHART) { + List selectedCompetitors = new ArrayList(); + Iterator allCompetitorsIt = competitorSelectionProvider.getAllCompetitors().iterator(); + int counter = 0; + while(counter < MAX_COMPETITORS_IN_CHART) { + selectedCompetitors.add(allCompetitorsIt.next()); + counter++; + } + competitorSelectionProvider.setSelection(selectedCompetitors, (CompetitorSelectionChangeListener[]) null); + } + } + + @Override + public void currentRaceSelected(RaceIdentifier raceIdentifier, RaceColumnDTO raceColumn) { + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesCompetitorAnalyticsTabView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesCompetitorAnalyticsTabView.ui.xml new file mode 100644 index 00000000000..8d2100385dd --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesCompetitorAnalyticsTabView.ui.xml @@ -0,0 +1,14 @@ + + + .outerBox { + padding-top: 10px; + + } + + + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesLeaderboardTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesLeaderboardTabView.java new file mode 100644 index 00000000000..db6d67e1129 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesLeaderboardTabView.java @@ -0,0 +1,111 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries.tabs; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.google.gwt.user.client.ui.Label; +import com.sap.sailing.domain.common.RaceIdentifier; +import com.sap.sailing.domain.common.dto.LeaderboardDTO; +import com.sap.sailing.domain.common.dto.RaceColumnDTO; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.place.event.oldleaderboard.OldLeaderboard; +import com.sap.sailing.gwt.home.client.place.fakeseries.EventSeriesAnalyticsDataManager; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesView; +import com.sap.sailing.gwt.home.client.shared.placeholder.Placeholder; +import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel; + +/** + * Created by pgtaboada on 25.11.14. + */ +public class EventSeriesLeaderboardTabView extends SharedLeaderboardEventSeriesTabView { + + interface MyBinder extends UiBinder { + } + + private static MyBinder ourUiBinder = GWT.create(MyBinder.class); + + private SeriesView.Presenter currentPresenter; + + @UiField + protected OldLeaderboard leaderboard; + + public EventSeriesLeaderboardTabView() { + super(); + } + + @Override + public Class getPlaceClassForActivation() { + return EventSeriesOverallLeaderboardPlace.class; + } + + @Override + public void setPresenter(SeriesView.Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + } + + @Override + public TabView.State getState() { + return currentPresenter.getCtx().getSeriesDTO().isHasAnalytics() ? TabView.State.VISIBLE : TabView.State.INVISIBLE; + } + + @Override + public void start(final EventSeriesOverallLeaderboardPlace myPlace, final AcceptsOneWidget contentArea) { + contentArea.setWidget(new Placeholder()); + String leaderboardName = myPlace.getCtx().getSeriesDTO().getLeaderboardId(); + if (leaderboardName != null && !leaderboardName.isEmpty()) { + EventSeriesAnalyticsDataManager eventSeriesAnalyticsManager = currentPresenter.getCtx().getAnalyticsManager(); + LeaderboardPanel leaderboardPanel = eventSeriesAnalyticsManager.getLeaderboardPanel(); + if(leaderboardPanel == null) { + leaderboardPanel = createSharedLeaderboardPanel(leaderboardName, eventSeriesAnalyticsManager); + } +// +// boolean autoExpandLastRaceColumn = GwtHttpRequestUtils.getBooleanParameter( +// LeaderboardUrlSettings.PARAM_AUTO_EXPAND_LAST_RACE_COLUMN, false); +// final LeaderboardSettings leaderboardSettings = EventParamUtils +// .createLeaderboardSettingsFromURLParameters(Window.Location +// .getParameterMap()); +// final RegattaAndRaceIdentifier preselectedRace = EventParamUtils +// .getPreselectedRace(Window.Location.getParameterMap()); +// LeaderboardPanel leaderboardPanel = regattaAnalyticsManager.createOverallLeaderboardPanel( +// leaderboardSettings, +// preselectedRace, +// "leaderboardGroupName", // TODO: keep using magic string? ask frank! +// leaderboardName, +// true, // this information came from place, now hard coded. check with frank +// autoExpandLastRaceColumn); + initWidget(ourUiBinder.createAndBindUi(this)); + leaderboard.setLeaderboard(leaderboardPanel, currentPresenter.getAutoRefreshTimer()); +// leaderboardPanel.addLeaderboardUpdateListener(this); + eventSeriesAnalyticsManager.hideCompetitorChart(); + contentArea.setWidget(this); + } else { + contentArea.setWidget(new Label("No leaderboard specified, cannot proceed to leaderboardpage")); + new com.google.gwt.user.client.Timer() { + @Override + public void run() { + currentPresenter.getHomeNavigation().goToPlace(); + } + }.schedule(3000); + } + } + + @Override + public void updatedLeaderboard(LeaderboardDTO leaderboard) { + this.leaderboard.updatedLeaderboard(leaderboard, true); + } + + @Override + public void currentRaceSelected(RaceIdentifier raceIdentifier, RaceColumnDTO raceColumn) { + } + + @Override + public void stop() { + } + + @Override + public EventSeriesOverallLeaderboardPlace placeToFire() { + return new EventSeriesOverallLeaderboardPlace(currentPresenter.getCtx()); + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesLeaderboardTabView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesLeaderboardTabView.ui.xml new file mode 100644 index 00000000000..c6cc403a7a8 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesLeaderboardTabView.ui.xml @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesLeaderboardsPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesLeaderboardsPlace.java new file mode 100644 index 00000000000..64c815c72d6 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesLeaderboardsPlace.java @@ -0,0 +1,25 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries.tabs; + +import com.google.gwt.place.shared.Prefix; +import com.sap.sailing.gwt.home.client.place.event.EventPrefixes; +import com.sap.sailing.gwt.home.client.place.fakeseries.AbstractSeriesPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.AbstractSeriesTabPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesContext; + +public class EventSeriesLeaderboardsPlace extends AbstractSeriesTabPlace { + public EventSeriesLeaderboardsPlace(String id) { + super(id); + } + + public EventSeriesLeaderboardsPlace(SeriesContext context) { + super(context); + } + + @Prefix(EventPrefixes.EventSeriesLeaderboards) + public static class Tokenizer extends AbstractSeriesPlace.Tokenizer { + @Override + protected EventSeriesLeaderboardsPlace getRealPlace(SeriesContext context) { + return new EventSeriesLeaderboardsPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesLeaderboardsTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesLeaderboardsTabView.java new file mode 100644 index 00000000000..e13b400eb31 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesLeaderboardsTabView.java @@ -0,0 +1,118 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries.tabs; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.google.gwt.user.client.ui.Label; +import com.sap.sailing.domain.common.RaceIdentifier; +import com.sap.sailing.domain.common.dto.LeaderboardDTO; +import com.sap.sailing.domain.common.dto.RaceColumnDTO; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.place.event.oldmultileaderboard.OldMultiLeaderboard; +import com.sap.sailing.gwt.home.client.place.event.utils.EventParamUtils; +import com.sap.sailing.gwt.home.client.place.fakeseries.EventSeriesAnalyticsDataManager; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesTabView; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesView; +import com.sap.sailing.gwt.home.client.shared.placeholder.Placeholder; +import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener; +import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings; +import com.sap.sailing.gwt.ui.leaderboard.LeaderboardUrlSettings; +import com.sap.sailing.gwt.ui.leaderboard.MultiLeaderboardPanel; +import com.sap.sailing.gwt.ui.shared.fakeseries.EventSeriesViewDTO.EventSeriesState; +import com.sap.sse.gwt.shared.GwtHttpRequestUtils; + +public class EventSeriesLeaderboardsTabView extends Composite implements SeriesTabView, + LeaderboardUpdateListener { + + interface MyBinder extends UiBinder { + } + + private static MyBinder ourUiBinder = GWT.create(MyBinder.class); + + private SeriesView.Presenter currentPresenter; + + @UiField + protected OldMultiLeaderboard leaderboard; + + public EventSeriesLeaderboardsTabView() { + } + + @Override + public Class getPlaceClassForActivation() { + return EventSeriesLeaderboardsPlace.class; + } + + @Override + public void setPresenter(SeriesView.Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + } + + @Override + public TabView.State getState() { + return currentPresenter.getCtx().getSeriesDTO().isHasAnalytics() ? TabView.State.VISIBLE : TabView.State.INVISIBLE; + } + + @Override + public void start(final EventSeriesLeaderboardsPlace myPlace, final AcceptsOneWidget contentArea) { + contentArea.setWidget(new Placeholder()); + String leaderboardName = myPlace.getCtx().getSeriesDTO().getLeaderboardId(); + + if (leaderboardName != null && !leaderboardName.isEmpty()) { + EventSeriesAnalyticsDataManager regattaAnalyticsManager = currentPresenter.getCtx().getAnalyticsManager(); + boolean autoExpandLastRaceColumn = GwtHttpRequestUtils.getBooleanParameter(LeaderboardUrlSettings.PARAM_AUTO_EXPAND_LAST_RACE_COLUMN, false); + final LeaderboardSettings leaderboardSettings = EventParamUtils.createLeaderboardSettingsFromURLParameters(Window.Location.getParameterMap()); + final RaceIdentifier preselectedRace = EventParamUtils.getPreselectedRace(Window.Location.getParameterMap()); + + MultiLeaderboardPanel leaderboardPanel = regattaAnalyticsManager.createMultiLeaderboardPanel(leaderboardSettings, + null, // TODO: preselectedLeaderboardName + preselectedRace, + "leaderboardGroupName", + leaderboardName, + true, // TODO @FM this information came from place, now hard coded. check with frank + autoExpandLastRaceColumn); + + initWidget(ourUiBinder.createAndBindUi(this)); + + leaderboard.setMultiLeaderboard(leaderboardPanel, currentPresenter.getAutoRefreshTimer()); + leaderboardPanel.addLeaderboardUpdateListener(this); + if (currentPresenter.getCtx().getSeriesDTO().getState() != EventSeriesState.RUNNING) { + // TODO: this.leaderboard.hideRefresh(); + } else { + // TODO: start autorefresh? + } + regattaAnalyticsManager.hideCompetitorChart(); + leaderboardPanel.setVisible(true); + contentArea.setWidget(this); + } else { + contentArea.setWidget(new Label("No leaderboard specified, cannot proceed to leaderboardpage")); + new com.google.gwt.user.client.Timer() { + @Override + public void run() { + currentPresenter.getHomeNavigation().goToPlace(); + } + }.schedule(3000); + } + } + + @Override + public void updatedLeaderboard(LeaderboardDTO leaderboard) { + this.leaderboard.updatedMultiLeaderboard(leaderboard, true); + } + + @Override + public void currentRaceSelected(RaceIdentifier raceIdentifier, RaceColumnDTO raceColumn) { + } + + @Override + public void stop() { + } + + @Override + public EventSeriesLeaderboardsPlace placeToFire() { + return new EventSeriesLeaderboardsPlace(currentPresenter.getCtx()); + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesLeaderboardsTabView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesLeaderboardsTabView.ui.xml new file mode 100644 index 00000000000..2d66bf4a8da --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesLeaderboardsTabView.ui.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesOverallLeaderboardPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesOverallLeaderboardPlace.java new file mode 100644 index 00000000000..0ac7a6b3829 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/EventSeriesOverallLeaderboardPlace.java @@ -0,0 +1,25 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries.tabs; + +import com.google.gwt.place.shared.Prefix; +import com.sap.sailing.gwt.home.client.place.event.EventPrefixes; +import com.sap.sailing.gwt.home.client.place.fakeseries.AbstractSeriesPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.AbstractSeriesTabPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesContext; + +public class EventSeriesOverallLeaderboardPlace extends AbstractSeriesTabPlace { + public EventSeriesOverallLeaderboardPlace(String id) { + super(id); + } + + public EventSeriesOverallLeaderboardPlace(SeriesContext context) { + super(context); + } + + @Prefix(EventPrefixes.EventSeriesOverallLeaderboard) + public static class Tokenizer extends AbstractSeriesPlace.Tokenizer { + @Override + protected EventSeriesOverallLeaderboardPlace getRealPlace(SeriesContext context) { + return new EventSeriesOverallLeaderboardPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesEventsPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesEventsPlace.java new file mode 100644 index 00000000000..eda58630994 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesEventsPlace.java @@ -0,0 +1,26 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries.tabs; + +import com.google.gwt.place.shared.Prefix; +import com.sap.sailing.gwt.home.client.place.event.EventPrefixes; +import com.sap.sailing.gwt.home.client.place.fakeseries.AbstractSeriesPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.AbstractSeriesTabPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesContext; + +public class SeriesEventsPlace extends AbstractSeriesTabPlace { + public SeriesEventsPlace(String id) { + super(id); + } + + public SeriesEventsPlace(SeriesContext context) { + super(context); + } + + @Prefix(EventPrefixes.SeriesEvents) + public static class Tokenizer extends AbstractSeriesPlace.Tokenizer { + + @Override + protected SeriesEventsPlace getRealPlace(SeriesContext context) { + return new SeriesEventsPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesEventsTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesEventsTabView.java new file mode 100644 index 00000000000..76a9686c920 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesEventsTabView.java @@ -0,0 +1,76 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries.tabs; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.place.event.EventDefaultPlace; +import com.sap.sailing.gwt.home.client.place.events.recent.RecentEventTeaser; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesTabView; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesView; +import com.sap.sailing.gwt.ui.shared.general.EventMetadataDTO; +import com.sap.sailing.gwt.ui.shared.general.EventState; + +/** + * Created by pgtaboada on 25.11.14. + */ +public class SeriesEventsTabView extends Composite implements SeriesTabView { + + interface MyBinder extends UiBinder { + } + + private static MyBinder ourUiBinder = GWT.create(MyBinder.class); + private SeriesView.Presenter currentPresenter; + + @UiField FlowPanel eventsContainer; + + public SeriesEventsTabView() { + } + + @Override + public Class getPlaceClassForActivation() { + return SeriesEventsPlace.class; + } + + @Override + public TabView.State getState() { + return TabView.State.VISIBLE; + } + + @Override + public void start(SeriesEventsPlace myPlace, AcceptsOneWidget contentArea) { + initWidget(ourUiBinder.createAndBindUi(this)); + + for (EventMetadataDTO eventOfSeries : currentPresenter.getCtx().getSeriesDTO().getEvents()) { + if(eventOfSeries.getState() == EventState.PLANNED) { + continue; + } + final PlaceNavigation eventNavigation = currentPresenter.getEventNavigation(eventOfSeries.getId()); + RecentEventTeaser eventTeaser = new RecentEventTeaser(eventNavigation, eventOfSeries, eventOfSeries.getState().getStateMarker()); + eventsContainer.add(eventTeaser); + } + + contentArea.setWidget(this); + + } + + @Override + public void stop() { + + } + + @Override + public SeriesEventsPlace placeToFire() { + return new SeriesEventsPlace(currentPresenter.getCtx()); + } + + @Override + public void setPresenter(SeriesView.Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesEventsTabView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesEventsTabView.ui.xml new file mode 100644 index 00000000000..318fb58ea5e --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesEventsTabView.ui.xml @@ -0,0 +1,13 @@ + + + + + .container { + padding-top: 3em; + padding-bottom: 3em; + } + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesMediaPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesMediaPlace.java new file mode 100644 index 00000000000..d10501afecd --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesMediaPlace.java @@ -0,0 +1,26 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries.tabs; + +import com.google.gwt.place.shared.Prefix; +import com.sap.sailing.gwt.home.client.place.event.EventPrefixes; +import com.sap.sailing.gwt.home.client.place.fakeseries.AbstractSeriesPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.AbstractSeriesTabPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesContext; + +public class SeriesMediaPlace extends AbstractSeriesTabPlace { + public SeriesMediaPlace(String id) { + super(id); + } + + public SeriesMediaPlace(SeriesContext context) { + super(context); + } + + @Prefix(EventPrefixes.EventSeriesMedia) + public static class Tokenizer extends AbstractSeriesPlace.Tokenizer { + + @Override + protected SeriesMediaPlace getRealPlace(SeriesContext context) { + return new SeriesMediaPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesMediaTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesMediaTabView.java new file mode 100644 index 00000000000..68d00586e09 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesMediaTabView.java @@ -0,0 +1,78 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries.tabs; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesTabView; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesView; +import com.sap.sailing.gwt.home.client.shared.media.MediaPage; +import com.sap.sailing.gwt.ui.shared.media.MediaDTO; + +public class SeriesMediaTabView extends Composite implements SeriesTabView { + + // TODO delete UiBinder if we do not need it for the new media page implementation + interface MyBinder extends UiBinder { + } + + @SuppressWarnings("unused") + private static MyBinder ourUiBinder = GWT.create(MyBinder.class); + private SeriesView.Presenter currentPresenter; + + public SeriesMediaTabView() { + } + + @Override + public Class getPlaceClassForActivation() { + return SeriesMediaPlace.class; + } + + @Override + public TabView.State getState() { + return TabView.State.INVISIBLE; + // TODO return currentPresenter.hasMedia() ? TabView.State.VISIBLE : TabView.State.INVISIBLE; + } + + @Override + public void start(SeriesMediaPlace myPlace, AcceptsOneWidget contentArea) { + final MediaPage mediaPage = new MediaPage(); + + currentPresenter.ensureMedia(new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + // TODO Auto-generated method stub + + } + + @Override + public void onSuccess(MediaDTO media) { + mediaPage.setMedia(media); + } + }); + + initWidget(mediaPage); + + // TODO do we need UiBinder here? +// initWidget(ourUiBinder.createAndBindUi(this)); + + contentArea.setWidget(this); + } + + @Override + public void stop() { + + } + + @Override + public SeriesMediaPlace placeToFire() { + return new SeriesMediaPlace(currentPresenter.getCtx()); + } + + @Override + public void setPresenter(SeriesView.Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesMediaTabView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesMediaTabView.ui.xml new file mode 100644 index 00000000000..80baf30fc20 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesMediaTabView.ui.xml @@ -0,0 +1,6 @@ + + +

This is the series media tab

+
+
\ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesOverviewPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesOverviewPlace.java new file mode 100644 index 00000000000..06b0567c305 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesOverviewPlace.java @@ -0,0 +1,26 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries.tabs; + +import com.google.gwt.place.shared.Prefix; +import com.sap.sailing.gwt.home.client.place.event.EventPrefixes; +import com.sap.sailing.gwt.home.client.place.fakeseries.AbstractSeriesPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.AbstractSeriesTabPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesContext; + +public class SeriesOverviewPlace extends AbstractSeriesTabPlace { + public SeriesOverviewPlace(String id) { + super(id); + } + + public SeriesOverviewPlace(SeriesContext context) { + super(context); + } + + @Prefix(EventPrefixes.SeriesOverview) + public static class Tokenizer extends AbstractSeriesPlace.Tokenizer { + + @Override + protected SeriesOverviewPlace getRealPlace(SeriesContext context) { + return new SeriesOverviewPlace(context); + } + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesOverviewTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesOverviewTabView.java new file mode 100644 index 00000000000..0a9973c5a69 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesOverviewTabView.java @@ -0,0 +1,57 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries.tabs; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.common.client.controls.tabbar.TabView; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesTabView; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesView; + +public class SeriesOverviewTabView extends Composite implements SeriesTabView { + + interface MyBinder extends UiBinder { + } + + private static MyBinder ourUiBinder = GWT.create(MyBinder.class); + private SeriesView.Presenter currentPresenter; + + public SeriesOverviewTabView() { + } + + @Override + public Class getPlaceClassForActivation() { + return SeriesOverviewPlace.class; + } + + @Override + public TabView.State getState() { + return TabView.State.NOT_AVAILABLE_SHOW_NEXT_AVAILABLE; + } + + @Override + public void start(SeriesOverviewPlace myPlace, AcceptsOneWidget contentArea) { + initWidget(ourUiBinder.createAndBindUi(this)); + + // TODO implement contents + + contentArea.setWidget(this); + + } + + @Override + public void stop() { + + } + + @Override + public SeriesOverviewPlace placeToFire() { + return new SeriesOverviewPlace(currentPresenter.getCtx()); + } + + @Override + public void setPresenter(SeriesView.Presenter currentPresenter) { + this.currentPresenter = currentPresenter; + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesOverviewTabView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesOverviewTabView.ui.xml new file mode 100644 index 00000000000..d78635f45b3 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SeriesOverviewTabView.ui.xml @@ -0,0 +1,13 @@ + + + + + .container { + padding-top: 3em; + padding-bottom: 3em; + } + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SharedLeaderboardEventSeriesTabView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SharedLeaderboardEventSeriesTabView.java new file mode 100644 index 00000000000..55a7547ae25 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/fakeseries/tabs/SharedLeaderboardEventSeriesTabView.java @@ -0,0 +1,44 @@ +package com.sap.sailing.gwt.home.client.place.fakeseries.tabs; + +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.Composite; +import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; +import com.sap.sailing.gwt.home.client.place.event.utils.EventParamUtils; +import com.sap.sailing.gwt.home.client.place.fakeseries.AbstractSeriesTabPlace; +import com.sap.sailing.gwt.home.client.place.fakeseries.EventSeriesAnalyticsDataManager; +import com.sap.sailing.gwt.home.client.place.fakeseries.SeriesTabView; +import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener; +import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel; +import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings; +import com.sap.sailing.gwt.ui.leaderboard.LeaderboardUrlSettings; +import com.sap.sse.gwt.shared.GwtHttpRequestUtils; + +/** + * An abstract series tabView with some shared functions between the overall leaderboard tab and competitors chart tab + */ +public abstract class SharedLeaderboardEventSeriesTabView extends Composite implements SeriesTabView, + LeaderboardUpdateListener { + + public SharedLeaderboardEventSeriesTabView() { + } + + public LeaderboardPanel createSharedLeaderboardPanel(String leaderboardName, EventSeriesAnalyticsDataManager eventSeriesAnalyticsManager) { + boolean autoExpandLastRaceColumn = GwtHttpRequestUtils.getBooleanParameter( + LeaderboardUrlSettings.PARAM_AUTO_EXPAND_LAST_RACE_COLUMN, false); + final LeaderboardSettings leaderboardSettings = EventParamUtils + .createLeaderboardSettingsFromURLParameters(Window.Location + .getParameterMap()); + final RegattaAndRaceIdentifier preselectedRace = EventParamUtils + .getPreselectedRace(Window.Location.getParameterMap()); + LeaderboardPanel leaderboardPanel = eventSeriesAnalyticsManager.createOverallLeaderboardPanel( + leaderboardSettings, + preselectedRace, + "leaderboardGroupName", + leaderboardName, + true, // this information came from place, now hard coded. check with frank + autoExpandLastRaceColumn); + leaderboardPanel.addLeaderboardUpdateListener(this); + return leaderboardPanel; + } +} + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/RegattaActivity.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/RegattaActivity.java deleted file mode 100644 index c9914124b47..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/RegattaActivity.java +++ /dev/null @@ -1,232 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.regatta; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import com.google.gwt.activity.shared.AbstractActivity; -import com.google.gwt.event.shared.EventBus; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.rpc.AsyncCallback; -import com.google.gwt.user.client.ui.AcceptsOneWidget; -import com.sap.sailing.domain.common.DetailType; -import com.sap.sailing.domain.common.LeaderboardType; -import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; -import com.sap.sailing.domain.common.RegattaNameAndRaceName; -import com.sap.sailing.gwt.common.client.i18n.TextMessages; -import com.sap.sailing.gwt.home.client.shared.placeholder.Placeholder; -import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings; -import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings.RaceColumnSelectionStrategies; -import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettingsFactory; -import com.sap.sailing.gwt.ui.leaderboard.LeaderboardUrlSettings; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sse.common.Util; -import com.sap.sse.gwt.client.async.AsyncActionsExecutor; -import com.sap.sse.gwt.client.async.MarkedAsyncCallback; -import com.sap.sse.gwt.client.mvp.ErrorView; -import com.sap.sse.gwt.client.player.Timer; -import com.sap.sse.gwt.client.player.Timer.PlayModes; -import com.sap.sse.gwt.client.player.Timer.PlayStates; -import com.sap.sse.gwt.client.useragent.UserAgentDetails; -import com.sap.sse.gwt.shared.GwtHttpRequestUtils; - -public class RegattaActivity extends AbstractActivity { - private final RegattaClientFactory clientFactory; - private final RegattaPlace regattaPlace; - private final Timer timerForClientServerOffset; - - private final UserAgentDetails userAgent = new UserAgentDetails(Window.Navigator.getUserAgent()); - - public RegattaActivity(RegattaPlace place, RegattaClientFactory clientFactory) { - this.clientFactory = clientFactory; - this.regattaPlace = place; - - timerForClientServerOffset = new Timer(PlayModes.Replay); - } - - @Override - public void start(final AcceptsOneWidget panel, EventBus eventBus) { - panel.setWidget(new Placeholder()); - - UUID eventUUID = UUID.fromString(regattaPlace.getEventUuidAsString()); - final String leaderboardName = regattaPlace.getLeaderboardIdAsNameString(); - final boolean showRaceDetails = regattaPlace.getShowRaceDetails(); - - clientFactory.getSailingService().getEventById(eventUUID, true, new AsyncCallback() { - @Override - public void onSuccess(final EventDTO event) { - if (leaderboardName != null) { - clientFactory.getSailingService().checkLeaderboardName(leaderboardName, new MarkedAsyncCallback>( - new AsyncCallback>() { - @Override - public void onSuccess(Util.Pair leaderboardNameAndType) { - if(leaderboardNameAndType != null && leaderboardName.equals(leaderboardNameAndType.getA())) { - if(leaderboardNameAndType.getB().isMetaLeaderboard()) { - createErrorView("Leaderboard is a meta leaderboard.", null, panel); - } else { - createAnalyticsViewer(panel, event, leaderboardNameAndType.getA(), leaderboardNameAndType.getB(), showRaceDetails); - } - } else { - createErrorView(TextMessages.INSTANCE.errorMessageNoSuchLeaderboard(), null, panel); - } - } - - @Override - public void onFailure(Throwable caught) { - createErrorView("Error while checking the leaderboard name with service checkLeaderboardName()", caught, panel); - } - })); - } else { - createErrorView(TextMessages.INSTANCE.errorMessageNoSuchLeaderboard(), null, panel); - } - } - - @Override - public void onFailure(Throwable caught) { - createErrorView("Error while loading the event with service getEventById()", caught, panel); - } - }); - } - - private void createAnalyticsViewer(AcceptsOneWidget panel, EventDTO event, String leaderboardName, LeaderboardType leaderboardType, boolean showRaceDetails) { - String leaderboardDisplayName = Window.Location.getParameter("displayName"); - if (leaderboardDisplayName == null || leaderboardDisplayName.isEmpty()) { - leaderboardDisplayName = leaderboardName; - } - - long delayBetweenAutoAdvancesInMilliseconds = 3000l; - final RegattaAndRaceIdentifier preselectedRace = getPreselectedRace(Window.Location.getParameterMap()); - // make a single live request as the default but don't continue to play by default - Timer timer = new Timer(PlayModes.Live, PlayStates.Paused, delayBetweenAutoAdvancesInMilliseconds); - final LeaderboardSettings leaderboardSettings = createLeaderboardSettingsFromURLParameters(Window.Location.getParameterMap()); - if (leaderboardSettings.getDelayBetweenAutoAdvancesInMilliseconds() != null) { - timer.setPlayMode(PlayModes.Live); // the leaderboard, viewed via the entry point, goes "live" and "playing" if an auto-refresh - } // interval has been specified - boolean autoExpandLastRaceColumn = GwtHttpRequestUtils.getBooleanParameter(LeaderboardUrlSettings.PARAM_AUTO_EXPAND_LAST_RACE_COLUMN, false); - boolean showOverallLeaderboard = GwtHttpRequestUtils.getBooleanParameter(LeaderboardUrlSettings.PARAM_SHOW_OVERALL_LEADERBOARD, false); - - RegattaAnalyticsView analyticsView = clientFactory.createRegattaAnalyticsView(event, leaderboardName, regattaPlace.getNavigationTab(), timerForClientServerOffset); - Window.setTitle(regattaPlace.getTitle(event.getName(), leaderboardDisplayName)); - - analyticsView.createRegattaAnalyticsViewer(clientFactory.getSailingService(), new AsyncActionsExecutor(), - timer, leaderboardSettings, preselectedRace, "leaderboardGroupName", leaderboardName, clientFactory.getErrorReporter(), - userAgent, showRaceDetails, autoExpandLastRaceColumn, showOverallLeaderboard); - - panel.setWidget(analyticsView.asWidget()); - } - - /** - * Constructs {@link LeaderboardSettings} from the URL parameters found - */ - private LeaderboardSettings createLeaderboardSettingsFromURLParameters(Map> parameterMap) { - LeaderboardSettings result; - Long refreshIntervalMillis = parameterMap.containsKey(LeaderboardUrlSettings.PARAM_REFRESH_INTERVAL_MILLIS) ? Long - .valueOf(parameterMap.get(LeaderboardUrlSettings.PARAM_REFRESH_INTERVAL_MILLIS).get(0)) : null; - RaceColumnSelectionStrategies raceColumnSelectionStrategy; - final Integer numberOfLastRacesToShow; - if (parameterMap.containsKey(LeaderboardUrlSettings.PARAM_NAME_LAST_N)) { - raceColumnSelectionStrategy = RaceColumnSelectionStrategies.LAST_N; - numberOfLastRacesToShow = Integer.valueOf(parameterMap.get(LeaderboardUrlSettings.PARAM_NAME_LAST_N).get(0)); - } else if (isSmallWidth()) { - raceColumnSelectionStrategy = RaceColumnSelectionStrategies.LAST_N; - int width = Window.getClientWidth(); - numberOfLastRacesToShow = (width-275)/40; - } else { - raceColumnSelectionStrategy = RaceColumnSelectionStrategies.EXPLICIT; - numberOfLastRacesToShow = null; - } - if (parameterMap.containsKey(LeaderboardUrlSettings.PARAM_RACE_NAME) || parameterMap.containsKey(LeaderboardUrlSettings.PARAM_RACE_DETAIL) || - parameterMap.containsKey(LeaderboardUrlSettings.PARAM_LEG_DETAIL) || parameterMap.containsKey(LeaderboardUrlSettings.PARAM_MANEUVER_DETAIL) || - parameterMap.containsKey(LeaderboardUrlSettings.PARAM_OVERALL_DETAIL) || parameterMap.containsKey(LeaderboardUrlSettings.PARAM_SHOW_ADDED_SCORES) || - parameterMap.containsKey(LeaderboardUrlSettings.PARAM_SHOW_OVERALL_COLUMN_WITH_NUMBER_OF_RACES_COMPLETED)) { - List maneuverDetails = getDetailTypeListFromParamValue(parameterMap.get(LeaderboardUrlSettings.PARAM_MANEUVER_DETAIL)); - List raceDetails = getDetailTypeListFromParamValue(parameterMap.get(LeaderboardUrlSettings.PARAM_RACE_DETAIL)); - List overallDetails = getDetailTypeListFromParamValue(parameterMap.get(LeaderboardUrlSettings.PARAM_OVERALL_DETAIL)); - if (overallDetails.isEmpty()) { - overallDetails = Collections.singletonList(DetailType.REGATTA_RANK); - } - List legDetails = getDetailTypeListFromParamValue(parameterMap.get(LeaderboardUrlSettings.PARAM_LEG_DETAIL)); - List namesOfRacesToShow = getStringListFromParamValue(parameterMap.get(LeaderboardUrlSettings.PARAM_RACE_NAME)); - boolean showAddedScores = parameterMap.containsKey(LeaderboardUrlSettings.PARAM_SHOW_ADDED_SCORES) ? - Boolean.valueOf(parameterMap.get(LeaderboardUrlSettings.PARAM_SHOW_ADDED_SCORES).get(0)) : false; - boolean showOverallColumnWithNumberOfRacesSailedPerCompetitor = parameterMap.containsKey(LeaderboardUrlSettings.PARAM_SHOW_OVERALL_COLUMN_WITH_NUMBER_OF_RACES_COMPLETED) ? - Boolean.valueOf(parameterMap.get(LeaderboardUrlSettings.PARAM_SHOW_OVERALL_COLUMN_WITH_NUMBER_OF_RACES_COMPLETED).get(0)) : false; - boolean autoExpandPreSelectedRace = parameterMap.containsKey(LeaderboardUrlSettings.PARAM_AUTO_EXPAND_PRESELECTED_RACE) ? - Boolean.valueOf(parameterMap.get(LeaderboardUrlSettings.PARAM_AUTO_EXPAND_PRESELECTED_RACE).get(0)) : - (namesOfRacesToShow != null && namesOfRacesToShow.size() == 1); - boolean showCompetitorSailIdColumn = true; - boolean showCompetitorFullNameColumn = true; - if (parameterMap.containsKey(LeaderboardUrlSettings.PARAM_SHOW_COMPETITOR_NAME_COLUMNS)) { - String value = parameterMap.get(LeaderboardUrlSettings.PARAM_SHOW_COMPETITOR_NAME_COLUMNS).get(0); - if (value.equals(LeaderboardUrlSettings.COMPETITOR_NAME_COLUMN_FULL_NAME)) { - showCompetitorSailIdColumn = false; - } else if (value.equals(LeaderboardUrlSettings.COMPETITOR_NAME_COLUMN_SAIL_ID)) { - showCompetitorFullNameColumn = false; - } else if (value.trim().equals("")) { - showCompetitorFullNameColumn = false; - showCompetitorSailIdColumn = false; - } - } - result = new LeaderboardSettings(maneuverDetails, legDetails, raceDetails, overallDetails, - /* namesOfRaceColumnsToShow */ null, - namesOfRacesToShow, numberOfLastRacesToShow, - autoExpandPreSelectedRace, refreshIntervalMillis, /* sort by column */ (namesOfRacesToShow != null && !namesOfRacesToShow.isEmpty()) ? - namesOfRacesToShow.get(0) : null, - /* ascending */ true, /* updateUponPlayStateChange */ raceDetails.isEmpty() && legDetails.isEmpty(), - raceColumnSelectionStrategy, showAddedScores, showOverallColumnWithNumberOfRacesSailedPerCompetitor, - showCompetitorSailIdColumn, showCompetitorFullNameColumn); - - } else { - final List overallDetails = Collections.singletonList(DetailType.REGATTA_RANK); - result = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, - /* overallDetails */ overallDetails, null, - /* autoExpandFirstRace */false, refreshIntervalMillis, numberOfLastRacesToShow, - raceColumnSelectionStrategy); - } - return result; - } - - private RegattaAndRaceIdentifier getPreselectedRace(Map> parameterMap) { - RegattaAndRaceIdentifier result; - if (parameterMap.containsKey(LeaderboardUrlSettings.PARAM_RACE_NAME) && parameterMap.get(LeaderboardUrlSettings.PARAM_RACE_NAME).size() == 1 && - parameterMap.containsKey(LeaderboardUrlSettings.PARAM_REGATTA_NAME) && parameterMap.get(LeaderboardUrlSettings.PARAM_REGATTA_NAME).size() == 1) { - result = new RegattaNameAndRaceName(parameterMap.get(LeaderboardUrlSettings.PARAM_REGATTA_NAME).get(0), parameterMap.get(LeaderboardUrlSettings.PARAM_RACE_NAME).get(0)); - } else { - result = null; - } - return result; - } - - private List getDetailTypeListFromParamValue(List list) { - List result = new ArrayList(); - if (list != null) { - for (String entry : list) { - try { - result.add(DetailType.valueOf(entry)); - } catch (IllegalArgumentException e) { - } - } - } - return result; - } - - private List getStringListFromParamValue(List list) { - List result = new ArrayList(); - if (list != null) { - result.addAll(list); - } - return result; - } - - private void createErrorView(String errorMessage, Throwable errorReason, AcceptsOneWidget panel) { - ErrorView view = clientFactory.createErrorView(errorMessage, errorReason); - panel.setWidget(view.asWidget()); - } - - public boolean isSmallWidth() { - int width = Window.getClientWidth(); - return width <= 720; - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/RegattaActivityProxy.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/RegattaActivityProxy.java deleted file mode 100644 index e1a718527fb..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/RegattaActivityProxy.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.regatta; - -import com.google.gwt.core.client.GWT; -import com.sap.sse.gwt.client.mvp.AbstractActivityProxy; - -public class RegattaActivityProxy extends AbstractActivityProxy { - - private final RegattaClientFactory clientFactory; - private final RegattaPlace place; - - public RegattaActivityProxy(RegattaPlace place, RegattaClientFactory clientFactory) { - this.place = place; - this.clientFactory = clientFactory; - } - - @Override - protected void startAsync() { - GWT.runAsync(new AbstractRunAsyncCallback() { - @Override - public void onSuccess() { - super.onSuccess(new RegattaActivity(place, clientFactory)); - } - }); - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/RegattaAnalyticsView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/RegattaAnalyticsView.java deleted file mode 100755 index 98bb8a8158b..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/RegattaAnalyticsView.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.regatta; - -import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; -import com.sap.sailing.gwt.ui.client.SailingServiceAsync; -import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings; -import com.sap.sse.gwt.client.ErrorReporter; -import com.sap.sse.gwt.client.async.AsyncActionsExecutor; -import com.sap.sse.gwt.client.player.Timer; -import com.sap.sse.gwt.client.useragent.UserAgentDetails; - -public interface RegattaAnalyticsView { - Widget asWidget(); - - void createRegattaAnalyticsViewer(final SailingServiceAsync sailingService, final AsyncActionsExecutor asyncActionsExecutor, - final Timer timer, final LeaderboardSettings leaderboardSettings, final RegattaAndRaceIdentifier preselectedRace, - final String leaderboardGroupName, String leaderboardName, final ErrorReporter errorReporter, - final UserAgentDetails userAgent, boolean showRaceDetails, - boolean autoExpandLastRaceColumn, boolean showOverallLeaderboard); -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/RegattaClientFactory.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/RegattaClientFactory.java deleted file mode 100644 index 9b064121dc7..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/RegattaClientFactory.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.regatta; - -import com.sap.sailing.gwt.home.client.place.regatta.RegattaPlace.RegattaNavigationTabs; -import com.sap.sailing.gwt.ui.client.SailingClientFactory; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sse.gwt.client.player.Timer; - -public interface RegattaClientFactory extends SailingClientFactory { - RegattaAnalyticsView createRegattaAnalyticsView(EventDTO event, String leaderboardName, RegattaNavigationTabs navigationTab, Timer timerForClientServerOffset); -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/TabletAndDesktopRegattaView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/TabletAndDesktopRegattaView.java deleted file mode 100644 index 13c56e0ca9f..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/TabletAndDesktopRegattaView.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.regatta; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; -import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; -import com.sap.sailing.gwt.home.client.place.event.regattaanalytics.RegattaAnalytics; -import com.sap.sailing.gwt.home.client.place.regatta.RegattaPlace.RegattaNavigationTabs; -import com.sap.sailing.gwt.ui.client.SailingServiceAsync; -import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sse.gwt.client.ErrorReporter; -import com.sap.sse.gwt.client.async.AsyncActionsExecutor; -import com.sap.sse.gwt.client.player.Timer; -import com.sap.sse.gwt.client.useragent.UserAgentDetails; - -public class TabletAndDesktopRegattaView extends Composite implements RegattaAnalyticsView { - private static TabletAndDesktopRegattaViewUiBinder uiBinder = GWT.create(TabletAndDesktopRegattaViewUiBinder.class); - - interface TabletAndDesktopRegattaViewUiBinder extends UiBinder { - } - - @UiField(provided=true) RegattaAnalytics regattaAnalytics; - - public TabletAndDesktopRegattaView(EventDTO event, String leaderboardName, RegattaNavigationTabs navigationTab, Timer timerForClientServerOffset, HomePlacesNavigator placeNavigator) { - regattaAnalytics = new RegattaAnalytics(event, leaderboardName, navigationTab, timerForClientServerOffset, placeNavigator); - - initWidget(uiBinder.createAndBindUi(this)); - - regattaAnalytics.setVisible(false); - } - - public void createRegattaAnalyticsViewer(final SailingServiceAsync sailingService, final AsyncActionsExecutor asyncActionsExecutor, - final Timer timer, final LeaderboardSettings leaderboardSettings, final RegattaAndRaceIdentifier preselectedRace, - final String leaderboardGroupName, String leaderboardName, final ErrorReporter errorReporter, - final UserAgentDetails userAgent, boolean showRaceDetails, - boolean autoExpandLastRaceColumn, boolean showOverallLeaderboard) { - regattaAnalytics.createRegattaAnalyticsViewer(sailingService, asyncActionsExecutor, timer, leaderboardSettings, preselectedRace, - leaderboardGroupName, leaderboardName, errorReporter, userAgent, showRaceDetails, autoExpandLastRaceColumn, showOverallLeaderboard); - regattaAnalytics.setVisible(true); - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/TabletAndDesktopRegattaView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/TabletAndDesktopRegattaView.ui.xml deleted file mode 100644 index a213594e35a..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/regatta/TabletAndDesktopRegattaView.ui.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/searchresult/SearchResultActivity.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/searchresult/SearchResultActivity.java index 968fc8e8580..277f71162b9 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/searchresult/SearchResultActivity.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/searchresult/SearchResultActivity.java @@ -44,10 +44,14 @@ public class SearchResultActivity extends AbstractActivity { panel.setWidget(view.asWidget()); Window.setTitle(searchResultPlace.getTitle()); + doSearch(searchResultPlace.getSearchText()); } protected void doSearch(final String searchText) { + if (searchText == null || searchText.isEmpty()) + return; + final KeywordQuery searchQuery = new KeywordQuery(searchText.split("[ \t]+")); clientFactory.getSailingService().getSearchServerNames(new AsyncCallback>() { @Override diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/SeriesActivity.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/SeriesActivity.java deleted file mode 100644 index c334e748a1f..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/SeriesActivity.java +++ /dev/null @@ -1,233 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.series; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import com.google.gwt.activity.shared.AbstractActivity; -import com.google.gwt.event.shared.EventBus; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.rpc.AsyncCallback; -import com.google.gwt.user.client.ui.AcceptsOneWidget; -import com.sap.sailing.domain.common.DetailType; -import com.sap.sailing.domain.common.LeaderboardType; -import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; -import com.sap.sailing.domain.common.RegattaNameAndRaceName; -import com.sap.sailing.gwt.common.client.i18n.TextMessages; -import com.sap.sailing.gwt.home.client.shared.placeholder.Placeholder; -import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings; -import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings.RaceColumnSelectionStrategies; -import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettingsFactory; -import com.sap.sailing.gwt.ui.leaderboard.LeaderboardUrlSettings; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sse.common.Util; -import com.sap.sse.gwt.client.async.AsyncActionsExecutor; -import com.sap.sse.gwt.client.async.MarkedAsyncCallback; -import com.sap.sse.gwt.client.mvp.ErrorView; -import com.sap.sse.gwt.client.player.Timer; -import com.sap.sse.gwt.client.player.Timer.PlayModes; -import com.sap.sse.gwt.client.player.Timer.PlayStates; -import com.sap.sse.gwt.client.useragent.UserAgentDetails; -import com.sap.sse.gwt.shared.GwtHttpRequestUtils; - -public class SeriesActivity extends AbstractActivity { - private final SeriesClientFactory clientFactory; - private final SeriesPlace seriesPlace; - private final Timer timerForClientServerOffset; - - private final UserAgentDetails userAgent = new UserAgentDetails(Window.Navigator.getUserAgent()); - - public SeriesActivity(SeriesPlace place, SeriesClientFactory clientFactory) { - this.clientFactory = clientFactory; - this.seriesPlace = place; - - timerForClientServerOffset = new Timer(PlayModes.Replay); - } - - @Override - public void start(final AcceptsOneWidget panel, EventBus eventBus) { - panel.setWidget(new Placeholder()); - - UUID eventUUID = UUID.fromString(seriesPlace.getEventUuidAsString()); - final String leaderboardName = seriesPlace.getLeaderboardIdAsNameString(); - final boolean showRaceDetails = seriesPlace.getShowRaceDetails(); - - clientFactory.getSailingService().getEventById(eventUUID, true, new AsyncCallback() { - @Override - public void onSuccess(final EventDTO event) { - if (leaderboardName != null) { - clientFactory.getSailingService().checkLeaderboardName(leaderboardName, new MarkedAsyncCallback>( - new AsyncCallback>() { - @Override - public void onSuccess(Util.Pair leaderboardNameAndType) { - if(leaderboardNameAndType != null && leaderboardName.equals(leaderboardNameAndType.getA())) { - if(!leaderboardNameAndType.getB().isMetaLeaderboard()) { - createErrorView("Leaderboard is a not meta leaderboard.", null, panel); - } else { - createAnalyticsViewer(panel, event, leaderboardNameAndType.getA(), leaderboardNameAndType.getB(), showRaceDetails); - } - } else { - createErrorView(TextMessages.INSTANCE.errorMessageNoSuchLeaderboard(), null, panel); - } - } - - @Override - public void onFailure(Throwable caught) { - createErrorView("Error while checking the leaderboard name with service checkLeaderboardName()", caught, panel); - } - })); - } else { - createErrorView(TextMessages.INSTANCE.errorMessageNoSuchLeaderboard(), null, panel); - } - } - - @Override - public void onFailure(Throwable caught) { - createErrorView("Error while loading the event with service getEventById()", caught, panel); - } - }); - } - - private void createAnalyticsViewer(AcceptsOneWidget panel, EventDTO event, String leaderboardName, LeaderboardType leaderboardType, boolean showRaceDetails) { - String leaderboardDisplayName = Window.Location.getParameter("displayName"); - if (leaderboardDisplayName == null || leaderboardDisplayName.isEmpty()) { - leaderboardDisplayName = leaderboardName; - } - - long delayBetweenAutoAdvancesInMilliseconds = 3000l; - final RegattaAndRaceIdentifier preselectedRace = getPreselectedRace(Window.Location.getParameterMap()); - // make a single live request as the default but don't continue to play by default - Timer timer = new Timer(PlayModes.Live, PlayStates.Paused, delayBetweenAutoAdvancesInMilliseconds); - final LeaderboardSettings leaderboardSettings = createLeaderboardSettingsFromURLParameters(Window.Location.getParameterMap()); - if (leaderboardSettings.getDelayBetweenAutoAdvancesInMilliseconds() != null) { - timer.setPlayMode(PlayModes.Live); // the leaderboard, viewed via the entry point, goes "live" and "playing" if an auto-refresh - } // interval has been specified - boolean autoExpandLastRaceColumn = GwtHttpRequestUtils.getBooleanParameter(LeaderboardUrlSettings.PARAM_AUTO_EXPAND_LAST_RACE_COLUMN, false); - boolean showSeriesLeaderboards = GwtHttpRequestUtils.getBooleanParameter(LeaderboardUrlSettings.PARAM_SHOW_SERIES_LEADERBOARDS, false); - - SeriesAnalyticsView analyticsView = clientFactory.createSeriesAnalyticsView(event, leaderboardName, - seriesPlace.getNavigationTab(), timerForClientServerOffset); - Window.setTitle(seriesPlace.getTitle(event.getName(), leaderboardDisplayName)); - - analyticsView.createSeriesAnalyticsViewer(clientFactory.getSailingService(), new AsyncActionsExecutor(), - timer, leaderboardSettings, null, preselectedRace, "leaderboardGroupName", leaderboardName, clientFactory.getErrorReporter(), - userAgent, showRaceDetails, autoExpandLastRaceColumn, showSeriesLeaderboards); - - panel.setWidget(analyticsView.asWidget()); - } - - /** - * Constructs {@link LeaderboardSettings} from the URL parameters found - */ - private LeaderboardSettings createLeaderboardSettingsFromURLParameters(Map> parameterMap) { - LeaderboardSettings result; - Long refreshIntervalMillis = parameterMap.containsKey(LeaderboardUrlSettings.PARAM_REFRESH_INTERVAL_MILLIS) ? Long - .valueOf(parameterMap.get(LeaderboardUrlSettings.PARAM_REFRESH_INTERVAL_MILLIS).get(0)) : null; - RaceColumnSelectionStrategies raceColumnSelectionStrategy; - final Integer numberOfLastRacesToShow; - if (parameterMap.containsKey(LeaderboardUrlSettings.PARAM_NAME_LAST_N)) { - raceColumnSelectionStrategy = RaceColumnSelectionStrategies.LAST_N; - numberOfLastRacesToShow = Integer.valueOf(parameterMap.get(LeaderboardUrlSettings.PARAM_NAME_LAST_N).get(0)); - } else if (isSmallWidth()) { - raceColumnSelectionStrategy = RaceColumnSelectionStrategies.LAST_N; - int width = Window.getClientWidth(); - numberOfLastRacesToShow = (width-275)/40; - } else { - raceColumnSelectionStrategy = RaceColumnSelectionStrategies.EXPLICIT; - numberOfLastRacesToShow = null; - } - if (parameterMap.containsKey(LeaderboardUrlSettings.PARAM_RACE_NAME) || parameterMap.containsKey(LeaderboardUrlSettings.PARAM_RACE_DETAIL) || - parameterMap.containsKey(LeaderboardUrlSettings.PARAM_LEG_DETAIL) || parameterMap.containsKey(LeaderboardUrlSettings.PARAM_MANEUVER_DETAIL) || - parameterMap.containsKey(LeaderboardUrlSettings.PARAM_OVERALL_DETAIL) || parameterMap.containsKey(LeaderboardUrlSettings.PARAM_SHOW_ADDED_SCORES) || - parameterMap.containsKey(LeaderboardUrlSettings.PARAM_SHOW_OVERALL_COLUMN_WITH_NUMBER_OF_RACES_COMPLETED)) { - List maneuverDetails = getDetailTypeListFromParamValue(parameterMap.get(LeaderboardUrlSettings.PARAM_MANEUVER_DETAIL)); - List raceDetails = getDetailTypeListFromParamValue(parameterMap.get(LeaderboardUrlSettings.PARAM_RACE_DETAIL)); - List overallDetails = getDetailTypeListFromParamValue(parameterMap.get(LeaderboardUrlSettings.PARAM_OVERALL_DETAIL)); - if (overallDetails.isEmpty()) { - overallDetails = Collections.singletonList(DetailType.REGATTA_RANK); - } - List legDetails = getDetailTypeListFromParamValue(parameterMap.get(LeaderboardUrlSettings.PARAM_LEG_DETAIL)); - List namesOfRacesToShow = getStringListFromParamValue(parameterMap.get(LeaderboardUrlSettings.PARAM_RACE_NAME)); - boolean showAddedScores = parameterMap.containsKey(LeaderboardUrlSettings.PARAM_SHOW_ADDED_SCORES) ? - Boolean.valueOf(parameterMap.get(LeaderboardUrlSettings.PARAM_SHOW_ADDED_SCORES).get(0)) : false; - boolean showOverallColumnWithNumberOfRacesSailedPerCompetitor = parameterMap.containsKey(LeaderboardUrlSettings.PARAM_SHOW_OVERALL_COLUMN_WITH_NUMBER_OF_RACES_COMPLETED) ? - Boolean.valueOf(parameterMap.get(LeaderboardUrlSettings.PARAM_SHOW_OVERALL_COLUMN_WITH_NUMBER_OF_RACES_COMPLETED).get(0)) : false; - boolean autoExpandPreSelectedRace = parameterMap.containsKey(LeaderboardUrlSettings.PARAM_AUTO_EXPAND_PRESELECTED_RACE) ? - Boolean.valueOf(parameterMap.get(LeaderboardUrlSettings.PARAM_AUTO_EXPAND_PRESELECTED_RACE).get(0)) : - (namesOfRacesToShow != null && namesOfRacesToShow.size() == 1); - boolean showCompetitorSailIdColumn = true; - boolean showCompetitorFullNameColumn = true; - if (parameterMap.containsKey(LeaderboardUrlSettings.PARAM_SHOW_COMPETITOR_NAME_COLUMNS)) { - String value = parameterMap.get(LeaderboardUrlSettings.PARAM_SHOW_COMPETITOR_NAME_COLUMNS).get(0); - if (value.equals(LeaderboardUrlSettings.COMPETITOR_NAME_COLUMN_FULL_NAME)) { - showCompetitorSailIdColumn = false; - } else if (value.equals(LeaderboardUrlSettings.COMPETITOR_NAME_COLUMN_SAIL_ID)) { - showCompetitorFullNameColumn = false; - } else if (value.trim().equals("")) { - showCompetitorFullNameColumn = false; - showCompetitorSailIdColumn = false; - } - } - result = new LeaderboardSettings(maneuverDetails, legDetails, raceDetails, overallDetails, - /* namesOfRaceColumnsToShow */ null, - namesOfRacesToShow, numberOfLastRacesToShow, - autoExpandPreSelectedRace, refreshIntervalMillis, /* sort by column */ (namesOfRacesToShow != null && !namesOfRacesToShow.isEmpty()) ? - namesOfRacesToShow.get(0) : null, - /* ascending */ true, /* updateUponPlayStateChange */ raceDetails.isEmpty() && legDetails.isEmpty(), - raceColumnSelectionStrategy, showAddedScores, showOverallColumnWithNumberOfRacesSailedPerCompetitor, - showCompetitorSailIdColumn, showCompetitorFullNameColumn); - - } else { - final List overallDetails = Collections.singletonList(DetailType.REGATTA_RANK); - result = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, - /* overallDetails */ overallDetails, null, - /* autoExpandFirstRace */false, refreshIntervalMillis, numberOfLastRacesToShow, - raceColumnSelectionStrategy); - } - return result; - } - - private RegattaAndRaceIdentifier getPreselectedRace(Map> parameterMap) { - RegattaAndRaceIdentifier result; - if (parameterMap.containsKey(LeaderboardUrlSettings.PARAM_RACE_NAME) && parameterMap.get(LeaderboardUrlSettings.PARAM_RACE_NAME).size() == 1 && - parameterMap.containsKey(LeaderboardUrlSettings.PARAM_REGATTA_NAME) && parameterMap.get(LeaderboardUrlSettings.PARAM_REGATTA_NAME).size() == 1) { - result = new RegattaNameAndRaceName(parameterMap.get(LeaderboardUrlSettings.PARAM_REGATTA_NAME).get(0), parameterMap.get(LeaderboardUrlSettings.PARAM_RACE_NAME).get(0)); - } else { - result = null; - } - return result; - } - - private List getDetailTypeListFromParamValue(List list) { - List result = new ArrayList(); - if (list != null) { - for (String entry : list) { - try { - result.add(DetailType.valueOf(entry)); - } catch (IllegalArgumentException e) { - } - } - } - return result; - } - - private List getStringListFromParamValue(List list) { - List result = new ArrayList(); - if (list != null) { - result.addAll(list); - } - return result; - } - - private void createErrorView(String errorMessage, Throwable errorReason, AcceptsOneWidget panel) { - ErrorView view = clientFactory.createErrorView(errorMessage, errorReason); - panel.setWidget(view.asWidget()); - } - - public boolean isSmallWidth() { - int width = Window.getClientWidth(); - return width <= 720; - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/SeriesActivityProxy.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/SeriesActivityProxy.java deleted file mode 100644 index fc85427f6b8..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/SeriesActivityProxy.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.series; - -import com.google.gwt.core.client.GWT; -import com.sap.sse.gwt.client.mvp.AbstractActivityProxy; - -public class SeriesActivityProxy extends AbstractActivityProxy { - - private final SeriesClientFactory clientFactory; - private final SeriesPlace place; - - public SeriesActivityProxy(SeriesPlace place, SeriesClientFactory clientFactory) { - this.place = place; - this.clientFactory = clientFactory; - } - - @Override - protected void startAsync() { - GWT.runAsync(new AbstractRunAsyncCallback() { - @Override - public void onSuccess() { - super.onSuccess(new SeriesActivity(place, clientFactory)); - } - }); - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/SeriesAnalyticsView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/SeriesAnalyticsView.java deleted file mode 100644 index 55668d8eb6c..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/SeriesAnalyticsView.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.series; - -import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; -import com.sap.sailing.gwt.ui.client.SailingServiceAsync; -import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings; -import com.sap.sse.gwt.client.ErrorReporter; -import com.sap.sse.gwt.client.async.AsyncActionsExecutor; -import com.sap.sse.gwt.client.player.Timer; -import com.sap.sse.gwt.client.useragent.UserAgentDetails; - -public interface SeriesAnalyticsView { - Widget asWidget(); - - void createSeriesAnalyticsViewer(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor, - Timer timer, LeaderboardSettings leaderboardSettings, String preselectedLeaderboardName, RegattaAndRaceIdentifier preselectedRace, - String leaderboardGroupName, String metaLeaderboardName, ErrorReporter errorReporter, - UserAgentDetails userAgent, boolean showRaceDetails, - boolean autoExpandLastRaceColumn, boolean showSeriesLeaderboards); -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/SeriesClientFactory.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/SeriesClientFactory.java deleted file mode 100644 index 0ede6be3e5f..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/SeriesClientFactory.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.series; - -import com.sap.sailing.gwt.home.client.place.series.SeriesPlace.SeriesNavigationTabs; -import com.sap.sailing.gwt.ui.client.SailingClientFactory; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sse.gwt.client.player.Timer; - -public interface SeriesClientFactory extends SailingClientFactory { - SeriesAnalyticsView createSeriesAnalyticsView(EventDTO event, String leaderboardName, SeriesNavigationTabs navigationTab, Timer timerForClientServerOffset); -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/TabletAndDesktopSeriesView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/TabletAndDesktopSeriesView.java deleted file mode 100755 index 05faff70aee..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/TabletAndDesktopSeriesView.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.sap.sailing.gwt.home.client.place.series; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.uibinder.client.UiBinder; -import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; -import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; -import com.sap.sailing.gwt.home.client.place.event.seriesanalytics.EventSeriesAnalytics; -import com.sap.sailing.gwt.home.client.place.series.SeriesPlace.SeriesNavigationTabs; -import com.sap.sailing.gwt.ui.client.SailingServiceAsync; -import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings; -import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sse.gwt.client.ErrorReporter; -import com.sap.sse.gwt.client.async.AsyncActionsExecutor; -import com.sap.sse.gwt.client.player.Timer; -import com.sap.sse.gwt.client.useragent.UserAgentDetails; - -public class TabletAndDesktopSeriesView extends Composite implements SeriesAnalyticsView { - private static TabletAndDesktopSeriesViewUiBinder uiBinder = GWT.create(TabletAndDesktopSeriesViewUiBinder.class); - - interface TabletAndDesktopSeriesViewUiBinder extends UiBinder { - } - - @UiField(provided=true) EventSeriesAnalytics seriesAnalytics; - - public TabletAndDesktopSeriesView(EventDTO event, String leaderboardName, SeriesNavigationTabs navigationTab, Timer timerForClientServerOffset, HomePlacesNavigator placeNavigator) { - seriesAnalytics = new EventSeriesAnalytics(event, leaderboardName, navigationTab, timerForClientServerOffset, placeNavigator); - - initWidget(uiBinder.createAndBindUi(this)); - - seriesAnalytics.setVisible(false); - } - - public void createSeriesAnalyticsViewer(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor, - Timer timer, LeaderboardSettings leaderboardSettings, String preselectedLeaderboardName, RegattaAndRaceIdentifier preselectedRace, - String leaderboardGroupName, String metaLeaderboardName, ErrorReporter errorReporter, - UserAgentDetails userAgent, boolean showRaceDetails, boolean autoExpandLastRaceColumn, boolean showSeriesLeaderboards) { - seriesAnalytics.createSeriesAnalyticsViewer(sailingService, asyncActionsExecutor, timer, leaderboardSettings, preselectedLeaderboardName, - preselectedRace, leaderboardGroupName, metaLeaderboardName, errorReporter, userAgent, showRaceDetails, autoExpandLastRaceColumn, showSeriesLeaderboards); - seriesAnalytics.setVisible(true); - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/TabletAndDesktopSeriesView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/TabletAndDesktopSeriesView.ui.xml deleted file mode 100644 index 7cda0a091f7..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/series/TabletAndDesktopSeriesView.ui.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/SmartphoneStartView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/SmartphoneStartView.java index e2f9d402274..349cf11f8a6 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/SmartphoneStartView.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/SmartphoneStartView.java @@ -1,7 +1,5 @@ package com.sap.sailing.gwt.home.client.place.start; -import java.util.List; - import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; @@ -12,9 +10,7 @@ import com.sap.sailing.gwt.home.client.shared.mainevents.MainEvents; import com.sap.sailing.gwt.home.client.shared.mainmedia.MainMedia; import com.sap.sailing.gwt.home.client.shared.mainsponsors.MainSponsors; import com.sap.sailing.gwt.home.client.shared.stage.Stage; -import com.sap.sailing.gwt.home.client.shared.stage.StageEventType; -import com.sap.sailing.gwt.ui.shared.EventBaseDTO; -import com.sap.sse.common.Util.Pair; +import com.sap.sailing.gwt.ui.shared.start.StartViewDTO; public class SmartphoneStartView extends Composite implements StartView { private static StartPageMobileViewUiBinder uiBinder = GWT.create(StartPageMobileViewUiBinder.class); @@ -34,15 +30,11 @@ public class SmartphoneStartView extends Composite implements StartView { mainMedia = new MainMedia(navigator); initWidget(uiBinder.createAndBindUi(this)); } - + @Override - public void setFeaturedEvents(List> featuredEvents) { - stage.setFeaturedEvents(featuredEvents); - } - - @Override - public void setRecentEvents(List recentEvents) { - mainEvents.setRecentEvents(recentEvents); - mainMedia.setRecentEvents(recentEvents); + public void setData(StartViewDTO data) { + stage.setFeaturedEvents(data.getStageEvents()); + mainEvents.setRecentEvents(data.getRecentEvents()); + mainMedia.setData(data.getVideos(), data.getPhotos()); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/StartActivity.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/StartActivity.java index db08e420d23..a9ada23b8a2 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/StartActivity.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/StartActivity.java @@ -1,24 +1,12 @@ package com.sap.sailing.gwt.home.client.place.start; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - import com.google.gwt.activity.shared.AbstractActivity; import com.google.gwt.event.shared.EventBus; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.AcceptsOneWidget; import com.sap.sailing.gwt.home.client.shared.placeholder.Placeholder; -import com.sap.sailing.gwt.home.client.shared.stage.StageEventType; -import com.sap.sailing.gwt.ui.shared.EventBaseDTO; -import com.sap.sse.common.Duration; -import com.sap.sse.common.TimePoint; -import com.sap.sse.common.TimeRange; -import com.sap.sse.common.Util.Pair; -import com.sap.sse.common.impl.MillisecondsTimePoint; -import com.sap.sse.common.impl.TimeRangeImpl; +import com.sap.sailing.gwt.ui.shared.start.StartViewDTO; public class StartActivity extends AbstractActivity { private final StartClientFactory clientFactory; @@ -32,70 +20,21 @@ public class StartActivity extends AbstractActivity { @Override public void start(final AcceptsOneWidget panel, EventBus eventBus) { panel.setWidget(new Placeholder()); - clientFactory.getSailingService().getPublicEventsOfAllSailingServers(new AsyncCallback>() { + clientFactory.getHomeService().getStartView(new AsyncCallback() { + @Override - public void onSuccess(List result) { + public void onFailure(Throwable caught) { + // TODO Auto-generated method stub + + } + + @Override + public void onSuccess(StartViewDTO result) { final StartView view = clientFactory.createStartView(); panel.setWidget(view.asWidget()); Window.setTitle(place.getTitle()); - fillStartPageEvents(view, result); - } - - @Override - public void onFailure(Throwable caught) { + view.setData(result); } }); } - - protected void fillStartPageEvents(final StartView view, List events) { - List> featuredEvents = new ArrayList>(); - List recentEventsOfLast12Month = new ArrayList(); - TimePoint now = MillisecondsTimePoint.now(); - final int MAX_STAGE_EVENTS = 5; - for (EventBaseDTO event : events) { - if (event.startDate != null && event.endDate != null) { - if (now.after(new MillisecondsTimePoint(event.startDate)) && now.before(new MillisecondsTimePoint(event.endDate))) { - featuredEvents.add(new Pair(StageEventType.RUNNING, event)); - } else if (new MillisecondsTimePoint(event.startDate).after(now) && - new MillisecondsTimePoint(event.startDate).before(now.plus(Duration.ONE_WEEK.times(4)))) { - featuredEvents.add(new Pair(StageEventType.UPCOMING_SOON, event)); - } else if (new MillisecondsTimePoint(event.endDate).before(now) && - new MillisecondsTimePoint(event.endDate).after(now.minus(Duration.ONE_YEAR))) { - recentEventsOfLast12Month.add(event); - featuredEvents.add(new Pair(StageEventType.POPULAR, event)); - } - } - } - Collections.sort(featuredEvents, new FeaturedEventsComparator()); - if(featuredEvents.size() > MAX_STAGE_EVENTS) { - featuredEvents = featuredEvents.subList(0, MAX_STAGE_EVENTS); - } - view.setFeaturedEvents(featuredEvents); - Collections.sort(recentEventsOfLast12Month, new Comparator() { - @Override - public int compare(EventBaseDTO o1, EventBaseDTO o2) { - final long diff = o2.endDate.getTime() - o1.endDate.getTime(); - return diff > 0l ? 1 : diff < 0l ? -1 : 0; - } - }); - view.setRecentEvents(recentEventsOfLast12Month); - } - - /** - * Sorts events by their time-wise distance from the current point in time. - * - * @author Frank - * @author Axel Uhl - */ - private class FeaturedEventsComparator implements Comparator> { - @Override - public int compare(Pair eventAndStageType1, - Pair eventAndStageType2) { - TimePoint now = MillisecondsTimePoint.now(); - TimeRange event1Range = new TimeRangeImpl(new MillisecondsTimePoint(eventAndStageType1.getB().startDate), new MillisecondsTimePoint(eventAndStageType1.getB().endDate)); - TimeRange event2Range = new TimeRangeImpl(new MillisecondsTimePoint(eventAndStageType2.getB().startDate), new MillisecondsTimePoint(eventAndStageType2.getB().endDate)); - return event1Range.timeDifference(now).compareTo(event2Range.timeDifference(now)); - } - } - } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/StartView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/StartView.java index 89ef4422020..c0c7cd9392c 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/StartView.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/StartView.java @@ -1,16 +1,10 @@ package com.sap.sailing.gwt.home.client.place.start; -import java.util.List; - import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.gwt.home.client.shared.stage.StageEventType; -import com.sap.sailing.gwt.ui.shared.EventBaseDTO; -import com.sap.sse.common.Util.Pair; +import com.sap.sailing.gwt.ui.shared.start.StartViewDTO; public interface StartView { Widget asWidget(); - void setFeaturedEvents(List> featuredEvents); - - void setRecentEvents(List recentEvents); + void setData(StartViewDTO data); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/TabletAndDesktopStartView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/TabletAndDesktopStartView.java index ba6dd2c51da..60b9b6700f3 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/TabletAndDesktopStartView.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/start/TabletAndDesktopStartView.java @@ -1,7 +1,5 @@ package com.sap.sailing.gwt.home.client.place.start; -import java.util.List; - import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; @@ -11,9 +9,7 @@ import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; import com.sap.sailing.gwt.home.client.shared.mainevents.MainEvents; import com.sap.sailing.gwt.home.client.shared.mainmedia.MainMedia; import com.sap.sailing.gwt.home.client.shared.stage.Stage; -import com.sap.sailing.gwt.home.client.shared.stage.StageEventType; -import com.sap.sailing.gwt.ui.shared.EventBaseDTO; -import com.sap.sse.common.Util.Pair; +import com.sap.sailing.gwt.ui.shared.start.StartViewDTO; public class TabletAndDesktopStartView extends Composite implements StartView { private static StartPageViewUiBinder uiBinder = GWT.create(StartPageViewUiBinder.class); @@ -34,16 +30,11 @@ public class TabletAndDesktopStartView extends Composite implements StartView { initWidget(uiBinder.createAndBindUi(this)); } - + @Override - public void setFeaturedEvents(List> featuredEvents) { - stage.setFeaturedEvents(featuredEvents); - mainMedia.setFeaturedEvents(featuredEvents); - } - - @Override - public void setRecentEvents(List recentEvents) { - mainEvents.setRecentEvents(recentEvents); - mainMedia.setRecentEvents(recentEvents); + public void setData(StartViewDTO data) { + stage.setFeaturedEvents(data.getStageEvents()); + mainEvents.setRecentEvents(data.getRecentEvents()); + mainMedia.setData(data.getVideos(), data.getPhotos()); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/whatsnew/TabletAndDesktopWhatsNewView.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/whatsnew/TabletAndDesktopWhatsNewView.java index 2580ee1b10c..b8d16132f99 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/whatsnew/TabletAndDesktopWhatsNewView.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/whatsnew/TabletAndDesktopWhatsNewView.java @@ -28,15 +28,15 @@ public class TabletAndDesktopWhatsNewView extends Composite implements WhatsNewV private static final HyperlinkImpl HYPERLINK_IMPL = GWT.create(HyperlinkImpl.class); @UiField HTML sailingAnalyticsNotes; -// @UiField HTML sailingSimulatorNotes; + @UiField HTML sailingSimulatorNotes; @UiField HTML raceCommitteeAppNotes; @UiField Anchor sailingAnalyticsNotesAnchor; -// @UiField Anchor sailingSimulatorNotesAnchor; + @UiField Anchor sailingSimulatorNotesAnchor; @UiField Anchor raceCommitteeAppNotesAnchor; private final PlaceNavigation sailingAnalyticNotesNavigation; -// private final PlaceNavigation sailingSimulatorNoteNavigation; + private final PlaceNavigation sailingSimulatorNoteNavigation; private final PlaceNavigation raceCommitteeAppNotesNavigation; private final List links; @@ -49,19 +49,19 @@ public class TabletAndDesktopWhatsNewView extends Composite implements WhatsNewV initWidget(uiBinder.createAndBindUi(this)); sailingAnalyticsNotes.setHTML(WhatsNewResources.INSTANCE.getSailingAnalyticsNotesHtml().getText()); -// sailingSimulatorNotes.setHTML(WhatsNewResources.INSTANCE.getSailingSimulatorNotesHtml().getText()); + sailingSimulatorNotes.setHTML(WhatsNewResources.INSTANCE.getSailingSimulatorNotesHtml().getText()); raceCommitteeAppNotes.setHTML(WhatsNewResources.INSTANCE.getRaceCommitteeAppNotesHtml().getText()); sailingAnalyticNotesNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingAnalytics); -// sailingSimulatorNoteNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingSimulator); + sailingSimulatorNoteNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingSimulator); raceCommitteeAppNotesNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.RaceCommiteeApp); sailingAnalyticsNotesAnchor.setHref(sailingAnalyticNotesNavigation.getTargetUrl()); -// sailingSimulatorNotesAnchor.setHref(sailingSimulatorNoteNavigation.getTargetUrl()); + sailingSimulatorNotesAnchor.setHref(sailingSimulatorNoteNavigation.getTargetUrl()); raceCommitteeAppNotesAnchor.setHref(raceCommitteeAppNotesNavigation.getTargetUrl()); - links = Arrays.asList(new Anchor[] { sailingAnalyticsNotesAnchor, /*sailingSimulatorNotesAnchor,*/ raceCommitteeAppNotesAnchor }); - contentWidgets = Arrays.asList(new HTML[] { sailingAnalyticsNotes, /*sailingSimulatorNotes,*/ raceCommitteeAppNotes }); + links = Arrays.asList(new Anchor[] { sailingAnalyticsNotesAnchor, sailingSimulatorNotesAnchor, raceCommitteeAppNotesAnchor }); + contentWidgets = Arrays.asList(new HTML[] { sailingAnalyticsNotes, sailingSimulatorNotes, raceCommitteeAppNotes }); switch(navigationTab) { case PostRaceAnalytics: @@ -73,7 +73,7 @@ public class TabletAndDesktopWhatsNewView extends Composite implements WhatsNewV setActiveContent(sailingAnalyticsNotes, sailingAnalyticsNotesAnchor); break; case SailingSimulator: -// setActiveContent(sailingSimulatorNotes, sailingSimulatorNotesAnchor); + setActiveContent(sailingSimulatorNotes, sailingSimulatorNotesAnchor); break; case TrainingDiary: break; @@ -85,13 +85,13 @@ public class TabletAndDesktopWhatsNewView extends Composite implements WhatsNewV setActiveContent(sailingAnalyticsNotes, sailingAnalyticsNotesAnchor); handleClickEventWithLocalNavigation(event, sailingAnalyticNotesNavigation); } -/* + @UiHandler("sailingSimulatorNotesAnchor") void featuresClicked(ClickEvent event) { setActiveContent(sailingSimulatorNotes, sailingSimulatorNotesAnchor); handleClickEventWithLocalNavigation(event, sailingSimulatorNoteNavigation); } -*/ + @UiHandler("raceCommitteeAppNotesAnchor") void releaseNotesClicked(ClickEvent event) { setActiveContent(raceCommitteeAppNotes, raceCommitteeAppNotesAnchor); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/whatsnew/TabletAndDesktopWhatsNewView.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/whatsnew/TabletAndDesktopWhatsNewView.ui.xml index ab4456dd416..5d08455b78a 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/whatsnew/TabletAndDesktopWhatsNewView.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/whatsnew/TabletAndDesktopWhatsNewView.ui.xml @@ -7,22 +7,18 @@
-
+
- +
-
+
-
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/LabelTypeUtil.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/LabelTypeUtil.java new file mode 100644 index 00000000000..09d06461003 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/LabelTypeUtil.java @@ -0,0 +1,18 @@ +package com.sap.sailing.gwt.home.client.shared; + +import com.google.gwt.dom.client.Element; +import com.sap.sailing.gwt.ui.shared.general.LabelType; + +public final class LabelTypeUtil { + private LabelTypeUtil() { + } + + public static void renderLabelType(Element labelElement, LabelType labelType) { + if(labelType == null || !labelType.isRendered()) { + labelElement.removeFromParent(); + return; + } + labelElement.setInnerText(labelType.getLabel()); + labelElement.setAttribute("data-labeltype", labelType.getLabelType()); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/error/ErrorMessage.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/error/ErrorMessage.css index 797f79e0d8b..b5ccb421b93 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/error/ErrorMessage.css +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/error/ErrorMessage.css @@ -8,8 +8,10 @@ } .error_message_detail { font-size: 15px; + margin-top: 20px; } .reload_page_message { font-size: 20px; margin-right: 20px; + margin-bottom: 20px; } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/error/ErrorMessage.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/error/ErrorMessage.java index b93ea9db87a..a18dbbefea2 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/error/ErrorMessage.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/error/ErrorMessage.java @@ -6,6 +6,7 @@ import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; +import com.google.gwt.user.client.Command; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Composite; @@ -22,19 +23,37 @@ public class ErrorMessage extends Composite { @UiField DivElement errorMessage; @UiField DivElement errorMessageDetail; @UiField Anchor reloadPageAnchor; + + private Command reloadCommand; + + public ErrorMessage(String errorMessageDetail, Throwable errorReason, Command reloadCommand) { + this(TextMessages.INSTANCE.errorMessageLoadingData(), errorMessageDetail, errorReason, reloadCommand); + + } - public ErrorMessage(String detailMessage, Throwable errorReason) { + public ErrorMessage(String errorMessage, String errorMessageDetail, Throwable errorReason, Command reloadCommand) { ErrorMessageResources.INSTANCE.css().ensureInjected(); initWidget(uiBinder.createAndBindUi(this)); - + this.reloadCommand = reloadCommand; this.setHeight(Window.getClientHeight() + "px"); - errorMessage.setInnerText(TextMessages.INSTANCE.errorMessageLoadingData()); - Window.setStatus(detailMessage); + if (errorMessage != null && !errorMessage.isEmpty()) { + this.errorMessage.setInnerText(errorMessage); + } else { + this.errorMessage.setInnerText(TextMessages.INSTANCE.errorMessageLoadingData()); + } + + this.errorMessageDetail.setInnerText(errorMessageDetail); + Window.setStatus(errorMessageDetail); } @UiHandler("reloadPageAnchor") void reloadPage(ClickEvent e) { - Window.Location.reload(); + if (reloadCommand != null) { + reloadCommand.execute(); + } else { + Window.Location.reload(); + } + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/error/ErrorMessage.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/error/ErrorMessage.ui.xml index 08b3373ee04..221197b88df 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/error/ErrorMessage.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/error/ErrorMessage.ui.xml @@ -6,14 +6,14 @@ -
+
- +
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/event/EventTeaser.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/event/EventTeaser.gss new file mode 100644 index 00000000000..2a272b8db69 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/event/EventTeaser.gss @@ -0,0 +1,73 @@ +/** + * A event teaser with image + */ +.eventteasercontainer { + font-size: 1rem; + text-align: center; + width: 100%; +} +.eventteaser { + font-size: 1rem; + display: inline-block; + margin-bottom: 2.666666666666667em; + text-align: left; + max-width: 100%; + width: 100%; +} +.eventteaser:hover { + text-decoration: none; +} +.eventteaser:hover .eventteaser_title { + font-size: inherit; +} +.eventteaser:hover .eventteaser_title_name { + text-decoration: underline; +} +.eventteaser:hover .eventteaser_image { + opacity: 0.9; +} +.eventteaser_image { + position: relative; + display: block; + max-width: 100%; + width: 100%; + height: 240px; + background-position: center; + background-size: cover; + background-repeat: no-repeat; +} +.eventteaser_image .eventteaser_series { + position: absolute; + bottom: 0; + right: 0; +} +.eventteaser_name { + width: 100%; + margin-top: 0.333333333333333em; + font-size: 1.466666666666667em; + font-weight: bold; + color: #008fcc; +} +.eventteaser_title { + clear: both; + overflow: hidden; + margin-top: 1em; +} +.eventteaser_title_name { + width: 100%; + float: right; + font-size: 22px; + font-weight: bold; + color: #008fcc; +} +.eventteaser_title_name_label { + float: right; + margin-left: 1.333333333333333em; +} +.eventteaser_title_name .label { + margin-top: 0; + vertical-align: top; +} +.eventteaser_location { + color: #222; +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/event/EventTeaser.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/event/EventTeaser.java new file mode 100644 index 00000000000..8202ddf3602 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/event/EventTeaser.java @@ -0,0 +1,90 @@ +package com.sap.sailing.gwt.home.client.shared.event; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.AnchorElement; +import com.google.gwt.dom.client.DivElement; +import com.google.gwt.dom.client.SpanElement; +import com.google.gwt.safehtml.shared.UriUtils; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.EventListener; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.common.client.LinkUtil; +import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.shared.EventDatesFormatterUtil; +import com.sap.sailing.gwt.home.client.shared.LabelTypeUtil; +import com.sap.sailing.gwt.home.client.shared.LongNamesUtil; +import com.sap.sailing.gwt.ui.shared.general.EventMetadataDTO; +import com.sap.sailing.gwt.ui.shared.general.LabelType; + +public class EventTeaser extends Composite { + + @UiField + SpanElement eventName; + @UiField + SpanElement venue; + @UiField + SpanElement eventDate; + @UiField + AnchorElement eventLink; + @UiField + DivElement eventImage; + @UiField + DivElement eventState; + + private final EventMetadataDTO event; + + interface EventTeaserUiBinder extends UiBinder { + } + + private static EventTeaserUiBinder uiBinder = GWT.create(EventTeaserUiBinder.class); + private final LabelType labelType; + + public EventTeaser(final PlaceNavigation placeNavigation, final EventMetadataDTO event, LabelType labelType) { + this.event = event; + this.labelType = labelType; + + EventTeaserResources.INSTANCE.css().ensureInjected(); + initWidget(uiBinder.createAndBindUi(this)); + eventLink.setHref(placeNavigation.getTargetUrl()); + + Event.sinkEvents(eventLink, Event.ONCLICK); + Event.setEventListener(eventLink, new EventListener() { + @Override + public void onBrowserEvent(Event event) { + if(LinkUtil.handleLinkClick(event)) { + event.preventDefault(); + placeNavigation.goToPlace(); + } + } + });; + + updateUI(); + } + + private void updateUI() { + eventName.setInnerSafeHtml(LongNamesUtil.breakLongName(event.getDisplayName())); + if(labelType.isRendered()) { + LabelTypeUtil.renderLabelType(eventState, labelType); + } else { + eventState.removeFromParent(); + } + + venue.setInnerText(event.getLocationOrVenue()); + eventDate.setInnerText(EventDatesFormatterUtil.formatDateRangeWithoutYear(event.getStartDate(), event.getEndDate())); + + final StringBuilder thumbnailUrlBuilder = new StringBuilder("url('"); + + final String thumbnailImageUrl = event.getThumbnailImageURL(); + if (thumbnailImageUrl == null || thumbnailImageUrl.isEmpty()) { + thumbnailUrlBuilder.append(EventTeaserResources.INSTANCE.defaultEventPhotoImage().getSafeUri().asString()); + } else { + thumbnailUrlBuilder.append(UriUtils.fromString(thumbnailImageUrl).asString()); + } + thumbnailUrlBuilder.append("')"); + eventImage.getStyle().setBackgroundImage(thumbnailUrlBuilder.toString()); + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/event/EventTeaser.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/event/EventTeaser.ui.xml new file mode 100644 index 00000000000..40ce2b5d6f2 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/event/EventTeaser.ui.xml @@ -0,0 +1,24 @@ + + + + + + +
+ +
+
+ + \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/recentevent/RecentEventResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/event/EventTeaserResources.java similarity index 61% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/recentevent/RecentEventResources.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/event/EventTeaserResources.java index 144d62d7b1b..96927122486 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/recentevent/RecentEventResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/event/EventTeaserResources.java @@ -1,23 +1,27 @@ -package com.sap.sailing.gwt.home.client.shared.recentevent; +package com.sap.sailing.gwt.home.client.shared.event; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.CssResource; import com.google.gwt.resources.client.ImageResource; -public interface RecentEventResources extends ClientBundle { - public static final RecentEventResources INSTANCE = GWT.create(RecentEventResources.class); +public interface EventTeaserResources extends ClientBundle { + public static final EventTeaserResources INSTANCE = GWT.create(EventTeaserResources.class); - @Source("com/sap/sailing/gwt/home/client/shared/recentevent/RecentEvent.css") + @Source("EventTeaser.gss") LocalCss css(); public interface LocalCss extends CssResource { + String eventteasercontainer(); String eventteaser(); - String eventteaser_name(); + String eventteaser_title(); + String eventteaser_title_name(); String eventteaser_image(); String eventteaser_series(); + String eventteaser_name(); + String eventteaser_title_name_label(); + String label(); String eventteaser_location(); - String eventteasercontainer(); } @Source("com/sap/sailing/gwt/home/images/default_event_photo.jpg") diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/eventsponsors/EventSponsors.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/eventsponsors/EventSponsors.ui.xml index 39b34fe5bbe..c9a47e5d4ba 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/eventsponsors/EventSponsors.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/eventsponsors/EventSponsors.ui.xml @@ -9,7 +9,7 @@
-
+

Event Sponsors

diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/Footer.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/Footer.gss index 1e8ed513bc6..bbb5545e440 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/Footer.gss +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/Footer.gss @@ -1,16 +1,25 @@ +/** + * Website footer styling + */ .sitefooter { - font-size: 15px; - /* @alternate */ font-size: 1rem; + font-size: 1rem; background: #333; - border-top: 5px solid #fff; + border-top: 0.333333333333333em solid #fff; color: #fff; - line-height: 3em; + line-height: 5em; width: 100%; + margin-top: -5.333333333333333em; + padding: 0 1.333333333333333em; } .sitefooter_copyright { font-weight: 600; margin-right: 2em; } +@media (min-width: 45em) { + .sitefooter_copyright { + float: left; + } +} .sitefooter_links { text-align: left; font-size: 1em; @@ -26,26 +35,22 @@ .sitefooter_links_link:last-child { margin-right: 0; } -.sitefooter_language { - text-align: left; -} -.sitefooter_language_link { - color: #f0ab00; - display: inline-block; - cursor: pointer; - margin-left: 0.666666666666667em; -} -@media (min-width: 25em) { - .sitefooter { - line-height: 4.666666666666667em; - } - .sitefooter_copyright { - float: left; - } +@media (min-width: 45em) { .sitefooter_links_link { display: inline-block; } +} +.sitefooter_language { + text-align: left; +} +@media (min-width: 45em) { .sitefooter_language { text-align: right; } } +.sitefooter_language_link { + color: #efaa00; + display: inline-block; + cursor: pointer; + margin-left: 0.666666666666667em; +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/Footer.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/Footer.java index 4bfa74d0ccb..8e5f8ea33e1 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/Footer.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/Footer.java @@ -6,20 +6,17 @@ import java.util.Map.Entry; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.DivElement; -import com.google.gwt.dom.client.Style.Display; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.http.client.UrlBuilder; import com.google.gwt.i18n.client.LocaleInfo; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; -import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.Window.Location; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; -import com.google.gwt.user.client.ui.impl.HyperlinkImpl; import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; import com.sap.sailing.gwt.home.client.app.PlaceNavigation; import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewPlace; @@ -32,40 +29,26 @@ public class Footer extends Composite { } @UiField Anchor changeLanguageLink; - @UiField Anchor releaseNotesLink; @UiField DivElement languageSelectionDiv; private final Map localeAndLanguages; - private final PlaceNavigation releaseNotesNavigation; - private final HomePlacesNavigator navigator; - - /** set-configuration-property name='locale.searchorder' value='queryparam,cookie,useragent' /> */ - private static final HyperlinkImpl HYPERLINK_IMPL = GWT.create(HyperlinkImpl.class); + @UiField(provided = true) + final PlaceNavigation releaseNotesNavigation; public Footer(final HomePlacesNavigator navigator) { - this.navigator = navigator; - localeAndLanguages = new HashMap(); - localeAndLanguages.put("default", "English"); + localeAndLanguages.put("en", "English"); localeAndLanguages.put("de", "Deutsch"); FooterResources.INSTANCE.css().ensureInjected(); + releaseNotesNavigation = navigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingAnalytics); initWidget(uiBinder.createAndBindUi(this)); - releaseNotesNavigation = navigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingAnalytics); - releaseNotesLink.setHref(releaseNotesNavigation.getTargetUrl()); - - languageSelectionDiv.getStyle().setDisplay(Display.NONE); updateUI(); } - @UiHandler("releaseNotesLink") - public void goToReleaseNotes(ClickEvent e) { - handleClickEvent(e, releaseNotesNavigation); - } - @UiHandler("changeLanguageLink") public void changeLanguage(ClickEvent e) { String selectedLanguage = changeLanguageLink.getText(); @@ -90,11 +73,4 @@ public class Footer extends Composite { changeLanguageLink.setText(languagesToSelectFrom.values().iterator().next()); } } - - private void handleClickEvent(ClickEvent e, PlaceNavigation placeNavigation) { - if (HYPERLINK_IMPL.handleAsClick((Event) e.getNativeEvent())) { - navigator.goToPlace(placeNavigation); - e.preventDefault(); - } - } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/Footer.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/Footer.ui.xml index 539c3b3389e..bfae282ac73 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/Footer.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/Footer.ui.xml @@ -1,37 +1,39 @@ - - - - - - - + xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"> + + + + + + +
+
+
+ +
+ +
+
+ : + +
+
+
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/FooterResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/FooterResources.java index adfe48ef546..9848eea29f7 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/FooterResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/footer/FooterResources.java @@ -3,7 +3,6 @@ package com.sap.sailing.gwt.home.client.shared.footer; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.CssResource; -import com.google.gwt.resources.client.CssResource.Shared; public interface FooterResources extends ClientBundle { public static final FooterResources INSTANCE = GWT.create(FooterResources.class); @@ -11,7 +10,6 @@ public interface FooterResources extends ClientBundle { @Source("com/sap/sailing/gwt/home/client/shared/footer/Footer.gss") LocalCss css(); - @Shared public interface LocalCss extends CssResource { String sitefooter(); String sitefooter_copyright(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/Header.gss b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/Header.gss index bf019bff8d2..ba9d697ac18 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/Header.gss +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/Header.gss @@ -1,122 +1,105 @@ +/** + * Website header bar + */ .siteheader { - font-size: 15px; - /* @alternate */ font-size: 1rem; + font-size: 1rem; background: #333; - border-bottom: 5px solid #f0ab00; - min-height: 4.333333333333333em; - line-height: 4em; + border-bottom: 0.333333333333333em solid #f0ab00; + height: 3.333333333333333em; + line-height: 3em; width: 100%; overflow: hidden; } -.siteheader_full { - border-width: 3.333333333333333em; - height: 7.333333333333333em; +.siteheader_logo { + font-size: 1rem; } -.logo { - margin: 0.8em 0; +.siteheader_logo:hover a { + text-decoration: none; +} +.siteheader_logo_image { float: left; + max-height: 2em; + margin-top: 0.466666666666667em; } -.logotitle { +.siteheader_logo_title { display: none; - height: 4.333333333333333em; - line-height: 4.333333333333333em; color: #f6f9fc; } -@media (min-width: 50em) { - .logotitle { +@media (min-width: 61em) { + .siteheader_logo_title { display: inline; } } .sitenavigation { - float: right; + display: inline-block; + overflow: hidden; text-align: right; - width: 100%; - height: 4.333333333333333em; } .sitenavigation_link { display: inline-block; - height: 4.642857142857143em; - line-height: 4.642857142857143em; font-size: 0.933333333333333em; font-weight: 600; color: #f6f9fc; text-transform: uppercase; - padding: 0 2.5em; + padding: 0 3%; } .sitenavigation_link:hover, .sitenavigation_link:focus { text-decoration: none; - background-color: #2d2d2d; + background-color: #0a0a0a; } .sitenavigation_linkactive, .sitenavigation_link:hover, .sitenavigation_link:focus { + text-decoration: none; color: #f0ab00; } .sitenavigation_search { display: inline-block; - height: 4.333333333333333em; + padding: 0 0 0 3%; font-weight: 600; color: #f6f9fc; text-transform: uppercase; - text-align: right; -} -.sitenavigationexpanded .searchsmall { - width: 14.666666666666666em; -} -.sitenavigationexpanded .searchsmall .search_textfield { - opacity: 1; - -ms-filter: none; - filter: none; - pointer-events: initial; - -webkit-box-shadow: -10px 0 10px rgba(51,51,51,0.9); - box-shadow: -10px 0 10px rgba(51,51,51,0.9); } .search { - font-size: 15px; - /* @alternate */ font-size: 1rem; - display: inline-block; - width: 100%; - margin-top: 0.2em; + font-size: 1rem; position: relative; } .search_textfield { - width: 100%; - padding: 0.785714285714286em 2.857142857142857em 0.785714285714286em 1.071428571428571em; - background: #222; + display: none; + width: 8em; + padding: 0.357142857142857em 2.857142857142857em 0.357142857142857em 0.357142857142857em; border: 1px solid #666; font-size: 0.933333333333333em; - color: #fff; - outline: none; + color: #f6f9fc; + background: #333; + -webkit-transition: width 0.33s ease-out; + -moz-transition: width 0.33s ease-out; + transition: width 0.33s ease-out; +} +@media (min-width: 61em) { + .search_textfield { + display: inline-block; + } +} +.search_textfield:focus { + width: 13.333333333333334em; } .search_button { - position: absolute; - right: 1.5em; - top: 50%; - margin-top: -0.666666666666667em; + width: 2.666666666666667em !important; + height: 1em !important; + vertical-align: middle !important; } -.search_button:hover, -.search_button:focus { - background-color: transparent; -} -.searchsmall { - position: absolute; - right: 2em; - width: 0; -} -.searchsmall .search_textfield { - opacity: 0; - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; - filter: alpha(opacity=0); - pointer-events: none; - -webkit-transition: height 0.1s ease; - -moz-transition: height 0.1s ease; - -o-transition: height 0.1s ease; - -ms-transition: height 0.1s ease; - transition: height 0.1s ease; -} -.searchsmall .search_button { - right: 0.666666666666667em; +@media (min-width: 61em) { + .search_button { + position: absolute; + top: 50%; + right: 0; + -webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); + } } .submit { font-size: inherit; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/Header.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/Header.java index 1c4281bf930..6fc34dbbdee 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/Header.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/Header.java @@ -8,25 +8,30 @@ import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.KeyPressHandler; +import com.google.gwt.place.shared.Place; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.Event; -import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.impl.HyperlinkImpl; +import com.google.web.bindery.event.shared.EventBus; import com.sap.sailing.gwt.common.client.i18n.TextMessages; import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.place.event.AbstractEventPlace; +import com.sap.sailing.gwt.home.client.place.event.legacy.EventPlace; +import com.sap.sailing.gwt.home.client.place.event.legacy.RegattaPlace; import com.sap.sailing.gwt.home.client.place.events.EventsPlace; import com.sap.sailing.gwt.home.client.place.searchresult.SearchResultPlace; import com.sap.sailing.gwt.home.client.place.solutions.SolutionsPlace; import com.sap.sailing.gwt.home.client.place.solutions.SolutionsPlace.SolutionsNavigationTabs; import com.sap.sailing.gwt.home.client.place.start.StartPlace; +import com.sap.sse.gwt.client.mvp.PlaceChangedEvent; public class Header extends Composite { @UiField Anchor startPageLink; @@ -51,6 +56,18 @@ public class Header extends Composite { private static HeaderUiBinder uiBinder = GWT.create(HeaderUiBinder.class); + public Header(final HomePlacesNavigator navigator, EventBus eventBus) { + this(navigator); + + eventBus.addHandler(PlaceChangedEvent.TYPE, new PlaceChangedEvent.Handler() { + + @Override + public void onPlaceChanged(PlaceChangedEvent event) { + updateActiveLink(event.getNewPlace()); + } + }); + } + public Header(final HomePlacesNavigator navigator) { this.navigator = navigator; @@ -100,12 +117,23 @@ public class Header extends Composite { @UiHandler("searchButton") void searchButtonClick(ClickEvent event) { - if(searchText.getText().isEmpty()) { - Window.alert(TextMessages.INSTANCE.pleaseEnterASearchTerm()); - } else { - PlaceNavigation searchResultNavigation = navigator.getSearchResultNavigation(searchText.getText()); - navigator.goToPlace(searchResultNavigation); + PlaceNavigation searchResultNavigation = navigator.getSearchResultNavigation(searchText + .getText()); + navigator.goToPlace(searchResultNavigation); + } + + private void updateActiveLink(Place place) { + if(place instanceof EventsPlace + || place instanceof AbstractEventPlace + || place instanceof EventPlace + || place instanceof RegattaPlace) { + setActiveLink(eventsPageLink); + } else if(place instanceof StartPlace) { + setActiveLink(startPageLink); + } else if(place instanceof SolutionsPlace) { + setActiveLink(solutionsPageLink); } + // TODO add more rules } private void setActiveLink(Anchor link) { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/Header.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/Header.ui.xml index 79ae5b25ed6..a819f512efe 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/Header.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/Header.ui.xml @@ -2,39 +2,38 @@ - + - - -
-
-
- - - -

Sailing Analytics

-
-
- -
- -
- - -
-
-
-
-
+ + + +
+ + +
+
\ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/HeaderResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/HeaderResources.java index 7f1a8cff0b8..1709b845a3f 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/HeaderResources.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/header/HeaderResources.java @@ -3,8 +3,6 @@ package com.sap.sailing.gwt.home.client.shared.header; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.CssResource; -import com.google.gwt.resources.client.CssResource.Shared; -import com.google.gwt.resources.client.ImageResource; public interface HeaderResources extends ClientBundle { public static final HeaderResources INSTANCE = GWT.create(HeaderResources.class); @@ -12,27 +10,18 @@ public interface HeaderResources extends ClientBundle { @Source("com/sap/sailing/gwt/home/client/shared/header/Header.gss") LocalCss css(); - @Shared public interface LocalCss extends CssResource { String siteheader(); - String siteheader_full(); - String logo(); - String logotitle(); + String siteheader_logo(); + String siteheader_logo_image(); + String siteheader_logo_title(); String sitenavigation(); String sitenavigation_link(); String sitenavigation_linkactive(); String sitenavigation_search(); - String sitenavigationexpanded(); - String searchsmall(); - String search_textfield(); String search(); + String search_textfield(); String search_button(); String submit(); } - - @Source("com/sap/sailing/gwt/home/images/logo-small@2x.png") - ImageResource logo(); - - @Source("com/sap/sailing/gwt/home/images/search-icon.png") - ImageResource searchIcon(); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainevents/MainEvents.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainevents/MainEvents.java index 511f0e77db7..2c2808765e4 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainevents/MainEvents.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainevents/MainEvents.java @@ -1,22 +1,22 @@ package com.sap.sailing.gwt.home.client.shared.mainevents; -import java.util.ArrayList; import java.util.List; import com.google.gwt.core.client.GWT; -import com.google.gwt.dom.client.DivElement; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.gwt.home.client.app.HomePlacesNavigator; import com.sap.sailing.gwt.home.client.app.PlaceNavigation; +import com.sap.sailing.gwt.home.client.place.event.EventDefaultPlace; import com.sap.sailing.gwt.home.client.place.events.EventsPlace; -import com.sap.sailing.gwt.home.client.shared.recentevent.RecentEvent; -import com.sap.sailing.gwt.ui.shared.EventBaseDTO; +import com.sap.sailing.gwt.home.client.place.events.recent.RecentEventTeaser; +import com.sap.sailing.gwt.ui.shared.eventlist.EventListEventDTO; public class MainEvents extends Composite { interface MainEventsUiBinder extends UiBinder { @@ -24,9 +24,7 @@ public class MainEvents extends Composite { private static MainEventsUiBinder uiBinder = GWT.create(MainEventsUiBinder.class); - private List recentEvents; - - @UiField DivElement recentEventsDiv; + @UiField FlowPanel recentEventsTeaserPanel; @UiField Anchor showAllEventsAnchor; private final HomePlacesNavigator navigator; @@ -41,27 +39,22 @@ public class MainEvents extends Composite { eventsNavigation = navigator.getEventsNavigation(); showAllEventsAnchor.setHref(eventsNavigation.getTargetUrl()); - recentEvents = new ArrayList(); } - public void setRecentEvents(List theRecentEvents) { + public void setRecentEvents(List recentEvents) { final int MAX_RECENT_EVENTS_ON_HOME_PAGE = 3; - recentEventsDiv.removeAllChildren(); - recentEvents.clear(); - recentEvents.addAll(theRecentEvents); + recentEventsTeaserPanel.clear(); for (int i=0; i eventNavigation = navigator.getEventNavigation(event.getId().toString(), event.getBaseURL(), event.isOnRemoteServer()); + RecentEventTeaser recentEvent = new RecentEventTeaser(eventNavigation, event, event.getState().getListStateMarker()); + recentEventsTeaserPanel.add(recentEvent); } } - - private void createRecentEvent(EventBaseDTO eventBase) { - RecentEvent event = new RecentEvent(navigator, eventBase); - recentEventsDiv.appendChild(event.getElement()); - } @UiHandler("showAllEventsAnchor") public void showAllEvents(ClickEvent e) { - navigator.goToPlace(eventsNavigation); + eventsNavigation.goToPlace(); e.preventDefault(); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainevents/MainEvents.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainevents/MainEvents.ui.xml index 8a9ddea3a2f..6ac92857f9c 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainevents/MainEvents.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainevents/MainEvents.ui.xml @@ -8,17 +8,17 @@
-
+

-
- -
-
+ + + +
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMedia.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMedia.css index 81c5443c71a..19574129fbc 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMedia.css +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMedia.css @@ -115,7 +115,6 @@ font-size: 1.466666666666667em; font-weight: bold; margin: 0; - color: #fff; } .videopreview img { margin: 0 auto; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMedia.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMedia.java index 8e5caf3c60e..bab98569187 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMedia.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMedia.java @@ -1,12 +1,8 @@ package com.sap.sailing.gwt.home.client.shared.mainmedia; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Random; -import java.util.Set; +import java.util.Collection; +import java.util.Iterator; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.DivElement; @@ -15,12 +11,9 @@ import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.domain.common.ImageSize; import com.sap.sailing.gwt.home.client.app.PlaceNavigator; -import com.sap.sailing.gwt.home.client.shared.stage.StageEventType; -import com.sap.sailing.gwt.ui.common.client.YoutubeApi; -import com.sap.sailing.gwt.ui.shared.EventBaseDTO; -import com.sap.sse.common.Util.Pair; +import com.sap.sailing.gwt.ui.shared.media.ImageReferenceDTO; +import com.sap.sailing.gwt.ui.shared.media.VideoMetadataDTO; import com.sap.sse.gwt.client.controls.carousel.ImageCarousel; public class MainMedia extends Composite { @@ -36,8 +29,6 @@ public class MainMedia extends Composite { @UiField ImageCarousel imageCarousel; - private final HashSet addedVideoUrls = new HashSet(MAX_VIDEO_COUNT); - interface MainMediaUiBinder extends UiBinder { } @@ -48,123 +39,18 @@ public class MainMedia extends Composite { initWidget(uiBinder.createAndBindUi(this)); } - public void setFeaturedEvents(List> featuredEvents) { - for (Pair featuredEventTypeAndEvent : featuredEvents) { - if (featuredEventTypeAndEvent.getB().getVideoURLs().size() > 0 && addedVideoUrls.size() < MAX_VIDEO_COUNT) { - String youTubeRandomUrl = getRandomVideoURL(featuredEventTypeAndEvent.getB()); - addVideoToVideoPanel(youTubeRandomUrl, featuredEventTypeAndEvent.getB()); - } - } - } - - public void setRecentEvents(List recentEvents) { - class Holder { - public Holder(String url, int height, int width) { - this.url = url; - this.height = height; - this.width = width; - } - String url; - int height; - int width; - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + height; - result = prime * result + ((url == null) ? 0 : url.hashCode()); - result = prime * result + width; - return result; - } - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Holder other = (Holder) obj; - if (height != other.height) - return false; - if (url == null) { - if (other.url != null) - return false; - } else if (!url.equals(other.url)) - return false; - if (width != other.width) - return false; - return true; - } - } - - final Set photoGalleryUrls = new HashSet<>(); // using a HashSet here leads to a reasonable amount of shuffling - final List> videoCandidates = new LinkedList<>(); - - for (EventBaseDTO event : recentEvents) { - for (String url : event.getSailingLovesPhotographyImages()) { - ImageSize size = event.getImageSize(url); - photoGalleryUrls.add(new Holder(url, size.getHeight(), size.getWidth())); - } - for (String videoUrl : event.getVideoURLs()) { - videoCandidates.add(new Pair(videoUrl, event)); - } - } - - final int numberOfCandidatesAvailable = videoCandidates.size(); - if (numberOfCandidatesAvailable <= (MAX_VIDEO_COUNT - addedVideoUrls.size())) { - // add all we have, no randomize - for (Pair videoCandidateInfo : videoCandidates) { - addVideoToVideoPanel(videoCandidateInfo.getA(), videoCandidateInfo.getB()); - } - } else { - // fill up the list randomly from videoCandidates - final Random videosRandomizer = new Random(numberOfCandidatesAvailable); - randomlyPick: for (int i = 0; i < numberOfCandidatesAvailable; i++) { - int nextVideoindex = videosRandomizer.nextInt(numberOfCandidatesAvailable); - final Pair videoCandidateInfo = videoCandidates.get(nextVideoindex); - final String youtubeUrl = videoCandidateInfo.getA(); - addVideoToVideoPanel(youtubeUrl, videoCandidateInfo.getB()); - if (addedVideoUrls.size() == MAX_VIDEO_COUNT) { - break randomlyPick; - } - } - } - Random random = new Random(); - List shuffledPhotoGallery = new ArrayList<>(photoGalleryUrls); - final int gallerySize = photoGalleryUrls.size(); - for (int i = 0; i < gallerySize; i++) { - Collections.swap(shuffledPhotoGallery, i, random.nextInt(gallerySize)); - } - for (Holder holder : shuffledPhotoGallery) { - imageCarousel.addImage(holder.url, holder.height, holder.width); - } - } - - private void addVideoToVideoPanel(String youtubeUrl, EventBaseDTO event) { - if (addedVideoUrls.contains(youtubeUrl)) { - return; - } - String eventName = event.getName(); - String youtubeId = YoutubeApi.getIdByUrl(youtubeUrl); - if (youtubeId != null && !youtubeId.trim().isEmpty()) { - MainMediaVideo video = new MainMediaVideo(eventName, youtubeId); + public void setData(Collection videos, ArrayList photos) { + Iterator videoIterator = videos.iterator(); + int videoCount = 0; + while(videoCount < MAX_VIDEO_COUNT && videoIterator.hasNext()) { + VideoMetadataDTO videoDTO = videoIterator.next(); + MainMediaVideo video = new MainMediaVideo(videoDTO.getTitle(), videoDTO.getRef()); videosPanel.add(video); - addedVideoUrls.add(youtubeUrl); + videoCount++; + } + + for (ImageReferenceDTO image : photos) { + imageCarousel.addImage(image.getImageURL(), image.getHeightInPx(), image.getWidthInPx()); } } - - private String getRandomVideoURL(EventBaseDTO event) { - final String result; - List videoURLs = event.getVideoURLs(); - if (!videoURLs.isEmpty()) { - result = event.getVideoURLs().get(new Random(videoURLs.size()).nextInt(videoURLs.size())); - } else { - result = null; - } - return result; - } - - - } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMedia.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMedia.ui.xml index 6c747cb4be2..5ed5b705758 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMedia.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMedia.ui.xml @@ -10,7 +10,7 @@
-
+

@@ -22,7 +22,7 @@

-
+
@@ -30,7 +30,7 @@
-
+

@@ -42,8 +42,8 @@

-
-
+
+
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMediaVideo.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMediaVideo.java index c928d42ea2d..bdcd9a8a28b 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMediaVideo.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMediaVideo.java @@ -1,6 +1,7 @@ package com.sap.sailing.gwt.home.client.shared.mainmedia; import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.IFrameElement; import com.google.gwt.dom.client.SpanElement; import com.google.gwt.safehtml.shared.SafeHtml; @@ -20,15 +21,28 @@ public class MainMediaVideo extends Composite { @UiField IFrameElement youtubeEmbed; @UiField SpanElement videoTitle; + @UiField Element videoTitleWrapper; public MainMediaVideo(String eventName, String youtubeId) { + this(eventName, youtubeId, false); + } + + public MainMediaVideo(String eventName, String youtubeId, boolean showInfo) { MainMediaResources.INSTANCE.css().ensureInjected(); initWidget(uiBinder.createAndBindUi(this)); - - youtubeEmbed.setSrc("//www.youtube.com/embed/" + youtubeId + "?modestbranding=1&rel=0&showinfo=0&autohide=1&fs=1"); - SafeHtml safeHtmlEventName = LongNamesUtil.breakLongName(eventName); - videoTitle.setInnerSafeHtml(safeHtmlEventName); + String youtubeUrl = "//www.youtube.com/embed/" + youtubeId + "?modestbranding=1&rel=0&autohide=1&fs=1"; + if(!showInfo) { + youtubeUrl += "&showinfo=0"; + } + youtubeEmbed.setSrc(youtubeUrl); + + if(eventName == null || eventName.isEmpty()) { + videoTitleWrapper.removeFromParent(); + } else { + SafeHtml safeHtmlEventName = LongNamesUtil.breakLongName(eventName); + videoTitle.setInnerSafeHtml(safeHtmlEventName); + } } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMediaVideo.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMediaVideo.ui.xml index b2d6b8d46fb..4823dffb709 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMediaVideo.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainmedia/MainMediaVideo.ui.xml @@ -12,7 +12,7 @@
-
+
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainsponsors/MainSponsors.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainsponsors/MainSponsors.ui.xml index 2ab3660dc0d..21c96d41ea4 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainsponsors/MainSponsors.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/mainsponsors/MainSponsors.ui.xml @@ -8,7 +8,7 @@
-
+

Solutions

diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/media/MediaPage.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/media/MediaPage.css new file mode 100644 index 00000000000..b29362c8ffb --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/media/MediaPage.css @@ -0,0 +1,11 @@ +.media { + font-size: 15px; + font-size: 1rem; + padding-top: 2em; + padding-bottom: 2em; +} + +.dark { + background: #333; + color: #fff; +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/media/MediaPage.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/media/MediaPage.java new file mode 100644 index 00000000000..52f22227f68 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/media/MediaPage.java @@ -0,0 +1,140 @@ +package com.sap.sailing.gwt.home.client.shared.media; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.DivElement; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.SimplePanel; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.home.client.shared.mainmedia.MainMediaVideo; +import com.sap.sailing.gwt.home.client.shared.placeholder.InfoPlaceholder; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sailing.gwt.ui.shared.media.ImageMetadataDTO; +import com.sap.sailing.gwt.ui.shared.media.MediaDTO; +import com.sap.sailing.gwt.ui.shared.media.VideoMetadataDTO; +import com.sap.sse.gwt.client.controls.carousel.ImageCarousel; + +public class MediaPage extends Composite { + + private static MediaPageUiBinder uiBinder = GWT.create(MediaPageUiBinder.class); + + interface MediaPageUiBinder extends UiBinder { + } + + // TODO use this when ImageGallery and VideoGallery is implemented correctly +// @UiField ImageGallery photos; +// @UiField VideoGallery videos; + // TODO remove -> temporary solution to get contents on the page + @UiField ImageCarousel imageCarousel; + @UiField DivElement photoWrapper; + @UiField DivElement videoWrapper; + @UiField DivElement videosPanel; + private final SimplePanel contentPanel; + + @UiField StringMessages i18n; + + public MediaPage() { + MediaPageResources.INSTANCE.css().ensureInjected(); + contentPanel = new SimplePanel(); + initWidget(contentPanel); + } + + public void setMedia(MediaDTO media) { + Widget mediaUi = uiBinder.createAndBindUi(this); + + boolean hasPhotos = !media.getPhotos().isEmpty(); + // TODO use this when ImageGallery is implemented correctly +// photos.setVisible(hasPhotos); +// if(hasPhotos) { +// ImageGalleryData data = mapPhotoData(media.getPhotos()); +// photos.setData(data); +// } + // TODO remove -> temporary solution to get contents on the page + if(hasPhotos) { + photoWrapper.getStyle().clearDisplay(); + Random random = new Random(); + List shuffledPhotoGallery = new ArrayList<>(media.getPhotos()); + final int gallerySize = media.getPhotos().size(); + for (int i = 0; i < gallerySize; i++) { + Collections.swap(shuffledPhotoGallery, i, random.nextInt(gallerySize)); + } + int count = 0; + do { + for (ImageMetadataDTO holder : shuffledPhotoGallery) { + imageCarousel.addImage(holder.getImageURL(), holder.getHeightInPx(), holder.getWidthInPx()); + count++; + } + } while (count < 3); + } + + boolean hasVideos = !media.getVideos().isEmpty(); + // TODO use this when VideoGallery is implemented correctly +// videos.setVisible(hasVideos); +// if(hasPhotos) { +// VideoGalleryData data = mapVideoData(media.getVideos()); +// videos.setData(data); +// } + // TODO remove -> temporary solution to get contents on the page + if(hasVideos) { + videoWrapper.getStyle().clearDisplay(); + if(hasPhotos) { + videoWrapper.addClassName(MediaPageResources.INSTANCE.css().dark()); + } + for (VideoMetadataDTO videoCandidateInfo : media.getVideos()) { + MainMediaVideo video = new MainMediaVideo(videoCandidateInfo.getTitle(), videoCandidateInfo.getRef(), true); + videosPanel.appendChild(video.getElement()); + } + } + + + if(!hasPhotos && !hasVideos) { + contentPanel.setWidget(new InfoPlaceholder(i18n.mediaNoContent())); + } else { + contentPanel.setWidget(mediaUi); + } + } + + + // private ImageGalleryData mapPhotoData(ArrayList photos) { + // List images = new ArrayList<>(); + // for(MediaEntryDTO entry : photos) { + // ImageDescriptor descriptor = new ImageDescriptor(entry.getMediaURL()); + // descriptor.setTitle(entry.getTitle()); + // descriptor.setSubtitle(entry.getSubtitle()); + // descriptor.setAuthor(entry.getAuthor()); + // descriptor.setCreatedAtDate(entry.getCreatedAtDate()); + // descriptor.setWidthInPx(entry.getWidthInPx()); + // descriptor.setHeightInPx(entry.getHeightInPx()); + // descriptor.setThumbnailURL(entry.getThumbnailURL()); + // descriptor.setThumbnailWidthInPx(entry.getThumbnailWidthInPx()); + // descriptor.setThumbnailHeightInPx(entry.getThumbnailHeightInPx()); + // images.add(descriptor); + // } + // return new ImageGalleryData(StringMessages.INSTANCE.photos(), images); + // } + // + // private VideoGalleryData mapVideoData(ArrayList photos) { + // List images = new ArrayList<>(); + // for(MediaEntryDTO entry : photos) { + // VideoDescriptor descriptor = new VideoDescriptor(entry.getMediaURL()); + // descriptor.setTitle(entry.getTitle()); + // descriptor.setSubtitle(entry.getSubtitle()); + // descriptor.setAuthor(entry.getAuthor()); + // descriptor.setCreatedAtDate(entry.getCreatedAtDate()); + // descriptor.setWidthInPx(entry.getWidthInPx()); + // descriptor.setHeightInPx(entry.getHeightInPx()); + // descriptor.setThumbnailURL(entry.getThumbnailURL()); + // descriptor.setThumbnailWidthInPx(entry.getThumbnailWidthInPx()); + // descriptor.setThumbnailHeightInPx(entry.getThumbnailHeightInPx()); + // images.add(descriptor); + // } + // return new VideoGalleryData(StringMessages.INSTANCE.videos(), images); + // } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/media/MediaPage.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/media/MediaPage.ui.xml new file mode 100644 index 00000000000..d8bc329f70b --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/media/MediaPage.ui.xml @@ -0,0 +1,41 @@ + + + + + + + + + +
+
+ + +
+
+ +