diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreFragment.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreFragment.java index d9846787f0..e29b7b8673 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreFragment.java @@ -1,16 +1,17 @@ package org.thoughtcrime.securesms.devicetransfer.newdevice; -import android.os.Build; import android.os.Bundle; import android.view.View; -import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.lifecycle.ViewModelProvider; import androidx.navigation.Navigation; +import org.signal.core.util.concurrent.LifecycleDisposable; import org.thoughtcrime.securesms.LoggingFragment; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.databinding.FragmentTransferRestoreBinding; import org.thoughtcrime.securesms.util.SpanUtil; import org.thoughtcrime.securesms.util.navigation.SafeNavigation; @@ -19,22 +20,42 @@ import org.thoughtcrime.securesms.util.navigation.SafeNavigation; */ public final class TransferOrRestoreFragment extends LoggingFragment { + private final LifecycleDisposable lifecycleDisposable = new LifecycleDisposable(); + + private FragmentTransferRestoreBinding binding; + public TransferOrRestoreFragment() { super(R.layout.fragment_transfer_restore); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - view.findViewById(R.id.transfer_or_restore_fragment_transfer) - .setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(v), R.id.action_new_device_transfer_instructions)); + binding = FragmentTransferRestoreBinding.bind(view); - View restoreBackup = view.findViewById(R.id.transfer_or_restore_fragment_restore); - restoreBackup.setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(v), R.id.action_choose_backup)); + TransferOrRestoreViewModel viewModel = new ViewModelProvider(this).get(TransferOrRestoreViewModel.class); + + binding.transferOrRestoreFragmentTransfer.setOnClickListener(v -> viewModel.onTransferFromAndroidDeviceSelected()); + binding.transferOrRestoreFragmentRestore.setOnClickListener(v -> viewModel.onRestoreFromLocalBackupSelected()); + binding.transferOrRestoreFragmentNext.setOnClickListener(v -> launchSelection(viewModel.getStateSnapshot())); String description = getString(R.string.TransferOrRestoreFragment__transfer_your_account_and_messages_from_your_old_android_device); String toBold = getString(R.string.TransferOrRestoreFragment__you_need_access_to_your_old_device); - TextView transferDescriptionView = view.findViewById(R.id.transfer_or_restore_fragment_transfer_description); - transferDescriptionView.setText(SpanUtil.boldSubstring(description, toBold)); + binding.transferOrRestoreFragmentTransferDescription.setText(SpanUtil.boldSubstring(description, toBold)); + + lifecycleDisposable.bindTo(getViewLifecycleOwner()); + lifecycleDisposable.add(viewModel.getState().subscribe(this::updateSelection)); + } + + private void updateSelection(TransferOrRestoreViewModel.RestorationType restorationType) { + binding.transferOrRestoreFragmentTransferCard.setSelected(restorationType == TransferOrRestoreViewModel.RestorationType.DEVICE_TRANSFER); + binding.transferOrRestoreFragmentRestoreCard.setSelected(restorationType == TransferOrRestoreViewModel.RestorationType.LOCAL_BACKUP); + } + + private void launchSelection(TransferOrRestoreViewModel.RestorationType restorationType) { + switch (restorationType) { + case DEVICE_TRANSFER -> SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), R.id.action_new_device_transfer_instructions); + case LOCAL_BACKUP -> SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), R.id.action_choose_backup); + } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreViewModel.kt new file mode 100644 index 0000000000..e6efdddbe9 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreViewModel.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2024 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.thoughtcrime.securesms.devicetransfer.newdevice + +import androidx.lifecycle.ViewModel +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.core.Flowable +import io.reactivex.rxjava3.processors.BehaviorProcessor + +/** + * Maintains state of the TransferOrRestoreFragment + */ +class TransferOrRestoreViewModel : ViewModel() { + + private val internalState = BehaviorProcessor.createDefault(RestorationType.DEVICE_TRANSFER) + + val state: Flowable = internalState.distinctUntilChanged().observeOn(AndroidSchedulers.mainThread()) + val stateSnapshot: RestorationType get() = internalState.value!! + + fun onTransferFromAndroidDeviceSelected() { + internalState.onNext(RestorationType.DEVICE_TRANSFER) + } + + fun onRestoreFromLocalBackupSelected() { + internalState.onNext(RestorationType.LOCAL_BACKUP) + } + + enum class RestorationType { + DEVICE_TRANSFER, + LOCAL_BACKUP + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/CallLogEventSendJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/CallLogEventSendJob.kt index 7c6f6ef754..b087aa260a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/CallLogEventSendJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/CallLogEventSendJob.kt @@ -6,7 +6,6 @@ package org.thoughtcrime.securesms.jobs import androidx.annotation.WorkerThread -import okio.ByteString import okio.ByteString.Companion.toByteString import org.thoughtcrime.securesms.database.CallTable import org.thoughtcrime.securesms.dependencies.ApplicationDependencies diff --git a/app/src/main/res/color/transfer_option_stroke_color_selector.xml b/app/src/main/res/color/transfer_option_stroke_color_selector.xml new file mode 100644 index 0000000000..a3edc5e38a --- /dev/null +++ b/app/src/main/res/color/transfer_option_stroke_color_selector.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/symbol_backup_light.xml b/app/src/main/res/drawable/symbol_backup_light.xml new file mode 100644 index 0000000000..6fc69d5930 --- /dev/null +++ b/app/src/main/res/drawable/symbol_backup_light.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/layout/fragment_transfer_restore.xml b/app/src/main/res/layout/fragment_transfer_restore.xml index 5fd2874571..9aea5a37eb 100644 --- a/app/src/main/res/layout/fragment_transfer_restore.xml +++ b/app/src/main/res/layout/fragment_transfer_restore.xml @@ -4,8 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:fillViewport="true" - tools:viewBindingIgnore="true"> + android:fillViewport="true"> + android:paddingBottom="24dp"> - + app:cardBackgroundColor="@color/signal_colorSurface2" + app:cardCornerRadius="12dp" + app:cardElevation="0dp" + app:strokeColor="@color/transfer_option_stroke_color_selector" + app:strokeWidth="2dp"> - + android:paddingVertical="16dp"> - + - + - + - + + + + + app:cardBackgroundColor="@color/signal_colorSurface2" + app:cardCornerRadius="12dp" + app:cardElevation="0dp" + app:strokeColor="@color/transfer_option_stroke_color_selector" + app:strokeWidth="2dp"> - + + + + + + + + + + + + + + + - - - - - - - + android:layout_gravity="end" + android:text="@string/RegistrationActivity_next" /> +