package ctbrec.ui.news; import static ctbrec.ErrorMessages.HTTP_RESPONSE_BODY_IS_NULL; import static ctbrec.io.HttpConstants.*; import java.io.IOException; import java.util.Objects; import ctbrec.Config; import org.json.JSONObject; import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.Moshi; import ctbrec.GlobalThreadPool; import ctbrec.io.HttpException; import ctbrec.ui.CamrecApplication; import ctbrec.ui.controls.Dialogs; import ctbrec.ui.tabs.TabSelectionListener; import javafx.application.Platform; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.ScrollPane; import javafx.scene.control.Tab; import javafx.scene.layout.VBox; import okhttp3.Request; public class NewsTab extends Tab implements TabSelectionListener { private static final String ACCESS_TOKEN = "a2804d73a89951a22e0f8483a6fcec8943afd88b7ba17c459c095aa9e6f94fd0"; private static final String URL = "https://mastodon.cloud/api/v1/accounts/480960/statuses?limit=20&exclude_replies=true"; private final Config config; private final VBox layout = new VBox(); public NewsTab(Config config) { this.config = config; setText("News"); layout.setMaxWidth(800); layout.setAlignment(Pos.CENTER); setContent(new ScrollPane(layout)); } @Override public void selected() { GlobalThreadPool.submit(this::loadToots); } private void loadToots() { try { var request = new Request.Builder() .url(URL) .header("Authorization", "Bearer " + ACCESS_TOKEN) .header(USER_AGENT, "ctbrec " + CamrecApplication.getVersion()) .build(); try (var response = CamrecApplication.httpClient.execute(request)) { if (response.isSuccessful()) { var body = Objects.requireNonNull(response.body(), HTTP_RESPONSE_BODY_IS_NULL).string(); if (body.startsWith("[")) { onSuccess(body); } else if (body.startsWith("{")) { onError(body); } else { throw new IOException("Unexpected response: " + body); } } else { throw new HttpException(response.code(), response.message()); } } } catch (IOException e) { Dialogs.showError(getTabPane().getScene(), "News", "Couldn't load news from mastodon", e); } } private void onError(String body) throws IOException { var json = new JSONObject(body); if (json.has("error")) { throw new IOException("Request not successful: " + json.getString("error")); } else { throw new IOException("Unexpected response: " + body); } } private void onSuccess(String body) throws IOException { var moshi = new Moshi.Builder().build(); JsonAdapter statusListAdapter = moshi.adapter(Status[].class); Status[] statusArray = Objects.requireNonNull(statusListAdapter.fromJson(body)); Platform.runLater(() -> { layout.getChildren().clear(); for (Status status : statusArray) { if (status.getInReplyToId() == null && !Objects.equals("direct", status.getVisibility())) { var stp = new StatusPane(status, config.getDateTimeFormatter()); layout.getChildren().add(stp); VBox.setMargin(stp, new Insets(10)); } } }); } @Override public void deselected() { // nothing to do } }