jafea7-ctbrec-v5.3.0-based/client/src/main/java/ctbrec/ui/action/SwitchStreamResolutionActio...

124 lines
5.0 KiB
Java

package ctbrec.ui.action;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import org.eclipse.jetty.io.RuntimeIOException;
import ctbrec.GlobalThreadPool;
import ctbrec.Model;
import ctbrec.recorder.Recorder;
import ctbrec.recorder.download.StreamSource;
import ctbrec.sites.ModelOfflineException;
import ctbrec.ui.StreamSourceSelectionDialog;
import ctbrec.ui.controls.Dialogs;
import javafx.application.Platform;
import javafx.scene.Cursor;
import javafx.scene.Node;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SwitchStreamResolutionAction {
private Node source;
private Model selectedModel;
private Recorder recorder;
public SwitchStreamResolutionAction(Node source, Model selectedModel, Recorder recorder) {
this.source = source;
this.selectedModel = selectedModel;
this.recorder = recorder;
}
public CompletableFuture<Void> execute() {
source.setCursor(Cursor.WAIT);
var couldntSwitchHeaderText = "Couldn't switch stream resolution";
return CompletableFuture.supplyAsync(() -> {
try {
checkOnlineState();
return Boolean.TRUE; // model is online
} catch (ModelOfflineException e) {
return Boolean.FALSE; // model is offline
}
}, GlobalThreadPool.get())
.thenAccept(isOnline -> Platform.runLater(() -> {
if (isOnline) {
// --- model is online: open selection dialog ---
StreamSourceSelectionDialog dialog =
new StreamSourceSelectionDialog(source.getScene(), selectedModel);
Optional<StreamSource> selectedSource = dialog.showAndWait();
if (selectedSource.isPresent()) {
StreamSource src = selectedSource.get();
if (src != StreamSourceSelectionDialog.LOADING) {
int index = dialog.indexOf(src);
selectedModel.setStreamUrlIndex(index);
try {
recorder.switchStreamSource(selectedModel);
} catch (InvalidKeyException | NoSuchAlgorithmException |
IllegalStateException | IOException e) {
log.error(couldntSwitchHeaderText, e);
Dialogs.showError(source.getScene(), couldntSwitchHeaderText,
"Error while switching stream resolution", e);
}
}
}
} else {
// --- model is offline: ask if user wants to reset ---
boolean confirmed = Dialogs.showConfirmDialog(
"Model is offline",
"Yes to reset to Default (Best resolution),\nNo to leave existing resolution unchanged.",
"",
source.getScene()
);
if (confirmed) {
selectedModel.setStreamUrlIndex(-1);
try {
recorder.switchStreamSource(selectedModel); // persist the change
} catch (InvalidKeyException | NoSuchAlgorithmException |
IllegalStateException | IOException e) {
log.error("Couldn't update recorder with reset stream index", e);
Dialogs.showError(source.getScene(),
"Couldn't reset stream resolution",
"Error while updating stream resolution", e);
}
// show confirmation popup
Dialogs.showError(
source.getScene(),
"Stream Resolution Reset",
"Stream resolution has been reset to Best (default).",
null
);
}
}
source.setCursor(Cursor.DEFAULT);
}))
.exceptionally(ex -> {
log.error("Unexpected error while switching resolution", ex);
Platform.runLater(() -> {
Dialogs.showError(source.getScene(), couldntSwitchHeaderText,
"Unexpected error occurred", ex);
source.setCursor(Cursor.DEFAULT);
});
return null;
});
}
private void checkOnlineState() {
try {
if (!selectedModel.isOnline(true)) {
throw new ModelOfflineException(selectedModel);
}
} catch (IOException | ExecutionException e) {
throw new RuntimeIOException(e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e); // NOSONAR
}
}
}