From 9e5a60ed1e032aa0cc79aacfc30252b0f5ffac77 Mon Sep 17 00:00:00 2001 From: nuclearfog Date: Tue, 31 May 2022 20:52:59 +0200 Subject: [PATCH] tweet & API bug fix --- .../twidda/backend/api/Twitter.java | 119 +++++++++--------- .../twidda/backend/api/impl/TweetV1.java | 27 ++-- .../twidda/backend/async/TweetAction.java | 90 ++++++------- .../twidda/ui/activities/TweetActivity.java | 112 +++++++++-------- .../twidda/ui/fragments/TweetFragment.java | 2 +- 5 files changed, 187 insertions(+), 163 deletions(-) diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/Twitter.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/Twitter.java index 7854b28e..b6e73e07 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/Twitter.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/Twitter.java @@ -214,7 +214,7 @@ public class Twitter implements GlobalSettings.SettingsListener { */ public String getRequestToken() throws TwitterException { try { - Response response = post(REQUEST_TOKEN, new ArrayList<>(1)); + Response response = post(REQUEST_TOKEN, new ArrayList<>()); if (response.code() == 200 && response.body() != null) { String res = response.body().string(); // extrect oauth_token from url @@ -234,7 +234,7 @@ public class Twitter implements GlobalSettings.SettingsListener { */ public User login(String oauth_token, String pin) throws TwitterException { try { - List params = new ArrayList<>(3); + List params = new ArrayList<>(); params.add("oauth_verifier=" + pin); params.add("oauth_token=" + oauth_token); Response response = post(OAUTH_VERIFIER, params); @@ -261,7 +261,7 @@ public class Twitter implements GlobalSettings.SettingsListener { */ public User getCredentials() throws TwitterException { try { - Response response = get(CREDENTIALS, new ArrayList<>(1)); + Response response = get(CREDENTIALS, new ArrayList<>()); if (response.body() != null && response.code() == 200) { JSONObject json = new JSONObject(response.body().string()); return new UserV1(json); @@ -281,7 +281,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return user information */ public User showUser(long id) throws TwitterException { - List params = new ArrayList<>(3); + List params = new ArrayList<>(); params.add("user_id=" + id); return getUser1(USER_LOOKUP, params); } @@ -293,7 +293,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return user information */ public User showUser(String screen_name) throws TwitterException { - List params = new ArrayList<>(3); + List params = new ArrayList<>(); if (screen_name.startsWith("@")) screen_name = screen_name.substring(1); params.add("screen_name=" + StringTools.encode(screen_name)); @@ -308,7 +308,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of users */ public Users getFollowing(long userId, long cursor) throws TwitterException { - List params = new ArrayList<>(5); + List params = new ArrayList<>(); params.add("user_id=" + userId); params.add("cursor=" + cursor); return getUsers1(USER_FOLLOWING, params); @@ -322,7 +322,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of users */ public Users getFollower(long userId, long cursor) throws TwitterException { - List params = new ArrayList<>(5); + List params = new ArrayList<>(); params.add("user_id=" + userId); params.add("cursor=" + cursor); return getUsers1(USER_FOLLOWER, params); @@ -336,7 +336,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of users */ public Users getListMember(long listId, long cursor) throws TwitterException { - List params = new ArrayList<>(5); + List params = new ArrayList<>(); params.add("list_id=" + listId); params.add("cursor=" + cursor); Users result = getUsers1(USER_LIST_MEMBER, params); @@ -357,7 +357,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of users */ public Users getListSubscriber(long listId, long cursor) throws TwitterException { - List params = new ArrayList<>(5); + List params = new ArrayList<>(); params.add("list_id=" + listId); params.add("cursor=" + cursor); Users result = getUsers1(USER_LIST_SUBSCRIBER, params); @@ -377,7 +377,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return relationship infirmation */ public Relation getRelationToUser(long userId) throws TwitterException { - List params = new ArrayList<>(5); + List params = new ArrayList<>(); params.add("source_id=" + settings.getCurrentUserId()); params.add("target_id=" + userId); try { @@ -401,7 +401,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return updated user information */ public User followUser(long userId) throws TwitterException { - List params = new ArrayList<>(4); + List params = new ArrayList<>(); params.add("user_id=" + userId); return getUser1(USER_FOLLOW, params); } @@ -413,7 +413,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return updated user information */ public User unfollowUser(long userId) throws TwitterException { - List params = new ArrayList<>(4); + List params = new ArrayList<>(); params.add("user_id=" + userId); return getUser1(USER_UNFOLLOW, params); } @@ -425,7 +425,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of users */ public Users getBlockedUsers(long cursor) throws TwitterException { - List params = new ArrayList<>(4); + List params = new ArrayList<>(); params.add("cursor=" + cursor); return getUsers1(BLOCK_LIST, params); } @@ -437,7 +437,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return updated user information */ public User blockUser(long userId) throws TwitterException { - List params = new ArrayList<>(4); + List params = new ArrayList<>(); params.add("user_id=" + userId); User user = getUser1(USER_BLOCK, params); filterDatabase.addUser(userId); @@ -451,7 +451,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return updated user information */ public User blockUser(String screen_name) throws TwitterException { - List params = new ArrayList<>(4); + List params = new ArrayList<>(); if (screen_name.startsWith("@")) screen_name = screen_name.substring(1); params.add("screen_name=" + StringTools.encode(screen_name)); @@ -467,7 +467,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return updated user information */ public User unblockUser(long userId) throws TwitterException { - List params = new ArrayList<>(4); + List params = new ArrayList<>(); params.add("user_id=" + userId); return getUser1(USER_UNBLOCK, params); } @@ -479,7 +479,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of users */ public Users getMutedUsers(long cursor) throws TwitterException { - List params = new ArrayList<>(4); + List params = new ArrayList<>(); params.add("cursor=" + cursor); return getUsers1(MUTES_LIST, params); } @@ -491,7 +491,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return updated user information */ public User muteUser(long userId) throws TwitterException { - List params = new ArrayList<>(4); + List params = new ArrayList<>(); params.add("user_id=" + userId); return getUser1(USER_MUTE, params); } @@ -503,7 +503,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return updated user information */ public User muteUser(String screen_name) throws TwitterException { - List params = new ArrayList<>(4); + List params = new ArrayList<>(); if (screen_name.startsWith("@")) screen_name = screen_name.substring(1); params.add("screen_name=" + StringTools.encode(screen_name)); @@ -517,7 +517,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return updated user information */ public User unmuteUser(long userId) throws TwitterException { - List params = new ArrayList<>(4); + List params = new ArrayList<>(); params.add("user_id=" + userId); return getUser1(USER_UNMUTE, params); } @@ -553,7 +553,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of tweets matching the search string */ public List searchTweets(String search, long minId, long maxId) throws TwitterException { - List params = new ArrayList<>(7); + List params = new ArrayList<>(); if (minId > 0) params.add("since_id=" + minId); if (maxId > 1) @@ -578,7 +578,7 @@ public class Twitter implements GlobalSettings.SettingsListener { long currentPage = page > 0 ? page : 1; long nextPage = currentPage + 1; - List params = new ArrayList<>(4); + List params = new ArrayList<>(); params.add("q=" + StringTools.encode(search)); params.add("page=" + currentPage); Users result = getUsers1(USER_SEARCH, params); @@ -600,7 +600,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return trend list */ public List getTrends(int id) throws TwitterException { - List params = new ArrayList<>(2); + List params = new ArrayList<>(); params.add("id=" + id); try { Response response = get(TRENDS, params); @@ -655,7 +655,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of tweets */ public List getHomeTimeline(long minId, long maxId) throws TwitterException { - List params = new ArrayList<>(7); + List params = new ArrayList<>(); if (minId > 0) params.add("since_id=" + minId); if (maxId > 0) @@ -671,7 +671,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of tweets */ public List getMentionTimeline(long minId, long maxId) throws TwitterException { - List params = new ArrayList<>(7); + List params = new ArrayList<>(); if (minId > 0) params.add("since_id=" + minId); if (maxId > 1) @@ -688,7 +688,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of tweets */ public List getUserTimeline(long userId, long minId, long maxId) throws TwitterException { - List params = new ArrayList<>(8); + List params = new ArrayList<>(); if (minId > 0) params.add("since_id=" + minId); if (maxId > 1) @@ -706,7 +706,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of tweets */ public List getUserTimeline(String screen_name, long minId, long maxId) throws TwitterException { - List params = new ArrayList<>(8); + List params = new ArrayList<>(); if (minId > 0) params.add("since_id=" + minId); if (maxId > 1) @@ -724,7 +724,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of tweets */ public List getUserFavorits(long userId, long minId, long maxId) throws TwitterException { - List params = new ArrayList<>(8); + List params = new ArrayList<>(); if (minId > 0) params.add("since_id=" + minId); if (maxId > 1) @@ -742,7 +742,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of tweets */ public List getUserFavorits(String screen_name, long minId, long maxId) throws TwitterException { - List params = new ArrayList<>(8); + List params = new ArrayList<>(); if (minId > 0) params.add("since_id=" + minId); if (maxId > 1) @@ -760,7 +760,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of tweets */ public List getUserlistTweets(long listId, long minId, long maxId) throws TwitterException { - List params = new ArrayList<>(8); + List params = new ArrayList<>(); if (minId > 0) params.add("since_id=" + minId); if (maxId > 1) @@ -779,7 +779,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of tweets */ public List getTweetReplies(String screen_name, long tweetId, long minId, long maxId) throws TwitterException { - List params = new ArrayList<>(7); + List params = new ArrayList<>(); if (minId > 0) params.add("since_id=" + minId); else @@ -809,7 +809,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return tweet information */ public Tweet showTweet(long tweetId) throws TwitterException { - List params = new ArrayList<>(3); + List params = new ArrayList<>(); params.add("id=" + tweetId); return getTweet1(SHOW_TWEET, params); } @@ -821,7 +821,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return updated tweet */ public Tweet favoriteTweet(long tweetId) throws TwitterException { - List params = new ArrayList<>(3); + List params = new ArrayList<>(); params.add("id=" + tweetId); TweetV1 result = getTweet1(TWEET_FAVORITE, params); result.setFavorite(true); @@ -835,7 +835,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return updated tweet */ public Tweet unfavoriteTweet(long tweetId) throws TwitterException { - List params = new ArrayList<>(3); + List params = new ArrayList<>(); params.add("id=" + tweetId); TweetV1 result = getTweet1(TWEET_UNFAVORITE, params); result.setFavorite(false); @@ -849,7 +849,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return updated tweet */ public Tweet retweetTweet(long tweetId) throws TwitterException { - TweetV1 result = getTweet1(TWEET_RETWEET + tweetId + JSON, new ArrayList<>(2)); + TweetV1 result = getTweet1(TWEET_RETWEET + tweetId + JSON, new ArrayList<>()); result.setRetweet(true); return result; } @@ -861,7 +861,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return updated tweet */ public Tweet unretweetTweet(long tweetId) throws TwitterException { - TweetV1 result = getTweet1(TWEET_UNRETWEET + tweetId + JSON, new ArrayList<>(2)); + TweetV1 result = getTweet1(TWEET_UNRETWEET + tweetId + JSON, new ArrayList<>()); result.setRetweet(false); return result; } @@ -875,7 +875,7 @@ public class Twitter implements GlobalSettings.SettingsListener { public void hideReply(long tweetId, boolean hide) throws TwitterException { try { RequestBody body = RequestBody.create(TYPE_JSON, "{\"hidden\":" + hide + "}"); - Response response = put(TWEET_UNI + tweetId + "/hidden", new ArrayList<>(2), body); + Response response = put(TWEET_UNI + tweetId + "/hidden", new ArrayList<>(), body); if (response.body() != null && response.code() == 200) { JSONObject json = new JSONObject(response.body().string()); @@ -897,7 +897,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @param tweetId tweet ID */ public void deleteTweet(long tweetId) throws TwitterException { - getTweet1(TWEET_DELETE + tweetId + JSON, new ArrayList<>(2)); + getTweet1(TWEET_DELETE + tweetId + JSON, new ArrayList<>()); } /** @@ -906,7 +906,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @param update tweet update information */ public void uploadTweet(TweetUpdate update, long[] mediaIds) throws TwitterException { - List params = new ArrayList<>(2); + List params = new ArrayList<>(); params.add("status=" + StringTools.encode(update.getText())); if (update.getReplyId() > 0) params.add("in_reply_to_status_id=" + update.getReplyId()); @@ -933,7 +933,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return updated user list */ public UserList createUserlist(UserlistUpdate update) throws TwitterException { - List params = new ArrayList<>(5); + List params = new ArrayList<>(); params.add("name=" + StringTools.encode(update.getTitle())); params.add("description=" + StringTools.encode(update.getDescription())); if (update.isPublic()) @@ -950,7 +950,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return updated user list */ public UserList updateUserlist(UserlistUpdate update) throws TwitterException { - List params = new ArrayList<>(6); + List params = new ArrayList<>(); params.add("list_id=" + update.getId()); params.add("name=" + StringTools.encode(update.getTitle())); params.add("description=" + StringTools.encode(update.getDescription())); @@ -968,7 +968,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return userlist information */ public UserList getUserlist1(long listId) throws TwitterException { - List params = new ArrayList<>(2); + List params = new ArrayList<>(); params.add("list_id=" + listId); return getUserlist1(USERLIST_SHOW, params); } @@ -980,7 +980,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return userlist information */ public UserList followUserlist(long listId) throws TwitterException { - List params = new ArrayList<>(2); + List params = new ArrayList<>(); params.add("list_id=" + listId); UserListV1 result = getUserlist1(USERLIST_FOLLOW, params); result.setFollowing(true); @@ -994,7 +994,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return userlist information */ public UserList unfollowUserlist(long listId) throws TwitterException { - List params = new ArrayList<>(2); + List params = new ArrayList<>(); params.add("list_id=" + listId); UserListV1 result = getUserlist1(USERLIST_UNFOLLOW, params); result.setFollowing(false); @@ -1008,7 +1008,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return removed userlist */ public UserList deleteUserlist(long listId) throws TwitterException { - List params = new ArrayList<>(2); + List params = new ArrayList<>(); params.add("list_id=" + listId); return getUserlist1(USERLIST_DESTROY, params); } @@ -1021,7 +1021,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of userlists */ public UserLists getUserListOwnerships(long userId, String screen_name) throws TwitterException { - List params = new ArrayList<>(3); + List params = new ArrayList<>(); if (userId > 0) params.add("user_id=" + userId); else @@ -1038,7 +1038,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of userlists */ public UserLists getUserListMemberships(long userId, String screen_name, long cursor) throws TwitterException { - List params = new ArrayList<>(5); + List params = new ArrayList<>(); if (userId > 0) params.add("user_id=" + userId); else @@ -1055,7 +1055,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @param screen_name screen name */ public void addUserToUserlist(long listId, String screen_name) throws TwitterException { - List params = new ArrayList<>(3); + List params = new ArrayList<>(); if (screen_name.startsWith("@")) screen_name = screen_name.substring(1); params.add("list_id=" + listId); @@ -1070,7 +1070,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @param screen_name screen name */ public void removeUserFromUserlist(long listId, String screen_name) throws TwitterException { - List params = new ArrayList<>(3); + List params = new ArrayList<>(); if (screen_name.startsWith("@")) screen_name = screen_name.substring(1); params.add("list_id=" + listId); @@ -1126,7 +1126,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @param messageId ID of the message to delete */ public void deleteDirectmessage(long messageId) throws TwitterException { - List params = new ArrayList<>(2); + List params = new ArrayList<>(); params.add("id=" + messageId); try { Response response = delete(DIRECTMESSAGE_DELETE, params); @@ -1145,7 +1145,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return list of direct messages */ public Directmessages getDirectmessages(String cursor) throws TwitterException { - List params = new ArrayList<>(3); + List params = new ArrayList<>(); params.add("count=" + settings.getListSize()); if (cursor != null && !cursor.isEmpty()) params.add("cursor=" + cursor); @@ -1299,7 +1299,7 @@ public class Twitter implements GlobalSettings.SettingsListener { * @return updated user information */ public User updateProfile(ProfileUpdate update) throws TwitterException { - List params = new ArrayList<>(7); + List params = new ArrayList<>(); params.add("name=" + StringTools.encode(update.getName())); params.add("url=" + StringTools.encode(update.getUrl())); params.add("location=" + StringTools.encode(update.getLocation())); @@ -1337,7 +1337,7 @@ public class Twitter implements GlobalSettings.SettingsListener { // the API returns up to 5000 blocked user IDs // but for bigger lists, we have to parse the whole list for (int i = 0; i < 10 && cursor != 0; i++) { - List params = new ArrayList<>(2); + List params = new ArrayList<>(); params.add("cursor=" + cursor); Response response = get(BLOCK_ID_LIST, params); if (response.body() != null && response.code() == 200) { @@ -1421,7 +1421,14 @@ public class Twitter implements GlobalSettings.SettingsListener { if (response.body() != null && response.code() == 200) { JSONObject json = new JSONObject(response.body().string()); long currentId = settings.getCurrentUserId(); - return new TweetV1(json, currentId); + TweetV1 result = new TweetV1(json, currentId); + // fix: embedded tweet information doesn't match with the parent tweet + // re-downloading embedded tweet information + if (result.getEmbeddedTweet() != null) { + Tweet embedded = showTweet(result.getEmbeddedTweet().getId()); + result.setEmbeddedTweet(embedded); + } + return result; } throw new TwitterException(response); } catch (IOException err) { @@ -1480,7 +1487,7 @@ public class Twitter implements GlobalSettings.SettingsListener { */ private Users getUsers2(String endpoint) throws TwitterException { try { - List params = new ArrayList<>(2); + List params = new ArrayList<>(); params.add(UserV2.PARAMS); Response response = get(endpoint, params); if (response.body() != null && response.code() == 200) { @@ -1619,7 +1626,7 @@ public class Twitter implements GlobalSettings.SettingsListener { */ private void updateImage(String endpoint, InputStream input, String key) throws TwitterException { try { - List params = new ArrayList<>(3); + List params = new ArrayList<>(); params.add("skip_status=true"); params.add("include_entities=false"); Response response = post(endpoint, params, input, key, false); diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/impl/TweetV1.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/impl/TweetV1.java index dbded107..c1edb159 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/impl/TweetV1.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/impl/TweetV1.java @@ -121,12 +121,6 @@ public class TweetV1 implements Tweet { } if (quoted_tweet != null) { embeddedTweet = new TweetV1(quoted_tweet, twitterId); - // API 1.1 bug: - // values of the embedded tweet should match with the parent tweet - // retweeted/favorited values does not match with the values of the embedded tweet - // fix: override retweeted/favorited with the embedded tweets values - isRetweeted = embeddedTweet.isRetweeted(); - isFavorited = embeddedTweet.isFavorited(); } // remove short media link int linkPos = text.lastIndexOf("https://t.co/"); @@ -265,9 +259,9 @@ public class TweetV1 implements Tweet { */ public void setRetweet(boolean isRetweeted) { this.isRetweeted = isRetweeted; - if (isRetweeted) { - retweetCount++; - } else if (retweetCount > 0) { + // note: Twitter API v1.1 doesn't increment/decrement retweet count right + // so we have to correct this number + if (!isRetweeted && retweetCount > 0) { retweetCount--; } if (embeddedTweet instanceof TweetV1) { @@ -282,9 +276,9 @@ public class TweetV1 implements Tweet { */ public void setFavorite(boolean isFavorited) { this.isFavorited = isFavorited; - if (isFavorited) { - favoriteCount++; - } else if (favoriteCount > 0) { + // note: Twitter API v1.1 doesn't increment/decrement favorite count right + // so we have to correct this number + if (!isFavorited && favoriteCount > 0) { favoriteCount--; } if (embeddedTweet instanceof TweetV1) { @@ -292,6 +286,15 @@ public class TweetV1 implements Tweet { } } + /** + * overwrite embedded tweet information + * + * @param tweet new embedded tweet + */ + public void setEmbeddedTweet(Tweet tweet) { + this.embeddedTweet = tweet; + } + /** * add media links to tweet if any */ diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/async/TweetAction.java b/app/src/main/java/org/nuclearfog/twidda/backend/async/TweetAction.java index 42ee68ed..552f1dcb 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/async/TweetAction.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/async/TweetAction.java @@ -19,7 +19,7 @@ import java.lang.ref.WeakReference; * @author nuclearfog * @see TweetActivity */ -public class TweetAction extends AsyncTask { +public class TweetAction extends AsyncTask { /** * actions for the tweet @@ -39,6 +39,7 @@ public class TweetAction extends AsyncTask { RETWEET, /** * remove retweet + * (delete operation, "retweet ID" required) */ UNRETWEET, /** @@ -59,6 +60,7 @@ public class TweetAction extends AsyncTask { UNHIDE, /** * delete own tweet + * (delete operation, "retweet ID" required) */ DELETE } @@ -70,95 +72,95 @@ public class TweetAction extends AsyncTask { private AppDatabase db; private Action action; - private long tweetId, retweetId; - /** - * @param tweetId ID of the tweet + * @param action action for a given tweet */ - public TweetAction(TweetActivity activity, Action action, long tweetId, long retweetId) { + public TweetAction(TweetActivity activity, Action action) { super(); + weakRef = new WeakReference<>(activity); db = new AppDatabase(activity); twitter = Twitter.get(activity); - weakRef = new WeakReference<>(activity); this.action = action; - this.retweetId = retweetId; - this.tweetId = tweetId; } - + /** + * @param ids first value is the tweet ID. The second value is the retweet ID. Required for delete operations + */ @Override - protected Void doInBackground(Void... v) { + protected Void doInBackground(Long... ids) { try { switch (action) { case LD_DB: - Tweet tweet = db.getTweet(tweetId); - if (tweet != null) { - publishProgress(tweet); + Tweet newTweet = db.getTweet(ids[0]); + if (newTweet != null) { + publishProgress(newTweet); } case LOAD: - tweet = twitter.showTweet(tweetId); + newTweet = twitter.showTweet(ids[0]); //tweet = mTwitter.getStatus(tweetId); - publishProgress(tweet); - if (db.containsTweet(tweetId)) { + publishProgress(newTweet); + if (db.containsTweet(ids[0])) { // update tweet if there is a database entry - db.updateTweet(tweet); + db.updateTweet(newTweet); } break; case DELETE: - twitter.deleteTweet(tweetId); - db.removeTweet(tweetId); + twitter.deleteTweet(ids[0]); + db.removeTweet(ids[0]); // removing retweet reference to this tweet - if (retweetId > 0) - db.removeTweet(retweetId); + db.removeTweet(ids[1]); break; case RETWEET: - tweet = twitter.retweetTweet(tweetId); - publishProgress(tweet); - db.updateTweet(tweet); + newTweet = twitter.retweetTweet(ids[0]); + if (newTweet.getEmbeddedTweet() != null) + publishProgress(newTweet.getEmbeddedTweet()); + db.updateTweet(newTweet); break; case UNRETWEET: - tweet = twitter.unretweetTweet(tweetId); - publishProgress(tweet); - db.updateTweet(tweet); + newTweet = twitter.unretweetTweet(ids[0]); + publishProgress(newTweet); + db.updateTweet(newTweet); // removing retweet reference to this tweet - if (retweetId > 0) - db.removeTweet(retweetId); - else - db.removeTweet(tweetId); + db.removeTweet(ids[1]); break; case FAVORITE: - tweet = twitter.favoriteTweet(tweetId); - publishProgress(tweet); - db.storeFavorite(tweet); + newTweet = twitter.favoriteTweet(ids[0]); + publishProgress(newTweet); + db.storeFavorite(newTweet); break; case UNFAVORITE: - tweet = twitter.unfavoriteTweet(tweetId); - publishProgress(tweet); - db.removeFavorite(tweet); + newTweet = twitter.unfavoriteTweet(ids[0]); + publishProgress(newTweet); + db.removeFavorite(newTweet); break; case HIDE: - twitter.hideReply(tweetId, true); - db.hideReply(tweetId, true); + twitter.hideReply(ids[0], true); + db.hideReply(ids[0], true); break; case UNHIDE: - twitter.hideReply(tweetId, false); - db.hideReply(tweetId, false); + twitter.hideReply(ids[0], false); + db.hideReply(ids[0], false); break; } } catch (TwitterException twException) { this.twException = twException; if (twException.getErrorType() == ErrorHandler.TwitterError.RESOURCE_NOT_FOUND) { - db.removeTweet(tweetId); + // delete database entry if tweet was not found + db.removeTweet(ids[0]); + if (ids.length > 1) { + // also remove reference to this tweet + db.removeTweet(ids[1]); + } } } return null; @@ -179,9 +181,9 @@ public class TweetAction extends AsyncTask { TweetActivity activity = weakRef.get(); if (activity != null) { if (twException == null) { - activity.OnSuccess(action, tweetId); + activity.OnSuccess(action); } else { - activity.onError(twException, tweetId); + activity.onError(twException); } } } diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/TweetActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/TweetActivity.java index f2489c80..3b50fc86 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/TweetActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/TweetActivity.java @@ -78,37 +78,38 @@ public class TweetActivity extends AppCompatActivity implements OnClickListener, OnLongClickListener, OnTagClickListener, OnConfirmListener { /** - * return code if a tweet was not found + * Activity result code to update existing tweet information */ public static final int RETURN_TWEET_UPDATE = 0x789CD38B; /** - * return code if a tweet was not found + * Activity result code if a tweet was not found or removed */ - public static final int RETURN_TWEET_NOT_FOUND = 0x8B03DB84; + public static final int RETURN_TWEET_REMOVED = 0x8B03DB84; /** - * ID of the tweet to open. required - */ - public static final String KEY_TWEET_ID = "tweet_tweet_id"; - - /** - * screen name of the author. optional - */ - public static final String KEY_TWEET_NAME = "tweet_author"; - - /** - * key for a tweet object + * bundle key for a {@link Tweet} value. + * If no tweet object exists, {@link #KEY_TWEET_ID} and {@link #KEY_TWEET_NAME} will be used instead */ public static final String KEY_TWEET_DATA = "tweet_data"; /** - * Key to return an ID of a removed tweet + * {@link Bundle} key for the Tweet ID value, alternative to {@link #KEY_TWEET_DATA} + */ + public static final String KEY_TWEET_ID = "tweet_tweet_id"; + + /** + * {@link Bundle} key for the tweet author's name. alternative to {@link #KEY_TWEET_DATA} + */ + public static final String KEY_TWEET_NAME = "tweet_author"; + + /** + * {@link Intent} key to return a tweet object with updated information */ public static final String INTENT_TWEET_UPDATE_DATA = "tweet_update_data"; /** - * Key to return an ID of a removed tweet + * @link Intent} key to return a tweet ID if this tweet was deleted */ public static final String INTENT_TWEET_REMOVED_ID = "tweet_removed_id"; @@ -237,15 +238,16 @@ public class TweetActivity extends AppCompatActivity implements OnClickListener, if (statusAsync == null) { // print Tweet object and get and update it if (tweet != null) { - statusAsync = new TweetAction(this, Action.LOAD, tweet.getId(), -1L); + statusAsync = new TweetAction(this, Action.LOAD); + statusAsync.execute(tweet.getId()); setTweet(tweet); } // Load Tweet from database first if no tweet is defined else { long tweetId = getIntent().getLongExtra(KEY_TWEET_ID, -1); - statusAsync = new TweetAction(this, Action.LD_DB, tweetId, -1L); + statusAsync = new TweetAction(this, Action.LD_DB); + statusAsync.execute(tweetId); } - statusAsync.execute(); } } @@ -332,11 +334,11 @@ public class TweetActivity extends AppCompatActivity implements OnClickListener, // hide tweet else if (item.getItemId() == R.id.menu_tweet_hide) { if (hidden) { - statusAsync = new TweetAction(this, Action.UNHIDE, tweet.getId(), -1L); + statusAsync = new TweetAction(this, Action.UNHIDE); } else { - statusAsync = new TweetAction(this, Action.HIDE, tweet.getId(), -1L); + statusAsync = new TweetAction(this, Action.HIDE); } - statusAsync.execute(); + statusAsync.execute(tweet.getId()); } // get tweet link else if (item.getItemId() == R.id.menu_tweet_browser) { @@ -353,7 +355,7 @@ public class TweetActivity extends AppCompatActivity implements OnClickListener, else if (item.getItemId() == R.id.menu_tweet_copy_text) { ClipboardManager clip = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); if (clip != null) { - ClipData linkClip = ClipData.newPlainText("tweet text", tweet.getText()); + ClipData linkClip = ClipData.newPlainText("tweet text", clickedTweet.getText()); clip.setPrimaryClip(linkClip); Toast.makeText(this, R.string.info_tweet_text_copied, LENGTH_SHORT).show(); } @@ -372,7 +374,7 @@ public class TweetActivity extends AppCompatActivity implements OnClickListener, // copy media links else if (item.getGroupId() == MENU_GROUP_COPY) { int index = item.getItemId(); - Uri[] mediaLinks = tweet.getMediaUris(); + Uri[] mediaLinks = clickedTweet.getMediaUris(); if (index >= 0 && index < mediaLinks.length) { ClipboardManager clip = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); if (clip != null) { @@ -481,25 +483,29 @@ public class TweetActivity extends AppCompatActivity implements OnClickListener, @Override public boolean onLongClick(View v) { if (tweet != null && (statusAsync == null || statusAsync.getStatus() != RUNNING)) { + Tweet clickedTweet = tweet; + if (tweet.getEmbeddedTweet() != null) { + clickedTweet = tweet.getEmbeddedTweet(); + } // retweet this tweet if (v.getId() == R.id.tweet_retweet) { - if (tweet.isRetweeted()) { - statusAsync = new TweetAction(this, Action.UNRETWEET, tweet.getId(), tweet.getRetweetId()); + if (clickedTweet.isRetweeted()) { + statusAsync = new TweetAction(this, Action.UNRETWEET); } else { - statusAsync = new TweetAction(this, Action.RETWEET, tweet.getId(), tweet.getRetweetId()); + statusAsync = new TweetAction(this, Action.RETWEET); } - statusAsync.execute(); + statusAsync.execute(clickedTweet.getId(), clickedTweet.getRetweetId()); Toast.makeText(this, R.string.info_loading, LENGTH_SHORT).show(); return true; } // favorite the tweet else if (v.getId() == R.id.tweet_favorite) { - if (tweet.isFavorited()) { - statusAsync = new TweetAction(this, Action.UNFAVORITE, tweet.getId(), tweet.getRetweetId()); + if (clickedTweet.isFavorited()) { + statusAsync = new TweetAction(this, Action.UNFAVORITE); } else { - statusAsync = new TweetAction(this, Action.FAVORITE, tweet.getId(), tweet.getRetweetId()); + statusAsync = new TweetAction(this, Action.FAVORITE); } - statusAsync.execute(); + statusAsync.execute(clickedTweet.getId()); Toast.makeText(this, R.string.info_loading, LENGTH_SHORT).show(); return true; } @@ -516,8 +522,8 @@ public class TweetActivity extends AppCompatActivity implements OnClickListener, clickedTweet = tweet.getEmbeddedTweet(); } if (type == DialogType.TWEET_DELETE) { - statusAsync = new TweetAction(this, Action.DELETE, clickedTweet.getId(), tweet.getRetweetId()); - statusAsync.execute(); + statusAsync = new TweetAction(this, Action.DELETE); + statusAsync.execute(clickedTweet.getId(), clickedTweet.getRetweetId()); } else if (type == DialogType.PROXY_CONFIRM) { settings.setIgnoreProxyWarning(rememberChoice); @@ -703,9 +709,8 @@ public class TweetActivity extends AppCompatActivity implements OnClickListener, * called after a tweet action * * @param action action type - * @param tweetId ID of the tweet */ - public void OnSuccess(Action action, long tweetId) { + public void OnSuccess(Action action) { switch (action) { case RETWEET: Toast.makeText(this, R.string.info_tweet_retweeted, LENGTH_SHORT).show(); @@ -713,6 +718,7 @@ public class TweetActivity extends AppCompatActivity implements OnClickListener, case UNRETWEET: Toast.makeText(this, R.string.info_tweet_unretweeted, LENGTH_SHORT).show(); + // todo remove old retweet from list fragment break; case FAVORITE: @@ -742,11 +748,16 @@ public class TweetActivity extends AppCompatActivity implements OnClickListener, break; case DELETE: - Toast.makeText(this, R.string.info_tweet_removed, LENGTH_SHORT).show(); - Intent returnData = new Intent(); - returnData.putExtra(INTENT_TWEET_REMOVED_ID, tweetId); - setResult(RETURN_TWEET_NOT_FOUND, returnData); - finish(); + if (tweet != null) { + Toast.makeText(this, R.string.info_tweet_removed, LENGTH_SHORT).show(); + Intent returnData = new Intent(); + if (tweet.getEmbeddedTweet() != null) + returnData.putExtra(INTENT_TWEET_REMOVED_ID, tweet.getEmbeddedTweet().getId()); + else + returnData.putExtra(INTENT_TWEET_REMOVED_ID, tweet.getId()); + setResult(RETURN_TWEET_REMOVED, returnData); + finish(); + } break; } } @@ -755,18 +766,19 @@ public class TweetActivity extends AppCompatActivity implements OnClickListener, * called when an error occurs * * @param error Error information - * @param tweetId ID of the tweet from which an error occurred */ - public void onError(@Nullable TwitterException error, long tweetId) { + public void onError(@Nullable TwitterException error) { ErrorHandler.handleFailure(this, error); - if (error != null && error.getErrorType() == ErrorHandler.TwitterError.RESOURCE_NOT_FOUND) { - // Mark tweet as removed, so it can be removed from the list - Intent returnData = new Intent(); - returnData.putExtra(INTENT_TWEET_REMOVED_ID, tweetId); - setResult(RETURN_TWEET_NOT_FOUND, returnData); - finish(); - } else if (tweet == null) { + if (tweet == null) { finish(); + } else { + if (error != null && error.getErrorType() == ErrorHandler.TwitterError.RESOURCE_NOT_FOUND) { + // Mark tweet as removed, so it can be removed from the list + Intent returnData = new Intent(); + returnData.putExtra(INTENT_TWEET_REMOVED_ID, tweet.getId()); + setResult(RETURN_TWEET_REMOVED, returnData); + finish(); + } } } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/fragments/TweetFragment.java b/app/src/main/java/org/nuclearfog/twidda/ui/fragments/TweetFragment.java index fe31c3dc..7ecf5dd0 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/fragments/TweetFragment.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/fragments/TweetFragment.java @@ -149,7 +149,7 @@ public class TweetFragment extends ListFragment implements TweetClickListener { Tweet updateTweet = (Tweet) data; adapter.updateItem(updateTweet); } - } else if (returnCode == TweetActivity.RETURN_TWEET_NOT_FOUND) { + } else if (returnCode == TweetActivity.RETURN_TWEET_REMOVED) { long removedTweetId = intent.getLongExtra(TweetActivity.INTENT_TWEET_REMOVED_ID, 0); adapter.remove(removedTweetId); }