Remove CamSoda shows tab

This commit is contained in:
0xb00bface 2021-09-08 21:01:04 +02:00
parent 8be632a708
commit c515ce7b2a
2 changed files with 0 additions and 297 deletions

View File

@ -1,296 +0,0 @@
package ctbrec.ui.sites.camsoda;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
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.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ctbrec.GlobalThreadPool;
import ctbrec.Model;
import ctbrec.recorder.Recorder;
import ctbrec.sites.camsoda.Camsoda;
import ctbrec.ui.AutosizeAlert;
import ctbrec.ui.DesktopIntegration;
import ctbrec.ui.SiteUiFactory;
import ctbrec.ui.tabs.TabSelectionListener;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Tab;
import javafx.scene.control.TitledPane;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import okhttp3.Request;
import okhttp3.Response;
public class CamsodaShowsTab extends Tab implements TabSelectionListener {
private static final Logger LOG = LoggerFactory.getLogger(CamsodaShowsTab.class);
private Camsoda camsoda;
private Recorder recorder;
private GridPane showList;
public CamsodaShowsTab(Camsoda camsoda, Recorder recorder) {
this.camsoda = camsoda;
this.recorder = recorder;
createGui();
}
private void createGui() {
showList = new GridPane();
showList.setPadding(new Insets(5));
showList.setHgap(5);
showList.setVgap(5);
var progressIndicator = new ProgressIndicator();
progressIndicator.setPrefSize(100, 100);
setContent(progressIndicator);
setClosable(false);
setText("Shows");
}
@Override
public void selected() {
Task<List<ShowBox>> task = new Task<List<ShowBox>>() {
@Override
protected List<ShowBox> call() throws Exception {
return loadShows();
}
@Override
protected void done() {
super.done();
Platform.runLater(() -> {
try {
List<ShowBox> boxes = get();
showList.getChildren().clear();
var index = 0;
for (ShowBox showBox : boxes) {
showList.add(showBox, index % 2, index++ / 2);
GridPane.setMargin(showBox, new Insets(20, 20, 0, 20));
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
LOG.error("Couldn't load upcoming camsoda shows", e);
} catch (Exception e) {
LOG.error("Couldn't load upcoming camsoda shows", e);
}
setContent(new ScrollPane(showList));
});
}
};
GlobalThreadPool.submit(task);
}
private List<ShowBox> loadShows() throws IOException {
String url = camsoda.getBaseUrl() + "/api/v1/user/model_shows";
Request req = new Request.Builder().url(url).build();
try(var response = camsoda.getHttpClient().execute(req)) {
if (response.isSuccessful()) {
var json = new JSONObject(response.body().string());
if (json.optInt("success") == 1) {
List<ShowBox> boxes = new ArrayList<>();
var results = json.getJSONArray("results");
for (var i = 0; i < results.length(); i++) {
var result = results.getJSONObject(i);
var modelUrl = camsoda.getBaseUrl() + result.getString("url");
var name = modelUrl.substring(modelUrl.lastIndexOf('/') + 1);
var model = camsoda.createModel(name);
ZonedDateTime startTime = parseUtcTime(result.getString("start"));
ZonedDateTime endTime = parseUtcTime(result.getString("end"));
boxes.add(new ShowBox(model, startTime, endTime));
}
return boxes;
} else {
LOG.error("Couldn't load upcoming camsoda shows. Unexpected response: {}", json);
showErrorDialog("Oh no!", "Couldn't load upcoming CamSoda shows", "Got an unexpected response from server");
}
} else {
showErrorDialog("Oh no!", "Couldn't load upcoming CamSoda shows", "Got an unexpected response from server");
LOG.error("Couldn't load upcoming camsoda shows: {} {}", response.code(), response.message());
}
}
return Collections.emptyList();
}
private ZonedDateTime parseUtcTime(String string) {
var formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
var ta = formatter.parse(string.replace(" UTC", ""));
var instant = Instant.from(ta);
return ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
}
@Override
public void deselected() {
// nothing to do
}
private void showErrorDialog(String title, String head, String msg) {
Platform.runLater(() -> {
Alert alert = new AutosizeAlert(Alert.AlertType.ERROR, getTabPane().getScene());
alert.setTitle(title);
alert.setHeaderText(head);
alert.setContentText(msg);
alert.showAndWait();
});
}
private class ShowBox extends TitledPane {
BorderPane root = new BorderPane();
int thumbSize = 200;
public ShowBox(Model model, ZonedDateTime startTime, ZonedDateTime endTime) {
setText(model.getName());
setPrefHeight(268);
setContent(root);
var thumb = new ImageView();
thumb.setPreserveRatio(true);
thumb.setFitHeight(thumbSize);
loadImage(model, thumb);
root.setLeft(new ProgressIndicator());
BorderPane.setMargin(thumb, new Insets(10, 30, 10, 10));
var formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.MEDIUM);
var grid = new GridPane();
grid.add(createLabel("Start", true), 0, 0);
grid.add(createLabel(formatter.format(startTime), false), 1, 0);
grid.add(createLabel("End", true), 0, 1);
grid.add(createLabel(formatter.format(endTime), false), 1, 1);
var recordButton = new Button("Record Model");
recordButton.setTooltip(new Tooltip(recordButton.getText()));
recordButton.setOnAction(evt -> recordModel(model));
grid.add(recordButton, 1, 2);
GridPane.setMargin(recordButton, new Insets(10));
var follow = new Button("Follow");
follow.setTooltip(new Tooltip(follow.getText()));
follow.setOnAction(evt -> follow(model));
grid.add(follow, 1, 3);
GridPane.setMargin(follow, new Insets(10));
var openInBrowser = new Button("Open in Browser");
openInBrowser.setTooltip(new Tooltip(openInBrowser.getText()));
openInBrowser.setOnAction(evt -> DesktopIntegration.open(model.getUrl()));
grid.add(openInBrowser, 1, 4);
GridPane.setMargin(openInBrowser, new Insets(10));
root.setCenter(grid);
loadImage(model, thumb);
recordButton.minWidthProperty().bind(openInBrowser.widthProperty());
follow.minWidthProperty().bind(openInBrowser.widthProperty());
}
private void follow(Model model) {
setCursor(Cursor.WAIT);
GlobalThreadPool.submit(() -> {
try {
SiteUiFactory.getUi(model.getSite()).login();
model.follow();
} catch (Exception e) {
LOG.error("Couldn't follow model {}", model, e);
showErrorDialog("Oh no!", "Couldn't follow model", e.getMessage());
} finally {
Platform.runLater(() -> setCursor(Cursor.DEFAULT));
}
});
}
private void recordModel(Model model) {
setCursor(Cursor.WAIT);
GlobalThreadPool.submit(() -> {
try {
recorder.addModel(model);
} catch (InvalidKeyException | NoSuchAlgorithmException | IllegalStateException | IOException e) {
showErrorDialog("Oh no!", "Couldn't add model to the recorder", "Recorder error: " + e.getMessage());
} finally {
Platform.runLater(() -> setCursor(Cursor.DEFAULT));
}
});
}
private void loadImage(Model model, ImageView thumb) {
GlobalThreadPool.submit(() -> {
try {
String url = camsoda.getBaseUrl() + "/api/v1/user/" + model.getName();
var detailRequest = new Request.Builder().url(url).build();
try (Response resp = camsoda.getHttpClient().execute(detailRequest)) {
if (resp.isSuccessful()) {
parseImageUrl(resp.body().string()).ifPresent(imageUrl -> updateImageView(thumb, imageUrl));
}
}
} catch (Exception e) {
LOG.error("Couldn't load model details", e);
}
});
}
private void updateImageView(ImageView view, String imageUrl) {
Platform.runLater(() -> {
var img = new Image(imageUrl, 1000, thumbSize, true, true, true);
img.progressProperty().addListener((ChangeListener<Number>) (observable, oldValue, newValue) -> {
if (newValue.doubleValue() == 1.0) {
view.setImage(img);
root.setLeft(view);
}
});
});
}
private Optional<String> parseImageUrl(String body) {
var json = new JSONObject(body);
if (json.optBoolean("status") && json.has("user")) {
var user = json.getJSONObject("user");
if (user.has("settings")) {
var settings = user.getJSONObject("settings");
String imageUrl;
if (Objects.equals(System.getenv("CTBREC_DEV"), "1")) {
imageUrl = getClass().getResource("/image_not_found.png").toString();
} else {
if (settings.has("offline_picture")) {
imageUrl = settings.getString("offline_picture");
} else {
imageUrl = "https:" + user.getString("thumb");
}
}
return Optional.of(imageUrl);
}
}
return Optional.empty();
}
private Node createLabel(String string, boolean bold) {
var label = new Label(string);
label.setPadding(new Insets(10));
var def = Font.getDefault();
label.setFont(Font.font(def.getFamily(), bold ? FontWeight.BOLD : FontWeight.NORMAL, 16));
return label;
}
}
}

View File

@ -40,7 +40,6 @@ public class CamsodaTabProvider implements TabProvider {
followedTab.setRecorder(recorder);
followedTab.setScene(scene);
tabs.add(followedTab);
tabs.add(new CamsodaShowsTab(camsoda, recorder));
return tabs;
}