diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/Connection.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/Connection.java index bb37f3f5..c9dd2c7b 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/Connection.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/Connection.java @@ -17,7 +17,6 @@ import org.nuclearfog.twidda.model.Trend; import org.nuclearfog.twidda.model.User; import org.nuclearfog.twidda.model.UserList; -import java.io.InputStream; import java.util.List; /** @@ -516,20 +515,6 @@ public interface Connection { */ User updateProfile(ProfileUpdate update) throws ConnectionException; - /** - * update current user's profile image - * - * @param inputStream inputstream of the local image file - */ - void updateProfileImage(InputStream inputStream) throws ConnectionException; - - /** - * update current user's profile banner image - * - * @param inputStream inputstream of the local image file - */ - void updateBannerImage(InputStream inputStream) throws ConnectionException; - /** * upload media file and generate a media ID * diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java index e872f764..3d4f8b77 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java @@ -95,6 +95,7 @@ public class Mastodon implements Connection { private static final String ENDPOINT_NOTIFICATION = "/api/v1/notifications"; private static final String ENDPOINT_UPLOAD_MEDIA = "/api/v2/media"; private static final String ENDPOINT_MEDIA_STATUS = "/api/v1/media/"; + private static final String ENDPOINT_UPDATE_CREDENTIALS = "/api/v1/accounts/update_credentials"; private static final MediaType TYPE_TEXT = MediaType.parse("text/plain"); private static final MediaType TYPE_STREAM = MediaType.parse("application/octet-stream"); @@ -352,8 +353,7 @@ public class Mastodon implements Connection { List params = new ArrayList<>(); params.add("q=" + StringTools.encode(search)); params.add("type=statuses"); - params.add("following=false"); - params.add("offset=0"); + params.add("resolve=true"); return getStatuses(SEARCH_TIMELINE, params, minId, maxId); } @@ -382,7 +382,7 @@ public class Mastodon implements Connection { @Override public List getLocations() throws MastodonException { - return new ArrayList<>(0); // todo add implementation + return new ArrayList<>(0); // not supported yet } @@ -429,7 +429,7 @@ public class Mastodon implements Connection { @Override public List getStatusReplies(String name, long id, long minId, long maxId) throws MastodonException { - throw new MastodonException("not implemented!"); // todo add implementation + return new ArrayList<>(0); // todo add implementation } @@ -662,19 +662,31 @@ public class Mastodon implements Connection { @Override public User updateProfile(ProfileUpdate update) throws MastodonException { - throw new MastodonException("not implemented!"); // todo add implementation - } + List params = new ArrayList<>(); + List streams = new ArrayList<>(); + List keys = new ArrayList<>(); - - @Override - public void updateProfileImage(InputStream inputStream) throws MastodonException { - throw new MastodonException("not implemented!"); // todo add implementation - } - - - @Override - public void updateBannerImage(InputStream inputStream) throws MastodonException { - throw new MastodonException("not implemented!"); // todo add implementation + params.add("display_name=" + update.getName()); + params.add("note=" + update.getDescription()); + if (update.getProfileImageStream() != null) { + streams.add(update.getProfileImageStream()); + keys.add("avatar"); + } + if (update.getBannerImageStream() != null) { + streams.add(update.getBannerImageStream()); + keys.add("header"); + } + try { + Response response = patch(ENDPOINT_UPDATE_CREDENTIALS, params, streams, keys); + ResponseBody body = response.body(); + if (response.code() == 200 && body != null) { + JSONObject json = new JSONObject(body.string()); + return new MastodonUser(json, settings.getLogin().getId()); + } + throw new MastodonException(response); + } catch (IOException | JSONException e) { + throw new MastodonException(e); + } } @@ -1026,19 +1038,8 @@ public class Mastodon implements Connection { * @return http response */ private Response post(String endpoint, List params, InputStream is, String addToKey) throws IOException { - RequestBody data = new RequestBody() { - @Override - public MediaType contentType() { - return TYPE_STREAM; - } - - @Override - public void writeTo(@NonNull BufferedSink sink) throws IOException { - sink.writeAll(Okio.buffer(Okio.source(is))); - } - }; Account login = settings.getLogin(); - RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart(addToKey, StringTools.getRandomString(), data).build(); + RequestBody body = createUploadRequest(is, addToKey); return post(login.getHostname(), endpoint, login.getBearerToken(), params, body); } @@ -1089,6 +1090,49 @@ public class Mastodon implements Connection { return client.newCall(request.build()).execute(); } + /** + * create a DELETE response + * + * @param endpoint endpoint url + * @param params additional parameters + * @return DELETE response + */ + private Response patch(String endpoint, List params, List streams, List keys) throws IOException { + Account login = settings.getLogin(); + Request.Builder builder = new Request.Builder().url(buildUrl(login.getHostname(), endpoint, params)); + if (streams.isEmpty() || keys.isEmpty()) { + builder.patch(RequestBody.create("", TYPE_TEXT)); + } else { + for (int i = 0; i < streams.size() && i < keys.size(); i++) { + builder.patch(createUploadRequest(streams.get(i), keys.get(i))); + } + } + Request request = builder.addHeader("Authorization", "Bearer " + login.getBearerToken()).build(); + return client.newCall(request).execute(); + } + + /** + * create requestbody with upload stream + * + * @param is input stream to upload a file + * @param addToKey upload stream key + * @return request body + */ + private RequestBody createUploadRequest(final InputStream is, String addToKey) { + RequestBody data = new RequestBody() { + @Override + public MediaType contentType() { + return TYPE_STREAM; + } + + @Override + public void writeTo(@NonNull BufferedSink sink) throws IOException { + sink.writeAll(Okio.buffer(Okio.source(is))); + } + }; + return new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart(addToKey, StringTools.getRandomString(), data).build(); + } + /** * append query parameters to an url * diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/twitter/Twitter.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/twitter/Twitter.java index 7fdcd452..689a008e 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/twitter/Twitter.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/twitter/Twitter.java @@ -1081,22 +1081,16 @@ public class Twitter implements Connection { params.add("url=" + StringTools.encode(update.getUrl())); params.add("location=" + StringTools.encode(update.getLocation())); params.add("description=" + StringTools.encode(update.getDescription())); + if (update.getProfileImageStream() != null) { + updateImage(PROFILE_UPDATE_IMAGE, update.getProfileImageStream(), "image"); + } + if (update.getBannerImageStream() != null) { + updateImage(PROFILE_UPDATE_BANNER, update.getBannerImageStream(), "banner"); + } return getUser1(PROFILE_UPDATE, params); } - @Override - public void updateProfileImage(InputStream inputStream) throws TwitterException { - updateImage(PROFILE_UPDATE_IMAGE, inputStream, "image"); - } - - - @Override - public void updateBannerImage(InputStream inputStream) throws TwitterException { - updateImage(PROFILE_UPDATE_BANNER, inputStream, "banner"); - } - - @Override public List getIdBlocklist() throws TwitterException { // Note: the API returns up to 5000 user IDs diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/async/UserUpdater.java b/app/src/main/java/org/nuclearfog/twidda/backend/async/UserUpdater.java index 1200aeb5..c2cbf917 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/async/UserUpdater.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/async/UserUpdater.java @@ -42,12 +42,6 @@ public class UserUpdater extends AsyncTask { @Override protected User doInBackground(Void... v) { try { - if (profile.getProfileImageStream() != null) { - connection.updateProfileImage(profile.getProfileImageStream()); - } - if (profile.getBannerImageStream() != null) { - connection.updateBannerImage(profile.getBannerImageStream()); - } User user = connection.updateProfile(profile); // save new user information db.saveUser(user); diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/update/ProfileUpdate.java b/app/src/main/java/org/nuclearfog/twidda/backend/update/ProfileUpdate.java index 2addeca9..adfcb854 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/update/ProfileUpdate.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/update/ProfileUpdate.java @@ -176,7 +176,6 @@ public class ProfileUpdate { result += " location:\"" + location + "\""; if (!url.isEmpty()) result += " url:\"" + url + "\""; - result += " image:" + imageAdded(); return result; } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java index 012fb647..340214c9 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java @@ -662,6 +662,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener userName.setText(author.getUsername()); screenName.setText(author.getScreenname()); createdAt.setText(SimpleDateFormat.getDateTimeInstance().format(status.getTimestamp())); + ansButton.setText(buttonNumber.format(status.getReplyCount())); favButton.setText(buttonNumber.format(status.getFavoriteCount())); rtwButton.setText(buttonNumber.format(status.getRepostCount())); statusApi.setText(R.string.tweet_sent_from);