Add support for announcement groups.

This commit is contained in:
Greyson Parrelli
2021-07-23 16:22:08 -04:00
parent 1a56924a56
commit 25234496bf
74 changed files with 1109 additions and 208 deletions

View File

@@ -80,6 +80,7 @@ public final class FeatureFlags {
private static final String RETRY_RESPOND_MAX_AGE = "android.retryRespondMaxAge";
private static final String SENDER_KEY = "android.senderKey.3";
private static final String SUGGEST_SMS_BLACKLIST = "android.suggestSmsBlacklist";
private static final String ANNOUNCEMENT_GROUPS = "android.announcementGroups";
/**
* We will only store remote values for flags in this set. If you want a flag to be controllable
@@ -113,7 +114,8 @@ public final class FeatureFlags {
RETRY_RECEIPT_LIFESPAN,
RETRY_RESPOND_MAX_AGE,
SENDER_KEY,
SUGGEST_SMS_BLACKLIST
SUGGEST_SMS_BLACKLIST,
ANNOUNCEMENT_GROUPS
);
@VisibleForTesting
@@ -362,6 +364,11 @@ public final class FeatureFlags {
return getBoolean(SENDER_KEY, false);
}
/** Whether or not showing the announcement group setting in the UI is enabled . */
public static boolean announcementGroups() {
return getBoolean(ANNOUNCEMENT_GROUPS, false);
}
/** A comma-delimited list of country codes that should not be told about SMS during onboarding. */
public static @NonNull String suggestSmsBlacklist() {
return getString(SUGGEST_SMS_BLACKLIST, "");

View File

@@ -0,0 +1,28 @@
package org.thoughtcrime.securesms.util
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.disposables.Disposable
/**
* A lifecycle-aware [Disposable] that, after being bound to a lifecycle, will automatically dispose all contained disposables at the proper time.
*/
class LifecycleDisposable : DefaultLifecycleObserver {
val disposables: CompositeDisposable = CompositeDisposable()
fun bindTo(lifecycle: Lifecycle): LifecycleDisposable {
lifecycle.addObserver(this)
return this
}
fun add(disposable: Disposable): LifecycleDisposable {
disposables.add(disposable)
return this
}
override fun onDestroy(owner: LifecycleOwner) {
disposables.clear()
}
}

View File

@@ -114,6 +114,44 @@ public final class SpanUtil {
return clickSubstring(learnMore, learnMore, onLearnMoreClicked, color);
}
/**
* Takes two resources:
* - one resource that has a single string placeholder
* - and another resource for a string you want to put in that placeholder with a click listener.
*
* Example:
*
* <string name="main_string">This is a %1$s string.</string>
* <string name="clickable_string">clickable</string>
*
* -> This is a clickable string.
* (where "clickable" is blue and will trigger the provided click listener when clicked)
*/
public static Spannable clickSubstring(@NonNull Context context, @StringRes int mainString, @StringRes int clickableString, @NonNull View.OnClickListener clickListener) {
String main = context.getString(mainString, SPAN_PLACE_HOLDER);
String clickable = context.getString(clickableString);
int start = main.indexOf(SPAN_PLACE_HOLDER);
int end = start + SPAN_PLACE_HOLDER.length();
Spannable spannable = new SpannableString(main.substring(0, start) + clickable + main.substring(end));
spannable.setSpan(new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
clickListener.onClick(widget);
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
}, start, start + clickable.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
return spannable;
}
public static CharSequence clickSubstring(@NonNull Context context,
@NonNull CharSequence fullString,
@NonNull CharSequence substring,