Removed expectation of interrupt exception on window updater.
0
ClipboardApi.java
Normal file → Executable file
0
ComposeWindow.java
Normal file → Executable file
0
ImageApi.java
Normal file → Executable file
0
ImageWindow.java
Normal file → Executable file
0
JKomasto.java
Normal file → Executable file
0
KDE_Dialog_Appear.wav
Normal file → Executable file
0
LoginWindow.java
Normal file → Executable file
108
MastodonApi.java
Normal file → Executable file
@ -3,10 +3,15 @@ import cafe.biskuteri.hinoki.Tree;
|
||||
import cafe.biskuteri.hinoki.JsonConverter;
|
||||
import cafe.biskuteri.hinoki.DSVTokeniser;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URLEncoder;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.FileReader;
|
||||
@ -14,7 +19,6 @@ import java.io.FileWriter;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.channels.ClosedByInterruptException;
|
||||
|
||||
class
|
||||
MastodonApi {
|
||||
@ -66,11 +70,10 @@ MastodonApi {
|
||||
try
|
||||
{
|
||||
URL endpoint = new URL(url);
|
||||
HttpURLConnection conn;
|
||||
conn = (HttpURLConnection)endpoint.openConnection();
|
||||
HttpURLConnection conn = cast(endpoint.openConnection());
|
||||
conn.connect();
|
||||
|
||||
returnResponseInTree(conn, handler);
|
||||
wrapResponseInTree(conn, handler);
|
||||
}
|
||||
catch (IOException eIo) { handler.connectionFailed(eIo); }
|
||||
}
|
||||
@ -83,14 +86,12 @@ MastodonApi {
|
||||
try
|
||||
{
|
||||
URL endpoint = new URL(instanceUrl + "/api/v1/apps");
|
||||
HttpURLConnection conn;
|
||||
conn = (HttpURLConnection)endpoint.openConnection();
|
||||
HttpURLConnection conn = cast(endpoint.openConnection());
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setDoOutput(true);
|
||||
conn.connect();
|
||||
|
||||
OutputStreamWriter output;
|
||||
output = new OutputStreamWriter(conn.getOutputStream());
|
||||
Writer output = owriter(conn.getOutputStream());
|
||||
output.write("client_name=JKomasto alpha");
|
||||
output.write("&redirect_uris=urn:ietf:wg:oauth:2.0:oob");
|
||||
output.write("&scopes=" + SCOPES);
|
||||
@ -135,14 +136,12 @@ MastodonApi {
|
||||
try
|
||||
{
|
||||
URL endpoint = new URL(instanceUrl + "/oauth/token");
|
||||
HttpURLConnection conn;
|
||||
conn = (HttpURLConnection)endpoint.openConnection();
|
||||
HttpURLConnection conn = cast(endpoint.openConnection());
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setDoOutput(true);
|
||||
conn.connect();
|
||||
|
||||
OutputStreamWriter output;
|
||||
output = new OutputStreamWriter(conn.getOutputStream());
|
||||
Writer output = owriter(conn.getOutputStream());
|
||||
output.write("client_id=" + id);
|
||||
output.write("&client_secret=" + secret);
|
||||
output.write("&redirect_uri=urn:ietf:wg:oauth:2.0:oob");
|
||||
@ -166,8 +165,7 @@ MastodonApi {
|
||||
{
|
||||
String s = "/api/v1/accounts/verify_credentials";
|
||||
URL endpoint = new URL(instanceUrl + s);
|
||||
HttpURLConnection conn;
|
||||
conn = (HttpURLConnection)endpoint.openConnection();
|
||||
HttpURLConnection conn = cast(endpoint.openConnection());
|
||||
String s2 = "Bearer " + token;
|
||||
conn.setRequestProperty("Authorization", s2);
|
||||
conn.connect();
|
||||
@ -213,8 +211,7 @@ MastodonApi {
|
||||
try
|
||||
{
|
||||
URL endpoint = new URL(url);
|
||||
HttpURLConnection conn;
|
||||
conn = (HttpURLConnection)endpoint.openConnection();
|
||||
HttpURLConnection conn = cast(endpoint.openConnection());
|
||||
String s2 = "Bearer " + token;
|
||||
conn.setRequestProperty("Authorization", s2);
|
||||
conn.connect();
|
||||
@ -237,8 +234,7 @@ MastodonApi {
|
||||
try
|
||||
{
|
||||
URL endpoint = new URL(url);
|
||||
HttpURLConnection conn;
|
||||
conn = (HttpURLConnection)endpoint.openConnection();
|
||||
HttpURLConnection conn = cast(endpoint.openConnection());
|
||||
String s3 = "Bearer " + token;
|
||||
conn.setRequestProperty("Authorization", s3);
|
||||
conn.setRequestMethod("POST");
|
||||
@ -262,8 +258,7 @@ MastodonApi {
|
||||
try
|
||||
{
|
||||
URL endpoint = new URL(url);
|
||||
HttpURLConnection conn;
|
||||
conn = (HttpURLConnection)endpoint.openConnection();
|
||||
HttpURLConnection conn = cast(endpoint.openConnection());
|
||||
String s3 = "Bearer " + token;
|
||||
conn.setRequestProperty("Authorization", s3);
|
||||
conn.setRequestMethod("POST");
|
||||
@ -299,8 +294,7 @@ MastodonApi {
|
||||
contentWarning = encode(contentWarning);
|
||||
|
||||
URL endpoint = new URL(url);
|
||||
HttpURLConnection conn;
|
||||
conn = (HttpURLConnection)endpoint.openConnection();
|
||||
HttpURLConnection conn = cast(endpoint.openConnection());
|
||||
String s1 = "Bearer " + token;
|
||||
conn.setRequestProperty("Authorization", s1);
|
||||
String s2 = Integer.toString(text.hashCode());
|
||||
@ -309,8 +303,7 @@ MastodonApi {
|
||||
conn.setRequestMethod("POST");
|
||||
conn.connect();
|
||||
|
||||
OutputStreamWriter output;
|
||||
output = new OutputStreamWriter(conn.getOutputStream());
|
||||
Writer output = owriter(conn.getOutputStream());
|
||||
output.write("status=" + text);
|
||||
output.write("&visibility=" + visibilityParam);
|
||||
if (replyTo != null) {
|
||||
@ -341,8 +334,7 @@ MastodonApi {
|
||||
try
|
||||
{
|
||||
URL endpoint = new URL(url);
|
||||
HttpURLConnection conn;
|
||||
conn = (HttpURLConnection)endpoint.openConnection();
|
||||
HttpURLConnection conn = cast(endpoint.openConnection());
|
||||
String s1 = "Bearer " + token;
|
||||
conn.setRequestProperty("Authorization", s1);
|
||||
conn.connect();
|
||||
@ -361,8 +353,7 @@ MastodonApi {
|
||||
try
|
||||
{
|
||||
URL endpoint = new URL(url);
|
||||
HttpURLConnection conn;
|
||||
conn = (HttpURLConnection)endpoint.openConnection();
|
||||
HttpURLConnection conn = cast(endpoint.openConnection());
|
||||
String s1 = "Bearer " + token;
|
||||
conn.setRequestProperty("Authorization", s1);
|
||||
conn.setRequestMethod("DELETE");
|
||||
@ -382,8 +373,7 @@ MastodonApi {
|
||||
try
|
||||
{
|
||||
URL endpoint = new URL(url);
|
||||
HttpURLConnection conn;
|
||||
conn = (HttpURLConnection)endpoint.openConnection();
|
||||
HttpURLConnection conn = cast(endpoint.openConnection());
|
||||
String s1 = "Bearer " + token;
|
||||
conn.setRequestProperty("Authorization", s1);
|
||||
conn.connect();
|
||||
@ -404,8 +394,7 @@ MastodonApi {
|
||||
try
|
||||
{
|
||||
URL endpoint = new URL(url);
|
||||
HttpURLConnection conn;
|
||||
conn = (HttpURLConnection)endpoint.openConnection();
|
||||
HttpURLConnection conn = cast(endpoint.openConnection());
|
||||
String s3 = "Bearer " + token;
|
||||
conn.setRequestProperty("Authorization", s3);
|
||||
conn.connect();
|
||||
@ -427,8 +416,7 @@ MastodonApi {
|
||||
try
|
||||
{
|
||||
URL endpoint = new URL(url);
|
||||
HttpURLConnection conn;
|
||||
conn = (HttpURLConnection)endpoint.openConnection();
|
||||
HttpURLConnection conn = cast(endpoint.openConnection());
|
||||
String s1 = "Bearer " + token;
|
||||
conn.setRequestProperty("Authorization", s1);
|
||||
conn.connect();
|
||||
@ -440,8 +428,7 @@ MastodonApi {
|
||||
|
||||
public void
|
||||
monitorTimeline(
|
||||
TimelineType type, ServerSideEventsListener handler)
|
||||
throws InterruptedException
|
||||
TimelineType type, ServerSideEventsListener handler)
|
||||
{
|
||||
String token = accessToken.get("access_token").value;
|
||||
|
||||
@ -457,35 +444,30 @@ MastodonApi {
|
||||
try
|
||||
{
|
||||
URL endpoint = new URL(url);
|
||||
HttpURLConnection conn;
|
||||
conn = (HttpURLConnection)endpoint.openConnection();
|
||||
HttpURLConnection conn = cast(endpoint.openConnection());
|
||||
String s = "Bearer " + token;
|
||||
conn.setRequestProperty("Authorization", s);
|
||||
conn.connect();
|
||||
|
||||
InputStreamReader input;
|
||||
int code = conn.getResponseCode();
|
||||
if (code >= 300)
|
||||
{
|
||||
input = new InputStreamReader(conn.getErrorStream());
|
||||
Reader input = ireader(conn.getErrorStream());
|
||||
Tree<String> response = JsonConverter.convert(input);
|
||||
input.close();
|
||||
handler.requestFailed(code, response);
|
||||
return;
|
||||
}
|
||||
|
||||
input = new InputStreamReader(conn.getInputStream());
|
||||
Reader input = ireader(conn.getInputStream());
|
||||
BufferedReader br = new BufferedReader(input);
|
||||
while (true)
|
||||
Thread thread = Thread.currentThread();
|
||||
while (!thread.isInterrupted())
|
||||
{
|
||||
String line = br.readLine();
|
||||
if (line != null) handler.lineReceived(line);
|
||||
}
|
||||
}
|
||||
catch (ClosedByInterruptException eIt)
|
||||
{
|
||||
throw new InterruptedException();
|
||||
}
|
||||
catch (IOException eIo) { handler.connectionFailed(eIo); }
|
||||
}
|
||||
|
||||
@ -496,40 +478,38 @@ MastodonApi {
|
||||
HttpURLConnection conn, RequestListener handler)
|
||||
throws IOException
|
||||
{
|
||||
InputStreamReader input;
|
||||
int code = conn.getResponseCode();
|
||||
if (code >= 300)
|
||||
{
|
||||
input = new InputStreamReader(conn.getErrorStream());
|
||||
Reader input = ireader(conn.getErrorStream());
|
||||
Tree<String> response = JsonConverter.convert(input);
|
||||
input.close();
|
||||
handler.requestFailed(code, response);
|
||||
return;
|
||||
}
|
||||
|
||||
input = new InputStreamReader(conn.getInputStream());
|
||||
Reader input = ireader(conn.getInputStream());
|
||||
Tree<String> response = JsonConverter.convert(input);
|
||||
input.close();
|
||||
handler.requestSucceeded(response);
|
||||
}
|
||||
|
||||
private void
|
||||
returnResponseInTree(
|
||||
wrapResponseInTree(
|
||||
HttpURLConnection conn, RequestListener handler)
|
||||
throws IOException
|
||||
{
|
||||
InputStreamReader input;
|
||||
int code = conn.getResponseCode();
|
||||
if (code >= 300)
|
||||
{
|
||||
input = new InputStreamReader(conn.getErrorStream());
|
||||
Reader input = ireader(conn.getErrorStream());
|
||||
Tree<String> response = fromPlain(input);
|
||||
input.close();
|
||||
handler.requestFailed(code, response);
|
||||
return;
|
||||
}
|
||||
|
||||
input = new InputStreamReader(conn.getInputStream());
|
||||
Reader input = ireader(conn.getInputStream());
|
||||
Tree<String> response = fromPlain(input);
|
||||
input.close();
|
||||
handler.requestSucceeded(response);
|
||||
@ -557,7 +537,7 @@ MastodonApi {
|
||||
// - -%- -
|
||||
|
||||
private static Tree<String>
|
||||
fromPlain(InputStreamReader r)
|
||||
fromPlain(Reader r)
|
||||
throws IOException
|
||||
{
|
||||
StringBuilder b = new StringBuilder();
|
||||
@ -584,6 +564,26 @@ MastodonApi {
|
||||
}
|
||||
}
|
||||
|
||||
private static HttpURLConnection
|
||||
cast(URLConnection conn)
|
||||
{
|
||||
return (HttpURLConnection)conn;
|
||||
}
|
||||
|
||||
private static InputStreamReader
|
||||
ireader(InputStream is)
|
||||
throws IOException
|
||||
{
|
||||
return new InputStreamReader(is);
|
||||
}
|
||||
|
||||
private static OutputStreamWriter
|
||||
owriter(OutputStream os)
|
||||
throws IOException
|
||||
{
|
||||
return new OutputStreamWriter(os);
|
||||
}
|
||||
|
||||
// ---%-@-%---
|
||||
|
||||
public void
|
||||
|
0
NotificationsWindow.java
Normal file → Executable file
0
PostWindow.java
Normal file → Executable file
7
RepliesWindow.java
Normal file → Executable file
@ -220,6 +220,13 @@ implements TreeSelectionListener {
|
||||
if (p == null)
|
||||
{
|
||||
assert false;
|
||||
/*
|
||||
* Besides descendants possibly not being in order,
|
||||
* the top of the thread might be deleted and so
|
||||
* thread.top gets set to the given post. Which
|
||||
* sibling replies aren't replying to, resulting
|
||||
* in assertion failure.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
|
0
RequestListener.java
Normal file → Executable file
0
RichTextPane.java
Normal file → Executable file
0
RudimentaryHTMLParser.java
Normal file → Executable file
10
TimelineWindow.java
Normal file → Executable file
@ -268,7 +268,7 @@ implements ActionListener {
|
||||
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(
|
||||
page.type,
|
||||
PREVIEW_COUNT, lastId, null,
|
||||
@ -305,7 +305,7 @@ implements ActionListener {
|
||||
// quietly cancel.
|
||||
return;
|
||||
}
|
||||
readEntity(json);
|
||||
readEntity(json);
|
||||
showingLatest = false;
|
||||
windowUpdater.remove(TimelineWindow.this);
|
||||
}
|
||||
@ -579,8 +579,10 @@ implements ActionListener {
|
||||
if (src == openNotifications)
|
||||
{
|
||||
NotificationsWindow w = primaire.getNotificationsWindow();
|
||||
w.setLocationByPlatform(true);
|
||||
w.setVisible(true);
|
||||
if (!w.isVisible()) {
|
||||
w.setLocationByPlatform(true);
|
||||
w.setVisible(true);
|
||||
}
|
||||
}
|
||||
if (src == flipToNewestPost)
|
||||
{
|
||||
|
0
TwoToggleButton.java
Normal file → Executable file
28
WindowUpdater.java
Normal file → Executable file
@ -100,15 +100,11 @@ WindowUpdater {
|
||||
public void
|
||||
stop()
|
||||
{
|
||||
try {
|
||||
thread.interrupt();
|
||||
thread.join();
|
||||
thread = null;
|
||||
}
|
||||
catch (InterruptedException eIt) {
|
||||
assert false;
|
||||
// Who would do that to us..
|
||||
}
|
||||
thread.interrupt();
|
||||
thread = null;
|
||||
// We should be sure that the thread will actually
|
||||
// terminate eventually after our interrupt. I'm
|
||||
// confident enough in that.
|
||||
}
|
||||
|
||||
public void
|
||||
@ -143,14 +139,12 @@ WindowUpdater {
|
||||
public void
|
||||
run()
|
||||
{
|
||||
try {
|
||||
event = new StringBuilder();
|
||||
data = new StringBuilder();
|
||||
api.monitorTimeline(type, this);
|
||||
// monitorTimeline should not return
|
||||
// until the connection is closed.
|
||||
}
|
||||
catch (InterruptedException eIt) { }
|
||||
event = new StringBuilder();
|
||||
data = new StringBuilder();
|
||||
api.monitorTimeline(type, this);
|
||||
// monitorTimeline should not return until
|
||||
// the connection is closed, or this thread
|
||||
// is interrupted.
|
||||
}
|
||||
|
||||
public void
|
||||
|
0
graphics/Federated.xcf
Normal file → Executable file
0
graphics/Flags.xcf
Normal file → Executable file
0
graphics/Hourglass.xcf
Normal file → Executable file
0
graphics/boostToggled.png
Normal file → Executable file
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
0
graphics/boostUntoggled.png
Normal file → Executable file
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
0
graphics/button.png
Normal file → Executable file
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
0
graphics/disabledOverlay.png
Normal file → Executable file
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
0
graphics/favouriteToggled.png
Normal file → Executable file
Before Width: | Height: | Size: 353 B After Width: | Height: | Size: 353 B |
0
graphics/favouriteUntoggled.png
Normal file → Executable file
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
0
graphics/federated.png
Normal file → Executable file
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
0
graphics/miscToggled.png
Normal file → Executable file
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
0
graphics/miscUntoggled.png
Normal file → Executable file
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
0
graphics/ref1.png
Normal file → Executable file
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
0
graphics/replyToggled.png
Normal file → Executable file
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
0
graphics/replyUntoggled.png
Normal file → Executable file
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
0
graphics/selectedOverlay.png
Normal file → Executable file
Before Width: | Height: | Size: 313 B After Width: | Height: | Size: 313 B |
0
graphics/test1.png
Normal file → Executable file
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
0
graphics/test2.png
Normal file → Executable file
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
0
graphics/test3.png
Normal file → Executable file
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
0
graphics/test4.png
Normal file → Executable file
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |