Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Custom Vibrate Patterns to Settings #1169

Closed
wants to merge 11 commits into from
50 changes: 50 additions & 0 deletions res/layout/vibrate_pattern_dialog.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/CustomVibrateLinearLayout"
android:layout_width="fill_parent"
android:orientation="vertical"
android:paddingLeft="5sp"
android:paddingRight="5sp">
<ScrollView
android:id="@+id/CustomVibrateScrollView"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<LinearLayout
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_width="fill_parent"
android:id="@+id/ScrollViewLinearLayout"
android:paddingLeft="5sp"
android:paddingRight="5sp"
android:paddingBottom="2sp"
android:paddingTop="2sp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="left"
android:layout_weight="1">
<TextView
android:id="@+id/VibratePatternLabel"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/preferences__pref_vibrate_custom_pattern_discription"
android:paddingTop="5sp" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="left"
android:layout_weight="1">
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/editTextPattern"
android:inputType="textNoSuggestions"
android:digits="0123456789, "/>
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
22 changes: 21 additions & 1 deletion res/values/arrays.xml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
<item>white</item>
<item>none</item>
</string-array>

<string-array name="pref_led_blink_pattern_entries">
<item>@string/preferences__fast</item>
<item>@string/preferences__normal</item>
Expand All @@ -125,6 +125,26 @@
<item>custom</item>
</string-array>

<string-array name="pref_vibrate_entries">
<item>@string/preferences__default</item>
<item>@string/preferences__pref_vibrate_2x_Short</item>
<item>@string/preferences__pref_vibrate_2x_Long</item>
<item>@string/preferences__pref_vibrate_3x_Short</item>
<item>@string/preferences__pref_vibrate_3x_Long</item>
<item>@string/preferences__custom</item>
<item>@string/preferences__pref_disabled</item>
</string-array>

<string-array name="pref_vibrate_values" translatable="false">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default/custom/disabled are all translatable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this are the vaules, they are never displayed. The pref_vibrate_entries above are displayed. Should I really remove the translatable=false?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no you're totally right, sorry I mixed the entries with values when I was speed reading :)

<item>default</item>
<item>0,300,200,300</item>
<item>0,750,400,750</item>
<item>0,300,200,300,200,300</item>
<item>0,750,400,750,400,750</item>
<item>custom</item>
<item>disabled</item>
</string-array>

<string-array name="navigation_drawer_text">
<item>@string/arrays__import_export</item>
<item>@string/arrays__my_identity_key</item>
Expand Down
13 changes: 11 additions & 2 deletions res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -702,12 +702,21 @@
<string name="preferences__pref_led_blink_custom_pattern_on_for">On For:</string>
<string name="preferences__pref_led_blink_custom_pattern_off_for">Off For:</string>
<string name="preferences__pref_led_blink_custom_pattern_set">Custom LED blink pattern set!</string>
<string name="preferences__pref_vibrate_title">Vibrate pattern</string>
<string name="preferences__pref_vibrate_2x_Short">2x short</string>
<string name="preferences__pref_vibrate_2x_Long">2x long</string>
<string name="preferences__pref_vibrate_3x_Short">3x short</string>
<string name="preferences__pref_vibrate_3x_Long">3x long</string>
<string name="preferences__pref_disabled">Disabled</string>
<string name="preferences__pref_vibrate_custom_pattern_test">Test</string>
<string name="preferences__pref_vibrate_custom_pattern_set">Custom vibrate pattern set!</string>
<string name="preferences__pref_vibrate_custom_pattern_title">Custom vibrate pattern</string>
<string name="preferences__pref_vibrate_custom_pattern_wrong">Wrong format of vibrate pattern!</string>
<string name="preferences__pref_vibrate_custom_pattern_discription">&lt;Time off&gt;,&lt;Time on&gt;,... (in ms)\n\nExample: 0,500,100,500</string>
<string name="preferences__sound">Sound</string>
<string name="preferences__change_notification_sound">Change notification sound</string>
<string name="preferences__inthread_notifications">In-thread notifications</string>
<string name="preferences__play_inthread_notifications">Play notification sound when viewing an active conversation.</string>
<string name="preferences__vibrate">Vibrate</string>
<string name="preferences__also_vibrate_when_notified">Also vibrate when notified</string>
<string name="preferences__minutes">minutes</string>
<string name="preferences__hours">hours</string>
<string name="preferences__green">Green</string>
Expand Down
12 changes: 7 additions & 5 deletions res/xml/preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,13 @@
android:dependency="pref_key_enable_notifications"
android:defaultValue="true" />

