Merge branch 'feature/delete-redraft' into fork
This commit is contained in:
@@ -27,7 +27,6 @@ import android.text.Layout;
|
|||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.text.format.DateUtils;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -196,19 +195,12 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
private boolean attachmentsErrorShowing;
|
private boolean attachmentsErrorShowing;
|
||||||
|
|
||||||
private Status editingStatus;
|
private Status editingStatus;
|
||||||
|
private boolean redraftStatus;
|
||||||
private boolean pollChanged;
|
private boolean pollChanged;
|
||||||
private boolean creatingView;
|
private boolean creatingView;
|
||||||
private boolean ignoreSelectionChanges=false;
|
private boolean ignoreSelectionChanges=false;
|
||||||
private Runnable updateUploadEtaRunnable;
|
private Runnable updateUploadEtaRunnable;
|
||||||
|
|
||||||
public static DraftMediaAttachment redraftAttachment(Attachment att) {
|
|
||||||
DraftMediaAttachment draft=new DraftMediaAttachment();
|
|
||||||
draft.serverAttachment=att;
|
|
||||||
draft.description=att.description;
|
|
||||||
draft.uri=Uri.parse(att.url);
|
|
||||||
return draft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState){
|
public void onCreate(Bundle savedInstanceState){
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -222,6 +214,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
instance=AccountSessionManager.getInstance().getInstanceInfo(instanceDomain);
|
instance=AccountSessionManager.getInstance().getInstanceInfo(instanceDomain);
|
||||||
if(getArguments().containsKey("editStatus")){
|
if(getArguments().containsKey("editStatus")){
|
||||||
editingStatus=Parcels.unwrap(getArguments().getParcelable("editStatus"));
|
editingStatus=Parcels.unwrap(getArguments().getParcelable("editStatus"));
|
||||||
|
redraftStatus=getArguments().getBoolean("redraftStatus");
|
||||||
}
|
}
|
||||||
if(instance==null){
|
if(instance==null){
|
||||||
Nav.finish(this);
|
Nav.finish(this);
|
||||||
@@ -328,18 +321,11 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
pollDurationView.setOnClickListener(v->showPollDurationMenu());
|
pollDurationView.setOnClickListener(v->showPollDurationMenu());
|
||||||
|
|
||||||
pollOptions.clear();
|
pollOptions.clear();
|
||||||
ArrayList<String> restoredPollOptions=(savedInstanceState!=null ? savedInstanceState : getArguments())
|
if(savedInstanceState!=null && savedInstanceState.containsKey("pollOptions")){
|
||||||
.getStringArrayList("pollOptions");
|
|
||||||
if(restoredPollOptions!=null){
|
|
||||||
if(savedInstanceState==null){
|
|
||||||
// restoring from arguments
|
|
||||||
pollDuration=getArguments().getInt("pollDuration");
|
|
||||||
pollDurationStr=DateUtils.formatElapsedTime(pollDuration); // getResources().getQuantityString(R.plurals.x_hours, pollDuration/3600);
|
|
||||||
}
|
|
||||||
pollBtn.setSelected(true);
|
pollBtn.setSelected(true);
|
||||||
mediaBtn.setEnabled(false);
|
mediaBtn.setEnabled(false);
|
||||||
pollWrap.setVisibility(View.VISIBLE);
|
pollWrap.setVisibility(View.VISIBLE);
|
||||||
for(String oldText:restoredPollOptions){
|
for(String oldText:savedInstanceState.getStringArrayList("pollOptions")){
|
||||||
DraftPollOption opt=createDraftPollOption();
|
DraftPollOption opt=createDraftPollOption();
|
||||||
opt.edit.setText(oldText);
|
opt.edit.setText(oldText);
|
||||||
}
|
}
|
||||||
@@ -374,13 +360,8 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
spoilerBtn.setSelected(true);
|
spoilerBtn.setSelected(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
sensitive = editingStatus != null ? editingStatus.sensitive
|
if(savedInstanceState!=null && savedInstanceState.containsKey("attachments")){
|
||||||
: (savedInstanceState != null && savedInstanceState.getBoolean("sensitive", false));
|
ArrayList<Parcelable> serializedAttachments=savedInstanceState.getParcelableArrayList("attachments");
|
||||||
sensitiveIcon.setSelected(sensitive);
|
|
||||||
|
|
||||||
ArrayList<Parcelable> serializedAttachments=(savedInstanceState!=null ? savedInstanceState : getArguments())
|
|
||||||
.getParcelableArrayList("attachments");
|
|
||||||
if(serializedAttachments!=null){
|
|
||||||
for(Parcelable a:serializedAttachments){
|
for(Parcelable a:serializedAttachments){
|
||||||
DraftMediaAttachment att=Parcels.unwrap(a);
|
DraftMediaAttachment att=Parcels.unwrap(a);
|
||||||
attachmentsView.addView(createMediaAttachmentView(att));
|
attachmentsView.addView(createMediaAttachmentView(att));
|
||||||
@@ -540,7 +521,8 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
spoilerBtn.setSelected(true);
|
spoilerBtn.setSelected(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else if (editingStatus==null || editingStatus.inReplyToId==null){
|
||||||
|
// TODO: remove workaround after https://github.com/mastodon/mastodon-android/issues/341 gets fixed
|
||||||
replyText.setVisibility(View.GONE);
|
replyText.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
if(savedInstanceState==null){
|
if(savedInstanceState==null){
|
||||||
@@ -592,7 +574,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
|
||||||
publishButton=new Button(getActivity());
|
publishButton=new Button(getActivity());
|
||||||
publishButton.setText(editingStatus==null ? R.string.publish : R.string.save);
|
publishButton.setText(editingStatus==null || redraftStatus ? R.string.publish : R.string.save);
|
||||||
publishButton.setOnClickListener(this::onPublishClick);
|
publishButton.setOnClickListener(this::onPublishClick);
|
||||||
LinearLayout wrap=new LinearLayout(getActivity());
|
LinearLayout wrap=new LinearLayout(getActivity());
|
||||||
wrap.setOrientation(LinearLayout.HORIZONTAL);
|
wrap.setOrientation(LinearLayout.HORIZONTAL);
|
||||||
@@ -697,8 +679,8 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
if(!attachments.isEmpty()){
|
if(!attachments.isEmpty()){
|
||||||
req.mediaIds=attachments.stream().map(a->a.serverAttachment.id).collect(Collectors.toList());
|
req.mediaIds=attachments.stream().map(a->a.serverAttachment.id).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
if(replyTo!=null){
|
if(replyTo!=null || editingStatus.inReplyToId!=null){
|
||||||
req.inReplyToId=replyTo.id;
|
req.inReplyToId=editingStatus!=null ? editingStatus.inReplyToId : replyTo.id;
|
||||||
}
|
}
|
||||||
if(!pollOptions.isEmpty()){
|
if(!pollOptions.isEmpty()){
|
||||||
req.poll=new CreateStatus.Request.Poll();
|
req.poll=new CreateStatus.Request.Poll();
|
||||||
@@ -741,6 +723,13 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
E.post(new StatusUpdatedEvent(result));
|
E.post(new StatusUpdatedEvent(result));
|
||||||
}
|
}
|
||||||
Nav.finish(ComposeFragment.this);
|
Nav.finish(ComposeFragment.this);
|
||||||
|
if (getArguments().getBoolean("navigateToStatus", false)) {
|
||||||
|
Bundle args=new Bundle();
|
||||||
|
args.putString("account", accountID);
|
||||||
|
args.putParcelable("status", Parcels.wrap(result));
|
||||||
|
if(replyTo!=null) args.putParcelable("inReplyToAccount", Parcels.wrap(replyTo));
|
||||||
|
Nav.go(getActivity(), ThreadFragment.class, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -754,7 +743,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if(editingStatus!=null){
|
if(editingStatus!=null && !redraftStatus){
|
||||||
new EditStatus(req, editingStatus.id)
|
new EditStatus(req, editingStatus.id)
|
||||||
.setCallback(resCallback)
|
.setCallback(resCallback)
|
||||||
.exec(accountID);
|
.exec(accountID);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import org.joinmastodon.android.api.session.AccountSessionManager;
|
|||||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||||
import org.joinmastodon.android.fragments.ComposeFragment;
|
import org.joinmastodon.android.fragments.ComposeFragment;
|
||||||
import org.joinmastodon.android.fragments.ProfileFragment;
|
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||||
|
import org.joinmastodon.android.fragments.ThreadFragment;
|
||||||
import org.joinmastodon.android.fragments.report.ReportReasonChoiceFragment;
|
import org.joinmastodon.android.fragments.report.ReportReasonChoiceFragment;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
import org.joinmastodon.android.model.Attachment;
|
import org.joinmastodon.android.model.Attachment;
|
||||||
@@ -137,10 +138,18 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
optionsMenu.setOnMenuItemClickListener(menuItem->{
|
optionsMenu.setOnMenuItemClickListener(menuItem->{
|
||||||
Account account=item.user;
|
Account account=item.user;
|
||||||
int id=menuItem.getItemId();
|
int id=menuItem.getItemId();
|
||||||
if(id==R.id.edit){
|
if(id==R.id.edit || id==R.id.delete_and_redraft) {
|
||||||
final Bundle args=new Bundle();
|
final Bundle args=new Bundle();
|
||||||
args.putString("account", item.parentFragment.getAccountID());
|
args.putString("account", item.parentFragment.getAccountID());
|
||||||
args.putParcelable("editStatus", Parcels.wrap(item.status));
|
args.putParcelable("editStatus", Parcels.wrap(item.status));
|
||||||
|
if (id==R.id.delete_and_redraft) {
|
||||||
|
args.putBoolean("redraftStatus", true);
|
||||||
|
if (item.parentFragment instanceof ThreadFragment thread && !thread.isItemEnabled(item.status.id)) {
|
||||||
|
// ("enabled" = clickable; opened status is not clickable)
|
||||||
|
// request navigation to the re-drafted status if status is currently opened
|
||||||
|
args.putBoolean("navigateToStatus", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
if(TextUtils.isEmpty(item.status.content) && TextUtils.isEmpty(item.status.spoilerText)){
|
if(TextUtils.isEmpty(item.status.content) && TextUtils.isEmpty(item.status.spoilerText)){
|
||||||
Nav.go(item.parentFragment.getActivity(), ComposeFragment.class, args);
|
Nav.go(item.parentFragment.getActivity(), ComposeFragment.class, args);
|
||||||
}else{
|
}else{
|
||||||
@@ -150,7 +159,13 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
public void onSuccess(GetStatusSourceText.Response result){
|
public void onSuccess(GetStatusSourceText.Response result){
|
||||||
args.putString("sourceText", result.text);
|
args.putString("sourceText", result.text);
|
||||||
args.putString("sourceSpoiler", result.spoilerText);
|
args.putString("sourceSpoiler", result.spoilerText);
|
||||||
Nav.go(item.parentFragment.getActivity(), ComposeFragment.class, args);
|
if (id==R.id.delete_and_redraft) {
|
||||||
|
UiUtils.confirmDeletePost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, s->{
|
||||||
|
Nav.go(item.parentFragment.getActivity(), ComposeFragment.class, args);
|
||||||
|
}, true);
|
||||||
|
} else {
|
||||||
|
Nav.go(item.parentFragment.getActivity(), ComposeFragment.class, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -163,8 +178,6 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
}
|
}
|
||||||
}else if(id==R.id.delete){
|
}else if(id==R.id.delete){
|
||||||
UiUtils.confirmDeletePost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, s->{});
|
UiUtils.confirmDeletePost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, s->{});
|
||||||
}else if(id==R.id.delete_and_redraft) {
|
|
||||||
UiUtils.confirmDeleteAndRedraftPost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, s->{});
|
|
||||||
}else if(id==R.id.pin || id==R.id.unpin){
|
}else if(id==R.id.pin || id==R.id.unpin){
|
||||||
UiUtils.confirmPinPost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, !item.status.pinned, s->{});
|
UiUtils.confirmPinPost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, !item.status.pinned, s->{});
|
||||||
}else if(id==R.id.mute){
|
}else if(id==R.id.mute){
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import android.os.Build;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Parcelable;
|
|
||||||
import android.provider.OpenableColumns;
|
import android.provider.OpenableColumns;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
@@ -58,10 +57,8 @@ import org.joinmastodon.android.model.Emoji;
|
|||||||
import org.joinmastodon.android.model.ListTimeline;
|
import org.joinmastodon.android.model.ListTimeline;
|
||||||
import org.joinmastodon.android.model.Relationship;
|
import org.joinmastodon.android.model.Relationship;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
import org.joinmastodon.android.model.StatusPrivacy;
|
|
||||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||||
import org.joinmastodon.android.ui.text.CustomEmojiSpan;
|
import org.joinmastodon.android.ui.text.CustomEmojiSpan;
|
||||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
|
||||||
import org.joinmastodon.android.ui.text.SpacerSpan;
|
import org.joinmastodon.android.ui.text.SpacerSpan;
|
||||||
import org.parceler.Parcels;
|
import org.parceler.Parcels;
|
||||||
|
|
||||||
@@ -72,8 +69,6 @@ import java.time.ZoneId;
|
|||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.FormatStyle;
|
import java.time.format.FormatStyle;
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -87,10 +82,6 @@ import androidx.annotation.StringRes;
|
|||||||
import androidx.browser.customtabs.CustomTabsIntent;
|
import androidx.browser.customtabs.CustomTabsIntent;
|
||||||
import androidx.recyclerview.widget.DiffUtil;
|
import androidx.recyclerview.widget.DiffUtil;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
import me.grishka.appkit.Nav;
|
import me.grishka.appkit.Nav;
|
||||||
import me.grishka.appkit.api.Callback;
|
import me.grishka.appkit.api.Callback;
|
||||||
import me.grishka.appkit.api.ErrorResponse;
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
@@ -403,9 +394,12 @@ public class UiUtils{
|
|||||||
.exec(accountID);
|
.exec(accountID);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void confirmDeletePost(Activity activity, String accountID, Status status, Consumer<Status> resultCallback){
|
public static void confirmDeletePost(Activity activity, String accountID, Status status, Consumer<Status> resultCallback){
|
||||||
showConfirmationAlert(activity, R.string.confirm_delete_title, R.string.confirm_delete, R.string.delete, ()->{
|
confirmDeletePost(activity, accountID, status, resultCallback, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void confirmDeletePost(Activity activity, String accountID, Status status, Consumer<Status> resultCallback, boolean forRedraft){
|
||||||
|
showConfirmationAlert(activity, forRedraft ? R.string.confirm_delete_and_redraft_title : R.string.confirm_delete_title, forRedraft ? R.string.confirm_delete_and_redraft : R.string.confirm_delete, forRedraft ? R.string.delete_and_redraft : R.string.delete, ()->{
|
||||||
new DeleteStatus(status.id)
|
new DeleteStatus(status.id)
|
||||||
.setCallback(new Callback<>(){
|
.setCallback(new Callback<>(){
|
||||||
@Override
|
@Override
|
||||||
@@ -452,61 +446,6 @@ public class UiUtils{
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void confirmDeleteAndRedraftPost(Activity activity, String accountID, Status status, Consumer<Status> resultCallback){
|
|
||||||
showConfirmationAlert(activity, R.string.confirm_delete_and_redraft_title, R.string.confirm_delete_and_redraft, R.string.delete_and_redraft, ()->{
|
|
||||||
new DeleteStatus(status.id)
|
|
||||||
.setCallback(new Callback<>(){
|
|
||||||
@Override
|
|
||||||
public void onSuccess(Status result){
|
|
||||||
resultCallback.accept(result);
|
|
||||||
AccountSessionManager.getInstance().getAccount(accountID).getCacheController().deleteStatus(status.id);
|
|
||||||
E.post(new StatusDeletedEvent(status.id, accountID));
|
|
||||||
UiUtils.redraftStatus(status, accountID, activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(ErrorResponse error){
|
|
||||||
error.showToast(activity);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.wrapProgress(activity, R.string.deleting, false)
|
|
||||||
.exec(accountID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void redraftStatus(Status status, String accountID, Activity activity) {
|
|
||||||
Bundle args=new Bundle();
|
|
||||||
args.putString("account", accountID);
|
|
||||||
args.putBoolean("hasDraft", true);
|
|
||||||
args.putString("prefilledText", HtmlParser.parse(status.content, status.emojis, status.mentions, status.tags, accountID).toString());
|
|
||||||
args.putString("spoilerText", status.spoilerText);
|
|
||||||
args.putSerializable("visibility", status.visibility);
|
|
||||||
if(status.poll!=null){
|
|
||||||
args.putInt("pollDuration", (int)status.poll.expiresAt.minus(status.createdAt.getEpochSecond(), ChronoUnit.SECONDS).getEpochSecond());
|
|
||||||
ArrayList<String> opts=status.poll.options.stream().map(o -> o.title).collect(Collectors.toCollection(ArrayList::new));
|
|
||||||
args.putStringArrayList("pollOptions", opts);
|
|
||||||
}
|
|
||||||
if(!status.mediaAttachments.isEmpty()){
|
|
||||||
ArrayList<Parcelable> serializedAttachments=status.mediaAttachments.stream()
|
|
||||||
.map(att -> Parcels.wrap(ComposeFragment.redraftAttachment(att)))
|
|
||||||
.collect(Collectors.toCollection(ArrayList::new));
|
|
||||||
args.putParcelableArrayList("attachments", serializedAttachments);
|
|
||||||
}
|
|
||||||
Callback<Status> cb=new Callback<>(){
|
|
||||||
@Override public void onError(ErrorResponse error) {
|
|
||||||
onSuccess(null);
|
|
||||||
error.showToast(activity);
|
|
||||||
}
|
|
||||||
@Override public void onSuccess(Status status) {
|
|
||||||
if (status!=null) args.putParcelable("replyTo", Parcels.wrap(status));
|
|
||||||
Nav.go(activity, ComposeFragment.class, args);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if(status.inReplyToId!=null) new GetStatusByID(status.inReplyToId).setCallback(cb).exec(accountID);
|
|
||||||
else cb.onSuccess(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setRelationshipToActionButton(Relationship relationship, Button button){
|
public static void setRelationshipToActionButton(Relationship relationship, Button button){
|
||||||
setRelationshipToActionButton(relationship, button, false);
|
setRelationshipToActionButton(relationship, button, false);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user