Improve UI features for time limited recordings
This commit is contained in:
parent
8fe48f91b7
commit
97715aecc5
|
@ -22,13 +22,15 @@ import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.beans.property.SimpleIntegerProperty;
|
import javafx.beans.property.SimpleIntegerProperty;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
|
import javafx.beans.property.StringProperty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just a wrapper for Model, which augments it with JavaFX value binding properties, so that UI widgets get updated proeprly
|
* Just a wrapper for Model, which augments it with JavaFX value binding properties, so that UI widgets get updated proeprly
|
||||||
*/
|
*/
|
||||||
public class JavaFxModel implements Model {
|
public class JavaFxModel implements Model {
|
||||||
private transient BooleanProperty onlineProperty = new SimpleBooleanProperty();
|
private transient StringProperty onlineProperty = new SimpleStringProperty();
|
||||||
private transient BooleanProperty recordingProperty = new SimpleBooleanProperty();
|
private transient StringProperty recordingProperty = new SimpleStringProperty();
|
||||||
private transient BooleanProperty pausedProperty = new SimpleBooleanProperty();
|
private transient BooleanProperty pausedProperty = new SimpleBooleanProperty();
|
||||||
private transient SimpleIntegerProperty priorityProperty = new SimpleIntegerProperty();
|
private transient SimpleIntegerProperty priorityProperty = new SimpleIntegerProperty();
|
||||||
private transient SimpleObjectProperty<Instant> lastSeenProperty = new SimpleObjectProperty<>();
|
private transient SimpleObjectProperty<Instant> lastSeenProperty = new SimpleObjectProperty<>();
|
||||||
|
@ -103,11 +105,11 @@ public class JavaFxModel implements Model {
|
||||||
return delegate.toString();
|
return delegate.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BooleanProperty getOnlineProperty() {
|
public StringProperty getOnlineProperty() {
|
||||||
return onlineProperty;
|
return onlineProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BooleanProperty getRecordingProperty() {
|
public StringProperty getRecordingProperty() {
|
||||||
return recordingProperty;
|
return recordingProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,4 +314,9 @@ public class JavaFxModel implements Model {
|
||||||
public boolean exists() throws IOException {
|
public boolean exists() throws IOException {
|
||||||
return delegate.exists();
|
return delegate.exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRecordingTimeLimited() {
|
||||||
|
return delegate.isRecordingTimeLimited();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package ctbrec.ui;
|
||||||
|
|
||||||
|
public class UnicodeEmoji {
|
||||||
|
|
||||||
|
public static final String HEAVY_CHECK_MARK = "✔";
|
||||||
|
public static final String CLOCK = "🕒";
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package ctbrec.ui.action;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import ctbrec.Model;
|
||||||
|
import ctbrec.recorder.Recorder;
|
||||||
|
import ctbrec.ui.controls.Dialogs;
|
||||||
|
import javafx.scene.Cursor;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
|
||||||
|
public class RemoveTimeLimitAction {
|
||||||
|
|
||||||
|
private Model selectedModel;
|
||||||
|
private Node source;
|
||||||
|
private Recorder recorder;
|
||||||
|
|
||||||
|
public RemoveTimeLimitAction(Node source, Model selectedModel, Recorder recorder) {
|
||||||
|
this.source = source;
|
||||||
|
this.selectedModel = selectedModel;
|
||||||
|
this.recorder = recorder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Boolean> execute() {
|
||||||
|
source.setCursor(Cursor.WAIT);
|
||||||
|
Instant unlimited = Instant.ofEpochMilli(Model.RECORD_INDEFINITELY);
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
try {
|
||||||
|
selectedModel.setRecordUntil(unlimited);
|
||||||
|
recorder.stopRecordingAt(selectedModel);
|
||||||
|
return true;
|
||||||
|
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) {
|
||||||
|
Dialogs.showError(source.getScene(), "Error", "Couln't remove stop date", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}).whenComplete((r,e) -> source.setCursor(Cursor.DEFAULT));
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package ctbrec.ui.tabs;
|
||||||
|
|
||||||
import static ctbrec.Recording.State.*;
|
import static ctbrec.Recording.State.*;
|
||||||
import static ctbrec.SubsequentAction.*;
|
import static ctbrec.SubsequentAction.*;
|
||||||
|
import static ctbrec.ui.UnicodeEmoji.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
|
@ -9,6 +10,9 @@ import java.security.NoSuchAlgorithmException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.FormatStyle;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -44,6 +48,7 @@ import ctbrec.ui.action.FollowAction;
|
||||||
import ctbrec.ui.action.OpenRecordingsDir;
|
import ctbrec.ui.action.OpenRecordingsDir;
|
||||||
import ctbrec.ui.action.PauseAction;
|
import ctbrec.ui.action.PauseAction;
|
||||||
import ctbrec.ui.action.PlayAction;
|
import ctbrec.ui.action.PlayAction;
|
||||||
|
import ctbrec.ui.action.RemoveTimeLimitAction;
|
||||||
import ctbrec.ui.action.ResumeAction;
|
import ctbrec.ui.action.ResumeAction;
|
||||||
import ctbrec.ui.action.StopRecordingAction;
|
import ctbrec.ui.action.StopRecordingAction;
|
||||||
import ctbrec.ui.action.ToggleRecordingAction;
|
import ctbrec.ui.action.ToggleRecordingAction;
|
||||||
|
@ -107,6 +112,8 @@ import javafx.util.converter.NumberStringConverter;
|
||||||
public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(RecordedModelsTab.class);
|
private static final Logger LOG = LoggerFactory.getLogger(RecordedModelsTab.class);
|
||||||
|
|
||||||
|
private static final String STYLE_ALIGN_CENTER = "-fx-alignment: CENTER;";
|
||||||
|
|
||||||
private ReentrantLock lock = new ReentrantLock();
|
private ReentrantLock lock = new ReentrantLock();
|
||||||
private ScheduledService<List<JavaFxModel>> updateService;
|
private ScheduledService<List<JavaFxModel>> updateService;
|
||||||
private Recorder recorder;
|
private Recorder recorder;
|
||||||
|
@ -168,28 +175,29 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
}
|
}
|
||||||
TableColumn<JavaFxModel, String> name = new TableColumn<>("Model");
|
TableColumn<JavaFxModel, String> name = new TableColumn<>("Model");
|
||||||
name.setPrefWidth(200);
|
name.setPrefWidth(200);
|
||||||
name.setCellValueFactory(new PropertyValueFactory<JavaFxModel, String>("displayName"));
|
name.setCellValueFactory(new PropertyValueFactory<>("displayName"));
|
||||||
name.setCellFactory(new ClickableCellFactory<>());
|
name.setCellFactory(new ClickableCellFactory<>());
|
||||||
name.setEditable(false);
|
name.setEditable(false);
|
||||||
name.setId("name");
|
name.setId("name");
|
||||||
TableColumn<JavaFxModel, String> url = new TableColumn<>("URL");
|
TableColumn<JavaFxModel, String> url = new TableColumn<>("URL");
|
||||||
url.setCellValueFactory(new PropertyValueFactory<JavaFxModel, String>("url"));
|
url.setCellValueFactory(new PropertyValueFactory<>("url"));
|
||||||
url.setCellFactory(new ClickableCellFactory<>());
|
url.setCellFactory(new ClickableCellFactory<>());
|
||||||
url.setPrefWidth(400);
|
url.setPrefWidth(400);
|
||||||
url.setEditable(false);
|
url.setEditable(false);
|
||||||
url.setId("url");
|
url.setId("url");
|
||||||
TableColumn<JavaFxModel, Boolean> online = new TableColumn<>("Online");
|
TableColumn<JavaFxModel, String> online = new TableColumn<>("Online");
|
||||||
online.setCellValueFactory(cdf -> cdf.getValue().getOnlineProperty());
|
online.setCellValueFactory(cdf -> cdf.getValue().getOnlineProperty());
|
||||||
online.setCellFactory(CheckBoxTableCell.forTableColumn(online));
|
|
||||||
online.setPrefWidth(100);
|
online.setPrefWidth(100);
|
||||||
online.setEditable(false);
|
online.setEditable(false);
|
||||||
online.setId("online");
|
online.setId("online");
|
||||||
TableColumn<JavaFxModel, Boolean> recording = new TableColumn<>("Recording");
|
online.setStyle(STYLE_ALIGN_CENTER);
|
||||||
|
TableColumn<JavaFxModel, String> recording = new TableColumn<>("Recording");
|
||||||
recording.setCellValueFactory(cdf -> cdf.getValue().getRecordingProperty());
|
recording.setCellValueFactory(cdf -> cdf.getValue().getRecordingProperty());
|
||||||
recording.setCellFactory(CheckBoxTableCell.forTableColumn(recording));
|
recording.setCellFactory(tc -> new RecordingCell());
|
||||||
recording.setPrefWidth(100);
|
recording.setPrefWidth(100);
|
||||||
recording.setEditable(false);
|
recording.setEditable(false);
|
||||||
recording.setId("recording");
|
recording.setId("recording");
|
||||||
|
recording.setStyle(STYLE_ALIGN_CENTER);
|
||||||
TableColumn<JavaFxModel, Boolean> paused = new TableColumn<>("Paused");
|
TableColumn<JavaFxModel, Boolean> paused = new TableColumn<>("Paused");
|
||||||
paused.setCellValueFactory(cdf -> cdf.getValue().getPausedProperty());
|
paused.setCellValueFactory(cdf -> cdf.getValue().getPausedProperty());
|
||||||
paused.setCellFactory(CheckBoxTableCell.forTableColumn(paused));
|
paused.setCellFactory(CheckBoxTableCell.forTableColumn(paused));
|
||||||
|
@ -207,13 +215,13 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
priority.setId("priority");
|
priority.setId("priority");
|
||||||
TableColumn<JavaFxModel, Instant> lastSeen = new TableColumn<>("last seen");
|
TableColumn<JavaFxModel, Instant> lastSeen = new TableColumn<>("last seen");
|
||||||
lastSeen.setCellValueFactory(cdf -> cdf.getValue().lastSeenProperty());
|
lastSeen.setCellValueFactory(cdf -> cdf.getValue().lastSeenProperty());
|
||||||
lastSeen.setCellFactory(new DateTimeCellFactory<JavaFxModel>());
|
lastSeen.setCellFactory(new DateTimeCellFactory<>());
|
||||||
lastSeen.setPrefWidth(150);
|
lastSeen.setPrefWidth(150);
|
||||||
lastSeen.setEditable(false);
|
lastSeen.setEditable(false);
|
||||||
lastSeen.setId("lastSeen");
|
lastSeen.setId("lastSeen");
|
||||||
TableColumn<JavaFxModel, Instant> lastRecorded = new TableColumn<>("last recorded");
|
TableColumn<JavaFxModel, Instant> lastRecorded = new TableColumn<>("last recorded");
|
||||||
lastRecorded.setCellValueFactory(cdf -> cdf.getValue().lastRecordedProperty());
|
lastRecorded.setCellValueFactory(cdf -> cdf.getValue().lastRecordedProperty());
|
||||||
lastRecorded.setCellFactory(new DateTimeCellFactory<JavaFxModel>());
|
lastRecorded.setCellFactory(new DateTimeCellFactory<>());
|
||||||
lastRecorded.setPrefWidth(150);
|
lastRecorded.setPrefWidth(150);
|
||||||
lastRecorded.setEditable(false);
|
lastRecorded.setEditable(false);
|
||||||
lastRecorded.setId("lastRecorded");
|
lastRecorded.setId("lastRecorded");
|
||||||
|
@ -581,17 +589,21 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
return recorder.getModels()
|
return recorder.getModels()
|
||||||
.stream()
|
.stream()
|
||||||
.map(JavaFxModel::new)
|
.map(JavaFxModel::new)
|
||||||
.peek(fxm -> {
|
.peek(fxm -> { // NOSONAR
|
||||||
for (Recording recording : recordings) {
|
for (Recording recording : recordings) {
|
||||||
if(recording.getStatus() == RECORDING && Objects.equals(recording.getModel(), fxm)){
|
if(recording.getStatus() == RECORDING && Objects.equals(recording.getModel(), fxm)){
|
||||||
fxm.getRecordingProperty().set(true);
|
String recordingValue = HEAVY_CHECK_MARK;
|
||||||
|
if(!Objects.equals(recording.getModel().getRecordUntil(), Instant.ofEpochMilli(Model.RECORD_INDEFINITELY))) {
|
||||||
|
recordingValue += ' ' + CLOCK;
|
||||||
|
}
|
||||||
|
fxm.getRecordingProperty().set(recordingValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Model onlineModel : onlineModels) {
|
for (Model onlineModel : onlineModels) {
|
||||||
if(Objects.equals(onlineModel, fxm)) {
|
if(Objects.equals(onlineModel, fxm)) {
|
||||||
fxm.getOnlineProperty().set(true);
|
fxm.getOnlineProperty().set(HEAVY_CHECK_MARK);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -649,6 +661,8 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
resumeRecording.setOnAction(e -> resumeRecording(selectedModels));
|
resumeRecording.setOnAction(e -> resumeRecording(selectedModels));
|
||||||
MenuItem stopRecordingAt = new MenuItem("Stop Recording at Date");
|
MenuItem stopRecordingAt = new MenuItem("Stop Recording at Date");
|
||||||
stopRecordingAt.setOnAction(e -> setStopDate(selectedModels.get(0)));
|
stopRecordingAt.setOnAction(e -> setStopDate(selectedModels.get(0)));
|
||||||
|
MenuItem removeTimeLimit = new MenuItem("Remove Time Limit");
|
||||||
|
removeTimeLimit.setOnAction(e -> removeTimeLimit(selectedModels.get(0)));
|
||||||
MenuItem openInBrowser = new MenuItem("Open in Browser");
|
MenuItem openInBrowser = new MenuItem("Open in Browser");
|
||||||
openInBrowser.setOnAction(e -> DesktopIntegration.open(selectedModels.get(0).getUrl()));
|
openInBrowser.setOnAction(e -> DesktopIntegration.open(selectedModels.get(0).getUrl()));
|
||||||
MenuItem openInPlayer = new MenuItem("Open in Player");
|
MenuItem openInPlayer = new MenuItem("Open in Player");
|
||||||
|
@ -669,6 +683,9 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
if (selectedModels.size() == 1) {
|
if (selectedModels.size() == 1) {
|
||||||
menu.getItems().add(selectedModels.get(0).isSuspended() ? resumeRecording : pauseRecording);
|
menu.getItems().add(selectedModels.get(0).isSuspended() ? resumeRecording : pauseRecording);
|
||||||
menu.getItems().add(stopRecordingAt);
|
menu.getItems().add(stopRecordingAt);
|
||||||
|
if (selectedModels.get(0).isRecordingTimeLimited()) {
|
||||||
|
menu.getItems().add(removeTimeLimit);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
menu.getItems().addAll(resumeRecording, pauseRecording);
|
menu.getItems().addAll(resumeRecording, pauseRecording);
|
||||||
}
|
}
|
||||||
|
@ -687,13 +704,13 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
|
|
||||||
private void setStopDate(JavaFxModel model) {
|
private void setStopDate(JavaFxModel model) {
|
||||||
DatePicker datePicker = new DatePicker();
|
DatePicker datePicker = new DatePicker();
|
||||||
GridPane grid = new GridPane();
|
GridPane gridPane = new GridPane();
|
||||||
grid.setHgap(10);
|
gridPane.setHgap(10);
|
||||||
grid.setVgap(10);
|
gridPane.setVgap(10);
|
||||||
grid.setPadding(new Insets(20, 150, 10, 10));
|
gridPane.setPadding(new Insets(20, 150, 10, 10));
|
||||||
grid.add(new Label("Stop at"), 0, 0);
|
gridPane.add(new Label("Stop at"), 0, 0);
|
||||||
grid.add(datePicker, 1, 0);
|
gridPane.add(datePicker, 1, 0);
|
||||||
grid.add(new Label("And then"), 0, 1);
|
gridPane.add(new Label("And then"), 0, 1);
|
||||||
ToggleGroup toggleGroup = new ToggleGroup();
|
ToggleGroup toggleGroup = new ToggleGroup();
|
||||||
RadioButton pauseButton = new RadioButton("pause recording");
|
RadioButton pauseButton = new RadioButton("pause recording");
|
||||||
pauseButton.setSelected(model.getRecordUntilSubsequentAction() == PAUSE);
|
pauseButton.setSelected(model.getRecordUntilSubsequentAction() == PAUSE);
|
||||||
|
@ -705,18 +722,19 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
row.getChildren().addAll(pauseButton, removeButton);
|
row.getChildren().addAll(pauseButton, removeButton);
|
||||||
HBox.setMargin(pauseButton, new Insets(5));
|
HBox.setMargin(pauseButton, new Insets(5));
|
||||||
HBox.setMargin(removeButton, new Insets(5));
|
HBox.setMargin(removeButton, new Insets(5));
|
||||||
grid.add(row, 1, 1);
|
gridPane.add(row, 1, 1);
|
||||||
if (model.getRecordUntil().toEpochMilli() != Model.RECORD_INDEFINITELY) {
|
if (model.isRecordingTimeLimited()) {
|
||||||
LocalDate localDate = LocalDate.ofInstant(model.getRecordUntil(), ZoneId.systemDefault());
|
LocalDate localDate = LocalDate.ofInstant(model.getRecordUntil(), ZoneId.systemDefault());
|
||||||
datePicker.setValue(localDate);
|
datePicker.setValue(localDate);
|
||||||
}
|
}
|
||||||
boolean userClickedOk = Dialogs.showCustomInput(getTabPane().getScene(), "Stop Recording at", grid);
|
boolean userClickedOk = Dialogs.showCustomInput(getTabPane().getScene(), "Stop Recording at", gridPane);
|
||||||
if (userClickedOk) {
|
if (userClickedOk) {
|
||||||
SubsequentAction action = pauseButton.isSelected() ? PAUSE : REMOVE;
|
SubsequentAction action = pauseButton.isSelected() ? PAUSE : REMOVE;
|
||||||
LOG.info("Stop at {} and {}", datePicker.getValue(), action);
|
LOG.info("Stop at {} and {}", datePicker.getValue(), action);
|
||||||
Instant stopAt = Instant.from(datePicker.getValue().atStartOfDay().atZone(ZoneId.systemDefault()));
|
Instant stopAt = Instant.from(datePicker.getValue().atStartOfDay().atZone(ZoneId.systemDefault()));
|
||||||
model.setRecordUntil(stopAt);
|
model.setRecordUntil(stopAt);
|
||||||
model.setRecordUntilSubsequentAction(action);
|
model.setRecordUntilSubsequentAction(action);
|
||||||
|
table.refresh();
|
||||||
try {
|
try {
|
||||||
recorder.stopRecordingAt(model.getDelegate());
|
recorder.stopRecordingAt(model.getDelegate());
|
||||||
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) {
|
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) {
|
||||||
|
@ -725,6 +743,12 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeTimeLimit(JavaFxModel selectedModel) {
|
||||||
|
new RemoveTimeLimitAction(table, selectedModel.getDelegate(), recorder) //
|
||||||
|
.execute() //
|
||||||
|
.whenComplete((result, exception) -> table.refresh());
|
||||||
|
}
|
||||||
|
|
||||||
private void ignore(ObservableList<JavaFxModel> selectedModels) {
|
private void ignore(ObservableList<JavaFxModel> selectedModels) {
|
||||||
for (JavaFxModel fxModel : selectedModels) {
|
for (JavaFxModel fxModel : selectedModels) {
|
||||||
Model modelToIgnore = fxModel.getDelegate();
|
Model modelToIgnore = fxModel.getDelegate();
|
||||||
|
@ -737,7 +761,7 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void follow(ObservableList<JavaFxModel> selectedModels) {
|
private void follow(ObservableList<JavaFxModel> selectedModels) {
|
||||||
new FollowAction(getTabPane(), new ArrayList<JavaFxModel>(selectedModels)).execute();
|
new FollowAction(getTabPane(), new ArrayList<>(selectedModels)).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notes(ObservableList<JavaFxModel> selectedModels) {
|
private void notes(ObservableList<JavaFxModel> selectedModels) {
|
||||||
|
@ -920,4 +944,25 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
return tableCell;
|
return tableCell;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class RecordingCell extends TableCell<JavaFxModel, String> {
|
||||||
|
@Override
|
||||||
|
protected void updateItem(String value, boolean empty) {
|
||||||
|
super.updateItem(value, empty);
|
||||||
|
if (value == null) {
|
||||||
|
setTooltip(null);
|
||||||
|
setText(null);
|
||||||
|
} else {
|
||||||
|
Model m = getTableView().getItems().get(getTableRow().getIndex());
|
||||||
|
if (m.isRecordingTimeLimited()) {
|
||||||
|
Tooltip tooltip = new Tooltip();
|
||||||
|
DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
|
||||||
|
ZonedDateTime zonedDateTime = m.getRecordUntil().atZone(ZoneId.systemDefault());
|
||||||
|
tooltip.setText("Recording until " + dtf.format(zonedDateTime));
|
||||||
|
setTooltip(tooltip);
|
||||||
|
}
|
||||||
|
setText(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,6 +237,11 @@ public abstract class AbstractModel implements Model {
|
||||||
this.lastRecorded = lastRecorded;
|
this.lastRecorded = lastRecorded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRecordingTimeLimited() {
|
||||||
|
return !getRecordUntil().equals(Instant.ofEpochMilli(RECORD_INDEFINITELY));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Instant getRecordUntil() {
|
public Instant getRecordUntil() {
|
||||||
return Optional.ofNullable(recordUntil).orElse(Instant.ofEpochMilli(RECORD_INDEFINITELY));
|
return Optional.ofNullable(recordUntil).orElse(Instant.ofEpochMilli(RECORD_INDEFINITELY));
|
||||||
|
|
|
@ -130,6 +130,7 @@ public interface Model extends Comparable<Model>, Serializable {
|
||||||
|
|
||||||
public HttpHeaderFactory getHttpHeaderFactory();
|
public HttpHeaderFactory getHttpHeaderFactory();
|
||||||
|
|
||||||
|
public boolean isRecordingTimeLimited();
|
||||||
public Instant getRecordUntil();
|
public Instant getRecordUntil();
|
||||||
public void setRecordUntil(Instant instant);
|
public void setRecordUntil(Instant instant);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue