Commit c37f4bb6 authored by Thomas's avatar Thomas
Browse files

Familiar followers on profiles

parent 098e2d87
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.text.method.LinkMovementMethod;
import android.text.style.ForegroundColorSpan;
import android.text.style.UnderlineSpan;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -76,6 +77,7 @@ import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.R;
import app.fedilab.android.client.entities.api.Account;
import app.fedilab.android.client.entities.api.Attachment;
import app.fedilab.android.client.entities.api.FamiliarFollowers;
import app.fedilab.android.client.entities.api.Field;
import app.fedilab.android.client.entities.api.IdentityProof;
import app.fedilab.android.client.entities.api.MastodonList;
@@ -86,6 +88,7 @@ import app.fedilab.android.client.entities.app.RemoteInstance;
import app.fedilab.android.client.entities.app.Timeline;
import app.fedilab.android.client.entities.app.WellKnownNodeinfo;
import app.fedilab.android.databinding.ActivityProfileBinding;
import app.fedilab.android.databinding.NotificationsRelatedAccountsBinding;
import app.fedilab.android.exception.DBException;
import app.fedilab.android.helper.CrossActionHelper;
import app.fedilab.android.helper.Helper;
@@ -106,6 +109,7 @@ public class ProfileActivity extends BaseActivity {


    private RelationShip relationship;
    private FamiliarFollowers familiarFollowers;
    private Account account;
    private ScheduledExecutorService scheduledExecutorService;
    private action doAction;
@@ -255,6 +259,13 @@ public class ProfileActivity extends BaseActivity {
                updateAccount();
            }
        });
        accountsVM.getFamiliarFollowers(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, accountListToCheck).observe(ProfileActivity.this, familiarFollowersList -> {
            if (familiarFollowersList != null && familiarFollowersList.size() > 0) {
                this.familiarFollowers = familiarFollowersList.get(0);
                updateAccount();
            }
        });

        //Retrieve identity proofs
        accountsVM.getIdentityProofs(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, account.id).observe(ProfileActivity.this, identityProofs -> {
            this.identityProofList = identityProofs;
@@ -567,6 +578,27 @@ public class ProfileActivity extends BaseActivity {
            }
        }

        if (familiarFollowers != null && familiarFollowers.accounts != null && familiarFollowers.accounts.size() > 0) {
            binding.relatedAccounts.removeAllViews();
            for (Account account : familiarFollowers.accounts) {
                NotificationsRelatedAccountsBinding notificationsRelatedAccountsBinding = NotificationsRelatedAccountsBinding.inflate(LayoutInflater.from(ProfileActivity.this));
                MastodonHelper.loadProfileMediaMastodonRound(ProfileActivity.this, notificationsRelatedAccountsBinding.profilePicture, account);
                notificationsRelatedAccountsBinding.acc.setText(account.username);
                notificationsRelatedAccountsBinding.relatedAccountContainer.setOnClickListener(v -> {
                    Intent intent = new Intent(ProfileActivity.this, ProfileActivity.class);
                    Bundle b = new Bundle();
                    b.putSerializable(Helper.ARG_ACCOUNT, account);
                    intent.putExtras(b);
                    ActivityOptionsCompat options = ActivityOptionsCompat
                            .makeSceneTransitionAnimation(ProfileActivity.this, notificationsRelatedAccountsBinding.profilePicture, getString(R.string.activity_porfile_pp));
                    // start the new activity
                    startActivity(intent, options.toBundle());
                });
                binding.relatedAccounts.addView(notificationsRelatedAccountsBinding.getRoot());
            }
            binding.familiarFollowers.setVisibility(View.VISIBLE);
        }

        binding.accountFollow.setEnabled(true);
        //Visibility depending of the relationship
        if (relationship != null) {
+8 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package app.fedilab.android.client.endpoints;
import java.util.List;

import app.fedilab.android.client.entities.api.Account;
import app.fedilab.android.client.entities.api.FamiliarFollowers;
import app.fedilab.android.client.entities.api.FeaturedTag;
import app.fedilab.android.client.entities.api.IdentityProof;
import app.fedilab.android.client.entities.api.MastodonList;
@@ -253,6 +254,13 @@ public interface MastodonAccountsService {
            @Query("id[]") List<String> ids
    );

    //Get familiar followers
    @GET("accounts/familiar_followers ")
    Call<List<FamiliarFollowers>> getFamiliarFollowers(
            @Header("Authorization") String token,
            @Query("id[]") List<String> ids
    );

    //Get search
    @GET("accounts/search")
    Call<List<Account>> searchAccounts(
+28 −0
Original line number Diff line number Diff line
package app.fedilab.android.client.entities.api;
/* Copyright 2022 Thomas Schneider
 *
 * This file is a part of Fedilab
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with Fedilab; if not,
 * see <http://www.gnu.org/licenses>. */

import com.google.gson.annotations.SerializedName;

import java.io.Serializable;
import java.util.List;

public class FamiliarFollowers implements Serializable {

    @SerializedName("id")
    public String id;
    @SerializedName("accounts")
    public List<Account> accounts;
}
+49 −0
Original line number Diff line number Diff line
@@ -40,6 +40,9 @@ import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import com.google.gson.annotations.SerializedName;

import java.text.SimpleDateFormat;
@@ -268,6 +271,52 @@ public class MastodonHelper {
        }
    }

    public static void loadProfileMediaMastodonRound(Activity activity, ImageView view, Account account) {
        Context context = view.getContext();
        SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
        boolean disableGif = sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_GIF), false);
        @DrawableRes int placeholder = R.drawable.ic_person;
        if (Helper.isValidContextForGlide(activity != null ? activity : context)) {
            if (account == null) {
                Glide.with(activity != null ? activity : context)
                        .asDrawable()
                        .load(placeholder)
                        .apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(16)))
                        .thumbnail(0.1f)
                        .placeholder(placeholder)
                        .into(view);
                return;
            }
            String targetedUrl = disableGif ? account.avatar_static : account.avatar;
            if (targetedUrl != null) {
                if (disableGif || (!targetedUrl.endsWith(".gif"))) {
                    Glide.with(activity != null ? activity : context)
                            .asDrawable()
                            .load(targetedUrl)
                            .apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10)))
                            .thumbnail(0.1f)
                            .placeholder(placeholder)
                            .into(view);
                } else {
                    Glide.with(activity != null ? activity : context)
                            .asGif()
                            .load(targetedUrl)
                            .apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10)))
                            .thumbnail(0.1f)
                            .placeholder(placeholder)
                            .into(view);
                }
            } else {
                Glide.with(activity != null ? activity : context)
                        .asDrawable()
                        .load(placeholder)
                        .apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10)))
                        .thumbnail(0.1f)
                        .into(view);
            }
        }
    }

    /**
     * Convert a date in String -> format yyyy-MM-dd HH:mm:ss
     *
+34 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import app.fedilab.android.client.endpoints.MastodonAccountsService;
import app.fedilab.android.client.entities.api.Account;
import app.fedilab.android.client.entities.api.Accounts;
import app.fedilab.android.client.entities.api.Domains;
import app.fedilab.android.client.entities.api.FamiliarFollowers;
import app.fedilab.android.client.entities.api.FeaturedTag;
import app.fedilab.android.client.entities.api.Field;
import app.fedilab.android.client.entities.api.Filter;
@@ -90,6 +91,7 @@ public class AccountsVM extends AndroidViewModel {
    private MutableLiveData<List<IdentityProof>> identityProofListMutableLiveData;
    private MutableLiveData<RelationShip> relationShipMutableLiveData;
    private MutableLiveData<List<RelationShip>> relationShipListMutableLiveData;
    private MutableLiveData<List<FamiliarFollowers>> familiarFollowersListMutableLiveData;
    private MutableLiveData<Filter> filterMutableLiveData;
    private MutableLiveData<List<Filter>> filterListMutableLiveData;
    private MutableLiveData<List<Tag>> tagListMutableLiveData;
@@ -1025,6 +1027,38 @@ public class AccountsVM extends AndroidViewModel {
        return relationShipListMutableLiveData;
    }


    /**
     * Obtain a list of all accounts that follow a given account, filtered for accounts you follow.
     *
     * @param ids {@link List} of account IDs to check
     * @return {@link LiveData} containing a {@link List} of {@link FamiliarFollowers}s to given account(s)
     */
    public LiveData<List<FamiliarFollowers>> getFamiliarFollowers(@NonNull String instance, String token, @NonNull List<String> ids) {
        familiarFollowersListMutableLiveData = new MutableLiveData<>();
        MastodonAccountsService mastodonAccountsService = init(instance);
        new Thread(() -> {
            List<FamiliarFollowers> familiarFollowers = null;
            Call<List<FamiliarFollowers>> familiarFollowersCall = mastodonAccountsService.getFamiliarFollowers(token, ids);

            if (familiarFollowersCall != null) {
                try {
                    Response<List<FamiliarFollowers>> familiarFollowersResponse = familiarFollowersCall.execute();
                    if (familiarFollowersResponse.isSuccessful()) {
                        familiarFollowers = familiarFollowersResponse.body();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            Handler mainHandler = new Handler(Looper.getMainLooper());
            List<FamiliarFollowers> finalFamiliarFollowers = familiarFollowers;
            Runnable myRunnable = () -> familiarFollowersListMutableLiveData.setValue(finalFamiliarFollowers);
            mainHandler.post(myRunnable);
        }).start();
        return familiarFollowersListMutableLiveData;
    }

    /**
     * Search for matching accounts by username or display name.
     *
Loading