Add permissions dialogs for scheduled messages.

main
Clark 2023-01-26 14:08:26 -05:00 zatwierdzone przez Greyson Parrelli
rodzic 31bcc2e2eb
commit c5c60b7214
7 zmienionych plików z 396 dodań i 7 usunięć

Wyświetl plik

@ -20,6 +20,7 @@ import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
@ -2942,8 +2943,8 @@ public class ConversationParentFragment extends Fragment
} }
private void sendMessage(@Nullable String metricId, long scheduledDate) { private void sendMessage(@Nullable String metricId, long scheduledDate) {
if (scheduledDate != -1 && !SignalStore.uiHints().hasSeenScheduledMessagesInfoSheet()) { if (scheduledDate != -1) {
ScheduleMessageFtuxBottomSheetDialog.show(getChildFragmentManager()); ReenableScheduledMessagesDialogFragment.showIfNeeded(requireContext(), getChildFragmentManager());
} }
if (inputPanel.isRecordingInLockedMode()) { if (inputPanel.isRecordingInLockedMode()) {
inputPanel.releaseRecordingLock(); inputPanel.releaseRecordingLock();

Wyświetl plik

@ -0,0 +1,66 @@
package org.thoughtcrime.securesms.conversation
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.FragmentManager
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.FixedRoundedCornerBottomSheetDialogFragment
import org.thoughtcrime.securesms.conversation.ScheduleMessageFtuxBottomSheetDialog.Companion.show
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.util.BottomSheetUtil
import org.thoughtcrime.securesms.util.ServiceUtil
/**
* Bottom sheet dialog to prompt user to enable schedule alarms permission for scheduling messages
*/
class ReenableScheduledMessagesDialogFragment : FixedRoundedCornerBottomSheetDialogFragment() {
override val peekHeightPercentage: Float = 1f
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.reenable_scheduled_messages_dialog_fragment, container, false)
}
@SuppressLint("InlinedApi")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val launcher: ActivityResultLauncher<Intent> = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK) {
dismissAllowingStateLoss()
}
}
view.findViewById<View>(R.id.reenable_scheduled_messages_go_to_settings).setOnClickListener {
launcher.launch(Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM, Uri.parse("package:" + requireContext().packageName)))
}
}
companion object {
@JvmStatic
fun showIfNeeded(context: Context, fragmentManager: FragmentManager) {
var hasPermission = true
if (Build.VERSION.SDK_INT >= 31) {
val alarmManager = ServiceUtil.getAlarmManager(context)
hasPermission = alarmManager.canScheduleExactAlarms()
}
val fragment = if (!SignalStore.uiHints().hasSeenScheduledMessagesInfoSheet()) {
ScheduleMessageFtuxBottomSheetDialog()
} else if (!hasPermission) {
ReenableScheduledMessagesDialogFragment()
} else {
null
}
fragment?.show(fragmentManager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG)
}
}
}

Wyświetl plik

