mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-20 04:35:32 +00:00
Merge branch 'master' into bug3803
This commit is contained in:
BIN
Binary file not shown.
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
|
||||
# You need an installation of the Mars release of "Eclipse IDE for Eclipse Committers" matching you OS and JDK (32 vs 64 Bit):
|
||||
# http://www.eclipse.org/downloads/packages/eclipse-ide-eclipse-committers/marsr
|
||||
|
||||
if [[ $1 == "" ]]; then
|
||||
echo "You need to specify the Eclipse installation directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
installPath="$1"
|
||||
|
||||
installPlugins() {
|
||||
"$installPath/eclipse" -application org.eclipse.equinox.p2.director -noSplash -roaming -repository $1 -installIU $2
|
||||
echo ""
|
||||
}
|
||||
|
||||
updatePlugins() {
|
||||
"$installPath/eclipse" -application org.eclipse.equinox.p2.director -noSplash -roaming -repository $1 -uninstallIU $2 -installIU $2
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Not necessary if using Eclipse for JEE developers
|
||||
echo "Installing webtools (WTP/WST/JPT) and m2e that are required by the GWT plugin..."
|
||||
installPlugins http://download.eclipse.org/releases/mars org.eclipse.wst.web_ui.feature.feature.group,org.eclipse.jst.web_ui.feature.feature.group,org.eclipse.wst.xml_ui.feature.feature.group,org.eclipse.jpt.common.feature.feature.group,org.eclipse.jpt.jpa.feature.feature.group,org.eclipse.m2e.feature.feature.group,org.eclipse.m2e.wtp.feature.feature.group
|
||||
|
||||
echo "Installing GWT plugin..."
|
||||
installPlugins http://storage.googleapis.com/gwt-eclipse-plugin/release com.google.gdt.eclipse.suite.e44.feature.feature.group
|
||||
|
||||
echo "Installing Android Tools..."
|
||||
installPlugins https://dl.google.com/eclipse/plugin/4.5 com.android.ide.eclipse.adt.feature.feature.group
|
||||
|
||||
echo "Installing GWT SDM debug bridge..."
|
||||
installPlugins http://p2.sapsailing.com/p2/sdbg com.github.sdbg.feature.feature.group
|
||||
|
||||
echo "Installing EasyShell..."
|
||||
installPlugins http://anb0s.github.io/EasyShell com.tetrade.eclipse.plugins.easyshell.feature.feature.group
|
||||
|
||||
echo "Installing latest version of Code Recommenders ..."
|
||||
updatePlugins http://download.eclipse.org/recommenders/updates/stable/ org.eclipse.recommenders.rcp.feature.feature.group,org.eclipse.recommenders.mylyn.rcp.feature.feature.group,org.eclipse.recommenders.snipmatch.rcp.feature.feature.group
|
||||
|
||||
echo "Installing latest version of EGit ..."
|
||||
updatePlugins http://download.eclipse.org/egit/updates org.eclipse.jgit.feature.group,org.eclipse.jgit.http.apache.feature.group,org.eclipse.egit.feature.group,org.eclipse.egit.mylyn.feature.group
|
||||
|
||||
echo "Installation completed!"
|
||||
@@ -4,7 +4,7 @@
|
||||
# http://www.eclipse.org/downloads/packages/eclipse-ide-eclipse-committers/neonr
|
||||
|
||||
if [[ $1 == "" ]]; then
|
||||
echo "You need to specify the Eclipse intallation directory"
|
||||
echo "You need to specify the Eclipse installation directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ SAP is at the center of today’s technology revolution, developing innovations
|
||||
* [[Racecommittee App|wiki/racecommittee-app]]
|
||||
* [[Tracking App|wiki/tracking-app]]
|
||||
* [[Web Services API|wiki/sailing-webservices]]
|
||||
* [[Theses (Bachelor, Master, ...)|wiki/theses]]
|
||||
* [[Thesis (Bachelor, Master, ...)|wiki/thesis]]
|
||||
* [[Google Analytics (Web Page Tracking)|wiki/ganalytics]]
|
||||
* [[Polars|wiki/Polars]]
|
||||
* Production Environment
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.sap.sailing.domain.test.compiler;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class EclipseNeonConstructorReferenceSerializationTest {
|
||||
|
||||
/**
|
||||
* We have serialization problems due to a regression in Eclipse Neon:
|
||||
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=497879
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorReferenceSerializationThatFailsOnEclipseNeon() throws Exception {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
|
||||
SerializableSupplier factory = TypeImplementation::new;
|
||||
oos.writeObject(factory);
|
||||
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
ObjectInputStream ois = new ObjectInputStream(bais);
|
||||
ois.readObject();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.sap.sailing.domain.test.compiler;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SerializableSupplier extends Serializable, Supplier<TypeDefinition> {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.sap.sailing.domain.test.compiler;
|
||||
|
||||
public interface TypeDefinition {
|
||||
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.sap.sailing.domain.test.compiler;
|
||||
|
||||
public class TypeImplementation implements TypeDefinition {
|
||||
|
||||
public TypeImplementation() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -448,8 +448,8 @@ img.openColumn {
|
||||
|
||||
.busyIndicator-Simple {
|
||||
position: absolute;
|
||||
top: 0.7em;
|
||||
right: 7.4em;
|
||||
top: 0.3em;
|
||||
right: 0.4em;
|
||||
}
|
||||
|
||||
.busyIndicator-Circle {
|
||||
|
||||
@@ -832,13 +832,10 @@ img.openColumn {
|
||||
}
|
||||
|
||||
.busyIndicator-Simple {
|
||||
position: absolute;
|
||||
top: 0.7em;
|
||||
right: 7.4em;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.busyIndicator-Circle {
|
||||
|
||||
}
|
||||
|
||||
.raceBoard-TitlePanel {
|
||||
|
||||
+4
-11
@@ -2,9 +2,8 @@ package com.sap.sailing.gwt.common.authentication;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.google.gwt.http.client.UrlBuilder;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.sap.sse.gwt.client.AbstractEntryPointLinkFactory;
|
||||
import com.sap.sse.gwt.settings.UrlBuilderUtil;
|
||||
import com.sap.sse.security.ui.authentication.generic.GenericAuthenticationLinkFactory;
|
||||
|
||||
public final class SailingAuthenticationEntryPointLinkFactory extends AbstractEntryPointLinkFactory implements
|
||||
@@ -17,7 +16,7 @@ public final class SailingAuthenticationEntryPointLinkFactory extends AbstractEn
|
||||
|
||||
@Override
|
||||
public final String createUserProfileLink() {
|
||||
return createEntryPointLink("/gwt/Home.html#/user/profile/:", new HashMap<String, String>());
|
||||
return createEntryPointLink("/gwt/Home.html", "/user/profile/:", new HashMap<String, String>());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -30,13 +29,7 @@ public final class SailingAuthenticationEntryPointLinkFactory extends AbstractEn
|
||||
return createFullQualifiedLink("/gwt/Home.html", "/user/passwordreset/:");
|
||||
}
|
||||
|
||||
private String createFullQualifiedLink(String baseUrl, String hash) {
|
||||
String path = createEntryPointLink(baseUrl, new HashMap<String, String>());
|
||||
UrlBuilder urlBuilder = Window.Location.createUrlBuilder();
|
||||
for (String parameter : Window.Location.getParameterMap().keySet()) {
|
||||
urlBuilder.removeParameter(parameter);
|
||||
}
|
||||
return urlBuilder.setPath(path).setHash(hash).buildString();
|
||||
private String createFullQualifiedLink(String path, String hash) {
|
||||
return UrlBuilderUtil.createUrlBuilderFromCurrentLocationWithCleanParametersAndPathAndHash(path, hash).buildString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.sap.sailing.gwt.common.client.suggestion;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sse.common.filter.AbstractListFilter;
|
||||
|
||||
public abstract class AbstractListSuggestOracle<C> extends AbstractSuggestOracle<C> {
|
||||
|
||||
private final List<C> suggestionObjectList = new ArrayList<>();
|
||||
private final AbstractListFilter<C> suggestionMatchingFilter = new AbstractListFilter<C>() {
|
||||
@Override
|
||||
public Iterable<String> getStrings(C value) {
|
||||
return getMatchingStrings(value);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected final void getSuggestions(Request request, Callback callback, Iterable<String> queryTokens) {
|
||||
Iterable<C> filteredList = suggestionMatchingFilter.applyFilter(queryTokens, suggestionObjectList);
|
||||
this.setSuggestions(request, callback, filteredList, queryTokens);
|
||||
}
|
||||
|
||||
public final AbstractListFilter<C> getSuggestionMatchingFilter() {
|
||||
return suggestionMatchingFilter;
|
||||
}
|
||||
|
||||
public void setSelectableValues(Collection<C> selectableValues) {
|
||||
suggestionObjectList.clear();
|
||||
suggestionObjectList.addAll(selectableValues);
|
||||
}
|
||||
|
||||
protected abstract Iterable<String> getMatchingStrings(C value);
|
||||
|
||||
protected abstract String createSuggestionKeyString(C value);
|
||||
|
||||
protected abstract String createSuggestionAdditionalDisplayString(C value);
|
||||
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
package com.sap.sailing.gwt.common.client.suggestion;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
|
||||
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
|
||||
import com.google.gwt.user.client.ui.SuggestOracle;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public abstract class AbstractSuggestOracle<T> extends SuggestOracle {
|
||||
|
||||
public final void setSuggestions(Request request, Callback callback, Iterable<T> suggestionObjects,
|
||||
Iterable<String> queryTokens) {
|
||||
List<Suggestion> suggestions = new ArrayList<>();
|
||||
List<String> normalizedQueryTokens = new ArrayList<>();
|
||||
for (String token : queryTokens) {
|
||||
normalizedQueryTokens.add(token.toLowerCase());
|
||||
}
|
||||
int count = 0;
|
||||
for (T match : suggestionObjects) {
|
||||
suggestions.add(new SimpleSuggestion(match, normalizedQueryTokens));
|
||||
if (++count >= request.getLimit()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Response response = new Response(suggestions);
|
||||
response.setMoreSuggestionsCount(Util.size(suggestionObjects) - count);
|
||||
callback.onSuggestionsReady(request, response);
|
||||
}
|
||||
|
||||
protected abstract void getSuggestions(Request request, Callback callback, Iterable<String> queryTokens);
|
||||
|
||||
protected abstract String createSuggestionKeyString(T value);
|
||||
|
||||
protected abstract String createSuggestionAdditionalDisplayString(T value);
|
||||
|
||||
@Override
|
||||
public final void requestDefaultSuggestions(Request request, Callback callback) {
|
||||
getSuggestions(request, callback, Collections.<String> emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void requestSuggestions(Request request, Callback callback) {
|
||||
String normalizedQuery = request.getQuery().trim();
|
||||
if (normalizedQuery == null || normalizedQuery.isEmpty()) {
|
||||
requestDefaultSuggestions(request, callback);
|
||||
} else {
|
||||
Iterable<String> queryTokens = Collections.singleton(normalizedQuery);
|
||||
getSuggestions(request, callback, queryTokens);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isDisplayStringHTML() {
|
||||
return true;
|
||||
}
|
||||
|
||||
class SimpleSuggestion implements Suggestion {
|
||||
|
||||
private static final String STRONG_TAG_OPEN = "<strong>", STRONG_TAG_CLOSE = "</strong>";
|
||||
private static final String ITALIC_TAG_OPEN = "<em>", ITALIC_TAG_CLOSE = "</em>";
|
||||
private final T suggestObject;
|
||||
private final Iterable<String> queryTokens;
|
||||
|
||||
private SimpleSuggestion(T suggestObject, Iterable<String> queryTokens) {
|
||||
this.suggestObject = suggestObject;
|
||||
this.queryTokens = queryTokens;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayString() {
|
||||
SafeHtmlBuilder builder = new SafeHtmlBuilder();
|
||||
appendHighlighted(builder, createSuggestionKeyString(suggestObject));
|
||||
String additionalString = createSuggestionAdditionalDisplayString(suggestObject);
|
||||
if (additionalString != null && !additionalString.isEmpty()) {
|
||||
builder.append(SafeHtmlUtils.fromTrustedString(ITALIC_TAG_OPEN));
|
||||
builder.append(SafeHtmlUtils.fromSafeConstant(" - "));
|
||||
appendHighlighted(builder, additionalString);
|
||||
builder.append(SafeHtmlUtils.fromTrustedString(ITALIC_TAG_CLOSE));
|
||||
}
|
||||
return builder.toSafeHtml().asString();
|
||||
}
|
||||
|
||||
private void appendHighlighted(SafeHtmlBuilder builder, String displayString) {
|
||||
String normalizedString = displayString.toLowerCase();
|
||||
int cursor = 0;
|
||||
while (true) {
|
||||
int index = displayString.length();
|
||||
String matchToken = null;
|
||||
for (String token : queryTokens) {
|
||||
int matchIndex = normalizedString.indexOf(token, cursor);
|
||||
if (matchIndex >= 0 && matchIndex < index) {
|
||||
index = matchIndex;
|
||||
matchToken = token;
|
||||
}
|
||||
}
|
||||
if (matchToken != null) {
|
||||
builder.appendEscaped(displayString.substring(cursor, index));
|
||||
builder.append(SafeHtmlUtils.fromTrustedString(STRONG_TAG_OPEN));
|
||||
builder.appendEscaped(displayString.substring(index, index + matchToken.length()));
|
||||
builder.append(SafeHtmlUtils.fromTrustedString(STRONG_TAG_CLOSE));
|
||||
cursor = index + matchToken.length();
|
||||
} else {
|
||||
builder.appendEscaped(displayString.substring(cursor));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReplacementString() {
|
||||
return createSuggestionKeyString(suggestObject);
|
||||
}
|
||||
|
||||
public T getSuggestObject() {
|
||||
return suggestObject;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.sap.sailing.gwt.common.client.suggestion;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.sap.sailing.domain.common.BoatClassMasterdata;
|
||||
|
||||
public class BoatClassMasterdataSuggestOracle extends AbstractListSuggestOracle<BoatClassMasterdata> {
|
||||
|
||||
public BoatClassMasterdataSuggestOracle() {
|
||||
this.setSelectableValues(Arrays.asList(BoatClassMasterdata.values()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String createSuggestionKeyString(BoatClassMasterdata value) {
|
||||
return value.getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String createSuggestionAdditionalDisplayString(BoatClassMasterdata value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<String> getMatchingStrings(BoatClassMasterdata value) {
|
||||
return value.getBoatClassNames();
|
||||
}
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.sap.sailing.gwt.common.client.suggestion;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
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.user.client.ui.SuggestBox;
|
||||
import com.google.gwt.user.client.ui.SuggestOracle;
|
||||
import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
|
||||
public class CustomSuggestBox<T> extends SuggestBox {
|
||||
|
||||
public CustomSuggestBox(AbstractSuggestOracle<T> suggestOracle) {
|
||||
this(suggestOracle, new CustomSuggestionDisplay());
|
||||
}
|
||||
|
||||
public CustomSuggestBox(AbstractSuggestOracle<T> suggestOracle, SuggestionDisplay suggestionDisplay) {
|
||||
super(suggestOracle, new TextBox(), suggestionDisplay);
|
||||
}
|
||||
|
||||
public final HandlerRegistration addSuggestionSelectionHandler(final SuggestionSelectionHandler<T> handler) {
|
||||
return this.addSelectionHandler(new SelectionHandler<SuggestOracle.Suggestion>() {
|
||||
@Override @SuppressWarnings("unchecked")
|
||||
public void onSelection(SelectionEvent<Suggestion> event) {
|
||||
handler.onSuggestionSelected(
|
||||
((AbstractSuggestOracle<T>.SimpleSuggestion) event.getSelectedItem()).getSuggestObject());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public interface SuggestionSelectionHandler<T> {
|
||||
void onSuggestionSelected(T suggestObject);
|
||||
}
|
||||
|
||||
private static class CustomSuggestionDisplay extends DefaultSuggestionDisplay {
|
||||
@Override
|
||||
protected void showSuggestions(SuggestBox suggestBox, Collection<? extends Suggestion> suggestions,
|
||||
boolean isDisplayStringHTML, boolean isAutoSelectEnabled, SuggestionCallback callback) {
|
||||
super.showSuggestions(suggestBox, suggestions, isDisplayStringHTML, isAutoSelectEnabled, callback);
|
||||
getPopupPanel().getElement().getStyle().setProperty("maxWidth", suggestBox.getOffsetWidth(), Unit.PX);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-4
@@ -18,7 +18,6 @@ import com.sap.sailing.gwt.home.desktop.places.start.StartActivityProxy;
|
||||
import com.sap.sailing.gwt.home.desktop.places.user.profile.UserProfileActivityProxy;
|
||||
import com.sap.sailing.gwt.home.desktop.places.whatsnew.WhatsNewActivityProxy;
|
||||
import com.sap.sailing.gwt.home.desktop.places.whatsnew.WhatsNewPlace;
|
||||
import com.sap.sailing.gwt.home.shared.ExperimentalFeatures;
|
||||
import com.sap.sailing.gwt.home.shared.SwitchingEntryPoint;
|
||||
import com.sap.sailing.gwt.home.shared.app.ApplicationPlaceUpdater;
|
||||
import com.sap.sailing.gwt.home.shared.places.error.ErrorPlace;
|
||||
@@ -69,9 +68,6 @@ public class DesktopActivityMapper implements ActivityMapper {
|
||||
} else if (place instanceof EventsPlace) {
|
||||
return new EventsActivityProxy((EventsPlace) place, clientFactory, clientFactory.getHomePlacesNavigator());
|
||||
} else if (place instanceof AbstractUserProfilePlace) {
|
||||
if (!ExperimentalFeatures.SHOW_USER_MANAGEMENT_ON_DESKTOP) {
|
||||
return new StartActivityProxy(new StartPlace(), clientFactory);
|
||||
}
|
||||
return new UserProfileActivityProxy((AbstractUserProfilePlace) place, clientFactory, clientFactory.getHomePlacesNavigator());
|
||||
} else if (place instanceof StartPlace) {
|
||||
return new StartActivityProxy((StartPlace) place, clientFactory);
|
||||
|
||||
+2
-112
@@ -1,128 +1,18 @@
|
||||
package com.sap.sailing.gwt.home.desktop.app;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gwt.place.shared.PlaceController;
|
||||
import com.sap.sailing.gwt.home.desktop.places.aboutus.AboutUsPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.contact.ContactPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.multiregatta.regattastab.MultiregattaRegattasPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.regatta.AbstractEventRegattaPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.regatta.analyticstab.RegattaCompetitorAnalyticsPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.regatta.leaderboardtab.RegattaLeaderboardPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.regatta.overviewtab.RegattaOverviewPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.sponsoring.SponsoringPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.whatsnew.WhatsNewPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.whatsnew.WhatsNewPlace.WhatsNewNavigationTabs;
|
||||
import com.sap.sailing.gwt.home.shared.app.AbstractPlaceNavigator;
|
||||
import com.sap.sailing.gwt.home.shared.app.HomePlacesNavigator;
|
||||
import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
|
||||
import com.sap.sailing.gwt.home.shared.places.event.AbstractEventPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.event.EventDefaultPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.events.EventsPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.fakeseries.SeriesDefaultPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.imprint.ImprintPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.solutions.SolutionsPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.solutions.SolutionsPlace.SolutionsNavigationTabs;
|
||||
import com.sap.sailing.gwt.home.shared.places.start.StartPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.confirmation.ConfirmationPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.confirmation.ConfirmationPlace.Action;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.passwordreset.PasswordResetPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.AbstractUserProfilePlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.UserProfileDefaultPlace;
|
||||
import com.sap.sailing.gwt.ui.client.EntryPointLinkFactory;
|
||||
|
||||
public class DesktopPlacesNavigator extends AbstractPlaceNavigator {
|
||||
public class DesktopPlacesNavigator extends HomePlacesNavigator {
|
||||
|
||||
protected DesktopPlacesNavigator(PlaceController placeController, boolean isStandaloneServer) {
|
||||
super(placeController, isStandaloneServer);
|
||||
}
|
||||
|
||||
public PlaceNavigation<StartPlace> getHomeNavigation() {
|
||||
return createGlobalPlaceNavigation(new StartPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<EventsPlace> getEventsNavigation() {
|
||||
return createGlobalPlaceNavigation(new EventsPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<SolutionsPlace> getSolutionsNavigation(SolutionsNavigationTabs navigationTab) {
|
||||
return createLocalPlaceNavigation(new SolutionsPlace(navigationTab));
|
||||
}
|
||||
|
||||
public PlaceNavigation<WhatsNewPlace> getWhatsNewNavigation(WhatsNewNavigationTabs navigationTab) {
|
||||
return createLocalPlaceNavigation(new WhatsNewPlace(navigationTab));
|
||||
}
|
||||
|
||||
public String getSimulatorURL() {
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
return EntryPointLinkFactory.createSimulatorLink(parameters);
|
||||
}
|
||||
|
||||
public PlaceNavigation<SponsoringPlace> getSponsoringNavigation() {
|
||||
return createGlobalPlaceNavigation(new SponsoringPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<AboutUsPlace> getAboutUsNavigation() {
|
||||
return createGlobalPlaceNavigation(new AboutUsPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<ContactPlace> getContactNavigation() {
|
||||
return createGlobalPlaceNavigation(new ContactPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<ImprintPlace> getImprintNavigation() {
|
||||
return createGlobalPlaceNavigation(new ImprintPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<ConfirmationPlace> getMailVerifiedConfirmationNavigation() {
|
||||
return createLocalPlaceNavigation(new ConfirmationPlace(Action.MAIL_VERIFIED));
|
||||
}
|
||||
|
||||
public PlaceNavigation<ConfirmationPlace> getPasswordResettedConfirmationNavigation(String username) {
|
||||
return createLocalPlaceNavigation(new ConfirmationPlace(Action.RESET_EXECUTED, username));
|
||||
}
|
||||
|
||||
public PlaceNavigation<PasswordResetPlace> getPasswordResetNavigation() {
|
||||
return createLocalPlaceNavigation(new PasswordResetPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<MultiregattaRegattasPlace> getEventRegattasNavigation(String eventUuidAsString, String baseUrl, boolean isOnRemoteServer) {
|
||||
MultiregattaRegattasPlace eventPlace = new MultiregattaRegattasPlace(eventUuidAsString);
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, eventPlace);
|
||||
}
|
||||
|
||||
public PlaceNavigation<SeriesDefaultPlace> getEventSeriesNavigation(String seriesId, String baseUrl, boolean isOnRemoteServer) {
|
||||
SeriesDefaultPlace place = new SeriesDefaultPlace(seriesId);
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, place);
|
||||
}
|
||||
|
||||
public PlaceNavigation<EventDefaultPlace> getEventNavigation(String eventUuidAsString, String baseUrl, boolean isOnRemoteServer) {
|
||||
EventDefaultPlace eventPlace = new EventDefaultPlace(eventUuidAsString);
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, eventPlace);
|
||||
}
|
||||
|
||||
public <P extends AbstractEventPlace> PlaceNavigation<P> getEventNavigation(P place, String baseUrl,
|
||||
boolean isOnRemoteServer) {
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, place);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public PlaceNavigation<AbstractEventRegattaPlace> getRegattaNavigation(String eventUuidAsString, String leaderboardIdAsNameString, String baseUrl, boolean isOnRemoteServer) {
|
||||
RegattaOverviewPlace eventPlace = new RegattaOverviewPlace(eventUuidAsString, leaderboardIdAsNameString);
|
||||
return (PlaceNavigation) createPlaceNavigation(baseUrl, isOnRemoteServer, eventPlace);
|
||||
}
|
||||
|
||||
public PlaceNavigation<RegattaCompetitorAnalyticsPlace> getCompetitorAnalyticsNavigation(String eventUuidAsString, String regattaId, String baseUrl, boolean isOnRemoteServer) {
|
||||
RegattaCompetitorAnalyticsPlace regattaPlace = new RegattaCompetitorAnalyticsPlace(eventUuidAsString, regattaId);
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, regattaPlace);
|
||||
}
|
||||
|
||||
public PlaceNavigation<RegattaLeaderboardPlace> getLeaderboardNavigation(String eventUuidAsString, String regattaId, String baseUrl, boolean isOnRemoteServer) {
|
||||
RegattaLeaderboardPlace regattaPlace = new RegattaLeaderboardPlace(eventUuidAsString, regattaId);
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, regattaPlace);
|
||||
}
|
||||
|
||||
public PlaceNavigation<? extends AbstractUserProfilePlace> getUserProfileNavigation() {
|
||||
return createLocalPlaceNavigation(new UserProfileDefaultPlace());
|
||||
}
|
||||
}
|
||||
|
||||
-4
@@ -24,7 +24,6 @@ import com.sap.sailing.gwt.common.client.i18n.TextMessages;
|
||||
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.desktop.app.DesktopPlacesNavigator;
|
||||
import com.sap.sailing.gwt.home.shared.ExperimentalFeatures;
|
||||
import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
|
||||
import com.sap.sailing.gwt.home.shared.places.event.AbstractEventPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.events.EventsPlace;
|
||||
@@ -97,9 +96,6 @@ public class Header extends Composite {
|
||||
});
|
||||
|
||||
authenticationMenuView = new AuthenticationMenuViewImpl(usermenu, HeaderResources.INSTANCE.css().loggedin(), HeaderResources.INSTANCE.css().open());
|
||||
if (!ExperimentalFeatures.SHOW_USER_MANAGEMENT_ON_DESKTOP) {
|
||||
usermenu.removeFromParent();
|
||||
}
|
||||
}
|
||||
|
||||
@UiHandler("startPageLink")
|
||||
|
||||
+1
@@ -46,5 +46,6 @@ public class MainMedia extends Composite {
|
||||
for (SailingImageDTO image : photos) {
|
||||
imageCarousel.addImage(image);
|
||||
}
|
||||
imageCarousel.setInfiniteScrolling(true);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -225,7 +225,7 @@ public class OldLeaderboard extends Composite implements BusyStateChangeListener
|
||||
@Override
|
||||
public void onBusyStateChange(boolean busyState) {
|
||||
busyIndicator.setBusy(busyState);
|
||||
if(delegate != null) {
|
||||
if (delegate != null) {
|
||||
delegate.setBusyState(busyState);
|
||||
}
|
||||
}
|
||||
|
||||
-7
@@ -15,7 +15,6 @@ import com.sap.sailing.gwt.home.mobile.places.start.StartActivityProxy;
|
||||
import com.sap.sailing.gwt.home.mobile.places.user.authentication.AuthenticationActivityProxy;
|
||||
import com.sap.sailing.gwt.home.mobile.places.user.authentication.AuthenticationPlace;
|
||||
import com.sap.sailing.gwt.home.mobile.places.user.profile.UserProfileActivityProxy;
|
||||
import com.sap.sailing.gwt.home.shared.ExperimentalFeatures;
|
||||
import com.sap.sailing.gwt.home.shared.SwitchingEntryPoint;
|
||||
import com.sap.sailing.gwt.home.shared.app.ApplicationPlaceUpdater;
|
||||
import com.sap.sailing.gwt.home.shared.places.error.ErrorPlace;
|
||||
@@ -68,9 +67,6 @@ public class MobileActivityMapper implements ActivityMapper {
|
||||
} else if (place instanceof SolutionsPlace) {
|
||||
return new SolutionsActivityProxy((SolutionsPlace) place, clientFactory);
|
||||
} else if (place instanceof AbstractUserProfilePlace) {
|
||||
if (!ExperimentalFeatures.SHOW_USER_MANAGEMENT_ON_MOBILE) {
|
||||
return new StartActivityProxy(new StartPlace(), clientFactory);
|
||||
}
|
||||
return new UserProfileActivityProxy((AbstractUserProfilePlace) place, clientFactory);
|
||||
} else if (place instanceof AuthenticationPlace) {
|
||||
return new AuthenticationActivityProxy((AuthenticationPlace) place, clientFactory);
|
||||
@@ -79,9 +75,6 @@ public class MobileActivityMapper implements ActivityMapper {
|
||||
} else if (place instanceof PasswordResetPlace) {
|
||||
return new PasswordResetActivityProxy((PasswordResetPlace) place, clientFactory);
|
||||
} else if (place instanceof AbstractUserProfilePlace) {
|
||||
if (!ExperimentalFeatures.SHOW_USER_MANAGEMENT_ON_MOBILE) {
|
||||
return new StartActivityProxy(new StartPlace(), clientFactory);
|
||||
}
|
||||
return new UserProfileActivityProxy((AbstractUserProfilePlace) place, clientFactory);
|
||||
} else if (place instanceof AuthenticationPlace) {
|
||||
return new AuthenticationActivityProxy((AuthenticationPlace) place, clientFactory);
|
||||
|
||||
+4
-101
@@ -4,122 +4,25 @@ import java.util.List;
|
||||
|
||||
import com.google.gwt.place.shared.PlaceController;
|
||||
import com.sap.sailing.gwt.home.communication.event.news.NewsEntryDTO;
|
||||
import com.sap.sailing.gwt.home.desktop.places.aboutus.AboutUsPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.contact.ContactPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.regatta.overviewtab.RegattaOverviewPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.whatsnew.WhatsNewPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.whatsnew.WhatsNewPlace.WhatsNewNavigationTabs;
|
||||
import com.sap.sailing.gwt.home.mobile.places.event.latestnews.LatestNewsPlace;
|
||||
import com.sap.sailing.gwt.home.mobile.places.user.authentication.AuthenticationPlace;
|
||||
import com.sap.sailing.gwt.home.shared.app.AbstractPlaceNavigator;
|
||||
import com.sap.sailing.gwt.home.shared.app.HomePlacesNavigator;
|
||||
import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
|
||||
import com.sap.sailing.gwt.home.shared.places.event.AbstractEventPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.event.EventContext;
|
||||
import com.sap.sailing.gwt.home.shared.places.event.EventDefaultPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.events.EventsPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.fakeseries.AbstractSeriesPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.fakeseries.SeriesDefaultPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.imprint.ImprintPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.solutions.SolutionsPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.solutions.SolutionsPlace.SolutionsNavigationTabs;
|
||||
import com.sap.sailing.gwt.home.shared.places.start.StartPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.confirmation.ConfirmationPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.confirmation.ConfirmationPlace.Action;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.passwordreset.PasswordResetPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.AbstractUserProfilePlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.UserProfileDefaultPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.preferences.UserProfilePreferencesPlace;
|
||||
|
||||
public class MobilePlacesNavigator extends AbstractPlaceNavigator {
|
||||
public class MobilePlacesNavigator extends HomePlacesNavigator {
|
||||
|
||||
protected MobilePlacesNavigator(PlaceController placeController, boolean isStandaloneServer) {
|
||||
super(placeController, isStandaloneServer);
|
||||
}
|
||||
|
||||
public PlaceNavigation<StartPlace> getHomeNavigation() {
|
||||
return createGlobalPlaceNavigation(new StartPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<EventsPlace> getEventsNavigation() {
|
||||
return createGlobalPlaceNavigation(new EventsPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<EventDefaultPlace> getEventNavigation(String eventUuidAsString, String baseUrl,
|
||||
boolean isOnRemoteServer) {
|
||||
EventDefaultPlace eventPlace = new EventDefaultPlace(eventUuidAsString);
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, eventPlace);
|
||||
}
|
||||
|
||||
public PlaceNavigation<SeriesDefaultPlace> getEventSeriesNavigation(String seriesId, String baseUrl,
|
||||
boolean isOnRemoteServer) {
|
||||
SeriesDefaultPlace place = new SeriesDefaultPlace(seriesId);
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, place);
|
||||
}
|
||||
|
||||
public <P extends AbstractSeriesPlace> PlaceNavigation<P> getSeriesNavigation(P place, String baseUrl,
|
||||
boolean isOnRemoteServer) {
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, place);
|
||||
}
|
||||
|
||||
public <P extends AbstractEventPlace> PlaceNavigation<P> getEventNavigation(P place, String baseUrl,
|
||||
boolean isOnRemoteServer) {
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, place);
|
||||
}
|
||||
|
||||
public PlaceNavigation<LatestNewsPlace> getEventLastestNewsNavigation(EventContext ctx, List<NewsEntryDTO> newsEntries,
|
||||
String baseUrl, boolean isOnRemoteServer) {
|
||||
public PlaceNavigation<LatestNewsPlace> getEventLastestNewsNavigation(EventContext ctx,
|
||||
List<NewsEntryDTO> newsEntries, String baseUrl, boolean isOnRemoteServer) {
|
||||
LatestNewsPlace place = new LatestNewsPlace(ctx, newsEntries);
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, place);
|
||||
}
|
||||
|
||||
// NOT MOBILE PLACES
|
||||
|
||||
public PlaceNavigation<SolutionsPlace> getSolutionsNavigation() {
|
||||
return createLocalPlaceNavigation(new SolutionsPlace(SolutionsNavigationTabs.SailingAnalytics));
|
||||
}
|
||||
|
||||
public PlaceNavigation<WhatsNewPlace> getWhatsNewNavigation(WhatsNewNavigationTabs navigationTab) {
|
||||
return createLocalPlaceNavigation(new WhatsNewPlace(navigationTab));
|
||||
}
|
||||
|
||||
public PlaceNavigation<AboutUsPlace> getAboutUsNavigation() {
|
||||
return createGlobalPlaceNavigation(new AboutUsPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<ImprintPlace> getImprintNavigation() {
|
||||
return createGlobalPlaceNavigation(new ImprintPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<ContactPlace> getContactNavigation() {
|
||||
return createGlobalPlaceNavigation(new ContactPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<?> getRegattaOverviewNavigation(String eventId, String leaderboardName, String baseUrl,
|
||||
boolean isOnRemoteServer) {
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, new RegattaOverviewPlace(eventId, leaderboardName));
|
||||
}
|
||||
|
||||
public PlaceNavigation<AuthenticationPlace> getSignInNavigation() {
|
||||
return createLocalPlaceNavigation(new AuthenticationPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<? extends AbstractUserProfilePlace> getUserProfileNavigation() {
|
||||
return createLocalPlaceNavigation(new UserProfileDefaultPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<? extends AbstractUserProfilePlace> getUserPreferencesNavigation() {
|
||||
return createLocalPlaceNavigation(new UserProfilePreferencesPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<ConfirmationPlace> getMailVerifiedConfirmationNavigation() {
|
||||
return createLocalPlaceNavigation(new ConfirmationPlace(Action.MAIL_VERIFIED));
|
||||
}
|
||||
|
||||
public PlaceNavigation<ConfirmationPlace> getPasswordResettedConfirmationNavigation(String username) {
|
||||
return createLocalPlaceNavigation(new ConfirmationPlace(Action.RESET_EXECUTED, username));
|
||||
}
|
||||
|
||||
public PlaceNavigation<PasswordResetPlace> getPasswordResetNavigation() {
|
||||
return createLocalPlaceNavigation(new PasswordResetPlace());
|
||||
}
|
||||
}
|
||||
|
||||
+12
-18
@@ -17,9 +17,9 @@ import com.google.gwt.user.client.ui.Widget;
|
||||
import com.google.web.bindery.event.shared.EventBus;
|
||||
import com.sap.sailing.gwt.common.client.i18n.TextMessages;
|
||||
import com.sap.sailing.gwt.home.mobile.app.MobilePlacesNavigator;
|
||||
import com.sap.sailing.gwt.home.shared.ExperimentalFeatures;
|
||||
import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
|
||||
import com.sap.sailing.gwt.home.shared.app.ResettableNavigationPathDisplay;
|
||||
import com.sap.sailing.gwt.home.shared.places.solutions.SolutionsPlace.SolutionsNavigationTabs;
|
||||
import com.sap.sailing.gwt.home.shared.utils.DropdownHandler;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.gwt.client.LinkUtil;
|
||||
@@ -64,7 +64,7 @@ public class Header extends Composite {
|
||||
|
||||
addNavigation(placeNavigator.getHomeNavigation(), StringMessages.INSTANCE.home());
|
||||
addNavigation(placeNavigator.getEventsNavigation(), StringMessages.INSTANCE.events());
|
||||
addNavigation(placeNavigator.getSolutionsNavigation(), TextMessages.INSTANCE.solutions());
|
||||
addNavigation(placeNavigator.getSolutionsNavigation(SolutionsNavigationTabs.SailingAnalytics), TextMessages.INSTANCE.solutions());
|
||||
addUrl("https://blog.sapsailing.com", TextMessages.INSTANCE.blog());
|
||||
signInNavigationItem = addNavigation(com.sap.sse.security.ui.client.i18n.StringMessages.INSTANCE.signIn(), new Runnable() {
|
||||
@Override
|
||||
@@ -94,22 +94,16 @@ public class Header extends Composite {
|
||||
}
|
||||
});
|
||||
|
||||
if (ExperimentalFeatures.SHOW_USER_MANAGEMENT_ON_MOBILE) {
|
||||
eventBus.addHandler(AuthenticationContextEvent.TYPE, new AuthenticationContextEvent.Handler() {
|
||||
@Override
|
||||
public void onUserChangeEvent(AuthenticationContextEvent event) {
|
||||
String loggedInStyle = HeaderResources.INSTANCE.css().header_navigation_iconsignedin();
|
||||
UIObject.setStyleName(dropdownTriggerUi, loggedInStyle, event.getCtx().isLoggedIn());
|
||||
signInNavigationItem.setVisible(!event.getCtx().isLoggedIn());
|
||||
userDetailsNavigationItem.setVisible(event.getCtx().isLoggedIn());
|
||||
signOutNavigationItem.setVisible(event.getCtx().isLoggedIn());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
signInNavigationItem.removeFromParent();
|
||||
userDetailsNavigationItem.removeFromParent();
|
||||
signOutNavigationItem.removeFromParent();
|
||||
}
|
||||
eventBus.addHandler(AuthenticationContextEvent.TYPE, new AuthenticationContextEvent.Handler() {
|
||||
@Override
|
||||
public void onUserChangeEvent(AuthenticationContextEvent event) {
|
||||
String loggedInStyle = HeaderResources.INSTANCE.css().header_navigation_iconsignedin();
|
||||
UIObject.setStyleName(dropdownTriggerUi, loggedInStyle, event.getCtx().isLoggedIn());
|
||||
signInNavigationItem.setVisible(!event.getCtx().isLoggedIn());
|
||||
userDetailsNavigationItem.setVisible(event.getCtx().isLoggedIn());
|
||||
signOutNavigationItem.setVisible(event.getCtx().isLoggedIn());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ResettableNavigationPathDisplay getNavigationPathDisplay() {
|
||||
|
||||
+1
-2
@@ -8,7 +8,6 @@ import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.sap.sailing.gwt.home.communication.race.SimpleRaceMetadataDTO;
|
||||
import com.sap.sailing.gwt.home.communication.race.SimpleRaceMetadataDTO.RaceTrackingState;
|
||||
import com.sap.sailing.gwt.home.shared.ExperimentalFeatures;
|
||||
import com.sap.sailing.gwt.home.shared.partials.regattacompetition.AbstractRegattaCompetitionFleetRace;
|
||||
import com.sap.sailing.gwt.home.shared.partials.regattacompetition.RegattaCompetitionPresenter;
|
||||
|
||||
@@ -70,7 +69,7 @@ public class RegattaCompetitionFleetRace extends AbstractRegattaCompetitionFleet
|
||||
|
||||
@Override
|
||||
protected boolean isUntrackedRace(RaceTrackingState trackingState) {
|
||||
return super.isUntrackedRace(trackingState) || !ExperimentalFeatures.ENABLE_RACE_VIEWER_LINK_ON_MOBILE;
|
||||
return super.isUntrackedRace(trackingState);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ public class SearchResultItem extends AbstractSearchResultItem {
|
||||
init(anchorUi = uiBinder.createAndBindUi(this), item);
|
||||
SearchResultEventInfoDTO event = item.getEvents().iterator().next();
|
||||
String eventId = String.valueOf(event.getId()), leaderboardName = item.getLeaderboardName(), baseUrl = item.getBaseUrl();
|
||||
PlaceNavigation<?> regattaNavigation = navigator.getRegattaOverviewNavigation(eventId, leaderboardName, baseUrl, item.isOnRemoteServer());
|
||||
PlaceNavigation<?> regattaNavigation = navigator.getRegattaNavigation(eventId, leaderboardName, baseUrl, item.isOnRemoteServer());
|
||||
regattaNavigation.configureAnchorElement(anchorUi);
|
||||
}
|
||||
|
||||
|
||||
+1
-3
@@ -19,7 +19,6 @@ import com.sap.sailing.gwt.home.mobile.partials.quickfinder.Quickfinder;
|
||||
import com.sap.sailing.gwt.home.mobile.partials.regattacompetition.RegattaCompetition;
|
||||
import com.sap.sailing.gwt.home.mobile.places.QuickfinderPresenter;
|
||||
import com.sap.sailing.gwt.home.mobile.places.event.AbstractEventView;
|
||||
import com.sap.sailing.gwt.home.shared.ExperimentalFeatures;
|
||||
import com.sap.sailing.gwt.home.shared.partials.filter.FilterPresenter;
|
||||
import com.sap.sailing.gwt.home.shared.partials.filter.FilterValueChangeHandler;
|
||||
import com.sap.sailing.gwt.home.shared.partials.filter.FilterWidget;
|
||||
@@ -68,8 +67,7 @@ public class RacesViewImpl extends AbstractEventView<RacesView.Presenter> implem
|
||||
|
||||
@Override
|
||||
protected String getRaceViewerURL(SimpleRaceMetadataDTO raceMetadata, String mode) {
|
||||
return ExperimentalFeatures.ENABLE_RACE_VIEWER_LINK_ON_MOBILE
|
||||
? currentPresenter.getRaceViewerURL(raceMetadata, mode) : null;
|
||||
return currentPresenter.getRaceViewerURL(raceMetadata, mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-12
@@ -9,18 +9,6 @@ public class ExperimentalFeatures {
|
||||
* Provide button to show the competitor analytics in fullscreen view (work in progress)
|
||||
*/
|
||||
public static final boolean SHOW_COMPETITOR_ANALYTICS_FULLSCREEN_VIEWER = false;
|
||||
/**
|
||||
* Enables/disables the link to the race board on mobile races view (competition format), in case of a tracked race
|
||||
*/
|
||||
public static final boolean ENABLE_RACE_VIEWER_LINK_ON_MOBILE = true;
|
||||
/**
|
||||
* Enables/disables user management on desktop by showing/hiding the respective menu in the upper right corner.
|
||||
*/
|
||||
public static final boolean SHOW_USER_MANAGEMENT_ON_DESKTOP = true;
|
||||
/**
|
||||
* Enables/disables user management on mobile UI by showing/hiding the respective menu item(s) in the upper right menu.
|
||||
*/
|
||||
public static final boolean SHOW_USER_MANAGEMENT_ON_MOBILE = true;
|
||||
/**
|
||||
* Provide buttons for user management login via social services like facebook or google.
|
||||
*/
|
||||
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package com.sap.sailing.gwt.home.shared.app;
|
||||
|
||||
import com.google.gwt.place.shared.PlaceController;
|
||||
import com.sap.sailing.gwt.home.desktop.places.aboutus.AboutUsPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.contact.ContactPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.regatta.overviewtab.RegattaOverviewPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.whatsnew.WhatsNewPlace;
|
||||
import com.sap.sailing.gwt.home.desktop.places.whatsnew.WhatsNewPlace.WhatsNewNavigationTabs;
|
||||
import com.sap.sailing.gwt.home.shared.places.event.AbstractEventPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.event.EventDefaultPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.events.EventsPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.fakeseries.AbstractSeriesPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.fakeseries.SeriesDefaultPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.imprint.ImprintPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.solutions.SolutionsPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.solutions.SolutionsPlace.SolutionsNavigationTabs;
|
||||
import com.sap.sailing.gwt.home.shared.places.start.StartPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.confirmation.ConfirmationPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.confirmation.ConfirmationPlace.Action;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.passwordreset.PasswordResetPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.AbstractUserProfilePlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.UserProfileDefaultPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.preferences.UserProfilePreferencesPlace;
|
||||
|
||||
public class HomePlacesNavigator extends AbstractPlaceNavigator {
|
||||
|
||||
protected HomePlacesNavigator(PlaceController placeController, boolean isStandaloneServer) {
|
||||
super(placeController, isStandaloneServer);
|
||||
}
|
||||
|
||||
public PlaceNavigation<StartPlace> getHomeNavigation() {
|
||||
return createGlobalPlaceNavigation(new StartPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<EventsPlace> getEventsNavigation() {
|
||||
return createGlobalPlaceNavigation(new EventsPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<SolutionsPlace> getSolutionsNavigation(SolutionsNavigationTabs navigationTab) {
|
||||
return createLocalPlaceNavigation(new SolutionsPlace(navigationTab));
|
||||
}
|
||||
|
||||
public PlaceNavigation<WhatsNewPlace> getWhatsNewNavigation(WhatsNewNavigationTabs navigationTab) {
|
||||
return createLocalPlaceNavigation(new WhatsNewPlace(navigationTab));
|
||||
}
|
||||
|
||||
public PlaceNavigation<AboutUsPlace> getAboutUsNavigation() {
|
||||
return createGlobalPlaceNavigation(new AboutUsPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<ContactPlace> getContactNavigation() {
|
||||
return createGlobalPlaceNavigation(new ContactPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<ImprintPlace> getImprintNavigation() {
|
||||
return createGlobalPlaceNavigation(new ImprintPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<EventDefaultPlace> getEventNavigation(String eventUuidAsString, String baseUrl,
|
||||
boolean isOnRemoteServer) {
|
||||
EventDefaultPlace eventPlace = new EventDefaultPlace(eventUuidAsString);
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, eventPlace);
|
||||
}
|
||||
|
||||
public <P extends AbstractEventPlace> PlaceNavigation<P> getEventNavigation(P place, String baseUrl,
|
||||
boolean isOnRemoteServer) {
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, place);
|
||||
}
|
||||
|
||||
public PlaceNavigation<SeriesDefaultPlace> getEventSeriesNavigation(String seriesId, String baseUrl,
|
||||
boolean isOnRemoteServer) {
|
||||
SeriesDefaultPlace place = new SeriesDefaultPlace(seriesId);
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, place);
|
||||
}
|
||||
|
||||
public <P extends AbstractSeriesPlace> PlaceNavigation<P> getSeriesNavigation(P place, String baseUrl,
|
||||
boolean isOnRemoteServer) {
|
||||
return createPlaceNavigation(baseUrl, isOnRemoteServer, place);
|
||||
}
|
||||
|
||||
public PlaceNavigation<RegattaOverviewPlace> getRegattaNavigation(String eventUuidAsString,
|
||||
String leaderboardIdAsNameString, String baseUrl, boolean isOnRemoteServer) {
|
||||
return getEventNavigation(new RegattaOverviewPlace(eventUuidAsString, leaderboardIdAsNameString), baseUrl,
|
||||
isOnRemoteServer);
|
||||
}
|
||||
|
||||
public PlaceNavigation<ConfirmationPlace> getMailVerifiedConfirmationNavigation() {
|
||||
return createLocalPlaceNavigation(new ConfirmationPlace(Action.MAIL_VERIFIED));
|
||||
}
|
||||
|
||||
public PlaceNavigation<ConfirmationPlace> getPasswordResettedConfirmationNavigation(String username) {
|
||||
return createLocalPlaceNavigation(new ConfirmationPlace(Action.RESET_EXECUTED, username));
|
||||
}
|
||||
|
||||
public PlaceNavigation<PasswordResetPlace> getPasswordResetNavigation() {
|
||||
return createLocalPlaceNavigation(new PasswordResetPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<? extends AbstractUserProfilePlace> getUserProfileNavigation() {
|
||||
return createLocalPlaceNavigation(new UserProfileDefaultPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<? extends AbstractUserProfilePlace> getUserPreferencesNavigation() {
|
||||
return createLocalPlaceNavigation(new UserProfilePreferencesPlace());
|
||||
}
|
||||
}
|
||||
+12
-13
@@ -1,7 +1,7 @@
|
||||
package com.sap.sailing.gwt.home.shared.app;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.AnchorElement;
|
||||
import com.google.gwt.http.client.UrlBuilder;
|
||||
import com.google.gwt.place.shared.Place;
|
||||
import com.google.gwt.place.shared.PlaceHistoryMapper;
|
||||
import com.google.gwt.user.client.DOM;
|
||||
@@ -9,6 +9,7 @@ import com.google.gwt.user.client.Event;
|
||||
import com.google.gwt.user.client.EventListener;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.sap.sse.gwt.client.LinkUtil;
|
||||
import com.sap.sse.gwt.settings.UrlBuilderUtil;
|
||||
|
||||
public class PlaceNavigation<T extends Place> {
|
||||
private final PlaceNavigator placeNavigator;
|
||||
@@ -53,27 +54,25 @@ public class PlaceNavigation<T extends Place> {
|
||||
}
|
||||
|
||||
private String buildPlaceUrl() {
|
||||
String url = "";
|
||||
if (isRemotePlace()) {
|
||||
url = baseUrl + "/gwt/Home.html";
|
||||
if (!GWT.isProdMode()) {
|
||||
url += "?gwt.codesvr=127.0.0.1:9997";
|
||||
}
|
||||
String localeValue = Window.Location.getParameter("locale");
|
||||
if (localeValue != null) {
|
||||
url += "?locale=" + localeValue;
|
||||
}
|
||||
final UrlBuilder urlBuilder = UrlBuilderUtil.createUrlBuilderFromBaseURLAndPathWithCleanParameters(baseUrl,
|
||||
"/gwt/Home.html");
|
||||
urlBuilder.setHash(getPlaceToken());
|
||||
return urlBuilder.buildString();
|
||||
}
|
||||
return url + getPlaceToken();
|
||||
return getPlaceTokenWithHash();
|
||||
}
|
||||
|
||||
public boolean isRemotePlace() {
|
||||
return isDestinationOnRemoteServer;
|
||||
}
|
||||
|
||||
private String getPlaceTokenWithHash() {
|
||||
return "#" + getPlaceToken();
|
||||
}
|
||||
|
||||
private String getPlaceToken() {
|
||||
return "#" + mapper.getToken(destinationPlace);
|
||||
|
||||
return mapper.getToken(destinationPlace);
|
||||
}
|
||||
|
||||
private boolean isLocationOnDefaultSapSailingServer(String urlToCheck) {
|
||||
|
||||
+3
-7
@@ -2,12 +2,13 @@ package com.sap.sailing.gwt.home.shared.partials.filter;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.sap.sailing.gwt.common.client.suggestion.AbstractSuggestOracle;
|
||||
import com.sap.sse.common.filter.Filter;
|
||||
|
||||
public abstract class AbstractAsyncSuggestBoxFilter<T, C> extends AbstractSuggestBoxFilter<T, C> {
|
||||
|
||||
protected AbstractAsyncSuggestBoxFilter(String placeholderText) {
|
||||
super(placeholderText);
|
||||
protected AbstractAsyncSuggestBoxFilter(AbstractSuggestOracle<C> suggestOracle, String placeholderText) {
|
||||
super(suggestOracle, placeholderText);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -15,11 +16,6 @@ public abstract class AbstractAsyncSuggestBoxFilter<T, C> extends AbstractSugges
|
||||
// Nothing to do here, because of external filtering
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final Iterable<String> getMatchingStrings(C value) {
|
||||
return null; // Not required here, because of external filtering
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final Filter<T> getFilter(String searchString) {
|
||||
return new Filter<T>() { // Return an always matching filter, because of external filtering
|
||||
|
||||
+9
-23
@@ -1,37 +1,23 @@
|
||||
package com.sap.sailing.gwt.home.shared.partials.filter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.user.client.ui.SuggestOracle.Callback;
|
||||
import com.google.gwt.user.client.ui.SuggestOracle.Request;
|
||||
import com.sap.sse.common.filter.AbstractListFilter;
|
||||
import com.sap.sailing.gwt.common.client.suggestion.AbstractListSuggestOracle;
|
||||
|
||||
public abstract class AbstractListSuggestBoxFilter<T, C> extends AbstractSuggestBoxFilter<T, C> {
|
||||
|
||||
private final List<C> suggestionObjectList = new ArrayList<>();
|
||||
protected final AbstractListFilter<C> suggestionMatchingFilter = new AbstractListFilter<C>() {
|
||||
@Override
|
||||
public Iterable<String> getStrings(C value) {
|
||||
return getMatchingStrings(value);
|
||||
}
|
||||
};
|
||||
|
||||
protected AbstractListSuggestBoxFilter(String placeholderText) {
|
||||
super(placeholderText);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getSuggestions(Request request, Callback callback, Iterable<String> queryTokens) {
|
||||
Iterable<C> filteredList = suggestionMatchingFilter.applyFilter(queryTokens, suggestionObjectList);
|
||||
this.setSuggestions(request, callback, filteredList, queryTokens);
|
||||
protected AbstractListSuggestBoxFilter(AbstractListSuggestOracle<C> suggestOracle, String placeholderText) {
|
||||
super(suggestOracle, placeholderText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectableValues(Collection<C> selectableValues) {
|
||||
suggestionObjectList.clear();
|
||||
suggestionObjectList.addAll(selectableValues);
|
||||
getSuggestOracle().setSelectableValues(selectableValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractListSuggestOracle<C> getSuggestOracle() {
|
||||
return (AbstractListSuggestOracle<C>) super.getSuggestOracle();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
-145
@@ -1,161 +1,28 @@
|
||||
package com.sap.sailing.gwt.home.shared.partials.filter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.event.logical.shared.SelectionEvent;
|
||||
import com.google.gwt.event.logical.shared.SelectionHandler;
|
||||
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
|
||||
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
|
||||
import com.google.gwt.user.client.ui.SuggestBox;
|
||||
import com.google.gwt.user.client.ui.SuggestBox.DefaultSuggestionDisplay;
|
||||
import com.google.gwt.user.client.ui.SuggestBox.SuggestionCallback;
|
||||
import com.google.gwt.user.client.ui.SuggestOracle;
|
||||
import com.google.gwt.user.client.ui.SuggestOracle.Callback;
|
||||
import com.google.gwt.user.client.ui.SuggestOracle.Request;
|
||||
import com.google.gwt.user.client.ui.SuggestOracle.Response;
|
||||
import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sailing.gwt.common.client.suggestion.AbstractSuggestOracle;
|
||||
import com.sap.sailing.gwt.common.client.suggestion.CustomSuggestBox;
|
||||
import com.sap.sailing.gwt.common.client.suggestion.CustomSuggestBox.SuggestionSelectionHandler;
|
||||
|
||||
public abstract class AbstractSuggestBoxFilter<T, C> extends AbstractTextInputFilter<T, C> {
|
||||
|
||||
private final ContainsSuggestOracle suggestOracle = new ContainsSuggestOracle();
|
||||
|
||||
protected AbstractSuggestBoxFilter(String placeholderText) {
|
||||
final SuggestBox suggestBox = new SuggestBox(suggestOracle, new TextBox(), new CustomSuggestionDisplay());
|
||||
initWidgets(suggestBox, placeholderText);
|
||||
suggestBox.addSelectionHandler(new SelectionHandler<SuggestOracle.Suggestion>() {
|
||||
private final AbstractSuggestOracle<C> suggestOracle;
|
||||
|
||||
protected AbstractSuggestBoxFilter(AbstractSuggestOracle<C> suggestOracle, String placeholderText) {
|
||||
final CustomSuggestBox<C> suggestBox = new CustomSuggestBox<>(this.suggestOracle = suggestOracle);
|
||||
suggestBox.addSuggestionSelectionHandler(new SuggestionSelectionHandler<C>() {
|
||||
@Override
|
||||
public void onSelection(SelectionEvent<Suggestion> event) {
|
||||
@SuppressWarnings("unchecked")
|
||||
C suggestObject = ((SimpleSuggestion) event.getSelectedItem()).suggestObject;
|
||||
public void onSuggestionSelected(C suggestObject) {
|
||||
AbstractSuggestBoxFilter.this.onSuggestionSelected(suggestObject);
|
||||
AbstractSuggestBoxFilter.super.update();
|
||||
}
|
||||
});
|
||||
initWidgets(suggestBox, placeholderText);
|
||||
}
|
||||
|
||||
protected final void setSuggestions(Request request, Callback callback, Iterable<C> suggestionObjects,
|
||||
Iterable<String> queryTokens) {
|
||||
List<Suggestion> suggestions = new ArrayList<>();
|
||||
List<String> normalizedQueryTokens = new ArrayList<>();
|
||||
for (String token : queryTokens) {
|
||||
normalizedQueryTokens.add(token.toLowerCase());
|
||||
}
|
||||
int count = 0;
|
||||
for (C match : suggestionObjects) {
|
||||
suggestions.add(new SimpleSuggestion(match, normalizedQueryTokens));
|
||||
if (++count >= request.getLimit()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Response response = new Response(suggestions);
|
||||
response.setMoreSuggestionsCount(Util.size(suggestionObjects) - count);
|
||||
callback.onSuggestionsReady(request, response);
|
||||
protected AbstractSuggestOracle<C> getSuggestOracle() {
|
||||
return suggestOracle;
|
||||
}
|
||||
|
||||
protected abstract void getSuggestions(Request request, Callback callback, Iterable<String> queryTokens);
|
||||
|
||||
protected abstract void onSuggestionSelected(C selectedItem);
|
||||
|
||||
protected abstract String createSuggestionKeyString(C value);
|
||||
|
||||
protected abstract String createSuggestionAdditionalDisplayString(C value);
|
||||
|
||||
protected abstract Iterable<String> getMatchingStrings(C value);
|
||||
|
||||
private class CustomSuggestionDisplay extends DefaultSuggestionDisplay {
|
||||
@Override
|
||||
protected void showSuggestions(SuggestBox suggestBox, Collection<? extends Suggestion> suggestions,
|
||||
boolean isDisplayStringHTML, boolean isAutoSelectEnabled, SuggestionCallback callback) {
|
||||
super.showSuggestions(suggestBox, suggestions, isDisplayStringHTML, isAutoSelectEnabled, callback);
|
||||
getPopupPanel().getElement().getStyle().setProperty("maxWidth", suggestBox.getOffsetWidth(), Unit.PX);
|
||||
}
|
||||
}
|
||||
|
||||
private class ContainsSuggestOracle extends SuggestOracle {
|
||||
|
||||
@Override
|
||||
public void requestDefaultSuggestions(Request request, Callback callback) {
|
||||
getSuggestions(request, callback, Collections.<String>emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestSuggestions(Request request, Callback callback) {
|
||||
String normalizedQuery = request.getQuery().trim();
|
||||
if (normalizedQuery == null || normalizedQuery.isEmpty()) {
|
||||
requestDefaultSuggestions(request, callback);
|
||||
} else {
|
||||
Iterable<String> queryTokens = Collections.singleton(normalizedQuery);
|
||||
getSuggestions(request, callback, queryTokens);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisplayStringHTML() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class SimpleSuggestion implements Suggestion {
|
||||
|
||||
private static final String STRONG_TAG_OPEN = "<strong>", STRONG_TAG_CLOSE = "</strong>";
|
||||
private static final String ITALIC_TAG_OPEN = "<em>", ITALIC_TAG_CLOSE = "</em>";
|
||||
private final C suggestObject;
|
||||
private final Iterable<String> queryTokens;
|
||||
|
||||
private SimpleSuggestion(C suggestObject, Iterable<String> queryTokens) {
|
||||
this.suggestObject = suggestObject;
|
||||
this.queryTokens = queryTokens;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayString() {
|
||||
SafeHtmlBuilder builder = new SafeHtmlBuilder();
|
||||
appendHighlighted(builder, createSuggestionKeyString(suggestObject));
|
||||
String additionalString = createSuggestionAdditionalDisplayString(suggestObject);
|
||||
if(additionalString != null && !additionalString.isEmpty()) {
|
||||
builder.append(SafeHtmlUtils.fromTrustedString(ITALIC_TAG_OPEN));
|
||||
builder.append(SafeHtmlUtils.fromSafeConstant(" - "));
|
||||
appendHighlighted(builder, additionalString);
|
||||
builder.append(SafeHtmlUtils.fromTrustedString(ITALIC_TAG_CLOSE));
|
||||
}
|
||||
return builder.toSafeHtml().asString();
|
||||
}
|
||||
|
||||
private void appendHighlighted(SafeHtmlBuilder builder, String displayString) {
|
||||
String normalizedString = displayString.toLowerCase();
|
||||
int cursor = 0;
|
||||
while(true) {
|
||||
int index = displayString.length();
|
||||
String matchToken = null;
|
||||
for (String token : queryTokens) {
|
||||
int matchIndex = normalizedString.indexOf(token, cursor);
|
||||
if (matchIndex >= 0 && matchIndex < index) {
|
||||
index = matchIndex;
|
||||
matchToken = token;
|
||||
}
|
||||
}
|
||||
if (matchToken != null) {
|
||||
builder.appendEscaped(displayString.substring(cursor, index));
|
||||
builder.append(SafeHtmlUtils.fromTrustedString(STRONG_TAG_OPEN));
|
||||
builder.appendEscaped(displayString.substring(index, index + matchToken.length()));
|
||||
builder.append(SafeHtmlUtils.fromTrustedString(STRONG_TAG_CLOSE));
|
||||
cursor = index + matchToken.length();
|
||||
} else {
|
||||
builder.appendEscaped(displayString.substring(cursor));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReplacementString() {
|
||||
return createSuggestionKeyString(suggestObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-17
@@ -4,10 +4,12 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.gwt.common.client.suggestion.AbstractListSuggestOracle;
|
||||
import com.sap.sailing.gwt.home.communication.event.SimpleCompetitorDTO;
|
||||
import com.sap.sailing.gwt.home.communication.race.SimpleRaceMetadataDTO;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.filter.AbstractListFilter;
|
||||
import com.sap.sse.common.filter.Filter;
|
||||
|
||||
public class RacesByCompetitorTextBoxFilter extends AbstractListSuggestBoxFilter<SimpleRaceMetadataDTO, SimpleCompetitorDTO> {
|
||||
@@ -15,7 +17,22 @@ public class RacesByCompetitorTextBoxFilter extends AbstractListSuggestBoxFilter
|
||||
private final RacesByCompetitorFilter filter = new RacesByCompetitorFilter();
|
||||
|
||||
public RacesByCompetitorTextBoxFilter() {
|
||||
super(StringMessages.INSTANCE.competitorsFilter());
|
||||
super(new AbstractListSuggestOracle<SimpleCompetitorDTO>() {
|
||||
@Override
|
||||
protected Iterable<String> getMatchingStrings(SimpleCompetitorDTO value) {
|
||||
return Arrays.asList(value.getName(), value.getSailID());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String createSuggestionKeyString(SimpleCompetitorDTO value) {
|
||||
return value.getSailID();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String createSuggestionAdditionalDisplayString(SimpleCompetitorDTO value) {
|
||||
return value.getName();
|
||||
}
|
||||
}, StringMessages.INSTANCE.competitorsFilter());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -31,28 +48,14 @@ public class RacesByCompetitorTextBoxFilter extends AbstractListSuggestBoxFilter
|
||||
protected void onSuggestionSelected(SimpleCompetitorDTO selectedItem) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String createSuggestionAdditionalDisplayString(SimpleCompetitorDTO value) {
|
||||
return value.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String createSuggestionKeyString(SimpleCompetitorDTO value) {
|
||||
return value.getSailID();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<String> getMatchingStrings(SimpleCompetitorDTO value) {
|
||||
return Arrays.asList(value.getName(), value.getSailID());
|
||||
}
|
||||
|
||||
private class RacesByCompetitorFilter implements Filter<SimpleRaceMetadataDTO> {
|
||||
|
||||
private final List<String> keywords = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public boolean matches(SimpleRaceMetadataDTO object) {
|
||||
return keywords.isEmpty() || !Util.isEmpty(suggestionMatchingFilter.applyFilter(keywords, object.getCompetitors()));
|
||||
AbstractListFilter<SimpleCompetitorDTO> filter = getSuggestOracle().getSuggestionMatchingFilter();
|
||||
return keywords.isEmpty() || !Util.isEmpty(filter.applyFilter(keywords, object.getCompetitors()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+10
@@ -45,6 +45,16 @@ public abstract class AbstractSuggestedMultiSelectionBoatClassDataProvider exten
|
||||
callback.setSuggestionItems(suggestionItems);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String createSuggestionKeyString(BoatClassDTO value) {
|
||||
return value.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String createSuggestionAdditionalDisplayString(BoatClassDTO value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initNotifications(boolean notifyAboutUpcomingRaces, boolean notifyAboutResults) {
|
||||
this.notifyAboutUpcomingRaces = notifyAboutUpcomingRaces;
|
||||
|
||||
+10
@@ -21,6 +21,16 @@ public abstract class AbstractSuggestedMultiSelectionCompetitorDataProvider exte
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String createSuggestionKeyString(SimpleCompetitorWithIdDTO value) {
|
||||
return value.getSailID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createSuggestionAdditionalDisplayString(SimpleCompetitorWithIdDTO value) {
|
||||
return value.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initNotifications(boolean notifyAboutResults) {
|
||||
this.notifyAboutResults = notifyAboutResults;
|
||||
|
||||
+30
-43
@@ -13,10 +13,9 @@ import com.google.gwt.user.client.ui.Button;
|
||||
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.SuggestOracle.Callback;
|
||||
import com.google.gwt.user.client.ui.SuggestOracle.Request;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.dto.BoatClassDTO;
|
||||
import com.sap.sailing.gwt.common.client.suggestion.AbstractSuggestOracle;
|
||||
import com.sap.sailing.gwt.home.communication.event.SimpleCompetitorWithIdDTO;
|
||||
import com.sap.sailing.gwt.home.shared.partials.filter.AbstractAsyncSuggestBoxFilter;
|
||||
import com.sap.sailing.gwt.home.shared.partials.filter.AbstractFilterWidget;
|
||||
@@ -107,31 +106,39 @@ public final class SuggestedMultiSelection<T> extends Composite implements Sugge
|
||||
removeAllButtonUi.setEnabled(itemContainerUi.getWidgetCount() > 0);
|
||||
}
|
||||
|
||||
private static abstract class AbstractSuggestedMultiSelectionFilter<T> extends AbstractAsyncSuggestBoxFilter<T, T> {
|
||||
private final SuggestedMultiSelectionDataProvider<T, ?> dataProvider;
|
||||
private static class SuggestedMultiSelectionFilter<T> extends AbstractAsyncSuggestBoxFilter<T, T> {
|
||||
private final SelectionCallback<T> selectionCallback;
|
||||
|
||||
protected AbstractSuggestedMultiSelectionFilter(SuggestedMultiSelectionDataProvider<T, ?> dataProvider,
|
||||
private SuggestedMultiSelectionFilter(final SuggestedMultiSelectionDataProvider<T, ?> dataProvider,
|
||||
SelectionCallback<T> selectionCallback, String placeholderText) {
|
||||
super(placeholderText);
|
||||
this.dataProvider = dataProvider;
|
||||
super(new AbstractSuggestOracle<T>() {
|
||||
@Override
|
||||
protected void getSuggestions(final Request request, final Callback callback,
|
||||
final Iterable<String> queryTokens) {
|
||||
dataProvider.getSuggestionItems(queryTokens, request.getLimit(), new SuggestionItemsCallback<T>() {
|
||||
@Override
|
||||
public void setSuggestionItems(Collection<T> suggestionItems) {
|
||||
setSuggestions(request, callback, suggestionItems, queryTokens);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String createSuggestionKeyString(T value) {
|
||||
return dataProvider.createSuggestionKeyString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String createSuggestionAdditionalDisplayString(T value) {
|
||||
return dataProvider.createSuggestionAdditionalDisplayString(value);
|
||||
}
|
||||
}, placeholderText);
|
||||
this.selectionCallback = selectionCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getSuggestions(final Request request, final Callback callback,
|
||||
final Iterable<String> queryTokens) {
|
||||
dataProvider.getSuggestionItems(queryTokens, request.getLimit(), new SuggestionItemsCallback<T>() {
|
||||
@Override
|
||||
public void setSuggestionItems(Collection<T> suggestionItems) {
|
||||
setSuggestions(request, callback, suggestionItems, queryTokens);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void onSuggestionSelected(T selectedItem) {
|
||||
AbstractSuggestedMultiSelectionFilter.this.clear();
|
||||
SuggestedMultiSelectionFilter.this.clear();
|
||||
selectionCallback.onSuggestionSelected(selectedItem);
|
||||
}
|
||||
}
|
||||
@@ -160,18 +167,8 @@ public final class SuggestedMultiSelection<T> extends Composite implements Sugge
|
||||
@Override
|
||||
public AbstractSuggestBoxFilter<SimpleCompetitorWithIdDTO, SimpleCompetitorWithIdDTO> getSuggestBoxFilter(
|
||||
SelectionCallback<SimpleCompetitorWithIdDTO> selectionCallback) {
|
||||
return new AbstractSuggestedMultiSelectionFilter<SimpleCompetitorWithIdDTO>(dataProvider,
|
||||
selectionCallback, StringMessages.INSTANCE.add(StringMessages.INSTANCE.competitor())) {
|
||||
@Override
|
||||
protected String createSuggestionKeyString(SimpleCompetitorWithIdDTO value) {
|
||||
return value.getSailID();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String createSuggestionAdditionalDisplayString(SimpleCompetitorWithIdDTO value) {
|
||||
return value.getName();
|
||||
}
|
||||
};
|
||||
return new SuggestedMultiSelectionFilter<SimpleCompetitorWithIdDTO>(dataProvider,
|
||||
selectionCallback, StringMessages.INSTANCE.add(StringMessages.INSTANCE.competitor()));
|
||||
}
|
||||
}, headerTitle);
|
||||
}
|
||||
@@ -187,18 +184,8 @@ public final class SuggestedMultiSelection<T> extends Composite implements Sugge
|
||||
@Override
|
||||
public AbstractSuggestBoxFilter<BoatClassDTO, BoatClassDTO> getSuggestBoxFilter(
|
||||
SelectionCallback<BoatClassDTO> selectionCallback) {
|
||||
return new AbstractSuggestedMultiSelectionFilter<BoatClassDTO>(dataProvider, selectionCallback,
|
||||
StringMessages.INSTANCE.add(StringMessages.INSTANCE.boatClass())) {
|
||||
@Override
|
||||
protected String createSuggestionKeyString(BoatClassDTO value) {
|
||||
return value.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String createSuggestionAdditionalDisplayString(BoatClassDTO value) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
return new SuggestedMultiSelectionFilter<BoatClassDTO>(dataProvider, selectionCallback,
|
||||
StringMessages.INSTANCE.add(StringMessages.INSTANCE.boatClass()));
|
||||
}
|
||||
}, headerTitle);
|
||||
}
|
||||
|
||||
+4
@@ -15,6 +15,10 @@ public interface SuggestedMultiSelectionDataProvider<T, D extends Display<T>> ex
|
||||
|
||||
void getSuggestionItems(Iterable<String> queryTokens, int limit, final SuggestionItemsCallback<T> callback);
|
||||
|
||||
String createSuggestionKeyString(T value);
|
||||
|
||||
String createSuggestionAdditionalDisplayString(T value);
|
||||
|
||||
void addDisplay(D display);
|
||||
|
||||
void persist();
|
||||
|
||||
+1
-2
@@ -938,8 +938,7 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
|
||||
return null;
|
||||
}
|
||||
private String createRegattaLink(RegattaOverviewEntryDTO entryDTO) {
|
||||
Map<String, String> leaderboardLinkParameters = Collections.emptyMap();
|
||||
String leaderboardLink = EntryPointLinkFactory.createLeaderboardTabLink(eventId.toString(), entryDTO.regattaName, leaderboardLinkParameters);
|
||||
String leaderboardLink = EntryPointLinkFactory.createLeaderboardTabLink(eventId.toString(), entryDTO.regattaName);
|
||||
return leaderboardLink;
|
||||
}
|
||||
public void setRepeatedInfoLabel(FlowPanel repeatedInfoLabel) {
|
||||
|
||||
+2
-6
@@ -13,11 +13,11 @@ import com.google.gwt.user.client.ui.ListBox;
|
||||
import com.google.gwt.user.client.ui.SuggestBox;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.BoatClassMasterdata;
|
||||
import com.sap.sailing.domain.common.dto.BoatClassDTO;
|
||||
import com.sap.sailing.domain.common.dto.BoatDTO;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTOImpl;
|
||||
import com.sap.sailing.gwt.common.client.suggestion.BoatClassMasterdataSuggestOracle;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.common.Color;
|
||||
import com.sap.sse.common.CountryCode;
|
||||
@@ -87,13 +87,9 @@ public class CompetitorEditDialog extends DataEntryDialog<CompetitorDTO> {
|
||||
this.stringMessages = stringMessages;
|
||||
this.competitorToEdit = competitorToEdit;
|
||||
|
||||
this.boatClassName = createSuggestBox(BoatClassMasterdata.getAllBoatClassNames(/* includeAlternativeNames */ true));
|
||||
this.boatClassName = createSuggestBox(new BoatClassMasterdataSuggestOracle());
|
||||
boatClassName.ensureDebugId("BoatClassNameSuggestBox");
|
||||
int i=0;
|
||||
List<String> boatClassNamesList = new ArrayList<String>();
|
||||
for (BoatClassMasterdata t : BoatClassMasterdata.values()) {
|
||||
boatClassNamesList.add(t.getDisplayName());
|
||||
}
|
||||
if (competitorToEdit.getBoatClass() != null) {
|
||||
boatClassName.setValue(competitorToEdit.getBoatClass().getName());
|
||||
boatClassName.setEnabled(false);
|
||||
|
||||
+2
-2
@@ -7,8 +7,8 @@ import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.SuggestBox;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.sap.sailing.domain.common.BoatClassMasterdata;
|
||||
import com.sap.sailing.domain.common.dto.BoatClassDTO;
|
||||
import com.sap.sailing.gwt.common.client.suggestion.BoatClassMasterdataSuggestOracle;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
|
||||
@@ -29,7 +29,7 @@ public abstract class RegattaWithSeriesAndFleetsDialog extends AbstractRegattaWi
|
||||
nameEntryField.ensureDebugId("NameTextBox");
|
||||
nameEntryField.setVisibleLength(40);
|
||||
nameEntryField.setText(regatta.getName());
|
||||
boatClassEntryField = createSuggestBox(BoatClassMasterdata.getAllBoatClassNames(/* include alternative names */ true));
|
||||
boatClassEntryField = createSuggestBox(new BoatClassMasterdataSuggestOracle());
|
||||
boatClassEntryField.getValueBox().ensureDebugId("BoatClassTextBox");
|
||||
if (regatta.boatClass != null) {
|
||||
boatClassEntryField.setText(regatta.boatClass.getName());
|
||||
|
||||
+11
-8
@@ -22,15 +22,18 @@ public class EntryPointLinkFactory extends AbstractEntryPointLinkFactory {
|
||||
return createEntryPointLink("/gwt/LeaderboardEditing.html", parameters);
|
||||
}
|
||||
|
||||
public static String createLeaderboardTabLink(String eventId, String regattaId, Map<String, String> parameters) {
|
||||
return createEntryPointLink("/gwt/Home.html#/regatta/leaderboard/:eventId=" + eventId + "®attaId=" + regattaId, parameters);
|
||||
public static String createLeaderboardTabLink(String eventId, String regattaId) {
|
||||
return createEventRegattaTabLink(eventId, regattaId, "leaderboard");
|
||||
}
|
||||
|
||||
public static String createLeaderboardPlaceLink(String eventId, String leaderboardName) {
|
||||
final Map<String, String> emptyParams = Collections.emptyMap();
|
||||
return createEntryPointLink("/gwt/Home.html#EventPlace:eventId="+eventId+
|
||||
"&navigationTab=Regatta&leaderboardName=" +leaderboardName, emptyParams);
|
||||
|
||||
public static String createRacesTabLink(String eventId, String leaderboardName) {
|
||||
return createEventRegattaTabLink(eventId, leaderboardName, "races");
|
||||
}
|
||||
|
||||
private static String createEventRegattaTabLink(String eventId, String regattaId, String tabName) {
|
||||
return createEntryPointLink(
|
||||
"/gwt/Home.html", "/regatta/" + tabName + "/:eventId=" + eventId + "®attaId=" + regattaId,
|
||||
Collections.<String, String>emptyMap());
|
||||
}
|
||||
|
||||
public static String createLeaderboardGroupLink(Map<String, String> parameters) {
|
||||
@@ -38,7 +41,7 @@ public class EntryPointLinkFactory extends AbstractEntryPointLinkFactory {
|
||||
}
|
||||
|
||||
public static String createEventPlaceLink(String eventId, Map<String, String> parameters) {
|
||||
return createEntryPointLink("/gwt/Home.html#/event/:eventId="+eventId, parameters);
|
||||
return createEntryPointLink("/gwt/Home.html", "/event/:eventId="+eventId, parameters);
|
||||
}
|
||||
|
||||
public static String createDashboardLink(Map<String, String> parameters) {
|
||||
|
||||
+6
-6
@@ -1,7 +1,7 @@
|
||||
.competitorFilterContainer {
|
||||
max-width: 400px;
|
||||
max-width: 425px;
|
||||
width: 100%;
|
||||
height: 2.14em;
|
||||
height: 2.25em;
|
||||
background-color: #FFFFFF;
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
@@ -17,7 +17,7 @@
|
||||
border: 1px solid #ccc;
|
||||
background-color: #eaeaea;
|
||||
border-radius: 4px;
|
||||
margin-right: 4.4em;
|
||||
margin-right: 6em;
|
||||
}
|
||||
|
||||
.searchInput {
|
||||
@@ -57,17 +57,17 @@
|
||||
}
|
||||
|
||||
.clearButton {
|
||||
right: 5.3em;
|
||||
right: 7.3em;
|
||||
top: 0.2em;
|
||||
}
|
||||
|
||||
.settingsButton {
|
||||
right: .4em;
|
||||
right: 2.4em;
|
||||
top: 0.2em;
|
||||
}
|
||||
|
||||
.filterButton {
|
||||
right: 2.4em;
|
||||
right: 4.4em;
|
||||
top: 0.2em;
|
||||
}
|
||||
|
||||
|
||||
+20
-10
@@ -189,23 +189,21 @@ public abstract class ExpandableSortableColumn<C> extends LeaderboardSortableCol
|
||||
if (isTogglingInProcess()) {
|
||||
queuedToggleRequests.add(expand);
|
||||
} else {
|
||||
final boolean oldBusyState = getLeaderboardPanel().isBusy();
|
||||
getLeaderboardPanel().setBusyState(true);
|
||||
setTogglingInProcess(true);
|
||||
final CellTable<LeaderboardRowDTO> table = getLeaderboardPanel().getLeaderboardTable();
|
||||
if (table == null) {
|
||||
GWT.log("WARNING: leaderborad table is null");
|
||||
} else {
|
||||
getLeaderboardPanel().addBusyTask();
|
||||
setTogglingInProcess(true);
|
||||
if (!expand) { // collapse
|
||||
if (isExpanded()) { // but only if currently expanded
|
||||
for (AbstractSortableColumnWithMinMax<LeaderboardRowDTO, ?> column : getAllVisibleChildren()) {
|
||||
getLeaderboardPanel().removeColumn(column); // removes only the children currently displayed
|
||||
}
|
||||
getLeaderboardPanel().setBusyState(false);
|
||||
setTogglingInProcess(false);
|
||||
// important: toggle expanded state after asking for all visible children
|
||||
setExpanded(!isExpanded());
|
||||
}
|
||||
finishCurrentToggling();
|
||||
} else { // expand
|
||||
if (!isExpanded()) { // but only if not expanded yet
|
||||
// important: toggle expanded state before asking for all visible children
|
||||
@@ -228,19 +226,31 @@ public abstract class ExpandableSortableColumn<C> extends LeaderboardSortableCol
|
||||
getLeaderboardPanel().getLeaderboardTable().redraw();
|
||||
}
|
||||
}
|
||||
getLeaderboardPanel().setBusyState(oldBusyState);
|
||||
setTogglingInProcess(false);
|
||||
if (!queuedToggleRequests.isEmpty()) {
|
||||
changeExpansionState(queuedToggleRequests.remove(0));
|
||||
}
|
||||
finishCurrentToggling();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
finishCurrentToggling();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Finishes the current toggling by removing the
|
||||
* {@link LeaderboardPanel#removeBusyTask() busy task} from the {@link #getLeaderboardPanel() leaderboard panel} and setting the
|
||||
* {@link #setTogglingInProcess(boolean) togglingInProcess flag} to <code>false</code>.
|
||||
* Afterwards, {@link #queuedToggleRequests queued toggling requests} are executed, if any.
|
||||
* Make sure that this method is called only once, and only after {@link LeaderboardPanel#addBusyTask()} has been called.
|
||||
*/
|
||||
private void finishCurrentToggling() {
|
||||
getLeaderboardPanel().removeBusyTask();
|
||||
setTogglingInProcess(false);
|
||||
if (!queuedToggleRequests.isEmpty()) {
|
||||
changeExpansionState(queuedToggleRequests.remove(0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to ensure that all data necessary to display the expanded data of this column is actually loaded.
|
||||
|
||||
+65
-36
@@ -302,6 +302,12 @@ public class LeaderboardPanel extends SimplePanel implements Component<Leaderboa
|
||||
private ImageResource pauseIcon;
|
||||
private ImageResource playIcon;
|
||||
|
||||
/**
|
||||
* For a leaderboard, zero or more tasks may be currently busy. The counter keeps track. If it goes
|
||||
* to {@code 0}, the {@link #busyIndicator} is set to non-busy. If it goes from {@code 0} to {@code 1}
|
||||
* the {@link #busyIndicator} is set to busy.
|
||||
*/
|
||||
private int busyTaskCounter;
|
||||
private final BusyIndicator busyIndicator;
|
||||
private final Set<BusyStateChangeListener> busyStateChangeListeners;
|
||||
|
||||
@@ -485,31 +491,32 @@ public class LeaderboardPanel extends SimplePanel implements Component<Leaderboa
|
||||
break;
|
||||
}
|
||||
|
||||
final boolean oldBusyState = isBusy();
|
||||
setBusyState(true);
|
||||
addBusyTask();
|
||||
Runnable doWhenNecessaryDetailHasBeenLoaded = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setAutoExpandPreSelectedRace(false); // avoid expansion during updateLeaderboard(...); will expand later
|
||||
// if it was expanded before
|
||||
// update leaderboard after settings panel column selection change
|
||||
updateLeaderboard(leaderboard);
|
||||
setAutoExpandPreSelectedRace(newSettings.isAutoExpandPreSelectedRace());
|
||||
|
||||
if (newSettings.getDelayBetweenAutoAdvancesInMilliseconds() != null) {
|
||||
timer.setRefreshInterval(newSettings.getDelayBetweenAutoAdvancesInMilliseconds());
|
||||
}
|
||||
for (ExpandableSortableColumn<?> expandableSortableColumn : columnsToExpandAgain) {
|
||||
expandableSortableColumn.changeExpansionState(/* expand */ true);
|
||||
}
|
||||
if (newSettings.getNameOfRaceToSort() != null) {
|
||||
final RaceColumn<?> raceColumnByRaceName = getRaceColumnByRaceName(newSettings
|
||||
.getNameOfRaceToSort());
|
||||
if (raceColumnByRaceName != null) {
|
||||
getLeaderboardTable().sortColumn(raceColumnByRaceName, /* ascending */true);
|
||||
try {
|
||||
setAutoExpandPreSelectedRace(false); // avoid expansion during updateLeaderboard(...); will expand later
|
||||
// if it was expanded before
|
||||
// update leaderboard after settings panel column selection change
|
||||
updateLeaderboard(leaderboard);
|
||||
setAutoExpandPreSelectedRace(newSettings.isAutoExpandPreSelectedRace());
|
||||
|
||||
if (newSettings.getDelayBetweenAutoAdvancesInMilliseconds() != null) {
|
||||
timer.setRefreshInterval(newSettings.getDelayBetweenAutoAdvancesInMilliseconds());
|
||||
}
|
||||
for (ExpandableSortableColumn<?> expandableSortableColumn : columnsToExpandAgain) {
|
||||
expandableSortableColumn.changeExpansionState(/* expand */ true);
|
||||
}
|
||||
if (newSettings.getNameOfRaceToSort() != null) {
|
||||
final RaceColumn<?> raceColumnByRaceName = getRaceColumnByRaceName(newSettings.getNameOfRaceToSort());
|
||||
if (raceColumnByRaceName != null) {
|
||||
getLeaderboardTable().sortColumn(raceColumnByRaceName, /* ascending */true);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
removeBusyTask();
|
||||
}
|
||||
setBusyState(oldBusyState);
|
||||
}
|
||||
};
|
||||
if (oldShallAddOverallDetails == shallAddOverallDetails() || oldShallAddOverallDetails || getLeaderboard().hasOverallDetails()) {
|
||||
@@ -1872,8 +1879,8 @@ public class LeaderboardPanel extends SimplePanel implements Component<Leaderboa
|
||||
contentPanel.add(toolbarPanel);
|
||||
}
|
||||
if (competitorSearchTextBox != null) {
|
||||
competitorSearchTextBox.add(busyIndicator);
|
||||
contentPanel.add(competitorSearchTextBox);
|
||||
contentPanel.add(busyIndicator);
|
||||
competitorSearchTextBox.getSettingsButton().addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
@@ -1894,7 +1901,7 @@ public class LeaderboardPanel extends SimplePanel implements Component<Leaderboa
|
||||
mainPanel.setWidget(contentPanel);
|
||||
this.setTitle(stringMessages.leaderboard());
|
||||
if (timer.isInitialized()) {
|
||||
loadCompleteLeaderboard(getLeaderboardDisplayDate());
|
||||
loadCompleteLeaderboard(/* showProgress */ false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1965,9 +1972,8 @@ public class LeaderboardPanel extends SimplePanel implements Component<Leaderboa
|
||||
filterClearButton.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
setBusyState(true);
|
||||
competitorFilterPanel.clearAllActiveFilters();
|
||||
timeChanged(new Date(), null);
|
||||
loadCompleteLeaderboard(/* showProgress */ true);
|
||||
}
|
||||
});
|
||||
filterControlPanel.add(filterClearButton);
|
||||
@@ -2271,8 +2277,12 @@ public class LeaderboardPanel extends SimplePanel implements Component<Leaderboa
|
||||
}
|
||||
}
|
||||
|
||||
private void loadCompleteLeaderboard(Date date) {
|
||||
public void loadCompleteLeaderboard(final boolean showProgress) {
|
||||
final Date date = getLeaderboardDisplayDate();
|
||||
if (needsDataLoading()) {
|
||||
if (showProgress) {
|
||||
addBusyTask();
|
||||
}
|
||||
GetLeaderboardByNameAction getLeaderboardByNameAction = new GetLeaderboardByNameAction(sailingService,
|
||||
getLeaderboardName(), useNullAsTimePoint() ? null : date,
|
||||
/* namesOfRaceColumnsForWhichToLoadLegDetails */getNamesOfExpandedRaceColumns(), shallAddOverallDetails(), /* previousLeaderboard */
|
||||
@@ -2281,20 +2291,25 @@ public class LeaderboardPanel extends SimplePanel implements Component<Leaderboa
|
||||
new AsyncCallback<LeaderboardDTO>() {
|
||||
@Override
|
||||
public void onSuccess(LeaderboardDTO result) {
|
||||
updateLeaderboard(result);
|
||||
setBusyState(false);
|
||||
try {
|
||||
updateLeaderboard(result);
|
||||
} finally {
|
||||
if (showProgress) {
|
||||
removeBusyTask();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
setBusyState(false);
|
||||
if (showProgress) {
|
||||
removeBusyTask();
|
||||
}
|
||||
getErrorReporter()
|
||||
.reportError("Error trying to obtain leaderboard contents: " + caught.getMessage(),
|
||||
true /* silentMode */);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
setBusyState(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2303,9 +2318,9 @@ public class LeaderboardPanel extends SimplePanel implements Component<Leaderboa
|
||||
}
|
||||
|
||||
/**
|
||||
* In {@link PlayModes#Live live mode}, when {@link #loadCompleteLeaderboard(Date) loading the leaderboard contents}, <code>null</code>
|
||||
* In {@link PlayModes#Live live mode}, when {@link #loadCompleteLeaderboard(boolean) loading the leaderboard contents}, <code>null</code>
|
||||
* is used as time point. The condition for this is encapsulated in this method so others can find out. For example, when a time change
|
||||
* is signaled due to local offset / delay adjustments, no additional call to {@link #loadCompleteLeaderboard(Date)} would be required
|
||||
* is signaled due to local offset / delay adjustments, no additional call to {@link #loadCompleteLeaderboard(boolean)} would be required
|
||||
* as <code>null</code> will be passed in any case, not being affected by local time offsets.
|
||||
*/
|
||||
private boolean useNullAsTimePoint() {
|
||||
@@ -2450,7 +2465,6 @@ public class LeaderboardPanel extends SimplePanel implements Component<Leaderboa
|
||||
liveRaceLabel.setVisible(hasLiveRace);
|
||||
}
|
||||
informLeaderboardUpdateListenersAboutLeaderboardUpdated(leaderboard);
|
||||
setBusyState(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3079,7 +3093,7 @@ public class LeaderboardPanel extends SimplePanel implements Component<Leaderboa
|
||||
*/
|
||||
@Override
|
||||
public void timeChanged(Date newTime, Date oldTime) {
|
||||
loadCompleteLeaderboard(getLeaderboardDisplayDate());
|
||||
loadCompleteLeaderboard(/* showProgress */ false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3336,8 +3350,7 @@ public class LeaderboardPanel extends SimplePanel implements Component<Leaderboa
|
||||
return busyIndicator.isBusy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBusyState(boolean isBusy) {
|
||||
private void setBusyState(boolean isBusy) {
|
||||
if (busyIndicator.isBusy() != isBusy) {
|
||||
busyIndicator.setBusy(isBusy);
|
||||
for (BusyStateChangeListener listener : busyStateChangeListeners) {
|
||||
@@ -3345,6 +3358,22 @@ public class LeaderboardPanel extends SimplePanel implements Component<Leaderboa
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBusyTask() {
|
||||
busyTaskCounter++;
|
||||
if (busyTaskCounter == 1) {
|
||||
setBusyState(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeBusyTask() {
|
||||
busyTaskCounter--;
|
||||
if (busyTaskCounter == 0) {
|
||||
setBusyState(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
|
||||
+3
-4
@@ -248,8 +248,7 @@ public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSett
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
super.setVisible(visible);
|
||||
|
||||
if(visible) {
|
||||
if (visible) {
|
||||
readAndUpdateLeaderboardsOfMetaleaderboard();
|
||||
} else {
|
||||
updateSelectedLeaderboard(null, -1);
|
||||
@@ -258,7 +257,7 @@ public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSett
|
||||
|
||||
@Override
|
||||
public void timeChanged(Date newTime, Date oldTime) {
|
||||
if(selectedLeaderboardPanel != null) {
|
||||
if (selectedLeaderboardPanel != null) {
|
||||
selectedLeaderboardPanel.timeChanged(newTime, oldTime);
|
||||
}
|
||||
}
|
||||
@@ -275,7 +274,7 @@ public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSett
|
||||
|
||||
@Override
|
||||
public void setSelectedLeaderboard(LeaderboardPanel selectedLeaderboard) {
|
||||
if(this.selectedLeaderboardPanel != selectedLeaderboard) {
|
||||
if (this.selectedLeaderboardPanel != selectedLeaderboard) {
|
||||
this.selectedLeaderboardPanel = selectedLeaderboard;
|
||||
for (SelectedLeaderboardChangeListener listener : selectedLeaderboardChangeListeners) {
|
||||
listener.onSelectedLeaderboardChanged(selectedLeaderboardPanel);
|
||||
|
||||
+13
-13
@@ -320,13 +320,13 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
final RowUpdateWhiteboard<LeaderboardRowDTO> whiteboard = new RowUpdateWhiteboard<LeaderboardRowDTO>(
|
||||
EditableLeaderboardPanel.this.getData());
|
||||
getWhiteboardOwner().whiteboardProduced(whiteboard);
|
||||
setBusyState(true);
|
||||
addBusyTask();
|
||||
getSailingService().updateLeaderboardMaxPointsReason(getLeaderboardName(), row.competitor.getIdAsString(),
|
||||
raceColumnName, value == null || value.trim().length() == 0 ? null : MaxPointsReason.valueOf(value.trim()),
|
||||
getLeaderboardDisplayDate(), new AsyncCallback<Util.Triple<Double, Double, Boolean>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
setBusyState(false);
|
||||
removeBusyTask();
|
||||
getErrorReporter().reportError(
|
||||
"Error trying to update max points reason for competitor "
|
||||
+ row.competitor.getName() + " in leaderboard " + getLeaderboardName()
|
||||
@@ -335,7 +335,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Util.Triple<Double, Double, Boolean> newTotalAndNetPointsAndIsCorrected) {
|
||||
setBusyState(false);
|
||||
removeBusyTask();
|
||||
row.fieldsByRaceColumnName.get(raceColumnName).reasonForMaxPoints = value == null
|
||||
|| value.length() == 0 ? null : MaxPointsReason.valueOf(value.trim());
|
||||
row.fieldsByRaceColumnName.get(raceColumnName).totalPoints = newTotalAndNetPointsAndIsCorrected.getA();
|
||||
@@ -445,14 +445,14 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
final RowUpdateWhiteboard<LeaderboardRowDTO> whiteboard = new RowUpdateWhiteboard<LeaderboardRowDTO>(
|
||||
EditableLeaderboardPanel.this.getData());
|
||||
getWhiteboardOwner().whiteboardProduced(whiteboard);
|
||||
setBusyState(true);
|
||||
addBusyTask();
|
||||
getSailingService().updateLeaderboardScoreCorrection(getLeaderboardName(), row.competitor.getIdAsString(), raceColumnName,
|
||||
value == null || value.trim().length() == 0 ? null : value.trim().equals("n/a") ? null
|
||||
: Double.valueOf(value.trim()), getLeaderboardDisplayDate(),
|
||||
new AsyncCallback<Util.Triple<Double, Double, Boolean>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
setBusyState(false);
|
||||
removeBusyTask();
|
||||
getErrorReporter().reportError("Error trying to update score correction for competitor "+
|
||||
row.competitor.getName()+" in leaderboard "+getLeaderboardName()+
|
||||
" for race "+raceColumnName+": "+t.getMessage()+
|
||||
@@ -461,7 +461,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Util.Triple<Double, Double, Boolean> newTotalAndTotalPointsAndIsCorrected) {
|
||||
setBusyState(false);
|
||||
removeBusyTask();
|
||||
final LeaderboardEntryDTO leaderboardEntryDTO = row.fieldsByRaceColumnName.get(raceColumnName);
|
||||
leaderboardEntryDTO.totalPoints = value == null || value.length() == 0 ? newTotalAndTotalPointsAndIsCorrected
|
||||
.getA() : Double.valueOf(value.trim());
|
||||
@@ -524,13 +524,13 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
row.fieldsByRaceColumnName.get(raceColumnName).totalPoints, new DialogCallback<Util.Pair<MaxPointsReason, Double>>() {
|
||||
@Override
|
||||
public void ok(final Util.Pair<MaxPointsReason, Double> editedObject) {
|
||||
setBusyState(true);
|
||||
addBusyTask();
|
||||
getSailingService().updateLeaderboardScoreCorrection(getLeaderboardName(), row.competitor.getIdAsString(), raceColumnName,
|
||||
editedObject.getB(), getLeaderboardDisplayDate(),
|
||||
new AsyncCallback<Util.Triple<Double, Double, Boolean>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
setBusyState(false);
|
||||
removeBusyTask();
|
||||
getErrorReporter().reportError("Error trying to update score correction for competitor "+
|
||||
row.competitor.getName()+" in leaderboard "+getLeaderboardName()+
|
||||
" for race "+raceColumnName+": "+t.getMessage()+
|
||||
@@ -544,7 +544,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
new AsyncCallback<Util.Triple<Double, Double, Boolean>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
setBusyState(false);
|
||||
removeBusyTask();
|
||||
getErrorReporter().reportError("Error trying to update score correction for competitor "+
|
||||
row.competitor.getName()+" in leaderboard "+getLeaderboardName()+
|
||||
" for race "+raceColumnName+": "+t.getMessage()+
|
||||
@@ -553,7 +553,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Util.Triple<Double, Double, Boolean> newTotalAndNetPointsAndIsCorrected) {
|
||||
setBusyState(false);
|
||||
removeBusyTask();
|
||||
final LeaderboardEntryDTO leaderboardEntryDTO = row.fieldsByRaceColumnName.get(raceColumnName);
|
||||
leaderboardEntryDTO.reasonForMaxPoints = editedObject.getA();
|
||||
leaderboardEntryDTO.totalPoints = newTotalAndNetPointsAndIsCorrected.getA();
|
||||
@@ -656,7 +656,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
showUncorrectedTotalPointsCheckbox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
||||
timeChanged(getTimer().getTime(), getTimer().getTime());
|
||||
loadCompleteLeaderboard(/* showProgress */ true);
|
||||
}
|
||||
});
|
||||
scoreCorrectionInfoGrid.setWidget(0, 3, showUncorrectedTotalPointsCheckbox);
|
||||
@@ -716,7 +716,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
public void onSuccess(Void result) {
|
||||
Window.setStatus("Successfully unsuppressed competitor "+object.getName());
|
||||
// force a reload of the entire editable leaderboard to hide the now suppressed competitor
|
||||
timeChanged(getLeaderboardDisplayDate(), null);
|
||||
loadCompleteLeaderboard(/* showProgress */ true);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -788,7 +788,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
// force a reload of the entire editable leaderboard to hide the now suppressed competitor
|
||||
timeChanged(getLeaderboardDisplayDate(), null);
|
||||
loadCompleteLeaderboard(/* showProgress */ true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+4
-4
@@ -409,20 +409,20 @@ public class MatchAndApplyScoreCorrectionsDialog extends DataEntryDialog<BulkSco
|
||||
|
||||
@Override
|
||||
public void ok(final BulkScoreCorrectionDTO result) {
|
||||
leaderboardPanel.setBusyState(true);
|
||||
leaderboardPanel.addBusyTask();
|
||||
sailingService.updateLeaderboardScoreCorrectionsAndMaxPointsReasons(result, new AsyncCallback<Void>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
leaderboardPanel.setBusyState(false);
|
||||
leaderboardPanel.removeBusyTask();
|
||||
errorReporter.reportError(stringMessages.errorUpdatingScoresForLeaderboard(result.getLeaderboardName(),
|
||||
caught.getMessage()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
leaderboardPanel.removeBusyTask();
|
||||
Window.setStatus(stringMessages.successfullyUpdatedScores());
|
||||
leaderboardPanel.timeChanged(/* time point is ignored */ null, null); // reload leaderboard contents to reflect changes
|
||||
// leaderboard panel sets busy indicator to non-busy after done with updating
|
||||
leaderboardPanel.loadCompleteLeaderboard(/* showProgress */ true); // reload leaderboard contents to reflect changes
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+3
-3
@@ -221,19 +221,19 @@ public class ResultSelectionAndApplyDialog extends DataEntryDialog<Util.Triple<S
|
||||
final String eventName = providerNameAndEventNameBoatClassNameCapturedWhen.getB();
|
||||
final String boatClassName = providerNameAndEventNameBoatClassNameCapturedWhen.getC().getA();
|
||||
final Date timePointWhenResultPublished = providerNameAndEventNameBoatClassNameCapturedWhen.getC().getB();
|
||||
leaderboardPanel.setBusyState(true);
|
||||
leaderboardPanel.addBusyTask();
|
||||
sailingService.getScoreCorrections(scoreCorrectionProviderName, eventName, boatClassName, timePointWhenResultPublished,
|
||||
new AsyncCallback<RegattaScoreCorrectionDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
leaderboardPanel.setBusyState(false);
|
||||
leaderboardPanel.removeBusyTask();
|
||||
errorReporter.reportError(stringMessages.errorObtainingScoreCorrections(scoreCorrectionProviderName,
|
||||
eventName, boatClassName, timePointWhenResultPublished.toString(), caught.getMessage()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(RegattaScoreCorrectionDTO result) {
|
||||
leaderboardPanel.setBusyState(false);
|
||||
leaderboardPanel.removeBusyTask();
|
||||
new MatchAndApplyScoreCorrectionsDialog(leaderboardPanel, stringMessages, sailingService,
|
||||
errorReporter, result).show();
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import com.sap.sse.gwt.client.AbstractEntryPointLinkFactory;
|
||||
public class EntryPointLinkFactory extends AbstractEntryPointLinkFactory {
|
||||
|
||||
public static final String createUserProfileLink() {
|
||||
return createEntryPointLink("/gwt/Home.html#/user/profile/:", new HashMap<String, String>());
|
||||
return createEntryPointLink("/gwt/Home.html", "/user/profile/:", new HashMap<String, String>());
|
||||
}
|
||||
|
||||
public static final String createEmailValidationLink() {
|
||||
|
||||
+7
-3
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.gwt.ui.raceboard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -534,7 +535,7 @@ public class RaceBoardPanel extends AbstractPerspectiveComposite<RaceBoardPerspe
|
||||
final Anchor regattaNameAnchor = new Anchor(raceIdentifier.getRegattaName());
|
||||
regattaNameAnchor.setTitle(raceIdentifier.getRegattaName());
|
||||
if (eventId != null) {
|
||||
String link = EntryPointLinkFactory.createLeaderboardPlaceLink(eventId.toString(), leaderboardName);
|
||||
String link = EntryPointLinkFactory.createRacesTabLink(eventId.toString(), leaderboardName);
|
||||
regattaNameAnchor.setHref(link);
|
||||
} else {
|
||||
String leaderboardGroupNameParam = Window.Location.getParameter("leaderboardGroupName");
|
||||
@@ -570,10 +571,13 @@ public class RaceBoardPanel extends AbstractPerspectiveComposite<RaceBoardPerspe
|
||||
}
|
||||
|
||||
private Label computeRaceInformation(RaceColumnDTO raceColumn, FleetDTO fleet) {
|
||||
final Date startDate = raceColumn.getStartDate(fleet);
|
||||
Label raceInformationLabel = new Label();
|
||||
raceInformationLabel.setStyleName("Race-Time-Label");
|
||||
DateTimeFormat formatter = DateTimeFormat.getFormat("E d/M/y");
|
||||
raceInformationLabel.setText(formatter.format(raceColumn.getStartDate(fleet)));
|
||||
if (startDate != null) {
|
||||
DateTimeFormat formatter = DateTimeFormat.getFormat("E d/M/y");
|
||||
raceInformationLabel.setText(formatter.format(startDate));
|
||||
}
|
||||
return raceInformationLabel;
|
||||
}
|
||||
|
||||
|
||||
+4
-7
@@ -27,7 +27,6 @@ import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.CheckBox;
|
||||
import com.google.gwt.user.client.ui.DecoratorPanel;
|
||||
import com.google.gwt.user.client.ui.DialogBox;
|
||||
import com.google.gwt.user.client.ui.DockLayoutPanel;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
@@ -580,7 +579,6 @@ public class SimulatorMainPanel extends SimplePanel {
|
||||
mapOptions.add(courseInputButton);
|
||||
}
|
||||
|
||||
mapOptions.add(busyIndicator);
|
||||
//rightPanel.add(mapOptions);
|
||||
mainPanel.addNorth(mapOptions, 45);
|
||||
|
||||
@@ -853,7 +851,7 @@ public class SimulatorMainPanel extends SimplePanel {
|
||||
private void initUpdateButton() {
|
||||
|
||||
this.updateButton = new Button(stringMessages.simulateButton());
|
||||
this.updateButton.getElement().getStyle().setProperty("marginLeft", "30px");
|
||||
this.updateButton.getElement().getStyle().setProperty("marginLeft", "6px");
|
||||
if (mode == SailingSimulatorConstants.ModeEvent) {
|
||||
this.updateButton.setEnabled(true);
|
||||
}
|
||||
@@ -986,14 +984,13 @@ public class SimulatorMainPanel extends SimplePanel {
|
||||
});
|
||||
|
||||
HorizontalPanel p = new HorizontalPanel();
|
||||
// p.add(busyIndicator);
|
||||
DecoratorPanel d = new DecoratorPanel();
|
||||
p.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
|
||||
p.add(busyIndicator);
|
||||
p.add(windDisplayButton);
|
||||
p.add(summaryButton);
|
||||
p.add(replayButton);
|
||||
// windDisplayButton.setValue(true);
|
||||
d.add(p);
|
||||
mapOptions.add(d);
|
||||
mapOptions.add(p);
|
||||
}
|
||||
|
||||
private DialogBox createPolarDiagramDialogBox() {
|
||||
|
||||
@@ -1,38 +1,14 @@
|
||||
package com.sap.sse.gwt.client;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.sap.sse.gwt.settings.UrlBuilderUtil;
|
||||
|
||||
public class AbstractEntryPointLinkFactory {
|
||||
protected static String createEntryPointLink(String baseLink, Map<String, String> parameters) {
|
||||
String debugParam = Window.Location.getParameter("gwt.codesvr");
|
||||
String localeParam = Window.Location.getParameter("locale");
|
||||
String[] documentAndFragment = baseLink.split("#", 2);
|
||||
StringBuilder link = new StringBuilder(documentAndFragment[0]);
|
||||
int i = 1;
|
||||
for (Entry<String, String> entry: parameters.entrySet()) {
|
||||
link.append(i == 1 ? "?" : "&");
|
||||
link.append(entry.getKey() + "=" + replaceAmpersand(URLEncoder.encode(entry.getValue())));
|
||||
i++;
|
||||
}
|
||||
if (debugParam != null && !debugParam.isEmpty()) {
|
||||
link.append(i == 1 ? "?" : "&");
|
||||
link.append("gwt.codesvr=" + debugParam);
|
||||
}
|
||||
if (localeParam != null && !localeParam.isEmpty()) {
|
||||
link.append(i == 1 ? "?" : "&");
|
||||
link.append("locale=" + localeParam);
|
||||
}
|
||||
if (documentAndFragment.length > 1) {
|
||||
link.append('#');
|
||||
link.append(URLEncoder.encode(documentAndFragment[1])); // append the fragment following the "#" again
|
||||
}
|
||||
return link.toString();
|
||||
protected static String createEntryPointLink(String path, Map<String, String> parameters) {
|
||||
return UrlBuilderUtil.createUrlBuilderWithPathAndParameters(path, parameters).buildString();
|
||||
}
|
||||
|
||||
private static String replaceAmpersand(String param) {
|
||||
return param.replaceAll("&", "%26");
|
||||
protected static String createEntryPointLink(String path, String hash, Map<String, String> parameters) {
|
||||
return UrlBuilderUtil.createUrlBuilderWithPathAndHashAndParameters(path, hash, parameters).buildString();
|
||||
}
|
||||
}
|
||||
|
||||
+10
-2
@@ -7,7 +7,15 @@ public interface BusyStateProvider {
|
||||
|
||||
void removeBusyStateChangeListener(BusyStateChangeListener listener);
|
||||
|
||||
void setBusyState(boolean isBusy);
|
||||
|
||||
boolean isBusy();
|
||||
|
||||
/**
|
||||
* A new task has begun that keeps us busy
|
||||
*/
|
||||
void addBusyTask();
|
||||
|
||||
/**
|
||||
* A task that kept us busy has finished
|
||||
*/
|
||||
void removeBusyTask();
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
|
||||
import com.google.gwt.user.client.ui.PasswordTextBox;
|
||||
import com.google.gwt.user.client.ui.RadioButton;
|
||||
import com.google.gwt.user.client.ui.SuggestBox;
|
||||
import com.google.gwt.user.client.ui.SuggestOracle;
|
||||
import com.google.gwt.user.client.ui.TextArea;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
@@ -176,13 +177,37 @@ public abstract class DataEntryDialog<T> {
|
||||
return createTextBoxInternal(initialValue, 30);
|
||||
}
|
||||
|
||||
public SuggestBox createSuggestBox(Iterable<String> suggestValues) {
|
||||
/**
|
||||
* This methods creates a {@link MultiWordSuggestOracle} where the given suggest values are
|
||||
* {@link MultiWordSuggestOracle#addAll(java.util.Collection) added} and
|
||||
* {@link MultiWordSuggestOracle#setDefaultSuggestionsFromText(java.util.Collection) set as default suggestions},
|
||||
* first. Afterwards, this oracle is used to {@link #createSuggestBox(SuggestOracle) create} as {@link SuggestBox}.
|
||||
*
|
||||
* @param suggestValues the plain text suggestions to use
|
||||
* @return the new {@link SuggestBox} instance
|
||||
*
|
||||
* @see #createSuggestBox(SuggestOracle)
|
||||
*/
|
||||
protected SuggestBox createSuggestBox(Iterable<String> suggestValues) {
|
||||
List<String> suggestValuesAsCollection = new ArrayList<>();
|
||||
Util.addAll(suggestValues, suggestValuesAsCollection);
|
||||
final MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();
|
||||
oracle.addAll(suggestValuesAsCollection);
|
||||
oracle.setDefaultSuggestionsFromText(suggestValuesAsCollection);
|
||||
final SuggestBox result = new SuggestBox(oracle);
|
||||
return createSuggestBox(oracle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SuggestBox} using the given {@link SuggestOracle}, a {@link TextBox} and the
|
||||
* {@link com.google.gwt.user.client.ui.SuggestBox.DefaultSuggestionDisplay DefaultSuggestionDisplay}
|
||||
*
|
||||
* @param suggestOracle the {@link SuggestOracle} to in the {@link SuggestBox}
|
||||
* @return the new {@link SuggestBox} instance
|
||||
*
|
||||
* @see SuggestBox#SuggestBox(SuggestOracle)
|
||||
*/
|
||||
protected SuggestBox createSuggestBox(SuggestOracle suggestOracle) {
|
||||
final SuggestBox result = new SuggestBox(suggestOracle);
|
||||
result.getValueBox().addValueChangeHandler(new ValueChangeHandler<String>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<String> event) {
|
||||
|
||||
+2
-2
@@ -7,8 +7,8 @@ public abstract class AbstractEntryPointWithSettingsLinkFactory {
|
||||
|
||||
private static final SettingsToUrlSerializer serializer = new SettingsToUrlSerializer();
|
||||
|
||||
protected static String createEntryPointLink(String baseLink, GenericSerializableSettings... settings) {
|
||||
UrlBuilder urlBuilder = UrlBuilderUtil.createUrlBuilderFromCurrentLocationWithCleanParameters(baseLink);
|
||||
protected static String createEntryPointLink(String path, GenericSerializableSettings... settings) {
|
||||
UrlBuilder urlBuilder = UrlBuilderUtil.createUrlBuilderFromCurrentLocationWithCleanParametersAndPath(path);
|
||||
for (GenericSerializableSettings setting : settings) {
|
||||
serializer.serializeToUrlBuilder(setting, urlBuilder);
|
||||
}
|
||||
|
||||
@@ -1,25 +1,168 @@
|
||||
package com.sap.sse.gwt.settings;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.gwt.http.client.UrlBuilder;
|
||||
import com.google.gwt.user.client.Window;
|
||||
|
||||
/**
|
||||
* Helps to construct pre-parameterized {@link UrlBuilder} instances based on the current location/url. The created
|
||||
* {@link UrlBuilder} instances are constructed in a way so that "locale" and "gwt.codesvr" parameters are preserved,
|
||||
* but all other parameters as well as the fragment/hash part are being erased from the resulting UrlBuilder.
|
||||
*/
|
||||
public class UrlBuilderUtil {
|
||||
|
||||
|
||||
private static final Logger log = Logger.getLogger(UrlBuilderUtil.class.getName());
|
||||
|
||||
/**
|
||||
* Creates an {@link UrlBuilder} based on the current location but with clean parameters and fragment/hash.
|
||||
* <p>
|
||||
*
|
||||
* Example:
|
||||
* <ul>
|
||||
* <li>Current location: http://www.sapsailing.com/gwt/Home.html?locale=de&some_param=some_value#abc123</li>
|
||||
* <li>Returned UrlBuilder: http://www.sapsailing.com/gwt/Home.html?locale=de</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static UrlBuilder createUrlBuilderFromCurrentLocationWithCleanParameters() {
|
||||
final UrlBuilder urlBuilder = Window.Location.createUrlBuilder();
|
||||
for(String parameterName : Window.Location.getParameterMap().keySet()) {
|
||||
if(!"gwt.codesvr".equals(parameterName)
|
||||
&& !"locale".equals(parameterName)) {
|
||||
for (String parameterName : Window.Location.getParameterMap().keySet()) {
|
||||
if (!"gwt.codesvr".equals(parameterName) && !"locale".equals(parameterName)) {
|
||||
urlBuilder.removeParameter(parameterName);
|
||||
}
|
||||
}
|
||||
urlBuilder.setHash(null);
|
||||
return urlBuilder;
|
||||
}
|
||||
|
||||
public static UrlBuilder createUrlBuilderFromCurrentLocationWithCleanParameters(String path) {
|
||||
|
||||
/**
|
||||
* Creates an {@link UrlBuilder} based on the current location but with clean parameters and fragment/hash. In
|
||||
* addition the base URL and path are being set specifically.
|
||||
* <p>
|
||||
*
|
||||
* Example:
|
||||
* <ul>
|
||||
* <li>Current location: http://www.sapsailing.com/gwt/Home.html?locale=de&some_param=some_value#abc123</li>
|
||||
* <li>baseUrl: http://kielerwoche2016.sapsailing.com path: /gwt/Leaderboard.html</li>
|
||||
* <li>Returned UrlBuilder: http://kielerwoche2016.sapsailing.com/gwt/Leaderboard.html?locale=de</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static UrlBuilder createUrlBuilderFromBaseURLAndPathWithCleanParameters(String baseUrl, String path) {
|
||||
final int colonIndex = baseUrl.indexOf(':');
|
||||
final String protocol = colonIndex >= 0 ? baseUrl.substring(0, colonIndex) : "http";
|
||||
|
||||
final int doubleSlashIndex = baseUrl.indexOf("//");
|
||||
final String baseURLWithoutProtocol = doubleSlashIndex >= 0 ? baseUrl.substring(doubleSlashIndex + 2) : baseUrl;
|
||||
final int pathIndex = baseURLWithoutProtocol.indexOf('/');
|
||||
final String hostAndPort = pathIndex >= 0 ? baseURLWithoutProtocol.substring(0, pathIndex)
|
||||
: baseURLWithoutProtocol;
|
||||
final String pathPrefix = pathIndex >= 0 ? baseURLWithoutProtocol.substring(pathIndex + 1) : "";
|
||||
|
||||
final int portColonIndex = hostAndPort.indexOf(':');
|
||||
final String host = portColonIndex >= 0 ? hostAndPort.substring(0, portColonIndex) : hostAndPort;
|
||||
int port = UrlBuilder.PORT_UNSPECIFIED;
|
||||
if (portColonIndex >= 0) {
|
||||
try {
|
||||
port = Integer.valueOf(hostAndPort.substring(portColonIndex + 1));
|
||||
} catch (Exception e) {
|
||||
log.log(Level.SEVERE, "Error while parsing port for baseUrl: " + baseUrl, e);
|
||||
}
|
||||
}
|
||||
|
||||
final StringBuilder pathBuilder = new StringBuilder(pathPrefix);
|
||||
if (pathPrefix.endsWith("/")) {
|
||||
pathBuilder.append(path.startsWith("/") ? path.substring(1) : path);
|
||||
} else {
|
||||
if (!path.startsWith("/")) {
|
||||
pathBuilder.append("/");
|
||||
}
|
||||
pathBuilder.append(path);
|
||||
}
|
||||
|
||||
final UrlBuilder urlBuilder = createUrlBuilderFromCurrentLocationWithCleanParameters();
|
||||
urlBuilder.setPath(path);
|
||||
urlBuilder.setProtocol(protocol);
|
||||
urlBuilder.setHost(host);
|
||||
urlBuilder.setPath(pathBuilder.toString());
|
||||
urlBuilder.setPort(port);
|
||||
return urlBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link UrlBuilder} based on the current location but with clean parameters and fragment/hash. In
|
||||
* addition, the path part can specifically being set while the base (host/port/protocol) is the one of the current
|
||||
* location.
|
||||
* <p>
|
||||
*
|
||||
* Example:
|
||||
* <ul>
|
||||
* <li>Current location: http://www.sapsailing.com/gwt/Home.html?locale=de&some_param=some_value#abc123</li>
|
||||
* <li>path: /gwt/SomePage.html</li>
|
||||
* <li>Returned UrlBuilder: http://www.sapsailing.com/gwt/SomePage.html?locale=de</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static UrlBuilder createUrlBuilderFromCurrentLocationWithCleanParametersAndPath(String path) {
|
||||
return createUrlBuilderFromCurrentLocationWithCleanParameters().setPath(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link UrlBuilder} based on the current location but with clean parameters and fragment/hash. In
|
||||
* addition, the path and hash parts can specifically being set while the base (host/port/protocol) is the one of
|
||||
* the current location.
|
||||
* <p>
|
||||
*
|
||||
* Example:
|
||||
* <ul>
|
||||
* <li>Current location: http://www.sapsailing.com/gwt/Home.html?locale=de&some_param=some_value#abc123</li>
|
||||
* <li>path: /gwt/SomePage.html</li>
|
||||
* <li>hash: /some/place/:key=value</li>
|
||||
* <li>Returned UrlBuilder: http://www.sapsailing.com/gwt/SomePage.html?locale=de#/some/place/:key=value</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static UrlBuilder createUrlBuilderFromCurrentLocationWithCleanParametersAndPathAndHash(String path,
|
||||
String hash) {
|
||||
return createUrlBuilderFromCurrentLocationWithCleanParametersAndPath(path).setHash(hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link UrlBuilder} based on the current location but with clean parameters and fragment/hash. In
|
||||
* addition, the path part as well as URL parameters can specifically being set while the base (host/port/protocol)
|
||||
* is the one of the current location.
|
||||
* <p>
|
||||
*
|
||||
* Example:
|
||||
* <ul>
|
||||
* <li>Current location: http://www.sapsailing.com/gwt/Home.html?locale=de&some_param=some_value#abc123</li>
|
||||
* <li>path: /gwt/SomePage.html</li>
|
||||
* <li>parameters: {p1: [abc], p2: [xyz, 123]}</li>
|
||||
* <li>Returned UrlBuilder: http://www.sapsailing.com/gwt/SomePage.html?locale=de&p1=abc&p2=xyz&p2=123</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static UrlBuilder createUrlBuilderWithPathAndParameters(String path, Map<String, String> parameters) {
|
||||
final UrlBuilder urlBuilder = createUrlBuilderFromCurrentLocationWithCleanParametersAndPath(path);
|
||||
for (Map.Entry<String, String> entry : parameters.entrySet()) {
|
||||
urlBuilder.setParameter(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return urlBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link UrlBuilder} based on the current location but with clean parameters and fragment/hash. In
|
||||
* addition, the path and hash parts as well as URL parameters can specifically being set while the base
|
||||
* (host/port/protocol) is the one of the current location.
|
||||
* <p>
|
||||
*
|
||||
* Example:
|
||||
* <ul>
|
||||
* <li>Current location: http://www.sapsailing.com/gwt/Home.html?locale=de&some_param=some_value#abc123</li>
|
||||
* <li>path: /gwt/SomePage.html</li>
|
||||
* <li>hash: /some/place/:key=value parameters: {p1: [abc]}</li>
|
||||
* <li>Returned UrlBuilder: http://www.sapsailing.com/gwt/SomePage.html?locale=de&p1=abc#/some/place/:key=value</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static UrlBuilder createUrlBuilderWithPathAndHashAndParameters(String path, String hash,
|
||||
Map<String, String> parameters) {
|
||||
return createUrlBuilderWithPathAndParameters(path, parameters).setHash(hash);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -488,7 +488,8 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
|
||||
|
||||
public StringBuilder buildURL(String baseURL, Map<String, String> urlParameters) {
|
||||
StringBuilder url = new StringBuilder(baseURL);
|
||||
boolean first = !baseURL.contains("?");
|
||||
// Potentially contained hash is checked to support place-based mail verification
|
||||
boolean first = !baseURL.contains("?") || baseURL.contains("#");
|
||||
for (Map.Entry<String, String> e : urlParameters.entrySet()) {
|
||||
if (first) {
|
||||
url.append('?');
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<!-- Please ensure that serialization/replication works correctly, when updating the tycho version.
|
||||
Due to ECJ/JDT bugs it may fail depending on the Eclipse version tycho is based on
|
||||
(see Bugzilla: https://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=3859). -->
|
||||
<!-- Most likely, serialization/replication will fail with tycho versions based on Eclipse Neon R (4.6.0). -->
|
||||
<tycho-version>0.21.0</tycho-version>
|
||||
<gwt.version>2.7.0</gwt.version>
|
||||
<gwt.minVersion>2.7.0</gwt.minVersion>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<string name="log_file_template" translatable="false">sap_log_%s.txt</string>
|
||||
<string name="crash_file_name" translatable="false">sap_crash_%s.txt</string>
|
||||
<string name="options_menu_live">Connection Information</string>
|
||||
<string name="remove">Remove</string>
|
||||
<string name="enter_new_item">Enter new item</string>
|
||||
|
||||
+3
-1
@@ -14,13 +14,14 @@ import java.util.concurrent.BlockingQueue;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.sap.sailing.android.shared.R;
|
||||
import com.sap.sailing.android.shared.util.FileHandlerUtils;
|
||||
|
||||
public class FileLoggingTask implements Runnable {
|
||||
|
||||
private final static String TAG = FileLoggingTask.class.getName();
|
||||
|
||||
private final static String logFileTemplate = "sap_rc_log_%s.txt";
|
||||
private static String logFileTemplate;
|
||||
private final static String logFileDateFormat = "yyyyMMdd";
|
||||
|
||||
private final BlockingQueue<String> queue;
|
||||
@@ -34,6 +35,7 @@ public class FileLoggingTask implements Runnable {
|
||||
public FileLoggingTask(BlockingQueue<String> queue, Context context) {
|
||||
this.queue = queue;
|
||||
this.context = context.getApplicationContext();
|
||||
logFileTemplate = this.context.getString(R.string.log_file_template);
|
||||
}
|
||||
|
||||
public FileLoggingTask(Context context) {
|
||||
|
||||
+3
-1
@@ -6,6 +6,8 @@ import java.util.Date;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.sap.sailing.android.shared.R;
|
||||
|
||||
public class LoggingExceptionHandler implements UncaughtExceptionHandler {
|
||||
|
||||
private static final String TAG = LoggingExceptionHandler.class.getName();
|
||||
@@ -20,7 +22,7 @@ public class LoggingExceptionHandler implements UncaughtExceptionHandler {
|
||||
|
||||
public void uncaughtException(Thread thread, Throwable ex) {
|
||||
FileLoggingTask task = new FileLoggingTask(context);
|
||||
if (task.tryStartFileLogging("sap_rc_crash_%s.txt")) {
|
||||
if (task.tryStartFileLogging(context.getString(R.string.crash_file_name))) {
|
||||
task.log(String.format("%s - Exception occured on thread %s:", new Date(), thread.getId()));
|
||||
task.logException(ex);
|
||||
} else {
|
||||
|
||||
+17
-24
@@ -2,36 +2,29 @@ package com.sap.sailing.android.shared.util;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.content.SharedPreferences;
|
||||
import android.text.TextUtils;
|
||||
|
||||
/**
|
||||
* I'm picking a device id based on this reply on Stack Overflow: http://stackoverflow.com/a/2853253/3589281
|
||||
*
|
||||
* @author lukas
|
||||
*/
|
||||
public class UniqueDeviceUuid {
|
||||
|
||||
public static String getUniqueId(Context context) {
|
||||
/*
|
||||
* String existingDeviceIdentifier = prefs.getDeviceIdentifier();
|
||||
*
|
||||
* if (existingDeviceIdentifier != null && existingDeviceIdentifier.length() > 0) { return
|
||||
* existingDeviceIdentifier; }
|
||||
*/
|
||||
private static final String FILENAME = "Installation";
|
||||
private static final String UUID_KEY = "UUID";
|
||||
|
||||
final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
private static String mDeviceId;
|
||||
|
||||
final String tmDevice, tmSerial, androidId;
|
||||
tmDevice = "" + tm.getDeviceId();
|
||||
tmSerial = "" + tm.getSimSerialNumber();
|
||||
androidId = ""
|
||||
+ android.provider.Settings.Secure.getString(context.getContentResolver(),
|
||||
android.provider.Settings.Secure.ANDROID_ID);
|
||||
@SuppressLint("CommitPrefEdits")
|
||||
public synchronized static String getUniqueId(Context context) {
|
||||
if (mDeviceId == null) {
|
||||
SharedPreferences preferences = context.getSharedPreferences(FILENAME, Context.MODE_PRIVATE);
|
||||
mDeviceId = preferences.getString(UUID_KEY, null);
|
||||
if (TextUtils.isEmpty(mDeviceId)) {
|
||||
mDeviceId = UUID.randomUUID().toString();
|
||||
preferences.edit().putString(UUID_KEY, mDeviceId).commit();
|
||||
}
|
||||
}
|
||||
|
||||
UUID deviceUuid = new UUID(androidId.hashCode(), ((long) tmDevice.hashCode() << 32) | tmSerial.hashCode());
|
||||
String deviceId = deviceUuid.toString();
|
||||
|
||||
return deviceId;
|
||||
return mDeviceId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
|
||||
<uses-permission android:name="com.sap.sailing.android.tracking.app.permission.C2D_MESSAGE"/>
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<string name="preference_energy_saving_is_enabled">Ein</string>
|
||||
<string name="preference_energy_saving_is_disabled">Aus</string>
|
||||
<string name="preference_energy_saving_summary_is_enabled">GPS Updates werden alle 30 Sekunden verschickt.</string>
|
||||
<string name="preference_energy_saving_summary_is_disabled">GPS Updates werden alle 3 Sekunden verschickt.</string>
|
||||
<string name="preference_energy_saving_summary_is_disabled">GPS Updates werden jede Sekunde verschickt.</string>
|
||||
<string name="preference_heading_with_declination_subtracted_is_enabled">Ein</string>
|
||||
<string name="preference_heading_with_declination_subtracted_is_disabled">Aus</string>
|
||||
<string name="preference_heading_with_declination_subtracted_summary_is_enabled">Anzeige: Missweisend</string>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<string name="tracking_time">Tracking Zeit</string>
|
||||
<string name="app_name">SAP Sail InSight</string>
|
||||
<string name="options_menu_settings">Einstellungen</string>
|
||||
<string name="options_menu_checkout">Checkout</string>
|
||||
<string name="options_menu_checkout">Abmelden</string>
|
||||
<string name="options_add_team_photo">Team Foto hinzufügen</string>
|
||||
<string name="options_replace_team_photo">Team Foto ersetzen</string>
|
||||
<string name="settings_category_other">Andere Einstellungen</string>
|
||||
@@ -13,8 +13,8 @@
|
||||
<string name="device_identifier">Geräte-ID</string>
|
||||
<string name="stop_tracking">Stoppe Tracking</string>
|
||||
<string name="start_tracking">Starte Tracking</string>
|
||||
<string name="tracker_started">SAP Sail InSight gestartet</string>
|
||||
<string name="tracker_stopped">SAP Sail InSight gestoppt</string>
|
||||
<string name="tracker_started">Tracking wurde erfolgreich gestartet</string>
|
||||
<string name="tracker_stopped">Tracking wurde erfolgreich gestoppt</string>
|
||||
<string name="title_activity_regatta">Regatta</string>
|
||||
<string name="title_activity_leaderboard">Leaderboard</string>
|
||||
<string name="title_activity_start">GPS Tracker einstellen</string>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<string name="preference_energy_saving_is_enabled">On</string>
|
||||
<string name="preference_energy_saving_is_disabled">Off</string>
|
||||
<string name="preference_energy_saving_summary_is_enabled">GPS updates are being sent to server every 30 seconds.</string>
|
||||
<string name="preference_energy_saving_summary_is_disabled">GPS updates are being sent to server every 3 seconds.</string>
|
||||
<string name="preference_energy_saving_summary_is_disabled">GPS updates are being sent to server every second.</string>
|
||||
|
||||
<string name="preference_gps_fix_interval_ms_key" translatable="false">gpsFixInterval</string>
|
||||
<string name="preference_gps_fix_interval_ms_default" translatable="false">500</string>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="empty" translatable="false"></string>
|
||||
<string name="log_file_template" translatable="false">sap_insight_log_%s.txt</string>
|
||||
<string name="crash_file_name" translatable="false">sap_insight_crash_%s.txt</string>
|
||||
<string name="app_name">SAP Sail InSight</string>
|
||||
<string name="options_menu_settings">Settings</string>
|
||||
<string name="options_menu_checkout">Checkout</string>
|
||||
@@ -8,8 +10,8 @@
|
||||
<string name="options_replace_team_photo">Replace Team Photo</string>
|
||||
<string name="settings_category_other">Other Settings</string>
|
||||
<string name="device_identifier">Device Identifier</string>
|
||||
<string name="tracker_started">SAP Sail InSight started</string>
|
||||
<string name="tracker_stopped">SAP Sail InSight stopped</string>
|
||||
<string name="tracker_started">Tracking was successfully started</string>
|
||||
<string name="tracker_stopped">Tracking was successfully stopped</string>
|
||||
<string name="title_activity_regatta">Regatta</string>
|
||||
<string name="title_activity_leaderboard">Leaderboard</string>
|
||||
<string name="title_activity_start">Set Up GPS Tracker</string>
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
|
||||
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
@@ -23,6 +22,9 @@
|
||||
android:glEsVersion="0x00020000"
|
||||
android:required="true"/>
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.location.gps"
|
||||
android:required="true"/>
|
||||
|
||||
<application
|
||||
android:name="com.sap.sailing.android.shared.application.LoggableApplication"
|
||||
|
||||
Regular → Executable
+2
-2
@@ -2,7 +2,7 @@
|
||||
<resources>
|
||||
|
||||
<string name="course_type">Kurstyp</string>
|
||||
<string name="marks">Kursmarkierungen</string>
|
||||
<string name="marks">Bahnmarken</string>
|
||||
<string name="set_position">Position setzen</string>
|
||||
<string name="set_position_disabled_gps">GPS aktivieren,\n um die Position zu setzen</string>
|
||||
<string name="set_position_no_gps_yet">Warte auf GPS Signal</string>
|
||||
@@ -25,7 +25,7 @@
|
||||
<string name="server">Polling Einstellungen</string>
|
||||
<string name="server_sync_settings">Abfrage Intervall (Sekunden)</string>
|
||||
|
||||
<string name="options_menu_checkout">Checkout</string>
|
||||
<string name="options_menu_checkout">Abmelden</string>
|
||||
<string name="checkout_warning_message">Möchten Sie sich wirklich ausloggen? Sie müssen sich erneut mit dem QR code einloggen, um ihre Bojen zu sehen!</string>
|
||||
|
||||
<string name="no_marks_message">Kein Bojen</string>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<resources>
|
||||
|
||||
<string name="app_name" translatable="false">SAP Buoy Pinger</string>
|
||||
<string name="log_file_template" translatable="false">sap_buoy_log_%s.txt</string>
|
||||
<string name="crash_file_name" translatable="false">sap_buoy_crash_%s.txt</string>
|
||||
<string name="title_activity_start" translatable="false">SAP Buoy Pinger</string>
|
||||
<string name="course_type">Course Type</string>
|
||||
<string name="marks">Marks</string>
|
||||
@@ -12,8 +14,8 @@
|
||||
<string name="set">set</string>
|
||||
<string name="not_set">not set</string>
|
||||
<string name="mark_list_accuracy">(Accurary ca. %1$sm)</string>
|
||||
<string name="buoy_detail_accuracy_ca" translatable="false">ca. %1$sm</string>
|
||||
<string name="buoy_detail_distance" translatable="false">%1$sm</string>
|
||||
<string name="buoy_detail_accuracy_ca" translatable="false">ca. %1$.02fm</string>
|
||||
<string name="buoy_detail_distance" translatable="false">%1$.02fm</string>
|
||||
<string name="accuracy">GPS Accuracy</string>
|
||||
<string name="distance">Distance to old buoy</string>
|
||||
<string name="position_set">The position has been set</string>
|
||||
|
||||
+5
@@ -116,6 +116,11 @@ public class PositioningActivity extends BaseActivity implements pingListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
public MarkInfo getMarkInfo() {
|
||||
return markInfo;
|
||||
}
|
||||
|
||||
+131
-107
@@ -1,21 +1,16 @@
|
||||
package com.sap.sailing.android.buoy.positioning.app.ui.fragments;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.FragmentManager;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.location.GpsStatus;
|
||||
import android.content.IntentSender;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -25,6 +20,17 @@ import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.google.android.gms.common.api.PendingResult;
|
||||
import com.google.android.gms.common.api.ResultCallback;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.location.LocationListener;
|
||||
import com.google.android.gms.location.LocationRequest;
|
||||
import com.google.android.gms.location.LocationServices;
|
||||
import com.google.android.gms.location.LocationSettingsRequest;
|
||||
import com.google.android.gms.location.LocationSettingsResult;
|
||||
import com.google.android.gms.location.LocationSettingsStatusCodes;
|
||||
import com.google.android.gms.maps.CameraUpdateFactory;
|
||||
import com.google.android.gms.maps.GoogleMap;
|
||||
import com.google.android.gms.maps.MapFragment;
|
||||
@@ -43,25 +49,31 @@ import com.sap.sailing.android.shared.util.LocationHelper;
|
||||
import com.sap.sailing.android.shared.util.ViewHelper;
|
||||
import com.sap.sailing.android.ui.fragments.BaseFragment;
|
||||
|
||||
public class BuoyFragment extends BaseFragment implements LocationListener {
|
||||
public class BuoyFragment extends BaseFragment
|
||||
implements GoogleApiClient.ConnectionCallbacks, LocationListener, GoogleApiClient.OnConnectionFailedListener {
|
||||
|
||||
private static final String TAG = BuoyFragment.class.getName();
|
||||
private static final int GPS_MIN_DISTANCE = 1;
|
||||
|
||||
private static final int GPS_MIN_TIME = 1000;
|
||||
private static final String N_A = "n/a";
|
||||
private static final int REQUEST_CHECK_SETTINGS = 1 << 16;
|
||||
|
||||
private TextView accuracyTextView;
|
||||
private TextView distanceTextView;
|
||||
private Button setPositionButton;
|
||||
private MapFragment mapFragment;
|
||||
private Location lastKnownLocation;
|
||||
private LatLng savedPosition;
|
||||
private LocationManager locationManager;
|
||||
private pingListener pingListener;
|
||||
private SignalQualityIndicatorView signalQualityIndicatorView;
|
||||
private boolean initialLocationUpdate;
|
||||
private IntentReceiver mReceiver;
|
||||
private PositioningActivity positioningActivity;
|
||||
private LocalBroadcastManager mBroadcastManager;
|
||||
private GPSListener mGpsListener;
|
||||
|
||||
private GoogleApiClient mGoogleApiClient;
|
||||
private LocationRequest mLocationRequest;
|
||||
private LocationSettingsRequest mSettingsRequest;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
@@ -78,10 +90,19 @@ public class BuoyFragment extends BaseFragment implements LocationListener {
|
||||
signalQualityIndicatorView.setSignalQuality(GPSQuality.noSignal.toInt());
|
||||
|
||||
mReceiver = new IntentReceiver();
|
||||
mGpsListener = new GPSListener();
|
||||
mBroadcastManager = LocalBroadcastManager.getInstance(inflater.getContext());
|
||||
initMapFragment();
|
||||
|
||||
mLocationRequest = LocationRequest.create();
|
||||
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
|
||||
mLocationRequest.setInterval(GPS_MIN_TIME);
|
||||
mLocationRequest.setFastestInterval(GPS_MIN_TIME);
|
||||
|
||||
mSettingsRequest = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest).build();
|
||||
|
||||
mGoogleApiClient = new GoogleApiClient.Builder(getActivity()).addApi(LocationServices.API).addConnectionCallbacks(this)
|
||||
.addOnConnectionFailedListener(this).build();
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
@@ -92,7 +113,6 @@ public class BuoyFragment extends BaseFragment implements LocationListener {
|
||||
positioningActivity = (PositioningActivity) getActivity();
|
||||
mapFragment.getMap().setMapType(GoogleMap.MAP_TYPE_SATELLITE);
|
||||
initialLocationUpdate = true;
|
||||
initLocationProvider();
|
||||
MarkInfo mark = positioningActivity.getMarkInfo();
|
||||
signalQualityIndicatorView.setSignalQuality(GPSQuality.noSignal.toInt());
|
||||
if (mark != null) {
|
||||
@@ -106,7 +126,6 @@ public class BuoyFragment extends BaseFragment implements LocationListener {
|
||||
}
|
||||
}
|
||||
initMarkerReceiver();
|
||||
checkGPS();
|
||||
}
|
||||
|
||||
private void initMapFragment() {
|
||||
@@ -125,26 +144,63 @@ public class BuoyFragment extends BaseFragment implements LocationListener {
|
||||
|
||||
private void disablePositionButton() {
|
||||
setPositionButton.setEnabled(false);
|
||||
boolean gpsEnabled = LocationHelper.isGPSEnabled(getActivity());
|
||||
int buttonTextId = gpsEnabled ? R.string.set_position_no_gps_yet : R.string.set_position_disabled_gps;
|
||||
String text = getString(buttonTextId);
|
||||
setPositionButton.setText(text);
|
||||
int resId = LocationHelper.isGPSEnabled(getActivity()) ? R.string.set_position_no_gps_yet : R.string.set_position_disabled_gps;
|
||||
setPositionButton.setText(resId);
|
||||
}
|
||||
|
||||
private void checkGPS() {
|
||||
if (lastKnownLocation == null) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AppTheme_AlertDialog)
|
||||
.setMessage(R.string.error_message_no_position)
|
||||
.setPositiveButton(android.R.string.ok, null);
|
||||
if (!LocationHelper.isGPSEnabled(getActivity())) {
|
||||
builder.setNegativeButton(R.string.settings, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
LocationHelper.openLocationSettings(getActivity());
|
||||
}
|
||||
});
|
||||
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, mSettingsRequest);
|
||||
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
|
||||
@Override
|
||||
public void onResult(LocationSettingsResult settingsResult) {
|
||||
final Status status = settingsResult.getStatus();
|
||||
switch (status.getStatusCode()) {
|
||||
case LocationSettingsStatusCodes.SUCCESS:
|
||||
// All location settings are satisfied. The client can initialize location
|
||||
// requests here.
|
||||
startLocationUpdates();
|
||||
break;
|
||||
|
||||
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
|
||||
// Location settings are not satisfied. But could be fixed by showing the user
|
||||
// a dialog.
|
||||
try {
|
||||
// Show the dialog by calling startResolutionForResult(),
|
||||
// and check the result in onActivityResult().
|
||||
status.startResolutionForResult(getActivity(), REQUEST_CHECK_SETTINGS);
|
||||
} catch (IntentSender.SendIntentException e) {
|
||||
// Ignore the error.
|
||||
}
|
||||
break;
|
||||
|
||||
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
|
||||
// Location settings are not satisfied. However, we have no way to fix the
|
||||
// settings so we won't show the dialog.
|
||||
break;
|
||||
}
|
||||
}
|
||||
builder.show();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
int code = (requestCode + 1) << 16;
|
||||
switch (code) {
|
||||
case REQUEST_CHECK_SETTINGS:
|
||||
switch (resultCode) {
|
||||
case Activity.RESULT_OK:
|
||||
// All required changes were successfully made
|
||||
mGoogleApiClient.connect();
|
||||
break;
|
||||
|
||||
case Activity.RESULT_CANCELED:
|
||||
// The user was asked to change settings, but chose not to
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,33 +211,38 @@ public class BuoyFragment extends BaseFragment implements LocationListener {
|
||||
mBroadcastManager.registerReceiver(mReceiver, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
|
||||
mGoogleApiClient.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
// Unsubscribe from location updates for power saving
|
||||
locationManager.removeUpdates(this);
|
||||
locationManager.removeGpsStatusListener(mGpsListener);
|
||||
if (mGoogleApiClient.isConnected()) {
|
||||
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
|
||||
}
|
||||
mGoogleApiClient.disconnect();
|
||||
|
||||
mBroadcastManager.unregisterReceiver(mReceiver);
|
||||
}
|
||||
|
||||
public void setUpTextUI(Location location) {
|
||||
private void setUpTextUI(Location location) {
|
||||
String accuracyText = N_A;
|
||||
String distanceText = N_A;
|
||||
DecimalFormat accuracyFormatter = new DecimalFormat("#.##");
|
||||
String accuracyString = getString(R.string.buoy_detail_accuracy_ca);
|
||||
String distanceString = getString(R.string.buoy_detail_distance);
|
||||
if (location != null) {
|
||||
accuracyText = String.format(accuracyString, accuracyFormatter.format(location.getAccuracy()));
|
||||
accuracyText = getString(R.string.buoy_detail_accuracy_ca, location.getAccuracy());
|
||||
MarkPingInfo markPing = positioningActivity.getMarkPing();
|
||||
if (markPing != null) {
|
||||
double savedLatitude = Double.parseDouble(markPing.getLatitude());
|
||||
double savedLongitude = Double.parseDouble(markPing.getLongitude());
|
||||
savedPosition = new LatLng(savedLatitude, savedLongitude);
|
||||
float[] results = new float[1];
|
||||
Location.distanceBetween(location.getLatitude(), location.getLongitude(), savedLatitude, savedLongitude,
|
||||
results);
|
||||
Location.distanceBetween(location.getLatitude(), location.getLongitude(), savedLatitude, savedLongitude, results);
|
||||
float distance = results[0];
|
||||
distanceText = String.format(distanceString, accuracyFormatter.format(distance));
|
||||
distanceText = getString(R.string.buoy_detail_distance, distance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +273,6 @@ public class BuoyFragment extends BaseFragment implements LocationListener {
|
||||
map.animateCamera(CameraUpdateFactory.newLatLngZoom(lastKnownLatLng, 15));
|
||||
initialLocationUpdate = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void configureMap(GoogleMap map) {
|
||||
@@ -221,55 +281,19 @@ public class BuoyFragment extends BaseFragment implements LocationListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(String provider, int status, Bundle extras) {
|
||||
if (getActivity() instanceof PositioningActivity) {
|
||||
initLocationProvider();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderEnabled(String provider) {
|
||||
if (getActivity() instanceof PositioningActivity) {
|
||||
initLocationProvider();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderDisabled(String provider) {
|
||||
if (getActivity() instanceof PositioningActivity) {
|
||||
initLocationProvider();
|
||||
}
|
||||
}
|
||||
|
||||
private void initLocationProvider() {
|
||||
locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
|
||||
locationManager.removeUpdates(this);
|
||||
locationManager.removeGpsStatusListener(mGpsListener);
|
||||
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_MIN_TIME, GPS_MIN_DISTANCE, this);
|
||||
locationManager.addGpsStatusListener(mGpsListener);
|
||||
|
||||
Location initialLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
|
||||
|
||||
if (initialLocation != null) {
|
||||
onLocationChanged(initialLocation);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateMap() {
|
||||
private void updateMap() {
|
||||
GoogleMap map = mapFragment.getMap();
|
||||
map.clear();
|
||||
|
||||
if (savedPosition != null) {
|
||||
MarkerOptions savedLocactionOptions = new MarkerOptions();
|
||||
savedLocactionOptions.position(savedPosition);
|
||||
savedLocactionOptions.visible(true);
|
||||
map.addMarker(savedLocactionOptions);
|
||||
MarkerOptions markerOptions = new MarkerOptions();
|
||||
markerOptions.position(savedPosition);
|
||||
markerOptions.visible(true);
|
||||
map.addMarker(markerOptions);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void reportGPSQuality(float gpsAccuracy) {
|
||||
private void reportGPSQuality(float gpsAccuracy) {
|
||||
GPSQuality quality = GPSQuality.noSignal;
|
||||
|
||||
if (gpsAccuracy > 48) {
|
||||
@@ -280,10 +304,9 @@ public class BuoyFragment extends BaseFragment implements LocationListener {
|
||||
quality = GPSQuality.great;
|
||||
}
|
||||
signalQualityIndicatorView.setSignalQuality(quality.toInt());
|
||||
|
||||
}
|
||||
|
||||
public void handleSuccessfulResponse(){
|
||||
private void handleSuccessfulResponse() {
|
||||
Toast.makeText(getActivity(), getString(R.string.position_set), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@@ -291,7 +314,27 @@ public class BuoyFragment extends BaseFragment implements LocationListener {
|
||||
pingListener = listener;
|
||||
}
|
||||
|
||||
public enum GPSQuality {
|
||||
@Override
|
||||
public void onConnected(Bundle bundle) {
|
||||
checkGPS();
|
||||
}
|
||||
|
||||
private void startLocationUpdates() {
|
||||
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
|
||||
lastKnownLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionSuspended(int i) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionFailed(ConnectionResult connectionResult) {
|
||||
ExLog.e(getActivity(), TAG, "Failed to connect to Google Play Services for location updates");
|
||||
}
|
||||
|
||||
private enum GPSQuality {
|
||||
noSignal(0), poor(2), good(3), great(4);
|
||||
|
||||
private final int gpsQuality;
|
||||
@@ -343,29 +386,10 @@ public class BuoyFragment extends BaseFragment implements LocationListener {
|
||||
setUpTextUI(lastKnownLocation);
|
||||
updateMap();
|
||||
}
|
||||
if (action.equals(getString(R.string.ping_reached_server))){
|
||||
if (action.equals(getString(R.string.ping_reached_server))) {
|
||||
Log.d(TAG, "Response reached Buoy Fragment");
|
||||
handleSuccessfulResponse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class GPSListener implements GpsStatus.Listener {
|
||||
|
||||
@Override
|
||||
public void onGpsStatusChanged(int event) {
|
||||
switch (event) {
|
||||
case GpsStatus.GPS_EVENT_STOPPED: {
|
||||
if (isAdded()) {
|
||||
disablePositionButton();
|
||||
distanceTextView.setText(N_A);
|
||||
accuracyTextView.setText(N_A);
|
||||
mapFragment.getMap().setMyLocationEnabled(false);
|
||||
reportGPSQuality(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
<string-array name="empty_array" tools:ignore="UnusedResources"/>
|
||||
<string name="empty"></string>
|
||||
<string name="log_file_template" translatable="false">sap_rc_log_%s.txt</string>
|
||||
<string name="crash_file_name" translatable="false">sap_rc_crash_%s.txt</string>
|
||||
|
||||
<string name="intent_update_ui" translatable="false">com.sap.sailing.racecommittee.intent.update-ui</string>
|
||||
<string name="intent_update_ui_data" translatable="false">com.sap.sailing.racecommittee.intent.update-ui.data</string>
|
||||
|
||||
+13
-10
@@ -8,7 +8,7 @@ First of all, make sure you've looked at http://www.amazon.de/Patterns-Elements-
|
||||
|
||||
#### Installations
|
||||
|
||||
1. Eclipse (Eclipse IDE for Eclipse Committers, e.g. version 4.6 "Neon"), http://www.eclipse.org
|
||||
1. Eclipse (Eclipse IDE for Eclipse Committers, e.g. version 4.5.2 "Mars SR2"), http://www.eclipse.org
|
||||
2. Eclipse Extensions
|
||||
* Install GWT Eclipse plugin for Eclipse (http://gwt-plugins.github.io/documentation/gwt-eclipse-plugin/Download.html)
|
||||
* Install Eclipse debugger for GWT SuperDevMode (master version: http://p2.sapsailing.com/p2/sdbg; public release: http://sdbg.github.io/p2)
|
||||
@@ -23,9 +23,9 @@ First of all, make sure you've looked at http://www.amazon.de/Patterns-Elements-
|
||||
|
||||
#### Automatic Eclipse plugin installation
|
||||
|
||||
The necessary Eclipse plugins described above can be automatically be installed into a newly unzipped version of [Eclipse IDE for Eclipse Committers 4.6 "Neon"](http://www.eclipse.org/downloads/packages/eclipse-ide-eclipse-committers/neonr) by using the script "configuration/installPluginsForEclipseNeon.sh". In addition, the script applies some updates to plugins packaged with Eclipse itself. To start the plugin installation, run the following command using our Eclipse installation directory as command line parameter for the script:
|
||||
The necessary Eclipse plugins described above can be automatically be installed into a newly unzipped version of [Eclipse IDE for Eclipse Committers 4.5.2 "Mars SR2"](http://www.eclipse.org/downloads/packages/eclipse-ide-eclipse-committers-452/mars2) by using the script "configuration/installPluginsForEclipseMars.sh". In addition, the script applies some updates to plugins packaged with Eclipse itself. To start the plugin installation, run the following command using your Eclipse installation directory as command line parameter for the script:
|
||||
|
||||
./installPluginsForEclipseNeon.sh "/some/path/on/my/computer/eclipse"
|
||||
./installPluginsForEclipseMars.sh "/some/path/on/my/computer/eclipse"
|
||||
|
||||
Be aware that with this script it's not possible to update the plugins to newer versions. Instead you can install a new version by unpacking the base package and executing the script.
|
||||
|
||||
@@ -35,6 +35,9 @@ On Mac OS, it's not sufficient to provide the path to the app, instead you need
|
||||
|
||||
Be aware hat the installation may take several minutes depending on your Internet connection. When the script finished running, please check that no errors occurred (the installation process only logs errors but doesn't fail).
|
||||
|
||||
__NOTE:__
|
||||
Beside the installation script for Eclipse Mars, there is also one for the new Eclipse Neon release (4.6.0). Due to a ECJ/JDT regression, this version will brake project functionality. If you've already installed Eclipse Neon, you can easily downgrade to Mars SR2, reusing your existing workspace. You just have to accept the warning you'll get during first startup and perform a workspace cleanup (`Project > Clean... > Clean all projects`). In rare cases, the target platform must be set again.
|
||||
|
||||
#### Further optional but recommended installations
|
||||
|
||||
1. Cygwin, http://www.cygwin.com/
|
||||
@@ -55,12 +58,12 @@ Be aware hat the installation may take several minutes depending on your Interne
|
||||
* Send a request to Axel Uhl or Simon Marcel Pamies that includes the SHA1 hash of your desired password. Obtain such an SHA1 hash for your password here: http://www.sha1-online.com/.
|
||||
4. Hudson
|
||||
* Request a Hudson user by sending e-mail to Axel Uhl, Frank Mittag or Simon Marcel Pamies.
|
||||
|
||||
#### Steps to build and run the Race Analysis Suite
|
||||
|
||||
|
||||
#### Steps to build and run the Race Analysis Suite
|
||||
|
||||
1. Get the content of the git repository
|
||||
* Generate SSH Keys with "ssh-keygen -t rsa -C "" " command in Cygwin Terminal (Not with Putty!!!)
|
||||
* Clone the repository to your local file system from `ssh://[SAP-User]@git.wdf.sap.corp:29418/SAPSail/sapsailingcapture.git` or `ssh://[user]@sapsailing.com/home/trac/git` User "trac" has all public ssh keys.
|
||||
* Clone the repository to your local file system from `ssh://[SAP-User]@git.wdf.sap.corp:29418/SAPSail/sapsailingcapture.git` or `ssh://[user]@sapsailing.com/home/trac/git` User "trac" has all public ssh keys.
|
||||
2. Check out the 'master' branch from the git repository. The 'master' branch is the main development branch. Please check that you start your work on this branch.
|
||||
3. Setup and configure Eclipse
|
||||
* Make absolutely sure to import CodeFormatter.xml (from $GIT_HOME/java) into your Eclipse preferences (Preferences->Java->Code Style->Fortmatter)
|
||||
@@ -100,7 +103,7 @@ Copy the settings.xml from the top-level git folder to your ~/.m2 directory and
|
||||
- Install the GWT Browser Plugin (Chrome or Firefox; as of this writing (2013-11-05), Firefox is the only platform where the plug-in runs stably) for the GWT Development mode
|
||||
|
||||
#### Additional steps required for Android projects
|
||||
|
||||
|
||||
To ensure that all components of the Analysis Suite are working, you should also import all Android projects (mobile/) into your workspace. There are some additional requirements to enable the build process of these projects.
|
||||
|
||||
1. Add the Android Development Tools (ADT) plugin to your Eclipse IDE
|
||||
@@ -149,7 +152,7 @@ If you are working with a linux-system and you get the error message `error whil
|
||||
|
||||
The Android Apps can be built in Android Studio or gradle command line. Android Studio is built on top of IntelliJ IDEA, so it is possible to use IntelliJ IDEA as well.
|
||||
|
||||
1. On the "Welcome Screen" choose "Import Project (Eclipse, ADT, Gradle, etc.)"
|
||||
1. On the "Welcome Screen" choose "Import Project (Eclipse, ADT, Gradle, etc.)"
|
||||
2. Navigate to the project root folder and select the "build.gradle" file (all used modules are defined in "settings.gradle")
|
||||
* it will download all necessary gradle runtime files
|
||||
* you will see floating messages at the top right
|
||||
@@ -181,4 +184,4 @@ If git is not in the Path system environment variable, the gradle build will not
|
||||
2. choose git in the drop down
|
||||
3. if everything is correct, you'll see the current branch at the bottom line
|
||||
|
||||
See [RaceCommittee App](racecommittee-app) for more information regarding the mobile app.
|
||||
See [RaceCommittee App](racecommittee-app) for more information regarding the mobile app.
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
## prerequisitites
|
||||
First of all, you need either an online server landscape which is accessible from outside, or a local one with a working setup allowing your smartphone or tablet to establish a connection to.
|
||||
|
||||
## event setup
|
||||
Log on to the Administration Console and make sure you have a working Event setup.
|
||||
For further information on how to achieve this, have a look at [this walkthrough](./wiki/racelog-tracking/walkthrough).
|
||||
After completing these steps up until the point "Add Device Mappings" or by simply following the step-by-step wizard, you should have the following setup:
|
||||
|
||||
* an Event
|
||||
* a Leaderboard Group
|
||||
* a Regatta linked to your event
|
||||
* A Leaderboard linked to your Leaderboard Group
|
||||
|
||||
_Hint:_ You can link Leaderboards to a Leaderboard Group by selecting your group under the tab "Leaderboards" on the left hand side and then selecting one or multiple Leaderboards on the right hand side and adding them by using the "<-" arrow.
|
||||
Usually this step is carried out by the wizard automatically.
|
||||
|
||||
* Competitors in your Regatta
|
||||
* races denoted for racelog tracking
|
||||
* defined course layouts for these races
|
||||
|
||||
## pinning buoys and other race marks
|
||||
To map positions of all of the required marks, you need to invite one or multiple people as Buoy Tenders. Do so by navigating to "Connectors->Smartphone Tracking" in the Admin Console, selecting your Regatta from the list, and then clicking the Mail Icon under "Actions" within the entry.
|
||||
|
||||
Those invited people then need to download the [SAP Sailing Buoy Pinger](https://play.google.com/store/apps/details?id=com.sap.sailing.android.buoy.positioning.app) App - a link is also provided in the mail they received. Once installed, they will see all marks related to this regatta listed within the app, enabling them to ping their exact positions via GPS.
|
||||
You can later on adjust these positions within the app, or manually in the Admin Console once Tracking has started.
|
||||
|
||||
## start tracking using an Android phone or tablet
|
||||
At the same location where you can invite Buoy Pinners, you'll also find the option to map devices to competitors and marks. It is the small smartphone icon next to the mail icon. Once clicked, you will see a screen with potentially earlier created device mappings.
|
||||
|
||||
**To add a new device**
|
||||
|
||||
* click "Add" in the top left corner, leading you to another screen
|
||||
* Within that screen, you can select a mark or a competitor you'd like to track
|
||||
* You possibly have to select the correct event if there is more than one
|
||||
* you will then be provided with a QR code which you will be asked for in the [SAP Sail InSight](https://play.google.com/store/apps/details?id=com.sap.sailing.android.tracking.app) App
|
||||
* get the app, scan the code and hit "Start Tracking".
|
||||
|
||||
Once tracking has started, you should see a running timer.
|
||||
|
||||
## follow trackers on the web interface
|
||||
Back in the Admin Console, you can click on the race you just started tracking. This will open a new tab showing the map of the course.
|
||||
|
||||
In the bottom right corner, you can edit mark positions and (possibly missed) passings manually, on the left hand side, there is the option to select the competitors you want to see on the map.
|
||||
Reference in New Issue
Block a user