summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap
diff options
context:
space:
mode:
authorcyBerta <cyberta@riseup.net>2018-03-02 23:09:08 +0100
committercyBerta <cyberta@riseup.net>2018-03-02 23:09:08 +0100
commitb14e4b9a7940adb4580c0f3c7a0edcb339c73ae8 (patch)
treeb364d18a5934736c24a1667b4728fa1032b8d327 /app/src/main/java/se/leap
parent30244cbf5b7eaf6152bcdc2cb5b6848f6e10798d (diff)
#8808 adds an optional dialog that shows instruction hints for always-on vpn
Diffstat (limited to 'app/src/main/java/se/leap')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/fragments/AlwaysOnDialog.java8
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/views/IconTextView.java96
2 files changed, 102 insertions, 2 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/fragments/AlwaysOnDialog.java b/app/src/main/java/se/leap/bitmaskclient/fragments/AlwaysOnDialog.java
index 80510b86..4e8e3d79 100644
--- a/app/src/main/java/se/leap/bitmaskclient/fragments/AlwaysOnDialog.java
+++ b/app/src/main/java/se/leap/bitmaskclient/fragments/AlwaysOnDialog.java
@@ -15,6 +15,7 @@ import android.widget.CheckBox;
import butterknife.ButterKnife;
import butterknife.InjectView;
import se.leap.bitmaskclient.R;
+import se.leap.bitmaskclient.views.IconTextView;
import static se.leap.bitmaskclient.ConfigHelper.saveShowAlwaysOnDialog;
@@ -31,6 +32,9 @@ public class AlwaysOnDialog extends AppCompatDialogFragment {
@InjectView(R.id.do_not_show_again)
CheckBox doNotShowAgainCheckBox;
+ @InjectView(R.id.user_message)
+ IconTextView userMessage;
+
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -44,8 +48,9 @@ public class AlwaysOnDialog extends AppCompatDialogFragment {
View view = inflater.inflate(R.layout.checkbox_confirm_dialog, null);
ButterKnife.inject(this, view);
+ userMessage.setIcon(R.drawable.ic_settings);
+ userMessage.setText(getString(R.string.always_on_vpn_user_message));
builder.setView(view)
- .setMessage(R.string.always_on_vpn_user_message)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (doNotShowAgainCheckBox.isChecked()) {
@@ -61,7 +66,6 @@ public class AlwaysOnDialog extends AppCompatDialogFragment {
dialog.cancel();
}
});
- // Create the AlertDialog object and return it
return builder.create();
}
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/views/IconTextView.java b/app/src/main/java/se/leap/bitmaskclient/views/IconTextView.java
new file mode 100644
index 00000000..0af33c68
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/views/IconTextView.java
@@ -0,0 +1,96 @@
+package se.leap.bitmaskclient.views;
+
+
+import android.content.Context;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.support.v7.widget.AppCompatTextView;
+import android.text.Spannable;
+import android.text.style.ImageSpan;
+import android.util.AttributeSet;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class IconTextView extends AppCompatTextView {
+
+ private int imageResource = 0;
+ /**
+ * Regex pattern that looks for embedded images of the format: [img src=imageName/]
+ */
+ public static final String PATTERN = "\\Q[img src]\\E";
+
+ public IconTextView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public IconTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public IconTextView(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void setText(CharSequence text, BufferType type) {
+ final Spannable spannable = getTextWithImages(getContext(), text, getLineHeight(), getCurrentTextColor());
+ super.setText(spannable, BufferType.SPANNABLE);
+ }
+
+ public void setIcon(int imageResource) {
+ this.imageResource = imageResource;
+ }
+
+ private Spannable getTextWithImages(Context context, CharSequence text, int lineHeight, int colour) {
+ final Spannable spannable = Spannable.Factory.getInstance().newSpannable(text);
+ addImages(context, spannable, lineHeight, colour);
+ return spannable;
+ }
+
+ private void addImages(Context context, Spannable spannable, int lineHeight, int colour) {
+ final Pattern refImg = Pattern.compile(PATTERN);
+
+ final Matcher matcher = refImg.matcher(spannable);
+ while (matcher.find()) {
+ boolean set = true;
+ for (ImageSpan span : spannable.getSpans(matcher.start(), matcher.end(), ImageSpan.class)) {
+ if (spannable.getSpanStart(span) >= matcher.start()
+ && spannable.getSpanEnd(span) <= matcher.end()) {
+ spannable.removeSpan(span);
+ } else {
+ set = false;
+ break;
+ }
+ }
+ if (set && imageResource != 0) {
+ spannable.setSpan(makeImageSpan(context, imageResource, lineHeight, colour),
+ matcher.start(),
+ matcher.end(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+ );
+ }
+ }
+ }
+
+ /**
+ * Create an ImageSpan for the given icon drawable. This also sets the image size and colour.
+ * Works best with a white, square icon because of the colouring and resizing.
+ *
+ * @param context The Android Context.
+ * @param drawableResId A drawable resource Id.
+ * @param size The desired size (i.e. width and height) of the image icon in pixels.
+ * Use the lineHeight of the TextView to make the image inline with the
+ * surrounding text.
+ * @param colour The colour (careful: NOT a resource Id) to apply to the image.
+ * @return An ImageSpan, aligned with the bottom of the text.
+ */
+ private ImageSpan makeImageSpan(Context context, int drawableResId, int size, int colour) {
+ final Drawable drawable = context.getResources().getDrawable(drawableResId);
+ drawable.mutate();
+ drawable.setColorFilter(colour, PorterDuff.Mode.MULTIPLY);
+ drawable.setBounds(0, 0, size, size);
+ return new ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM);
+ }
+
+} \ No newline at end of file