diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java index 3b1e91ef9..5ac645722 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java @@ -27,6 +27,7 @@ import org.briarproject.briar.android.contact.add.remote.NicknameFragment; import org.briarproject.briar.android.contact.add.remote.PendingContactListActivity; import org.briarproject.briar.android.conversation.AliasDialogFragment; import org.briarproject.briar.android.conversation.ConversationActivity; +import org.briarproject.briar.android.conversation.ConversationSettingsDialog; import org.briarproject.briar.android.conversation.ImageActivity; import org.briarproject.briar.android.conversation.ImageFragment; import org.briarproject.briar.android.forum.CreateForumActivity; @@ -238,4 +239,6 @@ public interface ActivityComponent { void inject(ConfirmAvatarDialogFragment fragment); + void inject(ConversationSettingsDialog dialog); + } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/AliasDialogFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/AliasDialogFragment.java index 30df0ecad..8db22b212 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/AliasDialogFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/AliasDialogFragment.java @@ -31,6 +31,8 @@ import static org.briarproject.briar.android.util.UiUtils.showSoftKeyboard; @MethodsNotNullByDefault @ParametersNotNullByDefault +// TODO: we can probably switch to androidx DialogFragment here but need to +// test this properly public class AliasDialogFragment extends AppCompatDialogFragment { final static String TAG = AliasDialogFragment.class.getName(); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java index 5b45365c2..375a72d70 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java @@ -50,6 +50,7 @@ import org.briarproject.briar.android.blog.BlogActivity; import org.briarproject.briar.android.conversation.ConversationVisitor.AttachmentCache; import org.briarproject.briar.android.conversation.ConversationVisitor.TextCache; import org.briarproject.briar.android.forum.ForumActivity; +import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener; import org.briarproject.briar.android.introduction.IntroductionActivity; import org.briarproject.briar.android.privategroup.conversation.GroupActivity; import org.briarproject.briar.android.util.BriarSnackbarBuilder; @@ -136,7 +137,6 @@ import static org.briarproject.briar.android.conversation.ImageActivity.ITEM_ID; import static org.briarproject.briar.android.conversation.ImageActivity.NAME; import static org.briarproject.briar.android.util.UiUtils.observeOnce; import static org.briarproject.briar.android.view.AuthorView.setAvatar; -import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER; import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_ATTACHMENTS_PER_MESSAGE; import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_TEXT_LENGTH; import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_IMAGES_AUTO_DELETE; @@ -145,8 +145,8 @@ import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_ONL @MethodsNotNullByDefault @ParametersNotNullByDefault public class ConversationActivity extends BriarActivity - implements EventListener, ConversationListener, TextCache, - AttachmentCache, AttachmentListener, ActionMode.Callback { + implements BaseFragmentListener, EventListener, ConversationListener, + TextCache, AttachmentCache, AttachmentListener, ActionMode.Callback { public static final String CONTACT_ID = "briar.CONTACT_ID"; @@ -374,10 +374,8 @@ public class ConversationActivity extends BriarActivity // show auto-delete timer setting only, if contacts supports it observeOnce(viewModel.getPrivateMessageFormat(), this, format -> { boolean visible = format == TEXT_IMAGES_AUTO_DELETE; - MenuItem item = menu.findItem(R.id.action_auto_delete); + MenuItem item = menu.findItem(R.id.action_conversation_settings); item.setVisible(visible); - viewModel.getAutoDeleteTimer().observe(this, timer -> - item.setChecked(timer != NO_AUTO_DELETE_TIMER)); }); return super.onCreateOptionsMenu(menu); @@ -400,10 +398,12 @@ public class ConversationActivity extends BriarActivity AliasDialogFragment.newInstance().show( getSupportFragmentManager(), AliasDialogFragment.TAG); return true; - case R.id.action_auto_delete: - boolean enabled = !item.isChecked(); - viewModel.setAutoDeleteTimerEnabled(enabled); - item.setChecked(enabled); + case R.id.action_conversation_settings: + if (contactId == null) return false; + ConversationSettingsDialog dialog = + ConversationSettingsDialog.newInstance(contactId); + dialog.show(getSupportFragmentManager(), + ConversationSettingsDialog.TAG); return true; case R.id.action_delete_all_messages: askToDeleteAllMessages(); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationSettingsDialog.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationSettingsDialog.java new file mode 100644 index 000000000..0f38d964e --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationSettingsDialog.java @@ -0,0 +1,122 @@ +package org.briarproject.briar.android.conversation; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; +import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; +import org.briarproject.briar.R; +import org.briarproject.briar.android.activity.ActivityComponent; +import org.briarproject.briar.android.fragment.BaseFragment; + +import java.util.logging.Logger; + +import javax.inject.Inject; + +import androidx.annotation.Nullable; +import androidx.appcompat.widget.SwitchCompat; +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentActivity; +import androidx.lifecycle.ViewModelProvider; + +import static org.briarproject.briar.android.conversation.ConversationActivity.CONTACT_ID; +import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER; + +@MethodsNotNullByDefault +@ParametersNotNullByDefault +public class ConversationSettingsDialog extends DialogFragment { + + final static String TAG = ConversationSettingsDialog.class.getName(); + + private static final Logger LOG = Logger.getLogger(TAG); + + @Inject + ViewModelProvider.Factory viewModelFactory; + + private ConversationViewModel viewModel; + + static ConversationSettingsDialog newInstance(ContactId contactId) { + Bundle args = new Bundle(); + args.putInt(CONTACT_ID, contactId.getInt()); + ConversationSettingsDialog dialog = new ConversationSettingsDialog(); + dialog.setArguments(args); + return dialog; + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + injectFragment(((BaseFragment.BaseFragmentListener) context) + .getActivityComponent()); + } + + public void injectFragment(ActivityComponent component) { + component.inject(this); + viewModel = new ViewModelProvider(requireActivity(), viewModelFactory) + .get(ConversationViewModel.class); + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setStyle(DialogFragment.STYLE_NO_FRAME, + R.style.BriarFullScreenDialogTheme); + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_conversation_settings, + container, false); + + Bundle args = requireArguments(); + int id = args.getInt(CONTACT_ID, -1); + if (id == -1) throw new IllegalStateException(); + ContactId contactId = new ContactId(id); + + FragmentActivity activity = requireActivity(); + viewModel = new ViewModelProvider(activity, viewModelFactory) + .get(ConversationViewModel.class); + viewModel.setContactId(contactId); + + Toolbar toolbar = view.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(v -> dismiss()); + + SwitchCompat switchDisappearingMessages = view.findViewById( + R.id.switchDisappearingMessages); + switchDisappearingMessages.setOnCheckedChangeListener( + (button, value) -> viewModel.setAutoDeleteTimerEnabled(value)); + + TextView buttonLearnMore = + view.findViewById(R.id.buttonLearnMore); + buttonLearnMore.setOnClickListener(e -> showLearnMoreDialog()); + + viewModel.getAutoDeleteTimer() + .observe(getViewLifecycleOwner(), timer -> { + LOG.info("Received auto delete timer: " + timer); + boolean disappearingMessages = + timer != NO_AUTO_DELETE_TIMER; + switchDisappearingMessages + .setChecked(disappearingMessages); + switchDisappearingMessages.setEnabled(true); + }); + + return view; + } + + private void showLearnMoreDialog() { + ConversationSettingsLearnMoreDialog + dialog = new ConversationSettingsLearnMoreDialog(); + dialog.show(getChildFragmentManager(), + ConversationSettingsLearnMoreDialog.TAG); + } + +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationSettingsLearnMoreDialog.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationSettingsLearnMoreDialog.java new file mode 100644 index 000000000..5f5b960fd --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationSettingsLearnMoreDialog.java @@ -0,0 +1,43 @@ +package org.briarproject.briar.android.conversation; + +import android.app.Dialog; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; + +import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; +import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; +import org.briarproject.briar.R; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentActivity; + +@MethodsNotNullByDefault +@ParametersNotNullByDefault +public class ConversationSettingsLearnMoreDialog extends DialogFragment { + + final static String TAG = + ConversationSettingsLearnMoreDialog.class.getName(); + + @Override + public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + FragmentActivity activity = requireActivity(); + + AlertDialog.Builder builder = new AlertDialog.Builder(activity, + R.style.OnboardingDialogTheme); + + LayoutInflater inflater = LayoutInflater.from(builder.getContext()); + View view = inflater.inflate( + R.layout.fragment_conversation_settings_learn_more, null); + builder.setView(view); + + builder.setTitle(R.string.disappearing_messages_title); + builder.setPositiveButton(R.string.ok, null); + + return builder.create(); + } + + +} diff --git a/briar-android/src/main/res/layout/fragment_conversation_settings.xml b/briar-android/src/main/res/layout/fragment_conversation_settings.xml new file mode 100644 index 000000000..c363d9b09 --- /dev/null +++ b/briar-android/src/main/res/layout/fragment_conversation_settings.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/briar-android/src/main/res/layout/fragment_conversation_settings_learn_more.xml b/briar-android/src/main/res/layout/fragment_conversation_settings_learn_more.xml new file mode 100644 index 000000000..3e3c6260d --- /dev/null +++ b/briar-android/src/main/res/layout/fragment_conversation_settings_learn_more.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/briar-android/src/main/res/menu/conversation_actions.xml b/briar-android/src/main/res/menu/conversation_actions.xml index 8695171fa..f3d057b08 100644 --- a/briar-android/src/main/res/menu/conversation_actions.xml +++ b/briar-android/src/main/res/menu/conversation_actions.xml @@ -17,9 +17,8 @@ app:showAsAction="never" /> diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index ef571e9f7..92f19a768 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -166,7 +166,7 @@ Image format unsupported: %s Change contact name Contact name - Disappearing messages + Disappearing messages Your messages will disappear after 7 days. Your messages will not disappear. %1$s\'s messages will disappear after 7 days. @@ -557,6 +557,19 @@ Choose ringtone Cannot load ringtone + + Disappearing messages + Turning on this setting will make new + messages in this conversation automatically disappear 7\u00A0days after being received. + This applies to messages you send to your contact as well as messages your contact sends to you. + Your contact can also change this setting for the both of you. + \n\nMessages that will disappear are marked with a bomb icon. + \n\nKeep in mind that recipients can still make copies of the messages you send. + \n\nIf you change this setting, it will apply to your messages immediately and to your + contact\'s messages once they receive your next message. + Learn more + Make future messages in this conversation automatically disappear 7\u00A0days after being received. + Feedback Send feedback diff --git a/briar-android/src/main/res/values/themes.xml b/briar-android/src/main/res/values/themes.xml index 211fe6ebc..72eac331f 100644 --- a/briar-android/src/main/res/values/themes.xml +++ b/briar-android/src/main/res/values/themes.xml @@ -43,6 +43,16 @@ true + + + +