2021-07-16 01:07:23 +02:00
|
|
|
|
|
|
|
import javax.swing.JFrame;
|
|
|
|
import javax.swing.JPanel;
|
2021-07-17 11:06:50 +02:00
|
|
|
import javax.swing.JTextArea;
|
2022-04-12 08:37:39 +02:00
|
|
|
import javax.swing.JTextField;
|
|
|
|
import javax.swing.JLabel;
|
2021-07-28 22:23:42 +02:00
|
|
|
import javax.swing.JComboBox;
|
2021-07-17 11:06:50 +02:00
|
|
|
import javax.swing.JButton;
|
|
|
|
import javax.swing.Box;
|
|
|
|
import javax.swing.BorderFactory;
|
2022-04-12 08:37:39 +02:00
|
|
|
import javax.swing.JOptionPane;
|
2022-05-01 08:46:10 +02:00
|
|
|
import javax.swing.border.Border;
|
2022-04-14 06:38:49 +02:00
|
|
|
import java.awt.GridLayout;
|
2021-07-17 11:06:50 +02:00
|
|
|
import java.awt.BorderLayout;
|
|
|
|
import java.awt.Dimension;
|
2021-07-28 22:23:42 +02:00
|
|
|
import java.awt.event.ActionListener;
|
|
|
|
import java.awt.event.ActionEvent;
|
2022-05-06 09:05:01 +02:00
|
|
|
import java.awt.event.KeyListener;
|
|
|
|
import java.awt.event.KeyEvent;
|
2021-07-28 22:23:42 +02:00
|
|
|
import java.awt.Cursor;
|
2022-05-01 08:46:10 +02:00
|
|
|
import java.awt.Color;
|
2022-05-06 09:05:01 +02:00
|
|
|
import javax.swing.event.CaretListener;
|
|
|
|
import javax.swing.event.CaretEvent;
|
2021-07-16 01:07:23 +02:00
|
|
|
|
2022-04-12 08:37:39 +02:00
|
|
|
import cafe.biskuteri.hinoki.Tree;
|
|
|
|
import java.io.IOException;
|
|
|
|
|
2021-07-16 01:07:23 +02:00
|
|
|
class
|
|
|
|
ComposeWindow extends JFrame {
|
|
|
|
|
2022-04-12 08:37:39 +02:00
|
|
|
private JKomasto
|
|
|
|
primaire;
|
|
|
|
|
|
|
|
private MastodonApi
|
|
|
|
api;
|
|
|
|
|
|
|
|
// - -%- -
|
|
|
|
|
2021-07-17 11:46:27 +02:00
|
|
|
private Composition
|
|
|
|
composition;
|
|
|
|
|
2021-07-16 01:07:23 +02:00
|
|
|
private ComposeComponent
|
|
|
|
display;
|
|
|
|
|
2021-07-17 11:46:27 +02:00
|
|
|
// ---%-@-%---
|
|
|
|
|
|
|
|
public void
|
2021-07-29 10:03:32 +02:00
|
|
|
setComposition(Composition composition)
|
2021-07-28 22:23:42 +02:00
|
|
|
{
|
2022-04-12 08:37:39 +02:00
|
|
|
assert composition != null;
|
2021-07-29 10:03:32 +02:00
|
|
|
this.composition = composition;
|
2021-07-28 23:55:30 +02:00
|
|
|
syncDisplayToComposition();
|
2021-07-28 22:23:42 +02:00
|
|
|
}
|
|
|
|
|
2022-04-12 08:37:39 +02:00
|
|
|
public void
|
|
|
|
newComposition()
|
|
|
|
{
|
|
|
|
composition = new Composition();
|
|
|
|
composition.text = "";
|
2022-04-28 03:56:25 +02:00
|
|
|
composition.visibility = PostVisibility.UNLISTED;
|
2022-04-12 08:37:39 +02:00
|
|
|
composition.replyToPostId = null;
|
2022-04-14 06:38:49 +02:00
|
|
|
composition.contentWarning = null;
|
2022-04-12 08:37:39 +02:00
|
|
|
syncDisplayToComposition();
|
|
|
|
}
|
|
|
|
|
2021-07-28 22:23:42 +02:00
|
|
|
public void
|
|
|
|
submit()
|
2021-07-17 11:46:27 +02:00
|
|
|
{
|
2021-07-28 23:55:30 +02:00
|
|
|
syncCompositionToDisplay();
|
2022-04-14 06:38:49 +02:00
|
|
|
|
|
|
|
if (composition.replyToPostId != null)
|
|
|
|
assert !composition.replyToPostId.trim().isEmpty();
|
|
|
|
if (composition.contentWarning != null)
|
|
|
|
assert !composition.contentWarning.trim().isEmpty();
|
|
|
|
|
2021-07-28 23:55:30 +02:00
|
|
|
display.setSubmitting(true);
|
2022-04-12 08:37:39 +02:00
|
|
|
api.submit(
|
|
|
|
composition.text, composition.visibility,
|
2022-04-14 06:38:49 +02:00
|
|
|
composition.replyToPostId, composition.contentWarning,
|
2022-04-12 08:37:39 +02:00
|
|
|
new RequestListener() {
|
|
|
|
|
|
|
|
public void
|
|
|
|
connectionFailed(IOException eIo)
|
|
|
|
{
|
|
|
|
JOptionPane.showMessageDialog(
|
|
|
|
ComposeWindow.this,
|
|
|
|
"Tried to submit post, failed..."
|
|
|
|
+ "\n" + eIo.getMessage()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void
|
|
|
|
requestFailed(int httpCode, Tree<String> json)
|
|
|
|
{
|
|
|
|
JOptionPane.showMessageDialog(
|
|
|
|
ComposeWindow.this,
|
|
|
|
"Tried to submit post, failed..."
|
|
|
|
+ "\n" + json.get("error").value
|
2022-05-06 09:05:01 +02:00
|
|
|
+ "\n(HTTP error code: " + httpCode + ")"
|
2022-04-12 08:37:39 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void
|
|
|
|
requestSucceeded(Tree<String> json)
|
|
|
|
{
|
|
|
|
newComposition();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
);
|
2021-07-28 23:55:30 +02:00
|
|
|
display.setSubmitting(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// - -%- -
|
2021-07-28 22:23:42 +02:00
|
|
|
|
2021-07-28 23:55:30 +02:00
|
|
|
private void
|
|
|
|
syncDisplayToComposition()
|
|
|
|
{
|
|
|
|
display.setText(composition.text);
|
2022-04-12 08:37:39 +02:00
|
|
|
display.setReplyToPostId(composition.replyToPostId);
|
2021-07-28 23:55:30 +02:00
|
|
|
display.setVisibility(stringFor(composition.visibility));
|
2022-04-14 06:38:49 +02:00
|
|
|
display.setContentWarning(composition.contentWarning);
|
2021-07-28 23:55:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private void
|
|
|
|
syncCompositionToDisplay()
|
|
|
|
{
|
|
|
|
composition.text = display.getText();
|
|
|
|
composition.visibility =
|
|
|
|
visibilityFrom(display.getVisibility());
|
2022-04-14 06:38:49 +02:00
|
|
|
composition.replyToPostId =
|
|
|
|
nonEmpty(display.getReplyToPostId());
|
|
|
|
composition.contentWarning =
|
|
|
|
nonEmpty(display.getContentWarning());
|
|
|
|
}
|
|
|
|
|
|
|
|
// - -%- -
|
|
|
|
|
|
|
|
private static String
|
|
|
|
nonEmpty(String s)
|
|
|
|
{
|
|
|
|
if (s.trim().isEmpty()) return null;
|
|
|
|
return s;
|
2021-07-17 11:46:27 +02:00
|
|
|
}
|
|
|
|
|
2021-07-16 01:07:23 +02:00
|
|
|
// ---%-@-%---
|
|
|
|
|
2022-04-12 08:37:39 +02:00
|
|
|
ComposeWindow(JKomasto primaire)
|
2021-07-16 01:07:23 +02:00
|
|
|
{
|
2022-04-12 08:37:39 +02:00
|
|
|
super("Submit a new post");
|
|
|
|
this.primaire = primaire;
|
|
|
|
this.api = primaire.getMastodonApi();
|
|
|
|
|
2021-07-16 11:46:17 +02:00
|
|
|
getContentPane().setPreferredSize(new Dimension(360, 270));
|
|
|
|
pack();
|
|
|
|
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
|
|
|
|
2021-07-28 22:23:42 +02:00
|
|
|
display = new ComposeComponent(this);
|
2022-04-12 08:37:39 +02:00
|
|
|
newComposition();
|
2021-07-17 12:03:59 +02:00
|
|
|
|
2021-07-16 01:07:23 +02:00
|
|
|
setContentPane(display);
|
2022-05-06 15:57:17 +02:00
|
|
|
setIconImage(primaire.getProgramIcon());
|
2021-07-16 01:07:23 +02:00
|
|
|
}
|
|
|
|
|
2021-07-28 23:55:30 +02:00
|
|
|
// - -%- -
|
|
|
|
|
|
|
|
private static final String
|
|
|
|
stringFor(PostVisibility visibility)
|
|
|
|
{
|
|
|
|
switch (visibility)
|
|
|
|
{
|
|
|
|
case PUBLIC: return "Public";
|
2022-04-12 08:37:39 +02:00
|
|
|
case UNLISTED: return "Unlisted";
|
2021-07-28 23:55:30 +02:00
|
|
|
case FOLLOWERS: return "Followers";
|
|
|
|
case MENTIONED: return "Mentioned";
|
|
|
|
}
|
|
|
|
|
2021-07-29 10:03:32 +02:00
|
|
|
assert false; return null;
|
2021-07-28 23:55:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private static final PostVisibility
|
|
|
|
visibilityFrom(String string)
|
|
|
|
{
|
|
|
|
if (string.equals("Public"))
|
|
|
|
return PostVisibility.PUBLIC;
|
2022-04-12 08:37:39 +02:00
|
|
|
if (string.equals("Unlisted"))
|
|
|
|
return PostVisibility.UNLISTED;
|
2021-07-28 23:55:30 +02:00
|
|
|
if (string.equals("Followers"))
|
|
|
|
return PostVisibility.FOLLOWERS;
|
|
|
|
if (string.equals("Mentioned"))
|
|
|
|
return PostVisibility.MENTIONED;
|
|
|
|
|
2021-07-29 10:03:32 +02:00
|
|
|
assert false; return null;
|
2021-07-28 23:55:30 +02:00
|
|
|
}
|
|
|
|
|
2021-07-16 01:07:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class
|
2021-07-28 22:23:42 +02:00
|
|
|
ComposeComponent extends JPanel
|
2022-05-06 09:05:01 +02:00
|
|
|
implements ActionListener, CaretListener, KeyListener {
|
2021-07-28 22:23:42 +02:00
|
|
|
|
|
|
|
private ComposeWindow
|
|
|
|
primaire;
|
|
|
|
|
|
|
|
// - -%- -
|
2021-07-17 11:06:50 +02:00
|
|
|
|
|
|
|
private JTextArea
|
|
|
|
text;
|
|
|
|
|
2022-04-12 08:37:39 +02:00
|
|
|
private JTextField
|
2022-04-14 06:38:49 +02:00
|
|
|
reply, contentWarning;
|
2022-04-12 08:37:39 +02:00
|
|
|
|
2022-05-06 09:05:01 +02:00
|
|
|
private JLabel
|
|
|
|
textLength;
|
|
|
|
|
2021-07-28 22:23:42 +02:00
|
|
|
private JComboBox<String>
|
|
|
|
visibility;
|
|
|
|
|
2021-07-17 11:06:50 +02:00
|
|
|
private JButton
|
|
|
|
submit;
|
|
|
|
|
|
|
|
// ---%-@-%---
|
|
|
|
|
2021-07-28 22:23:42 +02:00
|
|
|
public void
|
2021-07-28 23:55:30 +02:00
|
|
|
setText(String text)
|
2021-07-17 11:06:50 +02:00
|
|
|
{
|
2021-07-28 23:55:30 +02:00
|
|
|
this.text.setText(text);
|
|
|
|
}
|
2021-07-28 22:23:42 +02:00
|
|
|
|
2022-04-12 08:37:39 +02:00
|
|
|
public void
|
|
|
|
setReplyToPostId(String postId)
|
|
|
|
{
|
|
|
|
this.reply.setText(postId);
|
|
|
|
}
|
|
|
|
|
2021-07-28 23:55:30 +02:00
|
|
|
public void
|
|
|
|
setVisibility(String visibility)
|
|
|
|
{
|
|
|
|
if (visibility.equals("Public"))
|
|
|
|
this.visibility.setSelectedIndex(0);
|
2022-04-12 08:37:39 +02:00
|
|
|
else if (visibility.equals("Unlisted"))
|
2021-07-28 23:55:30 +02:00
|
|
|
this.visibility.setSelectedIndex(1);
|
|
|
|
else if (visibility.equals("Followers"))
|
|
|
|
this.visibility.setSelectedIndex(2);
|
|
|
|
else if (visibility.equals("Mentioned"))
|
|
|
|
this.visibility.setSelectedIndex(3);
|
2021-07-28 22:23:42 +02:00
|
|
|
}
|
|
|
|
|
2022-04-14 06:38:49 +02:00
|
|
|
public void
|
|
|
|
setContentWarning(String contentWarning)
|
|
|
|
{
|
|
|
|
this.contentWarning.setText(contentWarning);
|
|
|
|
}
|
|
|
|
|
2021-07-28 22:23:42 +02:00
|
|
|
public String
|
2021-07-28 23:55:30 +02:00
|
|
|
getText()
|
|
|
|
{
|
|
|
|
return text.getText();
|
|
|
|
}
|
2021-07-28 22:23:42 +02:00
|
|
|
|
2022-04-12 08:37:39 +02:00
|
|
|
public String
|
|
|
|
getReplyToPostId()
|
|
|
|
{
|
|
|
|
return reply.getText();
|
|
|
|
}
|
|
|
|
|
2022-04-14 06:38:49 +02:00
|
|
|
public String
|
|
|
|
getContentWarning()
|
|
|
|
{
|
|
|
|
return contentWarning.getText();
|
|
|
|
}
|
|
|
|
|
2021-07-28 22:23:42 +02:00
|
|
|
public String
|
2021-07-28 23:55:30 +02:00
|
|
|
getVisibility()
|
2021-07-28 22:23:42 +02:00
|
|
|
{
|
|
|
|
return (String)visibility.getSelectedItem();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void
|
2021-07-28 23:55:30 +02:00
|
|
|
setSubmitting(boolean submitting)
|
2021-07-28 22:23:42 +02:00
|
|
|
{
|
2021-07-28 23:55:30 +02:00
|
|
|
if (submitting)
|
|
|
|
{
|
|
|
|
text.setEnabled(false);
|
|
|
|
visibility.setEnabled(false);
|
|
|
|
submit.setEnabled(false);
|
2022-04-12 08:37:39 +02:00
|
|
|
setCursor(new Cursor(Cursor.WAIT_CURSOR));
|
2021-07-28 23:55:30 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
text.setEnabled(true);
|
|
|
|
visibility.setEnabled(true);
|
|
|
|
submit.setEnabled(true);
|
|
|
|
setCursor(null);
|
|
|
|
}
|
2021-07-28 22:23:42 +02:00
|
|
|
}
|
|
|
|
|
2021-07-28 23:55:30 +02:00
|
|
|
// - -%- -
|
|
|
|
|
2021-07-28 22:23:42 +02:00
|
|
|
public void
|
|
|
|
actionPerformed(ActionEvent eA) { primaire.submit(); }
|
|
|
|
|
2022-05-06 09:05:01 +02:00
|
|
|
public void
|
|
|
|
caretUpdate(CaretEvent eCa) { updateTextLength(); }
|
|
|
|
|
|
|
|
public void
|
|
|
|
keyPressed(KeyEvent eK) { updateTextLength(); }
|
|
|
|
|
|
|
|
public void
|
|
|
|
keyReleased(KeyEvent eK) { }
|
|
|
|
|
|
|
|
public void
|
|
|
|
keyTyped(KeyEvent eK) { }
|
|
|
|
|
|
|
|
private void
|
|
|
|
updateTextLength()
|
|
|
|
{
|
|
|
|
int length = text.getText().length();
|
|
|
|
/*
|
|
|
|
* The web interface doesn't do this expensive thing.
|
|
|
|
* It has an upwards counter, incremented by I'm not
|
|
|
|
* sure what. Presumably they have some control over
|
|
|
|
* the text input. I'd rather not, cause I use a
|
|
|
|
* Japanese IME, I'm going to see how laggy this is.
|
|
|
|
* It raises our app's system requirements, but, I was
|
|
|
|
* going to transition it to multithreading anyways,
|
|
|
|
* I don't think we're going to be very cheap.. Which
|
|
|
|
* sucks, but the Mastodon API is not helping us here.
|
|
|
|
*/
|
|
|
|
textLength.setText(Integer.toString(length));
|
|
|
|
/*
|
|
|
|
* Another thing I could do is temporarily move the
|
|
|
|
* caret to the end and then find its position, then
|
|
|
|
* seek back. Not sure how much that would help, but
|
|
|
|
* if this is too laggy, that's what I'd try next.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
2021-07-28 22:23:42 +02:00
|
|
|
// ---%-@-%---
|
|
|
|
|
|
|
|
ComposeComponent(ComposeWindow primaire)
|
|
|
|
{
|
|
|
|
this.primaire = primaire;
|
|
|
|
|
2022-05-01 08:46:10 +02:00
|
|
|
Border b1 = BorderFactory.createEmptyBorder(8, 8, 8, 8);
|
|
|
|
Border b2 = BorderFactory.createEmptyBorder(4, 4, 4, 4);
|
|
|
|
Border b3 = BorderFactory.createLineBorder(Color.GRAY);
|
|
|
|
Border bc = BorderFactory.createCompoundBorder(b3, b2);
|
|
|
|
|
2022-04-12 08:37:39 +02:00
|
|
|
reply = new JTextField();
|
2022-04-14 06:38:49 +02:00
|
|
|
JLabel replyLabel = new JLabel("In reply to: ");
|
|
|
|
replyLabel.setLabelFor(reply);
|
|
|
|
|
|
|
|
contentWarning = new JTextField();
|
|
|
|
JLabel cwLabel = new JLabel("Content warning: ");
|
|
|
|
cwLabel.setLabelFor(contentWarning);
|
|
|
|
|
|
|
|
JPanel top = new JPanel();
|
|
|
|
top.setOpaque(false);
|
|
|
|
top.setLayout(new GridLayout(2, 2, 8, 0));
|
|
|
|
top.add(replyLabel);
|
|
|
|
top.add(reply);
|
|
|
|
top.add(cwLabel);
|
|
|
|
top.add(contentWarning);
|
2021-07-17 11:06:50 +02:00
|
|
|
|
2022-05-06 09:05:01 +02:00
|
|
|
textLength = new JLabel("0");
|
|
|
|
textLength.setFont(textLength.getFont().deriveFont(14f));
|
|
|
|
|
2021-07-28 22:23:42 +02:00
|
|
|
visibility = new JComboBox<>(new String[] {
|
|
|
|
"Public",
|
2022-04-12 08:37:39 +02:00
|
|
|
"Unlisted",
|
2021-07-28 22:23:42 +02:00
|
|
|
"Followers",
|
|
|
|
"Mentioned"
|
2021-07-28 23:55:30 +02:00
|
|
|
// Where should we be saving strings..
|
2021-07-28 22:23:42 +02:00
|
|
|
});
|
|
|
|
visibility.setPreferredSize(new Dimension(64, 24));
|
|
|
|
|
2021-07-17 11:06:50 +02:00
|
|
|
submit = new JButton("Submit");
|
2021-07-28 22:23:42 +02:00
|
|
|
submit.addActionListener(this);
|
2021-07-17 11:06:50 +02:00
|
|
|
|
|
|
|
Box bottom = Box.createHorizontalBox();
|
|
|
|
bottom.add(Box.createGlue());
|
2022-05-06 09:05:01 +02:00
|
|
|
bottom.add(textLength);
|
|
|
|
bottom.add(Box.createHorizontalStrut(12));
|
2021-07-28 22:23:42 +02:00
|
|
|
bottom.add(visibility);
|
2022-05-06 09:05:01 +02:00
|
|
|
bottom.add(Box.createHorizontalStrut(12));
|
2021-07-17 11:06:50 +02:00
|
|
|
bottom.add(submit);
|
|
|
|
|
2022-04-14 06:38:49 +02:00
|
|
|
text = new JTextArea();
|
|
|
|
text.setLineWrap(true);
|
|
|
|
text.setWrapStyleWord(true);
|
2022-05-01 08:46:10 +02:00
|
|
|
text.setFont(text.getFont().deriveFont(16f));
|
|
|
|
text.setBorder(bc);
|
2022-05-06 09:05:01 +02:00
|
|
|
text.addCaretListener(this);
|
|
|
|
text.addKeyListener(this);
|
2022-04-12 08:37:39 +02:00
|
|
|
|
2021-07-17 11:06:50 +02:00
|
|
|
setLayout(new BorderLayout(0, 8));
|
2022-04-12 08:37:39 +02:00
|
|
|
add(top, BorderLayout.NORTH);
|
2021-07-17 11:06:50 +02:00
|
|
|
add(text, BorderLayout.CENTER);
|
|
|
|
add(bottom, BorderLayout.SOUTH);
|
|
|
|
|
2022-05-01 08:46:10 +02:00
|
|
|
setBorder(b1);
|
2021-07-17 11:06:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|