mirror of
https://gitlab.com/biskuteri-cafe/JKomasto2.git
synced 2025-01-23 18:51:43 +01:00
Moved most JSON parsing code to windows.
Made windows use JSON as data store.
This commit is contained in:
parent
a033a23ab9
commit
117503c5f2
@ -8,6 +8,7 @@ import java.awt.Cursor;
|
|||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
import cafe.biskuteri.hinoki.Tree;
|
||||||
|
|
||||||
|
|
||||||
class
|
class
|
||||||
@ -153,53 +154,12 @@ TimelinePage {
|
|||||||
public String
|
public String
|
||||||
accountNumId, listId;
|
accountNumId, listId;
|
||||||
|
|
||||||
public List<Post>
|
public Tree<String>
|
||||||
posts;
|
posts;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class
|
|
||||||
Post {
|
|
||||||
|
|
||||||
public String
|
|
||||||
text,
|
|
||||||
contentWarning,
|
|
||||||
html;
|
|
||||||
|
|
||||||
public String
|
|
||||||
authorId, authorName;
|
|
||||||
|
|
||||||
public Image
|
|
||||||
authorAvatar;
|
|
||||||
|
|
||||||
public String
|
|
||||||
authorNumId;
|
|
||||||
|
|
||||||
public String
|
|
||||||
boosterName;
|
|
||||||
|
|
||||||
public ZonedDateTime
|
|
||||||
date;
|
|
||||||
|
|
||||||
public PostVisibility
|
|
||||||
visibility;
|
|
||||||
|
|
||||||
public String
|
|
||||||
postId;
|
|
||||||
|
|
||||||
public boolean
|
|
||||||
boosted, favourited;
|
|
||||||
|
|
||||||
public Attachment[]
|
|
||||||
attachments;
|
|
||||||
|
|
||||||
public String[][]
|
|
||||||
emojiUrls;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class
|
class
|
||||||
Notification {
|
Notification {
|
||||||
|
|
||||||
|
195
PostWindow.java
195
PostWindow.java
@ -30,12 +30,14 @@ import java.util.List;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import cafe.biskuteri.hinoki.Tree;
|
import cafe.biskuteri.hinoki.Tree;
|
||||||
import java.text.BreakIterator;
|
import java.text.BreakIterator;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class
|
class
|
||||||
@ -48,8 +50,8 @@ implements ActionListener {
|
|||||||
private MastodonApi
|
private MastodonApi
|
||||||
api;
|
api;
|
||||||
|
|
||||||
private Post
|
private Tree<String>
|
||||||
post;
|
post;
|
||||||
|
|
||||||
// - -%- -
|
// - -%- -
|
||||||
|
|
||||||
@ -67,53 +69,58 @@ implements ActionListener {
|
|||||||
|
|
||||||
// ---%-@-%---
|
// ---%-@-%---
|
||||||
|
|
||||||
public void
|
public void
|
||||||
showPost(Post post)
|
displayEntity(Tree<String> post)
|
||||||
{
|
{
|
||||||
assert post != null;
|
|
||||||
this.post = post;
|
this.post = post;
|
||||||
|
|
||||||
List<RepliesComponent.Reply> replies = null;
|
Tree<String> boosted = post.get("reblog");
|
||||||
{
|
if (boosted.size() > 0) post = boosted;
|
||||||
List<Post> posts = null;
|
|
||||||
// We should make a request to JKomasto here.
|
|
||||||
}
|
|
||||||
if (replies == null)
|
|
||||||
{
|
|
||||||
RepliesComponent.Reply reply1, reply2, reply3;
|
|
||||||
reply1 = new RepliesComponent.Reply();
|
|
||||||
reply1.author = "Black tea";
|
|
||||||
reply1.text = "Rich..";
|
|
||||||
reply2 = new RepliesComponent.Reply();
|
|
||||||
reply2.author = "Green tea";
|
|
||||||
reply2.text = "Clean!";
|
|
||||||
reply3 = new RepliesComponent.Reply();
|
|
||||||
reply3.author = "Coffee";
|
|
||||||
reply3.text = "sleepy..";
|
|
||||||
|
|
||||||
replies = new ArrayList<>();
|
Tree<String> author = post.get("account");
|
||||||
replies.add(reply1);
|
Tree<String> emojis = post.get("emojis");
|
||||||
replies.add(reply2);
|
Tree<String> media = post.get("media_attachments");
|
||||||
replies.add(reply3);
|
|
||||||
}
|
|
||||||
|
|
||||||
postDisplay.setAuthorName(post.authorName);
|
String an = author.get("display_name").value;
|
||||||
postDisplay.setAuthorId(post.authorId);
|
if (an.isEmpty()) an = author.get("username").value;
|
||||||
postDisplay.setAuthorAvatar(post.authorAvatar);
|
postDisplay.setAuthorName(an);
|
||||||
postDisplay.setDate(DATE_FORMAT.format(post.date));
|
postDisplay.setAuthorId(author.get("acct").value);
|
||||||
postDisplay.setTime(TIME_FORMAT.format(post.date));
|
|
||||||
postDisplay.setEmojiUrls(post.emojiUrls);
|
String avurl = author.get("avatar").value;
|
||||||
postDisplay.setText(post.text);
|
postDisplay.setAuthorAvatar(ImageApi.remote(avurl));
|
||||||
postDisplay.setHtml(post.html);
|
|
||||||
postDisplay.setFavourited(post.favourited);
|
String sdate = post.get("created_at").value;
|
||||||
postDisplay.setBoosted(post.boosted);
|
ZonedDateTime date = ZonedDateTime.parse(sdate);
|
||||||
postDisplay.setMediaPreview(
|
date = date.withZoneSameInstant(ZoneId.systemDefault());
|
||||||
post.attachments.length == 0
|
postDisplay.setDate(DATE_FORMAT.format(date));
|
||||||
? null
|
postDisplay.setTime(TIME_FORMAT.format(date));
|
||||||
: post.attachments[0].image
|
|
||||||
);
|
String[][] emojiUrls = new String[emojis.size()][];
|
||||||
|
for (int o = 0; o < emojiUrls.length; ++o) {
|
||||||
|
Tree<String> emoji = emojis.get(o);
|
||||||
|
emojiUrls[o] = new String[2];
|
||||||
|
emojiUrls[o][0] = emoji.get("shortcode").value;
|
||||||
|
emojiUrls[o][1] = emoji.get("url").value;
|
||||||
|
}
|
||||||
|
postDisplay.setEmojiUrls(emojiUrls);
|
||||||
|
|
||||||
|
postDisplay.setHtml(post.get("content").value);
|
||||||
|
boolean f = post.get("favourited").value.equals("true");
|
||||||
|
boolean b = post.get("reblogged").value.equals("true");
|
||||||
|
postDisplay.setFavourited(f);
|
||||||
|
postDisplay.setBoosted(b);
|
||||||
|
|
||||||
|
if (media.size() > 0)
|
||||||
|
{
|
||||||
|
Tree<String> first = media.get(0);
|
||||||
|
String u1 = first.get("remote_url").value;
|
||||||
|
String u2 = first.get("text_url").value;
|
||||||
|
String u3 = first.get("url").value;
|
||||||
|
String purl = u1 != null ? u1 : u2 != null ? u2 : u3;
|
||||||
|
postDisplay.setMediaPreview(ImageApi.remote(purl));
|
||||||
|
}
|
||||||
|
else postDisplay.setMediaPreview(null);
|
||||||
|
|
||||||
repliesDisplay.setReplies(replies);
|
|
||||||
postDisplay.resetFocus();
|
postDisplay.resetFocus();
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
@ -121,8 +128,12 @@ implements ActionListener {
|
|||||||
public void
|
public void
|
||||||
openAuthorProfile()
|
openAuthorProfile()
|
||||||
{
|
{
|
||||||
TimelineWindow w = new TimelineWindow(primaire);
|
Tree<String> post = this.post;
|
||||||
w.showAuthorPosts(post.authorNumId);
|
Tree<String> boosted = post.get("reblog");
|
||||||
|
if (boosted.size() > 0) post = boosted;
|
||||||
|
|
||||||
|
TimelineWindow w = new TimelineWindow(primaire);
|
||||||
|
w.showAuthorPosts(post.get("account").get("id").value);
|
||||||
w.showLatestPage();
|
w.showLatestPage();
|
||||||
w.setLocationRelativeTo(this);
|
w.setLocationRelativeTo(this);
|
||||||
w.setVisible(true);
|
w.setVisible(true);
|
||||||
@ -131,6 +142,10 @@ implements ActionListener {
|
|||||||
public void
|
public void
|
||||||
favourite(boolean favourited)
|
favourite(boolean favourited)
|
||||||
{
|
{
|
||||||
|
Tree<String> post = this.post;
|
||||||
|
Tree<String> boosted = post.get("reblog");
|
||||||
|
if (boosted.size() > 0) post = boosted;
|
||||||
|
|
||||||
postDisplay.setCursor(new Cursor(Cursor.WAIT_CURSOR));
|
postDisplay.setCursor(new Cursor(Cursor.WAIT_CURSOR));
|
||||||
postDisplay.setFavouriteBoostEnabled(false);
|
postDisplay.setFavouriteBoostEnabled(false);
|
||||||
postDisplay.paintImmediately(postDisplay.getBounds());
|
postDisplay.paintImmediately(postDisplay.getBounds());
|
||||||
@ -160,11 +175,13 @@ implements ActionListener {
|
|||||||
public void
|
public void
|
||||||
requestSucceeded(Tree<String> json)
|
requestSucceeded(Tree<String> json)
|
||||||
{
|
{
|
||||||
post.favourited = favourited;
|
String n = Boolean.toString(favourited);
|
||||||
|
PostWindow.this.post.get("favourited").value = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
api.setPostFavourited(post.postId, favourited, handler);
|
String postId = post.get("id").value;
|
||||||
|
api.setPostFavourited(postId, favourited, handler);
|
||||||
postDisplay.setCursor(null);
|
postDisplay.setCursor(null);
|
||||||
postDisplay.setFavouriteBoostEnabled(true);
|
postDisplay.setFavouriteBoostEnabled(true);
|
||||||
postDisplay.repaint();
|
postDisplay.repaint();
|
||||||
@ -173,6 +190,10 @@ implements ActionListener {
|
|||||||
public void
|
public void
|
||||||
boost(boolean boosted)
|
boost(boolean boosted)
|
||||||
{
|
{
|
||||||
|
Tree<String> post = this.post;
|
||||||
|
Tree<String> boosted2 = post.get("reblog");
|
||||||
|
if (boosted2.size() > 0) post = boosted2;
|
||||||
|
|
||||||
postDisplay.setCursor(new Cursor(Cursor.WAIT_CURSOR));
|
postDisplay.setCursor(new Cursor(Cursor.WAIT_CURSOR));
|
||||||
postDisplay.setFavouriteBoostEnabled(false);
|
postDisplay.setFavouriteBoostEnabled(false);
|
||||||
postDisplay.paintImmediately(postDisplay.getBounds());
|
postDisplay.paintImmediately(postDisplay.getBounds());
|
||||||
@ -202,11 +223,13 @@ implements ActionListener {
|
|||||||
public void
|
public void
|
||||||
requestSucceeded(Tree<String> json)
|
requestSucceeded(Tree<String> json)
|
||||||
{
|
{
|
||||||
post.boosted = boosted;
|
String n = Boolean.toString(boosted);
|
||||||
|
PostWindow.this.post.get("reblogged").value = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
api.setPostBoosted(post.postId, boosted, handler);
|
String postId = post.get("id").value;
|
||||||
|
api.setPostBoosted(postId, boosted, handler);
|
||||||
postDisplay.setCursor(null);
|
postDisplay.setCursor(null);
|
||||||
postDisplay.setFavouriteBoostEnabled(true);
|
postDisplay.setFavouriteBoostEnabled(true);
|
||||||
postDisplay.repaint();
|
postDisplay.repaint();
|
||||||
@ -215,23 +238,57 @@ implements ActionListener {
|
|||||||
public void
|
public void
|
||||||
reply()
|
reply()
|
||||||
{
|
{
|
||||||
|
Tree<String> post = this.post;
|
||||||
|
Tree<String> boosted = post.get("reblog");
|
||||||
|
if (boosted.size() > 0) post = boosted;
|
||||||
|
|
||||||
|
String authorId = post.get("account").get("acct").value;
|
||||||
|
String postId = post.get("id").value;
|
||||||
|
String cw = post.get("spoiler_text").value;
|
||||||
|
String ourId = api.getAccountDetails().get("acct").value;
|
||||||
|
boolean replying = authorId != ourId;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
Composition c = new Composition();
|
||||||
|
c.contentWarning = cw;
|
||||||
|
c.text = replying ? "@" + authorId + " " : "";
|
||||||
|
c.visibility = v;
|
||||||
|
c.replyToPostId = postId;
|
||||||
|
|
||||||
ComposeWindow w = primaire.getComposeWindow();
|
ComposeWindow w = primaire.getComposeWindow();
|
||||||
w.setLocation(getX(), getY() + 100);
|
w.setLocation(getX(), getY() + 100);
|
||||||
w.setVisible(true);
|
w.setVisible(true);
|
||||||
Composition c = new Composition();
|
w.setComposition(c);
|
||||||
c.text = "@" + post.authorId + " ";
|
|
||||||
c.visibility = PostVisibility.PUBLIC;
|
|
||||||
c.replyToPostId = post.postId;
|
|
||||||
w.setComposition(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void
|
public void
|
||||||
openMedia()
|
openMedia()
|
||||||
{
|
{
|
||||||
|
Tree<String> media = post.get("media_attachments");
|
||||||
|
Attachment[] as = new Attachment[media.size()];
|
||||||
|
for (int o = 0; o < as.length; ++o)
|
||||||
|
{
|
||||||
|
Tree<String> medium = media.get(o);
|
||||||
|
String u1 = medium.get("remote_url").value;
|
||||||
|
String u2 = medium.get("text_url").value;
|
||||||
|
String u3 = medium.get("url").value;
|
||||||
|
|
||||||
|
Attachment a = as[o] = new Attachment();
|
||||||
|
a.url = u1 != null ? u1 : u2 != null ? u2 : u3;
|
||||||
|
a.type = medium.get("type").value;
|
||||||
|
a.description = medium.get("description").value;
|
||||||
|
a.image = ImageApi.remote(a.url);
|
||||||
|
}
|
||||||
|
|
||||||
ImageWindow w = primaire.getMediaWindow();
|
ImageWindow w = primaire.getMediaWindow();
|
||||||
w.showAttachments(post.attachments);
|
w.setTitle(post.get("id").value);
|
||||||
int l = Math.min(40, post.text.length());
|
w.showAttachments(as);
|
||||||
w.setTitle(post.text.substring(0, l));
|
|
||||||
if (!w.isVisible()) {
|
if (!w.isVisible()) {
|
||||||
w.setLocationRelativeTo(null);
|
w.setLocationRelativeTo(null);
|
||||||
w.setVisible(true);
|
w.setVisible(true);
|
||||||
@ -278,23 +335,8 @@ implements ActionListener {
|
|||||||
setLocationByPlatform(true);
|
setLocationByPlatform(true);
|
||||||
|
|
||||||
postDisplay = new PostComponent(this);
|
postDisplay = new PostComponent(this);
|
||||||
|
|
||||||
repliesDisplay = new RepliesComponent();
|
repliesDisplay = new RepliesComponent();
|
||||||
|
|
||||||
Post samplePost = new Post();
|
|
||||||
samplePost.text = "This is a sample post.";
|
|
||||||
samplePost.html = "";
|
|
||||||
samplePost.authorId = "snowyfox@biskuteri.cafe";
|
|
||||||
samplePost.authorName = "snowyfox";
|
|
||||||
samplePost.date = ZonedDateTime.now();
|
|
||||||
samplePost.visibility = PostVisibility.MENTIONED;
|
|
||||||
samplePost.postId = "000000000";
|
|
||||||
samplePost.boosted = false;
|
|
||||||
samplePost.favourited = true;
|
|
||||||
samplePost.attachments = new Attachment[0];
|
|
||||||
samplePost.emojiUrls = new String[0][];
|
|
||||||
showPost(samplePost);
|
|
||||||
|
|
||||||
setContentPane(postDisplay);
|
setContentPane(postDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,9 +394,6 @@ implements ActionListener {
|
|||||||
public void
|
public void
|
||||||
setTime(String n) { time.setText(n); }
|
setTime(String n) { time.setText(n); }
|
||||||
|
|
||||||
public void
|
|
||||||
setText(String n) { }
|
|
||||||
|
|
||||||
public void
|
public void
|
||||||
setEmojiUrls(String[][] n) { emojiUrls = n; }
|
setEmojiUrls(String[][] n) { emojiUrls = n; }
|
||||||
|
|
||||||
|
@ -143,10 +143,9 @@ implements ActionListener {
|
|||||||
public void
|
public void
|
||||||
requestSucceeded(Tree<String> json)
|
requestSucceeded(Tree<String> json)
|
||||||
{
|
{
|
||||||
List<Post> posts = toPosts(json);
|
page.posts = json;
|
||||||
page.posts = posts;
|
display.displayEntities(page.posts);
|
||||||
display.setPosts(page.posts);
|
boolean full = json.size() >= PREVIEW_COUNT;
|
||||||
boolean full = posts.size() >= PREVIEW_COUNT;
|
|
||||||
display.setNextPageAvailable(full);
|
display.setNextPageAvailable(full);
|
||||||
display.setPreviousPageAvailable(true);
|
display.setPreviousPageAvailable(true);
|
||||||
display.resetFocus();
|
display.resetFocus();
|
||||||
@ -162,12 +161,13 @@ implements ActionListener {
|
|||||||
{
|
{
|
||||||
assert page.posts != null;
|
assert page.posts != null;
|
||||||
assert page.posts.size() != 0;
|
assert page.posts.size() != 0;
|
||||||
Post last = page.posts.get(page.posts.size() - 1);
|
Tree<String> last = page.posts.get(page.posts.size() - 1);
|
||||||
|
String lastId = last.get("id").value;
|
||||||
|
|
||||||
display.setCursor(new Cursor(Cursor.WAIT_CURSOR));
|
display.setCursor(new Cursor(Cursor.WAIT_CURSOR));
|
||||||
api.getTimelinePage(
|
api.getTimelinePage(
|
||||||
page.type,
|
page.type,
|
||||||
PREVIEW_COUNT, last.postId, null,
|
PREVIEW_COUNT, lastId, null,
|
||||||
page.accountNumId, page.listId,
|
page.accountNumId, page.listId,
|
||||||
new RequestListener() {
|
new RequestListener() {
|
||||||
|
|
||||||
@ -187,16 +187,15 @@ implements ActionListener {
|
|||||||
public void
|
public void
|
||||||
requestSucceeded(Tree<String> json)
|
requestSucceeded(Tree<String> json)
|
||||||
{
|
{
|
||||||
List<Post> posts = toPosts(json);
|
if (json.size() == 0) {
|
||||||
if (posts.size() == 0) {
|
|
||||||
// We should probably say something
|
// We should probably say something
|
||||||
// to the user here? For now, we
|
// to the user here? For now, we
|
||||||
// quietly cancel.
|
// quietly cancel.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
page.posts = posts;
|
page.posts = json;
|
||||||
display.setPosts(page.posts);
|
display.displayEntities(page.posts);
|
||||||
boolean full = posts.size() >= PREVIEW_COUNT;
|
boolean full = json.size() >= PREVIEW_COUNT;
|
||||||
display.setNextPageAvailable(full);
|
display.setNextPageAvailable(full);
|
||||||
display.setPreviousPageAvailable(true);
|
display.setPreviousPageAvailable(true);
|
||||||
display.resetFocus();
|
display.resetFocus();
|
||||||
@ -212,12 +211,13 @@ implements ActionListener {
|
|||||||
{
|
{
|
||||||
assert page.posts != null;
|
assert page.posts != null;
|
||||||
assert page.posts.size() != 0;
|
assert page.posts.size() != 0;
|
||||||
Post first = page.posts.get(0);
|
Tree<String> first = page.posts.get(0);
|
||||||
|
String firstId = first.get("id").value;
|
||||||
|
|
||||||
display.setCursor(new Cursor(Cursor.WAIT_CURSOR));
|
display.setCursor(new Cursor(Cursor.WAIT_CURSOR));
|
||||||
api.getTimelinePage(
|
api.getTimelinePage(
|
||||||
page.type,
|
page.type,
|
||||||
PREVIEW_COUNT, null, first.postId,
|
PREVIEW_COUNT, null, firstId,
|
||||||
page.accountNumId, page.listId,
|
page.accountNumId, page.listId,
|
||||||
new RequestListener() {
|
new RequestListener() {
|
||||||
|
|
||||||
@ -237,13 +237,12 @@ implements ActionListener {
|
|||||||
public void
|
public void
|
||||||
requestSucceeded(Tree<String> json)
|
requestSucceeded(Tree<String> json)
|
||||||
{
|
{
|
||||||
List<Post> posts = toPosts(json);
|
if (json.size() < PREVIEW_COUNT) {
|
||||||
if (posts.size() < PREVIEW_COUNT) {
|
|
||||||
showLatestPage();
|
showLatestPage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
page.posts = posts;
|
page.posts = json;
|
||||||
display.setPosts(page.posts);
|
display.displayEntities(page.posts);
|
||||||
display.setNextPageAvailable(true);
|
display.setNextPageAvailable(true);
|
||||||
display.setPreviousPageAvailable(true);
|
display.setPreviousPageAvailable(true);
|
||||||
display.resetFocus();
|
display.resetFocus();
|
||||||
@ -376,16 +375,16 @@ implements ActionListener {
|
|||||||
// - -%- -
|
// - -%- -
|
||||||
|
|
||||||
public void
|
public void
|
||||||
postSelected(Post post)
|
postSelected(Tree<String> post)
|
||||||
{
|
{
|
||||||
primaire.getAutoViewWindow().showPost(post);
|
primaire.getAutoViewWindow().displayEntity(post);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void
|
public void
|
||||||
postOpened(Post post)
|
postOpened(Tree<String> post)
|
||||||
{
|
{
|
||||||
PostWindow w = new PostWindow(primaire);
|
PostWindow w = new PostWindow(primaire);
|
||||||
w.showPost(post);
|
w.displayEntity(post);
|
||||||
w.setLocationRelativeTo(this);
|
w.setLocationRelativeTo(this);
|
||||||
w.setVisible(true);
|
w.setVisible(true);
|
||||||
}
|
}
|
||||||
@ -453,112 +452,6 @@ implements ActionListener {
|
|||||||
|
|
||||||
// - -%- -
|
// - -%- -
|
||||||
|
|
||||||
private static List<Post>
|
|
||||||
toPosts(Tree<String> json)
|
|
||||||
{
|
|
||||||
List<Post> posts = new ArrayList<>();
|
|
||||||
for (Tree<String> post: json.children)
|
|
||||||
{
|
|
||||||
Post addee = new Post();
|
|
||||||
|
|
||||||
addee.postId = post.get("id").value;
|
|
||||||
// This fixes timeline navigation, but note that
|
|
||||||
// we will be pranked here if we try to reply
|
|
||||||
// to the boosted post.
|
|
||||||
|
|
||||||
if (post.get("reblog").size() != 0)
|
|
||||||
{
|
|
||||||
Tree<String> a = post.get("account");
|
|
||||||
addee.boosterName = a.get("display_name").value;
|
|
||||||
post = post.get("reblog");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
String s = post.get("created_at").value;
|
|
||||||
addee.date = ZonedDateTime.parse(s);
|
|
||||||
ZoneId z = ZoneId.systemDefault();
|
|
||||||
addee.date = addee.date.withZoneSameInstant(z);
|
|
||||||
}
|
|
||||||
catch (DateTimeParseException eDt) {
|
|
||||||
assert false;
|
|
||||||
addee.date = ZonedDateTime.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
String s2 = addee.html = post.get("content").value;
|
|
||||||
StringBuilder b = new StringBuilder();
|
|
||||||
Tree<String> nodes = RudimentaryHTMLParser.depthlessRead(s2);
|
|
||||||
for (Tree<String> node: nodes)
|
|
||||||
{
|
|
||||||
if (node.key.equals("tag"))
|
|
||||||
{
|
|
||||||
String tagName = node.get(0).key;
|
|
||||||
if (tagName.equals("br")) b.append(" \n ");
|
|
||||||
if (tagName.equals("/p")) b.append(" \n \n ");
|
|
||||||
}
|
|
||||||
if (node.key.equals("text"))
|
|
||||||
b.append(node.value);
|
|
||||||
if (node.key.equals("emoji"))
|
|
||||||
b.append(":" + node.value + ":");
|
|
||||||
}
|
|
||||||
addee.text = b.toString();
|
|
||||||
|
|
||||||
String s3 = post.get("spoiler_text").value;
|
|
||||||
if (!s3.isEmpty()) addee.contentWarning = s3;
|
|
||||||
else addee.contentWarning = null;
|
|
||||||
|
|
||||||
Tree<String> account = post.get("account");
|
|
||||||
addee.authorId = account.get("acct").value;
|
|
||||||
addee.authorName = account.get("username").value;
|
|
||||||
addee.authorNumId = account.get("id").value;
|
|
||||||
String s4 = account.get("display_name").value;
|
|
||||||
if (!s4.isEmpty()) addee.authorName = s4;
|
|
||||||
String s5 = account.get("avatar").value;
|
|
||||||
addee.authorAvatar = ImageApi.remote(s5);
|
|
||||||
if (addee.authorAvatar == null) {
|
|
||||||
s5 = "defaultAvatar";
|
|
||||||
addee.authorAvatar = ImageApi.local(s5);
|
|
||||||
}
|
|
||||||
|
|
||||||
String s6 = post.get("favourited").value;
|
|
||||||
String s7 = post.get("reblogged").value;
|
|
||||||
addee.favourited = s6.equals("true");
|
|
||||||
addee.boosted = s7.equals("true");
|
|
||||||
|
|
||||||
Tree<String> as1 = post.get("media_attachments");
|
|
||||||
Attachment[] as2 = new Attachment[as1.size()];
|
|
||||||
for (int o = 0; o < as2.length; ++o)
|
|
||||||
{
|
|
||||||
Tree<String> a1 = as1.get(o);
|
|
||||||
Attachment a2 = as2[o] = new Attachment();
|
|
||||||
|
|
||||||
a2.type = a1.get("type").value;
|
|
||||||
String u1 = a1.get("remote_url").value;
|
|
||||||
String u2 = a1.get("text_url").value;
|
|
||||||
String u3 = a1.get("url").value;
|
|
||||||
a2.url = u1 != null ? u1 : u2 != null ? u2 : u3;
|
|
||||||
a2.description = a1.get("description").value;
|
|
||||||
a2.image = null;
|
|
||||||
if (a2.type.equals("image"))
|
|
||||||
a2.image = ImageApi.remote(a2.url);
|
|
||||||
}
|
|
||||||
addee.attachments = as2;
|
|
||||||
|
|
||||||
Tree<String> es1 = post.get("emojis");
|
|
||||||
String[][] es2 = new String[es1.size()][];
|
|
||||||
for (int o = 0; o < es2.length; ++o)
|
|
||||||
{
|
|
||||||
Tree<String> e1 = es1.get(o);
|
|
||||||
String[] e2 = es2[o] = new String[2];
|
|
||||||
e2[0] = e1.get("shortcode").value;
|
|
||||||
e2[1] = e1.get("url").value;
|
|
||||||
}
|
|
||||||
addee.emojiUrls = es2;
|
|
||||||
|
|
||||||
posts.add(addee);
|
|
||||||
}
|
|
||||||
return posts;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String
|
private static String
|
||||||
plainify(String html)
|
plainify(String html)
|
||||||
{
|
{
|
||||||
@ -629,7 +522,7 @@ implements ActionListener {
|
|||||||
setJMenuBar(menuBar);
|
setJMenuBar(menuBar);
|
||||||
|
|
||||||
page = new TimelinePage();
|
page = new TimelinePage();
|
||||||
page.posts = new ArrayList<>();
|
page.posts = new Tree<String>();
|
||||||
|
|
||||||
display = new TimelineComponent(this);
|
display = new TimelineComponent(this);
|
||||||
display.setNextPageAvailable(false);
|
display.setNextPageAvailable(false);
|
||||||
@ -652,8 +545,8 @@ implements
|
|||||||
private TimelineWindow
|
private TimelineWindow
|
||||||
primaire;
|
primaire;
|
||||||
|
|
||||||
private final List<Post>
|
private Tree<String>
|
||||||
posts = new ArrayList<>();
|
posts;
|
||||||
|
|
||||||
// - -%- -
|
// - -%- -
|
||||||
|
|
||||||
@ -679,51 +572,82 @@ implements
|
|||||||
|
|
||||||
// ---%-@-%---
|
// ---%-@-%---
|
||||||
|
|
||||||
public void
|
public void
|
||||||
setPosts(List<Post> posts)
|
displayEntities(Tree<String> postArray)
|
||||||
{
|
{
|
||||||
this.posts.clear();
|
assert postArray.size() <= postPreviews.size();
|
||||||
this.posts.addAll(posts);
|
this.posts = postArray;
|
||||||
|
|
||||||
assert posts.size() <= postPreviews.size();
|
for (int o = 0; o < postArray.size(); ++o)
|
||||||
for (int o = 0; o < posts.size(); ++o)
|
{
|
||||||
{
|
PostPreviewComponent c = postPreviews.get(o);
|
||||||
PostPreviewComponent c = postPreviews.get(o);
|
Tree<String> p = postArray.get(o);
|
||||||
Post p = posts.get(o);
|
Tree<String> a = p.get("account");
|
||||||
{
|
|
||||||
c.setTopLeft(p.authorName);
|
String an = a.get("display_name").value;
|
||||||
if (p.boosterName != null)
|
if (an.isEmpty()) an = a.get("username").value;
|
||||||
c.setTopLeft("boosted by " + p.boosterName);
|
c.setTopLeft(an);
|
||||||
|
|
||||||
|
Tree<String> boosted = p.get("reblog");
|
||||||
|
if (boosted.size() > 0) {
|
||||||
|
c.setTopLeft("boosted by " + an);
|
||||||
|
p = boosted;
|
||||||
|
a = p.get("account");
|
||||||
}
|
}
|
||||||
{
|
|
||||||
String f = "";
|
|
||||||
if (p.attachments.length > 0)
|
|
||||||
f += "a";
|
|
||||||
|
|
||||||
String t;
|
String f = "";
|
||||||
ZonedDateTime now = ZonedDateTime.now();
|
if (p.get("media_attachments").size() > 0) f += "a";
|
||||||
long d = ChronoUnit.SECONDS.between(p.date, now);
|
String t = "";
|
||||||
|
try {
|
||||||
|
String jv = p.get("created_at").value;
|
||||||
|
ZonedDateTime pv = ZonedDateTime.parse(jv);
|
||||||
|
ZoneId z = ZoneId.systemDefault();
|
||||||
|
pv = pv.withZoneSameInstant(z);
|
||||||
|
|
||||||
|
ZonedDateTime now = ZonedDateTime.now();
|
||||||
|
long d = ChronoUnit.SECONDS.between(pv, now);
|
||||||
long s = Math.abs(d);
|
long s = Math.abs(d);
|
||||||
if (s < 30) t = "now";
|
if (s < 30) t = "now";
|
||||||
else if (s < 60) t = d + "s";
|
else if (s < 60) t = d + "s";
|
||||||
else if (s < 3600) t = (d / 60) + "m";
|
else if (s < 3600) t = (d / 60) + "m";
|
||||||
else if (s < 86400) t = (d / 3600) + "h";
|
else if (s < 86400) t = (d / 3600) + "h";
|
||||||
else t = (d / 86400) + "d";
|
else t = (d / 86400) + "d";
|
||||||
|
|
||||||
c.setTopRight(f + " " + t);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
if (p.contentWarning != null)
|
|
||||||
c.setBottom("(" + p.contentWarning + ")");
|
|
||||||
else
|
|
||||||
c.setBottom(p.text + " ");
|
|
||||||
}
|
}
|
||||||
}
|
catch (DateTimeParseException eDt) {
|
||||||
|
assert false;
|
||||||
|
}
|
||||||
|
c.setTopRight(f + " " + t);
|
||||||
|
|
||||||
|
String html = p.get("content").value;
|
||||||
|
String cw = p.get("spoiler_text").value;
|
||||||
|
if (!cw.isEmpty()) {
|
||||||
|
c.setBottom("(" + cw + ")");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
StringBuilder bu = new StringBuilder();
|
||||||
|
Tree<String> nodes;
|
||||||
|
nodes = RudimentaryHTMLParser.depthlessRead(html);
|
||||||
|
for (Tree<String> node: nodes)
|
||||||
|
{
|
||||||
|
if (node.key.equals("tag"))
|
||||||
|
{
|
||||||
|
String tagName = node.get(0).key;
|
||||||
|
if (tagName.equals("br")) bu.append(" \n ");
|
||||||
|
if (tagName.equals("/p")) bu.append(" \n \n ");
|
||||||
|
}
|
||||||
|
if (node.key.equals("text"))
|
||||||
|
bu.append(node.value);
|
||||||
|
if (node.key.equals("emoji"))
|
||||||
|
bu.append(":" + node.value + ":");
|
||||||
|
}
|
||||||
|
c.setBottom(bu.toString() + " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
for (int o = posts.size(); o < postPreviews.size(); ++o)
|
for (int o = posts.size(); o < postPreviews.size(); ++o)
|
||||||
{
|
{
|
||||||
postPreviews.get(o).reset();
|
postPreviews.get(o).reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void
|
public void
|
||||||
setPageLabel(String label)
|
setPageLabel(String label)
|
||||||
@ -768,18 +692,17 @@ implements
|
|||||||
select(Object c)
|
select(Object c)
|
||||||
{
|
{
|
||||||
assert c instanceof PostPreviewComponent;
|
assert c instanceof PostPreviewComponent;
|
||||||
PostPreviewComponent p = (PostPreviewComponent)c;
|
|
||||||
|
|
||||||
int offset = postPreviews.indexOf(p);
|
for (int o = 0; o < postPreviews.size(); ++o)
|
||||||
assert offset != -1;
|
{
|
||||||
if (offset < posts.size()) {
|
PostPreviewComponent p = postPreviews.get(o);
|
||||||
primaire.postSelected(posts.get(offset));
|
if (c == p) {
|
||||||
p.setSelected(true);
|
primaire.postSelected(posts.get(o));
|
||||||
}
|
p.setSelected(true);
|
||||||
else {
|
p.repaint();
|
||||||
p.setSelected(false);
|
}
|
||||||
}
|
else deselect(p);
|
||||||
p.repaint();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void
|
private void
|
||||||
@ -798,11 +721,10 @@ implements
|
|||||||
assert c instanceof PostPreviewComponent;
|
assert c instanceof PostPreviewComponent;
|
||||||
PostPreviewComponent p = (PostPreviewComponent)c;
|
PostPreviewComponent p = (PostPreviewComponent)c;
|
||||||
|
|
||||||
int offset = postPreviews.indexOf(p);
|
int o = postPreviews.indexOf(p);
|
||||||
assert offset != -1;
|
assert o != -1;
|
||||||
if (offset < posts.size()) {
|
if (o >= posts.size()) return;
|
||||||
primaire.postOpened(posts.get(offset));
|
primaire.postOpened(posts.get(o));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void
|
public void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user