1
0
mirror of https://framagit.org/tom79/fedilab-tube synced 2025-06-05 21:09:11 +02:00

display accounts

This commit is contained in:
Thomas
2020-09-03 18:56:48 +02:00
parent 6d66b2f08b
commit 38e9d9f090
20 changed files with 463 additions and 115 deletions

View File

@ -21,12 +21,12 @@ import androidx.multidex.MultiDexApplication;
import net.gotev.uploadservice.UploadService;
public class FedilabTupe extends MultiDexApplication {
public class FedilabTube extends MultiDexApplication {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(FedilabTupe.this);
MultiDex.install(FedilabTube.this);
UploadService.NAMESPACE = BuildConfig.APPLICATION_ID;
}

View File

@ -14,6 +14,7 @@ package app.fedilab.fedilabtube;
* You should have received a copy of the GNU General Public License along with TubeLab; if not,
* see <http://www.gnu.org/licenses>. */
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@ -112,9 +113,7 @@ public class MainActivity extends AppCompatActivity {
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
Account account = new AccountDAO(MainActivity.this, db).getUniqAccount(userId, instance);
if (account != null) {
new Thread(() -> {
new PeertubeAPI(MainActivity.this).refreshToken(account.getToken(), account.getInstance());
}).start();
new Thread(() -> new PeertubeAPI(MainActivity.this).refreshToken(account.getToken(), account.getInstance())).start();
}
} else {
instanceItem.setVisible(true);
@ -174,6 +173,7 @@ public class MainActivity extends AppCompatActivity {
}
}
@SuppressLint("ApplySharedPref")
private void showRadioButtonDialog() {
AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);

View File

@ -0,0 +1,50 @@
package app.fedilab.fedilabtube.asynctasks;
/* 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 <http://www.gnu.org/licenses>. */
import android.content.Context;
import android.os.AsyncTask;
import java.lang.ref.WeakReference;
import app.fedilab.fedilabtube.client.APIResponse;
import app.fedilab.fedilabtube.client.PeertubeAPI;
import app.fedilab.fedilabtube.interfaces.OnRetrieveAccountsInterface;
public class RetrieveAccountSubscriptionsAsyncTask extends AsyncTask<Void, Void, APIResponse> {
private OnRetrieveAccountsInterface listener;
private WeakReference<Context> contextReference;
private String max_id;
public RetrieveAccountSubscriptionsAsyncTask(Context context, String max_id, OnRetrieveAccountsInterface onRetrieveAccountsInterface) {
this.contextReference = new WeakReference<>(context);
this.max_id = max_id;
this.listener = onRetrieveAccountsInterface;
}
@Override
protected APIResponse doInBackground(Void... params) {
PeertubeAPI peertubeAPI = new PeertubeAPI(this.contextReference.get());
return peertubeAPI.getSubscriptionUsers(max_id);
}
@Override
protected void onPostExecute(APIResponse apiResponse) {
listener.onRetrieveAccounts(apiResponse);
}
}

View File

@ -24,9 +24,8 @@ import app.fedilab.fedilabtube.client.PeertubeAPI;
import app.fedilab.fedilabtube.interfaces.OnRetrieveAccountsInterface;
public class RetrieveAccountsAsyncTask extends AsyncTask<Void, Void, Void> {
public class RetrieveAccountsAsyncTask extends AsyncTask<Void, Void, APIResponse> {
private APIResponse apiResponse;
private OnRetrieveAccountsInterface listener;
private WeakReference<Context> contextReference;
private String name;
@ -39,16 +38,14 @@ public class RetrieveAccountsAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
protected APIResponse doInBackground(Void... params) {
PeertubeAPI peertubeAPI = new PeertubeAPI(this.contextReference.get());
apiResponse = peertubeAPI.getPeertubeChannel(name);
return null;
return peertubeAPI.getPeertubeChannel(name);
}
@Override
protected void onPostExecute(Void result) {
protected void onPostExecute(APIResponse apiResponse) {
listener.onRetrieveAccounts(apiResponse);
}
}

View File

@ -450,7 +450,9 @@ public class PeertubeAPI {
else
account.setNote("");
account.setUrl(accountObject.get("url").toString());
if (accountObject.has("url")) {
account.setUrl(accountObject.get("url").toString());
}
if (accountObject.has("avatar") && !accountObject.isNull("avatar")) {
account.setAvatar(accountObject.getJSONObject("avatar").get("path").toString());
account.setAvatar_static(accountObject.getJSONObject("avatar").get("path").toString());
@ -1168,7 +1170,7 @@ public class PeertubeAPI {
}
/**
* Retrieves subscription videos *synchronously*
* Retrieves subscriptions *synchronously*
*
* @param max_id String id max
* @return APIResponse
@ -1181,11 +1183,12 @@ public class PeertubeAPI {
if (max_id != null)
params.put("start", max_id);
params.put("sort", "-createdAt");
String response = httpsConnection.get("/users/me/subscriptions", 60, params, null);
String response = httpsConnection.get(getAbsoluteUrl("/users/me/subscriptions"), 10, params, prefKeyOauthTokenT);
JSONArray jsonArray = new JSONObject(response).getJSONArray("data");
accounts = parseAccountResponsePeertube(jsonArray);
} catch (HttpsConnection.HttpsConnectionException e) {
setError(e.getStatusCode(), e);
e.printStackTrace();
} catch (NoSuchAlgorithmException | IOException | KeyManagementException | JSONException e) {
e.printStackTrace();
}
@ -1867,7 +1870,7 @@ public class PeertubeAPI {
String errorM = jsonObject.getString("error");
message = "Error " + statusCode + " : " + errorM;
} catch (JSONException e) {
if (error.getMessage().split(".").length > 0) {
if (error.getMessage() != null && error.getMessage().split(".").length > 0) {
String errorM = error.getMessage().split(".")[0];
message = "Error " + statusCode + " : " + errorM;
}

View File

@ -0,0 +1,160 @@
package app.fedilab.fedilabtube.drawer;
/* 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 <http://www.gnu.org/licenses>. */
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.ShowAccountActivity;
import app.fedilab.fedilabtube.client.PeertubeAPI;
import app.fedilab.fedilabtube.client.entities.Account;
import app.fedilab.fedilabtube.client.entities.Error;
import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.interfaces.OnPostActionInterface;
import es.dmoral.toasty.Toasty;
public class AccountsHorizontalListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnPostActionInterface {
private List<Account> accounts;
private Context context;
private AccountsHorizontalListAdapter accountsListAdapter;
public AccountsHorizontalListAdapter(List<Account> accounts) {
this.accounts = accounts;
this.accountsListAdapter = this;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
LayoutInflater layoutInflater = LayoutInflater.from(context);
return new ViewHolder(layoutInflater.inflate(R.layout.drawer_horizontal_account, parent, false));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
final AccountsHorizontalListAdapter.ViewHolder holder = (AccountsHorizontalListAdapter.ViewHolder) viewHolder;
final Account account = accounts.get(position);
if (account.getDisplay_name() != null && !account.getDisplay_name().trim().equals(""))
holder.account_dn.setText(account.getDisplay_name());
else
holder.account_dn.setText(account.getUsername().replace("@", ""));
//Profile picture
Helper.loadGiF(context, account, holder.account_pp, 270);
holder.account_pp.setOnClickListener(v -> {
Intent intent = new Intent(context, ShowAccountActivity.class);
Bundle b = new Bundle();
b.putBoolean("peertubeaccount", true);
b.putBoolean("ischannel", true);
b.putString("targetedid", account.getAcct());
b.putParcelable("account", account);
intent.putExtras(b);
context.startActivity(intent);
});
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemCount() {
return accounts.size();
}
private Account getItemAt(int position) {
if (accounts.size() > position)
return accounts.get(position);
else
return null;
}
@Override
public void onPostAction(int statusCode, PeertubeAPI.StatusAction statusAction, String targetedId, Error error) {
if (error != null) {
Toasty.error(context, error.getError(), Toast.LENGTH_LONG).show();
return;
}
if (statusAction == PeertubeAPI.StatusAction.FOLLOW) {
/* if (action == RetrieveAccountsAsyncTask.Type.CHANNELS) {
SQLiteDatabase db = Sqlite.getInstance(context.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
new InstancesDAO(context, db).insertInstance(accounts.get(0).getAcct().split("@")[1], accounts.get(0).getAcct().split("@")[0], "PEERTUBE_CHANNEL");
} else {
for (Account account : accounts) {
if (account.getId().equals(targetedId)) {
account.setFollowType(Account.followAction.FOLLOW);
account.setMakingAction(false);
}
}
accountsListAdapter.notifyDataSetChanged();
}*/
}
if (statusAction == PeertubeAPI.StatusAction.UNFOLLOW) {
for (Account account : accounts) {
if (account.getId().equals(targetedId)) {
account.setFollowType(Account.followAction.NOT_FOLLOW);
account.setMakingAction(false);
}
}
accountsListAdapter.notifyDataSetChanged();
}
}
private void notifyAccountChanged(Account account) {
for (int i = 0; i < accountsListAdapter.getItemCount(); i++) {
//noinspection ConstantConditions
if (accountsListAdapter.getItemAt(i) != null && accountsListAdapter.getItemAt(i).getId().equals(account.getId())) {
try {
accountsListAdapter.notifyItemChanged(i);
} catch (Exception ignored) {
}
}
}
}
private static class ViewHolder extends RecyclerView.ViewHolder {
ImageView account_pp;
TextView account_dn;
ViewHolder(View itemView) {
super(itemView);
account_pp = itemView.findViewById(R.id.account_pp);
account_dn = itemView.findViewById(R.id.account_dn);
}
}
}

View File

@ -46,7 +46,7 @@ public class DisplayAccountsFragment extends Fragment implements OnRetrieveAccou
private boolean flag_loading;
private Context context;
private AsyncTask<Void, Void, Void> asyncTask;
private AsyncTask<Void, Void, APIResponse> asyncTask;
private AccountsListAdapter accountsListAdapter;
private String max_id;
private List<Account> accounts;

View File

@ -42,22 +42,27 @@ import java.util.ArrayList;
import java.util.List;
import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.asynctasks.RetrieveAccountSubscriptionsAsyncTask;
import app.fedilab.fedilabtube.asynctasks.RetrieveFeedsAsyncTask;
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;
import app.fedilab.fedilabtube.client.entities.Error;
import app.fedilab.fedilabtube.client.entities.Peertube;
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 es.dmoral.toasty.Toasty;
import static app.fedilab.fedilabtube.asynctasks.RetrieveFeedsAsyncTask.Type.POVERVIEW;
import static app.fedilab.fedilabtube.asynctasks.RetrieveFeedsAsyncTask.Type.PSUBSCRIPTIONS;
public class DisplayStatusFragment extends Fragment implements OnPostActionInterface, OnRetrieveFeedsInterface {
public class DisplayStatusFragment extends Fragment implements OnPostActionInterface, OnRetrieveFeedsInterface, OnRetrieveAccountsInterface {
private LinearLayoutManager mLayoutManager;
@ -66,8 +71,10 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter
private Context context;
private AsyncTask<Void, Void, Void> asyncTask;
private PeertubeAdapter peertubeAdapater;
private String max_id;
private AccountsHorizontalListAdapter accountsHorizontalListAdapter;
private String max_id, max_id_accounts;
private List<Peertube> peertubes;
private List<Account> accounts;
private RetrieveFeedsAsyncTask.Type type;
private RelativeLayout mainLoader, nextElementLoader, textviewNoAction;
private boolean firstLoad;
@ -78,7 +85,9 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter
private boolean ischannel;
private View rootView;
private RecyclerView lv_status;
private RecyclerView lv_accounts;
private String targetedId;
private boolean check_ScrollingUp;
public DisplayStatusFragment() {
}
@ -90,6 +99,7 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter
peertubes = new ArrayList<>();
accounts = new ArrayList<>();
context = getContext();
Bundle bundle = this.getArguments();
@ -111,10 +121,13 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter
lv_status = rootView.findViewById(R.id.lv_status);
lv_accounts = rootView.findViewById(R.id.lv_accounts);
max_id = null;
max_id_accounts = null;
flag_loading = true;
firstLoad = true;
check_ScrollingUp = false;
assert context != null;
sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
@ -130,6 +143,12 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter
peertubeAdapater = new PeertubeAdapter(this.peertubes);
lv_status.setAdapter(peertubeAdapater);
accountsHorizontalListAdapter = new AccountsHorizontalListAdapter(this.accounts);
LinearLayoutManager layoutManager
= new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
lv_accounts.setLayoutManager(layoutManager);
lv_accounts.setAdapter(accountsHorizontalListAdapter);
if (!Helper.isTablet(context)) {
mLayoutManager = new LinearLayoutManager(context);
lv_status.setLayoutManager(mLayoutManager);
@ -162,9 +181,39 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter
}, 500);
}
lv_accounts.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 && context != null) {
new RetrieveAccountSubscriptionsAsyncTask(context, max_id_accounts, DisplayStatusFragment.this).execute();
}
}
}
});
if (type != POVERVIEW) {
lv_status.addOnScrollListener(new RecyclerView.OnScrollListener() {
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
if (type == PSUBSCRIPTIONS) {
if (dy > 0) {
if (check_ScrollingUp) {
lv_accounts.setVisibility(View.GONE);
final Handler handler = new Handler();
handler.postDelayed(() -> check_ScrollingUp = false, 300);
}
} else {
if (!check_ScrollingUp) {
lv_accounts.setVisibility(View.VISIBLE);
final Handler handler = new Handler();
handler.postDelayed(() -> check_ScrollingUp = true, 300);
}
}
}
if (mLayoutManager != null) {
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
if (dy > 0) {
@ -207,7 +256,9 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter
}
});
}
if (type == PSUBSCRIPTIONS) {
new RetrieveAccountSubscriptionsAsyncTask(context, max_id, DisplayStatusFragment.this).execute();
}
return rootView;
}
@ -254,6 +305,24 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter
asyncTask.cancel(true);
}
@Override
public void onRetrieveAccounts(APIResponse apiResponse) {
if (apiResponse != null && apiResponse.getAccounts() != null && apiResponse.getAccounts().size() > 0) {
if (lv_accounts.getVisibility() == View.GONE) {
lv_accounts.setVisibility(View.VISIBLE);
}
int previousPosition = accounts.size();
accounts.addAll(apiResponse.getAccounts());
accountsHorizontalListAdapter.notifyItemRangeInserted(previousPosition, apiResponse.getAccounts().size());
if (max_id_accounts == null)
max_id_accounts = "0";
//max_id needs to work like an offset
int tootPerPage = sharedpreferences.getInt(Helper.SET_VIDEOS_PER_PAGE, Helper.VIDEOS_PER_PAGE);
max_id_accounts = String.valueOf(Integer.parseInt(max_id_accounts) + tootPerPage);
}
}
@Override
public void onRetrieveFeeds(APIResponse apiResponse) {
//hide loaders

View File

@ -407,14 +407,12 @@ public class Helper {
}
public static void loadGiF(final Context context, Account account, final ImageView imageView) {
public static void loadGiF(final Context context, Account account, final ImageView imageView, int round) {
if (account == null || account.getAvatar() == null || account.getAvatar().compareTo("null") == 0) {
Glide.with(imageView.getContext())
.asDrawable()
.load(R.drawable.missing_peertube)
.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10)))
.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(round)))
.into(imageView);
return;
}
@ -429,14 +427,14 @@ public class Helper {
Glide.with(imageView.getContext())
.load(url)
.thumbnail(0.1f)
.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10)))
.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(round)))
.into(imageView);
} catch (Exception e) {
try {
Glide.with(imageView.getContext())
.asDrawable()
.load(R.drawable.missing_peertube)
.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10)))
.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(round)))
.into(imageView);
} catch (Exception ignored) {
@ -444,6 +442,10 @@ public class Helper {
}
}
public static void loadGiF(final Context context, Account account, final ImageView imageView) {
loadGiF(context, account, imageView, 10);
}
public static void loadGiF(final Context context, String url, final ImageView imageView) {

View File

@ -68,11 +68,11 @@ public class AccountDAO {
values.put(Sqlite.COL_HEADER_STATIC, account.getHeader_static());
values.put(Sqlite.COL_CREATED_AT, Helper.dateToString(account.getCreated_at()));
values.put(Sqlite.COL_INSTANCE, account.getInstance());
if (account.getClient_id() != null && account.getClient_secret() != null ) {
if (account.getClient_id() != null && account.getClient_secret() != null) {
values.put(Sqlite.COL_CLIENT_ID, account.getClient_id());
values.put(Sqlite.COL_CLIENT_SECRET, account.getClient_secret());
}
if( account.getRefresh_token() != null) {
if (account.getRefresh_token() != null) {
values.put(Sqlite.COL_REFRESH_TOKEN, account.getRefresh_token());
}
if (account.getToken() != null)
@ -120,7 +120,7 @@ public class AccountDAO {
values.put(Sqlite.COL_CLIENT_ID, account.getClient_id());
values.put(Sqlite.COL_CLIENT_SECRET, account.getClient_secret());
}
if( account.getRefresh_token() != null) {
if (account.getRefresh_token() != null) {
values.put(Sqlite.COL_REFRESH_TOKEN, account.getRefresh_token());
}
if (account.getToken() != null)
@ -161,7 +161,7 @@ public class AccountDAO {
values.put(Sqlite.COL_CLIENT_ID, account.getClient_id());
values.put(Sqlite.COL_CLIENT_SECRET, account.getClient_secret());
}
if( account.getRefresh_token() != null) {
if (account.getRefresh_token() != null) {
values.put(Sqlite.COL_REFRESH_TOKEN, account.getRefresh_token());
}
if (account.getToken() != null)