diff options
13 files changed, 479 insertions, 414 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ConferenceDetailsActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/ConferenceDetailsActivity.java index 7ea83b92..1125b37e 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/ConferenceDetailsActivity.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/ConferenceDetailsActivity.java @@ -308,7 +308,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers } @Override - protected String getShareableUri() { + public String getShareableUri() { if (mConversation != null) { return "xmpp:" + mConversation.getJid().toBareJid().toString() + "?join"; } else { diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ContactDetailsActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/ContactDetailsActivity.java index be6a5994..245b7a38 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/ContactDetailsActivity.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/ContactDetailsActivity.java @@ -171,7 +171,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd } @Override - protected String getShareableUri() { + public String getShareableUri() { if (contact != null) { return contact.getShareableUri(); } else { diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java index 0167ef4b..69c1f817 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java @@ -46,7 +46,6 @@ import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import de.thedevstack.android.logcat.Logging; -import de.thedevstack.conversationsplus.entities.Presence; import de.thedevstack.conversationsplus.services.filetransfer.FileTransferManager; import de.thedevstack.conversationsplus.utils.AccountUtil; import de.thedevstack.conversationsplus.utils.UIHelper; @@ -149,7 +148,7 @@ public class ConversationActivity extends XmppActivity } @Override - protected String getShareableUri() { + public String getShareableUri() { Conversation conversation = getSelectedConversation(); if (conversation != null) { return conversation.getAccount().getShareableUri(); @@ -1251,12 +1250,12 @@ public class ConversationActivity extends XmppActivity Jid jid = getSelectedConversation().getJid(); try { Jid next = Jid.fromParts(jid.getLocalpart(), jid.getDomainpart(), nick); - this.mConversationFragment.privateMessageWith(next); + this.privateMessageWith(next); } catch (final InvalidJidException ignored) { //do nothing } } else { - this.mConversationFragment.highlightInConference(nick); + this.highlightNickInConference(nick); } } else { this.mConversationFragment.appendText(text); @@ -1275,6 +1274,14 @@ public class ConversationActivity extends XmppActivity } } + public void privateMessageWith(Jid jid) { + this.mConversationFragment.privateMessageWith(jid); + } + + public void highlightNickInConference(String nick) { + this.mConversationFragment.highlightInConference(nick); + } + private boolean selectConversationByUuid(String uuid) { if (uuid == null) { return false; diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java index 528e2a55..cd2ee4f8 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java @@ -64,8 +64,6 @@ import de.thedevstack.conversationsplus.services.XmppConnectionService; import de.thedevstack.conversationsplus.ui.XmppActivity.OnPresenceSelected; import de.thedevstack.conversationsplus.ui.XmppActivity.OnValueEdited; import de.thedevstack.conversationsplus.ui.adapter.MessageAdapter; -import de.thedevstack.conversationsplus.ui.adapter.MessageAdapter.OnContactPictureClicked; -import de.thedevstack.conversationsplus.ui.adapter.MessageAdapter.OnContactPictureLongClicked; import de.thedevstack.conversationsplus.ui.listeners.ConversationSwipeRefreshListener; import de.thedevstack.conversationsplus.ui.listeners.DeleteFileCallback; import de.thedevstack.conversationsplus.utils.AccountUtil; @@ -454,54 +452,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa messagesView = (ListView) view.findViewById(R.id.messages_view); messagesView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL); messageListAdapter = new MessageAdapter((ConversationActivity) getActivity(), this.messageList); - messageListAdapter.setOnContactPictureClicked(new OnContactPictureClicked() { - - @Override - public void onContactPictureClicked(Message message) { - if (message.getStatus() <= Message.STATUS_RECEIVED) { - if (message.getConversation().getMode() == Conversation.MODE_MULTI) { - if (message.getCounterpart() != null) { - String user = message.getCounterpart().isBareJid() ? message.getCounterpart().toString() : message.getCounterpart().getResourcepart(); - if (!message.getConversation().getMucOptions().isUserInRoom(user)) { - Toast.makeText(activity,activity.getString(R.string.user_has_left_conference,user),Toast.LENGTH_SHORT).show(); - } - highlightInConference(user); - } - } else { - activity.switchToContactDetails(message.getContact(), message.getFingerprint()); - } - } else { - Account account = message.getConversation().getAccount(); - Intent intent = new Intent(activity, EditAccountActivity.class); - intent.putExtra("jid", account.getJid().toBareJid().toString()); - intent.putExtra("fingerprint", message.getFingerprint()); - startActivity(intent); - } - } - }); - messageListAdapter - .setOnContactPictureLongClicked(new OnContactPictureLongClicked() { - - @Override - public void onContactPictureLongClicked(Message message) { - if (message.getStatus() <= Message.STATUS_RECEIVED) { - if (message.getConversation().getMode() == Conversation.MODE_MULTI) { - if (message.getCounterpart() != null) { - String user = message.getCounterpart().getResourcepart(); - if (user != null) { - if (message.getConversation().getMucOptions().isUserInRoom(user)) { - privateMessageWith(message.getCounterpart()); - } else { - Toast.makeText(activity, activity.getString(R.string.user_has_left_conference, user), Toast.LENGTH_SHORT).show(); - } - } - } - } - } else { - activity.showQrCode(); - } - } - }); messagesView.setAdapter(messageListAdapter); registerForContextMenu(messagesView); @@ -718,7 +668,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa updateSendButton(); } - protected void highlightInConference(String nick) { + public void highlightInConference(String nick) { String oldString = mEditMessage.getText().toString(); if (oldString.isEmpty() || mEditMessage.getSelectionStart() == 0) { mEditMessage.getText().insert(0, nick + ": "); diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/EditAccountActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/EditAccountActivity.java index 6856bc25..725e10a9 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/EditAccountActivity.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/EditAccountActivity.java @@ -376,7 +376,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate } @Override - protected String getShareableUri() { + public String getShareableUri() { if (mAccount != null) { return mAccount.getShareableUri(); } else { diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/VerifyOTRActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/VerifyOTRActivity.java index 4f1c9fc7..d6b3d838 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/VerifyOTRActivity.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/VerifyOTRActivity.java @@ -424,7 +424,7 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer } @Override - protected String getShareableUri() { + public String getShareableUri() { if (mAccount!=null) { return mAccount.getShareableUri(); } else { diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/XmppActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/XmppActivity.java index 85bc2af3..21292cec 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/XmppActivity.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/XmppActivity.java @@ -19,9 +19,6 @@ import android.content.IntentSender.SendIntentException; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import android.graphics.Bitmap; -import android.graphics.Color; -import android.graphics.Point; import android.net.Uri; import android.nfc.NdefMessage; import android.nfc.NdefRecord; @@ -41,26 +38,16 @@ import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.CompoundButton; import android.widget.EditText; -import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.Switch; import android.widget.TextView; import android.widget.Toast; -import com.google.zxing.BarcodeFormat; -import com.google.zxing.EncodeHintType; -import com.google.zxing.WriterException; -import com.google.zxing.common.BitMatrix; -import com.google.zxing.qrcode.QRCodeWriter; -import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; - import net.java.otr4j.session.SessionID; import java.util.ArrayList; -import java.util.Hashtable; import java.util.List; -import de.thedevstack.android.logcat.Logging; import de.thedevstack.conversationsplus.ConversationsPlusColors; import de.thedevstack.conversationsplus.ConversationsPlusPreferences; import de.thedevstack.conversationsplus.Config; @@ -77,6 +64,7 @@ import de.thedevstack.conversationsplus.services.XmppConnectionService; import de.thedevstack.conversationsplus.services.XmppConnectionService.XmppConnectionBinder; import de.thedevstack.conversationsplus.utils.CryptoHelper; import de.thedevstack.conversationsplus.utils.ExceptionHelper; +import de.thedevstack.conversationsplus.utils.ui.QrCodeUtil; import de.thedevstack.conversationsplus.utils.XmppSendUtil; import de.thedevstack.conversationsplus.xmpp.OnKeyStatusUpdated; import de.thedevstack.conversationsplus.xmpp.OnUpdateBlocklist; @@ -328,7 +316,7 @@ public abstract class XmppActivity extends Activity { finish(); break; case R.id.action_show_qr_code: - showQrCode(); + QrCodeUtil.showQrCode(this); break; } return super.onOptionsItemSelected(item); @@ -933,7 +921,7 @@ public abstract class XmppActivity extends Activity { } } - protected String getShareableUri() { + public String getShareableUri() { return null; } @@ -959,46 +947,6 @@ public abstract class XmppActivity extends Activity { this.unregisterNdefPushMessageCallback(); } - protected void showQrCode() { - String uri = getShareableUri(); - if (uri!=null) { - Point size = new Point(); - getWindowManager().getDefaultDisplay().getSize(size); - final int width = (size.x < size.y ? size.x : size.y); - Bitmap bitmap = createQrCodeBitmap(uri, width); - ImageView view = new ImageView(this); - view.setImageBitmap(bitmap); - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setView(view); - builder.create().show(); - } - } - - protected Bitmap createQrCodeBitmap(String input, int size) { - Logging.d(Config.LOGTAG,"qr code requested size: "+size); - try { - final QRCodeWriter QR_CODE_WRITER = new QRCodeWriter(); - final Hashtable<EncodeHintType, Object> hints = new Hashtable<>(); - hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); - final BitMatrix result = QR_CODE_WRITER.encode(input, BarcodeFormat.QR_CODE, size, size, hints); - final int width = result.getWidth(); - final int height = result.getHeight(); - final int[] pixels = new int[width * height]; - for (int y = 0; y < height; y++) { - final int offset = y * width; - for (int x = 0; x < width; x++) { - pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.TRANSPARENT; - } - } - final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - Logging.d(Config.LOGTAG,"output size: "+width+"x"+height); - bitmap.setPixels(pixels, 0, width, 0, 0, width, height); - return bitmap; - } catch (final WriterException e) { - return null; - } - } - protected Account extractAccount(Intent intent) { String jid = intent != null ? intent.getStringExtra(EXTRA_ACCOUNT) : null; try { diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java index 96b5954e..4991c512 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java @@ -1,11 +1,7 @@ package de.thedevstack.conversationsplus.ui.adapter; -import android.content.ActivityNotFoundException; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.graphics.Typeface; -import android.net.Uri; +import android.support.annotation.NonNull; import android.text.Spannable; import android.text.SpannableString; @@ -14,7 +10,6 @@ import android.text.style.ForegroundColorSpan; import android.text.style.StyleSpan; import android.text.util.Linkify; -import android.util.DisplayMetrics; import android.util.Patterns; import android.view.View; import android.view.View.OnClickListener; @@ -25,33 +20,30 @@ import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import android.widget.Toast; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; - -import de.thedevstack.conversationsplus.ConversationsPlusApplication; import de.thedevstack.conversationsplus.ConversationsPlusColors; import de.thedevstack.conversationsplus.ConversationsPlusPreferences; import de.thedevstack.conversationsplus.R; import de.thedevstack.conversationsplus.crypto.axolotl.XmppAxolotlSession; import de.thedevstack.conversationsplus.entities.Account; import de.thedevstack.conversationsplus.entities.Conversation; -import de.thedevstack.conversationsplus.entities.DownloadableFile; import de.thedevstack.conversationsplus.entities.FileParams; import de.thedevstack.conversationsplus.entities.Message; import de.thedevstack.conversationsplus.entities.Transferable; import de.thedevstack.conversationsplus.enums.FileStatus; -import de.thedevstack.conversationsplus.persistance.FileBackend; -import de.thedevstack.conversationsplus.providers.ConversationsPlusFileProvider; import de.thedevstack.conversationsplus.services.avatar.AvatarCache; import de.thedevstack.conversationsplus.services.avatar.AvatarService; -import de.thedevstack.conversationsplus.services.filetransfer.FileTransferStatusEnum; import de.thedevstack.conversationsplus.services.filetransfer.http.download.AutomaticFileDownload; import de.thedevstack.conversationsplus.ui.ConversationActivity; +import de.thedevstack.conversationsplus.ui.listeners.ContactPictureOnClickListener; +import de.thedevstack.conversationsplus.ui.listeners.ContactPictureOnLongClickListener; +import de.thedevstack.conversationsplus.ui.listeners.OpenFileOnClickListener; +import de.thedevstack.conversationsplus.ui.listeners.OpenLocationOnClickListener; import de.thedevstack.conversationsplus.utils.CryptoHelper; import de.thedevstack.conversationsplus.utils.GeoHelper; import de.thedevstack.conversationsplus.utils.ImageUtil; @@ -74,11 +66,6 @@ public class MessageAdapter extends ArrayAdapter<Message> { private ConversationActivity activity; - private DisplayMetrics metrics; - - private OnContactPictureClicked mOnContactPictureClickedListener; - private OnContactPictureLongClicked mOnContactPictureLongClickedListener; - private OnLongClickListener openContextMenu = new OnLongClickListener() { @Override @@ -88,20 +75,9 @@ public class MessageAdapter extends ArrayAdapter<Message> { } }; - public MessageAdapter(ConversationActivity activity, List<Message> messages) { super(activity, 0, messages); this.activity = activity; - metrics = getContext().getResources().getDisplayMetrics(); - } - - public void setOnContactPictureClicked(OnContactPictureClicked listener) { - this.mOnContactPictureClickedListener = listener; - } - - public void setOnContactPictureLongClicked( - OnContactPictureLongClicked listener) { - this.mOnContactPictureLongClickedListener = listener; } @Override @@ -138,9 +114,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { String filesize = null; String info = null; boolean error = false; - if (viewHolder.indicatorReceived != null) { - viewHolder.indicatorReceived.setVisibility(View.GONE); - } + ViewUtil.gone(viewHolder.indicatorReceived); boolean multiReceived = message.getConversation().getMode() == Conversation.MODE_MULTI && message.getStatus() <= Message.STATUS_RECEIVED; @@ -193,11 +167,76 @@ public class MessageAdapter extends ArrayAdapter<Message> { } break; } - if (error && type == SENT) { + + this.displayEncryptionIndicator(message, viewHolder); + + this.displayMessageTime(message, viewHolder, filesize, info, error, type == SENT); + + this.displayRemoteFileStatus(message, viewHolder); + } + + private void displayRemoteFileStatus(Message message, ViewHolder viewHolder) { + if (message.hasFileAttached() && null != message.getFileParams() && null != viewHolder.remoteFileStatus) { + FileStatus fileStatus = message.getFileParams().getFileStatus(); + if (fileStatus == FileStatus.DELETE_FAILED || fileStatus == FileStatus.DELETED || fileStatus == FileStatus.DELETING || fileStatus == FileStatus.NOT_FOUND) { + TextViewUtil.visible(viewHolder.remoteFileStatus); + switch (fileStatus) { + case DELETE_FAILED: + TextViewUtil.setColor(viewHolder.remoteFileStatus, R.color.error); + viewHolder.remoteFileStatus.setText(R.string.remote_filestatus_delete_failed); + break; + case DELETED: + viewHolder.remoteFileStatus.setText(R.string.remote_filestatus_delete_success); + break; + case DELETING: + viewHolder.remoteFileStatus.setText(R.string.remote_filestatus_delete_inprogress); + break; + case NOT_FOUND: + TextViewUtil.setColor(viewHolder.remoteFileStatus, R.color.error); + viewHolder.remoteFileStatus.setText(R.string.remote_filestatus_not_found); + break; + } + } else { + TextViewUtil.gone(viewHolder.remoteFileStatus); + } + } + } + + private void displayMessageTime(Message message, ViewHolder viewHolder, String filesize, String info, boolean error, boolean isSent) { + if (error && isSent) { viewHolder.time.setTextColor(ConversationsPlusColors.warning()); } else { viewHolder.time.setTextColor(this.getMessageTextColor(viewHolder.darkBackground, false)); } + String formatedTime = UIHelper.readableTimeDifferenceFull(getContext(), message.getTimeSent()); + String timeText = null; + if (message.getStatus() <= Message.STATUS_RECEIVED) { + StringBuilder timeTextBuilder = new StringBuilder(); + timeTextBuilder.append((null != formatedTime) ? formatedTime + ((null != info || null != filesize) ? " \u00B7 " : "") : ""); + timeTextBuilder.append((null != filesize) ? filesize + ((null != info) ? " \u00B7 " : "") : ""); + timeTextBuilder.append((null != info) ? info : ""); + + timeText = timeTextBuilder.toString(); + } else { + if ((filesize != null) && (info != null)) { + timeText = filesize + " \u00B7 " + info; + } else if ((filesize == null) && (info != null)) { + if (error) { + timeText = info + " \u00B7 " + formatedTime; + } else { + timeText = info; + } + } else if ((filesize != null) && (info == null)) { + timeText = filesize + " \u00B7 " + formatedTime; + } else { + timeText = formatedTime; + } + } + + TextViewUtil.setTextWithoutAutoLink(viewHolder.time, timeText); + } + + private void displayEncryptionIndicator(Message message, ViewHolder viewHolder) { if (message.getEncryption() == Message.ENCRYPTION_NONE) { viewHolder.indicator.setVisibility(View.GONE); } else { @@ -228,55 +267,6 @@ public class MessageAdapter extends ArrayAdapter<Message> { } } } - - String formatedTime = UIHelper.readableTimeDifferenceFull(getContext(), message.getTimeSent()); - if (message.getStatus() <= Message.STATUS_RECEIVED) { - StringBuilder timeText = new StringBuilder(); - timeText.append((null != formatedTime) ? formatedTime + ((null != info || null != filesize) ? " \u00B7 " : "") : ""); - timeText.append((null != filesize) ? filesize + ((null != info) ? " \u00B7 " : "") : ""); - timeText.append((null != info) ? info : ""); - - viewHolder.time.setText(timeText); - } else { - if ((filesize != null) && (info != null)) { - viewHolder.time.setText(filesize + " \u00B7 " + info); - } else if ((filesize == null) && (info != null)) { - if (error) { - viewHolder.time.setText(info + " \u00B7 " + formatedTime); - } else { - viewHolder.time.setText(info); - } - } else if ((filesize != null) && (info == null)) { - viewHolder.time.setText(filesize + " \u00B7 " + formatedTime); - } else { - viewHolder.time.setText(formatedTime); - } - } - - if (message.hasFileAttached() && null != message.getFileParams() && null != viewHolder.remoteFileStatus) { - FileStatus fileStatus = message.getFileParams().getFileStatus(); - if (fileStatus == FileStatus.DELETE_FAILED || fileStatus == FileStatus.DELETED || fileStatus == FileStatus.DELETING || fileStatus == FileStatus.NOT_FOUND) { - TextViewUtil.visible(viewHolder.remoteFileStatus); - switch (fileStatus) { - case DELETE_FAILED: - TextViewUtil.setColor(viewHolder.remoteFileStatus, R.color.error); - viewHolder.remoteFileStatus.setText(R.string.remote_filestatus_delete_failed); - break; - case DELETED: - viewHolder.remoteFileStatus.setText(R.string.remote_filestatus_delete_success); - break; - case DELETING: - viewHolder.remoteFileStatus.setText(R.string.remote_filestatus_delete_inprogress); - break; - case NOT_FOUND: - TextViewUtil.setColor(viewHolder.remoteFileStatus, R.color.error); - viewHolder.remoteFileStatus.setText(R.string.remote_filestatus_not_found); - break; - } - } else { - TextViewUtil.gone(viewHolder.remoteFileStatus); - } - } } private void displayInfoMessage(ViewHolder viewHolder, String text) { @@ -310,92 +300,87 @@ public class MessageAdapter extends ArrayAdapter<Message> { } private void displayTextMessage(final ViewHolder viewHolder, final Message message) { - if (viewHolder.download_button != null) { - viewHolder.download_button.setVisibility(View.GONE); - } - if (null != viewHolder.image) { - viewHolder.image.setVisibility(View.GONE); + ViewUtil.gone(viewHolder.download_button, viewHolder.image); + + viewHolder.messageBody.setVisibility(View.VISIBLE); + viewHolder.messageBody.setIncludeFontPadding(true); + if (message.getBody() != null) { + final String nick = UIHelper.getMessageDisplayName(message); + String body; + if (message.hasMeCommand()) { + body = message.getBodyReplacedMeCommand(nick); + } else { + body = message.getBody(); } + final SpannableString formattedBody = new SpannableString(body); - viewHolder.messageBody.setVisibility(View.VISIBLE); - viewHolder.messageBody.setIncludeFontPadding(true); - if (message.getBody() != null) { - final String nick = UIHelper.getMessageDisplayName(message); - String body; + if (message.getType() != Message.TYPE_PRIVATE) { if (message.hasMeCommand()) { - body = message.getBodyReplacedMeCommand(nick); + final Spannable span = new SpannableString(formattedBody); + span.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + viewHolder.messageBody.setText(span); } else { - body = message.getBody(); + viewHolder.messageBody.setText(formattedBody); } - final SpannableString formattedBody = new SpannableString(body); - - if (message.getType() != Message.TYPE_PRIVATE) { - if (message.hasMeCommand()) { - final Spannable span = new SpannableString(formattedBody); - span.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - viewHolder.messageBody.setText(span); - } else { - viewHolder.messageBody.setText(formattedBody); - } + } else { + String privateMarker; + if (message.getStatus() <= Message.STATUS_RECEIVED) { + privateMarker = activity.getString(R.string.private_message); } else { - String privateMarker; - if (message.getStatus() <= Message.STATUS_RECEIVED) { - privateMarker = activity.getString(R.string.private_message); + final String to; + if (message.getCounterpart() != null) { + to = message.getCounterpart().getResourcepart(); } else { - final String to; - if (message.getCounterpart() != null) { - to = message.getCounterpart().getResourcepart(); - } else { - to = ""; - } - privateMarker = activity.getString(R.string.private_message_to, to); - } - final Spannable span = new SpannableString(privateMarker + " " - + formattedBody); - span.setSpan(new ForegroundColorSpan(getMessageTextColor(viewHolder.darkBackground, false)), 0, privateMarker - .length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - span.setSpan(new StyleSpan(Typeface.BOLD), 0, - privateMarker.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - if (message.hasMeCommand()) { - span.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), privateMarker.length() + 1, - privateMarker.length() + 1 + nick.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + to = ""; } - viewHolder.messageBody.setText(span); + privateMarker = activity.getString(R.string.private_message_to, to); } - int patternMatchCount = 0; - int oldAutoLinkMask = viewHolder.messageBody.getAutoLinkMask(); - - // first check if we have a match on XMPP_PATTERN so we do not have to check for EMAIL_ADDRESSES - patternMatchCount += countMatches(XMPP_PATTERN, body); - if ((Linkify.EMAIL_ADDRESSES & oldAutoLinkMask) != 0 && patternMatchCount > 0) { - oldAutoLinkMask -= Linkify.EMAIL_ADDRESSES; + final Spannable span = new SpannableString(privateMarker + " " + + formattedBody); + span.setSpan(new ForegroundColorSpan(getMessageTextColor(viewHolder.darkBackground, false)), 0, privateMarker + .length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + span.setSpan(new StyleSpan(Typeface.BOLD), 0, + privateMarker.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + if (message.hasMeCommand()) { + span.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), privateMarker.length() + 1, + privateMarker.length() + 1 + nick.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } + viewHolder.messageBody.setText(span); + } + int patternMatchCount = 0; + int oldAutoLinkMask = viewHolder.messageBody.getAutoLinkMask(); - // count matches for all patterns - if ((Linkify.WEB_URLS & oldAutoLinkMask) != 0) { - patternMatchCount += countMatches(Patterns.WEB_URL, body); - } - if ((Linkify.EMAIL_ADDRESSES & oldAutoLinkMask) != 0) { - patternMatchCount += countMatches(Patterns.EMAIL_ADDRESS, body); - } - if ((Linkify.PHONE_NUMBERS & oldAutoLinkMask) != 0) { - patternMatchCount += countMatches(Patterns.PHONE, body); - } + // first check if we have a match on XMPP_PATTERN so we do not have to check for EMAIL_ADDRESSES + patternMatchCount += countMatches(XMPP_PATTERN, body); + if ((Linkify.EMAIL_ADDRESSES & oldAutoLinkMask) != 0 && patternMatchCount > 0) { + oldAutoLinkMask -= Linkify.EMAIL_ADDRESSES; + } - viewHolder.messageBody.setTextIsSelectable(patternMatchCount <= 1); - viewHolder.messageBody.setAutoLinkMask(0); - Linkify.addLinks(viewHolder.messageBody, XMPP_PATTERN, "xmpp"); - viewHolder.messageBody.setAutoLinkMask(oldAutoLinkMask); - } else { - viewHolder.messageBody.setText(""); - viewHolder.messageBody.setTextIsSelectable(false); + // count matches for all patterns + if ((Linkify.WEB_URLS & oldAutoLinkMask) != 0) { + patternMatchCount += countMatches(Patterns.WEB_URL, body); + } + if ((Linkify.EMAIL_ADDRESSES & oldAutoLinkMask) != 0) { + patternMatchCount += countMatches(Patterns.EMAIL_ADDRESS, body); } - viewHolder.messageBody.setTextColor(this.getMessageTextColor(viewHolder.darkBackground, true)); - viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); - viewHolder.messageBody.setOnLongClickListener(openContextMenu); + if ((Linkify.PHONE_NUMBERS & oldAutoLinkMask) != 0) { + patternMatchCount += countMatches(Patterns.PHONE, body); + } + + viewHolder.messageBody.setTextIsSelectable(patternMatchCount <= 1); + viewHolder.messageBody.setAutoLinkMask(0); + Linkify.addLinks(viewHolder.messageBody, XMPP_PATTERN, "xmpp"); + viewHolder.messageBody.setAutoLinkMask(oldAutoLinkMask); + } else { + viewHolder.messageBody.setText(""); + viewHolder.messageBody.setTextIsSelectable(false); + } + viewHolder.messageBody.setTextColor(this.getMessageTextColor(viewHolder.darkBackground, true)); + viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); + viewHolder.messageBody.setOnLongClickListener(openContextMenu); } /** @@ -427,10 +412,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { String filename = UIHelper.getDisplayFilename(message); fileInfos.append((null != filename && !filename.isEmpty()) ? (filename) : ""); - int oldAutoLinkMask = viewHolder.messageBody.getAutoLinkMask(); - viewHolder.messageBody.setAutoLinkMask(0); - viewHolder.messageBody.setText(fileInfos); - viewHolder.messageBody.setAutoLinkMask(oldAutoLinkMask); + TextViewUtil.setTextWithoutAutoLink(viewHolder.messageBody, fileInfos); } private void displayDownloadableMessage(ViewHolder viewHolder, final Message message) { @@ -471,12 +453,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { btnText = activity.getString(R.string.open_x_file, UIHelper.getFileDescriptionString(activity, message)); } - this.displayDownloadButton(viewHolder, btnText, new OnClickListener() { - @Override - public void onClick(View v) { - openDownloadable(message); - } - }); + this.displayDownloadButton(viewHolder, btnText, new OpenFileOnClickListener(this.activity, message)); } @@ -485,51 +462,43 @@ public class MessageAdapter extends ArrayAdapter<Message> { viewHolder.messageBody.setVisibility(View.GONE); viewHolder.download_button.setVisibility(View.VISIBLE); viewHolder.download_button.setText(R.string.show_location); - viewHolder.download_button.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - showLocation(message); - } - }); + viewHolder.download_button.setOnClickListener(new OpenLocationOnClickListener(this.activity, message)); viewHolder.download_button.setOnLongClickListener(openContextMenu); } private void displayImageMessage(ViewHolder viewHolder, final Message message) { - if (viewHolder.download_button != null) { - viewHolder.download_button.setVisibility(View.GONE); - } + ViewUtil.gone(viewHolder.download_button); ImageUtil.loadBitmap(message, viewHolder.image, viewHolder.messageBody, true); - viewHolder.image.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - openDownloadable(message); - } - }); + viewHolder.image.setOnClickListener(new OpenFileOnClickListener(this.activity, message)); viewHolder.image.setOnLongClickListener(openContextMenu); } private View displayStatusMessage(final Message message, ViewHolder viewHolder) { - if (null != viewHolder) { - final Conversation conversation = message.getConversation(); - - viewHolder.status_message.setVisibility(View.VISIBLE); - viewHolder.contact_picture.setVisibility(View.VISIBLE); - if (conversation.getMode() == Conversation.MODE_SINGLE) { - viewHolder.contact_picture.setImageBitmap(AvatarCache.get(conversation.getContact(), - activity.getPixel(32))); - viewHolder.contact_picture.setAlpha(0.5f); - } - viewHolder.status_message.setText(message.getBody()); + final Conversation conversation = message.getConversation(); + + viewHolder.status_message.setVisibility(View.VISIBLE); + viewHolder.contact_picture.setVisibility(View.VISIBLE); + if (conversation.getMode() == Conversation.MODE_SINGLE) { + viewHolder.contact_picture.setImageBitmap(AvatarCache.get(conversation.getContact(), + activity.getPixel(32))); + viewHolder.contact_picture.setAlpha(0.5f); } + viewHolder.status_message.setText(message.getBody()); return viewHolder.view; } private void displayFileMessage(final Message message, ViewHolder viewHolder) { + if (!(message.trusted() + && MessageUtil.needsDownload(message) + && ConversationsPlusPreferences.autoAcceptFileSize() > 0 + && message.isHttpUploaded() || ConversationsPlusPreferences.autoDownloadFileLink())) { + new AutomaticFileDownload(false).transferFile(message); + } Transferable transferable = message.getTransferable(); if (FileStatus.CHECKING_FILE_SIZE == message.getFileParams().getFileStatus()) { displayInfoMessage(viewHolder, activity.getString(R.string.checking_remote_filesize)); @@ -579,31 +548,9 @@ public class MessageAdapter extends ArrayAdapter<Message> { if (null != imageView) { AvatarService.getInstance().loadAvatar(message, imageView); - imageView.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - if (MessageAdapter.this.mOnContactPictureClickedListener != null) { - MessageAdapter.this.mOnContactPictureClickedListener - .onContactPictureClicked(message); - } - - } - }); + imageView.setOnClickListener(new ContactPictureOnClickListener(this.activity, message)); if (message.getConversation().getMode() == Conversation.MODE_MULTI) { - imageView.setOnLongClickListener(new OnLongClickListener() { - - @Override - public boolean onLongClick(View v) { - if (MessageAdapter.this.mOnContactPictureLongClickedListener != null) { - MessageAdapter.this.mOnContactPictureLongClickedListener - .onContactPictureLongClicked(message); - return true; - } else { - return false; - } - } - }); + imageView.setOnLongClickListener(new ContactPictureOnLongClickListener(this.activity, message)); } } } @@ -630,7 +577,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { return activity.getLayoutInflater().inflate(viewResId, parent, false); } - private ViewHolder initializeViewHolderAndView(Message message, int type, ViewGroup parent) { + private ViewHolder initializeViewHolderAndView(int type, ViewGroup parent) { View view = initializeView(type, parent); ViewHolder viewHolder = new ViewHolder(view); if (SENT == type @@ -667,15 +614,18 @@ public class MessageAdapter extends ArrayAdapter<Message> { } @Override - public View getView(int position, View view, ViewGroup parent) { + public View getView(int position, View view, @NonNull ViewGroup parent) { final Message message = getItem(position); + if (null == message) { + return view; + } final boolean isInValidSession = message.isValidInSession(); final Conversation conversation = message.getConversation(); final Account account = conversation.getAccount(); final int type = getItemViewType(position); ViewHolder viewHolder; if (null == view) { - viewHolder = initializeViewHolderAndView(message, type, parent); + viewHolder = initializeViewHolderAndView(type, parent); view = viewHolder.view; } else { viewHolder = (ViewHolder) view.getTag(); @@ -694,33 +644,11 @@ public class MessageAdapter extends ArrayAdapter<Message> { this.displayStatus(viewHolder, message, type); if (null != message.getTransferable() || message.hasFileAttached() || MessageUtil.hasDownloadableLink(message)) { - if (!(message.trusted() - && MessageUtil.needsDownload(message) - && ConversationsPlusPreferences.autoAcceptFileSize() > 0 - && message.isHttpUploaded() || ConversationsPlusPreferences.autoDownloadFileLink())) { - new AutomaticFileDownload(false).transferFile(message); - } displayFileMessage(message, viewHolder); } else if (GeoHelper.isGeoUri(message.getBody())) { displayLocationMessage(viewHolder, message); } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { - if (activity.hasPgp()) { - if (account.getPgpDecryptionService().isRunning()) { - displayInfoMessage(viewHolder, activity.getString(R.string.message_decrypting)); - } else { - displayInfoMessage(viewHolder, activity.getString(R.string.pgp_message)); - } - } else { - displayInfoMessage(viewHolder, activity.getString(R.string.install_openkeychain)); - if (viewHolder != null) { - viewHolder.message_box.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - activity.showInstallPgpDialog(); - } - }); - } - } + displayPgpEncryptedMessage(viewHolder, account); } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) { displayDecryptionFailed(viewHolder); } else { @@ -740,67 +668,22 @@ public class MessageAdapter extends ArrayAdapter<Message> { return view; } - public void openDownloadable(Message message) { - DownloadableFile file = FileBackend.getFile(message); - if (!file.exists()) { - Toast.makeText(activity, R.string.file_deleted, Toast.LENGTH_SHORT).show(); - return; - } - boolean bInPrivateStorage = false; - if (file.getAbsolutePath().startsWith(FileBackend.getPrivateFileDirectoryPath())) { - bInPrivateStorage = true; - } - Intent openIntent = new Intent(Intent.ACTION_VIEW); - String mime = file.getMimeType(); - if (mime == null) { - mime = "*/*"; - } - Uri uri; - if (bInPrivateStorage) { - uri = ConversationsPlusFileProvider.createUriForPrivateFile(file); - } else { - uri = Uri.fromFile(file); - } - openIntent.setDataAndType(uri, mime); - PackageManager manager = activity.getPackageManager(); - List<ResolveInfo> infos = manager.queryIntentActivities(openIntent, 0); - if (bInPrivateStorage) { - for (ResolveInfo info : infos) { - ConversationsPlusApplication.getAppContext().grantUriPermission(info.activityInfo.packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); - } - } - if (infos.size() == 0) { - openIntent.setDataAndType(uri, "*/*"); - } - if (bInPrivateStorage) { - openIntent.putExtra(Intent.EXTRA_STREAM, uri); - openIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - } - try { - getContext().startActivity(openIntent); - return; - } catch (ActivityNotFoundException e) { - //ignored - } - Toast.makeText(activity, R.string.no_application_found_to_open_file, Toast.LENGTH_SHORT).show(); - } - - public void showLocation(Message message) { - for (Intent intent : GeoHelper.createGeoIntentsFromMessage(message)) { - if (intent.resolveActivity(getContext().getPackageManager()) != null) { - getContext().startActivity(intent); - return; + private void displayPgpEncryptedMessage(ViewHolder viewHolder, Account account) { + if (activity.hasPgp()) { + if (account.getPgpDecryptionService().isRunning()) { + displayInfoMessage(viewHolder, activity.getString(R.string.message_decrypting)); + } else { + displayInfoMessage(viewHolder, activity.getString(R.string.pgp_message)); } + } else { + displayInfoMessage(viewHolder, activity.getString(R.string.install_openkeychain)); + viewHolder.message_box.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + activity.showInstallPgpDialog(); + } + }); } - Toast.makeText(activity, R.string.no_application_found_to_display_location, Toast.LENGTH_SHORT).show(); - } - - public interface OnContactPictureClicked { - void onContactPictureClicked(Message message); - } - - public interface OnContactPictureLongClicked { - void onContactPictureLongClicked(Message message); } private static class ViewHolder { diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ContactPictureOnClickListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ContactPictureOnClickListener.java new file mode 100644 index 00000000..e3c85fdf --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ContactPictureOnClickListener.java @@ -0,0 +1,48 @@ +package de.thedevstack.conversationsplus.ui.listeners; + +import android.app.Activity; +import android.content.Intent; +import android.view.View; +import android.widget.Toast; + +import de.thedevstack.conversationsplus.R; +import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.entities.Conversation; +import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.ui.ConversationActivity; +import de.thedevstack.conversationsplus.ui.EditAccountActivity; + +/** + */ +public class ContactPictureOnClickListener implements View.OnClickListener { + private final ConversationActivity activity; + private final Message message; + + public ContactPictureOnClickListener(ConversationActivity activity, Message message) { + this.activity = activity; + this.message = message; + } + + @Override + public void onClick(View view) { + if (message.getStatus() <= Message.STATUS_RECEIVED) { // What does this mean? + if (message.getConversation().getMode() == Conversation.MODE_MULTI) { + if (message.getCounterpart() != null) { + String user = message.getCounterpart().isBareJid() ? message.getCounterpart().toString() : message.getCounterpart().getResourcepart(); + if (!message.getConversation().getMucOptions().isUserInRoom(user)) { + Toast.makeText(activity, activity.getString(R.string.user_has_left_conference,user),Toast.LENGTH_SHORT).show(); + } + this.activity.highlightNickInConference(user); + } + } else { + this.activity.switchToContactDetails(message.getContact(), message.getFingerprint()); + } + } else { + Account account = message.getConversation().getAccount(); + Intent intent = new Intent(activity, EditAccountActivity.class); + intent.putExtra("jid", account.getJid().toBareJid().toString()); + intent.putExtra("fingerprint", message.getFingerprint()); + this.activity.startActivity(intent); + } + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ContactPictureOnLongClickListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ContactPictureOnLongClickListener.java new file mode 100644 index 00000000..49ff764b --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ContactPictureOnLongClickListener.java @@ -0,0 +1,43 @@ +package de.thedevstack.conversationsplus.ui.listeners; + +import android.view.View; +import android.widget.Toast; + +import de.thedevstack.conversationsplus.R; +import de.thedevstack.conversationsplus.entities.Conversation; +import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.ui.ConversationActivity; +import de.thedevstack.conversationsplus.utils.ui.QrCodeUtil; + +/** + */ +public class ContactPictureOnLongClickListener implements View.OnLongClickListener { + private final ConversationActivity activity; + private final Message message; + + public ContactPictureOnLongClickListener(ConversationActivity activity, Message message) { + this.activity = activity; + this.message = message; + } + + @Override + public boolean onLongClick(View view) { + if (message.getStatus() <= Message.STATUS_RECEIVED) { + if (message.getConversation().getMode() == Conversation.MODE_MULTI) { + if (message.getCounterpart() != null) { + String user = message.getCounterpart().getResourcepart(); + if (user != null) { + if (message.getConversation().getMucOptions().isUserInRoom(user)) { + this.activity.privateMessageWith(message.getCounterpart()); + } else { + Toast.makeText(activity, activity.getString(R.string.user_has_left_conference, user), Toast.LENGTH_SHORT).show(); + } + } + } + } + } else { + QrCodeUtil.showQrCode(this.activity); + } + return true; + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/OpenFileOnClickListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/OpenFileOnClickListener.java new file mode 100644 index 00000000..e0dcd4bf --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/OpenFileOnClickListener.java @@ -0,0 +1,81 @@ +package de.thedevstack.conversationsplus.ui.listeners; + +import android.app.Activity; +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.net.Uri; +import android.view.View; +import android.widget.Toast; + +import java.util.List; + +import de.thedevstack.conversationsplus.ConversationsPlusApplication; +import de.thedevstack.conversationsplus.R; +import de.thedevstack.conversationsplus.entities.DownloadableFile; +import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.persistance.FileBackend; +import de.thedevstack.conversationsplus.providers.ConversationsPlusFileProvider; + +/** + */ +public class OpenFileOnClickListener implements View.OnClickListener { + private final Activity activity; + private final Message message; + + public OpenFileOnClickListener(Activity activity, Message message) { + this.activity = activity; + this.message = message; + } + + @Override + public void onClick(View view) { + this.openFile(); + } + + public void openFile() { + DownloadableFile file = FileBackend.getFile(message); + if (!file.exists()) { + Toast.makeText(this.activity, R.string.file_deleted, Toast.LENGTH_SHORT).show(); + return; + } + boolean bInPrivateStorage = false; + if (file.getAbsolutePath().startsWith(FileBackend.getPrivateFileDirectoryPath())) { + bInPrivateStorage = true; + } + Intent openIntent = new Intent(Intent.ACTION_VIEW); + String mime = file.getMimeType(); + if (mime == null) { + mime = "*/*"; + } + Uri uri; + if (bInPrivateStorage) { + uri = ConversationsPlusFileProvider.createUriForPrivateFile(file); + } else { + uri = Uri.fromFile(file); + } + openIntent.setDataAndType(uri, mime); + PackageManager manager = this.activity.getPackageManager(); + List<ResolveInfo> infos = manager.queryIntentActivities(openIntent, 0); + if (bInPrivateStorage) { + for (ResolveInfo info : infos) { + ConversationsPlusApplication.getAppContext().grantUriPermission(info.activityInfo.packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); + } + } + if (infos.size() == 0) { + openIntent.setDataAndType(uri, "*/*"); + } + if (bInPrivateStorage) { + openIntent.putExtra(Intent.EXTRA_STREAM, uri); + openIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } + try { + this.activity.startActivity(openIntent); + return; + } catch (ActivityNotFoundException e) { + //ignored + } + Toast.makeText(this.activity, R.string.no_application_found_to_open_file, Toast.LENGTH_SHORT).show(); + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/OpenLocationOnClickListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/OpenLocationOnClickListener.java new file mode 100644 index 00000000..8e0b7893 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/OpenLocationOnClickListener.java @@ -0,0 +1,37 @@ +package de.thedevstack.conversationsplus.ui.listeners; + +import android.app.Activity; +import android.content.Intent; +import android.view.View; +import android.widget.Toast; + +import de.thedevstack.conversationsplus.R; +import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.utils.GeoHelper; + +/** + */ +public class OpenLocationOnClickListener implements View.OnClickListener { + private final Activity activity; + private final Message message; + + public OpenLocationOnClickListener(Activity activity, Message message) { + this.activity = activity; + this.message = message; + } + + @Override + public void onClick(View view) { + this.showLocation(); + } + + private void showLocation() { + for (Intent intent : GeoHelper.createGeoIntentsFromMessage(this.message)) { + if (intent.resolveActivity(this.activity.getPackageManager()) != null) { // Only if the intent can be opened + this.activity.startActivity(intent); + return; + } + } + Toast.makeText(this.activity, R.string.no_application_found_to_display_location, Toast.LENGTH_SHORT).show(); + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/ui/QrCodeUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/ui/QrCodeUtil.java new file mode 100644 index 00000000..1c342290 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/utils/ui/QrCodeUtil.java @@ -0,0 +1,68 @@ +package de.thedevstack.conversationsplus.utils.ui; + +import android.app.AlertDialog; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.Point; +import android.widget.ImageView; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; + +import java.util.Hashtable; + +import de.thedevstack.android.logcat.Logging; +import de.thedevstack.conversationsplus.Config; +import de.thedevstack.conversationsplus.ui.XmppActivity; + +/** + */ +public final class QrCodeUtil { + + public static void showQrCode(XmppActivity activity) { + String uri = activity.getShareableUri(); + if (uri != null) { + Point size = new Point(); + activity.getWindowManager().getDefaultDisplay().getSize(size); + final int width = (size.x < size.y ? size.x : size.y); + + Bitmap bitmap = QrCodeUtil.createQrCodeBitmap(uri, width); + ImageView view = new ImageView(activity); + view.setImageBitmap(bitmap); + AlertDialog.Builder builder = new AlertDialog.Builder(activity); + builder.setView(view); + builder.create().show(); + } + } + + public static Bitmap createQrCodeBitmap(String input, int size) { + Logging.d(Config.LOGTAG,"qr code requested size: "+size); + try { + final QRCodeWriter QR_CODE_WRITER = new QRCodeWriter(); + final Hashtable<EncodeHintType, Object> hints = new Hashtable<>(); + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + final BitMatrix result = QR_CODE_WRITER.encode(input, BarcodeFormat.QR_CODE, size, size, hints); + final int width = result.getWidth(); + final int height = result.getHeight(); + final int[] pixels = new int[width * height]; + for (int y = 0; y < height; y++) { + final int offset = y * width; + for (int x = 0; x < width; x++) { + pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.TRANSPARENT; + } + } + final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + Logging.d(Config.LOGTAG,"output size: "+width+"x"+height); + bitmap.setPixels(pixels, 0, width, 0, 0, width, height); + return bitmap; + } catch (final WriterException e) { + return null; + } + } + + private QrCodeUtil() {} +} |