385 lines
15 KiB
Java
385 lines
15 KiB
Java
/*
|
|
* Copyright (C) 2020 Stefan Schüller <sschueller@techdroid.com>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
package net.schueller.peertube.fragment;
|
|
|
|
import android.Manifest;
|
|
import android.app.Activity;
|
|
import android.content.Context;
|
|
import android.content.pm.PackageManager;
|
|
import android.content.res.ColorStateList;
|
|
import android.content.res.TypedArray;
|
|
import android.os.Bundle;
|
|
import android.util.Log;
|
|
import android.util.TypedValue;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.Button;
|
|
import android.widget.ImageView;
|
|
import android.widget.TextView;
|
|
import android.widget.Toast;
|
|
|
|
import com.mikepenz.iconics.Iconics;
|
|
import com.squareup.picasso.Picasso;
|
|
|
|
import net.schueller.peertube.R;
|
|
import net.schueller.peertube.helper.APIUrlHelper;
|
|
import net.schueller.peertube.helper.ErrorHelper;
|
|
import net.schueller.peertube.helper.MetaDataHelper;
|
|
import net.schueller.peertube.intents.Intents;
|
|
import net.schueller.peertube.model.Account;
|
|
import net.schueller.peertube.model.Avatar;
|
|
import net.schueller.peertube.model.Rating;
|
|
import net.schueller.peertube.model.Video;
|
|
import net.schueller.peertube.network.GetVideoDataService;
|
|
import net.schueller.peertube.network.RetrofitInstance;
|
|
import net.schueller.peertube.network.Session;
|
|
import net.schueller.peertube.service.VideoPlayerService;
|
|
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.appcompat.widget.PopupMenu;
|
|
import androidx.core.app.ActivityCompat;
|
|
import androidx.fragment.app.Fragment;
|
|
import okhttp3.RequestBody;
|
|
import okhttp3.ResponseBody;
|
|
import retrofit2.Call;
|
|
import retrofit2.Callback;
|
|
import retrofit2.Response;
|
|
|
|
public class VideoMetaDataFragment extends Fragment {
|
|
|
|
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 ColorStateList defaultTextColor;
|
|
|
|
private boolean leaveAppExpected = false;
|
|
|
|
@Override
|
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
|
Bundle savedInstanceState) {
|
|
|
|
// Inflate the layout for this fragment
|
|
return inflater.inflate(R.layout.fragment_video_meta, container, false);
|
|
}
|
|
|
|
@Override
|
|
public void onPause()
|
|
{
|
|
leaveAppExpected = false;
|
|
super.onPause();
|
|
}
|
|
|
|
public boolean isLeaveAppExpected()
|
|
{
|
|
return leaveAppExpected;
|
|
}
|
|
|
|
public void updateVideoMeta(Video video, VideoPlayerService mService) {
|
|
Context context = getContext();
|
|
Activity activity = getActivity();
|
|
|
|
String apiBaseURL = APIUrlHelper.getUrlWithVersion(context);
|
|
GetVideoDataService videoDataService = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(context)).create(GetVideoDataService.class);
|
|
|
|
// Thumbs up
|
|
Button thumbsUpButton = activity.findViewById(R.id.video_thumbs_up);
|
|
defaultTextColor = thumbsUpButton.getTextColors();
|
|
thumbsUpButton.setText(R.string.video_thumbs_up_icon);
|
|
new Iconics.Builder().on(thumbsUpButton).build();
|
|
thumbsUpButton.setOnClickListener(v -> {
|
|
rateVideo(true, video);
|
|
});
|
|
|
|
// Thumbs Down
|
|
Button thumbsDownButton = activity.findViewById(R.id.video_thumbs_down);
|
|
thumbsDownButton.setText(R.string.video_thumbs_down_icon);
|
|
new Iconics.Builder().on(thumbsDownButton).build();
|
|
thumbsDownButton.setOnClickListener(v -> {
|
|
rateVideo(false, video);
|
|
});
|
|
|
|
// video rating
|
|
videoRating = new Rating();
|
|
videoRating.setRating(RATING_NONE); // default
|
|
updateVideoRating(video);
|
|
|
|
// Retrieve which rating the user gave to this video
|
|
if (Session.getInstance().isLoggedIn()) {
|
|
Call<Rating> call = videoDataService.getVideoRating(video.getId());
|
|
call.enqueue(new Callback<Rating>() {
|
|
|
|
@Override
|
|
public void onResponse(Call<Rating> call, Response<Rating> response) {
|
|
videoRating = response.body();
|
|
updateVideoRating(video);
|
|
}
|
|
|
|
@Override
|
|
public void onFailure(Call<Rating> call, Throwable t) {
|
|
ErrorHelper.showToastFromCommunicationError( getActivity(), t );
|
|
// Do nothing.
|
|
}
|
|
});
|
|
}
|
|
|
|
// Share
|
|
Button videoShareButton = activity.findViewById(R.id.video_share);
|
|
videoShareButton.setText(R.string.video_share_icon);
|
|
new Iconics.Builder().on(videoShareButton).build();
|
|
videoShareButton.setOnClickListener(v ->
|
|
{
|
|
leaveAppExpected = true;
|
|
Intents.Share( context, video );
|
|
} );
|
|
|
|
// Download
|
|
Button videoDownloadButton = activity.findViewById(R.id.video_download);
|
|
videoDownloadButton.setText(R.string.video_download_icon);
|
|
new Iconics.Builder().on(videoDownloadButton).build();
|
|
videoDownloadButton.setOnClickListener(v -> {
|
|
// get permission to store file
|
|
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
|
leaveAppExpected = true;
|
|
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
|
|
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
|
Intents.Download(context, video);
|
|
} else {
|
|
Toast.makeText(context, getString(R.string.video_download_permission_error), Toast.LENGTH_LONG).show();
|
|
}
|
|
} else {
|
|
Intents.Download(context, video);
|
|
}
|
|
});
|
|
|
|
Account account = video.getAccount();
|
|
|
|
// owner / creator Avatar
|
|
Avatar avatar = account.getAvatar();
|
|
if (avatar != null) {
|
|
ImageView avatarView = activity.findViewById(R.id.avatar);
|
|
String baseUrl = APIUrlHelper.getUrl(context);
|
|
String avatarPath = avatar.getPath();
|
|
Picasso.get()
|
|
.load(baseUrl + avatarPath)
|
|
.into(avatarView);
|
|
}
|
|
|
|
|
|
// title / name
|
|
TextView videoName = activity.findViewById(R.id.sl_row_name);
|
|
videoName.setText(video.getName());
|
|
|
|
// created at / views
|
|
TextView videoMeta = activity.findViewById(R.id.videoMeta);
|
|
videoMeta.setText(
|
|
MetaDataHelper.getMetaString(
|
|
video.getCreatedAt(),
|
|
video.getViews(),
|
|
context
|
|
)
|
|
);
|
|
|
|
// owner / creator
|
|
TextView videoOwner = activity.findViewById(R.id.videoOwner);
|
|
videoOwner.setText(
|
|
MetaDataHelper.getOwnerString(video.getAccount().getName(),
|
|
video.getAccount().getHost(),
|
|
context
|
|
)
|
|
);
|
|
|
|
// description
|
|
TextView videoDescription = activity.findViewById(R.id.description);
|
|
videoDescription.setText(video.getDescription());
|
|
|
|
// video privacy
|
|
TextView videoPrivacy = activity.findViewById(R.id.video_privacy);
|
|
videoPrivacy.setText(video.getPrivacy().getLabel());
|
|
|
|
// video category
|
|
TextView videoCategory = activity.findViewById(R.id.video_category);
|
|
videoCategory.setText(video.getCategory().getLabel());
|
|
|
|
// video privacy
|
|
TextView videoLicense = activity.findViewById(R.id.video_license);
|
|
videoLicense.setText(video.getLicence().getLabel());
|
|
|
|
// video language
|
|
TextView videoLanguage = activity.findViewById(R.id.video_language);
|
|
videoLanguage.setText(video.getLanguage().getLabel());
|
|
|
|
// video privacy
|
|
TextView videoTags = activity.findViewById(R.id.video_tags);
|
|
videoTags.setText(android.text.TextUtils.join(", ", video.getTags()));
|
|
|
|
// more button
|
|
TextView moreButton = activity.findViewById(R.id.moreButton);
|
|
moreButton.setText(R.string.video_more_icon);
|
|
new Iconics.Builder().on(moreButton).build();
|
|
|
|
moreButton.setOnClickListener(v -> {
|
|
PopupMenu popup = new PopupMenu(context, v);
|
|
popup.setOnMenuItemClickListener(menuItem -> {
|
|
switch (menuItem.getItemId()) {
|
|
case R.id.video_more_report:
|
|
Log.v(TAG, "Report");
|
|
Toast.makeText(context, "Not Implemented", Toast.LENGTH_SHORT).show();
|
|
return true;
|
|
case R.id.video_more_blacklist:
|
|
Log.v(TAG, "Blacklist");
|
|
Toast.makeText(context, "Not Implemented", Toast.LENGTH_SHORT).show();
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
});
|
|
popup.inflate(R.menu.menu_video_more);
|
|
popup.show();
|
|
});
|
|
|
|
// video player options
|
|
TextView videoOptions = activity.findViewById(R.id.exo_more);
|
|
videoOptions.setText(R.string.video_more_icon);
|
|
new Iconics.Builder().on(videoOptions).build();
|
|
|
|
videoOptions.setOnClickListener(v -> {
|
|
VideoOptionsFragment videoOptionsFragment =
|
|
VideoOptionsFragment.newInstance(mService, video.getFiles());
|
|
videoOptionsFragment.show(getActivity().getSupportFragmentManager(),
|
|
VideoOptionsFragment.TAG);
|
|
});
|
|
|
|
}
|
|
|
|
void updateVideoRating(Video video) {
|
|
Button thumbsUpButton = getActivity().findViewById(R.id.video_thumbs_up);
|
|
Button thumbsDownButton = getActivity().findViewById(R.id.video_thumbs_down);
|
|
|
|
TypedValue typedValue = new TypedValue();
|
|
|
|
TypedArray a = getContext().obtainStyledAttributes(typedValue.data, new int[]{R.attr.colorPrimary});
|
|
int accentColor = a.getColor(0, 0);
|
|
|
|
// Change the color of the thumbs
|
|
switch (videoRating.getRating()) {
|
|
case RATING_NONE:
|
|
thumbsUpButton.setTextColor(defaultTextColor);
|
|
thumbsDownButton.setTextColor(defaultTextColor);
|
|
break;
|
|
case RATING_LIKE:
|
|
thumbsUpButton.setTextColor(accentColor);
|
|
thumbsDownButton.setTextColor(defaultTextColor);
|
|
break;
|
|
case RATING_DISLIKE:
|
|
thumbsUpButton.setTextColor(defaultTextColor);
|
|
thumbsDownButton.setTextColor(accentColor);
|
|
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();
|
|
}
|
|
|
|
void rateVideo(Boolean like, Video video) {
|
|
if (Session.getInstance().isLoggedIn()) {
|
|
final String ratePayload;
|
|
|
|
switch (videoRating.getRating()) {
|
|
case RATING_LIKE:
|
|
ratePayload = like ? RATING_NONE : RATING_DISLIKE;
|
|
break;
|
|
case RATING_DISLIKE:
|
|
ratePayload = like ? RATING_LIKE : RATING_NONE;
|
|
break;
|
|
case RATING_NONE:
|
|
default:
|
|
ratePayload = like ? RATING_LIKE : RATING_DISLIKE;
|
|
break;
|
|
}
|
|
|
|
RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json"), "{\"rating\":\"" + ratePayload + "\"}");
|
|
|
|
String apiBaseURL = APIUrlHelper.getUrlWithVersion(getContext());
|
|
GetVideoDataService videoDataService = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(getContext())).create(GetVideoDataService.class);
|
|
|
|
Call<ResponseBody> call = videoDataService.rateVideo(video.getId(), body);
|
|
|
|
call.enqueue(new Callback<ResponseBody>() {
|
|
|
|
@Override
|
|
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
|
|
//Log.v(TAG, response.toString());
|
|
|
|
// if 20x, update likes/dislikes
|
|
if (response.isSuccessful()) {
|
|
String previousRating = videoRating.getRating();
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onFailure(Call<ResponseBody> call, Throwable t) {
|
|
Toast.makeText(getContext(), getString(R.string.video_rating_failed), Toast.LENGTH_SHORT).show();
|
|
}
|
|
});
|
|
} else {
|
|
Toast.makeText(getContext(), getString(R.string.video_login_required_for_service), Toast.LENGTH_SHORT).show();
|
|
}
|
|
}
|
|
|
|
}
|