diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 4618ecc..bd10ce1 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -1,9 +1,9 @@
-
-
-
+
+
+
@@ -39,5 +39,14 @@
-
+
+
+
+
+
diff --git a/android/app/src/main/kotlin/com/example/fmassive/AlarmService.kt b/android/app/src/main/kotlin/com/example/fmassive/AlarmService.kt
new file mode 100644
index 0000000..0686bd8
--- /dev/null
+++ b/android/app/src/main/kotlin/com/example/fmassive/AlarmService.kt
@@ -0,0 +1,155 @@
+package com.example.fmassive
+
+import android.annotation.SuppressLint
+import android.app.*
+import android.content.Context
+import android.content.Intent
+import android.media.AudioAttributes
+import android.media.MediaPlayer
+import android.media.MediaPlayer.OnPreparedListener
+import android.net.Uri
+import android.os.*
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.core.app.NotificationCompat
+
+@RequiresApi(Build.VERSION_CODES.O)
+class AlarmService : Service(), OnPreparedListener {
+ private var mediaPlayer: MediaPlayer? = null
+ private var vibrator: Vibrator? = null
+
+ private fun getBuilder(): NotificationCompat.Builder {
+ val context = applicationContext
+ val contentIntent = Intent(context, MainActivity::class.java)
+ val pendingContent =
+ PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_IMMUTABLE)
+ val addBroadcast = Intent(MainActivity.ADD_BROADCAST).apply {
+ setPackage(context.packageName)
+ }
+ val pendingAdd =
+ PendingIntent.getBroadcast(context, 0, addBroadcast, PendingIntent.FLAG_MUTABLE)
+ val stopBroadcast = Intent(MainActivity.STOP_BROADCAST)
+ stopBroadcast.setPackage(context.packageName)
+ val pendingStop =
+ PendingIntent.getBroadcast(context, 0, stopBroadcast, PendingIntent.FLAG_IMMUTABLE)
+ return NotificationCompat.Builder(context, MainActivity.CHANNEL_ID_PENDING)
+ .setSmallIcon(R.drawable.ic_baseline_hourglass_bottom_24).setContentTitle("Resting")
+ .setContentIntent(pendingContent)
+ .addAction(R.drawable.ic_baseline_stop_24, "Stop", pendingStop)
+ .addAction(R.drawable.ic_baseline_stop_24, "Add 1 min", pendingAdd)
+ .setDeleteIntent(pendingStop)
+ }
+
+
+ @SuppressLint("Range")
+ private fun getSettings(): Settings {
+ val db = DatabaseHelper(applicationContext).readableDatabase
+ val cursor = db.rawQuery("SELECT sound, no_sound, vibrate FROM settings", null)
+ cursor.moveToFirst()
+ val sound = cursor.getString(cursor.getColumnIndex("sound"))
+ val noSound = cursor.getInt(cursor.getColumnIndex("no_sound")) == 1
+ val vibrate = cursor.getInt(cursor.getColumnIndex("vibrate")) == 1
+ Log.d("AlarmService", "vibrate=$vibrate")
+ cursor.close()
+ return Settings(sound, noSound, vibrate)
+ }
+
+ private fun playSound(settings: Settings) {
+ if (settings.sound == null && !settings.noSound) {
+ Log.d("AlarmService", "Playing default alarm sound...")
+ mediaPlayer = MediaPlayer.create(applicationContext, R.raw.argon)
+ mediaPlayer?.start()
+ mediaPlayer?.setOnCompletionListener { vibrator?.cancel() }
+ } else if (settings.sound != null && !settings.noSound) {
+ Log.d("AlarmService", "Playing custom alarm sound ${settings.sound}...")
+ mediaPlayer = MediaPlayer().apply {
+ setAudioAttributes(
+ AudioAttributes.Builder()
+ .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
+ .setUsage(AudioAttributes.USAGE_MEDIA)
+ .build()
+ )
+ setDataSource(applicationContext, Uri.parse(settings.sound))
+ prepare()
+ start()
+ setOnCompletionListener { vibrator?.cancel() }
+ }
+ }
+ }
+
+ private fun doNotify(): Notification {
+ Log.d("AlarmService", "doNotify")
+ val alarmsChannel = NotificationChannel(
+ CHANNEL_ID_DONE,
+ CHANNEL_ID_DONE,
+ NotificationManager.IMPORTANCE_HIGH
+ )
+ alarmsChannel.description = "Alarms for rest timers."
+ alarmsChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
+ alarmsChannel.setSound(null, null)
+ val manager = applicationContext.getSystemService(
+ NotificationManager::class.java
+ )
+ manager.createNotificationChannel(alarmsChannel)
+ val builder = getBuilder()
+ val context = applicationContext
+ val finishIntent = Intent(context, StopAlarm::class.java)
+ val finishPending = PendingIntent.getActivity(
+ context, 0, finishIntent, PendingIntent.FLAG_IMMUTABLE
+ )
+ builder.setContentText("Timer finished.").setProgress(0, 0, false)
+ .setAutoCancel(true).setOngoing(true)
+ .setContentIntent(finishPending).setChannelId(CHANNEL_ID_DONE)
+ .setCategory(NotificationCompat.CATEGORY_ALARM).priority =
+ NotificationCompat.PRIORITY_HIGH
+ val notification = builder.build()
+ manager.notify(NOTIFICATION_ID_DONE, notification)
+ manager.cancel(MainActivity.NOTIFICATION_ID_PENDING)
+ return notification
+ }
+
+ @SuppressLint("Recycle")
+ override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
+ Log.d("AlarmService", "onStartCommand")
+ val notification = doNotify()
+ startForeground(NOTIFICATION_ID_DONE, notification)
+ val settings = getSettings()
+ playSound(settings)
+ if (!settings.vibrate) return START_STICKY
+ val pattern = longArrayOf(0, 300, 1300, 300, 1300, 300)
+ vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ val vibratorManager =
+ getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
+ vibratorManager.defaultVibrator
+ } else {
+ @Suppress("DEPRECATION")
+ getSystemService(VIBRATOR_SERVICE) as Vibrator
+ }
+ val audioAttributes = AudioAttributes.Builder()
+ .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+ .setUsage(AudioAttributes.USAGE_ALARM)
+ .build()
+ vibrator!!.vibrate(VibrationEffect.createWaveform(pattern, 1), audioAttributes)
+ return START_STICKY
+ }
+
+ override fun onBind(intent: Intent): IBinder? {
+ return null
+ }
+
+ override fun onPrepared(player: MediaPlayer) {
+ player.start()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ mediaPlayer?.stop()
+ mediaPlayer?.release()
+ vibrator?.cancel()
+ }
+
+ companion object {
+ const val CHANNEL_ID_DONE = "Alarm"
+ const val NOTIFICATION_ID_DONE = 2
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/example/fmassive/DatabaseHelper.kt b/android/app/src/main/kotlin/com/example/fmassive/DatabaseHelper.kt
new file mode 100644
index 0000000..899a421
--- /dev/null
+++ b/android/app/src/main/kotlin/com/example/fmassive/DatabaseHelper.kt
@@ -0,0 +1,22 @@
+package com.example.fmassive
+
+import android.content.Context
+import android.database.sqlite.SQLiteDatabase
+import android.database.sqlite.SQLiteOpenHelper
+
+class DatabaseHelper(context: Context) :
+ SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
+ companion object {
+ private const val DATABASE_NAME = "massive.db"
+ private const val DATABASE_VERSION = 1
+ }
+
+ override fun onCreate(db: SQLiteDatabase) {
+ }
+
+ override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
+ }
+
+ override fun onDowngrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
+ }
+}
diff --git a/android/app/src/main/kotlin/com/example/fmassive/MainActivity.kt b/android/app/src/main/kotlin/com/example/fmassive/MainActivity.kt
index 8a70ed0..4f0e697 100644
--- a/android/app/src/main/kotlin/com/example/fmassive/MainActivity.kt
+++ b/android/app/src/main/kotlin/com/example/fmassive/MainActivity.kt
@@ -19,16 +19,14 @@ import io.flutter.plugin.common.MethodChannel
import kotlin.math.floor
class MainActivity : FlutterActivity() {
- private val CHANNEL = "com.massive/android"
-
@RequiresApi(Build.VERSION_CODES.O)
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
- MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
+ MethodChannel(flutterEngine.dartExecutor.binaryMessenger, FLUTTER_CHANNEL).setMethodCallHandler {
call, result ->
if (call.method == "timer") {
val args = call.arguments as ArrayList<*>
- timer(args[0] as Long)
+ timer(args[0] as Int)
} else {
result.notImplemented()
}
@@ -42,7 +40,7 @@ class MainActivity : FlutterActivity() {
private val stopReceiver = object : BroadcastReceiver() {
@RequiresApi(Build.VERSION_CODES.O)
override fun onReceive(context: Context?, intent: Intent?) {
- Log.d("AlarmModule", "Received stop broadcast intent")
+ Log.d("MainActivity", "Received stop broadcast intent")
stop()
}
}
@@ -59,59 +57,51 @@ class MainActivity : FlutterActivity() {
@RequiresApi(api = Build.VERSION_CODES.O)
fun add() {
- Log.d("AlarmModule", "Add 1 min to alarm.")
+ Log.d("MainActivity", "Add 1 min to alarm.")
countdownTimer?.cancel()
val newMs = if (running) currentMs.toInt().plus(60000) else 60000
- countdownTimer = getTimer(newMs.toLong())
+ countdownTimer = getTimer(newMs)
countdownTimer?.start()
running = true
- //val manager = getManager()
- //manager.cancel(AlarmService.NOTIFICATION_ID_DONE)
- //val intent = Intent(context, AlarmService::class.java)
- //context.stopService(intent)
+ val manager = getManager()
+ manager.cancel(AlarmService.NOTIFICATION_ID_DONE)
+ val intent = Intent(context, AlarmService::class.java)
+ context.stopService(intent)
}
@RequiresApi(api = Build.VERSION_CODES.O)
fun stop() {
- Log.d("AlarmModule", "Stop alarm.")
+ Log.d("MainActivity", "Stop alarm.")
countdownTimer?.cancel()
running = false
- //val intent = Intent(context, AlarmService::class.java)
- //reactApplicationContext?.stopService(intent)
- //val manager = getManager()
- //manager.cancel(AlarmService.NOTIFICATION_ID_DONE)
- //manager.cancel(NOTIFICATION_ID_PENDING)
- //val params = Arguments.createMap().apply {
- // putString("minutes", "00")
- // putString("seconds", "00")
- //}
- //reactApplicationContext
- // .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
- // .emit("tick", params)
+ val intent = Intent(context, AlarmService::class.java)
+ context.stopService(intent)
+ val manager = getManager()
+ manager.cancel(AlarmService.NOTIFICATION_ID_DONE)
+ manager.cancel(NOTIFICATION_ID_PENDING)
}
@RequiresApi(api = Build.VERSION_CODES.O)
- fun timer(milliseconds: Long) {
+ fun timer(milliseconds: Int) {
context.registerReceiver(stopReceiver, IntentFilter(STOP_BROADCAST))
context.registerReceiver(addReceiver, IntentFilter(ADD_BROADCAST))
- Log.d("AlarmModule", "Queue alarm for $milliseconds delay")
- //val manager = getManager()
- //manager.cancel(AlarmService.NOTIFICATION_ID_DONE)
- //val intent = Intent(reactApplicationContext, AlarmService::class.java)
- //reactApplicationContext.stopService(intent)
+ Log.d("MainActivity", "Queue alarm for $milliseconds delay")
+ val manager = getManager()
+ manager.cancel(AlarmService.NOTIFICATION_ID_DONE)
+ val intent = Intent(context, AlarmService::class.java)
+ context.stopService(intent)
countdownTimer?.cancel()
countdownTimer = getTimer(milliseconds)
countdownTimer?.start()
running = true
}
- @RequiresApi(Build.VERSION_CODES.M)
+ @RequiresApi(Build.VERSION_CODES.O)
private fun getTimer(
- endMs: Long,
+ endMs: Int,
): CountDownTimer {
val builder = getBuilder()
return object : CountDownTimer(endMs.toLong(), 1000) {
- @RequiresApi(Build.VERSION_CODES.O)
override fun onTick(current: Long) {
currentMs = current
val seconds =
@@ -123,27 +113,13 @@ class MainActivity : FlutterActivity() {
.setCategory(NotificationCompat.CATEGORY_PROGRESS).priority =
NotificationCompat.PRIORITY_LOW
val manager = getManager()
- Log.d("AlarmModule", "Notify $NOTIFICATION_ID_PENDING")
+ Log.d("MainActivity", "current=$current")
manager.notify(NOTIFICATION_ID_PENDING, builder.build())
- //val params = Arguments.createMap().apply {
- // putString("minutes", minutes)
- // putString("seconds", seconds)
- //}
- //reactApplicationContext
- // .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
- // .emit("tick", params)
}
- @RequiresApi(Build.VERSION_CODES.O)
override fun onFinish() {
- //val context = reactApplicationContext
- //context.startForegroundService(Intent(context, AlarmService::class.java))
- //context
- // .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
- // .emit("finish", Arguments.createMap().apply {
- // putString("minutes", "00")
- // putString("seconds", "00")
- // })
+ Log.d("MainActivity", "Finish")
+ context.startForegroundService(Intent(context, AlarmService::class.java))
}
}
}
@@ -190,5 +166,6 @@ class MainActivity : FlutterActivity() {
const val ADD_BROADCAST = "add-timer-event"
const val CHANNEL_ID_PENDING = "Timer"
const val NOTIFICATION_ID_PENDING = 1
+ const val FLUTTER_CHANNEL = "com.massive/android"
}
}
diff --git a/android/app/src/main/kotlin/com/example/fmassive/Settings.kt b/android/app/src/main/kotlin/com/example/fmassive/Settings.kt
new file mode 100644
index 0000000..9a72904
--- /dev/null
+++ b/android/app/src/main/kotlin/com/example/fmassive/Settings.kt
@@ -0,0 +1,3 @@
+package com.example.fmassive
+
+class Settings(val sound: String?, val noSound: Boolean, val vibrate: Boolean)
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/example/fmassive/StopAlarm.kt b/android/app/src/main/kotlin/com/example/fmassive/StopAlarm.kt
new file mode 100644
index 0000000..ac4d1ff
--- /dev/null
+++ b/android/app/src/main/kotlin/com/example/fmassive/StopAlarm.kt
@@ -0,0 +1,22 @@
+package com.example.fmassive
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Build
+import android.os.Bundle
+import android.util.Log
+import androidx.annotation.RequiresApi
+
+class StopAlarm : Activity() {
+ @RequiresApi(Build.VERSION_CODES.O_MR1)
+ override fun onCreate(savedInstanceState: Bundle?) {
+ Log.d("AlarmActivity", "Call to AlarmActivity")
+ super.onCreate(savedInstanceState)
+ val context = applicationContext
+ context.stopService(Intent(context, AlarmService::class.java))
+ savedInstanceState.apply { setShowWhenLocked(true) }
+ val intent = Intent(context, MainActivity::class.java)
+ intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ context.startActivity(intent)
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/res/raw/argon.mp3 b/android/app/src/main/res/raw/argon.mp3
new file mode 100644
index 0000000..d1f0065
Binary files /dev/null and b/android/app/src/main/res/raw/argon.mp3 differ
diff --git a/lib/database.dart b/lib/database.dart
index 5cfe49b..9ef6587 100644
--- a/lib/database.dart
+++ b/lib/database.dart
@@ -1,10 +1,12 @@
import 'dart:io';
import 'package:fmassive/gym_set.dart';
+import 'package:fmassive/main.dart';
import 'package:moor/ffi.dart';
import 'package:moor/moor.dart';
import 'package:path/path.dart';
-import 'package:path_provider/path_provider.dart';
+import 'package:sqflite/sqflite.dart';
+
import 'settings.dart';
part 'database.g.dart';
@@ -20,6 +22,8 @@ class MyDatabase extends _$MyDatabase {
MigrationStrategy get migration => MigrationStrategy(
onCreate: (Migrator m) async {
await m.createAll();
+ var data = await db.select(db.settings).get();
+ if (data.isEmpty) await db.into(db.settings).insert(defaultSettings);
},
onUpgrade: (Migrator m, int from, int to) async {
// no migrations yet
@@ -29,8 +33,9 @@ class MyDatabase extends _$MyDatabase {
LazyDatabase _openConnection() {
return LazyDatabase(() async {
- final dbFolder = await getApplicationDocumentsDirectory();
- final file = File(join(dbFolder.path, 'massive.db'));
+ final dbFolder = await getDatabasesPath();
+ final file = File(join(dbFolder, 'massive.db'));
+ print('file.path=${file.path}');
return VmDatabase(file, logStatements: true);
});
}
diff --git a/lib/database.g.dart b/lib/database.g.dart
index 3337bd6..2f9739c 100644
--- a/lib/database.g.dart
+++ b/lib/database.g.dart
@@ -10,7 +10,7 @@ part of 'database.dart';
class Setting extends DataClass implements Insertable {
final bool alarm;
final bool vibrate;
- final String sound;
+ final String? sound;
final bool notify;
final bool images;
final bool showUnit;
@@ -26,7 +26,7 @@ class Setting extends DataClass implements Insertable {
Setting(
{required this.alarm,
required this.vibrate,
- required this.sound,
+ this.sound,
required this.notify,
required this.images,
required this.showUnit,
@@ -48,7 +48,7 @@ class Setting extends DataClass implements Insertable {
vibrate: const BoolType()
.mapFromDatabaseResponse(data['${effectivePrefix}vibrate'])!,
sound: const StringType()
- .mapFromDatabaseResponse(data['${effectivePrefix}sound'])!,
+ .mapFromDatabaseResponse(data['${effectivePrefix}sound']),
notify: const BoolType()
.mapFromDatabaseResponse(data['${effectivePrefix}notify'])!,
images: const BoolType()
@@ -80,7 +80,9 @@ class Setting extends DataClass implements Insertable {
final map = {};
map['alarm'] = Variable(alarm);
map['vibrate'] = Variable(vibrate);
- map['sound'] = Variable(sound);
+ if (!nullToAbsent || sound != null) {
+ map['sound'] = Variable(sound);
+ }
map['notify'] = Variable(notify);
map['images'] = Variable(images);
map['show_unit'] = Variable(showUnit);
@@ -104,7 +106,8 @@ class Setting extends DataClass implements Insertable {
return SettingsCompanion(
alarm: Value(alarm),
vibrate: Value(vibrate),
- sound: Value(sound),
+ sound:
+ sound == null && nullToAbsent ? const Value.absent() : Value(sound),
notify: Value(notify),
images: Value(images),
showUnit: Value(showUnit),
@@ -130,7 +133,7 @@ class Setting extends DataClass implements Insertable {
return Setting(
alarm: serializer.fromJson(json['alarm']),
vibrate: serializer.fromJson(json['vibrate']),
- sound: serializer.fromJson(json['sound']),
+ sound: serializer.fromJson(json['sound']),
notify: serializer.fromJson(json['notify']),
images: serializer.fromJson(json['images']),
showUnit: serializer.fromJson(json['showUnit']),
@@ -151,7 +154,7 @@ class Setting extends DataClass implements Insertable {
return {
'alarm': serializer.toJson(alarm),
'vibrate': serializer.toJson(vibrate),
- 'sound': serializer.toJson(sound),
+ 'sound': serializer.toJson(sound),
'notify': serializer.toJson(notify),
'images': serializer.toJson(images),
'showUnit': serializer.toJson(showUnit),
@@ -263,7 +266,7 @@ class Setting extends DataClass implements Insertable {
class SettingsCompanion extends UpdateCompanion {
final Value alarm;
final Value vibrate;
- final Value sound;
+ final Value sound;
final Value notify;
final Value images;
final Value showUnit;
@@ -296,7 +299,7 @@ class SettingsCompanion extends UpdateCompanion {
SettingsCompanion.insert({
required bool alarm,
required bool vibrate,
- required String sound,
+ this.sound = const Value.absent(),
required bool notify,
required bool images,
required bool showUnit,
@@ -311,7 +314,6 @@ class SettingsCompanion extends UpdateCompanion {
required bool backup,
}) : alarm = Value(alarm),
vibrate = Value(vibrate),
- sound = Value(sound),
notify = Value(notify),
images = Value(images),
showUnit = Value(showUnit),
@@ -325,7 +327,7 @@ class SettingsCompanion extends UpdateCompanion {
static Insertable custom({
Expression? alarm,
Expression? vibrate,
- Expression? sound,
+ Expression? sound,
Expression? notify,
Expression? images,
Expression? showUnit,
@@ -361,7 +363,7 @@ class SettingsCompanion extends UpdateCompanion {
SettingsCompanion copyWith(
{Value? alarm,
Value? vibrate,
- Value? sound,
+ Value? sound,
Value? notify,
Value? images,
Value? showUnit,
@@ -403,7 +405,7 @@ class SettingsCompanion extends UpdateCompanion {
map['vibrate'] = Variable(vibrate.value);
}
if (sound.present) {
- map['sound'] = Variable(sound.value);
+ map['sound'] = Variable(sound.value);
}
if (notify.present) {
map['notify'] = Variable(notify.value);
@@ -489,8 +491,8 @@ class $SettingsTable extends Settings with TableInfo<$SettingsTable, Setting> {
final VerificationMeta _soundMeta = const VerificationMeta('sound');
@override
late final GeneratedColumn sound = GeneratedColumn(
- 'sound', aliasedName, false,
- type: const StringType(), requiredDuringInsert: true);
+ 'sound', aliasedName, true,
+ type: const StringType(), requiredDuringInsert: false);
final VerificationMeta _notifyMeta = const VerificationMeta('notify');
@override
late final GeneratedColumn notify = GeneratedColumn(
@@ -609,8 +611,6 @@ class $SettingsTable extends Settings with TableInfo<$SettingsTable, Setting> {
if (data.containsKey('sound')) {
context.handle(
_soundMeta, sound.isAcceptableOrUnknown(data['sound']!, _soundMeta));
- } else if (isInserting) {
- context.missing(_soundMeta);
}
if (data.containsKey('notify')) {
context.handle(_notifyMeta,
diff --git a/lib/edit_set.dart b/lib/edit_set.dart
index 8752ad9..012d2a5 100644
--- a/lib/edit_set.dart
+++ b/lib/edit_set.dart
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter/material.dart' as material;
+import 'package:flutter/services.dart';
import 'package:fmassive/database.dart';
import 'package:fmassive/main.dart';
import 'package:moor_flutter/moor_flutter.dart';
@@ -112,8 +113,11 @@ class _EditGymSetPageState extends State {
onPressed: () async {
if (gymSet.id.present)
await db.update(db.gymSets).write(gymSet);
- else
+ else {
await db.into(db.gymSets).insert(gymSet);
+ const platform = MethodChannel('com.massive/android');
+ platform.invokeMethod('timer', [3000]);
+ }
if (!mounted) return;
Navigator.pop(context);
},
diff --git a/lib/home_page.dart b/lib/home_page.dart
index ca068cc..b2c5422 100644
--- a/lib/home_page.dart
+++ b/lib/home_page.dart
@@ -33,6 +33,7 @@ class RootPage extends State {
void toggleSearch() {
setState(() {
+ if (showSearch) search = '';
showSearch = !showSearch;
});
focusNode.requestFocus();
diff --git a/lib/settings.dart b/lib/settings.dart
index 72a8658..c528810 100644
--- a/lib/settings.dart
+++ b/lib/settings.dart
@@ -4,7 +4,7 @@ import 'package:moor/moor.dart';
Setting defaultSettings = Setting(
alarm: true,
vibrate: true,
- sound: 'default.mp3',
+ sound: null,
notify: true,
images: true,
showUnit: true,
@@ -22,7 +22,7 @@ Setting defaultSettings = Setting(
class Settings extends Table {
BoolColumn get alarm => boolean()();
BoolColumn get vibrate => boolean()();
- TextColumn get sound => text()();
+ TextColumn get sound => text().nullable()();
BoolColumn get notify => boolean()();
BoolColumn get images => boolean()();
BoolColumn get showUnit => boolean()();
diff --git a/lib/settings_page.dart b/lib/settings_page.dart
index f586634..2e906d5 100644
--- a/lib/settings_page.dart
+++ b/lib/settings_page.dart
@@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/material.dart' as material;
import 'package:fmassive/database.dart';
import 'package:fmassive/main.dart';
-import 'package:fmassive/settings.dart';
import 'package:moor/moor.dart';
class SettingsPage extends StatelessWidget {
@@ -30,15 +29,9 @@ class _SettingsPageState extends State<_SettingsPage> {
final TextEditingController searchController = TextEditingController();
- void reset() async {
- var data = await db.select(db.settings).get();
- if (data.isEmpty) await db.into(db.settings).insert(defaultSettings);
- }
-
@override
void initState() {
super.initState();
- reset();
stream = db.select(db.settings).watchSingle();
}