More account/post actions
This commit is contained in:
parent
6e6f73f2c0
commit
789d02d810
|
@ -4,8 +4,20 @@ import org.joinmastodon.android.api.MastodonAPIRequest;
|
|||
import org.joinmastodon.android.model.Relationship;
|
||||
|
||||
public class SetAccountFollowed extends MastodonAPIRequest<Relationship>{
|
||||
public SetAccountFollowed(String id, boolean followed){
|
||||
public SetAccountFollowed(String id, boolean followed, boolean showReblogs){
|
||||
super(HttpMethod.POST, "/accounts/"+id+"/"+(followed ? "follow" : "unfollow"), Relationship.class);
|
||||
setRequestBody(new Object());
|
||||
if(followed)
|
||||
setRequestBody(new Request(showReblogs, null));
|
||||
else
|
||||
setRequestBody(new Object());
|
||||
}
|
||||
|
||||
private static class Request{
|
||||
public Boolean reblogs, notify;
|
||||
|
||||
public Request(Boolean reblogs, Boolean notify){
|
||||
this.reblogs=reblogs;
|
||||
this.notify=notify;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package org.joinmastodon.android.api.requests.accounts;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
|
||||
public class SetDomainBlocked extends MastodonAPIRequest<Object>{
|
||||
public SetDomainBlocked(String domain, boolean blocked){
|
||||
super(blocked ? HttpMethod.POST : HttpMethod.DELETE, "/domain_blocks", Object.class);
|
||||
setRequestBody(new Request(domain));
|
||||
}
|
||||
|
||||
private static class Request{
|
||||
public String domain;
|
||||
|
||||
public Request(String domain){
|
||||
this.domain=domain;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -39,6 +39,7 @@ import org.joinmastodon.android.api.requests.accounts.GetAccountByID;
|
|||
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
|
||||
import org.joinmastodon.android.api.requests.accounts.GetAccountStatuses;
|
||||
import org.joinmastodon.android.api.requests.accounts.GetOwnAccount;
|
||||
import org.joinmastodon.android.api.requests.accounts.SetAccountFollowed;
|
||||
import org.joinmastodon.android.api.requests.accounts.UpdateAccountCredentials;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.fragments.report.ReportReasonChoiceFragment;
|
||||
|
@ -479,14 +480,17 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
|||
if(relationship==null)
|
||||
return;
|
||||
inflater.inflate(R.menu.profile, menu);
|
||||
menu.findItem(R.id.share).setTitle(getString(R.string.share_user, account.displayName));
|
||||
menu.findItem(R.id.mute).setTitle(getString(relationship.muting ? R.string.unmute_user : R.string.mute_user, account.displayName));
|
||||
menu.findItem(R.id.block).setTitle(getString(relationship.blocking ? R.string.unblock_user : R.string.block_user, account.displayName));
|
||||
menu.findItem(R.id.report).setTitle(getString(R.string.report_user, account.displayName));
|
||||
// String domain=account.getDomain();
|
||||
// if(domain!=null)
|
||||
// menu.findItem(R.id.block_domain).setTitle(getString(relationship.domainBlocking ? R.string.unblock_domain : R.string.block_domain, domain));
|
||||
// else
|
||||
menu.findItem(R.id.share).setTitle(getString(R.string.share_user, account.getDisplayUsername()));
|
||||
menu.findItem(R.id.mute).setTitle(getString(relationship.muting ? R.string.unmute_user : R.string.mute_user, account.getDisplayUsername()));
|
||||
menu.findItem(R.id.block).setTitle(getString(relationship.blocking ? R.string.unblock_user : R.string.block_user, account.getDisplayUsername()));
|
||||
menu.findItem(R.id.report).setTitle(getString(R.string.report_user, account.getDisplayUsername()));
|
||||
if(relationship.following)
|
||||
menu.findItem(R.id.hide_boosts).setTitle(getString(relationship.showingReblogs ? R.string.hide_boosts_from_user : R.string.show_boosts_from_user, account.getDisplayUsername()));
|
||||
else
|
||||
menu.findItem(R.id.hide_boosts).setVisible(false);
|
||||
if(!account.isLocal())
|
||||
menu.findItem(R.id.block_domain).setTitle(getString(relationship.domainBlocking ? R.string.unblock_domain : R.string.block_domain, account.getDomain()));
|
||||
else
|
||||
menu.findItem(R.id.block_domain).setVisible(false);
|
||||
}
|
||||
|
||||
|
@ -507,6 +511,28 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
|||
args.putString("account", accountID);
|
||||
args.putParcelable("reportAccount", Parcels.wrap(account));
|
||||
Nav.go(getActivity(), ReportReasonChoiceFragment.class, args);
|
||||
}else if(id==R.id.open_in_browser){
|
||||
UiUtils.launchWebBrowser(getActivity(), account.url);
|
||||
}else if(id==R.id.block_domain){
|
||||
UiUtils.confirmToggleBlockDomain(getActivity(), accountID, account.getDomain(), relationship.domainBlocking, ()->{
|
||||
relationship.domainBlocking=!relationship.domainBlocking;
|
||||
updateRelationship();
|
||||
});
|
||||
}else if(id==R.id.hide_boosts){
|
||||
new SetAccountFollowed(account.id, true, !relationship.showingReblogs)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Relationship result){
|
||||
updateRelationship(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
error.showToast(getActivity());
|
||||
}
|
||||
})
|
||||
.wrapProgress(getActivity(), R.string.loading, false)
|
||||
.exec(accountID);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ public class ReportDoneFragment extends ToolbarFragment{
|
|||
}
|
||||
|
||||
private void onUnfollowClick(){
|
||||
new SetAccountFollowed(reportAccount.id, false)
|
||||
new SetAccountFollowed(reportAccount.id, false, false)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Relationship result){
|
||||
|
|
|
@ -160,6 +160,10 @@ public class Account extends BaseModel{
|
|||
return parts.length==1 ? null : parts[1];
|
||||
}
|
||||
|
||||
public String getDisplayUsername(){
|
||||
return '@'+acct;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "Account{"+
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.joinmastodon.android.ui.displayitems;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.drawable.Animatable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
@ -8,21 +9,25 @@ import android.os.Bundle;
|
|||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||
import org.joinmastodon.android.fragments.report.ReportReasonChoiceFragment;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Attachment;
|
||||
import org.joinmastodon.android.model.Relationship;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
||||
|
@ -30,8 +35,13 @@ import org.joinmastodon.android.ui.utils.UiUtils;
|
|||
import org.parceler.Parcels;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.api.APIRequest;
|
||||
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;
|
||||
|
@ -94,6 +104,9 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||
public static class Holder extends StatusDisplayItem.Holder<HeaderStatusDisplayItem> implements ImageLoaderViewHolder{
|
||||
private final TextView name, username, timestamp, extraText;
|
||||
private final ImageView avatar, more, visibility;
|
||||
private final PopupMenu optionsMenu;
|
||||
private Relationship relationship;
|
||||
private APIRequest<?> currentRelationshipRequest;
|
||||
|
||||
private static final ViewOutlineProvider roundCornersOutline=new ViewOutlineProvider(){
|
||||
@Override
|
||||
|
@ -116,6 +129,46 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||
avatar.setClipToOutline(true);
|
||||
more.setOnClickListener(this::onMoreClick);
|
||||
visibility.setOnClickListener(v->item.parentFragment.onVisibilityIconClick(this));
|
||||
|
||||
optionsMenu=new PopupMenu(activity, more);
|
||||
optionsMenu.inflate(R.menu.post);
|
||||
optionsMenu.setOnMenuItemClickListener(menuItem->{
|
||||
Account account=item.user;
|
||||
int id=menuItem.getItemId();
|
||||
if(id==R.id.delete){
|
||||
UiUtils.confirmDeletePost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, s->{});
|
||||
}else if(id==R.id.mute){
|
||||
UiUtils.confirmToggleMuteUser(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), account, relationship!=null && relationship.muting, r->{});
|
||||
}else if(id==R.id.block){
|
||||
UiUtils.confirmToggleBlockUser(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), account, relationship!=null && relationship.blocking, r->{});
|
||||
}else if(id==R.id.report){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", item.parentFragment.getAccountID());
|
||||
args.putParcelable("status", Parcels.wrap(item.status));
|
||||
args.putParcelable("reportAccount", Parcels.wrap(item.status.account));
|
||||
Nav.go(item.parentFragment.getActivity(), ReportReasonChoiceFragment.class, args);
|
||||
}else if(id==R.id.open_in_browser){
|
||||
UiUtils.launchWebBrowser(activity, item.status.url);
|
||||
}else if(id==R.id.follow){
|
||||
if(relationship==null)
|
||||
return true;
|
||||
ProgressDialog progress=new ProgressDialog(activity);
|
||||
progress.setCancelable(false);
|
||||
progress.setMessage(activity.getString(R.string.loading));
|
||||
UiUtils.performAccountAction(activity, account, item.parentFragment.getAccountID(), relationship, null, visible->{
|
||||
if(visible)
|
||||
progress.show();
|
||||
else
|
||||
progress.dismiss();
|
||||
}, rel->{
|
||||
relationship=rel;
|
||||
Toast.makeText(activity, activity.getString(rel.following ? R.string.followed_user : R.string.unfollowed_user, account.getDisplayUsername()), Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}else if(id==R.id.block_domain){
|
||||
UiUtils.confirmToggleBlockDomain(activity, item.parentFragment.getAccountID(), account.getDomain(), relationship!=null && relationship.domainBlocking, ()->{});
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -138,6 +191,10 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||
more.setVisibility(item.inset ? View.GONE : View.VISIBLE);
|
||||
avatar.setClickable(!item.inset);
|
||||
avatar.setContentDescription(item.parentFragment.getString(R.string.avatar_description, item.user.acct));
|
||||
if(currentRelationshipRequest!=null){
|
||||
currentRelationshipRequest.cancel();
|
||||
}
|
||||
relationship=null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -165,33 +222,61 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||
}
|
||||
|
||||
private void onMoreClick(View v){
|
||||
updateOptionsMenu();
|
||||
optionsMenu.show();
|
||||
if(relationship==null && currentRelationshipRequest==null){
|
||||
currentRelationshipRequest=new GetAccountRelationships(Collections.singletonList(item.user.id))
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(List<Relationship> result){
|
||||
if(!result.isEmpty()){
|
||||
relationship=result.get(0);
|
||||
updateOptionsMenu();
|
||||
}
|
||||
currentRelationshipRequest=null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
currentRelationshipRequest=null;
|
||||
}
|
||||
})
|
||||
.exec(item.parentFragment.getAccountID());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateOptionsMenu(){
|
||||
Account account=item.user;
|
||||
PopupMenu popup=new PopupMenu(v.getContext(), v);
|
||||
Menu menu=popup.getMenu();
|
||||
popup.getMenuInflater().inflate(R.menu.post, menu);
|
||||
if(item.status==null || !AccountSessionManager.getInstance().isSelf(item.parentFragment.getAccountID(), account))
|
||||
menu.findItem(R.id.delete).setVisible(false);
|
||||
menu.findItem(R.id.mute).setTitle(v.getResources().getString(/*relationship.muting ? R.string.unmute_user :*/ R.string.mute_user, account.displayName));
|
||||
menu.findItem(R.id.block).setTitle(v.getResources().getString(/*relationship.blocking ? R.string.unblock_user :*/ R.string.block_user, account.displayName));
|
||||
menu.findItem(R.id.report).setTitle(v.getResources().getString(R.string.report_user, account.displayName));
|
||||
popup.setOnMenuItemClickListener(menuItem->{
|
||||
int id=menuItem.getItemId();
|
||||
if(id==R.id.delete){
|
||||
UiUtils.confirmDeletePost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, s->{});
|
||||
}else if(id==R.id.mute){
|
||||
UiUtils.confirmToggleMuteUser(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), account, false, r->{});
|
||||
}else if(id==R.id.block){
|
||||
UiUtils.confirmToggleBlockUser(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), account, false, r->{});
|
||||
}else if(id==R.id.report){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", item.parentFragment.getAccountID());
|
||||
args.putParcelable("status", Parcels.wrap(item.status));
|
||||
args.putParcelable("reportAccount", Parcels.wrap(item.status.account));
|
||||
Nav.go(item.parentFragment.getActivity(), ReportReasonChoiceFragment.class, args);
|
||||
Menu menu=optionsMenu.getMenu();
|
||||
boolean isOwnPost=AccountSessionManager.getInstance().isSelf(item.parentFragment.getAccountID(), account);
|
||||
menu.findItem(R.id.delete).setVisible(item.status!=null && isOwnPost);
|
||||
MenuItem blockDomain=menu.findItem(R.id.block_domain);
|
||||
MenuItem mute=menu.findItem(R.id.mute);
|
||||
MenuItem block=menu.findItem(R.id.block);
|
||||
MenuItem report=menu.findItem(R.id.report);
|
||||
MenuItem follow=menu.findItem(R.id.follow);
|
||||
if(isOwnPost){
|
||||
mute.setVisible(false);
|
||||
block.setVisible(false);
|
||||
report.setVisible(false);
|
||||
follow.setVisible(false);
|
||||
blockDomain.setVisible(false);
|
||||
}else{
|
||||
mute.setVisible(true);
|
||||
block.setVisible(true);
|
||||
report.setVisible(true);
|
||||
follow.setVisible(relationship==null || relationship.following || (!relationship.blocking && !relationship.blockedBy && !relationship.domainBlocking && !relationship.muting));
|
||||
mute.setTitle(item.parentFragment.getString(relationship!=null && relationship.muting ? R.string.unmute_user : R.string.mute_user, account.getDisplayUsername()));
|
||||
block.setTitle(item.parentFragment.getString(relationship!=null && relationship.blocking ? R.string.unblock_user : R.string.block_user, account.getDisplayUsername()));
|
||||
report.setTitle(item.parentFragment.getString(R.string.report_user, account.getDisplayUsername()));
|
||||
if(!account.isLocal()){
|
||||
blockDomain.setVisible(true);
|
||||
blockDomain.setTitle(item.parentFragment.getString(relationship!=null && relationship.domainBlocking ? R.string.unblock_domain : R.string.block_domain, account.getDomain()));
|
||||
}else{
|
||||
blockDomain.setVisible(false);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
popup.show();
|
||||
follow.setTitle(item.parentFragment.getString(relationship!=null && relationship.following ? R.string.unfollow_user : R.string.follow_user, account.getDisplayUsername()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.joinmastodon.android.R;
|
|||
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.statuses.DeleteStatus;
|
||||
import org.joinmastodon.android.events.StatusDeletedEvent;
|
||||
import org.joinmastodon.android.fragments.HashtagTimelineFragment;
|
||||
|
@ -270,6 +271,27 @@ public class UiUtils{
|
|||
});
|
||||
}
|
||||
|
||||
public static void confirmToggleBlockDomain(Activity activity, String accountID, String domain, boolean currentlyBlocked, Runnable resultCallback){
|
||||
showConfirmationAlert(activity, activity.getString(currentlyBlocked ? R.string.confirm_unblock_domain_title : R.string.confirm_block_domain_title),
|
||||
activity.getString(currentlyBlocked ? R.string.confirm_unblock : R.string.confirm_block, domain),
|
||||
activity.getString(currentlyBlocked ? R.string.do_unblock : R.string.do_block), ()->{
|
||||
new SetDomainBlocked(domain, !currentlyBlocked)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Object result){
|
||||
resultCallback.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
error.showToast(activity);
|
||||
}
|
||||
})
|
||||
.wrapProgress(activity, R.string.loading, false)
|
||||
.exec(accountID);
|
||||
});
|
||||
}
|
||||
|
||||
public static void confirmToggleMuteUser(Activity activity, String accountID, Account account, boolean currentlyMuted, Consumer<Relationship> resultCallback){
|
||||
showConfirmationAlert(activity, activity.getString(currentlyMuted ? R.string.confirm_unmute_title : R.string.confirm_mute_title),
|
||||
activity.getString(currentlyMuted ? R.string.confirm_unmute : R.string.confirm_mute, account.displayName),
|
||||
|
@ -328,7 +350,7 @@ public class UiUtils{
|
|||
confirmToggleMuteUser(activity, accountID, account, true, resultCallback);
|
||||
}else{
|
||||
progressCallback.accept(true);
|
||||
new SetAccountFollowed(account.id, !relationship.following)
|
||||
new SetAccountFollowed(account.id, !relationship.following, true)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Relationship result){
|
||||
|
|
|
@ -3,5 +3,8 @@
|
|||
<item android:id="@+id/delete" android:title="@string/delete"/>
|
||||
<item android:id="@+id/mute" android:title="@string/mute_user"/>
|
||||
<item android:id="@+id/block" android:title="@string/block_user"/>
|
||||
<item android:id="@+id/block_domain" android:title="@string/block_domain"/>
|
||||
<item android:id="@+id/follow" android:title="@string/follow_user"/>
|
||||
<item android:id="@+id/report" android:title="@string/report_user"/>
|
||||
<item android:id="@+id/open_in_browser" android:title="@string/open_in_browser"/>
|
||||
</menu>
|
|
@ -5,4 +5,6 @@
|
|||
<item android:id="@+id/block" android:title="@string/block_user"/>
|
||||
<item android:id="@+id/report" android:title="@string/report_user"/>
|
||||
<item android:id="@+id/block_domain" android:title="@string/block_domain"/>
|
||||
<item android:id="@+id/hide_boosts" android:title="@string/hide_boosts_from_user"/>
|
||||
<item android:id="@+id/open_in_browser" android:title="@string/open_in_browser"/>
|
||||
</menu>
|
|
@ -114,9 +114,11 @@
|
|||
<string name="confirm_unmute">Confirm to unmute %s</string>
|
||||
<string name="do_unmute">Unmute</string>
|
||||
<string name="confirm_block_title">Block Account</string>
|
||||
<string name="confirm_block_domain_title">Block Domain</string>
|
||||
<string name="confirm_block">Confirm to block %s</string>
|
||||
<string name="do_block">Block</string>
|
||||
<string name="confirm_unblock_title">Unblock Account</string>
|
||||
<string name="confirm_unblock_domain_title">Unblock Domain</string>
|
||||
<string name="confirm_unblock">Confirm to unblock %s</string>
|
||||
<string name="do_unblock">Unblock</string>
|
||||
<string name="button_muted">Muted</string>
|
||||
|
@ -284,4 +286,10 @@
|
|||
<string name="home_timeline">Home timeline</string>
|
||||
<string name="my_profile">My profile</string>
|
||||
<string name="media_viewer">Media viewer</string>
|
||||
<string name="follow_user">Follow %s</string>
|
||||
<string name="unfollowed_user">Unfollowed %s</string>
|
||||
<string name="followed_user">You\'re now following %s</string>
|
||||
<string name="open_in_browser">Open in browser</string>
|
||||
<string name="hide_boosts_from_user">Hide boosts from %s</string>
|
||||
<string name="show_boosts_from_user">Show boosts from %s</string>
|
||||
</resources>
|
Loading…
Reference in New Issue