parent
5fa81e6c8a
commit
12fdd70ad0
|
@ -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<Relationship>{
|
||||
public AuthorizeFollowRequest(String id){
|
||||
super(HttpMethod.POST, "/follow_requests/"+id+"/authorize", Relationship.class);
|
||||
setRequestBody(new Object());
|
||||
}
|
||||
}
|
|
@ -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<Relationship>{
|
||||
public RejectFollowRequest(String id){
|
||||
super(HttpMethod.POST, "/follow_requests/"+id+"/reject", Relationship.class);
|
||||
setRequestBody(new Object());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package org.joinmastodon.android.events;
|
||||
|
||||
public class NotificationDeletedEvent{
|
||||
public final String id;
|
||||
|
||||
public NotificationDeletedEvent(String id){
|
||||
this.id=id;
|
||||
}
|
||||
}
|
|
@ -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<Notificati
|
|||
items.add(0, titleItem);
|
||||
return items;
|
||||
}else if(titleItem!=null){
|
||||
AccountCardStatusDisplayItem card=new AccountCardStatusDisplayItem(n.id, this, n.account, n.type);
|
||||
AccountCardStatusDisplayItem card=new AccountCardStatusDisplayItem(n.id, this, n.account, n);
|
||||
return Arrays.asList(titleItem, card);
|
||||
}else{
|
||||
return Collections.emptyList();
|
||||
|
@ -180,4 +181,28 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
|
|||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNotificationDeleted(NotificationDeletedEvent ev) {
|
||||
Notification notification = getNotificationByID(ev.id);
|
||||
if(notification==null)
|
||||
return;
|
||||
data.remove(notification);
|
||||
int index=-1;
|
||||
for(int i=0;i<displayItems.size();i++){
|
||||
if(ev.id.equals(displayItems.get(i).parentID)){
|
||||
index=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(index==-1)
|
||||
return;
|
||||
int lastIndex;
|
||||
for(lastIndex=index;lastIndex<displayItems.size();lastIndex++){
|
||||
if(!displayItems.get(lastIndex).parentID.equals(ev.id))
|
||||
break;
|
||||
}
|
||||
displayItems.subList(index, lastIndex).clear();
|
||||
adapter.notifyItemRangeRemoved(index, lastIndex-index);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,10 +13,13 @@ import android.widget.ProgressBar;
|
|||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.follow_requests.AuthorizeFollowRequest;
|
||||
import org.joinmastodon.android.api.requests.follow_requests.RejectFollowRequest;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Notification;
|
||||
import org.joinmastodon.android.model.Relationship;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.OutlineProviders;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
||||
|
@ -25,6 +28,8 @@ import org.joinmastodon.android.ui.views.ProgressBarButton;
|
|||
|
||||
import java.util.Collections;
|
||||
|
||||
import me.grishka.appkit.api.Callback;
|
||||
import me.grishka.appkit.api.ErrorResponse;
|
||||
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||
|
@ -32,15 +37,15 @@ import me.grishka.appkit.utils.V;
|
|||
|
||||
public class AccountCardStatusDisplayItem extends StatusDisplayItem{
|
||||
private final Account account;
|
||||
private final Notification.Type type;
|
||||
private final Notification notification;
|
||||
public ImageLoaderRequest avaRequest, coverRequest;
|
||||
public CustomEmojiHelper emojiHelper=new CustomEmojiHelper();
|
||||
public CharSequence parsedName, parsedBio;
|
||||
|
||||
public AccountCardStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Account account, Notification.Type type){
|
||||
public AccountCardStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Account account, Notification notification){
|
||||
super(parentID, parentFragment);
|
||||
this.account=account;
|
||||
this.type=type;
|
||||
this.notification=notification;
|
||||
if(!TextUtils.isEmpty(account.avatar))
|
||||
avaRequest=new UrlImageLoaderRequest(account.avatar, V.dp(50), V.dp(50));
|
||||
if(!TextUtils.isEmpty(account.header))
|
||||
|
@ -76,9 +81,9 @@ public class AccountCardStatusDisplayItem extends StatusDisplayItem{
|
|||
public static class Holder extends StatusDisplayItem.Holder<AccountCardStatusDisplayItem> implements ImageLoaderViewHolder{
|
||||
private final ImageView cover, avatar;
|
||||
private final TextView name, username, bio, followersCount, followingCount, postsCount, followersLabel, followingLabel, postsLabel;
|
||||
private final ProgressBarButton actionButton, rejectButton;
|
||||
private final ProgressBar actionProgress, rejectProgress;
|
||||
private final View actionWrap, rejectWrap;
|
||||
private final ProgressBarButton actionButton, acceptButton, rejectButton;
|
||||
private final ProgressBar actionProgress, acceptProgress, rejectProgress;
|
||||
private final View actionWrap, acceptWrap, rejectWrap;
|
||||
|
||||
private Relationship relationship;
|
||||
|
||||
|
@ -99,6 +104,9 @@ 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);
|
||||
|
@ -111,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
|
||||
|
@ -125,30 +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);
|
||||
}else if(item.type == Notification.Type.FOLLOW_REQUEST){
|
||||
actionWrap.setVisibility(View.VISIBLE);
|
||||
acceptWrap.setVisibility(View.VISIBLE);
|
||||
rejectWrap.setVisibility(View.VISIBLE);
|
||||
|
||||
|
||||
// i hate that i wasn't able to do this in xml
|
||||
actionButton.setCompoundDrawableTintList(actionButton.getTextColors());
|
||||
actionProgress.setIndeterminateTintList(actionButton.getTextColors());
|
||||
actionButton.setContentDescription(item.parentFragment.getString(R.string.accept_follow_request));
|
||||
acceptButton.setCompoundDrawableTintList(acceptButton.getTextColors());
|
||||
acceptProgress.setIndeterminateTintList(acceptButton.getTextColors());
|
||||
rejectButton.setCompoundDrawableTintList(rejectButton.getTextColors());
|
||||
rejectProgress.setIndeterminateTintList(rejectButton.getTextColors());
|
||||
rejectButton.setContentDescription(item.parentFragment.getString(R.string.reject_follow_request));
|
||||
|
||||
actionButton.setOnClickListener(i -> {
|
||||
|
||||
});
|
||||
}else if(relationship==null){
|
||||
actionWrap.setVisibility(View.GONE);
|
||||
acceptWrap.setVisibility(View.GONE);
|
||||
rejectWrap.setVisibility(View.GONE);
|
||||
}else{
|
||||
actionButton.setCompoundDrawables(null, null, null, null);
|
||||
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);
|
||||
|
|
|
@ -40,9 +40,12 @@ 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.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.events.NotificationDeletedEvent;
|
||||
import org.joinmastodon.android.events.StatusDeletedEvent;
|
||||
import org.joinmastodon.android.fragments.HashtagTimelineFragment;
|
||||
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||
|
@ -460,6 +463,38 @@ public class UiUtils{
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static void handleFollowRequest(Activity activity, Account account, String accountID, String notificationID, boolean accepted, Relationship relationship, Consumer<Relationship> 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 <T> void updateList(List<T> oldList, List<T> newList, RecyclerView list, RecyclerView.Adapter<?> adapter, BiPredicate<T, T> 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;
|
||||
|
|
|
@ -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" />
|
||||
|
||||
<View
|
||||
android:id="@+id/avatar_border"
|
||||
|
@ -81,6 +81,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/bio"
|
||||
android:paddingRight="8dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
|
@ -111,50 +112,54 @@
|
|||
android:id="@+id/followers_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_horizontal">
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/followers_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/m3_title_large"
|
||||
tools:text="123"/>
|
||||
tools:text="123" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/followers_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/m3_title_small"
|
||||
tools:text="following"/>
|
||||
tools:text="following" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/following_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_horizontal">
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/following_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/m3_title_large"
|
||||
tools:text="123"/>
|
||||
tools:text="123" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/following_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/m3_title_small"
|
||||
tools:text="following"/>
|
||||
tools:text="following" />
|
||||
</LinearLayout>
|
||||
|
||||
<Space
|
||||
android:layout_width="0px"
|
||||
android:layout_height="1px"
|
||||
android:layout_weight="1"/>
|
||||
android:layout_weight="1" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/reject_btn_wrap"
|
||||
|
@ -162,16 +167,17 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:clipToPadding="false"
|
||||
android:paddingVertical="8dp"
|
||||
android:visibility="gone">
|
||||
android:paddingHorizontal="4dp"
|
||||
android:paddingVertical="8dp">
|
||||
|
||||
<org.joinmastodon.android.ui.views.ProgressBarButton
|
||||
android:id="@+id/reject_btn"
|
||||
style="?secondaryButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/reject_follow_request"
|
||||
android:drawableStart="@drawable/ic_fluent_dismiss_24_filled"
|
||||
android:singleLine="true"/>
|
||||
android:singleLine="true" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/reject_progress"
|
||||
|
@ -182,7 +188,36 @@
|
|||
android:elevation="10dp"
|
||||
android:indeterminate="true"
|
||||
android:outlineProvider="none"
|
||||
android:visibility="gone"/>
|
||||
android:visibility="gone" />
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/accept_btn_wrap"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:clipToPadding="false"
|
||||
android:paddingHorizontal="4dp"
|
||||
android:paddingVertical="8dp">
|
||||
|
||||
<org.joinmastodon.android.ui.views.ProgressBarButton
|
||||
android:id="@+id/accept_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/accept_follow_request"
|
||||
android:drawableStart="@drawable/ic_fluent_checkmark_24_filled"
|
||||
android:singleLine="true" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/accept_progress"
|
||||
style="?android:progressBarStyleSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:elevation="10dp"
|
||||
android:indeterminate="true"
|
||||
android:outlineProvider="none"
|
||||
android:visibility="gone" />
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
|
@ -190,27 +225,28 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:clipToPadding="false"
|
||||
android:padding="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:clipToPadding="false">
|
||||
android:visibility="gone">
|
||||
|
||||
<org.joinmastodon.android.ui.views.ProgressBarButton
|
||||
android:id="@+id/action_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:drawableStart="@drawable/ic_fluent_checkmark_24_filled"
|
||||
tools:text="@string/follow_back"/>
|
||||
tools:text="@string/follow_back" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/action_progress"
|
||||
style="?android:progressBarStyleSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:indeterminate="true"
|
||||
style="?android:progressBarStyleSmall"
|
||||
android:elevation="10dp"
|
||||
android:outlineProvider="none"
|
||||
android:indeterminate="true"
|
||||
android:indeterminateTint="?colorButtonText"
|
||||
android:visibility="gone"/>
|
||||
android:outlineProvider="none"
|
||||
android:visibility="gone" />
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -387,6 +387,6 @@
|
|||
<string name="privacy_policy_title">Mastodon and your privacy</string>
|
||||
<string name="privacy_policy_subtitle">Although the Mastodon app does not collect any data, the server you sign up through may have a different policy. Take a minute to review and agree to the Mastodon app privacy policy and your server\'s privacy policy.</string>
|
||||
<string name="i_agree">I Agree</string>
|
||||
<string name="accept_follow_request">Accept follow request</string>
|
||||
<string name="accept_follow_request">Accept follow request</string>
|
||||
<string name="reject_follow_request">Reject follow request</string>
|
||||
</resources>
|
Loading…
Reference in New Issue