@ -1,9 +1,16 @@
package org.thoughtcrime.securesms.conversation package org.thoughtcrime.securesms.conversation
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.provider.Settings
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.FixedRoundedCornerBottomSheetDialogFragment import org.thoughtcrime.securesms.components.FixedRoundedCornerBottomSheetDialogFragment
@ -11,6 +18,7 @@ import org.thoughtcrime.securesms.components.ViewBinderDelegate
import org.thoughtcrime.securesms.databinding.ScheduleMessageFtuxBottomSheetBinding import org.thoughtcrime.securesms.databinding.ScheduleMessageFtuxBottomSheetBinding
import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.util.BottomSheetUtil import org.thoughtcrime.securesms.util.BottomSheetUtil
import org.thoughtcrime.securesms.util.ServiceUtil
class ScheduleMessageFtuxBottomSheetDialog : FixedRoundedCornerBottomSheetDialogFragment() { class ScheduleMessageFtuxBottomSheetDialog : FixedRoundedCornerBottomSheetDialogFragment() {
override val peekHeightPercentage: Float = 0.66f override val peekHeightPercentage: Float = 0.66f
@ -23,6 +31,20 @@ class ScheduleMessageFtuxBottomSheetDialog : FixedRoundedCornerBottomSheetDialog
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
if (Build.VERSION.SDK_INT >= 31 && !ServiceUtil.getAlarmManager(context).canScheduleExactAlarms()) {
binding.reenableSettings.visibility = View.VISIBLE
binding.okay.visibility = View.GONE
val launcher: ActivityResultLauncher<Intent> = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK) {
dismissAllowingStateLoss()
}
}
binding.enableScheduledMessagesGoToSettings.setOnClickListener {
SignalStore.uiHints().markHasSeenScheduledMessagesInfoSheet()
launcher.launch(Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM, Uri.parse("package:" + requireContext().packageName)))
dismiss()
}
}
binding.okay.setOnClickListener { binding.okay.setOnClickListener {
SignalStore.uiHints().markHasSeenScheduledMessagesInfoSheet() SignalStore.uiHints().markHasSeenScheduledMessagesInfoSheet()
dismiss() dismiss()

Wyświetl plik

@ -0,0 +1,154 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/handle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:importantForAccessibility="no"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/bottom_sheet_handle" />
<TextView
android:id="@+id/headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="32dp"
android:layout_marginTop="24dp"
android:gravity="center"
android:text="@string/ReenableScheduleMessagesDialogFragment_reenable_title"
android:textAppearance="@style/Signal.Text.TitleLarge"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/handle" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/circle_tintable"
android:backgroundTint="@color/signal_colorSurface3"
app:layout_constraintBottom_toBottomOf="@+id/bullet_1"
app:layout_constraintEnd_toEndOf="@+id/bullet_1"
app:layout_constraintStart_toStartOf="@+id/bullet_1"
app:layout_constraintTop_toTopOf="@+id/bullet_1" />
<TextView
android:id="@+id/bullet_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="24dp"
android:gravity="center"
android:minWidth="28dp"
android:minHeight="28dp"
android:padding="4dp"
android:text="@string/ChooseANewDefaultSmsAppFragment__bullet_1"
android:textAppearance="@style/Signal.Text.BodyMedium"
android:textColor="@color/signal_colorOnSurfaceVariant"
android:textStyle="bold"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/headline" />
<TextView
android:id="@+id/bullet_1_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="23dp"
android:layout_marginEnd="32dp"
android:minWidth="28dp"
android:minHeight="28dp"
android:padding="4dp"
android:text="@string/BackupSchedulePermissionMegaphone__tap_the_go_to_settings_button_below"
android:textAlignment="viewStart"
android:textAppearance="@style/Signal.Text.BodyLarge"
android:textColor="@color/signal_colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/bullet_1"
app:layout_constraintTop_toBottomOf="@id/headline" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/bullet_1_barrier"
android:layout_width="match_parent"
android:layout_height="1dp"
android:orientation="horizontal"
app:barrierDirection="bottom"
app:constraint_referenced_ids="bullet_1,bullet_1_text" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/circle_tintable"
android:backgroundTint="@color/signal_colorSurface3"
app:layout_constraintBottom_toBottomOf="@+id/bullet_2"
app:layout_constraintEnd_toEndOf="@+id/bullet_2"
app:layout_constraintStart_toStartOf="@+id/bullet_2"
app:layout_constraintTop_toTopOf="@+id/bullet_2" />
<TextView
android:id="@+id/bullet_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="24dp"
android:gravity="center"
android:minWidth="28dp"
android:minHeight="28dp"
android:padding="4dp"
android:text="@string/ChooseANewDefaultSmsAppFragment__bullet_2"
android:textAppearance="@style/Signal.Text.BodyMedium"
android:textColor="@color/signal_colorOnSurfaceVariant"
android:textStyle="bold"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/bullet_1_barrier" />
<TextView
android:id="@+id/bullet_2_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="23dp"
android:layout_marginEnd="32dp"
android:minWidth="28dp"
android:minHeight="28dp"
android:padding="4dp"
android:text="@string/BackupSchedulePermissionMegaphone__turn_on_allow_settings_alarms_and_reminders"
android:textAlignment="viewStart"
android:textAppearance="@style/Signal.Text.BodyLarge"
android:textColor="@color/signal_colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/bullet_2"
app:layout_constraintTop_toBottomOf="@id/bullet_1_barrier" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/bullet_2_barrier"
android:layout_width="match_parent"
android:layout_height="1dp"
android:orientation="horizontal"
app:barrierDirection="bottom"
app:constraint_referenced_ids="bullet_2,bullet_2_text" />
<com.google.android.material.button.MaterialButton
style="@style/Signal.Widget.Button.Large.Tonal"
android:id="@+id/reenable_scheduled_messages_go_to_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="32dp"
android:layout_marginBottom="24dp"
android:text="@string/BackupSchedulePermissionMegaphone__go_to_settings"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bullet_2_barrier" />
</androidx.constraintlayout.widget.ConstraintLayout>

Wyświetl plik

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat <androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
@ -40,6 +41,147 @@
android:text="@string/ScheduleMessageFTUXBottomSheet__disclaimer" android:text="@string/ScheduleMessageFTUXBottomSheet__disclaimer"
/> />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/reenable_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:orientation="vertical">
<TextView
android:id="@+id/headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="32dp"
android:layout_marginTop="24dp"
android:gravity="center"
android:text="@string/ReenableScheduleMessagesDialogFragment_reenable_title"
android:textAppearance="@style/Signal.Text.TitleMedium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:viewBindingIgnore="true"
/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="24dp"
android:gravity="center"
android:minWidth="28dp"
android:minHeight="28dp"
android:padding="4dp"
android:text="@string/ChooseANewDefaultSmsAppFragment__bullet_1"
android:background="@drawable/circle_tintable"
android:backgroundTint="@color/signal_colorSurface3"
android:textAppearance="@style/Signal.Text.BodyMedium"
android:textColor="@color/signal_colorOnSurfaceVariant"
android:textStyle="bold"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/headline"
tools:viewBindingIgnore="true"/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="23dp"
android:layout_marginEnd="32dp"
android:minWidth="28dp"
android:minHeight="28dp"
android:padding="4dp"
android:text="@string/BackupSchedulePermissionMegaphone__tap_the_go_to_settings_button_below"
android:textAlignment="viewStart"
android:textAppearance="@style/Signal.Text.BodyLarge"
android:textColor="@color/signal_colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/bullet_1"
app:layout_constraintTop_toBottomOf="@id/headline"
tools:viewBindingIgnore="true"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/bullet_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="24dp"
android:gravity="center"
android:minWidth="28dp"
android:minHeight="28dp"
android:padding="4dp"
android:text="@string/ChooseANewDefaultSmsAppFragment__bullet_2"
android:background="@drawable/circle_tintable"
android:backgroundTint="@color/signal_colorSurface3"
android:textAppearance="@style/Signal.Text.BodyMedium"
android:textColor="@color/signal_colorOnSurfaceVariant"
android:textStyle="bold"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/bullet_1_barrier"
tools:viewBindingIgnore="true"/>
<TextView
android:id="@+id/bullet_2_text"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="23dp"
android:layout_marginEnd="32dp"
android:minWidth="28dp"
android:minHeight="28dp"
android:padding="4dp"
android:text="@string/BackupSchedulePermissionMegaphone__turn_on_allow_settings_alarms_and_reminders"
android:textAlignment="viewStart"
android:textAppearance="@style/Signal.Text.BodyLarge"
android:textColor="@color/signal_colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/bullet_2"
app:layout_constraintTop_toBottomOf="@id/bullet_1_barrier"
tools:viewBindingIgnore="true"/>
<androidx.constraintlayout.widget.Barrier
android:id="@+id/bullet_2_barrier"
android:layout_width="match_parent"
android:layout_height="1dp"
android:orientation="horizontal"
app:barrierDirection="bottom"
app:constraint_referenced_ids="bullet_2,bullet_2_text"
tools:viewBindingIgnore="true"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.button.MaterialButton
style="@style/Signal.Widget.Button.Large.Tonal"
android:id="@+id/enable_scheduled_messages_go_to_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="32dp"
android:layout_marginBottom="24dp"
android:text="@string/BackupSchedulePermissionMegaphone__go_to_settings"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bullet_2_barrier" />
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/okay" android:id="@+id/okay"
style="@style/Signal.Widget.Button.Medium.Tonal" style="@style/Signal.Widget.Button.Medium.Tonal"

Wyświetl plik

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.appcompat.widget.LinearLayoutCompat
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
tools:viewBindingIgnore="true" tools:viewBindingIgnore="true"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
@ -28,6 +28,7 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
android:gravity="center" android:gravity="center"
android:layout_gravity="center_horizontal"
android:layout_marginTop="18dp" android:layout_marginTop="18dp"
android:text="@string/ScheduledMessagesBottomSheet__schedules_messages"/> android:text="@string/ScheduledMessagesBottomSheet__schedules_messages"/>
@ -51,4 +52,4 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.appcompat.widget.LinearLayoutCompat>

Wyświetl plik

@ -648,7 +648,10 @@
<string name="ScheduleMessageFTUXBottomSheet__disclaimer">When you send a scheduled message, make sure your device will be on and connected to the internet at the time of sending. If not, your message will send when your device reconnects.</string> <string name="ScheduleMessageFTUXBottomSheet__disclaimer">When you send a scheduled message, make sure your device will be on and connected to the internet at the time of sending. If not, your message will send when your device reconnects.</string>
<!-- Confirmation button text acknowledging the user understands the disclaimer --> <!-- Confirmation button text acknowledging the user understands the disclaimer -->
<string name="ScheduleMessageFTUXBottomSheet__okay">Okay</string> <string name="ScheduleMessageFTUXBottomSheet__okay">Okay</string>
<!-- Title for section asking users to allow alarm permissions for scheduled messages -->
<string name="ScheduleMessageFTUXBottomSheet_enable_title">To enable message scheduling:</string>
<!-- Title for dialog asking users to allow alarm permissions for scheduled messages -->
<string name="ReenableScheduleMessagesDialogFragment_reenable_title">To re-enable message scheduling:</string>
<!-- Title of dialog with a calendar to select the date the user wants to schedule a message. --> <!-- Title of dialog with a calendar to select the date the user wants to schedule a message. -->
<string name="ScheduleMessageTimePickerBottomSheet__select_date_title">Select date</string> <string name="ScheduleMessageTimePickerBottomSheet__select_date_title">Select date</string>
<!-- Title of dialog with a clock to select the time at which the user wants to schedule a message. --> <!-- Title of dialog with a clock to select the time at which the user wants to schedule a message. -->