From 81de1c1aa0f4e968242838dd8f621f21ebe8d6b9 Mon Sep 17 00:00:00 2001 From: Thomas Date: Mon, 7 Sep 2020 14:14:36 +0200 Subject: [PATCH] VM-v2 --- .../fragment/DisplayStatusFragment.java | 109 ++++-------------- .../fedilabtube/viewmodel/AccountsVM.java | 76 ++++++++++++ .../fedilabtube/viewmodel/FeedsVM.java | 16 +-- .../fedilabtube/viewmodel/SearchVM.java | 62 ++++++++++ .../mobile_navigation_connected.xml | 10 +- 5 files changed, 175 insertions(+), 98 deletions(-) create mode 100644 app/src/main/java/app/fedilab/fedilabtube/viewmodel/AccountsVM.java create mode 100644 app/src/main/java/app/fedilab/fedilabtube/viewmodel/SearchVM.java diff --git a/app/src/main/java/app/fedilab/fedilabtube/fragment/DisplayStatusFragment.java b/app/src/main/java/app/fedilab/fedilabtube/fragment/DisplayStatusFragment.java index 3966a6e..1292d29 100644 --- a/app/src/main/java/app/fedilab/fedilabtube/fragment/DisplayStatusFragment.java +++ b/app/src/main/java/app/fedilab/fedilabtube/fragment/DisplayStatusFragment.java @@ -17,10 +17,8 @@ package app.fedilab.fedilabtube.fragment; import android.content.Context; import android.content.SharedPreferences; import android.graphics.Rect; -import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; -import android.os.Looper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -45,8 +43,6 @@ import java.util.ArrayList; import java.util.List; import app.fedilab.fedilabtube.R; -import app.fedilab.fedilabtube.asynctasks.RetrieveAccountsAsyncTask; -import app.fedilab.fedilabtube.asynctasks.RetrievePeertubeSearchAsyncTask; import app.fedilab.fedilabtube.client.APIResponse; import app.fedilab.fedilabtube.client.PeertubeAPI; import app.fedilab.fedilabtube.client.entities.Account; @@ -56,23 +52,22 @@ import app.fedilab.fedilabtube.drawer.AccountsHorizontalListAdapter; import app.fedilab.fedilabtube.drawer.PeertubeAdapter; import app.fedilab.fedilabtube.helper.Helper; import app.fedilab.fedilabtube.interfaces.OnPostActionInterface; -import app.fedilab.fedilabtube.interfaces.OnRetrieveAccountsInterface; -import app.fedilab.fedilabtube.interfaces.OnRetrieveFeedsInterface; +import app.fedilab.fedilabtube.viewmodel.AccountsVM; import app.fedilab.fedilabtube.viewmodel.FeedsVM; +import app.fedilab.fedilabtube.viewmodel.SearchVM; import es.dmoral.toasty.Toasty; import static app.fedilab.fedilabtube.viewmodel.FeedsVM.Type.POVERVIEW; import static app.fedilab.fedilabtube.viewmodel.FeedsVM.Type.PSUBSCRIPTIONS; -public class DisplayStatusFragment extends Fragment implements OnPostActionInterface, OnRetrieveFeedsInterface, OnRetrieveAccountsInterface, AccountsHorizontalListAdapter.EventListener { +public class DisplayStatusFragment extends Fragment implements OnPostActionInterface, AccountsHorizontalListAdapter.EventListener { private LinearLayoutManager mLayoutManager; private GridLayoutManager gLayoutManager; private boolean flag_loading; private Context context; - private AsyncTask asyncTask; private PeertubeAdapter peertubeAdapater; private AccountsHorizontalListAdapter accountsHorizontalListAdapter; private String max_id, max_id_accounts; @@ -167,27 +162,13 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter swipeRefreshLayout.setOnRefreshListener(this::pullToRefresh); - if (context != null) { - //Load data depending of the value - if (search_peertube == null) { //Not a Peertube search - FeedsVM viewModel = new ViewModelProvider(DisplayStatusFragment.this.requireActivity()).get(FeedsVM.class); - viewModel.getVideos(type, "0", targetedId, null).observe(DisplayStatusFragment.this.requireActivity(), this::manageVIew); - } else { - asyncTask = new RetrievePeertubeSearchAsyncTask(context, "0", search_peertube, DisplayStatusFragment.this).execute(); - } + //Load data depending of the value + if (search_peertube == null) { //Not a Peertube search + FeedsVM viewModel = new ViewModelProvider(DisplayStatusFragment.this.requireActivity()).get(FeedsVM.class); + viewModel.getVideos(type, "0", targetedId, null).observe(DisplayStatusFragment.this.requireActivity(), this::manageVIewVideos); } else { - new Handler(Looper.getMainLooper()).postDelayed(() -> { - if (context != null) { - if (search_peertube == null) { //Not a Peertube search - if (getActivity() != null) { - FeedsVM viewModel = new ViewModelProvider(getActivity()).get(FeedsVM.class); - viewModel.getVideos(type, "0", targetedId, null).observe(getActivity(), this::manageVIew); - } - } else { - asyncTask = new RetrievePeertubeSearchAsyncTask(context, "0", search_peertube, DisplayStatusFragment.this).execute(); - } - } - }, 500); + SearchVM viewModel = new ViewModelProvider(DisplayStatusFragment.this.requireActivity()).get(SearchVM.class); + viewModel.getVideos("0", search_peertube).observe(DisplayStatusFragment.this.requireActivity(), this::manageVIewVideos); } lv_accounts.addOnScrollListener(new RecyclerView.OnScrollListener() { @@ -197,7 +178,8 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter int visibleItemCount = mLayoutManager.getChildCount(); int totalItemCount = mLayoutManager.getItemCount(); if (firstVisibleItem + visibleItemCount == totalItemCount && context != null) { - new RetrieveAccountsAsyncTask(context, max_id_accounts, RetrieveAccountsAsyncTask.accountFetch.SUBSCRIPTION, DisplayStatusFragment.this).execute(); + AccountsVM viewModel = new ViewModelProvider(DisplayStatusFragment.this.requireActivity()).get(AccountsVM.class); + viewModel.getAccounts(max_id_accounts, AccountsVM.accountFetch.SUBSCRIPTION).observe(DisplayStatusFragment.this.requireActivity(), apiResponse -> manageViewAccounts(apiResponse)); } } } @@ -233,9 +215,10 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter flag_loading = true; if (search_peertube == null) { //Not a Peertube search FeedsVM viewModel = new ViewModelProvider(DisplayStatusFragment.this.requireActivity()).get(FeedsVM.class); - viewModel.getVideos(type, max_id, null, null).observe(DisplayStatusFragment.this.requireActivity(), apiResponse -> manageVIew(apiResponse)); + viewModel.getVideos(type, max_id, null, null).observe(DisplayStatusFragment.this.requireActivity(), apiResponse -> manageVIewVideos(apiResponse)); } else { - asyncTask = new RetrievePeertubeSearchAsyncTask(context, max_id, search_peertube, DisplayStatusFragment.this).execute(); + SearchVM viewModel = new ViewModelProvider(DisplayStatusFragment.this.requireActivity()).get(SearchVM.class); + viewModel.getVideos(max_id, search_peertube).observe(DisplayStatusFragment.this.requireActivity(), apiResponse -> manageVIewVideos(apiResponse)); } nextElementLoader.setVisibility(View.VISIBLE); } @@ -253,9 +236,10 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter flag_loading = true; if (search_peertube == null) { //Not a Peertube search FeedsVM viewModel = new ViewModelProvider(DisplayStatusFragment.this.requireActivity()).get(FeedsVM.class); - viewModel.getVideos(type, max_id, null, null).observe(DisplayStatusFragment.this.requireActivity(), apiResponse -> manageVIew(apiResponse)); + viewModel.getVideos(type, max_id, null, null).observe(DisplayStatusFragment.this.requireActivity(), apiResponse -> manageVIewVideos(apiResponse)); } else { - asyncTask = new RetrievePeertubeSearchAsyncTask(context, max_id, search_peertube, DisplayStatusFragment.this).execute(); + SearchVM viewModel = new ViewModelProvider(DisplayStatusFragment.this.requireActivity()).get(SearchVM.class); + viewModel.getVideos(max_id, search_peertube).observe(DisplayStatusFragment.this.requireActivity(), apiResponse -> manageVIewVideos(apiResponse)); } nextElementLoader.setVisibility(View.VISIBLE); } @@ -268,7 +252,8 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter }); } if (type == PSUBSCRIPTIONS) { - new RetrieveAccountsAsyncTask(context, max_id, RetrieveAccountsAsyncTask.accountFetch.SUBSCRIPTION, DisplayStatusFragment.this).execute(); + AccountsVM viewModel = new ViewModelProvider(DisplayStatusFragment.this.requireActivity()).get(AccountsVM.class); + viewModel.getAccounts(max_id, AccountsVM.accountFetch.SUBSCRIPTION).observe(DisplayStatusFragment.this.requireActivity(), this::manageViewAccounts); } display_all.setOnClickListener(v -> { @@ -316,13 +301,10 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter @Override public void onDestroy() { super.onDestroy(); - if (asyncTask != null && asyncTask.getStatus() == AsyncTask.Status.RUNNING) - asyncTask.cancel(true); } - @Override - public void onRetrieveAccounts(APIResponse apiResponse) { + private void manageViewAccounts(APIResponse apiResponse) { if (apiResponse != null && apiResponse.getAccounts() != null && apiResponse.getAccounts().size() > 0) { if (top_account_container.getVisibility() == View.GONE) { top_account_container.setVisibility(View.VISIBLE); @@ -340,51 +322,7 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter } - private void manageVIew(APIResponse apiResponse) { - //hide loaders - mainLoader.setVisibility(View.GONE); - nextElementLoader.setVisibility(View.GONE); - //handle other API error but discards 404 - error which can often happen due to toots which have been deleted - if (this.peertubes == null || apiResponse == null || (apiResponse.getError() != null && apiResponse.getError().getStatusCode() != 404 && apiResponse.getError().getStatusCode() != 501)) { - if (apiResponse == null) - Toasty.error(context, context.getString(R.string.toast_error), Toast.LENGTH_LONG).show(); - else { - Toasty.error(context, apiResponse.getError().getError(), Toast.LENGTH_LONG).show(); - } - swipeRefreshLayout.setRefreshing(false); - flag_loading = false; - return; - } - int previousPosition = this.peertubes.size(); - if (max_id == null) - max_id = "0"; - //max_id needs to work like an offset - int tootPerPage = sharedpreferences.getInt(Helper.SET_VIDEOS_PER_PAGE, Helper.VIDEOS_PER_PAGE); - max_id = String.valueOf(Integer.parseInt(max_id) + tootPerPage); - if (apiResponse.getPeertubes() == null) { - return; - } - this.peertubes.addAll(apiResponse.getPeertubes()); - //If no item were inserted previously the adapter is created - if (previousPosition == 0) { - peertubeAdapater = new PeertubeAdapter(this.peertubes); - lv_status.setAdapter(peertubeAdapater); - } else - peertubeAdapater.notifyItemRangeInserted(previousPosition, apiResponse.getPeertubes().size()); - //remove handlers - swipeRefreshLayout.setRefreshing(false); - textviewNoAction.setVisibility(View.GONE); - if (firstLoad && (apiResponse.getPeertubes() == null || apiResponse.getPeertubes().size() == 0)) { - textviewNoActionText.setText(R.string.no_video_to_display); - textviewNoAction.setVisibility(View.VISIBLE); - } - flag_loading = false; - firstLoad = false; - } - - - @Override - public void onRetrieveFeeds(APIResponse apiResponse) { + private void manageVIewVideos(APIResponse apiResponse) { //hide loaders mainLoader.setVisibility(View.GONE); nextElementLoader.setVisibility(View.GONE); @@ -469,9 +407,10 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter } if (search_peertube == null) { //Not a Peertube search FeedsVM viewModel = new ViewModelProvider(DisplayStatusFragment.this.requireActivity()).get(FeedsVM.class); - viewModel.getVideos(type, "0", targetedId, null).observe(DisplayStatusFragment.this.requireActivity(), this::manageVIew); + viewModel.getVideos(type, "0", targetedId, null).observe(DisplayStatusFragment.this.requireActivity(), this::manageVIewVideos); } else { - asyncTask = new RetrievePeertubeSearchAsyncTask(context, "0", search_peertube, DisplayStatusFragment.this).execute(); + SearchVM viewModel = new ViewModelProvider(DisplayStatusFragment.this.requireActivity()).get(SearchVM.class); + viewModel.getVideos("0", search_peertube).observe(DisplayStatusFragment.this.requireActivity(), this::manageVIewVideos); } } diff --git a/app/src/main/java/app/fedilab/fedilabtube/viewmodel/AccountsVM.java b/app/src/main/java/app/fedilab/fedilabtube/viewmodel/AccountsVM.java new file mode 100644 index 0000000..36ed908 --- /dev/null +++ b/app/src/main/java/app/fedilab/fedilabtube/viewmodel/AccountsVM.java @@ -0,0 +1,76 @@ +package app.fedilab.fedilabtube.viewmodel; +/* Copyright 2020 Thomas Schneider + * + * This file is a part of TubeLab + * + * 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. + * + * TubeLab 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 TubeLab; if not, + * see . */ + +import android.app.Application; +import android.content.Context; +import android.os.Handler; +import android.os.Looper; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; + +import app.fedilab.fedilabtube.client.APIResponse; +import app.fedilab.fedilabtube.client.PeertubeAPI; + + +public class AccountsVM extends AndroidViewModel { + private MutableLiveData apiResponseMutableLiveData; + private Application application; + + public AccountsVM(@NonNull Application application) { + super(application); + this.application = application; + } + + public LiveData getAccounts(String max_id, accountFetch type) { + if (apiResponseMutableLiveData == null) { + apiResponseMutableLiveData = new MutableLiveData<>(); + loadAccounts(max_id, type); + } + return apiResponseMutableLiveData; + } + + private void loadAccounts(String max_id, accountFetch type) { + Context _mContext = this.application.getApplicationContext(); + new Thread(() -> { + try { + PeertubeAPI peertubeAPI = new PeertubeAPI(_mContext); + APIResponse apiResponse = null; + if (type == accountFetch.SUBSCRIPTION) { + apiResponse = peertubeAPI.getSubscriptionUsers(max_id); + } else if (type == accountFetch.MUTED) { + apiResponse = peertubeAPI.getMuted(max_id); + } else if (type == accountFetch.CHANNEL) { + apiResponse = peertubeAPI.getPeertubeChannel(max_id); + } + Handler mainHandler = new Handler(Looper.getMainLooper()); + APIResponse finalApiResponse = apiResponse; + Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(finalApiResponse); + mainHandler.post(myRunnable); + } catch (Exception e) { + e.printStackTrace(); + } + }).start(); + } + + public enum accountFetch { + SUBSCRIPTION, + CHANNEL, + MUTED + } +} diff --git a/app/src/main/java/app/fedilab/fedilabtube/viewmodel/FeedsVM.java b/app/src/main/java/app/fedilab/fedilabtube/viewmodel/FeedsVM.java index d93d2a5..afac550 100644 --- a/app/src/main/java/app/fedilab/fedilabtube/viewmodel/FeedsVM.java +++ b/app/src/main/java/app/fedilab/fedilabtube/viewmodel/FeedsVM.java @@ -17,6 +17,8 @@ package app.fedilab.fedilabtube.viewmodel; import android.app.Application; import android.content.Context; import android.database.sqlite.SQLiteDatabase; +import android.os.Handler; +import android.os.Looper; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; @@ -42,10 +44,8 @@ public class FeedsVM extends AndroidViewModel { } public LiveData getVideos(Type action, String max_id, String target, String forAccount) { - if (apiResponseMutableLiveData == null) { - apiResponseMutableLiveData = new MutableLiveData<>(); - loadVideos(action, max_id, target, forAccount); - } + apiResponseMutableLiveData = new MutableLiveData<>(); + loadVideos(action, max_id, target, forAccount); return apiResponseMutableLiveData; } @@ -73,7 +73,6 @@ public class FeedsVM extends AndroidViewModel { peertubeAPI = new PeertubeAPI(_mContext); apiResponse = peertubeAPI.getVideosChannel(target, max_id); break; - case CACHE_BOOKMARKS_PEERTUBE: apiResponse = new APIResponse(); SQLiteDatabase db = Sqlite.getInstance(_mContext, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); @@ -112,9 +111,11 @@ public class FeedsVM extends AndroidViewModel { peertubeAPI = new PeertubeAPI(_mContext); apiResponse = peertubeAPI.getLikedTL(max_id); break; - } - apiResponseMutableLiveData.setValue(apiResponse); + Handler mainHandler = new Handler(Looper.getMainLooper()); + APIResponse finalApiResponse = apiResponse; + Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(finalApiResponse); + mainHandler.post(myRunnable); } catch (Exception e) { e.printStackTrace(); } @@ -135,6 +136,5 @@ public class FeedsVM extends AndroidViewModel { MYVIDEOS, PEERTUBE_HISTORY, CACHE_BOOKMARKS_PEERTUBE, - } } diff --git a/app/src/main/java/app/fedilab/fedilabtube/viewmodel/SearchVM.java b/app/src/main/java/app/fedilab/fedilabtube/viewmodel/SearchVM.java new file mode 100644 index 0000000..38df4af --- /dev/null +++ b/app/src/main/java/app/fedilab/fedilabtube/viewmodel/SearchVM.java @@ -0,0 +1,62 @@ +package app.fedilab.fedilabtube.viewmodel; +/* Copyright 2020 Thomas Schneider + * + * This file is a part of TubeLab + * + * 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. + * + * TubeLab 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 TubeLab; if not, + * see . */ + +import android.app.Application; +import android.content.Context; +import android.os.Handler; +import android.os.Looper; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; + +import app.fedilab.fedilabtube.client.APIResponse; +import app.fedilab.fedilabtube.client.PeertubeAPI; + + +public class SearchVM extends AndroidViewModel { + private MutableLiveData apiResponseMutableLiveData; + private Application application; + + public SearchVM(@NonNull Application application) { + super(application); + this.application = application; + } + + public LiveData getVideos(String max_id, String query) { + if (apiResponseMutableLiveData == null) { + apiResponseMutableLiveData = new MutableLiveData<>(); + loadVideos(max_id, query); + } + return apiResponseMutableLiveData; + } + + private void loadVideos(String max_id, String query) { + Context _mContext = this.application.getApplicationContext(); + new Thread(() -> { + try { + PeertubeAPI api = new PeertubeAPI(_mContext); + APIResponse apiResponse = api.searchPeertube(query, max_id); + Handler mainHandler = new Handler(Looper.getMainLooper()); + Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse); + mainHandler.post(myRunnable); + } catch (Exception e) { + e.printStackTrace(); + } + }).start(); + } +} diff --git a/app/src/main/res/navigation/mobile_navigation_connected.xml b/app/src/main/res/navigation/mobile_navigation_connected.xml index 7561056..94a3108 100644 --- a/app/src/main/res/navigation/mobile_navigation_connected.xml +++ b/app/src/main/res/navigation/mobile_navigation_connected.xml @@ -14,7 +14,7 @@ + app:argType="app.fedilab.fedilabtube.viewmodel.FeedsVM$Type" /> @@ -26,7 +26,7 @@ + app:argType="app.fedilab.fedilabtube.viewmodel.FeedsVM$Type" /> @@ -38,7 +38,7 @@ + app:argType="app.fedilab.fedilabtube.viewmodel.FeedsVM$Type" /> + app:argType="app.fedilab.fedilabtube.viewmodel.FeedsVM$Type" /> @@ -61,7 +61,7 @@ + app:argType="app.fedilab.fedilabtube.viewmodel.FeedsVM$Type" /> \ No newline at end of file