Completed implementation of Likes & Dislikes

* Added the ability to change the rating from Like to Dislike and vice versa without having to "undo" the rating beforehand.
* Fixed Likes/Dislikes counters not being incremented/decremented (it previously required to go back and then re-open the video page to see the change).
* Improved overall code performance and readability by removing redundant calls.
* Fixed some typos in comments
* Removed "video_rating_none", "video_rating_like" and "video_rating_dislike" from strings.xml as they were not translatable and only used in the code without ever being displayed to the user.
This commit is contained in:
Florian CUNY 2020-07-05 14:39:50 +02:00
parent 90029aaf76
commit 52c593b9f1
2 changed files with 78 additions and 66 deletions

View File

@ -65,6 +65,10 @@ public class VideoMetaDataFragment extends Fragment {
private static final String TAG = "VideoMetaDataFragment"; private static final String TAG = "VideoMetaDataFragment";
private static final String RATING_NONE = "none";
private static final String RATING_LIKE = "like";
private static final String RATING_DISLIKE = "dislike";
private Rating videoRating; private Rating videoRating;
private ColorStateList defaultTextColor; private ColorStateList defaultTextColor;
@ -72,13 +76,11 @@ public class VideoMetaDataFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
// Inflate the layout for this fragment // Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_video_meta, container, false); return inflater.inflate(R.layout.fragment_video_meta, container, false);
} }
public void updateVideoMeta(Video video, VideoPlayerService mService) { public void updateVideoMeta(Video video, VideoPlayerService mService) {
Context context = getContext(); Context context = getContext();
Activity activity = getActivity(); Activity activity = getActivity();
@ -91,26 +93,23 @@ public class VideoMetaDataFragment extends Fragment {
thumbsUpButton.setText(R.string.video_thumbs_up_icon); thumbsUpButton.setText(R.string.video_thumbs_up_icon);
new Iconics.IconicsBuilder().ctx(context).on(thumbsUpButton).build(); new Iconics.IconicsBuilder().ctx(context).on(thumbsUpButton).build();
thumbsUpButton.setOnClickListener(v -> { thumbsUpButton.setOnClickListener(v -> {
rateVideo(true, video.getId()); rateVideo(true, video);
}); });
TextView thumbsUpButtonTotal = activity.findViewById(R.id.video_thumbs_up_total);
thumbsUpButtonTotal.setText(video.getLikes().toString());
// Thumbs Down // Thumbs Down
Button thumbsDownButton = activity.findViewById(R.id.video_thumbs_down); Button thumbsDownButton = activity.findViewById(R.id.video_thumbs_down);
thumbsDownButton.setText(R.string.video_thumbs_down_icon); thumbsDownButton.setText(R.string.video_thumbs_down_icon);
new Iconics.IconicsBuilder().ctx(context).on(thumbsDownButton).build(); new Iconics.IconicsBuilder().ctx(context).on(thumbsDownButton).build();
thumbsDownButton.setOnClickListener(v -> { thumbsDownButton.setOnClickListener(v -> {
rateVideo(false, video.getId()); rateVideo(false, video);
}); });
// video rating // video rating
videoRating = new Rating(); videoRating = new Rating();
videoRating.setRating("none"); // default videoRating.setRating(RATING_NONE); // default
updateVideoRating(); updateVideoRating(video);
// Retrieve which rating the user gave to this video
if (Session.getInstance().isLoggedIn()) { if (Session.getInstance().isLoggedIn()) {
Call<Rating> call = videoDataService.getVideoRating(video.getId()); Call<Rating> call = videoDataService.getVideoRating(video.getId());
call.enqueue(new Callback<Rating>() { call.enqueue(new Callback<Rating>() {
@ -118,20 +117,16 @@ public class VideoMetaDataFragment extends Fragment {
@Override @Override
public void onResponse(Call<Rating> call, Response<Rating> response) { public void onResponse(Call<Rating> call, Response<Rating> response) {
videoRating = response.body(); videoRating = response.body();
updateVideoRating(); updateVideoRating(video);
} }
@Override @Override
public void onFailure(Call<Rating> call, Throwable t) { public void onFailure(Call<Rating> call, Throwable t) {
// Toast.makeText(context, "Rating Failed", Toast.LENGTH_SHORT).show(); // Do nothing.
} }
}); });
} }
TextView thumbsDownButtonTotal = activity.findViewById(R.id.video_thumbs_down_total);
thumbsDownButtonTotal.setText(video.getDislikes().toString());
// Share // Share
Button videoShareButton = activity.findViewById(R.id.video_share); Button videoShareButton = activity.findViewById(R.id.video_share);
videoShareButton.setText(R.string.video_share_icon); videoShareButton.setText(R.string.video_share_icon);
@ -156,7 +151,6 @@ public class VideoMetaDataFragment extends Fragment {
} }
}); });
Account account = video.getAccount(); Account account = video.getAccount();
// owner / creator Avatar // owner / creator Avatar
@ -198,7 +192,6 @@ public class VideoMetaDataFragment extends Fragment {
TextView videoDescription = activity.findViewById(R.id.description); TextView videoDescription = activity.findViewById(R.id.description);
videoDescription.setText(video.getDescription()); videoDescription.setText(video.getDescription());
// video privacy // video privacy
TextView videoPrivacy = activity.findViewById(R.id.video_privacy); TextView videoPrivacy = activity.findViewById(R.id.video_privacy);
videoPrivacy.setText(video.getPrivacy().getLabel()); videoPrivacy.setText(video.getPrivacy().getLabel());
@ -211,7 +204,7 @@ public class VideoMetaDataFragment extends Fragment {
TextView videoLicense = activity.findViewById(R.id.video_license); TextView videoLicense = activity.findViewById(R.id.video_license);
videoLicense.setText(video.getLicence().getLabel()); videoLicense.setText(video.getLicence().getLabel());
// video langauge // video language
TextView videoLanguage = activity.findViewById(R.id.video_language); TextView videoLanguage = activity.findViewById(R.id.video_language);
videoLanguage.setText(video.getLanguage().getLabel()); videoLanguage.setText(video.getLanguage().getLabel());
@ -219,7 +212,6 @@ public class VideoMetaDataFragment extends Fragment {
TextView videoTags = activity.findViewById(R.id.video_tags); TextView videoTags = activity.findViewById(R.id.video_tags);
videoTags.setText(android.text.TextUtils.join(", ", video.getTags())); videoTags.setText(android.text.TextUtils.join(", ", video.getTags()));
// more button // more button
TextView moreButton = activity.findViewById(R.id.moreButton); TextView moreButton = activity.findViewById(R.id.moreButton);
moreButton.setText(R.string.video_more_icon); moreButton.setText(R.string.video_more_icon);
@ -259,8 +251,7 @@ public class VideoMetaDataFragment extends Fragment {
} }
void updateVideoRating(Video video) {
void updateVideoRating() {
Button thumbsUpButton = getActivity().findViewById(R.id.video_thumbs_up); Button thumbsUpButton = getActivity().findViewById(R.id.video_thumbs_up);
Button thumbsDownButton = getActivity().findViewById(R.id.video_thumbs_down); Button thumbsDownButton = getActivity().findViewById(R.id.video_thumbs_down);
@ -269,44 +260,46 @@ public class VideoMetaDataFragment extends Fragment {
TypedArray a = getContext().obtainStyledAttributes(typedValue.data, new int[]{R.attr.colorPrimary}); TypedArray a = getContext().obtainStyledAttributes(typedValue.data, new int[]{R.attr.colorPrimary});
int accentColor = a.getColor(0, 0); int accentColor = a.getColor(0, 0);
if (videoRating.getRating().equals(getString(R.string.video_rating_none))) { // Change the color of the thumbs
switch (videoRating.getRating()) {
case RATING_NONE:
thumbsUpButton.setTextColor(defaultTextColor); thumbsUpButton.setTextColor(defaultTextColor);
thumbsDownButton.setTextColor(defaultTextColor); thumbsDownButton.setTextColor(defaultTextColor);
//Log.v(TAG, getString(R.string.video_rating_none)); break;
case RATING_LIKE:
} else if (videoRating.getRating().equals(getString(R.string.video_rating_like))) {
thumbsUpButton.setTextColor(accentColor); thumbsUpButton.setTextColor(accentColor);
thumbsDownButton.setTextColor(defaultTextColor); thumbsDownButton.setTextColor(defaultTextColor);
//Log.v(TAG, getString(R.string.video_rating_like)); break;
case RATING_DISLIKE:
} else if (videoRating.getRating().equals(getString(R.string.video_rating_dislike))) {
thumbsUpButton.setTextColor(defaultTextColor); thumbsUpButton.setTextColor(defaultTextColor);
thumbsDownButton.setTextColor(accentColor); thumbsDownButton.setTextColor(accentColor);
//Log.v(TAG, getString(R.string.video_rating_dislike)); break;
} }
// Update the texts
TextView thumbsDownTotal = getActivity().findViewById(R.id.video_thumbs_down_total);
TextView thumbsUpTotal = getActivity().findViewById(R.id.video_thumbs_up_total);
thumbsUpTotal.setText(String.valueOf(video.getLikes()));
thumbsDownTotal.setText(String.valueOf(video.getDislikes()));
a.recycle(); a.recycle();
} }
void rateVideo(Boolean rate, Integer videoId) { void rateVideo(Boolean like, Video video) {
// TODO cleanup
if (Session.getInstance().isLoggedIn()) { if (Session.getInstance().isLoggedIn()) {
final String ratePayload;
String ratePayload = getString(R.string.video_rating_none); switch (videoRating.getRating()) {
case RATING_LIKE:
if (rate) { ratePayload = like ? RATING_NONE : RATING_DISLIKE;
// thumbsup break;
if (videoRating.getRating().equals(getString(R.string.video_rating_none))) { case RATING_DISLIKE:
ratePayload = getString(R.string.video_rating_like); ratePayload = like ? RATING_LIKE : RATING_NONE;
} break;
} else { case RATING_NONE:
// thumbsdown default:
if (videoRating.getRating().equals(getString(R.string.video_rating_none))) { ratePayload = like ? RATING_LIKE : RATING_DISLIKE;
ratePayload = getString(R.string.video_rating_dislike); break;
}
} }
RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json"), "{\"rating\":\"" + ratePayload + "\"}"); RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json"), "{\"rating\":\"" + ratePayload + "\"}");
@ -314,23 +307,47 @@ public class VideoMetaDataFragment extends Fragment {
String apiBaseURL = APIUrlHelper.getUrlWithVersion(getContext()); String apiBaseURL = APIUrlHelper.getUrlWithVersion(getContext());
GetVideoDataService videoDataService = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class); GetVideoDataService videoDataService = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class);
Call<ResponseBody> call = videoDataService.rateVideo(videoId, body); Call<ResponseBody> call = videoDataService.rateVideo(video.getId(), body);
final String newRating = ratePayload;
call.enqueue(new Callback<ResponseBody>() { call.enqueue(new Callback<ResponseBody>() {
@Override @Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//Log.v(TAG, response.toString()); //Log.v(TAG, response.toString());
// if 20x update likes // if 20x, update likes/dislikes
if (response.isSuccessful()) { if (response.isSuccessful()) {
videoRating.setRating(newRating); String previousRating = videoRating.getRating();
updateVideoRating();
// TODO: update count under thumb // Update the likes/dislikes count of the video, if needed.
// This is only a visual trick, as the actual like/dislike count has
// already been modified on the PeerTube instance.
if (!previousRating.equals(ratePayload)) {
switch (previousRating) {
case RATING_NONE:
if (ratePayload.equals(RATING_LIKE)) {
video.setLikes(video.getLikes() + 1);
} else {
video.setDislikes(video.getDislikes() + 1);
}
break;
case RATING_LIKE:
video.setLikes(video.getLikes() - 1);
if (ratePayload.equals(RATING_DISLIKE)) {
video.setDislikes(video.getDislikes() + 1);
}
break;
case RATING_DISLIKE:
video.setDislikes(video.getDislikes() - 1);
if (ratePayload.equals(RATING_LIKE)) {
video.setLikes(video.getLikes() + 1);
}
break;
}
}
videoRating.setRating(ratePayload);
updateVideoRating(video);
} }
} }
@ -341,9 +358,7 @@ public class VideoMetaDataFragment extends Fragment {
}); });
} else { } else {
Toast.makeText(getContext(), getString(R.string.video_login_required_for_service), Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), getString(R.string.video_login_required_for_service), Toast.LENGTH_SHORT).show();
} }
} }
} }

View File

@ -352,9 +352,6 @@
<string name="server_book_add_password">Password</string> <string name="server_book_add_password">Password</string>
<string name="server_book_add_add_button">Add</string> <string name="server_book_add_add_button">Add</string>
<string name="server_book_list_has_login">Has Login</string> <string name="server_book_list_has_login">Has Login</string>
<string name="video_rating_none" translatable="false">none</string>
<string name="video_rating_like" translatable="false">like</string>
<string name="video_rating_dislike" translatable="false">dislike</string>
<string name="peertube_required_server_version" translatable="false">1.0.0-alpha.7</string> <string name="peertube_required_server_version" translatable="false">1.0.0-alpha.7</string>
<string name="login_current_server_hint">Current Server</string> <string name="login_current_server_hint">Current Server</string>
<string name="title_activity_server_address_book">Address Book</string> <string name="title_activity_server_address_book">Address Book</string>