<CheckBoxPreference android:dependency="pref_key_enable_notifications"
android:key="pref_key_vibrate"
android:defaultValue="true"
android:title="@string/preferences__vibrate"
android:summary="@string/preferences__also_vibrate_when_notified" />
<org.thoughtcrime.securesms.preferences.VibratePatternListPreference
android:key="pref_vibrate"
android:defaultValue="default"
android:title="@string/preferences__pref_vibrate_title"
android:dependency="pref_key_enable_notifications"
android:entries="@array/pref_vibrate_entries"
android:entryValues="@array/pref_vibrate_values" />

</PreferenceCategory>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ protected void onCreate(Bundle icicle) {
.setOnPreferenceChangeListener(new ListSummaryListener());
this.findPreference(TextSecurePreferences.LED_BLINK_PREF)
.setOnPreferenceChangeListener(new ListSummaryListener());
this.findPreference(TextSecurePreferences.VIBRATE_PREF)
.setOnPreferenceChangeListener(new ListSummaryListener());
this.findPreference(TextSecurePreferences.RINGTONE_PREF)
.setOnPreferenceChangeListener(new RingtoneSummaryListener());
this.findPreference(UPDATE_DIRECTORY_PREF)
Expand All @@ -132,6 +134,7 @@ protected void onCreate(Bundle icicle) {
initializeOutgoingSmsSummary((OutgoingSmsPreference) findPreference(OUTGOING_SMS_PREF));
initializeListSummary((ListPreference) findPreference(TextSecurePreferences.LED_COLOR_PREF));
initializeListSummary((ListPreference) findPreference(TextSecurePreferences.LED_BLINK_PREF));
initializeListSummary((ListPreference) findPreference(TextSecurePreferences.VIBRATE_PREF));
initializeRingtoneSummary((RingtonePreference) findPreference(TextSecurePreferences.RINGTONE_PREF));
}

Expand Down
21 changes: 18 additions & 3 deletions src/org/thoughtcrime/securesms/notifications/MessageNotifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import org.whispersystems.textsecure.push.IncomingPushMessage;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
Expand Down Expand Up @@ -353,16 +354,19 @@ private static void setNotificationAlarms(Context context,
boolean signal)
{
String ringtone = TextSecurePreferences.getNotificationRingtone(context);
boolean vibrate = TextSecurePreferences.isNotificationVibrateEnabled(context);
String vibrate = TextSecurePreferences.getNotificationVibrate(context);
String vibratePatternCustom = TextSecurePreferences.getNotificationVibratePatternCustom(context);
String ledColor = TextSecurePreferences.getNotificationLedColor(context);
String ledBlinkPattern = TextSecurePreferences.getNotificationLedPattern(context);
String ledBlinkPatternCustom = TextSecurePreferences.getNotificationLedPatternCustom(context);
String[] blinkPatternArray = parseBlinkPattern(ledBlinkPattern, ledBlinkPatternCustom);

builder.setSound(TextUtils.isEmpty(ringtone) || !signal ? null : Uri.parse(ringtone));

if (signal && vibrate) {
builder.setDefaults(Notification.DEFAULT_VIBRATE);
if (signal && !vibrate.equals("disabled")) {
if (vibrate.equals("default")) builder.setDefaults(Notification.DEFAULT_VIBRATE);
else if (vibrate.equals("custom")) builder.setVibrate(parseVibratePattern(vibratePatternCustom));
else builder.setVibrate(parseVibratePattern(vibrate));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it necessary to have both a vibrate and a vibrate custom? Can you put the custom pattern in the same preference?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I would save the custom pattern in the vibrate preference, how can I then display "custom" in the ListPreference?

}

if (!ledColor.equals("none")) {
Expand All @@ -372,6 +376,17 @@ private static void setNotificationAlarms(Context context,
}
}

public static long[] parseVibratePattern(String vibratePattern) {
String[] vibratePatternCustomArrayString = vibratePattern.split(",");
long[] vibratePatternCustomArray = new long[vibratePatternCustomArrayString.length];

for (int i = 0; i < vibratePatternCustomArrayString.length; i++) {
vibratePatternCustomArray[i] = Long.parseLong(vibratePatternCustomArrayString[i].trim());
}

return vibratePatternCustomArray;
}

private static String[] parseBlinkPattern(String blinkPattern, String blinkPatternCustom) {
if (blinkPattern.equals("custom"))
blinkPattern = blinkPatternCustom;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
/**
* Copyright (C) 2014 Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms.preferences;

import android.app.AlertDialog;
import android.os.Vibrator;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Parcelable;
import android.preference.ListPreference;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Dialogs;

/**
* List preference for Vibrate Pattern
*
* @author agrajaghh
*/

public class VibratePatternListPreference extends ListPreference {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like this class could be more concise.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, it seems quite big, but I copied it from LedBlinkPatternListPreference and dont know how to make it shorter :(


private Context context;

private EditText vibratePatternEditText;

private boolean dialogInProgress;

public VibratePatternListPreference(Context context) {
super(context);
this.context = context;
TextSecurePreferences.migrateNotificationVibrate(context);
}

public VibratePatternListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
TextSecurePreferences.migrateNotificationVibrate(context);
}

@Override
protected void onDialogClosed(boolean positiveResult) {
String previousSetting = getValue();
super.onDialogClosed(positiveResult);

if (positiveResult && getValue().equals("custom")) {
setValue(previousSetting);
callChangeListener(previousSetting);

showDialog();
}
}

@Override
public CharSequence getSummary() {
if (getValue().equals("custom")) {
return getEntry() + ": " + TextSecurePreferences.getNotificationVibratePatternCustom(context);
} else {
return super.getSummary();
}
}

private void showDialog() {
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.vibrate_pattern_dialog, null);
this.vibratePatternEditText = (EditText)view.findViewById(R.id.editTextPattern);

initializeDialog(view);
vibratePatternEditText.setText(TextSecurePreferences.getNotificationVibratePatternCustom(context));
dialogInProgress = true;
}

private void initializeDialog(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setIcon(Dialogs.resolveIcon(context, R.attr.dialog_info_icon));
builder.setTitle(R.string.preferences__pref_vibrate_custom_pattern_title);
builder.setView(view);
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel (DialogInterface dialog){
dialogInProgress = false;
}
});
builder.setPositiveButton(android.R.string.ok, new EmptyClickListener());
builder.setNeutralButton(R.string.preferences__pref_vibrate_custom_pattern_test, new EmptyClickListener());
builder.setNegativeButton(android.R.string.cancel, new EmptyClickListener());
builder.setInverseBackgroundForced(true);

AlertDialog dialog = builder.show();
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new OkayListener(dialog));
dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(new TestListener(context));
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new CancelListener(dialog));
}

