diff --git a/ComposeWindow.java b/ComposeWindow.java index dba0eb9..2858fc0 100644 --- a/ComposeWindow.java +++ b/ComposeWindow.java @@ -102,19 +102,84 @@ ComposeWindow extends JFrame { if (composition.contentWarning != null) assert !composition.contentWarning.trim().isEmpty(); - // Oh, this is gonna be hell. + //tabs.setCursor(new Cursor(Cursor.WAIT_CURSOR)); /* - * (未) For every attachment in composition, - * attempt to upload it, then fill the media ID. - * Then change MastodonApi#submit to accept an - * array of media IDs. If any upload fails, - * show an error message then return. + * setCursor only works for components that are enabled. + * I don't think there's any technical reason for this, + * but it's what it is.. rely on the enablement visuals + * or a statusbar to indicate to user. + * + * If we really wanted it, I suspect we could use a glass + * pane (or a scroll pane with no scrolling) to have an + * enabled pass-through on top. + * + * Technically contentsDisplay and attachmentsDisplay + * themselves aren't disabled. But disabling the tab pane + * covers both the tab area and content area. We can't + * just the tab area, except maybe by disabling the + * individual tabs. */ + tabs.setEnabled(false); + tabs.setSelectedComponent(contentsDisplay); + contentsDisplay.setSubmitting(true); + tabs.paintImmediately(tabs.getBounds()); - contentsDisplay.setSubmitting(true); - api.submit( + boolean uploadsOkay = true; + for (Attachment a: composition.attachments) + { + if (a.id != null) continue; + // Assume it had already been uploaded. + + api.uploadFile(a.uploadee, new RequestListener() { + + public void + connectionFailed(IOException eIo) + { + JOptionPane.showMessageDialog( + ComposeWindow.this, + "Tried to upload attachment, failed..." + + "\n" + eIo.getMessage() + ); + } + + public void + requestFailed(int httpCode, Tree json) + { + JOptionPane.showMessageDialog( + ComposeWindow.this, + "Tried to upload attachment, failed..." + + "\n" + json.get("error").value + + "\n(HTTP code: " + httpCode + ")" + ); + } + + public void + requestSucceeded(Tree json) + { + a.id = json.get("id").value; + } + + }); + uploadsOkay &= a.id != null; + } + + if (!uploadsOkay) + { + contentsDisplay.setSubmitting(false); + tabs.setEnabled(true); + //tabs.setCursor(null); + return; + } + + int amt = composition.attachments.length; + String[] mediaIDs = new String[amt]; + for (int o = 0; o < mediaIDs.length; ++o) + mediaIDs[o] = composition.attachments[o].id; + + api.submit( composition.text, composition.visibility, composition.replyToPostId, composition.contentWarning, + mediaIDs, new RequestListener() { public void @@ -146,7 +211,10 @@ ComposeWindow extends JFrame { } ); + contentsDisplay.setSubmitting(false); + tabs.setEnabled(true); + tabs.setCursor(null); } // - -%- - @@ -339,14 +407,12 @@ implements ActionListener, CaretListener, KeyListener { text.setEnabled(false); visibility.setEnabled(false); submit.setEnabled(false); - setCursor(new Cursor(Cursor.WAIT_CURSOR)); } else { text.setEnabled(true); visibility.setEnabled(true); submit.setEnabled(true); - setCursor(null); } } diff --git a/MastodonApi.java b/MastodonApi.java index 360fb42..4624b18 100644 --- a/MastodonApi.java +++ b/MastodonApi.java @@ -276,6 +276,7 @@ MastodonApi { submit( String text, PostVisibility visibility, String replyTo, String contentWarning, + String[] mediaIDs, RequestListener handler) { String token = accessToken.get("access_token").value; @@ -315,6 +316,10 @@ MastodonApi { if (contentWarning != null) { output.write("&spoiler_text=" + contentWarning); } + for (String mediaID: mediaIDs) { + output.write("&media_ids[]=" + mediaID); + } + output.close(); doStandardJsonReturn(conn, handler); @@ -516,7 +521,7 @@ MastodonApi { istream.close(); ostream.close(); - wrapResponseInTree(conn, handler); + doStandardJsonReturn(conn, handler); } catch (IOException eIo) { handler.connectionFailed(eIo); } } diff --git a/PostWindow.java b/PostWindow.java index d9b2ef8..bfd42e4 100644 --- a/PostWindow.java +++ b/PostWindow.java @@ -469,6 +469,11 @@ implements ActionListener { * this, using MediaTracker. That assumes what I'm doing * right now definitely works. */ + /* + * (悪) It doesn't work. I might be forced to use + * BufferedImage with ImageIO. Or have + * ImageApi#getScaledInstance spam until it works. + */ profile.setImage(n); }