Quit trying to move timer logic into AlarmModule
I just can't figure out how to make the stop button and delete intents work.
This commit is contained in:
parent
c9125575cc
commit
21d9149498
|
@ -7,6 +7,7 @@ import {useSnackbar} from './MassiveSnack';
|
||||||
import Set from './set';
|
import Set from './set';
|
||||||
import {addSet, getSet, updateSet} from './set.service';
|
import {addSet, getSet, updateSet} from './set.service';
|
||||||
import SetForm from './SetForm';
|
import SetForm from './SetForm';
|
||||||
|
import {updateSettings} from './settings.service';
|
||||||
import StackHeader from './StackHeader';
|
import StackHeader from './StackHeader';
|
||||||
import {useSettings} from './use-settings';
|
import {useSettings} from './use-settings';
|
||||||
|
|
||||||
|
@ -22,11 +23,15 @@ export default function EditSet() {
|
||||||
if (!settings.alarm) return;
|
if (!settings.alarm) return;
|
||||||
const {minutes, seconds} = await getSet(name);
|
const {minutes, seconds} = await getSet(name);
|
||||||
const milliseconds = (minutes ?? 3) * 60 * 1000 + (seconds ?? 0) * 1000;
|
const milliseconds = (minutes ?? 3) * 60 * 1000 + (seconds ?? 0) * 1000;
|
||||||
|
console.log(`startTimer:`, `Starting timer in ${minutes}:${seconds}`);
|
||||||
NativeModules.AlarmModule.timer(
|
NativeModules.AlarmModule.timer(
|
||||||
milliseconds,
|
milliseconds,
|
||||||
!!settings.vibrate,
|
!!settings.vibrate,
|
||||||
settings.sound,
|
settings.sound,
|
||||||
);
|
);
|
||||||
|
const nextAlarm = new Date();
|
||||||
|
nextAlarm.setTime(nextAlarm.getTime() + milliseconds);
|
||||||
|
updateSettings({...settings, nextAlarm: nextAlarm.toISOString()});
|
||||||
},
|
},
|
||||||
[settings],
|
[settings],
|
||||||
);
|
);
|
||||||
|
|
20
Page.tsx
20
Page.tsx
|
@ -12,18 +12,20 @@ export default function Page({
|
||||||
}: {
|
}: {
|
||||||
children: JSX.Element | JSX.Element[];
|
children: JSX.Element | JSX.Element[];
|
||||||
onAdd?: () => void;
|
onAdd?: () => void;
|
||||||
search: string;
|
search?: string;
|
||||||
setSearch: (value: string) => void;
|
setSearch?: (value: string) => void;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Searchbar
|
{typeof search === 'string' && setSearch && (
|
||||||
placeholder="Search"
|
<Searchbar
|
||||||
value={search}
|
placeholder="Search"
|
||||||
onChangeText={setSearch}
|
value={search}
|
||||||
icon="search"
|
onChangeText={setSearch}
|
||||||
clearIcon="clear"
|
icon="search"
|
||||||
/>
|
clearIcon="clear"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{children}
|
{children}
|
||||||
{onAdd && <MassiveFab onPress={onAdd} />}
|
{onAdd && <MassiveFab onPress={onAdd} />}
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import {createDrawerNavigator} from '@react-navigation/drawer';
|
import {createDrawerNavigator} from '@react-navigation/drawer';
|
||||||
|
import {useNavigation} from '@react-navigation/native';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {IconButton} from 'react-native-paper';
|
import {IconButton} from 'react-native-paper';
|
||||||
import BestPage from './BestPage';
|
import BestPage from './BestPage';
|
||||||
|
@ -7,6 +8,7 @@ import HomePage from './HomePage';
|
||||||
import PlanPage from './PlanPage';
|
import PlanPage from './PlanPage';
|
||||||
import Route from './route';
|
import Route from './route';
|
||||||
import SettingsPage from './SettingsPage';
|
import SettingsPage from './SettingsPage';
|
||||||
|
import TimerPage from './TimerPage';
|
||||||
import useDark from './use-dark';
|
import useDark from './use-dark';
|
||||||
import WorkoutsPage from './WorkoutsPage';
|
import WorkoutsPage from './WorkoutsPage';
|
||||||
|
|
||||||
|
@ -14,12 +16,14 @@ const Drawer = createDrawerNavigator<DrawerParamList>();
|
||||||
|
|
||||||
export default function Routes() {
|
export default function Routes() {
|
||||||
const dark = useDark();
|
const dark = useDark();
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
const routes: Route[] = [
|
const routes: Route[] = [
|
||||||
{name: 'Home', component: HomePage, icon: 'home'},
|
{name: 'Home', component: HomePage, icon: 'home'},
|
||||||
{name: 'Plans', component: PlanPage, icon: 'event'},
|
{name: 'Plans', component: PlanPage, icon: 'event'},
|
||||||
{name: 'Best', component: BestPage, icon: 'insights'},
|
{name: 'Best', component: BestPage, icon: 'insights'},
|
||||||
{name: 'Workouts', component: WorkoutsPage, icon: 'fitness-center'},
|
{name: 'Workouts', component: WorkoutsPage, icon: 'fitness-center'},
|
||||||
|
{name: 'Timer', component: TimerPage, icon: 'access-time'},
|
||||||
{name: 'Settings', component: SettingsPage, icon: 'settings'},
|
{name: 'Settings', component: SettingsPage, icon: 'settings'},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
76
TimerPage.tsx
Normal file
76
TimerPage.tsx
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
import {useFocusEffect} from '@react-navigation/native';
|
||||||
|
import React, {useCallback, useState} from 'react';
|
||||||
|
import {NativeModules, View} from 'react-native';
|
||||||
|
import {Button, Subheading, Title} from 'react-native-paper';
|
||||||
|
import DrawerHeader from './DrawerHeader';
|
||||||
|
import MassiveFab from './MassiveFab';
|
||||||
|
import Page from './Page';
|
||||||
|
import {getSettings, updateSettings} from './settings.service';
|
||||||
|
import {useSettings} from './use-settings';
|
||||||
|
|
||||||
|
export default function TimerPage() {
|
||||||
|
const [remaining, setRemaining] = useState(0);
|
||||||
|
const {settings} = useSettings();
|
||||||
|
|
||||||
|
const minutes = Math.floor(remaining / 1000 / 60);
|
||||||
|
const seconds = Math.floor((remaining / 1000) % 60);
|
||||||
|
let interval = 0;
|
||||||
|
|
||||||
|
const tick = useCallback(() => {
|
||||||
|
let newRemaining = 0;
|
||||||
|
getSettings().then(gotSettings => {
|
||||||
|
if (!gotSettings.nextAlarm) return;
|
||||||
|
const date = new Date(gotSettings.nextAlarm);
|
||||||
|
newRemaining = date.getTime() - new Date().getTime();
|
||||||
|
if (newRemaining < 0) setRemaining(0);
|
||||||
|
else setRemaining(newRemaining);
|
||||||
|
});
|
||||||
|
interval = setInterval(() => {
|
||||||
|
console.log({newRemaining});
|
||||||
|
newRemaining -= 1000;
|
||||||
|
if (newRemaining > 0) return setRemaining(newRemaining);
|
||||||
|
clearInterval(interval);
|
||||||
|
setRemaining(0);
|
||||||
|
}, 1000);
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useFocusEffect(tick);
|
||||||
|
|
||||||
|
const stop = () => {
|
||||||
|
NativeModules.AlarmModule.stop();
|
||||||
|
clearInterval(interval);
|
||||||
|
setRemaining(0);
|
||||||
|
updateSettings({...settings, nextAlarm: undefined});
|
||||||
|
};
|
||||||
|
|
||||||
|
const add = async () => {
|
||||||
|
if (!settings.nextAlarm) return;
|
||||||
|
const date = new Date(settings.nextAlarm);
|
||||||
|
date.setTime(date.getTime() + 1000 * 60);
|
||||||
|
NativeModules.AlarmModule.add(date, settings.vibrate, settings.sound);
|
||||||
|
await updateSettings({...settings, nextAlarm: date.toISOString()});
|
||||||
|
tick();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<DrawerHeader name="Timer" />
|
||||||
|
<Page>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
}}>
|
||||||
|
<Title>Remaining</Title>
|
||||||
|
<Subheading>
|
||||||
|
{minutes}:{seconds}
|
||||||
|
</Subheading>
|
||||||
|
<Button onPress={add}>Add 1 min</Button>
|
||||||
|
</View>
|
||||||
|
</Page>
|
||||||
|
<MassiveFab icon="stop" onPress={stop} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,29 +1,55 @@
|
||||||
package com.massive
|
package com.massive
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.*
|
||||||
import android.content.ActivityNotFoundException
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.os.CountDownTimer
|
||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import com.facebook.react.bridge.ActivityEventListener
|
||||||
|
import com.facebook.react.bridge.Arguments
|
||||||
|
import com.facebook.react.bridge.BaseActivityEventListener
|
||||||
import com.facebook.react.bridge.Callback
|
import com.facebook.react.bridge.Callback
|
||||||
import com.facebook.react.bridge.ReactApplicationContext
|
import com.facebook.react.bridge.ReactApplicationContext
|
||||||
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
||||||
import com.facebook.react.bridge.ReactMethod
|
import com.facebook.react.bridge.ReactMethod
|
||||||
|
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
|
||||||
|
import kotlin.math.floor
|
||||||
|
|
||||||
|
|
||||||
class AlarmModule internal constructor(context: ReactApplicationContext?) :
|
class AlarmModule internal constructor(context: ReactApplicationContext?) :
|
||||||
ReactContextBaseJavaModule(context) {
|
ReactContextBaseJavaModule(context) {
|
||||||
|
|
||||||
|
var countdownTimer: CountDownTimer? = null
|
||||||
|
|
||||||
override fun getName(): String {
|
override fun getName(): String {
|
||||||
return "AlarmModule"
|
return "AlarmModule"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val mActivityEventListener: ActivityEventListener =
|
||||||
|
object : BaseActivityEventListener() {
|
||||||
|
override fun onActivityResult(
|
||||||
|
activity: Activity?,
|
||||||
|
requestCode: Int,
|
||||||
|
resultCode: Int,
|
||||||
|
data: Intent?
|
||||||
|
) {
|
||||||
|
Log.d("AlarmModule", "onActivityResult")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
reactApplicationContext.addActivityEventListener(mActivityEventListener)
|
||||||
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
fun add(milliseconds: Int, vibrate: Boolean, sound: String?) {
|
fun add(milliseconds: Int, vibrate: Boolean, sound: String?) {
|
||||||
|
@ -50,11 +76,19 @@ class AlarmModule internal constructor(context: ReactApplicationContext?) :
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
fun timer(milliseconds: Int, vibrate: Boolean, sound: String?) {
|
fun timer(milliseconds: Int, vibrate: Boolean, sound: String?) {
|
||||||
Log.d("AlarmModule", "Queue alarm for $milliseconds delay")
|
Log.d("AlarmModule", "Queue alarm for $milliseconds delay")
|
||||||
val intent = Intent(reactApplicationContext, TimerService::class.java)
|
val intent = Intent(reactApplicationContext, AlarmModule::class.java)
|
||||||
intent.putExtra("milliseconds", milliseconds)
|
currentActivity?.startActivityForResult(intent, 0)
|
||||||
intent.putExtra("vibrate", vibrate)
|
val manager = getManager()
|
||||||
intent.putExtra("sound", sound)
|
manager.cancel(NOTIFICATION_ID_DONE)
|
||||||
reactApplicationContext.startService(intent)
|
reactApplicationContext.stopService(
|
||||||
|
Intent(
|
||||||
|
reactApplicationContext,
|
||||||
|
AlarmService::class.java
|
||||||
|
)
|
||||||
|
)
|
||||||
|
countdownTimer?.cancel()
|
||||||
|
countdownTimer = getTimer(milliseconds, vibrate, sound)
|
||||||
|
countdownTimer?.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
@ -87,4 +121,113 @@ class AlarmModule internal constructor(context: ReactApplicationContext?) :
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
private fun getTimer(endMs: Int, vibrate: Boolean, sound: String?): CountDownTimer {
|
||||||
|
val builder = getBuilder()
|
||||||
|
return object : CountDownTimer(endMs.toLong(), 1000) {
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
override fun onTick(current: Long) {
|
||||||
|
val seconds = floor((current / 1000).toDouble() % 60)
|
||||||
|
.toInt().toString().padStart(2, '0')
|
||||||
|
val minutes = floor((current / 1000).toDouble() / 60)
|
||||||
|
.toInt().toString().padStart(2, '0')
|
||||||
|
builder.setContentText("$minutes:$seconds")
|
||||||
|
.setAutoCancel(false)
|
||||||
|
.setDefaults(0)
|
||||||
|
.setProgress(endMs, current.toInt(), false)
|
||||||
|
.setCategory(NotificationCompat.CATEGORY_PROGRESS)
|
||||||
|
.priority = NotificationCompat.PRIORITY_LOW
|
||||||
|
val manager = getManager()
|
||||||
|
manager.notify(NOTIFICATION_ID_PENDING, builder.build())
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
override fun onFinish() {
|
||||||
|
val context = reactApplicationContext
|
||||||
|
val finishIntent = Intent(context, StopAlarm::class.java)
|
||||||
|
val finishPending =
|
||||||
|
PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
finishIntent,
|
||||||
|
PendingIntent.FLAG_IMMUTABLE
|
||||||
|
)
|
||||||
|
val fullIntent = Intent(context, TimerDone::class.java)
|
||||||
|
val fullPending =
|
||||||
|
PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
fullIntent,
|
||||||
|
PendingIntent.FLAG_IMMUTABLE
|
||||||
|
)
|
||||||
|
builder.setContentText("Timer finished.")
|
||||||
|
.setProgress(0, 0, false)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setOngoing(true)
|
||||||
|
.setFullScreenIntent(fullPending, true)
|
||||||
|
.setContentIntent(finishPending)
|
||||||
|
.setChannelId(CHANNEL_ID_DONE)
|
||||||
|
.setCategory(NotificationCompat.CATEGORY_ALARM)
|
||||||
|
.priority = NotificationCompat.PRIORITY_HIGH
|
||||||
|
val manager = getManager()
|
||||||
|
manager.notify(NOTIFICATION_ID_DONE, builder.build())
|
||||||
|
manager.cancel(NOTIFICATION_ID_PENDING)
|
||||||
|
val alarmIntent = Intent(context, AlarmService::class.java)
|
||||||
|
alarmIntent.putExtra("vibrate", vibrate)
|
||||||
|
alarmIntent.putExtra("sound", sound)
|
||||||
|
context.startService(alarmIntent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("UnspecifiedImmutableFlag")
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
private fun getBuilder(): NotificationCompat.Builder {
|
||||||
|
val context = reactApplicationContext
|
||||||
|
val contentIntent = Intent(context, MainActivity::class.java)
|
||||||
|
val pendingContent =
|
||||||
|
PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||||
|
val stopIntent = Intent(context, StopTimer::class.java)
|
||||||
|
val pendingStop =
|
||||||
|
PendingIntent.getService(context, 0, stopIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||||
|
return NotificationCompat.Builder(context, CHANNEL_ID_PENDING)
|
||||||
|
.setSmallIcon(R.drawable.ic_baseline_hourglass_bottom_24)
|
||||||
|
.setContentTitle("Resting")
|
||||||
|
.setContentIntent(pendingContent)
|
||||||
|
.addAction(R.drawable.ic_baseline_stop_24, "Stop", pendingStop)
|
||||||
|
.setDeleteIntent(pendingStop)
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
fun getManager(): NotificationManager {
|
||||||
|
val alarmsChannel = NotificationChannel(
|
||||||
|
CHANNEL_ID_DONE,
|
||||||
|
CHANNEL_ID_DONE,
|
||||||
|
NotificationManager.IMPORTANCE_HIGH
|
||||||
|
)
|
||||||
|
alarmsChannel.description = "Alarms for rest timers."
|
||||||
|
alarmsChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
|
||||||
|
val notificationManager = reactApplicationContext.getSystemService(
|
||||||
|
NotificationManager::class.java
|
||||||
|
)
|
||||||
|
notificationManager.createNotificationChannel(alarmsChannel)
|
||||||
|
val timersChannel =
|
||||||
|
NotificationChannel(
|
||||||
|
CHANNEL_ID_PENDING,
|
||||||
|
CHANNEL_ID_PENDING,
|
||||||
|
NotificationManager.IMPORTANCE_LOW
|
||||||
|
)
|
||||||
|
timersChannel.setSound(null, null)
|
||||||
|
timersChannel.description = "Progress on rest timers."
|
||||||
|
notificationManager.createNotificationChannel(timersChannel)
|
||||||
|
return notificationManager
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val CHANNEL_ID_PENDING = "Timer"
|
||||||
|
const val CHANNEL_ID_DONE = "Alarm"
|
||||||
|
const val NOTIFICATION_ID_PENDING = 1
|
||||||
|
const val NOTIFICATION_ID_DONE = 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,52 @@
|
||||||
package com.massive
|
package com.massive
|
||||||
|
|
||||||
|
import android.app.Notification
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext
|
||||||
|
|
||||||
class StopTimer : Service() {
|
class StopTimer : Service() {
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
applicationContext.stopService(Intent(applicationContext, TimerService::class.java))
|
Log.d("StopTimer", "onStartCommand")
|
||||||
applicationContext.stopService(Intent(applicationContext, AlarmService::class.java))
|
applicationContext.stopService(Intent(applicationContext, AlarmService::class.java))
|
||||||
|
val manager = getManager();
|
||||||
|
manager.cancel(AlarmModule.NOTIFICATION_ID_DONE)
|
||||||
|
manager.cancel(AlarmModule.NOTIFICATION_ID_PENDING)
|
||||||
|
val mod = AlarmModule(applicationContext as ReactApplicationContext?)
|
||||||
|
Log.d("StopTimer", "countdownTimer=${mod.countdownTimer}")
|
||||||
return super.onStartCommand(intent, flags, startId)
|
return super.onStartCommand(intent, flags, startId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBind(p0: Intent?): IBinder? {
|
override fun onBind(p0: Intent?): IBinder? {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
private fun getManager(): NotificationManager {
|
||||||
|
val alarmsChannel = NotificationChannel(
|
||||||
|
AlarmModule.CHANNEL_ID_DONE,
|
||||||
|
AlarmModule.CHANNEL_ID_DONE,
|
||||||
|
NotificationManager.IMPORTANCE_HIGH
|
||||||
|
)
|
||||||
|
alarmsChannel.description = "Alarms for rest timers."
|
||||||
|
alarmsChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
|
||||||
|
val notificationManager = applicationContext.getSystemService(
|
||||||
|
NotificationManager::class.java
|
||||||
|
)
|
||||||
|
notificationManager.createNotificationChannel(alarmsChannel)
|
||||||
|
val timersChannel =
|
||||||
|
NotificationChannel(AlarmModule.CHANNEL_ID_PENDING, AlarmModule.CHANNEL_ID_PENDING, NotificationManager.IMPORTANCE_LOW)
|
||||||
|
timersChannel.setSound(null, null)
|
||||||
|
timersChannel.description = "Progress on rest timers."
|
||||||
|
notificationManager.createNotificationChannel(timersChannel)
|
||||||
|
return notificationManager
|
||||||
|
}
|
||||||
}
|
}
|
3
db.ts
3
db.ts
|
@ -117,6 +117,9 @@ const migrations = [
|
||||||
`
|
`
|
||||||
ALTER TABLE settings ADD COLUMN showSets BOOLEAN DEFAULT 1
|
ALTER TABLE settings ADD COLUMN showSets BOOLEAN DEFAULT 1
|
||||||
`,
|
`,
|
||||||
|
`
|
||||||
|
CREATE INDEX sets_created ON sets(created)
|
||||||
|
`,
|
||||||
];
|
];
|
||||||
|
|
||||||
export let db: SQLiteDatabase;
|
export let db: SQLiteDatabase;
|
||||||
|
|
|
@ -4,4 +4,5 @@ export type DrawerParamList = {
|
||||||
Best: {};
|
Best: {};
|
||||||
Plans: {};
|
Plans: {};
|
||||||
Workouts: {};
|
Workouts: {};
|
||||||
|
Timer: {};
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,4 +11,5 @@ export default interface Settings {
|
||||||
showDate: number;
|
showDate: number;
|
||||||
theme: 'system' | 'dark' | 'light';
|
theme: 'system' | 'dark' | 'light';
|
||||||
showSets: number;
|
showSets: number;
|
||||||
|
nextAlarm?: string;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user