From b5e9f70be68bf50553199fb9e146e5182f685bbd Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 3 Jan 2021 12:10:34 +0100 Subject: [PATCH] Allow to reblog/unreblog, favourite/unfavourite, bookmark/unbookmark videos from mastodon/pleroma Accounts --- app/src/acad/res/values/colors.xml | 2 + app/src/bittube/res/values/colors.xml | 2 + app/src/full/res/values/colors.xml | 2 + .../app/fedilab/fedilabtube/MainActivity.java | 2 +- .../fedilab/fedilabtube/PeertubeActivity.java | 96 ++++++++++++++ .../client/mastodon/MastodonService.java | 39 ++++++ .../client/mastodon/RetrofitMastodonAPI.java | 118 +++++++++++++----- .../fedilabtube/client/mastodon/Status.java | 57 ++++++++- .../mastodon/MastodonPostActionsVM.java | 48 +++++++ .../res/drawable/ic_baseline_bookmark_24.xml | 2 +- .../res/drawable/ic_baseline_repeat_24.xml | 10 ++ .../main/res/drawable/ic_baseline_star_24.xml | 10 ++ app/src/main/res/layout/activity_peertube.xml | 48 +++++++ app/src/queermotion/res/values/colors.xml | 2 + 14 files changed, 403 insertions(+), 35 deletions(-) create mode 100644 app/src/main/res/drawable/ic_baseline_repeat_24.xml create mode 100644 app/src/main/res/drawable/ic_baseline_star_24.xml diff --git a/app/src/acad/res/values/colors.xml b/app/src/acad/res/values/colors.xml index 41d179b..47924aa 100644 --- a/app/src/acad/res/values/colors.xml +++ b/app/src/acad/res/values/colors.xml @@ -7,6 +7,8 @@ #bbF2690D #FAFAFA #2b90d9 + #ca8f04 + #795548 #F44336 #DD000000 #F44336 diff --git a/app/src/bittube/res/values/colors.xml b/app/src/bittube/res/values/colors.xml index e40a9ba..0f32543 100644 --- a/app/src/bittube/res/values/colors.xml +++ b/app/src/bittube/res/values/colors.xml @@ -7,6 +7,8 @@ #bbF2690D #FAFAFA #2b90d9 + #ca8f04 + #795548 #F44336 #DD000000 #F44336 diff --git a/app/src/full/res/values/colors.xml b/app/src/full/res/values/colors.xml index 8d944f0..ad81ecc 100644 --- a/app/src/full/res/values/colors.xml +++ b/app/src/full/res/values/colors.xml @@ -7,6 +7,8 @@ #FAFAFA #2b90d9 #F44336 + #ca8f04 + #795548 #DD000000 #F44336 #80808080 diff --git a/app/src/main/java/app/fedilab/fedilabtube/MainActivity.java b/app/src/main/java/app/fedilab/fedilabtube/MainActivity.java index bcfe17e..38ad953 100644 --- a/app/src/main/java/app/fedilab/fedilabtube/MainActivity.java +++ b/app/src/main/java/app/fedilab/fedilabtube/MainActivity.java @@ -943,7 +943,7 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen UNKNOWN, NORMAL, SURFING, - REMOTE_ACCOUNT + REMOTE_ACCOUNT, } private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter { diff --git a/app/src/main/java/app/fedilab/fedilabtube/PeertubeActivity.java b/app/src/main/java/app/fedilab/fedilabtube/PeertubeActivity.java index 4517192..fa3b6a0 100644 --- a/app/src/main/java/app/fedilab/fedilabtube/PeertubeActivity.java +++ b/app/src/main/java/app/fedilab/fedilabtube/PeertubeActivity.java @@ -142,6 +142,7 @@ import app.fedilab.fedilabtube.client.entities.MenuItemView; import app.fedilab.fedilabtube.client.entities.PlaylistExist; import app.fedilab.fedilabtube.client.entities.Report; import app.fedilab.fedilabtube.client.entities.UserSettings; +import app.fedilab.fedilabtube.client.mastodon.RetrofitMastodonAPI; import app.fedilab.fedilabtube.databinding.ActivityPeertubeBinding; import app.fedilab.fedilabtube.drawer.CommentListAdapter; import app.fedilab.fedilabtube.drawer.MenuAdapter; @@ -218,6 +219,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd private boolean isRemote; private boolean willPlayFromIntent; private String chromeCastVideoURL; + private app.fedilab.fedilabtube.client.mastodon.Status status; public static void hideKeyboard(Activity activity) { if (activity != null && activity.getWindow() != null) { @@ -366,6 +368,15 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd willPlayFromIntent = manageIntentUrl(intent); + if (BuildConfig.allow_remote_connections && Helper.isLoggedInType(PeertubeActivity.this) == MainActivity.TypeOfConnection.REMOTE_ACCOUNT) { + binding.peertubeLikeCount.setVisibility(View.GONE); + binding.peertubeDislikeCount.setVisibility(View.GONE); + binding.peertubePlaylist.setVisibility(View.GONE); + binding.peertubeReblog.setVisibility(View.VISIBLE); + binding.peertubeFavorite.setVisibility(View.VISIBLE); + binding.peertubeBookmark.setVisibility(View.VISIBLE); + } + binding.peertubeDescriptionMore.setOnClickListener(v -> { if (show_more_content != null && peertube != null) { if (binding.peertubeDescriptionMore.getText().toString().compareTo(getString(R.string.show_more)) == 0) { @@ -1088,6 +1099,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd binding.writeCommentContainer.setVisibility(View.GONE); } + if (peertube.isNsfw()) { binding.videoSensitive.setVisibility(View.VISIBLE); } else { @@ -1209,6 +1221,24 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd changeColor(); initResolution(); + binding.peertubeReblog.setOnClickListener(v -> { + MastodonPostActionsVM mastodonPostActionsVM = new ViewModelProvider(PeertubeActivity.this).get(MastodonPostActionsVM.class); + RetrofitMastodonAPI.actionType type = status.isReblogged() ? RetrofitMastodonAPI.actionType.UNBOOST : RetrofitMastodonAPI.actionType.BOOST; + mastodonPostActionsVM.post(type, status).observe(PeertubeActivity.this, this::manageVIewPostActionsMastodon); + }); + + binding.peertubeFavorite.setOnClickListener(v -> { + MastodonPostActionsVM mastodonPostActionsVM = new ViewModelProvider(PeertubeActivity.this).get(MastodonPostActionsVM.class); + RetrofitMastodonAPI.actionType type = status.isFavourited() ? RetrofitMastodonAPI.actionType.UNFAVOURITE : RetrofitMastodonAPI.actionType.FAVOURITE; + mastodonPostActionsVM.post(type, status).observe(PeertubeActivity.this, this::manageVIewPostActionsMastodon); + }); + + binding.peertubeBookmark.setOnClickListener(v -> { + MastodonPostActionsVM mastodonPostActionsVM = new ViewModelProvider(PeertubeActivity.this).get(MastodonPostActionsVM.class); + RetrofitMastodonAPI.actionType type = status.isBookmarked() ? RetrofitMastodonAPI.actionType.UNBOOKMARK : RetrofitMastodonAPI.actionType.BOOKMARK; + mastodonPostActionsVM.post(type, status).observe(PeertubeActivity.this, this::manageVIewPostActionsMastodon); + }); + binding.peertubeLikeCount.setOnClickListener(v -> { if (isLoggedIn(PeertubeActivity.this) && !sepiaSearch) { String newState = peertube.getMyRating().equals("like") ? "none" : "like"; @@ -1260,6 +1290,11 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd } }); + if (BuildConfig.allow_remote_connections && Helper.isLoggedInType(PeertubeActivity.this) == MainActivity.TypeOfConnection.REMOTE_ACCOUNT) { + String url = "https://" + peertube.getChannel().getHost() + "/videos/watch/" + peertube.getUuid(); + MastodonPostActionsVM postActionsVM = new ViewModelProvider(PeertubeActivity.this).get(MastodonPostActionsVM.class); + postActionsVM.searchRemoteStatus(url).observe(PeertubeActivity.this, this::retrieveRemoteStatus); + } if (mode != Helper.VIDEO_MODE_WEBVIEW) { @@ -2173,6 +2208,17 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd binding.postComment.startAnimation(animateComment); } + public void manageVIewPostActionsMastodon(app.fedilab.fedilabtube.client.mastodon.Status status) { + if (status != null) { + this.status = status; + changeColorMastodon(); + binding.peertubeFavorite.setText(String.valueOf(status.getFavouriteCount())); + binding.peertubeReblog.setText(String.valueOf(status.getReblogsCount())); + } else { + Toasty.error(PeertubeActivity.this, getString(R.string.toast_error), Toasty.LENGTH_LONG).show(); + } + } + public void manageVIewPostActionsMastodon(RetrofitPeertubeAPI.ActionType statusAction, int position, app.fedilab.fedilabtube.client.mastodon.Status status) { if (peertube.isCommentsEnabled() && statusAction == ADD_COMMENT) { if (status != null) { @@ -2192,6 +2238,15 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd } } + public void retrieveRemoteStatus(app.fedilab.fedilabtube.client.mastodon.Status status) { + this.status = status; + if (status != null) { + changeColorMastodon(); + binding.peertubeFavorite.setText(String.valueOf(status.getFavouriteCount())); + binding.peertubeReblog.setText(String.valueOf(status.getReblogsCount())); + } + } + @SuppressWarnings({"unused", "RedundantSuppression"}) public void manageVIewPostActions(RetrofitPeertubeAPI.ActionType statusAction, int position, APIResponse apiResponse) { @@ -2269,6 +2324,47 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd } } + + private void changeColorMastodon() { + Drawable reblog = ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_repeat_24); + Drawable favorite = ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_star_24); + Drawable bookmark = ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_bookmark_24); + + int color = getAttColor(this, android.R.attr.colorControlNormal); + + if (reblog != null) { + reblog.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + DrawableCompat.setTint(reblog, color); + } + if (favorite != null) { + favorite.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + DrawableCompat.setTint(favorite, color); + } + + if (bookmark != null) { + bookmark.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + DrawableCompat.setTint(bookmark, color); + } + + if (status.isReblogged()) { + reblog.setColorFilter(getResources().getColor(R.color.positive_thumbs), PorterDuff.Mode.SRC_ATOP); + DrawableCompat.setTint(reblog, getResources().getColor(R.color.positive_thumbs)); + } + if (status.isFavourited()) { + favorite.setColorFilter(getResources().getColor(R.color.favorite), PorterDuff.Mode.SRC_ATOP); + DrawableCompat.setTint(favorite, getResources().getColor(R.color.favorite)); + } + + if (status.isBookmarked()) { + bookmark.setColorFilter(getResources().getColor(R.color.bookmark), PorterDuff.Mode.SRC_ATOP); + DrawableCompat.setTint(bookmark, getResources().getColor(R.color.bookmark)); + } + + binding.peertubeReblog.setCompoundDrawablesWithIntrinsicBounds(null, reblog, null, null); + binding.peertubeFavorite.setCompoundDrawablesWithIntrinsicBounds(null, favorite, null, null); + binding.peertubeBookmark.setCompoundDrawablesWithIntrinsicBounds(null, bookmark, null, null); + } + private void changeColor() { Drawable thumbUp = ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_thumb_up_alt_24); diff --git a/app/src/main/java/app/fedilab/fedilabtube/client/mastodon/MastodonService.java b/app/src/main/java/app/fedilab/fedilabtube/client/mastodon/MastodonService.java index 94c946c..e547f10 100644 --- a/app/src/main/java/app/fedilab/fedilabtube/client/mastodon/MastodonService.java +++ b/app/src/main/java/app/fedilab/fedilabtube/client/mastodon/MastodonService.java @@ -23,6 +23,7 @@ import retrofit2.http.FormUrlEncoded; import retrofit2.http.GET; import retrofit2.http.Header; import retrofit2.http.POST; +import retrofit2.http.Path; import retrofit2.http.Query; interface MastodonService { @@ -60,4 +61,42 @@ interface MastodonService { @Query("visibility") String visibility ); + + @POST("statuses/{id}/reblog") + Call boost( + @Header("Authorization") String credentials, + @Path("id") String id + ); + + @POST("statuses/{id}/unreblog") + Call unBoost( + @Header("Authorization") String credentials, + @Path("id") String id + ); + + + @POST("statuses/{id}/favourite") + Call favourite( + @Header("Authorization") String credentials, + @Path("id") String id + ); + + @POST("statuses/{id}/unfavourite") + Call unfavourite( + @Header("Authorization") String credentials, + @Path("id") String id + ); + + + @POST("statuses/{id}/bookmark") + Call bookmark( + @Header("Authorization") String credentials, + @Path("id") String id + ); + + @POST("statuses/{id}/unbookmark") + Call unbookmark( + @Header("Authorization") String credentials, + @Path("id") String id + ); } diff --git a/app/src/main/java/app/fedilab/fedilabtube/client/mastodon/RetrofitMastodonAPI.java b/app/src/main/java/app/fedilab/fedilabtube/client/mastodon/RetrofitMastodonAPI.java index a9a8c92..01e7a83 100644 --- a/app/src/main/java/app/fedilab/fedilabtube/client/mastodon/RetrofitMastodonAPI.java +++ b/app/src/main/java/app/fedilab/fedilabtube/client/mastodon/RetrofitMastodonAPI.java @@ -49,6 +49,30 @@ public class RetrofitMastodonAPI { private String instance; private String token; + public Status search(String url) throws Error { + MastodonService mastodonService2 = init2(); + Call statusCall = mastodonService2.searchMessage(getToken(), url); + Response response; + try { + response = statusCall.execute(); + if (response.isSuccessful() && response.body() != null && response.body().getStatuses() != null && response.body().getStatuses().size() > 0) { + return response.body().getStatuses().get(0); + } else { + Error error = new Error(); + error.setStatusCode(response.code()); + if (response.errorBody() != null) { + error.setError(response.errorBody().string()); + } else { + error.setError(_context.getString(R.string.toast_error)); + } + throw error; + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + public RetrofitMastodonAPI(Context context) { _context = context; @@ -231,44 +255,76 @@ public class RetrofitMastodonAPI { public Status commentAction(String url, String content) throws Error { MastodonService mastodonService = init(); - MastodonService mastodonService2 = init2(); - Call statusCall = mastodonService2.searchMessage(getToken(), url); - Response response; - try { - response = statusCall.execute(); - if (response.isSuccessful() && response.body() != null && response.body().getStatuses() != null && response.body().getStatuses().size() > 0) { - Status status = response.body().getStatuses().get(0); - if (status != null) { - Call postReplyCall = mastodonService.postReply(getToken(), status.getId(), content, null); - try { - Response responsePost = postReplyCall.execute(); - if (responsePost.isSuccessful()) { - Status statusReturned = responsePost.body(); - if (statusReturned != null && statusReturned.getAccount() != null) { - statusReturned.getAccount().setHost(instance); - } - return statusReturned; - } - } catch (IOException e) { - e.printStackTrace(); + Status status = search(url); + if (status != null) { + Call postReplyCall = mastodonService.postReply(getToken(), status.getId(), content, null); + try { + Response responsePost = postReplyCall.execute(); + if (responsePost.isSuccessful()) { + Status statusReturned = responsePost.body(); + if (statusReturned != null && statusReturned.getAccount() != null) { + statusReturned.getAccount().setHost(instance); } + return statusReturned; } - } else { - Error error = new Error(); - error.setStatusCode(response.code()); - if (response.errorBody() != null) { - error.setError(response.errorBody().string()); - } else { - error.setError(_context.getString(R.string.toast_error)); - } - throw error; + } catch (IOException e) { + e.printStackTrace(); } - } catch (IOException e) { - e.printStackTrace(); } return null; } + public Status postAction(actionType type, Status status) throws Error { + MastodonService mastodonService = init(); + Call postAction = null; + if (status != null) { + switch (type) { + case BOOST: + postAction = mastodonService.boost(getToken(), status.getId()); + break; + case UNBOOST: + postAction = mastodonService.unBoost(getToken(), status.getId()); + break; + case FAVOURITE: + postAction = mastodonService.favourite(getToken(), status.getId()); + break; + case UNFAVOURITE: + postAction = mastodonService.unfavourite(getToken(), status.getId()); + break; + case BOOKMARK: + postAction = mastodonService.bookmark(getToken(), status.getId()); + break; + case UNBOOKMARK: + postAction = mastodonService.unbookmark(getToken(), status.getId()); + break; + } + try { + if (postAction != null) { + Response responsePost = postAction.execute(); + if (responsePost.isSuccessful()) { + Status statusReturned = responsePost.body(); + if (statusReturned != null && statusReturned.getAccount() != null) { + statusReturned.getAccount().setHost(instance); + } + return statusReturned; + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + + + public enum actionType { + BOOST, + UNBOOST, + FAVOURITE, + UNFAVOURITE, + BOOKMARK, + UNBOOKMARK + } private String getToken() { if (token != null) { diff --git a/app/src/main/java/app/fedilab/fedilabtube/client/mastodon/Status.java b/app/src/main/java/app/fedilab/fedilabtube/client/mastodon/Status.java index f34ddd4..1577cec 100644 --- a/app/src/main/java/app/fedilab/fedilabtube/client/mastodon/Status.java +++ b/app/src/main/java/app/fedilab/fedilabtube/client/mastodon/Status.java @@ -16,13 +16,12 @@ package app.fedilab.fedilabtube.client.mastodon; import com.google.gson.annotations.SerializedName; -import org.w3c.dom.Comment; - import java.util.Date; import app.fedilab.fedilabtube.client.data.CommentData; +@SuppressWarnings("unused") public class Status { @SerializedName("id") @@ -37,6 +36,16 @@ public class Status { private String text; @SerializedName("created_at") private Date createdAt; + @SerializedName("reblogs_count") + private int reblogsCount; + @SerializedName("favourites_count") + private int favouritesCount; + @SerializedName("favourited") + private boolean favourited; + @SerializedName("reblogged") + private boolean reblogged; + @SerializedName("bookmarked") + private boolean bookmarked; public static CommentData.Comment convertStatusToComment(Status status) { CommentData.Comment comment = new CommentData.Comment(); @@ -93,4 +102,48 @@ public class Status { public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; } + + public int getReblogsCount() { + return reblogsCount; + } + + public void setReblogsCount(int reblogsCount) { + this.reblogsCount = reblogsCount; + } + + public int getFavouriteCount() { + return favouritesCount; + } + + public boolean isFavourited() { + return favourited; + } + + public void setFavourited(boolean favourited) { + this.favourited = favourited; + } + + public boolean isReblogged() { + return reblogged; + } + + public void setReblogged(boolean reblogged) { + this.reblogged = reblogged; + } + + public int getFavouritesCount() { + return favouritesCount; + } + + public void setFavouritesCount(int favouritesCount) { + this.favouritesCount = favouritesCount; + } + + public boolean isBookmarked() { + return bookmarked; + } + + public void setBookmarked(boolean bookmarked) { + this.bookmarked = bookmarked; + } } diff --git a/app/src/main/java/app/fedilab/fedilabtube/viewmodel/mastodon/MastodonPostActionsVM.java b/app/src/main/java/app/fedilab/fedilabtube/viewmodel/mastodon/MastodonPostActionsVM.java index a8b649e..ae6fdbc 100644 --- a/app/src/main/java/app/fedilab/fedilabtube/viewmodel/mastodon/MastodonPostActionsVM.java +++ b/app/src/main/java/app/fedilab/fedilabtube/viewmodel/mastodon/MastodonPostActionsVM.java @@ -37,12 +37,44 @@ public class MastodonPostActionsVM extends AndroidViewModel { } + public LiveData post(RetrofitMastodonAPI.actionType type, Status status) { + statusMutableLiveData = new MutableLiveData<>(); + postAction(type, status); + return statusMutableLiveData; + } + public LiveData comment(String url, String content) { statusMutableLiveData = new MutableLiveData<>(); postComment(url, content); return statusMutableLiveData; } + public LiveData searchRemoteStatus(String url) { + statusMutableLiveData = new MutableLiveData<>(); + search(url); + return statusMutableLiveData; + } + + private void search(String videoURL) { + Context _mContext = getApplication().getApplicationContext(); + new Thread(() -> { + try { + RetrofitMastodonAPI mastodonAPI = new RetrofitMastodonAPI(_mContext); + Status status = null; + try { + status = mastodonAPI.search(videoURL); + } catch (Error error) { + error.printStackTrace(); + } + Handler mainHandler = new Handler(Looper.getMainLooper()); + Status finalStatus = status; + Runnable myRunnable = () -> statusMutableLiveData.setValue(finalStatus); + mainHandler.post(myRunnable); + } catch (Exception e) { + e.printStackTrace(); + } + }).start(); + } private void postComment(String videoURL, String content) { Context _mContext = getApplication().getApplicationContext(); @@ -65,4 +97,20 @@ public class MastodonPostActionsVM extends AndroidViewModel { }).start(); } + + private void postAction(RetrofitMastodonAPI.actionType type, Status status) { + Context _mContext = getApplication().getApplicationContext(); + new Thread(() -> { + try { + RetrofitMastodonAPI mastodonAPI = new RetrofitMastodonAPI(_mContext); + Status statusReply = mastodonAPI.postAction(type, status); + Handler mainHandler = new Handler(Looper.getMainLooper()); + Runnable myRunnable = () -> statusMutableLiveData.setValue(statusReply); + mainHandler.post(myRunnable); + } catch (Exception | Error e) { + e.printStackTrace(); + } + }).start(); + } + } diff --git a/app/src/main/res/drawable/ic_baseline_bookmark_24.xml b/app/src/main/res/drawable/ic_baseline_bookmark_24.xml index 78ef499..f77ecc7 100644 --- a/app/src/main/res/drawable/ic_baseline_bookmark_24.xml +++ b/app/src/main/res/drawable/ic_baseline_bookmark_24.xml @@ -1,8 +1,8 @@ + + diff --git a/app/src/main/res/drawable/ic_baseline_star_24.xml b/app/src/main/res/drawable/ic_baseline_star_24.xml new file mode 100644 index 0000000..6335165 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_star_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/activity_peertube.xml b/app/src/main/res/layout/activity_peertube.xml index e8aa674..e79789d 100644 --- a/app/src/main/res/layout/activity_peertube.xml +++ b/app/src/main/res/layout/activity_peertube.xml @@ -272,6 +272,54 @@ app:drawableTopCompat="@drawable/ic_baseline_thumb_down_alt_24" tools:ignore="HardcodedText" /> + + + + + + #bb864692 #FAFAFA #2b90d9 + #ca8f04 + #795548 #F44336 #DD000000 #F44336