Some layouts improvements

This commit is contained in:
Thomas 2023-03-20 18:23:39 +01:00
parent b6a8df9410
commit 3da5cdf703
4 changed files with 607 additions and 216 deletions

View File

@ -59,6 +59,7 @@ import java.util.Map;
import app.fedilab.android.R;
import app.fedilab.android.databinding.DrawerPeertubeBinding;
import app.fedilab.android.databinding.DrawerPeertubeListBinding;
import app.fedilab.android.peertube.activities.PeertubeActivity;
import app.fedilab.android.peertube.activities.PeertubeEditUploadActivity;
import app.fedilab.android.peertube.activities.ShowChannelActivity;
@ -90,6 +91,22 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
private ChannelData.Channel forChannel;
private AccountData.PeertubeAccount forAccount;
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
boolean videoInList = sharedpreferences.getBoolean(context.getString(R.string.set_video_in_list_choice), false);
if (videoInList) {
DrawerPeertubeListBinding itemBinding = DrawerPeertubeListBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
return new VideoListViewHolder(itemBinding);
} else {
DrawerPeertubeBinding itemBinding = DrawerPeertubeBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
return new VideoViewHolder(itemBinding);
}
}
public PeertubeAdapter(List<VideoData.Video> videos, TimelineVM.TimelineType timelineType, boolean sepiaSearch, ChannelData.Channel forChannel, AccountData.PeertubeAccount forAccount) {
this.videos = videos;
this.timelineType = timelineType;
@ -103,95 +120,385 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
this.videos = videos;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
DrawerPeertubeBinding itemBinding = DrawerPeertubeBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
return new ViewHolder(itemBinding);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
final ViewHolder holder = (ViewHolder) viewHolder;
final VideoData.Video video = videos.get(position);
if (video == null) {
return;
}
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
boolean videoInList = sharedpreferences.getBoolean(context.getString(R.string.set_video_in_list_choice), false);
boolean ownVideos;
if (timelineType == TimelineVM.TimelineType.MY_VIDEOS) {
ownVideos = true;
} else {
ownVideos = Helper.isVideoOwner(context, video);
}
String instance = null;
if (sepiaSearch) {
instance = video.getAccount().getHost();
} else if (forChannel != null) {
instance = forChannel.getHost();
} else if (forAccount != null) {
instance = forAccount.getHost();
}
holder.binding.peertubeDisplayname.setText(video.getChannel().getDisplayName());
holder.binding.peertubeUsername.setText(video.getChannel().getAcct());
Helper.loadAvatar(context, video.getChannel(), holder.binding.peertubeChannelAvatar);
holder.binding.peertubeTitle.setText(video.getName());
if (video.isLive()) {
holder.binding.peertubeDuration.setText(R.string.live);
holder.binding.peertubeDuration.setBackgroundResource(R.drawable.rounded_live);
} else {
holder.binding.peertubeDuration.setText(Helper.secondsToString(video.getDuration()));
holder.binding.peertubeDuration.setBackgroundResource(R.drawable.rounded_corner);
}
holder.binding.peertubeDate.setText(String.format(" - %s", Helper.dateDiff(context, video.getCreatedAt())));
holder.binding.peertubeViews.setText(context.getString(R.string.number_view_video, Helper.withSuffix(video.getViews())));
boolean blur = sharedpreferences.getString(context.getString(R.string.set_video_sensitive_choice), Helper.BLUR).compareTo("blur") == 0 && video.isNsfw();
if (videoInList) {
Helper.loadGiF(context, instance, video.getThumbnailPath(), holder.binding.peertubeVideoImageSmall, blur);
holder.binding.peertubeVideoImageSmall.setVisibility(View.VISIBLE);
holder.binding.previewContainer.setVisibility(View.GONE);
} else {
loadImage(holder.binding.peertubeVideoImage, instance, video.getPreviewPath(), video.getThumbnailPath(), blur);
holder.binding.peertubeVideoImageSmall.setVisibility(View.GONE);
holder.binding.previewContainer.setVisibility(View.VISIBLE);
}
final VideoListViewHolder holder = (VideoListViewHolder) viewHolder;
final VideoData.Video video = videos.get(position);
//For Overview Videos: boolean values for displaying title is managed in the fragment
if (video.isHasTitle()) {
holder.binding.headerTitle.setVisibility(View.VISIBLE);
switch (video.getTitleType()) {
case TAG:
holder.binding.headerTitle.setText(String.format("#%s", video.getTitle()));
break;
case CHANNEL:
case CATEGORY:
holder.binding.headerTitle.setText(String.format("%s", video.getTitle()));
break;
if (video == null) {
return;
}
} else {
holder.binding.headerTitle.setVisibility(View.GONE);
}
if (!ownVideos) {
holder.binding.peertubeChannelInfo.setOnClickListener(v -> {
Intent intent = new Intent(context, ShowChannelActivity.class);
boolean ownVideos;
if (timelineType == TimelineVM.TimelineType.MY_VIDEOS) {
ownVideos = true;
} else {
ownVideos = Helper.isVideoOwner(context, video);
}
String instance = null;
if (sepiaSearch) {
instance = video.getAccount().getHost();
} else if (forChannel != null) {
instance = forChannel.getHost();
} else if (forAccount != null) {
instance = forAccount.getHost();
}
holder.binding.peertubeDisplayname.setText(video.getChannel().getDisplayName());
holder.binding.peertubeUsername.setText(video.getChannel().getAcct());
Helper.loadAvatar(context, video.getChannel(), holder.binding.peertubeChannelAvatar);
holder.binding.peertubeTitle.setText(video.getName());
if (video.isLive()) {
holder.binding.peertubeDuration.setText(R.string.live);
holder.binding.peertubeDuration.setBackgroundResource(R.drawable.rounded_live);
} else {
holder.binding.peertubeDuration.setText(Helper.secondsToString(video.getDuration()));
holder.binding.peertubeDuration.setBackgroundResource(R.drawable.rounded_corner);
}
holder.binding.peertubeDate.setText(String.format(" - %s", Helper.dateDiffFull(video.getCreatedAt())));
holder.binding.peertubeViews.setText(context.getString(R.string.number_view_video, Helper.withSuffix(video.getViews())));
boolean blur = sharedpreferences.getString(context.getString(R.string.set_video_sensitive_choice), Helper.BLUR).compareTo("blur") == 0 && video.isNsfw();
loadImage(holder.binding.peertubeVideoImage, instance, video.getPreviewPath(), video.getThumbnailPath(), blur);
holder.binding.previewContainer.setVisibility(View.VISIBLE);
//For Overview Videos: boolean values for displaying title is managed in the fragment
if (video.isHasTitle()) {
holder.binding.headerTitle.setVisibility(View.VISIBLE);
switch (video.getTitleType()) {
case TAG:
holder.binding.headerTitle.setText(String.format("#%s", video.getTitle()));
break;
case CHANNEL:
case CATEGORY:
holder.binding.headerTitle.setText(String.format("%s", video.getTitle()));
break;
}
} else {
holder.binding.headerTitle.setVisibility(View.GONE);
}
if (!ownVideos) {
holder.binding.peertubeChannelInfo.setOnClickListener(v -> {
Intent intent = new Intent(context, ShowChannelActivity.class);
Bundle b = new Bundle();
b.putSerializable("channel", video.getChannel());
b.putBoolean("sepia_search", sepiaSearch || forChannel != null);
if (sepiaSearch || forChannel != null) {
b.putString("peertube_instance", video.getAccount().getHost());
}
intent.putExtras(b);
context.startActivity(intent);
});
}
holder.binding.moreActions.setOnClickListener(view -> {
PopupMenu popup = new PopupMenu(context, holder.binding.moreActions);
popup.getMenuInflater()
.inflate(R.menu.video_drawer_menu_peertube, popup.getMenu());
if (timelineType == MY_VIDEOS) {
popup.getMenu().findItem(R.id.action_report).setVisible(false);
popup.getMenu().findItem(R.id.action_follow).setVisible(false);
} else {
popup.getMenu().findItem(R.id.action_edit).setVisible(false);
if (relationShipListener == null || relationShipListener.getRelationShip() == null || relationShipListener.getRelationShip().size() == 0) {
popup.getMenu().findItem(R.id.action_follow).setVisible(false);
} else {
popup.getMenu().findItem(R.id.action_follow).setVisible(true);
if (relationShipListener.getRelationShip().containsKey(video.getChannel().getAcct()) && relationShipListener.getRelationShip().get(video.getChannel().getAcct())) {
popup.getMenu().findItem(R.id.action_follow).setTitle(context.getString(R.string.action_unfollow));
} else {
popup.getMenu().findItem(R.id.action_follow).setTitle(context.getString(R.string.action_follow));
}
}
}
popup.getMenu().findItem(R.id.action_playlist).setVisible(playlistListener != null && playlistListener.getPlaylist() != null && playlistListener.getPlaylist().size() != 0);
popup.setOnMenuItemClickListener(item -> {
int itemId = item.getItemId();
if (itemId == R.id.action_follow) {
if (relationShipListener.getRelationShip().containsKey(video.getChannel().getAcct()) && relationShipListener.getRelationShip().get(video.getChannel().getAcct())) {
relationShipListener.getRelationShip().put(video.getChannel().getAcct(), false);
popup.getMenu().findItem(R.id.action_follow).setTitle(context.getString(R.string.action_follow));
boolean confirm_unfollow = sharedpreferences.getBoolean(Helper.SET_UNFOLLOW_VALIDATION, true);
if (confirm_unfollow) {
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(context);
unfollowConfirm.setTitle(context.getString(R.string.unfollow_confirm));
unfollowConfirm.setMessage(video.getChannel().getAcct());
unfollowConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
unfollowConfirm.setPositiveButton(R.string.yes, (dialog, which) -> {
PostActionsVM viewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(PostActionsVM.class);
viewModel.post(UNFOLLOW, video.getChannel().getAcct(), null).observe((LifecycleOwner) context, apiResponse -> manageVIewPostActions(UNFOLLOW, apiResponse));
dialog.dismiss();
});
unfollowConfirm.show();
} else {
PostActionsVM viewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(PostActionsVM.class);
viewModel.post(UNFOLLOW, video.getChannel().getAcct(), null).observe((LifecycleOwner) context, apiResponse -> manageVIewPostActions(UNFOLLOW, apiResponse));
}
} else {
relationShipListener.getRelationShip().put(video.getChannel().getAcct(), true);
popup.getMenu().findItem(R.id.action_follow).setTitle(context.getString(R.string.action_unfollow));
PostActionsVM viewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(PostActionsVM.class);
viewModel.post(FOLLOW, video.getChannel().getAcct(), null).observe((LifecycleOwner) context, apiResponse -> manageVIewPostActions(FOLLOW, apiResponse));
}
} else if (itemId == R.id.action_playlist) {
PlaylistsVM viewModelOwnerPlaylist = new ViewModelProvider((ViewModelStoreOwner) context).get(PlaylistsVM.class);
viewModelOwnerPlaylist.manage(PlaylistsVM.action.GET_PLAYLISTS, null, null).observe((LifecycleOwner) context, apiResponse -> manageVIewPlaylists(video, apiResponse));
} else if (itemId == R.id.action_edit) {
Intent intent = new Intent(context, PeertubeEditUploadActivity.class);
Bundle b = new Bundle();
b.putString("video_id", video.getUuid());
intent.putExtras(b);
context.startActivity(intent);
} else if (itemId == R.id.action_report) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(context);
LayoutInflater inflater1 = ((Activity) context).getLayoutInflater();
View dialogView = inflater1.inflate(R.layout.popup_report_peertube, new LinearLayout(context), false);
dialogBuilder.setView(dialogView);
EditText report_content = dialogView.findViewById(R.id.report_content);
dialogBuilder.setNeutralButton(R.string.cancel, (dialog2, id) -> dialog2.dismiss());
dialogBuilder.setPositiveButton(R.string.report, (dialog2, id) -> {
if (report_content.getText().toString().trim().length() == 0) {
Toasty.info(context, context.getString(R.string.report_comment_size), Toasty.LENGTH_LONG).show();
} else {
PostActionsVM viewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(PostActionsVM.class);
Report report = new Report();
Report.VideoReport videoReport = new Report.VideoReport();
videoReport.setId(video.getId());
report.setVideo(videoReport);
report.setReason(report_content.getText().toString());
viewModel.report(report).observe((LifecycleOwner) context, apiResponse -> manageVIewPostActions(RetrofitPeertubeAPI.ActionType.REPORT_VIDEO, apiResponse));
dialog2.dismiss();
}
});
AlertDialog alertDialog2 = dialogBuilder.create();
alertDialog2.show();
}
return true;
});
popup.show();
});
holder.binding.peertubeVideoInfo.setOnClickListener(v -> {
Intent intent = new Intent(context, PeertubeActivity.class);
Bundle b = new Bundle();
b.putSerializable("channel", video.getChannel());
b.putBoolean("sepia_search", sepiaSearch || forChannel != null);
if (sepiaSearch || forChannel != null) {
b.putString("video_id", video.getId());
b.putString("video_uuid", video.getUuid());
b.putBoolean("isMyVideo", ownVideos);
b.putBoolean("sepia_search", sepiaSearch);
b.putSerializable("video", video);
if (sepiaSearch) {
b.putString("peertube_instance", video.getAccount().getHost());
}
intent.putExtras(b);
context.startActivity(intent);
});
holder.binding.peertubeVideoImage.setOnClickListener(v -> {
Intent intent = new Intent(context, PeertubeActivity.class);
Bundle b = new Bundle();
b.putString("video_id", video.getId());
b.putSerializable("video", video);
b.putString("video_uuid", video.getUuid());
b.putBoolean("isMyVideo", ownVideos);
b.putBoolean("sepia_search", sepiaSearch);
if (sepiaSearch) {
b.putString("peertube_instance", video.getAccount().getHost());
}
intent.putExtras(b);
context.startActivity(intent);
});
} else {
final VideoViewHolder holder = (VideoViewHolder) viewHolder;
final VideoData.Video video = videos.get(position);
if (video == null) {
return;
}
boolean ownVideos;
if (timelineType == TimelineVM.TimelineType.MY_VIDEOS) {
ownVideos = true;
} else {
ownVideos = Helper.isVideoOwner(context, video);
}
String instance = null;
if (sepiaSearch) {
instance = video.getAccount().getHost();
} else if (forChannel != null) {
instance = forChannel.getHost();
} else if (forAccount != null) {
instance = forAccount.getHost();
}
holder.binding.peertubeDisplayname.setText(video.getChannel().getDisplayName());
holder.binding.peertubeUsername.setText(video.getChannel().getAcct());
Helper.loadAvatar(context, video.getChannel(), holder.binding.peertubeChannelAvatar);
holder.binding.peertubeTitle.setText(video.getName());
if (video.isLive()) {
holder.binding.peertubeDuration.setText(R.string.live);
holder.binding.peertubeDuration.setBackgroundResource(R.drawable.rounded_live);
} else {
holder.binding.peertubeDuration.setText(Helper.secondsToString(video.getDuration()));
holder.binding.peertubeDuration.setBackgroundResource(R.drawable.rounded_corner);
}
holder.binding.peertubeDate.setText(String.format(" - %s", Helper.dateDiffFull(video.getCreatedAt())));
holder.binding.peertubeViews.setText(context.getString(R.string.number_view_video, Helper.withSuffix(video.getViews())));
boolean blur = sharedpreferences.getString(context.getString(R.string.set_video_sensitive_choice), Helper.BLUR).compareTo("blur") == 0 && video.isNsfw();
loadImage(holder.binding.peertubeVideoImage, instance, video.getPreviewPath(), video.getThumbnailPath(), blur);
holder.binding.previewContainer.setVisibility(View.VISIBLE);
//For Overview Videos: boolean values for displaying title is managed in the fragment
if (video.isHasTitle()) {
holder.binding.headerTitle.setVisibility(View.VISIBLE);
switch (video.getTitleType()) {
case TAG:
holder.binding.headerTitle.setText(String.format("#%s", video.getTitle()));
break;
case CHANNEL:
case CATEGORY:
holder.binding.headerTitle.setText(String.format("%s", video.getTitle()));
break;
}
} else {
holder.binding.headerTitle.setVisibility(View.GONE);
}
if (!ownVideos) {
holder.binding.peertubeChannelInfo.setOnClickListener(v -> {
Intent intent = new Intent(context, ShowChannelActivity.class);
Bundle b = new Bundle();
b.putSerializable("channel", video.getChannel());
b.putBoolean("sepia_search", sepiaSearch || forChannel != null);
if (sepiaSearch || forChannel != null) {
b.putString("peertube_instance", video.getAccount().getHost());
}
intent.putExtras(b);
context.startActivity(intent);
});
}
holder.binding.moreActions.setOnClickListener(view -> {
PopupMenu popup = new PopupMenu(context, holder.binding.moreActions);
popup.getMenuInflater()
.inflate(R.menu.video_drawer_menu_peertube, popup.getMenu());
if (timelineType == MY_VIDEOS) {
popup.getMenu().findItem(R.id.action_report).setVisible(false);
popup.getMenu().findItem(R.id.action_follow).setVisible(false);
} else {
popup.getMenu().findItem(R.id.action_edit).setVisible(false);
if (relationShipListener == null || relationShipListener.getRelationShip() == null || relationShipListener.getRelationShip().size() == 0) {
popup.getMenu().findItem(R.id.action_follow).setVisible(false);
} else {
popup.getMenu().findItem(R.id.action_follow).setVisible(true);
if (relationShipListener.getRelationShip().containsKey(video.getChannel().getAcct()) && relationShipListener.getRelationShip().get(video.getChannel().getAcct())) {
popup.getMenu().findItem(R.id.action_follow).setTitle(context.getString(R.string.action_unfollow));
} else {
popup.getMenu().findItem(R.id.action_follow).setTitle(context.getString(R.string.action_follow));
}
}
}
popup.getMenu().findItem(R.id.action_playlist).setVisible(playlistListener != null && playlistListener.getPlaylist() != null && playlistListener.getPlaylist().size() != 0);
popup.setOnMenuItemClickListener(item -> {
int itemId = item.getItemId();
if (itemId == R.id.action_follow) {
if (relationShipListener.getRelationShip().containsKey(video.getChannel().getAcct()) && relationShipListener.getRelationShip().get(video.getChannel().getAcct())) {
relationShipListener.getRelationShip().put(video.getChannel().getAcct(), false);
popup.getMenu().findItem(R.id.action_follow).setTitle(context.getString(R.string.action_follow));
boolean confirm_unfollow = sharedpreferences.getBoolean(Helper.SET_UNFOLLOW_VALIDATION, true);
if (confirm_unfollow) {
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(context);
unfollowConfirm.setTitle(context.getString(R.string.unfollow_confirm));
unfollowConfirm.setMessage(video.getChannel().getAcct());
unfollowConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
unfollowConfirm.setPositiveButton(R.string.yes, (dialog, which) -> {
PostActionsVM viewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(PostActionsVM.class);
viewModel.post(UNFOLLOW, video.getChannel().getAcct(), null).observe((LifecycleOwner) context, apiResponse -> manageVIewPostActions(UNFOLLOW, apiResponse));
dialog.dismiss();
});
unfollowConfirm.show();
} else {
PostActionsVM viewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(PostActionsVM.class);
viewModel.post(UNFOLLOW, video.getChannel().getAcct(), null).observe((LifecycleOwner) context, apiResponse -> manageVIewPostActions(UNFOLLOW, apiResponse));
}
} else {
relationShipListener.getRelationShip().put(video.getChannel().getAcct(), true);
popup.getMenu().findItem(R.id.action_follow).setTitle(context.getString(R.string.action_unfollow));
PostActionsVM viewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(PostActionsVM.class);
viewModel.post(FOLLOW, video.getChannel().getAcct(), null).observe((LifecycleOwner) context, apiResponse -> manageVIewPostActions(FOLLOW, apiResponse));
}
} else if (itemId == R.id.action_playlist) {
PlaylistsVM viewModelOwnerPlaylist = new ViewModelProvider((ViewModelStoreOwner) context).get(PlaylistsVM.class);
viewModelOwnerPlaylist.manage(PlaylistsVM.action.GET_PLAYLISTS, null, null).observe((LifecycleOwner) context, apiResponse -> manageVIewPlaylists(video, apiResponse));
} else if (itemId == R.id.action_edit) {
Intent intent = new Intent(context, PeertubeEditUploadActivity.class);
Bundle b = new Bundle();
b.putString("video_id", video.getUuid());
intent.putExtras(b);
context.startActivity(intent);
} else if (itemId == R.id.action_report) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(context);
LayoutInflater inflater1 = ((Activity) context).getLayoutInflater();
View dialogView = inflater1.inflate(R.layout.popup_report_peertube, new LinearLayout(context), false);
dialogBuilder.setView(dialogView);
EditText report_content = dialogView.findViewById(R.id.report_content);
dialogBuilder.setNeutralButton(R.string.cancel, (dialog2, id) -> dialog2.dismiss());
dialogBuilder.setPositiveButton(R.string.report, (dialog2, id) -> {
if (report_content.getText().toString().trim().length() == 0) {
Toasty.info(context, context.getString(R.string.report_comment_size), Toasty.LENGTH_LONG).show();
} else {
PostActionsVM viewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(PostActionsVM.class);
Report report = new Report();
Report.VideoReport videoReport = new Report.VideoReport();
videoReport.setId(video.getId());
report.setVideo(videoReport);
report.setReason(report_content.getText().toString());
viewModel.report(report).observe((LifecycleOwner) context, apiResponse -> manageVIewPostActions(RetrofitPeertubeAPI.ActionType.REPORT_VIDEO, apiResponse));
dialog2.dismiss();
}
});
AlertDialog alertDialog2 = dialogBuilder.create();
alertDialog2.show();
}
return true;
});
popup.show();
});
holder.binding.peertubeVideoInfo.setOnClickListener(v -> {
Intent intent = new Intent(context, PeertubeActivity.class);
Bundle b = new Bundle();
b.putString("video_id", video.getId());
b.putString("video_uuid", video.getUuid());
b.putBoolean("isMyVideo", ownVideos);
b.putBoolean("sepia_search", sepiaSearch);
b.putSerializable("video", video);
if (sepiaSearch) {
b.putString("peertube_instance", video.getAccount().getHost());
}
intent.putExtras(b);
context.startActivity(intent);
});
holder.binding.peertubeVideoImage.setOnClickListener(v -> {
Intent intent = new Intent(context, PeertubeActivity.class);
Bundle b = new Bundle();
b.putString("video_id", video.getId());
b.putSerializable("video", video);
b.putString("video_uuid", video.getUuid());
b.putBoolean("isMyVideo", ownVideos);
b.putBoolean("sepia_search", sepiaSearch);
if (sepiaSearch) {
b.putString("peertube_instance", video.getAccount().getHost());
}
intent.putExtras(b);
@ -200,121 +507,12 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
}
holder.binding.moreActions.setOnClickListener(view -> {
PopupMenu popup = new PopupMenu(context, holder.binding.moreActions);
popup.getMenuInflater()
.inflate(R.menu.video_drawer_menu_peertube, popup.getMenu());
if (timelineType == MY_VIDEOS) {
popup.getMenu().findItem(R.id.action_report).setVisible(false);
popup.getMenu().findItem(R.id.action_follow).setVisible(false);
} else {
popup.getMenu().findItem(R.id.action_edit).setVisible(false);
if (relationShipListener == null || relationShipListener.getRelationShip() == null || relationShipListener.getRelationShip().size() == 0) {
popup.getMenu().findItem(R.id.action_follow).setVisible(false);
} else {
popup.getMenu().findItem(R.id.action_follow).setVisible(true);
if (relationShipListener.getRelationShip().containsKey(video.getChannel().getAcct()) && relationShipListener.getRelationShip().get(video.getChannel().getAcct())) {
popup.getMenu().findItem(R.id.action_follow).setTitle(context.getString(R.string.action_unfollow));
} else {
popup.getMenu().findItem(R.id.action_follow).setTitle(context.getString(R.string.action_follow));
}
}
}
popup.getMenu().findItem(R.id.action_playlist).setVisible(playlistListener != null && playlistListener.getPlaylist() != null && playlistListener.getPlaylist().size() != 0);
popup.setOnMenuItemClickListener(item -> {
int itemId = item.getItemId();
if (itemId == R.id.action_follow) {
if (relationShipListener.getRelationShip().containsKey(video.getChannel().getAcct()) && relationShipListener.getRelationShip().get(video.getChannel().getAcct())) {
relationShipListener.getRelationShip().put(video.getChannel().getAcct(), false);
popup.getMenu().findItem(R.id.action_follow).setTitle(context.getString(R.string.action_follow));
boolean confirm_unfollow = sharedpreferences.getBoolean(Helper.SET_UNFOLLOW_VALIDATION, true);
if (confirm_unfollow) {
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(context);
unfollowConfirm.setTitle(context.getString(R.string.unfollow_confirm));
unfollowConfirm.setMessage(video.getChannel().getAcct());
unfollowConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
unfollowConfirm.setPositiveButton(R.string.yes, (dialog, which) -> {
PostActionsVM viewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(PostActionsVM.class);
viewModel.post(UNFOLLOW, video.getChannel().getAcct(), null).observe((LifecycleOwner) context, apiResponse -> manageVIewPostActions(UNFOLLOW, apiResponse));
dialog.dismiss();
});
unfollowConfirm.show();
} else {
PostActionsVM viewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(PostActionsVM.class);
viewModel.post(UNFOLLOW, video.getChannel().getAcct(), null).observe((LifecycleOwner) context, apiResponse -> manageVIewPostActions(UNFOLLOW, apiResponse));
}
} else {
relationShipListener.getRelationShip().put(video.getChannel().getAcct(), true);
popup.getMenu().findItem(R.id.action_follow).setTitle(context.getString(R.string.action_unfollow));
PostActionsVM viewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(PostActionsVM.class);
viewModel.post(FOLLOW, video.getChannel().getAcct(), null).observe((LifecycleOwner) context, apiResponse -> manageVIewPostActions(FOLLOW, apiResponse));
}
} else if (itemId == R.id.action_playlist) {
PlaylistsVM viewModelOwnerPlaylist = new ViewModelProvider((ViewModelStoreOwner) context).get(PlaylistsVM.class);
viewModelOwnerPlaylist.manage(PlaylistsVM.action.GET_PLAYLISTS, null, null).observe((LifecycleOwner) context, apiResponse -> manageVIewPlaylists(video, apiResponse));
} else if (itemId == R.id.action_edit) {
Intent intent = new Intent(context, PeertubeEditUploadActivity.class);
Bundle b = new Bundle();
b.putString("video_id", video.getUuid());
intent.putExtras(b);
context.startActivity(intent);
} else if (itemId == R.id.action_report) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(context);
LayoutInflater inflater1 = ((Activity) context).getLayoutInflater();
View dialogView = inflater1.inflate(R.layout.popup_report_peertube, new LinearLayout(context), false);
dialogBuilder.setView(dialogView);
EditText report_content = dialogView.findViewById(R.id.report_content);
dialogBuilder.setNeutralButton(R.string.cancel, (dialog2, id) -> dialog2.dismiss());
dialogBuilder.setPositiveButton(R.string.report, (dialog2, id) -> {
if (report_content.getText().toString().trim().length() == 0) {
Toasty.info(context, context.getString(R.string.report_comment_size), Toasty.LENGTH_LONG).show();
} else {
PostActionsVM viewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(PostActionsVM.class);
Report report = new Report();
Report.VideoReport videoReport = new Report.VideoReport();
videoReport.setId(video.getId());
report.setVideo(videoReport);
report.setReason(report_content.getText().toString());
viewModel.report(report).observe((LifecycleOwner) context, apiResponse -> manageVIewPostActions(RetrofitPeertubeAPI.ActionType.REPORT_VIDEO, apiResponse));
dialog2.dismiss();
}
});
AlertDialog alertDialog2 = dialogBuilder.create();
alertDialog2.show();
}
return true;
});
popup.show();
});
holder.binding.peertubeVideoInfo.setOnClickListener(v -> {
Intent intent = new Intent(context, PeertubeActivity.class);
Bundle b = new Bundle();
b.putString("video_id", video.getId());
b.putString("video_uuid", video.getUuid());
b.putBoolean("isMyVideo", ownVideos);
b.putBoolean("sepia_search", sepiaSearch);
b.putSerializable("video", video);
if (sepiaSearch) {
b.putString("peertube_instance", video.getAccount().getHost());
}
intent.putExtras(b);
context.startActivity(intent);
});
holder.binding.peertubeVideoImage.setOnClickListener(v -> {
Intent intent = new Intent(context, PeertubeActivity.class);
Bundle b = new Bundle();
b.putString("video_id", video.getId());
b.putSerializable("video", video);
b.putString("video_uuid", video.getUuid());
b.putBoolean("isMyVideo", ownVideos);
b.putBoolean("sepia_search", sepiaSearch);
if (sepiaSearch) {
b.putString("peertube_instance", video.getAccount().getHost());
}
intent.putExtras(b);
context.startActivity(intent);
});
}
enum typeOfTimeline {
CLASSIC,
LIST
}
@ -477,14 +675,22 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
Map<String, List<PlaylistExist>> getPlaylist();
}
static class ViewHolder extends RecyclerView.ViewHolder {
static class VideoViewHolder extends RecyclerView.ViewHolder {
DrawerPeertubeBinding binding;
ViewHolder(DrawerPeertubeBinding itemView) {
VideoViewHolder(DrawerPeertubeBinding itemView) {
super(itemView.getRoot());
binding = itemView;
}
}
static class VideoListViewHolder extends RecyclerView.ViewHolder {
DrawerPeertubeListBinding binding;
VideoListViewHolder(DrawerPeertubeListBinding itemView) {
super(itemView.getRoot());
binding = itemView;
}
}
}

View File

@ -216,6 +216,16 @@ public class Helper {
return String.format(Locale.getDefault(), "%s:%s", strMin, strSec);
}
public static String dateDiffFull(Date dateToot) {
SimpleDateFormat df = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, Locale.getDefault());
try {
return df.format(dateToot);
} catch (Exception e) {
return "";
}
}
/***
* Returns a String depending of the date
* @param context Context

View File

@ -31,10 +31,8 @@
android:padding="6dp"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.Material3.TitleLarge"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
tools:text="Science"
tools:visibility="visible" />
tools:text="Science" />
<com.google.android.material.card.MaterialCardView
style="@style/Widget.Material3.CardView.Elevated"
@ -135,17 +133,6 @@
android:padding="6dp"
android:paddingHorizontal="6dp">
<ImageView
android:id="@+id/peertube_video_image_small"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_marginEnd="6dp"
android:contentDescription="@string/image_preview"
android:scaleType="centerCrop"
android:visibility="gone"
tools:src="@tools:sample/backgrounds/scenic"
tools:visibility="visible" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
@ -156,7 +143,7 @@
android:id="@+id/peertube_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
android:textColor="?colorPrimary"
android:textStyle="bold"
tools:maxLines="1"
@ -171,7 +158,7 @@
android:id="@+id/peertube_views"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.Material3.ActionBar.Subtitle"
android:textAppearance="@style/TextAppearance.Material3.BodyLarge"
tools:text="100 views" />
<TextView
@ -179,7 +166,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:textAppearance="@style/TextAppearance.Material3.ActionBar.Subtitle"
android:textAppearance="@style/TextAppearance.Material3.BodyLarge"
tools:text="- 1 h" />
</androidx.appcompat.widget.LinearLayoutCompat>
@ -190,9 +177,9 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/more_actions"
style="@style/Widget.Material3.Button.IconButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
android:layout_width="48dp"
android:layout_height="48dp"
app:icon="@drawable/ic_baseline_more_vert_24"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/peertube_video_image" />

View File

@ -0,0 +1,188 @@
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2023 Thomas Schneider
This file is a part of Fedilab
This program is free software; you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation; either version 3 of the
License, or (at your option) any later version.
Fedilab 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 General
Public License for more details.
You should have received a copy of the GNU General Public License along with Fedilab; if not,
see <http://www.gnu.org/licenses>.
-->
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/header_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:background="?colorSecondaryContainer"
android:padding="6dp"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.Material3.TitleLarge"
android:textColor="?colorOnSecondaryContainer"
app:layout_constraintTop_toTopOf="parent"
tools:text="Science" />
<com.google.android.material.card.MaterialCardView
style="@style/Widget.Material3.CardView.Elevated"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="6dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/peertube_channel_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="6dp">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/peertube_channel_avatar"
android:layout_width="36dp"
android:layout_height="36dp"
android:contentDescription="@string/profile_picture"
android:scaleType="fitCenter"
tools:src="@tools:sample/avatars" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/peertube_displayname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
tools:text="@tools:sample/full_names" />
<TextView
android:id="@+id/peertube_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:ellipsize="end"
android:singleLine="true"
tools:text="username@instance.test" />
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.button.MaterialButton
android:id="@+id/more_actions"
style="@style/Widget.Material3.Button.OutlinedButton.Icon"
android:layout_width="48dp"
android:layout_height="48dp"
app:icon="@drawable/ic_baseline_more_vert_24"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/peertube_video_image" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/preview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/peertube_video_info"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="6dp"
android:paddingHorizontal="6dp">
<ImageView
android:id="@+id/peertube_video_image"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_marginEnd="6dp"
android:contentDescription="@string/image_preview"
android:scaleType="centerCrop"
tools:src="@tools:sample/backgrounds/scenic" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/peertube_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
android:textColor="?colorPrimary"
android:textStyle="bold"
tools:maxLines="1"
tools:text="@tools:sample/lorem/random" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="10dp">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/peertube_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="6dp"
android:background="@drawable/rounded_corner"
android:paddingHorizontal="6dp"
android:textAppearance="@style/TextAppearance.Material3.LabelLarge"
android:textColor="@android:color/white"
tools:text="1:00" />
<TextView
android:id="@+id/peertube_views"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.Material3.BodyLarge"
tools:text="100 views" />
<TextView
android:id="@+id/peertube_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:textAppearance="@style/TextAppearance.Material3.BodyLarge"
tools:text="@tools:sample/date/day_of_week" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</com.google.android.material.card.MaterialCardView>
</androidx.appcompat.widget.LinearLayoutCompat>