mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-12 05:35:31 +00:00
Improved NewMediaDialog control flow
This commit is contained in:
1 parent
2286151aea
commit
5f9d7da2b9
1 file changed
+146
-115
+146
-115
@@ -54,14 +54,33 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> implements FileS
|
||||
|
||||
private static final boolean DONT_FIRE_EVENTS = false;
|
||||
|
||||
private static final Validator<MediaTrack> MEDIA_TRACK_VALIDATOR = new Validator<MediaTrack>() {
|
||||
protected static class MediaTrackValidator implements Validator<MediaTrack> {
|
||||
private final StringMessages stringMessages;
|
||||
|
||||
@Override
|
||||
public String getErrorMessage(MediaTrack valueToValidate) {
|
||||
return null;
|
||||
public MediaTrackValidator(StringMessages stringMessages) {
|
||||
this.stringMessages = stringMessages;
|
||||
}
|
||||
|
||||
};
|
||||
@Override
|
||||
public String getErrorMessage(MediaTrack media) {
|
||||
String errorMessage = null;
|
||||
|
||||
if (media.url == null || media.url.trim().isEmpty()) {
|
||||
errorMessage = stringMessages.pleaseEnterNonEmptyUrl();
|
||||
} else if (media.title == null || media.title.trim().isEmpty()) {
|
||||
errorMessage = stringMessages.pleaseEnterA(stringMessages.title());
|
||||
} else if (media.mimeType == null) {
|
||||
errorMessage = stringMessages.pleaseEnterA(stringMessages.mimeType());
|
||||
} else if (media.startTime == null) {
|
||||
errorMessage = stringMessages.pleaseEnterA(stringMessages.startTime());
|
||||
} else if (media.duration == null) {
|
||||
errorMessage = stringMessages.pleaseEnterA(stringMessages.duration());
|
||||
}
|
||||
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected final StringMessages stringMessages;
|
||||
|
||||
@@ -82,6 +101,7 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> implements FileS
|
||||
private Label infoLabelLabel;
|
||||
|
||||
final private RegattaAndRaceIdentifier raceIdentifier;
|
||||
final private Set<RegattaAndRaceIdentifier> assignedRaces;
|
||||
|
||||
final private MediaServiceAsync mediaService;
|
||||
|
||||
@@ -91,33 +111,144 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> implements FileS
|
||||
private Button defaultTimeButton;
|
||||
|
||||
private SimpleBusyIndicator busyIndicator;
|
||||
boolean manuallyEditedStartTime = false;
|
||||
|
||||
private String lastCheckedUrl;
|
||||
|
||||
private boolean manuallyEditedStartTime = false;
|
||||
|
||||
public NewMediaDialog(MediaServiceAsync mediaService, TimePoint defaultStartTime, StringMessages stringMessages,
|
||||
RegattaAndRaceIdentifier raceIdentifier, FileStorageServiceConnectionTestObservable storageServiceConnection,
|
||||
DialogCallback<MediaTrack> dialogCallback) {
|
||||
super(stringMessages.addMediaTrack(), "", stringMessages.ok(), stringMessages.cancel(), MEDIA_TRACK_VALIDATOR,
|
||||
dialogCallback);
|
||||
super(stringMessages.addMediaTrack(), "", stringMessages.ok(), stringMessages.cancel(),
|
||||
new MediaTrackValidator(stringMessages), dialogCallback);
|
||||
this.defaultStartTime = defaultStartTime != null ? defaultStartTime : MillisecondsTimePoint.now();
|
||||
this.stringMessages = stringMessages;
|
||||
this.raceIdentifier = raceIdentifier;
|
||||
this.assignedRaces = new HashSet<RegattaAndRaceIdentifier>();
|
||||
this.assignedRaces.add(raceIdentifier);
|
||||
this.mediaService = mediaService;
|
||||
|
||||
urlBox = new URLFieldWithFileUpload(stringMessages, false);
|
||||
urlBox.addValueChangeHandler(new ValueChangeHandler<String>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<String> event) {
|
||||
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
|
||||
@Override
|
||||
public void execute() {
|
||||
validateAndUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
titleBox = createTextBox(null);
|
||||
titleBox.addValueChangeHandler(new ValueChangeHandler<String>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<String> event) {
|
||||
validateAndUpdate();
|
||||
}
|
||||
});
|
||||
startTimeBox = new DateAndTimeInput(Accuracy.MILLISECONDS);
|
||||
startTimeBox.addValueChangeHandler(new ValueChangeHandler<Date>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<Date> event) {
|
||||
manuallyEditedStartTime = true;
|
||||
mediaTrack.startTime = new MillisecondsTimePoint(event.getValue());
|
||||
validateAndUpdate();
|
||||
}
|
||||
});
|
||||
defaultTimeButton = new Button(StringMessages.INSTANCE.resetStartTimeToDefault());
|
||||
defaultTimeButton.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
manuallyEditedStartTime = true;
|
||||
mediaTrack.startTime = defaultStartTime;
|
||||
refreshUI();
|
||||
validateAndUpdate();
|
||||
}
|
||||
});
|
||||
durationBox = createTextBox(null);
|
||||
durationBox.addValueChangeHandler(new ValueChangeHandler<String>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<String> event) {
|
||||
String duration = durationBox.getValue();
|
||||
if (duration != null && !duration.trim().isEmpty()) {
|
||||
mediaTrack.duration = TimeFormatUtil.hrsMinSecToMilliSeconds(duration);
|
||||
} else {
|
||||
mediaTrack.duration = null;
|
||||
}
|
||||
validateAndUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
storageServiceConnection.registerObserver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MediaTrack getResult() {
|
||||
mediaTrack.title = titleBox.getValue();
|
||||
updateFromUrl();
|
||||
connectMediaWithRace();
|
||||
return mediaTrack;
|
||||
}
|
||||
|
||||
|
||||
protected void connectMediaWithRace() {
|
||||
Set<RegattaAndRaceIdentifier> assignedRaces = new HashSet<RegattaAndRaceIdentifier>();
|
||||
assignedRaces.add(this.raceIdentifier);
|
||||
mediaTrack.assignedRaces = assignedRaces;
|
||||
}
|
||||
|
||||
protected void updateFromUrl() {
|
||||
String url = urlBox.getValue();
|
||||
if (url != null && !url.isEmpty()) {
|
||||
boolean urlChanged = !url.equals(lastCheckedUrl);
|
||||
lastCheckedUrl = url;
|
||||
if (urlChanged) {
|
||||
remoteMp4WasStarted = false;
|
||||
remoteMp4WasFinished = false;
|
||||
manuallyEditedStartTime = false;
|
||||
|
||||
String youtubeId = YoutubeApi.getIdByUrl(url);
|
||||
if (youtubeId != null) {
|
||||
mediaTrack.url = youtubeId;
|
||||
mediaTrack.mimeType = MimeType.youtube;
|
||||
mediaService.checkYoutubeMetadata(youtubeId, new AsyncCallback<VideoMetadataDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
infoLabel.setWidget(new Label(caught.getMessage()));
|
||||
}
|
||||
@Override
|
||||
public void onSuccess(VideoMetadataDTO result) {
|
||||
if (result.isDownloadable()) {
|
||||
mediaTrack.duration = result.getDuration();
|
||||
mediaTrack.title = result.getMessage();
|
||||
refreshUI();
|
||||
} else {
|
||||
infoLabel.setWidget(new Label(result.getMessage()));
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
mediaTrack.url = url;
|
||||
loadMediaDuration();
|
||||
AnchorElement anchor = Document.get().createAnchorElement();
|
||||
anchor.setHref(url);
|
||||
//remove trailing / as well
|
||||
String lastPathSegment = anchor.getPropertyString("pathname").substring(1);
|
||||
int dotPos = lastPathSegment.lastIndexOf('.');
|
||||
if (dotPos >= 0) {
|
||||
mediaTrack.title = lastPathSegment.substring(0, dotPos);
|
||||
String fileEnding = lastPathSegment.substring(dotPos + 1).toLowerCase();
|
||||
mediaTrack.mimeType = MimeType.byName(fileEnding);
|
||||
if (MimeType.mp4.equals(mediaTrack.mimeType)) {
|
||||
processMp4(mediaTrack);
|
||||
}
|
||||
} else {
|
||||
mediaTrack.title = mediaTrack.url;
|
||||
mediaTrack.mimeType = null;
|
||||
}
|
||||
}
|
||||
refreshUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//used for audio only tracks, using native mediaelement to determine time
|
||||
private void loadMediaDuration() {
|
||||
MediaBase mediaBase = Audio.createIfSupported();
|
||||
@@ -156,65 +287,23 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> implements FileS
|
||||
Grid formGrid = new Grid(6, 2);
|
||||
formGrid.setCellSpacing(3);
|
||||
formGrid.setWidget(0, 0, new Label(stringMessages.url() + ":"));
|
||||
urlBox = new URLFieldWithFileUpload(stringMessages, false);
|
||||
urlBox.addValueChangeHandler(new ValueChangeHandler<String>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<String> event) {
|
||||
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
|
||||
@Override
|
||||
public void execute() {
|
||||
manuallyEditedStartTime = false;
|
||||
updateFromUrl();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
formGrid.setWidget(0, 1, urlBox);
|
||||
formGrid.setWidget(1, 0, new Label(stringMessages.name() + ":"));
|
||||
titleBox = createTextBox(null);
|
||||
formGrid.setWidget(1, 1, titleBox);
|
||||
|
||||
infoLabelLabel = new Label();
|
||||
formGrid.setWidget(2, 0, infoLabelLabel);
|
||||
infoLabel = new SimplePanel();
|
||||
infoLabel.setWidget(new Label(""));
|
||||
formGrid.setWidget(2, 1, infoLabel);
|
||||
formGrid.setWidget(3, 0, new Label(stringMessages.startTime() + ":"));
|
||||
|
||||
startTimeBox = new DateAndTimeInput(Accuracy.MILLISECONDS);
|
||||
|
||||
FlowPanel startTimePanel = new FlowPanel();
|
||||
startTimePanel.add(startTimeBox);
|
||||
startTimeBox.addValueChangeHandler(new ValueChangeHandler<Date>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<Date> event) {
|
||||
manuallyEditedStartTime = true;
|
||||
mediaTrack.startTime = new MillisecondsTimePoint(event.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
defaultTimeButton = new Button(StringMessages.INSTANCE.resetStartTimeToDefault());
|
||||
defaultTimeButton.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
manuallyEditedStartTime = true;
|
||||
mediaTrack.startTime = defaultStartTime;
|
||||
refreshUI();
|
||||
}
|
||||
});
|
||||
startTimePanel.add(defaultTimeButton);
|
||||
formGrid.setWidget(3, 1, startTimePanel);
|
||||
|
||||
formGrid.setWidget(4, 0, new Label(stringMessages.duration() + ":"));
|
||||
durationBox = createTextBox(null);
|
||||
durationBox.addValueChangeHandler(new ValueChangeHandler<String>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<String> event) {
|
||||
String duration = durationBox.getValue();
|
||||
if (duration != null && !duration.trim().isEmpty()) {
|
||||
mediaTrack.duration = TimeFormatUtil.hrsMinSecToMilliSeconds(duration);
|
||||
} else {
|
||||
mediaTrack.duration = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
formGrid.setWidget(4, 1, durationBox);
|
||||
busyIndicator = new SimpleBusyIndicator();
|
||||
formGrid.setWidget(5, 0, busyIndicator);
|
||||
@@ -222,63 +311,6 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> implements FileS
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
protected void updateFromUrl() {
|
||||
String url = urlBox.getValue();
|
||||
String youtubeId = YoutubeApi.getIdByUrl(url);
|
||||
if (youtubeId != null) {
|
||||
mediaTrack.url = youtubeId;
|
||||
mediaTrack.mimeType = MimeType.youtube;
|
||||
loadYoutubeMetadata();
|
||||
} else {
|
||||
mediaTrack.url = url;
|
||||
loadMediaDuration();
|
||||
AnchorElement anchor = Document.get().createAnchorElement();
|
||||
anchor.setHref(url);
|
||||
//remove trailing / as well
|
||||
String lastPathSegment = anchor.getPropertyString("pathname").substring(1);
|
||||
int dotPos = lastPathSegment.lastIndexOf('.');
|
||||
if (dotPos >= 0) {
|
||||
mediaTrack.title = lastPathSegment.substring(0, dotPos);
|
||||
String fileEnding = lastPathSegment.substring(dotPos + 1).toLowerCase();
|
||||
mediaTrack.mimeType = MimeType.byName(fileEnding);
|
||||
} else {
|
||||
mediaTrack.title = mediaTrack.url;
|
||||
mediaTrack.mimeType = null;
|
||||
}
|
||||
}
|
||||
remoteMp4WasStarted = false;
|
||||
remoteMp4WasFinished = false;
|
||||
refreshUI();
|
||||
if (!remoteMp4WasStarted && MimeType.mp4.equals(mediaTrack.mimeType)) {
|
||||
processMp4(mediaTrack);
|
||||
} else {
|
||||
loadMediaDuration();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadYoutubeMetadata() {
|
||||
if(mediaTrack.url != null && !mediaTrack.url.isEmpty()) {
|
||||
mediaService.checkYoutubeMetadata(mediaTrack.url, new AsyncCallback<VideoMetadataDTO>() {
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
infoLabel.setWidget(new Label(caught.getMessage()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(VideoMetadataDTO result) {
|
||||
if (result.isDownloadable()) {
|
||||
mediaTrack.duration = result.getDuration();
|
||||
mediaTrack.title = result.getMessage();
|
||||
refreshUI();
|
||||
} else {
|
||||
infoLabel.setWidget(new Label(result.getMessage()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private String sliceBefore(String lastPathSegment, String slicer) {
|
||||
int paramSegment = lastPathSegment.indexOf(slicer);
|
||||
if (paramSegment > 0) {
|
||||
@@ -343,7 +375,6 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> implements FileS
|
||||
busyIndicator.setBusy(false);
|
||||
remoteMp4WasFinished = true;
|
||||
manualMimeTypeSelection(caught.getMessage(), mediaTrack);
|
||||
loadMediaDuration();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user