Add vibration setting for timers
This commit is contained in:
parent
16ba002387
commit
4c185f0346
2
App.tsx
2
App.tsx
|
@ -62,6 +62,8 @@ const App = () => {
|
|||
if (seconds === null) await setItem('seconds', '30');
|
||||
const alarmEnabled = await getItem('alarmEnabled');
|
||||
if (alarmEnabled === null) await setItem('alarmEnabled', 'false');
|
||||
const vibrate = await getItem('vibrate');
|
||||
if (vibrate === null) await setItem('vibrate', 'true');
|
||||
if (!(await getItem('predictiveSets')))
|
||||
await setItem('predictiveSets', 'true');
|
||||
if (!(await getItem('maxSets'))) await setItem('maxSets', '3');
|
||||
|
|
|
@ -29,13 +29,14 @@ export default function EditSet() {
|
|||
}, [navigation]),
|
||||
);
|
||||
|
||||
const notify = useCallback(async () => {
|
||||
const startTimer = useCallback(async () => {
|
||||
const enabled = await AsyncStorage.getItem('alarmEnabled');
|
||||
if (enabled !== 'true') return;
|
||||
const minutes = await AsyncStorage.getItem('minutes');
|
||||
const seconds = await AsyncStorage.getItem('seconds');
|
||||
const milliseconds = Number(minutes) * 60 * 1000 + Number(seconds) * 1000;
|
||||
NativeModules.AlarmModule.timer(milliseconds);
|
||||
const vibrate = (await AsyncStorage.getItem('vibrate')) === 'true';
|
||||
NativeModules.AlarmModule.timer(milliseconds, vibrate);
|
||||
}, []);
|
||||
|
||||
const update = useCallback(
|
||||
|
@ -57,11 +58,11 @@ export default function EditSet() {
|
|||
INSERT INTO sets(name, reps, weight, created, unit)
|
||||
VALUES (?,?,?,strftime('%Y-%m-%dT%H:%M:%S', 'now', 'localtime'),?)
|
||||
`;
|
||||
startTimer();
|
||||
await db.executeSql(insert, [name, reps, weight, unit]);
|
||||
notify();
|
||||
navigation.goBack();
|
||||
},
|
||||
[db, navigation, notify],
|
||||
[db, navigation, startTimer],
|
||||
);
|
||||
|
||||
const save = useCallback(
|
||||
|
|
|
@ -121,7 +121,7 @@ export default function SetList() {
|
|||
todaysWorkouts[todaysWorkouts.indexOf(todaysSets[0].name!) + 1];
|
||||
}
|
||||
const best = await getBest(nextWorkout);
|
||||
setNextSet({...best, created: new Date().toISOString()});
|
||||
setNextSet({...best});
|
||||
}, [getTodaysSets, getTodaysPlan, getBest]);
|
||||
|
||||
useFocusEffect(
|
||||
|
@ -171,7 +171,6 @@ export default function SetList() {
|
|||
reps: 0,
|
||||
weight: 0,
|
||||
unit: 'kg',
|
||||
created: new Date().toISOString(),
|
||||
};
|
||||
navigation.navigate('EditSet', {set: nextSet || set});
|
||||
}, [navigation, nextSet]);
|
||||
|
|
|
@ -14,19 +14,20 @@ import MassiveSwitch from './MassiveSwitch';
|
|||
const {getItem, setItem} = AsyncStorage;
|
||||
|
||||
export default function SettingsPage() {
|
||||
const [vibrate, setVibrate] = useState(true);
|
||||
const [minutes, setMinutes] = useState<string>('');
|
||||
const [maxSets, setMaxSets] = useState<string>('3');
|
||||
const [seconds, setSeconds] = useState<string>('');
|
||||
const [alarmEnabled, setAlarmEnabled] = useState<boolean>(false);
|
||||
const [predictiveSets, setPredictiveSets] = useState<boolean>(false);
|
||||
const [showBattery, setShowBattery] = useState(false);
|
||||
const [alarm, setAlarm] = useState<boolean>(false);
|
||||
const [predictive, setPredictive] = useState<boolean>(false);
|
||||
const [battery, setBattery] = useState(false);
|
||||
const [ignoring, setIgnoring] = useState(false);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
setMinutes((await getItem('minutes')) || '');
|
||||
setSeconds((await getItem('seconds')) || '');
|
||||
setAlarmEnabled((await getItem('alarmEnabled')) === 'true');
|
||||
setPredictiveSets((await getItem('predictiveSets')) === 'true');
|
||||
setAlarm((await getItem('alarmEnabled')) === 'true');
|
||||
setPredictive((await getItem('predictiveSets')) === 'true');
|
||||
setMaxSets((await getItem('maxSets')) || '');
|
||||
NativeModules.AlarmModule.ignoringBattery(setIgnoring);
|
||||
}, []);
|
||||
|
@ -37,27 +38,27 @@ export default function SettingsPage() {
|
|||
|
||||
const changeAlarmEnabled = useCallback(
|
||||
(enabled: boolean) => {
|
||||
setAlarmEnabled(enabled);
|
||||
if (enabled && !ignoring) setShowBattery(true);
|
||||
setAlarm(enabled);
|
||||
if (enabled && !ignoring) setBattery(true);
|
||||
setItem('alarmEnabled', enabled ? 'true' : 'false');
|
||||
},
|
||||
[setShowBattery, ignoring],
|
||||
[setBattery, ignoring],
|
||||
);
|
||||
|
||||
const changePredictive = useCallback(
|
||||
(enabled: boolean) => {
|
||||
setPredictiveSets(enabled);
|
||||
setPredictive(enabled);
|
||||
setItem('predictiveSets', enabled ? 'true' : 'false');
|
||||
ToastAndroid.show(
|
||||
'Predictive sets guess whats next based on todays plan.',
|
||||
ToastAndroid.LONG,
|
||||
);
|
||||
},
|
||||
[setPredictiveSets],
|
||||
[setPredictive],
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
const textInputs = (
|
||||
<>
|
||||
<TextInput
|
||||
label="Rest minutes"
|
||||
value={minutes}
|
||||
|
@ -68,8 +69,8 @@ export default function SettingsPage() {
|
|||
setItem('minutes', text);
|
||||
}}
|
||||
style={styles.text}
|
||||
selectTextOnFocus
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label="Rest seconds"
|
||||
value={seconds}
|
||||
|
@ -80,8 +81,8 @@ export default function SettingsPage() {
|
|||
setItem('seconds', s);
|
||||
}}
|
||||
style={styles.text}
|
||||
selectTextOnFocus
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label="Sets per workout"
|
||||
value={maxSets}
|
||||
|
@ -91,30 +92,48 @@ export default function SettingsPage() {
|
|||
setItem('maxSets', value);
|
||||
}}
|
||||
style={styles.text}
|
||||
selectTextOnFocus
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
const changeVibrate = useCallback(
|
||||
(value: boolean) => {
|
||||
setVibrate(value);
|
||||
setItem('vibrate', value ? 'true' : 'false');
|
||||
},
|
||||
[setVibrate],
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{textInputs}
|
||||
<Text style={styles.text}>Rest timers</Text>
|
||||
<MassiveSwitch
|
||||
style={[styles.text, {alignSelf: 'flex-start'}]}
|
||||
value={alarmEnabled}
|
||||
value={alarm}
|
||||
onValueChange={changeAlarmEnabled}
|
||||
/>
|
||||
|
||||
<Text style={styles.text}>Vibrate</Text>
|
||||
<MassiveSwitch
|
||||
style={[styles.text, {alignSelf: 'flex-start'}]}
|
||||
value={vibrate}
|
||||
onValueChange={changeVibrate}
|
||||
/>
|
||||
<ConfirmDialog
|
||||
title="Battery optimizations"
|
||||
show={showBattery}
|
||||
setShow={setShowBattery}
|
||||
show={battery}
|
||||
setShow={setBattery}
|
||||
onOk={() => {
|
||||
NativeModules.AlarmModule.openSettings();
|
||||
setShowBattery(false);
|
||||
setBattery(false);
|
||||
}}>
|
||||
Disable battery optimizations for Massive to use rest timers.
|
||||
</ConfirmDialog>
|
||||
|
||||
<Text style={styles.text}>Predictive sets</Text>
|
||||
<MassiveSwitch
|
||||
style={[styles.text, {alignSelf: 'flex-start'}]}
|
||||
value={predictiveSets}
|
||||
value={predictive}
|
||||
onValueChange={changePredictive}
|
||||
/>
|
||||
</View>
|
||||
|
|
|
@ -83,7 +83,7 @@ export default function ViewBest() {
|
|||
<XAxis
|
||||
style={{marginHorizontal: -10, height: xAxisHeight}}
|
||||
data={sets}
|
||||
formatLabel={(_value, index) => formatMonth(sets[index].created)}
|
||||
formatLabel={(_value, index) => formatMonth(sets[index].created!)}
|
||||
contentInset={{left: 10, right: 10}}
|
||||
svg={axesSvg}
|
||||
/>
|
||||
|
|
|
@ -23,10 +23,11 @@ class AlarmModule internal constructor(context: ReactApplicationContext?) :
|
|||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
@ReactMethod
|
||||
fun timer(milliseconds: Int) {
|
||||
fun timer(milliseconds: Int, vibrate: Boolean) {
|
||||
Log.d("AlarmModule", "Queue alarm for $milliseconds delay")
|
||||
val intent = Intent(reactApplicationContext, TimerService::class.java)
|
||||
intent.putExtra("milliseconds", milliseconds)
|
||||
intent.putExtra("vibrate", vibrate)
|
||||
reactApplicationContext.startService(intent)
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,9 @@ class AlarmService : Service(), OnPreparedListener {
|
|||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.setUsage(AudioAttributes.USAGE_ALARM)
|
||||
.build()
|
||||
vibrator!!.vibrate(VibrationEffect.createWaveform(pattern, 1), audioAttributes)
|
||||
val vibrate = intent.extras!!.getBoolean("vibrate")
|
||||
if (vibrate)
|
||||
vibrator!!.vibrate(VibrationEffect.createWaveform(pattern, 1), audioAttributes)
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
|
|
|
@ -19,17 +19,19 @@ class TimerService : Service() {
|
|||
private var endMs: Int? = null
|
||||
private var currentMs: Long? = null
|
||||
private var countdownTimer: CountDownTimer? = null
|
||||
private var vibrate: Boolean = true
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
Log.d("TimerService", "Started timer service.")
|
||||
Log.d("TimerService", "endMs=$endMs,currentMs=$currentMs")
|
||||
if (intent?.action == "add") {
|
||||
vibrate = intent!!.extras!!.getBoolean("vibrate")
|
||||
if (intent.action == "add") {
|
||||
endMs = currentMs!!.toInt().plus(60000)
|
||||
applicationContext.stopService(Intent(applicationContext, AlarmService::class.java))
|
||||
}
|
||||
else {
|
||||
endMs = intent!!.extras!!.getInt("milliseconds")
|
||||
endMs = intent.extras!!.getInt("milliseconds")
|
||||
}
|
||||
Log.d("TimerService", "endMs=$endMs,currentMs=$currentMs")
|
||||
notificationManager = getManager(applicationContext)
|
||||
|
@ -68,7 +70,9 @@ class TimerService : Service() {
|
|||
.setCategory(NotificationCompat.CATEGORY_ALARM)
|
||||
.priority = NotificationCompat.PRIORITY_HIGH
|
||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||
applicationContext.startService(Intent(applicationContext, AlarmService::class.java))
|
||||
val alarmIntent = Intent(applicationContext, AlarmService::class.java)
|
||||
alarmIntent.putExtra("vibrate", vibrate)
|
||||
applicationContext.startService(alarmIntent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user