mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-30 15:57:11 +00:00
Several bug fixes of the recent app implementation
This commit is contained in:
1 parent
6c68ae868c
commit
78f70a0134
10 files changed
+546
-523
No files matched your search
@@ -60,6 +60,7 @@
|
||||
<string name="racelist_scheduled">Scheduled for %s</string>
|
||||
<string name="racelist_startphase">Start at %s in progress</string>
|
||||
<string name="racelist_running">Running since %s</string>
|
||||
<string name="racelist_finishing">Finishing</string>
|
||||
<string name="racelist_finished">Finished</string>
|
||||
<string name="racelist_unknown">Unknown</string>
|
||||
<string name="currentlyLoading">Currently loading …</string>
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.SetStartTimeRaceF
|
||||
|
||||
public class AppConstants {
|
||||
|
||||
public static final boolean IS_DATA_OFFLINE = true;
|
||||
public static final boolean IS_DATA_OFFLINE = false;
|
||||
|
||||
public final static String ApplicationVersion = "2.0 Beta 1 - Jumbotron";
|
||||
|
||||
|
||||
+3
-1
@@ -12,6 +12,7 @@ import com.sap.sailing.domain.racelog.PassAwareRaceLog;
|
||||
import com.sap.sailing.domain.racelog.RaceLog;
|
||||
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
||||
import com.sap.sailing.racecommittee.app.domain.ManagedRaceIdentifier;
|
||||
import com.sap.sailing.racecommittee.app.domain.startprocedure.impl.ExtremeSailingSeriesStartProcedure;
|
||||
import com.sap.sailing.racecommittee.app.domain.state.RaceState;
|
||||
import com.sap.sailing.racecommittee.app.domain.state.impl.RaceStateImpl;
|
||||
|
||||
@@ -25,7 +26,8 @@ public class ManagedRaceImpl implements ManagedRace {
|
||||
private Iterable<Competitor> competitors;
|
||||
|
||||
public ManagedRaceImpl(ManagedRaceIdentifier identifier, PassAwareRaceLog raceLog, Iterable<Competitor> competitors) {
|
||||
this(identifier, new RaceStateImpl(raceLog, null), competitors);
|
||||
//TODO To be changed when the start procedure for a regatta/leaderboard can be selected in the GWT Admin Console on backend side
|
||||
this(identifier, new RaceStateImpl(raceLog, new ExtremeSailingSeriesStartProcedure(raceLog)), competitors);
|
||||
}
|
||||
|
||||
public ManagedRaceImpl(
|
||||
|
||||
+9
-2
@@ -83,15 +83,21 @@ public class RaceStateImpl implements RaceState, RaceLogChangedListener {
|
||||
RaceLogRaceStatus oldStatus = this.status;
|
||||
this.status = newStatus;
|
||||
if (oldStatus != newStatus) {
|
||||
notifyListeners();
|
||||
notifyListenersAboutStateChange();
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListeners() {
|
||||
private void notifyListenersAboutStateChange() {
|
||||
for (RaceStateChangedListener listener : stateChangedListeners) {
|
||||
listener.onRaceStateChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListenersAboutStartTimeChange(TimePoint newStartTime) {
|
||||
for (RaceStateChangedListener listener : stateChangedListeners) {
|
||||
listener.onStartTimeChanged(newStartTime);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerListener(RaceStateChangedListener listener) {
|
||||
stateChangedListeners.add(listener);
|
||||
@@ -116,6 +122,7 @@ public class RaceStateImpl implements RaceState, RaceLogChangedListener {
|
||||
RaceLogEvent event = RaceLogEventFactory.INSTANCE.createStartTimeEvent(eventTime, UUID.randomUUID(),
|
||||
Collections.<Competitor> emptyList(), raceLog.getCurrentPassId(), newStartTime);
|
||||
this.raceLog.add(event);
|
||||
notifyListenersAboutStartTimeChange(newStartTime);
|
||||
}
|
||||
|
||||
public TimePoint getFinishedTime() {
|
||||
|
||||
+3
-3
@@ -17,6 +17,7 @@ import android.content.Intent;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEvent;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
|
||||
@@ -160,7 +161,7 @@ public class RaceStateService extends Service {
|
||||
return;
|
||||
}
|
||||
|
||||
TimePoint eventTime = (TimePoint) intent.getSerializableExtra(AppConstants.RACING_EVENT_TIME);
|
||||
TimePoint eventTime = new MillisecondsTimePoint(intent.getExtras().getLong(AppConstants.RACING_EVENT_TIME));
|
||||
|
||||
if (getString(R.string.intentActionAlarmAction).equals(action)) {
|
||||
race.getState().getStartProcedure().dispatchFiredEventTimePoint(race.getState().getStartTime(), eventTime);
|
||||
@@ -208,8 +209,6 @@ public class RaceStateService extends Service {
|
||||
|
||||
this.registeredLogListeners.put(race, logListener);
|
||||
this.registeredStateListeners.put(race, stateListener);
|
||||
|
||||
ExLog.i(TAG, "Race " + race.getId() + " is scheduled now.");
|
||||
} else {
|
||||
ExLog.i(TAG, "Race " + race.getId() + " was already registered. Ignoring.");
|
||||
}
|
||||
@@ -235,6 +234,7 @@ public class RaceStateService extends Service {
|
||||
for (TimePoint eventFireTimePoint : fireTimePoints) {
|
||||
scheduleEventTime(race, eventFireTimePoint);
|
||||
}
|
||||
ExLog.i(TAG, "Race " + race.getId() + " is scheduled now.");
|
||||
}
|
||||
|
||||
private void scheduleEventTime(ManagedRace race, TimePoint eventFireTimePoint) {
|
||||
|
||||
+180
-169
@@ -1,169 +1,180 @@
|
||||
package com.sap.sailing.racecommittee.app.services.sending;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.sap.sailing.racecommittee.app.AppConstants;
|
||||
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
||||
import com.sap.sailing.racecommittee.app.utils.FileHandlerUtils;
|
||||
|
||||
public class EventPersistenceManager {
|
||||
|
||||
private final static String TAG = EventPersistenceManager.class.getName();
|
||||
|
||||
private final static String delayedEventFileName = "delayedEvents.txt";
|
||||
|
||||
private Context context;
|
||||
private String fileContent;
|
||||
|
||||
public EventPersistenceManager(Context context) {
|
||||
this.context = context;
|
||||
fileContent = "";
|
||||
initializeFile();
|
||||
}
|
||||
|
||||
public boolean areIntentsDelayed() {
|
||||
return !fileContent.isEmpty();
|
||||
}
|
||||
|
||||
public void persistIntent(Intent intent) {
|
||||
Bundle extras = intent.getExtras();
|
||||
|
||||
Serializable serializedEvent = extras.getSerializable(AppConstants.EXTRAS_JSON_KEY);
|
||||
String raceUuid = extras.getSerializable(AppConstants.RACE_ID_KEY).toString();
|
||||
|
||||
persistEvent(raceUuid, serializedEvent);
|
||||
}
|
||||
|
||||
private void persistEvent(String raceUuid, Serializable serializedEvent) {
|
||||
String eventLine = String.format("%s;%s\n", raceUuid, serializedEvent);
|
||||
ExLog.i(TAG, "Called to persist following event " + eventLine);
|
||||
|
||||
if (!fileContent.isEmpty()) {
|
||||
if (fileContent.contains(eventLine)) {
|
||||
ExLog.i(TAG, "The event to persist exists already in file");
|
||||
return;
|
||||
}
|
||||
}
|
||||
writeEventToFile(eventLine);
|
||||
}
|
||||
|
||||
public void removeIntent(Intent intent) {
|
||||
Bundle extras = intent.getExtras();
|
||||
|
||||
String serializedEvent = extras.getString(AppConstants.EXTRAS_JSON_KEY);
|
||||
String raceUuid = extras.getString(AppConstants.RACE_ID_KEY);
|
||||
|
||||
removeEvent(raceUuid, serializedEvent);
|
||||
}
|
||||
|
||||
private void removeEvent(String raceUuid, String serializedEvent) {
|
||||
if (fileContent.isEmpty())
|
||||
return;
|
||||
|
||||
ExLog.i(TAG, "removeEvent is called for " + raceUuid + ", serializedEvent " + serializedEvent);
|
||||
String eventLine = String.format("%s;%s\n", raceUuid, serializedEvent);
|
||||
|
||||
removeEntryInFileContent(eventLine);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param eventLine
|
||||
*/
|
||||
private void removeEntryInFileContent(String eventLine) {
|
||||
if (fileContent.contains(eventLine)) {
|
||||
fileContent = fileContent.replace(eventLine, "");
|
||||
writeFileContentToFile();
|
||||
ExLog.i(TAG, "Entry " + eventLine + " is removed from fileContent");
|
||||
}
|
||||
}
|
||||
|
||||
public int getEventCount() {
|
||||
if (fileContent.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
return fileContent.split("\n").length;
|
||||
}
|
||||
|
||||
public List<Intent> restoreEvents() {
|
||||
List<Intent> delayedIntents = new ArrayList<Intent>();
|
||||
|
||||
if (!fileContent.isEmpty()) {
|
||||
String[] eventLines = fileContent.split("\n");
|
||||
for (String line : eventLines) {
|
||||
String[] lineParts = line.split(";");
|
||||
|
||||
Intent eventIntent = EventSendingService.createEventIntent(context, lineParts[0], lineParts[1]);
|
||||
delayedIntents.add(eventIntent);
|
||||
}
|
||||
}
|
||||
|
||||
ExLog.i(TAG, "Restored " + delayedIntents.size() + " events");
|
||||
return delayedIntents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
private String getFileContent() throws FileNotFoundException {
|
||||
String fileContent = "";
|
||||
FileInputStream inputStream;
|
||||
try {
|
||||
inputStream = context.openFileInput(delayedEventFileName);
|
||||
|
||||
fileContent = FileHandlerUtils.convertStreamToString(inputStream);
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
ExLog.e(TAG, "In Method getFileContent(): " + e.getMessage() + " fileContent is empty");
|
||||
}
|
||||
return fileContent;
|
||||
}
|
||||
|
||||
private void writeEventToFile(String eventLine) {
|
||||
fileContent += eventLine;
|
||||
writeFileContentToFile();
|
||||
ExLog.i(TAG, "Wrote event to file: " + eventLine);
|
||||
}
|
||||
|
||||
private void writeFileContentToFile() {
|
||||
writeToFile(fileContent, Context.MODE_PRIVATE);
|
||||
ExLog.i(TAG, "Wrote file content to file: " + fileContent);
|
||||
}
|
||||
|
||||
private void initializeFile() {
|
||||
try {
|
||||
fileContent = getFileContent();
|
||||
} catch (FileNotFoundException e) {
|
||||
ExLog.w(TAG, "persistence file not found in internal storage. The file will be created.");
|
||||
clearFileContent();
|
||||
}
|
||||
ExLog.i(TAG, "Initialized file");
|
||||
}
|
||||
|
||||
private void clearFileContent() {
|
||||
fileContent = "";
|
||||
writeFileContentToFile();
|
||||
}
|
||||
|
||||
private void writeToFile(String content, int mode) {
|
||||
try {
|
||||
FileOutputStream outputStream = context.openFileOutput(delayedEventFileName, mode);
|
||||
outputStream.write(content.getBytes());
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
ExLog.e(TAG, "In Method writeToFile: " + e.getMessage() + " with content " + content + " and mode " + mode);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package com.sap.sailing.racecommittee.app.services.sending;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.sap.sailing.racecommittee.app.AppConstants;
|
||||
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
||||
import com.sap.sailing.racecommittee.app.utils.FileHandlerUtils;
|
||||
|
||||
public class EventPersistenceManager {
|
||||
|
||||
private final static String TAG = EventPersistenceManager.class.getName();
|
||||
|
||||
private final static String delayedEventFileName = "delayedEvents.txt";
|
||||
|
||||
private Context context;
|
||||
private String fileContent;
|
||||
|
||||
public EventPersistenceManager(Context context) {
|
||||
this.context = context;
|
||||
fileContent = "";
|
||||
initializeFile();
|
||||
}
|
||||
|
||||
public boolean areIntentsDelayed() {
|
||||
return !fileContent.isEmpty();
|
||||
}
|
||||
|
||||
public void persistIntent(Intent intent) {
|
||||
Bundle extras = intent.getExtras();
|
||||
|
||||
Serializable serializedEvent = extras.getSerializable(AppConstants.EXTRAS_JSON_KEY);
|
||||
String raceUuid = extras.getSerializable(AppConstants.RACE_ID_KEY).toString();
|
||||
|
||||
persistEvent(raceUuid, serializedEvent);
|
||||
}
|
||||
|
||||
private void persistEvent(String raceUuid, Serializable serializedEvent) {
|
||||
String eventLine = String.format("%s;%s\n", raceUuid, serializedEvent);
|
||||
ExLog.i(TAG, "Called to persist following event " + eventLine);
|
||||
|
||||
if (!fileContent.isEmpty()) {
|
||||
if (fileContent.contains(eventLine)) {
|
||||
ExLog.i(TAG, "The event to persist exists already in file");
|
||||
return;
|
||||
}
|
||||
}
|
||||
writeEventToFile(eventLine);
|
||||
}
|
||||
|
||||
public void removeIntent(Intent intent) {
|
||||
Bundle extras = intent.getExtras();
|
||||
|
||||
String serializedEvent = extras.getString(AppConstants.EXTRAS_JSON_KEY);
|
||||
String raceUuid = extras.getString(AppConstants.RACE_ID_KEY);
|
||||
|
||||
removeEvent(raceUuid, serializedEvent);
|
||||
}
|
||||
|
||||
private void removeEvent(String raceUuid, String serializedEvent) {
|
||||
if (fileContent.isEmpty())
|
||||
return;
|
||||
|
||||
ExLog.i(TAG, "removeEvent is called for " + raceUuid + ", serializedEvent " + serializedEvent);
|
||||
String eventLine = String.format("%s;%s\n", raceUuid, serializedEvent);
|
||||
|
||||
removeEntryInFileContent(eventLine);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param eventLine
|
||||
*/
|
||||
private void removeEntryInFileContent(String eventLine) {
|
||||
if (fileContent.contains(eventLine)) {
|
||||
fileContent = fileContent.replace(eventLine + "\n", "");
|
||||
writeFileContentToFile();
|
||||
ExLog.i(TAG, "Entry " + eventLine + " is removed from fileContent");
|
||||
}
|
||||
}
|
||||
|
||||
public int getEventCount() {
|
||||
if (fileContent.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
return fileContent.split("\n").length;
|
||||
}
|
||||
|
||||
public List<Intent> restoreEvents() {
|
||||
List<Intent> delayedIntents = new ArrayList<Intent>();
|
||||
List<String> fileEntriesToBeRemoved = new ArrayList<String>(); //These file entries may be too old. No appropriate race id has been found for this event.
|
||||
|
||||
if (!fileContent.isEmpty()) {
|
||||
String[] eventLines = fileContent.split("\n");
|
||||
for (String line : eventLines) {
|
||||
if (!line.isEmpty()) {
|
||||
String[] lineParts = line.split(";");
|
||||
|
||||
Intent eventIntent = EventSendingService.createEventIntent(context, lineParts[0], lineParts[1]);
|
||||
if (eventIntent != null) {
|
||||
delayedIntents.add(eventIntent);
|
||||
} else {
|
||||
fileEntriesToBeRemoved.add(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String lineToBeRemoved : fileEntriesToBeRemoved) {
|
||||
removeEntryInFileContent(lineToBeRemoved);
|
||||
}
|
||||
|
||||
ExLog.i(TAG, "Restored " + delayedIntents.size() + " events");
|
||||
return delayedIntents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
private String getFileContent() throws FileNotFoundException {
|
||||
String fileContent = "";
|
||||
FileInputStream inputStream;
|
||||
try {
|
||||
inputStream = context.openFileInput(delayedEventFileName);
|
||||
|
||||
fileContent = FileHandlerUtils.convertStreamToString(inputStream);
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
ExLog.e(TAG, "In Method getFileContent(): " + e.getMessage() + " fileContent is empty");
|
||||
}
|
||||
return fileContent;
|
||||
}
|
||||
|
||||
private void writeEventToFile(String eventLine) {
|
||||
fileContent += eventLine;
|
||||
writeFileContentToFile();
|
||||
ExLog.i(TAG, "Wrote event to file: " + eventLine);
|
||||
}
|
||||
|
||||
private void writeFileContentToFile() {
|
||||
writeToFile(fileContent, Context.MODE_PRIVATE);
|
||||
ExLog.i(TAG, "Wrote file content to file: " + fileContent);
|
||||
}
|
||||
|
||||
private void initializeFile() {
|
||||
try {
|
||||
fileContent = getFileContent();
|
||||
} catch (FileNotFoundException e) {
|
||||
ExLog.w(TAG, "persistence file not found in internal storage. The file will be created.");
|
||||
clearFileContent();
|
||||
}
|
||||
ExLog.i(TAG, "Initialized file");
|
||||
}
|
||||
|
||||
private void clearFileContent() {
|
||||
fileContent = "";
|
||||
writeFileContentToFile();
|
||||
}
|
||||
|
||||
private void writeToFile(String content, int mode) {
|
||||
try {
|
||||
FileOutputStream outputStream = context.openFileOutput(delayedEventFileName, mode);
|
||||
outputStream.write(content.getBytes());
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
ExLog.e(TAG, "In Method writeToFile: " + e.getMessage() + " with content " + content + " and mode " + mode);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+231
-232
@@ -1,232 +1,231 @@
|
||||
package com.sap.sailing.racecommittee.app.ui.adapters.racelist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Filter;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
||||
import com.sap.sailing.racecommittee.app.R;
|
||||
import com.sap.sailing.racecommittee.app.ui.comparators.RaceListDataTypeElementComparator;
|
||||
import com.sap.sailing.racecommittee.app.ui.comparators.RaceListDataTypeTitleComparator;
|
||||
|
||||
public class RaceListAdapter extends ArrayAdapter<RaceListDataType> {
|
||||
|
||||
public interface JuryFlagClickedListener {
|
||||
public void onJuryFlagClicked(BoatClassSeriesDataFleet clickedItem);
|
||||
}
|
||||
|
||||
public static final int VIEW_TYPE_COUNT = 2;
|
||||
public static final int VIEW_BOAT_GROUP = 0;
|
||||
public static final int VIEW_RACE = 1;
|
||||
|
||||
private LayoutInflater mInflater;
|
||||
private JuryFlagClickedListener juryListener;
|
||||
private RaceFilter filter;
|
||||
private final Object mLock = new Object();
|
||||
|
||||
private List<RaceListDataType> items;
|
||||
private List<RaceListDataType> originalItems;
|
||||
|
||||
public RaceListAdapter(Context context, int textViewResourceId,
|
||||
List<RaceListDataType> objects, JuryFlagClickedListener juryListener) {
|
||||
super(context, textViewResourceId, objects);
|
||||
this.items = objects;
|
||||
this.originalItems = new ArrayList<RaceListDataType>();
|
||||
|
||||
this.juryListener = juryListener;
|
||||
mInflater = (LayoutInflater) (getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
synchronized(mLock) {
|
||||
return items!=null ? items.size() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceListDataType getItem(int position) {
|
||||
RaceListDataType element = null;
|
||||
synchronized(mLock) {
|
||||
element = items!=null ? items.get(position) : null;
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return (getItem(position) instanceof RaceListDataTypeTitle ? VIEW_BOAT_GROUP
|
||||
: VIEW_RACE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
return VIEW_TYPE_COUNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int position) {
|
||||
return (getItem(position) instanceof RaceListDataTypeElement);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
RaceListDataType raceListElement = null;
|
||||
|
||||
raceListElement = getItem(position);
|
||||
|
||||
ViewHolder holder = null;
|
||||
int type = getItemViewType(position);
|
||||
|
||||
if (convertView == null) {
|
||||
holder = new ViewHolder();
|
||||
if (type == VIEW_BOAT_GROUP) {
|
||||
convertView = mInflater.inflate(R.layout.welter_one_row_no_image_label, null);
|
||||
holder.line1 = (TextView) convertView.findViewById(R.id.Welter_Cell_OneRowNoImageLabel_txtTitle);
|
||||
holder.button1 = (ImageButton) convertView.findViewById(R.id.Welter_Cell_OneRowNoImageLabel_btnJury);
|
||||
} else if (type == VIEW_RACE) {
|
||||
convertView = mInflater.inflate(R.layout.welter_two_row_no_image, null);
|
||||
holder.line1 = (TextView) convertView.findViewById(R.id.Welter_Cell_TwoRowNoImage_lineOne);
|
||||
holder.line2 = (TextView) convertView.findViewById(R.id.Welter_Cell_TwoRowNoImage_lineTwo);
|
||||
holder.updateLabel = (ImageView) convertView.findViewById(R.id.Welter_Cell_UpdateLabel);
|
||||
}
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
if (type == VIEW_BOAT_GROUP) {
|
||||
final RaceListDataTypeTitle title = (RaceListDataTypeTitle) raceListElement;
|
||||
holder.line1.setText(title.toString());
|
||||
holder.button1.setOnClickListener(new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
juryListener.onJuryFlagClicked(title.getBoatClassSeriesDataFleet());
|
||||
}
|
||||
});
|
||||
} else if (type == VIEW_RACE) {
|
||||
RaceListDataTypeElement element = (RaceListDataTypeElement) raceListElement;
|
||||
holder.line1.setText(element.getRaceName());
|
||||
holder.line2.setText(element.getStatus());
|
||||
|
||||
if (element.isUpdateIndicatorVisible()) {
|
||||
holder.updateLabel.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter getFilter() {
|
||||
if (filter == null) {
|
||||
filter = new RaceFilter();
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
public List<RaceListDataType> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
static class ViewHolder {
|
||||
TextView line1, line2;
|
||||
ImageButton button1;
|
||||
ImageView updateLabel;
|
||||
}
|
||||
|
||||
private class RaceFilter extends Filter {
|
||||
|
||||
@Override
|
||||
protected FilterResults performFiltering(CharSequence constraint) {
|
||||
// Initiate our results object
|
||||
FilterResults results = new FilterResults();
|
||||
List<RaceListDataType> dataTypeList = new ArrayList<RaceListDataType>();
|
||||
|
||||
if (originalItems.isEmpty()) {
|
||||
originalItems = new ArrayList<RaceListDataType>(items.size());
|
||||
for (RaceListDataType type : items) {
|
||||
originalItems.add(type);
|
||||
}
|
||||
}
|
||||
|
||||
if (originalItems.isEmpty()) {
|
||||
results.values = items;
|
||||
results.count = items.size();
|
||||
} else {
|
||||
Map<RaceListDataTypeTitle, List<RaceListDataTypeElement>> elementMap
|
||||
= new TreeMap<RaceListDataTypeTitle, List<RaceListDataTypeElement>>(new RaceListDataTypeTitleComparator());
|
||||
RaceListDataTypeTitle currentTitle = null;
|
||||
|
||||
for (RaceListDataType element : originalItems) {
|
||||
if (element instanceof RaceListDataTypeTitle) {
|
||||
currentTitle = (RaceListDataTypeTitle) element;
|
||||
elementMap.put(currentTitle, new ArrayList<RaceListDataTypeElement>());
|
||||
} else if (element instanceof RaceListDataTypeElement) {
|
||||
RaceListDataTypeElement listElement = (RaceListDataTypeElement) element;
|
||||
if (elementMap.containsKey(currentTitle)) {
|
||||
elementMap.get(currentTitle).add(listElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (RaceListDataTypeTitle title : elementMap.keySet()) {
|
||||
dataTypeList.add(title);
|
||||
List<RaceListDataTypeElement> elementList = elementMap.get(title);
|
||||
Collections.sort(elementList, new RaceListDataTypeElementComparator());
|
||||
RaceListDataTypeElement lastFinishedRace = null;
|
||||
int numberOfUnscheduledRaces = 0;
|
||||
|
||||
/// TODO: new status FINISHING?!?!?!
|
||||
for (RaceListDataTypeElement dataElement : elementList) {
|
||||
if (dataElement.getRace().getStatus().equals(RaceLogRaceStatus.FINISHED)) {
|
||||
lastFinishedRace = dataElement;
|
||||
}
|
||||
}
|
||||
|
||||
for (RaceListDataTypeElement dataElement : elementList) {
|
||||
if (dataElement.getRace().getStatus().equals(RaceLogRaceStatus.UNSCHEDULED)) {
|
||||
numberOfUnscheduledRaces++;
|
||||
if (numberOfUnscheduledRaces > 1)
|
||||
continue;
|
||||
} else if (dataElement.getRace().getStatus().equals(RaceLogRaceStatus.FINISHED)) {
|
||||
if (!dataElement.equals(lastFinishedRace)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
dataTypeList.add(dataElement);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
results.values = dataTypeList;
|
||||
results.count = dataTypeList.size();
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void publishResults(CharSequence constraint, FilterResults results) {
|
||||
synchronized(mLock) {
|
||||
items = (List<RaceListDataType>) results.values;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
package com.sap.sailing.racecommittee.app.ui.adapters.racelist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Filter;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
||||
import com.sap.sailing.racecommittee.app.R;
|
||||
import com.sap.sailing.racecommittee.app.ui.comparators.RaceListDataTypeElementComparator;
|
||||
import com.sap.sailing.racecommittee.app.ui.comparators.RaceListDataTypeTitleComparator;
|
||||
|
||||
public class RaceListAdapter extends ArrayAdapter<RaceListDataType> {
|
||||
|
||||
public interface JuryFlagClickedListener {
|
||||
public void onJuryFlagClicked(BoatClassSeriesDataFleet clickedItem);
|
||||
}
|
||||
|
||||
public static final int VIEW_TYPE_COUNT = 2;
|
||||
public static final int VIEW_BOAT_GROUP = 0;
|
||||
public static final int VIEW_RACE = 1;
|
||||
|
||||
private LayoutInflater mInflater;
|
||||
private JuryFlagClickedListener juryListener;
|
||||
private RaceFilter filter;
|
||||
private final Object mLock = new Object();
|
||||
|
||||
private List<RaceListDataType> items;
|
||||
private List<RaceListDataType> originalItems;
|
||||
|
||||
public RaceListAdapter(Context context, int textViewResourceId,
|
||||
List<RaceListDataType> objects, JuryFlagClickedListener juryListener) {
|
||||
super(context, textViewResourceId, objects);
|
||||
this.items = objects;
|
||||
this.originalItems = new ArrayList<RaceListDataType>();
|
||||
|
||||
this.juryListener = juryListener;
|
||||
mInflater = (LayoutInflater) (getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
synchronized(mLock) {
|
||||
return items!=null ? items.size() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceListDataType getItem(int position) {
|
||||
RaceListDataType element = null;
|
||||
synchronized(mLock) {
|
||||
element = items!=null ? items.get(position) : null;
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return (getItem(position) instanceof RaceListDataTypeTitle ? VIEW_BOAT_GROUP
|
||||
: VIEW_RACE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
return VIEW_TYPE_COUNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int position) {
|
||||
return (getItem(position) instanceof RaceListDataTypeElement);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
RaceListDataType raceListElement = null;
|
||||
|
||||
raceListElement = getItem(position);
|
||||
|
||||
ViewHolder holder = null;
|
||||
int type = getItemViewType(position);
|
||||
|
||||
if (convertView == null) {
|
||||
holder = new ViewHolder();
|
||||
if (type == VIEW_BOAT_GROUP) {
|
||||
convertView = mInflater.inflate(R.layout.welter_one_row_no_image_label, null);
|
||||
holder.line1 = (TextView) convertView.findViewById(R.id.Welter_Cell_OneRowNoImageLabel_txtTitle);
|
||||
holder.button1 = (ImageButton) convertView.findViewById(R.id.Welter_Cell_OneRowNoImageLabel_btnJury);
|
||||
} else if (type == VIEW_RACE) {
|
||||
convertView = mInflater.inflate(R.layout.welter_two_row_no_image, null);
|
||||
holder.line1 = (TextView) convertView.findViewById(R.id.Welter_Cell_TwoRowNoImage_lineOne);
|
||||
holder.line2 = (TextView) convertView.findViewById(R.id.Welter_Cell_TwoRowNoImage_lineTwo);
|
||||
holder.updateLabel = (ImageView) convertView.findViewById(R.id.Welter_Cell_UpdateLabel);
|
||||
}
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
if (type == VIEW_BOAT_GROUP) {
|
||||
final RaceListDataTypeTitle title = (RaceListDataTypeTitle) raceListElement;
|
||||
holder.line1.setText(title.toString());
|
||||
holder.button1.setOnClickListener(new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
juryListener.onJuryFlagClicked(title.getBoatClassSeriesDataFleet());
|
||||
}
|
||||
});
|
||||
} else if (type == VIEW_RACE) {
|
||||
RaceListDataTypeElement element = (RaceListDataTypeElement) raceListElement;
|
||||
holder.line1.setText(element.getRaceName());
|
||||
holder.line2.setText(element.getStatus());
|
||||
|
||||
if (element.isUpdateIndicatorVisible()) {
|
||||
holder.updateLabel.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter getFilter() {
|
||||
if (filter == null) {
|
||||
filter = new RaceFilter();
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
public List<RaceListDataType> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
static class ViewHolder {
|
||||
TextView line1, line2;
|
||||
ImageButton button1;
|
||||
ImageView updateLabel;
|
||||
}
|
||||
|
||||
private class RaceFilter extends Filter {
|
||||
|
||||
@Override
|
||||
protected FilterResults performFiltering(CharSequence constraint) {
|
||||
// Initiate our results object
|
||||
FilterResults results = new FilterResults();
|
||||
List<RaceListDataType> dataTypeList = new ArrayList<RaceListDataType>();
|
||||
|
||||
if (originalItems.isEmpty()) {
|
||||
originalItems = new ArrayList<RaceListDataType>(items.size());
|
||||
for (RaceListDataType type : items) {
|
||||
originalItems.add(type);
|
||||
}
|
||||
}
|
||||
|
||||
if (originalItems.isEmpty()) {
|
||||
results.values = items;
|
||||
results.count = items.size();
|
||||
} else {
|
||||
Map<RaceListDataTypeTitle, List<RaceListDataTypeElement>> elementMap
|
||||
= new TreeMap<RaceListDataTypeTitle, List<RaceListDataTypeElement>>(new RaceListDataTypeTitleComparator());
|
||||
RaceListDataTypeTitle currentTitle = null;
|
||||
|
||||
for (RaceListDataType element : originalItems) {
|
||||
if (element instanceof RaceListDataTypeTitle) {
|
||||
currentTitle = (RaceListDataTypeTitle) element;
|
||||
elementMap.put(currentTitle, new ArrayList<RaceListDataTypeElement>());
|
||||
} else if (element instanceof RaceListDataTypeElement) {
|
||||
RaceListDataTypeElement listElement = (RaceListDataTypeElement) element;
|
||||
if (elementMap.containsKey(currentTitle)) {
|
||||
elementMap.get(currentTitle).add(listElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (RaceListDataTypeTitle title : elementMap.keySet()) {
|
||||
dataTypeList.add(title);
|
||||
List<RaceListDataTypeElement> elementList = elementMap.get(title);
|
||||
Collections.sort(elementList, new RaceListDataTypeElementComparator());
|
||||
RaceListDataTypeElement lastFinishedRace = null;
|
||||
int numberOfUnscheduledRaces = 0;
|
||||
|
||||
for (RaceListDataTypeElement dataElement : elementList) {
|
||||
if (dataElement.getRace().getStatus().equals(RaceLogRaceStatus.FINISHED)) {
|
||||
lastFinishedRace = dataElement;
|
||||
}
|
||||
}
|
||||
|
||||
for (RaceListDataTypeElement dataElement : elementList) {
|
||||
if (dataElement.getRace().getStatus().equals(RaceLogRaceStatus.UNSCHEDULED)) {
|
||||
numberOfUnscheduledRaces++;
|
||||
if (numberOfUnscheduledRaces > 1)
|
||||
continue;
|
||||
} else if (dataElement.getRace().getStatus().equals(RaceLogRaceStatus.FINISHED)) {
|
||||
if (!dataElement.equals(lastFinishedRace)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
dataTypeList.add(dataElement);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
results.values = dataTypeList;
|
||||
results.count = dataTypeList.size();
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void publishResults(CharSequence constraint, FilterResults results) {
|
||||
synchronized(mLock) {
|
||||
items = (List<RaceListDataType>) results.values;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+114
-111
@@ -1,111 +1,114 @@
|
||||
package com.sap.sailing.racecommittee.app.ui.adapters.racelist;
|
||||
|
||||
import java.text.Format;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
import android.app.Fragment;
|
||||
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
||||
import com.sap.sailing.racecommittee.app.R;
|
||||
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
||||
|
||||
public class RaceListDataTypeElement extends RaceListDataType {
|
||||
|
||||
private boolean updateIndicatorVisible = false;
|
||||
|
||||
private ManagedRace race;
|
||||
private RaceLogRaceStatus currentRaceStatus;
|
||||
|
||||
private static String unscheduledTemplate;
|
||||
private static String scheduldedTemplate;
|
||||
private static String startPhaseTemplate;
|
||||
private static String runningTemplate;
|
||||
private static String finishedTemplate;
|
||||
private static String unknownTemplate;
|
||||
|
||||
private Format scheduleFormatter = new SimpleDateFormat("HH:mm", Locale.US);
|
||||
|
||||
public static void initializeTemplates(Fragment fragment) {
|
||||
unscheduledTemplate = fragment.getString(R.string.racelist_unscheduled);
|
||||
scheduldedTemplate = fragment.getString(R.string.racelist_scheduled);
|
||||
startPhaseTemplate = fragment.getString(R.string.racelist_startphase);
|
||||
runningTemplate = fragment.getString(R.string.racelist_running);
|
||||
finishedTemplate = fragment.getString(R.string.racelist_finished);
|
||||
unknownTemplate = fragment.getString(R.string.racelist_unknown);
|
||||
}
|
||||
|
||||
public RaceListDataTypeElement(ManagedRace race) {
|
||||
setRace(race);
|
||||
}
|
||||
|
||||
public ManagedRace getRace() {
|
||||
return race;
|
||||
}
|
||||
|
||||
public void setRace(ManagedRace race) {
|
||||
this.race = race;
|
||||
this.currentRaceStatus = race.getStatus();
|
||||
}
|
||||
|
||||
public void setUpdateIndicator(boolean visible) {
|
||||
this.updateIndicatorVisible = visible;
|
||||
}
|
||||
|
||||
public boolean isUpdateIndicatorVisible() {
|
||||
return updateIndicatorVisible;
|
||||
}
|
||||
|
||||
public String getRaceName() {
|
||||
if (race == null) {
|
||||
return "Invalid race";
|
||||
}
|
||||
|
||||
return race.getName();
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
if (race == null) {
|
||||
return "Invalid race";
|
||||
}
|
||||
|
||||
return getStatusString(race.getStatus());
|
||||
}
|
||||
|
||||
public RaceLogRaceStatus getPreviousRaceStatus() {
|
||||
return currentRaceStatus;
|
||||
}
|
||||
|
||||
public void setPreviousRaceStatus(RaceLogRaceStatus status) {
|
||||
this.currentRaceStatus = status;
|
||||
}
|
||||
|
||||
private String getStatusString(RaceLogRaceStatus status) {
|
||||
switch (status) {
|
||||
case UNSCHEDULED:
|
||||
return unscheduledTemplate;
|
||||
case SCHEDULED:
|
||||
return String.format(scheduldedTemplate, formatStartTime());
|
||||
case STARTPHASE:
|
||||
return String.format(startPhaseTemplate, formatStartTime());
|
||||
case RUNNING:
|
||||
case FINISHING:
|
||||
return String.format(runningTemplate, formatStartTime());
|
||||
case FINISHED:
|
||||
return finishedTemplate;
|
||||
default:
|
||||
return unknownTemplate;
|
||||
}
|
||||
}
|
||||
|
||||
private String formatStartTime() {
|
||||
TimePoint startTime = race.getState().getStartTime();
|
||||
if (startTime == null)
|
||||
{
|
||||
return unknownTemplate;
|
||||
}
|
||||
return scheduleFormatter.format(startTime.asDate());
|
||||
}
|
||||
|
||||
}
|
||||
package com.sap.sailing.racecommittee.app.ui.adapters.racelist;
|
||||
|
||||
import java.text.Format;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
import android.app.Fragment;
|
||||
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
||||
import com.sap.sailing.racecommittee.app.R;
|
||||
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
||||
|
||||
public class RaceListDataTypeElement extends RaceListDataType {
|
||||
|
||||
private boolean updateIndicatorVisible = false;
|
||||
|
||||
private ManagedRace race;
|
||||
private RaceLogRaceStatus currentRaceStatus;
|
||||
|
||||
private static String unscheduledTemplate;
|
||||
private static String scheduldedTemplate;
|
||||
private static String startPhaseTemplate;
|
||||
private static String runningTemplate;
|
||||
private static String finishingTemplate;
|
||||
private static String finishedTemplate;
|
||||
private static String unknownTemplate;
|
||||
|
||||
private Format scheduleFormatter = new SimpleDateFormat("HH:mm", Locale.US);
|
||||
|
||||
public static void initializeTemplates(Fragment fragment) {
|
||||
unscheduledTemplate = fragment.getString(R.string.racelist_unscheduled);
|
||||
scheduldedTemplate = fragment.getString(R.string.racelist_scheduled);
|
||||
startPhaseTemplate = fragment.getString(R.string.racelist_startphase);
|
||||
runningTemplate = fragment.getString(R.string.racelist_running);
|
||||
finishingTemplate = fragment.getString(R.string.racelist_finishing);
|
||||
finishedTemplate = fragment.getString(R.string.racelist_finished);
|
||||
unknownTemplate = fragment.getString(R.string.racelist_unknown);
|
||||
}
|
||||
|
||||
public RaceListDataTypeElement(ManagedRace race) {
|
||||
setRace(race);
|
||||
}
|
||||
|
||||
public ManagedRace getRace() {
|
||||
return race;
|
||||
}
|
||||
|
||||
public void setRace(ManagedRace race) {
|
||||
this.race = race;
|
||||
this.currentRaceStatus = race.getStatus();
|
||||
}
|
||||
|
||||
public void setUpdateIndicator(boolean visible) {
|
||||
this.updateIndicatorVisible = visible;
|
||||
}
|
||||
|
||||
public boolean isUpdateIndicatorVisible() {
|
||||
return updateIndicatorVisible;
|
||||
}
|
||||
|
||||
public String getRaceName() {
|
||||
if (race == null) {
|
||||
return "Invalid race";
|
||||
}
|
||||
|
||||
return race.getName();
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
if (race == null) {
|
||||
return "Invalid race";
|
||||
}
|
||||
|
||||
return getStatusString(race.getStatus());
|
||||
}
|
||||
|
||||
public RaceLogRaceStatus getPreviousRaceStatus() {
|
||||
return currentRaceStatus;
|
||||
}
|
||||
|
||||
public void setPreviousRaceStatus(RaceLogRaceStatus status) {
|
||||
this.currentRaceStatus = status;
|
||||
}
|
||||
|
||||
private String getStatusString(RaceLogRaceStatus status) {
|
||||
switch (status) {
|
||||
case UNSCHEDULED:
|
||||
return unscheduledTemplate;
|
||||
case SCHEDULED:
|
||||
return String.format(scheduldedTemplate, formatStartTime());
|
||||
case STARTPHASE:
|
||||
return String.format(startPhaseTemplate, formatStartTime());
|
||||
case RUNNING:
|
||||
return String.format(runningTemplate, formatStartTime());
|
||||
case FINISHING:
|
||||
return finishingTemplate;
|
||||
case FINISHED:
|
||||
return finishedTemplate;
|
||||
default:
|
||||
return unknownTemplate;
|
||||
}
|
||||
}
|
||||
|
||||
private String formatStartTime() {
|
||||
TimePoint startTime = race.getState().getStartTime();
|
||||
if (startTime == null)
|
||||
{
|
||||
return unknownTemplate;
|
||||
}
|
||||
return scheduleFormatter.format(startTime.asDate());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user