mirror of
https://github.com/oxen-io/session-android.git
synced 2025-06-08 21:28:33 +00:00
Add default option to message vibrate for pre API26.
This commit is contained in:
parent
71f54701d2
commit
841ee18435
@ -170,6 +170,10 @@ public class RecipientDatabase extends Database {
|
||||
public static VibrateState fromId(int id) {
|
||||
return values()[id];
|
||||
}
|
||||
|
||||
public static VibrateState fromBoolean(boolean enabled) {
|
||||
return enabled ? ENABLED : DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
public enum RegisteredState {
|
||||
|
@ -509,8 +509,8 @@ public class NotificationChannels {
|
||||
copy.setGroup(original.getGroup());
|
||||
copy.setSound(original.getSound(), original.getAudioAttributes());
|
||||
copy.setBypassDnd(original.canBypassDnd());
|
||||
copy.enableVibration(original.shouldVibrate());
|
||||
copy.setVibrationPattern(original.getVibrationPattern());
|
||||
copy.enableVibration(original.shouldVibrate());
|
||||
copy.setLockscreenVisibility(original.getLockscreenVisibility());
|
||||
copy.setShowBadge(original.canShowBadge());
|
||||
copy.setLightColor(original.getLightColor());
|
||||
|
@ -22,6 +22,8 @@ import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
|
||||
import com.annimon.stream.function.Consumer;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
@ -43,9 +45,10 @@ public class CustomNotificationsDialogFragment extends DialogFragment {
|
||||
private View soundRow;
|
||||
private View soundLabel;
|
||||
private TextView soundSelector;
|
||||
private View vibrateRow;
|
||||
private View vibrateLabel;
|
||||
private SwitchCompat vibrateSwitch;
|
||||
private View messageVibrateRow;
|
||||
private View messageVibrateLabel;
|
||||
private TextView messageVibrateSelector;
|
||||
private SwitchCompat messageVibrateSwitch;
|
||||
private View callHeading;
|
||||
private View ringtoneRow;
|
||||
private TextView ringtoneSelector;
|
||||
@ -115,14 +118,15 @@ public class CustomNotificationsDialogFragment extends DialogFragment {
|
||||
soundRow = view.findViewById(R.id.custom_notifications_sound_row);
|
||||
soundLabel = view.findViewById(R.id.custom_notifications_sound_label);
|
||||
soundSelector = view.findViewById(R.id.custom_notifications_sound_selection);
|
||||
vibrateRow = view.findViewById(R.id.custom_notifications_vibrate_row);
|
||||
vibrateLabel = view.findViewById(R.id.custom_notifications_vibrate_label);
|
||||
vibrateSwitch = view.findViewById(R.id.custom_notifications_vibrate_switch);
|
||||
messageVibrateSwitch = view.findViewById(R.id.custom_notifications_vibrate_switch);
|
||||
messageVibrateRow = view.findViewById(R.id.custom_notifications_message_vibrate_row);
|
||||
messageVibrateLabel = view.findViewById(R.id.custom_notifications_message_vibrate_label);
|
||||
messageVibrateSelector = view.findViewById(R.id.custom_notifications_message_vibrate_selector);
|
||||
callHeading = view.findViewById(R.id.custom_notifications_call_settings_section_header);
|
||||
ringtoneRow = view.findViewById(R.id.custom_notifications_ringtone_row);
|
||||
ringtoneSelector = view.findViewById(R.id.custom_notifications_ringtone_selection);
|
||||
callVibrateRow = view.findViewById(R.id.custom_notifications_call_vibrate_row);
|
||||
callVibrateSelector = view.findViewById(R.id.custom_notifications_call_vibrate_selection);
|
||||
callVibrateSelector = view.findViewById(R.id.custom_notifications_call_vibrate_selectior);
|
||||
|
||||
Toolbar toolbar = view.findViewById(R.id.custom_notifications_toolbar);
|
||||
|
||||
@ -134,46 +138,56 @@ public class CustomNotificationsDialogFragment extends DialogFragment {
|
||||
|
||||
viewModel.isInitialLoadComplete().observe(getViewLifecycleOwner(), customNotificationsSwitch::setEnabled);
|
||||
|
||||
viewModel.hasCustomNotifications().observe(getViewLifecycleOwner(), hasCustomNotifications -> {
|
||||
if (customNotificationsSwitch.isChecked() != hasCustomNotifications) {
|
||||
customNotificationsSwitch.setOnCheckedChangeListener(null);
|
||||
customNotificationsSwitch.setChecked(hasCustomNotifications);
|
||||
}
|
||||
if (NotificationChannels.supported()) {
|
||||
viewModel.hasCustomNotifications().observe(getViewLifecycleOwner(), hasCustomNotifications -> {
|
||||
if (customNotificationsSwitch.isChecked() != hasCustomNotifications) {
|
||||
customNotificationsSwitch.setOnCheckedChangeListener(null);
|
||||
customNotificationsSwitch.setChecked(hasCustomNotifications);
|
||||
}
|
||||
|
||||
customNotificationsSwitch.setOnCheckedChangeListener(onCustomNotificationsSwitchCheckChangedListener);
|
||||
customNotificationsRow.setOnClickListener(v -> customNotificationsSwitch.toggle());
|
||||
customNotificationsSwitch.setOnCheckedChangeListener(onCustomNotificationsSwitchCheckChangedListener);
|
||||
customNotificationsRow.setOnClickListener(v -> customNotificationsSwitch.toggle());
|
||||
|
||||
soundRow.setEnabled(hasCustomNotifications);
|
||||
soundLabel.setEnabled(hasCustomNotifications);
|
||||
vibrateRow.setEnabled(hasCustomNotifications);
|
||||
vibrateLabel.setEnabled(hasCustomNotifications);
|
||||
soundSelector.setVisibility(hasCustomNotifications ? View.VISIBLE : View.GONE);
|
||||
vibrateSwitch.setVisibility(hasCustomNotifications ? View.VISIBLE : View.GONE);
|
||||
});
|
||||
soundRow.setEnabled(hasCustomNotifications);
|
||||
soundLabel.setEnabled(hasCustomNotifications);
|
||||
messageVibrateRow.setEnabled(hasCustomNotifications);
|
||||
messageVibrateLabel.setEnabled(hasCustomNotifications);
|
||||
soundSelector.setVisibility(hasCustomNotifications ? View.VISIBLE : View.GONE);
|
||||
messageVibrateSwitch.setVisibility(hasCustomNotifications ? View.VISIBLE : View.GONE);
|
||||
});
|
||||
|
||||
if (!NotificationChannels.supported()) {
|
||||
customNotificationsSwitch.setVisibility(View.GONE);
|
||||
view.findViewById(R.id.custom_notifications_enable_label).setVisibility(View.GONE);
|
||||
messageVibrateSelector.setVisibility(View.GONE);
|
||||
messageVibrateSwitch.setVisibility(View.VISIBLE);
|
||||
|
||||
messageVibrateRow.setOnClickListener(v -> messageVibrateSwitch.toggle());
|
||||
|
||||
CompoundButton.OnCheckedChangeListener onVibrateSwitchCheckChangedListener = (buttonView, isChecked) -> viewModel.setMessageVibrate(RecipientDatabase.VibrateState.fromBoolean(isChecked));
|
||||
|
||||
viewModel.getMessageVibrateToggle().observe(getViewLifecycleOwner(), vibrateEnabled -> {
|
||||
if (messageVibrateSwitch.isChecked() != vibrateEnabled) {
|
||||
messageVibrateSwitch.setOnCheckedChangeListener(null);
|
||||
messageVibrateSwitch.setChecked(vibrateEnabled);
|
||||
}
|
||||
|
||||
messageVibrateSwitch.setOnCheckedChangeListener(onVibrateSwitchCheckChangedListener);
|
||||
});
|
||||
} else {
|
||||
customNotificationsRow.setVisibility(View.GONE);
|
||||
|
||||
messageVibrateSwitch.setVisibility(View.GONE);
|
||||
messageVibrateSelector.setVisibility(View.VISIBLE);
|
||||
|
||||
soundRow.setEnabled(true);
|
||||
soundLabel.setEnabled(true);
|
||||
messageVibrateRow.setEnabled(true);
|
||||
messageVibrateLabel.setEnabled(true);
|
||||
soundSelector.setVisibility(View.VISIBLE);
|
||||
|
||||
viewModel.getMessageVibrateState().observe(getViewLifecycleOwner(), vibrateState -> presentVibrateState(vibrateState, this.messageVibrateRow, this.messageVibrateSelector, (w) -> viewModel.setMessageVibrate(w)));
|
||||
}
|
||||
|
||||
CompoundButton.OnCheckedChangeListener onVibrateSwitchCheckChangedListener = (buttonView, isChecked) -> {
|
||||
viewModel.setMessageVibrate(isChecked ? RecipientDatabase.VibrateState.ENABLED : RecipientDatabase.VibrateState.DISABLED);
|
||||
};
|
||||
|
||||
viewModel.getVibrateState().observe(getViewLifecycleOwner(), vibrateState -> {
|
||||
boolean vibrateEnabled = vibrateState != RecipientDatabase.VibrateState.DISABLED;
|
||||
|
||||
if (vibrateSwitch.isChecked() != vibrateEnabled) {
|
||||
vibrateSwitch.setOnCheckedChangeListener(null);
|
||||
vibrateSwitch.setChecked(vibrateEnabled);
|
||||
}
|
||||
|
||||
vibrateSwitch.setOnCheckedChangeListener(onVibrateSwitchCheckChangedListener);
|
||||
});
|
||||
vibrateRow.setOnClickListener(v -> vibrateSwitch.toggle());
|
||||
|
||||
viewModel.getNotificationSound().observe(getViewLifecycleOwner(), sound -> {
|
||||
soundSelector.setText(getRingtoneSummary(requireContext(), sound));
|
||||
soundSelector.setText(getRingtoneSummary(requireContext(), sound, Settings.System.DEFAULT_NOTIFICATION_URI));
|
||||
soundSelector.setTag(sound);
|
||||
soundRow.setOnClickListener(v -> launchSoundSelector(sound, false));
|
||||
});
|
||||
@ -185,26 +199,32 @@ public class CustomNotificationsDialogFragment extends DialogFragment {
|
||||
});
|
||||
|
||||
viewModel.getRingtone().observe(getViewLifecycleOwner(), sound -> {
|
||||
ringtoneSelector.setText(getRingtoneSummary(requireContext(), sound));
|
||||
ringtoneSelector.setText(getRingtoneSummary(requireContext(), sound, Settings.System.DEFAULT_RINGTONE_URI));
|
||||
ringtoneSelector.setTag(sound);
|
||||
ringtoneRow.setOnClickListener(v -> launchSoundSelector(sound, true));
|
||||
});
|
||||
|
||||
viewModel.getCallingVibrateState().observe(getViewLifecycleOwner(), vibrateState -> {
|
||||
String vibrateSummary = getVibrateSummary(requireContext(), vibrateState);
|
||||
callVibrateSelector.setText(vibrateSummary);
|
||||
callVibrateRow.setOnClickListener(v -> new AlertDialog.Builder(requireContext())
|
||||
.setTitle(R.string.CustomNotificationsDialogFragment__vibrate)
|
||||
.setSingleChoiceItems(R.array.recipient_vibrate_entries, vibrateState.ordinal(), ((dialog, which) -> {
|
||||
viewModel.setCallingVibrate(RecipientDatabase.VibrateState.fromId(which));
|
||||
dialog.dismiss();
|
||||
})).setNegativeButton(android.R.string.cancel, null)
|
||||
.show());
|
||||
});
|
||||
viewModel.getCallingVibrateState().observe(getViewLifecycleOwner(), vibrateState -> presentVibrateState(vibrateState, this.callVibrateRow, this.callVibrateSelector, (w) -> viewModel.setCallingVibrate(w)));
|
||||
}
|
||||
|
||||
private @NonNull String getRingtoneSummary(@NonNull Context context, @Nullable Uri ringtone) {
|
||||
if (ringtone == null) {
|
||||
private void presentVibrateState(@NonNull RecipientDatabase.VibrateState vibrateState,
|
||||
@NonNull View vibrateRow,
|
||||
@NonNull TextView vibrateSelector,
|
||||
@NonNull Consumer<RecipientDatabase.VibrateState> onSelect)
|
||||
{
|
||||
vibrateSelector.setText(getVibrateSummary(requireContext(), vibrateState));
|
||||
vibrateRow.setOnClickListener(v -> new AlertDialog.Builder(requireContext())
|
||||
.setTitle(R.string.CustomNotificationsDialogFragment__vibrate)
|
||||
.setSingleChoiceItems(R.array.recipient_vibrate_entries, vibrateState.ordinal(), ((dialog, which) -> {
|
||||
onSelect.accept(RecipientDatabase.VibrateState.fromId(which));
|
||||
dialog.dismiss();
|
||||
}))
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show());
|
||||
}
|
||||
|
||||
private @NonNull String getRingtoneSummary(@NonNull Context context, @Nullable Uri ringtone, @Nullable Uri defaultNotificationUri) {
|
||||
if (ringtone == null || ringtone.equals(defaultNotificationUri)) {
|
||||
return context.getString(R.string.CustomNotificationsDialogFragment__default);
|
||||
} else if (ringtone.toString().isEmpty()) {
|
||||
return context.getString(R.string.preferences__silent);
|
||||
|
@ -30,10 +30,9 @@ class CustomNotificationsRepository {
|
||||
Recipient recipient = getRecipient();
|
||||
RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context);
|
||||
|
||||
if (NotificationChannels.supported()) {
|
||||
if (NotificationChannels.supported() && recipient.getNotificationChannel() != null) {
|
||||
recipientDatabase.setMessageRingtone(recipient.getId(), NotificationChannels.getMessageRingtone(context, recipient));
|
||||
recipientDatabase.setMessageVibrate(recipient.getId(), NotificationChannels.getMessageVibrate(context, recipient) ? RecipientDatabase.VibrateState.ENABLED
|
||||
: RecipientDatabase.VibrateState.DISABLED);
|
||||
recipientDatabase.setMessageVibrate(recipient.getId(), RecipientDatabase.VibrateState.fromBoolean(NotificationChannels.getMessageVibrate(context, recipient)));
|
||||
|
||||
NotificationChannels.ensureCustomChannelConsistency(context);
|
||||
}
|
||||
|
@ -11,80 +11,95 @@ import androidx.lifecycle.ViewModel;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
public final class CustomNotificationsViewModel extends ViewModel {
|
||||
|
||||
private final LiveData<Boolean> hasCustomNotifications;
|
||||
private final LiveData<RecipientDatabase.VibrateState> isVibrateEnabled;
|
||||
private final LiveData<RecipientDatabase.VibrateState> messageVibrateState;
|
||||
private final LiveData<Uri> notificationSound;
|
||||
private final CustomNotificationsRepository repository;
|
||||
private final MutableLiveData<Boolean> isInitialLoadComplete = new MutableLiveData<>();
|
||||
private final MutableLiveData<Boolean> isInitialLoadComplete = new MutableLiveData<>();
|
||||
private final LiveData<Boolean> showCallingOptions;
|
||||
private final LiveData<Uri> ringtone;
|
||||
private final LiveData<RecipientDatabase.VibrateState> isCallingVibrateEnabled;
|
||||
private final LiveData<RecipientDatabase.VibrateState> callingVibrateState;
|
||||
private final LiveData<Boolean> messageVibrateToggle;
|
||||
|
||||
private CustomNotificationsViewModel(@NonNull RecipientId recipientId, @NonNull CustomNotificationsRepository repository) {
|
||||
LiveData<Recipient> recipient = Recipient.live(recipientId).getLiveData();
|
||||
|
||||
this.repository = repository;
|
||||
this.hasCustomNotifications = Transformations.map(recipient, r -> r.getNotificationChannel() != null || !NotificationChannels.supported());
|
||||
this.isVibrateEnabled = Transformations.map(recipient, Recipient::getMessageVibrate);
|
||||
this.notificationSound = Transformations.map(recipient, Recipient::getMessageRingtone);
|
||||
this.showCallingOptions = Transformations.map(recipient, r -> !r.isGroup() && r.isRegistered());
|
||||
this.ringtone = Transformations.map(recipient, Recipient::getCallRingtone);
|
||||
this.isCallingVibrateEnabled = Transformations.map(recipient, Recipient::getCallVibrate);
|
||||
this.repository = repository;
|
||||
this.hasCustomNotifications = Transformations.map(recipient, r -> r.getNotificationChannel() != null || !NotificationChannels.supported());
|
||||
this.callingVibrateState = Transformations.map(recipient, Recipient::getCallVibrate);
|
||||
this.messageVibrateState = Transformations.map(recipient, Recipient::getMessageVibrate);
|
||||
this.notificationSound = Transformations.map(recipient, Recipient::getMessageRingtone);
|
||||
this.showCallingOptions = Transformations.map(recipient, r -> !r.isGroup() && r.isRegistered());
|
||||
this.ringtone = Transformations.map(recipient, Recipient::getCallRingtone);
|
||||
this.messageVibrateToggle = Transformations.map(messageVibrateState, vibrateState -> {
|
||||
switch (vibrateState) {
|
||||
case DISABLED: return false;
|
||||
case ENABLED : return true;
|
||||
case DEFAULT : return TextSecurePreferences.isNotificationVibrateEnabled(ApplicationDependencies.getApplication());
|
||||
default : throw new AssertionError();
|
||||
}
|
||||
});
|
||||
|
||||
repository.onLoad(() -> isInitialLoadComplete.postValue(true));
|
||||
}
|
||||
|
||||
public LiveData<Boolean> isInitialLoadComplete() {
|
||||
LiveData<Boolean> isInitialLoadComplete() {
|
||||
return isInitialLoadComplete;
|
||||
}
|
||||
|
||||
public LiveData<Boolean> hasCustomNotifications() {
|
||||
LiveData<Boolean> hasCustomNotifications() {
|
||||
return hasCustomNotifications;
|
||||
}
|
||||
|
||||
public LiveData<RecipientDatabase.VibrateState> getVibrateState() {
|
||||
return isVibrateEnabled;
|
||||
}
|
||||
|
||||
public LiveData<Uri> getNotificationSound() {
|
||||
LiveData<Uri> getNotificationSound() {
|
||||
return notificationSound;
|
||||
}
|
||||
|
||||
public void setHasCustomNotifications(boolean hasCustomNotifications) {
|
||||
LiveData<RecipientDatabase.VibrateState> getMessageVibrateState() {
|
||||
return messageVibrateState;
|
||||
}
|
||||
|
||||
LiveData<Boolean> getMessageVibrateToggle() {
|
||||
return messageVibrateToggle;
|
||||
}
|
||||
|
||||
void setHasCustomNotifications(boolean hasCustomNotifications) {
|
||||
repository.setHasCustomNotifications(hasCustomNotifications);
|
||||
}
|
||||
|
||||
public void setMessageVibrate(@NonNull RecipientDatabase.VibrateState vibrateState) {
|
||||
void setMessageVibrate(@NonNull RecipientDatabase.VibrateState vibrateState) {
|
||||
repository.setMessageVibrate(vibrateState);
|
||||
}
|
||||
|
||||
public void setMessageSound(@Nullable Uri sound) {
|
||||
void setMessageSound(@Nullable Uri sound) {
|
||||
repository.setMessageSound(sound);
|
||||
}
|
||||
|
||||
public void setCallSound(@Nullable Uri sound) {
|
||||
void setCallSound(@Nullable Uri sound) {
|
||||
repository.setCallSound(sound);
|
||||
}
|
||||
|
||||
public LiveData<Boolean> getShowCallingOptions() {
|
||||
LiveData<Boolean> getShowCallingOptions() {
|
||||
return showCallingOptions;
|
||||
}
|
||||
|
||||
public LiveData<Uri> getRingtone() {
|
||||
LiveData<Uri> getRingtone() {
|
||||
return ringtone;
|
||||
}
|
||||
|
||||
public LiveData<RecipientDatabase.VibrateState> getCallingVibrateState() {
|
||||
return isCallingVibrateEnabled;
|
||||
LiveData<RecipientDatabase.VibrateState> getCallingVibrateState() {
|
||||
return callingVibrateState;
|
||||
}
|
||||
|
||||
public void setCallingVibrate(@NonNull RecipientDatabase.VibrateState vibrateState) {
|
||||
void setCallingVibrate(@NonNull RecipientDatabase.VibrateState vibrateState) {
|
||||
repository.setCallingVibrate(vibrateState);
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/custom_notifications_vibrate_row"
|
||||
android:id="@+id/custom_notifications_message_vibrate_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:background="?selectableItemBackground"
|
||||
@ -121,7 +121,7 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/custom_notifications_sound_row">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/custom_notifications_vibrate_label"
|
||||
android:id="@+id/custom_notifications_message_vibrate_label"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
@ -132,6 +132,17 @@
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body2" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/custom_notifications_message_vibrate_selector"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:clickable="false"
|
||||
android:textColor="?attr/colorAccent"
|
||||
android:visibility="gone"
|
||||
tools:text="Default"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/custom_notifications_vibrate_switch"
|
||||
android:layout_width="wrap_content"
|
||||
@ -154,7 +165,7 @@
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/custom_notifications_vibrate_row"
|
||||
app:layout_constraintTop_toBottomOf="@id/custom_notifications_message_vibrate_row"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<LinearLayout
|
||||
@ -221,7 +232,7 @@
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body2" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/custom_notifications_call_vibrate_selection"
|
||||
android:id="@+id/custom_notifications_call_vibrate_selectior"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
|
Loading…
x
Reference in New Issue
Block a user