diff --git a/app/src/main/java/app/fedilab/android/activities/ComposeActivity.java b/app/src/main/java/app/fedilab/android/activities/ComposeActivity.java index fc3d8000..14ba600f 100644 --- a/app/src/main/java/app/fedilab/android/activities/ComposeActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/ComposeActivity.java @@ -149,6 +149,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana private ArrayList sharedUriList = new ArrayList<>(); private Uri sharedUri; private String sharedSubject, sharedContent, sharedTitle, sharedDescription, shareURL, sharedUrlMedia; + private String editMessageId; private static int visibilityToNumber(String visibility) { switch (visibility) { @@ -271,7 +272,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana statusList.addAll(0, context.ancestors); statusList.add(initialStatus); statusList.add(statusDraft.statusDraftList.get(0)); - composeAdapter = new ComposeAdapter(statusList, context.ancestors.size(), account, accountMention, visibility); + composeAdapter = new ComposeAdapter(statusList, context.ancestors.size(), account, accountMention, visibility, editMessageId); composeAdapter.manageDrafts = this; LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this); binding.recyclerView.setLayoutManager(mLayoutManager); @@ -487,6 +488,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana statusReplyId = b.getString(Helper.ARG_STATUS_REPLY_ID); statusMention = (Status) b.getSerializable(Helper.ARG_STATUS_MENTION); account = (BaseAccount) b.getSerializable(Helper.ARG_ACCOUNT); + editMessageId = b.getString(Helper.ARG_EDIT_STATUS_ID, null); instance = b.getString(Helper.ARG_INSTANCE, null); token = b.getString(Helper.ARG_TOKEN, null); visibility = b.getString(Helper.ARG_VISIBILITY, null); @@ -601,7 +603,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana } int statusCount = statusList.size(); statusList.addAll(statusDraft.statusDraftList); - composeAdapter = new ComposeAdapter(statusList, statusCount, account, accountMention, visibility); + composeAdapter = new ComposeAdapter(statusList, statusCount, account, accountMention, visibility, editMessageId); composeAdapter.manageDrafts = this; LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this); binding.recyclerView.setLayoutManager(mLayoutManager); @@ -652,7 +654,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana } //StatusDraftList at this point should only have one element statusList.addAll(statusDraftList); - composeAdapter = new ComposeAdapter(statusList, statusCount, account, accountMention, visibility); + composeAdapter = new ComposeAdapter(statusList, statusCount, account, accountMention, visibility, editMessageId); composeAdapter.manageDrafts = this; LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this); binding.recyclerView.setLayoutManager(mLayoutManager); @@ -662,7 +664,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana } else { //Compose without replying statusList.addAll(statusDraftList); - composeAdapter = new ComposeAdapter(statusList, 0, account, accountMention, visibility); + composeAdapter = new ComposeAdapter(statusList, 0, account, accountMention, visibility, editMessageId); composeAdapter.manageDrafts = this; LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this); binding.recyclerView.setLayoutManager(mLayoutManager); @@ -758,6 +760,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana private void storeDraft(boolean sendMessage, String scheduledDate) { new Thread(() -> { + //Collect all statusCompose List statusDrafts = new ArrayList<>(); List statusReplies = new ArrayList<>(); @@ -854,6 +857,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana .putString(Helper.ARG_STATUS_DRAFT_ID, String.valueOf(statusDraft.id)) .putString(Helper.ARG_INSTANCE, instance) .putString(Helper.ARG_TOKEN, token) + .putString(Helper.ARG_EDIT_STATUS_ID, editMessageId) .putString(Helper.ARG_USER_ID, account.user_id) .putString(Helper.ARG_SCHEDULED_DATE, scheduledDate).build(); OneTimeWorkRequest request = new OneTimeWorkRequest.Builder(ComposeWorker.class) @@ -863,7 +867,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana WorkManager.getInstance(ComposeActivity.this).enqueue(request); } else { - new ThreadMessageService(ComposeActivity.this, instance, account.user_id, token, statusDraft, scheduledDate); + new ThreadMessageService(ComposeActivity.this, instance, account.user_id, token, statusDraft, scheduledDate, editMessageId); } finish(); } diff --git a/app/src/main/java/app/fedilab/android/client/entities/api/Status.java b/app/src/main/java/app/fedilab/android/client/entities/api/Status.java index 1b2caea2..8a40c782 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/api/Status.java +++ b/app/src/main/java/app/fedilab/android/client/entities/api/Status.java @@ -113,6 +113,7 @@ public class Status implements Serializable, Cloneable { public transient boolean submitted = false; public transient boolean spoilerChecked = false; + public enum PositionFetchMore { TOP, BOTTOM diff --git a/app/src/main/java/app/fedilab/android/helper/Helper.java b/app/src/main/java/app/fedilab/android/helper/Helper.java index 5d45fca4..725c0bd5 100644 --- a/app/src/main/java/app/fedilab/android/helper/Helper.java +++ b/app/src/main/java/app/fedilab/android/helper/Helper.java @@ -218,6 +218,8 @@ public class Helper { public static final String ARG_STATUS_ACCOUNT_ID_DELETED = "ARG_STATUS_ACCOUNT_ID_DELETED"; public static final String ARG_STATUS_DRAFT = "ARG_STATUS_DRAFT"; + public static final String ARG_EDIT_STATUS_ID = "ARG_EDIT_STATUS_ID"; + public static final String ARG_STATUS_SCHEDULED = "ARG_STATUS_SCHEDULED"; public static final String ARG_SLUG_OF_FIRST_FRAGMENT = "ARG_SLUG_OF_FIRST_FRAGMENT"; diff --git a/app/src/main/java/app/fedilab/android/jobs/ComposeWorker.java b/app/src/main/java/app/fedilab/android/jobs/ComposeWorker.java index 50eca769..97041767 100644 --- a/app/src/main/java/app/fedilab/android/jobs/ComposeWorker.java +++ b/app/src/main/java/app/fedilab/android/jobs/ComposeWorker.java @@ -219,8 +219,13 @@ public class ComposeWorker extends Worker { } String language = sharedPreferences.getString(context.getString(R.string.SET_COMPOSE_LANGUAGE) + dataPost.userId + dataPost.instance, null); if (dataPost.scheduledDate == null) { - statusCall = mastodonStatusesService.createStatus(null, dataPost.token, statuses.get(i).text, attachmentIds, poll_options, poll_expire_in, - poll_multiple, poll_hide_totals, in_reply_to_status, statuses.get(i).sensitive, statuses.get(i).spoiler_text, statuses.get(i).visibility.toLowerCase(), language); + if (dataPost.statusEditId == null) { + statusCall = mastodonStatusesService.createStatus(null, dataPost.token, statuses.get(i).text, attachmentIds, poll_options, poll_expire_in, + poll_multiple, poll_hide_totals, in_reply_to_status, statuses.get(i).sensitive, statuses.get(i).spoiler_text, statuses.get(i).visibility.toLowerCase(), language); + } else { //Status is edited + statusCall = mastodonStatusesService.updateStatus(null, dataPost.token, dataPost.statusEditId, statuses.get(i).text, attachmentIds, poll_options, poll_expire_in, + poll_multiple, poll_hide_totals, in_reply_to_status, statuses.get(i).sensitive, statuses.get(i).spoiler_text, statuses.get(i).visibility.toLowerCase(), language); + } try { Response statusResponse = statusCall.execute(); if (statusResponse.isSuccessful()) { @@ -390,6 +395,7 @@ public class ComposeWorker extends Worker { String instance = inputData.getString(Helper.ARG_INSTANCE); String userId = inputData.getString(Helper.ARG_USER_ID); String scheduledDate = inputData.getString(Helper.ARG_SCHEDULED_DATE); + String editMessageId = inputData.getString(Helper.ARG_EDIT_STATUS_ID); //Should not be null, but a simple security if (token == null) { token = BaseMainActivity.currentToken; @@ -405,6 +411,7 @@ public class ComposeWorker extends Worker { dataPost.scheduledDate = scheduledDate; dataPost.notificationBuilder = notificationBuilder; dataPost.notificationManager = notificationManager; + dataPost.statusEditId = editMessageId; // Mark the Worker as important setForegroundAsync(createForegroundInfo()); publishMessage(getApplicationContext(), dataPost); @@ -469,6 +476,7 @@ public class ComposeWorker extends Worker { public String instance; public String token; public String userId; + public String statusEditId; public StatusDraft statusDraft; public int messageToSend; public int messageSent; diff --git a/app/src/main/java/app/fedilab/android/services/ThreadMessageService.java b/app/src/main/java/app/fedilab/android/services/ThreadMessageService.java index 39eb323a..9ec7469b 100644 --- a/app/src/main/java/app/fedilab/android/services/ThreadMessageService.java +++ b/app/src/main/java/app/fedilab/android/services/ThreadMessageService.java @@ -24,13 +24,14 @@ import app.fedilab.android.jobs.ComposeWorker; public class ThreadMessageService { - public ThreadMessageService(Context context, String instance, String userId, String token, StatusDraft statusDraft, String scheduledDate) { + public ThreadMessageService(Context context, String instance, String userId, String token, StatusDraft statusDraft, String scheduledDate, String editMessageId) { ComposeWorker.DataPost dataPost = new ComposeWorker.DataPost(); dataPost.instance = instance; dataPost.userId = userId; dataPost.token = token; dataPost.scheduledDate = scheduledDate; dataPost.statusDraft = statusDraft; + dataPost.statusEditId = editMessageId; publishMessage(context, dataPost); } } diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java index 635f628a..92fb144c 100644 --- a/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java +++ b/app/src/main/java/app/fedilab/android/ui/drawer/ComposeAdapter.java @@ -139,13 +139,15 @@ public class ComposeAdapter extends RecyclerView.Adapter emojisList = new ArrayList<>(); + private final String editMessageId; - public ComposeAdapter(List statusList, int statusCount, BaseAccount account, app.fedilab.android.client.entities.api.Account mentionedAccount, String visibility) { + public ComposeAdapter(List statusList, int statusCount, BaseAccount account, app.fedilab.android.client.entities.api.Account mentionedAccount, String visibility, String editMessageId) { this.statusList = statusList; this.statusCount = statusCount; this.account = account; this.mentionedAccount = mentionedAccount; this.visibility = visibility; + this.editMessageId = editMessageId; } @@ -334,7 +336,7 @@ public class ComposeAdapter extends RecyclerView.Adapter } else { popup.getMenu().findItem(R.id.action_pin).setVisible(false); popup.getMenu().findItem(R.id.action_redraft).setVisible(false); + popup.getMenu().findItem(R.id.action_edit).setVisible(false); popup.getMenu().findItem(R.id.action_remove).setVisible(false); if (statusToDeal.account.acct.split("@").length < 2) popup.getMenu().findItem(R.id.action_block_domain).setVisible(false); @@ -1712,6 +1713,25 @@ public class StatusAdapter extends RecyclerView.Adapter }); builderInner.setMessage(statusToDeal.text); builderInner.show(); + } else if (itemId == R.id.action_edit) { + statusesVM.getStatusSource(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id) + .observe((LifecycleOwner) context, statusSource -> { + if (statusSource != null) { + Intent intent = new Intent(context, ComposeActivity.class); + StatusDraft statusDraft = new StatusDraft(); + statusDraft.statusDraftList = new ArrayList<>(); + statusDraft.statusReplyList = new ArrayList<>(); + statusToDeal.text = statusSource.text; + statusToDeal.spoiler_text = statusSource.spoiler_text; + statusDraft.statusDraftList.add(statusToDeal); + intent.putExtra(Helper.ARG_STATUS_DRAFT, statusDraft); + intent.putExtra(Helper.ARG_EDIT_STATUS_ID, statusToDeal.id); + intent.putExtra(Helper.ARG_STATUS_REPLY_ID, statusToDeal.in_reply_to_id); + context.startActivity(intent); + } else { + Toasty.error(context, context.getString(R.string.toast_error), Toasty.LENGTH_SHORT).show(); + } + }); } else if (itemId == R.id.action_schedule_boost) { MastodonHelper.scheduleBoost(context, MastodonHelper.ScheduleType.BOOST, statusToDeal, null, null); } /*else if (itemId == R.id.action_admin) { diff --git a/app/src/main/java/app/fedilab/android/viewmodel/mastodon/StatusesVM.java b/app/src/main/java/app/fedilab/android/viewmodel/mastodon/StatusesVM.java index d0bd1838..e0c032c4 100644 --- a/app/src/main/java/app/fedilab/android/viewmodel/mastodon/StatusesVM.java +++ b/app/src/main/java/app/fedilab/android/viewmodel/mastodon/StatusesVM.java @@ -41,6 +41,7 @@ import app.fedilab.android.client.entities.api.Poll; import app.fedilab.android.client.entities.api.ScheduledStatus; import app.fedilab.android.client.entities.api.ScheduledStatuses; import app.fedilab.android.client.entities.api.Status; +import app.fedilab.android.client.entities.api.StatusSource; import app.fedilab.android.client.entities.app.BaseAccount; import app.fedilab.android.client.entities.app.StatusCache; import app.fedilab.android.client.entities.app.Timeline; @@ -63,6 +64,7 @@ public class StatusesVM extends AndroidViewModel { private MutableLiveData statusMutableLiveData; + private MutableLiveData statusSourceMutableLiveData; private MutableLiveData scheduledStatusMutableLiveData; private MutableLiveData scheduledStatusesMutableLiveData; private MutableLiveData voidMutableLiveData; @@ -298,6 +300,39 @@ public class StatusesVM extends AndroidViewModel { return statusMutableLiveData; } + + /** + * Get a status source by ID + * + * @param instance Instance domain of the active account + * @param token Access token of the active account + * @param id String - id of the status + * @return LiveData + */ + public LiveData getStatusSource(@NonNull String instance, String token, String id) { + MastodonStatusesService mastodonStatusesService = init(instance); + statusSourceMutableLiveData = new MutableLiveData<>(); + new Thread(() -> { + Call statusSourceCall = mastodonStatusesService.getStatusSource(token, id); + StatusSource statusSource = null; + if (statusSourceCall != null) { + try { + Response statusResponse = statusSourceCall.execute(); + if (statusResponse.isSuccessful()) { + statusSource = statusResponse.body(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + Handler mainHandler = new Handler(Looper.getMainLooper()); + StatusSource finalStatusSource = statusSource; + Runnable myRunnable = () -> statusSourceMutableLiveData.setValue(finalStatusSource); + mainHandler.post(myRunnable); + }).start(); + return statusSourceMutableLiveData; + } + /** * Delete a status by ID * diff --git a/app/src/main/res/menu/option_toot.xml b/app/src/main/res/menu/option_toot.xml index 5a3b3dd8..bb67f133 100644 --- a/app/src/main/res/menu/option_toot.xml +++ b/app/src/main/res/menu/option_toot.xml @@ -9,6 +9,10 @@ android:id="@+id/action_bookmark" android:title="@string/bookmark_add" app:showAsAction="never" /> + The message has been pinned Translate messages Force translation to a specific language. Choose first value to reset to device settings + Edit message