Add duration setting to alarm vibrations - 1.176 🚀

Closes #179
This commit is contained in:
Brandon Presley 2023-11-12 12:23:40 +13:00
parent 75263af8b3
commit 706d4d1bbd
7 changed files with 73 additions and 8 deletions

View File

@ -5,7 +5,7 @@ import { useForm } from "react-hook-form";
import { NativeModules, ScrollView } from "react-native"; import { NativeModules, ScrollView } from "react-native";
import DocumentPicker from "react-native-document-picker"; import DocumentPicker from "react-native-document-picker";
import { Dirs, FileSystem } from "react-native-file-access"; import { Dirs, FileSystem } from "react-native-file-access";
import { Button } from "react-native-paper"; import { Button, TextInput } from "react-native-paper";
import ConfirmDialog from "./ConfirmDialog"; import ConfirmDialog from "./ConfirmDialog";
import DrawerHeader from "./DrawerHeader"; import DrawerHeader from "./DrawerHeader";
import Page from "./Page"; import Page from "./Page";
@ -21,6 +21,7 @@ import Settings, { settingsUpdated } from "./settings";
import { toast } from "./toast"; import { toast } from "./toast";
import { useTheme } from "./use-theme"; import { useTheme } from "./use-theme";
import { check, PERMISSIONS, RESULTS, request } from "react-native-permissions"; import { check, PERMISSIONS, RESULTS, request } from "react-native-permissions";
import AppInput from "./AppInput";
const twelveHours = [ const twelveHours = [
"dd/LL/yyyy", "dd/LL/yyyy",
@ -220,6 +221,51 @@ export default function SettingsPage() {
[update, setTheme, setDarkColor, setLightColor, setValue] [update, setTheme, setDarkColor, setLightColor, setValue]
); );
const changeNumber = useCallback(
async (key: keyof Settings, value: number) => {
setValue(key, value);
await update(key, value);
switch (key) {
case "duration":
return toast("Changed duration of alarm vibrations.");
}
},
[update, setValue]
);
const numberInputs: Input<number>[] = useMemo(
() => [
{
name: "Vibration duration (ms)",
value: settings.duration,
key: "duration",
},
],
[settings]
);
const renderNumber = useCallback(
(item: Input<number>) => (
<AppInput
value={item.value?.toString() ?? "300"}
key={item.key}
label={item.name}
onChangeText={(value) => changeString(item.key, value)}
onSubmitEditing={(e) =>
changeNumber(item.key, Number(e.nativeEvent.text))
}
keyboardType="numeric"
blurOnSubmit
/>
),
[changeString, changeNumber]
);
const numbersMarkup = useMemo(
() => numberInputs.filter(filter).map((s) => renderNumber(s)),
[numberInputs, filter, renderNumber]
);
const selects: Input<string>[] = useMemo(() => { const selects: Input<string>[] = useMemo(() => {
const today = new Date(); const today = new Date();
return [ return [
@ -336,6 +382,7 @@ export default function SettingsPage() {
<Page term={term} search={setTerm} style={{ flexGrow: 1 }}> <Page term={term} search={setTerm} style={{ flexGrow: 1 }}>
<ScrollView style={{ marginTop: MARGIN, flex: 1 }}> <ScrollView style={{ marginTop: MARGIN, flex: 1 }}>
{selectsMarkup} {selectsMarkup}
{numbersMarkup}
{switchesMarkup} {switchesMarkup}
{buttonsMarkup} {buttonsMarkup}
</ScrollView> </ScrollView>

View File

@ -85,8 +85,8 @@ android {
applicationId "com.massive" applicationId "com.massive"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 36201 versionCode 36202
versionName "1.175" versionName "1.176"
} }
signingConfigs { signingConfigs {
release { release {

View File

@ -12,7 +12,7 @@ import android.os.*
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
class Settings(val sound: String?, val noSound: Boolean, val vibrate: Boolean) class Settings(val sound: String?, val noSound: Boolean, val vibrate: Boolean, val duration: Long)
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.O)
class AlarmService : Service(), OnPreparedListener { class AlarmService : Service(), OnPreparedListener {
@ -45,13 +45,15 @@ class AlarmService : Service(), OnPreparedListener {
@SuppressLint("Range") @SuppressLint("Range")
private fun getSettings(): Settings { private fun getSettings(): Settings {
val db = DatabaseHelper(applicationContext).readableDatabase val db = DatabaseHelper(applicationContext).readableDatabase
val cursor = db.rawQuery("SELECT sound, noSound, vibrate FROM settings", null) val cursor = db.rawQuery("SELECT sound, noSound, vibrate, duration FROM settings", null)
cursor.moveToFirst() cursor.moveToFirst()
val sound = cursor.getString(cursor.getColumnIndex("sound")) val sound = cursor.getString(cursor.getColumnIndex("sound"))
val noSound = cursor.getInt(cursor.getColumnIndex("noSound")) == 1 val noSound = cursor.getInt(cursor.getColumnIndex("noSound")) == 1
val vibrate = cursor.getInt(cursor.getColumnIndex("vibrate")) == 1 val vibrate = cursor.getInt(cursor.getColumnIndex("vibrate")) == 1
var duration = cursor.getLong(cursor.getColumnIndex("duration"))
if (duration.toInt() == 0) duration = 300
cursor.close() cursor.close()
return Settings(sound, noSound, vibrate) return Settings(sound, noSound, vibrate, duration)
} }
private fun playSound(settings: Settings) { private fun playSound(settings: Settings) {
@ -117,7 +119,7 @@ class AlarmService : Service(), OnPreparedListener {
val settings = getSettings() val settings = getSettings()
playSound(settings) playSound(settings)
if (!settings.vibrate) return START_STICKY if (!settings.vibrate) return START_STICKY
val pattern = longArrayOf(0, 300, 1300, 300, 1300, 300) val pattern = longArrayOf(0, settings.duration, 1300, settings.duration, 1300, settings.duration / 2)
vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val vibratorManager = val vibratorManager =
getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager

View File

@ -32,6 +32,7 @@ import Settings from "./settings";
import Weight from "./weight"; import Weight from "./weight";
import { exercises1699508495726 } from "./migrations/1699508495726-exercises"; import { exercises1699508495726 } from "./migrations/1699508495726-exercises";
import { exercisesFix1699613077628 } from "./migrations/1699613077628-exercises-fix"; import { exercisesFix1699613077628 } from "./migrations/1699613077628-exercises-fix";
import { settingsDuration1699743753975 } from "./migrations/1699743753975-settings-duration";
export const AppDataSource = new DataSource({ export const AppDataSource = new DataSource({
type: "react-native", type: "react-native",
@ -70,5 +71,6 @@ export const AppDataSource = new DataSource({
weight1697766633971, weight1697766633971,
exercises1699508495726, exercises1699508495726,
exercisesFix1699613077628, exercisesFix1699613077628,
settingsDuration1699743753975,
], ],
}); });

View File

@ -0,0 +1,11 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class settingsDuration1699743753975 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner
.query("ALTER TABLE settings ADD COLUMN duration INTEGER")
.catch(() => null);
}
public async down(queryRunner: QueryRunner): Promise<void> {}
}

View File

@ -1,6 +1,6 @@
{ {
"name": "massive", "name": "massive",
"version": "1.175", "version": "1.176",
"private": true, "private": true,
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"scripts": { "scripts": {

View File

@ -47,6 +47,9 @@ export default class Settings {
@Column("boolean") @Column("boolean")
backup: boolean; backup: boolean;
@Column("int")
duration: number;
} }
export const SETTINGS = "settings"; export const SETTINGS = "settings";