mirror of
https://gitlab.com/biskuteri-cafe/JKomasto2.git
synced 2025-01-08 02:54:45 +01:00
Added delete feature
This commit is contained in:
parent
26d4e8c97a
commit
0590cc6c19
@ -51,7 +51,7 @@ ComposeWindow extends JFrame {
|
||||
{
|
||||
composition = new Composition();
|
||||
composition.text = "";
|
||||
composition.visibility = PostVisibility.MENTIONED;
|
||||
composition.visibility = PostVisibility.UNLISTED;
|
||||
composition.replyToPostId = null;
|
||||
composition.contentWarning = null;
|
||||
syncDisplayToComposition();
|
||||
|
@ -351,6 +351,27 @@ MastodonApi {
|
||||
catch (IOException eIo) { handler.connectionFailed(eIo); }
|
||||
}
|
||||
|
||||
public void
|
||||
deletePost(String postId, RequestListener handler)
|
||||
{
|
||||
String token = accessToken.get("access_token").value;
|
||||
|
||||
String url = instanceUrl + "/api/v1/statuses/" + postId;
|
||||
try
|
||||
{
|
||||
URL endpoint = new URL(url);
|
||||
HttpURLConnection conn;
|
||||
conn = (HttpURLConnection)endpoint.openConnection();
|
||||
String s1 = "Bearer " + token;
|
||||
conn.setRequestProperty("Authorization", s1);
|
||||
conn.setRequestMethod("DELETE");
|
||||
conn.connect();
|
||||
|
||||
doStandardJsonReturn(conn, handler);
|
||||
}
|
||||
catch (IOException eIo) { handler.connectionFailed(eIo); }
|
||||
}
|
||||
|
||||
public void
|
||||
getAccounts(String query, RequestListener handler)
|
||||
{
|
||||
|
@ -132,13 +132,14 @@ NotificationsWindow extends JFrame {
|
||||
if (n.type != NotificationType.FOLLOW)
|
||||
{
|
||||
Tree<String> post = t.get("status");
|
||||
String pid = post.get("id").value;
|
||||
String ptext = post.get("content").value;
|
||||
String pid, phtml, ptext;
|
||||
pid = post.get("id").value;
|
||||
phtml = post.get("content").value;
|
||||
ptext =
|
||||
TimelineComponent
|
||||
.textApproximation(phtml);
|
||||
n.postId = pid;
|
||||
n.postText = ptext;
|
||||
// Should we ask TimelineWindow for help here?
|
||||
// Or should we break our text parsers into
|
||||
// a separate class?
|
||||
}
|
||||
|
||||
notifications.add(n);
|
||||
@ -162,7 +163,7 @@ NotificationsWindow extends JFrame {
|
||||
notifications = new ArrayList<>();
|
||||
|
||||
display = new NotificationsComponent(this);
|
||||
display.setPreferredSize(new Dimension(256, 400));
|
||||
display.setPreferredSize(new Dimension(256, 260));
|
||||
setContentPane(display);
|
||||
pack();
|
||||
|
||||
@ -190,7 +191,7 @@ implements ActionListener {
|
||||
// - -%- -
|
||||
|
||||
static final int
|
||||
ROW_COUNT = 16;
|
||||
ROW_COUNT = 10;
|
||||
|
||||
// ---%-@-%---
|
||||
|
||||
@ -203,7 +204,16 @@ implements ActionListener {
|
||||
Notification n = notifications.get(o);
|
||||
NotificationComponent c = rows.get(o);
|
||||
c.setName(n.actorName);
|
||||
c.setType(n.type.toString());
|
||||
switch (n.type)
|
||||
{
|
||||
case MENTION: c.setType("mentioned"); break;
|
||||
case BOOST: c.setType("boosted"); break;
|
||||
case FAVOURITE: c.setType("favourited"); break;
|
||||
case FOLLOW: c.setType("followed"); break;
|
||||
case FOLLOWREQ: c.setType("req. follow"); break;
|
||||
case POLL: c.setType("poll ended"); break;
|
||||
case ALERT: c.setType("posted"); break;
|
||||
}
|
||||
c.setText(n.postText);
|
||||
}
|
||||
}
|
||||
@ -279,13 +289,13 @@ implements ComponentListener {
|
||||
componentResized(ComponentEvent eC)
|
||||
{
|
||||
int w = getWidth(), h = getHeight();
|
||||
name.setPreferredSize(new Dimension(w * 4 / 10, h));
|
||||
type.setPreferredSize(new Dimension(w * 3 / 10, h));
|
||||
text.setPreferredSize(new Dimension(w * 2 / 10, h));
|
||||
name.setPreferredSize(new Dimension(w * 7 / 20, h));
|
||||
type.setPreferredSize(new Dimension(w * 6 / 20, h));
|
||||
text.setPreferredSize(new Dimension(w * 5 / 20, h));
|
||||
|
||||
name.setMaximumSize(new Dimension(w * 4 / 10, h));
|
||||
type.setMaximumSize(new Dimension(w * 3 / 10, h));
|
||||
text.setMaximumSize(new Dimension(w * 2 / 10, h));
|
||||
name.setMaximumSize(new Dimension(w * 7 / 20, h));
|
||||
type.setMaximumSize(new Dimension(w * 6 / 20, h));
|
||||
text.setMaximumSize(new Dimension(w * 5 / 20, h));
|
||||
}
|
||||
|
||||
public void
|
||||
@ -301,9 +311,13 @@ implements ComponentListener {
|
||||
|
||||
NotificationComponent()
|
||||
{
|
||||
Font f1 = new Font("Dialog", Font.PLAIN, 12);
|
||||
Font f2 = new Font("Dialog", Font.PLAIN, 10);
|
||||
Font f3 = new Font("Dialog", Font.ITALIC, 12);
|
||||
Font f = new Font("Dialog", Font.PLAIN, 12);
|
||||
Font f1 = f.deriveFont(Font.PLAIN, 14);
|
||||
Font f2 = f.deriveFont(Font.PLAIN, 11);
|
||||
Font f3 = f.deriveFont(Font.ITALIC, 14);
|
||||
|
||||
Color c = new Color(0, 0, 0, 25);
|
||||
Border b1 = BorderFactory.createMatteBorder(0, 0, 1, 0, c);
|
||||
|
||||
name = new JLabel();
|
||||
type = new JLabel();
|
||||
@ -314,17 +328,16 @@ implements ComponentListener {
|
||||
type.setHorizontalAlignment(JLabel.RIGHT);
|
||||
|
||||
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
|
||||
add(Box.createHorizontalStrut(4));
|
||||
add(name);
|
||||
add(Box.createHorizontalStrut(4));
|
||||
add(Box.createHorizontalStrut(8));
|
||||
add(type);
|
||||
add(Box.createHorizontalStrut(4));
|
||||
add(Box.createHorizontalStrut(8));
|
||||
add(text);
|
||||
add(Box.createHorizontalStrut(4));
|
||||
|
||||
this.addComponentListener(this);
|
||||
setBorder(
|
||||
BorderFactory.createMatteBorder
|
||||
(1, 0, 0, 0, new Color(0, 0, 0, 25))
|
||||
);
|
||||
setBorder(b1);
|
||||
}
|
||||
|
||||
}
|
160
PostWindow.java
160
PostWindow.java
@ -2,7 +2,7 @@
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
@ -86,6 +86,10 @@ implements ActionListener {
|
||||
postDisplay.setAuthorName(an);
|
||||
postDisplay.setAuthorId(author.get("acct").value);
|
||||
|
||||
String aid = author.get("id").value;
|
||||
String oid = api.getAccountDetails().get("id").value;
|
||||
postDisplay.setDeleteEnabled(aid.equals(oid));
|
||||
|
||||
String avurl = author.get("avatar").value;
|
||||
postDisplay.setAuthorAvatar(ImageApi.remote(avurl));
|
||||
|
||||
@ -255,7 +259,7 @@ implements ActionListener {
|
||||
if (vs.equals("unlisted")) v = PostVisibility.UNLISTED;
|
||||
if (vs.equals("private")) v = PostVisibility.FOLLOWERS;
|
||||
if (vs.equals("direct")) v = PostVisibility.MENTIONED;
|
||||
|
||||
|
||||
Composition c = new Composition();
|
||||
c.contentWarning = cw;
|
||||
c.text = id1.equals(id2) ? "" : "@" + authorId + " ";
|
||||
@ -300,6 +304,112 @@ implements ActionListener {
|
||||
}
|
||||
}
|
||||
|
||||
public void
|
||||
deletePost(boolean redraft)
|
||||
{
|
||||
postDisplay.setCursor(new Cursor(Cursor.WAIT_CURSOR));
|
||||
postDisplay.setDeleteEnabled(false);
|
||||
postDisplay.paintImmediately(postDisplay.getBounds());
|
||||
|
||||
if (redraft)
|
||||
{
|
||||
String html = post.get("content").value;
|
||||
StringBuilder b = new StringBuilder();
|
||||
Tree<String> nodes;
|
||||
nodes = RudimentaryHTMLParser.depthlessRead(html);
|
||||
// We have to salvage whatever we can from the HTML.
|
||||
for (Tree<String> node: nodes)
|
||||
{
|
||||
if (node.key.equals("text"))
|
||||
{
|
||||
b.append(node.value);
|
||||
}
|
||||
if (node.key.equals("emoji"))
|
||||
{
|
||||
b.append(":" + node.value + ":");
|
||||
}
|
||||
if (node.key.equals("tag"))
|
||||
{
|
||||
if (node.get(0).key.equals("/p"))
|
||||
b.append("\n\n");
|
||||
if (node.get(0).key.equals("br"))
|
||||
b.append("\n");
|
||||
if (node.get(0).key.equals("a")) {
|
||||
b.append(node.get("href").value);
|
||||
b.append(" ");
|
||||
continue;
|
||||
/*
|
||||
* We don't omit the contents of the <a>
|
||||
* which is an automatic label, but we'll
|
||||
* need a non-depthless parser to omit that.
|
||||
* For now prioritise not losing anything
|
||||
* from our composition.
|
||||
*/
|
||||
}
|
||||
// I think that's all. I hope.
|
||||
}
|
||||
}
|
||||
|
||||
String cw = post.get("spoiler_text").value;
|
||||
|
||||
String vs = post.get("visibility").value;
|
||||
PostVisibility v = null;
|
||||
if (vs.equals("public")) v = PostVisibility.PUBLIC;
|
||||
if (vs.equals("unlisted")) v = PostVisibility.UNLISTED;
|
||||
if (vs.equals("private")) v = PostVisibility.FOLLOWERS;
|
||||
if (vs.equals("direct")) v = PostVisibility.MENTIONED;
|
||||
|
||||
String replyTo = post.get("in_reply_to_id").value;
|
||||
|
||||
Composition c = new Composition();
|
||||
c.contentWarning = cw;
|
||||
c.text = b.toString();
|
||||
c.visibility = v;
|
||||
c.replyToPostId = replyTo;
|
||||
|
||||
ComposeWindow w = primaire.getComposeWindow();
|
||||
w.setLocation(getX(), getY() + 100);
|
||||
w.setVisible(true);
|
||||
w.setComposition(c);
|
||||
}
|
||||
|
||||
api.deletePost(post.get("id").value, new RequestListener() {
|
||||
|
||||
public void
|
||||
connectionFailed(IOException eIo)
|
||||
{
|
||||
JOptionPane.showMessageDialog(
|
||||
PostWindow.this,
|
||||
"Failed to delete post.."
|
||||
+ "\n" + eIo.getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
public void
|
||||
requestFailed(int httpCode, Tree<String> json)
|
||||
{
|
||||
JOptionPane.showMessageDialog(
|
||||
PostWindow.this,
|
||||
"Failed to delete post.."
|
||||
+ "\n" + json.get("error").value
|
||||
+ "\n(HTTP code: " + httpCode + ")"
|
||||
);
|
||||
}
|
||||
|
||||
public void
|
||||
requestSucceeded(Tree<String> json)
|
||||
{
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
postDisplay.setCursor(null);
|
||||
postDisplay.setDeleteEnabled(true);
|
||||
postDisplay.paintImmediately(postDisplay.getBounds());
|
||||
if (!isVisible()) dispose();
|
||||
}
|
||||
|
||||
// - -%- -
|
||||
|
||||
public void
|
||||
@ -379,6 +489,13 @@ implements ActionListener {
|
||||
profile,
|
||||
media;
|
||||
|
||||
private JPopupMenu
|
||||
miscMenu;
|
||||
|
||||
private JMenuItem
|
||||
deletePost,
|
||||
redraftPost;
|
||||
|
||||
// ---%-@-%---
|
||||
|
||||
public void
|
||||
@ -475,6 +592,13 @@ implements ActionListener {
|
||||
favouriteBoost.setEnabled(a);
|
||||
}
|
||||
|
||||
public void
|
||||
setDeleteEnabled(boolean a)
|
||||
{
|
||||
deletePost.setEnabled(a);
|
||||
redraftPost.setEnabled(a);
|
||||
}
|
||||
|
||||
public void
|
||||
setMediaPreview(Image n) { media.setImage(n); }
|
||||
|
||||
@ -510,7 +634,14 @@ implements ActionListener {
|
||||
|
||||
if (src == replyMisc)
|
||||
{
|
||||
if (command.startsWith("reply")) primaire.reply();
|
||||
if (command.startsWith("reply"))
|
||||
primaire.reply();
|
||||
if (command.startsWith("misc"))
|
||||
{
|
||||
int rx = replyMisc.getWidth() / 2;
|
||||
int ry = replyMisc.getHeight() - miscMenu.getHeight();
|
||||
miscMenu.show(replyMisc, rx, ry);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -531,7 +662,20 @@ implements ActionListener {
|
||||
{
|
||||
primaire.openMedia();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (src == deletePost)
|
||||
{
|
||||
primaire.deletePost(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (src == redraftPost)
|
||||
{
|
||||
primaire.deletePost(true);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void
|
||||
@ -584,6 +728,14 @@ implements ActionListener {
|
||||
nextPrev.addActionListener(this);
|
||||
media.addActionListener(this);
|
||||
|
||||
deletePost = new JMenuItem("Delete post");
|
||||
redraftPost = new JMenuItem("Delete and redraft post");
|
||||
deletePost.addActionListener(this);
|
||||
redraftPost.addActionListener(this);
|
||||
miscMenu = new JPopupMenu();
|
||||
miscMenu.add(deletePost);
|
||||
miscMenu.add(redraftPost);
|
||||
|
||||
Box buttons = Box.createVerticalBox();
|
||||
buttons.setOpaque(false);
|
||||
buttons.add(profile);
|
||||
|
@ -26,26 +26,6 @@ RudimentaryHTMLParser {
|
||||
}
|
||||
}
|
||||
|
||||
public static String
|
||||
stripTags(String html)
|
||||
{
|
||||
StringBuilder returnee = new StringBuilder();
|
||||
for (Tree<String> node: depthlessRead(html))
|
||||
{
|
||||
if (node.key.equals("tag")) continue;
|
||||
|
||||
if (node.key.equals("emoji"))
|
||||
{
|
||||
returnee.append(":" + node.value + ":");
|
||||
}
|
||||
if (node.key.equals("text"))
|
||||
{
|
||||
returnee.append(node.value);
|
||||
}
|
||||
}
|
||||
return returnee.toString();
|
||||
}
|
||||
|
||||
// - -%- -
|
||||
|
||||
private static Tree<String>
|
||||
|
@ -450,7 +450,7 @@ implements ActionListener {
|
||||
}
|
||||
}
|
||||
|
||||
// - -%- -
|
||||
// - -%- -
|
||||
|
||||
private static String
|
||||
plainify(String html)
|
||||
@ -620,12 +620,10 @@ implements
|
||||
|
||||
String html = p.get("content").value;
|
||||
String cw = p.get("spoiler_text").value;
|
||||
if (!cw.isEmpty()) {
|
||||
if (!cw.isEmpty())
|
||||
c.setBottom("(" + cw + ")");
|
||||
}
|
||||
else {
|
||||
c.setBottom(RudimentaryHTMLParser.stripTags(html) + " ");
|
||||
}
|
||||
else
|
||||
c.setBottom(textApproximation(html) + " ");
|
||||
}
|
||||
for (int o = posts.size(); o < postPreviews.size(); ++o)
|
||||
{
|
||||
@ -781,6 +779,34 @@ implements
|
||||
public void
|
||||
keyReleased(KeyEvent eK) { }
|
||||
|
||||
// - -%- -
|
||||
|
||||
public static String
|
||||
textApproximation(String html)
|
||||
{
|
||||
StringBuilder returnee = new StringBuilder();
|
||||
Tree<String> nodes = RudimentaryHTMLParser.depthlessRead(html);
|
||||
Tree<String> first = nodes.get(0);
|
||||
for (Tree<String> node: nodes)
|
||||
{
|
||||
if (node.key.equals("tag"))
|
||||
{
|
||||
if (node.get(0).key.equals("br"))
|
||||
returnee.append("; ");
|
||||
if (node.get(0).key.equals("p") && node != first)
|
||||
returnee.append("; ");
|
||||
}
|
||||
if (node.key.equals("emoji"))
|
||||
{
|
||||
returnee.append(":" + node.value + ":");
|
||||
}
|
||||
if (node.key.equals("text"))
|
||||
{
|
||||
returnee.append(node.value);
|
||||
}
|
||||
}
|
||||
return returnee.toString();
|
||||
}
|
||||
// ---%-@-%---
|
||||
|
||||
TimelineComponent(TimelineWindow primaire)
|
||||
|
Loading…
Reference in New Issue
Block a user