diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/requests/follow_requests/AuthorizeFollowRequest.java b/mastodon/src/main/java/org/joinmastodon/android/api/requests/follow_requests/AuthorizeFollowRequest.java new file mode 100644 index 000000000..765ef7f77 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/api/requests/follow_requests/AuthorizeFollowRequest.java @@ -0,0 +1,11 @@ +package org.joinmastodon.android.api.requests.follow_requests; + +import org.joinmastodon.android.api.MastodonAPIRequest; +import org.joinmastodon.android.model.Relationship; + +public class AuthorizeFollowRequest extends MastodonAPIRequest{ + public AuthorizeFollowRequest(String id){ + super(HttpMethod.POST, "/follow_requests/"+id+"/authorize", Relationship.class); + setRequestBody(new Object()); + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/requests/follow_requests/RejectFollowRequest.java b/mastodon/src/main/java/org/joinmastodon/android/api/requests/follow_requests/RejectFollowRequest.java new file mode 100644 index 000000000..23725795a --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/api/requests/follow_requests/RejectFollowRequest.java @@ -0,0 +1,11 @@ +package org.joinmastodon.android.api.requests.follow_requests; + +import org.joinmastodon.android.api.MastodonAPIRequest; +import org.joinmastodon.android.model.Relationship; + +public class RejectFollowRequest extends MastodonAPIRequest{ + public RejectFollowRequest(String id){ + super(HttpMethod.POST, "/follow_requests/"+id+"/reject", Relationship.class); + setRequestBody(new Object()); + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/events/NotificationDeletedEvent.java b/mastodon/src/main/java/org/joinmastodon/android/events/NotificationDeletedEvent.java new file mode 100644 index 000000000..e45419df0 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/events/NotificationDeletedEvent.java @@ -0,0 +1,9 @@ +package org.joinmastodon.android.events; + +public class NotificationDeletedEvent{ + public final String id; + + public NotificationDeletedEvent(String id){ + this.id=id; + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsListFragment.java index 2804be5c4..59f44ff49 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsListFragment.java @@ -9,6 +9,7 @@ import com.squareup.otto.Subscribe; import org.joinmastodon.android.E; import org.joinmastodon.android.R; import org.joinmastodon.android.api.session.AccountSessionManager; +import org.joinmastodon.android.events.NotificationDeletedEvent; import org.joinmastodon.android.events.PollUpdatedEvent; import org.joinmastodon.android.model.Notification; import org.joinmastodon.android.model.PaginatedResponse; @@ -78,7 +79,7 @@ public class NotificationsListFragment extends BaseStatusListFragment implements ImageLoaderViewHolder{ private final ImageView cover, avatar; private final TextView name, username, bio, followersCount, followingCount, postsCount, followersLabel, followingLabel, postsLabel; - private final ProgressBarButton actionButton; - private final ProgressBar actionProgress; - private final View actionWrap; + private final ProgressBarButton actionButton, acceptButton, rejectButton; + private final ProgressBar actionProgress, acceptProgress, rejectProgress; + private final View actionWrap, acceptWrap, rejectWrap; private Relationship relationship; @@ -96,6 +104,12 @@ public class AccountCardStatusDisplayItem extends StatusDisplayItem{ actionButton=findViewById(R.id.action_btn); actionProgress=findViewById(R.id.action_progress); actionWrap=findViewById(R.id.action_btn_wrap); + acceptButton=findViewById(R.id.accept_btn); + acceptProgress=findViewById(R.id.accept_progress); + acceptWrap=findViewById(R.id.accept_btn_wrap); + rejectButton=findViewById(R.id.reject_btn); + rejectProgress=findViewById(R.id.reject_progress); + rejectWrap=findViewById(R.id.reject_btn_wrap); View card=findViewById(R.id.card); card.setOutlineProvider(OutlineProviders.roundedRect(6)); @@ -105,6 +119,8 @@ public class AccountCardStatusDisplayItem extends StatusDisplayItem{ cover.setOutlineProvider(OutlineProviders.roundedRect(3)); cover.setClipToOutline(true); actionButton.setOnClickListener(this::onActionButtonClick); + acceptButton.setOnClickListener(this::onFollowRequestButtonClick); + rejectButton.setOnClickListener(this::onFollowRequestButtonClick); } @Override @@ -119,14 +135,36 @@ public class AccountCardStatusDisplayItem extends StatusDisplayItem{ followingLabel.setText(item.parentFragment.getResources().getQuantityString(R.plurals.following, (int)Math.min(999, item.account.followingCount))); postsLabel.setText(item.parentFragment.getResources().getQuantityString(R.plurals.posts, (int)Math.min(999, item.account.statusesCount))); relationship=item.parentFragment.getRelationship(item.account.id); - if(relationship==null){ + if(item.notification.type == Notification.Type.FOLLOW_REQUEST && (relationship == null || !relationship.followedBy)){ actionWrap.setVisibility(View.GONE); + acceptWrap.setVisibility(View.VISIBLE); + rejectWrap.setVisibility(View.VISIBLE); + + // i hate that i wasn't able to do this in xml + acceptButton.setCompoundDrawableTintList(acceptButton.getTextColors()); + acceptProgress.setIndeterminateTintList(acceptButton.getTextColors()); + rejectButton.setCompoundDrawableTintList(rejectButton.getTextColors()); + rejectProgress.setIndeterminateTintList(rejectButton.getTextColors()); + }else if(relationship==null){ + actionWrap.setVisibility(View.GONE); + acceptWrap.setVisibility(View.GONE); + rejectWrap.setVisibility(View.GONE); }else{ actionWrap.setVisibility(View.VISIBLE); + acceptWrap.setVisibility(View.GONE); + rejectWrap.setVisibility(View.GONE); UiUtils.setRelationshipToActionButton(relationship, actionButton); } } + private void onFollowRequestButtonClick(View v) { + itemView.setHasTransientState(true); + UiUtils.handleFollowRequest((Activity) v.getContext(), item.account, item.parentFragment.getAccountID(), item.notification.id , v == acceptButton, relationship, rel -> { + itemView.setHasTransientState(false); + item.parentFragment.putRelationship(item.account.id, rel); + rebind(); + }); + } private void onActionButtonClick(View v){ itemView.setHasTransientState(true); diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java index bd7e657f1..edddc815c 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java @@ -39,11 +39,14 @@ import org.joinmastodon.android.api.requests.accounts.SetAccountBlocked; import org.joinmastodon.android.api.requests.accounts.SetAccountFollowed; import org.joinmastodon.android.api.requests.accounts.SetAccountMuted; import org.joinmastodon.android.api.requests.accounts.SetDomainBlocked; +import org.joinmastodon.android.api.requests.follow_requests.AuthorizeFollowRequest; +import org.joinmastodon.android.api.requests.follow_requests.RejectFollowRequest; import org.joinmastodon.android.api.requests.statuses.DeleteStatus; import org.joinmastodon.android.api.requests.statuses.GetStatusByID; import org.joinmastodon.android.api.requests.statuses.SetStatusPinned; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.events.StatusCountersUpdatedEvent; +import org.joinmastodon.android.events.NotificationDeletedEvent; import org.joinmastodon.android.events.StatusDeletedEvent; import org.joinmastodon.android.events.StatusUnpinnedEvent; import org.joinmastodon.android.fragments.BaseStatusListFragment; @@ -532,6 +535,38 @@ public class UiUtils{ } } + + public static void handleFollowRequest(Activity activity, Account account, String accountID, String notificationID, boolean accepted, Relationship relationship, Consumer resultCallback) { + if (accepted) { + new AuthorizeFollowRequest(account.id).setCallback(new Callback<>() { + @Override + public void onSuccess(Relationship rel) { + resultCallback.accept(rel); + } + + @Override + public void onError(ErrorResponse error) { + resultCallback.accept(relationship); + error.showToast(activity); + } + }).exec(accountID); + } else { + new RejectFollowRequest(account.id).setCallback(new Callback<>() { + @Override + public void onSuccess(Relationship rel) { + E.post(new NotificationDeletedEvent(notificationID)); + resultCallback.accept(rel); + } + + @Override + public void onError(ErrorResponse error) { + resultCallback.accept(relationship); + error.showToast(activity); + } + }).exec(accountID); + } + } + public static void updateList(List oldList, List newList, RecyclerView list, RecyclerView.Adapter adapter, BiPredicate areItemsSame){ // Save topmost item position and offset because for some reason RecyclerView would scroll the list to weird places when you insert items at the top int topItem, topItemOffset; diff --git a/mastodon/src/main/res/layout/item_discover_account.xml b/mastodon/src/main/res/layout/item_discover_account.xml index b702da02a..bc5e67a00 100644 --- a/mastodon/src/main/res/layout/item_discover_account.xml +++ b/mastodon/src/main/res/layout/item_discover_account.xml @@ -11,11 +11,11 @@ android:id="@+id/cover" android:layout_width="match_parent" android:layout_height="128dp" - android:layout_marginTop="4dp" android:layout_marginLeft="4dp" + android:layout_marginTop="4dp" android:layout_marginRight="4dp" android:scaleType="centerCrop" - tools:src="#0f0"/> + tools:src="#0f0" /> + android:layout_marginTop="16dp" + android:gravity="center_horizontal" + android:orientation="vertical"> + + tools:text="123" /> + + tools:text="following" /> + android:layout_marginTop="16dp" + android:gravity="center_horizontal" + android:orientation="vertical"> + + tools:text="123" /> + + tools:text="following" /> + android:layout_weight="1" /> + + + + + + + + + + + + + + + android:visibility="gone"> + + tools:text="@string/follow_back" /> + + android:outlineProvider="none" + android:visibility="gone" /> diff --git a/mastodon/src/main/res/values-de-rDE/strings.xml b/mastodon/src/main/res/values-de-rDE/strings.xml index 3079c5a55..1faab4e3f 100644 --- a/mastodon/src/main/res/values-de-rDE/strings.xml +++ b/mastodon/src/main/res/values-de-rDE/strings.xml @@ -406,4 +406,6 @@ Kein Update verfügbar Listen Favorisierte Beiträge + Folgeanfrage akzeptieren + Folgeanfrage ablehnen diff --git a/mastodon/src/main/res/values/strings.xml b/mastodon/src/main/res/values/strings.xml index 4dd8fd65e..369ac84ca 100644 --- a/mastodon/src/main/res/values/strings.xml +++ b/mastodon/src/main/res/values/strings.xml @@ -416,4 +416,6 @@ I Agree Lists Favorited posts + Accept follow request + Reject follow request \ No newline at end of file