Add group link join version feature flag.
This commit is contained in:
parent
f18b653725
commit
92ecf2d5de
7 changed files with 127 additions and 12 deletions
|
@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
|
|||
import org.thoughtcrime.securesms.groups.v2.GroupInviteLinkUrl;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.PlayStoreUtil;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
|
||||
|
@ -91,15 +92,27 @@ public final class GroupJoinBottomSheetDialogFragment extends BottomSheetDialogF
|
|||
viewModel.getGroupDetails().observe(getViewLifecycleOwner(), details -> {
|
||||
groupName.setText(details.getGroupName());
|
||||
groupDetails.setText(requireContext().getResources().getQuantityString(R.plurals.GroupJoinBottomSheetDialogFragment_group_dot_d_members, details.getGroupMembershipCount(), details.getGroupMembershipCount()));
|
||||
groupJoinButton.setText(R.string.GroupJoinUpdateRequiredBottomSheetDialogFragment_update_signal);
|
||||
groupJoinButton.setOnClickListener(v -> {
|
||||
PlayStoreUtil.openPlayStoreOrOurApkDownloadPage(requireContext());
|
||||
dismiss();
|
||||
});
|
||||
groupJoinExplain.setText(R.string.GroupJoinUpdateRequiredBottomSheetDialogFragment_update_message);
|
||||
|
||||
switch (FeatureFlags.clientLocalGroupJoinStatus()) {
|
||||
case COMING_SOON:
|
||||
groupJoinExplain.setText(R.string.GroupJoinUpdateRequiredBottomSheetDialogFragment_coming_soon);
|
||||
groupCancelButton.setText(android.R.string.ok);
|
||||
groupJoinButton.setVisibility(View.GONE);
|
||||
break;
|
||||
case UPDATE_TO_JOIN:
|
||||
case LOCAL_CAN_JOIN:
|
||||
groupJoinExplain.setText(R.string.GroupJoinUpdateRequiredBottomSheetDialogFragment_update_message);
|
||||
groupJoinButton.setText(R.string.GroupJoinUpdateRequiredBottomSheetDialogFragment_update_signal);
|
||||
groupJoinButton.setOnClickListener(v -> {
|
||||
PlayStoreUtil.openPlayStoreOrOurApkDownloadPage(requireContext());
|
||||
dismiss();
|
||||
});
|
||||
groupJoinButton.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
}
|
||||
|
||||
avatar.setImageBytesForGroup(details.getAvatarBytes(), new FallbackPhotoProvider(), MaterialColor.STEEL);
|
||||
|
||||
groupJoinButton.setVisibility(View.VISIBLE);
|
||||
groupCancelButton.setVisibility(View.VISIBLE);
|
||||
});
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ import android.os.Bundle;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -14,11 +16,16 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
|||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.PlayStoreUtil;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
|
||||
public final class GroupJoinUpdateRequiredBottomSheetDialogFragment extends BottomSheetDialogFragment {
|
||||
|
||||
private TextView groupJoinTitle;
|
||||
private TextView groupJoinExplain;
|
||||
private Button groupJoinButton;
|
||||
|
||||
public static void show(@NonNull FragmentManager manager) {
|
||||
new GroupJoinUpdateRequiredBottomSheetDialogFragment().show(manager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG);
|
||||
}
|
||||
|
@ -34,18 +41,37 @@ public final class GroupJoinUpdateRequiredBottomSheetDialogFragment extends Bott
|
|||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.group_join_update_needed_bottom_sheet, container, false);
|
||||
View view = inflater.inflate(R.layout.group_join_update_needed_bottom_sheet, container, false);
|
||||
|
||||
groupJoinTitle = view.findViewById(R.id.group_join_update_title);
|
||||
groupJoinButton = view.findViewById(R.id.group_join_update_button);
|
||||
groupJoinExplain = view.findViewById(R.id.group_join_update_explain);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
view.findViewById(R.id.group_join_update_button)
|
||||
.setOnClickListener(v -> {
|
||||
switch (FeatureFlags.clientLocalGroupJoinStatus()) {
|
||||
case COMING_SOON:
|
||||
groupJoinTitle.setText(R.string.GroupJoinUpdateRequiredBottomSheetDialogFragment_group_links_coming_soon);
|
||||
groupJoinExplain.setText(R.string.GroupJoinUpdateRequiredBottomSheetDialogFragment_coming_soon);
|
||||
groupJoinButton.setText(android.R.string.ok);
|
||||
groupJoinButton.setOnClickListener(v -> dismiss());
|
||||
break;
|
||||
case UPDATE_TO_JOIN:
|
||||
case LOCAL_CAN_JOIN:
|
||||
groupJoinTitle.setText(R.string.GroupJoinUpdateRequiredBottomSheetDialogFragment_update_signal_to_use_group_links);
|
||||
groupJoinExplain.setText(R.string.GroupJoinUpdateRequiredBottomSheetDialogFragment_update_message);
|
||||
groupJoinButton.setText(R.string.GroupJoinUpdateRequiredBottomSheetDialogFragment_update_signal);
|
||||
groupJoinButton.setOnClickListener(v -> {
|
||||
PlayStoreUtil.openPlayStoreOrOurApkDownloadPage(requireContext());
|
||||
dismiss();
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -184,8 +184,12 @@ public class CommunicationActions {
|
|||
|
||||
handleGroupLinkUrl(activity, groupInviteLinkUrl);
|
||||
return true;
|
||||
} catch (GroupInviteLinkUrl.InvalidGroupLinkException | GroupInviteLinkUrl.UnknownGroupLinkVersionException e) {
|
||||
} catch (GroupInviteLinkUrl.InvalidGroupLinkException e) {
|
||||
Log.w(TAG, "Could not parse group URL", e);
|
||||
Toast.makeText(activity, R.string.GroupJoinUpdateRequiredBottomSheetDialogFragment_group_link_is_not_valid, Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
} catch (GroupInviteLinkUrl.UnknownGroupLinkVersionException e) {
|
||||
Log.w(TAG, "Group link is for an advanced version", e);
|
||||
GroupJoinUpdateRequiredBottomSheetDialogFragment.show(activity.getSupportFragmentManager());
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.google.android.collect.Sets;
|
|||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.thoughtcrime.securesms.BuildConfig;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob;
|
||||
import org.thoughtcrime.securesms.jobs.RefreshOwnProfileJob;
|
||||
|
@ -55,6 +56,7 @@ public final class FeatureFlags {
|
|||
private static final String GROUPS_V2_OLD_2 = "android.groupsv2.2";
|
||||
private static final String GROUPS_V2 = "android.groupsv2.3";
|
||||
private static final String GROUPS_V2_CREATE = "android.groupsv2.create.3";
|
||||
private static final String GROUPS_V2_JOIN_VERSION = "android.groupsv2.joinVersion";
|
||||
private static final String GROUPS_V2_CAPACITY = "global.groupsv2.maxGroupSize";
|
||||
private static final String CDS = "android.cds.4";
|
||||
private static final String INTERNAL_USER = "android.internalUser";
|
||||
|
@ -98,6 +100,7 @@ public final class FeatureFlags {
|
|||
private static final Set<String> HOT_SWAPPABLE = Sets.newHashSet(
|
||||
ATTACHMENTS_V3,
|
||||
GROUPS_V2_CREATE,
|
||||
GROUPS_V2_JOIN_VERSION,
|
||||
VERIFY_V2,
|
||||
CDS
|
||||
);
|
||||
|
@ -222,6 +225,30 @@ public final class FeatureFlags {
|
|||
return getInteger(GROUPS_V2_CAPACITY, 151);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ability of local client to join a GV2 group.
|
||||
* <p>
|
||||
* You must still check GV2 capabilities to respect linked devices.
|
||||
*/
|
||||
public static GroupJoinStatus clientLocalGroupJoinStatus() {
|
||||
int groupJoinVersion = getInteger(GROUPS_V2_JOIN_VERSION, 0);
|
||||
|
||||
if (groupJoinVersion == 0) return GroupJoinStatus.COMING_SOON;
|
||||
else if (groupJoinVersion > BuildConfig.CANONICAL_VERSION_CODE) return GroupJoinStatus.UPDATE_TO_JOIN;
|
||||
else return GroupJoinStatus.LOCAL_CAN_JOIN;
|
||||
}
|
||||
|
||||
public enum GroupJoinStatus {
|
||||
/** No version of the client that can join V2 groups by link is in production. */
|
||||
COMING_SOON,
|
||||
|
||||
/** A newer version of the client is in production that will allow joining via GV2 group links. */
|
||||
UPDATE_TO_JOIN,
|
||||
|
||||
/** This version of the client allows joining via GV2 group links. */
|
||||
LOCAL_CAN_JOIN
|
||||
}
|
||||
|
||||
/** Internal testing extensions. */
|
||||
public static boolean internalUser() {
|
||||
return getBoolean(INTERNAL_USER, false);
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:text="@android:string/cancel"
|
||||
android:visibility="gone"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/group_join_button"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
|
|
|
@ -660,9 +660,12 @@
|
|||
</plurals>
|
||||
|
||||
<!-- GroupJoinUpdateRequiredBottomSheetDialogFragment -->
|
||||
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_group_links_coming_soon">Group links coming soon</string>
|
||||
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_update_signal_to_use_group_links">Update Signal to use group links</string>
|
||||
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_coming_soon">Joining a group via a link is not yet supported by Signal. This feature will be released in an upcoming update.</string>
|
||||
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_update_message">The version of Signal you’re using does not support sharable group links. Update to the latest version to join this group via link.</string>
|
||||
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_update_signal">Update Signal</string>
|
||||
<string name="GroupJoinUpdateRequiredBottomSheetDialogFragment_group_link_is_not_valid">Group link is not valid</string>
|
||||
|
||||
<!-- CropImageActivity -->
|
||||
<string name="CropImageActivity_group_avatar">Group avatar</string>
|
||||
|
|
|
@ -64,6 +64,20 @@ public class FeatureFlagsTest extends BaseUnitTest {
|
|||
assertEquals(Change.ENABLED, result.getMemoryChanges().get(A));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateInternal_newValue_hotSwap_integer() {
|
||||
UpdateResult result = FeatureFlags.updateInternal(mapOf(A, 1),
|
||||
mapOf(),
|
||||
mapOf(),
|
||||
setOf(A),
|
||||
setOf(A),
|
||||
setOf());
|
||||
|
||||
assertEquals(mapOf(A, 1), result.getMemory());
|
||||
assertEquals(mapOf(A, 1), result.getDisk());
|
||||
assertEquals(Change.CHANGED, result.getMemoryChanges().get(A));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateInternal_newValue_sticky() {
|
||||
UpdateResult result = FeatureFlags.updateInternal(mapOf(A, true),
|
||||
|
@ -106,6 +120,20 @@ public class FeatureFlagsTest extends BaseUnitTest {
|
|||
assertTrue(result.getMemoryChanges().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateInternal_replaceValue_integer() {
|
||||
UpdateResult result = FeatureFlags.updateInternal(mapOf(A, 2),
|
||||
mapOf(A, 1),
|
||||
mapOf(A, 1),
|
||||
setOf(A),
|
||||
setOf(),
|
||||
setOf());
|
||||
|
||||
assertEquals(mapOf(A, 1), result.getMemory());
|
||||
assertEquals(mapOf(A, 2), result.getDisk());
|
||||
assertTrue(result.getMemoryChanges().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateInternal_replaceValue_hotSwap() {
|
||||
UpdateResult result = FeatureFlags.updateInternal(mapOf(A, true),
|
||||
|
@ -120,6 +148,20 @@ public class FeatureFlagsTest extends BaseUnitTest {
|
|||
assertEquals(Change.ENABLED, result.getMemoryChanges().get(A));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateInternal_replaceValue_hotSwa_integer() {
|
||||
UpdateResult result = FeatureFlags.updateInternal(mapOf(A, 2),
|
||||
mapOf(A, 1),
|
||||
mapOf(A, 1),
|
||||
setOf(A),
|
||||
setOf(A),
|
||||
setOf());
|
||||
|
||||
assertEquals(mapOf(A, 2), result.getMemory());
|
||||
assertEquals(mapOf(A, 2), result.getDisk());
|
||||
assertEquals(Change.CHANGED, result.getMemoryChanges().get(A));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateInternal_replaceValue_hotSwap_stickyChange() {
|
||||
UpdateResult result = FeatureFlags.updateInternal(mapOf(A, true),
|
||||
|
|
Loading…
Add table
Reference in a new issue