Send attachments in order
Not perfect. It means we lose paralellism of uploads which is maybe bad? If any one errors the subsequent ones stay queued I think. If you're offline or similar then it all gets written to the db and we stil lose ordering. May still be worth it, worth testing. (cherry picked from commit 0683b065f5a99d214e343fa92aa468b62e1cada8)
This commit is contained in:
parent
1b57462cdb
commit
2d76569b9f
5 changed files with 116 additions and 87 deletions
src/main/java/eu/siacs/conversations
|
@ -111,6 +111,10 @@ public class HttpConnectionManager extends AbstractConnectionManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createNewUploadConnection(final Message message, boolean delay) {
|
public void createNewUploadConnection(final Message message, boolean delay) {
|
||||||
|
createNewUploadConnection(message, delay, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createNewUploadConnection(final Message message, boolean delay, final Runnable cb) {
|
||||||
synchronized (this.uploadConnections) {
|
synchronized (this.uploadConnections) {
|
||||||
for (HttpUploadConnection connection : this.uploadConnections) {
|
for (HttpUploadConnection connection : this.uploadConnections) {
|
||||||
if (connection.getMessage() == message) {
|
if (connection.getMessage() == message) {
|
||||||
|
@ -118,7 +122,7 @@ public class HttpConnectionManager extends AbstractConnectionManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HttpUploadConnection connection = new HttpUploadConnection(message, Method.determine(message.getConversation().getAccount()), this);
|
HttpUploadConnection connection = new HttpUploadConnection(message, Method.determine(message.getConversation().getAccount()), this, cb);
|
||||||
connection.init(delay);
|
connection.init(delay);
|
||||||
this.uploadConnections.add(connection);
|
this.uploadConnections.add(connection);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,12 +52,14 @@ public class HttpUploadConnection implements Transferable, AbstractConnectionMan
|
||||||
private long transmitted = 0;
|
private long transmitted = 0;
|
||||||
private Call mostRecentCall;
|
private Call mostRecentCall;
|
||||||
private ListenableFuture<SlotRequester.Slot> slotFuture;
|
private ListenableFuture<SlotRequester.Slot> slotFuture;
|
||||||
|
private Runnable cb;
|
||||||
|
|
||||||
public HttpUploadConnection(Message message, Method method, HttpConnectionManager httpConnectionManager) {
|
public HttpUploadConnection(Message message, Method method, HttpConnectionManager httpConnectionManager, Runnable cb) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.mHttpConnectionManager = httpConnectionManager;
|
this.mHttpConnectionManager = httpConnectionManager;
|
||||||
this.mXmppConnectionService = httpConnectionManager.getXmppConnectionService();
|
this.mXmppConnectionService = httpConnectionManager.getXmppConnectionService();
|
||||||
|
this.cb = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -104,6 +106,7 @@ public class HttpUploadConnection implements Transferable, AbstractConnectionMan
|
||||||
final Future<SlotRequester.Slot> slotFuture = this.slotFuture;
|
final Future<SlotRequester.Slot> slotFuture = this.slotFuture;
|
||||||
final boolean cancelled = (call != null && call.isCanceled()) || (slotFuture != null && slotFuture.isCancelled());
|
final boolean cancelled = (call != null && call.isCanceled()) || (slotFuture != null && slotFuture.isCancelled());
|
||||||
mXmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED, cancelled ? Message.ERROR_MESSAGE_CANCELLED : errorMessage);
|
mXmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED, cancelled ? Message.ERROR_MESSAGE_CANCELLED : errorMessage);
|
||||||
|
if (cb != null) cb.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void finish() {
|
private void finish() {
|
||||||
|
@ -191,7 +194,7 @@ public class HttpUploadConnection implements Transferable, AbstractConnectionMan
|
||||||
if (!message.isPrivateMessage()) {
|
if (!message.isPrivateMessage()) {
|
||||||
message.setCounterpart(message.getConversation().getJid().asBareJid());
|
message.setCounterpart(message.getConversation().getJid().asBareJid());
|
||||||
}
|
}
|
||||||
mXmppConnectionService.resendMessage(message, delayed);
|
mXmppConnectionService.resendMessage(message, delayed, cb);
|
||||||
} else {
|
} else {
|
||||||
Log.d(Config.LOGTAG, "http upload failed because response code was " + code);
|
Log.d(Config.LOGTAG, "http upload failed because response code was " + code);
|
||||||
fail("http upload failed because response code was " + code);
|
fail("http upload failed because response code was " + code);
|
||||||
|
|
|
@ -63,8 +63,7 @@ public class AttachFileToConversationRunnable implements Runnable, TranscoderLis
|
||||||
final int encryption = message.getEncryption();
|
final int encryption = message.getEncryption();
|
||||||
mXmppConnectionService.getHttpConnectionManager().createNewDownloadConnection(message, false, (file) -> {
|
mXmppConnectionService.getHttpConnectionManager().createNewDownloadConnection(message, false, (file) -> {
|
||||||
message.setEncryption(encryption);
|
message.setEncryption(encryption);
|
||||||
mXmppConnectionService.sendMessage(message);
|
mXmppConnectionService.sendMessage(message, () -> callback.success(message));
|
||||||
callback.success(message);
|
|
||||||
});
|
});
|
||||||
} else if (path != null && !FileBackend.isPathBlacklisted(path)) {
|
} else if (path != null && !FileBackend.isPathBlacklisted(path)) {
|
||||||
message.setRelativeFilePath(path);
|
message.setRelativeFilePath(path);
|
||||||
|
@ -72,8 +71,7 @@ public class AttachFileToConversationRunnable implements Runnable, TranscoderLis
|
||||||
if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
|
if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
|
||||||
mXmppConnectionService.getPgpEngine().encrypt(message, callback);
|
mXmppConnectionService.getPgpEngine().encrypt(message, callback);
|
||||||
} else {
|
} else {
|
||||||
mXmppConnectionService.sendMessage(message);
|
mXmppConnectionService.sendMessage(message, () -> callback.success(message));
|
||||||
callback.success(message);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
|
@ -87,8 +85,7 @@ public class AttachFileToConversationRunnable implements Runnable, TranscoderLis
|
||||||
callback.error(R.string.unable_to_connect_to_keychain, null);
|
callback.error(R.string.unable_to_connect_to_keychain, null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mXmppConnectionService.sendMessage(message);
|
mXmppConnectionService.sendMessage(message, () -> callback.success(message));
|
||||||
callback.success(message);
|
|
||||||
}
|
}
|
||||||
} catch (FileBackend.FileCopyException e) {
|
} catch (FileBackend.FileCopyException e) {
|
||||||
callback.error(e.getResId(), message);
|
callback.error(e.getResId(), message);
|
||||||
|
@ -163,8 +160,7 @@ public class AttachFileToConversationRunnable implements Runnable, TranscoderLis
|
||||||
if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
|
if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
|
||||||
mXmppConnectionService.getPgpEngine().encrypt(message, callback);
|
mXmppConnectionService.getPgpEngine().encrypt(message, callback);
|
||||||
} else {
|
} else {
|
||||||
mXmppConnectionService.sendMessage(message);
|
mXmppConnectionService.sendMessage(message, () -> callback.success(message));
|
||||||
callback.success(message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -747,8 +747,7 @@ public class XmppConnectionService extends Service {
|
||||||
callback.error(R.string.unable_to_connect_to_keychain, null);
|
callback.error(R.string.unable_to_connect_to_keychain, null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sendMessage(message);
|
sendMessage(message, false, false, false, () -> callback.success(message));
|
||||||
callback.success(message);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1912,22 +1911,27 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendFileMessage(final Message message, final boolean delay) {
|
private void sendFileMessage(final Message message, final boolean delay, final Runnable cb) {
|
||||||
Log.d(Config.LOGTAG, "send file message");
|
Log.d(Config.LOGTAG, "send file message");
|
||||||
final Account account = message.getConversation().getAccount();
|
final Account account = message.getConversation().getAccount();
|
||||||
if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize())
|
if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize())
|
||||||
|| message.getConversation().getMode() == Conversation.MODE_MULTI) {
|
|| message.getConversation().getMode() == Conversation.MODE_MULTI) {
|
||||||
mHttpConnectionManager.createNewUploadConnection(message, delay);
|
mHttpConnectionManager.createNewUploadConnection(message, delay, cb);
|
||||||
} else {
|
} else {
|
||||||
mJingleConnectionManager.startJingleFileTransfer(message);
|
mJingleConnectionManager.startJingleFileTransfer(message);
|
||||||
|
if (cb != null) cb.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(final Message message) {
|
public void sendMessage(final Message message) {
|
||||||
sendMessage(message, false, false, false);
|
sendMessage(message, false, false, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendMessage(final Message message, final boolean resend, final boolean previewedLinks, final boolean delay) {
|
public void sendMessage(final Message message, final Runnable cb) {
|
||||||
|
sendMessage(message, false, false, false, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMessage(final Message message, final boolean resend, final boolean previewedLinks, final boolean delay, final Runnable cb) {
|
||||||
final Account account = message.getConversation().getAccount();
|
final Account account = message.getConversation().getAccount();
|
||||||
if (account.setShowErrorNotification(true)) {
|
if (account.setShowErrorNotification(true)) {
|
||||||
databaseBackend.updateAccount(account);
|
databaseBackend.updateAccount(account);
|
||||||
|
@ -1936,7 +1940,6 @@ public class XmppConnectionService extends Service {
|
||||||
final Conversation conversation = (Conversation) message.getConversation();
|
final Conversation conversation = (Conversation) message.getConversation();
|
||||||
account.deactivateGracePeriod();
|
account.deactivateGracePeriod();
|
||||||
|
|
||||||
|
|
||||||
if (QuickConversationsService.isQuicksy() && conversation.getMode() == Conversation.MODE_SINGLE) {
|
if (QuickConversationsService.isQuicksy() && conversation.getMode() == Conversation.MODE_SINGLE) {
|
||||||
final Contact contact = conversation.getContact();
|
final Contact contact = conversation.getContact();
|
||||||
if (!contact.showInRoster() && contact.getOption(Contact.Options.SYNCED_VIA_OTHER)) {
|
if (!contact.showInRoster() && contact.getOption(Contact.Options.SYNCED_VIA_OTHER)) {
|
||||||
|
@ -2014,7 +2017,7 @@ public class XmppConnectionService extends Service {
|
||||||
getHttpConnectionManager().createNewDownloadConnection(message, false, (file) -> {
|
getHttpConnectionManager().createNewDownloadConnection(message, false, (file) -> {
|
||||||
message.setEncryption(encryption);
|
message.setEncryption(encryption);
|
||||||
synchronized (message.getConversation()) {
|
synchronized (message.getConversation()) {
|
||||||
if (message.getStatus() == Message.STATUS_WAITING) sendMessage(message, true, true, false);
|
if (message.getStatus() == Message.STATUS_WAITING) sendMessage(message, true, true, false, cb);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
@ -2068,13 +2071,14 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
synchronized (message.getConversation()) {
|
synchronized (message.getConversation()) {
|
||||||
if (message.getStatus() == Message.STATUS_WAITING) sendMessage(message, true, true, false);
|
if (message.getStatus() == Message.STATUS_WAITING) sendMessage(message, true, true, false, cb);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean passedCbOn = false;
|
||||||
if (account.isOnlineAndConnected() && !inProgressJoin && !waitForPreview && message.getTimeSent() <= System.currentTimeMillis()) {
|
if (account.isOnlineAndConnected() && !inProgressJoin && !waitForPreview && message.getTimeSent() <= System.currentTimeMillis()) {
|
||||||
switch (message.getEncryption()) {
|
switch (message.getEncryption()) {
|
||||||
case Message.ENCRYPTION_NONE:
|
case Message.ENCRYPTION_NONE:
|
||||||
|
@ -2082,7 +2086,8 @@ public class XmppConnectionService extends Service {
|
||||||
if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize())
|
if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize())
|
||||||
|| conversation.getMode() == Conversation.MODE_MULTI
|
|| conversation.getMode() == Conversation.MODE_MULTI
|
||||||
|| message.fixCounterpart()) {
|
|| message.fixCounterpart()) {
|
||||||
this.sendFileMessage(message, delay);
|
this.sendFileMessage(message, delay, cb);
|
||||||
|
passedCbOn = true;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2096,7 +2101,8 @@ public class XmppConnectionService extends Service {
|
||||||
if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize())
|
if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize())
|
||||||
|| conversation.getMode() == Conversation.MODE_MULTI
|
|| conversation.getMode() == Conversation.MODE_MULTI
|
||||||
|| message.fixCounterpart()) {
|
|| message.fixCounterpart()) {
|
||||||
this.sendFileMessage(message, delay);
|
this.sendFileMessage(message, delay, cb);
|
||||||
|
passedCbOn = true;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2134,7 +2140,8 @@ public class XmppConnectionService extends Service {
|
||||||
if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize())
|
if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize())
|
||||||
|| conversation.getMode() == Conversation.MODE_MULTI
|
|| conversation.getMode() == Conversation.MODE_MULTI
|
||||||
|| message.fixCounterpart()) {
|
|| message.fixCounterpart()) {
|
||||||
this.sendFileMessage(message, delay);
|
this.sendFileMessage(message, delay, cb);
|
||||||
|
passedCbOn = true;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2172,6 +2179,7 @@ public class XmppConnectionService extends Service {
|
||||||
Log.e(Config.LOGTAG, "error updated message in DB after edit");
|
Log.e(Config.LOGTAG, "error updated message in DB after edit");
|
||||||
}
|
}
|
||||||
updateConversationUi();
|
updateConversationUi();
|
||||||
|
if (!waitForPreview && cb != null) cb.run();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
databaseBackend.createMessage(message);
|
databaseBackend.createMessage(message);
|
||||||
|
@ -2242,6 +2250,7 @@ public class XmppConnectionService extends Service {
|
||||||
if (message.getConversation() instanceof Conversation) presenceToMuc((Conversation) message.getConversation());
|
if (message.getConversation() instanceof Conversation) presenceToMuc((Conversation) message.getConversation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!waitForPreview && !passedCbOn && cb != null) { Log.d("WUT cb", message.getRawBody()); cb.run(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isJoinInProgress(final Conversation conversation) {
|
private boolean isJoinInProgress(final Conversation conversation) {
|
||||||
|
@ -2268,11 +2277,15 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resendMessage(final Message message, final boolean delay) {
|
public void resendMessage(final Message message, final boolean delay) {
|
||||||
sendMessage(message, true, false, delay);
|
sendMessage(message, true, false, delay, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resendMessage(final Message message, final boolean delay, final Runnable cb) {
|
||||||
|
sendMessage(message, true, false, delay, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resendMessage(final Message message, final boolean delay, final boolean previewedLinks) {
|
public void resendMessage(final Message message, final boolean delay, final boolean previewedLinks) {
|
||||||
sendMessage(message, true, previewedLinks, delay);
|
sendMessage(message, true, previewedLinks, delay, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<Account,Account> onboardingIncomplete() {
|
public Pair<Account,Account> onboardingIncomplete() {
|
||||||
|
|
|
@ -1076,7 +1076,7 @@ public class ConversationFragment extends XmppFragment
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void attachFileToConversation(Conversation conversation, Uri uri, String type) {
|
private void attachFileToConversation(Conversation conversation, Uri uri, String type, Runnable next) {
|
||||||
if (conversation == null) {
|
if (conversation == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1100,10 +1100,14 @@ public class ConversationFragment extends XmppFragment
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void success(Message message) {
|
public void success(Message message) {
|
||||||
runOnUiThread(() -> {
|
if (next == null) {
|
||||||
activity.hideToast();
|
runOnUiThread(() -> {
|
||||||
messageSent();
|
activity.hideToast();
|
||||||
});
|
messageSent();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
runOnUiThread(next);
|
||||||
|
}
|
||||||
hidePrepareFileToast(prepareFileToast);
|
hidePrepareFileToast(prepareFileToast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1126,7 +1130,7 @@ public class ConversationFragment extends XmppFragment
|
||||||
toggleInputMethod();
|
toggleInputMethod();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void attachImageToConversation(Conversation conversation, Uri uri, String type) {
|
private void attachImageToConversation(Conversation conversation, Uri uri, String type, Runnable next) {
|
||||||
if (conversation == null) {
|
if (conversation == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1150,7 +1154,11 @@ public class ConversationFragment extends XmppFragment
|
||||||
@Override
|
@Override
|
||||||
public void success(Message message) {
|
public void success(Message message) {
|
||||||
hidePrepareFileToast(prepareFileToast);
|
hidePrepareFileToast(prepareFileToast);
|
||||||
runOnUiThread(() -> messageSent());
|
if (next == null) {
|
||||||
|
runOnUiThread(() -> messageSent());
|
||||||
|
} else {
|
||||||
|
runOnUiThread(next);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1506,26 +1514,31 @@ public class ConversationFragment extends XmppFragment
|
||||||
}
|
}
|
||||||
final PresenceSelector.OnPresenceSelected callback =
|
final PresenceSelector.OnPresenceSelected callback =
|
||||||
() -> {
|
() -> {
|
||||||
for (Iterator<Attachment> i = attachments.iterator(); i.hasNext(); i.remove()) {
|
final Iterator<Attachment> i = attachments.iterator();
|
||||||
final Attachment attachment = i.next();
|
final Runnable next = new Runnable() {
|
||||||
if (attachment.getType() == Attachment.Type.LOCATION) {
|
@Override
|
||||||
attachLocationToConversation(conversation, attachment.getUri());
|
public void run() {
|
||||||
} else if (attachment.getType() == Attachment.Type.IMAGE) {
|
final Attachment attachment = i.next();
|
||||||
Log.d(
|
if (attachment.getType() == Attachment.Type.LOCATION) {
|
||||||
Config.LOGTAG,
|
attachLocationToConversation(conversation, attachment.getUri());
|
||||||
"ConversationsActivity.commitAttachments() - attaching image to conversations. CHOOSE_IMAGE");
|
if (i.hasNext()) runOnUiThread(this);
|
||||||
attachImageToConversation(
|
} else if (attachment.getType() == Attachment.Type.IMAGE) {
|
||||||
conversation, attachment.getUri(), attachment.getMime());
|
Log.d(
|
||||||
} else {
|
Config.LOGTAG,
|
||||||
Log.d(
|
"ConversationsActivity.commitAttachments() - attaching image to conversations. CHOOSE_IMAGE");
|
||||||
Config.LOGTAG,
|
attachImageToConversation(conversation, attachment.getUri(), attachment.getMime(), i.hasNext() ? this : null);
|
||||||
"ConversationsActivity.commitAttachments() - attaching file to conversations. CHOOSE_FILE/RECORD_VOICE/RECORD_VIDEO");
|
} else {
|
||||||
attachFileToConversation(
|
Log.d(
|
||||||
conversation, attachment.getUri(), attachment.getMime());
|
Config.LOGTAG,
|
||||||
|
"ConversationsActivity.commitAttachments() - attaching file to conversations. CHOOSE_FILE/RECORD_VOICE/RECORD_VIDEO");
|
||||||
|
attachFileToConversation(conversation, attachment.getUri(), attachment.getMime(), i.hasNext() ? this : null);
|
||||||
|
}
|
||||||
|
i.remove();
|
||||||
|
mediaPreviewAdapter.notifyDataSetChanged();
|
||||||
|
toggleInputMethod();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
mediaPreviewAdapter.notifyDataSetChanged();
|
next.run();
|
||||||
toggleInputMethod();
|
|
||||||
};
|
};
|
||||||
if (conversation == null
|
if (conversation == null
|
||||||
|| conversation.getMode() == Conversation.MODE_MULTI
|
|| conversation.getMode() == Conversation.MODE_MULTI
|
||||||
|
@ -1856,42 +1869,42 @@ public class ConversationFragment extends XmppFragment
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AutocompletePresenter.PopupDimensions getPopupDimensions() {
|
protected AutocompletePresenter.PopupDimensions getPopupDimensions() {
|
||||||
final var dim = new AutocompletePresenter.PopupDimensions();
|
final var dim = new AutocompletePresenter.PopupDimensions();
|
||||||
dim.width = displayMetrics.widthPixels * 4 / 5;
|
dim.width = displayMetrics.widthPixels * 4/5;
|
||||||
return dim;
|
return dim;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.with(new AutocompleteCallback<MucOptions.User>() {
|
.with(new AutocompleteCallback<MucOptions.User>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onPopupItemClicked(Editable editable, MucOptions.User user) {
|
public boolean onPopupItemClicked(Editable editable, MucOptions.User user) {
|
||||||
int[] range = com.otaliastudios.autocomplete.CharPolicy.getQueryRange(editable);
|
int[] range = com.otaliastudios.autocomplete.CharPolicy.getQueryRange(editable);
|
||||||
if (range == null) return false;
|
if (range == null) return false;
|
||||||
range[0] -= 1;
|
range[0] -= 1;
|
||||||
if ("\0attention".equals(user.getOccupantId())) {
|
if ("\0attention".equals(user.getOccupantId())) {
|
||||||
editable.delete(Math.max(0, range[0]), Math.min(editable.length(), range[1]));
|
editable.delete(Math.max(0, range[0]), Math.min(editable.length(), range[1]));
|
||||||
editable.insert(0, "@here ");
|
editable.insert(0, "@here ");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
int colon = editable.toString().indexOf(':');
|
int colon = editable.toString().indexOf(':');
|
||||||
final var beforeColon = range[0] < colon;
|
final var beforeColon = range[0] < colon;
|
||||||
String prefix = "";
|
String prefix = "";
|
||||||
String suffix = " ";
|
String suffix = " ";
|
||||||
if (beforeColon) suffix = ", ";
|
if (beforeColon) suffix = ", ";
|
||||||
if (colon < 0 && range[0] == 0) suffix = ": ";
|
if (colon < 0 && range[0] == 0) suffix = ": ";
|
||||||
if (colon > 0 && colon == range[0] - 2) {
|
if (colon > 0 && colon == range[0] - 2) {
|
||||||
prefix = ", ";
|
prefix = ", ";
|
||||||
suffix = ": ";
|
suffix = ": ";
|
||||||
range[0] -= 2;
|
range[0] -= 2;
|
||||||
}
|
}
|
||||||
var insert = user.getNick();
|
var insert = user.getNick();
|
||||||
if ("\0role:moderator".equals(user.getOccupantId())) {
|
if ("\0role:moderator".equals(user.getOccupantId())) {
|
||||||
insert = conversation.getMucOptions().getUsersByRole(MucOptions.Role.MODERATOR).stream().map(MucOptions.User::getNick).collect(Collectors.joining(", "));
|
insert = conversation.getMucOptions().getUsersByRole(MucOptions.Role.MODERATOR).stream().map(MucOptions.User::getNick).collect(Collectors.joining(", "));
|
||||||
}
|
}
|
||||||
editable.replace(Math.max(0, range[0]), Math.min(editable.length(), range[1]), prefix + insert + suffix);
|
editable.replace(Math.max(0, range[0]), Math.min(editable.length(), range[1]), prefix + insert + suffix);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPopupVisibilityChanged(boolean shown) {
|
public void onPopupVisibilityChanged(boolean shown) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue