added status edit support
This commit is contained in:
parent
05102cbc9c
commit
9f2ab52964
|
@ -417,8 +417,9 @@ public interface Connection {
|
|||
*
|
||||
* @param update status update information
|
||||
* @param mediaIds IDs of the uploaded media files if any
|
||||
* @return uploaded status
|
||||
*/
|
||||
void uploadStatus(StatusUpdate update, long[] mediaIds) throws ConnectionException;
|
||||
Status uploadStatus(StatusUpdate update, long[] mediaIds) throws ConnectionException;
|
||||
|
||||
/**
|
||||
* create userlist
|
||||
|
|
|
@ -593,7 +593,7 @@ public class Mastodon implements Connection {
|
|||
|
||||
|
||||
@Override
|
||||
public void uploadStatus(StatusUpdate update, long[] mediaIds) throws MastodonException {
|
||||
public Status uploadStatus(StatusUpdate update, long[] mediaIds) throws MastodonException {
|
||||
List<String> params = new ArrayList<>();
|
||||
// add identifier to prevent duplicate posts
|
||||
params.add("Idempotency-Key=" + System.currentTimeMillis() / 5000);
|
||||
|
@ -625,10 +625,15 @@ public class Mastodon implements Connection {
|
|||
params.add("poll[hide_totals]=" + poll.hideTotalVotes());
|
||||
}
|
||||
try {
|
||||
Response response = post(ENDPOINT_STATUS, params);
|
||||
if (response.code() != 200) {
|
||||
throw new MastodonException(response);
|
||||
Response response;
|
||||
if (update.statusExists())
|
||||
response = put(ENDPOINT_STATUS + update.getStatusId(), params);
|
||||
else
|
||||
response = post(ENDPOINT_STATUS, params);
|
||||
if (response.code() == 200) {
|
||||
return createStatus(response);
|
||||
}
|
||||
throw new MastodonException(response);
|
||||
} catch (IOException e) {
|
||||
throw new MastodonException(e);
|
||||
}
|
||||
|
|
|
@ -722,7 +722,7 @@ public class TwitterV1 implements Connection {
|
|||
|
||||
|
||||
@Override
|
||||
public void uploadStatus(StatusUpdate update, long[] mediaIds) throws TwitterException {
|
||||
public Status uploadStatus(StatusUpdate update, long[] mediaIds) throws TwitterException {
|
||||
List<String> params = new ArrayList<>();
|
||||
if (update.getText() != null)
|
||||
params.add("status=" + StringUtils.encode(update.getText()));
|
||||
|
@ -743,7 +743,7 @@ public class TwitterV1 implements Connection {
|
|||
params.add("lat=" + StringUtils.encode(lat));
|
||||
params.add("long=" + StringUtils.encode(lon));
|
||||
}
|
||||
getTweet(TWEET_UPLOAD, params);
|
||||
return getTweet(TWEET_UPLOAD, params);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.nuclearfog.twidda.backend.api.ConnectionException;
|
|||
import org.nuclearfog.twidda.backend.api.ConnectionManager;
|
||||
import org.nuclearfog.twidda.backend.helper.MediaStatus;
|
||||
import org.nuclearfog.twidda.backend.helper.StatusUpdate;
|
||||
import org.nuclearfog.twidda.model.Status;
|
||||
import org.nuclearfog.twidda.ui.activities.StatusEditor;
|
||||
|
||||
/**
|
||||
|
@ -41,16 +42,16 @@ public class StatusUpdater extends AsyncExecutor<StatusUpdate, StatusUpdater.Sta
|
|||
mediaIds[pos] = connection.uploadMedia(mediaUpdates[pos]);
|
||||
}
|
||||
// upload status
|
||||
connection.uploadStatus(update, mediaIds);
|
||||
return new StatusUpdateResult(true, null);
|
||||
Status status = connection.uploadStatus(update, mediaIds);
|
||||
return new StatusUpdateResult(status, null);
|
||||
} catch (ConnectionException exception) {
|
||||
return new StatusUpdateResult(false, exception);
|
||||
return new StatusUpdateResult(null, exception);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
update.close();
|
||||
}
|
||||
return new StatusUpdateResult(false, null);
|
||||
return new StatusUpdateResult(null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,12 +59,13 @@ public class StatusUpdater extends AsyncExecutor<StatusUpdate, StatusUpdater.Sta
|
|||
*/
|
||||
public static class StatusUpdateResult {
|
||||
|
||||
public final boolean success;
|
||||
@Nullable
|
||||
public final Status status;
|
||||
@Nullable
|
||||
public final ConnectionException exception;
|
||||
|
||||
StatusUpdateResult(boolean success, @Nullable ConnectionException exception) {
|
||||
this.success = success;
|
||||
StatusUpdateResult(@Nullable Status status, @Nullable ConnectionException exception) {
|
||||
this.status = status;
|
||||
this.exception = exception;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,25 +63,51 @@ public class StatusUpdate implements Serializable {
|
|||
private static final String MIME_IMAGE_ALL = "image/";
|
||||
private static final String MIME_VIDEO_ALL = "video/";
|
||||
|
||||
|
||||
private long replyId;
|
||||
@Nullable
|
||||
// main attributes
|
||||
private long statusId = 0L;
|
||||
private long replyId = 0L;
|
||||
private boolean sensitive = false;
|
||||
private boolean spoiler = false;
|
||||
private int visibility = Status.VISIBLE_PUBLIC;
|
||||
private String text;
|
||||
|
||||
// attachment attributes
|
||||
@Nullable
|
||||
private PollUpdate poll;
|
||||
@Nullable
|
||||
private LocationUpdate location;
|
||||
private MediaStatus[] mediaUpdates = {};
|
||||
private int attachment = EMPTY;
|
||||
|
||||
// helper attributes
|
||||
@Nullable
|
||||
private Instance instance;
|
||||
|
||||
private List<String> mediaUriStrings = new ArrayList<>(5);
|
||||
private Set<String> supportedFormats = new TreeSet<>();
|
||||
private MediaStatus[] mediaUpdates = {};
|
||||
private boolean attachmentLimitReached = false;
|
||||
private boolean sensitive = false;
|
||||
private boolean spoiler = false;
|
||||
private int visibility = Status.VISIBLE_PUBLIC;
|
||||
private int attachment = EMPTY;
|
||||
|
||||
/**
|
||||
* set existing status to edit
|
||||
*
|
||||
* @param status existing status
|
||||
*/
|
||||
public void setStatus(Status status) {
|
||||
statusId = status.getId();
|
||||
replyId = status.getRepliedStatusId();
|
||||
text = status.getText();
|
||||
sensitive = status.isSensitive();
|
||||
spoiler = status.isSpoiler();
|
||||
visibility = status.getVisibility();
|
||||
}
|
||||
|
||||
/**
|
||||
* to edit an existing status, the ID can added
|
||||
*
|
||||
* @param statusId ID of an existing status to edit
|
||||
*/
|
||||
public void addStatusId(long statusId) {
|
||||
this.statusId = statusId;
|
||||
}
|
||||
|
||||
/**
|
||||
* set ID of the replied status
|
||||
|
@ -226,6 +252,22 @@ public class StatusUpdate implements Serializable {
|
|||
this.instance = instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true to edit an existing status {@link #statusId} must be set
|
||||
*/
|
||||
public boolean statusExists() {
|
||||
return statusId != 0L;
|
||||
}
|
||||
|
||||
/**
|
||||
* get ID of an existing status to edit
|
||||
*
|
||||
* @return status ID or '0' to post a new status instead of edit
|
||||
*/
|
||||
public long getStatusId() {
|
||||
return statusId;
|
||||
}
|
||||
|
||||
/**
|
||||
* get ID of the replied status
|
||||
*
|
||||
|
|
|
@ -46,6 +46,7 @@ public enum Configuration {
|
|||
private final boolean statusVisibilitySupported;
|
||||
private final boolean directMessageSupported;
|
||||
private final boolean emojiSupported;
|
||||
private final boolean statusEditSupported;
|
||||
private final int arrayResHome;
|
||||
|
||||
/**
|
||||
|
@ -69,6 +70,7 @@ public enum Configuration {
|
|||
statusVisibilitySupported = false;
|
||||
directMessageSupported = true;
|
||||
emojiSupported = false;
|
||||
statusEditSupported = false;
|
||||
arrayResHome = R.array.home_twitter_icons;
|
||||
break;
|
||||
|
||||
|
@ -87,6 +89,7 @@ public enum Configuration {
|
|||
statusVisibilitySupported = true;
|
||||
directMessageSupported = false;
|
||||
emojiSupported = true;
|
||||
statusEditSupported = true;
|
||||
arrayResHome = R.array.home_mastodon_icons;
|
||||
break;
|
||||
}
|
||||
|
@ -190,6 +193,13 @@ public enum Configuration {
|
|||
return emojiSupported;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if status edit is supported
|
||||
*/
|
||||
public boolean isStatusEditSupported() {
|
||||
return statusEditSupported;
|
||||
}
|
||||
|
||||
/**
|
||||
* get home tabitems drawable IDs
|
||||
*
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.nuclearfog.twidda.ui.activities;
|
|||
|
||||
import static org.nuclearfog.twidda.ui.activities.SearchActivity.KEY_SEARCH_QUERY;
|
||||
import static org.nuclearfog.twidda.ui.activities.StatusEditor.KEY_STATUS_EDITOR_DATA;
|
||||
import static org.nuclearfog.twidda.ui.activities.StatusEditor.KEY_STATUS_EDITOR_EDIT;
|
||||
import static org.nuclearfog.twidda.ui.activities.UsersActivity.KEY_USERS_ID;
|
||||
import static org.nuclearfog.twidda.ui.activities.UsersActivity.KEY_USERS_MODE;
|
||||
import static org.nuclearfog.twidda.ui.activities.UsersActivity.USERS_FAVORIT;
|
||||
|
@ -33,6 +34,10 @@ import android.widget.ImageView;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.result.ActivityResult;
|
||||
import androidx.activity.result.ActivityResultCallback;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
@ -102,7 +107,7 @@ import jp.wasabeef.picasso.transformations.RoundedCornersTransformation;
|
|||
* @author nuclearfog
|
||||
*/
|
||||
public class StatusActivity extends AppCompatActivity implements OnClickListener, OnLongClickListener, OnTagClickListener,
|
||||
OnConfirmListener, OnCardClickListener, OnScrollChangeListener, LockCallback {
|
||||
OnConfirmListener, OnCardClickListener, OnScrollChangeListener, LockCallback, ActivityResultCallback<ActivityResult> {
|
||||
|
||||
/**
|
||||
* Activity result code to update existing status information
|
||||
|
@ -194,6 +199,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
|
|||
*/
|
||||
private static final int MENU_GROUP_COPY = 0x157426;
|
||||
|
||||
private ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), this);
|
||||
private AsyncCallback<StatusResult> statusCallback = this::onStatusResult;
|
||||
private AsyncCallback<PollActionResult> pollResult = this::onPollResult;
|
||||
private AsyncCallback<TranslationResult> translationResult = this::onTranslationResult;
|
||||
|
@ -439,6 +445,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
|
|||
MenuItem optCopy = m.findItem(R.id.menu_status_copy);
|
||||
MenuItem optMetrics = m.findItem(R.id.menu_status_metrics);
|
||||
MenuItem menuBookmark = m.findItem(R.id.menu_status_bookmark);
|
||||
MenuItem editStatus = m.findItem(R.id.menu_status_edit);
|
||||
SubMenu copyMenu = optCopy.getSubMenu();
|
||||
|
||||
// set status options
|
||||
|
@ -462,6 +469,9 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
|
|||
// enable/disable status hide option
|
||||
if (currentStatus.getAuthor().isCurrentUser()) {
|
||||
optDelete.setVisible(true);
|
||||
if (settings.getLogin().getConfiguration().isStatusEditSupported()) {
|
||||
editStatus.setVisible(true);
|
||||
}
|
||||
}
|
||||
// enable/disable status metrics option
|
||||
if (currentStatus.getMetrics() != null) {
|
||||
|
@ -496,7 +506,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
|
|||
return true;
|
||||
}
|
||||
// add/remove bookmark
|
||||
if (item.getItemId() == R.id.menu_status_bookmark) {
|
||||
else if (item.getItemId() == R.id.menu_status_bookmark) {
|
||||
Toast.makeText(getApplicationContext(), R.string.info_loading, Toast.LENGTH_SHORT).show();
|
||||
int mode = status.isBookmarked() ? StatusParam.UNBOOKMARK : StatusParam.BOOKMARK;
|
||||
StatusParam param = new StatusParam(mode, status.getId());
|
||||
|
@ -557,10 +567,28 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
|
|||
}
|
||||
return true;
|
||||
}
|
||||
// edit status
|
||||
else if (item.getItemId() == R.id.menu_status_edit) {
|
||||
Intent intent = new Intent(this, StatusEditor.class);
|
||||
intent.putExtra(KEY_STATUS_EDITOR_DATA, status);
|
||||
intent.putExtra(KEY_STATUS_EDITOR_EDIT, true);
|
||||
activityResultLauncher.launch(intent);
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onActivityResult(ActivityResult result) {
|
||||
if (result.getData() != null && result.getResultCode() == StatusEditor.RETURN_STATUS_UPDATE) {
|
||||
Serializable data = result.getData().getSerializableExtra(StatusEditor.RETURN_STATUS_DATA);
|
||||
if (data instanceof Status) {
|
||||
setStatus((Status) data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (status != null) {
|
||||
|
@ -835,7 +863,6 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
|
|||
} else {
|
||||
statusApi.setVisibility(View.GONE);
|
||||
}
|
||||
if (statusText.getText().length() == 0) {
|
||||
if (!status.getText().isEmpty()) {
|
||||
spannableText = Tagger.makeTextWithLinks(status.getText(), settings.getHighlightColor(), this);
|
||||
statusText.setVisibility(View.VISIBLE);
|
||||
|
@ -843,7 +870,6 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
|
|||
} else {
|
||||
statusText.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
if (status.getRepliedStatusId() > 0) {
|
||||
if (!status.getReplyName().isEmpty())
|
||||
replyName.setText(status.getReplyName());
|
||||
|
|
|
@ -55,18 +55,35 @@ import java.io.Serializable;
|
|||
public class StatusEditor extends MediaActivity implements OnClickListener, OnProgressStopListener, OnConfirmListener,
|
||||
OnMediaClickListener, TextWatcher, PollUpdateCallback, OnEmojiSelectListener {
|
||||
|
||||
/**
|
||||
* return code used to send status information to calling activity
|
||||
*/
|
||||
public static final int RETURN_STATUS_UPDATE = 0x30220;
|
||||
|
||||
/**
|
||||
* key to add the status to reply
|
||||
* value type is {@link Status}
|
||||
*/
|
||||
public static final String KEY_STATUS_EDITOR_DATA = "status_data";
|
||||
|
||||
/**
|
||||
* key to edit an existing status
|
||||
* value type is Boolean
|
||||
*/
|
||||
public static final String KEY_STATUS_EDITOR_EDIT = "status_edit";
|
||||
|
||||
/**
|
||||
* key for the text added to the status if any
|
||||
* value type is String
|
||||
*/
|
||||
public static final String KEY_STATUS_EDITOR_TEXT = "status_text";
|
||||
|
||||
/**
|
||||
* key to return uploaded status information
|
||||
* value type is {@link Status}
|
||||
*/
|
||||
public static final String RETURN_STATUS_DATA = "status_update";
|
||||
|
||||
/**
|
||||
* key for status update to restore
|
||||
* value type is {@link StatusUpdate}
|
||||
|
@ -103,8 +120,8 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
|
|||
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle b) {
|
||||
super.onCreate(b);
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.popup_status);
|
||||
ViewGroup root = findViewById(R.id.popup_status_root);
|
||||
ImageView background = findViewById(R.id.popup_status_background);
|
||||
|
@ -134,21 +151,33 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
|
|||
if (!settings.getLogin().getConfiguration().isEmojiSupported()) {
|
||||
emojiButton.setVisibility(View.GONE);
|
||||
}
|
||||
long replyId = 0L;
|
||||
String prefix;
|
||||
Serializable serializedStatus = getIntent().getSerializableExtra(KEY_STATUS_EDITOR_DATA);
|
||||
if (serializedStatus instanceof Status) {
|
||||
// fetch parameters
|
||||
if (savedInstanceState == null)
|
||||
savedInstanceState = getIntent().getExtras();
|
||||
if (savedInstanceState != null) {
|
||||
Serializable serializedStatus = savedInstanceState.getSerializable(KEY_STATUS_EDITOR_DATA);
|
||||
Serializable serializedStatusUpdate = savedInstanceState.getSerializable(KEY_STATUS_UPDATE);
|
||||
boolean editStatus = savedInstanceState.getBoolean(KEY_STATUS_EDITOR_EDIT, false);
|
||||
String prefix = savedInstanceState.getString(KEY_STATUS_EDITOR_TEXT);
|
||||
if (serializedStatusUpdate instanceof StatusUpdate) {
|
||||
statusUpdate = (StatusUpdate) serializedStatusUpdate;
|
||||
} else if (serializedStatus instanceof Status) {
|
||||
Status status = (Status) serializedStatus;
|
||||
replyId = status.getId();
|
||||
statusUpdate.setVisibility(status.getVisibility());
|
||||
prefix = status.getUserMentions();
|
||||
if (editStatus) {
|
||||
statusUpdate.setStatus(status);
|
||||
statusText.append(status.getText());
|
||||
} else {
|
||||
prefix = getIntent().getStringExtra(KEY_STATUS_EDITOR_TEXT);
|
||||
statusUpdate.addStatusId(status.getId());
|
||||
statusUpdate.addReplyStatusId(status.getId());
|
||||
statusUpdate.setVisibility(status.getVisibility());
|
||||
statusUpdate.addText(status.getUserMentions());
|
||||
statusText.append(status.getUserMentions());
|
||||
}
|
||||
statusUpdate.addReplyStatusId(replyId);
|
||||
if (prefix != null) {
|
||||
} else {
|
||||
statusUpdate.addText(prefix);
|
||||
statusText.append(prefix);
|
||||
}
|
||||
}
|
||||
adapter = new IconAdapter(settings, true);
|
||||
adapter.addOnMediaClickListener(this);
|
||||
iconList.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, true));
|
||||
|
@ -192,16 +221,6 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
Serializable serializedStatusUpdate = savedInstanceState.getSerializable(KEY_STATUS_UPDATE);
|
||||
if (serializedStatusUpdate instanceof StatusUpdate) {
|
||||
statusUpdate = (StatusUpdate) serializedStatusUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
showClosingMsg();
|
||||
|
@ -399,7 +418,10 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
|
|||
* called when the status was successfully updated
|
||||
*/
|
||||
private void onStatusUpdated(@NonNull StatusUpdateResult result) {
|
||||
if (result.success) {
|
||||
if (result.status != null) {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(RETURN_STATUS_DATA, result.status);
|
||||
setResult(RETURN_STATUS_UPDATE, intent);
|
||||
Toast.makeText(getApplicationContext(), R.string.info_status_sent, Toast.LENGTH_LONG).show();
|
||||
finish();
|
||||
} else {
|
||||
|
|
|
@ -34,6 +34,11 @@
|
|||
android:title="@string/menu_status_hide"
|
||||
android:visible="false" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_status_edit"
|
||||
android:title="@string/menu_status_edit"
|
||||
android:visible="false" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_status_delete"
|
||||
android:title="@string/menu_status_delete"
|
||||
|
|
|
@ -130,6 +130,7 @@
|
|||
<string name="menu_bookmark_remove">remove bookmark</string>
|
||||
<string name="menu_unmute_user">unmute</string>
|
||||
<string name="menu_follow_requested">follow requested</string>
|
||||
<string name="menu_status_edit">edit</string>
|
||||
<string name="menu_status_delete">delete</string>
|
||||
<string name="menu_status_hide">hide</string>
|
||||
<string name="menu_status_metrics">Metrics</string>
|
||||
|
|
Loading…
Reference in New Issue