Some fixes

This commit is contained in:
Thomas 2020-10-08 16:21:14 +02:00
parent 0604ac9ba8
commit e96b9f7f02
15 changed files with 364 additions and 430 deletions

View File

@ -32,13 +32,8 @@ import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.navigation.NavController; import androidx.fragment.app.Fragment;
import androidx.navigation.NavGraph; import androidx.fragment.app.FragmentManager;
import androidx.navigation.NavInflater;
import androidx.navigation.Navigation;
import androidx.navigation.fragment.NavHostFragment;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.bottomnavigation.BottomNavigationView;
@ -56,6 +51,8 @@ import app.fedilab.fedilabtube.client.entities.PeertubeInformation;
import app.fedilab.fedilabtube.client.entities.Token; import app.fedilab.fedilabtube.client.entities.Token;
import app.fedilab.fedilabtube.client.entities.UserMe; import app.fedilab.fedilabtube.client.entities.UserMe;
import app.fedilab.fedilabtube.client.entities.WellKnownNodeinfo; import app.fedilab.fedilabtube.client.entities.WellKnownNodeinfo;
import app.fedilab.fedilabtube.fragment.DisplayOverviewFragment;
import app.fedilab.fedilabtube.fragment.DisplayVideosFragment;
import app.fedilab.fedilabtube.helper.Helper; import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.services.RetrieveInfoService; import app.fedilab.fedilabtube.services.RetrieveInfoService;
import app.fedilab.fedilabtube.sqlite.AccountDAO; import app.fedilab.fedilabtube.sqlite.AccountDAO;
@ -70,6 +67,42 @@ public class MainActivity extends AppCompatActivity {
public static PeertubeInformation peertubeInformation; public static PeertubeInformation peertubeInformation;
public static int PICK_INSTANCE = 5641; public static int PICK_INSTANCE = 5641;
final FragmentManager fm = getSupportFragmentManager();
Fragment active;
private DisplayVideosFragment recentFragment, locaFragment, trendingFragment, subscriptionFragment, mostLikedFragment;
private DisplayOverviewFragment overviewFragment;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= item -> {
DisplayVideosFragment displayVideosFragment = null;
switch (item.getItemId()) {
case R.id.navigation_subscription:
displayVideosFragment = subscriptionFragment;
break;
case R.id.navigation_trending:
displayVideosFragment = trendingFragment;
break;
case R.id.navigation_most_liked:
displayVideosFragment = mostLikedFragment;
break;
case R.id.navigation_recently_added:
displayVideosFragment = recentFragment;
break;
case R.id.navigation_local:
displayVideosFragment = locaFragment;
break;
case R.id.navigation_discover:
fm.beginTransaction().hide(active).show(overviewFragment).commit();
active = overviewFragment;
return true;
}
if (displayVideosFragment != null) {
fm.beginTransaction().hide(active).show(displayVideosFragment).commit();
active = displayVideosFragment;
return true;
} else {
return false;
}
};
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -80,6 +113,47 @@ public class MainActivity extends AppCompatActivity {
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
BottomNavigationView navView = findViewById(R.id.nav_view); BottomNavigationView navView = findViewById(R.id.nav_view);
navView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
recentFragment = new DisplayVideosFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(Helper.TIMELINE_TYPE, TimelineVM.TimelineType.RECENT);
recentFragment.setArguments(bundle);
locaFragment = new DisplayVideosFragment();
bundle = new Bundle();
bundle.putSerializable(Helper.TIMELINE_TYPE, TimelineVM.TimelineType.LOCAL);
locaFragment.setArguments(bundle);
trendingFragment = new DisplayVideosFragment();
bundle = new Bundle();
bundle.putSerializable(Helper.TIMELINE_TYPE, TimelineVM.TimelineType.TRENDING);
trendingFragment.setArguments(bundle);
subscriptionFragment = new DisplayVideosFragment();
bundle = new Bundle();
bundle.putSerializable(Helper.TIMELINE_TYPE, TimelineVM.TimelineType.SUBSCRIBTIONS);
subscriptionFragment.setArguments(bundle);
mostLikedFragment = new DisplayVideosFragment();
bundle = new Bundle();
bundle.putSerializable(Helper.TIMELINE_TYPE, TimelineVM.TimelineType.MOST_LIKED);
mostLikedFragment.setArguments(bundle);
overviewFragment = new DisplayOverviewFragment();
active = overviewFragment;
fm.beginTransaction().add(R.id.nav_host_fragment, locaFragment, "5").hide(locaFragment).commit();
if (!Helper.isLoggedIn(MainActivity.this)) {
fm.beginTransaction().add(R.id.nav_host_fragment, recentFragment, "4").hide(recentFragment).commit();
fm.beginTransaction().add(R.id.nav_host_fragment, mostLikedFragment, "3").hide(trendingFragment).commit();
fm.beginTransaction().add(R.id.nav_host_fragment, trendingFragment, "2").hide(subscriptionFragment).commit();
fm.beginTransaction().add(R.id.nav_host_fragment, overviewFragment, "1").commit();
}
if (Helper.isLoggedIn(MainActivity.this)) { if (Helper.isLoggedIn(MainActivity.this)) {
navView.inflateMenu(R.menu.bottom_nav_menu_connected); navView.inflateMenu(R.menu.bottom_nav_menu_connected);
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
@ -102,6 +176,14 @@ public class MainActivity extends AppCompatActivity {
runOnUiThread(() -> Helper.logoutCurrentUser(MainActivity.this, account)); runOnUiThread(() -> Helper.logoutCurrentUser(MainActivity.this, account));
return; return;
} }
runOnUiThread(() -> {
//To avoid a token issue with subscriptions, adding fragment is done when the token is refreshed.
fm.beginTransaction().add(R.id.nav_host_fragment, recentFragment, "4").hide(recentFragment).commit();
fm.beginTransaction().add(R.id.nav_host_fragment, trendingFragment, "3").hide(trendingFragment).commit();
fm.beginTransaction().add(R.id.nav_host_fragment, subscriptionFragment, "2").hide(subscriptionFragment).commit();
fm.beginTransaction().add(R.id.nav_host_fragment, overviewFragment, "1").commit();
});
UserMe userMe = new RetrofitPeertubeAPI(MainActivity.this, instance, token.getAccess_token()).verifyCredentials(); UserMe userMe = new RetrofitPeertubeAPI(MainActivity.this, instance, token.getAccess_token()).verifyCredentials();
if (userMe != null && userMe.getAccount() != null) { if (userMe != null && userMe.getAccount() != null) {
new AccountDAO(MainActivity.this, db).updateAccount(userMe.getAccount()); new AccountDAO(MainActivity.this, db).updateAccount(userMe.getAccount());
@ -128,41 +210,9 @@ public class MainActivity extends AppCompatActivity {
} else { } else {
navView.inflateMenu(R.menu.bottom_nav_menu); navView.inflateMenu(R.menu.bottom_nav_menu);
} }
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
AppBarConfiguration appBarConfiguration;
//Bottom menu won't be the same if the user is authenticated
//When the user is authenticated, the subscription entry will be added and the local one removed.
if (Helper.isLoggedIn(MainActivity.this)) {
appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_discover, R.id.navigation_subscription, R.id.navigation_trending, R.id.navigation_local, R.id.navigation_recently_added)
.build();
} else {
appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_discover, R.id.navigation_trending, R.id.navigation_most_liked, R.id.navigation_recently_added, R.id.navigation_home)
.build();
}
startInForeground(); startInForeground();
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
if (navHostFragment != null) {
NavInflater inflater = navHostFragment.getNavController().getNavInflater();
NavGraph graph;
//the menu is inflated for authenticated or not authenticated account
if (Helper.isLoggedIn(MainActivity.this)) {
graph = inflater.inflate(R.navigation.mobile_navigation_connected);
} else {
graph = inflater.inflate(R.navigation.mobile_navigation);
}
navHostFragment.getNavController().setGraph(graph);
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navView, navController);
}
}
}
private void startInForeground() { private void startInForeground() {
Intent notificationIntent = new Intent(this, RetrieveInfoService.class); Intent notificationIntent = new Intent(this, RetrieveInfoService.class);

View File

@ -16,46 +16,21 @@ package app.fedilab.fedilabtube;
import android.os.Bundle; import android.os.Bundle;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider; import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import java.util.ArrayList; import app.fedilab.fedilabtube.client.data.PlaylistData;
import java.util.List; import app.fedilab.fedilabtube.fragment.DisplayVideosFragment;
import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.client.APIResponse; import app.fedilab.fedilabtube.viewmodel.TimelineVM;
import app.fedilab.fedilabtube.client.data.PlaylistData.Playlist;
import app.fedilab.fedilabtube.client.data.VideoData.Video;
import app.fedilab.fedilabtube.client.data.VideoPlaylistData;
import app.fedilab.fedilabtube.drawer.PeertubeAdapter;
import app.fedilab.fedilabtube.viewmodel.PlaylistsVM;
import es.dmoral.toasty.Toasty; import es.dmoral.toasty.Toasty;
import static app.fedilab.fedilabtube.viewmodel.PlaylistsVM.action.GET_LIST_VIDEOS;
public class PlaylistsActivity extends AppCompatActivity { public class PlaylistsActivity extends AppCompatActivity {
LinearLayoutManager mLayoutManager;
private RelativeLayout mainLoader, nextElementLoader, textviewNoAction;
private SwipeRefreshLayout swipeRefreshLayout;
private boolean swiped;
private List<Video> peertubes;
private String max_id;
private Playlist playlist;
private boolean firstLoad;
private boolean flag_loading;
private PeertubeAdapter peertubeAdapter;
private PlaylistsVM viewModel;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -65,73 +40,30 @@ public class PlaylistsActivity extends AppCompatActivity {
setContentView(R.layout.activity_playlists); setContentView(R.layout.activity_playlists);
peertubes = new ArrayList<>();
RecyclerView lv_playlist = findViewById(R.id.lv_playlist);
mainLoader = findViewById(R.id.loader);
nextElementLoader = findViewById(R.id.loading_next_status);
textviewNoAction = findViewById(R.id.no_action);
mainLoader.setVisibility(View.VISIBLE);
swipeRefreshLayout = findViewById(R.id.swipeContainer);
max_id = null; PlaylistData.Playlist playlist;
flag_loading = true;
firstLoad = true;
swiped = false;
mainLoader.setVisibility(View.VISIBLE);
nextElementLoader.setVisibility(View.GONE);
Bundle b = getIntent().getExtras(); Bundle b = getIntent().getExtras();
if (b != null) { if (b != null) {
playlist = b.getParcelable("playlist"); playlist = b.getParcelable("playlist");
if (playlist == null) {
return;
}
} else { } else {
Toasty.error(PlaylistsActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); Toasty.error(PlaylistsActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
return; return;
} }
peertubeAdapter = new PeertubeAdapter(this.peertubes, playlist);
lv_playlist.setAdapter(peertubeAdapter);
mLayoutManager = new LinearLayoutManager(PlaylistsActivity.this);
lv_playlist.setLayoutManager(mLayoutManager);
if (getSupportActionBar() != null)
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setTitle(playlist.getDisplayName()); setTitle(playlist.getDisplayName());
if (savedInstanceState == null) {
DisplayVideosFragment displayVideosFragment = new DisplayVideosFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(Helper.TIMELINE_TYPE, TimelineVM.TimelineType.VIDEOS_IN_PLAYLIST);
bundle.putSerializable("playlistId", playlist.getId());
displayVideosFragment.setArguments(bundle);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.nav_host_fragment, displayVideosFragment).commit();
}
viewModel = new ViewModelProvider(PlaylistsActivity.this).get(PlaylistsVM.class);
lv_playlist.addOnScrollListener(new RecyclerView.OnScrollListener() {
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
if (dy > 0) {
int visibleItemCount = mLayoutManager.getChildCount();
int totalItemCount = mLayoutManager.getItemCount();
if (firstVisibleItem + visibleItemCount == totalItemCount) {
if (!flag_loading) {
flag_loading = true;
viewModel.manage(GET_LIST_VIDEOS, playlist, null).observe(PlaylistsActivity.this, apiResponse -> manageVIewPlaylists(PlaylistsVM.action.GET_LIST_VIDEOS, apiResponse));
nextElementLoader.setVisibility(View.VISIBLE);
}
} else {
nextElementLoader.setVisibility(View.GONE);
}
}
}
});
swipeRefreshLayout.setOnRefreshListener(() -> {
max_id = null;
firstLoad = true;
flag_loading = true;
swiped = true;
viewModel.manage(GET_LIST_VIDEOS, playlist, null).observe(PlaylistsActivity.this, apiResponse -> manageVIewPlaylists(PlaylistsVM.action.GET_LIST_VIDEOS, apiResponse));
});
viewModel.manage(GET_LIST_VIDEOS, playlist, null).observe(PlaylistsActivity.this, apiResponse -> manageVIewPlaylists(PlaylistsVM.action.GET_LIST_VIDEOS, apiResponse));
} }
@ -144,46 +76,4 @@ public class PlaylistsActivity extends AppCompatActivity {
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
public void manageVIewPlaylists(PlaylistsVM.action actionType, APIResponse apiResponse) {
mainLoader.setVisibility(View.GONE);
nextElementLoader.setVisibility(View.GONE);
if (apiResponse.getError() != null) {
Toasty.error(PlaylistsActivity.this, apiResponse.getError().getError(), Toast.LENGTH_LONG).show();
swipeRefreshLayout.setRefreshing(false);
swiped = false;
flag_loading = false;
return;
}
if (actionType == GET_LIST_VIDEOS) {
int previousPosition = this.peertubes.size();
List<VideoPlaylistData.VideoPlaylist> videoPlaylists = apiResponse.getVideoPlaylist();
List<Video> videos = new ArrayList<>();
for (VideoPlaylistData.VideoPlaylist v : videoPlaylists) {
v.getVideo().setIdInPlaylist(v.getId());
videos.add(v.getVideo());
}
max_id = apiResponse.getMax_id();
flag_loading = (max_id == null);
if (!swiped && firstLoad && videos.size() == 0)
textviewNoAction.setVisibility(View.VISIBLE);
else
textviewNoAction.setVisibility(View.GONE);
if (swiped) {
if (previousPosition > 0) {
this.peertubes.subList(0, previousPosition).clear();
peertubeAdapter.notifyItemRangeRemoved(0, previousPosition);
}
swiped = false;
}
if (videos.size() > 0) {
this.peertubes.addAll(videos);
peertubeAdapter.notifyItemRangeInserted(previousPosition, videos.size());
}
swipeRefreshLayout.setRefreshing(false);
firstLoad = false;
}
}
} }

View File

@ -416,7 +416,7 @@ public class ShowChannelActivity extends AppCompatActivity {
if (position == 0) { if (position == 0) {
DisplayVideosFragment displayVideosFragment = new DisplayVideosFragment(); DisplayVideosFragment displayVideosFragment = new DisplayVideosFragment();
bundle = new Bundle(); bundle = new Bundle();
bundle.putSerializable("timelineType", TimelineVM.TimelineType.USER_VIDEOS); bundle.putSerializable(Helper.TIMELINE_TYPE, TimelineVM.TimelineType.USER_VIDEOS);
bundle.putString("channelId", channel.getAcct()); bundle.putString("channelId", channel.getAcct());
displayVideosFragment.setArguments(bundle); displayVideosFragment.setArguments(bundle);
return displayVideosFragment; return displayVideosFragment;

View File

@ -30,6 +30,7 @@ import app.fedilab.fedilabtube.client.data.AccountData.Account;
import app.fedilab.fedilabtube.client.entities.File; import app.fedilab.fedilabtube.client.entities.File;
import app.fedilab.fedilabtube.client.entities.Item; import app.fedilab.fedilabtube.client.entities.Item;
import app.fedilab.fedilabtube.client.entities.ItemStr; import app.fedilab.fedilabtube.client.entities.ItemStr;
import app.fedilab.fedilabtube.client.entities.PlaylistExist;
import app.fedilab.fedilabtube.client.entities.StreamingPlaylists; import app.fedilab.fedilabtube.client.entities.StreamingPlaylists;
import app.fedilab.fedilabtube.helper.Helper; import app.fedilab.fedilabtube.helper.Helper;
@ -129,7 +130,7 @@ public class VideoData {
private boolean hasTitle = false; private boolean hasTitle = false;
private String title; private String title;
private titleType titleType; private titleType titleType;
private String idInPlaylist; private List<PlaylistExist> playlistExists;
public Video() { public Video() {
} }
@ -556,12 +557,12 @@ public class VideoData {
this.titleType = titleType; this.titleType = titleType;
} }
public String getIdInPlaylist() { public List<PlaylistExist> getPlaylistExists() {
return idInPlaylist; return playlistExists;
} }
public void setIdInPlaylist(String idInPlaylist) { public void setPlaylistExists(List<PlaylistExist> playlistExists) {
this.idInPlaylist = idInPlaylist; this.playlistExists = playlistExists;
} }
@Override @Override

View File

@ -28,6 +28,7 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu; import androidx.appcompat.widget.PopupMenu;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@ -54,13 +55,13 @@ import app.fedilab.fedilabtube.viewmodel.PostActionsVM;
import app.fedilab.fedilabtube.viewmodel.TimelineVM; import app.fedilab.fedilabtube.viewmodel.TimelineVM;
import es.dmoral.toasty.Toasty; import es.dmoral.toasty.Toasty;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.FOLLOW;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.UNFOLLOW;
import static app.fedilab.fedilabtube.viewmodel.TimelineVM.TimelineType.MY_VIDEOS; import static app.fedilab.fedilabtube.viewmodel.TimelineVM.TimelineType.MY_VIDEOS;
import static app.fedilab.fedilabtube.viewmodel.TimelineVM.TimelineType.VIDEOS_IN_PLAYLIST;
public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public AllVideoRemoved allVideoRemoved;
public RelationShipListener relationShipListener; public RelationShipListener relationShipListener;
public PlaylistListener playlistListener; public PlaylistListener playlistListener;
public OwnerPlaylistsListener ownerPlaylistsListener; public OwnerPlaylistsListener ownerPlaylistsListener;
@ -73,10 +74,6 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
this.timelineType = timelineType; this.timelineType = timelineType;
} }
public PeertubeAdapter(List<VideoData.Video> videos, PlaylistData.Playlist playlist) {
this.videos = videos;
this.timelineType = VIDEOS_IN_PLAYLIST;
}
public PeertubeAdapter(List<VideoData.Video> videos) { public PeertubeAdapter(List<VideoData.Video> videos) {
this.videos = videos; this.videos = videos;
@ -155,64 +152,99 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
if (timelineType == MY_VIDEOS) { if (timelineType == MY_VIDEOS) {
popup.getMenu().findItem(R.id.action_report).setVisible(false); popup.getMenu().findItem(R.id.action_report).setVisible(false);
popup.getMenu().findItem(R.id.action_follow).setVisible(false); popup.getMenu().findItem(R.id.action_follow).setVisible(false);
if (playlistListener == null || playlistListener.getPlaylist() == null || playlistListener.getPlaylist().size() == 0) {
popup.getMenu().findItem(R.id.action_playlist).setVisible(false);
} else {
popup.getMenu().findItem(R.id.action_playlist).setVisible(true);
}
} else { } else {
popup.getMenu().findItem(R.id.action_edit).setVisible(false); popup.getMenu().findItem(R.id.action_edit).setVisible(false);
if (timelineType != VIDEOS_IN_PLAYLIST) { if (relationShipListener == null || relationShipListener.getRelationShip() == null || relationShipListener.getRelationShip().size() == 0) {
if (relationShipListener == null || relationShipListener.getRelationShip() == null || relationShipListener.getRelationShip().size() == 0) { popup.getMenu().findItem(R.id.action_follow).setVisible(false);
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 { } else {
popup.getMenu().findItem(R.id.action_follow).setVisible(true); popup.getMenu().findItem(R.id.action_follow).setTitle(context.getString(R.string.action_follow));
} }
} }
if (playlistListener == null || playlistListener.getPlaylist() == null || playlistListener.getPlaylist().size() == 0) { }
popup.getMenu().findItem(R.id.action_playlist).setVisible(false); if (playlistListener == null || playlistListener.getPlaylist() == null || playlistListener.getPlaylist().size() == 0) {
} else { popup.getMenu().findItem(R.id.action_playlist).setVisible(false);
popup.getMenu().findItem(R.id.action_playlist).setVisible(true); } else {
} popup.getMenu().findItem(R.id.action_playlist).setVisible(true);
} }
popup.setOnMenuItemClickListener(item -> { popup.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) { switch (item.getItemId()) {
case 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 AlertDialog.Builder(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));
}
break;
case R.id.action_playlist: case R.id.action_playlist:
androidx.appcompat.app.AlertDialog.Builder builder = new androidx.appcompat.app.AlertDialog.Builder(context); androidx.appcompat.app.AlertDialog.Builder builder = new androidx.appcompat.app.AlertDialog.Builder(context);
builder.setTitle(R.string.modify_playlists); builder.setTitle(R.string.modify_playlists);
List<PlaylistData.Playlist> ownerPlaylists = ownerPlaylistsListener.getOwnerPlaylists(); List<PlaylistData.Playlist> ownerPlaylists = ownerPlaylistsListener.getOwnerPlaylists();
if( ownerPlaylists == null){
return false;
}
String[] label = new String[ownerPlaylists.size()]; String[] label = new String[ownerPlaylists.size()];
boolean[] checked = new boolean[ownerPlaylists.size()]; boolean[] checked = new boolean[ownerPlaylists.size()];
int i = 0; int i = 0;
List<PlaylistExist> playlistsForVideo = playlistListener.getPlaylist().get(video.getId()); List<PlaylistExist> playlistsForVideo = playlistListener.getPlaylist().get(video.getId());
if (playlistsForVideo != null) {
for (PlaylistData.Playlist playlist : ownerPlaylists) { for (PlaylistData.Playlist playlist : ownerPlaylists) {
checked[i] = false;
if (playlistsForVideo != null) {
for (PlaylistExist playlistExist : playlistsForVideo) { for (PlaylistExist playlistExist : playlistsForVideo) {
if (playlistExist != null && playlistExist.getPlaylistId().compareTo(playlist.getId()) == 0) { if (playlistExist != null && playlistExist.getPlaylistId().compareTo(playlist.getId()) == 0) {
checked[i] = true; checked[i] = true;
break; break;
} }
} }
label[i] = playlist.getDisplayName();
i++;
} }
label[i] = playlist.getDisplayName();
i++;
} }
builder.setMultiChoiceItems(label, checked, (dialog, which, isChecked) -> new Thread(() -> { builder.setMultiChoiceItems(label, checked, (dialog, which, isChecked) -> {
PlaylistsVM playlistsViewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(PlaylistsVM.class); PlaylistsVM playlistsViewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(PlaylistsVM.class);
if (isChecked) { //Add to playlist if (isChecked) { //Add to playlist
playlistsViewModel.manage(PlaylistsVM.action.ADD_VIDEOS, ownerPlaylistsListener.getOwnerPlaylists().get(which), video.getUuid()).observe((LifecycleOwner) context, apiResponse3 -> addElement(ownerPlaylistsListener.getOwnerPlaylists().get(which).getId(), video.getId(), apiResponse3)); playlistsViewModel.manage(PlaylistsVM.action.ADD_VIDEOS, ownerPlaylistsListener.getOwnerPlaylists().get(which), video.getUuid()).observe((LifecycleOwner) context, apiResponse3 -> addElement(ownerPlaylistsListener.getOwnerPlaylists().get(which).getId(), video.getId(), apiResponse3));
} else { //Remove from playlist } else { //Remove from playlist
playlistsViewModel.manage(PlaylistsVM.action.DELETE_VIDEOS, ownerPlaylistsListener.getOwnerPlaylists().get(which), video.getIdInPlaylist()); String elementInPlaylistId = null;
for (PlaylistExist playlistExist : video.getPlaylistExists()) {
if (playlistExist.getPlaylistId().compareTo(ownerPlaylistsListener.getOwnerPlaylists().get(which).getId()) == 0) {
elementInPlaylistId = playlistExist.getPlaylistElementId();
}
}
playlistsViewModel.manage(PlaylistsVM.action.DELETE_VIDEOS, ownerPlaylistsListener.getOwnerPlaylists().get(which), elementInPlaylistId);
playlistListener.getPlaylist().remove(video.getId()); playlistListener.getPlaylist().remove(video.getId());
} }
}).start());
builder.setPositiveButton(R.string.close, (dialog, which) -> {
dialog.dismiss();
}); });
builder.setPositiveButton(R.string.close, (dialog, which) -> dialog.dismiss());
androidx.appcompat.app.AlertDialog dialog = builder.create(); androidx.appcompat.app.AlertDialog dialog = builder.create();
dialog.show(); dialog.show();
@ -277,6 +309,7 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
PlaylistExist playlistExist = new PlaylistExist(); PlaylistExist playlistExist = new PlaylistExist();
playlistExist.setPlaylistId(playlistId); playlistExist.setPlaylistId(playlistId);
playlistExist.setPlaylistElementId(apiResponse.getActionReturn());
List<PlaylistExist> playlistExistList = playlistListener.getPlaylist().get(videoId); List<PlaylistExist> playlistExistList = playlistListener.getPlaylist().get(videoId);
if (playlistExistList == null) { if (playlistExistList == null) {
playlistExistList = new ArrayList<>(); playlistExistList = new ArrayList<>();
@ -299,6 +332,11 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
public void manageVIewPostActions(RetrofitPeertubeAPI.ActionType statusAction, APIResponse apiResponse) { public void manageVIewPostActions(RetrofitPeertubeAPI.ActionType statusAction, APIResponse apiResponse) {
if (statusAction == RetrofitPeertubeAPI.ActionType.REPORT_VIDEO) { if (statusAction == RetrofitPeertubeAPI.ActionType.REPORT_VIDEO) {
Toasty.success(context, context.getString(R.string.successful_video_report), Toasty.LENGTH_LONG).show(); Toasty.success(context, context.getString(R.string.successful_video_report), Toasty.LENGTH_LONG).show();
} else if (statusAction == RetrofitPeertubeAPI.ActionType.UNFOLLOW) {
Bundle b = new Bundle();
b.putString("receive_action", apiResponse.getTargetedId());
Intent intentBC = new Intent(Helper.RECEIVE_ACTION);
intentBC.putExtras(b);
} }
} }
@ -315,10 +353,6 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
} }
public interface AllVideoRemoved {
void onAllVideoRemoved();
}
static class ViewHolder extends RecyclerView.ViewHolder { static class ViewHolder extends RecyclerView.ViewHolder {
LinearLayout main_container, bottom_container; LinearLayout main_container, bottom_container;
ImageView peertube_profile, peertube_video_image; ImageView peertube_profile, peertube_video_image;

View File

@ -36,15 +36,20 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import app.fedilab.fedilabtube.R; import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.client.APIResponse; import app.fedilab.fedilabtube.client.APIResponse;
import app.fedilab.fedilabtube.client.data.PlaylistData;
import app.fedilab.fedilabtube.client.data.VideoData; import app.fedilab.fedilabtube.client.data.VideoData;
import app.fedilab.fedilabtube.client.entities.OverviewVideo; import app.fedilab.fedilabtube.client.entities.OverviewVideo;
import app.fedilab.fedilabtube.drawer.AccountsHorizontalListAdapter; import app.fedilab.fedilabtube.client.entities.PlaylistExist;
import app.fedilab.fedilabtube.drawer.PeertubeAdapter; import app.fedilab.fedilabtube.drawer.PeertubeAdapter;
import app.fedilab.fedilabtube.helper.Helper; import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.viewmodel.PlaylistsVM;
import app.fedilab.fedilabtube.viewmodel.RelationshipVM;
import app.fedilab.fedilabtube.viewmodel.TimelineVM; import app.fedilab.fedilabtube.viewmodel.TimelineVM;
import es.dmoral.toasty.Toasty; import es.dmoral.toasty.Toasty;
@ -53,7 +58,7 @@ import static app.fedilab.fedilabtube.client.data.VideoData.Video.titleType.CHAN
import static app.fedilab.fedilabtube.client.data.VideoData.Video.titleType.TAG; import static app.fedilab.fedilabtube.client.data.VideoData.Video.titleType.TAG;
public class DisplayOverviewFragment extends Fragment implements AccountsHorizontalListAdapter.EventListener { public class DisplayOverviewFragment extends Fragment implements PeertubeAdapter.RelationShipListener, PeertubeAdapter.PlaylistListener, PeertubeAdapter.OwnerPlaylistsListener {
private LinearLayoutManager mLayoutManager; private LinearLayoutManager mLayoutManager;
@ -70,6 +75,9 @@ public class DisplayOverviewFragment extends Fragment implements AccountsHorizon
private View rootView; private View rootView;
private RecyclerView lv_status; private RecyclerView lv_status;
private TimelineVM viewModelFeeds; private TimelineVM viewModelFeeds;
private Map<String, Boolean> relationship;
private Map<String, List<PlaylistExist>> playlists;
private List<PlaylistData.Playlist> ownerPlaylists;
public DisplayOverviewFragment() { public DisplayOverviewFragment() {
} }
@ -96,6 +104,11 @@ public class DisplayOverviewFragment extends Fragment implements AccountsHorizon
nextElementLoader.setVisibility(View.GONE); nextElementLoader.setVisibility(View.GONE);
peertubeAdapater = new PeertubeAdapter(this.peertubes); peertubeAdapater = new PeertubeAdapter(this.peertubes);
peertubeAdapater.playlistListener = this;
peertubeAdapater.relationShipListener = this;
peertubeAdapater.ownerPlaylistsListener = this;
lv_status.setAdapter(peertubeAdapater); lv_status.setAdapter(peertubeAdapater);
@ -148,6 +161,12 @@ public class DisplayOverviewFragment extends Fragment implements AccountsHorizon
} }
} }
}); });
if (Helper.isLoggedIn(context)) {
PlaylistsVM viewModel = new ViewModelProvider(this).get(PlaylistsVM.class);
viewModel.manage(PlaylistsVM.action.GET_PLAYLISTS, null, null).observe(DisplayOverviewFragment.this.requireActivity(), apiResponse -> manageVIewPlaylists(PlaylistsVM.action.GET_PLAYLISTS, apiResponse));
}
return rootView; return rootView;
} }
@ -210,6 +229,8 @@ public class DisplayOverviewFragment extends Fragment implements AccountsHorizon
OverviewVideo overviewVideos = apiResponse.getOverviewVideo(); OverviewVideo overviewVideos = apiResponse.getOverviewVideo();
int totalAdded = 0; int totalAdded = 0;
int previousPosition = this.peertubes.size(); int previousPosition = this.peertubes.size();
apiResponse.setPeertubes(new ArrayList<>());
if (overviewVideos.getCategories().size() > 0 && overviewVideos.getCategories() != null) { if (overviewVideos.getCategories().size() > 0 && overviewVideos.getCategories() != null) {
String categoryTitle = overviewVideos.getCategories().get(0).getCategory().getLabel(); String categoryTitle = overviewVideos.getCategories().get(0).getCategory().getLabel();
List<VideoData.Video> videoCategories = overviewVideos.getCategories().get(0).getVideos(); List<VideoData.Video> videoCategories = overviewVideos.getCategories().get(0).getVideos();
@ -222,9 +243,11 @@ public class DisplayOverviewFragment extends Fragment implements AccountsHorizon
} }
i++; i++;
peertubes.add(video); peertubes.add(video);
apiResponse.getPeertubes().add(video);
totalAdded++; totalAdded++;
} }
} }
if (overviewVideos.getTags().size() > 0 && overviewVideos.getTags().get(0) != null) { if (overviewVideos.getTags().size() > 0 && overviewVideos.getTags().get(0) != null) {
String tagTitle = overviewVideos.getTags().get(0).getTag(); String tagTitle = overviewVideos.getTags().get(0).getTag();
List<VideoData.Video> videoTags = overviewVideos.getTags().get(0).getVideos(); List<VideoData.Video> videoTags = overviewVideos.getTags().get(0).getVideos();
@ -237,6 +260,7 @@ public class DisplayOverviewFragment extends Fragment implements AccountsHorizon
} }
i++; i++;
peertubes.add(video); peertubes.add(video);
apiResponse.getPeertubes().add(video);
totalAdded++; totalAdded++;
} }
} }
@ -252,16 +276,46 @@ public class DisplayOverviewFragment extends Fragment implements AccountsHorizon
} }
i++; i++;
peertubes.add(video); peertubes.add(video);
apiResponse.getPeertubes().add(video);
totalAdded++; totalAdded++;
} }
} }
if (Helper.isLoggedIn(context)) {
List<String> uids = new ArrayList<>();
for (VideoData.Video video : apiResponse.getPeertubes()) {
uids.add(video.getChannel().getName() + "@" + video.getChannel().getHost());
}
if (uids.size() > 0 && !DisplayOverviewFragment.this.isDetached()) {
try {
RelationshipVM viewModel = new ViewModelProvider(this).get(RelationshipVM.class);
viewModel.get(uids).observe(DisplayOverviewFragment.this.requireActivity(), this::manageVIewRelationship);
} catch (Exception ignored) {
}
}
List<String> videoIds = new ArrayList<>();
for (VideoData.Video video : apiResponse.getPeertubes()) {
videoIds.add(video.getId());
}
if (videoIds.size() > 0 && !DisplayOverviewFragment.this.isDetached()) {
try {
PlaylistsVM viewModel = new ViewModelProvider(this).get(PlaylistsVM.class);
viewModel.videoExists(videoIds).observe(DisplayOverviewFragment.this.requireActivity(), this::manageVIewPlaylist);
} catch (Exception ignored) {
}
}
}
//max_id needs to work like an offset //max_id needs to work like an offset
page++; page++;
//If no item were inserted previously the adapter is created //If no item were inserted previously the adapter is created
if (previousPosition == 0) { if (previousPosition == 0) {
peertubeAdapater = new PeertubeAdapter(this.peertubes); peertubeAdapater = new PeertubeAdapter(this.peertubes);
peertubeAdapater.playlistListener = DisplayOverviewFragment.this;
peertubeAdapater.relationShipListener = DisplayOverviewFragment.this;
peertubeAdapater.ownerPlaylistsListener = DisplayOverviewFragment.this;
lv_status.setAdapter(peertubeAdapater); lv_status.setAdapter(peertubeAdapater);
} else } else
peertubeAdapater.notifyItemRangeInserted(previousPosition, totalAdded); peertubeAdapater.notifyItemRangeInserted(previousPosition, totalAdded);
@ -314,11 +368,6 @@ public class DisplayOverviewFragment extends Fragment implements AccountsHorizon
loadTimeline(page); loadTimeline(page);
} }
@Override
public void click(String forAccount) {
pullToRefresh();
}
/** /**
* Manage timeline load * Manage timeline load
* *
@ -362,4 +411,59 @@ public class DisplayOverviewFragment extends Fragment implements AccountsHorizon
} }
} }
} }
public void manageVIewPlaylist(APIResponse apiResponse) {
if (apiResponse.getError() != null || apiResponse.getVideoExistPlaylist() == null) {
return;
}
if (playlists == null) {
playlists = new HashMap<>();
}
playlists.putAll(apiResponse.getVideoExistPlaylist());
for (VideoData.Video video : peertubes) {
video.setPlaylistExists(playlists.get(video.getId()));
}
}
public void manageVIewRelationship(APIResponse apiResponse) {
if (apiResponse.getError() != null) {
return;
}
if (relationship == null) {
relationship = new HashMap<>();
}
relationship.putAll(apiResponse.getRelationships());
}
public void manageVIewPlaylists(PlaylistsVM.action actionType, APIResponse apiResponse) {
if (apiResponse.getError() != null) {
return;
}
if (actionType == PlaylistsVM.action.GET_PLAYLISTS) {
if (apiResponse.getPlaylists() != null && apiResponse.getPlaylists().size() > 0) {
if (this.ownerPlaylists == null) {
this.ownerPlaylists = new ArrayList<>();
}
this.ownerPlaylists.addAll(apiResponse.getPlaylists());
}
}
}
@Override
public Map<String, Boolean> getRelationShip() {
return relationship;
}
@Override
public Map<String, List<PlaylistExist>> getPlaylist() {
return playlists;
}
@Override
public List<PlaylistData.Playlist> getOwnerPlaylists() {
return ownerPlaylists;
}
} }

View File

@ -50,6 +50,7 @@ import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
import app.fedilab.fedilabtube.client.data.AccountData.Account; import app.fedilab.fedilabtube.client.data.AccountData.Account;
import app.fedilab.fedilabtube.client.data.PlaylistData; import app.fedilab.fedilabtube.client.data.PlaylistData;
import app.fedilab.fedilabtube.client.data.VideoData; import app.fedilab.fedilabtube.client.data.VideoData;
import app.fedilab.fedilabtube.client.data.VideoPlaylistData;
import app.fedilab.fedilabtube.client.entities.PlaylistExist; import app.fedilab.fedilabtube.client.entities.PlaylistExist;
import app.fedilab.fedilabtube.drawer.AccountsHorizontalListAdapter; import app.fedilab.fedilabtube.drawer.AccountsHorizontalListAdapter;
import app.fedilab.fedilabtube.drawer.PeertubeAdapter; import app.fedilab.fedilabtube.drawer.PeertubeAdapter;
@ -62,7 +63,7 @@ import app.fedilab.fedilabtube.viewmodel.TimelineVM;
import es.dmoral.toasty.Toasty; import es.dmoral.toasty.Toasty;
public class DisplayVideosFragment extends Fragment implements AccountsHorizontalListAdapter.EventListener, PeertubeAdapter.AllVideoRemoved, PeertubeAdapter.RelationShipListener, PeertubeAdapter.PlaylistListener, PeertubeAdapter.OwnerPlaylistsListener { public class DisplayVideosFragment extends Fragment implements AccountsHorizontalListAdapter.EventListener, PeertubeAdapter.RelationShipListener, PeertubeAdapter.PlaylistListener, PeertubeAdapter.OwnerPlaylistsListener {
private LinearLayoutManager mLayoutManager; private LinearLayoutManager mLayoutManager;
@ -93,6 +94,7 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
private Map<String, Boolean> relationship; private Map<String, Boolean> relationship;
private Map<String, List<PlaylistExist>> playlists; private Map<String, List<PlaylistExist>> playlists;
private List<PlaylistData.Playlist> ownerPlaylists; private List<PlaylistData.Playlist> ownerPlaylists;
private String playlistId;
public DisplayVideosFragment() { public DisplayVideosFragment() {
} }
@ -110,13 +112,10 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
if (bundle != null) { if (bundle != null) {
search_peertube = bundle.getString("search_peertube", null); search_peertube = bundle.getString("search_peertube", null);
channelId = bundle.getString("channelId", null); channelId = bundle.getString("channelId", null);
type = (TimelineVM.TimelineType) bundle.get("timelineType"); type = (TimelineVM.TimelineType) bundle.get(Helper.TIMELINE_TYPE);
playlistId = bundle.getString("playlistId", null);
} }
max_id = "0"; max_id = "0";
if (getArguments() != null && type == null) {
type = DisplayVideosFragmentArgs.fromBundle(getArguments()).getType();
}
forAccount = null; forAccount = null;
lv_status = rootView.findViewById(R.id.lv_status); lv_status = rootView.findViewById(R.id.lv_status);
RecyclerView lv_accounts = rootView.findViewById(R.id.lv_accounts); RecyclerView lv_accounts = rootView.findViewById(R.id.lv_accounts);
@ -140,7 +139,6 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
nextElementLoader.setVisibility(View.GONE); nextElementLoader.setVisibility(View.GONE);
peertubeAdapater = new PeertubeAdapter(this.peertubes, type); peertubeAdapater = new PeertubeAdapter(this.peertubes, type);
peertubeAdapater.allVideoRemoved = this;
peertubeAdapater.playlistListener = this; peertubeAdapater.playlistListener = this;
peertubeAdapater.relationShipListener = this; peertubeAdapater.relationShipListener = this;
peertubeAdapater.ownerPlaylistsListener = this; peertubeAdapater.ownerPlaylistsListener = this;
@ -343,14 +341,19 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
//max_id needs to work like an offset //max_id needs to work like an offset
int tootPerPage = sharedpreferences.getInt(Helper.SET_VIDEOS_PER_PAGE, Helper.VIDEOS_PER_PAGE); int tootPerPage = sharedpreferences.getInt(Helper.SET_VIDEOS_PER_PAGE, Helper.VIDEOS_PER_PAGE);
max_id = String.valueOf(Integer.parseInt(max_id) + tootPerPage); max_id = String.valueOf(Integer.parseInt(max_id) + tootPerPage);
if (apiResponse.getPeertubes() == null) { if (apiResponse.getPeertubes() == null && apiResponse.getVideoPlaylist() == null) {
return; return;
} }
if (apiResponse.getVideoPlaylist() != null) {
apiResponse.setPeertubes(new ArrayList<>());
for (VideoPlaylistData.VideoPlaylist v : apiResponse.getVideoPlaylist()) {
apiResponse.getPeertubes().add(v.getVideo());
}
}
this.peertubes.addAll(apiResponse.getPeertubes()); this.peertubes.addAll(apiResponse.getPeertubes());
//If no item were inserted previously the adapter is created //If no item were inserted previously the adapter is created
if (previousPosition == 0) { if (previousPosition == 0) {
peertubeAdapater = new PeertubeAdapter(this.peertubes, type); peertubeAdapater = new PeertubeAdapter(this.peertubes, type);
peertubeAdapater.allVideoRemoved = DisplayVideosFragment.this;
peertubeAdapater.playlistListener = DisplayVideosFragment.this; peertubeAdapater.playlistListener = DisplayVideosFragment.this;
peertubeAdapater.relationShipListener = DisplayVideosFragment.this; peertubeAdapater.relationShipListener = DisplayVideosFragment.this;
peertubeAdapater.ownerPlaylistsListener = DisplayVideosFragment.this; peertubeAdapater.ownerPlaylistsListener = DisplayVideosFragment.this;
@ -372,31 +375,41 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
for (VideoData.Video video : apiResponse.getPeertubes()) { for (VideoData.Video video : apiResponse.getPeertubes()) {
uids.add(video.getChannel().getName() + "@" + video.getChannel().getHost()); uids.add(video.getChannel().getName() + "@" + video.getChannel().getHost());
} }
if (uids.size() > 0) { if (uids.size() > 0 && !DisplayVideosFragment.this.isDetached()) {
RelationshipVM viewModel = new ViewModelProvider(this).get(RelationshipVM.class); try {
viewModel.get(uids).observe(DisplayVideosFragment.this.requireActivity(), this::manageVIewRelationship); RelationshipVM viewModel = new ViewModelProvider(this).get(RelationshipVM.class);
viewModel.get(uids).observe(DisplayVideosFragment.this.requireActivity(), this::manageVIewRelationship);
} catch (Exception ignored) {
}
} }
List<String> videoIds = new ArrayList<>(); List<String> videoIds = new ArrayList<>();
for (VideoData.Video video : apiResponse.getPeertubes()) { for (VideoData.Video video : apiResponse.getPeertubes()) {
videoIds.add(video.getId()); videoIds.add(video.getId());
} }
if (videoIds.size() > 0) { if (videoIds.size() > 0 && !DisplayVideosFragment.this.isDetached()) {
PlaylistsVM viewModel = new ViewModelProvider(this).get(PlaylistsVM.class); try {
viewModel.videoExists(videoIds).observe(DisplayVideosFragment.this.requireActivity(), this::manageVIewPlaylist); PlaylistsVM viewModel = new ViewModelProvider(this).get(PlaylistsVM.class);
viewModel.videoExists(videoIds).observe(DisplayVideosFragment.this.requireActivity(), this::manageVIewPlaylist);
} catch (Exception ignored) {
}
} }
} }
} }
public void manageVIewPlaylist(APIResponse apiResponse) { public void manageVIewPlaylist(APIResponse apiResponse) {
if (apiResponse.getError() != null) { if (apiResponse.getError() != null || apiResponse.getVideoExistPlaylist() == null) {
return; return;
} }
if (playlists == null) { if (playlists == null) {
playlists = new HashMap<>(); playlists = new HashMap<>();
} }
playlists.putAll(apiResponse.getVideoExistPlaylist()); playlists.putAll(apiResponse.getVideoExistPlaylist());
for (VideoData.Video video : peertubes) {
video.setPlaylistExists(playlists.get(video.getId()));
}
} }
public void manageVIewRelationship(APIResponse apiResponse) { public void manageVIewRelationship(APIResponse apiResponse) {
@ -467,6 +480,8 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
if (search_peertube == null) { //Not a Peertube search if (search_peertube == null) { //Not a Peertube search
if (type == TimelineVM.TimelineType.USER_VIDEOS) { if (type == TimelineVM.TimelineType.USER_VIDEOS) {
viewModelFeeds.getVideosInChannel(channelId, max_id).observe(this.requireActivity(), this::manageVIewVideos); viewModelFeeds.getVideosInChannel(channelId, max_id).observe(this.requireActivity(), this::manageVIewVideos);
} else if (type == TimelineVM.TimelineType.VIDEOS_IN_PLAYLIST) {
viewModelFeeds.loadVideosInPlaylist(playlistId).observe(this.requireActivity(), this::manageVIewVideos);
} else { } else {
viewModelFeeds.getVideos(type, max_id).observe(this.requireActivity(), this::manageVIewVideos); viewModelFeeds.getVideos(type, max_id).observe(this.requireActivity(), this::manageVIewVideos);
} }
@ -475,10 +490,6 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
} }
} }
@Override
public void onAllVideoRemoved() {
textviewNoAction.setVisibility(View.VISIBLE);
}
@Override @Override
public Map<String, Boolean> getRelationShip() { public Map<String, Boolean> getRelationShip() {

View File

@ -72,6 +72,7 @@ public class Helper {
public static final int RELOAD_MYVIDEOS = 10; public static final int RELOAD_MYVIDEOS = 10;
public static final String SET_VIDEO_MODE = "set_video_mode"; public static final String SET_VIDEO_MODE = "set_video_mode";
public static final String SET_QUALITY_MODE = "set_quality_mode"; public static final String SET_QUALITY_MODE = "set_quality_mode";
public static final String TIMELINE_TYPE = Helper.TIMELINE_TYPE;
public static final int VIDEO_MODE_NORMAL = 0; public static final int VIDEO_MODE_NORMAL = 0;
public static final int VIDEO_MODE_STREAMING = 2; public static final int VIDEO_MODE_STREAMING = 2;
public static final int VIDEO_MODE_WEBVIEW = 1; public static final int VIDEO_MODE_WEBVIEW = 1;

View File

@ -28,6 +28,8 @@ import app.fedilab.fedilabtube.client.APIResponse;
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI; import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
import app.fedilab.fedilabtube.helper.Helper; import app.fedilab.fedilabtube.helper.Helper;
import static app.fedilab.fedilabtube.viewmodel.PlaylistsVM.action.GET_LIST_VIDEOS;
public class TimelineVM extends AndroidViewModel { public class TimelineVM extends AndroidViewModel {
private MutableLiveData<APIResponse> apiResponseMutableLiveData; private MutableLiveData<APIResponse> apiResponseMutableLiveData;
@ -55,6 +57,12 @@ public class TimelineVM extends AndroidViewModel {
return apiResponseMutableLiveData; return apiResponseMutableLiveData;
} }
public LiveData<APIResponse> loadVideosInPlaylist(String playlistId) {
apiResponseMutableLiveData = new MutableLiveData<>();
loadVideosInPlayList(playlistId);
return apiResponseMutableLiveData;
}
public LiveData<APIResponse> getMyVideo(String videoId) { public LiveData<APIResponse> getMyVideo(String videoId) {
apiResponseMutableLiveData = new MutableLiveData<>(); apiResponseMutableLiveData = new MutableLiveData<>();
getSingle(videoId, true); getSingle(videoId, true);
@ -104,6 +112,22 @@ public class TimelineVM extends AndroidViewModel {
}).start(); }).start();
} }
private void loadVideosInPlayList(String playlistId) {
Context _mContext = getApplication().getApplicationContext();
new Thread(() -> {
try {
RetrofitPeertubeAPI retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext);
APIResponse apiResponse = retrofitPeertubeAPI.playlistAction(GET_LIST_VIDEOS, playlistId, null, null);
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse);
mainHandler.post(myRunnable);
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
private void loadVideos(TimelineType timeline, String max_id) { private void loadVideos(TimelineType timeline, String max_id) {
Context _mContext = getApplication().getApplicationContext(); Context _mContext = getApplication().getApplicationContext();
new Thread(() -> { new Thread(() -> {

View File

@ -48,15 +48,13 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<fragment <FrameLayout
app:layout_behavior="@string/appbar_scrolling_view_behavior" app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:id="@+id/nav_host_fragment" android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:defaultNavHost="true"
android:layout_marginBottom="?attr/actionBarSize" android:layout_marginBottom="?attr/actionBarSize"
app:navGraph="@navigation/mobile_navigation" /> />
<com.google.android.material.bottomnavigation.BottomNavigationView <com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view" android:id="@+id/nav_view"
android:layout_gravity="bottom" android:layout_gravity="bottom"

View File

@ -18,6 +18,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"> android:fitsSystemWindows="true">
<androidx.coordinatorlayout.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
@ -25,70 +26,13 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".PlaylistsActivity"> tools:context=".PlaylistsActivity">
<RelativeLayout <fragment
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:padding="@dimen/fab_margin"> app:defaultNavHost="true"
/>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/lv_playlist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<RelativeLayout
android:id="@+id/no_action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:padding="10dp"
android:text="@string/action_playlist_empty_content"
android:textSize="25sp" />
</RelativeLayout>
<!-- Main Loader -->
<RelativeLayout
android:id="@+id/loader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:visibility="gone">
<com.github.ybq.android.spinkit.SpinKitView xmlns:app="http://schemas.android.com/apk/res-auto"
style="@style/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:SpinKit_Color="?colorAccent" />
</RelativeLayout>
<!-- Loader for next status -->
<RelativeLayout
android:id="@+id/loading_next_status"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom|center_horizontal"
android:gravity="bottom|center_horizontal"
android:visibility="gone">
<com.github.ybq.android.spinkit.SpinKitView xmlns:app="http://schemas.android.com/apk/res-auto"
style="@style/progressBottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:SpinKit_Color="?colorAccent" />
</RelativeLayout>
</RelativeLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.drawerlayout.widget.DrawerLayout> </androidx.drawerlayout.widget.DrawerLayout>

View File

@ -22,7 +22,7 @@
android:title="@string/title_recently_added" /> android:title="@string/title_recently_added" />
<item <item
android:id="@+id/navigation_home" android:id="@+id/navigation_local"
android:icon="@drawable/ic_home_black_24dp" android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_home" /> android:title="@string/title_home" />

View File

@ -16,14 +16,14 @@
android:icon="@drawable/ic_baseline_trending_up_24" android:icon="@drawable/ic_baseline_trending_up_24"
android:title="@string/title_trending" /> android:title="@string/title_trending" />
<item
android:id="@+id/navigation_local"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_local" />
<item <item
android:id="@+id/navigation_recently_added" android:id="@+id/navigation_recently_added"
android:icon="@drawable/ic_baseline_add_circle_outline_24" android:icon="@drawable/ic_baseline_add_circle_outline_24"
android:title="@string/title_recently_added" /> android:title="@string/title_recently_added" />
<item
android:id="@+id/navigation_local"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_local" />
</menu> </menu>

View File

@ -1,61 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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"
app:startDestination="@id/navigation_discover">
<fragment
android:id="@+id/navigation_discover"
android:name="app.fedilab.fedilabtube.fragment.DisplayOverviewFragment"
android:label="@string/title_discover"
tools:layout="@layout/fragment_video">
</fragment>
<fragment
android:id="@+id/navigation_trending"
android:name="app.fedilab.fedilabtube.fragment.DisplayVideosFragment"
android:label="@string/title_trending"
tools:layout="@layout/fragment_video">
<argument
android:name="type"
android:defaultValue="TRENDING"
app:argType="app.fedilab.fedilabtube.viewmodel.TimelineVM$TimelineType" />
</fragment>
<fragment
android:id="@+id/navigation_most_liked"
android:name="app.fedilab.fedilabtube.fragment.DisplayVideosFragment"
android:label="@string/title_most_liked"
tools:layout="@layout/fragment_video">
<argument
android:name="type"
android:defaultValue="MOST_LIKED"
app:argType="app.fedilab.fedilabtube.viewmodel.TimelineVM$TimelineType" />
</fragment>
<fragment
android:id="@+id/navigation_recently_added"
android:name="app.fedilab.fedilabtube.fragment.DisplayVideosFragment"
android:label="@string/title_recently_added"
tools:layout="@layout/fragment_video">
<argument
android:name="type"
android:defaultValue="RECENT"
app:argType="app.fedilab.fedilabtube.viewmodel.TimelineVM$TimelineType" />
</fragment>
<fragment
android:id="@+id/navigation_home"
android:name="app.fedilab.fedilabtube.fragment.DisplayVideosFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_video">
<argument
android:name="type"
android:defaultValue="LOCAL"
app:argType="app.fedilab.fedilabtube.viewmodel.TimelineVM$TimelineType" />
</fragment>
</navigation>

View File

@ -1,62 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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"
app:startDestination="@id/navigation_discover">
<fragment
android:id="@+id/navigation_discover"
android:name="app.fedilab.fedilabtube.fragment.DisplayOverviewFragment"
android:label="@string/title_discover"
tools:layout="@layout/fragment_video">
</fragment>
<fragment
android:id="@+id/navigation_subscription"
android:name="app.fedilab.fedilabtube.fragment.DisplayVideosFragment"
android:label="@string/subscriptions"
tools:layout="@layout/fragment_video">
<argument
android:name="type"
android:defaultValue="SUBSCRIBTIONS"
app:argType="app.fedilab.fedilabtube.viewmodel.TimelineVM$TimelineType" />
</fragment>
<fragment
android:id="@+id/navigation_trending"
android:name="app.fedilab.fedilabtube.fragment.DisplayVideosFragment"
android:label="@string/title_trending"
tools:layout="@layout/fragment_video">
<argument
android:name="type"
android:defaultValue="TRENDING"
app:argType="app.fedilab.fedilabtube.viewmodel.TimelineVM$TimelineType" />
</fragment>
<fragment
android:id="@+id/navigation_local"
android:name="app.fedilab.fedilabtube.fragment.DisplayVideosFragment"
android:label="@string/title_local"
tools:layout="@layout/fragment_video">
<argument
android:name="type"
android:defaultValue="LOCAL"
app:argType="app.fedilab.fedilabtube.viewmodel.TimelineVM$TimelineType" />
</fragment>
<fragment
android:id="@+id/navigation_recently_added"
android:name="app.fedilab.fedilabtube.fragment.DisplayVideosFragment"
android:label="@string/title_recently_added"
tools:layout="@layout/fragment_video">
<argument
android:name="type"
android:defaultValue="RECENT"
app:argType="app.fedilab.fedilabtube.viewmodel.TimelineVM$TimelineType" />
</fragment>
</navigation>