From 5d27744ead065e79f6477d39dcd800638886b12b Mon Sep 17 00:00:00 2001 From: Joshua Burman Date: Fri, 20 Dec 2024 13:56:26 -0500 Subject: [PATCH] convert to dao calls, prep for migration strategy and first start db seed --- analysis_options.yaml | 4 ++ lib/database/database.dart | 11 ++++++ lib/database/seed.dart | 2 +- lib/main.dart | 17 ++++---- lib/models/activity_timer_model.dart | 15 +++++--- lib/screens/sessions_screen.dart | 17 ++++---- lib/widgets/activity_action_view.dart | 2 +- lib/widgets/activity_card.dart | 45 +++++++++++----------- lib/widgets/session_view.dart | 18 +++++---- lib/widgets/session_view_achievements.dart | 10 ++--- lib/widgets/session_view_media.dart | 12 +++--- 11 files changed, 90 insertions(+), 63 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 61b6c4d..ddab027 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -9,6 +9,10 @@ # packages, and plugins designed to encourage good coding practices. include: package:flutter_lints/flutter.yaml +analyzer: + exclude: + - "**/*.g.dart" + linter: # The lint rules applied to this project can be customized in the # section below to disable rules from the `package:flutter_lints/flutter.yaml` diff --git a/lib/database/database.dart b/lib/database/database.dart index d44025c..52d4ad3 100644 --- a/lib/database/database.dart +++ b/lib/database/database.dart @@ -2,6 +2,7 @@ import 'package:drift/drift.dart'; import 'package:drift_flutter/drift_flutter.dart'; import 'package:sendtrain/database/daos/activities_dao.dart'; import 'package:sendtrain/database/daos/sessions_dao.dart'; +import 'package:sendtrain/database/seed.dart'; part 'database.g.dart'; @@ -125,6 +126,16 @@ class AppDatabase extends _$AppDatabase { @override int get schemaVersion => 1; + @override + MigrationStrategy get migration { + return MigrationStrategy( + onCreate: (m) async { + await m.createAll(); // create all tables + await seedDb(); // seed the tables + } + ); + } + static QueryExecutor _openConnection() { // `driftDatabase` from `package:drift_flutter` stores the database in // `getApplicationDocumentsDirectory()`. diff --git a/lib/database/seed.dart b/lib/database/seed.dart index ee9b6f6..27355b0 100644 --- a/lib/database/seed.dart +++ b/lib/database/seed.dart @@ -3,7 +3,7 @@ import 'dart:math'; import 'package:drift/drift.dart'; import 'package:sendtrain/database/database.dart'; -void seedDb() { +Future seedDb() async { final database = AppDatabase(); // seed data setup diff --git a/lib/main.dart b/lib/main.dart index 34a88c6..bd25344 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:sendtrain/database/database.dart'; import 'package:sendtrain/models/activity_timer_model.dart'; import 'package:sendtrain/screens/activities_screen.dart'; import 'package:sendtrain/screens/sessions_screen.dart'; @@ -11,7 +12,6 @@ class SendTrain extends StatelessWidget { @override Widget build(BuildContext context) { - // seedDb(); return MaterialApp( title: "Sendtrain", theme: ThemeData.dark(useMaterial3: true), @@ -93,10 +93,13 @@ class _AppState extends State { } void main() { - runApp( - ChangeNotifierProvider( - create: (context) => ActivityTimerModel(), - child: const SendTrain(), - ), - ); + runApp(MultiProvider( + providers: [ + ChangeNotifierProvider(create: (context) => ActivityTimerModel()), + Provider( + create: (context) => AppDatabase(), + dispose: (context, db) => db.close()), + ], + child: const SendTrain(), + )); } diff --git a/lib/models/activity_timer_model.dart b/lib/models/activity_timer_model.dart index 8159ed8..24e5d11 100644 --- a/lib/models/activity_timer_model.dart +++ b/lib/models/activity_timer_model.dart @@ -2,11 +2,13 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; +import 'package:sendtrain/database/database.dart'; import 'package:sendtrain/models/activity_model.dart'; class ActivityTimerModel with ChangeNotifier { int _actionCounter = 0; - ActivityModel? _activity; + ActivityModel? _activityModel; + Activity? _activity; List _sets = []; int _currentActionNum = 0; int _currentSetNum = 0; @@ -20,20 +22,21 @@ class ActivityTimerModel with ChangeNotifier { dynamic get currentAction => currentSet[_currentActionNum]; int get currentSetNum => _currentSetNum; dynamic get currentSet => _sets[_currentSetNum]; - ActivityModel? get activity => _activity; + ActivityModel? get activityModel => _activityModel; + Activity? get activity => _activity; List get sets => _sets; Timer? get periodicTimer => _periodicTimer; bool get isActive => _isActive(); double get progress => _progress; int get totalTime => _totalTime; - void setup(ActivityModel activity) { - if (_activity == null || activity.id != _activity?.id) { + void setup(ActivityModel activityModel) { + if (_activityModel == null || activityModel.id != _activityModel?.id) { _periodicTimer?.cancel(); _progress = 0; _isc = null; - _activity = activity; - _sets = activity.actions[0].items(); + _activityModel = activityModel; + _sets = activityModel.actions[0].items(); _currentActionNum = 0; _currentSetNum = 0; setActionCount(); diff --git a/lib/screens/sessions_screen.dart b/lib/screens/sessions_screen.dart index 84d21b0..22231b1 100644 --- a/lib/screens/sessions_screen.dart +++ b/lib/screens/sessions_screen.dart @@ -1,19 +1,18 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'package:sendtrain/database/daos/sessions_dao.dart'; import 'package:sendtrain/database/database.dart'; import '../widgets/session_card.dart'; class SessionsScreen extends StatelessWidget { - final AppDatabase database = AppDatabase(); - SessionsScreen({super.key}); + const SessionsScreen({super.key}); @override Widget build(BuildContext context) { return FutureBuilder>( - future: SessionsDao(database).all(), + future: SessionsDao(Provider.of(context)).all(), builder: (context, snapshot) { if (snapshot.hasData) { - database.close(); final sessions = snapshot.data!; final pending = sessions.where((session) => session.status == SessionStatus.completed || @@ -28,8 +27,6 @@ class SessionsScreen extends StatelessWidget { Widget upcomingSession = SessionCard(session: upcoming); Widget currentSession = SessionCard(session: current); - database.close(); - return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -66,7 +63,13 @@ class SessionsScreen extends StatelessWidget { ], ); } else { - return const CircularProgressIndicator(); + return Container( + alignment: Alignment.center, + child: SizedBox( + height: 50.0, + width: 50.0, + child: CircularProgressIndicator(), + )); } }); } diff --git a/lib/widgets/activity_action_view.dart b/lib/widgets/activity_action_view.dart index 2d88665..591fbad 100644 --- a/lib/widgets/activity_action_view.dart +++ b/lib/widgets/activity_action_view.dart @@ -25,7 +25,7 @@ class ActivityActionViewState extends State { Widget build(BuildContext context) { ActivityTimerModel atm = Provider.of(context, listen: true); - List>> sets = atm.activity!.actions[0].items(); + List>> sets = atm.activityModel!.actions[0].items(); // we need to set the scroll controller // so we can update the selected item position diff --git a/lib/widgets/activity_card.dart b/lib/widgets/activity_card.dart index e93a29e..4a5adc2 100644 --- a/lib/widgets/activity_card.dart +++ b/lib/widgets/activity_card.dart @@ -36,28 +36,28 @@ class ActivityCardState extends State { : Theme.of(context).colorScheme.surfaceContainerLow, clipBehavior: Clip.hardEdge, child: InkWell( - // onTap: () => showGeneralDialog( - // barrierColor: Colors.black.withOpacity(0.5), - // transitionDuration: const Duration(milliseconds: 220), - // transitionBuilder: (BuildContext context, - // Animation animation, - // Animation secondaryAnimation, - // Widget child) { - // Animation custom = Tween( - // begin: const Offset(0.0, 1.0), - // end: const Offset(0.0, 0.0)) - // .animate(animation); - // return SlideTransition( - // position: custom, - // child: Dialog.fullscreen( - // child: ActivityView(activity: widget.activity))); - // }, - // barrierDismissible: true, - // barrierLabel: '', - // context: context, - // pageBuilder: (context, animation1, animation2) { - // return Container(); - // }), + onTap: () => showGeneralDialog( + barrierColor: Colors.black.withOpacity(0.5), + transitionDuration: const Duration(milliseconds: 220), + transitionBuilder: (BuildContext context, + Animation animation, + Animation secondaryAnimation, + Widget child) { + Animation custom = Tween( + begin: const Offset(0.0, 1.0), + end: const Offset(0.0, 0.0)) + .animate(animation); + return SlideTransition( + position: custom, + child: Dialog.fullscreen( + child: ActivityView(activity: widget.activity))); + }, + barrierDismissible: true, + barrierLabel: '', + context: context, + pageBuilder: (context, animation1, animation2) { + return Container(); + }), child: Column( mainAxisSize: MainAxisSize.min, children: [ @@ -65,6 +65,7 @@ class ActivityCardState extends State { leading: Padding( padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), child: Container( + padding: EdgeInsets.only(top: 5, bottom: 5), width: 60, decoration: BoxDecoration( image: DecorationImage( diff --git a/lib/widgets/session_view.dart b/lib/widgets/session_view.dart index d7355fc..702ed35 100644 --- a/lib/widgets/session_view.dart +++ b/lib/widgets/session_view.dart @@ -1,8 +1,8 @@ -import 'package:drift/drift.dart' hide Column; import 'package:flutter/material.dart'; import 'package:flutter_expandable_fab/flutter_expandable_fab.dart'; import 'package:intl/intl.dart'; import 'package:intl/date_symbol_data_local.dart'; +import 'package:provider/provider.dart'; import 'package:sendtrain/database/daos/activities_dao.dart'; import 'package:sendtrain/database/database.dart'; @@ -12,11 +12,10 @@ import 'package:sendtrain/widgets/session_view_activities.dart'; import 'package:sendtrain/widgets/session_view_media.dart'; class SessionView extends StatelessWidget { - SessionView({super.key, required this.data, required this.session}); + const SessionView({super.key, required this.data, required this.session}); final SessionModel data; final Session session; - final AppDatabase database = AppDatabase(); @override Widget build(BuildContext context) { @@ -24,11 +23,10 @@ class SessionView extends StatelessWidget { final DateFormat dateFormat = DateFormat('yyyy-MM-dd'); return FutureBuilder>( - future: ActivitiesDao(database).sessionActivities(session.id), + future: ActivitiesDao(Provider.of(context)).sessionActivities(session.id), builder: (context, snapshot) { if (snapshot.hasData) { final activities = snapshot.data!; - database.close(); return Scaffold( floatingActionButtonLocation: ExpandableFab.location, floatingActionButton: ExpandableFab( @@ -84,7 +82,7 @@ class SessionView extends StatelessWidget { style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold), 'Media:')), - SessionViewMedia(session: session, media: data.media), + SessionViewMedia(session: session), const Padding( padding: EdgeInsets.fromLTRB(15, 30, 0, 10), child: Text( @@ -96,7 +94,13 @@ class SessionView extends StatelessWidget { ], )); } else { - return const CircularProgressIndicator(); + return Container( + alignment: Alignment.center, + child: SizedBox( + height: 50.0, + width: 50.0, + child: CircularProgressIndicator(), + )); } }); } diff --git a/lib/widgets/session_view_achievements.dart b/lib/widgets/session_view_achievements.dart index bb83454..df9a827 100644 --- a/lib/widgets/session_view_achievements.dart +++ b/lib/widgets/session_view_achievements.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'package:sendtrain/database/daos/session_activities_dao.dart'; import 'package:sendtrain/database/database.dart'; class SessionViewAchievements extends StatelessWidget { - SessionViewAchievements({super.key, required this.session}); + const SessionViewAchievements({super.key, required this.session}); final Session session; - final AppDatabase database = AppDatabase(); List getAchievements(List sessionActivities) { List achievements = []; @@ -26,12 +26,12 @@ class SessionViewAchievements extends StatelessWidget { @override Widget build(BuildContext context) { return FutureBuilder>( - future: SessionActivitiesDao(database).sessionActivitiesBySessionId(session.id), + future: SessionActivitiesDao(Provider.of(context)).sessionActivitiesBySessionId(session.id), builder: (context, snapshot) { if (snapshot.hasData) { final sessionActivities = snapshot.data!; final achievements = getAchievements(sessionActivities); - database.close(); + // database.close(); return Column( children: [ @@ -58,7 +58,7 @@ class SessionViewAchievements extends StatelessWidget { ], ); } else { - return const CircularProgressIndicator(); + return Padding(padding: EdgeInsets.all(15), child:CircularProgressIndicator()); } }); } diff --git a/lib/widgets/session_view_media.dart b/lib/widgets/session_view_media.dart index d719f5b..ade8c57 100644 --- a/lib/widgets/session_view_media.dart +++ b/lib/widgets/session_view_media.dart @@ -1,24 +1,22 @@ import 'package:flutter/material.dart'; -import 'package:sendtrain/classes/media.dart'; +import 'package:provider/provider.dart'; import 'package:sendtrain/database/daos/media_items_dao.dart'; import 'package:sendtrain/database/database.dart'; import 'package:sendtrain/widgets/media_card.dart'; class SessionViewMedia extends StatelessWidget { - SessionViewMedia({super.key, this.media, required this.session}); + const SessionViewMedia({super.key, required this.session}); - final List? media; final Session session; - final AppDatabase database = AppDatabase(); @override Widget build(BuildContext context) { return FutureBuilder>( - future: MediaItemsDao(database).mediaItemsFromSession(session), + future: MediaItemsDao(Provider.of(context)).mediaItemsFromSession(session), builder: (context, snapshot) { if (snapshot.hasData) { final mediaItems = snapshot.data!; - database.close(); + // database.close(); List mediaCards = List.generate( mediaItems.length, (i) => MediaCard(media: mediaItems[i])); @@ -37,7 +35,7 @@ class SessionViewMedia extends StatelessWidget { ], ); } else { - return CircularProgressIndicator(); + return Padding(padding: EdgeInsets.all(15), child:CircularProgressIndicator()); } }); }