From f207251f11c7661428d1fd707b45e27d39d88985 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asiel=20D=C3=ADaz=20Ben=C3=ADtez?= Date: Wed, 31 Jan 2024 09:26:15 -0500 Subject: [PATCH] copy invite links to clipboard (#2943) * copy invite links to clipboard * rename INVITE_PAGE to INVITE_DOMAIN * share link together with QR image, improve QR image * share invite-URL instead of QR image * 'Load QR code from image' is no longer a recommended workflow the primary UI works with invite-links now. 'Load QR code from image' is still supported, but is tuned down as no longer recommended workflow. --------- Co-authored-by: B. Petersen --- res/menu/qr_scan.xml | 9 ++++----- .../securesms/ConversationListActivity.java | 10 ++-------- .../thoughtcrime/securesms/qr/QrActivity.java | 2 +- .../securesms/qr/QrShowActivity.java | 2 +- .../securesms/qr/QrShowFragment.java | 19 +++++++++++++++++-- src/org/thoughtcrime/securesms/util/Util.java | 10 ++++++++++ 6 files changed, 35 insertions(+), 17 deletions(-) diff --git a/res/menu/qr_scan.xml b/res/menu/qr_scan.xml index a6ee5a836..55361dd65 100644 --- a/res/menu/qr_scan.xml +++ b/res/menu/qr_scan.xml @@ -2,13 +2,12 @@ - - + + diff --git a/src/org/thoughtcrime/securesms/ConversationListActivity.java b/src/org/thoughtcrime/securesms/ConversationListActivity.java index c1cf85ebd..360c482f5 100644 --- a/src/org/thoughtcrime/securesms/ConversationListActivity.java +++ b/src/org/thoughtcrime/securesms/ConversationListActivity.java @@ -82,7 +82,6 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit { private static final String TAG = ConversationListActivity.class.getSimpleName(); private static final String OPENPGP4FPR = "openpgp4fpr"; - private static final String INVITE_PAGE = "i.delta.chat"; private static final String NDK_ARCH_WARNED = "ndk_arch_warned"; public static final String CLEAR_NOTIFICATIONS = "clear_notifications"; public static final String ACCOUNT_ID_EXTRA = "account_id"; @@ -409,14 +408,9 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit return; } - if (uri.getScheme().equalsIgnoreCase(OPENPGP4FPR)) { - String uriString = uri.toString().replaceFirst(OPENPGP4FPR, OPENPGP4FPR.toUpperCase()); + if (uri.getScheme().equalsIgnoreCase(OPENPGP4FPR) || Util.isInviteURL(uri)) { QrCodeHandler qrCodeHandler = new QrCodeHandler(this); - qrCodeHandler.handleQrData(uriString); - } else if (INVITE_PAGE.equals(uri.getHost()) && uri.getEncodedFragment() != null) { - String data = OPENPGP4FPR.toUpperCase() + ":" + uri.getEncodedFragment().replaceFirst("&", "#"); - QrCodeHandler qrCodeHandler = new QrCodeHandler(this); - qrCodeHandler.handleQrData(data); + qrCodeHandler.handleQrData(uri.toString()); } } } diff --git a/src/org/thoughtcrime/securesms/qr/QrActivity.java b/src/org/thoughtcrime/securesms/qr/QrActivity.java index fe2f4cf68..28d9a2315 100644 --- a/src/org/thoughtcrime/securesms/qr/QrActivity.java +++ b/src/org/thoughtcrime/securesms/qr/QrActivity.java @@ -134,7 +134,7 @@ public class QrActivity extends BaseActionBarActivity { finish(); return true; case R.id.share: - qrShowFragment.shareQr(); + qrShowFragment.shareInviteURL(); break; case R.id.copy: qrShowFragment.copyQrData(); diff --git a/src/org/thoughtcrime/securesms/qr/QrShowActivity.java b/src/org/thoughtcrime/securesms/qr/QrShowActivity.java index e86799069..51cbd9e98 100644 --- a/src/org/thoughtcrime/securesms/qr/QrShowActivity.java +++ b/src/org/thoughtcrime/securesms/qr/QrShowActivity.java @@ -87,7 +87,7 @@ public class QrShowActivity extends AppCompatActivity { finish(); return true; case R.id.share: - fragment.shareQr(); + fragment.shareInviteURL(); break; case R.id.copy: fragment.copyQrData(); diff --git a/src/org/thoughtcrime/securesms/qr/QrShowFragment.java b/src/org/thoughtcrime/securesms/qr/QrShowFragment.java index ccb1535de..1549b22ac 100644 --- a/src/org/thoughtcrime/securesms/qr/QrShowFragment.java +++ b/src/org/thoughtcrime/securesms/qr/QrShowFragment.java @@ -111,7 +111,7 @@ public class QrShowFragment extends Fragment implements DcEventCenter.DcEventDel FileOutputStream stream = new FileOutputStream(file); Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); - canvas.drawRGB(255, 255, 255); // Clear background to white + canvas.drawARGB(0,255, 255, 255); // Clear background to white SVG svg = SVG.getFromString(fixSVG(dcContext.getSecurejoinQrSvg(chatId))); svg.renderToCanvas(canvas); bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream); @@ -121,6 +121,8 @@ public class QrShowFragment extends Fragment implements DcEventCenter.DcEventDel Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("image/png"); intent.putExtra(Intent.EXTRA_STREAM, uri); + String inviteURL = Util.QrDataToInviteURL(dcContext.getSecurejoinQr(chatId)); + intent.putExtra(Intent.EXTRA_TEXT, inviteURL); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(Intent.createChooser(intent, getString(R.string.chat_share_with_title))); } catch (Exception e) { @@ -128,8 +130,21 @@ public class QrShowFragment extends Fragment implements DcEventCenter.DcEventDel } } + public void shareInviteURL() { + try { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + String inviteURL = Util.QrDataToInviteURL(dcContext.getSecurejoinQr(chatId)); + intent.putExtra(Intent.EXTRA_TEXT, inviteURL); + startActivity(Intent.createChooser(intent, getString(R.string.chat_share_with_title))); + } catch (Exception e) { + Log.e(TAG, "failed to share invite URL", e); + } + } + public void copyQrData() { - Util.writeTextToClipboard(getActivity(), DcHelper.getContext(getActivity()).getSecurejoinQr(chatId)); + String inviteURL = Util.QrDataToInviteURL(dcContext.getSecurejoinQr(chatId)); + Util.writeTextToClipboard(getActivity(), inviteURL); Toast.makeText(getActivity(), getString(R.string.copied_to_clipboard), Toast.LENGTH_SHORT).show(); } diff --git a/src/org/thoughtcrime/securesms/util/Util.java b/src/org/thoughtcrime/securesms/util/Util.java index 90f9a03af..abe0a4bf5 100644 --- a/src/org/thoughtcrime/securesms/util/Util.java +++ b/src/org/thoughtcrime/securesms/util/Util.java @@ -23,6 +23,7 @@ import android.content.ClipDescription; import android.content.Context; import android.graphics.Color; import android.graphics.Typeface; +import android.net.Uri; import android.os.AsyncTask; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; @@ -56,6 +57,7 @@ import java.util.concurrent.CountDownLatch; public class Util { private static final String TAG = Util.class.getSimpleName(); + private static final String INVITE_DOMAIN = "i.delta.chat"; public static final Handler handler = new Handler(Looper.getMainLooper()); @@ -63,6 +65,14 @@ public class Util { return value == null || value.getText() == null || TextUtils.isEmpty(value.getTextTrimmed()); } + public static boolean isInviteURL(Uri uri) { + return INVITE_DOMAIN.equals(uri.getHost()); + } + + public static String QrDataToInviteURL(String qrData) { + return "https://" + INVITE_DOMAIN + "/#" + qrData.split(":", 2)[1].replaceFirst("#", "&"); + } + public static CharSequence getBoldedString(String value) { SpannableString spanned = new SpannableString(value); spanned.setSpan(new StyleSpan(Typeface.BOLD), 0,