diff options
author | Thomas <tschneider.ac@gmail.com> | 2023-01-12 11:13:52 +0100 |
---|---|---|
committer | Thomas <tschneider.ac@gmail.com> | 2023-01-12 11:13:52 +0100 |
commit | c37f4bb643789d220c74bf204719080d1f69aaaf (patch) | |
tree | efbec2af839303a99ce6318a6bde83a608235201 /app/src | |
parent | 098e2d87ec1270db6defc9537ec035cb0aaf91cd (diff) |
Familiar followers on profiles
Diffstat (limited to 'app/src')
7 files changed, 191 insertions, 1 deletions
diff --git a/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java b/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java index 1ab57d6d8..27e59b80d 100644 --- a/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java @@ -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) { diff --git a/app/src/main/java/app/fedilab/android/client/endpoints/MastodonAccountsService.java b/app/src/main/java/app/fedilab/android/client/endpoints/MastodonAccountsService.java index 398c43dcc..28b10231d 100644 --- a/app/src/main/java/app/fedilab/android/client/endpoints/MastodonAccountsService.java +++ b/app/src/main/java/app/fedilab/android/client/endpoints/MastodonAccountsService.java @@ -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( diff --git a/app/src/main/java/app/fedilab/android/client/entities/api/FamiliarFollowers.java b/app/src/main/java/app/fedilab/android/client/entities/api/FamiliarFollowers.java new file mode 100644 index 000000000..1d753c55e --- /dev/null +++ b/app/src/main/java/app/fedilab/android/client/entities/api/FamiliarFollowers.java @@ -0,0 +1,28 @@ +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; +} diff --git a/app/src/main/java/app/fedilab/android/helper/MastodonHelper.java b/app/src/main/java/app/fedilab/android/helper/MastodonHelper.java index b86a9ecd7..8212dc74b 100644 --- a/app/src/main/java/app/fedilab/android/helper/MastodonHelper.java +++ b/app/src/main/java/app/fedilab/android/helper/MastodonHelper.java @@ -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 * diff --git a/app/src/main/java/app/fedilab/android/viewmodel/mastodon/AccountsVM.java b/app/src/main/java/app/fedilab/android/viewmodel/mastodon/AccountsVM.java index fbf377466..e9f23ec1a 100644 --- a/app/src/main/java/app/fedilab/android/viewmodel/mastodon/AccountsVM.java +++ b/app/src/main/java/app/fedilab/android/viewmodel/mastodon/AccountsVM.java @@ -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. * diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml index f98dcda65..79f8910ce 100644 --- a/app/src/main/res/layout/activity_profile.xml +++ b/app/src/main/res/layout/activity_profile.xml @@ -341,6 +341,44 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/info" /> + + + <androidx.appcompat.widget.LinearLayoutCompat + android:id="@+id/familiar_followers" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginHorizontal="6dp" + android:gravity="center_vertical" + android:orientation="horizontal" + android:padding="10dp" + android:visibility="gone" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/fields_container" + tools:visibility="visible"> + + <androidx.appcompat.widget.AppCompatTextView + android:id="@+id/type_of_concat" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:text="@string/also_followed_by" /> + + <HorizontalScrollView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="10dp" + android:layout_weight="1" + android:gravity="center_vertical"> + + <androidx.appcompat.widget.LinearLayoutCompat + android:id="@+id/related_accounts" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" /> + </HorizontalScrollView> + </androidx.appcompat.widget.LinearLayoutCompat> + <!-- End Fields container --> <androidx.appcompat.widget.LinearLayoutCompat android:id="@+id/warning_container" @@ -350,7 +388,7 @@ android:visibility="gone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/fields_container" + app:layout_constraintTop_toBottomOf="@+id/familiar_followers" tools:visibility="visible"> <androidx.appcompat.widget.AppCompatTextView diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e83cc5cc7..52f4e2280 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2205,4 +2205,5 @@ <string name="set_pixelfed_presentation">Pixelfed presentation for media</string> <string name="set_display_compact_buttons">Compact action buttons</string> <string name="set_display_compact_buttons_description">Buttons at the bottom of messages will not take the whole width</string> + <string name="also_followed_by">Followed by:</string> </resources>
\ No newline at end of file |