private class EmptyClickListener implements DialogInterface.OnClickListener {
@Override
public void onClick(DialogInterface dialog, int which) { }
}

private class OkayListener implements View.OnClickListener {
private AlertDialog dialog;
public OkayListener( AlertDialog dialog) { this.dialog = dialog; }

@Override
public void onClick(View view) {
final String vibratePattern = vibratePatternEditText.getText().toString();

try {
MessageNotifier.parseVibratePattern(vibratePattern);
TextSecurePreferences.setNotificationVibratePatternCustom(context, vibratePattern);
setValue("custom");
callChangeListener("custom");
Toast.makeText(context, R.string.preferences__pref_vibrate_custom_pattern_set, Toast.LENGTH_LONG).show();
dialog.dismiss();
dialogInProgress = false;
} catch (NumberFormatException e) {
Toast.makeText(context, R.string.preferences__pref_vibrate_custom_pattern_wrong, Toast.LENGTH_LONG).show();
}
}
}

private class TestListener implements View.OnClickListener {
private Context context;
public TestListener(Context context) { this.context = context; }

@Override
public void onClick(View view) {
final String vibratePattern = vibratePatternEditText.getText().toString();

try {
Vibrator vibrator = (Vibrator)this.context.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(MessageNotifier.parseVibratePattern(vibratePattern), -1);
} catch(NumberFormatException e) {
Toast.makeText(context, R.string.preferences__pref_vibrate_custom_pattern_wrong, Toast.LENGTH_LONG).show();
}
}
}

private class CancelListener implements View.OnClickListener {
private AlertDialog dialog;
public CancelListener(AlertDialog dialog) { this.dialog = dialog; }

@Override
public void onClick(View view) {
dialog.dismiss();
dialogInProgress = false;
}
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(state);
if (dialogInProgress) {
showDialog();
}
}

@Override
protected View onCreateDialogView() {
dialogInProgress = false;
return super.onCreateDialogView();
}
}
Loading