allow to edit outgoing text messages

This commit is contained in:
adbenitez 2025-02-20 01:07:23 +01:00
parent c94f9371fe
commit d1737cb69f
5 changed files with 72 additions and 15 deletions

View file

@ -189,6 +189,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private boolean isDefaultSms = true; private boolean isDefaultSms = true;
private boolean isSecurityInitialized = false; private boolean isSecurityInitialized = false;
private boolean successfulForwardingAttempt = false; private boolean successfulForwardingAttempt = false;
private boolean isEditing = false;
@Override @Override
protected void onCreate(Bundle state, boolean ready) { protected void onCreate(Bundle state, boolean ready) {
@ -489,13 +490,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
Log.e(TAG, "cannot set up in-chat-search: ", e); Log.e(TAG, "cannot set up in-chat-search: ", e);
} }
if (!dcChat.canSend()) {
MenuItem attachItem = menu.findItem(R.id.menu_add_attachment);
if (attachItem!=null) {
attachItem.setVisible(false);
}
}
super.onPrepareOptionsMenu(menu); super.onPrepareOptionsMenu(menu);
return true; return true;
} }
@ -504,10 +498,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item); super.onOptionsItemSelected(item);
int itemId = item.getItemId(); int itemId = item.getItemId();
if (itemId == R.id.menu_add_attachment) { if (itemId == R.id.menu_leave) {
handleAddAttachment();
return true;
} else if (itemId == R.id.menu_leave) {
handleLeaveGroup(); handleLeaveGroup();
return true; return true;
} else if (itemId == R.id.menu_archive_chat) { } else if (itemId == R.id.menu_archive_chat) {
@ -731,6 +722,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
* @return * @return
*/ */
private ListenableFuture<Boolean> initializeDraft() { private ListenableFuture<Boolean> initializeDraft() {
isEditing = false;
final SettableFuture<Boolean> future = new SettableFuture<>(); final SettableFuture<Boolean> future = new SettableFuture<>();
DcMsg draft = dcContext.getDraft(chatId); DcMsg draft = dcContext.getDraft(chatId);
final String sharedText = RelayUtil.getSharedText(this); final String sharedText = RelayUtil.getSharedText(this);
@ -1016,6 +1008,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
DcMsg msg = null; DcMsg msg = null;
Optional<QuoteModel> quote = inputPanel.getQuote(); Optional<QuoteModel> quote = inputPanel.getQuote();
Integer recompress = 0; Integer recompress = 0;
boolean editing = isEditing;
// for a quick ui feedback, we clear the related controls immediately on sending messages. // for a quick ui feedback, we clear the related controls immediately on sending messages.
// for drafts, however, we do not change the controls, the activity may be resumed. // for drafts, however, we do not change the controls, the activity may be resumed.
@ -1024,6 +1017,18 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
inputPanel.clearQuote(); inputPanel.clearQuote();
} }
if (editing) {
int msgId = quote.get().getQuotedMsg().getId();
Util.runOnAnyBackgroundThread(() -> {
if (action == ACTION_SEND_OUT) {
dcContext.sendEditRequest(msgId, body);
} else {
dcContext.setDraft(chatId, null);
}
});
return future;
}
if(slideDeck!=null) { if(slideDeck!=null) {
if (action==ACTION_SEND_OUT) { if (action==ACTION_SEND_OUT) {
@ -1162,7 +1167,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
return; return;
} }
if (composeText.getText().length() == 0 && !attachmentManager.isAttachmentPresent()) { if (!isEditing && composeText.getText().length() == 0 && !attachmentManager.isAttachmentPresent()) {
buttonToggle.display(attachButton); buttonToggle.display(attachButton);
quickAttachmentToggle.show(); quickAttachmentToggle.show();
} else { } else {
@ -1280,9 +1285,16 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
} }
} }
@Override
public void onQuoteDismissed() {
isEditing = false;
composeText.setText("");
}
// media selected by the system keyboard // media selected by the system keyboard
@Override @Override
public void onMediaSelected(@NonNull Uri uri, String contentType) { public void onMediaSelected(@NonNull Uri uri, String contentType) {
if (isEditing) return;
if (MediaUtil.isImageType(contentType)) { if (MediaUtil.isImageType(contentType)) {
sendSticker(uri, contentType); sendSticker(uri, contentType);
} else if (MediaUtil.isVideoType(contentType)) { } else if (MediaUtil.isVideoType(contentType)) {
@ -1433,6 +1445,25 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
inputPanel.clickOnComposeInput(); inputPanel.clickOnComposeInput();
} }
@Override
public void handleEditMessage(DcMsg msg) {
isEditing = true;
Recipient author = new Recipient(this, dcContext.getContact(msg.getFromId()));
SlideDeck slideDeck = new SlideDeck();
String text = msg.getSummarytext(500);
inputPanel.setQuote(GlideApp.with(this),
msg,
msg.getTimestamp(),
author,
text,
slideDeck);
setDraftText(msg.getText());
inputPanel.clickOnComposeInput();
}
@Override @Override
public void onAttachmentChanged() { public void onAttachmentChanged() {
handleSecurityChange(isSecureText, isDefaultSms); handleSecurityChange(isSecureText, isDefaultSms);

View file

@ -324,6 +324,7 @@ public class ConversationFragment extends MessageSelectorFragment
menu.findItem(R.id.menu_context_details).setVisible(false); menu.findItem(R.id.menu_context_details).setVisible(false);
menu.findItem(R.id.menu_context_share).setVisible(false); menu.findItem(R.id.menu_context_share).setVisible(false);
menu.findItem(R.id.menu_context_reply).setVisible(false); menu.findItem(R.id.menu_context_reply).setVisible(false);
menu.findItem(R.id.menu_context_edit).setVisible(false);
menu.findItem(R.id.menu_context_reply_privately).setVisible(false); menu.findItem(R.id.menu_context_reply_privately).setVisible(false);
menu.findItem(R.id.menu_add_to_home_screen).setVisible(false); menu.findItem(R.id.menu_add_to_home_screen).setVisible(false);
} else { } else {
@ -333,6 +334,8 @@ public class ConversationFragment extends MessageSelectorFragment
menu.findItem(R.id.menu_context_share).setVisible(messageRecord.hasFile()); menu.findItem(R.id.menu_context_share).setVisible(messageRecord.hasFile());
boolean canReply = canReplyToMsg(messageRecord); boolean canReply = canReplyToMsg(messageRecord);
menu.findItem(R.id.menu_context_reply).setVisible(chat.canSend() && canReply); menu.findItem(R.id.menu_context_reply).setVisible(chat.canSend() && canReply);
boolean canEdit = canEditMsg(messageRecord);
menu.findItem(R.id.menu_context_edit).setVisible(chat.canSend() && canEdit);
boolean showReplyPrivately = chat.isMultiUser() && !messageRecord.isOutgoing() && canReply; boolean showReplyPrivately = chat.isMultiUser() && !messageRecord.isOutgoing() && canReply;
menu.findItem(R.id.menu_context_reply_privately).setVisible(showReplyPrivately); menu.findItem(R.id.menu_context_reply_privately).setVisible(showReplyPrivately);
menu.findItem(R.id.menu_add_to_home_screen).setVisible(messageRecord.getType() == DcMsg.DC_MSG_WEBXDC); menu.findItem(R.id.menu_add_to_home_screen).setVisible(messageRecord.getType() == DcMsg.DC_MSG_WEBXDC);
@ -361,6 +364,10 @@ public class ConversationFragment extends MessageSelectorFragment
return !dcMsg.isInfo() && dcMsg.getType() != DcMsg.DC_MSG_VIDEOCHAT_INVITATION; return !dcMsg.isInfo() && dcMsg.getType() != DcMsg.DC_MSG_VIDEOCHAT_INVITATION;
} }
static boolean canEditMsg(DcMsg dcMsg) {
return dcMsg.isOutgoing() && !dcMsg.isInfo() && dcMsg.getType() == DcMsg.DC_MSG_TEXT;
}
public void handleClearChat() { public void handleClearChat() {
handleDeleteMessages((int) chatId, getListAdapter().getMessageIds()); handleDeleteMessages((int) chatId, getListAdapter().getMessageIds());
} }
@ -461,6 +468,16 @@ public class ConversationFragment extends MessageSelectorFragment
listener.handleReplyMessage(message); listener.handleReplyMessage(message);
} }
@SuppressLint("RestrictedApi")
private void handleEditMessage(final DcMsg message) {
if (getActivity() != null) {
//noinspection ConstantConditions
((AppCompatActivity) getActivity()).getSupportActionBar().collapseActionView();
}
listener.handleEditMessage(message);
}
private void handleReplyMessagePrivately(final DcMsg msg) { private void handleReplyMessagePrivately(final DcMsg msg) {
if (getActivity() != null) { if (getActivity() != null) {
@ -591,6 +608,7 @@ public class ConversationFragment extends MessageSelectorFragment
public interface ConversationFragmentListener { public interface ConversationFragmentListener {
void handleReplyMessage(DcMsg messageRecord); void handleReplyMessage(DcMsg messageRecord);
void handleEditMessage(DcMsg messageRecord);
} }
private class ConversationScrollListener extends OnScrollListener { private class ConversationScrollListener extends OnScrollListener {
@ -958,6 +976,10 @@ public class ConversationFragment extends MessageSelectorFragment
handleReplyMessage(getSelectedMessageRecord(getListAdapter().getSelectedItems())); handleReplyMessage(getSelectedMessageRecord(getListAdapter().getSelectedItems()));
actionMode.finish(); actionMode.finish();
return true; return true;
} else if (itemId == R.id.menu_context_edit) {
handleEditMessage(getSelectedMessageRecord(getListAdapter().getSelectedItems()));
actionMode.finish();
return true;
} else if (itemId == R.id.menu_context_reply_privately) { } else if (itemId == R.id.menu_context_reply_privately) {
handleReplyMessagePrivately(getSelectedMessageRecord(getListAdapter().getSelectedItems())); handleReplyMessagePrivately(getSelectedMessageRecord(getListAdapter().getSelectedItems()));
return true; return true;

View file

@ -141,6 +141,7 @@ public class InputPanel extends ConstraintLayout
public void clearQuoteWithoutAnimation() { public void clearQuoteWithoutAnimation() {
quoteView.dismiss(); quoteView.dismiss();
if (listener != null) listener.onQuoteDismissed();
} }
public void clearQuote() { public void clearQuote() {
@ -152,6 +153,7 @@ public class InputPanel extends ConstraintLayout
@Override @Override
public void onAnimationEnd(@NonNull Animator animation) { public void onAnimationEnd(@NonNull Animator animation) {
quoteView.dismiss(); quoteView.dismiss();
if (listener != null) listener.onQuoteDismissed();
} }
}); });
@ -329,6 +331,7 @@ public class InputPanel extends ConstraintLayout
void onRecorderCanceled(); void onRecorderCanceled();
void onRecorderPermissionRequired(); void onRecorderPermissionRequired();
void onEmojiToggle(); void onEmojiToggle();
void onQuoteDismissed();
} }
private static class SlideToCancel { private static class SlideToCancel {

View file

@ -41,9 +41,6 @@
<item android:title="@string/menu_more_options"> <item android:title="@string/menu_more_options">
<menu> <menu>
<item android:title="@string/menu_add_attachment"
android:id="@+id/menu_add_attachment" />
<item android:id="@+id/menu_leave" <item android:id="@+id/menu_leave"
android:visible="false" android:visible="false"
android:title="@string/menu_leave_group"/> android:title="@string/menu_leave_group"/>

View file

@ -44,6 +44,10 @@
android:id="@+id/menu_context_reply_privately" android:id="@+id/menu_context_reply_privately"
app:showAsAction="never" /> app:showAsAction="never" />
<item android:title="@string/global_menu_edit_desktop"
android:id="@+id/menu_context_edit"
app:showAsAction="never" />
<item android:title="@string/resend" <item android:title="@string/resend"
android:id="@+id/menu_resend" android:id="@+id/menu_resend"
app:showAsAction="never" /> app:showAsAction="never" />