diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt
index de987818a1..daade299eb 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt
@@ -74,7 +74,6 @@ import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientExporter
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.recipients.ui.bottomsheet.RecipientBottomSheetDialogFragment
-import org.thoughtcrime.securesms.recipients.ui.sharablegrouplink.ShareableGroupLinkDialogFragment
import org.thoughtcrime.securesms.util.CommunicationActions
import org.thoughtcrime.securesms.util.ContextUtil
import org.thoughtcrime.securesms.util.ExpirationUtil
@@ -615,7 +614,7 @@ class ConversationSettingsFragment : DSLSettingsFragment(
summary = DSLSettingsText.from(if (groupState.groupLinkEnabled) R.string.preferences_on else R.string.preferences_off),
icon = DSLSettingsIcon.from(R.drawable.ic_link_16),
onClick = {
- ShareableGroupLinkDialogFragment.create(groupState.groupId.requireV2()).show(parentFragmentManager, "DIALOG")
+ navController.navigate(ConversationSettingsFragmentDirections.actionConversationSettingsFragmentToShareableGroupLinkFragment(groupState.groupId.requireV2().toString()))
}
)
diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/sharablegrouplink/ShareableGroupLinkDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/sharablegrouplink/ShareableGroupLinkDialogFragment.java
deleted file mode 100644
index 48d20b1d24..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/sharablegrouplink/ShareableGroupLinkDialogFragment.java
+++ /dev/null
@@ -1,157 +0,0 @@
-package org.thoughtcrime.securesms.recipients.ui.sharablegrouplink;
-
-import android.app.AlertDialog;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import androidx.appcompat.widget.SwitchCompat;
-import androidx.appcompat.widget.Toolbar;
-import androidx.fragment.app.DialogFragment;
-import androidx.lifecycle.ViewModelProviders;
-
-import org.thoughtcrime.securesms.R;
-import org.thoughtcrime.securesms.groups.GroupId;
-import org.thoughtcrime.securesms.util.ViewUtil;
-import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
-
-public final class ShareableGroupLinkDialogFragment extends DialogFragment {
-
- private static final String ARG_GROUP_ID = "group_id";
-
- private ShareableGroupLinkViewModel viewModel;
- private GroupId.V2 groupId;
- private SimpleProgressDialog.DismissibleDialog dialog;
-
- public static DialogFragment create(@NonNull GroupId.V2 groupId) {
- DialogFragment fragment = new ShareableGroupLinkDialogFragment();
- Bundle args = new Bundle();
-
- args.putString(ARG_GROUP_ID, groupId.toString());
- fragment.setArguments(args);
-
- return fragment;
- }
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setStyle(STYLE_NO_FRAME, R.style.Signal_DayNight_Dialog_Animated);
- }
-
- @Override
- public @Nullable View onCreateView(@NonNull LayoutInflater inflater,
- @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState)
- {
- return inflater.inflate(R.layout.shareable_group_link_dialog_fragment, container, false);
- }
-
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- initializeViewModel();
- initializeViews(view);
- }
-
- private void initializeViewModel() {
- //noinspection ConstantConditions
- groupId = GroupId.parseOrThrow(requireArguments().getString(ARG_GROUP_ID)).requireV2();
-
- ShareableGroupLinkRepository repository = new ShareableGroupLinkRepository(requireContext(), groupId);
- ShareableGroupLinkViewModel.Factory factory = new ShareableGroupLinkViewModel.Factory(groupId, repository);
-
- viewModel = ViewModelProviders.of(this, factory).get(ShareableGroupLinkViewModel.class);
- }
-
- private void initializeViews(@NonNull View view) {
- SwitchCompat shareableGroupLinkSwitch = view.findViewById(R.id.shareable_group_link_enable_switch);
- TextView shareableGroupLinkDisplay = view.findViewById(R.id.shareable_group_link_display);
- View shareableGroupLinkDisplayRow = view.findViewById(R.id.shareable_group_link_display_row);
- SwitchCompat approveNewMembersSwitch = view.findViewById(R.id.shareable_group_link_approve_new_members_switch);
- View shareableGroupLinkRow = view.findViewById(R.id.shareable_group_link_row);
- View shareRow = view.findViewById(R.id.shareable_group_link_share_row);
- View resetLinkRow = view.findViewById(R.id.shareable_group_link_reset_link_row);
- View approveNewMembersRow = view.findViewById(R.id.shareable_group_link_approve_new_members_row);
- View membersSectionHeader = view.findViewById(R.id.shareable_group_link_member_requests_section_header);
- View descriptionRow = view.findViewById(R.id.shareable_group_link_display_row2);
-
- Toolbar toolbar = view.findViewById(R.id.shareable_group_link_toolbar);
-
- toolbar.setNavigationOnClickListener(v -> dismissAllowingStateLoss());
-
- viewModel.getGroupLink().observe(getViewLifecycleOwner(), groupLink -> {
- shareableGroupLinkSwitch.setChecked(groupLink.isEnabled());
- approveNewMembersSwitch.setChecked(groupLink.isRequiresApproval());
- shareableGroupLinkDisplay.setText(formatForFullWidthWrapping(groupLink.getUrl()));
-
- shareableGroupLinkDisplayRow.setVisibility(groupLink.isEnabled() ? View.VISIBLE : View.GONE);
- ViewUtil.setEnabledRecursive(shareRow, groupLink.isEnabled());
- ViewUtil.setEnabledRecursive(resetLinkRow, groupLink.isEnabled());
- ViewUtil.setEnabledRecursive(membersSectionHeader, groupLink.isEnabled());
- ViewUtil.setEnabledRecursive(approveNewMembersRow, groupLink.isEnabled());
- ViewUtil.setEnabledRecursive(descriptionRow, groupLink.isEnabled());
- });
-
- shareRow.setOnClickListener(v -> GroupLinkBottomSheetDialogFragment.show(requireFragmentManager(), groupId));
-
- viewModel.getCanEdit().observe(getViewLifecycleOwner(), canEdit -> {
- if (canEdit) {
- shareableGroupLinkRow.setOnClickListener(v -> viewModel.onToggleGroupLink());
- approveNewMembersRow.setOnClickListener(v -> viewModel.onToggleApproveMembers());
- resetLinkRow.setOnClickListener(v -> onResetGroupLink());
- } else {
- shareableGroupLinkRow.setOnClickListener(v -> toast(R.string.ManageGroupActivity_only_admins_can_enable_or_disable_the_sharable_group_link));
- approveNewMembersRow.setOnClickListener(v -> toast(R.string.ManageGroupActivity_only_admins_can_enable_or_disable_the_option_to_approve_new_members));
- resetLinkRow.setOnClickListener(v -> toast(R.string.ManageGroupActivity_only_admins_can_reset_the_sharable_group_link));
- }
- });
-
- viewModel.getToasts().observe(getViewLifecycleOwner(), this::toast);
-
- viewModel.getBusy().observe(getViewLifecycleOwner(), busy -> {
- if (busy) {
- if (dialog == null) {
- dialog = SimpleProgressDialog.showDelayed(requireContext());
- }
- } else {
- if (dialog != null) {
- dialog.dismiss();
- dialog = null;
- }
- }
- });
- }
-
- private void onResetGroupLink() {
- new AlertDialog.Builder(requireContext())
- .setMessage(R.string.ShareableGroupLinkDialogFragment__are_you_sure_you_want_to_reset_the_group_link)
- .setPositiveButton(R.string.ShareableGroupLinkDialogFragment__reset_link, (dialog, which) -> viewModel.onResetLink())
- .setNegativeButton(android.R.string.cancel, null)
- .show();
- }
-
- protected void toast(@StringRes int message) {
- Toast.makeText(requireContext(), getString(message), Toast.LENGTH_SHORT).show();
- }
-
- /**
- * Inserts zero width space characters between each character in the original ensuring it takes
- * the full width of the TextView.
- */
- private static CharSequence formatForFullWidthWrapping(@NonNull String url) {
- char[] chars = new char[url.length() * 2];
-
- for (int i = 0; i < url.length(); i++) {
- chars[i * 2] = url.charAt(i);
- chars[i * 2 + 1] = '\u200B';
- }
-
- return new String(chars);
- }
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/sharablegrouplink/ShareableGroupLinkFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/sharablegrouplink/ShareableGroupLinkFragment.kt
new file mode 100644
index 0000000000..695c5f15ea
--- /dev/null
+++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/sharablegrouplink/ShareableGroupLinkFragment.kt
@@ -0,0 +1,132 @@
+package org.thoughtcrime.securesms.recipients.ui.sharablegrouplink
+
+import android.widget.Toast
+import androidx.annotation.StringRes
+import androidx.fragment.app.viewModels
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import org.thoughtcrime.securesms.R
+import org.thoughtcrime.securesms.components.settings.DSLConfiguration
+import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter
+import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment
+import org.thoughtcrime.securesms.components.settings.DSLSettingsIcon
+import org.thoughtcrime.securesms.components.settings.DSLSettingsText
+import org.thoughtcrime.securesms.components.settings.configure
+import org.thoughtcrime.securesms.groups.GroupId
+import org.thoughtcrime.securesms.groups.v2.GroupLinkUrlAndStatus
+import org.thoughtcrime.securesms.util.livedata.LiveDataUtil
+import org.thoughtcrime.securesms.util.views.SimpleProgressDialog
+
+/**
+ * Fragment providing user options to manage group links.
+ */
+class ShareableGroupLinkFragment : DSLSettingsFragment(
+ titleId = R.string.ShareableGroupLinkDialogFragment__group_link
+) {
+
+ private var busyDialog: SimpleProgressDialog.DismissibleDialog? = null
+
+ private val groupId: GroupId.V2
+ get() = GroupId.parseOrThrow(ShareableGroupLinkFragmentArgs.fromBundle(requireArguments()).groupId).requireV2()
+
+ private val viewModel: ShareableGroupLinkViewModel by viewModels(
+ factoryProducer = {
+ val repository = ShareableGroupLinkRepository(requireContext(), groupId)
+
+ ShareableGroupLinkViewModel.Factory(groupId, repository)
+ }
+ )
+
+ override fun bindAdapter(adapter: DSLSettingsAdapter) {
+ LiveDataUtil.combineLatest(viewModel.groupLink, viewModel.canEdit) { groupLink, canEdit ->
+ Pair(groupLink, canEdit)
+ }.observe(viewLifecycleOwner) { (groupLink, canEdit) ->
+ adapter.submitList(getConfiguration(groupLink, canEdit).toMappingModelList())
+ }
+
+ viewModel.toasts.observe(viewLifecycleOwner, this::toast)
+
+ viewModel.busy.observe(
+ viewLifecycleOwner,
+ { busy ->
+ if (busy) {
+ if (busyDialog == null) {
+ busyDialog = SimpleProgressDialog.showDelayed(requireContext())
+ }
+ } else {
+ busyDialog?.dismiss()
+ busyDialog = null
+ }
+ }
+ )
+ }
+
+ private fun toast(@StringRes message: Int) {
+ Toast.makeText(requireContext(), getString(message), Toast.LENGTH_SHORT).show()
+ }
+
+ private fun getConfiguration(groupLink: GroupLinkUrlAndStatus, canEdit: Boolean): DSLConfiguration {
+ return configure {
+ switchPref(
+ title = DSLSettingsText.from(R.string.ShareableGroupLinkDialogFragment__group_link),
+ summary = if (groupLink.isEnabled) DSLSettingsText.from(formatForFullWidthWrapping(groupLink.url)) else null,
+ isChecked = groupLink.isEnabled,
+ isEnabled = canEdit,
+ onClick = {
+ viewModel.onToggleGroupLink()
+ }
+ )
+
+ clickPref(
+ title = DSLSettingsText.from(R.string.ShareableGroupLinkDialogFragment__share),
+ icon = DSLSettingsIcon.from(R.drawable.ic_share_24_tinted),
+ isEnabled = groupLink.isEnabled,
+ onClick = {
+ GroupLinkBottomSheetDialogFragment.show(childFragmentManager, groupId)
+ }
+ )
+
+ clickPref(
+ title = DSLSettingsText.from(R.string.ShareableGroupLinkDialogFragment__reset_link),
+ icon = DSLSettingsIcon.from(R.drawable.ic_reset_24_tinted),
+ isEnabled = groupLink.isEnabled && canEdit,
+ onClick = {
+ onResetGroupLink()
+ }
+ )
+
+ dividerPref()
+
+ switchPref(
+ title = DSLSettingsText.from(R.string.ShareableGroupLinkDialogFragment__approve_new_members),
+ summary = DSLSettingsText.from(R.string.ShareableGroupLinkDialogFragment__require_an_admin_to_approve_new_members_joining_via_the_group_link),
+ isEnabled = groupLink.isEnabled && canEdit,
+ isChecked = groupLink.isRequiresApproval,
+ onClick = {
+ viewModel.onToggleApproveMembers()
+ }
+ )
+ }
+ }
+
+ private fun onResetGroupLink() {
+ MaterialAlertDialogBuilder(requireContext())
+ .setMessage(R.string.ShareableGroupLinkDialogFragment__are_you_sure_you_want_to_reset_the_group_link)
+ .setPositiveButton(R.string.ShareableGroupLinkDialogFragment__reset_link) { _, _ -> viewModel.onResetLink() }
+ .setNegativeButton(android.R.string.cancel, null)
+ .show()
+ }
+
+ /**
+ * Inserts zero width space characters between each character in the original ensuring it takes
+ * the full width of the TextView.
+ */
+ private fun formatForFullWidthWrapping(url: String): CharSequence {
+ val chars = CharArray(url.length * 2)
+ for (i in url.indices) {
+ chars[i * 2] = url[i]
+ chars[i * 2 + 1] = '\u200B'
+ }
+
+ return String(chars)
+ }
+}
diff --git a/app/src/main/res/layout/group_invite_link_enable_and_share_bottom_sheet.xml b/app/src/main/res/layout/group_invite_link_enable_and_share_bottom_sheet.xml
index e2457f9817..af107e48f5 100644
--- a/app/src/main/res/layout/group_invite_link_enable_and_share_bottom_sheet.xml
+++ b/app/src/main/res/layout/group_invite_link_enable_and_share_bottom_sheet.xml
@@ -68,11 +68,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:clickable="false"
- app:layout_constraintBottom_toBottomOf="@id/shareable_group_link_enable_label"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toEndOf="@id/shareable_group_link_enable_label"
- app:layout_constraintTop_toTopOf="@id/shareable_group_link_enable_label" />
+ android:clickable="false" />
diff --git a/app/src/main/res/layout/shareable_group_link_dialog_fragment.xml b/app/src/main/res/layout/shareable_group_link_dialog_fragment.xml
deleted file mode 100644
index 73633513ab..0000000000
--- a/app/src/main/res/layout/shareable_group_link_dialog_fragment.xml
+++ /dev/null
@@ -1,235 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/navigation/conversation_settings.xml b/app/src/main/res/navigation/conversation_settings.xml
index 0bbb2c3bd5..f73195bba0 100644
--- a/app/src/main/res/navigation/conversation_settings.xml
+++ b/app/src/main/res/navigation/conversation_settings.xml
@@ -33,8 +33,8 @@
+ app:argType="java.lang.Integer"
+ app:nullable="true" />
+
+
+
+
+
+
+
+
\ No newline at end of file