diff options
10 files changed, 136 insertions, 46 deletions
diff --git a/src/main/java/de/pixart/messenger/entities/Contact.java b/src/main/java/de/pixart/messenger/entities/Contact.java index b4908d08c..06fd4592c 100644 --- a/src/main/java/de/pixart/messenger/entities/Contact.java +++ b/src/main/java/de/pixart/messenger/entities/Contact.java @@ -526,11 +526,11 @@ public class Contact implements ListItem, Blockable { return this.mLastseen; } - public void setLastPresence(String presence) { - this.mLastPresence = presence; + public void setLastResource(String resource) { + this.mLastPresence = resource; } - public String getLastPresence() { + public String getLastResource() { return this.mLastPresence; } diff --git a/src/main/java/de/pixart/messenger/entities/Message.java b/src/main/java/de/pixart/messenger/entities/Message.java index 3145cdccf..e95781335 100644 --- a/src/main/java/de/pixart/messenger/entities/Message.java +++ b/src/main/java/de/pixart/messenger/entities/Message.java @@ -395,7 +395,7 @@ public class Message extends AbstractEntity { && this.counterpart.equals(message.getCounterpart()) && (body.equals(otherBody) ||(message.getEncryption() == Message.ENCRYPTION_PGP - && message.getRemoteMsgId().matches("[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}"))) ; + && CryptoHelper.UUID_PATTERN.matcher(message.getRemoteMsgId()).matches())); } else { return this.remoteMsgId == null && this.counterpart.equals(message.getCounterpart()) @@ -549,7 +549,7 @@ public class Message extends AbstractEntity { try { counterpart = Jid.fromParts(conversation.getJid().getLocalpart(), conversation.getJid().getDomainpart(), - presences.asStringArray()[0]); + presences.toResourceArray()[0]); return true; } catch (InvalidJidException e) { counterpart = null; diff --git a/src/main/java/de/pixart/messenger/entities/Presences.java b/src/main/java/de/pixart/messenger/entities/Presences.java index ecd826d41..2bf718faf 100644 --- a/src/main/java/de/pixart/messenger/entities/Presences.java +++ b/src/main/java/de/pixart/messenger/entities/Presences.java @@ -1,6 +1,10 @@ package de.pixart.messenger.entities; +import android.util.Pair; + import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.Hashtable; import java.util.List; @@ -49,7 +53,7 @@ public class Presences { } } - public String[] asStringArray() { + public String[] toResourceArray() { synchronized (this.presences) { final String[] presencesArray = new String[presences.size()]; presences.keySet().toArray(presencesArray); @@ -99,4 +103,28 @@ public class Presences { } return true; } + + public Pair<Map<String, String>,Map<String,String>> toTypeAndNameMap() { + Map<String,String> typeMap = new HashMap<>(); + Map<String,String> nameMap = new HashMap<>(); + synchronized (this.presences) { + for(Map.Entry<String,Presence> presenceEntry : this.presences.entrySet()) { + String resource = presenceEntry.getKey(); + Presence presence = presenceEntry.getValue(); + ServiceDiscoveryResult serviceDiscoveryResult = presence == null ? null : presence.getServiceDiscoveryResult(); + if (serviceDiscoveryResult != null && serviceDiscoveryResult.getIdentities().size() > 0) { + ServiceDiscoveryResult.Identity identity = serviceDiscoveryResult.getIdentities().get(0); + String type = identity.getType(); + String name = identity.getName(); + if (type != null) { + typeMap.put(resource,type); + } + if (name != null) { + nameMap.put(resource, name); + } + } + } + } + return new Pair(typeMap,nameMap); + } } diff --git a/src/main/java/de/pixart/messenger/parser/AbstractParser.java b/src/main/java/de/pixart/messenger/parser/AbstractParser.java index abde7019b..937327261 100644 --- a/src/main/java/de/pixart/messenger/parser/AbstractParser.java +++ b/src/main/java/de/pixart/messenger/parser/AbstractParser.java @@ -62,7 +62,7 @@ public abstract class AbstractParser { protected void updateLastseen(final Account account, final Jid from) { final Contact contact = account.getRoster().getContact(from); - contact.setLastPresence(from.isBareJid() ? "" : from.getResourcepart()); + contact.setLastResource(from.isBareJid() ? "" : from.getResourcepart()); } protected String avatarData(Element items) { diff --git a/src/main/java/de/pixart/messenger/persistance/FileBackend.java b/src/main/java/de/pixart/messenger/persistance/FileBackend.java index 4fab799b9..8a5a9af35 100644 --- a/src/main/java/de/pixart/messenger/persistance/FileBackend.java +++ b/src/main/java/de/pixart/messenger/persistance/FileBackend.java @@ -427,7 +427,12 @@ public class FileBackend { private Bitmap getFullsizeImagePreview(File file, int size) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = calcSampleSize(file, size); - return BitmapFactory.decodeFile(file.getAbsolutePath(), options); + try { + return BitmapFactory.decodeFile(file.getAbsolutePath(), options); + } catch (OutOfMemoryError e) { + options.inSampleSize *= 2; + return BitmapFactory.decodeFile(file.getAbsolutePath(), options); + } } private Bitmap getVideoPreview(File file, int size) { diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java index e5760598b..f322034b0 100644 --- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java +++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java @@ -197,7 +197,7 @@ public class XmppConnectionService extends Service { if (contact.getPresences().size() >= 1) { if (conversation.hasValidOtrSession()) { String otrResource = conversation.getOtrSession().getSessionID().getUserID(); - if (!(Arrays.asList(contact.getPresences().asStringArray()).contains(otrResource))) { + if (!(Arrays.asList(contact.getPresences().toResourceArray()).contains(otrResource))) { conversation.endOtrIfNeeded(); } } diff --git a/src/main/java/de/pixart/messenger/ui/XmppActivity.java b/src/main/java/de/pixart/messenger/ui/XmppActivity.java index 8f6192d04..2497d9ded 100644 --- a/src/main/java/de/pixart/messenger/ui/XmppActivity.java +++ b/src/main/java/de/pixart/messenger/ui/XmppActivity.java @@ -43,6 +43,7 @@ import android.preference.PreferenceManager; import android.text.InputType; import android.util.DisplayMetrics; import android.util.Log; +import android.util.Pair; import android.view.MenuItem; import android.view.View; import android.view.inputmethod.InputMethodManager; @@ -65,9 +66,13 @@ import net.java.otr4j.session.SessionID; import java.io.FileNotFoundException; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.Hashtable; import java.util.List; +import java.util.Map; import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.atomic.AtomicInteger; import de.pixart.messenger.Config; import de.pixart.messenger.R; @@ -88,6 +93,9 @@ import de.pixart.messenger.xmpp.OnKeyStatusUpdated; import de.pixart.messenger.xmpp.OnUpdateBlocklist; import de.pixart.messenger.xmpp.jid.InvalidJidException; import de.pixart.messenger.xmpp.jid.Jid; +import de.pixart.messenger.entities.Presence; +import de.pixart.messenger.entities.ServiceDiscoveryResult; +import de.pixart.messenger.utils.UIHelper; public abstract class XmppActivity extends Activity { @@ -951,7 +959,7 @@ public abstract class XmppActivity extends Activity { } else if (!contact.showInRoster()) { showAddToRosterDialog(conversation); } else { - Presences presences = contact.getPresences(); + final Presences presences = contact.getPresences(); if (presences.size() == 0) { if (!contact.getOption(Contact.Options.TO) && !contact.getOption(Contact.Options.ASKING) @@ -965,7 +973,7 @@ public abstract class XmppActivity extends Activity { listener.onPresenceSelected(); } } else if (presences.size() == 1) { - String presence = presences.asStringArray()[0]; + String presence = presences.toResourceArray()[0]; try { conversation.setNextCounterpart(Jid.fromParts(contact.getJid().getLocalpart(),contact.getJid().getDomainpart(),presence)); } catch (InvalidJidException e) { @@ -973,49 +981,72 @@ public abstract class XmppActivity extends Activity { } listener.onPresenceSelected(); } else { - final StringBuilder presence = new StringBuilder(); - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(getString(R.string.choose_presence)); - final String[] presencesArray = presences.asStringArray(); - int preselectedPresence = 0; - for (int i = 0; i < presencesArray.length; ++i) { - if (presencesArray[i].equals(contact.getLastPresence())) { - preselectedPresence = i; - break; + showPresenceSelectionDialog(presences,conversation,listener); + } + } + } + + private void showPresenceSelectionDialog(Presences presences, final Conversation conversation, final OnPresenceSelected listener) { + final Contact contact = conversation.getContact(); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(getString(R.string.choose_presence)); + final String[] resourceArray = presences.toResourceArray(); + Pair<Map<String, String>, Map<String, String>> typeAndName = presences.toTypeAndNameMap(); + final Map<String,String> resourceTypeMap = typeAndName.first; + final Map<String,String> resourceNameMap = typeAndName.second; + final String[] readableIdentities = new String[resourceArray.length]; + final AtomicInteger selectedResource = new AtomicInteger(0); + for (int i = 0; i < resourceArray.length; ++i) { + String resource = resourceArray[i]; + if (resource.equals(contact.getLastResource())) { + selectedResource.set(i); + } + String type = resourceTypeMap.get(resource); + String name = resourceNameMap.get(resource); + if (type != null) { + if (Collections.frequency(resourceTypeMap.values(),type) == 1) { + readableIdentities[i] = UIHelper.tranlasteType(this,type); + } else if (name != null) { + if (Collections.frequency(resourceNameMap.values(), name) == 1 + || CryptoHelper.UUID_PATTERN.matcher(resource).matches()) { + readableIdentities[i] = UIHelper.tranlasteType(this,type) + " (" + name+")"; + } else { + readableIdentities[i] = UIHelper.tranlasteType(this,type) + " (" + name +" / " + resource+")"; } + } else { + readableIdentities[i] = UIHelper.tranlasteType(this,type) + " (" + resource+")"; } - presence.append(presencesArray[preselectedPresence]); - builder.setSingleChoiceItems(presencesArray, - preselectedPresence, - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - presence.delete(0, presence.length()); - presence.append(presencesArray[which]); - } - }); - builder.setNegativeButton(R.string.cancel, null); - builder.setPositiveButton(R.string.ok, new OnClickListener() { + } else { + readableIdentities[i] = resource; + } + } + builder.setSingleChoiceItems(readableIdentities, + selectedResource.get(), + new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - try { - conversation.setNextCounterpart(Jid.fromParts(contact.getJid().getLocalpart(),contact.getJid().getDomainpart(),presence.toString())); - } catch (InvalidJidException e) { - conversation.setNextCounterpart(null); - } - listener.onPresenceSelected(); + selectedResource.set(which); } }); - builder.create().show(); + builder.setNegativeButton(R.string.cancel, null); + builder.setPositiveButton(R.string.ok, new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + try { + Jid next = Jid.fromParts(contact.getJid().getLocalpart(),contact.getJid().getDomainpart(),resourceArray[selectedResource.get()]); + conversation.setNextCounterpart(next); + } catch (InvalidJidException e) { + conversation.setNextCounterpart(null); + } + listener.onPresenceSelected(); } - } + }); + builder.create().show(); } - protected void onActivityResult(int requestCode, int resultCode, - final Intent data) { + protected void onActivityResult(int requestCode, int resultCode, final Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_INVITE_TO_CONVERSATION && resultCode == RESULT_OK) { mPendingConferenceInvite = ConferenceInvite.parse(data); @@ -1110,7 +1141,7 @@ public abstract class XmppActivity extends Activity { public NdefMessage createNdefMessage(NfcEvent nfcEvent) { return new NdefMessage(new NdefRecord[]{ NdefRecord.createUri(getShareableUri()), - NdefRecord.createApplicationRecord("eu.siacs.conversations") + NdefRecord.createApplicationRecord("de.pixart.messenger") }); } }, this); diff --git a/src/main/java/de/pixart/messenger/utils/CryptoHelper.java b/src/main/java/de/pixart/messenger/utils/CryptoHelper.java index d043e08b1..012ebf4d0 100644 --- a/src/main/java/de/pixart/messenger/utils/CryptoHelper.java +++ b/src/main/java/de/pixart/messenger/utils/CryptoHelper.java @@ -21,6 +21,7 @@ import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; +import java.util.regex.Pattern; import de.pixart.messenger.Config; import de.pixart.messenger.R; @@ -31,6 +32,8 @@ import de.pixart.messenger.xmpp.jid.Jid; public final class CryptoHelper { public static final String FILETRANSFER = "?FILETRANSFERv1:"; private final static char[] hexArray = "0123456789abcdef".toCharArray(); + + public static final Pattern UUID_PATTERN = Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}"); final public static byte[] ONE = new byte[] { 0, 0, 0, 1 }; public static String bytesToHex(byte[] bytes) { diff --git a/src/main/java/de/pixart/messenger/utils/UIHelper.java b/src/main/java/de/pixart/messenger/utils/UIHelper.java index 53c1b8a11..7f04c4b7b 100644 --- a/src/main/java/de/pixart/messenger/utils/UIHelper.java +++ b/src/main/java/de/pixart/messenger/utils/UIHelper.java @@ -19,6 +19,7 @@ import de.pixart.messenger.entities.Message; import de.pixart.messenger.entities.Presence; import de.pixart.messenger.entities.Transferable; import de.pixart.messenger.xmpp.jid.Jid; +import de.pixart.messenger.ui.XmppActivity; public class UIHelper { @@ -286,4 +287,21 @@ public class UIHelper { return new ListItem.Tag(context.getString(R.string.presence_online), 0xff259b24); } } + + public static String tranlasteType(Context context, String type) { + switch (type.toLowerCase()) { + case "pc": + return context.getString(R.string.type_pc); + case "phone": + return context.getString(R.string.type_phone); + case "tablet": + return context.getString(R.string.type_tablet); + case "web": + return context.getString(R.string.type_web); + case "console": + return context.getString(R.string.type_console); + default: + return type; + } + } } diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 3528dcc9e..370b07224 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -77,7 +77,7 @@ <string name="clear_histor_msg">Do you want to delete all messages within this Conversation?\n\n<b>Warning:</b> This will not influence messages stored on other devices or servers.</string> <string name="delete_messages">Delete messages</string> <string name="also_end_conversation">End this conversation afterwards</string> - <string name="choose_presence">Choose presence to contact</string> + <string name="choose_presence">Choose device</string> <string name="send_unencrypted_message">Send unencrypted message</string> <string name="send_message_to_x">Send message to %s</string> <string name="send_otr_message">Send OTR encrypted message</string> @@ -672,4 +672,9 @@ <string name="no_permission">Pix-Art Messenger has no permissions</string> <string name="send_image">Send image?</string> <string name="this_device_is_no_longer_in_use">This device is no longer in use</string> + <string name="type_pc">Computer</string> + <string name="type_phone">Mobile phone</string> + <string name="type_tablet">Tablet</string> + <string name="type_web">Web browser</string> + <string name="type_console">Console</string> </resources> |